diff --git a/Source/Project64-core/N64System/Recompiler/FunctionMapClass.h b/Source/Project64-core/N64System/Recompiler/FunctionMapClass.h index 0d6f1e6c8..61c61bdc4 100644 --- a/Source/Project64-core/N64System/Recompiler/FunctionMapClass.h +++ b/Source/Project64-core/N64System/Recompiler/FunctionMapClass.h @@ -1,35 +1,35 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include - -class CFunctionMap -{ -protected: - typedef CCompiledFunc * PCCompiledFunc; - typedef PCCompiledFunc * PCCompiledFunc_TABLE; - - CFunctionMap(); - ~CFunctionMap(); - - bool AllocateMemory(); - void Reset(bool bAllocate); - -public: - PCCompiledFunc_TABLE * FunctionTable() const { return m_FunctionTable; } - PCCompiledFunc * JumpTable() const { return m_JumpTable; } - -private: - void CleanBuffers(); - - PCCompiledFunc * m_JumpTable; - PCCompiledFunc_TABLE * m_FunctionTable; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +class CFunctionMap +{ +protected: + typedef CCompiledFunc * PCCompiledFunc; + typedef PCCompiledFunc * PCCompiledFunc_TABLE; + + CFunctionMap(); + ~CFunctionMap(); + + bool AllocateMemory(); + void Reset(bool bAllocate); + +public: + PCCompiledFunc_TABLE * FunctionTable() const { return m_FunctionTable; } + PCCompiledFunc * JumpTable() const { return m_JumpTable; } + +private: + void CleanBuffers(); + + PCCompiledFunc * m_JumpTable; + PCCompiledFunc_TABLE * m_FunctionTable; +}; diff --git a/Source/Project64-core/N64System/Recompiler/JumpInfo.h b/Source/Project64-core/N64System/Recompiler/JumpInfo.h index d8761675d..b7fde9ade 100644 --- a/Source/Project64-core/N64System/Recompiler/JumpInfo.h +++ b/Source/Project64-core/N64System/Recompiler/JumpInfo.h @@ -1,29 +1,29 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include - -struct CJumpInfo -{ - typedef CExitInfo::EXIT_REASON EXIT_REASON; - CJumpInfo(); - - uint32_t TargetPC; - uint32_t JumpPC; - stdstr BranchLabel; - uint32_t * LinkLocation; - uint32_t * LinkLocation2; - bool FallThrough; - bool PermLoop; - bool DoneDelaySlot; //maybe deletable - CRegInfo RegSet; - EXIT_REASON ExitReason; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +struct CJumpInfo +{ + typedef CExitInfo::EXIT_REASON EXIT_REASON; + CJumpInfo(); + + uint32_t TargetPC; + uint32_t JumpPC; + stdstr BranchLabel; + uint32_t * LinkLocation; + uint32_t * LinkLocation2; + bool FallThrough; + bool PermLoop; + bool DoneDelaySlot; //maybe deletable + CRegInfo RegSet; + EXIT_REASON ExitReason; +}; diff --git a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp index 6a114f70f..4b8b8b427 100644 --- a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp +++ b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp @@ -1,1330 +1,1330 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include "LoopAnalysis.h" - -#include -#include -#include -#include -#include -#include - -#ifdef _DEBUG -#define CHECKED_BUILD 1 -#endif - -bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); - -LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) : -m_EnterSection(Section), -m_BlockInfo(CodeBlock), -m_PC((uint32_t)-1), -m_NextInstruction(NORMAL), -m_Test(m_BlockInfo->NextTest()) -{ - memset(&m_Command, 0, sizeof(m_Command)); -} - -LoopAnalysis::~LoopAnalysis() -{ - for (RegisterMap::iterator itr = m_EnterRegisters.begin(); itr != m_EnterRegisters.end(); itr++) - { - delete itr->second; - } - m_EnterRegisters.clear(); - - for (RegisterMap::iterator itr = m_ContinueRegisters.begin(); itr != m_ContinueRegisters.end(); itr++) - { - delete itr->second; - } - m_ContinueRegisters.clear(); - - for (RegisterMap::iterator itr = m_JumpRegisters.begin(); itr != m_JumpRegisters.end(); itr++) - { - delete itr->second; - } - m_JumpRegisters.clear(); -} - -bool LoopAnalysis::SetupRegisterForLoop() -{ - if (!m_EnterSection->m_InLoop) - { - return false; - } - CPU_Message("%s: Section ID: %d Test: %X", __FUNCTION__, m_EnterSection->m_SectionID, m_Test); - if (!CheckLoopRegisterUsage(m_EnterSection)) - { - return false; - } - - RegisterMap::iterator itr = m_EnterRegisters.find(m_EnterSection->m_SectionID); - if (itr == m_EnterRegisters.end()) - { - return false; - } - m_EnterSection->m_RegEnter = *(itr->second); - return true; -} - -bool LoopAnalysis::SetupEnterSection(CCodeSection * Section, bool & bChanged, bool & bSkipedSection) -{ - bChanged = false; - bSkipedSection = false; - if (Section->m_ParentSection.empty()) { g_Notify->BreakPoint(__FILE__, __LINE__); return true; } - - CPU_Message("%s: Block EnterPC: %X Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, m_BlockInfo->VAddrEnter(), Section->m_SectionID, m_Test, Section->m_Test, Section->m_CompiledLocation); - - bool bFirstParent = true; - CRegInfo RegEnter; - for (CCodeSection::SECTION_LIST::iterator iter = Section->m_ParentSection.begin(); iter != Section->m_ParentSection.end(); iter++) - { - CCodeSection * Parent = *iter; - - CPU_Message("%s: Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, Parent->m_SectionID, m_Test, Parent->m_Test, Parent->m_CompiledLocation); - if (Parent->m_Test != m_Test && (m_EnterSection != Section || Parent->m_CompiledLocation == NULL) && Parent->m_InLoop) - { - CPU_Message("%s: Ignore Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, Parent->m_SectionID, m_Test, Parent->m_Test, Parent->m_CompiledLocation); - bSkipedSection = true; - continue; - } - RegisterMap::iterator Continue_itr = m_ContinueRegisters.find(Parent->m_SectionID); - RegisterMap::iterator Jump_itr = m_JumpRegisters.find(Parent->m_SectionID); - - CCodeSection * TargetSection[] = { Parent->m_ContinueSection, Parent->m_JumpSection }; - CRegInfo * JumpRegInfo[] = - { - Continue_itr == m_ContinueRegisters.end() ? &Parent->m_Cont.RegSet : Continue_itr->second, - Jump_itr == m_JumpRegisters.end() ? &Parent->m_Jump.RegSet : Jump_itr->second - }; - - for (int i = 0; i < 2; i++) - { - if (TargetSection[i] != Section) { continue; } - if (bFirstParent) - { - bFirstParent = false; - RegEnter = *JumpRegInfo[i]; - } - else - { - if (*JumpRegInfo[i] == RegEnter) - { - continue; - } - - SyncRegState(RegEnter, *JumpRegInfo[i]); - } - } - } - - if (bFirstParent) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); - if (itr != m_EnterRegisters.end()) - { - if (SyncRegState(*(itr->second), RegEnter)) - { - bChanged = true; - } - } - else - { - m_EnterRegisters.insert(RegisterMap::value_type(Section->m_SectionID, new CRegInfo(RegEnter))); - } - return true; -} - -bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section) -{ - if (Section == NULL) { return true; } - if (!Section->m_InLoop) { return true; } - - CPU_Message("%s: Section %d Block PC: 0x%X", __FUNCTION__, Section->m_SectionID, m_BlockInfo->VAddrEnter()); - - bool bChanged = false, bSkipedSection = false; - if (Section == m_EnterSection && Section->m_Test == m_Test) - { - if (!SetupEnterSection(Section, bChanged, bSkipedSection)) { return false; } - return true; - } - - if (!SetupEnterSection(Section, bChanged, bSkipedSection)) { return false; } - - if (Section->m_Test == m_Test && !bChanged) - { - return true; - } - - CPU_Message("%s: Set Section %d test to %X from %X", __FUNCTION__, Section->m_SectionID, m_Test, Section->m_Test); - Section->m_Test = m_Test; - m_PC = Section->m_EnterPC; - - RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); - m_Reg = itr != m_EnterRegisters.end() ? *(itr->second) : Section->m_RegEnter; - - m_NextInstruction = NORMAL; - uint32_t ContinueSectionPC = Section->m_ContinueSection ? Section->m_ContinueSection->m_EnterPC : (uint32_t)-1; - CPU_Message("ContinueSectionPC = %08X", ContinueSectionPC); - - do - { - if (!g_MMU->LW_VAddr(m_PC, m_Command.Hex)) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; - } - CPU_Message(" %08X: %s", m_PC, R4300iOpcodeName(m_Command.Hex, m_PC)); - CPU_Message(" %s state: %X value: %X", CRegName::GPR[3], m_Reg.GetMipsRegState(3), m_Reg.GetMipsRegLo(3)); - switch (m_Command.op) - { - case R4300i_SPECIAL: - switch (m_Command.funct) - { - case R4300i_SPECIAL_SLL: SPECIAL_SLL(); break; - case R4300i_SPECIAL_SRL: SPECIAL_SRL(); break; - case R4300i_SPECIAL_SRA: SPECIAL_SRA(); break; - case R4300i_SPECIAL_SLLV: SPECIAL_SLLV(); break; - case R4300i_SPECIAL_SRLV: SPECIAL_SRLV(); break; - case R4300i_SPECIAL_SRAV: SPECIAL_SRAV(); break; - case R4300i_SPECIAL_JR: SPECIAL_JR(); break; - case R4300i_SPECIAL_JALR: SPECIAL_JALR(); break; - case R4300i_SPECIAL_SYSCALL: SPECIAL_SYSCALL(Section); break; - case R4300i_SPECIAL_BREAK: SPECIAL_BREAK(Section); break; - case R4300i_SPECIAL_MFHI: SPECIAL_MFHI(); break; - case R4300i_SPECIAL_MTHI: SPECIAL_MTHI(); break; - case R4300i_SPECIAL_MFLO: SPECIAL_MFLO(); break; - case R4300i_SPECIAL_MTLO: SPECIAL_MTLO(); break; - case R4300i_SPECIAL_DSLLV: SPECIAL_DSLLV(); break; - case R4300i_SPECIAL_DSRLV: SPECIAL_DSRLV(); break; - case R4300i_SPECIAL_DSRAV: SPECIAL_DSRAV(); break; - case R4300i_SPECIAL_MULT: break; - case R4300i_SPECIAL_MULTU: break; - case R4300i_SPECIAL_DIV: break; - case R4300i_SPECIAL_DIVU: break; - case R4300i_SPECIAL_DMULT: break; - case R4300i_SPECIAL_DMULTU: break; - case R4300i_SPECIAL_DDIV: break; - case R4300i_SPECIAL_DDIVU: break; - case R4300i_SPECIAL_ADD: SPECIAL_ADD(); break; - case R4300i_SPECIAL_ADDU: SPECIAL_ADDU(); break; - case R4300i_SPECIAL_SUB: SPECIAL_SUB(); break; - case R4300i_SPECIAL_SUBU: SPECIAL_SUBU(); break; - case R4300i_SPECIAL_AND: SPECIAL_AND(); break; - case R4300i_SPECIAL_OR: SPECIAL_OR(); break; - case R4300i_SPECIAL_XOR: SPECIAL_XOR(); break; - case R4300i_SPECIAL_NOR: SPECIAL_NOR(); break; - case R4300i_SPECIAL_SLT: SPECIAL_SLT(); break; - case R4300i_SPECIAL_SLTU: SPECIAL_SLTU(); break; - case R4300i_SPECIAL_DADD: SPECIAL_DADD(); break; - case R4300i_SPECIAL_DADDU: SPECIAL_DADDU(); break; - case R4300i_SPECIAL_DSUB: SPECIAL_DSUB(); break; - case R4300i_SPECIAL_DSUBU: SPECIAL_DSUBU(); break; - case R4300i_SPECIAL_DSLL: SPECIAL_DSLL(); break; - case R4300i_SPECIAL_DSRL: SPECIAL_DSRL(); break; - case R4300i_SPECIAL_DSRA: SPECIAL_DSRA(); break; - case R4300i_SPECIAL_DSLL32: SPECIAL_DSLL32(); break; - case R4300i_SPECIAL_DSRL32: SPECIAL_DSRL32(); break; - case R4300i_SPECIAL_DSRA32: SPECIAL_DSRA32(); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - if (m_Command.Hex == 0x00000001) { break; } - g_Notify->DisplayError("Unhandled R4300i OpCode in FillSectionInfo 5\n%s", - R4300iOpcodeName(m_Command.Hex, m_PC)); -#endif - m_NextInstruction = END_BLOCK; - m_PC -= 4; - } - break; - case R4300i_REGIMM: - switch (m_Command.rt) - { - case R4300i_REGIMM_BLTZ: - case R4300i_REGIMM_BGEZ: - m_NextInstruction = DELAY_SLOT; -#ifdef CHECKED_BUILD - if (Section->m_Cont.TargetPC != m_PC + 8 && - Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4 && - Section->m_JumpSection != NULL && - Section->m_Jump.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_PC == Section->m_Jump.TargetPC) - { - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0) && !Section->m_Jump.PermLoop) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } -#endif - break; - case R4300i_REGIMM_BLTZL: - case R4300i_REGIMM_BGEZL: - m_NextInstruction = LIKELY_DELAY_SLOT; -#ifdef CHECKED_BUILD - if (Section->m_Cont.TargetPC != m_PC + 8 && - Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (Section->m_Jump.TargetPC != m_PC + 4 && - Section->m_JumpSection != NULL && - Section->m_Jump.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - /*if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - }*/ - if (m_PC == m_PC + ((int16_t)m_Command.offset << 2) + 4) - { - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0) && !Section->m_Jump.PermLoop) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } -#endif - break; - case R4300i_REGIMM_BLTZAL: - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - m_Reg.GetMipsRegLo(31) = m_PC + 8; - m_Reg.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); - Section->m_Cont.TargetPC = m_PC + 8; - Section->m_Jump.TargetPC = m_PC + ((int16_t)m_Command.offset << 2) + 4; - if (m_PC == Section->m_Jump.TargetPC) - { - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0)) - { - Section->m_Jump.PermLoop = true; - } - } -#endif - break; - case R4300i_REGIMM_BGEZAL: - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - m_NextInstruction = DELAY_SLOT; - if (m_Reg.IsConst(m_Command.rs)) - { - int64_t Value; - if (m_Reg.Is32Bit(m_Command.rs)) - { - Value = m_Reg.GetMipsRegLo_S(m_Command.rs); - } - else { - Value = m_Reg.GetMipsReg_S(m_Command.rs); - } - if (Value >= 0) - { - m_Reg.GetMipsRegLo(31) = m_PC + 8; - m_Reg.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); - Section->m_Jump.TargetPC = m_PC + ((int16_t)m_Command.offset << 2) + 4; - if (m_PC == Section->m_Jump.TargetPC) - { - if (!DelaySlotEffectsCompare(m_PC, 31, 0)) - { - Section->m_Jump.PermLoop = true; - } - } - break; - } - } - - m_Reg.GetMipsRegLo(31) = m_PC + 8; - m_Reg.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); - Section->m_Cont.TargetPC = m_PC + 8; - Section->m_Jump.TargetPC = m_PC + ((int16_t)m_Command.offset << 2) + 4; - if (m_PC == Section->m_Jump.TargetPC) - { - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0)) - { - Section->m_Jump.PermLoop = true; - } - } -#endif - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - if (m_Command.Hex == 0x0407000D) { break; } - g_Notify->DisplayError("Unhandled R4300i OpCode in FillSectionInfo 4\n%s", - R4300iOpcodeName(m_Command.Hex, m_PC)); - m_NextInstruction = END_BLOCK; - m_PC -= 4; -#endif - } - break; - case R4300i_JAL: - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - m_NextInstruction = DELAY_SLOT; - m_Reg.GetMipsRegLo(31) = m_PC + 8; - m_Reg.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); - Section->m_Jump.TargetPC = (m_PC & 0xF0000000) + (m_Command.target << 2); - if (m_PC == Section->m_Jump.TargetPC) - { - if (!DelaySlotEffectsCompare(m_PC, 31, 0)) - { - Section->m_Jump.PermLoop = true; - } - } -#endif - break; - case R4300i_J: - m_NextInstruction = DELAY_SLOT; -#ifdef CHECKED_BUILD - if (Section->m_Jump.TargetPC != (m_PC & 0xF0000000) + (m_Command.target << 2)) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_PC == Section->m_Jump.TargetPC && !Section->m_Jump.PermLoop) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } -#endif - break; - case R4300i_BEQ: - if (m_PC + ((int16_t)m_Command.offset << 2) + 4 != m_PC + 8) - { - m_NextInstruction = DELAY_SLOT; -#ifdef CHECKED_BUILD - if (m_Command.rs != 0 || m_Command.rt != 0) - { - if (Section->m_Cont.TargetPC != m_PC + 8 && - Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - else - { - if (Section->m_Cont.TargetPC != (uint32_t)-1) - { - //g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4) - { - //g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_PC == Section->m_Jump.TargetPC) - { - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } -#endif - } - break; - case R4300i_BNE: - case R4300i_BLEZ: - case R4300i_BGTZ: - if (m_PC + ((int16_t)m_Command.offset << 2) + 4 != m_PC + 8) - { - m_NextInstruction = DELAY_SLOT; -#ifdef CHECKED_BUILD - if (Section->m_Cont.TargetPC != m_PC + 8 && - Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4 && - Section->m_JumpSection != NULL && - Section->m_Jump.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_PC == Section->m_Jump.TargetPC) - { - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } -#endif - } - break; - case R4300i_ADDI: - case R4300i_ADDIU: - if (m_Command.rt == 0) { break; } - /*if (m_Command.rs == 0) { - m_Reg.GetMipsRegLo(m_Command.rt) = (int16_t)m_Command.immediate; - m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_CONST_32_SIGN); - } else {*/ - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - //} - break; - case R4300i_SLTI: - case R4300i_SLTIU: - if (m_Command.rt == 0) { break; } - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - break; - case R4300i_LUI: - if (m_Command.rt == 0) { break; } - if (!m_Reg.IsModified(m_Command.rt)) - { - m_Reg.SetMipsRegLo(m_Command.rt, ((int16_t)m_Command.offset << 16)); - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_CONST_32_SIGN); - } - break; - case R4300i_ANDI: - if (m_Command.rt == 0) { break; } - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - break; - case R4300i_ORI: - if (m_Command.rt == 0) { break; } - if (m_Command.rs == m_Command.rt) - { - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rs)) { - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_CONST_32_SIGN); - m_Reg.SetMipsRegLo(m_Command.rt, m_Reg.GetMipsRegLo(m_Command.rs) | m_Command.immediate); - } - else { - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - } - break; - case R4300i_XORI: - if (m_Command.rt == 0) { break; } - if (m_Command.rs == m_Command.rt) - { - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_CONST_32_SIGN); - m_Reg.SetMipsRegLo(m_Command.rt, m_Reg.GetMipsRegLo(m_Command.rs) ^ m_Command.immediate); - } - else - { - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - } - break; - case R4300i_CP0: - switch (m_Command.rs) - { - case R4300i_COP0_MF: - if (m_Command.rt == 0) { break; } - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - break; - case R4300i_COP0_MT: break; - default: - if ((m_Command.rs & 0x10) != 0) - { - switch (m_Command.funct) - { - case R4300i_COP0_CO_TLBR: break; - case R4300i_COP0_CO_TLBWI: break; - case R4300i_COP0_CO_TLBWR: break; - case R4300i_COP0_CO_TLBP: break; - case R4300i_COP0_CO_ERET: m_NextInstruction = END_BLOCK; break; - default: - g_Notify->DisplayError(stdstr_f("Unhandled R4300i OpCode in FillSectionInfo\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); - m_NextInstruction = END_BLOCK; - m_PC -= 4; - } - } - else - { - g_Notify->DisplayError(stdstr_f("Unhandled R4300i OpCode in FillSectionInfo 3\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); - m_NextInstruction = END_BLOCK; - m_PC -= 4; - } - } - break; - case R4300i_CP1: - switch (m_Command.fmt) - { - case R4300i_COP1_CF: - case R4300i_COP1_MF: - case R4300i_COP1_DMF: - if (m_Command.rt == 0) { break; } - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - break; - case R4300i_COP1_BC: - switch (m_Command.ft) - { - case R4300i_COP1_BC_BCFL: - case R4300i_COP1_BC_BCTL: - m_NextInstruction = LIKELY_DELAY_SLOT; -#ifdef CHECKED_BUILD - if (Section->m_Cont.TargetPC != m_PC + 8 && - Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_PC == m_PC + ((int16_t)m_Command.offset << 2) + 4) - { - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt)) - { - if (!Section->m_Jump.PermLoop) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } -#endif - } -#endif - break; - case R4300i_COP1_BC_BCF: - case R4300i_COP1_BC_BCT: - m_NextInstruction = DELAY_SLOT; -#ifdef CHECKED_BUILD - if (Section->m_Cont.TargetPC != m_PC + 8 && - Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_PC == Section->m_Jump.TargetPC) - { - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt)) { - Section->m_Jump.PermLoop = true; - } -#endif - } -#endif - break; - } - break; - case R4300i_COP1_MT: break; - case R4300i_COP1_DMT: break; - case R4300i_COP1_CT: break; - case R4300i_COP1_S: break; - case R4300i_COP1_D: break; - case R4300i_COP1_W: break; - case R4300i_COP1_L: break; - default: - g_Notify->DisplayError(stdstr_f("Unhandled R4300i OpCode in FillSectionInfo 2\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); - m_NextInstruction = END_BLOCK; - m_PC -= 4; - } - break; - case R4300i_BEQL: - case R4300i_BNEL: - case R4300i_BLEZL: - case R4300i_BGTZL: - m_NextInstruction = LIKELY_DELAY_SLOT; -#ifdef CHECKED_BUILD - if (Section->m_Cont.TargetPC != m_PC + 8 && - Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (Section->m_Jump.TargetPC != m_PC + 4) - { - //g_Notify->BreakPoint(__FILE__, __LINE__); - } - /*if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - }*/ - if (m_PC == m_PC + ((int16_t)m_Command.offset << 2) + 4) - { - if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } -#endif - break; - case R4300i_DADDI: - case R4300i_DADDIU: - if (m_Command.rt == 0) { break; } - if (m_Command.rs == m_Command.rt) - { - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rs)) - { - if (m_Reg.Is64Bit(m_Command.rs)) - { - int imm32 = (int16_t)m_Command.immediate; - int64_t imm64 = imm32; - m_Reg.SetMipsReg_S(m_Command.rt, m_Reg.GetMipsRegLo_S(m_Command.rs) + imm64); - } - else - { - m_Reg.SetMipsReg_S(m_Command.rt, m_Reg.GetMipsRegLo_S(m_Command.rs) + (int16_t)m_Command.immediate); - } - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_CONST_64); - } - else - { - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - } - break; - case R4300i_LDR: - case R4300i_LDL: - case R4300i_LB: - case R4300i_LH: - case R4300i_LWL: - case R4300i_LW: - case R4300i_LWU: - case R4300i_LL: - case R4300i_LBU: - case R4300i_LHU: - case R4300i_LWR: - case R4300i_SC: - if (m_Command.rt == 0) { break; } - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - break; - case R4300i_SB: break; - case R4300i_SH: break; - case R4300i_SWL: break; - case R4300i_SW: break; - case R4300i_SWR: break; - case R4300i_SDL: break; - case R4300i_SDR: break; - case R4300i_CACHE: break; - case R4300i_LWC1: break; - case R4300i_SWC1: break; - case R4300i_LDC1: break; - case R4300i_LD: - if (m_Command.rt == 0) { break; } - m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); - break; - case R4300i_SDC1: break; - case R4300i_SD: break; - default: - m_NextInstruction = END_BLOCK; - m_PC -= 4; - if (m_Command.Hex == 0x7C1C97C0) { break; } - if (m_Command.Hex == 0x7FFFFFFF) { break; } - if (m_Command.Hex == 0xF1F3F5F7) { break; } - if (m_Command.Hex == 0xC1200000) { break; } - if (m_Command.Hex == 0x4C5A5353) { break; } - g_Notify->DisplayError(stdstr_f("Unhandled R4300i OpCode in FillSectionInfo 1\n%s\n%X", R4300iOpcodeName(m_Command.Hex, m_PC), m_Command.Hex).c_str()); - } - - CPU_Message(" %s state: %X value: %X", CRegName::GPR[5], m_Reg.GetMipsRegState(5), m_Reg.GetMipsRegLo(5)); - - if (Section->m_DelaySlot) - { - if (m_NextInstruction != NORMAL && m_NextInstruction != END_BLOCK) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - m_NextInstruction = END_BLOCK; - SetJumpRegSet(Section, m_Reg); - } - else { - switch (m_NextInstruction) - { - case NORMAL: - m_PC += 4; - break; - case DELAY_SLOT: - m_NextInstruction = DELAY_SLOT_DONE; - m_PC += 4; - if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000)) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - break; - case LIKELY_DELAY_SLOT: - { - SetContinueRegSet(Section, m_Reg); - SetJumpRegSet(Section, m_Reg); - } - m_NextInstruction = END_BLOCK; - break; - case DELAY_SLOT_DONE: - { - SetContinueRegSet(Section, m_Reg); - SetJumpRegSet(Section, m_Reg); - } - m_NextInstruction = END_BLOCK; - break; - case LIKELY_DELAY_SLOT_DONE: - g_Notify->BreakPoint(__FILE__, __LINE__); - if (Section->m_CompiledLocation) - { - } - else - { - //Section->m_Jump.RegSet = m_Reg; - //Section->m_Jump.DoneDelaySlot = true; - } - m_NextInstruction = END_BLOCK; - break; - } - } - - if (m_PC == ContinueSectionPC) - { - m_NextInstruction = END_BLOCK; - SetContinueRegSet(Section, m_Reg); - } - - if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000)) - { - if (m_NextInstruction != END_BLOCK && m_NextInstruction != NORMAL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } while (m_NextInstruction != END_BLOCK); - - if (!CheckLoopRegisterUsage(Section->m_ContinueSection)) { return false; } - if (!CheckLoopRegisterUsage(Section->m_JumpSection)) { return false; } - return true; -} - -bool LoopAnalysis::SyncRegState(CRegInfo & RegSet, const CRegInfo& SyncReg) -{ - bool bChanged = false; - for (int x = 0; x < 32; x++) - { - if (RegSet.GetMipsRegState(x) != SyncReg.GetMipsRegState(x)) - { - CPU_Message("%s: Clear state %s RegEnter State: %X Jump Reg State: %X", __FUNCTION__, CRegName::GPR[x], RegSet.GetMipsRegState(x), SyncReg.GetMipsRegState(x)); - RegSet.SetMipsRegState(x, CRegInfo::STATE_MODIFIED); - bChanged = true; - } - else if (RegSet.IsConst(x) && RegSet.Is32Bit(x) && RegSet.GetMipsRegLo(x) != SyncReg.GetMipsRegLo(x)) - { - CPU_Message("%s: Clear state %s RegEnter State: %X Jump Reg State: %X", __FUNCTION__, CRegName::GPR[x], RegSet.GetMipsRegState(x), SyncReg.GetMipsRegState(x)); - RegSet.SetMipsRegState(x, CRegInfo::STATE_MODIFIED); - bChanged = true; - } - else if (RegSet.IsConst(x) && RegSet.Is64Bit(x) && RegSet.GetMipsReg_S(x) != SyncReg.GetMipsReg_S(x)) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - return bChanged; -} - -void LoopAnalysis::SetJumpRegSet(CCodeSection * Section, const CRegInfo &Reg) -{ - RegisterMap::iterator itr = m_JumpRegisters.find(Section->m_SectionID); - if (itr != m_JumpRegisters.end()) - { - *(itr->second) = Reg; - } - else - { - m_JumpRegisters.insert(RegisterMap::value_type(Section->m_SectionID, new CRegInfo(Reg))); - } -} - -void LoopAnalysis::SetContinueRegSet(CCodeSection * Section, const CRegInfo &Reg) -{ - RegisterMap::iterator itr = m_ContinueRegisters.find(Section->m_SectionID); - if (itr != m_ContinueRegisters.end()) - { - *(itr->second) = Reg; - } - else - { - m_ContinueRegisters.insert(RegisterMap::value_type(Section->m_SectionID, new CRegInfo(Reg))); - } -} - -void LoopAnalysis::SPECIAL_SLL() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_SRL() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_SRA() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_SLLV() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); - m_Reg.SetMipsRegLo(m_Command.rd, m_Reg.GetMipsRegLo(m_Command.rt) << (m_Reg.GetMipsRegLo(m_Command.rs) & 0x1F)); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_SRLV() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); - m_Reg.SetMipsRegLo(m_Command.rd, m_Reg.GetMipsRegLo(m_Command.rt) >> (m_Reg.GetMipsRegLo(m_Command.rs) & 0x1F)); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_SRAV() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); - m_Reg.SetMipsRegLo(m_Command.rd, m_Reg.GetMipsRegLo_S(m_Command.rt) >> (m_Reg.GetMipsRegLo(m_Command.rs) & 0x1F)); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_JR() -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - if (m_Reg.IsConst(m_Command.rs)) - { - Section->m_Jump.TargetPC = m_Reg.GetMipsRegLo(m_Command.rs); - } - else - { - Section->m_Jump.TargetPC = (uint32_t)-1; - } -#endif - m_NextInstruction = DELAY_SLOT; -} - -void LoopAnalysis::SPECIAL_JALR() -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - m_Reg.GetMipsRegLo(m_Command.rd) = m_PC + 8; - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); - if (m_Reg.IsConst(m_Command.rs)) { - Section->m_Jump.TargetPC = m_Reg.GetMipsRegLo(m_Command.rs); - } - else - { - Section->m_Jump.TargetPC = (uint32_t)-1; - } -#endif - m_NextInstruction = DELAY_SLOT; -} - -void LoopAnalysis::SPECIAL_SYSCALL(CCodeSection * Section) -{ -#ifdef CHECKED_BUILD - if (Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (Section->m_JumpSection != NULL && - Section->m_Jump.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } -#else - Section = Section; -#endif - m_NextInstruction = END_BLOCK; - m_PC -= 4; -} - -void LoopAnalysis::SPECIAL_BREAK(CCodeSection * Section) -{ -#ifdef CHECKED_BUILD - if (Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (Section->m_JumpSection != NULL && - Section->m_Jump.TargetPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } -#else - Section = Section; -#endif - m_NextInstruction = END_BLOCK; - m_PC -= 4; -} - -void LoopAnalysis::SPECIAL_MFHI() -{ - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_MTHI() -{ -} - -void LoopAnalysis::SPECIAL_MFLO() -{ - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_MTLO() -{ -} - -void LoopAnalysis::SPECIAL_DSLLV() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (uint64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) << (m_Reg.GetMipsRegLo(m_Command.rs) & 0x3F)); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSRLV() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (uint64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) >> (m_Reg.GetMipsRegLo(m_Command.rs) & 0x3F)); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSRAV() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg_S(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) >> (m_Reg.GetMipsRegLo(m_Command.rs) & 0x3F)); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_ADD() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_ADDU() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_SUB() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_SUBU() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_AND() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_OR() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_XOR() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_NOR() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_SLT() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_SLTU() -{ - if (m_Command.rd == 0) { return; } - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); -} - -void LoopAnalysis::SPECIAL_DADD() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsReg(m_Command.rd, - m_Reg.Is64Bit(m_Command.rs) ? m_Reg.GetMipsReg(m_Command.rs) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rs) + - m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) - ); - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DADDU() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsReg(m_Command.rd, - m_Reg.Is64Bit(m_Command.rs) ? m_Reg.GetMipsReg(m_Command.rs) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rs) + - m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) - ); - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSUB() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsReg(m_Command.rd, - m_Reg.Is64Bit(m_Command.rs) ? m_Reg.GetMipsReg(m_Command.rs) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rs) - - m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) - ); - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSUBU() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) - { - m_Reg.SetMipsReg(m_Command.rd, - m_Reg.Is64Bit(m_Command.rs) ? m_Reg.GetMipsReg(m_Command.rs) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rs) - - m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) - ); - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSLL() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) << m_Command.sa); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSRL() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (uint64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) >> m_Command.sa); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSRA() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - m_Reg.SetMipsReg_S(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg_S(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) >> m_Command.sa); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSLL32() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); - m_Reg.SetMipsReg(m_Command.rd, m_Reg.GetMipsRegLo(m_Command.rt) << (m_Command.sa + 32)); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSRL32() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); - m_Reg.SetMipsRegLo(m_Command.rd, (uint32_t)(m_Reg.GetMipsReg(m_Command.rt) >> (m_Command.sa + 32))); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } -} - -void LoopAnalysis::SPECIAL_DSRA32() -{ - if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt)) - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); - m_Reg.SetMipsRegLo(m_Command.rd, (uint32_t)(m_Reg.GetMipsReg_S(m_Command.rt) >> (m_Command.sa + 32))); - } - else - { - m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); - } +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include "LoopAnalysis.h" + +#include +#include +#include +#include +#include +#include + +#ifdef _DEBUG +#define CHECKED_BUILD 1 +#endif + +bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); + +LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) : +m_EnterSection(Section), +m_BlockInfo(CodeBlock), +m_PC((uint32_t)-1), +m_NextInstruction(NORMAL), +m_Test(m_BlockInfo->NextTest()) +{ + memset(&m_Command, 0, sizeof(m_Command)); +} + +LoopAnalysis::~LoopAnalysis() +{ + for (RegisterMap::iterator itr = m_EnterRegisters.begin(); itr != m_EnterRegisters.end(); itr++) + { + delete itr->second; + } + m_EnterRegisters.clear(); + + for (RegisterMap::iterator itr = m_ContinueRegisters.begin(); itr != m_ContinueRegisters.end(); itr++) + { + delete itr->second; + } + m_ContinueRegisters.clear(); + + for (RegisterMap::iterator itr = m_JumpRegisters.begin(); itr != m_JumpRegisters.end(); itr++) + { + delete itr->second; + } + m_JumpRegisters.clear(); +} + +bool LoopAnalysis::SetupRegisterForLoop() +{ + if (!m_EnterSection->m_InLoop) + { + return false; + } + CPU_Message("%s: Section ID: %d Test: %X", __FUNCTION__, m_EnterSection->m_SectionID, m_Test); + if (!CheckLoopRegisterUsage(m_EnterSection)) + { + return false; + } + + RegisterMap::iterator itr = m_EnterRegisters.find(m_EnterSection->m_SectionID); + if (itr == m_EnterRegisters.end()) + { + return false; + } + m_EnterSection->m_RegEnter = *(itr->second); + return true; +} + +bool LoopAnalysis::SetupEnterSection(CCodeSection * Section, bool & bChanged, bool & bSkipedSection) +{ + bChanged = false; + bSkipedSection = false; + if (Section->m_ParentSection.empty()) { g_Notify->BreakPoint(__FILE__, __LINE__); return true; } + + CPU_Message("%s: Block EnterPC: %X Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, m_BlockInfo->VAddrEnter(), Section->m_SectionID, m_Test, Section->m_Test, Section->m_CompiledLocation); + + bool bFirstParent = true; + CRegInfo RegEnter; + for (CCodeSection::SECTION_LIST::iterator iter = Section->m_ParentSection.begin(); iter != Section->m_ParentSection.end(); iter++) + { + CCodeSection * Parent = *iter; + + CPU_Message("%s: Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, Parent->m_SectionID, m_Test, Parent->m_Test, Parent->m_CompiledLocation); + if (Parent->m_Test != m_Test && (m_EnterSection != Section || Parent->m_CompiledLocation == NULL) && Parent->m_InLoop) + { + CPU_Message("%s: Ignore Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, Parent->m_SectionID, m_Test, Parent->m_Test, Parent->m_CompiledLocation); + bSkipedSection = true; + continue; + } + RegisterMap::iterator Continue_itr = m_ContinueRegisters.find(Parent->m_SectionID); + RegisterMap::iterator Jump_itr = m_JumpRegisters.find(Parent->m_SectionID); + + CCodeSection * TargetSection[] = { Parent->m_ContinueSection, Parent->m_JumpSection }; + CRegInfo * JumpRegInfo[] = + { + Continue_itr == m_ContinueRegisters.end() ? &Parent->m_Cont.RegSet : Continue_itr->second, + Jump_itr == m_JumpRegisters.end() ? &Parent->m_Jump.RegSet : Jump_itr->second + }; + + for (int i = 0; i < 2; i++) + { + if (TargetSection[i] != Section) { continue; } + if (bFirstParent) + { + bFirstParent = false; + RegEnter = *JumpRegInfo[i]; + } + else + { + if (*JumpRegInfo[i] == RegEnter) + { + continue; + } + + SyncRegState(RegEnter, *JumpRegInfo[i]); + } + } + } + + if (bFirstParent) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); + if (itr != m_EnterRegisters.end()) + { + if (SyncRegState(*(itr->second), RegEnter)) + { + bChanged = true; + } + } + else + { + m_EnterRegisters.insert(RegisterMap::value_type(Section->m_SectionID, new CRegInfo(RegEnter))); + } + return true; +} + +bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section) +{ + if (Section == NULL) { return true; } + if (!Section->m_InLoop) { return true; } + + CPU_Message("%s: Section %d Block PC: 0x%X", __FUNCTION__, Section->m_SectionID, m_BlockInfo->VAddrEnter()); + + bool bChanged = false, bSkipedSection = false; + if (Section == m_EnterSection && Section->m_Test == m_Test) + { + if (!SetupEnterSection(Section, bChanged, bSkipedSection)) { return false; } + return true; + } + + if (!SetupEnterSection(Section, bChanged, bSkipedSection)) { return false; } + + if (Section->m_Test == m_Test && !bChanged) + { + return true; + } + + CPU_Message("%s: Set Section %d test to %X from %X", __FUNCTION__, Section->m_SectionID, m_Test, Section->m_Test); + Section->m_Test = m_Test; + m_PC = Section->m_EnterPC; + + RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); + m_Reg = itr != m_EnterRegisters.end() ? *(itr->second) : Section->m_RegEnter; + + m_NextInstruction = NORMAL; + uint32_t ContinueSectionPC = Section->m_ContinueSection ? Section->m_ContinueSection->m_EnterPC : (uint32_t)-1; + CPU_Message("ContinueSectionPC = %08X", ContinueSectionPC); + + do + { + if (!g_MMU->LW_VAddr(m_PC, m_Command.Hex)) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; + } + CPU_Message(" %08X: %s", m_PC, R4300iOpcodeName(m_Command.Hex, m_PC)); + CPU_Message(" %s state: %X value: %X", CRegName::GPR[3], m_Reg.GetMipsRegState(3), m_Reg.GetMipsRegLo(3)); + switch (m_Command.op) + { + case R4300i_SPECIAL: + switch (m_Command.funct) + { + case R4300i_SPECIAL_SLL: SPECIAL_SLL(); break; + case R4300i_SPECIAL_SRL: SPECIAL_SRL(); break; + case R4300i_SPECIAL_SRA: SPECIAL_SRA(); break; + case R4300i_SPECIAL_SLLV: SPECIAL_SLLV(); break; + case R4300i_SPECIAL_SRLV: SPECIAL_SRLV(); break; + case R4300i_SPECIAL_SRAV: SPECIAL_SRAV(); break; + case R4300i_SPECIAL_JR: SPECIAL_JR(); break; + case R4300i_SPECIAL_JALR: SPECIAL_JALR(); break; + case R4300i_SPECIAL_SYSCALL: SPECIAL_SYSCALL(Section); break; + case R4300i_SPECIAL_BREAK: SPECIAL_BREAK(Section); break; + case R4300i_SPECIAL_MFHI: SPECIAL_MFHI(); break; + case R4300i_SPECIAL_MTHI: SPECIAL_MTHI(); break; + case R4300i_SPECIAL_MFLO: SPECIAL_MFLO(); break; + case R4300i_SPECIAL_MTLO: SPECIAL_MTLO(); break; + case R4300i_SPECIAL_DSLLV: SPECIAL_DSLLV(); break; + case R4300i_SPECIAL_DSRLV: SPECIAL_DSRLV(); break; + case R4300i_SPECIAL_DSRAV: SPECIAL_DSRAV(); break; + case R4300i_SPECIAL_MULT: break; + case R4300i_SPECIAL_MULTU: break; + case R4300i_SPECIAL_DIV: break; + case R4300i_SPECIAL_DIVU: break; + case R4300i_SPECIAL_DMULT: break; + case R4300i_SPECIAL_DMULTU: break; + case R4300i_SPECIAL_DDIV: break; + case R4300i_SPECIAL_DDIVU: break; + case R4300i_SPECIAL_ADD: SPECIAL_ADD(); break; + case R4300i_SPECIAL_ADDU: SPECIAL_ADDU(); break; + case R4300i_SPECIAL_SUB: SPECIAL_SUB(); break; + case R4300i_SPECIAL_SUBU: SPECIAL_SUBU(); break; + case R4300i_SPECIAL_AND: SPECIAL_AND(); break; + case R4300i_SPECIAL_OR: SPECIAL_OR(); break; + case R4300i_SPECIAL_XOR: SPECIAL_XOR(); break; + case R4300i_SPECIAL_NOR: SPECIAL_NOR(); break; + case R4300i_SPECIAL_SLT: SPECIAL_SLT(); break; + case R4300i_SPECIAL_SLTU: SPECIAL_SLTU(); break; + case R4300i_SPECIAL_DADD: SPECIAL_DADD(); break; + case R4300i_SPECIAL_DADDU: SPECIAL_DADDU(); break; + case R4300i_SPECIAL_DSUB: SPECIAL_DSUB(); break; + case R4300i_SPECIAL_DSUBU: SPECIAL_DSUBU(); break; + case R4300i_SPECIAL_DSLL: SPECIAL_DSLL(); break; + case R4300i_SPECIAL_DSRL: SPECIAL_DSRL(); break; + case R4300i_SPECIAL_DSRA: SPECIAL_DSRA(); break; + case R4300i_SPECIAL_DSLL32: SPECIAL_DSLL32(); break; + case R4300i_SPECIAL_DSRL32: SPECIAL_DSRL32(); break; + case R4300i_SPECIAL_DSRA32: SPECIAL_DSRA32(); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + if (m_Command.Hex == 0x00000001) { break; } + g_Notify->DisplayError("Unhandled R4300i OpCode in FillSectionInfo 5\n%s", + R4300iOpcodeName(m_Command.Hex, m_PC)); +#endif + m_NextInstruction = END_BLOCK; + m_PC -= 4; + } + break; + case R4300i_REGIMM: + switch (m_Command.rt) + { + case R4300i_REGIMM_BLTZ: + case R4300i_REGIMM_BGEZ: + m_NextInstruction = DELAY_SLOT; +#ifdef CHECKED_BUILD + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4 && + Section->m_JumpSection != NULL && + Section->m_Jump.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_PC == Section->m_Jump.TargetPC) + { + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0) && !Section->m_Jump.PermLoop) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } +#endif + break; + case R4300i_REGIMM_BLTZL: + case R4300i_REGIMM_BGEZL: + m_NextInstruction = LIKELY_DELAY_SLOT; +#ifdef CHECKED_BUILD + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (Section->m_Jump.TargetPC != m_PC + 4 && + Section->m_JumpSection != NULL && + Section->m_Jump.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + /*if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + }*/ + if (m_PC == m_PC + ((int16_t)m_Command.offset << 2) + 4) + { + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0) && !Section->m_Jump.PermLoop) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } +#endif + break; + case R4300i_REGIMM_BLTZAL: + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + m_Reg.GetMipsRegLo(31) = m_PC + 8; + m_Reg.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + Section->m_Cont.TargetPC = m_PC + 8; + Section->m_Jump.TargetPC = m_PC + ((int16_t)m_Command.offset << 2) + 4; + if (m_PC == Section->m_Jump.TargetPC) + { + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0)) + { + Section->m_Jump.PermLoop = true; + } + } +#endif + break; + case R4300i_REGIMM_BGEZAL: + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + m_NextInstruction = DELAY_SLOT; + if (m_Reg.IsConst(m_Command.rs)) + { + int64_t Value; + if (m_Reg.Is32Bit(m_Command.rs)) + { + Value = m_Reg.GetMipsRegLo_S(m_Command.rs); + } + else { + Value = m_Reg.GetMipsReg_S(m_Command.rs); + } + if (Value >= 0) + { + m_Reg.GetMipsRegLo(31) = m_PC + 8; + m_Reg.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + Section->m_Jump.TargetPC = m_PC + ((int16_t)m_Command.offset << 2) + 4; + if (m_PC == Section->m_Jump.TargetPC) + { + if (!DelaySlotEffectsCompare(m_PC, 31, 0)) + { + Section->m_Jump.PermLoop = true; + } + } + break; + } + } + + m_Reg.GetMipsRegLo(31) = m_PC + 8; + m_Reg.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + Section->m_Cont.TargetPC = m_PC + 8; + Section->m_Jump.TargetPC = m_PC + ((int16_t)m_Command.offset << 2) + 4; + if (m_PC == Section->m_Jump.TargetPC) + { + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0)) + { + Section->m_Jump.PermLoop = true; + } + } +#endif + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + if (m_Command.Hex == 0x0407000D) { break; } + g_Notify->DisplayError("Unhandled R4300i OpCode in FillSectionInfo 4\n%s", + R4300iOpcodeName(m_Command.Hex, m_PC)); + m_NextInstruction = END_BLOCK; + m_PC -= 4; +#endif + } + break; + case R4300i_JAL: + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + m_NextInstruction = DELAY_SLOT; + m_Reg.GetMipsRegLo(31) = m_PC + 8; + m_Reg.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + Section->m_Jump.TargetPC = (m_PC & 0xF0000000) + (m_Command.target << 2); + if (m_PC == Section->m_Jump.TargetPC) + { + if (!DelaySlotEffectsCompare(m_PC, 31, 0)) + { + Section->m_Jump.PermLoop = true; + } + } +#endif + break; + case R4300i_J: + m_NextInstruction = DELAY_SLOT; +#ifdef CHECKED_BUILD + if (Section->m_Jump.TargetPC != (m_PC & 0xF0000000) + (m_Command.target << 2)) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_PC == Section->m_Jump.TargetPC && !Section->m_Jump.PermLoop) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } +#endif + break; + case R4300i_BEQ: + if (m_PC + ((int16_t)m_Command.offset << 2) + 4 != m_PC + 8) + { + m_NextInstruction = DELAY_SLOT; +#ifdef CHECKED_BUILD + if (m_Command.rs != 0 || m_Command.rt != 0) + { + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + else + { + if (Section->m_Cont.TargetPC != (uint32_t)-1) + { + //g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4) + { + //g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_PC == Section->m_Jump.TargetPC) + { + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } +#endif + } + break; + case R4300i_BNE: + case R4300i_BLEZ: + case R4300i_BGTZ: + if (m_PC + ((int16_t)m_Command.offset << 2) + 4 != m_PC + 8) + { + m_NextInstruction = DELAY_SLOT; +#ifdef CHECKED_BUILD + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4 && + Section->m_JumpSection != NULL && + Section->m_Jump.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_PC == Section->m_Jump.TargetPC) + { + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } +#endif + } + break; + case R4300i_ADDI: + case R4300i_ADDIU: + if (m_Command.rt == 0) { break; } + /*if (m_Command.rs == 0) { + m_Reg.GetMipsRegLo(m_Command.rt) = (int16_t)m_Command.immediate; + m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_CONST_32_SIGN); + } else {*/ + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + //} + break; + case R4300i_SLTI: + case R4300i_SLTIU: + if (m_Command.rt == 0) { break; } + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + break; + case R4300i_LUI: + if (m_Command.rt == 0) { break; } + if (!m_Reg.IsModified(m_Command.rt)) + { + m_Reg.SetMipsRegLo(m_Command.rt, ((int16_t)m_Command.offset << 16)); + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_CONST_32_SIGN); + } + break; + case R4300i_ANDI: + if (m_Command.rt == 0) { break; } + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + break; + case R4300i_ORI: + if (m_Command.rt == 0) { break; } + if (m_Command.rs == m_Command.rt) + { + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rs)) { + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_CONST_32_SIGN); + m_Reg.SetMipsRegLo(m_Command.rt, m_Reg.GetMipsRegLo(m_Command.rs) | m_Command.immediate); + } + else { + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + } + break; + case R4300i_XORI: + if (m_Command.rt == 0) { break; } + if (m_Command.rs == m_Command.rt) + { + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_CONST_32_SIGN); + m_Reg.SetMipsRegLo(m_Command.rt, m_Reg.GetMipsRegLo(m_Command.rs) ^ m_Command.immediate); + } + else + { + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + } + break; + case R4300i_CP0: + switch (m_Command.rs) + { + case R4300i_COP0_MF: + if (m_Command.rt == 0) { break; } + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + break; + case R4300i_COP0_MT: break; + default: + if ((m_Command.rs & 0x10) != 0) + { + switch (m_Command.funct) + { + case R4300i_COP0_CO_TLBR: break; + case R4300i_COP0_CO_TLBWI: break; + case R4300i_COP0_CO_TLBWR: break; + case R4300i_COP0_CO_TLBP: break; + case R4300i_COP0_CO_ERET: m_NextInstruction = END_BLOCK; break; + default: + g_Notify->DisplayError(stdstr_f("Unhandled R4300i OpCode in FillSectionInfo\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); + m_NextInstruction = END_BLOCK; + m_PC -= 4; + } + } + else + { + g_Notify->DisplayError(stdstr_f("Unhandled R4300i OpCode in FillSectionInfo 3\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); + m_NextInstruction = END_BLOCK; + m_PC -= 4; + } + } + break; + case R4300i_CP1: + switch (m_Command.fmt) + { + case R4300i_COP1_CF: + case R4300i_COP1_MF: + case R4300i_COP1_DMF: + if (m_Command.rt == 0) { break; } + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + break; + case R4300i_COP1_BC: + switch (m_Command.ft) + { + case R4300i_COP1_BC_BCFL: + case R4300i_COP1_BC_BCTL: + m_NextInstruction = LIKELY_DELAY_SLOT; +#ifdef CHECKED_BUILD + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_PC == m_PC + ((int16_t)m_Command.offset << 2) + 4) + { + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt)) + { + if (!Section->m_Jump.PermLoop) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } +#endif + } +#endif + break; + case R4300i_COP1_BC_BCF: + case R4300i_COP1_BC_BCT: + m_NextInstruction = DELAY_SLOT; +#ifdef CHECKED_BUILD + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_PC == Section->m_Jump.TargetPC) + { + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt)) { + Section->m_Jump.PermLoop = true; + } +#endif + } +#endif + break; + } + break; + case R4300i_COP1_MT: break; + case R4300i_COP1_DMT: break; + case R4300i_COP1_CT: break; + case R4300i_COP1_S: break; + case R4300i_COP1_D: break; + case R4300i_COP1_W: break; + case R4300i_COP1_L: break; + default: + g_Notify->DisplayError(stdstr_f("Unhandled R4300i OpCode in FillSectionInfo 2\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); + m_NextInstruction = END_BLOCK; + m_PC -= 4; + } + break; + case R4300i_BEQL: + case R4300i_BNEL: + case R4300i_BLEZL: + case R4300i_BGTZL: + m_NextInstruction = LIKELY_DELAY_SLOT; +#ifdef CHECKED_BUILD + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (Section->m_Jump.TargetPC != m_PC + 4) + { + //g_Notify->BreakPoint(__FILE__, __LINE__); + } + /*if (Section->m_Jump.TargetPC != m_PC + ((int16_t)m_Command.offset << 2) + 4) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + }*/ + if (m_PC == m_PC + ((int16_t)m_Command.offset << 2) + 4) + { + if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } +#endif + break; + case R4300i_DADDI: + case R4300i_DADDIU: + if (m_Command.rt == 0) { break; } + if (m_Command.rs == m_Command.rt) + { + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rs)) + { + if (m_Reg.Is64Bit(m_Command.rs)) + { + int imm32 = (int16_t)m_Command.immediate; + int64_t imm64 = imm32; + m_Reg.SetMipsReg_S(m_Command.rt, m_Reg.GetMipsRegLo_S(m_Command.rs) + imm64); + } + else + { + m_Reg.SetMipsReg_S(m_Command.rt, m_Reg.GetMipsRegLo_S(m_Command.rs) + (int16_t)m_Command.immediate); + } + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_CONST_64); + } + else + { + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + } + break; + case R4300i_LDR: + case R4300i_LDL: + case R4300i_LB: + case R4300i_LH: + case R4300i_LWL: + case R4300i_LW: + case R4300i_LWU: + case R4300i_LL: + case R4300i_LBU: + case R4300i_LHU: + case R4300i_LWR: + case R4300i_SC: + if (m_Command.rt == 0) { break; } + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + break; + case R4300i_SB: break; + case R4300i_SH: break; + case R4300i_SWL: break; + case R4300i_SW: break; + case R4300i_SWR: break; + case R4300i_SDL: break; + case R4300i_SDR: break; + case R4300i_CACHE: break; + case R4300i_LWC1: break; + case R4300i_SWC1: break; + case R4300i_LDC1: break; + case R4300i_LD: + if (m_Command.rt == 0) { break; } + m_Reg.SetMipsRegState(m_Command.rt, CRegInfo::STATE_MODIFIED); + break; + case R4300i_SDC1: break; + case R4300i_SD: break; + default: + m_NextInstruction = END_BLOCK; + m_PC -= 4; + if (m_Command.Hex == 0x7C1C97C0) { break; } + if (m_Command.Hex == 0x7FFFFFFF) { break; } + if (m_Command.Hex == 0xF1F3F5F7) { break; } + if (m_Command.Hex == 0xC1200000) { break; } + if (m_Command.Hex == 0x4C5A5353) { break; } + g_Notify->DisplayError(stdstr_f("Unhandled R4300i OpCode in FillSectionInfo 1\n%s\n%X", R4300iOpcodeName(m_Command.Hex, m_PC), m_Command.Hex).c_str()); + } + + CPU_Message(" %s state: %X value: %X", CRegName::GPR[5], m_Reg.GetMipsRegState(5), m_Reg.GetMipsRegLo(5)); + + if (Section->m_DelaySlot) + { + if (m_NextInstruction != NORMAL && m_NextInstruction != END_BLOCK) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + m_NextInstruction = END_BLOCK; + SetJumpRegSet(Section, m_Reg); + } + else { + switch (m_NextInstruction) + { + case NORMAL: + m_PC += 4; + break; + case DELAY_SLOT: + m_NextInstruction = DELAY_SLOT_DONE; + m_PC += 4; + if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000)) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + break; + case LIKELY_DELAY_SLOT: + { + SetContinueRegSet(Section, m_Reg); + SetJumpRegSet(Section, m_Reg); + } + m_NextInstruction = END_BLOCK; + break; + case DELAY_SLOT_DONE: + { + SetContinueRegSet(Section, m_Reg); + SetJumpRegSet(Section, m_Reg); + } + m_NextInstruction = END_BLOCK; + break; + case LIKELY_DELAY_SLOT_DONE: + g_Notify->BreakPoint(__FILE__, __LINE__); + if (Section->m_CompiledLocation) + { + } + else + { + //Section->m_Jump.RegSet = m_Reg; + //Section->m_Jump.DoneDelaySlot = true; + } + m_NextInstruction = END_BLOCK; + break; + } + } + + if (m_PC == ContinueSectionPC) + { + m_NextInstruction = END_BLOCK; + SetContinueRegSet(Section, m_Reg); + } + + if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000)) + { + if (m_NextInstruction != END_BLOCK && m_NextInstruction != NORMAL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } while (m_NextInstruction != END_BLOCK); + + if (!CheckLoopRegisterUsage(Section->m_ContinueSection)) { return false; } + if (!CheckLoopRegisterUsage(Section->m_JumpSection)) { return false; } + return true; +} + +bool LoopAnalysis::SyncRegState(CRegInfo & RegSet, const CRegInfo& SyncReg) +{ + bool bChanged = false; + for (int x = 0; x < 32; x++) + { + if (RegSet.GetMipsRegState(x) != SyncReg.GetMipsRegState(x)) + { + CPU_Message("%s: Clear state %s RegEnter State: %X Jump Reg State: %X", __FUNCTION__, CRegName::GPR[x], RegSet.GetMipsRegState(x), SyncReg.GetMipsRegState(x)); + RegSet.SetMipsRegState(x, CRegInfo::STATE_MODIFIED); + bChanged = true; + } + else if (RegSet.IsConst(x) && RegSet.Is32Bit(x) && RegSet.GetMipsRegLo(x) != SyncReg.GetMipsRegLo(x)) + { + CPU_Message("%s: Clear state %s RegEnter State: %X Jump Reg State: %X", __FUNCTION__, CRegName::GPR[x], RegSet.GetMipsRegState(x), SyncReg.GetMipsRegState(x)); + RegSet.SetMipsRegState(x, CRegInfo::STATE_MODIFIED); + bChanged = true; + } + else if (RegSet.IsConst(x) && RegSet.Is64Bit(x) && RegSet.GetMipsReg_S(x) != SyncReg.GetMipsReg_S(x)) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + return bChanged; +} + +void LoopAnalysis::SetJumpRegSet(CCodeSection * Section, const CRegInfo &Reg) +{ + RegisterMap::iterator itr = m_JumpRegisters.find(Section->m_SectionID); + if (itr != m_JumpRegisters.end()) + { + *(itr->second) = Reg; + } + else + { + m_JumpRegisters.insert(RegisterMap::value_type(Section->m_SectionID, new CRegInfo(Reg))); + } +} + +void LoopAnalysis::SetContinueRegSet(CCodeSection * Section, const CRegInfo &Reg) +{ + RegisterMap::iterator itr = m_ContinueRegisters.find(Section->m_SectionID); + if (itr != m_ContinueRegisters.end()) + { + *(itr->second) = Reg; + } + else + { + m_ContinueRegisters.insert(RegisterMap::value_type(Section->m_SectionID, new CRegInfo(Reg))); + } +} + +void LoopAnalysis::SPECIAL_SLL() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_SRL() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_SRA() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_SLLV() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); + m_Reg.SetMipsRegLo(m_Command.rd, m_Reg.GetMipsRegLo(m_Command.rt) << (m_Reg.GetMipsRegLo(m_Command.rs) & 0x1F)); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_SRLV() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); + m_Reg.SetMipsRegLo(m_Command.rd, m_Reg.GetMipsRegLo(m_Command.rt) >> (m_Reg.GetMipsRegLo(m_Command.rs) & 0x1F)); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_SRAV() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); + m_Reg.SetMipsRegLo(m_Command.rd, m_Reg.GetMipsRegLo_S(m_Command.rt) >> (m_Reg.GetMipsRegLo(m_Command.rs) & 0x1F)); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_JR() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + if (m_Reg.IsConst(m_Command.rs)) + { + Section->m_Jump.TargetPC = m_Reg.GetMipsRegLo(m_Command.rs); + } + else + { + Section->m_Jump.TargetPC = (uint32_t)-1; + } +#endif + m_NextInstruction = DELAY_SLOT; +} + +void LoopAnalysis::SPECIAL_JALR() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + m_Reg.GetMipsRegLo(m_Command.rd) = m_PC + 8; + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); + if (m_Reg.IsConst(m_Command.rs)) { + Section->m_Jump.TargetPC = m_Reg.GetMipsRegLo(m_Command.rs); + } + else + { + Section->m_Jump.TargetPC = (uint32_t)-1; + } +#endif + m_NextInstruction = DELAY_SLOT; +} + +void LoopAnalysis::SPECIAL_SYSCALL(CCodeSection * Section) +{ +#ifdef CHECKED_BUILD + if (Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (Section->m_JumpSection != NULL && + Section->m_Jump.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } +#else + Section = Section; +#endif + m_NextInstruction = END_BLOCK; + m_PC -= 4; +} + +void LoopAnalysis::SPECIAL_BREAK(CCodeSection * Section) +{ +#ifdef CHECKED_BUILD + if (Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (Section->m_JumpSection != NULL && + Section->m_Jump.TargetPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } +#else + Section = Section; +#endif + m_NextInstruction = END_BLOCK; + m_PC -= 4; +} + +void LoopAnalysis::SPECIAL_MFHI() +{ + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_MTHI() +{ +} + +void LoopAnalysis::SPECIAL_MFLO() +{ + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_MTLO() +{ +} + +void LoopAnalysis::SPECIAL_DSLLV() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (uint64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) << (m_Reg.GetMipsRegLo(m_Command.rs) & 0x3F)); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSRLV() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (uint64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) >> (m_Reg.GetMipsRegLo(m_Command.rs) & 0x3F)); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSRAV() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg_S(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) >> (m_Reg.GetMipsRegLo(m_Command.rs) & 0x3F)); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_ADD() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_ADDU() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_SUB() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_SUBU() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_AND() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_OR() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_XOR() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_NOR() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_SLT() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_SLTU() +{ + if (m_Command.rd == 0) { return; } + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); +} + +void LoopAnalysis::SPECIAL_DADD() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsReg(m_Command.rd, + m_Reg.Is64Bit(m_Command.rs) ? m_Reg.GetMipsReg(m_Command.rs) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rs) + + m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) + ); + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DADDU() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsReg(m_Command.rd, + m_Reg.Is64Bit(m_Command.rs) ? m_Reg.GetMipsReg(m_Command.rs) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rs) + + m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) + ); + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSUB() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsReg(m_Command.rd, + m_Reg.Is64Bit(m_Command.rs) ? m_Reg.GetMipsReg(m_Command.rs) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rs) - + m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) + ); + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSUBU() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) + { + m_Reg.SetMipsReg(m_Command.rd, + m_Reg.Is64Bit(m_Command.rs) ? m_Reg.GetMipsReg(m_Command.rs) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rs) - + m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) + ); + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSLL() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) << m_Command.sa); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSRL() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + m_Reg.SetMipsReg(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg(m_Command.rt) : (uint64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) >> m_Command.sa); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSRA() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + m_Reg.SetMipsReg_S(m_Command.rd, m_Reg.Is64Bit(m_Command.rt) ? m_Reg.GetMipsReg_S(m_Command.rt) : (int64_t)m_Reg.GetMipsRegLo_S(m_Command.rt) >> m_Command.sa); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSLL32() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_64); + m_Reg.SetMipsReg(m_Command.rd, m_Reg.GetMipsRegLo(m_Command.rt) << (m_Command.sa + 32)); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSRL32() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); + m_Reg.SetMipsRegLo(m_Command.rd, (uint32_t)(m_Reg.GetMipsReg(m_Command.rt) >> (m_Command.sa + 32))); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } +} + +void LoopAnalysis::SPECIAL_DSRA32() +{ + if (m_Command.rd == 0) { return; } + if (m_Command.rt == m_Command.rd) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } + if (m_Reg.IsConst(m_Command.rt)) + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_CONST_32_SIGN); + m_Reg.SetMipsRegLo(m_Command.rd, (uint32_t)(m_Reg.GetMipsReg_S(m_Command.rt) >> (m_Command.sa + 32))); + } + else + { + m_Reg.SetMipsRegState(m_Command.rd, CRegInfo::STATE_MODIFIED); + } } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.h b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.h index d828b18fd..b4de7b6a5 100644 --- a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.h +++ b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.h @@ -1,89 +1,89 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include -#include - -class CCodeSection; -class CCodeBlock; - -class LoopAnalysis -{ -public: - LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section); - ~LoopAnalysis(); - - bool SetupRegisterForLoop(); - -private: - LoopAnalysis(); // Disable default constructor - LoopAnalysis(const LoopAnalysis&); // Disable copy constructor - LoopAnalysis& operator=(const LoopAnalysis&); // Disable assignment - - bool SetupEnterSection(CCodeSection * Section, bool & bChanged, bool & bSkipedSection); - bool CheckLoopRegisterUsage(CCodeSection * Section); - bool SyncRegState(CRegInfo & RegSet, const CRegInfo& SyncReg); - void SetJumpRegSet(CCodeSection * Section, const CRegInfo &Reg); - void SetContinueRegSet(CCodeSection * Section, const CRegInfo &Reg); - - /********************** R4300i OpCodes: Special **********************/ - void SPECIAL_SLL(); - void SPECIAL_SRL(); - void SPECIAL_SRA(); - void SPECIAL_SLLV(); - void SPECIAL_SRLV(); - void SPECIAL_SRAV(); - void SPECIAL_JR(); - void SPECIAL_JALR(); - void SPECIAL_SYSCALL(CCodeSection * Section); - void SPECIAL_BREAK(CCodeSection * Section); - void SPECIAL_MFHI(); - void SPECIAL_MTHI(); - void SPECIAL_MFLO(); - void SPECIAL_MTLO(); - void SPECIAL_DSLLV(); - void SPECIAL_DSRLV(); - void SPECIAL_DSRAV(); - void SPECIAL_ADD(); - void SPECIAL_ADDU(); - void SPECIAL_SUB(); - void SPECIAL_SUBU(); - void SPECIAL_AND(); - void SPECIAL_OR(); - void SPECIAL_XOR(); - void SPECIAL_NOR(); - void SPECIAL_SLT(); - void SPECIAL_SLTU(); - void SPECIAL_DADD(); - void SPECIAL_DADDU(); - void SPECIAL_DSUB(); - void SPECIAL_DSUBU(); - void SPECIAL_DSLL(); - void SPECIAL_DSRL(); - void SPECIAL_DSRA(); - void SPECIAL_DSLL32(); - void SPECIAL_DSRL32(); - void SPECIAL_DSRA32(); - - typedef std::map RegisterMap; - - RegisterMap m_EnterRegisters; - RegisterMap m_ContinueRegisters; - RegisterMap m_JumpRegisters; - CCodeSection * m_EnterSection; - CCodeBlock * m_BlockInfo; - uint32_t m_PC; - CRegInfo m_Reg; - STEP_TYPE m_NextInstruction; - OPCODE m_Command; - uint32_t m_Test; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include +#include + +class CCodeSection; +class CCodeBlock; + +class LoopAnalysis +{ +public: + LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section); + ~LoopAnalysis(); + + bool SetupRegisterForLoop(); + +private: + LoopAnalysis(); // Disable default constructor + LoopAnalysis(const LoopAnalysis&); // Disable copy constructor + LoopAnalysis& operator=(const LoopAnalysis&); // Disable assignment + + bool SetupEnterSection(CCodeSection * Section, bool & bChanged, bool & bSkipedSection); + bool CheckLoopRegisterUsage(CCodeSection * Section); + bool SyncRegState(CRegInfo & RegSet, const CRegInfo& SyncReg); + void SetJumpRegSet(CCodeSection * Section, const CRegInfo &Reg); + void SetContinueRegSet(CCodeSection * Section, const CRegInfo &Reg); + + /********************** R4300i OpCodes: Special **********************/ + void SPECIAL_SLL(); + void SPECIAL_SRL(); + void SPECIAL_SRA(); + void SPECIAL_SLLV(); + void SPECIAL_SRLV(); + void SPECIAL_SRAV(); + void SPECIAL_JR(); + void SPECIAL_JALR(); + void SPECIAL_SYSCALL(CCodeSection * Section); + void SPECIAL_BREAK(CCodeSection * Section); + void SPECIAL_MFHI(); + void SPECIAL_MTHI(); + void SPECIAL_MFLO(); + void SPECIAL_MTLO(); + void SPECIAL_DSLLV(); + void SPECIAL_DSRLV(); + void SPECIAL_DSRAV(); + void SPECIAL_ADD(); + void SPECIAL_ADDU(); + void SPECIAL_SUB(); + void SPECIAL_SUBU(); + void SPECIAL_AND(); + void SPECIAL_OR(); + void SPECIAL_XOR(); + void SPECIAL_NOR(); + void SPECIAL_SLT(); + void SPECIAL_SLTU(); + void SPECIAL_DADD(); + void SPECIAL_DADDU(); + void SPECIAL_DSUB(); + void SPECIAL_DSUBU(); + void SPECIAL_DSLL(); + void SPECIAL_DSRL(); + void SPECIAL_DSRA(); + void SPECIAL_DSLL32(); + void SPECIAL_DSRL32(); + void SPECIAL_DSRA32(); + + typedef std::map RegisterMap; + + RegisterMap m_EnterRegisters; + RegisterMap m_ContinueRegisters; + RegisterMap m_JumpRegisters; + CCodeSection * m_EnterSection; + CCodeBlock * m_BlockInfo; + uint32_t m_PC; + CRegInfo m_Reg; + STEP_TYPE m_NextInstruction; + OPCODE m_Command; + uint32_t m_Test; +}; diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerClass.cpp b/Source/Project64-core/N64System/Recompiler/RecompilerClass.cpp index e85867ef3..90e875868 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerClass.cpp +++ b/Source/Project64-core/N64System/Recompiler/RecompilerClass.cpp @@ -1,1063 +1,1063 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include -#include -#include - -CRecompiler::CRecompiler(CRegisters & Registers, CProfiling & Profile, bool & EndEmulation) : -m_Registers(Registers), -m_Profile(Profile), -m_EndEmulation(EndEmulation), -PROGRAM_COUNTER(Registers.m_PROGRAM_COUNTER) -{ - if (g_MMU != NULL) - { - ResetMemoryStackPos(); - } -} - -CRecompiler::~CRecompiler() -{ - ResetRecompCode(false); -} - -void CRecompiler::Run() -{ - if (bLogX86Code()) - { - Start_x86_Log(); - } - - if (!CRecompMemory::AllocateMemory()) - { - WriteTrace(TraceRecompiler, TraceError, "AllocateMemory failed"); - return; - } - if (!CFunctionMap::AllocateMemory()) - { - WriteTrace(TraceRecompiler, TraceError, "AllocateMemory failed"); - return; - } - m_EndEmulation = false; - -#ifdef legacycode - *g_MemoryStack = (uint32_t)(RDRAM+(_GPR[29].W[0] & 0x1FFFFFFF)); -#endif - __except_try() - { - if (g_System->LookUpMode() == FuncFind_VirtualLookup) - { - if (g_System->bSMM_ValidFunc()) - { - RecompilerMain_VirtualTable_validate(); - } - else - { - RecompilerMain_VirtualTable(); - } - } - else if (g_System->LookUpMode() == FuncFind_ChangeMemory) - { - RecompilerMain_ChangeMemory(); - } - else - { - if (g_System->bUseTlb()) - { - if (g_System->bSMM_ValidFunc()) - { - RecompilerMain_Lookup_validate_TLB(); - } - else - { - RecompilerMain_Lookup_TLB(); - } - } - else - { - if (g_System->bSMM_ValidFunc()) - { - RecompilerMain_Lookup_validate(); - } - else - { - RecompilerMain_Lookup(); - } - } - } - } - __except_catch() - { - g_Notify->DisplayError(MSG_UNKNOWN_MEM_ACTION); - } -} - -void CRecompiler::RecompilerMain_VirtualTable() -{ - bool & Done = m_EndEmulation; - uint32_t & PC = PROGRAM_COUNTER; - - while (!Done) - { - if (!g_TransVaddr->ValidVaddr(PC)) - { - m_Registers.DoTLBReadMiss(false, PC); - if (!g_TransVaddr->ValidVaddr(PC)) - { - g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PC).c_str()); - return; - } - continue; - } - - PCCompiledFunc_TABLE & table = FunctionTable()[PC >> 0xC]; - uint32_t TableEntry = (PC & 0xFFF) >> 2; - if (table) - { - CCompiledFunc * info = table[TableEntry]; - if (info != NULL) - { - (info->Function())(); - continue; - } - } - CCompiledFunc * info = CompilerCode(); - if (info == NULL || m_EndEmulation) - { - break; - } - - if (table == NULL) - { - table = new PCCompiledFunc[(0x1000 >> 2)]; - if (table == NULL) - { - WriteTrace(TraceRecompiler, TraceError, "failed to allocate PCCompiledFunc"); - g_Notify->FatalError(MSG_MEM_ALLOC_ERROR); - } - memset(table, 0, sizeof(PCCompiledFunc) * (0x1000 >> 2)); - if (g_System->bSMM_Protect()) - { - WriteTrace(TraceRecompiler, TraceError, "Create Table (%X): Index = %d", table, PC >> 0xC); - g_MMU->ProtectMemory(PC & ~0xFFF, PC | 0xFFF); - } - } - - table[TableEntry] = info; - (info->Function())(); - } -} - -void CRecompiler::RecompilerMain_VirtualTable_validate() -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - /* PCCompiledFunc_TABLE * m_FunctionTable = m_Functions.GetFunctionTable(); - - while(!m_EndEmulation) - { - /*if (NextInstruction == DELAY_SLOT) - { - CCompiledFunc * Info = m_FunctionsDelaySlot.FindFunction(PROGRAM_COUNTER); - //Find Block on hash table - if (Info == NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - #ifdef legacycode - if (!g_TLB->ValidVaddr(PROGRAM_COUNTER)) - { - DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); - NextInstruction = NORMAL; - if (!g_TLB->ValidVaddr(PROGRAM_COUNTER)) - { - g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); - return; - } - continue; - } - #endif - //Find Block on hash table - Info = CompileDelaySlot(PROGRAM_COUNTER); - - if (Info == NULL || EndEmulation()) - { - break; - } - } - const uint8_t * Block = Info->FunctionAddr(); - if ((*Info->MemLocation[0] != Info->MemContents[0]) || - (*Info->MemLocation[1] != Info->MemContents[1])) - { - ClearRecompCode_Virt((Info->VStartPC() - 0x1000) & ~0xFFF,0x2000,Remove_ValidateFunc); - NextInstruction = DELAY_SLOT; - Info = NULL; - continue; - } - _asm { - pushad - call Block - popad - } - continue; - }*/ - /* PCCompiledFunc_TABLE table = m_FunctionTable[PROGRAM_COUNTER >> 0xC]; - if (table) - { - CCompiledFunc * info = table[(PROGRAM_COUNTER & 0xFFF) >> 2]; - if (info != NULL) - { - if ((*info->MemLocation[0] != info->MemContents[0]) || - (*info->MemLocation[1] != info->MemContents[1])) - { - ClearRecompCode_Virt((info->VStartPC() - 0x1000) & ~0xFFF,0x3000,Remove_ValidateFunc); - info = NULL; - continue; - } - const uint8_t * Block = info->FunctionAddr(); - _asm { - pushad - call Block - popad - } - continue; - } - } - g_Notify->BreakPoint(__FILE__, __LINE__); - #ifdef legacycode - if (!g_TLB->ValidVaddr(PROGRAM_COUNTER)) - { - DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); - NextInstruction = NORMAL; - if (!g_TLB->ValidVaddr(PROGRAM_COUNTER)) - { - g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); - return; - } - } - #endif - CCompiledFunc * info = CompilerCode(); - - if (info == NULL || EndEmulation()) - { - break; - } - } - - /* - while(!m_EndEmulation) - { - if (!g_MMU->ValidVaddr(PROGRAM_COUNTER)) - { - DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); - NextInstruction = NORMAL; - if (!g_MMU->ValidVaddr(PROGRAM_COUNTER)) - { - g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); - return; - } - } - if (NextInstruction == DELAY_SLOT) - { - CCompiledFunc * Info = m_FunctionsDelaySlot.FindFunction(PROGRAM_COUNTER); - - //Find Block on hash table - if (Info == NULL) - { - Info = CompileDelaySlot(PROGRAM_COUNTER); - - if (Info == NULL || EndEmulation()) - { - break; - } - } - if (bSMM_ValidFunc()) - { - if ((*Info->MemLocation[0] != Info->MemContents[0]) || - (*Info->MemLocation[1] != Info->MemContents[1])) - { - ClearRecompCode_Virt((Info->StartPC() - 0x1000) & ~0xFFF,0x2000,Remove_ValidateFunc); - NextInstruction = DELAY_SLOT; - Info = NULL; - continue; - } - } - const uint8_t * Block = Info->FunctionAddr(); - _asm { - pushad - call Block - popad - } - continue; - } - - CCompiledFunc * Info = m_Functions.FindFunction(PROGRAM_COUNTER); - - //Find Block on hash table - if (Info == NULL) - { - Info = CompilerCode(); - - if (Info == NULL || EndEmulation()) - { - break; - } - } - if (bSMM_ValidFunc()) - { - if ((*Info->MemLocation[0] != Info->MemContents[0]) || - (*Info->MemLocation[1] != Info->MemContents[1])) - { - ClearRecompCode_Virt((Info->StartPC() - 0x1000) & ~0xFFF,0x3000,Remove_ValidateFunc); - Info = NULL; - continue; - } - } - const uint8_t * Block = Info->FunctionAddr(); - _asm { - pushad - call Block - popad - } - } - */ -} - -void CRecompiler::RecompilerMain_Lookup() -{ - while (!m_EndEmulation) - { - uint32_t PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF; - if (PhysicalAddr < g_System->RdramSize()) - { - CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; - if (info == NULL) - { - info = CompilerCode(); - if (info == NULL || m_EndEmulation) - { - break; - } - if (g_System->bSMM_Protect()) - { - g_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF, PROGRAM_COUNTER | 0xFFF); - } - JumpTable()[PhysicalAddr >> 2] = info; - } - (info->Function())(); - } - else - { - uint32_t opsExecuted = 0; - - while (g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize()) - { - CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); - opsExecuted += g_System->CountPerOp(); - } - - if (g_SyncSystem) - { - g_System->UpdateSyncCPU(g_SyncSystem, opsExecuted); - g_System->SyncCPU(g_SyncSystem); - } - } - } - /* - uint32_t Addr; - CCompiledFunc * Info; - //const uint8_t * Block; - - while(!m_EndEmulation) - { - /*if (bUseTlb()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - #ifdef legacycode - if (!g_TLB->TranslateVaddr(PROGRAM_COUNTER, Addr)) - { - DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); - NextInstruction = NORMAL; - if (!TranslateVaddr(PROGRAM_COUNTER, &Addr)) { - g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); - return; - } - } - #endif - } else { - Addr = PROGRAM_COUNTER & 0x1FFFFFFF; - }*/ - - /* if (NextInstruction == DELAY_SLOT) { - CCompiledFunc * Info = m_FunctionsDelaySlot.FindFunction(PROGRAM_COUNTER); - - //Find Block on hash table - if (Info == NULL) - { - Info = CompileDelaySlot(PROGRAM_COUNTER); - - if (Info == NULL || EndEmulation()) - { - break; - } - } - if (bSMM_ValidFunc()) - { - if ((*Info->MemLocation[0] != Info->MemContents[0]) || - (*Info->MemLocation[1] != Info->MemContents[1])) - { - ClearRecompCode_Virt((Info->VStartPC() - 0x1000) & ~0xFFF,0x2000,Remove_ValidateFunc); - NextInstruction = DELAY_SLOT; - Info = NULL; - continue; - } - } - const uint8_t * Block = Info->FunctionAddr(); - _asm { - pushad - call Block - popad - } - continue; - } - - __try { - if (Addr > 0x10000000) - { - if (bRomInMemory()) - { - if (Addr > 0x20000000) - { - WriteTraceF(TraceDebug,"Executing from non mapped space .1 PC: %X Addr: %X",PROGRAM_COUNTER, Addr); - g_Notify->DisplayError(GS(MSG_NONMAPPED_SPACE)); - break; - } - Info = (CCompiledFunc *)*(JumpTable + (Addr >> 2)); - } else { - if (PROGRAM_COUNTER >= 0xB0000000 && PROGRAM_COUNTER < (RomFileSize | 0xB0000000)) { - while (PROGRAM_COUNTER >= 0xB0000000 && PROGRAM_COUNTER < (RomFileSize | 0xB0000000)) { - ExecuteInterpreterOpCode(); - } - continue; - } else { - WriteTraceF(TraceDebug,"Executing from non mapped space .1 PC: %X Addr: %X",PROGRAM_COUNTER, Addr); - g_Notify->DisplayError(GS(MSG_NONMAPPED_SPACE)); - break; - } - } - } else { - Info = (CCompiledFunc *)*(JumpTable + (Addr >> 2)); - } - } __except(EXCEPTION_EXECUTE_HANDLER) { - if (PROGRAM_COUNTER >= 0xB0000000 && PROGRAM_COUNTER < (RomFileSize | 0xB0000000)) { - while (PROGRAM_COUNTER >= 0xB0000000 && PROGRAM_COUNTER < (RomFileSize | 0xB0000000)) { - ExecuteInterpreterOpCode(); - } - continue; - } else { - WriteTraceF(TraceDebug,"Executing from non mapped space .2 PC: %X Addr: %X",PROGRAM_COUNTER, Addr); - g_Notify->DisplayError(GS(MSG_NONMAPPED_SPACE)); - return; - } - } - - if (Info == NULL) - { - Info = CompilerCode(); - - if (Info == NULL || EndEmulation()) - { - break; - } - *(JumpTable + (Addr >> 2)) = (void *)Info; - - // if (SelfModCheck == ModCode_ProtectedMemory) { - // VirtualProtect(RDRAM + Addr, 4, PAGE_READONLY, &OldProtect); - // } - } - if (bSMM_ValidFunc()) - { - if ((*Info->MemLocation[0] != Info->MemContents[0]) || - (*Info->MemLocation[1] != Info->MemContents[1])) - { - ClearRecompCode_Virt((Info->VStartPC() - 0x1000) & ~0xFFF,0x3000,Remove_ValidateFunc); - Info = NULL; - continue; - } - } - g_Notify->BreakPoint(__FILE__, __LINE__); - #ifdef legacycode - if (Profiling && IndvidualBlock) { - static uint32_t ProfAddress = 0; - - if ((PROGRAM_COUNTER & ~0xFFF) != ProfAddress) { - char Label[100]; - - ProfAddress = PROGRAM_COUNTER & ~0xFFF; - sprintf(Label,"PC: %X to %X",ProfAddress,ProfAddress+ 0xFFC); - // StartTimer(Label); - } - /*if (PROGRAM_COUNTER >= 0x800DD000 && PROGRAM_COUNTER <= 0x800DDFFC) { - char Label[100]; - sprintf(Label,"PC: %X Block: %X",PROGRAM_COUNTER,Block); - StartTimer(Label); - }*/ - // } else if ((Profiling || ShowCPUPer) && ProfilingLabel[0] == 0) { - // StartTimer("r4300i Running"); - /* } - #endif - const uint8_t * Block = Info->FunctionAddr(); - _asm { - pushad - call Block - popad - } - }*/ -} - -void CRecompiler::RecompilerMain_Lookup_TLB() -{ - uint32_t PhysicalAddr; - - while (!m_EndEmulation) - { - if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) - { - m_Registers.DoTLBReadMiss(false, PROGRAM_COUNTER); - if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) - { - g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PROGRAM_COUNTER).c_str()); - m_EndEmulation = true; - } - continue; - } - if (PhysicalAddr < g_System->RdramSize()) - { - CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; - - if (info == NULL) - { - info = CompilerCode(); - if (info == NULL || m_EndEmulation) - { - break; - } - if (g_System->bSMM_Protect()) - { - g_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF, PROGRAM_COUNTER | 0xFFF); - } - JumpTable()[PhysicalAddr >> 2] = info; - } - (info->Function())(); - } - else - { - uint32_t opsExecuted = 0; - - while (g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize()) - { - CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); - opsExecuted += g_System->CountPerOp(); - } - - if (g_SyncSystem) - { - g_System->UpdateSyncCPU(g_SyncSystem, opsExecuted); - g_System->SyncCPU(g_SyncSystem); - } - } - } -} - -void CRecompiler::RecompilerMain_Lookup_validate() -{ - while (!m_EndEmulation) - { - uint32_t PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF; - if (PhysicalAddr < g_System->RdramSize()) - { - CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; - if (info == NULL) - { - info = CompilerCode(); - if (info == NULL || m_EndEmulation) - { - break; - } - if (g_System->bSMM_Protect()) - { - g_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF, PROGRAM_COUNTER | 0xFFF); - } - JumpTable()[PhysicalAddr >> 2] = info; - } - else - { - if (*(info->MemLocation(0)) != info->MemContents(0) || - *(info->MemLocation(1)) != info->MemContents(1)) - { - ClearRecompCode_Virt((info->EnterPC() - 0x1000) & ~0xFFF, 0x3000, Remove_ValidateFunc); - info = NULL; - continue; - } - } - (info->Function())(); - } - else - { - uint32_t opsExecuted = 0; - - while (g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize()) - { - CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); - opsExecuted += g_System->CountPerOp(); - } - - if (g_SyncSystem) - { - g_System->UpdateSyncCPU(g_SyncSystem, opsExecuted); - g_System->SyncCPU(g_SyncSystem); - } - } - } -} - -void CRecompiler::RecompilerMain_Lookup_validate_TLB() -{ - uint32_t PhysicalAddr; - - while (!m_EndEmulation) - { - if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) - { - m_Registers.DoTLBReadMiss(false, PROGRAM_COUNTER); - if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) - { - g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PROGRAM_COUNTER).c_str()); - m_EndEmulation = true; - } - continue; - } - if (PhysicalAddr < g_System->RdramSize()) - { - CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; - - if (info == NULL) - { - info = CompilerCode(); - if (info == NULL || m_EndEmulation) - { - break; - } - if (g_System->bSMM_Protect()) - { - g_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF, PROGRAM_COUNTER | 0xFFF); - } - JumpTable()[PhysicalAddr >> 2] = info; - } - else - { - if (*(info->MemLocation(0)) != info->MemContents(0) || - *(info->MemLocation(1)) != info->MemContents(1)) - { - if (PhysicalAddr > 0x1000) - { - ClearRecompCode_Phys((PhysicalAddr - 0x1000) & ~0xFFF, 0x3000, Remove_ValidateFunc); - } - else - { - ClearRecompCode_Phys(0, 0x2000, Remove_ValidateFunc); - } - info = JumpTable()[PhysicalAddr >> 2]; - if (info != NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - info = NULL; - } - continue; - } - } - (info->Function())(); - } - else - { - uint32_t opsExecuted = 0; - - while (g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize()) - { - CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); - opsExecuted += g_System->CountPerOp(); - } - - if (g_SyncSystem) - { - g_System->UpdateSyncCPU(g_SyncSystem, opsExecuted); - g_System->SyncCPU(g_SyncSystem); - } - } - } -} - -void CRecompiler::Reset() -{ - ResetRecompCode(true); - ResetMemoryStackPos(); -} - -void CRecompiler::ResetRecompCode(bool bAllocate) -{ - CRecompMemory::Reset(); - CFunctionMap::Reset(bAllocate); - - for (CCompiledFuncList::iterator iter = m_Functions.begin(); iter != m_Functions.end(); iter++) - { - CCompiledFunc * Func = iter->second; - while (Func != NULL) - { - CCompiledFunc * CurrentFunc = Func; - Func = Func->Next(); - - delete CurrentFunc; - } - } - m_Functions.clear(); -} - -void CRecompiler::RecompilerMain_ChangeMemory() -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - uint32_t Value, Addr; - uint8_t * Block; - - while(!EndEmulation()) - { - if (UseTlb) - { - if (!TranslateVaddr(PROGRAM_COUNTER, &Addr)) - { - DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); - NextInstruction = NORMAL; - if (!TranslateVaddr(PROGRAM_COUNTER, &Addr)) - { - g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); - ExitThread(0); - } - } - } else { - Addr = PROGRAM_COUNTER & 0x1FFFFFFF; - } - - if (NextInstruction == DELAY_SLOT) - { - __try - { - Value = (uint32_t)(*(DelaySlotTable + (Addr >> 12))); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - g_Notify->DisplayError("Executing Delay Slot from non maped space\nPROGRAM_COUNTER = 0x%X",PROGRAM_COUNTER); - ExitThread(0); - } - if ( (Value >> 16) == 0x7C7C) - { - uint32_t Index = (Value & 0xFFFF); - Block = (uint8_t *)OrigMem[Index].CompiledLocation; - if (OrigMem[Index].PAddr != Addr) { Block = NULL; } - if (OrigMem[Index].VAddr != PROGRAM_COUNTER) { Block = NULL; } - if (Index >= TargetIndex) { Block = NULL; } - } - else - { - Block = NULL; - } - if (Block == NULL) - { - uint32_t MemValue; - - Block = CompileDelaySlot(); - Value = 0x7C7C0000; - Value += (uint16_t)(TargetIndex); - MemValue = *(uint32_t *)(RDRAM + Addr); - if ( (MemValue >> 16) == 0x7C7C) - { - MemValue = OrigMem[(MemValue & 0xFFFF)].OriginalValue; - } - OrigMem[(uint16_t)(TargetIndex)].OriginalValue = MemValue; - OrigMem[(uint16_t)(TargetIndex)].CompiledLocation = Block; - OrigMem[(uint16_t)(TargetIndex)].PAddr = Addr; - OrigMem[(uint16_t)(TargetIndex)].VAddr = PROGRAM_COUNTER; - TargetIndex += 1; - *(DelaySlotTable + (Addr >> 12)) = (void *)Value; - NextInstruction = NORMAL; - } - _asm - { - pushad - call Block - popad - } - continue; - } - - __try - { - Value = *(uint32_t *)(RDRAM + Addr); - if ( (Value >> 16) == 0x7C7C) - { - uint32_t Index = (Value & 0xFFFF); - Block = (uint8_t *)OrigMem[Index].CompiledLocation; - if (OrigMem[Index].PAddr != Addr) { Block = NULL; } - if (OrigMem[Index].VAddr != PROGRAM_COUNTER) { Block = NULL; } - if (Index >= TargetIndex) { Block = NULL; } - } - else - { - Block = NULL; - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - g_Notify->DisplayError(GS(MSG_NONMAPPED_SPACE)); - ExitThread(0); - } - - if (Block == NULL) - { - uint32_t MemValue; - - __try - { - Block = Compiler4300iBlock(); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - ResetRecompCode(); - Block = Compiler4300iBlock(); - } - if (EndEmulation()) - { - continue; - } - if (TargetIndex == MaxOrigMem) - { - ResetRecompCode(); - continue; - } - Value = 0x7C7C0000; - Value += (uint16_t)(TargetIndex); - MemValue = *(uint32_t *)(RDRAM + Addr); - if ( (MemValue >> 16) == 0x7C7C) - { - MemValue = OrigMem[(MemValue & 0xFFFF)].OriginalValue; - } - OrigMem[(uint16_t)(TargetIndex)].OriginalValue = MemValue; - OrigMem[(uint16_t)(TargetIndex)].CompiledLocation = Block; - OrigMem[(uint16_t)(TargetIndex)].PAddr = Addr; - OrigMem[(uint16_t)(TargetIndex)].VAddr = PROGRAM_COUNTER; - TargetIndex += 1; - *(uint32_t *)(RDRAM + Addr) = Value; - NextInstruction = NORMAL; - } - if (Profiling && IndvidualBlock) - { - static uint32_t ProfAddress = 0; - - /*if ((PROGRAM_COUNTER & ~0xFFF) != ProfAddress) - { - char Label[100]; - - ProfAddress = PROGRAM_COUNTER & ~0xFFF; - sprintf(Label,"PC: %X to %X",ProfAddress,ProfAddress+ 0xFFC); - StartTimer(Label); - }*/ - /*if (PROGRAM_COUNTER >= 0x800DD000 && PROGRAM_COUNTER <= 0x800DDFFC) - { - char Label[100]; - sprintf(Label,"PC: %X Block: %X",PROGRAM_COUNTER,Block); - StartTimer(Label); - }*/ - // } else if ((Profiling || ShowCPUPer) && ProfilingLabel[0] == 0) { - // StartTimer("r4300i Running"); - } - _asm - { - pushad - call Block - popad - } - } // end for(;;) -#endif -} - -CCompiledFunc * CRecompiler::CompilerCode() -{ - uint32_t pAddr = 0; - if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, pAddr)) - { - WriteTrace(TraceRecompiler, TraceError, "Failed to translate %X", PROGRAM_COUNTER); - return NULL; - } - - CCompiledFuncList::iterator iter = m_Functions.find(PROGRAM_COUNTER); - if (iter != m_Functions.end()) - { - for (CCompiledFunc * Func = iter->second; Func != NULL; Func = Func->Next()) - { - uint32_t PAddr; - if (g_TransVaddr->TranslateVaddr(Func->MinPC(), PAddr)) - { - MD5Digest Hash; - MD5(g_MMU->Rdram() + PAddr, (Func->MaxPC() - Func->MinPC()) + 4).get_digest(Hash); - if (memcmp(Hash.digest, Func->Hash().digest, sizeof(Hash.digest)) == 0) - { - return Func; - } - } - } - } - - CheckRecompMem(); - - //uint32_t StartTime = timeGetTime(); - WriteTrace(TraceRecompiler, TraceDebug, ": Compile Block-Start: Program Counter: %X pAddr: %X", PROGRAM_COUNTER, pAddr); - - CCodeBlock CodeBlock(PROGRAM_COUNTER, RecompPos()); - if (!CodeBlock.Compile()) - { - return NULL; - } - - if (bShowRecompMemSize()) - { - ShowMemUsed(); - } - - CCompiledFunc * Func = new CCompiledFunc(CodeBlock); - std::pair ret = m_Functions.insert(CCompiledFuncList::value_type(Func->EnterPC(), Func)); - if (ret.second == false) - { - Func->SetNext(ret.first->second->Next()); - ret.first->second->SetNext(Func); - return Func; - } - return Func; -} - -void CRecompiler::ClearRecompCode_Phys(uint32_t Address, int length, REMOVE_REASON Reason) -{ - if (g_System->LookUpMode() == FuncFind_VirtualLookup) - { - ClearRecompCode_Virt(Address + 0x80000000, length, Reason); - ClearRecompCode_Virt(Address + 0xA0000000, length, Reason); - - if (g_System->bUseTlb()) - { - uint32_t VAddr, Index = 0; - while (g_TLB->PAddrToVAddr(Address, VAddr, Index)) - { - WriteTrace(TraceRecompiler, TraceDebug, "ClearRecompCode Vaddr %X len: %d", VAddr, length); - ClearRecompCode_Virt(VAddr, length, Reason); - } - } - } - else if (g_System->LookUpMode() == FuncFind_PhysicalLookup) - { - if (Address < g_System->RdramSize()) - { - int ClearLen = ((length + 3) & ~3); - if (Address + ClearLen > g_System->RdramSize()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - ClearLen = g_System->RdramSize() - Address; - } - WriteTrace(TraceRecompiler, TraceDebug, "Reseting Jump Table, Addr: %X len: %d", Address, ClearLen); - memset((uint8_t *)JumpTable() + Address, 0, ClearLen); - if (g_System->bSMM_Protect()) - { - g_MMU->UnProtectMemory(Address + 0x80000000, Address + 0x80000004); - } - } - else - { - WriteTrace(TraceRecompiler, TraceDebug, "Ignoring reset of Jump Table, Addr: %X len: %d", Address, ((length + 3) & ~3)); - } - } -} - -void CRecompiler::ClearRecompCode_Virt(uint32_t Address, int length, REMOVE_REASON Reason) -{ - switch (g_System->LookUpMode()) - { - case FuncFind_VirtualLookup: - { - uint32_t AddressIndex = Address >> 0xC; - uint32_t WriteStart = (Address & 0xFFC); - length = ((length + 3) & ~0x3); - - int DataInBlock = 0x1000 - WriteStart; - int DataToWrite = length < DataInBlock ? length : DataInBlock; - int DataLeft = length - DataToWrite; - - PCCompiledFunc_TABLE & table = FunctionTable()[AddressIndex]; - if (table) - { - WriteTrace(TraceRecompiler, TraceError, "Delete Table (%X): Index = %d", table, AddressIndex); - delete table; - table = NULL; - g_MMU->UnProtectMemory(Address, Address + length); - } - - if (DataLeft > 0) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - break; - case FuncFind_PhysicalLookup: - { - uint32_t pAddr = 0; - if (g_TransVaddr->TranslateVaddr(Address, pAddr)) - { - ClearRecompCode_Phys(pAddr, length, Reason); - } - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CRecompiler::ResetMemoryStackPos() -{ - if (g_MMU == NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - if (m_Registers.m_GPR[29].UW[0] == 0) - { - m_MemoryStack = 0; - return; - } - - uint32_t pAddr = 0; - if (g_TransVaddr->TranslateVaddr(m_Registers.m_GPR[29].UW[0], pAddr)) - { - m_MemoryStack = (uint32_t)(g_MMU->Rdram() + pAddr); - } - else - { - WriteTrace(TraceRecompiler, TraceError, "Failed to translate SP address (%s)", m_Registers.m_GPR[29].UW[0]); - g_Notify->BreakPoint(__FILE__, __LINE__); - } +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include +#include +#include + +CRecompiler::CRecompiler(CRegisters & Registers, CProfiling & Profile, bool & EndEmulation) : +m_Registers(Registers), +m_Profile(Profile), +m_EndEmulation(EndEmulation), +PROGRAM_COUNTER(Registers.m_PROGRAM_COUNTER) +{ + if (g_MMU != NULL) + { + ResetMemoryStackPos(); + } +} + +CRecompiler::~CRecompiler() +{ + ResetRecompCode(false); +} + +void CRecompiler::Run() +{ + if (bLogX86Code()) + { + Start_x86_Log(); + } + + if (!CRecompMemory::AllocateMemory()) + { + WriteTrace(TraceRecompiler, TraceError, "AllocateMemory failed"); + return; + } + if (!CFunctionMap::AllocateMemory()) + { + WriteTrace(TraceRecompiler, TraceError, "AllocateMemory failed"); + return; + } + m_EndEmulation = false; + +#ifdef legacycode + *g_MemoryStack = (uint32_t)(RDRAM+(_GPR[29].W[0] & 0x1FFFFFFF)); +#endif + __except_try() + { + if (g_System->LookUpMode() == FuncFind_VirtualLookup) + { + if (g_System->bSMM_ValidFunc()) + { + RecompilerMain_VirtualTable_validate(); + } + else + { + RecompilerMain_VirtualTable(); + } + } + else if (g_System->LookUpMode() == FuncFind_ChangeMemory) + { + RecompilerMain_ChangeMemory(); + } + else + { + if (g_System->bUseTlb()) + { + if (g_System->bSMM_ValidFunc()) + { + RecompilerMain_Lookup_validate_TLB(); + } + else + { + RecompilerMain_Lookup_TLB(); + } + } + else + { + if (g_System->bSMM_ValidFunc()) + { + RecompilerMain_Lookup_validate(); + } + else + { + RecompilerMain_Lookup(); + } + } + } + } + __except_catch() + { + g_Notify->DisplayError(MSG_UNKNOWN_MEM_ACTION); + } +} + +void CRecompiler::RecompilerMain_VirtualTable() +{ + bool & Done = m_EndEmulation; + uint32_t & PC = PROGRAM_COUNTER; + + while (!Done) + { + if (!g_TransVaddr->ValidVaddr(PC)) + { + m_Registers.DoTLBReadMiss(false, PC); + if (!g_TransVaddr->ValidVaddr(PC)) + { + g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PC).c_str()); + return; + } + continue; + } + + PCCompiledFunc_TABLE & table = FunctionTable()[PC >> 0xC]; + uint32_t TableEntry = (PC & 0xFFF) >> 2; + if (table) + { + CCompiledFunc * info = table[TableEntry]; + if (info != NULL) + { + (info->Function())(); + continue; + } + } + CCompiledFunc * info = CompilerCode(); + if (info == NULL || m_EndEmulation) + { + break; + } + + if (table == NULL) + { + table = new PCCompiledFunc[(0x1000 >> 2)]; + if (table == NULL) + { + WriteTrace(TraceRecompiler, TraceError, "failed to allocate PCCompiledFunc"); + g_Notify->FatalError(MSG_MEM_ALLOC_ERROR); + } + memset(table, 0, sizeof(PCCompiledFunc) * (0x1000 >> 2)); + if (g_System->bSMM_Protect()) + { + WriteTrace(TraceRecompiler, TraceError, "Create Table (%X): Index = %d", table, PC >> 0xC); + g_MMU->ProtectMemory(PC & ~0xFFF, PC | 0xFFF); + } + } + + table[TableEntry] = info; + (info->Function())(); + } +} + +void CRecompiler::RecompilerMain_VirtualTable_validate() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + /* PCCompiledFunc_TABLE * m_FunctionTable = m_Functions.GetFunctionTable(); + + while(!m_EndEmulation) + { + /*if (NextInstruction == DELAY_SLOT) + { + CCompiledFunc * Info = m_FunctionsDelaySlot.FindFunction(PROGRAM_COUNTER); + //Find Block on hash table + if (Info == NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + #ifdef legacycode + if (!g_TLB->ValidVaddr(PROGRAM_COUNTER)) + { + DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); + NextInstruction = NORMAL; + if (!g_TLB->ValidVaddr(PROGRAM_COUNTER)) + { + g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); + return; + } + continue; + } + #endif + //Find Block on hash table + Info = CompileDelaySlot(PROGRAM_COUNTER); + + if (Info == NULL || EndEmulation()) + { + break; + } + } + const uint8_t * Block = Info->FunctionAddr(); + if ((*Info->MemLocation[0] != Info->MemContents[0]) || + (*Info->MemLocation[1] != Info->MemContents[1])) + { + ClearRecompCode_Virt((Info->VStartPC() - 0x1000) & ~0xFFF,0x2000,Remove_ValidateFunc); + NextInstruction = DELAY_SLOT; + Info = NULL; + continue; + } + _asm { + pushad + call Block + popad + } + continue; + }*/ + /* PCCompiledFunc_TABLE table = m_FunctionTable[PROGRAM_COUNTER >> 0xC]; + if (table) + { + CCompiledFunc * info = table[(PROGRAM_COUNTER & 0xFFF) >> 2]; + if (info != NULL) + { + if ((*info->MemLocation[0] != info->MemContents[0]) || + (*info->MemLocation[1] != info->MemContents[1])) + { + ClearRecompCode_Virt((info->VStartPC() - 0x1000) & ~0xFFF,0x3000,Remove_ValidateFunc); + info = NULL; + continue; + } + const uint8_t * Block = info->FunctionAddr(); + _asm { + pushad + call Block + popad + } + continue; + } + } + g_Notify->BreakPoint(__FILE__, __LINE__); + #ifdef legacycode + if (!g_TLB->ValidVaddr(PROGRAM_COUNTER)) + { + DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); + NextInstruction = NORMAL; + if (!g_TLB->ValidVaddr(PROGRAM_COUNTER)) + { + g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); + return; + } + } + #endif + CCompiledFunc * info = CompilerCode(); + + if (info == NULL || EndEmulation()) + { + break; + } + } + + /* + while(!m_EndEmulation) + { + if (!g_MMU->ValidVaddr(PROGRAM_COUNTER)) + { + DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); + NextInstruction = NORMAL; + if (!g_MMU->ValidVaddr(PROGRAM_COUNTER)) + { + g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); + return; + } + } + if (NextInstruction == DELAY_SLOT) + { + CCompiledFunc * Info = m_FunctionsDelaySlot.FindFunction(PROGRAM_COUNTER); + + //Find Block on hash table + if (Info == NULL) + { + Info = CompileDelaySlot(PROGRAM_COUNTER); + + if (Info == NULL || EndEmulation()) + { + break; + } + } + if (bSMM_ValidFunc()) + { + if ((*Info->MemLocation[0] != Info->MemContents[0]) || + (*Info->MemLocation[1] != Info->MemContents[1])) + { + ClearRecompCode_Virt((Info->StartPC() - 0x1000) & ~0xFFF,0x2000,Remove_ValidateFunc); + NextInstruction = DELAY_SLOT; + Info = NULL; + continue; + } + } + const uint8_t * Block = Info->FunctionAddr(); + _asm { + pushad + call Block + popad + } + continue; + } + + CCompiledFunc * Info = m_Functions.FindFunction(PROGRAM_COUNTER); + + //Find Block on hash table + if (Info == NULL) + { + Info = CompilerCode(); + + if (Info == NULL || EndEmulation()) + { + break; + } + } + if (bSMM_ValidFunc()) + { + if ((*Info->MemLocation[0] != Info->MemContents[0]) || + (*Info->MemLocation[1] != Info->MemContents[1])) + { + ClearRecompCode_Virt((Info->StartPC() - 0x1000) & ~0xFFF,0x3000,Remove_ValidateFunc); + Info = NULL; + continue; + } + } + const uint8_t * Block = Info->FunctionAddr(); + _asm { + pushad + call Block + popad + } + } + */ +} + +void CRecompiler::RecompilerMain_Lookup() +{ + while (!m_EndEmulation) + { + uint32_t PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF; + if (PhysicalAddr < g_System->RdramSize()) + { + CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; + if (info == NULL) + { + info = CompilerCode(); + if (info == NULL || m_EndEmulation) + { + break; + } + if (g_System->bSMM_Protect()) + { + g_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF, PROGRAM_COUNTER | 0xFFF); + } + JumpTable()[PhysicalAddr >> 2] = info; + } + (info->Function())(); + } + else + { + uint32_t opsExecuted = 0; + + while (g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize()) + { + CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); + opsExecuted += g_System->CountPerOp(); + } + + if (g_SyncSystem) + { + g_System->UpdateSyncCPU(g_SyncSystem, opsExecuted); + g_System->SyncCPU(g_SyncSystem); + } + } + } + /* + uint32_t Addr; + CCompiledFunc * Info; + //const uint8_t * Block; + + while(!m_EndEmulation) + { + /*if (bUseTlb()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + #ifdef legacycode + if (!g_TLB->TranslateVaddr(PROGRAM_COUNTER, Addr)) + { + DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); + NextInstruction = NORMAL; + if (!TranslateVaddr(PROGRAM_COUNTER, &Addr)) { + g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); + return; + } + } + #endif + } else { + Addr = PROGRAM_COUNTER & 0x1FFFFFFF; + }*/ + + /* if (NextInstruction == DELAY_SLOT) { + CCompiledFunc * Info = m_FunctionsDelaySlot.FindFunction(PROGRAM_COUNTER); + + //Find Block on hash table + if (Info == NULL) + { + Info = CompileDelaySlot(PROGRAM_COUNTER); + + if (Info == NULL || EndEmulation()) + { + break; + } + } + if (bSMM_ValidFunc()) + { + if ((*Info->MemLocation[0] != Info->MemContents[0]) || + (*Info->MemLocation[1] != Info->MemContents[1])) + { + ClearRecompCode_Virt((Info->VStartPC() - 0x1000) & ~0xFFF,0x2000,Remove_ValidateFunc); + NextInstruction = DELAY_SLOT; + Info = NULL; + continue; + } + } + const uint8_t * Block = Info->FunctionAddr(); + _asm { + pushad + call Block + popad + } + continue; + } + + __try { + if (Addr > 0x10000000) + { + if (bRomInMemory()) + { + if (Addr > 0x20000000) + { + WriteTraceF(TraceDebug,"Executing from non mapped space .1 PC: %X Addr: %X",PROGRAM_COUNTER, Addr); + g_Notify->DisplayError(GS(MSG_NONMAPPED_SPACE)); + break; + } + Info = (CCompiledFunc *)*(JumpTable + (Addr >> 2)); + } else { + if (PROGRAM_COUNTER >= 0xB0000000 && PROGRAM_COUNTER < (RomFileSize | 0xB0000000)) { + while (PROGRAM_COUNTER >= 0xB0000000 && PROGRAM_COUNTER < (RomFileSize | 0xB0000000)) { + ExecuteInterpreterOpCode(); + } + continue; + } else { + WriteTraceF(TraceDebug,"Executing from non mapped space .1 PC: %X Addr: %X",PROGRAM_COUNTER, Addr); + g_Notify->DisplayError(GS(MSG_NONMAPPED_SPACE)); + break; + } + } + } else { + Info = (CCompiledFunc *)*(JumpTable + (Addr >> 2)); + } + } __except(EXCEPTION_EXECUTE_HANDLER) { + if (PROGRAM_COUNTER >= 0xB0000000 && PROGRAM_COUNTER < (RomFileSize | 0xB0000000)) { + while (PROGRAM_COUNTER >= 0xB0000000 && PROGRAM_COUNTER < (RomFileSize | 0xB0000000)) { + ExecuteInterpreterOpCode(); + } + continue; + } else { + WriteTraceF(TraceDebug,"Executing from non mapped space .2 PC: %X Addr: %X",PROGRAM_COUNTER, Addr); + g_Notify->DisplayError(GS(MSG_NONMAPPED_SPACE)); + return; + } + } + + if (Info == NULL) + { + Info = CompilerCode(); + + if (Info == NULL || EndEmulation()) + { + break; + } + *(JumpTable + (Addr >> 2)) = (void *)Info; + + // if (SelfModCheck == ModCode_ProtectedMemory) { + // VirtualProtect(RDRAM + Addr, 4, PAGE_READONLY, &OldProtect); + // } + } + if (bSMM_ValidFunc()) + { + if ((*Info->MemLocation[0] != Info->MemContents[0]) || + (*Info->MemLocation[1] != Info->MemContents[1])) + { + ClearRecompCode_Virt((Info->VStartPC() - 0x1000) & ~0xFFF,0x3000,Remove_ValidateFunc); + Info = NULL; + continue; + } + } + g_Notify->BreakPoint(__FILE__, __LINE__); + #ifdef legacycode + if (Profiling && IndvidualBlock) { + static uint32_t ProfAddress = 0; + + if ((PROGRAM_COUNTER & ~0xFFF) != ProfAddress) { + char Label[100]; + + ProfAddress = PROGRAM_COUNTER & ~0xFFF; + sprintf(Label,"PC: %X to %X",ProfAddress,ProfAddress+ 0xFFC); + // StartTimer(Label); + } + /*if (PROGRAM_COUNTER >= 0x800DD000 && PROGRAM_COUNTER <= 0x800DDFFC) { + char Label[100]; + sprintf(Label,"PC: %X Block: %X",PROGRAM_COUNTER,Block); + StartTimer(Label); + }*/ + // } else if ((Profiling || ShowCPUPer) && ProfilingLabel[0] == 0) { + // StartTimer("r4300i Running"); + /* } + #endif + const uint8_t * Block = Info->FunctionAddr(); + _asm { + pushad + call Block + popad + } + }*/ +} + +void CRecompiler::RecompilerMain_Lookup_TLB() +{ + uint32_t PhysicalAddr; + + while (!m_EndEmulation) + { + if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) + { + m_Registers.DoTLBReadMiss(false, PROGRAM_COUNTER); + if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) + { + g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PROGRAM_COUNTER).c_str()); + m_EndEmulation = true; + } + continue; + } + if (PhysicalAddr < g_System->RdramSize()) + { + CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; + + if (info == NULL) + { + info = CompilerCode(); + if (info == NULL || m_EndEmulation) + { + break; + } + if (g_System->bSMM_Protect()) + { + g_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF, PROGRAM_COUNTER | 0xFFF); + } + JumpTable()[PhysicalAddr >> 2] = info; + } + (info->Function())(); + } + else + { + uint32_t opsExecuted = 0; + + while (g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize()) + { + CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); + opsExecuted += g_System->CountPerOp(); + } + + if (g_SyncSystem) + { + g_System->UpdateSyncCPU(g_SyncSystem, opsExecuted); + g_System->SyncCPU(g_SyncSystem); + } + } + } +} + +void CRecompiler::RecompilerMain_Lookup_validate() +{ + while (!m_EndEmulation) + { + uint32_t PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF; + if (PhysicalAddr < g_System->RdramSize()) + { + CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; + if (info == NULL) + { + info = CompilerCode(); + if (info == NULL || m_EndEmulation) + { + break; + } + if (g_System->bSMM_Protect()) + { + g_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF, PROGRAM_COUNTER | 0xFFF); + } + JumpTable()[PhysicalAddr >> 2] = info; + } + else + { + if (*(info->MemLocation(0)) != info->MemContents(0) || + *(info->MemLocation(1)) != info->MemContents(1)) + { + ClearRecompCode_Virt((info->EnterPC() - 0x1000) & ~0xFFF, 0x3000, Remove_ValidateFunc); + info = NULL; + continue; + } + } + (info->Function())(); + } + else + { + uint32_t opsExecuted = 0; + + while (g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize()) + { + CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); + opsExecuted += g_System->CountPerOp(); + } + + if (g_SyncSystem) + { + g_System->UpdateSyncCPU(g_SyncSystem, opsExecuted); + g_System->SyncCPU(g_SyncSystem); + } + } + } +} + +void CRecompiler::RecompilerMain_Lookup_validate_TLB() +{ + uint32_t PhysicalAddr; + + while (!m_EndEmulation) + { + if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) + { + m_Registers.DoTLBReadMiss(false, PROGRAM_COUNTER); + if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr)) + { + g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PROGRAM_COUNTER).c_str()); + m_EndEmulation = true; + } + continue; + } + if (PhysicalAddr < g_System->RdramSize()) + { + CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2]; + + if (info == NULL) + { + info = CompilerCode(); + if (info == NULL || m_EndEmulation) + { + break; + } + if (g_System->bSMM_Protect()) + { + g_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF, PROGRAM_COUNTER | 0xFFF); + } + JumpTable()[PhysicalAddr >> 2] = info; + } + else + { + if (*(info->MemLocation(0)) != info->MemContents(0) || + *(info->MemLocation(1)) != info->MemContents(1)) + { + if (PhysicalAddr > 0x1000) + { + ClearRecompCode_Phys((PhysicalAddr - 0x1000) & ~0xFFF, 0x3000, Remove_ValidateFunc); + } + else + { + ClearRecompCode_Phys(0, 0x2000, Remove_ValidateFunc); + } + info = JumpTable()[PhysicalAddr >> 2]; + if (info != NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + info = NULL; + } + continue; + } + } + (info->Function())(); + } + else + { + uint32_t opsExecuted = 0; + + while (g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize()) + { + CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); + opsExecuted += g_System->CountPerOp(); + } + + if (g_SyncSystem) + { + g_System->UpdateSyncCPU(g_SyncSystem, opsExecuted); + g_System->SyncCPU(g_SyncSystem); + } + } + } +} + +void CRecompiler::Reset() +{ + ResetRecompCode(true); + ResetMemoryStackPos(); +} + +void CRecompiler::ResetRecompCode(bool bAllocate) +{ + CRecompMemory::Reset(); + CFunctionMap::Reset(bAllocate); + + for (CCompiledFuncList::iterator iter = m_Functions.begin(); iter != m_Functions.end(); iter++) + { + CCompiledFunc * Func = iter->second; + while (Func != NULL) + { + CCompiledFunc * CurrentFunc = Func; + Func = Func->Next(); + + delete CurrentFunc; + } + } + m_Functions.clear(); +} + +void CRecompiler::RecompilerMain_ChangeMemory() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + uint32_t Value, Addr; + uint8_t * Block; + + while(!EndEmulation()) + { + if (UseTlb) + { + if (!TranslateVaddr(PROGRAM_COUNTER, &Addr)) + { + DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER); + NextInstruction = NORMAL; + if (!TranslateVaddr(PROGRAM_COUNTER, &Addr)) + { + g_Notify->DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER); + ExitThread(0); + } + } + } else { + Addr = PROGRAM_COUNTER & 0x1FFFFFFF; + } + + if (NextInstruction == DELAY_SLOT) + { + __try + { + Value = (uint32_t)(*(DelaySlotTable + (Addr >> 12))); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + g_Notify->DisplayError("Executing Delay Slot from non maped space\nPROGRAM_COUNTER = 0x%X",PROGRAM_COUNTER); + ExitThread(0); + } + if ( (Value >> 16) == 0x7C7C) + { + uint32_t Index = (Value & 0xFFFF); + Block = (uint8_t *)OrigMem[Index].CompiledLocation; + if (OrigMem[Index].PAddr != Addr) { Block = NULL; } + if (OrigMem[Index].VAddr != PROGRAM_COUNTER) { Block = NULL; } + if (Index >= TargetIndex) { Block = NULL; } + } + else + { + Block = NULL; + } + if (Block == NULL) + { + uint32_t MemValue; + + Block = CompileDelaySlot(); + Value = 0x7C7C0000; + Value += (uint16_t)(TargetIndex); + MemValue = *(uint32_t *)(RDRAM + Addr); + if ( (MemValue >> 16) == 0x7C7C) + { + MemValue = OrigMem[(MemValue & 0xFFFF)].OriginalValue; + } + OrigMem[(uint16_t)(TargetIndex)].OriginalValue = MemValue; + OrigMem[(uint16_t)(TargetIndex)].CompiledLocation = Block; + OrigMem[(uint16_t)(TargetIndex)].PAddr = Addr; + OrigMem[(uint16_t)(TargetIndex)].VAddr = PROGRAM_COUNTER; + TargetIndex += 1; + *(DelaySlotTable + (Addr >> 12)) = (void *)Value; + NextInstruction = NORMAL; + } + _asm + { + pushad + call Block + popad + } + continue; + } + + __try + { + Value = *(uint32_t *)(RDRAM + Addr); + if ( (Value >> 16) == 0x7C7C) + { + uint32_t Index = (Value & 0xFFFF); + Block = (uint8_t *)OrigMem[Index].CompiledLocation; + if (OrigMem[Index].PAddr != Addr) { Block = NULL; } + if (OrigMem[Index].VAddr != PROGRAM_COUNTER) { Block = NULL; } + if (Index >= TargetIndex) { Block = NULL; } + } + else + { + Block = NULL; + } + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + g_Notify->DisplayError(GS(MSG_NONMAPPED_SPACE)); + ExitThread(0); + } + + if (Block == NULL) + { + uint32_t MemValue; + + __try + { + Block = Compiler4300iBlock(); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + ResetRecompCode(); + Block = Compiler4300iBlock(); + } + if (EndEmulation()) + { + continue; + } + if (TargetIndex == MaxOrigMem) + { + ResetRecompCode(); + continue; + } + Value = 0x7C7C0000; + Value += (uint16_t)(TargetIndex); + MemValue = *(uint32_t *)(RDRAM + Addr); + if ( (MemValue >> 16) == 0x7C7C) + { + MemValue = OrigMem[(MemValue & 0xFFFF)].OriginalValue; + } + OrigMem[(uint16_t)(TargetIndex)].OriginalValue = MemValue; + OrigMem[(uint16_t)(TargetIndex)].CompiledLocation = Block; + OrigMem[(uint16_t)(TargetIndex)].PAddr = Addr; + OrigMem[(uint16_t)(TargetIndex)].VAddr = PROGRAM_COUNTER; + TargetIndex += 1; + *(uint32_t *)(RDRAM + Addr) = Value; + NextInstruction = NORMAL; + } + if (Profiling && IndvidualBlock) + { + static uint32_t ProfAddress = 0; + + /*if ((PROGRAM_COUNTER & ~0xFFF) != ProfAddress) + { + char Label[100]; + + ProfAddress = PROGRAM_COUNTER & ~0xFFF; + sprintf(Label,"PC: %X to %X",ProfAddress,ProfAddress+ 0xFFC); + StartTimer(Label); + }*/ + /*if (PROGRAM_COUNTER >= 0x800DD000 && PROGRAM_COUNTER <= 0x800DDFFC) + { + char Label[100]; + sprintf(Label,"PC: %X Block: %X",PROGRAM_COUNTER,Block); + StartTimer(Label); + }*/ + // } else if ((Profiling || ShowCPUPer) && ProfilingLabel[0] == 0) { + // StartTimer("r4300i Running"); + } + _asm + { + pushad + call Block + popad + } + } // end for(;;) +#endif +} + +CCompiledFunc * CRecompiler::CompilerCode() +{ + uint32_t pAddr = 0; + if (!g_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, pAddr)) + { + WriteTrace(TraceRecompiler, TraceError, "Failed to translate %X", PROGRAM_COUNTER); + return NULL; + } + + CCompiledFuncList::iterator iter = m_Functions.find(PROGRAM_COUNTER); + if (iter != m_Functions.end()) + { + for (CCompiledFunc * Func = iter->second; Func != NULL; Func = Func->Next()) + { + uint32_t PAddr; + if (g_TransVaddr->TranslateVaddr(Func->MinPC(), PAddr)) + { + MD5Digest Hash; + MD5(g_MMU->Rdram() + PAddr, (Func->MaxPC() - Func->MinPC()) + 4).get_digest(Hash); + if (memcmp(Hash.digest, Func->Hash().digest, sizeof(Hash.digest)) == 0) + { + return Func; + } + } + } + } + + CheckRecompMem(); + + //uint32_t StartTime = timeGetTime(); + WriteTrace(TraceRecompiler, TraceDebug, ": Compile Block-Start: Program Counter: %X pAddr: %X", PROGRAM_COUNTER, pAddr); + + CCodeBlock CodeBlock(PROGRAM_COUNTER, RecompPos()); + if (!CodeBlock.Compile()) + { + return NULL; + } + + if (bShowRecompMemSize()) + { + ShowMemUsed(); + } + + CCompiledFunc * Func = new CCompiledFunc(CodeBlock); + std::pair ret = m_Functions.insert(CCompiledFuncList::value_type(Func->EnterPC(), Func)); + if (ret.second == false) + { + Func->SetNext(ret.first->second->Next()); + ret.first->second->SetNext(Func); + return Func; + } + return Func; +} + +void CRecompiler::ClearRecompCode_Phys(uint32_t Address, int length, REMOVE_REASON Reason) +{ + if (g_System->LookUpMode() == FuncFind_VirtualLookup) + { + ClearRecompCode_Virt(Address + 0x80000000, length, Reason); + ClearRecompCode_Virt(Address + 0xA0000000, length, Reason); + + if (g_System->bUseTlb()) + { + uint32_t VAddr, Index = 0; + while (g_TLB->PAddrToVAddr(Address, VAddr, Index)) + { + WriteTrace(TraceRecompiler, TraceDebug, "ClearRecompCode Vaddr %X len: %d", VAddr, length); + ClearRecompCode_Virt(VAddr, length, Reason); + } + } + } + else if (g_System->LookUpMode() == FuncFind_PhysicalLookup) + { + if (Address < g_System->RdramSize()) + { + int ClearLen = ((length + 3) & ~3); + if (Address + ClearLen > g_System->RdramSize()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + ClearLen = g_System->RdramSize() - Address; + } + WriteTrace(TraceRecompiler, TraceDebug, "Reseting Jump Table, Addr: %X len: %d", Address, ClearLen); + memset((uint8_t *)JumpTable() + Address, 0, ClearLen); + if (g_System->bSMM_Protect()) + { + g_MMU->UnProtectMemory(Address + 0x80000000, Address + 0x80000004); + } + } + else + { + WriteTrace(TraceRecompiler, TraceDebug, "Ignoring reset of Jump Table, Addr: %X len: %d", Address, ((length + 3) & ~3)); + } + } +} + +void CRecompiler::ClearRecompCode_Virt(uint32_t Address, int length, REMOVE_REASON Reason) +{ + switch (g_System->LookUpMode()) + { + case FuncFind_VirtualLookup: + { + uint32_t AddressIndex = Address >> 0xC; + uint32_t WriteStart = (Address & 0xFFC); + length = ((length + 3) & ~0x3); + + int DataInBlock = 0x1000 - WriteStart; + int DataToWrite = length < DataInBlock ? length : DataInBlock; + int DataLeft = length - DataToWrite; + + PCCompiledFunc_TABLE & table = FunctionTable()[AddressIndex]; + if (table) + { + WriteTrace(TraceRecompiler, TraceError, "Delete Table (%X): Index = %d", table, AddressIndex); + delete table; + table = NULL; + g_MMU->UnProtectMemory(Address, Address + length); + } + + if (DataLeft > 0) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + break; + case FuncFind_PhysicalLookup: + { + uint32_t pAddr = 0; + if (g_TransVaddr->TranslateVaddr(Address, pAddr)) + { + ClearRecompCode_Phys(pAddr, length, Reason); + } + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CRecompiler::ResetMemoryStackPos() +{ + if (g_MMU == NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + if (m_Registers.m_GPR[29].UW[0] == 0) + { + m_MemoryStack = 0; + return; + } + + uint32_t pAddr = 0; + if (g_TransVaddr->TranslateVaddr(m_Registers.m_GPR[29].UW[0], pAddr)) + { + m_MemoryStack = (uint32_t)(g_MMU->Rdram() + pAddr); + } + else + { + WriteTrace(TraceRecompiler, TraceError, "Failed to translate SP address (%s)", m_Registers.m_GPR[29].UW[0]); + g_Notify->BreakPoint(__FILE__, __LINE__); + } } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerClass.h b/Source/Project64-core/N64System/Recompiler/RecompilerClass.h index e8a200aba..09fcd2f13 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerClass.h +++ b/Source/Project64-core/N64System/Recompiler/RecompilerClass.h @@ -1,79 +1,79 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include -#include -#include -#include - -class CRecompiler : - protected CDebugSettings, - public CRecompilerSettings, - public CFunctionMap, - private CRecompMemory, - private CSystemRegisters -{ -public: - - enum REMOVE_REASON - { - Remove_InitialCode, - Remove_Cache, - Remove_ProtectedMem, - Remove_ValidateFunc, - Remove_TLB, - Remove_DMA, - Remove_StoreInstruc, - }; - - typedef void(*DelayFunc)(); - -public: - CRecompiler(CRegisters & Registers, CProfiling & Profile, bool & EndEmulation); - ~CRecompiler(); - - void Run(); - void Reset(); - void ResetRecompCode(bool bAllocate); - - //Self modifying code methods - void ClearRecompCode_Virt(uint32_t VirtualAddress, int32_t length, REMOVE_REASON Reason); - void ClearRecompCode_Phys(uint32_t PhysicalAddress, int32_t length, REMOVE_REASON Reason); - - void ResetMemoryStackPos(); - - uint32_t& MemoryStackPos() { return m_MemoryStack; } - -private: - CRecompiler(); // Disable default constructor - CRecompiler(const CRecompiler&); // Disable copy constructor - CRecompiler& operator=(const CRecompiler&); // Disable assignment - - CCompiledFunc * CompilerCode(); - - // Main loops for the different look up methods - void RecompilerMain_VirtualTable(); - void RecompilerMain_VirtualTable_validate(); - void RecompilerMain_ChangeMemory(); - void RecompilerMain_Lookup(); - void RecompilerMain_Lookup_TLB(); - void RecompilerMain_Lookup_validate(); - void RecompilerMain_Lookup_validate_TLB(); - - CCompiledFuncList m_Functions; - CRegisters & m_Registers; - CProfiling & m_Profile; - bool & m_EndEmulation; - uint32_t m_MemoryStack; - - //Quick access to registers - uint32_t & PROGRAM_COUNTER; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include +#include +#include +#include + +class CRecompiler : + protected CDebugSettings, + public CRecompilerSettings, + public CFunctionMap, + private CRecompMemory, + private CSystemRegisters +{ +public: + + enum REMOVE_REASON + { + Remove_InitialCode, + Remove_Cache, + Remove_ProtectedMem, + Remove_ValidateFunc, + Remove_TLB, + Remove_DMA, + Remove_StoreInstruc, + }; + + typedef void(*DelayFunc)(); + +public: + CRecompiler(CRegisters & Registers, CProfiling & Profile, bool & EndEmulation); + ~CRecompiler(); + + void Run(); + void Reset(); + void ResetRecompCode(bool bAllocate); + + //Self modifying code methods + void ClearRecompCode_Virt(uint32_t VirtualAddress, int32_t length, REMOVE_REASON Reason); + void ClearRecompCode_Phys(uint32_t PhysicalAddress, int32_t length, REMOVE_REASON Reason); + + void ResetMemoryStackPos(); + + uint32_t& MemoryStackPos() { return m_MemoryStack; } + +private: + CRecompiler(); // Disable default constructor + CRecompiler(const CRecompiler&); // Disable copy constructor + CRecompiler& operator=(const CRecompiler&); // Disable assignment + + CCompiledFunc * CompilerCode(); + + // Main loops for the different look up methods + void RecompilerMain_VirtualTable(); + void RecompilerMain_VirtualTable_validate(); + void RecompilerMain_ChangeMemory(); + void RecompilerMain_Lookup(); + void RecompilerMain_Lookup_TLB(); + void RecompilerMain_Lookup_validate(); + void RecompilerMain_Lookup_validate_TLB(); + + CCompiledFuncList m_Functions; + CRegisters & m_Registers; + CProfiling & m_Profile; + bool & m_EndEmulation; + uint32_t m_MemoryStack; + + //Quick access to registers + uint32_t & PROGRAM_COUNTER; +}; diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerMemory.cpp b/Source/Project64-core/N64System/Recompiler/RecompilerMemory.cpp index 7bd359adb..d3eba4479 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerMemory.cpp +++ b/Source/Project64-core/N64System/Recompiler/RecompilerMemory.cpp @@ -1,95 +1,95 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include - -CRecompMemory::CRecompMemory() : -m_RecompCode(NULL), -m_RecompSize(0) -{ - m_RecompPos = NULL; -} - -CRecompMemory::~CRecompMemory() -{ - if (m_RecompCode) - { - FreeAddressSpace(m_RecompCode,MaxCompileBufferSize + 4); - m_RecompCode = NULL; - } - m_RecompPos = NULL; -} - -bool CRecompMemory::AllocateMemory() -{ - uint8_t * RecompCodeBase = (uint8_t *)AllocateAddressSpace(MaxCompileBufferSize + 4); - if (RecompCodeBase == NULL) - { - WriteTrace(TraceRecompiler, TraceError, "failed to allocate RecompCodeBase"); - g_Notify->DisplayError(MSG_MEM_ALLOC_ERROR); - return false; - } - - m_RecompCode = (uint8_t *)CommitMemory(RecompCodeBase, InitialCompileBufferSize, MEM_EXECUTE_READWRITE); - if (m_RecompCode == NULL) - { - WriteTrace(TraceRecompiler, TraceError, "failed to commit initial buffer"); - FreeAddressSpace(RecompCodeBase,MaxCompileBufferSize + 4); - g_Notify->DisplayError(MSG_MEM_ALLOC_ERROR); - return false; - } - m_RecompSize = InitialCompileBufferSize; - m_RecompPos = m_RecompCode; - memset(m_RecompCode, 0, InitialCompileBufferSize); - return true; -} - -void CRecompMemory::CheckRecompMem() -{ - uint32_t Size = (uint32_t)((uint8_t *)m_RecompPos - (uint8_t *)m_RecompCode); - if ((Size + 0x20000) < m_RecompSize) - { - return; - } - if (m_RecompSize == MaxCompileBufferSize) - { - g_Recompiler->ResetRecompCode(true); - return; - } - void * MemAddr = CommitMemory(m_RecompCode + m_RecompSize, IncreaseCompileBufferSize, MEM_EXECUTE_READWRITE); - if (MemAddr == NULL) - { - WriteTrace(TraceRecompiler, TraceError, "failed to increase buffer"); - g_Notify->FatalError(MSG_MEM_ALLOC_ERROR); - } - m_RecompSize += IncreaseCompileBufferSize; -} - -void CRecompMemory::Reset() -{ - m_RecompPos = m_RecompCode; -} - -void CRecompMemory::ShowMemUsed() -{ - uint32_t Size = m_RecompPos - m_RecompCode; - uint32_t MB = Size / 0x100000; - Size -= MB * 0x100000; - uint32_t KB = Size / 1024; - Size -= KB * 1024; - - uint32_t TotalAvaliable = m_RecompSize / 0x100000; - - g_Notify->DisplayMessage(0, stdstr_f("Memory used: %d mb %-3d kb %-3d bytes Total Available: %d mb", MB, KB, Size, TotalAvaliable).c_str()); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include + +CRecompMemory::CRecompMemory() : +m_RecompCode(NULL), +m_RecompSize(0) +{ + m_RecompPos = NULL; +} + +CRecompMemory::~CRecompMemory() +{ + if (m_RecompCode) + { + FreeAddressSpace(m_RecompCode,MaxCompileBufferSize + 4); + m_RecompCode = NULL; + } + m_RecompPos = NULL; +} + +bool CRecompMemory::AllocateMemory() +{ + uint8_t * RecompCodeBase = (uint8_t *)AllocateAddressSpace(MaxCompileBufferSize + 4); + if (RecompCodeBase == NULL) + { + WriteTrace(TraceRecompiler, TraceError, "failed to allocate RecompCodeBase"); + g_Notify->DisplayError(MSG_MEM_ALLOC_ERROR); + return false; + } + + m_RecompCode = (uint8_t *)CommitMemory(RecompCodeBase, InitialCompileBufferSize, MEM_EXECUTE_READWRITE); + if (m_RecompCode == NULL) + { + WriteTrace(TraceRecompiler, TraceError, "failed to commit initial buffer"); + FreeAddressSpace(RecompCodeBase,MaxCompileBufferSize + 4); + g_Notify->DisplayError(MSG_MEM_ALLOC_ERROR); + return false; + } + m_RecompSize = InitialCompileBufferSize; + m_RecompPos = m_RecompCode; + memset(m_RecompCode, 0, InitialCompileBufferSize); + return true; +} + +void CRecompMemory::CheckRecompMem() +{ + uint32_t Size = (uint32_t)((uint8_t *)m_RecompPos - (uint8_t *)m_RecompCode); + if ((Size + 0x20000) < m_RecompSize) + { + return; + } + if (m_RecompSize == MaxCompileBufferSize) + { + g_Recompiler->ResetRecompCode(true); + return; + } + void * MemAddr = CommitMemory(m_RecompCode + m_RecompSize, IncreaseCompileBufferSize, MEM_EXECUTE_READWRITE); + if (MemAddr == NULL) + { + WriteTrace(TraceRecompiler, TraceError, "failed to increase buffer"); + g_Notify->FatalError(MSG_MEM_ALLOC_ERROR); + } + m_RecompSize += IncreaseCompileBufferSize; +} + +void CRecompMemory::Reset() +{ + m_RecompPos = m_RecompCode; +} + +void CRecompMemory::ShowMemUsed() +{ + uint32_t Size = m_RecompPos - m_RecompCode; + uint32_t MB = Size / 0x100000; + Size -= MB * 0x100000; + uint32_t KB = Size / 1024; + Size -= KB * 1024; + + uint32_t TotalAvaliable = m_RecompSize / 0x100000; + + g_Notify->DisplayMessage(0, stdstr_f("Memory used: %d mb %-3d kb %-3d bytes Total Available: %d mb", MB, KB, Size, TotalAvaliable).c_str()); } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerMemory.h b/Source/Project64-core/N64System/Recompiler/RecompilerMemory.h index 47db91a83..3d8b0568d 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerMemory.h +++ b/Source/Project64-core/N64System/Recompiler/RecompilerMemory.h @@ -1,38 +1,38 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include - -class CRecompMemory : - protected CX86Ops -{ -protected: - CRecompMemory(); - ~CRecompMemory(); - - bool AllocateMemory(); - void CheckRecompMem(); - void Reset(); - void ShowMemUsed(); - - uint8_t* RecompPos() const { return m_RecompPos; } - -private: - CRecompMemory(const CRecompMemory&); // Disable copy constructor - CRecompMemory& operator=(const CRecompMemory&); // Disable assignment - - uint8_t * m_RecompCode; - uint32_t m_RecompSize; - - enum { MaxCompileBufferSize = 0x03C00000 }; - enum { InitialCompileBufferSize = 0x00500000 }; - enum { IncreaseCompileBufferSize = 0x00100000 }; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +class CRecompMemory : + protected CX86Ops +{ +protected: + CRecompMemory(); + ~CRecompMemory(); + + bool AllocateMemory(); + void CheckRecompMem(); + void Reset(); + void ShowMemUsed(); + + uint8_t* RecompPos() const { return m_RecompPos; } + +private: + CRecompMemory(const CRecompMemory&); // Disable copy constructor + CRecompMemory& operator=(const CRecompMemory&); // Disable assignment + + uint8_t * m_RecompCode; + uint32_t m_RecompSize; + + enum { MaxCompileBufferSize = 0x03C00000 }; + enum { InitialCompileBufferSize = 0x00500000 }; + enum { IncreaseCompileBufferSize = 0x00100000 }; +}; diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/RecompilerOps.cpp index b12627a76..3cb0af2f7 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/RecompilerOps.cpp @@ -1,6742 +1,6742 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "x86CodeLog.h" - -CCodeSection * CRecompilerOps::m_Section = NULL; -CRegInfo CRecompilerOps::m_RegWorkingSet; -STEP_TYPE CRecompilerOps::m_NextInstruction; -uint32_t CRecompilerOps::m_CompilePC; -OPCODE CRecompilerOps::m_Opcode; -uint32_t CRecompilerOps::m_BranchCompare = 0; - -void CRecompilerOps::CompileReadTLBMiss(uint32_t VirtualAddress, x86Reg LookUpReg) -{ - MoveConstToVariable(VirtualAddress, g_TLBLoadAddress, "TLBLoadAddress"); - TestX86RegToX86Reg(LookUpReg, LookUpReg); - m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBReadMiss, false, JeLabel32); -} - -void CRecompilerOps::CompileReadTLBMiss(x86Reg AddressReg, x86Reg LookUpReg) -{ - MoveX86regToVariable(AddressReg, g_TLBLoadAddress, "TLBLoadAddress"); - TestX86RegToX86Reg(LookUpReg, LookUpReg); - m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBReadMiss, false, JeLabel32); -} - -void CRecompilerOps::CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg) -{ - MoveX86regToVariable(AddressReg, &g_TLBStoreAddress, "g_TLBStoreAddress"); - TestX86RegToX86Reg(LookUpReg, LookUpReg); - m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBWriteMiss, false, JeLabel32); -} - -bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); - -/************************** Branch functions ************************/ -void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link) -{ - static CRegInfo RegBeforeDelay; - static bool EffectDelaySlot; - - if (m_NextInstruction == NORMAL) - { - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4 == m_CompilePC + 8) - { - return; - } - - if ((m_CompilePC & 0xFFC) != 0xFFC) - { - switch (BranchType) - { - case BranchTypeRs: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0); break; - case BranchTypeRsRt: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, m_Opcode.rt); break; - case BranchTypeCop1: - { - OPCODE Command; - - if (!g_MMU->LW_VAddr(m_CompilePC + 4, Command.Hex)) - { - g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD)); - } - - EffectDelaySlot = false; - if (Command.op == R4300i_CP1) - { - if ((Command.fmt == R4300i_COP1_S && (Command.funct & 0x30) == 0x30) || - (Command.fmt == R4300i_COP1_D && (Command.funct & 0x30) == 0x30)) - { - EffectDelaySlot = true; - } - } - } - break; - default: - if (bHaveDebugger()) { g_Notify->DisplayError("Unknown branch type"); } - } - } - else - { - EffectDelaySlot = true; - } - m_Section->m_Jump.JumpPC = m_CompilePC; - m_Section->m_Jump.TargetPC = m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4; - if (m_Section->m_JumpSection != NULL) - { - m_Section->m_Jump.BranchLabel.Format("Section_%d", m_Section->m_JumpSection->m_SectionID); - } - else - { - m_Section->m_Jump.BranchLabel.Format("Exit_%X_jump_%X", m_Section->m_EnterPC, m_Section->m_Jump.TargetPC); - } - m_Section->m_Jump.LinkLocation = NULL; - m_Section->m_Jump.LinkLocation2 = NULL; - m_Section->m_Jump.DoneDelaySlot = false; - m_Section->m_Cont.JumpPC = m_CompilePC; - m_Section->m_Cont.TargetPC = m_CompilePC + 8; - if (m_Section->m_ContinueSection != NULL) - { - m_Section->m_Cont.BranchLabel.Format("Section_%d", m_Section->m_ContinueSection->m_SectionID); - } - else - { - m_Section->m_Cont.BranchLabel.Format("Exit_%X_continue_%X", m_Section->m_EnterPC, m_Section->m_Cont.TargetPC); - } - m_Section->m_Cont.LinkLocation = NULL; - m_Section->m_Cont.LinkLocation2 = NULL; - m_Section->m_Cont.DoneDelaySlot = false; - if (m_Section->m_Jump.TargetPC < m_Section->m_Cont.TargetPC) - { - m_Section->m_Cont.FallThrough = false; - m_Section->m_Jump.FallThrough = true; - } - else - { - m_Section->m_Cont.FallThrough = true; - m_Section->m_Jump.FallThrough = false; - } - - if (Link) - { - UnMap_GPR(31, false); - m_RegWorkingSet.SetMipsRegLo(31, m_CompilePC + 8); - m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); - } - if (EffectDelaySlot) - { - if ((m_CompilePC & 0xFFC) != 0xFFC) - { - m_Section->m_Cont.BranchLabel = m_Section->m_ContinueSection != NULL ? "Continue" : "ExitBlock"; - m_Section->m_Jump.BranchLabel = m_Section->m_JumpSection != NULL ? "Jump" : "ExitBlock"; - } - else - { - m_Section->m_Cont.BranchLabel = "Continue"; - m_Section->m_Jump.BranchLabel = "Jump"; - } - if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC) - { - CompareFunc(); - } - if (!m_Section->m_Jump.FallThrough && !m_Section->m_Cont.FallThrough) - { - if (m_Section->m_Jump.LinkLocation != NULL) - { - CPU_Message(""); - CPU_Message(" %s:", m_Section->m_Jump.BranchLabel.c_str()); - SetJump32((uint32_t *)m_Section->m_Jump.LinkLocation, (uint32_t *)m_RecompPos); - m_Section->m_Jump.LinkLocation = NULL; - if (m_Section->m_Jump.LinkLocation2 != NULL) - { - SetJump32((uint32_t *)m_Section->m_Jump.LinkLocation2, (uint32_t *)m_RecompPos); - m_Section->m_Jump.LinkLocation2 = NULL; - } - m_Section->m_Jump.FallThrough = true; - } - else if (m_Section->m_Cont.LinkLocation != NULL) - { - CPU_Message(""); - CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str()); - SetJump32((uint32_t *)m_Section->m_Cont.LinkLocation, (uint32_t *)m_RecompPos); - m_Section->m_Cont.LinkLocation = NULL; - if (m_Section->m_Cont.LinkLocation2 != NULL) - { - SetJump32((uint32_t *)m_Section->m_Cont.LinkLocation2, (uint32_t *)m_RecompPos); - m_Section->m_Cont.LinkLocation2 = NULL; - } - m_Section->m_Cont.FallThrough = true; - } - } - if ((m_CompilePC & 0xFFC) == 0xFFC) - { - uint8_t * DelayLinkLocation = NULL; - if (m_Section->m_Jump.FallThrough) - { - if (m_Section->m_Jump.LinkLocation != NULL || m_Section->m_Jump.LinkLocation2 != NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - } - else if (m_Section->m_Cont.FallThrough) - { - if (m_Section->m_Cont.LinkLocation != NULL || m_Section->m_Cont.LinkLocation2 != NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - MoveConstToVariable(m_Section->m_Cont.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - } - - if (m_Section->m_Jump.LinkLocation != NULL || m_Section->m_Jump.LinkLocation2 != NULL) - { - JmpLabel8("DoDelaySlot", 0); - if (DelayLinkLocation != NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } - DelayLinkLocation = (uint8_t *)(m_RecompPos - 1); - - CPU_Message(" "); - CPU_Message(" %s:", m_Section->m_Jump.BranchLabel.c_str()); - SetJump32(m_Section->m_Jump.LinkLocation, (uint32_t *)m_RecompPos); - m_Section->m_Jump.LinkLocation = NULL; - if (m_Section->m_Jump.LinkLocation2 != NULL) - { - SetJump32(m_Section->m_Jump.LinkLocation2, (uint32_t *)m_RecompPos); - m_Section->m_Jump.LinkLocation2 = NULL; - } - MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - } - if (m_Section->m_Cont.LinkLocation != NULL || m_Section->m_Cont.LinkLocation2 != NULL) - { - JmpLabel8("DoDelaySlot", 0); - if (DelayLinkLocation != NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } - DelayLinkLocation = (uint8_t *)(m_RecompPos - 1); - - CPU_Message(" "); - CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str()); - SetJump32(m_Section->m_Cont.LinkLocation, (uint32_t *)m_RecompPos); - m_Section->m_Cont.LinkLocation = NULL; - if (m_Section->m_Cont.LinkLocation2 != NULL) - { - SetJump32(m_Section->m_Cont.LinkLocation2, (uint32_t *)m_RecompPos); - m_Section->m_Cont.LinkLocation2 = NULL; - } - MoveConstToVariable(m_Section->m_Cont.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - } - if (DelayLinkLocation) - { - CPU_Message(""); - CPU_Message(" DoDelaySlot:"); - SetJump8(DelayLinkLocation, m_RecompPos); - } - OverflowDelaySlot(false); - return; - } - ResetX86Protection(); - RegBeforeDelay = m_RegWorkingSet; - } - m_NextInstruction = DO_DELAY_SLOT; - } - else if (m_NextInstruction == DELAY_SLOT_DONE) - { - if (EffectDelaySlot) - { - CJumpInfo * FallInfo = m_Section->m_Jump.FallThrough ? &m_Section->m_Jump : &m_Section->m_Cont; - CJumpInfo * JumpInfo = m_Section->m_Jump.FallThrough ? &m_Section->m_Cont : &m_Section->m_Jump; - - if (FallInfo->FallThrough && !FallInfo->DoneDelaySlot) - { - ResetX86Protection(); - FallInfo->RegSet = m_RegWorkingSet; - if (FallInfo == &m_Section->m_Jump) - { - if (m_Section->m_JumpSection != NULL) - { - m_Section->m_Jump.BranchLabel.Format("Section_%d", m_Section->m_JumpSection->m_SectionID); - } - else - { - m_Section->m_Jump.BranchLabel = "ExitBlock"; - } - if (FallInfo->TargetPC <= m_CompilePC) - { - UpdateCounters(m_Section->m_Jump.RegSet, true, true); - CPU_Message("CompileSystemCheck 12"); - CompileSystemCheck(FallInfo->TargetPC, m_Section->m_Jump.RegSet); - ResetX86Protection(); - FallInfo->ExitReason = CExitInfo::Normal_NoSysCheck; - FallInfo->JumpPC = (uint32_t)-1; - } - } - else - { - if (m_Section->m_ContinueSection != NULL) - { - m_Section->m_Cont.BranchLabel.Format("Section_%d", m_Section->m_ContinueSection->m_SectionID); - } - else - { - m_Section->m_Cont.BranchLabel = "ExitBlock"; - } - } - FallInfo->DoneDelaySlot = true; - if (!JumpInfo->DoneDelaySlot) - { - FallInfo->FallThrough = false; - JmpLabel32(FallInfo->BranchLabel.c_str(), 0); - FallInfo->LinkLocation = (uint32_t *)(m_RecompPos - 4); - - if (JumpInfo->LinkLocation != NULL) - { - CPU_Message(" %s:", JumpInfo->BranchLabel.c_str()); - SetJump32((uint32_t *)JumpInfo->LinkLocation, (uint32_t *)m_RecompPos); - JumpInfo->LinkLocation = NULL; - if (JumpInfo->LinkLocation2 != NULL) - { - SetJump32((uint32_t *)JumpInfo->LinkLocation2, (uint32_t *)m_RecompPos); - JumpInfo->LinkLocation2 = NULL; - } - JumpInfo->FallThrough = true; - m_NextInstruction = DO_DELAY_SLOT; - m_RegWorkingSet = RegBeforeDelay; - return; - } - } - } - } - else - { - if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC) - { - CompareFunc(); - ResetX86Protection(); - m_Section->m_Cont.RegSet = m_RegWorkingSet; - m_Section->m_Jump.RegSet = m_RegWorkingSet; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - m_Section->m_Cont.RegSet = m_RegWorkingSet; - if (m_Section->m_ContinueSection == NULL && m_Section->m_JumpSection != NULL) - { - m_Section->m_ContinueSection = m_Section->m_JumpSection; - m_Section->m_JumpSection = NULL; - } - if (m_Section->m_ContinueSection != NULL) - { - m_Section->m_Cont.BranchLabel.Format("Section_%d", m_Section->m_ContinueSection->m_SectionID); - } - else - { - m_Section->m_Cont.BranchLabel = "ExitBlock"; - } - } - } - m_Section->GenerateSectionLinkage(); - m_NextInstruction = END_BLOCK; - } - else - { - if (bHaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); - } - } -} - -void CRecompilerOps::Compile_BranchLikely(BranchFunction CompareFunc, bool Link) -{ - if (m_NextInstruction == NORMAL) - { - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (!g_System->bLinkBlocks() || (m_CompilePC & 0xFFC) == 0xFFC) - { - m_Section->m_Jump.JumpPC = m_CompilePC; - m_Section->m_Jump.TargetPC = m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4; - m_Section->m_Cont.JumpPC = m_CompilePC; - m_Section->m_Cont.TargetPC = m_CompilePC + 8; - } - else - { - if (m_Section->m_Jump.JumpPC != m_CompilePC) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_Section->m_Cont.JumpPC != m_CompilePC) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_Section->m_Cont.TargetPC != m_CompilePC + 8) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - - if (m_Section->m_JumpSection != NULL) - { - m_Section->m_Jump.BranchLabel.Format("Section_%d", ((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); - } - else - { - m_Section->m_Jump.BranchLabel = "ExitBlock"; - } - - if (m_Section->m_ContinueSection != NULL) - { - m_Section->m_Cont.BranchLabel.Format("Section_%d", ((CCodeSection *)m_Section->m_ContinueSection)->m_SectionID); - } - else - { - m_Section->m_Cont.BranchLabel = "ExitBlock"; - } - - m_Section->m_Jump.FallThrough = true; - m_Section->m_Jump.LinkLocation = NULL; - m_Section->m_Jump.LinkLocation2 = NULL; - m_Section->m_Cont.FallThrough = false; - m_Section->m_Cont.LinkLocation = NULL; - m_Section->m_Cont.LinkLocation2 = NULL; - - if (Link) - { - UnMap_GPR(31, false); - m_RegWorkingSet.SetMipsRegLo(31, m_CompilePC + 8); - m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); - } - - CompareFunc(); - ResetX86Protection(); - - m_Section->m_Cont.RegSet = m_RegWorkingSet; - if ((m_CompilePC & 0xFFC) == 0xFFC) - { - if (m_Section->m_Cont.FallThrough) - { - if (m_Section->m_Jump.LinkLocation != NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - - if (m_Section->m_Jump.LinkLocation != NULL || m_Section->m_Jump.FallThrough) - { - if (m_Section->m_Jump.LinkLocation != NULL) - { - SetJump32(m_Section->m_Jump.LinkLocation, (uint32_t *)m_RecompPos); - m_Section->m_Jump.LinkLocation = NULL; - if (m_Section->m_Jump.LinkLocation2 != NULL) - { - SetJump32(m_Section->m_Jump.LinkLocation2, (uint32_t *)m_RecompPos); - m_Section->m_Jump.LinkLocation2 = NULL; - } - } - - MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - OverflowDelaySlot(false); - CPU_Message(" "); - CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str()); - } - else if (!m_Section->m_Cont.FallThrough) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - if (m_Section->m_Cont.LinkLocation != NULL) - { - SetJump32(m_Section->m_Cont.LinkLocation, (uint32_t *)m_RecompPos); - m_Section->m_Cont.LinkLocation = NULL; - if (m_Section->m_Cont.LinkLocation2 != NULL) - { - SetJump32(m_Section->m_Cont.LinkLocation2, (uint32_t *)m_RecompPos); - m_Section->m_Cont.LinkLocation2 = NULL; - } - } - m_Section->CompileExit(m_CompilePC, m_CompilePC + 8, m_Section->m_Cont.RegSet, CExitInfo::Normal, true, NULL); - return; - } - else - { - m_NextInstruction = DO_DELAY_SLOT; - } - - if (g_System->bLinkBlocks()) - { - m_Section->m_Jump.RegSet = m_RegWorkingSet; - m_Section->GenerateSectionLinkage(); - m_NextInstruction = END_BLOCK; - } - else - { - if (m_Section->m_Cont.FallThrough) - { - if (m_Section->m_Jump.LinkLocation != NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - m_Section->GenerateSectionLinkage(); - m_NextInstruction = END_BLOCK; - } - } - } - else if (m_NextInstruction == DELAY_SLOT_DONE) - { - ResetX86Protection(); - m_Section->m_Jump.RegSet = m_RegWorkingSet; - m_Section->GenerateSectionLinkage(); - m_NextInstruction = END_BLOCK; - } - else if (bHaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("WTF\n\nBranchLikely\nNextInstruction = %X", m_NextInstruction).c_str()); - } -} - -void CRecompilerOps::BNE_Compare() -{ - uint8_t *Jump = NULL; - - if (IsKnown(m_Opcode.rs) && IsKnown(m_Opcode.rt)) - { - if (IsConst(m_Opcode.rs) && IsConst(m_Opcode.rt)) - { - if (Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) - { - CRecompilerOps::UnknownOpcode(); - } - else if (GetMipsRegLo(m_Opcode.rs) != GetMipsRegLo(m_Opcode.rt)) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else if (IsMapped(m_Opcode.rs) && IsMapped(m_Opcode.rt)) - { - ProtectGPR(m_Opcode.rs); - ProtectGPR(m_Opcode.rt); - if (Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) - { - CompX86RegToX86Reg( - Is32Bit(m_Opcode.rs) ? Map_TempReg(x86_Any, m_Opcode.rs, true) : GetMipsRegMapHi(m_Opcode.rs), - Is32Bit(m_Opcode.rt) ? Map_TempReg(x86_Any, m_Opcode.rt, true) : GetMipsRegMapHi(m_Opcode.rt) - ); - - if (m_Section->m_Jump.FallThrough) - { - JneLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); - if (m_Section->m_Cont.FallThrough) - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - CPU_Message(" "); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - else - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); - if (m_Section->m_Cont.FallThrough) - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - } - else - { - uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (Is64Bit(ConstReg) || Is64Bit(MappedReg)) - { - if (Is32Bit(ConstReg) || Is32Bit(MappedReg)) - { - ProtectGPR(MappedReg); - if (Is32Bit(MappedReg)) - { - CompConstToX86reg(Map_TempReg(x86_Any, MappedReg, true), GetMipsRegHi(ConstReg)); - } - else - { - CompConstToX86reg(GetMipsRegMapHi(MappedReg), GetMipsRegLo_S(ConstReg) >> 31); - } - } - else - { - CompConstToX86reg(GetMipsRegMapHi(MappedReg), GetMipsRegHi(ConstReg)); - } - if (m_Section->m_Jump.FallThrough) - { - JneLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); - if (m_Section->m_Cont.FallThrough) - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - CPU_Message(" "); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - else - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); - if (m_Section->m_Cont.FallThrough) - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - } - } - else if (IsKnown(m_Opcode.rs) || IsKnown(m_Opcode.rt)) - { - uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (!g_System->b32BitCore()) - { - if (IsConst(KnownReg)) - { - if (Is64Bit(KnownReg)) - { - CompConstToVariable(GetMipsRegHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else if (IsSigned(KnownReg)) - { - CompConstToVariable((GetMipsRegLo_S(KnownReg) >> 31), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else - { - CompConstToVariable(0, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - } - else - { - if (Is64Bit(KnownReg)) - { - CompX86regToVariable(GetMipsRegMapHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else if (IsSigned(KnownReg)) - { - ProtectGPR(KnownReg); - CompX86regToVariable(Map_TempReg(x86_Any, KnownReg, true), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else - { - CompConstToVariable(0, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - } - if (m_Section->m_Jump.FallThrough) - { - JneLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - if (IsConst(KnownReg)) - { - CompConstToVariable(GetMipsRegLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - else - { - CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - if (m_Section->m_Cont.FallThrough) - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - if (g_System->b32BitCore()) - { - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - else if (m_Section->m_Jump.FallThrough) - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - - if (Jump) - { - CPU_Message(" "); - CPU_Message(" continue:"); - - SetJump8(Jump, m_RecompPos); - } - } - else - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - if (g_System->b32BitCore()) - { - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - } - else - { - x86Reg Reg = x86_Any; - - if (!g_System->b32BitCore()) - { - Reg = Map_TempReg(x86_Any, m_Opcode.rt, true); - CompX86regToVariable(Reg, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); - if (m_Section->m_Jump.FallThrough) - { - JneLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - - Reg = Map_TempReg(Reg, m_Opcode.rt, false); - CompX86regToVariable(Reg, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - if (m_Section->m_Cont.FallThrough) - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - if (g_System->b32BitCore()) - { - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - else if (m_Section->m_Jump.FallThrough) - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - if (Jump) - { - CPU_Message(" "); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - } - else - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - if (g_System->b32BitCore()) - { - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - } -} - -void CRecompilerOps::BEQ_Compare() -{ - uint8_t *Jump = NULL; - - if (IsKnown(m_Opcode.rs) && IsKnown(m_Opcode.rt)) - { - if (IsConst(m_Opcode.rs) && IsConst(m_Opcode.rt)) - { - if (Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) - { - CRecompilerOps::UnknownOpcode(); - } - else if (GetMipsRegLo(m_Opcode.rs) == GetMipsRegLo(m_Opcode.rt)) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else if (IsMapped(m_Opcode.rs) && IsMapped(m_Opcode.rt)) - { - if ((Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) && !g_System->b32BitCore()) - { - ProtectGPR(m_Opcode.rs); - ProtectGPR(m_Opcode.rt); - - CompX86RegToX86Reg( - Is32Bit(m_Opcode.rs) ? Map_TempReg(x86_Any, m_Opcode.rs, true) : GetMipsRegMapHi(m_Opcode.rs), - Is32Bit(m_Opcode.rt) ? Map_TempReg(x86_Any, m_Opcode.rt, true) : GetMipsRegMapHi(m_Opcode.rt) - ); - if (m_Section->m_Cont.FallThrough) - { - JneLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); - if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - CPU_Message(" "); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - else if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); - if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - } - else - { - uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (Is64Bit(ConstReg) || Is64Bit(MappedReg)) - { - if (Is32Bit(ConstReg) || Is32Bit(MappedReg)) - { - if (Is32Bit(MappedReg)) - { - ProtectGPR(MappedReg); - CompConstToX86reg(Map_TempReg(x86_Any, MappedReg, true), GetMipsRegHi(ConstReg)); - } - else - { - CompConstToX86reg(GetMipsRegMapHi(MappedReg), GetMipsRegLo_S(ConstReg) >> 31); - } - } - else - { - CompConstToX86reg(GetMipsRegMapHi(MappedReg), GetMipsRegHi(ConstReg)); - } - if (m_Section->m_Cont.FallThrough) { - JneLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); - if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - CPU_Message(" "); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - else if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); - if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - } - } - else if (IsKnown(m_Opcode.rs) || IsKnown(m_Opcode.rt)) - { - uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (!g_System->b32BitCore()) - { - if (IsConst(KnownReg)) - { - if (Is64Bit(KnownReg)) - { - CompConstToVariable(GetMipsRegHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else if (IsSigned(KnownReg)) - { - CompConstToVariable(GetMipsRegLo_S(KnownReg) >> 31, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else - { - CompConstToVariable(0, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - } - else - { - ProtectGPR(KnownReg); - if (Is64Bit(KnownReg)) - { - CompX86regToVariable(GetMipsRegMapHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else if (IsSigned(KnownReg)) - { - CompX86regToVariable(Map_TempReg(x86_Any, KnownReg, true), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else - { - CompConstToVariable(0, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - } - if (m_Section->m_Cont.FallThrough) - { - JneLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - if (IsConst(KnownReg)) - { - CompConstToVariable(GetMipsRegLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - else - { - CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - if (Jump) - { - CPU_Message(" "); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - } - else if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - if (g_System->b32BitCore()) - { - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - x86Reg Reg = x86_Any; - if (!g_System->b32BitCore()) - { - Reg = Map_TempReg(x86_Any, m_Opcode.rs, true); - CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); - if (m_Section->m_Cont.FallThrough) - { - JneLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - CompX86regToVariable(Map_TempReg(Reg, m_Opcode.rs, false), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - if (Jump) - { - CPU_Message(" "); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - } - else if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - if (g_System->b32BitCore()) - { - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - if (g_System->b32BitCore()) - { - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } -} - -void CRecompilerOps::BGTZ_Compare() -{ - if (IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - if (GetMipsReg_S(m_Opcode.rs) > 0) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else - { - if (GetMipsRegLo_S(m_Opcode.rs) > 0) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - } - else if (IsMapped(m_Opcode.rs) && Is32Bit(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); - if (m_Section->m_Jump.FallThrough) - { - JleLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Cont.FallThrough) - { - JgLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JleLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else if (IsUnknown(m_Opcode.rs) && g_System->b32BitCore()) - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - if (m_Section->m_Jump.FallThrough) - { - JleLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Cont.FallThrough) - { - JgLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JleLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - uint8_t *Jump = NULL; - - if (IsMapped(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), 0); - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); - } - if (m_Section->m_Jump.FallThrough) - { - JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JgLabel8("continue", 0); - Jump = m_RecompPos - 1; - } - else if (m_Section->m_Cont.FallThrough) - { - JlLabel8("continue", 0); - Jump = m_RecompPos - 1; - JgLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JgLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - - if (IsMapped(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - } - if (m_Section->m_Jump.FallThrough) - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - else if (m_Section->m_Cont.FallThrough) - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - else - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } -} - -void CRecompilerOps::BLEZ_Compare() -{ - if (IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - if (GetMipsReg_S(m_Opcode.rs) <= 0) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else if (IsSigned(m_Opcode.rs)) - { - if (GetMipsRegLo_S(m_Opcode.rs) <= 0) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else - { - if (GetMipsRegLo(m_Opcode.rs) == 0) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - } - else if (IsMapped(m_Opcode.rs)) - { - if (Is32Bit(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); - if (m_Section->m_Jump.FallThrough) - { - JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Cont.FallThrough) - { - JleLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - uint8_t *Jump = NULL; - - if (IsMapped(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), 0); - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); - } - if (m_Section->m_Jump.FallThrough) - { - JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JlLabel8("Continue", 0); - Jump = m_RecompPos - 1; - } - else if (m_Section->m_Cont.FallThrough) - { - JgLabel8("Continue", 0); - Jump = m_RecompPos - 1; - JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - - if (IsMapped(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - } - if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - else if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - JmpLabel32("BranchToJump", 0); - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - } - else { - uint8_t *Jump = NULL; - - if (!g_System->b32BitCore()) - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); - if (m_Section->m_Jump.FallThrough) - { - JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JlLabel8("Continue", 0); - Jump = m_RecompPos - 1; - } - else if (m_Section->m_Cont.FallThrough) - { - JgLabel8("Continue", 0); - Jump = m_RecompPos - 1; - JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - if (g_System->b32BitCore()) - { - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - if (Jump) - { - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - } - else if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - if (Jump) - { - CPU_Message(" continue:"); - SetJump8(Jump, m_RecompPos); - } - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - JmpLabel32("BranchToJump", 0); - m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - if (m_Section->m_Jump.FallThrough) - { - JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Cont.FallThrough) - { - JleLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - } -} - -void CRecompilerOps::BLTZ_Compare() -{ - if (IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - if (GetMipsReg_S(m_Opcode.rs) < 0) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else if (IsSigned(m_Opcode.rs)) - { - if (GetMipsRegLo_S(m_Opcode.rs) < 0) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else if (IsMapped(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), 0); - if (m_Section->m_Jump.FallThrough) - { - JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Cont.FallThrough) - { - JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else if (IsSigned(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); - if (m_Section->m_Jump.FallThrough) - { - JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Cont.FallThrough) - { - JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else if (IsUnknown(m_Opcode.rs)) - { - if (g_System->b32BitCore()) - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); - } - if (m_Section->m_Jump.FallThrough) - { - JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Cont.FallThrough) - { - JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } -} - -void CRecompilerOps::BGEZ_Compare() -{ - if (IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - CRecompilerOps::UnknownOpcode(); - } - else if (IsSigned(m_Opcode.rs)) - { - if (GetMipsRegLo_S(m_Opcode.rs) >= 0) - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - else - { - m_Section->m_Jump.FallThrough = false; - m_Section->m_Cont.FallThrough = true; - } - } - else - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - } - else if (IsMapped(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), 0); - if (m_Section->m_Cont.FallThrough) - { - JgeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else if (IsSigned(m_Opcode.rs)) - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); - if (m_Section->m_Cont.FallThrough) - { - JgeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } - else - { - m_Section->m_Jump.FallThrough = true; - m_Section->m_Cont.FallThrough = false; - } - } - else - { - if (g_System->b32BitCore()) - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); - } - if (m_Section->m_Cont.FallThrough) - { - JgeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - } -} - -void CRecompilerOps::COP1_BCF_Compare() -{ - TestVariable(FPCSR_C, &_FPCR[31], "_FPCR[31]"); - if (m_Section->m_Cont.FallThrough) - { - JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } -} - -void CRecompilerOps::COP1_BCT_Compare() -{ - TestVariable(FPCSR_C, &_FPCR[31], "_FPCR[31]"); - if (m_Section->m_Cont.FallThrough) - { - JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else if (m_Section->m_Jump.FallThrough) - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } - else - { - JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); - m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); - JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); - m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); - } -} - -/************************* OpCode functions *************************/ -void CRecompilerOps::J() -{ - if (m_NextInstruction == NORMAL) - { - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if ((m_CompilePC & 0xFFC) == 0xFFC) - { - MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - OverflowDelaySlot(false); - return; - } - - m_Section->m_Jump.TargetPC = (m_CompilePC & 0xF0000000) + (m_Opcode.target << 2);; - m_Section->m_Jump.JumpPC = m_CompilePC; - if (m_Section->m_JumpSection != NULL) - { - m_Section->m_Jump.BranchLabel.Format("Section_%d", ((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); - } - else - { - m_Section->m_Jump.BranchLabel = "ExitBlock"; - } - m_Section->m_Jump.FallThrough = true; - m_Section->m_Jump.LinkLocation = NULL; - m_Section->m_Jump.LinkLocation2 = NULL; - m_NextInstruction = DO_DELAY_SLOT; - } - else if (m_NextInstruction == DELAY_SLOT_DONE) - { - m_Section->m_Jump.RegSet = m_RegWorkingSet; - m_Section->GenerateSectionLinkage(); - m_NextInstruction = END_BLOCK; - } - else if (bHaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("WTF\n\nJ\nNextInstruction = %X", m_NextInstruction).c_str()); - } -} - -void CRecompilerOps::JAL() -{ - if (m_NextInstruction == NORMAL) - { - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - Map_GPR_32bit(31, true, -1); - MoveVariableToX86reg(_PROGRAM_COUNTER, "_PROGRAM_COUNTER", GetMipsRegMapLo(31)); - AndConstToX86Reg(GetMipsRegMapLo(31), 0xF0000000); - AddConstToX86Reg(GetMipsRegMapLo(31), (m_CompilePC + 8) & ~0xF0000000); - if ((m_CompilePC & 0xFFC) == 0xFFC) - { - MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - OverflowDelaySlot(false); - return; - } - m_Section->m_Jump.TargetPC = (m_CompilePC & 0xF0000000) + (m_Opcode.target << 2); - m_Section->m_Jump.JumpPC = m_CompilePC; - if (m_Section->m_JumpSection != NULL) - { - m_Section->m_Jump.BranchLabel.Format("Section_%d", ((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); - } - else - { - m_Section->m_Jump.BranchLabel = "ExitBlock"; - } - m_Section->m_Jump.FallThrough = true; - m_Section->m_Jump.LinkLocation = NULL; - m_Section->m_Jump.LinkLocation2 = NULL; - m_NextInstruction = DO_DELAY_SLOT; - } - else if (m_NextInstruction == DELAY_SLOT_DONE) - { - if (m_Section->m_JumpSection) - { - m_Section->m_Jump.RegSet = m_RegWorkingSet; - m_Section->GenerateSectionLinkage(); - } - else - { - m_RegWorkingSet.WriteBackRegisters(); - - x86Reg pc_reg = Map_TempReg(x86_Any, -1, false); - MoveVariableToX86reg(_PROGRAM_COUNTER, "_PROGRAM_COUNTER", pc_reg); - AndConstToX86Reg(pc_reg, 0xF0000000); - AddConstToX86Reg(pc_reg, (m_Opcode.target << 2)); - MoveX86regToVariable(pc_reg, _PROGRAM_COUNTER, "_PROGRAM_COUNTER"); - - uint32_t TargetPC = (m_CompilePC & 0xF0000000) + (m_Opcode.target << 2); - bool bCheck = TargetPC <= m_CompilePC; - UpdateCounters(m_RegWorkingSet, bCheck, true); - - m_Section->CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, bCheck ? CExitInfo::Normal : CExitInfo::Normal_NoSysCheck, true, NULL); - } - m_NextInstruction = END_BLOCK; - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - return; -} - -void CRecompilerOps::ADDI() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rt == 0) { return; } - - if (g_System->bFastSP() && m_Opcode.rs == 29 && m_Opcode.rt == 29) - { - AddConstToX86Reg(Map_MemoryStack(x86_Any, true), (int16_t)m_Opcode.immediate); - } - - if (IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rt)) - { - UnMap_GPR(m_Opcode.rt, false); - } - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) + (int16_t)m_Opcode.immediate); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); - AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), (int16_t)m_Opcode.immediate); - } - if (g_System->bFastSP() && m_Opcode.rt == 29 && m_Opcode.rs != 29) - { - ResetX86Protection(); - g_MMU->ResetMemoryStack(); - } -} - -void CRecompilerOps::ADDIU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rt == 0 || (m_Opcode.immediate == 0 && m_Opcode.rs == m_Opcode.rt)) - { - return; - } - - if (g_System->bFastSP()) - { - if (m_Opcode.rs == 29 && m_Opcode.rt == 29) - { - AddConstToX86Reg(Map_MemoryStack(x86_Any, true), (int16_t)m_Opcode.immediate); - } - } - - if (IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rt)) - { - UnMap_GPR(m_Opcode.rt, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) + (int16_t)m_Opcode.immediate); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); - AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), (int16_t)m_Opcode.immediate); - } - - if (g_System->bFastSP() && m_Opcode.rt == 29 && m_Opcode.rs != 29) - { - ResetX86Protection(); - g_MMU->ResetMemoryStack(); - } -} - -void CRecompilerOps::SLTIU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rt == 0) - { - return; - } - - if (IsConst(m_Opcode.rs)) - { - uint32_t Result = Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) < ((unsigned)((int64_t)((int16_t)m_Opcode.immediate))) ? 1 : 0 : - GetMipsRegLo(m_Opcode.rs) < ((unsigned)((int16_t)m_Opcode.immediate)) ? 1 : 0; - UnMap_GPR(m_Opcode.rt, false); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, Result); - } - else if (IsMapped(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - uint8_t * Jump[2]; - - CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), ((int16_t)m_Opcode.immediate >> 31)); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), (int16_t)m_Opcode.immediate); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - Map_GPR_32bit(m_Opcode.rt, false, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), (int16_t)m_Opcode.immediate); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - Map_GPR_32bit(m_Opcode.rt, false, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); - } - } - else if (g_System->b32BitCore()) - { - CompConstToVariable((int16_t)m_Opcode.immediate, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - Map_GPR_32bit(m_Opcode.rt, false, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - uint8_t * Jump = NULL; - - CompConstToVariable(((int16_t)m_Opcode.immediate >> 31), &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); - JneLabel8("CompareSet", 0); - Jump = m_RecompPos - 1; - CompConstToVariable((int16_t)m_Opcode.immediate, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - CPU_Message(""); - CPU_Message(" CompareSet:"); - SetJump8(Jump, m_RecompPos); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - Map_GPR_32bit(m_Opcode.rt, false, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); - } -} - -void CRecompilerOps::SLTI() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rt == 0) - { - return; - } - - if (IsConst(m_Opcode.rs)) - { - uint32_t Result = Is64Bit(m_Opcode.rs) ? - ((int64_t)GetMipsReg(m_Opcode.rs) < (int64_t)((int16_t)m_Opcode.immediate) ? 1 : 0) : - (GetMipsRegLo_S(m_Opcode.rs) < (int16_t)m_Opcode.immediate ? 1 : 0); - - UnMap_GPR(m_Opcode.rt, false); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, Result); - } - else if (IsMapped(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - uint8_t * Jump[2]; - - CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), ((int16_t)m_Opcode.immediate >> 31)); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), (int16_t)m_Opcode.immediate); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - Map_GPR_32bit(m_Opcode.rt, false, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - /* CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs),(int16_t)m_Opcode.immediate); - SetlVariable(&m_BranchCompare,"m_BranchCompare"); - Map_GPR_32bit(m_Opcode.rt, false, -1); - MoveVariableToX86reg(&m_BranchCompare,"m_BranchCompare",GetMipsRegMapLo(m_Opcode.rt)); - */ - ProtectGPR(m_Opcode.rs); - Map_GPR_32bit(m_Opcode.rt, false, -1); - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), (int16_t)m_Opcode.immediate); - - if (GetMipsRegMapLo(m_Opcode.rt) > x86_EBX) - { - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - Setl(GetMipsRegMapLo(m_Opcode.rt)); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), 1); - } - } - } - else if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rt, false, -1); - CompConstToVariable((int16_t)m_Opcode.immediate, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - - if (GetMipsRegMapLo(m_Opcode.rt) > x86_EBX) - { - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - Setl(GetMipsRegMapLo(m_Opcode.rt)); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), 1); - } - } - else - { - uint8_t * Jump[2] = { NULL, NULL }; - CompConstToVariable(((int16_t)m_Opcode.immediate >> 31), &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompConstToVariable((int16_t)m_Opcode.immediate, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - if (Jump[1]) - { - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - } - Map_GPR_32bit(m_Opcode.rt, false, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); - } -} - -void CRecompilerOps::ANDI() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rt == 0) - { - return; - } - - if (IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rt)) - { - UnMap_GPR(m_Opcode.rt, false); - } - - m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) & m_Opcode.immediate); - } - else if (m_Opcode.immediate != 0) - { - Map_GPR_32bit(m_Opcode.rt, false, m_Opcode.rs); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), m_Opcode.immediate); - } - else - { - Map_GPR_32bit(m_Opcode.rt, false, 0); - } -} - -void CRecompilerOps::ORI() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rt == 0) - { - return; - } - - if (g_System->bFastSP() && m_Opcode.rs == 29 && m_Opcode.rt == 29) - { - OrConstToX86Reg(m_Opcode.immediate, Map_MemoryStack(x86_Any, true)); - } - - if (IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rt)) - { - UnMap_GPR(m_Opcode.rt, false); - } - - m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, GetMipsRegState(m_Opcode.rs)); - m_RegWorkingSet.SetMipsRegHi(m_Opcode.rt, GetMipsRegHi(m_Opcode.rs)); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) | m_Opcode.immediate); - } - else if (IsMapped(m_Opcode.rs)) - { - if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); - } - else - { - if (Is64Bit(m_Opcode.rs)) - { - Map_GPR_64bit(m_Opcode.rt, m_Opcode.rs); - } - else - { - Map_GPR_32bit(m_Opcode.rt, IsSigned(m_Opcode.rs), m_Opcode.rs); - } - } - OrConstToX86Reg(m_Opcode.immediate, GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); - } - else - { - Map_GPR_64bit(m_Opcode.rt, m_Opcode.rs); - } - OrConstToX86Reg(m_Opcode.immediate, GetMipsRegMapLo(m_Opcode.rt)); - } - - if (g_System->bFastSP() && m_Opcode.rt == 29 && m_Opcode.rs != 29) - { - ResetX86Protection(); - g_MMU->ResetMemoryStack(); - } -} - -void CRecompilerOps::XORI() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rt == 0) - { - return; - } - - if (IsConst(m_Opcode.rs)) - { - if (m_Opcode.rs != m_Opcode.rt) - { - UnMap_GPR(m_Opcode.rt, false); - } - - m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, GetMipsRegState(m_Opcode.rs)); - m_RegWorkingSet.SetMipsRegHi(m_Opcode.rt, GetMipsRegHi(m_Opcode.rs)); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) ^ m_Opcode.immediate); - } - else - { - if (IsMapped(m_Opcode.rs) && Is32Bit(m_Opcode.rs)) - { - Map_GPR_32bit(m_Opcode.rt, IsSigned(m_Opcode.rs), m_Opcode.rs); - } - else if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); - } - else - { - Map_GPR_64bit(m_Opcode.rt, m_Opcode.rs); - } - if (m_Opcode.immediate != 0) { XorConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), m_Opcode.immediate); } - } -} - -void CRecompilerOps::LUI() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rt == 0) - { - return; - } - - if (g_System->bFastSP() && m_Opcode.rt == 29) - { - x86Reg Reg = Map_MemoryStack(x86_Any, true, false); - uint32_t Address; - - g_TransVaddr->TranslateVaddr(((int16_t)m_Opcode.offset << 16), Address); - if (Reg < 0) - { - MoveConstToVariable((uint32_t)(Address + g_MMU->Rdram()), &(g_Recompiler->MemoryStackPos()), "MemoryStack"); - } - else - { - MoveConstToX86reg((uint32_t)(Address + g_MMU->Rdram()), Reg); - } - } - - UnMap_GPR(m_Opcode.rt, false); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, ((int16_t)m_Opcode.offset << 16)); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); -} - -void CRecompilerOps::DADDIU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rs != 0) - { - UnMap_GPR(m_Opcode.rs, true); - } - - if (m_Opcode.rs != 0) - { - UnMap_GPR(m_Opcode.rt, true); - } - - BeforeCallDirect(m_RegWorkingSet); - MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); - Call_Direct((void *)R4300iOp::DADDIU, "R4300iOp::DADDIU"); - AfterCallDirect(m_RegWorkingSet); -} - -void CRecompilerOps::CACHE() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (g_Settings->LoadDword(Game_SMM_Cache) == 0) - { - return; - } - - switch (m_Opcode.rt) - { - case 0: - case 16: - BeforeCallDirect(m_RegWorkingSet); - PushImm32("CRecompiler::Remove_Cache", CRecompiler::Remove_Cache); - PushImm32("0x20", 0x20); - if (IsConst(m_Opcode.base)) - { - uint32_t Address = GetMipsRegLo(m_Opcode.base) + (int16_t)m_Opcode.offset; - PushImm32("Address", Address); - } - else if (IsMapped(m_Opcode.base)) - { - AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.base), (int16_t)m_Opcode.offset); - Push(GetMipsRegMapLo(m_Opcode.base)); - } - else - { - MoveVariableToX86reg(&_GPR[m_Opcode.base].UW[0], CRegName::GPR_Lo[m_Opcode.base], x86_EAX); - AddConstToX86Reg(x86_EAX, (int16_t)m_Opcode.offset); - Push(x86_EAX); - } - MoveConstToX86reg((uint32_t)g_Recompiler, x86_ECX); - Call_Direct(AddressOf(&CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); - AfterCallDirect(m_RegWorkingSet); - break; - case 1: - case 3: - case 13: - case 5: - case 8: - case 9: - case 17: - case 21: - case 25: - break; - default: - if (bHaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("cache: %d", m_Opcode.rt).c_str()); - } - } -} - -/********************** R4300i OpCodes: Special **********************/ -void CRecompilerOps::SPECIAL_SLL() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rd == 0) - { - return; - } - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) << m_Opcode.sa); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - return; - } - if (m_Opcode.rd != m_Opcode.rt && IsMapped(m_Opcode.rt)) - { - switch (m_Opcode.sa) - { - case 0: - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - break; - case 1: - ProtectGPR(m_Opcode.rt); - Map_GPR_32bit(m_Opcode.rd, true, -1); - LeaRegReg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt), 0, Multip_x2); - break; - case 2: - ProtectGPR(m_Opcode.rt); - Map_GPR_32bit(m_Opcode.rd, true, -1); - LeaRegReg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt), 0, Multip_x4); - break; - case 3: - ProtectGPR(m_Opcode.rt); - Map_GPR_32bit(m_Opcode.rd, true, -1); - LeaRegReg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt), 0, Multip_x8); - break; - default: - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftLeftSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); - } - } - else - { - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftLeftSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); - } -} - -void CRecompilerOps::SPECIAL_SRL() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) >> m_Opcode.sa); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - return; - } - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftRightUnsignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); -} - -void CRecompilerOps::SPECIAL_SRA() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo_S(m_Opcode.rt) >> m_Opcode.sa); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - return; - } - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftRightSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); -} - -void CRecompilerOps::SPECIAL_SLLV() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rs)) - { - uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x1F); - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) << Shift); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftLeftSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)Shift); - } - return; - } - Map_TempReg(x86_ECX, m_Opcode.rs, false); - AndConstToX86Reg(x86_ECX, 0x1F); - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftLeftSign(GetMipsRegMapLo(m_Opcode.rd)); -} - -void CRecompilerOps::SPECIAL_SRLV() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsKnown(m_Opcode.rs) && IsConst(m_Opcode.rs)) - { - uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x1F); - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) >> Shift); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - return; - } - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftRightUnsignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)Shift); - return; - } - - Map_TempReg(x86_ECX, m_Opcode.rs, false); - AndConstToX86Reg(x86_ECX, 0x1F); - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftRightUnsign(GetMipsRegMapLo(m_Opcode.rd)); -} - -void CRecompilerOps::SPECIAL_SRAV() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsKnown(m_Opcode.rs) && IsConst(m_Opcode.rs)) - { - uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x1F); - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo_S(m_Opcode.rt) >> Shift); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - return; - } - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftRightSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)Shift); - return; - } - Map_TempReg(x86_ECX, m_Opcode.rs, false); - AndConstToX86Reg(x86_ECX, 0x1F); - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - ShiftRightSign(GetMipsRegMapLo(m_Opcode.rd)); -} - -void CRecompilerOps::SPECIAL_JR() -{ - if (m_NextInstruction == NORMAL) - { - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if ((m_CompilePC & 0xFFC) == 0xFFC) - { - if (IsMapped(m_Opcode.rs)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - m_RegWorkingSet.WriteBackRegisters(); - } - else - { - m_RegWorkingSet.WriteBackRegisters(); - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - } - OverflowDelaySlot(true); - return; - } - - m_Section->m_Jump.FallThrough = false; - m_Section->m_Jump.LinkLocation = NULL; - m_Section->m_Jump.LinkLocation2 = NULL; - m_Section->m_Cont.FallThrough = false; - m_Section->m_Cont.LinkLocation = NULL; - m_Section->m_Cont.LinkLocation2 = NULL; - - if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) - { - if (IsConst(m_Opcode.rs)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - else if (IsMapped(m_Opcode.rs)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - } - m_NextInstruction = DO_DELAY_SLOT; - } - else if (m_NextInstruction == DELAY_SLOT_DONE) - { - if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) - { - m_Section->CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); - } - else - { - UpdateCounters(m_RegWorkingSet, true, true); - if (IsConst(m_Opcode.rs)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - else if (IsMapped(m_Opcode.rs)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - m_Section->CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); - if (m_Section->m_JumpSection) - { - m_Section->GenerateSectionLinkage(); - } - } - m_NextInstruction = END_BLOCK; - } - else if (bHaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); - } -} - -void CRecompilerOps::SPECIAL_JALR() -{ - if (m_NextInstruction == NORMAL) - { - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0) && (m_CompilePC & 0xFFC) != 0xFFC) - { - if (IsConst(m_Opcode.rs)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - else if (IsMapped(m_Opcode.rs)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - } - UnMap_GPR(m_Opcode.rd, false); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, m_CompilePC + 8); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - if ((m_CompilePC & 0xFFC) == 0xFFC) - { - if (IsMapped(m_Opcode.rs)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - m_RegWorkingSet.WriteBackRegisters(); - } - else - { - m_RegWorkingSet.WriteBackRegisters(); - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); - } - OverflowDelaySlot(true); - return; - } - - m_Section->m_Jump.FallThrough = false; - m_Section->m_Jump.LinkLocation = NULL; - m_Section->m_Jump.LinkLocation2 = NULL; - m_Section->m_Cont.FallThrough = false; - m_Section->m_Cont.LinkLocation = NULL; - m_Section->m_Cont.LinkLocation2 = NULL; - - m_NextInstruction = DO_DELAY_SLOT; - } - else if (m_NextInstruction == DELAY_SLOT_DONE) - { - if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) - { - m_Section->CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); - } - else - { - UpdateCounters(m_RegWorkingSet, true, true); - if (IsConst(m_Opcode.rs)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - else if (IsMapped(m_Opcode.rs)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - m_Section->CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); - if (m_Section->m_JumpSection) - { - m_Section->GenerateSectionLinkage(); - } - } - m_NextInstruction = END_BLOCK; - } - else if (bHaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); - } -} - -void CRecompilerOps::SPECIAL_SYSCALL() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::DoSysCall, true, NULL); - m_NextInstruction = END_BLOCK; -} - -void CRecompilerOps::SPECIAL_MFLO() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) { return; } - - Map_GPR_64bit(m_Opcode.rd, -1); - MoveVariableToX86reg(&_RegLO->UW[0], "_RegLO->UW[0]", GetMipsRegMapLo(m_Opcode.rd)); - MoveVariableToX86reg(&_RegLO->UW[1], "_RegLO->UW[1]", GetMipsRegMapHi(m_Opcode.rd)); -} - -void CRecompilerOps::SPECIAL_MTLO() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsKnown(m_Opcode.rs) && IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - MoveConstToVariable(GetMipsRegHi(m_Opcode.rs), &_RegLO->UW[1], "_RegLO->UW[1]"); - } - else if (IsSigned(m_Opcode.rs) && ((GetMipsRegLo(m_Opcode.rs) & 0x80000000) != 0)) - { - MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]"); - } - else - { - MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); - } - MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), &_RegLO->UW[0], "_RegLO->UW[0]"); - } - else if (IsKnown(m_Opcode.rs) && IsMapped(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - MoveX86regToVariable(GetMipsRegMapHi(m_Opcode.rs), &_RegLO->UW[1], "_RegLO->UW[1]"); - } - else if (IsSigned(m_Opcode.rs)) - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, true), &_RegLO->UW[1], "_RegLO->UW[1]"); - } - else - { - MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); - } - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &_RegLO->UW[0], "_RegLO->UW[0]"); - } - else - { - x86Reg reg = Map_TempReg(x86_Any, m_Opcode.rs, true); - MoveX86regToVariable(reg, &_RegLO->UW[1], "_RegLO->UW[1]"); - MoveX86regToVariable(Map_TempReg(reg, m_Opcode.rs, false), &_RegLO->UW[0], "_RegLO->UW[0]"); - } -} - -void CRecompilerOps::SPECIAL_MFHI() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) { return; } - - Map_GPR_64bit(m_Opcode.rd, -1); - MoveVariableToX86reg(&_RegHI->UW[0], "_RegHI->UW[0]", GetMipsRegMapLo(m_Opcode.rd)); - MoveVariableToX86reg(&_RegHI->UW[1], "_RegHI->UW[1]", GetMipsRegMapHi(m_Opcode.rd)); -} - -void CRecompilerOps::SPECIAL_MTHI() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsKnown(m_Opcode.rs) && IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - MoveConstToVariable(GetMipsRegHi(m_Opcode.rs), &_RegHI->UW[1], "_RegHI->UW[1]"); - } - else if (IsSigned(m_Opcode.rs) && ((GetMipsRegLo(m_Opcode.rs) & 0x80000000) != 0)) - { - MoveConstToVariable(0xFFFFFFFF, &_RegHI->UW[1], "_RegHI->UW[1]"); - } - else - { - MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); - } - MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), &_RegHI->UW[0], "_RegHI->UW[0]"); - } - else if (IsKnown(m_Opcode.rs) && IsMapped(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rs)) - { - MoveX86regToVariable(GetMipsRegMapHi(m_Opcode.rs), &_RegHI->UW[1], "_RegHI->UW[1]"); - } - else if (IsSigned(m_Opcode.rs)) - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, true), &_RegHI->UW[1], "_RegHI->UW[1]"); - } - else - { - MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); - } - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &_RegHI->UW[0], "_RegHI->UW[0]"); - } - else - { - x86Reg reg = Map_TempReg(x86_Any, m_Opcode.rs, true); - MoveX86regToVariable(reg, &_RegHI->UW[1], "_RegHI->UW[1]"); - MoveX86regToVariable(Map_TempReg(reg, m_Opcode.rs, false), &_RegHI->UW[0], "_RegHI->UW[0]"); - } -} - -void CRecompilerOps::SPECIAL_DSLLV() -{ - uint8_t * Jump[2]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rs)) - { - //uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x3F); - CRecompilerOps::UnknownOpcode(); - return; - } - Map_TempReg(x86_ECX, m_Opcode.rs, false); - AndConstToX86Reg(x86_ECX, 0x3F); - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - CompConstToX86reg(x86_ECX, 0x20); - JaeLabel8("MORE32", 0); - Jump[0] = m_RecompPos - 1; - ShiftLeftDouble(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); - ShiftLeftSign(GetMipsRegMapLo(m_Opcode.rd)); - JmpLabel8("continue", 0); - Jump[1] = m_RecompPos - 1; - - //MORE32: - CPU_Message(""); - CPU_Message(" MORE32:"); - SetJump8(Jump[0], m_RecompPos); - MoveX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); - XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); - AndConstToX86Reg(x86_ECX, 0x1F); - ShiftLeftSign(GetMipsRegMapHi(m_Opcode.rd)); - - //continue: - CPU_Message(""); - CPU_Message(" continue:"); - SetJump8(Jump[1], m_RecompPos); -} - -void CRecompilerOps::SPECIAL_DSRLV() -{ - uint8_t * Jump[2]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rs)) - { - uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x3F); - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt)); - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, GetMipsReg(m_Opcode.rd) >> Shift); - if ((GetMipsRegHi(m_Opcode.rd) == 0) && (GetMipsRegLo(m_Opcode.rd) & 0x80000000) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if ((GetMipsRegHi(m_Opcode.rd) == 0xFFFFFFFF) && (GetMipsRegLo(m_Opcode.rd) & 0x80000000) != 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - return; - } - if (m_Opcode.rd == m_Opcode.rt) - { - CRecompilerOps::UnknownOpcode(); - return; - } - - Map_TempReg(x86_ECX, -1, false); - MoveConstToX86reg(Shift, x86_ECX); - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - if ((Shift & 0x20) == 0x20) - { - MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); - XorX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); - AndConstToX86Reg(x86_ECX, 0x1F); - ShiftRightUnsign(GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - ShiftRightDouble(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); - ShiftRightUnsign(GetMipsRegMapHi(m_Opcode.rd)); - } - } - else - { - Map_TempReg(x86_ECX, m_Opcode.rs, false); - AndConstToX86Reg(x86_ECX, 0x3F); - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - CompConstToX86reg(x86_ECX, 0x20); - JaeLabel8("MORE32", 0); - Jump[0] = m_RecompPos - 1; - ShiftRightDouble(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); - ShiftRightUnsign(GetMipsRegMapHi(m_Opcode.rd)); - JmpLabel8("continue", 0); - Jump[1] = m_RecompPos - 1; - - //MORE32: - CPU_Message(""); - CPU_Message(" MORE32:"); - SetJump8(Jump[0], m_RecompPos); - MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); - XorX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); - AndConstToX86Reg(x86_ECX, 0x1F); - ShiftRightUnsign(GetMipsRegMapLo(m_Opcode.rd)); - - //continue: - CPU_Message(""); - CPU_Message(" continue:"); - SetJump8(Jump[1], m_RecompPos); - } -} - -void CRecompilerOps::SPECIAL_DSRAV() -{ - uint8_t * Jump[2]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rs)) - { - //uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x3F); - CRecompilerOps::UnknownOpcode(); - return; - } - Map_TempReg(x86_ECX, m_Opcode.rs, false); - AndConstToX86Reg(x86_ECX, 0x3F); - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - CompConstToX86reg(x86_ECX, 0x20); - JaeLabel8("MORE32", 0); - Jump[0] = m_RecompPos - 1; - ShiftRightDouble(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); - ShiftRightSign(GetMipsRegMapHi(m_Opcode.rd)); - JmpLabel8("continue", 0); - Jump[1] = m_RecompPos - 1; - - //MORE32: - CPU_Message(""); - CPU_Message(" MORE32:"); - SetJump8(Jump[0], m_RecompPos); - MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); - ShiftRightSignImmed(GetMipsRegMapHi(m_Opcode.rd), 0x1F); - AndConstToX86Reg(x86_ECX, 0x1F); - ShiftRightSign(GetMipsRegMapLo(m_Opcode.rd)); - - //continue: - CPU_Message(""); - CPU_Message(" continue:"); - SetJump8(Jump[1], m_RecompPos); -} - -void CRecompilerOps::SPECIAL_MULT() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_RegWorkingSet.SetX86Protected(x86_EDX, true); - Map_TempReg(x86_EAX, m_Opcode.rs, false); - m_RegWorkingSet.SetX86Protected(x86_EDX, false); - Map_TempReg(x86_EDX, m_Opcode.rt, false); - - imulX86reg(x86_EDX); - - MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); - ShiftRightSignImmed(x86_EAX, 31); /* paired */ - ShiftRightSignImmed(x86_EDX, 31); - MoveX86regToVariable(x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); -} - -void CRecompilerOps::SPECIAL_MULTU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_RegWorkingSet.SetX86Protected(x86_EDX, true); - Map_TempReg(x86_EAX, m_Opcode.rs, false); - m_RegWorkingSet.SetX86Protected(x86_EDX, false); - Map_TempReg(x86_EDX, m_Opcode.rt, false); - - MulX86reg(x86_EDX); - - MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); - ShiftRightSignImmed(x86_EAX, 31); /* paired */ - ShiftRightSignImmed(x86_EDX, 31); - MoveX86regToVariable(x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); -} - -void CRecompilerOps::SPECIAL_DIV() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsConst(m_Opcode.rt)) - { - if (GetMipsRegLo(m_Opcode.rt) == 0) - { - MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]"); - MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); - MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]"); - MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); - return; - } - } - else - { - if (IsMapped(m_Opcode.rt)) - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), 0); - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - } - m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::DivByZero, false, JeLabel32); - } - /* lo = (SD)rs / (SD)rt; - hi = (SD)rs % (SD)rt; */ - - m_RegWorkingSet.SetX86Protected(x86_EDX, true); - Map_TempReg(x86_EAX, m_Opcode.rs, false); - - /* edx is the signed portion to eax */ - m_RegWorkingSet.SetX86Protected(x86_EDX, false); - Map_TempReg(x86_EDX, -1, false); - - MoveX86RegToX86Reg(x86_EAX, x86_EDX); - ShiftRightSignImmed(x86_EDX, 31); - - if (IsMapped(m_Opcode.rt)) - { - idivX86reg(GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - idivX86reg(Map_TempReg(x86_Any, m_Opcode.rt, false)); - } - - MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); - ShiftRightSignImmed(x86_EAX, 31); /* paired */ - ShiftRightSignImmed(x86_EDX, 31); - MoveX86regToVariable(x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); -} - -void CRecompilerOps::SPECIAL_DIVU() -{ - uint8_t *Jump[2]; - x86Reg Reg; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsConst(m_Opcode.rt)) - { - if (GetMipsRegLo(m_Opcode.rt) == 0) - { - MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]"); - MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); - MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]"); - MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); - return; - } - Jump[1] = NULL; - } - else - { - if (IsMapped(m_Opcode.rt)) - { - CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), 0); - } - else - { - CompConstToVariable(0, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - } - JneLabel8("NoExcept", 0); - Jump[0] = m_RecompPos - 1; - - MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]"); - MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); - MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]"); - MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); - - JmpLabel8("EndDivu", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" NoExcept:"); - SetJump8(Jump[0], m_RecompPos); - } - - /* lo = (UD)rs / (UD)rt; - hi = (UD)rs % (UD)rt; */ - - m_RegWorkingSet.SetX86Protected(x86_EAX, true); - Map_TempReg(x86_EDX, 0, false); - m_RegWorkingSet.SetX86Protected(x86_EAX, false); - - Map_TempReg(x86_EAX, m_Opcode.rs, false); - Reg = Map_TempReg(x86_Any, m_Opcode.rt, false); - - DivX86reg(Reg); - - MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); - - /* wouldnt these be zero (???) */ - - ShiftRightSignImmed(x86_EAX, 31); /* paired */ - ShiftRightSignImmed(x86_EDX, 31); - MoveX86regToVariable(x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); - - if (Jump[1] != NULL) - { - CPU_Message(""); - CPU_Message(" EndDivu:"); - SetJump8(Jump[1], m_RecompPos); - } -} - -void CRecompilerOps::SPECIAL_DMULT() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rs != 0) - { - UnMap_GPR(m_Opcode.rs, true); - } - - if (m_Opcode.rs != 0) - { - UnMap_GPR(m_Opcode.rt, true); - } - - BeforeCallDirect(m_RegWorkingSet); - MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); - Call_Direct((void *)R4300iOp::SPECIAL_DMULT, "R4300iOp::SPECIAL_DMULT"); - AfterCallDirect(m_RegWorkingSet); -} - -void CRecompilerOps::SPECIAL_DMULTU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - UnMap_GPR(m_Opcode.rs, true); - UnMap_GPR(m_Opcode.rt, true); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); - Call_Direct((void *)R4300iOp::SPECIAL_DMULTU, "R4300iOp::SPECIAL_DMULTU"); - AfterCallDirect(m_RegWorkingSet); - -#ifdef toremove - /* _RegLO->UDW = (uint64)_GPR[m_Opcode.rs].UW[0] * (uint64)_GPR[m_Opcode.rt].UW[0]; */ - X86Protected(x86_EDX) = true; - Map_TempReg(x86_EAX, m_Opcode.rs, false); - X86Protected(x86_EDX) = false; - Map_TempReg(x86_EDX, m_Opcode.rt, false); - - MulX86reg(x86_EDX); - MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); - MoveX86regToVariable(x86_EDX, &_RegLO->UW[1], "_RegLO->UW[1]"); - - /* _RegHI->UDW = (uint64)_GPR[m_Opcode.rs].UW[1] * (uint64)_GPR[m_Opcode.rt].UW[1]; */ - Map_TempReg(x86_EAX, m_Opcode.rs, true); - Map_TempReg(x86_EDX, m_Opcode.rt, true); - - MulX86reg(x86_EDX); - MoveX86regToVariable(x86_EAX, &_RegHI->UW[0], "_RegHI->UW[0]"); - MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); - - /* Tmp[0].UDW = (uint64)_GPR[m_Opcode.rs].UW[1] * (uint64)_GPR[m_Opcode.rt].UW[0]; */ - Map_TempReg(x86_EAX, m_Opcode.rs, true); - Map_TempReg(x86_EDX, m_Opcode.rt, false); - - Map_TempReg(x86_EBX, -1, false); - Map_TempReg(x86_ECX, -1, false); - - MulX86reg(x86_EDX); - MoveX86RegToX86Reg(x86_EAX, x86_EBX); /* EDX:EAX -> ECX:EBX */ - MoveX86RegToX86Reg(x86_EDX, x86_ECX); - - /* Tmp[1].UDW = (uint64)_GPR[m_Opcode.rs].UW[0] * (uint64)_GPR[m_Opcode.rt].UW[1]; */ - Map_TempReg(x86_EAX, m_Opcode.rs, false); - Map_TempReg(x86_EDX, m_Opcode.rt, true); - - MulX86reg(x86_EDX); - Map_TempReg(x86_ESI, -1, false); - Map_TempReg(x86_EDI, -1, false); - MoveX86RegToX86Reg(x86_EAX, x86_ESI); /* EDX:EAX -> EDI:ESI */ - MoveX86RegToX86Reg(x86_EDX, x86_EDI); - - /* Tmp[2].UDW = (uint64)_RegLO->UW[1] + (uint64)Tmp[0].UW[0] + (uint64)Tmp[1].UW[0]; */ - XorX86RegToX86Reg(x86_EDX, x86_EDX); - MoveVariableToX86reg(&_RegLO->UW[1], "_RegLO->UW[1]", x86_EAX); - AddX86RegToX86Reg(x86_EAX, x86_EBX); - AddConstToX86Reg(x86_EDX, 0); - AddX86RegToX86Reg(x86_EAX, x86_ESI); - AddConstToX86Reg(x86_EDX, 0); /* EDX:EAX */ - - /* _RegLO->UDW += ((uint64)Tmp[0].UW[0] + (uint64)Tmp[1].UW[0]) << 32; */ - /* [low+4] += ebx + esi */ - - AddX86regToVariable(x86_EBX, &_RegLO->UW[1], "_RegLO->UW[1]"); - AddX86regToVariable(x86_ESI, &_RegLO->UW[1], "_RegLO->UW[1]"); - - /* _RegHI->UDW += (uint64)Tmp[0].UW[1] + (uint64)Tmp[1].UW[1] + Tmp[2].UW[1]; */ - /* [hi] += ecx + edi + edx */ - - AddX86regToVariable(x86_ECX, &_RegHI->UW[0], "_RegHI->UW[0]"); - AdcConstToVariable(&_RegHI->UW[1], "_RegHI->UW[1]", 0); - - AddX86regToVariable(x86_EDI, &_RegHI->UW[0], "_RegHI->UW[0]"); - AdcConstToVariable(&_RegHI->UW[1], "_RegHI->UW[1]", 0); - - AddX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); - AdcConstToVariable(&_RegHI->UW[1], "_RegHI->UW[1]", 0); -#endif -} - -void CRecompilerOps::SPECIAL_DDIV() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - UnMap_GPR(m_Opcode.rs, true); - UnMap_GPR(m_Opcode.rt, true); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); - Call_Direct((void *)R4300iOp::SPECIAL_DDIV, "R4300iOp::SPECIAL_DDIV"); - AfterCallDirect(m_RegWorkingSet); -} - -void CRecompilerOps::SPECIAL_DDIVU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - UnMap_GPR(m_Opcode.rs, true); - UnMap_GPR(m_Opcode.rt, true); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); - Call_Direct((void *)R4300iOp::SPECIAL_DDIVU, "R4300iOp::SPECIAL_DDIVU"); - AfterCallDirect(m_RegWorkingSet); -} - -void CRecompilerOps::SPECIAL_ADD() -{ - int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; - int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(source1) && IsConst(source2)) - { - uint32_t temp = GetMipsRegLo(source1) + GetMipsRegLo(source2); - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, temp); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - return; - } - - Map_GPR_32bit(m_Opcode.rd, true, source1); - if (IsConst(source2)) - { - AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(source2)); - } - else if (IsKnown(source2) && IsMapped(source2)) - { - AddX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - else - { - AddVariableToX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[source2].W[0], CRegName::GPR_Lo[source2]); - } - if (g_System->bFastSP() && m_Opcode.rd == 29) - { - g_MMU->ResetMemoryStack(); - } -} - -void CRecompilerOps::SPECIAL_ADDU() -{ - int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; - int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(source1) && IsConst(source2)) - { - uint32_t temp = GetMipsRegLo(source1) + GetMipsRegLo(source2); - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, temp); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - return; - } - - Map_GPR_32bit(m_Opcode.rd, true, source1); - if (IsConst(source2)) - { - AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(source2)); - } - else if (IsKnown(source2) && IsMapped(source2)) - { - AddX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - else - { - AddVariableToX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[source2].W[0], CRegName::GPR_Lo[source2]); - } - if (g_System->bFastSP() && m_Opcode.rd == 29) - { - g_MMU->ResetMemoryStack(); - } -} - -void CRecompilerOps::SPECIAL_SUB() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - uint32_t temp = GetMipsRegLo(m_Opcode.rs) - GetMipsRegLo(m_Opcode.rt); - - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, temp); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - if (m_Opcode.rd == m_Opcode.rt) - { - x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rt, false); - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rs); - SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Reg); - return; - } - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rs); - if (IsConst(m_Opcode.rt)) - { - SubConstFromX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(m_Opcode.rt)); - } - else if (IsMapped(m_Opcode.rt)) - { - SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - SubVariableFromX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - } - } - if (g_System->bFastSP() && m_Opcode.rd == 29) - { - g_MMU->ResetMemoryStack(); - } -} - -void CRecompilerOps::SPECIAL_SUBU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - uint32_t temp = GetMipsRegLo(m_Opcode.rs) - GetMipsRegLo(m_Opcode.rt); - - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, temp); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - if (m_Opcode.rd == m_Opcode.rt) - { - x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rt, false); - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rs); - SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Reg); - return; - } - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rs); - if (IsConst(m_Opcode.rt)) - { - SubConstFromX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(m_Opcode.rt)); - } - else if (IsMapped(m_Opcode.rt)) - { - SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt)); - } - else - { - SubVariableFromX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - } - } - - if (g_System->bFastSP() && m_Opcode.rd == 29) - { - g_MMU->ResetMemoryStack(); - } -} - -void CRecompilerOps::SPECIAL_AND() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) - { - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, - (Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt)) & - (Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs)) - ); - - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - } - else - { - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) & GetMipsReg(m_Opcode.rs)); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - } - else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) - { - int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; - int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; - - ProtectGPR(source1); - ProtectGPR(source2); - if (Is32Bit(source1) && Is32Bit(source2)) - { - bool Sign = (IsSigned(m_Opcode.rt) && IsSigned(m_Opcode.rs)); - Map_GPR_32bit(m_Opcode.rd, Sign, source1); - AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - else if (Is32Bit(source1) || Is32Bit(source2)) - { - if (IsUnsigned(Is32Bit(source1) ? source1 : source2)) - { - Map_GPR_32bit(m_Opcode.rd, false, source1); - AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - else - { - Map_GPR_64bit(m_Opcode.rd, source1); - if (Is32Bit(source2)) - { - AndX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), Map_TempReg(x86_Any, source2, true)); - } - else - { - AndX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); - } - AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - } - else - { - Map_GPR_64bit(m_Opcode.rd, source1); - AndX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); - AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - } - else - { - int ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - int MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (Is64Bit(ConstReg)) - { - if (Is32Bit(MappedReg) && IsUnsigned(MappedReg)) - { - if (GetMipsRegLo(ConstReg) == 0) - { - Map_GPR_32bit(m_Opcode.rd, false, 0); - } - else - { - uint32_t Value = GetMipsRegLo(ConstReg); - Map_GPR_32bit(m_Opcode.rd, false, MappedReg); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); - } - } - else - { - int64_t Value = GetMipsReg(ConstReg); - Map_GPR_64bit(m_Opcode.rd, MappedReg); - AndConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), (uint32_t)(Value >> 32)); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), (uint32_t)(Value & 0xFFFFFFFF)); - } - } - else if (Is64Bit(MappedReg)) - { - uint32_t Value = GetMipsRegLo(ConstReg); - if (Value != 0) - { - Map_GPR_32bit(m_Opcode.rd, IsSigned(ConstReg), MappedReg); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); - } - else - { - Map_GPR_32bit(m_Opcode.rd, IsSigned(ConstReg), 0); - } - } - else - { - uint32_t Value = GetMipsRegLo(ConstReg); - bool Sign = false; - - if (IsSigned(ConstReg) && IsSigned(MappedReg)) - { - Sign = true; - } - - if (Value != 0) - { - Map_GPR_32bit(m_Opcode.rd, Sign, MappedReg); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); - } - else - { - Map_GPR_32bit(m_Opcode.rd, false, 0); - } - } - } - } - else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) - { - uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (IsConst(KnownReg)) - { - if (Is64Bit(KnownReg)) - { - uint64_t Value = GetMipsReg(KnownReg); - Map_GPR_64bit(m_Opcode.rd, UnknownReg); - AndConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), (uint32_t)(Value >> 32)); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), (uint32_t)(Value & 0xFFFFFFFF)); - } - else - { - uint32_t Value = GetMipsRegLo(KnownReg); - Map_GPR_32bit(m_Opcode.rd, IsSigned(KnownReg), UnknownReg); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); - } - } - else - { - ProtectGPR(KnownReg); - if (KnownReg == m_Opcode.rd) - { - if (Is64Bit(KnownReg) || !g_System->b32BitCore()) - { - Map_GPR_64bit(m_Opcode.rd, KnownReg); - AndVariableToX86Reg(&_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg], GetMipsRegMapHi(m_Opcode.rd)); - AndVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_32bit(m_Opcode.rd, IsSigned(KnownReg), KnownReg); - AndVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); - } - } - else - { - if (Is64Bit(KnownReg)) - { - Map_GPR_64bit(m_Opcode.rd, UnknownReg); - AndX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(KnownReg)); - AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(KnownReg)); - } - else - { - Map_GPR_32bit(m_Opcode.rd, IsSigned(KnownReg), UnknownReg); - AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(KnownReg)); - } - } - } - } - else - { - if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - } - else - { - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - AndVariableToX86Reg(&_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs], GetMipsRegMapHi(m_Opcode.rd)); - } - AndVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); - } -} - -void CRecompilerOps::SPECIAL_OR() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) - { - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, - (Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt)) | - (Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs)) - ); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - } - else - { - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) | GetMipsRegLo(m_Opcode.rs)); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - } - else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) - { - int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; - int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; - - ProtectGPR(m_Opcode.rt); - ProtectGPR(m_Opcode.rs); - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - Map_GPR_64bit(m_Opcode.rd, source1); - if (Is64Bit(source2)) - { - OrX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); - } - else - { - OrX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), Map_TempReg(x86_Any, source2, true)); - } - } - else - { - ProtectGPR(source2); - Map_GPR_32bit(m_Opcode.rd, true, source1); - } - OrX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - else - { - uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - uint64_t Value; - - if (Is64Bit(ConstReg)) - { - Value = GetMipsReg(ConstReg); - } - else - { - Value = IsSigned(ConstReg) ? (int64_t)GetMipsRegLo_S(ConstReg) : GetMipsRegLo(ConstReg); - } - Map_GPR_64bit(m_Opcode.rd, MappedReg); - if ((Value >> 32) != 0) - { - OrConstToX86Reg((uint32_t)(Value >> 32), GetMipsRegMapHi(m_Opcode.rd)); - } - uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); - if (dwValue != 0) - { - OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); - } - } - else - { - int Value = GetMipsRegLo(ConstReg); - Map_GPR_32bit(m_Opcode.rd, true, MappedReg); - if (Value != 0) { OrConstToX86Reg(Value, GetMipsRegMapLo(m_Opcode.rd)); } - } - } - } - else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) - { - int KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - int UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (IsConst(KnownReg)) - { - uint64_t Value = Is64Bit(KnownReg) ? GetMipsReg(KnownReg) : GetMipsRegLo_S(KnownReg); - uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); - - if (g_System->b32BitCore() && Is32Bit(KnownReg)) - { - Map_GPR_32bit(m_Opcode.rd, true, UnknownReg); - if (dwValue != 0) - { - OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); - } - } - else - { - Map_GPR_64bit(m_Opcode.rd, UnknownReg); - if ((Value >> 32) != 0) - { - OrConstToX86Reg((uint32_t)(Value >> 32), GetMipsRegMapHi(m_Opcode.rd)); - } - if (dwValue != 0) - { - OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); - } - } - } - else - { - if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rd, true, KnownReg); - OrVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_64bit(m_Opcode.rd, KnownReg); - OrVariableToX86Reg(&_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg], GetMipsRegMapHi(m_Opcode.rd)); - OrVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); - } - } - } - else - { - if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs], GetMipsRegMapHi(m_Opcode.rd)); - OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); - } - } - if (g_System->bFastSP() && m_Opcode.rd == 29) - { - ResetX86Protection(); - g_MMU->ResetMemoryStack(); - } -} - -void CRecompilerOps::SPECIAL_XOR() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - return; - - if (m_Opcode.rt == m_Opcode.rs) - { - UnMap_GPR(m_Opcode.rd, false); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 0); - return; - } - if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) - { - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - if (bHaveDebugger()) { g_Notify->DisplayError("XOR 1"); } - CRecompilerOps::UnknownOpcode(); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) ^ GetMipsRegLo(m_Opcode.rs)); - } - } - else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) - { - int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; - int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; - - ProtectGPR(source1); - ProtectGPR(source2); - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - Map_GPR_64bit(m_Opcode.rd, source1); - if (Is64Bit(source2)) - { - XorX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); - } - else if (IsSigned(source2)) - { - XorX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), Map_TempReg(x86_Any, source2, true)); - } - XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - else - { - if (IsSigned(m_Opcode.rt) != IsSigned(m_Opcode.rs)) - { - Map_GPR_32bit(m_Opcode.rd, true, source1); - } - else - { - Map_GPR_32bit(m_Opcode.rd, IsSigned(m_Opcode.rt), source1); - } - XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - } - else - { - uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - uint32_t ConstHi, ConstLo; - - ConstHi = Is32Bit(ConstReg) ? (uint32_t)(GetMipsRegLo_S(ConstReg) >> 31) : GetMipsRegHi(ConstReg); - ConstLo = GetMipsRegLo(ConstReg); - Map_GPR_64bit(m_Opcode.rd, MappedReg); - if (ConstHi != 0) { XorConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), ConstHi); } - if (ConstLo != 0) { XorConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), ConstLo); } - } - else - { - int Value = GetMipsRegLo(ConstReg); - if (IsSigned(m_Opcode.rt) != IsSigned(m_Opcode.rs)) - { - Map_GPR_32bit(m_Opcode.rd, true, MappedReg); - } - else - { - Map_GPR_32bit(m_Opcode.rd, IsSigned(MappedReg), MappedReg); - } - if (Value != 0) { XorConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); } - } - } - } - else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) - { - int KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - int UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (IsConst(KnownReg)) - { - uint64_t Value; - - if (Is64Bit(KnownReg)) - { - Value = GetMipsReg(KnownReg); - Map_GPR_64bit(m_Opcode.rd, UnknownReg); - if ((Value >> 32) != 0) - { - XorConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), (uint32_t)(Value >> 32)); - } - } - else - { - Map_GPR_32bit(m_Opcode.rd, true, UnknownReg); - if (IsSigned(KnownReg)) - { - Value = (int)GetMipsRegLo(KnownReg); - } - else - { - Value = GetMipsRegLo(KnownReg); - } - } - uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); - if (dwValue != 0) - { - XorConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), dwValue); - } - } - else - { - if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rd, true, KnownReg); - XorVariableToX86reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_64bit(m_Opcode.rd, KnownReg); - XorVariableToX86reg(&_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg], GetMipsRegMapHi(m_Opcode.rd)); - XorVariableToX86reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); - } - } - } - else if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - XorVariableToX86reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - XorVariableToX86reg(&_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs], GetMipsRegMapHi(m_Opcode.rd)); - XorVariableToX86reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); - } -} - -void CRecompilerOps::SPECIAL_NOR() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) - { - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rd)) - UnMap_GPR(m_Opcode.rd, false); - - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, - ~((Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt)) | - (Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs))) - ); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - } - else - { - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, ~(GetMipsRegLo(m_Opcode.rt) | GetMipsRegLo(m_Opcode.rs))); - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - } - else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) - { - int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; - int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; - - ProtectGPR(m_Opcode.rt); - ProtectGPR(m_Opcode.rs); - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - Map_GPR_64bit(m_Opcode.rd, source1); - if (Is64Bit(source2)) - { - OrX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); - } - else - { - OrX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), Map_TempReg(x86_Any, source2, true)); - } - } - else - { - ProtectGPR(source2); - Map_GPR_32bit(m_Opcode.rd, true, source1); - } - OrX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - } - else - { - uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - uint64_t Value; - - if (Is64Bit(ConstReg)) - { - Value = GetMipsReg(ConstReg); - } - else - { - Value = IsSigned(ConstReg) ? (int64_t)GetMipsRegLo_S(ConstReg) : GetMipsRegLo(ConstReg); - } - Map_GPR_64bit(m_Opcode.rd, MappedReg); - if ((Value >> 32) != 0) - { - OrConstToX86Reg((uint32_t)(Value >> 32), GetMipsRegMapHi(m_Opcode.rd)); - } - uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); - if (dwValue != 0) { - OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); - } - } - else - { - int Value = GetMipsRegLo(ConstReg); - Map_GPR_32bit(m_Opcode.rd, true, MappedReg); - if (Value != 0) { OrConstToX86Reg(Value, GetMipsRegMapLo(m_Opcode.rd)); } - } - } - } - else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) - { - int KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - int UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - if (IsConst(KnownReg)) - { - uint64_t Value = Is64Bit(KnownReg) ? GetMipsReg(KnownReg) : GetMipsRegLo_S(KnownReg); - uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); - - if (g_System->b32BitCore() && Is32Bit(KnownReg)) - { - Map_GPR_32bit(m_Opcode.rd, true, UnknownReg); - if (dwValue != 0) - { - OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); - } - } - else - { - Map_GPR_64bit(m_Opcode.rd, UnknownReg); - if ((Value >> 32) != 0) - { - OrConstToX86Reg((uint32_t)(Value >> 32), GetMipsRegMapHi(m_Opcode.rd)); - } - if (dwValue != 0) - { - OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); - } - } - } - else - { - if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rd, true, KnownReg); - OrVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_64bit(m_Opcode.rd, KnownReg); - OrVariableToX86Reg(&_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg], GetMipsRegMapHi(m_Opcode.rd)); - OrVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); - } - } - } - else - { - if (g_System->b32BitCore()) - { - Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); - OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs], GetMipsRegMapHi(m_Opcode.rd)); - OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); - } - } - - if (IsMapped(m_Opcode.rd)) - { - if (Is64Bit(m_Opcode.rd)) - { - NotX86Reg(GetMipsRegMapHi(m_Opcode.rd)); - } - NotX86Reg(GetMipsRegMapLo(m_Opcode.rd)); - } -} - -void CRecompilerOps::SPECIAL_SLT() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) - { - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - g_Notify->DisplayError("1"); - CRecompilerOps::UnknownOpcode(); - } - else - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - if (GetMipsRegLo_S(m_Opcode.rs) < GetMipsRegLo_S(m_Opcode.rt)) - { - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 1); - } - else - { - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 0); - } - } - } - else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) - { - ProtectGPR(m_Opcode.rt); - ProtectGPR(m_Opcode.rs); - if ((Is64Bit(m_Opcode.rt) && Is64Bit(m_Opcode.rs)) || - (!g_System->b32BitCore() && (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)))) - { - uint8_t *Jump[2]; - - CompX86RegToX86Reg( - Is64Bit(m_Opcode.rs) ? GetMipsRegMapHi(m_Opcode.rs) : Map_TempReg(x86_Any, m_Opcode.rs, true), - Is64Bit(m_Opcode.rt) ? GetMipsRegMapHi(m_Opcode.rt) : Map_TempReg(x86_Any, m_Opcode.rt, true) - ); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_32bit(m_Opcode.rd, true, -1); - CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); - - if (GetMipsRegMapLo(m_Opcode.rd) > x86_EBX) - { - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Setl(GetMipsRegMapLo(m_Opcode.rd)); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), 1); - } - } - } - else - { - uint32_t ConstReg = IsConst(m_Opcode.rs) ? m_Opcode.rs : m_Opcode.rt; - uint32_t MappedReg = IsConst(m_Opcode.rs) ? m_Opcode.rt : m_Opcode.rs; - - ProtectGPR(MappedReg); - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - uint8_t *Jump[2]; - - CompConstToX86reg( - Is64Bit(MappedReg) ? GetMipsRegMapHi(MappedReg) : Map_TempReg(x86_Any, MappedReg, true), - Is64Bit(ConstReg) ? GetMipsRegHi(ConstReg) : (GetMipsRegLo_S(ConstReg) >> 31) - ); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - if (MappedReg == m_Opcode.rs) - { - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetgVariable(&m_BranchCompare, "m_BranchCompare"); - } - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); - if (MappedReg == m_Opcode.rs) - { - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetaVariable(&m_BranchCompare, "m_BranchCompare"); - } - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - uint32_t Constant = GetMipsRegLo(ConstReg); - Map_GPR_32bit(m_Opcode.rd, true, -1); - CompConstToX86reg(GetMipsRegMapLo(MappedReg), Constant); - - if (GetMipsRegMapLo(m_Opcode.rd) > x86_EBX) - { - if (MappedReg == m_Opcode.rs) - { - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetgVariable(&m_BranchCompare, "m_BranchCompare"); - } - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - if (MappedReg == m_Opcode.rs) - { - Setl(GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Setg(GetMipsRegMapLo(m_Opcode.rd)); - } - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), 1); - } - } - } - } - else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) - { - uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - uint8_t *Jump[2]; - - if (!g_System->b32BitCore()) - { - if (Is64Bit(KnownReg)) - { - if (IsConst(KnownReg)) - { - CompConstToVariable(GetMipsRegHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else - { - CompX86regToVariable(GetMipsRegMapHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - } - else - { - if (IsConst(KnownReg)) - { - CompConstToVariable((GetMipsRegLo_S(KnownReg) >> 31), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else - { - ProtectGPR(KnownReg); - CompX86regToVariable(Map_TempReg(x86_Any, KnownReg, true), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - } - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - if (KnownReg == (IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt)) - { - SetgVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - } - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - if (IsConst(KnownReg)) - { - CompConstToVariable(GetMipsRegLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - else - { - CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - if (KnownReg == (IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt)) { - SetaVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - } - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - if (IsMapped(KnownReg)) - { - ProtectGPR(KnownReg); - } - bool bConstant = IsConst(KnownReg); - uint32_t Value = IsConst(KnownReg) ? GetMipsRegLo(KnownReg) : 0; - - Map_GPR_32bit(m_Opcode.rd, true, -1); - if (bConstant) - { - CompConstToVariable(Value, &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - else - { - CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - if (GetMipsRegMapLo(m_Opcode.rd) > x86_EBX) - { - if (KnownReg == (bConstant ? m_Opcode.rs : m_Opcode.rt)) - { - SetgVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - } - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - if (KnownReg == (bConstant ? m_Opcode.rs : m_Opcode.rt)) - { - Setg(GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Setl(GetMipsRegMapLo(m_Opcode.rd)); - } - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), 1); - } - } - } - else if (g_System->b32BitCore()) - { - x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rs, false); - Map_GPR_32bit(m_Opcode.rd, false, -1); - CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - if (GetMipsRegMapLo(m_Opcode.rd) > x86_EBX) - { - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Setl(GetMipsRegMapLo(m_Opcode.rd)); - AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), 1); - } - } - else - { - uint8_t *Jump[2] = { NULL, NULL }; - - x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rs, true); - CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - SetlVariable(&m_BranchCompare, "m_BranchCompare"); - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompX86regToVariable(Map_TempReg(Reg, m_Opcode.rs, false), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - if (Jump[1]) - { - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - } - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } -} - -void CRecompilerOps::SPECIAL_SLTU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) - { - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - g_Notify->DisplayError("1"); - CRecompilerOps::UnknownOpcode(); - } - else - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - if (GetMipsRegLo(m_Opcode.rs) < GetMipsRegLo(m_Opcode.rt)) - { - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 1); - } - else - { - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 0); - } - } - } - else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) - { - ProtectGPR(m_Opcode.rt); - ProtectGPR(m_Opcode.rs); - if ((Is64Bit(m_Opcode.rt) && Is64Bit(m_Opcode.rs)) || - (!g_System->b32BitCore() && (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)))) - { - uint8_t *Jump[2]; - - CompX86RegToX86Reg( - Is64Bit(m_Opcode.rs) ? GetMipsRegMapHi(m_Opcode.rs) : Map_TempReg(x86_Any, m_Opcode.rs, true), - Is64Bit(m_Opcode.rt) ? GetMipsRegMapHi(m_Opcode.rt) : Map_TempReg(x86_Any, m_Opcode.rt, true) - ); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - } - else - { - if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) - { - uint32_t ConstHi, ConstLo, ConstReg, MappedReg; - x86Reg MappedRegHi, MappedRegLo; - uint8_t *Jump[2]; - - ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - ConstLo = GetMipsRegLo_S(ConstReg); - ConstHi = GetMipsRegLo_S(ConstReg) >> 31; - if (Is64Bit(ConstReg)) { ConstHi = GetMipsRegHi(ConstReg); } - - ProtectGPR(MappedReg); - MappedRegLo = GetMipsRegMapLo(MappedReg); - MappedRegHi = GetMipsRegMapHi(MappedReg); - if (Is32Bit(MappedReg)) - { - MappedRegHi = Map_TempReg(x86_Any, MappedReg, true); - } - - Map_GPR_32bit(m_Opcode.rd, true, -1); - CompConstToX86reg(MappedRegHi, ConstHi); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - if (MappedReg == m_Opcode.rs) - { - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetaVariable(&m_BranchCompare, "m_BranchCompare"); - } - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompConstToX86reg(MappedRegLo, ConstLo); - if (MappedReg == m_Opcode.rs) - { - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetaVariable(&m_BranchCompare, "m_BranchCompare"); - } - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - uint32_t Const = IsConst(m_Opcode.rs) ? GetMipsRegLo(m_Opcode.rs) : GetMipsRegLo(m_Opcode.rt); - uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - - CompConstToX86reg(GetMipsRegMapLo(MappedReg), Const); - if (MappedReg == m_Opcode.rs) - { - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetaVariable(&m_BranchCompare, "m_BranchCompare"); - } - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - } - } - else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) - { - uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; - uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; - uint8_t *Jump[2] = { NULL, NULL }; - - ProtectGPR(KnownReg); - if (g_System->b32BitCore()) - { - uint32_t TestReg = IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt; - if (IsConst(KnownReg)) - { - uint32_t Value = GetMipsRegLo(KnownReg); - Map_GPR_32bit(m_Opcode.rd, true, -1); - CompConstToVariable(Value, &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - else - { - CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - if (KnownReg == TestReg) - { - SetaVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - } - } - else - { - if (IsConst(KnownReg)) - { - if (Is64Bit(KnownReg)) - { - CompConstToVariable(GetMipsRegHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else - { - CompConstToVariable((GetMipsRegLo_S(KnownReg) >> 31), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - } - else - { - if (Is64Bit(KnownReg)) - { - CompX86regToVariable(GetMipsRegMapHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - else - { - ProtectGPR(KnownReg); - CompX86regToVariable(Map_TempReg(x86_Any, KnownReg, true), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); - } - } - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - - if (KnownReg == (IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt)) - { - SetaVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - } - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - if (IsConst(KnownReg)) - { - CompConstToVariable(GetMipsRegLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - else - { - CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); - } - if (KnownReg == (IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt)) - { - SetaVariable(&m_BranchCompare, "m_BranchCompare"); - } - else - { - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - } - if (Jump[1]) - { - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - } - } - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else if (g_System->b32BitCore()) - { - x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rs, false); - Map_GPR_32bit(m_Opcode.rd, false, -1); - CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - uint8_t *Jump[2] = { NULL, NULL }; - - x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rs, true); - CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); - JeLabel8("Low Compare", 0); - Jump[0] = m_RecompPos - 1; - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - JmpLabel8("Continue", 0); - Jump[1] = m_RecompPos - 1; - - CPU_Message(""); - CPU_Message(" Low Compare:"); - SetJump8(Jump[0], m_RecompPos); - CompX86regToVariable(Map_TempReg(Reg, m_Opcode.rs, false), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - SetbVariable(&m_BranchCompare, "m_BranchCompare"); - if (Jump[1]) - { - CPU_Message(""); - CPU_Message(" Continue:"); - SetJump8(Jump[1], m_RecompPos); - } - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); - } -} - -void CRecompilerOps::SPECIAL_DADD() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, - Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs) + - Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt) - ); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - } - else - { - int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; - int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; - - if (IsMapped(source2)) { ProtectGPR(source2); } - Map_GPR_64bit(m_Opcode.rd, source1); - if (IsConst(source2)) - { - AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(source2)); - AddConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(source2)); - } - else if (IsMapped(source2)) - { - x86Reg HiReg = Is64Bit(source2) ? GetMipsRegMapHi(source2) : Map_TempReg(x86_Any, source2, true); - AddX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - AdcX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); - } - else - { - AddVariableToX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[source2].W[0], CRegName::GPR_Lo[source2]); - AdcVariableToX86reg(GetMipsRegMapHi(m_Opcode.rd), &_GPR[source2].W[1], CRegName::GPR_Hi[source2]); - } - } -} - -void CRecompilerOps::SPECIAL_DADDU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - return; - - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - int64_t ValRs = Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs); - int64_t ValRt = Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt); - if (IsMapped(m_Opcode.rd)) - UnMap_GPR(m_Opcode.rd, false); - - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, ValRs + ValRt); - if ((GetMipsRegHi(m_Opcode.rd) == 0) && (GetMipsRegLo(m_Opcode.rd) & 0x80000000) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if ((GetMipsRegHi(m_Opcode.rd) == 0xFFFFFFFF) && (GetMipsRegLo(m_Opcode.rd) & 0x80000000) != 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - } - else - { - int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; - int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; - - if (IsMapped(source2)) { ProtectGPR(source2); } - Map_GPR_64bit(m_Opcode.rd, source1); - if (IsConst(source2)) - { - DWORD LoReg = GetMipsRegLo(source2); - AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), LoReg); - if(LoReg != 0) - { - AdcConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(source2)); - } - else - { - AddConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(source2)); - } - } - else if (IsMapped(source2)) - { - x86Reg HiReg = Is64Bit(source2) ? GetMipsRegMapHi(source2) : Map_TempReg(x86_Any, source2, true); - AddX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); - AdcX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); - } - else - { - AddVariableToX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[source2].W[0], CRegName::GPR_Lo[source2]); - AdcVariableToX86reg(GetMipsRegMapHi(m_Opcode.rd), &_GPR[source2].W[1], CRegName::GPR_Hi[source2]); - } - } -} - -void CRecompilerOps::SPECIAL_DSUB() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, - Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs) - - Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt) - ); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - } - else - { - if (m_Opcode.rd == m_Opcode.rt) - { - x86Reg HiReg = Map_TempReg(x86_Any, m_Opcode.rt, true); - x86Reg LoReg = Map_TempReg(x86_Any, m_Opcode.rt, false); - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rs); - SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), LoReg); - SbbX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); - return; - } - - if (IsMapped(m_Opcode.rt)) { ProtectGPR(m_Opcode.rt); } - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rs); - if (IsConst(m_Opcode.rt)) - { - SubConstFromX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(m_Opcode.rt)); - SbbConstFromX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(m_Opcode.rt)); - } - else if (IsMapped(m_Opcode.rt)) - { - x86Reg HiReg = Is64Bit(m_Opcode.rt) ? GetMipsRegMapHi(m_Opcode.rt) : Map_TempReg(x86_Any, m_Opcode.rt, true); - SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt)); - SbbX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); - } - else - { - SubVariableFromX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - SbbVariableFromX86reg(GetMipsRegMapHi(m_Opcode.rd), &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); - } - } -} - -void CRecompilerOps::SPECIAL_DSUBU() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, - Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs) - - Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt) - ); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - } - else - { - if (m_Opcode.rd == m_Opcode.rt) - { - x86Reg HiReg = Map_TempReg(x86_Any, m_Opcode.rt, true); - x86Reg LoReg = Map_TempReg(x86_Any, m_Opcode.rt, false); - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rs); - SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), LoReg); - SbbX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); - return; - } - if (IsMapped(m_Opcode.rt)) { ProtectGPR(m_Opcode.rt); } - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rs); - if (IsConst(m_Opcode.rt)) - { - SubConstFromX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(m_Opcode.rt)); - SbbConstFromX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(m_Opcode.rt)); - } - else if (IsMapped(m_Opcode.rt)) - { - x86Reg HiReg = Is64Bit(m_Opcode.rt) ? GetMipsRegMapHi(m_Opcode.rt) : Map_TempReg(x86_Any, m_Opcode.rt, true); - SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt)); - SbbX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); - } - else - { - SubVariableFromX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); - SbbVariableFromX86reg(GetMipsRegMapHi(m_Opcode.rd), &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); - } - } -} - -void CRecompilerOps::SPECIAL_DSLL() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - int64_t Value = Is64Bit(m_Opcode.rt) ? GetMipsReg_S(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt); - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, Value << m_Opcode.sa); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - return; - } - - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - ShiftLeftDoubleImmed(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); - ShiftLeftSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); -} - -void CRecompilerOps::SPECIAL_DSRL() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - int64_t Value = Is64Bit(m_Opcode.rt) ? GetMipsReg_S(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt); - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, Value >> m_Opcode.sa); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - return; - } - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - ShiftRightDoubleImmed(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); - ShiftRightUnsignImmed(GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); -} - -void CRecompilerOps::SPECIAL_DSRA() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt)) - { - if (IsMapped(m_Opcode.rd)) - { - UnMap_GPR(m_Opcode.rd, false); - } - - int64_t Value = Is64Bit(m_Opcode.rt) ? GetMipsReg_S(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt); - m_RegWorkingSet.SetMipsReg_S(m_Opcode.rd, Value >> m_Opcode.sa); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - return; - } - - Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); - ShiftRightDoubleImmed(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); - ShiftRightSignImmed(GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); -} - -void CRecompilerOps::SPECIAL_DSLL32() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (m_Opcode.rd == 0) - { - return; - } - - if (IsConst(m_Opcode.rt)) - { - if (m_Opcode.rt != m_Opcode.rd) - { - UnMap_GPR(m_Opcode.rd, false); - } - m_RegWorkingSet.SetMipsRegHi(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) << m_Opcode.sa); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 0); - if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - } - else - { - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - } - } - else if (IsMapped(m_Opcode.rt)) - { - ProtectGPR(m_Opcode.rt); - Map_GPR_64bit(m_Opcode.rd, -1); - if (m_Opcode.rt != m_Opcode.rd) - { - MoveX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rt), GetMipsRegMapHi(m_Opcode.rd)); - } - else - { - CPU_Message(" regcache: switch hi (%s) with lo (%s) for %s", x86_Name(GetMipsRegMapHi(m_Opcode.rt)), x86_Name(GetMipsRegMapLo(m_Opcode.rt)), CRegName::GPR[m_Opcode.rt]); - x86Reg HiReg = GetMipsRegMapHi(m_Opcode.rt); - m_RegWorkingSet.SetMipsRegMapHi(m_Opcode.rt, GetMipsRegMapLo(m_Opcode.rt)); - m_RegWorkingSet.SetMipsRegMapLo(m_Opcode.rt, HiReg); - } - if ((uint8_t)m_Opcode.sa != 0) - { - ShiftLeftSignImmed(GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); - } - XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); - } - else - { - Map_GPR_64bit(m_Opcode.rd, -1); - MoveVariableToX86reg(&_GPR[m_Opcode.rt], CRegName::GPR_Hi[m_Opcode.rt], GetMipsRegMapHi(m_Opcode.rd)); - if ((uint8_t)m_Opcode.sa != 0) - { - ShiftLeftSignImmed(GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); - } - XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); - } -} - -void CRecompilerOps::SPECIAL_DSRL32() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsConst(m_Opcode.rt)) - { - if (m_Opcode.rt != m_Opcode.rd) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); - m_RegWorkingSet.SetMipsReg(m_Opcode.rd, (uint32_t)(GetMipsRegHi(m_Opcode.rt) >> m_Opcode.sa)); - } - else if (IsMapped(m_Opcode.rt)) - { - ProtectGPR(m_Opcode.rt); - if (Is64Bit(m_Opcode.rt)) - { - if (m_Opcode.rt == m_Opcode.rd) - { - CPU_Message(" regcache: switch hi (%s) with lo (%s) for %s", x86_Name(GetMipsRegMapHi(m_Opcode.rt)), x86_Name(GetMipsRegMapLo(m_Opcode.rt)), CRegName::GPR[m_Opcode.rt]); - x86Reg HiReg = GetMipsRegMapHi(m_Opcode.rt); - m_RegWorkingSet.SetMipsRegMapHi(m_Opcode.rt, GetMipsRegMapLo(m_Opcode.rt)); - m_RegWorkingSet.SetMipsRegMapLo(m_Opcode.rt, HiReg); - Map_GPR_32bit(m_Opcode.rd, false, -1); - } - else - { - Map_GPR_32bit(m_Opcode.rd, false, -1); - MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rt), GetMipsRegMapLo(m_Opcode.rd)); - } - if ((uint8_t)m_Opcode.sa != 0) - { - ShiftRightUnsignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); - } - } - else - { - CRecompilerOps::UnknownOpcode(); - } - } - else { - Map_GPR_32bit(m_Opcode.rd, false, -1); - MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[1], CRegName::GPR_Hi[m_Opcode.rt], GetMipsRegMapLo(m_Opcode.rd)); - if ((uint8_t)m_Opcode.sa != 0) - { - ShiftRightUnsignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); - } - } -} - -void CRecompilerOps::SPECIAL_DSRA32() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (IsConst(m_Opcode.rt)) - { - if (m_Opcode.rt != m_Opcode.rd) - { - UnMap_GPR(m_Opcode.rd, false); - } - - m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); - m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, (uint32_t)(GetMipsReg_S(m_Opcode.rt) >> (m_Opcode.sa + 32))); - } - else if (IsMapped(m_Opcode.rt)) - { - ProtectGPR(m_Opcode.rt); - if (Is64Bit(m_Opcode.rt)) - { - if (m_Opcode.rt == m_Opcode.rd) - { - CPU_Message(" regcache: switch hi (%s) with lo (%s) for %s", x86_Name(GetMipsRegMapHi(m_Opcode.rt)), x86_Name(GetMipsRegMapLo(m_Opcode.rt)), CRegName::GPR[m_Opcode.rt]); - x86Reg HiReg = GetMipsRegMapHi(m_Opcode.rt); - m_RegWorkingSet.SetMipsRegMapHi(m_Opcode.rt, GetMipsRegMapLo(m_Opcode.rt)); - m_RegWorkingSet.SetMipsRegMapLo(m_Opcode.rt, HiReg); - Map_GPR_32bit(m_Opcode.rd, true, -1); - } - else - { - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rt), GetMipsRegMapLo(m_Opcode.rd)); - } - if ((uint8_t)m_Opcode.sa != 0) - { - ShiftRightSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); - } - } - else - { - CRecompilerOps::UnknownOpcode(); - } - } - else { - Map_GPR_32bit(m_Opcode.rd, true, -1); - MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[1], CRegName::GPR_Lo[m_Opcode.rt], GetMipsRegMapLo(m_Opcode.rd)); - if ((uint8_t)m_Opcode.sa != 0) - { - ShiftRightSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); - } - } -} - -/************************** COP0 functions **************************/ -void CRecompilerOps::COP0_MF() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - switch (m_Opcode.rd) - { - case 9: //Count - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); - AfterCallDirect(m_RegWorkingSet); - } - Map_GPR_32bit(m_Opcode.rt, true, -1); - MoveVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], GetMipsRegMapLo(m_Opcode.rt)); -} - -void CRecompilerOps::COP0_MT() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - uint8_t *Jump; - - switch (m_Opcode.rd) - { - case 0: //Index - case 2: //EntryLo0 - case 3: //EntryLo1 - case 4: //Context - case 5: //PageMask - case 10: //Entry Hi - case 14: //EPC - case 16: //Config - case 18: //WatchLo - case 19: //WatchHi - case 28: //Tag lo - case 29: //Tag Hi - case 30: //ErrEPC - if (IsConst(m_Opcode.rt)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - if (m_Opcode.rd == 4) //Context - { - AndConstToVariable(0xFF800000, &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - break; - case 11: //Compare - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); - AfterCallDirect(m_RegWorkingSet); - if (IsConst(m_Opcode.rt)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - AndConstToVariable((uint32_t)~CAUSE_IP7, &g_Reg->FAKE_CAUSE_REGISTER, "FAKE_CAUSE_REGISTER"); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::UpdateCompareTimer), "CSystemTimer::UpdateCompareTimer"); - AfterCallDirect(m_RegWorkingSet); - break; - case 9: //Count - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); - AfterCallDirect(m_RegWorkingSet); - if (IsConst(m_Opcode.rt)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::UpdateCompareTimer), "CSystemTimer::UpdateCompareTimer"); - AfterCallDirect(m_RegWorkingSet); - break; - case 12: //Status - { - x86Reg OldStatusReg = Map_TempReg(x86_Any, -1, false); - MoveVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); - if (IsConst(m_Opcode.rt)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - XorVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); - TestConstToX86Reg(STATUS_FR, OldStatusReg); - JeLabel8("FpuFlagFine", 0); - Jump = m_RecompPos - 1; - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); - Call_Direct(AddressOf(&CRegisters::FixFpuLocations), "CRegisters::FixFpuLocations"); - - AfterCallDirect(m_RegWorkingSet); - SetJump8(Jump, m_RecompPos); - - //TestConstToX86Reg(STATUS_FR,OldStatusReg); - //BreakPoint(__FILEW__,__LINE__); //m_Section->CompileExit(m_CompilePC+4,m_RegWorkingSet,ExitResetRecompCode,false,JneLabel32); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); - Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); - AfterCallDirect(m_RegWorkingSet); - } - break; - case 6: //Wired - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); - AfterCallDirect(m_RegWorkingSet); - if (IsConst(m_Opcode.rt)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - break; - case 13: //cause - if (IsConst(m_Opcode.rt)) - { - AndConstToVariable(0xFFFFCFF, &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - if ((GetMipsRegLo(m_Opcode.rt) & 0x300) != 0 && bHaveDebugger()){ g_Notify->DisplayError("Set IP0 or IP1"); } - } - else - { - UnknownOpcode(); - return; - } - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); - Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); - AfterCallDirect(m_RegWorkingSet); - break; - default: - UnknownOpcode(); - } -} - -/************************** COP0 CO functions ***********************/ -void CRecompilerOps::COP0_CO_TLBR(void) -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (!g_System->bUseTlb()) { return; } - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_TLB, x86_ECX); - Call_Direct(AddressOf(&CTLB::ReadEntry), "CTLB::ReadEntry"); - AfterCallDirect(m_RegWorkingSet); -} - -void CRecompilerOps::COP0_CO_TLBWI(void) -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (!g_System->bUseTlb()) { return; } - BeforeCallDirect(m_RegWorkingSet); - PushImm32("false", 0); - MoveVariableToX86reg(&g_Reg->INDEX_REGISTER, "INDEX_REGISTER", x86_ECX); - AndConstToX86Reg(x86_ECX, 0x1F); - Push(x86_ECX); - MoveConstToX86reg((uint32_t)g_TLB, x86_ECX); - Call_Direct(AddressOf(&CTLB::WriteEntry), "CTLB::WriteEntry"); - AfterCallDirect(m_RegWorkingSet); -} - -void CRecompilerOps::COP0_CO_TLBWR(void) -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - if (!g_System->bUseTlb()) { return; } - - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); - - PushImm32("true", true); - MoveVariableToX86reg(&g_Reg->RANDOM_REGISTER, "RANDOM_REGISTER", x86_ECX); - AndConstToX86Reg(x86_ECX, 0x1F); - Push(x86_ECX); - MoveConstToX86reg((uint32_t)g_TLB, x86_ECX); - Call_Direct(AddressOf(&CTLB::WriteEntry), "CTLB::WriteEntry"); - AfterCallDirect(m_RegWorkingSet); -} - -void CRecompilerOps::COP0_CO_TLBP(void) -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - if (!g_System->bUseTlb()) { return; } - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_TLB, x86_ECX); - Call_Direct(AddressOf(&CTLB::Probe), "CTLB::TLB_Probe"); - AfterCallDirect(m_RegWorkingSet); -} - -void compiler_COP0_CO_ERET() -{ - if ((g_Reg->STATUS_REGISTER & STATUS_ERL) != 0) { - g_Reg->m_PROGRAM_COUNTER = g_Reg->ERROREPC_REGISTER; - g_Reg->STATUS_REGISTER &= ~STATUS_ERL; - } - else - { - g_Reg->m_PROGRAM_COUNTER = g_Reg->EPC_REGISTER; - g_Reg->STATUS_REGISTER &= ~STATUS_EXL; - } - g_Reg->m_LLBit = 0; - g_Reg->CheckInterrupts(); -} - -void CRecompilerOps::COP0_CO_ERET(void) -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_RegWorkingSet.WriteBackRegisters(); - Call_Direct((void *)compiler_COP0_CO_ERET, "compiler_COP0_CO_ERET"); - - UpdateCounters(m_RegWorkingSet, true, true); - m_Section->CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); - m_NextInstruction = END_BLOCK; -} - -/************************** FPU Options **************************/ -void CRecompilerOps::ChangeDefaultRoundingModel() -{ - switch ((_FPCR[31] & 3)) - { - case 0: *_RoundingModel = FE_TONEAREST; break; - case 1: *_RoundingModel = FE_TOWARDZERO; break; - case 2: *_RoundingModel = FE_UPWARD; break; - case 3: *_RoundingModel = FE_DOWNWARD; break; - } -} - -/************************** COP1 functions **************************/ -void CRecompilerOps::COP1_MF() -{ - x86Reg TempReg; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - - UnMap_FPR(m_Opcode.fs, true); - Map_GPR_32bit(m_Opcode.rt, true, -1); - TempReg = Map_TempReg(x86_Any, -1, false); - char Name[100]; - sprintf(Name, "_FPR_S[%d]", m_Opcode.fs); - MoveVariableToX86reg((uint8_t *)&_FPR_S[m_Opcode.fs], Name, TempReg); - MoveX86PointerToX86reg(GetMipsRegMapLo(m_Opcode.rt), TempReg); -} - -void CRecompilerOps::COP1_DMF() -{ - x86Reg TempReg; - char Name[50]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - - UnMap_FPR(m_Opcode.fs, true); - Map_GPR_64bit(m_Opcode.rt, -1); - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_D[%d]", m_Opcode.fs); - MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.fs], Name, TempReg); - AddConstToX86Reg(TempReg, 4); - MoveX86PointerToX86reg(GetMipsRegMapHi(m_Opcode.rt), TempReg); - sprintf(Name, "_FPR_D[%d]", m_Opcode.fs); - MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.fs], Name, TempReg); - MoveX86PointerToX86reg(GetMipsRegMapLo(m_Opcode.rt), TempReg); -} - -void CRecompilerOps::COP1_CF() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - - if (m_Opcode.fs != 31 && m_Opcode.fs != 0) - { - UnknownOpcode(); - return; - } - - Map_GPR_32bit(m_Opcode.rt, true, -1); - MoveVariableToX86reg(&_FPCR[m_Opcode.fs], CRegName::FPR_Ctrl[m_Opcode.fs], GetMipsRegMapLo(m_Opcode.rt)); -} - -void CRecompilerOps::COP1_MT() -{ - x86Reg TempReg; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - - if ((m_Opcode.fs & 1) != 0) - { - if (RegInStack(m_Opcode.fs - 1, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs - 1, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs - 1, true); - } - } - UnMap_FPR(m_Opcode.fs, true); - TempReg = Map_TempReg(x86_Any, -1, false); - char Name[50]; - sprintf(Name, "_FPR_S[%d]", m_Opcode.fs); - MoveVariableToX86reg((uint8_t *)&_FPR_S[m_Opcode.fs], Name, TempReg); - - if (IsConst(m_Opcode.rt)) - { - MoveConstToX86Pointer(GetMipsRegLo(m_Opcode.rt), TempReg); - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToX86Pointer(GetMipsRegMapLo(m_Opcode.rt), TempReg); - } - else - { - MoveX86regToX86Pointer(Map_TempReg(x86_Any, m_Opcode.rt, false), TempReg); - } -} - -void CRecompilerOps::COP1_DMT() -{ - x86Reg TempReg; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - - if ((m_Opcode.fs & 1) == 0) - { - if (RegInStack(m_Opcode.fs + 1, CRegInfo::FPU_Float) || RegInStack(m_Opcode.fs + 1, CRegInfo::FPU_Dword)) { - UnMap_FPR(m_Opcode.fs + 1, true); - } - } - UnMap_FPR(m_Opcode.fs, true); - TempReg = Map_TempReg(x86_Any, -1, false); - char Name[50]; - sprintf(Name, "_FPR_D[%d]", m_Opcode.fs); - MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.fs], Name, TempReg); - - if (IsConst(m_Opcode.rt)) - { - MoveConstToX86Pointer(GetMipsRegLo(m_Opcode.rt), TempReg); - AddConstToX86Reg(TempReg, 4); - if (Is64Bit(m_Opcode.rt)) - { - MoveConstToX86Pointer(GetMipsRegHi(m_Opcode.rt), TempReg); - } - else - { - MoveConstToX86Pointer(GetMipsRegLo_S(m_Opcode.rt) >> 31, TempReg); - } - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToX86Pointer(GetMipsRegMapLo(m_Opcode.rt), TempReg); - AddConstToX86Reg(TempReg, 4); - if (Is64Bit(m_Opcode.rt)) - { - MoveX86regToX86Pointer(GetMipsRegMapHi(m_Opcode.rt), TempReg); - } - else - { - MoveX86regToX86Pointer(Map_TempReg(x86_Any, m_Opcode.rt, true), TempReg); - } - } - else - { - x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rt, false); - MoveX86regToX86Pointer(Reg, TempReg); - AddConstToX86Reg(TempReg, 4); - MoveX86regToX86Pointer(Map_TempReg(Reg, m_Opcode.rt, true), TempReg); - } -} - -void CRecompilerOps::COP1_CT() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - - if (m_Opcode.fs != 31) - { - UnknownOpcode(); - return; - } - - if (IsConst(m_Opcode.rt)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_FPCR[m_Opcode.fs], CRegName::FPR_Ctrl[m_Opcode.fs]); - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_FPCR[m_Opcode.fs], CRegName::FPR_Ctrl[m_Opcode.fs]); - } - else - { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_FPCR[m_Opcode.fs], CRegName::FPR_Ctrl[m_Opcode.fs]); - } - BeforeCallDirect(m_RegWorkingSet); - Call_Direct((void *)ChangeDefaultRoundingModel, "ChangeDefaultRoundingModel"); - AfterCallDirect(m_RegWorkingSet); - m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); -} - -/************************** COP1: S functions ************************/ -void CRecompilerOps::COP1_S_ADD() -{ - uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - - Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); - if (RegInStack(Reg2, CRegInfo::FPU_Float)) - { - fpuAddReg(StackPosition(Reg2)); - } - else - { - x86Reg TempReg; - - UnMap_FPR(Reg2, true); - TempReg = Map_TempReg(x86_Any, -1, false); - char Name[50]; - sprintf(Name, "_FPR_S[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); - fpuAddDwordRegPointer(TempReg); - } - UnMap_FPR(m_Opcode.fd, true); -} - -void CRecompilerOps::COP1_S_SUB() -{ - uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - x86Reg TempReg; - char Name[50]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - - if (m_Opcode.fd == m_Opcode.ft) - { - UnMap_FPR(m_Opcode.fd, true); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_S[%d]", m_Opcode.ft); - MoveVariableToX86reg((uint8_t *)&_FPR_S[m_Opcode.ft], Name, TempReg); - fpuSubDwordRegPointer(TempReg); - } - else - { - Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); - if (RegInStack(Reg2, CRegInfo::FPU_Float)) - { - fpuSubReg(StackPosition(Reg2)); - } - else - { - UnMap_FPR(Reg2, true); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); - - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_S[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); - fpuSubDwordRegPointer(TempReg); - } - } - UnMap_FPR(m_Opcode.fd, true); -} - -void CRecompilerOps::COP1_S_MUL() -{ - uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - x86Reg TempReg; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - - Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); - if (RegInStack(Reg2, CRegInfo::FPU_Float)) - { - fpuMulReg(StackPosition(Reg2)); - } - else - { - UnMap_FPR(Reg2, true); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); - - TempReg = Map_TempReg(x86_Any, -1, false); - char Name[50]; - sprintf(Name, "_FPR_S[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); - fpuMulDwordRegPointer(TempReg); - } - UnMap_FPR(m_Opcode.fd, true); -} - -void CRecompilerOps::COP1_S_DIV() -{ - uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - x86Reg TempReg; - char Name[50]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - - if (m_Opcode.fd == m_Opcode.ft) - { - UnMap_FPR(m_Opcode.fd, true); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_S[%d]", m_Opcode.ft); - MoveVariableToX86reg((uint8_t *)&_FPR_S[m_Opcode.ft], Name, TempReg); - fpuDivDwordRegPointer(TempReg); - } - else - { - Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); - if (RegInStack(Reg2, CRegInfo::FPU_Float)) - { - fpuDivReg(StackPosition(Reg2)); - } - else - { - UnMap_FPR(Reg2, true); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); - - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_S[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); - fpuDivDwordRegPointer(TempReg); - } - } - - UnMap_FPR(m_Opcode.fd, true); -} - -void CRecompilerOps::COP1_S_ABS() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - fpuAbs(); - UnMap_FPR(m_Opcode.fd, true); -} - -void CRecompilerOps::COP1_S_NEG() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - fpuNeg(); - UnMap_FPR(m_Opcode.fd, true); -} - -void CRecompilerOps::COP1_S_SQRT() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - fpuSqrt(); - UnMap_FPR(m_Opcode.fd, true); -} - -void CRecompilerOps::COP1_S_MOV() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); -} - -void CRecompilerOps::COP1_S_TRUNC_L() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundTruncate); -} - -void CRecompilerOps::COP1_S_CEIL_L() //added by Witten -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundUp); -} - -void CRecompilerOps::COP1_S_FLOOR_L() //added by Witten -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundDown); -} - -void CRecompilerOps::COP1_S_ROUND_W() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundNearest); -} - -void CRecompilerOps::COP1_S_TRUNC_W() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundTruncate); -} - -void CRecompilerOps::COP1_S_CEIL_W() // added by Witten -{ // added by Witten - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundUp); -} - -void CRecompilerOps::COP1_S_FLOOR_W() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundDown); -} - -void CRecompilerOps::COP1_S_CVT_D() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Double, CRegInfo::RoundDefault); -} - -void CRecompilerOps::COP1_S_CVT_W() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundDefault); -} - -void CRecompilerOps::COP1_S_CVT_L() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundDefault); -} - -void CRecompilerOps::COP1_S_CMP() -{ - uint32_t Reg1 = m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft; - uint32_t cmp = 0; - - if ((m_Opcode.funct & 4) == 0) - { - Reg1 = RegInStack(m_Opcode.ft, CRegInfo::FPU_Float) ? m_Opcode.ft : m_Opcode.fs; - Reg2 = RegInStack(m_Opcode.ft, CRegInfo::FPU_Float) ? m_Opcode.fs : m_Opcode.ft; - } - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if ((m_Opcode.funct & 7) == 0) { CRecompilerOps::UnknownOpcode(); } - if ((m_Opcode.funct & 2) != 0) { cmp |= 0x4000; } - if ((m_Opcode.funct & 4) != 0) { cmp |= 0x0100; } - - Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Float); - Map_TempReg(x86_EAX, 0, false); - if (RegInStack(Reg2, CRegInfo::FPU_Float)) - { - fpuComReg(StackPosition(Reg2), false); - } - else - { - UnMap_FPR(Reg2, true); - Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Float); - - x86Reg TempReg = Map_TempReg(x86_Any, -1, false); - char Name[50]; - sprintf(Name, "_FPR_S[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); - fpuComDwordRegPointer(TempReg, false); - } - AndConstToVariable((uint32_t)~FPCSR_C, &_FPCR[31], "_FPCR[31]"); - fpuStoreStatus(); - x86Reg Reg = Map_TempReg(x86_Any8Bit, 0, false); - TestConstToX86Reg(cmp, x86_EAX); - Setnz(Reg); - - if (cmp != 0) - { - TestConstToX86Reg(cmp, x86_EAX); - Setnz(Reg); - - if ((m_Opcode.funct & 1) != 0) - { - x86Reg Reg2 = Map_TempReg(x86_Any8Bit, 0, false); - AndConstToX86Reg(x86_EAX, 0x4300); - CompConstToX86reg(x86_EAX, 0x4300); - Setz(Reg2); - - OrX86RegToX86Reg(Reg, Reg2); - } - } - else if ((m_Opcode.funct & 1) != 0) - { - AndConstToX86Reg(x86_EAX, 0x4300); - CompConstToX86reg(x86_EAX, 0x4300); - Setz(Reg); - } - ShiftLeftSignImmed(Reg, 23); - OrX86RegToVariable(&_FPCR[31], "_FPCR[31]", Reg); -} - -/************************** COP1: D functions ************************/ -void CRecompilerOps::COP1_D_ADD() -{ - uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - char Name[50]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - - Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); - if (RegInStack(Reg2, CRegInfo::FPU_Double)) - { - fpuAddReg(StackPosition(Reg2)); - } - else - { - x86Reg TempReg; - - UnMap_FPR(Reg2, true); - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_D[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Double); - fpuAddQwordRegPointer(TempReg); - } -} - -void CRecompilerOps::COP1_D_SUB() -{ - uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - x86Reg TempReg; - char Name[50]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - - if (m_Opcode.fd == m_Opcode.ft) - { - UnMap_FPR(m_Opcode.fd, true); - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_D[%d]", m_Opcode.ft); - MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.ft], Name, TempReg); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - fpuSubQwordRegPointer(TempReg); - } - else - { - Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); - if (RegInStack(Reg2, CRegInfo::FPU_Double)) - { - fpuSubReg(StackPosition(Reg2)); - } - else - { - UnMap_FPR(Reg2, true); - - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_D[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Double); - fpuSubQwordRegPointer(TempReg); - } - } -} - -void CRecompilerOps::COP1_D_MUL() -{ - uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - x86Reg TempReg; - char Name[50]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - FixRoundModel(CRegInfo::RoundDefault); - - Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); - if (RegInStack(Reg2, CRegInfo::FPU_Double)) - { - fpuMulReg(StackPosition(Reg2)); - } - else - { - UnMap_FPR(Reg2, true); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Double); - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_D[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); - fpuMulQwordRegPointer(TempReg); - } -} - -void CRecompilerOps::COP1_D_DIV() -{ - uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - x86Reg TempReg; - char Name[50]; - - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - - if (m_Opcode.fd == m_Opcode.ft) - { - UnMap_FPR(m_Opcode.fd, true); - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_D[%d]", m_Opcode.ft); - MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.ft], Name, TempReg); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - fpuDivQwordRegPointer(TempReg); - } - else - { - Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); - if (RegInStack(Reg2, CRegInfo::FPU_Double)) - { - fpuDivReg(StackPosition(Reg2)); - } - else - { - UnMap_FPR(Reg2, true); - TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_D[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Double); - fpuDivQwordRegPointer(TempReg); - } - } -} - -void CRecompilerOps::COP1_D_ABS() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - fpuAbs(); -} - -void CRecompilerOps::COP1_D_NEG() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - fpuNeg(); -} - -void CRecompilerOps::COP1_D_SQRT() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - fpuSqrt(); -} - -void CRecompilerOps::COP1_D_MOV() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); -} - -void CRecompilerOps::COP1_D_TRUNC_L() //added by Witten -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundTruncate); -} - -void CRecompilerOps::COP1_D_CEIL_L() //added by Witten -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundUp); -} - -void CRecompilerOps::COP1_D_FLOOR_L() //added by Witten -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundDown); -} - -void CRecompilerOps::COP1_D_ROUND_W() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundNearest); -} - -void CRecompilerOps::COP1_D_TRUNC_W() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fd, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundTruncate); -} - -void CRecompilerOps::COP1_D_CEIL_W() // added by Witten -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundUp); -} - -void CRecompilerOps::COP1_D_FLOOR_W() //added by Witten -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDown); -} - -void CRecompilerOps::COP1_D_CVT_S() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fd, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Float, CRegInfo::RoundDefault); -} - -void CRecompilerOps::COP1_D_CVT_W() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDefault); -} - -void CRecompilerOps::COP1_D_CVT_L() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) - { - UnMap_FPR(m_Opcode.fs, true); - } - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundDefault); -} - -void CRecompilerOps::COP1_D_CMP() -{ - uint32_t Reg1 = m_Opcode.fs; - uint32_t Reg2 = m_Opcode.ft; - uint32_t cmp = 0; - - if ((m_Opcode.funct & 4) == 0) - { - Reg1 = RegInStack(m_Opcode.ft, CRegInfo::FPU_Double) ? m_Opcode.ft : m_Opcode.fs; - Reg2 = RegInStack(m_Opcode.ft, CRegInfo::FPU_Double) ? m_Opcode.fs : m_Opcode.ft; - } - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if ((m_Opcode.funct & 7) == 0) { CRecompilerOps::UnknownOpcode(); } - if ((m_Opcode.funct & 2) != 0) { cmp |= 0x4000; } - if ((m_Opcode.funct & 4) != 0) { cmp |= 0x0100; } - - Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Double); - Map_TempReg(x86_EAX, 0, false); - if (RegInStack(Reg2, CRegInfo::FPU_Double)) - { - fpuComReg(StackPosition(Reg2), false); - } - else - { - char Name[50]; - - UnMap_FPR(Reg2, true); - x86Reg TempReg = Map_TempReg(x86_Any, -1, false); - sprintf(Name, "_FPR_D[%d]", Reg2); - MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); - Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Double); - fpuComQwordRegPointer(TempReg, false); - } - AndConstToVariable((uint32_t)~FPCSR_C, &_FPCR[31], "_FPCR[31]"); - fpuStoreStatus(); - x86Reg Reg = Map_TempReg(x86_Any8Bit, 0, false); - TestConstToX86Reg(cmp, x86_EAX); - Setnz(Reg); - if (cmp != 0) - { - TestConstToX86Reg(cmp, x86_EAX); - Setnz(Reg); - - if ((m_Opcode.funct & 1) != 0) - { - x86Reg Reg2 = Map_TempReg(x86_Any8Bit, 0, false); - AndConstToX86Reg(x86_EAX, 0x4300); - CompConstToX86reg(x86_EAX, 0x4300); - Setz(Reg2); - - OrX86RegToX86Reg(Reg, Reg2); - } - } - else if ((m_Opcode.funct & 1) != 0) - { - AndConstToX86Reg(x86_EAX, 0x4300); - CompConstToX86reg(x86_EAX, 0x4300); - Setz(Reg); - } - ShiftLeftSignImmed(Reg, 23); - OrX86RegToVariable(&_FPCR[31], "_FPCR[31]", Reg); -} - -/************************** COP1: W functions ************************/ -void CRecompilerOps::COP1_W_CVT_S() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Dword, CRegInfo::FPU_Float, CRegInfo::RoundDefault); -} - -void CRecompilerOps::COP1_W_CVT_D() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Dword, CRegInfo::FPU_Double, CRegInfo::RoundDefault); -} - -/************************** COP1: L functions ************************/ -void CRecompilerOps::COP1_L_CVT_S() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Qword, CRegInfo::FPU_Float, CRegInfo::RoundDefault); -} - -void CRecompilerOps::COP1_L_CVT_D() -{ - CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_Section->CompileCop1Test(); - if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) - { - Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword); - } - ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Qword, CRegInfo::FPU_Double, CRegInfo::RoundDefault); -} - -/************************** Other functions **************************/ -void CRecompilerOps::UnknownOpcode() -{ - CPU_Message(" %X Unhandled Opcode: %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - - m_RegWorkingSet.WriteBackRegisters(); - UpdateCounters(m_RegWorkingSet, false, true); - MoveConstToVariable(m_CompilePC, &g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER"); - if (g_SyncSystem) - { - MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - - MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); - Call_Direct((void *)R4300iOp::UnknownOpcode, "R4300iOp::UnknownOpcode"); - Ret(); - if (m_NextInstruction == NORMAL) { m_NextInstruction = END_BLOCK; } -} - -void CRecompilerOps::BeforeCallDirect(CRegInfo & RegSet) -{ - RegSet.UnMap_AllFPRs(); - Pushad(); -} - -void CRecompilerOps::AfterCallDirect(CRegInfo & RegSet) -{ - Popad(); - RegSet.SetRoundingModel(CRegInfo::RoundUnknown); -} - -void CRecompilerOps::EnterCodeBlock() -{ -#ifdef _DEBUG - Push(x86_ESI); -#else - Push(x86_EDI); - Push(x86_ESI); - Push(x86_EBX); -#endif -} - -void CRecompilerOps::ExitCodeBlock() -{ -#ifdef _DEBUG - Pop(x86_ESI); -#else - Pop(x86_EBX); - Pop(x86_ESI); - Pop(x86_EDI); -#endif - Ret(); -} - -void CRecompilerOps::UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles) -{ - if (!g_SyncSystem) - { - return; - } - - WriteX86Comment("Updating Sync CPU"); - BeforeCallDirect(RegSet); - PushImm32(stdstr_f("%d", Cycles).c_str(), Cycles); - PushImm32("g_SyncSystem", (uint32_t)g_SyncSystem); - MoveConstToX86reg((uint32_t)g_System, x86_ECX); - Call_Direct(AddressOf(&CN64System::UpdateSyncCPU), "CN64System::UpdateSyncCPU"); - AfterCallDirect(RegSet); -} - -void CRecompilerOps::UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues) -{ - if (RegSet.GetBlockCycleCount() != 0) - { - UpdateSyncCPU(RegSet, RegSet.GetBlockCycleCount()); - WriteX86Comment("Update Counter"); - SubConstFromVariable(RegSet.GetBlockCycleCount(), g_NextTimer, "g_NextTimer"); // updates compare flag - if (ClearValues) - { - RegSet.SetBlockCycleCount(0); - } - } - else if (CheckTimer) - { - CompConstToVariable(0, g_NextTimer, "g_NextTimer"); - } - - if (CheckTimer) - { - JnsLabel8("Continue_From_Timer_Test", 0); - uint8_t * Jump = m_RecompPos - 1; - Pushad(); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::TimerDone), "CSystemTimer::TimerDone"); - Popad(); - - CPU_Message(""); - CPU_Message(" $Continue_From_Timer_Test:"); - SetJump8(Jump, m_RecompPos); - } -} - -void CRecompilerOps::CompileSystemCheck(uint32_t TargetPC, const CRegInfo & RegSet) -{ - CompConstToVariable(0, (void *)&g_SystemEvents->DoSomething(), "g_SystemEvents->DoSomething()"); - JeLabel32("Continue_From_Interrupt_Test", 0); - uint32_t * Jump = (uint32_t *)(m_RecompPos - 4); - if (TargetPC != (uint32_t)-1) - { - MoveConstToVariable(TargetPC, &g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER"); - } - - CRegInfo RegSetCopy(RegSet); - RegSetCopy.WriteBackRegisters(); - - MoveConstToX86reg((uint32_t)g_SystemEvents, x86_ECX); - Call_Direct(AddressOf(&CSystemEvents::ExecuteEvents), "CSystemEvents::ExecuteEvents"); - if (g_SyncSystem) - { - MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - ExitCodeBlock(); - CPU_Message(""); - CPU_Message(" $Continue_From_Interrupt_Test:"); - SetJump32(Jump, (uint32_t *)m_RecompPos); -} - -void CRecompilerOps::OverflowDelaySlot(bool TestTimer) -{ - m_RegWorkingSet.WriteBackRegisters(); - UpdateCounters(m_RegWorkingSet, false, true); - MoveConstToVariable(CompilePC() + 4, _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - - if (g_SyncSystem) - { - MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - - MoveConstToVariable(JUMP, &R4300iOp::m_NextInstruction, "R4300iOp::m_NextInstruction"); - - if (TestTimer) - { - MoveConstToVariable(TestTimer, &R4300iOp::m_TestTimer, "R4300iOp::m_TestTimer"); - } - - PushImm32("g_System->CountPerOp()", g_System->CountPerOp()); - Call_Direct((void *)CInterpreterCPU::ExecuteOps, "CInterpreterCPU::ExecuteOps"); - AddConstToX86Reg(x86_ESP, 4); - - if (g_System->bFastSP() && g_Recompiler) - { - MoveConstToX86reg((uint32_t)g_Recompiler, x86_ECX); - Call_Direct(AddressOf(&CRecompiler::ResetMemoryStackPos), "CRecompiler::ResetMemoryStackPos"); - } - - if (g_SyncSystem) - { - UpdateSyncCPU(m_RegWorkingSet, g_System->CountPerOp()); - MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - - ExitCodeBlock(); - m_NextInstruction = END_BLOCK; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "x86CodeLog.h" + +CCodeSection * CRecompilerOps::m_Section = NULL; +CRegInfo CRecompilerOps::m_RegWorkingSet; +STEP_TYPE CRecompilerOps::m_NextInstruction; +uint32_t CRecompilerOps::m_CompilePC; +OPCODE CRecompilerOps::m_Opcode; +uint32_t CRecompilerOps::m_BranchCompare = 0; + +void CRecompilerOps::CompileReadTLBMiss(uint32_t VirtualAddress, x86Reg LookUpReg) +{ + MoveConstToVariable(VirtualAddress, g_TLBLoadAddress, "TLBLoadAddress"); + TestX86RegToX86Reg(LookUpReg, LookUpReg); + m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBReadMiss, false, JeLabel32); +} + +void CRecompilerOps::CompileReadTLBMiss(x86Reg AddressReg, x86Reg LookUpReg) +{ + MoveX86regToVariable(AddressReg, g_TLBLoadAddress, "TLBLoadAddress"); + TestX86RegToX86Reg(LookUpReg, LookUpReg); + m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBReadMiss, false, JeLabel32); +} + +void CRecompilerOps::CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg) +{ + MoveX86regToVariable(AddressReg, &g_TLBStoreAddress, "g_TLBStoreAddress"); + TestX86RegToX86Reg(LookUpReg, LookUpReg); + m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBWriteMiss, false, JeLabel32); +} + +bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); + +/************************** Branch functions ************************/ +void CRecompilerOps::Compile_Branch(CRecompilerOps::BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link) +{ + static CRegInfo RegBeforeDelay; + static bool EffectDelaySlot; + + if (m_NextInstruction == NORMAL) + { + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4 == m_CompilePC + 8) + { + return; + } + + if ((m_CompilePC & 0xFFC) != 0xFFC) + { + switch (BranchType) + { + case BranchTypeRs: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0); break; + case BranchTypeRsRt: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, m_Opcode.rt); break; + case BranchTypeCop1: + { + OPCODE Command; + + if (!g_MMU->LW_VAddr(m_CompilePC + 4, Command.Hex)) + { + g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD)); + } + + EffectDelaySlot = false; + if (Command.op == R4300i_CP1) + { + if ((Command.fmt == R4300i_COP1_S && (Command.funct & 0x30) == 0x30) || + (Command.fmt == R4300i_COP1_D && (Command.funct & 0x30) == 0x30)) + { + EffectDelaySlot = true; + } + } + } + break; + default: + if (bHaveDebugger()) { g_Notify->DisplayError("Unknown branch type"); } + } + } + else + { + EffectDelaySlot = true; + } + m_Section->m_Jump.JumpPC = m_CompilePC; + m_Section->m_Jump.TargetPC = m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4; + if (m_Section->m_JumpSection != NULL) + { + m_Section->m_Jump.BranchLabel.Format("Section_%d", m_Section->m_JumpSection->m_SectionID); + } + else + { + m_Section->m_Jump.BranchLabel.Format("Exit_%X_jump_%X", m_Section->m_EnterPC, m_Section->m_Jump.TargetPC); + } + m_Section->m_Jump.LinkLocation = NULL; + m_Section->m_Jump.LinkLocation2 = NULL; + m_Section->m_Jump.DoneDelaySlot = false; + m_Section->m_Cont.JumpPC = m_CompilePC; + m_Section->m_Cont.TargetPC = m_CompilePC + 8; + if (m_Section->m_ContinueSection != NULL) + { + m_Section->m_Cont.BranchLabel.Format("Section_%d", m_Section->m_ContinueSection->m_SectionID); + } + else + { + m_Section->m_Cont.BranchLabel.Format("Exit_%X_continue_%X", m_Section->m_EnterPC, m_Section->m_Cont.TargetPC); + } + m_Section->m_Cont.LinkLocation = NULL; + m_Section->m_Cont.LinkLocation2 = NULL; + m_Section->m_Cont.DoneDelaySlot = false; + if (m_Section->m_Jump.TargetPC < m_Section->m_Cont.TargetPC) + { + m_Section->m_Cont.FallThrough = false; + m_Section->m_Jump.FallThrough = true; + } + else + { + m_Section->m_Cont.FallThrough = true; + m_Section->m_Jump.FallThrough = false; + } + + if (Link) + { + UnMap_GPR(31, false); + m_RegWorkingSet.SetMipsRegLo(31, m_CompilePC + 8); + m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + } + if (EffectDelaySlot) + { + if ((m_CompilePC & 0xFFC) != 0xFFC) + { + m_Section->m_Cont.BranchLabel = m_Section->m_ContinueSection != NULL ? "Continue" : "ExitBlock"; + m_Section->m_Jump.BranchLabel = m_Section->m_JumpSection != NULL ? "Jump" : "ExitBlock"; + } + else + { + m_Section->m_Cont.BranchLabel = "Continue"; + m_Section->m_Jump.BranchLabel = "Jump"; + } + if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC) + { + CompareFunc(); + } + if (!m_Section->m_Jump.FallThrough && !m_Section->m_Cont.FallThrough) + { + if (m_Section->m_Jump.LinkLocation != NULL) + { + CPU_Message(""); + CPU_Message(" %s:", m_Section->m_Jump.BranchLabel.c_str()); + SetJump32((uint32_t *)m_Section->m_Jump.LinkLocation, (uint32_t *)m_RecompPos); + m_Section->m_Jump.LinkLocation = NULL; + if (m_Section->m_Jump.LinkLocation2 != NULL) + { + SetJump32((uint32_t *)m_Section->m_Jump.LinkLocation2, (uint32_t *)m_RecompPos); + m_Section->m_Jump.LinkLocation2 = NULL; + } + m_Section->m_Jump.FallThrough = true; + } + else if (m_Section->m_Cont.LinkLocation != NULL) + { + CPU_Message(""); + CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str()); + SetJump32((uint32_t *)m_Section->m_Cont.LinkLocation, (uint32_t *)m_RecompPos); + m_Section->m_Cont.LinkLocation = NULL; + if (m_Section->m_Cont.LinkLocation2 != NULL) + { + SetJump32((uint32_t *)m_Section->m_Cont.LinkLocation2, (uint32_t *)m_RecompPos); + m_Section->m_Cont.LinkLocation2 = NULL; + } + m_Section->m_Cont.FallThrough = true; + } + } + if ((m_CompilePC & 0xFFC) == 0xFFC) + { + uint8_t * DelayLinkLocation = NULL; + if (m_Section->m_Jump.FallThrough) + { + if (m_Section->m_Jump.LinkLocation != NULL || m_Section->m_Jump.LinkLocation2 != NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + } + else if (m_Section->m_Cont.FallThrough) + { + if (m_Section->m_Cont.LinkLocation != NULL || m_Section->m_Cont.LinkLocation2 != NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + MoveConstToVariable(m_Section->m_Cont.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + } + + if (m_Section->m_Jump.LinkLocation != NULL || m_Section->m_Jump.LinkLocation2 != NULL) + { + JmpLabel8("DoDelaySlot", 0); + if (DelayLinkLocation != NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } + DelayLinkLocation = (uint8_t *)(m_RecompPos - 1); + + CPU_Message(" "); + CPU_Message(" %s:", m_Section->m_Jump.BranchLabel.c_str()); + SetJump32(m_Section->m_Jump.LinkLocation, (uint32_t *)m_RecompPos); + m_Section->m_Jump.LinkLocation = NULL; + if (m_Section->m_Jump.LinkLocation2 != NULL) + { + SetJump32(m_Section->m_Jump.LinkLocation2, (uint32_t *)m_RecompPos); + m_Section->m_Jump.LinkLocation2 = NULL; + } + MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + } + if (m_Section->m_Cont.LinkLocation != NULL || m_Section->m_Cont.LinkLocation2 != NULL) + { + JmpLabel8("DoDelaySlot", 0); + if (DelayLinkLocation != NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } + DelayLinkLocation = (uint8_t *)(m_RecompPos - 1); + + CPU_Message(" "); + CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str()); + SetJump32(m_Section->m_Cont.LinkLocation, (uint32_t *)m_RecompPos); + m_Section->m_Cont.LinkLocation = NULL; + if (m_Section->m_Cont.LinkLocation2 != NULL) + { + SetJump32(m_Section->m_Cont.LinkLocation2, (uint32_t *)m_RecompPos); + m_Section->m_Cont.LinkLocation2 = NULL; + } + MoveConstToVariable(m_Section->m_Cont.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + } + if (DelayLinkLocation) + { + CPU_Message(""); + CPU_Message(" DoDelaySlot:"); + SetJump8(DelayLinkLocation, m_RecompPos); + } + OverflowDelaySlot(false); + return; + } + ResetX86Protection(); + RegBeforeDelay = m_RegWorkingSet; + } + m_NextInstruction = DO_DELAY_SLOT; + } + else if (m_NextInstruction == DELAY_SLOT_DONE) + { + if (EffectDelaySlot) + { + CJumpInfo * FallInfo = m_Section->m_Jump.FallThrough ? &m_Section->m_Jump : &m_Section->m_Cont; + CJumpInfo * JumpInfo = m_Section->m_Jump.FallThrough ? &m_Section->m_Cont : &m_Section->m_Jump; + + if (FallInfo->FallThrough && !FallInfo->DoneDelaySlot) + { + ResetX86Protection(); + FallInfo->RegSet = m_RegWorkingSet; + if (FallInfo == &m_Section->m_Jump) + { + if (m_Section->m_JumpSection != NULL) + { + m_Section->m_Jump.BranchLabel.Format("Section_%d", m_Section->m_JumpSection->m_SectionID); + } + else + { + m_Section->m_Jump.BranchLabel = "ExitBlock"; + } + if (FallInfo->TargetPC <= m_CompilePC) + { + UpdateCounters(m_Section->m_Jump.RegSet, true, true); + CPU_Message("CompileSystemCheck 12"); + CompileSystemCheck(FallInfo->TargetPC, m_Section->m_Jump.RegSet); + ResetX86Protection(); + FallInfo->ExitReason = CExitInfo::Normal_NoSysCheck; + FallInfo->JumpPC = (uint32_t)-1; + } + } + else + { + if (m_Section->m_ContinueSection != NULL) + { + m_Section->m_Cont.BranchLabel.Format("Section_%d", m_Section->m_ContinueSection->m_SectionID); + } + else + { + m_Section->m_Cont.BranchLabel = "ExitBlock"; + } + } + FallInfo->DoneDelaySlot = true; + if (!JumpInfo->DoneDelaySlot) + { + FallInfo->FallThrough = false; + JmpLabel32(FallInfo->BranchLabel.c_str(), 0); + FallInfo->LinkLocation = (uint32_t *)(m_RecompPos - 4); + + if (JumpInfo->LinkLocation != NULL) + { + CPU_Message(" %s:", JumpInfo->BranchLabel.c_str()); + SetJump32((uint32_t *)JumpInfo->LinkLocation, (uint32_t *)m_RecompPos); + JumpInfo->LinkLocation = NULL; + if (JumpInfo->LinkLocation2 != NULL) + { + SetJump32((uint32_t *)JumpInfo->LinkLocation2, (uint32_t *)m_RecompPos); + JumpInfo->LinkLocation2 = NULL; + } + JumpInfo->FallThrough = true; + m_NextInstruction = DO_DELAY_SLOT; + m_RegWorkingSet = RegBeforeDelay; + return; + } + } + } + } + else + { + if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC) + { + CompareFunc(); + ResetX86Protection(); + m_Section->m_Cont.RegSet = m_RegWorkingSet; + m_Section->m_Jump.RegSet = m_RegWorkingSet; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + m_Section->m_Cont.RegSet = m_RegWorkingSet; + if (m_Section->m_ContinueSection == NULL && m_Section->m_JumpSection != NULL) + { + m_Section->m_ContinueSection = m_Section->m_JumpSection; + m_Section->m_JumpSection = NULL; + } + if (m_Section->m_ContinueSection != NULL) + { + m_Section->m_Cont.BranchLabel.Format("Section_%d", m_Section->m_ContinueSection->m_SectionID); + } + else + { + m_Section->m_Cont.BranchLabel = "ExitBlock"; + } + } + } + m_Section->GenerateSectionLinkage(); + m_NextInstruction = END_BLOCK; + } + else + { + if (bHaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); + } + } +} + +void CRecompilerOps::Compile_BranchLikely(BranchFunction CompareFunc, bool Link) +{ + if (m_NextInstruction == NORMAL) + { + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (!g_System->bLinkBlocks() || (m_CompilePC & 0xFFC) == 0xFFC) + { + m_Section->m_Jump.JumpPC = m_CompilePC; + m_Section->m_Jump.TargetPC = m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4; + m_Section->m_Cont.JumpPC = m_CompilePC; + m_Section->m_Cont.TargetPC = m_CompilePC + 8; + } + else + { + if (m_Section->m_Jump.JumpPC != m_CompilePC) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_Section->m_Cont.JumpPC != m_CompilePC) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_Section->m_Cont.TargetPC != m_CompilePC + 8) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + + if (m_Section->m_JumpSection != NULL) + { + m_Section->m_Jump.BranchLabel.Format("Section_%d", ((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); + } + else + { + m_Section->m_Jump.BranchLabel = "ExitBlock"; + } + + if (m_Section->m_ContinueSection != NULL) + { + m_Section->m_Cont.BranchLabel.Format("Section_%d", ((CCodeSection *)m_Section->m_ContinueSection)->m_SectionID); + } + else + { + m_Section->m_Cont.BranchLabel = "ExitBlock"; + } + + m_Section->m_Jump.FallThrough = true; + m_Section->m_Jump.LinkLocation = NULL; + m_Section->m_Jump.LinkLocation2 = NULL; + m_Section->m_Cont.FallThrough = false; + m_Section->m_Cont.LinkLocation = NULL; + m_Section->m_Cont.LinkLocation2 = NULL; + + if (Link) + { + UnMap_GPR(31, false); + m_RegWorkingSet.SetMipsRegLo(31, m_CompilePC + 8); + m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + } + + CompareFunc(); + ResetX86Protection(); + + m_Section->m_Cont.RegSet = m_RegWorkingSet; + if ((m_CompilePC & 0xFFC) == 0xFFC) + { + if (m_Section->m_Cont.FallThrough) + { + if (m_Section->m_Jump.LinkLocation != NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + + if (m_Section->m_Jump.LinkLocation != NULL || m_Section->m_Jump.FallThrough) + { + if (m_Section->m_Jump.LinkLocation != NULL) + { + SetJump32(m_Section->m_Jump.LinkLocation, (uint32_t *)m_RecompPos); + m_Section->m_Jump.LinkLocation = NULL; + if (m_Section->m_Jump.LinkLocation2 != NULL) + { + SetJump32(m_Section->m_Jump.LinkLocation2, (uint32_t *)m_RecompPos); + m_Section->m_Jump.LinkLocation2 = NULL; + } + } + + MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + OverflowDelaySlot(false); + CPU_Message(" "); + CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str()); + } + else if (!m_Section->m_Cont.FallThrough) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + if (m_Section->m_Cont.LinkLocation != NULL) + { + SetJump32(m_Section->m_Cont.LinkLocation, (uint32_t *)m_RecompPos); + m_Section->m_Cont.LinkLocation = NULL; + if (m_Section->m_Cont.LinkLocation2 != NULL) + { + SetJump32(m_Section->m_Cont.LinkLocation2, (uint32_t *)m_RecompPos); + m_Section->m_Cont.LinkLocation2 = NULL; + } + } + m_Section->CompileExit(m_CompilePC, m_CompilePC + 8, m_Section->m_Cont.RegSet, CExitInfo::Normal, true, NULL); + return; + } + else + { + m_NextInstruction = DO_DELAY_SLOT; + } + + if (g_System->bLinkBlocks()) + { + m_Section->m_Jump.RegSet = m_RegWorkingSet; + m_Section->GenerateSectionLinkage(); + m_NextInstruction = END_BLOCK; + } + else + { + if (m_Section->m_Cont.FallThrough) + { + if (m_Section->m_Jump.LinkLocation != NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + m_Section->GenerateSectionLinkage(); + m_NextInstruction = END_BLOCK; + } + } + } + else if (m_NextInstruction == DELAY_SLOT_DONE) + { + ResetX86Protection(); + m_Section->m_Jump.RegSet = m_RegWorkingSet; + m_Section->GenerateSectionLinkage(); + m_NextInstruction = END_BLOCK; + } + else if (bHaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("WTF\n\nBranchLikely\nNextInstruction = %X", m_NextInstruction).c_str()); + } +} + +void CRecompilerOps::BNE_Compare() +{ + uint8_t *Jump = NULL; + + if (IsKnown(m_Opcode.rs) && IsKnown(m_Opcode.rt)) + { + if (IsConst(m_Opcode.rs) && IsConst(m_Opcode.rt)) + { + if (Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) + { + CRecompilerOps::UnknownOpcode(); + } + else if (GetMipsRegLo(m_Opcode.rs) != GetMipsRegLo(m_Opcode.rt)) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else if (IsMapped(m_Opcode.rs) && IsMapped(m_Opcode.rt)) + { + ProtectGPR(m_Opcode.rs); + ProtectGPR(m_Opcode.rt); + if (Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) + { + CompX86RegToX86Reg( + Is32Bit(m_Opcode.rs) ? Map_TempReg(x86_Any, m_Opcode.rs, true) : GetMipsRegMapHi(m_Opcode.rs), + Is32Bit(m_Opcode.rt) ? Map_TempReg(x86_Any, m_Opcode.rt, true) : GetMipsRegMapHi(m_Opcode.rt) + ); + + if (m_Section->m_Jump.FallThrough) + { + JneLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + if (m_Section->m_Cont.FallThrough) + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + else + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + if (m_Section->m_Cont.FallThrough) + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + } + else + { + uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (Is64Bit(ConstReg) || Is64Bit(MappedReg)) + { + if (Is32Bit(ConstReg) || Is32Bit(MappedReg)) + { + ProtectGPR(MappedReg); + if (Is32Bit(MappedReg)) + { + CompConstToX86reg(Map_TempReg(x86_Any, MappedReg, true), GetMipsRegHi(ConstReg)); + } + else + { + CompConstToX86reg(GetMipsRegMapHi(MappedReg), GetMipsRegLo_S(ConstReg) >> 31); + } + } + else + { + CompConstToX86reg(GetMipsRegMapHi(MappedReg), GetMipsRegHi(ConstReg)); + } + if (m_Section->m_Jump.FallThrough) + { + JneLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); + if (m_Section->m_Cont.FallThrough) + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + else + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); + if (m_Section->m_Cont.FallThrough) + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + } + } + else if (IsKnown(m_Opcode.rs) || IsKnown(m_Opcode.rt)) + { + uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (!g_System->b32BitCore()) + { + if (IsConst(KnownReg)) + { + if (Is64Bit(KnownReg)) + { + CompConstToVariable(GetMipsRegHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else if (IsSigned(KnownReg)) + { + CompConstToVariable((GetMipsRegLo_S(KnownReg) >> 31), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else + { + CompConstToVariable(0, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + } + else + { + if (Is64Bit(KnownReg)) + { + CompX86regToVariable(GetMipsRegMapHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else if (IsSigned(KnownReg)) + { + ProtectGPR(KnownReg); + CompX86regToVariable(Map_TempReg(x86_Any, KnownReg, true), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else + { + CompConstToVariable(0, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + } + if (m_Section->m_Jump.FallThrough) + { + JneLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + if (IsConst(KnownReg)) + { + CompConstToVariable(GetMipsRegLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + else + { + CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + if (m_Section->m_Cont.FallThrough) + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + if (g_System->b32BitCore()) + { + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + else if (m_Section->m_Jump.FallThrough) + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + + if (Jump) + { + CPU_Message(" "); + CPU_Message(" continue:"); + + SetJump8(Jump, m_RecompPos); + } + } + else + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + if (g_System->b32BitCore()) + { + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + } + else + { + x86Reg Reg = x86_Any; + + if (!g_System->b32BitCore()) + { + Reg = Map_TempReg(x86_Any, m_Opcode.rt, true); + CompX86regToVariable(Reg, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); + if (m_Section->m_Jump.FallThrough) + { + JneLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + + Reg = Map_TempReg(Reg, m_Opcode.rt, false); + CompX86regToVariable(Reg, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + if (m_Section->m_Cont.FallThrough) + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + if (g_System->b32BitCore()) + { + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + else if (m_Section->m_Jump.FallThrough) + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + if (Jump) + { + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + } + else + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + if (g_System->b32BitCore()) + { + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + } +} + +void CRecompilerOps::BEQ_Compare() +{ + uint8_t *Jump = NULL; + + if (IsKnown(m_Opcode.rs) && IsKnown(m_Opcode.rt)) + { + if (IsConst(m_Opcode.rs) && IsConst(m_Opcode.rt)) + { + if (Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) + { + CRecompilerOps::UnknownOpcode(); + } + else if (GetMipsRegLo(m_Opcode.rs) == GetMipsRegLo(m_Opcode.rt)) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else if (IsMapped(m_Opcode.rs) && IsMapped(m_Opcode.rt)) + { + if ((Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) && !g_System->b32BitCore()) + { + ProtectGPR(m_Opcode.rs); + ProtectGPR(m_Opcode.rt); + + CompX86RegToX86Reg( + Is32Bit(m_Opcode.rs) ? Map_TempReg(x86_Any, m_Opcode.rs, true) : GetMipsRegMapHi(m_Opcode.rs), + Is32Bit(m_Opcode.rt) ? Map_TempReg(x86_Any, m_Opcode.rt, true) : GetMipsRegMapHi(m_Opcode.rt) + ); + if (m_Section->m_Cont.FallThrough) + { + JneLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + else if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + } + else + { + uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (Is64Bit(ConstReg) || Is64Bit(MappedReg)) + { + if (Is32Bit(ConstReg) || Is32Bit(MappedReg)) + { + if (Is32Bit(MappedReg)) + { + ProtectGPR(MappedReg); + CompConstToX86reg(Map_TempReg(x86_Any, MappedReg, true), GetMipsRegHi(ConstReg)); + } + else + { + CompConstToX86reg(GetMipsRegMapHi(MappedReg), GetMipsRegLo_S(ConstReg) >> 31); + } + } + else + { + CompConstToX86reg(GetMipsRegMapHi(MappedReg), GetMipsRegHi(ConstReg)); + } + if (m_Section->m_Cont.FallThrough) { + JneLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); + if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + else if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); + if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + } + } + else if (IsKnown(m_Opcode.rs) || IsKnown(m_Opcode.rt)) + { + uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (!g_System->b32BitCore()) + { + if (IsConst(KnownReg)) + { + if (Is64Bit(KnownReg)) + { + CompConstToVariable(GetMipsRegHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else if (IsSigned(KnownReg)) + { + CompConstToVariable(GetMipsRegLo_S(KnownReg) >> 31, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else + { + CompConstToVariable(0, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + } + else + { + ProtectGPR(KnownReg); + if (Is64Bit(KnownReg)) + { + CompX86regToVariable(GetMipsRegMapHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else if (IsSigned(KnownReg)) + { + CompX86regToVariable(Map_TempReg(x86_Any, KnownReg, true), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else + { + CompConstToVariable(0, &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + } + if (m_Section->m_Cont.FallThrough) + { + JneLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + if (IsConst(KnownReg)) + { + CompConstToVariable(GetMipsRegLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + else + { + CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + if (Jump) + { + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + } + else if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + if (g_System->b32BitCore()) + { + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + x86Reg Reg = x86_Any; + if (!g_System->b32BitCore()) + { + Reg = Map_TempReg(x86_Any, m_Opcode.rs, true); + CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); + if (m_Section->m_Cont.FallThrough) + { + JneLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + CompX86regToVariable(Map_TempReg(Reg, m_Opcode.rs, false), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + if (Jump) + { + CPU_Message(" "); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + } + else if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + if (g_System->b32BitCore()) + { + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + if (g_System->b32BitCore()) + { + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } +} + +void CRecompilerOps::BGTZ_Compare() +{ + if (IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + if (GetMipsReg_S(m_Opcode.rs) > 0) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else + { + if (GetMipsRegLo_S(m_Opcode.rs) > 0) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + } + else if (IsMapped(m_Opcode.rs) && Is32Bit(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); + if (m_Section->m_Jump.FallThrough) + { + JleLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Cont.FallThrough) + { + JgLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JleLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else if (IsUnknown(m_Opcode.rs) && g_System->b32BitCore()) + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + if (m_Section->m_Jump.FallThrough) + { + JleLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Cont.FallThrough) + { + JgLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JleLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + uint8_t *Jump = NULL; + + if (IsMapped(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), 0); + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); + } + if (m_Section->m_Jump.FallThrough) + { + JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JgLabel8("continue", 0); + Jump = m_RecompPos - 1; + } + else if (m_Section->m_Cont.FallThrough) + { + JlLabel8("continue", 0); + Jump = m_RecompPos - 1; + JgLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JgLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + + if (IsMapped(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + } + if (m_Section->m_Jump.FallThrough) + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + else if (m_Section->m_Cont.FallThrough) + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + else + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } +} + +void CRecompilerOps::BLEZ_Compare() +{ + if (IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + if (GetMipsReg_S(m_Opcode.rs) <= 0) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else if (IsSigned(m_Opcode.rs)) + { + if (GetMipsRegLo_S(m_Opcode.rs) <= 0) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else + { + if (GetMipsRegLo(m_Opcode.rs) == 0) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + } + else if (IsMapped(m_Opcode.rs)) + { + if (Is32Bit(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); + if (m_Section->m_Jump.FallThrough) + { + JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Cont.FallThrough) + { + JleLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + uint8_t *Jump = NULL; + + if (IsMapped(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), 0); + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); + } + if (m_Section->m_Jump.FallThrough) + { + JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JlLabel8("Continue", 0); + Jump = m_RecompPos - 1; + } + else if (m_Section->m_Cont.FallThrough) + { + JgLabel8("Continue", 0); + Jump = m_RecompPos - 1; + JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + + if (IsMapped(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + } + if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + else if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + JmpLabel32("BranchToJump", 0); + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + } + else { + uint8_t *Jump = NULL; + + if (!g_System->b32BitCore()) + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); + if (m_Section->m_Jump.FallThrough) + { + JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JlLabel8("Continue", 0); + Jump = m_RecompPos - 1; + } + else if (m_Section->m_Cont.FallThrough) + { + JgLabel8("Continue", 0); + Jump = m_RecompPos - 1; + JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + if (g_System->b32BitCore()) + { + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + if (Jump) + { + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + } + else if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + if (Jump) + { + CPU_Message(" continue:"); + SetJump8(Jump, m_RecompPos); + } + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + JmpLabel32("BranchToJump", 0); + m_Section->m_Jump.LinkLocation2 = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + if (m_Section->m_Jump.FallThrough) + { + JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Cont.FallThrough) + { + JleLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JgLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + } +} + +void CRecompilerOps::BLTZ_Compare() +{ + if (IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + if (GetMipsReg_S(m_Opcode.rs) < 0) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else if (IsSigned(m_Opcode.rs)) + { + if (GetMipsRegLo_S(m_Opcode.rs) < 0) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else if (IsMapped(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), 0); + if (m_Section->m_Jump.FallThrough) + { + JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Cont.FallThrough) + { + JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else if (IsSigned(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); + if (m_Section->m_Jump.FallThrough) + { + JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Cont.FallThrough) + { + JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else if (IsUnknown(m_Opcode.rs)) + { + if (g_System->b32BitCore()) + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); + } + if (m_Section->m_Jump.FallThrough) + { + JgeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Cont.FallThrough) + { + JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JlLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } +} + +void CRecompilerOps::BGEZ_Compare() +{ + if (IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + CRecompilerOps::UnknownOpcode(); + } + else if (IsSigned(m_Opcode.rs)) + { + if (GetMipsRegLo_S(m_Opcode.rs) >= 0) + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + else + { + m_Section->m_Jump.FallThrough = false; + m_Section->m_Cont.FallThrough = true; + } + } + else + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + } + else if (IsMapped(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), 0); + if (m_Section->m_Cont.FallThrough) + { + JgeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else if (IsSigned(m_Opcode.rs)) + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), 0); + if (m_Section->m_Cont.FallThrough) + { + JgeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } + else + { + m_Section->m_Jump.FallThrough = true; + m_Section->m_Cont.FallThrough = false; + } + } + else + { + if (g_System->b32BitCore()) + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); + } + if (m_Section->m_Cont.FallThrough) + { + JgeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JlLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + } +} + +void CRecompilerOps::COP1_BCF_Compare() +{ + TestVariable(FPCSR_C, &_FPCR[31], "_FPCR[31]"); + if (m_Section->m_Cont.FallThrough) + { + JeLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JneLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } +} + +void CRecompilerOps::COP1_BCT_Compare() +{ + TestVariable(FPCSR_C, &_FPCR[31], "_FPCR[31]"); + if (m_Section->m_Cont.FallThrough) + { + JneLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else if (m_Section->m_Jump.FallThrough) + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } + else + { + JeLabel32(m_Section->m_Cont.BranchLabel.c_str(), 0); + m_Section->m_Cont.LinkLocation = (uint32_t *)(m_RecompPos - 4); + JmpLabel32(m_Section->m_Jump.BranchLabel.c_str(), 0); + m_Section->m_Jump.LinkLocation = (uint32_t *)(m_RecompPos - 4); + } +} + +/************************* OpCode functions *************************/ +void CRecompilerOps::J() +{ + if (m_NextInstruction == NORMAL) + { + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if ((m_CompilePC & 0xFFC) == 0xFFC) + { + MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + OverflowDelaySlot(false); + return; + } + + m_Section->m_Jump.TargetPC = (m_CompilePC & 0xF0000000) + (m_Opcode.target << 2);; + m_Section->m_Jump.JumpPC = m_CompilePC; + if (m_Section->m_JumpSection != NULL) + { + m_Section->m_Jump.BranchLabel.Format("Section_%d", ((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); + } + else + { + m_Section->m_Jump.BranchLabel = "ExitBlock"; + } + m_Section->m_Jump.FallThrough = true; + m_Section->m_Jump.LinkLocation = NULL; + m_Section->m_Jump.LinkLocation2 = NULL; + m_NextInstruction = DO_DELAY_SLOT; + } + else if (m_NextInstruction == DELAY_SLOT_DONE) + { + m_Section->m_Jump.RegSet = m_RegWorkingSet; + m_Section->GenerateSectionLinkage(); + m_NextInstruction = END_BLOCK; + } + else if (bHaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("WTF\n\nJ\nNextInstruction = %X", m_NextInstruction).c_str()); + } +} + +void CRecompilerOps::JAL() +{ + if (m_NextInstruction == NORMAL) + { + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + Map_GPR_32bit(31, true, -1); + MoveVariableToX86reg(_PROGRAM_COUNTER, "_PROGRAM_COUNTER", GetMipsRegMapLo(31)); + AndConstToX86Reg(GetMipsRegMapLo(31), 0xF0000000); + AddConstToX86Reg(GetMipsRegMapLo(31), (m_CompilePC + 8) & ~0xF0000000); + if ((m_CompilePC & 0xFFC) == 0xFFC) + { + MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + OverflowDelaySlot(false); + return; + } + m_Section->m_Jump.TargetPC = (m_CompilePC & 0xF0000000) + (m_Opcode.target << 2); + m_Section->m_Jump.JumpPC = m_CompilePC; + if (m_Section->m_JumpSection != NULL) + { + m_Section->m_Jump.BranchLabel.Format("Section_%d", ((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); + } + else + { + m_Section->m_Jump.BranchLabel = "ExitBlock"; + } + m_Section->m_Jump.FallThrough = true; + m_Section->m_Jump.LinkLocation = NULL; + m_Section->m_Jump.LinkLocation2 = NULL; + m_NextInstruction = DO_DELAY_SLOT; + } + else if (m_NextInstruction == DELAY_SLOT_DONE) + { + if (m_Section->m_JumpSection) + { + m_Section->m_Jump.RegSet = m_RegWorkingSet; + m_Section->GenerateSectionLinkage(); + } + else + { + m_RegWorkingSet.WriteBackRegisters(); + + x86Reg pc_reg = Map_TempReg(x86_Any, -1, false); + MoveVariableToX86reg(_PROGRAM_COUNTER, "_PROGRAM_COUNTER", pc_reg); + AndConstToX86Reg(pc_reg, 0xF0000000); + AddConstToX86Reg(pc_reg, (m_Opcode.target << 2)); + MoveX86regToVariable(pc_reg, _PROGRAM_COUNTER, "_PROGRAM_COUNTER"); + + uint32_t TargetPC = (m_CompilePC & 0xF0000000) + (m_Opcode.target << 2); + bool bCheck = TargetPC <= m_CompilePC; + UpdateCounters(m_RegWorkingSet, bCheck, true); + + m_Section->CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, bCheck ? CExitInfo::Normal : CExitInfo::Normal_NoSysCheck, true, NULL); + } + m_NextInstruction = END_BLOCK; + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + return; +} + +void CRecompilerOps::ADDI() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rt == 0) { return; } + + if (g_System->bFastSP() && m_Opcode.rs == 29 && m_Opcode.rt == 29) + { + AddConstToX86Reg(Map_MemoryStack(x86_Any, true), (int16_t)m_Opcode.immediate); + } + + if (IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rt)) + { + UnMap_GPR(m_Opcode.rt, false); + } + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) + (int16_t)m_Opcode.immediate); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); + AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), (int16_t)m_Opcode.immediate); + } + if (g_System->bFastSP() && m_Opcode.rt == 29 && m_Opcode.rs != 29) + { + ResetX86Protection(); + g_MMU->ResetMemoryStack(); + } +} + +void CRecompilerOps::ADDIU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rt == 0 || (m_Opcode.immediate == 0 && m_Opcode.rs == m_Opcode.rt)) + { + return; + } + + if (g_System->bFastSP()) + { + if (m_Opcode.rs == 29 && m_Opcode.rt == 29) + { + AddConstToX86Reg(Map_MemoryStack(x86_Any, true), (int16_t)m_Opcode.immediate); + } + } + + if (IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rt)) + { + UnMap_GPR(m_Opcode.rt, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) + (int16_t)m_Opcode.immediate); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); + AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), (int16_t)m_Opcode.immediate); + } + + if (g_System->bFastSP() && m_Opcode.rt == 29 && m_Opcode.rs != 29) + { + ResetX86Protection(); + g_MMU->ResetMemoryStack(); + } +} + +void CRecompilerOps::SLTIU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rt == 0) + { + return; + } + + if (IsConst(m_Opcode.rs)) + { + uint32_t Result = Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) < ((unsigned)((int64_t)((int16_t)m_Opcode.immediate))) ? 1 : 0 : + GetMipsRegLo(m_Opcode.rs) < ((unsigned)((int16_t)m_Opcode.immediate)) ? 1 : 0; + UnMap_GPR(m_Opcode.rt, false); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, Result); + } + else if (IsMapped(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + uint8_t * Jump[2]; + + CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), ((int16_t)m_Opcode.immediate >> 31)); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), (int16_t)m_Opcode.immediate); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + Map_GPR_32bit(m_Opcode.rt, false, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), (int16_t)m_Opcode.immediate); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + Map_GPR_32bit(m_Opcode.rt, false, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); + } + } + else if (g_System->b32BitCore()) + { + CompConstToVariable((int16_t)m_Opcode.immediate, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + Map_GPR_32bit(m_Opcode.rt, false, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + uint8_t * Jump = NULL; + + CompConstToVariable(((int16_t)m_Opcode.immediate >> 31), &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); + JneLabel8("CompareSet", 0); + Jump = m_RecompPos - 1; + CompConstToVariable((int16_t)m_Opcode.immediate, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + CPU_Message(""); + CPU_Message(" CompareSet:"); + SetJump8(Jump, m_RecompPos); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + Map_GPR_32bit(m_Opcode.rt, false, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); + } +} + +void CRecompilerOps::SLTI() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rt == 0) + { + return; + } + + if (IsConst(m_Opcode.rs)) + { + uint32_t Result = Is64Bit(m_Opcode.rs) ? + ((int64_t)GetMipsReg(m_Opcode.rs) < (int64_t)((int16_t)m_Opcode.immediate) ? 1 : 0) : + (GetMipsRegLo_S(m_Opcode.rs) < (int16_t)m_Opcode.immediate ? 1 : 0); + + UnMap_GPR(m_Opcode.rt, false); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, Result); + } + else if (IsMapped(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + uint8_t * Jump[2]; + + CompConstToX86reg(GetMipsRegMapHi(m_Opcode.rs), ((int16_t)m_Opcode.immediate >> 31)); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), (int16_t)m_Opcode.immediate); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + Map_GPR_32bit(m_Opcode.rt, false, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + /* CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs),(int16_t)m_Opcode.immediate); + SetlVariable(&m_BranchCompare,"m_BranchCompare"); + Map_GPR_32bit(m_Opcode.rt, false, -1); + MoveVariableToX86reg(&m_BranchCompare,"m_BranchCompare",GetMipsRegMapLo(m_Opcode.rt)); + */ + ProtectGPR(m_Opcode.rs); + Map_GPR_32bit(m_Opcode.rt, false, -1); + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs), (int16_t)m_Opcode.immediate); + + if (GetMipsRegMapLo(m_Opcode.rt) > x86_EBX) + { + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + Setl(GetMipsRegMapLo(m_Opcode.rt)); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), 1); + } + } + } + else if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rt, false, -1); + CompConstToVariable((int16_t)m_Opcode.immediate, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + + if (GetMipsRegMapLo(m_Opcode.rt) > x86_EBX) + { + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + Setl(GetMipsRegMapLo(m_Opcode.rt)); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), 1); + } + } + else + { + uint8_t * Jump[2] = { NULL, NULL }; + CompConstToVariable(((int16_t)m_Opcode.immediate >> 31), &_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs]); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompConstToVariable((int16_t)m_Opcode.immediate, &_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs]); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + if (Jump[1]) + { + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + } + Map_GPR_32bit(m_Opcode.rt, false, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rt)); + } +} + +void CRecompilerOps::ANDI() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rt == 0) + { + return; + } + + if (IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rt)) + { + UnMap_GPR(m_Opcode.rt, false); + } + + m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) & m_Opcode.immediate); + } + else if (m_Opcode.immediate != 0) + { + Map_GPR_32bit(m_Opcode.rt, false, m_Opcode.rs); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), m_Opcode.immediate); + } + else + { + Map_GPR_32bit(m_Opcode.rt, false, 0); + } +} + +void CRecompilerOps::ORI() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rt == 0) + { + return; + } + + if (g_System->bFastSP() && m_Opcode.rs == 29 && m_Opcode.rt == 29) + { + OrConstToX86Reg(m_Opcode.immediate, Map_MemoryStack(x86_Any, true)); + } + + if (IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rt)) + { + UnMap_GPR(m_Opcode.rt, false); + } + + m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, GetMipsRegState(m_Opcode.rs)); + m_RegWorkingSet.SetMipsRegHi(m_Opcode.rt, GetMipsRegHi(m_Opcode.rs)); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) | m_Opcode.immediate); + } + else if (IsMapped(m_Opcode.rs)) + { + if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); + } + else + { + if (Is64Bit(m_Opcode.rs)) + { + Map_GPR_64bit(m_Opcode.rt, m_Opcode.rs); + } + else + { + Map_GPR_32bit(m_Opcode.rt, IsSigned(m_Opcode.rs), m_Opcode.rs); + } + } + OrConstToX86Reg(m_Opcode.immediate, GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); + } + else + { + Map_GPR_64bit(m_Opcode.rt, m_Opcode.rs); + } + OrConstToX86Reg(m_Opcode.immediate, GetMipsRegMapLo(m_Opcode.rt)); + } + + if (g_System->bFastSP() && m_Opcode.rt == 29 && m_Opcode.rs != 29) + { + ResetX86Protection(); + g_MMU->ResetMemoryStack(); + } +} + +void CRecompilerOps::XORI() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rt == 0) + { + return; + } + + if (IsConst(m_Opcode.rs)) + { + if (m_Opcode.rs != m_Opcode.rt) + { + UnMap_GPR(m_Opcode.rt, false); + } + + m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, GetMipsRegState(m_Opcode.rs)); + m_RegWorkingSet.SetMipsRegHi(m_Opcode.rt, GetMipsRegHi(m_Opcode.rs)); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, GetMipsRegLo(m_Opcode.rs) ^ m_Opcode.immediate); + } + else + { + if (IsMapped(m_Opcode.rs) && Is32Bit(m_Opcode.rs)) + { + Map_GPR_32bit(m_Opcode.rt, IsSigned(m_Opcode.rs), m_Opcode.rs); + } + else if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rs); + } + else + { + Map_GPR_64bit(m_Opcode.rt, m_Opcode.rs); + } + if (m_Opcode.immediate != 0) { XorConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt), m_Opcode.immediate); } + } +} + +void CRecompilerOps::LUI() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rt == 0) + { + return; + } + + if (g_System->bFastSP() && m_Opcode.rt == 29) + { + x86Reg Reg = Map_MemoryStack(x86_Any, true, false); + uint32_t Address; + + g_TransVaddr->TranslateVaddr(((int16_t)m_Opcode.offset << 16), Address); + if (Reg < 0) + { + MoveConstToVariable((uint32_t)(Address + g_MMU->Rdram()), &(g_Recompiler->MemoryStackPos()), "MemoryStack"); + } + else + { + MoveConstToX86reg((uint32_t)(Address + g_MMU->Rdram()), Reg); + } + } + + UnMap_GPR(m_Opcode.rt, false); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rt, ((int16_t)m_Opcode.offset << 16)); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rt, CRegInfo::STATE_CONST_32_SIGN); +} + +void CRecompilerOps::DADDIU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rs != 0) + { + UnMap_GPR(m_Opcode.rs, true); + } + + if (m_Opcode.rs != 0) + { + UnMap_GPR(m_Opcode.rt, true); + } + + BeforeCallDirect(m_RegWorkingSet); + MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); + Call_Direct((void *)R4300iOp::DADDIU, "R4300iOp::DADDIU"); + AfterCallDirect(m_RegWorkingSet); +} + +void CRecompilerOps::CACHE() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (g_Settings->LoadDword(Game_SMM_Cache) == 0) + { + return; + } + + switch (m_Opcode.rt) + { + case 0: + case 16: + BeforeCallDirect(m_RegWorkingSet); + PushImm32("CRecompiler::Remove_Cache", CRecompiler::Remove_Cache); + PushImm32("0x20", 0x20); + if (IsConst(m_Opcode.base)) + { + uint32_t Address = GetMipsRegLo(m_Opcode.base) + (int16_t)m_Opcode.offset; + PushImm32("Address", Address); + } + else if (IsMapped(m_Opcode.base)) + { + AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.base), (int16_t)m_Opcode.offset); + Push(GetMipsRegMapLo(m_Opcode.base)); + } + else + { + MoveVariableToX86reg(&_GPR[m_Opcode.base].UW[0], CRegName::GPR_Lo[m_Opcode.base], x86_EAX); + AddConstToX86Reg(x86_EAX, (int16_t)m_Opcode.offset); + Push(x86_EAX); + } + MoveConstToX86reg((uint32_t)g_Recompiler, x86_ECX); + Call_Direct(AddressOf(&CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); + AfterCallDirect(m_RegWorkingSet); + break; + case 1: + case 3: + case 13: + case 5: + case 8: + case 9: + case 17: + case 21: + case 25: + break; + default: + if (bHaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("cache: %d", m_Opcode.rt).c_str()); + } + } +} + +/********************** R4300i OpCodes: Special **********************/ +void CRecompilerOps::SPECIAL_SLL() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rd == 0) + { + return; + } + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) << m_Opcode.sa); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + return; + } + if (m_Opcode.rd != m_Opcode.rt && IsMapped(m_Opcode.rt)) + { + switch (m_Opcode.sa) + { + case 0: + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + break; + case 1: + ProtectGPR(m_Opcode.rt); + Map_GPR_32bit(m_Opcode.rd, true, -1); + LeaRegReg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt), 0, Multip_x2); + break; + case 2: + ProtectGPR(m_Opcode.rt); + Map_GPR_32bit(m_Opcode.rd, true, -1); + LeaRegReg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt), 0, Multip_x4); + break; + case 3: + ProtectGPR(m_Opcode.rt); + Map_GPR_32bit(m_Opcode.rd, true, -1); + LeaRegReg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt), 0, Multip_x8); + break; + default: + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftLeftSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); + } + } + else + { + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftLeftSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); + } +} + +void CRecompilerOps::SPECIAL_SRL() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) >> m_Opcode.sa); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + return; + } + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftRightUnsignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); +} + +void CRecompilerOps::SPECIAL_SRA() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo_S(m_Opcode.rt) >> m_Opcode.sa); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + return; + } + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftRightSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); +} + +void CRecompilerOps::SPECIAL_SLLV() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rs)) + { + uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x1F); + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) << Shift); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftLeftSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)Shift); + } + return; + } + Map_TempReg(x86_ECX, m_Opcode.rs, false); + AndConstToX86Reg(x86_ECX, 0x1F); + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftLeftSign(GetMipsRegMapLo(m_Opcode.rd)); +} + +void CRecompilerOps::SPECIAL_SRLV() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsKnown(m_Opcode.rs) && IsConst(m_Opcode.rs)) + { + uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x1F); + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) >> Shift); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + return; + } + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftRightUnsignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)Shift); + return; + } + + Map_TempReg(x86_ECX, m_Opcode.rs, false); + AndConstToX86Reg(x86_ECX, 0x1F); + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftRightUnsign(GetMipsRegMapLo(m_Opcode.rd)); +} + +void CRecompilerOps::SPECIAL_SRAV() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsKnown(m_Opcode.rs) && IsConst(m_Opcode.rs)) + { + uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x1F); + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo_S(m_Opcode.rt) >> Shift); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + return; + } + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftRightSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)Shift); + return; + } + Map_TempReg(x86_ECX, m_Opcode.rs, false); + AndConstToX86Reg(x86_ECX, 0x1F); + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + ShiftRightSign(GetMipsRegMapLo(m_Opcode.rd)); +} + +void CRecompilerOps::SPECIAL_JR() +{ + if (m_NextInstruction == NORMAL) + { + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if ((m_CompilePC & 0xFFC) == 0xFFC) + { + if (IsMapped(m_Opcode.rs)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + m_RegWorkingSet.WriteBackRegisters(); + } + else + { + m_RegWorkingSet.WriteBackRegisters(); + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + } + OverflowDelaySlot(true); + return; + } + + m_Section->m_Jump.FallThrough = false; + m_Section->m_Jump.LinkLocation = NULL; + m_Section->m_Jump.LinkLocation2 = NULL; + m_Section->m_Cont.FallThrough = false; + m_Section->m_Cont.LinkLocation = NULL; + m_Section->m_Cont.LinkLocation2 = NULL; + + if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) + { + if (IsConst(m_Opcode.rs)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + else if (IsMapped(m_Opcode.rs)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + } + m_NextInstruction = DO_DELAY_SLOT; + } + else if (m_NextInstruction == DELAY_SLOT_DONE) + { + if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) + { + m_Section->CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); + } + else + { + UpdateCounters(m_RegWorkingSet, true, true); + if (IsConst(m_Opcode.rs)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + else if (IsMapped(m_Opcode.rs)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + m_Section->CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); + if (m_Section->m_JumpSection) + { + m_Section->GenerateSectionLinkage(); + } + } + m_NextInstruction = END_BLOCK; + } + else if (bHaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); + } +} + +void CRecompilerOps::SPECIAL_JALR() +{ + if (m_NextInstruction == NORMAL) + { + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0) && (m_CompilePC & 0xFFC) != 0xFFC) + { + if (IsConst(m_Opcode.rs)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + else if (IsMapped(m_Opcode.rs)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + } + UnMap_GPR(m_Opcode.rd, false); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, m_CompilePC + 8); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + if ((m_CompilePC & 0xFFC) == 0xFFC) + { + if (IsMapped(m_Opcode.rs)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + m_RegWorkingSet.WriteBackRegisters(); + } + else + { + m_RegWorkingSet.WriteBackRegisters(); + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); + } + OverflowDelaySlot(true); + return; + } + + m_Section->m_Jump.FallThrough = false; + m_Section->m_Jump.LinkLocation = NULL; + m_Section->m_Jump.LinkLocation2 = NULL; + m_Section->m_Cont.FallThrough = false; + m_Section->m_Cont.LinkLocation = NULL; + m_Section->m_Cont.LinkLocation2 = NULL; + + m_NextInstruction = DO_DELAY_SLOT; + } + else if (m_NextInstruction == DELAY_SLOT_DONE) + { + if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) + { + m_Section->CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); + } + else + { + UpdateCounters(m_RegWorkingSet, true, true); + if (IsConst(m_Opcode.rs)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + else if (IsMapped(m_Opcode.rs)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + m_Section->CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); + if (m_Section->m_JumpSection) + { + m_Section->GenerateSectionLinkage(); + } + } + m_NextInstruction = END_BLOCK; + } + else if (bHaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); + } +} + +void CRecompilerOps::SPECIAL_SYSCALL() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::DoSysCall, true, NULL); + m_NextInstruction = END_BLOCK; +} + +void CRecompilerOps::SPECIAL_MFLO() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) { return; } + + Map_GPR_64bit(m_Opcode.rd, -1); + MoveVariableToX86reg(&_RegLO->UW[0], "_RegLO->UW[0]", GetMipsRegMapLo(m_Opcode.rd)); + MoveVariableToX86reg(&_RegLO->UW[1], "_RegLO->UW[1]", GetMipsRegMapHi(m_Opcode.rd)); +} + +void CRecompilerOps::SPECIAL_MTLO() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsKnown(m_Opcode.rs) && IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + MoveConstToVariable(GetMipsRegHi(m_Opcode.rs), &_RegLO->UW[1], "_RegLO->UW[1]"); + } + else if (IsSigned(m_Opcode.rs) && ((GetMipsRegLo(m_Opcode.rs) & 0x80000000) != 0)) + { + MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]"); + } + else + { + MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); + } + MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), &_RegLO->UW[0], "_RegLO->UW[0]"); + } + else if (IsKnown(m_Opcode.rs) && IsMapped(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + MoveX86regToVariable(GetMipsRegMapHi(m_Opcode.rs), &_RegLO->UW[1], "_RegLO->UW[1]"); + } + else if (IsSigned(m_Opcode.rs)) + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, true), &_RegLO->UW[1], "_RegLO->UW[1]"); + } + else + { + MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); + } + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &_RegLO->UW[0], "_RegLO->UW[0]"); + } + else + { + x86Reg reg = Map_TempReg(x86_Any, m_Opcode.rs, true); + MoveX86regToVariable(reg, &_RegLO->UW[1], "_RegLO->UW[1]"); + MoveX86regToVariable(Map_TempReg(reg, m_Opcode.rs, false), &_RegLO->UW[0], "_RegLO->UW[0]"); + } +} + +void CRecompilerOps::SPECIAL_MFHI() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) { return; } + + Map_GPR_64bit(m_Opcode.rd, -1); + MoveVariableToX86reg(&_RegHI->UW[0], "_RegHI->UW[0]", GetMipsRegMapLo(m_Opcode.rd)); + MoveVariableToX86reg(&_RegHI->UW[1], "_RegHI->UW[1]", GetMipsRegMapHi(m_Opcode.rd)); +} + +void CRecompilerOps::SPECIAL_MTHI() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsKnown(m_Opcode.rs) && IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + MoveConstToVariable(GetMipsRegHi(m_Opcode.rs), &_RegHI->UW[1], "_RegHI->UW[1]"); + } + else if (IsSigned(m_Opcode.rs) && ((GetMipsRegLo(m_Opcode.rs) & 0x80000000) != 0)) + { + MoveConstToVariable(0xFFFFFFFF, &_RegHI->UW[1], "_RegHI->UW[1]"); + } + else + { + MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); + } + MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), &_RegHI->UW[0], "_RegHI->UW[0]"); + } + else if (IsKnown(m_Opcode.rs) && IsMapped(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rs)) + { + MoveX86regToVariable(GetMipsRegMapHi(m_Opcode.rs), &_RegHI->UW[1], "_RegHI->UW[1]"); + } + else if (IsSigned(m_Opcode.rs)) + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, true), &_RegHI->UW[1], "_RegHI->UW[1]"); + } + else + { + MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); + } + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &_RegHI->UW[0], "_RegHI->UW[0]"); + } + else + { + x86Reg reg = Map_TempReg(x86_Any, m_Opcode.rs, true); + MoveX86regToVariable(reg, &_RegHI->UW[1], "_RegHI->UW[1]"); + MoveX86regToVariable(Map_TempReg(reg, m_Opcode.rs, false), &_RegHI->UW[0], "_RegHI->UW[0]"); + } +} + +void CRecompilerOps::SPECIAL_DSLLV() +{ + uint8_t * Jump[2]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rs)) + { + //uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x3F); + CRecompilerOps::UnknownOpcode(); + return; + } + Map_TempReg(x86_ECX, m_Opcode.rs, false); + AndConstToX86Reg(x86_ECX, 0x3F); + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + CompConstToX86reg(x86_ECX, 0x20); + JaeLabel8("MORE32", 0); + Jump[0] = m_RecompPos - 1; + ShiftLeftDouble(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); + ShiftLeftSign(GetMipsRegMapLo(m_Opcode.rd)); + JmpLabel8("continue", 0); + Jump[1] = m_RecompPos - 1; + + //MORE32: + CPU_Message(""); + CPU_Message(" MORE32:"); + SetJump8(Jump[0], m_RecompPos); + MoveX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); + XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); + AndConstToX86Reg(x86_ECX, 0x1F); + ShiftLeftSign(GetMipsRegMapHi(m_Opcode.rd)); + + //continue: + CPU_Message(""); + CPU_Message(" continue:"); + SetJump8(Jump[1], m_RecompPos); +} + +void CRecompilerOps::SPECIAL_DSRLV() +{ + uint8_t * Jump[2]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rs)) + { + uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x3F); + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt)); + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, GetMipsReg(m_Opcode.rd) >> Shift); + if ((GetMipsRegHi(m_Opcode.rd) == 0) && (GetMipsRegLo(m_Opcode.rd) & 0x80000000) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if ((GetMipsRegHi(m_Opcode.rd) == 0xFFFFFFFF) && (GetMipsRegLo(m_Opcode.rd) & 0x80000000) != 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + return; + } + if (m_Opcode.rd == m_Opcode.rt) + { + CRecompilerOps::UnknownOpcode(); + return; + } + + Map_TempReg(x86_ECX, -1, false); + MoveConstToX86reg(Shift, x86_ECX); + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + if ((Shift & 0x20) == 0x20) + { + MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); + XorX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); + AndConstToX86Reg(x86_ECX, 0x1F); + ShiftRightUnsign(GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + ShiftRightDouble(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); + ShiftRightUnsign(GetMipsRegMapHi(m_Opcode.rd)); + } + } + else + { + Map_TempReg(x86_ECX, m_Opcode.rs, false); + AndConstToX86Reg(x86_ECX, 0x3F); + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + CompConstToX86reg(x86_ECX, 0x20); + JaeLabel8("MORE32", 0); + Jump[0] = m_RecompPos - 1; + ShiftRightDouble(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); + ShiftRightUnsign(GetMipsRegMapHi(m_Opcode.rd)); + JmpLabel8("continue", 0); + Jump[1] = m_RecompPos - 1; + + //MORE32: + CPU_Message(""); + CPU_Message(" MORE32:"); + SetJump8(Jump[0], m_RecompPos); + MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); + XorX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); + AndConstToX86Reg(x86_ECX, 0x1F); + ShiftRightUnsign(GetMipsRegMapLo(m_Opcode.rd)); + + //continue: + CPU_Message(""); + CPU_Message(" continue:"); + SetJump8(Jump[1], m_RecompPos); + } +} + +void CRecompilerOps::SPECIAL_DSRAV() +{ + uint8_t * Jump[2]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rs)) + { + //uint32_t Shift = (GetMipsRegLo(m_Opcode.rs) & 0x3F); + CRecompilerOps::UnknownOpcode(); + return; + } + Map_TempReg(x86_ECX, m_Opcode.rs, false); + AndConstToX86Reg(x86_ECX, 0x3F); + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + CompConstToX86reg(x86_ECX, 0x20); + JaeLabel8("MORE32", 0); + Jump[0] = m_RecompPos - 1; + ShiftRightDouble(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd)); + ShiftRightSign(GetMipsRegMapHi(m_Opcode.rd)); + JmpLabel8("continue", 0); + Jump[1] = m_RecompPos - 1; + + //MORE32: + CPU_Message(""); + CPU_Message(" MORE32:"); + SetJump8(Jump[0], m_RecompPos); + MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); + ShiftRightSignImmed(GetMipsRegMapHi(m_Opcode.rd), 0x1F); + AndConstToX86Reg(x86_ECX, 0x1F); + ShiftRightSign(GetMipsRegMapLo(m_Opcode.rd)); + + //continue: + CPU_Message(""); + CPU_Message(" continue:"); + SetJump8(Jump[1], m_RecompPos); +} + +void CRecompilerOps::SPECIAL_MULT() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_RegWorkingSet.SetX86Protected(x86_EDX, true); + Map_TempReg(x86_EAX, m_Opcode.rs, false); + m_RegWorkingSet.SetX86Protected(x86_EDX, false); + Map_TempReg(x86_EDX, m_Opcode.rt, false); + + imulX86reg(x86_EDX); + + MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); + ShiftRightSignImmed(x86_EAX, 31); /* paired */ + ShiftRightSignImmed(x86_EDX, 31); + MoveX86regToVariable(x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); +} + +void CRecompilerOps::SPECIAL_MULTU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_RegWorkingSet.SetX86Protected(x86_EDX, true); + Map_TempReg(x86_EAX, m_Opcode.rs, false); + m_RegWorkingSet.SetX86Protected(x86_EDX, false); + Map_TempReg(x86_EDX, m_Opcode.rt, false); + + MulX86reg(x86_EDX); + + MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); + ShiftRightSignImmed(x86_EAX, 31); /* paired */ + ShiftRightSignImmed(x86_EDX, 31); + MoveX86regToVariable(x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); +} + +void CRecompilerOps::SPECIAL_DIV() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsConst(m_Opcode.rt)) + { + if (GetMipsRegLo(m_Opcode.rt) == 0) + { + MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]"); + MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); + MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]"); + MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); + return; + } + } + else + { + if (IsMapped(m_Opcode.rt)) + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), 0); + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + } + m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::DivByZero, false, JeLabel32); + } + /* lo = (SD)rs / (SD)rt; + hi = (SD)rs % (SD)rt; */ + + m_RegWorkingSet.SetX86Protected(x86_EDX, true); + Map_TempReg(x86_EAX, m_Opcode.rs, false); + + /* edx is the signed portion to eax */ + m_RegWorkingSet.SetX86Protected(x86_EDX, false); + Map_TempReg(x86_EDX, -1, false); + + MoveX86RegToX86Reg(x86_EAX, x86_EDX); + ShiftRightSignImmed(x86_EDX, 31); + + if (IsMapped(m_Opcode.rt)) + { + idivX86reg(GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + idivX86reg(Map_TempReg(x86_Any, m_Opcode.rt, false)); + } + + MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); + ShiftRightSignImmed(x86_EAX, 31); /* paired */ + ShiftRightSignImmed(x86_EDX, 31); + MoveX86regToVariable(x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); +} + +void CRecompilerOps::SPECIAL_DIVU() +{ + uint8_t *Jump[2]; + x86Reg Reg; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsConst(m_Opcode.rt)) + { + if (GetMipsRegLo(m_Opcode.rt) == 0) + { + MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]"); + MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); + MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]"); + MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); + return; + } + Jump[1] = NULL; + } + else + { + if (IsMapped(m_Opcode.rt)) + { + CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), 0); + } + else + { + CompConstToVariable(0, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + } + JneLabel8("NoExcept", 0); + Jump[0] = m_RecompPos - 1; + + MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]"); + MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]"); + MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]"); + MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]"); + + JmpLabel8("EndDivu", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" NoExcept:"); + SetJump8(Jump[0], m_RecompPos); + } + + /* lo = (UD)rs / (UD)rt; + hi = (UD)rs % (UD)rt; */ + + m_RegWorkingSet.SetX86Protected(x86_EAX, true); + Map_TempReg(x86_EDX, 0, false); + m_RegWorkingSet.SetX86Protected(x86_EAX, false); + + Map_TempReg(x86_EAX, m_Opcode.rs, false); + Reg = Map_TempReg(x86_Any, m_Opcode.rt, false); + + DivX86reg(Reg); + + MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); + + /* wouldnt these be zero (???) */ + + ShiftRightSignImmed(x86_EAX, 31); /* paired */ + ShiftRightSignImmed(x86_EDX, 31); + MoveX86regToVariable(x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); + + if (Jump[1] != NULL) + { + CPU_Message(""); + CPU_Message(" EndDivu:"); + SetJump8(Jump[1], m_RecompPos); + } +} + +void CRecompilerOps::SPECIAL_DMULT() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rs != 0) + { + UnMap_GPR(m_Opcode.rs, true); + } + + if (m_Opcode.rs != 0) + { + UnMap_GPR(m_Opcode.rt, true); + } + + BeforeCallDirect(m_RegWorkingSet); + MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); + Call_Direct((void *)R4300iOp::SPECIAL_DMULT, "R4300iOp::SPECIAL_DMULT"); + AfterCallDirect(m_RegWorkingSet); +} + +void CRecompilerOps::SPECIAL_DMULTU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + UnMap_GPR(m_Opcode.rs, true); + UnMap_GPR(m_Opcode.rt, true); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); + Call_Direct((void *)R4300iOp::SPECIAL_DMULTU, "R4300iOp::SPECIAL_DMULTU"); + AfterCallDirect(m_RegWorkingSet); + +#ifdef toremove + /* _RegLO->UDW = (uint64)_GPR[m_Opcode.rs].UW[0] * (uint64)_GPR[m_Opcode.rt].UW[0]; */ + X86Protected(x86_EDX) = true; + Map_TempReg(x86_EAX, m_Opcode.rs, false); + X86Protected(x86_EDX) = false; + Map_TempReg(x86_EDX, m_Opcode.rt, false); + + MulX86reg(x86_EDX); + MoveX86regToVariable(x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]"); + MoveX86regToVariable(x86_EDX, &_RegLO->UW[1], "_RegLO->UW[1]"); + + /* _RegHI->UDW = (uint64)_GPR[m_Opcode.rs].UW[1] * (uint64)_GPR[m_Opcode.rt].UW[1]; */ + Map_TempReg(x86_EAX, m_Opcode.rs, true); + Map_TempReg(x86_EDX, m_Opcode.rt, true); + + MulX86reg(x86_EDX); + MoveX86regToVariable(x86_EAX, &_RegHI->UW[0], "_RegHI->UW[0]"); + MoveX86regToVariable(x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]"); + + /* Tmp[0].UDW = (uint64)_GPR[m_Opcode.rs].UW[1] * (uint64)_GPR[m_Opcode.rt].UW[0]; */ + Map_TempReg(x86_EAX, m_Opcode.rs, true); + Map_TempReg(x86_EDX, m_Opcode.rt, false); + + Map_TempReg(x86_EBX, -1, false); + Map_TempReg(x86_ECX, -1, false); + + MulX86reg(x86_EDX); + MoveX86RegToX86Reg(x86_EAX, x86_EBX); /* EDX:EAX -> ECX:EBX */ + MoveX86RegToX86Reg(x86_EDX, x86_ECX); + + /* Tmp[1].UDW = (uint64)_GPR[m_Opcode.rs].UW[0] * (uint64)_GPR[m_Opcode.rt].UW[1]; */ + Map_TempReg(x86_EAX, m_Opcode.rs, false); + Map_TempReg(x86_EDX, m_Opcode.rt, true); + + MulX86reg(x86_EDX); + Map_TempReg(x86_ESI, -1, false); + Map_TempReg(x86_EDI, -1, false); + MoveX86RegToX86Reg(x86_EAX, x86_ESI); /* EDX:EAX -> EDI:ESI */ + MoveX86RegToX86Reg(x86_EDX, x86_EDI); + + /* Tmp[2].UDW = (uint64)_RegLO->UW[1] + (uint64)Tmp[0].UW[0] + (uint64)Tmp[1].UW[0]; */ + XorX86RegToX86Reg(x86_EDX, x86_EDX); + MoveVariableToX86reg(&_RegLO->UW[1], "_RegLO->UW[1]", x86_EAX); + AddX86RegToX86Reg(x86_EAX, x86_EBX); + AddConstToX86Reg(x86_EDX, 0); + AddX86RegToX86Reg(x86_EAX, x86_ESI); + AddConstToX86Reg(x86_EDX, 0); /* EDX:EAX */ + + /* _RegLO->UDW += ((uint64)Tmp[0].UW[0] + (uint64)Tmp[1].UW[0]) << 32; */ + /* [low+4] += ebx + esi */ + + AddX86regToVariable(x86_EBX, &_RegLO->UW[1], "_RegLO->UW[1]"); + AddX86regToVariable(x86_ESI, &_RegLO->UW[1], "_RegLO->UW[1]"); + + /* _RegHI->UDW += (uint64)Tmp[0].UW[1] + (uint64)Tmp[1].UW[1] + Tmp[2].UW[1]; */ + /* [hi] += ecx + edi + edx */ + + AddX86regToVariable(x86_ECX, &_RegHI->UW[0], "_RegHI->UW[0]"); + AdcConstToVariable(&_RegHI->UW[1], "_RegHI->UW[1]", 0); + + AddX86regToVariable(x86_EDI, &_RegHI->UW[0], "_RegHI->UW[0]"); + AdcConstToVariable(&_RegHI->UW[1], "_RegHI->UW[1]", 0); + + AddX86regToVariable(x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]"); + AdcConstToVariable(&_RegHI->UW[1], "_RegHI->UW[1]", 0); +#endif +} + +void CRecompilerOps::SPECIAL_DDIV() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + UnMap_GPR(m_Opcode.rs, true); + UnMap_GPR(m_Opcode.rt, true); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); + Call_Direct((void *)R4300iOp::SPECIAL_DDIV, "R4300iOp::SPECIAL_DDIV"); + AfterCallDirect(m_RegWorkingSet); +} + +void CRecompilerOps::SPECIAL_DDIVU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + UnMap_GPR(m_Opcode.rs, true); + UnMap_GPR(m_Opcode.rt, true); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); + Call_Direct((void *)R4300iOp::SPECIAL_DDIVU, "R4300iOp::SPECIAL_DDIVU"); + AfterCallDirect(m_RegWorkingSet); +} + +void CRecompilerOps::SPECIAL_ADD() +{ + int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; + int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(source1) && IsConst(source2)) + { + uint32_t temp = GetMipsRegLo(source1) + GetMipsRegLo(source2); + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, temp); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + return; + } + + Map_GPR_32bit(m_Opcode.rd, true, source1); + if (IsConst(source2)) + { + AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(source2)); + } + else if (IsKnown(source2) && IsMapped(source2)) + { + AddX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + else + { + AddVariableToX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[source2].W[0], CRegName::GPR_Lo[source2]); + } + if (g_System->bFastSP() && m_Opcode.rd == 29) + { + g_MMU->ResetMemoryStack(); + } +} + +void CRecompilerOps::SPECIAL_ADDU() +{ + int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; + int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(source1) && IsConst(source2)) + { + uint32_t temp = GetMipsRegLo(source1) + GetMipsRegLo(source2); + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, temp); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + return; + } + + Map_GPR_32bit(m_Opcode.rd, true, source1); + if (IsConst(source2)) + { + AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(source2)); + } + else if (IsKnown(source2) && IsMapped(source2)) + { + AddX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + else + { + AddVariableToX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[source2].W[0], CRegName::GPR_Lo[source2]); + } + if (g_System->bFastSP() && m_Opcode.rd == 29) + { + g_MMU->ResetMemoryStack(); + } +} + +void CRecompilerOps::SPECIAL_SUB() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + uint32_t temp = GetMipsRegLo(m_Opcode.rs) - GetMipsRegLo(m_Opcode.rt); + + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, temp); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + if (m_Opcode.rd == m_Opcode.rt) + { + x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rt, false); + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rs); + SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Reg); + return; + } + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rs); + if (IsConst(m_Opcode.rt)) + { + SubConstFromX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(m_Opcode.rt)); + } + else if (IsMapped(m_Opcode.rt)) + { + SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + SubVariableFromX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + } + } + if (g_System->bFastSP() && m_Opcode.rd == 29) + { + g_MMU->ResetMemoryStack(); + } +} + +void CRecompilerOps::SPECIAL_SUBU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + uint32_t temp = GetMipsRegLo(m_Opcode.rs) - GetMipsRegLo(m_Opcode.rt); + + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, temp); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + if (m_Opcode.rd == m_Opcode.rt) + { + x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rt, false); + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rs); + SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Reg); + return; + } + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rs); + if (IsConst(m_Opcode.rt)) + { + SubConstFromX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(m_Opcode.rt)); + } + else if (IsMapped(m_Opcode.rt)) + { + SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt)); + } + else + { + SubVariableFromX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + } + } + + if (g_System->bFastSP() && m_Opcode.rd == 29) + { + g_MMU->ResetMemoryStack(); + } +} + +void CRecompilerOps::SPECIAL_AND() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) + { + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, + (Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt)) & + (Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs)) + ); + + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + } + else + { + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) & GetMipsReg(m_Opcode.rs)); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + } + else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) + { + int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; + int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; + + ProtectGPR(source1); + ProtectGPR(source2); + if (Is32Bit(source1) && Is32Bit(source2)) + { + bool Sign = (IsSigned(m_Opcode.rt) && IsSigned(m_Opcode.rs)); + Map_GPR_32bit(m_Opcode.rd, Sign, source1); + AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + else if (Is32Bit(source1) || Is32Bit(source2)) + { + if (IsUnsigned(Is32Bit(source1) ? source1 : source2)) + { + Map_GPR_32bit(m_Opcode.rd, false, source1); + AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + else + { + Map_GPR_64bit(m_Opcode.rd, source1); + if (Is32Bit(source2)) + { + AndX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), Map_TempReg(x86_Any, source2, true)); + } + else + { + AndX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); + } + AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + } + else + { + Map_GPR_64bit(m_Opcode.rd, source1); + AndX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); + AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + } + else + { + int ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + int MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (Is64Bit(ConstReg)) + { + if (Is32Bit(MappedReg) && IsUnsigned(MappedReg)) + { + if (GetMipsRegLo(ConstReg) == 0) + { + Map_GPR_32bit(m_Opcode.rd, false, 0); + } + else + { + uint32_t Value = GetMipsRegLo(ConstReg); + Map_GPR_32bit(m_Opcode.rd, false, MappedReg); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); + } + } + else + { + int64_t Value = GetMipsReg(ConstReg); + Map_GPR_64bit(m_Opcode.rd, MappedReg); + AndConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), (uint32_t)(Value >> 32)); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), (uint32_t)(Value & 0xFFFFFFFF)); + } + } + else if (Is64Bit(MappedReg)) + { + uint32_t Value = GetMipsRegLo(ConstReg); + if (Value != 0) + { + Map_GPR_32bit(m_Opcode.rd, IsSigned(ConstReg), MappedReg); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); + } + else + { + Map_GPR_32bit(m_Opcode.rd, IsSigned(ConstReg), 0); + } + } + else + { + uint32_t Value = GetMipsRegLo(ConstReg); + bool Sign = false; + + if (IsSigned(ConstReg) && IsSigned(MappedReg)) + { + Sign = true; + } + + if (Value != 0) + { + Map_GPR_32bit(m_Opcode.rd, Sign, MappedReg); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); + } + else + { + Map_GPR_32bit(m_Opcode.rd, false, 0); + } + } + } + } + else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) + { + uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (IsConst(KnownReg)) + { + if (Is64Bit(KnownReg)) + { + uint64_t Value = GetMipsReg(KnownReg); + Map_GPR_64bit(m_Opcode.rd, UnknownReg); + AndConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), (uint32_t)(Value >> 32)); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), (uint32_t)(Value & 0xFFFFFFFF)); + } + else + { + uint32_t Value = GetMipsRegLo(KnownReg); + Map_GPR_32bit(m_Opcode.rd, IsSigned(KnownReg), UnknownReg); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); + } + } + else + { + ProtectGPR(KnownReg); + if (KnownReg == m_Opcode.rd) + { + if (Is64Bit(KnownReg) || !g_System->b32BitCore()) + { + Map_GPR_64bit(m_Opcode.rd, KnownReg); + AndVariableToX86Reg(&_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg], GetMipsRegMapHi(m_Opcode.rd)); + AndVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_32bit(m_Opcode.rd, IsSigned(KnownReg), KnownReg); + AndVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); + } + } + else + { + if (Is64Bit(KnownReg)) + { + Map_GPR_64bit(m_Opcode.rd, UnknownReg); + AndX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(KnownReg)); + AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(KnownReg)); + } + else + { + Map_GPR_32bit(m_Opcode.rd, IsSigned(KnownReg), UnknownReg); + AndX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(KnownReg)); + } + } + } + } + else + { + if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + } + else + { + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + AndVariableToX86Reg(&_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs], GetMipsRegMapHi(m_Opcode.rd)); + } + AndVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); + } +} + +void CRecompilerOps::SPECIAL_OR() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) + { + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, + (Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt)) | + (Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs)) + ); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + } + else + { + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) | GetMipsRegLo(m_Opcode.rs)); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + } + else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) + { + int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; + int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; + + ProtectGPR(m_Opcode.rt); + ProtectGPR(m_Opcode.rs); + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + Map_GPR_64bit(m_Opcode.rd, source1); + if (Is64Bit(source2)) + { + OrX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); + } + else + { + OrX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), Map_TempReg(x86_Any, source2, true)); + } + } + else + { + ProtectGPR(source2); + Map_GPR_32bit(m_Opcode.rd, true, source1); + } + OrX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + else + { + uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + uint64_t Value; + + if (Is64Bit(ConstReg)) + { + Value = GetMipsReg(ConstReg); + } + else + { + Value = IsSigned(ConstReg) ? (int64_t)GetMipsRegLo_S(ConstReg) : GetMipsRegLo(ConstReg); + } + Map_GPR_64bit(m_Opcode.rd, MappedReg); + if ((Value >> 32) != 0) + { + OrConstToX86Reg((uint32_t)(Value >> 32), GetMipsRegMapHi(m_Opcode.rd)); + } + uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); + if (dwValue != 0) + { + OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); + } + } + else + { + int Value = GetMipsRegLo(ConstReg); + Map_GPR_32bit(m_Opcode.rd, true, MappedReg); + if (Value != 0) { OrConstToX86Reg(Value, GetMipsRegMapLo(m_Opcode.rd)); } + } + } + } + else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) + { + int KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + int UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (IsConst(KnownReg)) + { + uint64_t Value = Is64Bit(KnownReg) ? GetMipsReg(KnownReg) : GetMipsRegLo_S(KnownReg); + uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); + + if (g_System->b32BitCore() && Is32Bit(KnownReg)) + { + Map_GPR_32bit(m_Opcode.rd, true, UnknownReg); + if (dwValue != 0) + { + OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); + } + } + else + { + Map_GPR_64bit(m_Opcode.rd, UnknownReg); + if ((Value >> 32) != 0) + { + OrConstToX86Reg((uint32_t)(Value >> 32), GetMipsRegMapHi(m_Opcode.rd)); + } + if (dwValue != 0) + { + OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); + } + } + } + else + { + if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rd, true, KnownReg); + OrVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_64bit(m_Opcode.rd, KnownReg); + OrVariableToX86Reg(&_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg], GetMipsRegMapHi(m_Opcode.rd)); + OrVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); + } + } + } + else + { + if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs], GetMipsRegMapHi(m_Opcode.rd)); + OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); + } + } + if (g_System->bFastSP() && m_Opcode.rd == 29) + { + ResetX86Protection(); + g_MMU->ResetMemoryStack(); + } +} + +void CRecompilerOps::SPECIAL_XOR() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + return; + + if (m_Opcode.rt == m_Opcode.rs) + { + UnMap_GPR(m_Opcode.rd, false); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 0); + return; + } + if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) + { + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + if (bHaveDebugger()) { g_Notify->DisplayError("XOR 1"); } + CRecompilerOps::UnknownOpcode(); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) ^ GetMipsRegLo(m_Opcode.rs)); + } + } + else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) + { + int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; + int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; + + ProtectGPR(source1); + ProtectGPR(source2); + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + Map_GPR_64bit(m_Opcode.rd, source1); + if (Is64Bit(source2)) + { + XorX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); + } + else if (IsSigned(source2)) + { + XorX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), Map_TempReg(x86_Any, source2, true)); + } + XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + else + { + if (IsSigned(m_Opcode.rt) != IsSigned(m_Opcode.rs)) + { + Map_GPR_32bit(m_Opcode.rd, true, source1); + } + else + { + Map_GPR_32bit(m_Opcode.rd, IsSigned(m_Opcode.rt), source1); + } + XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + } + else + { + uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + uint32_t ConstHi, ConstLo; + + ConstHi = Is32Bit(ConstReg) ? (uint32_t)(GetMipsRegLo_S(ConstReg) >> 31) : GetMipsRegHi(ConstReg); + ConstLo = GetMipsRegLo(ConstReg); + Map_GPR_64bit(m_Opcode.rd, MappedReg); + if (ConstHi != 0) { XorConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), ConstHi); } + if (ConstLo != 0) { XorConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), ConstLo); } + } + else + { + int Value = GetMipsRegLo(ConstReg); + if (IsSigned(m_Opcode.rt) != IsSigned(m_Opcode.rs)) + { + Map_GPR_32bit(m_Opcode.rd, true, MappedReg); + } + else + { + Map_GPR_32bit(m_Opcode.rd, IsSigned(MappedReg), MappedReg); + } + if (Value != 0) { XorConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), Value); } + } + } + } + else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) + { + int KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + int UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (IsConst(KnownReg)) + { + uint64_t Value; + + if (Is64Bit(KnownReg)) + { + Value = GetMipsReg(KnownReg); + Map_GPR_64bit(m_Opcode.rd, UnknownReg); + if ((Value >> 32) != 0) + { + XorConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), (uint32_t)(Value >> 32)); + } + } + else + { + Map_GPR_32bit(m_Opcode.rd, true, UnknownReg); + if (IsSigned(KnownReg)) + { + Value = (int)GetMipsRegLo(KnownReg); + } + else + { + Value = GetMipsRegLo(KnownReg); + } + } + uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); + if (dwValue != 0) + { + XorConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), dwValue); + } + } + else + { + if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rd, true, KnownReg); + XorVariableToX86reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_64bit(m_Opcode.rd, KnownReg); + XorVariableToX86reg(&_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg], GetMipsRegMapHi(m_Opcode.rd)); + XorVariableToX86reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); + } + } + } + else if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + XorVariableToX86reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + XorVariableToX86reg(&_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs], GetMipsRegMapHi(m_Opcode.rd)); + XorVariableToX86reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); + } +} + +void CRecompilerOps::SPECIAL_NOR() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) + { + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rd)) + UnMap_GPR(m_Opcode.rd, false); + + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, + ~((Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt)) | + (Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs))) + ); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + } + else + { + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, ~(GetMipsRegLo(m_Opcode.rt) | GetMipsRegLo(m_Opcode.rs))); + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + } + else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) + { + int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; + int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; + + ProtectGPR(m_Opcode.rt); + ProtectGPR(m_Opcode.rs); + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + Map_GPR_64bit(m_Opcode.rd, source1); + if (Is64Bit(source2)) + { + OrX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapHi(source2)); + } + else + { + OrX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), Map_TempReg(x86_Any, source2, true)); + } + } + else + { + ProtectGPR(source2); + Map_GPR_32bit(m_Opcode.rd, true, source1); + } + OrX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + } + else + { + uint32_t ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + uint64_t Value; + + if (Is64Bit(ConstReg)) + { + Value = GetMipsReg(ConstReg); + } + else + { + Value = IsSigned(ConstReg) ? (int64_t)GetMipsRegLo_S(ConstReg) : GetMipsRegLo(ConstReg); + } + Map_GPR_64bit(m_Opcode.rd, MappedReg); + if ((Value >> 32) != 0) + { + OrConstToX86Reg((uint32_t)(Value >> 32), GetMipsRegMapHi(m_Opcode.rd)); + } + uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); + if (dwValue != 0) { + OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); + } + } + else + { + int Value = GetMipsRegLo(ConstReg); + Map_GPR_32bit(m_Opcode.rd, true, MappedReg); + if (Value != 0) { OrConstToX86Reg(Value, GetMipsRegMapLo(m_Opcode.rd)); } + } + } + } + else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) + { + int KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + int UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + if (IsConst(KnownReg)) + { + uint64_t Value = Is64Bit(KnownReg) ? GetMipsReg(KnownReg) : GetMipsRegLo_S(KnownReg); + uint32_t dwValue = (uint32_t)(Value & 0xFFFFFFFF); + + if (g_System->b32BitCore() && Is32Bit(KnownReg)) + { + Map_GPR_32bit(m_Opcode.rd, true, UnknownReg); + if (dwValue != 0) + { + OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); + } + } + else + { + Map_GPR_64bit(m_Opcode.rd, UnknownReg); + if ((Value >> 32) != 0) + { + OrConstToX86Reg((uint32_t)(Value >> 32), GetMipsRegMapHi(m_Opcode.rd)); + } + if (dwValue != 0) + { + OrConstToX86Reg(dwValue, GetMipsRegMapLo(m_Opcode.rd)); + } + } + } + else + { + if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rd, true, KnownReg); + OrVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_64bit(m_Opcode.rd, KnownReg); + OrVariableToX86Reg(&_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg], GetMipsRegMapHi(m_Opcode.rd)); + OrVariableToX86Reg(&_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg], GetMipsRegMapLo(m_Opcode.rd)); + } + } + } + else + { + if (g_System->b32BitCore()) + { + Map_GPR_32bit(m_Opcode.rd, true, m_Opcode.rt); + OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[1], CRegName::GPR_Hi[m_Opcode.rs], GetMipsRegMapHi(m_Opcode.rd)); + OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0], CRegName::GPR_Lo[m_Opcode.rs], GetMipsRegMapLo(m_Opcode.rd)); + } + } + + if (IsMapped(m_Opcode.rd)) + { + if (Is64Bit(m_Opcode.rd)) + { + NotX86Reg(GetMipsRegMapHi(m_Opcode.rd)); + } + NotX86Reg(GetMipsRegMapLo(m_Opcode.rd)); + } +} + +void CRecompilerOps::SPECIAL_SLT() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) + { + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + g_Notify->DisplayError("1"); + CRecompilerOps::UnknownOpcode(); + } + else + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + if (GetMipsRegLo_S(m_Opcode.rs) < GetMipsRegLo_S(m_Opcode.rt)) + { + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 1); + } + else + { + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 0); + } + } + } + else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) + { + ProtectGPR(m_Opcode.rt); + ProtectGPR(m_Opcode.rs); + if ((Is64Bit(m_Opcode.rt) && Is64Bit(m_Opcode.rs)) || + (!g_System->b32BitCore() && (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)))) + { + uint8_t *Jump[2]; + + CompX86RegToX86Reg( + Is64Bit(m_Opcode.rs) ? GetMipsRegMapHi(m_Opcode.rs) : Map_TempReg(x86_Any, m_Opcode.rs, true), + Is64Bit(m_Opcode.rt) ? GetMipsRegMapHi(m_Opcode.rt) : Map_TempReg(x86_Any, m_Opcode.rt, true) + ); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_32bit(m_Opcode.rd, true, -1); + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + + if (GetMipsRegMapLo(m_Opcode.rd) > x86_EBX) + { + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Setl(GetMipsRegMapLo(m_Opcode.rd)); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), 1); + } + } + } + else + { + uint32_t ConstReg = IsConst(m_Opcode.rs) ? m_Opcode.rs : m_Opcode.rt; + uint32_t MappedReg = IsConst(m_Opcode.rs) ? m_Opcode.rt : m_Opcode.rs; + + ProtectGPR(MappedReg); + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + uint8_t *Jump[2]; + + CompConstToX86reg( + Is64Bit(MappedReg) ? GetMipsRegMapHi(MappedReg) : Map_TempReg(x86_Any, MappedReg, true), + Is64Bit(ConstReg) ? GetMipsRegHi(ConstReg) : (GetMipsRegLo_S(ConstReg) >> 31) + ); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + if (MappedReg == m_Opcode.rs) + { + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetgVariable(&m_BranchCompare, "m_BranchCompare"); + } + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompConstToX86reg(GetMipsRegMapLo(MappedReg), GetMipsRegLo(ConstReg)); + if (MappedReg == m_Opcode.rs) + { + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetaVariable(&m_BranchCompare, "m_BranchCompare"); + } + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + uint32_t Constant = GetMipsRegLo(ConstReg); + Map_GPR_32bit(m_Opcode.rd, true, -1); + CompConstToX86reg(GetMipsRegMapLo(MappedReg), Constant); + + if (GetMipsRegMapLo(m_Opcode.rd) > x86_EBX) + { + if (MappedReg == m_Opcode.rs) + { + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetgVariable(&m_BranchCompare, "m_BranchCompare"); + } + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + if (MappedReg == m_Opcode.rs) + { + Setl(GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Setg(GetMipsRegMapLo(m_Opcode.rd)); + } + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), 1); + } + } + } + } + else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) + { + uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + uint8_t *Jump[2]; + + if (!g_System->b32BitCore()) + { + if (Is64Bit(KnownReg)) + { + if (IsConst(KnownReg)) + { + CompConstToVariable(GetMipsRegHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else + { + CompX86regToVariable(GetMipsRegMapHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + } + else + { + if (IsConst(KnownReg)) + { + CompConstToVariable((GetMipsRegLo_S(KnownReg) >> 31), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else + { + ProtectGPR(KnownReg); + CompX86regToVariable(Map_TempReg(x86_Any, KnownReg, true), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + } + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + if (KnownReg == (IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt)) + { + SetgVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + } + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + if (IsConst(KnownReg)) + { + CompConstToVariable(GetMipsRegLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + else + { + CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + if (KnownReg == (IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt)) { + SetaVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + } + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + if (IsMapped(KnownReg)) + { + ProtectGPR(KnownReg); + } + bool bConstant = IsConst(KnownReg); + uint32_t Value = IsConst(KnownReg) ? GetMipsRegLo(KnownReg) : 0; + + Map_GPR_32bit(m_Opcode.rd, true, -1); + if (bConstant) + { + CompConstToVariable(Value, &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + else + { + CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + if (GetMipsRegMapLo(m_Opcode.rd) > x86_EBX) + { + if (KnownReg == (bConstant ? m_Opcode.rs : m_Opcode.rt)) + { + SetgVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + } + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + if (KnownReg == (bConstant ? m_Opcode.rs : m_Opcode.rt)) + { + Setg(GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Setl(GetMipsRegMapLo(m_Opcode.rd)); + } + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), 1); + } + } + } + else if (g_System->b32BitCore()) + { + x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rs, false); + Map_GPR_32bit(m_Opcode.rd, false, -1); + CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + if (GetMipsRegMapLo(m_Opcode.rd) > x86_EBX) + { + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Setl(GetMipsRegMapLo(m_Opcode.rd)); + AndConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), 1); + } + } + else + { + uint8_t *Jump[2] = { NULL, NULL }; + + x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rs, true); + CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + SetlVariable(&m_BranchCompare, "m_BranchCompare"); + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompX86regToVariable(Map_TempReg(Reg, m_Opcode.rs, false), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + if (Jump[1]) + { + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + } + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } +} + +void CRecompilerOps::SPECIAL_SLTU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsKnown(m_Opcode.rt) && IsKnown(m_Opcode.rs)) + { + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + g_Notify->DisplayError("1"); + CRecompilerOps::UnknownOpcode(); + } + else + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + if (GetMipsRegLo(m_Opcode.rs) < GetMipsRegLo(m_Opcode.rt)) + { + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 1); + } + else + { + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 0); + } + } + } + else if (IsMapped(m_Opcode.rt) && IsMapped(m_Opcode.rs)) + { + ProtectGPR(m_Opcode.rt); + ProtectGPR(m_Opcode.rs); + if ((Is64Bit(m_Opcode.rt) && Is64Bit(m_Opcode.rs)) || + (!g_System->b32BitCore() && (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)))) + { + uint8_t *Jump[2]; + + CompX86RegToX86Reg( + Is64Bit(m_Opcode.rs) ? GetMipsRegMapHi(m_Opcode.rs) : Map_TempReg(x86_Any, m_Opcode.rs, true), + Is64Bit(m_Opcode.rt) ? GetMipsRegMapHi(m_Opcode.rt) : Map_TempReg(x86_Any, m_Opcode.rt, true) + ); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + CompX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rs), GetMipsRegMapLo(m_Opcode.rt)); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + } + else + { + if (Is64Bit(m_Opcode.rt) || Is64Bit(m_Opcode.rs)) + { + uint32_t ConstHi, ConstLo, ConstReg, MappedReg; + x86Reg MappedRegHi, MappedRegLo; + uint8_t *Jump[2]; + + ConstReg = IsConst(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + ConstLo = GetMipsRegLo_S(ConstReg); + ConstHi = GetMipsRegLo_S(ConstReg) >> 31; + if (Is64Bit(ConstReg)) { ConstHi = GetMipsRegHi(ConstReg); } + + ProtectGPR(MappedReg); + MappedRegLo = GetMipsRegMapLo(MappedReg); + MappedRegHi = GetMipsRegMapHi(MappedReg); + if (Is32Bit(MappedReg)) + { + MappedRegHi = Map_TempReg(x86_Any, MappedReg, true); + } + + Map_GPR_32bit(m_Opcode.rd, true, -1); + CompConstToX86reg(MappedRegHi, ConstHi); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + if (MappedReg == m_Opcode.rs) + { + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetaVariable(&m_BranchCompare, "m_BranchCompare"); + } + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompConstToX86reg(MappedRegLo, ConstLo); + if (MappedReg == m_Opcode.rs) + { + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetaVariable(&m_BranchCompare, "m_BranchCompare"); + } + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + uint32_t Const = IsConst(m_Opcode.rs) ? GetMipsRegLo(m_Opcode.rs) : GetMipsRegLo(m_Opcode.rt); + uint32_t MappedReg = IsConst(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + + CompConstToX86reg(GetMipsRegMapLo(MappedReg), Const); + if (MappedReg == m_Opcode.rs) + { + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetaVariable(&m_BranchCompare, "m_BranchCompare"); + } + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + } + } + else if (IsKnown(m_Opcode.rt) || IsKnown(m_Opcode.rs)) + { + uint32_t KnownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rt : m_Opcode.rs; + uint32_t UnknownReg = IsKnown(m_Opcode.rt) ? m_Opcode.rs : m_Opcode.rt; + uint8_t *Jump[2] = { NULL, NULL }; + + ProtectGPR(KnownReg); + if (g_System->b32BitCore()) + { + uint32_t TestReg = IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt; + if (IsConst(KnownReg)) + { + uint32_t Value = GetMipsRegLo(KnownReg); + Map_GPR_32bit(m_Opcode.rd, true, -1); + CompConstToVariable(Value, &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + else + { + CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + if (KnownReg == TestReg) + { + SetaVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + } + } + else + { + if (IsConst(KnownReg)) + { + if (Is64Bit(KnownReg)) + { + CompConstToVariable(GetMipsRegHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else + { + CompConstToVariable((GetMipsRegLo_S(KnownReg) >> 31), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + } + else + { + if (Is64Bit(KnownReg)) + { + CompX86regToVariable(GetMipsRegMapHi(KnownReg), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + else + { + ProtectGPR(KnownReg); + CompX86regToVariable(Map_TempReg(x86_Any, KnownReg, true), &_GPR[UnknownReg].W[1], CRegName::GPR_Hi[UnknownReg]); + } + } + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + + if (KnownReg == (IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt)) + { + SetaVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + } + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + if (IsConst(KnownReg)) + { + CompConstToVariable(GetMipsRegLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + else + { + CompX86regToVariable(GetMipsRegMapLo(KnownReg), &_GPR[UnknownReg].W[0], CRegName::GPR_Lo[UnknownReg]); + } + if (KnownReg == (IsConst(KnownReg) ? m_Opcode.rs : m_Opcode.rt)) + { + SetaVariable(&m_BranchCompare, "m_BranchCompare"); + } + else + { + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + } + if (Jump[1]) + { + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + } + } + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else if (g_System->b32BitCore()) + { + x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rs, false); + Map_GPR_32bit(m_Opcode.rd, false, -1); + CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + uint8_t *Jump[2] = { NULL, NULL }; + + x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rs, true); + CompX86regToVariable(Reg, &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); + JeLabel8("Low Compare", 0); + Jump[0] = m_RecompPos - 1; + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + JmpLabel8("Continue", 0); + Jump[1] = m_RecompPos - 1; + + CPU_Message(""); + CPU_Message(" Low Compare:"); + SetJump8(Jump[0], m_RecompPos); + CompX86regToVariable(Map_TempReg(Reg, m_Opcode.rs, false), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + SetbVariable(&m_BranchCompare, "m_BranchCompare"); + if (Jump[1]) + { + CPU_Message(""); + CPU_Message(" Continue:"); + SetJump8(Jump[1], m_RecompPos); + } + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&m_BranchCompare, "m_BranchCompare", GetMipsRegMapLo(m_Opcode.rd)); + } +} + +void CRecompilerOps::SPECIAL_DADD() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, + Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs) + + Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt) + ); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + } + else + { + int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; + int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; + + if (IsMapped(source2)) { ProtectGPR(source2); } + Map_GPR_64bit(m_Opcode.rd, source1); + if (IsConst(source2)) + { + AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(source2)); + AddConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(source2)); + } + else if (IsMapped(source2)) + { + x86Reg HiReg = Is64Bit(source2) ? GetMipsRegMapHi(source2) : Map_TempReg(x86_Any, source2, true); + AddX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + AdcX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); + } + else + { + AddVariableToX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[source2].W[0], CRegName::GPR_Lo[source2]); + AdcVariableToX86reg(GetMipsRegMapHi(m_Opcode.rd), &_GPR[source2].W[1], CRegName::GPR_Hi[source2]); + } + } +} + +void CRecompilerOps::SPECIAL_DADDU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + return; + + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + int64_t ValRs = Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs); + int64_t ValRt = Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt); + if (IsMapped(m_Opcode.rd)) + UnMap_GPR(m_Opcode.rd, false); + + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, ValRs + ValRt); + if ((GetMipsRegHi(m_Opcode.rd) == 0) && (GetMipsRegLo(m_Opcode.rd) & 0x80000000) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if ((GetMipsRegHi(m_Opcode.rd) == 0xFFFFFFFF) && (GetMipsRegLo(m_Opcode.rd) & 0x80000000) != 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + } + else + { + int source1 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rt : m_Opcode.rs; + int source2 = m_Opcode.rd == m_Opcode.rt ? m_Opcode.rs : m_Opcode.rt; + + if (IsMapped(source2)) { ProtectGPR(source2); } + Map_GPR_64bit(m_Opcode.rd, source1); + if (IsConst(source2)) + { + DWORD LoReg = GetMipsRegLo(source2); + AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rd), LoReg); + if(LoReg != 0) + { + AdcConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(source2)); + } + else + { + AddConstToX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(source2)); + } + } + else if (IsMapped(source2)) + { + x86Reg HiReg = Is64Bit(source2) ? GetMipsRegMapHi(source2) : Map_TempReg(x86_Any, source2, true); + AddX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(source2)); + AdcX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); + } + else + { + AddVariableToX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[source2].W[0], CRegName::GPR_Lo[source2]); + AdcVariableToX86reg(GetMipsRegMapHi(m_Opcode.rd), &_GPR[source2].W[1], CRegName::GPR_Hi[source2]); + } + } +} + +void CRecompilerOps::SPECIAL_DSUB() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, + Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs) - + Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt) + ); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + } + else + { + if (m_Opcode.rd == m_Opcode.rt) + { + x86Reg HiReg = Map_TempReg(x86_Any, m_Opcode.rt, true); + x86Reg LoReg = Map_TempReg(x86_Any, m_Opcode.rt, false); + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rs); + SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), LoReg); + SbbX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); + return; + } + + if (IsMapped(m_Opcode.rt)) { ProtectGPR(m_Opcode.rt); } + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rs); + if (IsConst(m_Opcode.rt)) + { + SubConstFromX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(m_Opcode.rt)); + SbbConstFromX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(m_Opcode.rt)); + } + else if (IsMapped(m_Opcode.rt)) + { + x86Reg HiReg = Is64Bit(m_Opcode.rt) ? GetMipsRegMapHi(m_Opcode.rt) : Map_TempReg(x86_Any, m_Opcode.rt, true); + SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt)); + SbbX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); + } + else + { + SubVariableFromX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + SbbVariableFromX86reg(GetMipsRegMapHi(m_Opcode.rd), &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); + } + } +} + +void CRecompilerOps::SPECIAL_DSUBU() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt) && IsConst(m_Opcode.rs)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, + Is64Bit(m_Opcode.rs) ? GetMipsReg(m_Opcode.rs) : (int64_t)GetMipsRegLo_S(m_Opcode.rs) - + Is64Bit(m_Opcode.rt) ? GetMipsReg(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt) + ); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + } + else + { + if (m_Opcode.rd == m_Opcode.rt) + { + x86Reg HiReg = Map_TempReg(x86_Any, m_Opcode.rt, true); + x86Reg LoReg = Map_TempReg(x86_Any, m_Opcode.rt, false); + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rs); + SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), LoReg); + SbbX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); + return; + } + if (IsMapped(m_Opcode.rt)) { ProtectGPR(m_Opcode.rt); } + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rs); + if (IsConst(m_Opcode.rt)) + { + SubConstFromX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegLo(m_Opcode.rt)); + SbbConstFromX86Reg(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegHi(m_Opcode.rt)); + } + else if (IsMapped(m_Opcode.rt)) + { + x86Reg HiReg = Is64Bit(m_Opcode.rt) ? GetMipsRegMapHi(m_Opcode.rt) : Map_TempReg(x86_Any, m_Opcode.rt, true); + SubX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rt)); + SbbX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rd), HiReg); + } + else + { + SubVariableFromX86reg(GetMipsRegMapLo(m_Opcode.rd), &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]); + SbbVariableFromX86reg(GetMipsRegMapHi(m_Opcode.rd), &_GPR[m_Opcode.rt].W[1], CRegName::GPR_Hi[m_Opcode.rt]); + } + } +} + +void CRecompilerOps::SPECIAL_DSLL() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + int64_t Value = Is64Bit(m_Opcode.rt) ? GetMipsReg_S(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt); + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, Value << m_Opcode.sa); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + return; + } + + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + ShiftLeftDoubleImmed(GetMipsRegMapHi(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); + ShiftLeftSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); +} + +void CRecompilerOps::SPECIAL_DSRL() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + int64_t Value = Is64Bit(m_Opcode.rt) ? GetMipsReg_S(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt); + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, Value >> m_Opcode.sa); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + return; + } + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + ShiftRightDoubleImmed(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); + ShiftRightUnsignImmed(GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); +} + +void CRecompilerOps::SPECIAL_DSRA() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt)) + { + if (IsMapped(m_Opcode.rd)) + { + UnMap_GPR(m_Opcode.rd, false); + } + + int64_t Value = Is64Bit(m_Opcode.rt) ? GetMipsReg_S(m_Opcode.rt) : (int64_t)GetMipsRegLo_S(m_Opcode.rt); + m_RegWorkingSet.SetMipsReg_S(m_Opcode.rd, Value >> m_Opcode.sa); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + return; + } + + Map_GPR_64bit(m_Opcode.rd, m_Opcode.rt); + ShiftRightDoubleImmed(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); + ShiftRightSignImmed(GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); +} + +void CRecompilerOps::SPECIAL_DSLL32() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (m_Opcode.rd == 0) + { + return; + } + + if (IsConst(m_Opcode.rt)) + { + if (m_Opcode.rt != m_Opcode.rd) + { + UnMap_GPR(m_Opcode.rd, false); + } + m_RegWorkingSet.SetMipsRegHi(m_Opcode.rd, GetMipsRegLo(m_Opcode.rt) << m_Opcode.sa); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, 0); + if (GetMipsRegLo_S(m_Opcode.rd) < 0 && GetMipsRegHi_S(m_Opcode.rd) == -1) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else if (GetMipsRegLo_S(m_Opcode.rd) >= 0 && GetMipsRegHi_S(m_Opcode.rd) == 0) + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + } + else + { + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + } + } + else if (IsMapped(m_Opcode.rt)) + { + ProtectGPR(m_Opcode.rt); + Map_GPR_64bit(m_Opcode.rd, -1); + if (m_Opcode.rt != m_Opcode.rd) + { + MoveX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rt), GetMipsRegMapHi(m_Opcode.rd)); + } + else + { + CPU_Message(" regcache: switch hi (%s) with lo (%s) for %s", x86_Name(GetMipsRegMapHi(m_Opcode.rt)), x86_Name(GetMipsRegMapLo(m_Opcode.rt)), CRegName::GPR[m_Opcode.rt]); + x86Reg HiReg = GetMipsRegMapHi(m_Opcode.rt); + m_RegWorkingSet.SetMipsRegMapHi(m_Opcode.rt, GetMipsRegMapLo(m_Opcode.rt)); + m_RegWorkingSet.SetMipsRegMapLo(m_Opcode.rt, HiReg); + } + if ((uint8_t)m_Opcode.sa != 0) + { + ShiftLeftSignImmed(GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); + } + XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); + } + else + { + Map_GPR_64bit(m_Opcode.rd, -1); + MoveVariableToX86reg(&_GPR[m_Opcode.rt], CRegName::GPR_Hi[m_Opcode.rt], GetMipsRegMapHi(m_Opcode.rd)); + if ((uint8_t)m_Opcode.sa != 0) + { + ShiftLeftSignImmed(GetMipsRegMapHi(m_Opcode.rd), (uint8_t)m_Opcode.sa); + } + XorX86RegToX86Reg(GetMipsRegMapLo(m_Opcode.rd), GetMipsRegMapLo(m_Opcode.rd)); + } +} + +void CRecompilerOps::SPECIAL_DSRL32() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsConst(m_Opcode.rt)) + { + if (m_Opcode.rt != m_Opcode.rd) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_64); + m_RegWorkingSet.SetMipsReg(m_Opcode.rd, (uint32_t)(GetMipsRegHi(m_Opcode.rt) >> m_Opcode.sa)); + } + else if (IsMapped(m_Opcode.rt)) + { + ProtectGPR(m_Opcode.rt); + if (Is64Bit(m_Opcode.rt)) + { + if (m_Opcode.rt == m_Opcode.rd) + { + CPU_Message(" regcache: switch hi (%s) with lo (%s) for %s", x86_Name(GetMipsRegMapHi(m_Opcode.rt)), x86_Name(GetMipsRegMapLo(m_Opcode.rt)), CRegName::GPR[m_Opcode.rt]); + x86Reg HiReg = GetMipsRegMapHi(m_Opcode.rt); + m_RegWorkingSet.SetMipsRegMapHi(m_Opcode.rt, GetMipsRegMapLo(m_Opcode.rt)); + m_RegWorkingSet.SetMipsRegMapLo(m_Opcode.rt, HiReg); + Map_GPR_32bit(m_Opcode.rd, false, -1); + } + else + { + Map_GPR_32bit(m_Opcode.rd, false, -1); + MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rt), GetMipsRegMapLo(m_Opcode.rd)); + } + if ((uint8_t)m_Opcode.sa != 0) + { + ShiftRightUnsignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); + } + } + else + { + CRecompilerOps::UnknownOpcode(); + } + } + else { + Map_GPR_32bit(m_Opcode.rd, false, -1); + MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[1], CRegName::GPR_Hi[m_Opcode.rt], GetMipsRegMapLo(m_Opcode.rd)); + if ((uint8_t)m_Opcode.sa != 0) + { + ShiftRightUnsignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); + } + } +} + +void CRecompilerOps::SPECIAL_DSRA32() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (IsConst(m_Opcode.rt)) + { + if (m_Opcode.rt != m_Opcode.rd) + { + UnMap_GPR(m_Opcode.rd, false); + } + + m_RegWorkingSet.SetMipsRegState(m_Opcode.rd, CRegInfo::STATE_CONST_32_SIGN); + m_RegWorkingSet.SetMipsRegLo(m_Opcode.rd, (uint32_t)(GetMipsReg_S(m_Opcode.rt) >> (m_Opcode.sa + 32))); + } + else if (IsMapped(m_Opcode.rt)) + { + ProtectGPR(m_Opcode.rt); + if (Is64Bit(m_Opcode.rt)) + { + if (m_Opcode.rt == m_Opcode.rd) + { + CPU_Message(" regcache: switch hi (%s) with lo (%s) for %s", x86_Name(GetMipsRegMapHi(m_Opcode.rt)), x86_Name(GetMipsRegMapLo(m_Opcode.rt)), CRegName::GPR[m_Opcode.rt]); + x86Reg HiReg = GetMipsRegMapHi(m_Opcode.rt); + m_RegWorkingSet.SetMipsRegMapHi(m_Opcode.rt, GetMipsRegMapLo(m_Opcode.rt)); + m_RegWorkingSet.SetMipsRegMapLo(m_Opcode.rt, HiReg); + Map_GPR_32bit(m_Opcode.rd, true, -1); + } + else + { + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveX86RegToX86Reg(GetMipsRegMapHi(m_Opcode.rt), GetMipsRegMapLo(m_Opcode.rd)); + } + if ((uint8_t)m_Opcode.sa != 0) + { + ShiftRightSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); + } + } + else + { + CRecompilerOps::UnknownOpcode(); + } + } + else { + Map_GPR_32bit(m_Opcode.rd, true, -1); + MoveVariableToX86reg(&_GPR[m_Opcode.rt].UW[1], CRegName::GPR_Lo[m_Opcode.rt], GetMipsRegMapLo(m_Opcode.rd)); + if ((uint8_t)m_Opcode.sa != 0) + { + ShiftRightSignImmed(GetMipsRegMapLo(m_Opcode.rd), (uint8_t)m_Opcode.sa); + } + } +} + +/************************** COP0 functions **************************/ +void CRecompilerOps::COP0_MF() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + switch (m_Opcode.rd) + { + case 9: //Count + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + UpdateCounters(m_RegWorkingSet, false, true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); + AfterCallDirect(m_RegWorkingSet); + } + Map_GPR_32bit(m_Opcode.rt, true, -1); + MoveVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], GetMipsRegMapLo(m_Opcode.rt)); +} + +void CRecompilerOps::COP0_MT() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + uint8_t *Jump; + + switch (m_Opcode.rd) + { + case 0: //Index + case 2: //EntryLo0 + case 3: //EntryLo1 + case 4: //Context + case 5: //PageMask + case 10: //Entry Hi + case 14: //EPC + case 16: //Config + case 18: //WatchLo + case 19: //WatchHi + case 28: //Tag lo + case 29: //Tag Hi + case 30: //ErrEPC + if (IsConst(m_Opcode.rt)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + if (m_Opcode.rd == 4) //Context + { + AndConstToVariable(0xFF800000, &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + break; + case 11: //Compare + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + UpdateCounters(m_RegWorkingSet, false, true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); + AfterCallDirect(m_RegWorkingSet); + if (IsConst(m_Opcode.rt)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + AndConstToVariable((uint32_t)~CAUSE_IP7, &g_Reg->FAKE_CAUSE_REGISTER, "FAKE_CAUSE_REGISTER"); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::UpdateCompareTimer), "CSystemTimer::UpdateCompareTimer"); + AfterCallDirect(m_RegWorkingSet); + break; + case 9: //Count + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + UpdateCounters(m_RegWorkingSet, false, true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); + AfterCallDirect(m_RegWorkingSet); + if (IsConst(m_Opcode.rt)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::UpdateCompareTimer), "CSystemTimer::UpdateCompareTimer"); + AfterCallDirect(m_RegWorkingSet); + break; + case 12: //Status + { + x86Reg OldStatusReg = Map_TempReg(x86_Any, -1, false); + MoveVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); + if (IsConst(m_Opcode.rt)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + XorVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); + TestConstToX86Reg(STATUS_FR, OldStatusReg); + JeLabel8("FpuFlagFine", 0); + Jump = m_RecompPos - 1; + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); + Call_Direct(AddressOf(&CRegisters::FixFpuLocations), "CRegisters::FixFpuLocations"); + + AfterCallDirect(m_RegWorkingSet); + SetJump8(Jump, m_RecompPos); + + //TestConstToX86Reg(STATUS_FR,OldStatusReg); + //BreakPoint(__FILEW__,__LINE__); //m_Section->CompileExit(m_CompilePC+4,m_RegWorkingSet,ExitResetRecompCode,false,JneLabel32); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); + Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); + AfterCallDirect(m_RegWorkingSet); + } + break; + case 6: //Wired + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + UpdateCounters(m_RegWorkingSet, false, true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); + AfterCallDirect(m_RegWorkingSet); + if (IsConst(m_Opcode.rt)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + break; + case 13: //cause + if (IsConst(m_Opcode.rt)) + { + AndConstToVariable(0xFFFFCFF, &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + if ((GetMipsRegLo(m_Opcode.rt) & 0x300) != 0 && bHaveDebugger()){ g_Notify->DisplayError("Set IP0 or IP1"); } + } + else + { + UnknownOpcode(); + return; + } + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); + Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); + AfterCallDirect(m_RegWorkingSet); + break; + default: + UnknownOpcode(); + } +} + +/************************** COP0 CO functions ***********************/ +void CRecompilerOps::COP0_CO_TLBR(void) +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (!g_System->bUseTlb()) { return; } + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_TLB, x86_ECX); + Call_Direct(AddressOf(&CTLB::ReadEntry), "CTLB::ReadEntry"); + AfterCallDirect(m_RegWorkingSet); +} + +void CRecompilerOps::COP0_CO_TLBWI(void) +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (!g_System->bUseTlb()) { return; } + BeforeCallDirect(m_RegWorkingSet); + PushImm32("false", 0); + MoveVariableToX86reg(&g_Reg->INDEX_REGISTER, "INDEX_REGISTER", x86_ECX); + AndConstToX86Reg(x86_ECX, 0x1F); + Push(x86_ECX); + MoveConstToX86reg((uint32_t)g_TLB, x86_ECX); + Call_Direct(AddressOf(&CTLB::WriteEntry), "CTLB::WriteEntry"); + AfterCallDirect(m_RegWorkingSet); +} + +void CRecompilerOps::COP0_CO_TLBWR(void) +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + if (!g_System->bUseTlb()) { return; } + + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + UpdateCounters(m_RegWorkingSet, false, true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::UpdateTimers), "CSystemTimer::UpdateTimers"); + + PushImm32("true", true); + MoveVariableToX86reg(&g_Reg->RANDOM_REGISTER, "RANDOM_REGISTER", x86_ECX); + AndConstToX86Reg(x86_ECX, 0x1F); + Push(x86_ECX); + MoveConstToX86reg((uint32_t)g_TLB, x86_ECX); + Call_Direct(AddressOf(&CTLB::WriteEntry), "CTLB::WriteEntry"); + AfterCallDirect(m_RegWorkingSet); +} + +void CRecompilerOps::COP0_CO_TLBP(void) +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + if (!g_System->bUseTlb()) { return; } + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_TLB, x86_ECX); + Call_Direct(AddressOf(&CTLB::Probe), "CTLB::TLB_Probe"); + AfterCallDirect(m_RegWorkingSet); +} + +void compiler_COP0_CO_ERET() +{ + if ((g_Reg->STATUS_REGISTER & STATUS_ERL) != 0) { + g_Reg->m_PROGRAM_COUNTER = g_Reg->ERROREPC_REGISTER; + g_Reg->STATUS_REGISTER &= ~STATUS_ERL; + } + else + { + g_Reg->m_PROGRAM_COUNTER = g_Reg->EPC_REGISTER; + g_Reg->STATUS_REGISTER &= ~STATUS_EXL; + } + g_Reg->m_LLBit = 0; + g_Reg->CheckInterrupts(); +} + +void CRecompilerOps::COP0_CO_ERET(void) +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_RegWorkingSet.WriteBackRegisters(); + Call_Direct((void *)compiler_COP0_CO_ERET, "compiler_COP0_CO_ERET"); + + UpdateCounters(m_RegWorkingSet, true, true); + m_Section->CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, NULL); + m_NextInstruction = END_BLOCK; +} + +/************************** FPU Options **************************/ +void CRecompilerOps::ChangeDefaultRoundingModel() +{ + switch ((_FPCR[31] & 3)) + { + case 0: *_RoundingModel = FE_TONEAREST; break; + case 1: *_RoundingModel = FE_TOWARDZERO; break; + case 2: *_RoundingModel = FE_UPWARD; break; + case 3: *_RoundingModel = FE_DOWNWARD; break; + } +} + +/************************** COP1 functions **************************/ +void CRecompilerOps::COP1_MF() +{ + x86Reg TempReg; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + + UnMap_FPR(m_Opcode.fs, true); + Map_GPR_32bit(m_Opcode.rt, true, -1); + TempReg = Map_TempReg(x86_Any, -1, false); + char Name[100]; + sprintf(Name, "_FPR_S[%d]", m_Opcode.fs); + MoveVariableToX86reg((uint8_t *)&_FPR_S[m_Opcode.fs], Name, TempReg); + MoveX86PointerToX86reg(GetMipsRegMapLo(m_Opcode.rt), TempReg); +} + +void CRecompilerOps::COP1_DMF() +{ + x86Reg TempReg; + char Name[50]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + + UnMap_FPR(m_Opcode.fs, true); + Map_GPR_64bit(m_Opcode.rt, -1); + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_D[%d]", m_Opcode.fs); + MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.fs], Name, TempReg); + AddConstToX86Reg(TempReg, 4); + MoveX86PointerToX86reg(GetMipsRegMapHi(m_Opcode.rt), TempReg); + sprintf(Name, "_FPR_D[%d]", m_Opcode.fs); + MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.fs], Name, TempReg); + MoveX86PointerToX86reg(GetMipsRegMapLo(m_Opcode.rt), TempReg); +} + +void CRecompilerOps::COP1_CF() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + + if (m_Opcode.fs != 31 && m_Opcode.fs != 0) + { + UnknownOpcode(); + return; + } + + Map_GPR_32bit(m_Opcode.rt, true, -1); + MoveVariableToX86reg(&_FPCR[m_Opcode.fs], CRegName::FPR_Ctrl[m_Opcode.fs], GetMipsRegMapLo(m_Opcode.rt)); +} + +void CRecompilerOps::COP1_MT() +{ + x86Reg TempReg; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + + if ((m_Opcode.fs & 1) != 0) + { + if (RegInStack(m_Opcode.fs - 1, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs - 1, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs - 1, true); + } + } + UnMap_FPR(m_Opcode.fs, true); + TempReg = Map_TempReg(x86_Any, -1, false); + char Name[50]; + sprintf(Name, "_FPR_S[%d]", m_Opcode.fs); + MoveVariableToX86reg((uint8_t *)&_FPR_S[m_Opcode.fs], Name, TempReg); + + if (IsConst(m_Opcode.rt)) + { + MoveConstToX86Pointer(GetMipsRegLo(m_Opcode.rt), TempReg); + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToX86Pointer(GetMipsRegMapLo(m_Opcode.rt), TempReg); + } + else + { + MoveX86regToX86Pointer(Map_TempReg(x86_Any, m_Opcode.rt, false), TempReg); + } +} + +void CRecompilerOps::COP1_DMT() +{ + x86Reg TempReg; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + + if ((m_Opcode.fs & 1) == 0) + { + if (RegInStack(m_Opcode.fs + 1, CRegInfo::FPU_Float) || RegInStack(m_Opcode.fs + 1, CRegInfo::FPU_Dword)) { + UnMap_FPR(m_Opcode.fs + 1, true); + } + } + UnMap_FPR(m_Opcode.fs, true); + TempReg = Map_TempReg(x86_Any, -1, false); + char Name[50]; + sprintf(Name, "_FPR_D[%d]", m_Opcode.fs); + MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.fs], Name, TempReg); + + if (IsConst(m_Opcode.rt)) + { + MoveConstToX86Pointer(GetMipsRegLo(m_Opcode.rt), TempReg); + AddConstToX86Reg(TempReg, 4); + if (Is64Bit(m_Opcode.rt)) + { + MoveConstToX86Pointer(GetMipsRegHi(m_Opcode.rt), TempReg); + } + else + { + MoveConstToX86Pointer(GetMipsRegLo_S(m_Opcode.rt) >> 31, TempReg); + } + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToX86Pointer(GetMipsRegMapLo(m_Opcode.rt), TempReg); + AddConstToX86Reg(TempReg, 4); + if (Is64Bit(m_Opcode.rt)) + { + MoveX86regToX86Pointer(GetMipsRegMapHi(m_Opcode.rt), TempReg); + } + else + { + MoveX86regToX86Pointer(Map_TempReg(x86_Any, m_Opcode.rt, true), TempReg); + } + } + else + { + x86Reg Reg = Map_TempReg(x86_Any, m_Opcode.rt, false); + MoveX86regToX86Pointer(Reg, TempReg); + AddConstToX86Reg(TempReg, 4); + MoveX86regToX86Pointer(Map_TempReg(Reg, m_Opcode.rt, true), TempReg); + } +} + +void CRecompilerOps::COP1_CT() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + + if (m_Opcode.fs != 31) + { + UnknownOpcode(); + return; + } + + if (IsConst(m_Opcode.rt)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_FPCR[m_Opcode.fs], CRegName::FPR_Ctrl[m_Opcode.fs]); + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_FPCR[m_Opcode.fs], CRegName::FPR_Ctrl[m_Opcode.fs]); + } + else + { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_FPCR[m_Opcode.fs], CRegName::FPR_Ctrl[m_Opcode.fs]); + } + BeforeCallDirect(m_RegWorkingSet); + Call_Direct((void *)ChangeDefaultRoundingModel, "ChangeDefaultRoundingModel"); + AfterCallDirect(m_RegWorkingSet); + m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); +} + +/************************** COP1: S functions ************************/ +void CRecompilerOps::COP1_S_ADD() +{ + uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + + Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); + if (RegInStack(Reg2, CRegInfo::FPU_Float)) + { + fpuAddReg(StackPosition(Reg2)); + } + else + { + x86Reg TempReg; + + UnMap_FPR(Reg2, true); + TempReg = Map_TempReg(x86_Any, -1, false); + char Name[50]; + sprintf(Name, "_FPR_S[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); + fpuAddDwordRegPointer(TempReg); + } + UnMap_FPR(m_Opcode.fd, true); +} + +void CRecompilerOps::COP1_S_SUB() +{ + uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; + x86Reg TempReg; + char Name[50]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + + if (m_Opcode.fd == m_Opcode.ft) + { + UnMap_FPR(m_Opcode.fd, true); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_S[%d]", m_Opcode.ft); + MoveVariableToX86reg((uint8_t *)&_FPR_S[m_Opcode.ft], Name, TempReg); + fpuSubDwordRegPointer(TempReg); + } + else + { + Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); + if (RegInStack(Reg2, CRegInfo::FPU_Float)) + { + fpuSubReg(StackPosition(Reg2)); + } + else + { + UnMap_FPR(Reg2, true); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); + + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_S[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); + fpuSubDwordRegPointer(TempReg); + } + } + UnMap_FPR(m_Opcode.fd, true); +} + +void CRecompilerOps::COP1_S_MUL() +{ + uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; + x86Reg TempReg; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + + Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); + if (RegInStack(Reg2, CRegInfo::FPU_Float)) + { + fpuMulReg(StackPosition(Reg2)); + } + else + { + UnMap_FPR(Reg2, true); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); + + TempReg = Map_TempReg(x86_Any, -1, false); + char Name[50]; + sprintf(Name, "_FPR_S[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); + fpuMulDwordRegPointer(TempReg); + } + UnMap_FPR(m_Opcode.fd, true); +} + +void CRecompilerOps::COP1_S_DIV() +{ + uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; + x86Reg TempReg; + char Name[50]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + + if (m_Opcode.fd == m_Opcode.ft) + { + UnMap_FPR(m_Opcode.fd, true); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_S[%d]", m_Opcode.ft); + MoveVariableToX86reg((uint8_t *)&_FPR_S[m_Opcode.ft], Name, TempReg); + fpuDivDwordRegPointer(TempReg); + } + else + { + Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); + if (RegInStack(Reg2, CRegInfo::FPU_Float)) + { + fpuDivReg(StackPosition(Reg2)); + } + else + { + UnMap_FPR(Reg2, true); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); + + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_S[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); + fpuDivDwordRegPointer(TempReg); + } + } + + UnMap_FPR(m_Opcode.fd, true); +} + +void CRecompilerOps::COP1_S_ABS() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + fpuAbs(); + UnMap_FPR(m_Opcode.fd, true); +} + +void CRecompilerOps::COP1_S_NEG() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + fpuNeg(); + UnMap_FPR(m_Opcode.fd, true); +} + +void CRecompilerOps::COP1_S_SQRT() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + fpuSqrt(); + UnMap_FPR(m_Opcode.fd, true); +} + +void CRecompilerOps::COP1_S_MOV() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); +} + +void CRecompilerOps::COP1_S_TRUNC_L() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundTruncate); +} + +void CRecompilerOps::COP1_S_CEIL_L() //added by Witten +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundUp); +} + +void CRecompilerOps::COP1_S_FLOOR_L() //added by Witten +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundDown); +} + +void CRecompilerOps::COP1_S_ROUND_W() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundNearest); +} + +void CRecompilerOps::COP1_S_TRUNC_W() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundTruncate); +} + +void CRecompilerOps::COP1_S_CEIL_W() // added by Witten +{ // added by Witten + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundUp); +} + +void CRecompilerOps::COP1_S_FLOOR_W() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundDown); +} + +void CRecompilerOps::COP1_S_CVT_D() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Double, CRegInfo::RoundDefault); +} + +void CRecompilerOps::COP1_S_CVT_W() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Dword, CRegInfo::RoundDefault); +} + +void CRecompilerOps::COP1_S_CVT_L() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundDefault); +} + +void CRecompilerOps::COP1_S_CMP() +{ + uint32_t Reg1 = m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft; + uint32_t cmp = 0; + + if ((m_Opcode.funct & 4) == 0) + { + Reg1 = RegInStack(m_Opcode.ft, CRegInfo::FPU_Float) ? m_Opcode.ft : m_Opcode.fs; + Reg2 = RegInStack(m_Opcode.ft, CRegInfo::FPU_Float) ? m_Opcode.fs : m_Opcode.ft; + } + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if ((m_Opcode.funct & 7) == 0) { CRecompilerOps::UnknownOpcode(); } + if ((m_Opcode.funct & 2) != 0) { cmp |= 0x4000; } + if ((m_Opcode.funct & 4) != 0) { cmp |= 0x0100; } + + Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Float); + Map_TempReg(x86_EAX, 0, false); + if (RegInStack(Reg2, CRegInfo::FPU_Float)) + { + fpuComReg(StackPosition(Reg2), false); + } + else + { + UnMap_FPR(Reg2, true); + Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Float); + + x86Reg TempReg = Map_TempReg(x86_Any, -1, false); + char Name[50]; + sprintf(Name, "_FPR_S[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_S[Reg2], Name, TempReg); + fpuComDwordRegPointer(TempReg, false); + } + AndConstToVariable((uint32_t)~FPCSR_C, &_FPCR[31], "_FPCR[31]"); + fpuStoreStatus(); + x86Reg Reg = Map_TempReg(x86_Any8Bit, 0, false); + TestConstToX86Reg(cmp, x86_EAX); + Setnz(Reg); + + if (cmp != 0) + { + TestConstToX86Reg(cmp, x86_EAX); + Setnz(Reg); + + if ((m_Opcode.funct & 1) != 0) + { + x86Reg Reg2 = Map_TempReg(x86_Any8Bit, 0, false); + AndConstToX86Reg(x86_EAX, 0x4300); + CompConstToX86reg(x86_EAX, 0x4300); + Setz(Reg2); + + OrX86RegToX86Reg(Reg, Reg2); + } + } + else if ((m_Opcode.funct & 1) != 0) + { + AndConstToX86Reg(x86_EAX, 0x4300); + CompConstToX86reg(x86_EAX, 0x4300); + Setz(Reg); + } + ShiftLeftSignImmed(Reg, 23); + OrX86RegToVariable(&_FPCR[31], "_FPCR[31]", Reg); +} + +/************************** COP1: D functions ************************/ +void CRecompilerOps::COP1_D_ADD() +{ + uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; + char Name[50]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + + Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); + if (RegInStack(Reg2, CRegInfo::FPU_Double)) + { + fpuAddReg(StackPosition(Reg2)); + } + else + { + x86Reg TempReg; + + UnMap_FPR(Reg2, true); + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_D[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Double); + fpuAddQwordRegPointer(TempReg); + } +} + +void CRecompilerOps::COP1_D_SUB() +{ + uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; + x86Reg TempReg; + char Name[50]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + + if (m_Opcode.fd == m_Opcode.ft) + { + UnMap_FPR(m_Opcode.fd, true); + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_D[%d]", m_Opcode.ft); + MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.ft], Name, TempReg); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + fpuSubQwordRegPointer(TempReg); + } + else + { + Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); + if (RegInStack(Reg2, CRegInfo::FPU_Double)) + { + fpuSubReg(StackPosition(Reg2)); + } + else + { + UnMap_FPR(Reg2, true); + + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_D[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Double); + fpuSubQwordRegPointer(TempReg); + } + } +} + +void CRecompilerOps::COP1_D_MUL() +{ + uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; + x86Reg TempReg; + char Name[50]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + FixRoundModel(CRegInfo::RoundDefault); + + Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); + if (RegInStack(Reg2, CRegInfo::FPU_Double)) + { + fpuMulReg(StackPosition(Reg2)); + } + else + { + UnMap_FPR(Reg2, true); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Double); + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_D[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); + fpuMulQwordRegPointer(TempReg); + } +} + +void CRecompilerOps::COP1_D_DIV() +{ + uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; + x86Reg TempReg; + char Name[50]; + + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + + if (m_Opcode.fd == m_Opcode.ft) + { + UnMap_FPR(m_Opcode.fd, true); + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_D[%d]", m_Opcode.ft); + MoveVariableToX86reg((uint8_t *)&_FPR_D[m_Opcode.ft], Name, TempReg); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + fpuDivQwordRegPointer(TempReg); + } + else + { + Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); + if (RegInStack(Reg2, CRegInfo::FPU_Double)) + { + fpuDivReg(StackPosition(Reg2)); + } + else + { + UnMap_FPR(Reg2, true); + TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_D[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Double); + fpuDivQwordRegPointer(TempReg); + } + } +} + +void CRecompilerOps::COP1_D_ABS() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + fpuAbs(); +} + +void CRecompilerOps::COP1_D_NEG() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + fpuNeg(); +} + +void CRecompilerOps::COP1_D_SQRT() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + fpuSqrt(); +} + +void CRecompilerOps::COP1_D_MOV() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); +} + +void CRecompilerOps::COP1_D_TRUNC_L() //added by Witten +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundTruncate); +} + +void CRecompilerOps::COP1_D_CEIL_L() //added by Witten +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundUp); +} + +void CRecompilerOps::COP1_D_FLOOR_L() //added by Witten +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundDown); +} + +void CRecompilerOps::COP1_D_ROUND_W() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundNearest); +} + +void CRecompilerOps::COP1_D_TRUNC_W() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fd, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundTruncate); +} + +void CRecompilerOps::COP1_D_CEIL_W() // added by Witten +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundUp); +} + +void CRecompilerOps::COP1_D_FLOOR_W() //added by Witten +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDown); +} + +void CRecompilerOps::COP1_D_CVT_S() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fd, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Float, CRegInfo::RoundDefault); +} + +void CRecompilerOps::COP1_D_CVT_W() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDefault); +} + +void CRecompilerOps::COP1_D_CVT_L() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) + { + UnMap_FPR(m_Opcode.fs, true); + } + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Double)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundDefault); +} + +void CRecompilerOps::COP1_D_CMP() +{ + uint32_t Reg1 = m_Opcode.fs; + uint32_t Reg2 = m_Opcode.ft; + uint32_t cmp = 0; + + if ((m_Opcode.funct & 4) == 0) + { + Reg1 = RegInStack(m_Opcode.ft, CRegInfo::FPU_Double) ? m_Opcode.ft : m_Opcode.fs; + Reg2 = RegInStack(m_Opcode.ft, CRegInfo::FPU_Double) ? m_Opcode.fs : m_Opcode.ft; + } + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if ((m_Opcode.funct & 7) == 0) { CRecompilerOps::UnknownOpcode(); } + if ((m_Opcode.funct & 2) != 0) { cmp |= 0x4000; } + if ((m_Opcode.funct & 4) != 0) { cmp |= 0x0100; } + + Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Double); + Map_TempReg(x86_EAX, 0, false); + if (RegInStack(Reg2, CRegInfo::FPU_Double)) + { + fpuComReg(StackPosition(Reg2), false); + } + else + { + char Name[50]; + + UnMap_FPR(Reg2, true); + x86Reg TempReg = Map_TempReg(x86_Any, -1, false); + sprintf(Name, "_FPR_D[%d]", Reg2); + MoveVariableToX86reg((uint8_t *)&_FPR_D[Reg2], Name, TempReg); + Load_FPR_ToTop(Reg1, Reg1, CRegInfo::FPU_Double); + fpuComQwordRegPointer(TempReg, false); + } + AndConstToVariable((uint32_t)~FPCSR_C, &_FPCR[31], "_FPCR[31]"); + fpuStoreStatus(); + x86Reg Reg = Map_TempReg(x86_Any8Bit, 0, false); + TestConstToX86Reg(cmp, x86_EAX); + Setnz(Reg); + if (cmp != 0) + { + TestConstToX86Reg(cmp, x86_EAX); + Setnz(Reg); + + if ((m_Opcode.funct & 1) != 0) + { + x86Reg Reg2 = Map_TempReg(x86_Any8Bit, 0, false); + AndConstToX86Reg(x86_EAX, 0x4300); + CompConstToX86reg(x86_EAX, 0x4300); + Setz(Reg2); + + OrX86RegToX86Reg(Reg, Reg2); + } + } + else if ((m_Opcode.funct & 1) != 0) + { + AndConstToX86Reg(x86_EAX, 0x4300); + CompConstToX86reg(x86_EAX, 0x4300); + Setz(Reg); + } + ShiftLeftSignImmed(Reg, 23); + OrX86RegToVariable(&_FPCR[31], "_FPCR[31]", Reg); +} + +/************************** COP1: W functions ************************/ +void CRecompilerOps::COP1_W_CVT_S() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Dword, CRegInfo::FPU_Float, CRegInfo::RoundDefault); +} + +void CRecompilerOps::COP1_W_CVT_D() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Dword, CRegInfo::FPU_Double, CRegInfo::RoundDefault); +} + +/************************** COP1: L functions ************************/ +void CRecompilerOps::COP1_L_CVT_S() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Qword, CRegInfo::FPU_Float, CRegInfo::RoundDefault); +} + +void CRecompilerOps::COP1_L_CVT_D() +{ + CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_Section->CompileCop1Test(); + if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) + { + Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword); + } + ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Qword, CRegInfo::FPU_Double, CRegInfo::RoundDefault); +} + +/************************** Other functions **************************/ +void CRecompilerOps::UnknownOpcode() +{ + CPU_Message(" %X Unhandled Opcode: %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); + + m_RegWorkingSet.WriteBackRegisters(); + UpdateCounters(m_RegWorkingSet, false, true); + MoveConstToVariable(m_CompilePC, &g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER"); + if (g_SyncSystem) + { + MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + + MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); + Call_Direct((void *)R4300iOp::UnknownOpcode, "R4300iOp::UnknownOpcode"); + Ret(); + if (m_NextInstruction == NORMAL) { m_NextInstruction = END_BLOCK; } +} + +void CRecompilerOps::BeforeCallDirect(CRegInfo & RegSet) +{ + RegSet.UnMap_AllFPRs(); + Pushad(); +} + +void CRecompilerOps::AfterCallDirect(CRegInfo & RegSet) +{ + Popad(); + RegSet.SetRoundingModel(CRegInfo::RoundUnknown); +} + +void CRecompilerOps::EnterCodeBlock() +{ +#ifdef _DEBUG + Push(x86_ESI); +#else + Push(x86_EDI); + Push(x86_ESI); + Push(x86_EBX); +#endif +} + +void CRecompilerOps::ExitCodeBlock() +{ +#ifdef _DEBUG + Pop(x86_ESI); +#else + Pop(x86_EBX); + Pop(x86_ESI); + Pop(x86_EDI); +#endif + Ret(); +} + +void CRecompilerOps::UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles) +{ + if (!g_SyncSystem) + { + return; + } + + WriteX86Comment("Updating Sync CPU"); + BeforeCallDirect(RegSet); + PushImm32(stdstr_f("%d", Cycles).c_str(), Cycles); + PushImm32("g_SyncSystem", (uint32_t)g_SyncSystem); + MoveConstToX86reg((uint32_t)g_System, x86_ECX); + Call_Direct(AddressOf(&CN64System::UpdateSyncCPU), "CN64System::UpdateSyncCPU"); + AfterCallDirect(RegSet); +} + +void CRecompilerOps::UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues) +{ + if (RegSet.GetBlockCycleCount() != 0) + { + UpdateSyncCPU(RegSet, RegSet.GetBlockCycleCount()); + WriteX86Comment("Update Counter"); + SubConstFromVariable(RegSet.GetBlockCycleCount(), g_NextTimer, "g_NextTimer"); // updates compare flag + if (ClearValues) + { + RegSet.SetBlockCycleCount(0); + } + } + else if (CheckTimer) + { + CompConstToVariable(0, g_NextTimer, "g_NextTimer"); + } + + if (CheckTimer) + { + JnsLabel8("Continue_From_Timer_Test", 0); + uint8_t * Jump = m_RecompPos - 1; + Pushad(); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::TimerDone), "CSystemTimer::TimerDone"); + Popad(); + + CPU_Message(""); + CPU_Message(" $Continue_From_Timer_Test:"); + SetJump8(Jump, m_RecompPos); + } +} + +void CRecompilerOps::CompileSystemCheck(uint32_t TargetPC, const CRegInfo & RegSet) +{ + CompConstToVariable(0, (void *)&g_SystemEvents->DoSomething(), "g_SystemEvents->DoSomething()"); + JeLabel32("Continue_From_Interrupt_Test", 0); + uint32_t * Jump = (uint32_t *)(m_RecompPos - 4); + if (TargetPC != (uint32_t)-1) + { + MoveConstToVariable(TargetPC, &g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER"); + } + + CRegInfo RegSetCopy(RegSet); + RegSetCopy.WriteBackRegisters(); + + MoveConstToX86reg((uint32_t)g_SystemEvents, x86_ECX); + Call_Direct(AddressOf(&CSystemEvents::ExecuteEvents), "CSystemEvents::ExecuteEvents"); + if (g_SyncSystem) + { + MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } + ExitCodeBlock(); + CPU_Message(""); + CPU_Message(" $Continue_From_Interrupt_Test:"); + SetJump32(Jump, (uint32_t *)m_RecompPos); +} + +void CRecompilerOps::OverflowDelaySlot(bool TestTimer) +{ + m_RegWorkingSet.WriteBackRegisters(); + UpdateCounters(m_RegWorkingSet, false, true); + MoveConstToVariable(CompilePC() + 4, _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + + if (g_SyncSystem) + { + MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } + + MoveConstToVariable(JUMP, &R4300iOp::m_NextInstruction, "R4300iOp::m_NextInstruction"); + + if (TestTimer) + { + MoveConstToVariable(TestTimer, &R4300iOp::m_TestTimer, "R4300iOp::m_TestTimer"); + } + + PushImm32("g_System->CountPerOp()", g_System->CountPerOp()); + Call_Direct((void *)CInterpreterCPU::ExecuteOps, "CInterpreterCPU::ExecuteOps"); + AddConstToX86Reg(x86_ESP, 4); + + if (g_System->bFastSP() && g_Recompiler) + { + MoveConstToX86reg((uint32_t)g_Recompiler, x86_ECX); + Call_Direct(AddressOf(&CRecompiler::ResetMemoryStackPos), "CRecompiler::ResetMemoryStackPos"); + } + + if (g_SyncSystem) + { + UpdateSyncCPU(m_RegWorkingSet, g_System->CountPerOp()); + MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } + + ExitCodeBlock(); + m_NextInstruction = END_BLOCK; } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/RecompilerOps.h index 5b2e9d77e..0bcc46866 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/RecompilerOps.h @@ -1,335 +1,335 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -class CCodeSection; - -class CRecompilerOps : - protected CDebugSettings, - protected CX86Ops, - protected CSystemRegisters, - protected CN64SystemSettings, - protected CRecompilerSettings -{ -protected: - enum BRANCH_TYPE - { - BranchTypeCop1, BranchTypeRs, BranchTypeRsRt - }; - - typedef void ( * BranchFunction )(); - - /************************** Branch functions ************************/ - static void Compile_Branch ( BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link); - static void Compile_BranchLikely ( BranchFunction CompareFunc, bool Link); - static void BNE_Compare(); - static void BEQ_Compare(); - static void BGTZ_Compare(); - static void BLEZ_Compare(); - static void BLTZ_Compare(); - static void BGEZ_Compare(); - static void COP1_BCF_Compare(); - static void COP1_BCT_Compare(); - - /************************* OpCode functions *************************/ - static void J (); - static void JAL (); - static void ADDI (); - static void ADDIU (); - static void SLTI (); - static void SLTIU (); - static void ANDI (); - static void ORI (); - static void XORI (); - static void LUI (); - static void DADDIU (); - // static void LDL (); - // static void LDR (); - // static void LB (); - // static void LH (); - // static void LWL (); - // static void LW (); - // static void LBU (); - // static void LHU (); - // static void LWR (); - // static void LWU (); //added by Witten - // static void SB (); - // static void SH (); - // static void SWL (); - // static void SW (); - // static void SWR (); - // static void SDL (); - // static void SDR (); - static void CACHE (); - // static void LL (); - // static void LWC1 (); - // static void LDC1 (); - // static void LD (); - // static void SC (); - // static void SWC1 (); - // static void SDC1 (); - // static void SD (); - - /********************** R4300i OpCodes: Special **********************/ - static void SPECIAL_SLL (); - static void SPECIAL_SRL (); - static void SPECIAL_SRA (); - static void SPECIAL_SLLV (); - static void SPECIAL_SRLV (); - static void SPECIAL_SRAV (); - static void SPECIAL_JR (); - static void SPECIAL_JALR (); - static void SPECIAL_SYSCALL(); - static void SPECIAL_MFLO (); - static void SPECIAL_MTLO (); - static void SPECIAL_MFHI (); - static void SPECIAL_MTHI (); - static void SPECIAL_DSLLV (); - static void SPECIAL_DSRLV (); - static void SPECIAL_DSRAV (); - static void SPECIAL_MULT (); - static void SPECIAL_MULTU (); - static void SPECIAL_DIV (); - static void SPECIAL_DIVU (); - static void SPECIAL_DMULT (); - static void SPECIAL_DMULTU (); - static void SPECIAL_DDIV (); - static void SPECIAL_DDIVU (); - static void SPECIAL_ADD (); - static void SPECIAL_ADDU (); - static void SPECIAL_SUB (); - static void SPECIAL_SUBU (); - static void SPECIAL_AND (); - static void SPECIAL_OR (); - static void SPECIAL_XOR (); - static void SPECIAL_NOR (); - static void SPECIAL_SLT (); - static void SPECIAL_SLTU (); - static void SPECIAL_DADD (); - static void SPECIAL_DADDU (); - static void SPECIAL_DSUB (); - static void SPECIAL_DSUBU (); - static void SPECIAL_DSLL (); - static void SPECIAL_DSRL (); - static void SPECIAL_DSRA (); - static void SPECIAL_DSLL32 (); - static void SPECIAL_DSRL32 (); - static void SPECIAL_DSRA32 (); - - /************************** COP0 functions **************************/ - static void COP0_MF (); - static void COP0_MT (); - - /************************** COP0 CO functions ***********************/ - static void COP0_CO_TLBR (); - static void COP0_CO_TLBWI (); - static void COP0_CO_TLBWR (); - static void COP0_CO_TLBP (); - static void COP0_CO_ERET (); - - /************************** COP1 functions **************************/ - static void COP1_MF (); - static void COP1_DMF (); - static void COP1_CF (); - static void COP1_MT (); - static void COP1_DMT (); - static void COP1_CT (); - - /************************** COP1: S functions ************************/ - static void COP1_S_ADD (); - static void COP1_S_SUB (); - static void COP1_S_MUL (); - static void COP1_S_DIV (); - static void COP1_S_ABS (); - static void COP1_S_NEG (); - static void COP1_S_SQRT (); - static void COP1_S_MOV (); - static void COP1_S_TRUNC_L (); - static void COP1_S_CEIL_L (); //added by Witten - static void COP1_S_FLOOR_L (); //added by Witten - static void COP1_S_ROUND_W (); - static void COP1_S_TRUNC_W (); - static void COP1_S_CEIL_W (); //added by Witten - static void COP1_S_FLOOR_W (); - static void COP1_S_CVT_D (); - static void COP1_S_CVT_W (); - static void COP1_S_CVT_L (); - static void COP1_S_CMP (); - - /************************** COP1: D functions ************************/ - static void COP1_D_ADD (); - static void COP1_D_SUB (); - static void COP1_D_MUL (); - static void COP1_D_DIV (); - static void COP1_D_ABS (); - static void COP1_D_NEG (); - static void COP1_D_SQRT (); - static void COP1_D_MOV (); - static void COP1_D_TRUNC_L (); //added by Witten - static void COP1_D_CEIL_L (); //added by Witten - static void COP1_D_FLOOR_L (); //added by Witten - static void COP1_D_ROUND_W (); - static void COP1_D_TRUNC_W (); - static void COP1_D_CEIL_W (); //added by Witten - static void COP1_D_FLOOR_W (); //added by Witten - static void COP1_D_CVT_S (); - static void COP1_D_CVT_W (); - static void COP1_D_CVT_L (); - static void COP1_D_CMP (); - - /************************** COP1: W functions ************************/ - static void COP1_W_CVT_S (); - static void COP1_W_CVT_D (); - - /************************** COP1: L functions ************************/ - static void COP1_L_CVT_S (); - static void COP1_L_CVT_D (); - - /************************** Other functions **************************/ - static void UnknownOpcode (); - - static void BeforeCallDirect(CRegInfo & RegSet); - static void AfterCallDirect(CRegInfo & RegSet); - static void EnterCodeBlock(); - static void ExitCodeBlock(); - static void CompileReadTLBMiss(uint32_t VirtualAddress, x86Reg LookUpReg); - static void CompileReadTLBMiss(x86Reg AddressReg, x86Reg LookUpReg); - static void CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg); - static void UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles); - static void UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false); - static void CompileSystemCheck(uint32_t TargetPC, const CRegInfo & RegSet); - static void ChangeDefaultRoundingModel(); - static void OverflowDelaySlot(bool TestTimer); - - static STEP_TYPE m_NextInstruction; - static uint32_t m_CompilePC; - static OPCODE m_Opcode; - static CRegInfo m_RegWorkingSet; - static uint32_t m_BranchCompare; - static CCodeSection * m_Section; - - /********* Helper Functions *********/ - typedef CRegInfo::REG_STATE REG_STATE; - - static REG_STATE GetMipsRegState ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegState(Reg); } - static uint64_t GetMipsReg ( int32_t Reg ) { return m_RegWorkingSet.GetMipsReg(Reg); } - static int64_t GetMipsReg_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsReg_S(Reg); } - static uint32_t GetMipsRegLo ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegLo(Reg); } - static int32_t GetMipsRegLo_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegLo_S(Reg); } - static uint32_t GetMipsRegHi ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegHi(Reg); } - static int32_t GetMipsRegHi_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegHi_S(Reg); } - static CX86Ops::x86Reg GetMipsRegMapLo ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegMapLo(Reg); } - static CX86Ops::x86Reg GetMipsRegMapHi ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegMapHi(Reg); } - - static bool IsKnown ( int32_t Reg ) { return m_RegWorkingSet.IsKnown(Reg); } - static bool IsUnknown ( int32_t Reg ) { return m_RegWorkingSet.IsUnknown(Reg); } - static bool IsMapped ( int32_t Reg ) { return m_RegWorkingSet.IsMapped(Reg); } - static bool IsConst ( int32_t Reg ) { return m_RegWorkingSet.IsConst(Reg); } - static bool IsSigned ( int32_t Reg ) { return m_RegWorkingSet.IsSigned(Reg); } - static bool IsUnsigned ( int32_t Reg ) { return m_RegWorkingSet.IsUnsigned(Reg); } - static bool Is32Bit ( int32_t Reg ) { return m_RegWorkingSet.Is32Bit(Reg); } - static bool Is64Bit ( int32_t Reg ) { return m_RegWorkingSet.Is64Bit(Reg); } - static bool Is32BitMapped ( int32_t Reg ) { return m_RegWorkingSet.Is32BitMapped(Reg); } - static bool Is64BitMapped ( int32_t Reg ) { return m_RegWorkingSet.Is64BitMapped(Reg); } - - static void FixRoundModel ( CRegInfo::FPU_ROUND RoundMethod ) - { - m_RegWorkingSet.FixRoundModel(RoundMethod); - } - static void ChangeFPURegFormat ( int32_t Reg, CRegInfo::FPU_STATE OldFormat, CRegInfo::FPU_STATE NewFormat, CRegInfo::FPU_ROUND RoundingModel ) - { - m_RegWorkingSet.ChangeFPURegFormat(Reg,OldFormat,NewFormat,RoundingModel); - } - static void Load_FPR_ToTop ( int32_t Reg, int32_t RegToLoad, CRegInfo::FPU_STATE Format) - { - m_RegWorkingSet.Load_FPR_ToTop(Reg,RegToLoad,Format); - } - static bool RegInStack ( int32_t Reg, CRegInfo::FPU_STATE Format ) - { - return m_RegWorkingSet.RegInStack(Reg,Format); - } - static x86FpuValues StackPosition ( int32_t Reg ) - { - return m_RegWorkingSet.StackPosition(Reg); - } - static void UnMap_AllFPRs() - { - m_RegWorkingSet.UnMap_AllFPRs(); - } - static void UnMap_FPR ( uint32_t Reg, bool WriteBackValue ) - { - m_RegWorkingSet.UnMap_FPR(Reg,WriteBackValue); - } - - static x86Reg FreeX86Reg() - { - return m_RegWorkingSet.FreeX86Reg(); - } - static x86Reg Free8BitX86Reg() - { - return m_RegWorkingSet.Free8BitX86Reg(); - } - static void Map_GPR_32bit ( int32_t Reg, bool SignValue, int32_t MipsRegToLoad ) - { - m_RegWorkingSet.Map_GPR_32bit(Reg,SignValue,MipsRegToLoad); - } - static void Map_GPR_64bit ( int32_t Reg, int32_t MipsRegToLoad ) - { - m_RegWorkingSet.Map_GPR_64bit(Reg,MipsRegToLoad); - } - static x86Reg Get_MemoryStack() - { - return m_RegWorkingSet.Get_MemoryStack(); - } - static x86Reg Map_MemoryStack ( x86Reg Reg, bool bMapRegister, bool LoadValue = true ) - { - return m_RegWorkingSet.Map_MemoryStack(Reg,bMapRegister,LoadValue); - } - static x86Reg Map_TempReg ( x86Reg Reg, int32_t MipsReg, bool LoadHiWord ) - { - return m_RegWorkingSet.Map_TempReg(Reg,MipsReg,LoadHiWord); - } - static void ProtectGPR ( uint32_t Reg ) - { - m_RegWorkingSet.ProtectGPR(Reg); - } - static void UnProtectGPR ( uint32_t Reg ) - { - m_RegWorkingSet.UnProtectGPR(Reg); - } - static void ResetX86Protection() - { - m_RegWorkingSet.ResetX86Protection(); - } - static x86Reg UnMap_TempReg() - { - return m_RegWorkingSet.UnMap_TempReg(); - } - static void UnMap_GPR ( uint32_t Reg, bool WriteBackValue ) - { - m_RegWorkingSet.UnMap_GPR(Reg,WriteBackValue); - } - static bool UnMap_X86reg ( x86Reg Reg ) - { - return m_RegWorkingSet.UnMap_X86reg(Reg); - } - -public: - static uint32_t CompilePC() { return m_CompilePC; } -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +class CCodeSection; + +class CRecompilerOps : + protected CDebugSettings, + protected CX86Ops, + protected CSystemRegisters, + protected CN64SystemSettings, + protected CRecompilerSettings +{ +protected: + enum BRANCH_TYPE + { + BranchTypeCop1, BranchTypeRs, BranchTypeRsRt + }; + + typedef void ( * BranchFunction )(); + + /************************** Branch functions ************************/ + static void Compile_Branch ( BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link); + static void Compile_BranchLikely ( BranchFunction CompareFunc, bool Link); + static void BNE_Compare(); + static void BEQ_Compare(); + static void BGTZ_Compare(); + static void BLEZ_Compare(); + static void BLTZ_Compare(); + static void BGEZ_Compare(); + static void COP1_BCF_Compare(); + static void COP1_BCT_Compare(); + + /************************* OpCode functions *************************/ + static void J (); + static void JAL (); + static void ADDI (); + static void ADDIU (); + static void SLTI (); + static void SLTIU (); + static void ANDI (); + static void ORI (); + static void XORI (); + static void LUI (); + static void DADDIU (); + // static void LDL (); + // static void LDR (); + // static void LB (); + // static void LH (); + // static void LWL (); + // static void LW (); + // static void LBU (); + // static void LHU (); + // static void LWR (); + // static void LWU (); //added by Witten + // static void SB (); + // static void SH (); + // static void SWL (); + // static void SW (); + // static void SWR (); + // static void SDL (); + // static void SDR (); + static void CACHE (); + // static void LL (); + // static void LWC1 (); + // static void LDC1 (); + // static void LD (); + // static void SC (); + // static void SWC1 (); + // static void SDC1 (); + // static void SD (); + + /********************** R4300i OpCodes: Special **********************/ + static void SPECIAL_SLL (); + static void SPECIAL_SRL (); + static void SPECIAL_SRA (); + static void SPECIAL_SLLV (); + static void SPECIAL_SRLV (); + static void SPECIAL_SRAV (); + static void SPECIAL_JR (); + static void SPECIAL_JALR (); + static void SPECIAL_SYSCALL(); + static void SPECIAL_MFLO (); + static void SPECIAL_MTLO (); + static void SPECIAL_MFHI (); + static void SPECIAL_MTHI (); + static void SPECIAL_DSLLV (); + static void SPECIAL_DSRLV (); + static void SPECIAL_DSRAV (); + static void SPECIAL_MULT (); + static void SPECIAL_MULTU (); + static void SPECIAL_DIV (); + static void SPECIAL_DIVU (); + static void SPECIAL_DMULT (); + static void SPECIAL_DMULTU (); + static void SPECIAL_DDIV (); + static void SPECIAL_DDIVU (); + static void SPECIAL_ADD (); + static void SPECIAL_ADDU (); + static void SPECIAL_SUB (); + static void SPECIAL_SUBU (); + static void SPECIAL_AND (); + static void SPECIAL_OR (); + static void SPECIAL_XOR (); + static void SPECIAL_NOR (); + static void SPECIAL_SLT (); + static void SPECIAL_SLTU (); + static void SPECIAL_DADD (); + static void SPECIAL_DADDU (); + static void SPECIAL_DSUB (); + static void SPECIAL_DSUBU (); + static void SPECIAL_DSLL (); + static void SPECIAL_DSRL (); + static void SPECIAL_DSRA (); + static void SPECIAL_DSLL32 (); + static void SPECIAL_DSRL32 (); + static void SPECIAL_DSRA32 (); + + /************************** COP0 functions **************************/ + static void COP0_MF (); + static void COP0_MT (); + + /************************** COP0 CO functions ***********************/ + static void COP0_CO_TLBR (); + static void COP0_CO_TLBWI (); + static void COP0_CO_TLBWR (); + static void COP0_CO_TLBP (); + static void COP0_CO_ERET (); + + /************************** COP1 functions **************************/ + static void COP1_MF (); + static void COP1_DMF (); + static void COP1_CF (); + static void COP1_MT (); + static void COP1_DMT (); + static void COP1_CT (); + + /************************** COP1: S functions ************************/ + static void COP1_S_ADD (); + static void COP1_S_SUB (); + static void COP1_S_MUL (); + static void COP1_S_DIV (); + static void COP1_S_ABS (); + static void COP1_S_NEG (); + static void COP1_S_SQRT (); + static void COP1_S_MOV (); + static void COP1_S_TRUNC_L (); + static void COP1_S_CEIL_L (); //added by Witten + static void COP1_S_FLOOR_L (); //added by Witten + static void COP1_S_ROUND_W (); + static void COP1_S_TRUNC_W (); + static void COP1_S_CEIL_W (); //added by Witten + static void COP1_S_FLOOR_W (); + static void COP1_S_CVT_D (); + static void COP1_S_CVT_W (); + static void COP1_S_CVT_L (); + static void COP1_S_CMP (); + + /************************** COP1: D functions ************************/ + static void COP1_D_ADD (); + static void COP1_D_SUB (); + static void COP1_D_MUL (); + static void COP1_D_DIV (); + static void COP1_D_ABS (); + static void COP1_D_NEG (); + static void COP1_D_SQRT (); + static void COP1_D_MOV (); + static void COP1_D_TRUNC_L (); //added by Witten + static void COP1_D_CEIL_L (); //added by Witten + static void COP1_D_FLOOR_L (); //added by Witten + static void COP1_D_ROUND_W (); + static void COP1_D_TRUNC_W (); + static void COP1_D_CEIL_W (); //added by Witten + static void COP1_D_FLOOR_W (); //added by Witten + static void COP1_D_CVT_S (); + static void COP1_D_CVT_W (); + static void COP1_D_CVT_L (); + static void COP1_D_CMP (); + + /************************** COP1: W functions ************************/ + static void COP1_W_CVT_S (); + static void COP1_W_CVT_D (); + + /************************** COP1: L functions ************************/ + static void COP1_L_CVT_S (); + static void COP1_L_CVT_D (); + + /************************** Other functions **************************/ + static void UnknownOpcode (); + + static void BeforeCallDirect(CRegInfo & RegSet); + static void AfterCallDirect(CRegInfo & RegSet); + static void EnterCodeBlock(); + static void ExitCodeBlock(); + static void CompileReadTLBMiss(uint32_t VirtualAddress, x86Reg LookUpReg); + static void CompileReadTLBMiss(x86Reg AddressReg, x86Reg LookUpReg); + static void CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg); + static void UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles); + static void UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false); + static void CompileSystemCheck(uint32_t TargetPC, const CRegInfo & RegSet); + static void ChangeDefaultRoundingModel(); + static void OverflowDelaySlot(bool TestTimer); + + static STEP_TYPE m_NextInstruction; + static uint32_t m_CompilePC; + static OPCODE m_Opcode; + static CRegInfo m_RegWorkingSet; + static uint32_t m_BranchCompare; + static CCodeSection * m_Section; + + /********* Helper Functions *********/ + typedef CRegInfo::REG_STATE REG_STATE; + + static REG_STATE GetMipsRegState ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegState(Reg); } + static uint64_t GetMipsReg ( int32_t Reg ) { return m_RegWorkingSet.GetMipsReg(Reg); } + static int64_t GetMipsReg_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsReg_S(Reg); } + static uint32_t GetMipsRegLo ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegLo(Reg); } + static int32_t GetMipsRegLo_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegLo_S(Reg); } + static uint32_t GetMipsRegHi ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegHi(Reg); } + static int32_t GetMipsRegHi_S ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegHi_S(Reg); } + static CX86Ops::x86Reg GetMipsRegMapLo ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegMapLo(Reg); } + static CX86Ops::x86Reg GetMipsRegMapHi ( int32_t Reg ) { return m_RegWorkingSet.GetMipsRegMapHi(Reg); } + + static bool IsKnown ( int32_t Reg ) { return m_RegWorkingSet.IsKnown(Reg); } + static bool IsUnknown ( int32_t Reg ) { return m_RegWorkingSet.IsUnknown(Reg); } + static bool IsMapped ( int32_t Reg ) { return m_RegWorkingSet.IsMapped(Reg); } + static bool IsConst ( int32_t Reg ) { return m_RegWorkingSet.IsConst(Reg); } + static bool IsSigned ( int32_t Reg ) { return m_RegWorkingSet.IsSigned(Reg); } + static bool IsUnsigned ( int32_t Reg ) { return m_RegWorkingSet.IsUnsigned(Reg); } + static bool Is32Bit ( int32_t Reg ) { return m_RegWorkingSet.Is32Bit(Reg); } + static bool Is64Bit ( int32_t Reg ) { return m_RegWorkingSet.Is64Bit(Reg); } + static bool Is32BitMapped ( int32_t Reg ) { return m_RegWorkingSet.Is32BitMapped(Reg); } + static bool Is64BitMapped ( int32_t Reg ) { return m_RegWorkingSet.Is64BitMapped(Reg); } + + static void FixRoundModel ( CRegInfo::FPU_ROUND RoundMethod ) + { + m_RegWorkingSet.FixRoundModel(RoundMethod); + } + static void ChangeFPURegFormat ( int32_t Reg, CRegInfo::FPU_STATE OldFormat, CRegInfo::FPU_STATE NewFormat, CRegInfo::FPU_ROUND RoundingModel ) + { + m_RegWorkingSet.ChangeFPURegFormat(Reg,OldFormat,NewFormat,RoundingModel); + } + static void Load_FPR_ToTop ( int32_t Reg, int32_t RegToLoad, CRegInfo::FPU_STATE Format) + { + m_RegWorkingSet.Load_FPR_ToTop(Reg,RegToLoad,Format); + } + static bool RegInStack ( int32_t Reg, CRegInfo::FPU_STATE Format ) + { + return m_RegWorkingSet.RegInStack(Reg,Format); + } + static x86FpuValues StackPosition ( int32_t Reg ) + { + return m_RegWorkingSet.StackPosition(Reg); + } + static void UnMap_AllFPRs() + { + m_RegWorkingSet.UnMap_AllFPRs(); + } + static void UnMap_FPR ( uint32_t Reg, bool WriteBackValue ) + { + m_RegWorkingSet.UnMap_FPR(Reg,WriteBackValue); + } + + static x86Reg FreeX86Reg() + { + return m_RegWorkingSet.FreeX86Reg(); + } + static x86Reg Free8BitX86Reg() + { + return m_RegWorkingSet.Free8BitX86Reg(); + } + static void Map_GPR_32bit ( int32_t Reg, bool SignValue, int32_t MipsRegToLoad ) + { + m_RegWorkingSet.Map_GPR_32bit(Reg,SignValue,MipsRegToLoad); + } + static void Map_GPR_64bit ( int32_t Reg, int32_t MipsRegToLoad ) + { + m_RegWorkingSet.Map_GPR_64bit(Reg,MipsRegToLoad); + } + static x86Reg Get_MemoryStack() + { + return m_RegWorkingSet.Get_MemoryStack(); + } + static x86Reg Map_MemoryStack ( x86Reg Reg, bool bMapRegister, bool LoadValue = true ) + { + return m_RegWorkingSet.Map_MemoryStack(Reg,bMapRegister,LoadValue); + } + static x86Reg Map_TempReg ( x86Reg Reg, int32_t MipsReg, bool LoadHiWord ) + { + return m_RegWorkingSet.Map_TempReg(Reg,MipsReg,LoadHiWord); + } + static void ProtectGPR ( uint32_t Reg ) + { + m_RegWorkingSet.ProtectGPR(Reg); + } + static void UnProtectGPR ( uint32_t Reg ) + { + m_RegWorkingSet.UnProtectGPR(Reg); + } + static void ResetX86Protection() + { + m_RegWorkingSet.ResetX86Protection(); + } + static x86Reg UnMap_TempReg() + { + return m_RegWorkingSet.UnMap_TempReg(); + } + static void UnMap_GPR ( uint32_t Reg, bool WriteBackValue ) + { + m_RegWorkingSet.UnMap_GPR(Reg,WriteBackValue); + } + static bool UnMap_X86reg ( x86Reg Reg ) + { + return m_RegWorkingSet.UnMap_X86reg(Reg); + } + +public: + static uint32_t CompilePC() { return m_CompilePC; } +}; diff --git a/Source/Project64-core/N64System/Recompiler/RegInfo.cpp b/Source/Project64-core/N64System/Recompiler/RegInfo.cpp index 510ce69cc..f799014b3 100644 --- a/Source/Project64-core/N64System/Recompiler/RegInfo.cpp +++ b/Source/Project64-core/N64System/Recompiler/RegInfo.cpp @@ -1,1470 +1,1470 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include - -#include -#include -#include -#include "x86CodeLog.h" - -uint32_t CRegInfo::m_fpuControl = 0; - -const char *Format_Name[] = { "Unknown", "dword", "qword", "float", "double" }; - -CRegInfo::CRegInfo() : -m_CycleCount(0), -m_Stack_TopPos(0), -m_Fpu_Used(false), -m_RoundingModel(RoundUnknown) -{ - m_MIPS_RegState[0] = STATE_CONST_32_SIGN; - m_MIPS_RegVal[0].DW = 0; - m_RegMapLo[0] = x86_Unknown; - m_RegMapHi[0] = x86_Unknown; - - for (int32_t i = 1; i < 32; i++) - { - m_MIPS_RegState[i] = STATE_UNKNOWN; - m_MIPS_RegVal[i].DW = 0; - m_RegMapLo[i] = x86_Unknown; - m_RegMapHi[i] = x86_Unknown; - } - for (int32_t i = 0, n = sizeof(m_x86reg_MappedTo) / sizeof(m_x86reg_MappedTo[0]); i < n; i++) - { - m_x86reg_MappedTo[i] = NotMapped; - m_x86reg_Protected[i] = false; - m_x86reg_MapOrder[i] = 0; - } - for (int32_t i = 0, n = sizeof(m_x86fpu_MappedTo) / sizeof(m_x86fpu_MappedTo[0]); i < n; i++) - { - m_x86fpu_MappedTo[i] = -1; - m_x86fpu_State[i] = FPU_Unknown; - m_x86fpu_StateChanged[i] = false; - m_x86fpu_RoundingModel[i] = RoundDefault; - } -} - -CRegInfo::CRegInfo(const CRegInfo& rhs) -{ - *this = rhs; -} - -CRegInfo::~CRegInfo() -{ -} - -CRegInfo& CRegInfo::operator=(const CRegInfo& right) -{ - m_CycleCount = right.m_CycleCount; - m_Stack_TopPos = right.m_Stack_TopPos; - m_Fpu_Used = right.m_Fpu_Used; - m_RoundingModel = right.m_RoundingModel; - - memcpy(&m_MIPS_RegState, &right.m_MIPS_RegState, sizeof(m_MIPS_RegState)); - memcpy(&m_MIPS_RegVal, &right.m_MIPS_RegVal, sizeof(m_MIPS_RegVal)); - memcpy(&m_RegMapLo, &right.m_RegMapLo, sizeof(m_RegMapLo)); - memcpy(&m_RegMapHi, &right.m_RegMapHi, sizeof(m_RegMapHi)); - memcpy(&m_x86reg_MappedTo, &right.m_x86reg_MappedTo, sizeof(m_x86reg_MappedTo)); - memcpy(&m_x86reg_Protected, &right.m_x86reg_Protected, sizeof(m_x86reg_Protected)); - memcpy(&m_x86reg_MapOrder, &right.m_x86reg_MapOrder, sizeof(m_x86reg_MapOrder)); - - memcpy(&m_x86fpu_MappedTo, &right.m_x86fpu_MappedTo, sizeof(m_x86fpu_MappedTo)); - memcpy(&m_x86fpu_State, &right.m_x86fpu_State, sizeof(m_x86fpu_State)); - memcpy(&m_x86fpu_StateChanged, &right.m_x86fpu_StateChanged, sizeof(m_x86fpu_StateChanged)); - memcpy(&m_x86fpu_RoundingModel, &right.m_x86fpu_RoundingModel, sizeof(m_x86fpu_RoundingModel)); - -#ifdef _DEBUG - if (*this != right) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } -#endif - return *this; -} - -bool CRegInfo::operator==(const CRegInfo& right) const -{ - int32_t count; - - for (count = 0; count < 32; count++) - { - if (m_MIPS_RegState[count] != right.m_MIPS_RegState[count]) - { - return false; - } - if (m_MIPS_RegState[count] == STATE_UNKNOWN) - { - continue; - } - if (m_MIPS_RegVal[count].DW != right.m_MIPS_RegVal[count].DW) - { - return false; - } - } - for (count = 0; count < 10; count++) - { - if (m_x86reg_MappedTo[count] != right.m_x86reg_MappedTo[count]) { return false; } - if (m_x86reg_Protected[count] != right.m_x86reg_Protected[count]) { return false; } - if (m_x86reg_MapOrder[count] != right.m_x86reg_MapOrder[count]) { return false; } - } - if (m_CycleCount != right.m_CycleCount) { return false; } - if (m_Stack_TopPos != right.m_Stack_TopPos) { return false; } - - for (count = 0; count < 8; count++) - { - if (m_x86fpu_MappedTo[count] != right.m_x86fpu_MappedTo[count]) { return false; } - if (m_x86fpu_State[count] != right.m_x86fpu_State[count]) { return false; } - if (m_x86fpu_RoundingModel[count] != right.m_x86fpu_RoundingModel[count]) { return false; } - } - if (m_Fpu_Used != right.m_Fpu_Used) { return false; } - if (GetRoundingModel() != right.GetRoundingModel()) { return false; } - return true; -} - -bool CRegInfo::operator!=(const CRegInfo& right) const -{ - return !(right == *this); -} - -CRegInfo::REG_STATE CRegInfo::ConstantsType(int64_t Value) -{ - if (((Value >> 32) == -1) && ((Value & 0x80000000) != 0)) { return STATE_CONST_32_SIGN; } - if (((Value >> 32) == 0) && ((Value & 0x80000000) == 0)) { return STATE_CONST_32_SIGN; } - return STATE_CONST_64; -} - -void CRegInfo::FixRoundModel(FPU_ROUND RoundMethod) -{ - if (GetRoundingModel() == RoundMethod) - { - return; - } - CPU_Message(" FixRoundModel: CurrentRoundingModel: %s targetRoundModel: %s", RoundingModelName(GetRoundingModel()), RoundingModelName(RoundMethod)); - - m_fpuControl = 0; - fpuStoreControl(&m_fpuControl, "m_fpuControl"); - x86Reg reg = Map_TempReg(x86_Any, -1, false); - MoveVariableToX86reg(&m_fpuControl, "m_fpuControl", reg); - AndConstToX86Reg(reg, 0xF3FF); - - if (RoundMethod == RoundDefault) - { - static const unsigned int msRound[4] = { _RC_NEAR, _RC_CHOP, _RC_UP, _RC_DOWN }; - - x86Reg RoundReg = Map_TempReg(x86_Any, -1, false); - MoveVariableToX86reg(&g_Reg->m_RoundingModel, "m_RoundingModel", RoundReg); - MoveVariableDispToX86Reg((void *)&msRound[0], "msRound", RoundReg, RoundReg, Multip_x4); - - ShiftLeftSignImmed(RoundReg, 2); - OrX86RegToX86Reg(reg, RoundReg); - SetX86Protected(RoundReg, false); - } - else - { - switch (RoundMethod) - { - case RoundTruncate: OrConstToX86Reg(0x0C00, reg); break; - case RoundNearest: /*OrConstToX86Reg(0x0000, reg);*/ break; - case RoundDown: OrConstToX86Reg(0x0400, reg); break; - case RoundUp: OrConstToX86Reg(0x0800, reg); break; - default: - g_Notify->DisplayError("Unknown Rounding model"); - } - } - MoveX86regToVariable(reg, &m_fpuControl, "m_fpuControl"); - SetX86Protected(reg, false); - fpuLoadControl(&m_fpuControl, "m_fpuControl"); - SetRoundingModel(RoundMethod); -} - -void CRegInfo::ChangeFPURegFormat(int32_t Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel) -{ - for (uint32_t i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] != Reg) - { - continue; - } - if (m_x86fpu_State[i] != OldFormat || m_x86fpu_StateChanged[i]) - { - UnMap_FPR(Reg, true); - Load_FPR_ToTop(Reg, Reg, OldFormat); - } - else - { - CPU_Message(" regcache: Changed format of ST(%d) from %s to %s", (i - StackTopPos() + 8) & 7, Format_Name[OldFormat], Format_Name[NewFormat]); - } - FpuRoundingModel(i) = RoundingModel; - m_x86fpu_State[i] = NewFormat; - m_x86fpu_StateChanged[i] = true; - return; - } - - if (bHaveDebugger()) - { - g_Notify->DisplayError("ChangeFormat: Register not on stack!!"); - } -} - -void CRegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Format) -{ - if (GetRoundingModel() != RoundDefault) - { - FixRoundModel(RoundDefault); - } - CPU_Message("CurrentRoundingModel: %s FpuRoundingModel(StackTopPos()): %s", RoundingModelName(GetRoundingModel()), RoundingModelName(FpuRoundingModel(StackTopPos()))); - int32_t i; - - if (RegToLoad < 0) { g_Notify->DisplayError("Load_FPR_ToTop\nRegToLoad < 0 ???"); return; } - if (Reg < 0) { g_Notify->DisplayError("Load_FPR_ToTop\nReg < 0 ???"); return; } - - if (Format == FPU_Double || Format == FPU_Qword) - { - UnMap_FPR(Reg + 1, true); - UnMap_FPR(RegToLoad + 1, true); - } - else - { - if ((Reg & 1) != 0) - { - for (i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] == (Reg - 1)) - { - if (m_x86fpu_State[i] == FPU_Double || m_x86fpu_State[i] == FPU_Qword) - { - UnMap_FPR(Reg, true); - } - i = 8; - } - } - } - if ((RegToLoad & 1) != 0) - { - for (i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] == (RegToLoad - 1)) - { - if (m_x86fpu_State[i] == FPU_Double || m_x86fpu_State[i] == FPU_Qword) - { - UnMap_FPR(RegToLoad, true); - } - i = 8; - } - } - } - } - - if (Reg == RegToLoad) - { - //if different format then unmap original reg from stack - for (i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] != Reg) - { - continue; - } - if (m_x86fpu_State[i] != Format) - { - UnMap_FPR(Reg, true); - } - break; - } - } - else - { - //if different format then unmap original reg from stack - for (i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] != Reg) - { - continue; - } - UnMap_FPR(Reg, m_x86fpu_State[i] != Format); - break; - } - } - - if (RegInStack(RegToLoad, Format)) - { - if (Reg != RegToLoad) - { - if (m_x86fpu_MappedTo[(StackTopPos() - 1) & 7] != RegToLoad) - { - UnMap_FPR(m_x86fpu_MappedTo[(StackTopPos() - 1) & 7], true); - CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]); - fpuLoadReg(&StackTopPos(), StackPosition(RegToLoad)); - FpuRoundingModel(StackTopPos()) = RoundDefault; - m_x86fpu_MappedTo[StackTopPos()] = Reg; - m_x86fpu_State[StackTopPos()] = Format; - m_x86fpu_StateChanged[StackTopPos()] = false; - } - else - { - UnMap_FPR(m_x86fpu_MappedTo[(StackTopPos() - 1) & 7], true); - Load_FPR_ToTop(Reg, RegToLoad, Format); - } - } - else - { - x86FpuValues RegPos = x86_ST_Unknown; - for (uint32_t i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] == Reg) - { - RegPos = (x86FpuValues)i; - i = 8; - } - } - - if (RegPos == StackTopPos()) - { - return; - } - x86FpuValues StackPos = StackPosition(Reg); - - FpuRoundingModel(RegPos) = FpuRoundingModel(StackTopPos()); - m_x86fpu_MappedTo[RegPos] = m_x86fpu_MappedTo[StackTopPos()]; - m_x86fpu_State[RegPos] = m_x86fpu_State[StackTopPos()]; - m_x86fpu_StateChanged[RegPos] = m_x86fpu_StateChanged[StackTopPos()]; - CPU_Message(" regcache: allocate ST(%d) to %s", StackPos, CRegName::FPR[m_x86fpu_MappedTo[RegPos]]); - CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]); - - fpuExchange(StackPos); - - FpuRoundingModel(StackTopPos()) = RoundDefault; - m_x86fpu_MappedTo[StackTopPos()] = Reg; - m_x86fpu_State[StackTopPos()] = Format; - m_x86fpu_StateChanged[StackTopPos()] = false; - } - } - else - { - char Name[50]; - x86Reg TempReg; - - UnMap_FPR(m_x86fpu_MappedTo[(StackTopPos() - 1) & 7], true); - for (i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] == RegToLoad) - { - UnMap_FPR(RegToLoad, true); - i = 8; - } - } - CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]); - TempReg = Map_TempReg(x86_Any, -1, false); - switch (Format) - { - case FPU_Dword: - sprintf(Name, "m_FPR_S[%d]", RegToLoad); - MoveVariableToX86reg(&g_Reg->m_FPR_S[RegToLoad], Name, TempReg); - fpuLoadIntegerDwordFromX86Reg(&StackTopPos(), TempReg); - break; - case FPU_Qword: - sprintf(Name, "m_FPR_D[%d]", RegToLoad); - MoveVariableToX86reg(&g_Reg->m_FPR_D[RegToLoad], Name, TempReg); - fpuLoadIntegerQwordFromX86Reg(&StackTopPos(), TempReg); - break; - case FPU_Float: - sprintf(Name, "m_FPR_S[%d]", RegToLoad); - MoveVariableToX86reg(&g_Reg->m_FPR_S[RegToLoad], Name, TempReg); - fpuLoadDwordFromX86Reg(&StackTopPos(), TempReg); - break; - case FPU_Double: - sprintf(Name, "m_FPR_D[%d]", RegToLoad); - MoveVariableToX86reg(&g_Reg->m_FPR_D[RegToLoad], Name, TempReg); - fpuLoadQwordFromX86Reg(&StackTopPos(), TempReg); - break; - default: - if (bHaveDebugger()) { g_Notify->DisplayError(stdstr_f("Load_FPR_ToTop\nUnkown format to load %d", Format).c_str()); } - } - SetX86Protected(TempReg, false); - FpuRoundingModel(StackTopPos()) = RoundDefault; - m_x86fpu_MappedTo[StackTopPos()] = Reg; - m_x86fpu_State[StackTopPos()] = Format; - m_x86fpu_StateChanged[StackTopPos()] = false; - } -} - -CRegInfo::x86FpuValues CRegInfo::StackPosition(int32_t Reg) -{ - int32_t i; - - for (i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] == Reg) - { - return (x86FpuValues)((i - StackTopPos()) & 7); - } - } - return x86_ST_Unknown; -} - -CX86Ops::x86Reg CRegInfo::FreeX86Reg() -{ - if (GetX86Mapped(x86_EDI) == NotMapped && !GetX86Protected(x86_EDI)) { return x86_EDI; } - if (GetX86Mapped(x86_ESI) == NotMapped && !GetX86Protected(x86_ESI)) { return x86_ESI; } - if (GetX86Mapped(x86_EBX) == NotMapped && !GetX86Protected(x86_EBX)) { return x86_EBX; } - if (GetX86Mapped(x86_EAX) == NotMapped && !GetX86Protected(x86_EAX)) { return x86_EAX; } - if (GetX86Mapped(x86_EDX) == NotMapped && !GetX86Protected(x86_EDX)) { return x86_EDX; } - if (GetX86Mapped(x86_ECX) == NotMapped && !GetX86Protected(x86_ECX)) { return x86_ECX; } - - x86Reg Reg = UnMap_TempReg(); - if (Reg != x86_Unknown) { return Reg; } - - int32_t count, MapCount[10]; - x86Reg MapReg[10]; - - for (count = 0; count < 10; count++) - { - MapCount[count] = GetX86MapOrder((x86Reg)count); - MapReg[count] = (x86Reg)count; - } - for (count = 0; count < 10; count++) - { - int32_t i; - - for (i = 0; i < 9; i++) - { - x86Reg tempReg; - uint32_t temp; - - if (MapCount[i] < MapCount[i + 1]) - { - temp = MapCount[i]; - MapCount[i] = MapCount[i + 1]; - MapCount[i + 1] = temp; - tempReg = MapReg[i]; - MapReg[i] = MapReg[i + 1]; - MapReg[i + 1] = tempReg; - } - } - } - - x86Reg StackReg = x86_Unknown; - for (count = 0; count < 10; count++) - { - if (MapCount[count] > 0 && GetX86Mapped(MapReg[count]) != Stack_Mapped) - { - if (UnMap_X86reg((x86Reg)MapReg[count])) - { - return (x86Reg)MapReg[count]; - } - } - if (GetX86Mapped(MapReg[count]) == Stack_Mapped) { StackReg = MapReg[count]; } - } - if (StackReg != x86_Unknown) - { - UnMap_X86reg(StackReg); - return StackReg; - } - - return x86_Unknown; -} - -CX86Ops::x86Reg CRegInfo::Free8BitX86Reg() -{ - if (GetX86Mapped(x86_EBX) == NotMapped && !GetX86Protected(x86_EBX)) { return x86_EBX; } - if (GetX86Mapped(x86_EAX) == NotMapped && !GetX86Protected(x86_EAX)) { return x86_EAX; } - if (GetX86Mapped(x86_EDX) == NotMapped && !GetX86Protected(x86_EDX)) { return x86_EDX; } - if (GetX86Mapped(x86_ECX) == NotMapped && !GetX86Protected(x86_ECX)) { return x86_ECX; } - - x86Reg Reg = UnMap_8BitTempReg(); - if (Reg > 0) { return Reg; } - - int32_t count, MapCount[10], MapReg[10]; - for (count = 0; count < 10; count++) - { - MapCount[count] = GetX86MapOrder((x86Reg)count); - MapReg[count] = count; - } - for (count = 0; count < 10; count++) - { - int32_t i; - - for (i = 0; i < 9; i++) - { - int32_t temp; - - if (MapCount[i] < MapCount[i + 1]) - { - temp = MapCount[i]; - MapCount[i] = MapCount[i + 1]; - MapCount[i + 1] = temp; - temp = MapReg[i]; - MapReg[i] = MapReg[i + 1]; - MapReg[i + 1] = temp; - } - } - } - for (count = 0; count < 10; count++) - { - if (MapCount[count] > 0) - { - if (!Is8BitReg((x86Reg)count)) { continue; } - if (UnMap_X86reg((x86Reg)count)) - { - return (x86Reg)count; - } - } - } - return x86_Unknown; -} - -CX86Ops::x86Reg CRegInfo::UnMap_8BitTempReg() -{ - int32_t count; - - for (count = 0; count < 10; count++) - { - if (!Is8BitReg((x86Reg)count)) { continue; } - if (GetX86Mapped((x86Reg)count) == Temp_Mapped) - { - if (GetX86Protected((x86Reg)count) == false) - { - CPU_Message(" regcache: unallocate %s from temp storage", x86_Name((x86Reg)count)); - SetX86Mapped((x86Reg)count, CRegInfo::NotMapped); - return (x86Reg)count; - } - } - } - return x86_Unknown; -} - -CRegInfo::x86Reg CRegInfo::Get_MemoryStack() const -{ - for (int32_t i = 0, n = sizeof(x86_Registers) / sizeof(x86_Registers[0]); i < n; i++) - { - if (GetX86Mapped(x86_Registers[i]) == Stack_Mapped) - { - return x86_Registers[i]; - } - } - return x86_Unknown; -} - -CRegInfo::x86Reg CRegInfo::Map_MemoryStack(x86Reg Reg, bool bMapRegister, bool LoadValue) -{ - x86Reg CurrentMap = Get_MemoryStack(); - if (!bMapRegister) - { - //if not mapping then just return what the current mapping is - return CurrentMap; - } - - if (CurrentMap != x86_Unknown && CurrentMap == Reg) - { - //already mapped to correct reg - return CurrentMap; - } - // map a register - if (Reg == x86_Any) - { - if (CurrentMap != x86_Unknown) - { - return CurrentMap; - } - Reg = FreeX86Reg(); - if (Reg == x86_Unknown) - { - g_Notify->DisplayError("Map_MemoryStack\n\nOut of registers"); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - SetX86Mapped(Reg, CRegInfo::Stack_Mapped); - CPU_Message(" regcache: allocate %s as Memory Stack", x86_Name(Reg)); - if (LoadValue) - { - MoveVariableToX86reg(&g_Recompiler->MemoryStackPos(), "MemoryStack", Reg); - } - return Reg; - } - - //move to a register/allocate register - UnMap_X86reg(Reg); - if (CurrentMap != x86_Unknown) - { - CPU_Message(" regcache: change allocation of Memory Stack from %s to %s", x86_Name(CurrentMap), x86_Name(Reg)); - SetX86Mapped(Reg, CRegInfo::Stack_Mapped); - SetX86Mapped(CurrentMap, CRegInfo::NotMapped); - MoveX86RegToX86Reg(CurrentMap, Reg); - } - else - { - SetX86Mapped(Reg, CRegInfo::Stack_Mapped); - CPU_Message(" regcache: allocate %s as Memory Stack", x86_Name(Reg)); - if (LoadValue) - { - MoveVariableToX86reg(&g_Recompiler->MemoryStackPos(), "MemoryStack", Reg); - } - } - return Reg; -} - -void CRegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsRegToLoad) -{ - int32_t count; - - x86Reg Reg; - if (MipsReg == 0) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - - if (IsUnknown(MipsReg) || IsConst(MipsReg)) - { - Reg = FreeX86Reg(); - if (Reg < 0) - { - if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_32bit\n\nOut of registers"); } - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - CPU_Message(" regcache: allocate %s to %s", x86_Name(Reg), CRegName::GPR[MipsReg]); - } - else - { - if (Is64Bit(MipsReg)) - { - CPU_Message(" regcache: unallocate %s from high 32bit of %s", x86_Name(GetMipsRegMapHi(MipsReg)), CRegName::GPR_Hi[MipsReg]); - SetX86MapOrder(GetMipsRegMapHi(MipsReg), 0); - SetX86Mapped(GetMipsRegMapHi(MipsReg), NotMapped); - SetX86Protected(GetMipsRegMapHi(MipsReg), false); - SetMipsRegHi(MipsReg, 0); - } - Reg = GetMipsRegMapLo(MipsReg); - } - for (count = 0; count < 10; count++) - { - uint32_t Count = GetX86MapOrder((x86Reg)count); - if (Count > 0) - { - SetX86MapOrder((x86Reg)count, Count + 1); - } - } - SetX86MapOrder(Reg, 1); - - if (MipsRegToLoad > 0) - { - if (IsUnknown(MipsRegToLoad)) - { - MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0], CRegName::GPR_Lo[MipsRegToLoad], Reg); - } - else if (IsMapped(MipsRegToLoad)) - { - if (MipsReg != MipsRegToLoad) - { - MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), Reg); - } - } - else - { - MoveConstToX86reg(GetMipsRegLo(MipsRegToLoad), Reg); - } - } - else if (MipsRegToLoad == 0) - { - XorX86RegToX86Reg(Reg, Reg); - } - SetX86Mapped(Reg, GPR_Mapped); - SetX86Protected(Reg, true); - SetMipsRegMapLo(MipsReg, Reg); - SetMipsRegState(MipsReg, SignValue ? STATE_MAPPED_32_SIGN : STATE_MAPPED_32_ZERO); -} - -void CRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad) -{ - x86Reg x86Hi, x86lo; - int32_t count; - - if (MipsReg == 0) - { - if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_32bit\n\nWhy are you trying to map reg 0"); } - return; - } - - ProtectGPR(MipsReg); - if (IsUnknown(MipsReg) || IsConst(MipsReg)) - { - x86Hi = FreeX86Reg(); - if (x86Hi < 0) - { - if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); } - return; - } - SetX86Protected(x86Hi, true); - - x86lo = FreeX86Reg(); - if (x86lo < 0) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); return; } - SetX86Protected(x86lo, true); - - CPU_Message(" regcache: allocate %s to hi word of %s", x86_Name(x86Hi), CRegName::GPR[MipsReg]); - CPU_Message(" regcache: allocate %s to low word of %s", x86_Name(x86lo), CRegName::GPR[MipsReg]); - } - else - { - x86lo = GetMipsRegMapLo(MipsReg); - if (Is32Bit(MipsReg)) - { - SetX86Protected(x86lo, true); - x86Hi = FreeX86Reg(); - if (x86Hi == x86_Unknown) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - SetX86Protected(x86Hi, true); - - CPU_Message(" regcache: allocate %s to hi word of %s", x86_Name(x86Hi), CRegName::GPR[MipsReg]); - } - else - { - x86Hi = GetMipsRegMapHi(MipsReg); - } - } - - for (count = 0; count < 10; count++) - { - int32_t MapOrder = GetX86MapOrder((x86Reg)count); - if (MapOrder > 0) - { - SetX86MapOrder((x86Reg)count, MapOrder + 1); - } - } - - SetX86MapOrder(x86Hi, 1); - SetX86MapOrder(x86lo, 1); - if (MipsRegToLoad > 0) - { - if (IsUnknown(MipsRegToLoad)) - { - MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[1], CRegName::GPR_Hi[MipsRegToLoad], x86Hi); - MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0], CRegName::GPR_Lo[MipsRegToLoad], x86lo); - } - else if (IsMapped(MipsRegToLoad)) - { - if (Is32Bit(MipsRegToLoad)) - { - if (IsSigned(MipsRegToLoad)) - { - MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86Hi); - ShiftRightSignImmed(x86Hi, 31); - } - else - { - XorX86RegToX86Reg(x86Hi, x86Hi); - } - if (MipsReg != MipsRegToLoad) - { - MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86lo); - } - } - else - { - if (MipsReg != MipsRegToLoad) - { - MoveX86RegToX86Reg(GetMipsRegMapHi(MipsRegToLoad), x86Hi); - MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86lo); - } - } - } - else - { - CPU_Message("Map_GPR_64bit 11"); - if (Is32Bit(MipsRegToLoad)) - { - if (IsSigned(MipsRegToLoad)) - { - MoveConstToX86reg(GetMipsRegLo_S(MipsRegToLoad) >> 31, x86Hi); - } - else - { - MoveConstToX86reg(0, x86Hi); - } - } - else - { - MoveConstToX86reg(GetMipsRegHi(MipsRegToLoad), x86Hi); - } - MoveConstToX86reg(GetMipsRegLo(MipsRegToLoad), x86lo); - } - } - else if (MipsRegToLoad == 0) - { - XorX86RegToX86Reg(x86Hi, x86Hi); - XorX86RegToX86Reg(x86lo, x86lo); - } - SetX86Mapped(x86Hi, GPR_Mapped); - SetX86Mapped(x86lo, GPR_Mapped); - SetMipsRegMapHi(MipsReg, x86Hi); - SetMipsRegMapLo(MipsReg, x86lo); - SetMipsRegState(MipsReg, STATE_MAPPED_64); -} - -CX86Ops::x86Reg CRegInfo::Map_TempReg(CX86Ops::x86Reg Reg, int32_t MipsReg, bool LoadHiWord) -{ - int32_t count; - - if (Reg == x86_Any) - { - if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } - else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } - else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } - else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } - else if (GetX86Mapped(x86_ESI) == Temp_Mapped && !GetX86Protected(x86_ESI)) { Reg = x86_ESI; } - else if (GetX86Mapped(x86_EDI) == Temp_Mapped && !GetX86Protected(x86_EDI)) { Reg = x86_EDI; } - else if (GetX86Mapped(x86_EBP) == Temp_Mapped && !GetX86Protected(x86_EBP)) { Reg = x86_EBP; } - else if (GetX86Mapped(x86_ESP) == Temp_Mapped && !GetX86Protected(x86_ESP)) { Reg = x86_ESP; } - - if (Reg == x86_Any) - { - Reg = FreeX86Reg(); - if (Reg == x86_Unknown) - { - WriteTrace(TraceRegisterCache, TraceError, "Failed to find a free register"); - g_Notify->BreakPoint(__FILE__, __LINE__); - return x86_Unknown; - } - } - } - else if (Reg == x86_Any8Bit) - { - if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } - else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } - else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } - else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } - - if (Reg == x86_Any8Bit) - { - Reg = Free8BitX86Reg(); - if (Reg < 0) - { - WriteTrace(TraceRegisterCache, TraceError, "Failed to find a free 8 bit register"); - g_Notify->BreakPoint(__FILE__, __LINE__); - return x86_Unknown; - } - } - } - else if (GetX86Mapped(Reg) == GPR_Mapped) - { - if (GetX86Protected(Reg)) - { - WriteTrace(TraceRegisterCache, TraceError, "Register is protected"); - g_Notify->BreakPoint(__FILE__, __LINE__); - return x86_Unknown; - } - - SetX86Protected(Reg, true); - x86Reg NewReg = FreeX86Reg(); - for (count = 1; count < 32; count++) - { - if (!IsMapped(count)) - { - continue; - } - if (GetMipsRegMapLo(count) == Reg) - { - if (NewReg == x86_Unknown) - { - UnMap_GPR(count, true); - break; - } - CPU_Message(" regcache: change allocation of %s from %s to %s", CRegName::GPR[count], x86_Name(Reg), x86_Name(NewReg)); - SetX86Mapped(NewReg, GPR_Mapped); - SetX86MapOrder(NewReg, GetX86MapOrder(Reg)); - SetMipsRegMapLo(count, NewReg); - MoveX86RegToX86Reg(Reg, NewReg); - if (MipsReg == count && !LoadHiWord) - { - MipsReg = -1; - } - break; - } - if (Is64Bit(count) && GetMipsRegMapHi(count) == Reg) - { - if (NewReg == x86_Unknown) - { - UnMap_GPR(count, true); - break; - } - CPU_Message(" regcache: change allocation of %s from %s to %s", CRegName::GPR_Hi[count], x86_Name(Reg), x86_Name(NewReg)); - SetX86Mapped(NewReg, GPR_Mapped); - SetX86MapOrder(NewReg, GetX86MapOrder(Reg)); - SetMipsRegMapHi(count, NewReg); - MoveX86RegToX86Reg(Reg, NewReg); - if (MipsReg == count && LoadHiWord) - { - MipsReg = -1; - } - break; - } - } - } - else if (GetX86Mapped(Reg) == Stack_Mapped) - { - UnMap_X86reg(Reg); - } - CPU_Message(" regcache: allocate %s as temp storage", x86_Name(Reg)); - - if (MipsReg >= 0) - { - if (LoadHiWord) - { - if (IsUnknown(MipsReg)) - { - MoveVariableToX86reg(&_GPR[MipsReg].UW[1], CRegName::GPR_Hi[MipsReg], Reg); - } - else if (IsMapped(MipsReg)) - { - if (Is64Bit(MipsReg)) - { - MoveX86RegToX86Reg(GetMipsRegMapHi(MipsReg), Reg); - } - else if (IsSigned(MipsReg)) - { - MoveX86RegToX86Reg(GetMipsRegMapLo(MipsReg), Reg); - ShiftRightSignImmed(Reg, 31); - } - else - { - MoveConstToX86reg(0, Reg); - } - } - else - { - if (Is64Bit(MipsReg)) - { - MoveConstToX86reg(GetMipsRegHi(MipsReg), Reg); - } - else - { - MoveConstToX86reg(GetMipsRegLo_S(MipsReg) >> 31, Reg); - } - } - } - else - { - if (IsUnknown(MipsReg)) - { - MoveVariableToX86reg(&_GPR[MipsReg].UW[0], CRegName::GPR_Lo[MipsReg], Reg); - } - else if (IsMapped(MipsReg)) - { - MoveX86RegToX86Reg(GetMipsRegMapLo(MipsReg), Reg); - } - else - { - MoveConstToX86reg(GetMipsRegLo(MipsReg), Reg); - } - } - } - SetX86Mapped(Reg, Temp_Mapped); - SetX86Protected(Reg, true); - for (count = 0; count < 10; count++) - { - int32_t MapOrder = GetX86MapOrder((x86Reg)count); - if (MapOrder > 0) - { - SetX86MapOrder((x86Reg)count, MapOrder + 1); - } - } - SetX86MapOrder(Reg, 1); - return Reg; -} - -void CRegInfo::ProtectGPR(uint32_t Reg) -{ - if (IsUnknown(Reg) || IsConst(Reg)) - { - return; - } - if (Is64Bit(Reg)) - { - SetX86Protected(GetMipsRegMapHi(Reg), true); - } - SetX86Protected(GetMipsRegMapLo(Reg), true); -} - -void CRegInfo::UnProtectGPR(uint32_t Reg) -{ - if (IsUnknown(Reg) || IsConst(Reg)) - { - return; - } - if (Is64Bit(Reg)) - { - SetX86Protected(GetMipsRegMapHi(Reg), false); - } - SetX86Protected(GetMipsRegMapLo(Reg), false); -} - -void CRegInfo::ResetX86Protection() -{ - for (int32_t count = 0; count < 10; count++) - { - SetX86Protected((x86Reg)count, false); - } -} - -bool CRegInfo::RegInStack(int32_t Reg, FPU_STATE Format) -{ - for (int32_t i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] == Reg) - { - if (m_x86fpu_State[i] == Format || Format == FPU_Any) - { - return true; - } - return false; - } - } - return false; -} - -void CRegInfo::UnMap_AllFPRs() -{ - for (;;) - { - int32_t StackPos = StackTopPos(); - if (m_x86fpu_MappedTo[StackPos] != -1) - { - UnMap_FPR(m_x86fpu_MappedTo[StackPos], true); - continue; - } - //see if any more registers mapped - int32_t StartPos = StackTopPos(); - for (int32_t i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[(StartPos + i) & 7] != -1) { fpuIncStack(&StackTopPos()); } - } - if (StackPos != StackTopPos()) { continue; } - return; - } -} - -void CRegInfo::UnMap_FPR(int32_t Reg, bool WriteBackValue) -{ - char Name[50]; - int32_t i; - - if (Reg < 0) { return; } - for (i = 0; i < 8; i++) - { - if (m_x86fpu_MappedTo[i] != Reg) { continue; } - CPU_Message(" regcache: unallocate %s from ST(%d)", CRegName::FPR[Reg], (i - StackTopPos() + 8) & 7); - if (WriteBackValue) - { - int32_t RegPos; - - if (((i - StackTopPos() + 8) & 7) != 0) - { - if (m_x86fpu_MappedTo[StackTopPos()] == -1 && m_x86fpu_MappedTo[(StackTopPos() + 1) & 7] == Reg) - { - fpuIncStack(&StackTopPos()); - } - else - { - CRegInfo::FPU_ROUND RoundingModel = FpuRoundingModel(StackTopPos()); - FPU_STATE RegState = m_x86fpu_State[StackTopPos()]; - bool Changed = m_x86fpu_StateChanged[StackTopPos()]; - uint32_t MappedTo = m_x86fpu_MappedTo[StackTopPos()]; - FpuRoundingModel(StackTopPos()) = FpuRoundingModel(i); - m_x86fpu_MappedTo[StackTopPos()] = m_x86fpu_MappedTo[i]; - m_x86fpu_State[StackTopPos()] = m_x86fpu_State[i]; - m_x86fpu_StateChanged[StackTopPos()] = m_x86fpu_StateChanged[i]; - FpuRoundingModel(i) = RoundingModel; - m_x86fpu_MappedTo[i] = MappedTo; - m_x86fpu_State[i] = RegState; - m_x86fpu_StateChanged[i] = Changed; - fpuExchange((x86FpuValues)((i - StackTopPos()) & 7)); - } - } - - FixRoundModel(FpuRoundingModel(i)); - - RegPos = StackTopPos(); - x86Reg TempReg = Map_TempReg(x86_Any, -1, false); - switch (m_x86fpu_State[StackTopPos()]) - { - case FPU_Dword: - sprintf(Name, "_FPR_S[%d]", m_x86fpu_MappedTo[StackTopPos()]); - MoveVariableToX86reg(&_FPR_S[m_x86fpu_MappedTo[StackTopPos()]], Name, TempReg); - fpuStoreIntegerDwordFromX86Reg(&StackTopPos(), TempReg, true); - break; - case FPU_Qword: - sprintf(Name, "_FPR_D[%d]", m_x86fpu_MappedTo[StackTopPos()]); - MoveVariableToX86reg(&_FPR_D[m_x86fpu_MappedTo[StackTopPos()]], Name, TempReg); - fpuStoreIntegerQwordFromX86Reg(&StackTopPos(), TempReg, true); - break; - case FPU_Float: - sprintf(Name, "_FPR_S[%d]", m_x86fpu_MappedTo[StackTopPos()]); - MoveVariableToX86reg(&_FPR_S[m_x86fpu_MappedTo[StackTopPos()]], Name, TempReg); - fpuStoreDwordFromX86Reg(&StackTopPos(), TempReg, true); - break; - case FPU_Double: - sprintf(Name, "_FPR_D[%d]", m_x86fpu_MappedTo[StackTopPos()]); - MoveVariableToX86reg(&_FPR_D[m_x86fpu_MappedTo[StackTopPos()]], Name, TempReg); - fpuStoreQwordFromX86Reg(&StackTopPos(), TempReg, true); - break; - default: - if (bHaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("%s\nUnknown format to load %d", __FUNCTION__, m_x86fpu_State[StackTopPos()]).c_str()); - } - } - SetX86Protected(TempReg, false); - FpuRoundingModel(RegPos) = RoundDefault; - m_x86fpu_MappedTo[RegPos] = -1; - m_x86fpu_State[RegPos] = FPU_Unknown; - m_x86fpu_StateChanged[RegPos] = false; - } - else - { - fpuFree((x86FpuValues)((i - StackTopPos()) & 7)); - FpuRoundingModel(i) = RoundDefault; - m_x86fpu_MappedTo[i] = -1; - m_x86fpu_State[i] = FPU_Unknown; - m_x86fpu_StateChanged[i] = false; - } - return; - } -} - -void CRegInfo::UnMap_GPR(uint32_t Reg, bool WriteBackValue) -{ - if (Reg == 0) - { - if (bHaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("%s\n\nWhy are you trying to unmap reg 0", __FUNCTION__).c_str()); - } - return; - } - - if (IsUnknown(Reg)) { return; } - //CPU_Message("UnMap_GPR: State: %X\tReg: %s\tWriteBack: %s",State,CRegName::GPR[Reg],WriteBackValue?"true":"false"); - if (IsConst(Reg)) - { - if (!WriteBackValue) - { - SetMipsRegState(Reg, STATE_UNKNOWN); - return; - } - if (Is64Bit(Reg)) - { - MoveConstToVariable(GetMipsRegHi(Reg), &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); - MoveConstToVariable(GetMipsRegLo(Reg), &_GPR[Reg].UW[0], CRegName::GPR_Lo[Reg]); - SetMipsRegState(Reg, STATE_UNKNOWN); - return; - } - if ((GetMipsRegLo(Reg) & 0x80000000) != 0) - { - MoveConstToVariable(0xFFFFFFFF, &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); - } - else - { - MoveConstToVariable(0, &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); - } - MoveConstToVariable(GetMipsRegLo(Reg), &_GPR[Reg].UW[0], CRegName::GPR_Lo[Reg]); - SetMipsRegState(Reg, STATE_UNKNOWN); - return; - } - if (Is64Bit(Reg)) - { - CPU_Message(" regcache: unallocate %s from %s", x86_Name(GetMipsRegMapHi(Reg)), CRegName::GPR_Hi[Reg]); - SetX86Mapped(GetMipsRegMapHi(Reg), NotMapped); - SetX86Protected(GetMipsRegMapHi(Reg), false); - } - CPU_Message(" regcache: unallocate %s from %s", x86_Name(GetMipsRegMapLo(Reg)), CRegName::GPR_Lo[Reg]); - SetX86Mapped(GetMipsRegMapLo(Reg), NotMapped); - SetX86Protected(GetMipsRegMapLo(Reg), false); - if (!WriteBackValue) - { - SetMipsRegState(Reg, STATE_UNKNOWN); - return; - } - MoveX86regToVariable(GetMipsRegMapLo(Reg), &_GPR[Reg].UW[0], CRegName::GPR_Lo[Reg]); - if (Is64Bit(Reg)) - { - SetMipsRegMapLo(Reg, x86_Unknown); - MoveX86regToVariable(GetMipsRegMapHi(Reg), &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); - SetMipsRegMapHi(Reg, x86_Unknown); - } - else - { - if (!g_System->b32BitCore()) - { - if (IsSigned(Reg)) - { - ShiftRightSignImmed(GetMipsRegMapLo(Reg), 31); - MoveX86regToVariable(GetMipsRegMapLo(Reg), &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); - } - else - { - MoveConstToVariable(0, &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); - } - } - SetMipsRegMapLo(Reg, x86_Unknown); - } - SetMipsRegState(Reg, STATE_UNKNOWN); -} - -CX86Ops::x86Reg CRegInfo::UnMap_TempReg() -{ - CX86Ops::x86Reg Reg = x86_Unknown; - - if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } - else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } - else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } - else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } - else if (GetX86Mapped(x86_ESI) == Temp_Mapped && !GetX86Protected(x86_ESI)) { Reg = x86_ESI; } - else if (GetX86Mapped(x86_EDI) == Temp_Mapped && !GetX86Protected(x86_EDI)) { Reg = x86_EDI; } - else if (GetX86Mapped(x86_EBP) == Temp_Mapped && !GetX86Protected(x86_EBP)) { Reg = x86_EBP; } - else if (GetX86Mapped(x86_ESP) == Temp_Mapped && !GetX86Protected(x86_ESP)) { Reg = x86_ESP; } - - if (Reg != x86_Unknown) - { - if (GetX86Mapped(Reg) == Temp_Mapped) - { - CPU_Message(" regcache: unallocate %s from temp storage", x86_Name(Reg)); - } - SetX86Mapped(Reg, NotMapped); - } - return Reg; -} - -bool CRegInfo::UnMap_X86reg(CX86Ops::x86Reg Reg) -{ - int32_t count; - - if (GetX86Mapped(Reg) == NotMapped) - { - if (!GetX86Protected(Reg)) - { - return true; - } - } - else if (GetX86Mapped(Reg) == CRegInfo::GPR_Mapped) - { - for (count = 1; count < 32; count++) - { - if (!IsMapped(count)) - { - continue; - } - - if (Is64Bit(count) && GetMipsRegMapHi(count) == Reg) - { - if (!GetX86Protected(Reg)) - { - UnMap_GPR(count, true); - return true; - } - break; - } - if (GetMipsRegMapLo(count) == Reg) - { - if (!GetX86Protected(Reg)) - { - UnMap_GPR(count, true); - return true; - } - break; - } - } - } - else if (GetX86Mapped(Reg) == CRegInfo::Temp_Mapped) - { - if (!GetX86Protected(Reg)) - { - CPU_Message(" regcache: unallocate %s from temp storage", x86_Name(Reg)); - SetX86Mapped(Reg, NotMapped); - return true; - } - } - else if (GetX86Mapped(Reg) == CRegInfo::Stack_Mapped) - { - CPU_Message(" regcache: unallocate %s from Memory Stack", x86_Name(Reg)); - MoveX86regToVariable(Reg, &(g_Recompiler->MemoryStackPos()), "MemoryStack"); - SetX86Mapped(Reg, NotMapped); - return true; - } - - return false; -} - -void CRegInfo::WriteBackRegisters() -{ - UnMap_AllFPRs(); - - int32_t count; - bool bEdiZero = false; - bool bEsiSign = false; - - int32_t X86RegCount = sizeof(x86_Registers) / sizeof(x86_Registers[0]); - for (int32_t i = 0; i < X86RegCount; i++) { SetX86Protected(x86_Registers[i], false); } - for (int32_t i = 0; i < X86RegCount; i++) { UnMap_X86reg(x86_Registers[i]); } - - /*************************************/ - - for (count = 1; count < 32; count++) - { - switch (GetMipsRegState(count)) - { - case CRegInfo::STATE_UNKNOWN: break; - case CRegInfo::STATE_CONST_32_SIGN: - if (!g_System->b32BitCore()) - { - if (!bEdiZero && (!GetMipsRegLo(count) || !(GetMipsRegLo(count) & 0x80000000))) - { - XorX86RegToX86Reg(x86_EDI, x86_EDI); - bEdiZero = true; - } - if (!bEsiSign && (GetMipsRegLo(count) & 0x80000000)) - { - MoveConstToX86reg(0xFFFFFFFF, x86_ESI); - bEsiSign = true; - } - if ((GetMipsRegLo(count) & 0x80000000) != 0) - { - MoveX86regToVariable(x86_ESI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); - } - else - { - MoveX86regToVariable(x86_EDI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); - } - } - - if (GetMipsRegLo(count) == 0) - { - if (g_System->b32BitCore()) - { - if (!bEdiZero) - { - XorX86RegToX86Reg(x86_EDI, x86_EDI); - bEdiZero = true; - } - } - MoveX86regToVariable(x86_EDI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); - } - else if (GetMipsRegLo(count) == 0xFFFFFFFF) - { - if (g_System->b32BitCore()) - { - if (!bEsiSign) - { - MoveConstToX86reg(0xFFFFFFFF, x86_ESI); - bEsiSign = true; - } - } - MoveX86regToVariable(x86_ESI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); - } - else - { - MoveConstToVariable(GetMipsRegLo(count), &_GPR[count].UW[0], CRegName::GPR_Lo[count]); - } - - SetMipsRegState(count, CRegInfo::STATE_UNKNOWN); - break; - case CRegInfo::STATE_CONST_32_ZERO: - if (!g_System->b32BitCore()) - { - if (!bEdiZero) - { - XorX86RegToX86Reg(x86_EDI, x86_EDI); - bEdiZero = true; - } - MoveX86regToVariable(x86_EDI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); - } - - if (GetMipsRegLo(count) == 0) - { - if (g_System->b32BitCore()) - { - if (!bEdiZero) - { - XorX86RegToX86Reg(x86_EDI, x86_EDI); - bEdiZero = true; - } - } - MoveX86regToVariable(x86_EDI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); - } - else - { - MoveConstToVariable(GetMipsRegLo(count), &_GPR[count].UW[0], CRegName::GPR_Lo[count]); - } - SetMipsRegState(count, CRegInfo::STATE_UNKNOWN); - break; - case CRegInfo::STATE_CONST_64: - if (GetMipsRegLo(count) == 0 || GetMipsRegHi(count) == 0) - { - XorX86RegToX86Reg(x86_EDI, x86_EDI); - bEdiZero = true; - } - if (GetMipsRegLo(count) == 0xFFFFFFFF || GetMipsRegHi(count) == 0xFFFFFFFF) - { - MoveConstToX86reg(0xFFFFFFFF, x86_ESI); - bEsiSign = true; - } - - if (GetMipsRegHi(count) == 0) - { - MoveX86regToVariable(x86_EDI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); - } - else if (GetMipsRegLo(count) == 0xFFFFFFFF) - { - MoveX86regToVariable(x86_ESI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); - } - else - { - MoveConstToVariable(GetMipsRegHi(count), &_GPR[count].UW[1], CRegName::GPR_Hi[count]); - } - - if (GetMipsRegLo(count) == 0) - { - MoveX86regToVariable(x86_EDI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); - } - else if (GetMipsRegLo(count) == 0xFFFFFFFF) - { - MoveX86regToVariable(x86_ESI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); - } - else - { - MoveConstToVariable(GetMipsRegLo(count), &_GPR[count].UW[0], CRegName::GPR_Lo[count]); - } - SetMipsRegState(count, CRegInfo::STATE_UNKNOWN); - break; - default: - CPU_Message("%s: Unknown State: %d reg %d (%s)", __FUNCTION__, GetMipsRegState(count), count, CRegName::GPR[count]); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } -} - -const char * CRegInfo::RoundingModelName(FPU_ROUND RoundType) -{ - switch (RoundType) - { - case RoundUnknown: return "RoundUnknown"; - case RoundDefault: return "RoundDefault"; - case RoundTruncate: return "RoundTruncate"; - case RoundNearest: return "RoundNearest"; - case RoundDown: return "RoundDown"; - case RoundUp: return "RoundUp"; - } - return "** Invalid **"; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include + +#include +#include +#include +#include "x86CodeLog.h" + +uint32_t CRegInfo::m_fpuControl = 0; + +const char *Format_Name[] = { "Unknown", "dword", "qword", "float", "double" }; + +CRegInfo::CRegInfo() : +m_CycleCount(0), +m_Stack_TopPos(0), +m_Fpu_Used(false), +m_RoundingModel(RoundUnknown) +{ + m_MIPS_RegState[0] = STATE_CONST_32_SIGN; + m_MIPS_RegVal[0].DW = 0; + m_RegMapLo[0] = x86_Unknown; + m_RegMapHi[0] = x86_Unknown; + + for (int32_t i = 1; i < 32; i++) + { + m_MIPS_RegState[i] = STATE_UNKNOWN; + m_MIPS_RegVal[i].DW = 0; + m_RegMapLo[i] = x86_Unknown; + m_RegMapHi[i] = x86_Unknown; + } + for (int32_t i = 0, n = sizeof(m_x86reg_MappedTo) / sizeof(m_x86reg_MappedTo[0]); i < n; i++) + { + m_x86reg_MappedTo[i] = NotMapped; + m_x86reg_Protected[i] = false; + m_x86reg_MapOrder[i] = 0; + } + for (int32_t i = 0, n = sizeof(m_x86fpu_MappedTo) / sizeof(m_x86fpu_MappedTo[0]); i < n; i++) + { + m_x86fpu_MappedTo[i] = -1; + m_x86fpu_State[i] = FPU_Unknown; + m_x86fpu_StateChanged[i] = false; + m_x86fpu_RoundingModel[i] = RoundDefault; + } +} + +CRegInfo::CRegInfo(const CRegInfo& rhs) +{ + *this = rhs; +} + +CRegInfo::~CRegInfo() +{ +} + +CRegInfo& CRegInfo::operator=(const CRegInfo& right) +{ + m_CycleCount = right.m_CycleCount; + m_Stack_TopPos = right.m_Stack_TopPos; + m_Fpu_Used = right.m_Fpu_Used; + m_RoundingModel = right.m_RoundingModel; + + memcpy(&m_MIPS_RegState, &right.m_MIPS_RegState, sizeof(m_MIPS_RegState)); + memcpy(&m_MIPS_RegVal, &right.m_MIPS_RegVal, sizeof(m_MIPS_RegVal)); + memcpy(&m_RegMapLo, &right.m_RegMapLo, sizeof(m_RegMapLo)); + memcpy(&m_RegMapHi, &right.m_RegMapHi, sizeof(m_RegMapHi)); + memcpy(&m_x86reg_MappedTo, &right.m_x86reg_MappedTo, sizeof(m_x86reg_MappedTo)); + memcpy(&m_x86reg_Protected, &right.m_x86reg_Protected, sizeof(m_x86reg_Protected)); + memcpy(&m_x86reg_MapOrder, &right.m_x86reg_MapOrder, sizeof(m_x86reg_MapOrder)); + + memcpy(&m_x86fpu_MappedTo, &right.m_x86fpu_MappedTo, sizeof(m_x86fpu_MappedTo)); + memcpy(&m_x86fpu_State, &right.m_x86fpu_State, sizeof(m_x86fpu_State)); + memcpy(&m_x86fpu_StateChanged, &right.m_x86fpu_StateChanged, sizeof(m_x86fpu_StateChanged)); + memcpy(&m_x86fpu_RoundingModel, &right.m_x86fpu_RoundingModel, sizeof(m_x86fpu_RoundingModel)); + +#ifdef _DEBUG + if (*this != right) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } +#endif + return *this; +} + +bool CRegInfo::operator==(const CRegInfo& right) const +{ + int32_t count; + + for (count = 0; count < 32; count++) + { + if (m_MIPS_RegState[count] != right.m_MIPS_RegState[count]) + { + return false; + } + if (m_MIPS_RegState[count] == STATE_UNKNOWN) + { + continue; + } + if (m_MIPS_RegVal[count].DW != right.m_MIPS_RegVal[count].DW) + { + return false; + } + } + for (count = 0; count < 10; count++) + { + if (m_x86reg_MappedTo[count] != right.m_x86reg_MappedTo[count]) { return false; } + if (m_x86reg_Protected[count] != right.m_x86reg_Protected[count]) { return false; } + if (m_x86reg_MapOrder[count] != right.m_x86reg_MapOrder[count]) { return false; } + } + if (m_CycleCount != right.m_CycleCount) { return false; } + if (m_Stack_TopPos != right.m_Stack_TopPos) { return false; } + + for (count = 0; count < 8; count++) + { + if (m_x86fpu_MappedTo[count] != right.m_x86fpu_MappedTo[count]) { return false; } + if (m_x86fpu_State[count] != right.m_x86fpu_State[count]) { return false; } + if (m_x86fpu_RoundingModel[count] != right.m_x86fpu_RoundingModel[count]) { return false; } + } + if (m_Fpu_Used != right.m_Fpu_Used) { return false; } + if (GetRoundingModel() != right.GetRoundingModel()) { return false; } + return true; +} + +bool CRegInfo::operator!=(const CRegInfo& right) const +{ + return !(right == *this); +} + +CRegInfo::REG_STATE CRegInfo::ConstantsType(int64_t Value) +{ + if (((Value >> 32) == -1) && ((Value & 0x80000000) != 0)) { return STATE_CONST_32_SIGN; } + if (((Value >> 32) == 0) && ((Value & 0x80000000) == 0)) { return STATE_CONST_32_SIGN; } + return STATE_CONST_64; +} + +void CRegInfo::FixRoundModel(FPU_ROUND RoundMethod) +{ + if (GetRoundingModel() == RoundMethod) + { + return; + } + CPU_Message(" FixRoundModel: CurrentRoundingModel: %s targetRoundModel: %s", RoundingModelName(GetRoundingModel()), RoundingModelName(RoundMethod)); + + m_fpuControl = 0; + fpuStoreControl(&m_fpuControl, "m_fpuControl"); + x86Reg reg = Map_TempReg(x86_Any, -1, false); + MoveVariableToX86reg(&m_fpuControl, "m_fpuControl", reg); + AndConstToX86Reg(reg, 0xF3FF); + + if (RoundMethod == RoundDefault) + { + static const unsigned int msRound[4] = { _RC_NEAR, _RC_CHOP, _RC_UP, _RC_DOWN }; + + x86Reg RoundReg = Map_TempReg(x86_Any, -1, false); + MoveVariableToX86reg(&g_Reg->m_RoundingModel, "m_RoundingModel", RoundReg); + MoveVariableDispToX86Reg((void *)&msRound[0], "msRound", RoundReg, RoundReg, Multip_x4); + + ShiftLeftSignImmed(RoundReg, 2); + OrX86RegToX86Reg(reg, RoundReg); + SetX86Protected(RoundReg, false); + } + else + { + switch (RoundMethod) + { + case RoundTruncate: OrConstToX86Reg(0x0C00, reg); break; + case RoundNearest: /*OrConstToX86Reg(0x0000, reg);*/ break; + case RoundDown: OrConstToX86Reg(0x0400, reg); break; + case RoundUp: OrConstToX86Reg(0x0800, reg); break; + default: + g_Notify->DisplayError("Unknown Rounding model"); + } + } + MoveX86regToVariable(reg, &m_fpuControl, "m_fpuControl"); + SetX86Protected(reg, false); + fpuLoadControl(&m_fpuControl, "m_fpuControl"); + SetRoundingModel(RoundMethod); +} + +void CRegInfo::ChangeFPURegFormat(int32_t Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel) +{ + for (uint32_t i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] != Reg) + { + continue; + } + if (m_x86fpu_State[i] != OldFormat || m_x86fpu_StateChanged[i]) + { + UnMap_FPR(Reg, true); + Load_FPR_ToTop(Reg, Reg, OldFormat); + } + else + { + CPU_Message(" regcache: Changed format of ST(%d) from %s to %s", (i - StackTopPos() + 8) & 7, Format_Name[OldFormat], Format_Name[NewFormat]); + } + FpuRoundingModel(i) = RoundingModel; + m_x86fpu_State[i] = NewFormat; + m_x86fpu_StateChanged[i] = true; + return; + } + + if (bHaveDebugger()) + { + g_Notify->DisplayError("ChangeFormat: Register not on stack!!"); + } +} + +void CRegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Format) +{ + if (GetRoundingModel() != RoundDefault) + { + FixRoundModel(RoundDefault); + } + CPU_Message("CurrentRoundingModel: %s FpuRoundingModel(StackTopPos()): %s", RoundingModelName(GetRoundingModel()), RoundingModelName(FpuRoundingModel(StackTopPos()))); + int32_t i; + + if (RegToLoad < 0) { g_Notify->DisplayError("Load_FPR_ToTop\nRegToLoad < 0 ???"); return; } + if (Reg < 0) { g_Notify->DisplayError("Load_FPR_ToTop\nReg < 0 ???"); return; } + + if (Format == FPU_Double || Format == FPU_Qword) + { + UnMap_FPR(Reg + 1, true); + UnMap_FPR(RegToLoad + 1, true); + } + else + { + if ((Reg & 1) != 0) + { + for (i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] == (Reg - 1)) + { + if (m_x86fpu_State[i] == FPU_Double || m_x86fpu_State[i] == FPU_Qword) + { + UnMap_FPR(Reg, true); + } + i = 8; + } + } + } + if ((RegToLoad & 1) != 0) + { + for (i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] == (RegToLoad - 1)) + { + if (m_x86fpu_State[i] == FPU_Double || m_x86fpu_State[i] == FPU_Qword) + { + UnMap_FPR(RegToLoad, true); + } + i = 8; + } + } + } + } + + if (Reg == RegToLoad) + { + //if different format then unmap original reg from stack + for (i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] != Reg) + { + continue; + } + if (m_x86fpu_State[i] != Format) + { + UnMap_FPR(Reg, true); + } + break; + } + } + else + { + //if different format then unmap original reg from stack + for (i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] != Reg) + { + continue; + } + UnMap_FPR(Reg, m_x86fpu_State[i] != Format); + break; + } + } + + if (RegInStack(RegToLoad, Format)) + { + if (Reg != RegToLoad) + { + if (m_x86fpu_MappedTo[(StackTopPos() - 1) & 7] != RegToLoad) + { + UnMap_FPR(m_x86fpu_MappedTo[(StackTopPos() - 1) & 7], true); + CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]); + fpuLoadReg(&StackTopPos(), StackPosition(RegToLoad)); + FpuRoundingModel(StackTopPos()) = RoundDefault; + m_x86fpu_MappedTo[StackTopPos()] = Reg; + m_x86fpu_State[StackTopPos()] = Format; + m_x86fpu_StateChanged[StackTopPos()] = false; + } + else + { + UnMap_FPR(m_x86fpu_MappedTo[(StackTopPos() - 1) & 7], true); + Load_FPR_ToTop(Reg, RegToLoad, Format); + } + } + else + { + x86FpuValues RegPos = x86_ST_Unknown; + for (uint32_t i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] == Reg) + { + RegPos = (x86FpuValues)i; + i = 8; + } + } + + if (RegPos == StackTopPos()) + { + return; + } + x86FpuValues StackPos = StackPosition(Reg); + + FpuRoundingModel(RegPos) = FpuRoundingModel(StackTopPos()); + m_x86fpu_MappedTo[RegPos] = m_x86fpu_MappedTo[StackTopPos()]; + m_x86fpu_State[RegPos] = m_x86fpu_State[StackTopPos()]; + m_x86fpu_StateChanged[RegPos] = m_x86fpu_StateChanged[StackTopPos()]; + CPU_Message(" regcache: allocate ST(%d) to %s", StackPos, CRegName::FPR[m_x86fpu_MappedTo[RegPos]]); + CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]); + + fpuExchange(StackPos); + + FpuRoundingModel(StackTopPos()) = RoundDefault; + m_x86fpu_MappedTo[StackTopPos()] = Reg; + m_x86fpu_State[StackTopPos()] = Format; + m_x86fpu_StateChanged[StackTopPos()] = false; + } + } + else + { + char Name[50]; + x86Reg TempReg; + + UnMap_FPR(m_x86fpu_MappedTo[(StackTopPos() - 1) & 7], true); + for (i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] == RegToLoad) + { + UnMap_FPR(RegToLoad, true); + i = 8; + } + } + CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]); + TempReg = Map_TempReg(x86_Any, -1, false); + switch (Format) + { + case FPU_Dword: + sprintf(Name, "m_FPR_S[%d]", RegToLoad); + MoveVariableToX86reg(&g_Reg->m_FPR_S[RegToLoad], Name, TempReg); + fpuLoadIntegerDwordFromX86Reg(&StackTopPos(), TempReg); + break; + case FPU_Qword: + sprintf(Name, "m_FPR_D[%d]", RegToLoad); + MoveVariableToX86reg(&g_Reg->m_FPR_D[RegToLoad], Name, TempReg); + fpuLoadIntegerQwordFromX86Reg(&StackTopPos(), TempReg); + break; + case FPU_Float: + sprintf(Name, "m_FPR_S[%d]", RegToLoad); + MoveVariableToX86reg(&g_Reg->m_FPR_S[RegToLoad], Name, TempReg); + fpuLoadDwordFromX86Reg(&StackTopPos(), TempReg); + break; + case FPU_Double: + sprintf(Name, "m_FPR_D[%d]", RegToLoad); + MoveVariableToX86reg(&g_Reg->m_FPR_D[RegToLoad], Name, TempReg); + fpuLoadQwordFromX86Reg(&StackTopPos(), TempReg); + break; + default: + if (bHaveDebugger()) { g_Notify->DisplayError(stdstr_f("Load_FPR_ToTop\nUnkown format to load %d", Format).c_str()); } + } + SetX86Protected(TempReg, false); + FpuRoundingModel(StackTopPos()) = RoundDefault; + m_x86fpu_MappedTo[StackTopPos()] = Reg; + m_x86fpu_State[StackTopPos()] = Format; + m_x86fpu_StateChanged[StackTopPos()] = false; + } +} + +CRegInfo::x86FpuValues CRegInfo::StackPosition(int32_t Reg) +{ + int32_t i; + + for (i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] == Reg) + { + return (x86FpuValues)((i - StackTopPos()) & 7); + } + } + return x86_ST_Unknown; +} + +CX86Ops::x86Reg CRegInfo::FreeX86Reg() +{ + if (GetX86Mapped(x86_EDI) == NotMapped && !GetX86Protected(x86_EDI)) { return x86_EDI; } + if (GetX86Mapped(x86_ESI) == NotMapped && !GetX86Protected(x86_ESI)) { return x86_ESI; } + if (GetX86Mapped(x86_EBX) == NotMapped && !GetX86Protected(x86_EBX)) { return x86_EBX; } + if (GetX86Mapped(x86_EAX) == NotMapped && !GetX86Protected(x86_EAX)) { return x86_EAX; } + if (GetX86Mapped(x86_EDX) == NotMapped && !GetX86Protected(x86_EDX)) { return x86_EDX; } + if (GetX86Mapped(x86_ECX) == NotMapped && !GetX86Protected(x86_ECX)) { return x86_ECX; } + + x86Reg Reg = UnMap_TempReg(); + if (Reg != x86_Unknown) { return Reg; } + + int32_t count, MapCount[10]; + x86Reg MapReg[10]; + + for (count = 0; count < 10; count++) + { + MapCount[count] = GetX86MapOrder((x86Reg)count); + MapReg[count] = (x86Reg)count; + } + for (count = 0; count < 10; count++) + { + int32_t i; + + for (i = 0; i < 9; i++) + { + x86Reg tempReg; + uint32_t temp; + + if (MapCount[i] < MapCount[i + 1]) + { + temp = MapCount[i]; + MapCount[i] = MapCount[i + 1]; + MapCount[i + 1] = temp; + tempReg = MapReg[i]; + MapReg[i] = MapReg[i + 1]; + MapReg[i + 1] = tempReg; + } + } + } + + x86Reg StackReg = x86_Unknown; + for (count = 0; count < 10; count++) + { + if (MapCount[count] > 0 && GetX86Mapped(MapReg[count]) != Stack_Mapped) + { + if (UnMap_X86reg((x86Reg)MapReg[count])) + { + return (x86Reg)MapReg[count]; + } + } + if (GetX86Mapped(MapReg[count]) == Stack_Mapped) { StackReg = MapReg[count]; } + } + if (StackReg != x86_Unknown) + { + UnMap_X86reg(StackReg); + return StackReg; + } + + return x86_Unknown; +} + +CX86Ops::x86Reg CRegInfo::Free8BitX86Reg() +{ + if (GetX86Mapped(x86_EBX) == NotMapped && !GetX86Protected(x86_EBX)) { return x86_EBX; } + if (GetX86Mapped(x86_EAX) == NotMapped && !GetX86Protected(x86_EAX)) { return x86_EAX; } + if (GetX86Mapped(x86_EDX) == NotMapped && !GetX86Protected(x86_EDX)) { return x86_EDX; } + if (GetX86Mapped(x86_ECX) == NotMapped && !GetX86Protected(x86_ECX)) { return x86_ECX; } + + x86Reg Reg = UnMap_8BitTempReg(); + if (Reg > 0) { return Reg; } + + int32_t count, MapCount[10], MapReg[10]; + for (count = 0; count < 10; count++) + { + MapCount[count] = GetX86MapOrder((x86Reg)count); + MapReg[count] = count; + } + for (count = 0; count < 10; count++) + { + int32_t i; + + for (i = 0; i < 9; i++) + { + int32_t temp; + + if (MapCount[i] < MapCount[i + 1]) + { + temp = MapCount[i]; + MapCount[i] = MapCount[i + 1]; + MapCount[i + 1] = temp; + temp = MapReg[i]; + MapReg[i] = MapReg[i + 1]; + MapReg[i + 1] = temp; + } + } + } + for (count = 0; count < 10; count++) + { + if (MapCount[count] > 0) + { + if (!Is8BitReg((x86Reg)count)) { continue; } + if (UnMap_X86reg((x86Reg)count)) + { + return (x86Reg)count; + } + } + } + return x86_Unknown; +} + +CX86Ops::x86Reg CRegInfo::UnMap_8BitTempReg() +{ + int32_t count; + + for (count = 0; count < 10; count++) + { + if (!Is8BitReg((x86Reg)count)) { continue; } + if (GetX86Mapped((x86Reg)count) == Temp_Mapped) + { + if (GetX86Protected((x86Reg)count) == false) + { + CPU_Message(" regcache: unallocate %s from temp storage", x86_Name((x86Reg)count)); + SetX86Mapped((x86Reg)count, CRegInfo::NotMapped); + return (x86Reg)count; + } + } + } + return x86_Unknown; +} + +CRegInfo::x86Reg CRegInfo::Get_MemoryStack() const +{ + for (int32_t i = 0, n = sizeof(x86_Registers) / sizeof(x86_Registers[0]); i < n; i++) + { + if (GetX86Mapped(x86_Registers[i]) == Stack_Mapped) + { + return x86_Registers[i]; + } + } + return x86_Unknown; +} + +CRegInfo::x86Reg CRegInfo::Map_MemoryStack(x86Reg Reg, bool bMapRegister, bool LoadValue) +{ + x86Reg CurrentMap = Get_MemoryStack(); + if (!bMapRegister) + { + //if not mapping then just return what the current mapping is + return CurrentMap; + } + + if (CurrentMap != x86_Unknown && CurrentMap == Reg) + { + //already mapped to correct reg + return CurrentMap; + } + // map a register + if (Reg == x86_Any) + { + if (CurrentMap != x86_Unknown) + { + return CurrentMap; + } + Reg = FreeX86Reg(); + if (Reg == x86_Unknown) + { + g_Notify->DisplayError("Map_MemoryStack\n\nOut of registers"); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + SetX86Mapped(Reg, CRegInfo::Stack_Mapped); + CPU_Message(" regcache: allocate %s as Memory Stack", x86_Name(Reg)); + if (LoadValue) + { + MoveVariableToX86reg(&g_Recompiler->MemoryStackPos(), "MemoryStack", Reg); + } + return Reg; + } + + //move to a register/allocate register + UnMap_X86reg(Reg); + if (CurrentMap != x86_Unknown) + { + CPU_Message(" regcache: change allocation of Memory Stack from %s to %s", x86_Name(CurrentMap), x86_Name(Reg)); + SetX86Mapped(Reg, CRegInfo::Stack_Mapped); + SetX86Mapped(CurrentMap, CRegInfo::NotMapped); + MoveX86RegToX86Reg(CurrentMap, Reg); + } + else + { + SetX86Mapped(Reg, CRegInfo::Stack_Mapped); + CPU_Message(" regcache: allocate %s as Memory Stack", x86_Name(Reg)); + if (LoadValue) + { + MoveVariableToX86reg(&g_Recompiler->MemoryStackPos(), "MemoryStack", Reg); + } + } + return Reg; +} + +void CRegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsRegToLoad) +{ + int32_t count; + + x86Reg Reg; + if (MipsReg == 0) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + + if (IsUnknown(MipsReg) || IsConst(MipsReg)) + { + Reg = FreeX86Reg(); + if (Reg < 0) + { + if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_32bit\n\nOut of registers"); } + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + CPU_Message(" regcache: allocate %s to %s", x86_Name(Reg), CRegName::GPR[MipsReg]); + } + else + { + if (Is64Bit(MipsReg)) + { + CPU_Message(" regcache: unallocate %s from high 32bit of %s", x86_Name(GetMipsRegMapHi(MipsReg)), CRegName::GPR_Hi[MipsReg]); + SetX86MapOrder(GetMipsRegMapHi(MipsReg), 0); + SetX86Mapped(GetMipsRegMapHi(MipsReg), NotMapped); + SetX86Protected(GetMipsRegMapHi(MipsReg), false); + SetMipsRegHi(MipsReg, 0); + } + Reg = GetMipsRegMapLo(MipsReg); + } + for (count = 0; count < 10; count++) + { + uint32_t Count = GetX86MapOrder((x86Reg)count); + if (Count > 0) + { + SetX86MapOrder((x86Reg)count, Count + 1); + } + } + SetX86MapOrder(Reg, 1); + + if (MipsRegToLoad > 0) + { + if (IsUnknown(MipsRegToLoad)) + { + MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0], CRegName::GPR_Lo[MipsRegToLoad], Reg); + } + else if (IsMapped(MipsRegToLoad)) + { + if (MipsReg != MipsRegToLoad) + { + MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), Reg); + } + } + else + { + MoveConstToX86reg(GetMipsRegLo(MipsRegToLoad), Reg); + } + } + else if (MipsRegToLoad == 0) + { + XorX86RegToX86Reg(Reg, Reg); + } + SetX86Mapped(Reg, GPR_Mapped); + SetX86Protected(Reg, true); + SetMipsRegMapLo(MipsReg, Reg); + SetMipsRegState(MipsReg, SignValue ? STATE_MAPPED_32_SIGN : STATE_MAPPED_32_ZERO); +} + +void CRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad) +{ + x86Reg x86Hi, x86lo; + int32_t count; + + if (MipsReg == 0) + { + if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_32bit\n\nWhy are you trying to map reg 0"); } + return; + } + + ProtectGPR(MipsReg); + if (IsUnknown(MipsReg) || IsConst(MipsReg)) + { + x86Hi = FreeX86Reg(); + if (x86Hi < 0) + { + if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); } + return; + } + SetX86Protected(x86Hi, true); + + x86lo = FreeX86Reg(); + if (x86lo < 0) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); return; } + SetX86Protected(x86lo, true); + + CPU_Message(" regcache: allocate %s to hi word of %s", x86_Name(x86Hi), CRegName::GPR[MipsReg]); + CPU_Message(" regcache: allocate %s to low word of %s", x86_Name(x86lo), CRegName::GPR[MipsReg]); + } + else + { + x86lo = GetMipsRegMapLo(MipsReg); + if (Is32Bit(MipsReg)) + { + SetX86Protected(x86lo, true); + x86Hi = FreeX86Reg(); + if (x86Hi == x86_Unknown) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + SetX86Protected(x86Hi, true); + + CPU_Message(" regcache: allocate %s to hi word of %s", x86_Name(x86Hi), CRegName::GPR[MipsReg]); + } + else + { + x86Hi = GetMipsRegMapHi(MipsReg); + } + } + + for (count = 0; count < 10; count++) + { + int32_t MapOrder = GetX86MapOrder((x86Reg)count); + if (MapOrder > 0) + { + SetX86MapOrder((x86Reg)count, MapOrder + 1); + } + } + + SetX86MapOrder(x86Hi, 1); + SetX86MapOrder(x86lo, 1); + if (MipsRegToLoad > 0) + { + if (IsUnknown(MipsRegToLoad)) + { + MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[1], CRegName::GPR_Hi[MipsRegToLoad], x86Hi); + MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0], CRegName::GPR_Lo[MipsRegToLoad], x86lo); + } + else if (IsMapped(MipsRegToLoad)) + { + if (Is32Bit(MipsRegToLoad)) + { + if (IsSigned(MipsRegToLoad)) + { + MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86Hi); + ShiftRightSignImmed(x86Hi, 31); + } + else + { + XorX86RegToX86Reg(x86Hi, x86Hi); + } + if (MipsReg != MipsRegToLoad) + { + MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86lo); + } + } + else + { + if (MipsReg != MipsRegToLoad) + { + MoveX86RegToX86Reg(GetMipsRegMapHi(MipsRegToLoad), x86Hi); + MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86lo); + } + } + } + else + { + CPU_Message("Map_GPR_64bit 11"); + if (Is32Bit(MipsRegToLoad)) + { + if (IsSigned(MipsRegToLoad)) + { + MoveConstToX86reg(GetMipsRegLo_S(MipsRegToLoad) >> 31, x86Hi); + } + else + { + MoveConstToX86reg(0, x86Hi); + } + } + else + { + MoveConstToX86reg(GetMipsRegHi(MipsRegToLoad), x86Hi); + } + MoveConstToX86reg(GetMipsRegLo(MipsRegToLoad), x86lo); + } + } + else if (MipsRegToLoad == 0) + { + XorX86RegToX86Reg(x86Hi, x86Hi); + XorX86RegToX86Reg(x86lo, x86lo); + } + SetX86Mapped(x86Hi, GPR_Mapped); + SetX86Mapped(x86lo, GPR_Mapped); + SetMipsRegMapHi(MipsReg, x86Hi); + SetMipsRegMapLo(MipsReg, x86lo); + SetMipsRegState(MipsReg, STATE_MAPPED_64); +} + +CX86Ops::x86Reg CRegInfo::Map_TempReg(CX86Ops::x86Reg Reg, int32_t MipsReg, bool LoadHiWord) +{ + int32_t count; + + if (Reg == x86_Any) + { + if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } + else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } + else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } + else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } + else if (GetX86Mapped(x86_ESI) == Temp_Mapped && !GetX86Protected(x86_ESI)) { Reg = x86_ESI; } + else if (GetX86Mapped(x86_EDI) == Temp_Mapped && !GetX86Protected(x86_EDI)) { Reg = x86_EDI; } + else if (GetX86Mapped(x86_EBP) == Temp_Mapped && !GetX86Protected(x86_EBP)) { Reg = x86_EBP; } + else if (GetX86Mapped(x86_ESP) == Temp_Mapped && !GetX86Protected(x86_ESP)) { Reg = x86_ESP; } + + if (Reg == x86_Any) + { + Reg = FreeX86Reg(); + if (Reg == x86_Unknown) + { + WriteTrace(TraceRegisterCache, TraceError, "Failed to find a free register"); + g_Notify->BreakPoint(__FILE__, __LINE__); + return x86_Unknown; + } + } + } + else if (Reg == x86_Any8Bit) + { + if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } + else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } + else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } + else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } + + if (Reg == x86_Any8Bit) + { + Reg = Free8BitX86Reg(); + if (Reg < 0) + { + WriteTrace(TraceRegisterCache, TraceError, "Failed to find a free 8 bit register"); + g_Notify->BreakPoint(__FILE__, __LINE__); + return x86_Unknown; + } + } + } + else if (GetX86Mapped(Reg) == GPR_Mapped) + { + if (GetX86Protected(Reg)) + { + WriteTrace(TraceRegisterCache, TraceError, "Register is protected"); + g_Notify->BreakPoint(__FILE__, __LINE__); + return x86_Unknown; + } + + SetX86Protected(Reg, true); + x86Reg NewReg = FreeX86Reg(); + for (count = 1; count < 32; count++) + { + if (!IsMapped(count)) + { + continue; + } + if (GetMipsRegMapLo(count) == Reg) + { + if (NewReg == x86_Unknown) + { + UnMap_GPR(count, true); + break; + } + CPU_Message(" regcache: change allocation of %s from %s to %s", CRegName::GPR[count], x86_Name(Reg), x86_Name(NewReg)); + SetX86Mapped(NewReg, GPR_Mapped); + SetX86MapOrder(NewReg, GetX86MapOrder(Reg)); + SetMipsRegMapLo(count, NewReg); + MoveX86RegToX86Reg(Reg, NewReg); + if (MipsReg == count && !LoadHiWord) + { + MipsReg = -1; + } + break; + } + if (Is64Bit(count) && GetMipsRegMapHi(count) == Reg) + { + if (NewReg == x86_Unknown) + { + UnMap_GPR(count, true); + break; + } + CPU_Message(" regcache: change allocation of %s from %s to %s", CRegName::GPR_Hi[count], x86_Name(Reg), x86_Name(NewReg)); + SetX86Mapped(NewReg, GPR_Mapped); + SetX86MapOrder(NewReg, GetX86MapOrder(Reg)); + SetMipsRegMapHi(count, NewReg); + MoveX86RegToX86Reg(Reg, NewReg); + if (MipsReg == count && LoadHiWord) + { + MipsReg = -1; + } + break; + } + } + } + else if (GetX86Mapped(Reg) == Stack_Mapped) + { + UnMap_X86reg(Reg); + } + CPU_Message(" regcache: allocate %s as temp storage", x86_Name(Reg)); + + if (MipsReg >= 0) + { + if (LoadHiWord) + { + if (IsUnknown(MipsReg)) + { + MoveVariableToX86reg(&_GPR[MipsReg].UW[1], CRegName::GPR_Hi[MipsReg], Reg); + } + else if (IsMapped(MipsReg)) + { + if (Is64Bit(MipsReg)) + { + MoveX86RegToX86Reg(GetMipsRegMapHi(MipsReg), Reg); + } + else if (IsSigned(MipsReg)) + { + MoveX86RegToX86Reg(GetMipsRegMapLo(MipsReg), Reg); + ShiftRightSignImmed(Reg, 31); + } + else + { + MoveConstToX86reg(0, Reg); + } + } + else + { + if (Is64Bit(MipsReg)) + { + MoveConstToX86reg(GetMipsRegHi(MipsReg), Reg); + } + else + { + MoveConstToX86reg(GetMipsRegLo_S(MipsReg) >> 31, Reg); + } + } + } + else + { + if (IsUnknown(MipsReg)) + { + MoveVariableToX86reg(&_GPR[MipsReg].UW[0], CRegName::GPR_Lo[MipsReg], Reg); + } + else if (IsMapped(MipsReg)) + { + MoveX86RegToX86Reg(GetMipsRegMapLo(MipsReg), Reg); + } + else + { + MoveConstToX86reg(GetMipsRegLo(MipsReg), Reg); + } + } + } + SetX86Mapped(Reg, Temp_Mapped); + SetX86Protected(Reg, true); + for (count = 0; count < 10; count++) + { + int32_t MapOrder = GetX86MapOrder((x86Reg)count); + if (MapOrder > 0) + { + SetX86MapOrder((x86Reg)count, MapOrder + 1); + } + } + SetX86MapOrder(Reg, 1); + return Reg; +} + +void CRegInfo::ProtectGPR(uint32_t Reg) +{ + if (IsUnknown(Reg) || IsConst(Reg)) + { + return; + } + if (Is64Bit(Reg)) + { + SetX86Protected(GetMipsRegMapHi(Reg), true); + } + SetX86Protected(GetMipsRegMapLo(Reg), true); +} + +void CRegInfo::UnProtectGPR(uint32_t Reg) +{ + if (IsUnknown(Reg) || IsConst(Reg)) + { + return; + } + if (Is64Bit(Reg)) + { + SetX86Protected(GetMipsRegMapHi(Reg), false); + } + SetX86Protected(GetMipsRegMapLo(Reg), false); +} + +void CRegInfo::ResetX86Protection() +{ + for (int32_t count = 0; count < 10; count++) + { + SetX86Protected((x86Reg)count, false); + } +} + +bool CRegInfo::RegInStack(int32_t Reg, FPU_STATE Format) +{ + for (int32_t i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] == Reg) + { + if (m_x86fpu_State[i] == Format || Format == FPU_Any) + { + return true; + } + return false; + } + } + return false; +} + +void CRegInfo::UnMap_AllFPRs() +{ + for (;;) + { + int32_t StackPos = StackTopPos(); + if (m_x86fpu_MappedTo[StackPos] != -1) + { + UnMap_FPR(m_x86fpu_MappedTo[StackPos], true); + continue; + } + //see if any more registers mapped + int32_t StartPos = StackTopPos(); + for (int32_t i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[(StartPos + i) & 7] != -1) { fpuIncStack(&StackTopPos()); } + } + if (StackPos != StackTopPos()) { continue; } + return; + } +} + +void CRegInfo::UnMap_FPR(int32_t Reg, bool WriteBackValue) +{ + char Name[50]; + int32_t i; + + if (Reg < 0) { return; } + for (i = 0; i < 8; i++) + { + if (m_x86fpu_MappedTo[i] != Reg) { continue; } + CPU_Message(" regcache: unallocate %s from ST(%d)", CRegName::FPR[Reg], (i - StackTopPos() + 8) & 7); + if (WriteBackValue) + { + int32_t RegPos; + + if (((i - StackTopPos() + 8) & 7) != 0) + { + if (m_x86fpu_MappedTo[StackTopPos()] == -1 && m_x86fpu_MappedTo[(StackTopPos() + 1) & 7] == Reg) + { + fpuIncStack(&StackTopPos()); + } + else + { + CRegInfo::FPU_ROUND RoundingModel = FpuRoundingModel(StackTopPos()); + FPU_STATE RegState = m_x86fpu_State[StackTopPos()]; + bool Changed = m_x86fpu_StateChanged[StackTopPos()]; + uint32_t MappedTo = m_x86fpu_MappedTo[StackTopPos()]; + FpuRoundingModel(StackTopPos()) = FpuRoundingModel(i); + m_x86fpu_MappedTo[StackTopPos()] = m_x86fpu_MappedTo[i]; + m_x86fpu_State[StackTopPos()] = m_x86fpu_State[i]; + m_x86fpu_StateChanged[StackTopPos()] = m_x86fpu_StateChanged[i]; + FpuRoundingModel(i) = RoundingModel; + m_x86fpu_MappedTo[i] = MappedTo; + m_x86fpu_State[i] = RegState; + m_x86fpu_StateChanged[i] = Changed; + fpuExchange((x86FpuValues)((i - StackTopPos()) & 7)); + } + } + + FixRoundModel(FpuRoundingModel(i)); + + RegPos = StackTopPos(); + x86Reg TempReg = Map_TempReg(x86_Any, -1, false); + switch (m_x86fpu_State[StackTopPos()]) + { + case FPU_Dword: + sprintf(Name, "_FPR_S[%d]", m_x86fpu_MappedTo[StackTopPos()]); + MoveVariableToX86reg(&_FPR_S[m_x86fpu_MappedTo[StackTopPos()]], Name, TempReg); + fpuStoreIntegerDwordFromX86Reg(&StackTopPos(), TempReg, true); + break; + case FPU_Qword: + sprintf(Name, "_FPR_D[%d]", m_x86fpu_MappedTo[StackTopPos()]); + MoveVariableToX86reg(&_FPR_D[m_x86fpu_MappedTo[StackTopPos()]], Name, TempReg); + fpuStoreIntegerQwordFromX86Reg(&StackTopPos(), TempReg, true); + break; + case FPU_Float: + sprintf(Name, "_FPR_S[%d]", m_x86fpu_MappedTo[StackTopPos()]); + MoveVariableToX86reg(&_FPR_S[m_x86fpu_MappedTo[StackTopPos()]], Name, TempReg); + fpuStoreDwordFromX86Reg(&StackTopPos(), TempReg, true); + break; + case FPU_Double: + sprintf(Name, "_FPR_D[%d]", m_x86fpu_MappedTo[StackTopPos()]); + MoveVariableToX86reg(&_FPR_D[m_x86fpu_MappedTo[StackTopPos()]], Name, TempReg); + fpuStoreQwordFromX86Reg(&StackTopPos(), TempReg, true); + break; + default: + if (bHaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("%s\nUnknown format to load %d", __FUNCTION__, m_x86fpu_State[StackTopPos()]).c_str()); + } + } + SetX86Protected(TempReg, false); + FpuRoundingModel(RegPos) = RoundDefault; + m_x86fpu_MappedTo[RegPos] = -1; + m_x86fpu_State[RegPos] = FPU_Unknown; + m_x86fpu_StateChanged[RegPos] = false; + } + else + { + fpuFree((x86FpuValues)((i - StackTopPos()) & 7)); + FpuRoundingModel(i) = RoundDefault; + m_x86fpu_MappedTo[i] = -1; + m_x86fpu_State[i] = FPU_Unknown; + m_x86fpu_StateChanged[i] = false; + } + return; + } +} + +void CRegInfo::UnMap_GPR(uint32_t Reg, bool WriteBackValue) +{ + if (Reg == 0) + { + if (bHaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("%s\n\nWhy are you trying to unmap reg 0", __FUNCTION__).c_str()); + } + return; + } + + if (IsUnknown(Reg)) { return; } + //CPU_Message("UnMap_GPR: State: %X\tReg: %s\tWriteBack: %s",State,CRegName::GPR[Reg],WriteBackValue?"true":"false"); + if (IsConst(Reg)) + { + if (!WriteBackValue) + { + SetMipsRegState(Reg, STATE_UNKNOWN); + return; + } + if (Is64Bit(Reg)) + { + MoveConstToVariable(GetMipsRegHi(Reg), &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); + MoveConstToVariable(GetMipsRegLo(Reg), &_GPR[Reg].UW[0], CRegName::GPR_Lo[Reg]); + SetMipsRegState(Reg, STATE_UNKNOWN); + return; + } + if ((GetMipsRegLo(Reg) & 0x80000000) != 0) + { + MoveConstToVariable(0xFFFFFFFF, &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); + } + else + { + MoveConstToVariable(0, &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); + } + MoveConstToVariable(GetMipsRegLo(Reg), &_GPR[Reg].UW[0], CRegName::GPR_Lo[Reg]); + SetMipsRegState(Reg, STATE_UNKNOWN); + return; + } + if (Is64Bit(Reg)) + { + CPU_Message(" regcache: unallocate %s from %s", x86_Name(GetMipsRegMapHi(Reg)), CRegName::GPR_Hi[Reg]); + SetX86Mapped(GetMipsRegMapHi(Reg), NotMapped); + SetX86Protected(GetMipsRegMapHi(Reg), false); + } + CPU_Message(" regcache: unallocate %s from %s", x86_Name(GetMipsRegMapLo(Reg)), CRegName::GPR_Lo[Reg]); + SetX86Mapped(GetMipsRegMapLo(Reg), NotMapped); + SetX86Protected(GetMipsRegMapLo(Reg), false); + if (!WriteBackValue) + { + SetMipsRegState(Reg, STATE_UNKNOWN); + return; + } + MoveX86regToVariable(GetMipsRegMapLo(Reg), &_GPR[Reg].UW[0], CRegName::GPR_Lo[Reg]); + if (Is64Bit(Reg)) + { + SetMipsRegMapLo(Reg, x86_Unknown); + MoveX86regToVariable(GetMipsRegMapHi(Reg), &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); + SetMipsRegMapHi(Reg, x86_Unknown); + } + else + { + if (!g_System->b32BitCore()) + { + if (IsSigned(Reg)) + { + ShiftRightSignImmed(GetMipsRegMapLo(Reg), 31); + MoveX86regToVariable(GetMipsRegMapLo(Reg), &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); + } + else + { + MoveConstToVariable(0, &_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg]); + } + } + SetMipsRegMapLo(Reg, x86_Unknown); + } + SetMipsRegState(Reg, STATE_UNKNOWN); +} + +CX86Ops::x86Reg CRegInfo::UnMap_TempReg() +{ + CX86Ops::x86Reg Reg = x86_Unknown; + + if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } + else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } + else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } + else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } + else if (GetX86Mapped(x86_ESI) == Temp_Mapped && !GetX86Protected(x86_ESI)) { Reg = x86_ESI; } + else if (GetX86Mapped(x86_EDI) == Temp_Mapped && !GetX86Protected(x86_EDI)) { Reg = x86_EDI; } + else if (GetX86Mapped(x86_EBP) == Temp_Mapped && !GetX86Protected(x86_EBP)) { Reg = x86_EBP; } + else if (GetX86Mapped(x86_ESP) == Temp_Mapped && !GetX86Protected(x86_ESP)) { Reg = x86_ESP; } + + if (Reg != x86_Unknown) + { + if (GetX86Mapped(Reg) == Temp_Mapped) + { + CPU_Message(" regcache: unallocate %s from temp storage", x86_Name(Reg)); + } + SetX86Mapped(Reg, NotMapped); + } + return Reg; +} + +bool CRegInfo::UnMap_X86reg(CX86Ops::x86Reg Reg) +{ + int32_t count; + + if (GetX86Mapped(Reg) == NotMapped) + { + if (!GetX86Protected(Reg)) + { + return true; + } + } + else if (GetX86Mapped(Reg) == CRegInfo::GPR_Mapped) + { + for (count = 1; count < 32; count++) + { + if (!IsMapped(count)) + { + continue; + } + + if (Is64Bit(count) && GetMipsRegMapHi(count) == Reg) + { + if (!GetX86Protected(Reg)) + { + UnMap_GPR(count, true); + return true; + } + break; + } + if (GetMipsRegMapLo(count) == Reg) + { + if (!GetX86Protected(Reg)) + { + UnMap_GPR(count, true); + return true; + } + break; + } + } + } + else if (GetX86Mapped(Reg) == CRegInfo::Temp_Mapped) + { + if (!GetX86Protected(Reg)) + { + CPU_Message(" regcache: unallocate %s from temp storage", x86_Name(Reg)); + SetX86Mapped(Reg, NotMapped); + return true; + } + } + else if (GetX86Mapped(Reg) == CRegInfo::Stack_Mapped) + { + CPU_Message(" regcache: unallocate %s from Memory Stack", x86_Name(Reg)); + MoveX86regToVariable(Reg, &(g_Recompiler->MemoryStackPos()), "MemoryStack"); + SetX86Mapped(Reg, NotMapped); + return true; + } + + return false; +} + +void CRegInfo::WriteBackRegisters() +{ + UnMap_AllFPRs(); + + int32_t count; + bool bEdiZero = false; + bool bEsiSign = false; + + int32_t X86RegCount = sizeof(x86_Registers) / sizeof(x86_Registers[0]); + for (int32_t i = 0; i < X86RegCount; i++) { SetX86Protected(x86_Registers[i], false); } + for (int32_t i = 0; i < X86RegCount; i++) { UnMap_X86reg(x86_Registers[i]); } + + /*************************************/ + + for (count = 1; count < 32; count++) + { + switch (GetMipsRegState(count)) + { + case CRegInfo::STATE_UNKNOWN: break; + case CRegInfo::STATE_CONST_32_SIGN: + if (!g_System->b32BitCore()) + { + if (!bEdiZero && (!GetMipsRegLo(count) || !(GetMipsRegLo(count) & 0x80000000))) + { + XorX86RegToX86Reg(x86_EDI, x86_EDI); + bEdiZero = true; + } + if (!bEsiSign && (GetMipsRegLo(count) & 0x80000000)) + { + MoveConstToX86reg(0xFFFFFFFF, x86_ESI); + bEsiSign = true; + } + if ((GetMipsRegLo(count) & 0x80000000) != 0) + { + MoveX86regToVariable(x86_ESI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); + } + else + { + MoveX86regToVariable(x86_EDI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); + } + } + + if (GetMipsRegLo(count) == 0) + { + if (g_System->b32BitCore()) + { + if (!bEdiZero) + { + XorX86RegToX86Reg(x86_EDI, x86_EDI); + bEdiZero = true; + } + } + MoveX86regToVariable(x86_EDI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); + } + else if (GetMipsRegLo(count) == 0xFFFFFFFF) + { + if (g_System->b32BitCore()) + { + if (!bEsiSign) + { + MoveConstToX86reg(0xFFFFFFFF, x86_ESI); + bEsiSign = true; + } + } + MoveX86regToVariable(x86_ESI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); + } + else + { + MoveConstToVariable(GetMipsRegLo(count), &_GPR[count].UW[0], CRegName::GPR_Lo[count]); + } + + SetMipsRegState(count, CRegInfo::STATE_UNKNOWN); + break; + case CRegInfo::STATE_CONST_32_ZERO: + if (!g_System->b32BitCore()) + { + if (!bEdiZero) + { + XorX86RegToX86Reg(x86_EDI, x86_EDI); + bEdiZero = true; + } + MoveX86regToVariable(x86_EDI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); + } + + if (GetMipsRegLo(count) == 0) + { + if (g_System->b32BitCore()) + { + if (!bEdiZero) + { + XorX86RegToX86Reg(x86_EDI, x86_EDI); + bEdiZero = true; + } + } + MoveX86regToVariable(x86_EDI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); + } + else + { + MoveConstToVariable(GetMipsRegLo(count), &_GPR[count].UW[0], CRegName::GPR_Lo[count]); + } + SetMipsRegState(count, CRegInfo::STATE_UNKNOWN); + break; + case CRegInfo::STATE_CONST_64: + if (GetMipsRegLo(count) == 0 || GetMipsRegHi(count) == 0) + { + XorX86RegToX86Reg(x86_EDI, x86_EDI); + bEdiZero = true; + } + if (GetMipsRegLo(count) == 0xFFFFFFFF || GetMipsRegHi(count) == 0xFFFFFFFF) + { + MoveConstToX86reg(0xFFFFFFFF, x86_ESI); + bEsiSign = true; + } + + if (GetMipsRegHi(count) == 0) + { + MoveX86regToVariable(x86_EDI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); + } + else if (GetMipsRegLo(count) == 0xFFFFFFFF) + { + MoveX86regToVariable(x86_ESI, &_GPR[count].UW[1], CRegName::GPR_Hi[count]); + } + else + { + MoveConstToVariable(GetMipsRegHi(count), &_GPR[count].UW[1], CRegName::GPR_Hi[count]); + } + + if (GetMipsRegLo(count) == 0) + { + MoveX86regToVariable(x86_EDI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); + } + else if (GetMipsRegLo(count) == 0xFFFFFFFF) + { + MoveX86regToVariable(x86_ESI, &_GPR[count].UW[0], CRegName::GPR_Lo[count]); + } + else + { + MoveConstToVariable(GetMipsRegLo(count), &_GPR[count].UW[0], CRegName::GPR_Lo[count]); + } + SetMipsRegState(count, CRegInfo::STATE_UNKNOWN); + break; + default: + CPU_Message("%s: Unknown State: %d reg %d (%s)", __FUNCTION__, GetMipsRegState(count), count, CRegName::GPR[count]); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } +} + +const char * CRegInfo::RoundingModelName(FPU_ROUND RoundType) +{ + switch (RoundType) + { + case RoundUnknown: return "RoundUnknown"; + case RoundDefault: return "RoundDefault"; + case RoundTruncate: return "RoundTruncate"; + case RoundNearest: return "RoundNearest"; + case RoundDown: return "RoundDown"; + case RoundUp: return "RoundUp"; + } + return "** Invalid **"; } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Recompiler/RegInfo.h b/Source/Project64-core/N64System/Recompiler/RegInfo.h index 945d9b887..dcc4517ba 100644 --- a/Source/Project64-core/N64System/Recompiler/RegInfo.h +++ b/Source/Project64-core/N64System/Recompiler/RegInfo.h @@ -1,186 +1,186 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include -#include -#include - -class CRegInfo : - private CDebugSettings, - private CX86Ops, - private CSystemRegisters -{ -public: - //enums - enum REG_STATE - { - STATE_UNKNOWN = 0x00, - STATE_KNOWN_VALUE = 0x01, - STATE_X86_MAPPED = 0x02, - STATE_SIGN = 0x04, - STATE_32BIT = 0x08, - STATE_MODIFIED = 0x10, - - STATE_MAPPED_64 = (STATE_KNOWN_VALUE | STATE_X86_MAPPED), // = 3 - STATE_MAPPED_32_ZERO = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT), // = 11 - STATE_MAPPED_32_SIGN = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT | STATE_SIGN), // = 15 - - STATE_CONST_32_ZERO = (STATE_KNOWN_VALUE | STATE_32BIT), // = 9 - STATE_CONST_32_SIGN = (STATE_KNOWN_VALUE | STATE_32BIT | STATE_SIGN), // = 13 - STATE_CONST_64 = (STATE_KNOWN_VALUE), // = 1 - }; - - enum REG_MAPPED - { - NotMapped = 0, - GPR_Mapped = 1, - Temp_Mapped = 2, - Stack_Mapped = 3, - }; - - enum FPU_STATE - { - FPU_Any = -1, - FPU_Unknown = 0, - FPU_Dword = 1, - FPU_Qword = 2, - FPU_Float = 3, - FPU_Double = 4, - }; - - enum FPU_ROUND - { - RoundUnknown = -1, - RoundDefault = 0, - RoundTruncate = 1, - RoundNearest = 2, - RoundDown = 3, - RoundUp = 4, - }; - -public: - CRegInfo(); - CRegInfo(const CRegInfo&); - ~CRegInfo(); - - CRegInfo& operator=(const CRegInfo&); - - bool operator==(const CRegInfo& right) const; - bool operator!=(const CRegInfo& right) const; - - static REG_STATE ConstantsType(int64_t Value); - - void FixRoundModel(FPU_ROUND RoundMethod); - void ChangeFPURegFormat(int32_t Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel); - void Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Format); - bool RegInStack(int32_t Reg, FPU_STATE Format); - void UnMap_AllFPRs(); - void UnMap_FPR(int32_t Reg, bool WriteBackValue); - x86FpuValues StackPosition(int32_t Reg); - - x86Reg FreeX86Reg(); - x86Reg Free8BitX86Reg(); - void Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsRegToLoad); - void Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad); - x86Reg Get_MemoryStack() const; - x86Reg Map_MemoryStack(x86Reg Reg, bool bMapRegister, bool LoadValue = true); - x86Reg Map_TempReg(x86Reg Reg, int32_t MipsReg, bool LoadHiWord); - void ProtectGPR(uint32_t Reg); - void UnProtectGPR(uint32_t Reg); - void ResetX86Protection(); - x86Reg UnMap_TempReg(); - void UnMap_GPR(uint32_t Reg, bool WriteBackValue); - bool UnMap_X86reg(x86Reg Reg); - void WriteBackRegisters(); - - bool IsKnown(int32_t Reg) const { return ((GetMipsRegState(Reg) & STATE_KNOWN_VALUE) != 0); } - bool IsUnknown(int32_t Reg) const { return ((GetMipsRegState(Reg) & STATE_KNOWN_VALUE) == 0); } - bool IsModified(int32_t Reg) const { return ((GetMipsRegState(Reg) & STATE_MODIFIED) != 0); } - - bool IsMapped(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_X86_MAPPED)); } - bool IsConst(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_X86_MAPPED)) == STATE_KNOWN_VALUE); } - - bool IsSigned(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_SIGN)) == (STATE_KNOWN_VALUE | STATE_SIGN)); } - bool IsUnsigned(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_SIGN)) == STATE_KNOWN_VALUE); } - - bool Is32Bit(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT)) == (STATE_KNOWN_VALUE | STATE_32BIT)); } - bool Is64Bit(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT)) == STATE_KNOWN_VALUE); } - - bool Is32BitMapped(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)); } - bool Is64BitMapped(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_X86_MAPPED)); } - - REG_STATE GetMipsRegState(int32_t Reg) const { return m_MIPS_RegState[Reg]; } - uint64_t GetMipsReg(int32_t Reg) const { return m_MIPS_RegVal[Reg].UDW; } - int64_t GetMipsReg_S(int32_t Reg) const { return m_MIPS_RegVal[Reg].DW; } - uint32_t GetMipsRegLo(int32_t Reg) const { return m_MIPS_RegVal[Reg].UW[0]; } - int32_t GetMipsRegLo_S(int32_t Reg) const { return m_MIPS_RegVal[Reg].W[0]; } - uint32_t GetMipsRegHi(int32_t Reg) const { return m_MIPS_RegVal[Reg].UW[1]; } - int32_t GetMipsRegHi_S(int32_t Reg) const { return m_MIPS_RegVal[Reg].W[1]; } - CX86Ops::x86Reg GetMipsRegMapLo(int32_t Reg) const { return m_RegMapLo[Reg]; } - CX86Ops::x86Reg GetMipsRegMapHi(int32_t Reg) const { return m_RegMapHi[Reg]; } - - uint32_t GetX86MapOrder(x86Reg Reg) const { return m_x86reg_MapOrder[Reg]; } - bool GetX86Protected(x86Reg Reg) const { return m_x86reg_Protected[Reg]; } - REG_MAPPED GetX86Mapped(x86Reg Reg) const { return m_x86reg_MappedTo[Reg]; } - - uint32_t GetBlockCycleCount() const { return m_CycleCount; } - - void SetMipsReg(int32_t Reg, uint64_t Value) { m_MIPS_RegVal[Reg].UDW = Value; } - void SetMipsReg_S(int32_t Reg, int64_t Value) { m_MIPS_RegVal[Reg].DW = Value; } - void SetMipsRegLo(int32_t Reg, uint32_t Value) { m_MIPS_RegVal[Reg].UW[0] = Value; } - void SetMipsRegHi(int32_t Reg, uint32_t Value) { m_MIPS_RegVal[Reg].UW[1] = Value; } - void SetMipsRegMapLo(int32_t GetMipsReg, x86Reg Reg) { m_RegMapLo[GetMipsReg] = Reg; } - void SetMipsRegMapHi(int32_t GetMipsReg, x86Reg Reg) { m_RegMapHi[GetMipsReg] = Reg; } - void SetMipsRegState(int32_t GetMipsReg, REG_STATE State) { m_MIPS_RegState[GetMipsReg] = State; } - - void SetX86MapOrder(x86Reg Reg, uint32_t Order) { m_x86reg_MapOrder[Reg] = Order; } - void SetX86Protected(x86Reg Reg, bool Protected) { m_x86reg_Protected[Reg] = Protected; } - void SetX86Mapped(x86Reg Reg, REG_MAPPED Mapping) { m_x86reg_MappedTo[Reg] = Mapping; } - - void SetBlockCycleCount(uint32_t CyleCount) { m_CycleCount = CyleCount; } - - int32_t & StackTopPos() { return m_Stack_TopPos; } - int32_t & FpuMappedTo(int32_t Reg) { return m_x86fpu_MappedTo[Reg]; } - FPU_STATE & FpuState(int32_t Reg) { return m_x86fpu_State[Reg]; } - FPU_ROUND & FpuRoundingModel(int32_t Reg) { return m_x86fpu_RoundingModel[Reg]; } - bool & FpuBeenUsed() { return m_Fpu_Used; } - - FPU_ROUND GetRoundingModel() const { return m_RoundingModel; } - void SetRoundingModel(FPU_ROUND RoundingModel) { m_RoundingModel = RoundingModel; } - -private: - const char * RoundingModelName(FPU_ROUND RoundType); - x86Reg UnMap_8BitTempReg(); - - //r4k - REG_STATE m_MIPS_RegState[32]; - MIPS_DWORD m_MIPS_RegVal[32]; - x86Reg m_RegMapHi[32]; - x86Reg m_RegMapLo[32]; - - REG_MAPPED m_x86reg_MappedTo[10]; - uint32_t m_x86reg_MapOrder[10]; - bool m_x86reg_Protected[10]; - - uint32_t m_CycleCount; - - //FPU - int32_t m_Stack_TopPos; - int32_t m_x86fpu_MappedTo[8]; - FPU_STATE m_x86fpu_State[8]; - bool m_x86fpu_StateChanged[8]; - FPU_ROUND m_x86fpu_RoundingModel[8]; - - bool m_Fpu_Used; - FPU_ROUND m_RoundingModel; - - static uint32_t m_fpuControl; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include +#include +#include + +class CRegInfo : + private CDebugSettings, + private CX86Ops, + private CSystemRegisters +{ +public: + //enums + enum REG_STATE + { + STATE_UNKNOWN = 0x00, + STATE_KNOWN_VALUE = 0x01, + STATE_X86_MAPPED = 0x02, + STATE_SIGN = 0x04, + STATE_32BIT = 0x08, + STATE_MODIFIED = 0x10, + + STATE_MAPPED_64 = (STATE_KNOWN_VALUE | STATE_X86_MAPPED), // = 3 + STATE_MAPPED_32_ZERO = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT), // = 11 + STATE_MAPPED_32_SIGN = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT | STATE_SIGN), // = 15 + + STATE_CONST_32_ZERO = (STATE_KNOWN_VALUE | STATE_32BIT), // = 9 + STATE_CONST_32_SIGN = (STATE_KNOWN_VALUE | STATE_32BIT | STATE_SIGN), // = 13 + STATE_CONST_64 = (STATE_KNOWN_VALUE), // = 1 + }; + + enum REG_MAPPED + { + NotMapped = 0, + GPR_Mapped = 1, + Temp_Mapped = 2, + Stack_Mapped = 3, + }; + + enum FPU_STATE + { + FPU_Any = -1, + FPU_Unknown = 0, + FPU_Dword = 1, + FPU_Qword = 2, + FPU_Float = 3, + FPU_Double = 4, + }; + + enum FPU_ROUND + { + RoundUnknown = -1, + RoundDefault = 0, + RoundTruncate = 1, + RoundNearest = 2, + RoundDown = 3, + RoundUp = 4, + }; + +public: + CRegInfo(); + CRegInfo(const CRegInfo&); + ~CRegInfo(); + + CRegInfo& operator=(const CRegInfo&); + + bool operator==(const CRegInfo& right) const; + bool operator!=(const CRegInfo& right) const; + + static REG_STATE ConstantsType(int64_t Value); + + void FixRoundModel(FPU_ROUND RoundMethod); + void ChangeFPURegFormat(int32_t Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel); + void Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Format); + bool RegInStack(int32_t Reg, FPU_STATE Format); + void UnMap_AllFPRs(); + void UnMap_FPR(int32_t Reg, bool WriteBackValue); + x86FpuValues StackPosition(int32_t Reg); + + x86Reg FreeX86Reg(); + x86Reg Free8BitX86Reg(); + void Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsRegToLoad); + void Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad); + x86Reg Get_MemoryStack() const; + x86Reg Map_MemoryStack(x86Reg Reg, bool bMapRegister, bool LoadValue = true); + x86Reg Map_TempReg(x86Reg Reg, int32_t MipsReg, bool LoadHiWord); + void ProtectGPR(uint32_t Reg); + void UnProtectGPR(uint32_t Reg); + void ResetX86Protection(); + x86Reg UnMap_TempReg(); + void UnMap_GPR(uint32_t Reg, bool WriteBackValue); + bool UnMap_X86reg(x86Reg Reg); + void WriteBackRegisters(); + + bool IsKnown(int32_t Reg) const { return ((GetMipsRegState(Reg) & STATE_KNOWN_VALUE) != 0); } + bool IsUnknown(int32_t Reg) const { return ((GetMipsRegState(Reg) & STATE_KNOWN_VALUE) == 0); } + bool IsModified(int32_t Reg) const { return ((GetMipsRegState(Reg) & STATE_MODIFIED) != 0); } + + bool IsMapped(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_X86_MAPPED)); } + bool IsConst(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_X86_MAPPED)) == STATE_KNOWN_VALUE); } + + bool IsSigned(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_SIGN)) == (STATE_KNOWN_VALUE | STATE_SIGN)); } + bool IsUnsigned(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_SIGN)) == STATE_KNOWN_VALUE); } + + bool Is32Bit(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT)) == (STATE_KNOWN_VALUE | STATE_32BIT)); } + bool Is64Bit(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT)) == STATE_KNOWN_VALUE); } + + bool Is32BitMapped(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)); } + bool Is64BitMapped(int32_t Reg) const { return ((GetMipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_X86_MAPPED)); } + + REG_STATE GetMipsRegState(int32_t Reg) const { return m_MIPS_RegState[Reg]; } + uint64_t GetMipsReg(int32_t Reg) const { return m_MIPS_RegVal[Reg].UDW; } + int64_t GetMipsReg_S(int32_t Reg) const { return m_MIPS_RegVal[Reg].DW; } + uint32_t GetMipsRegLo(int32_t Reg) const { return m_MIPS_RegVal[Reg].UW[0]; } + int32_t GetMipsRegLo_S(int32_t Reg) const { return m_MIPS_RegVal[Reg].W[0]; } + uint32_t GetMipsRegHi(int32_t Reg) const { return m_MIPS_RegVal[Reg].UW[1]; } + int32_t GetMipsRegHi_S(int32_t Reg) const { return m_MIPS_RegVal[Reg].W[1]; } + CX86Ops::x86Reg GetMipsRegMapLo(int32_t Reg) const { return m_RegMapLo[Reg]; } + CX86Ops::x86Reg GetMipsRegMapHi(int32_t Reg) const { return m_RegMapHi[Reg]; } + + uint32_t GetX86MapOrder(x86Reg Reg) const { return m_x86reg_MapOrder[Reg]; } + bool GetX86Protected(x86Reg Reg) const { return m_x86reg_Protected[Reg]; } + REG_MAPPED GetX86Mapped(x86Reg Reg) const { return m_x86reg_MappedTo[Reg]; } + + uint32_t GetBlockCycleCount() const { return m_CycleCount; } + + void SetMipsReg(int32_t Reg, uint64_t Value) { m_MIPS_RegVal[Reg].UDW = Value; } + void SetMipsReg_S(int32_t Reg, int64_t Value) { m_MIPS_RegVal[Reg].DW = Value; } + void SetMipsRegLo(int32_t Reg, uint32_t Value) { m_MIPS_RegVal[Reg].UW[0] = Value; } + void SetMipsRegHi(int32_t Reg, uint32_t Value) { m_MIPS_RegVal[Reg].UW[1] = Value; } + void SetMipsRegMapLo(int32_t GetMipsReg, x86Reg Reg) { m_RegMapLo[GetMipsReg] = Reg; } + void SetMipsRegMapHi(int32_t GetMipsReg, x86Reg Reg) { m_RegMapHi[GetMipsReg] = Reg; } + void SetMipsRegState(int32_t GetMipsReg, REG_STATE State) { m_MIPS_RegState[GetMipsReg] = State; } + + void SetX86MapOrder(x86Reg Reg, uint32_t Order) { m_x86reg_MapOrder[Reg] = Order; } + void SetX86Protected(x86Reg Reg, bool Protected) { m_x86reg_Protected[Reg] = Protected; } + void SetX86Mapped(x86Reg Reg, REG_MAPPED Mapping) { m_x86reg_MappedTo[Reg] = Mapping; } + + void SetBlockCycleCount(uint32_t CyleCount) { m_CycleCount = CyleCount; } + + int32_t & StackTopPos() { return m_Stack_TopPos; } + int32_t & FpuMappedTo(int32_t Reg) { return m_x86fpu_MappedTo[Reg]; } + FPU_STATE & FpuState(int32_t Reg) { return m_x86fpu_State[Reg]; } + FPU_ROUND & FpuRoundingModel(int32_t Reg) { return m_x86fpu_RoundingModel[Reg]; } + bool & FpuBeenUsed() { return m_Fpu_Used; } + + FPU_ROUND GetRoundingModel() const { return m_RoundingModel; } + void SetRoundingModel(FPU_ROUND RoundingModel) { m_RoundingModel = RoundingModel; } + +private: + const char * RoundingModelName(FPU_ROUND RoundType); + x86Reg UnMap_8BitTempReg(); + + //r4k + REG_STATE m_MIPS_RegState[32]; + MIPS_DWORD m_MIPS_RegVal[32]; + x86Reg m_RegMapHi[32]; + x86Reg m_RegMapLo[32]; + + REG_MAPPED m_x86reg_MappedTo[10]; + uint32_t m_x86reg_MapOrder[10]; + bool m_x86reg_Protected[10]; + + uint32_t m_CycleCount; + + //FPU + int32_t m_Stack_TopPos; + int32_t m_x86fpu_MappedTo[8]; + FPU_STATE m_x86fpu_State[8]; + bool m_x86fpu_StateChanged[8]; + FPU_ROUND m_x86fpu_RoundingModel[8]; + + bool m_Fpu_Used; + FPU_ROUND m_RoundingModel; + + static uint32_t m_fpuControl; +}; diff --git a/Source/Project64-core/N64System/Recompiler/SectionInfo.cpp b/Source/Project64-core/N64System/Recompiler/SectionInfo.cpp index 7824fd3de..b7ac3111e 100644 --- a/Source/Project64-core/N64System/Recompiler/SectionInfo.cpp +++ b/Source/Project64-core/N64System/Recompiler/SectionInfo.cpp @@ -1,173 +1,173 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SectionInfo.h" -#include "JumpInfo.h" - -CJumpInfo::CJumpInfo() -{ - TargetPC = (uint32_t)-1; - JumpPC = (uint32_t)-1; - BranchLabel = ""; - LinkLocation = NULL; - LinkLocation2 = NULL; - FallThrough = false; - PermLoop = false; - DoneDelaySlot = false; - ExitReason = CExitInfo::Normal; -} - -#ifdef legacycode - -bool CCodeSection::IsAllParentLoops(CCodeSection * Parent, bool IgnoreIfCompiled, uint32_t Test) -{ - if (IgnoreIfCompiled && Parent->CompiledLocation != NULL) { return true; } - if (!InLoop) { return false; } - if (!Parent->InLoop) { return false; } - if (Parent->ParentSection.empty()) { return false; } - if (this == Parent) { return true; } - if (Parent->Test == Test) { return true; } - Parent->Test = Test; - - for (SECTION_LIST::iterator iter = Parent->ParentSection.begin(); iter != Parent->ParentSection.end(); iter++) - { - CCodeSection * ParentSection = *iter; - if (!IsAllParentLoops(ParentSection,IgnoreIfCompiled,Test)) { return false; } - } - return true; -} - -void CCodeSection::UnlinkParent( CCodeSection * Parent, bool AllowDelete, bool ContinueSection ) -{ - if (this == NULL) - { - return; - } - - SECTION_LIST::iterator iter = ParentSection.begin(); - while ( iter != ParentSection.end()) - { - CCodeSection * ParentIter = *iter; - if (ParentIter == Parent && (Parent->ContinueSection != this || Parent->JumpSection != this)) - { - ParentSection.erase(iter); - iter = ParentSection.begin(); - } else { - iter++; - } - } - - // if (Parent->ContinueSection != Parent->JumpSection) - // { - // if (!ContinueSection && Parent->ContinueSection == this) - // { - // g_Notify->BreakPoint(__FILE__, __LINE__); - // } - // } - if (ContinueSection && Parent->ContinueSection == this) - { - Parent->ContinueSection = NULL; - } - // if (Parent->ContinueSection != Parent->JumpSection) - // { - // if (ContinueSection && Parent->JumpSection == this) - // { - // g_Notify->BreakPoint(__FILE__, __LINE__); - // } - // } - if (!ContinueSection && Parent->JumpSection == this) - { - Parent->JumpSection = NULL; - } - if (AllowDelete) - { - bool KillMe = true; - for (SECTION_LIST::iterator iter = ParentSection.begin(); iter != ParentSection.end(); iter++) - { - if (!IsAllParentLoops(*iter,false,GetNewTestValue())) - { - KillMe = false; - break; - } - } - if (KillMe) - { - delete this; - } - } -} - -CCodeSection::~CCodeSection() -{ - while (ParentSection.size() > 0) - { - CCodeSection * Parent = *ParentSection.begin(); - if (Parent->ContinueSection == this) { UnlinkParent(Parent, false, true); } - if (Parent->JumpSection == this) { UnlinkParent(Parent, false, false); } - } - - if (ContinueSection) - { - ContinueSection->UnlinkParent(this, true, true); - if (ContinueSection) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - ContinueSection = NULL; - } - if (JumpSection) - { - JumpSection->UnlinkParent(this, true, false); - if (JumpSection) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - JumpSection = NULL; - } -} - -uint32_t CCodeSection::GetNewTestValue() -{ - static uint32_t LastTest = 0; - if (LastTest == 0xFFFFFFFF) { LastTest = 0; } - LastTest += 1; - return LastTest; -} - -void CRegInfo::Initialize() -{ - int count; - - MIPS_RegState[0] = STATE_CONST_32_SIGN; - MIPS_RegVal[0].DW = 0; - for (count = 1; count < 32; count ++ ) { - MIPS_RegState[count] = STATE_UNKNOWN; - MIPS_RegVal[count].DW = 0; - } - for (count = 0; count < 10; count ++ ) { - x86reg_MappedTo[count] = NotMapped; - x86reg_Protected[count] = false; - x86reg_MapOrder[count] = 0; - } - CycleCount = 0; - RandomModifier = 0; - - Stack_TopPos = 0; - for (count = 0; count < 8; count ++ ) { - x86fpu_MappedTo[count] = -1; - x86fpu_State[count] = FPU_Unkown; - x86fpu_RoundingModel[count] = RoundDefault; - } - Fpu_Used = false; - RoundingModel = RoundUnknown; -} - +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SectionInfo.h" +#include "JumpInfo.h" + +CJumpInfo::CJumpInfo() +{ + TargetPC = (uint32_t)-1; + JumpPC = (uint32_t)-1; + BranchLabel = ""; + LinkLocation = NULL; + LinkLocation2 = NULL; + FallThrough = false; + PermLoop = false; + DoneDelaySlot = false; + ExitReason = CExitInfo::Normal; +} + +#ifdef legacycode + +bool CCodeSection::IsAllParentLoops(CCodeSection * Parent, bool IgnoreIfCompiled, uint32_t Test) +{ + if (IgnoreIfCompiled && Parent->CompiledLocation != NULL) { return true; } + if (!InLoop) { return false; } + if (!Parent->InLoop) { return false; } + if (Parent->ParentSection.empty()) { return false; } + if (this == Parent) { return true; } + if (Parent->Test == Test) { return true; } + Parent->Test = Test; + + for (SECTION_LIST::iterator iter = Parent->ParentSection.begin(); iter != Parent->ParentSection.end(); iter++) + { + CCodeSection * ParentSection = *iter; + if (!IsAllParentLoops(ParentSection,IgnoreIfCompiled,Test)) { return false; } + } + return true; +} + +void CCodeSection::UnlinkParent( CCodeSection * Parent, bool AllowDelete, bool ContinueSection ) +{ + if (this == NULL) + { + return; + } + + SECTION_LIST::iterator iter = ParentSection.begin(); + while ( iter != ParentSection.end()) + { + CCodeSection * ParentIter = *iter; + if (ParentIter == Parent && (Parent->ContinueSection != this || Parent->JumpSection != this)) + { + ParentSection.erase(iter); + iter = ParentSection.begin(); + } else { + iter++; + } + } + + // if (Parent->ContinueSection != Parent->JumpSection) + // { + // if (!ContinueSection && Parent->ContinueSection == this) + // { + // g_Notify->BreakPoint(__FILE__, __LINE__); + // } + // } + if (ContinueSection && Parent->ContinueSection == this) + { + Parent->ContinueSection = NULL; + } + // if (Parent->ContinueSection != Parent->JumpSection) + // { + // if (ContinueSection && Parent->JumpSection == this) + // { + // g_Notify->BreakPoint(__FILE__, __LINE__); + // } + // } + if (!ContinueSection && Parent->JumpSection == this) + { + Parent->JumpSection = NULL; + } + if (AllowDelete) + { + bool KillMe = true; + for (SECTION_LIST::iterator iter = ParentSection.begin(); iter != ParentSection.end(); iter++) + { + if (!IsAllParentLoops(*iter,false,GetNewTestValue())) + { + KillMe = false; + break; + } + } + if (KillMe) + { + delete this; + } + } +} + +CCodeSection::~CCodeSection() +{ + while (ParentSection.size() > 0) + { + CCodeSection * Parent = *ParentSection.begin(); + if (Parent->ContinueSection == this) { UnlinkParent(Parent, false, true); } + if (Parent->JumpSection == this) { UnlinkParent(Parent, false, false); } + } + + if (ContinueSection) + { + ContinueSection->UnlinkParent(this, true, true); + if (ContinueSection) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + ContinueSection = NULL; + } + if (JumpSection) + { + JumpSection->UnlinkParent(this, true, false); + if (JumpSection) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + JumpSection = NULL; + } +} + +uint32_t CCodeSection::GetNewTestValue() +{ + static uint32_t LastTest = 0; + if (LastTest == 0xFFFFFFFF) { LastTest = 0; } + LastTest += 1; + return LastTest; +} + +void CRegInfo::Initialize() +{ + int count; + + MIPS_RegState[0] = STATE_CONST_32_SIGN; + MIPS_RegVal[0].DW = 0; + for (count = 1; count < 32; count ++ ) { + MIPS_RegState[count] = STATE_UNKNOWN; + MIPS_RegVal[count].DW = 0; + } + for (count = 0; count < 10; count ++ ) { + x86reg_MappedTo[count] = NotMapped; + x86reg_Protected[count] = false; + x86reg_MapOrder[count] = 0; + } + CycleCount = 0; + RandomModifier = 0; + + Stack_TopPos = 0; + for (count = 0; count < 8; count ++ ) { + x86fpu_MappedTo[count] = -1; + x86fpu_State[count] = FPU_Unkown; + x86fpu_RoundingModel[count] = RoundDefault; + } + Fpu_Used = false; + RoundingModel = RoundUnknown; +} + #endif \ No newline at end of file diff --git a/Source/Project64-core/N64System/Recompiler/SectionInfo.h b/Source/Project64-core/N64System/Recompiler/SectionInfo.h index 0a1788dad..cd63b1845 100644 --- a/Source/Project64-core/N64System/Recompiler/SectionInfo.h +++ b/Source/Project64-core/N64System/Recompiler/SectionInfo.h @@ -1,23 +1,23 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CCodeSection; -class CCodeBlock; -struct CJumpInfo; - -struct BLOCK_PARENT -{ - CCodeSection * Parent; - CJumpInfo * JumpInfo; -}; - -typedef std::vector BLOCK_PARENT_LIST; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CCodeSection; +class CCodeBlock; +struct CJumpInfo; + +struct BLOCK_PARENT +{ + CCodeSection * Parent; + CJumpInfo * JumpInfo; +}; + +typedef std::vector BLOCK_PARENT_LIST; diff --git a/Source/Project64-core/N64System/Recompiler/X86ops.cpp b/Source/Project64-core/N64System/Recompiler/X86ops.cpp index c1b681bd3..38b64ab20 100644 --- a/Source/Project64-core/N64System/Recompiler/X86ops.cpp +++ b/Source/Project64-core/N64System/Recompiler/X86ops.cpp @@ -1,4290 +1,4290 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include "x86CodeLog.h" - -#define PUTDST8(dest,value) (*((uint8_t *)(dest))=(uint8_t)(value)); dest += 1; -#define PUTDST16(dest,value) (*((uint16_t *)(dest))=(uint16_t)(value)); dest += 2; -#define PUTDST32(dest,value) (*((uint32_t *)(dest))=(uint32_t)(value)); dest += 4; - -uint8_t * CX86Ops::m_RecompPos; - -char CX86Ops::m_fpupop[2][2] = -{ - "", "p" -}; - -CX86Ops::x86Reg CX86Ops::x86_Registers[8] = -{ - x86_ESI, - x86_EDI, - x86_EBX, - x86_ECX, - x86_EDX, - x86_EAX, - x86_EBP, - x86_ESP -}; - -/************************************************************************** -* Logging Functions * -**************************************************************************/ -void CX86Ops::WriteX86Comment(const char * Comment) -{ - CPU_Message(""); - CPU_Message(" // %s", Comment); -} - -void CX86Ops::WriteX86Label(const char * Label) -{ - CPU_Message(""); - CPU_Message(" %s:", Label); -} - -void CX86Ops::AdcX86regToVariable(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" adc dword ptr [%s], %s", VariableName, x86_Name(reg)); - PUTDST16(m_RecompPos, 0x0511 + (reg * 0x100)); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::AdcConstToVariable(void *Variable, const char * VariableName, uint8_t Constant) -{ - CPU_Message(" adc dword ptr [%s], %Xh", VariableName, Constant); - PUTDST16(m_RecompPos, 0x1583); - PUTDST32(m_RecompPos, Variable); - PUTDST8(m_RecompPos, Constant); -} - -void CX86Ops::AdcConstToX86Reg(x86Reg reg, uint32_t Const) -{ - CPU_Message(" adc %s, %Xh", x86_Name(reg), Const); - if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - PUTDST16(m_RecompPos, 0xD081 + (reg * 0x100)); - PUTDST32(m_RecompPos, Const); - } - else - { - PUTDST16(m_RecompPos, 0xD083 + (reg * 0x100)); - PUTDST8(m_RecompPos, Const); - } -} - -void CX86Ops::AdcVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" adc %s, dword ptr [%s]", x86_Name(reg), VariableName); - PUTDST16(m_RecompPos, 0x0513 + (reg * 0x800)); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::AdcX86RegToX86Reg(x86Reg Destination, x86Reg Source) -{ - CPU_Message(" adc %s, %s", x86_Name(Destination), x86_Name(Source)); - PUTDST16(m_RecompPos, 0xC013 + (Source * 0x100) + (Destination * 0x800)); -} - -void CX86Ops::AddConstToVariable(uint32_t Const, void *Variable, const char * VariableName) -{ - CPU_Message(" add dword ptr [%s], 0x%X", VariableName, Const); - PUTDST16(m_RecompPos, 0x0581); - PUTDST32(m_RecompPos, Variable); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::AddConstToX86Reg(x86Reg reg, uint32_t Const) -{ - if (Const == 0) - { - } - else if (Const == 1) - { - IncX86reg(reg); - } - else if (Const == 0xFFFFFFFF) - { - DecX86reg(reg); - } - else if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - CPU_Message(" add %s, %Xh", x86_Name(reg), Const); - PUTDST16(m_RecompPos, 0xC081 + (reg * 0x100)); - PUTDST32(m_RecompPos, Const); - } - else - { - CPU_Message(" add %s, %Xh", x86_Name(reg), Const); - PUTDST16(m_RecompPos, 0xC083 + (reg * 0x100)); - PUTDST8(m_RecompPos, Const); - } -} - -void CX86Ops::AddVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" add %s, dword ptr [%s]", x86_Name(reg), VariableName); - PUTDST16(m_RecompPos, 0x0503 + (reg * 0x800)); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::AddX86regToVariable(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" add dword ptr [%s], %s", VariableName, x86_Name(reg)); - PUTDST16(m_RecompPos, 0x0501 + (reg * 0x800)); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::AddX86RegToX86Reg(x86Reg Destination, x86Reg Source) -{ - CPU_Message(" add %s, %s", x86_Name(Destination), x86_Name(Source)); - PUTDST16(m_RecompPos, 0xC003 + (Source * 0x100) + (Destination * 0x800)); -} - -void CX86Ops::AndConstToVariable(uint32_t Const, void *Variable, const char * VariableName) -{ - CPU_Message(" and dword ptr [%s], 0x%X", VariableName, Const); - PUTDST16(m_RecompPos, 0x2581); - PUTDST32(m_RecompPos, Variable); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::AndConstToX86Reg(x86Reg reg, uint32_t Const) -{ - CPU_Message(" and %s, %Xh", x86_Name(reg), Const); - if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - PUTDST16(m_RecompPos, 0xE081 + (reg * 0x100)); - PUTDST32(m_RecompPos, Const); - } - else - { - PUTDST16(m_RecompPos, 0xE083 + (reg * 0x100)); - PUTDST8(m_RecompPos, Const); - } -} - -void CX86Ops::AndVariableDispToX86Reg(void *Variable, const char * VariableName, x86Reg reg, x86Reg AddrReg, Multipler Multiply) -{ - CPU_Message(" and %s, dword ptr [%s+%s*%i]", x86_Name(reg), VariableName, x86_Name(AddrReg), Multiply); - - PUTDST16(m_RecompPos, 0x0423 + (reg * 0x800)); - PUTDST8(m_RecompPos, 0x05 + CalcMultiplyCode(Multiply) + (AddrReg * 0x8)); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::AndVariableToX86Reg(void * Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" and %s, dword ptr [%s]", x86_Name(reg), VariableName); - PUTDST16(m_RecompPos, 0x0523 + (reg * 0x800)); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::AndX86RegToX86Reg(x86Reg Destination, x86Reg Source) -{ - CPU_Message(" and %s, %s", x86_Name(Destination), x86_Name(Source)); - PUTDST16(m_RecompPos, 0xC021 + (Destination * 0x100) + (Source * 0x800)); -} - -void CX86Ops::BreakPointNotification(const char * FileName, int32_t LineNumber) -{ - g_Notify->BreakPoint(FileName, LineNumber); -} - -void CX86Ops::X86HardBreakPoint() -{ - CPU_Message(" int 3"); - PUTDST8(m_RecompPos, 0xCC); -} - -void CX86Ops::X86BreakPoint(const char * FileName, int LineNumber) -{ - Pushad(); - PushImm32(stdstr_f("%d", LineNumber).c_str(), LineNumber); - PushImm32(FileName, (uint32_t)FileName); - Call_Direct((void *)BreakPointNotification, "BreakPointNotification"); - AddConstToX86Reg(x86_ESP, 8); - Popad(); -} - -void CX86Ops::Call_Direct(void * FunctAddress, const char * FunctName) -{ - CPU_Message(" call offset %s", FunctName); - PUTDST8(m_RecompPos, 0xE8); - PUTDST32(m_RecompPos, (uint32_t)FunctAddress - (uint32_t)m_RecompPos - 4); -} - -void CX86Ops::Call_Indirect(void * FunctAddress, const char * FunctName) -{ - CPU_Message(" call [%s]", FunctName); - PUTDST16(m_RecompPos, 0x15FF); - PUTDST32(m_RecompPos, FunctAddress); -} - -void CX86Ops::CompConstToVariable(uint32_t Const, void * Variable, const char * VariableName) -{ - CPU_Message(" cmp dword ptr [%s], 0x%X", VariableName, Const); - PUTDST16(m_RecompPos, 0x3D81); - PUTDST32(m_RecompPos, Variable); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::CompConstToX86reg(x86Reg reg, uint32_t Const) -{ - if (Const == 0) - { - OrX86RegToX86Reg(reg, reg); - } - else - { - CPU_Message(" cmp %s, %Xh", x86_Name(reg), Const); - if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - PUTDST16(m_RecompPos, 0xF881 + (reg * 0x100)); - PUTDST32(m_RecompPos, Const); - } - else - { - PUTDST16(m_RecompPos, 0xF883 + (reg * 0x100)); - PUTDST8(m_RecompPos, Const); - } - } -} - -void CX86Ops::CompConstToX86regPointer(x86Reg reg, uint32_t Const) -{ - if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - CPU_Message(" cmp dword ptr [%s], %Xh", x86_Name(reg), Const); - PUTDST16(m_RecompPos, 0x3881 + (reg * 0x100)); - PUTDST32(m_RecompPos, Const); - } - else - { - CPU_Message(" cmp byte ptr [%s], %Xh", x86_Name(reg), Const); - PUTDST16(m_RecompPos, 0x3883 + (reg * 0x100)); - PUTDST8(m_RecompPos, Const); - } -} - -void CX86Ops::CompX86regToVariable(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" cmp %s, dword ptr [%s]", x86_Name(reg), VariableName); - PUTDST16(m_RecompPos, 0x053B + (reg * 0x800)); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::CompVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" cmp dword ptr [%s], %s", VariableName, x86_Name(reg)); - PUTDST16(m_RecompPos, 0x0539 + (reg * 0x800)); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::CompX86RegToX86Reg(x86Reg Destination, x86Reg Source) -{ - uint16_t x86Command = 0; - - CPU_Message(" cmp %s, %s", x86_Name(Destination), x86_Name(Source)); - - switch (Source) - { - case x86_EAX: x86Command = 0x003B; break; - case x86_EBX: x86Command = 0x033B; break; - case x86_ECX: x86Command = 0x013B; break; - case x86_EDX: x86Command = 0x023B; break; - case x86_ESI: x86Command = 0x063B; break; - case x86_EDI: x86Command = 0x073B; break; - case x86_ESP: x86Command = 0x043B; break; - case x86_EBP: x86Command = 0x053B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (Destination) - { - case x86_EAX: x86Command += 0xC000; break; - case x86_EBX: x86Command += 0xD800; break; - case x86_ECX: x86Command += 0xC800; break; - case x86_EDX: x86Command += 0xD000; break; - case x86_ESI: x86Command += 0xF000; break; - case x86_EDI: x86Command += 0xF800; break; - case x86_ESP: x86Command += 0xE000; break; - case x86_EBP: x86Command += 0xE800; break; - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::DecX86reg(x86Reg reg) -{ - CPU_Message(" dec %s", x86_Name(reg)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xC8FF); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xCBFF); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xC9FF); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xCAFF); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xCEFF); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xCFFF); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x4C); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x4D); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::DivX86reg(x86Reg reg) -{ - CPU_Message(" div %s", x86_Name(reg)); - switch (reg) - { - case x86_EBX: PUTDST16(m_RecompPos, 0xf3F7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xf1F7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xf2F7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xf6F7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xf7F7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xf4F7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xf5F7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::idivX86reg(x86Reg reg) -{ - CPU_Message(" idiv %s", x86_Name(reg)); - - switch (reg) - { - case x86_EBX: PUTDST16(m_RecompPos, 0xfbF7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xf9F7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xfaF7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xfeF7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xffF7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xfcF7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xfdF7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::imulX86reg(x86Reg reg) -{ - CPU_Message(" imul %s", x86_Name(reg)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE8F7); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xEBF7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE9F7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xEAF7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xEEF7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xEFF7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xECF7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xEDF7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::IncX86reg(x86Reg reg) -{ - CPU_Message(" inc %s", x86_Name(reg)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xC0FF); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xC3FF); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xC1FF); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xC2FF); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xC6FF); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xC7FF); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x44); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x45); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::JaeLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jae $%s", Label); - PUTDST8(m_RecompPos, 0x73); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JaeLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" jae $%s", Label); - PUTDST16(m_RecompPos, 0x830F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JaLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" ja $%s", Label); - PUTDST8(m_RecompPos, 0x77); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JaLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" ja $%s", Label); - PUTDST16(m_RecompPos, 0x870F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JbLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jb $%s", Label); - PUTDST8(m_RecompPos, 0x72); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JbLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" jb $%s", Label); - PUTDST16(m_RecompPos, 0x820F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JecxzLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jecxz $%s", Label); - PUTDST8(m_RecompPos, 0xE3); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JeLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" je $%s", Label); - PUTDST8(m_RecompPos, 0x74); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JeLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" je $%s", Label); - PUTDST16(m_RecompPos, 0x840F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JgeLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" jge $%s", Label); - PUTDST16(m_RecompPos, 0x8D0F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JgLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jg $%s", Label); - PUTDST8(m_RecompPos, 0x7F); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JgLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" jg $%s", Label); - PUTDST16(m_RecompPos, 0x8F0F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JleLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jle $%s", Label); - PUTDST8(m_RecompPos, 0x7E); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JleLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" jle $%s", Label); - PUTDST16(m_RecompPos, 0x8E0F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JlLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jl $%s", Label); - PUTDST8(m_RecompPos, 0x7C); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JlLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" jl $%s", Label); - PUTDST16(m_RecompPos, 0x8C0F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JmpDirectReg(x86Reg reg) -{ - CPU_Message(" jmp %s", x86_Name(reg)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE0ff); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xE3ff); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE1ff); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xE2ff); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xE6ff); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xE7ff); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::JmpIndirectLabel32(const char * Label, uint32_t location) -{ - CPU_Message(" jmp dword ptr [%s]", Label); - PUTDST16(m_RecompPos, 0x25ff); - PUTDST32(m_RecompPos, location); -} - -void CX86Ops::JmpIndirectReg(x86Reg reg) -{ - CPU_Message(" jmp dword ptr [%s]", x86_Name(reg)); - - switch (reg) { - case x86_EAX: PUTDST16(m_RecompPos, 0x20ff); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x23ff); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x21ff); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x22ff); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x26ff); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x27ff); break; - case x86_ESP: - PUTDST8(m_RecompPos, 0xff); - PUTDST16(m_RecompPos, 0x2434); - /* g_Notify->BreakPoint(__FILEW__,__LINE__); */ - break; - case x86_EBP: - PUTDST8(m_RecompPos, 0xff); - PUTDST16(m_RecompPos, 0x0065); - /* g_Notify->BreakPoint(__FILEW__,__LINE__); */ - break; - } -} - -void CX86Ops::JmpLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jmp $%s", Label); - PUTDST8(m_RecompPos, 0xEB); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JmpLabel32(const char * Label, uint32_t Value) -{ - CPU_Message(" jmp $%s", Label); - PUTDST8(m_RecompPos, 0xE9); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JneLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jne $%s", Label); - PUTDST8(m_RecompPos, 0x75); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JneLabel32(const char *Label, uint32_t Value) -{ - CPU_Message(" jne $%s", Label); - PUTDST16(m_RecompPos, 0x850F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JnsLabel8(const char * Label, uint8_t Value) -{ - CPU_Message(" jns $%s", Label); - PUTDST8(m_RecompPos, 0x79); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JnsLabel32(const char *Label, uint32_t Value) -{ - CPU_Message(" jns $%s", Label); - PUTDST16(m_RecompPos, 0x890F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JnzLabel8(const char *Label, uint8_t Value) -{ - CPU_Message(" jnz $%s", Label); - PUTDST8(m_RecompPos, 0x75); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JnzLabel32(const char *Label, uint32_t Value) -{ - CPU_Message(" jnz $%s", Label); - PUTDST16(m_RecompPos, 0x850F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JsLabel32(const char *Label, uint32_t Value) -{ - CPU_Message(" js $%s", Label); - PUTDST16(m_RecompPos, 0x880F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::JzLabel8(const char *Label, uint8_t Value) -{ - CPU_Message(" jz $%s", Label); - PUTDST8(m_RecompPos, 0x74); - PUTDST8(m_RecompPos, Value); -} - -void CX86Ops::JzLabel32(const char *Label, uint32_t Value) -{ - CPU_Message(" jz $%s", Label); - PUTDST16(m_RecompPos, 0x840F); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::LeaRegReg(x86Reg RegDest, x86Reg RegSrc, uint32_t Const, Multipler multiplier) -{ - if (Const != 0) - { - CPU_Message(" lea %s, [%s*%i+%X]", x86_Name(RegDest), x86_Name(RegSrc), multiplier, Const); - } - else { - CPU_Message(" lea %s, [%s*%i]", x86_Name(RegDest), x86_Name(RegSrc), multiplier); - } - - PUTDST8(m_RecompPos, 0x8D); - PUTDST8(m_RecompPos, 0x04 + (RegDest * 8)); - PUTDST8(m_RecompPos, 0x05 + (RegSrc * 8) + CalcMultiplyCode(multiplier)); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::LeaRegReg2(x86Reg RegDest, x86Reg RegSrc, x86Reg RegSrc2, Multipler multiplier) -{ - CPU_Message(" lea %s, [%s+%s*%i]", x86_Name(RegDest), x86_Name(RegSrc), x86_Name(RegSrc2), multiplier); - - if (RegSrc2 == x86_ESP || RegSrc2 == x86_EBP) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - PUTDST8(m_RecompPos, 0x8D); - PUTDST8(m_RecompPos, 0x04 + (RegDest * 0x8)); - PUTDST8(m_RecompPos, 0x05 + (RegSrc * 0x8) + RegSrc2 + CalcMultiplyCode(multiplier)); -} - -void CX86Ops::LeaSourceAndOffset(x86Reg x86DestReg, x86Reg x86SourceReg, int offset) -{ - uint16_t x86Command = 0; - - CPU_Message(" lea %s, [%s + %0Xh]", x86_Name(x86DestReg), x86_Name(x86SourceReg), offset); - - // if ((offset & 0xFFFFFF80) != 0 && (offset & 0xFFFFFF80) != 0xFFFFFF80) { - if (1) - { - switch (x86DestReg) - { - case x86_EAX: x86Command = 0x808D; break; - case x86_EBX: x86Command = 0x988D; break; - case x86_ECX: x86Command = 0x888D; break; - case x86_EDX: x86Command = 0x908D; break; - case x86_ESI: x86Command = 0xB08D; break; - case x86_EDI: x86Command = 0xB88D; break; - case x86_ESP: x86Command = 0xA08D; break; - case x86_EBP: x86Command = 0xA88D; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (x86SourceReg) - { - case x86_EAX: x86Command += 0x0000; break; - case x86_EBX: x86Command += 0x0300; break; - case x86_ECX: x86Command += 0x0100; break; - case x86_EDX: x86Command += 0x0200; break; - case x86_ESI: x86Command += 0x0600; break; - case x86_EDI: x86Command += 0x0700; break; - case x86_ESP: x86Command += 0x0400; break; - case x86_EBP: x86Command += 0x0500; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, offset); - } - else - { - switch (x86DestReg) - { - case x86_EAX: x86Command = 0x408D; break; - case x86_EBX: x86Command = 0x588D; break; - case x86_ECX: x86Command = 0x488D; break; - case x86_EDX: x86Command = 0x508D; break; - case x86_ESI: x86Command = 0x708D; break; - case x86_EDI: x86Command = 0x788D; break; - case x86_ESP: x86Command = 0x608D; break; - case x86_EBP: x86Command = 0x688D; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (x86SourceReg) - { - case x86_EAX: x86Command += 0x0000; break; - case x86_EBX: x86Command += 0x0300; break; - case x86_ECX: x86Command += 0x0100; break; - case x86_EDX: x86Command += 0x0200; break; - case x86_ESI: x86Command += 0x0600; break; - case x86_EDI: x86Command += 0x0700; break; - case x86_ESP: x86Command += 0x0400; break; - case x86_EBP: x86Command += 0x0500; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); - PUTDST8(m_RecompPos, offset); - } -} - -void CX86Ops::MoveConstByteToN64Mem(uint8_t Const, x86Reg AddrReg) -{ - CPU_Message(" mov byte ptr [%s+N64mem], %Xh", x86_Name(AddrReg), Const); - switch (AddrReg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x80C6); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x83C6); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x81C6); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x82C6); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x86C6); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x87C6); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x84C6); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x85C6); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, g_MMU->Rdram()); - PUTDST8(m_RecompPos, Const); -} - -void CX86Ops::MoveConstByteToVariable(uint8_t Const, void *Variable, const char * VariableName) -{ - CPU_Message(" mov byte ptr [%s], %Xh", VariableName, Const); - PUTDST16(m_RecompPos, 0x05C6); - PUTDST32(m_RecompPos, Variable); - PUTDST8(m_RecompPos, Const); -} - -void CX86Ops::MoveConstHalfToN64Mem(uint16_t Const, x86Reg AddrReg) -{ - CPU_Message(" mov word ptr [%s+N64mem], %Xh", x86_Name(AddrReg), Const); - PUTDST8(m_RecompPos, 0x66); - switch (AddrReg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x80C7); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x83C7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x81C7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x82C7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x86C7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x87C7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x84C7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x85C7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, g_MMU->Rdram()); - PUTDST16(m_RecompPos, Const); -} - -void CX86Ops::MoveConstHalfToVariable(uint16_t Const, void *Variable, const char * VariableName) -{ - CPU_Message(" mov word ptr [%s], %Xh", VariableName, Const); - PUTDST8(m_RecompPos, 0x66); - PUTDST16(m_RecompPos, 0x05C7); - PUTDST32(m_RecompPos, Variable); - PUTDST16(m_RecompPos, Const); -} - -void CX86Ops::MoveConstHalfToX86regPointer(uint16_t Const, x86Reg AddrReg1, x86Reg AddrReg2) -{ - uint8_t Param = 0; - - CPU_Message(" mov word ptr [%s+%s],%Xh", x86_Name(AddrReg1), x86_Name(AddrReg2), Const); - - PUTDST8(m_RecompPos, 0x66); - PUTDST16(m_RecompPos, 0x04C7); - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); - PUTDST16(m_RecompPos, Const); -} - -void CX86Ops::MoveConstToMemoryDisp(uint32_t Const, x86Reg AddrReg, uint32_t Disp) -{ - CPU_Message(" mov dword ptr [%s+%Xh], %Xh", x86_Name(AddrReg), Disp, Const); - switch (AddrReg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x80C7); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x83C7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x81C7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x82C7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x86C7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x87C7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x84C7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x85C7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Disp); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::MoveConstToN64Mem(uint32_t Const, x86Reg AddrReg) -{ - CPU_Message(" mov dword ptr [%s+N64mem], %Xh", x86_Name(AddrReg), Const); - switch (AddrReg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x80C7); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x83C7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x81C7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x82C7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x86C7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x87C7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x84C7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x85C7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, g_MMU->Rdram()); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::MoveConstToN64MemDisp(uint32_t Const, x86Reg AddrReg, uint8_t Disp) -{ - CPU_Message(" mov dword ptr [%s+N64mem+%Xh], %Xh", x86_Name(AddrReg), Const, Disp); - switch (AddrReg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x80C7); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x83C7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x81C7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x82C7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x86C7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x87C7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x84C7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x85C7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, g_MMU->Rdram() + Disp); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::MoveConstToVariable(uint32_t Const, void *Variable, const char * VariableName) -{ - CPU_Message(" mov dword ptr [%s], %Xh", VariableName, Const); - PUTDST16(m_RecompPos, 0x05C7); - PUTDST32(m_RecompPos, Variable); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::MoveConstToX86Pointer(uint32_t Const, x86Reg X86Pointer) -{ - CPU_Message(" mov dword ptr [%s], %Xh", x86_Name(X86Pointer), Const); - PUTDST16(m_RecompPos, 0x00C7 + (X86Pointer * 0x100)); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::MoveConstToX86reg(uint32_t Const, x86Reg reg) -{ - if (Const == 0) - { - XorX86RegToX86Reg(reg, reg); - } - else - { - CPU_Message(" mov %s, %Xh", x86_Name(reg), Const); - PUTDST16(m_RecompPos, 0xC0C7 + (reg * 0x100)); - PUTDST32(m_RecompPos, Const); - } -} - -void CX86Ops::MoveConstByteToX86regPointer(uint8_t Const, x86Reg AddrReg1, x86Reg AddrReg2) -{ - uint8_t Param = 0; - - CPU_Message(" mov byte ptr [%s+%s],%Xh", x86_Name(AddrReg1), x86_Name(AddrReg2), Const); - - PUTDST16(m_RecompPos, 0x04C6); - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); - PUTDST8(m_RecompPos, Const); -} - -void CX86Ops::MoveConstToX86regPointer(uint32_t Const, x86Reg AddrReg1, x86Reg AddrReg2) -{ - uint8_t Param = 0; - - CPU_Message(" mov dword ptr [%s+%s],%Xh", x86_Name(AddrReg1), x86_Name(AddrReg2), Const); - - PUTDST16(m_RecompPos, 0x04C7); - - switch (AddrReg1) { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::MoveN64MemDispToX86reg(x86Reg reg, x86Reg AddrReg, uint8_t Disp) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov %s, dword ptr [%s+N64mem+%Xh]", x86_Name(reg), x86_Name(AddrReg), Disp); - switch (AddrReg) - { - case x86_EAX: x86Command = 0x008B; break; - case x86_EBX: x86Command = 0x038B; break; - case x86_ECX: x86Command = 0x018B; break; - case x86_EDX: x86Command = 0x028B; break; - case x86_ESI: x86Command = 0x068B; break; - case x86_EDI: x86Command = 0x078B; break; - case x86_ESP: x86Command = 0x048B; break; - case x86_EBP: x86Command = 0x058B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram() + Disp); -} - -void CX86Ops::MoveN64MemToX86reg(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov %s, dword ptr [%s+N64mem]", x86_Name(reg), x86_Name(AddrReg)); - - switch (AddrReg) - { - case x86_EAX: x86Command = 0x008B; break; - case x86_EBX: x86Command = 0x038B; break; - case x86_ECX: x86Command = 0x018B; break; - case x86_EDX: x86Command = 0x028B; break; - case x86_ESI: x86Command = 0x068B; break; - case x86_EDI: x86Command = 0x078B; break; - case x86_ESP: x86Command = 0x048B; break; - case x86_EBP: x86Command = 0x058B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveN64MemToX86regByte(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov %s, byte ptr [%s+N64mem]", x86_ByteName(reg), x86_Name(AddrReg)); - switch (AddrReg) - { - case x86_EAX: x86Command = 0x008A; break; - case x86_EBX: x86Command = 0x038A; break; - case x86_ECX: x86Command = 0x018A; break; - case x86_EDX: x86Command = 0x028A; break; - case x86_ESI: x86Command = 0x068A; break; - case x86_EDI: x86Command = 0x078A; break; - case x86_ESP: x86Command = 0x048A; break; - case x86_EBP: x86Command = 0x058A; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - /* case x86_ESI: x86Command += 0xB000; break; */ - /* case x86_EDI: x86Command += 0xB800; break; */ - /* case x86_ESP: case x86_EBP: */ - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov %s, word ptr [%s+N64mem]", x86_HalfName(reg), x86_Name(AddrReg)); - - PUTDST8(m_RecompPos, 0x66); - switch (AddrReg) - { - case x86_EAX: x86Command = 0x008B; break; - case x86_EBX: x86Command = 0x038B; break; - case x86_ECX: x86Command = 0x018B; break; - case x86_EDX: x86Command = 0x028B; break; - case x86_ESI: x86Command = 0x068B; break; - case x86_EDI: x86Command = 0x078B; break; - case x86_ESP: x86Command = 0x048B; break; - case x86_EBP: x86Command = 0x058B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveSxByteX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) -{ - uint8_t Param = 0; - - CPU_Message(" movsx %s, byte ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); - - PUTDST16(m_RecompPos, 0xBE0F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); -} - -void CX86Ops::MoveSxHalfX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) -{ - uint8_t Param = 0; - - CPU_Message(" movsx %s, word ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); - - PUTDST16(m_RecompPos, 0xBF0F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); -} - -void CX86Ops::MoveSxN64MemToX86regByte(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" movsx %s, byte ptr [%s+Dmem]", x86_Name(reg), x86_Name(AddrReg)); - switch (AddrReg) - { - case x86_EAX: x86Command = 0x00BE; break; - case x86_EBX: x86Command = 0x03BE; break; - case x86_ECX: x86Command = 0x01BE; break; - case x86_EDX: x86Command = 0x02BE; break; - case x86_ESI: x86Command = 0x06BE; break; - case x86_EDI: x86Command = 0x07BE; break; - case x86_ESP: x86Command = 0x04BE; break; - case x86_EBP: x86Command = 0x05BE; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } - PUTDST8(m_RecompPos, 0x0f); - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveSxN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" movsx %s, word ptr [%s+Dmem]", x86_Name(reg), x86_Name(AddrReg)); - - switch (AddrReg) - { - case x86_EAX: x86Command = 0x00BF; break; - case x86_EBX: x86Command = 0x03BF; break; - case x86_ECX: x86Command = 0x01BF; break; - case x86_EDX: x86Command = 0x02BF; break; - case x86_ESI: x86Command = 0x06BF; break; - case x86_EDI: x86Command = 0x07BF; break; - case x86_ESP: x86Command = 0x04BF; break; - case x86_EBP: x86Command = 0x05BF; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - } - - PUTDST8(m_RecompPos, 0x0f); - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveSxVariableToX86regByte(void *Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" movsx %s, byte ptr [%s]", x86_Name(reg), VariableName); - - PUTDST16(m_RecompPos, 0xbe0f); - - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x05); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1D); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0D); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x15); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x35); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3D); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x25); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2D); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveSxVariableToX86regHalf(void *Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" movsx %s, word ptr [%s]", x86_Name(reg), VariableName); - - PUTDST16(m_RecompPos, 0xbf0f); - - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x05); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1D); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0D); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x15); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x35); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3D); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x25); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2D); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveVariableToX86reg(void *Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" mov %s, dword ptr [%s]", x86_Name(reg), VariableName); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x058B); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D8B); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D8B); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x158B); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x358B); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D8B); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x258B); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D8B); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveVariableDispToX86Reg(void *Variable, const char * VariableName, x86Reg reg, x86Reg AddrReg, int Multiplier) -{ - int x = 0; - CPU_Message(" mov %s, dword ptr [%s+%s*%i]", x86_Name(reg), VariableName, x86_Name(AddrReg), Multiplier); - - PUTDST8(m_RecompPos, 0x8B); - - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - /* put in shifter 2(01), 4(10), 8(11) */ - switch (Multiplier) - { - case 1: x = 0; break; - case 2: x = 0x40; break; - case 4: x = 0x80; break; - case 8: x = 0xC0; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - /* format xx|000000 */ - switch (AddrReg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x05 | x); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1D | x); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0D | x); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x15 | x); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x35 | x); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3D | x); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x25 | x); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2D | x); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveVariableToX86regByte(void *Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" mov %s, byte ptr [%s]", x86_ByteName(reg), VariableName); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x058A); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D8A); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D8A); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x158A); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveVariableToX86regHalf(void *Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" mov %s, word ptr [%s]", x86_HalfName(reg), VariableName); - - PUTDST8(m_RecompPos, 0x66); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x058B); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D8B); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D8B); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x158B); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x358B); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D8B); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x258B); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D8B); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveX86regByteToN64Mem(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov byte ptr [%s+N64mem], %s", x86_Name(AddrReg), x86_ByteName(reg)); - - switch (AddrReg) - { - case x86_EAX: x86Command = 0x0088; break; - case x86_EBX: x86Command = 0x0388; break; - case x86_ECX: x86Command = 0x0188; break; - case x86_EDX: x86Command = 0x0288; break; - case x86_ESI: x86Command = 0x0688; break; - case x86_EDI: x86Command = 0x0788; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveX86regByteToVariable(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" mov byte ptr [%s], %s", VariableName, x86_ByteName(reg)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x0588); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D88); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D88); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x1588); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveX86regByteToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2) -{ - uint8_t Param = 0; - - CPU_Message(" mov byte ptr [%s+%s],%s", x86_Name(AddrReg1), x86_Name(AddrReg2), x86_ByteName(reg)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x0488); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1C88); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0C88); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x1488); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x3488); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3C88); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x2488); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2C88); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); -} - -void CX86Ops::MoveX86regHalfToN64Mem(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov word ptr [%s+N64mem], %s", x86_Name(AddrReg), x86_HalfName(reg)); - - PUTDST8(m_RecompPos, 0x66); - switch (AddrReg) - { - case x86_EAX: x86Command = 0x0089; break; - case x86_EBX: x86Command = 0x0389; break; - case x86_ECX: x86Command = 0x0189; break; - case x86_EDX: x86Command = 0x0289; break; - case x86_ESI: x86Command = 0x0689; break; - case x86_EDI: x86Command = 0x0789; break; - case x86_ESP: x86Command = 0x0489; break; - case x86_EBP: x86Command = 0x0589; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveX86regHalfToVariable(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" mov word ptr [%s], %s", VariableName, x86_HalfName(reg)); - PUTDST8(m_RecompPos, 0x66); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x0589); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D89); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D89); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x1589); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x3589); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D89); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x2589); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D89); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveX86regHalfToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2) -{ - uint8_t Param = 0; - - CPU_Message(" mov word ptr [%s+%s],%s", x86_Name(AddrReg1), x86_Name(AddrReg2), x86_HalfName(reg)); - - PUTDST8(m_RecompPos, 0x66); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x0489); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1C89); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0C89); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x1489); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x3489); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3C89); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x2489); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2C89); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); -} - -void CX86Ops::MoveX86PointerToX86reg(x86Reg reg, x86Reg X86Pointer) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov %s, dword ptr [%s]", x86_Name(reg), x86_Name(X86Pointer)); - - switch (X86Pointer) - { - case x86_EAX: x86Command = 0x008B; break; - case x86_EBX: x86Command = 0x038B; break; - case x86_ECX: x86Command = 0x018B; break; - case x86_EDX: x86Command = 0x028B; break; - case x86_ESI: x86Command = 0x068B; break; - case x86_EDI: x86Command = 0x078B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (reg) - { - case x86_EAX: x86Command += 0x0000; break; - case x86_EBX: x86Command += 0x1800; break; - case x86_ECX: x86Command += 0x0800; break; - case x86_EDX: x86Command += 0x1000; break; - case x86_ESI: x86Command += 0x3000; break; - case x86_EDI: x86Command += 0x3800; break; - case x86_ESP: x86Command += 0x2000; break; - case x86_EBP: x86Command += 0x2800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::MoveX86PointerToX86regDisp(x86Reg reg, x86Reg X86Pointer, uint8_t Disp) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov %s, dword ptr [%s] + %d", x86_Name(reg), x86_Name(X86Pointer), Disp); - - switch (X86Pointer) - { - case x86_EAX: x86Command = 0x408B; break; - case x86_EBX: x86Command = 0x438B; break; - case x86_ECX: x86Command = 0x418B; break; - case x86_EDX: x86Command = 0x428B; break; - case x86_ESI: x86Command = 0x468B; break; - case x86_EDI: x86Command = 0x478B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (reg) - { - case x86_EAX: x86Command += 0x0000; break; - case x86_EBX: x86Command += 0x1800; break; - case x86_ECX: x86Command += 0x0800; break; - case x86_EDX: x86Command += 0x1000; break; - case x86_ESI: x86Command += 0x3000; break; - case x86_EDI: x86Command += 0x3800; break; - case x86_ESP: x86Command += 0x2000; break; - case x86_EBP: x86Command += 0x2800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); - PUTDST8(m_RecompPos, Disp); -} - -void CX86Ops::MoveX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) -{ - uint8_t Param = 0; - - CPU_Message(" mov %s, dword ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x048B); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1C8B); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0C8B); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x148B); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x348B); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3C8B); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x248B); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2C8B); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); -} - -void CX86Ops::MoveX86regPointerToX86regDisp8(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg, uint8_t offset) -{ - uint8_t Param = 0; - - CPU_Message(" mov %s, dword ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x448B); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x5C8B); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x4C8B); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x548B); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x748B); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x7C8B); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x648B); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x6C8B); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); - PUTDST8(m_RecompPos, offset); -} - -void CX86Ops::MoveX86regToMemory(x86Reg reg, x86Reg AddrReg, uint32_t Disp) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov dword ptr [%s+%X], %s", x86_Name(AddrReg), Disp, x86_Name(reg)); - switch (AddrReg) - { - case x86_EAX: x86Command = 0x0089; break; - case x86_EBX: x86Command = 0x0389; break; - case x86_ECX: x86Command = 0x0189; break; - case x86_EDX: x86Command = 0x0289; break; - case x86_ESI: x86Command = 0x0689; break; - case x86_EDI: x86Command = 0x0789; break; - case x86_ESP: x86Command = 0x0489; break; - case x86_EBP: x86Command = 0x0589; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, Disp); -} - -void CX86Ops::MoveX86regToN64Mem(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov dword ptr [%s+N64mem], %s", x86_Name(AddrReg), x86_Name(reg)); - switch (AddrReg) - { - case x86_EAX: x86Command = 0x0089; break; - case x86_EBX: x86Command = 0x0389; break; - case x86_ECX: x86Command = 0x0189; break; - case x86_EDX: x86Command = 0x0289; break; - case x86_ESI: x86Command = 0x0689; break; - case x86_EDI: x86Command = 0x0789; break; - case x86_ESP: x86Command = 0x0489; break; - case x86_EBP: x86Command = 0x0589; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveX86regToN64MemDisp(x86Reg reg, x86Reg AddrReg, uint8_t Disp) -{ - CPU_Message(" mov dword ptr [%s+N64mem+%d], %s", x86_Name(AddrReg), Disp, x86_Name(reg)); - uint16_t x86Command = 0; - - switch (AddrReg) - { - case x86_EAX: x86Command = 0x0089; break; - case x86_EBX: x86Command = 0x0389; break; - case x86_ECX: x86Command = 0x0189; break; - case x86_EDX: x86Command = 0x0289; break; - case x86_ESI: x86Command = 0x0689; break; - case x86_EDI: x86Command = 0x0789; break; - case x86_ESP: x86Command = 0x0489; break; - case x86_EBP: x86Command = 0x0589; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram() + Disp); -} - -void CX86Ops::MoveX86regToVariable(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" mov dword ptr [%s], %s", VariableName, x86_Name(reg)); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x0589); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D89); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D89); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x1589); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x3589); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D89); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x2589); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D89); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveX86RegToX86Reg(x86Reg Source, x86Reg Destination) -{ - uint16_t x86Command = 0; - - if (Source == Destination) - { - return; - } - CPU_Message(" mov %s, %s", x86_Name(Destination), x86_Name(Source)); - - switch (Destination) - { - case x86_EAX: x86Command = 0x0089; break; - case x86_EBX: x86Command = 0x0389; break; - case x86_ECX: x86Command = 0x0189; break; - case x86_EDX: x86Command = 0x0289; break; - case x86_ESI: x86Command = 0x0689; break; - case x86_EDI: x86Command = 0x0789; break; - case x86_ESP: x86Command = 0x0489; break; - case x86_EBP: x86Command = 0x0589; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (Source) - { - case x86_EAX: x86Command += 0xC000; break; - case x86_EBX: x86Command += 0xD800; break; - case x86_ECX: x86Command += 0xC800; break; - case x86_EDX: x86Command += 0xD000; break; - case x86_ESI: x86Command += 0xF000; break; - case x86_EDI: x86Command += 0xF800; break; - case x86_ESP: x86Command += 0xE000; break; - case x86_EBP: x86Command += 0xE800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::MoveX86regToX86Pointer(x86Reg reg, x86Reg X86Pointer) -{ - uint16_t x86Command = 0; - - CPU_Message(" mov dword ptr [%s], %s", x86_Name(X86Pointer), x86_Name(reg)); - - switch (X86Pointer) - { - case x86_EAX: x86Command = 0x0089; break; - case x86_EBX: x86Command = 0x0389; break; - case x86_ECX: x86Command = 0x0189; break; - case x86_EDX: x86Command = 0x0289; break; - case x86_ESI: x86Command = 0x0689; break; - case x86_EDI: x86Command = 0x0789; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (reg) - { - case x86_EAX: x86Command += 0x0000; break; - case x86_EBX: x86Command += 0x1800; break; - case x86_ECX: x86Command += 0x0800; break; - case x86_EDX: x86Command += 0x1000; break; - case x86_ESI: x86Command += 0x3000; break; - case x86_EDI: x86Command += 0x3800; break; - case x86_ESP: x86Command += 0x2000; break; - case x86_EBP: x86Command += 0x2800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::MoveX86regToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2) -{ - uint8_t Param = 0; - - CPU_Message(" mov dword ptr [%s+%s],%s", x86_Name(AddrReg1), x86_Name(AddrReg2), x86_Name(reg)); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x0489); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1C89); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0C89); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x1489); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x3489); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3C89); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x2489); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2C89); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); -} - -void CX86Ops::MoveZxByteX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) -{ - uint8_t Param = 0; - - CPU_Message(" movzx %s, byte ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); - - PUTDST16(m_RecompPos, 0xB60F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); -} - -void CX86Ops::MoveZxHalfX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) -{ - uint8_t Param = 0; - - CPU_Message(" movzx %s, word ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); - - PUTDST16(m_RecompPos, 0xB70F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg1) - { - case x86_EAX: Param = 0x00; break; - case x86_EBX: Param = 0x03; break; - case x86_ECX: Param = 0x01; break; - case x86_EDX: Param = 0x02; break; - case x86_ESI: Param = 0x06; break; - case x86_EDI: Param = 0x07; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (AddrReg2) - { - case x86_EAX: Param += 0x00; break; - case x86_EBX: Param += 0x18; break; - case x86_ECX: Param += 0x08; break; - case x86_EDX: Param += 0x10; break; - case x86_ESI: Param += 0x30; break; - case x86_EDI: Param += 0x38; break; - case x86_ESP: Param += 0x20; break; - case x86_EBP: Param += 0x28; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Param); -} - -void CX86Ops::MoveZxN64MemToX86regByte(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" movzx %s, byte ptr [%s+g_MMU->Rdram()]", x86_Name(reg), x86_Name(AddrReg)); - switch (AddrReg) - { - case x86_EAX: x86Command = 0x00B6; break; - case x86_EBX: x86Command = 0x03B6; break; - case x86_ECX: x86Command = 0x01B6; break; - case x86_EDX: x86Command = 0x02B6; break; - case x86_ESI: x86Command = 0x06B6; break; - case x86_EDI: x86Command = 0x07B6; break; - case x86_ESP: x86Command = 0x04B6; break; - case x86_EBP: x86Command = 0x05B6; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } - PUTDST8(m_RecompPos, 0x0f); - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveZxN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg) -{ - uint16_t x86Command = 0; - - CPU_Message(" movzx %s, word ptr [%s+g_MMU->Rdram()]", x86_Name(reg), x86_Name(AddrReg)); - - switch (AddrReg) - { - case x86_EAX: x86Command = 0x00B7; break; - case x86_EBX: x86Command = 0x03B7; break; - case x86_ECX: x86Command = 0x01B7; break; - case x86_EDX: x86Command = 0x02B7; break; - case x86_ESI: x86Command = 0x06B7; break; - case x86_EDI: x86Command = 0x07B7; break; - case x86_ESP: x86Command = 0x04B7; break; - case x86_EBP: x86Command = 0x05B7; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (reg) - { - case x86_EAX: x86Command += 0x8000; break; - case x86_EBX: x86Command += 0x9800; break; - case x86_ECX: x86Command += 0x8800; break; - case x86_EDX: x86Command += 0x9000; break; - case x86_ESI: x86Command += 0xB000; break; - case x86_EDI: x86Command += 0xB800; break; - case x86_ESP: x86Command += 0xA000; break; - case x86_EBP: x86Command += 0xA800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, 0x0f); - PUTDST16(m_RecompPos, x86Command); - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::MoveZxVariableToX86regByte(void *Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" movzx %s, byte ptr [%s]", x86_Name(reg), VariableName); - - PUTDST16(m_RecompPos, 0xb60f); - - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x05); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1D); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0D); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x15); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x35); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3D); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x25); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2D); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MoveZxVariableToX86regHalf(void *Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" movzx %s, word ptr [%s]", x86_Name(reg), VariableName); - - PUTDST16(m_RecompPos, 0xb70f); - - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x05); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x1D); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x0D); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x15); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x35); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x3D); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x25); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x2D); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::MulX86reg(x86Reg reg) -{ - CPU_Message(" mul %s", x86_Name(reg)); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE0F7); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xE3F7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE1F7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xE2F7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xE6F7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xE7F7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xE4F7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xE5F7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::NotX86Reg(x86Reg reg) -{ - CPU_Message(" not %s", x86_Name(reg)); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xD0F7); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xD3F7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xD1F7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xD2F7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xD6F7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xD7F7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xD4F7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xD5F7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::OrConstToVariable(uint32_t Const, void * Variable, const char * VariableName) -{ - CPU_Message(" or dword ptr [%s], 0x%X", VariableName, Const); - PUTDST16(m_RecompPos, 0x0D81); - PUTDST32(m_RecompPos, Variable); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::OrConstToX86Reg(uint32_t Const, x86Reg reg) -{ - CPU_Message(" or %s, %Xh", x86_Name(reg), Const); - if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - switch (reg) { - case x86_EAX: PUTDST16(m_RecompPos, 0xC881); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xCB81); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xC981); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xCA81); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xCE81); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xCF81); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xCC81); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xCD81); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Const); - } - else - { - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xC883); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xCB83); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xC983); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xCA83); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xCE83); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xCF83); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xCC83); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xCD83); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Const); - } -} - -void CX86Ops::OrVariableToX86Reg(void * Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" or %s, dword ptr [%s]", x86_Name(reg), VariableName); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x050B); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D0B); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D0B); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x150B); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x350B); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D0B); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x250B); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D0B); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::OrX86RegToVariable(void * Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" or dword ptr [%s], %s", VariableName, x86_Name(reg)); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x0509); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D09); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D09); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x1509); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x3509); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D09); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x2509); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D09); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::OrX86RegToX86Reg(x86Reg Destination, x86Reg Source) -{ - uint16_t x86Command = 0; - - CPU_Message(" or %s, %s", x86_Name(Destination), x86_Name(Source)); - switch (Source) - { - case x86_EAX: x86Command = 0x000B; break; - case x86_EBX: x86Command = 0x030B; break; - case x86_ECX: x86Command = 0x010B; break; - case x86_EDX: x86Command = 0x020B; break; - case x86_ESI: x86Command = 0x060B; break; - case x86_EDI: x86Command = 0x070B; break; - case x86_ESP: x86Command = 0x040B; break; - case x86_EBP: x86Command = 0x050B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (Destination) - { - case x86_EAX: x86Command += 0xC000; break; - case x86_EBX: x86Command += 0xD800; break; - case x86_ECX: x86Command += 0xC800; break; - case x86_EDX: x86Command += 0xD000; break; - case x86_ESI: x86Command += 0xF000; break; - case x86_EDI: x86Command += 0xF800; break; - case x86_ESP: x86Command += 0xE000; break; - case x86_EBP: x86Command += 0xE800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::Popad(void) -{ - CPU_Message(" popad"); - PUTDST8(m_RecompPos, 0x61); -} - -void CX86Ops::Pushad(void) -{ - CPU_Message(" pushad"); - PUTDST8(m_RecompPos, 0x60); -} - -void CX86Ops::Push(x86Reg reg) -{ - CPU_Message(" push %s", x86_Name(reg)); - - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x50); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x53); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x51); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x52); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x56); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x57); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x54); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x55); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::Pop(x86Reg reg) -{ - CPU_Message(" pop %s", x86_Name(reg)); - - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x58); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x5B); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x59); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x5A); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x5E); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x5F); break; - case x86_ESP: PUTDST8(m_RecompPos, 0x5C); break; - case x86_EBP: PUTDST8(m_RecompPos, 0x5D); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::PushImm32(uint32_t Value) -{ - PushImm32(stdstr_f("%d", Value).c_str(), Value); -} - -void CX86Ops::PushImm32(const char * String, uint32_t Value) -{ - CPU_Message(" push %s", String); - PUTDST8(m_RecompPos, 0x68); - PUTDST32(m_RecompPos, Value); -} - -void CX86Ops::Ret(void) { - CPU_Message(" ret"); - PUTDST8(m_RecompPos, 0xC3); -} - -void CX86Ops::Seta(x86Reg reg) -{ - CPU_Message(" seta %s", x86_ByteName(reg)); - PUTDST16(m_RecompPos, 0x970F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; - case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; - case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; - case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::SetaVariable(void * Variable, const char * VariableName) -{ - CPU_Message(" seta byte ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x970F); - PUTDST8(m_RecompPos, 0x05); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::Setae(x86Reg reg) -{ - CPU_Message(" setae %s", x86_ByteName(reg)); - PUTDST16(m_RecompPos, 0x930F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; - case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; - case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; - case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::Setb(x86Reg reg) -{ - CPU_Message(" setb %s", x86_ByteName(reg)); - PUTDST16(m_RecompPos, 0x920F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; - case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; - case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; - case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::SetbVariable(void * Variable, const char * VariableName) -{ - CPU_Message(" setb byte ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x920F); - PUTDST8(m_RecompPos, 0x05); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::Setg(x86Reg reg) -{ - CPU_Message(" setg %s", x86_ByteName(reg)); - PUTDST16(m_RecompPos, 0x9F0F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; - case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; - case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; - case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::SetgVariable(void * Variable, const char * VariableName) -{ - CPU_Message(" setg byte ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x9F0F); - PUTDST8(m_RecompPos, 0x05); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::Setl(x86Reg reg) -{ - CPU_Message(" setl %s", x86_ByteName(reg)); - PUTDST16(m_RecompPos, 0x9C0F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; - case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; - case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; - case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::SetlVariable(void * Variable, const char * VariableName) -{ - CPU_Message(" setl byte ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x9C0F); - PUTDST8(m_RecompPos, 0x05); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::Setz(x86Reg reg) -{ - CPU_Message(" setz %s", x86_ByteName(reg)); - PUTDST16(m_RecompPos, 0x940F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; - case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; - case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; - case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::Setnz(x86Reg reg) -{ - CPU_Message(" setnz %s", x86_ByteName(reg)); - PUTDST16(m_RecompPos, 0x950F); - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; - case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; - case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; - case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::ShiftLeftDouble(x86Reg Destination, x86Reg Source) -{ - uint8_t s = 0xC0; - - CPU_Message(" shld %s, %s, cl", x86_Name(Destination), x86_Name(Source)); - PUTDST16(m_RecompPos, 0xA50F); - - switch (Destination) - { - case x86_EAX: s |= 0x00; break; - case x86_EBX: s |= 0x03; break; - case x86_ECX: s |= 0x01; break; - case x86_EDX: s |= 0x02; break; - case x86_ESI: s |= 0x06; break; - case x86_EDI: s |= 0x07; break; - case x86_ESP: s |= 0x04; break; - case x86_EBP: s |= 0x05; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (Source) - { - case x86_EAX: s |= 0x00 << 3; break; - case x86_EBX: s |= 0x03 << 3; break; - case x86_ECX: s |= 0x01 << 3; break; - case x86_EDX: s |= 0x02 << 3; break; - case x86_ESI: s |= 0x06 << 3; break; - case x86_EDI: s |= 0x07 << 3; break; - case x86_ESP: s |= 0x04 << 3; break; - case x86_EBP: s |= 0x05 << 3; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, s); -} - -void CX86Ops::ShiftLeftDoubleImmed(x86Reg Destination, x86Reg Source, uint8_t Immediate) -{ - uint8_t s = 0xC0; - - CPU_Message(" shld %s, %s, %Xh", x86_Name(Destination), x86_Name(Source), Immediate); - PUTDST16(m_RecompPos, 0xA40F); - - switch (Destination) - { - case x86_EAX: s |= 0x00; break; - case x86_EBX: s |= 0x03; break; - case x86_ECX: s |= 0x01; break; - case x86_EDX: s |= 0x02; break; - case x86_ESI: s |= 0x06; break; - case x86_EDI: s |= 0x07; break; - case x86_ESP: s |= 0x04; break; - case x86_EBP: s |= 0x05; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (Source) - { - case x86_EAX: s |= 0x00 << 3; break; - case x86_EBX: s |= 0x03 << 3; break; - case x86_ECX: s |= 0x01 << 3; break; - case x86_EDX: s |= 0x02 << 3; break; - case x86_ESI: s |= 0x06 << 3; break; - case x86_EDI: s |= 0x07 << 3; break; - case x86_ESP: s |= 0x04 << 3; break; - case x86_EBP: s |= 0x05 << 3; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, s); - PUTDST8(m_RecompPos, Immediate); -} - -void CX86Ops::ShiftLeftSign(x86Reg reg) -{ - CPU_Message(" shl %s, cl", x86_Name(reg)); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE0D3); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xE3D3); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE1D3); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xE2D3); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xE6D3); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xE7D3); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xE4D3); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xE5D3); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::ShiftLeftSignImmed(x86Reg reg, uint8_t Immediate) -{ - CPU_Message(" shl %s, %Xh", x86_Name(reg), Immediate); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE0C1); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xE3C1); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE1C1); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xE2C1); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xE6C1); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xE7C1); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xE4C1); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xE5C1); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Immediate); -} - -void CX86Ops::ShiftRightSign(x86Reg reg) -{ - CPU_Message(" sar %s, cl", x86_Name(reg)); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xF8D3); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xFBD3); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xF9D3); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xFAD3); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xFED3); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xFFD3); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xFCD3); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xFDD3); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::ShiftRightSignImmed(x86Reg reg, uint8_t Immediate) -{ - CPU_Message(" sar %s, %Xh", x86_Name(reg), Immediate); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xF8C1); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xFBC1); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xF9C1); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xFAC1); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xFEC1); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xFFC1); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xFCC1); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xFDC1); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Immediate); -} - -void CX86Ops::ShiftRightUnsign(x86Reg reg) -{ - CPU_Message(" shr %s, cl", x86_Name(reg)); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE8D3); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xEBD3); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE9D3); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xEAD3); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xEED3); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xEFD3); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xECD3); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xEDD3); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::ShiftRightDouble(x86Reg Destination, x86Reg Source) -{ - uint8_t s = 0xC0; - - CPU_Message(" shrd %s, %s, cl", x86_Name(Destination), x86_Name(Source)); - PUTDST16(m_RecompPos, 0xAD0F); - - switch (Destination) - { - case x86_EAX: s |= 0x00; break; - case x86_EBX: s |= 0x03; break; - case x86_ECX: s |= 0x01; break; - case x86_EDX: s |= 0x02; break; - case x86_ESI: s |= 0x06; break; - case x86_EDI: s |= 0x07; break; - case x86_ESP: s |= 0x04; break; - case x86_EBP: s |= 0x05; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (Source) - { - case x86_EAX: s |= 0x00 << 3; break; - case x86_EBX: s |= 0x03 << 3; break; - case x86_ECX: s |= 0x01 << 3; break; - case x86_EDX: s |= 0x02 << 3; break; - case x86_ESI: s |= 0x06 << 3; break; - case x86_EDI: s |= 0x07 << 3; break; - case x86_ESP: s |= 0x04 << 3; break; - case x86_EBP: s |= 0x05 << 3; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, s); -} - -void CX86Ops::ShiftRightDoubleImmed(x86Reg Destination, x86Reg Source, uint8_t Immediate) -{ - uint8_t s = 0xC0; - - CPU_Message(" shrd %s, %s, %Xh", x86_Name(Destination), x86_Name(Source), Immediate); - PUTDST16(m_RecompPos, 0xAC0F); - - switch (Destination) - { - case x86_EAX: s |= 0x00; break; - case x86_EBX: s |= 0x03; break; - case x86_ECX: s |= 0x01; break; - case x86_EDX: s |= 0x02; break; - case x86_ESI: s |= 0x06; break; - case x86_EDI: s |= 0x07; break; - case x86_ESP: s |= 0x04; break; - case x86_EBP: s |= 0x05; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (Source) - { - case x86_EAX: s |= 0x00 << 3; break; - case x86_EBX: s |= 0x03 << 3; break; - case x86_ECX: s |= 0x01 << 3; break; - case x86_EDX: s |= 0x02 << 3; break; - case x86_ESI: s |= 0x06 << 3; break; - case x86_EDI: s |= 0x07 << 3; break; - case x86_ESP: s |= 0x04 << 3; break; - case x86_EBP: s |= 0x05 << 3; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, s); - PUTDST8(m_RecompPos, Immediate); -} - -void CX86Ops::ShiftRightUnsignImmed(x86Reg reg, uint8_t Immediate) -{ - CPU_Message(" shr %s, %Xh", x86_Name(reg), Immediate); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE8C1); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xEBC1); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE9C1); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xEAC1); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xEEC1); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xEFC1); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xECC1); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xEDC1); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Immediate); -} - -void CX86Ops::SbbConstFromX86Reg(x86Reg reg, uint32_t Const) -{ - CPU_Message(" sbb %s, %Xh", x86_Name(reg), Const); - if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xD881); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xDB81); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xD981); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xDA81); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xDE81); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xDF81); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xDC81); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xDD81); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Const); - } - else - { - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xD883); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xDB83); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xD983); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xDA83); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xDE83); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xDF83); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xDC83); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xDD83); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Const); - } -} - -void CX86Ops::SbbVariableFromX86reg(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" sbb %s, dword ptr [%s]", x86_Name(reg), VariableName); - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x051B); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D1B); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D1B); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x151B); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x351B); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D1B); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x251B); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D1B); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::SbbX86RegToX86Reg(x86Reg Destination, x86Reg Source) -{ - uint16_t x86Command = 0; - CPU_Message(" sbb %s, %s", x86_Name(Destination), x86_Name(Source)); - switch (Source) - { - case x86_EAX: x86Command = 0x001B; break; - case x86_EBX: x86Command = 0x031B; break; - case x86_ECX: x86Command = 0x011B; break; - case x86_EDX: x86Command = 0x021B; break; - case x86_ESI: x86Command = 0x061B; break; - case x86_EDI: x86Command = 0x071B; break; - case x86_ESP: x86Command = 0x041B; break; - case x86_EBP: x86Command = 0x051B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (Destination) - { - case x86_EAX: x86Command += 0xC000; break; - case x86_EBX: x86Command += 0xD800; break; - case x86_ECX: x86Command += 0xC800; break; - case x86_EDX: x86Command += 0xD000; break; - case x86_ESI: x86Command += 0xF000; break; - case x86_EDI: x86Command += 0xF800; break; - case x86_ESP: x86Command += 0xE000; break; - case x86_EBP: x86Command += 0xE800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::SubConstFromVariable(uint32_t Const, void *Variable, const char * VariableName) -{ - CPU_Message(" sub dword ptr [%s], 0x%X", VariableName, Const); - - PUTDST16(m_RecompPos, 0x2D81); - PUTDST32(m_RecompPos, Variable); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::SubConstFromX86Reg(x86Reg reg, uint32_t Const) -{ - CPU_Message(" sub %s, %Xh", x86_Name(reg), Const); - if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE881); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xEB81); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE981); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xEA81); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xEE81); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xEF81); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xEC81); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xED81); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Const); - } - else - { - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xE883); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xEB83); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xE983); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xEA83); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xEE83); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xEF83); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xEC83); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xED83); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Const); - } -} - -void CX86Ops::SubVariableFromX86reg(x86Reg reg, void * Variable, const char * VariableName) -{ - CPU_Message(" sub %s, dword ptr [%s]", x86_Name(reg), VariableName); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x052B); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D2B); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D2B); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x152B); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x352B); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D2B); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x252B); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D2B); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::SubX86RegToX86Reg(x86Reg Destination, x86Reg Source) -{ - uint16_t x86Command = 0; - CPU_Message(" sub %s, %s", x86_Name(Destination), x86_Name(Source)); - - switch (Source) - { - case x86_EAX: x86Command = 0x002B; break; - case x86_EBX: x86Command = 0x032B; break; - case x86_ECX: x86Command = 0x012B; break; - case x86_EDX: x86Command = 0x022B; break; - case x86_ESI: x86Command = 0x062B; break; - case x86_EDI: x86Command = 0x072B; break; - case x86_ESP: x86Command = 0x042B; break; - case x86_EBP: x86Command = 0x052B; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (Destination) - { - case x86_EAX: x86Command += 0xC000; break; - case x86_EBX: x86Command += 0xD800; break; - case x86_ECX: x86Command += 0xC800; break; - case x86_EDX: x86Command += 0xD000; break; - case x86_ESI: x86Command += 0xF000; break; - case x86_EDI: x86Command += 0xF800; break; - case x86_ESP: x86Command += 0xE000; break; - case x86_EBP: x86Command += 0xE800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::TestConstToX86Reg(uint32_t Const, x86Reg reg) -{ - CPU_Message(" test %s, 0x%X", x86_Name(reg), Const); - - switch (reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0xA9); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xC3F7); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xC1F7); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xC2F7); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xC6F7); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xC7F7); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xC4F7); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xC5F7); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::TestVariable(uint32_t Const, void * Variable, const char * VariableName) -{ - CPU_Message(" test dword ptr ds:[%s], 0x%X", VariableName, Const); - PUTDST16(m_RecompPos, 0x05F7); - PUTDST32(m_RecompPos, Variable); - PUTDST32(m_RecompPos, Const); -} - -void CX86Ops::TestX86RegToX86Reg(x86Reg Destination, x86Reg Source) -{ - uint16_t x86Command = 0; - CPU_Message(" test %s, %s", x86_Name(Destination), x86_Name(Source)); - switch (Source) - { - case x86_EAX: x86Command = 0x0085; break; - case x86_EBX: x86Command = 0x0385; break; - case x86_ECX: x86Command = 0x0185; break; - case x86_EDX: x86Command = 0x0285; break; - case x86_ESI: x86Command = 0x0685; break; - case x86_EDI: x86Command = 0x0785; break; - case x86_ESP: x86Command = 0x0485; break; - case x86_EBP: x86Command = 0x0585; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (Destination) - { - case x86_EAX: x86Command += 0xC000; break; - case x86_EBX: x86Command += 0xD800; break; - case x86_ECX: x86Command += 0xC800; break; - case x86_EDX: x86Command += 0xD000; break; - case x86_ESI: x86Command += 0xF000; break; - case x86_EDI: x86Command += 0xF800; break; - case x86_ESP: x86Command += 0xE000; break; - case x86_EBP: x86Command += 0xE800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::XorConstToX86Reg(x86Reg reg, uint32_t Const) -{ - CPU_Message(" xor %s, %Xh", x86_Name(reg), Const); - if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) - { - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xF081); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xF381); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xF181); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xF281); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xF681); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xF781); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xF481); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xF581); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Const); - } - else - { - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0xF083); break; - case x86_EBX: PUTDST16(m_RecompPos, 0xF383); break; - case x86_ECX: PUTDST16(m_RecompPos, 0xF183); break; - case x86_EDX: PUTDST16(m_RecompPos, 0xF283); break; - case x86_ESI: PUTDST16(m_RecompPos, 0xF683); break; - case x86_EDI: PUTDST16(m_RecompPos, 0xF783); break; - case x86_ESP: PUTDST16(m_RecompPos, 0xF483); break; - case x86_EBP: PUTDST16(m_RecompPos, 0xF583); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST8(m_RecompPos, Const); - } -} - -void CX86Ops::XorX86RegToX86Reg(x86Reg Source, x86Reg Destination) -{ - uint16_t x86Command = 0; - - CPU_Message(" xor %s, %s", x86_Name(Source), x86_Name(Destination)); - - switch (Source) - { - case x86_EAX: x86Command = 0x0031; break; - case x86_EBX: x86Command = 0x0331; break; - case x86_ECX: x86Command = 0x0131; break; - case x86_EDX: x86Command = 0x0231; break; - case x86_ESI: x86Command = 0x0631; break; - case x86_EDI: x86Command = 0x0731; break; - case x86_ESP: x86Command = 0x0431; break; - case x86_EBP: x86Command = 0x0531; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - switch (Destination) - { - case x86_EAX: x86Command += 0xC000; break; - case x86_EBX: x86Command += 0xD800; break; - case x86_ECX: x86Command += 0xC800; break; - case x86_EDX: x86Command += 0xD000; break; - case x86_ESI: x86Command += 0xF000; break; - case x86_EDI: x86Command += 0xF800; break; - case x86_ESP: x86Command += 0xE000; break; - case x86_EBP: x86Command += 0xE800; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::XorVariableToX86reg(void *Variable, const char * VariableName, x86Reg reg) -{ - CPU_Message(" Xor %s, dword ptr [%s]", x86_Name(reg), VariableName); - - switch (reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x0533); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x1D33); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x0D33); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x1533); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x3533); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x3D33); break; - case x86_ESP: PUTDST16(m_RecompPos, 0x2533); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x2D33); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuAbs(void) -{ - CPU_Message(" fabs ST(0)"); - PUTDST16(m_RecompPos, 0xE1D9); -} - -void CX86Ops::fpuAddDword(void *Variable, const char * VariableName) -{ - CPU_Message(" fadd ST(0), dword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x05D8); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuAddDwordRegPointer(x86Reg x86Pointer) -{ - CPU_Message(" fadd ST(0), dword ptr [%s]", x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x00D8); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x03D8); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x01D8); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x02D8); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x06D8); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x07D8); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuAddQword(void *Variable, const char * VariableName) -{ - CPU_Message(" fadd ST(0), qword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x05DC); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuAddQwordRegPointer(x86Reg x86Pointer) -{ - CPU_Message(" fadd ST(0), qword ptr [%s]", x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x00DC); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x03DC); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x01DC); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x02DC); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x06DC); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x07DC); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuAddReg(x86FpuValues x86reg) -{ - CPU_Message(" fadd ST(0), %s", fpu_Name(x86reg)); - switch (x86reg) { - case x86_ST0: PUTDST16(m_RecompPos, 0xC0D8); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xC1D8); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xC2D8); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xC3D8); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xC4D8); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xC5D8); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xC6D8); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xC7D8); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuAddRegPop(int * StackPos, x86FpuValues reg) -{ - CPU_Message(" faddp ST(0), %s", fpu_Name(reg)); - *StackPos = (*StackPos + 1) & 7; - switch (reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xC0DE); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xC1DE); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xC2DE); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xC3DE); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xC4DE); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xC5DE); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xC6DE); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xC7DE); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuComDword(void *Variable, const char * VariableName, bool Pop) -{ - CPU_Message(" fcom%s ST(0), dword ptr [%s]", m_fpupop[Pop], VariableName); - PUTDST16(m_RecompPos, Pop ? 0x1DD8 : 0x15D8); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuComDwordRegPointer(x86Reg x86Pointer, bool Pop) -{ - uint16_t x86Command; - - CPU_Message(" fcom%s ST(0), dword ptr [%s]", m_fpupop[Pop], x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: x86Command = 0x10D8; break; - case x86_EBX: x86Command = 0x13D8; break; - case x86_ECX: x86Command = 0x11D8; break; - case x86_EDX: x86Command = 0x12D8; break; - case x86_ESI: x86Command = 0x16D8; break; - case x86_EDI: x86Command = 0x17D8; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - if (Pop) - { - x86Command |= 0x0800; - } - - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::fpuComQword(void *Variable, const char * VariableName, bool Pop) -{ - CPU_Message(" fcom%s ST(0), qword ptr [%s]", m_fpupop[Pop], VariableName); - PUTDST16(m_RecompPos, Pop ? 0x1DDC : 0x15DC); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuComQwordRegPointer(x86Reg x86Pointer, bool Pop) -{ - uint16_t x86Command; - - CPU_Message(" fcom%s ST(0), qword ptr [%s]", m_fpupop[Pop], x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: x86Command = 0x10DC; break; - case x86_EBX: x86Command = 0x13DC; break; - case x86_ECX: x86Command = 0x11DC; break; - case x86_EDX: x86Command = 0x12DC; break; - case x86_ESI: x86Command = 0x16DC; break; - case x86_EDI: x86Command = 0x17DC; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - if (Pop) - { - x86Command |= 0x0800; - } - - PUTDST16(m_RecompPos, x86Command); -} - -void CX86Ops::fpuComReg(x86FpuValues x86reg, bool Pop) -{ - int s = Pop ? 0x0800 : 0x0000; - CPU_Message(" fcom%s ST(0), %s", m_fpupop[Pop], fpu_Name(x86reg)); - - switch (x86reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xD0D8 | s); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xD1D8 | s); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xD2D8 | s); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xD3D8 | s); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xD4D8 | s); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xD5D8 | s); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xD6D8 | s); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xD7D8 | s); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuDivDword(void *Variable, const char * VariableName) -{ - CPU_Message(" fdiv ST(0), dword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x35D8); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuDivDwordRegPointer(x86Reg x86Pointer) -{ - CPU_Message(" fdiv ST(0), dword ptr [%s]", x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x30D8); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x33D8); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x31D8); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x32D8); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x36D8); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x37D8); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuDivQword(void *Variable, const char * VariableName) -{ - CPU_Message(" fdiv ST(0), qword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x35DC); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuDivQwordRegPointer(x86Reg x86Pointer) -{ - CPU_Message(" fdiv ST(0), qword ptr [%s]", x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x30DC); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x33DC); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x31DC); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x32DC); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x36DC); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x37DC); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuDivReg(x86FpuValues Reg) -{ - CPU_Message(" fdiv ST(0), %s", fpu_Name(Reg)); - switch (Reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xF0D8); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xF1D8); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xF2D8); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xF3D8); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xF4D8); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xF5D8); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xF6D8); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xF7D8); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuDivRegPop(x86FpuValues reg) -{ - CPU_Message(" fdivp ST(0), %s", fpu_Name(reg)); - switch (reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xF8DE); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xF9DE); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xFADE); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xFBDE); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xFCDE); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xFDDE); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xFEDE); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xFFDE); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuExchange(x86FpuValues Reg) -{ - CPU_Message(" fxch ST(0), %s", fpu_Name(Reg)); - switch (Reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xC8D9); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xC9D9); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xCAD9); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xCBD9); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xCCD9); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xCDD9); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xCED9); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xCFD9); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuFree(x86FpuValues Reg) -{ - CPU_Message(" ffree %s", fpu_Name(Reg)); - switch (Reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xC0DD); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xC1DD); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xC2DD); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xC3DD); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xC4DD); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xC5DD); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xC6DD); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xC7DD); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuDecStack(int * StackPos) -{ - CPU_Message(" fdecstp"); - *StackPos = (*StackPos - 1) & 7; - PUTDST16(m_RecompPos, 0xF6D9); -} - -void CX86Ops::fpuIncStack(int * StackPos) -{ - CPU_Message(" fincstp"); - *StackPos = (*StackPos + 1) & 7; - PUTDST16(m_RecompPos, 0xF7D9); -} - -void CX86Ops::fpuLoadControl(void *Variable, const char * VariableName) -{ - CPU_Message(" fldcw [%s]", VariableName); - PUTDST16(m_RecompPos, 0x2DD9); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuLoadDword(int * StackPos, void *Variable, const char * VariableName) -{ - CPU_Message(" fld dword ptr [%s]", VariableName); - *StackPos = (*StackPos - 1) & 7; - PUTDST16(m_RecompPos, 0x05D9); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuLoadDwordFromX86Reg(int * StackPos, x86Reg x86reg) -{ - CPU_Message(" fld dword ptr [%s]", x86_Name(x86reg)); - *StackPos = (*StackPos - 1) & 7; - PUTDST8(m_RecompPos, 0xD9); - switch (x86reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x00); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x03); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x01); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x02); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x06); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x07); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::fpuLoadDwordFromN64Mem(int * StackPos, x86Reg x86reg) -{ - CPU_Message(" fld dword ptr [%s+N64mem]", x86_Name(x86reg)); - *StackPos = (*StackPos - 1) & 7; - switch (x86reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x80D9); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x83D9); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x81D9); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x82D9); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x86D9); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x87D9); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x85D9); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::fpuLoadInt32bFromN64Mem(int * StackPos, x86Reg x86reg) -{ - CPU_Message(" fild dword ptr [%s+N64mem]", x86_Name(x86reg)); - *StackPos = (*StackPos - 1) & 7; - switch (x86reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x80DB); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x83DB); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x81DB); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x82DB); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x86DB); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x87DB); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x85DB); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::fpuLoadIntegerDword(int * StackPos, void *Variable, const char * VariableName) -{ - CPU_Message(" fild dword ptr [%s]", VariableName); - *StackPos = (*StackPos - 1) & 7; - PUTDST16(m_RecompPos, 0x05DB); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuLoadIntegerDwordFromX86Reg(int * StackPos, x86Reg x86reg) -{ - CPU_Message(" fild dword ptr [%s]", x86_Name(x86reg)); - *StackPos = (*StackPos - 1) & 7; - PUTDST8(m_RecompPos, 0xDB); - switch (x86reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x00); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x03); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x01); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x02); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x06); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x07); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::fpuLoadIntegerQword(int * StackPos, void *Variable, const char * VariableName) -{ - CPU_Message(" fild qword ptr [%s]", VariableName); - *StackPos = (*StackPos - 1) & 7; - PUTDST16(m_RecompPos, 0x2DDF); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuLoadIntegerQwordFromX86Reg(int * StackPos, x86Reg x86reg) -{ - CPU_Message(" fild qword ptr [%s]", x86_Name(x86reg)); - *StackPos = (*StackPos - 1) & 7; - PUTDST8(m_RecompPos, 0xDF); - switch (x86reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x28); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x2B); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x29); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x2A); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x2E); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x2F); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::fpuLoadQword(int * StackPos, void *Variable, const char * VariableName) -{ - CPU_Message(" fld qword ptr [%s]", VariableName); - *StackPos = (*StackPos - 1) & 7; - PUTDST16(m_RecompPos, 0x05DD); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuLoadQwordFromX86Reg(int * StackPos, x86Reg x86reg) -{ - CPU_Message(" fld qword ptr [%s]", x86_Name(x86reg)); - *StackPos = (*StackPos - 1) & 7; - PUTDST8(m_RecompPos, 0xDD); - switch (x86reg) - { - case x86_EAX: PUTDST8(m_RecompPos, 0x00); break; - case x86_EBX: PUTDST8(m_RecompPos, 0x03); break; - case x86_ECX: PUTDST8(m_RecompPos, 0x01); break; - case x86_EDX: PUTDST8(m_RecompPos, 0x02); break; - case x86_ESI: PUTDST8(m_RecompPos, 0x06); break; - case x86_EDI: PUTDST8(m_RecompPos, 0x07); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::fpuLoadQwordFromN64Mem(int * StackPos, x86Reg x86reg) -{ - CPU_Message(" fld qword ptr [%s+N64mem]", x86_Name(x86reg)); - *StackPos = (*StackPos - 1) & 7; - switch (x86reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x80DD); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x83DD); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x81DD); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x82DD); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x86DD); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x87DD); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x85DD); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::fpuLoadReg(int * StackPos, x86FpuValues Reg) -{ - CPU_Message(" fld ST(0), %s", fpu_Name(Reg)); - *StackPos = (*StackPos - 1) & 7; - switch (Reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xC0D9); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xC1D9); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xC2D9); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xC3D9); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xC4D9); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xC5D9); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xC6D9); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xC7D9); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuMulDword(void *Variable, const char * VariableName) -{ - CPU_Message(" fmul ST(0), dword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x0DD8); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuMulDwordRegPointer(x86Reg x86Pointer) -{ - CPU_Message(" fmul ST(0), dword ptr [%s]", x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x08D8); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x0BD8); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x09D8); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x0AD8); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x0ED8); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x0FD8); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuMulQword(void *Variable, const char * VariableName) -{ - CPU_Message(" fmul ST(0), qword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x0DDC); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuMulQwordRegPointer(x86Reg x86Pointer) -{ - CPU_Message(" fmul ST(0), qword ptr [%s]", x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x08DC); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x0BDC); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x09DC); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x0ADC); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x0EDC); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x0FDC); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuMulReg(x86FpuValues x86reg) -{ - CPU_Message(" fmul ST(0), %s", fpu_Name(x86reg)); - switch (x86reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xC8D8); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xC9D8); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xCAD8); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xCBD8); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xCCD8); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xCDD8); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xCED8); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xCFD8); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuMulRegPop(x86FpuValues x86reg) -{ - CPU_Message(" fmulp ST(0), %s", fpu_Name(x86reg)); - switch (x86reg) - { - case x86_ST0: PUTDST16(m_RecompPos, 0xC8DE); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xC9DE); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xCADE); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xCBDE); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xCCDE); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xCDDE); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xCEDE); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xCFDE); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuNeg(void) -{ - CPU_Message(" fchs ST(0)"); - PUTDST16(m_RecompPos, 0xE0D9); -} - -void CX86Ops::fpuRound(void) -{ - CPU_Message(" frndint ST(0)"); - PUTDST16(m_RecompPos, 0xFCD9); -} - -void CX86Ops::fpuSqrt(void) -{ - CPU_Message(" fsqrt ST(0)"); - PUTDST16(m_RecompPos, 0xFAD9); -} - -void CX86Ops::fpuStoreControl(void *Variable, const char * VariableName) -{ - CPU_Message(" fnstcw [%s]", VariableName); - PUTDST16(m_RecompPos, 0x3DD9); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuStoreDword(int * StackPos, void *Variable, const char * VariableName, bool pop) -{ - CPU_Message(" fst%s dword ptr [%s]", m_fpupop[pop], VariableName); - - if (pop) - { - *StackPos = (*StackPos + 1) & 7; - } - - PUTDST16(m_RecompPos, pop ? 0x1DD9 : 0x15D9); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuStoreDwordFromX86Reg(int * StackPos, x86Reg x86reg, bool pop) -{ - uint8_t Command = 0; - - CPU_Message(" fst%s dword ptr [%s]", m_fpupop[pop], x86_Name(x86reg)); - - if (pop) - { - *StackPos = (*StackPos + 1) & 7; - } - - PUTDST8(m_RecompPos, 0xD9); - - switch (x86reg) - { - case x86_EAX: Command = 0x10; break; - case x86_EBX: Command = 0x13; break; - case x86_ECX: Command = 0x11; break; - case x86_EDX: Command = 0x12; break; - case x86_ESI: Command = 0x16; break; - case x86_EDI: Command = 0x17; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, pop ? (Command + 0x8) : Command); -} - -void CX86Ops::fpuStoreDwordToN64Mem(int * StackPos, x86Reg x86reg, bool Pop) -{ - int s = Pop ? 0x0800 : 0; - - CPU_Message(" fst%s dword ptr [%s+N64mem]", m_fpupop[Pop], x86_Name(x86reg)); - - if (Pop) - { - *StackPos = (*StackPos + 1) & 7; - } - - switch (x86reg) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x90D9 | s); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x93D9 | s); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x91D9 | s); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x92D9 | s); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x96D9 | s); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x97D9 | s); break; - case x86_EBP: PUTDST16(m_RecompPos, 0x95D9 | s); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST32(m_RecompPos, g_MMU->Rdram()); -} - -void CX86Ops::fpuStoreIntegerDword(int * StackPos, void *Variable, const char * VariableName, bool pop) -{ - CPU_Message(" fist%s dword ptr [%s]", m_fpupop[pop], VariableName); - - if (pop) - { - *StackPos = (*StackPos + 1) & 7; - } - PUTDST16(m_RecompPos, pop ? 0x1DDB : 0x15DB); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuStoreIntegerDwordFromX86Reg(int * StackPos, x86Reg x86reg, bool pop) -{ - uint8_t Command = 0; - - CPU_Message(" fist%s dword ptr [%s]", m_fpupop[pop], x86_Name(x86reg)); - - if (pop) - { - *StackPos = (*StackPos + 1) & 7; - } - - PUTDST8(m_RecompPos, 0xDB); - - switch (x86reg) - { - case x86_EAX: Command = 0x10; break; - case x86_EBX: Command = 0x13; break; - case x86_ECX: Command = 0x11; break; - case x86_EDX: Command = 0x12; break; - case x86_ESI: Command = 0x16; break; - case x86_EDI: Command = 0x17; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, pop ? (Command + 0x8) : Command); -} - -void CX86Ops::fpuStoreIntegerQword(int * StackPos, void *Variable, const char * VariableName, bool pop) -{ - CPU_Message(" fist%s qword ptr [%s]", m_fpupop[pop], VariableName); - - if (pop) - { - *StackPos = (*StackPos + 1) & 7; - } - - PUTDST16(m_RecompPos, pop ? 0x3DDF : 0x35DF); - PUTDST32(m_RecompPos, Variable); - - if (!pop) - { - X86BreakPoint(__FILE__, __LINE__); - } -} - -void CX86Ops::fpuStoreIntegerQwordFromX86Reg(int * StackPos, x86Reg x86reg, bool pop) -{ - uint8_t Command = 0; - - CPU_Message(" fist%s qword ptr [%s]", m_fpupop[pop], x86_Name(x86reg)); - - if (pop) - { - *StackPos = (*StackPos + 1) & 7; - } - - PUTDST8(m_RecompPos, 0xDF); - - switch (x86reg) { - case x86_EAX: Command = 0x30; break; - case x86_EBX: Command = 0x33; break; - case x86_ECX: Command = 0x31; break; - case x86_EDX: Command = 0x32; break; - case x86_ESI: Command = 0x36; break; - case x86_EDI: Command = 0x37; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, pop ? (Command + 0x8) : Command); -} - -void CX86Ops::fpuStoreQwordFromX86Reg(int * StackPos, x86Reg x86reg, bool pop) -{ - uint8_t Command = 0; - - CPU_Message(" fst%s qword ptr [%s]", m_fpupop[pop], x86_Name(x86reg)); - - if (pop) - { - *StackPos = (*StackPos + 1) & 7; - } - - PUTDST8(m_RecompPos, 0xDD); - - switch (x86reg) - { - case x86_EAX: Command = 0x10; break; - case x86_EBX: Command = 0x13; break; - case x86_ECX: Command = 0x11; break; - case x86_EDX: Command = 0x12; break; - case x86_ESI: Command = 0x16; break; - case x86_EDI: Command = 0x17; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - PUTDST8(m_RecompPos, pop ? (Command + 0x8) : Command); -} - -void CX86Ops::fpuStoreStatus(void) -{ - CPU_Message(" fnstsw ax"); - PUTDST16(m_RecompPos, 0xE0DF); -} - -void CX86Ops::fpuSubDword(void *Variable, const char * VariableName) -{ - CPU_Message(" fsub ST(0), dword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x25D8); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuSubDwordRegPointer(x86Reg x86Pointer) -{ - CPU_Message(" fsub ST(0), dword ptr [%s]", x86_Name(x86Pointer)); - switch (x86Pointer) - { - case x86_EAX: PUTDST16(m_RecompPos, 0x20D8); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x23D8); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x21D8); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x22D8); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x26D8); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x27D8); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuSubDwordReverse(void *Variable, const char * VariableName) -{ - CPU_Message(" fsubr ST(0), dword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x2DD8); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuSubQword(void *Variable, const char * VariableName) -{ - CPU_Message(" fsub ST(0), qword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x25DC); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuSubQwordRegPointer(x86Reg x86Pointer) -{ - CPU_Message(" fsub ST(0), qword ptr [%s]", x86_Name(x86Pointer)); - switch (x86Pointer) { - case x86_EAX: PUTDST16(m_RecompPos, 0x20DC); break; - case x86_EBX: PUTDST16(m_RecompPos, 0x23DC); break; - case x86_ECX: PUTDST16(m_RecompPos, 0x21DC); break; - case x86_EDX: PUTDST16(m_RecompPos, 0x22DC); break; - case x86_ESI: PUTDST16(m_RecompPos, 0x26DC); break; - case x86_EDI: PUTDST16(m_RecompPos, 0x27DC); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuSubQwordReverse(void *Variable, const char * VariableName) -{ - CPU_Message(" fsubr ST(0), qword ptr [%s]", VariableName); - PUTDST16(m_RecompPos, 0x2DDC); - PUTDST32(m_RecompPos, Variable); -} - -void CX86Ops::fpuSubReg(x86FpuValues x86reg) -{ - CPU_Message(" fsub ST(0), %s", fpu_Name(x86reg)); - switch (x86reg) { - case x86_ST0: PUTDST16(m_RecompPos, 0xE0D8); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xE1D8); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xE2D8); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xE3D8); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xE4D8); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xE5D8); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xE6D8); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xE7D8); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -void CX86Ops::fpuSubRegPop(x86FpuValues x86reg) -{ - CPU_Message(" fsubp ST(0), %s", fpu_Name(x86reg)); - switch (x86reg) { - case x86_ST0: PUTDST16(m_RecompPos, 0xE8DE); break; - case x86_ST1: PUTDST16(m_RecompPos, 0xE9DE); break; - case x86_ST2: PUTDST16(m_RecompPos, 0xEADE); break; - case x86_ST3: PUTDST16(m_RecompPos, 0xEBDE); break; - case x86_ST4: PUTDST16(m_RecompPos, 0xECDE); break; - case x86_ST5: PUTDST16(m_RecompPos, 0xEDDE); break; - case x86_ST6: PUTDST16(m_RecompPos, 0xEEDE); break; - case x86_ST7: PUTDST16(m_RecompPos, 0xEFDE); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } -} - -const char * CX86Ops::x86_Name(x86Reg Reg) -{ - switch (Reg) { - case x86_EAX: return "eax"; - case x86_EBX: return "ebx"; - case x86_ECX: return "ecx"; - case x86_EDX: return "edx"; - case x86_ESI: return "esi"; - case x86_EDI: return "edi"; - case x86_EBP: return "ebp"; - case x86_ESP: return "esp"; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - return "???"; -} - -const char * CX86Ops::x86_ByteName(x86Reg Reg) -{ - switch (Reg) { - case x86_AL: return "al"; - case x86_BL: return "bl"; - case x86_CL: return "cl"; - case x86_DL: return "dl"; - case x86_AH: return "ah"; - case x86_BH: return "bh"; - case x86_CH: return "ch"; - case x86_DH: return "dh"; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - return "???"; -} - -const char * CX86Ops::x86_HalfName(x86Reg Reg) -{ - switch (Reg) - { - case x86_EAX: return "ax"; - case x86_EBX: return "bx"; - case x86_ECX: return "cx"; - case x86_EDX: return "dx"; - case x86_ESI: return "si"; - case x86_EDI: return "di"; - case x86_EBP: return "bp"; - case x86_ESP: return "sp"; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - return "???"; -} - -const char * CX86Ops::fpu_Name(x86FpuValues Reg) -{ - switch (Reg) - { - case x86_ST0: return "ST(0)"; - case x86_ST1: return "ST(1)"; - case x86_ST2: return "ST(2)"; - case x86_ST3: return "ST(3)"; - case x86_ST4: return "ST(4)"; - case x86_ST5: return "ST(5)"; - case x86_ST6: return "ST(6)"; - case x86_ST7: return "ST(7)"; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - return "???"; -} - -bool CX86Ops::Is8BitReg(x86Reg Reg) -{ - return (Reg == x86_EAX) || - (Reg == x86_EBX) || - (Reg == x86_ECX) || - (Reg == x86_EDX); -} - -uint8_t CX86Ops::CalcMultiplyCode(Multipler Multiply) -{ - switch (Multiply) - { - case Multip_x2: return 0x40; - case Multip_x4: return 0x80; - case Multip_x8: return 0xC0; - default: return 0; - } -} - -void CX86Ops::SetJump32(uint32_t * Loc, uint32_t * JumpLoc) -{ - *Loc = (uint32_t)(((uint32_t)JumpLoc) - (((uint32_t)(Loc)) + 4)); -} - -void CX86Ops::SetJump8(uint8_t * Loc, uint8_t * JumpLoc) -{ - if (Loc == NULL || JumpLoc == NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - uint32_t diffrence = (uint32_t)(((uint32_t)JumpLoc) - (((uint32_t)(Loc)) + 1)); - if (diffrence > 255) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - *Loc = (uint8_t)diffrence; -} - -void * CX86Ops::GetAddressOf(int value, ...) -{ - void * Address; - - va_list ap; - va_start(ap, value); - Address = va_arg(ap, void *); - va_end(ap); - - return Address; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include "x86CodeLog.h" + +#define PUTDST8(dest,value) (*((uint8_t *)(dest))=(uint8_t)(value)); dest += 1; +#define PUTDST16(dest,value) (*((uint16_t *)(dest))=(uint16_t)(value)); dest += 2; +#define PUTDST32(dest,value) (*((uint32_t *)(dest))=(uint32_t)(value)); dest += 4; + +uint8_t * CX86Ops::m_RecompPos; + +char CX86Ops::m_fpupop[2][2] = +{ + "", "p" +}; + +CX86Ops::x86Reg CX86Ops::x86_Registers[8] = +{ + x86_ESI, + x86_EDI, + x86_EBX, + x86_ECX, + x86_EDX, + x86_EAX, + x86_EBP, + x86_ESP +}; + +/************************************************************************** +* Logging Functions * +**************************************************************************/ +void CX86Ops::WriteX86Comment(const char * Comment) +{ + CPU_Message(""); + CPU_Message(" // %s", Comment); +} + +void CX86Ops::WriteX86Label(const char * Label) +{ + CPU_Message(""); + CPU_Message(" %s:", Label); +} + +void CX86Ops::AdcX86regToVariable(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" adc dword ptr [%s], %s", VariableName, x86_Name(reg)); + PUTDST16(m_RecompPos, 0x0511 + (reg * 0x100)); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::AdcConstToVariable(void *Variable, const char * VariableName, uint8_t Constant) +{ + CPU_Message(" adc dword ptr [%s], %Xh", VariableName, Constant); + PUTDST16(m_RecompPos, 0x1583); + PUTDST32(m_RecompPos, Variable); + PUTDST8(m_RecompPos, Constant); +} + +void CX86Ops::AdcConstToX86Reg(x86Reg reg, uint32_t Const) +{ + CPU_Message(" adc %s, %Xh", x86_Name(reg), Const); + if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + PUTDST16(m_RecompPos, 0xD081 + (reg * 0x100)); + PUTDST32(m_RecompPos, Const); + } + else + { + PUTDST16(m_RecompPos, 0xD083 + (reg * 0x100)); + PUTDST8(m_RecompPos, Const); + } +} + +void CX86Ops::AdcVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" adc %s, dword ptr [%s]", x86_Name(reg), VariableName); + PUTDST16(m_RecompPos, 0x0513 + (reg * 0x800)); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::AdcX86RegToX86Reg(x86Reg Destination, x86Reg Source) +{ + CPU_Message(" adc %s, %s", x86_Name(Destination), x86_Name(Source)); + PUTDST16(m_RecompPos, 0xC013 + (Source * 0x100) + (Destination * 0x800)); +} + +void CX86Ops::AddConstToVariable(uint32_t Const, void *Variable, const char * VariableName) +{ + CPU_Message(" add dword ptr [%s], 0x%X", VariableName, Const); + PUTDST16(m_RecompPos, 0x0581); + PUTDST32(m_RecompPos, Variable); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::AddConstToX86Reg(x86Reg reg, uint32_t Const) +{ + if (Const == 0) + { + } + else if (Const == 1) + { + IncX86reg(reg); + } + else if (Const == 0xFFFFFFFF) + { + DecX86reg(reg); + } + else if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + CPU_Message(" add %s, %Xh", x86_Name(reg), Const); + PUTDST16(m_RecompPos, 0xC081 + (reg * 0x100)); + PUTDST32(m_RecompPos, Const); + } + else + { + CPU_Message(" add %s, %Xh", x86_Name(reg), Const); + PUTDST16(m_RecompPos, 0xC083 + (reg * 0x100)); + PUTDST8(m_RecompPos, Const); + } +} + +void CX86Ops::AddVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" add %s, dword ptr [%s]", x86_Name(reg), VariableName); + PUTDST16(m_RecompPos, 0x0503 + (reg * 0x800)); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::AddX86regToVariable(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" add dword ptr [%s], %s", VariableName, x86_Name(reg)); + PUTDST16(m_RecompPos, 0x0501 + (reg * 0x800)); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::AddX86RegToX86Reg(x86Reg Destination, x86Reg Source) +{ + CPU_Message(" add %s, %s", x86_Name(Destination), x86_Name(Source)); + PUTDST16(m_RecompPos, 0xC003 + (Source * 0x100) + (Destination * 0x800)); +} + +void CX86Ops::AndConstToVariable(uint32_t Const, void *Variable, const char * VariableName) +{ + CPU_Message(" and dword ptr [%s], 0x%X", VariableName, Const); + PUTDST16(m_RecompPos, 0x2581); + PUTDST32(m_RecompPos, Variable); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::AndConstToX86Reg(x86Reg reg, uint32_t Const) +{ + CPU_Message(" and %s, %Xh", x86_Name(reg), Const); + if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + PUTDST16(m_RecompPos, 0xE081 + (reg * 0x100)); + PUTDST32(m_RecompPos, Const); + } + else + { + PUTDST16(m_RecompPos, 0xE083 + (reg * 0x100)); + PUTDST8(m_RecompPos, Const); + } +} + +void CX86Ops::AndVariableDispToX86Reg(void *Variable, const char * VariableName, x86Reg reg, x86Reg AddrReg, Multipler Multiply) +{ + CPU_Message(" and %s, dword ptr [%s+%s*%i]", x86_Name(reg), VariableName, x86_Name(AddrReg), Multiply); + + PUTDST16(m_RecompPos, 0x0423 + (reg * 0x800)); + PUTDST8(m_RecompPos, 0x05 + CalcMultiplyCode(Multiply) + (AddrReg * 0x8)); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::AndVariableToX86Reg(void * Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" and %s, dword ptr [%s]", x86_Name(reg), VariableName); + PUTDST16(m_RecompPos, 0x0523 + (reg * 0x800)); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::AndX86RegToX86Reg(x86Reg Destination, x86Reg Source) +{ + CPU_Message(" and %s, %s", x86_Name(Destination), x86_Name(Source)); + PUTDST16(m_RecompPos, 0xC021 + (Destination * 0x100) + (Source * 0x800)); +} + +void CX86Ops::BreakPointNotification(const char * FileName, int32_t LineNumber) +{ + g_Notify->BreakPoint(FileName, LineNumber); +} + +void CX86Ops::X86HardBreakPoint() +{ + CPU_Message(" int 3"); + PUTDST8(m_RecompPos, 0xCC); +} + +void CX86Ops::X86BreakPoint(const char * FileName, int LineNumber) +{ + Pushad(); + PushImm32(stdstr_f("%d", LineNumber).c_str(), LineNumber); + PushImm32(FileName, (uint32_t)FileName); + Call_Direct((void *)BreakPointNotification, "BreakPointNotification"); + AddConstToX86Reg(x86_ESP, 8); + Popad(); +} + +void CX86Ops::Call_Direct(void * FunctAddress, const char * FunctName) +{ + CPU_Message(" call offset %s", FunctName); + PUTDST8(m_RecompPos, 0xE8); + PUTDST32(m_RecompPos, (uint32_t)FunctAddress - (uint32_t)m_RecompPos - 4); +} + +void CX86Ops::Call_Indirect(void * FunctAddress, const char * FunctName) +{ + CPU_Message(" call [%s]", FunctName); + PUTDST16(m_RecompPos, 0x15FF); + PUTDST32(m_RecompPos, FunctAddress); +} + +void CX86Ops::CompConstToVariable(uint32_t Const, void * Variable, const char * VariableName) +{ + CPU_Message(" cmp dword ptr [%s], 0x%X", VariableName, Const); + PUTDST16(m_RecompPos, 0x3D81); + PUTDST32(m_RecompPos, Variable); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::CompConstToX86reg(x86Reg reg, uint32_t Const) +{ + if (Const == 0) + { + OrX86RegToX86Reg(reg, reg); + } + else + { + CPU_Message(" cmp %s, %Xh", x86_Name(reg), Const); + if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + PUTDST16(m_RecompPos, 0xF881 + (reg * 0x100)); + PUTDST32(m_RecompPos, Const); + } + else + { + PUTDST16(m_RecompPos, 0xF883 + (reg * 0x100)); + PUTDST8(m_RecompPos, Const); + } + } +} + +void CX86Ops::CompConstToX86regPointer(x86Reg reg, uint32_t Const) +{ + if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + CPU_Message(" cmp dword ptr [%s], %Xh", x86_Name(reg), Const); + PUTDST16(m_RecompPos, 0x3881 + (reg * 0x100)); + PUTDST32(m_RecompPos, Const); + } + else + { + CPU_Message(" cmp byte ptr [%s], %Xh", x86_Name(reg), Const); + PUTDST16(m_RecompPos, 0x3883 + (reg * 0x100)); + PUTDST8(m_RecompPos, Const); + } +} + +void CX86Ops::CompX86regToVariable(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" cmp %s, dword ptr [%s]", x86_Name(reg), VariableName); + PUTDST16(m_RecompPos, 0x053B + (reg * 0x800)); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::CompVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" cmp dword ptr [%s], %s", VariableName, x86_Name(reg)); + PUTDST16(m_RecompPos, 0x0539 + (reg * 0x800)); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::CompX86RegToX86Reg(x86Reg Destination, x86Reg Source) +{ + uint16_t x86Command = 0; + + CPU_Message(" cmp %s, %s", x86_Name(Destination), x86_Name(Source)); + + switch (Source) + { + case x86_EAX: x86Command = 0x003B; break; + case x86_EBX: x86Command = 0x033B; break; + case x86_ECX: x86Command = 0x013B; break; + case x86_EDX: x86Command = 0x023B; break; + case x86_ESI: x86Command = 0x063B; break; + case x86_EDI: x86Command = 0x073B; break; + case x86_ESP: x86Command = 0x043B; break; + case x86_EBP: x86Command = 0x053B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (Destination) + { + case x86_EAX: x86Command += 0xC000; break; + case x86_EBX: x86Command += 0xD800; break; + case x86_ECX: x86Command += 0xC800; break; + case x86_EDX: x86Command += 0xD000; break; + case x86_ESI: x86Command += 0xF000; break; + case x86_EDI: x86Command += 0xF800; break; + case x86_ESP: x86Command += 0xE000; break; + case x86_EBP: x86Command += 0xE800; break; + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::DecX86reg(x86Reg reg) +{ + CPU_Message(" dec %s", x86_Name(reg)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xC8FF); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xCBFF); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xC9FF); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xCAFF); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xCEFF); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xCFFF); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x4C); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x4D); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::DivX86reg(x86Reg reg) +{ + CPU_Message(" div %s", x86_Name(reg)); + switch (reg) + { + case x86_EBX: PUTDST16(m_RecompPos, 0xf3F7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xf1F7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xf2F7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xf6F7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xf7F7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xf4F7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xf5F7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::idivX86reg(x86Reg reg) +{ + CPU_Message(" idiv %s", x86_Name(reg)); + + switch (reg) + { + case x86_EBX: PUTDST16(m_RecompPos, 0xfbF7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xf9F7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xfaF7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xfeF7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xffF7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xfcF7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xfdF7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::imulX86reg(x86Reg reg) +{ + CPU_Message(" imul %s", x86_Name(reg)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE8F7); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xEBF7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE9F7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xEAF7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xEEF7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xEFF7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xECF7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xEDF7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::IncX86reg(x86Reg reg) +{ + CPU_Message(" inc %s", x86_Name(reg)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xC0FF); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xC3FF); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xC1FF); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xC2FF); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xC6FF); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xC7FF); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x44); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x45); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::JaeLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jae $%s", Label); + PUTDST8(m_RecompPos, 0x73); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JaeLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" jae $%s", Label); + PUTDST16(m_RecompPos, 0x830F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JaLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" ja $%s", Label); + PUTDST8(m_RecompPos, 0x77); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JaLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" ja $%s", Label); + PUTDST16(m_RecompPos, 0x870F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JbLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jb $%s", Label); + PUTDST8(m_RecompPos, 0x72); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JbLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" jb $%s", Label); + PUTDST16(m_RecompPos, 0x820F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JecxzLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jecxz $%s", Label); + PUTDST8(m_RecompPos, 0xE3); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JeLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" je $%s", Label); + PUTDST8(m_RecompPos, 0x74); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JeLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" je $%s", Label); + PUTDST16(m_RecompPos, 0x840F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JgeLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" jge $%s", Label); + PUTDST16(m_RecompPos, 0x8D0F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JgLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jg $%s", Label); + PUTDST8(m_RecompPos, 0x7F); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JgLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" jg $%s", Label); + PUTDST16(m_RecompPos, 0x8F0F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JleLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jle $%s", Label); + PUTDST8(m_RecompPos, 0x7E); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JleLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" jle $%s", Label); + PUTDST16(m_RecompPos, 0x8E0F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JlLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jl $%s", Label); + PUTDST8(m_RecompPos, 0x7C); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JlLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" jl $%s", Label); + PUTDST16(m_RecompPos, 0x8C0F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JmpDirectReg(x86Reg reg) +{ + CPU_Message(" jmp %s", x86_Name(reg)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE0ff); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xE3ff); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE1ff); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xE2ff); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xE6ff); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xE7ff); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::JmpIndirectLabel32(const char * Label, uint32_t location) +{ + CPU_Message(" jmp dword ptr [%s]", Label); + PUTDST16(m_RecompPos, 0x25ff); + PUTDST32(m_RecompPos, location); +} + +void CX86Ops::JmpIndirectReg(x86Reg reg) +{ + CPU_Message(" jmp dword ptr [%s]", x86_Name(reg)); + + switch (reg) { + case x86_EAX: PUTDST16(m_RecompPos, 0x20ff); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x23ff); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x21ff); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x22ff); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x26ff); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x27ff); break; + case x86_ESP: + PUTDST8(m_RecompPos, 0xff); + PUTDST16(m_RecompPos, 0x2434); + /* g_Notify->BreakPoint(__FILEW__,__LINE__); */ + break; + case x86_EBP: + PUTDST8(m_RecompPos, 0xff); + PUTDST16(m_RecompPos, 0x0065); + /* g_Notify->BreakPoint(__FILEW__,__LINE__); */ + break; + } +} + +void CX86Ops::JmpLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jmp $%s", Label); + PUTDST8(m_RecompPos, 0xEB); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JmpLabel32(const char * Label, uint32_t Value) +{ + CPU_Message(" jmp $%s", Label); + PUTDST8(m_RecompPos, 0xE9); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JneLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jne $%s", Label); + PUTDST8(m_RecompPos, 0x75); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JneLabel32(const char *Label, uint32_t Value) +{ + CPU_Message(" jne $%s", Label); + PUTDST16(m_RecompPos, 0x850F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JnsLabel8(const char * Label, uint8_t Value) +{ + CPU_Message(" jns $%s", Label); + PUTDST8(m_RecompPos, 0x79); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JnsLabel32(const char *Label, uint32_t Value) +{ + CPU_Message(" jns $%s", Label); + PUTDST16(m_RecompPos, 0x890F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JnzLabel8(const char *Label, uint8_t Value) +{ + CPU_Message(" jnz $%s", Label); + PUTDST8(m_RecompPos, 0x75); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JnzLabel32(const char *Label, uint32_t Value) +{ + CPU_Message(" jnz $%s", Label); + PUTDST16(m_RecompPos, 0x850F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JsLabel32(const char *Label, uint32_t Value) +{ + CPU_Message(" js $%s", Label); + PUTDST16(m_RecompPos, 0x880F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::JzLabel8(const char *Label, uint8_t Value) +{ + CPU_Message(" jz $%s", Label); + PUTDST8(m_RecompPos, 0x74); + PUTDST8(m_RecompPos, Value); +} + +void CX86Ops::JzLabel32(const char *Label, uint32_t Value) +{ + CPU_Message(" jz $%s", Label); + PUTDST16(m_RecompPos, 0x840F); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::LeaRegReg(x86Reg RegDest, x86Reg RegSrc, uint32_t Const, Multipler multiplier) +{ + if (Const != 0) + { + CPU_Message(" lea %s, [%s*%i+%X]", x86_Name(RegDest), x86_Name(RegSrc), multiplier, Const); + } + else { + CPU_Message(" lea %s, [%s*%i]", x86_Name(RegDest), x86_Name(RegSrc), multiplier); + } + + PUTDST8(m_RecompPos, 0x8D); + PUTDST8(m_RecompPos, 0x04 + (RegDest * 8)); + PUTDST8(m_RecompPos, 0x05 + (RegSrc * 8) + CalcMultiplyCode(multiplier)); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::LeaRegReg2(x86Reg RegDest, x86Reg RegSrc, x86Reg RegSrc2, Multipler multiplier) +{ + CPU_Message(" lea %s, [%s+%s*%i]", x86_Name(RegDest), x86_Name(RegSrc), x86_Name(RegSrc2), multiplier); + + if (RegSrc2 == x86_ESP || RegSrc2 == x86_EBP) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + PUTDST8(m_RecompPos, 0x8D); + PUTDST8(m_RecompPos, 0x04 + (RegDest * 0x8)); + PUTDST8(m_RecompPos, 0x05 + (RegSrc * 0x8) + RegSrc2 + CalcMultiplyCode(multiplier)); +} + +void CX86Ops::LeaSourceAndOffset(x86Reg x86DestReg, x86Reg x86SourceReg, int offset) +{ + uint16_t x86Command = 0; + + CPU_Message(" lea %s, [%s + %0Xh]", x86_Name(x86DestReg), x86_Name(x86SourceReg), offset); + + // if ((offset & 0xFFFFFF80) != 0 && (offset & 0xFFFFFF80) != 0xFFFFFF80) { + if (1) + { + switch (x86DestReg) + { + case x86_EAX: x86Command = 0x808D; break; + case x86_EBX: x86Command = 0x988D; break; + case x86_ECX: x86Command = 0x888D; break; + case x86_EDX: x86Command = 0x908D; break; + case x86_ESI: x86Command = 0xB08D; break; + case x86_EDI: x86Command = 0xB88D; break; + case x86_ESP: x86Command = 0xA08D; break; + case x86_EBP: x86Command = 0xA88D; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (x86SourceReg) + { + case x86_EAX: x86Command += 0x0000; break; + case x86_EBX: x86Command += 0x0300; break; + case x86_ECX: x86Command += 0x0100; break; + case x86_EDX: x86Command += 0x0200; break; + case x86_ESI: x86Command += 0x0600; break; + case x86_EDI: x86Command += 0x0700; break; + case x86_ESP: x86Command += 0x0400; break; + case x86_EBP: x86Command += 0x0500; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, offset); + } + else + { + switch (x86DestReg) + { + case x86_EAX: x86Command = 0x408D; break; + case x86_EBX: x86Command = 0x588D; break; + case x86_ECX: x86Command = 0x488D; break; + case x86_EDX: x86Command = 0x508D; break; + case x86_ESI: x86Command = 0x708D; break; + case x86_EDI: x86Command = 0x788D; break; + case x86_ESP: x86Command = 0x608D; break; + case x86_EBP: x86Command = 0x688D; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (x86SourceReg) + { + case x86_EAX: x86Command += 0x0000; break; + case x86_EBX: x86Command += 0x0300; break; + case x86_ECX: x86Command += 0x0100; break; + case x86_EDX: x86Command += 0x0200; break; + case x86_ESI: x86Command += 0x0600; break; + case x86_EDI: x86Command += 0x0700; break; + case x86_ESP: x86Command += 0x0400; break; + case x86_EBP: x86Command += 0x0500; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); + PUTDST8(m_RecompPos, offset); + } +} + +void CX86Ops::MoveConstByteToN64Mem(uint8_t Const, x86Reg AddrReg) +{ + CPU_Message(" mov byte ptr [%s+N64mem], %Xh", x86_Name(AddrReg), Const); + switch (AddrReg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x80C6); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x83C6); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x81C6); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x82C6); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x86C6); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x87C6); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x84C6); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x85C6); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, g_MMU->Rdram()); + PUTDST8(m_RecompPos, Const); +} + +void CX86Ops::MoveConstByteToVariable(uint8_t Const, void *Variable, const char * VariableName) +{ + CPU_Message(" mov byte ptr [%s], %Xh", VariableName, Const); + PUTDST16(m_RecompPos, 0x05C6); + PUTDST32(m_RecompPos, Variable); + PUTDST8(m_RecompPos, Const); +} + +void CX86Ops::MoveConstHalfToN64Mem(uint16_t Const, x86Reg AddrReg) +{ + CPU_Message(" mov word ptr [%s+N64mem], %Xh", x86_Name(AddrReg), Const); + PUTDST8(m_RecompPos, 0x66); + switch (AddrReg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x80C7); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x83C7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x81C7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x82C7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x86C7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x87C7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x84C7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x85C7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, g_MMU->Rdram()); + PUTDST16(m_RecompPos, Const); +} + +void CX86Ops::MoveConstHalfToVariable(uint16_t Const, void *Variable, const char * VariableName) +{ + CPU_Message(" mov word ptr [%s], %Xh", VariableName, Const); + PUTDST8(m_RecompPos, 0x66); + PUTDST16(m_RecompPos, 0x05C7); + PUTDST32(m_RecompPos, Variable); + PUTDST16(m_RecompPos, Const); +} + +void CX86Ops::MoveConstHalfToX86regPointer(uint16_t Const, x86Reg AddrReg1, x86Reg AddrReg2) +{ + uint8_t Param = 0; + + CPU_Message(" mov word ptr [%s+%s],%Xh", x86_Name(AddrReg1), x86_Name(AddrReg2), Const); + + PUTDST8(m_RecompPos, 0x66); + PUTDST16(m_RecompPos, 0x04C7); + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); + PUTDST16(m_RecompPos, Const); +} + +void CX86Ops::MoveConstToMemoryDisp(uint32_t Const, x86Reg AddrReg, uint32_t Disp) +{ + CPU_Message(" mov dword ptr [%s+%Xh], %Xh", x86_Name(AddrReg), Disp, Const); + switch (AddrReg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x80C7); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x83C7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x81C7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x82C7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x86C7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x87C7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x84C7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x85C7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Disp); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::MoveConstToN64Mem(uint32_t Const, x86Reg AddrReg) +{ + CPU_Message(" mov dword ptr [%s+N64mem], %Xh", x86_Name(AddrReg), Const); + switch (AddrReg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x80C7); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x83C7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x81C7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x82C7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x86C7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x87C7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x84C7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x85C7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, g_MMU->Rdram()); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::MoveConstToN64MemDisp(uint32_t Const, x86Reg AddrReg, uint8_t Disp) +{ + CPU_Message(" mov dword ptr [%s+N64mem+%Xh], %Xh", x86_Name(AddrReg), Const, Disp); + switch (AddrReg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x80C7); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x83C7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x81C7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x82C7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x86C7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x87C7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x84C7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x85C7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, g_MMU->Rdram() + Disp); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::MoveConstToVariable(uint32_t Const, void *Variable, const char * VariableName) +{ + CPU_Message(" mov dword ptr [%s], %Xh", VariableName, Const); + PUTDST16(m_RecompPos, 0x05C7); + PUTDST32(m_RecompPos, Variable); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::MoveConstToX86Pointer(uint32_t Const, x86Reg X86Pointer) +{ + CPU_Message(" mov dword ptr [%s], %Xh", x86_Name(X86Pointer), Const); + PUTDST16(m_RecompPos, 0x00C7 + (X86Pointer * 0x100)); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::MoveConstToX86reg(uint32_t Const, x86Reg reg) +{ + if (Const == 0) + { + XorX86RegToX86Reg(reg, reg); + } + else + { + CPU_Message(" mov %s, %Xh", x86_Name(reg), Const); + PUTDST16(m_RecompPos, 0xC0C7 + (reg * 0x100)); + PUTDST32(m_RecompPos, Const); + } +} + +void CX86Ops::MoveConstByteToX86regPointer(uint8_t Const, x86Reg AddrReg1, x86Reg AddrReg2) +{ + uint8_t Param = 0; + + CPU_Message(" mov byte ptr [%s+%s],%Xh", x86_Name(AddrReg1), x86_Name(AddrReg2), Const); + + PUTDST16(m_RecompPos, 0x04C6); + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); + PUTDST8(m_RecompPos, Const); +} + +void CX86Ops::MoveConstToX86regPointer(uint32_t Const, x86Reg AddrReg1, x86Reg AddrReg2) +{ + uint8_t Param = 0; + + CPU_Message(" mov dword ptr [%s+%s],%Xh", x86_Name(AddrReg1), x86_Name(AddrReg2), Const); + + PUTDST16(m_RecompPos, 0x04C7); + + switch (AddrReg1) { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::MoveN64MemDispToX86reg(x86Reg reg, x86Reg AddrReg, uint8_t Disp) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov %s, dword ptr [%s+N64mem+%Xh]", x86_Name(reg), x86_Name(AddrReg), Disp); + switch (AddrReg) + { + case x86_EAX: x86Command = 0x008B; break; + case x86_EBX: x86Command = 0x038B; break; + case x86_ECX: x86Command = 0x018B; break; + case x86_EDX: x86Command = 0x028B; break; + case x86_ESI: x86Command = 0x068B; break; + case x86_EDI: x86Command = 0x078B; break; + case x86_ESP: x86Command = 0x048B; break; + case x86_EBP: x86Command = 0x058B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram() + Disp); +} + +void CX86Ops::MoveN64MemToX86reg(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov %s, dword ptr [%s+N64mem]", x86_Name(reg), x86_Name(AddrReg)); + + switch (AddrReg) + { + case x86_EAX: x86Command = 0x008B; break; + case x86_EBX: x86Command = 0x038B; break; + case x86_ECX: x86Command = 0x018B; break; + case x86_EDX: x86Command = 0x028B; break; + case x86_ESI: x86Command = 0x068B; break; + case x86_EDI: x86Command = 0x078B; break; + case x86_ESP: x86Command = 0x048B; break; + case x86_EBP: x86Command = 0x058B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveN64MemToX86regByte(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov %s, byte ptr [%s+N64mem]", x86_ByteName(reg), x86_Name(AddrReg)); + switch (AddrReg) + { + case x86_EAX: x86Command = 0x008A; break; + case x86_EBX: x86Command = 0x038A; break; + case x86_ECX: x86Command = 0x018A; break; + case x86_EDX: x86Command = 0x028A; break; + case x86_ESI: x86Command = 0x068A; break; + case x86_EDI: x86Command = 0x078A; break; + case x86_ESP: x86Command = 0x048A; break; + case x86_EBP: x86Command = 0x058A; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + /* case x86_ESI: x86Command += 0xB000; break; */ + /* case x86_EDI: x86Command += 0xB800; break; */ + /* case x86_ESP: case x86_EBP: */ + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov %s, word ptr [%s+N64mem]", x86_HalfName(reg), x86_Name(AddrReg)); + + PUTDST8(m_RecompPos, 0x66); + switch (AddrReg) + { + case x86_EAX: x86Command = 0x008B; break; + case x86_EBX: x86Command = 0x038B; break; + case x86_ECX: x86Command = 0x018B; break; + case x86_EDX: x86Command = 0x028B; break; + case x86_ESI: x86Command = 0x068B; break; + case x86_EDI: x86Command = 0x078B; break; + case x86_ESP: x86Command = 0x048B; break; + case x86_EBP: x86Command = 0x058B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveSxByteX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) +{ + uint8_t Param = 0; + + CPU_Message(" movsx %s, byte ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); + + PUTDST16(m_RecompPos, 0xBE0F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); +} + +void CX86Ops::MoveSxHalfX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) +{ + uint8_t Param = 0; + + CPU_Message(" movsx %s, word ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); + + PUTDST16(m_RecompPos, 0xBF0F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); +} + +void CX86Ops::MoveSxN64MemToX86regByte(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" movsx %s, byte ptr [%s+Dmem]", x86_Name(reg), x86_Name(AddrReg)); + switch (AddrReg) + { + case x86_EAX: x86Command = 0x00BE; break; + case x86_EBX: x86Command = 0x03BE; break; + case x86_ECX: x86Command = 0x01BE; break; + case x86_EDX: x86Command = 0x02BE; break; + case x86_ESI: x86Command = 0x06BE; break; + case x86_EDI: x86Command = 0x07BE; break; + case x86_ESP: x86Command = 0x04BE; break; + case x86_EBP: x86Command = 0x05BE; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } + PUTDST8(m_RecompPos, 0x0f); + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveSxN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" movsx %s, word ptr [%s+Dmem]", x86_Name(reg), x86_Name(AddrReg)); + + switch (AddrReg) + { + case x86_EAX: x86Command = 0x00BF; break; + case x86_EBX: x86Command = 0x03BF; break; + case x86_ECX: x86Command = 0x01BF; break; + case x86_EDX: x86Command = 0x02BF; break; + case x86_ESI: x86Command = 0x06BF; break; + case x86_EDI: x86Command = 0x07BF; break; + case x86_ESP: x86Command = 0x04BF; break; + case x86_EBP: x86Command = 0x05BF; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + } + + PUTDST8(m_RecompPos, 0x0f); + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveSxVariableToX86regByte(void *Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" movsx %s, byte ptr [%s]", x86_Name(reg), VariableName); + + PUTDST16(m_RecompPos, 0xbe0f); + + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x05); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1D); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0D); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x15); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x35); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3D); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x25); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2D); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveSxVariableToX86regHalf(void *Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" movsx %s, word ptr [%s]", x86_Name(reg), VariableName); + + PUTDST16(m_RecompPos, 0xbf0f); + + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x05); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1D); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0D); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x15); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x35); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3D); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x25); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2D); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveVariableToX86reg(void *Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" mov %s, dword ptr [%s]", x86_Name(reg), VariableName); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x058B); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D8B); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D8B); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x158B); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x358B); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D8B); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x258B); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D8B); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveVariableDispToX86Reg(void *Variable, const char * VariableName, x86Reg reg, x86Reg AddrReg, int Multiplier) +{ + int x = 0; + CPU_Message(" mov %s, dword ptr [%s+%s*%i]", x86_Name(reg), VariableName, x86_Name(AddrReg), Multiplier); + + PUTDST8(m_RecompPos, 0x8B); + + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + /* put in shifter 2(01), 4(10), 8(11) */ + switch (Multiplier) + { + case 1: x = 0; break; + case 2: x = 0x40; break; + case 4: x = 0x80; break; + case 8: x = 0xC0; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + /* format xx|000000 */ + switch (AddrReg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x05 | x); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1D | x); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0D | x); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x15 | x); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x35 | x); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3D | x); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x25 | x); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2D | x); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveVariableToX86regByte(void *Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" mov %s, byte ptr [%s]", x86_ByteName(reg), VariableName); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x058A); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D8A); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D8A); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x158A); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveVariableToX86regHalf(void *Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" mov %s, word ptr [%s]", x86_HalfName(reg), VariableName); + + PUTDST8(m_RecompPos, 0x66); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x058B); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D8B); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D8B); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x158B); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x358B); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D8B); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x258B); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D8B); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveX86regByteToN64Mem(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov byte ptr [%s+N64mem], %s", x86_Name(AddrReg), x86_ByteName(reg)); + + switch (AddrReg) + { + case x86_EAX: x86Command = 0x0088; break; + case x86_EBX: x86Command = 0x0388; break; + case x86_ECX: x86Command = 0x0188; break; + case x86_EDX: x86Command = 0x0288; break; + case x86_ESI: x86Command = 0x0688; break; + case x86_EDI: x86Command = 0x0788; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveX86regByteToVariable(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" mov byte ptr [%s], %s", VariableName, x86_ByteName(reg)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x0588); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D88); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D88); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x1588); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveX86regByteToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2) +{ + uint8_t Param = 0; + + CPU_Message(" mov byte ptr [%s+%s],%s", x86_Name(AddrReg1), x86_Name(AddrReg2), x86_ByteName(reg)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x0488); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1C88); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0C88); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x1488); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x3488); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3C88); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x2488); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2C88); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); +} + +void CX86Ops::MoveX86regHalfToN64Mem(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov word ptr [%s+N64mem], %s", x86_Name(AddrReg), x86_HalfName(reg)); + + PUTDST8(m_RecompPos, 0x66); + switch (AddrReg) + { + case x86_EAX: x86Command = 0x0089; break; + case x86_EBX: x86Command = 0x0389; break; + case x86_ECX: x86Command = 0x0189; break; + case x86_EDX: x86Command = 0x0289; break; + case x86_ESI: x86Command = 0x0689; break; + case x86_EDI: x86Command = 0x0789; break; + case x86_ESP: x86Command = 0x0489; break; + case x86_EBP: x86Command = 0x0589; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveX86regHalfToVariable(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" mov word ptr [%s], %s", VariableName, x86_HalfName(reg)); + PUTDST8(m_RecompPos, 0x66); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x0589); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D89); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D89); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x1589); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x3589); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D89); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x2589); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D89); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveX86regHalfToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2) +{ + uint8_t Param = 0; + + CPU_Message(" mov word ptr [%s+%s],%s", x86_Name(AddrReg1), x86_Name(AddrReg2), x86_HalfName(reg)); + + PUTDST8(m_RecompPos, 0x66); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x0489); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1C89); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0C89); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x1489); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x3489); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3C89); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x2489); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2C89); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); +} + +void CX86Ops::MoveX86PointerToX86reg(x86Reg reg, x86Reg X86Pointer) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov %s, dword ptr [%s]", x86_Name(reg), x86_Name(X86Pointer)); + + switch (X86Pointer) + { + case x86_EAX: x86Command = 0x008B; break; + case x86_EBX: x86Command = 0x038B; break; + case x86_ECX: x86Command = 0x018B; break; + case x86_EDX: x86Command = 0x028B; break; + case x86_ESI: x86Command = 0x068B; break; + case x86_EDI: x86Command = 0x078B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (reg) + { + case x86_EAX: x86Command += 0x0000; break; + case x86_EBX: x86Command += 0x1800; break; + case x86_ECX: x86Command += 0x0800; break; + case x86_EDX: x86Command += 0x1000; break; + case x86_ESI: x86Command += 0x3000; break; + case x86_EDI: x86Command += 0x3800; break; + case x86_ESP: x86Command += 0x2000; break; + case x86_EBP: x86Command += 0x2800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::MoveX86PointerToX86regDisp(x86Reg reg, x86Reg X86Pointer, uint8_t Disp) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov %s, dword ptr [%s] + %d", x86_Name(reg), x86_Name(X86Pointer), Disp); + + switch (X86Pointer) + { + case x86_EAX: x86Command = 0x408B; break; + case x86_EBX: x86Command = 0x438B; break; + case x86_ECX: x86Command = 0x418B; break; + case x86_EDX: x86Command = 0x428B; break; + case x86_ESI: x86Command = 0x468B; break; + case x86_EDI: x86Command = 0x478B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (reg) + { + case x86_EAX: x86Command += 0x0000; break; + case x86_EBX: x86Command += 0x1800; break; + case x86_ECX: x86Command += 0x0800; break; + case x86_EDX: x86Command += 0x1000; break; + case x86_ESI: x86Command += 0x3000; break; + case x86_EDI: x86Command += 0x3800; break; + case x86_ESP: x86Command += 0x2000; break; + case x86_EBP: x86Command += 0x2800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); + PUTDST8(m_RecompPos, Disp); +} + +void CX86Ops::MoveX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) +{ + uint8_t Param = 0; + + CPU_Message(" mov %s, dword ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x048B); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1C8B); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0C8B); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x148B); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x348B); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3C8B); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x248B); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2C8B); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); +} + +void CX86Ops::MoveX86regPointerToX86regDisp8(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg, uint8_t offset) +{ + uint8_t Param = 0; + + CPU_Message(" mov %s, dword ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x448B); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x5C8B); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x4C8B); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x548B); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x748B); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x7C8B); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x648B); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x6C8B); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); + PUTDST8(m_RecompPos, offset); +} + +void CX86Ops::MoveX86regToMemory(x86Reg reg, x86Reg AddrReg, uint32_t Disp) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov dword ptr [%s+%X], %s", x86_Name(AddrReg), Disp, x86_Name(reg)); + switch (AddrReg) + { + case x86_EAX: x86Command = 0x0089; break; + case x86_EBX: x86Command = 0x0389; break; + case x86_ECX: x86Command = 0x0189; break; + case x86_EDX: x86Command = 0x0289; break; + case x86_ESI: x86Command = 0x0689; break; + case x86_EDI: x86Command = 0x0789; break; + case x86_ESP: x86Command = 0x0489; break; + case x86_EBP: x86Command = 0x0589; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, Disp); +} + +void CX86Ops::MoveX86regToN64Mem(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov dword ptr [%s+N64mem], %s", x86_Name(AddrReg), x86_Name(reg)); + switch (AddrReg) + { + case x86_EAX: x86Command = 0x0089; break; + case x86_EBX: x86Command = 0x0389; break; + case x86_ECX: x86Command = 0x0189; break; + case x86_EDX: x86Command = 0x0289; break; + case x86_ESI: x86Command = 0x0689; break; + case x86_EDI: x86Command = 0x0789; break; + case x86_ESP: x86Command = 0x0489; break; + case x86_EBP: x86Command = 0x0589; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveX86regToN64MemDisp(x86Reg reg, x86Reg AddrReg, uint8_t Disp) +{ + CPU_Message(" mov dword ptr [%s+N64mem+%d], %s", x86_Name(AddrReg), Disp, x86_Name(reg)); + uint16_t x86Command = 0; + + switch (AddrReg) + { + case x86_EAX: x86Command = 0x0089; break; + case x86_EBX: x86Command = 0x0389; break; + case x86_ECX: x86Command = 0x0189; break; + case x86_EDX: x86Command = 0x0289; break; + case x86_ESI: x86Command = 0x0689; break; + case x86_EDI: x86Command = 0x0789; break; + case x86_ESP: x86Command = 0x0489; break; + case x86_EBP: x86Command = 0x0589; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram() + Disp); +} + +void CX86Ops::MoveX86regToVariable(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" mov dword ptr [%s], %s", VariableName, x86_Name(reg)); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x0589); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D89); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D89); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x1589); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x3589); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D89); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x2589); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D89); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveX86RegToX86Reg(x86Reg Source, x86Reg Destination) +{ + uint16_t x86Command = 0; + + if (Source == Destination) + { + return; + } + CPU_Message(" mov %s, %s", x86_Name(Destination), x86_Name(Source)); + + switch (Destination) + { + case x86_EAX: x86Command = 0x0089; break; + case x86_EBX: x86Command = 0x0389; break; + case x86_ECX: x86Command = 0x0189; break; + case x86_EDX: x86Command = 0x0289; break; + case x86_ESI: x86Command = 0x0689; break; + case x86_EDI: x86Command = 0x0789; break; + case x86_ESP: x86Command = 0x0489; break; + case x86_EBP: x86Command = 0x0589; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (Source) + { + case x86_EAX: x86Command += 0xC000; break; + case x86_EBX: x86Command += 0xD800; break; + case x86_ECX: x86Command += 0xC800; break; + case x86_EDX: x86Command += 0xD000; break; + case x86_ESI: x86Command += 0xF000; break; + case x86_EDI: x86Command += 0xF800; break; + case x86_ESP: x86Command += 0xE000; break; + case x86_EBP: x86Command += 0xE800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::MoveX86regToX86Pointer(x86Reg reg, x86Reg X86Pointer) +{ + uint16_t x86Command = 0; + + CPU_Message(" mov dword ptr [%s], %s", x86_Name(X86Pointer), x86_Name(reg)); + + switch (X86Pointer) + { + case x86_EAX: x86Command = 0x0089; break; + case x86_EBX: x86Command = 0x0389; break; + case x86_ECX: x86Command = 0x0189; break; + case x86_EDX: x86Command = 0x0289; break; + case x86_ESI: x86Command = 0x0689; break; + case x86_EDI: x86Command = 0x0789; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (reg) + { + case x86_EAX: x86Command += 0x0000; break; + case x86_EBX: x86Command += 0x1800; break; + case x86_ECX: x86Command += 0x0800; break; + case x86_EDX: x86Command += 0x1000; break; + case x86_ESI: x86Command += 0x3000; break; + case x86_EDI: x86Command += 0x3800; break; + case x86_ESP: x86Command += 0x2000; break; + case x86_EBP: x86Command += 0x2800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::MoveX86regToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2) +{ + uint8_t Param = 0; + + CPU_Message(" mov dword ptr [%s+%s],%s", x86_Name(AddrReg1), x86_Name(AddrReg2), x86_Name(reg)); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x0489); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1C89); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0C89); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x1489); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x3489); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3C89); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x2489); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2C89); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); +} + +void CX86Ops::MoveZxByteX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) +{ + uint8_t Param = 0; + + CPU_Message(" movzx %s, byte ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); + + PUTDST16(m_RecompPos, 0xB60F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); +} + +void CX86Ops::MoveZxHalfX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg) +{ + uint8_t Param = 0; + + CPU_Message(" movzx %s, word ptr [%s+%s]", x86_Name(reg), x86_Name(AddrReg1), x86_Name(AddrReg2)); + + PUTDST16(m_RecompPos, 0xB70F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x04); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1C); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0C); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x14); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x34); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3C); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x24); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2C); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg1) + { + case x86_EAX: Param = 0x00; break; + case x86_EBX: Param = 0x03; break; + case x86_ECX: Param = 0x01; break; + case x86_EDX: Param = 0x02; break; + case x86_ESI: Param = 0x06; break; + case x86_EDI: Param = 0x07; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (AddrReg2) + { + case x86_EAX: Param += 0x00; break; + case x86_EBX: Param += 0x18; break; + case x86_ECX: Param += 0x08; break; + case x86_EDX: Param += 0x10; break; + case x86_ESI: Param += 0x30; break; + case x86_EDI: Param += 0x38; break; + case x86_ESP: Param += 0x20; break; + case x86_EBP: Param += 0x28; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Param); +} + +void CX86Ops::MoveZxN64MemToX86regByte(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" movzx %s, byte ptr [%s+g_MMU->Rdram()]", x86_Name(reg), x86_Name(AddrReg)); + switch (AddrReg) + { + case x86_EAX: x86Command = 0x00B6; break; + case x86_EBX: x86Command = 0x03B6; break; + case x86_ECX: x86Command = 0x01B6; break; + case x86_EDX: x86Command = 0x02B6; break; + case x86_ESI: x86Command = 0x06B6; break; + case x86_EDI: x86Command = 0x07B6; break; + case x86_ESP: x86Command = 0x04B6; break; + case x86_EBP: x86Command = 0x05B6; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } + PUTDST8(m_RecompPos, 0x0f); + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveZxN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg) +{ + uint16_t x86Command = 0; + + CPU_Message(" movzx %s, word ptr [%s+g_MMU->Rdram()]", x86_Name(reg), x86_Name(AddrReg)); + + switch (AddrReg) + { + case x86_EAX: x86Command = 0x00B7; break; + case x86_EBX: x86Command = 0x03B7; break; + case x86_ECX: x86Command = 0x01B7; break; + case x86_EDX: x86Command = 0x02B7; break; + case x86_ESI: x86Command = 0x06B7; break; + case x86_EDI: x86Command = 0x07B7; break; + case x86_ESP: x86Command = 0x04B7; break; + case x86_EBP: x86Command = 0x05B7; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (reg) + { + case x86_EAX: x86Command += 0x8000; break; + case x86_EBX: x86Command += 0x9800; break; + case x86_ECX: x86Command += 0x8800; break; + case x86_EDX: x86Command += 0x9000; break; + case x86_ESI: x86Command += 0xB000; break; + case x86_EDI: x86Command += 0xB800; break; + case x86_ESP: x86Command += 0xA000; break; + case x86_EBP: x86Command += 0xA800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, 0x0f); + PUTDST16(m_RecompPos, x86Command); + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::MoveZxVariableToX86regByte(void *Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" movzx %s, byte ptr [%s]", x86_Name(reg), VariableName); + + PUTDST16(m_RecompPos, 0xb60f); + + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x05); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1D); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0D); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x15); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x35); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3D); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x25); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2D); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MoveZxVariableToX86regHalf(void *Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" movzx %s, word ptr [%s]", x86_Name(reg), VariableName); + + PUTDST16(m_RecompPos, 0xb70f); + + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x05); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x1D); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x0D); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x15); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x35); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x3D); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x25); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x2D); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::MulX86reg(x86Reg reg) +{ + CPU_Message(" mul %s", x86_Name(reg)); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE0F7); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xE3F7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE1F7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xE2F7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xE6F7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xE7F7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xE4F7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xE5F7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::NotX86Reg(x86Reg reg) +{ + CPU_Message(" not %s", x86_Name(reg)); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xD0F7); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xD3F7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xD1F7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xD2F7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xD6F7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xD7F7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xD4F7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xD5F7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::OrConstToVariable(uint32_t Const, void * Variable, const char * VariableName) +{ + CPU_Message(" or dword ptr [%s], 0x%X", VariableName, Const); + PUTDST16(m_RecompPos, 0x0D81); + PUTDST32(m_RecompPos, Variable); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::OrConstToX86Reg(uint32_t Const, x86Reg reg) +{ + CPU_Message(" or %s, %Xh", x86_Name(reg), Const); + if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + switch (reg) { + case x86_EAX: PUTDST16(m_RecompPos, 0xC881); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xCB81); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xC981); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xCA81); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xCE81); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xCF81); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xCC81); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xCD81); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Const); + } + else + { + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xC883); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xCB83); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xC983); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xCA83); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xCE83); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xCF83); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xCC83); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xCD83); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Const); + } +} + +void CX86Ops::OrVariableToX86Reg(void * Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" or %s, dword ptr [%s]", x86_Name(reg), VariableName); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x050B); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D0B); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D0B); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x150B); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x350B); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D0B); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x250B); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D0B); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::OrX86RegToVariable(void * Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" or dword ptr [%s], %s", VariableName, x86_Name(reg)); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x0509); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D09); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D09); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x1509); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x3509); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D09); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x2509); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D09); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::OrX86RegToX86Reg(x86Reg Destination, x86Reg Source) +{ + uint16_t x86Command = 0; + + CPU_Message(" or %s, %s", x86_Name(Destination), x86_Name(Source)); + switch (Source) + { + case x86_EAX: x86Command = 0x000B; break; + case x86_EBX: x86Command = 0x030B; break; + case x86_ECX: x86Command = 0x010B; break; + case x86_EDX: x86Command = 0x020B; break; + case x86_ESI: x86Command = 0x060B; break; + case x86_EDI: x86Command = 0x070B; break; + case x86_ESP: x86Command = 0x040B; break; + case x86_EBP: x86Command = 0x050B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (Destination) + { + case x86_EAX: x86Command += 0xC000; break; + case x86_EBX: x86Command += 0xD800; break; + case x86_ECX: x86Command += 0xC800; break; + case x86_EDX: x86Command += 0xD000; break; + case x86_ESI: x86Command += 0xF000; break; + case x86_EDI: x86Command += 0xF800; break; + case x86_ESP: x86Command += 0xE000; break; + case x86_EBP: x86Command += 0xE800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::Popad(void) +{ + CPU_Message(" popad"); + PUTDST8(m_RecompPos, 0x61); +} + +void CX86Ops::Pushad(void) +{ + CPU_Message(" pushad"); + PUTDST8(m_RecompPos, 0x60); +} + +void CX86Ops::Push(x86Reg reg) +{ + CPU_Message(" push %s", x86_Name(reg)); + + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x50); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x53); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x51); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x52); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x56); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x57); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x54); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x55); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::Pop(x86Reg reg) +{ + CPU_Message(" pop %s", x86_Name(reg)); + + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x58); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x5B); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x59); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x5A); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x5E); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x5F); break; + case x86_ESP: PUTDST8(m_RecompPos, 0x5C); break; + case x86_EBP: PUTDST8(m_RecompPos, 0x5D); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::PushImm32(uint32_t Value) +{ + PushImm32(stdstr_f("%d", Value).c_str(), Value); +} + +void CX86Ops::PushImm32(const char * String, uint32_t Value) +{ + CPU_Message(" push %s", String); + PUTDST8(m_RecompPos, 0x68); + PUTDST32(m_RecompPos, Value); +} + +void CX86Ops::Ret(void) { + CPU_Message(" ret"); + PUTDST8(m_RecompPos, 0xC3); +} + +void CX86Ops::Seta(x86Reg reg) +{ + CPU_Message(" seta %s", x86_ByteName(reg)); + PUTDST16(m_RecompPos, 0x970F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; + case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; + case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; + case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::SetaVariable(void * Variable, const char * VariableName) +{ + CPU_Message(" seta byte ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x970F); + PUTDST8(m_RecompPos, 0x05); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::Setae(x86Reg reg) +{ + CPU_Message(" setae %s", x86_ByteName(reg)); + PUTDST16(m_RecompPos, 0x930F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; + case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; + case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; + case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::Setb(x86Reg reg) +{ + CPU_Message(" setb %s", x86_ByteName(reg)); + PUTDST16(m_RecompPos, 0x920F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; + case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; + case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; + case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::SetbVariable(void * Variable, const char * VariableName) +{ + CPU_Message(" setb byte ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x920F); + PUTDST8(m_RecompPos, 0x05); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::Setg(x86Reg reg) +{ + CPU_Message(" setg %s", x86_ByteName(reg)); + PUTDST16(m_RecompPos, 0x9F0F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; + case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; + case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; + case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::SetgVariable(void * Variable, const char * VariableName) +{ + CPU_Message(" setg byte ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x9F0F); + PUTDST8(m_RecompPos, 0x05); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::Setl(x86Reg reg) +{ + CPU_Message(" setl %s", x86_ByteName(reg)); + PUTDST16(m_RecompPos, 0x9C0F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; + case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; + case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; + case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::SetlVariable(void * Variable, const char * VariableName) +{ + CPU_Message(" setl byte ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x9C0F); + PUTDST8(m_RecompPos, 0x05); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::Setz(x86Reg reg) +{ + CPU_Message(" setz %s", x86_ByteName(reg)); + PUTDST16(m_RecompPos, 0x940F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; + case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; + case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; + case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::Setnz(x86Reg reg) +{ + CPU_Message(" setnz %s", x86_ByteName(reg)); + PUTDST16(m_RecompPos, 0x950F); + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0xC0); break; + case x86_EBX: PUTDST8(m_RecompPos, 0xC3); break; + case x86_ECX: PUTDST8(m_RecompPos, 0xC1); break; + case x86_EDX: PUTDST8(m_RecompPos, 0xC2); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::ShiftLeftDouble(x86Reg Destination, x86Reg Source) +{ + uint8_t s = 0xC0; + + CPU_Message(" shld %s, %s, cl", x86_Name(Destination), x86_Name(Source)); + PUTDST16(m_RecompPos, 0xA50F); + + switch (Destination) + { + case x86_EAX: s |= 0x00; break; + case x86_EBX: s |= 0x03; break; + case x86_ECX: s |= 0x01; break; + case x86_EDX: s |= 0x02; break; + case x86_ESI: s |= 0x06; break; + case x86_EDI: s |= 0x07; break; + case x86_ESP: s |= 0x04; break; + case x86_EBP: s |= 0x05; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (Source) + { + case x86_EAX: s |= 0x00 << 3; break; + case x86_EBX: s |= 0x03 << 3; break; + case x86_ECX: s |= 0x01 << 3; break; + case x86_EDX: s |= 0x02 << 3; break; + case x86_ESI: s |= 0x06 << 3; break; + case x86_EDI: s |= 0x07 << 3; break; + case x86_ESP: s |= 0x04 << 3; break; + case x86_EBP: s |= 0x05 << 3; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, s); +} + +void CX86Ops::ShiftLeftDoubleImmed(x86Reg Destination, x86Reg Source, uint8_t Immediate) +{ + uint8_t s = 0xC0; + + CPU_Message(" shld %s, %s, %Xh", x86_Name(Destination), x86_Name(Source), Immediate); + PUTDST16(m_RecompPos, 0xA40F); + + switch (Destination) + { + case x86_EAX: s |= 0x00; break; + case x86_EBX: s |= 0x03; break; + case x86_ECX: s |= 0x01; break; + case x86_EDX: s |= 0x02; break; + case x86_ESI: s |= 0x06; break; + case x86_EDI: s |= 0x07; break; + case x86_ESP: s |= 0x04; break; + case x86_EBP: s |= 0x05; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (Source) + { + case x86_EAX: s |= 0x00 << 3; break; + case x86_EBX: s |= 0x03 << 3; break; + case x86_ECX: s |= 0x01 << 3; break; + case x86_EDX: s |= 0x02 << 3; break; + case x86_ESI: s |= 0x06 << 3; break; + case x86_EDI: s |= 0x07 << 3; break; + case x86_ESP: s |= 0x04 << 3; break; + case x86_EBP: s |= 0x05 << 3; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, s); + PUTDST8(m_RecompPos, Immediate); +} + +void CX86Ops::ShiftLeftSign(x86Reg reg) +{ + CPU_Message(" shl %s, cl", x86_Name(reg)); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE0D3); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xE3D3); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE1D3); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xE2D3); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xE6D3); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xE7D3); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xE4D3); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xE5D3); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::ShiftLeftSignImmed(x86Reg reg, uint8_t Immediate) +{ + CPU_Message(" shl %s, %Xh", x86_Name(reg), Immediate); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE0C1); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xE3C1); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE1C1); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xE2C1); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xE6C1); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xE7C1); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xE4C1); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xE5C1); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Immediate); +} + +void CX86Ops::ShiftRightSign(x86Reg reg) +{ + CPU_Message(" sar %s, cl", x86_Name(reg)); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xF8D3); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xFBD3); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xF9D3); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xFAD3); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xFED3); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xFFD3); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xFCD3); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xFDD3); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::ShiftRightSignImmed(x86Reg reg, uint8_t Immediate) +{ + CPU_Message(" sar %s, %Xh", x86_Name(reg), Immediate); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xF8C1); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xFBC1); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xF9C1); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xFAC1); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xFEC1); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xFFC1); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xFCC1); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xFDC1); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Immediate); +} + +void CX86Ops::ShiftRightUnsign(x86Reg reg) +{ + CPU_Message(" shr %s, cl", x86_Name(reg)); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE8D3); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xEBD3); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE9D3); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xEAD3); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xEED3); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xEFD3); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xECD3); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xEDD3); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::ShiftRightDouble(x86Reg Destination, x86Reg Source) +{ + uint8_t s = 0xC0; + + CPU_Message(" shrd %s, %s, cl", x86_Name(Destination), x86_Name(Source)); + PUTDST16(m_RecompPos, 0xAD0F); + + switch (Destination) + { + case x86_EAX: s |= 0x00; break; + case x86_EBX: s |= 0x03; break; + case x86_ECX: s |= 0x01; break; + case x86_EDX: s |= 0x02; break; + case x86_ESI: s |= 0x06; break; + case x86_EDI: s |= 0x07; break; + case x86_ESP: s |= 0x04; break; + case x86_EBP: s |= 0x05; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (Source) + { + case x86_EAX: s |= 0x00 << 3; break; + case x86_EBX: s |= 0x03 << 3; break; + case x86_ECX: s |= 0x01 << 3; break; + case x86_EDX: s |= 0x02 << 3; break; + case x86_ESI: s |= 0x06 << 3; break; + case x86_EDI: s |= 0x07 << 3; break; + case x86_ESP: s |= 0x04 << 3; break; + case x86_EBP: s |= 0x05 << 3; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, s); +} + +void CX86Ops::ShiftRightDoubleImmed(x86Reg Destination, x86Reg Source, uint8_t Immediate) +{ + uint8_t s = 0xC0; + + CPU_Message(" shrd %s, %s, %Xh", x86_Name(Destination), x86_Name(Source), Immediate); + PUTDST16(m_RecompPos, 0xAC0F); + + switch (Destination) + { + case x86_EAX: s |= 0x00; break; + case x86_EBX: s |= 0x03; break; + case x86_ECX: s |= 0x01; break; + case x86_EDX: s |= 0x02; break; + case x86_ESI: s |= 0x06; break; + case x86_EDI: s |= 0x07; break; + case x86_ESP: s |= 0x04; break; + case x86_EBP: s |= 0x05; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (Source) + { + case x86_EAX: s |= 0x00 << 3; break; + case x86_EBX: s |= 0x03 << 3; break; + case x86_ECX: s |= 0x01 << 3; break; + case x86_EDX: s |= 0x02 << 3; break; + case x86_ESI: s |= 0x06 << 3; break; + case x86_EDI: s |= 0x07 << 3; break; + case x86_ESP: s |= 0x04 << 3; break; + case x86_EBP: s |= 0x05 << 3; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, s); + PUTDST8(m_RecompPos, Immediate); +} + +void CX86Ops::ShiftRightUnsignImmed(x86Reg reg, uint8_t Immediate) +{ + CPU_Message(" shr %s, %Xh", x86_Name(reg), Immediate); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE8C1); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xEBC1); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE9C1); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xEAC1); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xEEC1); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xEFC1); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xECC1); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xEDC1); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Immediate); +} + +void CX86Ops::SbbConstFromX86Reg(x86Reg reg, uint32_t Const) +{ + CPU_Message(" sbb %s, %Xh", x86_Name(reg), Const); + if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xD881); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xDB81); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xD981); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xDA81); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xDE81); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xDF81); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xDC81); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xDD81); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Const); + } + else + { + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xD883); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xDB83); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xD983); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xDA83); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xDE83); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xDF83); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xDC83); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xDD83); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Const); + } +} + +void CX86Ops::SbbVariableFromX86reg(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" sbb %s, dword ptr [%s]", x86_Name(reg), VariableName); + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x051B); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D1B); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D1B); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x151B); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x351B); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D1B); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x251B); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D1B); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::SbbX86RegToX86Reg(x86Reg Destination, x86Reg Source) +{ + uint16_t x86Command = 0; + CPU_Message(" sbb %s, %s", x86_Name(Destination), x86_Name(Source)); + switch (Source) + { + case x86_EAX: x86Command = 0x001B; break; + case x86_EBX: x86Command = 0x031B; break; + case x86_ECX: x86Command = 0x011B; break; + case x86_EDX: x86Command = 0x021B; break; + case x86_ESI: x86Command = 0x061B; break; + case x86_EDI: x86Command = 0x071B; break; + case x86_ESP: x86Command = 0x041B; break; + case x86_EBP: x86Command = 0x051B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (Destination) + { + case x86_EAX: x86Command += 0xC000; break; + case x86_EBX: x86Command += 0xD800; break; + case x86_ECX: x86Command += 0xC800; break; + case x86_EDX: x86Command += 0xD000; break; + case x86_ESI: x86Command += 0xF000; break; + case x86_EDI: x86Command += 0xF800; break; + case x86_ESP: x86Command += 0xE000; break; + case x86_EBP: x86Command += 0xE800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::SubConstFromVariable(uint32_t Const, void *Variable, const char * VariableName) +{ + CPU_Message(" sub dword ptr [%s], 0x%X", VariableName, Const); + + PUTDST16(m_RecompPos, 0x2D81); + PUTDST32(m_RecompPos, Variable); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::SubConstFromX86Reg(x86Reg reg, uint32_t Const) +{ + CPU_Message(" sub %s, %Xh", x86_Name(reg), Const); + if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE881); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xEB81); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE981); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xEA81); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xEE81); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xEF81); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xEC81); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xED81); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Const); + } + else + { + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xE883); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xEB83); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xE983); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xEA83); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xEE83); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xEF83); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xEC83); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xED83); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Const); + } +} + +void CX86Ops::SubVariableFromX86reg(x86Reg reg, void * Variable, const char * VariableName) +{ + CPU_Message(" sub %s, dword ptr [%s]", x86_Name(reg), VariableName); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x052B); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D2B); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D2B); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x152B); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x352B); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D2B); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x252B); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D2B); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::SubX86RegToX86Reg(x86Reg Destination, x86Reg Source) +{ + uint16_t x86Command = 0; + CPU_Message(" sub %s, %s", x86_Name(Destination), x86_Name(Source)); + + switch (Source) + { + case x86_EAX: x86Command = 0x002B; break; + case x86_EBX: x86Command = 0x032B; break; + case x86_ECX: x86Command = 0x012B; break; + case x86_EDX: x86Command = 0x022B; break; + case x86_ESI: x86Command = 0x062B; break; + case x86_EDI: x86Command = 0x072B; break; + case x86_ESP: x86Command = 0x042B; break; + case x86_EBP: x86Command = 0x052B; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (Destination) + { + case x86_EAX: x86Command += 0xC000; break; + case x86_EBX: x86Command += 0xD800; break; + case x86_ECX: x86Command += 0xC800; break; + case x86_EDX: x86Command += 0xD000; break; + case x86_ESI: x86Command += 0xF000; break; + case x86_EDI: x86Command += 0xF800; break; + case x86_ESP: x86Command += 0xE000; break; + case x86_EBP: x86Command += 0xE800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::TestConstToX86Reg(uint32_t Const, x86Reg reg) +{ + CPU_Message(" test %s, 0x%X", x86_Name(reg), Const); + + switch (reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0xA9); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xC3F7); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xC1F7); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xC2F7); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xC6F7); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xC7F7); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xC4F7); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xC5F7); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::TestVariable(uint32_t Const, void * Variable, const char * VariableName) +{ + CPU_Message(" test dword ptr ds:[%s], 0x%X", VariableName, Const); + PUTDST16(m_RecompPos, 0x05F7); + PUTDST32(m_RecompPos, Variable); + PUTDST32(m_RecompPos, Const); +} + +void CX86Ops::TestX86RegToX86Reg(x86Reg Destination, x86Reg Source) +{ + uint16_t x86Command = 0; + CPU_Message(" test %s, %s", x86_Name(Destination), x86_Name(Source)); + switch (Source) + { + case x86_EAX: x86Command = 0x0085; break; + case x86_EBX: x86Command = 0x0385; break; + case x86_ECX: x86Command = 0x0185; break; + case x86_EDX: x86Command = 0x0285; break; + case x86_ESI: x86Command = 0x0685; break; + case x86_EDI: x86Command = 0x0785; break; + case x86_ESP: x86Command = 0x0485; break; + case x86_EBP: x86Command = 0x0585; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (Destination) + { + case x86_EAX: x86Command += 0xC000; break; + case x86_EBX: x86Command += 0xD800; break; + case x86_ECX: x86Command += 0xC800; break; + case x86_EDX: x86Command += 0xD000; break; + case x86_ESI: x86Command += 0xF000; break; + case x86_EDI: x86Command += 0xF800; break; + case x86_ESP: x86Command += 0xE000; break; + case x86_EBP: x86Command += 0xE800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::XorConstToX86Reg(x86Reg reg, uint32_t Const) +{ + CPU_Message(" xor %s, %Xh", x86_Name(reg), Const); + if ((Const & 0xFFFFFF80) != 0 && (Const & 0xFFFFFF80) != 0xFFFFFF80) + { + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xF081); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xF381); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xF181); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xF281); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xF681); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xF781); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xF481); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xF581); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Const); + } + else + { + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0xF083); break; + case x86_EBX: PUTDST16(m_RecompPos, 0xF383); break; + case x86_ECX: PUTDST16(m_RecompPos, 0xF183); break; + case x86_EDX: PUTDST16(m_RecompPos, 0xF283); break; + case x86_ESI: PUTDST16(m_RecompPos, 0xF683); break; + case x86_EDI: PUTDST16(m_RecompPos, 0xF783); break; + case x86_ESP: PUTDST16(m_RecompPos, 0xF483); break; + case x86_EBP: PUTDST16(m_RecompPos, 0xF583); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST8(m_RecompPos, Const); + } +} + +void CX86Ops::XorX86RegToX86Reg(x86Reg Source, x86Reg Destination) +{ + uint16_t x86Command = 0; + + CPU_Message(" xor %s, %s", x86_Name(Source), x86_Name(Destination)); + + switch (Source) + { + case x86_EAX: x86Command = 0x0031; break; + case x86_EBX: x86Command = 0x0331; break; + case x86_ECX: x86Command = 0x0131; break; + case x86_EDX: x86Command = 0x0231; break; + case x86_ESI: x86Command = 0x0631; break; + case x86_EDI: x86Command = 0x0731; break; + case x86_ESP: x86Command = 0x0431; break; + case x86_EBP: x86Command = 0x0531; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + switch (Destination) + { + case x86_EAX: x86Command += 0xC000; break; + case x86_EBX: x86Command += 0xD800; break; + case x86_ECX: x86Command += 0xC800; break; + case x86_EDX: x86Command += 0xD000; break; + case x86_ESI: x86Command += 0xF000; break; + case x86_EDI: x86Command += 0xF800; break; + case x86_ESP: x86Command += 0xE000; break; + case x86_EBP: x86Command += 0xE800; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::XorVariableToX86reg(void *Variable, const char * VariableName, x86Reg reg) +{ + CPU_Message(" Xor %s, dword ptr [%s]", x86_Name(reg), VariableName); + + switch (reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x0533); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x1D33); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x0D33); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x1533); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x3533); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x3D33); break; + case x86_ESP: PUTDST16(m_RecompPos, 0x2533); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x2D33); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuAbs(void) +{ + CPU_Message(" fabs ST(0)"); + PUTDST16(m_RecompPos, 0xE1D9); +} + +void CX86Ops::fpuAddDword(void *Variable, const char * VariableName) +{ + CPU_Message(" fadd ST(0), dword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x05D8); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuAddDwordRegPointer(x86Reg x86Pointer) +{ + CPU_Message(" fadd ST(0), dword ptr [%s]", x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x00D8); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x03D8); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x01D8); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x02D8); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x06D8); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x07D8); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuAddQword(void *Variable, const char * VariableName) +{ + CPU_Message(" fadd ST(0), qword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x05DC); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuAddQwordRegPointer(x86Reg x86Pointer) +{ + CPU_Message(" fadd ST(0), qword ptr [%s]", x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x00DC); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x03DC); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x01DC); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x02DC); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x06DC); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x07DC); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuAddReg(x86FpuValues x86reg) +{ + CPU_Message(" fadd ST(0), %s", fpu_Name(x86reg)); + switch (x86reg) { + case x86_ST0: PUTDST16(m_RecompPos, 0xC0D8); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xC1D8); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xC2D8); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xC3D8); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xC4D8); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xC5D8); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xC6D8); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xC7D8); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuAddRegPop(int * StackPos, x86FpuValues reg) +{ + CPU_Message(" faddp ST(0), %s", fpu_Name(reg)); + *StackPos = (*StackPos + 1) & 7; + switch (reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xC0DE); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xC1DE); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xC2DE); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xC3DE); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xC4DE); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xC5DE); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xC6DE); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xC7DE); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuComDword(void *Variable, const char * VariableName, bool Pop) +{ + CPU_Message(" fcom%s ST(0), dword ptr [%s]", m_fpupop[Pop], VariableName); + PUTDST16(m_RecompPos, Pop ? 0x1DD8 : 0x15D8); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuComDwordRegPointer(x86Reg x86Pointer, bool Pop) +{ + uint16_t x86Command; + + CPU_Message(" fcom%s ST(0), dword ptr [%s]", m_fpupop[Pop], x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: x86Command = 0x10D8; break; + case x86_EBX: x86Command = 0x13D8; break; + case x86_ECX: x86Command = 0x11D8; break; + case x86_EDX: x86Command = 0x12D8; break; + case x86_ESI: x86Command = 0x16D8; break; + case x86_EDI: x86Command = 0x17D8; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + if (Pop) + { + x86Command |= 0x0800; + } + + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::fpuComQword(void *Variable, const char * VariableName, bool Pop) +{ + CPU_Message(" fcom%s ST(0), qword ptr [%s]", m_fpupop[Pop], VariableName); + PUTDST16(m_RecompPos, Pop ? 0x1DDC : 0x15DC); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuComQwordRegPointer(x86Reg x86Pointer, bool Pop) +{ + uint16_t x86Command; + + CPU_Message(" fcom%s ST(0), qword ptr [%s]", m_fpupop[Pop], x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: x86Command = 0x10DC; break; + case x86_EBX: x86Command = 0x13DC; break; + case x86_ECX: x86Command = 0x11DC; break; + case x86_EDX: x86Command = 0x12DC; break; + case x86_ESI: x86Command = 0x16DC; break; + case x86_EDI: x86Command = 0x17DC; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + if (Pop) + { + x86Command |= 0x0800; + } + + PUTDST16(m_RecompPos, x86Command); +} + +void CX86Ops::fpuComReg(x86FpuValues x86reg, bool Pop) +{ + int s = Pop ? 0x0800 : 0x0000; + CPU_Message(" fcom%s ST(0), %s", m_fpupop[Pop], fpu_Name(x86reg)); + + switch (x86reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xD0D8 | s); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xD1D8 | s); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xD2D8 | s); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xD3D8 | s); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xD4D8 | s); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xD5D8 | s); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xD6D8 | s); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xD7D8 | s); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuDivDword(void *Variable, const char * VariableName) +{ + CPU_Message(" fdiv ST(0), dword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x35D8); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuDivDwordRegPointer(x86Reg x86Pointer) +{ + CPU_Message(" fdiv ST(0), dword ptr [%s]", x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x30D8); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x33D8); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x31D8); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x32D8); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x36D8); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x37D8); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuDivQword(void *Variable, const char * VariableName) +{ + CPU_Message(" fdiv ST(0), qword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x35DC); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuDivQwordRegPointer(x86Reg x86Pointer) +{ + CPU_Message(" fdiv ST(0), qword ptr [%s]", x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x30DC); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x33DC); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x31DC); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x32DC); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x36DC); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x37DC); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuDivReg(x86FpuValues Reg) +{ + CPU_Message(" fdiv ST(0), %s", fpu_Name(Reg)); + switch (Reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xF0D8); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xF1D8); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xF2D8); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xF3D8); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xF4D8); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xF5D8); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xF6D8); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xF7D8); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuDivRegPop(x86FpuValues reg) +{ + CPU_Message(" fdivp ST(0), %s", fpu_Name(reg)); + switch (reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xF8DE); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xF9DE); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xFADE); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xFBDE); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xFCDE); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xFDDE); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xFEDE); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xFFDE); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuExchange(x86FpuValues Reg) +{ + CPU_Message(" fxch ST(0), %s", fpu_Name(Reg)); + switch (Reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xC8D9); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xC9D9); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xCAD9); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xCBD9); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xCCD9); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xCDD9); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xCED9); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xCFD9); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuFree(x86FpuValues Reg) +{ + CPU_Message(" ffree %s", fpu_Name(Reg)); + switch (Reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xC0DD); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xC1DD); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xC2DD); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xC3DD); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xC4DD); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xC5DD); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xC6DD); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xC7DD); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuDecStack(int * StackPos) +{ + CPU_Message(" fdecstp"); + *StackPos = (*StackPos - 1) & 7; + PUTDST16(m_RecompPos, 0xF6D9); +} + +void CX86Ops::fpuIncStack(int * StackPos) +{ + CPU_Message(" fincstp"); + *StackPos = (*StackPos + 1) & 7; + PUTDST16(m_RecompPos, 0xF7D9); +} + +void CX86Ops::fpuLoadControl(void *Variable, const char * VariableName) +{ + CPU_Message(" fldcw [%s]", VariableName); + PUTDST16(m_RecompPos, 0x2DD9); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuLoadDword(int * StackPos, void *Variable, const char * VariableName) +{ + CPU_Message(" fld dword ptr [%s]", VariableName); + *StackPos = (*StackPos - 1) & 7; + PUTDST16(m_RecompPos, 0x05D9); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuLoadDwordFromX86Reg(int * StackPos, x86Reg x86reg) +{ + CPU_Message(" fld dword ptr [%s]", x86_Name(x86reg)); + *StackPos = (*StackPos - 1) & 7; + PUTDST8(m_RecompPos, 0xD9); + switch (x86reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x00); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x03); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x01); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x02); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x06); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x07); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::fpuLoadDwordFromN64Mem(int * StackPos, x86Reg x86reg) +{ + CPU_Message(" fld dword ptr [%s+N64mem]", x86_Name(x86reg)); + *StackPos = (*StackPos - 1) & 7; + switch (x86reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x80D9); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x83D9); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x81D9); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x82D9); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x86D9); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x87D9); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x85D9); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::fpuLoadInt32bFromN64Mem(int * StackPos, x86Reg x86reg) +{ + CPU_Message(" fild dword ptr [%s+N64mem]", x86_Name(x86reg)); + *StackPos = (*StackPos - 1) & 7; + switch (x86reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x80DB); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x83DB); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x81DB); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x82DB); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x86DB); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x87DB); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x85DB); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::fpuLoadIntegerDword(int * StackPos, void *Variable, const char * VariableName) +{ + CPU_Message(" fild dword ptr [%s]", VariableName); + *StackPos = (*StackPos - 1) & 7; + PUTDST16(m_RecompPos, 0x05DB); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuLoadIntegerDwordFromX86Reg(int * StackPos, x86Reg x86reg) +{ + CPU_Message(" fild dword ptr [%s]", x86_Name(x86reg)); + *StackPos = (*StackPos - 1) & 7; + PUTDST8(m_RecompPos, 0xDB); + switch (x86reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x00); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x03); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x01); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x02); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x06); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x07); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::fpuLoadIntegerQword(int * StackPos, void *Variable, const char * VariableName) +{ + CPU_Message(" fild qword ptr [%s]", VariableName); + *StackPos = (*StackPos - 1) & 7; + PUTDST16(m_RecompPos, 0x2DDF); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuLoadIntegerQwordFromX86Reg(int * StackPos, x86Reg x86reg) +{ + CPU_Message(" fild qword ptr [%s]", x86_Name(x86reg)); + *StackPos = (*StackPos - 1) & 7; + PUTDST8(m_RecompPos, 0xDF); + switch (x86reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x28); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x2B); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x29); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x2A); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x2E); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x2F); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::fpuLoadQword(int * StackPos, void *Variable, const char * VariableName) +{ + CPU_Message(" fld qword ptr [%s]", VariableName); + *StackPos = (*StackPos - 1) & 7; + PUTDST16(m_RecompPos, 0x05DD); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuLoadQwordFromX86Reg(int * StackPos, x86Reg x86reg) +{ + CPU_Message(" fld qword ptr [%s]", x86_Name(x86reg)); + *StackPos = (*StackPos - 1) & 7; + PUTDST8(m_RecompPos, 0xDD); + switch (x86reg) + { + case x86_EAX: PUTDST8(m_RecompPos, 0x00); break; + case x86_EBX: PUTDST8(m_RecompPos, 0x03); break; + case x86_ECX: PUTDST8(m_RecompPos, 0x01); break; + case x86_EDX: PUTDST8(m_RecompPos, 0x02); break; + case x86_ESI: PUTDST8(m_RecompPos, 0x06); break; + case x86_EDI: PUTDST8(m_RecompPos, 0x07); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::fpuLoadQwordFromN64Mem(int * StackPos, x86Reg x86reg) +{ + CPU_Message(" fld qword ptr [%s+N64mem]", x86_Name(x86reg)); + *StackPos = (*StackPos - 1) & 7; + switch (x86reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x80DD); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x83DD); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x81DD); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x82DD); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x86DD); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x87DD); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x85DD); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::fpuLoadReg(int * StackPos, x86FpuValues Reg) +{ + CPU_Message(" fld ST(0), %s", fpu_Name(Reg)); + *StackPos = (*StackPos - 1) & 7; + switch (Reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xC0D9); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xC1D9); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xC2D9); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xC3D9); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xC4D9); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xC5D9); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xC6D9); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xC7D9); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuMulDword(void *Variable, const char * VariableName) +{ + CPU_Message(" fmul ST(0), dword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x0DD8); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuMulDwordRegPointer(x86Reg x86Pointer) +{ + CPU_Message(" fmul ST(0), dword ptr [%s]", x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x08D8); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x0BD8); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x09D8); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x0AD8); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x0ED8); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x0FD8); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuMulQword(void *Variable, const char * VariableName) +{ + CPU_Message(" fmul ST(0), qword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x0DDC); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuMulQwordRegPointer(x86Reg x86Pointer) +{ + CPU_Message(" fmul ST(0), qword ptr [%s]", x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x08DC); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x0BDC); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x09DC); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x0ADC); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x0EDC); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x0FDC); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuMulReg(x86FpuValues x86reg) +{ + CPU_Message(" fmul ST(0), %s", fpu_Name(x86reg)); + switch (x86reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xC8D8); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xC9D8); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xCAD8); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xCBD8); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xCCD8); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xCDD8); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xCED8); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xCFD8); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuMulRegPop(x86FpuValues x86reg) +{ + CPU_Message(" fmulp ST(0), %s", fpu_Name(x86reg)); + switch (x86reg) + { + case x86_ST0: PUTDST16(m_RecompPos, 0xC8DE); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xC9DE); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xCADE); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xCBDE); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xCCDE); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xCDDE); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xCEDE); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xCFDE); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuNeg(void) +{ + CPU_Message(" fchs ST(0)"); + PUTDST16(m_RecompPos, 0xE0D9); +} + +void CX86Ops::fpuRound(void) +{ + CPU_Message(" frndint ST(0)"); + PUTDST16(m_RecompPos, 0xFCD9); +} + +void CX86Ops::fpuSqrt(void) +{ + CPU_Message(" fsqrt ST(0)"); + PUTDST16(m_RecompPos, 0xFAD9); +} + +void CX86Ops::fpuStoreControl(void *Variable, const char * VariableName) +{ + CPU_Message(" fnstcw [%s]", VariableName); + PUTDST16(m_RecompPos, 0x3DD9); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuStoreDword(int * StackPos, void *Variable, const char * VariableName, bool pop) +{ + CPU_Message(" fst%s dword ptr [%s]", m_fpupop[pop], VariableName); + + if (pop) + { + *StackPos = (*StackPos + 1) & 7; + } + + PUTDST16(m_RecompPos, pop ? 0x1DD9 : 0x15D9); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuStoreDwordFromX86Reg(int * StackPos, x86Reg x86reg, bool pop) +{ + uint8_t Command = 0; + + CPU_Message(" fst%s dword ptr [%s]", m_fpupop[pop], x86_Name(x86reg)); + + if (pop) + { + *StackPos = (*StackPos + 1) & 7; + } + + PUTDST8(m_RecompPos, 0xD9); + + switch (x86reg) + { + case x86_EAX: Command = 0x10; break; + case x86_EBX: Command = 0x13; break; + case x86_ECX: Command = 0x11; break; + case x86_EDX: Command = 0x12; break; + case x86_ESI: Command = 0x16; break; + case x86_EDI: Command = 0x17; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, pop ? (Command + 0x8) : Command); +} + +void CX86Ops::fpuStoreDwordToN64Mem(int * StackPos, x86Reg x86reg, bool Pop) +{ + int s = Pop ? 0x0800 : 0; + + CPU_Message(" fst%s dword ptr [%s+N64mem]", m_fpupop[Pop], x86_Name(x86reg)); + + if (Pop) + { + *StackPos = (*StackPos + 1) & 7; + } + + switch (x86reg) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x90D9 | s); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x93D9 | s); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x91D9 | s); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x92D9 | s); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x96D9 | s); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x97D9 | s); break; + case x86_EBP: PUTDST16(m_RecompPos, 0x95D9 | s); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST32(m_RecompPos, g_MMU->Rdram()); +} + +void CX86Ops::fpuStoreIntegerDword(int * StackPos, void *Variable, const char * VariableName, bool pop) +{ + CPU_Message(" fist%s dword ptr [%s]", m_fpupop[pop], VariableName); + + if (pop) + { + *StackPos = (*StackPos + 1) & 7; + } + PUTDST16(m_RecompPos, pop ? 0x1DDB : 0x15DB); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuStoreIntegerDwordFromX86Reg(int * StackPos, x86Reg x86reg, bool pop) +{ + uint8_t Command = 0; + + CPU_Message(" fist%s dword ptr [%s]", m_fpupop[pop], x86_Name(x86reg)); + + if (pop) + { + *StackPos = (*StackPos + 1) & 7; + } + + PUTDST8(m_RecompPos, 0xDB); + + switch (x86reg) + { + case x86_EAX: Command = 0x10; break; + case x86_EBX: Command = 0x13; break; + case x86_ECX: Command = 0x11; break; + case x86_EDX: Command = 0x12; break; + case x86_ESI: Command = 0x16; break; + case x86_EDI: Command = 0x17; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, pop ? (Command + 0x8) : Command); +} + +void CX86Ops::fpuStoreIntegerQword(int * StackPos, void *Variable, const char * VariableName, bool pop) +{ + CPU_Message(" fist%s qword ptr [%s]", m_fpupop[pop], VariableName); + + if (pop) + { + *StackPos = (*StackPos + 1) & 7; + } + + PUTDST16(m_RecompPos, pop ? 0x3DDF : 0x35DF); + PUTDST32(m_RecompPos, Variable); + + if (!pop) + { + X86BreakPoint(__FILE__, __LINE__); + } +} + +void CX86Ops::fpuStoreIntegerQwordFromX86Reg(int * StackPos, x86Reg x86reg, bool pop) +{ + uint8_t Command = 0; + + CPU_Message(" fist%s qword ptr [%s]", m_fpupop[pop], x86_Name(x86reg)); + + if (pop) + { + *StackPos = (*StackPos + 1) & 7; + } + + PUTDST8(m_RecompPos, 0xDF); + + switch (x86reg) { + case x86_EAX: Command = 0x30; break; + case x86_EBX: Command = 0x33; break; + case x86_ECX: Command = 0x31; break; + case x86_EDX: Command = 0x32; break; + case x86_ESI: Command = 0x36; break; + case x86_EDI: Command = 0x37; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, pop ? (Command + 0x8) : Command); +} + +void CX86Ops::fpuStoreQwordFromX86Reg(int * StackPos, x86Reg x86reg, bool pop) +{ + uint8_t Command = 0; + + CPU_Message(" fst%s qword ptr [%s]", m_fpupop[pop], x86_Name(x86reg)); + + if (pop) + { + *StackPos = (*StackPos + 1) & 7; + } + + PUTDST8(m_RecompPos, 0xDD); + + switch (x86reg) + { + case x86_EAX: Command = 0x10; break; + case x86_EBX: Command = 0x13; break; + case x86_ECX: Command = 0x11; break; + case x86_EDX: Command = 0x12; break; + case x86_ESI: Command = 0x16; break; + case x86_EDI: Command = 0x17; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + PUTDST8(m_RecompPos, pop ? (Command + 0x8) : Command); +} + +void CX86Ops::fpuStoreStatus(void) +{ + CPU_Message(" fnstsw ax"); + PUTDST16(m_RecompPos, 0xE0DF); +} + +void CX86Ops::fpuSubDword(void *Variable, const char * VariableName) +{ + CPU_Message(" fsub ST(0), dword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x25D8); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuSubDwordRegPointer(x86Reg x86Pointer) +{ + CPU_Message(" fsub ST(0), dword ptr [%s]", x86_Name(x86Pointer)); + switch (x86Pointer) + { + case x86_EAX: PUTDST16(m_RecompPos, 0x20D8); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x23D8); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x21D8); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x22D8); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x26D8); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x27D8); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuSubDwordReverse(void *Variable, const char * VariableName) +{ + CPU_Message(" fsubr ST(0), dword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x2DD8); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuSubQword(void *Variable, const char * VariableName) +{ + CPU_Message(" fsub ST(0), qword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x25DC); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuSubQwordRegPointer(x86Reg x86Pointer) +{ + CPU_Message(" fsub ST(0), qword ptr [%s]", x86_Name(x86Pointer)); + switch (x86Pointer) { + case x86_EAX: PUTDST16(m_RecompPos, 0x20DC); break; + case x86_EBX: PUTDST16(m_RecompPos, 0x23DC); break; + case x86_ECX: PUTDST16(m_RecompPos, 0x21DC); break; + case x86_EDX: PUTDST16(m_RecompPos, 0x22DC); break; + case x86_ESI: PUTDST16(m_RecompPos, 0x26DC); break; + case x86_EDI: PUTDST16(m_RecompPos, 0x27DC); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuSubQwordReverse(void *Variable, const char * VariableName) +{ + CPU_Message(" fsubr ST(0), qword ptr [%s]", VariableName); + PUTDST16(m_RecompPos, 0x2DDC); + PUTDST32(m_RecompPos, Variable); +} + +void CX86Ops::fpuSubReg(x86FpuValues x86reg) +{ + CPU_Message(" fsub ST(0), %s", fpu_Name(x86reg)); + switch (x86reg) { + case x86_ST0: PUTDST16(m_RecompPos, 0xE0D8); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xE1D8); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xE2D8); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xE3D8); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xE4D8); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xE5D8); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xE6D8); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xE7D8); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +void CX86Ops::fpuSubRegPop(x86FpuValues x86reg) +{ + CPU_Message(" fsubp ST(0), %s", fpu_Name(x86reg)); + switch (x86reg) { + case x86_ST0: PUTDST16(m_RecompPos, 0xE8DE); break; + case x86_ST1: PUTDST16(m_RecompPos, 0xE9DE); break; + case x86_ST2: PUTDST16(m_RecompPos, 0xEADE); break; + case x86_ST3: PUTDST16(m_RecompPos, 0xEBDE); break; + case x86_ST4: PUTDST16(m_RecompPos, 0xECDE); break; + case x86_ST5: PUTDST16(m_RecompPos, 0xEDDE); break; + case x86_ST6: PUTDST16(m_RecompPos, 0xEEDE); break; + case x86_ST7: PUTDST16(m_RecompPos, 0xEFDE); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } +} + +const char * CX86Ops::x86_Name(x86Reg Reg) +{ + switch (Reg) { + case x86_EAX: return "eax"; + case x86_EBX: return "ebx"; + case x86_ECX: return "ecx"; + case x86_EDX: return "edx"; + case x86_ESI: return "esi"; + case x86_EDI: return "edi"; + case x86_EBP: return "ebp"; + case x86_ESP: return "esp"; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + return "???"; +} + +const char * CX86Ops::x86_ByteName(x86Reg Reg) +{ + switch (Reg) { + case x86_AL: return "al"; + case x86_BL: return "bl"; + case x86_CL: return "cl"; + case x86_DL: return "dl"; + case x86_AH: return "ah"; + case x86_BH: return "bh"; + case x86_CH: return "ch"; + case x86_DH: return "dh"; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + return "???"; +} + +const char * CX86Ops::x86_HalfName(x86Reg Reg) +{ + switch (Reg) + { + case x86_EAX: return "ax"; + case x86_EBX: return "bx"; + case x86_ECX: return "cx"; + case x86_EDX: return "dx"; + case x86_ESI: return "si"; + case x86_EDI: return "di"; + case x86_EBP: return "bp"; + case x86_ESP: return "sp"; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + return "???"; +} + +const char * CX86Ops::fpu_Name(x86FpuValues Reg) +{ + switch (Reg) + { + case x86_ST0: return "ST(0)"; + case x86_ST1: return "ST(1)"; + case x86_ST2: return "ST(2)"; + case x86_ST3: return "ST(3)"; + case x86_ST4: return "ST(4)"; + case x86_ST5: return "ST(5)"; + case x86_ST6: return "ST(6)"; + case x86_ST7: return "ST(7)"; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + return "???"; +} + +bool CX86Ops::Is8BitReg(x86Reg Reg) +{ + return (Reg == x86_EAX) || + (Reg == x86_EBX) || + (Reg == x86_ECX) || + (Reg == x86_EDX); +} + +uint8_t CX86Ops::CalcMultiplyCode(Multipler Multiply) +{ + switch (Multiply) + { + case Multip_x2: return 0x40; + case Multip_x4: return 0x80; + case Multip_x8: return 0xC0; + default: return 0; + } +} + +void CX86Ops::SetJump32(uint32_t * Loc, uint32_t * JumpLoc) +{ + *Loc = (uint32_t)(((uint32_t)JumpLoc) - (((uint32_t)(Loc)) + 4)); +} + +void CX86Ops::SetJump8(uint8_t * Loc, uint8_t * JumpLoc) +{ + if (Loc == NULL || JumpLoc == NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + uint32_t diffrence = (uint32_t)(((uint32_t)JumpLoc) - (((uint32_t)(Loc)) + 1)); + if (diffrence > 255) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + *Loc = (uint8_t)diffrence; +} + +void * CX86Ops::GetAddressOf(int value, ...) +{ + void * Address; + + va_list ap; + va_start(ap, value); + Address = va_arg(ap, void *); + va_end(ap); + + return Address; } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Recompiler/X86ops.h b/Source/Project64-core/N64System/Recompiler/X86ops.h index c6c5d6101..5afeedb3d 100644 --- a/Source/Project64-core/N64System/Recompiler/X86ops.h +++ b/Source/Project64-core/N64System/Recompiler/X86ops.h @@ -1,304 +1,304 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CX86Ops -{ -public: - enum x86Reg - { - x86_EAX = 0, - x86_EBX = 3, - x86_ECX = 1, - x86_EDX = 2, - x86_ESI = 6, - x86_EDI = 7, - x86_EBP = 5, - x86_ESP = 4, - x86_Any8Bit = -3, - x86_Any = -2, - x86_Unknown = -1, - - x86_AL = 0, x86_BL = 3, x86_CL = 1, x86_DL = 2, - x86_AH = 4, x86_BH = 7, x86_CH = 5, x86_DH = 6 - }; - - enum x86FpuValues - { - x86_ST_Unknown = -1, - x86_ST0 = 0, - x86_ST1 = 1, - x86_ST2 = 2, - x86_ST3 = 3, - x86_ST4 = 4, - x86_ST5 = 5, - x86_ST6 = 6, - x86_ST7 = 7 - }; - - enum Multipler - { - Multip_x1 = 1, - Multip_x2 = 2, - Multip_x4 = 4, - Multip_x8 = 8 - }; - - static x86Reg x86_Registers[8]; - static const char * x86_Name(x86Reg Reg); - static const char * x86_ByteName(x86Reg Reg); - static const char * x86_HalfName(x86Reg Reg); - static const char * fpu_Name(x86FpuValues Reg); - -protected: - //Logging Functions - static void WriteX86Comment(const char * Comment); - static void WriteX86Label(const char * Label); - - static void AdcX86regToVariable(x86Reg reg, void * Variable, const char * VariableName); - static void AdcConstToVariable(void *Variable, const char * VariableName, uint8_t Constant); - static void AdcConstToX86Reg(x86Reg Reg, uint32_t Const); - static void AdcVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName); - static void AdcX86RegToX86Reg(x86Reg Destination, x86Reg Source); - static void AddConstToVariable(uint32_t Const, void *Variable, const char * VariableName); - static void AddConstToX86Reg(x86Reg Reg, uint32_t Const); - static void AddVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName); - static void AddX86regToVariable(x86Reg reg, void * Variable, const char * VariableName); - static void AddX86RegToX86Reg(x86Reg Destination, x86Reg Source); - static void AndConstToVariable(uint32_t Const, void *Variable, const char * VariableName); - static void AndConstToX86Reg(x86Reg Reg, uint32_t Const); - static void AndVariableToX86Reg(void * Variable, const char * VariableName, x86Reg Reg); - static void AndVariableDispToX86Reg(void * Variable, const char * VariableName, x86Reg Reg, x86Reg AddrReg, Multipler Multiply); - static void AndX86RegToX86Reg(x86Reg Destination, x86Reg Source); - static void X86HardBreakPoint(); - static void X86BreakPoint(const char * FileName, int32_t LineNumber); - static void Call_Direct(void * FunctAddress, const char * FunctName); - static void Call_Indirect(void * FunctAddress, const char * FunctName); - static void CompConstToVariable(uint32_t Const, void * Variable, const char * VariableName); - static void CompConstToX86reg(x86Reg Reg, uint32_t Const); - static void CompConstToX86regPointer(x86Reg Reg, uint32_t Const); - static void CompX86regToVariable(x86Reg Reg, void * Variable, const char * VariableName); - static void CompVariableToX86reg(x86Reg Reg, void * Variable, const char * VariableName); - static void CompX86RegToX86Reg(x86Reg Destination, x86Reg Source); - static void DecX86reg(x86Reg Reg); - static void DivX86reg(x86Reg reg); - static void idivX86reg(x86Reg reg); - static void imulX86reg(x86Reg reg); - static void IncX86reg(x86Reg Reg); - static void JaeLabel8(const char * Label, uint8_t Value); - static void JaeLabel32(const char * Label, uint32_t Value); - static void JaLabel8(const char * Label, uint8_t Value); - static void JaLabel32(const char * Label, uint32_t Value); - static void JbLabel8(const char * Label, uint8_t Value); - static void JbLabel32(const char * Label, uint32_t Value); - static void JecxzLabel8(const char * Label, uint8_t Value); - static void JeLabel8(const char * Label, uint8_t Value); - static void JeLabel32(const char * Label, uint32_t Value); - static void JgeLabel32(const char * Label, uint32_t Value); - static void JgLabel8(const char * Label, uint8_t Value); - static void JgLabel32(const char * Label, uint32_t Value); - static void JleLabel8(const char * Label, uint8_t Value); - static void JleLabel32(const char * Label, uint32_t Value); - static void JlLabel8(const char * Label, uint8_t Value); - static void JlLabel32(const char * Label, uint32_t Value); - static void JmpDirectReg(x86Reg reg); - static void JmpIndirectLabel32(const char * Label, uint32_t location); - static void JmpIndirectReg(x86Reg reg); - static void JmpLabel8(const char * Label, uint8_t Value); - static void JmpLabel32(const char * Label, uint32_t Value); - static void JneLabel8(const char * Label, uint8_t Value); - static void JneLabel32(const char * Label, uint32_t Value); - static void JnsLabel8(const char * Label, uint8_t Value); - static void JnsLabel32(const char * Label, uint32_t Value); - static void JnzLabel8(const char * Label, uint8_t Value); - static void JnzLabel32(const char * Label, uint32_t Value); - static void JsLabel32(const char * Label, uint32_t Value); - static void JzLabel8(const char * Label, uint8_t Value); - static void JzLabel32(const char * Label, uint32_t Value); - static void LeaRegReg(x86Reg RegDest, x86Reg RegSrc, uint32_t Const, Multipler multiplier); - static void LeaRegReg2(x86Reg RegDest, x86Reg RegSrc, x86Reg RegSrc2, Multipler multiplier); - static void LeaSourceAndOffset(x86Reg x86DestReg, x86Reg x86SourceReg, int32_t offset); - static void MoveConstByteToN64Mem(uint8_t Const, x86Reg AddrReg); - static void MoveConstHalfToN64Mem(uint16_t Const, x86Reg AddrReg); - static void MoveConstByteToVariable(uint8_t Const, void * Variable, const char * VariableName); - static void MoveConstByteToX86regPointer(uint8_t Const, x86Reg AddrReg1, x86Reg AddrReg2); - static void MoveConstHalfToVariable(uint16_t Const, void * Variable, const char * VariableName); - static void MoveConstHalfToX86regPointer(uint16_t Const, x86Reg AddrReg1, x86Reg AddrReg2); - static void MoveConstToMemoryDisp(uint32_t Const, x86Reg AddrReg, uint32_t Disp); - static void MoveConstToN64Mem(uint32_t Const, x86Reg AddrReg); - static void MoveConstToN64MemDisp(uint32_t Const, x86Reg AddrReg, uint8_t Disp); - static void MoveConstToVariable(uint32_t Const, void * Variable, const char * VariableName); - static void MoveConstToX86Pointer(uint32_t Const, x86Reg X86Pointer); - static void MoveConstToX86reg(uint32_t Const, x86Reg reg); - static void MoveConstToX86regPointer(uint32_t Const, x86Reg AddrReg1, x86Reg AddrReg2); - static void MoveN64MemDispToX86reg(x86Reg reg, x86Reg AddrReg, uint8_t Disp); - static void MoveN64MemToX86reg(x86Reg reg, x86Reg AddrReg); - static void MoveN64MemToX86regByte(x86Reg reg, x86Reg AddrReg); - static void MoveN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg); - static void MoveSxByteX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); - static void MoveSxHalfX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); - static void MoveSxN64MemToX86regByte(x86Reg reg, x86Reg AddrReg); - static void MoveSxN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg); - static void MoveSxVariableToX86regByte(void * Variable, const char * VariableName, x86Reg reg); - static void MoveSxVariableToX86regHalf(void * Variable, const char * VariableName, x86Reg reg); - static void MoveVariableDispToX86Reg(void * Variable, const char * VariableName, x86Reg Reg, x86Reg AddrReg, int32_t Multiplier); - static void MoveVariableToX86reg(void * Variable, const char * VariableName, x86Reg reg); - static void MoveVariableToX86regByte(void * Variable, const char * VariableName, x86Reg reg); - static void MoveVariableToX86regHalf(void * Variable, const char * VariableName, x86Reg reg); - static void MoveX86PointerToX86reg(x86Reg reg, x86Reg X86Pointer); - static void MoveX86PointerToX86regDisp(x86Reg reg, x86Reg X86Pointer, uint8_t Disp); - static void MoveX86regByteToN64Mem(x86Reg reg, x86Reg AddrReg); - static void MoveX86regByteToVariable(x86Reg reg, void * Variable, const char * VariableName); - static void MoveX86regByteToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2); - static void MoveX86regHalfToN64Mem(x86Reg reg, x86Reg AddrReg); - static void MoveX86regHalfToVariable(x86Reg reg, void * Variable, const char * VariableName); - static void MoveX86regHalfToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2); - static void MoveX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); - static void MoveX86regPointerToX86regDisp8(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg, uint8_t offset); - static void MoveX86regToMemory(x86Reg reg, x86Reg AddrReg, uint32_t Disp); - static void MoveX86regToN64Mem(x86Reg reg, x86Reg AddrReg); - static void MoveX86regToN64MemDisp(x86Reg reg, x86Reg AddrReg, uint8_t Disp); - static void MoveX86regToVariable(x86Reg reg, void * Variable, const char * VariableName); - static void MoveX86RegToX86Reg(x86Reg Source, x86Reg Destination); - static void MoveX86regToX86Pointer(x86Reg reg, x86Reg X86Pointer); - static void MoveX86regToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2); - static void MoveZxByteX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); - static void MoveZxHalfX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); - static void MoveZxN64MemToX86regByte(x86Reg reg, x86Reg AddrReg); - static void MoveZxN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg); - static void MoveZxVariableToX86regByte(void * Variable, const char * VariableName, x86Reg reg); - static void MoveZxVariableToX86regHalf(void * Variable, const char * VariableName, x86Reg reg); - static void MulX86reg(x86Reg reg); - static void NotX86Reg(x86Reg Reg); - static void OrConstToVariable(uint32_t Const, void * Variable, const char * VariableName); - static void OrConstToX86Reg(uint32_t Const, x86Reg reg); - static void OrVariableToX86Reg(void * Variable, const char * VariableName, x86Reg Reg); - static void OrX86RegToVariable(void * Variable, const char * VariableName, x86Reg Reg); - static void OrX86RegToX86Reg(x86Reg Destination, x86Reg Source); - static void Push(x86Reg reg); - static void Pushad(); - static void PushImm32(uint32_t Value); - static void PushImm32(const char * String, uint32_t Value); - static void Pop(x86Reg reg); - static void Popad(); - static void Ret(); - static void Seta(x86Reg reg); - static void Setae(x86Reg reg); - static void SetaVariable(void * Variable, const char * VariableName); - static void Setb(x86Reg reg); - static void SetbVariable(void * Variable, const char * VariableName); - static void Setg(x86Reg reg); - static void SetgVariable(void * Variable, const char * VariableName); - static void Setl(x86Reg reg); - static void SetlVariable(void * Variable, const char * VariableName); - static void Setz(x86Reg reg); - static void Setnz(x86Reg reg); - static void ShiftLeftDouble(x86Reg Destination, x86Reg Source); - static void ShiftLeftDoubleImmed(x86Reg Destination, x86Reg Source, uint8_t Immediate); - static void ShiftLeftSign(x86Reg reg); - static void ShiftLeftSignImmed(x86Reg reg, uint8_t Immediate); - static void ShiftRightDouble(x86Reg Destination, x86Reg Source); - static void ShiftRightDoubleImmed(x86Reg Destination, x86Reg Source, uint8_t Immediate); - static void ShiftRightSign(x86Reg reg); - static void ShiftRightSignImmed(x86Reg reg, uint8_t Immediate); - static void ShiftRightUnsign(x86Reg reg); - static void ShiftRightUnsignImmed(x86Reg reg, uint8_t Immediate); - static void SbbConstFromX86Reg(x86Reg Reg, uint32_t Const); - static void SbbVariableFromX86reg(x86Reg reg, void * Variable, const char * VariableName); - static void SbbX86RegToX86Reg(x86Reg Destination, x86Reg Source); - static void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName); - static void SubConstFromX86Reg(x86Reg Reg, uint32_t Const); - static void SubVariableFromX86reg(x86Reg reg, void * Variable, const char * VariableName); - static void SubX86RegToX86Reg(x86Reg Destination, x86Reg Source); - static void TestConstToX86Reg(uint32_t Const, x86Reg reg); - static void TestVariable(uint32_t Const, void * Variable, const char * VariableName); - static void TestX86RegToX86Reg(x86Reg Destination, x86Reg Source); - static void XorConstToX86Reg(x86Reg Reg, uint32_t Const); - static void XorX86RegToX86Reg(x86Reg Source, x86Reg Destination); - static void XorVariableToX86reg(void * Variable, const char * VariableName, x86Reg reg); - - static void fpuAbs(); - static void fpuAddDword(void * Variable, const char * VariableName); - static void fpuAddDwordRegPointer(x86Reg x86Pointer); - static void fpuAddQword(void * Variable, const char * VariableName); - static void fpuAddQwordRegPointer(x86Reg X86Pointer); - static void fpuAddReg(x86FpuValues reg); - static void fpuAddRegPop(int32_t * StackPos, x86FpuValues reg); - static void fpuComDword(void * Variable, const char * VariableName, bool Pop); - static void fpuComDwordRegPointer(x86Reg X86Pointer, bool Pop); - static void fpuComQword(void * Variable, const char * VariableName, bool Pop); - static void fpuComQwordRegPointer(x86Reg X86Pointer, bool Pop); - static void fpuComReg(x86FpuValues reg, bool Pop); - static void fpuDivDword(void * Variable, const char * VariableName); - static void fpuDivDwordRegPointer(x86Reg X86Pointer); - static void fpuDivQword(void * Variable, const char * VariableName); - static void fpuDivQwordRegPointer(x86Reg X86Pointer); - static void fpuDivReg(x86FpuValues Reg); - static void fpuDivRegPop(x86FpuValues reg); - static void fpuExchange(x86FpuValues Reg); - static void fpuFree(x86FpuValues Reg); - static void fpuDecStack(int32_t * StackPos); - static void fpuIncStack(int32_t * StackPos); - static void fpuLoadControl(void * Variable, const char * VariableName); - static void fpuLoadDword(int32_t * StackPos, void * Variable, const char * VariableName); - static void fpuLoadDwordFromX86Reg(int32_t * StackPos, x86Reg reg); - static void fpuLoadDwordFromN64Mem(int32_t * StackPos, x86Reg reg); - static void fpuLoadInt32bFromN64Mem(int32_t * StackPos, x86Reg reg); - static void fpuLoadIntegerDword(int32_t * StackPos, void * Variable, const char * VariableName); - static void fpuLoadIntegerDwordFromX86Reg(int32_t * StackPos, x86Reg Reg); - static void fpuLoadIntegerQword(int32_t * StackPos, void * Variable, const char * VariableName); - static void fpuLoadIntegerQwordFromX86Reg(int32_t * StackPos, x86Reg Reg); - static void fpuLoadQword(int32_t * StackPos, void * Variable, const char * VariableName); - static void fpuLoadQwordFromX86Reg(int32_t * StackPos, x86Reg Reg); - static void fpuLoadQwordFromN64Mem(int32_t * StackPos, x86Reg reg); - static void fpuLoadReg(int32_t * StackPos, x86FpuValues Reg); - static void fpuMulDword(void * Variable, const char * VariableName); - static void fpuMulDwordRegPointer(x86Reg X86Pointer); - static void fpuMulQword(void * Variable, const char * VariableName); - static void fpuMulQwordRegPointer(x86Reg X86Pointer); - static void fpuMulReg(x86FpuValues reg); - static void fpuMulRegPop(x86FpuValues reg); - static void fpuNeg(); - static void fpuRound(); - static void fpuSqrt(); - static void fpuStoreControl(void * Variable, const char * VariableName); - static void fpuStoreDword(int32_t * StackPos, void * Variable, const char * VariableName, bool pop); - static void fpuStoreDwordFromX86Reg(int32_t * StackPos, x86Reg Reg, bool pop); - static void fpuStoreDwordToN64Mem(int32_t * StackPos, x86Reg reg, bool Pop); - static void fpuStoreIntegerDword(int32_t * StackPos, void * Variable, const char * VariableName, bool pop); - static void fpuStoreIntegerDwordFromX86Reg(int32_t * StackPos, x86Reg Reg, bool pop); - static void fpuStoreIntegerQword(int32_t * StackPos, void * Variable, const char * VariableName, bool pop); - static void fpuStoreIntegerQwordFromX86Reg(int32_t * StackPos, x86Reg Reg, bool pop); - static void fpuStoreQwordFromX86Reg(int32_t * StackPos, x86Reg Reg, bool pop); - static void fpuStoreStatus(); - static void fpuSubDword(void * Variable, const char * VariableName); - static void fpuSubDwordRegPointer(x86Reg X86Pointer); - static void fpuSubDwordReverse(void * Variable, const char * VariableName); - static void fpuSubQword(void * Variable, const char * VariableName); - static void fpuSubQwordRegPointer(x86Reg X86Pointer); - static void fpuSubQwordReverse(void * Variable, const char * VariableName); - static void fpuSubReg(x86FpuValues reg); - static void fpuSubRegPop(x86FpuValues reg); - - static bool Is8BitReg(x86Reg Reg); - static uint8_t CalcMultiplyCode(Multipler Multiply); - static uint8_t * m_RecompPos; - - static void * GetAddressOf(int32_t value, ...); - static void SetJump32(uint32_t * Loc, uint32_t * JumpLoc); - static void SetJump8(uint8_t * Loc, uint8_t * JumpLoc); - -private: - static void BreakPointNotification(const char * FileName, int32_t LineNumber); - static char m_fpupop[2][2]; -}; - -#define AddressOf(Addr) CX86Ops::GetAddressOf(5,(Addr)) +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CX86Ops +{ +public: + enum x86Reg + { + x86_EAX = 0, + x86_EBX = 3, + x86_ECX = 1, + x86_EDX = 2, + x86_ESI = 6, + x86_EDI = 7, + x86_EBP = 5, + x86_ESP = 4, + x86_Any8Bit = -3, + x86_Any = -2, + x86_Unknown = -1, + + x86_AL = 0, x86_BL = 3, x86_CL = 1, x86_DL = 2, + x86_AH = 4, x86_BH = 7, x86_CH = 5, x86_DH = 6 + }; + + enum x86FpuValues + { + x86_ST_Unknown = -1, + x86_ST0 = 0, + x86_ST1 = 1, + x86_ST2 = 2, + x86_ST3 = 3, + x86_ST4 = 4, + x86_ST5 = 5, + x86_ST6 = 6, + x86_ST7 = 7 + }; + + enum Multipler + { + Multip_x1 = 1, + Multip_x2 = 2, + Multip_x4 = 4, + Multip_x8 = 8 + }; + + static x86Reg x86_Registers[8]; + static const char * x86_Name(x86Reg Reg); + static const char * x86_ByteName(x86Reg Reg); + static const char * x86_HalfName(x86Reg Reg); + static const char * fpu_Name(x86FpuValues Reg); + +protected: + //Logging Functions + static void WriteX86Comment(const char * Comment); + static void WriteX86Label(const char * Label); + + static void AdcX86regToVariable(x86Reg reg, void * Variable, const char * VariableName); + static void AdcConstToVariable(void *Variable, const char * VariableName, uint8_t Constant); + static void AdcConstToX86Reg(x86Reg Reg, uint32_t Const); + static void AdcVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName); + static void AdcX86RegToX86Reg(x86Reg Destination, x86Reg Source); + static void AddConstToVariable(uint32_t Const, void *Variable, const char * VariableName); + static void AddConstToX86Reg(x86Reg Reg, uint32_t Const); + static void AddVariableToX86reg(x86Reg reg, void * Variable, const char * VariableName); + static void AddX86regToVariable(x86Reg reg, void * Variable, const char * VariableName); + static void AddX86RegToX86Reg(x86Reg Destination, x86Reg Source); + static void AndConstToVariable(uint32_t Const, void *Variable, const char * VariableName); + static void AndConstToX86Reg(x86Reg Reg, uint32_t Const); + static void AndVariableToX86Reg(void * Variable, const char * VariableName, x86Reg Reg); + static void AndVariableDispToX86Reg(void * Variable, const char * VariableName, x86Reg Reg, x86Reg AddrReg, Multipler Multiply); + static void AndX86RegToX86Reg(x86Reg Destination, x86Reg Source); + static void X86HardBreakPoint(); + static void X86BreakPoint(const char * FileName, int32_t LineNumber); + static void Call_Direct(void * FunctAddress, const char * FunctName); + static void Call_Indirect(void * FunctAddress, const char * FunctName); + static void CompConstToVariable(uint32_t Const, void * Variable, const char * VariableName); + static void CompConstToX86reg(x86Reg Reg, uint32_t Const); + static void CompConstToX86regPointer(x86Reg Reg, uint32_t Const); + static void CompX86regToVariable(x86Reg Reg, void * Variable, const char * VariableName); + static void CompVariableToX86reg(x86Reg Reg, void * Variable, const char * VariableName); + static void CompX86RegToX86Reg(x86Reg Destination, x86Reg Source); + static void DecX86reg(x86Reg Reg); + static void DivX86reg(x86Reg reg); + static void idivX86reg(x86Reg reg); + static void imulX86reg(x86Reg reg); + static void IncX86reg(x86Reg Reg); + static void JaeLabel8(const char * Label, uint8_t Value); + static void JaeLabel32(const char * Label, uint32_t Value); + static void JaLabel8(const char * Label, uint8_t Value); + static void JaLabel32(const char * Label, uint32_t Value); + static void JbLabel8(const char * Label, uint8_t Value); + static void JbLabel32(const char * Label, uint32_t Value); + static void JecxzLabel8(const char * Label, uint8_t Value); + static void JeLabel8(const char * Label, uint8_t Value); + static void JeLabel32(const char * Label, uint32_t Value); + static void JgeLabel32(const char * Label, uint32_t Value); + static void JgLabel8(const char * Label, uint8_t Value); + static void JgLabel32(const char * Label, uint32_t Value); + static void JleLabel8(const char * Label, uint8_t Value); + static void JleLabel32(const char * Label, uint32_t Value); + static void JlLabel8(const char * Label, uint8_t Value); + static void JlLabel32(const char * Label, uint32_t Value); + static void JmpDirectReg(x86Reg reg); + static void JmpIndirectLabel32(const char * Label, uint32_t location); + static void JmpIndirectReg(x86Reg reg); + static void JmpLabel8(const char * Label, uint8_t Value); + static void JmpLabel32(const char * Label, uint32_t Value); + static void JneLabel8(const char * Label, uint8_t Value); + static void JneLabel32(const char * Label, uint32_t Value); + static void JnsLabel8(const char * Label, uint8_t Value); + static void JnsLabel32(const char * Label, uint32_t Value); + static void JnzLabel8(const char * Label, uint8_t Value); + static void JnzLabel32(const char * Label, uint32_t Value); + static void JsLabel32(const char * Label, uint32_t Value); + static void JzLabel8(const char * Label, uint8_t Value); + static void JzLabel32(const char * Label, uint32_t Value); + static void LeaRegReg(x86Reg RegDest, x86Reg RegSrc, uint32_t Const, Multipler multiplier); + static void LeaRegReg2(x86Reg RegDest, x86Reg RegSrc, x86Reg RegSrc2, Multipler multiplier); + static void LeaSourceAndOffset(x86Reg x86DestReg, x86Reg x86SourceReg, int32_t offset); + static void MoveConstByteToN64Mem(uint8_t Const, x86Reg AddrReg); + static void MoveConstHalfToN64Mem(uint16_t Const, x86Reg AddrReg); + static void MoveConstByteToVariable(uint8_t Const, void * Variable, const char * VariableName); + static void MoveConstByteToX86regPointer(uint8_t Const, x86Reg AddrReg1, x86Reg AddrReg2); + static void MoveConstHalfToVariable(uint16_t Const, void * Variable, const char * VariableName); + static void MoveConstHalfToX86regPointer(uint16_t Const, x86Reg AddrReg1, x86Reg AddrReg2); + static void MoveConstToMemoryDisp(uint32_t Const, x86Reg AddrReg, uint32_t Disp); + static void MoveConstToN64Mem(uint32_t Const, x86Reg AddrReg); + static void MoveConstToN64MemDisp(uint32_t Const, x86Reg AddrReg, uint8_t Disp); + static void MoveConstToVariable(uint32_t Const, void * Variable, const char * VariableName); + static void MoveConstToX86Pointer(uint32_t Const, x86Reg X86Pointer); + static void MoveConstToX86reg(uint32_t Const, x86Reg reg); + static void MoveConstToX86regPointer(uint32_t Const, x86Reg AddrReg1, x86Reg AddrReg2); + static void MoveN64MemDispToX86reg(x86Reg reg, x86Reg AddrReg, uint8_t Disp); + static void MoveN64MemToX86reg(x86Reg reg, x86Reg AddrReg); + static void MoveN64MemToX86regByte(x86Reg reg, x86Reg AddrReg); + static void MoveN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg); + static void MoveSxByteX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); + static void MoveSxHalfX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); + static void MoveSxN64MemToX86regByte(x86Reg reg, x86Reg AddrReg); + static void MoveSxN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg); + static void MoveSxVariableToX86regByte(void * Variable, const char * VariableName, x86Reg reg); + static void MoveSxVariableToX86regHalf(void * Variable, const char * VariableName, x86Reg reg); + static void MoveVariableDispToX86Reg(void * Variable, const char * VariableName, x86Reg Reg, x86Reg AddrReg, int32_t Multiplier); + static void MoveVariableToX86reg(void * Variable, const char * VariableName, x86Reg reg); + static void MoveVariableToX86regByte(void * Variable, const char * VariableName, x86Reg reg); + static void MoveVariableToX86regHalf(void * Variable, const char * VariableName, x86Reg reg); + static void MoveX86PointerToX86reg(x86Reg reg, x86Reg X86Pointer); + static void MoveX86PointerToX86regDisp(x86Reg reg, x86Reg X86Pointer, uint8_t Disp); + static void MoveX86regByteToN64Mem(x86Reg reg, x86Reg AddrReg); + static void MoveX86regByteToVariable(x86Reg reg, void * Variable, const char * VariableName); + static void MoveX86regByteToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2); + static void MoveX86regHalfToN64Mem(x86Reg reg, x86Reg AddrReg); + static void MoveX86regHalfToVariable(x86Reg reg, void * Variable, const char * VariableName); + static void MoveX86regHalfToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2); + static void MoveX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); + static void MoveX86regPointerToX86regDisp8(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg, uint8_t offset); + static void MoveX86regToMemory(x86Reg reg, x86Reg AddrReg, uint32_t Disp); + static void MoveX86regToN64Mem(x86Reg reg, x86Reg AddrReg); + static void MoveX86regToN64MemDisp(x86Reg reg, x86Reg AddrReg, uint8_t Disp); + static void MoveX86regToVariable(x86Reg reg, void * Variable, const char * VariableName); + static void MoveX86RegToX86Reg(x86Reg Source, x86Reg Destination); + static void MoveX86regToX86Pointer(x86Reg reg, x86Reg X86Pointer); + static void MoveX86regToX86regPointer(x86Reg reg, x86Reg AddrReg1, x86Reg AddrReg2); + static void MoveZxByteX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); + static void MoveZxHalfX86regPointerToX86reg(x86Reg AddrReg1, x86Reg AddrReg2, x86Reg reg); + static void MoveZxN64MemToX86regByte(x86Reg reg, x86Reg AddrReg); + static void MoveZxN64MemToX86regHalf(x86Reg reg, x86Reg AddrReg); + static void MoveZxVariableToX86regByte(void * Variable, const char * VariableName, x86Reg reg); + static void MoveZxVariableToX86regHalf(void * Variable, const char * VariableName, x86Reg reg); + static void MulX86reg(x86Reg reg); + static void NotX86Reg(x86Reg Reg); + static void OrConstToVariable(uint32_t Const, void * Variable, const char * VariableName); + static void OrConstToX86Reg(uint32_t Const, x86Reg reg); + static void OrVariableToX86Reg(void * Variable, const char * VariableName, x86Reg Reg); + static void OrX86RegToVariable(void * Variable, const char * VariableName, x86Reg Reg); + static void OrX86RegToX86Reg(x86Reg Destination, x86Reg Source); + static void Push(x86Reg reg); + static void Pushad(); + static void PushImm32(uint32_t Value); + static void PushImm32(const char * String, uint32_t Value); + static void Pop(x86Reg reg); + static void Popad(); + static void Ret(); + static void Seta(x86Reg reg); + static void Setae(x86Reg reg); + static void SetaVariable(void * Variable, const char * VariableName); + static void Setb(x86Reg reg); + static void SetbVariable(void * Variable, const char * VariableName); + static void Setg(x86Reg reg); + static void SetgVariable(void * Variable, const char * VariableName); + static void Setl(x86Reg reg); + static void SetlVariable(void * Variable, const char * VariableName); + static void Setz(x86Reg reg); + static void Setnz(x86Reg reg); + static void ShiftLeftDouble(x86Reg Destination, x86Reg Source); + static void ShiftLeftDoubleImmed(x86Reg Destination, x86Reg Source, uint8_t Immediate); + static void ShiftLeftSign(x86Reg reg); + static void ShiftLeftSignImmed(x86Reg reg, uint8_t Immediate); + static void ShiftRightDouble(x86Reg Destination, x86Reg Source); + static void ShiftRightDoubleImmed(x86Reg Destination, x86Reg Source, uint8_t Immediate); + static void ShiftRightSign(x86Reg reg); + static void ShiftRightSignImmed(x86Reg reg, uint8_t Immediate); + static void ShiftRightUnsign(x86Reg reg); + static void ShiftRightUnsignImmed(x86Reg reg, uint8_t Immediate); + static void SbbConstFromX86Reg(x86Reg Reg, uint32_t Const); + static void SbbVariableFromX86reg(x86Reg reg, void * Variable, const char * VariableName); + static void SbbX86RegToX86Reg(x86Reg Destination, x86Reg Source); + static void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName); + static void SubConstFromX86Reg(x86Reg Reg, uint32_t Const); + static void SubVariableFromX86reg(x86Reg reg, void * Variable, const char * VariableName); + static void SubX86RegToX86Reg(x86Reg Destination, x86Reg Source); + static void TestConstToX86Reg(uint32_t Const, x86Reg reg); + static void TestVariable(uint32_t Const, void * Variable, const char * VariableName); + static void TestX86RegToX86Reg(x86Reg Destination, x86Reg Source); + static void XorConstToX86Reg(x86Reg Reg, uint32_t Const); + static void XorX86RegToX86Reg(x86Reg Source, x86Reg Destination); + static void XorVariableToX86reg(void * Variable, const char * VariableName, x86Reg reg); + + static void fpuAbs(); + static void fpuAddDword(void * Variable, const char * VariableName); + static void fpuAddDwordRegPointer(x86Reg x86Pointer); + static void fpuAddQword(void * Variable, const char * VariableName); + static void fpuAddQwordRegPointer(x86Reg X86Pointer); + static void fpuAddReg(x86FpuValues reg); + static void fpuAddRegPop(int32_t * StackPos, x86FpuValues reg); + static void fpuComDword(void * Variable, const char * VariableName, bool Pop); + static void fpuComDwordRegPointer(x86Reg X86Pointer, bool Pop); + static void fpuComQword(void * Variable, const char * VariableName, bool Pop); + static void fpuComQwordRegPointer(x86Reg X86Pointer, bool Pop); + static void fpuComReg(x86FpuValues reg, bool Pop); + static void fpuDivDword(void * Variable, const char * VariableName); + static void fpuDivDwordRegPointer(x86Reg X86Pointer); + static void fpuDivQword(void * Variable, const char * VariableName); + static void fpuDivQwordRegPointer(x86Reg X86Pointer); + static void fpuDivReg(x86FpuValues Reg); + static void fpuDivRegPop(x86FpuValues reg); + static void fpuExchange(x86FpuValues Reg); + static void fpuFree(x86FpuValues Reg); + static void fpuDecStack(int32_t * StackPos); + static void fpuIncStack(int32_t * StackPos); + static void fpuLoadControl(void * Variable, const char * VariableName); + static void fpuLoadDword(int32_t * StackPos, void * Variable, const char * VariableName); + static void fpuLoadDwordFromX86Reg(int32_t * StackPos, x86Reg reg); + static void fpuLoadDwordFromN64Mem(int32_t * StackPos, x86Reg reg); + static void fpuLoadInt32bFromN64Mem(int32_t * StackPos, x86Reg reg); + static void fpuLoadIntegerDword(int32_t * StackPos, void * Variable, const char * VariableName); + static void fpuLoadIntegerDwordFromX86Reg(int32_t * StackPos, x86Reg Reg); + static void fpuLoadIntegerQword(int32_t * StackPos, void * Variable, const char * VariableName); + static void fpuLoadIntegerQwordFromX86Reg(int32_t * StackPos, x86Reg Reg); + static void fpuLoadQword(int32_t * StackPos, void * Variable, const char * VariableName); + static void fpuLoadQwordFromX86Reg(int32_t * StackPos, x86Reg Reg); + static void fpuLoadQwordFromN64Mem(int32_t * StackPos, x86Reg reg); + static void fpuLoadReg(int32_t * StackPos, x86FpuValues Reg); + static void fpuMulDword(void * Variable, const char * VariableName); + static void fpuMulDwordRegPointer(x86Reg X86Pointer); + static void fpuMulQword(void * Variable, const char * VariableName); + static void fpuMulQwordRegPointer(x86Reg X86Pointer); + static void fpuMulReg(x86FpuValues reg); + static void fpuMulRegPop(x86FpuValues reg); + static void fpuNeg(); + static void fpuRound(); + static void fpuSqrt(); + static void fpuStoreControl(void * Variable, const char * VariableName); + static void fpuStoreDword(int32_t * StackPos, void * Variable, const char * VariableName, bool pop); + static void fpuStoreDwordFromX86Reg(int32_t * StackPos, x86Reg Reg, bool pop); + static void fpuStoreDwordToN64Mem(int32_t * StackPos, x86Reg reg, bool Pop); + static void fpuStoreIntegerDword(int32_t * StackPos, void * Variable, const char * VariableName, bool pop); + static void fpuStoreIntegerDwordFromX86Reg(int32_t * StackPos, x86Reg Reg, bool pop); + static void fpuStoreIntegerQword(int32_t * StackPos, void * Variable, const char * VariableName, bool pop); + static void fpuStoreIntegerQwordFromX86Reg(int32_t * StackPos, x86Reg Reg, bool pop); + static void fpuStoreQwordFromX86Reg(int32_t * StackPos, x86Reg Reg, bool pop); + static void fpuStoreStatus(); + static void fpuSubDword(void * Variable, const char * VariableName); + static void fpuSubDwordRegPointer(x86Reg X86Pointer); + static void fpuSubDwordReverse(void * Variable, const char * VariableName); + static void fpuSubQword(void * Variable, const char * VariableName); + static void fpuSubQwordRegPointer(x86Reg X86Pointer); + static void fpuSubQwordReverse(void * Variable, const char * VariableName); + static void fpuSubReg(x86FpuValues reg); + static void fpuSubRegPop(x86FpuValues reg); + + static bool Is8BitReg(x86Reg Reg); + static uint8_t CalcMultiplyCode(Multipler Multiply); + static uint8_t * m_RecompPos; + + static void * GetAddressOf(int32_t value, ...); + static void SetJump32(uint32_t * Loc, uint32_t * JumpLoc); + static void SetJump8(uint8_t * Loc, uint8_t * JumpLoc); + +private: + static void BreakPointNotification(const char * FileName, int32_t LineNumber); + static char m_fpupop[2][2]; +}; + +#define AddressOf(Addr) CX86Ops::GetAddressOf(5,(Addr)) diff --git a/Source/Project64-core/N64System/Recompiler/x86CodeLog.cpp b/Source/Project64-core/N64System/Recompiler/x86CodeLog.cpp index 9bd60a426..e64a2fe22 100644 --- a/Source/Project64-core/N64System/Recompiler/x86CodeLog.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86CodeLog.cpp @@ -1,58 +1,58 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "x86CodeLog.h" -#include -#include - -static HANDLE hCPULogFile = NULL; -bool bX86Logging = false; - -void x86_Log_Message (const char * Message, ...) -{ - DWORD dwWritten; - char Msg[400]; - - va_list ap; - va_start( ap, Message ); - vsprintf( Msg, Message, ap ); - va_end( ap ); - - strcat(Msg,"\r\n"); - - WriteFile( hCPULogFile,Msg,strlen(Msg),&dwWritten,NULL ); -} - -void Start_x86_Log (void) -{ - CPath LogFileName(CPath::MODULE_DIRECTORY); - LogFileName.AppendDirectory("Logs"); - LogFileName.SetNameExtension("CPUoutput.log"); - - if (hCPULogFile) { Stop_x86_Log(); } - hCPULogFile = CreateFile(LogFileName,GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, - CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hCPULogFile) - { - bX86Logging = true; - SetFilePointer(hCPULogFile,0,NULL,FILE_BEGIN); - } -} - -void Stop_x86_Log (void) -{ - if (hCPULogFile) - { - CloseHandle(hCPULogFile); - hCPULogFile = NULL; - bX86Logging = false; - } -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "x86CodeLog.h" +#include +#include + +static HANDLE hCPULogFile = NULL; +bool bX86Logging = false; + +void x86_Log_Message (const char * Message, ...) +{ + DWORD dwWritten; + char Msg[400]; + + va_list ap; + va_start( ap, Message ); + vsprintf( Msg, Message, ap ); + va_end( ap ); + + strcat(Msg,"\r\n"); + + WriteFile( hCPULogFile,Msg,strlen(Msg),&dwWritten,NULL ); +} + +void Start_x86_Log (void) +{ + CPath LogFileName(CPath::MODULE_DIRECTORY); + LogFileName.AppendDirectory("Logs"); + LogFileName.SetNameExtension("CPUoutput.log"); + + if (hCPULogFile) { Stop_x86_Log(); } + hCPULogFile = CreateFile(LogFileName,GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, + CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (hCPULogFile) + { + bX86Logging = true; + SetFilePointer(hCPULogFile,0,NULL,FILE_BEGIN); + } +} + +void Stop_x86_Log (void) +{ + if (hCPULogFile) + { + CloseHandle(hCPULogFile); + hCPULogFile = NULL; + bX86Logging = false; + } +} diff --git a/Source/Project64-core/N64System/SpeedLimiterClass.cpp b/Source/Project64-core/N64System/SpeedLimiterClass.cpp index f090d53cb..892a63c8f 100644 --- a/Source/Project64-core/N64System/SpeedLimiterClass.cpp +++ b/Source/Project64-core/N64System/SpeedLimiterClass.cpp @@ -1,135 +1,135 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SpeedLimiterClass.h" -#include -#ifdef _WIN32 -#include -#include -#pragma comment(lib, "winmm.lib") -#endif - -CSpeedLimiter::CSpeedLimiter() -{ - m_Frames = 0; - m_LastTime = 0; - m_Speed = 60; - m_BaseSpeed = 60; - m_Ratio = 1000.0F / (float)m_Speed; - -#ifdef _WIN32 - TIMECAPS Caps; - timeGetDevCaps(&Caps, sizeof(Caps)); - if (timeBeginPeriod(Caps.wPeriodMin) == TIMERR_NOCANDO) - { - g_Notify->DisplayError("Error during timer begin"); - } -#endif -} - -CSpeedLimiter::~CSpeedLimiter() -{ -#ifdef _WIN32 - TIMECAPS Caps; - timeGetDevCaps(&Caps, sizeof(Caps)); - timeEndPeriod(Caps.wPeriodMin); -#endif -} - -void CSpeedLimiter::SetHertz(uint32_t Hertz) -{ - m_Speed = Hertz; - m_BaseSpeed = Hertz; - FixSpeedRatio(); -} - -void CSpeedLimiter::FixSpeedRatio() -{ - m_Ratio = 1000.0f / static_cast(m_Speed); - m_Frames = 0; -#ifdef _WIN32 - m_LastTime = timeGetTime(); -#endif -} - -bool CSpeedLimiter::Timer_Process(uint32_t * FrameRate) -{ -#ifdef _WIN32 - m_Frames += 1; - uint32_t CurrentTime = timeGetTime(); - - /* Calculate time that should of elapsed for this frame */ - double CalculatedTime = (double)m_LastTime + (m_Ratio * (double)m_Frames); - if ((double)CurrentTime < CalculatedTime) - { - int32_t time = (int)(CalculatedTime - (double)CurrentTime); - if (time > 0) - { - pjutil::Sleep(time); - } - - /* Refresh current time */ - CurrentTime = timeGetTime(); - } - - if (CurrentTime - m_LastTime >= 1000) - { - /* Output FPS */ - if (FrameRate != NULL) { *FrameRate = m_Frames; } - m_Frames = 0; - m_LastTime = CurrentTime; - - return true; - } - else - { - return false; - } -#else - return false; -#endif -} - -void CSpeedLimiter::IncreaseSpeed() -{ - if (m_Speed >= 60) - { - m_Speed += 10; - } - else if (m_Speed >= 15) - { - m_Speed += 5; - } - else - { - m_Speed += 1; - } - SpeedChanged(m_Speed); - FixSpeedRatio(); -} - -void CSpeedLimiter::DecreaseSpeed() -{ - if (m_Speed > 60) - { - m_Speed -= 10; - } - else if (m_Speed > 15) - { - m_Speed -= 5; - } - else if (m_Speed > 1) - { - m_Speed -= 1; - } - SpeedChanged(m_Speed); - FixSpeedRatio(); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SpeedLimiterClass.h" +#include +#ifdef _WIN32 +#include +#include +#pragma comment(lib, "winmm.lib") +#endif + +CSpeedLimiter::CSpeedLimiter() +{ + m_Frames = 0; + m_LastTime = 0; + m_Speed = 60; + m_BaseSpeed = 60; + m_Ratio = 1000.0F / (float)m_Speed; + +#ifdef _WIN32 + TIMECAPS Caps; + timeGetDevCaps(&Caps, sizeof(Caps)); + if (timeBeginPeriod(Caps.wPeriodMin) == TIMERR_NOCANDO) + { + g_Notify->DisplayError("Error during timer begin"); + } +#endif +} + +CSpeedLimiter::~CSpeedLimiter() +{ +#ifdef _WIN32 + TIMECAPS Caps; + timeGetDevCaps(&Caps, sizeof(Caps)); + timeEndPeriod(Caps.wPeriodMin); +#endif +} + +void CSpeedLimiter::SetHertz(uint32_t Hertz) +{ + m_Speed = Hertz; + m_BaseSpeed = Hertz; + FixSpeedRatio(); +} + +void CSpeedLimiter::FixSpeedRatio() +{ + m_Ratio = 1000.0f / static_cast(m_Speed); + m_Frames = 0; +#ifdef _WIN32 + m_LastTime = timeGetTime(); +#endif +} + +bool CSpeedLimiter::Timer_Process(uint32_t * FrameRate) +{ +#ifdef _WIN32 + m_Frames += 1; + uint32_t CurrentTime = timeGetTime(); + + /* Calculate time that should of elapsed for this frame */ + double CalculatedTime = (double)m_LastTime + (m_Ratio * (double)m_Frames); + if ((double)CurrentTime < CalculatedTime) + { + int32_t time = (int)(CalculatedTime - (double)CurrentTime); + if (time > 0) + { + pjutil::Sleep(time); + } + + /* Refresh current time */ + CurrentTime = timeGetTime(); + } + + if (CurrentTime - m_LastTime >= 1000) + { + /* Output FPS */ + if (FrameRate != NULL) { *FrameRate = m_Frames; } + m_Frames = 0; + m_LastTime = CurrentTime; + + return true; + } + else + { + return false; + } +#else + return false; +#endif +} + +void CSpeedLimiter::IncreaseSpeed() +{ + if (m_Speed >= 60) + { + m_Speed += 10; + } + else if (m_Speed >= 15) + { + m_Speed += 5; + } + else + { + m_Speed += 1; + } + SpeedChanged(m_Speed); + FixSpeedRatio(); +} + +void CSpeedLimiter::DecreaseSpeed() +{ + if (m_Speed > 60) + { + m_Speed -= 10; + } + else if (m_Speed > 15) + { + m_Speed -= 5; + } + else if (m_Speed > 1) + { + m_Speed -= 1; + } + SpeedChanged(m_Speed); + FixSpeedRatio(); +} diff --git a/Source/Project64-core/N64System/SpeedLimiterClass.h b/Source/Project64-core/N64System/SpeedLimiterClass.h index 22ff9fab3..0969be7fe 100644 --- a/Source/Project64-core/N64System/SpeedLimiterClass.h +++ b/Source/Project64-core/N64System/SpeedLimiterClass.h @@ -1,35 +1,35 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CSpeedLimiter : - private CGameSettings -{ -public: - CSpeedLimiter(); - ~CSpeedLimiter(); - - void SetHertz(const uint32_t Hertz); - bool Timer_Process(uint32_t* const FrameRate); - void IncreaseSpeed(); - void DecreaseSpeed(); - -private: - CSpeedLimiter(const CSpeedLimiter&); // Disable copy constructor - CSpeedLimiter& operator=(const CSpeedLimiter&); // Disable assignment - - void FixSpeedRatio(); - - uint32_t m_Speed, m_BaseSpeed, m_Frames, m_LastTime; - double m_Ratio; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CSpeedLimiter : + private CGameSettings +{ +public: + CSpeedLimiter(); + ~CSpeedLimiter(); + + void SetHertz(const uint32_t Hertz); + bool Timer_Process(uint32_t* const FrameRate); + void IncreaseSpeed(); + void DecreaseSpeed(); + +private: + CSpeedLimiter(const CSpeedLimiter&); // Disable copy constructor + CSpeedLimiter& operator=(const CSpeedLimiter&); // Disable assignment + + void FixSpeedRatio(); + + uint32_t m_Speed, m_BaseSpeed, m_Frames, m_LastTime; + double m_Ratio; +}; diff --git a/Source/Project64-core/N64System/SystemGlobals.cpp b/Source/Project64-core/N64System/SystemGlobals.cpp index f46c5a754..53f0214bc 100644 --- a/Source/Project64-core/N64System/SystemGlobals.cpp +++ b/Source/Project64-core/N64System/SystemGlobals.cpp @@ -1,34 +1,34 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SystemGlobals.h" - -CN64System * g_System = NULL; -CN64System * g_BaseSystem = NULL; -CN64System * g_SyncSystem = NULL; -CRecompiler * g_Recompiler = NULL; -CMipsMemoryVM * g_MMU = NULL; //Memory of the n64 -CTLB * g_TLB = NULL; //TLB Unit -CRegisters * g_Reg = NULL; //Current Register Set attacted to the g_MMU -CNotification * g_Notify = NULL; -CPlugins * g_Plugins = NULL; -CN64Rom * g_Rom = NULL; //The current rom that this system is executing.. it can only execute one file at the time -CN64Rom * g_DDRom = NULL; //64DD IPL ROM -CN64Disk * g_Disk = NULL; //64DD DISK -CAudio * g_Audio = NULL; -CSystemTimer * g_SystemTimer = NULL; -CTransVaddr * g_TransVaddr = NULL; -CSystemEvents * g_SystemEvents = NULL; -uint32_t * g_TLBLoadAddress = NULL; -uint32_t * g_TLBStoreAddress = NULL; -CDebugger * g_Debugger = NULL; - +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SystemGlobals.h" + +CN64System * g_System = NULL; +CN64System * g_BaseSystem = NULL; +CN64System * g_SyncSystem = NULL; +CRecompiler * g_Recompiler = NULL; +CMipsMemoryVM * g_MMU = NULL; //Memory of the n64 +CTLB * g_TLB = NULL; //TLB Unit +CRegisters * g_Reg = NULL; //Current Register Set attacted to the g_MMU +CNotification * g_Notify = NULL; +CPlugins * g_Plugins = NULL; +CN64Rom * g_Rom = NULL; //The current rom that this system is executing.. it can only execute one file at the time +CN64Rom * g_DDRom = NULL; //64DD IPL ROM +CN64Disk * g_Disk = NULL; //64DD DISK +CAudio * g_Audio = NULL; +CSystemTimer * g_SystemTimer = NULL; +CTransVaddr * g_TransVaddr = NULL; +CSystemEvents * g_SystemEvents = NULL; +uint32_t * g_TLBLoadAddress = NULL; +uint32_t * g_TLBStoreAddress = NULL; +CDebugger * g_Debugger = NULL; + int * g_NextTimer; \ No newline at end of file diff --git a/Source/Project64-core/N64System/SystemGlobals.h b/Source/Project64-core/N64System/SystemGlobals.h index de4086076..80b338b21 100644 --- a/Source/Project64-core/N64System/SystemGlobals.h +++ b/Source/Project64-core/N64System/SystemGlobals.h @@ -1,60 +1,60 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettings; -extern CSettings * g_Settings; - -class CN64System; -extern CN64System * g_System; -extern CN64System * g_BaseSystem; -extern CN64System * g_SyncSystem; - -class CRecompiler; -extern CRecompiler * g_Recompiler; - -class CMipsMemoryVM; -extern CMipsMemoryVM * g_MMU; //Memory of the n64 - -class CTLB; -extern CTLB * g_TLB; //TLB Unit - -class CRegisters; -extern CRegisters * g_Reg; //Current Register Set attached to the g_MMU - -class CPlugins; -extern CPlugins * g_Plugins; - -class CN64Rom; -extern CN64Rom * g_Rom; //The current rom that this system is executing.. it can only execute one file at the time -extern CN64Rom * g_DDRom; //64DD IPL ROM - -class CN64Disk; -extern CN64Disk * g_Disk; //64DD DISK - -class CAudio; -extern CAudio * g_Audio; - -class CSystemTimer; -extern CSystemTimer * g_SystemTimer; - -__interface CTransVaddr; -extern CTransVaddr * g_TransVaddr; - -class CSystemEvents; -extern CSystemEvents * g_SystemEvents; - -extern int32_t * g_NextTimer; -extern uint32_t * g_TLBLoadAddress; -extern uint32_t * g_TLBStoreAddress; - -__interface CDebugger; -extern CDebugger * g_Debugger; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettings; +extern CSettings * g_Settings; + +class CN64System; +extern CN64System * g_System; +extern CN64System * g_BaseSystem; +extern CN64System * g_SyncSystem; + +class CRecompiler; +extern CRecompiler * g_Recompiler; + +class CMipsMemoryVM; +extern CMipsMemoryVM * g_MMU; //Memory of the n64 + +class CTLB; +extern CTLB * g_TLB; //TLB Unit + +class CRegisters; +extern CRegisters * g_Reg; //Current Register Set attached to the g_MMU + +class CPlugins; +extern CPlugins * g_Plugins; + +class CN64Rom; +extern CN64Rom * g_Rom; //The current rom that this system is executing.. it can only execute one file at the time +extern CN64Rom * g_DDRom; //64DD IPL ROM + +class CN64Disk; +extern CN64Disk * g_Disk; //64DD DISK + +class CAudio; +extern CAudio * g_Audio; + +class CSystemTimer; +extern CSystemTimer * g_SystemTimer; + +__interface CTransVaddr; +extern CTransVaddr * g_TransVaddr; + +class CSystemEvents; +extern CSystemEvents * g_SystemEvents; + +extern int32_t * g_NextTimer; +extern uint32_t * g_TLBLoadAddress; +extern uint32_t * g_TLBStoreAddress; + +__interface CDebugger; +extern CDebugger * g_Debugger; diff --git a/Source/Project64-core/Plugin.h b/Source/Project64-core/Plugin.h index c87be00f4..d18d5f508 100644 --- a/Source/Project64-core/Plugin.h +++ b/Source/Project64-core/Plugin.h @@ -1,22 +1,22 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -//Plugin controller -#include "Plugins/PluginClass.h" - -//Base Plugin class, all plugin derive from this, handles core functions -#include "Plugins/PluginBase.h" - -#include "Plugins/GFXPlugin.h" -#include "Plugins/AudioPlugin.h" -#include "Plugins/ControllerPlugin.h" -#include "Plugins/RSPPlugin.h" +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +//Plugin controller +#include "Plugins/PluginClass.h" + +//Base Plugin class, all plugin derive from this, handles core functions +#include "Plugins/PluginBase.h" + +#include "Plugins/GFXPlugin.h" +#include "Plugins/AudioPlugin.h" +#include "Plugins/ControllerPlugin.h" +#include "Plugins/RSPPlugin.h" diff --git a/Source/Project64-core/Plugins/AudioPlugin.cpp b/Source/Project64-core/Plugins/AudioPlugin.cpp index dd8749d56..53483c62f 100644 --- a/Source/Project64-core/Plugins/AudioPlugin.cpp +++ b/Source/Project64-core/Plugins/AudioPlugin.cpp @@ -1,208 +1,208 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include -#include -#include -#ifdef _WIN32 -#include -#endif - -CAudioPlugin::CAudioPlugin() : - AiLenChanged(NULL), - AiReadLength(NULL), - ProcessAList(NULL), - m_hAudioThread(NULL), - AiUpdate(NULL), - AiDacrateChanged(NULL) -{ -} - -CAudioPlugin::~CAudioPlugin() -{ - Close(); - UnloadPlugin(); -} - -bool CAudioPlugin::LoadFunctions(void) -{ - // Find entries for functions in DLL - void(CALL *InitiateAudio)(void); - LoadFunction(InitiateAudio); - LoadFunction(AiDacrateChanged); - LoadFunction(AiLenChanged); - LoadFunction(AiReadLength); - LoadFunction(AiUpdate); - LoadFunction(ProcessAList); - - // Make sure dll has all needed functions - if (AiDacrateChanged == NULL) { UnloadPlugin(); return false; } - if (AiLenChanged == NULL) { UnloadPlugin(); return false; } - if (AiReadLength == NULL) { UnloadPlugin(); return false; } - if (InitiateAudio == NULL) { UnloadPlugin(); return false; } - if (ProcessAList == NULL) { UnloadPlugin(); return false; } - - if (m_PluginInfo.Version >= 0x0102) - { - if (PluginOpened == NULL) { UnloadPlugin(); return false; } - } - return true; -} - -bool CAudioPlugin::Initiate(CN64System * System, RenderWindow * Window) -{ - struct AUDIO_INFO - { - void * hwnd; - void * hinst; - - int32_t MemoryBswaped; // If this is set to TRUE, then the memory has been pre - - // bswap on a dword (32 bits) boundry - // eg. the first 8 bytes are stored like this: - // 4 3 2 1 8 7 6 5 - uint8_t * HEADER; // This is the rom header (first 40h bytes of the rom - // This will be in the same memory format as the rest of the memory. - uint8_t * RDRAM; - uint8_t * DMEM; - uint8_t * IMEM; - - uint32_t * MI__INTR_REG; - - uint32_t * AI__DRAM_ADDR_REG; - uint32_t * AI__LEN_REG; - uint32_t * AI__CONTROL_REG; - uint32_t * AI__STATUS_REG; - uint32_t * AI__DACRATE_REG; - uint32_t * AI__BITRATE_REG; - - void(CALL *CheckInterrupts)(void); - }; - - //Get Function from DLL - int32_t(CALL *InitiateAudio)(AUDIO_INFO Audio_Info); - LoadFunction(InitiateAudio); - if (InitiateAudio == NULL) { return false; } - - AUDIO_INFO Info = { 0 }; - - Info.hwnd = Window ? Window->GetWindowHandle() : NULL; - Info.hinst = Window ? Window->GetModuleInstance() : NULL;; - Info.MemoryBswaped = true; - Info.CheckInterrupts = DummyCheckInterrupts; - - // We are initializing the plugin before any rom is loaded so we do not have any correct - // parameters here.. just needed to we can config the DLL. - if (System == NULL) - { - uint8_t Buffer[100]; - uint32_t Value = 0; - - Info.HEADER = Buffer; - Info.RDRAM = Buffer; - Info.DMEM = Buffer; - Info.IMEM = Buffer; - Info.MI__INTR_REG = &Value; - Info.AI__DRAM_ADDR_REG = &Value; - Info.AI__LEN_REG = &Value; - Info.AI__CONTROL_REG = &Value; - Info.AI__STATUS_REG = &Value; - Info.AI__DACRATE_REG = &Value; - Info.AI__BITRATE_REG = &Value; - } - // Send initialization information to the DLL - else - { - Info.HEADER = g_Rom->GetRomAddress(); - Info.RDRAM = g_MMU->Rdram(); - Info.DMEM = g_MMU->Dmem(); - Info.IMEM = g_MMU->Imem(); - Info.MI__INTR_REG = &g_Reg->m_AudioIntrReg; - Info.AI__DRAM_ADDR_REG = &g_Reg->AI_DRAM_ADDR_REG; - Info.AI__LEN_REG = &g_Reg->AI_LEN_REG; - Info.AI__CONTROL_REG = &g_Reg->AI_CONTROL_REG; - Info.AI__STATUS_REG = &g_Reg->AI_STATUS_REG; - Info.AI__DACRATE_REG = &g_Reg->AI_DACRATE_REG; - Info.AI__BITRATE_REG = &g_Reg->AI_BITRATE_REG; - } - - m_Initialized = InitiateAudio(Info) != 0; - -#ifdef _WIN32 - //jabo had a bug so I call CreateThread so his dllmain gets called again - pjutil::DynLibCallDllMain(); - - if (System != NULL) - { - if (AiUpdate) - { - if (m_hAudioThread) - { - WriteTrace(TraceAudioPlugin, TraceDebug, "Terminate Audio Thread"); - TerminateThread(m_hAudioThread, 0); - } - DWORD ThreadID; - m_hAudioThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AudioThread, (LPVOID)this, 0, &ThreadID); - } - - if (g_Reg->AI_DACRATE_REG != 0) - { - DacrateChanged(System->SystemType()); - } - } -#endif - return m_Initialized; -} - -void CAudioPlugin::UnloadPluginDetails(void) -{ -#ifdef _WIN32 - if (m_hAudioThread) - { - WriteTrace(TraceAudioPlugin, TraceDebug, "Terminate Audio Thread"); - TerminateThread(m_hAudioThread, 0); - m_hAudioThread = NULL; - } -#endif - AiDacrateChanged = NULL; - AiLenChanged = NULL; - AiReadLength = NULL; - AiUpdate = NULL; - ProcessAList = NULL; -} - -void CAudioPlugin::DacrateChanged(SYSTEM_TYPE Type) -{ - if (!Initialized()) { return; } - WriteTrace(TraceAudioPlugin, TraceDebug, "SystemType: %s", Type == SYSTEM_NTSC ? "SYSTEM_NTSC" : "SYSTEM_PAL"); - - //uint32_t Frequency = g_Reg->AI_DACRATE_REG * 30; - //uint32_t CountsPerSecond = (g_Reg->VI_V_SYNC_REG != 0 ? (g_Reg->VI_V_SYNC_REG + 1) * g_Settings->LoadDword(Game_ViRefreshRate) : 500000) * 60; - AiDacrateChanged(Type); -} - -#ifdef _WIN32 -void CAudioPlugin::AudioThread(CAudioPlugin * _this) -{ - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - if (g_Settings->LoadBool(Setting_CN64TimeCritical)) - { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - } - for (;;) - { - _this->AiUpdate(true); - } -} -#endif +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +CAudioPlugin::CAudioPlugin() : + AiLenChanged(NULL), + AiReadLength(NULL), + ProcessAList(NULL), + m_hAudioThread(NULL), + AiUpdate(NULL), + AiDacrateChanged(NULL) +{ +} + +CAudioPlugin::~CAudioPlugin() +{ + Close(); + UnloadPlugin(); +} + +bool CAudioPlugin::LoadFunctions(void) +{ + // Find entries for functions in DLL + void(CALL *InitiateAudio)(void); + LoadFunction(InitiateAudio); + LoadFunction(AiDacrateChanged); + LoadFunction(AiLenChanged); + LoadFunction(AiReadLength); + LoadFunction(AiUpdate); + LoadFunction(ProcessAList); + + // Make sure dll has all needed functions + if (AiDacrateChanged == NULL) { UnloadPlugin(); return false; } + if (AiLenChanged == NULL) { UnloadPlugin(); return false; } + if (AiReadLength == NULL) { UnloadPlugin(); return false; } + if (InitiateAudio == NULL) { UnloadPlugin(); return false; } + if (ProcessAList == NULL) { UnloadPlugin(); return false; } + + if (m_PluginInfo.Version >= 0x0102) + { + if (PluginOpened == NULL) { UnloadPlugin(); return false; } + } + return true; +} + +bool CAudioPlugin::Initiate(CN64System * System, RenderWindow * Window) +{ + struct AUDIO_INFO + { + void * hwnd; + void * hinst; + + int32_t MemoryBswaped; // If this is set to TRUE, then the memory has been pre + + // bswap on a dword (32 bits) boundry + // eg. the first 8 bytes are stored like this: + // 4 3 2 1 8 7 6 5 + uint8_t * HEADER; // This is the rom header (first 40h bytes of the rom + // This will be in the same memory format as the rest of the memory. + uint8_t * RDRAM; + uint8_t * DMEM; + uint8_t * IMEM; + + uint32_t * MI__INTR_REG; + + uint32_t * AI__DRAM_ADDR_REG; + uint32_t * AI__LEN_REG; + uint32_t * AI__CONTROL_REG; + uint32_t * AI__STATUS_REG; + uint32_t * AI__DACRATE_REG; + uint32_t * AI__BITRATE_REG; + + void(CALL *CheckInterrupts)(void); + }; + + //Get Function from DLL + int32_t(CALL *InitiateAudio)(AUDIO_INFO Audio_Info); + LoadFunction(InitiateAudio); + if (InitiateAudio == NULL) { return false; } + + AUDIO_INFO Info = { 0 }; + + Info.hwnd = Window ? Window->GetWindowHandle() : NULL; + Info.hinst = Window ? Window->GetModuleInstance() : NULL;; + Info.MemoryBswaped = true; + Info.CheckInterrupts = DummyCheckInterrupts; + + // We are initializing the plugin before any rom is loaded so we do not have any correct + // parameters here.. just needed to we can config the DLL. + if (System == NULL) + { + uint8_t Buffer[100]; + uint32_t Value = 0; + + Info.HEADER = Buffer; + Info.RDRAM = Buffer; + Info.DMEM = Buffer; + Info.IMEM = Buffer; + Info.MI__INTR_REG = &Value; + Info.AI__DRAM_ADDR_REG = &Value; + Info.AI__LEN_REG = &Value; + Info.AI__CONTROL_REG = &Value; + Info.AI__STATUS_REG = &Value; + Info.AI__DACRATE_REG = &Value; + Info.AI__BITRATE_REG = &Value; + } + // Send initialization information to the DLL + else + { + Info.HEADER = g_Rom->GetRomAddress(); + Info.RDRAM = g_MMU->Rdram(); + Info.DMEM = g_MMU->Dmem(); + Info.IMEM = g_MMU->Imem(); + Info.MI__INTR_REG = &g_Reg->m_AudioIntrReg; + Info.AI__DRAM_ADDR_REG = &g_Reg->AI_DRAM_ADDR_REG; + Info.AI__LEN_REG = &g_Reg->AI_LEN_REG; + Info.AI__CONTROL_REG = &g_Reg->AI_CONTROL_REG; + Info.AI__STATUS_REG = &g_Reg->AI_STATUS_REG; + Info.AI__DACRATE_REG = &g_Reg->AI_DACRATE_REG; + Info.AI__BITRATE_REG = &g_Reg->AI_BITRATE_REG; + } + + m_Initialized = InitiateAudio(Info) != 0; + +#ifdef _WIN32 + //jabo had a bug so I call CreateThread so his dllmain gets called again + pjutil::DynLibCallDllMain(); + + if (System != NULL) + { + if (AiUpdate) + { + if (m_hAudioThread) + { + WriteTrace(TraceAudioPlugin, TraceDebug, "Terminate Audio Thread"); + TerminateThread(m_hAudioThread, 0); + } + DWORD ThreadID; + m_hAudioThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AudioThread, (LPVOID)this, 0, &ThreadID); + } + + if (g_Reg->AI_DACRATE_REG != 0) + { + DacrateChanged(System->SystemType()); + } + } +#endif + return m_Initialized; +} + +void CAudioPlugin::UnloadPluginDetails(void) +{ +#ifdef _WIN32 + if (m_hAudioThread) + { + WriteTrace(TraceAudioPlugin, TraceDebug, "Terminate Audio Thread"); + TerminateThread(m_hAudioThread, 0); + m_hAudioThread = NULL; + } +#endif + AiDacrateChanged = NULL; + AiLenChanged = NULL; + AiReadLength = NULL; + AiUpdate = NULL; + ProcessAList = NULL; +} + +void CAudioPlugin::DacrateChanged(SYSTEM_TYPE Type) +{ + if (!Initialized()) { return; } + WriteTrace(TraceAudioPlugin, TraceDebug, "SystemType: %s", Type == SYSTEM_NTSC ? "SYSTEM_NTSC" : "SYSTEM_PAL"); + + //uint32_t Frequency = g_Reg->AI_DACRATE_REG * 30; + //uint32_t CountsPerSecond = (g_Reg->VI_V_SYNC_REG != 0 ? (g_Reg->VI_V_SYNC_REG + 1) * g_Settings->LoadDword(Game_ViRefreshRate) : 500000) * 60; + AiDacrateChanged(Type); +} + +#ifdef _WIN32 +void CAudioPlugin::AudioThread(CAudioPlugin * _this) +{ + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + if (g_Settings->LoadBool(Setting_CN64TimeCritical)) + { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); + } + for (;;) + { + _this->AiUpdate(true); + } +} +#endif diff --git a/Source/Project64-core/Plugins/AudioPlugin.h b/Source/Project64-core/Plugins/AudioPlugin.h index 97a924bae..b7a93a515 100644 --- a/Source/Project64-core/Plugins/AudioPlugin.h +++ b/Source/Project64-core/Plugins/AudioPlugin.h @@ -1,45 +1,45 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include - -class CAudioPlugin : public CPlugin -{ -public: - CAudioPlugin(void); - ~CAudioPlugin(); - - void DacrateChanged(SYSTEM_TYPE Type); - bool Initiate(CN64System * System, RenderWindow * Window); - - void(CALL *AiLenChanged)(void); - uint32_t(CALL *AiReadLength)(void); - void(CALL *ProcessAList)(void); - -private: - CAudioPlugin(const CAudioPlugin&); // Disable copy constructor - CAudioPlugin& operator=(const CAudioPlugin&); // Disable assignment - - virtual int32_t GetDefaultSettingStartRange() const { return FirstAudioDefaultSet; } - virtual int32_t GetSettingStartRange() const { return FirstAudioSettings; } - PLUGIN_TYPE type() { return PLUGIN_TYPE_AUDIO; } - - void * m_hAudioThread; - - bool LoadFunctions(void); - void UnloadPluginDetails(void); - - void(CALL *AiUpdate) (int32_t Wait); - void(CALL *AiDacrateChanged)(SYSTEM_TYPE Type); - - // Function used in a thread for using audio - static void AudioThread(CAudioPlugin * _this); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +class CAudioPlugin : public CPlugin +{ +public: + CAudioPlugin(void); + ~CAudioPlugin(); + + void DacrateChanged(SYSTEM_TYPE Type); + bool Initiate(CN64System * System, RenderWindow * Window); + + void(CALL *AiLenChanged)(void); + uint32_t(CALL *AiReadLength)(void); + void(CALL *ProcessAList)(void); + +private: + CAudioPlugin(const CAudioPlugin&); // Disable copy constructor + CAudioPlugin& operator=(const CAudioPlugin&); // Disable assignment + + virtual int32_t GetDefaultSettingStartRange() const { return FirstAudioDefaultSet; } + virtual int32_t GetSettingStartRange() const { return FirstAudioSettings; } + PLUGIN_TYPE type() { return PLUGIN_TYPE_AUDIO; } + + void * m_hAudioThread; + + bool LoadFunctions(void); + void UnloadPluginDetails(void); + + void(CALL *AiUpdate) (int32_t Wait); + void(CALL *AiDacrateChanged)(SYSTEM_TYPE Type); + + // Function used in a thread for using audio + static void AudioThread(CAudioPlugin * _this); +}; diff --git a/Source/Project64-core/Plugins/ControllerPlugin.cpp b/Source/Project64-core/Plugins/ControllerPlugin.cpp index 5a6854455..0cbc226e1 100644 --- a/Source/Project64-core/Plugins/ControllerPlugin.cpp +++ b/Source/Project64-core/Plugins/ControllerPlugin.cpp @@ -1,183 +1,183 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include "ControllerPlugin.h" - -CControl_Plugin::CControl_Plugin(void) : - WM_KeyDown(NULL), - WM_KeyUp(NULL), - RumbleCommand(NULL), - GetKeys(NULL), - ReadController(NULL), - ControllerCommand(NULL), - m_AllocatedControllers(false) -{ - memset(&m_PluginControllers, 0, sizeof(m_PluginControllers)); - memset(&m_Controllers, 0, sizeof(m_Controllers)); -} - -CControl_Plugin::~CControl_Plugin() -{ - Close(); - UnloadPlugin(); -} - -bool CControl_Plugin::LoadFunctions(void) -{ - // Find entries for functions in DLL - void(CALL *InitiateControllers)(void); - LoadFunction(InitiateControllers); - LoadFunction(ControllerCommand); - LoadFunction(GetKeys); - LoadFunction(ReadController); - LoadFunction(WM_KeyDown); - LoadFunction(WM_KeyUp); - LoadFunction(RumbleCommand); - - //Make sure dll had all needed functions - if (InitiateControllers == NULL) { UnloadPlugin(); return false; } - - if (m_PluginInfo.Version >= 0x0102) - { - if (PluginOpened == NULL) { UnloadPlugin(); return false; } - } - - // Allocate our own controller - m_AllocatedControllers = true; - for (int32_t i = 0; i < 4; i++) - { - m_Controllers[i] = new CCONTROL(m_PluginControllers[i].Present, m_PluginControllers[i].RawData, m_PluginControllers[i].Plugin); - } - return true; -} - -bool CControl_Plugin::Initiate(CN64System * System, RenderWindow * Window) -{ - uint8_t Buffer[100]; - - for (int32_t i = 0; i < 4; i++) - { - m_PluginControllers[i].Present = false; - m_PluginControllers[i].RawData = false; - m_PluginControllers[i].Plugin = PLUGIN_NONE; - } - - // Test Plugin version - if (m_PluginInfo.Version == 0x0100) - { - //Get Function from DLL - void(CALL *InitiateControllers_1_0)(void * hMainWindow, CONTROL Controls[4]); - _LoadFunction("InitiateControllers",InitiateControllers_1_0); - if (InitiateControllers_1_0 == NULL) { return false; } - InitiateControllers_1_0(Window->GetWindowHandle(), m_PluginControllers); - m_Initialized = true; - } - else if (m_PluginInfo.Version >= 0x0101) - { - CONTROL_INFO ControlInfo; - ControlInfo.Controls = m_PluginControllers; - ControlInfo.HEADER = (System == NULL ? Buffer : g_Rom->GetRomAddress()); - ControlInfo.hinst = Window ? Window->GetModuleInstance() : NULL; - ControlInfo.hMainWindow = Window ? Window->GetWindowHandle() : NULL; - ControlInfo.MemoryBswaped = true; - - if (m_PluginInfo.Version == 0x0101) - { - //Get Function from DLL - void(CALL *InitiateControllers_1_1)(CONTROL_INFO ControlInfo); - _LoadFunction("InitiateControllers",InitiateControllers_1_1); - if (InitiateControllers_1_1 == NULL) { return false; } - - InitiateControllers_1_1(ControlInfo); - m_Initialized = true; - } - else if (m_PluginInfo.Version >= 0x0102) - { - //Get Function from DLL - void(CALL *InitiateControllers_1_2)(CONTROL_INFO * ControlInfo); - _LoadFunction("InitiateControllers",InitiateControllers_1_2); - if (InitiateControllers_1_2 == NULL) { return false; } - - InitiateControllers_1_2(&ControlInfo); - m_Initialized = true; - } - } - -#ifdef _WIN32 - //jabo had a bug so I call CreateThread so his dllmain gets called again - pjutil::DynLibCallDllMain(); -#endif - - return m_Initialized; -} - -void CControl_Plugin::UnloadPluginDetails(void) -{ - if (m_AllocatedControllers) - { - for (int32_t count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) - { - delete m_Controllers[count]; - m_Controllers[count] = NULL; - } - } - - m_AllocatedControllers = false; - ControllerCommand = NULL; - GetKeys = NULL; - ReadController = NULL; - WM_KeyDown = NULL; - WM_KeyUp = NULL; -} - -void CControl_Plugin::UpdateKeys(void) -{ - if (!m_AllocatedControllers) { return; } - for (int32_t cont = 0; cont < sizeof(m_Controllers) / sizeof(m_Controllers[0]); cont++) - { - if (!m_Controllers[cont]->m_Present) { continue; } - if (!m_Controllers[cont]->m_RawData) - { - GetKeys(cont, &m_Controllers[cont]->m_Buttons); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - if (ReadController) { ReadController(-1, NULL); } -} - -void CControl_Plugin::SetControl(CControl_Plugin const * const Plugin) -{ - if (m_AllocatedControllers) - { - for (int32_t count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) - { - delete m_Controllers[count]; - m_Controllers[count] = NULL; - } - } - m_AllocatedControllers = false; - for (int32_t count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) - { - m_Controllers[count] = Plugin->m_Controllers[count]; - } -} - -CCONTROL::CCONTROL(int32_t &Present, int32_t &RawData, int32_t &PlugType) : - m_Present(Present), m_RawData(RawData), m_PlugType(PlugType) -{ - m_Buttons.Value = 0; -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include "ControllerPlugin.h" + +CControl_Plugin::CControl_Plugin(void) : + WM_KeyDown(NULL), + WM_KeyUp(NULL), + RumbleCommand(NULL), + GetKeys(NULL), + ReadController(NULL), + ControllerCommand(NULL), + m_AllocatedControllers(false) +{ + memset(&m_PluginControllers, 0, sizeof(m_PluginControllers)); + memset(&m_Controllers, 0, sizeof(m_Controllers)); +} + +CControl_Plugin::~CControl_Plugin() +{ + Close(); + UnloadPlugin(); +} + +bool CControl_Plugin::LoadFunctions(void) +{ + // Find entries for functions in DLL + void(CALL *InitiateControllers)(void); + LoadFunction(InitiateControllers); + LoadFunction(ControllerCommand); + LoadFunction(GetKeys); + LoadFunction(ReadController); + LoadFunction(WM_KeyDown); + LoadFunction(WM_KeyUp); + LoadFunction(RumbleCommand); + + //Make sure dll had all needed functions + if (InitiateControllers == NULL) { UnloadPlugin(); return false; } + + if (m_PluginInfo.Version >= 0x0102) + { + if (PluginOpened == NULL) { UnloadPlugin(); return false; } + } + + // Allocate our own controller + m_AllocatedControllers = true; + for (int32_t i = 0; i < 4; i++) + { + m_Controllers[i] = new CCONTROL(m_PluginControllers[i].Present, m_PluginControllers[i].RawData, m_PluginControllers[i].Plugin); + } + return true; +} + +bool CControl_Plugin::Initiate(CN64System * System, RenderWindow * Window) +{ + uint8_t Buffer[100]; + + for (int32_t i = 0; i < 4; i++) + { + m_PluginControllers[i].Present = false; + m_PluginControllers[i].RawData = false; + m_PluginControllers[i].Plugin = PLUGIN_NONE; + } + + // Test Plugin version + if (m_PluginInfo.Version == 0x0100) + { + //Get Function from DLL + void(CALL *InitiateControllers_1_0)(void * hMainWindow, CONTROL Controls[4]); + _LoadFunction("InitiateControllers",InitiateControllers_1_0); + if (InitiateControllers_1_0 == NULL) { return false; } + InitiateControllers_1_0(Window->GetWindowHandle(), m_PluginControllers); + m_Initialized = true; + } + else if (m_PluginInfo.Version >= 0x0101) + { + CONTROL_INFO ControlInfo; + ControlInfo.Controls = m_PluginControllers; + ControlInfo.HEADER = (System == NULL ? Buffer : g_Rom->GetRomAddress()); + ControlInfo.hinst = Window ? Window->GetModuleInstance() : NULL; + ControlInfo.hMainWindow = Window ? Window->GetWindowHandle() : NULL; + ControlInfo.MemoryBswaped = true; + + if (m_PluginInfo.Version == 0x0101) + { + //Get Function from DLL + void(CALL *InitiateControllers_1_1)(CONTROL_INFO ControlInfo); + _LoadFunction("InitiateControllers",InitiateControllers_1_1); + if (InitiateControllers_1_1 == NULL) { return false; } + + InitiateControllers_1_1(ControlInfo); + m_Initialized = true; + } + else if (m_PluginInfo.Version >= 0x0102) + { + //Get Function from DLL + void(CALL *InitiateControllers_1_2)(CONTROL_INFO * ControlInfo); + _LoadFunction("InitiateControllers",InitiateControllers_1_2); + if (InitiateControllers_1_2 == NULL) { return false; } + + InitiateControllers_1_2(&ControlInfo); + m_Initialized = true; + } + } + +#ifdef _WIN32 + //jabo had a bug so I call CreateThread so his dllmain gets called again + pjutil::DynLibCallDllMain(); +#endif + + return m_Initialized; +} + +void CControl_Plugin::UnloadPluginDetails(void) +{ + if (m_AllocatedControllers) + { + for (int32_t count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) + { + delete m_Controllers[count]; + m_Controllers[count] = NULL; + } + } + + m_AllocatedControllers = false; + ControllerCommand = NULL; + GetKeys = NULL; + ReadController = NULL; + WM_KeyDown = NULL; + WM_KeyUp = NULL; +} + +void CControl_Plugin::UpdateKeys(void) +{ + if (!m_AllocatedControllers) { return; } + for (int32_t cont = 0; cont < sizeof(m_Controllers) / sizeof(m_Controllers[0]); cont++) + { + if (!m_Controllers[cont]->m_Present) { continue; } + if (!m_Controllers[cont]->m_RawData) + { + GetKeys(cont, &m_Controllers[cont]->m_Buttons); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + if (ReadController) { ReadController(-1, NULL); } +} + +void CControl_Plugin::SetControl(CControl_Plugin const * const Plugin) +{ + if (m_AllocatedControllers) + { + for (int32_t count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) + { + delete m_Controllers[count]; + m_Controllers[count] = NULL; + } + } + m_AllocatedControllers = false; + for (int32_t count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) + { + m_Controllers[count] = Plugin->m_Controllers[count]; + } +} + +CCONTROL::CCONTROL(int32_t &Present, int32_t &RawData, int32_t &PlugType) : + m_Present(Present), m_RawData(RawData), m_PlugType(PlugType) +{ + m_Buttons.Value = 0; +} diff --git a/Source/Project64-core/Plugins/ControllerPlugin.h b/Source/Project64-core/Plugins/ControllerPlugin.h index 6923174f5..1f19108a7 100644 --- a/Source/Project64-core/Plugins/ControllerPlugin.h +++ b/Source/Project64-core/Plugins/ControllerPlugin.h @@ -1,130 +1,130 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include - -#pragma warning(push) -#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union - -typedef union -{ - uint32_t Value; - struct - { - unsigned R_DPAD : 1; - unsigned L_DPAD : 1; - unsigned D_DPAD : 1; - unsigned U_DPAD : 1; - unsigned START_BUTTON : 1; - unsigned Z_TRIG : 1; - unsigned B_BUTTON : 1; - unsigned A_BUTTON : 1; - - unsigned R_CBUTTON : 1; - unsigned L_CBUTTON : 1; - unsigned D_CBUTTON : 1; - unsigned U_CBUTTON : 1; - unsigned R_TRIG : 1; - unsigned L_TRIG : 1; - unsigned Reserved1 : 1; - unsigned Reserved2 : 1; - - signed Y_AXIS : 8; - - signed X_AXIS : 8; - }; -} BUTTONS; -#pragma warning(pop) - -typedef struct -{ - int32_t Present; - int32_t RawData; - int32_t Plugin; -} CONTROL; - -typedef struct -{ - void * hMainWindow; - void * hinst; - - int32_t MemoryBswaped; // memory in client- or server-native endian - uint8_t * HEADER; // the ROM header (first 40h bytes of the ROM) - CONTROL * Controls; // pointer to array of 4 controllers, i.e.: CONTROL Controls[4]; -} CONTROL_INFO; - -enum PluginType -{ - PLUGIN_NONE = 1, - PLUGIN_MEMPAK = 2, - PLUGIN_RUMBLE_PAK = 3, - PLUGIN_TANSFER_PAK = 4, // not implemeted for non raw data - PLUGIN_RAW = 5, // the controller plugin is passed in raw data -}; - -class CControl_Plugin; - -class CCONTROL -{ -public: - CCONTROL(int32_t &Present, int32_t &RawData, int32_t &PlugType); - inline bool Present(void) const { return m_Present != 0; } - inline uint32_t Buttons(void) const { return m_Buttons.Value; } - inline PluginType Plugin(void) const { return static_cast(m_PlugType); } -private: - friend CControl_Plugin; //controller plugin class has full access - - int32_t & m_Present; - int32_t & m_RawData; - int32_t & m_PlugType; - BUTTONS m_Buttons; - - CCONTROL(void); // Disable default constructor - CCONTROL(const CCONTROL&); // Disable copy constructor - CCONTROL& operator=(const CCONTROL&); // Disable assignment -}; - -class CControl_Plugin : public CPlugin -{ -public: - CControl_Plugin(void); - ~CControl_Plugin(); - - bool Initiate(CN64System * System, RenderWindow * Window); - void SetControl(CControl_Plugin const * const Plugin); - void UpdateKeys(void); - - void(CALL *WM_KeyDown) (uint32_t wParam, uint32_t lParam); - void(CALL *WM_KeyUp) (uint32_t wParam, uint32_t lParam); - void(CALL *RumbleCommand) (int32_t Control, int32_t bRumble); - void(CALL *GetKeys) (int32_t Control, BUTTONS * Keys); - void(CALL *ReadController) (int32_t Control, uint8_t * Command); - void(CALL *ControllerCommand) (int32_t Control, uint8_t * Command); - - inline CCONTROL const * Controller(int32_t control) { return m_Controllers[control]; } - inline CONTROL * PluginControllers(void) { return m_PluginControllers; } - -private: - CControl_Plugin(const CControl_Plugin&); // Disable copy constructor - CControl_Plugin& operator=(const CControl_Plugin&); // Disable assignment - - virtual int32_t GetDefaultSettingStartRange() const { return FirstCtrlDefaultSet; } - virtual int32_t GetSettingStartRange() const { return FirstCtrlSettings; } - PLUGIN_TYPE type() { return PLUGIN_TYPE_CONTROLLER; } - bool LoadFunctions(void); - void UnloadPluginDetails(void); - - bool m_AllocatedControllers; - - // What the different controls are set up as - CONTROL m_PluginControllers[4]; - CCONTROL * m_Controllers[4]; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +#pragma warning(push) +#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union + +typedef union +{ + uint32_t Value; + struct + { + unsigned R_DPAD : 1; + unsigned L_DPAD : 1; + unsigned D_DPAD : 1; + unsigned U_DPAD : 1; + unsigned START_BUTTON : 1; + unsigned Z_TRIG : 1; + unsigned B_BUTTON : 1; + unsigned A_BUTTON : 1; + + unsigned R_CBUTTON : 1; + unsigned L_CBUTTON : 1; + unsigned D_CBUTTON : 1; + unsigned U_CBUTTON : 1; + unsigned R_TRIG : 1; + unsigned L_TRIG : 1; + unsigned Reserved1 : 1; + unsigned Reserved2 : 1; + + signed Y_AXIS : 8; + + signed X_AXIS : 8; + }; +} BUTTONS; +#pragma warning(pop) + +typedef struct +{ + int32_t Present; + int32_t RawData; + int32_t Plugin; +} CONTROL; + +typedef struct +{ + void * hMainWindow; + void * hinst; + + int32_t MemoryBswaped; // memory in client- or server-native endian + uint8_t * HEADER; // the ROM header (first 40h bytes of the ROM) + CONTROL * Controls; // pointer to array of 4 controllers, i.e.: CONTROL Controls[4]; +} CONTROL_INFO; + +enum PluginType +{ + PLUGIN_NONE = 1, + PLUGIN_MEMPAK = 2, + PLUGIN_RUMBLE_PAK = 3, + PLUGIN_TANSFER_PAK = 4, // not implemeted for non raw data + PLUGIN_RAW = 5, // the controller plugin is passed in raw data +}; + +class CControl_Plugin; + +class CCONTROL +{ +public: + CCONTROL(int32_t &Present, int32_t &RawData, int32_t &PlugType); + inline bool Present(void) const { return m_Present != 0; } + inline uint32_t Buttons(void) const { return m_Buttons.Value; } + inline PluginType Plugin(void) const { return static_cast(m_PlugType); } +private: + friend CControl_Plugin; //controller plugin class has full access + + int32_t & m_Present; + int32_t & m_RawData; + int32_t & m_PlugType; + BUTTONS m_Buttons; + + CCONTROL(void); // Disable default constructor + CCONTROL(const CCONTROL&); // Disable copy constructor + CCONTROL& operator=(const CCONTROL&); // Disable assignment +}; + +class CControl_Plugin : public CPlugin +{ +public: + CControl_Plugin(void); + ~CControl_Plugin(); + + bool Initiate(CN64System * System, RenderWindow * Window); + void SetControl(CControl_Plugin const * const Plugin); + void UpdateKeys(void); + + void(CALL *WM_KeyDown) (uint32_t wParam, uint32_t lParam); + void(CALL *WM_KeyUp) (uint32_t wParam, uint32_t lParam); + void(CALL *RumbleCommand) (int32_t Control, int32_t bRumble); + void(CALL *GetKeys) (int32_t Control, BUTTONS * Keys); + void(CALL *ReadController) (int32_t Control, uint8_t * Command); + void(CALL *ControllerCommand) (int32_t Control, uint8_t * Command); + + inline CCONTROL const * Controller(int32_t control) { return m_Controllers[control]; } + inline CONTROL * PluginControllers(void) { return m_PluginControllers; } + +private: + CControl_Plugin(const CControl_Plugin&); // Disable copy constructor + CControl_Plugin& operator=(const CControl_Plugin&); // Disable assignment + + virtual int32_t GetDefaultSettingStartRange() const { return FirstCtrlDefaultSet; } + virtual int32_t GetSettingStartRange() const { return FirstCtrlSettings; } + PLUGIN_TYPE type() { return PLUGIN_TYPE_CONTROLLER; } + bool LoadFunctions(void); + void UnloadPluginDetails(void); + + bool m_AllocatedControllers; + + // What the different controls are set up as + CONTROL m_PluginControllers[4]; + CCONTROL * m_Controllers[4]; +}; diff --git a/Source/Project64-core/Plugins/GFXPlugin.cpp b/Source/Project64-core/Plugins/GFXPlugin.cpp index 7170922b8..7499785da 100644 --- a/Source/Project64-core/Plugins/GFXPlugin.cpp +++ b/Source/Project64-core/Plugins/GFXPlugin.cpp @@ -1,269 +1,269 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include -#include "GFXPlugin.h" - -CGfxPlugin::CGfxPlugin() : - CaptureScreen(NULL), - ChangeWindow(NULL), - DrawScreen(NULL), - DrawStatus(NULL), - MoveScreen(NULL), - ProcessDList(NULL), - ProcessRDPList(NULL), - ShowCFB(NULL), - UpdateScreen(NULL), - ViStatusChanged(NULL), - ViWidthChanged(NULL), - SoftReset(NULL), - GetRomBrowserMenu(NULL), - OnRomBrowserMenuItem(NULL), - GetDebugInfo(NULL), - InitiateDebugger(NULL) -{ - memset(&m_GFXDebug, 0, sizeof(m_GFXDebug)); -} - -CGfxPlugin::~CGfxPlugin() -{ - Close(); - UnloadPlugin(); -} - -bool CGfxPlugin::LoadFunctions(void) -{ - // Find entries for functions in DLL - int32_t(CALL *InitiateGFX) (void * Gfx_Info); - LoadFunction(InitiateGFX); - LoadFunction(ChangeWindow); - LoadFunction(DrawScreen); - LoadFunction(MoveScreen); - LoadFunction(ProcessDList); - LoadFunction(UpdateScreen); - LoadFunction(ViStatusChanged); - LoadFunction(ViWidthChanged); - LoadFunction(SoftReset); - - // version 0x104 functions - _LoadFunction("DrawFullScreenStatus", DrawStatus); - - // Rom Browser - LoadFunction(GetRomBrowserMenu); - LoadFunction(OnRomBrowserMenuItem); - - //Make sure dll had all needed functions - if (ChangeWindow == NULL) { UnloadPlugin(); return false; } - if (DrawScreen == NULL) { DrawScreen = DummyDrawScreen; } - if (InitiateGFX == NULL) { UnloadPlugin(); return false; } - if (MoveScreen == NULL) { MoveScreen = DummyMoveScreen; } - if (ProcessDList == NULL) { UnloadPlugin(); return false; } - if (UpdateScreen == NULL) { UnloadPlugin(); return false; } - if (ViStatusChanged == NULL) { ViStatusChanged = DummyViStatusChanged; } - if (ViWidthChanged == NULL) { ViWidthChanged = DummyViWidthChanged; } - if (SoftReset == NULL) { SoftReset = DummySoftReset; } - - if (m_PluginInfo.Version >= 0x0103) - { - LoadFunction(ProcessRDPList); - LoadFunction(CaptureScreen); - LoadFunction(ShowCFB); - LoadFunction(GetDebugInfo); - _LoadFunction("InitiateGFXDebugger", InitiateDebugger); - - if (ProcessRDPList == NULL) { UnloadPlugin(); return false; } - if (CaptureScreen == NULL) { UnloadPlugin(); return false; } - if (ShowCFB == NULL) { UnloadPlugin(); return false; } - } - - if (m_PluginInfo.Version >= 0x0104) - { - if (PluginOpened == NULL) { UnloadPlugin(); return false; } - } - - if (GetDebugInfo != NULL) - { - GetDebugInfo(&m_GFXDebug); - } - return true; -} - -bool CGfxPlugin::Initiate(CN64System * System, RenderWindow * Window) -{ - if (m_Initialized) - { - Close(); - } - - typedef struct - { - void * hWnd; /* Render window */ - void * hStatusBar; /* if render window does not have a status bar then this is NULL */ - - int32_t MemoryBswaped; // If this is set to TRUE, then the memory has been pre - // bswap on a dword (32 bits) boundry - // eg. the first 8 bytes are stored like this: - // 4 3 2 1 8 7 6 5 - - uint8_t * HEADER; // This is the rom header (first 40h bytes of the rom - // This will be in the same memory format as the rest of the memory. - uint8_t * RDRAM; - uint8_t * DMEM; - uint8_t * IMEM; - - uint32_t * MI__INTR_REG; - - uint32_t * DPC__START_REG; - uint32_t * DPC__END_REG; - uint32_t * DPC__CURRENT_REG; - uint32_t * DPC__STATUS_REG; - uint32_t * DPC__CLOCK_REG; - uint32_t * DPC__BUFBUSY_REG; - uint32_t * DPC__PIPEBUSY_REG; - uint32_t * DPC__TMEM_REG; - - uint32_t * VI__STATUS_REG; - uint32_t * VI__ORIGIN_REG; - uint32_t * VI__WIDTH_REG; - uint32_t * VI__INTR_REG; - uint32_t * VI__V_CURRENT_LINE_REG; - uint32_t * VI__TIMING_REG; - uint32_t * VI__V_SYNC_REG; - uint32_t * VI__H_SYNC_REG; - uint32_t * VI__LEAP_REG; - uint32_t * VI__H_START_REG; - uint32_t * VI__V_START_REG; - uint32_t * VI__V_BURST_REG; - uint32_t * VI__X_SCALE_REG; - uint32_t * VI__Y_SCALE_REG; - - void(CALL *CheckInterrupts)(void); - } GFX_INFO; - - //Get Function from DLL - int32_t(CALL *InitiateGFX)(GFX_INFO Gfx_Info); - _LoadFunction("InitiateGFX",InitiateGFX); - if (InitiateGFX == NULL) { return false; } - - GFX_INFO Info = { 0 }; - - Info.MemoryBswaped = true; - Info.hWnd = Window->GetWindowHandle(); - Info.hStatusBar = Window->GetStatusBar(); - Info.CheckInterrupts = DummyCheckInterrupts; - - // We are initializing the plugin before any rom is loaded so we do not have any correct - // parameters here.. it's just needed so we can config the DLL. - if (System == NULL) - { - uint8_t Buffer[100]; - uint32_t Value = 0; - - Info.HEADER = Buffer; - Info.RDRAM = Buffer; - Info.DMEM = Buffer; - Info.IMEM = Buffer; - Info.MI__INTR_REG = &Value; - Info.VI__STATUS_REG = &Value; - Info.VI__ORIGIN_REG = &Value; - Info.VI__WIDTH_REG = &Value; - Info.VI__INTR_REG = &Value; - Info.VI__V_CURRENT_LINE_REG = &Value; - Info.VI__TIMING_REG = &Value; - Info.VI__V_SYNC_REG = &Value; - Info.VI__H_SYNC_REG = &Value; - Info.VI__LEAP_REG = &Value; - Info.VI__H_START_REG = &Value; - Info.VI__V_START_REG = &Value; - Info.VI__V_BURST_REG = &Value; - Info.VI__X_SCALE_REG = &Value; - Info.VI__Y_SCALE_REG = &Value; - } - // Send initialization information to the DLL - else - { - Info.HEADER = g_Rom->GetRomAddress(); - Info.RDRAM = g_MMU->Rdram(); - Info.DMEM = g_MMU->Dmem(); - Info.IMEM = g_MMU->Imem(); - Info.MI__INTR_REG = &g_Reg->m_GfxIntrReg; - Info.DPC__START_REG = &g_Reg->DPC_START_REG; - Info.DPC__END_REG = &g_Reg->DPC_END_REG; - Info.DPC__CURRENT_REG = &g_Reg->DPC_CURRENT_REG; - Info.DPC__STATUS_REG = &g_Reg->DPC_STATUS_REG; - Info.DPC__CLOCK_REG = &g_Reg->DPC_CLOCK_REG; - Info.DPC__BUFBUSY_REG = &g_Reg->DPC_BUFBUSY_REG; - Info.DPC__PIPEBUSY_REG = &g_Reg->DPC_PIPEBUSY_REG; - Info.DPC__TMEM_REG = &g_Reg->DPC_TMEM_REG; - Info.VI__STATUS_REG = &g_Reg->VI_STATUS_REG; - Info.VI__ORIGIN_REG = &g_Reg->VI_ORIGIN_REG; - Info.VI__WIDTH_REG = &g_Reg->VI_WIDTH_REG; - Info.VI__INTR_REG = &g_Reg->VI_INTR_REG; - Info.VI__V_CURRENT_LINE_REG = &g_Reg->VI_CURRENT_REG; - Info.VI__TIMING_REG = &g_Reg->VI_TIMING_REG; - Info.VI__V_SYNC_REG = &g_Reg->VI_V_SYNC_REG; - Info.VI__H_SYNC_REG = &g_Reg->VI_H_SYNC_REG; - Info.VI__LEAP_REG = &g_Reg->VI_LEAP_REG; - Info.VI__H_START_REG = &g_Reg->VI_H_START_REG; - Info.VI__V_START_REG = &g_Reg->VI_V_START_REG; - Info.VI__V_BURST_REG = &g_Reg->VI_V_BURST_REG; - Info.VI__X_SCALE_REG = &g_Reg->VI_X_SCALE_REG; - Info.VI__Y_SCALE_REG = &g_Reg->VI_Y_SCALE_REG; - } - - m_Initialized = InitiateGFX(Info) != 0; - -#ifdef _WIN32 - //jabo had a bug so I call CreateThread so his dllmain gets called again - pjutil::DynLibCallDllMain(); -#endif - - return m_Initialized; -} - -void CGfxPlugin::UnloadPluginDetails(void) -{ - if (m_LibHandle != NULL) - { - pjutil::DynLibClose(m_LibHandle); - m_LibHandle = NULL; - } - memset(&m_GFXDebug, 0, sizeof(m_GFXDebug)); - - // CaptureScreen = NULL; - ChangeWindow = NULL; - GetDebugInfo = NULL; - DrawScreen = NULL; - DrawStatus = NULL; - // FrameBufferRead = NULL; - // FrameBufferWrite = NULL; - InitiateDebugger = NULL; - MoveScreen = NULL; - ProcessDList = NULL; - ProcessRDPList = NULL; - ShowCFB = NULL; - UpdateScreen = NULL; - ViStatusChanged = NULL; - ViWidthChanged = NULL; - GetRomBrowserMenu = NULL; - OnRomBrowserMenuItem = NULL; -} - -void CGfxPlugin::ProcessMenuItem(int32_t id) -{ - if (m_GFXDebug.ProcessMenuItem) - { - m_GFXDebug.ProcessMenuItem(id); - } +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include +#include "GFXPlugin.h" + +CGfxPlugin::CGfxPlugin() : + CaptureScreen(NULL), + ChangeWindow(NULL), + DrawScreen(NULL), + DrawStatus(NULL), + MoveScreen(NULL), + ProcessDList(NULL), + ProcessRDPList(NULL), + ShowCFB(NULL), + UpdateScreen(NULL), + ViStatusChanged(NULL), + ViWidthChanged(NULL), + SoftReset(NULL), + GetRomBrowserMenu(NULL), + OnRomBrowserMenuItem(NULL), + GetDebugInfo(NULL), + InitiateDebugger(NULL) +{ + memset(&m_GFXDebug, 0, sizeof(m_GFXDebug)); +} + +CGfxPlugin::~CGfxPlugin() +{ + Close(); + UnloadPlugin(); +} + +bool CGfxPlugin::LoadFunctions(void) +{ + // Find entries for functions in DLL + int32_t(CALL *InitiateGFX) (void * Gfx_Info); + LoadFunction(InitiateGFX); + LoadFunction(ChangeWindow); + LoadFunction(DrawScreen); + LoadFunction(MoveScreen); + LoadFunction(ProcessDList); + LoadFunction(UpdateScreen); + LoadFunction(ViStatusChanged); + LoadFunction(ViWidthChanged); + LoadFunction(SoftReset); + + // version 0x104 functions + _LoadFunction("DrawFullScreenStatus", DrawStatus); + + // Rom Browser + LoadFunction(GetRomBrowserMenu); + LoadFunction(OnRomBrowserMenuItem); + + //Make sure dll had all needed functions + if (ChangeWindow == NULL) { UnloadPlugin(); return false; } + if (DrawScreen == NULL) { DrawScreen = DummyDrawScreen; } + if (InitiateGFX == NULL) { UnloadPlugin(); return false; } + if (MoveScreen == NULL) { MoveScreen = DummyMoveScreen; } + if (ProcessDList == NULL) { UnloadPlugin(); return false; } + if (UpdateScreen == NULL) { UnloadPlugin(); return false; } + if (ViStatusChanged == NULL) { ViStatusChanged = DummyViStatusChanged; } + if (ViWidthChanged == NULL) { ViWidthChanged = DummyViWidthChanged; } + if (SoftReset == NULL) { SoftReset = DummySoftReset; } + + if (m_PluginInfo.Version >= 0x0103) + { + LoadFunction(ProcessRDPList); + LoadFunction(CaptureScreen); + LoadFunction(ShowCFB); + LoadFunction(GetDebugInfo); + _LoadFunction("InitiateGFXDebugger", InitiateDebugger); + + if (ProcessRDPList == NULL) { UnloadPlugin(); return false; } + if (CaptureScreen == NULL) { UnloadPlugin(); return false; } + if (ShowCFB == NULL) { UnloadPlugin(); return false; } + } + + if (m_PluginInfo.Version >= 0x0104) + { + if (PluginOpened == NULL) { UnloadPlugin(); return false; } + } + + if (GetDebugInfo != NULL) + { + GetDebugInfo(&m_GFXDebug); + } + return true; +} + +bool CGfxPlugin::Initiate(CN64System * System, RenderWindow * Window) +{ + if (m_Initialized) + { + Close(); + } + + typedef struct + { + void * hWnd; /* Render window */ + void * hStatusBar; /* if render window does not have a status bar then this is NULL */ + + int32_t MemoryBswaped; // If this is set to TRUE, then the memory has been pre + // bswap on a dword (32 bits) boundry + // eg. the first 8 bytes are stored like this: + // 4 3 2 1 8 7 6 5 + + uint8_t * HEADER; // This is the rom header (first 40h bytes of the rom + // This will be in the same memory format as the rest of the memory. + uint8_t * RDRAM; + uint8_t * DMEM; + uint8_t * IMEM; + + uint32_t * MI__INTR_REG; + + uint32_t * DPC__START_REG; + uint32_t * DPC__END_REG; + uint32_t * DPC__CURRENT_REG; + uint32_t * DPC__STATUS_REG; + uint32_t * DPC__CLOCK_REG; + uint32_t * DPC__BUFBUSY_REG; + uint32_t * DPC__PIPEBUSY_REG; + uint32_t * DPC__TMEM_REG; + + uint32_t * VI__STATUS_REG; + uint32_t * VI__ORIGIN_REG; + uint32_t * VI__WIDTH_REG; + uint32_t * VI__INTR_REG; + uint32_t * VI__V_CURRENT_LINE_REG; + uint32_t * VI__TIMING_REG; + uint32_t * VI__V_SYNC_REG; + uint32_t * VI__H_SYNC_REG; + uint32_t * VI__LEAP_REG; + uint32_t * VI__H_START_REG; + uint32_t * VI__V_START_REG; + uint32_t * VI__V_BURST_REG; + uint32_t * VI__X_SCALE_REG; + uint32_t * VI__Y_SCALE_REG; + + void(CALL *CheckInterrupts)(void); + } GFX_INFO; + + //Get Function from DLL + int32_t(CALL *InitiateGFX)(GFX_INFO Gfx_Info); + _LoadFunction("InitiateGFX",InitiateGFX); + if (InitiateGFX == NULL) { return false; } + + GFX_INFO Info = { 0 }; + + Info.MemoryBswaped = true; + Info.hWnd = Window->GetWindowHandle(); + Info.hStatusBar = Window->GetStatusBar(); + Info.CheckInterrupts = DummyCheckInterrupts; + + // We are initializing the plugin before any rom is loaded so we do not have any correct + // parameters here.. it's just needed so we can config the DLL. + if (System == NULL) + { + uint8_t Buffer[100]; + uint32_t Value = 0; + + Info.HEADER = Buffer; + Info.RDRAM = Buffer; + Info.DMEM = Buffer; + Info.IMEM = Buffer; + Info.MI__INTR_REG = &Value; + Info.VI__STATUS_REG = &Value; + Info.VI__ORIGIN_REG = &Value; + Info.VI__WIDTH_REG = &Value; + Info.VI__INTR_REG = &Value; + Info.VI__V_CURRENT_LINE_REG = &Value; + Info.VI__TIMING_REG = &Value; + Info.VI__V_SYNC_REG = &Value; + Info.VI__H_SYNC_REG = &Value; + Info.VI__LEAP_REG = &Value; + Info.VI__H_START_REG = &Value; + Info.VI__V_START_REG = &Value; + Info.VI__V_BURST_REG = &Value; + Info.VI__X_SCALE_REG = &Value; + Info.VI__Y_SCALE_REG = &Value; + } + // Send initialization information to the DLL + else + { + Info.HEADER = g_Rom->GetRomAddress(); + Info.RDRAM = g_MMU->Rdram(); + Info.DMEM = g_MMU->Dmem(); + Info.IMEM = g_MMU->Imem(); + Info.MI__INTR_REG = &g_Reg->m_GfxIntrReg; + Info.DPC__START_REG = &g_Reg->DPC_START_REG; + Info.DPC__END_REG = &g_Reg->DPC_END_REG; + Info.DPC__CURRENT_REG = &g_Reg->DPC_CURRENT_REG; + Info.DPC__STATUS_REG = &g_Reg->DPC_STATUS_REG; + Info.DPC__CLOCK_REG = &g_Reg->DPC_CLOCK_REG; + Info.DPC__BUFBUSY_REG = &g_Reg->DPC_BUFBUSY_REG; + Info.DPC__PIPEBUSY_REG = &g_Reg->DPC_PIPEBUSY_REG; + Info.DPC__TMEM_REG = &g_Reg->DPC_TMEM_REG; + Info.VI__STATUS_REG = &g_Reg->VI_STATUS_REG; + Info.VI__ORIGIN_REG = &g_Reg->VI_ORIGIN_REG; + Info.VI__WIDTH_REG = &g_Reg->VI_WIDTH_REG; + Info.VI__INTR_REG = &g_Reg->VI_INTR_REG; + Info.VI__V_CURRENT_LINE_REG = &g_Reg->VI_CURRENT_REG; + Info.VI__TIMING_REG = &g_Reg->VI_TIMING_REG; + Info.VI__V_SYNC_REG = &g_Reg->VI_V_SYNC_REG; + Info.VI__H_SYNC_REG = &g_Reg->VI_H_SYNC_REG; + Info.VI__LEAP_REG = &g_Reg->VI_LEAP_REG; + Info.VI__H_START_REG = &g_Reg->VI_H_START_REG; + Info.VI__V_START_REG = &g_Reg->VI_V_START_REG; + Info.VI__V_BURST_REG = &g_Reg->VI_V_BURST_REG; + Info.VI__X_SCALE_REG = &g_Reg->VI_X_SCALE_REG; + Info.VI__Y_SCALE_REG = &g_Reg->VI_Y_SCALE_REG; + } + + m_Initialized = InitiateGFX(Info) != 0; + +#ifdef _WIN32 + //jabo had a bug so I call CreateThread so his dllmain gets called again + pjutil::DynLibCallDllMain(); +#endif + + return m_Initialized; +} + +void CGfxPlugin::UnloadPluginDetails(void) +{ + if (m_LibHandle != NULL) + { + pjutil::DynLibClose(m_LibHandle); + m_LibHandle = NULL; + } + memset(&m_GFXDebug, 0, sizeof(m_GFXDebug)); + + // CaptureScreen = NULL; + ChangeWindow = NULL; + GetDebugInfo = NULL; + DrawScreen = NULL; + DrawStatus = NULL; + // FrameBufferRead = NULL; + // FrameBufferWrite = NULL; + InitiateDebugger = NULL; + MoveScreen = NULL; + ProcessDList = NULL; + ProcessRDPList = NULL; + ShowCFB = NULL; + UpdateScreen = NULL; + ViStatusChanged = NULL; + ViWidthChanged = NULL; + GetRomBrowserMenu = NULL; + OnRomBrowserMenuItem = NULL; +} + +void CGfxPlugin::ProcessMenuItem(int32_t id) +{ + if (m_GFXDebug.ProcessMenuItem) + { + m_GFXDebug.ProcessMenuItem(id); + } } \ No newline at end of file diff --git a/Source/Project64-core/Plugins/GFXPlugin.h b/Source/Project64-core/Plugins/GFXPlugin.h index 562e4da9d..a5a9f7350 100644 --- a/Source/Project64-core/Plugins/GFXPlugin.h +++ b/Source/Project64-core/Plugins/GFXPlugin.h @@ -1,98 +1,98 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include - -class CGfxPlugin : public CPlugin -{ - typedef struct - { - /* Menu */ - /* Items should have an ID between 5101 and 5200 */ - void * hGFXMenu; - void(CALL *ProcessMenuItem)(int32_t ID); - - /* Break Points */ - int32_t UseBPoints; - char BPPanelName[20]; - void(CALL *Add_BPoint) (void); - void(CALL *CreateBPPanel) (void * hDlg, void * rcBox); - void(CALL *HideBPPanel) (void); - void(CALL *PaintBPPanel) (void * ps); - void(CALL *ShowBPPanel) (void); - void(CALL *RefreshBpoints) (void * hList); - void(CALL *RemoveBpoint) (void * hList, int32_t index); - void(CALL *RemoveAllBpoint) (void); - - /* GFX command Window */ - void(CALL *Enter_GFX_Commands_Window)(void); - } GFXDEBUG_INFO; - - typedef struct - { - void(CALL *UpdateBreakPoints)(void); - void(CALL *UpdateMemory)(void); - void(CALL *UpdateR4300iRegisters)(void); - void(CALL *Enter_BPoint_Window)(void); - void(CALL *Enter_R4300i_Commands_Window)(void); - void(CALL *Enter_R4300i_Register_Window)(void); - void(CALL *Enter_RSP_Commands_Window)(void); - void(CALL *Enter_Memory_Window)(void); - } DEBUG_INFO; - -public: - CGfxPlugin(void); - ~CGfxPlugin(); - - bool LoadFunctions(void); - bool Initiate(CN64System * System, RenderWindow * Window); - - void(CALL *CaptureScreen) (const char *); - void(CALL *ChangeWindow) (void); - void(CALL *DrawScreen) (void); - void(CALL *DrawStatus) (const char * lpString, int32_t RightAlign); - void(CALL *MoveScreen) (int32_t xpos, int32_t ypos); - void(CALL *ProcessDList) (void); - void(CALL *ProcessRDPList) (void); - void(CALL *ShowCFB) (void); - void(CALL *UpdateScreen) (void); - void(CALL *ViStatusChanged) (void); - void(CALL *ViWidthChanged) (void); - void(CALL *SoftReset) (void); - - //Rom Browser - void *(CALL * GetRomBrowserMenu)(void); /* Items should have an ID between 4101 and 4200 */ - void(CALL * OnRomBrowserMenuItem)(int32_t MenuID, void * hParent, uint8_t * HEADER); - - void * GetDebugMenu(void) { return m_GFXDebug.hGFXMenu; } - void ProcessMenuItem(int32_t id); - -private: - CGfxPlugin(const CGfxPlugin&); // Disable copy constructor - CGfxPlugin& operator=(const CGfxPlugin&); // Disable assignment - - virtual int32_t GetDefaultSettingStartRange() const { return FirstGfxDefaultSet; } - virtual int32_t GetSettingStartRange() const { return FirstGfxSettings; } - PLUGIN_TYPE type() { return PLUGIN_TYPE_GFX; } - - void UnloadPluginDetails(void); - - GFXDEBUG_INFO m_GFXDebug; - - void(CALL *GetDebugInfo) (GFXDEBUG_INFO * GFXDebugInfo); - void(CALL *InitiateDebugger)(DEBUG_INFO DebugInfo); - - static void CALL DummyDrawScreen(void) {} - static void CALL DummyMoveScreen(int32_t /*xpos*/, int32_t /*ypos*/) {} - static void CALL DummyViStatusChanged(void) {} - static void CALL DummyViWidthChanged(void) {} - static void CALL DummySoftReset(void) {} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +class CGfxPlugin : public CPlugin +{ + typedef struct + { + /* Menu */ + /* Items should have an ID between 5101 and 5200 */ + void * hGFXMenu; + void(CALL *ProcessMenuItem)(int32_t ID); + + /* Break Points */ + int32_t UseBPoints; + char BPPanelName[20]; + void(CALL *Add_BPoint) (void); + void(CALL *CreateBPPanel) (void * hDlg, void * rcBox); + void(CALL *HideBPPanel) (void); + void(CALL *PaintBPPanel) (void * ps); + void(CALL *ShowBPPanel) (void); + void(CALL *RefreshBpoints) (void * hList); + void(CALL *RemoveBpoint) (void * hList, int32_t index); + void(CALL *RemoveAllBpoint) (void); + + /* GFX command Window */ + void(CALL *Enter_GFX_Commands_Window)(void); + } GFXDEBUG_INFO; + + typedef struct + { + void(CALL *UpdateBreakPoints)(void); + void(CALL *UpdateMemory)(void); + void(CALL *UpdateR4300iRegisters)(void); + void(CALL *Enter_BPoint_Window)(void); + void(CALL *Enter_R4300i_Commands_Window)(void); + void(CALL *Enter_R4300i_Register_Window)(void); + void(CALL *Enter_RSP_Commands_Window)(void); + void(CALL *Enter_Memory_Window)(void); + } DEBUG_INFO; + +public: + CGfxPlugin(void); + ~CGfxPlugin(); + + bool LoadFunctions(void); + bool Initiate(CN64System * System, RenderWindow * Window); + + void(CALL *CaptureScreen) (const char *); + void(CALL *ChangeWindow) (void); + void(CALL *DrawScreen) (void); + void(CALL *DrawStatus) (const char * lpString, int32_t RightAlign); + void(CALL *MoveScreen) (int32_t xpos, int32_t ypos); + void(CALL *ProcessDList) (void); + void(CALL *ProcessRDPList) (void); + void(CALL *ShowCFB) (void); + void(CALL *UpdateScreen) (void); + void(CALL *ViStatusChanged) (void); + void(CALL *ViWidthChanged) (void); + void(CALL *SoftReset) (void); + + //Rom Browser + void *(CALL * GetRomBrowserMenu)(void); /* Items should have an ID between 4101 and 4200 */ + void(CALL * OnRomBrowserMenuItem)(int32_t MenuID, void * hParent, uint8_t * HEADER); + + void * GetDebugMenu(void) { return m_GFXDebug.hGFXMenu; } + void ProcessMenuItem(int32_t id); + +private: + CGfxPlugin(const CGfxPlugin&); // Disable copy constructor + CGfxPlugin& operator=(const CGfxPlugin&); // Disable assignment + + virtual int32_t GetDefaultSettingStartRange() const { return FirstGfxDefaultSet; } + virtual int32_t GetSettingStartRange() const { return FirstGfxSettings; } + PLUGIN_TYPE type() { return PLUGIN_TYPE_GFX; } + + void UnloadPluginDetails(void); + + GFXDEBUG_INFO m_GFXDebug; + + void(CALL *GetDebugInfo) (GFXDEBUG_INFO * GFXDebugInfo); + void(CALL *InitiateDebugger)(DEBUG_INFO DebugInfo); + + static void CALL DummyDrawScreen(void) {} + static void CALL DummyMoveScreen(int32_t /*xpos*/, int32_t /*ypos*/) {} + static void CALL DummyViStatusChanged(void) {} + static void CALL DummyViWidthChanged(void) {} + static void CALL DummySoftReset(void) {} }; \ No newline at end of file diff --git a/Source/Project64-core/Plugins/PluginClass.cpp b/Source/Project64-core/Plugins/PluginClass.cpp index af6b7ea21..1fee7ddfc 100644 --- a/Source/Project64-core/Plugins/PluginClass.cpp +++ b/Source/Project64-core/Plugins/PluginClass.cpp @@ -1,426 +1,426 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include - -CPlugins::CPlugins(const stdstr & PluginDir) : - m_MainWindow(NULL), - m_SyncWindow(NULL), - m_PluginDir(PluginDir), - m_Gfx(NULL), - m_Audio(NULL), - m_RSP(NULL), - m_Control(NULL) -{ - CreatePlugins(); - g_Settings->RegisterChangeCB(Plugin_RSP_Current, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Plugin_GFX_Current, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Plugin_AUDIO_Current, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Plugin_CONT_Current, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Plugin_UseHleGfx, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Plugin_UseHleAudio, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Game_EditPlugin_Gfx, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Game_EditPlugin_Audio, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Game_EditPlugin_Contr, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->RegisterChangeCB(Game_EditPlugin_RSP, this, (CSettings::SettingChangedFunc)PluginChanged); -} - -CPlugins::~CPlugins(void) -{ - g_Settings->UnregisterChangeCB(Plugin_RSP_Current, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Plugin_GFX_Current, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Plugin_AUDIO_Current, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Plugin_CONT_Current, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Plugin_UseHleGfx, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Plugin_UseHleAudio, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Game_EditPlugin_Gfx, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Game_EditPlugin_Audio, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Game_EditPlugin_Contr, this, (CSettings::SettingChangedFunc)PluginChanged); - g_Settings->UnregisterChangeCB(Game_EditPlugin_RSP, this, (CSettings::SettingChangedFunc)PluginChanged); - - DestroyGfxPlugin(); - DestroyAudioPlugin(); - DestroyRspPlugin(); - DestroyControlPlugin(); -} - -void CPlugins::PluginChanged(CPlugins * _this) -{ - if (g_Settings->LoadBool(Game_TempLoaded) == true) - { - return; - } - bool bGfxChange = _stricmp(_this->m_GfxFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str()) != 0; - bool bAudioChange = _stricmp(_this->m_AudioFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()) != 0; - bool bRspChange = _stricmp(_this->m_RSPFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()) != 0; - bool bContChange = _stricmp(_this->m_ControlFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()) != 0; - - if (bGfxChange || bAudioChange || bRspChange || bContChange) - { - if (g_Settings->LoadBool(GameRunning_CPU_Running)) - { - //Ensure that base system actually exists before we go triggering the event - if (g_BaseSystem) - { - g_BaseSystem->ExternalEvent(SysEvent_ChangePlugins); - } - } - else - { - _this->Reset(NULL); - } - } -} - -template -static void LoadPlugin(SettingID PluginSettingID, SettingID PluginVerSettingID, plugin_type * & plugin, const char * PluginDir, stdstr & FileName, TraceModuleProject64 TraceLevel, const char * type) -{ - if (plugin != NULL) - { - return; - } - FileName = g_Settings->LoadStringVal(PluginSettingID); - CPath PluginFileName(PluginDir, FileName.c_str()); - plugin = new plugin_type(); - if (plugin) - { - WriteTrace(TraceLevel, TraceDebug, "%s Loading (%s): Starting", type, (const char *)PluginFileName); - if (plugin->Load(PluginFileName)) - { - WriteTrace(TraceLevel, TraceDebug, "%s Current Ver: %s", type, plugin->PluginName()); - g_Settings->SaveString(PluginVerSettingID, plugin->PluginName()); - } - else - { - WriteTrace(TraceError, TraceDebug, "Failed to load %s", (const char *)PluginFileName); - delete plugin; - plugin = NULL; - } - WriteTrace(TraceLevel, TraceDebug, "%s Loading Done", type); - } - else - { - WriteTrace(TraceError, TraceDebug, "Failed to allocate %s plugin", type); - } -} - -void CPlugins::CreatePlugins(void) -{ - LoadPlugin(Game_Plugin_Gfx, Plugin_GFX_CurVer, m_Gfx, m_PluginDir.c_str(), m_GfxFile, TraceGFXPlugin, "GFX"); - LoadPlugin(Game_Plugin_Audio, Plugin_AUDIO_CurVer, m_Audio, m_PluginDir.c_str(), m_AudioFile, TraceAudioPlugin, "Audio"); - LoadPlugin(Game_Plugin_RSP, Plugin_RSP_CurVer, m_RSP, m_PluginDir.c_str(), m_RSPFile, TraceRSPPlugin, "RSP"); - LoadPlugin(Game_Plugin_Controller, Plugin_CONT_CurVer, m_Control, m_PluginDir.c_str(), m_ControlFile, TraceControllerPlugin, "Control"); - - //Enable debugger - if (m_RSP != NULL && m_RSP->EnableDebugging) - { - WriteTrace(TraceRSPPlugin, TraceInfo, "EnableDebugging starting"); - m_RSP->EnableDebugging(bHaveDebugger()); - WriteTrace(TraceRSPPlugin, TraceInfo, "EnableDebugging done"); - } -} - -void CPlugins::GameReset(void) -{ - if (m_Gfx) - { - m_Gfx->GameReset(); - } - if (m_Audio) - { - m_Audio->GameReset(); - } - if (m_RSP) - { - m_RSP->GameReset(); - } - if (m_Control) - { - m_Control->GameReset(); - } -} - -void CPlugins::DestroyGfxPlugin(void) -{ - if (m_Gfx == NULL) - { - return; - } - WriteTrace(TraceGFXPlugin, TraceInfo, "before delete m_Gfx"); - delete m_Gfx; - WriteTrace(TraceGFXPlugin, TraceInfo, "after delete m_Gfx"); - m_Gfx = NULL; - // g_Settings->UnknownSetting_GFX = NULL; - DestroyRspPlugin(); -} - -void CPlugins::DestroyAudioPlugin(void) -{ - if (m_Audio == NULL) - { - return; - } - WriteTrace(TraceAudioPlugin, TraceDebug, "before close"); - m_Audio->Close(); - WriteTrace(TraceAudioPlugin, TraceDebug, "before delete"); - delete m_Audio; - WriteTrace(TraceAudioPlugin, TraceDebug, "after delete"); - m_Audio = NULL; - WriteTrace(TraceAudioPlugin, TraceDebug, "before DestroyRspPlugin"); - // g_Settings->UnknownSetting_AUDIO = NULL; - DestroyRspPlugin(); - WriteTrace(TraceAudioPlugin, TraceDebug, "after DestroyRspPlugin"); -} - -void CPlugins::DestroyRspPlugin(void) -{ - if (m_RSP == NULL) - { - return; - } - WriteTrace(TraceRSPPlugin, TraceDebug, "before close"); - m_RSP->Close(); - WriteTrace(TraceRSPPlugin, TraceDebug, "before delete"); - delete m_RSP; - m_RSP = NULL; - WriteTrace(TraceRSPPlugin, TraceDebug, "after delete"); - // g_Settings->UnknownSetting_RSP = NULL; -} - -void CPlugins::DestroyControlPlugin(void) -{ - if (m_Control == NULL) - { - return; - } - WriteTrace(TraceControllerPlugin, TraceDebug, "before close"); - m_Control->Close(); - WriteTrace(TraceControllerPlugin, TraceDebug, "before delete"); - delete m_Control; - m_Control = NULL; - WriteTrace(TraceControllerPlugin, TraceDebug, "after delete"); - // g_Settings->UnknownSetting_CTRL = NULL; -} - -void CPlugins::SetRenderWindows(RenderWindow * MainWindow, RenderWindow * SyncWindow) -{ - m_MainWindow = MainWindow; - m_SyncWindow = SyncWindow; -} - -void CPlugins::RomOpened(void) -{ - m_Gfx->RomOpened(); - m_RSP->RomOpened(); - m_Audio->RomOpened(); - m_Control->RomOpened(); -} - -void CPlugins::RomClosed(void) -{ - m_Gfx->RomClose(); - m_RSP->RomClose(); - m_Audio->RomClose(); - m_Control->RomClose(); -} - -bool CPlugins::Initiate(CN64System * System) -{ - WriteTrace(TracePlugins, TraceDebug, "Start"); - //Check to make sure we have the plugin available to be used - if (m_Gfx == NULL) { return false; } - if (m_Audio == NULL) { return false; } - if (m_RSP == NULL) { return false; } - if (m_Control == NULL) { return false; } - - WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Starting"); - if (!m_Gfx->Initiate(System, m_MainWindow)) { return false; } - WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Done"); - WriteTrace(TraceAudioPlugin, TraceDebug, "Audio Initiate Starting"); - if (!m_Audio->Initiate(System, m_MainWindow)) { return false; } - WriteTrace(TraceAudioPlugin, TraceDebug, "Audio Initiate Done"); - WriteTrace(TraceControllerPlugin, TraceDebug, "Control Initiate Starting"); - if (!m_Control->Initiate(System, m_MainWindow)) { return false; } - WriteTrace(TraceControllerPlugin, TraceDebug, "Control Initiate Done"); - WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Starting"); - if (!m_RSP->Initiate(this, System)) { return false; } - WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Done"); - WriteTrace(TracePlugins, TraceDebug, "Done"); - return true; -} - -bool CPlugins::ResetInUiThread(CN64System * System) -{ - return m_MainWindow->ResetPluginsInUiThread(this, System); -} - -bool CPlugins::Reset(CN64System * System) -{ - WriteTrace(TracePlugins, TraceDebug, "Start"); - - bool bGfxChange = _stricmp(m_GfxFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str()) != 0; - bool bAudioChange = _stricmp(m_AudioFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()) != 0; - bool bRspChange = _stricmp(m_RSPFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()) != 0; - bool bContChange = _stricmp(m_ControlFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()) != 0; - - //if GFX and Audio has changed we also need to force reset of RSP - if (bGfxChange || bAudioChange) - bRspChange = true; - - if (bGfxChange) { DestroyGfxPlugin(); } - if (bAudioChange) { DestroyAudioPlugin(); } - if (bRspChange) { DestroyRspPlugin(); } - if (bContChange) { DestroyControlPlugin(); } - - CreatePlugins(); - - if (m_Gfx && bGfxChange) - { - WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Starting"); - if (!m_Gfx->Initiate(System, m_MainWindow)) { return false; } - WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Done"); - } - if (m_Audio && bAudioChange) - { - WriteTrace(TraceAudioPlugin, TraceDebug, "Audio Initiate Starting"); - if (!m_Audio->Initiate(System, m_MainWindow)) { return false; } - WriteTrace(TraceAudioPlugin, TraceDebug, "Audio Initiate Done"); - } - if (m_Control && bContChange) - { - WriteTrace(TraceControllerPlugin, TraceDebug, "Control Initiate Starting"); - if (!m_Control->Initiate(System, m_MainWindow)) { return false; } - WriteTrace(TraceControllerPlugin, TraceDebug, "Control Initiate Done"); - } - if (m_RSP && bRspChange) - { - WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Starting"); - if (!m_RSP->Initiate(this, System)) { return false; } - WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Done"); - } - WriteTrace(TracePlugins, TraceDebug, "Done"); - return true; -} - -void CPlugins::ConfigPlugin(void* hParent, PLUGIN_TYPE Type) -{ - switch (Type) - { - case PLUGIN_TYPE_RSP: - if (m_RSP == NULL || m_RSP->DllConfig == NULL) { break; } - if (!m_RSP->Initialized()) - { - if (!m_RSP->Initiate(this, NULL)) - { - break; - } - } - m_RSP->DllConfig(hParent); - break; - case PLUGIN_TYPE_GFX: - if (m_Gfx == NULL || m_Gfx->DllConfig == NULL) { break; } - if (!m_Gfx->Initialized()) - { - if (!m_Gfx->Initiate(NULL, m_MainWindow)) - { - break; - } - } - m_Gfx->DllConfig(hParent); - break; - case PLUGIN_TYPE_AUDIO: - if (m_Audio == NULL || m_Audio->DllConfig == NULL) { break; } - if (!m_Audio->Initialized()) - { - if (!m_Audio->Initiate(NULL, m_MainWindow)) - { - break; - } - } - m_Audio->DllConfig(hParent); - break; - case PLUGIN_TYPE_CONTROLLER: - if (m_Control == NULL || m_Control->DllConfig == NULL) { break; } - if (!m_Control->Initialized()) - { - if (!m_Control->Initiate(NULL, m_MainWindow)) - { - break; - } - } - m_Control->DllConfig(hParent); - break; - } -} - -void DummyCheckInterrupts(void) -{ -} - -void DummyFunction(void) -{ -} - -bool CPlugins::CopyPlugins(const stdstr & DstDir) const -{ - //Copy GFX Plugin - CPath srcGfxPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str()); - CPath dstGfxPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str()); - - if (!dstGfxPlugin.DirectoryExists()) - { - dstGfxPlugin.DirectoryCreate(); - } - if (!srcGfxPlugin.CopyTo(dstGfxPlugin)) - { - return false; - } - - //Copy m_Audio Plugin - CPath srcAudioPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()); - CPath dstAudioPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()); - if (!dstAudioPlugin.DirectoryExists()) - { - dstAudioPlugin.DirectoryCreate(); - } - if (!srcAudioPlugin.CopyTo(dstAudioPlugin)) - { - return false; - } - - //Copy RSP Plugin - CPath srcRSPPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()); - CPath dstRSPPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()); - if (!dstRSPPlugin.DirectoryExists()) - { - dstRSPPlugin.DirectoryCreate(); - } - if (!srcRSPPlugin.CopyTo(dstRSPPlugin)) - { - return false; - } - - //Copy Controller Plugin - CPath srcContPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()); - CPath dstContPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()); - if (!dstContPlugin.DirectoryExists()) - { - dstContPlugin.DirectoryCreate(); - } - if (!srcContPlugin.CopyTo(dstContPlugin)) - { - return false; - } - return true; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include + +CPlugins::CPlugins(const stdstr & PluginDir) : + m_MainWindow(NULL), + m_SyncWindow(NULL), + m_PluginDir(PluginDir), + m_Gfx(NULL), + m_Audio(NULL), + m_RSP(NULL), + m_Control(NULL) +{ + CreatePlugins(); + g_Settings->RegisterChangeCB(Plugin_RSP_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Plugin_GFX_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Plugin_AUDIO_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Plugin_CONT_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Plugin_UseHleGfx, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Plugin_UseHleAudio, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Game_EditPlugin_Gfx, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Game_EditPlugin_Audio, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Game_EditPlugin_Contr, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Game_EditPlugin_RSP, this, (CSettings::SettingChangedFunc)PluginChanged); +} + +CPlugins::~CPlugins(void) +{ + g_Settings->UnregisterChangeCB(Plugin_RSP_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Plugin_GFX_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Plugin_AUDIO_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Plugin_CONT_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Plugin_UseHleGfx, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Plugin_UseHleAudio, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Game_EditPlugin_Gfx, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Game_EditPlugin_Audio, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Game_EditPlugin_Contr, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Game_EditPlugin_RSP, this, (CSettings::SettingChangedFunc)PluginChanged); + + DestroyGfxPlugin(); + DestroyAudioPlugin(); + DestroyRspPlugin(); + DestroyControlPlugin(); +} + +void CPlugins::PluginChanged(CPlugins * _this) +{ + if (g_Settings->LoadBool(Game_TempLoaded) == true) + { + return; + } + bool bGfxChange = _stricmp(_this->m_GfxFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str()) != 0; + bool bAudioChange = _stricmp(_this->m_AudioFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()) != 0; + bool bRspChange = _stricmp(_this->m_RSPFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()) != 0; + bool bContChange = _stricmp(_this->m_ControlFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()) != 0; + + if (bGfxChange || bAudioChange || bRspChange || bContChange) + { + if (g_Settings->LoadBool(GameRunning_CPU_Running)) + { + //Ensure that base system actually exists before we go triggering the event + if (g_BaseSystem) + { + g_BaseSystem->ExternalEvent(SysEvent_ChangePlugins); + } + } + else + { + _this->Reset(NULL); + } + } +} + +template +static void LoadPlugin(SettingID PluginSettingID, SettingID PluginVerSettingID, plugin_type * & plugin, const char * PluginDir, stdstr & FileName, TraceModuleProject64 TraceLevel, const char * type) +{ + if (plugin != NULL) + { + return; + } + FileName = g_Settings->LoadStringVal(PluginSettingID); + CPath PluginFileName(PluginDir, FileName.c_str()); + plugin = new plugin_type(); + if (plugin) + { + WriteTrace(TraceLevel, TraceDebug, "%s Loading (%s): Starting", type, (const char *)PluginFileName); + if (plugin->Load(PluginFileName)) + { + WriteTrace(TraceLevel, TraceDebug, "%s Current Ver: %s", type, plugin->PluginName()); + g_Settings->SaveString(PluginVerSettingID, plugin->PluginName()); + } + else + { + WriteTrace(TraceError, TraceDebug, "Failed to load %s", (const char *)PluginFileName); + delete plugin; + plugin = NULL; + } + WriteTrace(TraceLevel, TraceDebug, "%s Loading Done", type); + } + else + { + WriteTrace(TraceError, TraceDebug, "Failed to allocate %s plugin", type); + } +} + +void CPlugins::CreatePlugins(void) +{ + LoadPlugin(Game_Plugin_Gfx, Plugin_GFX_CurVer, m_Gfx, m_PluginDir.c_str(), m_GfxFile, TraceGFXPlugin, "GFX"); + LoadPlugin(Game_Plugin_Audio, Plugin_AUDIO_CurVer, m_Audio, m_PluginDir.c_str(), m_AudioFile, TraceAudioPlugin, "Audio"); + LoadPlugin(Game_Plugin_RSP, Plugin_RSP_CurVer, m_RSP, m_PluginDir.c_str(), m_RSPFile, TraceRSPPlugin, "RSP"); + LoadPlugin(Game_Plugin_Controller, Plugin_CONT_CurVer, m_Control, m_PluginDir.c_str(), m_ControlFile, TraceControllerPlugin, "Control"); + + //Enable debugger + if (m_RSP != NULL && m_RSP->EnableDebugging) + { + WriteTrace(TraceRSPPlugin, TraceInfo, "EnableDebugging starting"); + m_RSP->EnableDebugging(bHaveDebugger()); + WriteTrace(TraceRSPPlugin, TraceInfo, "EnableDebugging done"); + } +} + +void CPlugins::GameReset(void) +{ + if (m_Gfx) + { + m_Gfx->GameReset(); + } + if (m_Audio) + { + m_Audio->GameReset(); + } + if (m_RSP) + { + m_RSP->GameReset(); + } + if (m_Control) + { + m_Control->GameReset(); + } +} + +void CPlugins::DestroyGfxPlugin(void) +{ + if (m_Gfx == NULL) + { + return; + } + WriteTrace(TraceGFXPlugin, TraceInfo, "before delete m_Gfx"); + delete m_Gfx; + WriteTrace(TraceGFXPlugin, TraceInfo, "after delete m_Gfx"); + m_Gfx = NULL; + // g_Settings->UnknownSetting_GFX = NULL; + DestroyRspPlugin(); +} + +void CPlugins::DestroyAudioPlugin(void) +{ + if (m_Audio == NULL) + { + return; + } + WriteTrace(TraceAudioPlugin, TraceDebug, "before close"); + m_Audio->Close(); + WriteTrace(TraceAudioPlugin, TraceDebug, "before delete"); + delete m_Audio; + WriteTrace(TraceAudioPlugin, TraceDebug, "after delete"); + m_Audio = NULL; + WriteTrace(TraceAudioPlugin, TraceDebug, "before DestroyRspPlugin"); + // g_Settings->UnknownSetting_AUDIO = NULL; + DestroyRspPlugin(); + WriteTrace(TraceAudioPlugin, TraceDebug, "after DestroyRspPlugin"); +} + +void CPlugins::DestroyRspPlugin(void) +{ + if (m_RSP == NULL) + { + return; + } + WriteTrace(TraceRSPPlugin, TraceDebug, "before close"); + m_RSP->Close(); + WriteTrace(TraceRSPPlugin, TraceDebug, "before delete"); + delete m_RSP; + m_RSP = NULL; + WriteTrace(TraceRSPPlugin, TraceDebug, "after delete"); + // g_Settings->UnknownSetting_RSP = NULL; +} + +void CPlugins::DestroyControlPlugin(void) +{ + if (m_Control == NULL) + { + return; + } + WriteTrace(TraceControllerPlugin, TraceDebug, "before close"); + m_Control->Close(); + WriteTrace(TraceControllerPlugin, TraceDebug, "before delete"); + delete m_Control; + m_Control = NULL; + WriteTrace(TraceControllerPlugin, TraceDebug, "after delete"); + // g_Settings->UnknownSetting_CTRL = NULL; +} + +void CPlugins::SetRenderWindows(RenderWindow * MainWindow, RenderWindow * SyncWindow) +{ + m_MainWindow = MainWindow; + m_SyncWindow = SyncWindow; +} + +void CPlugins::RomOpened(void) +{ + m_Gfx->RomOpened(); + m_RSP->RomOpened(); + m_Audio->RomOpened(); + m_Control->RomOpened(); +} + +void CPlugins::RomClosed(void) +{ + m_Gfx->RomClose(); + m_RSP->RomClose(); + m_Audio->RomClose(); + m_Control->RomClose(); +} + +bool CPlugins::Initiate(CN64System * System) +{ + WriteTrace(TracePlugins, TraceDebug, "Start"); + //Check to make sure we have the plugin available to be used + if (m_Gfx == NULL) { return false; } + if (m_Audio == NULL) { return false; } + if (m_RSP == NULL) { return false; } + if (m_Control == NULL) { return false; } + + WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Starting"); + if (!m_Gfx->Initiate(System, m_MainWindow)) { return false; } + WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Done"); + WriteTrace(TraceAudioPlugin, TraceDebug, "Audio Initiate Starting"); + if (!m_Audio->Initiate(System, m_MainWindow)) { return false; } + WriteTrace(TraceAudioPlugin, TraceDebug, "Audio Initiate Done"); + WriteTrace(TraceControllerPlugin, TraceDebug, "Control Initiate Starting"); + if (!m_Control->Initiate(System, m_MainWindow)) { return false; } + WriteTrace(TraceControllerPlugin, TraceDebug, "Control Initiate Done"); + WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Starting"); + if (!m_RSP->Initiate(this, System)) { return false; } + WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Done"); + WriteTrace(TracePlugins, TraceDebug, "Done"); + return true; +} + +bool CPlugins::ResetInUiThread(CN64System * System) +{ + return m_MainWindow->ResetPluginsInUiThread(this, System); +} + +bool CPlugins::Reset(CN64System * System) +{ + WriteTrace(TracePlugins, TraceDebug, "Start"); + + bool bGfxChange = _stricmp(m_GfxFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str()) != 0; + bool bAudioChange = _stricmp(m_AudioFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()) != 0; + bool bRspChange = _stricmp(m_RSPFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()) != 0; + bool bContChange = _stricmp(m_ControlFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()) != 0; + + //if GFX and Audio has changed we also need to force reset of RSP + if (bGfxChange || bAudioChange) + bRspChange = true; + + if (bGfxChange) { DestroyGfxPlugin(); } + if (bAudioChange) { DestroyAudioPlugin(); } + if (bRspChange) { DestroyRspPlugin(); } + if (bContChange) { DestroyControlPlugin(); } + + CreatePlugins(); + + if (m_Gfx && bGfxChange) + { + WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Starting"); + if (!m_Gfx->Initiate(System, m_MainWindow)) { return false; } + WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Done"); + } + if (m_Audio && bAudioChange) + { + WriteTrace(TraceAudioPlugin, TraceDebug, "Audio Initiate Starting"); + if (!m_Audio->Initiate(System, m_MainWindow)) { return false; } + WriteTrace(TraceAudioPlugin, TraceDebug, "Audio Initiate Done"); + } + if (m_Control && bContChange) + { + WriteTrace(TraceControllerPlugin, TraceDebug, "Control Initiate Starting"); + if (!m_Control->Initiate(System, m_MainWindow)) { return false; } + WriteTrace(TraceControllerPlugin, TraceDebug, "Control Initiate Done"); + } + if (m_RSP && bRspChange) + { + WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Starting"); + if (!m_RSP->Initiate(this, System)) { return false; } + WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Done"); + } + WriteTrace(TracePlugins, TraceDebug, "Done"); + return true; +} + +void CPlugins::ConfigPlugin(void* hParent, PLUGIN_TYPE Type) +{ + switch (Type) + { + case PLUGIN_TYPE_RSP: + if (m_RSP == NULL || m_RSP->DllConfig == NULL) { break; } + if (!m_RSP->Initialized()) + { + if (!m_RSP->Initiate(this, NULL)) + { + break; + } + } + m_RSP->DllConfig(hParent); + break; + case PLUGIN_TYPE_GFX: + if (m_Gfx == NULL || m_Gfx->DllConfig == NULL) { break; } + if (!m_Gfx->Initialized()) + { + if (!m_Gfx->Initiate(NULL, m_MainWindow)) + { + break; + } + } + m_Gfx->DllConfig(hParent); + break; + case PLUGIN_TYPE_AUDIO: + if (m_Audio == NULL || m_Audio->DllConfig == NULL) { break; } + if (!m_Audio->Initialized()) + { + if (!m_Audio->Initiate(NULL, m_MainWindow)) + { + break; + } + } + m_Audio->DllConfig(hParent); + break; + case PLUGIN_TYPE_CONTROLLER: + if (m_Control == NULL || m_Control->DllConfig == NULL) { break; } + if (!m_Control->Initialized()) + { + if (!m_Control->Initiate(NULL, m_MainWindow)) + { + break; + } + } + m_Control->DllConfig(hParent); + break; + } +} + +void DummyCheckInterrupts(void) +{ +} + +void DummyFunction(void) +{ +} + +bool CPlugins::CopyPlugins(const stdstr & DstDir) const +{ + //Copy GFX Plugin + CPath srcGfxPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str()); + CPath dstGfxPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str()); + + if (!dstGfxPlugin.DirectoryExists()) + { + dstGfxPlugin.DirectoryCreate(); + } + if (!srcGfxPlugin.CopyTo(dstGfxPlugin)) + { + return false; + } + + //Copy m_Audio Plugin + CPath srcAudioPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()); + CPath dstAudioPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()); + if (!dstAudioPlugin.DirectoryExists()) + { + dstAudioPlugin.DirectoryCreate(); + } + if (!srcAudioPlugin.CopyTo(dstAudioPlugin)) + { + return false; + } + + //Copy RSP Plugin + CPath srcRSPPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()); + CPath dstRSPPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()); + if (!dstRSPPlugin.DirectoryExists()) + { + dstRSPPlugin.DirectoryCreate(); + } + if (!srcRSPPlugin.CopyTo(dstRSPPlugin)) + { + return false; + } + + //Copy Controller Plugin + CPath srcContPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()); + CPath dstContPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()); + if (!dstContPlugin.DirectoryExists()) + { + dstContPlugin.DirectoryCreate(); + } + if (!srcContPlugin.CopyTo(dstContPlugin)) + { + return false; + } + return true; } \ No newline at end of file diff --git a/Source/Project64-core/Plugins/PluginClass.h b/Source/Project64-core/Plugins/PluginClass.h index bac35b984..3e92e78d3 100644 --- a/Source/Project64-core/Plugins/PluginClass.h +++ b/Source/Project64-core/Plugins/PluginClass.h @@ -1,154 +1,154 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include -#include - -#ifndef PLUGIN_INFO_STRUCT -#define PLUGIN_INFO_STRUCT - -typedef struct -{ - uint16_t Version; /* Should be set to 1 */ - uint16_t Type; /* Set to PLUGIN_TYPE_GFX */ - char Name[100]; /* Name of the DLL */ - - /* If DLL supports memory these memory options then set them to TRUE or FALSE - if it does not support it */ - int32_t NormalMemory; /* a normal BYTE array */ - int32_t MemoryBswaped; /* a normal BYTE array where the memory has been pre - bswap on a dword (32 bits) boundry */ -} PLUGIN_INFO; - -#endif - -// enum's -enum SETTING_DATA_TYPE -{ - Data_DWORD_General = 0, // A uint32_t setting used anywhere - Data_String_General = 1, // A string setting used anywhere - Data_DWORD_Game = 2, // A uint32_t associated with the current game - Data_String_Game = 3, // A string associated with the current game - Data_DWORD_RDB = 4, // A uint32_t associated with the current game in the rom database - Data_String_RDB = 5, // A string associated with the current game in the rom database - Data_DWORD_RDB_Setting = 6, // A uint32_t read from the rom database, with config file - Data_String_RDB_Setting = 7, // A string read from the rom database, with config file -}; - -typedef struct -{ - uint32_t dwSize; - int32_t DefaultStartRange; - int32_t SettingStartRange; - int32_t MaximumSettings; - int32_t NoDefault; - int32_t DefaultLocation; - void * handle; - uint32_t(*GetSetting) (void * handle, int32_t ID); - const char * (*GetSettingSz) (void * handle, int32_t ID, char * Buffer, int32_t BufferLen); - void(*SetSetting) (void * handle, int32_t ID, uint32_t Value); - void(*SetSettingSz) (void * handle, int32_t ID, const char * Value); - void(*RegisterSetting) (void * handle, int32_t ID, int32_t DefaultID, SettingDataType Type, - SettingType Location, const char * Category, const char * DefaultStr, uint32_t Value); - void(*UseUnregisteredSetting) (int32_t ID); -} PLUGIN_SETTINGS; - -typedef struct -{ - uint32_t(*FindSystemSettingId) (void * handle, const char * Name); -} PLUGIN_SETTINGS2; - -typedef struct -{ - void(*FlushSettings) (void * handle); -} PLUGIN_SETTINGS3; - -enum PLUGIN_TYPE -{ - PLUGIN_TYPE_NONE = 0, - PLUGIN_TYPE_RSP = 1, - PLUGIN_TYPE_GFX = 2, - PLUGIN_TYPE_AUDIO = 3, - PLUGIN_TYPE_CONTROLLER = 4, -}; - -class CSettings; -class CGfxPlugin; class CAudioPlugin; class CRSP_Plugin; class CControl_Plugin; -class CN64System; -class CPlugins; - -__interface RenderWindow -{ - virtual bool ResetPluginsInUiThread(CPlugins * plugins, CN64System * System) = 0; - virtual void * GetWindowHandle(void) const = 0; - virtual void * GetStatusBar(void) const = 0; - virtual void * GetModuleInstance(void) const = 0; -}; - -class CPlugins : - private CDebugSettings -{ -public: - //Functions - CPlugins(const stdstr & PluginDir); - ~CPlugins(); - - bool Initiate(CN64System * System); - void RomOpened(void); - void RomClosed(void); - void SetRenderWindows(RenderWindow * MainWindow, RenderWindow * SyncWindow); - void ConfigPlugin(void * hParent, PLUGIN_TYPE Type); - bool CopyPlugins(const stdstr & DstDir) const; - void CreatePlugins(void); - bool Reset(CN64System * System); - bool ResetInUiThread(CN64System * System); - void GameReset(void); - - inline CGfxPlugin * Gfx(void) const { return m_Gfx; } - inline CAudioPlugin * Audio(void) const { return m_Audio; } - inline CRSP_Plugin * RSP(void) const { return m_RSP; } - inline CControl_Plugin * Control(void) const { return m_Control; } - - inline RenderWindow * MainWindow(void) const { return m_MainWindow; } - inline RenderWindow * SyncWindow(void) const { return m_SyncWindow; } - -private: - CPlugins(void); // Disable default constructor - CPlugins(const CPlugins&); // Disable copy constructor - CPlugins& operator=(const CPlugins&); // Disable assignment - - void DestroyGfxPlugin(void); - void DestroyAudioPlugin(void); - void DestroyRspPlugin(void); - void DestroyControlPlugin(void); - - static void PluginChanged(CPlugins * _this); - - RenderWindow * m_MainWindow; - RenderWindow * m_SyncWindow; - - stdstr const m_PluginDir; - - //Plugins - CGfxPlugin * m_Gfx; - CAudioPlugin * m_Audio; - CRSP_Plugin * m_RSP; - CControl_Plugin * m_Control; - - stdstr m_GfxFile; - stdstr m_AudioFile; - stdstr m_RSPFile; - stdstr m_ControlFile; -}; - -//Dummy Functions -void DummyCheckInterrupts(void); -void DummyFunction(void); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include +#include + +#ifndef PLUGIN_INFO_STRUCT +#define PLUGIN_INFO_STRUCT + +typedef struct +{ + uint16_t Version; /* Should be set to 1 */ + uint16_t Type; /* Set to PLUGIN_TYPE_GFX */ + char Name[100]; /* Name of the DLL */ + + /* If DLL supports memory these memory options then set them to TRUE or FALSE + if it does not support it */ + int32_t NormalMemory; /* a normal BYTE array */ + int32_t MemoryBswaped; /* a normal BYTE array where the memory has been pre + bswap on a dword (32 bits) boundry */ +} PLUGIN_INFO; + +#endif + +// enum's +enum SETTING_DATA_TYPE +{ + Data_DWORD_General = 0, // A uint32_t setting used anywhere + Data_String_General = 1, // A string setting used anywhere + Data_DWORD_Game = 2, // A uint32_t associated with the current game + Data_String_Game = 3, // A string associated with the current game + Data_DWORD_RDB = 4, // A uint32_t associated with the current game in the rom database + Data_String_RDB = 5, // A string associated with the current game in the rom database + Data_DWORD_RDB_Setting = 6, // A uint32_t read from the rom database, with config file + Data_String_RDB_Setting = 7, // A string read from the rom database, with config file +}; + +typedef struct +{ + uint32_t dwSize; + int32_t DefaultStartRange; + int32_t SettingStartRange; + int32_t MaximumSettings; + int32_t NoDefault; + int32_t DefaultLocation; + void * handle; + uint32_t(*GetSetting) (void * handle, int32_t ID); + const char * (*GetSettingSz) (void * handle, int32_t ID, char * Buffer, int32_t BufferLen); + void(*SetSetting) (void * handle, int32_t ID, uint32_t Value); + void(*SetSettingSz) (void * handle, int32_t ID, const char * Value); + void(*RegisterSetting) (void * handle, int32_t ID, int32_t DefaultID, SettingDataType Type, + SettingType Location, const char * Category, const char * DefaultStr, uint32_t Value); + void(*UseUnregisteredSetting) (int32_t ID); +} PLUGIN_SETTINGS; + +typedef struct +{ + uint32_t(*FindSystemSettingId) (void * handle, const char * Name); +} PLUGIN_SETTINGS2; + +typedef struct +{ + void(*FlushSettings) (void * handle); +} PLUGIN_SETTINGS3; + +enum PLUGIN_TYPE +{ + PLUGIN_TYPE_NONE = 0, + PLUGIN_TYPE_RSP = 1, + PLUGIN_TYPE_GFX = 2, + PLUGIN_TYPE_AUDIO = 3, + PLUGIN_TYPE_CONTROLLER = 4, +}; + +class CSettings; +class CGfxPlugin; class CAudioPlugin; class CRSP_Plugin; class CControl_Plugin; +class CN64System; +class CPlugins; + +__interface RenderWindow +{ + virtual bool ResetPluginsInUiThread(CPlugins * plugins, CN64System * System) = 0; + virtual void * GetWindowHandle(void) const = 0; + virtual void * GetStatusBar(void) const = 0; + virtual void * GetModuleInstance(void) const = 0; +}; + +class CPlugins : + private CDebugSettings +{ +public: + //Functions + CPlugins(const stdstr & PluginDir); + ~CPlugins(); + + bool Initiate(CN64System * System); + void RomOpened(void); + void RomClosed(void); + void SetRenderWindows(RenderWindow * MainWindow, RenderWindow * SyncWindow); + void ConfigPlugin(void * hParent, PLUGIN_TYPE Type); + bool CopyPlugins(const stdstr & DstDir) const; + void CreatePlugins(void); + bool Reset(CN64System * System); + bool ResetInUiThread(CN64System * System); + void GameReset(void); + + inline CGfxPlugin * Gfx(void) const { return m_Gfx; } + inline CAudioPlugin * Audio(void) const { return m_Audio; } + inline CRSP_Plugin * RSP(void) const { return m_RSP; } + inline CControl_Plugin * Control(void) const { return m_Control; } + + inline RenderWindow * MainWindow(void) const { return m_MainWindow; } + inline RenderWindow * SyncWindow(void) const { return m_SyncWindow; } + +private: + CPlugins(void); // Disable default constructor + CPlugins(const CPlugins&); // Disable copy constructor + CPlugins& operator=(const CPlugins&); // Disable assignment + + void DestroyGfxPlugin(void); + void DestroyAudioPlugin(void); + void DestroyRspPlugin(void); + void DestroyControlPlugin(void); + + static void PluginChanged(CPlugins * _this); + + RenderWindow * m_MainWindow; + RenderWindow * m_SyncWindow; + + stdstr const m_PluginDir; + + //Plugins + CGfxPlugin * m_Gfx; + CAudioPlugin * m_Audio; + CRSP_Plugin * m_RSP; + CControl_Plugin * m_Control; + + stdstr m_GfxFile; + stdstr m_AudioFile; + stdstr m_RSPFile; + stdstr m_ControlFile; +}; + +//Dummy Functions +void DummyCheckInterrupts(void); +void DummyFunction(void); diff --git a/Source/Project64-core/Plugins/RSPPlugin.cpp b/Source/Project64-core/Plugins/RSPPlugin.cpp index a5a9897ba..ec474e44c 100644 --- a/Source/Project64-core/Plugins/RSPPlugin.cpp +++ b/Source/Project64-core/Plugins/RSPPlugin.cpp @@ -1,218 +1,218 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include "RSPPlugin.h" -#include "GFXPlugin.h" -#include - -void DummyFunc1(int a) { a += 1; } - -CRSP_Plugin::CRSP_Plugin(void) : - DoRspCycles(NULL), - EnableDebugging(NULL), - m_CycleCount(0), - GetDebugInfo(NULL), - InitiateDebugger(NULL) -{ - memset(&m_RSPDebug, 0, sizeof(m_RSPDebug)); -} - -CRSP_Plugin::~CRSP_Plugin() -{ - Close(); - UnloadPlugin(); -} - -bool CRSP_Plugin::LoadFunctions(void) -{ - // Find entries for functions in DLL - void(CALL *InitiateRSP)(void); - LoadFunction(InitiateRSP); - LoadFunction(DoRspCycles); - _LoadFunction("GetRspDebugInfo", GetDebugInfo); - _LoadFunction("InitiateRSPDebugger", InitiateDebugger); - LoadFunction(EnableDebugging); - if (EnableDebugging == NULL) { EnableDebugging = DummyFunc1; } - - //Make sure dll had all needed functions - if (DoRspCycles == NULL) { UnloadPlugin(); return false; } - if (InitiateRSP == NULL) { UnloadPlugin(); return false; } - if (RomClosed == NULL) { UnloadPlugin(); return false; } - if (CloseDLL == NULL) { UnloadPlugin(); return false; } - - if (m_PluginInfo.Version >= 0x0102) - { - if (PluginOpened == NULL) { UnloadPlugin(); return false; } - } - - // Get debug info if able - if (GetDebugInfo != NULL) - { - GetDebugInfo(&m_RSPDebug); - } - return true; -} - -bool CRSP_Plugin::Initiate(CPlugins * Plugins, CN64System * System) -{ - if (m_PluginInfo.Version == 1 || m_PluginInfo.Version == 0x100) - { - return false; - } - - typedef struct - { - void * hInst; - int MemoryBswaped; /* If this is set to TRUE, then the memory has been pre - bswap on a dword (32 bits) boundry */ - uint8_t * RDRAM; - uint8_t * DMEM; - uint8_t * IMEM; - - uint32_t * MI__INTR_REG; - - uint32_t * SP__MEM_ADDR_REG; - uint32_t * SP__DRAM_ADDR_REG; - uint32_t * SP__RD_LEN_REG; - uint32_t * SP__WR_LEN_REG; - uint32_t * SP__STATUS_REG; - uint32_t * SP__DMA_FULL_REG; - uint32_t * SP__DMA_BUSY_REG; - uint32_t * SP__PC_REG; - uint32_t * SP__SEMAPHORE_REG; - - uint32_t * DPC__START_REG; - uint32_t * DPC__END_REG; - uint32_t * DPC__CURRENT_REG; - uint32_t * DPC__STATUS_REG; - uint32_t * DPC__CLOCK_REG; - uint32_t * DPC__BUFBUSY_REG; - uint32_t * DPC__PIPEBUSY_REG; - uint32_t * DPC__TMEM_REG; - - void(CALL *CheckInterrupts)(void); - void(CALL *ProcessDlist)(void); - void(CALL *ProcessAlist)(void); - void(CALL *ProcessRdpList)(void); - void(CALL *ShowCFB)(void); - } RSP_INFO_1_1; - - RSP_INFO_1_1 Info = { 0 }; - - Info.hInst = Plugins->MainWindow()->GetModuleInstance(); - Info.CheckInterrupts = DummyCheckInterrupts; - Info.MemoryBswaped = (System == NULL); // only true when the system's not yet loaded - - //Get Function from DLL - void(CALL *InitiateRSP) (RSP_INFO_1_1 Audio_Info, uint32_t * Cycles); - LoadFunction(InitiateRSP); - if (InitiateRSP == NULL) { return false; } - - // We are initializing the plugin before any rom is loaded so we do not have any correct - // parameters here.. just needed to we can config the DLL. - if (System == NULL) - { - uint8_t Buffer[100]; - uint32_t Value = 0; - - Info.ProcessDlist = DummyCheckInterrupts; - Info.ProcessRdpList = DummyCheckInterrupts; - Info.ShowCFB = DummyCheckInterrupts; - Info.ProcessAlist = DummyCheckInterrupts; - - Info.RDRAM = Buffer; - Info.DMEM = Buffer; - Info.IMEM = Buffer; - - Info.MI__INTR_REG = &Value; - - Info.SP__MEM_ADDR_REG = &Value; - Info.SP__DRAM_ADDR_REG = &Value; - Info.SP__RD_LEN_REG = &Value; - Info.SP__WR_LEN_REG = &Value; - Info.SP__STATUS_REG = &Value; - Info.SP__DMA_FULL_REG = &Value; - Info.SP__DMA_BUSY_REG = &Value; - Info.SP__PC_REG = &Value; - Info.SP__SEMAPHORE_REG = &Value; - - Info.DPC__START_REG = &Value; - Info.DPC__END_REG = &Value; - Info.DPC__CURRENT_REG = &Value; - Info.DPC__STATUS_REG = &Value; - Info.DPC__CLOCK_REG = &Value; - Info.DPC__BUFBUSY_REG = &Value; - Info.DPC__PIPEBUSY_REG = &Value; - Info.DPC__TMEM_REG = &Value; - } - // Send initialization information to the DLL - else - { - Info.ProcessDlist = Plugins->Gfx()->ProcessDList; - Info.ProcessRdpList = Plugins->Gfx()->ProcessRDPList; - Info.ShowCFB = Plugins->Gfx()->ShowCFB; - Info.ProcessAlist = Plugins->Audio()->ProcessAList; - - Info.RDRAM = g_MMU->Rdram(); - Info.DMEM = g_MMU->Dmem(); - Info.IMEM = g_MMU->Imem(); - - Info.MI__INTR_REG = &g_Reg->m_RspIntrReg; - - Info.SP__MEM_ADDR_REG = &g_Reg->SP_MEM_ADDR_REG; - Info.SP__DRAM_ADDR_REG = &g_Reg->SP_DRAM_ADDR_REG; - Info.SP__RD_LEN_REG = &g_Reg->SP_RD_LEN_REG; - Info.SP__WR_LEN_REG = &g_Reg->SP_WR_LEN_REG; - Info.SP__STATUS_REG = &g_Reg->SP_STATUS_REG; - Info.SP__DMA_FULL_REG = &g_Reg->SP_DMA_FULL_REG; - Info.SP__DMA_BUSY_REG = &g_Reg->SP_DMA_BUSY_REG; - Info.SP__PC_REG = &g_Reg->SP_PC_REG; - Info.SP__SEMAPHORE_REG = &g_Reg->SP_SEMAPHORE_REG; - - Info.DPC__START_REG = &g_Reg->DPC_START_REG; - Info.DPC__END_REG = &g_Reg->DPC_END_REG; - Info.DPC__CURRENT_REG = &g_Reg->DPC_CURRENT_REG; - Info.DPC__STATUS_REG = &g_Reg->DPC_STATUS_REG; - Info.DPC__CLOCK_REG = &g_Reg->DPC_CLOCK_REG; - Info.DPC__BUFBUSY_REG = &g_Reg->DPC_BUFBUSY_REG; - Info.DPC__PIPEBUSY_REG = &g_Reg->DPC_PIPEBUSY_REG; - Info.DPC__TMEM_REG = &g_Reg->DPC_TMEM_REG; - } - - InitiateRSP(Info, &m_CycleCount); - m_Initialized = true; - -#ifdef _WIN32 - //jabo had a bug so I call CreateThread so his dllmain gets called again - pjutil::DynLibCallDllMain(); -#endif - return m_Initialized; -} - -void CRSP_Plugin::UnloadPluginDetails(void) -{ - memset(&m_RSPDebug, 0, sizeof(m_RSPDebug)); - DoRspCycles = NULL; - EnableDebugging = NULL; - GetDebugInfo = NULL; - InitiateDebugger = NULL; -} - -void CRSP_Plugin::ProcessMenuItem(int id) -{ - if (m_RSPDebug.ProcessMenuItem) - { - m_RSPDebug.ProcessMenuItem(id); - } +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include "RSPPlugin.h" +#include "GFXPlugin.h" +#include + +void DummyFunc1(int a) { a += 1; } + +CRSP_Plugin::CRSP_Plugin(void) : + DoRspCycles(NULL), + EnableDebugging(NULL), + m_CycleCount(0), + GetDebugInfo(NULL), + InitiateDebugger(NULL) +{ + memset(&m_RSPDebug, 0, sizeof(m_RSPDebug)); +} + +CRSP_Plugin::~CRSP_Plugin() +{ + Close(); + UnloadPlugin(); +} + +bool CRSP_Plugin::LoadFunctions(void) +{ + // Find entries for functions in DLL + void(CALL *InitiateRSP)(void); + LoadFunction(InitiateRSP); + LoadFunction(DoRspCycles); + _LoadFunction("GetRspDebugInfo", GetDebugInfo); + _LoadFunction("InitiateRSPDebugger", InitiateDebugger); + LoadFunction(EnableDebugging); + if (EnableDebugging == NULL) { EnableDebugging = DummyFunc1; } + + //Make sure dll had all needed functions + if (DoRspCycles == NULL) { UnloadPlugin(); return false; } + if (InitiateRSP == NULL) { UnloadPlugin(); return false; } + if (RomClosed == NULL) { UnloadPlugin(); return false; } + if (CloseDLL == NULL) { UnloadPlugin(); return false; } + + if (m_PluginInfo.Version >= 0x0102) + { + if (PluginOpened == NULL) { UnloadPlugin(); return false; } + } + + // Get debug info if able + if (GetDebugInfo != NULL) + { + GetDebugInfo(&m_RSPDebug); + } + return true; +} + +bool CRSP_Plugin::Initiate(CPlugins * Plugins, CN64System * System) +{ + if (m_PluginInfo.Version == 1 || m_PluginInfo.Version == 0x100) + { + return false; + } + + typedef struct + { + void * hInst; + int MemoryBswaped; /* If this is set to TRUE, then the memory has been pre + bswap on a dword (32 bits) boundry */ + uint8_t * RDRAM; + uint8_t * DMEM; + uint8_t * IMEM; + + uint32_t * MI__INTR_REG; + + uint32_t * SP__MEM_ADDR_REG; + uint32_t * SP__DRAM_ADDR_REG; + uint32_t * SP__RD_LEN_REG; + uint32_t * SP__WR_LEN_REG; + uint32_t * SP__STATUS_REG; + uint32_t * SP__DMA_FULL_REG; + uint32_t * SP__DMA_BUSY_REG; + uint32_t * SP__PC_REG; + uint32_t * SP__SEMAPHORE_REG; + + uint32_t * DPC__START_REG; + uint32_t * DPC__END_REG; + uint32_t * DPC__CURRENT_REG; + uint32_t * DPC__STATUS_REG; + uint32_t * DPC__CLOCK_REG; + uint32_t * DPC__BUFBUSY_REG; + uint32_t * DPC__PIPEBUSY_REG; + uint32_t * DPC__TMEM_REG; + + void(CALL *CheckInterrupts)(void); + void(CALL *ProcessDlist)(void); + void(CALL *ProcessAlist)(void); + void(CALL *ProcessRdpList)(void); + void(CALL *ShowCFB)(void); + } RSP_INFO_1_1; + + RSP_INFO_1_1 Info = { 0 }; + + Info.hInst = Plugins->MainWindow()->GetModuleInstance(); + Info.CheckInterrupts = DummyCheckInterrupts; + Info.MemoryBswaped = (System == NULL); // only true when the system's not yet loaded + + //Get Function from DLL + void(CALL *InitiateRSP) (RSP_INFO_1_1 Audio_Info, uint32_t * Cycles); + LoadFunction(InitiateRSP); + if (InitiateRSP == NULL) { return false; } + + // We are initializing the plugin before any rom is loaded so we do not have any correct + // parameters here.. just needed to we can config the DLL. + if (System == NULL) + { + uint8_t Buffer[100]; + uint32_t Value = 0; + + Info.ProcessDlist = DummyCheckInterrupts; + Info.ProcessRdpList = DummyCheckInterrupts; + Info.ShowCFB = DummyCheckInterrupts; + Info.ProcessAlist = DummyCheckInterrupts; + + Info.RDRAM = Buffer; + Info.DMEM = Buffer; + Info.IMEM = Buffer; + + Info.MI__INTR_REG = &Value; + + Info.SP__MEM_ADDR_REG = &Value; + Info.SP__DRAM_ADDR_REG = &Value; + Info.SP__RD_LEN_REG = &Value; + Info.SP__WR_LEN_REG = &Value; + Info.SP__STATUS_REG = &Value; + Info.SP__DMA_FULL_REG = &Value; + Info.SP__DMA_BUSY_REG = &Value; + Info.SP__PC_REG = &Value; + Info.SP__SEMAPHORE_REG = &Value; + + Info.DPC__START_REG = &Value; + Info.DPC__END_REG = &Value; + Info.DPC__CURRENT_REG = &Value; + Info.DPC__STATUS_REG = &Value; + Info.DPC__CLOCK_REG = &Value; + Info.DPC__BUFBUSY_REG = &Value; + Info.DPC__PIPEBUSY_REG = &Value; + Info.DPC__TMEM_REG = &Value; + } + // Send initialization information to the DLL + else + { + Info.ProcessDlist = Plugins->Gfx()->ProcessDList; + Info.ProcessRdpList = Plugins->Gfx()->ProcessRDPList; + Info.ShowCFB = Plugins->Gfx()->ShowCFB; + Info.ProcessAlist = Plugins->Audio()->ProcessAList; + + Info.RDRAM = g_MMU->Rdram(); + Info.DMEM = g_MMU->Dmem(); + Info.IMEM = g_MMU->Imem(); + + Info.MI__INTR_REG = &g_Reg->m_RspIntrReg; + + Info.SP__MEM_ADDR_REG = &g_Reg->SP_MEM_ADDR_REG; + Info.SP__DRAM_ADDR_REG = &g_Reg->SP_DRAM_ADDR_REG; + Info.SP__RD_LEN_REG = &g_Reg->SP_RD_LEN_REG; + Info.SP__WR_LEN_REG = &g_Reg->SP_WR_LEN_REG; + Info.SP__STATUS_REG = &g_Reg->SP_STATUS_REG; + Info.SP__DMA_FULL_REG = &g_Reg->SP_DMA_FULL_REG; + Info.SP__DMA_BUSY_REG = &g_Reg->SP_DMA_BUSY_REG; + Info.SP__PC_REG = &g_Reg->SP_PC_REG; + Info.SP__SEMAPHORE_REG = &g_Reg->SP_SEMAPHORE_REG; + + Info.DPC__START_REG = &g_Reg->DPC_START_REG; + Info.DPC__END_REG = &g_Reg->DPC_END_REG; + Info.DPC__CURRENT_REG = &g_Reg->DPC_CURRENT_REG; + Info.DPC__STATUS_REG = &g_Reg->DPC_STATUS_REG; + Info.DPC__CLOCK_REG = &g_Reg->DPC_CLOCK_REG; + Info.DPC__BUFBUSY_REG = &g_Reg->DPC_BUFBUSY_REG; + Info.DPC__PIPEBUSY_REG = &g_Reg->DPC_PIPEBUSY_REG; + Info.DPC__TMEM_REG = &g_Reg->DPC_TMEM_REG; + } + + InitiateRSP(Info, &m_CycleCount); + m_Initialized = true; + +#ifdef _WIN32 + //jabo had a bug so I call CreateThread so his dllmain gets called again + pjutil::DynLibCallDllMain(); +#endif + return m_Initialized; +} + +void CRSP_Plugin::UnloadPluginDetails(void) +{ + memset(&m_RSPDebug, 0, sizeof(m_RSPDebug)); + DoRspCycles = NULL; + EnableDebugging = NULL; + GetDebugInfo = NULL; + InitiateDebugger = NULL; +} + +void CRSP_Plugin::ProcessMenuItem(int id) +{ + if (m_RSPDebug.ProcessMenuItem) + { + m_RSPDebug.ProcessMenuItem(id); + } } \ No newline at end of file diff --git a/Source/Project64-core/Plugins/RSPPlugin.h b/Source/Project64-core/Plugins/RSPPlugin.h index 1fa8401f2..2f38c658e 100644 --- a/Source/Project64-core/Plugins/RSPPlugin.h +++ b/Source/Project64-core/Plugins/RSPPlugin.h @@ -1,77 +1,77 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include - -class CRSP_Plugin : public CPlugin -{ - typedef struct { - /* Menu */ - /* Items should have an ID between 5001 and 5100 */ - void * hRSPMenu; - void(CALL *ProcessMenuItem) (int32_t ID); - - /* Break Points */ - int32_t UseBPoints; - char BPPanelName[20]; - void(CALL *Add_BPoint) (void); - void(CALL *CreateBPPanel) (void); - void(CALL *HideBPPanel) (void); - void(CALL *PaintBPPanel) (void); - void(CALL *ShowBPPanel) (void); - void(CALL *RefreshBpoints) (void * hList); - void(CALL *RemoveBpoint) (void * hList, int32_t index); - void(CALL *RemoveAllBpoint) (void); - - /* RSP command Window */ - void(CALL *Enter_RSP_Commands_Window)(void); - } RSPDEBUG_INFO; - - typedef struct { - void(CALL *UpdateBreakPoints)(void); - void(CALL *UpdateMemory)(void); - void(CALL *UpdateR4300iRegisters)(void); - void(CALL *Enter_BPoint_Window)(void); - void(CALL *Enter_R4300i_Commands_Window)(void); - void(CALL *Enter_R4300i_Register_Window)(void); - void(CALL *Enter_RSP_Commands_Window)(void); - void(CALL *Enter_Memory_Window)(void); - } DEBUG_INFO; - -public: - CRSP_Plugin(void); - ~CRSP_Plugin(); - - bool Initiate(CPlugins * Plugins, CN64System * System); - - uint32_t(CALL *DoRspCycles)(uint32_t); - void(CALL *EnableDebugging)(int32_t Enable); - - void * GetDebugMenu(void) { return m_RSPDebug.hRSPMenu; } - void ProcessMenuItem(int32_t id); - -private: - CRSP_Plugin(const CRSP_Plugin&); // Disable copy constructor - CRSP_Plugin& operator=(const CRSP_Plugin&); // Disable assignment - - PLUGIN_TYPE type() { return PLUGIN_TYPE_RSP; } - virtual int32_t GetDefaultSettingStartRange() const { return FirstRSPDefaultSet; } - virtual int32_t GetSettingStartRange() const { return FirstRSPSettings; } - - bool LoadFunctions(void); - void UnloadPluginDetails(void); - - RSPDEBUG_INFO m_RSPDebug; - uint32_t m_CycleCount; - - void(CALL *GetDebugInfo) (RSPDEBUG_INFO * GFXDebugInfo); - void(CALL *InitiateDebugger)(DEBUG_INFO DebugInfo); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +class CRSP_Plugin : public CPlugin +{ + typedef struct { + /* Menu */ + /* Items should have an ID between 5001 and 5100 */ + void * hRSPMenu; + void(CALL *ProcessMenuItem) (int32_t ID); + + /* Break Points */ + int32_t UseBPoints; + char BPPanelName[20]; + void(CALL *Add_BPoint) (void); + void(CALL *CreateBPPanel) (void); + void(CALL *HideBPPanel) (void); + void(CALL *PaintBPPanel) (void); + void(CALL *ShowBPPanel) (void); + void(CALL *RefreshBpoints) (void * hList); + void(CALL *RemoveBpoint) (void * hList, int32_t index); + void(CALL *RemoveAllBpoint) (void); + + /* RSP command Window */ + void(CALL *Enter_RSP_Commands_Window)(void); + } RSPDEBUG_INFO; + + typedef struct { + void(CALL *UpdateBreakPoints)(void); + void(CALL *UpdateMemory)(void); + void(CALL *UpdateR4300iRegisters)(void); + void(CALL *Enter_BPoint_Window)(void); + void(CALL *Enter_R4300i_Commands_Window)(void); + void(CALL *Enter_R4300i_Register_Window)(void); + void(CALL *Enter_RSP_Commands_Window)(void); + void(CALL *Enter_Memory_Window)(void); + } DEBUG_INFO; + +public: + CRSP_Plugin(void); + ~CRSP_Plugin(); + + bool Initiate(CPlugins * Plugins, CN64System * System); + + uint32_t(CALL *DoRspCycles)(uint32_t); + void(CALL *EnableDebugging)(int32_t Enable); + + void * GetDebugMenu(void) { return m_RSPDebug.hRSPMenu; } + void ProcessMenuItem(int32_t id); + +private: + CRSP_Plugin(const CRSP_Plugin&); // Disable copy constructor + CRSP_Plugin& operator=(const CRSP_Plugin&); // Disable assignment + + PLUGIN_TYPE type() { return PLUGIN_TYPE_RSP; } + virtual int32_t GetDefaultSettingStartRange() const { return FirstRSPDefaultSet; } + virtual int32_t GetSettingStartRange() const { return FirstRSPSettings; } + + bool LoadFunctions(void); + void UnloadPluginDetails(void); + + RSPDEBUG_INFO m_RSPDebug; + uint32_t m_CycleCount; + + void(CALL *GetDebugInfo) (RSPDEBUG_INFO * GFXDebugInfo); + void(CALL *InitiateDebugger)(DEBUG_INFO DebugInfo); +}; diff --git a/Source/Project64-core/Settings/DebugSettings.cpp b/Source/Project64-core/Settings/DebugSettings.cpp index a78f15d8a..7112c9055 100644 --- a/Source/Project64-core/Settings/DebugSettings.cpp +++ b/Source/Project64-core/Settings/DebugSettings.cpp @@ -1,55 +1,55 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "DebugSettings.h" - -int CDebugSettings::m_RefCount = 0; - -bool CDebugSettings::m_bHaveDebugger = false; -bool CDebugSettings::m_bLogX86Code = false; -bool CDebugSettings::m_bShowTLBMisses = false; -bool CDebugSettings::m_bShowDivByZero = false; -bool CDebugSettings::m_Registered = false; - -CDebugSettings::CDebugSettings() -{ - m_RefCount += 1; - if (!m_Registered && g_Settings) - { - m_Registered = true; - g_Settings->RegisterChangeCB(Debugger_Enabled, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - g_Settings->RegisterChangeCB(Debugger_GenerateLogFiles, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - g_Settings->RegisterChangeCB(Debugger_ShowTLBMisses, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - g_Settings->RegisterChangeCB(Debugger_ShowDivByZero, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - - RefreshSettings(); - } -} - -CDebugSettings::~CDebugSettings() -{ - m_RefCount -= 1; - if (m_RefCount == 0 && g_Settings) - { - g_Settings->UnregisterChangeCB(Debugger_Enabled, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - g_Settings->UnregisterChangeCB(Debugger_GenerateLogFiles, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - g_Settings->UnregisterChangeCB(Debugger_ShowTLBMisses, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - g_Settings->UnregisterChangeCB(Debugger_ShowDivByZero, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - } -} - -void CDebugSettings::RefreshSettings() -{ - m_bHaveDebugger = g_Settings->LoadBool(Debugger_Enabled); - m_bLogX86Code = m_bHaveDebugger && g_Settings->LoadBool(Debugger_GenerateLogFiles); - m_bShowTLBMisses = m_bHaveDebugger && g_Settings->LoadBool(Debugger_ShowTLBMisses); - m_bShowDivByZero = m_bHaveDebugger && g_Settings->LoadBool(Debugger_ShowDivByZero); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "DebugSettings.h" + +int CDebugSettings::m_RefCount = 0; + +bool CDebugSettings::m_bHaveDebugger = false; +bool CDebugSettings::m_bLogX86Code = false; +bool CDebugSettings::m_bShowTLBMisses = false; +bool CDebugSettings::m_bShowDivByZero = false; +bool CDebugSettings::m_Registered = false; + +CDebugSettings::CDebugSettings() +{ + m_RefCount += 1; + if (!m_Registered && g_Settings) + { + m_Registered = true; + g_Settings->RegisterChangeCB(Debugger_Enabled, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + g_Settings->RegisterChangeCB(Debugger_GenerateLogFiles, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + g_Settings->RegisterChangeCB(Debugger_ShowTLBMisses, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + g_Settings->RegisterChangeCB(Debugger_ShowDivByZero, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + + RefreshSettings(); + } +} + +CDebugSettings::~CDebugSettings() +{ + m_RefCount -= 1; + if (m_RefCount == 0 && g_Settings) + { + g_Settings->UnregisterChangeCB(Debugger_Enabled, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + g_Settings->UnregisterChangeCB(Debugger_GenerateLogFiles, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + g_Settings->UnregisterChangeCB(Debugger_ShowTLBMisses, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + g_Settings->UnregisterChangeCB(Debugger_ShowDivByZero, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + } +} + +void CDebugSettings::RefreshSettings() +{ + m_bHaveDebugger = g_Settings->LoadBool(Debugger_Enabled); + m_bLogX86Code = m_bHaveDebugger && g_Settings->LoadBool(Debugger_GenerateLogFiles); + m_bShowTLBMisses = m_bHaveDebugger && g_Settings->LoadBool(Debugger_ShowTLBMisses); + m_bShowDivByZero = m_bHaveDebugger && g_Settings->LoadBool(Debugger_ShowDivByZero); } \ No newline at end of file diff --git a/Source/Project64-core/Settings/DebugSettings.h b/Source/Project64-core/Settings/DebugSettings.h index d82d89f52..ee3a7eef6 100644 --- a/Source/Project64-core/Settings/DebugSettings.h +++ b/Source/Project64-core/Settings/DebugSettings.h @@ -1,42 +1,42 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CDebugSettings -{ -public: - CDebugSettings(); - virtual ~CDebugSettings(); - - static inline bool bHaveDebugger(void) { return m_bHaveDebugger; } - static inline bool bLogX86Code(void) { return m_bLogX86Code; } - static inline bool bShowTLBMisses(void) { return m_bShowTLBMisses; } - static inline bool bShowDivByZero(void) { return m_bShowDivByZero; } - -private: - static void StaticRefreshSettings(CDebugSettings * _this) - { - _this->RefreshSettings(); - } - - void RefreshSettings(void); - - //Settings that can be changed on the fly - static bool m_bHaveDebugger; - static bool m_bLogX86Code; - static bool m_bShowTLBMisses; - static bool m_bShowDivByZero; - - static int32_t m_RefCount; - static bool m_Registered; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CDebugSettings +{ +public: + CDebugSettings(); + virtual ~CDebugSettings(); + + static inline bool bHaveDebugger(void) { return m_bHaveDebugger; } + static inline bool bLogX86Code(void) { return m_bLogX86Code; } + static inline bool bShowTLBMisses(void) { return m_bShowTLBMisses; } + static inline bool bShowDivByZero(void) { return m_bShowDivByZero; } + +private: + static void StaticRefreshSettings(CDebugSettings * _this) + { + _this->RefreshSettings(); + } + + void RefreshSettings(void); + + //Settings that can be changed on the fly + static bool m_bHaveDebugger; + static bool m_bLogX86Code; + static bool m_bShowTLBMisses; + static bool m_bShowDivByZero; + + static int32_t m_RefCount; + static bool m_Registered; +}; diff --git a/Source/Project64-core/Settings/GameSettings.cpp b/Source/Project64-core/Settings/GameSettings.cpp index c29c3e552..e09fd5ac0 100644 --- a/Source/Project64-core/Settings/GameSettings.cpp +++ b/Source/Project64-core/Settings/GameSettings.cpp @@ -1,78 +1,78 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include - -bool CGameSettings::m_bSMM_StoreInstruc; -bool CGameSettings::m_bSMM_Protect; -bool CGameSettings::m_bSMM_ValidFunc; -bool CGameSettings::m_bSMM_PIDMA; -bool CGameSettings::m_bSMM_TLB; -bool CGameSettings::m_bUseTlb; -uint32_t CGameSettings::m_CountPerOp = 2; -uint32_t CGameSettings::m_ViRefreshRate = 1500; -uint32_t CGameSettings::m_AiCountPerBytes = 500; -bool CGameSettings::m_DelayDP = false; -bool CGameSettings::m_DelaySI = false; -uint32_t CGameSettings::m_RdramSize = 0; -bool CGameSettings::m_bFixedAudio = true; -bool CGameSettings::m_bSyncingToAudio = true; -bool CGameSettings::m_bSyncToAudio = true; -bool CGameSettings::m_bFastSP = true; -bool CGameSettings::m_b32Bit = true; -bool CGameSettings::m_RspAudioSignal; -bool CGameSettings::m_bRomInMemory; -bool CGameSettings::m_RegCaching; -bool CGameSettings::m_bLinkBlocks; -uint32_t CGameSettings::m_LookUpMode; //FUNC_LOOKUP_METHOD -SYSTEM_TYPE CGameSettings::m_SystemType = SYSTEM_NTSC; -CPU_TYPE CGameSettings::m_CpuType = CPU_Recompiler; - -void CGameSettings::RefreshGameSettings() -{ - m_bSMM_StoreInstruc = false /*g_Settings->LoadBool(Game_SMM_StoreInstruc)*/; - m_bSMM_Protect = g_Settings->LoadBool(Game_SMM_Protect); - m_bSMM_ValidFunc = g_Settings->LoadBool(Game_SMM_ValidFunc); - m_bSMM_PIDMA = g_Settings->LoadBool(Game_SMM_PIDMA); - m_bSMM_TLB = g_Settings->LoadBool(Game_SMM_TLB); - m_bUseTlb = g_Settings->LoadBool(Game_UseTlb); - m_ViRefreshRate = g_Settings->LoadDword(Game_ViRefreshRate); - m_AiCountPerBytes = g_Settings->LoadDword(Game_AiCountPerBytes); - m_CountPerOp = g_Settings->LoadDword(Game_CounterFactor); - m_RdramSize = g_Settings->LoadDword(Game_RDRamSize); - m_DelaySI = g_Settings->LoadBool(Game_DelaySI); - m_DelayDP = g_Settings->LoadBool(Game_DelayDP); - m_bFixedAudio = g_Settings->LoadBool(Game_FixedAudio); - m_bSyncToAudio = m_bFixedAudio ? g_Settings->LoadBool(Game_SyncViaAudio) : false; - m_b32Bit = g_Settings->LoadBool(Game_32Bit); - m_bFastSP = g_Settings->LoadBool(Game_FastSP); - m_RspAudioSignal = g_Settings->LoadBool(Game_RspAudioSignal); - m_bRomInMemory = g_Settings->LoadBool(Game_LoadRomToMemory); - m_RegCaching = g_Settings->LoadBool(Game_RegCache); - m_bLinkBlocks = g_Settings->LoadBool(Game_BlockLinking); - m_LookUpMode = g_Settings->LoadDword(Game_FuncLookupMode); - m_SystemType = (SYSTEM_TYPE)g_Settings->LoadDword(Game_SystemType); - m_CpuType = (CPU_TYPE)g_Settings->LoadDword(Game_CpuType); - - m_bSyncingToAudio = m_bSyncToAudio; - if (m_CountPerOp == 0) - { - m_CountPerOp = 2; - } -} - -void CGameSettings::SpeedChanged(int SpeedLimit) -{ - int FullSpeed = g_System->m_SystemType == SYSTEM_PAL ? 50 : 60; - m_bSyncingToAudio = SpeedLimit == FullSpeed ? m_bSyncToAudio : false; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include + +bool CGameSettings::m_bSMM_StoreInstruc; +bool CGameSettings::m_bSMM_Protect; +bool CGameSettings::m_bSMM_ValidFunc; +bool CGameSettings::m_bSMM_PIDMA; +bool CGameSettings::m_bSMM_TLB; +bool CGameSettings::m_bUseTlb; +uint32_t CGameSettings::m_CountPerOp = 2; +uint32_t CGameSettings::m_ViRefreshRate = 1500; +uint32_t CGameSettings::m_AiCountPerBytes = 500; +bool CGameSettings::m_DelayDP = false; +bool CGameSettings::m_DelaySI = false; +uint32_t CGameSettings::m_RdramSize = 0; +bool CGameSettings::m_bFixedAudio = true; +bool CGameSettings::m_bSyncingToAudio = true; +bool CGameSettings::m_bSyncToAudio = true; +bool CGameSettings::m_bFastSP = true; +bool CGameSettings::m_b32Bit = true; +bool CGameSettings::m_RspAudioSignal; +bool CGameSettings::m_bRomInMemory; +bool CGameSettings::m_RegCaching; +bool CGameSettings::m_bLinkBlocks; +uint32_t CGameSettings::m_LookUpMode; //FUNC_LOOKUP_METHOD +SYSTEM_TYPE CGameSettings::m_SystemType = SYSTEM_NTSC; +CPU_TYPE CGameSettings::m_CpuType = CPU_Recompiler; + +void CGameSettings::RefreshGameSettings() +{ + m_bSMM_StoreInstruc = false /*g_Settings->LoadBool(Game_SMM_StoreInstruc)*/; + m_bSMM_Protect = g_Settings->LoadBool(Game_SMM_Protect); + m_bSMM_ValidFunc = g_Settings->LoadBool(Game_SMM_ValidFunc); + m_bSMM_PIDMA = g_Settings->LoadBool(Game_SMM_PIDMA); + m_bSMM_TLB = g_Settings->LoadBool(Game_SMM_TLB); + m_bUseTlb = g_Settings->LoadBool(Game_UseTlb); + m_ViRefreshRate = g_Settings->LoadDword(Game_ViRefreshRate); + m_AiCountPerBytes = g_Settings->LoadDword(Game_AiCountPerBytes); + m_CountPerOp = g_Settings->LoadDword(Game_CounterFactor); + m_RdramSize = g_Settings->LoadDword(Game_RDRamSize); + m_DelaySI = g_Settings->LoadBool(Game_DelaySI); + m_DelayDP = g_Settings->LoadBool(Game_DelayDP); + m_bFixedAudio = g_Settings->LoadBool(Game_FixedAudio); + m_bSyncToAudio = m_bFixedAudio ? g_Settings->LoadBool(Game_SyncViaAudio) : false; + m_b32Bit = g_Settings->LoadBool(Game_32Bit); + m_bFastSP = g_Settings->LoadBool(Game_FastSP); + m_RspAudioSignal = g_Settings->LoadBool(Game_RspAudioSignal); + m_bRomInMemory = g_Settings->LoadBool(Game_LoadRomToMemory); + m_RegCaching = g_Settings->LoadBool(Game_RegCache); + m_bLinkBlocks = g_Settings->LoadBool(Game_BlockLinking); + m_LookUpMode = g_Settings->LoadDword(Game_FuncLookupMode); + m_SystemType = (SYSTEM_TYPE)g_Settings->LoadDword(Game_SystemType); + m_CpuType = (CPU_TYPE)g_Settings->LoadDword(Game_CpuType); + + m_bSyncingToAudio = m_bSyncToAudio; + if (m_CountPerOp == 0) + { + m_CountPerOp = 2; + } +} + +void CGameSettings::SpeedChanged(int SpeedLimit) +{ + int FullSpeed = g_System->m_SystemType == SYSTEM_PAL ? 50 : 60; + m_bSyncingToAudio = SpeedLimit == FullSpeed ? m_bSyncToAudio : false; } \ No newline at end of file diff --git a/Source/Project64-core/Settings/GameSettings.h b/Source/Project64-core/Settings/GameSettings.h index 737014f27..e1cc1dc4e 100644 --- a/Source/Project64-core/Settings/GameSettings.h +++ b/Source/Project64-core/Settings/GameSettings.h @@ -1,73 +1,73 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CGameSettings -{ -public: - void RefreshGameSettings(void); - - inline static bool bRomInMemory(void) { return m_bRomInMemory; } - inline static bool bRegCaching(void) { return m_RegCaching; } - inline static bool bLinkBlocks(void) { return m_bLinkBlocks; } - inline static FUNC_LOOKUP_METHOD LookUpMode(void) { return (FUNC_LOOKUP_METHOD)m_LookUpMode; } - inline static bool bUseTlb(void) { return m_bUseTlb; } - inline static uint32_t CountPerOp(void) { return m_CountPerOp; } - inline static uint32_t ViRefreshRate(void) { return m_ViRefreshRate; } - inline static uint32_t AiCountPerBytes(void) { return m_AiCountPerBytes; } - inline static bool bDelayDP(void) { return m_DelayDP; } - inline static bool bDelaySI(void) { return m_DelaySI; } - inline static uint32_t RdramSize(void) { return m_RdramSize; } - inline static bool bFixedAudio(void) { return m_bFixedAudio; } - inline static bool bSyncToAudio(void) { return m_bSyncingToAudio; } - inline static bool bFastSP(void) { return m_bFastSP; } - inline static bool b32BitCore(void) { return m_b32Bit; } - inline static bool RspAudioSignal(void) { return m_RspAudioSignal; } - inline static bool bSMM_StoreInstruc(void) { return m_bSMM_StoreInstruc; } - inline static bool bSMM_Protect(void) { return m_bSMM_Protect; } - inline static bool bSMM_ValidFunc(void) { return m_bSMM_ValidFunc; } - inline static bool bSMM_PIDMA(void) { return m_bSMM_PIDMA; } - inline static bool bSMM_TLB(void) { return m_bSMM_TLB; } - inline static SYSTEM_TYPE SystemType(void) { return m_SystemType; } - inline static CPU_TYPE CpuType(void) { return m_CpuType; } - -protected: - static void SpeedChanged(int32_t SpeedLimit); - -private: - //Settings that can be changed on the fly - static bool m_bRomInMemory; - static bool m_RegCaching; - static bool m_bLinkBlocks; - static uint32_t m_LookUpMode; //FUNC_LOOKUP_METHOD - static bool m_bUseTlb; - static uint32_t m_CountPerOp; - static uint32_t m_ViRefreshRate; - static uint32_t m_AiCountPerBytes; - static bool m_DelayDP; - static bool m_DelaySI; - static uint32_t m_RdramSize; - static bool m_bFixedAudio; - static bool m_bSyncingToAudio; - static bool m_bSyncToAudio; - static bool m_bFastSP; - static bool m_b32Bit; - static bool m_RspAudioSignal; - static bool m_bSMM_StoreInstruc; - static bool m_bSMM_Protect; - static bool m_bSMM_ValidFunc; - static bool m_bSMM_PIDMA; - static bool m_bSMM_TLB; - static SYSTEM_TYPE m_SystemType; - static CPU_TYPE m_CpuType; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CGameSettings +{ +public: + void RefreshGameSettings(void); + + inline static bool bRomInMemory(void) { return m_bRomInMemory; } + inline static bool bRegCaching(void) { return m_RegCaching; } + inline static bool bLinkBlocks(void) { return m_bLinkBlocks; } + inline static FUNC_LOOKUP_METHOD LookUpMode(void) { return (FUNC_LOOKUP_METHOD)m_LookUpMode; } + inline static bool bUseTlb(void) { return m_bUseTlb; } + inline static uint32_t CountPerOp(void) { return m_CountPerOp; } + inline static uint32_t ViRefreshRate(void) { return m_ViRefreshRate; } + inline static uint32_t AiCountPerBytes(void) { return m_AiCountPerBytes; } + inline static bool bDelayDP(void) { return m_DelayDP; } + inline static bool bDelaySI(void) { return m_DelaySI; } + inline static uint32_t RdramSize(void) { return m_RdramSize; } + inline static bool bFixedAudio(void) { return m_bFixedAudio; } + inline static bool bSyncToAudio(void) { return m_bSyncingToAudio; } + inline static bool bFastSP(void) { return m_bFastSP; } + inline static bool b32BitCore(void) { return m_b32Bit; } + inline static bool RspAudioSignal(void) { return m_RspAudioSignal; } + inline static bool bSMM_StoreInstruc(void) { return m_bSMM_StoreInstruc; } + inline static bool bSMM_Protect(void) { return m_bSMM_Protect; } + inline static bool bSMM_ValidFunc(void) { return m_bSMM_ValidFunc; } + inline static bool bSMM_PIDMA(void) { return m_bSMM_PIDMA; } + inline static bool bSMM_TLB(void) { return m_bSMM_TLB; } + inline static SYSTEM_TYPE SystemType(void) { return m_SystemType; } + inline static CPU_TYPE CpuType(void) { return m_CpuType; } + +protected: + static void SpeedChanged(int32_t SpeedLimit); + +private: + //Settings that can be changed on the fly + static bool m_bRomInMemory; + static bool m_RegCaching; + static bool m_bLinkBlocks; + static uint32_t m_LookUpMode; //FUNC_LOOKUP_METHOD + static bool m_bUseTlb; + static uint32_t m_CountPerOp; + static uint32_t m_ViRefreshRate; + static uint32_t m_AiCountPerBytes; + static bool m_DelayDP; + static bool m_DelaySI; + static uint32_t m_RdramSize; + static bool m_bFixedAudio; + static bool m_bSyncingToAudio; + static bool m_bSyncToAudio; + static bool m_bFastSP; + static bool m_b32Bit; + static bool m_RspAudioSignal; + static bool m_bSMM_StoreInstruc; + static bool m_bSMM_Protect; + static bool m_bSMM_ValidFunc; + static bool m_bSMM_PIDMA; + static bool m_bSMM_TLB; + static SYSTEM_TYPE m_SystemType; + static CPU_TYPE m_CpuType; +}; diff --git a/Source/Project64-core/Settings/N64SystemSettings.cpp b/Source/Project64-core/Settings/N64SystemSettings.cpp index cf0c8113d..f76ab634c 100644 --- a/Source/Project64-core/Settings/N64SystemSettings.cpp +++ b/Source/Project64-core/Settings/N64SystemSettings.cpp @@ -1,66 +1,66 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "N64SystemSettings.h" - -int32_t CN64SystemSettings::m_RefCount = 0; - -bool CN64SystemSettings::m_bShowCPUPer; -bool CN64SystemSettings::m_bProfiling; -bool CN64SystemSettings::m_bBasicMode; -bool CN64SystemSettings::m_bLimitFPS; -bool CN64SystemSettings::m_bShowDListAListCount; -bool CN64SystemSettings::m_bDisplayFrameRate; - -CN64SystemSettings::CN64SystemSettings() -{ - m_RefCount += 1; - if (m_RefCount == 1) - { - g_Settings->RegisterChangeCB(UserInterface_BasicMode, NULL, RefreshSettings); - g_Settings->RegisterChangeCB(UserInterface_ShowCPUPer, NULL, RefreshSettings); - g_Settings->RegisterChangeCB(UserInterface_DisplayFrameRate, NULL, RefreshSettings); - - g_Settings->RegisterChangeCB(Debugger_ProfileCode, NULL, RefreshSettings); - g_Settings->RegisterChangeCB(Debugger_ShowDListAListCount, NULL, RefreshSettings); - - g_Settings->RegisterChangeCB(GameRunning_LimitFPS, NULL, RefreshSettings); - - RefreshSettings(NULL); - } -} - -CN64SystemSettings::~CN64SystemSettings() -{ - m_RefCount -= 1; - if (m_RefCount == 0) - { - g_Settings->UnregisterChangeCB(UserInterface_BasicMode, NULL, RefreshSettings); - g_Settings->UnregisterChangeCB(UserInterface_DisplayFrameRate, NULL, RefreshSettings); - g_Settings->UnregisterChangeCB(UserInterface_ShowCPUPer, NULL, RefreshSettings); - - g_Settings->UnregisterChangeCB(Debugger_ProfileCode, NULL, RefreshSettings); - g_Settings->UnregisterChangeCB(Debugger_ShowDListAListCount, NULL, RefreshSettings); - - g_Settings->UnregisterChangeCB(GameRunning_LimitFPS, NULL, RefreshSettings); - } -} - -void CN64SystemSettings::RefreshSettings(void *) -{ - m_bBasicMode = g_Settings->LoadBool(UserInterface_BasicMode); - m_bDisplayFrameRate = g_Settings->LoadBool(UserInterface_DisplayFrameRate); - - m_bShowCPUPer = g_Settings->LoadBool(UserInterface_ShowCPUPer); - m_bProfiling = g_Settings->LoadBool(Debugger_ProfileCode); - m_bShowDListAListCount = g_Settings->LoadBool(Debugger_ShowDListAListCount); - m_bLimitFPS = g_Settings->LoadBool(GameRunning_LimitFPS); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "N64SystemSettings.h" + +int32_t CN64SystemSettings::m_RefCount = 0; + +bool CN64SystemSettings::m_bShowCPUPer; +bool CN64SystemSettings::m_bProfiling; +bool CN64SystemSettings::m_bBasicMode; +bool CN64SystemSettings::m_bLimitFPS; +bool CN64SystemSettings::m_bShowDListAListCount; +bool CN64SystemSettings::m_bDisplayFrameRate; + +CN64SystemSettings::CN64SystemSettings() +{ + m_RefCount += 1; + if (m_RefCount == 1) + { + g_Settings->RegisterChangeCB(UserInterface_BasicMode, NULL, RefreshSettings); + g_Settings->RegisterChangeCB(UserInterface_ShowCPUPer, NULL, RefreshSettings); + g_Settings->RegisterChangeCB(UserInterface_DisplayFrameRate, NULL, RefreshSettings); + + g_Settings->RegisterChangeCB(Debugger_ProfileCode, NULL, RefreshSettings); + g_Settings->RegisterChangeCB(Debugger_ShowDListAListCount, NULL, RefreshSettings); + + g_Settings->RegisterChangeCB(GameRunning_LimitFPS, NULL, RefreshSettings); + + RefreshSettings(NULL); + } +} + +CN64SystemSettings::~CN64SystemSettings() +{ + m_RefCount -= 1; + if (m_RefCount == 0) + { + g_Settings->UnregisterChangeCB(UserInterface_BasicMode, NULL, RefreshSettings); + g_Settings->UnregisterChangeCB(UserInterface_DisplayFrameRate, NULL, RefreshSettings); + g_Settings->UnregisterChangeCB(UserInterface_ShowCPUPer, NULL, RefreshSettings); + + g_Settings->UnregisterChangeCB(Debugger_ProfileCode, NULL, RefreshSettings); + g_Settings->UnregisterChangeCB(Debugger_ShowDListAListCount, NULL, RefreshSettings); + + g_Settings->UnregisterChangeCB(GameRunning_LimitFPS, NULL, RefreshSettings); + } +} + +void CN64SystemSettings::RefreshSettings(void *) +{ + m_bBasicMode = g_Settings->LoadBool(UserInterface_BasicMode); + m_bDisplayFrameRate = g_Settings->LoadBool(UserInterface_DisplayFrameRate); + + m_bShowCPUPer = g_Settings->LoadBool(UserInterface_ShowCPUPer); + m_bProfiling = g_Settings->LoadBool(Debugger_ProfileCode); + m_bShowDListAListCount = g_Settings->LoadBool(Debugger_ShowDListAListCount); + m_bLimitFPS = g_Settings->LoadBool(GameRunning_LimitFPS); } \ No newline at end of file diff --git a/Source/Project64-core/Settings/N64SystemSettings.h b/Source/Project64-core/Settings/N64SystemSettings.h index 3944aa826..9daeaa247 100644 --- a/Source/Project64-core/Settings/N64SystemSettings.h +++ b/Source/Project64-core/Settings/N64SystemSettings.h @@ -1,37 +1,37 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CN64SystemSettings -{ -protected: - CN64SystemSettings(); - virtual ~CN64SystemSettings(); - - inline static bool bBasicMode(void) { return m_bBasicMode; } - inline static bool bDisplayFrameRate(void) { return m_bDisplayFrameRate; } - inline static bool bShowCPUPer(void) { return m_bShowCPUPer; } - inline static bool bProfiling(void) { return m_bProfiling; } - inline static bool bShowDListAListCount(void) { return m_bShowDListAListCount; } - inline static bool bLimitFPS(void) { return m_bLimitFPS; } - -private: - static void RefreshSettings(void *); - - static bool m_bShowCPUPer; - static bool m_bProfiling; - static bool m_bBasicMode; - static bool m_bLimitFPS; - static bool m_bShowDListAListCount; - static bool m_bDisplayFrameRate; - - static int32_t m_RefCount; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CN64SystemSettings +{ +protected: + CN64SystemSettings(); + virtual ~CN64SystemSettings(); + + inline static bool bBasicMode(void) { return m_bBasicMode; } + inline static bool bDisplayFrameRate(void) { return m_bDisplayFrameRate; } + inline static bool bShowCPUPer(void) { return m_bShowCPUPer; } + inline static bool bProfiling(void) { return m_bProfiling; } + inline static bool bShowDListAListCount(void) { return m_bShowDListAListCount; } + inline static bool bLimitFPS(void) { return m_bLimitFPS; } + +private: + static void RefreshSettings(void *); + + static bool m_bShowCPUPer; + static bool m_bProfiling; + static bool m_bBasicMode; + static bool m_bLimitFPS; + static bool m_bShowDListAListCount; + static bool m_bDisplayFrameRate; + + static int32_t m_RefCount; +}; diff --git a/Source/Project64-core/Settings/RecompilerSettings.h b/Source/Project64-core/Settings/RecompilerSettings.h index 5b28782be..1b1f75806 100644 --- a/Source/Project64-core/Settings/RecompilerSettings.h +++ b/Source/Project64-core/Settings/RecompilerSettings.h @@ -1,38 +1,38 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CRecompilerSettings -{ -public: - CRecompilerSettings(); - virtual ~CRecompilerSettings(); - - static bool bShowRecompMemSize(void) { return m_bShowRecompMemSize; } - - static bool bProfiling(void) { return m_bProfiling; } - -private: - static void StaticRefreshSettings(CRecompilerSettings * _this) - { - _this->RefreshSettings(); - } - - void RefreshSettings(void); - - //Settings that can be changed on the fly - static bool m_bShowRecompMemSize; - static bool m_bProfiling; - - static int32_t m_RefCount; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CRecompilerSettings +{ +public: + CRecompilerSettings(); + virtual ~CRecompilerSettings(); + + static bool bShowRecompMemSize(void) { return m_bShowRecompMemSize; } + + static bool bProfiling(void) { return m_bProfiling; } + +private: + static void StaticRefreshSettings(CRecompilerSettings * _this) + { + _this->RefreshSettings(); + } + + void RefreshSettings(void); + + //Settings that can be changed on the fly + static bool m_bShowRecompMemSize; + static bool m_bProfiling; + + static int32_t m_RefCount; +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-Application.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-Application.cpp index 08294dbe9..17ba22f80 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-Application.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-Application.cpp @@ -1,260 +1,260 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-Application.h" -#include - -CIniFile * CSettingTypeApplication::m_SettingsIniFile = NULL; - -CSettingTypeApplication::CSettingTypeApplication(const char * Section, const char * Name, uint32_t DefaultValue ) : - m_DefaultStr(""), - m_DefaultValue(DefaultValue), - m_DefaultSetting(Default_Constant), - m_Section(FixSectionName(Section)), - m_KeyName(Name), - m_KeyNameIdex(m_KeyName) -{ -} - -CSettingTypeApplication::CSettingTypeApplication(const char * Section, const char * Name, bool DefaultValue ) : - m_DefaultStr(""), - m_DefaultValue(DefaultValue), - m_DefaultSetting(Default_Constant), - m_Section(FixSectionName(Section)), - m_KeyName(Name), - m_KeyNameIdex(m_KeyName) -{ -} - -CSettingTypeApplication::CSettingTypeApplication(const char * Section, const char * Name, const char * DefaultValue ) : - m_DefaultStr(DefaultValue), - m_DefaultValue(0), - m_DefaultSetting(Default_Constant), - m_Section(FixSectionName(Section)), - m_KeyName(Name), - m_KeyNameIdex(m_KeyName) -{ -} - -CSettingTypeApplication::CSettingTypeApplication(const char * Section, const char * Name, SettingID DefaultSetting ) : - m_DefaultStr(""), - m_DefaultValue(0), - m_DefaultSetting(DefaultSetting), - m_Section(FixSectionName(Section)), - m_KeyName(Name), - m_KeyNameIdex(m_KeyName) -{ -} - -CSettingTypeApplication::~CSettingTypeApplication() -{ -} - -void CSettingTypeApplication::Initialize( const char * /*AppName*/ ) -{ - CPath BaseDir(g_Settings->LoadStringVal(Cmd_BaseDirectory).c_str(),""); - if (!BaseDir.DirectoryExists()) - { - printf("BaseDir does not exists, doing nothing"); - return; - } - - stdstr SettingsFile, OrigSettingsFile; - - for (int i = 0; i < 100; i++) - { - OrigSettingsFile = SettingsFile; - if (!g_Settings->LoadStringVal(SupportFile_Settings,SettingsFile) && i > 0) - { - break; - } - if (SettingsFile == OrigSettingsFile) - { - break; - } - if (m_SettingsIniFile) - { - delete m_SettingsIniFile; - } -#ifdef _WIN32 - CPath SettingsDir(CPath(SettingsFile).GetDriveDirectory(),""); -#else - CPath SettingsDir(CPath(SettingsFile).GetDirectory(), ""); -#endif - if (!SettingsDir.DirectoryExists()) - { - SettingsDir.DirectoryCreate(); - } - - m_SettingsIniFile = new CIniFile(SettingsFile.c_str()); - } - - m_SettingsIniFile->SetAutoFlush(false); -} - -void CSettingTypeApplication::Flush() -{ - if (m_SettingsIniFile) - { - m_SettingsIniFile->FlushChanges(); - } -} - -void CSettingTypeApplication::CleanUp() -{ - if (m_SettingsIniFile) - { - m_SettingsIniFile->SetAutoFlush(true); - delete m_SettingsIniFile; - m_SettingsIniFile = NULL; - } -} - -bool CSettingTypeApplication::Load ( int /*Index*/, bool & Value ) const -{ - bool bRes = false; - - uint32_t dwValue; - bRes = m_SettingsIniFile->GetNumber(SectionName(),m_KeyNameIdex.c_str(),Value,dwValue); - if (bRes) - { - Value = dwValue != 0; - } - - if (!bRes && m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue != 0; - } - else - { - g_Settings->LoadBool(m_DefaultSetting,Value); - } - } - return bRes; -} - -bool CSettingTypeApplication::Load ( int /*Index*/, uint32_t & Value ) const -{ - bool bRes = m_SettingsIniFile->GetNumber(SectionName(),m_KeyNameIdex.c_str(),Value,Value); - if (!bRes && m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue; - } - else - { - g_Settings->LoadDword(m_DefaultSetting,Value); - } - } - return bRes; -} - -const char * CSettingTypeApplication::SectionName ( void ) const -{ - return m_Section.c_str(); -} - -bool CSettingTypeApplication::Load ( int Index, stdstr & Value ) const -{ - bool bRes = m_SettingsIniFile ? m_SettingsIniFile->GetString(SectionName(),m_KeyNameIdex.c_str(),m_DefaultStr,Value) : false; - if (!bRes) - { - CSettingTypeApplication::LoadDefault(Index,Value); - } - return bRes; -} - -//return the default values -void CSettingTypeApplication::LoadDefault ( int /*Index*/, bool & Value ) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue != 0; - } - else - { - g_Settings->LoadBool(m_DefaultSetting,Value); - } - } -} - -void CSettingTypeApplication::LoadDefault(int /*Index*/, uint32_t & Value) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue; - } - else - { - g_Settings->LoadDword(m_DefaultSetting,Value); - } - } -} - -void CSettingTypeApplication::LoadDefault ( int /*Index*/, stdstr & Value ) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultStr; - } - else - { - g_Settings->LoadStringVal(m_DefaultSetting,Value); - } - } -} - -//Update the settings -void CSettingTypeApplication::Save ( int /*Index*/, bool Value ) -{ - m_SettingsIniFile->SaveNumber(SectionName(),m_KeyNameIdex.c_str(),Value); -} - -void CSettingTypeApplication::Save ( int /*Index*/, uint32_t Value ) -{ - m_SettingsIniFile->SaveNumber(SectionName(),m_KeyNameIdex.c_str(),Value); -} - -void CSettingTypeApplication::Save ( int /*Index*/, const stdstr & Value ) -{ - m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),Value.c_str()); -} - -void CSettingTypeApplication::Save ( int /*Index*/, const char * Value ) -{ - m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),Value); -} - -stdstr CSettingTypeApplication::FixSectionName(const char * Section) -{ - stdstr SectionName(Section); - - if (SectionName.empty()) - { - SectionName = "default"; - } - SectionName.Replace("\\","-"); - return SectionName; -} - -void CSettingTypeApplication::Delete( int /*Index*/ ) -{ - m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),NULL); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-Application.h" +#include + +CIniFile * CSettingTypeApplication::m_SettingsIniFile = NULL; + +CSettingTypeApplication::CSettingTypeApplication(const char * Section, const char * Name, uint32_t DefaultValue ) : + m_DefaultStr(""), + m_DefaultValue(DefaultValue), + m_DefaultSetting(Default_Constant), + m_Section(FixSectionName(Section)), + m_KeyName(Name), + m_KeyNameIdex(m_KeyName) +{ +} + +CSettingTypeApplication::CSettingTypeApplication(const char * Section, const char * Name, bool DefaultValue ) : + m_DefaultStr(""), + m_DefaultValue(DefaultValue), + m_DefaultSetting(Default_Constant), + m_Section(FixSectionName(Section)), + m_KeyName(Name), + m_KeyNameIdex(m_KeyName) +{ +} + +CSettingTypeApplication::CSettingTypeApplication(const char * Section, const char * Name, const char * DefaultValue ) : + m_DefaultStr(DefaultValue), + m_DefaultValue(0), + m_DefaultSetting(Default_Constant), + m_Section(FixSectionName(Section)), + m_KeyName(Name), + m_KeyNameIdex(m_KeyName) +{ +} + +CSettingTypeApplication::CSettingTypeApplication(const char * Section, const char * Name, SettingID DefaultSetting ) : + m_DefaultStr(""), + m_DefaultValue(0), + m_DefaultSetting(DefaultSetting), + m_Section(FixSectionName(Section)), + m_KeyName(Name), + m_KeyNameIdex(m_KeyName) +{ +} + +CSettingTypeApplication::~CSettingTypeApplication() +{ +} + +void CSettingTypeApplication::Initialize( const char * /*AppName*/ ) +{ + CPath BaseDir(g_Settings->LoadStringVal(Cmd_BaseDirectory).c_str(),""); + if (!BaseDir.DirectoryExists()) + { + printf("BaseDir does not exists, doing nothing"); + return; + } + + stdstr SettingsFile, OrigSettingsFile; + + for (int i = 0; i < 100; i++) + { + OrigSettingsFile = SettingsFile; + if (!g_Settings->LoadStringVal(SupportFile_Settings,SettingsFile) && i > 0) + { + break; + } + if (SettingsFile == OrigSettingsFile) + { + break; + } + if (m_SettingsIniFile) + { + delete m_SettingsIniFile; + } +#ifdef _WIN32 + CPath SettingsDir(CPath(SettingsFile).GetDriveDirectory(),""); +#else + CPath SettingsDir(CPath(SettingsFile).GetDirectory(), ""); +#endif + if (!SettingsDir.DirectoryExists()) + { + SettingsDir.DirectoryCreate(); + } + + m_SettingsIniFile = new CIniFile(SettingsFile.c_str()); + } + + m_SettingsIniFile->SetAutoFlush(false); +} + +void CSettingTypeApplication::Flush() +{ + if (m_SettingsIniFile) + { + m_SettingsIniFile->FlushChanges(); + } +} + +void CSettingTypeApplication::CleanUp() +{ + if (m_SettingsIniFile) + { + m_SettingsIniFile->SetAutoFlush(true); + delete m_SettingsIniFile; + m_SettingsIniFile = NULL; + } +} + +bool CSettingTypeApplication::Load ( int /*Index*/, bool & Value ) const +{ + bool bRes = false; + + uint32_t dwValue; + bRes = m_SettingsIniFile->GetNumber(SectionName(),m_KeyNameIdex.c_str(),Value,dwValue); + if (bRes) + { + Value = dwValue != 0; + } + + if (!bRes && m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } + else + { + g_Settings->LoadBool(m_DefaultSetting,Value); + } + } + return bRes; +} + +bool CSettingTypeApplication::Load ( int /*Index*/, uint32_t & Value ) const +{ + bool bRes = m_SettingsIniFile->GetNumber(SectionName(),m_KeyNameIdex.c_str(),Value,Value); + if (!bRes && m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } + else + { + g_Settings->LoadDword(m_DefaultSetting,Value); + } + } + return bRes; +} + +const char * CSettingTypeApplication::SectionName ( void ) const +{ + return m_Section.c_str(); +} + +bool CSettingTypeApplication::Load ( int Index, stdstr & Value ) const +{ + bool bRes = m_SettingsIniFile ? m_SettingsIniFile->GetString(SectionName(),m_KeyNameIdex.c_str(),m_DefaultStr,Value) : false; + if (!bRes) + { + CSettingTypeApplication::LoadDefault(Index,Value); + } + return bRes; +} + +//return the default values +void CSettingTypeApplication::LoadDefault ( int /*Index*/, bool & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } + else + { + g_Settings->LoadBool(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeApplication::LoadDefault(int /*Index*/, uint32_t & Value) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } + else + { + g_Settings->LoadDword(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeApplication::LoadDefault ( int /*Index*/, stdstr & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultStr; + } + else + { + g_Settings->LoadStringVal(m_DefaultSetting,Value); + } + } +} + +//Update the settings +void CSettingTypeApplication::Save ( int /*Index*/, bool Value ) +{ + m_SettingsIniFile->SaveNumber(SectionName(),m_KeyNameIdex.c_str(),Value); +} + +void CSettingTypeApplication::Save ( int /*Index*/, uint32_t Value ) +{ + m_SettingsIniFile->SaveNumber(SectionName(),m_KeyNameIdex.c_str(),Value); +} + +void CSettingTypeApplication::Save ( int /*Index*/, const stdstr & Value ) +{ + m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),Value.c_str()); +} + +void CSettingTypeApplication::Save ( int /*Index*/, const char * Value ) +{ + m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),Value); +} + +stdstr CSettingTypeApplication::FixSectionName(const char * Section) +{ + stdstr SectionName(Section); + + if (SectionName.empty()) + { + SectionName = "default"; + } + SectionName.Replace("\\","-"); + return SectionName; +} + +void CSettingTypeApplication::Delete( int /*Index*/ ) +{ + m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),NULL); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-Application.h b/Source/Project64-core/Settings/SettingType/SettingsType-Application.h index 9412a8e3a..d8614b342 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-Application.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-Application.h @@ -1,72 +1,72 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include -#include - -class CSettingTypeApplication : - public CSettingType -{ -public: - CSettingTypeApplication(const char * Section, const char * Name, const char * DefaultValue); - CSettingTypeApplication(const char * Section, const char * Name, bool DefaultValue); - CSettingTypeApplication(const char * Section, const char * Name, uint32_t DefaultValue); - CSettingTypeApplication(const char * Section, const char * Name, SettingID DefaultSetting); - virtual ~CSettingTypeApplication(); - - virtual bool IndexBasedSetting(void) const { return false; } - virtual SettingType GetSettingType(void) const { return SettingType_CfgFile; } - - //return the values - virtual bool Load(int32_t Index, bool & Value) const; - virtual bool Load(int32_t Index, uint32_t & Value) const; - virtual bool Load(int32_t Index, stdstr & Value) const; - - //return the default values - virtual void LoadDefault(int32_t Index, bool & Value) const; - virtual void LoadDefault(int32_t Index, uint32_t & Value) const; - virtual void LoadDefault(int32_t Index, stdstr & Value) const; - - //Update the settings - virtual void Save(int32_t Index, bool Value); - virtual void Save(int32_t Index, uint32_t Value); - virtual void Save(int32_t Index, const stdstr & Value); - virtual void Save(int32_t Index, const char * Value); - - // Delete the setting - virtual void Delete(int32_t Index); - - // Initialize this class to use ini or registry - static void Initialize(const char * AppName); - static void CleanUp(void); - static void Flush(void); - - const char * GetKeyName(void) const { return m_KeyName.c_str(); } - -protected: - const char * m_DefaultStr; - const uint32_t m_DefaultValue; - const SettingID m_DefaultSetting; - - stdstr FixSectionName(const char * Section); - - static CIniFile * m_SettingsIniFile; - const stdstr m_Section; - const stdstr m_KeyName; - mutable stdstr m_KeyNameIdex; - - virtual const char * SectionName(void) const; - -private: - CSettingTypeApplication(const CSettingTypeApplication&); // Disable copy constructor - CSettingTypeApplication& operator=(const CSettingTypeApplication&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include +#include + +class CSettingTypeApplication : + public CSettingType +{ +public: + CSettingTypeApplication(const char * Section, const char * Name, const char * DefaultValue); + CSettingTypeApplication(const char * Section, const char * Name, bool DefaultValue); + CSettingTypeApplication(const char * Section, const char * Name, uint32_t DefaultValue); + CSettingTypeApplication(const char * Section, const char * Name, SettingID DefaultSetting); + virtual ~CSettingTypeApplication(); + + virtual bool IndexBasedSetting(void) const { return false; } + virtual SettingType GetSettingType(void) const { return SettingType_CfgFile; } + + //return the values + virtual bool Load(int32_t Index, bool & Value) const; + virtual bool Load(int32_t Index, uint32_t & Value) const; + virtual bool Load(int32_t Index, stdstr & Value) const; + + //return the default values + virtual void LoadDefault(int32_t Index, bool & Value) const; + virtual void LoadDefault(int32_t Index, uint32_t & Value) const; + virtual void LoadDefault(int32_t Index, stdstr & Value) const; + + //Update the settings + virtual void Save(int32_t Index, bool Value); + virtual void Save(int32_t Index, uint32_t Value); + virtual void Save(int32_t Index, const stdstr & Value); + virtual void Save(int32_t Index, const char * Value); + + // Delete the setting + virtual void Delete(int32_t Index); + + // Initialize this class to use ini or registry + static void Initialize(const char * AppName); + static void CleanUp(void); + static void Flush(void); + + const char * GetKeyName(void) const { return m_KeyName.c_str(); } + +protected: + const char * m_DefaultStr; + const uint32_t m_DefaultValue; + const SettingID m_DefaultSetting; + + stdstr FixSectionName(const char * Section); + + static CIniFile * m_SettingsIniFile; + const stdstr m_Section; + const stdstr m_KeyName; + mutable stdstr m_KeyNameIdex; + + virtual const char * SectionName(void) const; + +private: + CSettingTypeApplication(const CSettingTypeApplication&); // Disable copy constructor + CSettingTypeApplication& operator=(const CSettingTypeApplication&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationIndex.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationIndex.cpp index c84cd20cd..e9fe50d46 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationIndex.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationIndex.cpp @@ -1,105 +1,105 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-Application.h" -#include "SettingsType-ApplicationIndex.h" - -CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(const char * Section, const char * Name, uint32_t DefaultValue ) : - CSettingTypeApplication(Section,Name,DefaultValue) -{ -} - -CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(const char * Section, const char * Name, bool DefaultValue ) : - CSettingTypeApplication(Section,Name,DefaultValue) -{ -} - -CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(const char * Section, const char * Name, const char * DefaultValue ) : - CSettingTypeApplication(Section,Name,DefaultValue) -{ -} - -CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(const char * Section, const char * Name, SettingID DefaultSetting ) : - CSettingTypeApplication(Section,Name,DefaultSetting) -{ -} - -CSettingTypeApplicationIndex::~CSettingTypeApplicationIndex ( void ) -{ -} - -bool CSettingTypeApplicationIndex::Load ( int Index, bool & Value ) const -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - return CSettingTypeApplication::Load(0,Value); -} - -bool CSettingTypeApplicationIndex::Load ( int Index, uint32_t & Value ) const -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - return CSettingTypeApplication::Load(0,Value); -} - -bool CSettingTypeApplicationIndex::Load ( int Index, stdstr & Value ) const -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - return CSettingTypeApplication::Load(0,Value); -} - -//return the default values -void CSettingTypeApplicationIndex::LoadDefault ( int Index, bool & Value ) const -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - CSettingTypeApplication::LoadDefault(0,Value); -} - -void CSettingTypeApplicationIndex::LoadDefault ( int Index, uint32_t & Value ) const -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - CSettingTypeApplication::LoadDefault(0,Value); -} - -void CSettingTypeApplicationIndex::LoadDefault ( int Index, stdstr & Value ) const -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - CSettingTypeApplication::LoadDefault(0,Value); -} - -//Update the settings -void CSettingTypeApplicationIndex::Save ( int Index, bool Value ) -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - CSettingTypeApplication::Save(0,Value); -} - -void CSettingTypeApplicationIndex::Save ( int Index, uint32_t Value ) -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - CSettingTypeApplication::Save(0,Value); -} - -void CSettingTypeApplicationIndex::Save ( int Index, const stdstr & Value ) -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - CSettingTypeApplication::Save(0,Value); -} - -void CSettingTypeApplicationIndex::Save ( int Index, const char * Value ) -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - CSettingTypeApplication::Save(0,Value); -} - -void CSettingTypeApplicationIndex::Delete ( int Index ) -{ - m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); - CSettingTypeApplication::Save(0,(const char *)NULL); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-Application.h" +#include "SettingsType-ApplicationIndex.h" + +CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(const char * Section, const char * Name, uint32_t DefaultValue ) : + CSettingTypeApplication(Section,Name,DefaultValue) +{ +} + +CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(const char * Section, const char * Name, bool DefaultValue ) : + CSettingTypeApplication(Section,Name,DefaultValue) +{ +} + +CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(const char * Section, const char * Name, const char * DefaultValue ) : + CSettingTypeApplication(Section,Name,DefaultValue) +{ +} + +CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(const char * Section, const char * Name, SettingID DefaultSetting ) : + CSettingTypeApplication(Section,Name,DefaultSetting) +{ +} + +CSettingTypeApplicationIndex::~CSettingTypeApplicationIndex ( void ) +{ +} + +bool CSettingTypeApplicationIndex::Load ( int Index, bool & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + return CSettingTypeApplication::Load(0,Value); +} + +bool CSettingTypeApplicationIndex::Load ( int Index, uint32_t & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + return CSettingTypeApplication::Load(0,Value); +} + +bool CSettingTypeApplicationIndex::Load ( int Index, stdstr & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + return CSettingTypeApplication::Load(0,Value); +} + +//return the default values +void CSettingTypeApplicationIndex::LoadDefault ( int Index, bool & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::LoadDefault(0,Value); +} + +void CSettingTypeApplicationIndex::LoadDefault ( int Index, uint32_t & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::LoadDefault(0,Value); +} + +void CSettingTypeApplicationIndex::LoadDefault ( int Index, stdstr & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::LoadDefault(0,Value); +} + +//Update the settings +void CSettingTypeApplicationIndex::Save ( int Index, bool Value ) +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::Save(0,Value); +} + +void CSettingTypeApplicationIndex::Save ( int Index, uint32_t Value ) +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::Save(0,Value); +} + +void CSettingTypeApplicationIndex::Save ( int Index, const stdstr & Value ) +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::Save(0,Value); +} + +void CSettingTypeApplicationIndex::Save ( int Index, const char * Value ) +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::Save(0,Value); +} + +void CSettingTypeApplicationIndex::Delete ( int Index ) +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::Save(0,(const char *)NULL); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationIndex.h b/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationIndex.h index c195d0738..02660299d 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationIndex.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationIndex.h @@ -1,48 +1,48 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeApplicationIndex : - public CSettingTypeApplication -{ -public: - CSettingTypeApplicationIndex(const char * Section, const char * Name, const char * DefaultValue ); - CSettingTypeApplicationIndex(const char * Section, const char * Name, bool DefaultValue ); - CSettingTypeApplicationIndex(const char * Section, const char * Name, uint32_t DefaultValue ); - CSettingTypeApplicationIndex(const char * Section, const char * Name, SettingID DefaultSetting ); - ~CSettingTypeApplicationIndex(); - - virtual bool IndexBasedSetting ( void ) const { return true; } - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeApplicationIndex(void); // Disable default constructor - CSettingTypeApplicationIndex(const CSettingTypeApplicationIndex&); // Disable copy constructor - CSettingTypeApplicationIndex& operator=(const CSettingTypeApplicationIndex&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeApplicationIndex : + public CSettingTypeApplication +{ +public: + CSettingTypeApplicationIndex(const char * Section, const char * Name, const char * DefaultValue ); + CSettingTypeApplicationIndex(const char * Section, const char * Name, bool DefaultValue ); + CSettingTypeApplicationIndex(const char * Section, const char * Name, uint32_t DefaultValue ); + CSettingTypeApplicationIndex(const char * Section, const char * Name, SettingID DefaultSetting ); + ~CSettingTypeApplicationIndex(); + + virtual bool IndexBasedSetting ( void ) const { return true; } + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeApplicationIndex(void); // Disable default constructor + CSettingTypeApplicationIndex(const CSettingTypeApplicationIndex&); // Disable copy constructor + CSettingTypeApplicationIndex& operator=(const CSettingTypeApplicationIndex&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationPath.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationPath.cpp index 5b2cf754d..080bb6c37 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationPath.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationPath.cpp @@ -1,44 +1,44 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-Application.h" -#include "SettingsType-ApplicationPath.h" -#include - -CSettingTypeApplicationPath::CSettingTypeApplicationPath(const char * Section, const char * Name, SettingID DefaultSetting ) : - CSettingTypeApplication(Section,Name,DefaultSetting) -{ - -} - -CSettingTypeApplicationPath::~CSettingTypeApplicationPath() -{ -} - -bool CSettingTypeApplicationPath::Load ( int Index, stdstr & Value ) const -{ - bool bRes = CSettingTypeApplication::Load(Index,Value); -#ifdef WIN32 - if (bRes) - { - if (Value.substr(0,2) == ".\\" || Value.substr(0,2) == "./" || - Value.substr(0,3) == "..\\" || Value.substr(0,3) == "../") - { - CPath FullFilePath(CPath::MODULE_DIRECTORY), RelativePath(Value); - FullFilePath.SetNameExtension(RelativePath.GetNameExtension().c_str()); - FullFilePath.AppendDirectory(RelativePath.GetDirectory().c_str()); - - Value = (const std::string &)FullFilePath; - } - } -#endif - return bRes; -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-Application.h" +#include "SettingsType-ApplicationPath.h" +#include + +CSettingTypeApplicationPath::CSettingTypeApplicationPath(const char * Section, const char * Name, SettingID DefaultSetting ) : + CSettingTypeApplication(Section,Name,DefaultSetting) +{ + +} + +CSettingTypeApplicationPath::~CSettingTypeApplicationPath() +{ +} + +bool CSettingTypeApplicationPath::Load ( int Index, stdstr & Value ) const +{ + bool bRes = CSettingTypeApplication::Load(Index,Value); +#ifdef WIN32 + if (bRes) + { + if (Value.substr(0,2) == ".\\" || Value.substr(0,2) == "./" || + Value.substr(0,3) == "..\\" || Value.substr(0,3) == "../") + { + CPath FullFilePath(CPath::MODULE_DIRECTORY), RelativePath(Value); + FullFilePath.SetNameExtension(RelativePath.GetNameExtension().c_str()); + FullFilePath.AppendDirectory(RelativePath.GetDirectory().c_str()); + + Value = (const std::string &)FullFilePath; + } + } +#endif + return bRes; +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationPath.h b/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationPath.h index e2e369501..585c6aa40 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationPath.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-ApplicationPath.h @@ -1,32 +1,32 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeApplicationPath : - public CSettingTypeApplication -{ -public: - virtual ~CSettingTypeApplicationPath(); - - CSettingTypeApplicationPath(const char * Section, const char * Name, SettingID DefaultSetting ); - - //return the values - virtual bool Load ( int32_t Index, stdstr & Value ) const; - -private: - CSettingTypeApplicationPath(void); // Disable default constructor - CSettingTypeApplicationPath(const CSettingTypeApplicationPath&); // Disable copy constructor - CSettingTypeApplicationPath& operator=(const CSettingTypeApplicationPath&); // Disable assignment - - CSettingTypeApplicationPath(const char * Section, const char * Name, const char * DefaultValue ); - CSettingTypeApplicationPath(const char * Section, const char * Name, bool DefaultValue ); - CSettingTypeApplicationPath(const char * Section, const char * Name, uint32_t DefaultValue ); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeApplicationPath : + public CSettingTypeApplication +{ +public: + virtual ~CSettingTypeApplicationPath(); + + CSettingTypeApplicationPath(const char * Section, const char * Name, SettingID DefaultSetting ); + + //return the values + virtual bool Load ( int32_t Index, stdstr & Value ) const; + +private: + CSettingTypeApplicationPath(void); // Disable default constructor + CSettingTypeApplicationPath(const CSettingTypeApplicationPath&); // Disable copy constructor + CSettingTypeApplicationPath& operator=(const CSettingTypeApplicationPath&); // Disable assignment + + CSettingTypeApplicationPath(const char * Section, const char * Name, const char * DefaultValue ); + CSettingTypeApplicationPath(const char * Section, const char * Name, bool DefaultValue ); + CSettingTypeApplicationPath(const char * Section, const char * Name, uint32_t DefaultValue ); +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-Base.h b/Source/Project64-core/Settings/SettingType/SettingsType-Base.h index c0c78233c..a3910449c 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-Base.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-Base.h @@ -1,61 +1,61 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include -#include - -enum SettingType -{ - SettingType_Unknown = -1, - SettingType_ConstString = 0, - SettingType_ConstValue = 1, - SettingType_CfgFile = 2, - SettingType_Registry = 3, - SettingType_RelativePath = 4, - TemporarySetting = 5, - SettingType_RomDatabase = 6, - SettingType_CheatSetting = 7, - SettingType_GameSetting = 8, - SettingType_BoolVariable = 9, - SettingType_NumberVariable = 10, - SettingType_StringVariable = 11, - SettingType_SelectedDirectory = 12, - SettingType_RdbSetting = 13, -}; - -class CSettingType -{ -public: - virtual ~CSettingType() {}; - - virtual SettingType GetSettingType ( void ) const = 0; - virtual bool IndexBasedSetting ( void ) const = 0; - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const = 0; - virtual bool Load ( int32_t Index, uint32_t & Value ) const = 0; - virtual bool Load ( int32_t Index, stdstr & Value ) const = 0; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const = 0; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const = 0; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const = 0; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ) = 0; - virtual void Save ( int32_t Index, uint32_t Value ) = 0; - virtual void Save ( int32_t Index, const stdstr & Value ) = 0; - virtual void Save ( int32_t Index, const char * Value ) = 0; - - // Delete the setting - virtual void Delete ( int32_t Index ) = 0; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include +#include + +enum SettingType +{ + SettingType_Unknown = -1, + SettingType_ConstString = 0, + SettingType_ConstValue = 1, + SettingType_CfgFile = 2, + SettingType_Registry = 3, + SettingType_RelativePath = 4, + TemporarySetting = 5, + SettingType_RomDatabase = 6, + SettingType_CheatSetting = 7, + SettingType_GameSetting = 8, + SettingType_BoolVariable = 9, + SettingType_NumberVariable = 10, + SettingType_StringVariable = 11, + SettingType_SelectedDirectory = 12, + SettingType_RdbSetting = 13, +}; + +class CSettingType +{ +public: + virtual ~CSettingType() {}; + + virtual SettingType GetSettingType ( void ) const = 0; + virtual bool IndexBasedSetting ( void ) const = 0; + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const = 0; + virtual bool Load ( int32_t Index, uint32_t & Value ) const = 0; + virtual bool Load ( int32_t Index, stdstr & Value ) const = 0; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const = 0; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const = 0; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const = 0; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ) = 0; + virtual void Save ( int32_t Index, uint32_t Value ) = 0; + virtual void Save ( int32_t Index, const stdstr & Value ) = 0; + virtual void Save ( int32_t Index, const char * Value ) = 0; + + // Delete the setting + virtual void Delete ( int32_t Index ) = 0; +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.cpp index 85cba3966..f457addc8 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.cpp @@ -1,148 +1,148 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-Cheats.h" - - - -CIniFile * CSettingTypeCheats::m_CheatIniFile = NULL; -stdstr * CSettingTypeCheats::m_SectionIdent = NULL; - -CSettingTypeCheats::CSettingTypeCheats(const char * PostFix ) : - m_PostFix(PostFix) -{ -} - -CSettingTypeCheats::~CSettingTypeCheats ( void ) -{ -} - -void CSettingTypeCheats::Initialize ( void ) -{ - m_CheatIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Cheats).c_str()); - m_CheatIniFile->SetAutoFlush(false); - g_Settings->RegisterChangeCB(Game_IniKey,NULL,GameChanged); - m_SectionIdent = new stdstr(g_Settings->LoadStringVal(Game_IniKey)); - GameChanged(NULL); -} - -void CSettingTypeCheats::CleanUp ( void ) -{ - if (m_CheatIniFile) - { - m_CheatIniFile->SetAutoFlush(true); - delete m_CheatIniFile; - m_CheatIniFile = NULL; - } - if (m_SectionIdent) - { - delete m_SectionIdent; - m_SectionIdent = NULL; - } -} - -void CSettingTypeCheats::FlushChanges( void ) -{ - if (m_CheatIniFile) - { - m_CheatIniFile->FlushChanges(); - } -} - -void CSettingTypeCheats::GameChanged ( void * /*Data */ ) -{ - *m_SectionIdent = g_Settings->LoadStringVal(Game_IniKey); -} - -/*stdstr CSettingTypeCheats::FixName ( const char * Section, const char * Name ) -{ -} - -const char * CSettingTypeCheats::SectionName ( void ) const -{ -return ""; -} - -void CSettingTypeCheats::UpdateSettings ( void * ) -{ -g_Notify->BreakPoint(__FILE__, __LINE__); -}*/ - -bool CSettingTypeCheats::Load ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeCheats::Load ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeCheats::Load ( int Index, stdstr & Value ) const -{ - if (m_CheatIniFile == NULL) - { - return false; - } - stdstr_f Key("Cheat%d%s",Index,m_PostFix); - return m_CheatIniFile->GetString(m_SectionIdent->c_str(),Key.c_str(),"",Value); -} - -//return the default values -void CSettingTypeCheats::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeCheats::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeCheats::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -//Update the settings -void CSettingTypeCheats::Save ( int /*Index*/, bool /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeCheats::Save ( int /*Index*/, uint32_t /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeCheats::Save ( int Index, const stdstr & Value ) -{ - if (m_CheatIniFile == NULL) { return; } - - stdstr_f Key("Cheat%d%s",Index,m_PostFix); - m_CheatIniFile->SaveString(m_SectionIdent->c_str(),Key.c_str(),Value.c_str()); -} - -void CSettingTypeCheats::Save ( int Index, const char * Value ) -{ - if (m_CheatIniFile == NULL) { return; } - - stdstr_f Key("Cheat%d%s",Index,m_PostFix); - m_CheatIniFile->SaveString(m_SectionIdent->c_str(),Key.c_str(),Value); -} - -void CSettingTypeCheats::Delete ( int Index ) -{ - stdstr_f Key("Cheat%d%s",Index,m_PostFix); - m_CheatIniFile->SaveString(m_SectionIdent->c_str(),Key.c_str(),NULL); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-Cheats.h" + + + +CIniFile * CSettingTypeCheats::m_CheatIniFile = NULL; +stdstr * CSettingTypeCheats::m_SectionIdent = NULL; + +CSettingTypeCheats::CSettingTypeCheats(const char * PostFix ) : + m_PostFix(PostFix) +{ +} + +CSettingTypeCheats::~CSettingTypeCheats ( void ) +{ +} + +void CSettingTypeCheats::Initialize ( void ) +{ + m_CheatIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Cheats).c_str()); + m_CheatIniFile->SetAutoFlush(false); + g_Settings->RegisterChangeCB(Game_IniKey,NULL,GameChanged); + m_SectionIdent = new stdstr(g_Settings->LoadStringVal(Game_IniKey)); + GameChanged(NULL); +} + +void CSettingTypeCheats::CleanUp ( void ) +{ + if (m_CheatIniFile) + { + m_CheatIniFile->SetAutoFlush(true); + delete m_CheatIniFile; + m_CheatIniFile = NULL; + } + if (m_SectionIdent) + { + delete m_SectionIdent; + m_SectionIdent = NULL; + } +} + +void CSettingTypeCheats::FlushChanges( void ) +{ + if (m_CheatIniFile) + { + m_CheatIniFile->FlushChanges(); + } +} + +void CSettingTypeCheats::GameChanged ( void * /*Data */ ) +{ + *m_SectionIdent = g_Settings->LoadStringVal(Game_IniKey); +} + +/*stdstr CSettingTypeCheats::FixName ( const char * Section, const char * Name ) +{ +} + +const char * CSettingTypeCheats::SectionName ( void ) const +{ +return ""; +} + +void CSettingTypeCheats::UpdateSettings ( void * ) +{ +g_Notify->BreakPoint(__FILE__, __LINE__); +}*/ + +bool CSettingTypeCheats::Load ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeCheats::Load ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeCheats::Load ( int Index, stdstr & Value ) const +{ + if (m_CheatIniFile == NULL) + { + return false; + } + stdstr_f Key("Cheat%d%s",Index,m_PostFix); + return m_CheatIniFile->GetString(m_SectionIdent->c_str(),Key.c_str(),"",Value); +} + +//return the default values +void CSettingTypeCheats::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeCheats::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeCheats::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +//Update the settings +void CSettingTypeCheats::Save ( int /*Index*/, bool /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeCheats::Save ( int /*Index*/, uint32_t /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeCheats::Save ( int Index, const stdstr & Value ) +{ + if (m_CheatIniFile == NULL) { return; } + + stdstr_f Key("Cheat%d%s",Index,m_PostFix); + m_CheatIniFile->SaveString(m_SectionIdent->c_str(),Key.c_str(),Value.c_str()); +} + +void CSettingTypeCheats::Save ( int Index, const char * Value ) +{ + if (m_CheatIniFile == NULL) { return; } + + stdstr_f Key("Cheat%d%s",Index,m_PostFix); + m_CheatIniFile->SaveString(m_SectionIdent->c_str(),Key.c_str(),Value); +} + +void CSettingTypeCheats::Delete ( int Index ) +{ + stdstr_f Key("Cheat%d%s",Index,m_PostFix); + m_CheatIniFile->SaveString(m_SectionIdent->c_str(),Key.c_str(),NULL); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.h b/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.h index c78eac2f8..e9cd294be 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.h @@ -1,60 +1,60 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include -#include - -class CSettingTypeCheats : - public CSettingType -{ -public: - CSettingTypeCheats(const char * PostFix ); - ~CSettingTypeCheats(); - - virtual bool IndexBasedSetting ( void ) const { return true; } - virtual SettingType GetSettingType ( void ) const { return SettingType_CheatSetting; } - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - - // Initialize this class to use ini or registry - static void Initialize ( void ); - static void CleanUp ( void ); - static void FlushChanges ( void ); - -protected: - static CIniFile * m_CheatIniFile; - static stdstr * m_SectionIdent; - const char * const m_PostFix; - static void GameChanged ( void * /*Data */ ); - -private: - CSettingTypeCheats(void); // Disable default constructor - CSettingTypeCheats(const CSettingTypeCheats&); // Disable copy constructor - CSettingTypeCheats& operator=(const CSettingTypeCheats&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include +#include + +class CSettingTypeCheats : + public CSettingType +{ +public: + CSettingTypeCheats(const char * PostFix ); + ~CSettingTypeCheats(); + + virtual bool IndexBasedSetting ( void ) const { return true; } + virtual SettingType GetSettingType ( void ) const { return SettingType_CheatSetting; } + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + + // Initialize this class to use ini or registry + static void Initialize ( void ); + static void CleanUp ( void ); + static void FlushChanges ( void ); + +protected: + static CIniFile * m_CheatIniFile; + static stdstr * m_SectionIdent; + const char * const m_PostFix; + static void GameChanged ( void * /*Data */ ); + +private: + CSettingTypeCheats(void); // Disable default constructor + CSettingTypeCheats(const CSettingTypeCheats&); // Disable copy constructor + CSettingTypeCheats& operator=(const CSettingTypeCheats&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-GameSetting.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-GameSetting.cpp index 72f615211..614c224c0 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-GameSetting.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-GameSetting.cpp @@ -1,259 +1,259 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-Application.h" -#include "SettingsType-GameSetting.h" - -bool CSettingTypeGame::m_RdbEditor = false; -bool CSettingTypeGame::m_EraseDefaults = true; -stdstr * CSettingTypeGame::m_SectionIdent = NULL; - -CSettingTypeGame::CSettingTypeGame(const char * Name, const char * DefaultValue ) : - CSettingTypeApplication("",Name,DefaultValue) -{ -} - -CSettingTypeGame::CSettingTypeGame(const char * Name, uint32_t DefaultValue ) : - CSettingTypeApplication("",Name,DefaultValue) -{ -} - -CSettingTypeGame::CSettingTypeGame(const char * Name, SettingID DefaultSetting ) : - CSettingTypeApplication("",Name,DefaultSetting) -{ -} - -CSettingTypeGame::~CSettingTypeGame() -{ -} - -void CSettingTypeGame::Initialize ( void ) -{ - UpdateSettings(NULL); - g_Settings->RegisterChangeCB(Game_IniKey,NULL,UpdateSettings); -} - -void CSettingTypeGame::CleanUp ( void ) -{ - g_Settings->UnregisterChangeCB(Game_IniKey,NULL,UpdateSettings); - if (m_SectionIdent) - { - delete m_SectionIdent; - m_SectionIdent = NULL; - } -} - -const char * CSettingTypeGame::SectionName ( void ) const -{ - return m_SectionIdent ? m_SectionIdent->c_str() : ""; -} - -void CSettingTypeGame::UpdateSettings ( void * /*Data */ ) -{ - m_RdbEditor = g_Settings->LoadBool(Setting_RdbEditor); - m_EraseDefaults = g_Settings->LoadBool(Setting_EraseGameDefaults); - stdstr SectionIdent = g_Settings->LoadStringVal(Game_IniKey); - - if (m_SectionIdent == NULL) - { - m_SectionIdent = new stdstr; - } - if (SectionIdent != *m_SectionIdent) - { - *m_SectionIdent = SectionIdent; - g_Settings->SettingTypeChanged(SettingType_GameSetting); - g_Settings->SettingTypeChanged(SettingType_RomDatabase); - } -} - -bool CSettingTypeGame::Load ( int Index, bool & Value ) const -{ - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - return g_Settings->LoadBoolIndex(m_DefaultSetting,Index,Value); - } else { - return g_Settings->LoadBool(m_DefaultSetting,Value); - } - } - return CSettingTypeApplication::Load(Index,Value); -} - -bool CSettingTypeGame::Load ( int Index, uint32_t & Value ) const -{ - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - return g_Settings->LoadDwordIndex(m_DefaultSetting,Index,Value); - } else { - return g_Settings->LoadDword(m_DefaultSetting,Value); - } - } - return CSettingTypeApplication::Load(Index,Value); -} - -bool CSettingTypeGame::Load ( int Index, stdstr & Value ) const -{ - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - return g_Settings->LoadStringIndex(m_DefaultSetting,Index,Value); - } else { - return g_Settings->LoadStringVal(m_DefaultSetting,Value); - } - } - return CSettingTypeApplication::Load(Index,Value); -} - -//return the default values -void CSettingTypeGame::LoadDefault ( int Index, bool & Value ) const -{ - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - g_Settings->LoadDefaultBoolIndex(m_DefaultSetting,Index,Value); - } else { - g_Settings->LoadDefaultBool(m_DefaultSetting,Value); - } - } else { - CSettingTypeApplication::LoadDefault(Index,Value); - } -} - -void CSettingTypeGame::LoadDefault ( int Index, uint32_t & Value ) const -{ - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - g_Settings->LoadDefaultDwordIndex(m_DefaultSetting,Index,Value); - } else { - g_Settings->LoadDefaultDword(m_DefaultSetting,Value); - } - } else { - CSettingTypeApplication::LoadDefault(Index,Value); - } -} - -void CSettingTypeGame::LoadDefault ( int Index, stdstr & Value ) const -{ - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - g_Settings->LoadDefaultStringIndex(m_DefaultSetting,Index,Value); - } else { - g_Settings->LoadDefaultString(m_DefaultSetting,Value); - } - } else { - CSettingTypeApplication::LoadDefault(Index,Value); - } -} - -//Update the settings -void CSettingTypeGame::Save ( int Index, bool Value ) -{ - if (m_EraseDefaults) - { - bool bDefault; - LoadDefault(Index,bDefault); - if (bDefault == Value) - { - Delete(Index); - return; - } - } - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - g_Settings->SaveBoolIndex(m_DefaultSetting,Index,Value); - } else { - g_Settings->SaveBool(m_DefaultSetting,Value); - } - } else { - CSettingTypeApplication::Save(Index,Value); - } -} - -void CSettingTypeGame::Save ( int Index, uint32_t Value ) -{ - if (m_EraseDefaults) - { - uint32_t ulDefault; - CSettingTypeGame::LoadDefault(Index,ulDefault); - if (ulDefault == Value) - { - Delete(Index); - return; - } - } - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - g_Settings->SaveDwordIndex(m_DefaultSetting,Index,Value); - } else { - g_Settings->SaveDword(m_DefaultSetting,Value); - } - } else { - CSettingTypeApplication::Save(Index,Value); - } -} - -void CSettingTypeGame::Save ( int Index, const stdstr & Value ) -{ - Save(Index,Value.c_str()); -} - -void CSettingTypeGame::Save ( int Index, const char * Value ) -{ - if (m_EraseDefaults && m_DefaultSetting != Rdb_GoodName) - { - stdstr szDefault; - CSettingTypeGame::LoadDefault(Index,szDefault); - if (_stricmp(szDefault.c_str(),Value) == 0) - { - Delete(Index); - return; - } - } - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - g_Settings->SaveStringIndex(m_DefaultSetting,Index,Value); - } else { - g_Settings->SaveString(m_DefaultSetting,Value); - } - } else { - CSettingTypeApplication::Save(Index,Value); - } -} - -void CSettingTypeGame::Delete ( int Index ) -{ - if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) - { - if (g_Settings->IndexBasedSetting(m_DefaultSetting)) - { - g_Settings->DeleteSettingIndex(m_DefaultSetting,Index); - } else { - g_Settings->DeleteSetting(m_DefaultSetting); - } - } else { - CSettingTypeApplication::Delete(Index); - } -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-Application.h" +#include "SettingsType-GameSetting.h" + +bool CSettingTypeGame::m_RdbEditor = false; +bool CSettingTypeGame::m_EraseDefaults = true; +stdstr * CSettingTypeGame::m_SectionIdent = NULL; + +CSettingTypeGame::CSettingTypeGame(const char * Name, const char * DefaultValue ) : + CSettingTypeApplication("",Name,DefaultValue) +{ +} + +CSettingTypeGame::CSettingTypeGame(const char * Name, uint32_t DefaultValue ) : + CSettingTypeApplication("",Name,DefaultValue) +{ +} + +CSettingTypeGame::CSettingTypeGame(const char * Name, SettingID DefaultSetting ) : + CSettingTypeApplication("",Name,DefaultSetting) +{ +} + +CSettingTypeGame::~CSettingTypeGame() +{ +} + +void CSettingTypeGame::Initialize ( void ) +{ + UpdateSettings(NULL); + g_Settings->RegisterChangeCB(Game_IniKey,NULL,UpdateSettings); +} + +void CSettingTypeGame::CleanUp ( void ) +{ + g_Settings->UnregisterChangeCB(Game_IniKey,NULL,UpdateSettings); + if (m_SectionIdent) + { + delete m_SectionIdent; + m_SectionIdent = NULL; + } +} + +const char * CSettingTypeGame::SectionName ( void ) const +{ + return m_SectionIdent ? m_SectionIdent->c_str() : ""; +} + +void CSettingTypeGame::UpdateSettings ( void * /*Data */ ) +{ + m_RdbEditor = g_Settings->LoadBool(Setting_RdbEditor); + m_EraseDefaults = g_Settings->LoadBool(Setting_EraseGameDefaults); + stdstr SectionIdent = g_Settings->LoadStringVal(Game_IniKey); + + if (m_SectionIdent == NULL) + { + m_SectionIdent = new stdstr; + } + if (SectionIdent != *m_SectionIdent) + { + *m_SectionIdent = SectionIdent; + g_Settings->SettingTypeChanged(SettingType_GameSetting); + g_Settings->SettingTypeChanged(SettingType_RomDatabase); + } +} + +bool CSettingTypeGame::Load ( int Index, bool & Value ) const +{ + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + return g_Settings->LoadBoolIndex(m_DefaultSetting,Index,Value); + } else { + return g_Settings->LoadBool(m_DefaultSetting,Value); + } + } + return CSettingTypeApplication::Load(Index,Value); +} + +bool CSettingTypeGame::Load ( int Index, uint32_t & Value ) const +{ + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + return g_Settings->LoadDwordIndex(m_DefaultSetting,Index,Value); + } else { + return g_Settings->LoadDword(m_DefaultSetting,Value); + } + } + return CSettingTypeApplication::Load(Index,Value); +} + +bool CSettingTypeGame::Load ( int Index, stdstr & Value ) const +{ + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + return g_Settings->LoadStringIndex(m_DefaultSetting,Index,Value); + } else { + return g_Settings->LoadStringVal(m_DefaultSetting,Value); + } + } + return CSettingTypeApplication::Load(Index,Value); +} + +//return the default values +void CSettingTypeGame::LoadDefault ( int Index, bool & Value ) const +{ + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + g_Settings->LoadDefaultBoolIndex(m_DefaultSetting,Index,Value); + } else { + g_Settings->LoadDefaultBool(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::LoadDefault(Index,Value); + } +} + +void CSettingTypeGame::LoadDefault ( int Index, uint32_t & Value ) const +{ + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + g_Settings->LoadDefaultDwordIndex(m_DefaultSetting,Index,Value); + } else { + g_Settings->LoadDefaultDword(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::LoadDefault(Index,Value); + } +} + +void CSettingTypeGame::LoadDefault ( int Index, stdstr & Value ) const +{ + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + g_Settings->LoadDefaultStringIndex(m_DefaultSetting,Index,Value); + } else { + g_Settings->LoadDefaultString(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::LoadDefault(Index,Value); + } +} + +//Update the settings +void CSettingTypeGame::Save ( int Index, bool Value ) +{ + if (m_EraseDefaults) + { + bool bDefault; + LoadDefault(Index,bDefault); + if (bDefault == Value) + { + Delete(Index); + return; + } + } + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + g_Settings->SaveBoolIndex(m_DefaultSetting,Index,Value); + } else { + g_Settings->SaveBool(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::Save(Index,Value); + } +} + +void CSettingTypeGame::Save ( int Index, uint32_t Value ) +{ + if (m_EraseDefaults) + { + uint32_t ulDefault; + CSettingTypeGame::LoadDefault(Index,ulDefault); + if (ulDefault == Value) + { + Delete(Index); + return; + } + } + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + g_Settings->SaveDwordIndex(m_DefaultSetting,Index,Value); + } else { + g_Settings->SaveDword(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::Save(Index,Value); + } +} + +void CSettingTypeGame::Save ( int Index, const stdstr & Value ) +{ + Save(Index,Value.c_str()); +} + +void CSettingTypeGame::Save ( int Index, const char * Value ) +{ + if (m_EraseDefaults && m_DefaultSetting != Rdb_GoodName) + { + stdstr szDefault; + CSettingTypeGame::LoadDefault(Index,szDefault); + if (_stricmp(szDefault.c_str(),Value) == 0) + { + Delete(Index); + return; + } + } + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + g_Settings->SaveStringIndex(m_DefaultSetting,Index,Value); + } else { + g_Settings->SaveString(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::Save(Index,Value); + } +} + +void CSettingTypeGame::Delete ( int Index ) +{ + if (m_RdbEditor && g_Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (g_Settings->IndexBasedSetting(m_DefaultSetting)) + { + g_Settings->DeleteSettingIndex(m_DefaultSetting,Index); + } else { + g_Settings->DeleteSetting(m_DefaultSetting); + } + } else { + CSettingTypeApplication::Delete(Index); + } +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-GameSetting.h b/Source/Project64-core/Settings/SettingType/SettingsType-GameSetting.h index 29141e7e0..d35f386e4 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-GameSetting.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-GameSetting.h @@ -1,60 +1,60 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeGame : - public CSettingTypeApplication -{ -protected: - static bool m_RdbEditor; - static bool m_EraseDefaults; - static stdstr * m_SectionIdent; - - static void UpdateSettings ( void * /*Data */ ); - - virtual const char * SectionName ( void ) const; - -public: - CSettingTypeGame(const char * Name, const char * DefaultValue ); - CSettingTypeGame(const char * Name, uint32_t DefaultValue ); - CSettingTypeGame(const char * Name, SettingID DefaultSetting ); - virtual ~CSettingTypeGame(); - - virtual bool IndexBasedSetting ( void ) const { return false; } - virtual SettingType GetSettingType ( void ) const { return SettingType_GameSetting; } - - static void Initialize( void ); - static void CleanUp ( void ); - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeGame(void); // Disable default constructor - CSettingTypeGame(const CSettingTypeGame&); // Disable copy constructor - CSettingTypeGame& operator=(const CSettingTypeGame&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeGame : + public CSettingTypeApplication +{ +protected: + static bool m_RdbEditor; + static bool m_EraseDefaults; + static stdstr * m_SectionIdent; + + static void UpdateSettings ( void * /*Data */ ); + + virtual const char * SectionName ( void ) const; + +public: + CSettingTypeGame(const char * Name, const char * DefaultValue ); + CSettingTypeGame(const char * Name, uint32_t DefaultValue ); + CSettingTypeGame(const char * Name, SettingID DefaultSetting ); + virtual ~CSettingTypeGame(); + + virtual bool IndexBasedSetting ( void ) const { return false; } + virtual SettingType GetSettingType ( void ) const { return SettingType_GameSetting; } + + static void Initialize( void ); + static void CleanUp ( void ); + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeGame(void); // Disable default constructor + CSettingTypeGame(const CSettingTypeGame&); // Disable copy constructor + CSettingTypeGame& operator=(const CSettingTypeGame&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-GameSettingIndex.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-GameSettingIndex.cpp index 3f42fa8e8..f697a2c46 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-GameSettingIndex.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-GameSettingIndex.cpp @@ -1,104 +1,104 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-Application.h" -#include "SettingsType-GameSetting.h" -#include "SettingsType-GameSettingIndex.h" - -CSettingTypeGameIndex::CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, SettingID DefaultSetting ) : - CSettingTypeGame("", DefaultSetting), - m_PreIndex(PreIndex), - m_PostIndex(PostIndex) -{ -} - -CSettingTypeGameIndex::CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, uint32_t DefaultValue ) : - CSettingTypeGame("", DefaultValue), - m_PreIndex(PreIndex), - m_PostIndex(PostIndex) -{ -} - -CSettingTypeGameIndex::CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, const char * DefaultValue ) : - CSettingTypeGame("", DefaultValue), - m_PreIndex(PreIndex), - m_PostIndex(PostIndex) -{ -} - -CSettingTypeGameIndex::~CSettingTypeGameIndex() -{ -} - -bool CSettingTypeGameIndex::Load ( int Index, bool & Value ) const -{ - m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - return CSettingTypeGame::Load(Index,Value); -} - -bool CSettingTypeGameIndex::Load ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeGameIndex::Load ( int Index, stdstr & Value ) const -{ - m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - return CSettingTypeGame::Load(0,Value); -} - -//return the default values -void CSettingTypeGameIndex::LoadDefault ( int Index, bool & Value ) const -{ - m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - CSettingTypeGame::LoadDefault(0,Value); -} - -void CSettingTypeGameIndex::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeGameIndex::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -//Update the settings -void CSettingTypeGameIndex::Save ( int Index, bool Value ) -{ - m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - CSettingTypeGame::Save(Index,Value); -} - -void CSettingTypeGameIndex::Save(int Index, uint32_t Value) -{ - m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - CSettingTypeGame::Save(0,Value); -} - -void CSettingTypeGameIndex::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeGameIndex::Save ( int Index, const char * Value ) -{ - m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - CSettingTypeGame::Save(0,Value); -} - -void CSettingTypeGameIndex::Delete ( int Index ) -{ - m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - CSettingTypeGame::Delete(0); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-Application.h" +#include "SettingsType-GameSetting.h" +#include "SettingsType-GameSettingIndex.h" + +CSettingTypeGameIndex::CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, SettingID DefaultSetting ) : + CSettingTypeGame("", DefaultSetting), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeGameIndex::CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, uint32_t DefaultValue ) : + CSettingTypeGame("", DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeGameIndex::CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, const char * DefaultValue ) : + CSettingTypeGame("", DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeGameIndex::~CSettingTypeGameIndex() +{ +} + +bool CSettingTypeGameIndex::Load ( int Index, bool & Value ) const +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + return CSettingTypeGame::Load(Index,Value); +} + +bool CSettingTypeGameIndex::Load ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeGameIndex::Load ( int Index, stdstr & Value ) const +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + return CSettingTypeGame::Load(0,Value); +} + +//return the default values +void CSettingTypeGameIndex::LoadDefault ( int Index, bool & Value ) const +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeGame::LoadDefault(0,Value); +} + +void CSettingTypeGameIndex::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeGameIndex::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +//Update the settings +void CSettingTypeGameIndex::Save ( int Index, bool Value ) +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeGame::Save(Index,Value); +} + +void CSettingTypeGameIndex::Save(int Index, uint32_t Value) +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeGame::Save(0,Value); +} + +void CSettingTypeGameIndex::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeGameIndex::Save ( int Index, const char * Value ) +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeGame::Save(0,Value); +} + +void CSettingTypeGameIndex::Delete ( int Index ) +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeGame::Delete(0); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-GameSettingIndex.h b/Source/Project64-core/Settings/SettingType/SettingsType-GameSettingIndex.h index 3f36e1fb5..275ed826c 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-GameSettingIndex.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-GameSettingIndex.h @@ -1,50 +1,50 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeGameIndex : - public CSettingTypeGame -{ - stdstr m_PreIndex, m_PostIndex; - -public: - CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, const char * DefaultValue ); - CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, uint32_t DefaultValue ); - CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, SettingID DefaultSetting ); - ~CSettingTypeGameIndex(); - - virtual bool IndexBasedSetting ( void ) const { return true; } - virtual SettingType GetSettingType ( void ) const { return SettingType_GameSetting; } - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeGameIndex(void); // Disable default constructor - CSettingTypeGameIndex(const CSettingTypeGameIndex&); // Disable copy constructor - CSettingTypeGameIndex& operator=(const CSettingTypeGameIndex&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeGameIndex : + public CSettingTypeGame +{ + stdstr m_PreIndex, m_PostIndex; + +public: + CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, const char * DefaultValue ); + CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, uint32_t DefaultValue ); + CSettingTypeGameIndex(const char * PreIndex, const char * PostIndex, SettingID DefaultSetting ); + ~CSettingTypeGameIndex(); + + virtual bool IndexBasedSetting ( void ) const { return true; } + virtual SettingType GetSettingType ( void ) const { return SettingType_GameSetting; } + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeGameIndex(void); // Disable default constructor + CSettingTypeGameIndex(const CSettingTypeGameIndex&); // Disable copy constructor + CSettingTypeGameIndex& operator=(const CSettingTypeGameIndex&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBCpuType.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RDBCpuType.cpp index 7395ec57d..c2a8d859a 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBCpuType.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBCpuType.cpp @@ -1,123 +1,123 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RomDatabase.h" -#include "SettingsType-RDBCpuType.h" -#include - -CSettingTypeRDBCpuType::CSettingTypeRDBCpuType(const char * Name, SettingID DefaultSetting ) : - CSettingTypeRomDatabase(Name,DefaultSetting) -{ -} - -CSettingTypeRDBCpuType::CSettingTypeRDBCpuType(const char * Name, int DefaultValue ) : - CSettingTypeRomDatabase(Name,DefaultValue) -{ -} - -CSettingTypeRDBCpuType::~CSettingTypeRDBCpuType() -{ -} - -bool CSettingTypeRDBCpuType::Load ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeRDBCpuType::Load ( int Index, uint32_t & Value ) const -{ - stdstr strValue; - bool bRes = m_SettingsIniFile->GetString(m_SectionIdent->c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); - if (!bRes) - { - LoadDefault(Index,Value); - return false; - } - const char * String = strValue.c_str(); - - if (_stricmp(String,"Interpreter") == 0) { Value = CPU_Interpreter; } - else if (_stricmp(String,"Recompiler") == 0) { Value = CPU_Recompiler; } - else if (_stricmp(String,"SyncCores") == 0) { Value = CPU_SyncCores; } - else if (_stricmp(String,"default") == 0) - { - LoadDefault(Index,Value); - return false; - } - else { g_Notify->BreakPoint(__FILE__, __LINE__); } - - return true; -} - -bool CSettingTypeRDBCpuType::Load ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -//return the default values -void CSettingTypeRDBCpuType::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBCpuType::LoadDefault ( int /*Index*/, uint32_t & Value ) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue; - } else { - g_Settings->LoadDword(m_DefaultSetting,Value); - } - } -} - -void CSettingTypeRDBCpuType::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -//Update the settings -void CSettingTypeRDBCpuType::Save ( int /*Index*/, bool /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBCpuType::Save ( int /*Index*/, uint32_t Value ) -{ - stdstr strValue; - switch (Value) - { - case CPU_Interpreter: strValue = "Interpreter"; break; - case CPU_Recompiler: strValue = "Recompiler"; break; - case CPU_SyncCores: strValue = "SyncCores"; break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),strValue.c_str()); -} - -void CSettingTypeRDBCpuType::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBCpuType::Save ( int /*Index*/, const char * /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBCpuType::Delete( int /*Index*/ ) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBCpuType.h" +#include + +CSettingTypeRDBCpuType::CSettingTypeRDBCpuType(const char * Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBCpuType::CSettingTypeRDBCpuType(const char * Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + +CSettingTypeRDBCpuType::~CSettingTypeRDBCpuType() +{ +} + +bool CSettingTypeRDBCpuType::Load ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeRDBCpuType::Load ( int Index, uint32_t & Value ) const +{ + stdstr strValue; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent->c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); + if (!bRes) + { + LoadDefault(Index,Value); + return false; + } + const char * String = strValue.c_str(); + + if (_stricmp(String,"Interpreter") == 0) { Value = CPU_Interpreter; } + else if (_stricmp(String,"Recompiler") == 0) { Value = CPU_Recompiler; } + else if (_stricmp(String,"SyncCores") == 0) { Value = CPU_SyncCores; } + else if (_stricmp(String,"default") == 0) + { + LoadDefault(Index,Value); + return false; + } + else { g_Notify->BreakPoint(__FILE__, __LINE__); } + + return true; +} + +bool CSettingTypeRDBCpuType::Load ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBCpuType::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBCpuType::LoadDefault ( int /*Index*/, uint32_t & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } else { + g_Settings->LoadDword(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRDBCpuType::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +//Update the settings +void CSettingTypeRDBCpuType::Save ( int /*Index*/, bool /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBCpuType::Save ( int /*Index*/, uint32_t Value ) +{ + stdstr strValue; + switch (Value) + { + case CPU_Interpreter: strValue = "Interpreter"; break; + case CPU_Recompiler: strValue = "Recompiler"; break; + case CPU_SyncCores: strValue = "SyncCores"; break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),strValue.c_str()); +} + +void CSettingTypeRDBCpuType::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBCpuType::Save ( int /*Index*/, const char * /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBCpuType::Delete( int /*Index*/ ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBCpuType.h b/Source/Project64-core/Settings/SettingType/SettingsType-RDBCpuType.h index 80ea280f4..085602efc 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBCpuType.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBCpuType.h @@ -1,44 +1,44 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeRDBCpuType : - public CSettingTypeRomDatabase -{ -public: - CSettingTypeRDBCpuType(const char * Name, SettingID DefaultSetting ); - CSettingTypeRDBCpuType(const char * Name, int32_t DefaultValue ); - ~CSettingTypeRDBCpuType(); - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeRDBCpuType(void); // Disable default constructor - CSettingTypeRDBCpuType(const CSettingTypeRDBCpuType&); // Disable copy constructor - CSettingTypeRDBCpuType& operator=(const CSettingTypeRDBCpuType&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeRDBCpuType : + public CSettingTypeRomDatabase +{ +public: + CSettingTypeRDBCpuType(const char * Name, SettingID DefaultSetting ); + CSettingTypeRDBCpuType(const char * Name, int32_t DefaultValue ); + ~CSettingTypeRDBCpuType(); + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeRDBCpuType(void); // Disable default constructor + CSettingTypeRDBCpuType(const CSettingTypeRDBCpuType&); // Disable copy constructor + CSettingTypeRDBCpuType& operator=(const CSettingTypeRDBCpuType&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBOnOff.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RDBOnOff.cpp index 1462230ac..0a9e6e3f6 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBOnOff.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBOnOff.cpp @@ -1,112 +1,112 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RomDatabase.h" -#include "SettingsType-RDBOnOff.h" - -CSettingTypeRDBOnOff::CSettingTypeRDBOnOff(const char * Name, SettingID DefaultSetting ) : - CSettingTypeRomDatabase(Name,DefaultSetting) -{ -} - -CSettingTypeRDBOnOff::CSettingTypeRDBOnOff(const char * Name, int DefaultValue ) : - CSettingTypeRomDatabase(Name,DefaultValue) -{ -} - -CSettingTypeRDBOnOff::~CSettingTypeRDBOnOff() -{ -} - -bool CSettingTypeRDBOnOff::Load ( int Index, bool & Value ) const -{ - stdstr strValue; - bool bRes = m_SettingsIniFile->GetString(m_SectionIdent->c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); - if (!bRes) - { - LoadDefault(Index,Value); - return false; - } - const char * String = strValue.c_str(); - - if (_stricmp(String,"On") == 0) { Value = true; } - else if (_stricmp(String,"Off") == 0) { Value = false; } - else if (_stricmp(String,"Global") == 0 || _stricmp(String,"default")) - { - LoadDefault(Index,Value); - return false; - } - else { g_Notify->BreakPoint(__FILE__, __LINE__); } - - return true; -} - -bool CSettingTypeRDBOnOff::Load ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeRDBOnOff::Load ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -//return the default values -void CSettingTypeRDBOnOff::LoadDefault ( int /*Index*/, bool & Value ) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue != 0; - } else { - g_Settings->LoadBool(m_DefaultSetting,Value); - } - } -} - -void CSettingTypeRDBOnOff::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBOnOff::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -//Update the settings -void CSettingTypeRDBOnOff::Save ( int /*Index*/, bool Value ) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),Value? "On" : "Off"); -} - -void CSettingTypeRDBOnOff::Save ( int /*Index*/, uint32_t /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBOnOff::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBOnOff::Save ( int /*Index*/, const char * /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBOnOff::Delete( int /*Index*/ ) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBOnOff.h" + +CSettingTypeRDBOnOff::CSettingTypeRDBOnOff(const char * Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBOnOff::CSettingTypeRDBOnOff(const char * Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + +CSettingTypeRDBOnOff::~CSettingTypeRDBOnOff() +{ +} + +bool CSettingTypeRDBOnOff::Load ( int Index, bool & Value ) const +{ + stdstr strValue; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent->c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); + if (!bRes) + { + LoadDefault(Index,Value); + return false; + } + const char * String = strValue.c_str(); + + if (_stricmp(String,"On") == 0) { Value = true; } + else if (_stricmp(String,"Off") == 0) { Value = false; } + else if (_stricmp(String,"Global") == 0 || _stricmp(String,"default")) + { + LoadDefault(Index,Value); + return false; + } + else { g_Notify->BreakPoint(__FILE__, __LINE__); } + + return true; +} + +bool CSettingTypeRDBOnOff::Load ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeRDBOnOff::Load ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBOnOff::LoadDefault ( int /*Index*/, bool & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } else { + g_Settings->LoadBool(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRDBOnOff::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBOnOff::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +//Update the settings +void CSettingTypeRDBOnOff::Save ( int /*Index*/, bool Value ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),Value? "On" : "Off"); +} + +void CSettingTypeRDBOnOff::Save ( int /*Index*/, uint32_t /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBOnOff::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBOnOff::Save ( int /*Index*/, const char * /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBOnOff::Delete( int /*Index*/ ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBOnOff.h b/Source/Project64-core/Settings/SettingType/SettingsType-RDBOnOff.h index 973f9c426..7fbc99b28 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBOnOff.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBOnOff.h @@ -1,44 +1,44 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeRDBOnOff : - public CSettingTypeRomDatabase -{ -public: - CSettingTypeRDBOnOff(const char * Name, SettingID DefaultSetting ); - CSettingTypeRDBOnOff(const char * Name, int32_t DefaultValue ); - ~CSettingTypeRDBOnOff(); - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeRDBOnOff(void); // Disable default constructor - CSettingTypeRDBOnOff(const CSettingTypeRDBOnOff&); // Disable copy constructor - CSettingTypeRDBOnOff& operator=(const CSettingTypeRDBOnOff&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeRDBOnOff : + public CSettingTypeRomDatabase +{ +public: + CSettingTypeRDBOnOff(const char * Name, SettingID DefaultSetting ); + CSettingTypeRDBOnOff(const char * Name, int32_t DefaultValue ); + ~CSettingTypeRDBOnOff(); + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeRDBOnOff(void); // Disable default constructor + CSettingTypeRDBOnOff(const CSettingTypeRDBOnOff&); // Disable copy constructor + CSettingTypeRDBOnOff& operator=(const CSettingTypeRDBOnOff&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBRamSize.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RDBRamSize.cpp index 3577cb1bc..482213d31 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBRamSize.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBRamSize.cpp @@ -1,99 +1,99 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RomDatabase.h" -#include "SettingsType-RDBRamSize.h" - -// == 8 ? 0x800000 : 0x400000 - -CSettingTypeRDBRDRamSize::CSettingTypeRDBRDRamSize(const char * Name, SettingID DefaultSetting ) : - CSettingTypeRomDatabase(Name,DefaultSetting) -{ -} - -CSettingTypeRDBRDRamSize::CSettingTypeRDBRDRamSize(const char * Name, int DefaultValue ) : - CSettingTypeRomDatabase(Name,DefaultValue) -{ -} - -CSettingTypeRDBRDRamSize::~CSettingTypeRDBRDRamSize() -{ -} - -bool CSettingTypeRDBRDRamSize::Load ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeRDBRDRamSize::Load ( int Index, uint32_t & Value ) const -{ - uint32_t ulValue; - bool bRes = m_SettingsIniFile->GetNumber(m_SectionIdent->c_str(),m_KeyName.c_str(),m_DefaultValue,ulValue); - if (!bRes) - { - LoadDefault(Index,ulValue); - } - Value = 0x400000; - if (ulValue == 8) - { - Value = 0x800000; - } - return bRes; -} - -bool CSettingTypeRDBRDRamSize::Load ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -//return the default values -void CSettingTypeRDBRDRamSize::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBRDRamSize::LoadDefault ( int /*Index*/, uint32_t & Value ) const -{ - Value = m_DefaultValue; -} - -void CSettingTypeRDBRDRamSize::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -//Update the settings -void CSettingTypeRDBRDRamSize::Save ( int /*Index*/, bool /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBRDRamSize::Save ( int /*Index*/, uint32_t Value ) -{ - m_SettingsIniFile->SaveNumber(m_SectionIdent->c_str(),m_KeyName.c_str(),Value == 0x800000 ? 8 : 4); -} - -void CSettingTypeRDBRDRamSize::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBRDRamSize::Save ( int /*Index*/, const char * /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBRDRamSize::Delete( int /*Index*/ ) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBRamSize.h" + +// == 8 ? 0x800000 : 0x400000 + +CSettingTypeRDBRDRamSize::CSettingTypeRDBRDRamSize(const char * Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBRDRamSize::CSettingTypeRDBRDRamSize(const char * Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + +CSettingTypeRDBRDRamSize::~CSettingTypeRDBRDRamSize() +{ +} + +bool CSettingTypeRDBRDRamSize::Load ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeRDBRDRamSize::Load ( int Index, uint32_t & Value ) const +{ + uint32_t ulValue; + bool bRes = m_SettingsIniFile->GetNumber(m_SectionIdent->c_str(),m_KeyName.c_str(),m_DefaultValue,ulValue); + if (!bRes) + { + LoadDefault(Index,ulValue); + } + Value = 0x400000; + if (ulValue == 8) + { + Value = 0x800000; + } + return bRes; +} + +bool CSettingTypeRDBRDRamSize::Load ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBRDRamSize::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBRDRamSize::LoadDefault ( int /*Index*/, uint32_t & Value ) const +{ + Value = m_DefaultValue; +} + +void CSettingTypeRDBRDRamSize::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +//Update the settings +void CSettingTypeRDBRDRamSize::Save ( int /*Index*/, bool /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBRDRamSize::Save ( int /*Index*/, uint32_t Value ) +{ + m_SettingsIniFile->SaveNumber(m_SectionIdent->c_str(),m_KeyName.c_str(),Value == 0x800000 ? 8 : 4); +} + +void CSettingTypeRDBRDRamSize::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBRDRamSize::Save ( int /*Index*/, const char * /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBRDRamSize::Delete( int /*Index*/ ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBRamSize.h b/Source/Project64-core/Settings/SettingType/SettingsType-RDBRamSize.h index f1d4956db..e452c6769 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBRamSize.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBRamSize.h @@ -1,44 +1,44 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeRDBRDRamSize : - public CSettingTypeRomDatabase -{ -public: - CSettingTypeRDBRDRamSize(const char * Name, SettingID DefaultSetting ); - CSettingTypeRDBRDRamSize(const char * Name, int32_t DefaultValue ); - ~CSettingTypeRDBRDRamSize(); - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeRDBRDRamSize(void); // Disable default constructor - CSettingTypeRDBRDRamSize(const CSettingTypeRDBRDRamSize&); // Disable copy constructor - CSettingTypeRDBRDRamSize& operator=(const CSettingTypeRDBRDRamSize&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeRDBRDRamSize : + public CSettingTypeRomDatabase +{ +public: + CSettingTypeRDBRDRamSize(const char * Name, SettingID DefaultSetting ); + CSettingTypeRDBRDRamSize(const char * Name, int32_t DefaultValue ); + ~CSettingTypeRDBRDRamSize(); + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeRDBRDRamSize(void); // Disable default constructor + CSettingTypeRDBRDRamSize(const CSettingTypeRDBRDRamSize&); // Disable copy constructor + CSettingTypeRDBRDRamSize& operator=(const CSettingTypeRDBRDRamSize&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBSaveChip.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RDBSaveChip.cpp index fb754db34..3ffae5dfb 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBSaveChip.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBSaveChip.cpp @@ -1,126 +1,126 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RomDatabase.h" -#include "SettingsType-RDBSaveChip.h" -#include - -CSettingTypeRDBSaveChip::CSettingTypeRDBSaveChip(const char * Name, SettingID DefaultSetting ) : - CSettingTypeRomDatabase(Name,DefaultSetting) -{ -} - -CSettingTypeRDBSaveChip::CSettingTypeRDBSaveChip(const char * Name, int DefaultValue ) : - CSettingTypeRomDatabase(Name,DefaultValue) -{ -} - -CSettingTypeRDBSaveChip::~CSettingTypeRDBSaveChip() -{ -} - -bool CSettingTypeRDBSaveChip::Load ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeRDBSaveChip::Load ( int Index, uint32_t & Value ) const -{ - stdstr strValue; - bool bRes = m_SettingsIniFile->GetString(m_SectionIdent->c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); - if (!bRes) - { - LoadDefault(Index,Value); - return false; - } - const char * String = strValue.c_str(); - - if (_stricmp(String,"First Save Type") == 0) { Value = (uint32_t)SaveChip_Auto; } - else if (_stricmp(String,"4kbit Eeprom") == 0) { Value = SaveChip_Eeprom_4K; } - else if (_stricmp(String,"16kbit Eeprom") == 0) { Value = SaveChip_Eeprom_16K; } - else if (_stricmp(String,"Sram") == 0) { Value = SaveChip_Sram; } - else if (_stricmp(String,"FlashRam") == 0) { Value = SaveChip_FlashRam; } - else if (_stricmp(String,"default") == 0) - { - LoadDefault(Index,Value); - return false; - } else { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - return true; -} - -bool CSettingTypeRDBSaveChip::Load ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -//return the default values -void CSettingTypeRDBSaveChip::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBSaveChip::LoadDefault ( int /*Index*/, uint32_t & Value ) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue; - } else { - g_Settings->LoadDword(m_DefaultSetting,Value); - } - } -} - -void CSettingTypeRDBSaveChip::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -//Update the settings -void CSettingTypeRDBSaveChip::Save ( int /*Index*/, bool /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBSaveChip::Save ( int /*Index*/, uint32_t Value ) -{ - switch (Value) - { - case SaveChip_Auto: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"First Save Type"); break; - case SaveChip_Eeprom_4K: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"4kbit Eeprom"); break; - case SaveChip_Eeprom_16K: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"16kbit Eeprom"); break; - case SaveChip_Sram: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"Sram"); break; - case SaveChip_FlashRam: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"FlashRam"); break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -void CSettingTypeRDBSaveChip::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBSaveChip::Save ( int /*Index*/, const char * /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBSaveChip::Delete( int /*Index*/ ) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBSaveChip.h" +#include + +CSettingTypeRDBSaveChip::CSettingTypeRDBSaveChip(const char * Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBSaveChip::CSettingTypeRDBSaveChip(const char * Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + +CSettingTypeRDBSaveChip::~CSettingTypeRDBSaveChip() +{ +} + +bool CSettingTypeRDBSaveChip::Load ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeRDBSaveChip::Load ( int Index, uint32_t & Value ) const +{ + stdstr strValue; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent->c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); + if (!bRes) + { + LoadDefault(Index,Value); + return false; + } + const char * String = strValue.c_str(); + + if (_stricmp(String,"First Save Type") == 0) { Value = (uint32_t)SaveChip_Auto; } + else if (_stricmp(String,"4kbit Eeprom") == 0) { Value = SaveChip_Eeprom_4K; } + else if (_stricmp(String,"16kbit Eeprom") == 0) { Value = SaveChip_Eeprom_16K; } + else if (_stricmp(String,"Sram") == 0) { Value = SaveChip_Sram; } + else if (_stricmp(String,"FlashRam") == 0) { Value = SaveChip_FlashRam; } + else if (_stricmp(String,"default") == 0) + { + LoadDefault(Index,Value); + return false; + } else { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + return true; +} + +bool CSettingTypeRDBSaveChip::Load ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBSaveChip::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBSaveChip::LoadDefault ( int /*Index*/, uint32_t & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } else { + g_Settings->LoadDword(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRDBSaveChip::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +//Update the settings +void CSettingTypeRDBSaveChip::Save ( int /*Index*/, bool /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBSaveChip::Save ( int /*Index*/, uint32_t Value ) +{ + switch (Value) + { + case SaveChip_Auto: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"First Save Type"); break; + case SaveChip_Eeprom_4K: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"4kbit Eeprom"); break; + case SaveChip_Eeprom_16K: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"16kbit Eeprom"); break; + case SaveChip_Sram: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"Sram"); break; + case SaveChip_FlashRam: m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),"FlashRam"); break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +void CSettingTypeRDBSaveChip::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBSaveChip::Save ( int /*Index*/, const char * /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBSaveChip::Delete( int /*Index*/ ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBSaveChip.h b/Source/Project64-core/Settings/SettingType/SettingsType-RDBSaveChip.h index 1b473fb17..2be7d281b 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBSaveChip.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBSaveChip.h @@ -1,44 +1,44 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeRDBSaveChip : - public CSettingTypeRomDatabase -{ -public: - CSettingTypeRDBSaveChip(const char * Name, SettingID DefaultSetting ); - CSettingTypeRDBSaveChip(const char * Name, int32_t DefaultValue ); - ~CSettingTypeRDBSaveChip(); - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeRDBSaveChip(void); // Disable default constructor - CSettingTypeRDBSaveChip(const CSettingTypeRDBSaveChip&); // Disable copy constructor - CSettingTypeRDBSaveChip& operator=(const CSettingTypeRDBSaveChip&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeRDBSaveChip : + public CSettingTypeRomDatabase +{ +public: + CSettingTypeRDBSaveChip(const char * Name, SettingID DefaultSetting ); + CSettingTypeRDBSaveChip(const char * Name, int32_t DefaultValue ); + ~CSettingTypeRDBSaveChip(); + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeRDBSaveChip(void); // Disable default constructor + CSettingTypeRDBSaveChip(const CSettingTypeRDBSaveChip&); // Disable copy constructor + CSettingTypeRDBSaveChip& operator=(const CSettingTypeRDBSaveChip&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBYesNo.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RDBYesNo.cpp index f99742d55..31230708b 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBYesNo.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBYesNo.cpp @@ -1,124 +1,124 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RomDatabase.h" -#include "SettingsType-RDBYesNo.h" - -CSettingTypeRDBYesNo::CSettingTypeRDBYesNo(const char * Name, SettingID DefaultSetting) : -CSettingTypeRomDatabase(Name, DefaultSetting) -{ -} - -CSettingTypeRDBYesNo::CSettingTypeRDBYesNo(const char * Name, int DefaultValue) : -CSettingTypeRomDatabase(Name, DefaultValue) -{ -} - -CSettingTypeRDBYesNo::~CSettingTypeRDBYesNo() -{ -} - -bool CSettingTypeRDBYesNo::Load(int Index, bool & Value) const -{ - stdstr strValue; - bool bRes = m_SettingsIniFile->GetString(m_SectionIdent->c_str(), m_KeyName.c_str(), m_DefaultStr, strValue); - if (!bRes) - { - LoadDefault(Index, Value); - return false; - } - const char * String = strValue.c_str(); - - if (_stricmp(String, "Yes") == 0) - { - Value = true; - } - else if (_stricmp(String, "No") == 0) - { - Value = false; - } - else if (_stricmp(String, "default") == 0) - { - LoadDefault(Index, Value); - return false; - } - else - { - WriteTrace(TraceSettings, TraceError, "Invalid Yes/No setting value (Section: %s Key: %s Value: %s)", m_SectionIdent->c_str(), String, m_KeyName.c_str(), strValue.c_str()); - LoadDefault(Index, Value); - return false; - } - - return true; -} - -bool CSettingTypeRDBYesNo::Load(int /*Index*/, uint32_t & /*Value*/) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeRDBYesNo::Load(int /*Index*/, stdstr & /*Value*/) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -//return the default values -void CSettingTypeRDBYesNo::LoadDefault(int /*Index*/, bool & Value) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue != 0; - } - else { - g_Settings->LoadBool(m_DefaultSetting, Value); - } - } -} - -void CSettingTypeRDBYesNo::LoadDefault(int /*Index*/, uint32_t & /*Value*/) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBYesNo::LoadDefault(int /*Index*/, stdstr & /*Value*/) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -//Update the settings -void CSettingTypeRDBYesNo::Save(int /*Index*/, bool Value) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(), m_KeyName.c_str(), Value ? "Yes" : "No"); -} - -void CSettingTypeRDBYesNo::Save(int /*Index*/, uint32_t Value) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(), m_KeyName.c_str(), Value ? "Yes" : "No"); -} - -void CSettingTypeRDBYesNo::Save(int /*Index*/, const stdstr & /*Value*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBYesNo::Save(int /*Index*/, const char * /*Value*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRDBYesNo::Delete(int /*Index*/) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(), m_KeyName.c_str(), NULL); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBYesNo.h" + +CSettingTypeRDBYesNo::CSettingTypeRDBYesNo(const char * Name, SettingID DefaultSetting) : +CSettingTypeRomDatabase(Name, DefaultSetting) +{ +} + +CSettingTypeRDBYesNo::CSettingTypeRDBYesNo(const char * Name, int DefaultValue) : +CSettingTypeRomDatabase(Name, DefaultValue) +{ +} + +CSettingTypeRDBYesNo::~CSettingTypeRDBYesNo() +{ +} + +bool CSettingTypeRDBYesNo::Load(int Index, bool & Value) const +{ + stdstr strValue; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent->c_str(), m_KeyName.c_str(), m_DefaultStr, strValue); + if (!bRes) + { + LoadDefault(Index, Value); + return false; + } + const char * String = strValue.c_str(); + + if (_stricmp(String, "Yes") == 0) + { + Value = true; + } + else if (_stricmp(String, "No") == 0) + { + Value = false; + } + else if (_stricmp(String, "default") == 0) + { + LoadDefault(Index, Value); + return false; + } + else + { + WriteTrace(TraceSettings, TraceError, "Invalid Yes/No setting value (Section: %s Key: %s Value: %s)", m_SectionIdent->c_str(), String, m_KeyName.c_str(), strValue.c_str()); + LoadDefault(Index, Value); + return false; + } + + return true; +} + +bool CSettingTypeRDBYesNo::Load(int /*Index*/, uint32_t & /*Value*/) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeRDBYesNo::Load(int /*Index*/, stdstr & /*Value*/) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBYesNo::LoadDefault(int /*Index*/, bool & Value) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } + else { + g_Settings->LoadBool(m_DefaultSetting, Value); + } + } +} + +void CSettingTypeRDBYesNo::LoadDefault(int /*Index*/, uint32_t & /*Value*/) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBYesNo::LoadDefault(int /*Index*/, stdstr & /*Value*/) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +//Update the settings +void CSettingTypeRDBYesNo::Save(int /*Index*/, bool Value) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(), m_KeyName.c_str(), Value ? "Yes" : "No"); +} + +void CSettingTypeRDBYesNo::Save(int /*Index*/, uint32_t Value) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(), m_KeyName.c_str(), Value ? "Yes" : "No"); +} + +void CSettingTypeRDBYesNo::Save(int /*Index*/, const stdstr & /*Value*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBYesNo::Save(int /*Index*/, const char * /*Value*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRDBYesNo::Delete(int /*Index*/) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(), m_KeyName.c_str(), NULL); } \ No newline at end of file diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RDBYesNo.h b/Source/Project64-core/Settings/SettingType/SettingsType-RDBYesNo.h index de019dbb5..79da55cbc 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RDBYesNo.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RDBYesNo.h @@ -1,44 +1,44 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeRDBYesNo : - public CSettingTypeRomDatabase -{ -public: - CSettingTypeRDBYesNo(const char * Name, SettingID DefaultSetting ); - CSettingTypeRDBYesNo(const char * Name, int32_t DefaultValue ); - ~CSettingTypeRDBYesNo(); - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeRDBYesNo(void); // Disable default constructor - CSettingTypeRDBYesNo(const CSettingTypeRDBYesNo&); // Disable copy constructor - CSettingTypeRDBYesNo& operator=(const CSettingTypeRDBYesNo&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeRDBYesNo : + public CSettingTypeRomDatabase +{ +public: + CSettingTypeRDBYesNo(const char * Name, SettingID DefaultSetting ); + CSettingTypeRDBYesNo(const char * Name, int32_t DefaultValue ); + ~CSettingTypeRDBYesNo(); + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeRDBYesNo(void); // Disable default constructor + CSettingTypeRDBYesNo(const CSettingTypeRDBYesNo&); // Disable copy constructor + CSettingTypeRDBYesNo& operator=(const CSettingTypeRDBYesNo&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RelativePath.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RelativePath.cpp index 88049c257..f71f855ef 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RelativePath.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RelativePath.cpp @@ -1,89 +1,89 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RelativePath.h" - -CSettingTypeRelativePath::CSettingTypeRelativePath(const char * Directory, const char * FileName) : -m_Directory(Directory), -m_FileName(FileName) -{ - BuildPath(); - g_Settings->RegisterChangeCB(Cmd_BaseDirectory, this, RefreshSettings); -} - -CSettingTypeRelativePath::~CSettingTypeRelativePath(void) -{ - g_Settings->UnregisterChangeCB(Cmd_BaseDirectory, this, RefreshSettings); -} - -bool CSettingTypeRelativePath::Load(int /*Index*/, stdstr & value) const -{ - value = m_FullPath; - return true; -} - -//return the default values -void CSettingTypeRelativePath::LoadDefault(int /*Index*/, bool & /*Value*/) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRelativePath::LoadDefault(int /*Index*/, uint32_t & /*Value*/) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRelativePath::LoadDefault(int /*Index*/, stdstr & /*Value*/) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRelativePath::Save(int /*Index*/, bool /*Value*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRelativePath::Save(int /*Index*/, uint32_t /*Value*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRelativePath::Save(int /*Index*/, const stdstr & Value) -{ - m_Directory = ""; - m_FileName = Value; - BuildPath(); -} - -void CSettingTypeRelativePath::Save(int /*Index*/, const char * Value) -{ - m_Directory = ""; - m_FileName = Value; - BuildPath(); -} - -void CSettingTypeRelativePath::Delete(int /*Index*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRelativePath::BuildPath(void) -{ - CPath FullPath(g_Settings->LoadStringVal(Cmd_BaseDirectory).c_str(),""); - FullPath.AppendDirectory(m_Directory.c_str()); - FullPath.SetNameExtension(m_FileName.c_str()); - m_FullPath = (const char *)FullPath; -} - -void CSettingTypeRelativePath::RefreshSettings(void * _this) -{ - ((CSettingTypeRelativePath *)_this)->BuildPath(); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RelativePath.h" + +CSettingTypeRelativePath::CSettingTypeRelativePath(const char * Directory, const char * FileName) : +m_Directory(Directory), +m_FileName(FileName) +{ + BuildPath(); + g_Settings->RegisterChangeCB(Cmd_BaseDirectory, this, RefreshSettings); +} + +CSettingTypeRelativePath::~CSettingTypeRelativePath(void) +{ + g_Settings->UnregisterChangeCB(Cmd_BaseDirectory, this, RefreshSettings); +} + +bool CSettingTypeRelativePath::Load(int /*Index*/, stdstr & value) const +{ + value = m_FullPath; + return true; +} + +//return the default values +void CSettingTypeRelativePath::LoadDefault(int /*Index*/, bool & /*Value*/) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRelativePath::LoadDefault(int /*Index*/, uint32_t & /*Value*/) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRelativePath::LoadDefault(int /*Index*/, stdstr & /*Value*/) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRelativePath::Save(int /*Index*/, bool /*Value*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRelativePath::Save(int /*Index*/, uint32_t /*Value*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRelativePath::Save(int /*Index*/, const stdstr & Value) +{ + m_Directory = ""; + m_FileName = Value; + BuildPath(); +} + +void CSettingTypeRelativePath::Save(int /*Index*/, const char * Value) +{ + m_Directory = ""; + m_FileName = Value; + BuildPath(); +} + +void CSettingTypeRelativePath::Delete(int /*Index*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRelativePath::BuildPath(void) +{ + CPath FullPath(g_Settings->LoadStringVal(Cmd_BaseDirectory).c_str(),""); + FullPath.AppendDirectory(m_Directory.c_str()); + FullPath.SetNameExtension(m_FileName.c_str()); + m_FullPath = (const char *)FullPath; +} + +void CSettingTypeRelativePath::RefreshSettings(void * _this) +{ + ((CSettingTypeRelativePath *)_this)->BuildPath(); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RelativePath.h b/Source/Project64-core/Settings/SettingType/SettingsType-RelativePath.h index ab5ef6876..805e3265a 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RelativePath.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RelativePath.h @@ -1,55 +1,55 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include -#include - -class CSettingTypeRelativePath : - public CSettingType -{ -public: - CSettingTypeRelativePath(const char * Directory, const char * FileName); - ~CSettingTypeRelativePath(); - - bool IndexBasedSetting ( void ) const { return false; } - SettingType GetSettingType ( void ) const { return SettingType_RelativePath; } - - //return the values - bool Load ( int32_t /*Index*/, bool & /*Value*/ ) const { return false; }; - bool Load ( int32_t /*Index*/, uint32_t & /*Value*/ ) const { return false; }; - bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - void LoadDefault ( int32_t Index, bool & Value ) const; - void LoadDefault ( int32_t Index, uint32_t & Value ) const; - void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - void Save ( int32_t Index, bool Value ); - void Save ( int32_t Index, uint32_t Value ); - void Save ( int32_t Index, const stdstr & Value ); - void Save ( int32_t Index, const char * Value ); - - // Delete the setting - void Delete ( int32_t Index ); - -private: - CSettingTypeRelativePath(void); // Disable default constructor - CSettingTypeRelativePath(const CSettingTypeRelativePath&); // Disable copy constructor - CSettingTypeRelativePath& operator=(const CSettingTypeRelativePath&); // Disable assignment - - static void RefreshSettings(void * _this); - void BuildPath ( void ); - - std::string m_FullPath; - std::string m_Directory; - std::string m_FileName; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include +#include + +class CSettingTypeRelativePath : + public CSettingType +{ +public: + CSettingTypeRelativePath(const char * Directory, const char * FileName); + ~CSettingTypeRelativePath(); + + bool IndexBasedSetting ( void ) const { return false; } + SettingType GetSettingType ( void ) const { return SettingType_RelativePath; } + + //return the values + bool Load ( int32_t /*Index*/, bool & /*Value*/ ) const { return false; }; + bool Load ( int32_t /*Index*/, uint32_t & /*Value*/ ) const { return false; }; + bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + void LoadDefault ( int32_t Index, bool & Value ) const; + void LoadDefault ( int32_t Index, uint32_t & Value ) const; + void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + void Save ( int32_t Index, bool Value ); + void Save ( int32_t Index, uint32_t Value ); + void Save ( int32_t Index, const stdstr & Value ); + void Save ( int32_t Index, const char * Value ); + + // Delete the setting + void Delete ( int32_t Index ); + +private: + CSettingTypeRelativePath(void); // Disable default constructor + CSettingTypeRelativePath(const CSettingTypeRelativePath&); // Disable copy constructor + CSettingTypeRelativePath& operator=(const CSettingTypeRelativePath&); // Disable assignment + + static void RefreshSettings(void * _this); + void BuildPath ( void ); + + std::string m_FullPath; + std::string m_Directory; + std::string m_FileName; +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabase.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabase.cpp index c45e6b69e..9d177d2fd 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabase.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabase.cpp @@ -1,318 +1,318 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RomDatabase.h" - -CIniFile * CSettingTypeRomDatabase::m_SettingsIniFile = NULL; -CIniFile * CSettingTypeRomDatabase::m_GlideIniFile = NULL; -stdstr * CSettingTypeRomDatabase::m_SectionIdent = NULL; - -CSettingTypeRomDatabase::CSettingTypeRomDatabase(const char * Name, int DefaultValue, bool DeleteOnDefault ) : - m_KeyName(StripNameSection(Name)), - m_DefaultStr(""), - m_DefaultValue(DefaultValue), - m_DefaultSetting(Default_Constant), - m_DeleteOnDefault(DeleteOnDefault), - m_GlideSetting(IsGlideSetting(Name)) -{ -} - -CSettingTypeRomDatabase::CSettingTypeRomDatabase(const char * Name, bool DefaultValue, bool DeleteOnDefault ) : - m_KeyName(StripNameSection(Name)), - m_DefaultStr(""), - m_DefaultValue(DefaultValue), - m_DefaultSetting(Default_Constant), - m_DeleteOnDefault(DeleteOnDefault), - m_GlideSetting(IsGlideSetting(Name)) -{ -} - -CSettingTypeRomDatabase::CSettingTypeRomDatabase(const char * Name, const char * DefaultValue, bool DeleteOnDefault ) : - m_KeyName(StripNameSection(Name)), - m_DefaultStr(DefaultValue), - m_DefaultValue(0), - m_DefaultSetting(Default_Constant), - m_DeleteOnDefault(DeleteOnDefault), - m_GlideSetting(IsGlideSetting(Name)) -{ -} - -CSettingTypeRomDatabase::CSettingTypeRomDatabase(const char * Name, SettingID DefaultSetting, bool DeleteOnDefault ) : - m_KeyName(Name), - m_DefaultStr(""), - m_DefaultValue(0), - m_DefaultSetting(DefaultSetting), - m_DeleteOnDefault(DeleteOnDefault), - m_GlideSetting(IsGlideSetting(Name)) -{ -} - -CSettingTypeRomDatabase::~CSettingTypeRomDatabase() -{ -} - -void CSettingTypeRomDatabase::Initialize( void ) -{ - m_SettingsIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); - m_GlideIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Glide64RDB).c_str()); - - g_Settings->RegisterChangeCB(Game_IniKey,NULL,GameChanged); - g_Settings->RegisterChangeCB(Cmd_BaseDirectory,NULL,BaseDirChanged); - - m_SectionIdent = new stdstr(g_Settings->LoadStringVal(Game_IniKey)); -} - -void CSettingTypeRomDatabase::CleanUp( void ) -{ - g_Settings->UnregisterChangeCB(Cmd_BaseDirectory,NULL,BaseDirChanged); - g_Settings->UnregisterChangeCB(Game_IniKey,NULL,GameChanged); - if (m_SettingsIniFile) - { - delete m_SettingsIniFile; - m_SettingsIniFile = NULL; - } - if (m_GlideIniFile) - { - delete m_GlideIniFile; - m_GlideIniFile = NULL; - } - if (m_SectionIdent) - { - delete m_SectionIdent; - m_SectionIdent = NULL; - } -} - -void CSettingTypeRomDatabase::BaseDirChanged ( void * /*Data */ ) -{ - if (m_SettingsIniFile) - { - delete m_SettingsIniFile; - m_SettingsIniFile = NULL; - } - if (m_GlideIniFile) - { - delete m_GlideIniFile; - m_GlideIniFile = NULL; - } - m_SettingsIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); - m_GlideIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Glide64RDB).c_str()); -} - -void CSettingTypeRomDatabase::GameChanged ( void * /*Data */ ) -{ - if (m_SectionIdent) - { - *m_SectionIdent = g_Settings->LoadStringVal(Game_IniKey); - } -} - -bool CSettingTypeRomDatabase::Load ( int Index, bool & Value ) const -{ - uint32_t temp_value = Value; - bool bRes = Load(Index,temp_value); - Value = temp_value != 0; - return bRes; -} - -bool CSettingTypeRomDatabase::Load ( int Index, uint32_t & Value ) const -{ - bool bRes = false; - if (m_GlideSetting) - { - bRes = m_GlideIniFile->GetNumber(Section(),m_KeyName.c_str(),Value,Value); - } - else - { - bRes = m_SettingsIniFile->GetNumber(Section(),m_KeyName.c_str(),Value,Value); - } - if (!bRes) - { - LoadDefault(Index,Value); - } - return bRes; -} - -bool CSettingTypeRomDatabase::Load ( int Index, stdstr & Value ) const -{ - stdstr temp_value; - bool bRes = false; - if (m_GlideSetting) - { - bRes = m_GlideIniFile->GetString(Section(),m_KeyName.c_str(),m_DefaultStr,temp_value); - } - else - { - bRes = m_SettingsIniFile->GetString(Section(),m_KeyName.c_str(),m_DefaultStr,temp_value); - } - if (bRes) - { - Value = temp_value; - } - else - { - LoadDefault(Index,Value); - } - return bRes; -} - -//return the default values -void CSettingTypeRomDatabase::LoadDefault ( int /*Index*/, bool & Value ) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue != 0; - } else { - g_Settings->LoadBool(m_DefaultSetting,Value); - } - } -} - -void CSettingTypeRomDatabase::LoadDefault ( int /*Index*/, uint32_t & Value ) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultValue; - } else { - g_Settings->LoadDword(m_DefaultSetting,Value); - } - } -} - -void CSettingTypeRomDatabase::LoadDefault ( int /*Index*/, stdstr & Value ) const -{ - if (m_DefaultSetting != Default_None) - { - if (m_DefaultSetting == Default_Constant) - { - Value = m_DefaultStr; - } else { - g_Settings->LoadStringVal(m_DefaultSetting,Value); - } - } -} - -//Update the settings -void CSettingTypeRomDatabase::Save ( int /*Index*/, bool Value ) -{ - if (!g_Settings->LoadBool(Setting_RdbEditor)) - { - return; - } - if (m_DeleteOnDefault) - { - g_Notify->BreakPoint(__FILE__,__LINE__); - } - if (m_GlideSetting) - { - m_GlideIniFile->SaveNumber(Section(),m_KeyName.c_str(),Value); - } - else - { - m_SettingsIniFile->SaveNumber(Section(),m_KeyName.c_str(),Value); - } -} - -void CSettingTypeRomDatabase::Save ( int Index, uint32_t Value ) -{ - if (!g_Settings->LoadBool(Setting_RdbEditor)) - { - return; - } - if (m_DeleteOnDefault) - { - uint32_t defaultValue = 0; - LoadDefault(Index,defaultValue); - if (defaultValue == Value) - { - Delete(Index); - return; - } - } - if (m_GlideSetting) - { - m_GlideIniFile->SaveNumber(Section(),m_KeyName.c_str(),Value); - } - else - { - m_SettingsIniFile->SaveNumber(Section(),m_KeyName.c_str(),Value); - } -} - -void CSettingTypeRomDatabase::Save ( int /*Index*/, const stdstr & Value ) -{ - if (!g_Settings->LoadBool(Setting_RdbEditor)) - { - return; - } - if (m_GlideSetting) - { - m_GlideIniFile->SaveString(Section(),m_KeyName.c_str(),Value.c_str()); - } - else - { - m_SettingsIniFile->SaveString(Section(),m_KeyName.c_str(),Value.c_str()); - } -} - -void CSettingTypeRomDatabase::Save ( int /*Index*/, const char * Value ) -{ - if (!g_Settings->LoadBool(Setting_RdbEditor)) - { - return; - } - if (m_GlideSetting) - { - m_GlideIniFile->SaveString(Section(),m_KeyName.c_str(),Value); - } - else - { - m_SettingsIniFile->SaveString(Section(),m_KeyName.c_str(),Value); - } -} - -void CSettingTypeRomDatabase::Delete ( int /*Index*/ ) -{ - if (!g_Settings->LoadBool(Setting_RdbEditor)) - { - return; - } - if (m_GlideSetting) - { - m_GlideIniFile->SaveString(Section(),m_KeyName.c_str(),NULL); - } - else - { - m_SettingsIniFile->SaveString(Section(),m_KeyName.c_str(),NULL); - } -} - -bool CSettingTypeRomDatabase::IsGlideSetting (const char * Name) -{ - if (_strnicmp(Name,"Glide64-",8) == 0) - { - return true; - } - return false; -} - -const char * CSettingTypeRomDatabase::StripNameSection (const char * Name) -{ - if (_strnicmp(Name,"Glide64-",8) == 0) - { - return &Name[8]; - } - return Name; -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RomDatabase.h" + +CIniFile * CSettingTypeRomDatabase::m_SettingsIniFile = NULL; +CIniFile * CSettingTypeRomDatabase::m_GlideIniFile = NULL; +stdstr * CSettingTypeRomDatabase::m_SectionIdent = NULL; + +CSettingTypeRomDatabase::CSettingTypeRomDatabase(const char * Name, int DefaultValue, bool DeleteOnDefault ) : + m_KeyName(StripNameSection(Name)), + m_DefaultStr(""), + m_DefaultValue(DefaultValue), + m_DefaultSetting(Default_Constant), + m_DeleteOnDefault(DeleteOnDefault), + m_GlideSetting(IsGlideSetting(Name)) +{ +} + +CSettingTypeRomDatabase::CSettingTypeRomDatabase(const char * Name, bool DefaultValue, bool DeleteOnDefault ) : + m_KeyName(StripNameSection(Name)), + m_DefaultStr(""), + m_DefaultValue(DefaultValue), + m_DefaultSetting(Default_Constant), + m_DeleteOnDefault(DeleteOnDefault), + m_GlideSetting(IsGlideSetting(Name)) +{ +} + +CSettingTypeRomDatabase::CSettingTypeRomDatabase(const char * Name, const char * DefaultValue, bool DeleteOnDefault ) : + m_KeyName(StripNameSection(Name)), + m_DefaultStr(DefaultValue), + m_DefaultValue(0), + m_DefaultSetting(Default_Constant), + m_DeleteOnDefault(DeleteOnDefault), + m_GlideSetting(IsGlideSetting(Name)) +{ +} + +CSettingTypeRomDatabase::CSettingTypeRomDatabase(const char * Name, SettingID DefaultSetting, bool DeleteOnDefault ) : + m_KeyName(Name), + m_DefaultStr(""), + m_DefaultValue(0), + m_DefaultSetting(DefaultSetting), + m_DeleteOnDefault(DeleteOnDefault), + m_GlideSetting(IsGlideSetting(Name)) +{ +} + +CSettingTypeRomDatabase::~CSettingTypeRomDatabase() +{ +} + +void CSettingTypeRomDatabase::Initialize( void ) +{ + m_SettingsIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); + m_GlideIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Glide64RDB).c_str()); + + g_Settings->RegisterChangeCB(Game_IniKey,NULL,GameChanged); + g_Settings->RegisterChangeCB(Cmd_BaseDirectory,NULL,BaseDirChanged); + + m_SectionIdent = new stdstr(g_Settings->LoadStringVal(Game_IniKey)); +} + +void CSettingTypeRomDatabase::CleanUp( void ) +{ + g_Settings->UnregisterChangeCB(Cmd_BaseDirectory,NULL,BaseDirChanged); + g_Settings->UnregisterChangeCB(Game_IniKey,NULL,GameChanged); + if (m_SettingsIniFile) + { + delete m_SettingsIniFile; + m_SettingsIniFile = NULL; + } + if (m_GlideIniFile) + { + delete m_GlideIniFile; + m_GlideIniFile = NULL; + } + if (m_SectionIdent) + { + delete m_SectionIdent; + m_SectionIdent = NULL; + } +} + +void CSettingTypeRomDatabase::BaseDirChanged ( void * /*Data */ ) +{ + if (m_SettingsIniFile) + { + delete m_SettingsIniFile; + m_SettingsIniFile = NULL; + } + if (m_GlideIniFile) + { + delete m_GlideIniFile; + m_GlideIniFile = NULL; + } + m_SettingsIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); + m_GlideIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Glide64RDB).c_str()); +} + +void CSettingTypeRomDatabase::GameChanged ( void * /*Data */ ) +{ + if (m_SectionIdent) + { + *m_SectionIdent = g_Settings->LoadStringVal(Game_IniKey); + } +} + +bool CSettingTypeRomDatabase::Load ( int Index, bool & Value ) const +{ + uint32_t temp_value = Value; + bool bRes = Load(Index,temp_value); + Value = temp_value != 0; + return bRes; +} + +bool CSettingTypeRomDatabase::Load ( int Index, uint32_t & Value ) const +{ + bool bRes = false; + if (m_GlideSetting) + { + bRes = m_GlideIniFile->GetNumber(Section(),m_KeyName.c_str(),Value,Value); + } + else + { + bRes = m_SettingsIniFile->GetNumber(Section(),m_KeyName.c_str(),Value,Value); + } + if (!bRes) + { + LoadDefault(Index,Value); + } + return bRes; +} + +bool CSettingTypeRomDatabase::Load ( int Index, stdstr & Value ) const +{ + stdstr temp_value; + bool bRes = false; + if (m_GlideSetting) + { + bRes = m_GlideIniFile->GetString(Section(),m_KeyName.c_str(),m_DefaultStr,temp_value); + } + else + { + bRes = m_SettingsIniFile->GetString(Section(),m_KeyName.c_str(),m_DefaultStr,temp_value); + } + if (bRes) + { + Value = temp_value; + } + else + { + LoadDefault(Index,Value); + } + return bRes; +} + +//return the default values +void CSettingTypeRomDatabase::LoadDefault ( int /*Index*/, bool & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } else { + g_Settings->LoadBool(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRomDatabase::LoadDefault ( int /*Index*/, uint32_t & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } else { + g_Settings->LoadDword(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRomDatabase::LoadDefault ( int /*Index*/, stdstr & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultStr; + } else { + g_Settings->LoadStringVal(m_DefaultSetting,Value); + } + } +} + +//Update the settings +void CSettingTypeRomDatabase::Save ( int /*Index*/, bool Value ) +{ + if (!g_Settings->LoadBool(Setting_RdbEditor)) + { + return; + } + if (m_DeleteOnDefault) + { + g_Notify->BreakPoint(__FILE__,__LINE__); + } + if (m_GlideSetting) + { + m_GlideIniFile->SaveNumber(Section(),m_KeyName.c_str(),Value); + } + else + { + m_SettingsIniFile->SaveNumber(Section(),m_KeyName.c_str(),Value); + } +} + +void CSettingTypeRomDatabase::Save ( int Index, uint32_t Value ) +{ + if (!g_Settings->LoadBool(Setting_RdbEditor)) + { + return; + } + if (m_DeleteOnDefault) + { + uint32_t defaultValue = 0; + LoadDefault(Index,defaultValue); + if (defaultValue == Value) + { + Delete(Index); + return; + } + } + if (m_GlideSetting) + { + m_GlideIniFile->SaveNumber(Section(),m_KeyName.c_str(),Value); + } + else + { + m_SettingsIniFile->SaveNumber(Section(),m_KeyName.c_str(),Value); + } +} + +void CSettingTypeRomDatabase::Save ( int /*Index*/, const stdstr & Value ) +{ + if (!g_Settings->LoadBool(Setting_RdbEditor)) + { + return; + } + if (m_GlideSetting) + { + m_GlideIniFile->SaveString(Section(),m_KeyName.c_str(),Value.c_str()); + } + else + { + m_SettingsIniFile->SaveString(Section(),m_KeyName.c_str(),Value.c_str()); + } +} + +void CSettingTypeRomDatabase::Save ( int /*Index*/, const char * Value ) +{ + if (!g_Settings->LoadBool(Setting_RdbEditor)) + { + return; + } + if (m_GlideSetting) + { + m_GlideIniFile->SaveString(Section(),m_KeyName.c_str(),Value); + } + else + { + m_SettingsIniFile->SaveString(Section(),m_KeyName.c_str(),Value); + } +} + +void CSettingTypeRomDatabase::Delete ( int /*Index*/ ) +{ + if (!g_Settings->LoadBool(Setting_RdbEditor)) + { + return; + } + if (m_GlideSetting) + { + m_GlideIniFile->SaveString(Section(),m_KeyName.c_str(),NULL); + } + else + { + m_SettingsIniFile->SaveString(Section(),m_KeyName.c_str(),NULL); + } +} + +bool CSettingTypeRomDatabase::IsGlideSetting (const char * Name) +{ + if (_strnicmp(Name,"Glide64-",8) == 0) + { + return true; + } + return false; +} + +const char * CSettingTypeRomDatabase::StripNameSection (const char * Name) +{ + if (_strnicmp(Name,"Glide64-",8) == 0) + { + return &Name[8]; + } + return Name; +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabase.h b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabase.h index 6df365f0d..e707b6302 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabase.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabase.h @@ -1,75 +1,75 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include -#include - -class CSettingTypeRomDatabase : - public CSettingType -{ -public: - CSettingTypeRomDatabase(const char * Name, const char * DefaultValue, bool DeleteOnDefault = false ); - CSettingTypeRomDatabase(const char * Name, bool DefaultValue, bool DeleteOnDefault = false ); - CSettingTypeRomDatabase(const char * Name, int32_t DefaultValue, bool DeleteOnDefault = false ); - CSettingTypeRomDatabase(const char * Name, SettingID DefaultSetting, bool DeleteOnDefault = false ); - - virtual ~CSettingTypeRomDatabase(); - - virtual bool IndexBasedSetting ( void ) const { return false; } - virtual SettingType GetSettingType ( void ) const { return SettingType_RomDatabase; } - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - - static void Initialize( void ); - static void CleanUp ( void ); - -protected: - static void GameChanged ( void * /*Data */ ); - static void BaseDirChanged ( void * /*Data */ ); - - static bool IsGlideSetting (const char * Name); - static const char * StripNameSection (const char * Name); - virtual const char * Section ( void ) const { return m_SectionIdent->c_str(); } - - mutable stdstr m_KeyName; - const char *const m_DefaultStr; - const int32_t m_DefaultValue; - const SettingID m_DefaultSetting; - const bool m_DeleteOnDefault; - bool m_GlideSetting; - - static stdstr * m_SectionIdent; - static CIniFile * m_SettingsIniFile; - static CIniFile * m_GlideIniFile; - -private: - CSettingTypeRomDatabase(); // Disable default constructor - CSettingTypeRomDatabase(const CSettingTypeRomDatabase&); // Disable copy constructor - CSettingTypeRomDatabase& operator=(const CSettingTypeRomDatabase&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include +#include + +class CSettingTypeRomDatabase : + public CSettingType +{ +public: + CSettingTypeRomDatabase(const char * Name, const char * DefaultValue, bool DeleteOnDefault = false ); + CSettingTypeRomDatabase(const char * Name, bool DefaultValue, bool DeleteOnDefault = false ); + CSettingTypeRomDatabase(const char * Name, int32_t DefaultValue, bool DeleteOnDefault = false ); + CSettingTypeRomDatabase(const char * Name, SettingID DefaultSetting, bool DeleteOnDefault = false ); + + virtual ~CSettingTypeRomDatabase(); + + virtual bool IndexBasedSetting ( void ) const { return false; } + virtual SettingType GetSettingType ( void ) const { return SettingType_RomDatabase; } + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + + static void Initialize( void ); + static void CleanUp ( void ); + +protected: + static void GameChanged ( void * /*Data */ ); + static void BaseDirChanged ( void * /*Data */ ); + + static bool IsGlideSetting (const char * Name); + static const char * StripNameSection (const char * Name); + virtual const char * Section ( void ) const { return m_SectionIdent->c_str(); } + + mutable stdstr m_KeyName; + const char *const m_DefaultStr; + const int32_t m_DefaultValue; + const SettingID m_DefaultSetting; + const bool m_DeleteOnDefault; + bool m_GlideSetting; + + static stdstr * m_SectionIdent; + static CIniFile * m_SettingsIniFile; + static CIniFile * m_GlideIniFile; + +private: + CSettingTypeRomDatabase(); // Disable default constructor + CSettingTypeRomDatabase(const CSettingTypeRomDatabase&); // Disable copy constructor + CSettingTypeRomDatabase& operator=(const CSettingTypeRomDatabase&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseIndex.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseIndex.cpp index fe7797232..8c02eb3b3 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseIndex.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseIndex.cpp @@ -1,106 +1,106 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RomDatabase.h" -#include "SettingsType-RomDatabaseIndex.h" - -CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, const char * DefaultValue ) : - CSettingTypeRomDatabase("",DefaultValue), - m_PreIndex(PreIndex), - m_PostIndex(PostIndex) -{ -} - -CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, bool DefaultValue ) : - CSettingTypeRomDatabase("",DefaultValue), - m_PreIndex(PreIndex), - m_PostIndex(PostIndex) -{ -} - -CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, int DefaultValue ) : - CSettingTypeRomDatabase("",DefaultValue), - m_PreIndex(PreIndex), - m_PostIndex(PostIndex) -{ -} - -CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, SettingID DefaultSetting ) : - CSettingTypeRomDatabase("",DefaultSetting), - m_PreIndex(PreIndex), - m_PostIndex(PostIndex) -{ -} - -CSettingTypeRomDatabaseIndex::~CSettingTypeRomDatabaseIndex() -{ -} - -bool CSettingTypeRomDatabaseIndex::Load ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeRomDatabaseIndex::Load ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeRomDatabaseIndex::Load ( int Index, stdstr & Value ) const -{ - m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - return CSettingTypeRomDatabase::Load(0,Value); -} - -void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, bool & Value ) const -{ - m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - CSettingTypeRomDatabase::LoadDefault(0,Value); -} - -void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, uint32_t & Value ) const -{ - m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - CSettingTypeRomDatabase::LoadDefault(0,Value); -} - -void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, stdstr & Value ) const -{ - m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); - CSettingTypeRomDatabase::LoadDefault(0,Value); -} - -void CSettingTypeRomDatabaseIndex::Save ( int /*Index*/, bool /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRomDatabaseIndex::Save ( int /*Index*/, uint32_t /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRomDatabaseIndex::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRomDatabaseIndex::Save ( int /*Index*/, const char * /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeRomDatabaseIndex::Delete ( int /*Index*/ ) -{ - m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RomDatabaseIndex.h" + +CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, const char * DefaultValue ) : + CSettingTypeRomDatabase("",DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, bool DefaultValue ) : + CSettingTypeRomDatabase("",DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, int DefaultValue ) : + CSettingTypeRomDatabase("",DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, SettingID DefaultSetting ) : + CSettingTypeRomDatabase("",DefaultSetting), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeRomDatabaseIndex::~CSettingTypeRomDatabaseIndex() +{ +} + +bool CSettingTypeRomDatabaseIndex::Load ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeRomDatabaseIndex::Load ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeRomDatabaseIndex::Load ( int Index, stdstr & Value ) const +{ + m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + return CSettingTypeRomDatabase::Load(0,Value); +} + +void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, bool & Value ) const +{ + m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeRomDatabase::LoadDefault(0,Value); +} + +void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, uint32_t & Value ) const +{ + m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeRomDatabase::LoadDefault(0,Value); +} + +void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, stdstr & Value ) const +{ + m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeRomDatabase::LoadDefault(0,Value); +} + +void CSettingTypeRomDatabaseIndex::Save ( int /*Index*/, bool /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRomDatabaseIndex::Save ( int /*Index*/, uint32_t /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRomDatabaseIndex::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRomDatabaseIndex::Save ( int /*Index*/, const char * /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeRomDatabaseIndex::Delete ( int /*Index*/ ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent->c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseIndex.h b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseIndex.h index e62fec2da..2d638a12f 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseIndex.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseIndex.h @@ -1,51 +1,51 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CSettingTypeRomDatabaseIndex : - public CSettingTypeRomDatabase -{ -public: - CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, const char * DefaultValue ); - CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, bool DefaultValue ); - CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, int32_t DefaultValue ); - CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, SettingID DefaultSetting ); - - virtual ~CSettingTypeRomDatabaseIndex(); - - virtual bool IndexBasedSetting ( void ) const { return true; } - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeRomDatabaseIndex(void); // Disable default constructor - CSettingTypeRomDatabaseIndex(const CSettingTypeRomDatabaseIndex&); // Disable copy constructor - CSettingTypeRomDatabaseIndex& operator=(const CSettingTypeRomDatabaseIndex&); // Disable assignment - - stdstr m_PreIndex, m_PostIndex; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CSettingTypeRomDatabaseIndex : + public CSettingTypeRomDatabase +{ +public: + CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, const char * DefaultValue ); + CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, bool DefaultValue ); + CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, int32_t DefaultValue ); + CSettingTypeRomDatabaseIndex(const char * PreIndex, const char * PostIndex, SettingID DefaultSetting ); + + virtual ~CSettingTypeRomDatabaseIndex(); + + virtual bool IndexBasedSetting ( void ) const { return true; } + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeRomDatabaseIndex(void); // Disable default constructor + CSettingTypeRomDatabaseIndex(const CSettingTypeRomDatabaseIndex&); // Disable copy constructor + CSettingTypeRomDatabaseIndex& operator=(const CSettingTypeRomDatabaseIndex&); // Disable assignment + + stdstr m_PreIndex, m_PostIndex; +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseSetting.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseSetting.cpp index b01742bea..f2561c7dc 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseSetting.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseSetting.cpp @@ -1,64 +1,64 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-RomDatabaseSetting.h" - -CSettingTypeRomDatabaseSetting::CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, int DefaultValue, bool DeleteOnDefault ) : - CSettingTypeRomDatabase(Name, DefaultValue, DeleteOnDefault), - m_SectionIdent(SectionIdent) -{ - m_SectionIdent.Replace("\\","-"); - if (!m_GlideSetting) - { - m_GlideSetting = IsGlideSetting(m_SectionIdent.c_str()); - m_SectionIdent = StripNameSection(m_SectionIdent.c_str()); - } -} - -CSettingTypeRomDatabaseSetting::CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, bool DefaultValue, bool DeleteOnDefault ) : - CSettingTypeRomDatabase(Name, DefaultValue, DeleteOnDefault), - m_SectionIdent(SectionIdent) -{ - m_SectionIdent.Replace("\\","-"); - if (!m_GlideSetting) - { - m_GlideSetting = IsGlideSetting(m_SectionIdent.c_str()); - m_SectionIdent = StripNameSection(m_SectionIdent.c_str()); - } -} - -CSettingTypeRomDatabaseSetting::CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, const char * DefaultValue, bool DeleteOnDefault ) : - CSettingTypeRomDatabase(Name, DefaultValue, DeleteOnDefault), - m_SectionIdent(SectionIdent) -{ - m_SectionIdent.Replace("\\","-"); - if (!m_GlideSetting) - { - m_GlideSetting = IsGlideSetting(m_SectionIdent.c_str()); - m_SectionIdent = StripNameSection(m_SectionIdent.c_str()); - } -} - -CSettingTypeRomDatabaseSetting::CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, SettingID DefaultSetting, bool DeleteOnDefault ) : - CSettingTypeRomDatabase(Name, DefaultSetting, DeleteOnDefault), - m_SectionIdent(SectionIdent) -{ - m_SectionIdent.Replace("\\","-"); - if (!m_GlideSetting) - { - m_GlideSetting = IsGlideSetting(m_SectionIdent.c_str()); - m_SectionIdent = StripNameSection(m_SectionIdent.c_str()); - } -} - -CSettingTypeRomDatabaseSetting::~CSettingTypeRomDatabaseSetting() -{ -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-RomDatabaseSetting.h" + +CSettingTypeRomDatabaseSetting::CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, int DefaultValue, bool DeleteOnDefault ) : + CSettingTypeRomDatabase(Name, DefaultValue, DeleteOnDefault), + m_SectionIdent(SectionIdent) +{ + m_SectionIdent.Replace("\\","-"); + if (!m_GlideSetting) + { + m_GlideSetting = IsGlideSetting(m_SectionIdent.c_str()); + m_SectionIdent = StripNameSection(m_SectionIdent.c_str()); + } +} + +CSettingTypeRomDatabaseSetting::CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, bool DefaultValue, bool DeleteOnDefault ) : + CSettingTypeRomDatabase(Name, DefaultValue, DeleteOnDefault), + m_SectionIdent(SectionIdent) +{ + m_SectionIdent.Replace("\\","-"); + if (!m_GlideSetting) + { + m_GlideSetting = IsGlideSetting(m_SectionIdent.c_str()); + m_SectionIdent = StripNameSection(m_SectionIdent.c_str()); + } +} + +CSettingTypeRomDatabaseSetting::CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, const char * DefaultValue, bool DeleteOnDefault ) : + CSettingTypeRomDatabase(Name, DefaultValue, DeleteOnDefault), + m_SectionIdent(SectionIdent) +{ + m_SectionIdent.Replace("\\","-"); + if (!m_GlideSetting) + { + m_GlideSetting = IsGlideSetting(m_SectionIdent.c_str()); + m_SectionIdent = StripNameSection(m_SectionIdent.c_str()); + } +} + +CSettingTypeRomDatabaseSetting::CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, SettingID DefaultSetting, bool DeleteOnDefault ) : + CSettingTypeRomDatabase(Name, DefaultSetting, DeleteOnDefault), + m_SectionIdent(SectionIdent) +{ + m_SectionIdent.Replace("\\","-"); + if (!m_GlideSetting) + { + m_GlideSetting = IsGlideSetting(m_SectionIdent.c_str()); + m_SectionIdent = StripNameSection(m_SectionIdent.c_str()); + } +} + +CSettingTypeRomDatabaseSetting::~CSettingTypeRomDatabaseSetting() +{ +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseSetting.h b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseSetting.h index b763ec032..3e7920162 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseSetting.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RomDatabaseSetting.h @@ -1,37 +1,37 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include "SettingsType-RomDatabase.h" - -class CSettingTypeRomDatabaseSetting : - public CSettingTypeRomDatabase -{ -public: - CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, const char * DefaultValue, bool DeleteOnDefault = false ); - CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, bool DefaultValue, bool DeleteOnDefault = false ); - CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, int DefaultValue, bool DeleteOnDefault = false ); - CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, SettingID DefaultSetting, bool DeleteOnDefault = false ); - - virtual ~CSettingTypeRomDatabaseSetting(); - - virtual SettingType GetSettingType ( void ) const { return SettingType_RdbSetting; } - -private: - virtual const char * Section ( void ) const { return m_SectionIdent.c_str(); } - - stdstr m_SectionIdent; - -private: - CSettingTypeRomDatabaseSetting(void); // Disable default constructor - CSettingTypeRomDatabaseSetting(const CSettingTypeRomDatabaseSetting&); // Disable copy constructor - CSettingTypeRomDatabaseSetting& operator=(const CSettingTypeRomDatabaseSetting&); // Disable assignment -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include "SettingsType-RomDatabase.h" + +class CSettingTypeRomDatabaseSetting : + public CSettingTypeRomDatabase +{ +public: + CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, const char * DefaultValue, bool DeleteOnDefault = false ); + CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, bool DefaultValue, bool DeleteOnDefault = false ); + CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, int DefaultValue, bool DeleteOnDefault = false ); + CSettingTypeRomDatabaseSetting(const char * SectionIdent, const char * Name, SettingID DefaultSetting, bool DeleteOnDefault = false ); + + virtual ~CSettingTypeRomDatabaseSetting(); + + virtual SettingType GetSettingType ( void ) const { return SettingType_RdbSetting; } + +private: + virtual const char * Section ( void ) const { return m_SectionIdent.c_str(); } + + stdstr m_SectionIdent; + +private: + CSettingTypeRomDatabaseSetting(void); // Disable default constructor + CSettingTypeRomDatabaseSetting(const CSettingTypeRomDatabaseSetting&); // Disable copy constructor + CSettingTypeRomDatabaseSetting& operator=(const CSettingTypeRomDatabaseSetting&); // Disable assignment +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-RomSetting.h b/Source/Project64-core/Settings/SettingType/SettingsType-RomSetting.h index dcee7573b..ab69c683f 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-RomSetting.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-RomSetting.h @@ -1,40 +1,40 @@ -#pragma once - -class CSettingTypeRomDatabase : - public CSettingType -{ -public: - CSettingTypeRomDatabase(const char * Name, const char * DefaultValue ); - CSettingTypeRomDatabase(const char * Name, bool DefaultValue ); - CSettingTypeRomDatabase(const char * Name, int32_t DefaultValue ); - CSettingTypeRomDatabase(const char * Name, SettingID DefaultSetting ); - ~CSettingTypeRomDatabase(); - - virtual SettingLocation GetSettingsLocation ( void ) const { return SettingLocation_RomDatabase; } - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - static void Initilize ( void ); - -private: - CSettingTypeRomDatabase(void); // Disable default constructor - CSettingTypeRomDatabase(const CSettingTypeRomDatabase&); // Disable copy constructor - CSettingTypeRomDatabase& operator=(const CSettingTypeRomDatabase&); // Disable assignment - - const const char * m_KeyName; - const const char * m_DefaultStr; - const int32_t m_DefaultValue; - const SettingID m_DefaultSetting; - - static CIniFile * m_SettingsIniFile; - stdstr m_SectionIdent; -}; +#pragma once + +class CSettingTypeRomDatabase : + public CSettingType +{ +public: + CSettingTypeRomDatabase(const char * Name, const char * DefaultValue ); + CSettingTypeRomDatabase(const char * Name, bool DefaultValue ); + CSettingTypeRomDatabase(const char * Name, int32_t DefaultValue ); + CSettingTypeRomDatabase(const char * Name, SettingID DefaultSetting ); + ~CSettingTypeRomDatabase(); + + virtual SettingLocation GetSettingsLocation ( void ) const { return SettingLocation_RomDatabase; } + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + static void Initilize ( void ); + +private: + CSettingTypeRomDatabase(void); // Disable default constructor + CSettingTypeRomDatabase(const CSettingTypeRomDatabase&); // Disable copy constructor + CSettingTypeRomDatabase& operator=(const CSettingTypeRomDatabase&); // Disable assignment + + const const char * m_KeyName; + const const char * m_DefaultStr; + const int32_t m_DefaultValue; + const SettingID m_DefaultSetting; + + static CIniFile * m_SettingsIniFile; + stdstr m_SectionIdent; +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-SelectedDirectory.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-SelectedDirectory.cpp index c48a0b304..d4521036b 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-SelectedDirectory.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-SelectedDirectory.cpp @@ -1,85 +1,85 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-SelectedDirectory.h" - -CSettingTypeSelectedDirectory::CSettingTypeSelectedDirectory(const char * Name, SettingID InitialDir, SettingID SelectedDir, SettingID UseSelected ) : - m_Name(Name), - m_InitialDir(InitialDir), - m_SelectedDir(SelectedDir), - m_UseSelected(UseSelected) -{ -} - -CSettingTypeSelectedDirectory::~CSettingTypeSelectedDirectory() -{ -} - -bool CSettingTypeSelectedDirectory::Load ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__,__LINE__); - return false; -} - -bool CSettingTypeSelectedDirectory::Load ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__,__LINE__); - return false; -} - -bool CSettingTypeSelectedDirectory::Load ( int /*Index*/, stdstr & Value ) const -{ - SettingID DirSettingId = g_Settings->LoadBool(m_UseSelected) ? m_SelectedDir : m_InitialDir; - return g_Settings->LoadStringVal(DirSettingId, Value); -} - -//return the default values -void CSettingTypeSelectedDirectory::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__,__LINE__); -} - -void CSettingTypeSelectedDirectory::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__,__LINE__); -} - -void CSettingTypeSelectedDirectory::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__,__LINE__); -} - -//Update the settings -void CSettingTypeSelectedDirectory::Save ( int /*Index*/, bool /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__,__LINE__); -} - -void CSettingTypeSelectedDirectory::Save ( int /*Index*/, uint32_t /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__,__LINE__); -} - -void CSettingTypeSelectedDirectory::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__,__LINE__); -} - -void CSettingTypeSelectedDirectory::Save ( int /*Index*/, const char * Value ) -{ - g_Settings->SaveBool(m_UseSelected,true); - g_Settings->SaveString(m_SelectedDir,Value); -} - -void CSettingTypeSelectedDirectory::Delete( int /*Index*/ ) -{ - g_Notify->BreakPoint(__FILE__,__LINE__); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-SelectedDirectory.h" + +CSettingTypeSelectedDirectory::CSettingTypeSelectedDirectory(const char * Name, SettingID InitialDir, SettingID SelectedDir, SettingID UseSelected ) : + m_Name(Name), + m_InitialDir(InitialDir), + m_SelectedDir(SelectedDir), + m_UseSelected(UseSelected) +{ +} + +CSettingTypeSelectedDirectory::~CSettingTypeSelectedDirectory() +{ +} + +bool CSettingTypeSelectedDirectory::Load ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeSelectedDirectory::Load ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeSelectedDirectory::Load ( int /*Index*/, stdstr & Value ) const +{ + SettingID DirSettingId = g_Settings->LoadBool(m_UseSelected) ? m_SelectedDir : m_InitialDir; + return g_Settings->LoadStringVal(DirSettingId, Value); +} + +//return the default values +void CSettingTypeSelectedDirectory::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__,__LINE__); +} + +//Update the settings +void CSettingTypeSelectedDirectory::Save ( int /*Index*/, bool /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::Save ( int /*Index*/, uint32_t /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::Save ( int /*Index*/, const char * Value ) +{ + g_Settings->SaveBool(m_UseSelected,true); + g_Settings->SaveString(m_SelectedDir,Value); +} + +void CSettingTypeSelectedDirectory::Delete( int /*Index*/ ) +{ + g_Notify->BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-SelectedDirectory.h b/Source/Project64-core/Settings/SettingType/SettingsType-SelectedDirectory.h index ea20bc320..980fbe7b4 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-SelectedDirectory.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-SelectedDirectory.h @@ -1,55 +1,55 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CSettingTypeSelectedDirectory : - public CSettingType -{ -public: - CSettingTypeSelectedDirectory(const char * Name, SettingID InitialDir, SettingID SelectedDir, SettingID UseSelected ); - ~CSettingTypeSelectedDirectory(); - - virtual bool IndexBasedSetting ( void ) const { return false; } - virtual SettingType GetSettingType ( void ) const { return SettingType_SelectedDirectory; } - - const char * GetName ( void ) const { return m_Name.c_str(); } - - //return the values - virtual bool Load ( int32_t Index, bool & Value ) const; - virtual bool Load ( int32_t Index, uint32_t & Value ) const; - virtual bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - virtual void LoadDefault ( int32_t Index, bool & Value ) const; - virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; - virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - virtual void Save ( int32_t Index, bool Value ); - virtual void Save ( int32_t Index, uint32_t Value ); - virtual void Save ( int32_t Index, const stdstr & Value ); - virtual void Save ( int32_t Index, const char * Value ); - - // Delete the setting - virtual void Delete ( int32_t Index ); - -private: - CSettingTypeSelectedDirectory(void); // Disable default constructor - CSettingTypeSelectedDirectory(const CSettingTypeSelectedDirectory&); // Disable copy constructor - CSettingTypeSelectedDirectory& operator=(const CSettingTypeSelectedDirectory&); // Disable assignment - - std::string m_Name; - SettingID m_InitialDir; - SettingID m_SelectedDir; - SettingID m_UseSelected; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CSettingTypeSelectedDirectory : + public CSettingType +{ +public: + CSettingTypeSelectedDirectory(const char * Name, SettingID InitialDir, SettingID SelectedDir, SettingID UseSelected ); + ~CSettingTypeSelectedDirectory(); + + virtual bool IndexBasedSetting ( void ) const { return false; } + virtual SettingType GetSettingType ( void ) const { return SettingType_SelectedDirectory; } + + const char * GetName ( void ) const { return m_Name.c_str(); } + + //return the values + virtual bool Load ( int32_t Index, bool & Value ) const; + virtual bool Load ( int32_t Index, uint32_t & Value ) const; + virtual bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int32_t Index, bool & Value ) const; + virtual void LoadDefault ( int32_t Index, uint32_t & Value ) const; + virtual void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int32_t Index, bool Value ); + virtual void Save ( int32_t Index, uint32_t Value ); + virtual void Save ( int32_t Index, const stdstr & Value ); + virtual void Save ( int32_t Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int32_t Index ); + +private: + CSettingTypeSelectedDirectory(void); // Disable default constructor + CSettingTypeSelectedDirectory(const CSettingTypeSelectedDirectory&); // Disable copy constructor + CSettingTypeSelectedDirectory& operator=(const CSettingTypeSelectedDirectory&); // Disable assignment + + std::string m_Name; + SettingID m_InitialDir; + SettingID m_SelectedDir; + SettingID m_UseSelected; +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-TempBool.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-TempBool.cpp index 70a8b4728..4a53d8091 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-TempBool.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-TempBool.cpp @@ -1,80 +1,80 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-TempBool.h" - -CSettingTypeTempBool::CSettingTypeTempBool(bool initialValue) : - m_value(initialValue) -{ -} - -CSettingTypeTempBool::~CSettingTypeTempBool ( void ) -{ -} - -bool CSettingTypeTempBool::Load ( int /*Index*/, bool & Value ) const -{ - Value = m_value; - return true; -} - -bool CSettingTypeTempBool::Load ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeTempBool::Load ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -//return the default values -void CSettingTypeTempBool::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempBool::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempBool::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempBool::Save ( int /*Index*/, bool Value ) -{ - m_value = Value; -} - -void CSettingTypeTempBool::Save ( int /*Index*/, uint32_t /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempBool::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempBool::Save ( int /*Index*/, const char * /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempBool::Delete( int /*Index*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-TempBool.h" + +CSettingTypeTempBool::CSettingTypeTempBool(bool initialValue) : + m_value(initialValue) +{ +} + +CSettingTypeTempBool::~CSettingTypeTempBool ( void ) +{ +} + +bool CSettingTypeTempBool::Load ( int /*Index*/, bool & Value ) const +{ + Value = m_value; + return true; +} + +bool CSettingTypeTempBool::Load ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeTempBool::Load ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +//return the default values +void CSettingTypeTempBool::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempBool::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempBool::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempBool::Save ( int /*Index*/, bool Value ) +{ + m_value = Value; +} + +void CSettingTypeTempBool::Save ( int /*Index*/, uint32_t /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempBool::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempBool::Save ( int /*Index*/, const char * /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempBool::Delete( int /*Index*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-TempBool.h b/Source/Project64-core/Settings/SettingType/SettingsType-TempBool.h index e09181793..9d5047f99 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-TempBool.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-TempBool.h @@ -1,50 +1,50 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CSettingTypeTempBool : - public CSettingType -{ -public: - CSettingTypeTempBool(bool initialValue ); - ~CSettingTypeTempBool(); - - bool IndexBasedSetting ( void ) const { return false; } - SettingType GetSettingType ( void ) const { return SettingType_BoolVariable; } - - //return the values - bool Load ( int32_t Index, bool & Value ) const; - bool Load ( int32_t Index, uint32_t & Value ) const; - bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - void LoadDefault ( int32_t Index, bool & Value ) const; - void LoadDefault ( int32_t Index, uint32_t & Value ) const; - void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - void Save ( int32_t Index, bool Value ); - void Save ( int32_t Index, uint32_t Value ); - void Save ( int32_t Index, const stdstr & Value ); - void Save ( int32_t Index, const char * Value ); - - // Delete the setting - void Delete ( int32_t Index ); - -private: - CSettingTypeTempBool(void); // Disable default constructor - CSettingTypeTempBool(const CSettingTypeTempBool&); // Disable copy constructor - CSettingTypeTempBool& operator=(const CSettingTypeTempBool&); // Disable assignment - - bool m_value; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CSettingTypeTempBool : + public CSettingType +{ +public: + CSettingTypeTempBool(bool initialValue ); + ~CSettingTypeTempBool(); + + bool IndexBasedSetting ( void ) const { return false; } + SettingType GetSettingType ( void ) const { return SettingType_BoolVariable; } + + //return the values + bool Load ( int32_t Index, bool & Value ) const; + bool Load ( int32_t Index, uint32_t & Value ) const; + bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + void LoadDefault ( int32_t Index, bool & Value ) const; + void LoadDefault ( int32_t Index, uint32_t & Value ) const; + void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + void Save ( int32_t Index, bool Value ); + void Save ( int32_t Index, uint32_t Value ); + void Save ( int32_t Index, const stdstr & Value ); + void Save ( int32_t Index, const char * Value ); + + // Delete the setting + void Delete ( int32_t Index ); + +private: + CSettingTypeTempBool(void); // Disable default constructor + CSettingTypeTempBool(const CSettingTypeTempBool&); // Disable copy constructor + CSettingTypeTempBool& operator=(const CSettingTypeTempBool&); // Disable assignment + + bool m_value; +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-TempNumber.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-TempNumber.cpp index 35796870a..6511d760f 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-TempNumber.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-TempNumber.cpp @@ -1,80 +1,80 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-TempNumber.h" - -CSettingTypeTempNumber::CSettingTypeTempNumber(uint32_t initialValue) : - m_value(initialValue) -{ -} - -CSettingTypeTempNumber::~CSettingTypeTempNumber ( void ) -{ -} - -bool CSettingTypeTempNumber::Load ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return true; -} - -bool CSettingTypeTempNumber::Load ( int /*Index*/, uint32_t & Value ) const -{ - Value = m_value; - return false; -} - -bool CSettingTypeTempNumber::Load ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -//return the default values -void CSettingTypeTempNumber::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempNumber::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempNumber::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempNumber::Save ( int /*Index*/, bool /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempNumber::Save ( int /*Index*/, uint32_t Value ) -{ - m_value = Value; -} - -void CSettingTypeTempNumber::Save ( int /*Index*/, const stdstr & /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempNumber::Save ( int /*Index*/, const char * /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempNumber::Delete( int /*Index*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-TempNumber.h" + +CSettingTypeTempNumber::CSettingTypeTempNumber(uint32_t initialValue) : + m_value(initialValue) +{ +} + +CSettingTypeTempNumber::~CSettingTypeTempNumber ( void ) +{ +} + +bool CSettingTypeTempNumber::Load ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return true; +} + +bool CSettingTypeTempNumber::Load ( int /*Index*/, uint32_t & Value ) const +{ + Value = m_value; + return false; +} + +bool CSettingTypeTempNumber::Load ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +//return the default values +void CSettingTypeTempNumber::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempNumber::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempNumber::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempNumber::Save ( int /*Index*/, bool /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempNumber::Save ( int /*Index*/, uint32_t Value ) +{ + m_value = Value; +} + +void CSettingTypeTempNumber::Save ( int /*Index*/, const stdstr & /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempNumber::Save ( int /*Index*/, const char * /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempNumber::Delete( int /*Index*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-TempNumber.h b/Source/Project64-core/Settings/SettingType/SettingsType-TempNumber.h index 9b5727bc8..0c8a0be26 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-TempNumber.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-TempNumber.h @@ -1,50 +1,50 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CSettingTypeTempNumber : - public CSettingType -{ -public: - CSettingTypeTempNumber(uint32_t initialValue); - ~CSettingTypeTempNumber(); - - bool IndexBasedSetting ( void ) const { return false; } - SettingType GetSettingType ( void ) const { return SettingType_NumberVariable; } - - //return the values - bool Load ( int32_t Index, bool & Value ) const; - bool Load ( int32_t Index, uint32_t & Value ) const; - bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - void LoadDefault ( int32_t Index, bool & Value ) const; - void LoadDefault ( int32_t Index, uint32_t & Value ) const; - void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - void Save ( int32_t Index, bool Value ); - void Save ( int32_t Index, uint32_t Value ); - void Save ( int32_t Index, const stdstr & Value ); - void Save ( int32_t Index, const char * Value ); - - // Delete the setting - void Delete ( int32_t Index ); - -private: - CSettingTypeTempNumber(void); // Disable default constructor - CSettingTypeTempNumber(const CSettingTypeTempNumber&); // Disable copy constructor - CSettingTypeTempNumber& operator=(const CSettingTypeTempNumber&); // Disable assignment - - uint32_t m_value; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CSettingTypeTempNumber : + public CSettingType +{ +public: + CSettingTypeTempNumber(uint32_t initialValue); + ~CSettingTypeTempNumber(); + + bool IndexBasedSetting ( void ) const { return false; } + SettingType GetSettingType ( void ) const { return SettingType_NumberVariable; } + + //return the values + bool Load ( int32_t Index, bool & Value ) const; + bool Load ( int32_t Index, uint32_t & Value ) const; + bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + void LoadDefault ( int32_t Index, bool & Value ) const; + void LoadDefault ( int32_t Index, uint32_t & Value ) const; + void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + void Save ( int32_t Index, bool Value ); + void Save ( int32_t Index, uint32_t Value ); + void Save ( int32_t Index, const stdstr & Value ); + void Save ( int32_t Index, const char * Value ); + + // Delete the setting + void Delete ( int32_t Index ); + +private: + CSettingTypeTempNumber(void); // Disable default constructor + CSettingTypeTempNumber(const CSettingTypeTempNumber&); // Disable copy constructor + CSettingTypeTempNumber& operator=(const CSettingTypeTempNumber&); // Disable assignment + + uint32_t m_value; +}; diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-TempString.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-TempString.cpp index 51a56124a..940365701 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-TempString.cpp +++ b/Source/Project64-core/Settings/SettingType/SettingsType-TempString.cpp @@ -1,80 +1,80 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "SettingsType-TempString.h" - -CSettingTypeTempString::CSettingTypeTempString(const char * initialValue) : - m_value(initialValue) -{ -} - -CSettingTypeTempString::~CSettingTypeTempString ( void ) -{ -} - -bool CSettingTypeTempString::Load ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeTempString::Load ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -bool CSettingTypeTempString::Load ( int /*Index*/, stdstr & Value ) const -{ - Value = m_value; - return true; -} - -//return the default values -void CSettingTypeTempString::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempString::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempString::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempString::Save ( int /*Index*/, bool /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempString::Save ( int /*Index*/, uint32_t /*Value*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettingTypeTempString::Save ( int /*Index*/, const stdstr & Value ) -{ - m_value = Value; -} - -void CSettingTypeTempString::Save ( int /*Index*/, const char * Value ) -{ - m_value = Value; -} - -void CSettingTypeTempString::Delete( int /*Index*/ ) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "SettingsType-TempString.h" + +CSettingTypeTempString::CSettingTypeTempString(const char * initialValue) : + m_value(initialValue) +{ +} + +CSettingTypeTempString::~CSettingTypeTempString ( void ) +{ +} + +bool CSettingTypeTempString::Load ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeTempString::Load ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +bool CSettingTypeTempString::Load ( int /*Index*/, stdstr & Value ) const +{ + Value = m_value; + return true; +} + +//return the default values +void CSettingTypeTempString::LoadDefault ( int /*Index*/, bool & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempString::LoadDefault ( int /*Index*/, uint32_t & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempString::LoadDefault ( int /*Index*/, stdstr & /*Value*/ ) const +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempString::Save ( int /*Index*/, bool /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempString::Save ( int /*Index*/, uint32_t /*Value*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettingTypeTempString::Save ( int /*Index*/, const stdstr & Value ) +{ + m_value = Value; +} + +void CSettingTypeTempString::Save ( int /*Index*/, const char * Value ) +{ + m_value = Value; +} + +void CSettingTypeTempString::Delete( int /*Index*/ ) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-TempString.h b/Source/Project64-core/Settings/SettingType/SettingsType-TempString.h index e7f3be1e4..9856009ed 100644 --- a/Source/Project64-core/Settings/SettingType/SettingsType-TempString.h +++ b/Source/Project64-core/Settings/SettingType/SettingsType-TempString.h @@ -1,50 +1,50 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CSettingTypeTempString : - public CSettingType -{ -public: - CSettingTypeTempString(const char * initialValue); - ~CSettingTypeTempString(); - - bool IndexBasedSetting ( void ) const { return false; } - SettingType GetSettingType ( void ) const { return SettingType_StringVariable; } - - //return the values - bool Load ( int32_t Index, bool & Value ) const; - bool Load ( int32_t Index, uint32_t & Value ) const; - bool Load ( int32_t Index, stdstr & Value ) const; - - //return the default values - void LoadDefault ( int32_t Index, bool & Value ) const; - void LoadDefault ( int32_t Index, uint32_t & Value ) const; - void LoadDefault ( int32_t Index, stdstr & Value ) const; - - //Update the settings - void Save ( int32_t Index, bool Value ); - void Save ( int32_t Index, uint32_t Value ); - void Save ( int32_t Index, const stdstr & Value ); - void Save ( int32_t Index, const char * Value ); - - // Delete the setting - void Delete ( int32_t Index ); - -private: - CSettingTypeTempString(void); // Disable default constructor - CSettingTypeTempString(const CSettingTypeTempString&); // Disable copy constructor - CSettingTypeTempString& operator=(const CSettingTypeTempString&); // Disable assignment - - stdstr m_value; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CSettingTypeTempString : + public CSettingType +{ +public: + CSettingTypeTempString(const char * initialValue); + ~CSettingTypeTempString(); + + bool IndexBasedSetting ( void ) const { return false; } + SettingType GetSettingType ( void ) const { return SettingType_StringVariable; } + + //return the values + bool Load ( int32_t Index, bool & Value ) const; + bool Load ( int32_t Index, uint32_t & Value ) const; + bool Load ( int32_t Index, stdstr & Value ) const; + + //return the default values + void LoadDefault ( int32_t Index, bool & Value ) const; + void LoadDefault ( int32_t Index, uint32_t & Value ) const; + void LoadDefault ( int32_t Index, stdstr & Value ) const; + + //Update the settings + void Save ( int32_t Index, bool Value ); + void Save ( int32_t Index, uint32_t Value ); + void Save ( int32_t Index, const stdstr & Value ); + void Save ( int32_t Index, const char * Value ); + + // Delete the setting + void Delete ( int32_t Index ); + +private: + CSettingTypeTempString(void); // Disable default constructor + CSettingTypeTempString(const CSettingTypeTempString&); // Disable copy constructor + CSettingTypeTempString& operator=(const CSettingTypeTempString&); // Disable assignment + + stdstr m_value; +}; diff --git a/Source/Project64-core/Settings/Settings.h b/Source/Project64-core/Settings/Settings.h index 010f4cc1d..43eb12bd4 100644 --- a/Source/Project64-core/Settings/Settings.h +++ b/Source/Project64-core/Settings/Settings.h @@ -1,318 +1,318 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -enum -{ - MaxPluginSetting = 65535 -}; - -enum SettingID -{ - //Default values - Default_None, - Default_Constant, - - //information - temp keys - Info_ShortCutsChanged, - - //Command Settings - Cmd_BaseDirectory, - Cmd_RomFile, - Cmd_ShowHelp, - - //Support Files - SupportFile_Settings, - SupportFile_SettingsDefault, - SupportFile_RomDatabase, - SupportFile_RomDatabaseDefault, - SupportFile_Glide64RDB, - SupportFile_Glide64RDBDefault, - SupportFile_Cheats, - SupportFile_CheatsDefault, - SupportFile_Notes, - SupportFile_NotesDefault, - SupportFile_ExtInfo, - SupportFile_ExtInfoDefault, - SupportFile_ShortCuts, - SupportFile_ShortCutsDefault, - SupportFile_RomListCache, - SupportFile_RomListCacheDefault, - SupportFile_7zipCache, - SupportFile_7zipCacheDefault, - - //Settings - Setting_ApplicationName, - Setting_UseFromRegistry, - Setting_RdbEditor, - Setting_CN64TimeCritical, - Setting_PluginPageFirst, - Setting_DisableScrSaver, - Setting_AutoSleep, - Setting_AutoStart, - Setting_AutoFullscreen, - Setting_CheckEmuRunning, - Setting_EraseGameDefaults, - - Setting_AutoZipInstantSave, - Setting_RememberCheats, - Setting_LanguageDir, - Setting_LanguageDirDefault, - Setting_CurrentLanguage, - Setting_EnableDisk, - - //RDB TLB Settings - Rdb_GoodName, - Rdb_SaveChip, - Rdb_CpuType, - Rdb_RDRamSize, - Rdb_CounterFactor, - Rdb_UseTlb, - Rdb_DelayDP, - Rdb_DelaySi, - Rdb_32Bit, - Rdb_FastSP, - Rdb_Status, - Rdb_NotesCore, - Rdb_NotesPlugin, - Rdb_FixedAudio, - Rdb_SyncViaAudio, - Rdb_RspAudioSignal, - Rdb_TLB_VAddrStart, - Rdb_TLB_VAddrLen, - Rdb_TLB_PAddrStart, - Rdb_UseHleGfx, - Rdb_UseHleAudio, - Rdb_LoadRomToMemory, - Rdb_ScreenHertz, - Rdb_FuncLookupMode, - Rdb_RegCache, - Rdb_BlockLinking, - Rdb_SMM_StoreInstruc, - Rdb_SMM_Cache, - Rdb_SMM_PIDMA, - Rdb_SMM_TLB, - Rdb_SMM_Protect, - Rdb_SMM_ValidFunc, - Rdb_GameCheatFix, - Rdb_GameCheatFixPlugin, - Rdb_ViRefreshRate, - Rdb_AiCountPerBytes, - Rdb_AudioResetOnLoad, - Rdb_AllowROMWrites, - Rdb_CRC_Recalc, - - //Individual Game Settings - Game_IniKey, - Game_File, - Game_GameName, - Game_GoodName, - Game_TempLoaded, - Game_SystemType, - Game_EditPlugin_Gfx, - Game_EditPlugin_Audio, - Game_EditPlugin_Contr, - Game_EditPlugin_RSP, - Game_Plugin_Gfx, - Game_Plugin_Audio, - Game_Plugin_Controller, - Game_Plugin_RSP, - Game_SaveChip, - Game_CpuType, - Game_LastSaveSlot, - Game_FixedAudio, - Game_SyncViaAudio, - Game_32Bit, - Game_SMM_Cache, - Game_SMM_Protect, - Game_SMM_ValidFunc, - Game_SMM_PIDMA, - Game_SMM_TLB, - Game_SMM_StoreInstruc, - Game_CurrentSaveState, - Game_RDRamSize, - Game_CounterFactor, - Game_UseTlb, - Game_DelayDP, - Game_DelaySI, - Game_FastSP, - Game_FuncLookupMode, - Game_RegCache, - Game_BlockLinking, - Game_ScreenHertz, - Game_RspAudioSignal, - Game_UseHleGfx, - Game_UseHleAudio, - Game_LoadRomToMemory, - Game_ViRefreshRate, - Game_AiCountPerBytes, - Game_AudioResetOnLoad, - Game_AllowROMWrites, - Game_CRC_Recalc, - - // General Game running info - GameRunning_LoadingInProgress, - GameRunning_CPU_Running, - GameRunning_CPU_Paused, - GameRunning_CPU_PausedType, - GameRunning_InstantSaveFile, - GameRunning_LimitFPS, - GameRunning_ScreenHertz, - GameRunning_InReset, - - //User Interface - UserInterface_BasicMode, - UserInterface_ShowCPUPer, - UserInterface_DisplayFrameRate, - UserInterface_InFullScreen, - UserInterface_FrameDisplayType, - UserInterface_MainWindowTop, - UserInterface_MainWindowLeft, - UserInterface_AlwaysOnTop, - - RomBrowser_Enabled, - RomBrowser_ColoumnsChanged, - RomBrowser_Top, - RomBrowser_Left, - RomBrowser_Width, - RomBrowser_Height, - RomBrowser_PosIndex, - RomBrowser_WidthIndex, - RomBrowser_SortFieldIndex, - RomBrowser_SortAscendingIndex, - RomBrowser_Recursive, - RomBrowser_Maximized, - - //Directory Info - Directory_LastSave, - Directory_RecentGameDirCount, - Directory_RecentGameDirIndex, - Directory_Game, - Directory_GameInitial, - Directory_GameSelected, - Directory_GameUseSelected, - Directory_Plugin, - Directory_PluginInitial, - Directory_PluginSelected, - Directory_PluginUseSelected, - Directory_PluginSync, - Directory_SnapShot, - Directory_SnapShotInitial, - Directory_SnapShotSelected, - Directory_SnapShotUseSelected, - Directory_NativeSave, - Directory_NativeSaveInitial, - Directory_NativeSaveSelected, - Directory_NativeSaveUseSelected, - Directory_InstantSave, - Directory_InstantSaveInitial, - Directory_InstantSaveSelected, - Directory_InstantSaveUseSelected, - Directory_Texture, - Directory_TextureInitial, - Directory_TextureSelected, - Directory_TextureUseSelected, - - //File Info - File_RecentGameFileCount, - File_RecentGameFileIndex, - File_DiskIPLPath, - - //Debugger - Debugger_Enabled, - Debugger_ShowTLBMisses, - Debugger_ShowUnhandledMemory, - Debugger_ShowPifErrors, - Debugger_ShowDivByZero, - Debugger_GenerateLogFiles, - Debugger_ProfileCode, - Debugger_DisableGameFixes, - Debugger_AppLogLevel, - Debugger_AppLogFlush, - Debugger_ShowDListAListCount, - Debugger_ShowRecompMemSize, - - //Trace - Debugger_TraceMD5, - Debugger_TraceSettings, - Debugger_TraceUnknown, - Debugger_TraceAppInit, - Debugger_TraceAppCleanup, - Debugger_TraceN64System, - Debugger_TracePlugins, - Debugger_TraceGFXPlugin, - Debugger_TraceAudioPlugin, - Debugger_TraceControllerPlugin, - Debugger_TraceRSPPlugin, - Debugger_TraceRSP, - Debugger_TraceAudio, - Debugger_TraceRegisterCache, - Debugger_TraceRecompiler, - Debugger_TraceTLB, - Debugger_TraceProtectedMEM, - Debugger_TraceUserInterface, - - //Plugins - Plugin_RSP_Current, - Plugin_RSP_CurVer, - Plugin_GFX_Current, - Plugin_GFX_CurVer, - Plugin_AUDIO_Current, - Plugin_AUDIO_CurVer, - Plugin_CONT_Current, - Plugin_CONT_CurVer, - Plugin_UseHleGfx, - Plugin_UseHleAudio, - - Logging_GenerateLog, - Logging_LogRDRamRegisters, - Logging_LogSPRegisters, - Logging_LogDPCRegisters, - Logging_LogDPSRegisters, - Logging_LogMIPSInterface, - Logging_LogVideoInterface, - Logging_LogAudioInterface, - Logging_LogPerInterface, - Logging_LogRDRAMInterface, - Logging_LogSerialInterface, - Logging_LogPRDMAOperations, - Logging_LogPRDirectMemLoads, - Logging_LogPRDMAMemLoads, - Logging_LogPRDirectMemStores, - Logging_LogPRDMAMemStores, - Logging_LogControllerPak, - Logging_LogCP0changes, - Logging_LogCP0reads, - Logging_LogTLB, - Logging_LogExceptions, - Logging_NoInterrupts, - Logging_LogCache, - Logging_LogRomHeader, - Logging_LogUnknown, - - //Cheats - Cheat_Entry, - Cheat_Active, - Cheat_Extension, - Cheat_Notes, - Cheat_Options, - Cheat_Range, - Cheat_RangeNotes, - - FirstRSPDefaultSet, LastRSPDefaultSet = FirstRSPDefaultSet + MaxPluginSetting, - FirstRSPSettings, LastRSPSettings = FirstRSPSettings + MaxPluginSetting, - FirstGfxDefaultSet, LastGfxDefaultSet = FirstGfxDefaultSet + MaxPluginSetting, - FirstGfxSettings, LastGfxSettings = FirstGfxSettings + MaxPluginSetting, - FirstAudioDefaultSet, LastAudioDefaultSet = FirstAudioDefaultSet + MaxPluginSetting, - FirstAudioSettings, LastAudioSettings = FirstAudioSettings + MaxPluginSetting, - FirstCtrlDefaultSet, LastCtrlDefaultSet = FirstCtrlDefaultSet + MaxPluginSetting, - FirstCtrlSettings, LastCtrlSettings = FirstCtrlSettings + MaxPluginSetting, -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +enum +{ + MaxPluginSetting = 65535 +}; + +enum SettingID +{ + //Default values + Default_None, + Default_Constant, + + //information - temp keys + Info_ShortCutsChanged, + + //Command Settings + Cmd_BaseDirectory, + Cmd_RomFile, + Cmd_ShowHelp, + + //Support Files + SupportFile_Settings, + SupportFile_SettingsDefault, + SupportFile_RomDatabase, + SupportFile_RomDatabaseDefault, + SupportFile_Glide64RDB, + SupportFile_Glide64RDBDefault, + SupportFile_Cheats, + SupportFile_CheatsDefault, + SupportFile_Notes, + SupportFile_NotesDefault, + SupportFile_ExtInfo, + SupportFile_ExtInfoDefault, + SupportFile_ShortCuts, + SupportFile_ShortCutsDefault, + SupportFile_RomListCache, + SupportFile_RomListCacheDefault, + SupportFile_7zipCache, + SupportFile_7zipCacheDefault, + + //Settings + Setting_ApplicationName, + Setting_UseFromRegistry, + Setting_RdbEditor, + Setting_CN64TimeCritical, + Setting_PluginPageFirst, + Setting_DisableScrSaver, + Setting_AutoSleep, + Setting_AutoStart, + Setting_AutoFullscreen, + Setting_CheckEmuRunning, + Setting_EraseGameDefaults, + + Setting_AutoZipInstantSave, + Setting_RememberCheats, + Setting_LanguageDir, + Setting_LanguageDirDefault, + Setting_CurrentLanguage, + Setting_EnableDisk, + + //RDB TLB Settings + Rdb_GoodName, + Rdb_SaveChip, + Rdb_CpuType, + Rdb_RDRamSize, + Rdb_CounterFactor, + Rdb_UseTlb, + Rdb_DelayDP, + Rdb_DelaySi, + Rdb_32Bit, + Rdb_FastSP, + Rdb_Status, + Rdb_NotesCore, + Rdb_NotesPlugin, + Rdb_FixedAudio, + Rdb_SyncViaAudio, + Rdb_RspAudioSignal, + Rdb_TLB_VAddrStart, + Rdb_TLB_VAddrLen, + Rdb_TLB_PAddrStart, + Rdb_UseHleGfx, + Rdb_UseHleAudio, + Rdb_LoadRomToMemory, + Rdb_ScreenHertz, + Rdb_FuncLookupMode, + Rdb_RegCache, + Rdb_BlockLinking, + Rdb_SMM_StoreInstruc, + Rdb_SMM_Cache, + Rdb_SMM_PIDMA, + Rdb_SMM_TLB, + Rdb_SMM_Protect, + Rdb_SMM_ValidFunc, + Rdb_GameCheatFix, + Rdb_GameCheatFixPlugin, + Rdb_ViRefreshRate, + Rdb_AiCountPerBytes, + Rdb_AudioResetOnLoad, + Rdb_AllowROMWrites, + Rdb_CRC_Recalc, + + //Individual Game Settings + Game_IniKey, + Game_File, + Game_GameName, + Game_GoodName, + Game_TempLoaded, + Game_SystemType, + Game_EditPlugin_Gfx, + Game_EditPlugin_Audio, + Game_EditPlugin_Contr, + Game_EditPlugin_RSP, + Game_Plugin_Gfx, + Game_Plugin_Audio, + Game_Plugin_Controller, + Game_Plugin_RSP, + Game_SaveChip, + Game_CpuType, + Game_LastSaveSlot, + Game_FixedAudio, + Game_SyncViaAudio, + Game_32Bit, + Game_SMM_Cache, + Game_SMM_Protect, + Game_SMM_ValidFunc, + Game_SMM_PIDMA, + Game_SMM_TLB, + Game_SMM_StoreInstruc, + Game_CurrentSaveState, + Game_RDRamSize, + Game_CounterFactor, + Game_UseTlb, + Game_DelayDP, + Game_DelaySI, + Game_FastSP, + Game_FuncLookupMode, + Game_RegCache, + Game_BlockLinking, + Game_ScreenHertz, + Game_RspAudioSignal, + Game_UseHleGfx, + Game_UseHleAudio, + Game_LoadRomToMemory, + Game_ViRefreshRate, + Game_AiCountPerBytes, + Game_AudioResetOnLoad, + Game_AllowROMWrites, + Game_CRC_Recalc, + + // General Game running info + GameRunning_LoadingInProgress, + GameRunning_CPU_Running, + GameRunning_CPU_Paused, + GameRunning_CPU_PausedType, + GameRunning_InstantSaveFile, + GameRunning_LimitFPS, + GameRunning_ScreenHertz, + GameRunning_InReset, + + //User Interface + UserInterface_BasicMode, + UserInterface_ShowCPUPer, + UserInterface_DisplayFrameRate, + UserInterface_InFullScreen, + UserInterface_FrameDisplayType, + UserInterface_MainWindowTop, + UserInterface_MainWindowLeft, + UserInterface_AlwaysOnTop, + + RomBrowser_Enabled, + RomBrowser_ColoumnsChanged, + RomBrowser_Top, + RomBrowser_Left, + RomBrowser_Width, + RomBrowser_Height, + RomBrowser_PosIndex, + RomBrowser_WidthIndex, + RomBrowser_SortFieldIndex, + RomBrowser_SortAscendingIndex, + RomBrowser_Recursive, + RomBrowser_Maximized, + + //Directory Info + Directory_LastSave, + Directory_RecentGameDirCount, + Directory_RecentGameDirIndex, + Directory_Game, + Directory_GameInitial, + Directory_GameSelected, + Directory_GameUseSelected, + Directory_Plugin, + Directory_PluginInitial, + Directory_PluginSelected, + Directory_PluginUseSelected, + Directory_PluginSync, + Directory_SnapShot, + Directory_SnapShotInitial, + Directory_SnapShotSelected, + Directory_SnapShotUseSelected, + Directory_NativeSave, + Directory_NativeSaveInitial, + Directory_NativeSaveSelected, + Directory_NativeSaveUseSelected, + Directory_InstantSave, + Directory_InstantSaveInitial, + Directory_InstantSaveSelected, + Directory_InstantSaveUseSelected, + Directory_Texture, + Directory_TextureInitial, + Directory_TextureSelected, + Directory_TextureUseSelected, + + //File Info + File_RecentGameFileCount, + File_RecentGameFileIndex, + File_DiskIPLPath, + + //Debugger + Debugger_Enabled, + Debugger_ShowTLBMisses, + Debugger_ShowUnhandledMemory, + Debugger_ShowPifErrors, + Debugger_ShowDivByZero, + Debugger_GenerateLogFiles, + Debugger_ProfileCode, + Debugger_DisableGameFixes, + Debugger_AppLogLevel, + Debugger_AppLogFlush, + Debugger_ShowDListAListCount, + Debugger_ShowRecompMemSize, + + //Trace + Debugger_TraceMD5, + Debugger_TraceSettings, + Debugger_TraceUnknown, + Debugger_TraceAppInit, + Debugger_TraceAppCleanup, + Debugger_TraceN64System, + Debugger_TracePlugins, + Debugger_TraceGFXPlugin, + Debugger_TraceAudioPlugin, + Debugger_TraceControllerPlugin, + Debugger_TraceRSPPlugin, + Debugger_TraceRSP, + Debugger_TraceAudio, + Debugger_TraceRegisterCache, + Debugger_TraceRecompiler, + Debugger_TraceTLB, + Debugger_TraceProtectedMEM, + Debugger_TraceUserInterface, + + //Plugins + Plugin_RSP_Current, + Plugin_RSP_CurVer, + Plugin_GFX_Current, + Plugin_GFX_CurVer, + Plugin_AUDIO_Current, + Plugin_AUDIO_CurVer, + Plugin_CONT_Current, + Plugin_CONT_CurVer, + Plugin_UseHleGfx, + Plugin_UseHleAudio, + + Logging_GenerateLog, + Logging_LogRDRamRegisters, + Logging_LogSPRegisters, + Logging_LogDPCRegisters, + Logging_LogDPSRegisters, + Logging_LogMIPSInterface, + Logging_LogVideoInterface, + Logging_LogAudioInterface, + Logging_LogPerInterface, + Logging_LogRDRAMInterface, + Logging_LogSerialInterface, + Logging_LogPRDMAOperations, + Logging_LogPRDirectMemLoads, + Logging_LogPRDMAMemLoads, + Logging_LogPRDirectMemStores, + Logging_LogPRDMAMemStores, + Logging_LogControllerPak, + Logging_LogCP0changes, + Logging_LogCP0reads, + Logging_LogTLB, + Logging_LogExceptions, + Logging_NoInterrupts, + Logging_LogCache, + Logging_LogRomHeader, + Logging_LogUnknown, + + //Cheats + Cheat_Entry, + Cheat_Active, + Cheat_Extension, + Cheat_Notes, + Cheat_Options, + Cheat_Range, + Cheat_RangeNotes, + + FirstRSPDefaultSet, LastRSPDefaultSet = FirstRSPDefaultSet + MaxPluginSetting, + FirstRSPSettings, LastRSPSettings = FirstRSPSettings + MaxPluginSetting, + FirstGfxDefaultSet, LastGfxDefaultSet = FirstGfxDefaultSet + MaxPluginSetting, + FirstGfxSettings, LastGfxSettings = FirstGfxSettings + MaxPluginSetting, + FirstAudioDefaultSet, LastAudioDefaultSet = FirstAudioDefaultSet + MaxPluginSetting, + FirstAudioSettings, LastAudioSettings = FirstAudioSettings + MaxPluginSetting, + FirstCtrlDefaultSet, LastCtrlDefaultSet = FirstCtrlDefaultSet + MaxPluginSetting, + FirstCtrlSettings, LastCtrlSettings = FirstCtrlSettings + MaxPluginSetting, +}; diff --git a/Source/Project64-core/Settings/SettingsClass.cpp b/Source/Project64-core/Settings/SettingsClass.cpp index eff641bb6..98fec7585 100644 --- a/Source/Project64-core/Settings/SettingsClass.cpp +++ b/Source/Project64-core/Settings/SettingsClass.cpp @@ -1,1247 +1,1247 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include -#include "SettingType/SettingsType-Application.h" -#include "SettingType/SettingsType-ApplicationPath.h" -#include "SettingType/SettingsType-ApplicationIndex.h" -#include "SettingType/SettingsType-Cheats.h" -#include "SettingType/SettingsType-GameSetting.h" -#include "SettingType/SettingsType-GameSettingIndex.h" -#include "SettingType/SettingsType-RelativePath.h" -#include "SettingType/SettingsType-RomDatabase.h" -#include "SettingType/SettingsType-RomDatabaseSetting.h" -#include "SettingType/SettingsType-RomDatabaseIndex.h" -#include "SettingType/SettingsType-RDBCpuType.h" -#include "SettingType/SettingsType-RDBRamSize.h" -#include "SettingType/SettingsType-RDBSaveChip.h" -#include "SettingType/SettingsType-RDBYesNo.h" -#include "SettingType/SettingsType-RDBOnOff.h" -#include "SettingType/SettingsType-SelectedDirectory.h" -#include "SettingType/SettingsType-TempString.h" -#include "SettingType/SettingsType-TempNumber.h" -#include "SettingType/SettingsType-TempBool.h" -#include "SettingsClass.h" -#include -#include - -CSettings * g_Settings = NULL; - -CSettings::CSettings() : -m_NextAutoSettingId(0x200000) -{ -} - -CSettings::~CSettings() -{ - CSettingTypeApplication::CleanUp(); - CSettingTypeRomDatabase::CleanUp(); - CSettingTypeGame::CleanUp(); - CSettingTypeCheats::CleanUp(); - - for (SETTING_MAP::iterator iter = m_SettingInfo.begin(); iter != m_SettingInfo.end(); iter++) - { - delete iter->second; - } - - for (SETTING_CALLBACK::iterator cb_iter = m_Callback.begin(); cb_iter != m_Callback.end(); cb_iter++) - { - SETTING_CHANGED_CB * item = cb_iter->second; - while (item != NULL) - { - SETTING_CHANGED_CB * current_item = item; - item = item->Next; - delete current_item; - } - } -} - -void CSettings::AddHandler(SettingID TypeID, CSettingType * Handler) -{ - std::pair res = m_SettingInfo.insert(SETTING_MAP::value_type(TypeID, Handler)); - if (!res.second) - { - delete res.first->second; - m_SettingInfo.erase(res.first); - res = m_SettingInfo.insert(SETTING_MAP::value_type(TypeID, Handler)); - if (!res.second) - { - delete Handler; - } - } -} - -void CSettings::AddHowToHandleSetting() -{ - //information - temp keys - AddHandler(Info_ShortCutsChanged, new CSettingTypeTempBool(false)); - - //Command Settings -#ifdef _WIN32 - AddHandler(Cmd_BaseDirectory, new CSettingTypeTempString(CPath(CPath::MODULE_DIRECTORY))); -#else - AddHandler(Cmd_BaseDirectory, new CSettingTypeTempString("")); -#endif - AddHandler(Cmd_ShowHelp, new CSettingTypeTempBool(false)); - AddHandler(Cmd_RomFile, new CSettingTypeTempString("")); - - //Support Files - AddHandler(SupportFile_Settings, new CSettingTypeApplicationPath("", "ConfigFile", SupportFile_SettingsDefault)); - AddHandler(SupportFile_SettingsDefault, new CSettingTypeRelativePath("Config", "Project64.cfg")); - AddHandler(SupportFile_RomDatabase, new CSettingTypeApplicationPath("", "RomDatabase", SupportFile_RomDatabaseDefault)); - AddHandler(SupportFile_RomDatabaseDefault, new CSettingTypeRelativePath("Config", "Project64.rdb")); - AddHandler(SupportFile_Glide64RDB, new CSettingTypeApplicationPath("", "Glide64RDB", SupportFile_Glide64RDBDefault)); - AddHandler(SupportFile_Glide64RDBDefault, new CSettingTypeRelativePath("Config", "Glide64.rdb")); - AddHandler(SupportFile_Cheats, new CSettingTypeApplicationPath("", "Cheats", SupportFile_CheatsDefault)); - AddHandler(SupportFile_CheatsDefault, new CSettingTypeRelativePath("Config", "Project64.cht")); - AddHandler(SupportFile_Notes, new CSettingTypeApplicationPath("", "Notes", SupportFile_NotesDefault)); - AddHandler(SupportFile_NotesDefault, new CSettingTypeRelativePath("Config", "Project64.rdn")); - AddHandler(SupportFile_ExtInfo, new CSettingTypeApplicationPath("", "ExtInfo", SupportFile_ExtInfoDefault)); - AddHandler(SupportFile_ExtInfoDefault, new CSettingTypeRelativePath("Config", "Project64.rdx")); - AddHandler(SupportFile_ShortCuts, new CSettingTypeApplicationPath("", "ShortCuts", SupportFile_ShortCutsDefault)); - AddHandler(SupportFile_ShortCutsDefault, new CSettingTypeRelativePath("Config", "Project64.sc3")); - AddHandler(SupportFile_RomListCache, new CSettingTypeApplicationPath("", "RomListCache", SupportFile_RomListCacheDefault)); - AddHandler(SupportFile_RomListCacheDefault, new CSettingTypeRelativePath("Config", "Project64.cache3")); - AddHandler(SupportFile_7zipCache, new CSettingTypeApplicationPath("", "7zipCache", SupportFile_7zipCacheDefault)); - AddHandler(SupportFile_7zipCacheDefault, new CSettingTypeRelativePath("Config", "Project64.zcache")); - - //AddHandler(SyncPluginDir, new CSettingTypeRelativePath("SyncPlugin","")); - - //Settings location - AddHandler(Setting_ApplicationName, new CSettingTypeTempString("")); - AddHandler(Setting_UseFromRegistry, new CSettingTypeApplication("Settings", "Use Registry", (uint32_t)false)); - AddHandler(Setting_RdbEditor, new CSettingTypeApplication("", "Rdb Editor", false)); - AddHandler(Setting_CN64TimeCritical, new CSettingTypeApplication("", "CN64TimeCritical", false)); - AddHandler(Setting_PluginPageFirst, new CSettingTypeApplication("", "Plugin Page First", false)); - AddHandler(Setting_DisableScrSaver, new CSettingTypeApplication("", "Disable Screen Saver", (uint32_t)true)); - AddHandler(Setting_AutoSleep, new CSettingTypeApplication("", "Auto Sleep", (uint32_t)true)); - AddHandler(Setting_AutoStart, new CSettingTypeApplication("", "Auto Start", (uint32_t)true)); - AddHandler(Setting_AutoFullscreen, new CSettingTypeApplication("", "Auto Full Screen", (uint32_t)false)); - AddHandler(Setting_AutoZipInstantSave, new CSettingTypeApplication("", "Auto Zip Saves", (uint32_t)true)); - AddHandler(Setting_EraseGameDefaults, new CSettingTypeApplication("", "Erase on default", (uint32_t)true)); - AddHandler(Setting_CheckEmuRunning, new CSettingTypeApplication("", "Check Running", (uint32_t)true)); - - AddHandler(Setting_RememberCheats, new CSettingTypeApplication("", "Remember Cheats", (uint32_t)false)); - AddHandler(Setting_CurrentLanguage, new CSettingTypeApplication("", "Current Language", "")); - AddHandler(Setting_EnableDisk, new CSettingTypeApplication("", "Enable Disk", (uint32_t)true)); - AddHandler(Setting_LanguageDirDefault, new CSettingTypeRelativePath("Lang", "")); - AddHandler(Setting_LanguageDir, new CSettingTypeApplicationPath("Directory", "Lang", Setting_LanguageDirDefault)); - - AddHandler(Rdb_GoodName, new CSettingTypeRomDatabase("Good Name", Game_GameName)); - AddHandler(Rdb_SaveChip, new CSettingTypeRDBSaveChip("Save Type", SaveChip_Auto)); -#ifdef _DEBUG - AddHandler(Rdb_CpuType, new CSettingTypeRDBCpuType("CPU Type", CPU_SyncCores)); -#else - AddHandler(Rdb_CpuType, new CSettingTypeRDBCpuType("CPU Type", CPU_Recompiler)); -#endif - AddHandler(Rdb_RDRamSize, new CSettingTypeRDBRDRamSize("RDRAM Size", 0x400000)); - AddHandler(Rdb_CounterFactor, new CSettingTypeRomDatabase("Counter Factor", 2)); - AddHandler(Rdb_UseTlb, new CSettingTypeRDBYesNo("Use TLB", true)); - AddHandler(Rdb_DelayDP, new CSettingTypeRDBYesNo("Delay DP", true)); - AddHandler(Rdb_DelaySi, new CSettingTypeRDBYesNo("Delay SI", false)); - AddHandler(Rdb_32Bit, new CSettingTypeRDBYesNo("32bit", true)); - AddHandler(Rdb_FastSP, new CSettingTypeRDBYesNo("Fast SP", true)); - AddHandler(Rdb_Status, new CSettingTypeRomDatabase("Status", "Unknown")); - AddHandler(Rdb_NotesCore, new CSettingTypeRomDatabase("Core Note", "")); - AddHandler(Rdb_NotesPlugin, new CSettingTypeRomDatabase("Plugin Note", "")); -#ifdef _DEBUG - AddHandler(Rdb_FixedAudio, new CSettingTypeRomDatabase("Fixed Audio", true)); -#else - AddHandler(Rdb_FixedAudio, new CSettingTypeRomDatabase("Fixed Audio", true)); -#endif - AddHandler(Rdb_SyncViaAudio, new CSettingTypeRomDatabase("Sync Audio", false)); - AddHandler(Rdb_RspAudioSignal, new CSettingTypeRDBYesNo("Audio Signal", false)); - AddHandler(Rdb_TLB_VAddrStart, new CSettingTypeRomDatabase("TLB: Vaddr Start", 0)); - AddHandler(Rdb_TLB_VAddrLen, new CSettingTypeRomDatabase("TLB: Vaddr Len", 0)); - AddHandler(Rdb_TLB_PAddrStart, new CSettingTypeRomDatabase("TLB: PAddr Start", 0)); - AddHandler(Rdb_UseHleGfx, new CSettingTypeRomDatabase("HLE GFX", Plugin_UseHleGfx)); - AddHandler(Rdb_UseHleAudio, new CSettingTypeRomDatabase("HLE Audio", Plugin_UseHleAudio)); - AddHandler(Rdb_LoadRomToMemory, new CSettingTypeRomDatabase("Rom In Memory", false)); - AddHandler(Rdb_ScreenHertz, new CSettingTypeRomDatabase("ScreenHertz", 0)); - AddHandler(Rdb_FuncLookupMode, new CSettingTypeRomDatabase("FuncFind", FuncFind_PhysicalLookup)); - AddHandler(Rdb_RegCache, new CSettingTypeRDBYesNo("Reg Cache", true)); - AddHandler(Rdb_BlockLinking, new CSettingTypeRDBOnOff("Linking", true)); - AddHandler(Rdb_SMM_Cache, new CSettingTypeRomDatabase("SMM-Cache", true)); - AddHandler(Rdb_SMM_StoreInstruc, new CSettingTypeRomDatabase("SMM-StoreInstr", false)); - AddHandler(Rdb_SMM_PIDMA, new CSettingTypeRomDatabase("SMM-PI DMA", true)); - AddHandler(Rdb_SMM_TLB, new CSettingTypeRomDatabase("SMM-TLB", true)); - AddHandler(Rdb_SMM_Protect, new CSettingTypeRomDatabase("SMM-Protect", false)); - AddHandler(Rdb_SMM_ValidFunc, new CSettingTypeRomDatabase("SMM-FUNC", true)); - AddHandler(Rdb_GameCheatFix, new CSettingTypeRomDatabaseIndex("Cheat", "", "")); - AddHandler(Rdb_GameCheatFixPlugin, new CSettingTypeRomDatabaseIndex("CheatPlugin", "", "")); - AddHandler(Rdb_ViRefreshRate, new CSettingTypeRomDatabase("ViRefresh", 1500)); - AddHandler(Rdb_AiCountPerBytes, new CSettingTypeRomDatabase("AiCountPerBytes", 0)); - AddHandler(Rdb_AudioResetOnLoad, new CSettingTypeRDBYesNo("AudioResetOnLoad", false)); - AddHandler(Rdb_AllowROMWrites, new CSettingTypeRDBYesNo("AllowROMWrites", false)); - AddHandler(Rdb_CRC_Recalc, new CSettingTypeRDBYesNo("CRC-Recalc", false)); - - AddHandler(Game_IniKey, new CSettingTypeTempString("")); - AddHandler(Game_File, new CSettingTypeTempString("")); - AddHandler(Game_GameName, new CSettingTypeTempString("")); - AddHandler(Game_GoodName, new CSettingTypeGame("Good Name", Rdb_GoodName)); - AddHandler(Game_TempLoaded, new CSettingTypeTempBool(false)); - AddHandler(Game_SystemType, new CSettingTypeTempNumber(SYSTEM_NTSC)); - AddHandler(Game_EditPlugin_Gfx, new CSettingTypeGame("Plugin-Gfx", Default_None)); - AddHandler(Game_EditPlugin_Audio, new CSettingTypeGame("Plugin-Audio", Default_None)); - AddHandler(Game_EditPlugin_Contr, new CSettingTypeGame("Plugin-Controller", Default_None)); - AddHandler(Game_EditPlugin_RSP, new CSettingTypeGame("Plugin-RSP", Default_None)); - AddHandler(Game_Plugin_Gfx, new CSettingTypeGame("Plugin-Gfx", Plugin_GFX_Current)); - AddHandler(Game_Plugin_Audio, new CSettingTypeGame("Plugin-Audio", Plugin_AUDIO_Current)); - AddHandler(Game_Plugin_Controller, new CSettingTypeGame("Plugin-Controller", Plugin_CONT_Current)); - AddHandler(Game_Plugin_RSP, new CSettingTypeGame("Plugin-RSP", Plugin_RSP_Current)); - AddHandler(Game_SaveChip, new CSettingTypeGame("SaveChip", Rdb_SaveChip)); - AddHandler(Game_CpuType, new CSettingTypeGame("CpuType", Rdb_CpuType)); - AddHandler(Game_LastSaveSlot, new CSettingTypeGame("Last Used Save Slot", (uint32_t)0)); - AddHandler(Game_FixedAudio, new CSettingTypeGame("Fixed Audio", Rdb_FixedAudio)); - AddHandler(Game_RDRamSize, new CSettingTypeGame("RDRamSize", Rdb_RDRamSize)); - AddHandler(Game_CounterFactor, new CSettingTypeGame("Counter Factor", Rdb_CounterFactor)); - AddHandler(Game_UseTlb, new CSettingTypeGame("Use TLB", Rdb_UseTlb)); - AddHandler(Game_DelayDP, new CSettingTypeGame("Delay DP", Rdb_DelayDP)); - AddHandler(Game_DelaySI, new CSettingTypeGame("Delay SI", Rdb_DelaySi)); - AddHandler(Game_RspAudioSignal, new CSettingTypeGame("Audio Signal", Rdb_RspAudioSignal)); - AddHandler(Game_32Bit, new CSettingTypeGame("32bit", Rdb_32Bit)); - AddHandler(Game_FastSP, new CSettingTypeGame("Fast SP", Rdb_FastSP)); - AddHandler(Game_CurrentSaveState, new CSettingTypeTempNumber(0)); - AddHandler(Game_SyncViaAudio, new CSettingTypeGame("Sync Audio", Rdb_SyncViaAudio)); - AddHandler(Game_UseHleGfx, new CSettingTypeGame("HLE GFX", Rdb_UseHleGfx)); - AddHandler(Game_UseHleAudio, new CSettingTypeGame("HLE Audio", Rdb_UseHleAudio)); - AddHandler(Game_LoadRomToMemory, new CSettingTypeGame("Rom In Memory", Rdb_LoadRomToMemory)); - AddHandler(Game_ScreenHertz, new CSettingTypeGame("ScreenHertz", Rdb_ScreenHertz)); - AddHandler(Game_FuncLookupMode, new CSettingTypeGame("FuncFind", Rdb_FuncLookupMode)); - AddHandler(Game_RegCache, new CSettingTypeGame("Reg Cache", Rdb_RegCache)); - AddHandler(Game_BlockLinking, new CSettingTypeGame("Linking", Rdb_BlockLinking)); - AddHandler(Game_SMM_StoreInstruc, new CSettingTypeGame("SMM-StoreInst", Rdb_SMM_StoreInstruc)); - AddHandler(Game_SMM_Cache, new CSettingTypeGame("SMM-Cache", Rdb_SMM_Cache)); - AddHandler(Game_SMM_PIDMA, new CSettingTypeGame("SMM-PI DMA", Rdb_SMM_PIDMA)); - AddHandler(Game_SMM_TLB, new CSettingTypeGame("SMM-TLB", Rdb_SMM_TLB)); - AddHandler(Game_SMM_Protect, new CSettingTypeGame("SMM-Protect", Rdb_SMM_Protect)); - AddHandler(Game_SMM_ValidFunc, new CSettingTypeGame("SMM-FUNC", Rdb_SMM_ValidFunc)); - AddHandler(Game_ViRefreshRate, new CSettingTypeGame("ViRefresh", Rdb_ViRefreshRate)); - AddHandler(Game_AiCountPerBytes, new CSettingTypeGame("AiCountPerBytes", Rdb_AiCountPerBytes)); - AddHandler(Game_AudioResetOnLoad, new CSettingTypeGame("AudioResetOnLoad", Rdb_AudioResetOnLoad)); - AddHandler(Game_AllowROMWrites, new CSettingTypeGame("AllowROMWrites", Rdb_AllowROMWrites)); - AddHandler(Game_CRC_Recalc, new CSettingTypeGame("CRC-Recalc", Rdb_CRC_Recalc)); - - //User Interface - AddHandler(UserInterface_BasicMode, new CSettingTypeApplication("", "Basic Mode", (uint32_t)true)); - AddHandler(UserInterface_ShowCPUPer, new CSettingTypeApplication("", "Display CPU Usage", (uint32_t)false)); - AddHandler(UserInterface_DisplayFrameRate, new CSettingTypeApplication("", "Display Frame Rate", (uint32_t)true)); - AddHandler(UserInterface_InFullScreen, new CSettingTypeTempBool(false)); - AddHandler(UserInterface_FrameDisplayType, new CSettingTypeApplication("", "Frame Rate Display Type", (uint32_t)FR_VIs)); - AddHandler(UserInterface_MainWindowTop, new CSettingTypeApplication("Main Window", "Top", Default_None)); - AddHandler(UserInterface_MainWindowLeft, new CSettingTypeApplication("Main Window", "Left", Default_None)); - AddHandler(UserInterface_AlwaysOnTop, new CSettingTypeApplication("", "Always on top", (uint32_t)false)); - - AddHandler(RomBrowser_Enabled, new CSettingTypeApplication("Rom Browser", "Rom Browser", true)); - AddHandler(RomBrowser_ColoumnsChanged, new CSettingTypeTempBool(false)); - AddHandler(RomBrowser_Top, new CSettingTypeApplication("Rom Browser", "Top", Default_None)); - AddHandler(RomBrowser_Left, new CSettingTypeApplication("Rom Browser", "Left", Default_None)); - AddHandler(RomBrowser_Width, new CSettingTypeApplication("Rom Browser", "Width", (uint32_t)640)); - AddHandler(RomBrowser_Height, new CSettingTypeApplication("Rom Browser", "Height", (uint32_t)480)); - AddHandler(RomBrowser_PosIndex, new CSettingTypeApplicationIndex("Rom Browser\\Field Pos", "Field", Default_None)); - AddHandler(RomBrowser_WidthIndex, new CSettingTypeApplicationIndex("Rom Browser\\Field Width", "Field", Default_None)); - AddHandler(RomBrowser_SortFieldIndex, new CSettingTypeApplicationIndex("Rom Browser", "Sort Field", Default_None)); - AddHandler(RomBrowser_SortAscendingIndex, new CSettingTypeApplicationIndex("Rom Browser", "Sort Ascending", Default_None)); - AddHandler(RomBrowser_Recursive, new CSettingTypeApplication("Rom Browser", "Recursive", false)); - AddHandler(RomBrowser_Maximized, new CSettingTypeApplication("Rom Browser", "Maximized", false)); - - AddHandler(Directory_RecentGameDirCount, new CSettingTypeApplication("", "Remembered Rom Dirs", (uint32_t)10)); - AddHandler(Directory_RecentGameDirIndex, new CSettingTypeApplicationIndex("Recent Dir", "Recent Dir", Default_None)); - - //Directory_Game, - AddHandler(Directory_Game, new CSettingTypeSelectedDirectory("Dir:Game", Directory_GameInitial, Directory_GameSelected, Directory_GameUseSelected)); - AddHandler(Directory_GameInitial, new CSettingTypeRelativePath("Game Directory", "")); - AddHandler(Directory_GameSelected, new CSettingTypeApplication("Directory", "Game", Directory_GameInitial)); - AddHandler(Directory_GameUseSelected, new CSettingTypeApplication("Directory", "Game - Use Selected", false)); - - AddHandler(Directory_Plugin, new CSettingTypeSelectedDirectory("Dir:Plugin", Directory_PluginInitial, Directory_PluginSelected, Directory_PluginUseSelected)); -#ifdef _M_IX86 - AddHandler(Directory_PluginInitial, new CSettingTypeRelativePath("Plugin", "")); - AddHandler(Directory_PluginSelected, new CSettingTypeApplicationPath("Directory", "Plugin", Directory_PluginInitial)); - AddHandler(Directory_PluginUseSelected, new CSettingTypeApplication("Directory", "Plugin - Use Selected", false)); - AddHandler(Directory_PluginSync, new CSettingTypeRelativePath("SyncPlugin", "")); -#else - AddHandler(Directory_PluginInitial, new CSettingTypeRelativePath("Plugin64", "")); - AddHandler(Directory_PluginSelected, new CSettingTypeApplicationPath("Directory", "Plugin64", Directory_PluginInitial)); - AddHandler(Directory_PluginUseSelected, new CSettingTypeApplication("Directory", "Plugin - Use Selected", false)); - AddHandler(Directory_PluginSync, new CSettingTypeRelativePath("SyncPlugin64", "")); -#endif - - AddHandler(Directory_SnapShot, new CSettingTypeSelectedDirectory("Dir:Snapshot", Directory_SnapShotInitial, Directory_SnapShotSelected, Directory_SnapShotUseSelected)); - AddHandler(Directory_SnapShotInitial, new CSettingTypeRelativePath("Screenshots", "")); - AddHandler(Directory_SnapShotSelected, new CSettingTypeApplicationPath("Directory", "Snap Shot", Directory_SnapShotInitial)); - AddHandler(Directory_SnapShotUseSelected, new CSettingTypeApplication("Directory", "Snap Shot - Use Selected", false)); - - AddHandler(Directory_NativeSave, new CSettingTypeSelectedDirectory("Dir:NativeSave", Directory_NativeSaveInitial, Directory_NativeSaveSelected, Directory_NativeSaveUseSelected)); - AddHandler(Directory_NativeSaveInitial, new CSettingTypeRelativePath("Save", "")); - AddHandler(Directory_NativeSaveSelected, new CSettingTypeApplicationPath("Directory", "Save", Directory_NativeSaveInitial)); - AddHandler(Directory_NativeSaveUseSelected, new CSettingTypeApplication("Directory", "Save - Use Selected", false)); - - AddHandler(Directory_InstantSave, new CSettingTypeSelectedDirectory("Dir:InstantSave", Directory_InstantSaveInitial, Directory_InstantSaveSelected, Directory_InstantSaveUseSelected)); - AddHandler(Directory_InstantSaveInitial, new CSettingTypeRelativePath("Save", "")); - AddHandler(Directory_InstantSaveSelected, new CSettingTypeApplicationPath("Directory", "Instant Save", Directory_InstantSaveInitial)); - AddHandler(Directory_InstantSaveUseSelected, new CSettingTypeApplication("Directory", "Instant Save - Use Selected", false)); - - AddHandler(Directory_Texture, new CSettingTypeSelectedDirectory("Dir:Texture", Directory_TextureInitial, Directory_TextureSelected, Directory_TextureUseSelected)); - AddHandler(Directory_TextureInitial, new CSettingTypeRelativePath("Textures", "")); - AddHandler(Directory_TextureSelected, new CSettingTypeApplicationPath("Directory", "Texture Dir", Directory_InstantSaveInitial)); - AddHandler(Directory_TextureUseSelected, new CSettingTypeApplication("Directory", "Texture Dir - Use Selected", false)); - - AddHandler(Directory_LastSave, new CSettingTypeApplication("Directory", "Last Save Directory", Directory_InstantSave)); - - AddHandler(GameRunning_LoadingInProgress, new CSettingTypeTempBool(false)); - AddHandler(GameRunning_CPU_Running, new CSettingTypeTempBool(false)); - AddHandler(GameRunning_CPU_Paused, new CSettingTypeTempBool(false)); - AddHandler(GameRunning_CPU_PausedType, new CSettingTypeTempNumber(Default_None)); - AddHandler(GameRunning_InstantSaveFile, new CSettingTypeTempString("")); - AddHandler(GameRunning_LimitFPS, new CSettingTypeTempBool(true)); - AddHandler(GameRunning_ScreenHertz, new CSettingTypeTempNumber(60)); - AddHandler(GameRunning_InReset, new CSettingTypeTempBool(false)); - - AddHandler(File_RecentGameFileCount, new CSettingTypeApplication("", "Remembered Rom Files", (uint32_t)10)); - AddHandler(File_RecentGameFileIndex, new CSettingTypeApplicationIndex("Recent File", "Recent Rom", Default_None)); - AddHandler(File_DiskIPLPath, new CSettingTypeApplicationPath("", "Disk IPL ROM Path", Default_None)); - - AddHandler(Debugger_Enabled, new CSettingTypeApplication("Debugger", "Debugger", false)); - AddHandler(Debugger_ShowTLBMisses, new CSettingTypeApplication("Debugger", "Show TLB Misses", false)); - AddHandler(Debugger_ShowUnhandledMemory, new CSettingTypeApplication("Debugger", "Show Unhandled Memory", false)); - AddHandler(Debugger_ShowPifErrors, new CSettingTypeApplication("Debugger", "Show Pif Errors", false)); - AddHandler(Debugger_DisableGameFixes, new CSettingTypeApplication("Debugger", "Disable Game Fixes", false)); - AddHandler(Debugger_ShowDListAListCount, new CSettingTypeApplication("Debugger", "Show Dlist Alist Count", false)); - AddHandler(Debugger_ShowRecompMemSize, new CSettingTypeApplication("Debugger", "Show Recompiler Memory size", false)); - AddHandler(Debugger_ShowDivByZero, new CSettingTypeApplication("Debugger", "Show Div by zero", false)); - AddHandler(Debugger_ProfileCode, new CSettingTypeApplication("Debugger", "Profile Code", (uint32_t)false)); - AddHandler(Debugger_AppLogFlush, new CSettingTypeApplication("Logging", "Log Auto Flush", (uint32_t)false)); - AddHandler(Debugger_GenerateLogFiles, new CSettingTypeApplication("Debugger", "Generate Log Files", false)); - - //Logging - AddHandler(Debugger_TraceMD5, new CSettingTypeApplication("Logging", "MD5", (uint32_t)g_ModuleLogLevel[TraceMD5])); - AddHandler(Debugger_TraceSettings, new CSettingTypeApplication("Logging", "Settings", (uint32_t)g_ModuleLogLevel[TraceSettings])); - AddHandler(Debugger_TraceUnknown, new CSettingTypeApplication("Logging", "Unknown", (uint32_t)g_ModuleLogLevel[TraceUnknown])); - AddHandler(Debugger_TraceAppInit, new CSettingTypeApplication("Logging", "App Init", (uint32_t)g_ModuleLogLevel[TraceAppInit])); - AddHandler(Debugger_TraceAppCleanup, new CSettingTypeApplication("Logging", "App Cleanup", (uint32_t)g_ModuleLogLevel[TraceAppCleanup])); - AddHandler(Debugger_TraceN64System, new CSettingTypeApplication("Logging", "N64 System", (uint32_t)g_ModuleLogLevel[TraceN64System])); - AddHandler(Debugger_TracePlugins, new CSettingTypeApplication("Logging", "Plugins", (uint32_t)g_ModuleLogLevel[TracePlugins])); - AddHandler(Debugger_TraceGFXPlugin, new CSettingTypeApplication("Logging", "GFX Plugin", (uint32_t)g_ModuleLogLevel[TraceGFXPlugin])); - AddHandler(Debugger_TraceAudioPlugin, new CSettingTypeApplication("Logging", "Audio Plugin", (uint32_t)g_ModuleLogLevel[TraceAudioPlugin])); - AddHandler(Debugger_TraceControllerPlugin, new CSettingTypeApplication("Logging", "Controller Plugin", (uint32_t)g_ModuleLogLevel[TraceControllerPlugin])); - AddHandler(Debugger_TraceRSPPlugin, new CSettingTypeApplication("Logging", "RSP Plugin", (uint32_t)g_ModuleLogLevel[TraceRSPPlugin])); - AddHandler(Debugger_TraceRSP, new CSettingTypeApplication("Logging", "RSP", (uint32_t)g_ModuleLogLevel[TraceRSP])); - AddHandler(Debugger_TraceAudio, new CSettingTypeApplication("Logging", "Audio", (uint32_t)g_ModuleLogLevel[TraceAudio])); - AddHandler(Debugger_TraceRegisterCache, new CSettingTypeApplication("Logging", "Register Cache", (uint32_t)g_ModuleLogLevel[TraceRegisterCache])); - AddHandler(Debugger_TraceRecompiler, new CSettingTypeApplication("Logging", "Recompiler", (uint32_t)g_ModuleLogLevel[TraceRecompiler])); - AddHandler(Debugger_TraceTLB, new CSettingTypeApplication("Logging", "TLB", (uint32_t)g_ModuleLogLevel[TraceTLB])); - AddHandler(Debugger_TraceProtectedMEM, new CSettingTypeApplication("Logging", "Protected MEM", (uint32_t)g_ModuleLogLevel[TraceProtectedMem])); - AddHandler(Debugger_TraceUserInterface, new CSettingTypeApplication("Logging", "User Interface", (uint32_t)g_ModuleLogLevel[TraceUserInterface])); - - //Plugin - AddHandler(Plugin_RSP_Current, new CSettingTypeApplication("Plugin", "RSP Dll", "RSP\\RSP 1.7.dll")); - AddHandler(Plugin_GFX_Current, new CSettingTypeApplication("Plugin", "Graphics Dll", "GFX\\Jabo_Direct3D8.dll")); - AddHandler(Plugin_AUDIO_Current, new CSettingTypeApplication("Plugin", "Audio Dll", "Audio\\Jabo_Dsound.dll")); - AddHandler(Plugin_CONT_Current, new CSettingTypeApplication("Plugin", "Controller Dll", "Input\\PJ64_NRage.dll")); - - AddHandler(Plugin_RSP_CurVer, new CSettingTypeApplication("Plugin", "RSP Dll Ver", "")); - AddHandler(Plugin_GFX_CurVer, new CSettingTypeApplication("Plugin", "Graphics Dll Ver", "")); - AddHandler(Plugin_AUDIO_CurVer, new CSettingTypeApplication("Plugin", "Audio Dll Ver", "")); - AddHandler(Plugin_CONT_CurVer, new CSettingTypeApplication("Plugin", "Controller Dll Ver", "")); - - AddHandler(Plugin_UseHleGfx, new CSettingTypeApplication("RSP", "HLE GFX", true)); - AddHandler(Plugin_UseHleAudio, new CSettingTypeApplication("RSP", "HLE Audio", false)); - - //Logging - AddHandler(Logging_GenerateLog, new CSettingTypeApplication("Logging", "Generate Log Files", false)); - AddHandler(Logging_LogRDRamRegisters, new CSettingTypeApplication("Logging", "Log RDRam Registers", false)); - AddHandler(Logging_LogSPRegisters, new CSettingTypeApplication("Logging", "Log SP Registers", false)); - AddHandler(Logging_LogDPCRegisters, new CSettingTypeApplication("Logging", "Log DPC Registers", false)); - AddHandler(Logging_LogDPSRegisters, new CSettingTypeApplication("Logging", "Log DPS Registers", false)); - AddHandler(Logging_LogMIPSInterface, new CSettingTypeApplication("Logging", "Log MIPS Interface", false)); - AddHandler(Logging_LogVideoInterface, new CSettingTypeApplication("Logging", "Log Video Interface", false)); - AddHandler(Logging_LogAudioInterface, new CSettingTypeApplication("Logging", "Log Audio Interface", false)); - AddHandler(Logging_LogPerInterface, new CSettingTypeApplication("Logging", "Log Per Interface", false)); - AddHandler(Logging_LogRDRAMInterface, new CSettingTypeApplication("Logging", "Log RDRAM Interface", false)); - AddHandler(Logging_LogSerialInterface, new CSettingTypeApplication("Logging", "Log Serial Interface", false)); - AddHandler(Logging_LogPRDMAOperations, new CSettingTypeApplication("Logging", "Log PR DMA Operations", false)); - AddHandler(Logging_LogPRDirectMemLoads, new CSettingTypeApplication("Logging", "Log PR Direct Mem Loads", false)); - AddHandler(Logging_LogPRDMAMemLoads, new CSettingTypeApplication("Logging", "Log PR DMA Mem Loads", false)); - AddHandler(Logging_LogPRDirectMemStores, new CSettingTypeApplication("Logging", "Log PR Direct Mem Stores", false)); - AddHandler(Logging_LogPRDMAMemStores, new CSettingTypeApplication("Logging", "Log PRDMA Mem Stores", false)); - AddHandler(Logging_LogControllerPak, new CSettingTypeApplication("Logging", "Log Controller Pak", false)); - AddHandler(Logging_LogCP0changes, new CSettingTypeApplication("Logging", "Log CP0 changes", false)); - AddHandler(Logging_LogCP0reads, new CSettingTypeApplication("Logging", "Log CP0 reads", false)); - AddHandler(Logging_LogTLB, new CSettingTypeApplication("Logging", "Log TLB", false)); - AddHandler(Logging_LogExceptions, new CSettingTypeApplication("Logging", "Log Exceptions", false)); - AddHandler(Logging_NoInterrupts, new CSettingTypeApplication("Logging", "No Interrupts", false)); - AddHandler(Logging_LogCache, new CSettingTypeApplication("Logging", "Log Cache", false)); - AddHandler(Logging_LogRomHeader, new CSettingTypeApplication("Logging", "Generate Log Files", false)); - AddHandler(Logging_LogUnknown, new CSettingTypeApplication("Logging", "Log Rom Header", false)); - - // cheats - AddHandler(Cheat_Entry, new CSettingTypeCheats("")); - AddHandler(Cheat_Active, new CSettingTypeGameIndex("Cheat", "", (uint32_t)false)); - AddHandler(Cheat_Extension, new CSettingTypeGameIndex("Cheat", ".exten", "??? - Not Set")); - AddHandler(Cheat_Notes, new CSettingTypeCheats("_N")); - AddHandler(Cheat_Options, new CSettingTypeCheats("_O")); - AddHandler(Cheat_Range, new CSettingTypeCheats("_R")); - AddHandler(Cheat_RangeNotes, new CSettingTypeCheats("_RN")); -} - -uint32_t CSettings::FindSetting(CSettings * _this, const char * Name) -{ - for (SETTING_MAP::iterator iter = _this->m_SettingInfo.begin(); iter != _this->m_SettingInfo.end(); iter++) - { - CSettingType * Setting = iter->second; - if (Setting->GetSettingType() == SettingType_GameSetting) - { - CSettingTypeGame * GameSetting = (CSettingTypeGame *)Setting; - if (_stricmp(GameSetting->GetKeyName(), Name) != 0) - { - continue; - } - return iter->first; - } - if (Setting->GetSettingType() == SettingType_CfgFile) - { - CSettingTypeApplication * CfgSetting = (CSettingTypeApplication *)Setting; - if (_stricmp(CfgSetting->GetKeyName(), Name) != 0) - { - continue; - } - return iter->first; - } - if (Setting->GetSettingType() == SettingType_SelectedDirectory) - { - CSettingTypeSelectedDirectory * SelectedDirectory = (CSettingTypeSelectedDirectory *)Setting; - if (_stricmp(SelectedDirectory->GetName(), Name) != 0) - { - continue; - } - return iter->first; - } - } - return 0; -} - -void CSettings::FlushSettings(CSettings * /*_this*/) -{ - CSettingTypeCheats::FlushChanges(); - CSettingTypeApplication::Flush(); -} - -uint32_t CSettings::GetSetting(CSettings * _this, SettingID Type) -{ - return _this->LoadDword(Type); -} - -const char * CSettings::GetSettingSz(CSettings * _this, SettingID Type, char * Buffer, int BufferSize) -{ - if (Buffer && BufferSize > 0) - { - Buffer[0] = 0; - _this->LoadStringVal(Type, Buffer, BufferSize); - } - return Buffer; -} - -void CSettings::SetSetting(CSettings * _this, SettingID ID, uint32_t Value) -{ - _this->SaveDword(ID, Value); -} - -void CSettings::SetSettingSz(CSettings * _this, SettingID ID, const char * Value) -{ - _this->SaveString(ID, Value); -} - -void CSettings::RegisterSetting(CSettings * _this, SettingID ID, SettingID DefaultID, SettingDataType DataType, - SettingType Type, const char * Category, const char * DefaultStr, - uint32_t Value) -{ - switch (Type) - { - case SettingType_ConstValue: - if (DataType != Data_DWORD) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - _this->AddHandler(ID, new CSettingTypeTempNumber(Value)); - break; - case SettingType_ConstString: - if (DataType != Data_String) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - _this->AddHandler(ID, new CSettingTypeTempString(DefaultStr)); - break; - case SettingType_CfgFile: - case SettingType_Registry: - switch (DataType) - { - case Data_DWORD: - if (DefaultID == Default_None) - { - _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, Value)); - } - else - { - _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, DefaultID)); - } - break; - case Data_String: - if (DefaultID == Default_None) - { - _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, "")); - } - else - { - _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, DefaultID)); - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - break; - case SettingType_GameSetting: - { - stdstr_f Name("%s-%s", Category, DefaultStr); - switch (DataType) - { - case Data_DWORD: - if (DefaultID == Default_None) - { - SettingID RdbSetting = (SettingID)_this->m_NextAutoSettingId; - _this->m_NextAutoSettingId += 1; - _this->AddHandler(RdbSetting, new CSettingTypeRomDatabase(Name.c_str(), (int)Value)); - _this->AddHandler(ID, new CSettingTypeGame(Name.c_str(), RdbSetting)); - } - else - { - _this->AddHandler(ID, new CSettingTypeGame(Name.c_str(), DefaultID)); - } - break; - case Data_String: - if (DefaultID == Default_None) - { - _this->AddHandler(ID, new CSettingTypeGame(Name.c_str(), "")); - } - else - { - _this->AddHandler(ID, new CSettingTypeGame(Name.c_str(), DefaultID)); - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - break; - case SettingType_RomDatabase: - switch (DataType) - { - case Data_DWORD: - if (DefaultID == Default_None) - { - _this->AddHandler(ID, new CSettingTypeRomDatabase(DefaultStr, (int)Value, true)); - } - else - { - _this->AddHandler(ID, new CSettingTypeRomDatabase(DefaultStr, (SettingID)Value, true)); - } - break; - case Data_String: - if (DefaultID == Default_None) - { - _this->AddHandler(ID, new CSettingTypeRomDatabase(DefaultStr, "", true)); - } - else - { - _this->AddHandler(ID, new CSettingTypeRomDatabase(DefaultStr, DefaultID, true)); - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - break; - case SettingType_RdbSetting: - switch (DataType) - { - case Data_DWORD: - if (DefaultID == Default_None) - { - _this->AddHandler(ID, new CSettingTypeRomDatabaseSetting(Category, DefaultStr, (int)Value, true)); - } - else - { - SettingID RdbSetting = (SettingID)_this->m_NextAutoSettingId; - _this->m_NextAutoSettingId += 1; - _this->AddHandler(RdbSetting, new CSettingTypeRomDatabaseSetting(Category, DefaultStr, DefaultID, true)); - _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, RdbSetting)); - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} - -bool CSettings::Initialize(const char * AppName) -{ - AddHowToHandleSetting(); - CSettingTypeApplication::Initialize(AppName); - CSettingTypeRomDatabase::Initialize(); - CSettingTypeGame::Initialize(); - CSettingTypeCheats::Initialize(); - - g_Settings->SaveString(Setting_ApplicationName, AppName); - return true; -} - -bool CSettings::LoadBool(SettingID Type) -{ - bool Value = false; - LoadBool(Type, Value); - return Value; -} - -bool CSettings::LoadBool(SettingID Type, bool & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return 0; - } - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - return FindInfo->second->Load(0, Value); - } - return false; -} - -bool CSettings::LoadBoolIndex(SettingID Type, int index) -{ - bool Value = false; - LoadBoolIndex(Type, index, Value); - return Value; -} - -bool CSettings::LoadBoolIndex(SettingID Type, int index, bool & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return false; - } - if (FindInfo->second->IndexBasedSetting()) - { - return FindInfo->second->Load(index, Value); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - return false; -} - -uint32_t CSettings::LoadDword(SettingID Type) -{ - uint32_t Value = 0; - LoadDword(Type, Value); - return Value; -} - -bool CSettings::LoadDword(SettingID Type, uint32_t & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return false; - } - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - return FindInfo->second->Load(0, Value); - } - return false; -} - -uint32_t CSettings::LoadDwordIndex(SettingID Type, int index) -{ - uint32_t Value; - LoadDwordIndex(Type, index, Value); - return Value; -} - -bool CSettings::LoadDwordIndex(SettingID Type, int index, uint32_t & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return 0; - } - if (FindInfo->second->IndexBasedSetting()) - { - return FindInfo->second->Load(index, Value); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - return false; -} - -stdstr CSettings::LoadStringVal(SettingID Type) -{ - stdstr Value; - LoadStringVal(Type, Value); - return Value; -} - -bool CSettings::LoadStringVal(SettingID Type, stdstr & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return 0; - } - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - return FindInfo->second->Load(0, Value); - } - return false; -} - -bool CSettings::LoadStringVal(SettingID Type, char * Buffer, int BufferSize) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return 0; - } - bool bRes = false; - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - stdstr Value; - bRes = FindInfo->second->Load(0, Value); - int len = BufferSize; - if ((Value.length() + 1) < (size_t)len) - { - len = Value.length() + 1; - } - strncpy(Buffer, Value.c_str(), len); - } - return bRes; -} - -stdstr CSettings::LoadStringIndex(SettingID Type, int index) -{ - stdstr Value; - LoadStringIndex(Type, index, Value); - return Value; -} - -bool CSettings::LoadStringIndex(SettingID Type, int index, stdstr & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return 0; - } - if (FindInfo->second->IndexBasedSetting()) - { - return FindInfo->second->Load(index, Value); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - return false; -} - -bool CSettings::LoadStringIndex(SettingID /*Type*/, int /*index*/, char * /*Buffer*/, int /*BufferSize*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -//Load the default value for the setting -bool CSettings::LoadDefaultBool(SettingID Type) -{ - bool Value = false; - LoadDefaultBool(Type, Value); - return Value; -} - -void CSettings::LoadDefaultBool(SettingID Type, bool & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - } - else - { - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - FindInfo->second->LoadDefault(0, Value); - } - } -} - -bool CSettings::LoadDefaultBoolIndex(SettingID /*Type*/, int /*index*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -void CSettings::LoadDefaultBoolIndex(SettingID /*Type*/, int /*index*/, bool & /*Value*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -uint32_t CSettings::LoadDefaultDword(SettingID Type) -{ - uint32_t Value = 0; - LoadDefaultDword(Type, Value); - return Value; -} - -void CSettings::LoadDefaultDword(SettingID Type, uint32_t & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - } - else - { - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - FindInfo->second->LoadDefault(0, Value); - } - } -} - -uint32_t CSettings::LoadDefaultDwordIndex(SettingID /*Type*/, int /*index*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; -} - -void CSettings::LoadDefaultDwordIndex(SettingID /*Type*/, int /*index*/, uint32_t & /*Value*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -stdstr CSettings::LoadDefaultString(SettingID Type) -{ - stdstr Value; - LoadDefaultString(Type, Value); - return Value; -} - -void CSettings::LoadDefaultString(SettingID Type, stdstr & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - } - else - { - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - FindInfo->second->LoadDefault(0, Value); - } - } -} - -void CSettings::LoadDefaultString(SettingID /*Type*/, char * /*Buffer*/, int /*BufferSize*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -stdstr CSettings::LoadDefaultStringIndex(SettingID /*Type*/, int /*index*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); - return ""; -} - -void CSettings::LoadDefaultStringIndex(SettingID /*Type*/, int /*index*/, stdstr & /*Value*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettings::LoadDefaultStringIndex(SettingID /*Type*/, int /*index*/, char * /*Buffer*/, int /*BufferSize*/) -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CSettings::SaveBool(SettingID Type, bool Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return; - } - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - FindInfo->second->Save(0, Value); - } - NotifyCallBacks(Type); -} - -void CSettings::SaveBoolIndex(SettingID Type, int index, bool Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return; - } - if (FindInfo->second->IndexBasedSetting()) - { - FindInfo->second->Save(index, Value); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - NotifyCallBacks(Type); -} - -void CSettings::SaveDword(SettingID Type, uint32_t Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return; - } - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - FindInfo->second->Save(0, Value); - } - NotifyCallBacks(Type); -} - -void CSettings::SaveDwordIndex(SettingID Type, int index, uint32_t Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return; - } - if (FindInfo->second->IndexBasedSetting()) - { - FindInfo->second->Save(index, Value); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - NotifyCallBacks(Type); -} - -void CSettings::SaveString(SettingID Type, const stdstr & Value) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return; - } - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - FindInfo->second->Save(0, Value); - } - NotifyCallBacks(Type); -} - -void CSettings::SaveString(SettingID Type, const char * Buffer) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - } - else if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - FindInfo->second->Save(0, Buffer); - } - NotifyCallBacks(Type); -} - -void CSettings::SaveStringIndex(SettingID Type, int index, const char * Buffer) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - } - if (FindInfo->second->IndexBasedSetting()) - { - FindInfo->second->Save(index, Buffer); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - NotifyCallBacks(Type); -} - -void CSettings::SaveStringIndex(SettingID Type, int index, const stdstr & Value) -{ - SaveStringIndex(Type, index, Value.c_str()); -} - -void CSettings::DeleteSetting(SettingID Type) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - } - if (FindInfo->second->IndexBasedSetting()) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - else - { - FindInfo->second->Delete(0); - } - NotifyCallBacks(Type); -} - -void CSettings::DeleteSettingIndex(SettingID Type, int index) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - } - if (FindInfo->second->IndexBasedSetting()) - { - FindInfo->second->Delete(index); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - NotifyCallBacks(Type); -} - -SettingType CSettings::GetSettingType(SettingID Type) -{ - if (Type == Default_None || Type == Default_Constant) - { - return SettingType_Unknown; - } - - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - return SettingType_Unknown; - } - return FindInfo->second->GetSettingType(); -} - -bool CSettings::IndexBasedSetting(SettingID Type) -{ - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - return false; - } - return FindInfo->second->IndexBasedSetting(); -} - -void CSettings::SettingTypeChanged(SettingType Type) -{ - for (SETTING_MAP::iterator iter = m_SettingInfo.begin(); iter != m_SettingInfo.end(); iter++) - { - if (iter->second->GetSettingType() == Type) - { - NotifyCallBacks(iter->first); - } - } -} -void CSettings::UnknownSetting(SettingID /*Type*/) -{ -#ifdef _DEBUG - g_Notify->BreakPoint(__FILE__, __LINE__); -#endif -} - -void CSettings::NotifyCallBacks(SettingID Type) -{ - SETTING_CALLBACK::iterator Callback = m_Callback.find(Type); - if (Callback == m_Callback.end()) - { - return; - } - - for (SETTING_CHANGED_CB * item = Callback->second; item != NULL; item = item->Next) - { - item->Func(item->Data); - } -} - -void CSettings::RegisterChangeCB(SettingID Type, void * Data, SettingChangedFunc Func) -{ - SETTING_CHANGED_CB * new_item = new SETTING_CHANGED_CB; - new_item->Data = Data; - new_item->Func = Func; - new_item->Next = NULL; - - SETTING_CALLBACK::iterator Callback = m_Callback.find(Type); - if (Callback != m_Callback.end()) - { - SETTING_CHANGED_CB * item = Callback->second; - while (item->Next) - { - item = item->Next; - } - item->Next = new_item; - } - else - { - m_Callback.insert(SETTING_CALLBACK::value_type(Type, new_item)); - } -} - -void CSettings::UnregisterChangeCB(SettingID Type, void * Data, SettingChangedFunc Func) -{ - bool bRemoved = false; - - //Find out the information for handling the setting type from the list - SETTING_CALLBACK::iterator Callback = m_Callback.find(Type); - if (Callback != m_Callback.end()) - { - SETTING_CHANGED_CB * PrevItem = NULL; - SETTING_CHANGED_CB * item = Callback->second; - - while (item) - { - if (Callback->first == Type && item->Data == Data && item->Func == Func) - { - bRemoved = true; - if (PrevItem == NULL) - { - if (item->Next) - { - SettingID Type = Callback->first; - SETTING_CHANGED_CB * Next = item->Next; - m_Callback.erase(Callback); - m_Callback.insert(SETTING_CALLBACK::value_type(Type, Next)); - } - else - { - m_Callback.erase(Callback); - } - } - else - { - PrevItem->Next = item->Next; - } - delete item; - item = NULL; - break; - } - PrevItem = item; - item = item->Next; - } - } - else - { - UnknownSetting(Type); - return; - } - - if (!bRemoved) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include +#include "SettingType/SettingsType-Application.h" +#include "SettingType/SettingsType-ApplicationPath.h" +#include "SettingType/SettingsType-ApplicationIndex.h" +#include "SettingType/SettingsType-Cheats.h" +#include "SettingType/SettingsType-GameSetting.h" +#include "SettingType/SettingsType-GameSettingIndex.h" +#include "SettingType/SettingsType-RelativePath.h" +#include "SettingType/SettingsType-RomDatabase.h" +#include "SettingType/SettingsType-RomDatabaseSetting.h" +#include "SettingType/SettingsType-RomDatabaseIndex.h" +#include "SettingType/SettingsType-RDBCpuType.h" +#include "SettingType/SettingsType-RDBRamSize.h" +#include "SettingType/SettingsType-RDBSaveChip.h" +#include "SettingType/SettingsType-RDBYesNo.h" +#include "SettingType/SettingsType-RDBOnOff.h" +#include "SettingType/SettingsType-SelectedDirectory.h" +#include "SettingType/SettingsType-TempString.h" +#include "SettingType/SettingsType-TempNumber.h" +#include "SettingType/SettingsType-TempBool.h" +#include "SettingsClass.h" +#include +#include + +CSettings * g_Settings = NULL; + +CSettings::CSettings() : +m_NextAutoSettingId(0x200000) +{ +} + +CSettings::~CSettings() +{ + CSettingTypeApplication::CleanUp(); + CSettingTypeRomDatabase::CleanUp(); + CSettingTypeGame::CleanUp(); + CSettingTypeCheats::CleanUp(); + + for (SETTING_MAP::iterator iter = m_SettingInfo.begin(); iter != m_SettingInfo.end(); iter++) + { + delete iter->second; + } + + for (SETTING_CALLBACK::iterator cb_iter = m_Callback.begin(); cb_iter != m_Callback.end(); cb_iter++) + { + SETTING_CHANGED_CB * item = cb_iter->second; + while (item != NULL) + { + SETTING_CHANGED_CB * current_item = item; + item = item->Next; + delete current_item; + } + } +} + +void CSettings::AddHandler(SettingID TypeID, CSettingType * Handler) +{ + std::pair res = m_SettingInfo.insert(SETTING_MAP::value_type(TypeID, Handler)); + if (!res.second) + { + delete res.first->second; + m_SettingInfo.erase(res.first); + res = m_SettingInfo.insert(SETTING_MAP::value_type(TypeID, Handler)); + if (!res.second) + { + delete Handler; + } + } +} + +void CSettings::AddHowToHandleSetting() +{ + //information - temp keys + AddHandler(Info_ShortCutsChanged, new CSettingTypeTempBool(false)); + + //Command Settings +#ifdef _WIN32 + AddHandler(Cmd_BaseDirectory, new CSettingTypeTempString(CPath(CPath::MODULE_DIRECTORY))); +#else + AddHandler(Cmd_BaseDirectory, new CSettingTypeTempString("")); +#endif + AddHandler(Cmd_ShowHelp, new CSettingTypeTempBool(false)); + AddHandler(Cmd_RomFile, new CSettingTypeTempString("")); + + //Support Files + AddHandler(SupportFile_Settings, new CSettingTypeApplicationPath("", "ConfigFile", SupportFile_SettingsDefault)); + AddHandler(SupportFile_SettingsDefault, new CSettingTypeRelativePath("Config", "Project64.cfg")); + AddHandler(SupportFile_RomDatabase, new CSettingTypeApplicationPath("", "RomDatabase", SupportFile_RomDatabaseDefault)); + AddHandler(SupportFile_RomDatabaseDefault, new CSettingTypeRelativePath("Config", "Project64.rdb")); + AddHandler(SupportFile_Glide64RDB, new CSettingTypeApplicationPath("", "Glide64RDB", SupportFile_Glide64RDBDefault)); + AddHandler(SupportFile_Glide64RDBDefault, new CSettingTypeRelativePath("Config", "Glide64.rdb")); + AddHandler(SupportFile_Cheats, new CSettingTypeApplicationPath("", "Cheats", SupportFile_CheatsDefault)); + AddHandler(SupportFile_CheatsDefault, new CSettingTypeRelativePath("Config", "Project64.cht")); + AddHandler(SupportFile_Notes, new CSettingTypeApplicationPath("", "Notes", SupportFile_NotesDefault)); + AddHandler(SupportFile_NotesDefault, new CSettingTypeRelativePath("Config", "Project64.rdn")); + AddHandler(SupportFile_ExtInfo, new CSettingTypeApplicationPath("", "ExtInfo", SupportFile_ExtInfoDefault)); + AddHandler(SupportFile_ExtInfoDefault, new CSettingTypeRelativePath("Config", "Project64.rdx")); + AddHandler(SupportFile_ShortCuts, new CSettingTypeApplicationPath("", "ShortCuts", SupportFile_ShortCutsDefault)); + AddHandler(SupportFile_ShortCutsDefault, new CSettingTypeRelativePath("Config", "Project64.sc3")); + AddHandler(SupportFile_RomListCache, new CSettingTypeApplicationPath("", "RomListCache", SupportFile_RomListCacheDefault)); + AddHandler(SupportFile_RomListCacheDefault, new CSettingTypeRelativePath("Config", "Project64.cache3")); + AddHandler(SupportFile_7zipCache, new CSettingTypeApplicationPath("", "7zipCache", SupportFile_7zipCacheDefault)); + AddHandler(SupportFile_7zipCacheDefault, new CSettingTypeRelativePath("Config", "Project64.zcache")); + + //AddHandler(SyncPluginDir, new CSettingTypeRelativePath("SyncPlugin","")); + + //Settings location + AddHandler(Setting_ApplicationName, new CSettingTypeTempString("")); + AddHandler(Setting_UseFromRegistry, new CSettingTypeApplication("Settings", "Use Registry", (uint32_t)false)); + AddHandler(Setting_RdbEditor, new CSettingTypeApplication("", "Rdb Editor", false)); + AddHandler(Setting_CN64TimeCritical, new CSettingTypeApplication("", "CN64TimeCritical", false)); + AddHandler(Setting_PluginPageFirst, new CSettingTypeApplication("", "Plugin Page First", false)); + AddHandler(Setting_DisableScrSaver, new CSettingTypeApplication("", "Disable Screen Saver", (uint32_t)true)); + AddHandler(Setting_AutoSleep, new CSettingTypeApplication("", "Auto Sleep", (uint32_t)true)); + AddHandler(Setting_AutoStart, new CSettingTypeApplication("", "Auto Start", (uint32_t)true)); + AddHandler(Setting_AutoFullscreen, new CSettingTypeApplication("", "Auto Full Screen", (uint32_t)false)); + AddHandler(Setting_AutoZipInstantSave, new CSettingTypeApplication("", "Auto Zip Saves", (uint32_t)true)); + AddHandler(Setting_EraseGameDefaults, new CSettingTypeApplication("", "Erase on default", (uint32_t)true)); + AddHandler(Setting_CheckEmuRunning, new CSettingTypeApplication("", "Check Running", (uint32_t)true)); + + AddHandler(Setting_RememberCheats, new CSettingTypeApplication("", "Remember Cheats", (uint32_t)false)); + AddHandler(Setting_CurrentLanguage, new CSettingTypeApplication("", "Current Language", "")); + AddHandler(Setting_EnableDisk, new CSettingTypeApplication("", "Enable Disk", (uint32_t)true)); + AddHandler(Setting_LanguageDirDefault, new CSettingTypeRelativePath("Lang", "")); + AddHandler(Setting_LanguageDir, new CSettingTypeApplicationPath("Directory", "Lang", Setting_LanguageDirDefault)); + + AddHandler(Rdb_GoodName, new CSettingTypeRomDatabase("Good Name", Game_GameName)); + AddHandler(Rdb_SaveChip, new CSettingTypeRDBSaveChip("Save Type", SaveChip_Auto)); +#ifdef _DEBUG + AddHandler(Rdb_CpuType, new CSettingTypeRDBCpuType("CPU Type", CPU_SyncCores)); +#else + AddHandler(Rdb_CpuType, new CSettingTypeRDBCpuType("CPU Type", CPU_Recompiler)); +#endif + AddHandler(Rdb_RDRamSize, new CSettingTypeRDBRDRamSize("RDRAM Size", 0x400000)); + AddHandler(Rdb_CounterFactor, new CSettingTypeRomDatabase("Counter Factor", 2)); + AddHandler(Rdb_UseTlb, new CSettingTypeRDBYesNo("Use TLB", true)); + AddHandler(Rdb_DelayDP, new CSettingTypeRDBYesNo("Delay DP", true)); + AddHandler(Rdb_DelaySi, new CSettingTypeRDBYesNo("Delay SI", false)); + AddHandler(Rdb_32Bit, new CSettingTypeRDBYesNo("32bit", true)); + AddHandler(Rdb_FastSP, new CSettingTypeRDBYesNo("Fast SP", true)); + AddHandler(Rdb_Status, new CSettingTypeRomDatabase("Status", "Unknown")); + AddHandler(Rdb_NotesCore, new CSettingTypeRomDatabase("Core Note", "")); + AddHandler(Rdb_NotesPlugin, new CSettingTypeRomDatabase("Plugin Note", "")); +#ifdef _DEBUG + AddHandler(Rdb_FixedAudio, new CSettingTypeRomDatabase("Fixed Audio", true)); +#else + AddHandler(Rdb_FixedAudio, new CSettingTypeRomDatabase("Fixed Audio", true)); +#endif + AddHandler(Rdb_SyncViaAudio, new CSettingTypeRomDatabase("Sync Audio", false)); + AddHandler(Rdb_RspAudioSignal, new CSettingTypeRDBYesNo("Audio Signal", false)); + AddHandler(Rdb_TLB_VAddrStart, new CSettingTypeRomDatabase("TLB: Vaddr Start", 0)); + AddHandler(Rdb_TLB_VAddrLen, new CSettingTypeRomDatabase("TLB: Vaddr Len", 0)); + AddHandler(Rdb_TLB_PAddrStart, new CSettingTypeRomDatabase("TLB: PAddr Start", 0)); + AddHandler(Rdb_UseHleGfx, new CSettingTypeRomDatabase("HLE GFX", Plugin_UseHleGfx)); + AddHandler(Rdb_UseHleAudio, new CSettingTypeRomDatabase("HLE Audio", Plugin_UseHleAudio)); + AddHandler(Rdb_LoadRomToMemory, new CSettingTypeRomDatabase("Rom In Memory", false)); + AddHandler(Rdb_ScreenHertz, new CSettingTypeRomDatabase("ScreenHertz", 0)); + AddHandler(Rdb_FuncLookupMode, new CSettingTypeRomDatabase("FuncFind", FuncFind_PhysicalLookup)); + AddHandler(Rdb_RegCache, new CSettingTypeRDBYesNo("Reg Cache", true)); + AddHandler(Rdb_BlockLinking, new CSettingTypeRDBOnOff("Linking", true)); + AddHandler(Rdb_SMM_Cache, new CSettingTypeRomDatabase("SMM-Cache", true)); + AddHandler(Rdb_SMM_StoreInstruc, new CSettingTypeRomDatabase("SMM-StoreInstr", false)); + AddHandler(Rdb_SMM_PIDMA, new CSettingTypeRomDatabase("SMM-PI DMA", true)); + AddHandler(Rdb_SMM_TLB, new CSettingTypeRomDatabase("SMM-TLB", true)); + AddHandler(Rdb_SMM_Protect, new CSettingTypeRomDatabase("SMM-Protect", false)); + AddHandler(Rdb_SMM_ValidFunc, new CSettingTypeRomDatabase("SMM-FUNC", true)); + AddHandler(Rdb_GameCheatFix, new CSettingTypeRomDatabaseIndex("Cheat", "", "")); + AddHandler(Rdb_GameCheatFixPlugin, new CSettingTypeRomDatabaseIndex("CheatPlugin", "", "")); + AddHandler(Rdb_ViRefreshRate, new CSettingTypeRomDatabase("ViRefresh", 1500)); + AddHandler(Rdb_AiCountPerBytes, new CSettingTypeRomDatabase("AiCountPerBytes", 0)); + AddHandler(Rdb_AudioResetOnLoad, new CSettingTypeRDBYesNo("AudioResetOnLoad", false)); + AddHandler(Rdb_AllowROMWrites, new CSettingTypeRDBYesNo("AllowROMWrites", false)); + AddHandler(Rdb_CRC_Recalc, new CSettingTypeRDBYesNo("CRC-Recalc", false)); + + AddHandler(Game_IniKey, new CSettingTypeTempString("")); + AddHandler(Game_File, new CSettingTypeTempString("")); + AddHandler(Game_GameName, new CSettingTypeTempString("")); + AddHandler(Game_GoodName, new CSettingTypeGame("Good Name", Rdb_GoodName)); + AddHandler(Game_TempLoaded, new CSettingTypeTempBool(false)); + AddHandler(Game_SystemType, new CSettingTypeTempNumber(SYSTEM_NTSC)); + AddHandler(Game_EditPlugin_Gfx, new CSettingTypeGame("Plugin-Gfx", Default_None)); + AddHandler(Game_EditPlugin_Audio, new CSettingTypeGame("Plugin-Audio", Default_None)); + AddHandler(Game_EditPlugin_Contr, new CSettingTypeGame("Plugin-Controller", Default_None)); + AddHandler(Game_EditPlugin_RSP, new CSettingTypeGame("Plugin-RSP", Default_None)); + AddHandler(Game_Plugin_Gfx, new CSettingTypeGame("Plugin-Gfx", Plugin_GFX_Current)); + AddHandler(Game_Plugin_Audio, new CSettingTypeGame("Plugin-Audio", Plugin_AUDIO_Current)); + AddHandler(Game_Plugin_Controller, new CSettingTypeGame("Plugin-Controller", Plugin_CONT_Current)); + AddHandler(Game_Plugin_RSP, new CSettingTypeGame("Plugin-RSP", Plugin_RSP_Current)); + AddHandler(Game_SaveChip, new CSettingTypeGame("SaveChip", Rdb_SaveChip)); + AddHandler(Game_CpuType, new CSettingTypeGame("CpuType", Rdb_CpuType)); + AddHandler(Game_LastSaveSlot, new CSettingTypeGame("Last Used Save Slot", (uint32_t)0)); + AddHandler(Game_FixedAudio, new CSettingTypeGame("Fixed Audio", Rdb_FixedAudio)); + AddHandler(Game_RDRamSize, new CSettingTypeGame("RDRamSize", Rdb_RDRamSize)); + AddHandler(Game_CounterFactor, new CSettingTypeGame("Counter Factor", Rdb_CounterFactor)); + AddHandler(Game_UseTlb, new CSettingTypeGame("Use TLB", Rdb_UseTlb)); + AddHandler(Game_DelayDP, new CSettingTypeGame("Delay DP", Rdb_DelayDP)); + AddHandler(Game_DelaySI, new CSettingTypeGame("Delay SI", Rdb_DelaySi)); + AddHandler(Game_RspAudioSignal, new CSettingTypeGame("Audio Signal", Rdb_RspAudioSignal)); + AddHandler(Game_32Bit, new CSettingTypeGame("32bit", Rdb_32Bit)); + AddHandler(Game_FastSP, new CSettingTypeGame("Fast SP", Rdb_FastSP)); + AddHandler(Game_CurrentSaveState, new CSettingTypeTempNumber(0)); + AddHandler(Game_SyncViaAudio, new CSettingTypeGame("Sync Audio", Rdb_SyncViaAudio)); + AddHandler(Game_UseHleGfx, new CSettingTypeGame("HLE GFX", Rdb_UseHleGfx)); + AddHandler(Game_UseHleAudio, new CSettingTypeGame("HLE Audio", Rdb_UseHleAudio)); + AddHandler(Game_LoadRomToMemory, new CSettingTypeGame("Rom In Memory", Rdb_LoadRomToMemory)); + AddHandler(Game_ScreenHertz, new CSettingTypeGame("ScreenHertz", Rdb_ScreenHertz)); + AddHandler(Game_FuncLookupMode, new CSettingTypeGame("FuncFind", Rdb_FuncLookupMode)); + AddHandler(Game_RegCache, new CSettingTypeGame("Reg Cache", Rdb_RegCache)); + AddHandler(Game_BlockLinking, new CSettingTypeGame("Linking", Rdb_BlockLinking)); + AddHandler(Game_SMM_StoreInstruc, new CSettingTypeGame("SMM-StoreInst", Rdb_SMM_StoreInstruc)); + AddHandler(Game_SMM_Cache, new CSettingTypeGame("SMM-Cache", Rdb_SMM_Cache)); + AddHandler(Game_SMM_PIDMA, new CSettingTypeGame("SMM-PI DMA", Rdb_SMM_PIDMA)); + AddHandler(Game_SMM_TLB, new CSettingTypeGame("SMM-TLB", Rdb_SMM_TLB)); + AddHandler(Game_SMM_Protect, new CSettingTypeGame("SMM-Protect", Rdb_SMM_Protect)); + AddHandler(Game_SMM_ValidFunc, new CSettingTypeGame("SMM-FUNC", Rdb_SMM_ValidFunc)); + AddHandler(Game_ViRefreshRate, new CSettingTypeGame("ViRefresh", Rdb_ViRefreshRate)); + AddHandler(Game_AiCountPerBytes, new CSettingTypeGame("AiCountPerBytes", Rdb_AiCountPerBytes)); + AddHandler(Game_AudioResetOnLoad, new CSettingTypeGame("AudioResetOnLoad", Rdb_AudioResetOnLoad)); + AddHandler(Game_AllowROMWrites, new CSettingTypeGame("AllowROMWrites", Rdb_AllowROMWrites)); + AddHandler(Game_CRC_Recalc, new CSettingTypeGame("CRC-Recalc", Rdb_CRC_Recalc)); + + //User Interface + AddHandler(UserInterface_BasicMode, new CSettingTypeApplication("", "Basic Mode", (uint32_t)true)); + AddHandler(UserInterface_ShowCPUPer, new CSettingTypeApplication("", "Display CPU Usage", (uint32_t)false)); + AddHandler(UserInterface_DisplayFrameRate, new CSettingTypeApplication("", "Display Frame Rate", (uint32_t)true)); + AddHandler(UserInterface_InFullScreen, new CSettingTypeTempBool(false)); + AddHandler(UserInterface_FrameDisplayType, new CSettingTypeApplication("", "Frame Rate Display Type", (uint32_t)FR_VIs)); + AddHandler(UserInterface_MainWindowTop, new CSettingTypeApplication("Main Window", "Top", Default_None)); + AddHandler(UserInterface_MainWindowLeft, new CSettingTypeApplication("Main Window", "Left", Default_None)); + AddHandler(UserInterface_AlwaysOnTop, new CSettingTypeApplication("", "Always on top", (uint32_t)false)); + + AddHandler(RomBrowser_Enabled, new CSettingTypeApplication("Rom Browser", "Rom Browser", true)); + AddHandler(RomBrowser_ColoumnsChanged, new CSettingTypeTempBool(false)); + AddHandler(RomBrowser_Top, new CSettingTypeApplication("Rom Browser", "Top", Default_None)); + AddHandler(RomBrowser_Left, new CSettingTypeApplication("Rom Browser", "Left", Default_None)); + AddHandler(RomBrowser_Width, new CSettingTypeApplication("Rom Browser", "Width", (uint32_t)640)); + AddHandler(RomBrowser_Height, new CSettingTypeApplication("Rom Browser", "Height", (uint32_t)480)); + AddHandler(RomBrowser_PosIndex, new CSettingTypeApplicationIndex("Rom Browser\\Field Pos", "Field", Default_None)); + AddHandler(RomBrowser_WidthIndex, new CSettingTypeApplicationIndex("Rom Browser\\Field Width", "Field", Default_None)); + AddHandler(RomBrowser_SortFieldIndex, new CSettingTypeApplicationIndex("Rom Browser", "Sort Field", Default_None)); + AddHandler(RomBrowser_SortAscendingIndex, new CSettingTypeApplicationIndex("Rom Browser", "Sort Ascending", Default_None)); + AddHandler(RomBrowser_Recursive, new CSettingTypeApplication("Rom Browser", "Recursive", false)); + AddHandler(RomBrowser_Maximized, new CSettingTypeApplication("Rom Browser", "Maximized", false)); + + AddHandler(Directory_RecentGameDirCount, new CSettingTypeApplication("", "Remembered Rom Dirs", (uint32_t)10)); + AddHandler(Directory_RecentGameDirIndex, new CSettingTypeApplicationIndex("Recent Dir", "Recent Dir", Default_None)); + + //Directory_Game, + AddHandler(Directory_Game, new CSettingTypeSelectedDirectory("Dir:Game", Directory_GameInitial, Directory_GameSelected, Directory_GameUseSelected)); + AddHandler(Directory_GameInitial, new CSettingTypeRelativePath("Game Directory", "")); + AddHandler(Directory_GameSelected, new CSettingTypeApplication("Directory", "Game", Directory_GameInitial)); + AddHandler(Directory_GameUseSelected, new CSettingTypeApplication("Directory", "Game - Use Selected", false)); + + AddHandler(Directory_Plugin, new CSettingTypeSelectedDirectory("Dir:Plugin", Directory_PluginInitial, Directory_PluginSelected, Directory_PluginUseSelected)); +#ifdef _M_IX86 + AddHandler(Directory_PluginInitial, new CSettingTypeRelativePath("Plugin", "")); + AddHandler(Directory_PluginSelected, new CSettingTypeApplicationPath("Directory", "Plugin", Directory_PluginInitial)); + AddHandler(Directory_PluginUseSelected, new CSettingTypeApplication("Directory", "Plugin - Use Selected", false)); + AddHandler(Directory_PluginSync, new CSettingTypeRelativePath("SyncPlugin", "")); +#else + AddHandler(Directory_PluginInitial, new CSettingTypeRelativePath("Plugin64", "")); + AddHandler(Directory_PluginSelected, new CSettingTypeApplicationPath("Directory", "Plugin64", Directory_PluginInitial)); + AddHandler(Directory_PluginUseSelected, new CSettingTypeApplication("Directory", "Plugin - Use Selected", false)); + AddHandler(Directory_PluginSync, new CSettingTypeRelativePath("SyncPlugin64", "")); +#endif + + AddHandler(Directory_SnapShot, new CSettingTypeSelectedDirectory("Dir:Snapshot", Directory_SnapShotInitial, Directory_SnapShotSelected, Directory_SnapShotUseSelected)); + AddHandler(Directory_SnapShotInitial, new CSettingTypeRelativePath("Screenshots", "")); + AddHandler(Directory_SnapShotSelected, new CSettingTypeApplicationPath("Directory", "Snap Shot", Directory_SnapShotInitial)); + AddHandler(Directory_SnapShotUseSelected, new CSettingTypeApplication("Directory", "Snap Shot - Use Selected", false)); + + AddHandler(Directory_NativeSave, new CSettingTypeSelectedDirectory("Dir:NativeSave", Directory_NativeSaveInitial, Directory_NativeSaveSelected, Directory_NativeSaveUseSelected)); + AddHandler(Directory_NativeSaveInitial, new CSettingTypeRelativePath("Save", "")); + AddHandler(Directory_NativeSaveSelected, new CSettingTypeApplicationPath("Directory", "Save", Directory_NativeSaveInitial)); + AddHandler(Directory_NativeSaveUseSelected, new CSettingTypeApplication("Directory", "Save - Use Selected", false)); + + AddHandler(Directory_InstantSave, new CSettingTypeSelectedDirectory("Dir:InstantSave", Directory_InstantSaveInitial, Directory_InstantSaveSelected, Directory_InstantSaveUseSelected)); + AddHandler(Directory_InstantSaveInitial, new CSettingTypeRelativePath("Save", "")); + AddHandler(Directory_InstantSaveSelected, new CSettingTypeApplicationPath("Directory", "Instant Save", Directory_InstantSaveInitial)); + AddHandler(Directory_InstantSaveUseSelected, new CSettingTypeApplication("Directory", "Instant Save - Use Selected", false)); + + AddHandler(Directory_Texture, new CSettingTypeSelectedDirectory("Dir:Texture", Directory_TextureInitial, Directory_TextureSelected, Directory_TextureUseSelected)); + AddHandler(Directory_TextureInitial, new CSettingTypeRelativePath("Textures", "")); + AddHandler(Directory_TextureSelected, new CSettingTypeApplicationPath("Directory", "Texture Dir", Directory_InstantSaveInitial)); + AddHandler(Directory_TextureUseSelected, new CSettingTypeApplication("Directory", "Texture Dir - Use Selected", false)); + + AddHandler(Directory_LastSave, new CSettingTypeApplication("Directory", "Last Save Directory", Directory_InstantSave)); + + AddHandler(GameRunning_LoadingInProgress, new CSettingTypeTempBool(false)); + AddHandler(GameRunning_CPU_Running, new CSettingTypeTempBool(false)); + AddHandler(GameRunning_CPU_Paused, new CSettingTypeTempBool(false)); + AddHandler(GameRunning_CPU_PausedType, new CSettingTypeTempNumber(Default_None)); + AddHandler(GameRunning_InstantSaveFile, new CSettingTypeTempString("")); + AddHandler(GameRunning_LimitFPS, new CSettingTypeTempBool(true)); + AddHandler(GameRunning_ScreenHertz, new CSettingTypeTempNumber(60)); + AddHandler(GameRunning_InReset, new CSettingTypeTempBool(false)); + + AddHandler(File_RecentGameFileCount, new CSettingTypeApplication("", "Remembered Rom Files", (uint32_t)10)); + AddHandler(File_RecentGameFileIndex, new CSettingTypeApplicationIndex("Recent File", "Recent Rom", Default_None)); + AddHandler(File_DiskIPLPath, new CSettingTypeApplicationPath("", "Disk IPL ROM Path", Default_None)); + + AddHandler(Debugger_Enabled, new CSettingTypeApplication("Debugger", "Debugger", false)); + AddHandler(Debugger_ShowTLBMisses, new CSettingTypeApplication("Debugger", "Show TLB Misses", false)); + AddHandler(Debugger_ShowUnhandledMemory, new CSettingTypeApplication("Debugger", "Show Unhandled Memory", false)); + AddHandler(Debugger_ShowPifErrors, new CSettingTypeApplication("Debugger", "Show Pif Errors", false)); + AddHandler(Debugger_DisableGameFixes, new CSettingTypeApplication("Debugger", "Disable Game Fixes", false)); + AddHandler(Debugger_ShowDListAListCount, new CSettingTypeApplication("Debugger", "Show Dlist Alist Count", false)); + AddHandler(Debugger_ShowRecompMemSize, new CSettingTypeApplication("Debugger", "Show Recompiler Memory size", false)); + AddHandler(Debugger_ShowDivByZero, new CSettingTypeApplication("Debugger", "Show Div by zero", false)); + AddHandler(Debugger_ProfileCode, new CSettingTypeApplication("Debugger", "Profile Code", (uint32_t)false)); + AddHandler(Debugger_AppLogFlush, new CSettingTypeApplication("Logging", "Log Auto Flush", (uint32_t)false)); + AddHandler(Debugger_GenerateLogFiles, new CSettingTypeApplication("Debugger", "Generate Log Files", false)); + + //Logging + AddHandler(Debugger_TraceMD5, new CSettingTypeApplication("Logging", "MD5", (uint32_t)g_ModuleLogLevel[TraceMD5])); + AddHandler(Debugger_TraceSettings, new CSettingTypeApplication("Logging", "Settings", (uint32_t)g_ModuleLogLevel[TraceSettings])); + AddHandler(Debugger_TraceUnknown, new CSettingTypeApplication("Logging", "Unknown", (uint32_t)g_ModuleLogLevel[TraceUnknown])); + AddHandler(Debugger_TraceAppInit, new CSettingTypeApplication("Logging", "App Init", (uint32_t)g_ModuleLogLevel[TraceAppInit])); + AddHandler(Debugger_TraceAppCleanup, new CSettingTypeApplication("Logging", "App Cleanup", (uint32_t)g_ModuleLogLevel[TraceAppCleanup])); + AddHandler(Debugger_TraceN64System, new CSettingTypeApplication("Logging", "N64 System", (uint32_t)g_ModuleLogLevel[TraceN64System])); + AddHandler(Debugger_TracePlugins, new CSettingTypeApplication("Logging", "Plugins", (uint32_t)g_ModuleLogLevel[TracePlugins])); + AddHandler(Debugger_TraceGFXPlugin, new CSettingTypeApplication("Logging", "GFX Plugin", (uint32_t)g_ModuleLogLevel[TraceGFXPlugin])); + AddHandler(Debugger_TraceAudioPlugin, new CSettingTypeApplication("Logging", "Audio Plugin", (uint32_t)g_ModuleLogLevel[TraceAudioPlugin])); + AddHandler(Debugger_TraceControllerPlugin, new CSettingTypeApplication("Logging", "Controller Plugin", (uint32_t)g_ModuleLogLevel[TraceControllerPlugin])); + AddHandler(Debugger_TraceRSPPlugin, new CSettingTypeApplication("Logging", "RSP Plugin", (uint32_t)g_ModuleLogLevel[TraceRSPPlugin])); + AddHandler(Debugger_TraceRSP, new CSettingTypeApplication("Logging", "RSP", (uint32_t)g_ModuleLogLevel[TraceRSP])); + AddHandler(Debugger_TraceAudio, new CSettingTypeApplication("Logging", "Audio", (uint32_t)g_ModuleLogLevel[TraceAudio])); + AddHandler(Debugger_TraceRegisterCache, new CSettingTypeApplication("Logging", "Register Cache", (uint32_t)g_ModuleLogLevel[TraceRegisterCache])); + AddHandler(Debugger_TraceRecompiler, new CSettingTypeApplication("Logging", "Recompiler", (uint32_t)g_ModuleLogLevel[TraceRecompiler])); + AddHandler(Debugger_TraceTLB, new CSettingTypeApplication("Logging", "TLB", (uint32_t)g_ModuleLogLevel[TraceTLB])); + AddHandler(Debugger_TraceProtectedMEM, new CSettingTypeApplication("Logging", "Protected MEM", (uint32_t)g_ModuleLogLevel[TraceProtectedMem])); + AddHandler(Debugger_TraceUserInterface, new CSettingTypeApplication("Logging", "User Interface", (uint32_t)g_ModuleLogLevel[TraceUserInterface])); + + //Plugin + AddHandler(Plugin_RSP_Current, new CSettingTypeApplication("Plugin", "RSP Dll", "RSP\\RSP 1.7.dll")); + AddHandler(Plugin_GFX_Current, new CSettingTypeApplication("Plugin", "Graphics Dll", "GFX\\Jabo_Direct3D8.dll")); + AddHandler(Plugin_AUDIO_Current, new CSettingTypeApplication("Plugin", "Audio Dll", "Audio\\Jabo_Dsound.dll")); + AddHandler(Plugin_CONT_Current, new CSettingTypeApplication("Plugin", "Controller Dll", "Input\\PJ64_NRage.dll")); + + AddHandler(Plugin_RSP_CurVer, new CSettingTypeApplication("Plugin", "RSP Dll Ver", "")); + AddHandler(Plugin_GFX_CurVer, new CSettingTypeApplication("Plugin", "Graphics Dll Ver", "")); + AddHandler(Plugin_AUDIO_CurVer, new CSettingTypeApplication("Plugin", "Audio Dll Ver", "")); + AddHandler(Plugin_CONT_CurVer, new CSettingTypeApplication("Plugin", "Controller Dll Ver", "")); + + AddHandler(Plugin_UseHleGfx, new CSettingTypeApplication("RSP", "HLE GFX", true)); + AddHandler(Plugin_UseHleAudio, new CSettingTypeApplication("RSP", "HLE Audio", false)); + + //Logging + AddHandler(Logging_GenerateLog, new CSettingTypeApplication("Logging", "Generate Log Files", false)); + AddHandler(Logging_LogRDRamRegisters, new CSettingTypeApplication("Logging", "Log RDRam Registers", false)); + AddHandler(Logging_LogSPRegisters, new CSettingTypeApplication("Logging", "Log SP Registers", false)); + AddHandler(Logging_LogDPCRegisters, new CSettingTypeApplication("Logging", "Log DPC Registers", false)); + AddHandler(Logging_LogDPSRegisters, new CSettingTypeApplication("Logging", "Log DPS Registers", false)); + AddHandler(Logging_LogMIPSInterface, new CSettingTypeApplication("Logging", "Log MIPS Interface", false)); + AddHandler(Logging_LogVideoInterface, new CSettingTypeApplication("Logging", "Log Video Interface", false)); + AddHandler(Logging_LogAudioInterface, new CSettingTypeApplication("Logging", "Log Audio Interface", false)); + AddHandler(Logging_LogPerInterface, new CSettingTypeApplication("Logging", "Log Per Interface", false)); + AddHandler(Logging_LogRDRAMInterface, new CSettingTypeApplication("Logging", "Log RDRAM Interface", false)); + AddHandler(Logging_LogSerialInterface, new CSettingTypeApplication("Logging", "Log Serial Interface", false)); + AddHandler(Logging_LogPRDMAOperations, new CSettingTypeApplication("Logging", "Log PR DMA Operations", false)); + AddHandler(Logging_LogPRDirectMemLoads, new CSettingTypeApplication("Logging", "Log PR Direct Mem Loads", false)); + AddHandler(Logging_LogPRDMAMemLoads, new CSettingTypeApplication("Logging", "Log PR DMA Mem Loads", false)); + AddHandler(Logging_LogPRDirectMemStores, new CSettingTypeApplication("Logging", "Log PR Direct Mem Stores", false)); + AddHandler(Logging_LogPRDMAMemStores, new CSettingTypeApplication("Logging", "Log PRDMA Mem Stores", false)); + AddHandler(Logging_LogControllerPak, new CSettingTypeApplication("Logging", "Log Controller Pak", false)); + AddHandler(Logging_LogCP0changes, new CSettingTypeApplication("Logging", "Log CP0 changes", false)); + AddHandler(Logging_LogCP0reads, new CSettingTypeApplication("Logging", "Log CP0 reads", false)); + AddHandler(Logging_LogTLB, new CSettingTypeApplication("Logging", "Log TLB", false)); + AddHandler(Logging_LogExceptions, new CSettingTypeApplication("Logging", "Log Exceptions", false)); + AddHandler(Logging_NoInterrupts, new CSettingTypeApplication("Logging", "No Interrupts", false)); + AddHandler(Logging_LogCache, new CSettingTypeApplication("Logging", "Log Cache", false)); + AddHandler(Logging_LogRomHeader, new CSettingTypeApplication("Logging", "Generate Log Files", false)); + AddHandler(Logging_LogUnknown, new CSettingTypeApplication("Logging", "Log Rom Header", false)); + + // cheats + AddHandler(Cheat_Entry, new CSettingTypeCheats("")); + AddHandler(Cheat_Active, new CSettingTypeGameIndex("Cheat", "", (uint32_t)false)); + AddHandler(Cheat_Extension, new CSettingTypeGameIndex("Cheat", ".exten", "??? - Not Set")); + AddHandler(Cheat_Notes, new CSettingTypeCheats("_N")); + AddHandler(Cheat_Options, new CSettingTypeCheats("_O")); + AddHandler(Cheat_Range, new CSettingTypeCheats("_R")); + AddHandler(Cheat_RangeNotes, new CSettingTypeCheats("_RN")); +} + +uint32_t CSettings::FindSetting(CSettings * _this, const char * Name) +{ + for (SETTING_MAP::iterator iter = _this->m_SettingInfo.begin(); iter != _this->m_SettingInfo.end(); iter++) + { + CSettingType * Setting = iter->second; + if (Setting->GetSettingType() == SettingType_GameSetting) + { + CSettingTypeGame * GameSetting = (CSettingTypeGame *)Setting; + if (_stricmp(GameSetting->GetKeyName(), Name) != 0) + { + continue; + } + return iter->first; + } + if (Setting->GetSettingType() == SettingType_CfgFile) + { + CSettingTypeApplication * CfgSetting = (CSettingTypeApplication *)Setting; + if (_stricmp(CfgSetting->GetKeyName(), Name) != 0) + { + continue; + } + return iter->first; + } + if (Setting->GetSettingType() == SettingType_SelectedDirectory) + { + CSettingTypeSelectedDirectory * SelectedDirectory = (CSettingTypeSelectedDirectory *)Setting; + if (_stricmp(SelectedDirectory->GetName(), Name) != 0) + { + continue; + } + return iter->first; + } + } + return 0; +} + +void CSettings::FlushSettings(CSettings * /*_this*/) +{ + CSettingTypeCheats::FlushChanges(); + CSettingTypeApplication::Flush(); +} + +uint32_t CSettings::GetSetting(CSettings * _this, SettingID Type) +{ + return _this->LoadDword(Type); +} + +const char * CSettings::GetSettingSz(CSettings * _this, SettingID Type, char * Buffer, int BufferSize) +{ + if (Buffer && BufferSize > 0) + { + Buffer[0] = 0; + _this->LoadStringVal(Type, Buffer, BufferSize); + } + return Buffer; +} + +void CSettings::SetSetting(CSettings * _this, SettingID ID, uint32_t Value) +{ + _this->SaveDword(ID, Value); +} + +void CSettings::SetSettingSz(CSettings * _this, SettingID ID, const char * Value) +{ + _this->SaveString(ID, Value); +} + +void CSettings::RegisterSetting(CSettings * _this, SettingID ID, SettingID DefaultID, SettingDataType DataType, + SettingType Type, const char * Category, const char * DefaultStr, + uint32_t Value) +{ + switch (Type) + { + case SettingType_ConstValue: + if (DataType != Data_DWORD) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + _this->AddHandler(ID, new CSettingTypeTempNumber(Value)); + break; + case SettingType_ConstString: + if (DataType != Data_String) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + _this->AddHandler(ID, new CSettingTypeTempString(DefaultStr)); + break; + case SettingType_CfgFile: + case SettingType_Registry: + switch (DataType) + { + case Data_DWORD: + if (DefaultID == Default_None) + { + _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, Value)); + } + else + { + _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, DefaultID)); + } + break; + case Data_String: + if (DefaultID == Default_None) + { + _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, "")); + } + else + { + _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, DefaultID)); + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + break; + case SettingType_GameSetting: + { + stdstr_f Name("%s-%s", Category, DefaultStr); + switch (DataType) + { + case Data_DWORD: + if (DefaultID == Default_None) + { + SettingID RdbSetting = (SettingID)_this->m_NextAutoSettingId; + _this->m_NextAutoSettingId += 1; + _this->AddHandler(RdbSetting, new CSettingTypeRomDatabase(Name.c_str(), (int)Value)); + _this->AddHandler(ID, new CSettingTypeGame(Name.c_str(), RdbSetting)); + } + else + { + _this->AddHandler(ID, new CSettingTypeGame(Name.c_str(), DefaultID)); + } + break; + case Data_String: + if (DefaultID == Default_None) + { + _this->AddHandler(ID, new CSettingTypeGame(Name.c_str(), "")); + } + else + { + _this->AddHandler(ID, new CSettingTypeGame(Name.c_str(), DefaultID)); + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + break; + case SettingType_RomDatabase: + switch (DataType) + { + case Data_DWORD: + if (DefaultID == Default_None) + { + _this->AddHandler(ID, new CSettingTypeRomDatabase(DefaultStr, (int)Value, true)); + } + else + { + _this->AddHandler(ID, new CSettingTypeRomDatabase(DefaultStr, (SettingID)Value, true)); + } + break; + case Data_String: + if (DefaultID == Default_None) + { + _this->AddHandler(ID, new CSettingTypeRomDatabase(DefaultStr, "", true)); + } + else + { + _this->AddHandler(ID, new CSettingTypeRomDatabase(DefaultStr, DefaultID, true)); + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + break; + case SettingType_RdbSetting: + switch (DataType) + { + case Data_DWORD: + if (DefaultID == Default_None) + { + _this->AddHandler(ID, new CSettingTypeRomDatabaseSetting(Category, DefaultStr, (int)Value, true)); + } + else + { + SettingID RdbSetting = (SettingID)_this->m_NextAutoSettingId; + _this->m_NextAutoSettingId += 1; + _this->AddHandler(RdbSetting, new CSettingTypeRomDatabaseSetting(Category, DefaultStr, DefaultID, true)); + _this->AddHandler(ID, new CSettingTypeApplication(Category, DefaultStr, RdbSetting)); + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + +bool CSettings::Initialize(const char * AppName) +{ + AddHowToHandleSetting(); + CSettingTypeApplication::Initialize(AppName); + CSettingTypeRomDatabase::Initialize(); + CSettingTypeGame::Initialize(); + CSettingTypeCheats::Initialize(); + + g_Settings->SaveString(Setting_ApplicationName, AppName); + return true; +} + +bool CSettings::LoadBool(SettingID Type) +{ + bool Value = false; + LoadBool(Type, Value); + return Value; +} + +bool CSettings::LoadBool(SettingID Type, bool & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return 0; + } + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + return FindInfo->second->Load(0, Value); + } + return false; +} + +bool CSettings::LoadBoolIndex(SettingID Type, int index) +{ + bool Value = false; + LoadBoolIndex(Type, index, Value); + return Value; +} + +bool CSettings::LoadBoolIndex(SettingID Type, int index, bool & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return false; + } + if (FindInfo->second->IndexBasedSetting()) + { + return FindInfo->second->Load(index, Value); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + return false; +} + +uint32_t CSettings::LoadDword(SettingID Type) +{ + uint32_t Value = 0; + LoadDword(Type, Value); + return Value; +} + +bool CSettings::LoadDword(SettingID Type, uint32_t & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return false; + } + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + return FindInfo->second->Load(0, Value); + } + return false; +} + +uint32_t CSettings::LoadDwordIndex(SettingID Type, int index) +{ + uint32_t Value; + LoadDwordIndex(Type, index, Value); + return Value; +} + +bool CSettings::LoadDwordIndex(SettingID Type, int index, uint32_t & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return 0; + } + if (FindInfo->second->IndexBasedSetting()) + { + return FindInfo->second->Load(index, Value); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + return false; +} + +stdstr CSettings::LoadStringVal(SettingID Type) +{ + stdstr Value; + LoadStringVal(Type, Value); + return Value; +} + +bool CSettings::LoadStringVal(SettingID Type, stdstr & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return 0; + } + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + return FindInfo->second->Load(0, Value); + } + return false; +} + +bool CSettings::LoadStringVal(SettingID Type, char * Buffer, int BufferSize) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return 0; + } + bool bRes = false; + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + stdstr Value; + bRes = FindInfo->second->Load(0, Value); + int len = BufferSize; + if ((Value.length() + 1) < (size_t)len) + { + len = Value.length() + 1; + } + strncpy(Buffer, Value.c_str(), len); + } + return bRes; +} + +stdstr CSettings::LoadStringIndex(SettingID Type, int index) +{ + stdstr Value; + LoadStringIndex(Type, index, Value); + return Value; +} + +bool CSettings::LoadStringIndex(SettingID Type, int index, stdstr & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return 0; + } + if (FindInfo->second->IndexBasedSetting()) + { + return FindInfo->second->Load(index, Value); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + return false; +} + +bool CSettings::LoadStringIndex(SettingID /*Type*/, int /*index*/, char * /*Buffer*/, int /*BufferSize*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +//Load the default value for the setting +bool CSettings::LoadDefaultBool(SettingID Type) +{ + bool Value = false; + LoadDefaultBool(Type, Value); + return Value; +} + +void CSettings::LoadDefaultBool(SettingID Type, bool & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + else + { + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + FindInfo->second->LoadDefault(0, Value); + } + } +} + +bool CSettings::LoadDefaultBoolIndex(SettingID /*Type*/, int /*index*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +void CSettings::LoadDefaultBoolIndex(SettingID /*Type*/, int /*index*/, bool & /*Value*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +uint32_t CSettings::LoadDefaultDword(SettingID Type) +{ + uint32_t Value = 0; + LoadDefaultDword(Type, Value); + return Value; +} + +void CSettings::LoadDefaultDword(SettingID Type, uint32_t & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + else + { + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + FindInfo->second->LoadDefault(0, Value); + } + } +} + +uint32_t CSettings::LoadDefaultDwordIndex(SettingID /*Type*/, int /*index*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; +} + +void CSettings::LoadDefaultDwordIndex(SettingID /*Type*/, int /*index*/, uint32_t & /*Value*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +stdstr CSettings::LoadDefaultString(SettingID Type) +{ + stdstr Value; + LoadDefaultString(Type, Value); + return Value; +} + +void CSettings::LoadDefaultString(SettingID Type, stdstr & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + else + { + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + FindInfo->second->LoadDefault(0, Value); + } + } +} + +void CSettings::LoadDefaultString(SettingID /*Type*/, char * /*Buffer*/, int /*BufferSize*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +stdstr CSettings::LoadDefaultStringIndex(SettingID /*Type*/, int /*index*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); + return ""; +} + +void CSettings::LoadDefaultStringIndex(SettingID /*Type*/, int /*index*/, stdstr & /*Value*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettings::LoadDefaultStringIndex(SettingID /*Type*/, int /*index*/, char * /*Buffer*/, int /*BufferSize*/) +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CSettings::SaveBool(SettingID Type, bool Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return; + } + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + FindInfo->second->Save(0, Value); + } + NotifyCallBacks(Type); +} + +void CSettings::SaveBoolIndex(SettingID Type, int index, bool Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return; + } + if (FindInfo->second->IndexBasedSetting()) + { + FindInfo->second->Save(index, Value); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + NotifyCallBacks(Type); +} + +void CSettings::SaveDword(SettingID Type, uint32_t Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return; + } + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + FindInfo->second->Save(0, Value); + } + NotifyCallBacks(Type); +} + +void CSettings::SaveDwordIndex(SettingID Type, int index, uint32_t Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return; + } + if (FindInfo->second->IndexBasedSetting()) + { + FindInfo->second->Save(index, Value); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + NotifyCallBacks(Type); +} + +void CSettings::SaveString(SettingID Type, const stdstr & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return; + } + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + FindInfo->second->Save(0, Value); + } + NotifyCallBacks(Type); +} + +void CSettings::SaveString(SettingID Type, const char * Buffer) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + else if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + FindInfo->second->Save(0, Buffer); + } + NotifyCallBacks(Type); +} + +void CSettings::SaveStringIndex(SettingID Type, int index, const char * Buffer) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + if (FindInfo->second->IndexBasedSetting()) + { + FindInfo->second->Save(index, Buffer); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + NotifyCallBacks(Type); +} + +void CSettings::SaveStringIndex(SettingID Type, int index, const stdstr & Value) +{ + SaveStringIndex(Type, index, Value.c_str()); +} + +void CSettings::DeleteSetting(SettingID Type) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + if (FindInfo->second->IndexBasedSetting()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + else + { + FindInfo->second->Delete(0); + } + NotifyCallBacks(Type); +} + +void CSettings::DeleteSettingIndex(SettingID Type, int index) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + if (FindInfo->second->IndexBasedSetting()) + { + FindInfo->second->Delete(index); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + NotifyCallBacks(Type); +} + +SettingType CSettings::GetSettingType(SettingID Type) +{ + if (Type == Default_None || Type == Default_Constant) + { + return SettingType_Unknown; + } + + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + return SettingType_Unknown; + } + return FindInfo->second->GetSettingType(); +} + +bool CSettings::IndexBasedSetting(SettingID Type) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + return false; + } + return FindInfo->second->IndexBasedSetting(); +} + +void CSettings::SettingTypeChanged(SettingType Type) +{ + for (SETTING_MAP::iterator iter = m_SettingInfo.begin(); iter != m_SettingInfo.end(); iter++) + { + if (iter->second->GetSettingType() == Type) + { + NotifyCallBacks(iter->first); + } + } +} +void CSettings::UnknownSetting(SettingID /*Type*/) +{ +#ifdef _DEBUG + g_Notify->BreakPoint(__FILE__, __LINE__); +#endif +} + +void CSettings::NotifyCallBacks(SettingID Type) +{ + SETTING_CALLBACK::iterator Callback = m_Callback.find(Type); + if (Callback == m_Callback.end()) + { + return; + } + + for (SETTING_CHANGED_CB * item = Callback->second; item != NULL; item = item->Next) + { + item->Func(item->Data); + } +} + +void CSettings::RegisterChangeCB(SettingID Type, void * Data, SettingChangedFunc Func) +{ + SETTING_CHANGED_CB * new_item = new SETTING_CHANGED_CB; + new_item->Data = Data; + new_item->Func = Func; + new_item->Next = NULL; + + SETTING_CALLBACK::iterator Callback = m_Callback.find(Type); + if (Callback != m_Callback.end()) + { + SETTING_CHANGED_CB * item = Callback->second; + while (item->Next) + { + item = item->Next; + } + item->Next = new_item; + } + else + { + m_Callback.insert(SETTING_CALLBACK::value_type(Type, new_item)); + } +} + +void CSettings::UnregisterChangeCB(SettingID Type, void * Data, SettingChangedFunc Func) +{ + bool bRemoved = false; + + //Find out the information for handling the setting type from the list + SETTING_CALLBACK::iterator Callback = m_Callback.find(Type); + if (Callback != m_Callback.end()) + { + SETTING_CHANGED_CB * PrevItem = NULL; + SETTING_CHANGED_CB * item = Callback->second; + + while (item) + { + if (Callback->first == Type && item->Data == Data && item->Func == Func) + { + bRemoved = true; + if (PrevItem == NULL) + { + if (item->Next) + { + SettingID Type = Callback->first; + SETTING_CHANGED_CB * Next = item->Next; + m_Callback.erase(Callback); + m_Callback.insert(SETTING_CALLBACK::value_type(Type, Next)); + } + else + { + m_Callback.erase(Callback); + } + } + else + { + PrevItem->Next = item->Next; + } + delete item; + item = NULL; + break; + } + PrevItem = item; + item = item->Next; + } + } + else + { + UnknownSetting(Type); + return; + } + + if (!bRemoved) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} diff --git a/Source/Project64/N64System.h b/Source/Project64/N64System.h index 44fc083a9..13b42335a 100644 --- a/Source/Project64/N64System.h +++ b/Source/Project64/N64System.h @@ -1,29 +1,29 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include "Support.h" -#include //needed for stl string (std::string) -#include -#include - -#include "UserInterface.h" -#include - -#include - -//General Mips Information -#include -#include -#include -#include -#include -#include +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include "Support.h" +#include //needed for stl string (std::string) +#include +#include + +#include "UserInterface.h" +#include + +#include + +//General Mips Information +#include +#include +#include +#include +#include +#include diff --git a/Source/Project64/N64System/Debugger/DebugDialog.h b/Source/Project64/N64System/Debugger/DebugDialog.h index a64a45c24..70413dc31 100644 --- a/Source/Project64/N64System/Debugger/DebugDialog.h +++ b/Source/Project64/N64System/Debugger/DebugDialog.h @@ -1,76 +1,76 @@ -template -class CDebugDialog : - public CDialogImpl < T > -{ -protected: - CDebuggerUI * m_Debugger; - HANDLE m_CreatedEvent; - HANDLE m_DialogThread; - - static DWORD CreateDebuggerWindow(CDebugDialog * pThis) - { - pThis->DoModal(NULL); - pThis->WindowCreated(); - return 0; - } - - void WindowCreated(void) - { - SetEvent(m_CreatedEvent); - } - -public: - CDebugDialog(CDebuggerUI * debugger) : - m_Debugger(debugger), - m_CreatedEvent(CreateEvent(NULL, true, false, NULL)), - m_DialogThread(NULL) - { - } - virtual ~CDebugDialog(void) - { - HideWindow(); - CloseHandle(m_CreatedEvent); - if (m_DialogThread) - { - CloseHandle(m_DialogThread); - m_DialogThread = NULL; - } - } - - void HideWindow(void) - { - if (m_hWnd && ::IsWindow(m_hWnd)) - { - ::EndDialog(m_hWnd, 0); - } - if (m_DialogThread) - { - if (WaitForSingleObject(m_DialogThread, 5000) == WAIT_TIMEOUT) - { - WriteTrace(TraceUserInterface, TraceError, "CDebugDialog - time out on close"); - - TerminateThread(m_DialogThread, 1); - } - CloseHandle(m_DialogThread); - m_DialogThread = NULL; - } - } - - void ShowWindow(void) - { - if (m_hWnd) - { - SetForegroundWindow((HWND)m_hWnd); - } - else - { - DWORD ThreadID; - ResetEvent(m_CreatedEvent); - m_DialogThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateDebuggerWindow, (LPVOID)this, 0, &ThreadID); - if (WaitForSingleObject(m_CreatedEvent, 20000) == WAIT_TIMEOUT) - { - WriteTrace(TraceUserInterface, TraceError, "Failed to get window create notification"); - } - } - } -}; +template +class CDebugDialog : + public CDialogImpl < T > +{ +protected: + CDebuggerUI * m_Debugger; + HANDLE m_CreatedEvent; + HANDLE m_DialogThread; + + static DWORD CreateDebuggerWindow(CDebugDialog * pThis) + { + pThis->DoModal(NULL); + pThis->WindowCreated(); + return 0; + } + + void WindowCreated(void) + { + SetEvent(m_CreatedEvent); + } + +public: + CDebugDialog(CDebuggerUI * debugger) : + m_Debugger(debugger), + m_CreatedEvent(CreateEvent(NULL, true, false, NULL)), + m_DialogThread(NULL) + { + } + virtual ~CDebugDialog(void) + { + HideWindow(); + CloseHandle(m_CreatedEvent); + if (m_DialogThread) + { + CloseHandle(m_DialogThread); + m_DialogThread = NULL; + } + } + + void HideWindow(void) + { + if (m_hWnd && ::IsWindow(m_hWnd)) + { + ::EndDialog(m_hWnd, 0); + } + if (m_DialogThread) + { + if (WaitForSingleObject(m_DialogThread, 5000) == WAIT_TIMEOUT) + { + WriteTrace(TraceUserInterface, TraceError, "CDebugDialog - time out on close"); + + TerminateThread(m_DialogThread, 1); + } + CloseHandle(m_DialogThread); + m_DialogThread = NULL; + } + } + + void ShowWindow(void) + { + if (m_hWnd) + { + SetForegroundWindow((HWND)m_hWnd); + } + else + { + DWORD ThreadID; + ResetEvent(m_CreatedEvent); + m_DialogThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateDebuggerWindow, (LPVOID)this, 0, &ThreadID); + if (WaitForSingleObject(m_CreatedEvent, 20000) == WAIT_TIMEOUT) + { + WriteTrace(TraceUserInterface, TraceError, "Failed to get window create notification"); + } + } + } +}; diff --git a/Source/Project64/N64System/Debugger/Debugger-MemoryDump.cpp b/Source/Project64/N64System/Debugger/Debugger-MemoryDump.cpp index 4b90ecc4e..7f594d24c 100644 --- a/Source/Project64/N64System/Debugger/Debugger-MemoryDump.cpp +++ b/Source/Project64/N64System/Debugger/Debugger-MemoryDump.cpp @@ -1,157 +1,157 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "DebuggerUI.h" - -CDumpMemory::CDumpMemory(CDebuggerUI * debugger) : -CDebugDialog(debugger) -{ -} - -CDumpMemory::~CDumpMemory() -{ -} - -LRESULT CDumpMemory::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ - m_StartAddress.Attach(GetDlgItem(IDC_E_START_ADDR)); - m_EndAddress.Attach(GetDlgItem(IDC_E_END_ADDR)); - m_PC.Attach(GetDlgItem(IDC_E_ALT_PC)); - - m_StartAddress.SetDisplayType(CEditNumber::DisplayHex); - m_EndAddress.SetDisplayType(CEditNumber::DisplayHex); - m_PC.SetDisplayType(CEditNumber::DisplayHex); - - m_StartAddress.SetValue(0x80000000, true, true); - m_EndAddress.SetValue(0x803FFFF0, true, true); - m_PC.SetValue(0x80000000); - HWND hFormatList = GetDlgItem(IDC_FORMAT); - int pos = ::SendMessage(hFormatList, CB_ADDSTRING, (WPARAM)0, (LPARAM)"TEXT - Disassembly + PC"); - ::SendMessage(hFormatList, CB_SETITEMDATA, (WPARAM)pos, (LPARAM)DisassemblyWithPC); - ::SendMessage(hFormatList, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); - - WindowCreated(); - return TRUE; -} - -LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ - switch (wID) - { - case IDCANCEL: - EndDialog(0); - break; - case IDC_BTN_CHOOSE_FILE: - { - char FileName[_MAX_PATH], Directory[_MAX_PATH]; - OPENFILENAME openfilename; - - memset(&FileName, 0, sizeof(FileName)); - memset(&openfilename, 0, sizeof(openfilename)); - strcpy(Directory, CPath(CPath::MODULE_DIRECTORY)); - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = m_hWnd; - openfilename.lpstrFilter = "Text file (*.txt)\0*.txt;\0All files (*.*)\0*.*\0"; - openfilename.lpstrFile = FileName; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_HIDEREADONLY; - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_DumpMemory); - if (GetOpenFileName(&openfilename)) - { - char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; - _splitpath(FileName, drive, dir, fname, ext); - if (strlen(ext) == 0) - { - strcat(FileName, ".txt"); - } - SetDlgItemText(IDC_FILENAME, FileName); - } - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_DumpMemory); - } - break; - case IDOK: - { - TCHAR FileName[MAX_PATH]; - int CurrentFormatSel = SendDlgItemMessage(IDC_FORMAT, CB_GETCURSEL, 0, 0); - DumpFormat Format = (DumpFormat)SendDlgItemMessage(IDC_FORMAT, CB_GETITEMDATA, CurrentFormatSel, 0); - DWORD StartPC = m_StartAddress.GetValue(); - DWORD EndPC = m_EndAddress.GetValue(); - DWORD DumpPC = m_PC.GetValue(); - GetDlgItemText(IDC_FILENAME, FileName, sizeof(FileName)); - if (strlen(FileName) == 0) - { - g_Notify->DisplayError("Please Choose target file"); - ::SetFocus(GetDlgItem(IDC_FILENAME)); - return false; - } - if (SendDlgItemMessage(IDC_USE_ALT_PC, BM_GETSTATE, 0, 0) != BST_CHECKED) - { - DumpPC = g_Reg->m_PROGRAM_COUNTER; - } - //disable buttons - ::EnableWindow(GetDlgItem(IDC_E_START_ADDR), FALSE); - ::EnableWindow(GetDlgItem(IDC_E_END_ADDR), FALSE); - ::EnableWindow(GetDlgItem(IDC_E_ALT_PC), FALSE); - ::EnableWindow(GetDlgItem(IDC_USE_ALT_PC), FALSE); - ::EnableWindow(GetDlgItem(IDC_FILENAME), FALSE); - ::EnableWindow(GetDlgItem(IDC_BTN_CHOOSE_FILE), FALSE); - ::EnableWindow(GetDlgItem(IDC_FORMAT), FALSE); - ::EnableWindow(GetDlgItem(IDOK), FALSE); - ::EnableWindow(GetDlgItem(IDCANCEL), FALSE); - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_DumpMemory); - if (!DumpMemory(FileName, Format, StartPC, EndPC, DumpPC)) - { - //enable buttons - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_DumpMemory); - return false; - } - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_DumpMemory); - } - EndDialog(0); - break; - } - return FALSE; -} - -bool CDumpMemory::DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD /*DumpPC*/) -{ - switch (Format) - { - case DisassemblyWithPC: - { - CLog LogFile; - if (!LogFile.Open(FileName)) - { - g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str()); - return false; - } - LogFile.SetFlush(false); - LogFile.SetTruncateFile(false); - g_Notify->BreakPoint(__FILE__, __LINE__); -#ifdef legacycode - char Command[200]; - for (COpcode OpCode(StartPC); OpCode.PC() < EndPC; OpCode.Next()) - { - const char * szOpName = OpCode.OpcodeName(); - OpCode.OpcodeParam(Command); - LogFile.LogF("%X: %-15s%s\r\n",OpCode.PC(),szOpName,Command); - } -#endif - m_StartAddress.SetValue(StartPC, true, true); - m_EndAddress.SetValue(EndPC, true, true); - return true; - } - break; - } - return false; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "DebuggerUI.h" + +CDumpMemory::CDumpMemory(CDebuggerUI * debugger) : +CDebugDialog(debugger) +{ +} + +CDumpMemory::~CDumpMemory() +{ +} + +LRESULT CDumpMemory::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + m_StartAddress.Attach(GetDlgItem(IDC_E_START_ADDR)); + m_EndAddress.Attach(GetDlgItem(IDC_E_END_ADDR)); + m_PC.Attach(GetDlgItem(IDC_E_ALT_PC)); + + m_StartAddress.SetDisplayType(CEditNumber::DisplayHex); + m_EndAddress.SetDisplayType(CEditNumber::DisplayHex); + m_PC.SetDisplayType(CEditNumber::DisplayHex); + + m_StartAddress.SetValue(0x80000000, true, true); + m_EndAddress.SetValue(0x803FFFF0, true, true); + m_PC.SetValue(0x80000000); + HWND hFormatList = GetDlgItem(IDC_FORMAT); + int pos = ::SendMessage(hFormatList, CB_ADDSTRING, (WPARAM)0, (LPARAM)"TEXT - Disassembly + PC"); + ::SendMessage(hFormatList, CB_SETITEMDATA, (WPARAM)pos, (LPARAM)DisassemblyWithPC); + ::SendMessage(hFormatList, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); + + WindowCreated(); + return TRUE; +} + +LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + switch (wID) + { + case IDCANCEL: + EndDialog(0); + break; + case IDC_BTN_CHOOSE_FILE: + { + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + OPENFILENAME openfilename; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + strcpy(Directory, CPath(CPath::MODULE_DIRECTORY)); + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = m_hWnd; + openfilename.lpstrFilter = "Text file (*.txt)\0*.txt;\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_HIDEREADONLY; + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_DumpMemory); + if (GetOpenFileName(&openfilename)) + { + char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; + _splitpath(FileName, drive, dir, fname, ext); + if (strlen(ext) == 0) + { + strcat(FileName, ".txt"); + } + SetDlgItemText(IDC_FILENAME, FileName); + } + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_DumpMemory); + } + break; + case IDOK: + { + TCHAR FileName[MAX_PATH]; + int CurrentFormatSel = SendDlgItemMessage(IDC_FORMAT, CB_GETCURSEL, 0, 0); + DumpFormat Format = (DumpFormat)SendDlgItemMessage(IDC_FORMAT, CB_GETITEMDATA, CurrentFormatSel, 0); + DWORD StartPC = m_StartAddress.GetValue(); + DWORD EndPC = m_EndAddress.GetValue(); + DWORD DumpPC = m_PC.GetValue(); + GetDlgItemText(IDC_FILENAME, FileName, sizeof(FileName)); + if (strlen(FileName) == 0) + { + g_Notify->DisplayError("Please Choose target file"); + ::SetFocus(GetDlgItem(IDC_FILENAME)); + return false; + } + if (SendDlgItemMessage(IDC_USE_ALT_PC, BM_GETSTATE, 0, 0) != BST_CHECKED) + { + DumpPC = g_Reg->m_PROGRAM_COUNTER; + } + //disable buttons + ::EnableWindow(GetDlgItem(IDC_E_START_ADDR), FALSE); + ::EnableWindow(GetDlgItem(IDC_E_END_ADDR), FALSE); + ::EnableWindow(GetDlgItem(IDC_E_ALT_PC), FALSE); + ::EnableWindow(GetDlgItem(IDC_USE_ALT_PC), FALSE); + ::EnableWindow(GetDlgItem(IDC_FILENAME), FALSE); + ::EnableWindow(GetDlgItem(IDC_BTN_CHOOSE_FILE), FALSE); + ::EnableWindow(GetDlgItem(IDC_FORMAT), FALSE); + ::EnableWindow(GetDlgItem(IDOK), FALSE); + ::EnableWindow(GetDlgItem(IDCANCEL), FALSE); + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_DumpMemory); + if (!DumpMemory(FileName, Format, StartPC, EndPC, DumpPC)) + { + //enable buttons + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_DumpMemory); + return false; + } + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_DumpMemory); + } + EndDialog(0); + break; + } + return FALSE; +} + +bool CDumpMemory::DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD /*DumpPC*/) +{ + switch (Format) + { + case DisassemblyWithPC: + { + CLog LogFile; + if (!LogFile.Open(FileName)) + { + g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str()); + return false; + } + LogFile.SetFlush(false); + LogFile.SetTruncateFile(false); + g_Notify->BreakPoint(__FILE__, __LINE__); +#ifdef legacycode + char Command[200]; + for (COpcode OpCode(StartPC); OpCode.PC() < EndPC; OpCode.Next()) + { + const char * szOpName = OpCode.OpcodeName(); + OpCode.OpcodeParam(Command); + LogFile.LogF("%X: %-15s%s\r\n",OpCode.PC(),szOpName,Command); + } +#endif + m_StartAddress.SetValue(StartPC, true, true); + m_EndAddress.SetValue(EndPC, true, true); + return true; + } + break; + } + return false; } \ No newline at end of file diff --git a/Source/Project64/N64System/Debugger/Debugger-MemoryDump.h b/Source/Project64/N64System/Debugger/Debugger-MemoryDump.h index 3cc97858f..61b4839bf 100644 --- a/Source/Project64/N64System/Debugger/Debugger-MemoryDump.h +++ b/Source/Project64/N64System/Debugger/Debugger-MemoryDump.h @@ -1,43 +1,43 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CDumpMemory : - public CDebugDialog < CDumpMemory > -{ -public: - enum { IDD = IDD_Cheats_DumpMemory }; - - CDumpMemory(CDebuggerUI * debugger); - virtual ~CDumpMemory(void); - -private: - CDumpMemory(void); // Disable default constructor - CDumpMemory(const CDumpMemory&); // Disable copy constructor - CDumpMemory& operator=(const CDumpMemory&); // Disable assignment - - enum DumpFormat - { - DisassemblyWithPC - }; - - BEGIN_MSG_MAP_EX(CDumpMemory) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); - - bool DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD DumpPC); - - CEditNumber m_StartAddress, m_EndAddress, m_PC; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CDumpMemory : + public CDebugDialog < CDumpMemory > +{ +public: + enum { IDD = IDD_Cheats_DumpMemory }; + + CDumpMemory(CDebuggerUI * debugger); + virtual ~CDumpMemory(void); + +private: + CDumpMemory(void); // Disable default constructor + CDumpMemory(const CDumpMemory&); // Disable copy constructor + CDumpMemory& operator=(const CDumpMemory&); // Disable assignment + + enum DumpFormat + { + DisassemblyWithPC + }; + + BEGIN_MSG_MAP_EX(CDumpMemory) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); + + bool DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD DumpPC); + + CEditNumber m_StartAddress, m_EndAddress, m_PC; +}; diff --git a/Source/Project64/N64System/Debugger/Debugger-MemorySearch.cpp b/Source/Project64/N64System/Debugger/Debugger-MemorySearch.cpp index 9b9499c00..253688c2b 100644 --- a/Source/Project64/N64System/Debugger/Debugger-MemorySearch.cpp +++ b/Source/Project64/N64System/Debugger/Debugger-MemorySearch.cpp @@ -1,790 +1,790 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "DebuggerUI.h" - -CDebugMemorySearch::CDebugMemorySearch(CDebuggerUI * debugger) : - CDebugDialog(debugger), - m_MemoryState(NULL), - m_MemoryStateSize(0) -{ -} - -CDebugMemorySearch::~CDebugMemorySearch() -{ - if (m_MemoryState) - { - delete m_MemoryState; - } -} - -void CDebugMemorySearch::AddAlignmentOptions(CComboBox & ctrl) -{ - int Index = ctrl.AddString("32 bits (aligned)"); - ctrl.SetItemData(Index, _32Bit); - Index = ctrl.AddString("16bits (aligned)"); - ctrl.SetItemData(Index, _16Bit); - Index = ctrl.AddString("8bits"); - ctrl.SetCurSel(Index); - ctrl.SetItemData(Index, _8Bit); -} - -LRESULT CDebugMemorySearch::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ - m_PAddrStart.Attach(GetDlgItem(IDC_PADDR_START)); - m_PAddrStart.SetDisplayType(CEditNumber::DisplayHex); - m_SearchLen.Attach(GetDlgItem(IDC_ADDR_END)); - m_SearchLen.SetDisplayType(CEditNumber::DisplayHex); - m_SearchValue.Attach(GetDlgItem(IDC_SEARCH_VALUE)); - m_SearchValue.SetDisplayType(CEditNumber::DisplayDec); - m_SearchValue.SetValue(0); - m_MaxSearch.Attach(GetDlgItem(IDC_MAX_SEARCH)); - m_MaxSearch.SetDisplayType(CEditNumber::DisplayDec); - m_MaxSearch.SetValue(50000); - m_UnknownSize.Attach(GetDlgItem(IDC_UNKNOWN_ALIGN)); - AddAlignmentOptions(m_UnknownSize); - m_ValueSize.Attach(GetDlgItem(IDC_VALUE_ALIGN)); - AddAlignmentOptions(m_ValueSize); - m_SearchResults.Attach(GetDlgItem(IDC_LST_RESULTS)); - m_SearchResults.AddColumn("ID", 0); - m_SearchResults.AddColumn("PAddr", 1); - m_SearchResults.AddColumn("Value", 2); - m_SearchResults.SetColumnWidth(0, 50); - m_SearchResults.SetColumnWidth(1, 75); - m_SearchResults.SetColumnWidth(2, 75); - m_SearchResults.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); - m_UnknownOptions.Attach(GetDlgItem(IDC_CMB_UNKNOWN)); - m_HaveResults = false; - FixUnknownOptions(true); - - SendMessage(GetDlgItem(IDC_RADIO_VALUE), BM_SETCHECK, BST_CHECKED, 0); - - BOOL bHandled; - OnClicked(0, IDC_BTN_RDRAM, NULL, bHandled); - OnClicked(0, IDC_RADIO_VALUE, NULL, bHandled); - WindowCreated(); - return TRUE; -} - -LRESULT CDebugMemorySearch::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/) -{ - switch (wID) - { - case IDCANCEL: - EndDialog(0); - break; - case IDC_BTN_RDRAM: - m_PAddrStart.SetValue(0, true, true); - m_SearchLen.SetValue(g_MMU->RdramSize(), true, true); - break; - case IDC_BTN_ROM: - m_PAddrStart.SetValue(0x10000000, true, true); - m_SearchLen.SetValue(g_Rom->GetRomSize(), true, true); - break; - case IDC_BTN_SPMEM: - m_PAddrStart.SetValue(0x04000000, true, true); - m_SearchLen.SetValue(0x2000, true, true); - break; - case IDC_SEARCH_HEX: - { - bool bChecked = (SendMessage(hWndCtl, BM_GETSTATE, 0, 0) & BST_CHECKED) != 0; - m_SearchValue.SetDisplayType(bChecked ? CEditNumber::DisplayHex : CEditNumber::DisplayDec); - } - break; - case ID_POPUP_SHOWINMEMORYVIEWER: - { - LONG iItem = m_SearchResults.GetNextItem(-1, LVNI_SELECTED); - if (iItem == -1) - { - break; - } - - int ItemId = m_SearchResults.GetItemData(iItem); - SearchResultItem & Result = m_SearchResult[ItemId]; - m_Debugger->Debug_ShowMemoryLocation(Result.PAddr, false); - } - break; - case IDC_RADIO_UNKNOWN: - EnableUnknownOptions(true); - EnableValueOptions(false); - EnableTextOptions(false); - EnableJalOptions(false); - break; - case IDC_RADIO_VALUE: - EnableUnknownOptions(false); - EnableValueOptions(true); - EnableTextOptions(false); - EnableJalOptions(false); - break; - case IDC_RADIO_TEXT: - EnableUnknownOptions(false); - EnableValueOptions(false); - EnableTextOptions(true); - EnableJalOptions(false); - break; - case IDC_RADIO_JAL: - EnableUnknownOptions(false); - EnableValueOptions(false); - EnableTextOptions(false); - EnableJalOptions(true); - break; - case IDC_BTN_SEARCH: - if (SendMessage(GetDlgItem(IDC_RADIO_UNKNOWN), BM_GETSTATE, 0, 0) == BST_CHECKED) - { - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SearchMemory); - SearchForUnknown(); - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SearchMemory); - break; - } - if (SendMessage(GetDlgItem(IDC_RADIO_VALUE), BM_GETSTATE, 0, 0) == BST_CHECKED) - { - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SearchMemory); - SearchForValue(); - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SearchMemory); - break; - } - if (SendMessage(GetDlgItem(IDC_RADIO_TEXT), BM_GETSTATE, 0, 0) == BST_CHECKED) - { - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SearchMemory); - SearchForText(); - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SearchMemory); - break; - } - case IDC_RESET_BUTTON: - Reset(); - break; - } - return FALSE; -} - -LRESULT CDebugMemorySearch::OnResultRClick(LPNMHDR /*lpnmh*/) -{ - LONG iItem = m_SearchResults.GetNextItem(-1, LVNI_SELECTED); - if (iItem == -1) - { - return true; - } - - //Load the menu - HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MEM_SEARCH)); - HMENU hPopupMenu = GetSubMenu(hMenu, 0); - - //Get the current Mouse location - POINT Mouse; - GetCursorPos(&Mouse); - - //Show the menu - TrackPopupMenu(hPopupMenu, 0, Mouse.x, Mouse.y, 0, m_hWnd, NULL); - DestroyMenu(hMenu); - return true; -} - -void CDebugMemorySearch::EnableValueOptions(bool Enable) -{ - if (Enable) - { - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), m_HaveResults ? "Search Results" : "Search"); - } - ::EnableWindow(GetDlgItem(IDC_SEARCH_VALUE), Enable); - ::EnableWindow(GetDlgItem(IDC_SEARCH_HEX), Enable); - ::EnableWindow(GetDlgItem(IDC_VALUE_ALIGN), m_HaveResults ? false : Enable); -} - -void CDebugMemorySearch::EnableTextOptions(bool Enable) -{ - if (Enable) - { - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), m_HaveResults ? "Search Results" : "Search"); - } - ::EnableWindow(GetDlgItem(IDC_SEARCH_TEXT), Enable); - ::EnableWindow(GetDlgItem(IDC_CASE_SENSITIVE), Enable); -} - -void CDebugMemorySearch::EnableJalOptions(bool Enable) -{ - if (Enable) - { - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), m_HaveResults ? "Search Results" : "Search"); - } - ::EnableWindow(GetDlgItem(IDC_JAL_ADDR), Enable); -} - -void CDebugMemorySearch::EnableUnknownOptions(bool Enable) -{ - if (m_UnknownOptions.GetCount() > 1) - { - ::EnableWindow(GetDlgItem(IDC_UNKNOWN_ALIGN), m_HaveResults ? false : Enable); - if (Enable) - { - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), m_HaveResults ? "Search Results" : "Search"); - } - } - else - { - ::EnableWindow(GetDlgItem(IDC_UNKNOWN_ALIGN), false); - if (Enable) - { - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Create"); - } - } - ::EnableWindow(GetDlgItem(IDC_CMB_UNKNOWN), Enable); -} - -void CDebugMemorySearch::SearchForValue(void) -{ - MemorySize Size = (MemorySize)m_ValueSize.GetItemData(m_ValueSize.GetCurSel()); - DWORD Value = m_SearchValue.GetValue(); - DWORD StartAddress = m_PAddrStart.GetValue(); - DWORD Len = m_SearchLen.GetValue(); - DWORD MaxSearch = m_MaxSearch.GetValue(); - - DWORD MoveSize = (Size == _32Bit ? 4 : (Size == _16Bit ? 2 : 1)); - - m_UnknownSize.SetCurSel(m_ValueSize.GetCurSel()); - - LPCTSTR DisplayStr = "0x%08X"; - if (Size == _16Bit) - { - DisplayStr = "0x%04X"; - } - else if (Size == _8Bit) - { - DisplayStr = "0x%04X"; - } - - if (!m_HaveResults) - { - m_HaveResults = true; - - FixUnknownOptions(false); - m_SearchResults.DeleteAllItems(); - DWORD ItemsAdded = 0; - - while (SearchForValue(Value, Size, StartAddress, Len)) - { - SearchResultItem Result; - Result.PAddr = StartAddress; - Result.Value = Value; - - char LocationStr[20]; - sprintf(LocationStr, "%d", ItemsAdded + 1); - int Index = m_SearchResults.AddItem(ItemsAdded, 0, LocationStr); - m_SearchResults.SetItemData(Index, m_SearchResult.size()); - m_SearchResult.push_back(Result); - sprintf(LocationStr, "0x%08X", StartAddress); - m_SearchResults.SetItemText(Index, 1, LocationStr); - sprintf(LocationStr, DisplayStr, Value); - m_SearchResults.SetItemText(Index, 2, LocationStr); - sprintf(LocationStr, DisplayStr, Value); - m_SearchResults.SetItemText(Index, 3, LocationStr); - StartAddress += MoveSize; - Len -= MoveSize; - ItemsAdded += 1; - if (ItemsAdded >= MaxSearch) - { - break; - } - } - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search Results"); - ::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_SHOW); - ::EnableWindow(GetDlgItem(IDC_VALUE_ALIGN), false); - } - else - { - int ItemCount = m_SearchResults.GetItemCount(); - for (int i = ItemCount - 1; i >= 0; i--) - { - int ItemId = m_SearchResults.GetItemData(i); - SearchResultItem & Result = m_SearchResult[ItemId]; - - uint32_t NewValue = 0; - bool valid = false; - - switch (Size) - { - case _8Bit: - { - BYTE mem = 0; - valid = g_MMU->LB_PAddr(Result.PAddr, mem); - NewValue = mem; - } - break; - case _16Bit: - { - WORD mem = 0; - valid = g_MMU->LH_PAddr(Result.PAddr, mem); - NewValue = mem; - } - break; - case _32Bit: - valid = g_MMU->LW_PAddr(Result.PAddr, NewValue); - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - if (Value == NewValue) - { - char LocationStr[20]; - sprintf(LocationStr, DisplayStr, NewValue); - m_SearchResults.SetItemText(i, 2, LocationStr); - sprintf(LocationStr, DisplayStr, Result.Value); - m_SearchResults.SetItemText(i, 3, LocationStr); - Result.Value = NewValue; - } - else - { - m_SearchResults.DeleteItem(i); - } - } - } - ::SetWindowText(GetDlgItem(IDC_BORDER_RESULTS), stdstr_f("Results (%d)", m_SearchResults.GetItemCount()).c_str()); -} - -void CDebugMemorySearch::SearchForUnknown() -{ - SearchMemChangeState Option = (SearchMemChangeState)m_UnknownOptions.GetItemData(m_UnknownOptions.GetCurSel()); - if (Option == SearchChangeState_Reset) - { - m_SearchResults.DeleteAllItems(); - SearchSetBaseForChanges(); - FixUnknownOptions(false); - ::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_SHOW); - ::EnableWindow(GetDlgItem(IDC_UNKNOWN_ALIGN), true); - return; - } - MemorySize Size = (MemorySize)m_UnknownSize.GetItemData(m_UnknownSize.GetCurSel()); - m_ValueSize.SetCurSel(m_UnknownSize.GetCurSel()); - LPCTSTR DisplayStr = "0x%08X"; - if (Size == _16Bit) - { - DisplayStr = "0x%04X"; - } - else if (Size == _8Bit) - { - DisplayStr = "0x%04X"; - } - if (!m_HaveResults) - { - m_HaveResults = true; - - ::EnableWindow(GetDlgItem(IDC_UNKNOWN_ALIGN), false); - DWORD StartAddress = m_PAddrStart.GetValue(); - DWORD Len = m_SearchLen.GetValue(); - DWORD MaxSearch = m_MaxSearch.GetValue(); - - DWORD MoveSize = (Size == _32Bit ? 4 : (Size == _16Bit ? 2 : 1)); - - for (int i = 2; i < 10; i++) - { - if (!m_SearchResults.DeleteColumn(i)) - { - break; - } - } - m_SearchResults.AddColumn("New Value", 2); - m_SearchResults.AddColumn("Old Value", 3); - m_SearchResults.SetColumnWidth(0, 50); - m_SearchResults.SetColumnWidth(1, 75); - m_SearchResults.SetColumnWidth(2, 75); - m_SearchResults.SetColumnWidth(3, 75); - - m_SearchResults.DeleteAllItems(); - DWORD ItemsAdded = 0, OldValue, NewValue; - - while (SearchForChanges(Option, Size, StartAddress, Len, OldValue, NewValue)) - { - SearchResultItem Result; - Result.PAddr = StartAddress; - Result.Value = NewValue; - - //if list size > max, then break - char LocationStr[20]; - sprintf(LocationStr, "%d", ItemsAdded + 1); - int Index = m_SearchResults.AddItem(ItemsAdded, 0, LocationStr); - m_SearchResults.SetItemData(Index, m_SearchResult.size()); - m_SearchResult.push_back(Result); - sprintf(LocationStr, "0x%08X", StartAddress); - m_SearchResults.SetItemText(Index, 1, LocationStr); - sprintf(LocationStr, DisplayStr, NewValue); - m_SearchResults.SetItemText(Index, 2, LocationStr); - sprintf(LocationStr, DisplayStr, OldValue); - m_SearchResults.SetItemText(Index, 3, LocationStr); - StartAddress += MoveSize; - Len -= MoveSize; - ItemsAdded += 1; - if (ItemsAdded >= MaxSearch) - { - break; - } - } - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search Results"); - ::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_SHOW); - ::EnableWindow(GetDlgItem(IDC_RADIO_TEXT), false); - ::EnableWindow(GetDlgItem(IDC_RADIO_JAL), false); - } - else - { - int ItemCount = m_SearchResults.GetItemCount(); - for (int i = ItemCount - 1; i >= 0; i--) - { - int ItemId = m_SearchResults.GetItemData(i); - SearchResultItem & Result = m_SearchResult[ItemId]; - - bool UpdateResult = false; - uint32_t NewValue = 0; - bool valid = false; - - switch (Size) - { - case _8Bit: - { - BYTE mem = 0; - valid = g_MMU->LB_PAddr(Result.PAddr, mem); - NewValue = mem; - } - break; - case _16Bit: - { - WORD mem = 0; - valid = g_MMU->LH_PAddr(Result.PAddr, mem); - NewValue = mem; - } - break; - case _32Bit: - valid = g_MMU->LW_PAddr(Result.PAddr, NewValue); - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - switch (Option) - { - case SearchChangeState_Changed: - if (Result.Value != NewValue) - { - UpdateResult = true; - } - break; - case SearchChangeState_Unchanged: - if (Result.Value == NewValue) - { - UpdateResult = true; - } - break; - case SearchChangeState_Greater: - if (NewValue > Result.Value) - { - UpdateResult = true; - } - break; - case SearchChangeState_Lessthan: - if (NewValue < Result.Value) - { - UpdateResult = true; - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - if (UpdateResult) - { - char LocationStr[20]; - sprintf(LocationStr, DisplayStr, NewValue); - m_SearchResults.SetItemText(i, 2, LocationStr); - sprintf(LocationStr, DisplayStr, Result.Value); - m_SearchResults.SetItemText(i, 3, LocationStr); - Result.Value = NewValue; - } - else - { - m_SearchResults.DeleteItem(i); - } - } - } - ::SetWindowText(GetDlgItem(IDC_BORDER_RESULTS), stdstr_f("Results (%d)", m_SearchResults.GetItemCount()).c_str()); -} - -void CDebugMemorySearch::SearchForText() -{ - g_Notify->BreakPoint(__FILE__, __LINE__); -} - -void CDebugMemorySearch::Reset(void) -{ - m_HaveResults = false; - SendMessage(GetDlgItem(IDC_RADIO_VALUE), BM_SETCHECK, BST_CHECKED, 0); - EnableUnknownOptions(false); - EnableValueOptions(true); - EnableTextOptions(false); - EnableJalOptions(false); - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search"); - ::SetWindowText(GetDlgItem(IDC_BORDER_RESULTS), "Results"); - ::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_HIDE); - ::EnableWindow(GetDlgItem(IDC_RADIO_UNKNOWN), true); - ::EnableWindow(GetDlgItem(IDC_RADIO_VALUE), true); - ::EnableWindow(GetDlgItem(IDC_RADIO_TEXT), false); - ::EnableWindow(GetDlgItem(IDC_RADIO_JAL), false); - for (int i = 1; i < 10; i++) - { - if (!m_SearchResults.DeleteColumn(i)) - { - break; - } - } - m_SearchResults.AddColumn("Value", 2); - m_SearchResults.DeleteAllItems(); - m_SearchResults.SetColumnWidth(0, 50); - m_SearchResults.SetColumnWidth(1, 75); - m_SearchResults.SetColumnWidth(2, 75); - m_SearchResults.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); - FixUnknownOptions(true); -} - -void CDebugMemorySearch::FixUnknownOptions(bool Reset) -{ - CComboBox & cb = m_UnknownOptions; - - if (!Reset && cb.GetCount() > 1) - { - return; - } - cb.ResetContent(); - if (Reset) - { - cb.SetItemData(cb.AddString("Create compare base"), SearchChangeState_Reset); - cb.SetCurSel(0); - return; - } - cb.SetItemData(cb.AddString("memory changed"), SearchChangeState_Changed); - cb.SetItemData(cb.AddString("memory unchanged"), SearchChangeState_Unchanged); - cb.SetItemData(cb.AddString("Value has increased"), SearchChangeState_Greater); - cb.SetItemData(cb.AddString("Value has descreased"), SearchChangeState_Lessthan); - cb.SetCurSel(1); - ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search"); -} - -bool CDebugMemorySearch::SearchSetBaseForChanges(void) -{ - if (m_MemoryState != NULL) - { - delete[] m_MemoryState; - } - m_MemoryStateSize = g_MMU->RdramSize(); - m_MemoryState = new BYTE[m_MemoryStateSize]; - memcpy(m_MemoryState, g_MMU->Rdram(), m_MemoryStateSize); - return true; -} - -bool CDebugMemorySearch::SearchForChanges(SearchMemChangeState SearchType, MemorySize Size, - DWORD &StartAddress, DWORD &Len, - DWORD &OldValue, DWORD &NewValue) -{ - if (g_MMU == NULL) - { - return false; - } - - if (SearchType == SearchChangeState_Reset) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (Size == _32Bit) { StartAddress = ((StartAddress + 3) & ~3); } - if (Size == _16Bit) { StartAddress = ((StartAddress + 1) & ~1); } - - //search memory - if (StartAddress < g_MMU->RdramSize()) - { - DWORD EndMemSearchAddr = StartAddress + Len; - if (EndMemSearchAddr > g_MMU->RdramSize()) - { - EndMemSearchAddr = g_MMU->RdramSize(); - } - - DWORD pos; - switch (Size) - { - case _32Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos += 4) - { - OldValue = *(DWORD *)(m_MemoryState + pos); - NewValue = *(DWORD *)(g_MMU->Rdram() + pos); - if ((SearchType == SearchChangeState_Changed && NewValue != OldValue) || - (SearchType == SearchChangeState_Unchanged && NewValue == OldValue) || - (SearchType == SearchChangeState_Greater && NewValue > OldValue) || - (SearchType == SearchChangeState_Lessthan && NewValue < OldValue)) - { - *(DWORD *)(m_MemoryState + pos) = NewValue; - Len -= pos - StartAddress; - StartAddress = pos; - return true; - } - } - break; - case _16Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos += 2) - { - OldValue = *(WORD *)(m_MemoryState + (pos ^ 2)); - NewValue = *(WORD *)(g_MMU->Rdram() + (pos ^ 2)); - if ((SearchType == SearchChangeState_Changed && NewValue != OldValue) || - (SearchType == SearchChangeState_Unchanged && NewValue == OldValue) || - (SearchType == SearchChangeState_Greater && NewValue > OldValue) || - (SearchType == SearchChangeState_Lessthan && NewValue < OldValue)) - { - Len -= pos - StartAddress; - StartAddress = pos; - return true; - } - } - break; - case _8Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos++) - { - OldValue = *(BYTE *)(m_MemoryState + (pos ^ 3)); - NewValue = *(BYTE *)(g_MMU->Rdram() + (pos ^ 3)); - if ((SearchType == SearchChangeState_Changed && NewValue != OldValue) || - (SearchType == SearchChangeState_Unchanged && NewValue == OldValue) || - (SearchType == SearchChangeState_Greater && NewValue > OldValue) || - (SearchType == SearchChangeState_Lessthan && NewValue < OldValue)) - { - Len -= pos - StartAddress; - StartAddress = pos; - return true; - } - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - return false; -} - -bool CDebugMemorySearch::SearchForValue(DWORD Value, MemorySize Size, DWORD &StartAddress, DWORD &Len) -{ - if (g_MMU == NULL || g_Rom == NULL) - { - return false; - } - - if (Size == _32Bit) - { - StartAddress = ((StartAddress + 3) & ~3); - } - if (Size == _16Bit) - { - StartAddress = ((StartAddress + 1) & ~1); - } - - //search memory - if (StartAddress < g_MMU->RdramSize()) - { - DWORD EndMemSearchAddr = StartAddress + Len; - if (EndMemSearchAddr > g_MMU->RdramSize()) - { - EndMemSearchAddr = g_MMU->RdramSize(); - } - - DWORD pos; - BYTE * RDRAM = g_MMU->Rdram(); - switch (Size) - { - case _32Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos += 4) - { - if (*(DWORD *)(RDRAM + pos) == Value) - { - Len -= pos - StartAddress; - StartAddress = pos; - return true; - } - } - break; - case _16Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos += 2) - { - if (*(WORD *)(RDRAM + (pos ^ 2)) == (WORD)Value) - { - Len -= pos - StartAddress; - StartAddress = pos; - return true; - } - } - break; - case _8Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos++) - { - if (*(BYTE *)(RDRAM + (pos ^ 3)) == (BYTE)Value) - { - Len -= pos - StartAddress; - StartAddress = pos; - return true; - } - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - if (StartAddress >= 0x10000000) - { - DWORD EndMemSearchAddr = StartAddress + Len - 0x10000000; - if (EndMemSearchAddr > g_Rom->GetRomSize()) - { - EndMemSearchAddr = g_Rom->GetRomSize(); - } - StartAddress -= 0x10000000; - - DWORD pos; - BYTE * ROM = g_Rom->GetRomAddress(); - switch (Size) - { - case _32Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos += 4) - { - if (*(DWORD *)(ROM + pos) == Value) - { - Len -= pos - StartAddress; - StartAddress = pos + 0x10000000; - return true; - } - } - break; - case _16Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos += 2) - { - if (*(WORD *)(ROM + (pos ^ 2)) == (WORD)Value) - { - Len -= pos - StartAddress; - StartAddress = pos + 0x10000000; - return true; - } - } - break; - case _8Bit: - for (pos = StartAddress; pos < EndMemSearchAddr; pos++) - { - if (*(BYTE *)(ROM + (pos ^ 3)) == (BYTE)Value) - { - Len -= pos - StartAddress; - StartAddress = pos + 0x10000000; - return true; - } - } - break; - default: - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - return false; -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "DebuggerUI.h" + +CDebugMemorySearch::CDebugMemorySearch(CDebuggerUI * debugger) : + CDebugDialog(debugger), + m_MemoryState(NULL), + m_MemoryStateSize(0) +{ +} + +CDebugMemorySearch::~CDebugMemorySearch() +{ + if (m_MemoryState) + { + delete m_MemoryState; + } +} + +void CDebugMemorySearch::AddAlignmentOptions(CComboBox & ctrl) +{ + int Index = ctrl.AddString("32 bits (aligned)"); + ctrl.SetItemData(Index, _32Bit); + Index = ctrl.AddString("16bits (aligned)"); + ctrl.SetItemData(Index, _16Bit); + Index = ctrl.AddString("8bits"); + ctrl.SetCurSel(Index); + ctrl.SetItemData(Index, _8Bit); +} + +LRESULT CDebugMemorySearch::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + m_PAddrStart.Attach(GetDlgItem(IDC_PADDR_START)); + m_PAddrStart.SetDisplayType(CEditNumber::DisplayHex); + m_SearchLen.Attach(GetDlgItem(IDC_ADDR_END)); + m_SearchLen.SetDisplayType(CEditNumber::DisplayHex); + m_SearchValue.Attach(GetDlgItem(IDC_SEARCH_VALUE)); + m_SearchValue.SetDisplayType(CEditNumber::DisplayDec); + m_SearchValue.SetValue(0); + m_MaxSearch.Attach(GetDlgItem(IDC_MAX_SEARCH)); + m_MaxSearch.SetDisplayType(CEditNumber::DisplayDec); + m_MaxSearch.SetValue(50000); + m_UnknownSize.Attach(GetDlgItem(IDC_UNKNOWN_ALIGN)); + AddAlignmentOptions(m_UnknownSize); + m_ValueSize.Attach(GetDlgItem(IDC_VALUE_ALIGN)); + AddAlignmentOptions(m_ValueSize); + m_SearchResults.Attach(GetDlgItem(IDC_LST_RESULTS)); + m_SearchResults.AddColumn("ID", 0); + m_SearchResults.AddColumn("PAddr", 1); + m_SearchResults.AddColumn("Value", 2); + m_SearchResults.SetColumnWidth(0, 50); + m_SearchResults.SetColumnWidth(1, 75); + m_SearchResults.SetColumnWidth(2, 75); + m_SearchResults.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); + m_UnknownOptions.Attach(GetDlgItem(IDC_CMB_UNKNOWN)); + m_HaveResults = false; + FixUnknownOptions(true); + + SendMessage(GetDlgItem(IDC_RADIO_VALUE), BM_SETCHECK, BST_CHECKED, 0); + + BOOL bHandled; + OnClicked(0, IDC_BTN_RDRAM, NULL, bHandled); + OnClicked(0, IDC_RADIO_VALUE, NULL, bHandled); + WindowCreated(); + return TRUE; +} + +LRESULT CDebugMemorySearch::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/) +{ + switch (wID) + { + case IDCANCEL: + EndDialog(0); + break; + case IDC_BTN_RDRAM: + m_PAddrStart.SetValue(0, true, true); + m_SearchLen.SetValue(g_MMU->RdramSize(), true, true); + break; + case IDC_BTN_ROM: + m_PAddrStart.SetValue(0x10000000, true, true); + m_SearchLen.SetValue(g_Rom->GetRomSize(), true, true); + break; + case IDC_BTN_SPMEM: + m_PAddrStart.SetValue(0x04000000, true, true); + m_SearchLen.SetValue(0x2000, true, true); + break; + case IDC_SEARCH_HEX: + { + bool bChecked = (SendMessage(hWndCtl, BM_GETSTATE, 0, 0) & BST_CHECKED) != 0; + m_SearchValue.SetDisplayType(bChecked ? CEditNumber::DisplayHex : CEditNumber::DisplayDec); + } + break; + case ID_POPUP_SHOWINMEMORYVIEWER: + { + LONG iItem = m_SearchResults.GetNextItem(-1, LVNI_SELECTED); + if (iItem == -1) + { + break; + } + + int ItemId = m_SearchResults.GetItemData(iItem); + SearchResultItem & Result = m_SearchResult[ItemId]; + m_Debugger->Debug_ShowMemoryLocation(Result.PAddr, false); + } + break; + case IDC_RADIO_UNKNOWN: + EnableUnknownOptions(true); + EnableValueOptions(false); + EnableTextOptions(false); + EnableJalOptions(false); + break; + case IDC_RADIO_VALUE: + EnableUnknownOptions(false); + EnableValueOptions(true); + EnableTextOptions(false); + EnableJalOptions(false); + break; + case IDC_RADIO_TEXT: + EnableUnknownOptions(false); + EnableValueOptions(false); + EnableTextOptions(true); + EnableJalOptions(false); + break; + case IDC_RADIO_JAL: + EnableUnknownOptions(false); + EnableValueOptions(false); + EnableTextOptions(false); + EnableJalOptions(true); + break; + case IDC_BTN_SEARCH: + if (SendMessage(GetDlgItem(IDC_RADIO_UNKNOWN), BM_GETSTATE, 0, 0) == BST_CHECKED) + { + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SearchMemory); + SearchForUnknown(); + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SearchMemory); + break; + } + if (SendMessage(GetDlgItem(IDC_RADIO_VALUE), BM_GETSTATE, 0, 0) == BST_CHECKED) + { + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SearchMemory); + SearchForValue(); + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SearchMemory); + break; + } + if (SendMessage(GetDlgItem(IDC_RADIO_TEXT), BM_GETSTATE, 0, 0) == BST_CHECKED) + { + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SearchMemory); + SearchForText(); + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SearchMemory); + break; + } + case IDC_RESET_BUTTON: + Reset(); + break; + } + return FALSE; +} + +LRESULT CDebugMemorySearch::OnResultRClick(LPNMHDR /*lpnmh*/) +{ + LONG iItem = m_SearchResults.GetNextItem(-1, LVNI_SELECTED); + if (iItem == -1) + { + return true; + } + + //Load the menu + HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MEM_SEARCH)); + HMENU hPopupMenu = GetSubMenu(hMenu, 0); + + //Get the current Mouse location + POINT Mouse; + GetCursorPos(&Mouse); + + //Show the menu + TrackPopupMenu(hPopupMenu, 0, Mouse.x, Mouse.y, 0, m_hWnd, NULL); + DestroyMenu(hMenu); + return true; +} + +void CDebugMemorySearch::EnableValueOptions(bool Enable) +{ + if (Enable) + { + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), m_HaveResults ? "Search Results" : "Search"); + } + ::EnableWindow(GetDlgItem(IDC_SEARCH_VALUE), Enable); + ::EnableWindow(GetDlgItem(IDC_SEARCH_HEX), Enable); + ::EnableWindow(GetDlgItem(IDC_VALUE_ALIGN), m_HaveResults ? false : Enable); +} + +void CDebugMemorySearch::EnableTextOptions(bool Enable) +{ + if (Enable) + { + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), m_HaveResults ? "Search Results" : "Search"); + } + ::EnableWindow(GetDlgItem(IDC_SEARCH_TEXT), Enable); + ::EnableWindow(GetDlgItem(IDC_CASE_SENSITIVE), Enable); +} + +void CDebugMemorySearch::EnableJalOptions(bool Enable) +{ + if (Enable) + { + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), m_HaveResults ? "Search Results" : "Search"); + } + ::EnableWindow(GetDlgItem(IDC_JAL_ADDR), Enable); +} + +void CDebugMemorySearch::EnableUnknownOptions(bool Enable) +{ + if (m_UnknownOptions.GetCount() > 1) + { + ::EnableWindow(GetDlgItem(IDC_UNKNOWN_ALIGN), m_HaveResults ? false : Enable); + if (Enable) + { + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), m_HaveResults ? "Search Results" : "Search"); + } + } + else + { + ::EnableWindow(GetDlgItem(IDC_UNKNOWN_ALIGN), false); + if (Enable) + { + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Create"); + } + } + ::EnableWindow(GetDlgItem(IDC_CMB_UNKNOWN), Enable); +} + +void CDebugMemorySearch::SearchForValue(void) +{ + MemorySize Size = (MemorySize)m_ValueSize.GetItemData(m_ValueSize.GetCurSel()); + DWORD Value = m_SearchValue.GetValue(); + DWORD StartAddress = m_PAddrStart.GetValue(); + DWORD Len = m_SearchLen.GetValue(); + DWORD MaxSearch = m_MaxSearch.GetValue(); + + DWORD MoveSize = (Size == _32Bit ? 4 : (Size == _16Bit ? 2 : 1)); + + m_UnknownSize.SetCurSel(m_ValueSize.GetCurSel()); + + LPCTSTR DisplayStr = "0x%08X"; + if (Size == _16Bit) + { + DisplayStr = "0x%04X"; + } + else if (Size == _8Bit) + { + DisplayStr = "0x%04X"; + } + + if (!m_HaveResults) + { + m_HaveResults = true; + + FixUnknownOptions(false); + m_SearchResults.DeleteAllItems(); + DWORD ItemsAdded = 0; + + while (SearchForValue(Value, Size, StartAddress, Len)) + { + SearchResultItem Result; + Result.PAddr = StartAddress; + Result.Value = Value; + + char LocationStr[20]; + sprintf(LocationStr, "%d", ItemsAdded + 1); + int Index = m_SearchResults.AddItem(ItemsAdded, 0, LocationStr); + m_SearchResults.SetItemData(Index, m_SearchResult.size()); + m_SearchResult.push_back(Result); + sprintf(LocationStr, "0x%08X", StartAddress); + m_SearchResults.SetItemText(Index, 1, LocationStr); + sprintf(LocationStr, DisplayStr, Value); + m_SearchResults.SetItemText(Index, 2, LocationStr); + sprintf(LocationStr, DisplayStr, Value); + m_SearchResults.SetItemText(Index, 3, LocationStr); + StartAddress += MoveSize; + Len -= MoveSize; + ItemsAdded += 1; + if (ItemsAdded >= MaxSearch) + { + break; + } + } + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search Results"); + ::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_SHOW); + ::EnableWindow(GetDlgItem(IDC_VALUE_ALIGN), false); + } + else + { + int ItemCount = m_SearchResults.GetItemCount(); + for (int i = ItemCount - 1; i >= 0; i--) + { + int ItemId = m_SearchResults.GetItemData(i); + SearchResultItem & Result = m_SearchResult[ItemId]; + + uint32_t NewValue = 0; + bool valid = false; + + switch (Size) + { + case _8Bit: + { + BYTE mem = 0; + valid = g_MMU->LB_PAddr(Result.PAddr, mem); + NewValue = mem; + } + break; + case _16Bit: + { + WORD mem = 0; + valid = g_MMU->LH_PAddr(Result.PAddr, mem); + NewValue = mem; + } + break; + case _32Bit: + valid = g_MMU->LW_PAddr(Result.PAddr, NewValue); + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + if (Value == NewValue) + { + char LocationStr[20]; + sprintf(LocationStr, DisplayStr, NewValue); + m_SearchResults.SetItemText(i, 2, LocationStr); + sprintf(LocationStr, DisplayStr, Result.Value); + m_SearchResults.SetItemText(i, 3, LocationStr); + Result.Value = NewValue; + } + else + { + m_SearchResults.DeleteItem(i); + } + } + } + ::SetWindowText(GetDlgItem(IDC_BORDER_RESULTS), stdstr_f("Results (%d)", m_SearchResults.GetItemCount()).c_str()); +} + +void CDebugMemorySearch::SearchForUnknown() +{ + SearchMemChangeState Option = (SearchMemChangeState)m_UnknownOptions.GetItemData(m_UnknownOptions.GetCurSel()); + if (Option == SearchChangeState_Reset) + { + m_SearchResults.DeleteAllItems(); + SearchSetBaseForChanges(); + FixUnknownOptions(false); + ::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_SHOW); + ::EnableWindow(GetDlgItem(IDC_UNKNOWN_ALIGN), true); + return; + } + MemorySize Size = (MemorySize)m_UnknownSize.GetItemData(m_UnknownSize.GetCurSel()); + m_ValueSize.SetCurSel(m_UnknownSize.GetCurSel()); + LPCTSTR DisplayStr = "0x%08X"; + if (Size == _16Bit) + { + DisplayStr = "0x%04X"; + } + else if (Size == _8Bit) + { + DisplayStr = "0x%04X"; + } + if (!m_HaveResults) + { + m_HaveResults = true; + + ::EnableWindow(GetDlgItem(IDC_UNKNOWN_ALIGN), false); + DWORD StartAddress = m_PAddrStart.GetValue(); + DWORD Len = m_SearchLen.GetValue(); + DWORD MaxSearch = m_MaxSearch.GetValue(); + + DWORD MoveSize = (Size == _32Bit ? 4 : (Size == _16Bit ? 2 : 1)); + + for (int i = 2; i < 10; i++) + { + if (!m_SearchResults.DeleteColumn(i)) + { + break; + } + } + m_SearchResults.AddColumn("New Value", 2); + m_SearchResults.AddColumn("Old Value", 3); + m_SearchResults.SetColumnWidth(0, 50); + m_SearchResults.SetColumnWidth(1, 75); + m_SearchResults.SetColumnWidth(2, 75); + m_SearchResults.SetColumnWidth(3, 75); + + m_SearchResults.DeleteAllItems(); + DWORD ItemsAdded = 0, OldValue, NewValue; + + while (SearchForChanges(Option, Size, StartAddress, Len, OldValue, NewValue)) + { + SearchResultItem Result; + Result.PAddr = StartAddress; + Result.Value = NewValue; + + //if list size > max, then break + char LocationStr[20]; + sprintf(LocationStr, "%d", ItemsAdded + 1); + int Index = m_SearchResults.AddItem(ItemsAdded, 0, LocationStr); + m_SearchResults.SetItemData(Index, m_SearchResult.size()); + m_SearchResult.push_back(Result); + sprintf(LocationStr, "0x%08X", StartAddress); + m_SearchResults.SetItemText(Index, 1, LocationStr); + sprintf(LocationStr, DisplayStr, NewValue); + m_SearchResults.SetItemText(Index, 2, LocationStr); + sprintf(LocationStr, DisplayStr, OldValue); + m_SearchResults.SetItemText(Index, 3, LocationStr); + StartAddress += MoveSize; + Len -= MoveSize; + ItemsAdded += 1; + if (ItemsAdded >= MaxSearch) + { + break; + } + } + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search Results"); + ::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_SHOW); + ::EnableWindow(GetDlgItem(IDC_RADIO_TEXT), false); + ::EnableWindow(GetDlgItem(IDC_RADIO_JAL), false); + } + else + { + int ItemCount = m_SearchResults.GetItemCount(); + for (int i = ItemCount - 1; i >= 0; i--) + { + int ItemId = m_SearchResults.GetItemData(i); + SearchResultItem & Result = m_SearchResult[ItemId]; + + bool UpdateResult = false; + uint32_t NewValue = 0; + bool valid = false; + + switch (Size) + { + case _8Bit: + { + BYTE mem = 0; + valid = g_MMU->LB_PAddr(Result.PAddr, mem); + NewValue = mem; + } + break; + case _16Bit: + { + WORD mem = 0; + valid = g_MMU->LH_PAddr(Result.PAddr, mem); + NewValue = mem; + } + break; + case _32Bit: + valid = g_MMU->LW_PAddr(Result.PAddr, NewValue); + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + switch (Option) + { + case SearchChangeState_Changed: + if (Result.Value != NewValue) + { + UpdateResult = true; + } + break; + case SearchChangeState_Unchanged: + if (Result.Value == NewValue) + { + UpdateResult = true; + } + break; + case SearchChangeState_Greater: + if (NewValue > Result.Value) + { + UpdateResult = true; + } + break; + case SearchChangeState_Lessthan: + if (NewValue < Result.Value) + { + UpdateResult = true; + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + if (UpdateResult) + { + char LocationStr[20]; + sprintf(LocationStr, DisplayStr, NewValue); + m_SearchResults.SetItemText(i, 2, LocationStr); + sprintf(LocationStr, DisplayStr, Result.Value); + m_SearchResults.SetItemText(i, 3, LocationStr); + Result.Value = NewValue; + } + else + { + m_SearchResults.DeleteItem(i); + } + } + } + ::SetWindowText(GetDlgItem(IDC_BORDER_RESULTS), stdstr_f("Results (%d)", m_SearchResults.GetItemCount()).c_str()); +} + +void CDebugMemorySearch::SearchForText() +{ + g_Notify->BreakPoint(__FILE__, __LINE__); +} + +void CDebugMemorySearch::Reset(void) +{ + m_HaveResults = false; + SendMessage(GetDlgItem(IDC_RADIO_VALUE), BM_SETCHECK, BST_CHECKED, 0); + EnableUnknownOptions(false); + EnableValueOptions(true); + EnableTextOptions(false); + EnableJalOptions(false); + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search"); + ::SetWindowText(GetDlgItem(IDC_BORDER_RESULTS), "Results"); + ::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_HIDE); + ::EnableWindow(GetDlgItem(IDC_RADIO_UNKNOWN), true); + ::EnableWindow(GetDlgItem(IDC_RADIO_VALUE), true); + ::EnableWindow(GetDlgItem(IDC_RADIO_TEXT), false); + ::EnableWindow(GetDlgItem(IDC_RADIO_JAL), false); + for (int i = 1; i < 10; i++) + { + if (!m_SearchResults.DeleteColumn(i)) + { + break; + } + } + m_SearchResults.AddColumn("Value", 2); + m_SearchResults.DeleteAllItems(); + m_SearchResults.SetColumnWidth(0, 50); + m_SearchResults.SetColumnWidth(1, 75); + m_SearchResults.SetColumnWidth(2, 75); + m_SearchResults.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); + FixUnknownOptions(true); +} + +void CDebugMemorySearch::FixUnknownOptions(bool Reset) +{ + CComboBox & cb = m_UnknownOptions; + + if (!Reset && cb.GetCount() > 1) + { + return; + } + cb.ResetContent(); + if (Reset) + { + cb.SetItemData(cb.AddString("Create compare base"), SearchChangeState_Reset); + cb.SetCurSel(0); + return; + } + cb.SetItemData(cb.AddString("memory changed"), SearchChangeState_Changed); + cb.SetItemData(cb.AddString("memory unchanged"), SearchChangeState_Unchanged); + cb.SetItemData(cb.AddString("Value has increased"), SearchChangeState_Greater); + cb.SetItemData(cb.AddString("Value has descreased"), SearchChangeState_Lessthan); + cb.SetCurSel(1); + ::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search"); +} + +bool CDebugMemorySearch::SearchSetBaseForChanges(void) +{ + if (m_MemoryState != NULL) + { + delete[] m_MemoryState; + } + m_MemoryStateSize = g_MMU->RdramSize(); + m_MemoryState = new BYTE[m_MemoryStateSize]; + memcpy(m_MemoryState, g_MMU->Rdram(), m_MemoryStateSize); + return true; +} + +bool CDebugMemorySearch::SearchForChanges(SearchMemChangeState SearchType, MemorySize Size, + DWORD &StartAddress, DWORD &Len, + DWORD &OldValue, DWORD &NewValue) +{ + if (g_MMU == NULL) + { + return false; + } + + if (SearchType == SearchChangeState_Reset) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (Size == _32Bit) { StartAddress = ((StartAddress + 3) & ~3); } + if (Size == _16Bit) { StartAddress = ((StartAddress + 1) & ~1); } + + //search memory + if (StartAddress < g_MMU->RdramSize()) + { + DWORD EndMemSearchAddr = StartAddress + Len; + if (EndMemSearchAddr > g_MMU->RdramSize()) + { + EndMemSearchAddr = g_MMU->RdramSize(); + } + + DWORD pos; + switch (Size) + { + case _32Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos += 4) + { + OldValue = *(DWORD *)(m_MemoryState + pos); + NewValue = *(DWORD *)(g_MMU->Rdram() + pos); + if ((SearchType == SearchChangeState_Changed && NewValue != OldValue) || + (SearchType == SearchChangeState_Unchanged && NewValue == OldValue) || + (SearchType == SearchChangeState_Greater && NewValue > OldValue) || + (SearchType == SearchChangeState_Lessthan && NewValue < OldValue)) + { + *(DWORD *)(m_MemoryState + pos) = NewValue; + Len -= pos - StartAddress; + StartAddress = pos; + return true; + } + } + break; + case _16Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos += 2) + { + OldValue = *(WORD *)(m_MemoryState + (pos ^ 2)); + NewValue = *(WORD *)(g_MMU->Rdram() + (pos ^ 2)); + if ((SearchType == SearchChangeState_Changed && NewValue != OldValue) || + (SearchType == SearchChangeState_Unchanged && NewValue == OldValue) || + (SearchType == SearchChangeState_Greater && NewValue > OldValue) || + (SearchType == SearchChangeState_Lessthan && NewValue < OldValue)) + { + Len -= pos - StartAddress; + StartAddress = pos; + return true; + } + } + break; + case _8Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos++) + { + OldValue = *(BYTE *)(m_MemoryState + (pos ^ 3)); + NewValue = *(BYTE *)(g_MMU->Rdram() + (pos ^ 3)); + if ((SearchType == SearchChangeState_Changed && NewValue != OldValue) || + (SearchType == SearchChangeState_Unchanged && NewValue == OldValue) || + (SearchType == SearchChangeState_Greater && NewValue > OldValue) || + (SearchType == SearchChangeState_Lessthan && NewValue < OldValue)) + { + Len -= pos - StartAddress; + StartAddress = pos; + return true; + } + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + return false; +} + +bool CDebugMemorySearch::SearchForValue(DWORD Value, MemorySize Size, DWORD &StartAddress, DWORD &Len) +{ + if (g_MMU == NULL || g_Rom == NULL) + { + return false; + } + + if (Size == _32Bit) + { + StartAddress = ((StartAddress + 3) & ~3); + } + if (Size == _16Bit) + { + StartAddress = ((StartAddress + 1) & ~1); + } + + //search memory + if (StartAddress < g_MMU->RdramSize()) + { + DWORD EndMemSearchAddr = StartAddress + Len; + if (EndMemSearchAddr > g_MMU->RdramSize()) + { + EndMemSearchAddr = g_MMU->RdramSize(); + } + + DWORD pos; + BYTE * RDRAM = g_MMU->Rdram(); + switch (Size) + { + case _32Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos += 4) + { + if (*(DWORD *)(RDRAM + pos) == Value) + { + Len -= pos - StartAddress; + StartAddress = pos; + return true; + } + } + break; + case _16Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos += 2) + { + if (*(WORD *)(RDRAM + (pos ^ 2)) == (WORD)Value) + { + Len -= pos - StartAddress; + StartAddress = pos; + return true; + } + } + break; + case _8Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos++) + { + if (*(BYTE *)(RDRAM + (pos ^ 3)) == (BYTE)Value) + { + Len -= pos - StartAddress; + StartAddress = pos; + return true; + } + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + if (StartAddress >= 0x10000000) + { + DWORD EndMemSearchAddr = StartAddress + Len - 0x10000000; + if (EndMemSearchAddr > g_Rom->GetRomSize()) + { + EndMemSearchAddr = g_Rom->GetRomSize(); + } + StartAddress -= 0x10000000; + + DWORD pos; + BYTE * ROM = g_Rom->GetRomAddress(); + switch (Size) + { + case _32Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos += 4) + { + if (*(DWORD *)(ROM + pos) == Value) + { + Len -= pos - StartAddress; + StartAddress = pos + 0x10000000; + return true; + } + } + break; + case _16Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos += 2) + { + if (*(WORD *)(ROM + (pos ^ 2)) == (WORD)Value) + { + Len -= pos - StartAddress; + StartAddress = pos + 0x10000000; + return true; + } + } + break; + case _8Bit: + for (pos = StartAddress; pos < EndMemSearchAddr; pos++) + { + if (*(BYTE *)(ROM + (pos ^ 3)) == (BYTE)Value) + { + Len -= pos - StartAddress; + StartAddress = pos + 0x10000000; + return true; + } + } + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + return false; +} diff --git a/Source/Project64/N64System/Debugger/Debugger-MemorySearch.h b/Source/Project64/N64System/Debugger/Debugger-MemorySearch.h index 9e7127a04..017cccf08 100644 --- a/Source/Project64/N64System/Debugger/Debugger-MemorySearch.h +++ b/Source/Project64/N64System/Debugger/Debugger-MemorySearch.h @@ -1,86 +1,86 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CDebugMemorySearch : - public CDebugDialog < CDebugMemorySearch > -{ -public: - enum { IDD = IDD_Debugger_Search }; - - CDebugMemorySearch(CDebuggerUI * debugger); - virtual ~CDebugMemorySearch(void); - -private: - CDebugMemorySearch(void); // Disable default constructor - CDebugMemorySearch(const CDebugMemorySearch&); // Disable copy constructor - CDebugMemorySearch& operator=(const CDebugMemorySearch&); // Disable assignment - - enum MemorySize - { - _8Bit, - _16Bit, - _32Bit, - }; - - //Searching for value - enum SearchMemChangeState - { - SearchChangeState_Reset, - SearchChangeState_Changed, - SearchChangeState_Unchanged, - SearchChangeState_Greater, - SearchChangeState_Lessthan, - }; - - struct SearchResultItem - { - DWORD PAddr; - DWORD Value; - }; - - typedef std::vector SearchResult; - - BEGIN_MSG_MAP_EX(CDebugMemorySearch) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) - NOTIFY_HANDLER_EX(IDC_LST_RESULTS, NM_RCLICK, OnResultRClick) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); - LRESULT OnResultRClick(LPNMHDR lpnmh); - - void EnableUnknownOptions(bool Enable); - void EnableValueOptions(bool Enable); - void EnableTextOptions(bool Enable); - void EnableJalOptions(bool Enable); - void AddAlignmentOptions(CComboBox & ctrl); - - CEditNumber m_PAddrStart, m_SearchLen, m_SearchValue, m_MaxSearch; - CComboBox m_UnknownOptions, m_ValueSize, m_UnknownSize; - CListViewCtrl m_SearchResults; - SearchResult m_SearchResult; - bool m_HaveResults; - - //Searching memory - BYTE * m_MemoryState; - DWORD m_MemoryStateSize; - - void FixUnknownOptions(bool Reset); - void SearchForUnknown(void); - void SearchForValue(void); - void SearchForText(void); - void Reset(void); - bool SearchSetBaseForChanges(void); - bool SearchForChanges(SearchMemChangeState SearchType, MemorySize Size, DWORD &StartAddress, DWORD &Len, DWORD &OldValue, DWORD &NewValue); - bool SearchForValue(DWORD Value, MemorySize Size, DWORD &StartAddress, DWORD &Len); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CDebugMemorySearch : + public CDebugDialog < CDebugMemorySearch > +{ +public: + enum { IDD = IDD_Debugger_Search }; + + CDebugMemorySearch(CDebuggerUI * debugger); + virtual ~CDebugMemorySearch(void); + +private: + CDebugMemorySearch(void); // Disable default constructor + CDebugMemorySearch(const CDebugMemorySearch&); // Disable copy constructor + CDebugMemorySearch& operator=(const CDebugMemorySearch&); // Disable assignment + + enum MemorySize + { + _8Bit, + _16Bit, + _32Bit, + }; + + //Searching for value + enum SearchMemChangeState + { + SearchChangeState_Reset, + SearchChangeState_Changed, + SearchChangeState_Unchanged, + SearchChangeState_Greater, + SearchChangeState_Lessthan, + }; + + struct SearchResultItem + { + DWORD PAddr; + DWORD Value; + }; + + typedef std::vector SearchResult; + + BEGIN_MSG_MAP_EX(CDebugMemorySearch) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) + NOTIFY_HANDLER_EX(IDC_LST_RESULTS, NM_RCLICK, OnResultRClick) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); + LRESULT OnResultRClick(LPNMHDR lpnmh); + + void EnableUnknownOptions(bool Enable); + void EnableValueOptions(bool Enable); + void EnableTextOptions(bool Enable); + void EnableJalOptions(bool Enable); + void AddAlignmentOptions(CComboBox & ctrl); + + CEditNumber m_PAddrStart, m_SearchLen, m_SearchValue, m_MaxSearch; + CComboBox m_UnknownOptions, m_ValueSize, m_UnknownSize; + CListViewCtrl m_SearchResults; + SearchResult m_SearchResult; + bool m_HaveResults; + + //Searching memory + BYTE * m_MemoryState; + DWORD m_MemoryStateSize; + + void FixUnknownOptions(bool Reset); + void SearchForUnknown(void); + void SearchForValue(void); + void SearchForText(void); + void Reset(void); + bool SearchSetBaseForChanges(void); + bool SearchForChanges(SearchMemChangeState SearchType, MemorySize Size, DWORD &StartAddress, DWORD &Len, DWORD &OldValue, DWORD &NewValue); + bool SearchForValue(DWORD Value, MemorySize Size, DWORD &StartAddress, DWORD &Len); +}; diff --git a/Source/Project64/N64System/Debugger/Debugger-TLB.cpp b/Source/Project64/N64System/Debugger/Debugger-TLB.cpp index 518a44c2d..4f12cc801 100644 --- a/Source/Project64/N64System/Debugger/Debugger-TLB.cpp +++ b/Source/Project64/N64System/Debugger/Debugger-TLB.cpp @@ -1,288 +1,288 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "DebuggerUI.h" - -CDebugTlb::CDebugTlb(CDebuggerUI * debugger) : - CDebugDialog(debugger) -{ -} - -CDebugTlb::~CDebugTlb() -{ -} - -LRESULT CDebugTlb::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ - LV_COLUMN col; - - col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - col.fmt = LVCFMT_LEFT; - - col.pszText = "Index"; - col.cx = 40; - col.iSubItem = 0; - ListView_InsertColumn(GetDlgItem(IDC_LIST), 0, &col); - - col.pszText = "Page Mask"; - col.cx = 90; - col.iSubItem = 1; - ListView_InsertColumn(GetDlgItem(IDC_LIST), 1, &col); - - col.pszText = "Entry Hi"; - col.cx = 90; - col.iSubItem = 2; - ListView_InsertColumn(GetDlgItem(IDC_LIST), 2, &col); - - col.pszText = "Entry Lo0"; - col.cx = 90; - col.iSubItem = 3; - ListView_InsertColumn(GetDlgItem(IDC_LIST), 3, &col); - - col.pszText = "Entry Lo1"; - col.cx = 90; - col.iSubItem = 4; - ListView_InsertColumn(GetDlgItem(IDC_LIST), 4, &col); - - col.pszText = "Index"; - col.cx = 40; - col.iSubItem = 0; - ListView_InsertColumn(GetDlgItem(IDC_LIST2), 0, &col); - - col.pszText = "Valid"; - col.cx = 40; - col.iSubItem = 1; - ListView_InsertColumn(GetDlgItem(IDC_LIST2), 1, &col); - - col.pszText = "Dirty"; - col.cx = 40; - col.iSubItem = 2; - ListView_InsertColumn(GetDlgItem(IDC_LIST2), 2, &col); - - col.pszText = "Rule"; - col.cx = 270; - col.iSubItem = 3; - ListView_InsertColumn(GetDlgItem(IDC_LIST2), 3, &col); - - RefreshTLBWindow(); - SendMessage(GetDlgItem(IDC_TLB_ENTRIES), BM_SETCHECK, BST_CHECKED, 0); - - // if (Settings().Load(TLBWindowLeft) <= 0) - // { - // SetWindowPos(NULL,Settings().Load(TLBWindowLeft),Settings().Load(TLBWindowTop),0,0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); - // } - WindowCreated(); - return TRUE; -} - -LRESULT CDebugTlb::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/) -{ - switch (wID) - { - case IDCANCEL: - EndDialog(0); - break; - case IDC_TLB_ENTRIES: - ::ShowWindow(GetDlgItem(IDC_LIST), SW_SHOW); - ::ShowWindow(GetDlgItem(IDC_LIST2), SW_HIDE); - break; - case IDC_TLB_RULES: - ::ShowWindow(GetDlgItem(IDC_LIST), SW_HIDE); - ::ShowWindow(GetDlgItem(IDC_LIST2), SW_SHOW); - break; - } - return FALSE; -} - -void CDebugTlb::RefreshTLBWindow(void) -{ - if (m_hWnd == NULL) - { - return; - } - - HWND hList = GetDlgItem(IDC_LIST); - char Output[100], OldText[100]; - LV_ITEM item, OldItem; - int count; - - CTLB::TLB_ENTRY * tlb = g_TLB->m_tlb; - for (count = 0; count < 32; count++) - { - sprintf(Output, "0x%02X", count); - item.mask = LVIF_TEXT; - item.iItem = count; - item.pszText = Output; - item.iSubItem = 0; - - OldItem.mask = LVIF_TEXT; - OldItem.iItem = count; - OldItem.pszText = OldText; - OldItem.cchTextMax = sizeof(OldText) - 1; - OldItem.iSubItem = 0; - - if (ListView_GetItemCount(hList) <= count) - { - ListView_InsertItem(hList, &item); - } - else - { - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - } - if (tlb[count].EntryDefined) - { - sprintf(Output, "0x%08X", tlb[count].PageMask.Value); - } - else - { - strcpy(Output, "................"); - } - item.iSubItem = 1; - OldItem.iSubItem = 1; - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - - if (tlb[count].EntryDefined) - { - sprintf(Output, "0x%08X", tlb[count].EntryHi.Value); - } - else - { - strcpy(Output, "................"); - } - item.iSubItem = 2; - OldItem.iSubItem = 2; - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - - if (tlb[count].EntryDefined) - { - sprintf(Output, "0x%08X", tlb[count].EntryLo0.Value); - } - else - { - strcpy(Output, "................"); - } - item.iSubItem = 3; - OldItem.iSubItem = 3; - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - - if (tlb[count].EntryDefined) - { - sprintf(Output, "0x%08X", tlb[count].EntryLo1.Value); - } - else - { - strcpy(Output, "................"); - } - item.iSubItem = 4; - OldItem.iSubItem = 4; - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - } - - CTLB::FASTTLB * FastTlb = g_TLB->m_FastTlb; - hList = GetDlgItem(IDC_LIST2); - for (count = 0; count < 64; count++) - { - sprintf(Output, "0x%02X", count); - item.mask = LVIF_TEXT; - item.iItem = count; - item.pszText = Output; - item.iSubItem = 0; - - OldItem.mask = LVIF_TEXT; - OldItem.iItem = count; - OldItem.pszText = OldText; - OldItem.cchTextMax = sizeof(OldText) - 1; - OldItem.iSubItem = 0; - - if (ListView_GetItemCount(hList) <= count) - { - item.iItem = ListView_InsertItem(hList, &item); - } - else - { - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - } - - if (FastTlb[count].ValidEntry) - { - sprintf(Output, "%s", FastTlb[count].VALID ? "Yes" : "No"); - } - else - { - strcpy(Output, "................"); - } - item.iSubItem = 1; - OldItem.iSubItem = 1; - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - - if (FastTlb[count].ValidEntry && FastTlb[count].VALID) - { - sprintf(Output, "%s", FastTlb[count].DIRTY ? "Yes" : "No"); - } - else - { - strcpy(Output, "................"); - } - item.iSubItem = 2; - OldItem.iSubItem = 2; - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - - if (FastTlb[count].ValidEntry && FastTlb[count].VALID) - { - sprintf(Output, "%08X:%08X -> %08X:%08X", FastTlb[count].VSTART, FastTlb[count].VEND, - FastTlb[count].PHYSSTART, FastTlb[count].PHYSEND); - } - else - { - strcpy(Output, "................"); - } - item.iSubItem = 3; - OldItem.iSubItem = 3; - ListView_GetItem(hList, &OldItem); - if (strcmp(item.pszText, OldItem.pszText) != 0) - { - ListView_SetItem(hList, &item); - } - } -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "DebuggerUI.h" + +CDebugTlb::CDebugTlb(CDebuggerUI * debugger) : + CDebugDialog(debugger) +{ +} + +CDebugTlb::~CDebugTlb() +{ +} + +LRESULT CDebugTlb::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + LV_COLUMN col; + + col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + col.fmt = LVCFMT_LEFT; + + col.pszText = "Index"; + col.cx = 40; + col.iSubItem = 0; + ListView_InsertColumn(GetDlgItem(IDC_LIST), 0, &col); + + col.pszText = "Page Mask"; + col.cx = 90; + col.iSubItem = 1; + ListView_InsertColumn(GetDlgItem(IDC_LIST), 1, &col); + + col.pszText = "Entry Hi"; + col.cx = 90; + col.iSubItem = 2; + ListView_InsertColumn(GetDlgItem(IDC_LIST), 2, &col); + + col.pszText = "Entry Lo0"; + col.cx = 90; + col.iSubItem = 3; + ListView_InsertColumn(GetDlgItem(IDC_LIST), 3, &col); + + col.pszText = "Entry Lo1"; + col.cx = 90; + col.iSubItem = 4; + ListView_InsertColumn(GetDlgItem(IDC_LIST), 4, &col); + + col.pszText = "Index"; + col.cx = 40; + col.iSubItem = 0; + ListView_InsertColumn(GetDlgItem(IDC_LIST2), 0, &col); + + col.pszText = "Valid"; + col.cx = 40; + col.iSubItem = 1; + ListView_InsertColumn(GetDlgItem(IDC_LIST2), 1, &col); + + col.pszText = "Dirty"; + col.cx = 40; + col.iSubItem = 2; + ListView_InsertColumn(GetDlgItem(IDC_LIST2), 2, &col); + + col.pszText = "Rule"; + col.cx = 270; + col.iSubItem = 3; + ListView_InsertColumn(GetDlgItem(IDC_LIST2), 3, &col); + + RefreshTLBWindow(); + SendMessage(GetDlgItem(IDC_TLB_ENTRIES), BM_SETCHECK, BST_CHECKED, 0); + + // if (Settings().Load(TLBWindowLeft) <= 0) + // { + // SetWindowPos(NULL,Settings().Load(TLBWindowLeft),Settings().Load(TLBWindowTop),0,0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); + // } + WindowCreated(); + return TRUE; +} + +LRESULT CDebugTlb::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/) +{ + switch (wID) + { + case IDCANCEL: + EndDialog(0); + break; + case IDC_TLB_ENTRIES: + ::ShowWindow(GetDlgItem(IDC_LIST), SW_SHOW); + ::ShowWindow(GetDlgItem(IDC_LIST2), SW_HIDE); + break; + case IDC_TLB_RULES: + ::ShowWindow(GetDlgItem(IDC_LIST), SW_HIDE); + ::ShowWindow(GetDlgItem(IDC_LIST2), SW_SHOW); + break; + } + return FALSE; +} + +void CDebugTlb::RefreshTLBWindow(void) +{ + if (m_hWnd == NULL) + { + return; + } + + HWND hList = GetDlgItem(IDC_LIST); + char Output[100], OldText[100]; + LV_ITEM item, OldItem; + int count; + + CTLB::TLB_ENTRY * tlb = g_TLB->m_tlb; + for (count = 0; count < 32; count++) + { + sprintf(Output, "0x%02X", count); + item.mask = LVIF_TEXT; + item.iItem = count; + item.pszText = Output; + item.iSubItem = 0; + + OldItem.mask = LVIF_TEXT; + OldItem.iItem = count; + OldItem.pszText = OldText; + OldItem.cchTextMax = sizeof(OldText) - 1; + OldItem.iSubItem = 0; + + if (ListView_GetItemCount(hList) <= count) + { + ListView_InsertItem(hList, &item); + } + else + { + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + } + if (tlb[count].EntryDefined) + { + sprintf(Output, "0x%08X", tlb[count].PageMask.Value); + } + else + { + strcpy(Output, "................"); + } + item.iSubItem = 1; + OldItem.iSubItem = 1; + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + + if (tlb[count].EntryDefined) + { + sprintf(Output, "0x%08X", tlb[count].EntryHi.Value); + } + else + { + strcpy(Output, "................"); + } + item.iSubItem = 2; + OldItem.iSubItem = 2; + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + + if (tlb[count].EntryDefined) + { + sprintf(Output, "0x%08X", tlb[count].EntryLo0.Value); + } + else + { + strcpy(Output, "................"); + } + item.iSubItem = 3; + OldItem.iSubItem = 3; + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + + if (tlb[count].EntryDefined) + { + sprintf(Output, "0x%08X", tlb[count].EntryLo1.Value); + } + else + { + strcpy(Output, "................"); + } + item.iSubItem = 4; + OldItem.iSubItem = 4; + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + } + + CTLB::FASTTLB * FastTlb = g_TLB->m_FastTlb; + hList = GetDlgItem(IDC_LIST2); + for (count = 0; count < 64; count++) + { + sprintf(Output, "0x%02X", count); + item.mask = LVIF_TEXT; + item.iItem = count; + item.pszText = Output; + item.iSubItem = 0; + + OldItem.mask = LVIF_TEXT; + OldItem.iItem = count; + OldItem.pszText = OldText; + OldItem.cchTextMax = sizeof(OldText) - 1; + OldItem.iSubItem = 0; + + if (ListView_GetItemCount(hList) <= count) + { + item.iItem = ListView_InsertItem(hList, &item); + } + else + { + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + } + + if (FastTlb[count].ValidEntry) + { + sprintf(Output, "%s", FastTlb[count].VALID ? "Yes" : "No"); + } + else + { + strcpy(Output, "................"); + } + item.iSubItem = 1; + OldItem.iSubItem = 1; + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + + if (FastTlb[count].ValidEntry && FastTlb[count].VALID) + { + sprintf(Output, "%s", FastTlb[count].DIRTY ? "Yes" : "No"); + } + else + { + strcpy(Output, "................"); + } + item.iSubItem = 2; + OldItem.iSubItem = 2; + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + + if (FastTlb[count].ValidEntry && FastTlb[count].VALID) + { + sprintf(Output, "%08X:%08X -> %08X:%08X", FastTlb[count].VSTART, FastTlb[count].VEND, + FastTlb[count].PHYSSTART, FastTlb[count].PHYSEND); + } + else + { + strcpy(Output, "................"); + } + item.iSubItem = 3; + OldItem.iSubItem = 3; + ListView_GetItem(hList, &OldItem); + if (strcmp(item.pszText, OldItem.pszText) != 0) + { + ListView_SetItem(hList, &item); + } + } +} diff --git a/Source/Project64/N64System/Debugger/Debugger-TLB.h b/Source/Project64/N64System/Debugger/Debugger-TLB.h index 5039d1ca5..3a884ed5f 100644 --- a/Source/Project64/N64System/Debugger/Debugger-TLB.h +++ b/Source/Project64/N64System/Debugger/Debugger-TLB.h @@ -1,31 +1,31 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CDebugTlb : - public CDebugDialog < CDebugTlb > -{ - BEGIN_MSG_MAP_EX(CDebugTlb) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); - -public: - enum { IDD = IDD_Debugger_TLB }; - - CDebugTlb(CDebuggerUI * debugger); - virtual ~CDebugTlb(void); - - void RefreshTLBWindow(void); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CDebugTlb : + public CDebugDialog < CDebugTlb > +{ + BEGIN_MSG_MAP_EX(CDebugTlb) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); + +public: + enum { IDD = IDD_Debugger_TLB }; + + CDebugTlb(CDebuggerUI * debugger); + virtual ~CDebugTlb(void); + + void RefreshTLBWindow(void); +}; diff --git a/Source/Project64/N64System/Debugger/Debugger-ViewMemory.cpp b/Source/Project64/N64System/Debugger/Debugger-ViewMemory.cpp index 5efc2e926..674732e8d 100644 --- a/Source/Project64/N64System/Debugger/Debugger-ViewMemory.cpp +++ b/Source/Project64/N64System/Debugger/Debugger-ViewMemory.cpp @@ -1,472 +1,472 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "DebuggerUI.h" - -CDebugMemoryView::CDebugMemoryView(CDebuggerUI * debugger) : -CDebugDialog(debugger), -m_MemoryList(NULL) -{ - if (m_MemoryList == NULL) - { - m_MemoryList = new CListCtrl; - m_MemoryList->RegisterClass(); - } -} - -CDebugMemoryView::~CDebugMemoryView() -{ -} - -LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ - m_DataStartLoc = (DWORD)-1; - m_CompareStartLoc = (DWORD)-1; - memset(m_CompareData, 0, sizeof(m_CompareData)); - memset(m_CompareValid, 0, sizeof(m_CompareValid)); - - HWND hScrlBar = GetDlgItem(IDC_SCRL_BAR); - if (hScrlBar) - { - SCROLLINFO si; - - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; - si.nMin = 0; - si.nMax = 0xFFFF; - si.nPos = 0x8000; - si.nPage = 100; - ::SetScrollInfo(hScrlBar, SB_CTL, &si, TRUE); - } - - m_MemAddr.Attach(GetDlgItem(IDC_ADDR_EDIT)); - m_MemAddr.SetDisplayType(CEditNumber::DisplayHex); - m_MemAddr.SetValue(0x80000000, true, true); - - SendDlgItemMessage(IDC_CHK_VADDR, BM_SETCHECK, BST_CHECKED, 0); - - if (m_MemoryList == NULL) - { - m_MemoryList = new CListCtrl; - m_MemoryList->RegisterClass(); - } - m_MemoryList->SubclassWindow(GetDlgItem(IDC_MEM_DETAILS)); - m_MemoryList->ShowHeader(false); - m_MemoryList->SetSortEnabled(FALSE); - m_MemoryList->AddColumn(_T("Address"), 90); - m_MemoryList->AddColumn(_T("1"), 20); - m_MemoryList->AddColumn(_T("2"), 20); - m_MemoryList->AddColumn(_T("3"), 20); - m_MemoryList->AddColumn(_T("4"), 20); - m_MemoryList->AddColumn(_T("-"), 10); - m_MemoryList->AddColumn(_T("5"), 20); - m_MemoryList->AddColumn(_T("6"), 20); - m_MemoryList->AddColumn(_T("7"), 20); - m_MemoryList->AddColumn(_T("8"), 20); - m_MemoryList->AddColumn(_T("-"), 10); - m_MemoryList->AddColumn(_T("9"), 20); - m_MemoryList->AddColumn(_T("10"), 20); - m_MemoryList->AddColumn(_T("11"), 20); - m_MemoryList->AddColumn(_T("12"), 20); - m_MemoryList->AddColumn(_T("-"), 10); - m_MemoryList->AddColumn(_T("13"), 20); - m_MemoryList->AddColumn(_T("14"), 20); - m_MemoryList->AddColumn(_T("15"), 20); - m_MemoryList->AddColumn(_T("16"), 35); - m_MemoryList->AddColumn(_T("Memory Ascii"), 140); - ::SetWindowLongPtr(m_MemoryList->m_hWnd, GWL_EXSTYLE, WS_EX_CLIENTEDGE); - RefreshMemory(false); - int height = m_MemoryList->GetTotalHeight(); - - RECT MemoryListRect = { 0 }; - ::GetClientRect(GetDlgItem(IDC_MEM_DETAILS), &MemoryListRect); - - if (height > MemoryListRect.bottom) - { - RECT MemoryListWindow = { 0 }; - GetWindowRect(&MemoryListWindow); - SetWindowPos(NULL, 0, 0, MemoryListWindow.right - MemoryListWindow.left, (MemoryListWindow.bottom - MemoryListWindow.top) + (height - MemoryListRect.bottom), SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER); - - RECT DlgItemRect = { 0 }; - ::GetWindowRect(GetDlgItem(IDC_BORDER), &DlgItemRect); - ::SetWindowPos(GetDlgItem(IDC_BORDER), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE); - - ::GetWindowRect(GetDlgItem(IDC_MEM_DETAILS), &DlgItemRect); - ::SetWindowPos(GetDlgItem(IDC_MEM_DETAILS), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE); - - ::GetWindowRect(GetDlgItem(IDC_SCRL_BAR), &DlgItemRect); - ::SetWindowPos(GetDlgItem(IDC_SCRL_BAR), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE); - } - WindowCreated(); - return TRUE; -} - -LRESULT CDebugMemoryView::OnDestroy(void) -{ - if (m_MemoryList) - { - m_MemoryList->UnsubclassWindow(); - delete m_MemoryList; - m_MemoryList = NULL; - } - return 0; -} - -LRESULT CDebugMemoryView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/) -{ - switch (wID) - { - case IDC_REFRSH_MEM: - RefreshMemory(true); - break; - case IDC_CHK_VADDR: - RefreshMemory(false); - break; - case IDC_DUMP_MEM: - m_Debugger->Debug_ShowMemoryDump(); - break; - case IDC_SEARCH_MEM: - m_Debugger->Debug_ShowMemorySearch(); - break; - case IDCANCEL: - EndDialog(0); - break; - } - return FALSE; -} - -LRESULT CDebugMemoryView::OnMemoryModified(LPNMHDR lpNMHDR) -{ - CListNotify *pListNotify = reinterpret_cast(lpNMHDR); - int LineNumber = pListNotify->m_nItem; - int Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 1)); - if (pListNotify->m_nSubItem >= 6 && pListNotify->m_nSubItem < 10) - { - Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 2)); - } - if (pListNotify->m_nSubItem >= 11 && pListNotify->m_nSubItem < 15) - { - Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 3)); - } - if (pListNotify->m_nSubItem >= 16 && pListNotify->m_nSubItem < 20) - { - Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 4)); - } - - LPCSTR strValue = m_MemoryList->GetItemText(pListNotify->m_nItem, pListNotify->m_nSubItem); - int Finish = strlen(strValue); - if (Finish > 8) - { - Finish = 8; - } - DWORD Value = 0; - for (int i = 0; i < Finish; i++) - { - Value = (Value << 4); - if (strValue[i] <= '9' && strValue[i] >= '0') - { - Value |= strValue[i] - '0'; - } - else if (strValue[i] <= 'f' && strValue[i] >= 'a') - { - Value |= strValue[i] - 'a' + 10; - } - else if (strValue[i] <= 'F' && strValue[i] >= 'A') - { - Value |= strValue[i] - 'A' + 10; - } - } - - if (m_CurrentData[Pos] == Value) - { - return 0; - } - - if (m_CompareStartLoc != m_DataStartLoc || - m_CompareVAddrr != m_DataVAddrr) - { - // copy current data for change comparison - m_CompareStartLoc = m_DataStartLoc; - m_CompareVAddrr = m_DataVAddrr; - memcpy(m_CompareData, m_CurrentData, sizeof(m_CurrentData)); - memcpy(m_CompareValid, m_DataValid, sizeof(m_CompareValid)); - } - - m_CompareData[Pos] = m_CurrentData[Pos]; - m_CurrentData[Pos] = (BYTE)Value; - - //sb - if (m_DataVAddrr) - { - if (!g_MMU->SB_VAddr(m_DataStartLoc + Pos, (BYTE)Value)) - { - WriteTrace(TraceUserInterface, TraceError, "failed to store at %X", m_DataStartLoc + Pos); - } - } - else - { - if (!g_MMU->SB_PAddr(m_DataStartLoc + Pos, (BYTE)Value)) - { - WriteTrace(TraceUserInterface, TraceError, "failed to store at %X", m_DataStartLoc + Pos); - } - } - Insert_MemoryLineDump(LineNumber); - - return 0; -} - -void CDebugMemoryView::ShowAddress(DWORD Address, bool VAddr) -{ - if (m_hWnd == NULL) - { - return; - } - - SendDlgItemMessage(IDC_CHK_VADDR, BM_SETCHECK, VAddr ? BST_CHECKED : BST_UNCHECKED, 0); - m_MemAddr.SetValue(Address, true, true); - RefreshMemory(true); -} - -void CDebugMemoryView::Insert_MemoryLineDump(int LineNumber) -{ - if (m_MemoryList == NULL || m_MemoryList->GetColumnCount() == 0) - { - return; - } - char Output[20], Hex[60], Ascii[20], AsciiAddOn[15]; - sprintf(Output, "0x%08X", m_DataStartLoc + (LineNumber << 4)); - if (m_MemoryList->GetItemCount() <= LineNumber) - { - HFONT hFont = (HFONT)GetStockObject(ANSI_FIXED_FONT); - m_MemoryList->AddItemAt(LineNumber, Output); - for (int i = 0; i < m_MemoryList->GetColumnCount(); i++) - { - m_MemoryList->SetItemFont(LineNumber, i, hFont); - if (i == 5 || i == 10 || i == 15) - { - m_MemoryList->SetItemText(LineNumber, i, "-"); - } - } - } - else - { - if (strcmp(Output, m_MemoryList->GetItemText(LineNumber, 0)) != 0) - { - m_MemoryList->SetItemText(LineNumber, 0, Output); - } - } - - Hex[0] = 0; - Ascii[0] = 0; - int CompareStartPos = m_DataStartLoc - m_CompareStartLoc; - - for (int i = 0, col = 1; i < 0x10; i++, col++) - { - int Pos = ((LineNumber << 4) + i); - if (m_DataValid[Pos]) - { - int ComparePos = CompareStartPos + Pos; - bool Changed = false; - - if (ComparePos >= 0 && ComparePos < MemoryToDisplay && - m_DataVAddrr == m_CompareVAddrr && - m_DataValid[ComparePos] && - m_CurrentData[Pos] != m_CompareData[ComparePos]) - { - Changed = true; - } - sprintf(Hex, "%02X", m_CurrentData[Pos]); - m_MemoryList->SetItemText(LineNumber, col, Hex); - m_MemoryList->SetItemFormat(LineNumber, col, ITEM_FORMAT_EDIT, ITEM_FLAGS_EDIT_HEX); - m_MemoryList->SetItemMaxEditLen(LineNumber, col, 2); - m_MemoryList->SetItemColours(LineNumber, col, GetSysColor(COLOR_WINDOW), - Changed ? RGB(255, 0, 0) : GetSysColor(COLOR_WINDOWTEXT)); - m_MemoryList->SetItemHighlightColours(LineNumber, col, - Changed ? RGB(255, 0, 0) : GetSysColor(COLOR_HIGHLIGHTTEXT)); - if (m_CurrentData[Pos] < 30) - { - strcat(Ascii, "."); - } - else - { - sprintf(AsciiAddOn, "%c", m_CurrentData[Pos]); - strcat(Ascii, AsciiAddOn); - } - } - else - { - m_MemoryList->SetItemText(LineNumber, col, "**"); - m_MemoryList->SetItemFormat(LineNumber, col, ITEM_FORMAT_NONE, ITEM_FLAGS_NONE); - m_MemoryList->SetItemColours(LineNumber, col, GetSysColor(COLOR_WINDOW), GetSysColor(COLOR_WINDOWTEXT)); - strcat(Ascii, "*"); - } - if (i != 0xF) - { - if ((i & 3) == 3) - { - col += 1; - } - } - } - - if (strcmp(Ascii, m_MemoryList->GetItemText(LineNumber, 20)) != 0) - { - m_MemoryList->SetItemText(LineNumber, 20, Ascii); - } -} - -void CDebugMemoryView::OnAddrChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - RefreshMemory(false); -} - -void CDebugMemoryView::OnVScroll(int request, short Pos, HWND ctrl) -{ - if (ctrl != GetDlgItem(IDC_SCRL_BAR)) - { - return; - } - DWORD Location = m_MemAddr.GetValue(); - switch (request) - { - case SB_LINEDOWN: - m_MemAddr.SetValue(Location < 0xFFFFFFEF ? Location + 0x10 : 0xFFFFFFFF, true, true); - break; - case SB_LINEUP: - m_MemAddr.SetValue(Location > 0x10 ? Location - 0x10 : 0, true, true); - break; - case SB_PAGEDOWN: - m_MemAddr.SetValue(Location < 0xFFFFFEFF ? Location + 0x100 : 0xFFFFFFFF, true, true); - break; - case SB_PAGEUP: - m_MemAddr.SetValue(Location > 0x100 ? Location - 0x100 : 0, true, true); - break; - case SB_THUMBPOSITION: - m_MemAddr.SetValue((DWORD)Pos << 0x10, true, true); - break; - default: - break; - } -} - -void CDebugMemoryView::RefreshMemory(bool ResetCompare) -{ - if (m_MemoryList && m_MemoryList->GetHasEditItem()) - { - m_MemoryList->SetFocus(); - } - - DWORD NewAddress = m_MemAddr.GetValue(); - if (NewAddress != m_DataStartLoc) - { - HWND hScrlBar = GetDlgItem(IDC_SCRL_BAR); - if (hScrlBar) - { - SCROLLINFO si; - - si.cbSize = sizeof(si); - si.fMask = SIF_POS; - si.nPos = NewAddress >> 0x10; - ::SetScrollInfo(hScrlBar, SB_CTL, &si, TRUE); - } - } - - if (ResetCompare) - { - // copy current data for change comparison - m_CompareStartLoc = m_DataStartLoc; - m_CompareVAddrr = m_DataVAddrr; - memcpy(m_CompareData, m_CurrentData, sizeof(m_CurrentData)); - memcpy(m_CompareValid, m_DataValid, sizeof(m_CompareValid)); - } - - m_DataStartLoc = m_MemAddr.GetValue(); - if (m_DataStartLoc > 0xFFFFFF00) { m_DataStartLoc = 0xFFFFFF00; } - int WritePos = 0; - - m_DataVAddrr = (SendDlgItemMessage(IDC_CHK_VADDR, BM_GETCHECK, 0, 0) & BST_CHECKED) != 0; - - if ((m_DataStartLoc & 3) != 0) - { - MIPS_WORD word; - bool ValidData = true; - - if (m_DataVAddrr) - { - if (!g_MMU->LW_VAddr(m_DataStartLoc & ~3, word.UW)) - { - ValidData = false; - } - } - else - { - if (!g_MMU->LW_PAddr(m_DataStartLoc & ~3, word.UW)) - { - ValidData = false; - } - } - - int Offset = (m_DataStartLoc & 3); - for (int i = 0; i < (4 - Offset); i++) - { - if (WritePos >= MemoryToDisplay) - { - break; - } - m_DataValid[WritePos + i] = ValidData; - if (ValidData) - { - m_CurrentData[WritePos + i] = word.UB[3 - (i + Offset)]; - } - } - WritePos = 4 - Offset; - } - - for (DWORD Pos = ((m_DataStartLoc + 3) & ~3); Pos < (m_DataStartLoc + MemoryToDisplay); WritePos += 4, Pos += 4) - { - MIPS_WORD word; - bool ValidData = true; - - if (m_DataVAddrr) - { - if (!g_MMU->LW_VAddr(Pos, word.UW)) - { - ValidData = false; - } - } - else - { - if (!g_MMU->LW_PAddr(Pos, word.UW)) - { - ValidData = false; - } - } - - for (int i = 0; i < 4; i++) - { - if ((WritePos + i) >= MemoryToDisplay) - { - break; - } - m_DataValid[WritePos + i] = ValidData; - if (ValidData) - { - m_CurrentData[WritePos + i] = word.UB[3 - i]; - } - } - } - - for (int count = 0; count < 16; count++) - { - Insert_MemoryLineDump(count); - } +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "DebuggerUI.h" + +CDebugMemoryView::CDebugMemoryView(CDebuggerUI * debugger) : +CDebugDialog(debugger), +m_MemoryList(NULL) +{ + if (m_MemoryList == NULL) + { + m_MemoryList = new CListCtrl; + m_MemoryList->RegisterClass(); + } +} + +CDebugMemoryView::~CDebugMemoryView() +{ +} + +LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + m_DataStartLoc = (DWORD)-1; + m_CompareStartLoc = (DWORD)-1; + memset(m_CompareData, 0, sizeof(m_CompareData)); + memset(m_CompareValid, 0, sizeof(m_CompareValid)); + + HWND hScrlBar = GetDlgItem(IDC_SCRL_BAR); + if (hScrlBar) + { + SCROLLINFO si; + + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; + si.nMin = 0; + si.nMax = 0xFFFF; + si.nPos = 0x8000; + si.nPage = 100; + ::SetScrollInfo(hScrlBar, SB_CTL, &si, TRUE); + } + + m_MemAddr.Attach(GetDlgItem(IDC_ADDR_EDIT)); + m_MemAddr.SetDisplayType(CEditNumber::DisplayHex); + m_MemAddr.SetValue(0x80000000, true, true); + + SendDlgItemMessage(IDC_CHK_VADDR, BM_SETCHECK, BST_CHECKED, 0); + + if (m_MemoryList == NULL) + { + m_MemoryList = new CListCtrl; + m_MemoryList->RegisterClass(); + } + m_MemoryList->SubclassWindow(GetDlgItem(IDC_MEM_DETAILS)); + m_MemoryList->ShowHeader(false); + m_MemoryList->SetSortEnabled(FALSE); + m_MemoryList->AddColumn(_T("Address"), 90); + m_MemoryList->AddColumn(_T("1"), 20); + m_MemoryList->AddColumn(_T("2"), 20); + m_MemoryList->AddColumn(_T("3"), 20); + m_MemoryList->AddColumn(_T("4"), 20); + m_MemoryList->AddColumn(_T("-"), 10); + m_MemoryList->AddColumn(_T("5"), 20); + m_MemoryList->AddColumn(_T("6"), 20); + m_MemoryList->AddColumn(_T("7"), 20); + m_MemoryList->AddColumn(_T("8"), 20); + m_MemoryList->AddColumn(_T("-"), 10); + m_MemoryList->AddColumn(_T("9"), 20); + m_MemoryList->AddColumn(_T("10"), 20); + m_MemoryList->AddColumn(_T("11"), 20); + m_MemoryList->AddColumn(_T("12"), 20); + m_MemoryList->AddColumn(_T("-"), 10); + m_MemoryList->AddColumn(_T("13"), 20); + m_MemoryList->AddColumn(_T("14"), 20); + m_MemoryList->AddColumn(_T("15"), 20); + m_MemoryList->AddColumn(_T("16"), 35); + m_MemoryList->AddColumn(_T("Memory Ascii"), 140); + ::SetWindowLongPtr(m_MemoryList->m_hWnd, GWL_EXSTYLE, WS_EX_CLIENTEDGE); + RefreshMemory(false); + int height = m_MemoryList->GetTotalHeight(); + + RECT MemoryListRect = { 0 }; + ::GetClientRect(GetDlgItem(IDC_MEM_DETAILS), &MemoryListRect); + + if (height > MemoryListRect.bottom) + { + RECT MemoryListWindow = { 0 }; + GetWindowRect(&MemoryListWindow); + SetWindowPos(NULL, 0, 0, MemoryListWindow.right - MemoryListWindow.left, (MemoryListWindow.bottom - MemoryListWindow.top) + (height - MemoryListRect.bottom), SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER); + + RECT DlgItemRect = { 0 }; + ::GetWindowRect(GetDlgItem(IDC_BORDER), &DlgItemRect); + ::SetWindowPos(GetDlgItem(IDC_BORDER), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE); + + ::GetWindowRect(GetDlgItem(IDC_MEM_DETAILS), &DlgItemRect); + ::SetWindowPos(GetDlgItem(IDC_MEM_DETAILS), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE); + + ::GetWindowRect(GetDlgItem(IDC_SCRL_BAR), &DlgItemRect); + ::SetWindowPos(GetDlgItem(IDC_SCRL_BAR), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE); + } + WindowCreated(); + return TRUE; +} + +LRESULT CDebugMemoryView::OnDestroy(void) +{ + if (m_MemoryList) + { + m_MemoryList->UnsubclassWindow(); + delete m_MemoryList; + m_MemoryList = NULL; + } + return 0; +} + +LRESULT CDebugMemoryView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/) +{ + switch (wID) + { + case IDC_REFRSH_MEM: + RefreshMemory(true); + break; + case IDC_CHK_VADDR: + RefreshMemory(false); + break; + case IDC_DUMP_MEM: + m_Debugger->Debug_ShowMemoryDump(); + break; + case IDC_SEARCH_MEM: + m_Debugger->Debug_ShowMemorySearch(); + break; + case IDCANCEL: + EndDialog(0); + break; + } + return FALSE; +} + +LRESULT CDebugMemoryView::OnMemoryModified(LPNMHDR lpNMHDR) +{ + CListNotify *pListNotify = reinterpret_cast(lpNMHDR); + int LineNumber = pListNotify->m_nItem; + int Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 1)); + if (pListNotify->m_nSubItem >= 6 && pListNotify->m_nSubItem < 10) + { + Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 2)); + } + if (pListNotify->m_nSubItem >= 11 && pListNotify->m_nSubItem < 15) + { + Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 3)); + } + if (pListNotify->m_nSubItem >= 16 && pListNotify->m_nSubItem < 20) + { + Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 4)); + } + + LPCSTR strValue = m_MemoryList->GetItemText(pListNotify->m_nItem, pListNotify->m_nSubItem); + int Finish = strlen(strValue); + if (Finish > 8) + { + Finish = 8; + } + DWORD Value = 0; + for (int i = 0; i < Finish; i++) + { + Value = (Value << 4); + if (strValue[i] <= '9' && strValue[i] >= '0') + { + Value |= strValue[i] - '0'; + } + else if (strValue[i] <= 'f' && strValue[i] >= 'a') + { + Value |= strValue[i] - 'a' + 10; + } + else if (strValue[i] <= 'F' && strValue[i] >= 'A') + { + Value |= strValue[i] - 'A' + 10; + } + } + + if (m_CurrentData[Pos] == Value) + { + return 0; + } + + if (m_CompareStartLoc != m_DataStartLoc || + m_CompareVAddrr != m_DataVAddrr) + { + // copy current data for change comparison + m_CompareStartLoc = m_DataStartLoc; + m_CompareVAddrr = m_DataVAddrr; + memcpy(m_CompareData, m_CurrentData, sizeof(m_CurrentData)); + memcpy(m_CompareValid, m_DataValid, sizeof(m_CompareValid)); + } + + m_CompareData[Pos] = m_CurrentData[Pos]; + m_CurrentData[Pos] = (BYTE)Value; + + //sb + if (m_DataVAddrr) + { + if (!g_MMU->SB_VAddr(m_DataStartLoc + Pos, (BYTE)Value)) + { + WriteTrace(TraceUserInterface, TraceError, "failed to store at %X", m_DataStartLoc + Pos); + } + } + else + { + if (!g_MMU->SB_PAddr(m_DataStartLoc + Pos, (BYTE)Value)) + { + WriteTrace(TraceUserInterface, TraceError, "failed to store at %X", m_DataStartLoc + Pos); + } + } + Insert_MemoryLineDump(LineNumber); + + return 0; +} + +void CDebugMemoryView::ShowAddress(DWORD Address, bool VAddr) +{ + if (m_hWnd == NULL) + { + return; + } + + SendDlgItemMessage(IDC_CHK_VADDR, BM_SETCHECK, VAddr ? BST_CHECKED : BST_UNCHECKED, 0); + m_MemAddr.SetValue(Address, true, true); + RefreshMemory(true); +} + +void CDebugMemoryView::Insert_MemoryLineDump(int LineNumber) +{ + if (m_MemoryList == NULL || m_MemoryList->GetColumnCount() == 0) + { + return; + } + char Output[20], Hex[60], Ascii[20], AsciiAddOn[15]; + sprintf(Output, "0x%08X", m_DataStartLoc + (LineNumber << 4)); + if (m_MemoryList->GetItemCount() <= LineNumber) + { + HFONT hFont = (HFONT)GetStockObject(ANSI_FIXED_FONT); + m_MemoryList->AddItemAt(LineNumber, Output); + for (int i = 0; i < m_MemoryList->GetColumnCount(); i++) + { + m_MemoryList->SetItemFont(LineNumber, i, hFont); + if (i == 5 || i == 10 || i == 15) + { + m_MemoryList->SetItemText(LineNumber, i, "-"); + } + } + } + else + { + if (strcmp(Output, m_MemoryList->GetItemText(LineNumber, 0)) != 0) + { + m_MemoryList->SetItemText(LineNumber, 0, Output); + } + } + + Hex[0] = 0; + Ascii[0] = 0; + int CompareStartPos = m_DataStartLoc - m_CompareStartLoc; + + for (int i = 0, col = 1; i < 0x10; i++, col++) + { + int Pos = ((LineNumber << 4) + i); + if (m_DataValid[Pos]) + { + int ComparePos = CompareStartPos + Pos; + bool Changed = false; + + if (ComparePos >= 0 && ComparePos < MemoryToDisplay && + m_DataVAddrr == m_CompareVAddrr && + m_DataValid[ComparePos] && + m_CurrentData[Pos] != m_CompareData[ComparePos]) + { + Changed = true; + } + sprintf(Hex, "%02X", m_CurrentData[Pos]); + m_MemoryList->SetItemText(LineNumber, col, Hex); + m_MemoryList->SetItemFormat(LineNumber, col, ITEM_FORMAT_EDIT, ITEM_FLAGS_EDIT_HEX); + m_MemoryList->SetItemMaxEditLen(LineNumber, col, 2); + m_MemoryList->SetItemColours(LineNumber, col, GetSysColor(COLOR_WINDOW), + Changed ? RGB(255, 0, 0) : GetSysColor(COLOR_WINDOWTEXT)); + m_MemoryList->SetItemHighlightColours(LineNumber, col, + Changed ? RGB(255, 0, 0) : GetSysColor(COLOR_HIGHLIGHTTEXT)); + if (m_CurrentData[Pos] < 30) + { + strcat(Ascii, "."); + } + else + { + sprintf(AsciiAddOn, "%c", m_CurrentData[Pos]); + strcat(Ascii, AsciiAddOn); + } + } + else + { + m_MemoryList->SetItemText(LineNumber, col, "**"); + m_MemoryList->SetItemFormat(LineNumber, col, ITEM_FORMAT_NONE, ITEM_FLAGS_NONE); + m_MemoryList->SetItemColours(LineNumber, col, GetSysColor(COLOR_WINDOW), GetSysColor(COLOR_WINDOWTEXT)); + strcat(Ascii, "*"); + } + if (i != 0xF) + { + if ((i & 3) == 3) + { + col += 1; + } + } + } + + if (strcmp(Ascii, m_MemoryList->GetItemText(LineNumber, 20)) != 0) + { + m_MemoryList->SetItemText(LineNumber, 20, Ascii); + } +} + +void CDebugMemoryView::OnAddrChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + RefreshMemory(false); +} + +void CDebugMemoryView::OnVScroll(int request, short Pos, HWND ctrl) +{ + if (ctrl != GetDlgItem(IDC_SCRL_BAR)) + { + return; + } + DWORD Location = m_MemAddr.GetValue(); + switch (request) + { + case SB_LINEDOWN: + m_MemAddr.SetValue(Location < 0xFFFFFFEF ? Location + 0x10 : 0xFFFFFFFF, true, true); + break; + case SB_LINEUP: + m_MemAddr.SetValue(Location > 0x10 ? Location - 0x10 : 0, true, true); + break; + case SB_PAGEDOWN: + m_MemAddr.SetValue(Location < 0xFFFFFEFF ? Location + 0x100 : 0xFFFFFFFF, true, true); + break; + case SB_PAGEUP: + m_MemAddr.SetValue(Location > 0x100 ? Location - 0x100 : 0, true, true); + break; + case SB_THUMBPOSITION: + m_MemAddr.SetValue((DWORD)Pos << 0x10, true, true); + break; + default: + break; + } +} + +void CDebugMemoryView::RefreshMemory(bool ResetCompare) +{ + if (m_MemoryList && m_MemoryList->GetHasEditItem()) + { + m_MemoryList->SetFocus(); + } + + DWORD NewAddress = m_MemAddr.GetValue(); + if (NewAddress != m_DataStartLoc) + { + HWND hScrlBar = GetDlgItem(IDC_SCRL_BAR); + if (hScrlBar) + { + SCROLLINFO si; + + si.cbSize = sizeof(si); + si.fMask = SIF_POS; + si.nPos = NewAddress >> 0x10; + ::SetScrollInfo(hScrlBar, SB_CTL, &si, TRUE); + } + } + + if (ResetCompare) + { + // copy current data for change comparison + m_CompareStartLoc = m_DataStartLoc; + m_CompareVAddrr = m_DataVAddrr; + memcpy(m_CompareData, m_CurrentData, sizeof(m_CurrentData)); + memcpy(m_CompareValid, m_DataValid, sizeof(m_CompareValid)); + } + + m_DataStartLoc = m_MemAddr.GetValue(); + if (m_DataStartLoc > 0xFFFFFF00) { m_DataStartLoc = 0xFFFFFF00; } + int WritePos = 0; + + m_DataVAddrr = (SendDlgItemMessage(IDC_CHK_VADDR, BM_GETCHECK, 0, 0) & BST_CHECKED) != 0; + + if ((m_DataStartLoc & 3) != 0) + { + MIPS_WORD word; + bool ValidData = true; + + if (m_DataVAddrr) + { + if (!g_MMU->LW_VAddr(m_DataStartLoc & ~3, word.UW)) + { + ValidData = false; + } + } + else + { + if (!g_MMU->LW_PAddr(m_DataStartLoc & ~3, word.UW)) + { + ValidData = false; + } + } + + int Offset = (m_DataStartLoc & 3); + for (int i = 0; i < (4 - Offset); i++) + { + if (WritePos >= MemoryToDisplay) + { + break; + } + m_DataValid[WritePos + i] = ValidData; + if (ValidData) + { + m_CurrentData[WritePos + i] = word.UB[3 - (i + Offset)]; + } + } + WritePos = 4 - Offset; + } + + for (DWORD Pos = ((m_DataStartLoc + 3) & ~3); Pos < (m_DataStartLoc + MemoryToDisplay); WritePos += 4, Pos += 4) + { + MIPS_WORD word; + bool ValidData = true; + + if (m_DataVAddrr) + { + if (!g_MMU->LW_VAddr(Pos, word.UW)) + { + ValidData = false; + } + } + else + { + if (!g_MMU->LW_PAddr(Pos, word.UW)) + { + ValidData = false; + } + } + + for (int i = 0; i < 4; i++) + { + if ((WritePos + i) >= MemoryToDisplay) + { + break; + } + m_DataValid[WritePos + i] = ValidData; + if (ValidData) + { + m_CurrentData[WritePos + i] = word.UB[3 - i]; + } + } + } + + for (int count = 0; count < 16; count++) + { + Insert_MemoryLineDump(count); + } } \ No newline at end of file diff --git a/Source/Project64/N64System/Debugger/Debugger-ViewMemory.h b/Source/Project64/N64System/Debugger/Debugger-ViewMemory.h index f90cb3507..47610a09e 100644 --- a/Source/Project64/N64System/Debugger/Debugger-ViewMemory.h +++ b/Source/Project64/N64System/Debugger/Debugger-ViewMemory.h @@ -1,58 +1,58 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CDebugMemoryView : - public CDebugDialog < CDebugMemoryView > -{ -public: - enum { IDD = IDD_Debugger_Memory }; - - CDebugMemoryView(CDebuggerUI * debugger); - virtual ~CDebugMemoryView(void); - - void ShowAddress(DWORD Address, bool VAddr); - -private: - BEGIN_MSG_MAP_EX(CDebugMemoryView) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) - COMMAND_HANDLER_EX(IDC_ADDR_EDIT, EN_CHANGE, OnAddrChanged) - NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_MODIFIED, OnMemoryModified) - MSG_WM_DESTROY(OnDestroy) - MSG_WM_VSCROLL(OnVScroll) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); - void OnAddrChanged(UINT Code, int id, HWND ctl); - void OnVScroll(int request, short Pos, HWND ctrl); - LRESULT OnMemoryModified(LPNMHDR lpNMHDR); - LRESULT OnDestroy(void); - - void Insert_MemoryLineDump(int LineNumber); - void RefreshMemory(bool ResetCompare); - - enum { MemoryToDisplay = 0x100 }; - - CEditNumber m_MemAddr; - CListCtrl * m_MemoryList; - - DWORD m_DataStartLoc; - bool m_DataVAddrr; - BYTE m_CurrentData[MemoryToDisplay]; - bool m_DataValid[MemoryToDisplay]; - - DWORD m_CompareStartLoc; - bool m_CompareVAddrr; - BYTE m_CompareData[MemoryToDisplay]; - bool m_CompareValid[MemoryToDisplay]; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CDebugMemoryView : + public CDebugDialog < CDebugMemoryView > +{ +public: + enum { IDD = IDD_Debugger_Memory }; + + CDebugMemoryView(CDebuggerUI * debugger); + virtual ~CDebugMemoryView(void); + + void ShowAddress(DWORD Address, bool VAddr); + +private: + BEGIN_MSG_MAP_EX(CDebugMemoryView) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) + COMMAND_HANDLER_EX(IDC_ADDR_EDIT, EN_CHANGE, OnAddrChanged) + NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_MODIFIED, OnMemoryModified) + MSG_WM_DESTROY(OnDestroy) + MSG_WM_VSCROLL(OnVScroll) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); + void OnAddrChanged(UINT Code, int id, HWND ctl); + void OnVScroll(int request, short Pos, HWND ctrl); + LRESULT OnMemoryModified(LPNMHDR lpNMHDR); + LRESULT OnDestroy(void); + + void Insert_MemoryLineDump(int LineNumber); + void RefreshMemory(bool ResetCompare); + + enum { MemoryToDisplay = 0x100 }; + + CEditNumber m_MemAddr; + CListCtrl * m_MemoryList; + + DWORD m_DataStartLoc; + bool m_DataVAddrr; + BYTE m_CurrentData[MemoryToDisplay]; + bool m_DataValid[MemoryToDisplay]; + + DWORD m_CompareStartLoc; + bool m_CompareVAddrr; + BYTE m_CompareData[MemoryToDisplay]; + bool m_CompareValid[MemoryToDisplay]; +}; diff --git a/Source/Project64/N64System/Debugger/Debugger.cpp b/Source/Project64/N64System/Debugger/Debugger.cpp index bdd65b567..912682389 100644 --- a/Source/Project64/N64System/Debugger/Debugger.cpp +++ b/Source/Project64/N64System/Debugger/Debugger.cpp @@ -1,149 +1,149 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "DebuggerUI.h" - -CPj64Module _Module; - -CDebuggerUI::CDebuggerUI () : - m_MemoryDump(NULL), - m_MemoryView(NULL), - m_MemorySearch(NULL), - m_DebugTLB(NULL) -{ - g_Settings->RegisterChangeCB(GameRunning_InReset,this,(CSettings::SettingChangedFunc)GameReset); - g_Debugger = this; -} - -CDebuggerUI::~CDebuggerUI (void) -{ - g_Settings->UnregisterChangeCB(GameRunning_InReset,this,(CSettings::SettingChangedFunc)GameReset); - Debug_Reset(); -} - -void CDebuggerUI::GameReset ( CDebuggerUI * _this ) -{ - if (!g_Settings->LoadBool(GameRunning_InReset)) - { - return; - } - _this->Debug_Reset(); -} - -void CDebuggerUI::Debug_Reset ( void ) -{ - if (m_MemoryDump) - { - m_MemoryDump->HideWindow(); - delete m_MemoryDump; - m_MemoryDump = NULL; - } - if (m_MemoryView) - { - m_MemoryView->HideWindow(); - delete m_MemoryView; - m_MemoryView = NULL; - } - if (m_MemorySearch) - { - m_MemorySearch->HideWindow(); - delete m_MemorySearch; - m_MemorySearch = NULL; - } - if (m_DebugTLB) - { - m_DebugTLB->HideWindow(); - delete m_DebugTLB; - m_DebugTLB = NULL; - } -} - -void CDebuggerUI::Debug_ShowMemoryDump() -{ - if (g_MMU == NULL) - { - return; - } - if (m_MemoryDump == NULL) - { - m_MemoryDump = new CDumpMemory(this); - } - if (m_MemoryDump) - { - m_MemoryDump->ShowWindow(); - } -} - -void CDebuggerUI::Debug_ShowMemoryWindow ( void ) -{ - if (g_MMU == NULL) - { - return; - } - if (m_MemoryView == NULL) - { - m_MemoryView = new CDebugMemoryView(this); - } - if (m_MemoryView) - { - m_MemoryView->ShowWindow(); - } -} - -void CDebuggerUI::Debug_ShowMemoryLocation ( uint32_t Address, bool VAddr ) -{ - Debug_ShowMemoryWindow(); - if (m_MemoryView) - { - m_MemoryView->ShowAddress(Address,VAddr); - } -} - -void CDebuggerUI::Debug_ShowTLBWindow (void) -{ - if (g_MMU == NULL) - { - return; - } - if (m_DebugTLB == NULL) - { - m_DebugTLB = new CDebugTlb(this); - } - if (m_DebugTLB) - { - m_DebugTLB->ShowWindow(); - } -} - -void CDebuggerUI::Debug_RefreshTLBWindow(void) -{ - if (m_DebugTLB) - { - m_DebugTLB->RefreshTLBWindow(); - } -} - -void CDebuggerUI::Debug_ShowMemorySearch() -{ - if (m_MemorySearch == NULL) - { - m_MemorySearch = new CDebugMemorySearch(this); - } - if (m_MemorySearch) - { - m_MemorySearch->ShowWindow(); - } -} - -void CDebuggerUI::TLBChanged() -{ - Debug_RefreshTLBWindow(); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "DebuggerUI.h" + +CPj64Module _Module; + +CDebuggerUI::CDebuggerUI () : + m_MemoryDump(NULL), + m_MemoryView(NULL), + m_MemorySearch(NULL), + m_DebugTLB(NULL) +{ + g_Settings->RegisterChangeCB(GameRunning_InReset,this,(CSettings::SettingChangedFunc)GameReset); + g_Debugger = this; +} + +CDebuggerUI::~CDebuggerUI (void) +{ + g_Settings->UnregisterChangeCB(GameRunning_InReset,this,(CSettings::SettingChangedFunc)GameReset); + Debug_Reset(); +} + +void CDebuggerUI::GameReset ( CDebuggerUI * _this ) +{ + if (!g_Settings->LoadBool(GameRunning_InReset)) + { + return; + } + _this->Debug_Reset(); +} + +void CDebuggerUI::Debug_Reset ( void ) +{ + if (m_MemoryDump) + { + m_MemoryDump->HideWindow(); + delete m_MemoryDump; + m_MemoryDump = NULL; + } + if (m_MemoryView) + { + m_MemoryView->HideWindow(); + delete m_MemoryView; + m_MemoryView = NULL; + } + if (m_MemorySearch) + { + m_MemorySearch->HideWindow(); + delete m_MemorySearch; + m_MemorySearch = NULL; + } + if (m_DebugTLB) + { + m_DebugTLB->HideWindow(); + delete m_DebugTLB; + m_DebugTLB = NULL; + } +} + +void CDebuggerUI::Debug_ShowMemoryDump() +{ + if (g_MMU == NULL) + { + return; + } + if (m_MemoryDump == NULL) + { + m_MemoryDump = new CDumpMemory(this); + } + if (m_MemoryDump) + { + m_MemoryDump->ShowWindow(); + } +} + +void CDebuggerUI::Debug_ShowMemoryWindow ( void ) +{ + if (g_MMU == NULL) + { + return; + } + if (m_MemoryView == NULL) + { + m_MemoryView = new CDebugMemoryView(this); + } + if (m_MemoryView) + { + m_MemoryView->ShowWindow(); + } +} + +void CDebuggerUI::Debug_ShowMemoryLocation ( uint32_t Address, bool VAddr ) +{ + Debug_ShowMemoryWindow(); + if (m_MemoryView) + { + m_MemoryView->ShowAddress(Address,VAddr); + } +} + +void CDebuggerUI::Debug_ShowTLBWindow (void) +{ + if (g_MMU == NULL) + { + return; + } + if (m_DebugTLB == NULL) + { + m_DebugTLB = new CDebugTlb(this); + } + if (m_DebugTLB) + { + m_DebugTLB->ShowWindow(); + } +} + +void CDebuggerUI::Debug_RefreshTLBWindow(void) +{ + if (m_DebugTLB) + { + m_DebugTLB->RefreshTLBWindow(); + } +} + +void CDebuggerUI::Debug_ShowMemorySearch() +{ + if (m_MemorySearch == NULL) + { + m_MemorySearch = new CDebugMemorySearch(this); + } + if (m_MemorySearch) + { + m_MemorySearch->ShowWindow(); + } +} + +void CDebuggerUI::TLBChanged() +{ + Debug_RefreshTLBWindow(); } \ No newline at end of file diff --git a/Source/Project64/N64System/Debugger/DebuggerUI.h b/Source/Project64/N64System/Debugger/DebuggerUI.h index a57eb9b3d..d21658db5 100644 --- a/Source/Project64/N64System/Debugger/DebuggerUI.h +++ b/Source/Project64/N64System/Debugger/DebuggerUI.h @@ -1,9 +1,9 @@ -#pragma once - -#include "../../WTLApp.h" -#include "../../N64System.h" -#include "DebugDialog.h" -#include "Debugger-MemorySearch.h" -#include "Debugger-ViewMemory.h" -#include "Debugger-MemoryDump.h" -#include "Debugger-TLB.h" +#pragma once + +#include "../../WTLApp.h" +#include "../../N64System.h" +#include "DebugDialog.h" +#include "Debugger-MemorySearch.h" +#include "Debugger-ViewMemory.h" +#include "Debugger-MemoryDump.h" +#include "Debugger-TLB.h" diff --git a/Source/Project64/N64System/Debugger/debugger.h b/Source/Project64/N64System/Debugger/debugger.h index 568c3f89f..3495de0c8 100644 --- a/Source/Project64/N64System/Debugger/debugger.h +++ b/Source/Project64/N64System/Debugger/debugger.h @@ -1,47 +1,47 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CDumpMemory; -class CDebugMemoryView; -class CDebugMemorySearch; -class CDebugTlb; - -__interface CDebugger -{ - virtual void TLBChanged ( void ) = 0; -}; - -class CDebuggerUI : - public CDebugger -{ - CDumpMemory * m_MemoryDump; - CDebugMemoryView * m_MemoryView; - CDebugMemorySearch * m_MemorySearch; - CDebugTlb * m_DebugTLB; - -protected: - CDebuggerUI(); - virtual ~CDebuggerUI(); - - void TLBChanged ( void ); - -public: - void Debug_Reset ( void ); - void Debug_ShowMemoryDump ( void ); - void Debug_ShowMemoryWindow ( void ); - void Debug_ShowMemoryLocation ( uint32_t Address, bool VAddr ); - void Debug_ShowMemorySearch ( void ); - void Debug_ShowTLBWindow ( void ); - void Debug_RefreshTLBWindow ( void ); - - static void GameReset ( CDebuggerUI * _this ); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CDumpMemory; +class CDebugMemoryView; +class CDebugMemorySearch; +class CDebugTlb; + +__interface CDebugger +{ + virtual void TLBChanged ( void ) = 0; +}; + +class CDebuggerUI : + public CDebugger +{ + CDumpMemory * m_MemoryDump; + CDebugMemoryView * m_MemoryView; + CDebugMemorySearch * m_MemorySearch; + CDebugTlb * m_DebugTLB; + +protected: + CDebuggerUI(); + virtual ~CDebuggerUI(); + + void TLBChanged ( void ); + +public: + void Debug_Reset ( void ); + void Debug_ShowMemoryDump ( void ); + void Debug_ShowMemoryWindow ( void ); + void Debug_ShowMemoryLocation ( uint32_t Address, bool VAddr ); + void Debug_ShowMemorySearch ( void ); + void Debug_ShowTLBWindow ( void ); + void Debug_RefreshTLBWindow ( void ); + + static void GameReset ( CDebuggerUI * _this ); +}; diff --git a/Source/Project64/Plugins/PluginList.cpp b/Source/Project64/Plugins/PluginList.cpp index 38a47384a..e71e13bcc 100644 --- a/Source/Project64/Plugins/PluginList.cpp +++ b/Source/Project64/Plugins/PluginList.cpp @@ -1,119 +1,119 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include "PluginList.h" -#include - -CPluginList::CPluginList(bool bAutoFill /* = true */) : -m_PluginDir(g_Settings->LoadStringVal(Directory_Plugin), "") -{ - if (bAutoFill) - { - LoadList(); - } -} - -CPluginList::~CPluginList() -{ -} - -int CPluginList::GetPluginCount() const -{ - return m_PluginList.size(); -} - -const CPluginList::PLUGIN * CPluginList::GetPluginInfo(int indx) const -{ - if (indx < 0 || indx >= (int)m_PluginList.size()) - { - return NULL; - } - return &m_PluginList[indx]; -} - -bool CPluginList::LoadList() -{ - WriteTrace(TraceUserInterface, TraceDebug, "Start"); - m_PluginList.clear(); - AddPluginFromDir(m_PluginDir); - WriteTrace(TraceUserInterface, TraceDebug, "Done"); - return true; -} - -void CPluginList::AddPluginFromDir(CPath Dir) -{ - Dir.SetNameExtension("*.*"); - if (Dir.FindFirst(_A_SUBDIR)) - { - do - { - AddPluginFromDir(Dir); - } while (Dir.FindNext()); - Dir.UpDirectory(); - } - - Dir.SetNameExtension("*.dll"); - if (Dir.FindFirst()) - { - HMODULE hLib = NULL; - do - { - if (hLib) - { - FreeLibrary(hLib); - hLib = NULL; - } - - //UINT LastErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS ); - WriteTrace(TraceUserInterface, TraceDebug, "loading %s", (LPCSTR)Dir); - hLib = LoadLibrary(Dir); - //SetErrorMode(LastErrorMode); - - if (hLib == NULL) - { - DWORD LoadError = GetLastError(); - WriteTrace(TraceUserInterface, TraceDebug, "failed to loadi %s (error: %d)", (LPCSTR)Dir, LoadError); - continue; - } - - void(CALL *GetDllInfo) (PLUGIN_INFO * PluginInfo); - GetDllInfo = (void(CALL *)(PLUGIN_INFO *))GetProcAddress(hLib, "GetDllInfo"); - if (GetDllInfo == NULL) - { - continue; - } - - PLUGIN Plugin = { 0 }; - Plugin.Info.MemoryBswaped = true; - GetDllInfo(&Plugin.Info); - if (!CPlugin::ValidPluginVersion(Plugin.Info)) - { - continue; - } - - Plugin.FullPath = Dir; - Plugin.FileName = stdstr((const char *)Dir).substr(strlen(m_PluginDir)); - - if (GetProcAddress(hLib, "DllAbout") != NULL) - { - Plugin.AboutFunction = true; - } - m_PluginList.push_back(Plugin); - } while (Dir.FindNext()); - - if (hLib) - { - FreeLibrary(hLib); - hLib = NULL; - } - } +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include "PluginList.h" +#include + +CPluginList::CPluginList(bool bAutoFill /* = true */) : +m_PluginDir(g_Settings->LoadStringVal(Directory_Plugin), "") +{ + if (bAutoFill) + { + LoadList(); + } +} + +CPluginList::~CPluginList() +{ +} + +int CPluginList::GetPluginCount() const +{ + return m_PluginList.size(); +} + +const CPluginList::PLUGIN * CPluginList::GetPluginInfo(int indx) const +{ + if (indx < 0 || indx >= (int)m_PluginList.size()) + { + return NULL; + } + return &m_PluginList[indx]; +} + +bool CPluginList::LoadList() +{ + WriteTrace(TraceUserInterface, TraceDebug, "Start"); + m_PluginList.clear(); + AddPluginFromDir(m_PluginDir); + WriteTrace(TraceUserInterface, TraceDebug, "Done"); + return true; +} + +void CPluginList::AddPluginFromDir(CPath Dir) +{ + Dir.SetNameExtension("*.*"); + if (Dir.FindFirst(_A_SUBDIR)) + { + do + { + AddPluginFromDir(Dir); + } while (Dir.FindNext()); + Dir.UpDirectory(); + } + + Dir.SetNameExtension("*.dll"); + if (Dir.FindFirst()) + { + HMODULE hLib = NULL; + do + { + if (hLib) + { + FreeLibrary(hLib); + hLib = NULL; + } + + //UINT LastErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS ); + WriteTrace(TraceUserInterface, TraceDebug, "loading %s", (LPCSTR)Dir); + hLib = LoadLibrary(Dir); + //SetErrorMode(LastErrorMode); + + if (hLib == NULL) + { + DWORD LoadError = GetLastError(); + WriteTrace(TraceUserInterface, TraceDebug, "failed to loadi %s (error: %d)", (LPCSTR)Dir, LoadError); + continue; + } + + void(CALL *GetDllInfo) (PLUGIN_INFO * PluginInfo); + GetDllInfo = (void(CALL *)(PLUGIN_INFO *))GetProcAddress(hLib, "GetDllInfo"); + if (GetDllInfo == NULL) + { + continue; + } + + PLUGIN Plugin = { 0 }; + Plugin.Info.MemoryBswaped = true; + GetDllInfo(&Plugin.Info); + if (!CPlugin::ValidPluginVersion(Plugin.Info)) + { + continue; + } + + Plugin.FullPath = Dir; + Plugin.FileName = stdstr((const char *)Dir).substr(strlen(m_PluginDir)); + + if (GetProcAddress(hLib, "DllAbout") != NULL) + { + Plugin.AboutFunction = true; + } + m_PluginList.push_back(Plugin); + } while (Dir.FindNext()); + + if (hLib) + { + FreeLibrary(hLib); + hLib = NULL; + } + } } \ No newline at end of file diff --git a/Source/Project64/Plugins/PluginList.h b/Source/Project64/Plugins/PluginList.h index 2a58014ac..6ddc7ab48 100644 --- a/Source/Project64/Plugins/PluginList.h +++ b/Source/Project64/Plugins/PluginList.h @@ -1,41 +1,41 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CPluginList -{ -public: - typedef struct - { - PLUGIN_INFO Info; - bool AboutFunction; - CPath FullPath; - stdstr FileName; - } PLUGIN; - -public: - CPluginList(bool bAutoFill = true); - ~CPluginList(); - - bool LoadList(void); - int GetPluginCount(void) const; - const PLUGIN * GetPluginInfo(int indx) const; - -private: - typedef std::vector PluginList; - - PluginList m_PluginList; - CPath m_PluginDir; - - void AddPluginFromDir(CPath Dir); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CPluginList +{ +public: + typedef struct + { + PLUGIN_INFO Info; + bool AboutFunction; + CPath FullPath; + stdstr FileName; + } PLUGIN; + +public: + CPluginList(bool bAutoFill = true); + ~CPluginList(); + + bool LoadList(void); + int GetPluginCount(void) const; + const PLUGIN * GetPluginInfo(int indx) const; + +private: + typedef std::vector PluginList; + + PluginList m_PluginList; + CPath m_PluginDir; + + void AddPluginFromDir(CPath Dir); +}; diff --git a/Source/Project64/Project64.dsp b/Source/Project64/Project64.dsp index cf79ed5bd..4ee58a90b 100644 --- a/Source/Project64/Project64.dsp +++ b/Source/Project64/Project64.dsp @@ -1,1384 +1,1384 @@ -# Microsoft Developer Studio Project File - Name="Project64" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=Project64 - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Project64.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Project64.mak" CFG="Project64 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Project64 - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Project64 - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE "Project64 - Win32 External Release" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/Project64/Project 64 1.7", RCBAAAAA" -# PROP Scc_LocalPath ".." -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Project64 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "../../Bin/Release" -# PROP Intermediate_Dir "../../Build/Project64/Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "../" /I "./" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0xc09 /d "NDEBUG" -# ADD RSC /l 0xc09 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 - -!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "../../Bin/Debug" -# PROP Intermediate_Dir "../../Build/Project64/Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../" /I "./" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0xc09 /d "_DEBUG" -# ADD RSC /l 0xc09 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# SUBTRACT LINK32 /map - -!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Project64___Win32_External_Release" -# PROP BASE Intermediate_Dir "Project64___Win32_External_Release" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "../../Bin/External" -# PROP Intermediate_Dir "../../Build/Project64/External" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /I "./" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "EXTERNAL_RELEASE" /Yu"stdafx.h" /FD /EHa /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0xc09 /d "NDEBUG" -# ADD RSC /l 0xc09 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"..\Bin\Release\Project64.exe" -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 - -!ENDIF - -# Begin Target - -# Name "Project64 - Win32 Release" -# Name "Project64 - Win32 Debug" -# Name "Project64 - Win32 External Release" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Group "Settings Files" - -# PROP Default_Filter "" -# Begin Group "Setting Types Files" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-Application.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-ApplicationIndex.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-Cheats.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-GameSetting.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-GameSettingIndex.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBCpuType.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBOnOff.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBRamSize.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBSaveChip.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBYesNo.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RelativePath.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RomDatabase.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RomDatabaseIndex.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-SelectedDirectory.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-TempBool.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-TempNumber.cpp" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-TempString.cpp" -# End Source File -# End Group -# Begin Source File - -SOURCE="Settings\N64System Settings.cpp" -# End Source File -# Begin Source File - -SOURCE="Settings\Notification Settings.cpp" -# End Source File -# Begin Source File - -SOURCE="Settings\Recompiler Settings.cpp" -# End Source File -# Begin Source File - -SOURCE="Settings\Settings Class.cpp" -# End Source File -# End Group -# Begin Group "User Interface Source" - -# PROP Default_Filter "" -# Begin Group "Settings Source" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Advanced Options.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Directories.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game - General.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game - Plugin.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game - Recompiler.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game - Status.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game Browser.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Keyboard Shortcuts.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Options.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Plugin.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page.cpp" -# End Source File -# End Group -# Begin Group "WTL Controls Source" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\User Interface\WTL Controls\ModifiedEditBox.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\WTL Controls\PartialGroupBox.cpp" -# End Source File -# End Group -# Begin Group "Debugger Source" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger - Memory Dump.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger - Memory Search.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger - TLB.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger - View Memory.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger.cpp" -# End Source File -# End Group -# Begin Source File - -SOURCE="User Interface\Frame Per Second Class.cpp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Gui Class.cpp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Main Menu Class.cpp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Menu Class.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\MenuShortCuts.cpp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Notification Class.cpp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Rom Browser Class.cpp" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings Config.cpp" -# End Source File -# End Group -# Begin Group "Multilanguage Source" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="Multilanguage\Language Class.cpp" -# End Source File -# End Group -# Begin Group "N64 System Source" - -# PROP Default_Filter "" -# Begin Group "Mips Source" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="N64 System\Mips\Audio.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Dma.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Eeprom.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\FlashRam.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\Memory Labels Class.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Memory Virtual Mem.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\Memory.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\OpCode Analysis Class.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\OpCode Class.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Pif Ram.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\Register Class.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Sram.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\System Events.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\System Timing.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\TLB class.cpp" -# End Source File -# End Group -# Begin Group "C Core Source" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\N64 System\C Core\BreakPoints.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\C Core Interface.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\C Core\C main.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\C Core\CPU Log.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\C Core\Logging.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\C Core\Mempak.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\C Core\r4300i Commands.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\C Core\r4300i Registers.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\C Core\Win32Timer.cpp" -# End Source File -# End Group -# Begin Group "Recompiler Files" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Code Block.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Code Section.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Delay Slot Map Class.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Function Info.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Function Map Class.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Jump Info.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Recompiler Class.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Recompiler Memory.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Recompiler Ops.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Reg Info.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Section Info.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\X86ops.cpp" -# End Source File -# End Group -# Begin Group "Interpreter Files" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\N64 System\Interpreter\Interpreter CPU.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Interpreter\Interpreter Ops 32.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Interpreter\Interpreter Ops.cpp" -# End Source File -# End Group -# Begin Source File - -SOURCE="N64 System\Cheat Class.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\N64 Class.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\N64 Rom Class.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Profiling Class.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Rom Information Class.cpp" -# End Source File -# Begin Source File - -SOURCE="N64 System\Speed Limiter Class.cpp" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\System Globals.cpp" -# End Source File -# End Group -# Begin Group "Plugin Source" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="Plugins\Audio Plugin.cpp" -# End Source File -# Begin Source File - -SOURCE="Plugins\Controller Plugin.cpp" -# End Source File -# Begin Source File - -SOURCE="Plugins\GFX plugin.cpp" -# End Source File -# Begin Source File - -SOURCE="Plugins\Plugin Class.cpp" -# End Source File -# Begin Source File - -SOURCE="Plugins\Plugin List.cpp" -# End Source File -# Begin Source File - -SOURCE="Plugins\RSP Plugin.cpp" -# End Source File -# End Group -# Begin Group "3rd Party Source" - -# PROP Default_Filter "" -# Begin Group "ZLib Source" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="3rd Party\zlib\UNZIP.C" - -!IF "$(CFG)" == "Project64 - Win32 Release" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE="3rd Party\zlib\zip.c" - -!IF "$(CFG)" == "Project64 - Win32 Release" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" - -!ENDIF - -# End Source File -# End Group -# Begin Source File - -SOURCE="3rd Party\7zip.cpp" - -!IF "$(CFG)" == "Project64 - Win32 Release" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE="3rd Party\Processor Info.cpp" - -!IF "$(CFG)" == "Project64 - Win32 Release" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" - -!ENDIF - -# End Source File -# End Group -# Begin Source File - -SOURCE="Settings\Gui Settings.cpp" -# End Source File -# Begin Source File - -SOURCE=main.cpp -# End Source File -# Begin Source File - -SOURCE=.\stdafx.cpp -# ADD CPP /Yc"stdafx.h" -# End Source File -# Begin Source File - -SOURCE=ValidateBinary.cpp -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE="User Interface\Bitmaps\AboutScreen.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\AboutScreenBottom.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\AboutScreenMiddle.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\AboutScreenTop.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\CloseNormal.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Icons\divider.cur" -# End Source File -# Begin Source File - -SOURCE="User Interface\Icons\hand.cur" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\LangOK.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\LangOK_down.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Icons\left.ico" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\ListItems.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\pj64.BMP" -# End Source File -# Begin Source File - -SOURCE="User Interface\Icons\PJ64.ICO" -# End Source File -# Begin Source File - -SOURCE="User Interface\Icons\right.ico" -# End Source File -# Begin Source File - -SOURCE="User Interface\Bitmaps\tri-state.bmp" -# End Source File -# Begin Source File - -SOURCE="User Interface\UI Resources.rc" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Group "Settings Headers" - -# PROP Default_Filter "" -# Begin Group "Setting Types Header" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-Application.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-ApplicationIndex.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-Base.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-Cheats.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-GameSetting.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-GameSettingIndex.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBCpuType.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBOnOff.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBRamSize.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBSaveChip.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RDBYesNo.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RelativePath.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RomDatabase.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-RomDatabaseIndex.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-SelectedDirectory.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-TempBool.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-TempNumber.h" -# End Source File -# Begin Source File - -SOURCE=".\Settings\SettingType\SettingsType-TempString.h" -# End Source File -# End Group -# Begin Source File - -SOURCE="Settings\Gui Settings.h" -# End Source File -# Begin Source File - -SOURCE="Settings\N64System Settings.h" -# End Source File -# Begin Source File - -SOURCE="Settings\Notification Settings.h" -# End Source File -# Begin Source File - -SOURCE="Settings\Recompiler Settings.h" -# End Source File -# Begin Source File - -SOURCE="Settings\Settings Class.h" -# End Source File -# End Group -# Begin Group "User Interface Headers" - -# PROP Default_Filter "" -# Begin Group "Settings Header" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Advanced Options.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Directories.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game - General.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game - Plugin.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game - Recompiler.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game - Status.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Game Browser.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Keyboard Shortcuts.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Options.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page - Plugin.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\Settings\Settings Page.h" -# End Source File -# End Group -# Begin Group "WTL Controls Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\User Interface\WTL Controls\ModifiedCheckBox.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\WTL Controls\ModifiedComboBox.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\WTL Controls\ModifiedEditBox.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\WTL Controls\numberctrl.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\WTL Controls\PartialGroupBox.h" -# End Source File -# End Group -# Begin Source File - -SOURCE="User Interface\Frame Per Second Class.h" -# End Source File -# Begin Source File - -SOURCE="User Interface\Gui Class.h" -# End Source File -# Begin Source File - -SOURCE="User Interface\Log Class.h" -# End Source File -# Begin Source File - -SOURCE="User Interface\Main Menu Class.h" -# End Source File -# Begin Source File - -SOURCE="User Interface\Menu Class.h" -# End Source File -# Begin Source File - -SOURCE=".\User Interface\MenuShortCuts.h" -# End Source File -# Begin Source File - -SOURCE="User Interface\Notification Class.h" -# End Source File -# Begin Source File - -SOURCE="User Interface\resource.h" -# End Source File -# Begin Source File - -SOURCE="User Interface\Rom Browser.h" -# End Source File -# End Group -# Begin Group "Multilanguage Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="Multilanguage\Language Class.h" -# End Source File -# End Group -# Begin Group "N64 System Headers" - -# PROP Default_Filter "" -# Begin Group "Mips Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="N64 System\Mips\Audio.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Dma.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Eeprom.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Exception.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\FlashRam.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\Memory Class.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\Memory Labels Class.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Memory Virtual Mem.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\OpCode Analysis Class.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\OpCode Class.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\OpCode.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Pif Ram.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\Register Class.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\Sram.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\System Events.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\System Timing.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Mips\TLB Class.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Mips\TranslateVaddr.h" -# End Source File -# End Group -# Begin Group "C Core Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="N64 System\C Core\BreakPoints.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\C Core Interface.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\Core Settings.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\CPU Log.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\CPU.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\Debugger.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\Eeprom.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\Flashram.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\Logging.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\Main.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\MEMPAK.H" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\r4300i Commands.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\r4300i Memory.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\r4300i Registers.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\C Core\Win32Timer.h" -# End Source File -# End Group -# Begin Group "Debugger Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger - Memory Dump.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger - Memory Search.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger - TLB.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Debugger\Debugger - View Memory.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Debugger\debugger.h" -# End Source File -# End Group -# Begin Group "Recompiler Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Code Block.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Code Section.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Delay Slot Map Class.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Exit Info.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Function Info.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Function Map Class.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Jump Info.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Recompiler Class.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Recompiler Memory.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Recompiler Ops.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\Reg Info.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Recompiler\Section Info.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Recompiler\X86ops.h" -# End Source File -# End Group -# Begin Group "Interpreter Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=".\N64 System\Interpreter\Interpreter CPU.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Interpreter\Interpreter Ops 32.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\Interpreter\Interpreter Ops.h" -# End Source File -# End Group -# Begin Source File - -SOURCE="N64 System\Cheat Class.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\N64 Class.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\N64 Rom Class.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\N64 Types.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Profiling Class.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Rom Information Class.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Speed Limiter Class.h" -# End Source File -# Begin Source File - -SOURCE=".\N64 System\System Globals.h" -# End Source File -# Begin Source File - -SOURCE="N64 System\Types.h" -# End Source File -# End Group -# Begin Group "Plugin Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="Plugins\Audio Plugin.h" -# End Source File -# Begin Source File - -SOURCE="Plugins\Controller Plugin.h" -# End Source File -# Begin Source File - -SOURCE="Plugins\GFX plugin.h" -# End Source File -# Begin Source File - -SOURCE="Plugins\Plugin Class.h" -# End Source File -# Begin Source File - -SOURCE="Plugins\Plugin List.h" -# End Source File -# Begin Source File - -SOURCE="Plugins\RSP Plugin.h" -# End Source File -# End Group -# Begin Group "3rd Party Headers" - -# PROP Default_Filter "" -# Begin Group "HTML Help" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="3rd Party\HTML Help\HTMLHELP.H" -# End Source File -# End Group -# Begin Group "Zlib Headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE="3rd Party\zlib\UNZIP.H" -# End Source File -# Begin Source File - -SOURCE="3rd Party\zlib\ZCONF.H" -# End Source File -# Begin Source File - -SOURCE="3rd Party\zlib\zip.h" -# End Source File -# Begin Source File - -SOURCE="3rd Party\zlib\ZLIB.H" -# End Source File -# End Group -# Begin Source File - -SOURCE="3rd Party\7zip.h" -# End Source File -# Begin Source File - -SOURCE="3rd Party\Processor Info.h" -# End Source File -# Begin Source File - -SOURCE="3rd Party\zip.h" -# End Source File -# End Group -# Begin Source File - -SOURCE="C:\Program Files\Microsoft Visual Studio\VC98\ATL\Include\ATLWIN.H" -# End Source File -# Begin Source File - -SOURCE=Multilanguage.h -# End Source File -# Begin Source File - -SOURCE="N64 System.h" -# End Source File -# Begin Source File - -SOURCE=Plugin.h -# End Source File -# Begin Source File - -SOURCE=Settings.h -# End Source File -# Begin Source File - -SOURCE=.\stdafx.h -# End Source File -# Begin Source File - -SOURCE="User Interface.h" -# End Source File -# Begin Source File - -SOURCE="Validate Binary.h" -# End Source File -# Begin Source File - -SOURCE=".\WTL App.h" -# End Source File -# End Group -# Begin Group "Logs" - -# PROP Default_Filter "" -# Begin Group "Debug" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\Bin\Debug\CPUoutput.log -# End Source File -# Begin Source File - -SOURCE=..\Bin\Debug\Project64.log -# End Source File -# Begin Source File - -SOURCE="..\Bin\Debug\Sync Errors.txt" -# End Source File -# End Group -# Begin Group "Release" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\Bin\Release\CPUoutput.log -# End Source File -# Begin Source File - -SOURCE=..\Bin\Release\Project64.log -# End Source File -# Begin Source File - -SOURCE="..\Bin\Release\Sync Errors.txt" -# End Source File -# End Group -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="Project64" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=Project64 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Project64.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Project64.mak" CFG="Project64 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Project64 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Project64 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "Project64 - Win32 External Release" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName ""$/Project64/Project 64 1.7", RCBAAAAA" +# PROP Scc_LocalPath ".." +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Project64 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../../Bin/Release" +# PROP Intermediate_Dir "../../Build/Project64/Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "../" /I "./" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc09 /d "NDEBUG" +# ADD RSC /l 0xc09 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 + +!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "../../Bin/Debug" +# PROP Intermediate_Dir "../../Build/Project64/Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../" /I "./" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc09 /d "_DEBUG" +# ADD RSC /l 0xc09 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /map + +!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Project64___Win32_External_Release" +# PROP BASE Intermediate_Dir "Project64___Win32_External_Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../../Bin/External" +# PROP Intermediate_Dir "../../Build/Project64/External" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /I "./" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "EXTERNAL_RELEASE" /Yu"stdafx.h" /FD /EHa /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc09 /d "NDEBUG" +# ADD RSC /l 0xc09 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"..\Bin\Release\Project64.exe" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 + +!ENDIF + +# Begin Target + +# Name "Project64 - Win32 Release" +# Name "Project64 - Win32 Debug" +# Name "Project64 - Win32 External Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "Settings Files" + +# PROP Default_Filter "" +# Begin Group "Setting Types Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-Application.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-ApplicationIndex.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-Cheats.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-GameSetting.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-GameSettingIndex.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBCpuType.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBOnOff.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBRamSize.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBSaveChip.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBYesNo.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RelativePath.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RomDatabase.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RomDatabaseIndex.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-SelectedDirectory.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-TempBool.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-TempNumber.cpp" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-TempString.cpp" +# End Source File +# End Group +# Begin Source File + +SOURCE="Settings\N64System Settings.cpp" +# End Source File +# Begin Source File + +SOURCE="Settings\Notification Settings.cpp" +# End Source File +# Begin Source File + +SOURCE="Settings\Recompiler Settings.cpp" +# End Source File +# Begin Source File + +SOURCE="Settings\Settings Class.cpp" +# End Source File +# End Group +# Begin Group "User Interface Source" + +# PROP Default_Filter "" +# Begin Group "Settings Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Advanced Options.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Directories.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game - General.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game - Plugin.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game - Recompiler.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game - Status.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game Browser.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Keyboard Shortcuts.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Options.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Plugin.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page.cpp" +# End Source File +# End Group +# Begin Group "WTL Controls Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\User Interface\WTL Controls\ModifiedEditBox.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\WTL Controls\PartialGroupBox.cpp" +# End Source File +# End Group +# Begin Group "Debugger Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger - Memory Dump.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger - Memory Search.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger - TLB.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger - View Memory.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger.cpp" +# End Source File +# End Group +# Begin Source File + +SOURCE="User Interface\Frame Per Second Class.cpp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Gui Class.cpp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Main Menu Class.cpp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Menu Class.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\MenuShortCuts.cpp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Notification Class.cpp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Rom Browser Class.cpp" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings Config.cpp" +# End Source File +# End Group +# Begin Group "Multilanguage Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="Multilanguage\Language Class.cpp" +# End Source File +# End Group +# Begin Group "N64 System Source" + +# PROP Default_Filter "" +# Begin Group "Mips Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="N64 System\Mips\Audio.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Dma.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Eeprom.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\FlashRam.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\Memory Labels Class.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Memory Virtual Mem.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\Memory.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\OpCode Analysis Class.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\OpCode Class.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Pif Ram.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\Register Class.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Sram.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\System Events.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\System Timing.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\TLB class.cpp" +# End Source File +# End Group +# Begin Group "C Core Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\N64 System\C Core\BreakPoints.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\C Core Interface.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\C Core\C main.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\C Core\CPU Log.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\C Core\Logging.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\C Core\Mempak.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\C Core\r4300i Commands.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\C Core\r4300i Registers.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\C Core\Win32Timer.cpp" +# End Source File +# End Group +# Begin Group "Recompiler Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Code Block.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Code Section.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Delay Slot Map Class.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Function Info.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Function Map Class.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Jump Info.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Recompiler Class.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Recompiler Memory.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Recompiler Ops.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Reg Info.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Section Info.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\X86ops.cpp" +# End Source File +# End Group +# Begin Group "Interpreter Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\N64 System\Interpreter\Interpreter CPU.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Interpreter\Interpreter Ops 32.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Interpreter\Interpreter Ops.cpp" +# End Source File +# End Group +# Begin Source File + +SOURCE="N64 System\Cheat Class.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\N64 Class.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\N64 Rom Class.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Profiling Class.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Rom Information Class.cpp" +# End Source File +# Begin Source File + +SOURCE="N64 System\Speed Limiter Class.cpp" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\System Globals.cpp" +# End Source File +# End Group +# Begin Group "Plugin Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="Plugins\Audio Plugin.cpp" +# End Source File +# Begin Source File + +SOURCE="Plugins\Controller Plugin.cpp" +# End Source File +# Begin Source File + +SOURCE="Plugins\GFX plugin.cpp" +# End Source File +# Begin Source File + +SOURCE="Plugins\Plugin Class.cpp" +# End Source File +# Begin Source File + +SOURCE="Plugins\Plugin List.cpp" +# End Source File +# Begin Source File + +SOURCE="Plugins\RSP Plugin.cpp" +# End Source File +# End Group +# Begin Group "3rd Party Source" + +# PROP Default_Filter "" +# Begin Group "ZLib Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="3rd Party\zlib\UNZIP.C" + +!IF "$(CFG)" == "Project64 - Win32 Release" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE="3rd Party\zlib\zip.c" + +!IF "$(CFG)" == "Project64 - Win32 Release" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE="3rd Party\7zip.cpp" + +!IF "$(CFG)" == "Project64 - Win32 Release" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE="3rd Party\Processor Info.cpp" + +!IF "$(CFG)" == "Project64 - Win32 Release" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Project64 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Project64 - Win32 External Release" + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE="Settings\Gui Settings.cpp" +# End Source File +# Begin Source File + +SOURCE=main.cpp +# End Source File +# Begin Source File + +SOURCE=.\stdafx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=ValidateBinary.cpp +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE="User Interface\Bitmaps\AboutScreen.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\AboutScreenBottom.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\AboutScreenMiddle.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\AboutScreenTop.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\CloseNormal.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Icons\divider.cur" +# End Source File +# Begin Source File + +SOURCE="User Interface\Icons\hand.cur" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\LangOK.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\LangOK_down.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Icons\left.ico" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\ListItems.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\pj64.BMP" +# End Source File +# Begin Source File + +SOURCE="User Interface\Icons\PJ64.ICO" +# End Source File +# Begin Source File + +SOURCE="User Interface\Icons\right.ico" +# End Source File +# Begin Source File + +SOURCE="User Interface\Bitmaps\tri-state.bmp" +# End Source File +# Begin Source File + +SOURCE="User Interface\UI Resources.rc" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Group "Settings Headers" + +# PROP Default_Filter "" +# Begin Group "Setting Types Header" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-Application.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-ApplicationIndex.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-Base.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-Cheats.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-GameSetting.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-GameSettingIndex.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBCpuType.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBOnOff.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBRamSize.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBSaveChip.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RDBYesNo.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RelativePath.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RomDatabase.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-RomDatabaseIndex.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-SelectedDirectory.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-TempBool.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-TempNumber.h" +# End Source File +# Begin Source File + +SOURCE=".\Settings\SettingType\SettingsType-TempString.h" +# End Source File +# End Group +# Begin Source File + +SOURCE="Settings\Gui Settings.h" +# End Source File +# Begin Source File + +SOURCE="Settings\N64System Settings.h" +# End Source File +# Begin Source File + +SOURCE="Settings\Notification Settings.h" +# End Source File +# Begin Source File + +SOURCE="Settings\Recompiler Settings.h" +# End Source File +# Begin Source File + +SOURCE="Settings\Settings Class.h" +# End Source File +# End Group +# Begin Group "User Interface Headers" + +# PROP Default_Filter "" +# Begin Group "Settings Header" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Advanced Options.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Directories.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game - General.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game - Plugin.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game - Recompiler.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game - Status.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Game Browser.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Keyboard Shortcuts.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Options.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page - Plugin.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\Settings\Settings Page.h" +# End Source File +# End Group +# Begin Group "WTL Controls Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\User Interface\WTL Controls\ModifiedCheckBox.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\WTL Controls\ModifiedComboBox.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\WTL Controls\ModifiedEditBox.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\WTL Controls\numberctrl.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\WTL Controls\PartialGroupBox.h" +# End Source File +# End Group +# Begin Source File + +SOURCE="User Interface\Frame Per Second Class.h" +# End Source File +# Begin Source File + +SOURCE="User Interface\Gui Class.h" +# End Source File +# Begin Source File + +SOURCE="User Interface\Log Class.h" +# End Source File +# Begin Source File + +SOURCE="User Interface\Main Menu Class.h" +# End Source File +# Begin Source File + +SOURCE="User Interface\Menu Class.h" +# End Source File +# Begin Source File + +SOURCE=".\User Interface\MenuShortCuts.h" +# End Source File +# Begin Source File + +SOURCE="User Interface\Notification Class.h" +# End Source File +# Begin Source File + +SOURCE="User Interface\resource.h" +# End Source File +# Begin Source File + +SOURCE="User Interface\Rom Browser.h" +# End Source File +# End Group +# Begin Group "Multilanguage Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="Multilanguage\Language Class.h" +# End Source File +# End Group +# Begin Group "N64 System Headers" + +# PROP Default_Filter "" +# Begin Group "Mips Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="N64 System\Mips\Audio.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Dma.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Eeprom.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Exception.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\FlashRam.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\Memory Class.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\Memory Labels Class.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Memory Virtual Mem.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\OpCode Analysis Class.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\OpCode Class.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\OpCode.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Pif Ram.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\Register Class.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\Sram.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\System Events.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\System Timing.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Mips\TLB Class.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Mips\TranslateVaddr.h" +# End Source File +# End Group +# Begin Group "C Core Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="N64 System\C Core\BreakPoints.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\C Core Interface.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\Core Settings.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\CPU Log.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\CPU.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\Debugger.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\Eeprom.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\Flashram.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\Logging.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\Main.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\MEMPAK.H" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\r4300i Commands.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\r4300i Memory.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\r4300i Registers.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\C Core\Win32Timer.h" +# End Source File +# End Group +# Begin Group "Debugger Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger - Memory Dump.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger - Memory Search.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger - TLB.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Debugger\Debugger - View Memory.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Debugger\debugger.h" +# End Source File +# End Group +# Begin Group "Recompiler Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Code Block.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Code Section.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Delay Slot Map Class.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Exit Info.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Function Info.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Function Map Class.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Jump Info.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Recompiler Class.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Recompiler Memory.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Recompiler Ops.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\Reg Info.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Recompiler\Section Info.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Recompiler\X86ops.h" +# End Source File +# End Group +# Begin Group "Interpreter Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\N64 System\Interpreter\Interpreter CPU.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Interpreter\Interpreter Ops 32.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\Interpreter\Interpreter Ops.h" +# End Source File +# End Group +# Begin Source File + +SOURCE="N64 System\Cheat Class.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\N64 Class.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\N64 Rom Class.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\N64 Types.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Profiling Class.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Rom Information Class.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Speed Limiter Class.h" +# End Source File +# Begin Source File + +SOURCE=".\N64 System\System Globals.h" +# End Source File +# Begin Source File + +SOURCE="N64 System\Types.h" +# End Source File +# End Group +# Begin Group "Plugin Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="Plugins\Audio Plugin.h" +# End Source File +# Begin Source File + +SOURCE="Plugins\Controller Plugin.h" +# End Source File +# Begin Source File + +SOURCE="Plugins\GFX plugin.h" +# End Source File +# Begin Source File + +SOURCE="Plugins\Plugin Class.h" +# End Source File +# Begin Source File + +SOURCE="Plugins\Plugin List.h" +# End Source File +# Begin Source File + +SOURCE="Plugins\RSP Plugin.h" +# End Source File +# End Group +# Begin Group "3rd Party Headers" + +# PROP Default_Filter "" +# Begin Group "HTML Help" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="3rd Party\HTML Help\HTMLHELP.H" +# End Source File +# End Group +# Begin Group "Zlib Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE="3rd Party\zlib\UNZIP.H" +# End Source File +# Begin Source File + +SOURCE="3rd Party\zlib\ZCONF.H" +# End Source File +# Begin Source File + +SOURCE="3rd Party\zlib\zip.h" +# End Source File +# Begin Source File + +SOURCE="3rd Party\zlib\ZLIB.H" +# End Source File +# End Group +# Begin Source File + +SOURCE="3rd Party\7zip.h" +# End Source File +# Begin Source File + +SOURCE="3rd Party\Processor Info.h" +# End Source File +# Begin Source File + +SOURCE="3rd Party\zip.h" +# End Source File +# End Group +# Begin Source File + +SOURCE="C:\Program Files\Microsoft Visual Studio\VC98\ATL\Include\ATLWIN.H" +# End Source File +# Begin Source File + +SOURCE=Multilanguage.h +# End Source File +# Begin Source File + +SOURCE="N64 System.h" +# End Source File +# Begin Source File + +SOURCE=Plugin.h +# End Source File +# Begin Source File + +SOURCE=Settings.h +# End Source File +# Begin Source File + +SOURCE=.\stdafx.h +# End Source File +# Begin Source File + +SOURCE="User Interface.h" +# End Source File +# Begin Source File + +SOURCE="Validate Binary.h" +# End Source File +# Begin Source File + +SOURCE=".\WTL App.h" +# End Source File +# End Group +# Begin Group "Logs" + +# PROP Default_Filter "" +# Begin Group "Debug" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Bin\Debug\CPUoutput.log +# End Source File +# Begin Source File + +SOURCE=..\Bin\Debug\Project64.log +# End Source File +# Begin Source File + +SOURCE="..\Bin\Debug\Sync Errors.txt" +# End Source File +# End Group +# Begin Group "Release" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Bin\Release\CPUoutput.log +# End Source File +# Begin Source File + +SOURCE=..\Bin\Release\Project64.log +# End Source File +# Begin Source File + +SOURCE="..\Bin\Release\Sync Errors.txt" +# End Source File +# End Group +# End Group +# End Target +# End Project diff --git a/Source/Project64/Project64.vcxproj b/Source/Project64/Project64.vcxproj index 62f561915..25c9aded3 100644 --- a/Source/Project64/Project64.vcxproj +++ b/Source/Project64/Project64.vcxproj @@ -1,154 +1,154 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {7E534C8E-1ACE-4A88-8807-39A11ED4DA18} - Project64 - - - Application - - - - - - - - - - Windows - 5.01 - 5.02 - 1 - false - - - true - - - - - - - - - - - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {3326e128-33af-422c-bb7c-67cc6b915610} - false - - - {731bd205-2826-4631-b7af-117658e88dbc} - false - - - {b4a4b994-9111-42b1-93c2-6f1ca8bc4421} - false - - - {00c7b43a-ded7-4df0-b072-9a5783ef866d} - - - - - - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {7E534C8E-1ACE-4A88-8807-39A11ED4DA18} + Project64 + + + Application + + + + + + + + + + Windows + 5.01 + 5.02 + 1 + false + + + true + + + + + + + + + + + + + + + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {3326e128-33af-422c-bb7c-67cc6b915610} + false + + + {731bd205-2826-4631-b7af-117658e88dbc} + false + + + {b4a4b994-9111-42b1-93c2-6f1ca8bc4421} + false + + + {00c7b43a-ded7-4df0-b072-9a5783ef866d} + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/Project64/Project64.vcxproj.filters b/Source/Project64/Project64.vcxproj.filters index 646d3f872..2cb394a3f 100644 --- a/Source/Project64/Project64.vcxproj.filters +++ b/Source/Project64/Project64.vcxproj.filters @@ -1,303 +1,303 @@ - - - - - {994eee48-3b61-4493-9a7f-6340a5a47175} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {60e2fd87-7b6b-4147-82fe-e12516efe43c} - - - {7b81a6a8-b20b-464e-8184-864886bb00fd} - - - {bbef87b7-814a-4c87-9713-a07a2de577d4} - - - {19f68e68-7068-4a3c-a11d-c3ff48fe78b2} - - - {89244064-68f5-44d9-9021-7a592d910e43} - - - {94e87bf5-3b11-4f61-8a4a-333690ecf588} - - - {242ae4a5-b150-44e6-b31c-027acd6d38b0} - - - {1e3eb4f7-a0b1-4d09-9e50-b5c699f24050} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - {bc88015e-37f7-4320-8aa4-d5043d17a386} - h;hpp;hxx;hm;inl - - - {54e8f51f-d81d-4f8f-b4f1-76584c1b29a5} - - - {81b58fad-f73f-4098-8ebc-ffceaff53478} - - - {838a58e7-e1d2-45d3-bcf0-dcedad19610c} - - - {5531af4d-33bb-4e84-8a55-c971a18ec7bf} - - - {6cfab019-2f8d-4e09-be41-1df513b5a680} - - - {c4249d55-df70-4453-b017-b548514ad094} - - - - - Source Files - - - Source Files\User Interface Source\WTL Controls Source - - - Source Files\User Interface Source\WTL Controls Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\User Interface Source\Settings Source - - - Source Files\Plugin Source - - - Source Files - - - Source Files\User Interface Source - - - Source Files\User Interface Source - - - Source Files\User Interface Source - - - Source Files\User Interface Source - - - Source Files\User Interface Source - - - Source Files\User Interface Source - - - Source Files\User Interface Source - - - Source Files\User Interface Source - - - Source Files\User Interface Source - - - Source Files\User Interface Source\Debugger Source - - - Source Files\User Interface Source\Debugger Source - - - Source Files\User Interface Source\Debugger Source - - - Source Files\User Interface Source\Debugger Source - - - Source Files\User Interface Source\Debugger Source - - - Source Files\Settings Files - - - Source Files\Settings Files - - - Source Files\Multilanguage Source - - - Source Files\User Interface Source - - - - - Resource Files - - - Header Files\Multilanguage Headers - - - Header Files\N64 System Headers - - - Header Files\N64 System Headers\Debugger Headers - - - Header Files\N64 System Headers\Debugger Headers - - - Header Files\N64 System Headers\Debugger Headers - - - Header Files\N64 System Headers\Debugger Headers - - - Header Files\N64 System Headers\Debugger Headers - - - Header Files\N64 System Headers\Debugger Headers - - - Header Files\N64 System Headers\Debugger Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers - - - Header Files\User Interface Headers\WTL Controls Headers - - - Header Files\User Interface Headers\WTL Controls Headers - - - Header Files\User Interface Headers\WTL Controls Headers - - - Header Files\User Interface Headers\WTL Controls Headers - - - Header Files\User Interface Headers\WTL Controls Headers - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files\User Interface Headers\Settings Header - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files\User Interface Headers - - - - - Resource Files - - - Resource Files - - - - - Resource Files - - - - - Resource Files - - + + + + + {994eee48-3b61-4493-9a7f-6340a5a47175} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {60e2fd87-7b6b-4147-82fe-e12516efe43c} + + + {7b81a6a8-b20b-464e-8184-864886bb00fd} + + + {bbef87b7-814a-4c87-9713-a07a2de577d4} + + + {19f68e68-7068-4a3c-a11d-c3ff48fe78b2} + + + {89244064-68f5-44d9-9021-7a592d910e43} + + + {94e87bf5-3b11-4f61-8a4a-333690ecf588} + + + {242ae4a5-b150-44e6-b31c-027acd6d38b0} + + + {1e3eb4f7-a0b1-4d09-9e50-b5c699f24050} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {bc88015e-37f7-4320-8aa4-d5043d17a386} + h;hpp;hxx;hm;inl + + + {54e8f51f-d81d-4f8f-b4f1-76584c1b29a5} + + + {81b58fad-f73f-4098-8ebc-ffceaff53478} + + + {838a58e7-e1d2-45d3-bcf0-dcedad19610c} + + + {5531af4d-33bb-4e84-8a55-c971a18ec7bf} + + + {6cfab019-2f8d-4e09-be41-1df513b5a680} + + + {c4249d55-df70-4453-b017-b548514ad094} + + + + + Source Files + + + Source Files\User Interface Source\WTL Controls Source + + + Source Files\User Interface Source\WTL Controls Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\User Interface Source\Settings Source + + + Source Files\Plugin Source + + + Source Files + + + Source Files\User Interface Source + + + Source Files\User Interface Source + + + Source Files\User Interface Source + + + Source Files\User Interface Source + + + Source Files\User Interface Source + + + Source Files\User Interface Source + + + Source Files\User Interface Source + + + Source Files\User Interface Source + + + Source Files\User Interface Source + + + Source Files\User Interface Source\Debugger Source + + + Source Files\User Interface Source\Debugger Source + + + Source Files\User Interface Source\Debugger Source + + + Source Files\User Interface Source\Debugger Source + + + Source Files\User Interface Source\Debugger Source + + + Source Files\Settings Files + + + Source Files\Settings Files + + + Source Files\Multilanguage Source + + + Source Files\User Interface Source + + + + + Resource Files + + + Header Files\Multilanguage Headers + + + Header Files\N64 System Headers + + + Header Files\N64 System Headers\Debugger Headers + + + Header Files\N64 System Headers\Debugger Headers + + + Header Files\N64 System Headers\Debugger Headers + + + Header Files\N64 System Headers\Debugger Headers + + + Header Files\N64 System Headers\Debugger Headers + + + Header Files\N64 System Headers\Debugger Headers + + + Header Files\N64 System Headers\Debugger Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers + + + Header Files\User Interface Headers\WTL Controls Headers + + + Header Files\User Interface Headers\WTL Controls Headers + + + Header Files\User Interface Headers\WTL Controls Headers + + + Header Files\User Interface Headers\WTL Controls Headers + + + Header Files\User Interface Headers\WTL Controls Headers + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files\User Interface Headers\Settings Header + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\User Interface Headers + + + + + Resource Files + + + Resource Files + + + + + Resource Files + + + + + Resource Files + + \ No newline at end of file diff --git a/Source/Project64/Settings/GuiSettings.cpp b/Source/Project64/Settings/GuiSettings.cpp index 9eca59014..8003eb37f 100644 --- a/Source/Project64/Settings/GuiSettings.cpp +++ b/Source/Project64/Settings/GuiSettings.cpp @@ -1,43 +1,43 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -int CGuiSettings::m_RefCount = 0; -bool CGuiSettings::m_bCPURunning; -bool CGuiSettings::m_bAutoSleep; - -CGuiSettings::CGuiSettings() -{ - m_RefCount += 1; - if (m_RefCount == 1) - { - g_Settings->RegisterChangeCB(GameRunning_CPU_Running,NULL,RefreshSettings); - g_Settings->RegisterChangeCB(Setting_AutoSleep,NULL,RefreshSettings); - RefreshSettings(NULL); - } -} - -CGuiSettings::~CGuiSettings() -{ - m_RefCount -= 1; - if (m_RefCount == 0) - { - g_Settings->UnregisterChangeCB(GameRunning_CPU_Running,NULL,RefreshSettings); - g_Settings->UnregisterChangeCB(Setting_AutoSleep,NULL,RefreshSettings); - } -} - -void CGuiSettings::RefreshSettings(void *) -{ - m_bCPURunning = g_Settings->LoadBool(GameRunning_CPU_Running); - m_bAutoSleep = g_Settings->LoadBool(Setting_AutoSleep); -} - +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +int CGuiSettings::m_RefCount = 0; +bool CGuiSettings::m_bCPURunning; +bool CGuiSettings::m_bAutoSleep; + +CGuiSettings::CGuiSettings() +{ + m_RefCount += 1; + if (m_RefCount == 1) + { + g_Settings->RegisterChangeCB(GameRunning_CPU_Running,NULL,RefreshSettings); + g_Settings->RegisterChangeCB(Setting_AutoSleep,NULL,RefreshSettings); + RefreshSettings(NULL); + } +} + +CGuiSettings::~CGuiSettings() +{ + m_RefCount -= 1; + if (m_RefCount == 0) + { + g_Settings->UnregisterChangeCB(GameRunning_CPU_Running,NULL,RefreshSettings); + g_Settings->UnregisterChangeCB(Setting_AutoSleep,NULL,RefreshSettings); + } +} + +void CGuiSettings::RefreshSettings(void *) +{ + m_bCPURunning = g_Settings->LoadBool(GameRunning_CPU_Running); + m_bAutoSleep = g_Settings->LoadBool(Setting_AutoSleep); +} + diff --git a/Source/Project64/Settings/GuiSettings.h b/Source/Project64/Settings/GuiSettings.h index 78c76326d..e0c8e7e1e 100644 --- a/Source/Project64/Settings/GuiSettings.h +++ b/Source/Project64/Settings/GuiSettings.h @@ -1,30 +1,30 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CGuiSettings -{ -protected: - CGuiSettings(); - virtual ~CGuiSettings(); - - static inline bool bCPURunning ( void) { return m_bCPURunning; } - static inline bool bAutoSleep ( void) { return m_bAutoSleep; } - -private: - static void RefreshSettings (void *); - - static bool m_bCPURunning; - static bool m_bAutoSleep; - - static int m_RefCount; - -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CGuiSettings +{ +protected: + CGuiSettings(); + virtual ~CGuiSettings(); + + static inline bool bCPURunning ( void) { return m_bCPURunning; } + static inline bool bAutoSleep ( void) { return m_bAutoSleep; } + +private: + static void RefreshSettings (void *); + + static bool m_bCPURunning; + static bool m_bAutoSleep; + + static int m_RefCount; + +}; diff --git a/Source/Project64/Settings/NotificationSettings.cpp b/Source/Project64/Settings/NotificationSettings.cpp index 572798d33..b94460571 100644 --- a/Source/Project64/Settings/NotificationSettings.cpp +++ b/Source/Project64/Settings/NotificationSettings.cpp @@ -1,36 +1,36 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -bool CNotificationSettings::m_bInFullScreen = false; - -CNotificationSettings::CNotificationSettings() -{ -} - -CNotificationSettings::~CNotificationSettings() -{ - if (g_Settings) - { - g_Settings->UnregisterChangeCB(UserInterface_InFullScreen, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - } -} - -void CNotificationSettings::RegisterNotifications() -{ - g_Settings->RegisterChangeCB(UserInterface_InFullScreen, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); - RefreshSettings(); -} - -void CNotificationSettings::RefreshSettings() -{ - m_bInFullScreen = g_Settings->LoadBool(UserInterface_InFullScreen); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +bool CNotificationSettings::m_bInFullScreen = false; + +CNotificationSettings::CNotificationSettings() +{ +} + +CNotificationSettings::~CNotificationSettings() +{ + if (g_Settings) + { + g_Settings->UnregisterChangeCB(UserInterface_InFullScreen, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + } +} + +void CNotificationSettings::RegisterNotifications() +{ + g_Settings->RegisterChangeCB(UserInterface_InFullScreen, this, (CSettings::SettingChangedFunc)StaticRefreshSettings); + RefreshSettings(); +} + +void CNotificationSettings::RefreshSettings() +{ + m_bInFullScreen = g_Settings->LoadBool(UserInterface_InFullScreen); } \ No newline at end of file diff --git a/Source/Project64/Settings/NotificationSettings.h b/Source/Project64/Settings/NotificationSettings.h index 5be7f8e14..cc87ecb1d 100644 --- a/Source/Project64/Settings/NotificationSettings.h +++ b/Source/Project64/Settings/NotificationSettings.h @@ -1,30 +1,30 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CNotificationSettings -{ - static void StaticRefreshSettings(CNotificationSettings * _this) - { - _this->RefreshSettings(); - } - - void RefreshSettings(void); - - static bool m_bInFullScreen; - -protected: - CNotificationSettings(); - virtual ~CNotificationSettings(); - - void RegisterNotifications(void); - inline bool InFullScreen(void) const { return m_bInFullScreen; } -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CNotificationSettings +{ + static void StaticRefreshSettings(CNotificationSettings * _this) + { + _this->RefreshSettings(); + } + + void RefreshSettings(void); + + static bool m_bInFullScreen; + +protected: + CNotificationSettings(); + virtual ~CNotificationSettings(); + + void RegisterNotifications(void); + inline bool InFullScreen(void) const { return m_bInFullScreen; } +}; diff --git a/Source/Project64/Support.h b/Source/Project64/Support.h index 8e7558b3e..2380ecee0 100644 --- a/Source/Project64/Support.h +++ b/Source/Project64/Support.h @@ -1,12 +1,12 @@ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/Source/Project64/UserInterface.h b/Source/Project64/UserInterface.h index 3ef6f404d..7e56092e4 100644 --- a/Source/Project64/UserInterface.h +++ b/Source/Project64/UserInterface.h @@ -1,29 +1,29 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#pragma warning(disable:4786) -#include "Support.h" - -#include -#include - -#include "WTLApp.h" -#include "UserInterface/MenuShortCuts.h" -#include "UserInterface/RomBrowser.h" -#include "UserInterface/GuiClass.h" -#include "UserInterface/MenuClass.h" -#include "UserInterface/MainMenuClass.h" -#include "UserInterface/NotificationClass.h" -#include -#include "UserInterface/resource.h" -#include "UserInterface/SettingsConfig.h" -#include "UserInterface/CheatClassUI.h" +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#pragma warning(disable:4786) +#include "Support.h" + +#include +#include + +#include "WTLApp.h" +#include "UserInterface/MenuShortCuts.h" +#include "UserInterface/RomBrowser.h" +#include "UserInterface/GuiClass.h" +#include "UserInterface/MenuClass.h" +#include "UserInterface/MainMenuClass.h" +#include "UserInterface/NotificationClass.h" +#include +#include "UserInterface/resource.h" +#include "UserInterface/SettingsConfig.h" +#include "UserInterface/CheatClassUI.h" diff --git a/Source/Project64/UserInterface/GuiClass.cpp b/Source/Project64/UserInterface/GuiClass.cpp index 018d4d1c4..5f6c86372 100644 --- a/Source/Project64/UserInterface/GuiClass.cpp +++ b/Source/Project64/UserInterface/GuiClass.cpp @@ -1,1340 +1,1340 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include "RomInformationClass.h" - -#include -#include - -void EnterLogOptions(HWND hwndOwner); - -#pragma comment(lib, "Comctl32.lib") - -DWORD CALLBACK AboutBoxProc(HWND WndHandle, DWORD uMsg, DWORD wParam, DWORD lParam); -LRESULT CALLBACK MainGui_Proc(HWND WndHandle, DWORD uMsg, DWORD wParam, DWORD lParam); - -extern BOOL set_about_field(HWND hDlg, int nIDDlgItem, const wchar_t * config_string, const wchar_t * language_string); - -CMainGui::CMainGui(bool bMainWindow, const char * WindowTitle) : - CRomBrowser(m_hMainWindow, m_hStatusWnd), - m_ThreadId(GetCurrentThreadId()), - m_bMainWindow(bMainWindow), - m_Created(false), - m_AttachingMenu(false), - m_MakingVisible(false), - m_ResetPlugins(false), - m_ResetInfo(NULL) -{ - m_Menu = NULL; - - m_hMainWindow = 0; - m_hStatusWnd = 0; - m_SaveMainWindowPos = false; - m_SaveMainWindowTop = 0; - m_SaveMainWindowLeft = 0; - - m_SaveRomBrowserPos = false; - m_SaveRomBrowserTop = 0; - m_SaveRomBrowserLeft = 0; - - if (m_bMainWindow) - { - g_Settings->RegisterChangeCB(RomBrowser_Enabled, this, (CSettings::SettingChangedFunc)RomBowserEnabledChanged); - g_Settings->RegisterChangeCB(RomBrowser_ColoumnsChanged, this, (CSettings::SettingChangedFunc)RomBowserColoumnsChanged); - g_Settings->RegisterChangeCB(RomBrowser_Recursive, this, (CSettings::SettingChangedFunc)RomBrowserRecursiveChanged); - g_Settings->RegisterChangeCB(GameRunning_LoadingInProgress, this, (CSettings::SettingChangedFunc)LoadingInProgressChanged); - g_Settings->RegisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunning); - g_Settings->RegisterChangeCB(GameRunning_CPU_Paused, this, (CSettings::SettingChangedFunc)GamePaused); - g_Settings->RegisterChangeCB(Game_File, this, (CSettings::SettingChangedFunc)GameLoaded); - } - - //if this fails then it has already been created - RegisterWinClass(); - Create(WindowTitle); -} - -CMainGui::~CMainGui(void) -{ - WriteTrace(TraceUserInterface, TraceDebug, "Start"); - if (m_bMainWindow) - { - g_Settings->UnregisterChangeCB(RomBrowser_Enabled, this, (CSettings::SettingChangedFunc)RomBowserEnabledChanged); - g_Settings->UnregisterChangeCB(RomBrowser_ColoumnsChanged, this, (CSettings::SettingChangedFunc)RomBowserColoumnsChanged); - g_Settings->UnregisterChangeCB(RomBrowser_Recursive, this, (CSettings::SettingChangedFunc)RomBrowserRecursiveChanged); - g_Settings->UnregisterChangeCB(GameRunning_LoadingInProgress, this, (CSettings::SettingChangedFunc)LoadingInProgressChanged); - g_Settings->UnregisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunning); - g_Settings->UnregisterChangeCB(GameRunning_CPU_Paused, this, (CSettings::SettingChangedFunc)GamePaused); - g_Settings->UnregisterChangeCB(Game_File, this, (CSettings::SettingChangedFunc)GameLoaded); - } - if (m_hMainWindow) - { - DestroyWindow(m_hMainWindow); - } - WriteTrace(TraceUserInterface, TraceDebug, "Done"); -} - -bool CMainGui::RegisterWinClass(void) -{ - stdstr_f VersionDisplay("Project64 %s", VER_FILE_VERSION_STR); - - WNDCLASS wcl; - - wcl.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; - wcl.cbClsExtra = 0; - wcl.cbWndExtra = 0; - wcl.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_PJ64_Icon)); - wcl.hCursor = LoadCursor(NULL, IDC_ARROW); - wcl.hInstance = GetModuleHandle(NULL); - - wcl.lpfnWndProc = (WNDPROC)MainGui_Proc; - wcl.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wcl.lpszMenuName = NULL; - wcl.lpszClassName = VersionDisplay.c_str(); - if (RegisterClass(&wcl) == 0) return false; - return true; -} - -void CMainGui::AddRecentRom(const char * ImagePath) -{ - if (HIWORD(ImagePath) == NULL) { return; } - - //Get Information about the stored rom list - size_t MaxRememberedFiles = g_Settings->LoadDword(File_RecentGameFileCount); - strlist RecentGames; - size_t i; - for (i = 0; i < MaxRememberedFiles; i++) - { - stdstr RecentGame = g_Settings->LoadStringIndex(File_RecentGameFileIndex, i); - if (RecentGame.empty()) - { - break; - } - RecentGames.push_back(RecentGame); - } - - //See if the dir is already in the list if so then move it to the top of the list - strlist::iterator iter; - for (iter = RecentGames.begin(); iter != RecentGames.end(); iter++) - { - if (_stricmp(ImagePath, iter->c_str()) != 0) - { - continue; - } - RecentGames.erase(iter); - break; - } - RecentGames.push_front(ImagePath); - if (RecentGames.size() > MaxRememberedFiles) - { - RecentGames.pop_back(); - } - - for (i = 0, iter = RecentGames.begin(); iter != RecentGames.end(); iter++, i++) - { - g_Settings->SaveStringIndex(File_RecentGameFileIndex, i, *iter); - } -} - -void CMainGui::SetWindowCaption(const wchar_t * title) -{ - static const size_t TITLE_SIZE = 256; - wchar_t WinTitle[TITLE_SIZE]; - - _snwprintf(WinTitle, TITLE_SIZE, L"%s - %s", title, g_Settings->LoadStringVal(Setting_ApplicationName).ToUTF16().c_str()); - WinTitle[TITLE_SIZE - 1] = 0; - Caption(WinTitle); -} - -void CMainGui::ShowRomBrowser(void) -{ - if (g_Settings->LoadDword(RomBrowser_Enabled)) - { - ShowRomList(); - HighLightLastRom(); - } -} - -void RomBowserEnabledChanged(CMainGui * Gui) -{ - if (Gui && g_Settings->LoadBool(RomBrowser_Enabled)) - { - if (!Gui->RomBrowserVisible()) - { - Gui->ShowRomList(); - } - } - else - { - if (Gui->RomBrowserVisible()) - { - Gui->HideRomList(); - } - } -} - -void CMainGui::LoadingInProgressChanged(CMainGui * Gui) -{ - Gui->RefreshMenu(); - if (!g_Settings->LoadBool(GameRunning_LoadingInProgress) && g_Settings->LoadStringVal(Game_File).length() == 0) - { - Notify().WindowMode(); - if (g_Settings->LoadDword(RomBrowser_Enabled)) - { - Gui->ShowRomBrowser(); - } - Gui->MakeWindowOnTop(false); - } -} - -void CMainGui::GameLoaded(CMainGui * Gui) -{ - stdstr FileLoc = g_Settings->LoadStringVal(Game_File); - if (FileLoc.length() > 0) - { - WriteTrace(TraceUserInterface, TraceDebug, "Add Recent Rom"); - Gui->AddRecentRom(FileLoc.c_str()); - Gui->SetWindowCaption(g_Settings->LoadStringVal(Game_GoodName).ToUTF16().c_str()); - Gui->HideRomList(); - } -} - -void CMainGui::GamePaused(CMainGui * Gui) -{ - Gui->RefreshMenu(); -} - -void CMainGui::GameCpuRunning(CMainGui * Gui) -{ - if (g_Settings->LoadBool(GameRunning_CPU_Running)) - { - Gui->MakeWindowOnTop(g_Settings->LoadBool(UserInterface_AlwaysOnTop)); - if (g_Settings->LoadBool(Setting_AutoFullscreen)) - { - WriteTrace(TraceUserInterface, TraceDebug, "15"); - CIniFile RomIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); - stdstr Status = g_Settings->LoadStringVal(Rdb_Status); - - char String[100]; - RomIniFile.GetString("Rom Status", stdstr_f("%s.AutoFullScreen", Status.c_str()).c_str(), "true", String, sizeof(String)); - if (_stricmp(String, "true") == 0) - { - g_Notify->ChangeFullScreen(); - } - } - Gui->RefreshMenu(); - Gui->BringToTop(); - } - else - { - PostMessage(Gui->m_hMainWindow, WM_GAME_CLOSED, 0, 0); - } -} - -void RomBowserColoumnsChanged(CMainGui * Gui) -{ - Gui->ResetRomBrowserColomuns(); -} - -void RomBrowserRecursiveChanged(CMainGui * Gui) -{ - Gui->RefreshRomBrowser(); - Gui->HighLightLastRom(); -} - -void CMainGui::ChangeWinSize(long width, long height) -{ - CGuard Guard(m_CS); - WINDOWPLACEMENT wndpl; - RECT rc1, swrect; - - wndpl.length = sizeof(wndpl); - GetWindowPlacement(m_hMainWindow, &wndpl); - - if ((HWND)m_hStatusWnd != NULL) - { - GetClientRect((HWND)m_hStatusWnd, &swrect); - SetRect(&rc1, 0, 0, width, height + swrect.bottom); - } - else - { - SetRect(&rc1, 0, 0, width, height); - } - - AdjustWindowRectEx(&rc1, GetWindowLong(m_hMainWindow, GWL_STYLE), GetMenu(m_hMainWindow) != NULL, GetWindowLong(m_hMainWindow, GWL_EXSTYLE)); - - MoveWindow(m_hMainWindow, wndpl.rcNormalPosition.left, wndpl.rcNormalPosition.top, rc1.right - rc1.left, rc1.bottom - rc1.top, TRUE); -} - -void * CMainGui::GetModuleInstance(void) const -{ - return GetModuleHandle(NULL); -} - -void CMainGui::AboutBox(void) -{ - DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_About), m_hMainWindow, (DLGPROC)AboutBoxProc, (LPARAM)this); -} - -void CMainGui::AboutIniBox(void) -{ - DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_About_Ini), m_hMainWindow, (DLGPROC)AboutIniBoxProc, (LPARAM)this); -} - -DWORD CALLBACK AboutIniBoxProc(HWND hDlg, DWORD uMsg, DWORD wParam, DWORD /*lParam*/) -{ - static wchar_t RDBHomePage[300], CHTHomePage[300], RDXHomePage[300]; - - switch (uMsg) { - case WM_INITDIALOG: - { - wchar_t String[200]; - - //Title - SetWindowTextW(hDlg, wGS(INI_TITLE).c_str()); - - //Language - SetDlgItemTextW(hDlg, IDC_LAN, wGS(INI_CURRENT_LANG).c_str()); - set_about_field(hDlg, IDC_LAN_AUTHOR, wGS(INI_AUTHOR).c_str(), wGS(LANGUAGE_AUTHOR).c_str()); - set_about_field(hDlg, IDC_LAN_VERSION, wGS(INI_VERSION).c_str(), wGS(LANGUAGE_VERSION).c_str()); - set_about_field(hDlg, IDC_LAN_DATE, wGS(INI_DATE).c_str(), wGS(LANGUAGE_DATE).c_str()); - if (wcslen(wGS(LANGUAGE_NAME).c_str()) == 0) - { - EnableWindow(GetDlgItem(hDlg, IDC_LAN), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_LAN_AUTHOR), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_LAN_VERSION), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_LAN_DATE), FALSE); - } - //RDB - CIniFile RdbIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); - wcsncpy(String, RdbIniFile.GetString("Meta", "Author", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - if (wcslen(String) == 0) - { - EnableWindow(GetDlgItem(hDlg, IDC_RDB), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_RDB_AUTHOR), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_RDB_VERSION), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_RDB_DATE), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_RDB_HOME), FALSE); - } - - set_about_field(hDlg, IDC_RDB_AUTHOR, wGS(INI_AUTHOR).c_str(), String); - - wcsncpy(String, RdbIniFile.GetString("Meta", "Version", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - set_about_field(hDlg, IDC_RDB_VERSION, wGS(INI_VERSION).c_str(), String); - wcsncpy(String, RdbIniFile.GetString("Meta", "Date", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - set_about_field(hDlg, IDC_RDB_DATE, wGS(INI_DATE).c_str(), String); - wcsncpy(RDBHomePage, RdbIniFile.GetString("Meta", "Homepage", "").ToUTF16().c_str(), sizeof(RDBHomePage) / sizeof(RDBHomePage[0])); - SetDlgItemTextW(hDlg, IDC_RDB_HOME, wGS(INI_HOMEPAGE).c_str()); - if (wcslen(RDBHomePage) == 0) - { - EnableWindow(GetDlgItem(hDlg, IDC_RDB_HOME), FALSE); - } - - //Cheat - SetDlgItemTextW(hDlg, IDC_CHT, wGS(INI_CURRENT_CHT).c_str()); - CIniFile CheatIniFile(g_Settings->LoadStringVal(SupportFile_Cheats).c_str()); - wcsncpy(String, CheatIniFile.GetString("Meta", "Author", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - if (wcslen(String) == 0) - { - EnableWindow(GetDlgItem(hDlg, IDC_CHT), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_CHT_AUTHOR), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_CHT_VERSION), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_CHT_DATE), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_CHT_HOME), FALSE); - } - set_about_field(hDlg, IDC_CHT_AUTHOR, wGS(INI_AUTHOR).c_str(), String); - wcsncpy(String, CheatIniFile.GetString("Meta", "Version", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - set_about_field(hDlg, IDC_CHT_VERSION, wGS(INI_VERSION).c_str(), String); - wcsncpy(String, CheatIniFile.GetString("Meta", "Date", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - set_about_field(hDlg, IDC_CHT_DATE, wGS(INI_DATE).c_str(), String); - wcsncpy(CHTHomePage, CheatIniFile.GetString("Meta", "Homepage", "").ToUTF16().c_str(), sizeof(CHTHomePage) / sizeof(CHTHomePage[0])); - SetDlgItemTextW(hDlg, IDC_CHT_HOME, wGS(INI_HOMEPAGE).c_str()); - if (wcslen(CHTHomePage) == 0) - { - EnableWindow(GetDlgItem(hDlg, IDC_CHT_HOME), FALSE); - } - - //Extended Info - SetDlgItemTextW(hDlg, IDC_RDX, wGS(INI_CURRENT_RDX).c_str()); - CIniFile RdxIniFile(g_Settings->LoadStringVal(SupportFile_ExtInfo).c_str()); - wcsncpy(String, RdxIniFile.GetString("Meta", "Author", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - if (wcslen(String) == 0) - { - EnableWindow(GetDlgItem(hDlg, IDC_RDX), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_RDX_AUTHOR), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_RDX_VERSION), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_RDX_DATE), FALSE); - EnableWindow(GetDlgItem(hDlg, IDC_RDX_HOME), FALSE); - } - set_about_field(hDlg, IDC_RDX_AUTHOR, wGS(INI_AUTHOR).c_str(), String); - wcsncpy(String, RdxIniFile.GetString("Meta", "Version", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - set_about_field(hDlg, IDC_RDX_VERSION, wGS(INI_VERSION).c_str(), String); - wcsncpy(String, RdxIniFile.GetString("Meta", "Date", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); - set_about_field(hDlg, IDC_RDX_DATE, wGS(INI_DATE).c_str(), String); - wcsncpy(RDXHomePage, RdxIniFile.GetString("Meta", "Homepage", "").ToUTF16().c_str(), sizeof(RDXHomePage) / sizeof(RDXHomePage[0])); - SetDlgItemTextW(hDlg, IDC_RDX_HOME, wGS(INI_HOMEPAGE).c_str()); - if (wcslen(RDXHomePage) == 0) - { - EnableWindow(GetDlgItem(hDlg, IDC_RDX_HOME), FALSE); - } - SetDlgItemTextW(hDlg, IDOK, wGS(CHEAT_OK).c_str()); - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_RDB_HOME: ShellExecuteW(NULL, L"open", RDBHomePage, NULL, NULL, SW_SHOWNORMAL); break; - case IDC_CHT_HOME: ShellExecuteW(NULL, L"open", CHTHomePage, NULL, NULL, SW_SHOWNORMAL); break; - case IDC_RDX_HOME: ShellExecuteW(NULL, L"open", RDXHomePage, NULL, NULL, SW_SHOWNORMAL); break; - case IDOK: - case IDCANCEL: - EndDialog(hDlg, 0); - break; - } - default: - return FALSE; - } - return TRUE; -} - -bool CMainGui::ResetPluginsInUiThread(CPlugins * plugins, CN64System * System) -{ - RESET_PLUGIN info; - info.system = System; - info.plugins = plugins; - info.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - bool bRes = true; - if (info.hEvent) - { - PostMessage(m_hMainWindow, WM_RESET_PLUGIN, (WPARAM)&bRes, (LPARAM)&info); -#ifdef _DEBUG - DWORD dwRes = WaitForSingleObject(info.hEvent, INFINITE); -#else - DWORD dwRes = WaitForSingleObject(info.hEvent, 5000); -#endif - dwRes = dwRes; - CloseHandle(info.hEvent); - } - else - { - WriteTrace(TraceUserInterface, TraceError, "Failed to create event"); - bRes = false; - } - Notify().RefreshMenu(); - return bRes; -} - -void CMainGui::BringToTop(void) -{ - CGuard Guard(m_CS); - SetForegroundWindow(m_hMainWindow); - SetFocus(GetDesktopWindow()); - Sleep(100); - SetFocus(m_hMainWindow); -} - -void CMainGui::MakeWindowOnTop(bool OnTop) -{ - CGuard Guard(m_CS); - SetWindowPos(m_hMainWindow, OnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW); -} - -void CMainGui::Caption(LPCWSTR Caption) -{ - CGuard Guard(m_CS); - SetWindowTextW(m_hMainWindow, Caption); -} - -void CMainGui::Create(const char * WindowTitle) -{ - stdstr_f VersionDisplay("Project64 %s", VER_FILE_VERSION_STR); - m_hMainWindow = CreateWindowExW(WS_EX_ACCEPTFILES, VersionDisplay.ToUTF16().c_str(), stdstr(WindowTitle).ToUTF16().c_str(), WS_OVERLAPPED | WS_CLIPCHILDREN | - WS_CLIPSIBLINGS | WS_SYSMENU | WS_MINIMIZEBOX, 5, 5, 640, 480, - NULL, NULL, GetModuleHandle(NULL), this); - m_Created = m_hMainWindow != NULL; -} - -void CMainGui::CreateStatusBar(void) -{ - m_hStatusWnd = (HWND)CreateStatusWindow(WS_CHILD | WS_VISIBLE, "", m_hMainWindow, StatusBarID); - SendMessage((HWND)m_hStatusWnd, SB_SETTEXT, 0, (LPARAM)""); -} - -WPARAM CMainGui::ProcessAllMessages(void) -{ - MSG msg; - - while (GetMessage(&msg, NULL, 0, 0)) - { - if (g_cheatUI != NULL && g_cheatUI->IsCheatMessage(&msg)) - { - continue; - } - - if (m_ResetPlugins) - { - m_ResetPlugins = false; - m_ResetInfo->res = m_ResetInfo->plugins->Reset(m_ResetInfo->system); - SetEvent(m_ResetInfo->hEvent); - m_ResetInfo = NULL; - } - if (g_cheatUI && g_cheatUI->IsCheatMessage(&msg)) { continue; } - if (m_Menu->ProcessAccelerator(m_hMainWindow, &msg)) { continue; } - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return msg.wParam; -} - -bool CMainGui::ProcessGuiMessages(void) -{ - MSG msg; - - while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) - { - if (m_ResetPlugins) - { - m_ResetPlugins = false; - } - if (msg.message == WM_QUIT) - { - return true; - } - PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); - if (m_Menu->ProcessAccelerator(m_hMainWindow, &msg)) { continue; } - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return false; -} - -void CMainGui::Resize(DWORD /*fwSizeType*/, WORD nWidth, WORD nHeight) -{ - RECT clrect, swrect; - GetClientRect(m_hMainWindow, &clrect); - GetClientRect((HWND)m_hStatusWnd, &swrect); - - int Parts[2]; - Parts[0] = (nWidth - (int)(clrect.right * 0.25)); - Parts[1] = nWidth; - - SendMessage((HWND)m_hStatusWnd, SB_SETPARTS, 2, (LPARAM)&Parts[0]); - MoveWindow((HWND)m_hStatusWnd, 0, clrect.bottom - swrect.bottom, nWidth, nHeight, TRUE); -} - -void CMainGui::Show(bool Visible) -{ - m_MakingVisible = true; - - CGuard Guard(m_CS); - if (m_hMainWindow) - { - ShowWindow(m_hMainWindow, Visible ? SW_SHOW : SW_HIDE); - if (Visible && RomBrowserVisible()) - { - RomBrowserToTop(); - } - } - - m_MakingVisible = false; -} - -void CMainGui::EnterLogOptions(void) -{ - ::EnterLogOptions(m_hMainWindow); -} - -int CMainGui::Height(void) -{ - if (!m_hMainWindow) { return 0; } - - RECT rect; - GetWindowRect(m_hMainWindow, &rect); - return rect.bottom - rect.top; -} - -int CMainGui::Width(void) -{ - if (!m_hMainWindow) { return 0; } - - RECT rect; - GetWindowRect(m_hMainWindow, &rect); - return rect.right - rect.left; -} - -void CMainGui::SetPos(int X, int Y) -{ - SetWindowPos(m_hMainWindow, NULL, X, Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); -} - -void CMainGui::SetWindowMenu(CBaseMenu * Menu) -{ - m_AttachingMenu = true; - - HMENU hMenu = NULL; - { - CGuard Guard(m_CS); - m_Menu = Menu; - hMenu = (HMENU)Menu->GetHandle(); - } - - if (hMenu) - { - SetMenu(m_hMainWindow, hMenu); - } - - m_AttachingMenu = false; -} - -void CMainGui::RefreshMenu(void) -{ - if (!m_Menu) { return; } - m_Menu->ResetMenu(); -} - -void CMainGui::SetStatusText(int Panel, const wchar_t * Text) -{ - static wchar_t Message[2][500]; - if (Panel >= 2) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return; - } - wchar_t * Msg = Message[Panel]; - - memset(Msg, 0, sizeof(Message[0])); - _snwprintf(Msg, sizeof(Message[0]) / sizeof(Message[0][0]), L"%s", Text); - Msg[(sizeof(Message[0]) / sizeof(Message[0][0])) - 1] = 0; - if (GetCurrentThreadId() == m_ThreadId) - { - SendMessageW((HWND)m_hStatusWnd, SB_SETTEXTW, Panel, (LPARAM)Msg); - } - else { - PostMessageW((HWND)m_hStatusWnd, SB_SETTEXTW, Panel, (LPARAM)Msg); - } -} - -void CMainGui::ShowStatusBar(bool ShowBar) -{ - ShowWindow((HWND)m_hStatusWnd, ShowBar ? SW_SHOW : SW_HIDE); -} - -void CMainGui::SaveWindowLoc(void) -{ - bool flush = false; - if (m_SaveMainWindowPos) - { - m_SaveMainWindowPos = false; - g_Settings->SaveDword(UserInterface_MainWindowTop, m_SaveMainWindowTop); - g_Settings->SaveDword(UserInterface_MainWindowLeft, m_SaveMainWindowLeft); - flush = true; - } - - if (m_SaveRomBrowserPos) - { - m_SaveRomBrowserPos = false; - g_Settings->SaveDword(RomBrowser_Top, m_SaveRomBrowserTop); - g_Settings->SaveDword(RomBrowser_Left, m_SaveRomBrowserLeft); - flush = true; - } - - if (flush) - { - CSettingTypeApplication::Flush(); - } -} - -LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWORD lParam) -{ - switch (uMsg) - { - case WM_CREATE: - { - //record class for future usage - LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam; - CMainGui * _this = (CMainGui *)lpcs->lpCreateParams; - SetProp(hWnd, "Class", _this); - - _this->m_hMainWindow = hWnd; - _this->CreateStatusBar(); - - //Move the Main window to the location last executed from or center the window - int X = (GetSystemMetrics(SM_CXSCREEN) - _this->Width()) / 2; - int Y = (GetSystemMetrics(SM_CYSCREEN) - _this->Height()) / 2; - - g_Settings->LoadDword(UserInterface_MainWindowTop, (uint32_t &)Y); - g_Settings->LoadDword(UserInterface_MainWindowLeft, (uint32_t &)X); - - _this->SetPos(X, Y); - - _this->ChangeWinSize(640, 480); - } - break; - case WM_SYSCOMMAND: - switch (wParam) { - case SC_SCREENSAVE: - case SC_MONITORPOWER: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this && - _this->bCPURunning() && - !g_Settings->LoadBool(GameRunning_CPU_Paused) && - g_Settings->LoadDword(Setting_DisableScrSaver)) - { - return 0; - } - } - break; - case SC_MAXIMIZE: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this) - { - if (_this->RomBrowserVisible()) - { - _this->RomBrowserMaximize(true); - } - } - } - break; - } - return DefWindowProc(hWnd, uMsg, wParam, lParam); - break; - case WM_MOVE: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - - if (!_this->m_bMainWindow || - !_this->m_Created || - _this->m_AttachingMenu || - _this->m_MakingVisible || - IsIconic(hWnd) || - _this->ShowingRomBrowser()) - { - break; - } - - if (IsZoomed(hWnd)) - { - if (_this->RomBrowserVisible()) - { - // save that browser is maximized - } - break; - } - - //get the current position of the window - RECT WinRect; - GetWindowRect(hWnd, &WinRect); - - //save the location of the window - if (_this->RomBrowserVisible()) - { - _this->m_SaveRomBrowserPos = true; - _this->m_SaveRomBrowserTop = WinRect.top; - _this->m_SaveRomBrowserLeft = WinRect.left; - } - else - { - _this->m_SaveMainWindowPos = true; - _this->m_SaveMainWindowTop = WinRect.top; - _this->m_SaveMainWindowLeft = WinRect.left; - } - KillTimer(hWnd, Timer_SetWindowPos); - SetTimer(hWnd, Timer_SetWindowPos, 1000, NULL); - } - if (CGuiSettings::bCPURunning() && g_BaseSystem) - { - if (g_Plugins->Gfx() && g_Plugins->Gfx()->MoveScreen) - { - WriteTrace(TraceGFXPlugin, TraceDebug, "Starting"); - g_Plugins->Gfx()->MoveScreen((int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam)); - WriteTrace(TraceGFXPlugin, TraceDebug, "Done"); - } - } - break; - case WM_TIMER: - if (wParam == Timer_SetWindowPos) - { - KillTimer(hWnd, Timer_SetWindowPos); - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - _this->SaveWindowLoc(); - break; - } - break; - case WM_SIZE: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this) { _this->Resize(wParam, LOWORD(lParam), HIWORD(lParam)); } - if (_this) - { - if (wParam == SIZE_MAXIMIZED) - { - if (_this->RomBrowserVisible()) - { - _this->RomBrowserMaximize(true); - } - } - _this->ResizeRomList(LOWORD(lParam), HIWORD(lParam)); - } - if (_this) - { - if (wParam == SIZE_RESTORED && _this->RomBrowserVisible()) - { - _this->RomBrowserMaximize(false); - } - } - } - break; - case WM_NOTIFY: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this == NULL || !_this->RomBrowserVisible() || !_this->RomListNotify(wParam, lParam)) - { - return DefWindowProc(hWnd, uMsg, wParam, lParam); - } - } - break; - case WM_DRAWITEM: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this) - { - if (!_this->RomListDrawItem(wParam, lParam)) - { - return DefWindowProc(hWnd, uMsg, wParam, lParam); - } - } - } - break; - case WM_PAINT: - { - // CMainGui * _this = (CMainGui *)GetProp(hWnd,"Class"); - // CN64System * System = _this->m_System; - - // if (bCPURunning() && Settings->Load(CPU_Paused)) { - // CPlugins * Plugins = System->Plugins(); - // if (Plugins->Gfx()->DrawScreen) { - // Plugins->Gfx()->DrawScreen(); - // } - // } - ValidateRect(hWnd, NULL); - } - break; - case WM_KEYUP: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - - if (_this->m_bMainWindow && bCPURunning()) - { - if (g_BaseSystem) - { - if (g_Plugins && g_Plugins->Control()->WM_KeyUp) { - g_Plugins->Control()->WM_KeyUp(wParam, lParam); - } - } - } - } - break; - case WM_KEYDOWN: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - - if (_this->m_bMainWindow && bCPURunning()) - { - if (g_BaseSystem) - { - if (g_Plugins && g_Plugins->Control()->WM_KeyDown) - { - g_Plugins->Control()->WM_KeyDown(wParam, lParam); - } - } - } - } - break; - case WM_SETFOCUS: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this->RomBrowserVisible()) - { - PostMessage(hWnd, WM_BROWSER_TOP, 0, 0); - break; - } - - if (_this->m_bMainWindow && bCPURunning() && bAutoSleep()) - { - if (g_BaseSystem) - { - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_AppGainedFocus); - } - } - } - break; - case WM_KILLFOCUS: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this->RomBrowserVisible()) - { - break; - } - - if (_this->m_bMainWindow && bCPURunning() && bAutoSleep()) - { - if (g_BaseSystem) - { - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_AppLostFocus); - } - } - } - break; - case WM_ACTIVATEAPP: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - DWORD fActive = (BOOL)wParam; - - if (fActive && _this->RomBrowserVisible()) - { - PostMessage(hWnd, WM_BROWSER_TOP, 0, 0); - } - if (_this->m_bMainWindow && bCPURunning()) - { - if (!fActive && g_Settings->LoadBool(UserInterface_InFullScreen)) - { - Notify().WindowMode(); - if (bAutoSleep() && g_BaseSystem) - { - //System->ExternalEvent(PauseCPU_AppLostActiveDelayed ); - } - break; - } - if (bAutoSleep() || fActive) - { - if (g_BaseSystem) - { - g_BaseSystem->ExternalEvent(fActive ? SysEvent_ResumeCPU_AppGainedActive : SysEvent_PauseCPU_AppLostActive); - } - } - } - } - break; - case WM_HIDE_CUROSR: - if (!wParam) - { - while (ShowCursor(FALSE) >= 0) { Sleep(0); } - } - else - { - while (ShowCursor(TRUE) < 0) { Sleep(0); } - } - break; - case WM_MAKE_FOCUS: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - _this->BringToTop(); - } - break; - case WM_BROWSER_TOP: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - _this->RomBrowserToTop(); - } - break; - case WM_RESET_PLUGIN: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this->m_ResetInfo != NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - _this->m_ResetInfo = (RESET_PLUGIN *)lParam; - _this->m_ResetPlugins = true; - } - break; - case WM_GAME_CLOSED: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - Notify().WindowMode(); - if (g_Settings->LoadDword(RomBrowser_Enabled)) - { - _this->ShowRomBrowser(); - } - _this->RefreshMenu(); - _this->MakeWindowOnTop(false); - _this->SetStatusText(0, L""); - _this->SetStatusText(1, L""); - } - break; - case WM_COMMAND: - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this == NULL) { break; } - - switch (LOWORD(wParam)) { - case ID_POPUPMENU_PLAYGAME: g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); break; - case ID_POPUPMENU_PLAYGAMEWITHDISK: - { - stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); - if ((IPLROM.length() <= 0) || (!g_BaseSystem->RunFileImageIPL(IPLROM.c_str()))) - { - // Open DDROM - OPENFILENAME openfilename; - char FileName[_MAX_PATH], Directory[_MAX_PATH]; - - memset(&FileName, 0, sizeof(FileName)); - memset(&openfilename, 0, sizeof(openfilename)); - - strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); - - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hWnd; - openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; - openfilename.lpstrFile = FileName; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - - if (GetOpenFileName(&openfilename)) - { - g_BaseSystem->RunFileImageIPL(FileName); - // Open Disk - openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; - if (GetOpenFileName(&openfilename)) - { - if (g_BaseSystem->RunDiskImage(FileName)) - g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); - } - } - } - else - { - // Open Disk - OPENFILENAME openfilename; - char FileName[_MAX_PATH], Directory[_MAX_PATH]; - - memset(&FileName, 0, sizeof(FileName)); - memset(&openfilename, 0, sizeof(openfilename)); - - strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); - - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hWnd; - openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; - openfilename.lpstrFile = FileName; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - - if (GetOpenFileName(&openfilename)) - { - if (g_BaseSystem->RunDiskImage(FileName)) - g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); - } - } - } - break; - case ID_POPUPMENU_ROMDIRECTORY: _this->SelectRomDir(); break; - case ID_POPUPMENU_REFRESHROMLIST: _this->RefreshRomBrowser(); break; - case ID_POPUPMENU_ROMINFORMATION: - { - RomInformation Info(_this->CurrentedSelectedRom()); - Info.DisplayInformation(hWnd); - } - break; - case ID_POPUPMENU_EDITSETTINGS: - case ID_POPUPMENU_EDITCHEATS: - { - CN64Rom Rom; - Rom.LoadN64Image(_this->CurrentedSelectedRom(), true); - Rom.SaveRomSettingID(true); - - if (LOWORD(wParam) == ID_POPUPMENU_EDITSETTINGS) - { - CSettingConfig SettingConfig(true); - SettingConfig.Display(hWnd); - } - - if (LOWORD(wParam) == ID_POPUPMENU_EDITCHEATS) - { - CCheatsUI * cheatUI = new CCheatsUI; - g_cheatUI = cheatUI; - cheatUI->SelectCheats(hWnd, true); - if (g_cheatUI == cheatUI) - { - g_cheatUI = NULL; - } - } - - if (g_Rom) - { - g_Rom->SaveRomSettingID(false); - } - else - { - Rom.ClearRomSettingID(); - } - } - break; - default: - if (_this->m_Menu) - { - if (LOWORD(wParam) > 5000 && LOWORD(wParam) <= 5100) - { - if (g_Plugins->RSP()) - { - g_Plugins->RSP()->ProcessMenuItem(LOWORD(wParam)); - } - } - else if (LOWORD(wParam) > 5100 && LOWORD(wParam) <= 5200) - { - if (g_Plugins->Gfx()) - { - WriteTrace(TraceGFXPlugin, TraceDebug, "Starting"); - g_Plugins->Gfx()->ProcessMenuItem(LOWORD(wParam)); - WriteTrace(TraceGFXPlugin, TraceDebug, "Done"); - } - } - else if (LOWORD(wParam) > 5200 && LOWORD(wParam) <= 5300) - { - if (g_Plugins->Gfx() && g_Plugins->Gfx()->OnRomBrowserMenuItem != NULL) - { - CN64Rom Rom; - if (!Rom.LoadN64Image(_this->CurrentedSelectedRom(), true)) - { - break; - } - Rom.SaveRomSettingID(true); - g_Notify->DisplayMessage(0, ""); - BYTE * RomHeader = Rom.GetRomAddress(); - WriteTrace(TraceGFXPlugin, TraceDebug, "OnRomBrowserMenuItem - Starting"); - g_Plugins->Gfx()->OnRomBrowserMenuItem(LOWORD(wParam), hWnd, RomHeader); - WriteTrace(TraceGFXPlugin, TraceDebug, "OnRomBrowserMenuItem - Done"); - if (g_Rom) - { - g_Rom->SaveRomSettingID(false); - } - else - { - g_Settings->SaveString(Game_IniKey, ""); - } - } - } - else if (_this->m_Menu->ProcessMessage(hWnd, HIWORD(wParam), LOWORD(wParam))) - { - return true; - } - } - } - } - break; - case WM_DROPFILES: - { - char filename[MAX_PATH]; - - HDROP hDrop = (HDROP)wParam; - DragQueryFile(hDrop, 0, filename, sizeof(filename)); - DragFinish(hDrop); - - stdstr ext = CPath(filename).GetExtension(); - if (!(_stricmp(ext.c_str(), "ndd") == 0)) - { - delete g_DDRom; - g_DDRom = NULL; - CN64System::RunFileImage(filename); - } - else - { - // Open Disk - if (CN64System::RunDiskImage(filename)) - { - stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); - if ((IPLROM.length() <= 0) || (!CN64System::RunFileImage(IPLROM.c_str()))) - { - // Open DDROM - OPENFILENAME openfilename; - char FileName[_MAX_PATH], Directory[_MAX_PATH]; - memset(&FileName, 0, sizeof(FileName)); - memset(&openfilename, 0, sizeof(openfilename)); - - strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hWnd; - openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; - openfilename.lpstrFile = FileName; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - - if (GetOpenFileName(&openfilename)) - { - CN64System::RunFileImage(FileName); - } - } - } - } - } - break; - case WM_DESTROY: - WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - start"); - { - CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); - if (_this->m_bMainWindow) - { - Notify().WindowMode(); - } - _this->m_hMainWindow = NULL; - WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - 1"); - if (_this->m_bMainWindow) - { - _this->SaveRomListColoumnInfo(); - WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - 2"); - _this->SaveWindowLoc(); - } - } - WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - 3"); - RemoveProp(hWnd, "Class"); - WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - 4"); - PostQuitMessage(0); - WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - Done"); - break; - default: - return DefWindowProc(hWnd, uMsg, wParam, lParam); - } - return TRUE; -} - -DWORD CALLBACK AboutBoxProc(HWND hWnd, DWORD uMsg, DWORD wParam, DWORD lParam) -{ - static HBITMAP hbmpBackgroundTop = NULL; - static HFONT hPageHeadingFont = NULL; - static HFONT hTextFont = NULL; - static HFONT hAuthorFont = NULL; - - switch (uMsg) { - case WM_INITDIALOG: - { - //Title - SetWindowTextW(hWnd, wGS(PLUG_ABOUT).c_str()); - - // Use the size of the image - hbmpBackgroundTop = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_ABOUT_LOGO)); - - BITMAP bmTL; - GetObject(hbmpBackgroundTop, sizeof(BITMAP), &bmTL); - - hTextFont = ::CreateFont(18, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); - hAuthorFont = ::CreateFont(18, 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); - - hPageHeadingFont = ::CreateFont(24, 0, 0, 0, FW_BOLD, 0, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial Bold"); - - SendDlgItemMessage(hWnd, IDC_VERSION, WM_SETFONT, (WPARAM)hTextFont, TRUE); - SendDlgItemMessage(hWnd, IDC_TEAM, WM_SETFONT, (WPARAM)hPageHeadingFont, TRUE); - SendDlgItemMessage(hWnd, IDC_THANKS, WM_SETFONT, (WPARAM)hPageHeadingFont, TRUE); - - SendDlgItemMessage(hWnd, IDC_ZILMAR, WM_SETFONT, (WPARAM)hAuthorFont, TRUE); - SendDlgItemMessage(hWnd, IDC_JABO, WM_SETFONT, (WPARAM)hAuthorFont, TRUE); - SendDlgItemMessage(hWnd, IDC_SMIFF, WM_SETFONT, (WPARAM)hAuthorFont, TRUE); - SendDlgItemMessage(hWnd, IDC_GENT, WM_SETFONT, (WPARAM)hAuthorFont, TRUE); - - SendDlgItemMessage(hWnd, IDC_ZILMAR_DETAILS, WM_SETFONT, (WPARAM)hTextFont, TRUE); - SendDlgItemMessage(hWnd, IDC_JABO_DETAILS, WM_SETFONT, (WPARAM)hTextFont, TRUE); - SendDlgItemMessage(hWnd, IDC_SMIFF_DETAILS, WM_SETFONT, (WPARAM)hTextFont, TRUE); - SendDlgItemMessage(hWnd, IDC_GENT_DETAILS, WM_SETFONT, (WPARAM)hTextFont, TRUE); - - SendDlgItemMessage(hWnd, IDC_THANK_LIST, WM_SETFONT, (WPARAM)hTextFont, TRUE); - - stdstr_f VersionDisplay("Version: %s", VER_FILE_VERSION_STR); - SetWindowText(GetDlgItem(hWnd, IDC_VERSION), VersionDisplay.c_str()); - } - break; - case WM_CTLCOLORSTATIC: - { - HDC hdcStatic = (HDC)wParam; - SetTextColor(hdcStatic, RGB(0, 0, 0)); - SetBkMode(hdcStatic, TRANSPARENT); - return (LONG)(LRESULT)((HBRUSH)GetStockObject(NULL_BRUSH)); - } - break; - case WM_ERASEBKGND: - { - HPEN outline; - HBRUSH fill; - RECT rect; - - outline = CreatePen(PS_SOLID, 1, 0x00FFFFFF); - fill = CreateSolidBrush(0x00FFFFFF); - SelectObject((HDC)wParam, outline); - SelectObject((HDC)wParam, fill); - - GetClientRect(hWnd, &rect); - - Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom); - } - break; - case WM_PAINT: - { - PAINTSTRUCT ps; - - if (BeginPaint(hWnd, &ps)) - { - RECT rcClient; - GetClientRect(hWnd, &rcClient); - - BITMAP bmTL_top; - GetObject(hbmpBackgroundTop, sizeof(BITMAP), &bmTL_top); - - HDC memdc = CreateCompatibleDC(ps.hdc); - HGDIOBJ save = SelectObject(memdc, hbmpBackgroundTop); - BitBlt(ps.hdc, 0, 0, bmTL_top.bmWidth, bmTL_top.bmHeight, memdc, 0, 0, SRCCOPY); - SelectObject(memdc, save); - DeleteDC(memdc); - - EndPaint(hWnd, &ps); - } - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - case IDCANCEL: - if (hbmpBackgroundTop) - { - DeleteObject(hbmpBackgroundTop); - } - if (hTextFont) - { - ::DeleteObject(hTextFont); - } - if (hPageHeadingFont) - { - ::DeleteObject(hPageHeadingFont); - } - if (hAuthorFont) - { - ::DeleteObject(hAuthorFont); - } - //ReleaseCapture(); - EndDialog(hWnd, 0); - break; - } - default: - return FALSE; - } - return TRUE; -} - -BOOL set_about_field(HWND hDlg, int nIDDlgItem, const wchar_t * config_string, const wchar_t * language_string) -{ - wchar_t temp_string[200]; - - swprintf(temp_string, sizeof(temp_string) / sizeof(temp_string[0]), L"%s: %s", config_string, language_string); - return SetDlgItemTextW(hDlg, nIDDlgItem, temp_string); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include "RomInformationClass.h" + +#include +#include + +void EnterLogOptions(HWND hwndOwner); + +#pragma comment(lib, "Comctl32.lib") + +DWORD CALLBACK AboutBoxProc(HWND WndHandle, DWORD uMsg, DWORD wParam, DWORD lParam); +LRESULT CALLBACK MainGui_Proc(HWND WndHandle, DWORD uMsg, DWORD wParam, DWORD lParam); + +extern BOOL set_about_field(HWND hDlg, int nIDDlgItem, const wchar_t * config_string, const wchar_t * language_string); + +CMainGui::CMainGui(bool bMainWindow, const char * WindowTitle) : + CRomBrowser(m_hMainWindow, m_hStatusWnd), + m_ThreadId(GetCurrentThreadId()), + m_bMainWindow(bMainWindow), + m_Created(false), + m_AttachingMenu(false), + m_MakingVisible(false), + m_ResetPlugins(false), + m_ResetInfo(NULL) +{ + m_Menu = NULL; + + m_hMainWindow = 0; + m_hStatusWnd = 0; + m_SaveMainWindowPos = false; + m_SaveMainWindowTop = 0; + m_SaveMainWindowLeft = 0; + + m_SaveRomBrowserPos = false; + m_SaveRomBrowserTop = 0; + m_SaveRomBrowserLeft = 0; + + if (m_bMainWindow) + { + g_Settings->RegisterChangeCB(RomBrowser_Enabled, this, (CSettings::SettingChangedFunc)RomBowserEnabledChanged); + g_Settings->RegisterChangeCB(RomBrowser_ColoumnsChanged, this, (CSettings::SettingChangedFunc)RomBowserColoumnsChanged); + g_Settings->RegisterChangeCB(RomBrowser_Recursive, this, (CSettings::SettingChangedFunc)RomBrowserRecursiveChanged); + g_Settings->RegisterChangeCB(GameRunning_LoadingInProgress, this, (CSettings::SettingChangedFunc)LoadingInProgressChanged); + g_Settings->RegisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunning); + g_Settings->RegisterChangeCB(GameRunning_CPU_Paused, this, (CSettings::SettingChangedFunc)GamePaused); + g_Settings->RegisterChangeCB(Game_File, this, (CSettings::SettingChangedFunc)GameLoaded); + } + + //if this fails then it has already been created + RegisterWinClass(); + Create(WindowTitle); +} + +CMainGui::~CMainGui(void) +{ + WriteTrace(TraceUserInterface, TraceDebug, "Start"); + if (m_bMainWindow) + { + g_Settings->UnregisterChangeCB(RomBrowser_Enabled, this, (CSettings::SettingChangedFunc)RomBowserEnabledChanged); + g_Settings->UnregisterChangeCB(RomBrowser_ColoumnsChanged, this, (CSettings::SettingChangedFunc)RomBowserColoumnsChanged); + g_Settings->UnregisterChangeCB(RomBrowser_Recursive, this, (CSettings::SettingChangedFunc)RomBrowserRecursiveChanged); + g_Settings->UnregisterChangeCB(GameRunning_LoadingInProgress, this, (CSettings::SettingChangedFunc)LoadingInProgressChanged); + g_Settings->UnregisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunning); + g_Settings->UnregisterChangeCB(GameRunning_CPU_Paused, this, (CSettings::SettingChangedFunc)GamePaused); + g_Settings->UnregisterChangeCB(Game_File, this, (CSettings::SettingChangedFunc)GameLoaded); + } + if (m_hMainWindow) + { + DestroyWindow(m_hMainWindow); + } + WriteTrace(TraceUserInterface, TraceDebug, "Done"); +} + +bool CMainGui::RegisterWinClass(void) +{ + stdstr_f VersionDisplay("Project64 %s", VER_FILE_VERSION_STR); + + WNDCLASS wcl; + + wcl.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + wcl.cbClsExtra = 0; + wcl.cbWndExtra = 0; + wcl.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_PJ64_Icon)); + wcl.hCursor = LoadCursor(NULL, IDC_ARROW); + wcl.hInstance = GetModuleHandle(NULL); + + wcl.lpfnWndProc = (WNDPROC)MainGui_Proc; + wcl.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcl.lpszMenuName = NULL; + wcl.lpszClassName = VersionDisplay.c_str(); + if (RegisterClass(&wcl) == 0) return false; + return true; +} + +void CMainGui::AddRecentRom(const char * ImagePath) +{ + if (HIWORD(ImagePath) == NULL) { return; } + + //Get Information about the stored rom list + size_t MaxRememberedFiles = g_Settings->LoadDword(File_RecentGameFileCount); + strlist RecentGames; + size_t i; + for (i = 0; i < MaxRememberedFiles; i++) + { + stdstr RecentGame = g_Settings->LoadStringIndex(File_RecentGameFileIndex, i); + if (RecentGame.empty()) + { + break; + } + RecentGames.push_back(RecentGame); + } + + //See if the dir is already in the list if so then move it to the top of the list + strlist::iterator iter; + for (iter = RecentGames.begin(); iter != RecentGames.end(); iter++) + { + if (_stricmp(ImagePath, iter->c_str()) != 0) + { + continue; + } + RecentGames.erase(iter); + break; + } + RecentGames.push_front(ImagePath); + if (RecentGames.size() > MaxRememberedFiles) + { + RecentGames.pop_back(); + } + + for (i = 0, iter = RecentGames.begin(); iter != RecentGames.end(); iter++, i++) + { + g_Settings->SaveStringIndex(File_RecentGameFileIndex, i, *iter); + } +} + +void CMainGui::SetWindowCaption(const wchar_t * title) +{ + static const size_t TITLE_SIZE = 256; + wchar_t WinTitle[TITLE_SIZE]; + + _snwprintf(WinTitle, TITLE_SIZE, L"%s - %s", title, g_Settings->LoadStringVal(Setting_ApplicationName).ToUTF16().c_str()); + WinTitle[TITLE_SIZE - 1] = 0; + Caption(WinTitle); +} + +void CMainGui::ShowRomBrowser(void) +{ + if (g_Settings->LoadDword(RomBrowser_Enabled)) + { + ShowRomList(); + HighLightLastRom(); + } +} + +void RomBowserEnabledChanged(CMainGui * Gui) +{ + if (Gui && g_Settings->LoadBool(RomBrowser_Enabled)) + { + if (!Gui->RomBrowserVisible()) + { + Gui->ShowRomList(); + } + } + else + { + if (Gui->RomBrowserVisible()) + { + Gui->HideRomList(); + } + } +} + +void CMainGui::LoadingInProgressChanged(CMainGui * Gui) +{ + Gui->RefreshMenu(); + if (!g_Settings->LoadBool(GameRunning_LoadingInProgress) && g_Settings->LoadStringVal(Game_File).length() == 0) + { + Notify().WindowMode(); + if (g_Settings->LoadDword(RomBrowser_Enabled)) + { + Gui->ShowRomBrowser(); + } + Gui->MakeWindowOnTop(false); + } +} + +void CMainGui::GameLoaded(CMainGui * Gui) +{ + stdstr FileLoc = g_Settings->LoadStringVal(Game_File); + if (FileLoc.length() > 0) + { + WriteTrace(TraceUserInterface, TraceDebug, "Add Recent Rom"); + Gui->AddRecentRom(FileLoc.c_str()); + Gui->SetWindowCaption(g_Settings->LoadStringVal(Game_GoodName).ToUTF16().c_str()); + Gui->HideRomList(); + } +} + +void CMainGui::GamePaused(CMainGui * Gui) +{ + Gui->RefreshMenu(); +} + +void CMainGui::GameCpuRunning(CMainGui * Gui) +{ + if (g_Settings->LoadBool(GameRunning_CPU_Running)) + { + Gui->MakeWindowOnTop(g_Settings->LoadBool(UserInterface_AlwaysOnTop)); + if (g_Settings->LoadBool(Setting_AutoFullscreen)) + { + WriteTrace(TraceUserInterface, TraceDebug, "15"); + CIniFile RomIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); + stdstr Status = g_Settings->LoadStringVal(Rdb_Status); + + char String[100]; + RomIniFile.GetString("Rom Status", stdstr_f("%s.AutoFullScreen", Status.c_str()).c_str(), "true", String, sizeof(String)); + if (_stricmp(String, "true") == 0) + { + g_Notify->ChangeFullScreen(); + } + } + Gui->RefreshMenu(); + Gui->BringToTop(); + } + else + { + PostMessage(Gui->m_hMainWindow, WM_GAME_CLOSED, 0, 0); + } +} + +void RomBowserColoumnsChanged(CMainGui * Gui) +{ + Gui->ResetRomBrowserColomuns(); +} + +void RomBrowserRecursiveChanged(CMainGui * Gui) +{ + Gui->RefreshRomBrowser(); + Gui->HighLightLastRom(); +} + +void CMainGui::ChangeWinSize(long width, long height) +{ + CGuard Guard(m_CS); + WINDOWPLACEMENT wndpl; + RECT rc1, swrect; + + wndpl.length = sizeof(wndpl); + GetWindowPlacement(m_hMainWindow, &wndpl); + + if ((HWND)m_hStatusWnd != NULL) + { + GetClientRect((HWND)m_hStatusWnd, &swrect); + SetRect(&rc1, 0, 0, width, height + swrect.bottom); + } + else + { + SetRect(&rc1, 0, 0, width, height); + } + + AdjustWindowRectEx(&rc1, GetWindowLong(m_hMainWindow, GWL_STYLE), GetMenu(m_hMainWindow) != NULL, GetWindowLong(m_hMainWindow, GWL_EXSTYLE)); + + MoveWindow(m_hMainWindow, wndpl.rcNormalPosition.left, wndpl.rcNormalPosition.top, rc1.right - rc1.left, rc1.bottom - rc1.top, TRUE); +} + +void * CMainGui::GetModuleInstance(void) const +{ + return GetModuleHandle(NULL); +} + +void CMainGui::AboutBox(void) +{ + DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_About), m_hMainWindow, (DLGPROC)AboutBoxProc, (LPARAM)this); +} + +void CMainGui::AboutIniBox(void) +{ + DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_About_Ini), m_hMainWindow, (DLGPROC)AboutIniBoxProc, (LPARAM)this); +} + +DWORD CALLBACK AboutIniBoxProc(HWND hDlg, DWORD uMsg, DWORD wParam, DWORD /*lParam*/) +{ + static wchar_t RDBHomePage[300], CHTHomePage[300], RDXHomePage[300]; + + switch (uMsg) { + case WM_INITDIALOG: + { + wchar_t String[200]; + + //Title + SetWindowTextW(hDlg, wGS(INI_TITLE).c_str()); + + //Language + SetDlgItemTextW(hDlg, IDC_LAN, wGS(INI_CURRENT_LANG).c_str()); + set_about_field(hDlg, IDC_LAN_AUTHOR, wGS(INI_AUTHOR).c_str(), wGS(LANGUAGE_AUTHOR).c_str()); + set_about_field(hDlg, IDC_LAN_VERSION, wGS(INI_VERSION).c_str(), wGS(LANGUAGE_VERSION).c_str()); + set_about_field(hDlg, IDC_LAN_DATE, wGS(INI_DATE).c_str(), wGS(LANGUAGE_DATE).c_str()); + if (wcslen(wGS(LANGUAGE_NAME).c_str()) == 0) + { + EnableWindow(GetDlgItem(hDlg, IDC_LAN), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_LAN_AUTHOR), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_LAN_VERSION), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_LAN_DATE), FALSE); + } + //RDB + CIniFile RdbIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); + wcsncpy(String, RdbIniFile.GetString("Meta", "Author", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + if (wcslen(String) == 0) + { + EnableWindow(GetDlgItem(hDlg, IDC_RDB), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_RDB_AUTHOR), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_RDB_VERSION), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_RDB_DATE), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_RDB_HOME), FALSE); + } + + set_about_field(hDlg, IDC_RDB_AUTHOR, wGS(INI_AUTHOR).c_str(), String); + + wcsncpy(String, RdbIniFile.GetString("Meta", "Version", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + set_about_field(hDlg, IDC_RDB_VERSION, wGS(INI_VERSION).c_str(), String); + wcsncpy(String, RdbIniFile.GetString("Meta", "Date", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + set_about_field(hDlg, IDC_RDB_DATE, wGS(INI_DATE).c_str(), String); + wcsncpy(RDBHomePage, RdbIniFile.GetString("Meta", "Homepage", "").ToUTF16().c_str(), sizeof(RDBHomePage) / sizeof(RDBHomePage[0])); + SetDlgItemTextW(hDlg, IDC_RDB_HOME, wGS(INI_HOMEPAGE).c_str()); + if (wcslen(RDBHomePage) == 0) + { + EnableWindow(GetDlgItem(hDlg, IDC_RDB_HOME), FALSE); + } + + //Cheat + SetDlgItemTextW(hDlg, IDC_CHT, wGS(INI_CURRENT_CHT).c_str()); + CIniFile CheatIniFile(g_Settings->LoadStringVal(SupportFile_Cheats).c_str()); + wcsncpy(String, CheatIniFile.GetString("Meta", "Author", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + if (wcslen(String) == 0) + { + EnableWindow(GetDlgItem(hDlg, IDC_CHT), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_CHT_AUTHOR), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_CHT_VERSION), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_CHT_DATE), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_CHT_HOME), FALSE); + } + set_about_field(hDlg, IDC_CHT_AUTHOR, wGS(INI_AUTHOR).c_str(), String); + wcsncpy(String, CheatIniFile.GetString("Meta", "Version", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + set_about_field(hDlg, IDC_CHT_VERSION, wGS(INI_VERSION).c_str(), String); + wcsncpy(String, CheatIniFile.GetString("Meta", "Date", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + set_about_field(hDlg, IDC_CHT_DATE, wGS(INI_DATE).c_str(), String); + wcsncpy(CHTHomePage, CheatIniFile.GetString("Meta", "Homepage", "").ToUTF16().c_str(), sizeof(CHTHomePage) / sizeof(CHTHomePage[0])); + SetDlgItemTextW(hDlg, IDC_CHT_HOME, wGS(INI_HOMEPAGE).c_str()); + if (wcslen(CHTHomePage) == 0) + { + EnableWindow(GetDlgItem(hDlg, IDC_CHT_HOME), FALSE); + } + + //Extended Info + SetDlgItemTextW(hDlg, IDC_RDX, wGS(INI_CURRENT_RDX).c_str()); + CIniFile RdxIniFile(g_Settings->LoadStringVal(SupportFile_ExtInfo).c_str()); + wcsncpy(String, RdxIniFile.GetString("Meta", "Author", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + if (wcslen(String) == 0) + { + EnableWindow(GetDlgItem(hDlg, IDC_RDX), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_RDX_AUTHOR), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_RDX_VERSION), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_RDX_DATE), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_RDX_HOME), FALSE); + } + set_about_field(hDlg, IDC_RDX_AUTHOR, wGS(INI_AUTHOR).c_str(), String); + wcsncpy(String, RdxIniFile.GetString("Meta", "Version", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + set_about_field(hDlg, IDC_RDX_VERSION, wGS(INI_VERSION).c_str(), String); + wcsncpy(String, RdxIniFile.GetString("Meta", "Date", "").ToUTF16().c_str(), sizeof(String) / sizeof(String[0])); + set_about_field(hDlg, IDC_RDX_DATE, wGS(INI_DATE).c_str(), String); + wcsncpy(RDXHomePage, RdxIniFile.GetString("Meta", "Homepage", "").ToUTF16().c_str(), sizeof(RDXHomePage) / sizeof(RDXHomePage[0])); + SetDlgItemTextW(hDlg, IDC_RDX_HOME, wGS(INI_HOMEPAGE).c_str()); + if (wcslen(RDXHomePage) == 0) + { + EnableWindow(GetDlgItem(hDlg, IDC_RDX_HOME), FALSE); + } + SetDlgItemTextW(hDlg, IDOK, wGS(CHEAT_OK).c_str()); + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_RDB_HOME: ShellExecuteW(NULL, L"open", RDBHomePage, NULL, NULL, SW_SHOWNORMAL); break; + case IDC_CHT_HOME: ShellExecuteW(NULL, L"open", CHTHomePage, NULL, NULL, SW_SHOWNORMAL); break; + case IDC_RDX_HOME: ShellExecuteW(NULL, L"open", RDXHomePage, NULL, NULL, SW_SHOWNORMAL); break; + case IDOK: + case IDCANCEL: + EndDialog(hDlg, 0); + break; + } + default: + return FALSE; + } + return TRUE; +} + +bool CMainGui::ResetPluginsInUiThread(CPlugins * plugins, CN64System * System) +{ + RESET_PLUGIN info; + info.system = System; + info.plugins = plugins; + info.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + bool bRes = true; + if (info.hEvent) + { + PostMessage(m_hMainWindow, WM_RESET_PLUGIN, (WPARAM)&bRes, (LPARAM)&info); +#ifdef _DEBUG + DWORD dwRes = WaitForSingleObject(info.hEvent, INFINITE); +#else + DWORD dwRes = WaitForSingleObject(info.hEvent, 5000); +#endif + dwRes = dwRes; + CloseHandle(info.hEvent); + } + else + { + WriteTrace(TraceUserInterface, TraceError, "Failed to create event"); + bRes = false; + } + Notify().RefreshMenu(); + return bRes; +} + +void CMainGui::BringToTop(void) +{ + CGuard Guard(m_CS); + SetForegroundWindow(m_hMainWindow); + SetFocus(GetDesktopWindow()); + Sleep(100); + SetFocus(m_hMainWindow); +} + +void CMainGui::MakeWindowOnTop(bool OnTop) +{ + CGuard Guard(m_CS); + SetWindowPos(m_hMainWindow, OnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW); +} + +void CMainGui::Caption(LPCWSTR Caption) +{ + CGuard Guard(m_CS); + SetWindowTextW(m_hMainWindow, Caption); +} + +void CMainGui::Create(const char * WindowTitle) +{ + stdstr_f VersionDisplay("Project64 %s", VER_FILE_VERSION_STR); + m_hMainWindow = CreateWindowExW(WS_EX_ACCEPTFILES, VersionDisplay.ToUTF16().c_str(), stdstr(WindowTitle).ToUTF16().c_str(), WS_OVERLAPPED | WS_CLIPCHILDREN | + WS_CLIPSIBLINGS | WS_SYSMENU | WS_MINIMIZEBOX, 5, 5, 640, 480, + NULL, NULL, GetModuleHandle(NULL), this); + m_Created = m_hMainWindow != NULL; +} + +void CMainGui::CreateStatusBar(void) +{ + m_hStatusWnd = (HWND)CreateStatusWindow(WS_CHILD | WS_VISIBLE, "", m_hMainWindow, StatusBarID); + SendMessage((HWND)m_hStatusWnd, SB_SETTEXT, 0, (LPARAM)""); +} + +WPARAM CMainGui::ProcessAllMessages(void) +{ + MSG msg; + + while (GetMessage(&msg, NULL, 0, 0)) + { + if (g_cheatUI != NULL && g_cheatUI->IsCheatMessage(&msg)) + { + continue; + } + + if (m_ResetPlugins) + { + m_ResetPlugins = false; + m_ResetInfo->res = m_ResetInfo->plugins->Reset(m_ResetInfo->system); + SetEvent(m_ResetInfo->hEvent); + m_ResetInfo = NULL; + } + if (g_cheatUI && g_cheatUI->IsCheatMessage(&msg)) { continue; } + if (m_Menu->ProcessAccelerator(m_hMainWindow, &msg)) { continue; } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return msg.wParam; +} + +bool CMainGui::ProcessGuiMessages(void) +{ + MSG msg; + + while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) + { + if (m_ResetPlugins) + { + m_ResetPlugins = false; + } + if (msg.message == WM_QUIT) + { + return true; + } + PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + if (m_Menu->ProcessAccelerator(m_hMainWindow, &msg)) { continue; } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return false; +} + +void CMainGui::Resize(DWORD /*fwSizeType*/, WORD nWidth, WORD nHeight) +{ + RECT clrect, swrect; + GetClientRect(m_hMainWindow, &clrect); + GetClientRect((HWND)m_hStatusWnd, &swrect); + + int Parts[2]; + Parts[0] = (nWidth - (int)(clrect.right * 0.25)); + Parts[1] = nWidth; + + SendMessage((HWND)m_hStatusWnd, SB_SETPARTS, 2, (LPARAM)&Parts[0]); + MoveWindow((HWND)m_hStatusWnd, 0, clrect.bottom - swrect.bottom, nWidth, nHeight, TRUE); +} + +void CMainGui::Show(bool Visible) +{ + m_MakingVisible = true; + + CGuard Guard(m_CS); + if (m_hMainWindow) + { + ShowWindow(m_hMainWindow, Visible ? SW_SHOW : SW_HIDE); + if (Visible && RomBrowserVisible()) + { + RomBrowserToTop(); + } + } + + m_MakingVisible = false; +} + +void CMainGui::EnterLogOptions(void) +{ + ::EnterLogOptions(m_hMainWindow); +} + +int CMainGui::Height(void) +{ + if (!m_hMainWindow) { return 0; } + + RECT rect; + GetWindowRect(m_hMainWindow, &rect); + return rect.bottom - rect.top; +} + +int CMainGui::Width(void) +{ + if (!m_hMainWindow) { return 0; } + + RECT rect; + GetWindowRect(m_hMainWindow, &rect); + return rect.right - rect.left; +} + +void CMainGui::SetPos(int X, int Y) +{ + SetWindowPos(m_hMainWindow, NULL, X, Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); +} + +void CMainGui::SetWindowMenu(CBaseMenu * Menu) +{ + m_AttachingMenu = true; + + HMENU hMenu = NULL; + { + CGuard Guard(m_CS); + m_Menu = Menu; + hMenu = (HMENU)Menu->GetHandle(); + } + + if (hMenu) + { + SetMenu(m_hMainWindow, hMenu); + } + + m_AttachingMenu = false; +} + +void CMainGui::RefreshMenu(void) +{ + if (!m_Menu) { return; } + m_Menu->ResetMenu(); +} + +void CMainGui::SetStatusText(int Panel, const wchar_t * Text) +{ + static wchar_t Message[2][500]; + if (Panel >= 2) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + wchar_t * Msg = Message[Panel]; + + memset(Msg, 0, sizeof(Message[0])); + _snwprintf(Msg, sizeof(Message[0]) / sizeof(Message[0][0]), L"%s", Text); + Msg[(sizeof(Message[0]) / sizeof(Message[0][0])) - 1] = 0; + if (GetCurrentThreadId() == m_ThreadId) + { + SendMessageW((HWND)m_hStatusWnd, SB_SETTEXTW, Panel, (LPARAM)Msg); + } + else { + PostMessageW((HWND)m_hStatusWnd, SB_SETTEXTW, Panel, (LPARAM)Msg); + } +} + +void CMainGui::ShowStatusBar(bool ShowBar) +{ + ShowWindow((HWND)m_hStatusWnd, ShowBar ? SW_SHOW : SW_HIDE); +} + +void CMainGui::SaveWindowLoc(void) +{ + bool flush = false; + if (m_SaveMainWindowPos) + { + m_SaveMainWindowPos = false; + g_Settings->SaveDword(UserInterface_MainWindowTop, m_SaveMainWindowTop); + g_Settings->SaveDword(UserInterface_MainWindowLeft, m_SaveMainWindowLeft); + flush = true; + } + + if (m_SaveRomBrowserPos) + { + m_SaveRomBrowserPos = false; + g_Settings->SaveDword(RomBrowser_Top, m_SaveRomBrowserTop); + g_Settings->SaveDword(RomBrowser_Left, m_SaveRomBrowserLeft); + flush = true; + } + + if (flush) + { + CSettingTypeApplication::Flush(); + } +} + +LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWORD lParam) +{ + switch (uMsg) + { + case WM_CREATE: + { + //record class for future usage + LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam; + CMainGui * _this = (CMainGui *)lpcs->lpCreateParams; + SetProp(hWnd, "Class", _this); + + _this->m_hMainWindow = hWnd; + _this->CreateStatusBar(); + + //Move the Main window to the location last executed from or center the window + int X = (GetSystemMetrics(SM_CXSCREEN) - _this->Width()) / 2; + int Y = (GetSystemMetrics(SM_CYSCREEN) - _this->Height()) / 2; + + g_Settings->LoadDword(UserInterface_MainWindowTop, (uint32_t &)Y); + g_Settings->LoadDword(UserInterface_MainWindowLeft, (uint32_t &)X); + + _this->SetPos(X, Y); + + _this->ChangeWinSize(640, 480); + } + break; + case WM_SYSCOMMAND: + switch (wParam) { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this && + _this->bCPURunning() && + !g_Settings->LoadBool(GameRunning_CPU_Paused) && + g_Settings->LoadDword(Setting_DisableScrSaver)) + { + return 0; + } + } + break; + case SC_MAXIMIZE: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this) + { + if (_this->RomBrowserVisible()) + { + _this->RomBrowserMaximize(true); + } + } + } + break; + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); + break; + case WM_MOVE: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + + if (!_this->m_bMainWindow || + !_this->m_Created || + _this->m_AttachingMenu || + _this->m_MakingVisible || + IsIconic(hWnd) || + _this->ShowingRomBrowser()) + { + break; + } + + if (IsZoomed(hWnd)) + { + if (_this->RomBrowserVisible()) + { + // save that browser is maximized + } + break; + } + + //get the current position of the window + RECT WinRect; + GetWindowRect(hWnd, &WinRect); + + //save the location of the window + if (_this->RomBrowserVisible()) + { + _this->m_SaveRomBrowserPos = true; + _this->m_SaveRomBrowserTop = WinRect.top; + _this->m_SaveRomBrowserLeft = WinRect.left; + } + else + { + _this->m_SaveMainWindowPos = true; + _this->m_SaveMainWindowTop = WinRect.top; + _this->m_SaveMainWindowLeft = WinRect.left; + } + KillTimer(hWnd, Timer_SetWindowPos); + SetTimer(hWnd, Timer_SetWindowPos, 1000, NULL); + } + if (CGuiSettings::bCPURunning() && g_BaseSystem) + { + if (g_Plugins->Gfx() && g_Plugins->Gfx()->MoveScreen) + { + WriteTrace(TraceGFXPlugin, TraceDebug, "Starting"); + g_Plugins->Gfx()->MoveScreen((int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam)); + WriteTrace(TraceGFXPlugin, TraceDebug, "Done"); + } + } + break; + case WM_TIMER: + if (wParam == Timer_SetWindowPos) + { + KillTimer(hWnd, Timer_SetWindowPos); + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + _this->SaveWindowLoc(); + break; + } + break; + case WM_SIZE: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this) { _this->Resize(wParam, LOWORD(lParam), HIWORD(lParam)); } + if (_this) + { + if (wParam == SIZE_MAXIMIZED) + { + if (_this->RomBrowserVisible()) + { + _this->RomBrowserMaximize(true); + } + } + _this->ResizeRomList(LOWORD(lParam), HIWORD(lParam)); + } + if (_this) + { + if (wParam == SIZE_RESTORED && _this->RomBrowserVisible()) + { + _this->RomBrowserMaximize(false); + } + } + } + break; + case WM_NOTIFY: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this == NULL || !_this->RomBrowserVisible() || !_this->RomListNotify(wParam, lParam)) + { + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + } + break; + case WM_DRAWITEM: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this) + { + if (!_this->RomListDrawItem(wParam, lParam)) + { + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + } + } + break; + case WM_PAINT: + { + // CMainGui * _this = (CMainGui *)GetProp(hWnd,"Class"); + // CN64System * System = _this->m_System; + + // if (bCPURunning() && Settings->Load(CPU_Paused)) { + // CPlugins * Plugins = System->Plugins(); + // if (Plugins->Gfx()->DrawScreen) { + // Plugins->Gfx()->DrawScreen(); + // } + // } + ValidateRect(hWnd, NULL); + } + break; + case WM_KEYUP: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + + if (_this->m_bMainWindow && bCPURunning()) + { + if (g_BaseSystem) + { + if (g_Plugins && g_Plugins->Control()->WM_KeyUp) { + g_Plugins->Control()->WM_KeyUp(wParam, lParam); + } + } + } + } + break; + case WM_KEYDOWN: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + + if (_this->m_bMainWindow && bCPURunning()) + { + if (g_BaseSystem) + { + if (g_Plugins && g_Plugins->Control()->WM_KeyDown) + { + g_Plugins->Control()->WM_KeyDown(wParam, lParam); + } + } + } + } + break; + case WM_SETFOCUS: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this->RomBrowserVisible()) + { + PostMessage(hWnd, WM_BROWSER_TOP, 0, 0); + break; + } + + if (_this->m_bMainWindow && bCPURunning() && bAutoSleep()) + { + if (g_BaseSystem) + { + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_AppGainedFocus); + } + } + } + break; + case WM_KILLFOCUS: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this->RomBrowserVisible()) + { + break; + } + + if (_this->m_bMainWindow && bCPURunning() && bAutoSleep()) + { + if (g_BaseSystem) + { + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_AppLostFocus); + } + } + } + break; + case WM_ACTIVATEAPP: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + DWORD fActive = (BOOL)wParam; + + if (fActive && _this->RomBrowserVisible()) + { + PostMessage(hWnd, WM_BROWSER_TOP, 0, 0); + } + if (_this->m_bMainWindow && bCPURunning()) + { + if (!fActive && g_Settings->LoadBool(UserInterface_InFullScreen)) + { + Notify().WindowMode(); + if (bAutoSleep() && g_BaseSystem) + { + //System->ExternalEvent(PauseCPU_AppLostActiveDelayed ); + } + break; + } + if (bAutoSleep() || fActive) + { + if (g_BaseSystem) + { + g_BaseSystem->ExternalEvent(fActive ? SysEvent_ResumeCPU_AppGainedActive : SysEvent_PauseCPU_AppLostActive); + } + } + } + } + break; + case WM_HIDE_CUROSR: + if (!wParam) + { + while (ShowCursor(FALSE) >= 0) { Sleep(0); } + } + else + { + while (ShowCursor(TRUE) < 0) { Sleep(0); } + } + break; + case WM_MAKE_FOCUS: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + _this->BringToTop(); + } + break; + case WM_BROWSER_TOP: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + _this->RomBrowserToTop(); + } + break; + case WM_RESET_PLUGIN: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this->m_ResetInfo != NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + _this->m_ResetInfo = (RESET_PLUGIN *)lParam; + _this->m_ResetPlugins = true; + } + break; + case WM_GAME_CLOSED: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + Notify().WindowMode(); + if (g_Settings->LoadDword(RomBrowser_Enabled)) + { + _this->ShowRomBrowser(); + } + _this->RefreshMenu(); + _this->MakeWindowOnTop(false); + _this->SetStatusText(0, L""); + _this->SetStatusText(1, L""); + } + break; + case WM_COMMAND: + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this == NULL) { break; } + + switch (LOWORD(wParam)) { + case ID_POPUPMENU_PLAYGAME: g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); break; + case ID_POPUPMENU_PLAYGAMEWITHDISK: + { + stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); + if ((IPLROM.length() <= 0) || (!g_BaseSystem->RunFileImageIPL(IPLROM.c_str()))) + { + // Open DDROM + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + g_BaseSystem->RunFileImageIPL(FileName); + // Open Disk + openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; + if (GetOpenFileName(&openfilename)) + { + if (g_BaseSystem->RunDiskImage(FileName)) + g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); + } + } + } + else + { + // Open Disk + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + if (g_BaseSystem->RunDiskImage(FileName)) + g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); + } + } + } + break; + case ID_POPUPMENU_ROMDIRECTORY: _this->SelectRomDir(); break; + case ID_POPUPMENU_REFRESHROMLIST: _this->RefreshRomBrowser(); break; + case ID_POPUPMENU_ROMINFORMATION: + { + RomInformation Info(_this->CurrentedSelectedRom()); + Info.DisplayInformation(hWnd); + } + break; + case ID_POPUPMENU_EDITSETTINGS: + case ID_POPUPMENU_EDITCHEATS: + { + CN64Rom Rom; + Rom.LoadN64Image(_this->CurrentedSelectedRom(), true); + Rom.SaveRomSettingID(true); + + if (LOWORD(wParam) == ID_POPUPMENU_EDITSETTINGS) + { + CSettingConfig SettingConfig(true); + SettingConfig.Display(hWnd); + } + + if (LOWORD(wParam) == ID_POPUPMENU_EDITCHEATS) + { + CCheatsUI * cheatUI = new CCheatsUI; + g_cheatUI = cheatUI; + cheatUI->SelectCheats(hWnd, true); + if (g_cheatUI == cheatUI) + { + g_cheatUI = NULL; + } + } + + if (g_Rom) + { + g_Rom->SaveRomSettingID(false); + } + else + { + Rom.ClearRomSettingID(); + } + } + break; + default: + if (_this->m_Menu) + { + if (LOWORD(wParam) > 5000 && LOWORD(wParam) <= 5100) + { + if (g_Plugins->RSP()) + { + g_Plugins->RSP()->ProcessMenuItem(LOWORD(wParam)); + } + } + else if (LOWORD(wParam) > 5100 && LOWORD(wParam) <= 5200) + { + if (g_Plugins->Gfx()) + { + WriteTrace(TraceGFXPlugin, TraceDebug, "Starting"); + g_Plugins->Gfx()->ProcessMenuItem(LOWORD(wParam)); + WriteTrace(TraceGFXPlugin, TraceDebug, "Done"); + } + } + else if (LOWORD(wParam) > 5200 && LOWORD(wParam) <= 5300) + { + if (g_Plugins->Gfx() && g_Plugins->Gfx()->OnRomBrowserMenuItem != NULL) + { + CN64Rom Rom; + if (!Rom.LoadN64Image(_this->CurrentedSelectedRom(), true)) + { + break; + } + Rom.SaveRomSettingID(true); + g_Notify->DisplayMessage(0, ""); + BYTE * RomHeader = Rom.GetRomAddress(); + WriteTrace(TraceGFXPlugin, TraceDebug, "OnRomBrowserMenuItem - Starting"); + g_Plugins->Gfx()->OnRomBrowserMenuItem(LOWORD(wParam), hWnd, RomHeader); + WriteTrace(TraceGFXPlugin, TraceDebug, "OnRomBrowserMenuItem - Done"); + if (g_Rom) + { + g_Rom->SaveRomSettingID(false); + } + else + { + g_Settings->SaveString(Game_IniKey, ""); + } + } + } + else if (_this->m_Menu->ProcessMessage(hWnd, HIWORD(wParam), LOWORD(wParam))) + { + return true; + } + } + } + } + break; + case WM_DROPFILES: + { + char filename[MAX_PATH]; + + HDROP hDrop = (HDROP)wParam; + DragQueryFile(hDrop, 0, filename, sizeof(filename)); + DragFinish(hDrop); + + stdstr ext = CPath(filename).GetExtension(); + if (!(_stricmp(ext.c_str(), "ndd") == 0)) + { + delete g_DDRom; + g_DDRom = NULL; + CN64System::RunFileImage(filename); + } + else + { + // Open Disk + if (CN64System::RunDiskImage(filename)) + { + stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); + if ((IPLROM.length() <= 0) || (!CN64System::RunFileImage(IPLROM.c_str()))) + { + // Open DDROM + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + CN64System::RunFileImage(FileName); + } + } + } + } + } + break; + case WM_DESTROY: + WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - start"); + { + CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this->m_bMainWindow) + { + Notify().WindowMode(); + } + _this->m_hMainWindow = NULL; + WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - 1"); + if (_this->m_bMainWindow) + { + _this->SaveRomListColoumnInfo(); + WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - 2"); + _this->SaveWindowLoc(); + } + } + WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - 3"); + RemoveProp(hWnd, "Class"); + WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - 4"); + PostQuitMessage(0); + WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - Done"); + break; + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return TRUE; +} + +DWORD CALLBACK AboutBoxProc(HWND hWnd, DWORD uMsg, DWORD wParam, DWORD lParam) +{ + static HBITMAP hbmpBackgroundTop = NULL; + static HFONT hPageHeadingFont = NULL; + static HFONT hTextFont = NULL; + static HFONT hAuthorFont = NULL; + + switch (uMsg) { + case WM_INITDIALOG: + { + //Title + SetWindowTextW(hWnd, wGS(PLUG_ABOUT).c_str()); + + // Use the size of the image + hbmpBackgroundTop = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_ABOUT_LOGO)); + + BITMAP bmTL; + GetObject(hbmpBackgroundTop, sizeof(BITMAP), &bmTL); + + hTextFont = ::CreateFont(18, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); + hAuthorFont = ::CreateFont(18, 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); + + hPageHeadingFont = ::CreateFont(24, 0, 0, 0, FW_BOLD, 0, FALSE, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial Bold"); + + SendDlgItemMessage(hWnd, IDC_VERSION, WM_SETFONT, (WPARAM)hTextFont, TRUE); + SendDlgItemMessage(hWnd, IDC_TEAM, WM_SETFONT, (WPARAM)hPageHeadingFont, TRUE); + SendDlgItemMessage(hWnd, IDC_THANKS, WM_SETFONT, (WPARAM)hPageHeadingFont, TRUE); + + SendDlgItemMessage(hWnd, IDC_ZILMAR, WM_SETFONT, (WPARAM)hAuthorFont, TRUE); + SendDlgItemMessage(hWnd, IDC_JABO, WM_SETFONT, (WPARAM)hAuthorFont, TRUE); + SendDlgItemMessage(hWnd, IDC_SMIFF, WM_SETFONT, (WPARAM)hAuthorFont, TRUE); + SendDlgItemMessage(hWnd, IDC_GENT, WM_SETFONT, (WPARAM)hAuthorFont, TRUE); + + SendDlgItemMessage(hWnd, IDC_ZILMAR_DETAILS, WM_SETFONT, (WPARAM)hTextFont, TRUE); + SendDlgItemMessage(hWnd, IDC_JABO_DETAILS, WM_SETFONT, (WPARAM)hTextFont, TRUE); + SendDlgItemMessage(hWnd, IDC_SMIFF_DETAILS, WM_SETFONT, (WPARAM)hTextFont, TRUE); + SendDlgItemMessage(hWnd, IDC_GENT_DETAILS, WM_SETFONT, (WPARAM)hTextFont, TRUE); + + SendDlgItemMessage(hWnd, IDC_THANK_LIST, WM_SETFONT, (WPARAM)hTextFont, TRUE); + + stdstr_f VersionDisplay("Version: %s", VER_FILE_VERSION_STR); + SetWindowText(GetDlgItem(hWnd, IDC_VERSION), VersionDisplay.c_str()); + } + break; + case WM_CTLCOLORSTATIC: + { + HDC hdcStatic = (HDC)wParam; + SetTextColor(hdcStatic, RGB(0, 0, 0)); + SetBkMode(hdcStatic, TRANSPARENT); + return (LONG)(LRESULT)((HBRUSH)GetStockObject(NULL_BRUSH)); + } + break; + case WM_ERASEBKGND: + { + HPEN outline; + HBRUSH fill; + RECT rect; + + outline = CreatePen(PS_SOLID, 1, 0x00FFFFFF); + fill = CreateSolidBrush(0x00FFFFFF); + SelectObject((HDC)wParam, outline); + SelectObject((HDC)wParam, fill); + + GetClientRect(hWnd, &rect); + + Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom); + } + break; + case WM_PAINT: + { + PAINTSTRUCT ps; + + if (BeginPaint(hWnd, &ps)) + { + RECT rcClient; + GetClientRect(hWnd, &rcClient); + + BITMAP bmTL_top; + GetObject(hbmpBackgroundTop, sizeof(BITMAP), &bmTL_top); + + HDC memdc = CreateCompatibleDC(ps.hdc); + HGDIOBJ save = SelectObject(memdc, hbmpBackgroundTop); + BitBlt(ps.hdc, 0, 0, bmTL_top.bmWidth, bmTL_top.bmHeight, memdc, 0, 0, SRCCOPY); + SelectObject(memdc, save); + DeleteDC(memdc); + + EndPaint(hWnd, &ps); + } + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: + if (hbmpBackgroundTop) + { + DeleteObject(hbmpBackgroundTop); + } + if (hTextFont) + { + ::DeleteObject(hTextFont); + } + if (hPageHeadingFont) + { + ::DeleteObject(hPageHeadingFont); + } + if (hAuthorFont) + { + ::DeleteObject(hAuthorFont); + } + //ReleaseCapture(); + EndDialog(hWnd, 0); + break; + } + default: + return FALSE; + } + return TRUE; +} + +BOOL set_about_field(HWND hDlg, int nIDDlgItem, const wchar_t * config_string, const wchar_t * language_string) +{ + wchar_t temp_string[200]; + + swprintf(temp_string, sizeof(temp_string) / sizeof(temp_string[0]), L"%s: %s", config_string, language_string); + return SetDlgItemTextW(hDlg, nIDDlgItem, temp_string); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/GuiClass.h b/Source/Project64/UserInterface/GuiClass.h index 04869ea96..d336f713d 100644 --- a/Source/Project64/UserInterface/GuiClass.h +++ b/Source/Project64/UserInterface/GuiClass.h @@ -1,145 +1,145 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include "../Settings/GuiSettings.h" -#include -#include - -class CGfxPlugin; //Plugin that controls the rendering -class CAudioPlugin; //Plugin for audio, need the hwnd -class CControl_Plugin; //Controller needs hwnd to see if it is the focused window -class CBaseMenu; //Menu for the gui -class CN64System; -class CriticalSection; - -enum -{ - WM_HIDE_CUROSR = WM_USER + 10, - WM_MAKE_FOCUS = WM_USER + 17, - WM_RESET_PLUGIN = WM_USER + 18, - WM_GAME_CLOSED = WM_USER + 19, - WM_BROWSER_TOP = WM_USER + 40, -}; - -class CMainGui : - public RenderWindow, - public CRomBrowser, - public CDebuggerUI, - private CGuiSettings -{ - enum { StatusBarID = 400 }; - - enum { Timer_SetWindowPos = 1 }; - - struct RESET_PLUGIN - { - CN64System * system; - CPlugins * plugins; - HANDLE hEvent; - bool res; - }; -public: - CMainGui(bool bMainWindow, const char * WindowTitle = ""); - ~CMainGui(void); - - //Message Processing - WPARAM ProcessAllMessages(void); - bool ProcessGuiMessages(void); - - //debugging functions - void EnterLogOptions(void); - - //Get Information about the window - int Height(void); //Get the Height of the window - int Width(void); //Get the Width of the window - - //Manipulate the state of the window - void SetPos(int X, int Y); //Move the window to this screen location - void Show(bool ShowWindow); //Show or Hide the current window - void MakeWindowOnTop(bool OnTop); - void BringToTop(void); - void Caption(LPCWSTR Caption); //Set the caption of the window - void SaveWindowLoc(void); - - //Menu Function - void SetWindowMenu(CBaseMenu * Menu); - void RefreshMenu(void); - CBaseMenu * GetMenuClass(void) { return m_Menu; } - - // Status bar - void SetStatusText(int Panel, const wchar_t * Text); - void ShowStatusBar(bool ShowBar); - - //About Window - void AboutIniBox(void); - void AboutBox(void); - - //Plugins - bool ResetPluginsInUiThread(CPlugins * plugins, CN64System * System); - - //Get Window Handle - void * GetWindowHandle(void) const { return m_hMainWindow; } - void * GetStatusBar(void) const { return m_hStatusWnd; } - void * GetModuleInstance(void) const; - -private: - CMainGui(void); // Disable default constructor - CMainGui(const CMainGui&); // Disable copy constructor - CMainGui& operator=(const CMainGui&); // Disable assignment - - friend CGfxPlugin; - friend CAudioPlugin; - friend CControl_Plugin; - - bool RegisterWinClass(void); - void ChangeWinSize(long width, long height); - void Create(const char * WindowTitle); - void CreateStatusBar(void); - void Resize(DWORD fwSizeType, WORD nWidth, WORD nHeight); //responding to WM_SIZE - void AddRecentRom(const char * ImagePath); - void SetWindowCaption(const wchar_t * Caption); - void ShowRomBrowser(void); - - friend DWORD CALLBACK AboutBoxProc(HWND, DWORD, DWORD, DWORD); - friend DWORD CALLBACK AboutIniBoxProc(HWND, DWORD, DWORD, DWORD); - static LRESULT CALLBACK MainGui_Proc(HWND, DWORD, DWORD, DWORD); - - friend void RomBowserEnabledChanged(CMainGui * Gui); - friend void RomBowserColoumnsChanged(CMainGui * Gui); - friend void RomBrowserRecursiveChanged(CMainGui * Gui); - static void LoadingInProgressChanged(CMainGui * Gui); - static void GameLoaded(CMainGui * Gui); - static void GamePaused(CMainGui * Gui); - static void GameCpuRunning(CMainGui * Gui); - - CBaseMenu * m_Menu; - - HWND m_hMainWindow, m_hStatusWnd; - DWORD m_ThreadId; - - const bool m_bMainWindow; - bool m_Created; - bool m_AttachingMenu; - bool m_MakingVisible; - bool m_ResetPlugins; - RESET_PLUGIN * m_ResetInfo; - - CriticalSection m_CS; - - bool m_SaveMainWindowPos; - LONG m_SaveMainWindowTop; - LONG m_SaveMainWindowLeft; - - bool m_SaveRomBrowserPos; - LONG m_SaveRomBrowserTop; - LONG m_SaveRomBrowserLeft; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include "../Settings/GuiSettings.h" +#include +#include + +class CGfxPlugin; //Plugin that controls the rendering +class CAudioPlugin; //Plugin for audio, need the hwnd +class CControl_Plugin; //Controller needs hwnd to see if it is the focused window +class CBaseMenu; //Menu for the gui +class CN64System; +class CriticalSection; + +enum +{ + WM_HIDE_CUROSR = WM_USER + 10, + WM_MAKE_FOCUS = WM_USER + 17, + WM_RESET_PLUGIN = WM_USER + 18, + WM_GAME_CLOSED = WM_USER + 19, + WM_BROWSER_TOP = WM_USER + 40, +}; + +class CMainGui : + public RenderWindow, + public CRomBrowser, + public CDebuggerUI, + private CGuiSettings +{ + enum { StatusBarID = 400 }; + + enum { Timer_SetWindowPos = 1 }; + + struct RESET_PLUGIN + { + CN64System * system; + CPlugins * plugins; + HANDLE hEvent; + bool res; + }; +public: + CMainGui(bool bMainWindow, const char * WindowTitle = ""); + ~CMainGui(void); + + //Message Processing + WPARAM ProcessAllMessages(void); + bool ProcessGuiMessages(void); + + //debugging functions + void EnterLogOptions(void); + + //Get Information about the window + int Height(void); //Get the Height of the window + int Width(void); //Get the Width of the window + + //Manipulate the state of the window + void SetPos(int X, int Y); //Move the window to this screen location + void Show(bool ShowWindow); //Show or Hide the current window + void MakeWindowOnTop(bool OnTop); + void BringToTop(void); + void Caption(LPCWSTR Caption); //Set the caption of the window + void SaveWindowLoc(void); + + //Menu Function + void SetWindowMenu(CBaseMenu * Menu); + void RefreshMenu(void); + CBaseMenu * GetMenuClass(void) { return m_Menu; } + + // Status bar + void SetStatusText(int Panel, const wchar_t * Text); + void ShowStatusBar(bool ShowBar); + + //About Window + void AboutIniBox(void); + void AboutBox(void); + + //Plugins + bool ResetPluginsInUiThread(CPlugins * plugins, CN64System * System); + + //Get Window Handle + void * GetWindowHandle(void) const { return m_hMainWindow; } + void * GetStatusBar(void) const { return m_hStatusWnd; } + void * GetModuleInstance(void) const; + +private: + CMainGui(void); // Disable default constructor + CMainGui(const CMainGui&); // Disable copy constructor + CMainGui& operator=(const CMainGui&); // Disable assignment + + friend CGfxPlugin; + friend CAudioPlugin; + friend CControl_Plugin; + + bool RegisterWinClass(void); + void ChangeWinSize(long width, long height); + void Create(const char * WindowTitle); + void CreateStatusBar(void); + void Resize(DWORD fwSizeType, WORD nWidth, WORD nHeight); //responding to WM_SIZE + void AddRecentRom(const char * ImagePath); + void SetWindowCaption(const wchar_t * Caption); + void ShowRomBrowser(void); + + friend DWORD CALLBACK AboutBoxProc(HWND, DWORD, DWORD, DWORD); + friend DWORD CALLBACK AboutIniBoxProc(HWND, DWORD, DWORD, DWORD); + static LRESULT CALLBACK MainGui_Proc(HWND, DWORD, DWORD, DWORD); + + friend void RomBowserEnabledChanged(CMainGui * Gui); + friend void RomBowserColoumnsChanged(CMainGui * Gui); + friend void RomBrowserRecursiveChanged(CMainGui * Gui); + static void LoadingInProgressChanged(CMainGui * Gui); + static void GameLoaded(CMainGui * Gui); + static void GamePaused(CMainGui * Gui); + static void GameCpuRunning(CMainGui * Gui); + + CBaseMenu * m_Menu; + + HWND m_hMainWindow, m_hStatusWnd; + DWORD m_ThreadId; + + const bool m_bMainWindow; + bool m_Created; + bool m_AttachingMenu; + bool m_MakingVisible; + bool m_ResetPlugins; + RESET_PLUGIN * m_ResetInfo; + + CriticalSection m_CS; + + bool m_SaveMainWindowPos; + LONG m_SaveMainWindowTop; + LONG m_SaveMainWindowLeft; + + bool m_SaveRomBrowserPos; + LONG m_SaveRomBrowserTop; + LONG m_SaveRomBrowserLeft; +}; diff --git a/Source/Project64/UserInterface/LoggingUI.cpp b/Source/Project64/UserInterface/LoggingUI.cpp index fc2f25151..28c2aa33f 100644 --- a/Source/Project64/UserInterface/LoggingUI.cpp +++ b/Source/Project64/UserInterface/LoggingUI.cpp @@ -1,170 +1,170 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include - -LRESULT CALLBACK LogGeneralProc(HWND, UINT, WPARAM, LPARAM); -LRESULT CALLBACK LogPifProc(HWND, UINT, WPARAM, LPARAM); -LRESULT CALLBACK LogRegProc(HWND, UINT, WPARAM, LPARAM); - -void EnterLogOptions(HWND hwndOwner) -{ - PROPSHEETPAGE psp[3]; - PROPSHEETHEADER psh; - CLogSettings logSettings; - - psp[0].dwSize = sizeof(PROPSHEETPAGE); - psp[0].dwFlags = PSP_USETITLE; - psp[0].hInstance = GetModuleHandle(NULL); - psp[0].pszTemplate = MAKEINTRESOURCE(IDD_Logging_Registers); - psp[0].pfnDlgProc = (DLGPROC)LogRegProc; - psp[0].pszTitle = "Registers"; - psp[0].lParam = (LPARAM)&logSettings; - psp[0].pfnCallback = NULL; - - psp[1].dwSize = sizeof(PROPSHEETPAGE); - psp[1].dwFlags = PSP_USETITLE; - psp[1].hInstance = GetModuleHandle(NULL); - psp[1].pszTemplate = MAKEINTRESOURCE(IDD_Logging_PifRam); - psp[1].pfnDlgProc = (DLGPROC)LogPifProc; - psp[1].pszTitle = "Pif Ram"; - psp[1].lParam = (LPARAM)&logSettings; - psp[1].pfnCallback = NULL; - - psp[2].dwSize = sizeof(PROPSHEETPAGE); - psp[2].dwFlags = PSP_USETITLE; - psp[2].hInstance = GetModuleHandle(NULL); - psp[2].pszTemplate = MAKEINTRESOURCE(IDD_Logging_General); - psp[2].pfnDlgProc = (DLGPROC)LogGeneralProc; - psp[2].pszTitle = "General"; - psp[2].lParam = (LPARAM)&logSettings; - psp[2].pfnCallback = NULL; - - psh.dwSize = sizeof(PROPSHEETHEADER); - psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; - psh.hwndParent = hwndOwner; - psh.hInstance = GetModuleHandle(NULL); - psh.pszCaption = (LPSTR) "Log Options"; - psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE); - psh.nStartPage = 0; - psh.ppsp = (LPCPROPSHEETPAGE)&psp; - psh.pfnCallback = NULL; - - PropertySheet(&psh); - return; -} - -LRESULT CALLBACK LogGeneralProc(HWND hDlg, UINT uMsg, WPARAM /*wParam*/, LPARAM lParam) -{ - switch (uMsg) - { - case WM_INITDIALOG: - { - if (CLogSettings::LogCP0changes()) { CheckDlgButton(hDlg, IDC_CP0_WRITE, BST_CHECKED); } - if (CLogSettings::LogCP0reads()) { CheckDlgButton(hDlg, IDC_CP0_READ, BST_CHECKED); } - if (CLogSettings::LogCache()) { CheckDlgButton(hDlg, IDC_CACHE, BST_CHECKED); } - if (CLogSettings::LogExceptions()) { CheckDlgButton(hDlg, IDC_EXCEPTIONS, BST_CHECKED); } - if (CLogSettings::LogNoInterrupts()) { CheckDlgButton(hDlg, IDC_INTERRUPTS, BST_CHECKED); } - if (CLogSettings::LogTLB()) { CheckDlgButton(hDlg, IDC_TLB, BST_CHECKED); } - if (CLogSettings::LogRomHeader()) { CheckDlgButton(hDlg, IDC_ROM_HEADER, BST_CHECKED); } - if (CLogSettings::LogUnknown()) { CheckDlgButton(hDlg, IDC_UNKOWN, BST_CHECKED); } - } - break; - case WM_NOTIFY: - if (((NMHDR FAR *) lParam)->code != PSN_APPLY) { break; } - g_Settings->SaveBool(Logging_LogCP0changes, IsDlgButtonChecked(hDlg, IDC_CP0_WRITE) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogCP0reads, IsDlgButtonChecked(hDlg, IDC_CP0_READ) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogCache, IsDlgButtonChecked(hDlg, IDC_CACHE) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogExceptions, IsDlgButtonChecked(hDlg, IDC_EXCEPTIONS) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_NoInterrupts, IsDlgButtonChecked(hDlg, IDC_INTERRUPTS) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogTLB, IsDlgButtonChecked(hDlg, IDC_TLB) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogRomHeader, IsDlgButtonChecked(hDlg, IDC_ROM_HEADER) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogUnknown, IsDlgButtonChecked(hDlg, IDC_UNKOWN) == BST_CHECKED ? true : false); - break; - default: - return FALSE; - } - return TRUE; -} - -LRESULT CALLBACK LogPifProc(HWND hDlg, UINT uMsg, WPARAM /*wParam*/, LPARAM lParam) -{ - switch (uMsg) - { - case WM_INITDIALOG: - { - if (CLogSettings::LogPRDMAOperations()) { CheckDlgButton(hDlg, IDC_SI_DMA, BST_CHECKED); } - if (CLogSettings::LogPRDirectMemLoads()) { CheckDlgButton(hDlg, IDC_DIRECT_WRITE, BST_CHECKED); } - if (CLogSettings::LogPRDMAMemLoads()) { CheckDlgButton(hDlg, IDC_DMA_WRITE, BST_CHECKED); } - if (CLogSettings::LogPRDirectMemStores()) { CheckDlgButton(hDlg, IDC_DIRECT_READ, BST_CHECKED); } - if (CLogSettings::LogPRDMAMemStores()) { CheckDlgButton(hDlg, IDC_DMA_READ, BST_CHECKED); } - if (CLogSettings::LogControllerPak()) { CheckDlgButton(hDlg, IDC_CONT_PAK, BST_CHECKED); } - } - break; - case WM_NOTIFY: - if (((NMHDR FAR *) lParam)->code != PSN_APPLY) - { - break; - } - g_Settings->SaveBool(Logging_LogPRDMAOperations, IsDlgButtonChecked(hDlg, IDC_SI_DMA) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogPRDirectMemLoads, IsDlgButtonChecked(hDlg, IDC_DIRECT_WRITE) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogPRDMAMemLoads, IsDlgButtonChecked(hDlg, IDC_DMA_WRITE) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogPRDirectMemStores, IsDlgButtonChecked(hDlg, IDC_DIRECT_READ) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogPRDMAMemStores, IsDlgButtonChecked(hDlg, IDC_DMA_READ) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogControllerPak, IsDlgButtonChecked(hDlg, IDC_CONT_PAK) == BST_CHECKED ? true : false); - break; - default: - return FALSE; - } - return TRUE; -} - -LRESULT CALLBACK LogRegProc(HWND hDlg, UINT uMsg, WPARAM /*wParam*/, LPARAM lParam) -{ - switch (uMsg) - { - case WM_INITDIALOG: - { - if (CLogSettings::LogRDRamRegisters()) { CheckDlgButton(hDlg, IDC_RDRAM, BST_CHECKED); } - if (CLogSettings::LogSPRegisters()) { CheckDlgButton(hDlg, IDC_SP_REG, BST_CHECKED); } - if (CLogSettings::LogDPCRegisters()) { CheckDlgButton(hDlg, IDC_DPC_REG, BST_CHECKED); } - if (CLogSettings::LogDPSRegisters()) { CheckDlgButton(hDlg, IDC_DPS_REG, BST_CHECKED); } - if (CLogSettings::LogMIPSInterface()) { CheckDlgButton(hDlg, IDC_MI_REG, BST_CHECKED); } - if (CLogSettings::LogVideoInterface()) { CheckDlgButton(hDlg, IDC_VI_REG, BST_CHECKED); } - if (CLogSettings::LogAudioInterface()) { CheckDlgButton(hDlg, IDC_AI_REG, BST_CHECKED); } - if (CLogSettings::LogPerInterface()) { CheckDlgButton(hDlg, IDC_PI_REG, BST_CHECKED); } - if (CLogSettings::LogRDRAMInterface()) { CheckDlgButton(hDlg, IDC_RI_REG, BST_CHECKED); } - if (CLogSettings::LogSerialInterface()) { CheckDlgButton(hDlg, IDC_SI_REG, BST_CHECKED); } - } - break; - case WM_NOTIFY: - if (((NMHDR FAR *) lParam)->code != PSN_APPLY) - { - break; - } - g_Settings->SaveBool(Logging_LogRDRamRegisters, IsDlgButtonChecked(hDlg, IDC_RDRAM) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogSPRegisters, IsDlgButtonChecked(hDlg, IDC_SP_REG) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogDPCRegisters, IsDlgButtonChecked(hDlg, IDC_DPC_REG) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogDPSRegisters, IsDlgButtonChecked(hDlg, IDC_DPS_REG) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogMIPSInterface, IsDlgButtonChecked(hDlg, IDC_MI_REG) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogVideoInterface, IsDlgButtonChecked(hDlg, IDC_VI_REG) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogAudioInterface, IsDlgButtonChecked(hDlg, IDC_AI_REG) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogPerInterface, IsDlgButtonChecked(hDlg, IDC_PI_REG) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogRDRAMInterface, IsDlgButtonChecked(hDlg, IDC_RI_REG) == BST_CHECKED ? true : false); - g_Settings->SaveBool(Logging_LogSerialInterface, IsDlgButtonChecked(hDlg, IDC_SI_REG) == BST_CHECKED ? true : false); - break; - default: - return FALSE; - } - return TRUE; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include + +LRESULT CALLBACK LogGeneralProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK LogPifProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK LogRegProc(HWND, UINT, WPARAM, LPARAM); + +void EnterLogOptions(HWND hwndOwner) +{ + PROPSHEETPAGE psp[3]; + PROPSHEETHEADER psh; + CLogSettings logSettings; + + psp[0].dwSize = sizeof(PROPSHEETPAGE); + psp[0].dwFlags = PSP_USETITLE; + psp[0].hInstance = GetModuleHandle(NULL); + psp[0].pszTemplate = MAKEINTRESOURCE(IDD_Logging_Registers); + psp[0].pfnDlgProc = (DLGPROC)LogRegProc; + psp[0].pszTitle = "Registers"; + psp[0].lParam = (LPARAM)&logSettings; + psp[0].pfnCallback = NULL; + + psp[1].dwSize = sizeof(PROPSHEETPAGE); + psp[1].dwFlags = PSP_USETITLE; + psp[1].hInstance = GetModuleHandle(NULL); + psp[1].pszTemplate = MAKEINTRESOURCE(IDD_Logging_PifRam); + psp[1].pfnDlgProc = (DLGPROC)LogPifProc; + psp[1].pszTitle = "Pif Ram"; + psp[1].lParam = (LPARAM)&logSettings; + psp[1].pfnCallback = NULL; + + psp[2].dwSize = sizeof(PROPSHEETPAGE); + psp[2].dwFlags = PSP_USETITLE; + psp[2].hInstance = GetModuleHandle(NULL); + psp[2].pszTemplate = MAKEINTRESOURCE(IDD_Logging_General); + psp[2].pfnDlgProc = (DLGPROC)LogGeneralProc; + psp[2].pszTitle = "General"; + psp[2].lParam = (LPARAM)&logSettings; + psp[2].pfnCallback = NULL; + + psh.dwSize = sizeof(PROPSHEETHEADER); + psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; + psh.hwndParent = hwndOwner; + psh.hInstance = GetModuleHandle(NULL); + psh.pszCaption = (LPSTR) "Log Options"; + psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE); + psh.nStartPage = 0; + psh.ppsp = (LPCPROPSHEETPAGE)&psp; + psh.pfnCallback = NULL; + + PropertySheet(&psh); + return; +} + +LRESULT CALLBACK LogGeneralProc(HWND hDlg, UINT uMsg, WPARAM /*wParam*/, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + if (CLogSettings::LogCP0changes()) { CheckDlgButton(hDlg, IDC_CP0_WRITE, BST_CHECKED); } + if (CLogSettings::LogCP0reads()) { CheckDlgButton(hDlg, IDC_CP0_READ, BST_CHECKED); } + if (CLogSettings::LogCache()) { CheckDlgButton(hDlg, IDC_CACHE, BST_CHECKED); } + if (CLogSettings::LogExceptions()) { CheckDlgButton(hDlg, IDC_EXCEPTIONS, BST_CHECKED); } + if (CLogSettings::LogNoInterrupts()) { CheckDlgButton(hDlg, IDC_INTERRUPTS, BST_CHECKED); } + if (CLogSettings::LogTLB()) { CheckDlgButton(hDlg, IDC_TLB, BST_CHECKED); } + if (CLogSettings::LogRomHeader()) { CheckDlgButton(hDlg, IDC_ROM_HEADER, BST_CHECKED); } + if (CLogSettings::LogUnknown()) { CheckDlgButton(hDlg, IDC_UNKOWN, BST_CHECKED); } + } + break; + case WM_NOTIFY: + if (((NMHDR FAR *) lParam)->code != PSN_APPLY) { break; } + g_Settings->SaveBool(Logging_LogCP0changes, IsDlgButtonChecked(hDlg, IDC_CP0_WRITE) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogCP0reads, IsDlgButtonChecked(hDlg, IDC_CP0_READ) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogCache, IsDlgButtonChecked(hDlg, IDC_CACHE) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogExceptions, IsDlgButtonChecked(hDlg, IDC_EXCEPTIONS) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_NoInterrupts, IsDlgButtonChecked(hDlg, IDC_INTERRUPTS) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogTLB, IsDlgButtonChecked(hDlg, IDC_TLB) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogRomHeader, IsDlgButtonChecked(hDlg, IDC_ROM_HEADER) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogUnknown, IsDlgButtonChecked(hDlg, IDC_UNKOWN) == BST_CHECKED ? true : false); + break; + default: + return FALSE; + } + return TRUE; +} + +LRESULT CALLBACK LogPifProc(HWND hDlg, UINT uMsg, WPARAM /*wParam*/, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + if (CLogSettings::LogPRDMAOperations()) { CheckDlgButton(hDlg, IDC_SI_DMA, BST_CHECKED); } + if (CLogSettings::LogPRDirectMemLoads()) { CheckDlgButton(hDlg, IDC_DIRECT_WRITE, BST_CHECKED); } + if (CLogSettings::LogPRDMAMemLoads()) { CheckDlgButton(hDlg, IDC_DMA_WRITE, BST_CHECKED); } + if (CLogSettings::LogPRDirectMemStores()) { CheckDlgButton(hDlg, IDC_DIRECT_READ, BST_CHECKED); } + if (CLogSettings::LogPRDMAMemStores()) { CheckDlgButton(hDlg, IDC_DMA_READ, BST_CHECKED); } + if (CLogSettings::LogControllerPak()) { CheckDlgButton(hDlg, IDC_CONT_PAK, BST_CHECKED); } + } + break; + case WM_NOTIFY: + if (((NMHDR FAR *) lParam)->code != PSN_APPLY) + { + break; + } + g_Settings->SaveBool(Logging_LogPRDMAOperations, IsDlgButtonChecked(hDlg, IDC_SI_DMA) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogPRDirectMemLoads, IsDlgButtonChecked(hDlg, IDC_DIRECT_WRITE) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogPRDMAMemLoads, IsDlgButtonChecked(hDlg, IDC_DMA_WRITE) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogPRDirectMemStores, IsDlgButtonChecked(hDlg, IDC_DIRECT_READ) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogPRDMAMemStores, IsDlgButtonChecked(hDlg, IDC_DMA_READ) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogControllerPak, IsDlgButtonChecked(hDlg, IDC_CONT_PAK) == BST_CHECKED ? true : false); + break; + default: + return FALSE; + } + return TRUE; +} + +LRESULT CALLBACK LogRegProc(HWND hDlg, UINT uMsg, WPARAM /*wParam*/, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + if (CLogSettings::LogRDRamRegisters()) { CheckDlgButton(hDlg, IDC_RDRAM, BST_CHECKED); } + if (CLogSettings::LogSPRegisters()) { CheckDlgButton(hDlg, IDC_SP_REG, BST_CHECKED); } + if (CLogSettings::LogDPCRegisters()) { CheckDlgButton(hDlg, IDC_DPC_REG, BST_CHECKED); } + if (CLogSettings::LogDPSRegisters()) { CheckDlgButton(hDlg, IDC_DPS_REG, BST_CHECKED); } + if (CLogSettings::LogMIPSInterface()) { CheckDlgButton(hDlg, IDC_MI_REG, BST_CHECKED); } + if (CLogSettings::LogVideoInterface()) { CheckDlgButton(hDlg, IDC_VI_REG, BST_CHECKED); } + if (CLogSettings::LogAudioInterface()) { CheckDlgButton(hDlg, IDC_AI_REG, BST_CHECKED); } + if (CLogSettings::LogPerInterface()) { CheckDlgButton(hDlg, IDC_PI_REG, BST_CHECKED); } + if (CLogSettings::LogRDRAMInterface()) { CheckDlgButton(hDlg, IDC_RI_REG, BST_CHECKED); } + if (CLogSettings::LogSerialInterface()) { CheckDlgButton(hDlg, IDC_SI_REG, BST_CHECKED); } + } + break; + case WM_NOTIFY: + if (((NMHDR FAR *) lParam)->code != PSN_APPLY) + { + break; + } + g_Settings->SaveBool(Logging_LogRDRamRegisters, IsDlgButtonChecked(hDlg, IDC_RDRAM) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogSPRegisters, IsDlgButtonChecked(hDlg, IDC_SP_REG) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogDPCRegisters, IsDlgButtonChecked(hDlg, IDC_DPC_REG) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogDPSRegisters, IsDlgButtonChecked(hDlg, IDC_DPS_REG) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogMIPSInterface, IsDlgButtonChecked(hDlg, IDC_MI_REG) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogVideoInterface, IsDlgButtonChecked(hDlg, IDC_VI_REG) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogAudioInterface, IsDlgButtonChecked(hDlg, IDC_AI_REG) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogPerInterface, IsDlgButtonChecked(hDlg, IDC_PI_REG) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogRDRAMInterface, IsDlgButtonChecked(hDlg, IDC_RI_REG) == BST_CHECKED ? true : false); + g_Settings->SaveBool(Logging_LogSerialInterface, IsDlgButtonChecked(hDlg, IDC_SI_REG) == BST_CHECKED ? true : false); + break; + default: + return FALSE; + } + return TRUE; } \ No newline at end of file diff --git a/Source/Project64/UserInterface/LoggingUI.h b/Source/Project64/UserInterface/LoggingUI.h index de73fcab0..ee12f33da 100644 --- a/Source/Project64/UserInterface/LoggingUI.h +++ b/Source/Project64/UserInterface/LoggingUI.h @@ -1,13 +1,13 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -void EnterLogOptions ( HWND hwndOwner ); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +void EnterLogOptions ( HWND hwndOwner ); diff --git a/Source/Project64/UserInterface/MainMenuClass.cpp b/Source/Project64/UserInterface/MainMenuClass.cpp index 9cd63e182..17095778d 100644 --- a/Source/Project64/UserInterface/MainMenuClass.cpp +++ b/Source/Project64/UserInterface/MainMenuClass.cpp @@ -1,1280 +1,1280 @@ -#include "stdafx.h" -#include "RomInformationClass.h" - -#include -#include - -CMainMenu::CMainMenu(CMainGui * hMainWindow) : -CBaseMenu(), -m_ResetAccelerators(true), -m_Gui(hMainWindow) -{ - ResetMenu(); - - hMainWindow->SetWindowMenu(this); - - m_ChangeSettingList.push_back(Info_ShortCutsChanged); - m_ChangeSettingList.push_back(GameRunning_LimitFPS); - m_ChangeSettingList.push_back(UserInterface_InFullScreen); - m_ChangeSettingList.push_back(UserInterface_AlwaysOnTop); - m_ChangeSettingList.push_back(UserInterface_ShowCPUPer); - m_ChangeSettingList.push_back(Logging_GenerateLog); - m_ChangeSettingList.push_back(Debugger_ProfileCode); - m_ChangeSettingList.push_back(Debugger_ShowTLBMisses); - m_ChangeSettingList.push_back(Debugger_ShowUnhandledMemory); - m_ChangeSettingList.push_back(Debugger_ShowPifErrors); - m_ChangeSettingList.push_back(Debugger_ShowDListAListCount); - m_ChangeSettingList.push_back(Debugger_ShowRecompMemSize); - m_ChangeSettingList.push_back(Debugger_ShowDivByZero); - m_ChangeSettingList.push_back(Debugger_GenerateLogFiles); - m_ChangeSettingList.push_back(Debugger_DisableGameFixes); - m_ChangeSettingList.push_back(Debugger_TraceMD5); - m_ChangeSettingList.push_back(Debugger_TraceSettings); - m_ChangeSettingList.push_back(Debugger_TraceUnknown); - m_ChangeSettingList.push_back(Debugger_TraceAppInit); - m_ChangeSettingList.push_back(Debugger_TraceAppCleanup); - m_ChangeSettingList.push_back(Debugger_TraceN64System); - m_ChangeSettingList.push_back(Debugger_TracePlugins); - m_ChangeSettingList.push_back(Debugger_TraceGFXPlugin); - m_ChangeSettingList.push_back(Debugger_TraceAudioPlugin); - m_ChangeSettingList.push_back(Debugger_TraceControllerPlugin); - m_ChangeSettingList.push_back(Debugger_TraceRSPPlugin); - m_ChangeSettingList.push_back(Debugger_TraceRSP); - m_ChangeSettingList.push_back(Debugger_TraceAudio); - m_ChangeSettingList.push_back(Debugger_TraceRegisterCache); - m_ChangeSettingList.push_back(Debugger_TraceRecompiler); - m_ChangeSettingList.push_back(Debugger_TraceTLB); - m_ChangeSettingList.push_back(Debugger_TraceProtectedMEM); - m_ChangeSettingList.push_back(Debugger_TraceUserInterface); - m_ChangeSettingList.push_back(Debugger_AppLogFlush); - m_ChangeSettingList.push_back(Game_CurrentSaveState); - m_ChangeSettingList.push_back(Setting_CurrentLanguage); - - for (SettingList::const_iterator iter = m_ChangeSettingList.begin(); iter != m_ChangeSettingList.end(); iter++) - { - g_Settings->RegisterChangeCB(*iter, this, (CSettings::SettingChangedFunc)SettingsChanged); - } -} - -CMainMenu::~CMainMenu() -{ - for (SettingList::const_iterator iter = m_ChangeSettingList.begin(); iter != m_ChangeSettingList.end(); iter++) - { - g_Settings->UnregisterChangeCB(*iter, this, (CSettings::SettingChangedFunc)SettingsChanged); - } -} - -void CMainMenu::SettingsChanged(CMainMenu * _this) -{ - _this->ResetMenu(); -} - -int CMainMenu::ProcessAccelerator(HWND hWnd, void * lpMsg) -{ - if (m_ResetAccelerators) - { - m_ResetAccelerators = false; - RebuildAccelerators(); - } - if (!m_AccelTable) { return false; } - return TranslateAccelerator((HWND)hWnd, (HACCEL)m_AccelTable, (LPMSG)lpMsg); -} - -stdstr CMainMenu::ChooseFileToOpen(HWND hParent) -{ - OPENFILENAME openfilename; - char FileName[_MAX_PATH], Directory[_MAX_PATH]; - - memset(&FileName, 0, sizeof(FileName)); - memset(&openfilename, 0, sizeof(openfilename)); - - strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); - - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hParent; - openfilename.lpstrFilter = "N64 ROMs (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin, *.ndd)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal;*.ndd\0All files (*.*)\0*.*\0"; - openfilename.lpstrFile = FileName; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - - if (GetOpenFileName(&openfilename)) - { - return stdstr(FileName); - } - return stdstr(""); -} - -void CMainMenu::SetTraceModuleSetttings(SettingID Type) -{ - uint32_t value = g_Settings->LoadDword(Type) == TraceVerbose ? g_Settings->LoadDefaultDword(Type) : TraceVerbose; - g_Settings->SaveDword(Type, value); -} - -bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuID) -{ - switch (MenuID) { - case ID_FILE_OPEN_ROM: - { - stdstr File = ChooseFileToOpen(hWnd); - if (File.length() > 0) - { - stdstr ext = CPath(File).GetExtension(); - if (!(_stricmp(ext.c_str(), "ndd") == 0)) - { - delete g_DDRom; - g_DDRom = NULL; - g_BaseSystem->RunFileImage(File.c_str()); - } - else - { - // Open Disk - if (g_BaseSystem->RunDiskImage(File.c_str())) - { - stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); - if ((IPLROM.length() <= 0) || (!g_BaseSystem->RunFileImage(IPLROM.c_str()))) - { - // Open DDROM - OPENFILENAME openfilename; - char FileName[_MAX_PATH], Directory[_MAX_PATH]; - memset(&FileName, 0, sizeof(FileName)); - memset(&openfilename, 0, sizeof(openfilename)); - - strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hWnd; - openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; - openfilename.lpstrFile = FileName; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - - if (GetOpenFileName(&openfilename)) - { - g_BaseSystem->RunFileImage(FileName); - } - } - } - } - - } - } - break; - case ID_FILE_ROM_INFO: - { - if (g_Rom) - { - RomInformation Info(g_Rom); - Info.DisplayInformation(hWnd); - } - } - break; - case ID_FILE_STARTEMULATION: - m_Gui->SaveWindowLoc(); - //Before we go and create the new system, ensure the previous one has been closed - CN64System::CloseSystem(); - //Ok now g_BaseSystem should definitely be clean for initialization - g_BaseSystem = new CN64System(g_Plugins, false); - //Now we have created again, we can start up emulation - g_BaseSystem->StartEmulation(true); - break; - case ID_FILE_ENDEMULATION: - WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ENDEMULATION"); - CN64System::CloseSystem(); - m_Gui->SaveWindowLoc(); - break; - case ID_FILE_ROMDIRECTORY: - WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ROMDIRECTORY 1"); - m_Gui->SelectRomDir(); - WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ROMDIRECTORY 2"); - m_Gui->RefreshMenu(); - WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ROMDIRECTORY 3"); - break; - case ID_FILE_REFRESHROMLIST: m_Gui->RefreshRomBrowser(); break; - case ID_FILE_EXIT: DestroyWindow((HWND)hWnd); break; - case ID_SYSTEM_RESET_SOFT: - WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_RESET_SOFT"); - g_BaseSystem->ExternalEvent(SysEvent_ResetCPU_Soft); - break; - case ID_SYSTEM_RESET_HARD: - WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_RESET_HARD"); - g_BaseSystem->ExternalEvent(SysEvent_ResetCPU_Hard); - break; - case ID_SYSTEM_PAUSE: - m_Gui->SaveWindowLoc(); - WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_PAUSE"); - g_BaseSystem->ExternalEvent(g_Settings->LoadBool(GameRunning_CPU_Paused) ? SysEvent_ResumeCPU_FromMenu : SysEvent_PauseCPU_FromMenu); - WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_PAUSE 1"); - break; - case ID_SYSTEM_BITMAP: - { - stdstr Dir(g_Settings->LoadStringVal(Directory_SnapShot)); - WriteTrace(TraceGFXPlugin, TraceDebug, "CaptureScreen(%s): Starting", Dir.c_str()); - g_Plugins->Gfx()->CaptureScreen(Dir.c_str()); - WriteTrace(TraceGFXPlugin, TraceDebug, "CaptureScreen: Done"); - } - break; - case ID_SYSTEM_LIMITFPS: - WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_LIMITFPS"); - g_Settings->SaveBool(GameRunning_LimitFPS, !g_Settings->LoadBool(GameRunning_LimitFPS)); - WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_LIMITFPS 1"); - break; - case ID_SYSTEM_SAVE: - WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_SAVE"); - g_BaseSystem->ExternalEvent(SysEvent_SaveMachineState); - break; - case ID_SYSTEM_SAVEAS: - { - char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; - char Directory[255], SaveFile[255]; - OPENFILENAME openfilename; - - memset(&SaveFile, 0, sizeof(SaveFile)); - memset(&openfilename, 0, sizeof(openfilename)); - - g_Settings->LoadStringVal(Directory_LastSave, Directory, sizeof(Directory)); - - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hWnd; - openfilename.lpstrFilter = "PJ64 Saves (*.zip, *.pj)\0*.pj?;*.pj;*.zip;"; - openfilename.lpstrFile = SaveFile; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_HIDEREADONLY; - - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SaveGame); - if (GetSaveFileName(&openfilename)) - { - _splitpath(SaveFile, drive, dir, fname, ext); - if (_stricmp(ext, ".pj") == 0 || _stricmp(ext, ".zip") == 0) - { - _makepath(SaveFile, drive, dir, fname, NULL); - _splitpath(SaveFile, drive, dir, fname, ext); - if (_stricmp(ext, ".pj") == 0) - { - _makepath(SaveFile, drive, dir, fname, NULL); - } - } - g_Settings->SaveString(GameRunning_InstantSaveFile, SaveFile); - - char SaveDir[MAX_PATH]; - _makepath(SaveDir, drive, dir, NULL, NULL); - g_Settings->SaveString(Directory_LastSave, SaveDir); - g_BaseSystem->ExternalEvent(SysEvent_SaveMachineState); - } - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SaveGame); - } - break; - case ID_SYSTEM_RESTORE: WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_RESTORE"); g_BaseSystem->ExternalEvent(SysEvent_LoadMachineState); break; - case ID_SYSTEM_LOAD: - { - char Directory[255], SaveFile[255]; - OPENFILENAME openfilename; - - memset(&SaveFile, 0, sizeof(SaveFile)); - memset(&openfilename, 0, sizeof(openfilename)); - - g_Settings->LoadStringVal(Directory_LastSave, Directory, sizeof(Directory)); - - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hWnd; - openfilename.lpstrFilter = "PJ64 Saves (*.zip, *.pj)\0*.pj?;*.pj;*.zip;"; - openfilename.lpstrFile = SaveFile; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_HIDEREADONLY; - - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_LoadGame); - if (GetOpenFileName(&openfilename)) - { - g_Settings->SaveString(GameRunning_InstantSaveFile, SaveFile); - char SaveDir[MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; - _splitpath(SaveFile, drive, dir, fname, ext); - _makepath(SaveDir, drive, dir, NULL, NULL); - g_Settings->SaveString(Directory_LastSave, SaveDir); - g_System->LoadState(); - } - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_LoadGame); - } - break; - case ID_SYSTEM_CHEAT: - { - CCheatsUI * cheatUI = new CCheatsUI; - g_cheatUI = cheatUI; - cheatUI->SelectCheats(hWnd, false); - } - break; - case ID_SYSTEM_GSBUTTON: - g_BaseSystem->ExternalEvent(SysEvent_GSButtonPressed); - break; - case ID_OPTIONS_DISPLAY_FR: - g_Settings->SaveBool(UserInterface_DisplayFrameRate, !g_Settings->LoadBool(UserInterface_DisplayFrameRate)); - break; - case ID_OPTIONS_CHANGE_FR: - switch (g_Settings->LoadDword(UserInterface_FrameDisplayType)) - { - case FR_VIs: - g_Settings->SaveDword(UserInterface_FrameDisplayType, FR_DLs); - break; - case FR_DLs: - g_Settings->SaveDword(UserInterface_FrameDisplayType, FR_PERCENT); - break; - default: - g_Settings->SaveDword(UserInterface_FrameDisplayType, FR_VIs); - } - break; - case ID_OPTIONS_INCREASE_SPEED: - g_BaseSystem->IncreaseSpeed(); - break; - case ID_OPTIONS_DECREASE_SPEED: - g_BaseSystem->DecreaseSpeed(); - break; - case ID_OPTIONS_FULLSCREEN: - g_BaseSystem->ExternalEvent(SysEvent_ChangingFullScreen); - break; - case ID_OPTIONS_FULLSCREEN2: - if (g_Settings->LoadBool(UserInterface_InFullScreen)) - { - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN a"); - m_Gui->MakeWindowOnTop(false); - Notify().SetGfxPlugin(NULL); - WriteTrace(TraceGFXPlugin, TraceDebug, "ChangeWindow: Starting"); - g_Plugins->Gfx()->ChangeWindow(); - WriteTrace(TraceGFXPlugin, TraceDebug, "ChangeWindow: Done"); - ShowCursor(true); - m_Gui->ShowStatusBar(true); - m_Gui->MakeWindowOnTop(g_Settings->LoadBool(UserInterface_AlwaysOnTop)); - g_Settings->SaveBool(UserInterface_InFullScreen, (DWORD)false); - } - else - { - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b"); - ShowCursor(false); - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 1"); - m_Gui->ShowStatusBar(false); - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 2"); - try - { - WriteTrace(TraceGFXPlugin, TraceDebug, "ChangeWindow: Starting"); - g_Plugins->Gfx()->ChangeWindow(); - WriteTrace(TraceGFXPlugin, TraceDebug, "ChangeWindow: Done"); - } - catch (...) - { - WriteTrace(TraceError, TraceDebug, "Exception when going to full screen"); - char Message[600]; - sprintf(Message, "Exception caught\nFile: %s\nLine: %d", __FILE__, __LINE__); - MessageBox(NULL, Message, "Exception", MB_OK); - } - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 4"); - m_Gui->MakeWindowOnTop(false); - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 5"); - Notify().SetGfxPlugin(g_Plugins->Gfx()); - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 3"); - g_Settings->SaveBool(UserInterface_InFullScreen, true); - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 6"); - } - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN 1"); - break; - case ID_OPTIONS_ALWAYSONTOP: - if (g_Settings->LoadDword(UserInterface_AlwaysOnTop)) - { - g_Settings->SaveBool(UserInterface_AlwaysOnTop, false); - m_Gui->MakeWindowOnTop(false); - } - else - { - g_Settings->SaveBool(UserInterface_AlwaysOnTop, true); - m_Gui->MakeWindowOnTop(g_Settings->LoadBool(GameRunning_CPU_Running)); - } - break; - case ID_OPTIONS_CONFIG_RSP: - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_RSP"); - g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_RSP); - break; - case ID_OPTIONS_CONFIG_GFX: - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_GFX"); - g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_GFX); - break; - case ID_OPTIONS_CONFIG_AUDIO: - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_AUDIO"); - g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_AUDIO); - break; - case ID_OPTIONS_CONFIG_CONT: - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_CONT"); - g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_CONTROLLER); - break; - case ID_OPTIONS_CPU_USAGE: - WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CPU_USAGE"); - if (g_Settings->LoadBool(UserInterface_ShowCPUPer)) - { - g_Settings->SaveBool(UserInterface_ShowCPUPer, false); - g_Notify->DisplayMessage(0, ""); - } - else - { - g_Settings->SaveBool(UserInterface_ShowCPUPer, true); - } - break; - case ID_OPTIONS_SETTINGS: - { - CSettingConfig SettingConfig; - SettingConfig.Display(hWnd); - } - break; - case ID_PROFILE_PROFILE: - g_Settings->SaveBool(Debugger_ProfileCode, !g_Settings->LoadBool(Debugger_ProfileCode)); - g_BaseSystem->ExternalEvent(SysEvent_Profile_StartStop); - break; - case ID_PROFILE_RESETCOUNTER: g_BaseSystem->ExternalEvent(SysEvent_Profile_ResetLogs); break; - case ID_PROFILE_GENERATELOG: g_BaseSystem->ExternalEvent(SysEvent_Profile_GenerateLogs); break; - case ID_DEBUG_SHOW_TLB_MISSES: - g_Settings->SaveBool(Debugger_ShowTLBMisses, !g_Settings->LoadBool(Debugger_ShowTLBMisses)); - break; - case ID_DEBUG_SHOW_UNHANDLED_MEM: - g_Settings->SaveBool(Debugger_ShowUnhandledMemory, !g_Settings->LoadBool(Debugger_ShowUnhandledMemory)); - break; - case ID_DEBUG_SHOW_PIF_ERRORS: - g_Settings->SaveBool(Debugger_ShowPifErrors, !g_Settings->LoadBool(Debugger_ShowPifErrors)); - break; - case ID_DEBUG_SHOW_DLIST_COUNT: - g_Notify->DisplayMessage(0, ""); - g_Settings->SaveBool(Debugger_ShowDListAListCount, !g_Settings->LoadBool(Debugger_ShowDListAListCount)); - break; - case ID_DEBUG_SHOW_RECOMP_MEM_SIZE: - g_Notify->DisplayMessage(0, ""); - g_Settings->SaveBool(Debugger_ShowRecompMemSize, !g_Settings->LoadBool(Debugger_ShowRecompMemSize)); - break; - case ID_DEBUG_SHOW_DIV_BY_ZERO: - g_Settings->SaveBool(Debugger_ShowDivByZero, !g_Settings->LoadBool(Debugger_ShowDivByZero)); - break; - case ID_DEBUG_GENERATE_LOG_FILES: - g_Settings->SaveBool(Debugger_GenerateLogFiles, !g_Settings->LoadBool(Debugger_GenerateLogFiles)); - break; - case ID_DEBUG_DISABLE_GAMEFIX: - g_Settings->SaveBool(Debugger_DisableGameFixes, !g_Settings->LoadBool(Debugger_DisableGameFixes)); - break; - case ID_DEBUGGER_TRACE_MD5: SetTraceModuleSetttings(Debugger_TraceMD5); break; - case ID_DEBUGGER_TRACE_SETTINGS: SetTraceModuleSetttings(Debugger_TraceSettings); break; - case ID_DEBUGGER_TRACE_UNKNOWN: SetTraceModuleSetttings(Debugger_TraceUnknown); break; - case ID_DEBUGGER_TRACE_APPINIT: SetTraceModuleSetttings(Debugger_TraceAppInit); break; - case ID_DEBUGGER_TRACE_APPCLEANUP: SetTraceModuleSetttings(Debugger_TraceAppCleanup); break; - case ID_DEBUGGER_TRACE_N64SYSTEM: SetTraceModuleSetttings(Debugger_TraceN64System); break; - case ID_DEBUGGER_TRACE_PLUGINS: SetTraceModuleSetttings(Debugger_TracePlugins); break; - case ID_DEBUGGER_TRACE_GFXPLUGIN: SetTraceModuleSetttings(Debugger_TraceGFXPlugin); break; - case ID_DEBUGGER_TRACE_AUDIOPLUGIN: SetTraceModuleSetttings(Debugger_TraceAudioPlugin); break; - case ID_DEBUGGER_TRACE_CONTROLLERPLUGIN: SetTraceModuleSetttings(Debugger_TraceControllerPlugin); break; - case ID_DEBUGGER_TRACE_RSPPLUGIN: SetTraceModuleSetttings(Debugger_TraceRSPPlugin); break; - case ID_DEBUGGER_TRACE_RSP: SetTraceModuleSetttings(Debugger_TraceRSP); break; - case ID_DEBUGGER_TRACE_AUDIO: SetTraceModuleSetttings(Debugger_TraceAudio); break; - case ID_DEBUGGER_TRACE_REGISTERCACHE: SetTraceModuleSetttings(Debugger_TraceRegisterCache); break; - case ID_DEBUGGER_TRACE_RECOMPILER: SetTraceModuleSetttings(Debugger_TraceRecompiler); break; - case ID_DEBUGGER_TRACE_TLB: SetTraceModuleSetttings(Debugger_TraceTLB); break; - case ID_DEBUGGER_TRACE_PROTECTEDMEM: SetTraceModuleSetttings(Debugger_TraceProtectedMEM); break; - case ID_DEBUGGER_TRACE_USERINTERFACE: SetTraceModuleSetttings(Debugger_TraceUserInterface); break; - - case ID_DEBUGGER_APPLOG_FLUSH: - g_Settings->SaveBool(Debugger_AppLogFlush, !g_Settings->LoadBool(Debugger_AppLogFlush)); - break; - case ID_DEBUGGER_LOGOPTIONS: m_Gui->EnterLogOptions(); break; - case ID_DEBUGGER_GENERATELOG: - g_Settings->SaveBool(Logging_GenerateLog, !g_Settings->LoadBool(Logging_GenerateLog)); - break; - case ID_DEBUGGER_DUMPMEMORY: m_Gui->Debug_ShowMemoryDump(); break; - case ID_DEBUGGER_SEARCHMEMORY: m_Gui->Debug_ShowMemorySearch(); break; - case ID_DEBUGGER_MEMORY: m_Gui->Debug_ShowMemoryWindow(); break; - case ID_DEBUGGER_TLBENTRIES: m_Gui->Debug_ShowTLBWindow(); break; - case ID_DEBUGGER_INTERRUPT_SP: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_SP); break; - case ID_DEBUGGER_INTERRUPT_SI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_SI); break; - case ID_DEBUGGER_INTERRUPT_AI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_AI); break; - case ID_DEBUGGER_INTERRUPT_VI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_VI); break; - case ID_DEBUGGER_INTERRUPT_PI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_PI); break; - case ID_DEBUGGER_INTERRUPT_DP: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_DP); break; - case ID_CURRENT_SAVE_DEFAULT: - g_Notify->DisplayMessage(3, stdstr_f(GS(MENU_SLOT_SAVE), GetSaveSlotString(MenuID - ID_CURRENT_SAVE_DEFAULT).c_str()).c_str()); - g_Settings->SaveDword(Game_CurrentSaveState, (DWORD)(MenuID - ID_CURRENT_SAVE_DEFAULT)); - break; - case ID_CURRENT_SAVE_1: - case ID_CURRENT_SAVE_2: - case ID_CURRENT_SAVE_3: - case ID_CURRENT_SAVE_4: - case ID_CURRENT_SAVE_5: - case ID_CURRENT_SAVE_6: - case ID_CURRENT_SAVE_7: - case ID_CURRENT_SAVE_8: - case ID_CURRENT_SAVE_9: - case ID_CURRENT_SAVE_10: - g_Notify->DisplayMessage(3, stdstr_f(GS(MENU_SLOT_SAVE), GetSaveSlotString((MenuID - ID_CURRENT_SAVE_1) + 1).c_str()).c_str()); - g_Settings->SaveDword(Game_CurrentSaveState, (DWORD)((MenuID - ID_CURRENT_SAVE_1) + 1)); - break; - case ID_HELP_SUPPORTFORUM: ShellExecute(NULL, "open", "http://forum.pj64-emu.com/", NULL, NULL, SW_SHOWMAXIMIZED); break; - case ID_HELP_HOMEPAGE: ShellExecute(NULL, "open", "http://www.pj64-emu.com", NULL, NULL, SW_SHOWMAXIMIZED); break; - case ID_HELP_ABOUT: m_Gui->AboutBox(); break; - case ID_HELP_ABOUTSETTINGFILES: m_Gui->AboutIniBox(); break; - default: - if (MenuID >= ID_RECENT_ROM_START && MenuID < ID_RECENT_ROM_END) - { - stdstr FileName; - if (g_Settings->LoadStringIndex(File_RecentGameFileIndex, MenuID - ID_RECENT_ROM_START, FileName) && - FileName.length() > 0) - { - g_BaseSystem->RunFileImage(FileName.c_str()); - } - } - if (MenuID >= ID_RECENT_DIR_START && MenuID < ID_RECENT_DIR_END) - { - int Offset = MenuID - ID_RECENT_DIR_START; - stdstr Dir = g_Settings->LoadStringIndex(Directory_RecentGameDirIndex, Offset); - if (Dir.length() > 0) - { - g_Settings->SaveString(Directory_Game, Dir.c_str()); - Notify().AddRecentDir(Dir.c_str()); - m_Gui->RefreshMenu(); - if (m_Gui->RomBrowserVisible()) - { - m_Gui->RefreshRomBrowser(); - } - } - } - if (MenuID >= ID_LANG_START && MenuID < ID_LANG_END) - { - MENUITEMINFOW menuinfo; - wchar_t String[300]; - - menuinfo.cbSize = sizeof(MENUITEMINFO); - menuinfo.fMask = MIIM_TYPE; - menuinfo.fType = MFT_STRING; - menuinfo.dwTypeData = String; - menuinfo.cch = sizeof(String); - GetMenuItemInfoW((HMENU)m_MenuHandle, MenuID, FALSE, &menuinfo); - - g_Lang->SetLanguage(stdstr().FromUTF16(String).c_str()); - m_Gui->ResetRomBrowserColomuns(); - break; - } - return false; - } - return true; -} - -stdstr CMainMenu::GetFileLastMod(stdstr FileName) -{ - HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - return ""; - } - FILETIME CreationTime, LastAccessTime, LastWriteTime; - stdstr LastMod; - if (GetFileTime(hFile, &CreationTime, &LastAccessTime, &LastWriteTime)) - { - SYSTEMTIME stUTC, stLocal; - - // Convert the last-write time to local time. - FileTimeToSystemTime(&LastWriteTime, &stUTC); - SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); - - LastMod.Format(" [%d/%02d/%02d %02d:%02d]", stLocal.wYear, stLocal.wMonth, stLocal.wDay, stLocal.wHour, stLocal.wMinute); - } - CloseHandle(hFile); - - return LastMod; -} - -std::wstring CMainMenu::GetSaveSlotString(int Slot) -{ - stdstr SlotName; - switch (Slot) - { - case 0: SlotName = GS(MENU_SLOT_DEFAULT); break; - case 1: SlotName = GS(MENU_SLOT_1); break; - case 2: SlotName = GS(MENU_SLOT_2); break; - case 3: SlotName = GS(MENU_SLOT_3); break; - case 4: SlotName = GS(MENU_SLOT_4); break; - case 5: SlotName = GS(MENU_SLOT_5); break; - case 6: SlotName = GS(MENU_SLOT_6); break; - case 7: SlotName = GS(MENU_SLOT_7); break; - case 8: SlotName = GS(MENU_SLOT_8); break; - case 9: SlotName = GS(MENU_SLOT_9); break; - case 10: SlotName = GS(MENU_SLOT_10); break; - } - - if (!g_Settings->LoadBool(GameRunning_CPU_Running)) { return SlotName.ToUTF16(); } - - stdstr LastSaveTime; - - //check first save name - stdstr _GoodName = g_Settings->LoadStringVal(Game_GoodName); - stdstr _InstantSaveDirectory = g_Settings->LoadStringVal(Directory_InstantSave); - stdstr CurrentSaveName; - if (Slot != 0) - { - CurrentSaveName.Format("%s.pj%d", _GoodName.c_str(), Slot); - } - else - { - CurrentSaveName.Format("%s.pj", _GoodName.c_str()); - } - stdstr_f FileName("%s%s", _InstantSaveDirectory.c_str(), CurrentSaveName.c_str()); - - if (g_Settings->LoadDword(Setting_AutoZipInstantSave)) - { - stdstr_f ZipFileName("%s.zip", FileName.c_str()); - LastSaveTime = GetFileLastMod(ZipFileName); - } - if (LastSaveTime.empty()) - { - LastSaveTime = GetFileLastMod(FileName); - } - - // Check old file name - if (LastSaveTime.empty()) - { - stdstr _RomName = g_Settings->LoadStringVal(Game_GameName); - if (Slot > 0) - { - FileName.Format("%s%s.pj%d", _InstantSaveDirectory.c_str(), _RomName.c_str(), Slot); - } - else - { - FileName.Format("%s%s.pj", _InstantSaveDirectory.c_str(), _RomName.c_str()); - } - - if (g_Settings->LoadBool(Setting_AutoZipInstantSave)) - { - stdstr_f ZipFileName("%s.zip", FileName.c_str()); - LastSaveTime = GetFileLastMod(ZipFileName); - } - if (LastSaveTime.empty()) - { - LastSaveTime = GetFileLastMod(FileName); - } - } - SlotName += LastSaveTime; - return SlotName.ToUTF16(); -} - -void CMainMenu::FillOutMenu(HMENU hMenu) -{ - CGuard Guard(m_CS); - - MENU_ITEM Item; - - //Get all flags - bool inBasicMode = g_Settings->LoadBool(UserInterface_BasicMode); - bool CPURunning = g_Settings->LoadBool(GameRunning_CPU_Running); - bool RomLoading = g_Settings->LoadBool(GameRunning_LoadingInProgress); - bool RomLoaded = g_Settings->LoadStringVal(Game_GameName).length() > 0; - bool RomList = g_Settings->LoadBool(RomBrowser_Enabled) && !CPURunning; - - CMenuShortCutKey::ACCESS_MODE AccessLevel = CMenuShortCutKey::GAME_NOT_RUNNING; - if (g_Settings->LoadBool(GameRunning_CPU_Running)) - { - AccessLevel = g_Settings->LoadBool(UserInterface_InFullScreen) ? CMenuShortCutKey::GAME_RUNNING_FULLSCREEN : CMenuShortCutKey::GAME_RUNNING_WINDOW; - } - - //Get the system information to make the menu - LanguageList LangList = g_Lang->GetLangList(); - - MenuItemList LangMenu; - int Offset = 0; - for (LanguageList::iterator Language = LangList.begin(); Language != LangList.end(); Language++) - { - Item.Reset(ID_LANG_START + Offset++, EMPTY_STRING, EMPTY_STDSTR, NULL, stdstr(Language->LanguageName).ToUTF16().c_str()); - if (g_Lang->IsCurrentLang(*Language)) - { - Item.SetItemTicked(true); - } - LangMenu.push_back(Item); - } - - //Go through the settings to create a list of Recent Roms - MenuItemList RecentRomMenu; - DWORD count, RomsToRemember = g_Settings->LoadDword(File_RecentGameFileCount); - - for (count = 0; count < RomsToRemember; count++) - { - stdstr LastRom = g_Settings->LoadStringIndex(File_RecentGameFileIndex, count); - if (LastRom.empty()) - { - break; - } - stdstr_f MenuString("&%d %s", (count + 1) % 10, LastRom.c_str()); - - RecentRomMenu.push_back(MENU_ITEM(ID_RECENT_ROM_START + count, EMPTY_STRING, EMPTY_STDSTR, NULL, MenuString.ToUTF16(CP_ACP).c_str())); - } - - /* Recent Dir - ****************/ - MenuItemList RecentDirMenu; - DWORD DirsToRemember = g_Settings->LoadDword(Directory_RecentGameDirCount); - - for (count = 0; count < DirsToRemember; count++) - { - stdstr LastDir = g_Settings->LoadStringIndex(Directory_RecentGameDirIndex, count); - if (LastDir.empty()) - { - break; - } - - stdstr_f MenuString("&%d %s", (count + 1) % 10, LastDir.c_str()); - - RecentDirMenu.push_back(MENU_ITEM(ID_RECENT_DIR_START + count, EMPTY_STRING, EMPTY_STDSTR, NULL, MenuString.ToUTF16(CP_ACP).c_str())); - } - - /* File Menu - ****************/ - MenuItemList FileMenu; - Item.Reset(ID_FILE_OPEN_ROM, MENU_OPEN, m_ShortCuts.ShortCutString(ID_FILE_OPEN_ROM, AccessLevel)); - FileMenu.push_back(Item); - if (!inBasicMode) - { - Item.Reset(ID_FILE_ROM_INFO, MENU_ROM_INFO, m_ShortCuts.ShortCutString(ID_FILE_ROM_INFO, AccessLevel)); - Item.SetItemEnabled(RomLoaded); - FileMenu.push_back(Item); - FileMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(ID_FILE_STARTEMULATION, MENU_START, m_ShortCuts.ShortCutString(ID_FILE_STARTEMULATION, AccessLevel)); - Item.SetItemEnabled(RomLoaded && !CPURunning); - FileMenu.push_back(Item); - } - Item.Reset(ID_FILE_ENDEMULATION, MENU_END, m_ShortCuts.ShortCutString(ID_FILE_ENDEMULATION, AccessLevel)); - Item.SetItemEnabled(CPURunning); - FileMenu.push_back(Item); - FileMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(SUB_MENU, MENU_LANGUAGE, EMPTY_STDSTR, &LangMenu); - FileMenu.push_back(Item); - if (RomList) - { - FileMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(ID_FILE_ROMDIRECTORY, MENU_CHOOSE_ROM, m_ShortCuts.ShortCutString(ID_FILE_ROMDIRECTORY, AccessLevel)); - FileMenu.push_back(Item); - Item.Reset(ID_FILE_REFRESHROMLIST, MENU_REFRESH, m_ShortCuts.ShortCutString(ID_FILE_REFRESHROMLIST, AccessLevel)); - FileMenu.push_back(Item); - } - - if (!inBasicMode && RomList) - { - FileMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(SUB_MENU, MENU_RECENT_ROM, EMPTY_STDSTR, &RecentRomMenu); - if (RecentRomMenu.size() == 0) - { - RecentRomMenu.push_back(MENU_ITEM(SPLITER)); - Item.SetItemEnabled(false); - } - FileMenu.push_back(Item); - Item.Reset(SUB_MENU, MENU_RECENT_DIR, EMPTY_STDSTR, &RecentDirMenu); - if (RecentDirMenu.size() == 0) - { - RecentDirMenu.push_back(MENU_ITEM(SPLITER)); - Item.SetItemEnabled(false); - } - FileMenu.push_back(Item); - } - else - { - if (RecentRomMenu.size() != 0) - { - FileMenu.push_back(MENU_ITEM(SPLITER)); - for (MenuItemList::iterator MenuItem = RecentRomMenu.begin(); MenuItem != RecentRomMenu.end(); MenuItem++) - { - FileMenu.push_back(*MenuItem); - } - } - } - FileMenu.push_back(MENU_ITEM(SPLITER)); - FileMenu.push_back(MENU_ITEM(ID_FILE_EXIT, MENU_EXIT, m_ShortCuts.ShortCutString(ID_FILE_EXIT, AccessLevel))); - - /* Current Save - ****************/ - MenuItemList CurrentSaveMenu; - DWORD _CurrentSaveState = g_Settings->LoadDword(Game_CurrentSaveState); - Item.Reset(ID_CURRENT_SAVE_DEFAULT, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_DEFAULT, AccessLevel), NULL, GetSaveSlotString(0)); - if (_CurrentSaveState == 0) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - CurrentSaveMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(ID_CURRENT_SAVE_1, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_1, AccessLevel), NULL, GetSaveSlotString(1)); - if (_CurrentSaveState == 1) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_2, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_2, AccessLevel), NULL, GetSaveSlotString(2)); - if (_CurrentSaveState == 2) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_3, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_3, AccessLevel), NULL, GetSaveSlotString(3)); - if (_CurrentSaveState == 3) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_4, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_4, AccessLevel), NULL, GetSaveSlotString(4)); - if (_CurrentSaveState == 4) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_5, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_5, AccessLevel), NULL, GetSaveSlotString(5)); - if (_CurrentSaveState == 5) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_6, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_6, AccessLevel), NULL, GetSaveSlotString(6)); - if (_CurrentSaveState == 6) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_7, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_7, AccessLevel), NULL, GetSaveSlotString(7)); - if (_CurrentSaveState == 7) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_8, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_8, AccessLevel), NULL, GetSaveSlotString(8)); - if (_CurrentSaveState == 8) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_9, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_9, AccessLevel), NULL, GetSaveSlotString(9)); - if (_CurrentSaveState == 9) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_10, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_10, AccessLevel), NULL, GetSaveSlotString(10)); - if (_CurrentSaveState == 10) { Item.SetItemTicked(true); } - CurrentSaveMenu.push_back(Item); - - /* System Menu - ****************/ - MenuItemList SystemMenu; - MenuItemList ResetMenu; - if (inBasicMode) - { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT, AccessLevel))); - } - else - { - ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET_SOFT, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT, AccessLevel))); - ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_HARD, MENU_RESET_HARD, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_HARD, AccessLevel))); - SystemMenu.push_back(MENU_ITEM(SUB_MENU, MENU_RESET, EMPTY_STDSTR, &ResetMenu)); - } - if (g_Settings->LoadBool(GameRunning_CPU_Paused)) - { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_RESUME, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE, AccessLevel))); - } - else - { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_PAUSE, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE, AccessLevel))); - } - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_BITMAP, MENU_BITMAP, m_ShortCuts.ShortCutString(ID_SYSTEM_BITMAP, AccessLevel))); - SystemMenu.push_back(MENU_ITEM(SPLITER)); - if (!inBasicMode) - { - Item.Reset(ID_SYSTEM_LIMITFPS, MENU_LIMIT_FPS, m_ShortCuts.ShortCutString(ID_SYSTEM_LIMITFPS, AccessLevel)); - if (g_Settings->LoadBool(GameRunning_LimitFPS)) { Item.SetItemTicked(true); } - SystemMenu.push_back(Item); - SystemMenu.push_back(MENU_ITEM(SPLITER)); - } - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVE, MENU_SAVE, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVE, AccessLevel))); - if (!inBasicMode) - { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVEAS, MENU_SAVE_AS, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVEAS, AccessLevel))); - } - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESTORE, MENU_RESTORE, m_ShortCuts.ShortCutString(ID_SYSTEM_RESTORE, AccessLevel))); - if (!inBasicMode) - { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_LOAD, MENU_LOAD, m_ShortCuts.ShortCutString(ID_SYSTEM_LOAD, AccessLevel))); - } - SystemMenu.push_back(MENU_ITEM(SPLITER)); - SystemMenu.push_back(MENU_ITEM(SUB_MENU, MENU_CURRENT_SAVE, EMPTY_STDSTR, &CurrentSaveMenu)); - SystemMenu.push_back(MENU_ITEM(SPLITER)); - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_CHEAT, MENU_CHEAT, m_ShortCuts.ShortCutString(ID_SYSTEM_CHEAT, AccessLevel))); - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_GSBUTTON, MENU_GS_BUTTON, m_ShortCuts.ShortCutString(ID_SYSTEM_GSBUTTON, AccessLevel))); - - /* Option Menu - ****************/ - MenuItemList OptionMenu; - Item.Reset(ID_OPTIONS_FULLSCREEN, MENU_FULL_SCREEN, m_ShortCuts.ShortCutString(ID_OPTIONS_FULLSCREEN, AccessLevel)); - Item.SetItemEnabled(CPURunning); - if (g_Plugins && g_Plugins->Gfx() && g_Plugins->Gfx()->ChangeWindow == NULL) - { - Item.SetItemEnabled(false); - } - OptionMenu.push_back(Item); - if (!inBasicMode) - { - Item.Reset(ID_OPTIONS_ALWAYSONTOP, MENU_ON_TOP, m_ShortCuts.ShortCutString(ID_OPTIONS_ALWAYSONTOP, AccessLevel)); - if (g_Settings->LoadDword(UserInterface_AlwaysOnTop)) { Item.SetItemTicked(true); } - Item.SetItemEnabled(CPURunning); - OptionMenu.push_back(Item); - } - OptionMenu.push_back(MENU_ITEM(SPLITER)); - - Item.Reset(ID_OPTIONS_CONFIG_GFX, MENU_CONFG_GFX, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_GFX, AccessLevel)); - if (g_Plugins && g_Plugins->Gfx() == NULL || g_Plugins->Gfx()->DllConfig == NULL) - { - Item.SetItemEnabled(false); - } - OptionMenu.push_back(Item); - Item.Reset(ID_OPTIONS_CONFIG_AUDIO, MENU_CONFG_AUDIO, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_AUDIO, AccessLevel)); - if (g_Plugins->Audio() == NULL || g_Plugins->Audio()->DllConfig == NULL) - { - Item.SetItemEnabled(false); - } - OptionMenu.push_back(Item); - if (!inBasicMode) - { - Item.Reset(ID_OPTIONS_CONFIG_RSP, MENU_CONFG_RSP, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_RSP, AccessLevel)); - if (g_Plugins->RSP() == NULL || g_Plugins->RSP()->DllConfig == NULL) - { - Item.SetItemEnabled(false); - } - OptionMenu.push_back(Item); - } - Item.Reset(ID_OPTIONS_CONFIG_CONT, MENU_CONFG_CTRL, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_CONT, AccessLevel)); - if (g_Plugins && g_Plugins->Control() == NULL || g_Plugins->Control()->DllConfig == NULL) - { - Item.SetItemEnabled(false); - } - OptionMenu.push_back(Item); - - OptionMenu.push_back(MENU_ITEM(SPLITER)); - if (!inBasicMode) - { - Item.Reset(ID_OPTIONS_CPU_USAGE, MENU_SHOW_CPU, m_ShortCuts.ShortCutString(ID_OPTIONS_CPU_USAGE, AccessLevel)); - if (g_Settings->LoadDword(UserInterface_ShowCPUPer)) { Item.SetItemTicked(true); } - OptionMenu.push_back(Item); - } - OptionMenu.push_back(MENU_ITEM(ID_OPTIONS_SETTINGS, MENU_SETTINGS, m_ShortCuts.ShortCutString(ID_OPTIONS_SETTINGS, AccessLevel))); - - /* Profile Menu - ****************/ - MenuItemList DebugProfileMenu; - if (bHaveDebugger()) - { - Item.Reset(ID_PROFILE_PROFILE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Profile Code"); - if (g_Settings->LoadBool(Debugger_ProfileCode)) { Item.SetItemTicked(true); } - DebugProfileMenu.push_back(Item); - Item.Reset(ID_PROFILE_RESETCOUNTER, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Reset Counters"); - if (!CPURunning) { Item.SetItemEnabled(false); } - DebugProfileMenu.push_back(Item); - Item.Reset(ID_PROFILE_GENERATELOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Generate Log File"); - if (!CPURunning) { Item.SetItemEnabled(false); } - DebugProfileMenu.push_back(Item); - } - - /* Debugger Menu - ****************/ - MenuItemList DebugMenu; - MenuItemList DebugLoggingMenu; - MenuItemList DebugAppLoggingMenu; - MenuItemList DebugR4300Menu; - MenuItemList DebugMemoryMenu; - MenuItemList DebugInterrupt; - MenuItemList DebugNotificationMenu; - if (bHaveDebugger()) - { - /* Debug - Interrupt - *******************/ - Item.Reset(ID_DEBUGGER_INTERRUPT_SP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"SP Interrupt"); - Item.SetItemEnabled(CPURunning); - DebugInterrupt.push_back(Item); - Item.Reset(ID_DEBUGGER_INTERRUPT_SI, EMPTY_STRING, EMPTY_STDSTR, NULL, L"SI Interrupt"); - Item.SetItemEnabled(CPURunning); - DebugInterrupt.push_back(Item); - Item.Reset(ID_DEBUGGER_INTERRUPT_AI, EMPTY_STRING, EMPTY_STDSTR, NULL, L"AI Interrupt"); - Item.SetItemEnabled(CPURunning); - DebugInterrupt.push_back(Item); - Item.Reset(ID_DEBUGGER_INTERRUPT_VI, EMPTY_STRING, EMPTY_STDSTR, NULL, L"VI Interrupt"); - Item.SetItemEnabled(CPURunning); - DebugInterrupt.push_back(Item); - Item.Reset(ID_DEBUGGER_INTERRUPT_PI, EMPTY_STRING, EMPTY_STDSTR, NULL, L"PI Interrupt"); - Item.SetItemEnabled(CPURunning); - DebugInterrupt.push_back(Item); - Item.Reset(ID_DEBUGGER_INTERRUPT_DP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"DP Interrupt"); - Item.SetItemEnabled(CPURunning); - DebugInterrupt.push_back(Item); - - /* Debug - R4300i - *******************/ - Item.Reset(ID_DEBUGGER_LOGOPTIONS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Commands..."); - Item.SetItemEnabled(false); - DebugR4300Menu.push_back(Item); - Item.Reset(ID_DEBUGGER_R4300REGISTERS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Registers..."); - Item.SetItemEnabled(true); - DebugR4300Menu.push_back(Item); - Item.Reset(ID_DEBUG_DISABLE_GAMEFIX, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Disable Game Fixes"); - if (g_Settings->LoadBool(Debugger_DisableGameFixes)) - { - Item.SetItemTicked(true); - } - DebugR4300Menu.push_back(Item); - Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugInterrupt, L"&Generate Interrupt"); - DebugR4300Menu.push_back(Item); - - /* Debug - Memory - ****************/ - Item.Reset(ID_DEBUGGER_MEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"View..."); - DebugMemoryMenu.push_back(Item); - Item.Reset(ID_DEBUGGER_SEARCHMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Search..."); - DebugMemoryMenu.push_back(Item); - Item.Reset(ID_DEBUGGER_DUMPMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Dump..."); - DebugMemoryMenu.push_back(Item); - Item.Reset(ID_DEBUGGER_TLBENTRIES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"TLB Entries..."); - DebugMemoryMenu.push_back(Item); - - /* Debug - App logging - *******************/ - Item.Reset(ID_DEBUGGER_TRACE_MD5, EMPTY_STRING, EMPTY_STDSTR, NULL, L"MD5"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceMD5) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_SETTINGS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Settings"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceSettings) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_UNKNOWN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Unknown"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceUnknown) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_APPINIT, EMPTY_STRING, EMPTY_STDSTR, NULL, L"App Init"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceAppInit) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_APPCLEANUP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"App Cleanup"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceAppCleanup) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_N64SYSTEM, EMPTY_STRING, EMPTY_STDSTR, NULL, L"N64 System"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceN64System) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_PLUGINS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Plugins"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TracePlugins) == TraceVerbose);; - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_GFXPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"GFX Plugin"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceGFXPlugin) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_AUDIOPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Audio Plugin"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceAudioPlugin) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_CONTROLLERPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Controller Plugin"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceControllerPlugin) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_RSPPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"RSP Plugin"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRSPPlugin) == TraceVerbose);; - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_RSP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"RSP"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRSP) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_AUDIO, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Audio"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceAudio) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_REGISTERCACHE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Register Cache"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRegisterCache) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_RECOMPILER, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Recompiler"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRecompiler) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_TLB, EMPTY_STRING, EMPTY_STDSTR, NULL, L"TLB"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceTLB) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_PROTECTEDMEM, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Protected MEM"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceProtectedMEM) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_TRACE_USERINTERFACE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"User Interface"); - Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceUserInterface) == TraceVerbose); - DebugAppLoggingMenu.push_back(Item); - - DebugAppLoggingMenu.push_back(MENU_ITEM(SPLITER)); - - Item.Reset(ID_DEBUGGER_APPLOG_FLUSH, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Auto flush file"); - if (g_Settings->LoadBool(Debugger_AppLogFlush)) { Item.SetItemTicked(true); } - DebugAppLoggingMenu.push_back(Item); - - /* Debug - Logging - *******************/ - Item.Reset(ID_DEBUGGER_LOGOPTIONS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Log Options..."); - DebugLoggingMenu.push_back(Item); - - Item.Reset(ID_DEBUGGER_GENERATELOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Generate Log"); - if (g_Settings->LoadBool(Logging_GenerateLog)) { Item.SetItemTicked(true); } - DebugLoggingMenu.push_back(Item); - - /* Debugger Main Menu - ****************/ - Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Breakpoint..."); - Item.SetItemEnabled(CPURunning); - DebugMenu.push_back(Item); - DebugMenu.push_back(MENU_ITEM(SPLITER)); - - /* Debug - RSP - *******************/ - if (g_Plugins && g_Plugins->RSP() != NULL && IsMenu((HMENU)g_Plugins->RSP()->GetDebugMenu())) - { - Item.Reset(ID_PLUGIN_MENU, EMPTY_STRING, EMPTY_STDSTR, g_Plugins->RSP()->GetDebugMenu(), L"&RSP"); - DebugMenu.push_back(Item); - } - - /* Debug - RDP - *******************/ - if (g_Plugins && g_Plugins->Gfx() != NULL && IsMenu((HMENU)g_Plugins->Gfx()->GetDebugMenu())) - { - Item.Reset(ID_PLUGIN_MENU, EMPTY_STRING, EMPTY_STDSTR, g_Plugins->Gfx()->GetDebugMenu(), L"&RDP"); - DebugMenu.push_back(Item); - } - - /* Notification Menu - *******************/ - Item.Reset(ID_DEBUG_SHOW_UNHANDLED_MEM, EMPTY_STRING, EMPTY_STDSTR, NULL, L"On Unhandled Memory Actions"); - if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) - { - Item.SetItemTicked(true); - } - DebugNotificationMenu.push_back(Item); - Item.Reset(ID_DEBUG_SHOW_PIF_ERRORS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"On PIF Errors"); - if (g_Settings->LoadBool(Debugger_ShowPifErrors)) - { - Item.SetItemTicked(true); - } - DebugNotificationMenu.push_back(Item); - Item.Reset(ID_DEBUG_SHOW_DIV_BY_ZERO, EMPTY_STRING, EMPTY_STDSTR, NULL, L"On Div By Zero"); - if (g_Settings->LoadBool(Debugger_ShowDivByZero)) - { - Item.SetItemTicked(true); - } - DebugNotificationMenu.push_back(Item); - - Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugR4300Menu, L"&R4300i"); - DebugMenu.push_back(Item); - Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugMemoryMenu, L"Memory"); - Item.SetItemEnabled(CPURunning); - DebugMenu.push_back(Item); - DebugMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugProfileMenu, L"Profile"); - DebugMenu.push_back(Item); - Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugAppLoggingMenu, L"App Logging"); - DebugMenu.push_back(Item); - Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugLoggingMenu, L"Logging"); - DebugMenu.push_back(Item); - Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugNotificationMenu, L"Notification"); - DebugMenu.push_back(Item); - DebugMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(ID_DEBUG_SHOW_TLB_MISSES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Show TLB Misses"); - if (g_Settings->LoadBool(Debugger_ShowTLBMisses)) - { - Item.SetItemTicked(true); - } - Item.Reset(ID_DEBUG_SHOW_DLIST_COUNT, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Display Alist/Dlist Count"); - if (g_Settings->LoadBool(Debugger_ShowDListAListCount)) - { - Item.SetItemTicked(true); - } - DebugMenu.push_back(Item); - Item.Reset(ID_DEBUG_SHOW_RECOMP_MEM_SIZE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Display Recompiler Code Buffer Size"); - if (g_Settings->LoadBool(Debugger_ShowRecompMemSize)) - { - Item.SetItemTicked(true); - } - DebugMenu.push_back(Item); - DebugMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(ID_DEBUG_GENERATE_LOG_FILES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Generate Log Files"); - if (g_Settings->LoadBool(Debugger_GenerateLogFiles)) - { - Item.SetItemTicked(true); - } - DebugMenu.push_back(Item); - } - - /* Help Menu - ****************/ - MenuItemList HelpMenu; - - HelpMenu.push_back(MENU_ITEM(ID_HELP_SUPPORTFORUM, MENU_FORUM)); - HelpMenu.push_back(MENU_ITEM(ID_HELP_HOMEPAGE, MENU_HOMEPAGE)); - HelpMenu.push_back(MENU_ITEM(SPLITER)); - if (!inBasicMode) - { - HelpMenu.push_back(MENU_ITEM(ID_HELP_ABOUTSETTINGFILES, MENU_ABOUT_INI)); - } - HelpMenu.push_back(MENU_ITEM(ID_HELP_ABOUT, MENU_ABOUT_PJ64)); - - /* Main Title bar Menu - ***********************/ - MenuItemList MainTitleMenu; - Item.Reset(SUB_MENU, MENU_FILE, EMPTY_STDSTR, &FileMenu); - if (RomLoading) { Item.SetItemEnabled(false); } - MainTitleMenu.push_back(Item); - if (CPURunning) - { - Item.Reset(SUB_MENU, MENU_SYSTEM, EMPTY_STDSTR, &SystemMenu); - if (RomLoading) { Item.SetItemEnabled(false); } - MainTitleMenu.push_back(Item); - } - Item.Reset(SUB_MENU, MENU_OPTIONS, EMPTY_STDSTR, &OptionMenu); - if (RomLoading) { Item.SetItemEnabled(false); } - MainTitleMenu.push_back(Item); - if (!inBasicMode) - { - if (bHaveDebugger()) - { - Item.Reset(SUB_MENU, MENU_DEBUGGER, EMPTY_STDSTR, &DebugMenu); - if (RomLoading) { Item.SetItemEnabled(false); } - MainTitleMenu.push_back(Item); - } - } - Item.Reset(SUB_MENU, MENU_HELP, EMPTY_STDSTR, &HelpMenu); - if (RomLoading) { Item.SetItemEnabled(false); } - MainTitleMenu.push_back(Item); - - AddMenu(hMenu, MainTitleMenu); -} - -void CMainMenu::RebuildAccelerators(void) -{ - CGuard Guard(m_CS); - - //Delete the old accel list - WriteTrace(TraceUserInterface, TraceDebug, "Start"); - - HACCEL m_OldAccelTable = (HACCEL)m_AccelTable; - m_AccelTable = m_ShortCuts.GetAcceleratorTable(); - if (m_OldAccelTable) { - DestroyAcceleratorTable(m_OldAccelTable); - } - WriteTrace(TraceUserInterface, TraceDebug, "Done"); -} - -void CMainMenu::ResetMenu(void) -{ - WriteTrace(TraceUserInterface, TraceDebug, "Start"); - if (!g_Settings->LoadBool(UserInterface_InFullScreen)) - { - //Create a new window with all the items - WriteTrace(TraceUserInterface, TraceDebug, "Create Menu"); - HMENU hMenu = CreateMenu(); - FillOutMenu(hMenu); - WriteTrace(TraceUserInterface, TraceDebug, "Create Menu Done"); - - //save old menu to destroy latter - HMENU OldMenuHandle; - { - CGuard Guard(m_CS); - OldMenuHandle = m_MenuHandle; - - //save handle and re-attach to a window - WriteTrace(TraceUserInterface, TraceDebug, "Attach Menu"); - m_MenuHandle = hMenu; - } - m_Gui->SetWindowMenu(this); - - WriteTrace(TraceUserInterface, TraceDebug, "Remove plugin menu"); - if (g_Plugins->Gfx() != NULL && IsMenu((HMENU)g_Plugins->Gfx()->GetDebugMenu())) - { - RemoveMenu((HMENU)OldMenuHandle, (DWORD)g_Plugins->Gfx()->GetDebugMenu(), MF_BYCOMMAND); - } - if (g_Plugins->RSP() != NULL && IsMenu((HMENU)g_Plugins->RSP()->GetDebugMenu())) - { - RemoveMenu((HMENU)OldMenuHandle, (DWORD)g_Plugins->RSP()->GetDebugMenu(), MF_BYCOMMAND); - } - WriteTrace(TraceUserInterface, TraceDebug, "Destroy Old Menu"); - - //Destroy the old menu - DestroyMenu((HMENU)OldMenuHandle); - } - - ResetAccelerators(); - - WriteTrace(TraceUserInterface, TraceDebug, "Done"); +#include "stdafx.h" +#include "RomInformationClass.h" + +#include +#include + +CMainMenu::CMainMenu(CMainGui * hMainWindow) : +CBaseMenu(), +m_ResetAccelerators(true), +m_Gui(hMainWindow) +{ + ResetMenu(); + + hMainWindow->SetWindowMenu(this); + + m_ChangeSettingList.push_back(Info_ShortCutsChanged); + m_ChangeSettingList.push_back(GameRunning_LimitFPS); + m_ChangeSettingList.push_back(UserInterface_InFullScreen); + m_ChangeSettingList.push_back(UserInterface_AlwaysOnTop); + m_ChangeSettingList.push_back(UserInterface_ShowCPUPer); + m_ChangeSettingList.push_back(Logging_GenerateLog); + m_ChangeSettingList.push_back(Debugger_ProfileCode); + m_ChangeSettingList.push_back(Debugger_ShowTLBMisses); + m_ChangeSettingList.push_back(Debugger_ShowUnhandledMemory); + m_ChangeSettingList.push_back(Debugger_ShowPifErrors); + m_ChangeSettingList.push_back(Debugger_ShowDListAListCount); + m_ChangeSettingList.push_back(Debugger_ShowRecompMemSize); + m_ChangeSettingList.push_back(Debugger_ShowDivByZero); + m_ChangeSettingList.push_back(Debugger_GenerateLogFiles); + m_ChangeSettingList.push_back(Debugger_DisableGameFixes); + m_ChangeSettingList.push_back(Debugger_TraceMD5); + m_ChangeSettingList.push_back(Debugger_TraceSettings); + m_ChangeSettingList.push_back(Debugger_TraceUnknown); + m_ChangeSettingList.push_back(Debugger_TraceAppInit); + m_ChangeSettingList.push_back(Debugger_TraceAppCleanup); + m_ChangeSettingList.push_back(Debugger_TraceN64System); + m_ChangeSettingList.push_back(Debugger_TracePlugins); + m_ChangeSettingList.push_back(Debugger_TraceGFXPlugin); + m_ChangeSettingList.push_back(Debugger_TraceAudioPlugin); + m_ChangeSettingList.push_back(Debugger_TraceControllerPlugin); + m_ChangeSettingList.push_back(Debugger_TraceRSPPlugin); + m_ChangeSettingList.push_back(Debugger_TraceRSP); + m_ChangeSettingList.push_back(Debugger_TraceAudio); + m_ChangeSettingList.push_back(Debugger_TraceRegisterCache); + m_ChangeSettingList.push_back(Debugger_TraceRecompiler); + m_ChangeSettingList.push_back(Debugger_TraceTLB); + m_ChangeSettingList.push_back(Debugger_TraceProtectedMEM); + m_ChangeSettingList.push_back(Debugger_TraceUserInterface); + m_ChangeSettingList.push_back(Debugger_AppLogFlush); + m_ChangeSettingList.push_back(Game_CurrentSaveState); + m_ChangeSettingList.push_back(Setting_CurrentLanguage); + + for (SettingList::const_iterator iter = m_ChangeSettingList.begin(); iter != m_ChangeSettingList.end(); iter++) + { + g_Settings->RegisterChangeCB(*iter, this, (CSettings::SettingChangedFunc)SettingsChanged); + } +} + +CMainMenu::~CMainMenu() +{ + for (SettingList::const_iterator iter = m_ChangeSettingList.begin(); iter != m_ChangeSettingList.end(); iter++) + { + g_Settings->UnregisterChangeCB(*iter, this, (CSettings::SettingChangedFunc)SettingsChanged); + } +} + +void CMainMenu::SettingsChanged(CMainMenu * _this) +{ + _this->ResetMenu(); +} + +int CMainMenu::ProcessAccelerator(HWND hWnd, void * lpMsg) +{ + if (m_ResetAccelerators) + { + m_ResetAccelerators = false; + RebuildAccelerators(); + } + if (!m_AccelTable) { return false; } + return TranslateAccelerator((HWND)hWnd, (HACCEL)m_AccelTable, (LPMSG)lpMsg); +} + +stdstr CMainMenu::ChooseFileToOpen(HWND hParent) +{ + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hParent; + openfilename.lpstrFilter = "N64 ROMs (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin, *.ndd)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal;*.ndd\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + return stdstr(FileName); + } + return stdstr(""); +} + +void CMainMenu::SetTraceModuleSetttings(SettingID Type) +{ + uint32_t value = g_Settings->LoadDword(Type) == TraceVerbose ? g_Settings->LoadDefaultDword(Type) : TraceVerbose; + g_Settings->SaveDword(Type, value); +} + +bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuID) +{ + switch (MenuID) { + case ID_FILE_OPEN_ROM: + { + stdstr File = ChooseFileToOpen(hWnd); + if (File.length() > 0) + { + stdstr ext = CPath(File).GetExtension(); + if (!(_stricmp(ext.c_str(), "ndd") == 0)) + { + delete g_DDRom; + g_DDRom = NULL; + g_BaseSystem->RunFileImage(File.c_str()); + } + else + { + // Open Disk + if (g_BaseSystem->RunDiskImage(File.c_str())) + { + stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); + if ((IPLROM.length() <= 0) || (!g_BaseSystem->RunFileImage(IPLROM.c_str()))) + { + // Open DDROM + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + g_BaseSystem->RunFileImage(FileName); + } + } + } + } + + } + } + break; + case ID_FILE_ROM_INFO: + { + if (g_Rom) + { + RomInformation Info(g_Rom); + Info.DisplayInformation(hWnd); + } + } + break; + case ID_FILE_STARTEMULATION: + m_Gui->SaveWindowLoc(); + //Before we go and create the new system, ensure the previous one has been closed + CN64System::CloseSystem(); + //Ok now g_BaseSystem should definitely be clean for initialization + g_BaseSystem = new CN64System(g_Plugins, false); + //Now we have created again, we can start up emulation + g_BaseSystem->StartEmulation(true); + break; + case ID_FILE_ENDEMULATION: + WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ENDEMULATION"); + CN64System::CloseSystem(); + m_Gui->SaveWindowLoc(); + break; + case ID_FILE_ROMDIRECTORY: + WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ROMDIRECTORY 1"); + m_Gui->SelectRomDir(); + WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ROMDIRECTORY 2"); + m_Gui->RefreshMenu(); + WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ROMDIRECTORY 3"); + break; + case ID_FILE_REFRESHROMLIST: m_Gui->RefreshRomBrowser(); break; + case ID_FILE_EXIT: DestroyWindow((HWND)hWnd); break; + case ID_SYSTEM_RESET_SOFT: + WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_RESET_SOFT"); + g_BaseSystem->ExternalEvent(SysEvent_ResetCPU_Soft); + break; + case ID_SYSTEM_RESET_HARD: + WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_RESET_HARD"); + g_BaseSystem->ExternalEvent(SysEvent_ResetCPU_Hard); + break; + case ID_SYSTEM_PAUSE: + m_Gui->SaveWindowLoc(); + WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_PAUSE"); + g_BaseSystem->ExternalEvent(g_Settings->LoadBool(GameRunning_CPU_Paused) ? SysEvent_ResumeCPU_FromMenu : SysEvent_PauseCPU_FromMenu); + WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_PAUSE 1"); + break; + case ID_SYSTEM_BITMAP: + { + stdstr Dir(g_Settings->LoadStringVal(Directory_SnapShot)); + WriteTrace(TraceGFXPlugin, TraceDebug, "CaptureScreen(%s): Starting", Dir.c_str()); + g_Plugins->Gfx()->CaptureScreen(Dir.c_str()); + WriteTrace(TraceGFXPlugin, TraceDebug, "CaptureScreen: Done"); + } + break; + case ID_SYSTEM_LIMITFPS: + WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_LIMITFPS"); + g_Settings->SaveBool(GameRunning_LimitFPS, !g_Settings->LoadBool(GameRunning_LimitFPS)); + WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_LIMITFPS 1"); + break; + case ID_SYSTEM_SAVE: + WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_SAVE"); + g_BaseSystem->ExternalEvent(SysEvent_SaveMachineState); + break; + case ID_SYSTEM_SAVEAS: + { + char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; + char Directory[255], SaveFile[255]; + OPENFILENAME openfilename; + + memset(&SaveFile, 0, sizeof(SaveFile)); + memset(&openfilename, 0, sizeof(openfilename)); + + g_Settings->LoadStringVal(Directory_LastSave, Directory, sizeof(Directory)); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "PJ64 Saves (*.zip, *.pj)\0*.pj?;*.pj;*.zip;"; + openfilename.lpstrFile = SaveFile; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_HIDEREADONLY; + + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SaveGame); + if (GetSaveFileName(&openfilename)) + { + _splitpath(SaveFile, drive, dir, fname, ext); + if (_stricmp(ext, ".pj") == 0 || _stricmp(ext, ".zip") == 0) + { + _makepath(SaveFile, drive, dir, fname, NULL); + _splitpath(SaveFile, drive, dir, fname, ext); + if (_stricmp(ext, ".pj") == 0) + { + _makepath(SaveFile, drive, dir, fname, NULL); + } + } + g_Settings->SaveString(GameRunning_InstantSaveFile, SaveFile); + + char SaveDir[MAX_PATH]; + _makepath(SaveDir, drive, dir, NULL, NULL); + g_Settings->SaveString(Directory_LastSave, SaveDir); + g_BaseSystem->ExternalEvent(SysEvent_SaveMachineState); + } + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SaveGame); + } + break; + case ID_SYSTEM_RESTORE: WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_RESTORE"); g_BaseSystem->ExternalEvent(SysEvent_LoadMachineState); break; + case ID_SYSTEM_LOAD: + { + char Directory[255], SaveFile[255]; + OPENFILENAME openfilename; + + memset(&SaveFile, 0, sizeof(SaveFile)); + memset(&openfilename, 0, sizeof(openfilename)); + + g_Settings->LoadStringVal(Directory_LastSave, Directory, sizeof(Directory)); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "PJ64 Saves (*.zip, *.pj)\0*.pj?;*.pj;*.zip;"; + openfilename.lpstrFile = SaveFile; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_HIDEREADONLY; + + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_LoadGame); + if (GetOpenFileName(&openfilename)) + { + g_Settings->SaveString(GameRunning_InstantSaveFile, SaveFile); + char SaveDir[MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; + _splitpath(SaveFile, drive, dir, fname, ext); + _makepath(SaveDir, drive, dir, NULL, NULL); + g_Settings->SaveString(Directory_LastSave, SaveDir); + g_System->LoadState(); + } + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_LoadGame); + } + break; + case ID_SYSTEM_CHEAT: + { + CCheatsUI * cheatUI = new CCheatsUI; + g_cheatUI = cheatUI; + cheatUI->SelectCheats(hWnd, false); + } + break; + case ID_SYSTEM_GSBUTTON: + g_BaseSystem->ExternalEvent(SysEvent_GSButtonPressed); + break; + case ID_OPTIONS_DISPLAY_FR: + g_Settings->SaveBool(UserInterface_DisplayFrameRate, !g_Settings->LoadBool(UserInterface_DisplayFrameRate)); + break; + case ID_OPTIONS_CHANGE_FR: + switch (g_Settings->LoadDword(UserInterface_FrameDisplayType)) + { + case FR_VIs: + g_Settings->SaveDword(UserInterface_FrameDisplayType, FR_DLs); + break; + case FR_DLs: + g_Settings->SaveDword(UserInterface_FrameDisplayType, FR_PERCENT); + break; + default: + g_Settings->SaveDword(UserInterface_FrameDisplayType, FR_VIs); + } + break; + case ID_OPTIONS_INCREASE_SPEED: + g_BaseSystem->IncreaseSpeed(); + break; + case ID_OPTIONS_DECREASE_SPEED: + g_BaseSystem->DecreaseSpeed(); + break; + case ID_OPTIONS_FULLSCREEN: + g_BaseSystem->ExternalEvent(SysEvent_ChangingFullScreen); + break; + case ID_OPTIONS_FULLSCREEN2: + if (g_Settings->LoadBool(UserInterface_InFullScreen)) + { + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN a"); + m_Gui->MakeWindowOnTop(false); + Notify().SetGfxPlugin(NULL); + WriteTrace(TraceGFXPlugin, TraceDebug, "ChangeWindow: Starting"); + g_Plugins->Gfx()->ChangeWindow(); + WriteTrace(TraceGFXPlugin, TraceDebug, "ChangeWindow: Done"); + ShowCursor(true); + m_Gui->ShowStatusBar(true); + m_Gui->MakeWindowOnTop(g_Settings->LoadBool(UserInterface_AlwaysOnTop)); + g_Settings->SaveBool(UserInterface_InFullScreen, (DWORD)false); + } + else + { + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b"); + ShowCursor(false); + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 1"); + m_Gui->ShowStatusBar(false); + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 2"); + try + { + WriteTrace(TraceGFXPlugin, TraceDebug, "ChangeWindow: Starting"); + g_Plugins->Gfx()->ChangeWindow(); + WriteTrace(TraceGFXPlugin, TraceDebug, "ChangeWindow: Done"); + } + catch (...) + { + WriteTrace(TraceError, TraceDebug, "Exception when going to full screen"); + char Message[600]; + sprintf(Message, "Exception caught\nFile: %s\nLine: %d", __FILE__, __LINE__); + MessageBox(NULL, Message, "Exception", MB_OK); + } + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 4"); + m_Gui->MakeWindowOnTop(false); + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 5"); + Notify().SetGfxPlugin(g_Plugins->Gfx()); + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 3"); + g_Settings->SaveBool(UserInterface_InFullScreen, true); + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN b 6"); + } + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_FULLSCREEN 1"); + break; + case ID_OPTIONS_ALWAYSONTOP: + if (g_Settings->LoadDword(UserInterface_AlwaysOnTop)) + { + g_Settings->SaveBool(UserInterface_AlwaysOnTop, false); + m_Gui->MakeWindowOnTop(false); + } + else + { + g_Settings->SaveBool(UserInterface_AlwaysOnTop, true); + m_Gui->MakeWindowOnTop(g_Settings->LoadBool(GameRunning_CPU_Running)); + } + break; + case ID_OPTIONS_CONFIG_RSP: + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_RSP"); + g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_RSP); + break; + case ID_OPTIONS_CONFIG_GFX: + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_GFX"); + g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_GFX); + break; + case ID_OPTIONS_CONFIG_AUDIO: + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_AUDIO"); + g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_AUDIO); + break; + case ID_OPTIONS_CONFIG_CONT: + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_CONT"); + g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_CONTROLLER); + break; + case ID_OPTIONS_CPU_USAGE: + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CPU_USAGE"); + if (g_Settings->LoadBool(UserInterface_ShowCPUPer)) + { + g_Settings->SaveBool(UserInterface_ShowCPUPer, false); + g_Notify->DisplayMessage(0, ""); + } + else + { + g_Settings->SaveBool(UserInterface_ShowCPUPer, true); + } + break; + case ID_OPTIONS_SETTINGS: + { + CSettingConfig SettingConfig; + SettingConfig.Display(hWnd); + } + break; + case ID_PROFILE_PROFILE: + g_Settings->SaveBool(Debugger_ProfileCode, !g_Settings->LoadBool(Debugger_ProfileCode)); + g_BaseSystem->ExternalEvent(SysEvent_Profile_StartStop); + break; + case ID_PROFILE_RESETCOUNTER: g_BaseSystem->ExternalEvent(SysEvent_Profile_ResetLogs); break; + case ID_PROFILE_GENERATELOG: g_BaseSystem->ExternalEvent(SysEvent_Profile_GenerateLogs); break; + case ID_DEBUG_SHOW_TLB_MISSES: + g_Settings->SaveBool(Debugger_ShowTLBMisses, !g_Settings->LoadBool(Debugger_ShowTLBMisses)); + break; + case ID_DEBUG_SHOW_UNHANDLED_MEM: + g_Settings->SaveBool(Debugger_ShowUnhandledMemory, !g_Settings->LoadBool(Debugger_ShowUnhandledMemory)); + break; + case ID_DEBUG_SHOW_PIF_ERRORS: + g_Settings->SaveBool(Debugger_ShowPifErrors, !g_Settings->LoadBool(Debugger_ShowPifErrors)); + break; + case ID_DEBUG_SHOW_DLIST_COUNT: + g_Notify->DisplayMessage(0, ""); + g_Settings->SaveBool(Debugger_ShowDListAListCount, !g_Settings->LoadBool(Debugger_ShowDListAListCount)); + break; + case ID_DEBUG_SHOW_RECOMP_MEM_SIZE: + g_Notify->DisplayMessage(0, ""); + g_Settings->SaveBool(Debugger_ShowRecompMemSize, !g_Settings->LoadBool(Debugger_ShowRecompMemSize)); + break; + case ID_DEBUG_SHOW_DIV_BY_ZERO: + g_Settings->SaveBool(Debugger_ShowDivByZero, !g_Settings->LoadBool(Debugger_ShowDivByZero)); + break; + case ID_DEBUG_GENERATE_LOG_FILES: + g_Settings->SaveBool(Debugger_GenerateLogFiles, !g_Settings->LoadBool(Debugger_GenerateLogFiles)); + break; + case ID_DEBUG_DISABLE_GAMEFIX: + g_Settings->SaveBool(Debugger_DisableGameFixes, !g_Settings->LoadBool(Debugger_DisableGameFixes)); + break; + case ID_DEBUGGER_TRACE_MD5: SetTraceModuleSetttings(Debugger_TraceMD5); break; + case ID_DEBUGGER_TRACE_SETTINGS: SetTraceModuleSetttings(Debugger_TraceSettings); break; + case ID_DEBUGGER_TRACE_UNKNOWN: SetTraceModuleSetttings(Debugger_TraceUnknown); break; + case ID_DEBUGGER_TRACE_APPINIT: SetTraceModuleSetttings(Debugger_TraceAppInit); break; + case ID_DEBUGGER_TRACE_APPCLEANUP: SetTraceModuleSetttings(Debugger_TraceAppCleanup); break; + case ID_DEBUGGER_TRACE_N64SYSTEM: SetTraceModuleSetttings(Debugger_TraceN64System); break; + case ID_DEBUGGER_TRACE_PLUGINS: SetTraceModuleSetttings(Debugger_TracePlugins); break; + case ID_DEBUGGER_TRACE_GFXPLUGIN: SetTraceModuleSetttings(Debugger_TraceGFXPlugin); break; + case ID_DEBUGGER_TRACE_AUDIOPLUGIN: SetTraceModuleSetttings(Debugger_TraceAudioPlugin); break; + case ID_DEBUGGER_TRACE_CONTROLLERPLUGIN: SetTraceModuleSetttings(Debugger_TraceControllerPlugin); break; + case ID_DEBUGGER_TRACE_RSPPLUGIN: SetTraceModuleSetttings(Debugger_TraceRSPPlugin); break; + case ID_DEBUGGER_TRACE_RSP: SetTraceModuleSetttings(Debugger_TraceRSP); break; + case ID_DEBUGGER_TRACE_AUDIO: SetTraceModuleSetttings(Debugger_TraceAudio); break; + case ID_DEBUGGER_TRACE_REGISTERCACHE: SetTraceModuleSetttings(Debugger_TraceRegisterCache); break; + case ID_DEBUGGER_TRACE_RECOMPILER: SetTraceModuleSetttings(Debugger_TraceRecompiler); break; + case ID_DEBUGGER_TRACE_TLB: SetTraceModuleSetttings(Debugger_TraceTLB); break; + case ID_DEBUGGER_TRACE_PROTECTEDMEM: SetTraceModuleSetttings(Debugger_TraceProtectedMEM); break; + case ID_DEBUGGER_TRACE_USERINTERFACE: SetTraceModuleSetttings(Debugger_TraceUserInterface); break; + + case ID_DEBUGGER_APPLOG_FLUSH: + g_Settings->SaveBool(Debugger_AppLogFlush, !g_Settings->LoadBool(Debugger_AppLogFlush)); + break; + case ID_DEBUGGER_LOGOPTIONS: m_Gui->EnterLogOptions(); break; + case ID_DEBUGGER_GENERATELOG: + g_Settings->SaveBool(Logging_GenerateLog, !g_Settings->LoadBool(Logging_GenerateLog)); + break; + case ID_DEBUGGER_DUMPMEMORY: m_Gui->Debug_ShowMemoryDump(); break; + case ID_DEBUGGER_SEARCHMEMORY: m_Gui->Debug_ShowMemorySearch(); break; + case ID_DEBUGGER_MEMORY: m_Gui->Debug_ShowMemoryWindow(); break; + case ID_DEBUGGER_TLBENTRIES: m_Gui->Debug_ShowTLBWindow(); break; + case ID_DEBUGGER_INTERRUPT_SP: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_SP); break; + case ID_DEBUGGER_INTERRUPT_SI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_SI); break; + case ID_DEBUGGER_INTERRUPT_AI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_AI); break; + case ID_DEBUGGER_INTERRUPT_VI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_VI); break; + case ID_DEBUGGER_INTERRUPT_PI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_PI); break; + case ID_DEBUGGER_INTERRUPT_DP: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_DP); break; + case ID_CURRENT_SAVE_DEFAULT: + g_Notify->DisplayMessage(3, stdstr_f(GS(MENU_SLOT_SAVE), GetSaveSlotString(MenuID - ID_CURRENT_SAVE_DEFAULT).c_str()).c_str()); + g_Settings->SaveDword(Game_CurrentSaveState, (DWORD)(MenuID - ID_CURRENT_SAVE_DEFAULT)); + break; + case ID_CURRENT_SAVE_1: + case ID_CURRENT_SAVE_2: + case ID_CURRENT_SAVE_3: + case ID_CURRENT_SAVE_4: + case ID_CURRENT_SAVE_5: + case ID_CURRENT_SAVE_6: + case ID_CURRENT_SAVE_7: + case ID_CURRENT_SAVE_8: + case ID_CURRENT_SAVE_9: + case ID_CURRENT_SAVE_10: + g_Notify->DisplayMessage(3, stdstr_f(GS(MENU_SLOT_SAVE), GetSaveSlotString((MenuID - ID_CURRENT_SAVE_1) + 1).c_str()).c_str()); + g_Settings->SaveDword(Game_CurrentSaveState, (DWORD)((MenuID - ID_CURRENT_SAVE_1) + 1)); + break; + case ID_HELP_SUPPORTFORUM: ShellExecute(NULL, "open", "http://forum.pj64-emu.com/", NULL, NULL, SW_SHOWMAXIMIZED); break; + case ID_HELP_HOMEPAGE: ShellExecute(NULL, "open", "http://www.pj64-emu.com", NULL, NULL, SW_SHOWMAXIMIZED); break; + case ID_HELP_ABOUT: m_Gui->AboutBox(); break; + case ID_HELP_ABOUTSETTINGFILES: m_Gui->AboutIniBox(); break; + default: + if (MenuID >= ID_RECENT_ROM_START && MenuID < ID_RECENT_ROM_END) + { + stdstr FileName; + if (g_Settings->LoadStringIndex(File_RecentGameFileIndex, MenuID - ID_RECENT_ROM_START, FileName) && + FileName.length() > 0) + { + g_BaseSystem->RunFileImage(FileName.c_str()); + } + } + if (MenuID >= ID_RECENT_DIR_START && MenuID < ID_RECENT_DIR_END) + { + int Offset = MenuID - ID_RECENT_DIR_START; + stdstr Dir = g_Settings->LoadStringIndex(Directory_RecentGameDirIndex, Offset); + if (Dir.length() > 0) + { + g_Settings->SaveString(Directory_Game, Dir.c_str()); + Notify().AddRecentDir(Dir.c_str()); + m_Gui->RefreshMenu(); + if (m_Gui->RomBrowserVisible()) + { + m_Gui->RefreshRomBrowser(); + } + } + } + if (MenuID >= ID_LANG_START && MenuID < ID_LANG_END) + { + MENUITEMINFOW menuinfo; + wchar_t String[300]; + + menuinfo.cbSize = sizeof(MENUITEMINFO); + menuinfo.fMask = MIIM_TYPE; + menuinfo.fType = MFT_STRING; + menuinfo.dwTypeData = String; + menuinfo.cch = sizeof(String); + GetMenuItemInfoW((HMENU)m_MenuHandle, MenuID, FALSE, &menuinfo); + + g_Lang->SetLanguage(stdstr().FromUTF16(String).c_str()); + m_Gui->ResetRomBrowserColomuns(); + break; + } + return false; + } + return true; +} + +stdstr CMainMenu::GetFileLastMod(stdstr FileName) +{ + HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + return ""; + } + FILETIME CreationTime, LastAccessTime, LastWriteTime; + stdstr LastMod; + if (GetFileTime(hFile, &CreationTime, &LastAccessTime, &LastWriteTime)) + { + SYSTEMTIME stUTC, stLocal; + + // Convert the last-write time to local time. + FileTimeToSystemTime(&LastWriteTime, &stUTC); + SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal); + + LastMod.Format(" [%d/%02d/%02d %02d:%02d]", stLocal.wYear, stLocal.wMonth, stLocal.wDay, stLocal.wHour, stLocal.wMinute); + } + CloseHandle(hFile); + + return LastMod; +} + +std::wstring CMainMenu::GetSaveSlotString(int Slot) +{ + stdstr SlotName; + switch (Slot) + { + case 0: SlotName = GS(MENU_SLOT_DEFAULT); break; + case 1: SlotName = GS(MENU_SLOT_1); break; + case 2: SlotName = GS(MENU_SLOT_2); break; + case 3: SlotName = GS(MENU_SLOT_3); break; + case 4: SlotName = GS(MENU_SLOT_4); break; + case 5: SlotName = GS(MENU_SLOT_5); break; + case 6: SlotName = GS(MENU_SLOT_6); break; + case 7: SlotName = GS(MENU_SLOT_7); break; + case 8: SlotName = GS(MENU_SLOT_8); break; + case 9: SlotName = GS(MENU_SLOT_9); break; + case 10: SlotName = GS(MENU_SLOT_10); break; + } + + if (!g_Settings->LoadBool(GameRunning_CPU_Running)) { return SlotName.ToUTF16(); } + + stdstr LastSaveTime; + + //check first save name + stdstr _GoodName = g_Settings->LoadStringVal(Game_GoodName); + stdstr _InstantSaveDirectory = g_Settings->LoadStringVal(Directory_InstantSave); + stdstr CurrentSaveName; + if (Slot != 0) + { + CurrentSaveName.Format("%s.pj%d", _GoodName.c_str(), Slot); + } + else + { + CurrentSaveName.Format("%s.pj", _GoodName.c_str()); + } + stdstr_f FileName("%s%s", _InstantSaveDirectory.c_str(), CurrentSaveName.c_str()); + + if (g_Settings->LoadDword(Setting_AutoZipInstantSave)) + { + stdstr_f ZipFileName("%s.zip", FileName.c_str()); + LastSaveTime = GetFileLastMod(ZipFileName); + } + if (LastSaveTime.empty()) + { + LastSaveTime = GetFileLastMod(FileName); + } + + // Check old file name + if (LastSaveTime.empty()) + { + stdstr _RomName = g_Settings->LoadStringVal(Game_GameName); + if (Slot > 0) + { + FileName.Format("%s%s.pj%d", _InstantSaveDirectory.c_str(), _RomName.c_str(), Slot); + } + else + { + FileName.Format("%s%s.pj", _InstantSaveDirectory.c_str(), _RomName.c_str()); + } + + if (g_Settings->LoadBool(Setting_AutoZipInstantSave)) + { + stdstr_f ZipFileName("%s.zip", FileName.c_str()); + LastSaveTime = GetFileLastMod(ZipFileName); + } + if (LastSaveTime.empty()) + { + LastSaveTime = GetFileLastMod(FileName); + } + } + SlotName += LastSaveTime; + return SlotName.ToUTF16(); +} + +void CMainMenu::FillOutMenu(HMENU hMenu) +{ + CGuard Guard(m_CS); + + MENU_ITEM Item; + + //Get all flags + bool inBasicMode = g_Settings->LoadBool(UserInterface_BasicMode); + bool CPURunning = g_Settings->LoadBool(GameRunning_CPU_Running); + bool RomLoading = g_Settings->LoadBool(GameRunning_LoadingInProgress); + bool RomLoaded = g_Settings->LoadStringVal(Game_GameName).length() > 0; + bool RomList = g_Settings->LoadBool(RomBrowser_Enabled) && !CPURunning; + + CMenuShortCutKey::ACCESS_MODE AccessLevel = CMenuShortCutKey::GAME_NOT_RUNNING; + if (g_Settings->LoadBool(GameRunning_CPU_Running)) + { + AccessLevel = g_Settings->LoadBool(UserInterface_InFullScreen) ? CMenuShortCutKey::GAME_RUNNING_FULLSCREEN : CMenuShortCutKey::GAME_RUNNING_WINDOW; + } + + //Get the system information to make the menu + LanguageList LangList = g_Lang->GetLangList(); + + MenuItemList LangMenu; + int Offset = 0; + for (LanguageList::iterator Language = LangList.begin(); Language != LangList.end(); Language++) + { + Item.Reset(ID_LANG_START + Offset++, EMPTY_STRING, EMPTY_STDSTR, NULL, stdstr(Language->LanguageName).ToUTF16().c_str()); + if (g_Lang->IsCurrentLang(*Language)) + { + Item.SetItemTicked(true); + } + LangMenu.push_back(Item); + } + + //Go through the settings to create a list of Recent Roms + MenuItemList RecentRomMenu; + DWORD count, RomsToRemember = g_Settings->LoadDword(File_RecentGameFileCount); + + for (count = 0; count < RomsToRemember; count++) + { + stdstr LastRom = g_Settings->LoadStringIndex(File_RecentGameFileIndex, count); + if (LastRom.empty()) + { + break; + } + stdstr_f MenuString("&%d %s", (count + 1) % 10, LastRom.c_str()); + + RecentRomMenu.push_back(MENU_ITEM(ID_RECENT_ROM_START + count, EMPTY_STRING, EMPTY_STDSTR, NULL, MenuString.ToUTF16(CP_ACP).c_str())); + } + + /* Recent Dir + ****************/ + MenuItemList RecentDirMenu; + DWORD DirsToRemember = g_Settings->LoadDword(Directory_RecentGameDirCount); + + for (count = 0; count < DirsToRemember; count++) + { + stdstr LastDir = g_Settings->LoadStringIndex(Directory_RecentGameDirIndex, count); + if (LastDir.empty()) + { + break; + } + + stdstr_f MenuString("&%d %s", (count + 1) % 10, LastDir.c_str()); + + RecentDirMenu.push_back(MENU_ITEM(ID_RECENT_DIR_START + count, EMPTY_STRING, EMPTY_STDSTR, NULL, MenuString.ToUTF16(CP_ACP).c_str())); + } + + /* File Menu + ****************/ + MenuItemList FileMenu; + Item.Reset(ID_FILE_OPEN_ROM, MENU_OPEN, m_ShortCuts.ShortCutString(ID_FILE_OPEN_ROM, AccessLevel)); + FileMenu.push_back(Item); + if (!inBasicMode) + { + Item.Reset(ID_FILE_ROM_INFO, MENU_ROM_INFO, m_ShortCuts.ShortCutString(ID_FILE_ROM_INFO, AccessLevel)); + Item.SetItemEnabled(RomLoaded); + FileMenu.push_back(Item); + FileMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(ID_FILE_STARTEMULATION, MENU_START, m_ShortCuts.ShortCutString(ID_FILE_STARTEMULATION, AccessLevel)); + Item.SetItemEnabled(RomLoaded && !CPURunning); + FileMenu.push_back(Item); + } + Item.Reset(ID_FILE_ENDEMULATION, MENU_END, m_ShortCuts.ShortCutString(ID_FILE_ENDEMULATION, AccessLevel)); + Item.SetItemEnabled(CPURunning); + FileMenu.push_back(Item); + FileMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(SUB_MENU, MENU_LANGUAGE, EMPTY_STDSTR, &LangMenu); + FileMenu.push_back(Item); + if (RomList) + { + FileMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(ID_FILE_ROMDIRECTORY, MENU_CHOOSE_ROM, m_ShortCuts.ShortCutString(ID_FILE_ROMDIRECTORY, AccessLevel)); + FileMenu.push_back(Item); + Item.Reset(ID_FILE_REFRESHROMLIST, MENU_REFRESH, m_ShortCuts.ShortCutString(ID_FILE_REFRESHROMLIST, AccessLevel)); + FileMenu.push_back(Item); + } + + if (!inBasicMode && RomList) + { + FileMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(SUB_MENU, MENU_RECENT_ROM, EMPTY_STDSTR, &RecentRomMenu); + if (RecentRomMenu.size() == 0) + { + RecentRomMenu.push_back(MENU_ITEM(SPLITER)); + Item.SetItemEnabled(false); + } + FileMenu.push_back(Item); + Item.Reset(SUB_MENU, MENU_RECENT_DIR, EMPTY_STDSTR, &RecentDirMenu); + if (RecentDirMenu.size() == 0) + { + RecentDirMenu.push_back(MENU_ITEM(SPLITER)); + Item.SetItemEnabled(false); + } + FileMenu.push_back(Item); + } + else + { + if (RecentRomMenu.size() != 0) + { + FileMenu.push_back(MENU_ITEM(SPLITER)); + for (MenuItemList::iterator MenuItem = RecentRomMenu.begin(); MenuItem != RecentRomMenu.end(); MenuItem++) + { + FileMenu.push_back(*MenuItem); + } + } + } + FileMenu.push_back(MENU_ITEM(SPLITER)); + FileMenu.push_back(MENU_ITEM(ID_FILE_EXIT, MENU_EXIT, m_ShortCuts.ShortCutString(ID_FILE_EXIT, AccessLevel))); + + /* Current Save + ****************/ + MenuItemList CurrentSaveMenu; + DWORD _CurrentSaveState = g_Settings->LoadDword(Game_CurrentSaveState); + Item.Reset(ID_CURRENT_SAVE_DEFAULT, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_DEFAULT, AccessLevel), NULL, GetSaveSlotString(0)); + if (_CurrentSaveState == 0) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + CurrentSaveMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(ID_CURRENT_SAVE_1, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_1, AccessLevel), NULL, GetSaveSlotString(1)); + if (_CurrentSaveState == 1) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_2, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_2, AccessLevel), NULL, GetSaveSlotString(2)); + if (_CurrentSaveState == 2) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_3, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_3, AccessLevel), NULL, GetSaveSlotString(3)); + if (_CurrentSaveState == 3) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_4, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_4, AccessLevel), NULL, GetSaveSlotString(4)); + if (_CurrentSaveState == 4) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_5, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_5, AccessLevel), NULL, GetSaveSlotString(5)); + if (_CurrentSaveState == 5) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_6, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_6, AccessLevel), NULL, GetSaveSlotString(6)); + if (_CurrentSaveState == 6) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_7, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_7, AccessLevel), NULL, GetSaveSlotString(7)); + if (_CurrentSaveState == 7) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_8, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_8, AccessLevel), NULL, GetSaveSlotString(8)); + if (_CurrentSaveState == 8) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_9, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_9, AccessLevel), NULL, GetSaveSlotString(9)); + if (_CurrentSaveState == 9) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + Item.Reset(ID_CURRENT_SAVE_10, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_10, AccessLevel), NULL, GetSaveSlotString(10)); + if (_CurrentSaveState == 10) { Item.SetItemTicked(true); } + CurrentSaveMenu.push_back(Item); + + /* System Menu + ****************/ + MenuItemList SystemMenu; + MenuItemList ResetMenu; + if (inBasicMode) + { + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT, AccessLevel))); + } + else + { + ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET_SOFT, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT, AccessLevel))); + ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_HARD, MENU_RESET_HARD, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_HARD, AccessLevel))); + SystemMenu.push_back(MENU_ITEM(SUB_MENU, MENU_RESET, EMPTY_STDSTR, &ResetMenu)); + } + if (g_Settings->LoadBool(GameRunning_CPU_Paused)) + { + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_RESUME, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE, AccessLevel))); + } + else + { + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_PAUSE, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE, AccessLevel))); + } + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_BITMAP, MENU_BITMAP, m_ShortCuts.ShortCutString(ID_SYSTEM_BITMAP, AccessLevel))); + SystemMenu.push_back(MENU_ITEM(SPLITER)); + if (!inBasicMode) + { + Item.Reset(ID_SYSTEM_LIMITFPS, MENU_LIMIT_FPS, m_ShortCuts.ShortCutString(ID_SYSTEM_LIMITFPS, AccessLevel)); + if (g_Settings->LoadBool(GameRunning_LimitFPS)) { Item.SetItemTicked(true); } + SystemMenu.push_back(Item); + SystemMenu.push_back(MENU_ITEM(SPLITER)); + } + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVE, MENU_SAVE, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVE, AccessLevel))); + if (!inBasicMode) + { + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVEAS, MENU_SAVE_AS, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVEAS, AccessLevel))); + } + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESTORE, MENU_RESTORE, m_ShortCuts.ShortCutString(ID_SYSTEM_RESTORE, AccessLevel))); + if (!inBasicMode) + { + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_LOAD, MENU_LOAD, m_ShortCuts.ShortCutString(ID_SYSTEM_LOAD, AccessLevel))); + } + SystemMenu.push_back(MENU_ITEM(SPLITER)); + SystemMenu.push_back(MENU_ITEM(SUB_MENU, MENU_CURRENT_SAVE, EMPTY_STDSTR, &CurrentSaveMenu)); + SystemMenu.push_back(MENU_ITEM(SPLITER)); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_CHEAT, MENU_CHEAT, m_ShortCuts.ShortCutString(ID_SYSTEM_CHEAT, AccessLevel))); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_GSBUTTON, MENU_GS_BUTTON, m_ShortCuts.ShortCutString(ID_SYSTEM_GSBUTTON, AccessLevel))); + + /* Option Menu + ****************/ + MenuItemList OptionMenu; + Item.Reset(ID_OPTIONS_FULLSCREEN, MENU_FULL_SCREEN, m_ShortCuts.ShortCutString(ID_OPTIONS_FULLSCREEN, AccessLevel)); + Item.SetItemEnabled(CPURunning); + if (g_Plugins && g_Plugins->Gfx() && g_Plugins->Gfx()->ChangeWindow == NULL) + { + Item.SetItemEnabled(false); + } + OptionMenu.push_back(Item); + if (!inBasicMode) + { + Item.Reset(ID_OPTIONS_ALWAYSONTOP, MENU_ON_TOP, m_ShortCuts.ShortCutString(ID_OPTIONS_ALWAYSONTOP, AccessLevel)); + if (g_Settings->LoadDword(UserInterface_AlwaysOnTop)) { Item.SetItemTicked(true); } + Item.SetItemEnabled(CPURunning); + OptionMenu.push_back(Item); + } + OptionMenu.push_back(MENU_ITEM(SPLITER)); + + Item.Reset(ID_OPTIONS_CONFIG_GFX, MENU_CONFG_GFX, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_GFX, AccessLevel)); + if (g_Plugins && g_Plugins->Gfx() == NULL || g_Plugins->Gfx()->DllConfig == NULL) + { + Item.SetItemEnabled(false); + } + OptionMenu.push_back(Item); + Item.Reset(ID_OPTIONS_CONFIG_AUDIO, MENU_CONFG_AUDIO, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_AUDIO, AccessLevel)); + if (g_Plugins->Audio() == NULL || g_Plugins->Audio()->DllConfig == NULL) + { + Item.SetItemEnabled(false); + } + OptionMenu.push_back(Item); + if (!inBasicMode) + { + Item.Reset(ID_OPTIONS_CONFIG_RSP, MENU_CONFG_RSP, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_RSP, AccessLevel)); + if (g_Plugins->RSP() == NULL || g_Plugins->RSP()->DllConfig == NULL) + { + Item.SetItemEnabled(false); + } + OptionMenu.push_back(Item); + } + Item.Reset(ID_OPTIONS_CONFIG_CONT, MENU_CONFG_CTRL, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_CONT, AccessLevel)); + if (g_Plugins && g_Plugins->Control() == NULL || g_Plugins->Control()->DllConfig == NULL) + { + Item.SetItemEnabled(false); + } + OptionMenu.push_back(Item); + + OptionMenu.push_back(MENU_ITEM(SPLITER)); + if (!inBasicMode) + { + Item.Reset(ID_OPTIONS_CPU_USAGE, MENU_SHOW_CPU, m_ShortCuts.ShortCutString(ID_OPTIONS_CPU_USAGE, AccessLevel)); + if (g_Settings->LoadDword(UserInterface_ShowCPUPer)) { Item.SetItemTicked(true); } + OptionMenu.push_back(Item); + } + OptionMenu.push_back(MENU_ITEM(ID_OPTIONS_SETTINGS, MENU_SETTINGS, m_ShortCuts.ShortCutString(ID_OPTIONS_SETTINGS, AccessLevel))); + + /* Profile Menu + ****************/ + MenuItemList DebugProfileMenu; + if (bHaveDebugger()) + { + Item.Reset(ID_PROFILE_PROFILE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Profile Code"); + if (g_Settings->LoadBool(Debugger_ProfileCode)) { Item.SetItemTicked(true); } + DebugProfileMenu.push_back(Item); + Item.Reset(ID_PROFILE_RESETCOUNTER, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Reset Counters"); + if (!CPURunning) { Item.SetItemEnabled(false); } + DebugProfileMenu.push_back(Item); + Item.Reset(ID_PROFILE_GENERATELOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Generate Log File"); + if (!CPURunning) { Item.SetItemEnabled(false); } + DebugProfileMenu.push_back(Item); + } + + /* Debugger Menu + ****************/ + MenuItemList DebugMenu; + MenuItemList DebugLoggingMenu; + MenuItemList DebugAppLoggingMenu; + MenuItemList DebugR4300Menu; + MenuItemList DebugMemoryMenu; + MenuItemList DebugInterrupt; + MenuItemList DebugNotificationMenu; + if (bHaveDebugger()) + { + /* Debug - Interrupt + *******************/ + Item.Reset(ID_DEBUGGER_INTERRUPT_SP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"SP Interrupt"); + Item.SetItemEnabled(CPURunning); + DebugInterrupt.push_back(Item); + Item.Reset(ID_DEBUGGER_INTERRUPT_SI, EMPTY_STRING, EMPTY_STDSTR, NULL, L"SI Interrupt"); + Item.SetItemEnabled(CPURunning); + DebugInterrupt.push_back(Item); + Item.Reset(ID_DEBUGGER_INTERRUPT_AI, EMPTY_STRING, EMPTY_STDSTR, NULL, L"AI Interrupt"); + Item.SetItemEnabled(CPURunning); + DebugInterrupt.push_back(Item); + Item.Reset(ID_DEBUGGER_INTERRUPT_VI, EMPTY_STRING, EMPTY_STDSTR, NULL, L"VI Interrupt"); + Item.SetItemEnabled(CPURunning); + DebugInterrupt.push_back(Item); + Item.Reset(ID_DEBUGGER_INTERRUPT_PI, EMPTY_STRING, EMPTY_STDSTR, NULL, L"PI Interrupt"); + Item.SetItemEnabled(CPURunning); + DebugInterrupt.push_back(Item); + Item.Reset(ID_DEBUGGER_INTERRUPT_DP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"DP Interrupt"); + Item.SetItemEnabled(CPURunning); + DebugInterrupt.push_back(Item); + + /* Debug - R4300i + *******************/ + Item.Reset(ID_DEBUGGER_LOGOPTIONS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Commands..."); + Item.SetItemEnabled(false); + DebugR4300Menu.push_back(Item); + Item.Reset(ID_DEBUGGER_R4300REGISTERS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Registers..."); + Item.SetItemEnabled(true); + DebugR4300Menu.push_back(Item); + Item.Reset(ID_DEBUG_DISABLE_GAMEFIX, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Disable Game Fixes"); + if (g_Settings->LoadBool(Debugger_DisableGameFixes)) + { + Item.SetItemTicked(true); + } + DebugR4300Menu.push_back(Item); + Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugInterrupt, L"&Generate Interrupt"); + DebugR4300Menu.push_back(Item); + + /* Debug - Memory + ****************/ + Item.Reset(ID_DEBUGGER_MEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"View..."); + DebugMemoryMenu.push_back(Item); + Item.Reset(ID_DEBUGGER_SEARCHMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Search..."); + DebugMemoryMenu.push_back(Item); + Item.Reset(ID_DEBUGGER_DUMPMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Dump..."); + DebugMemoryMenu.push_back(Item); + Item.Reset(ID_DEBUGGER_TLBENTRIES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"TLB Entries..."); + DebugMemoryMenu.push_back(Item); + + /* Debug - App logging + *******************/ + Item.Reset(ID_DEBUGGER_TRACE_MD5, EMPTY_STRING, EMPTY_STDSTR, NULL, L"MD5"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceMD5) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_SETTINGS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Settings"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceSettings) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_UNKNOWN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Unknown"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceUnknown) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_APPINIT, EMPTY_STRING, EMPTY_STDSTR, NULL, L"App Init"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceAppInit) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_APPCLEANUP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"App Cleanup"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceAppCleanup) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_N64SYSTEM, EMPTY_STRING, EMPTY_STDSTR, NULL, L"N64 System"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceN64System) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_PLUGINS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Plugins"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TracePlugins) == TraceVerbose);; + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_GFXPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"GFX Plugin"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceGFXPlugin) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_AUDIOPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Audio Plugin"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceAudioPlugin) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_CONTROLLERPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Controller Plugin"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceControllerPlugin) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_RSPPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"RSP Plugin"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRSPPlugin) == TraceVerbose);; + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_RSP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"RSP"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRSP) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_AUDIO, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Audio"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceAudio) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_REGISTERCACHE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Register Cache"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRegisterCache) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_RECOMPILER, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Recompiler"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRecompiler) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_TLB, EMPTY_STRING, EMPTY_STDSTR, NULL, L"TLB"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceTLB) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_PROTECTEDMEM, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Protected MEM"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceProtectedMEM) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_TRACE_USERINTERFACE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"User Interface"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceUserInterface) == TraceVerbose); + DebugAppLoggingMenu.push_back(Item); + + DebugAppLoggingMenu.push_back(MENU_ITEM(SPLITER)); + + Item.Reset(ID_DEBUGGER_APPLOG_FLUSH, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Auto flush file"); + if (g_Settings->LoadBool(Debugger_AppLogFlush)) { Item.SetItemTicked(true); } + DebugAppLoggingMenu.push_back(Item); + + /* Debug - Logging + *******************/ + Item.Reset(ID_DEBUGGER_LOGOPTIONS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Log Options..."); + DebugLoggingMenu.push_back(Item); + + Item.Reset(ID_DEBUGGER_GENERATELOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Generate Log"); + if (g_Settings->LoadBool(Logging_GenerateLog)) { Item.SetItemTicked(true); } + DebugLoggingMenu.push_back(Item); + + /* Debugger Main Menu + ****************/ + Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Breakpoint..."); + Item.SetItemEnabled(CPURunning); + DebugMenu.push_back(Item); + DebugMenu.push_back(MENU_ITEM(SPLITER)); + + /* Debug - RSP + *******************/ + if (g_Plugins && g_Plugins->RSP() != NULL && IsMenu((HMENU)g_Plugins->RSP()->GetDebugMenu())) + { + Item.Reset(ID_PLUGIN_MENU, EMPTY_STRING, EMPTY_STDSTR, g_Plugins->RSP()->GetDebugMenu(), L"&RSP"); + DebugMenu.push_back(Item); + } + + /* Debug - RDP + *******************/ + if (g_Plugins && g_Plugins->Gfx() != NULL && IsMenu((HMENU)g_Plugins->Gfx()->GetDebugMenu())) + { + Item.Reset(ID_PLUGIN_MENU, EMPTY_STRING, EMPTY_STDSTR, g_Plugins->Gfx()->GetDebugMenu(), L"&RDP"); + DebugMenu.push_back(Item); + } + + /* Notification Menu + *******************/ + Item.Reset(ID_DEBUG_SHOW_UNHANDLED_MEM, EMPTY_STRING, EMPTY_STDSTR, NULL, L"On Unhandled Memory Actions"); + if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) + { + Item.SetItemTicked(true); + } + DebugNotificationMenu.push_back(Item); + Item.Reset(ID_DEBUG_SHOW_PIF_ERRORS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"On PIF Errors"); + if (g_Settings->LoadBool(Debugger_ShowPifErrors)) + { + Item.SetItemTicked(true); + } + DebugNotificationMenu.push_back(Item); + Item.Reset(ID_DEBUG_SHOW_DIV_BY_ZERO, EMPTY_STRING, EMPTY_STDSTR, NULL, L"On Div By Zero"); + if (g_Settings->LoadBool(Debugger_ShowDivByZero)) + { + Item.SetItemTicked(true); + } + DebugNotificationMenu.push_back(Item); + + Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugR4300Menu, L"&R4300i"); + DebugMenu.push_back(Item); + Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugMemoryMenu, L"Memory"); + Item.SetItemEnabled(CPURunning); + DebugMenu.push_back(Item); + DebugMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugProfileMenu, L"Profile"); + DebugMenu.push_back(Item); + Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugAppLoggingMenu, L"App Logging"); + DebugMenu.push_back(Item); + Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugLoggingMenu, L"Logging"); + DebugMenu.push_back(Item); + Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugNotificationMenu, L"Notification"); + DebugMenu.push_back(Item); + DebugMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(ID_DEBUG_SHOW_TLB_MISSES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Show TLB Misses"); + if (g_Settings->LoadBool(Debugger_ShowTLBMisses)) + { + Item.SetItemTicked(true); + } + Item.Reset(ID_DEBUG_SHOW_DLIST_COUNT, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Display Alist/Dlist Count"); + if (g_Settings->LoadBool(Debugger_ShowDListAListCount)) + { + Item.SetItemTicked(true); + } + DebugMenu.push_back(Item); + Item.Reset(ID_DEBUG_SHOW_RECOMP_MEM_SIZE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Display Recompiler Code Buffer Size"); + if (g_Settings->LoadBool(Debugger_ShowRecompMemSize)) + { + Item.SetItemTicked(true); + } + DebugMenu.push_back(Item); + DebugMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(ID_DEBUG_GENERATE_LOG_FILES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Generate Log Files"); + if (g_Settings->LoadBool(Debugger_GenerateLogFiles)) + { + Item.SetItemTicked(true); + } + DebugMenu.push_back(Item); + } + + /* Help Menu + ****************/ + MenuItemList HelpMenu; + + HelpMenu.push_back(MENU_ITEM(ID_HELP_SUPPORTFORUM, MENU_FORUM)); + HelpMenu.push_back(MENU_ITEM(ID_HELP_HOMEPAGE, MENU_HOMEPAGE)); + HelpMenu.push_back(MENU_ITEM(SPLITER)); + if (!inBasicMode) + { + HelpMenu.push_back(MENU_ITEM(ID_HELP_ABOUTSETTINGFILES, MENU_ABOUT_INI)); + } + HelpMenu.push_back(MENU_ITEM(ID_HELP_ABOUT, MENU_ABOUT_PJ64)); + + /* Main Title bar Menu + ***********************/ + MenuItemList MainTitleMenu; + Item.Reset(SUB_MENU, MENU_FILE, EMPTY_STDSTR, &FileMenu); + if (RomLoading) { Item.SetItemEnabled(false); } + MainTitleMenu.push_back(Item); + if (CPURunning) + { + Item.Reset(SUB_MENU, MENU_SYSTEM, EMPTY_STDSTR, &SystemMenu); + if (RomLoading) { Item.SetItemEnabled(false); } + MainTitleMenu.push_back(Item); + } + Item.Reset(SUB_MENU, MENU_OPTIONS, EMPTY_STDSTR, &OptionMenu); + if (RomLoading) { Item.SetItemEnabled(false); } + MainTitleMenu.push_back(Item); + if (!inBasicMode) + { + if (bHaveDebugger()) + { + Item.Reset(SUB_MENU, MENU_DEBUGGER, EMPTY_STDSTR, &DebugMenu); + if (RomLoading) { Item.SetItemEnabled(false); } + MainTitleMenu.push_back(Item); + } + } + Item.Reset(SUB_MENU, MENU_HELP, EMPTY_STDSTR, &HelpMenu); + if (RomLoading) { Item.SetItemEnabled(false); } + MainTitleMenu.push_back(Item); + + AddMenu(hMenu, MainTitleMenu); +} + +void CMainMenu::RebuildAccelerators(void) +{ + CGuard Guard(m_CS); + + //Delete the old accel list + WriteTrace(TraceUserInterface, TraceDebug, "Start"); + + HACCEL m_OldAccelTable = (HACCEL)m_AccelTable; + m_AccelTable = m_ShortCuts.GetAcceleratorTable(); + if (m_OldAccelTable) { + DestroyAcceleratorTable(m_OldAccelTable); + } + WriteTrace(TraceUserInterface, TraceDebug, "Done"); +} + +void CMainMenu::ResetMenu(void) +{ + WriteTrace(TraceUserInterface, TraceDebug, "Start"); + if (!g_Settings->LoadBool(UserInterface_InFullScreen)) + { + //Create a new window with all the items + WriteTrace(TraceUserInterface, TraceDebug, "Create Menu"); + HMENU hMenu = CreateMenu(); + FillOutMenu(hMenu); + WriteTrace(TraceUserInterface, TraceDebug, "Create Menu Done"); + + //save old menu to destroy latter + HMENU OldMenuHandle; + { + CGuard Guard(m_CS); + OldMenuHandle = m_MenuHandle; + + //save handle and re-attach to a window + WriteTrace(TraceUserInterface, TraceDebug, "Attach Menu"); + m_MenuHandle = hMenu; + } + m_Gui->SetWindowMenu(this); + + WriteTrace(TraceUserInterface, TraceDebug, "Remove plugin menu"); + if (g_Plugins->Gfx() != NULL && IsMenu((HMENU)g_Plugins->Gfx()->GetDebugMenu())) + { + RemoveMenu((HMENU)OldMenuHandle, (DWORD)g_Plugins->Gfx()->GetDebugMenu(), MF_BYCOMMAND); + } + if (g_Plugins->RSP() != NULL && IsMenu((HMENU)g_Plugins->RSP()->GetDebugMenu())) + { + RemoveMenu((HMENU)OldMenuHandle, (DWORD)g_Plugins->RSP()->GetDebugMenu(), MF_BYCOMMAND); + } + WriteTrace(TraceUserInterface, TraceDebug, "Destroy Old Menu"); + + //Destroy the old menu + DestroyMenu((HMENU)OldMenuHandle); + } + + ResetAccelerators(); + + WriteTrace(TraceUserInterface, TraceDebug, "Done"); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/MainMenuClass.h b/Source/Project64/UserInterface/MainMenuClass.h index dafda79c5..d9c3dd43b 100644 --- a/Source/Project64/UserInterface/MainMenuClass.h +++ b/Source/Project64/UserInterface/MainMenuClass.h @@ -1,93 +1,93 @@ -#pragma once - -enum MainMenuID -{ - //File Menu - ID_FILE_OPEN_ROM = 4000, ID_FILE_ROM_INFO, ID_FILE_STARTEMULATION, ID_FILE_ENDEMULATION, - ID_FILE_ROMDIRECTORY, ID_FILE_REFRESHROMLIST, ID_FILE_EXIT, - - //language - ID_LANG_START, ID_LANG_END = ID_LANG_START + 100, - - //Recent Files - ID_RECENT_ROM_START, ID_RECENT_ROM_END = ID_RECENT_ROM_START + 20, - - //Recent Dir - ID_RECENT_DIR_START, ID_RECENT_DIR_END = ID_RECENT_DIR_START + 20, - - //System Menu - ID_SYSTEM_RESET_SOFT, ID_SYSTEM_RESET_HARD, ID_SYSTEM_PAUSE, ID_SYSTEM_BITMAP, - ID_SYSTEM_LIMITFPS, ID_SYSTEM_RESTORE, ID_SYSTEM_LOAD, ID_SYSTEM_SAVE, - ID_SYSTEM_SAVEAS, ID_SYSTEM_CHEAT, ID_SYSTEM_GSBUTTON, - - //Current Save Slot - ID_CURRENT_SAVE_1, ID_CURRENT_SAVE_2, ID_CURRENT_SAVE_3, ID_CURRENT_SAVE_4, ID_CURRENT_SAVE_5, - ID_CURRENT_SAVE_6, ID_CURRENT_SAVE_7, ID_CURRENT_SAVE_8, ID_CURRENT_SAVE_9, ID_CURRENT_SAVE_10, - ID_CURRENT_SAVE_DEFAULT, - - //Option Menu - ID_OPTIONS_FULLSCREEN, ID_OPTIONS_FULLSCREEN2, ID_OPTIONS_ALWAYSONTOP, ID_OPTIONS_CONFIG_GFX, - ID_OPTIONS_CONFIG_AUDIO, ID_OPTIONS_CONFIG_CONT, ID_OPTIONS_CONFIG_RSP, ID_OPTIONS_CPU_USAGE, - ID_OPTIONS_SETTINGS, ID_OPTIONS_DISPLAY_FR, ID_OPTIONS_CHANGE_FR, ID_OPTIONS_INCREASE_SPEED, - ID_OPTIONS_DECREASE_SPEED, - - //Debugger Menu - ID_DEBUG_SHOW_TLB_MISSES, ID_DEBUG_SHOW_UNHANDLED_MEM, ID_DEBUG_SHOW_PIF_ERRORS, - ID_DEBUG_SHOW_DLIST_COUNT, ID_DEBUG_SHOW_RECOMP_MEM_SIZE, ID_DEBUG_SHOW_DIV_BY_ZERO, - ID_DEBUG_GENERATE_LOG_FILES, ID_DEBUG_DISABLE_GAMEFIX, - ID_DEBUGGER_LOGOPTIONS, ID_DEBUGGER_GENERATELOG, ID_DEBUGGER_DUMPMEMORY, ID_DEBUGGER_SEARCHMEMORY, - ID_DEBUGGER_TLBENTRIES, ID_DEBUGGER_BREAKPOINTS, ID_DEBUGGER_MEMORY, ID_DEBUGGER_R4300REGISTERS, - ID_DEBUGGER_INTERRUPT_SP, ID_DEBUGGER_INTERRUPT_SI, ID_DEBUGGER_INTERRUPT_AI, ID_DEBUGGER_INTERRUPT_VI, - ID_DEBUGGER_INTERRUPT_PI, ID_DEBUGGER_INTERRUPT_DP, - - // App logging - ID_DEBUGGER_APPLOG_FLUSH, ID_DEBUGGER_TRACE_MD5, ID_DEBUGGER_TRACE_SETTINGS, ID_DEBUGGER_TRACE_UNKNOWN, ID_DEBUGGER_TRACE_APPINIT, - ID_DEBUGGER_TRACE_APPCLEANUP, ID_DEBUGGER_TRACE_N64SYSTEM, ID_DEBUGGER_TRACE_PLUGINS, ID_DEBUGGER_TRACE_GFXPLUGIN, - ID_DEBUGGER_TRACE_AUDIOPLUGIN, ID_DEBUGGER_TRACE_CONTROLLERPLUGIN, ID_DEBUGGER_TRACE_RSPPLUGIN, ID_DEBUGGER_TRACE_RSP, - ID_DEBUGGER_TRACE_AUDIO, ID_DEBUGGER_TRACE_REGISTERCACHE, ID_DEBUGGER_TRACE_RECOMPILER, ID_DEBUGGER_TRACE_TLB, - ID_DEBUGGER_TRACE_PROTECTEDMEM, ID_DEBUGGER_TRACE_USERINTERFACE, - - //Profile Menu - ID_PROFILE_PROFILE, ID_PROFILE_RESETCOUNTER, ID_PROFILE_GENERATELOG, - - //Help Menu - ID_HELP_SUPPORTFORUM, ID_HELP_HOMEPAGE, ID_HELP_ABOUTSETTINGFILES, ID_HELP_ABOUT, -}; - -class CMainMenu : - public CBaseMenu, - private CDebugSettings -{ -public: - CMainMenu(CMainGui * Window); - ~CMainMenu(); - - int ProcessAccelerator(HWND hWnd, void * lpMsg); - bool ProcessMessage(HWND hWnd, DWORD wNotifyCode, DWORD wID); - void ResetMenu(void); - void ResetAccelerators(void) { m_ResetAccelerators = true; } - -private: - CMainMenu(); // Disable default constructor - CMainMenu(const CMainMenu&); // Disable copy constructor - CMainMenu& operator=(const CMainMenu&); // Disable assignment - - void FillOutMenu(HMENU hMenu); - std::wstring GetSaveSlotString(int Slot); - stdstr GetFileLastMod(stdstr FileName); - void RebuildAccelerators(void); - stdstr ChooseFileToOpen(HWND hParent); - void SetTraceModuleSetttings(SettingID Type); - - static void SettingsChanged(CMainMenu * _this); - - typedef std::list SettingList; - - CMainGui * m_Gui; - - void * m_AccelTable; - bool m_ResetAccelerators; - CShortCuts m_ShortCuts; - SettingList m_ChangeSettingList; - CriticalSection m_CS; -}; +#pragma once + +enum MainMenuID +{ + //File Menu + ID_FILE_OPEN_ROM = 4000, ID_FILE_ROM_INFO, ID_FILE_STARTEMULATION, ID_FILE_ENDEMULATION, + ID_FILE_ROMDIRECTORY, ID_FILE_REFRESHROMLIST, ID_FILE_EXIT, + + //language + ID_LANG_START, ID_LANG_END = ID_LANG_START + 100, + + //Recent Files + ID_RECENT_ROM_START, ID_RECENT_ROM_END = ID_RECENT_ROM_START + 20, + + //Recent Dir + ID_RECENT_DIR_START, ID_RECENT_DIR_END = ID_RECENT_DIR_START + 20, + + //System Menu + ID_SYSTEM_RESET_SOFT, ID_SYSTEM_RESET_HARD, ID_SYSTEM_PAUSE, ID_SYSTEM_BITMAP, + ID_SYSTEM_LIMITFPS, ID_SYSTEM_RESTORE, ID_SYSTEM_LOAD, ID_SYSTEM_SAVE, + ID_SYSTEM_SAVEAS, ID_SYSTEM_CHEAT, ID_SYSTEM_GSBUTTON, + + //Current Save Slot + ID_CURRENT_SAVE_1, ID_CURRENT_SAVE_2, ID_CURRENT_SAVE_3, ID_CURRENT_SAVE_4, ID_CURRENT_SAVE_5, + ID_CURRENT_SAVE_6, ID_CURRENT_SAVE_7, ID_CURRENT_SAVE_8, ID_CURRENT_SAVE_9, ID_CURRENT_SAVE_10, + ID_CURRENT_SAVE_DEFAULT, + + //Option Menu + ID_OPTIONS_FULLSCREEN, ID_OPTIONS_FULLSCREEN2, ID_OPTIONS_ALWAYSONTOP, ID_OPTIONS_CONFIG_GFX, + ID_OPTIONS_CONFIG_AUDIO, ID_OPTIONS_CONFIG_CONT, ID_OPTIONS_CONFIG_RSP, ID_OPTIONS_CPU_USAGE, + ID_OPTIONS_SETTINGS, ID_OPTIONS_DISPLAY_FR, ID_OPTIONS_CHANGE_FR, ID_OPTIONS_INCREASE_SPEED, + ID_OPTIONS_DECREASE_SPEED, + + //Debugger Menu + ID_DEBUG_SHOW_TLB_MISSES, ID_DEBUG_SHOW_UNHANDLED_MEM, ID_DEBUG_SHOW_PIF_ERRORS, + ID_DEBUG_SHOW_DLIST_COUNT, ID_DEBUG_SHOW_RECOMP_MEM_SIZE, ID_DEBUG_SHOW_DIV_BY_ZERO, + ID_DEBUG_GENERATE_LOG_FILES, ID_DEBUG_DISABLE_GAMEFIX, + ID_DEBUGGER_LOGOPTIONS, ID_DEBUGGER_GENERATELOG, ID_DEBUGGER_DUMPMEMORY, ID_DEBUGGER_SEARCHMEMORY, + ID_DEBUGGER_TLBENTRIES, ID_DEBUGGER_BREAKPOINTS, ID_DEBUGGER_MEMORY, ID_DEBUGGER_R4300REGISTERS, + ID_DEBUGGER_INTERRUPT_SP, ID_DEBUGGER_INTERRUPT_SI, ID_DEBUGGER_INTERRUPT_AI, ID_DEBUGGER_INTERRUPT_VI, + ID_DEBUGGER_INTERRUPT_PI, ID_DEBUGGER_INTERRUPT_DP, + + // App logging + ID_DEBUGGER_APPLOG_FLUSH, ID_DEBUGGER_TRACE_MD5, ID_DEBUGGER_TRACE_SETTINGS, ID_DEBUGGER_TRACE_UNKNOWN, ID_DEBUGGER_TRACE_APPINIT, + ID_DEBUGGER_TRACE_APPCLEANUP, ID_DEBUGGER_TRACE_N64SYSTEM, ID_DEBUGGER_TRACE_PLUGINS, ID_DEBUGGER_TRACE_GFXPLUGIN, + ID_DEBUGGER_TRACE_AUDIOPLUGIN, ID_DEBUGGER_TRACE_CONTROLLERPLUGIN, ID_DEBUGGER_TRACE_RSPPLUGIN, ID_DEBUGGER_TRACE_RSP, + ID_DEBUGGER_TRACE_AUDIO, ID_DEBUGGER_TRACE_REGISTERCACHE, ID_DEBUGGER_TRACE_RECOMPILER, ID_DEBUGGER_TRACE_TLB, + ID_DEBUGGER_TRACE_PROTECTEDMEM, ID_DEBUGGER_TRACE_USERINTERFACE, + + //Profile Menu + ID_PROFILE_PROFILE, ID_PROFILE_RESETCOUNTER, ID_PROFILE_GENERATELOG, + + //Help Menu + ID_HELP_SUPPORTFORUM, ID_HELP_HOMEPAGE, ID_HELP_ABOUTSETTINGFILES, ID_HELP_ABOUT, +}; + +class CMainMenu : + public CBaseMenu, + private CDebugSettings +{ +public: + CMainMenu(CMainGui * Window); + ~CMainMenu(); + + int ProcessAccelerator(HWND hWnd, void * lpMsg); + bool ProcessMessage(HWND hWnd, DWORD wNotifyCode, DWORD wID); + void ResetMenu(void); + void ResetAccelerators(void) { m_ResetAccelerators = true; } + +private: + CMainMenu(); // Disable default constructor + CMainMenu(const CMainMenu&); // Disable copy constructor + CMainMenu& operator=(const CMainMenu&); // Disable assignment + + void FillOutMenu(HMENU hMenu); + std::wstring GetSaveSlotString(int Slot); + stdstr GetFileLastMod(stdstr FileName); + void RebuildAccelerators(void); + stdstr ChooseFileToOpen(HWND hParent); + void SetTraceModuleSetttings(SettingID Type); + + static void SettingsChanged(CMainMenu * _this); + + typedef std::list SettingList; + + CMainGui * m_Gui; + + void * m_AccelTable; + bool m_ResetAccelerators; + CShortCuts m_ShortCuts; + SettingList m_ChangeSettingList; + CriticalSection m_CS; +}; diff --git a/Source/Project64/UserInterface/MenuClass.cpp b/Source/Project64/UserInterface/MenuClass.cpp index 6d7ec284d..adfad2063 100644 --- a/Source/Project64/UserInterface/MenuClass.cpp +++ b/Source/Project64/UserInterface/MenuClass.cpp @@ -1,72 +1,72 @@ -#include "stdafx.h" - -CBaseMenu::CBaseMenu() : -m_MenuHandle((HMENU)CreateMenu()) -{ -} - -bool CBaseMenu::AddMenu(HMENU hMenu, MenuItemList Items) -{ - if (Items.begin() == Items.end()) { return false; } - - UINT ItemID, uFlags; - std::wstring Text, String; - for (MenuItemList::iterator MenuItem = Items.begin(); MenuItem != Items.end(); MenuItem++) - { - ItemID = MenuItem->ID(); - uFlags = MF_STRING; - Text = wGS(MenuItem->Title()); - - if (MenuItem->Title() == EMPTY_STRING && MenuItem->ManualString().length() > 0) - { - Text = MenuItem->ManualString(); - } - if (ItemID == SPLITER) - { - uFlags |= MF_SEPARATOR; - } - if (MenuItem->ItemTicked()) - { - uFlags |= MFS_CHECKED; - } - if (MenuItem->ItemEnabled()) - { - uFlags |= MFS_ENABLED; - } - else - { - uFlags |= MFS_DISABLED; - } - - MenuItemList * SubMenu = (MenuItemList *)MenuItem->SubMenu(); - if (ItemID == SUB_MENU && HIWORD(SubMenu) != 0 && (SubMenu->begin() != SubMenu->end())) - { - ItemID = (UINT)CreatePopupMenu(); - uFlags |= MF_POPUP; - - AddMenu((HMENU)ItemID, *SubMenu); - } - - if (ItemID == ID_PLUGIN_MENU) - { - ItemID = (UINT)MenuItem->SubMenu(); - uFlags |= MF_POPUP; - MENUITEMINFO lpmii; - - lpmii.cbSize = sizeof(MENUITEMINFO); - lpmii.fMask = MIIM_STATE; - lpmii.fState = 0; - SetMenuItemInfo((HMENU)ItemID, (DWORD)MenuItem->SubMenu(), FALSE, &lpmii); - } - - if (MenuItem->ShortCut().empty() == false) - { - String = Text; - String += L"\t"; - String += MenuItem->ShortCut(); - Text = String; - } - AppendMenuW(hMenu, uFlags, ItemID, Text.c_str()); - } - return true; +#include "stdafx.h" + +CBaseMenu::CBaseMenu() : +m_MenuHandle((HMENU)CreateMenu()) +{ +} + +bool CBaseMenu::AddMenu(HMENU hMenu, MenuItemList Items) +{ + if (Items.begin() == Items.end()) { return false; } + + UINT ItemID, uFlags; + std::wstring Text, String; + for (MenuItemList::iterator MenuItem = Items.begin(); MenuItem != Items.end(); MenuItem++) + { + ItemID = MenuItem->ID(); + uFlags = MF_STRING; + Text = wGS(MenuItem->Title()); + + if (MenuItem->Title() == EMPTY_STRING && MenuItem->ManualString().length() > 0) + { + Text = MenuItem->ManualString(); + } + if (ItemID == SPLITER) + { + uFlags |= MF_SEPARATOR; + } + if (MenuItem->ItemTicked()) + { + uFlags |= MFS_CHECKED; + } + if (MenuItem->ItemEnabled()) + { + uFlags |= MFS_ENABLED; + } + else + { + uFlags |= MFS_DISABLED; + } + + MenuItemList * SubMenu = (MenuItemList *)MenuItem->SubMenu(); + if (ItemID == SUB_MENU && HIWORD(SubMenu) != 0 && (SubMenu->begin() != SubMenu->end())) + { + ItemID = (UINT)CreatePopupMenu(); + uFlags |= MF_POPUP; + + AddMenu((HMENU)ItemID, *SubMenu); + } + + if (ItemID == ID_PLUGIN_MENU) + { + ItemID = (UINT)MenuItem->SubMenu(); + uFlags |= MF_POPUP; + MENUITEMINFO lpmii; + + lpmii.cbSize = sizeof(MENUITEMINFO); + lpmii.fMask = MIIM_STATE; + lpmii.fState = 0; + SetMenuItemInfo((HMENU)ItemID, (DWORD)MenuItem->SubMenu(), FALSE, &lpmii); + } + + if (MenuItem->ShortCut().empty() == false) + { + String = Text; + String += L"\t"; + String += MenuItem->ShortCut(); + Text = String; + } + AppendMenuW(hMenu, uFlags, ItemID, Text.c_str()); + } + return true; } \ No newline at end of file diff --git a/Source/Project64/UserInterface/MenuClass.h b/Source/Project64/UserInterface/MenuClass.h index fc0e4a3d6..2500ac193 100644 --- a/Source/Project64/UserInterface/MenuClass.h +++ b/Source/Project64/UserInterface/MenuClass.h @@ -1,85 +1,85 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -enum Menu_ID -{ - //ControlID - SPLITER, SUB_MENU, NO_ID, ID_PLUGIN_MENU, -}; - -const std::wstring EMPTY_STDSTR = L""; - -class MENU_ITEM -{ -public: - MENU_ITEM (void) - { - Reset(NO_ID); - } - MENU_ITEM ( int ID, LanguageStringID Title = EMPTY_STRING, const std::wstring & ShortCut = EMPTY_STDSTR, - void * SubMenu = NULL, const std::wstring & ManualString = EMPTY_STDSTR) - { - Reset(ID,Title,ShortCut,SubMenu,ManualString); - } - void Reset ( int ID, LanguageStringID Title = EMPTY_STRING, const std::wstring & ShortCut2 = EMPTY_STDSTR, - void * SubMenu = NULL, const std::wstring & ManualString = EMPTY_STDSTR) - { - this->m_ID = ID; - this->m_Title = Title; - this->m_ShortCut = ShortCut2; - this->m_SubMenu = SubMenu; - this->m_ManualString = ManualString; - this->m_ItemTicked = false; - this->m_ItemEnabled = true; - } - - int ID() const { return m_ID; } - LanguageStringID Title() const { return m_Title; } - const std::wstring & ShortCut() const { return m_ShortCut; } - void * SubMenu() const { return m_SubMenu; } - const std::wstring & ManualString() const { return m_ManualString; } - bool ItemTicked() const { return m_ItemTicked; } - bool ItemEnabled() const { return m_ItemEnabled; } - - void SetItemTicked(bool ItemTicked) { m_ItemTicked = ItemTicked; } - void SetItemEnabled(bool ItemEnabled) { m_ItemEnabled = ItemEnabled; } - - -private: - int m_ID; - LanguageStringID m_Title; - std::wstring m_ShortCut; - void * m_SubMenu; - std::wstring m_ManualString; - bool m_ItemTicked; - bool m_ItemEnabled; -}; - -typedef std::list MenuItemList; - -class CBaseMenu { -protected: - HMENU m_MenuHandle; - - bool AddMenu ( HMENU hMenu, MenuItemList Items ); - -public: - CBaseMenu (); - - - virtual int ProcessAccelerator(HWND hWnd, void * lpMsg ) = 0; // pure virtual draw() function - virtual bool ProcessMessage(HWND hWnd, DWORD wNotifyCode, DWORD wID) = 0; // pure virtual draw() function - virtual void ResetMenu(void) = 0; // pure virtual draw() function - HMENU GetHandle (void) { return m_MenuHandle; } -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +enum Menu_ID +{ + //ControlID + SPLITER, SUB_MENU, NO_ID, ID_PLUGIN_MENU, +}; + +const std::wstring EMPTY_STDSTR = L""; + +class MENU_ITEM +{ +public: + MENU_ITEM (void) + { + Reset(NO_ID); + } + MENU_ITEM ( int ID, LanguageStringID Title = EMPTY_STRING, const std::wstring & ShortCut = EMPTY_STDSTR, + void * SubMenu = NULL, const std::wstring & ManualString = EMPTY_STDSTR) + { + Reset(ID,Title,ShortCut,SubMenu,ManualString); + } + void Reset ( int ID, LanguageStringID Title = EMPTY_STRING, const std::wstring & ShortCut2 = EMPTY_STDSTR, + void * SubMenu = NULL, const std::wstring & ManualString = EMPTY_STDSTR) + { + this->m_ID = ID; + this->m_Title = Title; + this->m_ShortCut = ShortCut2; + this->m_SubMenu = SubMenu; + this->m_ManualString = ManualString; + this->m_ItemTicked = false; + this->m_ItemEnabled = true; + } + + int ID() const { return m_ID; } + LanguageStringID Title() const { return m_Title; } + const std::wstring & ShortCut() const { return m_ShortCut; } + void * SubMenu() const { return m_SubMenu; } + const std::wstring & ManualString() const { return m_ManualString; } + bool ItemTicked() const { return m_ItemTicked; } + bool ItemEnabled() const { return m_ItemEnabled; } + + void SetItemTicked(bool ItemTicked) { m_ItemTicked = ItemTicked; } + void SetItemEnabled(bool ItemEnabled) { m_ItemEnabled = ItemEnabled; } + + +private: + int m_ID; + LanguageStringID m_Title; + std::wstring m_ShortCut; + void * m_SubMenu; + std::wstring m_ManualString; + bool m_ItemTicked; + bool m_ItemEnabled; +}; + +typedef std::list MenuItemList; + +class CBaseMenu { +protected: + HMENU m_MenuHandle; + + bool AddMenu ( HMENU hMenu, MenuItemList Items ); + +public: + CBaseMenu (); + + + virtual int ProcessAccelerator(HWND hWnd, void * lpMsg ) = 0; // pure virtual draw() function + virtual bool ProcessMessage(HWND hWnd, DWORD wNotifyCode, DWORD wID) = 0; // pure virtual draw() function + virtual void ResetMenu(void) = 0; // pure virtual draw() function + HMENU GetHandle (void) { return m_MenuHandle; } +}; diff --git a/Source/Project64/UserInterface/MenuShortCuts.cpp b/Source/Project64/UserInterface/MenuShortCuts.cpp index 989ffd905..e76dd6665 100644 --- a/Source/Project64/UserInterface/MenuShortCuts.cpp +++ b/Source/Project64/UserInterface/MenuShortCuts.cpp @@ -1,504 +1,504 @@ -#include "stdafx.h" - -VIRTUAL_KEY CMenuShortCutKey::m_VirtualKeyList[] = { - { "VK_LBUTTON", 0x01, "VK_LBUTTON" }, - { "VK_RBUTTON", 0x02, "VK_RBUTTON" }, - { "VK_CANCEL", 0x03, "VK_CANCEL" }, - { "VK_MBUTTON", 0x04, "VK_MBUTTON" }, - { "VK_XBUTTON1", 0x05, "VK_XBUTTON1" }, - { "VK_XBUTTON2", 0x06, "VK_XBUTTON2" }, - { "VK_BACK", 0x08, "VK_BACK" }, - { "VK_TAB", 0x09, "VK_TAB" }, - { "VK_CLEAR", 0x0C, "VK_CLEAR" }, - { "VK_RETURN", 0x0D, "Return" }, - { "VK_SHIFT", 0x10, "VK_SHIFT" }, - { "VK_CONTROL", 0x11, "VK_CONTROL" }, - { "VK_MENU", 0x12, "VK_MENU" }, - { "VK_PAUSE", 0x13, "Pause" }, - { "VK_CAPITAL", 0x14, "VK_CAPITAL" }, - { "VK_KANA", 0x15, "VK_KANA" }, - { "VK_HANGUL", 0x15, "VK_HANGUL" }, - { "VK_JUNJA", 0x17, "VK_JUNJA" }, - { "VK_FINAL", 0x18, "VK_FINAL" }, - { "VK_HANJA", 0x19, "VK_HANJA" }, - { "VK_KANJI", 0x19, "VK_KANJI" }, - { "VK_ESCAPE", 0x1B, "Esc" }, - { "VK_CONVERT", 0x1C, "VK_CONVERT" }, - { "VK_NONCONVERT", 0x1D, "VK_NONCONVERT" }, - { "VK_ACCEPT", 0x1E, "VK_ACCEPT" }, - { "VK_MODECHANGE", 0x1F, "VK_MODECHANGE" }, - { "VK_SPACE", 0x20, "Space" }, - { "VK_PRIOR", 0x21, "Page Up" }, - { "VK_NEXT", 0x22, "Page Down" }, - { "VK_END", 0x23, "End" }, - { "VK_HOME", 0x24, "Home" }, - { "VK_LEFT", 0x25, "Left" }, - { "VK_UP", 0x26, "Up" }, - { "VK_RIGHT", 0x27, "Right" }, - { "VK_DOWN", 0x28, "Down" }, - { "VK_SELECT", 0x29, "VK_SELECT" }, - { "VK_PRINT", 0x2A, "VK_PRINT" }, - { "VK_EXECUTE", 0x2B, "VK_EXECUTE" }, - { "VK_SNAPSHOT", 0x2C, "VK_SNAPSHOT" }, - { "VK_INSERT", 0x2D, "Insert" }, - { "VK_DELETE", 0x2E, "Delete" }, - { "VK_HELP", 0x2F, "Help" }, - { "VK_0", 0x30, "0" }, - { "VK_1", 0x31, "1" }, - { "VK_2", 0x32, "2" }, - { "VK_3", 0x33, "3" }, - { "VK_4", 0x34, "4" }, - { "VK_5", 0x35, "5" }, - { "VK_6", 0x36, "6" }, - { "VK_7", 0x37, "7" }, - { "VK_8", 0x38, "8" }, - { "VK_9", 0x39, "9" }, - { "VK_A", 0x41, "A" }, - { "VK_B", 0x42, "B" }, - { "VK_C", 0x43, "C" }, - { "VK_D", 0x44, "D" }, - { "VK_E", 0x45, "E" }, - { "VK_F", 0x46, "F" }, - { "VK_G", 0x47, "G" }, - { "VK_H", 0x48, "H" }, - { "VK_I", 0x49, "I" }, - { "VK_J", 0x4A, "J" }, - { "VK_K", 0x4B, "K" }, - { "VK_L", 0x4C, "L" }, - { "VK_M", 0x4D, "M" }, - { "VK_N", 0x4E, "N" }, - { "VK_O", 0x4F, "O" }, - { "VK_P", 0x50, "P" }, - { "VK_Q", 0x51, "Q" }, - { "VK_R", 0x52, "R" }, - { "VK_S", 0x53, "S" }, - { "VK_T", 0x54, "T" }, - { "VK_U", 0x55, "U" }, - { "VK_V", 0x56, "V" }, - { "VK_W", 0x57, "W" }, - { "VK_X", 0x58, "X" }, - { "VK_Y", 0x59, "Y" }, - { "VK_Z", 0x5A, "Z" }, - { "VK_LWIN", 0x5B, "VK_LWIN" }, - { "VK_RWIN", 0x5C, "VK_RWIN" }, - { "VK_APPS", 0x5D, "VK_APPS" }, - { "VK_SLEEP", 0x5D, "VK_SLEEP" }, - { "VK_NUMPAD0", 0x60, "Numpad0" }, - { "VK_NUMPAD1", 0x61, "Numpad1" }, - { "VK_NUMPAD2", 0x62, "Numpad2" }, - { "VK_NUMPAD3", 0x63, "Numpad3" }, - { "VK_NUMPAD4", 0x64, "Numpad4" }, - { "VK_NUMPAD5", 0x65, "Numpad5" }, - { "VK_NUMPAD6", 0x66, "Numpad6" }, - { "VK_NUMPAD7", 0x67, "Numpad7" }, - { "VK_NUMPAD8", 0x68, "Numpad8" }, - { "VK_NUMPAD9", 0x69, "Numpad9" }, - { "VK_MULTIPLY", 0x6A, "*" }, - { "VK_ADD", 0x6B, "+" }, - { "VK_SEPARATOR", 0x6C, "" }, - { "VK_SUBTRACT", 0x6D, "-" }, - { "VK_DECIMAL", 0x6E, "." }, - { "VK_DIVIDE", 0x6F, "/" }, - { "VK_F1", 0x70, "F1" }, - { "VK_F2", 0x71, "F2" }, - { "VK_F3", 0x72, "F3" }, - { "VK_F4", 0x73, "F4" }, - { "VK_F5", 0x74, "F5" }, - { "VK_F6", 0x75, "F6" }, - { "VK_F7", 0x76, "F7" }, - { "VK_F8", 0x77, "F8" }, - { "VK_F9", 0x78, "F9" }, - { "VK_F10", 0x79, "F10" }, - { "VK_F11", 0x7A, "F11" }, - { "VK_F12", 0x7B, "F12" }, - { "VK_F13", 0x7C, "F13" }, - { "VK_F14", 0x7D, "F14" }, - { "VK_F15", 0x7E, "F15" }, - { "VK_F16", 0x7F, "F16" }, - { "VK_F17", 0x80, "F17" }, - { "VK_F18", 0x81, "F18" }, - { "VK_F19", 0x82, "F19" }, - { "VK_F20", 0x83, "F20" }, - { "VK_F21", 0x84, "F21" }, - { "VK_F22", 0x85, "F22" }, - { "VK_F23", 0x86, "F23" }, - { "VK_F24", 0x87, "F24" }, - { "VK_NUMLOCK", 0x90, "Numlock" }, - { "VK_SCROLL", 0x91, "VK_SCROLL" }, - { "VK_LSHIFT", 0xA0, "VK_LSHIFT" }, - { "VK_RSHIFT", 0xA1, "VK_RSHIFT" }, - { "VK_LCONTROL", 0xA2, "VK_LCONTROL" }, - { "VK_RCONTROL", 0xA3, "VK_RCONTROL" }, - { "VK_LMENU", 0xA4, "VK_LMENU" }, - { "VK_RMENU", 0xA5, "VK_RMENU" }, - { "VK_BROWSER_BACK", 0xA6, "" }, - { "VK_BROWSER_FORWARD", 0xA7, "" }, - { "VK_BROWSER_REFRESH", 0xA8, "" }, - { "VK_BROWSER_STOP", 0xA9, "" }, - { "VK_BROWSER_SEARCH", 0xAA, "" }, - { "VK_BROWSER_FAVORITES", 0xAB, "" }, - { "VK_BROWSER_HOME", 0xAC, "" }, - { "VK_VOLUME_MUTE", 0xAD, "" }, - { "VK_VOLUME_DOWN", 0xAE, "" }, - { "VK_VOLUME_UP", 0xAF, "" }, - { "VK_MEDIA_NEXT_TRACK", 0xB0, "" }, - { "VK_MEDIA_PREV_TRACK", 0xB1, "" }, - { "VK_MEDIA_STOP", 0xB2, "" }, - { "VK_MEDIA_PLAY_PAUSE", 0xB3, "" }, - { "VK_LAUNCH_MAIL", 0xB4, "" }, - { "VK_LAUNCH_MEDIA_SELECT", 0xB5, "" }, - { "VK_LAUNCH_APP1", 0xB6, "" }, - { "VK_LAUNCH_APP2", 0xB7, "" }, - { "VK_OEM_1 (;:)", 0xBA, "" }, - { "VK_OEM_PLUS", 0xBB, "+" }, - { "VK_OEM_COMMA", 0xBC, "" }, - { "VK_OEM_MINUS", 0xBD, "-" }, - { "VK_OEM_PERIOD", 0xBE, "." }, - { "VK_OEM_2 (/?)", 0xBF, "" }, - { "VK_OEM_3 (`~)", 0xC0, "~" }, - { "VK_ATTN", 0xF6, "" }, - { "VK_CRSEL", 0xF7, "" }, - { "VK_EXSEL", 0xF8, "" }, - { "VK_EREOF", 0xF9, "" }, - { "VK_PLAY", 0xFA, "" }, - { "VK_ZOOM", 0xFB, "" }, - { "VK_NONAME", 0xFC, "" }, - { "VK_PA1", 0xFD, "" }, - { "VK_OEM_CLEAR", 0xFE } -}; - -CMenuShortCutKey::CMenuShortCutKey(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive) : -m_key(key), -m_bCtrl(bCtrl), -m_bAlt(bAlt), -m_bShift(bShift), -m_AccessMode(AccessMode), -m_bUserAdded(bUserAdded), -m_bInactive(bInactive) -{ - m_ShortCutName = ""; - for (int i = 0, n = sizeof(m_VirtualKeyList) / sizeof(m_VirtualKeyList[0]); i < n; i++) - { - if (key == m_VirtualKeyList[i].Key) - { - m_ShortCutName = m_VirtualKeyList[i].KeyName; - break; - } - } - if (m_bShift) { m_ShortCutName.Format("Shift+%s", m_ShortCutName.c_str()); } - if (m_bCtrl) { m_ShortCutName.Format("Ctrl+%s", m_ShortCutName.c_str()); } - if (m_bAlt) { m_ShortCutName.Format("Alt+%s", m_ShortCutName.c_str()); } -} - -VIRTUAL_KEY * CMenuShortCutKey::VirtualKeyList(int &Size) -{ - Size = sizeof(m_VirtualKeyList) / sizeof(m_VirtualKeyList[0]); - return (VIRTUAL_KEY *)m_VirtualKeyList; -} - -bool CMenuShortCutKey::Same(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode) const -{ - if (key != m_key) { return false; } - if (bShift != m_bShift) { return false; } - if (bCtrl != m_bCtrl) { return false; } - if (bAlt != m_bAlt) { return false; } - if ((m_AccessMode & AccessMode) != AccessMode) { return false; } - return true; -} - -CShortCutItem::CShortCutItem(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access) -{ - Reset(Section, Title, Access); -} - -void CShortCutItem::Reset(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access) -{ - this->m_Section = Section; - this->m_Title = Title; - this->m_Access = Access; -} - -void CShortCutItem::AddShortCut(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive) -{ - m_AccelList.push_back(CMenuShortCutKey(key, bCtrl, bAlt, bShift, AccessMode, bUserAdded, bInactive)); -} - -void CShortCutItem::RemoveItem(CMenuShortCutKey * ShortCut) -{ - if (ShortCut->UserAdded()) - { - for (SHORTCUT_KEY_LIST::iterator item = m_AccelList.begin(); item != m_AccelList.end(); item++) - { - if (ShortCut == &*item) - { - m_AccelList.erase(item); - break; - } - } - } - else - { - ShortCut->SetInactive(true); - } -} - -CShortCuts::CShortCuts() -{ - Load(); -} - -CShortCuts::~CShortCuts() -{ -} - -std::wstring CShortCuts::ShortCutString(int MenuID, CMenuShortCutKey::ACCESS_MODE AccessLevel) -{ - CGuard CS(m_CS); - - MSC_MAP::iterator MenuItem = m_ShortCuts.find(MenuID); - if (MenuItem == m_ShortCuts.end()) { return L""; } - - const SHORTCUT_KEY_LIST & ShortCutList = MenuItem->second.GetAccelItems(); - for (SHORTCUT_KEY_LIST::const_iterator item = ShortCutList.begin(); item != ShortCutList.end(); item++) - { - ACCESS_MODE ItemMode = item->AccessMode(); - if ((ItemMode & AccessLevel) != AccessLevel) - { - continue; - } - if (item->Inactive()) - { - continue; - } - return item->Name().ToUTF16(); - } - return L""; -} - -LanguageStringID CShortCuts::GetMenuItemName(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE Access) -{ - CGuard CS(m_CS); - - for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) - { - CShortCutItem & short_cut = Item->second; - - for (SHORTCUT_KEY_LIST::const_iterator AccelItem = short_cut.GetAccelItems().begin(); AccelItem != short_cut.GetAccelItems().end(); AccelItem++) - { - if (!AccelItem->Same(key, bCtrl, bAlt, bShift, Access)) { continue; } - return short_cut.Title(); - } - } - return EMPTY_STRING; -} - -void CShortCuts::AddShortCut(WORD ID, LanguageStringID Section, LanguageStringID LangID, CMenuShortCutKey::ACCESS_MODE AccessMode) -{ - m_ShortCuts.insert(MSC_MAP::value_type(ID, CShortCutItem(Section, LangID, AccessMode))); -} - -void CShortCuts::Load(bool InitialValues) -{ - CGuard CS(m_CS); - - m_ShortCuts.clear(); - - AddShortCut(ID_FILE_OPEN_ROM, STR_SHORTCUT_FILEMENU, MENU_OPEN, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_FILE_ROM_INFO, STR_SHORTCUT_FILEMENU, MENU_ROM_INFO, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_FILE_STARTEMULATION, STR_SHORTCUT_FILEMENU, MENU_START, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_FILE_ENDEMULATION, STR_SHORTCUT_FILEMENU, MENU_END, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_FILE_ROMDIRECTORY, STR_SHORTCUT_FILEMENU, MENU_CHOOSE_ROM, CMenuShortCutKey::GAME_NOT_RUNNING); - AddShortCut(ID_FILE_REFRESHROMLIST, STR_SHORTCUT_FILEMENU, MENU_REFRESH, CMenuShortCutKey::GAME_NOT_RUNNING); - AddShortCut(ID_FILE_EXIT, STR_SHORTCUT_FILEMENU, MENU_EXIT, CMenuShortCutKey::ANYTIME); - - AddShortCut(ID_SYSTEM_RESET_SOFT, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_SOFT, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_SYSTEM_RESET_HARD, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_HARD, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_SYSTEM_PAUSE, STR_SHORTCUT_SYSTEMMENU, MENU_PAUSE, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_SYSTEM_BITMAP, STR_SHORTCUT_SYSTEMMENU, MENU_BITMAP, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_SYSTEM_LIMITFPS, STR_SHORTCUT_SYSTEMMENU, MENU_LIMIT_FPS, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_SYSTEM_SAVE, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_SYSTEM_SAVEAS, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE_AS, CMenuShortCutKey::GAME_RUNNING_WINDOW); - AddShortCut(ID_SYSTEM_RESTORE, STR_SHORTCUT_SYSTEMMENU, MENU_RESTORE, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_SYSTEM_LOAD, STR_SHORTCUT_SYSTEMMENU, MENU_LOAD, CMenuShortCutKey::GAME_RUNNING_WINDOW); - AddShortCut(ID_SYSTEM_CHEAT, STR_SHORTCUT_SYSTEMMENU, MENU_CHEAT, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_SYSTEM_GSBUTTON, STR_SHORTCUT_SYSTEMMENU, MENU_GS_BUTTON, CMenuShortCutKey::GAME_RUNNING); - - AddShortCut(ID_OPTIONS_DISPLAY_FR, STR_SHORTCUT_OPTIONS, OPTION_DISPLAY_FR, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_OPTIONS_CHANGE_FR, STR_SHORTCUT_OPTIONS, OPTION_CHANGE_FR, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_OPTIONS_INCREASE_SPEED, STR_SHORTCUT_OPTIONS, STR_INSREASE_SPEED, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_OPTIONS_DECREASE_SPEED, STR_SHORTCUT_OPTIONS, STR_DECREASE_SPEED, CMenuShortCutKey::GAME_RUNNING); - - AddShortCut(ID_CURRENT_SAVE_DEFAULT, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_DEFAULT, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_1, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_1, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_2, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_2, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_3, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_3, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_4, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_4, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_5, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_5, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_6, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_6, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_7, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_7, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_8, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_8, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_9, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_9, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_CURRENT_SAVE_10, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_10, CMenuShortCutKey::GAME_RUNNING); - - //Option Menu - AddShortCut(ID_OPTIONS_FULLSCREEN, STR_SHORTCUT_OPTIONS, MENU_FULL_SCREEN, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_OPTIONS_ALWAYSONTOP, STR_SHORTCUT_OPTIONS, MENU_ON_TOP, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_OPTIONS_CONFIG_GFX, STR_SHORTCUT_OPTIONS, MENU_CONFG_GFX, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_OPTIONS_CONFIG_AUDIO, STR_SHORTCUT_OPTIONS, MENU_CONFG_AUDIO, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_OPTIONS_CONFIG_CONT, STR_SHORTCUT_OPTIONS, MENU_CONFG_CTRL, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_OPTIONS_CONFIG_RSP, STR_SHORTCUT_OPTIONS, MENU_CONFG_RSP, CMenuShortCutKey::NOT_IN_FULLSCREEN); - AddShortCut(ID_OPTIONS_CPU_USAGE, STR_SHORTCUT_OPTIONS, MENU_SHOW_CPU, CMenuShortCutKey::GAME_RUNNING); - AddShortCut(ID_OPTIONS_SETTINGS, STR_SHORTCUT_OPTIONS, MENU_SETTINGS, CMenuShortCutKey::NOT_IN_FULLSCREEN); - - CPath ShortCutFile = g_Settings->LoadStringVal(SupportFile_ShortCuts); - if (!ShortCutFile.Exists() || InitialValues) - { - m_ShortCuts.find(ID_FILE_OPEN_ROM)->second.AddShortCut('O', TRUE, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_FILE_OPEN_ROM)->second.AddShortCut('O', TRUE, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); - m_ShortCuts.find(ID_FILE_STARTEMULATION)->second.AddShortCut(VK_F11, false, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); - m_ShortCuts.find(ID_FILE_ENDEMULATION)->second.AddShortCut(VK_F12, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_FILE_REFRESHROMLIST)->second.AddShortCut(VK_F5, false, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); - m_ShortCuts.find(ID_FILE_EXIT)->second.AddShortCut(VK_F4, false, true, false, CMenuShortCutKey::GAME_NOT_RUNNING); - m_ShortCuts.find(ID_FILE_EXIT)->second.AddShortCut(VK_F4, false, true, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_DEFAULT)->second.AddShortCut(0xC0, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_1)->second.AddShortCut('1', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_2)->second.AddShortCut('2', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_3)->second.AddShortCut('3', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_4)->second.AddShortCut('4', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_5)->second.AddShortCut('5', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_6)->second.AddShortCut('6', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_7)->second.AddShortCut('7', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_8)->second.AddShortCut('8', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_9)->second.AddShortCut('9', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_CURRENT_SAVE_10)->second.AddShortCut('0', false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_OPTIONS_FULLSCREEN)->second.AddShortCut(VK_RETURN, false, true, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_OPTIONS_FULLSCREEN)->second.AddShortCut(VK_ESCAPE, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_OPTIONS_ALWAYSONTOP)->second.AddShortCut('A', true, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); - m_ShortCuts.find(ID_OPTIONS_ALWAYSONTOP)->second.AddShortCut('A', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); - m_ShortCuts.find(ID_OPTIONS_SETTINGS)->second.AddShortCut('T', true, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); - m_ShortCuts.find(ID_OPTIONS_SETTINGS)->second.AddShortCut('T', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); - m_ShortCuts.find(ID_SYSTEM_RESET_SOFT)->second.AddShortCut(VK_F1, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_SYSTEM_RESET_HARD)->second.AddShortCut(VK_F1, false, false, true, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_F2, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_PAUSE, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_SYSTEM_BITMAP)->second.AddShortCut(VK_F3, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_SYSTEM_LIMITFPS)->second.AddShortCut(VK_F4, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_SYSTEM_SAVE)->second.AddShortCut(VK_F5, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_SYSTEM_RESTORE)->second.AddShortCut(VK_F7, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_SYSTEM_LOAD)->second.AddShortCut('L', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); - m_ShortCuts.find(ID_SYSTEM_SAVEAS)->second.AddShortCut('S', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); - m_ShortCuts.find(ID_SYSTEM_CHEAT)->second.AddShortCut('C', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); - m_ShortCuts.find(ID_SYSTEM_GSBUTTON)->second.AddShortCut(VK_F9, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_OPTIONS_INCREASE_SPEED)->second.AddShortCut(VK_OEM_PLUS, false, false, false, CMenuShortCutKey::GAME_RUNNING); - m_ShortCuts.find(ID_OPTIONS_DECREASE_SPEED)->second.AddShortCut(VK_OEM_MINUS, false, false, false, CMenuShortCutKey::GAME_RUNNING); - } - else - { - CMenuShortCutKey::ACCESS_MODE AccessMode; - int ID, key, bCtrl, bAlt, bShift, bUserAdded, bInactive; - - FILE *file = fopen(ShortCutFile, "r"); - if (file) - { - do - { - char Line[300]; - if (fgets(Line, sizeof(Line), file) != NULL) - { - sscanf(Line, "%d,%d,%d,%d,%d,%d,%d,%d", &ID, &key, &bCtrl, &bAlt, &bShift, &AccessMode, - &bUserAdded, &bInactive); - - MSC_MAP::iterator item = m_ShortCuts.find(ID); - if (item == m_ShortCuts.end()) { continue; } - item->second.AddShortCut((WORD)(key & 0xFFFF), bCtrl == 1, bAlt == 1, bShift == 1, AccessMode, bUserAdded == 1, bInactive == 1); - } - } while (feof(file) == 0); - fclose(file); - } - } -} - -void CShortCuts::Save(void) -{ - CGuard CS(m_CS); - - stdstr FileName = g_Settings->LoadStringVal(SupportFile_ShortCuts); - FILE *file = fopen(FileName.c_str(), "w"); - if (file == NULL) - { - return; - } - - for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) - { - for (SHORTCUT_KEY_LIST::const_iterator ShortCut = Item->second.GetAccelItems().begin(); ShortCut != Item->second.GetAccelItems().end(); ShortCut++) - { - fprintf(file, "%d,%d,%d,%d,%d,%d,%d,%d\n", - Item->first, - ShortCut->Key(), - ShortCut->Ctrl(), - ShortCut->Alt(), - ShortCut->Shift(), - ShortCut->AccessMode(), - ShortCut->UserAdded(), - ShortCut->Inactive()); - } - } - fclose(file); -} - -HACCEL CShortCuts::GetAcceleratorTable(void) -{ - CGuard CS(m_CS); - - //Generate a ACCEL list - CMenuShortCutKey::ACCESS_MODE AccessLevel = CMenuShortCutKey::GAME_NOT_RUNNING; - if (g_Settings->LoadBool(GameRunning_CPU_Running)) - { - AccessLevel = g_Settings->LoadBool(UserInterface_InFullScreen) ? - CMenuShortCutKey::GAME_RUNNING_FULLSCREEN : - CMenuShortCutKey::GAME_RUNNING_WINDOW; - } - - int size = 0, MaxSize = m_ShortCuts.size() * 5; - ACCEL * AccelList = new ACCEL[MaxSize]; - - for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) - { - CShortCutItem & short_cut = Item->second; - - CMenuShortCutKey::ACCESS_MODE ItemMode = short_cut.AccessMode(); - if ((ItemMode & AccessLevel) != AccessLevel) - { - continue; - } - - SHORTCUT_KEY_LIST ShortCutAccelList = short_cut.GetAccelItems(); - for (SHORTCUT_KEY_LIST::iterator AccelIter = ShortCutAccelList.begin(); AccelIter != ShortCutAccelList.end(); AccelIter++) - { - CMenuShortCutKey & Key = *AccelIter; - if (Key.Inactive()) - { - continue; - } - if ((Key.AccessMode() & AccessLevel) != AccessLevel) - { - continue; - } - if (size >= MaxSize) { break; } - AccelList[size].cmd = (WORD)Item->first; - AccelList[size].key = Key.Key(); - AccelList[size].fVirt = FVIRTKEY; - if (Key.Alt()) { AccelList[size].fVirt |= FALT; } - if (Key.Ctrl()) { AccelList[size].fVirt |= FCONTROL; } - if (Key.Shift()) { AccelList[size].fVirt |= FSHIFT; } - size += 1; - } - } - - WriteTrace(TraceUserInterface, TraceDebug, "CreateAcceleratorTable"); - HACCEL AccelTable = CreateAcceleratorTable(AccelList, size); - WriteTrace(TraceUserInterface, TraceDebug, "Delete accel list"); - delete[] AccelList; - return AccelTable; +#include "stdafx.h" + +VIRTUAL_KEY CMenuShortCutKey::m_VirtualKeyList[] = { + { "VK_LBUTTON", 0x01, "VK_LBUTTON" }, + { "VK_RBUTTON", 0x02, "VK_RBUTTON" }, + { "VK_CANCEL", 0x03, "VK_CANCEL" }, + { "VK_MBUTTON", 0x04, "VK_MBUTTON" }, + { "VK_XBUTTON1", 0x05, "VK_XBUTTON1" }, + { "VK_XBUTTON2", 0x06, "VK_XBUTTON2" }, + { "VK_BACK", 0x08, "VK_BACK" }, + { "VK_TAB", 0x09, "VK_TAB" }, + { "VK_CLEAR", 0x0C, "VK_CLEAR" }, + { "VK_RETURN", 0x0D, "Return" }, + { "VK_SHIFT", 0x10, "VK_SHIFT" }, + { "VK_CONTROL", 0x11, "VK_CONTROL" }, + { "VK_MENU", 0x12, "VK_MENU" }, + { "VK_PAUSE", 0x13, "Pause" }, + { "VK_CAPITAL", 0x14, "VK_CAPITAL" }, + { "VK_KANA", 0x15, "VK_KANA" }, + { "VK_HANGUL", 0x15, "VK_HANGUL" }, + { "VK_JUNJA", 0x17, "VK_JUNJA" }, + { "VK_FINAL", 0x18, "VK_FINAL" }, + { "VK_HANJA", 0x19, "VK_HANJA" }, + { "VK_KANJI", 0x19, "VK_KANJI" }, + { "VK_ESCAPE", 0x1B, "Esc" }, + { "VK_CONVERT", 0x1C, "VK_CONVERT" }, + { "VK_NONCONVERT", 0x1D, "VK_NONCONVERT" }, + { "VK_ACCEPT", 0x1E, "VK_ACCEPT" }, + { "VK_MODECHANGE", 0x1F, "VK_MODECHANGE" }, + { "VK_SPACE", 0x20, "Space" }, + { "VK_PRIOR", 0x21, "Page Up" }, + { "VK_NEXT", 0x22, "Page Down" }, + { "VK_END", 0x23, "End" }, + { "VK_HOME", 0x24, "Home" }, + { "VK_LEFT", 0x25, "Left" }, + { "VK_UP", 0x26, "Up" }, + { "VK_RIGHT", 0x27, "Right" }, + { "VK_DOWN", 0x28, "Down" }, + { "VK_SELECT", 0x29, "VK_SELECT" }, + { "VK_PRINT", 0x2A, "VK_PRINT" }, + { "VK_EXECUTE", 0x2B, "VK_EXECUTE" }, + { "VK_SNAPSHOT", 0x2C, "VK_SNAPSHOT" }, + { "VK_INSERT", 0x2D, "Insert" }, + { "VK_DELETE", 0x2E, "Delete" }, + { "VK_HELP", 0x2F, "Help" }, + { "VK_0", 0x30, "0" }, + { "VK_1", 0x31, "1" }, + { "VK_2", 0x32, "2" }, + { "VK_3", 0x33, "3" }, + { "VK_4", 0x34, "4" }, + { "VK_5", 0x35, "5" }, + { "VK_6", 0x36, "6" }, + { "VK_7", 0x37, "7" }, + { "VK_8", 0x38, "8" }, + { "VK_9", 0x39, "9" }, + { "VK_A", 0x41, "A" }, + { "VK_B", 0x42, "B" }, + { "VK_C", 0x43, "C" }, + { "VK_D", 0x44, "D" }, + { "VK_E", 0x45, "E" }, + { "VK_F", 0x46, "F" }, + { "VK_G", 0x47, "G" }, + { "VK_H", 0x48, "H" }, + { "VK_I", 0x49, "I" }, + { "VK_J", 0x4A, "J" }, + { "VK_K", 0x4B, "K" }, + { "VK_L", 0x4C, "L" }, + { "VK_M", 0x4D, "M" }, + { "VK_N", 0x4E, "N" }, + { "VK_O", 0x4F, "O" }, + { "VK_P", 0x50, "P" }, + { "VK_Q", 0x51, "Q" }, + { "VK_R", 0x52, "R" }, + { "VK_S", 0x53, "S" }, + { "VK_T", 0x54, "T" }, + { "VK_U", 0x55, "U" }, + { "VK_V", 0x56, "V" }, + { "VK_W", 0x57, "W" }, + { "VK_X", 0x58, "X" }, + { "VK_Y", 0x59, "Y" }, + { "VK_Z", 0x5A, "Z" }, + { "VK_LWIN", 0x5B, "VK_LWIN" }, + { "VK_RWIN", 0x5C, "VK_RWIN" }, + { "VK_APPS", 0x5D, "VK_APPS" }, + { "VK_SLEEP", 0x5D, "VK_SLEEP" }, + { "VK_NUMPAD0", 0x60, "Numpad0" }, + { "VK_NUMPAD1", 0x61, "Numpad1" }, + { "VK_NUMPAD2", 0x62, "Numpad2" }, + { "VK_NUMPAD3", 0x63, "Numpad3" }, + { "VK_NUMPAD4", 0x64, "Numpad4" }, + { "VK_NUMPAD5", 0x65, "Numpad5" }, + { "VK_NUMPAD6", 0x66, "Numpad6" }, + { "VK_NUMPAD7", 0x67, "Numpad7" }, + { "VK_NUMPAD8", 0x68, "Numpad8" }, + { "VK_NUMPAD9", 0x69, "Numpad9" }, + { "VK_MULTIPLY", 0x6A, "*" }, + { "VK_ADD", 0x6B, "+" }, + { "VK_SEPARATOR", 0x6C, "" }, + { "VK_SUBTRACT", 0x6D, "-" }, + { "VK_DECIMAL", 0x6E, "." }, + { "VK_DIVIDE", 0x6F, "/" }, + { "VK_F1", 0x70, "F1" }, + { "VK_F2", 0x71, "F2" }, + { "VK_F3", 0x72, "F3" }, + { "VK_F4", 0x73, "F4" }, + { "VK_F5", 0x74, "F5" }, + { "VK_F6", 0x75, "F6" }, + { "VK_F7", 0x76, "F7" }, + { "VK_F8", 0x77, "F8" }, + { "VK_F9", 0x78, "F9" }, + { "VK_F10", 0x79, "F10" }, + { "VK_F11", 0x7A, "F11" }, + { "VK_F12", 0x7B, "F12" }, + { "VK_F13", 0x7C, "F13" }, + { "VK_F14", 0x7D, "F14" }, + { "VK_F15", 0x7E, "F15" }, + { "VK_F16", 0x7F, "F16" }, + { "VK_F17", 0x80, "F17" }, + { "VK_F18", 0x81, "F18" }, + { "VK_F19", 0x82, "F19" }, + { "VK_F20", 0x83, "F20" }, + { "VK_F21", 0x84, "F21" }, + { "VK_F22", 0x85, "F22" }, + { "VK_F23", 0x86, "F23" }, + { "VK_F24", 0x87, "F24" }, + { "VK_NUMLOCK", 0x90, "Numlock" }, + { "VK_SCROLL", 0x91, "VK_SCROLL" }, + { "VK_LSHIFT", 0xA0, "VK_LSHIFT" }, + { "VK_RSHIFT", 0xA1, "VK_RSHIFT" }, + { "VK_LCONTROL", 0xA2, "VK_LCONTROL" }, + { "VK_RCONTROL", 0xA3, "VK_RCONTROL" }, + { "VK_LMENU", 0xA4, "VK_LMENU" }, + { "VK_RMENU", 0xA5, "VK_RMENU" }, + { "VK_BROWSER_BACK", 0xA6, "" }, + { "VK_BROWSER_FORWARD", 0xA7, "" }, + { "VK_BROWSER_REFRESH", 0xA8, "" }, + { "VK_BROWSER_STOP", 0xA9, "" }, + { "VK_BROWSER_SEARCH", 0xAA, "" }, + { "VK_BROWSER_FAVORITES", 0xAB, "" }, + { "VK_BROWSER_HOME", 0xAC, "" }, + { "VK_VOLUME_MUTE", 0xAD, "" }, + { "VK_VOLUME_DOWN", 0xAE, "" }, + { "VK_VOLUME_UP", 0xAF, "" }, + { "VK_MEDIA_NEXT_TRACK", 0xB0, "" }, + { "VK_MEDIA_PREV_TRACK", 0xB1, "" }, + { "VK_MEDIA_STOP", 0xB2, "" }, + { "VK_MEDIA_PLAY_PAUSE", 0xB3, "" }, + { "VK_LAUNCH_MAIL", 0xB4, "" }, + { "VK_LAUNCH_MEDIA_SELECT", 0xB5, "" }, + { "VK_LAUNCH_APP1", 0xB6, "" }, + { "VK_LAUNCH_APP2", 0xB7, "" }, + { "VK_OEM_1 (;:)", 0xBA, "" }, + { "VK_OEM_PLUS", 0xBB, "+" }, + { "VK_OEM_COMMA", 0xBC, "" }, + { "VK_OEM_MINUS", 0xBD, "-" }, + { "VK_OEM_PERIOD", 0xBE, "." }, + { "VK_OEM_2 (/?)", 0xBF, "" }, + { "VK_OEM_3 (`~)", 0xC0, "~" }, + { "VK_ATTN", 0xF6, "" }, + { "VK_CRSEL", 0xF7, "" }, + { "VK_EXSEL", 0xF8, "" }, + { "VK_EREOF", 0xF9, "" }, + { "VK_PLAY", 0xFA, "" }, + { "VK_ZOOM", 0xFB, "" }, + { "VK_NONAME", 0xFC, "" }, + { "VK_PA1", 0xFD, "" }, + { "VK_OEM_CLEAR", 0xFE } +}; + +CMenuShortCutKey::CMenuShortCutKey(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive) : +m_key(key), +m_bCtrl(bCtrl), +m_bAlt(bAlt), +m_bShift(bShift), +m_AccessMode(AccessMode), +m_bUserAdded(bUserAdded), +m_bInactive(bInactive) +{ + m_ShortCutName = ""; + for (int i = 0, n = sizeof(m_VirtualKeyList) / sizeof(m_VirtualKeyList[0]); i < n; i++) + { + if (key == m_VirtualKeyList[i].Key) + { + m_ShortCutName = m_VirtualKeyList[i].KeyName; + break; + } + } + if (m_bShift) { m_ShortCutName.Format("Shift+%s", m_ShortCutName.c_str()); } + if (m_bCtrl) { m_ShortCutName.Format("Ctrl+%s", m_ShortCutName.c_str()); } + if (m_bAlt) { m_ShortCutName.Format("Alt+%s", m_ShortCutName.c_str()); } +} + +VIRTUAL_KEY * CMenuShortCutKey::VirtualKeyList(int &Size) +{ + Size = sizeof(m_VirtualKeyList) / sizeof(m_VirtualKeyList[0]); + return (VIRTUAL_KEY *)m_VirtualKeyList; +} + +bool CMenuShortCutKey::Same(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode) const +{ + if (key != m_key) { return false; } + if (bShift != m_bShift) { return false; } + if (bCtrl != m_bCtrl) { return false; } + if (bAlt != m_bAlt) { return false; } + if ((m_AccessMode & AccessMode) != AccessMode) { return false; } + return true; +} + +CShortCutItem::CShortCutItem(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access) +{ + Reset(Section, Title, Access); +} + +void CShortCutItem::Reset(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access) +{ + this->m_Section = Section; + this->m_Title = Title; + this->m_Access = Access; +} + +void CShortCutItem::AddShortCut(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive) +{ + m_AccelList.push_back(CMenuShortCutKey(key, bCtrl, bAlt, bShift, AccessMode, bUserAdded, bInactive)); +} + +void CShortCutItem::RemoveItem(CMenuShortCutKey * ShortCut) +{ + if (ShortCut->UserAdded()) + { + for (SHORTCUT_KEY_LIST::iterator item = m_AccelList.begin(); item != m_AccelList.end(); item++) + { + if (ShortCut == &*item) + { + m_AccelList.erase(item); + break; + } + } + } + else + { + ShortCut->SetInactive(true); + } +} + +CShortCuts::CShortCuts() +{ + Load(); +} + +CShortCuts::~CShortCuts() +{ +} + +std::wstring CShortCuts::ShortCutString(int MenuID, CMenuShortCutKey::ACCESS_MODE AccessLevel) +{ + CGuard CS(m_CS); + + MSC_MAP::iterator MenuItem = m_ShortCuts.find(MenuID); + if (MenuItem == m_ShortCuts.end()) { return L""; } + + const SHORTCUT_KEY_LIST & ShortCutList = MenuItem->second.GetAccelItems(); + for (SHORTCUT_KEY_LIST::const_iterator item = ShortCutList.begin(); item != ShortCutList.end(); item++) + { + ACCESS_MODE ItemMode = item->AccessMode(); + if ((ItemMode & AccessLevel) != AccessLevel) + { + continue; + } + if (item->Inactive()) + { + continue; + } + return item->Name().ToUTF16(); + } + return L""; +} + +LanguageStringID CShortCuts::GetMenuItemName(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE Access) +{ + CGuard CS(m_CS); + + for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) + { + CShortCutItem & short_cut = Item->second; + + for (SHORTCUT_KEY_LIST::const_iterator AccelItem = short_cut.GetAccelItems().begin(); AccelItem != short_cut.GetAccelItems().end(); AccelItem++) + { + if (!AccelItem->Same(key, bCtrl, bAlt, bShift, Access)) { continue; } + return short_cut.Title(); + } + } + return EMPTY_STRING; +} + +void CShortCuts::AddShortCut(WORD ID, LanguageStringID Section, LanguageStringID LangID, CMenuShortCutKey::ACCESS_MODE AccessMode) +{ + m_ShortCuts.insert(MSC_MAP::value_type(ID, CShortCutItem(Section, LangID, AccessMode))); +} + +void CShortCuts::Load(bool InitialValues) +{ + CGuard CS(m_CS); + + m_ShortCuts.clear(); + + AddShortCut(ID_FILE_OPEN_ROM, STR_SHORTCUT_FILEMENU, MENU_OPEN, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_FILE_ROM_INFO, STR_SHORTCUT_FILEMENU, MENU_ROM_INFO, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_FILE_STARTEMULATION, STR_SHORTCUT_FILEMENU, MENU_START, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_FILE_ENDEMULATION, STR_SHORTCUT_FILEMENU, MENU_END, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_FILE_ROMDIRECTORY, STR_SHORTCUT_FILEMENU, MENU_CHOOSE_ROM, CMenuShortCutKey::GAME_NOT_RUNNING); + AddShortCut(ID_FILE_REFRESHROMLIST, STR_SHORTCUT_FILEMENU, MENU_REFRESH, CMenuShortCutKey::GAME_NOT_RUNNING); + AddShortCut(ID_FILE_EXIT, STR_SHORTCUT_FILEMENU, MENU_EXIT, CMenuShortCutKey::ANYTIME); + + AddShortCut(ID_SYSTEM_RESET_SOFT, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_SOFT, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_SYSTEM_RESET_HARD, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_HARD, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_SYSTEM_PAUSE, STR_SHORTCUT_SYSTEMMENU, MENU_PAUSE, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_SYSTEM_BITMAP, STR_SHORTCUT_SYSTEMMENU, MENU_BITMAP, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_SYSTEM_LIMITFPS, STR_SHORTCUT_SYSTEMMENU, MENU_LIMIT_FPS, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_SYSTEM_SAVE, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_SYSTEM_SAVEAS, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE_AS, CMenuShortCutKey::GAME_RUNNING_WINDOW); + AddShortCut(ID_SYSTEM_RESTORE, STR_SHORTCUT_SYSTEMMENU, MENU_RESTORE, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_SYSTEM_LOAD, STR_SHORTCUT_SYSTEMMENU, MENU_LOAD, CMenuShortCutKey::GAME_RUNNING_WINDOW); + AddShortCut(ID_SYSTEM_CHEAT, STR_SHORTCUT_SYSTEMMENU, MENU_CHEAT, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_SYSTEM_GSBUTTON, STR_SHORTCUT_SYSTEMMENU, MENU_GS_BUTTON, CMenuShortCutKey::GAME_RUNNING); + + AddShortCut(ID_OPTIONS_DISPLAY_FR, STR_SHORTCUT_OPTIONS, OPTION_DISPLAY_FR, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_OPTIONS_CHANGE_FR, STR_SHORTCUT_OPTIONS, OPTION_CHANGE_FR, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_OPTIONS_INCREASE_SPEED, STR_SHORTCUT_OPTIONS, STR_INSREASE_SPEED, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_OPTIONS_DECREASE_SPEED, STR_SHORTCUT_OPTIONS, STR_DECREASE_SPEED, CMenuShortCutKey::GAME_RUNNING); + + AddShortCut(ID_CURRENT_SAVE_DEFAULT, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_DEFAULT, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_1, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_1, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_2, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_2, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_3, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_3, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_4, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_4, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_5, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_5, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_6, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_6, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_7, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_7, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_8, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_8, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_9, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_9, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_CURRENT_SAVE_10, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_10, CMenuShortCutKey::GAME_RUNNING); + + //Option Menu + AddShortCut(ID_OPTIONS_FULLSCREEN, STR_SHORTCUT_OPTIONS, MENU_FULL_SCREEN, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_OPTIONS_ALWAYSONTOP, STR_SHORTCUT_OPTIONS, MENU_ON_TOP, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_OPTIONS_CONFIG_GFX, STR_SHORTCUT_OPTIONS, MENU_CONFG_GFX, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_OPTIONS_CONFIG_AUDIO, STR_SHORTCUT_OPTIONS, MENU_CONFG_AUDIO, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_OPTIONS_CONFIG_CONT, STR_SHORTCUT_OPTIONS, MENU_CONFG_CTRL, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_OPTIONS_CONFIG_RSP, STR_SHORTCUT_OPTIONS, MENU_CONFG_RSP, CMenuShortCutKey::NOT_IN_FULLSCREEN); + AddShortCut(ID_OPTIONS_CPU_USAGE, STR_SHORTCUT_OPTIONS, MENU_SHOW_CPU, CMenuShortCutKey::GAME_RUNNING); + AddShortCut(ID_OPTIONS_SETTINGS, STR_SHORTCUT_OPTIONS, MENU_SETTINGS, CMenuShortCutKey::NOT_IN_FULLSCREEN); + + CPath ShortCutFile = g_Settings->LoadStringVal(SupportFile_ShortCuts); + if (!ShortCutFile.Exists() || InitialValues) + { + m_ShortCuts.find(ID_FILE_OPEN_ROM)->second.AddShortCut('O', TRUE, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_FILE_OPEN_ROM)->second.AddShortCut('O', TRUE, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_FILE_STARTEMULATION)->second.AddShortCut(VK_F11, false, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_FILE_ENDEMULATION)->second.AddShortCut(VK_F12, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_FILE_REFRESHROMLIST)->second.AddShortCut(VK_F5, false, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_FILE_EXIT)->second.AddShortCut(VK_F4, false, true, false, CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_FILE_EXIT)->second.AddShortCut(VK_F4, false, true, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_DEFAULT)->second.AddShortCut(0xC0, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_1)->second.AddShortCut('1', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_2)->second.AddShortCut('2', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_3)->second.AddShortCut('3', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_4)->second.AddShortCut('4', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_5)->second.AddShortCut('5', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_6)->second.AddShortCut('6', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_7)->second.AddShortCut('7', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_8)->second.AddShortCut('8', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_9)->second.AddShortCut('9', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_10)->second.AddShortCut('0', false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_FULLSCREEN)->second.AddShortCut(VK_RETURN, false, true, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_FULLSCREEN)->second.AddShortCut(VK_ESCAPE, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_ALWAYSONTOP)->second.AddShortCut('A', true, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_OPTIONS_ALWAYSONTOP)->second.AddShortCut('A', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_OPTIONS_SETTINGS)->second.AddShortCut('T', true, false, false, CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_OPTIONS_SETTINGS)->second.AddShortCut('T', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_SYSTEM_RESET_SOFT)->second.AddShortCut(VK_F1, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_RESET_HARD)->second.AddShortCut(VK_F1, false, false, true, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_F2, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_PAUSE, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_BITMAP)->second.AddShortCut(VK_F3, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_LIMITFPS)->second.AddShortCut(VK_F4, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_SAVE)->second.AddShortCut(VK_F5, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_RESTORE)->second.AddShortCut(VK_F7, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_LOAD)->second.AddShortCut('L', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_SYSTEM_SAVEAS)->second.AddShortCut('S', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_SYSTEM_CHEAT)->second.AddShortCut('C', true, false, false, CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_SYSTEM_GSBUTTON)->second.AddShortCut(VK_F9, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_INCREASE_SPEED)->second.AddShortCut(VK_OEM_PLUS, false, false, false, CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_DECREASE_SPEED)->second.AddShortCut(VK_OEM_MINUS, false, false, false, CMenuShortCutKey::GAME_RUNNING); + } + else + { + CMenuShortCutKey::ACCESS_MODE AccessMode; + int ID, key, bCtrl, bAlt, bShift, bUserAdded, bInactive; + + FILE *file = fopen(ShortCutFile, "r"); + if (file) + { + do + { + char Line[300]; + if (fgets(Line, sizeof(Line), file) != NULL) + { + sscanf(Line, "%d,%d,%d,%d,%d,%d,%d,%d", &ID, &key, &bCtrl, &bAlt, &bShift, &AccessMode, + &bUserAdded, &bInactive); + + MSC_MAP::iterator item = m_ShortCuts.find(ID); + if (item == m_ShortCuts.end()) { continue; } + item->second.AddShortCut((WORD)(key & 0xFFFF), bCtrl == 1, bAlt == 1, bShift == 1, AccessMode, bUserAdded == 1, bInactive == 1); + } + } while (feof(file) == 0); + fclose(file); + } + } +} + +void CShortCuts::Save(void) +{ + CGuard CS(m_CS); + + stdstr FileName = g_Settings->LoadStringVal(SupportFile_ShortCuts); + FILE *file = fopen(FileName.c_str(), "w"); + if (file == NULL) + { + return; + } + + for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) + { + for (SHORTCUT_KEY_LIST::const_iterator ShortCut = Item->second.GetAccelItems().begin(); ShortCut != Item->second.GetAccelItems().end(); ShortCut++) + { + fprintf(file, "%d,%d,%d,%d,%d,%d,%d,%d\n", + Item->first, + ShortCut->Key(), + ShortCut->Ctrl(), + ShortCut->Alt(), + ShortCut->Shift(), + ShortCut->AccessMode(), + ShortCut->UserAdded(), + ShortCut->Inactive()); + } + } + fclose(file); +} + +HACCEL CShortCuts::GetAcceleratorTable(void) +{ + CGuard CS(m_CS); + + //Generate a ACCEL list + CMenuShortCutKey::ACCESS_MODE AccessLevel = CMenuShortCutKey::GAME_NOT_RUNNING; + if (g_Settings->LoadBool(GameRunning_CPU_Running)) + { + AccessLevel = g_Settings->LoadBool(UserInterface_InFullScreen) ? + CMenuShortCutKey::GAME_RUNNING_FULLSCREEN : + CMenuShortCutKey::GAME_RUNNING_WINDOW; + } + + int size = 0, MaxSize = m_ShortCuts.size() * 5; + ACCEL * AccelList = new ACCEL[MaxSize]; + + for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) + { + CShortCutItem & short_cut = Item->second; + + CMenuShortCutKey::ACCESS_MODE ItemMode = short_cut.AccessMode(); + if ((ItemMode & AccessLevel) != AccessLevel) + { + continue; + } + + SHORTCUT_KEY_LIST ShortCutAccelList = short_cut.GetAccelItems(); + for (SHORTCUT_KEY_LIST::iterator AccelIter = ShortCutAccelList.begin(); AccelIter != ShortCutAccelList.end(); AccelIter++) + { + CMenuShortCutKey & Key = *AccelIter; + if (Key.Inactive()) + { + continue; + } + if ((Key.AccessMode() & AccessLevel) != AccessLevel) + { + continue; + } + if (size >= MaxSize) { break; } + AccelList[size].cmd = (WORD)Item->first; + AccelList[size].key = Key.Key(); + AccelList[size].fVirt = FVIRTKEY; + if (Key.Alt()) { AccelList[size].fVirt |= FALT; } + if (Key.Ctrl()) { AccelList[size].fVirt |= FCONTROL; } + if (Key.Shift()) { AccelList[size].fVirt |= FSHIFT; } + size += 1; + } + } + + WriteTrace(TraceUserInterface, TraceDebug, "CreateAcceleratorTable"); + HACCEL AccelTable = CreateAcceleratorTable(AccelList, size); + WriteTrace(TraceUserInterface, TraceDebug, "Delete accel list"); + delete[] AccelList; + return AccelTable; } \ No newline at end of file diff --git a/Source/Project64/UserInterface/MenuShortCuts.h b/Source/Project64/UserInterface/MenuShortCuts.h index 735ac65ea..1f88dd3e3 100644 --- a/Source/Project64/UserInterface/MenuShortCuts.h +++ b/Source/Project64/UserInterface/MenuShortCuts.h @@ -1,114 +1,114 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -struct VIRTUAL_KEY -{ - LPCSTR Name; - int Key; - LPCSTR KeyName; -}; - -class CMenuShortCutKey -{ -public: - enum ACCESS_MODE - { - NONE = 0, - GAME_NOT_RUNNING = 1, - GAME_RUNNING_WINDOW = 2, - NOT_IN_FULLSCREEN = 3, - GAME_RUNNING_FULLSCREEN = 4, - GAME_RUNNING = 6, - ANYTIME = 7, - }; - -private: - static VIRTUAL_KEY m_VirtualKeyList[]; - - stdstr m_ShortCutName; - WORD m_key; - bool m_bCtrl; - bool m_bAlt; - bool m_bShift; - ACCESS_MODE m_AccessMode; - bool m_bUserAdded; - bool m_bInactive; - -public: - CMenuShortCutKey(void); - CMenuShortCutKey(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive); - bool Same(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode) const; - - static VIRTUAL_KEY * VirtualKeyList(int &Size); - - inline stdstr Name(void) const { return m_ShortCutName; } - inline WORD Key(void) const { return m_key; } - inline bool Ctrl(void) const { return m_bCtrl; } - inline bool Alt(void) const { return m_bAlt; } - inline bool Shift(void) const { return m_bShift; } - inline bool UserAdded(void) const { return m_bUserAdded; } - inline bool Inactive(void) const { return m_bInactive; } - inline ACCESS_MODE AccessMode(void) const { return m_AccessMode; } - - inline void SetInactive(bool Inactive) { m_bInactive = Inactive; } -}; - -class CShortCutItem -{ -public: - typedef std::list SHORTCUT_KEY_LIST; - -private: - typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; - - ACCESS_MODE m_Access; - LanguageStringID m_Section; - LanguageStringID m_Title; - SHORTCUT_KEY_LIST m_AccelList; - -public: - CShortCutItem(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access); - void Reset(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access); - void AddShortCut(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded = false, bool bInactive = false); - void RemoveItem(CMenuShortCutKey * ShortCut); - - inline const SHORTCUT_KEY_LIST & GetAccelItems(void) const { return m_AccelList; } - inline LanguageStringID Section(void) const { return m_Section; } - inline LanguageStringID Title(void) const { return m_Title; } - inline ACCESS_MODE AccessMode(void) const { return m_Access; } -}; - -typedef std::map MSC_MAP; - -class CShortCuts -{ - typedef CShortCutItem::SHORTCUT_KEY_LIST SHORTCUT_KEY_LIST; - typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; - typedef LanguageStringID LangStr; - - MSC_MAP m_ShortCuts; - CriticalSection m_CS; - - void AddShortCut(WORD ID, LangStr Section, LangStr LangID, CMenuShortCutKey::ACCESS_MODE AccessMode); - -public: - CShortCuts(void); - ~CShortCuts(void); - - std::wstring ShortCutString(int MenuID, ACCESS_MODE AccessLevel); - LangStr GetMenuItemName(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE Access); - HACCEL GetAcceleratorTable(void); - MSC_MAP & GetShortCuts(void) { return m_ShortCuts; } - - void Load(bool InitialValues = false); - void Save(void); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +struct VIRTUAL_KEY +{ + LPCSTR Name; + int Key; + LPCSTR KeyName; +}; + +class CMenuShortCutKey +{ +public: + enum ACCESS_MODE + { + NONE = 0, + GAME_NOT_RUNNING = 1, + GAME_RUNNING_WINDOW = 2, + NOT_IN_FULLSCREEN = 3, + GAME_RUNNING_FULLSCREEN = 4, + GAME_RUNNING = 6, + ANYTIME = 7, + }; + +private: + static VIRTUAL_KEY m_VirtualKeyList[]; + + stdstr m_ShortCutName; + WORD m_key; + bool m_bCtrl; + bool m_bAlt; + bool m_bShift; + ACCESS_MODE m_AccessMode; + bool m_bUserAdded; + bool m_bInactive; + +public: + CMenuShortCutKey(void); + CMenuShortCutKey(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive); + bool Same(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode) const; + + static VIRTUAL_KEY * VirtualKeyList(int &Size); + + inline stdstr Name(void) const { return m_ShortCutName; } + inline WORD Key(void) const { return m_key; } + inline bool Ctrl(void) const { return m_bCtrl; } + inline bool Alt(void) const { return m_bAlt; } + inline bool Shift(void) const { return m_bShift; } + inline bool UserAdded(void) const { return m_bUserAdded; } + inline bool Inactive(void) const { return m_bInactive; } + inline ACCESS_MODE AccessMode(void) const { return m_AccessMode; } + + inline void SetInactive(bool Inactive) { m_bInactive = Inactive; } +}; + +class CShortCutItem +{ +public: + typedef std::list SHORTCUT_KEY_LIST; + +private: + typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; + + ACCESS_MODE m_Access; + LanguageStringID m_Section; + LanguageStringID m_Title; + SHORTCUT_KEY_LIST m_AccelList; + +public: + CShortCutItem(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access); + void Reset(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access); + void AddShortCut(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded = false, bool bInactive = false); + void RemoveItem(CMenuShortCutKey * ShortCut); + + inline const SHORTCUT_KEY_LIST & GetAccelItems(void) const { return m_AccelList; } + inline LanguageStringID Section(void) const { return m_Section; } + inline LanguageStringID Title(void) const { return m_Title; } + inline ACCESS_MODE AccessMode(void) const { return m_Access; } +}; + +typedef std::map MSC_MAP; + +class CShortCuts +{ + typedef CShortCutItem::SHORTCUT_KEY_LIST SHORTCUT_KEY_LIST; + typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; + typedef LanguageStringID LangStr; + + MSC_MAP m_ShortCuts; + CriticalSection m_CS; + + void AddShortCut(WORD ID, LangStr Section, LangStr LangID, CMenuShortCutKey::ACCESS_MODE AccessMode); + +public: + CShortCuts(void); + ~CShortCuts(void); + + std::wstring ShortCutString(int MenuID, ACCESS_MODE AccessLevel); + LangStr GetMenuItemName(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE Access); + HACCEL GetAcceleratorTable(void); + MSC_MAP & GetShortCuts(void) { return m_ShortCuts; } + + void Load(bool InitialValues = false); + void Save(void); +}; diff --git a/Source/Project64/UserInterface/NotificationClass.cpp b/Source/Project64/UserInterface/NotificationClass.cpp index ea4be7d89..281c41440 100644 --- a/Source/Project64/UserInterface/NotificationClass.cpp +++ b/Source/Project64/UserInterface/NotificationClass.cpp @@ -1,267 +1,267 @@ -#include "stdafx.h" -#include - -CNotificationImp & Notify(void) -{ - static CNotificationImp g_Notify; - return g_Notify; -} - -CNotificationImp::CNotificationImp() : -m_hWnd(NULL), -m_gfxPlugin(NULL), -m_NextMsg(0) -{ - _tzset(); -} - -void CNotificationImp::AppInitDone(void) -{ - CNotificationSettings::RegisterNotifications(); -} - -void CNotificationImp::SetMainWindow(CMainGui * Gui) -{ - m_hWnd = Gui; -} - -void CNotificationImp::WindowMode(void) const -{ - static bool InsideFunc = false; - if (InsideFunc) - { - return; - } - InsideFunc = true; - if (InFullScreen()) - { - ChangeFullScreen(); - for (int i = 0; i < 5; i++) - { - Sleep(50); - if (ProcessGuiMessages()) - { - break; - } - } - } - InsideFunc = false; -} - -void CNotificationImp::DisplayError(LanguageStringID StringID) const -{ - DisplayError(g_Lang->GetString(StringID).c_str()); -} - -void CNotificationImp::DisplayError(const char * Message) const -{ - if (this == NULL) { return; } - - WriteTrace(TraceUserInterface, TraceError, Message); - WindowMode(); - - HWND Parent = NULL; - if (m_hWnd) - { - Parent = reinterpret_cast(m_hWnd->GetWindowHandle()); - } - MessageBoxW(Parent, stdstr(Message).ToUTF16().c_str(), wGS(MSG_MSGBOX_TITLE).c_str(), MB_OK | MB_ICONERROR | MB_SETFOREGROUND); -} - -void CNotificationImp::DisplayMessage(int DisplayTime, LanguageStringID StringID) const -{ - DisplayMessage(DisplayTime, g_Lang->GetString(StringID).c_str()); -} - -void CNotificationImp::DisplayMessage(int DisplayTime, const char * Message) const -{ - if (!m_hWnd) { return; } - - if (m_NextMsg > 0 || DisplayTime > 0) - { - time_t Now = time(NULL); - if (DisplayTime == 0 && Now < m_NextMsg) - { - return; - } - if (DisplayTime > 0) - { - m_NextMsg = Now + DisplayTime; - } - if (m_NextMsg == 0) - { - m_NextMsg = 0; - } - } - - if (InFullScreen()) - { - if (m_gfxPlugin && m_gfxPlugin->DrawStatus) - { - WriteTrace(TraceGFXPlugin, TraceDebug, "DrawStatus - Starting"); - m_gfxPlugin->DrawStatus(Message, FALSE); - WriteTrace(TraceGFXPlugin, TraceDebug, "DrawStatus - Done"); - } - } - else - { - m_hWnd->SetStatusText(0, stdstr(Message).ToUTF16().c_str()); - } -} - -void CNotificationImp::DisplayMessage2(const char * Message) const -{ - if (!m_hWnd) { return; } - - m_hWnd->SetStatusText(1, stdstr(Message).ToUTF16().c_str()); -} - -bool CNotificationImp::AskYesNoQuestion(const char * Question) const -{ - if (this == NULL) { return false; } - - WriteTrace(TraceUserInterface, TraceError, Question); - WindowMode(); - - HWND Parent = NULL; - if (m_hWnd) - { - Parent = reinterpret_cast(m_hWnd->GetWindowHandle()); - } - int result = MessageBoxW(Parent, stdstr(Question).ToUTF16().c_str(), wGS(MSG_MSGBOX_TITLE).c_str(), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 | MB_SETFOREGROUND); - return result == IDYES; -} - -void CNotificationImp::SetGfxPlugin(CGfxPlugin * Plugin) -{ - m_gfxPlugin = Plugin; -} - -void CNotificationImp::FatalError(LanguageStringID StringID) const -{ - FatalError(g_Lang->GetString(StringID).c_str()); -} - -void CNotificationImp::FatalError(const char * Message) const -{ - WriteTrace(TraceUserInterface, TraceError, Message); - WindowMode(); - - HWND Parent = NULL; - if (m_hWnd) { Parent = reinterpret_cast(m_hWnd->GetWindowHandle()); } - MessageBoxW(Parent, stdstr(Message).ToUTF16().c_str(), L"Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); - ExitThread(0); -} - -void CNotificationImp::AddRecentDir(const char * RomDir) -{ - //Validate the passed string - if (HIWORD(RomDir) == NULL) { return; } - - //Get Information about the stored rom list - size_t MaxRememberedDirs = g_Settings->LoadDword(Directory_RecentGameDirCount); - strlist RecentDirs; - size_t i; - for (i = 0; i < MaxRememberedDirs; i++) - { - stdstr RecentDir = g_Settings->LoadStringIndex(Directory_RecentGameDirIndex, i); - if (RecentDir.empty()) - { - break; - } - RecentDirs.push_back(RecentDir); - } - - //See if the dir is already in the list if so then move it to the top of the list - strlist::iterator iter; - for (iter = RecentDirs.begin(); iter != RecentDirs.end(); iter++) - { - if (_stricmp(RomDir, iter->c_str()) != 0) - { - continue; - } - RecentDirs.erase(iter); - break; - } - RecentDirs.push_front(RomDir); - if (RecentDirs.size() > MaxRememberedDirs) - { - RecentDirs.pop_back(); - } - - for (i = 0, iter = RecentDirs.begin(); iter != RecentDirs.end(); iter++, i++) - { - g_Settings->SaveStringIndex(Directory_RecentGameDirIndex, i, *iter); - } -} - -void CNotificationImp::RefreshMenu(void) -{ - if (m_hWnd == NULL) { return; } - - m_hWnd->RefreshMenu(); -} - -void CNotificationImp::HideRomBrowser(void) -{ - if (m_hWnd == NULL) { return; } - m_hWnd->HideRomList(); -} - -void CNotificationImp::ShowRomBrowser(void) -{ - if (m_hWnd == NULL) { return; } - if (g_Settings->LoadDword(RomBrowser_Enabled)) - { - //Display the rom browser - m_hWnd->ShowRomList(); - m_hWnd->HighLightLastRom(); - } -} - -void CNotificationImp::BringToTop(void) -{ - if (m_hWnd == NULL) { return; } - - m_hWnd->BringToTop(); -} - -void CNotificationImp::ChangeFullScreen(void) const -{ - if (m_hWnd == NULL) { return; } - SendMessage((HWND)(m_hWnd->GetWindowHandle()), WM_COMMAND, MAKELPARAM(ID_OPTIONS_FULLSCREEN2, false), 0); -} - -bool CNotificationImp::ProcessGuiMessages(void) const -{ - if (m_hWnd == NULL) { return false; } - - return m_hWnd->ProcessGuiMessages(); -} - -void CNotificationImp::BreakPoint(const char * FileName, int LineNumber) -{ - if (g_Settings->LoadBool(Debugger_Enabled)) - { - DisplayError(stdstr_f("Break point found at\n%s\n%d", FileName, LineNumber).c_str()); - if (IsDebuggerPresent() != 0) - { - DebugBreak(); - } - else - { - if (g_BaseSystem) - { - g_BaseSystem->CloseCpu(); - } - } - } - else - { - DisplayError("Fatal Error: Stopping emulation"); - if (g_BaseSystem) - { - g_BaseSystem->CloseCpu(); - } - } +#include "stdafx.h" +#include + +CNotificationImp & Notify(void) +{ + static CNotificationImp g_Notify; + return g_Notify; +} + +CNotificationImp::CNotificationImp() : +m_hWnd(NULL), +m_gfxPlugin(NULL), +m_NextMsg(0) +{ + _tzset(); +} + +void CNotificationImp::AppInitDone(void) +{ + CNotificationSettings::RegisterNotifications(); +} + +void CNotificationImp::SetMainWindow(CMainGui * Gui) +{ + m_hWnd = Gui; +} + +void CNotificationImp::WindowMode(void) const +{ + static bool InsideFunc = false; + if (InsideFunc) + { + return; + } + InsideFunc = true; + if (InFullScreen()) + { + ChangeFullScreen(); + for (int i = 0; i < 5; i++) + { + Sleep(50); + if (ProcessGuiMessages()) + { + break; + } + } + } + InsideFunc = false; +} + +void CNotificationImp::DisplayError(LanguageStringID StringID) const +{ + DisplayError(g_Lang->GetString(StringID).c_str()); +} + +void CNotificationImp::DisplayError(const char * Message) const +{ + if (this == NULL) { return; } + + WriteTrace(TraceUserInterface, TraceError, Message); + WindowMode(); + + HWND Parent = NULL; + if (m_hWnd) + { + Parent = reinterpret_cast(m_hWnd->GetWindowHandle()); + } + MessageBoxW(Parent, stdstr(Message).ToUTF16().c_str(), wGS(MSG_MSGBOX_TITLE).c_str(), MB_OK | MB_ICONERROR | MB_SETFOREGROUND); +} + +void CNotificationImp::DisplayMessage(int DisplayTime, LanguageStringID StringID) const +{ + DisplayMessage(DisplayTime, g_Lang->GetString(StringID).c_str()); +} + +void CNotificationImp::DisplayMessage(int DisplayTime, const char * Message) const +{ + if (!m_hWnd) { return; } + + if (m_NextMsg > 0 || DisplayTime > 0) + { + time_t Now = time(NULL); + if (DisplayTime == 0 && Now < m_NextMsg) + { + return; + } + if (DisplayTime > 0) + { + m_NextMsg = Now + DisplayTime; + } + if (m_NextMsg == 0) + { + m_NextMsg = 0; + } + } + + if (InFullScreen()) + { + if (m_gfxPlugin && m_gfxPlugin->DrawStatus) + { + WriteTrace(TraceGFXPlugin, TraceDebug, "DrawStatus - Starting"); + m_gfxPlugin->DrawStatus(Message, FALSE); + WriteTrace(TraceGFXPlugin, TraceDebug, "DrawStatus - Done"); + } + } + else + { + m_hWnd->SetStatusText(0, stdstr(Message).ToUTF16().c_str()); + } +} + +void CNotificationImp::DisplayMessage2(const char * Message) const +{ + if (!m_hWnd) { return; } + + m_hWnd->SetStatusText(1, stdstr(Message).ToUTF16().c_str()); +} + +bool CNotificationImp::AskYesNoQuestion(const char * Question) const +{ + if (this == NULL) { return false; } + + WriteTrace(TraceUserInterface, TraceError, Question); + WindowMode(); + + HWND Parent = NULL; + if (m_hWnd) + { + Parent = reinterpret_cast(m_hWnd->GetWindowHandle()); + } + int result = MessageBoxW(Parent, stdstr(Question).ToUTF16().c_str(), wGS(MSG_MSGBOX_TITLE).c_str(), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 | MB_SETFOREGROUND); + return result == IDYES; +} + +void CNotificationImp::SetGfxPlugin(CGfxPlugin * Plugin) +{ + m_gfxPlugin = Plugin; +} + +void CNotificationImp::FatalError(LanguageStringID StringID) const +{ + FatalError(g_Lang->GetString(StringID).c_str()); +} + +void CNotificationImp::FatalError(const char * Message) const +{ + WriteTrace(TraceUserInterface, TraceError, Message); + WindowMode(); + + HWND Parent = NULL; + if (m_hWnd) { Parent = reinterpret_cast(m_hWnd->GetWindowHandle()); } + MessageBoxW(Parent, stdstr(Message).ToUTF16().c_str(), L"Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + ExitThread(0); +} + +void CNotificationImp::AddRecentDir(const char * RomDir) +{ + //Validate the passed string + if (HIWORD(RomDir) == NULL) { return; } + + //Get Information about the stored rom list + size_t MaxRememberedDirs = g_Settings->LoadDword(Directory_RecentGameDirCount); + strlist RecentDirs; + size_t i; + for (i = 0; i < MaxRememberedDirs; i++) + { + stdstr RecentDir = g_Settings->LoadStringIndex(Directory_RecentGameDirIndex, i); + if (RecentDir.empty()) + { + break; + } + RecentDirs.push_back(RecentDir); + } + + //See if the dir is already in the list if so then move it to the top of the list + strlist::iterator iter; + for (iter = RecentDirs.begin(); iter != RecentDirs.end(); iter++) + { + if (_stricmp(RomDir, iter->c_str()) != 0) + { + continue; + } + RecentDirs.erase(iter); + break; + } + RecentDirs.push_front(RomDir); + if (RecentDirs.size() > MaxRememberedDirs) + { + RecentDirs.pop_back(); + } + + for (i = 0, iter = RecentDirs.begin(); iter != RecentDirs.end(); iter++, i++) + { + g_Settings->SaveStringIndex(Directory_RecentGameDirIndex, i, *iter); + } +} + +void CNotificationImp::RefreshMenu(void) +{ + if (m_hWnd == NULL) { return; } + + m_hWnd->RefreshMenu(); +} + +void CNotificationImp::HideRomBrowser(void) +{ + if (m_hWnd == NULL) { return; } + m_hWnd->HideRomList(); +} + +void CNotificationImp::ShowRomBrowser(void) +{ + if (m_hWnd == NULL) { return; } + if (g_Settings->LoadDword(RomBrowser_Enabled)) + { + //Display the rom browser + m_hWnd->ShowRomList(); + m_hWnd->HighLightLastRom(); + } +} + +void CNotificationImp::BringToTop(void) +{ + if (m_hWnd == NULL) { return; } + + m_hWnd->BringToTop(); +} + +void CNotificationImp::ChangeFullScreen(void) const +{ + if (m_hWnd == NULL) { return; } + SendMessage((HWND)(m_hWnd->GetWindowHandle()), WM_COMMAND, MAKELPARAM(ID_OPTIONS_FULLSCREEN2, false), 0); +} + +bool CNotificationImp::ProcessGuiMessages(void) const +{ + if (m_hWnd == NULL) { return false; } + + return m_hWnd->ProcessGuiMessages(); +} + +void CNotificationImp::BreakPoint(const char * FileName, int LineNumber) +{ + if (g_Settings->LoadBool(Debugger_Enabled)) + { + DisplayError(stdstr_f("Break point found at\n%s\n%d", FileName, LineNumber).c_str()); + if (IsDebuggerPresent() != 0) + { + DebugBreak(); + } + else + { + if (g_BaseSystem) + { + g_BaseSystem->CloseCpu(); + } + } + } + else + { + DisplayError("Fatal Error: Stopping emulation"); + if (g_BaseSystem) + { + g_BaseSystem->CloseCpu(); + } + } } \ No newline at end of file diff --git a/Source/Project64/UserInterface/NotificationClass.h b/Source/Project64/UserInterface/NotificationClass.h index c7fb4c643..a48f65cdc 100644 --- a/Source/Project64/UserInterface/NotificationClass.h +++ b/Source/Project64/UserInterface/NotificationClass.h @@ -1,73 +1,73 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include "../Settings/NotificationSettings.h" -#include - -class CSettings; - -class CNotificationImp : - public CNotification, - CNotificationSettings -{ -public: - CNotificationImp(void); - - void AppInitDone(void); - - // Make sure we are not in full screen - void WindowMode(void) const; - - //Error Messages - virtual void DisplayError(const char * Message) const; - virtual void DisplayError(LanguageStringID StringID) const; - - virtual void FatalError(const char * Message) const; - virtual void FatalError(LanguageStringID StringID) const; - - //User Feedback - virtual void DisplayMessage(int DisplayTime, const char * Message) const; - virtual void DisplayMessage(int DisplayTime, LanguageStringID StringID) const; - - virtual void DisplayMessage2(const char * Message) const; - - // Ask a Yes/No Question to the user, yes = true, no = false - virtual bool AskYesNoQuestion(const char * Question) const; - - virtual void BreakPoint(const char * FileName, int32_t LineNumber); - - void SetWindowCaption(const wchar_t * Caption); - - //Remember roms loaded and Rom Dir selected - void AddRecentDir(const char * RomDir); - - //Gui for responses - void SetMainWindow(CMainGui * Gui); - void RefreshMenu(void); - void HideRomBrowser(void); - void ShowRomBrowser(void); - void BringToTop(void); - bool ProcessGuiMessages(void) const; - void ChangeFullScreen(void) const; - void SetGfxPlugin(CGfxPlugin * Plugin); - -private: - CNotificationImp(const CNotificationImp&); // Disable copy constructor - CNotificationImp& operator=(const CNotificationImp&); // Disable assignment - - CMainGui * m_hWnd; - CGfxPlugin * m_gfxPlugin; - - mutable time_t m_NextMsg; -}; - -CNotificationImp & Notify(void); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include "../Settings/NotificationSettings.h" +#include + +class CSettings; + +class CNotificationImp : + public CNotification, + CNotificationSettings +{ +public: + CNotificationImp(void); + + void AppInitDone(void); + + // Make sure we are not in full screen + void WindowMode(void) const; + + //Error Messages + virtual void DisplayError(const char * Message) const; + virtual void DisplayError(LanguageStringID StringID) const; + + virtual void FatalError(const char * Message) const; + virtual void FatalError(LanguageStringID StringID) const; + + //User Feedback + virtual void DisplayMessage(int DisplayTime, const char * Message) const; + virtual void DisplayMessage(int DisplayTime, LanguageStringID StringID) const; + + virtual void DisplayMessage2(const char * Message) const; + + // Ask a Yes/No Question to the user, yes = true, no = false + virtual bool AskYesNoQuestion(const char * Question) const; + + virtual void BreakPoint(const char * FileName, int32_t LineNumber); + + void SetWindowCaption(const wchar_t * Caption); + + //Remember roms loaded and Rom Dir selected + void AddRecentDir(const char * RomDir); + + //Gui for responses + void SetMainWindow(CMainGui * Gui); + void RefreshMenu(void); + void HideRomBrowser(void); + void ShowRomBrowser(void); + void BringToTop(void); + bool ProcessGuiMessages(void) const; + void ChangeFullScreen(void) const; + void SetGfxPlugin(CGfxPlugin * Plugin); + +private: + CNotificationImp(const CNotificationImp&); // Disable copy constructor + CNotificationImp& operator=(const CNotificationImp&); // Disable assignment + + CMainGui * m_hWnd; + CGfxPlugin * m_gfxPlugin; + + mutable time_t m_NextMsg; +}; + +CNotificationImp & Notify(void); diff --git a/Source/Project64/UserInterface/RomBrowser.h b/Source/Project64/UserInterface/RomBrowser.h index 55974ce29..99b5f9aeb 100644 --- a/Source/Project64/UserInterface/RomBrowser.h +++ b/Source/Project64/UserInterface/RomBrowser.h @@ -1,219 +1,219 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CMainGui; -class CPlugins; - -class ROMBROWSER_FIELDS -{ - stdstr m_Name; - size_t m_Pos, m_DefaultPos; - int m_ID; - uint32_t m_ColWidth; - LanguageStringID m_LangID; - bool m_PosChanged; - -public: - ROMBROWSER_FIELDS(const char * Name, int Pos, int ID, int ColWidth, LanguageStringID LangID, bool UseDefault) : - m_Name(Name), - m_Pos(Pos), - m_DefaultPos(Pos), - m_ID(ID), - m_ColWidth(ColWidth), - m_LangID(LangID), - m_PosChanged(false) - - { - if (!UseDefault) - { - m_PosChanged = g_Settings->LoadDwordIndex(RomBrowser_PosIndex, m_ID, (uint32_t &)m_Pos); - g_Settings->LoadDwordIndex(RomBrowser_WidthIndex, m_ID, m_ColWidth); - } - } - inline LPCSTR Name(void) const { return m_Name.c_str(); } - inline size_t Pos(void) const { return m_Pos; } - inline bool PosChanged(void) const { return m_PosChanged; } - inline int ID(void) const { return m_ID; } - inline int ColWidth(void) const { return m_ColWidth; } - inline LanguageStringID LangID(void) const { return m_LangID; } - - void SetColWidth(int ColWidth) - { - m_ColWidth = ColWidth; - g_Settings->SaveDwordIndex(RomBrowser_WidthIndex, m_ID, m_ColWidth); - } - void SetColPos(int Pos) - { - m_Pos = Pos; - g_Settings->SaveDwordIndex(RomBrowser_PosIndex, m_ID, m_Pos); - m_PosChanged = true; - } - void ResetPos(void) - { - m_Pos = m_DefaultPos; - g_Settings->DeleteSettingIndex(RomBrowser_PosIndex, m_ID); - m_PosChanged = false; - } -}; - -typedef std::vector ROMBROWSER_FIELDS_LIST; -typedef std::vector FIELD_TYPE_LIST; - -class CRomBrowser; -struct SORT_FIELD -{ - CRomBrowser * _this; - int Key; - bool KeyAscend; -}; - -class C7zip; -class CRomBrowser -{ - enum { IDC_ROMLIST = 223 }; - enum - { - RB_FileName = 0, RB_InternalName = 1, RB_GoodName = 2, - RB_Status = 3, RB_RomSize = 4, RB_CoreNotes = 5, - RB_PluginNotes = 6, RB_UserNotes = 7, RB_CartridgeID = 8, - RB_Manufacturer = 9, RB_Country = 10, RB_Developer = 11, - RB_Crc1 = 12, RB_Crc2 = 13, RB_CICChip = 14, - RB_ReleaseDate = 15, RB_Genre = 16, RB_Players = 17, - RB_ForceFeedback = 18, RB_FileFormat = 19 - }; - - enum FILE_FORMAT - { - Format_Uncompressed, - Format_Zip, - Format_7zip, - }; - - enum - { - NoOfSortKeys = 3 - }; - - struct ROM_INFO - { - char szFullFileName[300]; - FILE_FORMAT FileFormat; - wchar_t Status[60]; - char FileName[200]; - wchar_t InternalName[22]; - wchar_t GoodName[200]; - wchar_t CartID[3]; - wchar_t PluginNotes[250]; - wchar_t CoreNotes[250]; - wchar_t UserNotes[250]; - wchar_t Developer[30]; - wchar_t ReleaseDate[30]; - wchar_t Genre[15]; - int32_t Players; - uint32_t TextColor; - int32_t SelColor; - uint32_t SelTextColor; - uint32_t SelColorBrush; - int32_t RomSize; - uint8_t Manufacturer; - uint8_t Country; - uint32_t CRC1; - uint32_t CRC2; - int32_t CicChip; - wchar_t ForceFeedback[15]; - }; - - typedef std::vector ROMINFO_LIST; - - HWND & m_MainWindow; - HWND & m_StatusWindow; - HWND m_hRomList; - ROMBROWSER_FIELDS_LIST m_Fields; - FIELD_TYPE_LIST m_FieldType; - ROMINFO_LIST m_RomInfo; - std::string m_SelectedRom; - bool m_Visible; - bool m_ShowingRomBrowser; - HANDLE m_RefreshThread; - bool m_StopRefresh; - CIniFile * m_RomIniFile; - CIniFile * m_NotesIniFile; - CIniFile * m_ExtIniFile; - CIniFile * m_ZipIniFile; - bool m_AllowSelectionLastRom; - static std::wstring m_UnknownGoodName; - - void AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File); - void AddRomToList(const char * RomLocation, const char * lpLastRom); - void AddRomInfoToList(ROM_INFO &RomInfo, const char * lpLastRom); - void AllocateBrushs(void); - static void ByteSwapRomData(uint8_t * Data, int DataLen); - int CalcSortPosition(uint32_t lParam); - void CreateRomListControl(void); - void DeallocateBrushs(void); - void FillRomExtensionInfo(ROM_INFO * pRomInfo); - bool FillRomInfo(ROM_INFO * pRomInfo); - void FillRomList(strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, const char * lpLastRom); - void FixRomListWindow(void); - static int32_t GetCicChipID(uint8_t * RomData); - bool LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat); - void LoadRomList(void); - void MenuSetText(HMENU hMenu, int32_t MenuPos, const wchar_t * Title, char * ShortCut); - void SaveRomList(strlist & FileList); - void RomList_ColoumnSortList(uint32_t pnmh); - void RomList_GetDispInfo(uint32_t pnmh); - void RomList_OpenRom(uint32_t pnmh); - void RomList_PopupMenu(uint32_t pnmh); - void RomList_SortList(void); - bool GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, bool InWatchThread); - MD5 RomListHash(strlist & FileList); - - static void NotificationCB(const char * Status, CRomBrowser * _this); - - //Watch Directory Changed function - HANDLE m_WatchThread, m_WatchStopEvent; - DWORD m_WatchThreadID; - stdstr m_WatchRomDir; - void WatchThreadStart(void); - void WatchThreadStop(void); - bool RomDirNeedsRefresh(void); // Called from watch thread - static void WatchRomDirChanged(CRomBrowser * _this); - static void RefreshRomBrowserStatic(CRomBrowser * _this); - static void AddField(ROMBROWSER_FIELDS_LIST & Fields, const char * Name, int32_t Pos, int32_t ID, int32_t Width, LanguageStringID LangID, bool UseDefault); - - //Callback - static int CALLBACK SelectRomDirCallBack(HWND hwnd, uint32_t uMsg, uint32_t lp, uint32_t lpData); - static int CALLBACK RomList_CompareItems(uint32_t lParam1, uint32_t lParam2, uint32_t lParamSort); - -public: - CRomBrowser(HWND & hMainWindow, HWND & StatusWindow); - ~CRomBrowser(void); - void HighLightLastRom(void); - void HideRomList(void); - void RefreshRomBrowser(void); - void ResetRomBrowserColomuns(void); - void ResizeRomList(WORD nWidth, WORD nHeight); - void RomBrowserToTop(void); - void RomBrowserMaximize(bool Mazimize); - bool RomBrowserVisible(void); - bool RomListDrawItem(int idCtrl, uint32_t lParam); - bool RomListNotify(int idCtrl, uint32_t pnmh); - void SaveRomListColoumnInfo(void); - void SelectRomDir(void); - void ShowRomList(void); - bool ShowingRomBrowser(void) { return m_ShowingRomBrowser; } - const char * CurrentedSelectedRom(void) { return m_SelectedRom.c_str(); } - - static void GetFieldInfo(ROMBROWSER_FIELDS_LIST & Fields, bool UseDefault = false); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CMainGui; +class CPlugins; + +class ROMBROWSER_FIELDS +{ + stdstr m_Name; + size_t m_Pos, m_DefaultPos; + int m_ID; + uint32_t m_ColWidth; + LanguageStringID m_LangID; + bool m_PosChanged; + +public: + ROMBROWSER_FIELDS(const char * Name, int Pos, int ID, int ColWidth, LanguageStringID LangID, bool UseDefault) : + m_Name(Name), + m_Pos(Pos), + m_DefaultPos(Pos), + m_ID(ID), + m_ColWidth(ColWidth), + m_LangID(LangID), + m_PosChanged(false) + + { + if (!UseDefault) + { + m_PosChanged = g_Settings->LoadDwordIndex(RomBrowser_PosIndex, m_ID, (uint32_t &)m_Pos); + g_Settings->LoadDwordIndex(RomBrowser_WidthIndex, m_ID, m_ColWidth); + } + } + inline LPCSTR Name(void) const { return m_Name.c_str(); } + inline size_t Pos(void) const { return m_Pos; } + inline bool PosChanged(void) const { return m_PosChanged; } + inline int ID(void) const { return m_ID; } + inline int ColWidth(void) const { return m_ColWidth; } + inline LanguageStringID LangID(void) const { return m_LangID; } + + void SetColWidth(int ColWidth) + { + m_ColWidth = ColWidth; + g_Settings->SaveDwordIndex(RomBrowser_WidthIndex, m_ID, m_ColWidth); + } + void SetColPos(int Pos) + { + m_Pos = Pos; + g_Settings->SaveDwordIndex(RomBrowser_PosIndex, m_ID, m_Pos); + m_PosChanged = true; + } + void ResetPos(void) + { + m_Pos = m_DefaultPos; + g_Settings->DeleteSettingIndex(RomBrowser_PosIndex, m_ID); + m_PosChanged = false; + } +}; + +typedef std::vector ROMBROWSER_FIELDS_LIST; +typedef std::vector FIELD_TYPE_LIST; + +class CRomBrowser; +struct SORT_FIELD +{ + CRomBrowser * _this; + int Key; + bool KeyAscend; +}; + +class C7zip; +class CRomBrowser +{ + enum { IDC_ROMLIST = 223 }; + enum + { + RB_FileName = 0, RB_InternalName = 1, RB_GoodName = 2, + RB_Status = 3, RB_RomSize = 4, RB_CoreNotes = 5, + RB_PluginNotes = 6, RB_UserNotes = 7, RB_CartridgeID = 8, + RB_Manufacturer = 9, RB_Country = 10, RB_Developer = 11, + RB_Crc1 = 12, RB_Crc2 = 13, RB_CICChip = 14, + RB_ReleaseDate = 15, RB_Genre = 16, RB_Players = 17, + RB_ForceFeedback = 18, RB_FileFormat = 19 + }; + + enum FILE_FORMAT + { + Format_Uncompressed, + Format_Zip, + Format_7zip, + }; + + enum + { + NoOfSortKeys = 3 + }; + + struct ROM_INFO + { + char szFullFileName[300]; + FILE_FORMAT FileFormat; + wchar_t Status[60]; + char FileName[200]; + wchar_t InternalName[22]; + wchar_t GoodName[200]; + wchar_t CartID[3]; + wchar_t PluginNotes[250]; + wchar_t CoreNotes[250]; + wchar_t UserNotes[250]; + wchar_t Developer[30]; + wchar_t ReleaseDate[30]; + wchar_t Genre[15]; + int32_t Players; + uint32_t TextColor; + int32_t SelColor; + uint32_t SelTextColor; + uint32_t SelColorBrush; + int32_t RomSize; + uint8_t Manufacturer; + uint8_t Country; + uint32_t CRC1; + uint32_t CRC2; + int32_t CicChip; + wchar_t ForceFeedback[15]; + }; + + typedef std::vector ROMINFO_LIST; + + HWND & m_MainWindow; + HWND & m_StatusWindow; + HWND m_hRomList; + ROMBROWSER_FIELDS_LIST m_Fields; + FIELD_TYPE_LIST m_FieldType; + ROMINFO_LIST m_RomInfo; + std::string m_SelectedRom; + bool m_Visible; + bool m_ShowingRomBrowser; + HANDLE m_RefreshThread; + bool m_StopRefresh; + CIniFile * m_RomIniFile; + CIniFile * m_NotesIniFile; + CIniFile * m_ExtIniFile; + CIniFile * m_ZipIniFile; + bool m_AllowSelectionLastRom; + static std::wstring m_UnknownGoodName; + + void AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File); + void AddRomToList(const char * RomLocation, const char * lpLastRom); + void AddRomInfoToList(ROM_INFO &RomInfo, const char * lpLastRom); + void AllocateBrushs(void); + static void ByteSwapRomData(uint8_t * Data, int DataLen); + int CalcSortPosition(uint32_t lParam); + void CreateRomListControl(void); + void DeallocateBrushs(void); + void FillRomExtensionInfo(ROM_INFO * pRomInfo); + bool FillRomInfo(ROM_INFO * pRomInfo); + void FillRomList(strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, const char * lpLastRom); + void FixRomListWindow(void); + static int32_t GetCicChipID(uint8_t * RomData); + bool LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat); + void LoadRomList(void); + void MenuSetText(HMENU hMenu, int32_t MenuPos, const wchar_t * Title, char * ShortCut); + void SaveRomList(strlist & FileList); + void RomList_ColoumnSortList(uint32_t pnmh); + void RomList_GetDispInfo(uint32_t pnmh); + void RomList_OpenRom(uint32_t pnmh); + void RomList_PopupMenu(uint32_t pnmh); + void RomList_SortList(void); + bool GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, bool InWatchThread); + MD5 RomListHash(strlist & FileList); + + static void NotificationCB(const char * Status, CRomBrowser * _this); + + //Watch Directory Changed function + HANDLE m_WatchThread, m_WatchStopEvent; + DWORD m_WatchThreadID; + stdstr m_WatchRomDir; + void WatchThreadStart(void); + void WatchThreadStop(void); + bool RomDirNeedsRefresh(void); // Called from watch thread + static void WatchRomDirChanged(CRomBrowser * _this); + static void RefreshRomBrowserStatic(CRomBrowser * _this); + static void AddField(ROMBROWSER_FIELDS_LIST & Fields, const char * Name, int32_t Pos, int32_t ID, int32_t Width, LanguageStringID LangID, bool UseDefault); + + //Callback + static int CALLBACK SelectRomDirCallBack(HWND hwnd, uint32_t uMsg, uint32_t lp, uint32_t lpData); + static int CALLBACK RomList_CompareItems(uint32_t lParam1, uint32_t lParam2, uint32_t lParamSort); + +public: + CRomBrowser(HWND & hMainWindow, HWND & StatusWindow); + ~CRomBrowser(void); + void HighLightLastRom(void); + void HideRomList(void); + void RefreshRomBrowser(void); + void ResetRomBrowserColomuns(void); + void ResizeRomList(WORD nWidth, WORD nHeight); + void RomBrowserToTop(void); + void RomBrowserMaximize(bool Mazimize); + bool RomBrowserVisible(void); + bool RomListDrawItem(int idCtrl, uint32_t lParam); + bool RomListNotify(int idCtrl, uint32_t pnmh); + void SaveRomListColoumnInfo(void); + void SelectRomDir(void); + void ShowRomList(void); + bool ShowingRomBrowser(void) { return m_ShowingRomBrowser; } + const char * CurrentedSelectedRom(void) { return m_SelectedRom.c_str(); } + + static void GetFieldInfo(ROMBROWSER_FIELDS_LIST & Fields, bool UseDefault = false); +}; diff --git a/Source/Project64/UserInterface/RomBrowserClass.cpp b/Source/Project64/UserInterface/RomBrowserClass.cpp index 735072bdb..c123c9df6 100644 --- a/Source/Project64/UserInterface/RomBrowserClass.cpp +++ b/Source/Project64/UserInterface/RomBrowserClass.cpp @@ -1,1959 +1,1959 @@ -#include "stdafx.h" - -#include -#include - -std::wstring CRomBrowser::m_UnknownGoodName; - -CRomBrowser::CRomBrowser(HWND & MainWindow, HWND & StatusWindow) : -m_MainWindow(MainWindow), -m_StatusWindow(StatusWindow), -m_ShowingRomBrowser(false), -m_RefreshThread(NULL), -m_RomIniFile(NULL), -m_NotesIniFile(NULL), -m_ExtIniFile(NULL), -m_ZipIniFile(NULL), -m_AllowSelectionLastRom(true), -m_WatchThreadID(0) -{ - if (g_Settings) - { - m_RomIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); - m_NotesIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Notes).c_str()); - m_ExtIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_ExtInfo).c_str()); - m_ZipIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_7zipCache).c_str()); - } - - m_hRomList = 0; - m_Visible = false; - m_WatchThread = NULL; - m_WatchStopEvent = NULL; - - GetFieldInfo(m_Fields); - m_FieldType.resize(m_Fields.size()); -} - -CRomBrowser::~CRomBrowser(void) -{ - m_StopRefresh = true; - WatchThreadStop(); - DeallocateBrushs(); - - if (m_RomIniFile) - { - delete m_RomIniFile; - m_RomIniFile = NULL; - } - if (m_NotesIniFile) - { - delete m_NotesIniFile; - m_NotesIniFile = NULL; - } - if (m_ExtIniFile) - { - delete m_ExtIniFile; - m_ExtIniFile = NULL; - } - if (m_ZipIniFile) - { - delete m_ZipIniFile; - m_ZipIniFile = NULL; - } -} - -void CRomBrowser::AddField(ROMBROWSER_FIELDS_LIST & Fields, LPCSTR Name, int32_t Pos, int32_t ID, int32_t Width, LanguageStringID LangID, bool UseDefault) -{ - Fields.push_back(ROMBROWSER_FIELDS(Name, Pos, ID, Width, LangID, UseDefault)); -} - -void CRomBrowser::GetFieldInfo(ROMBROWSER_FIELDS_LIST & Fields, bool UseDefault /* = false */) -{ - Fields.clear(); - - AddField(Fields, "File Name", -1, RB_FileName, 218, RB_FILENAME, UseDefault); - AddField(Fields, "Internal Name", -1, RB_InternalName, 200, RB_INTERNALNAME, UseDefault); - AddField(Fields, "Good Name", 0, RB_GoodName, 218, RB_GOODNAME, UseDefault); - AddField(Fields, "Status", 1, RB_Status, 92, RB_STATUS, UseDefault); - AddField(Fields, "Rom Size", -1, RB_RomSize, 100, RB_ROMSIZE, UseDefault); - AddField(Fields, "Notes (Core)", 2, RB_CoreNotes, 120, RB_NOTES_CORE, UseDefault); - AddField(Fields, "Notes (default plugins)", 3, RB_PluginNotes, 188, RB_NOTES_PLUGIN, UseDefault); - AddField(Fields, "Notes (User)", -1, RB_UserNotes, 100, RB_NOTES_USER, UseDefault); - AddField(Fields, "Cartridge ID", -1, RB_CartridgeID, 100, RB_CART_ID, UseDefault); - AddField(Fields, "Manufacturer", -1, RB_Manufacturer, 100, RB_MANUFACTUER, UseDefault); - AddField(Fields, "Country", -1, RB_Country, 100, RB_COUNTRY, UseDefault); - AddField(Fields, "Developer", -1, RB_Developer, 100, RB_DEVELOPER, UseDefault); - AddField(Fields, "CRC1", -1, RB_Crc1, 100, RB_CRC1, UseDefault); - AddField(Fields, "CRC2", -1, RB_Crc2, 100, RB_CRC2, UseDefault); - AddField(Fields, "CIC Chip", -1, RB_CICChip, 100, RB_CICCHIP, UseDefault); - AddField(Fields, "Release Date", -1, RB_ReleaseDate, 100, RB_RELEASE_DATE, UseDefault); - AddField(Fields, "Genre", -1, RB_Genre, 100, RB_GENRE, UseDefault); - AddField(Fields, "Players", -1, RB_Players, 100, RB_PLAYERS, UseDefault); - AddField(Fields, "Force Feedback", -1, RB_ForceFeedback, 100, RB_FORCE_FEEDBACK, UseDefault); - AddField(Fields, "File Format", -1, RB_FileFormat, 100, RB_FILE_FORMAT, UseDefault); -} - -int32_t CRomBrowser::CalcSortPosition(uint32_t lParam) -{ - int32_t Start = 0; - int32_t End = ListView_GetItemCount(m_hRomList) - 1; - if (End < 0) - { - return 0; - } - - for (int32_t SortIndex = NoOfSortKeys; SortIndex >= 0; SortIndex--) - { - stdstr SortFieldName = g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, SortIndex); - if (SortFieldName.length() == 0) - { - continue; - } - - if (End == Start) - { - break; - } - - size_t index; - for (index = 0; index < m_Fields.size(); index++) - { - if (_stricmp(m_Fields[index].Name(), SortFieldName.c_str()) == 0) { break; } - } - if (index >= m_Fields.size()) { continue; } - SORT_FIELD SortFieldInfo; - SortFieldInfo._this = this; - SortFieldInfo.Key = index; - SortFieldInfo.KeyAscend = g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, SortIndex); - - //calc new start and end - int32_t LastTestPos = -1; - while (Start < End) - { - int32_t TestPos = (int32_t)floor((float)((Start + End) / 2)); - if (LastTestPos == TestPos) - { - TestPos += 1; - } - LastTestPos = TestPos; - - LVITEMW lvItem; - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_PARAM; - lvItem.iItem = TestPos; - if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) - { - return End; - } - - int32_t Result = RomList_CompareItems(lParam, lvItem.lParam, (uint32_t)&SortFieldInfo); - if (Result < 0) - { - if (End == TestPos) - { - break; - } - End = TestPos; - } - else if (Result > 0) - { - if (Start == TestPos) - { - break; - } - Start = TestPos; - } - else - { - //Find new start - float Left = (float)Start; - float Right = (float)TestPos; - while (Left < Right) - { - int32_t NewTestPos = (int32_t)floor((Left + Right) / 2); - if (LastTestPos == NewTestPos) - { - NewTestPos += 1; - } - LastTestPos = NewTestPos; - - LVITEMW lvItem; - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_PARAM; - lvItem.iItem = NewTestPos; - if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) - { - return End; - } - - int32_t Result = RomList_CompareItems(lParam, lvItem.lParam, (uint32_t)&SortFieldInfo); - if (Result <= 0) - { - if (Right == NewTestPos) - { - break; - } - Right = (float)NewTestPos; - } - else if (Result > 0) - { - Left = Left != (float)NewTestPos ? (float)NewTestPos : Left + 1; - } - } - Start = (int32_t)((float)Right); - - //Find new end - Left = (float)TestPos; - Right = (float)End; - while (Left < Right) - { - int32_t NewTestPos = (int32_t)ceil((Left + Right) / 2); - if (LastTestPos == NewTestPos) - { - NewTestPos -= 1; - } - LastTestPos = NewTestPos; - - LVITEMW lvItem; - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_PARAM; - lvItem.iItem = NewTestPos; - if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return End; } - - int32_t Result = RomList_CompareItems(lParam, lvItem.lParam, (uint32_t)&SortFieldInfo); - if (Result >= 0) - { - if (Left == NewTestPos) - { - break; - } - Left = (float)NewTestPos; - } - if (Result < 0) - { - Right = (float)NewTestPos; - } - } - End = (int32_t)Left; - break; - } - } - } - - //Compare end with item to see if we should do it after or before it - for (int32_t SortIndex = 0; SortIndex < NoOfSortKeys; SortIndex++) - { - stdstr SortFieldName = g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, SortIndex); - if (SortFieldName.length() == 0) - { - continue; - } - - size_t index; - for (index = 0; index < m_Fields.size(); index++) - { - if (_stricmp(m_Fields[index].Name(), SortFieldName.c_str()) == 0) { break; } - } - if (index >= m_Fields.size()) { continue; } - SORT_FIELD SortFieldInfo; - SortFieldInfo._this = this; - SortFieldInfo.Key = index; - SortFieldInfo.KeyAscend = g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, SortIndex) != 0; - - LVITEMW lvItem; - memset(&lvItem, 0, sizeof(LVITEMW)); - lvItem.mask = LVIF_PARAM; - lvItem.iItem = End; - if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return End; } - - int32_t Result = RomList_CompareItems(lParam, lvItem.lParam, (uint32_t)&SortFieldInfo); - if (Result < 0) - { - return End; - } - if (Result > 0) - { - return End + 1; - } - } - return End + 1; -} - -void CRomBrowser::AddRomToList(const char * RomLocation, const char * lpLastRom) -{ - ROM_INFO RomInfo; - - memset(&RomInfo, 0, sizeof(ROM_INFO)); - strncpy(RomInfo.szFullFileName, RomLocation, (sizeof(RomInfo.szFullFileName) / sizeof(RomInfo.szFullFileName[0])) - 1); - if (!FillRomInfo(&RomInfo)) { return; } - AddRomInfoToList(RomInfo, lpLastRom); -} - -void CRomBrowser::AddRomInfoToList(ROM_INFO &RomInfo, const char * lpLastRom) -{ - int32_t ListPos = m_RomInfo.size(); - m_RomInfo.push_back(RomInfo); - - LVITEMW lvItem; - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_TEXT | LVIF_PARAM; - lvItem.iItem = CalcSortPosition(ListPos); - lvItem.lParam = (LPARAM)ListPos; - lvItem.pszText = LPSTR_TEXTCALLBACKW; - - int32_t index = ListView_InsertItem(m_hRomList, &lvItem); - - int32_t iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); - //if (iItem == -1) { return; } - - //if the last rom then highlight the item - if (iItem < 0 && _stricmp(RomInfo.szFullFileName, lpLastRom) == 0) - { - ListView_SetItemState(m_hRomList, index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - } - - if (iItem >= 0) - { - ListView_EnsureVisible(m_hRomList, iItem, FALSE); - } -} - -void CRomBrowser::AllocateBrushs(void) -{ - for (size_t count = 0; count < m_RomInfo.size(); count++) - { - if (m_RomInfo[count].SelColor == -1) - { - m_RomInfo[count].SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1)); - } - else - { - m_RomInfo[count].SelColorBrush = (uint32_t)CreateSolidBrush(m_RomInfo[count].SelColor); - } - } -} - -void CRomBrowser::CreateRomListControl(void) -{ - m_hRomList = CreateWindowW(WC_LISTVIEWW, NULL, WS_TABSTOP | WS_VISIBLE | WS_CHILD | LVS_OWNERDRAWFIXED | LVS_SINGLESEL | LVS_REPORT, 0, 0, 0, 0, m_MainWindow, (HMENU)IDC_ROMLIST, GetModuleHandle(NULL), NULL); - ResetRomBrowserColomuns(); - LoadRomList(); -} - -void CRomBrowser::DeallocateBrushs(void) -{ - for (size_t count = 0; count < m_RomInfo.size(); count++) - { - if (m_RomInfo[count].SelColor == -1) - { - continue; - } - if (m_RomInfo[count].SelColorBrush) - { - DeleteObject((HBRUSH)m_RomInfo[count].SelColorBrush); - m_RomInfo[count].SelColorBrush = NULL; - } - } -} - -void CRomBrowser::FillRomExtensionInfo(ROM_INFO * pRomInfo) -{ - //Initialize the structure - pRomInfo->UserNotes[0] = 0; - pRomInfo->Developer[0] = 0; - pRomInfo->ReleaseDate[0] = 0; - pRomInfo->Genre[0] = 0; - pRomInfo->Players = 1; - pRomInfo->CoreNotes[0] = 0; - pRomInfo->PluginNotes[0] = 0; - wcscpy(pRomInfo->GoodName, L"#340#"); - wcscpy(pRomInfo->Status, L"Unknown"); - - //Get File Identifier - char Identifier[100]; - sprintf(Identifier, "%08X-%08X-C:%X", pRomInfo->CRC1, pRomInfo->CRC2, pRomInfo->Country); - - //Rom Notes - if (m_Fields[RB_UserNotes].Pos() >= 0) - { - wcsncpy(pRomInfo->UserNotes, m_NotesIniFile->GetString(Identifier, "Note", "").ToUTF16().c_str(), sizeof(pRomInfo->UserNotes) / sizeof(wchar_t)); - } - - //Rom Extension info - if (m_Fields[RB_Developer].Pos() >= 0) - { - wcsncpy(pRomInfo->Developer, m_ExtIniFile->GetString(Identifier, "Developer", "").ToUTF16().c_str(), sizeof(pRomInfo->Developer) / sizeof(wchar_t)); - } - if (m_Fields[RB_ReleaseDate].Pos() >= 0) - { - wcsncpy(pRomInfo->ReleaseDate, m_ExtIniFile->GetString(Identifier, "ReleaseDate", "").ToUTF16().c_str(), sizeof(pRomInfo->ReleaseDate) / sizeof(wchar_t)); - } - if (m_Fields[RB_Genre].Pos() >= 0) - { - wcsncpy(pRomInfo->Genre, m_ExtIniFile->GetString(Identifier, "Genre", "").ToUTF16().c_str(), sizeof(pRomInfo->Genre) / sizeof(wchar_t)); - } - if (m_Fields[RB_Players].Pos() >= 0) - { - m_ExtIniFile->GetNumber(Identifier, "Players", 1, (uint32_t &)pRomInfo->Players); - } - if (m_Fields[RB_ForceFeedback].Pos() >= 0) - { - wcsncpy(pRomInfo->ForceFeedback, m_ExtIniFile->GetString(Identifier, "ForceFeedback", "unknown").ToUTF16().c_str(), sizeof(pRomInfo->ForceFeedback) / sizeof(wchar_t)); - } - - //Rom Settings - if (m_Fields[RB_GoodName].Pos() >= 0) - { - wcsncpy(pRomInfo->GoodName, m_RomIniFile->GetString(Identifier, "Good Name", stdstr().FromUTF16(pRomInfo->GoodName).c_str()).ToUTF16().c_str(), sizeof(pRomInfo->GoodName) / sizeof(wchar_t)); - } - wcsncpy(pRomInfo->Status, m_RomIniFile->GetString(Identifier, "Status", stdstr().FromUTF16(pRomInfo->Status).c_str()).ToUTF16().c_str(), sizeof(pRomInfo->Status) / sizeof(wchar_t)); - if (m_Fields[RB_CoreNotes].Pos() >= 0) - { - wcsncpy(pRomInfo->CoreNotes, m_RomIniFile->GetString(Identifier, "Core Note", "").ToUTF16().c_str(), sizeof(pRomInfo->CoreNotes) / sizeof(wchar_t)); - } - if (m_Fields[RB_PluginNotes].Pos() >= 0) - { - wcsncpy(pRomInfo->PluginNotes, m_RomIniFile->GetString(Identifier, "Plugin Note", "").ToUTF16().c_str(), sizeof(pRomInfo->PluginNotes) / sizeof(wchar_t)); - } - - //Get the text color - stdstr String = m_RomIniFile->GetString("Rom Status", stdstr().FromUTF16(pRomInfo->Status).c_str(), "000000"); - pRomInfo->TextColor = (std::strtoul(String.c_str(), 0, 16) & 0xFFFFFF); - pRomInfo->TextColor = (pRomInfo->TextColor & 0x00FF00) | ((pRomInfo->TextColor >> 0x10) & 0xFF) | ((pRomInfo->TextColor & 0xFF) << 0x10); - - //Get the selected color - String.Format("%ws.Sel", pRomInfo->Status); - String = m_RomIniFile->GetString("Rom Status", String.c_str(), "FFFFFFFF"); - uint32_t selcol = std::strtoul(String.c_str(), NULL, 16); - if (selcol & 0x80000000) - { - pRomInfo->SelColor = -1; - } - else - { - selcol = (selcol & 0x00FF00) | ((selcol >> 0x10) & 0xFF) | ((selcol & 0xFF) << 0x10); - pRomInfo->SelColor = selcol; - } - - //Get the selected text color - String.Format("%ws.Seltext", pRomInfo->Status); - String = m_RomIniFile->GetString("Rom Status", String.c_str(), "FFFFFF"); - pRomInfo->SelTextColor = (std::strtoul(String.c_str(), 0, 16) & 0xFFFFFF); - pRomInfo->SelTextColor = (pRomInfo->SelTextColor & 0x00FF00) | ((pRomInfo->SelTextColor >> 0x10) & 0xFF) | ((pRomInfo->SelTextColor & 0xFF) << 0x10); -} - -bool CRomBrowser::FillRomInfo(ROM_INFO * pRomInfo) -{ - int32_t count; - uint8_t RomData[0x1000]; - - if (!LoadDataFromRomFile(pRomInfo->szFullFileName, RomData, sizeof(RomData), &pRomInfo->RomSize, pRomInfo->FileFormat)) - { - return false; - } - else - { - if (strstr(pRomInfo->szFullFileName, "?") != NULL) - { - strcpy(pRomInfo->FileName, strstr(pRomInfo->szFullFileName, "?") + 1); - } - else - { - strncpy(pRomInfo->FileName, CPath(pRomInfo->szFullFileName).GetNameExtension().c_str(), sizeof(pRomInfo->FileName) / sizeof(pRomInfo->FileName[0])); - } - if (m_Fields[RB_InternalName].Pos() >= 0) - { - char InternalName[22]; - memcpy(InternalName, (void *)(RomData + 0x20), 20); - for (count = 0; count < 20; count += 4) - { - InternalName[count] ^= InternalName[count + 3]; - InternalName[count + 3] ^= InternalName[count]; - InternalName[count] ^= InternalName[count + 3]; - InternalName[count + 1] ^= InternalName[count + 2]; - InternalName[count + 2] ^= InternalName[count + 1]; - InternalName[count + 1] ^= InternalName[count + 2]; - } - InternalName[20] = '\0'; - wcscpy(pRomInfo->InternalName, stdstr(InternalName).ToUTF16(stdstr::CODEPAGE_932).c_str()); - } - pRomInfo->CartID[0] = *(RomData + 0x3F); - pRomInfo->CartID[1] = *(RomData + 0x3E); - pRomInfo->CartID[2] = '\0'; - pRomInfo->Manufacturer = *(RomData + 0x38); - pRomInfo->Country = *(RomData + 0x3D); - pRomInfo->CRC1 = *(uint32_t *)(RomData + 0x10); - pRomInfo->CRC2 = *(uint32_t *)(RomData + 0x14); - pRomInfo->CicChip = GetCicChipID(RomData); - - FillRomExtensionInfo(pRomInfo); - - if (pRomInfo->SelColor == -1) - { - pRomInfo->SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1)); - } - else - { - pRomInfo->SelColorBrush = (uint32_t)CreateSolidBrush(pRomInfo->SelColor); - } - - return true; - } -} - -bool CRomBrowser::GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, bool InWatchThread) -{ - if (!BaseDirectory.DirectoryExists()) - { - return false; - } - CPath SearchPath(BaseDirectory, "*.*"); - SearchPath.AppendDirectory(Directory.c_str()); - - if (!SearchPath.FindFirst(CPath::_A_ALLFILES)) - { - return false; - } - - do - { - if (InWatchThread && WaitForSingleObject(m_WatchStopEvent, 0) != WAIT_TIMEOUT) - { - return false; - } - - if (SearchPath.IsDirectory()) - { - if (g_Settings->LoadDword(RomBrowser_Recursive)) - { - stdstr CurrentDir = Directory + SearchPath.GetLastDirectory() + "\\"; - GetRomFileNames(FileList, BaseDirectory, CurrentDir, InWatchThread); - } - } - else - { - AddFileNameToList(FileList, Directory, SearchPath); - } - } while (SearchPath.FindNext()); - return true; -} - -void CRomBrowser::NotificationCB(const char * Status, CRomBrowser * /*_this*/) -{ - g_Notify->DisplayMessage(5, Status); -} - -static const char* ROM_extensions[] = -{ - "zip", "7z", "v64", "z64", "n64", "rom", "jap", "pal", "usa", "eur", "bin", -}; - -void CRomBrowser::AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File) -{ - uint8_t i; - - if (FileList.size() > 3000) - { - return; - } - - stdstr Drive, Dir, Name, Extension; - File.GetComponents(NULL, &Dir, &Name, &Extension); - Extension.ToLower(); - for (i = 0; i < sizeof(ROM_extensions) / sizeof(ROM_extensions[0]); i++) - { - if (Extension == ROM_extensions[i]) - { - stdstr FileName = Directory + Name + Extension; - FileName.ToLower(); - FileList.push_back(FileName); - break; - } - } -} - -void CRomBrowser::FillRomList(strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, const char * lpLastRom) -{ - CPath SearchPath(BaseDirectory, "*.*"); - SearchPath.AppendDirectory(Directory.c_str()); - - WriteTrace(TraceUserInterface, TraceDebug, "1 %s", (const char *)SearchPath); - if (!SearchPath.FindFirst(CPath::_A_ALLFILES)) - { - return; - } - - do - { - uint8_t ext_ID; - int8_t new_list_entry = 0; - const uint8_t exts = sizeof(ROM_extensions) / sizeof(ROM_extensions[0]); - - WriteTrace(TraceUserInterface, TraceDebug, ": 2 %s m_StopRefresh = %d", (const char *)SearchPath, m_StopRefresh); - if (m_StopRefresh) { break; } - - if (SearchPath.IsDirectory()) - { - if (g_Settings->LoadDword(RomBrowser_Recursive)) - { - stdstr CurrentDir = Directory + SearchPath.GetLastDirectory() + "\\"; - FillRomList(FileList, BaseDirectory, CurrentDir, lpLastRom); - } - continue; - } - - AddFileNameToList(FileList, Directory, SearchPath); - - stdstr Extension = SearchPath.GetExtension(); - Extension.ToLower(); - - for (ext_ID = 0; ext_ID < exts; ext_ID++) - { - if (Extension == ROM_extensions[ext_ID] && Extension != "7z") - { - new_list_entry = 1; - break; - } - } - if (new_list_entry) - { - AddRomToList(SearchPath, lpLastRom); - continue; - } - - if (Extension == "7z") - { - try - { - C7zip ZipFile(SearchPath); - if (!ZipFile.OpenSuccess()) - { - continue; - } - char ZipFileName[260]; - stdstr_f SectionName("%s-%d", ZipFile.FileName(ZipFileName, sizeof(ZipFileName)), ZipFile.FileSize()); - SectionName.ToLower(); - - WriteTrace(TraceUserInterface, TraceDebug, "4 %s", SectionName.c_str()); - for (int32_t i = 0; i < ZipFile.NumFiles(); i++) - { - CSzFileItem * f = ZipFile.FileItem(i); - if (f->IsDir) - { - continue; - } - ROM_INFO RomInfo; - - std::wstring FileNameW = ZipFile.FileNameIndex(i); - if (FileNameW.length() == 0) - { - continue; - } - - stdstr FileName; - FileName.FromUTF16(FileNameW.c_str()); - WriteTrace(TraceUserInterface, TraceDebug, "5"); - char drive2[_MAX_DRIVE], dir2[_MAX_DIR], FileName2[MAX_PATH], ext2[_MAX_EXT]; - _splitpath(FileName.c_str(), drive2, dir2, FileName2, ext2); - - WriteTrace(TraceUserInterface, TraceDebug, ": 6 %s", ext2); - if (_stricmp(ext2, ".bin") == 0) - { - continue; - } - WriteTrace(TraceUserInterface, TraceDebug, "7"); - memset(&RomInfo, 0, sizeof(ROM_INFO)); - stdstr_f zipFileName("%s?%s", (LPCSTR)SearchPath, FileName.c_str()); - ZipFile.SetNotificationCallback((C7zip::LP7ZNOTIFICATION)NotificationCB, this); - - strncpy(RomInfo.szFullFileName, zipFileName.c_str(), sizeof(RomInfo.szFullFileName) - 1); - RomInfo.szFullFileName[sizeof(RomInfo.szFullFileName) - 1] = 0; - strcpy(RomInfo.FileName, strstr(RomInfo.szFullFileName, "?") + 1); - RomInfo.FileFormat = Format_7zip; - - WriteTrace(TraceUserInterface, TraceDebug, "8"); - char szHeader[0x90]; - if (m_ZipIniFile->GetString(SectionName.c_str(), FileName.c_str(), "", szHeader, sizeof(szHeader)) == 0) - { - uint8_t RomData[0x1000]; - if (!ZipFile.GetFile(i, RomData, sizeof(RomData))) - { - continue; - } - WriteTrace(TraceUserInterface, TraceDebug, "9"); - if (!CN64Rom::IsValidRomImage(RomData)) { continue; } - WriteTrace(TraceUserInterface, TraceDebug, "10"); - ByteSwapRomData(RomData, sizeof(RomData)); - WriteTrace(TraceUserInterface, TraceDebug, "11"); - - stdstr RomHeader; - for (int32_t x = 0; x < 0x40; x += 4) - { - RomHeader += stdstr_f("%08X", *((uint32_t *)&RomData[x])); - } - WriteTrace(TraceUserInterface, TraceDebug, "11a %s", RomHeader.c_str()); - int32_t CicChip = GetCicChipID(RomData); - - //save this info - WriteTrace(TraceUserInterface, TraceDebug, "12"); - m_ZipIniFile->SaveString(SectionName.c_str(), FileName.c_str(), RomHeader.c_str()); - m_ZipIniFile->SaveNumber(SectionName.c_str(), stdstr_f("%s-Cic", FileName.c_str()).c_str(), CicChip); - strcpy(szHeader, RomHeader.c_str()); - } - WriteTrace(TraceUserInterface, TraceDebug, "13"); - uint8_t RomData[0x40]; - - for (int32_t x = 0; x < 0x40; x += 4) - { - const size_t delimit_offset = sizeof("FFFFFFFF") - 1; - const char backup_character = szHeader[2 * x + delimit_offset]; - - szHeader[2 * x + delimit_offset] = '\0'; - *(uint32_t *)&RomData[x] = std::strtoul(&szHeader[2 * x], NULL, 16); - szHeader[2 * x + delimit_offset] = backup_character; - } - - WriteTrace(TraceUserInterface, TraceDebug, "14"); - { - char InternalName[22]; - memcpy(InternalName, (void *)(RomData + 0x20), 20); - for (int32_t count = 0; count < 20; count += 4) - { - InternalName[count] ^= InternalName[count + 3]; - InternalName[count + 3] ^= InternalName[count]; - InternalName[count] ^= InternalName[count + 3]; - InternalName[count + 1] ^= InternalName[count + 2]; - InternalName[count + 2] ^= InternalName[count + 1]; - InternalName[count + 1] ^= InternalName[count + 2]; - } - InternalName[20] = '\0'; - wcscpy(RomInfo.InternalName, stdstr(InternalName).ToUTF16(stdstr::CODEPAGE_932).c_str()); - } - RomInfo.RomSize = (int32_t)f->Size; - - WriteTrace(TraceUserInterface, TraceDebug, "15"); - RomInfo.CartID[0] = *(RomData + 0x3F); - RomInfo.CartID[1] = *(RomData + 0x3E); - RomInfo.CartID[2] = '\0'; - RomInfo.Manufacturer = *(RomData + 0x38); - RomInfo.Country = *(RomData + 0x3D); - RomInfo.CRC1 = *(uint32_t *)(RomData + 0x10); - RomInfo.CRC2 = *(uint32_t *)(RomData + 0x14); - m_ZipIniFile->GetNumber(SectionName.c_str(), stdstr_f("%s-Cic", FileName.c_str()).c_str(), (ULONG)-1, (uint32_t &)RomInfo.CicChip); - WriteTrace(TraceUserInterface, TraceDebug, "16"); - FillRomExtensionInfo(&RomInfo); - - if (RomInfo.SelColor == -1) - { - RomInfo.SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1)); - } - else - { - RomInfo.SelColorBrush = (uint32_t)CreateSolidBrush(RomInfo.SelColor); - } - WriteTrace(TraceUserInterface, TraceDebug, "17"); - AddRomInfoToList(RomInfo, lpLastRom); - } - } - catch (...) - { - WriteTrace(TraceUserInterface, TraceError, "execpetion processing %s", (LPCSTR)SearchPath); - } - continue; - } - } while (SearchPath.FindNext()); - m_ZipIniFile->FlushChanges(); -} - -int32_t CRomBrowser::GetCicChipID(uint8_t * RomData) -{ - __int64 CRC = 0; - int32_t count; - - for (count = 0x40; count < 0x1000; count += 4) - { - CRC += *(uint32_t *)(RomData + count); - } - switch (CRC) - { - case 0x000000D0027FDF31: return CIC_NUS_6101; - case 0x000000CFFB631223: return CIC_NUS_6101; - case 0x000000D057C85244: return CIC_NUS_6102; - case 0x000000D6497E414B: return CIC_NUS_6103; - case 0x0000011A49F60E96: return CIC_NUS_6105; - case 0x000000D6D5BE5580: return CIC_NUS_6106; - case 0x000001053BC19870: return CIC_NUS_5167; //64DD CONVERSION CIC - case 0x000000D2E53EF008: return CIC_NUS_8303; //64DD IPL - default: - return CIC_UNKNOWN; - } -} - -void CRomBrowser::HighLightLastRom(void) -{ - if (!m_AllowSelectionLastRom) - { - return; - } - //Make sure Rom browser is visible - if (!RomBrowserVisible()) { return; } - - //Get the string to the last rom - stdstr LastRom = g_Settings->LoadStringIndex(File_RecentGameFileIndex, 0); - LPCSTR lpLastRom = LastRom.c_str(); - - LVITEMW lvItem; - lvItem.mask = LVIF_PARAM; - - int32_t ItemCount = ListView_GetItemCount(m_hRomList); - for (int32_t index = 0; index < ItemCount; index++) - { - //Get The next item - lvItem.iItem = index; - if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return; } - - //Get the rom info for that item - if (lvItem.lParam < 0 || lvItem.lParam >= (LPARAM)m_RomInfo.size()) - { - return; - } - ROM_INFO * pRomInfo = &m_RomInfo[lvItem.lParam]; - - if (!m_AllowSelectionLastRom) - { - return; - } - - //if the last rom then highlight the item - if (_stricmp(pRomInfo->szFullFileName, lpLastRom) == 0) - { - ListView_SetItemState(m_hRomList, index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - ListView_EnsureVisible(m_hRomList, index, FALSE); - return; - } - } -} - -bool CRomBrowser::LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat) -{ - uint8_t Test[4]; - - if (_strnicmp(&FileName[strlen(FileName) - 4], ".ZIP", 4) == 0) - { - int32_t len, port = 0, FoundRom; - unz_file_info info; - char zname[132]; - unzFile file; - file = unzOpen(FileName); - if (file == NULL) { return false; } - - port = unzGoToFirstFile(file); - FoundRom = FALSE; - while (port == UNZ_OK && FoundRom == FALSE) - { - unzGetCurrentFileInfo(file, &info, zname, 128, NULL, 0, NULL, 0); - if (unzLocateFile(file, zname, 1) != UNZ_OK) - { - unzClose(file); - return true; - } - if (unzOpenCurrentFile(file) != UNZ_OK) - { - unzClose(file); - return true; - } - unzReadCurrentFile(file, Test, 4); - if (CN64Rom::IsValidRomImage(Test)) - { - FoundRom = true; - memcpy(Data, Test, 4); - len = unzReadCurrentFile(file, &Data[4], DataLen - 4) + 4; - - if ((int32_t)DataLen != len) - { - unzCloseCurrentFile(file); - unzClose(file); - return false; - } - *RomSize = info.uncompressed_size; - if (unzCloseCurrentFile(file) == UNZ_CRCERROR) - { - unzClose(file); - return false; - } - unzClose(file); - } - if (FoundRom == false) - { - unzCloseCurrentFile(file); - port = unzGoToNextFile(file); - } - } - if (FoundRom == false) - { - return false; - } - FileFormat = Format_Zip; - } - else - { - HANDLE hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); - if (hFile == INVALID_HANDLE_VALUE) { return false; } - SetFilePointer(hFile, 0, 0, FILE_BEGIN); - - DWORD dwRead; - ReadFile(hFile, Test, 4, &dwRead, NULL); - if (!CN64Rom::IsValidRomImage(Test)) { CloseHandle(hFile); return false; } - SetFilePointer(hFile, 0, 0, FILE_BEGIN); - if (!ReadFile(hFile, Data, DataLen, &dwRead, NULL)) { CloseHandle(hFile); return false; } - *RomSize = GetFileSize(hFile, NULL); - CloseHandle(hFile); - FileFormat = Format_Uncompressed; - } - ByteSwapRomData(Data, DataLen); - return true; -} - -void CRomBrowser::ByteSwapRomData(uint8_t * Data, int32_t DataLen) -{ - int32_t count; - - switch (*((uint32_t *)&Data[0])) - { - case 0x12408037: - for (count = 0; count < DataLen; count += 4) - { - Data[count] ^= Data[count + 2]; - Data[count + 2] ^= Data[count]; - Data[count] ^= Data[count + 2]; - Data[count + 1] ^= Data[count + 3]; - Data[count + 3] ^= Data[count + 1]; - Data[count + 1] ^= Data[count + 3]; - } - break; - case 0x40072780: //64DD IPL - case 0x40123780: - for (count = 0; count < DataLen; count += 4) - { - Data[count] ^= Data[count + 3]; - Data[count + 3] ^= Data[count]; - Data[count] ^= Data[count + 3]; - Data[count + 1] ^= Data[count + 2]; - Data[count + 2] ^= Data[count + 1]; - Data[count + 1] ^= Data[count + 2]; - } - break; - case 0x80371240: break; - } -} - -void CRomBrowser::LoadRomList(void) -{ - stdstr FileName = g_Settings->LoadStringVal(SupportFile_RomListCache); - - //Open the cache file - HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - //if file does not exist then refresh the data - RefreshRomBrowser(); - return; - } - - DWORD dwRead; - unsigned char md5[16]; - ReadFile(hFile, &md5, sizeof(md5), &dwRead, NULL); - - //Read the size of ROM_INFO - int32_t RomInfoSize = 0; - ReadFile(hFile, &RomInfoSize, sizeof(RomInfoSize), &dwRead, NULL); - if (RomInfoSize != sizeof(ROM_INFO) || dwRead != sizeof(RomInfoSize)) - { - CloseHandle(hFile); - RefreshRomBrowser(); - return; - } - - //Read the Number of entries - int32_t Entries = 0; - ReadFile(hFile, &Entries, sizeof(Entries), &dwRead, NULL); - - //Read Every Entry - DeallocateBrushs(); - m_RomInfo.clear(); - for (int32_t count = 0; count < Entries; count++) - { - ROM_INFO RomInfo; - ReadFile(hFile, &RomInfo, RomInfoSize, &dwRead, NULL); - RomInfo.SelColorBrush = NULL; - - LVITEMW lvItem; - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_TEXT | LVIF_PARAM; - lvItem.iItem = ListView_GetItemCount(m_hRomList); - lvItem.lParam = (LPARAM)m_RomInfo.size(); - lvItem.pszText = LPSTR_TEXTCALLBACKW; - - SendMessageW(m_hRomList, LVM_INSERTITEMW, 0, (LPARAM)&lvItem); - m_RomInfo.push_back(RomInfo); - } - CloseHandle(hFile); - AllocateBrushs(); - RomList_SortList(); -} - -void CRomBrowser::MenuSetText(HMENU hMenu, int32_t MenuPos, const wchar_t * Title, char * ShortCut) -{ - MENUITEMINFOW MenuInfo; - wchar_t String[256]; - - if (Title == NULL || wcslen(Title) == 0) { return; } - - memset(&MenuInfo, 0, sizeof(MENUITEMINFO)); - MenuInfo.cbSize = sizeof(MENUITEMINFO); - MenuInfo.fMask = MIIM_TYPE; - MenuInfo.fType = MFT_STRING; - MenuInfo.fState = MFS_ENABLED; - MenuInfo.dwTypeData = String; - MenuInfo.cch = 256; - - GetMenuItemInfoW(hMenu, MenuPos, TRUE, &MenuInfo); - wcscpy(String, Title); - if (wcschr(String, '\t') != NULL) { *(wcschr(String, '\t')) = '\0'; } - if (ShortCut) { swprintf(String, sizeof(String) / sizeof(String[0]), L"%s\t%s", String, ShortCut); } - SetMenuItemInfoW(hMenu, MenuPos, TRUE, &MenuInfo); -} - -void CRomBrowser::RefreshRomBrowser(void) -{ - DWORD ThreadID; - - if (m_RefreshThread) - { - return; - } - WriteTrace(TraceUserInterface, TraceDebug, "1"); - m_StopRefresh = false; - m_RefreshThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RefreshRomBrowserStatic, (LPVOID)this, 0, &ThreadID); - WriteTrace(TraceUserInterface, TraceDebug, "2"); -} - -void CRomBrowser::RefreshRomBrowserStatic(CRomBrowser * _this) -{ - try - { - if (_this->m_hRomList == NULL) { return; } - - //delete cache - stdstr CacheFileName = g_Settings->LoadStringVal(SupportFile_RomListCache); - DeleteFile(CacheFileName.c_str()); - - //clear all current items - WriteTrace(TraceUserInterface, TraceDebug, "1"); - ListView_DeleteAllItems((HWND)_this->m_hRomList); - _this->DeallocateBrushs(); - _this->m_RomInfo.clear(); - WriteTrace(TraceUserInterface, TraceDebug, "2"); - InvalidateRect((HWND)_this->m_hRomList, NULL, TRUE); - Sleep(100); - WriteTrace(TraceUserInterface, TraceDebug, "3"); - - if (_this->m_WatchRomDir != g_Settings->LoadStringVal(Directory_Game)) - { - WriteTrace(TraceUserInterface, TraceDebug, "4"); - _this->WatchThreadStop(); - WriteTrace(TraceUserInterface, TraceDebug, "5"); - _this->WatchThreadStart(); - WriteTrace(TraceUserInterface, TraceDebug, "6"); - } - - WriteTrace(TraceUserInterface, TraceDebug, "7"); - stdstr RomDir = g_Settings->LoadStringVal(Directory_Game); - stdstr LastRom = g_Settings->LoadStringIndex(File_RecentGameFileIndex, 0); - WriteTrace(TraceUserInterface, TraceDebug, "8"); - - strlist FileNames; - _this->FillRomList(FileNames, CPath(RomDir), stdstr(""), LastRom.c_str()); - WriteTrace(TraceUserInterface, TraceDebug, "9"); - _this->SaveRomList(FileNames); - WriteTrace(TraceUserInterface, TraceDebug, "10"); - CloseHandle(_this->m_RefreshThread); - _this->m_RefreshThread = NULL; - WriteTrace(TraceUserInterface, TraceDebug, "11"); - } - catch (...) - { - WriteTrace(TraceUserInterface, TraceError, "Unhandled Exception "); - } -} - -void CRomBrowser::ResetRomBrowserColomuns(void) -{ - size_t Coloumn, index; - LV_COLUMNW lvColumn; - wchar_t szString[300]; - - GetFieldInfo(m_Fields); - - //Remove all current coloumns - memset(&lvColumn, 0, sizeof(lvColumn)); - lvColumn.mask = LVCF_FMT; - while (ListView_GetColumn(m_hRomList, 0, &lvColumn)) - { - ListView_DeleteColumn(m_hRomList, 0); - } - - //Add Colomuns - lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - lvColumn.fmt = LVCFMT_LEFT; - lvColumn.pszText = szString; - - for (Coloumn = 0; Coloumn < m_Fields.size(); Coloumn++) - { - for (index = 0; index < m_Fields.size(); index++) - { - if (m_Fields[index].Pos() == Coloumn) { break; } - } - if (index == m_Fields.size() || m_Fields[index].Pos() != Coloumn) - { - m_FieldType[Coloumn] = -1; - break; - } - - m_FieldType[Coloumn] = m_Fields[index].ID(); - lvColumn.cx = m_Fields[index].ColWidth(); - wcsncpy(szString, wGS(m_Fields[index].LangID()).c_str(), sizeof(szString) / sizeof(szString[0])); - SendMessage(m_hRomList, LVM_INSERTCOLUMNW, (WPARAM)(int32_t)(Coloumn), (LPARAM)(const LV_COLUMNW *)(&lvColumn)); - } -} - -void CRomBrowser::ResizeRomList(WORD nWidth, WORD nHeight) -{ - if (RomBrowserVisible()) - { - if (g_Settings->LoadDword(RomBrowser_Maximized) == 0 && nHeight != 0) - { - if (g_Settings->LoadDword(RomBrowser_Width) != nWidth) - { - g_Settings->SaveDword(RomBrowser_Width, nWidth); - } - if (g_Settings->LoadDword(RomBrowser_Height) != nHeight) - { - g_Settings->SaveDword(RomBrowser_Height, nHeight); - } - } - if (IsWindow((HWND)m_StatusWindow)) - { - RECT rc; - - GetWindowRect((HWND)m_StatusWindow, &rc); - nHeight -= (WORD)(rc.bottom - rc.top); - } - MoveWindow(m_hRomList, 0, 0, nWidth, nHeight, TRUE); - } -} - -bool CRomBrowser::RomBrowserVisible(void) -{ - if (!IsWindow(m_hRomList)) { return false; } - if (!IsWindowVisible(m_hRomList)) { return false; } - if (!m_Visible) { return false; } - return true; -} - -void CRomBrowser::RomBrowserToTop(void) -{ - BringWindowToTop(m_hRomList); - SetFocus(m_hRomList); -} - -void CRomBrowser::RomBrowserMaximize(bool Mazimize) -{ - g_Settings->SaveDword(RomBrowser_Maximized, (uint32_t)Mazimize); -} - -bool CRomBrowser::RomListDrawItem(int32_t idCtrl, uint32_t lParam) -{ - if (idCtrl != IDC_ROMLIST) { return false; } - LPDRAWITEMSTRUCT ditem = (LPDRAWITEMSTRUCT)lParam; - - RECT rcItem, rcDraw; - wchar_t String[300]; - LVITEMW lvItem; - HBRUSH hBrush; - LV_COLUMN lvc; - int32_t nColumn; - - lvItem.mask = LVIF_PARAM; - lvItem.iItem = ditem->itemID; - if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return false; } - lvItem.state = ListView_GetItemState(m_hRomList, ditem->itemID, -1); - bool bSelected = (lvItem.state & LVIS_SELECTED) != 0; - - if (lvItem.lParam < 0 || lvItem.lParam >= (LPARAM)m_RomInfo.size()) - { - return true; - } - ROM_INFO * pRomInfo = &m_RomInfo[lvItem.lParam]; - if (pRomInfo == NULL) - { - return true; - } - if (bSelected) - { - hBrush = (HBRUSH)pRomInfo->SelColorBrush; - SetTextColor(ditem->hDC, pRomInfo->SelTextColor); - } - else - { - hBrush = (HBRUSH)(COLOR_WINDOW + 1); - SetTextColor(ditem->hDC, pRomInfo->TextColor); - } - FillRect(ditem->hDC, &ditem->rcItem, hBrush); - SetBkMode(ditem->hDC, TRANSPARENT); - - //Draw - ListView_GetItemRect(m_hRomList, ditem->itemID, &rcItem, LVIR_LABEL); - lvItem.iSubItem = 0; - lvItem.cchTextMax = sizeof(String) / sizeof(String[0]); - lvItem.pszText = String; - SendMessageW(m_hRomList, LVM_GETITEMTEXTW, (WPARAM)ditem->itemID, (LPARAM)&lvItem); - - memcpy(&rcDraw, &rcItem, sizeof(RECT)); - rcDraw.right -= 3; - std::wstring text = String; - if (wcscmp(L"#340#", text.c_str()) == 0) - { - text = wGS(RB_NOT_GOOD_FILE); - } - - DrawTextW(ditem->hDC, text.c_str(), text.length(), &rcDraw, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_WORD_ELLIPSIS); - - memset(&lvc, 0, sizeof(lvc)); - lvc.mask = LVCF_FMT | LVCF_WIDTH; - for (nColumn = 1; ListView_GetColumn(m_hRomList, nColumn, &lvc); nColumn += 1) - { - rcItem.left = rcItem.right; - rcItem.right += lvc.cx; - - lvItem.iSubItem = nColumn; - lvItem.cchTextMax = sizeof(String) / sizeof(String[0]); - lvItem.pszText = String; - SendMessageW(m_hRomList, LVM_GETITEMTEXTW, ditem->itemID, (LPARAM)&lvItem); - memcpy(&rcDraw, &rcItem, sizeof(RECT)); - rcDraw.right -= 3; - text = String; - if (wcscmp(L"#340#", text.c_str()) == 0) - { - text = wGS(RB_NOT_GOOD_FILE); - } - DrawTextW(ditem->hDC, text.c_str(), text.length(), &rcDraw, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_WORD_ELLIPSIS); - } - return true; -} - -bool CRomBrowser::RomListNotify(int32_t idCtrl, uint32_t pnmh) -{ - if (idCtrl != IDC_ROMLIST) { return false; } - if (!RomBrowserVisible()) { return false; } - - switch (((LPNMHDR)pnmh)->code) - { - case LVN_COLUMNCLICK: RomList_ColoumnSortList(pnmh); break; - case NM_RETURN: RomList_OpenRom(pnmh); break; - case NM_DBLCLK: RomList_OpenRom(pnmh); break; - case LVN_GETDISPINFOW: RomList_GetDispInfo(pnmh); break; - case NM_RCLICK: RomList_PopupMenu(pnmh); break; - case NM_CLICK: - { - LONG iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); - if (iItem != -1) - { - m_AllowSelectionLastRom = false; - } - } - break; - default: - return false; - } - return true; -} - -void CRomBrowser::RomList_ColoumnSortList(uint32_t pnmh) -{ - LPNMLISTVIEW pnmv = (LPNMLISTVIEW)pnmh; - size_t index; - - for (index = 0; index < m_Fields.size(); index++) - { - if (m_Fields[index].Pos() == (size_t)pnmv->iSubItem) { break; } - } - if (m_Fields.size() == index) { return; } - if (_stricmp(g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, 0).c_str(), m_Fields[index].Name()) == 0) - { - g_Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex, 0, !g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, 0)); - } - else - { - int32_t count; - - for (count = NoOfSortKeys; count > 0; count--) - { - g_Settings->SaveStringIndex(RomBrowser_SortFieldIndex, count, g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, count - 1).c_str()); - g_Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex, count, g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, count - 1)); - } - g_Settings->SaveStringIndex(RomBrowser_SortFieldIndex, 0, m_Fields[index].Name()); - g_Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex, 0, true); - } - RomList_SortList(); -} - -int32_t CALLBACK CRomBrowser::RomList_CompareItems(uint32_t lParam1, uint32_t lParam2, uint32_t lParamSort) -{ - SORT_FIELD * SortFieldInfo = (SORT_FIELD *)lParamSort; - CRomBrowser * _this = SortFieldInfo->_this; - if (lParam1 < 0 || lParam1 >= _this->m_RomInfo.size()) - { - return 0; - } - if (lParam2 < 0 || lParam2 >= _this->m_RomInfo.size()) - { - return 0; - } - ROM_INFO * pRomInfo1 = &_this->m_RomInfo[SortFieldInfo->KeyAscend ? lParam1 : lParam2]; - ROM_INFO * pRomInfo2 = &_this->m_RomInfo[SortFieldInfo->KeyAscend ? lParam2 : lParam1]; - int32_t result; - - const wchar_t * GoodName1 = NULL, *GoodName2 = NULL; - if (SortFieldInfo->Key == RB_GoodName) - { - GoodName1 = wcscmp(L"#340#", pRomInfo1->GoodName) != 0 ? pRomInfo1->GoodName : m_UnknownGoodName.c_str(); - GoodName2 = wcscmp(L"#340#", pRomInfo2->GoodName) != 0 ? pRomInfo2->GoodName : m_UnknownGoodName.c_str(); - } - - switch (SortFieldInfo->Key) - { - case RB_FileName: result = (int32_t)lstrcmpi(pRomInfo1->FileName, pRomInfo2->FileName); break; - case RB_InternalName: result = (int32_t)lstrcmpiW(pRomInfo1->InternalName, pRomInfo2->InternalName); break; - case RB_GoodName: result = (int32_t)lstrcmpiW(GoodName1, GoodName2); break; - case RB_Status: result = (int32_t)lstrcmpiW(pRomInfo1->Status, pRomInfo2->Status); break; - case RB_RomSize: result = (int32_t)pRomInfo1->RomSize - (int32_t)pRomInfo2->RomSize; break; - case RB_CoreNotes: result = (int32_t)lstrcmpiW(pRomInfo1->CoreNotes, pRomInfo2->CoreNotes); break; - case RB_PluginNotes: result = (int32_t)lstrcmpiW(pRomInfo1->PluginNotes, pRomInfo2->PluginNotes); break; - case RB_UserNotes: result = (int32_t)lstrcmpiW(pRomInfo1->UserNotes, pRomInfo2->UserNotes); break; - case RB_CartridgeID: result = (int32_t)lstrcmpiW(pRomInfo1->CartID, pRomInfo2->CartID); break; - case RB_Manufacturer: result = (int32_t)pRomInfo1->Manufacturer - (int32_t)pRomInfo2->Manufacturer; break; - case RB_Country: result = (int32_t)pRomInfo1->Country - (int32_t)pRomInfo2->Country; break; - case RB_Developer: result = (int32_t)lstrcmpiW(pRomInfo1->Developer, pRomInfo2->Developer); break; - case RB_Crc1: result = (int32_t)pRomInfo1->CRC1 - (int32_t)pRomInfo2->CRC1; break; - case RB_Crc2: result = (int32_t)pRomInfo1->CRC2 - (int32_t)pRomInfo2->CRC2; break; - case RB_CICChip: result = (int32_t)pRomInfo1->CicChip - (int32_t)pRomInfo2->CicChip; break; - case RB_ReleaseDate: result = (int32_t)lstrcmpiW(pRomInfo1->ReleaseDate, pRomInfo2->ReleaseDate); break; - case RB_Players: result = (int32_t)pRomInfo1->Players - (int32_t)pRomInfo2->Players; break; - case RB_ForceFeedback: result = (int32_t)lstrcmpiW(pRomInfo1->ForceFeedback, pRomInfo2->ForceFeedback); break; - case RB_Genre: result = (int32_t)lstrcmpiW(pRomInfo1->Genre, pRomInfo2->Genre); break; - case RB_FileFormat: result = (int32_t)pRomInfo1->FileFormat - (int32_t)pRomInfo2->FileFormat; break; - default: result = 0; break; - } - return result; -} - -void CRomBrowser::RomList_GetDispInfo(uint32_t pnmh) -{ - LV_DISPINFOW * lpdi = (LV_DISPINFOW *)pnmh; - if (lpdi->item.lParam < 0 || lpdi->item.lParam >= (LPARAM)m_RomInfo.size()) - { - return; - } - - ROM_INFO * pRomInfo = &m_RomInfo[lpdi->item.lParam]; - - if (pRomInfo == NULL) - { - wcscpy(lpdi->item.pszText, L" "); - return; - } - - switch (m_FieldType[lpdi->item.iSubItem]) - { - case RB_FileName: wcsncpy(lpdi->item.pszText, stdstr(pRomInfo->FileName).ToUTF16(CP_ACP).c_str(), lpdi->item.cchTextMax); break; - case RB_InternalName: wcsncpy(lpdi->item.pszText, pRomInfo->InternalName, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_GoodName: wcsncpy(lpdi->item.pszText, pRomInfo->GoodName, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_CoreNotes: wcsncpy(lpdi->item.pszText, pRomInfo->CoreNotes, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_PluginNotes: wcsncpy(lpdi->item.pszText, pRomInfo->PluginNotes, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_Status: wcsncpy(lpdi->item.pszText, pRomInfo->Status, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_RomSize: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"%.1f MBit", (float)pRomInfo->RomSize / 0x20000); break; - case RB_CartridgeID: wcsncpy(lpdi->item.pszText, pRomInfo->CartID, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_Manufacturer: - switch (pRomInfo->Manufacturer) - { - case 'N':wcsncpy(lpdi->item.pszText, L"Nintendo", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 0: wcsncpy(lpdi->item.pszText, L"None", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - default: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"(Unknown %c (%X))", pRomInfo->Manufacturer, pRomInfo->Manufacturer); break; - } - break; - case RB_Country: - switch (pRomInfo->Country) - { - case '7': wcsncpy(lpdi->item.pszText, L"Beta", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'A': wcsncpy(lpdi->item.pszText, L"NTSC", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'D': wcsncpy(lpdi->item.pszText, L"Germany", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'E': wcsncpy(lpdi->item.pszText, L"America", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'F': wcsncpy(lpdi->item.pszText, L"France", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'J': wcsncpy(lpdi->item.pszText, L"Japan", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'I': wcsncpy(lpdi->item.pszText, L"Italy", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'P': wcsncpy(lpdi->item.pszText, L"Europe", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'S': wcsncpy(lpdi->item.pszText, L"Spain", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'U': wcsncpy(lpdi->item.pszText, L"Australia", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'X': wcsncpy(lpdi->item.pszText, L"PAL", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 'Y': wcsncpy(lpdi->item.pszText, L"PAL", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case 0: wcsncpy(lpdi->item.pszText, L"None", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - default: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"Unknown %c (%02X)", pRomInfo->Country, pRomInfo->Country); break; - } - break; - case RB_Crc1: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"0x%08X", pRomInfo->CRC1); break; - case RB_Crc2: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"0x%08X", pRomInfo->CRC2); break; - case RB_CICChip: - if (pRomInfo->CicChip < 0) - { - swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"Unknown CIC Chip"); - } - else if (pRomInfo->CicChip == CIC_NUS_8303) - { - swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"CIC-NUS-8303", pRomInfo->CicChip); - } - else if (pRomInfo->CicChip == CIC_NUS_5167) - { - swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"CIC-NUS-5167", pRomInfo->CicChip); - } - else - { - swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"CIC-NUS-610%d", pRomInfo->CicChip); - } - break; - case RB_UserNotes: wcsncpy(lpdi->item.pszText, pRomInfo->UserNotes, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_Developer: wcsncpy(lpdi->item.pszText, pRomInfo->Developer, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_ReleaseDate: wcsncpy(lpdi->item.pszText, pRomInfo->ReleaseDate, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_Genre: wcsncpy(lpdi->item.pszText, pRomInfo->Genre, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_Players: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"%d", pRomInfo->Players); break; - case RB_ForceFeedback: wcsncpy(lpdi->item.pszText, pRomInfo->ForceFeedback, lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case RB_FileFormat: - switch (pRomInfo->FileFormat) - { - case Format_Uncompressed: wcsncpy(lpdi->item.pszText, L"Uncompressed", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case Format_Zip: wcsncpy(lpdi->item.pszText, L"Zip", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - case Format_7zip: wcsncpy(lpdi->item.pszText, L"7zip", lpdi->item.cchTextMax / sizeof(wchar_t)); break; - default: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"Unknown (%X)", pRomInfo->FileFormat); break; - } - break; - default: wcsncpy(lpdi->item.pszText, L" ", lpdi->item.cchTextMax); - } - if (lpdi->item.pszText == NULL || wcslen(lpdi->item.pszText) == 0) { lpdi->item.pszText = L" "; } -} - -void CRomBrowser::RomList_OpenRom(uint32_t /*pnmh*/) -{ - ROM_INFO * pRomInfo; - LV_ITEM lvItem; - LONG iItem; - - iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); - if (iItem == -1) { return; } - - memset(&lvItem, 0, sizeof(LV_ITEM)); - lvItem.mask = LVIF_PARAM; - lvItem.iItem = iItem; - if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return; } - if (lvItem.lParam < 0 || lvItem.lParam >= (LPARAM)m_RomInfo.size()) - { - return; - } - pRomInfo = &m_RomInfo[lvItem.lParam]; - - if (!pRomInfo) { return; } - m_StopRefresh = true; - - delete g_DDRom; - g_DDRom = NULL; - - CN64System::RunFileImage(pRomInfo->szFullFileName); -} - -void CRomBrowser::RomList_PopupMenu(uint32_t /*pnmh*/) -{ - LONG iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); - m_SelectedRom = ""; - if (iItem != -1) - { - LV_ITEM lvItem; - memset(&lvItem, 0, sizeof(LV_ITEM)); - lvItem.mask = LVIF_PARAM; - lvItem.iItem = iItem; - if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return; } - if (lvItem.lParam < 0 || lvItem.lParam >= (LPARAM)m_RomInfo.size()) - { - return; - } - ROM_INFO * pRomInfo = &m_RomInfo[lvItem.lParam]; - - if (!pRomInfo) { return; } - m_SelectedRom = pRomInfo->szFullFileName; - } - - //Load the menu - HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_POPUP)); - HMENU hPopupMenu = (HMENU)GetSubMenu(hMenu, 0); - - //Fix up menu - MenuSetText(hPopupMenu, 0, wGS(POPUP_PLAY).c_str(), NULL); - MenuSetText(hPopupMenu, 1, wGS(POPUP_PLAYDISK).c_str(), NULL); - MenuSetText(hPopupMenu, 3, wGS(MENU_REFRESH).c_str(), NULL); - MenuSetText(hPopupMenu, 4, wGS(MENU_CHOOSE_ROM).c_str(), NULL); - MenuSetText(hPopupMenu, 6, wGS(POPUP_INFO).c_str(), NULL); - MenuSetText(hPopupMenu, 7, wGS(POPUP_GFX_PLUGIN).c_str(), NULL); - MenuSetText(hPopupMenu, 9, wGS(POPUP_SETTINGS).c_str(), NULL); - MenuSetText(hPopupMenu, 10, wGS(POPUP_CHEATS).c_str(), NULL); - - if (m_SelectedRom.size() == 0) - { - DeleteMenu(hPopupMenu, 10, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 9, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 8, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 7, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 6, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 5, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 2, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 1, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 0, MF_BYPOSITION); - } - else - { - bool inBasicMode = g_Settings->LoadDword(UserInterface_BasicMode) != 0; - bool CheatsRemembered = g_Settings->LoadDword(Setting_RememberCheats) != 0; - if (!CheatsRemembered) { DeleteMenu(hPopupMenu, 10, MF_BYPOSITION); } - if (inBasicMode) { DeleteMenu(hPopupMenu, 9, MF_BYPOSITION); } - if (inBasicMode && !CheatsRemembered) { DeleteMenu(hPopupMenu, 8, MF_BYPOSITION); } - DeleteMenu(hPopupMenu, 7, MF_BYPOSITION); - if (!inBasicMode && g_Plugins && g_Plugins->Gfx() && g_Plugins->Gfx()->GetRomBrowserMenu != NULL) - { - HMENU GfxMenu = (HMENU)g_Plugins->Gfx()->GetRomBrowserMenu(); - if (GfxMenu) - { - MENUITEMINFO lpmii; - InsertMenuW(hPopupMenu, 7, MF_POPUP | MF_BYPOSITION, (uint32_t)GfxMenu, wGS(POPUP_GFX_PLUGIN).c_str()); - lpmii.cbSize = sizeof(MENUITEMINFO); - lpmii.fMask = MIIM_STATE; - lpmii.fState = 0; - SetMenuItemInfo(hPopupMenu, (uint32_t)GfxMenu, MF_BYCOMMAND, &lpmii); - } - } - } - - //Get the current Mouse location - POINT Mouse; - GetCursorPos(&Mouse); - - //Show the menu - TrackPopupMenu(hPopupMenu, 0, Mouse.x, Mouse.y, 0, m_MainWindow, NULL); - DestroyMenu(hMenu); -} - -void CRomBrowser::RomList_SortList(void) -{ - SORT_FIELD SortFieldInfo; - m_UnknownGoodName = wGS(RB_NOT_GOOD_FILE); - - for (int32_t count = NoOfSortKeys; count >= 0; count--) - { - stdstr SortFieldName = g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, count); - - size_t index; - for (index = 0; index < m_Fields.size(); index++) - { - if (_stricmp(m_Fields[index].Name(), SortFieldName.c_str()) == 0) { break; } - } - if (index >= m_Fields.size()) { continue; } - SortFieldInfo._this = this; - SortFieldInfo.Key = index; - SortFieldInfo.KeyAscend = g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, count) != 0; - ListView_SortItems(m_hRomList, RomList_CompareItems, &SortFieldInfo); - } -} - -/* -* SaveRomList - save all the rom information about the current roms in the rom brower -* to a cache file, so it is quick to reload the information -*/ -void CRomBrowser::SaveRomList(strlist & FileList) -{ - MD5 ListHash = RomListHash(FileList); - - stdstr FileName = g_Settings->LoadStringVal(SupportFile_RomListCache); - HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); - - DWORD dwWritten; - WriteFile(hFile, ListHash.raw_digest(), 16, &dwWritten, NULL); - - //Write the size of ROM_INFO - int32_t RomInfoSize = sizeof(ROM_INFO); - WriteFile(hFile, &RomInfoSize, sizeof(RomInfoSize), &dwWritten, NULL); - - //Write the Number of entries - int32_t Entries = m_RomInfo.size(); - WriteFile(hFile, &Entries, sizeof(Entries), &dwWritten, NULL); - - //Write Every Entry - for (int32_t count = 0; count < Entries; count++) - { - ROM_INFO * RomInfo = &m_RomInfo[count]; - WriteFile(hFile, RomInfo, RomInfoSize, &dwWritten, NULL); - } - - //Close the file handle - CloseHandle(hFile); -} - -void CRomBrowser::SaveRomListColoumnInfo(void) -{ - WriteTrace(TraceUserInterface, TraceDebug, "Start"); - // if (!RomBrowserVisible()) { return; } - if (g_Settings == NULL) { return; } - - LV_COLUMN lvColumn; - - memset(&lvColumn, 0, sizeof(lvColumn)); - lvColumn.mask = LVCF_WIDTH; - - for (size_t Coloumn = 0; ListView_GetColumn(m_hRomList, Coloumn, &lvColumn); Coloumn++) - { - size_t index; - bool bFound = false; - for (index = 0; index < m_Fields.size(); index++) - { - if (m_Fields[index].Pos() == Coloumn) - { - bFound = true; - break; - } - } - if (bFound) - { - if (m_Fields[index].ColWidth() != lvColumn.cx) - { - m_Fields[index].SetColWidth(lvColumn.cx); - } - } - } - WriteTrace(TraceUserInterface, TraceDebug, "Done"); -} - -int32_t CALLBACK CRomBrowser::SelectRomDirCallBack(HWND hwnd, uint32_t uMsg, uint32_t /*lp*/, uint32_t lpData) -{ - switch (uMsg) - { - case BFFM_INITIALIZED: - // WParam is TRUE since you are passing a path. - // It would be FALSE if you were passing a pidl. - if (lpData) - { - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData); - SetWindowTextW(hwnd, wGS(DIR_SELECT_ROM).c_str()); - } - break; - } - return 0; -} - -void CRomBrowser::SelectRomDir(void) -{ - wchar_t SelectedDir[MAX_PATH]; - LPITEMIDLIST pidl; - BROWSEINFOW bi; - - std::wstring title = wGS(SELECT_ROM_DIR); - - WriteTrace(TraceUserInterface, TraceDebug, "1"); - stdstr RomDir = g_Settings->LoadStringVal(Directory_Game); - bi.hwndOwner = m_MainWindow; - bi.pidlRoot = NULL; - bi.pszDisplayName = SelectedDir; - bi.lpszTitle = title.c_str(); - bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; - bi.lpfn = (BFFCALLBACK)SelectRomDirCallBack; - bi.lParam = (uint32_t)RomDir.c_str(); - WriteTrace(TraceUserInterface, TraceDebug, "2"); - if ((pidl = SHBrowseForFolderW(&bi)) != NULL) - { - WriteTrace(TraceUserInterface, TraceDebug, "3"); - char Directory[_MAX_PATH]; - if (SHGetPathFromIDList(pidl, Directory)) - { - int32_t len = strlen(Directory); - - WriteTrace(TraceUserInterface, TraceDebug, "4"); - if (Directory[len - 1] != '\\') - { - strcat(Directory, "\\"); - } - WriteTrace(TraceUserInterface, TraceDebug, "5"); - WriteTrace(TraceUserInterface, TraceDebug, "6"); - g_Settings->SaveString(Directory_Game, Directory); - WriteTrace(TraceUserInterface, TraceDebug, "7"); - Notify().AddRecentDir(Directory); - WriteTrace(TraceUserInterface, TraceDebug, "8"); - RefreshRomBrowser(); - WriteTrace(TraceUserInterface, TraceDebug, "9"); - } - } -} - -void CRomBrowser::FixRomListWindow(void) -{ - //Change the window Style - long Style = GetWindowLong(m_MainWindow, GWL_STYLE) | WS_SIZEBOX | WS_MAXIMIZEBOX; - SetWindowLong(m_MainWindow, GWL_STYLE, Style); - - //Get the current window size - RECT rect; - GetWindowRect(m_MainWindow, &rect); - - //We find the middle position of the screen, we use this if theres no setting - int32_t X = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2; - int32_t Y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2; - - //Load the value from settings, if none is available, default to above - g_Settings->LoadDword(RomBrowser_Top, (uint32_t &)Y); - g_Settings->LoadDword(RomBrowser_Left, (uint32_t &)X); - - SetWindowPos(m_MainWindow, NULL, X, Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - - //Fix height and width - int32_t Width = g_Settings->LoadDword(RomBrowser_Width); - int32_t Height = g_Settings->LoadDword(RomBrowser_Height); - - if (Width < 200) { Width = 200; } - if (Height < 200) { Height = 200; } - - RECT rcClient; - rcClient.top = 0; - rcClient.bottom = Height; - rcClient.left = 0; - rcClient.right = Width; - AdjustWindowRect(&rcClient, GetWindowLong(m_MainWindow, GWL_STYLE), true); - - int32_t WindowHeight = rcClient.bottom - rcClient.top; - int32_t WindowWidth = rcClient.right - rcClient.left; - - SetWindowPos(m_MainWindow, NULL, 0, 0, WindowWidth, WindowHeight, SWP_NOMOVE | SWP_NOZORDER); -} - -void CRomBrowser::ShowRomList(void) -{ - if (m_Visible || g_Settings->LoadBool(GameRunning_CPU_Running)) { return; } - m_ShowingRomBrowser = true; - WatchThreadStop(); - if (m_hRomList == NULL) { CreateRomListControl(); } - EnableWindow(m_hRomList, TRUE); - ShowWindow(m_hRomList, SW_SHOW); - FixRomListWindow(); - m_AllowSelectionLastRom = true; - - //Make sure selected item is visible - int32_t iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); - ListView_EnsureVisible(m_hRomList, iItem, FALSE); - - //Mark the window as visible - m_Visible = true; - - RECT rcWindow; - if (GetClientRect(m_MainWindow, &rcWindow)) - { - ResizeRomList((WORD)rcWindow.right, (WORD)rcWindow.bottom); - } - - InvalidateRect(m_hRomList, NULL, TRUE); - - //Start thread to watch for dir changed - WatchThreadStart(); - m_ShowingRomBrowser = false; -} - -void CRomBrowser::HideRomList(void) -{ - if (!RomBrowserVisible()) { return; } - ShowWindow(m_MainWindow, SW_HIDE); - - SaveRomListColoumnInfo(); - WatchThreadStop(); - - //Make sure the window does disappear - Sleep(100); - - //Disable the rom list - EnableWindow(m_hRomList, FALSE); - ShowWindow(m_hRomList, SW_HIDE); - - if (g_Settings->LoadBool(RomBrowser_Maximized)) { ShowWindow(m_MainWindow, SW_RESTORE); } - - //Change the window style - long Style = GetWindowLong(m_MainWindow, GWL_STYLE) & ~(WS_SIZEBOX | WS_MAXIMIZEBOX); - SetWindowLong(m_MainWindow, GWL_STYLE, Style); - - //Move window to correct location - RECT rect; - GetWindowRect(m_MainWindow, &rect); - int32_t X = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2; - int32_t Y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2; - g_Settings->LoadDword(UserInterface_MainWindowTop, (uint32_t &)Y); - g_Settings->LoadDword(UserInterface_MainWindowLeft, (uint32_t &)X); - SetWindowPos(m_MainWindow, NULL, X, Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - - //Mark the window as not visible - m_Visible = false; - - //Make the main window visible again - ShowWindow(m_MainWindow, SW_SHOW); - BringWindowToTop(m_MainWindow); - PostMessage(m_MainWindow, WM_MAKE_FOCUS, 0, 0); -} - -bool CRomBrowser::RomDirNeedsRefresh(void) -{ - bool InWatchThread = (m_WatchThreadID == GetCurrentThreadId()); - - //Get Old MD5 of file names - stdstr FileName = g_Settings->LoadStringVal(SupportFile_RomListCache); - HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - //if file does not exist then refresh the data - return true; - } - - DWORD dwRead; - unsigned char CurrentFileMD5[16]; - ReadFile(hFile, &CurrentFileMD5, sizeof(CurrentFileMD5), &dwRead, NULL); - CloseHandle(hFile); - - //Get Current MD5 of file names - strlist FileNames; - if (!GetRomFileNames(FileNames, CPath(g_Settings->LoadStringVal(Directory_Game)), stdstr(""), InWatchThread)) - { - return false; - } - FileNames.sort(); - - MD5 NewMd5 = RomListHash(FileNames); - if (memcmp(NewMd5.raw_digest(), CurrentFileMD5, sizeof(CurrentFileMD5)) != 0) - { - return true; - } - return false; -} - -MD5 CRomBrowser::RomListHash(strlist & FileList) -{ - stdstr NewFileNames; - FileList.sort(); - for (strlist::iterator iter = FileList.begin(); iter != FileList.end(); iter++) - { - NewFileNames += *iter; - NewFileNames += ";"; - } - MD5 md5Hash((const unsigned char *)NewFileNames.c_str(), NewFileNames.length()); - WriteTrace(TraceUserInterface, TraceDebug, "%s - %s", md5Hash.hex_digest(), NewFileNames.c_str()); - return md5Hash; -} - -void CRomBrowser::WatchRomDirChanged(CRomBrowser * _this) -{ - try - { - WriteTrace(TraceUserInterface, TraceDebug, "1"); - _this->m_WatchRomDir = g_Settings->LoadStringVal(Directory_Game); - WriteTrace(TraceUserInterface, TraceDebug, "2"); - if (_this->RomDirNeedsRefresh()) - { - WriteTrace(TraceUserInterface, TraceDebug, "2a"); - PostMessage((HWND)_this->m_MainWindow, WM_COMMAND, ID_FILE_REFRESHROMLIST, 0); - } - WriteTrace(TraceUserInterface, TraceDebug, "3"); - HANDLE hChange[] = { - _this->m_WatchStopEvent, - FindFirstChangeNotification(_this->m_WatchRomDir.c_str(), g_Settings->LoadDword(RomBrowser_Recursive), FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE), - }; - WriteTrace(TraceUserInterface, TraceDebug, "4"); - for (;;) - { - WriteTrace(TraceUserInterface, TraceDebug, "5"); - if (WaitForMultipleObjects(sizeof(hChange) / sizeof(hChange[0]), hChange, false, INFINITE) == WAIT_OBJECT_0) - { - WriteTrace(TraceUserInterface, TraceDebug, "5a"); - FindCloseChangeNotification(hChange[1]); - return; - } - WriteTrace(TraceUserInterface, TraceDebug, "5b"); - if (_this->RomDirNeedsRefresh()) - { - PostMessage((HWND)_this->m_MainWindow, WM_COMMAND, ID_FILE_REFRESHROMLIST, 0); - } - WriteTrace(TraceUserInterface, TraceDebug, "5c"); - if (!FindNextChangeNotification(hChange[1])) - { - FindCloseChangeNotification(hChange[1]); - return; - } - WriteTrace(TraceUserInterface, TraceDebug, "5d"); - } - } - catch (...) - { - WriteTrace(TraceUserInterface, TraceError, __FUNCTION__ ": Unhandled Exception"); - } -} - -void CRomBrowser::WatchThreadStart(void) -{ - WriteTrace(TraceUserInterface, TraceDebug, "1"); - WatchThreadStop(); - WriteTrace(TraceUserInterface, TraceDebug, "2"); - m_WatchStopEvent = CreateEvent(NULL, true, false, NULL); - WriteTrace(TraceUserInterface, TraceDebug, "3"); - m_WatchThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WatchRomDirChanged, this, 0, &m_WatchThreadID); - WriteTrace(TraceUserInterface, TraceDebug, "4"); -} - -void CRomBrowser::WatchThreadStop(void) -{ - if (m_WatchThread == NULL) - { - return; - } - WriteTrace(TraceUserInterface, TraceDebug, "1"); - SetEvent(m_WatchStopEvent); - DWORD ExitCode = 0; - for (int32_t count = 0; count < 20; count++) - { - WriteTrace(TraceUserInterface, TraceDebug, "2"); - GetExitCodeThread(m_WatchThread, &ExitCode); - if (ExitCode != STILL_ACTIVE) - { - break; - } - Sleep(200); - } - WriteTrace(TraceUserInterface, TraceDebug, "3"); - if (ExitCode == STILL_ACTIVE) - { - WriteTrace(TraceUserInterface, TraceDebug, "3a"); - TerminateThread(m_WatchThread, 0); - } - WriteTrace(TraceUserInterface, TraceDebug, "4"); - - CloseHandle(m_WatchThread); - CloseHandle(m_WatchStopEvent); - m_WatchStopEvent = NULL; - m_WatchThread = NULL; - m_WatchThreadID = 0; - WriteTrace(TraceUserInterface, TraceDebug, "5"); +#include "stdafx.h" + +#include +#include + +std::wstring CRomBrowser::m_UnknownGoodName; + +CRomBrowser::CRomBrowser(HWND & MainWindow, HWND & StatusWindow) : +m_MainWindow(MainWindow), +m_StatusWindow(StatusWindow), +m_ShowingRomBrowser(false), +m_RefreshThread(NULL), +m_RomIniFile(NULL), +m_NotesIniFile(NULL), +m_ExtIniFile(NULL), +m_ZipIniFile(NULL), +m_AllowSelectionLastRom(true), +m_WatchThreadID(0) +{ + if (g_Settings) + { + m_RomIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); + m_NotesIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Notes).c_str()); + m_ExtIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_ExtInfo).c_str()); + m_ZipIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_7zipCache).c_str()); + } + + m_hRomList = 0; + m_Visible = false; + m_WatchThread = NULL; + m_WatchStopEvent = NULL; + + GetFieldInfo(m_Fields); + m_FieldType.resize(m_Fields.size()); +} + +CRomBrowser::~CRomBrowser(void) +{ + m_StopRefresh = true; + WatchThreadStop(); + DeallocateBrushs(); + + if (m_RomIniFile) + { + delete m_RomIniFile; + m_RomIniFile = NULL; + } + if (m_NotesIniFile) + { + delete m_NotesIniFile; + m_NotesIniFile = NULL; + } + if (m_ExtIniFile) + { + delete m_ExtIniFile; + m_ExtIniFile = NULL; + } + if (m_ZipIniFile) + { + delete m_ZipIniFile; + m_ZipIniFile = NULL; + } +} + +void CRomBrowser::AddField(ROMBROWSER_FIELDS_LIST & Fields, LPCSTR Name, int32_t Pos, int32_t ID, int32_t Width, LanguageStringID LangID, bool UseDefault) +{ + Fields.push_back(ROMBROWSER_FIELDS(Name, Pos, ID, Width, LangID, UseDefault)); +} + +void CRomBrowser::GetFieldInfo(ROMBROWSER_FIELDS_LIST & Fields, bool UseDefault /* = false */) +{ + Fields.clear(); + + AddField(Fields, "File Name", -1, RB_FileName, 218, RB_FILENAME, UseDefault); + AddField(Fields, "Internal Name", -1, RB_InternalName, 200, RB_INTERNALNAME, UseDefault); + AddField(Fields, "Good Name", 0, RB_GoodName, 218, RB_GOODNAME, UseDefault); + AddField(Fields, "Status", 1, RB_Status, 92, RB_STATUS, UseDefault); + AddField(Fields, "Rom Size", -1, RB_RomSize, 100, RB_ROMSIZE, UseDefault); + AddField(Fields, "Notes (Core)", 2, RB_CoreNotes, 120, RB_NOTES_CORE, UseDefault); + AddField(Fields, "Notes (default plugins)", 3, RB_PluginNotes, 188, RB_NOTES_PLUGIN, UseDefault); + AddField(Fields, "Notes (User)", -1, RB_UserNotes, 100, RB_NOTES_USER, UseDefault); + AddField(Fields, "Cartridge ID", -1, RB_CartridgeID, 100, RB_CART_ID, UseDefault); + AddField(Fields, "Manufacturer", -1, RB_Manufacturer, 100, RB_MANUFACTUER, UseDefault); + AddField(Fields, "Country", -1, RB_Country, 100, RB_COUNTRY, UseDefault); + AddField(Fields, "Developer", -1, RB_Developer, 100, RB_DEVELOPER, UseDefault); + AddField(Fields, "CRC1", -1, RB_Crc1, 100, RB_CRC1, UseDefault); + AddField(Fields, "CRC2", -1, RB_Crc2, 100, RB_CRC2, UseDefault); + AddField(Fields, "CIC Chip", -1, RB_CICChip, 100, RB_CICCHIP, UseDefault); + AddField(Fields, "Release Date", -1, RB_ReleaseDate, 100, RB_RELEASE_DATE, UseDefault); + AddField(Fields, "Genre", -1, RB_Genre, 100, RB_GENRE, UseDefault); + AddField(Fields, "Players", -1, RB_Players, 100, RB_PLAYERS, UseDefault); + AddField(Fields, "Force Feedback", -1, RB_ForceFeedback, 100, RB_FORCE_FEEDBACK, UseDefault); + AddField(Fields, "File Format", -1, RB_FileFormat, 100, RB_FILE_FORMAT, UseDefault); +} + +int32_t CRomBrowser::CalcSortPosition(uint32_t lParam) +{ + int32_t Start = 0; + int32_t End = ListView_GetItemCount(m_hRomList) - 1; + if (End < 0) + { + return 0; + } + + for (int32_t SortIndex = NoOfSortKeys; SortIndex >= 0; SortIndex--) + { + stdstr SortFieldName = g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, SortIndex); + if (SortFieldName.length() == 0) + { + continue; + } + + if (End == Start) + { + break; + } + + size_t index; + for (index = 0; index < m_Fields.size(); index++) + { + if (_stricmp(m_Fields[index].Name(), SortFieldName.c_str()) == 0) { break; } + } + if (index >= m_Fields.size()) { continue; } + SORT_FIELD SortFieldInfo; + SortFieldInfo._this = this; + SortFieldInfo.Key = index; + SortFieldInfo.KeyAscend = g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, SortIndex); + + //calc new start and end + int32_t LastTestPos = -1; + while (Start < End) + { + int32_t TestPos = (int32_t)floor((float)((Start + End) / 2)); + if (LastTestPos == TestPos) + { + TestPos += 1; + } + LastTestPos = TestPos; + + LVITEMW lvItem; + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_PARAM; + lvItem.iItem = TestPos; + if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) + { + return End; + } + + int32_t Result = RomList_CompareItems(lParam, lvItem.lParam, (uint32_t)&SortFieldInfo); + if (Result < 0) + { + if (End == TestPos) + { + break; + } + End = TestPos; + } + else if (Result > 0) + { + if (Start == TestPos) + { + break; + } + Start = TestPos; + } + else + { + //Find new start + float Left = (float)Start; + float Right = (float)TestPos; + while (Left < Right) + { + int32_t NewTestPos = (int32_t)floor((Left + Right) / 2); + if (LastTestPos == NewTestPos) + { + NewTestPos += 1; + } + LastTestPos = NewTestPos; + + LVITEMW lvItem; + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_PARAM; + lvItem.iItem = NewTestPos; + if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) + { + return End; + } + + int32_t Result = RomList_CompareItems(lParam, lvItem.lParam, (uint32_t)&SortFieldInfo); + if (Result <= 0) + { + if (Right == NewTestPos) + { + break; + } + Right = (float)NewTestPos; + } + else if (Result > 0) + { + Left = Left != (float)NewTestPos ? (float)NewTestPos : Left + 1; + } + } + Start = (int32_t)((float)Right); + + //Find new end + Left = (float)TestPos; + Right = (float)End; + while (Left < Right) + { + int32_t NewTestPos = (int32_t)ceil((Left + Right) / 2); + if (LastTestPos == NewTestPos) + { + NewTestPos -= 1; + } + LastTestPos = NewTestPos; + + LVITEMW lvItem; + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_PARAM; + lvItem.iItem = NewTestPos; + if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return End; } + + int32_t Result = RomList_CompareItems(lParam, lvItem.lParam, (uint32_t)&SortFieldInfo); + if (Result >= 0) + { + if (Left == NewTestPos) + { + break; + } + Left = (float)NewTestPos; + } + if (Result < 0) + { + Right = (float)NewTestPos; + } + } + End = (int32_t)Left; + break; + } + } + } + + //Compare end with item to see if we should do it after or before it + for (int32_t SortIndex = 0; SortIndex < NoOfSortKeys; SortIndex++) + { + stdstr SortFieldName = g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, SortIndex); + if (SortFieldName.length() == 0) + { + continue; + } + + size_t index; + for (index = 0; index < m_Fields.size(); index++) + { + if (_stricmp(m_Fields[index].Name(), SortFieldName.c_str()) == 0) { break; } + } + if (index >= m_Fields.size()) { continue; } + SORT_FIELD SortFieldInfo; + SortFieldInfo._this = this; + SortFieldInfo.Key = index; + SortFieldInfo.KeyAscend = g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, SortIndex) != 0; + + LVITEMW lvItem; + memset(&lvItem, 0, sizeof(LVITEMW)); + lvItem.mask = LVIF_PARAM; + lvItem.iItem = End; + if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return End; } + + int32_t Result = RomList_CompareItems(lParam, lvItem.lParam, (uint32_t)&SortFieldInfo); + if (Result < 0) + { + return End; + } + if (Result > 0) + { + return End + 1; + } + } + return End + 1; +} + +void CRomBrowser::AddRomToList(const char * RomLocation, const char * lpLastRom) +{ + ROM_INFO RomInfo; + + memset(&RomInfo, 0, sizeof(ROM_INFO)); + strncpy(RomInfo.szFullFileName, RomLocation, (sizeof(RomInfo.szFullFileName) / sizeof(RomInfo.szFullFileName[0])) - 1); + if (!FillRomInfo(&RomInfo)) { return; } + AddRomInfoToList(RomInfo, lpLastRom); +} + +void CRomBrowser::AddRomInfoToList(ROM_INFO &RomInfo, const char * lpLastRom) +{ + int32_t ListPos = m_RomInfo.size(); + m_RomInfo.push_back(RomInfo); + + LVITEMW lvItem; + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_TEXT | LVIF_PARAM; + lvItem.iItem = CalcSortPosition(ListPos); + lvItem.lParam = (LPARAM)ListPos; + lvItem.pszText = LPSTR_TEXTCALLBACKW; + + int32_t index = ListView_InsertItem(m_hRomList, &lvItem); + + int32_t iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); + //if (iItem == -1) { return; } + + //if the last rom then highlight the item + if (iItem < 0 && _stricmp(RomInfo.szFullFileName, lpLastRom) == 0) + { + ListView_SetItemState(m_hRomList, index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + } + + if (iItem >= 0) + { + ListView_EnsureVisible(m_hRomList, iItem, FALSE); + } +} + +void CRomBrowser::AllocateBrushs(void) +{ + for (size_t count = 0; count < m_RomInfo.size(); count++) + { + if (m_RomInfo[count].SelColor == -1) + { + m_RomInfo[count].SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1)); + } + else + { + m_RomInfo[count].SelColorBrush = (uint32_t)CreateSolidBrush(m_RomInfo[count].SelColor); + } + } +} + +void CRomBrowser::CreateRomListControl(void) +{ + m_hRomList = CreateWindowW(WC_LISTVIEWW, NULL, WS_TABSTOP | WS_VISIBLE | WS_CHILD | LVS_OWNERDRAWFIXED | LVS_SINGLESEL | LVS_REPORT, 0, 0, 0, 0, m_MainWindow, (HMENU)IDC_ROMLIST, GetModuleHandle(NULL), NULL); + ResetRomBrowserColomuns(); + LoadRomList(); +} + +void CRomBrowser::DeallocateBrushs(void) +{ + for (size_t count = 0; count < m_RomInfo.size(); count++) + { + if (m_RomInfo[count].SelColor == -1) + { + continue; + } + if (m_RomInfo[count].SelColorBrush) + { + DeleteObject((HBRUSH)m_RomInfo[count].SelColorBrush); + m_RomInfo[count].SelColorBrush = NULL; + } + } +} + +void CRomBrowser::FillRomExtensionInfo(ROM_INFO * pRomInfo) +{ + //Initialize the structure + pRomInfo->UserNotes[0] = 0; + pRomInfo->Developer[0] = 0; + pRomInfo->ReleaseDate[0] = 0; + pRomInfo->Genre[0] = 0; + pRomInfo->Players = 1; + pRomInfo->CoreNotes[0] = 0; + pRomInfo->PluginNotes[0] = 0; + wcscpy(pRomInfo->GoodName, L"#340#"); + wcscpy(pRomInfo->Status, L"Unknown"); + + //Get File Identifier + char Identifier[100]; + sprintf(Identifier, "%08X-%08X-C:%X", pRomInfo->CRC1, pRomInfo->CRC2, pRomInfo->Country); + + //Rom Notes + if (m_Fields[RB_UserNotes].Pos() >= 0) + { + wcsncpy(pRomInfo->UserNotes, m_NotesIniFile->GetString(Identifier, "Note", "").ToUTF16().c_str(), sizeof(pRomInfo->UserNotes) / sizeof(wchar_t)); + } + + //Rom Extension info + if (m_Fields[RB_Developer].Pos() >= 0) + { + wcsncpy(pRomInfo->Developer, m_ExtIniFile->GetString(Identifier, "Developer", "").ToUTF16().c_str(), sizeof(pRomInfo->Developer) / sizeof(wchar_t)); + } + if (m_Fields[RB_ReleaseDate].Pos() >= 0) + { + wcsncpy(pRomInfo->ReleaseDate, m_ExtIniFile->GetString(Identifier, "ReleaseDate", "").ToUTF16().c_str(), sizeof(pRomInfo->ReleaseDate) / sizeof(wchar_t)); + } + if (m_Fields[RB_Genre].Pos() >= 0) + { + wcsncpy(pRomInfo->Genre, m_ExtIniFile->GetString(Identifier, "Genre", "").ToUTF16().c_str(), sizeof(pRomInfo->Genre) / sizeof(wchar_t)); + } + if (m_Fields[RB_Players].Pos() >= 0) + { + m_ExtIniFile->GetNumber(Identifier, "Players", 1, (uint32_t &)pRomInfo->Players); + } + if (m_Fields[RB_ForceFeedback].Pos() >= 0) + { + wcsncpy(pRomInfo->ForceFeedback, m_ExtIniFile->GetString(Identifier, "ForceFeedback", "unknown").ToUTF16().c_str(), sizeof(pRomInfo->ForceFeedback) / sizeof(wchar_t)); + } + + //Rom Settings + if (m_Fields[RB_GoodName].Pos() >= 0) + { + wcsncpy(pRomInfo->GoodName, m_RomIniFile->GetString(Identifier, "Good Name", stdstr().FromUTF16(pRomInfo->GoodName).c_str()).ToUTF16().c_str(), sizeof(pRomInfo->GoodName) / sizeof(wchar_t)); + } + wcsncpy(pRomInfo->Status, m_RomIniFile->GetString(Identifier, "Status", stdstr().FromUTF16(pRomInfo->Status).c_str()).ToUTF16().c_str(), sizeof(pRomInfo->Status) / sizeof(wchar_t)); + if (m_Fields[RB_CoreNotes].Pos() >= 0) + { + wcsncpy(pRomInfo->CoreNotes, m_RomIniFile->GetString(Identifier, "Core Note", "").ToUTF16().c_str(), sizeof(pRomInfo->CoreNotes) / sizeof(wchar_t)); + } + if (m_Fields[RB_PluginNotes].Pos() >= 0) + { + wcsncpy(pRomInfo->PluginNotes, m_RomIniFile->GetString(Identifier, "Plugin Note", "").ToUTF16().c_str(), sizeof(pRomInfo->PluginNotes) / sizeof(wchar_t)); + } + + //Get the text color + stdstr String = m_RomIniFile->GetString("Rom Status", stdstr().FromUTF16(pRomInfo->Status).c_str(), "000000"); + pRomInfo->TextColor = (std::strtoul(String.c_str(), 0, 16) & 0xFFFFFF); + pRomInfo->TextColor = (pRomInfo->TextColor & 0x00FF00) | ((pRomInfo->TextColor >> 0x10) & 0xFF) | ((pRomInfo->TextColor & 0xFF) << 0x10); + + //Get the selected color + String.Format("%ws.Sel", pRomInfo->Status); + String = m_RomIniFile->GetString("Rom Status", String.c_str(), "FFFFFFFF"); + uint32_t selcol = std::strtoul(String.c_str(), NULL, 16); + if (selcol & 0x80000000) + { + pRomInfo->SelColor = -1; + } + else + { + selcol = (selcol & 0x00FF00) | ((selcol >> 0x10) & 0xFF) | ((selcol & 0xFF) << 0x10); + pRomInfo->SelColor = selcol; + } + + //Get the selected text color + String.Format("%ws.Seltext", pRomInfo->Status); + String = m_RomIniFile->GetString("Rom Status", String.c_str(), "FFFFFF"); + pRomInfo->SelTextColor = (std::strtoul(String.c_str(), 0, 16) & 0xFFFFFF); + pRomInfo->SelTextColor = (pRomInfo->SelTextColor & 0x00FF00) | ((pRomInfo->SelTextColor >> 0x10) & 0xFF) | ((pRomInfo->SelTextColor & 0xFF) << 0x10); +} + +bool CRomBrowser::FillRomInfo(ROM_INFO * pRomInfo) +{ + int32_t count; + uint8_t RomData[0x1000]; + + if (!LoadDataFromRomFile(pRomInfo->szFullFileName, RomData, sizeof(RomData), &pRomInfo->RomSize, pRomInfo->FileFormat)) + { + return false; + } + else + { + if (strstr(pRomInfo->szFullFileName, "?") != NULL) + { + strcpy(pRomInfo->FileName, strstr(pRomInfo->szFullFileName, "?") + 1); + } + else + { + strncpy(pRomInfo->FileName, CPath(pRomInfo->szFullFileName).GetNameExtension().c_str(), sizeof(pRomInfo->FileName) / sizeof(pRomInfo->FileName[0])); + } + if (m_Fields[RB_InternalName].Pos() >= 0) + { + char InternalName[22]; + memcpy(InternalName, (void *)(RomData + 0x20), 20); + for (count = 0; count < 20; count += 4) + { + InternalName[count] ^= InternalName[count + 3]; + InternalName[count + 3] ^= InternalName[count]; + InternalName[count] ^= InternalName[count + 3]; + InternalName[count + 1] ^= InternalName[count + 2]; + InternalName[count + 2] ^= InternalName[count + 1]; + InternalName[count + 1] ^= InternalName[count + 2]; + } + InternalName[20] = '\0'; + wcscpy(pRomInfo->InternalName, stdstr(InternalName).ToUTF16(stdstr::CODEPAGE_932).c_str()); + } + pRomInfo->CartID[0] = *(RomData + 0x3F); + pRomInfo->CartID[1] = *(RomData + 0x3E); + pRomInfo->CartID[2] = '\0'; + pRomInfo->Manufacturer = *(RomData + 0x38); + pRomInfo->Country = *(RomData + 0x3D); + pRomInfo->CRC1 = *(uint32_t *)(RomData + 0x10); + pRomInfo->CRC2 = *(uint32_t *)(RomData + 0x14); + pRomInfo->CicChip = GetCicChipID(RomData); + + FillRomExtensionInfo(pRomInfo); + + if (pRomInfo->SelColor == -1) + { + pRomInfo->SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1)); + } + else + { + pRomInfo->SelColorBrush = (uint32_t)CreateSolidBrush(pRomInfo->SelColor); + } + + return true; + } +} + +bool CRomBrowser::GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, bool InWatchThread) +{ + if (!BaseDirectory.DirectoryExists()) + { + return false; + } + CPath SearchPath(BaseDirectory, "*.*"); + SearchPath.AppendDirectory(Directory.c_str()); + + if (!SearchPath.FindFirst(CPath::_A_ALLFILES)) + { + return false; + } + + do + { + if (InWatchThread && WaitForSingleObject(m_WatchStopEvent, 0) != WAIT_TIMEOUT) + { + return false; + } + + if (SearchPath.IsDirectory()) + { + if (g_Settings->LoadDword(RomBrowser_Recursive)) + { + stdstr CurrentDir = Directory + SearchPath.GetLastDirectory() + "\\"; + GetRomFileNames(FileList, BaseDirectory, CurrentDir, InWatchThread); + } + } + else + { + AddFileNameToList(FileList, Directory, SearchPath); + } + } while (SearchPath.FindNext()); + return true; +} + +void CRomBrowser::NotificationCB(const char * Status, CRomBrowser * /*_this*/) +{ + g_Notify->DisplayMessage(5, Status); +} + +static const char* ROM_extensions[] = +{ + "zip", "7z", "v64", "z64", "n64", "rom", "jap", "pal", "usa", "eur", "bin", +}; + +void CRomBrowser::AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File) +{ + uint8_t i; + + if (FileList.size() > 3000) + { + return; + } + + stdstr Drive, Dir, Name, Extension; + File.GetComponents(NULL, &Dir, &Name, &Extension); + Extension.ToLower(); + for (i = 0; i < sizeof(ROM_extensions) / sizeof(ROM_extensions[0]); i++) + { + if (Extension == ROM_extensions[i]) + { + stdstr FileName = Directory + Name + Extension; + FileName.ToLower(); + FileList.push_back(FileName); + break; + } + } +} + +void CRomBrowser::FillRomList(strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, const char * lpLastRom) +{ + CPath SearchPath(BaseDirectory, "*.*"); + SearchPath.AppendDirectory(Directory.c_str()); + + WriteTrace(TraceUserInterface, TraceDebug, "1 %s", (const char *)SearchPath); + if (!SearchPath.FindFirst(CPath::_A_ALLFILES)) + { + return; + } + + do + { + uint8_t ext_ID; + int8_t new_list_entry = 0; + const uint8_t exts = sizeof(ROM_extensions) / sizeof(ROM_extensions[0]); + + WriteTrace(TraceUserInterface, TraceDebug, ": 2 %s m_StopRefresh = %d", (const char *)SearchPath, m_StopRefresh); + if (m_StopRefresh) { break; } + + if (SearchPath.IsDirectory()) + { + if (g_Settings->LoadDword(RomBrowser_Recursive)) + { + stdstr CurrentDir = Directory + SearchPath.GetLastDirectory() + "\\"; + FillRomList(FileList, BaseDirectory, CurrentDir, lpLastRom); + } + continue; + } + + AddFileNameToList(FileList, Directory, SearchPath); + + stdstr Extension = SearchPath.GetExtension(); + Extension.ToLower(); + + for (ext_ID = 0; ext_ID < exts; ext_ID++) + { + if (Extension == ROM_extensions[ext_ID] && Extension != "7z") + { + new_list_entry = 1; + break; + } + } + if (new_list_entry) + { + AddRomToList(SearchPath, lpLastRom); + continue; + } + + if (Extension == "7z") + { + try + { + C7zip ZipFile(SearchPath); + if (!ZipFile.OpenSuccess()) + { + continue; + } + char ZipFileName[260]; + stdstr_f SectionName("%s-%d", ZipFile.FileName(ZipFileName, sizeof(ZipFileName)), ZipFile.FileSize()); + SectionName.ToLower(); + + WriteTrace(TraceUserInterface, TraceDebug, "4 %s", SectionName.c_str()); + for (int32_t i = 0; i < ZipFile.NumFiles(); i++) + { + CSzFileItem * f = ZipFile.FileItem(i); + if (f->IsDir) + { + continue; + } + ROM_INFO RomInfo; + + std::wstring FileNameW = ZipFile.FileNameIndex(i); + if (FileNameW.length() == 0) + { + continue; + } + + stdstr FileName; + FileName.FromUTF16(FileNameW.c_str()); + WriteTrace(TraceUserInterface, TraceDebug, "5"); + char drive2[_MAX_DRIVE], dir2[_MAX_DIR], FileName2[MAX_PATH], ext2[_MAX_EXT]; + _splitpath(FileName.c_str(), drive2, dir2, FileName2, ext2); + + WriteTrace(TraceUserInterface, TraceDebug, ": 6 %s", ext2); + if (_stricmp(ext2, ".bin") == 0) + { + continue; + } + WriteTrace(TraceUserInterface, TraceDebug, "7"); + memset(&RomInfo, 0, sizeof(ROM_INFO)); + stdstr_f zipFileName("%s?%s", (LPCSTR)SearchPath, FileName.c_str()); + ZipFile.SetNotificationCallback((C7zip::LP7ZNOTIFICATION)NotificationCB, this); + + strncpy(RomInfo.szFullFileName, zipFileName.c_str(), sizeof(RomInfo.szFullFileName) - 1); + RomInfo.szFullFileName[sizeof(RomInfo.szFullFileName) - 1] = 0; + strcpy(RomInfo.FileName, strstr(RomInfo.szFullFileName, "?") + 1); + RomInfo.FileFormat = Format_7zip; + + WriteTrace(TraceUserInterface, TraceDebug, "8"); + char szHeader[0x90]; + if (m_ZipIniFile->GetString(SectionName.c_str(), FileName.c_str(), "", szHeader, sizeof(szHeader)) == 0) + { + uint8_t RomData[0x1000]; + if (!ZipFile.GetFile(i, RomData, sizeof(RomData))) + { + continue; + } + WriteTrace(TraceUserInterface, TraceDebug, "9"); + if (!CN64Rom::IsValidRomImage(RomData)) { continue; } + WriteTrace(TraceUserInterface, TraceDebug, "10"); + ByteSwapRomData(RomData, sizeof(RomData)); + WriteTrace(TraceUserInterface, TraceDebug, "11"); + + stdstr RomHeader; + for (int32_t x = 0; x < 0x40; x += 4) + { + RomHeader += stdstr_f("%08X", *((uint32_t *)&RomData[x])); + } + WriteTrace(TraceUserInterface, TraceDebug, "11a %s", RomHeader.c_str()); + int32_t CicChip = GetCicChipID(RomData); + + //save this info + WriteTrace(TraceUserInterface, TraceDebug, "12"); + m_ZipIniFile->SaveString(SectionName.c_str(), FileName.c_str(), RomHeader.c_str()); + m_ZipIniFile->SaveNumber(SectionName.c_str(), stdstr_f("%s-Cic", FileName.c_str()).c_str(), CicChip); + strcpy(szHeader, RomHeader.c_str()); + } + WriteTrace(TraceUserInterface, TraceDebug, "13"); + uint8_t RomData[0x40]; + + for (int32_t x = 0; x < 0x40; x += 4) + { + const size_t delimit_offset = sizeof("FFFFFFFF") - 1; + const char backup_character = szHeader[2 * x + delimit_offset]; + + szHeader[2 * x + delimit_offset] = '\0'; + *(uint32_t *)&RomData[x] = std::strtoul(&szHeader[2 * x], NULL, 16); + szHeader[2 * x + delimit_offset] = backup_character; + } + + WriteTrace(TraceUserInterface, TraceDebug, "14"); + { + char InternalName[22]; + memcpy(InternalName, (void *)(RomData + 0x20), 20); + for (int32_t count = 0; count < 20; count += 4) + { + InternalName[count] ^= InternalName[count + 3]; + InternalName[count + 3] ^= InternalName[count]; + InternalName[count] ^= InternalName[count + 3]; + InternalName[count + 1] ^= InternalName[count + 2]; + InternalName[count + 2] ^= InternalName[count + 1]; + InternalName[count + 1] ^= InternalName[count + 2]; + } + InternalName[20] = '\0'; + wcscpy(RomInfo.InternalName, stdstr(InternalName).ToUTF16(stdstr::CODEPAGE_932).c_str()); + } + RomInfo.RomSize = (int32_t)f->Size; + + WriteTrace(TraceUserInterface, TraceDebug, "15"); + RomInfo.CartID[0] = *(RomData + 0x3F); + RomInfo.CartID[1] = *(RomData + 0x3E); + RomInfo.CartID[2] = '\0'; + RomInfo.Manufacturer = *(RomData + 0x38); + RomInfo.Country = *(RomData + 0x3D); + RomInfo.CRC1 = *(uint32_t *)(RomData + 0x10); + RomInfo.CRC2 = *(uint32_t *)(RomData + 0x14); + m_ZipIniFile->GetNumber(SectionName.c_str(), stdstr_f("%s-Cic", FileName.c_str()).c_str(), (ULONG)-1, (uint32_t &)RomInfo.CicChip); + WriteTrace(TraceUserInterface, TraceDebug, "16"); + FillRomExtensionInfo(&RomInfo); + + if (RomInfo.SelColor == -1) + { + RomInfo.SelColorBrush = (uint32_t)((HBRUSH)(COLOR_HIGHLIGHT + 1)); + } + else + { + RomInfo.SelColorBrush = (uint32_t)CreateSolidBrush(RomInfo.SelColor); + } + WriteTrace(TraceUserInterface, TraceDebug, "17"); + AddRomInfoToList(RomInfo, lpLastRom); + } + } + catch (...) + { + WriteTrace(TraceUserInterface, TraceError, "execpetion processing %s", (LPCSTR)SearchPath); + } + continue; + } + } while (SearchPath.FindNext()); + m_ZipIniFile->FlushChanges(); +} + +int32_t CRomBrowser::GetCicChipID(uint8_t * RomData) +{ + __int64 CRC = 0; + int32_t count; + + for (count = 0x40; count < 0x1000; count += 4) + { + CRC += *(uint32_t *)(RomData + count); + } + switch (CRC) + { + case 0x000000D0027FDF31: return CIC_NUS_6101; + case 0x000000CFFB631223: return CIC_NUS_6101; + case 0x000000D057C85244: return CIC_NUS_6102; + case 0x000000D6497E414B: return CIC_NUS_6103; + case 0x0000011A49F60E96: return CIC_NUS_6105; + case 0x000000D6D5BE5580: return CIC_NUS_6106; + case 0x000001053BC19870: return CIC_NUS_5167; //64DD CONVERSION CIC + case 0x000000D2E53EF008: return CIC_NUS_8303; //64DD IPL + default: + return CIC_UNKNOWN; + } +} + +void CRomBrowser::HighLightLastRom(void) +{ + if (!m_AllowSelectionLastRom) + { + return; + } + //Make sure Rom browser is visible + if (!RomBrowserVisible()) { return; } + + //Get the string to the last rom + stdstr LastRom = g_Settings->LoadStringIndex(File_RecentGameFileIndex, 0); + LPCSTR lpLastRom = LastRom.c_str(); + + LVITEMW lvItem; + lvItem.mask = LVIF_PARAM; + + int32_t ItemCount = ListView_GetItemCount(m_hRomList); + for (int32_t index = 0; index < ItemCount; index++) + { + //Get The next item + lvItem.iItem = index; + if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return; } + + //Get the rom info for that item + if (lvItem.lParam < 0 || lvItem.lParam >= (LPARAM)m_RomInfo.size()) + { + return; + } + ROM_INFO * pRomInfo = &m_RomInfo[lvItem.lParam]; + + if (!m_AllowSelectionLastRom) + { + return; + } + + //if the last rom then highlight the item + if (_stricmp(pRomInfo->szFullFileName, lpLastRom) == 0) + { + ListView_SetItemState(m_hRomList, index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + ListView_EnsureVisible(m_hRomList, index, FALSE); + return; + } + } +} + +bool CRomBrowser::LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat) +{ + uint8_t Test[4]; + + if (_strnicmp(&FileName[strlen(FileName) - 4], ".ZIP", 4) == 0) + { + int32_t len, port = 0, FoundRom; + unz_file_info info; + char zname[132]; + unzFile file; + file = unzOpen(FileName); + if (file == NULL) { return false; } + + port = unzGoToFirstFile(file); + FoundRom = FALSE; + while (port == UNZ_OK && FoundRom == FALSE) + { + unzGetCurrentFileInfo(file, &info, zname, 128, NULL, 0, NULL, 0); + if (unzLocateFile(file, zname, 1) != UNZ_OK) + { + unzClose(file); + return true; + } + if (unzOpenCurrentFile(file) != UNZ_OK) + { + unzClose(file); + return true; + } + unzReadCurrentFile(file, Test, 4); + if (CN64Rom::IsValidRomImage(Test)) + { + FoundRom = true; + memcpy(Data, Test, 4); + len = unzReadCurrentFile(file, &Data[4], DataLen - 4) + 4; + + if ((int32_t)DataLen != len) + { + unzCloseCurrentFile(file); + unzClose(file); + return false; + } + *RomSize = info.uncompressed_size; + if (unzCloseCurrentFile(file) == UNZ_CRCERROR) + { + unzClose(file); + return false; + } + unzClose(file); + } + if (FoundRom == false) + { + unzCloseCurrentFile(file); + port = unzGoToNextFile(file); + } + } + if (FoundRom == false) + { + return false; + } + FileFormat = Format_Zip; + } + else + { + HANDLE hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); + if (hFile == INVALID_HANDLE_VALUE) { return false; } + SetFilePointer(hFile, 0, 0, FILE_BEGIN); + + DWORD dwRead; + ReadFile(hFile, Test, 4, &dwRead, NULL); + if (!CN64Rom::IsValidRomImage(Test)) { CloseHandle(hFile); return false; } + SetFilePointer(hFile, 0, 0, FILE_BEGIN); + if (!ReadFile(hFile, Data, DataLen, &dwRead, NULL)) { CloseHandle(hFile); return false; } + *RomSize = GetFileSize(hFile, NULL); + CloseHandle(hFile); + FileFormat = Format_Uncompressed; + } + ByteSwapRomData(Data, DataLen); + return true; +} + +void CRomBrowser::ByteSwapRomData(uint8_t * Data, int32_t DataLen) +{ + int32_t count; + + switch (*((uint32_t *)&Data[0])) + { + case 0x12408037: + for (count = 0; count < DataLen; count += 4) + { + Data[count] ^= Data[count + 2]; + Data[count + 2] ^= Data[count]; + Data[count] ^= Data[count + 2]; + Data[count + 1] ^= Data[count + 3]; + Data[count + 3] ^= Data[count + 1]; + Data[count + 1] ^= Data[count + 3]; + } + break; + case 0x40072780: //64DD IPL + case 0x40123780: + for (count = 0; count < DataLen; count += 4) + { + Data[count] ^= Data[count + 3]; + Data[count + 3] ^= Data[count]; + Data[count] ^= Data[count + 3]; + Data[count + 1] ^= Data[count + 2]; + Data[count + 2] ^= Data[count + 1]; + Data[count + 1] ^= Data[count + 2]; + } + break; + case 0x80371240: break; + } +} + +void CRomBrowser::LoadRomList(void) +{ + stdstr FileName = g_Settings->LoadStringVal(SupportFile_RomListCache); + + //Open the cache file + HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + //if file does not exist then refresh the data + RefreshRomBrowser(); + return; + } + + DWORD dwRead; + unsigned char md5[16]; + ReadFile(hFile, &md5, sizeof(md5), &dwRead, NULL); + + //Read the size of ROM_INFO + int32_t RomInfoSize = 0; + ReadFile(hFile, &RomInfoSize, sizeof(RomInfoSize), &dwRead, NULL); + if (RomInfoSize != sizeof(ROM_INFO) || dwRead != sizeof(RomInfoSize)) + { + CloseHandle(hFile); + RefreshRomBrowser(); + return; + } + + //Read the Number of entries + int32_t Entries = 0; + ReadFile(hFile, &Entries, sizeof(Entries), &dwRead, NULL); + + //Read Every Entry + DeallocateBrushs(); + m_RomInfo.clear(); + for (int32_t count = 0; count < Entries; count++) + { + ROM_INFO RomInfo; + ReadFile(hFile, &RomInfo, RomInfoSize, &dwRead, NULL); + RomInfo.SelColorBrush = NULL; + + LVITEMW lvItem; + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_TEXT | LVIF_PARAM; + lvItem.iItem = ListView_GetItemCount(m_hRomList); + lvItem.lParam = (LPARAM)m_RomInfo.size(); + lvItem.pszText = LPSTR_TEXTCALLBACKW; + + SendMessageW(m_hRomList, LVM_INSERTITEMW, 0, (LPARAM)&lvItem); + m_RomInfo.push_back(RomInfo); + } + CloseHandle(hFile); + AllocateBrushs(); + RomList_SortList(); +} + +void CRomBrowser::MenuSetText(HMENU hMenu, int32_t MenuPos, const wchar_t * Title, char * ShortCut) +{ + MENUITEMINFOW MenuInfo; + wchar_t String[256]; + + if (Title == NULL || wcslen(Title) == 0) { return; } + + memset(&MenuInfo, 0, sizeof(MENUITEMINFO)); + MenuInfo.cbSize = sizeof(MENUITEMINFO); + MenuInfo.fMask = MIIM_TYPE; + MenuInfo.fType = MFT_STRING; + MenuInfo.fState = MFS_ENABLED; + MenuInfo.dwTypeData = String; + MenuInfo.cch = 256; + + GetMenuItemInfoW(hMenu, MenuPos, TRUE, &MenuInfo); + wcscpy(String, Title); + if (wcschr(String, '\t') != NULL) { *(wcschr(String, '\t')) = '\0'; } + if (ShortCut) { swprintf(String, sizeof(String) / sizeof(String[0]), L"%s\t%s", String, ShortCut); } + SetMenuItemInfoW(hMenu, MenuPos, TRUE, &MenuInfo); +} + +void CRomBrowser::RefreshRomBrowser(void) +{ + DWORD ThreadID; + + if (m_RefreshThread) + { + return; + } + WriteTrace(TraceUserInterface, TraceDebug, "1"); + m_StopRefresh = false; + m_RefreshThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RefreshRomBrowserStatic, (LPVOID)this, 0, &ThreadID); + WriteTrace(TraceUserInterface, TraceDebug, "2"); +} + +void CRomBrowser::RefreshRomBrowserStatic(CRomBrowser * _this) +{ + try + { + if (_this->m_hRomList == NULL) { return; } + + //delete cache + stdstr CacheFileName = g_Settings->LoadStringVal(SupportFile_RomListCache); + DeleteFile(CacheFileName.c_str()); + + //clear all current items + WriteTrace(TraceUserInterface, TraceDebug, "1"); + ListView_DeleteAllItems((HWND)_this->m_hRomList); + _this->DeallocateBrushs(); + _this->m_RomInfo.clear(); + WriteTrace(TraceUserInterface, TraceDebug, "2"); + InvalidateRect((HWND)_this->m_hRomList, NULL, TRUE); + Sleep(100); + WriteTrace(TraceUserInterface, TraceDebug, "3"); + + if (_this->m_WatchRomDir != g_Settings->LoadStringVal(Directory_Game)) + { + WriteTrace(TraceUserInterface, TraceDebug, "4"); + _this->WatchThreadStop(); + WriteTrace(TraceUserInterface, TraceDebug, "5"); + _this->WatchThreadStart(); + WriteTrace(TraceUserInterface, TraceDebug, "6"); + } + + WriteTrace(TraceUserInterface, TraceDebug, "7"); + stdstr RomDir = g_Settings->LoadStringVal(Directory_Game); + stdstr LastRom = g_Settings->LoadStringIndex(File_RecentGameFileIndex, 0); + WriteTrace(TraceUserInterface, TraceDebug, "8"); + + strlist FileNames; + _this->FillRomList(FileNames, CPath(RomDir), stdstr(""), LastRom.c_str()); + WriteTrace(TraceUserInterface, TraceDebug, "9"); + _this->SaveRomList(FileNames); + WriteTrace(TraceUserInterface, TraceDebug, "10"); + CloseHandle(_this->m_RefreshThread); + _this->m_RefreshThread = NULL; + WriteTrace(TraceUserInterface, TraceDebug, "11"); + } + catch (...) + { + WriteTrace(TraceUserInterface, TraceError, "Unhandled Exception "); + } +} + +void CRomBrowser::ResetRomBrowserColomuns(void) +{ + size_t Coloumn, index; + LV_COLUMNW lvColumn; + wchar_t szString[300]; + + GetFieldInfo(m_Fields); + + //Remove all current coloumns + memset(&lvColumn, 0, sizeof(lvColumn)); + lvColumn.mask = LVCF_FMT; + while (ListView_GetColumn(m_hRomList, 0, &lvColumn)) + { + ListView_DeleteColumn(m_hRomList, 0); + } + + //Add Colomuns + lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvColumn.fmt = LVCFMT_LEFT; + lvColumn.pszText = szString; + + for (Coloumn = 0; Coloumn < m_Fields.size(); Coloumn++) + { + for (index = 0; index < m_Fields.size(); index++) + { + if (m_Fields[index].Pos() == Coloumn) { break; } + } + if (index == m_Fields.size() || m_Fields[index].Pos() != Coloumn) + { + m_FieldType[Coloumn] = -1; + break; + } + + m_FieldType[Coloumn] = m_Fields[index].ID(); + lvColumn.cx = m_Fields[index].ColWidth(); + wcsncpy(szString, wGS(m_Fields[index].LangID()).c_str(), sizeof(szString) / sizeof(szString[0])); + SendMessage(m_hRomList, LVM_INSERTCOLUMNW, (WPARAM)(int32_t)(Coloumn), (LPARAM)(const LV_COLUMNW *)(&lvColumn)); + } +} + +void CRomBrowser::ResizeRomList(WORD nWidth, WORD nHeight) +{ + if (RomBrowserVisible()) + { + if (g_Settings->LoadDword(RomBrowser_Maximized) == 0 && nHeight != 0) + { + if (g_Settings->LoadDword(RomBrowser_Width) != nWidth) + { + g_Settings->SaveDword(RomBrowser_Width, nWidth); + } + if (g_Settings->LoadDword(RomBrowser_Height) != nHeight) + { + g_Settings->SaveDword(RomBrowser_Height, nHeight); + } + } + if (IsWindow((HWND)m_StatusWindow)) + { + RECT rc; + + GetWindowRect((HWND)m_StatusWindow, &rc); + nHeight -= (WORD)(rc.bottom - rc.top); + } + MoveWindow(m_hRomList, 0, 0, nWidth, nHeight, TRUE); + } +} + +bool CRomBrowser::RomBrowserVisible(void) +{ + if (!IsWindow(m_hRomList)) { return false; } + if (!IsWindowVisible(m_hRomList)) { return false; } + if (!m_Visible) { return false; } + return true; +} + +void CRomBrowser::RomBrowserToTop(void) +{ + BringWindowToTop(m_hRomList); + SetFocus(m_hRomList); +} + +void CRomBrowser::RomBrowserMaximize(bool Mazimize) +{ + g_Settings->SaveDword(RomBrowser_Maximized, (uint32_t)Mazimize); +} + +bool CRomBrowser::RomListDrawItem(int32_t idCtrl, uint32_t lParam) +{ + if (idCtrl != IDC_ROMLIST) { return false; } + LPDRAWITEMSTRUCT ditem = (LPDRAWITEMSTRUCT)lParam; + + RECT rcItem, rcDraw; + wchar_t String[300]; + LVITEMW lvItem; + HBRUSH hBrush; + LV_COLUMN lvc; + int32_t nColumn; + + lvItem.mask = LVIF_PARAM; + lvItem.iItem = ditem->itemID; + if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return false; } + lvItem.state = ListView_GetItemState(m_hRomList, ditem->itemID, -1); + bool bSelected = (lvItem.state & LVIS_SELECTED) != 0; + + if (lvItem.lParam < 0 || lvItem.lParam >= (LPARAM)m_RomInfo.size()) + { + return true; + } + ROM_INFO * pRomInfo = &m_RomInfo[lvItem.lParam]; + if (pRomInfo == NULL) + { + return true; + } + if (bSelected) + { + hBrush = (HBRUSH)pRomInfo->SelColorBrush; + SetTextColor(ditem->hDC, pRomInfo->SelTextColor); + } + else + { + hBrush = (HBRUSH)(COLOR_WINDOW + 1); + SetTextColor(ditem->hDC, pRomInfo->TextColor); + } + FillRect(ditem->hDC, &ditem->rcItem, hBrush); + SetBkMode(ditem->hDC, TRANSPARENT); + + //Draw + ListView_GetItemRect(m_hRomList, ditem->itemID, &rcItem, LVIR_LABEL); + lvItem.iSubItem = 0; + lvItem.cchTextMax = sizeof(String) / sizeof(String[0]); + lvItem.pszText = String; + SendMessageW(m_hRomList, LVM_GETITEMTEXTW, (WPARAM)ditem->itemID, (LPARAM)&lvItem); + + memcpy(&rcDraw, &rcItem, sizeof(RECT)); + rcDraw.right -= 3; + std::wstring text = String; + if (wcscmp(L"#340#", text.c_str()) == 0) + { + text = wGS(RB_NOT_GOOD_FILE); + } + + DrawTextW(ditem->hDC, text.c_str(), text.length(), &rcDraw, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_WORD_ELLIPSIS); + + memset(&lvc, 0, sizeof(lvc)); + lvc.mask = LVCF_FMT | LVCF_WIDTH; + for (nColumn = 1; ListView_GetColumn(m_hRomList, nColumn, &lvc); nColumn += 1) + { + rcItem.left = rcItem.right; + rcItem.right += lvc.cx; + + lvItem.iSubItem = nColumn; + lvItem.cchTextMax = sizeof(String) / sizeof(String[0]); + lvItem.pszText = String; + SendMessageW(m_hRomList, LVM_GETITEMTEXTW, ditem->itemID, (LPARAM)&lvItem); + memcpy(&rcDraw, &rcItem, sizeof(RECT)); + rcDraw.right -= 3; + text = String; + if (wcscmp(L"#340#", text.c_str()) == 0) + { + text = wGS(RB_NOT_GOOD_FILE); + } + DrawTextW(ditem->hDC, text.c_str(), text.length(), &rcDraw, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_WORD_ELLIPSIS); + } + return true; +} + +bool CRomBrowser::RomListNotify(int32_t idCtrl, uint32_t pnmh) +{ + if (idCtrl != IDC_ROMLIST) { return false; } + if (!RomBrowserVisible()) { return false; } + + switch (((LPNMHDR)pnmh)->code) + { + case LVN_COLUMNCLICK: RomList_ColoumnSortList(pnmh); break; + case NM_RETURN: RomList_OpenRom(pnmh); break; + case NM_DBLCLK: RomList_OpenRom(pnmh); break; + case LVN_GETDISPINFOW: RomList_GetDispInfo(pnmh); break; + case NM_RCLICK: RomList_PopupMenu(pnmh); break; + case NM_CLICK: + { + LONG iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); + if (iItem != -1) + { + m_AllowSelectionLastRom = false; + } + } + break; + default: + return false; + } + return true; +} + +void CRomBrowser::RomList_ColoumnSortList(uint32_t pnmh) +{ + LPNMLISTVIEW pnmv = (LPNMLISTVIEW)pnmh; + size_t index; + + for (index = 0; index < m_Fields.size(); index++) + { + if (m_Fields[index].Pos() == (size_t)pnmv->iSubItem) { break; } + } + if (m_Fields.size() == index) { return; } + if (_stricmp(g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, 0).c_str(), m_Fields[index].Name()) == 0) + { + g_Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex, 0, !g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, 0)); + } + else + { + int32_t count; + + for (count = NoOfSortKeys; count > 0; count--) + { + g_Settings->SaveStringIndex(RomBrowser_SortFieldIndex, count, g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, count - 1).c_str()); + g_Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex, count, g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, count - 1)); + } + g_Settings->SaveStringIndex(RomBrowser_SortFieldIndex, 0, m_Fields[index].Name()); + g_Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex, 0, true); + } + RomList_SortList(); +} + +int32_t CALLBACK CRomBrowser::RomList_CompareItems(uint32_t lParam1, uint32_t lParam2, uint32_t lParamSort) +{ + SORT_FIELD * SortFieldInfo = (SORT_FIELD *)lParamSort; + CRomBrowser * _this = SortFieldInfo->_this; + if (lParam1 < 0 || lParam1 >= _this->m_RomInfo.size()) + { + return 0; + } + if (lParam2 < 0 || lParam2 >= _this->m_RomInfo.size()) + { + return 0; + } + ROM_INFO * pRomInfo1 = &_this->m_RomInfo[SortFieldInfo->KeyAscend ? lParam1 : lParam2]; + ROM_INFO * pRomInfo2 = &_this->m_RomInfo[SortFieldInfo->KeyAscend ? lParam2 : lParam1]; + int32_t result; + + const wchar_t * GoodName1 = NULL, *GoodName2 = NULL; + if (SortFieldInfo->Key == RB_GoodName) + { + GoodName1 = wcscmp(L"#340#", pRomInfo1->GoodName) != 0 ? pRomInfo1->GoodName : m_UnknownGoodName.c_str(); + GoodName2 = wcscmp(L"#340#", pRomInfo2->GoodName) != 0 ? pRomInfo2->GoodName : m_UnknownGoodName.c_str(); + } + + switch (SortFieldInfo->Key) + { + case RB_FileName: result = (int32_t)lstrcmpi(pRomInfo1->FileName, pRomInfo2->FileName); break; + case RB_InternalName: result = (int32_t)lstrcmpiW(pRomInfo1->InternalName, pRomInfo2->InternalName); break; + case RB_GoodName: result = (int32_t)lstrcmpiW(GoodName1, GoodName2); break; + case RB_Status: result = (int32_t)lstrcmpiW(pRomInfo1->Status, pRomInfo2->Status); break; + case RB_RomSize: result = (int32_t)pRomInfo1->RomSize - (int32_t)pRomInfo2->RomSize; break; + case RB_CoreNotes: result = (int32_t)lstrcmpiW(pRomInfo1->CoreNotes, pRomInfo2->CoreNotes); break; + case RB_PluginNotes: result = (int32_t)lstrcmpiW(pRomInfo1->PluginNotes, pRomInfo2->PluginNotes); break; + case RB_UserNotes: result = (int32_t)lstrcmpiW(pRomInfo1->UserNotes, pRomInfo2->UserNotes); break; + case RB_CartridgeID: result = (int32_t)lstrcmpiW(pRomInfo1->CartID, pRomInfo2->CartID); break; + case RB_Manufacturer: result = (int32_t)pRomInfo1->Manufacturer - (int32_t)pRomInfo2->Manufacturer; break; + case RB_Country: result = (int32_t)pRomInfo1->Country - (int32_t)pRomInfo2->Country; break; + case RB_Developer: result = (int32_t)lstrcmpiW(pRomInfo1->Developer, pRomInfo2->Developer); break; + case RB_Crc1: result = (int32_t)pRomInfo1->CRC1 - (int32_t)pRomInfo2->CRC1; break; + case RB_Crc2: result = (int32_t)pRomInfo1->CRC2 - (int32_t)pRomInfo2->CRC2; break; + case RB_CICChip: result = (int32_t)pRomInfo1->CicChip - (int32_t)pRomInfo2->CicChip; break; + case RB_ReleaseDate: result = (int32_t)lstrcmpiW(pRomInfo1->ReleaseDate, pRomInfo2->ReleaseDate); break; + case RB_Players: result = (int32_t)pRomInfo1->Players - (int32_t)pRomInfo2->Players; break; + case RB_ForceFeedback: result = (int32_t)lstrcmpiW(pRomInfo1->ForceFeedback, pRomInfo2->ForceFeedback); break; + case RB_Genre: result = (int32_t)lstrcmpiW(pRomInfo1->Genre, pRomInfo2->Genre); break; + case RB_FileFormat: result = (int32_t)pRomInfo1->FileFormat - (int32_t)pRomInfo2->FileFormat; break; + default: result = 0; break; + } + return result; +} + +void CRomBrowser::RomList_GetDispInfo(uint32_t pnmh) +{ + LV_DISPINFOW * lpdi = (LV_DISPINFOW *)pnmh; + if (lpdi->item.lParam < 0 || lpdi->item.lParam >= (LPARAM)m_RomInfo.size()) + { + return; + } + + ROM_INFO * pRomInfo = &m_RomInfo[lpdi->item.lParam]; + + if (pRomInfo == NULL) + { + wcscpy(lpdi->item.pszText, L" "); + return; + } + + switch (m_FieldType[lpdi->item.iSubItem]) + { + case RB_FileName: wcsncpy(lpdi->item.pszText, stdstr(pRomInfo->FileName).ToUTF16(CP_ACP).c_str(), lpdi->item.cchTextMax); break; + case RB_InternalName: wcsncpy(lpdi->item.pszText, pRomInfo->InternalName, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_GoodName: wcsncpy(lpdi->item.pszText, pRomInfo->GoodName, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_CoreNotes: wcsncpy(lpdi->item.pszText, pRomInfo->CoreNotes, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_PluginNotes: wcsncpy(lpdi->item.pszText, pRomInfo->PluginNotes, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_Status: wcsncpy(lpdi->item.pszText, pRomInfo->Status, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_RomSize: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"%.1f MBit", (float)pRomInfo->RomSize / 0x20000); break; + case RB_CartridgeID: wcsncpy(lpdi->item.pszText, pRomInfo->CartID, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_Manufacturer: + switch (pRomInfo->Manufacturer) + { + case 'N':wcsncpy(lpdi->item.pszText, L"Nintendo", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 0: wcsncpy(lpdi->item.pszText, L"None", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + default: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"(Unknown %c (%X))", pRomInfo->Manufacturer, pRomInfo->Manufacturer); break; + } + break; + case RB_Country: + switch (pRomInfo->Country) + { + case '7': wcsncpy(lpdi->item.pszText, L"Beta", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'A': wcsncpy(lpdi->item.pszText, L"NTSC", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'D': wcsncpy(lpdi->item.pszText, L"Germany", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'E': wcsncpy(lpdi->item.pszText, L"America", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'F': wcsncpy(lpdi->item.pszText, L"France", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'J': wcsncpy(lpdi->item.pszText, L"Japan", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'I': wcsncpy(lpdi->item.pszText, L"Italy", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'P': wcsncpy(lpdi->item.pszText, L"Europe", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'S': wcsncpy(lpdi->item.pszText, L"Spain", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'U': wcsncpy(lpdi->item.pszText, L"Australia", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'X': wcsncpy(lpdi->item.pszText, L"PAL", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 'Y': wcsncpy(lpdi->item.pszText, L"PAL", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case 0: wcsncpy(lpdi->item.pszText, L"None", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + default: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"Unknown %c (%02X)", pRomInfo->Country, pRomInfo->Country); break; + } + break; + case RB_Crc1: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"0x%08X", pRomInfo->CRC1); break; + case RB_Crc2: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"0x%08X", pRomInfo->CRC2); break; + case RB_CICChip: + if (pRomInfo->CicChip < 0) + { + swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"Unknown CIC Chip"); + } + else if (pRomInfo->CicChip == CIC_NUS_8303) + { + swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"CIC-NUS-8303", pRomInfo->CicChip); + } + else if (pRomInfo->CicChip == CIC_NUS_5167) + { + swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"CIC-NUS-5167", pRomInfo->CicChip); + } + else + { + swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"CIC-NUS-610%d", pRomInfo->CicChip); + } + break; + case RB_UserNotes: wcsncpy(lpdi->item.pszText, pRomInfo->UserNotes, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_Developer: wcsncpy(lpdi->item.pszText, pRomInfo->Developer, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_ReleaseDate: wcsncpy(lpdi->item.pszText, pRomInfo->ReleaseDate, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_Genre: wcsncpy(lpdi->item.pszText, pRomInfo->Genre, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_Players: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"%d", pRomInfo->Players); break; + case RB_ForceFeedback: wcsncpy(lpdi->item.pszText, pRomInfo->ForceFeedback, lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case RB_FileFormat: + switch (pRomInfo->FileFormat) + { + case Format_Uncompressed: wcsncpy(lpdi->item.pszText, L"Uncompressed", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case Format_Zip: wcsncpy(lpdi->item.pszText, L"Zip", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + case Format_7zip: wcsncpy(lpdi->item.pszText, L"7zip", lpdi->item.cchTextMax / sizeof(wchar_t)); break; + default: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"Unknown (%X)", pRomInfo->FileFormat); break; + } + break; + default: wcsncpy(lpdi->item.pszText, L" ", lpdi->item.cchTextMax); + } + if (lpdi->item.pszText == NULL || wcslen(lpdi->item.pszText) == 0) { lpdi->item.pszText = L" "; } +} + +void CRomBrowser::RomList_OpenRom(uint32_t /*pnmh*/) +{ + ROM_INFO * pRomInfo; + LV_ITEM lvItem; + LONG iItem; + + iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); + if (iItem == -1) { return; } + + memset(&lvItem, 0, sizeof(LV_ITEM)); + lvItem.mask = LVIF_PARAM; + lvItem.iItem = iItem; + if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return; } + if (lvItem.lParam < 0 || lvItem.lParam >= (LPARAM)m_RomInfo.size()) + { + return; + } + pRomInfo = &m_RomInfo[lvItem.lParam]; + + if (!pRomInfo) { return; } + m_StopRefresh = true; + + delete g_DDRom; + g_DDRom = NULL; + + CN64System::RunFileImage(pRomInfo->szFullFileName); +} + +void CRomBrowser::RomList_PopupMenu(uint32_t /*pnmh*/) +{ + LONG iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); + m_SelectedRom = ""; + if (iItem != -1) + { + LV_ITEM lvItem; + memset(&lvItem, 0, sizeof(LV_ITEM)); + lvItem.mask = LVIF_PARAM; + lvItem.iItem = iItem; + if (!SendMessageW(m_hRomList, LVM_GETITEMW, 0, (LPARAM)&lvItem)) { return; } + if (lvItem.lParam < 0 || lvItem.lParam >= (LPARAM)m_RomInfo.size()) + { + return; + } + ROM_INFO * pRomInfo = &m_RomInfo[lvItem.lParam]; + + if (!pRomInfo) { return; } + m_SelectedRom = pRomInfo->szFullFileName; + } + + //Load the menu + HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_POPUP)); + HMENU hPopupMenu = (HMENU)GetSubMenu(hMenu, 0); + + //Fix up menu + MenuSetText(hPopupMenu, 0, wGS(POPUP_PLAY).c_str(), NULL); + MenuSetText(hPopupMenu, 1, wGS(POPUP_PLAYDISK).c_str(), NULL); + MenuSetText(hPopupMenu, 3, wGS(MENU_REFRESH).c_str(), NULL); + MenuSetText(hPopupMenu, 4, wGS(MENU_CHOOSE_ROM).c_str(), NULL); + MenuSetText(hPopupMenu, 6, wGS(POPUP_INFO).c_str(), NULL); + MenuSetText(hPopupMenu, 7, wGS(POPUP_GFX_PLUGIN).c_str(), NULL); + MenuSetText(hPopupMenu, 9, wGS(POPUP_SETTINGS).c_str(), NULL); + MenuSetText(hPopupMenu, 10, wGS(POPUP_CHEATS).c_str(), NULL); + + if (m_SelectedRom.size() == 0) + { + DeleteMenu(hPopupMenu, 10, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 9, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 8, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 7, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 6, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 5, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 2, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 1, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 0, MF_BYPOSITION); + } + else + { + bool inBasicMode = g_Settings->LoadDword(UserInterface_BasicMode) != 0; + bool CheatsRemembered = g_Settings->LoadDword(Setting_RememberCheats) != 0; + if (!CheatsRemembered) { DeleteMenu(hPopupMenu, 10, MF_BYPOSITION); } + if (inBasicMode) { DeleteMenu(hPopupMenu, 9, MF_BYPOSITION); } + if (inBasicMode && !CheatsRemembered) { DeleteMenu(hPopupMenu, 8, MF_BYPOSITION); } + DeleteMenu(hPopupMenu, 7, MF_BYPOSITION); + if (!inBasicMode && g_Plugins && g_Plugins->Gfx() && g_Plugins->Gfx()->GetRomBrowserMenu != NULL) + { + HMENU GfxMenu = (HMENU)g_Plugins->Gfx()->GetRomBrowserMenu(); + if (GfxMenu) + { + MENUITEMINFO lpmii; + InsertMenuW(hPopupMenu, 7, MF_POPUP | MF_BYPOSITION, (uint32_t)GfxMenu, wGS(POPUP_GFX_PLUGIN).c_str()); + lpmii.cbSize = sizeof(MENUITEMINFO); + lpmii.fMask = MIIM_STATE; + lpmii.fState = 0; + SetMenuItemInfo(hPopupMenu, (uint32_t)GfxMenu, MF_BYCOMMAND, &lpmii); + } + } + } + + //Get the current Mouse location + POINT Mouse; + GetCursorPos(&Mouse); + + //Show the menu + TrackPopupMenu(hPopupMenu, 0, Mouse.x, Mouse.y, 0, m_MainWindow, NULL); + DestroyMenu(hMenu); +} + +void CRomBrowser::RomList_SortList(void) +{ + SORT_FIELD SortFieldInfo; + m_UnknownGoodName = wGS(RB_NOT_GOOD_FILE); + + for (int32_t count = NoOfSortKeys; count >= 0; count--) + { + stdstr SortFieldName = g_Settings->LoadStringIndex(RomBrowser_SortFieldIndex, count); + + size_t index; + for (index = 0; index < m_Fields.size(); index++) + { + if (_stricmp(m_Fields[index].Name(), SortFieldName.c_str()) == 0) { break; } + } + if (index >= m_Fields.size()) { continue; } + SortFieldInfo._this = this; + SortFieldInfo.Key = index; + SortFieldInfo.KeyAscend = g_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, count) != 0; + ListView_SortItems(m_hRomList, RomList_CompareItems, &SortFieldInfo); + } +} + +/* +* SaveRomList - save all the rom information about the current roms in the rom brower +* to a cache file, so it is quick to reload the information +*/ +void CRomBrowser::SaveRomList(strlist & FileList) +{ + MD5 ListHash = RomListHash(FileList); + + stdstr FileName = g_Settings->LoadStringVal(SupportFile_RomListCache); + HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); + + DWORD dwWritten; + WriteFile(hFile, ListHash.raw_digest(), 16, &dwWritten, NULL); + + //Write the size of ROM_INFO + int32_t RomInfoSize = sizeof(ROM_INFO); + WriteFile(hFile, &RomInfoSize, sizeof(RomInfoSize), &dwWritten, NULL); + + //Write the Number of entries + int32_t Entries = m_RomInfo.size(); + WriteFile(hFile, &Entries, sizeof(Entries), &dwWritten, NULL); + + //Write Every Entry + for (int32_t count = 0; count < Entries; count++) + { + ROM_INFO * RomInfo = &m_RomInfo[count]; + WriteFile(hFile, RomInfo, RomInfoSize, &dwWritten, NULL); + } + + //Close the file handle + CloseHandle(hFile); +} + +void CRomBrowser::SaveRomListColoumnInfo(void) +{ + WriteTrace(TraceUserInterface, TraceDebug, "Start"); + // if (!RomBrowserVisible()) { return; } + if (g_Settings == NULL) { return; } + + LV_COLUMN lvColumn; + + memset(&lvColumn, 0, sizeof(lvColumn)); + lvColumn.mask = LVCF_WIDTH; + + for (size_t Coloumn = 0; ListView_GetColumn(m_hRomList, Coloumn, &lvColumn); Coloumn++) + { + size_t index; + bool bFound = false; + for (index = 0; index < m_Fields.size(); index++) + { + if (m_Fields[index].Pos() == Coloumn) + { + bFound = true; + break; + } + } + if (bFound) + { + if (m_Fields[index].ColWidth() != lvColumn.cx) + { + m_Fields[index].SetColWidth(lvColumn.cx); + } + } + } + WriteTrace(TraceUserInterface, TraceDebug, "Done"); +} + +int32_t CALLBACK CRomBrowser::SelectRomDirCallBack(HWND hwnd, uint32_t uMsg, uint32_t /*lp*/, uint32_t lpData) +{ + switch (uMsg) + { + case BFFM_INITIALIZED: + // WParam is TRUE since you are passing a path. + // It would be FALSE if you were passing a pidl. + if (lpData) + { + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData); + SetWindowTextW(hwnd, wGS(DIR_SELECT_ROM).c_str()); + } + break; + } + return 0; +} + +void CRomBrowser::SelectRomDir(void) +{ + wchar_t SelectedDir[MAX_PATH]; + LPITEMIDLIST pidl; + BROWSEINFOW bi; + + std::wstring title = wGS(SELECT_ROM_DIR); + + WriteTrace(TraceUserInterface, TraceDebug, "1"); + stdstr RomDir = g_Settings->LoadStringVal(Directory_Game); + bi.hwndOwner = m_MainWindow; + bi.pidlRoot = NULL; + bi.pszDisplayName = SelectedDir; + bi.lpszTitle = title.c_str(); + bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; + bi.lpfn = (BFFCALLBACK)SelectRomDirCallBack; + bi.lParam = (uint32_t)RomDir.c_str(); + WriteTrace(TraceUserInterface, TraceDebug, "2"); + if ((pidl = SHBrowseForFolderW(&bi)) != NULL) + { + WriteTrace(TraceUserInterface, TraceDebug, "3"); + char Directory[_MAX_PATH]; + if (SHGetPathFromIDList(pidl, Directory)) + { + int32_t len = strlen(Directory); + + WriteTrace(TraceUserInterface, TraceDebug, "4"); + if (Directory[len - 1] != '\\') + { + strcat(Directory, "\\"); + } + WriteTrace(TraceUserInterface, TraceDebug, "5"); + WriteTrace(TraceUserInterface, TraceDebug, "6"); + g_Settings->SaveString(Directory_Game, Directory); + WriteTrace(TraceUserInterface, TraceDebug, "7"); + Notify().AddRecentDir(Directory); + WriteTrace(TraceUserInterface, TraceDebug, "8"); + RefreshRomBrowser(); + WriteTrace(TraceUserInterface, TraceDebug, "9"); + } + } +} + +void CRomBrowser::FixRomListWindow(void) +{ + //Change the window Style + long Style = GetWindowLong(m_MainWindow, GWL_STYLE) | WS_SIZEBOX | WS_MAXIMIZEBOX; + SetWindowLong(m_MainWindow, GWL_STYLE, Style); + + //Get the current window size + RECT rect; + GetWindowRect(m_MainWindow, &rect); + + //We find the middle position of the screen, we use this if theres no setting + int32_t X = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2; + int32_t Y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2; + + //Load the value from settings, if none is available, default to above + g_Settings->LoadDword(RomBrowser_Top, (uint32_t &)Y); + g_Settings->LoadDword(RomBrowser_Left, (uint32_t &)X); + + SetWindowPos(m_MainWindow, NULL, X, Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + + //Fix height and width + int32_t Width = g_Settings->LoadDword(RomBrowser_Width); + int32_t Height = g_Settings->LoadDword(RomBrowser_Height); + + if (Width < 200) { Width = 200; } + if (Height < 200) { Height = 200; } + + RECT rcClient; + rcClient.top = 0; + rcClient.bottom = Height; + rcClient.left = 0; + rcClient.right = Width; + AdjustWindowRect(&rcClient, GetWindowLong(m_MainWindow, GWL_STYLE), true); + + int32_t WindowHeight = rcClient.bottom - rcClient.top; + int32_t WindowWidth = rcClient.right - rcClient.left; + + SetWindowPos(m_MainWindow, NULL, 0, 0, WindowWidth, WindowHeight, SWP_NOMOVE | SWP_NOZORDER); +} + +void CRomBrowser::ShowRomList(void) +{ + if (m_Visible || g_Settings->LoadBool(GameRunning_CPU_Running)) { return; } + m_ShowingRomBrowser = true; + WatchThreadStop(); + if (m_hRomList == NULL) { CreateRomListControl(); } + EnableWindow(m_hRomList, TRUE); + ShowWindow(m_hRomList, SW_SHOW); + FixRomListWindow(); + m_AllowSelectionLastRom = true; + + //Make sure selected item is visible + int32_t iItem = ListView_GetNextItem(m_hRomList, -1, LVNI_SELECTED); + ListView_EnsureVisible(m_hRomList, iItem, FALSE); + + //Mark the window as visible + m_Visible = true; + + RECT rcWindow; + if (GetClientRect(m_MainWindow, &rcWindow)) + { + ResizeRomList((WORD)rcWindow.right, (WORD)rcWindow.bottom); + } + + InvalidateRect(m_hRomList, NULL, TRUE); + + //Start thread to watch for dir changed + WatchThreadStart(); + m_ShowingRomBrowser = false; +} + +void CRomBrowser::HideRomList(void) +{ + if (!RomBrowserVisible()) { return; } + ShowWindow(m_MainWindow, SW_HIDE); + + SaveRomListColoumnInfo(); + WatchThreadStop(); + + //Make sure the window does disappear + Sleep(100); + + //Disable the rom list + EnableWindow(m_hRomList, FALSE); + ShowWindow(m_hRomList, SW_HIDE); + + if (g_Settings->LoadBool(RomBrowser_Maximized)) { ShowWindow(m_MainWindow, SW_RESTORE); } + + //Change the window style + long Style = GetWindowLong(m_MainWindow, GWL_STYLE) & ~(WS_SIZEBOX | WS_MAXIMIZEBOX); + SetWindowLong(m_MainWindow, GWL_STYLE, Style); + + //Move window to correct location + RECT rect; + GetWindowRect(m_MainWindow, &rect); + int32_t X = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2; + int32_t Y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2; + g_Settings->LoadDword(UserInterface_MainWindowTop, (uint32_t &)Y); + g_Settings->LoadDword(UserInterface_MainWindowLeft, (uint32_t &)X); + SetWindowPos(m_MainWindow, NULL, X, Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + + //Mark the window as not visible + m_Visible = false; + + //Make the main window visible again + ShowWindow(m_MainWindow, SW_SHOW); + BringWindowToTop(m_MainWindow); + PostMessage(m_MainWindow, WM_MAKE_FOCUS, 0, 0); +} + +bool CRomBrowser::RomDirNeedsRefresh(void) +{ + bool InWatchThread = (m_WatchThreadID == GetCurrentThreadId()); + + //Get Old MD5 of file names + stdstr FileName = g_Settings->LoadStringVal(SupportFile_RomListCache); + HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + //if file does not exist then refresh the data + return true; + } + + DWORD dwRead; + unsigned char CurrentFileMD5[16]; + ReadFile(hFile, &CurrentFileMD5, sizeof(CurrentFileMD5), &dwRead, NULL); + CloseHandle(hFile); + + //Get Current MD5 of file names + strlist FileNames; + if (!GetRomFileNames(FileNames, CPath(g_Settings->LoadStringVal(Directory_Game)), stdstr(""), InWatchThread)) + { + return false; + } + FileNames.sort(); + + MD5 NewMd5 = RomListHash(FileNames); + if (memcmp(NewMd5.raw_digest(), CurrentFileMD5, sizeof(CurrentFileMD5)) != 0) + { + return true; + } + return false; +} + +MD5 CRomBrowser::RomListHash(strlist & FileList) +{ + stdstr NewFileNames; + FileList.sort(); + for (strlist::iterator iter = FileList.begin(); iter != FileList.end(); iter++) + { + NewFileNames += *iter; + NewFileNames += ";"; + } + MD5 md5Hash((const unsigned char *)NewFileNames.c_str(), NewFileNames.length()); + WriteTrace(TraceUserInterface, TraceDebug, "%s - %s", md5Hash.hex_digest(), NewFileNames.c_str()); + return md5Hash; +} + +void CRomBrowser::WatchRomDirChanged(CRomBrowser * _this) +{ + try + { + WriteTrace(TraceUserInterface, TraceDebug, "1"); + _this->m_WatchRomDir = g_Settings->LoadStringVal(Directory_Game); + WriteTrace(TraceUserInterface, TraceDebug, "2"); + if (_this->RomDirNeedsRefresh()) + { + WriteTrace(TraceUserInterface, TraceDebug, "2a"); + PostMessage((HWND)_this->m_MainWindow, WM_COMMAND, ID_FILE_REFRESHROMLIST, 0); + } + WriteTrace(TraceUserInterface, TraceDebug, "3"); + HANDLE hChange[] = { + _this->m_WatchStopEvent, + FindFirstChangeNotification(_this->m_WatchRomDir.c_str(), g_Settings->LoadDword(RomBrowser_Recursive), FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE), + }; + WriteTrace(TraceUserInterface, TraceDebug, "4"); + for (;;) + { + WriteTrace(TraceUserInterface, TraceDebug, "5"); + if (WaitForMultipleObjects(sizeof(hChange) / sizeof(hChange[0]), hChange, false, INFINITE) == WAIT_OBJECT_0) + { + WriteTrace(TraceUserInterface, TraceDebug, "5a"); + FindCloseChangeNotification(hChange[1]); + return; + } + WriteTrace(TraceUserInterface, TraceDebug, "5b"); + if (_this->RomDirNeedsRefresh()) + { + PostMessage((HWND)_this->m_MainWindow, WM_COMMAND, ID_FILE_REFRESHROMLIST, 0); + } + WriteTrace(TraceUserInterface, TraceDebug, "5c"); + if (!FindNextChangeNotification(hChange[1])) + { + FindCloseChangeNotification(hChange[1]); + return; + } + WriteTrace(TraceUserInterface, TraceDebug, "5d"); + } + } + catch (...) + { + WriteTrace(TraceUserInterface, TraceError, __FUNCTION__ ": Unhandled Exception"); + } +} + +void CRomBrowser::WatchThreadStart(void) +{ + WriteTrace(TraceUserInterface, TraceDebug, "1"); + WatchThreadStop(); + WriteTrace(TraceUserInterface, TraceDebug, "2"); + m_WatchStopEvent = CreateEvent(NULL, true, false, NULL); + WriteTrace(TraceUserInterface, TraceDebug, "3"); + m_WatchThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WatchRomDirChanged, this, 0, &m_WatchThreadID); + WriteTrace(TraceUserInterface, TraceDebug, "4"); +} + +void CRomBrowser::WatchThreadStop(void) +{ + if (m_WatchThread == NULL) + { + return; + } + WriteTrace(TraceUserInterface, TraceDebug, "1"); + SetEvent(m_WatchStopEvent); + DWORD ExitCode = 0; + for (int32_t count = 0; count < 20; count++) + { + WriteTrace(TraceUserInterface, TraceDebug, "2"); + GetExitCodeThread(m_WatchThread, &ExitCode); + if (ExitCode != STILL_ACTIVE) + { + break; + } + Sleep(200); + } + WriteTrace(TraceUserInterface, TraceDebug, "3"); + if (ExitCode == STILL_ACTIVE) + { + WriteTrace(TraceUserInterface, TraceDebug, "3a"); + TerminateThread(m_WatchThread, 0); + } + WriteTrace(TraceUserInterface, TraceDebug, "4"); + + CloseHandle(m_WatchThread); + CloseHandle(m_WatchStopEvent); + m_WatchStopEvent = NULL; + m_WatchThread = NULL; + m_WatchThreadID = 0; + WriteTrace(TraceUserInterface, TraceDebug, "5"); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-AdvancedOptions.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-AdvancedOptions.cpp index ee3dd028b..427a39efe 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-AdvancedOptions.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-AdvancedOptions.cpp @@ -1,73 +1,73 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" - -CAdvancedOptionsPage::CAdvancedOptionsPage(HWND hParent, const RECT & rcDispay) -{ - if (!Create(hParent, rcDispay)) - { - return; - } - - //Set the text for all gui Items - SetDlgItemTextW(m_hWnd, IDC_START_ON_ROM_OPEN, wGS(ADVANCE_AUTO_START).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ZIP, wGS(ADVANCE_COMPRESS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_DEBUGGER, wGS(ADVANCE_DEBUGGER).c_str()); - SetDlgItemTextW(m_hWnd, IDC_REMEMBER_CHEAT, wGS(OPTION_REMEMBER_CHEAT).c_str()); - SetDlgItemTextW(m_hWnd, IDC_CHECK_RUNNING, wGS(OPTION_CHECK_RUNNING).c_str()); - SetDlgItemTextW(m_hWnd, IDC_DISPLAY_FRAMERATE, wGS(OPTION_CHANGE_FR).c_str()); - - AddModCheckBox(GetDlgItem(IDC_START_ON_ROM_OPEN), Setting_AutoStart); - AddModCheckBox(GetDlgItem(IDC_ZIP), Setting_AutoZipInstantSave); - AddModCheckBox(GetDlgItem(IDC_DEBUGGER), Debugger_Enabled); - AddModCheckBox(GetDlgItem(IDC_REMEMBER_CHEAT), Setting_RememberCheats); - AddModCheckBox(GetDlgItem(IDC_CHECK_RUNNING), Setting_CheckEmuRunning); - AddModCheckBox(GetDlgItem(IDC_DISPLAY_FRAMERATE), UserInterface_DisplayFrameRate); - - CModifiedComboBox * ComboBox; - ComboBox = AddModComboBox(GetDlgItem(IDC_FRAME_DISPLAY_TYPE), UserInterface_FrameDisplayType); - if (ComboBox) - { - ComboBox->AddItemW(wGS(STR_FR_VIS).c_str(), FR_VIs); - ComboBox->AddItemW(wGS(STR_FR_DLS).c_str(), FR_DLs); - ComboBox->AddItemW(wGS(STR_FR_PERCENT).c_str(), FR_PERCENT); - } - - UpdatePageSettings(); -} - -void CAdvancedOptionsPage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void CAdvancedOptionsPage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void CAdvancedOptionsPage::ApplySettings(bool UpdateScreen) -{ - CSettingsPageImpl::ApplySettings(UpdateScreen); -} - -bool CAdvancedOptionsPage::EnableReset(void) -{ - if (CSettingsPageImpl::EnableReset()) { return true; } - return false; -} - -void CAdvancedOptionsPage::ResetPage() -{ - CSettingsPageImpl::ResetPage(); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" + +CAdvancedOptionsPage::CAdvancedOptionsPage(HWND hParent, const RECT & rcDispay) +{ + if (!Create(hParent, rcDispay)) + { + return; + } + + //Set the text for all gui Items + SetDlgItemTextW(m_hWnd, IDC_START_ON_ROM_OPEN, wGS(ADVANCE_AUTO_START).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ZIP, wGS(ADVANCE_COMPRESS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_DEBUGGER, wGS(ADVANCE_DEBUGGER).c_str()); + SetDlgItemTextW(m_hWnd, IDC_REMEMBER_CHEAT, wGS(OPTION_REMEMBER_CHEAT).c_str()); + SetDlgItemTextW(m_hWnd, IDC_CHECK_RUNNING, wGS(OPTION_CHECK_RUNNING).c_str()); + SetDlgItemTextW(m_hWnd, IDC_DISPLAY_FRAMERATE, wGS(OPTION_CHANGE_FR).c_str()); + + AddModCheckBox(GetDlgItem(IDC_START_ON_ROM_OPEN), Setting_AutoStart); + AddModCheckBox(GetDlgItem(IDC_ZIP), Setting_AutoZipInstantSave); + AddModCheckBox(GetDlgItem(IDC_DEBUGGER), Debugger_Enabled); + AddModCheckBox(GetDlgItem(IDC_REMEMBER_CHEAT), Setting_RememberCheats); + AddModCheckBox(GetDlgItem(IDC_CHECK_RUNNING), Setting_CheckEmuRunning); + AddModCheckBox(GetDlgItem(IDC_DISPLAY_FRAMERATE), UserInterface_DisplayFrameRate); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(IDC_FRAME_DISPLAY_TYPE), UserInterface_FrameDisplayType); + if (ComboBox) + { + ComboBox->AddItemW(wGS(STR_FR_VIS).c_str(), FR_VIs); + ComboBox->AddItemW(wGS(STR_FR_DLS).c_str(), FR_DLs); + ComboBox->AddItemW(wGS(STR_FR_PERCENT).c_str(), FR_PERCENT); + } + + UpdatePageSettings(); +} + +void CAdvancedOptionsPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void CAdvancedOptionsPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void CAdvancedOptionsPage::ApplySettings(bool UpdateScreen) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CAdvancedOptionsPage::EnableReset(void) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CAdvancedOptionsPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-AdvancedOptions.h b/Source/Project64/UserInterface/Settings/SettingsPage-AdvancedOptions.h index 85d0e4243..c76dd7ffb 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-AdvancedOptions.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-AdvancedOptions.h @@ -1,42 +1,42 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CAdvancedOptionsPage : - public CSettingsPageImpl, - public CSettingsPage -{ - - BEGIN_MSG_MAP_EX(CAdvancedOptionsPage) - COMMAND_ID_HANDLER_EX(IDC_START_ON_ROM_OPEN,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_ZIP,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_DEBUGGER,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_REMEMBER_CHEAT,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_CHECK_RUNNING,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_DISPLAY_FRAMERATE,CheckBoxChanged) - COMMAND_HANDLER_EX(IDC_FRAME_DISPLAY_TYPE,LBN_SELCHANGE,ComboBoxChanged) - - END_MSG_MAP() - - enum { IDD = IDD_Settings_Advanced }; - -public: - CAdvancedOptionsPage(HWND hParent, const RECT & rcDispay ); - - LanguageStringID PageTitle ( void ) { return TAB_ADVANCED; } - void HidePage ( void ); - void ShowPage ( void ); - void ApplySettings ( bool UpdateScreen ); - bool EnableReset ( void ); - void ResetPage ( void ); - -private: -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CAdvancedOptionsPage : + public CSettingsPageImpl, + public CSettingsPage +{ + + BEGIN_MSG_MAP_EX(CAdvancedOptionsPage) + COMMAND_ID_HANDLER_EX(IDC_START_ON_ROM_OPEN,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ZIP,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_DEBUGGER,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_REMEMBER_CHEAT,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_CHECK_RUNNING,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_DISPLAY_FRAMERATE,CheckBoxChanged) + COMMAND_HANDLER_EX(IDC_FRAME_DISPLAY_TYPE,LBN_SELCHANGE,ComboBoxChanged) + + END_MSG_MAP() + + enum { IDD = IDD_Settings_Advanced }; + +public: + CAdvancedOptionsPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_ADVANCED; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Directories.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-Directories.cpp index 3420e53cf..e760ffed7 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Directories.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Directories.cpp @@ -1,354 +1,354 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" - -COptionsDirectoriesPage::COptionsDirectoriesPage(HWND hParent, const RECT & rcDispay) : -m_InUpdateSettings(false) -{ - Create(hParent); - if (m_hWnd == NULL) - { - return; - } - SetWindowPos(HWND_TOP, &rcDispay, SWP_HIDEWINDOW); - - m_PluginGroup.Attach(GetDlgItem(IDC_DIR_FRAME1)); - m_AutoSaveGroup.Attach(GetDlgItem(IDC_DIR_FRAME3)); - m_InstantSaveGroup.Attach(GetDlgItem(IDC_DIR_FRAME4)); - m_ScreenShotGroup.Attach(GetDlgItem(IDC_DIR_FRAME5)); - m_TextureGroup.Attach(GetDlgItem(IDC_DIR_TEXTURE_FRAME)); - - m_PluginDir.Attach(GetDlgItem(IDC_PLUGIN_DIR)); - m_AutoSaveDir.Attach(GetDlgItem(IDC_AUTO_DIR)); - m_InstantSaveDir.Attach(GetDlgItem(IDC_INSTANT_DIR)); - m_ScreenShotDir.Attach(GetDlgItem(IDC_SNAP_DIR)); - m_TextureDir.Attach(GetDlgItem(IDC_TEXTURE_DIR)); - - m_PluginDefault.Attach(GetDlgItem(IDC_PLUGIN_DEFAULT)); - m_PluginSelected.Attach(GetDlgItem(IDC_PLUGIN_OTHER)); - m_AutoSaveDefault.Attach(GetDlgItem(IDC_AUTO_DEFAULT)); - m_AutoSaveSelected.Attach(GetDlgItem(IDC_AUTO_OTHER)); - m_InstantDefault.Attach(GetDlgItem(IDC_INSTANT_DEFAULT)); - m_InstantSelected.Attach(GetDlgItem(IDC_INSTANT_OTHER)); - m_ScreenShotDefault.Attach(GetDlgItem(IDC_SNAP_DEFAULT)); - m_ScreenShotSelected.Attach(GetDlgItem(IDC_SNAP_OTHER)); - m_TextureDefault.Attach(GetDlgItem(IDC_TEXTURE_DEFAULT)); - m_TextureSelected.Attach(GetDlgItem(IDC_TEXTURE_OTHER)); - - //Set Text language for the dialog box - ::SetWindowTextW(m_PluginGroup.m_hWnd, wGS(DIR_PLUGIN).c_str()); - ::SetWindowTextW(m_AutoSaveGroup.m_hWnd, wGS(DIR_AUTO_SAVE).c_str()); - ::SetWindowTextW(m_InstantSaveGroup.m_hWnd, wGS(DIR_INSTANT_SAVE).c_str()); - ::SetWindowTextW(m_ScreenShotGroup.m_hWnd, wGS(DIR_SCREEN_SHOT).c_str()); - ::SetWindowTextW(m_TextureGroup.m_hWnd, wGS(DIR_TEXTURE).c_str()); - - UpdatePageSettings(); -} - -int CALLBACK COptionsDirectoriesPage::SelectDirCallBack(HWND hwnd, DWORD uMsg, DWORD /*lp*/, DWORD lpData) -{ - switch (uMsg) - { - case BFFM_INITIALIZED: - // WParam is TRUE since you are passing a path. - // It would be FALSE if you were passing a pidl. - if (lpData) - { - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData); - } - break; - } - return 0; -} - -void COptionsDirectoriesPage::SelectDirectory(LanguageStringID Title, CModifiedEditBox & EditBox, CModifiedButton & Default, CModifiedButton & selected) -{ - wchar_t Buffer[MAX_PATH], Directory[MAX_PATH]; - LPITEMIDLIST pidl; - BROWSEINFOW bi; - - stdstr InitialDir = EditBox.GetWindowText(); - std::wstring wTitle = wGS(Title); - bi.hwndOwner = m_hWnd; - bi.pidlRoot = NULL; - bi.pszDisplayName = Buffer; - bi.lpszTitle = wTitle.c_str(); - bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; - bi.lpfn = (BFFCALLBACK)SelectDirCallBack; - bi.lParam = (DWORD)InitialDir.c_str(); - if ((pidl = SHBrowseForFolderW(&bi)) != NULL) - { - if (SHGetPathFromIDListW(pidl, Directory)) - { - stdstr path; - CPath SelectedDir(path.FromUTF16(Directory), ""); - EditBox.SetChanged(true); - EditBox.SetWindowText(SelectedDir); - Default.SetChanged(true); - Default.SetCheck(BST_UNCHECKED); - selected.SetCheck(BM_SETCHECK); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); - } - } -} - -void COptionsDirectoriesPage::PluginDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - if (m_InUpdateSettings) { return; } - m_PluginDir.SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsDirectoriesPage::AutoSaveDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - if (m_InUpdateSettings) { return; } - m_AutoSaveDir.SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsDirectoriesPage::InstantSaveDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - if (m_InUpdateSettings) { return; } - m_InstantSaveDir.SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsDirectoriesPage::SnapShotDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - if (m_InUpdateSettings) { return; } - m_ScreenShotDir.SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsDirectoriesPage::TextureDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - if (m_InUpdateSettings) { return; } - m_TextureDir.SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsDirectoriesPage::SelectPluginDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - SelectDirectory(DIR_SELECT_PLUGIN, m_PluginDir, m_PluginDefault, m_PluginSelected); -} - -void COptionsDirectoriesPage::SelectAutoDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - SelectDirectory(DIR_SELECT_AUTO, m_AutoSaveDir, m_AutoSaveDefault, m_AutoSaveSelected); -} - -void COptionsDirectoriesPage::SelectInstantDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - SelectDirectory(DIR_SELECT_INSTANT, m_InstantSaveDir, m_InstantDefault, m_InstantSelected); -} - -void COptionsDirectoriesPage::SelectSnapShotDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - SelectDirectory(DIR_SELECT_SCREEN, m_ScreenShotDir, m_ScreenShotDefault, m_ScreenShotSelected); -} - -void COptionsDirectoriesPage::SelectTextureDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - SelectDirectory(DIR_SELECT_TEXTURE, m_TextureDir, m_TextureDefault, m_TextureSelected); -} - -void COptionsDirectoriesPage::UpdatePageSettings() -{ - stdstr Directory; - - m_InUpdateSettings = true; - m_PluginDir.SetChanged(g_Settings->LoadStringVal(Directory_PluginSelected, Directory)); - m_PluginDir.SetWindowText(Directory.c_str()); - m_AutoSaveDir.SetChanged(g_Settings->LoadStringVal(Directory_NativeSaveSelected, Directory)); - m_AutoSaveDir.SetWindowText(Directory.c_str()); - m_InstantSaveDir.SetChanged(g_Settings->LoadStringVal(Directory_InstantSaveSelected, Directory)); - m_InstantSaveDir.SetWindowText(Directory.c_str()); - m_ScreenShotDir.SetChanged(g_Settings->LoadStringVal(Directory_SnapShotSelected, Directory)); - m_ScreenShotDir.SetWindowText(Directory.c_str()); - m_TextureDir.SetChanged(g_Settings->LoadStringVal(Directory_TextureSelected, Directory)); - m_TextureDir.SetWindowText(Directory.c_str()); - - bool UseSelected; - m_PluginDefault.SetChanged(g_Settings->LoadBool(Directory_PluginUseSelected, UseSelected)); - m_PluginDefault.SetCheck(!UseSelected); - m_PluginSelected.SetCheck(UseSelected); - - m_AutoSaveDefault.SetChanged(g_Settings->LoadBool(Directory_NativeSaveUseSelected, UseSelected)); - m_AutoSaveDefault.SetCheck(!UseSelected); - m_AutoSaveSelected.SetCheck(UseSelected); - - m_InstantDefault.SetChanged(g_Settings->LoadBool(Directory_InstantSaveUseSelected, UseSelected)); - m_InstantDefault.SetCheck(!UseSelected); - m_InstantSelected.SetCheck(UseSelected); - - m_ScreenShotDefault.SetChanged(g_Settings->LoadBool(Directory_SnapShotUseSelected, UseSelected)); - m_ScreenShotDefault.SetCheck(!UseSelected); - m_ScreenShotSelected.SetCheck(UseSelected); - - m_TextureDefault.SetChanged(g_Settings->LoadBool(Directory_TextureUseSelected, UseSelected)); - m_TextureDefault.SetCheck(!UseSelected); - m_TextureSelected.SetCheck(UseSelected); - - m_InUpdateSettings = false; -} - -void COptionsDirectoriesPage::UseSelectedClicked(UINT /*Code*/, int id, HWND /*ctl*/) -{ - CModifiedButton * Button = NULL; - switch (id) - { - case IDC_PLUGIN_DEFAULT: Button = &m_PluginDefault; break; - case IDC_PLUGIN_OTHER: Button = &m_PluginDefault; break; - case IDC_AUTO_DEFAULT: Button = &m_AutoSaveDefault; break; - case IDC_AUTO_OTHER: Button = &m_AutoSaveDefault; break; - case IDC_INSTANT_DEFAULT: Button = &m_InstantDefault; break; - case IDC_INSTANT_OTHER: Button = &m_InstantDefault; break; - case IDC_SNAP_DEFAULT: Button = &m_ScreenShotDefault; break; - case IDC_SNAP_OTHER: Button = &m_ScreenShotDefault; break; - case IDC_TEXTURE_DEFAULT: Button = &m_TextureDefault; break; - case IDC_TEXTURE_OTHER: Button = &m_TextureDefault; break; - } - - if (Button == NULL) - { - return; - } - - if (!Button->IsChanged() || Button->IsReset()) - { - if ((int)Button->GetMenu() == id) - { - return; - } - } - Button->SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsDirectoriesPage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void COptionsDirectoriesPage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void COptionsDirectoriesPage::ResetDirectory(CModifiedEditBox & EditBox, SettingID Type) -{ - if (!EditBox.IsChanged()) - { - return; - } - stdstr dir; - g_Settings->LoadDefaultString(Type, dir); - EditBox.SetWindowText(dir.c_str()); - EditBox.SetReset(true); -} - -void COptionsDirectoriesPage::ResetDefaultSelected(CModifiedButton & ButtonDefault, CModifiedButton & ButtonSelected, SettingID Type) -{ - if (!ButtonDefault.IsChanged()) - { - return; - } - bool UseSelected; - g_Settings->LoadDefaultBool(Type, UseSelected); - ButtonDefault.SetCheck(!UseSelected); - ButtonSelected.SetCheck(UseSelected); - ButtonDefault.SetReset(true); -} - -void COptionsDirectoriesPage::UpdateDirectory(CModifiedEditBox & EditBox, SettingID Type) -{ - if (EditBox.IsChanged()) - { - stdstr dir = EditBox.GetWindowText(); - g_Settings->SaveString(Type, dir.c_str()); - } - if (EditBox.IsReset()) - { - g_Settings->DeleteSetting(Type); - } -} - -void COptionsDirectoriesPage::UpdateDefaultSelected(CModifiedButton & Button, SettingID Type) -{ - if (Button.IsChanged()) - { - bool bUseSelected = (Button.GetCheck() & BST_CHECKED) == 0; - g_Settings->SaveBool(Type, bUseSelected); - - if (Type == Directory_TextureUseSelected && !bUseSelected) - { - g_Settings->DeleteSetting(Directory_TextureSelected); - } - } - if (Button.IsReset()) - { - g_Settings->DeleteSetting(Type); - } -} - -void COptionsDirectoriesPage::ApplySettings(bool UpdateScreen) -{ - UpdateDirectory(m_PluginDir, Directory_PluginSelected); - UpdateDirectory(m_AutoSaveDir, Directory_NativeSaveSelected); - UpdateDirectory(m_InstantSaveDir, Directory_InstantSaveSelected); - UpdateDirectory(m_ScreenShotDir, Directory_SnapShotSelected); - UpdateDirectory(m_TextureDir, Directory_TextureSelected); - - UpdateDefaultSelected(m_PluginDefault, Directory_PluginUseSelected); - UpdateDefaultSelected(m_AutoSaveDefault, Directory_NativeSaveUseSelected); - UpdateDefaultSelected(m_InstantDefault, Directory_InstantSaveUseSelected); - UpdateDefaultSelected(m_ScreenShotDefault, Directory_SnapShotUseSelected); - UpdateDefaultSelected(m_TextureDefault, Directory_TextureUseSelected); - - if (UpdateScreen) - { - UpdatePageSettings(); - } -} - -bool COptionsDirectoriesPage::EnableReset(void) -{ - if (m_PluginDir.IsChanged()) { return true; } - if (m_AutoSaveDir.IsChanged()) { return true; } - if (m_InstantSaveDir.IsChanged()) { return true; } - if (m_ScreenShotDir.IsChanged()) { return true; } - if (m_TextureDir.IsChanged()) { return true; } - if (m_PluginDefault.IsChanged()) { return true; } - if (m_AutoSaveDefault.IsChanged()) { return true; } - if (m_InstantDefault.IsChanged()) { return true; } - if (m_ScreenShotDefault.IsChanged()) { return true; } - if (m_TextureDefault.IsChanged()) { return true; } - return false; -} - -void COptionsDirectoriesPage::ResetPage() -{ - ResetDirectory(m_PluginDir, Directory_PluginSelected); - ResetDirectory(m_AutoSaveDir, Directory_NativeSaveSelected); - ResetDirectory(m_InstantSaveDir, Directory_InstantSaveSelected); - ResetDirectory(m_ScreenShotDir, Directory_SnapShotSelected); - ResetDirectory(m_TextureDir, Directory_TextureSelected); - - ResetDefaultSelected(m_PluginDefault, m_PluginSelected, Directory_PluginUseSelected); - ResetDefaultSelected(m_AutoSaveDefault, m_AutoSaveSelected, Directory_NativeSaveUseSelected); - ResetDefaultSelected(m_InstantDefault, m_InstantSelected, Directory_InstantSaveUseSelected); - ResetDefaultSelected(m_ScreenShotDefault, m_ScreenShotSelected, Directory_SnapShotUseSelected); - ResetDefaultSelected(m_TextureDefault, m_TextureSelected, Directory_TextureUseSelected); - - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" + +COptionsDirectoriesPage::COptionsDirectoriesPage(HWND hParent, const RECT & rcDispay) : +m_InUpdateSettings(false) +{ + Create(hParent); + if (m_hWnd == NULL) + { + return; + } + SetWindowPos(HWND_TOP, &rcDispay, SWP_HIDEWINDOW); + + m_PluginGroup.Attach(GetDlgItem(IDC_DIR_FRAME1)); + m_AutoSaveGroup.Attach(GetDlgItem(IDC_DIR_FRAME3)); + m_InstantSaveGroup.Attach(GetDlgItem(IDC_DIR_FRAME4)); + m_ScreenShotGroup.Attach(GetDlgItem(IDC_DIR_FRAME5)); + m_TextureGroup.Attach(GetDlgItem(IDC_DIR_TEXTURE_FRAME)); + + m_PluginDir.Attach(GetDlgItem(IDC_PLUGIN_DIR)); + m_AutoSaveDir.Attach(GetDlgItem(IDC_AUTO_DIR)); + m_InstantSaveDir.Attach(GetDlgItem(IDC_INSTANT_DIR)); + m_ScreenShotDir.Attach(GetDlgItem(IDC_SNAP_DIR)); + m_TextureDir.Attach(GetDlgItem(IDC_TEXTURE_DIR)); + + m_PluginDefault.Attach(GetDlgItem(IDC_PLUGIN_DEFAULT)); + m_PluginSelected.Attach(GetDlgItem(IDC_PLUGIN_OTHER)); + m_AutoSaveDefault.Attach(GetDlgItem(IDC_AUTO_DEFAULT)); + m_AutoSaveSelected.Attach(GetDlgItem(IDC_AUTO_OTHER)); + m_InstantDefault.Attach(GetDlgItem(IDC_INSTANT_DEFAULT)); + m_InstantSelected.Attach(GetDlgItem(IDC_INSTANT_OTHER)); + m_ScreenShotDefault.Attach(GetDlgItem(IDC_SNAP_DEFAULT)); + m_ScreenShotSelected.Attach(GetDlgItem(IDC_SNAP_OTHER)); + m_TextureDefault.Attach(GetDlgItem(IDC_TEXTURE_DEFAULT)); + m_TextureSelected.Attach(GetDlgItem(IDC_TEXTURE_OTHER)); + + //Set Text language for the dialog box + ::SetWindowTextW(m_PluginGroup.m_hWnd, wGS(DIR_PLUGIN).c_str()); + ::SetWindowTextW(m_AutoSaveGroup.m_hWnd, wGS(DIR_AUTO_SAVE).c_str()); + ::SetWindowTextW(m_InstantSaveGroup.m_hWnd, wGS(DIR_INSTANT_SAVE).c_str()); + ::SetWindowTextW(m_ScreenShotGroup.m_hWnd, wGS(DIR_SCREEN_SHOT).c_str()); + ::SetWindowTextW(m_TextureGroup.m_hWnd, wGS(DIR_TEXTURE).c_str()); + + UpdatePageSettings(); +} + +int CALLBACK COptionsDirectoriesPage::SelectDirCallBack(HWND hwnd, DWORD uMsg, DWORD /*lp*/, DWORD lpData) +{ + switch (uMsg) + { + case BFFM_INITIALIZED: + // WParam is TRUE since you are passing a path. + // It would be FALSE if you were passing a pidl. + if (lpData) + { + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData); + } + break; + } + return 0; +} + +void COptionsDirectoriesPage::SelectDirectory(LanguageStringID Title, CModifiedEditBox & EditBox, CModifiedButton & Default, CModifiedButton & selected) +{ + wchar_t Buffer[MAX_PATH], Directory[MAX_PATH]; + LPITEMIDLIST pidl; + BROWSEINFOW bi; + + stdstr InitialDir = EditBox.GetWindowText(); + std::wstring wTitle = wGS(Title); + bi.hwndOwner = m_hWnd; + bi.pidlRoot = NULL; + bi.pszDisplayName = Buffer; + bi.lpszTitle = wTitle.c_str(); + bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; + bi.lpfn = (BFFCALLBACK)SelectDirCallBack; + bi.lParam = (DWORD)InitialDir.c_str(); + if ((pidl = SHBrowseForFolderW(&bi)) != NULL) + { + if (SHGetPathFromIDListW(pidl, Directory)) + { + stdstr path; + CPath SelectedDir(path.FromUTF16(Directory), ""); + EditBox.SetChanged(true); + EditBox.SetWindowText(SelectedDir); + Default.SetChanged(true); + Default.SetCheck(BST_UNCHECKED); + selected.SetCheck(BM_SETCHECK); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); + } + } +} + +void COptionsDirectoriesPage::PluginDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + if (m_InUpdateSettings) { return; } + m_PluginDir.SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsDirectoriesPage::AutoSaveDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + if (m_InUpdateSettings) { return; } + m_AutoSaveDir.SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsDirectoriesPage::InstantSaveDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + if (m_InUpdateSettings) { return; } + m_InstantSaveDir.SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsDirectoriesPage::SnapShotDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + if (m_InUpdateSettings) { return; } + m_ScreenShotDir.SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsDirectoriesPage::TextureDirChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + if (m_InUpdateSettings) { return; } + m_TextureDir.SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsDirectoriesPage::SelectPluginDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + SelectDirectory(DIR_SELECT_PLUGIN, m_PluginDir, m_PluginDefault, m_PluginSelected); +} + +void COptionsDirectoriesPage::SelectAutoDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + SelectDirectory(DIR_SELECT_AUTO, m_AutoSaveDir, m_AutoSaveDefault, m_AutoSaveSelected); +} + +void COptionsDirectoriesPage::SelectInstantDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + SelectDirectory(DIR_SELECT_INSTANT, m_InstantSaveDir, m_InstantDefault, m_InstantSelected); +} + +void COptionsDirectoriesPage::SelectSnapShotDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + SelectDirectory(DIR_SELECT_SCREEN, m_ScreenShotDir, m_ScreenShotDefault, m_ScreenShotSelected); +} + +void COptionsDirectoriesPage::SelectTextureDir(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + SelectDirectory(DIR_SELECT_TEXTURE, m_TextureDir, m_TextureDefault, m_TextureSelected); +} + +void COptionsDirectoriesPage::UpdatePageSettings() +{ + stdstr Directory; + + m_InUpdateSettings = true; + m_PluginDir.SetChanged(g_Settings->LoadStringVal(Directory_PluginSelected, Directory)); + m_PluginDir.SetWindowText(Directory.c_str()); + m_AutoSaveDir.SetChanged(g_Settings->LoadStringVal(Directory_NativeSaveSelected, Directory)); + m_AutoSaveDir.SetWindowText(Directory.c_str()); + m_InstantSaveDir.SetChanged(g_Settings->LoadStringVal(Directory_InstantSaveSelected, Directory)); + m_InstantSaveDir.SetWindowText(Directory.c_str()); + m_ScreenShotDir.SetChanged(g_Settings->LoadStringVal(Directory_SnapShotSelected, Directory)); + m_ScreenShotDir.SetWindowText(Directory.c_str()); + m_TextureDir.SetChanged(g_Settings->LoadStringVal(Directory_TextureSelected, Directory)); + m_TextureDir.SetWindowText(Directory.c_str()); + + bool UseSelected; + m_PluginDefault.SetChanged(g_Settings->LoadBool(Directory_PluginUseSelected, UseSelected)); + m_PluginDefault.SetCheck(!UseSelected); + m_PluginSelected.SetCheck(UseSelected); + + m_AutoSaveDefault.SetChanged(g_Settings->LoadBool(Directory_NativeSaveUseSelected, UseSelected)); + m_AutoSaveDefault.SetCheck(!UseSelected); + m_AutoSaveSelected.SetCheck(UseSelected); + + m_InstantDefault.SetChanged(g_Settings->LoadBool(Directory_InstantSaveUseSelected, UseSelected)); + m_InstantDefault.SetCheck(!UseSelected); + m_InstantSelected.SetCheck(UseSelected); + + m_ScreenShotDefault.SetChanged(g_Settings->LoadBool(Directory_SnapShotUseSelected, UseSelected)); + m_ScreenShotDefault.SetCheck(!UseSelected); + m_ScreenShotSelected.SetCheck(UseSelected); + + m_TextureDefault.SetChanged(g_Settings->LoadBool(Directory_TextureUseSelected, UseSelected)); + m_TextureDefault.SetCheck(!UseSelected); + m_TextureSelected.SetCheck(UseSelected); + + m_InUpdateSettings = false; +} + +void COptionsDirectoriesPage::UseSelectedClicked(UINT /*Code*/, int id, HWND /*ctl*/) +{ + CModifiedButton * Button = NULL; + switch (id) + { + case IDC_PLUGIN_DEFAULT: Button = &m_PluginDefault; break; + case IDC_PLUGIN_OTHER: Button = &m_PluginDefault; break; + case IDC_AUTO_DEFAULT: Button = &m_AutoSaveDefault; break; + case IDC_AUTO_OTHER: Button = &m_AutoSaveDefault; break; + case IDC_INSTANT_DEFAULT: Button = &m_InstantDefault; break; + case IDC_INSTANT_OTHER: Button = &m_InstantDefault; break; + case IDC_SNAP_DEFAULT: Button = &m_ScreenShotDefault; break; + case IDC_SNAP_OTHER: Button = &m_ScreenShotDefault; break; + case IDC_TEXTURE_DEFAULT: Button = &m_TextureDefault; break; + case IDC_TEXTURE_OTHER: Button = &m_TextureDefault; break; + } + + if (Button == NULL) + { + return; + } + + if (!Button->IsChanged() || Button->IsReset()) + { + if ((int)Button->GetMenu() == id) + { + return; + } + } + Button->SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsDirectoriesPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void COptionsDirectoriesPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void COptionsDirectoriesPage::ResetDirectory(CModifiedEditBox & EditBox, SettingID Type) +{ + if (!EditBox.IsChanged()) + { + return; + } + stdstr dir; + g_Settings->LoadDefaultString(Type, dir); + EditBox.SetWindowText(dir.c_str()); + EditBox.SetReset(true); +} + +void COptionsDirectoriesPage::ResetDefaultSelected(CModifiedButton & ButtonDefault, CModifiedButton & ButtonSelected, SettingID Type) +{ + if (!ButtonDefault.IsChanged()) + { + return; + } + bool UseSelected; + g_Settings->LoadDefaultBool(Type, UseSelected); + ButtonDefault.SetCheck(!UseSelected); + ButtonSelected.SetCheck(UseSelected); + ButtonDefault.SetReset(true); +} + +void COptionsDirectoriesPage::UpdateDirectory(CModifiedEditBox & EditBox, SettingID Type) +{ + if (EditBox.IsChanged()) + { + stdstr dir = EditBox.GetWindowText(); + g_Settings->SaveString(Type, dir.c_str()); + } + if (EditBox.IsReset()) + { + g_Settings->DeleteSetting(Type); + } +} + +void COptionsDirectoriesPage::UpdateDefaultSelected(CModifiedButton & Button, SettingID Type) +{ + if (Button.IsChanged()) + { + bool bUseSelected = (Button.GetCheck() & BST_CHECKED) == 0; + g_Settings->SaveBool(Type, bUseSelected); + + if (Type == Directory_TextureUseSelected && !bUseSelected) + { + g_Settings->DeleteSetting(Directory_TextureSelected); + } + } + if (Button.IsReset()) + { + g_Settings->DeleteSetting(Type); + } +} + +void COptionsDirectoriesPage::ApplySettings(bool UpdateScreen) +{ + UpdateDirectory(m_PluginDir, Directory_PluginSelected); + UpdateDirectory(m_AutoSaveDir, Directory_NativeSaveSelected); + UpdateDirectory(m_InstantSaveDir, Directory_InstantSaveSelected); + UpdateDirectory(m_ScreenShotDir, Directory_SnapShotSelected); + UpdateDirectory(m_TextureDir, Directory_TextureSelected); + + UpdateDefaultSelected(m_PluginDefault, Directory_PluginUseSelected); + UpdateDefaultSelected(m_AutoSaveDefault, Directory_NativeSaveUseSelected); + UpdateDefaultSelected(m_InstantDefault, Directory_InstantSaveUseSelected); + UpdateDefaultSelected(m_ScreenShotDefault, Directory_SnapShotUseSelected); + UpdateDefaultSelected(m_TextureDefault, Directory_TextureUseSelected); + + if (UpdateScreen) + { + UpdatePageSettings(); + } +} + +bool COptionsDirectoriesPage::EnableReset(void) +{ + if (m_PluginDir.IsChanged()) { return true; } + if (m_AutoSaveDir.IsChanged()) { return true; } + if (m_InstantSaveDir.IsChanged()) { return true; } + if (m_ScreenShotDir.IsChanged()) { return true; } + if (m_TextureDir.IsChanged()) { return true; } + if (m_PluginDefault.IsChanged()) { return true; } + if (m_AutoSaveDefault.IsChanged()) { return true; } + if (m_InstantDefault.IsChanged()) { return true; } + if (m_ScreenShotDefault.IsChanged()) { return true; } + if (m_TextureDefault.IsChanged()) { return true; } + return false; +} + +void COptionsDirectoriesPage::ResetPage() +{ + ResetDirectory(m_PluginDir, Directory_PluginSelected); + ResetDirectory(m_AutoSaveDir, Directory_NativeSaveSelected); + ResetDirectory(m_InstantSaveDir, Directory_InstantSaveSelected); + ResetDirectory(m_ScreenShotDir, Directory_SnapShotSelected); + ResetDirectory(m_TextureDir, Directory_TextureSelected); + + ResetDefaultSelected(m_PluginDefault, m_PluginSelected, Directory_PluginUseSelected); + ResetDefaultSelected(m_AutoSaveDefault, m_AutoSaveSelected, Directory_NativeSaveUseSelected); + ResetDefaultSelected(m_InstantDefault, m_InstantSelected, Directory_InstantSaveUseSelected); + ResetDefaultSelected(m_ScreenShotDefault, m_ScreenShotSelected, Directory_SnapShotUseSelected); + ResetDefaultSelected(m_TextureDefault, m_TextureSelected, Directory_TextureUseSelected); + + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Directories.h b/Source/Project64/UserInterface/Settings/SettingsPage-Directories.h index 4593f41b2..0acb2ed10 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Directories.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Directories.h @@ -1,86 +1,86 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class COptionsDirectoriesPage : - public CDialogImpl, - public CSettingsPage -{ - BEGIN_MSG_MAP_EX(COptionsDirectoriesPage) - COMMAND_ID_HANDLER_EX(IDC_SELECT_PLUGIN_DIR, SelectPluginDir) - COMMAND_ID_HANDLER_EX(IDC_SELECT_AUTO_DIR, SelectAutoDir) - COMMAND_ID_HANDLER_EX(IDC_SELECT_INSTANT_DIR, SelectInstantDir) - COMMAND_ID_HANDLER_EX(IDC_SELECT_SNAP_DIR, SelectSnapShotDir) - COMMAND_ID_HANDLER_EX(IDC_SELECT_TEXTURE_DIR, SelectTextureDir) - COMMAND_HANDLER_EX(IDC_PLUGIN_DIR, EN_UPDATE, PluginDirChanged) - COMMAND_HANDLER_EX(IDC_AUTO_DIR, EN_UPDATE, AutoSaveDirChanged) - COMMAND_HANDLER_EX(IDC_INSTANT_DIR, EN_UPDATE, InstantSaveDirChanged) - COMMAND_HANDLER_EX(IDC_SNAP_DIR, EN_UPDATE, SnapShotDirChanged) - COMMAND_HANDLER_EX(IDC_TEXTURE_DIR, EN_UPDATE, TextureDirChanged) - - COMMAND_HANDLER_EX(IDC_PLUGIN_DEFAULT, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_PLUGIN_OTHER, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_AUTO_DEFAULT, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_AUTO_OTHER, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_INSTANT_DEFAULT, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_INSTANT_OTHER, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_SNAP_DEFAULT, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_SNAP_OTHER, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_TEXTURE_DEFAULT, BN_CLICKED, UseSelectedClicked) - COMMAND_HANDLER_EX(IDC_TEXTURE_OTHER, BN_CLICKED, UseSelectedClicked) - END_MSG_MAP() - - enum { IDD = IDD_Settings_Directory }; - -public: - COptionsDirectoriesPage(HWND hParent, const RECT & rcDispay); - - LanguageStringID PageTitle(void) { return TAB_DIRECTORY; } - void HidePage(void); - void ShowPage(void); - void ApplySettings(bool UpdateScreen); - bool EnableReset(void); - void ResetPage(void); - -private: - void SelectPluginDir(UINT Code, int id, HWND ctl); - void SelectAutoDir(UINT Code, int id, HWND ctl); - void SelectInstantDir(UINT Code, int id, HWND ctl); - void SelectSnapShotDir(UINT Code, int id, HWND ctl); - void SelectTextureDir(UINT Code, int id, HWND ctl); - void PluginDirChanged(UINT Code, int id, HWND ctl); - void AutoSaveDirChanged(UINT Code, int id, HWND ctl); - void InstantSaveDirChanged(UINT Code, int id, HWND ctl); - void SnapShotDirChanged(UINT Code, int id, HWND ctl); - void TextureDirChanged(UINT Code, int id, HWND ctl); - void UseSelectedClicked(UINT Code, int id, HWND ctl); - void UpdatePageSettings(void); - void SelectDirectory(LanguageStringID Title, CModifiedEditBox & EditBox, CModifiedButton & Default, CModifiedButton & selected); - - void UpdateDirectory(CModifiedEditBox & EditBox, SettingID Type); - void UpdateDefaultSelected(CModifiedButton & Button, SettingID Type); - - void ResetDirectory(CModifiedEditBox & EditBox, SettingID Type); - void ResetDefaultSelected(CModifiedButton & ButtonDefault, CModifiedButton & ButtonSelected, SettingID Type); - - static int CALLBACK SelectDirCallBack(HWND hwnd, DWORD uMsg, DWORD lp, DWORD lpData); - - CPartialGroupBox m_PluginGroup, m_AutoSaveGroup, m_InstantSaveGroup, - m_ScreenShotGroup, m_TextureGroup; - CModifiedEditBox m_PluginDir, m_AutoSaveDir, m_InstantSaveDir, - m_ScreenShotDir, m_TextureDir; - - CModifiedButton m_PluginDefault, m_PluginSelected, m_AutoSaveDefault, m_AutoSaveSelected, - m_InstantDefault, m_InstantSelected, m_ScreenShotDefault, m_ScreenShotSelected, - m_TextureDefault, m_TextureSelected; - - bool m_InUpdateSettings; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class COptionsDirectoriesPage : + public CDialogImpl, + public CSettingsPage +{ + BEGIN_MSG_MAP_EX(COptionsDirectoriesPage) + COMMAND_ID_HANDLER_EX(IDC_SELECT_PLUGIN_DIR, SelectPluginDir) + COMMAND_ID_HANDLER_EX(IDC_SELECT_AUTO_DIR, SelectAutoDir) + COMMAND_ID_HANDLER_EX(IDC_SELECT_INSTANT_DIR, SelectInstantDir) + COMMAND_ID_HANDLER_EX(IDC_SELECT_SNAP_DIR, SelectSnapShotDir) + COMMAND_ID_HANDLER_EX(IDC_SELECT_TEXTURE_DIR, SelectTextureDir) + COMMAND_HANDLER_EX(IDC_PLUGIN_DIR, EN_UPDATE, PluginDirChanged) + COMMAND_HANDLER_EX(IDC_AUTO_DIR, EN_UPDATE, AutoSaveDirChanged) + COMMAND_HANDLER_EX(IDC_INSTANT_DIR, EN_UPDATE, InstantSaveDirChanged) + COMMAND_HANDLER_EX(IDC_SNAP_DIR, EN_UPDATE, SnapShotDirChanged) + COMMAND_HANDLER_EX(IDC_TEXTURE_DIR, EN_UPDATE, TextureDirChanged) + + COMMAND_HANDLER_EX(IDC_PLUGIN_DEFAULT, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_PLUGIN_OTHER, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_AUTO_DEFAULT, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_AUTO_OTHER, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_INSTANT_DEFAULT, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_INSTANT_OTHER, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_SNAP_DEFAULT, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_SNAP_OTHER, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_TEXTURE_DEFAULT, BN_CLICKED, UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_TEXTURE_OTHER, BN_CLICKED, UseSelectedClicked) + END_MSG_MAP() + + enum { IDD = IDD_Settings_Directory }; + +public: + COptionsDirectoriesPage(HWND hParent, const RECT & rcDispay); + + LanguageStringID PageTitle(void) { return TAB_DIRECTORY; } + void HidePage(void); + void ShowPage(void); + void ApplySettings(bool UpdateScreen); + bool EnableReset(void); + void ResetPage(void); + +private: + void SelectPluginDir(UINT Code, int id, HWND ctl); + void SelectAutoDir(UINT Code, int id, HWND ctl); + void SelectInstantDir(UINT Code, int id, HWND ctl); + void SelectSnapShotDir(UINT Code, int id, HWND ctl); + void SelectTextureDir(UINT Code, int id, HWND ctl); + void PluginDirChanged(UINT Code, int id, HWND ctl); + void AutoSaveDirChanged(UINT Code, int id, HWND ctl); + void InstantSaveDirChanged(UINT Code, int id, HWND ctl); + void SnapShotDirChanged(UINT Code, int id, HWND ctl); + void TextureDirChanged(UINT Code, int id, HWND ctl); + void UseSelectedClicked(UINT Code, int id, HWND ctl); + void UpdatePageSettings(void); + void SelectDirectory(LanguageStringID Title, CModifiedEditBox & EditBox, CModifiedButton & Default, CModifiedButton & selected); + + void UpdateDirectory(CModifiedEditBox & EditBox, SettingID Type); + void UpdateDefaultSelected(CModifiedButton & Button, SettingID Type); + + void ResetDirectory(CModifiedEditBox & EditBox, SettingID Type); + void ResetDefaultSelected(CModifiedButton & ButtonDefault, CModifiedButton & ButtonSelected, SettingID Type); + + static int CALLBACK SelectDirCallBack(HWND hwnd, DWORD uMsg, DWORD lp, DWORD lpData); + + CPartialGroupBox m_PluginGroup, m_AutoSaveGroup, m_InstantSaveGroup, + m_ScreenShotGroup, m_TextureGroup; + CModifiedEditBox m_PluginDir, m_AutoSaveDir, m_InstantSaveDir, + m_ScreenShotDir, m_TextureDir; + + CModifiedButton m_PluginDefault, m_PluginSelected, m_AutoSaveDefault, m_AutoSaveSelected, + m_InstantDefault, m_InstantSelected, m_ScreenShotDefault, m_ScreenShotSelected, + m_TextureDefault, m_TextureSelected; + + bool m_InUpdateSettings; +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Game-General.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-Game-General.cpp index 521f9c5b9..bac02c5b5 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Game-General.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Game-General.cpp @@ -1,115 +1,115 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" -#include "SettingsPage-Game-General.h" - -CGameGeneralPage::CGameGeneralPage(HWND hParent, const RECT & rcDispay) -{ - if (!Create(hParent, rcDispay)) - { - return; - } - - //Set the text for all gui Items - SetDlgItemTextW(m_hWnd, IDC_GOOD_NAME_TEXT, wGS(RB_GOODNAME).c_str()); - - SetDlgItemTextW(m_hWnd, IDC_MEMORY_SIZE_TEXT, wGS(ROM_MEM_SIZE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_SAVE_TYPE_TEXT, wGS(ROM_SAVE_TYPE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_COUNTFACT_TEXT, wGS(ROM_COUNTER_FACTOR).c_str()); - SetDlgItemTextW(m_hWnd, IDC_VIREFESH_TEXT, wGS(ROM_VIREFRESH).c_str()); - SetDlgItemTextW(m_hWnd, IDC_COUNTPERBYTE_TEXT, wGS(ROM_COUNTPERBYTE).c_str()); - - SetDlgItemTextW(m_hWnd, IDC_ROM_32BIT, wGS(ROM_32BIT).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ROM_FIXEDAUDIO, wGS(ROM_FIXED_AUDIO).c_str()); - SetDlgItemTextW(m_hWnd, IDC_DELAY_DP, wGS(ROM_DELAY_DP).c_str()); - SetDlgItemTextW(m_hWnd, IDC_SYNC_AUDIO, wGS(ROM_SYNC_AUDIO).c_str()); - SetDlgItemTextW(m_hWnd, IDC_USE_TLB, wGS(ROM_USE_TLB).c_str()); - SetDlgItemTextW(m_hWnd, IDC_DELAY_SI, wGS(ROM_DELAY_SI).c_str()); - SetDlgItemTextW(m_hWnd, IDC_AUDIO_SIGNAL, wGS(ROM_AUDIO_SIGNAL).c_str()); - - AddModCheckBox(GetDlgItem(IDC_ROM_32BIT), Game_32Bit); - AddModCheckBox(GetDlgItem(IDC_SYNC_AUDIO), Game_SyncViaAudio); - AddModCheckBox(GetDlgItem(IDC_ROM_FIXEDAUDIO), Game_FixedAudio); - AddModCheckBox(GetDlgItem(IDC_USE_TLB), Game_UseTlb); - AddModCheckBox(GetDlgItem(IDC_DELAY_DP), Game_DelayDP); - AddModCheckBox(GetDlgItem(IDC_DELAY_SI), Game_DelaySI); - AddModCheckBox(GetDlgItem(IDC_AUDIO_SIGNAL), Game_RspAudioSignal); - - CModifiedComboBox * ComboBox; - ComboBox = AddModComboBox(GetDlgItem(IDC_RDRAM_SIZE), Game_RDRamSize); - if (ComboBox) - { - ComboBox->SetTextField(GetDlgItem(IDC_MEMORY_SIZE_TEXT)); - ComboBox->AddItemW(wGS(RDRAM_4MB).c_str(), 0x400000); - ComboBox->AddItemW(wGS(RDRAM_8MB).c_str(), 0x800000); - } - - ComboBox = AddModComboBox(GetDlgItem(IDC_SAVE_TYPE), Game_SaveChip); - if (ComboBox) - { - ComboBox->SetTextField(GetDlgItem(IDC_SAVE_TYPE_TEXT)); - ComboBox->AddItemW(wGS(SAVE_FIRST_USED).c_str(), (WPARAM)SaveChip_Auto); - ComboBox->AddItemW(wGS(SAVE_4K_EEPROM).c_str(), SaveChip_Eeprom_4K); - ComboBox->AddItemW(wGS(SAVE_16K_EEPROM).c_str(), SaveChip_Eeprom_16K); - ComboBox->AddItemW(wGS(SAVE_SRAM).c_str(), SaveChip_Sram); - ComboBox->AddItemW(wGS(SAVE_FLASHRAM).c_str(), SaveChip_FlashRam); - } - - ComboBox = AddModComboBox(GetDlgItem(IDC_COUNTFACT), Game_CounterFactor); - if (ComboBox) - { - ComboBox->SetTextField(GetDlgItem(IDC_COUNTFACT_TEXT)); - ComboBox->AddItemW(wGS(NUMBER_1).c_str(), 1); - ComboBox->AddItemW(wGS(NUMBER_2).c_str(), 2); - ComboBox->AddItemW(wGS(NUMBER_3).c_str(), 3); - ComboBox->AddItemW(wGS(NUMBER_4).c_str(), 4); - ComboBox->AddItemW(wGS(NUMBER_5).c_str(), 5); - ComboBox->AddItemW(wGS(NUMBER_6).c_str(), 6); - } - - SetDlgItemText(IDC_GOOD_NAME, g_Settings->LoadStringVal(Game_GoodName).c_str()); - - CModifiedEditBox * TxtBox = AddModTextBox(GetDlgItem(IDC_VIREFRESH), Game_ViRefreshRate, false); - TxtBox->SetTextField(GetDlgItem(IDC_VIREFESH_TEXT)); - - TxtBox = AddModTextBox(GetDlgItem(IDC_COUNTPERBYTE), Game_AiCountPerBytes, false); - TxtBox->SetTextField(GetDlgItem(IDC_COUNTPERBYTE_TEXT)); - - UpdatePageSettings(); -} - -void CGameGeneralPage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void CGameGeneralPage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void CGameGeneralPage::ApplySettings(bool UpdateScreen) -{ - CSettingsPageImpl::ApplySettings(UpdateScreen); -} - -bool CGameGeneralPage::EnableReset(void) -{ - if (CSettingsPageImpl::EnableReset()) { return true; } - return false; -} - -void CGameGeneralPage::ResetPage() -{ - CSettingsPageImpl::ResetPage(); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" +#include "SettingsPage-Game-General.h" + +CGameGeneralPage::CGameGeneralPage(HWND hParent, const RECT & rcDispay) +{ + if (!Create(hParent, rcDispay)) + { + return; + } + + //Set the text for all gui Items + SetDlgItemTextW(m_hWnd, IDC_GOOD_NAME_TEXT, wGS(RB_GOODNAME).c_str()); + + SetDlgItemTextW(m_hWnd, IDC_MEMORY_SIZE_TEXT, wGS(ROM_MEM_SIZE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_SAVE_TYPE_TEXT, wGS(ROM_SAVE_TYPE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_COUNTFACT_TEXT, wGS(ROM_COUNTER_FACTOR).c_str()); + SetDlgItemTextW(m_hWnd, IDC_VIREFESH_TEXT, wGS(ROM_VIREFRESH).c_str()); + SetDlgItemTextW(m_hWnd, IDC_COUNTPERBYTE_TEXT, wGS(ROM_COUNTPERBYTE).c_str()); + + SetDlgItemTextW(m_hWnd, IDC_ROM_32BIT, wGS(ROM_32BIT).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ROM_FIXEDAUDIO, wGS(ROM_FIXED_AUDIO).c_str()); + SetDlgItemTextW(m_hWnd, IDC_DELAY_DP, wGS(ROM_DELAY_DP).c_str()); + SetDlgItemTextW(m_hWnd, IDC_SYNC_AUDIO, wGS(ROM_SYNC_AUDIO).c_str()); + SetDlgItemTextW(m_hWnd, IDC_USE_TLB, wGS(ROM_USE_TLB).c_str()); + SetDlgItemTextW(m_hWnd, IDC_DELAY_SI, wGS(ROM_DELAY_SI).c_str()); + SetDlgItemTextW(m_hWnd, IDC_AUDIO_SIGNAL, wGS(ROM_AUDIO_SIGNAL).c_str()); + + AddModCheckBox(GetDlgItem(IDC_ROM_32BIT), Game_32Bit); + AddModCheckBox(GetDlgItem(IDC_SYNC_AUDIO), Game_SyncViaAudio); + AddModCheckBox(GetDlgItem(IDC_ROM_FIXEDAUDIO), Game_FixedAudio); + AddModCheckBox(GetDlgItem(IDC_USE_TLB), Game_UseTlb); + AddModCheckBox(GetDlgItem(IDC_DELAY_DP), Game_DelayDP); + AddModCheckBox(GetDlgItem(IDC_DELAY_SI), Game_DelaySI); + AddModCheckBox(GetDlgItem(IDC_AUDIO_SIGNAL), Game_RspAudioSignal); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(IDC_RDRAM_SIZE), Game_RDRamSize); + if (ComboBox) + { + ComboBox->SetTextField(GetDlgItem(IDC_MEMORY_SIZE_TEXT)); + ComboBox->AddItemW(wGS(RDRAM_4MB).c_str(), 0x400000); + ComboBox->AddItemW(wGS(RDRAM_8MB).c_str(), 0x800000); + } + + ComboBox = AddModComboBox(GetDlgItem(IDC_SAVE_TYPE), Game_SaveChip); + if (ComboBox) + { + ComboBox->SetTextField(GetDlgItem(IDC_SAVE_TYPE_TEXT)); + ComboBox->AddItemW(wGS(SAVE_FIRST_USED).c_str(), (WPARAM)SaveChip_Auto); + ComboBox->AddItemW(wGS(SAVE_4K_EEPROM).c_str(), SaveChip_Eeprom_4K); + ComboBox->AddItemW(wGS(SAVE_16K_EEPROM).c_str(), SaveChip_Eeprom_16K); + ComboBox->AddItemW(wGS(SAVE_SRAM).c_str(), SaveChip_Sram); + ComboBox->AddItemW(wGS(SAVE_FLASHRAM).c_str(), SaveChip_FlashRam); + } + + ComboBox = AddModComboBox(GetDlgItem(IDC_COUNTFACT), Game_CounterFactor); + if (ComboBox) + { + ComboBox->SetTextField(GetDlgItem(IDC_COUNTFACT_TEXT)); + ComboBox->AddItemW(wGS(NUMBER_1).c_str(), 1); + ComboBox->AddItemW(wGS(NUMBER_2).c_str(), 2); + ComboBox->AddItemW(wGS(NUMBER_3).c_str(), 3); + ComboBox->AddItemW(wGS(NUMBER_4).c_str(), 4); + ComboBox->AddItemW(wGS(NUMBER_5).c_str(), 5); + ComboBox->AddItemW(wGS(NUMBER_6).c_str(), 6); + } + + SetDlgItemText(IDC_GOOD_NAME, g_Settings->LoadStringVal(Game_GoodName).c_str()); + + CModifiedEditBox * TxtBox = AddModTextBox(GetDlgItem(IDC_VIREFRESH), Game_ViRefreshRate, false); + TxtBox->SetTextField(GetDlgItem(IDC_VIREFESH_TEXT)); + + TxtBox = AddModTextBox(GetDlgItem(IDC_COUNTPERBYTE), Game_AiCountPerBytes, false); + TxtBox->SetTextField(GetDlgItem(IDC_COUNTPERBYTE_TEXT)); + + UpdatePageSettings(); +} + +void CGameGeneralPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void CGameGeneralPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void CGameGeneralPage::ApplySettings(bool UpdateScreen) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CGameGeneralPage::EnableReset(void) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CGameGeneralPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Game-General.h b/Source/Project64/UserInterface/Settings/SettingsPage-Game-General.h index 6579fcb70..e332f584e 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Game-General.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Game-General.h @@ -1,46 +1,46 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include "../WTLControls/ModifiedCheckBox.h" -#include - -class CGameGeneralPage : - public CSettingsPageImpl, - public CSettingsPage -{ - BEGIN_MSG_MAP_EX(CGameGeneralPage) - COMMAND_HANDLER_EX(IDC_RDRAM_SIZE, LBN_SELCHANGE, ComboBoxChanged) - COMMAND_HANDLER_EX(IDC_SAVE_TYPE, LBN_SELCHANGE, ComboBoxChanged) - COMMAND_HANDLER_EX(IDC_COUNTFACT, LBN_SELCHANGE, ComboBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_ROM_32BIT, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_SYNC_AUDIO, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_ROM_FIXEDAUDIO, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_USE_TLB, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_DELAY_DP, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_DELAY_SI, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_AUDIO_SIGNAL, CheckBoxChanged) - COMMAND_HANDLER_EX(IDC_VIREFRESH, EN_UPDATE, EditBoxChanged) - COMMAND_HANDLER_EX(IDC_COUNTPERBYTE, EN_UPDATE, EditBoxChanged) - END_MSG_MAP() - - enum { IDD = IDD_Settings_GameGeneral }; - -public: - CGameGeneralPage(HWND hParent, const RECT & rcDispay); - - LanguageStringID PageTitle(void) { return TAB_ROMSETTINGS; } - void HidePage(void); - void ShowPage(void); - void ApplySettings(bool UpdateScreen); - bool EnableReset(void); - void ResetPage(void); -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include "../WTLControls/ModifiedCheckBox.h" +#include + +class CGameGeneralPage : + public CSettingsPageImpl, + public CSettingsPage +{ + BEGIN_MSG_MAP_EX(CGameGeneralPage) + COMMAND_HANDLER_EX(IDC_RDRAM_SIZE, LBN_SELCHANGE, ComboBoxChanged) + COMMAND_HANDLER_EX(IDC_SAVE_TYPE, LBN_SELCHANGE, ComboBoxChanged) + COMMAND_HANDLER_EX(IDC_COUNTFACT, LBN_SELCHANGE, ComboBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ROM_32BIT, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SYNC_AUDIO, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ROM_FIXEDAUDIO, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_USE_TLB, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_DELAY_DP, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_DELAY_SI, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_AUDIO_SIGNAL, CheckBoxChanged) + COMMAND_HANDLER_EX(IDC_VIREFRESH, EN_UPDATE, EditBoxChanged) + COMMAND_HANDLER_EX(IDC_COUNTPERBYTE, EN_UPDATE, EditBoxChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_GameGeneral }; + +public: + CGameGeneralPage(HWND hParent, const RECT & rcDispay); + + LanguageStringID PageTitle(void) { return TAB_ROMSETTINGS; } + void HidePage(void); + void ShowPage(void); + void ApplySettings(bool UpdateScreen); + bool EnableReset(void); + void ResetPage(void); +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Recompiler.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Recompiler.cpp index c2591d211..dd7331420 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Recompiler.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Recompiler.cpp @@ -1,97 +1,97 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" -#include "SettingsPage-Game-Recompiler.h" - -CGameRecompilePage::CGameRecompilePage(HWND hParent, const RECT & rcDispay) -{ - if (!Create(hParent, rcDispay)) - { - return; - } - - //Set the text for all gui Items - SetDlgItemTextW(m_hWnd, IDC_CPU_TYPE_TEXT, wGS(ROM_CPU_STYLE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_FUNCFIND_TEXT, wGS(ROM_FUNC_FIND).c_str()); - - SetDlgItemTextW(m_hWnd, IDC_ROM_REGCACHE, wGS(ROM_REG_CACHE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_BLOCK_LINKING, wGS(ADVANCE_ABL).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ROM_FASTSP, wGS(ROM_FAST_SP).c_str()); - - SetDlgItemTextW(m_hWnd, IDC_SMM_FRAME, wGS(ADVANCE_SMCM).c_str()); - SetDlgItemTextW(m_hWnd, IDC_SMM_CACHE, wGS(ADVANCE_SMM_CACHE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_SMM_DMA, wGS(ADVANCE_SMM_PIDMA).c_str()); - SetDlgItemTextW(m_hWnd, IDC_SMM_VALIDATE, wGS(ADVANCE_SMM_VALIDATE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_SMM_TLB, wGS(ADVANCE_SMM_TLB).c_str()); - SetDlgItemTextW(m_hWnd, IDC_SMM_PROTECT, wGS(ADVANCE_SMM_PROTECT).c_str()); - - m_SelfModGroup.Attach(GetDlgItem(IDC_SMM_FRAME)); - - AddModCheckBox(GetDlgItem(IDC_ROM_REGCACHE), Game_RegCache); - AddModCheckBox(GetDlgItem(IDC_BLOCK_LINKING), Game_BlockLinking); - AddModCheckBox(GetDlgItem(IDC_SMM_CACHE), Game_SMM_Cache); - AddModCheckBox(GetDlgItem(IDC_SMM_DMA), Game_SMM_PIDMA); - AddModCheckBox(GetDlgItem(IDC_SMM_VALIDATE), Game_SMM_ValidFunc); - AddModCheckBox(GetDlgItem(IDC_SMM_TLB), Game_SMM_TLB); - AddModCheckBox(GetDlgItem(IDC_SMM_PROTECT), Game_SMM_Protect); - ::ShowWindow(GetDlgItem(IDC_SMM_STORE), SW_HIDE); - //AddModCheckBox(GetDlgItem(IDC_SMM_STORE),Game_SMM_StoreInstruc); - AddModCheckBox(GetDlgItem(IDC_ROM_FASTSP), Game_FastSP); - - CModifiedComboBox * ComboBox; - ComboBox = AddModComboBox(GetDlgItem(IDC_CPU_TYPE), Game_CpuType); - if (ComboBox) - { - ComboBox->AddItemW(wGS(CORE_RECOMPILER).c_str(), CPU_Recompiler); - ComboBox->AddItemW(wGS(CORE_INTERPTER).c_str(), CPU_Interpreter); - if (g_Settings->LoadBool(Debugger_Enabled)) - { - ComboBox->AddItemW(wGS(CORE_SYNC).c_str(), CPU_SyncCores); - } - } - - ComboBox = AddModComboBox(GetDlgItem(IDC_FUNCFIND), Game_FuncLookupMode); - if (ComboBox) - { - ComboBox->AddItemW(wGS(FLM_PLOOKUP).c_str(), FuncFind_PhysicalLookup); - ComboBox->AddItemW(wGS(FLM_VLOOKUP).c_str(), FuncFind_VirtualLookup); - //ComboBox->AddItem(wGS(FLM_CHANGEMEM).c_str(), FuncFind_ChangeMemory); - } - UpdatePageSettings(); -} - -void CGameRecompilePage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void CGameRecompilePage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void CGameRecompilePage::ApplySettings(bool UpdateScreen) -{ - CSettingsPageImpl::ApplySettings(UpdateScreen); -} - -bool CGameRecompilePage::EnableReset(void) -{ - if (CSettingsPageImpl::EnableReset()) { return true; } - return false; -} - -void CGameRecompilePage::ResetPage() -{ - CSettingsPageImpl::ResetPage(); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" +#include "SettingsPage-Game-Recompiler.h" + +CGameRecompilePage::CGameRecompilePage(HWND hParent, const RECT & rcDispay) +{ + if (!Create(hParent, rcDispay)) + { + return; + } + + //Set the text for all gui Items + SetDlgItemTextW(m_hWnd, IDC_CPU_TYPE_TEXT, wGS(ROM_CPU_STYLE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_FUNCFIND_TEXT, wGS(ROM_FUNC_FIND).c_str()); + + SetDlgItemTextW(m_hWnd, IDC_ROM_REGCACHE, wGS(ROM_REG_CACHE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_BLOCK_LINKING, wGS(ADVANCE_ABL).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ROM_FASTSP, wGS(ROM_FAST_SP).c_str()); + + SetDlgItemTextW(m_hWnd, IDC_SMM_FRAME, wGS(ADVANCE_SMCM).c_str()); + SetDlgItemTextW(m_hWnd, IDC_SMM_CACHE, wGS(ADVANCE_SMM_CACHE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_SMM_DMA, wGS(ADVANCE_SMM_PIDMA).c_str()); + SetDlgItemTextW(m_hWnd, IDC_SMM_VALIDATE, wGS(ADVANCE_SMM_VALIDATE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_SMM_TLB, wGS(ADVANCE_SMM_TLB).c_str()); + SetDlgItemTextW(m_hWnd, IDC_SMM_PROTECT, wGS(ADVANCE_SMM_PROTECT).c_str()); + + m_SelfModGroup.Attach(GetDlgItem(IDC_SMM_FRAME)); + + AddModCheckBox(GetDlgItem(IDC_ROM_REGCACHE), Game_RegCache); + AddModCheckBox(GetDlgItem(IDC_BLOCK_LINKING), Game_BlockLinking); + AddModCheckBox(GetDlgItem(IDC_SMM_CACHE), Game_SMM_Cache); + AddModCheckBox(GetDlgItem(IDC_SMM_DMA), Game_SMM_PIDMA); + AddModCheckBox(GetDlgItem(IDC_SMM_VALIDATE), Game_SMM_ValidFunc); + AddModCheckBox(GetDlgItem(IDC_SMM_TLB), Game_SMM_TLB); + AddModCheckBox(GetDlgItem(IDC_SMM_PROTECT), Game_SMM_Protect); + ::ShowWindow(GetDlgItem(IDC_SMM_STORE), SW_HIDE); + //AddModCheckBox(GetDlgItem(IDC_SMM_STORE),Game_SMM_StoreInstruc); + AddModCheckBox(GetDlgItem(IDC_ROM_FASTSP), Game_FastSP); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(IDC_CPU_TYPE), Game_CpuType); + if (ComboBox) + { + ComboBox->AddItemW(wGS(CORE_RECOMPILER).c_str(), CPU_Recompiler); + ComboBox->AddItemW(wGS(CORE_INTERPTER).c_str(), CPU_Interpreter); + if (g_Settings->LoadBool(Debugger_Enabled)) + { + ComboBox->AddItemW(wGS(CORE_SYNC).c_str(), CPU_SyncCores); + } + } + + ComboBox = AddModComboBox(GetDlgItem(IDC_FUNCFIND), Game_FuncLookupMode); + if (ComboBox) + { + ComboBox->AddItemW(wGS(FLM_PLOOKUP).c_str(), FuncFind_PhysicalLookup); + ComboBox->AddItemW(wGS(FLM_VLOOKUP).c_str(), FuncFind_VirtualLookup); + //ComboBox->AddItem(wGS(FLM_CHANGEMEM).c_str(), FuncFind_ChangeMemory); + } + UpdatePageSettings(); +} + +void CGameRecompilePage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void CGameRecompilePage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void CGameRecompilePage::ApplySettings(bool UpdateScreen) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CGameRecompilePage::EnableReset(void) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CGameRecompilePage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Recompiler.h b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Recompiler.h index 6c0fd0988..ec33ee034 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Recompiler.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Recompiler.h @@ -1,45 +1,45 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CGameRecompilePage : - public CSettingsPageImpl, - public CSettingsPage -{ - BEGIN_MSG_MAP_EX(CGameRecompilePage) - COMMAND_HANDLER_EX(IDC_CPU_TYPE, LBN_SELCHANGE, ComboBoxChanged) - COMMAND_HANDLER_EX(IDC_FUNCFIND, LBN_SELCHANGE, ComboBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_ROM_REGCACHE, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_ROM_FASTSP, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_BLOCK_LINKING, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_SMM_CACHE, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_SMM_DMA, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_SMM_VALIDATE, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_SMM_TLB, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_SMM_PROTECT, CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_SMM_STORE, CheckBoxChanged) - END_MSG_MAP() - - enum { IDD = IDD_Settings_GameRecompiler }; - -public: - CGameRecompilePage(HWND hParent, const RECT & rcDispay); - - LanguageStringID PageTitle(void) { return TAB_RECOMPILER; } - void HidePage(void); - void ShowPage(void); - void ApplySettings(bool UpdateScreen); - bool EnableReset(void); - void ResetPage(void); - -private: - CPartialGroupBox m_SelfModGroup; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CGameRecompilePage : + public CSettingsPageImpl, + public CSettingsPage +{ + BEGIN_MSG_MAP_EX(CGameRecompilePage) + COMMAND_HANDLER_EX(IDC_CPU_TYPE, LBN_SELCHANGE, ComboBoxChanged) + COMMAND_HANDLER_EX(IDC_FUNCFIND, LBN_SELCHANGE, ComboBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ROM_REGCACHE, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ROM_FASTSP, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_BLOCK_LINKING, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_CACHE, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_DMA, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_VALIDATE, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_TLB, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_PROTECT, CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_STORE, CheckBoxChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_GameRecompiler }; + +public: + CGameRecompilePage(HWND hParent, const RECT & rcDispay); + + LanguageStringID PageTitle(void) { return TAB_RECOMPILER; } + void HidePage(void); + void ShowPage(void); + void ApplySettings(bool UpdateScreen); + bool EnableReset(void); + void ResetPage(void); + +private: + CPartialGroupBox m_SelfModGroup; +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Status.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Status.cpp index f6b4763eb..9aaefbf79 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Status.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Status.cpp @@ -1,73 +1,73 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" -#include "SettingsPage-Game-Status.h" - -CGameStatusPage::CGameStatusPage(HWND hParent, const RECT & rcDispay) -{ - if (!Create(hParent, rcDispay)) - { - return; - } - - CIniFile RomIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); - strlist Keys; - RomIniFile.GetKeyList("Rom Status", Keys); - stdstr Status = g_Settings->LoadStringVal(Rdb_Status); - - CModifiedComboBoxTxt * ComboBox; - ComboBox = AddModComboBoxTxt(GetDlgItem(IDC_STATUS_TYPE), Rdb_Status); - if (ComboBox) - { - for (strlist::iterator item = Keys.begin(); item != Keys.end(); item++) - { - if (strstr(item->c_str(), ".Sel") != NULL) { continue; } - if (strstr(item->c_str(), ".Auto") != NULL) { continue; } - ComboBox->AddItem(item->c_str(), item->c_str()); - } - ComboBox->SetTextField(GetDlgItem(IDC_STATUS_TEXT)); - } - CModifiedEditBox * TxtBox; - TxtBox = AddModTextBox(GetDlgItem(IDC_NOTES_CORE), Rdb_NotesCore, true); - TxtBox->SetTextField(GetDlgItem(IDC_NOTES_CORE_TEXT)); - TxtBox = AddModTextBox(GetDlgItem(IDC_NOTES_PLUGIN), Rdb_NotesPlugin, true); - TxtBox->SetTextField(GetDlgItem(IDC_NOTES_PLUGIN_TEXT)); - - UpdatePageSettings(); -} - -void CGameStatusPage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void CGameStatusPage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void CGameStatusPage::ApplySettings(bool UpdateScreen) -{ - CSettingsPageImpl::ApplySettings(UpdateScreen); -} - -bool CGameStatusPage::EnableReset(void) -{ - if (CSettingsPageImpl::EnableReset()) { return true; } - return false; -} - -void CGameStatusPage::ResetPage() -{ - CSettingsPageImpl::ResetPage(); -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" +#include "SettingsPage-Game-Status.h" + +CGameStatusPage::CGameStatusPage(HWND hParent, const RECT & rcDispay) +{ + if (!Create(hParent, rcDispay)) + { + return; + } + + CIniFile RomIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); + strlist Keys; + RomIniFile.GetKeyList("Rom Status", Keys); + stdstr Status = g_Settings->LoadStringVal(Rdb_Status); + + CModifiedComboBoxTxt * ComboBox; + ComboBox = AddModComboBoxTxt(GetDlgItem(IDC_STATUS_TYPE), Rdb_Status); + if (ComboBox) + { + for (strlist::iterator item = Keys.begin(); item != Keys.end(); item++) + { + if (strstr(item->c_str(), ".Sel") != NULL) { continue; } + if (strstr(item->c_str(), ".Auto") != NULL) { continue; } + ComboBox->AddItem(item->c_str(), item->c_str()); + } + ComboBox->SetTextField(GetDlgItem(IDC_STATUS_TEXT)); + } + CModifiedEditBox * TxtBox; + TxtBox = AddModTextBox(GetDlgItem(IDC_NOTES_CORE), Rdb_NotesCore, true); + TxtBox->SetTextField(GetDlgItem(IDC_NOTES_CORE_TEXT)); + TxtBox = AddModTextBox(GetDlgItem(IDC_NOTES_PLUGIN), Rdb_NotesPlugin, true); + TxtBox->SetTextField(GetDlgItem(IDC_NOTES_PLUGIN_TEXT)); + + UpdatePageSettings(); +} + +void CGameStatusPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void CGameStatusPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void CGameStatusPage::ApplySettings(bool UpdateScreen) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CGameStatusPage::EnableReset(void) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CGameStatusPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); +} diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Status.h b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Status.h index 8de3c6f9b..491d6a881 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Status.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Status.h @@ -1,36 +1,36 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CGameStatusPage : - public CSettingsPageImpl, - public CSettingsPage -{ - - BEGIN_MSG_MAP_EX(CGameStatusPage) - COMMAND_HANDLER_EX(IDC_STATUS_TYPE,LBN_SELCHANGE,ComboBoxChanged) - COMMAND_HANDLER_EX(IDC_NOTES_CORE,EN_UPDATE,EditBoxChanged) - COMMAND_HANDLER_EX(IDC_NOTES_PLUGIN,EN_UPDATE,EditBoxChanged) - END_MSG_MAP() - - enum { IDD = IDD_Settings_GameStatus }; - -public: - CGameStatusPage(HWND hParent, const RECT & rcDispay ); - - LanguageStringID PageTitle ( void ) { return TAB_ROMNOTES; } - void HidePage ( void ); - void ShowPage ( void ); - void ApplySettings ( bool UpdateScreen ); - bool EnableReset ( void ); - void ResetPage ( void ); - -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CGameStatusPage : + public CSettingsPageImpl, + public CSettingsPage +{ + + BEGIN_MSG_MAP_EX(CGameStatusPage) + COMMAND_HANDLER_EX(IDC_STATUS_TYPE,LBN_SELCHANGE,ComboBoxChanged) + COMMAND_HANDLER_EX(IDC_NOTES_CORE,EN_UPDATE,EditBoxChanged) + COMMAND_HANDLER_EX(IDC_NOTES_PLUGIN,EN_UPDATE,EditBoxChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_GameStatus }; + +public: + CGameStatusPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_ROMNOTES; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-GameBrowser.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-GameBrowser.cpp index 5a088bb2d..c7c8bbe91 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-GameBrowser.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-GameBrowser.cpp @@ -1,257 +1,257 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" - -COptionsGameBrowserPage::COptionsGameBrowserPage(HWND hParent, const RECT & rcDispay) : -m_OrderChanged(false), -m_OrderReset(false) -{ - if (!Create(hParent, rcDispay)) - { - return; - } - - SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT2, wGS(RB_ROMS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT4, wGS(RB_DIRS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_USE_ROMBROWSER, wGS(RB_USE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_RECURSION, wGS(RB_DIR_RECURSION).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT5, wGS(RB_AVALIABLE_FIELDS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT6, wGS(RB_SHOW_FIELDS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ADD, wGS(RB_ADD).c_str()); - SetDlgItemTextW(m_hWnd, IDC_REMOVE, wGS(RB_REMOVE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_UP, wGS(RB_UP).c_str()); - SetDlgItemTextW(m_hWnd, IDC_DOWN, wGS(RB_DOWN).c_str()); - - AddModCheckBox(GetDlgItem(IDC_USE_ROMBROWSER), RomBrowser_Enabled); - AddModCheckBox(GetDlgItem(IDC_RECURSION), RomBrowser_Recursive); - - m_Avaliable.Attach(GetDlgItem(IDC_AVALIABLE)); - m_Using.Attach(GetDlgItem(IDC_USING)); - - CRomBrowser::GetFieldInfo(m_Fields); - - UpdatePageSettings(); -} - -void COptionsGameBrowserPage::UpdateFieldList(const ROMBROWSER_FIELDS_LIST & Fields) -{ - m_Avaliable.ResetContent(); - m_Using.ResetContent(); - - m_OrderChanged = false; - for (int i = 0, n = Fields.size(); i < n; i++) - { - if (Fields[i].PosChanged()) - { - m_OrderChanged = true; - } - int Pos = Fields[i].Pos(); - if (Pos < 0) - { - m_Avaliable.SetItemData(m_Avaliable.AddStringW(wGS(Fields[i].LangID()).c_str()), i); - continue; - } - int listCount = m_Using.GetCount(); - if (Pos > listCount) { Pos = listCount; } - m_Using.SetItemData(m_Using.InsertStringW(Pos, wGS(Fields[i].LangID()).c_str()), i); - } -} - -void COptionsGameBrowserPage::UpdatePageSettings(void) -{ - UpdateFieldList(m_Fields); - CSettingsPageImpl::UpdatePageSettings(); - FixCtrlState(); -} - -void COptionsGameBrowserPage::UseRomBrowserChanged(UINT Code, int id, HWND ctl) -{ - CheckBoxChanged(Code, id, ctl); - FixCtrlState(); -} - -void COptionsGameBrowserPage::FixCtrlState(void) -{ - bool bEnabled = (SendDlgItemMessage(IDC_USE_ROMBROWSER, BM_GETCHECK, 0, 0) == BST_CHECKED); - ::EnableWindow(GetDlgItem(IDC_ROMSEL_TEXT5), bEnabled); - ::EnableWindow(GetDlgItem(IDC_ROMSEL_TEXT6), bEnabled); - ::EnableWindow(GetDlgItem(IDC_AVALIABLE), bEnabled); - ::EnableWindow(GetDlgItem(IDC_ADD), bEnabled); - ::EnableWindow(GetDlgItem(IDC_REMOVE), bEnabled); - ::EnableWindow(GetDlgItem(IDC_USING), bEnabled); - ::EnableWindow(GetDlgItem(IDC_UP), bEnabled); - ::EnableWindow(GetDlgItem(IDC_DOWN), bEnabled); - ::EnableWindow(GetDlgItem(IDC_RECURSION), bEnabled); -} - -void COptionsGameBrowserPage::AddFieldClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - int index = m_Avaliable.GetCurSel(); - if (index < 0) - { - return; - } - //remove from list - int i = m_Avaliable.GetItemData(index); - m_Avaliable.DeleteString(index); - - //select next in list - int listCount = m_Avaliable.GetCount(); - if (index >= listCount) { index -= 1; } - m_Avaliable.SetCurSel(index); - - //Add to list - index = m_Using.AddStringW(wGS(m_Fields[i].LangID()).c_str()); - m_Using.SetItemData(index, i); - m_Using.SetCurSel(index); - - m_OrderChanged = true; - m_OrderReset = false; - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsGameBrowserPage::RemoveFieldClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - int index = m_Using.GetCurSel(); - if (index < 0) - { - return; - } - //remove from list - int i = m_Using.GetItemData(index); - m_Using.DeleteString(index); - - //select next in list - int listCount = m_Using.GetCount(); - if (index >= listCount) { index -= 1; } - m_Using.SetCurSel(index); - - //Add to list - index = m_Avaliable.AddStringW(wGS(m_Fields[i].LangID()).c_str()); - m_Avaliable.SetItemData(index, i); - m_Avaliable.SetCurSel(index); - - m_OrderChanged = true; - m_OrderReset = false; - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsGameBrowserPage::MoveFieldUpClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - int index = m_Using.GetCurSel(); - if (index <= 0) - { - return; - } - int i = m_Using.GetItemData(index); - m_Using.DeleteString(index); - - index = m_Using.InsertStringW(index - 1, wGS(m_Fields[i].LangID()).c_str()); - m_Using.SetItemData(index, i); - m_Using.SetCurSel(index); - - m_OrderChanged = true; - m_OrderReset = false; - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsGameBrowserPage::MoveFieldDownClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - int index = m_Using.GetCurSel(); - if (index < 0 || index >= (m_Using.GetCount() - 1)) - { - return; - } - int i = m_Using.GetItemData(index); - m_Using.DeleteString(index); - - index = m_Using.InsertStringW(index + 1, wGS(m_Fields[i].LangID()).c_str()); - m_Using.SetItemData(index, i); - m_Using.SetCurSel(index); - - m_OrderChanged = true; - m_OrderReset = false; - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsGameBrowserPage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void COptionsGameBrowserPage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void COptionsGameBrowserPage::ApplySettings(bool UpdateScreen) -{ - bool bColChanged = false; - if (m_OrderReset) - { - for (size_t i = 0; i < m_Fields.size(); i++) - { - m_Fields[i].ResetPos(); - } - bColChanged = true; - } - else - { - size_t Item, listCount = m_Using.GetCount(); - for (Item = 0; Item < listCount; Item++) - { - int Pos = m_Using.GetItemData(Item); - if (m_OrderReset || m_Fields[Pos].Pos() != Item) - { - m_Fields[Pos].SetColPos(Item); - bColChanged = true; - } - } - - listCount = m_Avaliable.GetCount(); - for (Item = 0; Item < listCount; Item++) - { - int Pos = m_Avaliable.GetItemData(Item); - if (m_OrderReset || m_Fields[Pos].Pos() != -1) - { - m_Fields[Pos].SetColPos(-1); - bColChanged = true; - } - } - } - if (bColChanged) - { - g_Settings->SaveBool(RomBrowser_ColoumnsChanged, !g_Settings->LoadBool(RomBrowser_ColoumnsChanged)); - } - - CSettingsPageImpl::ApplySettings(UpdateScreen); -} - -bool COptionsGameBrowserPage::EnableReset(void) -{ - if (m_OrderChanged) { return true; } - return CSettingsPageImpl::EnableReset(); -} - -void COptionsGameBrowserPage::ResetPage() -{ - if (m_OrderChanged) - { - ROMBROWSER_FIELDS_LIST Fields; - CRomBrowser::GetFieldInfo(Fields, true); - UpdateFieldList(Fields); - m_OrderReset = true; - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); - } - CSettingsPageImpl::ResetPage(); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" + +COptionsGameBrowserPage::COptionsGameBrowserPage(HWND hParent, const RECT & rcDispay) : +m_OrderChanged(false), +m_OrderReset(false) +{ + if (!Create(hParent, rcDispay)) + { + return; + } + + SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT2, wGS(RB_ROMS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT4, wGS(RB_DIRS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_USE_ROMBROWSER, wGS(RB_USE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_RECURSION, wGS(RB_DIR_RECURSION).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT5, wGS(RB_AVALIABLE_FIELDS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT6, wGS(RB_SHOW_FIELDS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ADD, wGS(RB_ADD).c_str()); + SetDlgItemTextW(m_hWnd, IDC_REMOVE, wGS(RB_REMOVE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_UP, wGS(RB_UP).c_str()); + SetDlgItemTextW(m_hWnd, IDC_DOWN, wGS(RB_DOWN).c_str()); + + AddModCheckBox(GetDlgItem(IDC_USE_ROMBROWSER), RomBrowser_Enabled); + AddModCheckBox(GetDlgItem(IDC_RECURSION), RomBrowser_Recursive); + + m_Avaliable.Attach(GetDlgItem(IDC_AVALIABLE)); + m_Using.Attach(GetDlgItem(IDC_USING)); + + CRomBrowser::GetFieldInfo(m_Fields); + + UpdatePageSettings(); +} + +void COptionsGameBrowserPage::UpdateFieldList(const ROMBROWSER_FIELDS_LIST & Fields) +{ + m_Avaliable.ResetContent(); + m_Using.ResetContent(); + + m_OrderChanged = false; + for (int i = 0, n = Fields.size(); i < n; i++) + { + if (Fields[i].PosChanged()) + { + m_OrderChanged = true; + } + int Pos = Fields[i].Pos(); + if (Pos < 0) + { + m_Avaliable.SetItemData(m_Avaliable.AddStringW(wGS(Fields[i].LangID()).c_str()), i); + continue; + } + int listCount = m_Using.GetCount(); + if (Pos > listCount) { Pos = listCount; } + m_Using.SetItemData(m_Using.InsertStringW(Pos, wGS(Fields[i].LangID()).c_str()), i); + } +} + +void COptionsGameBrowserPage::UpdatePageSettings(void) +{ + UpdateFieldList(m_Fields); + CSettingsPageImpl::UpdatePageSettings(); + FixCtrlState(); +} + +void COptionsGameBrowserPage::UseRomBrowserChanged(UINT Code, int id, HWND ctl) +{ + CheckBoxChanged(Code, id, ctl); + FixCtrlState(); +} + +void COptionsGameBrowserPage::FixCtrlState(void) +{ + bool bEnabled = (SendDlgItemMessage(IDC_USE_ROMBROWSER, BM_GETCHECK, 0, 0) == BST_CHECKED); + ::EnableWindow(GetDlgItem(IDC_ROMSEL_TEXT5), bEnabled); + ::EnableWindow(GetDlgItem(IDC_ROMSEL_TEXT6), bEnabled); + ::EnableWindow(GetDlgItem(IDC_AVALIABLE), bEnabled); + ::EnableWindow(GetDlgItem(IDC_ADD), bEnabled); + ::EnableWindow(GetDlgItem(IDC_REMOVE), bEnabled); + ::EnableWindow(GetDlgItem(IDC_USING), bEnabled); + ::EnableWindow(GetDlgItem(IDC_UP), bEnabled); + ::EnableWindow(GetDlgItem(IDC_DOWN), bEnabled); + ::EnableWindow(GetDlgItem(IDC_RECURSION), bEnabled); +} + +void COptionsGameBrowserPage::AddFieldClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + int index = m_Avaliable.GetCurSel(); + if (index < 0) + { + return; + } + //remove from list + int i = m_Avaliable.GetItemData(index); + m_Avaliable.DeleteString(index); + + //select next in list + int listCount = m_Avaliable.GetCount(); + if (index >= listCount) { index -= 1; } + m_Avaliable.SetCurSel(index); + + //Add to list + index = m_Using.AddStringW(wGS(m_Fields[i].LangID()).c_str()); + m_Using.SetItemData(index, i); + m_Using.SetCurSel(index); + + m_OrderChanged = true; + m_OrderReset = false; + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsGameBrowserPage::RemoveFieldClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + int index = m_Using.GetCurSel(); + if (index < 0) + { + return; + } + //remove from list + int i = m_Using.GetItemData(index); + m_Using.DeleteString(index); + + //select next in list + int listCount = m_Using.GetCount(); + if (index >= listCount) { index -= 1; } + m_Using.SetCurSel(index); + + //Add to list + index = m_Avaliable.AddStringW(wGS(m_Fields[i].LangID()).c_str()); + m_Avaliable.SetItemData(index, i); + m_Avaliable.SetCurSel(index); + + m_OrderChanged = true; + m_OrderReset = false; + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsGameBrowserPage::MoveFieldUpClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + int index = m_Using.GetCurSel(); + if (index <= 0) + { + return; + } + int i = m_Using.GetItemData(index); + m_Using.DeleteString(index); + + index = m_Using.InsertStringW(index - 1, wGS(m_Fields[i].LangID()).c_str()); + m_Using.SetItemData(index, i); + m_Using.SetCurSel(index); + + m_OrderChanged = true; + m_OrderReset = false; + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsGameBrowserPage::MoveFieldDownClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + int index = m_Using.GetCurSel(); + if (index < 0 || index >= (m_Using.GetCount() - 1)) + { + return; + } + int i = m_Using.GetItemData(index); + m_Using.DeleteString(index); + + index = m_Using.InsertStringW(index + 1, wGS(m_Fields[i].LangID()).c_str()); + m_Using.SetItemData(index, i); + m_Using.SetCurSel(index); + + m_OrderChanged = true; + m_OrderReset = false; + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsGameBrowserPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void COptionsGameBrowserPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void COptionsGameBrowserPage::ApplySettings(bool UpdateScreen) +{ + bool bColChanged = false; + if (m_OrderReset) + { + for (size_t i = 0; i < m_Fields.size(); i++) + { + m_Fields[i].ResetPos(); + } + bColChanged = true; + } + else + { + size_t Item, listCount = m_Using.GetCount(); + for (Item = 0; Item < listCount; Item++) + { + int Pos = m_Using.GetItemData(Item); + if (m_OrderReset || m_Fields[Pos].Pos() != Item) + { + m_Fields[Pos].SetColPos(Item); + bColChanged = true; + } + } + + listCount = m_Avaliable.GetCount(); + for (Item = 0; Item < listCount; Item++) + { + int Pos = m_Avaliable.GetItemData(Item); + if (m_OrderReset || m_Fields[Pos].Pos() != -1) + { + m_Fields[Pos].SetColPos(-1); + bColChanged = true; + } + } + } + if (bColChanged) + { + g_Settings->SaveBool(RomBrowser_ColoumnsChanged, !g_Settings->LoadBool(RomBrowser_ColoumnsChanged)); + } + + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool COptionsGameBrowserPage::EnableReset(void) +{ + if (m_OrderChanged) { return true; } + return CSettingsPageImpl::EnableReset(); +} + +void COptionsGameBrowserPage::ResetPage() +{ + if (m_OrderChanged) + { + ROMBROWSER_FIELDS_LIST Fields; + CRomBrowser::GetFieldInfo(Fields, true); + UpdateFieldList(Fields); + m_OrderReset = true; + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); + } + CSettingsPageImpl::ResetPage(); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-GameBrowser.h b/Source/Project64/UserInterface/Settings/SettingsPage-GameBrowser.h index 2aaea0144..a5a08b4f0 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-GameBrowser.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-GameBrowser.h @@ -1,51 +1,51 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class COptionsGameBrowserPage : - public CSettingsPageImpl, - public CSettingsPage -{ - BEGIN_MSG_MAP_EX(COptionsGameBrowserPage) - COMMAND_HANDLER_EX(IDC_ADD, BN_CLICKED, AddFieldClicked) - COMMAND_HANDLER_EX(IDC_REMOVE, BN_CLICKED, RemoveFieldClicked) - COMMAND_HANDLER_EX(IDC_UP, BN_CLICKED, MoveFieldUpClicked) - COMMAND_HANDLER_EX(IDC_DOWN, BN_CLICKED, MoveFieldDownClicked) - COMMAND_ID_HANDLER_EX(IDC_USE_ROMBROWSER, UseRomBrowserChanged) - COMMAND_ID_HANDLER_EX(IDC_RECURSION, CheckBoxChanged) - END_MSG_MAP() - - enum { IDD = IDD_Settings_RomBrowser }; - -public: - COptionsGameBrowserPage(HWND hParent, const RECT & rcDispay); - - LanguageStringID PageTitle(void) { return TAB_ROMSELECTION; } - void HidePage(void); - void ShowPage(void); - void ApplySettings(bool UpdateScreen); - bool EnableReset(void); - void ResetPage(void); - -private: - void UpdatePageSettings(void); - void UpdateFieldList(const ROMBROWSER_FIELDS_LIST & Fields); - void AddFieldClicked(UINT Code, int id, HWND ctl); - void RemoveFieldClicked(UINT Code, int id, HWND ctl); - void MoveFieldUpClicked(UINT Code, int id, HWND ctl); - void MoveFieldDownClicked(UINT Code, int id, HWND ctl); - void UseRomBrowserChanged(UINT Code, int id, HWND ctl); - void FixCtrlState(void); - - ROMBROWSER_FIELDS_LIST m_Fields; - CListBox m_Avaliable, m_Using; - bool m_OrderChanged, m_OrderReset; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class COptionsGameBrowserPage : + public CSettingsPageImpl, + public CSettingsPage +{ + BEGIN_MSG_MAP_EX(COptionsGameBrowserPage) + COMMAND_HANDLER_EX(IDC_ADD, BN_CLICKED, AddFieldClicked) + COMMAND_HANDLER_EX(IDC_REMOVE, BN_CLICKED, RemoveFieldClicked) + COMMAND_HANDLER_EX(IDC_UP, BN_CLICKED, MoveFieldUpClicked) + COMMAND_HANDLER_EX(IDC_DOWN, BN_CLICKED, MoveFieldDownClicked) + COMMAND_ID_HANDLER_EX(IDC_USE_ROMBROWSER, UseRomBrowserChanged) + COMMAND_ID_HANDLER_EX(IDC_RECURSION, CheckBoxChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_RomBrowser }; + +public: + COptionsGameBrowserPage(HWND hParent, const RECT & rcDispay); + + LanguageStringID PageTitle(void) { return TAB_ROMSELECTION; } + void HidePage(void); + void ShowPage(void); + void ApplySettings(bool UpdateScreen); + bool EnableReset(void); + void ResetPage(void); + +private: + void UpdatePageSettings(void); + void UpdateFieldList(const ROMBROWSER_FIELDS_LIST & Fields); + void AddFieldClicked(UINT Code, int id, HWND ctl); + void RemoveFieldClicked(UINT Code, int id, HWND ctl); + void MoveFieldUpClicked(UINT Code, int id, HWND ctl); + void MoveFieldDownClicked(UINT Code, int id, HWND ctl); + void UseRomBrowserChanged(UINT Code, int id, HWND ctl); + void FixCtrlState(void); + + ROMBROWSER_FIELDS_LIST m_Fields; + CListBox m_Avaliable, m_Using; + bool m_OrderChanged, m_OrderReset; +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-KeyboardShortcuts.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-KeyboardShortcuts.cpp index cb47ea1f9..28c37feea 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-KeyboardShortcuts.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-KeyboardShortcuts.cpp @@ -1,375 +1,375 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" - -COptionsShortCutsPage::COptionsShortCutsPage(HWND hParent, const RECT & rcDispay) : -m_EnableReset(false) -{ - if (!Create(hParent, rcDispay)) - { - return; - } - - SetDlgItemTextW(m_hWnd, IDC_S_CPU_STATE, wGS(ACCEL_CPUSTATE_TITLE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_MENU_ITEM_TEXT, wGS(ACCEL_MENUITEM_TITLE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_S_CURRENT_KEYS, wGS(ACCEL_CURRENTKEYS_TITLE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_S_SELECT_SHORT, wGS(ACCEL_SELKEY_TITLE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_S_CURRENT_ASSIGN, wGS(ACCEL_ASSIGNEDTO_TITLE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ASSIGN, wGS(ACCEL_ASSIGN_BTN).c_str()); - SetDlgItemTextW(m_hWnd, IDC_REMOVE, wGS(ACCEL_REMOVE_BTN).c_str()); - SetDlgItemTextW(m_hWnd, IDC_KEY_PROMPT, wGS(ACCEL_DETECTKEY).c_str()); - - m_CreateNewShortCut.AttachToDlgItem(m_hWnd, IDC_S_SELECT_SHORT); - m_CpuState.Attach(GetDlgItem(IDC_C_CPU_STATE)); - m_MenuItems.Attach(GetDlgItem(IDC_MENU_ITEMS)); - m_CurrentKeys.Attach(GetDlgItem(IDC_CURRENT_KEYS)); - m_VirtualKeyList.Attach(GetDlgItem(IDC_VIRTUALKEY)); - - m_MenuItems.ModifyStyle(0, TVS_SHOWSELALWAYS); - - m_CpuState.SetItemData(m_CpuState.AddStringW(wGS(ACCEL_CPUSTATE_1).c_str()), CMenuShortCutKey::GAME_NOT_RUNNING); - m_CpuState.SetItemData(m_CpuState.AddStringW(wGS(ACCEL_CPUSTATE_3).c_str()), CMenuShortCutKey::GAME_RUNNING_WINDOW); - m_CpuState.SetItemData(m_CpuState.AddStringW(wGS(ACCEL_CPUSTATE_4).c_str()), CMenuShortCutKey::GAME_RUNNING_FULLSCREEN); - m_CpuState.SetCurSel(0); - - int VirtualKeyListSize; - VIRTUAL_KEY * VirtualKeyList = CMenuShortCutKey::VirtualKeyList(VirtualKeyListSize); - for (int count = 0; count < VirtualKeyListSize; count++) - { - m_VirtualKeyList.SetItemData(m_VirtualKeyList.AddString(VirtualKeyList[count].Name), VirtualKeyList[count].Key); - } - - OnCpuStateChanged(LBN_SELCHANGE, IDC_C_CPU_STATE, GetDlgItem(IDC_C_CPU_STATE)); - CheckResetEnable(); -} - -void COptionsShortCutsPage::CheckResetEnable(void) -{ - MSC_MAP & ShortCuts = m_ShortCuts.GetShortCuts(); - for (MSC_MAP::iterator Item = ShortCuts.begin(); Item != ShortCuts.end(); Item++) - { - const SHORTCUT_KEY_LIST & ShortCutList = Item->second.GetAccelItems(); - for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item++) - { - if (!ShortCut_item->Inactive() && !ShortCut_item->UserAdded()) - { - continue; - } - m_EnableReset = true; - return; - } - } - m_EnableReset = false; -} - -void COptionsShortCutsPage::OnCpuStateChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); - - MSC_MAP & ShortCuts = m_ShortCuts.GetShortCuts(); - m_MenuItems.DeleteAllItems(); - - for (MSC_MAP::iterator Item = ShortCuts.begin(); Item != ShortCuts.end(); Item++) - { - ACCESS_MODE ItemMode = Item->second.AccessMode(); - if ((ItemMode & AccessLevel) != AccessLevel) - { - continue; - } - //find Parent - HTREEITEM hParent = m_MenuItems.GetChildItem(TVI_ROOT); - while (hParent) - { - if (m_MenuItems.GetItemData(hParent) == (DWORD_PTR)Item->second.Section()) - { - break; - } - hParent = m_MenuItems.GetNextSiblingItem(hParent); - } - - if (hParent == NULL) - { - hParent = m_MenuItems.InsertItemW(TVIF_TEXT | TVIF_PARAM, wGS(Item->second.Section()).c_str(), 0, 0, 0, 0, Item->second.Section(), TVI_ROOT, TVI_LAST); - } - - wstring str = wGS(Item->second.Title()); - std::wstring::size_type pos = str.find(L"&"); - while (pos != std::wstring::npos) - { - str.replace(pos, 1, L""); - pos = str.find(L"&", pos); - } - pos = str.find(L"..."); - while (pos != std::wstring::npos) - { - str.replace(pos, 3, L""); - pos = str.find(L"...", pos); - } - - HTREEITEM hItem = m_MenuItems.InsertItemW(TVIF_TEXT | TVIF_PARAM, str.c_str(), 0, 0, 0, 0, (DWORD_PTR)&Item->second, hParent, TVI_LAST); - - const SHORTCUT_KEY_LIST & ShortCutList = Item->second.GetAccelItems(); - for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item++) - { - if (!ShortCut_item->Inactive() && !ShortCut_item->UserAdded()) - { - continue; - } - m_MenuItems.SetItemState(hItem, TVIS_BOLD, TVIS_BOLD); - m_MenuItems.SetItemState(hParent, TVIS_BOLD, TVIS_BOLD); - break; - } - } -} - -void COptionsShortCutsPage::OnRemoveClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - HTREEITEM hSelectedItem = m_MenuItems.GetSelectedItem(); - if (hSelectedItem == NULL) - { - g_Notify->DisplayError(GS(MSG_NO_SEL_SHORTCUT)); - return; - } - HTREEITEM hParent = m_MenuItems.GetParentItem(hSelectedItem); - if (hParent == NULL) - { - g_Notify->DisplayError(GS(MSG_NO_SEL_SHORTCUT)); - return; - } - - CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hSelectedItem); - - //Make sure an item is selected - int index = m_CurrentKeys.GetCurSel(); - if (index < 0) - { - g_Notify->DisplayError(GS(MSG_NO_SEL_SHORTCUT)); - return; - } - ShortCut->RemoveItem((CMenuShortCutKey *)m_CurrentKeys.GetItemData(index)); - m_MenuItems.SetItemState(hSelectedItem, TVIS_BOLD, TVIS_BOLD); - m_MenuItems.SetItemState(hParent, TVIS_BOLD, TVIS_BOLD); - m_EnableReset = true; - - RefreshShortCutOptions(hSelectedItem); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsShortCutsPage::OnDetectKeyClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)stInputGetKeys, this, 0, NULL)); -} - -void COptionsShortCutsPage::OnAssignClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - //Get the virtual key info - int index = m_VirtualKeyList.GetCurSel(); - if (index < 0) - { - g_Notify->DisplayError(GS(MSG_NO_SHORTCUT_SEL)); - return; - } - - WORD key = (WORD)SendDlgItemMessage(IDC_VIRTUALKEY, CB_GETITEMDATA, index, 0); - bool bCtrl = (SendDlgItemMessage(IDC_CTL, BM_GETCHECK, 0, 0) == BST_CHECKED); - bool bAlt = (SendDlgItemMessage(IDC_ALT, BM_GETCHECK, 0, 0) == BST_CHECKED); - bool bShift = (SendDlgItemMessage(IDC_SHIFT, BM_GETCHECK, 0, 0) == BST_CHECKED); - - ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); - - HTREEITEM hSelectedItem = m_MenuItems.GetSelectedItem(); - if (hSelectedItem == NULL) - { - g_Notify->DisplayError(GS(MSG_NO_MENUITEM_SEL)); - return; - } - HTREEITEM hParent = m_MenuItems.GetParentItem(hSelectedItem); - if (hParent == NULL) - { - g_Notify->DisplayError(GS(MSG_NO_MENUITEM_SEL)); - return; - } - - CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hSelectedItem); - - LanguageStringID strid = m_ShortCuts.GetMenuItemName(key, bCtrl, bAlt, bShift, AccessLevel); - if (strid != EMPTY_STRING) - { - g_Notify->DisplayError(GS(MSG_MENUITEM_ASSIGNED)); - return; - } - ShortCut->AddShortCut(key, bCtrl, bAlt, bShift, AccessLevel, true, false); - m_MenuItems.SetItemState(hSelectedItem, TVIS_BOLD, TVIS_BOLD); - m_MenuItems.SetItemState(hParent, TVIS_BOLD, TVIS_BOLD); - m_EnableReset = true; - - RefreshShortCutOptions(hSelectedItem); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); -} - -void COptionsShortCutsPage::OnShortCutChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) -{ - //Get the virtual key info - int index = m_VirtualKeyList.GetCurSel(); - if (index < 0) { return; } - WORD key = (WORD)m_VirtualKeyList.GetItemData(index); - bool bCtrl = (SendDlgItemMessage(IDC_CTL, BM_GETCHECK, 0, 0) == BST_CHECKED); - bool bAlt = (SendDlgItemMessage(IDC_ALT, BM_GETCHECK, 0, 0) == BST_CHECKED); - bool bShift = (SendDlgItemMessage(IDC_SHIFT, BM_GETCHECK, 0, 0) == BST_CHECKED); - - ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); - - stdstr str = GS(m_ShortCuts.GetMenuItemName(key, bCtrl, bAlt, bShift, AccessLevel)); - if (str.length() > 0) - { - str.resize(std::remove(str.begin(), str.end(), '&') - str.begin()); - } - else - { - str = "None"; - } - SetDlgItemText(IDC_ASSIGNED_MENU_ITEM, str.c_str()); -} - -LRESULT COptionsShortCutsPage::OnMenuItemChanged(LPNMHDR lpnmh) -{ - RefreshShortCutOptions(((LPNMTREEVIEW)lpnmh)->itemNew.hItem); - return true; -} - -void COptionsShortCutsPage::RefreshShortCutOptions(HTREEITEM hItem) -{ - HTREEITEM hParent = m_MenuItems.GetParentItem(hItem); - if (hParent == NULL) - { - return; - } - - ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); - CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hItem); - - m_CurrentKeys.ResetContent(); - - const SHORTCUT_KEY_LIST & ShortCutList = ShortCut->GetAccelItems(); - for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item++) - { - if (ShortCut_item->Inactive()) - { - continue; - } - - ACCESS_MODE ItemMode = ShortCut_item->AccessMode(); - if ((ItemMode & AccessLevel) != AccessLevel) - { - continue; - } - stdstr Name = ShortCut_item->Name(); - m_CurrentKeys.SetItemData(m_CurrentKeys.AddString(Name.c_str()), (DWORD_PTR)&*ShortCut_item); - } -} - -BOOL CALLBACK KeyPromptDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM /*lParam*/) -{ - switch (uMsg) - { - case WM_INITDIALOG: - break; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDCANCEL: - SetForegroundWindow(GetParent(hDlg)); - DestroyWindow(hDlg); - break; - } - break; - default: - return FALSE; - } - return TRUE; -} - -void COptionsShortCutsPage::InputGetKeys(void) -{ - HWND hKeyDlg = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_Key_Prompt), m_hWnd, (DLGPROC)KeyPromptDlgProc, (LPARAM)::GetDlgItem(m_hWnd, IDC_VIRTUALKEY)); - ::EnableWindow(GetParent(), false); - MSG msg; - - for (bool fDone = false; !fDone; MsgWaitForMultipleObjects(0, NULL, false, 45, QS_ALLINPUT)) { - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) { - fDone = true; - ::PostMessage(NULL, WM_QUIT, 0, 0); - break; - } - if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) { - int nVirtKey = (int)msg.wParam; - if (nVirtKey == VK_SHIFT) { continue; } - if (nVirtKey == VK_CONTROL) { continue; } - if (nVirtKey == VK_MENU) { continue; } - SendDlgItemMessage(IDC_VIRTUALKEY, CB_SETCURSEL, (WPARAM)-1, 0); - for (int count = 0; count < SendDlgItemMessage(IDC_VIRTUALKEY, CB_GETCOUNT, 0, 0); count++) { - int Data = (int)SendDlgItemMessage(IDC_VIRTUALKEY, CB_GETITEMDATA, count, 0); - if (Data != nVirtKey) { continue; } - SendDlgItemMessage(IDC_VIRTUALKEY, CB_SETCURSEL, count, 0); - SendDlgItemMessage(IDC_CTL, BM_SETCHECK, (GetKeyState(VK_CONTROL) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(IDC_ALT, BM_SETCHECK, (GetKeyState(VK_MENU) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage(IDC_SHIFT, BM_SETCHECK, (GetKeyState(VK_SHIFT) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED, 0); - SendMessage(WM_COMMAND, MAKELPARAM(IDC_VIRTUALKEY, LBN_SELCHANGE), (LPARAM)::GetDlgItem(m_hWnd, IDC_VIRTUALKEY)); - SetForegroundWindow(GetParent()); - ::DestroyWindow(hKeyDlg); - } - continue; - } - if (!::IsDialogMessage(hKeyDlg, &msg)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - if (!::IsWindow(hKeyDlg)) { fDone = true; } - } - ::SetFocus(GetParent()); - ::EnableWindow(GetParent(), true); -} - -void COptionsShortCutsPage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void COptionsShortCutsPage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void COptionsShortCutsPage::ApplySettings(bool /*UpdateScreen*/) -{ - m_ShortCuts.Save(); - g_Settings->SaveBool(Info_ShortCutsChanged, true); -} - -bool COptionsShortCutsPage::EnableReset(void) -{ - return m_EnableReset; -} - -void COptionsShortCutsPage::ResetPage() -{ - m_EnableReset = false; - m_ShortCuts.Load(true); - OnCpuStateChanged(LBN_SELCHANGE, IDC_C_CPU_STATE, GetDlgItem(IDC_C_CPU_STATE)); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); - m_CurrentKeys.ResetContent(); - CSettingsPageImpl::ResetPage(); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" + +COptionsShortCutsPage::COptionsShortCutsPage(HWND hParent, const RECT & rcDispay) : +m_EnableReset(false) +{ + if (!Create(hParent, rcDispay)) + { + return; + } + + SetDlgItemTextW(m_hWnd, IDC_S_CPU_STATE, wGS(ACCEL_CPUSTATE_TITLE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_MENU_ITEM_TEXT, wGS(ACCEL_MENUITEM_TITLE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_S_CURRENT_KEYS, wGS(ACCEL_CURRENTKEYS_TITLE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_S_SELECT_SHORT, wGS(ACCEL_SELKEY_TITLE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_S_CURRENT_ASSIGN, wGS(ACCEL_ASSIGNEDTO_TITLE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ASSIGN, wGS(ACCEL_ASSIGN_BTN).c_str()); + SetDlgItemTextW(m_hWnd, IDC_REMOVE, wGS(ACCEL_REMOVE_BTN).c_str()); + SetDlgItemTextW(m_hWnd, IDC_KEY_PROMPT, wGS(ACCEL_DETECTKEY).c_str()); + + m_CreateNewShortCut.AttachToDlgItem(m_hWnd, IDC_S_SELECT_SHORT); + m_CpuState.Attach(GetDlgItem(IDC_C_CPU_STATE)); + m_MenuItems.Attach(GetDlgItem(IDC_MENU_ITEMS)); + m_CurrentKeys.Attach(GetDlgItem(IDC_CURRENT_KEYS)); + m_VirtualKeyList.Attach(GetDlgItem(IDC_VIRTUALKEY)); + + m_MenuItems.ModifyStyle(0, TVS_SHOWSELALWAYS); + + m_CpuState.SetItemData(m_CpuState.AddStringW(wGS(ACCEL_CPUSTATE_1).c_str()), CMenuShortCutKey::GAME_NOT_RUNNING); + m_CpuState.SetItemData(m_CpuState.AddStringW(wGS(ACCEL_CPUSTATE_3).c_str()), CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_CpuState.SetItemData(m_CpuState.AddStringW(wGS(ACCEL_CPUSTATE_4).c_str()), CMenuShortCutKey::GAME_RUNNING_FULLSCREEN); + m_CpuState.SetCurSel(0); + + int VirtualKeyListSize; + VIRTUAL_KEY * VirtualKeyList = CMenuShortCutKey::VirtualKeyList(VirtualKeyListSize); + for (int count = 0; count < VirtualKeyListSize; count++) + { + m_VirtualKeyList.SetItemData(m_VirtualKeyList.AddString(VirtualKeyList[count].Name), VirtualKeyList[count].Key); + } + + OnCpuStateChanged(LBN_SELCHANGE, IDC_C_CPU_STATE, GetDlgItem(IDC_C_CPU_STATE)); + CheckResetEnable(); +} + +void COptionsShortCutsPage::CheckResetEnable(void) +{ + MSC_MAP & ShortCuts = m_ShortCuts.GetShortCuts(); + for (MSC_MAP::iterator Item = ShortCuts.begin(); Item != ShortCuts.end(); Item++) + { + const SHORTCUT_KEY_LIST & ShortCutList = Item->second.GetAccelItems(); + for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item++) + { + if (!ShortCut_item->Inactive() && !ShortCut_item->UserAdded()) + { + continue; + } + m_EnableReset = true; + return; + } + } + m_EnableReset = false; +} + +void COptionsShortCutsPage::OnCpuStateChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + + MSC_MAP & ShortCuts = m_ShortCuts.GetShortCuts(); + m_MenuItems.DeleteAllItems(); + + for (MSC_MAP::iterator Item = ShortCuts.begin(); Item != ShortCuts.end(); Item++) + { + ACCESS_MODE ItemMode = Item->second.AccessMode(); + if ((ItemMode & AccessLevel) != AccessLevel) + { + continue; + } + //find Parent + HTREEITEM hParent = m_MenuItems.GetChildItem(TVI_ROOT); + while (hParent) + { + if (m_MenuItems.GetItemData(hParent) == (DWORD_PTR)Item->second.Section()) + { + break; + } + hParent = m_MenuItems.GetNextSiblingItem(hParent); + } + + if (hParent == NULL) + { + hParent = m_MenuItems.InsertItemW(TVIF_TEXT | TVIF_PARAM, wGS(Item->second.Section()).c_str(), 0, 0, 0, 0, Item->second.Section(), TVI_ROOT, TVI_LAST); + } + + wstring str = wGS(Item->second.Title()); + std::wstring::size_type pos = str.find(L"&"); + while (pos != std::wstring::npos) + { + str.replace(pos, 1, L""); + pos = str.find(L"&", pos); + } + pos = str.find(L"..."); + while (pos != std::wstring::npos) + { + str.replace(pos, 3, L""); + pos = str.find(L"...", pos); + } + + HTREEITEM hItem = m_MenuItems.InsertItemW(TVIF_TEXT | TVIF_PARAM, str.c_str(), 0, 0, 0, 0, (DWORD_PTR)&Item->second, hParent, TVI_LAST); + + const SHORTCUT_KEY_LIST & ShortCutList = Item->second.GetAccelItems(); + for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item++) + { + if (!ShortCut_item->Inactive() && !ShortCut_item->UserAdded()) + { + continue; + } + m_MenuItems.SetItemState(hItem, TVIS_BOLD, TVIS_BOLD); + m_MenuItems.SetItemState(hParent, TVIS_BOLD, TVIS_BOLD); + break; + } + } +} + +void COptionsShortCutsPage::OnRemoveClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + HTREEITEM hSelectedItem = m_MenuItems.GetSelectedItem(); + if (hSelectedItem == NULL) + { + g_Notify->DisplayError(GS(MSG_NO_SEL_SHORTCUT)); + return; + } + HTREEITEM hParent = m_MenuItems.GetParentItem(hSelectedItem); + if (hParent == NULL) + { + g_Notify->DisplayError(GS(MSG_NO_SEL_SHORTCUT)); + return; + } + + CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hSelectedItem); + + //Make sure an item is selected + int index = m_CurrentKeys.GetCurSel(); + if (index < 0) + { + g_Notify->DisplayError(GS(MSG_NO_SEL_SHORTCUT)); + return; + } + ShortCut->RemoveItem((CMenuShortCutKey *)m_CurrentKeys.GetItemData(index)); + m_MenuItems.SetItemState(hSelectedItem, TVIS_BOLD, TVIS_BOLD); + m_MenuItems.SetItemState(hParent, TVIS_BOLD, TVIS_BOLD); + m_EnableReset = true; + + RefreshShortCutOptions(hSelectedItem); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsShortCutsPage::OnDetectKeyClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)stInputGetKeys, this, 0, NULL)); +} + +void COptionsShortCutsPage::OnAssignClicked(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + //Get the virtual key info + int index = m_VirtualKeyList.GetCurSel(); + if (index < 0) + { + g_Notify->DisplayError(GS(MSG_NO_SHORTCUT_SEL)); + return; + } + + WORD key = (WORD)SendDlgItemMessage(IDC_VIRTUALKEY, CB_GETITEMDATA, index, 0); + bool bCtrl = (SendDlgItemMessage(IDC_CTL, BM_GETCHECK, 0, 0) == BST_CHECKED); + bool bAlt = (SendDlgItemMessage(IDC_ALT, BM_GETCHECK, 0, 0) == BST_CHECKED); + bool bShift = (SendDlgItemMessage(IDC_SHIFT, BM_GETCHECK, 0, 0) == BST_CHECKED); + + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + + HTREEITEM hSelectedItem = m_MenuItems.GetSelectedItem(); + if (hSelectedItem == NULL) + { + g_Notify->DisplayError(GS(MSG_NO_MENUITEM_SEL)); + return; + } + HTREEITEM hParent = m_MenuItems.GetParentItem(hSelectedItem); + if (hParent == NULL) + { + g_Notify->DisplayError(GS(MSG_NO_MENUITEM_SEL)); + return; + } + + CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hSelectedItem); + + LanguageStringID strid = m_ShortCuts.GetMenuItemName(key, bCtrl, bAlt, bShift, AccessLevel); + if (strid != EMPTY_STRING) + { + g_Notify->DisplayError(GS(MSG_MENUITEM_ASSIGNED)); + return; + } + ShortCut->AddShortCut(key, bCtrl, bAlt, bShift, AccessLevel, true, false); + m_MenuItems.SetItemState(hSelectedItem, TVIS_BOLD, TVIS_BOLD); + m_MenuItems.SetItemState(hParent, TVIS_BOLD, TVIS_BOLD); + m_EnableReset = true; + + RefreshShortCutOptions(hSelectedItem); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); +} + +void COptionsShortCutsPage::OnShortCutChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +{ + //Get the virtual key info + int index = m_VirtualKeyList.GetCurSel(); + if (index < 0) { return; } + WORD key = (WORD)m_VirtualKeyList.GetItemData(index); + bool bCtrl = (SendDlgItemMessage(IDC_CTL, BM_GETCHECK, 0, 0) == BST_CHECKED); + bool bAlt = (SendDlgItemMessage(IDC_ALT, BM_GETCHECK, 0, 0) == BST_CHECKED); + bool bShift = (SendDlgItemMessage(IDC_SHIFT, BM_GETCHECK, 0, 0) == BST_CHECKED); + + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + + stdstr str = GS(m_ShortCuts.GetMenuItemName(key, bCtrl, bAlt, bShift, AccessLevel)); + if (str.length() > 0) + { + str.resize(std::remove(str.begin(), str.end(), '&') - str.begin()); + } + else + { + str = "None"; + } + SetDlgItemText(IDC_ASSIGNED_MENU_ITEM, str.c_str()); +} + +LRESULT COptionsShortCutsPage::OnMenuItemChanged(LPNMHDR lpnmh) +{ + RefreshShortCutOptions(((LPNMTREEVIEW)lpnmh)->itemNew.hItem); + return true; +} + +void COptionsShortCutsPage::RefreshShortCutOptions(HTREEITEM hItem) +{ + HTREEITEM hParent = m_MenuItems.GetParentItem(hItem); + if (hParent == NULL) + { + return; + } + + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hItem); + + m_CurrentKeys.ResetContent(); + + const SHORTCUT_KEY_LIST & ShortCutList = ShortCut->GetAccelItems(); + for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item++) + { + if (ShortCut_item->Inactive()) + { + continue; + } + + ACCESS_MODE ItemMode = ShortCut_item->AccessMode(); + if ((ItemMode & AccessLevel) != AccessLevel) + { + continue; + } + stdstr Name = ShortCut_item->Name(); + m_CurrentKeys.SetItemData(m_CurrentKeys.AddString(Name.c_str()), (DWORD_PTR)&*ShortCut_item); + } +} + +BOOL CALLBACK KeyPromptDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM /*lParam*/) +{ + switch (uMsg) + { + case WM_INITDIALOG: + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: + SetForegroundWindow(GetParent(hDlg)); + DestroyWindow(hDlg); + break; + } + break; + default: + return FALSE; + } + return TRUE; +} + +void COptionsShortCutsPage::InputGetKeys(void) +{ + HWND hKeyDlg = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_Key_Prompt), m_hWnd, (DLGPROC)KeyPromptDlgProc, (LPARAM)::GetDlgItem(m_hWnd, IDC_VIRTUALKEY)); + ::EnableWindow(GetParent(), false); + MSG msg; + + for (bool fDone = false; !fDone; MsgWaitForMultipleObjects(0, NULL, false, 45, QS_ALLINPUT)) { + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) { + fDone = true; + ::PostMessage(NULL, WM_QUIT, 0, 0); + break; + } + if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) { + int nVirtKey = (int)msg.wParam; + if (nVirtKey == VK_SHIFT) { continue; } + if (nVirtKey == VK_CONTROL) { continue; } + if (nVirtKey == VK_MENU) { continue; } + SendDlgItemMessage(IDC_VIRTUALKEY, CB_SETCURSEL, (WPARAM)-1, 0); + for (int count = 0; count < SendDlgItemMessage(IDC_VIRTUALKEY, CB_GETCOUNT, 0, 0); count++) { + int Data = (int)SendDlgItemMessage(IDC_VIRTUALKEY, CB_GETITEMDATA, count, 0); + if (Data != nVirtKey) { continue; } + SendDlgItemMessage(IDC_VIRTUALKEY, CB_SETCURSEL, count, 0); + SendDlgItemMessage(IDC_CTL, BM_SETCHECK, (GetKeyState(VK_CONTROL) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(IDC_ALT, BM_SETCHECK, (GetKeyState(VK_MENU) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage(IDC_SHIFT, BM_SETCHECK, (GetKeyState(VK_SHIFT) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED, 0); + SendMessage(WM_COMMAND, MAKELPARAM(IDC_VIRTUALKEY, LBN_SELCHANGE), (LPARAM)::GetDlgItem(m_hWnd, IDC_VIRTUALKEY)); + SetForegroundWindow(GetParent()); + ::DestroyWindow(hKeyDlg); + } + continue; + } + if (!::IsDialogMessage(hKeyDlg, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + if (!::IsWindow(hKeyDlg)) { fDone = true; } + } + ::SetFocus(GetParent()); + ::EnableWindow(GetParent(), true); +} + +void COptionsShortCutsPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void COptionsShortCutsPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void COptionsShortCutsPage::ApplySettings(bool /*UpdateScreen*/) +{ + m_ShortCuts.Save(); + g_Settings->SaveBool(Info_ShortCutsChanged, true); +} + +bool COptionsShortCutsPage::EnableReset(void) +{ + return m_EnableReset; +} + +void COptionsShortCutsPage::ResetPage() +{ + m_EnableReset = false; + m_ShortCuts.Load(true); + OnCpuStateChanged(LBN_SELCHANGE, IDC_C_CPU_STATE, GetDlgItem(IDC_C_CPU_STATE)); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); + m_CurrentKeys.ResetContent(); + CSettingsPageImpl::ResetPage(); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-KeyboardShortcuts.h b/Source/Project64/UserInterface/Settings/SettingsPage-KeyboardShortcuts.h index efe129cbf..4fc59ddf4 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-KeyboardShortcuts.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-KeyboardShortcuts.h @@ -1,67 +1,67 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class COptionsShortCutsPage : - public CSettingsPageImpl, - public CSettingsPage -{ - typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; - typedef CShortCutItem::SHORTCUT_KEY_LIST SHORTCUT_KEY_LIST; - - BEGIN_MSG_MAP_EX(COptionsShortCutsPage) - COMMAND_HANDLER_EX(IDC_C_CPU_STATE,LBN_SELCHANGE,OnCpuStateChanged); - NOTIFY_HANDLER_EX(IDC_MENU_ITEMS,TVN_SELCHANGED,OnMenuItemChanged); - COMMAND_HANDLER_EX(IDC_REMOVE,BN_CLICKED,OnRemoveClicked) - COMMAND_HANDLER_EX(IDC_KEY_PROMPT,BN_CLICKED,OnDetectKeyClicked) - COMMAND_HANDLER_EX(IDC_ASSIGN,BN_CLICKED,OnAssignClicked) - COMMAND_HANDLER_EX(IDC_CTL,BN_CLICKED,OnShortCutChanged) - COMMAND_HANDLER_EX(IDC_ALT,BN_CLICKED,OnShortCutChanged) - COMMAND_HANDLER_EX(IDC_SHIFT,BN_CLICKED,OnShortCutChanged) - COMMAND_HANDLER_EX(IDC_VIRTUALKEY,LBN_SELCHANGE,OnShortCutChanged) - END_MSG_MAP() - - enum { IDD = IDD_Settings_Accelerator }; - -public: - COptionsShortCutsPage(HWND hParent, const RECT & rcDispay ); - - LanguageStringID PageTitle ( void ) { return TAB_SHORTCUTS; } - void HidePage ( void ); - void ShowPage ( void ); - void ApplySettings ( bool UpdateScreen ); - bool EnableReset ( void ); - void ResetPage ( void ); - -private: - void OnCpuStateChanged ( UINT Code, int id, HWND ctl ); - void OnRemoveClicked ( UINT Code, int id, HWND ctl ); - void OnDetectKeyClicked ( UINT Code, int id, HWND ctl ); - void OnAssignClicked ( UINT Code, int id, HWND ctl ); - void OnShortCutChanged ( UINT Code, int id, HWND ctl ); - LRESULT OnMenuItemChanged ( LPNMHDR lpnmh ); - - void RefreshShortCutOptions ( HTREEITEM hItem ); - void InputGetKeys ( void ); - void CheckResetEnable ( void ); - - static void stInputGetKeys (COptionsShortCutsPage * _this ) - { - _this->InputGetKeys(); - } - - CPartialGroupBox m_CreateNewShortCut; - CComboBox m_CpuState, m_VirtualKeyList; - CShortCuts m_ShortCuts; - CTreeViewCtrl m_MenuItems; - CListBox m_CurrentKeys; - bool m_EnableReset; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class COptionsShortCutsPage : + public CSettingsPageImpl, + public CSettingsPage +{ + typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; + typedef CShortCutItem::SHORTCUT_KEY_LIST SHORTCUT_KEY_LIST; + + BEGIN_MSG_MAP_EX(COptionsShortCutsPage) + COMMAND_HANDLER_EX(IDC_C_CPU_STATE,LBN_SELCHANGE,OnCpuStateChanged); + NOTIFY_HANDLER_EX(IDC_MENU_ITEMS,TVN_SELCHANGED,OnMenuItemChanged); + COMMAND_HANDLER_EX(IDC_REMOVE,BN_CLICKED,OnRemoveClicked) + COMMAND_HANDLER_EX(IDC_KEY_PROMPT,BN_CLICKED,OnDetectKeyClicked) + COMMAND_HANDLER_EX(IDC_ASSIGN,BN_CLICKED,OnAssignClicked) + COMMAND_HANDLER_EX(IDC_CTL,BN_CLICKED,OnShortCutChanged) + COMMAND_HANDLER_EX(IDC_ALT,BN_CLICKED,OnShortCutChanged) + COMMAND_HANDLER_EX(IDC_SHIFT,BN_CLICKED,OnShortCutChanged) + COMMAND_HANDLER_EX(IDC_VIRTUALKEY,LBN_SELCHANGE,OnShortCutChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_Accelerator }; + +public: + COptionsShortCutsPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_SHORTCUTS; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: + void OnCpuStateChanged ( UINT Code, int id, HWND ctl ); + void OnRemoveClicked ( UINT Code, int id, HWND ctl ); + void OnDetectKeyClicked ( UINT Code, int id, HWND ctl ); + void OnAssignClicked ( UINT Code, int id, HWND ctl ); + void OnShortCutChanged ( UINT Code, int id, HWND ctl ); + LRESULT OnMenuItemChanged ( LPNMHDR lpnmh ); + + void RefreshShortCutOptions ( HTREEITEM hItem ); + void InputGetKeys ( void ); + void CheckResetEnable ( void ); + + static void stInputGetKeys (COptionsShortCutsPage * _this ) + { + _this->InputGetKeys(); + } + + CPartialGroupBox m_CreateNewShortCut; + CComboBox m_CpuState, m_VirtualKeyList; + CShortCuts m_ShortCuts; + CTreeViewCtrl m_MenuItems; + CListBox m_CurrentKeys; + bool m_EnableReset; +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Options.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-Options.cpp index e0f41f9bd..2df2fd0cc 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Options.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Options.cpp @@ -1,78 +1,78 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" - -CGeneralOptionsPage::CGeneralOptionsPage(CSettingConfig * SettingsConfig, HWND hParent, const RECT & rcDispay) : -m_SettingsConfig(SettingsConfig) -{ - if (!Create(hParent, rcDispay)) - { - return; - } - - //Set the text for all gui Items - SetDlgItemTextW(m_hWnd, IDC_AUTOSLEEP, wGS(OPTION_AUTO_SLEEP).c_str()); - SetDlgItemTextW(m_hWnd, IDC_LOAD_FULLSCREEN, wGS(OPTION_AUTO_FULLSCREEN).c_str()); - SetDlgItemTextW(m_hWnd, IDC_SCREEN_SAVER, wGS(OPTION_DISABLE_SS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_BASIC_MODE, wGS(OPTION_BASIC_MODE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_MAXROMS_TXT, wGS(RB_MAX_ROMS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT2, wGS(RB_ROMS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_MAXROMDIR_TXT, wGS(RB_MAX_DIRS).c_str()); - SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT4, wGS(RB_DIRS).c_str()); - - AddModCheckBox(GetDlgItem(IDC_AUTOSLEEP), Setting_AutoSleep); - AddModCheckBox(GetDlgItem(IDC_LOAD_FULLSCREEN), Setting_AutoFullscreen); - AddModCheckBox(GetDlgItem(IDC_SCREEN_SAVER), Setting_DisableScrSaver); - AddModCheckBox(GetDlgItem(IDC_BASIC_MODE), UserInterface_BasicMode); - - CModifiedEditBox * TxtBox = AddModTextBox(GetDlgItem(IDC_REMEMBER), File_RecentGameFileCount, false); - TxtBox->SetTextField(GetDlgItem(IDC_MAXROMS_TXT)); - - TxtBox = AddModTextBox(GetDlgItem(IDC_REMEMBERDIR), Directory_RecentGameDirCount, false); - TxtBox->SetTextField(GetDlgItem(IDC_MAXROMDIR_TXT)); - - UpdatePageSettings(); -} - -void CGeneralOptionsPage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void CGeneralOptionsPage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void CGeneralOptionsPage::ApplySettings(bool UpdateScreen) -{ - CSettingsPageImpl::ApplySettings(UpdateScreen); -} - -bool CGeneralOptionsPage::EnableReset(void) -{ - if (CSettingsPageImpl::EnableReset()) { return true; } - return false; -} - -void CGeneralOptionsPage::ResetPage() -{ - CSettingsPageImpl::ResetPage(); - m_SettingsConfig->UpdateAdvanced((int)::SendMessage(GetDlgItem(IDC_BASIC_MODE), BM_GETCHECK, 0, 0) == 0); -} - -void CGeneralOptionsPage::OnBasicMode(UINT Code, int id, HWND ctl) -{ - CheckBoxChanged(Code, id, ctl); - m_SettingsConfig->UpdateAdvanced((int)::SendMessage(ctl, BM_GETCHECK, 0, 0) == 0); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" + +CGeneralOptionsPage::CGeneralOptionsPage(CSettingConfig * SettingsConfig, HWND hParent, const RECT & rcDispay) : +m_SettingsConfig(SettingsConfig) +{ + if (!Create(hParent, rcDispay)) + { + return; + } + + //Set the text for all gui Items + SetDlgItemTextW(m_hWnd, IDC_AUTOSLEEP, wGS(OPTION_AUTO_SLEEP).c_str()); + SetDlgItemTextW(m_hWnd, IDC_LOAD_FULLSCREEN, wGS(OPTION_AUTO_FULLSCREEN).c_str()); + SetDlgItemTextW(m_hWnd, IDC_SCREEN_SAVER, wGS(OPTION_DISABLE_SS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_BASIC_MODE, wGS(OPTION_BASIC_MODE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_MAXROMS_TXT, wGS(RB_MAX_ROMS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT2, wGS(RB_ROMS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_MAXROMDIR_TXT, wGS(RB_MAX_DIRS).c_str()); + SetDlgItemTextW(m_hWnd, IDC_ROMSEL_TEXT4, wGS(RB_DIRS).c_str()); + + AddModCheckBox(GetDlgItem(IDC_AUTOSLEEP), Setting_AutoSleep); + AddModCheckBox(GetDlgItem(IDC_LOAD_FULLSCREEN), Setting_AutoFullscreen); + AddModCheckBox(GetDlgItem(IDC_SCREEN_SAVER), Setting_DisableScrSaver); + AddModCheckBox(GetDlgItem(IDC_BASIC_MODE), UserInterface_BasicMode); + + CModifiedEditBox * TxtBox = AddModTextBox(GetDlgItem(IDC_REMEMBER), File_RecentGameFileCount, false); + TxtBox->SetTextField(GetDlgItem(IDC_MAXROMS_TXT)); + + TxtBox = AddModTextBox(GetDlgItem(IDC_REMEMBERDIR), Directory_RecentGameDirCount, false); + TxtBox->SetTextField(GetDlgItem(IDC_MAXROMDIR_TXT)); + + UpdatePageSettings(); +} + +void CGeneralOptionsPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void CGeneralOptionsPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void CGeneralOptionsPage::ApplySettings(bool UpdateScreen) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CGeneralOptionsPage::EnableReset(void) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CGeneralOptionsPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); + m_SettingsConfig->UpdateAdvanced((int)::SendMessage(GetDlgItem(IDC_BASIC_MODE), BM_GETCHECK, 0, 0) == 0); +} + +void CGeneralOptionsPage::OnBasicMode(UINT Code, int id, HWND ctl) +{ + CheckBoxChanged(Code, id, ctl); + m_SettingsConfig->UpdateAdvanced((int)::SendMessage(ctl, BM_GETCHECK, 0, 0) == 0); } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Options.h b/Source/Project64/UserInterface/Settings/SettingsPage-Options.h index 00240541d..436cc5631 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Options.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Options.h @@ -1,42 +1,42 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -class CGeneralOptionsPage : - public CSettingsPageImpl, - public CSettingsPage -{ - - BEGIN_MSG_MAP_EX(CGeneralOptionsPage) - COMMAND_ID_HANDLER_EX(IDC_AUTOSLEEP,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_LOAD_FULLSCREEN,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_SCREEN_SAVER,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_BASIC_MODE,OnBasicMode) - COMMAND_HANDLER_EX(IDC_REMEMBER,EN_UPDATE,EditBoxChanged) - COMMAND_HANDLER_EX(IDC_REMEMBERDIR,EN_UPDATE,EditBoxChanged) - END_MSG_MAP() - - enum { IDD = IDD_Settings_General }; - -public: - CGeneralOptionsPage(CSettingConfig * SettingsConfig, HWND hParent, const RECT & rcDispay ); - - LanguageStringID PageTitle ( void ) { return TAB_OPTIONS; } - void HidePage ( void ); - void ShowPage ( void ); - void ApplySettings ( bool UpdateScreen ); - bool EnableReset ( void ); - void ResetPage ( void ); - -private: - void OnBasicMode ( UINT Code, int id, HWND ctl ); - CSettingConfig * m_SettingsConfig; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +class CGeneralOptionsPage : + public CSettingsPageImpl, + public CSettingsPage +{ + + BEGIN_MSG_MAP_EX(CGeneralOptionsPage) + COMMAND_ID_HANDLER_EX(IDC_AUTOSLEEP,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_LOAD_FULLSCREEN,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SCREEN_SAVER,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_BASIC_MODE,OnBasicMode) + COMMAND_HANDLER_EX(IDC_REMEMBER,EN_UPDATE,EditBoxChanged) + COMMAND_HANDLER_EX(IDC_REMEMBERDIR,EN_UPDATE,EditBoxChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_General }; + +public: + CGeneralOptionsPage(CSettingConfig * SettingsConfig, HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_OPTIONS; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: + void OnBasicMode ( UINT Code, int id, HWND ctl ); + CSettingConfig * m_SettingsConfig; +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.cpp index fcd661b2f..c6697dd52 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.cpp @@ -1,334 +1,334 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" - -COptionPluginPage::COptionPluginPage(HWND hParent, const RECT & rcDispay) -{ - if (!Create(hParent, rcDispay)) - { - return; - } - - //Set the text for all gui Items - SetDlgItemTextW(m_hWnd, RSP_ABOUT, wGS(PLUG_ABOUT).c_str()); - SetDlgItemTextW(m_hWnd, GFX_ABOUT, wGS(PLUG_ABOUT).c_str()); - SetDlgItemTextW(m_hWnd, AUDIO_ABOUT, wGS(PLUG_ABOUT).c_str()); - SetDlgItemTextW(m_hWnd, CONT_ABOUT, wGS(PLUG_ABOUT).c_str()); - - SetDlgItemTextW(m_hWnd, IDC_RSP_NAME, wGS(PLUG_RSP).c_str()); - SetDlgItemTextW(m_hWnd, IDC_GFX_NAME, wGS(PLUG_GFX).c_str()); - SetDlgItemTextW(m_hWnd, IDC_AUDIO_NAME, wGS(PLUG_AUDIO).c_str()); - SetDlgItemTextW(m_hWnd, IDC_CONT_NAME, wGS(PLUG_CTRL).c_str()); - - SetDlgItemTextW(m_hWnd, IDC_HLE_GFX, wGS(PLUG_HLE_GFX).c_str()); - SetDlgItemTextW(m_hWnd, IDC_HLE_AUDIO, wGS(PLUG_HLE_AUDIO).c_str()); - - m_GfxGroup.Attach(GetDlgItem(IDC_GFX_NAME)); - m_AudioGroup.Attach(GetDlgItem(IDC_AUDIO_NAME)); - m_ControlGroup.Attach(GetDlgItem(IDC_CONT_NAME)); - m_RspGroup.Attach(GetDlgItem(IDC_RSP_NAME)); - - AddPlugins(GFX_LIST, Plugin_GFX_Current, PLUGIN_TYPE_GFX); - AddPlugins(AUDIO_LIST, Plugin_AUDIO_Current, PLUGIN_TYPE_AUDIO); - AddPlugins(CONT_LIST, Plugin_CONT_Current, PLUGIN_TYPE_CONTROLLER); - AddPlugins(RSP_LIST, Plugin_RSP_Current, PLUGIN_TYPE_RSP); - - AddModCheckBox(GetDlgItem(IDC_HLE_GFX), Plugin_UseHleGfx); - AddModCheckBox(GetDlgItem(IDC_HLE_AUDIO), Plugin_UseHleAudio); - - UpdatePageSettings(); -} - -void COptionPluginPage::AddPlugins(int ListId, SettingID Type, PLUGIN_TYPE PluginType) -{ - stdstr Default = g_Settings->LoadStringVal(Type); - - CModifiedComboBox * ComboBox; - ComboBox = AddModComboBox(GetDlgItem(ListId), Type); - for (int i = 0, n = m_PluginList.GetPluginCount(); i < n; i++) - { - const CPluginList::PLUGIN * Plugin = m_PluginList.GetPluginInfo(i); - if (Plugin == NULL) - { - continue; - } - if (Plugin->Info.Type != PluginType) - { - continue; - } - if (_stricmp(Default.c_str(), Plugin->FileName.c_str()) == 0) - { - ComboBox->SetDefault((WPARAM)Plugin); - } - ComboBox->AddItem(Plugin->Info.Name, (WPARAM)Plugin); - } -} - -void COptionPluginPage::ShowAboutButton(int id) -{ - CModifiedComboBox * ComboBox = NULL; - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter++) - { - if ((int)(cb_iter->second->GetMenu()) != id) - { - continue; - } - ComboBox = cb_iter->second; - break; - } - if (ComboBox == NULL) - { - return; - } - int index = ComboBox->GetCurSel(); - if (index == CB_ERR) - { - return; - } - - const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox->GetItemDataPtr(index); - if (PluginPtr == NULL) - { - return; - } - - const CPluginList::PLUGIN * Plugin = *PluginPtr; - if (Plugin == NULL) - { - return; - } - - //Load the plugin - UINT LastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); - HMODULE hLib = LoadLibrary(Plugin->FullPath); - SetErrorMode(LastErrorMode); - if (hLib == NULL) - { - return; - } - - //Get DLL about - void(CALL *DllAbout) (HWND hWnd); - DllAbout = (void(CALL *)(HWND))GetProcAddress(hLib, "DllAbout"); - - //call the function from the dll - DllAbout(m_hWnd); - - FreeLibrary(hLib); -} - -void COptionPluginPage::PluginItemChanged(int id, int AboutID, bool bSetChanged) -{ - CModifiedComboBox * ComboBox = NULL; - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter++) - { - if ((int)(cb_iter->second->GetMenu()) != id) - { - continue; - } - ComboBox = cb_iter->second; - break; - } - if (ComboBox == NULL) - { - return; - } - - int index = ComboBox->GetCurSel(); - if (index == CB_ERR) - { - return; - } - const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox->GetItemDataPtr(index); - if (PluginPtr) - { - const CPluginList::PLUGIN * Plugin = *PluginPtr; - if (Plugin) - { - ::EnableWindow(GetDlgItem(AboutID), Plugin->AboutFunction); - } - } - - if (bSetChanged) - { - ComboBox->SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); - } -} - -void COptionPluginPage::UpdatePageSettings(void) -{ - UpdateCheckBoxes(); - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter++) - { - CModifiedComboBox * ComboBox = cb_iter->second; - stdstr SelectedValue; - - ComboBox->SetChanged(g_Settings->LoadStringVal(cb_iter->first, SelectedValue)); - for (int i = 0, n = ComboBox->GetCount(); i < n; i++) - { - const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox->GetItemDataPtr(i); - if (PluginPtr == NULL) - { - continue; - } - const CPluginList::PLUGIN * Plugin = *PluginPtr; - if (Plugin == NULL) - { - continue; - } - if (_stricmp(SelectedValue.c_str(), Plugin->FileName.c_str()) != 0) - { - continue; - } - ComboBox->SetDefault((WPARAM)Plugin); - } - } - PluginItemChanged(GFX_LIST, GFX_ABOUT, false); - PluginItemChanged(AUDIO_LIST, AUDIO_ABOUT, false); - PluginItemChanged(CONT_LIST, CONT_ABOUT, false); - PluginItemChanged(RSP_LIST, RSP_ABOUT, false); -} - -void COptionPluginPage::HidePage() -{ - ShowWindow(SW_HIDE); -} - -void COptionPluginPage::ShowPage() -{ - ShowWindow(SW_SHOW); -} - -void COptionPluginPage::ApplySettings(bool UpdateScreen) -{ - CSettingsPageImpl::ApplySettings(UpdateScreen); -} - -bool COptionPluginPage::EnableReset(void) -{ - if (CSettingsPageImpl::EnableReset()) { return true; } - return false; -} - -void COptionPluginPage::ResetPage() -{ - CSettingsPageImpl::ResetPage(); -} - -void COptionPluginPage::ApplyComboBoxes(void) -{ - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter++) - { - CModifiedComboBox * ComboBox = cb_iter->second; - if (ComboBox->IsChanged()) - { - int index = ComboBox->GetCurSel(); - if (index == CB_ERR) - { - return; - } - - const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox->GetItemDataPtr(index); - if (PluginPtr == NULL) - { - return; - } - - const CPluginList::PLUGIN * Plugin = *PluginPtr; - - g_Settings->SaveString(cb_iter->first, Plugin->FileName.c_str()); - } - if (ComboBox->IsReset()) - { - g_Settings->DeleteSetting(cb_iter->first); - ComboBox->SetReset(false); - } - } -} - -bool COptionPluginPage::ResetComboBox(CModifiedComboBox & ComboBox, SettingID Type) -{ - if (!ComboBox.IsChanged()) - { - return false; - } - - ComboBox.SetReset(true); - stdstr Value = g_Settings->LoadDefaultString(Type); - for (int i = 0, n = ComboBox.GetCount(); i < n; i++) - { - const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox.GetItemDataPtr(i); - if (PluginPtr == NULL) - { - continue; - } - - const CPluginList::PLUGIN * Plugin = *PluginPtr; - if (Plugin->FileName != Value) - { - continue; - } - ComboBox.SetCurSel(i); - return true; - } - return false; -} - -void COptionPluginPage::HleGfxChanged(UINT /*Code*/, int id, HWND /*ctl*/) -{ - for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter++) - { - CModifiedButton * Button = iter->second; - if ((int)Button->GetMenu() != id) - { - continue; - } - if ((Button->GetCheck() & BST_CHECKED) == 0) - { - int res = MessageBoxW(m_hWnd, wGS(MSG_SET_LLE_GFX_MSG).c_str(), wGS(MSG_SET_LLE_GFX_TITLE).c_str(), MB_YESNO | MB_ICONWARNING); - if (res != IDYES) - { - Button->SetCheck(BST_CHECKED); - return; - } - } - Button->SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); - break; - } -} - -void COptionPluginPage::HleAudioChanged(UINT /*Code*/, int id, HWND /*ctl*/) -{ - for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter++) - { - CModifiedButton * Button = iter->second; - if ((int)Button->GetMenu() != id) - { - continue; - } - if ((Button->GetCheck() & BST_CHECKED) != 0) - { - int res = MessageBoxW(m_hWnd, wGS(MSG_SET_HLE_AUD_MSG).c_str(), wGS(MSG_SET_HLE_AUD_TITLE).c_str(), MB_ICONWARNING | MB_YESNO); - if (res != IDYES) - { - Button->SetCheck(BST_UNCHECKED); - return; - } - } - Button->SetChanged(true); - SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); - break; - } +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" + +COptionPluginPage::COptionPluginPage(HWND hParent, const RECT & rcDispay) +{ + if (!Create(hParent, rcDispay)) + { + return; + } + + //Set the text for all gui Items + SetDlgItemTextW(m_hWnd, RSP_ABOUT, wGS(PLUG_ABOUT).c_str()); + SetDlgItemTextW(m_hWnd, GFX_ABOUT, wGS(PLUG_ABOUT).c_str()); + SetDlgItemTextW(m_hWnd, AUDIO_ABOUT, wGS(PLUG_ABOUT).c_str()); + SetDlgItemTextW(m_hWnd, CONT_ABOUT, wGS(PLUG_ABOUT).c_str()); + + SetDlgItemTextW(m_hWnd, IDC_RSP_NAME, wGS(PLUG_RSP).c_str()); + SetDlgItemTextW(m_hWnd, IDC_GFX_NAME, wGS(PLUG_GFX).c_str()); + SetDlgItemTextW(m_hWnd, IDC_AUDIO_NAME, wGS(PLUG_AUDIO).c_str()); + SetDlgItemTextW(m_hWnd, IDC_CONT_NAME, wGS(PLUG_CTRL).c_str()); + + SetDlgItemTextW(m_hWnd, IDC_HLE_GFX, wGS(PLUG_HLE_GFX).c_str()); + SetDlgItemTextW(m_hWnd, IDC_HLE_AUDIO, wGS(PLUG_HLE_AUDIO).c_str()); + + m_GfxGroup.Attach(GetDlgItem(IDC_GFX_NAME)); + m_AudioGroup.Attach(GetDlgItem(IDC_AUDIO_NAME)); + m_ControlGroup.Attach(GetDlgItem(IDC_CONT_NAME)); + m_RspGroup.Attach(GetDlgItem(IDC_RSP_NAME)); + + AddPlugins(GFX_LIST, Plugin_GFX_Current, PLUGIN_TYPE_GFX); + AddPlugins(AUDIO_LIST, Plugin_AUDIO_Current, PLUGIN_TYPE_AUDIO); + AddPlugins(CONT_LIST, Plugin_CONT_Current, PLUGIN_TYPE_CONTROLLER); + AddPlugins(RSP_LIST, Plugin_RSP_Current, PLUGIN_TYPE_RSP); + + AddModCheckBox(GetDlgItem(IDC_HLE_GFX), Plugin_UseHleGfx); + AddModCheckBox(GetDlgItem(IDC_HLE_AUDIO), Plugin_UseHleAudio); + + UpdatePageSettings(); +} + +void COptionPluginPage::AddPlugins(int ListId, SettingID Type, PLUGIN_TYPE PluginType) +{ + stdstr Default = g_Settings->LoadStringVal(Type); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(ListId), Type); + for (int i = 0, n = m_PluginList.GetPluginCount(); i < n; i++) + { + const CPluginList::PLUGIN * Plugin = m_PluginList.GetPluginInfo(i); + if (Plugin == NULL) + { + continue; + } + if (Plugin->Info.Type != PluginType) + { + continue; + } + if (_stricmp(Default.c_str(), Plugin->FileName.c_str()) == 0) + { + ComboBox->SetDefault((WPARAM)Plugin); + } + ComboBox->AddItem(Plugin->Info.Name, (WPARAM)Plugin); + } +} + +void COptionPluginPage::ShowAboutButton(int id) +{ + CModifiedComboBox * ComboBox = NULL; + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter++) + { + if ((int)(cb_iter->second->GetMenu()) != id) + { + continue; + } + ComboBox = cb_iter->second; + break; + } + if (ComboBox == NULL) + { + return; + } + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + + const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox->GetItemDataPtr(index); + if (PluginPtr == NULL) + { + return; + } + + const CPluginList::PLUGIN * Plugin = *PluginPtr; + if (Plugin == NULL) + { + return; + } + + //Load the plugin + UINT LastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); + HMODULE hLib = LoadLibrary(Plugin->FullPath); + SetErrorMode(LastErrorMode); + if (hLib == NULL) + { + return; + } + + //Get DLL about + void(CALL *DllAbout) (HWND hWnd); + DllAbout = (void(CALL *)(HWND))GetProcAddress(hLib, "DllAbout"); + + //call the function from the dll + DllAbout(m_hWnd); + + FreeLibrary(hLib); +} + +void COptionPluginPage::PluginItemChanged(int id, int AboutID, bool bSetChanged) +{ + CModifiedComboBox * ComboBox = NULL; + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter++) + { + if ((int)(cb_iter->second->GetMenu()) != id) + { + continue; + } + ComboBox = cb_iter->second; + break; + } + if (ComboBox == NULL) + { + return; + } + + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox->GetItemDataPtr(index); + if (PluginPtr) + { + const CPluginList::PLUGIN * Plugin = *PluginPtr; + if (Plugin) + { + ::EnableWindow(GetDlgItem(AboutID), Plugin->AboutFunction); + } + } + + if (bSetChanged) + { + ComboBox->SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); + } +} + +void COptionPluginPage::UpdatePageSettings(void) +{ + UpdateCheckBoxes(); + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + stdstr SelectedValue; + + ComboBox->SetChanged(g_Settings->LoadStringVal(cb_iter->first, SelectedValue)); + for (int i = 0, n = ComboBox->GetCount(); i < n; i++) + { + const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox->GetItemDataPtr(i); + if (PluginPtr == NULL) + { + continue; + } + const CPluginList::PLUGIN * Plugin = *PluginPtr; + if (Plugin == NULL) + { + continue; + } + if (_stricmp(SelectedValue.c_str(), Plugin->FileName.c_str()) != 0) + { + continue; + } + ComboBox->SetDefault((WPARAM)Plugin); + } + } + PluginItemChanged(GFX_LIST, GFX_ABOUT, false); + PluginItemChanged(AUDIO_LIST, AUDIO_ABOUT, false); + PluginItemChanged(CONT_LIST, CONT_ABOUT, false); + PluginItemChanged(RSP_LIST, RSP_ABOUT, false); +} + +void COptionPluginPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void COptionPluginPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void COptionPluginPage::ApplySettings(bool UpdateScreen) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool COptionPluginPage::EnableReset(void) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void COptionPluginPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); +} + +void COptionPluginPage::ApplyComboBoxes(void) +{ + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if (ComboBox->IsChanged()) + { + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + + const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox->GetItemDataPtr(index); + if (PluginPtr == NULL) + { + return; + } + + const CPluginList::PLUGIN * Plugin = *PluginPtr; + + g_Settings->SaveString(cb_iter->first, Plugin->FileName.c_str()); + } + if (ComboBox->IsReset()) + { + g_Settings->DeleteSetting(cb_iter->first); + ComboBox->SetReset(false); + } + } +} + +bool COptionPluginPage::ResetComboBox(CModifiedComboBox & ComboBox, SettingID Type) +{ + if (!ComboBox.IsChanged()) + { + return false; + } + + ComboBox.SetReset(true); + stdstr Value = g_Settings->LoadDefaultString(Type); + for (int i = 0, n = ComboBox.GetCount(); i < n; i++) + { + const CPluginList::PLUGIN ** PluginPtr = (const CPluginList::PLUGIN **)ComboBox.GetItemDataPtr(i); + if (PluginPtr == NULL) + { + continue; + } + + const CPluginList::PLUGIN * Plugin = *PluginPtr; + if (Plugin->FileName != Value) + { + continue; + } + ComboBox.SetCurSel(i); + return true; + } + return false; +} + +void COptionPluginPage::HleGfxChanged(UINT /*Code*/, int id, HWND /*ctl*/) +{ + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter++) + { + CModifiedButton * Button = iter->second; + if ((int)Button->GetMenu() != id) + { + continue; + } + if ((Button->GetCheck() & BST_CHECKED) == 0) + { + int res = MessageBoxW(m_hWnd, wGS(MSG_SET_LLE_GFX_MSG).c_str(), wGS(MSG_SET_LLE_GFX_TITLE).c_str(), MB_YESNO | MB_ICONWARNING); + if (res != IDYES) + { + Button->SetCheck(BST_CHECKED); + return; + } + } + Button->SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); + break; + } +} + +void COptionPluginPage::HleAudioChanged(UINT /*Code*/, int id, HWND /*ctl*/) +{ + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter++) + { + CModifiedButton * Button = iter->second; + if ((int)Button->GetMenu() != id) + { + continue; + } + if ((Button->GetCheck() & BST_CHECKED) != 0) + { + int res = MessageBoxW(m_hWnd, wGS(MSG_SET_HLE_AUD_MSG).c_str(), wGS(MSG_SET_HLE_AUD_TITLE).c_str(), MB_ICONWARNING | MB_YESNO); + if (res != IDYES) + { + Button->SetCheck(BST_UNCHECKED); + return; + } + } + Button->SetChanged(true); + SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); + break; + } } \ No newline at end of file diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.h b/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.h index f9f3314a2..e234f360f 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.h @@ -1,68 +1,68 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class COptionPluginPage : - public CSettingsPageImpl, - public CSettingsPage -{ - BEGIN_MSG_MAP_EX(COptionPluginPage) - COMMAND_HANDLER_EX(GFX_LIST, LBN_SELCHANGE, GfxPluginChanged) - COMMAND_HANDLER_EX(AUDIO_LIST, LBN_SELCHANGE, AudioPluginChanged) - COMMAND_HANDLER_EX(CONT_LIST, LBN_SELCHANGE, ControllerPluginChanged) - COMMAND_HANDLER_EX(RSP_LIST, LBN_SELCHANGE, RspPluginChanged) - COMMAND_ID_HANDLER_EX(GFX_ABOUT, GfxPluginAbout) - COMMAND_ID_HANDLER_EX(AUDIO_ABOUT, AudioPluginAbout) - COMMAND_ID_HANDLER_EX(CONT_ABOUT, ControllerPluginAbout) - COMMAND_ID_HANDLER_EX(RSP_ABOUT, RspPluginAbout) - COMMAND_ID_HANDLER_EX(IDC_HLE_GFX, HleGfxChanged) - COMMAND_ID_HANDLER_EX(IDC_HLE_AUDIO, HleAudioChanged) - END_MSG_MAP() - - enum { IDD = IDD_Settings_PlugSel }; - -public: - COptionPluginPage(HWND hParent, const RECT & rcDispay); - - LanguageStringID PageTitle(void) { return TAB_PLUGIN; } - void HidePage(void); - void ShowPage(void); - void ApplySettings(bool UpdateScreen); - bool EnableReset(void); - void ResetPage(void); - -private: - void GfxPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(GFX_LIST); } - void AudioPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(AUDIO_LIST); } - void ControllerPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(CONT_LIST); } - void RspPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(RSP_LIST); } - - void GfxPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(GFX_LIST, GFX_ABOUT); } - void AudioPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(AUDIO_LIST, AUDIO_ABOUT); } - void ControllerPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(CONT_LIST, CONT_ABOUT); } - void RspPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(RSP_LIST, RSP_ABOUT); } - - void HleGfxChanged(UINT Code, int id, HWND ctl); - void HleAudioChanged(UINT Code, int id, HWND ctl); - - void ShowAboutButton(int id); - void PluginItemChanged(int id, int AboutID, bool bSetChanged = true); - - void AddPlugins(int ListId, SettingID Type, PLUGIN_TYPE PluginType); - void UpdatePageSettings(void); - void ApplyComboBoxes(void); - bool ResetComboBox(CModifiedComboBox & ComboBox, SettingID Type); - - CPartialGroupBox m_GfxGroup, m_AudioGroup, m_ControlGroup, m_RspGroup; - CPluginList m_PluginList; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class COptionPluginPage : + public CSettingsPageImpl, + public CSettingsPage +{ + BEGIN_MSG_MAP_EX(COptionPluginPage) + COMMAND_HANDLER_EX(GFX_LIST, LBN_SELCHANGE, GfxPluginChanged) + COMMAND_HANDLER_EX(AUDIO_LIST, LBN_SELCHANGE, AudioPluginChanged) + COMMAND_HANDLER_EX(CONT_LIST, LBN_SELCHANGE, ControllerPluginChanged) + COMMAND_HANDLER_EX(RSP_LIST, LBN_SELCHANGE, RspPluginChanged) + COMMAND_ID_HANDLER_EX(GFX_ABOUT, GfxPluginAbout) + COMMAND_ID_HANDLER_EX(AUDIO_ABOUT, AudioPluginAbout) + COMMAND_ID_HANDLER_EX(CONT_ABOUT, ControllerPluginAbout) + COMMAND_ID_HANDLER_EX(RSP_ABOUT, RspPluginAbout) + COMMAND_ID_HANDLER_EX(IDC_HLE_GFX, HleGfxChanged) + COMMAND_ID_HANDLER_EX(IDC_HLE_AUDIO, HleAudioChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_PlugSel }; + +public: + COptionPluginPage(HWND hParent, const RECT & rcDispay); + + LanguageStringID PageTitle(void) { return TAB_PLUGIN; } + void HidePage(void); + void ShowPage(void); + void ApplySettings(bool UpdateScreen); + bool EnableReset(void); + void ResetPage(void); + +private: + void GfxPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(GFX_LIST); } + void AudioPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(AUDIO_LIST); } + void ControllerPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(CONT_LIST); } + void RspPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(RSP_LIST); } + + void GfxPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(GFX_LIST, GFX_ABOUT); } + void AudioPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(AUDIO_LIST, AUDIO_ABOUT); } + void ControllerPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(CONT_LIST, CONT_ABOUT); } + void RspPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(RSP_LIST, RSP_ABOUT); } + + void HleGfxChanged(UINT Code, int id, HWND ctl); + void HleAudioChanged(UINT Code, int id, HWND ctl); + + void ShowAboutButton(int id); + void PluginItemChanged(int id, int AboutID, bool bSetChanged = true); + + void AddPlugins(int ListId, SettingID Type, PLUGIN_TYPE PluginType); + void UpdatePageSettings(void); + void ApplyComboBoxes(void); + bool ResetComboBox(CModifiedComboBox & ComboBox, SettingID Type); + + CPartialGroupBox m_GfxGroup, m_AudioGroup, m_ControlGroup, m_RspGroup; + CPluginList m_PluginList; +}; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage.cpp b/Source/Project64/UserInterface/Settings/SettingsPage.cpp index 499f49ab2..f783523d2 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage.cpp @@ -1,42 +1,42 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" - -#include "SettingsPage.h" - -CConfigSettingSection::CConfigSettingSection(LPCWSTR PageTitle) : -m_PageTitle(PageTitle) -{ -} - -CConfigSettingSection::~CConfigSettingSection() -{ - for (size_t i = 0; i < m_Pages.size(); i++) - { - CSettingsPage * Page = m_Pages[i]; - delete Page; - } - m_Pages.clear(); -} - -void CConfigSettingSection::AddPage(CSettingsPage * Page) -{ - m_Pages.push_back(Page); -} - -CSettingsPage * CConfigSettingSection::GetPage(int PageNo) -{ - if (PageNo < 0 || PageNo >= (int)m_Pages.size()) - { - return NULL; - } - return m_Pages[PageNo]; -} +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" + +#include "SettingsPage.h" + +CConfigSettingSection::CConfigSettingSection(LPCWSTR PageTitle) : +m_PageTitle(PageTitle) +{ +} + +CConfigSettingSection::~CConfigSettingSection() +{ + for (size_t i = 0; i < m_Pages.size(); i++) + { + CSettingsPage * Page = m_Pages[i]; + delete Page; + } + m_Pages.clear(); +} + +void CConfigSettingSection::AddPage(CSettingsPage * Page) +{ + m_Pages.push_back(Page); +} + +CSettingsPage * CConfigSettingSection::GetPage(int PageNo) +{ + if (PageNo < 0 || PageNo >= (int)m_Pages.size()) + { + return NULL; + } + return m_Pages[PageNo]; +} diff --git a/Source/Project64/UserInterface/Settings/SettingsPage.h b/Source/Project64/UserInterface/Settings/SettingsPage.h index 578478df2..20c9caa89 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage.h @@ -1,576 +1,576 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once - -#include - -class CSettingsPage -{ -public: - virtual ~CSettingsPage ( void ) = 0 {}; - - virtual LanguageStringID PageTitle ( void ) = 0; - virtual void HidePage ( void ) = 0; - virtual void ShowPage ( void ) = 0; - virtual void ApplySettings ( bool UpdateScreen ) = 0; - virtual bool EnableReset ( void ) = 0; - virtual void ResetPage ( void ) = 0; -}; - -template -class CSettingsPageImpl : - public CDialogImpl -{ -protected: - typedef std::map TextBoxList; - typedef std::map ButtonList; - typedef std::map ComboBoxList; - typedef std::map ComboBoxTxtList; - - virtual ~CSettingsPageImpl() - { - for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) - { - delete eb_iter->second; - } - for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) - { - delete iter->second; - } - for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) - { - delete cbtxt_iter->second; - } - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) - { - delete cb_iter->second; - } - - } - bool Create(HWND hParent, const RECT & rcDispay) - { - BOOL result = m_thunk.Init(NULL, NULL); - if (result == FALSE) - { - SetLastError(ERROR_OUTOFMEMORY); - return false; - } - - _AtlWinModule.AddCreateWndData(&m_thunk.cd, this); -#ifdef _DEBUG - m_bModal = false; -#endif //_DEBUG - m_hWnd = ::CreateDialogParamW(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCEW(static_cast(this)->IDD), hParent, T::StartDialogProc, NULL); - if (m_hWnd == NULL) - { - return false; - } - SetWindowPos(HWND_TOP,&rcDispay,SWP_HIDEWINDOW); - m_UpdatingTxt = false; - return true; - } - - void CheckBoxChanged ( UINT /*Code*/, int id, HWND /*ctl*/ ) - { - for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) - { - CModifiedButton * Button = iter->second; - if ((int)Button->GetMenu() != id) - { - continue; - } - Button->SetChanged(true); - SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); - break; - } - } - - void UpdateModEditBox ( CModifiedEditBox & EditBox, SettingID Type ) - { - if (EditBox.IsChanged()) - { - stdstr Value = EditBox.GetWindowText(); - if (EditBox.IsbString()) - { - g_Settings->SaveString(Type,Value); - } else { - DWORD dwValue = atoi(Value.c_str()); - g_Settings->SaveDword(Type,dwValue); - } - } - if (EditBox.IsReset()) - { - g_Settings->DeleteSetting(Type); - EditBox.SetReset(false); - } - } - - - void UpdateModCheckBox ( CModifiedButton & CheckBox, SettingID Type ) - { - if (CheckBox.IsChanged()) - { - bool bValue = CheckBox.GetCheck() == BST_CHECKED; - if (bValue != g_Settings->LoadBool(Type)) - { - g_Settings->SaveBool(Type,bValue); - } - } - if (CheckBox.IsReset()) - { - g_Settings->DeleteSetting(Type); - CheckBox.SetReset(false); - } - } - - bool ResetCheckBox ( CModifiedButton & CheckBox, SettingID Type ) - { - if (!CheckBox.IsChanged()) - { - return false; - } - - bool Value = g_Settings->LoadDefaultBool(Type); - CheckBox.SetReset(true); - CheckBox.SetCheck(Value ? BST_CHECKED : BST_UNCHECKED); - return true; - } - - bool ResetEditBox ( CModifiedEditBox & EditBox, SettingID Type ) - { - if (!EditBox.IsChanged()) - { - return false; - } - - if (EditBox.IsbString()) - { - stdstr Value = g_Settings->LoadDefaultString(Type); - EditBox.SetWindowText(Value.c_str()); - EditBox.SetReset(true); - } else { - DWORD Value = g_Settings->LoadDefaultDword(Type); - EditBox.SetWindowText(stdstr_f("%d",Value).c_str()); - EditBox.SetReset(true); - } - return true; - } - - CModifiedEditBox * AddModTextBox ( HWND hWnd, SettingID Type, bool bString ) - { - TextBoxList::iterator item = m_TxtBoxList.find(Type); - if (item == m_TxtBoxList.end()) - { - CModifiedEditBox * EditBox = new CModifiedEditBox(bString); - if (EditBox == NULL) - { - return NULL; - } - EditBox->Attach(hWnd); - - m_TxtBoxList.insert(TextBoxList::value_type(Type,EditBox)); - return EditBox; - } - return NULL; - } - - void AddModCheckBox ( HWND hWnd, SettingID Type ) - { - ButtonList::iterator item = m_ButtonList.find(Type); - if (item == m_ButtonList.end()) - { - CModifiedButton * Button = new CModifiedButton; - if (Button == NULL) - { - return; - } - Button->Attach(hWnd); - - m_ButtonList.insert(ButtonList::value_type(Type,Button)); - } - } - - CModifiedComboBox * AddModComboBox ( HWND hWnd, SettingID Type ) - { - ComboBoxList::iterator item = m_ComboBoxList.find(Type); - if (item != m_ComboBoxList.end()) - { - return item->second; - } - - CModifiedComboBox * ComboBox = new CModifiedComboBox(g_Settings->LoadDefaultDword(Type),NULL,false); - if (ComboBox == NULL) - { - return NULL; - } - ComboBox->Attach(hWnd); - m_ComboBoxList.insert(ComboBoxList::value_type(Type,ComboBox)); - return ComboBox; - } - - CModifiedComboBoxTxt * AddModComboBoxTxt ( HWND hWnd, SettingID Type ) - { - ComboBoxTxtList::iterator item = m_ComboBoxTxtList.find(Type); - if (item != m_ComboBoxTxtList.end()) - { - return item->second; - } - - CModifiedComboBoxTxt * ComboBox = new CModifiedComboBoxTxt(g_Settings->LoadDefaultString(Type)); - if (ComboBox == NULL) - { - return NULL; - } - ComboBox->Attach(hWnd); - m_ComboBoxTxtList.insert(ComboBoxTxtList::value_type(Type,ComboBox)); - return ComboBox; - } - - void UpdateCheckBoxes ( void ) - { - for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) - { - CModifiedButton * Button = iter->second; - bool SettingSelected; - - Button->SetChanged(g_Settings->LoadBool(iter->first,SettingSelected)); - Button->SetCheck(SettingSelected ? BST_CHECKED : BST_UNCHECKED); - } - - } - - void UpdateComboBoxes ( void) - { - for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) - { - CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; - stdstr SelectedValue; - - ComboBox->SetChanged(g_Settings->LoadStringVal(cbtxt_iter->first,SelectedValue)); - ComboBox->SetDefault(SelectedValue); - } - - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) - { - CModifiedComboBox * ComboBox = cb_iter->second; - uint32_t SelectedValue; - - ComboBox->SetChanged(g_Settings->LoadDword(cb_iter->first,SelectedValue)); - ComboBox->SetDefault(SelectedValue); - } - } - - void UpdateTextBoxes ( void) - { - for (TextBoxList::iterator iter = m_TxtBoxList.begin(); iter != m_TxtBoxList.end(); iter ++) - { - CModifiedEditBox * TextBox = iter->second; - - m_UpdatingTxt = true; - if (TextBox->IsbString()) - { - stdstr SelectedValue; - TextBox->SetChanged(g_Settings->LoadStringVal(iter->first,SelectedValue)); - TextBox->SetWindowText(SelectedValue.c_str()); - } else { - uint32_t SelectedValue; - TextBox->SetChanged(g_Settings->LoadDword(iter->first,SelectedValue)); - TextBox->SetWindowText(stdstr_f("%d",SelectedValue).c_str()); - } - m_UpdatingTxt = false; - } - } - - virtual void UpdatePageSettings ( void ) - { - UpdateCheckBoxes(); - UpdateComboBoxes(); - UpdateTextBoxes(); - } - - void ComboBoxChanged ( UINT /*Code*/, int id, HWND /*ctl*/ ) - { - for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) - { - CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; - if ((int)ComboBox->GetMenu() != id) - { - continue; - } - ComboBox->SetChanged(true); - SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); - break; - } - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) - { - CModifiedComboBox * ComboBox = cb_iter->second; - if ((int)ComboBox->GetMenu() != id) - { - continue; - } - ComboBox->SetChanged(true); - SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); - break; - } - } - - void EditBoxChanged ( UINT /*Code*/, int id, HWND /*ctl*/ ) - { - if (m_UpdatingTxt) - { - return; - } - - for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) - { - CModifiedEditBox * EditBox = eb_iter->second; - if ((int)EditBox->GetMenu() != id) - { - continue; - } - EditBox->SetChanged(true); - SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); - break; - } - } - - virtual bool ResetComboBox ( CModifiedComboBox & ComboBox, SettingID Type ) - { - if (!ComboBox.IsChanged()) - { - return false; - } - - ComboBox.SetReset(true); - DWORD Value = g_Settings->LoadDefaultDword(Type); - for (int i = 0, n = ComboBox.GetCount(); i < n; i++) - { - if (*((WPARAM *)ComboBox.GetItemData(i)) != Value) - { - continue; - } - ComboBox.SetCurSel(i); - return true; - } - return false; - } - - virtual bool ResetComboBoxTxt ( CModifiedComboBoxTxt & ComboBox, SettingID Type ) - { - if (!ComboBox.IsChanged()) - { - return false; - } - - ComboBox.SetReset(true); - stdstr Value = g_Settings->LoadDefaultString(Type); - for (int i = 0, n = ComboBox.GetCount(); i < n; i++) - { - if (*((stdstr *)ComboBox.GetItemData(i)) != Value) - { - continue; - } - ComboBox.SetCurSel(i); - return true; - } - return false; - } - - virtual void UpdateModComboBox ( CModifiedComboBox & ComboBox, SettingID Type ) - { - if (ComboBox.IsChanged()) - { - int index = ComboBox.GetCurSel(); - if (index == CB_ERR) - { - return; - } - g_Settings->SaveDword(Type,*(DWORD *)ComboBox.GetItemData(index)); - } - if (ComboBox.IsReset()) - { - g_Settings->DeleteSetting(Type); - ComboBox.SetReset(false); - } - } - - virtual void UpdateModComboBoxTxt ( CModifiedComboBoxTxt & ComboBox, SettingID Type ) - { - if (ComboBox.IsChanged()) - { - int index = ComboBox.GetCurSel(); - if (index == CB_ERR) - { - return; - } - g_Settings->SaveString(Type,((stdstr *)ComboBox.GetItemData(index))->c_str()); - } - if (ComboBox.IsReset()) - { - g_Settings->DeleteSetting(Type); - ComboBox.SetReset(false); - } - } -public: - virtual void ApplyEditBoxes ( void ) - { - for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) - { - CModifiedEditBox * EditBox = eb_iter->second; - UpdateModEditBox(*EditBox,eb_iter->first); - } - } - virtual void ApplyCheckBoxes ( void ) - { - for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) - { - CModifiedButton * Button = iter->second; - UpdateModCheckBox(*Button,iter->first); - } - } - virtual void ApplyComboBoxes ( void ) - { - for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) - { - CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; - UpdateModComboBoxTxt(*ComboBox,cbtxt_iter->first); - } - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) - { - CModifiedComboBox * ComboBox = cb_iter->second; - UpdateModComboBox(*ComboBox,cb_iter->first); - } - } - void ApplySettings( bool UpdateScreen ) - { - ApplyEditBoxes(); - ApplyCheckBoxes(); - ApplyComboBoxes(); - - if (UpdateScreen) - { - UpdatePageSettings(); - } - } - - bool EnableReset ( void ) - { - for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) - { - CModifiedEditBox * EditBox = eb_iter->second; - if (EditBox->IsChanged()) - { - return true; - } - } - for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) - { - CModifiedButton * Button = iter->second; - if (Button->IsChanged()) - { - return true; - } - } - for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) - { - CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; - if (ComboBox->IsChanged()) - { - return true; - } - } - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) - { - CModifiedComboBox * ComboBox = cb_iter->second; - if (ComboBox->IsChanged()) - { - return true; - } - } - return false; - } - - void ResetPage ( void ) - { - bool Changed = false; - for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) - { - CModifiedEditBox * EditBox = eb_iter->second; - if (ResetEditBox(*EditBox,eb_iter->first)) - { - Changed = true; - } - } - for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) - { - CModifiedButton * Button = iter->second; - if (ResetCheckBox(*Button,iter->first)) - { - Changed = true; - } - } - for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) - { - CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; - if (ResetComboBoxTxt(*ComboBox,cbtxt_iter->first)) - { - Changed = true; - } - } - for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) - { - CModifiedComboBox * ComboBox = cb_iter->second; - if (ResetComboBox(*ComboBox,cb_iter->first)) - { - Changed = true; - } - } - if (Changed) - { - SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); - } - } -protected: - TextBoxList m_TxtBoxList; - ButtonList m_ButtonList; - ComboBoxList m_ComboBoxList; - ComboBoxTxtList m_ComboBoxTxtList; - bool m_UpdatingTxt; -}; - - -typedef std::vector SETTING_PAGES; - -class CConfigSettingSection -{ - SETTING_PAGES m_Pages; - std::wstring m_PageTitle; - -public: - CConfigSettingSection ( LPCWSTR PageTitle ); - ~CConfigSettingSection(); - - LPCWSTR GetPageTitle ( void ) const { return m_PageTitle.c_str(); } - void AddPage ( CSettingsPage * Page ); - size_t GetPageCount ( void ) const { return m_Pages.size(); } - CSettingsPage * GetPage ( int PageNo ); -}; - -#include "SettingsPage-AdvancedOptions.h" -#include "SettingsPage-Directories.h" -#include "SettingsPage-Game-General.h" -#include "SettingsPage-Game-Plugin.h" -#include "SettingsPage-Game-Recompiler.h" -#include "SettingsPage-Game-Status.h" -#include "SettingsPage-GameBrowser.h" -#include "SettingsPage-KeyboardShortcuts.h" -#include "SettingsPage-Options.h" -#include "SettingsPage-Plugin.h" +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#include + +class CSettingsPage +{ +public: + virtual ~CSettingsPage ( void ) = 0 {}; + + virtual LanguageStringID PageTitle ( void ) = 0; + virtual void HidePage ( void ) = 0; + virtual void ShowPage ( void ) = 0; + virtual void ApplySettings ( bool UpdateScreen ) = 0; + virtual bool EnableReset ( void ) = 0; + virtual void ResetPage ( void ) = 0; +}; + +template +class CSettingsPageImpl : + public CDialogImpl +{ +protected: + typedef std::map TextBoxList; + typedef std::map ButtonList; + typedef std::map ComboBoxList; + typedef std::map ComboBoxTxtList; + + virtual ~CSettingsPageImpl() + { + for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) + { + delete eb_iter->second; + } + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + delete iter->second; + } + for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) + { + delete cbtxt_iter->second; + } + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + delete cb_iter->second; + } + + } + bool Create(HWND hParent, const RECT & rcDispay) + { + BOOL result = m_thunk.Init(NULL, NULL); + if (result == FALSE) + { + SetLastError(ERROR_OUTOFMEMORY); + return false; + } + + _AtlWinModule.AddCreateWndData(&m_thunk.cd, this); +#ifdef _DEBUG + m_bModal = false; +#endif //_DEBUG + m_hWnd = ::CreateDialogParamW(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCEW(static_cast(this)->IDD), hParent, T::StartDialogProc, NULL); + if (m_hWnd == NULL) + { + return false; + } + SetWindowPos(HWND_TOP,&rcDispay,SWP_HIDEWINDOW); + m_UpdatingTxt = false; + return true; + } + + void CheckBoxChanged ( UINT /*Code*/, int id, HWND /*ctl*/ ) + { + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if ((int)Button->GetMenu() != id) + { + continue; + } + Button->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } + } + + void UpdateModEditBox ( CModifiedEditBox & EditBox, SettingID Type ) + { + if (EditBox.IsChanged()) + { + stdstr Value = EditBox.GetWindowText(); + if (EditBox.IsbString()) + { + g_Settings->SaveString(Type,Value); + } else { + DWORD dwValue = atoi(Value.c_str()); + g_Settings->SaveDword(Type,dwValue); + } + } + if (EditBox.IsReset()) + { + g_Settings->DeleteSetting(Type); + EditBox.SetReset(false); + } + } + + + void UpdateModCheckBox ( CModifiedButton & CheckBox, SettingID Type ) + { + if (CheckBox.IsChanged()) + { + bool bValue = CheckBox.GetCheck() == BST_CHECKED; + if (bValue != g_Settings->LoadBool(Type)) + { + g_Settings->SaveBool(Type,bValue); + } + } + if (CheckBox.IsReset()) + { + g_Settings->DeleteSetting(Type); + CheckBox.SetReset(false); + } + } + + bool ResetCheckBox ( CModifiedButton & CheckBox, SettingID Type ) + { + if (!CheckBox.IsChanged()) + { + return false; + } + + bool Value = g_Settings->LoadDefaultBool(Type); + CheckBox.SetReset(true); + CheckBox.SetCheck(Value ? BST_CHECKED : BST_UNCHECKED); + return true; + } + + bool ResetEditBox ( CModifiedEditBox & EditBox, SettingID Type ) + { + if (!EditBox.IsChanged()) + { + return false; + } + + if (EditBox.IsbString()) + { + stdstr Value = g_Settings->LoadDefaultString(Type); + EditBox.SetWindowText(Value.c_str()); + EditBox.SetReset(true); + } else { + DWORD Value = g_Settings->LoadDefaultDword(Type); + EditBox.SetWindowText(stdstr_f("%d",Value).c_str()); + EditBox.SetReset(true); + } + return true; + } + + CModifiedEditBox * AddModTextBox ( HWND hWnd, SettingID Type, bool bString ) + { + TextBoxList::iterator item = m_TxtBoxList.find(Type); + if (item == m_TxtBoxList.end()) + { + CModifiedEditBox * EditBox = new CModifiedEditBox(bString); + if (EditBox == NULL) + { + return NULL; + } + EditBox->Attach(hWnd); + + m_TxtBoxList.insert(TextBoxList::value_type(Type,EditBox)); + return EditBox; + } + return NULL; + } + + void AddModCheckBox ( HWND hWnd, SettingID Type ) + { + ButtonList::iterator item = m_ButtonList.find(Type); + if (item == m_ButtonList.end()) + { + CModifiedButton * Button = new CModifiedButton; + if (Button == NULL) + { + return; + } + Button->Attach(hWnd); + + m_ButtonList.insert(ButtonList::value_type(Type,Button)); + } + } + + CModifiedComboBox * AddModComboBox ( HWND hWnd, SettingID Type ) + { + ComboBoxList::iterator item = m_ComboBoxList.find(Type); + if (item != m_ComboBoxList.end()) + { + return item->second; + } + + CModifiedComboBox * ComboBox = new CModifiedComboBox(g_Settings->LoadDefaultDword(Type),NULL,false); + if (ComboBox == NULL) + { + return NULL; + } + ComboBox->Attach(hWnd); + m_ComboBoxList.insert(ComboBoxList::value_type(Type,ComboBox)); + return ComboBox; + } + + CModifiedComboBoxTxt * AddModComboBoxTxt ( HWND hWnd, SettingID Type ) + { + ComboBoxTxtList::iterator item = m_ComboBoxTxtList.find(Type); + if (item != m_ComboBoxTxtList.end()) + { + return item->second; + } + + CModifiedComboBoxTxt * ComboBox = new CModifiedComboBoxTxt(g_Settings->LoadDefaultString(Type)); + if (ComboBox == NULL) + { + return NULL; + } + ComboBox->Attach(hWnd); + m_ComboBoxTxtList.insert(ComboBoxTxtList::value_type(Type,ComboBox)); + return ComboBox; + } + + void UpdateCheckBoxes ( void ) + { + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + bool SettingSelected; + + Button->SetChanged(g_Settings->LoadBool(iter->first,SettingSelected)); + Button->SetCheck(SettingSelected ? BST_CHECKED : BST_UNCHECKED); + } + + } + + void UpdateComboBoxes ( void) + { + for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) + { + CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; + stdstr SelectedValue; + + ComboBox->SetChanged(g_Settings->LoadStringVal(cbtxt_iter->first,SelectedValue)); + ComboBox->SetDefault(SelectedValue); + } + + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + uint32_t SelectedValue; + + ComboBox->SetChanged(g_Settings->LoadDword(cb_iter->first,SelectedValue)); + ComboBox->SetDefault(SelectedValue); + } + } + + void UpdateTextBoxes ( void) + { + for (TextBoxList::iterator iter = m_TxtBoxList.begin(); iter != m_TxtBoxList.end(); iter ++) + { + CModifiedEditBox * TextBox = iter->second; + + m_UpdatingTxt = true; + if (TextBox->IsbString()) + { + stdstr SelectedValue; + TextBox->SetChanged(g_Settings->LoadStringVal(iter->first,SelectedValue)); + TextBox->SetWindowText(SelectedValue.c_str()); + } else { + uint32_t SelectedValue; + TextBox->SetChanged(g_Settings->LoadDword(iter->first,SelectedValue)); + TextBox->SetWindowText(stdstr_f("%d",SelectedValue).c_str()); + } + m_UpdatingTxt = false; + } + } + + virtual void UpdatePageSettings ( void ) + { + UpdateCheckBoxes(); + UpdateComboBoxes(); + UpdateTextBoxes(); + } + + void ComboBoxChanged ( UINT /*Code*/, int id, HWND /*ctl*/ ) + { + for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) + { + CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; + if ((int)ComboBox->GetMenu() != id) + { + continue; + } + ComboBox->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if ((int)ComboBox->GetMenu() != id) + { + continue; + } + ComboBox->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } + } + + void EditBoxChanged ( UINT /*Code*/, int id, HWND /*ctl*/ ) + { + if (m_UpdatingTxt) + { + return; + } + + for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) + { + CModifiedEditBox * EditBox = eb_iter->second; + if ((int)EditBox->GetMenu() != id) + { + continue; + } + EditBox->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } + } + + virtual bool ResetComboBox ( CModifiedComboBox & ComboBox, SettingID Type ) + { + if (!ComboBox.IsChanged()) + { + return false; + } + + ComboBox.SetReset(true); + DWORD Value = g_Settings->LoadDefaultDword(Type); + for (int i = 0, n = ComboBox.GetCount(); i < n; i++) + { + if (*((WPARAM *)ComboBox.GetItemData(i)) != Value) + { + continue; + } + ComboBox.SetCurSel(i); + return true; + } + return false; + } + + virtual bool ResetComboBoxTxt ( CModifiedComboBoxTxt & ComboBox, SettingID Type ) + { + if (!ComboBox.IsChanged()) + { + return false; + } + + ComboBox.SetReset(true); + stdstr Value = g_Settings->LoadDefaultString(Type); + for (int i = 0, n = ComboBox.GetCount(); i < n; i++) + { + if (*((stdstr *)ComboBox.GetItemData(i)) != Value) + { + continue; + } + ComboBox.SetCurSel(i); + return true; + } + return false; + } + + virtual void UpdateModComboBox ( CModifiedComboBox & ComboBox, SettingID Type ) + { + if (ComboBox.IsChanged()) + { + int index = ComboBox.GetCurSel(); + if (index == CB_ERR) + { + return; + } + g_Settings->SaveDword(Type,*(DWORD *)ComboBox.GetItemData(index)); + } + if (ComboBox.IsReset()) + { + g_Settings->DeleteSetting(Type); + ComboBox.SetReset(false); + } + } + + virtual void UpdateModComboBoxTxt ( CModifiedComboBoxTxt & ComboBox, SettingID Type ) + { + if (ComboBox.IsChanged()) + { + int index = ComboBox.GetCurSel(); + if (index == CB_ERR) + { + return; + } + g_Settings->SaveString(Type,((stdstr *)ComboBox.GetItemData(index))->c_str()); + } + if (ComboBox.IsReset()) + { + g_Settings->DeleteSetting(Type); + ComboBox.SetReset(false); + } + } +public: + virtual void ApplyEditBoxes ( void ) + { + for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) + { + CModifiedEditBox * EditBox = eb_iter->second; + UpdateModEditBox(*EditBox,eb_iter->first); + } + } + virtual void ApplyCheckBoxes ( void ) + { + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + UpdateModCheckBox(*Button,iter->first); + } + } + virtual void ApplyComboBoxes ( void ) + { + for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) + { + CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; + UpdateModComboBoxTxt(*ComboBox,cbtxt_iter->first); + } + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + UpdateModComboBox(*ComboBox,cb_iter->first); + } + } + void ApplySettings( bool UpdateScreen ) + { + ApplyEditBoxes(); + ApplyCheckBoxes(); + ApplyComboBoxes(); + + if (UpdateScreen) + { + UpdatePageSettings(); + } + } + + bool EnableReset ( void ) + { + for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) + { + CModifiedEditBox * EditBox = eb_iter->second; + if (EditBox->IsChanged()) + { + return true; + } + } + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if (Button->IsChanged()) + { + return true; + } + } + for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) + { + CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; + if (ComboBox->IsChanged()) + { + return true; + } + } + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if (ComboBox->IsChanged()) + { + return true; + } + } + return false; + } + + void ResetPage ( void ) + { + bool Changed = false; + for (TextBoxList::iterator eb_iter = m_TxtBoxList.begin(); eb_iter != m_TxtBoxList.end(); eb_iter ++) + { + CModifiedEditBox * EditBox = eb_iter->second; + if (ResetEditBox(*EditBox,eb_iter->first)) + { + Changed = true; + } + } + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if (ResetCheckBox(*Button,iter->first)) + { + Changed = true; + } + } + for (ComboBoxTxtList::iterator cbtxt_iter = m_ComboBoxTxtList.begin(); cbtxt_iter != m_ComboBoxTxtList.end(); cbtxt_iter ++) + { + CModifiedComboBoxTxt * ComboBox = cbtxt_iter->second; + if (ResetComboBoxTxt(*ComboBox,cbtxt_iter->first)) + { + Changed = true; + } + } + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if (ResetComboBox(*ComboBox,cb_iter->first)) + { + Changed = true; + } + } + if (Changed) + { + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + } + } +protected: + TextBoxList m_TxtBoxList; + ButtonList m_ButtonList; + ComboBoxList m_ComboBoxList; + ComboBoxTxtList m_ComboBoxTxtList; + bool m_UpdatingTxt; +}; + + +typedef std::vector SETTING_PAGES; + +class CConfigSettingSection +{ + SETTING_PAGES m_Pages; + std::wstring m_PageTitle; + +public: + CConfigSettingSection ( LPCWSTR PageTitle ); + ~CConfigSettingSection(); + + LPCWSTR GetPageTitle ( void ) const { return m_PageTitle.c_str(); } + void AddPage ( CSettingsPage * Page ); + size_t GetPageCount ( void ) const { return m_Pages.size(); } + CSettingsPage * GetPage ( int PageNo ); +}; + +#include "SettingsPage-AdvancedOptions.h" +#include "SettingsPage-Directories.h" +#include "SettingsPage-Game-General.h" +#include "SettingsPage-Game-Plugin.h" +#include "SettingsPage-Game-Recompiler.h" +#include "SettingsPage-Game-Status.h" +#include "SettingsPage-GameBrowser.h" +#include "SettingsPage-KeyboardShortcuts.h" +#include "SettingsPage-Options.h" +#include "SettingsPage-Plugin.h" diff --git a/Source/Project64/UserInterface/SettingsConfig.cpp b/Source/Project64/UserInterface/SettingsConfig.cpp index e7fdc4c44..6cbbd624b 100644 --- a/Source/Project64/UserInterface/SettingsConfig.cpp +++ b/Source/Project64/UserInterface/SettingsConfig.cpp @@ -1,342 +1,342 @@ -#include "stdafx.h" - -#include "SettingsConfig.h" -#include "Settings/SettingsPage.h" -#include - -CSettingConfig::CSettingConfig(bool bJustGameSetting /* = false */) : -m_CurrentPage(NULL), -m_GeneralOptionsPage(NULL), -m_AdvancedPage(NULL), -m_GameConfig(bJustGameSetting) -{ -} - -CSettingConfig::~CSettingConfig() -{ - for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) - { - CConfigSettingSection * Section = *iter; - delete Section; - } -} - -void CSettingConfig::Display(void * ParentWindow) -{ - if (g_BaseSystem) - { - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_Settings); - } - - BOOL result = m_thunk.Init(NULL, NULL); - if (result) - { - _AtlWinModule.AddCreateWndData(&m_thunk.cd, this); -#ifdef _DEBUG - m_bModal = true; -#endif //_DEBUG - ::DialogBoxParamW(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCEW(IDD), (HWND)ParentWindow, StartDialogProc, NULL); - } - - if (g_BaseSystem) - { - g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_Settings); - } -} - -void CSettingConfig::UpdateAdvanced(bool AdvancedMode) -{ - UpdateAdvanced(AdvancedMode, m_PagesTreeList.GetRootItem()); - BoldChangedPages(m_PagesTreeList.GetRootItem()); -} - -bool CSettingConfig::UpdateAdvanced(bool AdvancedMode, HTREEITEM hItem) -{ - while (hItem) - { - CSettingsPage * Page = (CSettingsPage *)m_PagesTreeList.GetItemData(hItem); - if (!AdvancedMode && Page == m_AdvancedPage) - { - m_PagesTreeList.DeleteItem(hItem); - return true; - } - if (AdvancedMode && Page == m_GeneralOptionsPage) - { - m_PagesTreeList.InsertItemW(TVIF_TEXT | TVIF_PARAM, wGS(m_AdvancedPage->PageTitle()).c_str(), 0, 0, 0, 0, (ULONG)m_AdvancedPage, hItem, TVI_FIRST); - return true; - } - if (UpdateAdvanced(AdvancedMode, m_PagesTreeList.GetChildItem(hItem))) - { - return true; - } - hItem = m_PagesTreeList.GetNextSiblingItem(hItem); - } - return false; -} - -LRESULT CSettingConfig::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ - stdstr ConfigRomTitle, GameIni(g_Settings->LoadStringVal(Game_IniKey)); - - if (!GameIni.empty()) - { - ConfigRomTitle.Format("Config: %s", g_Settings->LoadStringVal(Game_GoodName).c_str()); - } - - RECT rcSettingInfo; - ::GetWindowRect(GetDlgItem(IDC_SETTING_INFO), &rcSettingInfo); - ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcSettingInfo, 2); - - CConfigSettingSection * SettingsSection; - - //Set the text for all gui Items - SetDlgItemTextW(m_hWnd, IDC_RESET_PAGE, wGS(BOTTOM_RESET_PAGE).c_str()); - SetDlgItemTextW(m_hWnd, IDC_RESET_ALL, wGS(BOTTOM_RESET_ALL).c_str()); - SetDlgItemTextW(m_hWnd, IDOK, wGS(CHEAT_OK).c_str()); - SetDlgItemTextW(m_hWnd, IDCANCEL, wGS(CHEAT_CANCEL).c_str()); - SetDlgItemTextW(m_hWnd, IDAPPLY, wGS(BOTTOM_APPLY).c_str()); - - if (m_GameConfig) - { - if (g_Settings->LoadBool(Setting_RdbEditor)) - { - SetWindowText(stdstr_f("%s ** RDB Edit Mode **", ConfigRomTitle.c_str()).c_str()); - } - else - { - SetWindowText(ConfigRomTitle.c_str()); - } - } - else - { - if (g_Settings->LoadBool(Setting_RdbEditor)) - { - SetWindowTextW(m_hWnd, stdstr_f("%s ** RDB Edit Mode **", GS(OPTIONS_TITLE)).ToUTF16().c_str()); - } - else - { - ::SetWindowTextW(m_hWnd, wGS(OPTIONS_TITLE).c_str()); - } - - if (g_Settings->LoadBool(Setting_PluginPageFirst)) - { - SettingsSection = new CConfigSettingSection(wGS(TAB_PLUGIN).c_str()); - SettingsSection->AddPage(new COptionPluginPage(this->m_hWnd, rcSettingInfo)); - m_Sections.push_back(SettingsSection); - } - - m_GeneralOptionsPage = new CGeneralOptionsPage(this, this->m_hWnd, rcSettingInfo); - m_AdvancedPage = new CAdvancedOptionsPage(this->m_hWnd, rcSettingInfo); - - SettingsSection = new CConfigSettingSection(wGS(TAB_OPTIONS).c_str()); - SettingsSection->AddPage(m_GeneralOptionsPage); - SettingsSection->AddPage(m_AdvancedPage); - SettingsSection->AddPage(new COptionsDirectoriesPage(this->m_hWnd, rcSettingInfo)); - m_Sections.push_back(SettingsSection); - - SettingsSection = new CConfigSettingSection(wGS(TAB_ROMSELECTION).c_str()); - SettingsSection->AddPage(new COptionsGameBrowserPage(this->m_hWnd, rcSettingInfo)); - m_Sections.push_back(SettingsSection); - - SettingsSection = new CConfigSettingSection(wGS(TAB_SHORTCUTS).c_str()); - SettingsSection->AddPage(new COptionsShortCutsPage(this->m_hWnd, rcSettingInfo)); - m_Sections.push_back(SettingsSection); - - if (!g_Settings->LoadBool(Setting_PluginPageFirst)) - { - SettingsSection = new CConfigSettingSection(wGS(TAB_PLUGIN).c_str()); - SettingsSection->AddPage(new COptionPluginPage(this->m_hWnd, rcSettingInfo)); - m_Sections.push_back(SettingsSection); - } - } - - //Game Settings - if (!GameIni.empty()) - { - CConfigSettingSection * GameSettings = new CConfigSettingSection(ConfigRomTitle.ToUTF16().c_str()); - GameSettings->AddPage(new CGameGeneralPage(this->m_hWnd, rcSettingInfo)); - GameSettings->AddPage(new CGameRecompilePage(this->m_hWnd, rcSettingInfo)); - GameSettings->AddPage(new CGamePluginPage(this->m_hWnd, rcSettingInfo)); - if (g_Settings->LoadBool(Setting_RdbEditor)) - { - GameSettings->AddPage(new CGameStatusPage(this->m_hWnd, rcSettingInfo)); - } - m_Sections.push_back(GameSettings); - } - - m_PagesTreeList.Attach(GetDlgItem(IDC_PAGELIST)); - - bool bFirstItem = true; - bool HideAdvanced = g_Settings->LoadBool(UserInterface_BasicMode); - for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) - { - CConfigSettingSection * Section = *iter; - - HTREEITEM hSectionItem = NULL; - - for (size_t i = 0; i < Section->GetPageCount(); i++) - { - CSettingsPage * Page = Section->GetPage(i); - if (HideAdvanced && Page == m_AdvancedPage) - { - continue; - } - if (i == 0) - { - hSectionItem = m_PagesTreeList.InsertItemW(TVIF_TEXT | TVIF_PARAM, Section->GetPageTitle(), 0, 0, 0, 0, (ULONG)Page, TVI_ROOT, TVI_LAST); - continue; - } - if (hSectionItem == NULL) - { - continue; - } - m_PagesTreeList.InsertItemW(TVIF_TEXT | TVIF_PARAM, wGS(Page->PageTitle()).c_str(), 0, 0, 0, 0, (ULONG)Page, hSectionItem, TVI_LAST); - } - if (bFirstItem && hSectionItem != NULL) - { - bFirstItem = false; - m_PagesTreeList.Expand(hSectionItem); - m_PagesTreeList.SelectItem(hSectionItem); - } - } - - BoldChangedPages(m_PagesTreeList.GetRootItem()); - return TRUE; -} - -LRESULT CSettingConfig::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/) -{ - switch (wID) - { - case IDAPPLY: - ApplySettings(true); - break; - case IDOK: - ApplySettings(false); - EndDialog(1); - break; - case IDCANCEL: - EndDialog(0); - break; - case IDC_RESET_PAGE: - if (m_CurrentPage) - { - m_CurrentPage->ResetPage(); - } - break; - case IDC_RESET_ALL: - for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) - { - CConfigSettingSection * Section = *iter; - - for (size_t i = 0; i < Section->GetPageCount(); i++) - { - CSettingsPage * Page = Section->GetPage(i); - if (Page->EnableReset()) - { - Page->ResetPage(); - } - } - } - - break; - } - return FALSE; -} - -void CSettingConfig::ApplySettings(bool UpdateScreen) -{ - stdstr GameIni(g_Settings->LoadStringVal(Game_IniKey)); - - if (!GameIni.empty()) - { - stdstr GoodName; - if (!g_Settings->LoadStringVal(Game_GoodName, GoodName)) - { - g_Settings->SaveString(Game_GoodName, GoodName); - } - } - - for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) - { - CConfigSettingSection * Section = *iter; - - for (size_t i = 0; i < Section->GetPageCount(); i++) - { - CSettingsPage * Page = Section->GetPage(i); - Page->ApplySettings(UpdateScreen); - } - } - - if (UpdateScreen) - { - ::EnableWindow(GetDlgItem(IDAPPLY), false); - ::EnableWindow(GetDlgItem(IDC_RESET_PAGE), m_CurrentPage->EnableReset()); - } - - if (!g_Settings->LoadStringVal(Game_IniKey).empty()) - { - stdstr GoodName = g_Settings->LoadStringVal(Rdb_GoodName); - if (GoodName.length() > 0) - { - g_Settings->SaveString(Game_GoodName, GoodName); - } - } - CSettingTypeApplication::Flush(); -} - -LRESULT CSettingConfig::OnPageListItemChanged(NMHDR* /*phdr*/) -{ - HTREEITEM hItem = m_PagesTreeList.GetSelectedItem(); - CSettingsPage * Page = (CSettingsPage *)m_PagesTreeList.GetItemData(hItem); - - if (Page) - { - if (m_CurrentPage) - { - m_CurrentPage->HidePage(); - } - m_CurrentPage = Page; - m_CurrentPage->ShowPage(); - ::EnableWindow(GetDlgItem(IDC_RESET_PAGE), m_CurrentPage->EnableReset()); - } - return 0; // retval ignored -} - -LRESULT CSettingConfig::OnSettingPageChanged(UINT /*uMsg*/, WPARAM /*wPage*/, LPARAM /*lParam*/) -{ - ::EnableWindow(GetDlgItem(IDAPPLY), true); - ::EnableWindow(GetDlgItem(IDC_RESET_PAGE), m_CurrentPage->EnableReset()); - BoldChangedPages(m_PagesTreeList.GetRootItem()); - return 0; -} - -void CSettingConfig::BoldChangedPages(HTREEITEM hItem) -{ - if (hItem == m_PagesTreeList.GetRootItem()) - { - ::EnableWindow(GetDlgItem(IDC_RESET_ALL), false); - } - bool bEnableResetAll = false; - - while (hItem) - { - CSettingsPage * Page = (CSettingsPage *)m_PagesTreeList.GetItemData(hItem); - if (Page) - { - m_PagesTreeList.SetItemState(hItem, Page->EnableReset() ? TVIS_BOLD : 0, TVIS_BOLD); - if (Page->EnableReset()) - { - bEnableResetAll = true; - } - } - - BoldChangedPages(m_PagesTreeList.GetChildItem(hItem)); - hItem = m_PagesTreeList.GetNextSiblingItem(hItem); - } - - if (bEnableResetAll) - { - ::EnableWindow(GetDlgItem(IDC_RESET_ALL), true); - } -} +#include "stdafx.h" + +#include "SettingsConfig.h" +#include "Settings/SettingsPage.h" +#include + +CSettingConfig::CSettingConfig(bool bJustGameSetting /* = false */) : +m_CurrentPage(NULL), +m_GeneralOptionsPage(NULL), +m_AdvancedPage(NULL), +m_GameConfig(bJustGameSetting) +{ +} + +CSettingConfig::~CSettingConfig() +{ + for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) + { + CConfigSettingSection * Section = *iter; + delete Section; + } +} + +void CSettingConfig::Display(void * ParentWindow) +{ + if (g_BaseSystem) + { + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_Settings); + } + + BOOL result = m_thunk.Init(NULL, NULL); + if (result) + { + _AtlWinModule.AddCreateWndData(&m_thunk.cd, this); +#ifdef _DEBUG + m_bModal = true; +#endif //_DEBUG + ::DialogBoxParamW(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCEW(IDD), (HWND)ParentWindow, StartDialogProc, NULL); + } + + if (g_BaseSystem) + { + g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_Settings); + } +} + +void CSettingConfig::UpdateAdvanced(bool AdvancedMode) +{ + UpdateAdvanced(AdvancedMode, m_PagesTreeList.GetRootItem()); + BoldChangedPages(m_PagesTreeList.GetRootItem()); +} + +bool CSettingConfig::UpdateAdvanced(bool AdvancedMode, HTREEITEM hItem) +{ + while (hItem) + { + CSettingsPage * Page = (CSettingsPage *)m_PagesTreeList.GetItemData(hItem); + if (!AdvancedMode && Page == m_AdvancedPage) + { + m_PagesTreeList.DeleteItem(hItem); + return true; + } + if (AdvancedMode && Page == m_GeneralOptionsPage) + { + m_PagesTreeList.InsertItemW(TVIF_TEXT | TVIF_PARAM, wGS(m_AdvancedPage->PageTitle()).c_str(), 0, 0, 0, 0, (ULONG)m_AdvancedPage, hItem, TVI_FIRST); + return true; + } + if (UpdateAdvanced(AdvancedMode, m_PagesTreeList.GetChildItem(hItem))) + { + return true; + } + hItem = m_PagesTreeList.GetNextSiblingItem(hItem); + } + return false; +} + +LRESULT CSettingConfig::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + stdstr ConfigRomTitle, GameIni(g_Settings->LoadStringVal(Game_IniKey)); + + if (!GameIni.empty()) + { + ConfigRomTitle.Format("Config: %s", g_Settings->LoadStringVal(Game_GoodName).c_str()); + } + + RECT rcSettingInfo; + ::GetWindowRect(GetDlgItem(IDC_SETTING_INFO), &rcSettingInfo); + ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcSettingInfo, 2); + + CConfigSettingSection * SettingsSection; + + //Set the text for all gui Items + SetDlgItemTextW(m_hWnd, IDC_RESET_PAGE, wGS(BOTTOM_RESET_PAGE).c_str()); + SetDlgItemTextW(m_hWnd, IDC_RESET_ALL, wGS(BOTTOM_RESET_ALL).c_str()); + SetDlgItemTextW(m_hWnd, IDOK, wGS(CHEAT_OK).c_str()); + SetDlgItemTextW(m_hWnd, IDCANCEL, wGS(CHEAT_CANCEL).c_str()); + SetDlgItemTextW(m_hWnd, IDAPPLY, wGS(BOTTOM_APPLY).c_str()); + + if (m_GameConfig) + { + if (g_Settings->LoadBool(Setting_RdbEditor)) + { + SetWindowText(stdstr_f("%s ** RDB Edit Mode **", ConfigRomTitle.c_str()).c_str()); + } + else + { + SetWindowText(ConfigRomTitle.c_str()); + } + } + else + { + if (g_Settings->LoadBool(Setting_RdbEditor)) + { + SetWindowTextW(m_hWnd, stdstr_f("%s ** RDB Edit Mode **", GS(OPTIONS_TITLE)).ToUTF16().c_str()); + } + else + { + ::SetWindowTextW(m_hWnd, wGS(OPTIONS_TITLE).c_str()); + } + + if (g_Settings->LoadBool(Setting_PluginPageFirst)) + { + SettingsSection = new CConfigSettingSection(wGS(TAB_PLUGIN).c_str()); + SettingsSection->AddPage(new COptionPluginPage(this->m_hWnd, rcSettingInfo)); + m_Sections.push_back(SettingsSection); + } + + m_GeneralOptionsPage = new CGeneralOptionsPage(this, this->m_hWnd, rcSettingInfo); + m_AdvancedPage = new CAdvancedOptionsPage(this->m_hWnd, rcSettingInfo); + + SettingsSection = new CConfigSettingSection(wGS(TAB_OPTIONS).c_str()); + SettingsSection->AddPage(m_GeneralOptionsPage); + SettingsSection->AddPage(m_AdvancedPage); + SettingsSection->AddPage(new COptionsDirectoriesPage(this->m_hWnd, rcSettingInfo)); + m_Sections.push_back(SettingsSection); + + SettingsSection = new CConfigSettingSection(wGS(TAB_ROMSELECTION).c_str()); + SettingsSection->AddPage(new COptionsGameBrowserPage(this->m_hWnd, rcSettingInfo)); + m_Sections.push_back(SettingsSection); + + SettingsSection = new CConfigSettingSection(wGS(TAB_SHORTCUTS).c_str()); + SettingsSection->AddPage(new COptionsShortCutsPage(this->m_hWnd, rcSettingInfo)); + m_Sections.push_back(SettingsSection); + + if (!g_Settings->LoadBool(Setting_PluginPageFirst)) + { + SettingsSection = new CConfigSettingSection(wGS(TAB_PLUGIN).c_str()); + SettingsSection->AddPage(new COptionPluginPage(this->m_hWnd, rcSettingInfo)); + m_Sections.push_back(SettingsSection); + } + } + + //Game Settings + if (!GameIni.empty()) + { + CConfigSettingSection * GameSettings = new CConfigSettingSection(ConfigRomTitle.ToUTF16().c_str()); + GameSettings->AddPage(new CGameGeneralPage(this->m_hWnd, rcSettingInfo)); + GameSettings->AddPage(new CGameRecompilePage(this->m_hWnd, rcSettingInfo)); + GameSettings->AddPage(new CGamePluginPage(this->m_hWnd, rcSettingInfo)); + if (g_Settings->LoadBool(Setting_RdbEditor)) + { + GameSettings->AddPage(new CGameStatusPage(this->m_hWnd, rcSettingInfo)); + } + m_Sections.push_back(GameSettings); + } + + m_PagesTreeList.Attach(GetDlgItem(IDC_PAGELIST)); + + bool bFirstItem = true; + bool HideAdvanced = g_Settings->LoadBool(UserInterface_BasicMode); + for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) + { + CConfigSettingSection * Section = *iter; + + HTREEITEM hSectionItem = NULL; + + for (size_t i = 0; i < Section->GetPageCount(); i++) + { + CSettingsPage * Page = Section->GetPage(i); + if (HideAdvanced && Page == m_AdvancedPage) + { + continue; + } + if (i == 0) + { + hSectionItem = m_PagesTreeList.InsertItemW(TVIF_TEXT | TVIF_PARAM, Section->GetPageTitle(), 0, 0, 0, 0, (ULONG)Page, TVI_ROOT, TVI_LAST); + continue; + } + if (hSectionItem == NULL) + { + continue; + } + m_PagesTreeList.InsertItemW(TVIF_TEXT | TVIF_PARAM, wGS(Page->PageTitle()).c_str(), 0, 0, 0, 0, (ULONG)Page, hSectionItem, TVI_LAST); + } + if (bFirstItem && hSectionItem != NULL) + { + bFirstItem = false; + m_PagesTreeList.Expand(hSectionItem); + m_PagesTreeList.SelectItem(hSectionItem); + } + } + + BoldChangedPages(m_PagesTreeList.GetRootItem()); + return TRUE; +} + +LRESULT CSettingConfig::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/) +{ + switch (wID) + { + case IDAPPLY: + ApplySettings(true); + break; + case IDOK: + ApplySettings(false); + EndDialog(1); + break; + case IDCANCEL: + EndDialog(0); + break; + case IDC_RESET_PAGE: + if (m_CurrentPage) + { + m_CurrentPage->ResetPage(); + } + break; + case IDC_RESET_ALL: + for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) + { + CConfigSettingSection * Section = *iter; + + for (size_t i = 0; i < Section->GetPageCount(); i++) + { + CSettingsPage * Page = Section->GetPage(i); + if (Page->EnableReset()) + { + Page->ResetPage(); + } + } + } + + break; + } + return FALSE; +} + +void CSettingConfig::ApplySettings(bool UpdateScreen) +{ + stdstr GameIni(g_Settings->LoadStringVal(Game_IniKey)); + + if (!GameIni.empty()) + { + stdstr GoodName; + if (!g_Settings->LoadStringVal(Game_GoodName, GoodName)) + { + g_Settings->SaveString(Game_GoodName, GoodName); + } + } + + for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) + { + CConfigSettingSection * Section = *iter; + + for (size_t i = 0; i < Section->GetPageCount(); i++) + { + CSettingsPage * Page = Section->GetPage(i); + Page->ApplySettings(UpdateScreen); + } + } + + if (UpdateScreen) + { + ::EnableWindow(GetDlgItem(IDAPPLY), false); + ::EnableWindow(GetDlgItem(IDC_RESET_PAGE), m_CurrentPage->EnableReset()); + } + + if (!g_Settings->LoadStringVal(Game_IniKey).empty()) + { + stdstr GoodName = g_Settings->LoadStringVal(Rdb_GoodName); + if (GoodName.length() > 0) + { + g_Settings->SaveString(Game_GoodName, GoodName); + } + } + CSettingTypeApplication::Flush(); +} + +LRESULT CSettingConfig::OnPageListItemChanged(NMHDR* /*phdr*/) +{ + HTREEITEM hItem = m_PagesTreeList.GetSelectedItem(); + CSettingsPage * Page = (CSettingsPage *)m_PagesTreeList.GetItemData(hItem); + + if (Page) + { + if (m_CurrentPage) + { + m_CurrentPage->HidePage(); + } + m_CurrentPage = Page; + m_CurrentPage->ShowPage(); + ::EnableWindow(GetDlgItem(IDC_RESET_PAGE), m_CurrentPage->EnableReset()); + } + return 0; // retval ignored +} + +LRESULT CSettingConfig::OnSettingPageChanged(UINT /*uMsg*/, WPARAM /*wPage*/, LPARAM /*lParam*/) +{ + ::EnableWindow(GetDlgItem(IDAPPLY), true); + ::EnableWindow(GetDlgItem(IDC_RESET_PAGE), m_CurrentPage->EnableReset()); + BoldChangedPages(m_PagesTreeList.GetRootItem()); + return 0; +} + +void CSettingConfig::BoldChangedPages(HTREEITEM hItem) +{ + if (hItem == m_PagesTreeList.GetRootItem()) + { + ::EnableWindow(GetDlgItem(IDC_RESET_ALL), false); + } + bool bEnableResetAll = false; + + while (hItem) + { + CSettingsPage * Page = (CSettingsPage *)m_PagesTreeList.GetItemData(hItem); + if (Page) + { + m_PagesTreeList.SetItemState(hItem, Page->EnableReset() ? TVIS_BOLD : 0, TVIS_BOLD); + if (Page->EnableReset()) + { + bEnableResetAll = true; + } + } + + BoldChangedPages(m_PagesTreeList.GetChildItem(hItem)); + hItem = m_PagesTreeList.GetNextSiblingItem(hItem); + } + + if (bEnableResetAll) + { + ::EnableWindow(GetDlgItem(IDC_RESET_ALL), true); + } +} diff --git a/Source/Project64/UserInterface/SettingsConfig.h b/Source/Project64/UserInterface/SettingsConfig.h index 7f1a33620..02a005787 100644 --- a/Source/Project64/UserInterface/SettingsConfig.h +++ b/Source/Project64/UserInterface/SettingsConfig.h @@ -1,45 +1,45 @@ -#pragma once - -#include - -class CConfigSettingSection; -class CSettingsPage; - -class CSettingConfig : - public CDialogImpl < CSettingConfig > -{ -public: - BEGIN_MSG_MAP_EX(CSettingConfig) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) - NOTIFY_HANDLER_EX(IDC_PAGELIST, TVN_SELCHANGED, OnPageListItemChanged) - MESSAGE_HANDLER_EX(PSM_CHANGED, OnSettingPageChanged) - REFLECT_NOTIFICATIONS() - END_MSG_MAP() - - enum { IDD = IDD_Settings_Config }; - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); - LRESULT OnPageListItemChanged(NMHDR* phdr); - LRESULT OnSettingPageChanged(UINT /*uMsg*/, WPARAM wPage, LPARAM /*lParam*/); - -public: - CSettingConfig(bool bJustGameSetting = false); - ~CSettingConfig(void); - - void Display(void * ParentWindow); - void UpdateAdvanced(bool AdvancedMode); - -private: - bool UpdateAdvanced(bool AdvancedMode, HTREEITEM hItem); - void ApplySettings(bool UpdateScreen); - void BoldChangedPages(HTREEITEM hItem); - - typedef std::list SETTING_SECTIONS; - - CTreeViewCtrl m_PagesTreeList; - SETTING_SECTIONS m_Sections; - CSettingsPage * m_CurrentPage, *m_GeneralOptionsPage, *m_AdvancedPage; - bool m_GameConfig; -}; +#pragma once + +#include + +class CConfigSettingSection; +class CSettingsPage; + +class CSettingConfig : + public CDialogImpl < CSettingConfig > +{ +public: + BEGIN_MSG_MAP_EX(CSettingConfig) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) + NOTIFY_HANDLER_EX(IDC_PAGELIST, TVN_SELCHANGED, OnPageListItemChanged) + MESSAGE_HANDLER_EX(PSM_CHANGED, OnSettingPageChanged) + REFLECT_NOTIFICATIONS() + END_MSG_MAP() + + enum { IDD = IDD_Settings_Config }; + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); + LRESULT OnPageListItemChanged(NMHDR* phdr); + LRESULT OnSettingPageChanged(UINT /*uMsg*/, WPARAM wPage, LPARAM /*lParam*/); + +public: + CSettingConfig(bool bJustGameSetting = false); + ~CSettingConfig(void); + + void Display(void * ParentWindow); + void UpdateAdvanced(bool AdvancedMode); + +private: + bool UpdateAdvanced(bool AdvancedMode, HTREEITEM hItem); + void ApplySettings(bool UpdateScreen); + void BoldChangedPages(HTREEITEM hItem); + + typedef std::list SETTING_SECTIONS; + + CTreeViewCtrl m_PagesTreeList; + SETTING_SECTIONS m_Sections; + CSettingsPage * m_CurrentPage, *m_GeneralOptionsPage, *m_AdvancedPage; + bool m_GameConfig; +}; diff --git a/Source/Project64/UserInterface/UIResources.rc b/Source/Project64/UserInterface/UIResources.rc index afbc0b00d..84e773e2f 100644 --- a/Source/Project64/UserInterface/UIResources.rc +++ b/Source/Project64/UserInterface/UIResources.rc @@ -1,986 +1,986 @@ - -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" -#include "../../Project64-core/Version.h" - -#define APSTUDIO_READONLY_SYMBOLS - -#include "WinResrc.h" - -#ifdef IDC_STATIC -#undef IDC_STATIC -#endif -#define IDC_STATIC (-1) - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""WinResrc.h""\r\n" - "\r\n" - "#ifdef IDC_STATIC\r\n" - "#undef IDC_STATIC\r\n" - "#endif\r\n" - "#define IDC_STATIC (-1)\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_PJ64_Icon ICON "Icons\\PJ64.ICO" -IDI_RIGHT ICON "Icons\\right.ico" -IDI_LEFT ICON "Icons\\left.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_Settings_PlugSel DIALOGEX 0, 0, 231, 206 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - COMBOBOX GFX_LIST,7,18,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "About",GFX_ABOUT,166,18,44,13,WS_DISABLED - COMBOBOX AUDIO_LIST,7,48,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "About",AUDIO_ABOUT,166,48,44,13,WS_DISABLED - COMBOBOX CONT_LIST,7,76,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "About",CONT_ABOUT,166,76,44,13,WS_DISABLED - COMBOBOX RSP_LIST,7,105,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "About",RSP_ABOUT,166,105,44,13,WS_DISABLED - CONTROL "Use High Level GFX",IDC_HLE_GFX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,127,193,10 - CONTROL "Use High Level Audio",IDC_HLE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,140,188,10 - GROUPBOX "Graphics:",IDC_GFX_NAME,6,6,208,29 - GROUPBOX "Audio:",IDC_AUDIO_NAME,6,38,208,29 - GROUPBOX "Controller:",IDC_CONT_NAME,6,66,208,29 - GROUPBOX "Reality Signal Processor: ",IDC_RSP_NAME,6,96,208,29 -END - -IDD_Settings_Directory DIALOGEX 0, 0, 231, 206 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Plugin Directoy",IDC_DIR_FRAME1,5,4,208,34 - CONTROL "$AppPath\\Plugin\\",IDC_PLUGIN_DEFAULT,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,6,13,179,8 - CONTROL "",IDC_PLUGIN_OTHER,"Button",BS_AUTORADIOBUTTON,6,22,11,12 - EDITTEXT IDC_PLUGIN_DIR,18,22,170,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_SELECT_PLUGIN_DIR,193,22,14,12 - GROUPBOX "N64 Auto saves",IDC_DIR_FRAME3,5,36,208,34 - CONTROL "$AppPath\\Save\\",IDC_AUTO_DEFAULT,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,6,45,179,8 - CONTROL "",IDC_AUTO_OTHER,"Button",BS_AUTORADIOBUTTON,6,54,11,12 - EDITTEXT IDC_AUTO_DIR,18,54,170,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_SELECT_AUTO_DIR,193,54,14,12 - GROUPBOX "Instant saves",IDC_DIR_FRAME4,5,68,208,34 - CONTROL "$AppPath\\Save\\",IDC_INSTANT_DEFAULT,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,6,77,179,8 - CONTROL "",IDC_INSTANT_OTHER,"Button",BS_AUTORADIOBUTTON,6,87,11,12 - EDITTEXT IDC_INSTANT_DIR,18,86,170,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_SELECT_INSTANT_DIR,193,86,14,12 - GROUPBOX "Screenshots",IDC_DIR_FRAME5,5,99,208,34 - CONTROL "$AppPath\\Screenshots\\",IDC_SNAP_DEFAULT,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,6,109,179,8 - CONTROL "",IDC_SNAP_OTHER,"Button",BS_AUTORADIOBUTTON,6,118,11,12 - EDITTEXT IDC_SNAP_DIR,18,118,170,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_SELECT_SNAP_DIR,193,118,14,12 - GROUPBOX "Texture Directory",IDC_DIR_TEXTURE_FRAME,5,131,208,34 - CONTROL "$AppPath\\textures\\",IDC_TEXTURE_DEFAULT,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,6,140,179,8 - CONTROL "",IDC_TEXTURE_OTHER,"Button",BS_AUTORADIOBUTTON,6,150,11,12 - EDITTEXT IDC_TEXTURE_DIR,18,149,170,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_SELECT_TEXTURE_DIR,193,149,14,12 -END - -IDD_Settings_RomBrowser DIALOGEX 0, 0, 231, 206 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Use Rom Browser",IDC_USE_ROMBROWSER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,7,206,10 - CONTROL "Use Directory recursion",IDC_RECURSION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,148,202,10 - LTEXT "Available fields",IDC_ROMSEL_TEXT5,6,26,77,10 - LISTBOX IDC_AVALIABLE,6,38,76,104,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - LTEXT "Show fields in this order:",IDC_ROMSEL_TEXT6,135,26,81,10 - LISTBOX IDC_USING,134,38,76,87,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add ->",IDC_ADD,85,38,45,12 - PUSHBUTTON "<- Remove",IDC_REMOVE,85,54,45,12 - PUSHBUTTON "Up",IDC_UP,134,131,34,11 - PUSHBUTTON "Down",IDC_DOWN,175,131,34,11 - CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,6,19,208,1 -END - -IDD_Settings_General DIALOGEX 0, 0, 231, 210 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Pause emulation when window is not active?",IDC_AUTOSLEEP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,9,206,10 - CONTROL "On loading a ROM go to full screen",IDC_LOAD_FULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,25,206,10 - CONTROL "Disable Screen Saver when running rom",IDC_SCREEN_SAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,41,206,10 - CONTROL "Hide Advanced Settings",IDC_BASIC_MODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,57,206,10 - LTEXT "Max # of Roms Remembered (Max 10):",IDC_MAXROMS_TXT,6,81,145,10 - EDITTEXT IDC_REMEMBER,148,79,26,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "roms",IDC_ROMSEL_TEXT2,178,82,31,10 - LTEXT "Max # of Rom Dirs Remembered (Max 10):",IDC_MAXROMDIR_TXT,6,96,145,10 - EDITTEXT IDC_REMEMBERDIR,148,94,26,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "dirs",IDC_ROMSEL_TEXT4,178,98,34,10 - CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,4,73,208,1 -END - -IDD_Rom_Information DIALOGEX 0, 0, 239, 207 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Rom Information" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - DEFPUSHBUTTON "&Close",IDC_CLOSE_BUTTON,169,186,64,14 - GROUPBOX "",IDC_STATIC,6,5,228,177 - LTEXT "ROM Name:",IDC_ROM_NAME,11,16,64,10 - EDITTEXT IDC_INFO_ROMNAME,77,15,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "File Name:",IDC_FILE_NAME,11,31,64,10 - EDITTEXT IDC_INFO_FILENAME,77,30,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "Rom Size:",IDC_ROM_SIZE,11,74,64,10 - EDITTEXT IDC_INFO_ROMSIZE,77,74,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "Cartridge ID:",IDC_CART_ID,11,90,64,10 - EDITTEXT IDC_INFO_CARTID,77,89,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "Manufacturer:",IDC_MANUFACTURER,11,106,64,10 - EDITTEXT IDC_INFO_MANUFACTURER,77,104,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "Country:",IDC_COUNTRY,11,122,64,10 - EDITTEXT IDC_INFO_COUNTRY,77,119,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "CRC1:",IDC_CRC1,11,135,64,10 - EDITTEXT IDC_INFO_CRC1,77,134,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "CRC2:",IDC_CRC2,11,151,64,10 - EDITTEXT IDC_INFO_CRC2,77,149,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "CIC Chip:",IDC_CIC_CHIP,11,167,64,10 - EDITTEXT IDC_INFO_CIC,77,164,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "Location:",IDC_LOCATION,11,45,64,10 - EDITTEXT IDC_INFO_LOCATION,77,45,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE - LTEXT "MD5:",IDC_ROM_MD5,11,60,64,10 - EDITTEXT IDC_INFO_MD5,77,59,153,13,ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE | WS_EX_STATICEDGE -END - -IDD_Settings_GameGeneral DIALOGEX 0, 0, 218, 158 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Good Name:",IDC_GOOD_NAME_TEXT,6,8,91,10 - EDITTEXT IDC_GOOD_NAME,102,7,109,12,ES_AUTOHSCROLL | ES_READONLY - CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,4,25,208,1 - LTEXT "Memory Size:",IDC_MEMORY_SIZE_TEXT,6,34,91,10 - COMBOBOX IDC_RDRAM_SIZE,102,32,109,49,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Default Save type:",IDC_SAVE_TYPE_TEXT,6,49,91,10 - COMBOBOX IDC_SAVE_TYPE,102,47,109,49,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Counter Factor:",IDC_COUNTFACT_TEXT,6,64,91,10 - COMBOBOX IDC_COUNTFACT,102,61,109,49,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Vi Refresh Rate:",IDC_VIREFESH_TEXT,6,77,91,10 - EDITTEXT IDC_VIREFRESH,102,75,109,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "AI Count Per Byte:",IDC_COUNTPERBYTE_TEXT,6,90,91,10 - EDITTEXT IDC_COUNTPERBYTE,102,88,109,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,3,103,208,1 - CONTROL "32 Bit Engine",IDC_ROM_32BIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,107,91,10 - CONTROL "Use TLB",IDC_USE_TLB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,107,91,10 - CONTROL "Fixed Audio Timing",IDC_ROM_FIXEDAUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,118,91,10 - CONTROL "Sync using Audio",IDC_SYNC_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,118,91,10 - CONTROL "Delay DP Interrupt",IDC_DELAY_DP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,129,91,10 - CONTROL "Delay SI Interrupt",IDC_DELAY_SI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,129,91,10 - CONTROL "RSP Audio Signal",IDC_AUDIO_SIGNAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,140,91,10 -END - -IDD_Settings_Accelerator DIALOGEX 0, 0, 218, 183 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "CPU State:",IDC_S_CPU_STATE,8,9,52,10 - COMBOBOX IDC_C_CPU_STATE,68,7,144,66,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Menu Item:",IDC_MENU_ITEM_TEXT,8,23,84,10 - CONTROL "Tree1",IDC_MENU_ITEMS,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_NOTOOLTIPS | TVS_TRACKSELECT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,8,33,128,78 - LTEXT "Current Keys:",IDC_S_CURRENT_KEYS,142,23,52,10 - LISTBOX IDC_CURRENT_KEYS,144,33,68,59,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Remove",IDC_REMOVE,144,97,68,12 - GROUPBOX "Create New Shortcut Key:",IDC_S_SELECT_SHORT,8,115,207,57 - COMBOBOX IDC_VIRTUALKEY,8,125,91,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Detect Key",IDC_KEY_PROMPT,103,125,62,12 - PUSHBUTTON "Assign to Menu",IDC_ASSIGN,170,125,42,12 - CONTROL "&Ctrl",IDC_CTL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,142,23,10 - CONTROL "A<",IDC_ALT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,39,142,21,10 - CONTROL "&Shift",IDC_SHIFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,69,142,26,10 - LTEXT "Currently Assigned To:",IDC_S_CURRENT_ASSIGN,8,155,72,10 - LTEXT "",IDC_ASSIGNED_MENU_ITEM,89,155,118,10 -END - -IDD_Key_Prompt DIALOGEX 0, 0, 105, 43 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE -FONT 8, "MS Shell Dlg", 0, 0, 0x0 -BEGIN - PUSHBUTTON "Cancel",IDCANCEL,5,24,50,14 - LTEXT "Press a key to be used as an accelerator",IDC_STATIC,5,3,96,19 -END - -IDD_Cheats_Select DIALOGEX 0, 0, 412, 226 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Cheats" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - PUSHBUTTON "Button1",IDC_STATE,195,5,20,20,BS_ICON | BS_FLAT,WS_EX_TRANSPARENT -END - -IDD_Cheats_List DIALOGEX 0, 0, 201, 221 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Cheats",IDC_CHEATSFRAME,0,0,199,160 - PUSHBUTTON "Unmark All",IDC_UNMARK,145,145,49,11 - GROUPBOX " Notes: ",IDC_NOTESFRAME,0,165,199,51 - EDITTEXT IDC_NOTES,5,175,188,36,ES_MULTILINE | ES_READONLY | ES_WANTRETURN | NOT WS_BORDER | WS_VSCROLL -END - -IDD_Cheats_Add DIALOGEX 0, 0, 191, 215 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "",IDC_ADDCHEATSFRAME,2,0,188,145 - LTEXT "Name:",IDC_NAME,7,13,25,10 - EDITTEXT IDC_CODE_NAME,37,12,146,12,ES_AUTOHSCROLL - LTEXT "Code:",IDC_CODE,7,30,25,10 - LTEXT "
",IDC_CODE_DES,7,40,60,10 - LTEXT "Options:",IDC_LABEL_OPTIONS,82,30,30,10,WS_DISABLED - LTEXT "