diff --git a/build.rb b/build.rb index b9538a2aa1..62b67e6906 100755 --- a/build.rb +++ b/build.rb @@ -22,7 +22,7 @@ $pcsx2_prefix = " --prefix #{$main_dir}" $plugins_prefix = " --prefix #{$plugin_install_dir}" $plugin_list=["CDVDnull", "dev9null", "FWnull", "USBnull", "SPU2null", "zerogs", "zzogl", "zeropad", "zerospu2", "PeopsSPU2", "CDVDiso", "CDVDisoEFP", "CDVDlinuz"] -$full_plugin_list=["CDVDnull", "dev9null", "FWnull", "USBnull", "SPU2null", "zerogs", "zzogl", "zeropad", "zerospu2", "PeopsSPU2", "CDVDiso", "CDVDisoEFP", "CDVDlinuz","GSnull","PadNull","wxpad"] +$full_plugin_list=["CDVDnull", "dev9null", "FWnull", "USBnull", "SPU2null", "zerogs", "zzogl", "zeropad", "zerospu2", "PeopsSPU2", "CDVDiso", "CDVDisoEFP", "CDVDlinuz","GSnull","PadNull","onepad"] $pcsx2_build_types = { "dev" => " --enable-devbuild ", diff --git a/clean_msvc.cmd b/clean_msvc.cmd new file mode 100644 index 0000000000..a438137585 --- /dev/null +++ b/clean_msvc.cmd @@ -0,0 +1,12 @@ +-- clean_msvc.cmd +-- +-- This batch file cleans up some files that MSVC's Clean/Rebuild commands tend to miss. +-- In particular the .ilk and .pdb files are known to get corrupted and cause all sorts of odd +-- linker errors, and the .ncb files can also get corrupted and cause intellisense breakges. +-- +-- Safety: This tool should be pretty safe. None of the files it deletes are important. That +-- is, they're all files MSVC just rebuilds automatically next time you run/recompile. But even +-- so, don't go running this batch file in your root c:\ folder. It's probably not a wise action. +-- Enjoy. :) + +del /s *.ncb;*.ilk;*.pdb;*.bsc;*.sbr \ No newline at end of file diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index 6a231705ad..b3c7ddc7b4 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -393,6 +393,17 @@ void CALLBACK CDVDabout(); s32 CALLBACK CDVDtest(); void CALLBACK CDVDnewDiskCB(void (*callback)()); +// new funcs + +// read a track directly +s32 CALLBACK CDVDreadSector(u8* buffer, s32 lsn, int mode); + +// improved getBuffer +s32 CALLBACK CDVDgetBuffer2(u8* buffer); + +// tool function +s32 CALLBACK CDVDgetDualInfo(s32* dualType, u32* _layer1start); + #endif /* DEV9 plugin API */ @@ -521,6 +532,7 @@ typedef void (CALLBACK* _GSprintf)(int timeout, char *fmt, ...); typedef void (CALLBACK* _GSsetBaseMem)(void*); typedef void (CALLBACK* _GSsetGameCRC)(int, int); typedef void (CALLBACK* _GSsetFrameSkip)(int frameskip); +typedef void (CALLBACK* _GSsetFrameLimit)(int limit); typedef int (CALLBACK* _GSsetupRecording)(int, void*); typedef void (CALLBACK* _GSreset)(); typedef void (CALLBACK* _GSwriteCSR)(u32 value); @@ -615,12 +627,16 @@ typedef s32 (CALLBACK* _CDVDgetDiskType)(); typedef s32 (CALLBACK* _CDVDgetTrayStatus)(); typedef s32 (CALLBACK* _CDVDctrlTrayOpen)(); typedef s32 (CALLBACK* _CDVDctrlTrayClose)(); +typedef s32 (CALLBACK* _CDVDreadSector)(u8* buffer, u32 lsn, int mode); +typedef s32 (CALLBACK* _CDVDgetBuffer2)(u8* buffer); +typedef s32 (CALLBACK* _CDVDgetDualInfo)(s32* dualType, u32* _layer1start); typedef void (CALLBACK* _CDVDconfigure)(); typedef s32 (CALLBACK* _CDVDtest)(); typedef void (CALLBACK* _CDVDabout)(); typedef void (CALLBACK* _CDVDnewDiskCB)(void (*callback)()); + // DEV9 // NOTE: The read/write functions CANNOT use XMM/MMX regs // If you want to use them, need to save and restore current ones @@ -710,6 +726,7 @@ extern _GSprintf GSprintf; extern _GSsetBaseMem GSsetBaseMem; extern _GSsetGameCRC GSsetGameCRC; extern _GSsetFrameSkip GSsetFrameSkip; +extern _GSsetFrameLimit GSsetFrameLimit; extern _GSsetupRecording GSsetupRecording; extern _GSreset GSreset; extern _GSwriteCSR GSwriteCSR; @@ -802,25 +819,35 @@ extern _SPU2test SPU2test; extern _SPU2about SPU2about; // CDVD -extern _CDVDinit CDVDinit; -extern _CDVDopen CDVDopen; -extern _CDVDclose CDVDclose; -extern _CDVDshutdown CDVDshutdown; -extern _CDVDreadTrack CDVDreadTrack; -extern _CDVDgetBuffer CDVDgetBuffer; -extern _CDVDreadSubQ CDVDreadSubQ; -extern _CDVDgetTN CDVDgetTN; -extern _CDVDgetTD CDVDgetTD; -extern _CDVDgetTOC CDVDgetTOC; -extern _CDVDgetDiskType CDVDgetDiskType; -extern _CDVDgetTrayStatus CDVDgetTrayStatus; -extern _CDVDctrlTrayOpen CDVDctrlTrayOpen; -extern _CDVDctrlTrayClose CDVDctrlTrayClose; +struct CDVDplugin { + _CDVDinit init; + _CDVDopen open; + _CDVDclose close; + _CDVDshutdown shutdown; + _CDVDreadTrack readTrack; + _CDVDgetBuffer getBuffer; + _CDVDreadSubQ readSubQ; + _CDVDgetTN getTN; + _CDVDgetTD getTD; + _CDVDgetTOC getTOC; + _CDVDgetDiskType getDiskType; + _CDVDgetTrayStatus getTrayStatus; + _CDVDctrlTrayOpen ctrlTrayOpen; + _CDVDctrlTrayClose ctrlTrayClose; -extern _CDVDconfigure CDVDconfigure; -extern _CDVDtest CDVDtest; -extern _CDVDabout CDVDabout; -extern _CDVDnewDiskCB CDVDnewDiskCB; + _CDVDconfigure configure; + _CDVDtest test; + _CDVDabout about; + _CDVDnewDiskCB newDiskCB; + + // special functions, not in external interface yet + _CDVDreadSector readSector; + _CDVDgetBuffer2 getBuffer2; + _CDVDgetDualInfo getDualInfo; + + int* initCount; +}; +extern CDVDplugin CDVD_plugin; // _plugin because of // DEV9 extern _DEV9init DEV9init; diff --git a/common/include/Pcsx2Config.h b/common/include/Pcsx2Config.h index fde95f4111..01734271b3 100644 --- a/common/include/Pcsx2Config.h +++ b/common/include/Pcsx2Config.h @@ -167,7 +167,7 @@ public: struct Hacks_t { int EECycleRate; bool IOPCycleDouble; - bool WaitCycleExt; + //bool WaitCycleExt; bool INTCSTATSlow; bool IdleLoopFF; int VUCycleSteal; @@ -183,6 +183,8 @@ public: u32 sseVUMXCSR; u32 eeOptions; u32 vuOptions; + + int Blockdump; }; extern PcsxConfig Config; diff --git a/common/include/Utilities/win_memzero.h b/common/include/Utilities/win_memzero.h index 4dddf64ea8..5ca1e1906a 100644 --- a/common/include/Utilities/win_memzero.h +++ b/common/include/Utilities/win_memzero.h @@ -47,26 +47,35 @@ // alignment of the stack at compile time, so I'm forced to use movups to store and // retrieve xmm0. +// MSVC Template Issue: +// MSVC treats int template parameters like macro insertions. That is, if you have a +// a template parameter in the form of "func<10-5>()", MSVC inserts 10-5 into the +// templated function, causing order-of-operation problems (sigh). The normal fix would +// be to assign the template parameter to a static const int inside each function, but that +// won't fly with the enums optimization. So in order to fix the problem I define a macro +// that encapsulates the template parameter inside parenthesis for us: + +#define MZFbytes (_bytes) // This is an implementation of the memzero_ptr fast memset routine (for zero-clears only). -template< size_t bytes > +template< size_t _bytes > static __forceinline void memzero_ptr( void *dest ) { - if( bytes == 0 ) return; + if( MZFbytes == 0 ) return; // This function only works on 32-bit alignments. For anything else we just fall back // on the compiler-provided implementation of memset... - if( (bytes & 0x3) != 0 ) + if( (MZFbytes & 0x3) != 0 ) { - memset( dest, 0, bytes ); + memset( dest, 0, MZFbytes ); return; } enum { - remainder = bytes & 127, - bytes128 = bytes / 128 + remainder = MZFbytes & 127, + bytes128 = MZFbytes / 128 }; // Initial check -- if the length is not a multiple of 16 then fall back on @@ -74,7 +83,7 @@ static __forceinline void memzero_ptr( void *dest ) // manner isn't necessary in pcsx2 (meaning they aren't used in speed-critical // scenarios). - if( (bytes & 0xf) == 0 ) + if( (MZFbytes & 0xf) == 0 ) { u64 _xmm_backup[2]; @@ -177,12 +186,12 @@ static __forceinline void memzero_ptr( void *dest ) } // This function only works on 32-bit alignments. - jASSUME( (bytes & 0x3) == 0 ); + jASSUME( (MZFbytes & 0x3) == 0 ); jASSUME( ((uptr)dest & 0x3) == 0 ); enum { - remdat = bytes>>2 + remdat = MZFbytes >> 2 }; // This case statement handles 5 special-case sizes (small blocks) @@ -247,28 +256,28 @@ static __forceinline void memzero_ptr( void *dest ) } // An optimized memset for 8 bit destination data. -template< u8 data, size_t bytes > +template< u8 data, size_t _bytes > static __forceinline void memset_8( void *dest ) { - if( bytes == 0 ) return; + if( MZFbytes == 0 ) return; - if( (bytes & 0x3) != 0 ) + if( (MZFbytes & 0x3) != 0 ) { // unaligned data length. No point in doing an optimized inline version (too complicated!) // So fall back on the compiler implementation: - memset( dest, data, bytes ); + memset( dest, data, MZFbytes ); return; } //u64 _xmm_backup[2]; - /*static const size_t remainder = bytes & 127; - static const size_t bytes128 = bytes / 128; + /*static const size_t remainder = MZFbytes & 127; + static const size_t bytes128 = MZFbytes / 128; if( bytes128 > 32 ) { // This function only works on 128-bit alignments. - jASSUME( (bytes & 0xf) == 0 ); + jASSUME( (MZFbytes & 0xf) == 0 ); jASSUME( ((uptr)dest & 0xf) == 0 ); __asm @@ -313,11 +322,11 @@ static __forceinline void memset_8( void *dest ) }*/ // This function only works on 32-bit alignments of data copied. - jASSUME( (bytes & 0x3) == 0 ); + jASSUME( (MZFbytes & 0x3) == 0 ); enum { - remdat = bytes>>2, + remdat = MZFbytes >> 2, data32 = data + (data<<8) + (data<<16) + (data<<24) }; @@ -381,31 +390,31 @@ static __forceinline void memset_8( void *dest ) } } -template< u16 data, size_t bytes > +template< u16 data, size_t _bytes > static __forceinline void memset_16( void *dest ) { - if( bytes == 0 ) return; + if( MZFbytes == 0 ) return; - if( (bytes & 0x1) != 0 ) + if( (MZFbytes & 0x1) != 0 ) throw Exception::LogicError( "Invalid parameter passed to memset_16 - data length is not a multiple of 16 or 32 bits." ); - if( (bytes & 0x3) != 0 ) + if( (MZFbytes & 0x3) != 0 ) { // Unaligned data length. No point in doing an optimized inline version (too complicated with // remainders and such). - _memset16_unaligned( dest, data, bytes ); + _memset16_unaligned( dest, data, MZFbytes ); return; } //u64 _xmm_backup[2]; // This function only works on 32-bit alignments of data copied. - jASSUME( (bytes & 0x3) == 0 ); + jASSUME( (MZFbytes & 0x3) == 0 ); enum { - remdat = bytes>>2, + remdat = MZFbytes >> 2, data32 = data + (data<<16) }; @@ -469,12 +478,12 @@ static __forceinline void memset_16( void *dest ) } } -template< u32 data, size_t bytes > +template< u32 data, size_t MZFbytes > static __forceinline void memset_32( void *dest ) { - if( bytes == 0 ) return; + if( MZFbytes == 0 ) return; - if( (bytes & 0x3) != 0 ) + if( (MZFbytes & 0x3) != 0 ) throw Exception::LogicError( "Invalid parameter passed to memset_32 - data length is not a multiple of 32 bits." ); @@ -484,11 +493,11 @@ static __forceinline void memset_32( void *dest ) // If the data length is not a factor of 32 bits, the C++ optimizing compiler will // probably just generate mysteriously broken code in Release builds. ;) - jASSUME( (bytes & 0x3) == 0 ); + jASSUME( (MZFbytes & 0x3) == 0 ); enum { - remdat = bytes>>2, + remdat = MZFbytes>>2, data32 = data }; @@ -582,3 +591,4 @@ static __forceinline void memset32_obj( T& object ) memset_32( &object ); } +#undef MZFbytes diff --git a/common/include/x86emitter/legacy_instructions.h b/common/include/x86emitter/legacy_instructions.h index ad91a6a51f..192601504b 100644 --- a/common/include/x86emitter/legacy_instructions.h +++ b/common/include/x86emitter/legacy_instructions.h @@ -1344,11 +1344,11 @@ extern void SSSE3_PABSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from); #ifndef _MM_MK_INSERTPS_NDX #define _MM_MK_INSERTPS_NDX(srcField, dstField, zeroMask) (((srcField)<<6) | ((dstField)<<4) | (zeroMask)) #endif - extern void SSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); extern void SSE4_DPPS_M128_to_XMM(x86SSERegType to, uptr from, u8 imm8); extern void SSE4_INSERTPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); extern void SSE4_EXTRACTPS_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8); +extern void SSE4_EXTRACTPS_XMM_to_M32(uptr to, x86SSERegType from, u8 imm8); extern void SSE4_BLENDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8); extern void SSE4_BLENDVPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from); extern void SSE4_BLENDVPS_M128_to_XMM(x86SSERegType to, uptr from); diff --git a/common/src/x86emitter/legacy_sse.cpp b/common/src/x86emitter/legacy_sse.cpp index 716da65fed..93bc311d2a 100644 --- a/common/src/x86emitter/legacy_sse.cpp +++ b/common/src/x86emitter/legacy_sse.cpp @@ -364,6 +364,7 @@ emitterT void SSE4_PINSRD_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 im emitterT void SSE4_INSERTPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) { xINSERTPS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } emitterT void SSE4_EXTRACTPS_XMM_to_R32(x86IntRegType to, x86SSERegType from, u8 imm8) { xEXTRACTPS( xRegister32(to), xRegisterSSE(from), imm8 ); } +emitterT void SSE4_EXTRACTPS_XMM_to_M32(uptr to, x86SSERegType from, u8 imm8) { xEXTRACTPS( (u32*)to, xRegisterSSE(from), imm8 ); } emitterT void SSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) { xDP.PS( xRegisterSSE(to), xRegisterSSE(from), imm8 ); } emitterT void SSE4_DPPS_M128_to_XMM(x86SSERegType to, uptr from, u8 imm8) { xDP.PS( xRegisterSSE(to), (void*)from, imm8 ); } diff --git a/nsis/nsis_instructions.txt b/nsis/nsis_instructions.txt new file mode 100644 index 0000000000..a6f995be47 --- /dev/null +++ b/nsis/nsis_instructions.txt @@ -0,0 +1,10 @@ +Instruction for installations: + +Install NSIS (tested with 2.45) +Install NSIS Script Advanced Uninstall Log NSIS Header (you can find it opn NSIS wiki) +Create a folder +Put the nsis script in said folder +Put vcredist_x86.exe in said folder +Put the pcsx2 folder in said folder (warning, leave only the files you want in the installer. All files from the pcsx2 folder will be added to the installer ) +Edit the NSIS script with a text editor, changing the installer name and putting the correct name for the menu item (2 times, both filename and link name) +Compile the NSIS script diff --git a/nsis/pcsx2_installer_script.nsi b/nsis/pcsx2_installer_script.nsi new file mode 100644 index 0000000000..fa4a69b775 --- /dev/null +++ b/nsis/pcsx2_installer_script.nsi @@ -0,0 +1,147 @@ +; Pcsx2 NSIS installer script +; loosely based on a collection of examples and on information from the wikipedia + +!define APP_NAME "Pcsx2 - A Playstation 2 Emulator" +!define INSTDIR_REG_ROOT "HKLM" +!define INSTDIR_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" + +;-------------------------------- +;Include Modern UI 2 and advanced log uninstaller. all credits to the respective authors + + !include "MUI2.nsh" + !include "AdvUninstLog.nsh" + +;-------------------------------- + +; The name of the installer +Name "Pcsx2" + +; The file to write. To change each release +OutFile "Pcsx2-beta-1474-setup.exe" + +; The default installation directory +InstallDir "$PROGRAMFILES\Pcsx2" + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKLM "Software\Pcsx2" "Install_Dir" + +; Request application privileges for Windows Vista +RequestExecutionLevel admin + +; Pages + + !insertmacro UNATTENDED_UNINSTALL + !define MUI_COMPONENTSPAGE_NODESC ;no decription is really necessary at this stage... + !insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_DIRECTORY + !insertmacro MUI_PAGE_INSTFILES + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_COMPONENTS + !insertmacro MUI_UNPAGE_INSTFILES + + +;-------------------------------- + +; Basic section (emulation proper) +Section "Pcsx2 (required)" + + SectionIn RO + + ; Set output path to the installation directory. + SetOutPath $INSTDIR + + ; Put file there. It's catched by the uninstaller script + !insertmacro UNINSTALL.LOG_OPEN_INSTALL + File /r "Pcsx2\" + !insertmacro UNINSTALL.LOG_CLOSE_INSTALL + + ; Write the installation path into the registry + WriteRegStr HKLM Software\Pcsx2 "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2" "DisplayName" "Pcsx2 - Playstation 2 Emulator" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2" "NoRepair" 1 + WriteUninstaller "uninstall.exe" + +SectionEnd + +; Optional sections (can be disabled by the user) +Section "Start Menu Shortcuts" + + ; Need to change name too, for each version + CreateDirectory "$SMPROGRAMS\Pcsx2" + CreateShortCut "$SMPROGRAMS\Pcsx2\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\Pcsx2\Pcsx2.lnk" "$INSTDIR\pcsx2-beta-1474.exe" "" "$INSTDIR\pcsx2-beta-1474.exe" 0 + +SectionEnd + +; Optional, but required if you don't already have it +Section "Microsoft Visual C++ 2008 SP1 Redist(Required)" + + SetOutPath $TEMP + File "vcredist_x86.exe" + ExecWait "$TEMP\vcredist_x86.exe" + +SectionEnd + +;-------------------------------- + +Function .onInit + + ;prepare log always within .onInit function + !insertmacro UNINSTALL.LOG_PREPARE_INSTALL + +FunctionEnd + + +Function .onInstSuccess + + ;create/update log always within .onInstSuccess function + !insertmacro UNINSTALL.LOG_UPDATE_INSTALL + +FunctionEnd + +;-------------------------------- + + + +; Uninstaller + +Section "Un.Standard uninstallation (Leaves user created files untouched)" + + ; Remove registry keys + DeleteRegKey HKLM Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2 + DeleteRegKey HKLM Software\Pcsx2 + + ; Remove shortcuts, if any + Delete "$SMPROGRAMS\Pcsx2\*.*" + RMDir "$SMPROGRAMS\Pcsx2" + + !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR" + DeleteRegKey ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" + +SectionEnd + +; This option lets you COMPLETELY uninstall by deleting the main folder. Caution! :) +Section /o "Un.Complete Uninstall. WARNING, this will delete every file in the program folder" + + MessageBox MB_YESNO "You have chosen to remove ALL files in the installation folder. This will remove all your saves, screenshots, patches and bios as well. Do you want to proceed?" IDYES true IDNO false + true: + Delete "$SMPROGRAMS\Pcsx2\*.*" + RMDir "$SMPROGRAMS\Pcsx2" + RMDir /r "$INSTDIR" + DeleteRegKey ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" + false: + +SectionEnd + +Function UN.onInit + + ;begin uninstall, could be added on top of uninstall section instead + !insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL + +FunctionEnd \ No newline at end of file diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index 0d546da1de..c93c224fce 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -1,1988 +1,1951 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2009 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "PrecompiledHeader.h" - -#include -#include - -#include "IopCommon.h" -#include "CDVDiso.h" -#include "CDVD_internal.h" - -static cdvdStruct cdvd; - -static __forceinline void SetResultSize(u8 size) -{ - cdvd.ResultC = size; - cdvd.ResultP = 0; - cdvd.sDataIn&=~0x40; -} - -static void CDVDREAD_INT(int eCycle) -{ - PSX_INT(IopEvt_CdvdRead, eCycle); -} - -static void CDVD_INT(int eCycle) -{ - if( eCycle == 0 ) - cdvdActionInterrupt(); - else - PSX_INT(IopEvt_Cdvd, eCycle); -} - -// Sets the cdvd IRQ and the reason for the IRQ, and signals the IOP for a branch -// test (which will cause the exception to be handled). -static void cdvdSetIrq( uint id = (1<FullpathToBios().ToAscii().data() ); - - ptr = file; - i = (int)strlen(file); - - while (i > 0) { if (ptr[i] == '.') break; i--; } - ptr[i+1] = '\0'; - strcat(file, "MEC"); - - // if file doesnt exist, create empty one - fd = fopen(file, "r+b"); - if (fd == NULL) { - Console::Notice("MEC File Not Found , Creating Blank File"); - fd = fopen(file, "wb"); - if (fd == NULL) - { - Console::Error( "\tMEC File Creation failed!" ); - throw Exception::CreateStream( file ); - //Msgbox::Alert( "_cdvdOpenMechaVer: Error creating %s", params file); - //exit(1); - } - - fputc(0x03, fd); - fputc(0x06, fd); - fputc(0x02, fd); - fputc(0x00, fd); - } - return fd; -} - -s32 cdvdGetMechaVer(u8* ver) -{ - FILE* fd = _cdvdOpenMechaVer(); - if (fd == NULL) return 1; - fseek(fd, 0, SEEK_SET); - fread(ver, 1, 4, fd); - fclose(fd); - return 0; -} - -FILE *_cdvdOpenNVM() { - char *ptr; - int i; - char file[g_MaxPath]; - FILE* fd; - - // get the name of the bios file - - // use the bios filename to get the name of the nvm file - // [TODO] : Upgrade this to use std::string! - - strcpy( file, g_Conf->FullpathToBios().ToAscii().data() ); - ptr = file; - i = (int)strlen(file); - - while (i > 0) { if (ptr[i] == '.') break; i--; } - ptr[i+1] = '\0'; - - strcat(file, "NVM"); - - // if file doesnt exist, create empty one - fd = fopen(file, "r+b"); - if (fd == NULL) { - Console::Notice("NVM File Not Found , Creating Blank File"); - fd = fopen(file, "wb"); - if (fd == NULL) - { - throw Exception::CreateStream( file ); - //Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file); - //exit(1); - } - for (i=0; i<1024; i++) fputc(0, fd); - } - return fd; -} - -// -// the following 'cdvd' functions all return 0 if successful -// - -s32 cdvdReadNVM(u8 *dst, int offset, int bytes) { - FILE* fd = _cdvdOpenNVM(); - if (fd == NULL) return 1; - - fseek(fd, offset, SEEK_SET); - fread(dst, 1, bytes, fd); - fclose(fd); - - return 0; -} -s32 cdvdWriteNVM(const u8 *src, int offset, int bytes) { - FILE* fd = _cdvdOpenNVM(); - if (fd == NULL) return 1; - - fseek(fd, offset, SEEK_SET); - fwrite(src, 1, bytes, fd); - fclose(fd); - - return 0; -} - -NVMLayout* getNvmLayout(void) -{ - NVMLayout* nvmLayout = NULL; - s32 nvmIdx; - - for(nvmIdx=0; nvmIdx= cdvd.CNumBlocks) - return 1; - else if( - ((cdvd.COffset == 0) && (cdvd.CBlockIndex >= 4))|| - ((cdvd.COffset == 1) && (cdvd.CBlockIndex >= 2))|| - ((cdvd.COffset == 2) && (cdvd.CBlockIndex >= 7)) - ) - { - memzero_ptr<16>(config); - return 0; - } - - // get config data - switch (cdvd.COffset) - { - case 0: - return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config0)); - break; - case 2: - return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2)); - break; - default: - return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1)); - } -} -s32 cdvdWriteConfig(const u8* config) -{ - // make sure its in write mode - if(cdvd.CReadWrite != 1) - return 1; - // check if block index is in bounds - else if(cdvd.CBlockIndex >= cdvd.CNumBlocks) - return 1; - else if( - ((cdvd.COffset == 0) && (cdvd.CBlockIndex >= 4))|| - ((cdvd.COffset == 1) && (cdvd.CBlockIndex >= 2))|| - ((cdvd.COffset == 2) && (cdvd.CBlockIndex >= 7)) - ) - return 0; - - // get config data - switch (cdvd.COffset) - { - case 0: - return setNvmData(config, (cdvd.CBlockIndex++)*16, 16,offsetof(NVMLayout, config0)); - break; - case 2: - return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2)); - break; - default: - return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1)); - } -} - - -void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) { - wxString fname; - char exeName[12]; - s32 numbers, letters; - u32 key_0_3; - u8 key_4, key_14; - - // get main elf name - GetPS2ElfName(fname); - const wxCharBuffer crap( fname.ToAscii() ); - const char* str = crap.data(); - sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]); - DevCon::Notice("exeName = %s", params &str[8]); - - // convert the number characters to a real 32bit number - numbers = ((((exeName[5] - '0'))*10000) + - (((exeName[ 6] - '0'))*1000) + - (((exeName[ 7] - '0'))*100) + - (((exeName[ 9] - '0'))*10) + - (((exeName[10] - '0'))*1) ); - - // combine the lower 7 bits of each char - // to make the 4 letters fit into a single u32 - letters = (s32)((exeName[3]&0x7F)<< 0) | - (s32)((exeName[2]&0x7F)<< 7) | - (s32)((exeName[1]&0x7F)<<14) | - (s32)((exeName[0]&0x7F)<<21); - - // calculate magic numbers - key_0_3 = ((numbers & 0x1FC00) >> 10) | ((0x01FFFFFF & letters) << 7); // numbers = 7F letters = FFFFFF80 - key_4 = ((numbers & 0x0001F) << 3) | ((0x0E000000 & letters) >> 25); // numbers = F8 letters = 07 - key_14 = ((numbers & 0x003E0) >> 2) | 0x04; // numbers = F8 extra = 04 unused = 03 - - // clear key values - memzero_ptr<16>(key); - - // store key values - key[ 0] = (key_0_3&0x000000FF)>> 0; - key[ 1] = (key_0_3&0x0000FF00)>> 8; - key[ 2] = (key_0_3&0x00FF0000)>>16; - key[ 3] = (key_0_3&0xFF000000)>>24; - key[ 4] = key_4; - - if(arg2 == 75) - { - key[14] = key_14; - key[15] = 0x05; - } - else if(arg2 == 3075) - { - key[15] = 0x01; - } - else if(arg2 == 4246) - { - // 0x0001F2F707 = sector 0x0001F2F7 dec 0x07 - key[ 0] = 0x07; - key[ 1] = 0xF7; - key[ 2] = 0xF2; - key[ 3] = 0x01; - key[ 4] = 0x00; - key[15] = 0x01; - } - else - { - key[15] = 0x01; - } - - Console::WriteLn( "CDVD.KEY = %02X,%02X,%02X,%02X,%02X,%02X,%02X", params - cdvd.Key[0],cdvd.Key[1],cdvd.Key[2],cdvd.Key[3],cdvd.Key[4],cdvd.Key[14],cdvd.Key[15] ); - - // Now's a good time to reload the ELF info... - if( ElfCRC == 0 ) - { - ElfCRC = loadElfCRC( str ); - ElfApplyPatches(); - GSsetGameCRC( ElfCRC, 0 ); - } -} - -s32 cdvdGetToc(void* toc) -{ - s32 ret = CDVDgetTOC(toc); - if (ret == -1) ret = 0x80; - return ret; -} - -s32 cdvdReadSubQ(s32 lsn, cdvdSubQ* subq) -{ - s32 ret = CDVDreadSubQ(lsn, subq); - if (ret == -1) ret = 0x80; - return ret; -} - -s32 cdvdCtrlTrayOpen() -{ - s32 ret = CDVDctrlTrayOpen(); - if (ret == -1) ret = 0x80; - return ret; -} - -s32 cdvdCtrlTrayClose() -{ - s32 ret = CDVDctrlTrayClose(); - if (ret == -1) ret = 0x80; - return ret; -} - -// Modified by (efp) - 16/01/2006 -// checks if tray was opened since last call to this func -s32 cdvdGetTrayStatus() -{ - s32 ret = CDVDgetTrayStatus(); - - if (ret == -1) - return(CDVD_TRAY_CLOSE); - else - return(ret); -} - -// Note: Is tray status being kept as a var here somewhere? -// cdvdNewDiskCB() can update it's status as well... - -// Modified by (efp) - 16/01/2006 -static __forceinline void cdvdGetDiskType() -{ - // defs 0.9.0 - if (CDVDnewDiskCB || (cdvd.Type != CDVD_TYPE_NODISC)) return; - - // defs.0.8.1 - if (cdvdGetTrayStatus() == CDVD_TRAY_OPEN) - { - cdvd.Type = CDVD_TYPE_NODISC; - return; - } - - cdvd.Type = CDVDgetDiskType(); - - // Is the type listed as a PS2 CD? - if (cdvd.Type == CDVD_TYPE_PS2CD) // && needReset == 1) - { - wxString str; - - if (GetPS2ElfName(str) == 1) - { - // Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then. - cdvd.Type = CDVD_TYPE_PSCD; - } - } -} - -// check whether disc is single or dual layer -// if its dual layer, check what the disctype is and what sector number -// layer1 starts at -// -// args: gets value for dvd type (0=single layer, 1=ptp, 2=otp) -// gets value for start lsn of layer1 -// returns: 1 if on dual layer disc -// 0 if not on dual layer disc -static s32 cdvdReadDvdDualInfo(s32* dualType, u32* layer1Start) -{ - u8 toc[2064]; - *dualType = 0; - *layer1Start = 0; - - // if error getting toc, settle for single layer disc ;) - if(cdvdGetToc(toc)) - return 0; - if(toc[14] & 0x60) - { - if(toc[14] & 0x10) - { - // otp dvd - *dualType = 2; - *layer1Start = (toc[25]<<16) + (toc[26]<<8) + (toc[27]) - 0x30000 + 1; - } - else - { - // ptp dvd - *dualType = 1; - *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; - } - } - else - { - // single layer dvd - *dualType = 0; - *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; - } - - return 1; -} - -static uint cdvdBlockReadTime( CDVD_MODE_TYPE mode ) -{ - return (PSXCLK * cdvd.BlockSize) / (((mode==MODE_CDROM) ? PSX_CD_READSPEED : PSX_DVD_READSPEED) * cdvd.Speed); -} - -void cdvdReset() -{ - memzero_obj(cdvd); - - cdvd.Type = CDVD_TYPE_NODISC; - cdvd.Spinning = false; - - cdvd.sDataIn = 0x40; - cdvd.Ready = CDVD_READY2; - cdvd.Speed = 4; - cdvd.BlockSize = 2064; - cdvd.Action = cdvdAction_None; - cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); - - wxDateTime curtime( wxDateTime::GetTimeNow() ); - cdvd.RTC.second = (u8)curtime.GetSecond(); - cdvd.RTC.minute = (u8)curtime.GetMinute(); - cdvd.RTC.hour = (u8)(curtime.GetHour()+1) % 24; - cdvd.RTC.day = (u8)curtime.GetDay(); - cdvd.RTC.month = (u8)curtime.GetMonth(); - cdvd.RTC.year = (u8)(curtime.GetYear() - 2000); -} - -struct Freeze_v10Compat -{ - u8 Action; - u32 SeekToSector; - u32 ReadTime; - bool Spinning; -}; - -void SaveState::cdvdFreeze() -{ - FreezeTag( "cdvd" ); - Freeze( cdvd ); - - if (IsLoading()) - { - // Make sure the Cdvd plugin has the expected track loaded into the buffer. - // If cdvd.Readed is cleared it means we need to load the SeekToSector (ie, a - // seek is in progress!) - - if( cdvd.Reading ) - cdvd.RErr = CDVDreadTrack( cdvd.Readed ? cdvd.Sector : cdvd.SeekToSector, cdvd.ReadMode); - } -} - -// Modified by (efp) - 16/01/2006 -void cdvdNewDiskCB() -{ - cdvd.Type = CDVDgetDiskType(); - - wxString str; - int result = GetPS2ElfName(str); - - if (cdvd.Type == CDVD_TYPE_PS2CD) - { - - // Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then. - if(result == 1) cdvd.Type = CDVD_TYPE_PSCD; - } - - // Now's a good time to reload the ELF info... - if( ElfCRC == 0 ) - { - ElfCRC = loadElfCRC( str.ToAscii().data() ); - ElfApplyPatches(); - GSsetGameCRC( ElfCRC, 0 ); - } - -} - -void mechaDecryptBytes( u32 madr, int size ) -{ - int i; - - int shiftAmount = (cdvd.decSet>>4) & 7; - int doXor = (cdvd.decSet) & 1; - int doShift = (cdvd.decSet) & 2; - - u8* curval = iopPhysMem( madr ); - for( i=0; i> shiftAmount) | (*curval << (8-shiftAmount) ); - } -} - -int cdvdReadSector() { - s32 bcr; - - CDR_LOG("SECTOR %d (BCR %x;%x)", cdvd.Sector, HW_DMA3_BCR_H16, HW_DMA3_BCR_L16); - - bcr = (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4; - if (bcr < cdvd.BlockSize) { - CDR_LOG( "READBLOCK: bcr < cdvd.BlockSize; %x < %x", bcr, cdvd.BlockSize ); - if (HW_DMA3_CHCR & 0x01000000) { - HW_DMA3_CHCR &= ~0x01000000; - psxDmaInterrupt(3); - } - return -1; - } - - // DMAs use physical addresses (air) - u8* mdest = iopPhysMem( HW_DMA3_MADR ); - - // if raw dvd sector 'fill in the blanks' - if (cdvd.BlockSize == 2064) - { - // get info on dvd type and layer1 start - u32 layer1Start; - s32 dualType; - s32 layerNum; - u32 lsn = cdvd.Sector; - - cdvdReadDvdDualInfo(&dualType, &layer1Start); - - if((dualType == 1) && (lsn >= layer1Start)) - { - // dual layer ptp disc - layerNum = 1; - lsn = lsn-layer1Start + 0x30000; - } - else if((dualType == 2) && (lsn >= layer1Start)) - { - // dual layer otp disc - layerNum = 1; - lsn = ~(layer1Start+0x30000 - 1); - } - else - { // Assumed the other dualType is 0. - // single layer disc - // or on first layer of dual layer disc - layerNum = 0; - lsn += 0x30000; - } - - mdest[0] = 0x20 | layerNum; - mdest[1] = (u8)(lsn >> 16); - mdest[2] = (u8)(lsn >> 8); - mdest[3] = (u8)(lsn ); - - // sector IED (not calculated at present) - mdest[4] = 0; - mdest[5] = 0; - - // sector CPR_MAI (not calculated at present) - mdest[6] = 0; - mdest[7] = 0; - mdest[8] = 0; - mdest[9] = 0; - mdest[10] = 0; - mdest[11] = 0; - - // normal 2048 bytes of sector data - memcpy_fast( &mdest[12], cdr.pTransfer, 2048); - - // 4 bytes of edc (not calculated at present) - mdest[2060] = 0; - mdest[2061] = 0; - mdest[2062] = 0; - mdest[2063] = 0; - } - else - { - memcpy_fast( mdest, cdr.pTransfer, cdvd.BlockSize); - } - - // decrypt sector's bytes - if( cdvd.decSet ) mechaDecryptBytes( HW_DMA3_MADR, cdvd.BlockSize ); - - // Added a clear after memory write .. never seemed to be necessary before but *should* - // be more correct. (air) - psxCpu->Clear( HW_DMA3_MADR, cdvd.BlockSize/4 ); - -// Console::WriteLn("sector %x;%x;%x", params PSXMu8(madr+0), PSXMu8(madr+1), PSXMu8(madr+2)); - - HW_DMA3_BCR_H16 -= (cdvd.BlockSize / (HW_DMA3_BCR_L16*4)); - HW_DMA3_MADR += cdvd.BlockSize; - - return 0; -} - -// inlined due to being referenced in only one place. -__forceinline void cdvdActionInterrupt() -{ - switch( cdvd.Action ) - { - case cdvdAction_Seek: - case cdvdAction_Standby: - cdvd.Spinning = true; - cdvd.Ready = CDVD_READY1; - cdvd.Sector = cdvd.SeekToSector; - cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; - break; - - case cdvdAction_Stop: - cdvd.Spinning = false; - cdvd.Ready = CDVD_READY1; - cdvd.Sector = 0; - cdvd.Status = CDVD_STATUS_NONE; - break; - - case cdvdAction_Break: - // Make sure the cdvd action state is pretty well cleared: - cdvd.Reading = 0; - cdvd.Readed = 0; - cdvd.Ready = CDVD_READY2; // should be CDVD_READY1 or something else? - cdvd.Status = CDVD_STATUS_NONE; - cdvd.RErr = 0; - cdvd.nCommand = 0; - break; - } - cdvd.Action = cdvdAction_None; - - cdvd.PwOff |= 1< Scheduling block read interrupt at iopcycle=%8.8x.", - psxRegs.cycle + cdvd.ReadTime ); - - CDVDREAD_INT(cdvd.ReadTime); - return; - } - else - { - if (cdvd.RErr == 0) - cdr.pTransfer = CDVDgetBuffer(); - else - cdr.pTransfer = NULL; - - if (cdr.pTransfer == NULL) - { - cdvd.RetryCntP++; - Console::Error("CDVD READ ERROR, sector=%d", params cdvd.Sector); - - if (cdvd.RetryCntP <= cdvd.RetryCnt) - { - cdvd.RErr = CDVDreadTrack(cdvd.Sector, cdvd.ReadMode); - CDVDREAD_INT(cdvd.ReadTime); - return; - } - } - cdvd.Reading = false; - } - - if (cdvdReadSector() == -1) - { - assert((int)cdvd.ReadTime > 0 ); - CDVDREAD_INT(cdvd.ReadTime); - return; - } - - cdvd.Sector++; - - if (--cdvd.nSectors <= 0) - { - cdvd.PwOff |= 1< Simulating CdRom Spinup Time, and seek to sector %d", cdvd.SeekToSector ); - seektime = PSXCLK / 3; // 333ms delay - cdvd.Spinning = true; - } - else if( (tbl_ContigiousSeekDelta[mode] == 0) || (delta >= tbl_ContigiousSeekDelta[mode]) ) - { - // Select either Full or Fast seek depending on delta: - - if( delta >= tbl_FastSeekDelta[mode] ) - { - // Full Seek - CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FULL]", cdvd.SeekToSector, cdvd.Sector, delta ); - seektime = Cdvd_FullSeek_Cycles; - } - else - { - CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FAST]", cdvd.SeekToSector, cdvd.Sector, delta ); - seektime = Cdvd_FastSeek_Cycles; - } - } - else - { - CDR_LOG( "CdSeek Begin > Contiguous block without seek - delta=%d sectors", delta ); - - // seektime is the time it takes to read to the destination block: - seektime = delta * cdvd.ReadTime; - - if( delta == 0 ) - { - cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; - cdvd.Readed = 1; // Note: 1, not 0, as implied by the next comment. Need to look into this. --arcum42 - cdvd.RetryCntP = 0; - - // setting Readed to 0 skips the seek logic, which means the next call to - // cdvdReadInterrupt will load a block. So make sure it's properly scheduled - // based on sector read speeds: - - seektime = cdvd.ReadTime; - } - } - - return seektime; -} - -u8 monthmap[13] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -void cdvdVsync() { - cdvd.RTCcount++; - if (cdvd.RTCcount < ((Config.PsxType & 1) ? 50 : 60)) return; - cdvd.RTCcount = 0; - - cdvd.RTC.second++; - if (cdvd.RTC.second < 60) return; - cdvd.RTC.second = 0; - - cdvd.RTC.minute++; - if (cdvd.RTC.minute < 60) return; - cdvd.RTC.minute = 0; - - cdvd.RTC.hour++; - if (cdvd.RTC.hour < 24) return; - cdvd.RTC.hour = 0; - - cdvd.RTC.day++; - if (cdvd.RTC.day <= monthmap[cdvd.RTC.month-1]) return; - cdvd.RTC.day = 1; - - cdvd.RTC.month++; - if (cdvd.RTC.month <= 12) return; - cdvd.RTC.month = 1; - - cdvd.RTC.year++; - if (cdvd.RTC.year < 100) return; - cdvd.RTC.year = 0; -} - -static __forceinline u8 cdvdRead18(void) // SDATAOUT -{ - u8 ret = 0; - - if (((cdvd.sDataIn & 0x40) == 0) && (cdvd.ResultP < cdvd.ResultC)) - { - cdvd.ResultP++; - if (cdvd.ResultP >= cdvd.ResultC) cdvd.sDataIn|= 0x40; - ret = cdvd.Result[cdvd.ResultP-1]; - } - CDR_LOG("cdvdRead18(SDataOut) %x (ResultC=%d, ResultP=%d)", ret, cdvd.ResultC, cdvd.ResultP); - - return ret; -} - -u8 cdvdRead(u8 key) -{ - switch (key) - { - case 0x04: // NCOMMAND - CDR_LOG("cdvdRead04(NCMD) %x", cdvd.nCommand); - return cdvd.nCommand; - break; - - case 0x05: // N-READY - CDR_LOG("cdvdRead05(NReady) %x", cdvd.Ready); - return cdvd.Ready; - break; - - case 0x06: // ERROR - CDR_LOG("cdvdRead06(Error) %x", cdvd.Error); - return cdvd.Error; - break; - - case 0x07: // BREAK - CDR_LOG("cdvdRead07(Break) %x", 0); - return 0; - break; - - case 0x08: // STATUS - CDR_LOG("cdvdRead0A(Status) %x", cdvd.Status); - return cdvd.Status; - break; - - case 0x0A: // STATUS - CDR_LOG("cdvdRead0A(Status) %x", cdvd.Status); - return cdvd.Status; - break; - - case 0x0B: // TRAY-STATE (if tray has been opened) - { - u8 tray = cdvdGetTrayStatus(); - CDR_LOG("cdvdRead0B(Tray) %x", tray); - return tray; - break; - } - case 0x0C: // CRT MINUTE - CDR_LOG("cdvdRead0C(Min) %x", itob((u8)(cdvd.Sector/(60*75)))); - return itob((u8)(cdvd.Sector/(60*75))); - break; - - case 0x0D: // CRT SECOND - CDR_LOG("cdvdRead0D(Sec) %x", itob((u8)((cdvd.Sector/75)%60)+2)); - return itob((u8)((cdvd.Sector/75)%60)+2); - break; - - case 0x0E: // CRT FRAME - CDR_LOG("cdvdRead0E(Frame) %x", itob((u8)(cdvd.Sector%75))); - return itob((u8)(cdvd.Sector%75)); - break; - - case 0x0F: // TYPE - CDR_LOG("cdvdRead0F(Disc Type) %x", cdvd.Type); - cdvdGetDiskType(); - return cdvd.Type; - break; - - case 0x13: // UNKNOWN - CDR_LOG("cdvdRead13(Unknown) %x", 4); - return 4; - break; - - case 0x15: // RSV - CDR_LOG("cdvdRead15(RSV)"); - return 0x01; // | 0x80 for ATAPI mode - break; - - case 0x16: // SCOMMAND - CDR_LOG("cdvdRead16(SCMD) %x", cdvd.sCommand); - return cdvd.sCommand; - break; - - case 0x17: // SREADY - CDR_LOG("cdvdRead17(SReady) %x", cdvd.sDataIn); - return cdvd.sDataIn; - break; - - case 0x18: - return cdvdRead18(); - break; - - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - { - int temp = key - 0x20; - - CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); - return cdvd.Key[temp]; - break; - } - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - { - int temp = key - 0x23; - - CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); - return cdvd.Key[temp]; - break; - } - - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - { - int temp = key - 0x26; - - CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); - return cdvd.Key[temp]; - break; - } - - case 0x38: // valid parts of key data (first and last are valid) - CDR_LOG("cdvdRead38(KeysValid) %x", cdvd.Key[15]); - - return cdvd.Key[15]; - break; - - case 0x39: // KEY-XOR - CDR_LOG("cdvdRead39(KeyXor) %x", cdvd.KeyXor); - - return cdvd.KeyXor; - break; - - case 0x3A: // DEC_SET - CDR_LOG("cdvdRead3A(DecSet) %x", cdvd.decSet); - - Console::WriteLn("DecSet Read: %02X", params cdvd.decSet); - return cdvd.decSet; - break; - - default: - // note: notify the console since this is a potentially serious emulation problem: - PSXHW_LOG("*Unknown 8bit read at address 0x1f4020%x", key); - Console::Error( "IOP Unknown 8bit read from addr 0x1f4020%x", params key ); - return 0; - break; - } -} - -static void cdvdWrite04(u8 rt) { // NCOMMAND - CDR_LOG("cdvdWrite04: NCMD %s (%x) (ParamP = %x)", nCmdName[rt], rt, cdvd.ParamP); - - cdvd.nCommand = rt; - cdvd.Status = CDVD_STATUS_NONE; - cdvd.PwOff = Irq_None; // good or bad? - - switch (rt) { - case N_CD_SYNC: // CdSync - case N_CD_NOP: // CdNop_ - cdvdSetIrq(); - break; - - case N_CD_STANDBY: // CdStandby - - // Seek to sector zero. The cdvdStartSeek function will simulate - // spinup times if needed. - - DevCon::Notice( "CdStandby : %d", params rt ); - cdvd.Action = cdvdAction_Standby; - cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); - CDVD_INT( cdvdStartSeek( 0, MODE_DVDROM ) ); - break; - - case N_CD_STOP: // CdStop - DevCon::Notice( "CdStop : %d", params rt ); - cdvd.Action = cdvdAction_Stop; - CDVD_INT( PSXCLK / 6 ); // 166ms delay? - break; - - // from an emulation point of view there is not much need to do anything for this one - case N_CD_PAUSE: // CdPause - cdvdSetIrq(); - break; - - case N_CD_SEEK: // CdSeek - cdvd.Action = cdvdAction_Seek; - cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); - CDVD_INT( cdvdStartSeek( *(uint*)(cdvd.Param+0), MODE_DVDROM ) ); - break; - - case N_CD_READ: // CdRead - cdvd.SeekToSector = *(uint*)(cdvd.Param+0); - cdvd.nSectors = *(int*)(cdvd.Param+4); - cdvd.RetryCnt = (cdvd.Param[8] == 0) ? 0x100 : cdvd.Param[8]; - cdvd.SpindlCtrl = cdvd.Param[9]; - cdvd.Speed = 24; - switch (cdvd.Param[10]) { - case 2: cdvd.ReadMode = CDVD_MODE_2340; cdvd.BlockSize = 2340; break; - case 1: cdvd.ReadMode = CDVD_MODE_2328; cdvd.BlockSize = 2328; break; - case 0: - default: cdvd.ReadMode = CDVD_MODE_2048; cdvd.BlockSize = 2048; break; - } - - CDR_LOG( "CdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)", - cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); - - if( Config.cdvdPrint ) - Console::WriteLn("CdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", - params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); - - cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); - CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector,MODE_CDROM ) ); - - // Read-ahead by telling the plugin about the track now. - // This helps improve performance on actual from-cd emulation - // (ie, not using the hard drive) - cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); - - // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contiguous then - // this'll skip the seek delay. - cdvd.Reading = 1; - break; - - case N_CD_READ_CDDA: // CdReadCDDA - case N_CD_READ_XCDDA: // CdReadXCDDA - cdvd.SeekToSector = *(int*)(cdvd.Param+0); - cdvd.nSectors = *(int*)(cdvd.Param+4); - - if (cdvd.Param[8] == 0) - cdvd.RetryCnt = 0x100; - else - cdvd.RetryCnt = cdvd.Param[8]; - - cdvd.SpindlCtrl = cdvd.Param[9]; - - switch (cdvd.Param[9]) { - case 0x01: cdvd.Speed = 1; break; - case 0x02: cdvd.Speed = 2; break; - case 0x03: cdvd.Speed = 4; break; - case 0x04: cdvd.Speed = 12; break; - default: cdvd.Speed = 24; break; - } - - switch (cdvd.Param[10]) { - case 1: cdvd.ReadMode = CDVD_MODE_2368; cdvd.BlockSize = 2368; break; - case 2: - case 0: cdvd.ReadMode = CDVD_MODE_2352; cdvd.BlockSize = 2352; break; - } - - CDR_LOG( "CdReadCDDA > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%xx(%x), ReadMode=%x(%x) (1074=%x)", - cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); - - if( Config.cdvdPrint ) - Console::WriteLn("CdAudioRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", - params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); - - cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); - CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_CDROM ) ); - - // Read-ahead by telling the plugin about the track now. - // This helps improve performance on actual from-cd emulation - // (ie, not using the hard drive) - cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); - - // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contiguous then - // this'll skip the seek delay. - cdvd.Reading = 1; - break; - - case N_DVD_READ: // DvdRead - cdvd.SeekToSector = *(int*)(cdvd.Param+0); - cdvd.nSectors = *(int*)(cdvd.Param+4); - - if (cdvd.Param[8] == 0) - cdvd.RetryCnt = 0x100; - else - cdvd.RetryCnt = cdvd.Param[8]; - - cdvd.SpindlCtrl = cdvd.Param[9]; - cdvd.Speed = 4; - cdvd.ReadMode = CDVD_MODE_2048; - cdvd.BlockSize = 2064; // Why oh why was it 2064 - - CDR_LOG( "DvdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)", - cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); - - if( Config.cdvdPrint ) - Console::WriteLn("DvdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", - params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); - - cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); - CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_DVDROM ) ); - - // Read-ahead by telling the plugin about the track now. - // This helps improve performance on actual from-cd emulation - // (ie, not using the hard drive) - cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); - - // Set the reading block flag. If a seek is pending then Readed will - // take priority in the handler anyway. If the read is contiguous then - // this'll skip the seek delay. - cdvd.Reading = 1; - break; - - case N_CD_GET_TOC: // CdGetToc & cdvdman_call19 - //Param[0] is 0 for CdGetToc and any value for cdvdman_call19 - //the code below handles only CdGetToc! - //if(cdvd.Param[0]==0x01) - //{ - DevCon::WriteLn("CDGetToc Param[0]=%d, Param[1]=%d", params cdvd.Param[0],cdvd.Param[1]); - //} - cdvdGetToc( iopPhysMem( HW_DMA3_MADR ) ); - cdvdSetIrq( (1< remote key code - SetResultSize(5); - cdvd.Result[0] = 0x00; - cdvd.Result[1] = 0x14; - cdvd.Result[2] = 0x00; - cdvd.Result[3] = 0x00; - cdvd.Result[4] = 0x00; - break; - -// case 0x1F: // sceRemote2_7 (2:1) - cdvdman_call117 -// break; - - case 0x20: // sceRemote2_6 (0:3) // 00 01 00 - SetResultSize(3); - cdvd.Result[0] = 0x00; - cdvd.Result[1] = 0x01; - cdvd.Result[2] = 0x00; - break; - -// case 0x21: // sceCdWriteWakeUpTime (8:1) -// break; - - case 0x22: // sceCdReadWakeUpTime (0:10) - SetResultSize(10); - cdvd.Result[0] = 0; - cdvd.Result[1] = 0; - cdvd.Result[2] = 0; - cdvd.Result[3] = 0; - cdvd.Result[4] = 0; - cdvd.Result[5] = 0; - cdvd.Result[6] = 0; - cdvd.Result[7] = 0; - cdvd.Result[8] = 0; - cdvd.Result[9] = 0; - break; - - case 0x24: // sceCdRCBypassCtrl (1:1) - In V10 Bios - // FIXME: because PRId<0x23, the bit 0 of sio2 don't get updated 0xBF808284 - SetResultSize(1); - cdvd.Result[0] = 0; - break; - -// case 0x25: // cdvdman_call120 (1:1) - In V10 Bios -// break; - -// case 0x26: // cdvdman_call128 (0,3) - In V10 Bios -// break; - -// case 0x27: // cdvdman_call148 (0:13) - In V10 Bios -// break; - -// case 0x28: // cdvdman_call150 (1:1) - In V10 Bios -// break; - - case 0x29: //sceCdNoticeGameStart (1:1) - SetResultSize(1); - cdvd.Result[0] = 0; - break; - -// case 0x2C: //sceCdXBSPowerCtl (2:2) -// break; - -// case 0x2D: //sceCdXLEDCtl (2:2) -// break; - -// case 0x2E: //sceCdBuzzerCtl (0:1) -// break; - -// case 0x2F: //cdvdman_call167 (16:1) -// break; - -// case 0x30: //cdvdman_call169 (1:9) -// break; - - case 0x31: //sceCdSetMediumRemoval (1:1) - SetResultSize(1); - cdvd.Result[0] = 0; - break; - - case 0x32: //sceCdGetMediumRemoval (0:2) - SetResultSize(2); - cdvd.Result[0] = 0; - //cdvd.Result[0] = 0; // fixme: I'm pretty sure that the same variable shouldn't be set twice here. Perhaps cdvd.Result[1]? - break; - -// case 0x33: //sceCdXDVRPReset (1:1) -// break; - - case 0x36: //cdvdman_call189 [__sceCdReadRegionParams - made up name] (0:15) i think it is 16, not 15 - SetResultSize(15); - - cdvdGetMechaVer(&cdvd.Result[1]); - cdvd.Result[0] = cdvdReadRegionParams(&cdvd.Result[3]);//size==8 - Console::WriteLn("REGION PARAMS = %s %s", params mg_zones[cdvd.Result[1]], &cdvd.Result[3]); - cdvd.Result[1] = 1 << cdvd.Result[1]; //encryption zone; see offset 0x1C in encrypted headers - ////////////////////////////////////////// - cdvd.Result[2] = 0; //?? -// cdvd.Result[3] == ROMVER[4] == *0xBFC7FF04 -// cdvd.Result[4] == OSDVER[4] == CAP Jjpn, Aeng, Eeng, Heng, Reng, Csch, Kkor? -// cdvd.Result[5] == OSDVER[5] == small -// cdvd.Result[6] == OSDVER[6] == small -// cdvd.Result[7] == OSDVER[7] == small -// cdvd.Result[8] == VERSTR[0x22] == *0xBFC7FF52 -// cdvd.Result[9] == DVDID J U O E A R C M -// cdvd.Result[10]== 0; //?? - cdvd.Result[11] = 0; //?? - cdvd.Result[12] = 0; //?? - ////////////////////////////////////////// - cdvd.Result[13] = 0; //0xFF - 77001 - cdvd.Result[14] = 0; //?? - break; - - case 0x37: //called from EECONF [sceCdReadMAC - made up name] (0:9) - SetResultSize(9); - cdvd.Result[0] = cdvdReadMAC(&cdvd.Result[1]); - break; - - case 0x38: //used to fix the MAC back after accidentally trashed it :D [sceCdWriteMAC - made up name] (8:1) - SetResultSize(1); - cdvd.Result[0] = cdvdWriteMAC(&cdvd.Param[0]); - break; - - case 0x3E: //[__sceCdWriteRegionParams - made up name] (15:1) [Florin: hum, i was expecting 14:1] - SetResultSize(1); - cdvd.Result[0] = cdvdWriteRegionParams(&cdvd.Param[2]); - break; - - case 0x40: // CdOpenConfig (3:1) - SetResultSize(1); - cdvd.CReadWrite = cdvd.Param[0]; - cdvd.COffset = cdvd.Param[1]; - cdvd.CNumBlocks = cdvd.Param[2]; - cdvd.CBlockIndex= 0; - cdvd.Result[0] = 0; - break; - - case 0x41: // CdReadConfig (0:16) - SetResultSize(16); - cdvdReadConfig(&cdvd.Result[0]); - break; - - case 0x42: // CdWriteConfig (16:1) - SetResultSize(1); - cdvd.Result[0] = cdvdWriteConfig(&cdvd.Param[0]); - break; - - case 0x43: // CdCloseConfig (0:1) - SetResultSize(1); - cdvd.CReadWrite = 0; - cdvd.COffset = 0; - cdvd.CNumBlocks = 0; - cdvd.CBlockIndex= 0; - cdvd.Result[0] = 0; - break; - - case 0x80: // secrman: __mechacon_auth_0x80 - SetResultSize(1);//in:1 - cdvd.mg_datatype = 0;//data - cdvd.Result[0] = 0; - break; - - case 0x81: // secrman: __mechacon_auth_0x81 - SetResultSize(1);//in:1 - cdvd.mg_datatype = 0;//data - cdvd.Result[0] = 0; - break; - - case 0x82: // secrman: __mechacon_auth_0x82 - SetResultSize(1);//in:16 - cdvd.Result[0] = 0; - break; - - case 0x83: // secrman: __mechacon_auth_0x83 - SetResultSize(1);//in:8 - cdvd.Result[0] = 0; - break; - - case 0x84: // secrman: __mechacon_auth_0x84 - SetResultSize(1+8+4);//in:0 - cdvd.Result[0] = 0; - - cdvd.Result[1] = 0x21; - cdvd.Result[2] = 0xdc; - cdvd.Result[3] = 0x31; - cdvd.Result[4] = 0x96; - cdvd.Result[5] = 0xce; - cdvd.Result[6] = 0x72; - cdvd.Result[7] = 0xe0; - cdvd.Result[8] = 0xc8; - - cdvd.Result[9] = 0x69; - cdvd.Result[10] = 0xda; - cdvd.Result[11] = 0x34; - cdvd.Result[12] = 0x9b; - break; - - case 0x85: // secrman: __mechacon_auth_0x85 - SetResultSize(1+4+8);//in:0 - cdvd.Result[0] = 0; - - cdvd.Result[1] = 0xeb; - cdvd.Result[2] = 0x01; - cdvd.Result[3] = 0xc7; - cdvd.Result[4] = 0xa9; - - cdvd.Result[ 5] = 0x3f; - cdvd.Result[ 6] = 0x9c; - cdvd.Result[ 7] = 0x5b; - cdvd.Result[ 8] = 0x19; - cdvd.Result[ 9] = 0x31; - cdvd.Result[10] = 0xa0; - cdvd.Result[11] = 0xb3; - cdvd.Result[12] = 0xa3; - break; - - case 0x86: // secrman: __mechacon_auth_0x86 - SetResultSize(1);//in:16 - cdvd.Result[0] = 0; - break; - - case 0x87: // secrman: __mechacon_auth_0x87 - SetResultSize(1);//in:8 - cdvd.Result[0] = 0; - break; - - case 0x8D: // sceMgWriteData - SetResultSize(1);//in:length<=16 - if (cdvd.mg_size + cdvd.ParamC > cdvd.mg_maxsize) - { - cdvd.Result[0] = 0x80; - } - else - { - memcpy_fast(cdvd.mg_buffer + cdvd.mg_size, cdvd.Param, cdvd.ParamC); - cdvd.mg_size += cdvd.ParamC; - cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error - } - break; - - case 0x8E: // sceMgReadData - SetResultSize( std::min(16, cdvd.mg_size) ); - memcpy_fast(cdvd.Result, cdvd.mg_buffer, cdvd.ResultC); - cdvd.mg_size -= cdvd.ResultC; - memcpy_fast(cdvd.mg_buffer, cdvd.mg_buffer+cdvd.ResultC, cdvd.mg_size); - break; - - case 0x88: // secrman: __mechacon_auth_0x88 //for now it is the same; so, fall;) - case 0x8F: // secrman: __mechacon_auth_0x8F - SetResultSize(1);//in:0 - if (cdvd.mg_datatype == 1) // header data - { - u64* psrc, *pdst; - int bit_ofs, i; - - if ((cdvd.mg_maxsize != cdvd.mg_size)||(cdvd.mg_size < 0x20) || (cdvd.mg_size != *(u16*)&cdvd.mg_buffer[0x14])) - { - fail_pol_cal(); - break; - } - - Console::Write("[MG] ELF_size=0x%X Hdr_size=0x%X unk=0x%X flags=0x%X count=%d zones=", - params *(u32*)&cdvd.mg_buffer[0x10], *(u16*)&cdvd.mg_buffer[0x14], *(u16*)&cdvd.mg_buffer[0x16], - *(u16*)&cdvd.mg_buffer[0x18], *(u16*)&cdvd.mg_buffer[0x1A]); - for (i=0; i<8; i++) - { - if (cdvd.mg_buffer[0x1C] & (1<> 0) & 0xFF; - cdvd.Result[2] = (cdvd.mg_size >> 8) & 0xFF; - break; - } - case 0x92: // sceMgWriteDatainLength - SetResultSize(1);//in:2 - cdvd.mg_size = 0; - cdvd.mg_datatype = 0;//data (encrypted) - cdvd.mg_maxsize = cdvd.Param[0] | (((int)cdvd.Param[1])<<8); - cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error - break; - - case 0x93: // sceMgWriteDataoutLength - SetResultSize(1);//in:2 - if (((cdvd.Param[0] | (((int)cdvd.Param[1])<<8)) == cdvd.mg_size) && (cdvd.mg_datatype == 0)) - { - cdvd.mg_maxsize = 0; // don't allow any write - cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error - } - else - { - cdvd.Result[0] = 0x80; - } - break; - - case 0x94: // sceMgReadKbit - read first half of BIT key - SetResultSize(1+8);//in:0 - cdvd.Result[0] = 0; - - ((int*)(cdvd.Result+1))[0] = ((int*)cdvd.mg_kbit)[0]; - ((int*)(cdvd.Result+1))[1] = ((int*)cdvd.mg_kbit)[1]; - //memcpy(cdvd.Result+1, cdvd.mg_kbit, 8); - break; - - case 0x95: // sceMgReadKbit2 - read second half of BIT key - SetResultSize(1+8);//in:0 - cdvd.Result[0] = 0; - ((int*)(cdvd.Result+1))[0] = ((int*)(cdvd.mg_kbit+8))[0]; - ((int*)(cdvd.Result+1))[1] = ((int*)(cdvd.mg_kbit+8))[1]; - //memcpy(cdvd.Result+1, cdvd.mg_kbit+8, 8); - break; - - case 0x96: // sceMgReadKcon - read first half of content key - SetResultSize(1+8);//in:0 - cdvd.Result[0] = 0; - ((int*)(cdvd.Result+1))[0] = ((int*)cdvd.mg_kcon)[0]; - ((int*)(cdvd.Result+1))[1] = ((int*)cdvd.mg_kcon)[1]; - //memcpy(cdvd.Result+1, cdvd.mg_kcon, 8); - break; - - case 0x97: // sceMgReadKcon2 - read second half of content key - SetResultSize(1+8);//in:0 - cdvd.Result[0] = 0; - ((int*)(cdvd.Result+1))[0] = ((int*)(cdvd.mg_kcon+8))[0]; - ((int*)(cdvd.Result+1))[1] = ((int*)(cdvd.mg_kcon+8))[1]; - //memcpy(cdvd.Result+1, cdvd.mg_kcon+8, 8); - break; - - default: - // fake a 'correct' command - SetResultSize(1); //in:0 - cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error - Console::WriteLn("SCMD Unknown %x", params rt); - break; - } // end switch - - //Console::WriteLn("SCMD - 0x%x\n", params rt); - cdvd.ParamP = 0; - cdvd.ParamC = 0; -} - -static __forceinline void cdvdWrite17(u8 rt) { // SDATAIN - CDR_LOG("cdvdWrite17(SDataIn) %x", rt); - - if (cdvd.ParamP < 32) { - cdvd.Param[cdvd.ParamP++] = rt; - cdvd.ParamC++; - } -} - -static __forceinline void cdvdWrite18(u8 rt) { // SDATAOUT - CDR_LOG("cdvdWrite18(SDataOut) %x", rt); - Console::WriteLn("*PCSX2* SDATAOUT"); -} - -static __forceinline void cdvdWrite3A(u8 rt) { // DEC-SET - CDR_LOG("cdvdWrite3A(DecSet) %x", rt); - cdvd.decSet = rt; - Console::WriteLn("DecSet Write: %02X", params cdvd.decSet); -} - -void cdvdWrite(u8 key, u8 rt) -{ - switch (key) - { - case 0x04: cdvdWrite04(rt); break; - case 0x05: cdvdWrite05(rt); break; - case 0x06: cdvdWrite06(rt); break; - case 0x07: cdvdWrite07(rt); break; - case 0x08: cdvdWrite08(rt); break; - case 0x0A: cdvdWrite0A(rt); break; - case 0x0F: cdvdWrite0F(rt); break; - case 0x14: cdvdWrite14(rt); break; - case 0x16: cdvdWrite16(rt); break; - case 0x17: cdvdWrite17(rt); break; - case 0x18: cdvdWrite18(rt); break; - case 0x3A: cdvdWrite3A(rt); break; - default: - Console::Notice("IOP Unknown 8bit write to addr 0x1f4020%x = 0x%x", params key, rt); - break; - } -} +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" + +#include +#include + +#include "IopCommon.h" +#include "IsoFStools.h" +#include "CDVD_internal.h" +#include "CDVDisoReader.h" + +static cdvdStruct cdvd; + +static __forceinline void SetResultSize(u8 size) +{ + cdvd.ResultC = size; + cdvd.ResultP = 0; + cdvd.sDataIn&=~0x40; +} + +static void CDVDREAD_INT(int eCycle) +{ + PSX_INT(IopEvt_CdvdRead, eCycle); +} + +static void CDVD_INT(int eCycle) +{ + if( eCycle == 0 ) + cdvdActionInterrupt(); + else + PSX_INT(IopEvt_Cdvd, eCycle); +} + +// Sets the cdvd IRQ and the reason for the IRQ, and signals the IOP for a branch +// test (which will cause the exception to be handled). +static void cdvdSetIrq( uint id = (1<FullpathToBios().ToAscii().data() ); + + ptr = file; + i = (int)strlen(file); + + while (i > 0) { if (ptr[i] == '.') break; i--; } + ptr[i+1] = '\0'; + strcat(file, "MEC"); + + // if file doesnt exist, create empty one + fd = fopen(file, "r+b"); + if (fd == NULL) { + Console::Notice("MEC File Not Found , Creating Blank File"); + fd = fopen(file, "wb"); + if (fd == NULL) + { + Console::Error( "\tMEC File Creation failed!" ); + throw Exception::CreateStream( file ); + //Msgbox::Alert( "_cdvdOpenMechaVer: Error creating %s", params file); + //exit(1); + } + + fputc(0x03, fd); + fputc(0x06, fd); + fputc(0x02, fd); + fputc(0x00, fd); + } + return fd; +} + +s32 cdvdGetMechaVer(u8* ver) +{ + FILE* fd = _cdvdOpenMechaVer(); + if (fd == NULL) return 1; + fseek(fd, 0, SEEK_SET); + fread(ver, 1, 4, fd); + fclose(fd); + return 0; +} + +FILE *_cdvdOpenNVM() { + char *ptr; + int i; + char file[g_MaxPath]; + FILE* fd; + + // get the name of the bios file + + // use the bios filename to get the name of the nvm file + // [TODO] : Upgrade this to use std::string! + + strcpy( file, g_Conf->FullpathToBios().ToAscii().data() ); + ptr = file; + i = (int)strlen(file); + + while (i > 0) { if (ptr[i] == '.') break; i--; } + ptr[i+1] = '\0'; + + strcat(file, "NVM"); + + // if file doesnt exist, create empty one + fd = fopen(file, "r+b"); + if (fd == NULL) { + Console::Notice("NVM File Not Found , Creating Blank File"); + fd = fopen(file, "wb"); + if (fd == NULL) + { + throw Exception::CreateStream( file ); + //Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file); + //exit(1); + } + for (i=0; i<1024; i++) fputc(0, fd); + } + return fd; +} + +// +// the following 'cdvd' functions all return 0 if successful +// + +s32 cdvdReadNVM(u8 *dst, int offset, int bytes) { + FILE* fd = _cdvdOpenNVM(); + if (fd == NULL) return 1; + + fseek(fd, offset, SEEK_SET); + fread(dst, 1, bytes, fd); + fclose(fd); + + return 0; +} +s32 cdvdWriteNVM(const u8 *src, int offset, int bytes) { + FILE* fd = _cdvdOpenNVM(); + if (fd == NULL) return 1; + + fseek(fd, offset, SEEK_SET); + fwrite(src, 1, bytes, fd); + fclose(fd); + + return 0; +} + +NVMLayout* getNvmLayout(void) +{ + NVMLayout* nvmLayout = NULL; + s32 nvmIdx; + + for(nvmIdx=0; nvmIdx= cdvd.CNumBlocks) + return 1; + else if( + ((cdvd.COffset == 0) && (cdvd.CBlockIndex >= 4))|| + ((cdvd.COffset == 1) && (cdvd.CBlockIndex >= 2))|| + ((cdvd.COffset == 2) && (cdvd.CBlockIndex >= 7)) + ) + { + memzero_ptr<16>(config); + return 0; + } + + // get config data + switch (cdvd.COffset) + { + case 0: + return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config0)); + break; + case 2: + return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2)); + break; + default: + return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1)); + } +} +s32 cdvdWriteConfig(const u8* config) +{ + // make sure its in write mode + if(cdvd.CReadWrite != 1) + return 1; + // check if block index is in bounds + else if(cdvd.CBlockIndex >= cdvd.CNumBlocks) + return 1; + else if( + ((cdvd.COffset == 0) && (cdvd.CBlockIndex >= 4))|| + ((cdvd.COffset == 1) && (cdvd.CBlockIndex >= 2))|| + ((cdvd.COffset == 2) && (cdvd.CBlockIndex >= 7)) + ) + return 0; + + // get config data + switch (cdvd.COffset) + { + case 0: + return setNvmData(config, (cdvd.CBlockIndex++)*16, 16,offsetof(NVMLayout, config0)); + break; + case 2: + return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2)); + break; + default: + return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1)); + } +} + + +void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) { + wxString fname; + char exeName[12]; + s32 numbers, letters; + u32 key_0_3; + u8 key_4, key_14; + + // get main elf name + GetPS2ElfName(fname); + const wxCharBuffer crap( fname.ToAscii() ); + const char* str = crap.data(); + sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]); + DevCon::Notice("exeName = %s", params &str[8]); + + // convert the number characters to a real 32bit number + numbers = ((((exeName[5] - '0'))*10000) + + (((exeName[ 6] - '0'))*1000) + + (((exeName[ 7] - '0'))*100) + + (((exeName[ 9] - '0'))*10) + + (((exeName[10] - '0'))*1) ); + + // combine the lower 7 bits of each char + // to make the 4 letters fit into a single u32 + letters = (s32)((exeName[3]&0x7F)<< 0) | + (s32)((exeName[2]&0x7F)<< 7) | + (s32)((exeName[1]&0x7F)<<14) | + (s32)((exeName[0]&0x7F)<<21); + + // calculate magic numbers + key_0_3 = ((numbers & 0x1FC00) >> 10) | ((0x01FFFFFF & letters) << 7); // numbers = 7F letters = FFFFFF80 + key_4 = ((numbers & 0x0001F) << 3) | ((0x0E000000 & letters) >> 25); // numbers = F8 letters = 07 + key_14 = ((numbers & 0x003E0) >> 2) | 0x04; // numbers = F8 extra = 04 unused = 03 + + // clear key values + memzero_ptr<16>(key); + + // store key values + key[ 0] = (key_0_3&0x000000FF)>> 0; + key[ 1] = (key_0_3&0x0000FF00)>> 8; + key[ 2] = (key_0_3&0x00FF0000)>>16; + key[ 3] = (key_0_3&0xFF000000)>>24; + key[ 4] = key_4; + + if(arg2 == 75) + { + key[14] = key_14; + key[15] = 0x05; + } + else if(arg2 == 3075) + { + key[15] = 0x01; + } + else if(arg2 == 4246) + { + // 0x0001F2F707 = sector 0x0001F2F7 dec 0x07 + key[ 0] = 0x07; + key[ 1] = 0xF7; + key[ 2] = 0xF2; + key[ 3] = 0x01; + key[ 4] = 0x00; + key[15] = 0x01; + } + else + { + key[15] = 0x01; + } + + Console::WriteLn( "CDVD.KEY = %02X,%02X,%02X,%02X,%02X,%02X,%02X", params + cdvd.Key[0],cdvd.Key[1],cdvd.Key[2],cdvd.Key[3],cdvd.Key[4],cdvd.Key[14],cdvd.Key[15] ); + + // Now's a good time to reload the ELF info... + if( ElfCRC == 0 ) + { + ElfCRC = loadElfCRC( str ); + ElfApplyPatches(); + GSsetGameCRC( ElfCRC, 0 ); + } +} + +s32 cdvdGetToc(void* toc) +{ + s32 ret = CDVD.getTOC(toc); + if (ret == -1) ret = 0x80; + return ret; +} + +s32 cdvdReadSubQ(s32 lsn, cdvdSubQ* subq) +{ + s32 ret = CDVD.readSubQ(lsn, subq); + if (ret == -1) ret = 0x80; + return ret; +} + +s32 cdvdCtrlTrayOpen() +{ + s32 ret = CDVD.ctrlTrayOpen(); + if (ret == -1) ret = 0x80; + return ret; +} + +s32 cdvdCtrlTrayClose() +{ + s32 ret = CDVD.ctrlTrayClose(); + if (ret == -1) ret = 0x80; + return ret; +} + +// Modified by (efp) - 16/01/2006 +// checks if tray was opened since last call to this func +s32 cdvdGetTrayStatus() +{ + s32 ret = CDVD.getTrayStatus(); + + if (ret == -1) + return(CDVD_TRAY_CLOSE); + else + return(ret); +} + +// Note: Is tray status being kept as a var here somewhere? +// cdvdNewDiskCB() can update it's status as well... + +// Modified by (efp) - 16/01/2006 +static __forceinline void cdvdGetDiskType() +{ + cdvd.Type = DoCDVDdetectDiskType(); +} + +// check whether disc is single or dual layer +// if its dual layer, check what the disctype is and what sector number +// layer1 starts at +// +// args: gets value for dvd type (0=single layer, 1=ptp, 2=otp) +// gets value for start lsn of layer1 +// returns: 1 if on dual layer disc +// 0 if not on dual layer disc +static s32 cdvdReadDvdDualInfo(s32* dualType, u32* layer1Start) +{ + *dualType = 0; + *layer1Start = 0; + + return CDVD.getDualInfo(dualType,layer1Start); +} + +static uint cdvdBlockReadTime( CDVD_MODE_TYPE mode ) +{ + return (PSXCLK * cdvd.BlockSize) / (((mode==MODE_CDROM) ? PSX_CD_READSPEED : PSX_DVD_READSPEED) * cdvd.Speed); +} + +void cdvdReset() +{ + memzero_obj(cdvd); + + cdvd.Type = CDVD_TYPE_NODISC; + cdvd.Spinning = false; + + cdvd.sDataIn = 0x40; + cdvd.Ready = CDVD_READY2; + cdvd.Speed = 4; + cdvd.BlockSize = 2064; + cdvd.Action = cdvdAction_None; + cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); + + wxDateTime curtime( wxDateTime::GetTimeNow() ); + cdvd.RTC.second = (u8)curtime.GetSecond(); + cdvd.RTC.minute = (u8)curtime.GetMinute(); + cdvd.RTC.hour = (u8)(curtime.GetHour()+1) % 24; + cdvd.RTC.day = (u8)curtime.GetDay(); + cdvd.RTC.month = (u8)curtime.GetMonth(); + cdvd.RTC.year = (u8)(curtime.GetYear() - 2000); +} + +struct Freeze_v10Compat +{ + u8 Action; + u32 SeekToSector; + u32 ReadTime; + bool Spinning; +}; + +void SaveState::cdvdFreeze() +{ + FreezeTag( "cdvd" ); + Freeze( cdvd ); + + if (IsLoading()) + { + // Make sure the Cdvd plugin has the expected track loaded into the buffer. + // If cdvd.Readed is cleared it means we need to load the SeekToSector (ie, a + // seek is in progress!) + + if( cdvd.Reading ) + cdvd.RErr = DoCDVDreadTrack( cdvd.Readed ? cdvd.Sector : cdvd.SeekToSector, cdvd.ReadMode); + } +} + +// Modified by (efp) - 16/01/2006 + +void cdvdDetectDisk() +{ + cdvd.Type = DoCDVDdetectDiskType(); + + wxString str; + int result = GetPS2ElfName(str); + + // Now's a good time to reload the ELF info... + if( ElfCRC == 0 ) + { + ElfCRC = loadElfCRC( str.ToAscii().data() ); + ElfApplyPatches(); + GSsetGameCRC( ElfCRC, 0 ); + } +} + +void cdvdNewDiskCB() +{ + DoCDVDresetDiskTypeCache(); + + cdvdDetectDisk(); +} + +void mechaDecryptBytes( u32 madr, int size ) +{ + int i; + + int shiftAmount = (cdvd.decSet>>4) & 7; + int doXor = (cdvd.decSet) & 1; + int doShift = (cdvd.decSet) & 2; + + u8* curval = iopPhysMem( madr ); + for( i=0; i> shiftAmount) | (*curval << (8-shiftAmount) ); + } +} + +int cdvdReadSector() { + s32 bcr; + + CDR_LOG("SECTOR %d (BCR %x;%x)", cdvd.Sector, HW_DMA3_BCR_H16, HW_DMA3_BCR_L16); + + bcr = (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4; + if (bcr < cdvd.BlockSize) { + CDR_LOG( "READBLOCK: bcr < cdvd.BlockSize; %x < %x", bcr, cdvd.BlockSize ); + if (HW_DMA3_CHCR & 0x01000000) { + HW_DMA3_CHCR &= ~0x01000000; + psxDmaInterrupt(3); + } + return -1; + } + + // DMAs use physical addresses (air) + u8* mdest = iopPhysMem( HW_DMA3_MADR ); + + // if raw dvd sector 'fill in the blanks' + if (cdvd.BlockSize == 2064) + { + // get info on dvd type and layer1 start + u32 layer1Start; + s32 dualType; + s32 layerNum; + u32 lsn = cdvd.Sector; + + cdvdReadDvdDualInfo(&dualType, &layer1Start); + + if((dualType == 1) && (lsn >= layer1Start)) + { + // dual layer ptp disc + layerNum = 1; + lsn = lsn-layer1Start + 0x30000; + } + else if((dualType == 2) && (lsn >= layer1Start)) + { + // dual layer otp disc + layerNum = 1; + lsn = ~(layer1Start+0x30000 - 1); + } + else + { // Assumed the other dualType is 0. + // single layer disc + // or on first layer of dual layer disc + layerNum = 0; + lsn += 0x30000; + } + + mdest[0] = 0x20 | layerNum; + mdest[1] = (u8)(lsn >> 16); + mdest[2] = (u8)(lsn >> 8); + mdest[3] = (u8)(lsn ); + + // sector IED (not calculated at present) + mdest[4] = 0; + mdest[5] = 0; + + // sector CPR_MAI (not calculated at present) + mdest[6] = 0; + mdest[7] = 0; + mdest[8] = 0; + mdest[9] = 0; + mdest[10] = 0; + mdest[11] = 0; + + // normal 2048 bytes of sector data + memcpy_fast( &mdest[12], cdr.pTransfer, 2048); + + // 4 bytes of edc (not calculated at present) + mdest[2060] = 0; + mdest[2061] = 0; + mdest[2062] = 0; + mdest[2063] = 0; + } + else + { + memcpy_fast( mdest, cdr.pTransfer, cdvd.BlockSize); + } + + // decrypt sector's bytes + if( cdvd.decSet ) mechaDecryptBytes( HW_DMA3_MADR, cdvd.BlockSize ); + + // Added a clear after memory write .. never seemed to be necessary before but *should* + // be more correct. (air) + psxCpu->Clear( HW_DMA3_MADR, cdvd.BlockSize/4 ); + +// Console::WriteLn("sector %x;%x;%x", params PSXMu8(madr+0), PSXMu8(madr+1), PSXMu8(madr+2)); + + HW_DMA3_BCR_H16 -= (cdvd.BlockSize / (HW_DMA3_BCR_L16*4)); + HW_DMA3_MADR += cdvd.BlockSize; + + return 0; +} + +// inlined due to being referenced in only one place. +__forceinline void cdvdActionInterrupt() +{ + switch( cdvd.Action ) + { + case cdvdAction_Seek: + case cdvdAction_Standby: + cdvd.Spinning = true; + cdvd.Ready = CDVD_READY1; + cdvd.Sector = cdvd.SeekToSector; + cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; + break; + + case cdvdAction_Stop: + cdvd.Spinning = false; + cdvd.Ready = CDVD_READY1; + cdvd.Sector = 0; + cdvd.Status = CDVD_STATUS_NONE; + break; + + case cdvdAction_Break: + // Make sure the cdvd action state is pretty well cleared: + cdvd.Reading = 0; + cdvd.Readed = 0; + cdvd.Ready = CDVD_READY2; // should be CDVD_READY1 or something else? + cdvd.Status = CDVD_STATUS_NONE; + cdvd.RErr = 0; + cdvd.nCommand = 0; + break; + } + cdvd.Action = cdvdAction_None; + + cdvd.PwOff |= 1< Scheduling block read interrupt at iopcycle=%8.8x.", + psxRegs.cycle + cdvd.ReadTime ); + + CDVDREAD_INT(cdvd.ReadTime); + return; + } + else + { + + if (cdvd.RErr == 0) + { + cdr.RErr = DoCDVDgetBuffer(cdr.Transfer); + cdr.pTransfer = cdr.Transfer; + } + else + cdr.pTransfer = NULL; + + if (cdr.RErr == -1) + { + cdvd.RetryCntP++; + Console::Error("CDVD READ ERROR, sector=%d", params cdvd.Sector); + + if (cdvd.RetryCntP <= cdvd.RetryCnt) + { + cdvd.RErr = DoCDVDreadTrack(cdvd.Sector, cdvd.ReadMode); + CDVDREAD_INT(cdvd.ReadTime); + return; + } + } + else if(cdr.RErr == -2) + { + // not finished yet ... give it a bit more time + CDVDREAD_INT(cdvd.ReadTime); + return; + } + cdvd.Reading = false; + } + + if (cdvdReadSector() == -1) + { + assert((int)cdvd.ReadTime > 0 ); + CDVDREAD_INT(cdvd.ReadTime); + return; + } + + cdvd.Sector++; + + if (--cdvd.nSectors <= 0) + { + cdvd.PwOff |= 1< Simulating CdRom Spinup Time, and seek to sector %d", cdvd.SeekToSector ); + seektime = PSXCLK / 3; // 333ms delay + cdvd.Spinning = true; + } + else if( (tbl_ContigiousSeekDelta[mode] == 0) || (delta >= tbl_ContigiousSeekDelta[mode]) ) + { + // Select either Full or Fast seek depending on delta: + + if( delta >= tbl_FastSeekDelta[mode] ) + { + // Full Seek + CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FULL]", cdvd.SeekToSector, cdvd.Sector, delta ); + seektime = Cdvd_FullSeek_Cycles; + } + else + { + CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FAST]", cdvd.SeekToSector, cdvd.Sector, delta ); + seektime = Cdvd_FastSeek_Cycles; + } + } + else + { + CDR_LOG( "CdSeek Begin > Contiguous block without seek - delta=%d sectors", delta ); + + // seektime is the time it takes to read to the destination block: + seektime = delta * cdvd.ReadTime; + + if( delta == 0 ) + { + cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; + cdvd.Readed = 1; // Note: 1, not 0, as implied by the next comment. Need to look into this. --arcum42 + cdvd.RetryCntP = 0; + + // setting Readed to 0 skips the seek logic, which means the next call to + // cdvdReadInterrupt will load a block. So make sure it's properly scheduled + // based on sector read speeds: + + seektime = cdvd.ReadTime; + } + } + + return seektime; +} + +u8 monthmap[13] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +void cdvdVsync() { + cdvd.RTCcount++; + if (cdvd.RTCcount < ((Config.PsxType & 1) ? 50 : 60)) return; + cdvd.RTCcount = 0; + + cdvd.RTC.second++; + if (cdvd.RTC.second < 60) return; + cdvd.RTC.second = 0; + + cdvd.RTC.minute++; + if (cdvd.RTC.minute < 60) return; + cdvd.RTC.minute = 0; + + cdvd.RTC.hour++; + if (cdvd.RTC.hour < 24) return; + cdvd.RTC.hour = 0; + + cdvd.RTC.day++; + if (cdvd.RTC.day <= monthmap[cdvd.RTC.month-1]) return; + cdvd.RTC.day = 1; + + cdvd.RTC.month++; + if (cdvd.RTC.month <= 12) return; + cdvd.RTC.month = 1; + + cdvd.RTC.year++; + if (cdvd.RTC.year < 100) return; + cdvd.RTC.year = 0; +} + +static __forceinline u8 cdvdRead18(void) // SDATAOUT +{ + u8 ret = 0; + + if (((cdvd.sDataIn & 0x40) == 0) && (cdvd.ResultP < cdvd.ResultC)) + { + cdvd.ResultP++; + if (cdvd.ResultP >= cdvd.ResultC) cdvd.sDataIn|= 0x40; + ret = cdvd.Result[cdvd.ResultP-1]; + } + CDR_LOG("cdvdRead18(SDataOut) %x (ResultC=%d, ResultP=%d)", ret, cdvd.ResultC, cdvd.ResultP); + + return ret; +} + +u8 cdvdRead(u8 key) +{ + switch (key) + { + case 0x04: // NCOMMAND + CDR_LOG("cdvdRead04(NCMD) %x", cdvd.nCommand); + return cdvd.nCommand; + break; + + case 0x05: // N-READY + CDR_LOG("cdvdRead05(NReady) %x", cdvd.Ready); + return cdvd.Ready; + break; + + case 0x06: // ERROR + CDR_LOG("cdvdRead06(Error) %x", cdvd.Error); + return cdvd.Error; + break; + + case 0x07: // BREAK + CDR_LOG("cdvdRead07(Break) %x", 0); + return 0; + break; + + case 0x08: // STATUS + CDR_LOG("cdvdRead08(Status) %x", cdvd.Status); + return cdvd.Status; + break; + + case 0x0A: // STATUS + CDR_LOG("cdvdRead0A(Status) %x", cdvd.Status); + return cdvd.Status; + break; + + case 0x0B: // TRAY-STATE (if tray has been opened) + { + u8 tray = cdvdGetTrayStatus(); + CDR_LOG("cdvdRead0B(Tray) %x", tray); + return tray; + break; + } + case 0x0C: // CRT MINUTE + CDR_LOG("cdvdRead0C(Min) %x", itob((u8)(cdvd.Sector/(60*75)))); + return itob((u8)(cdvd.Sector/(60*75))); + break; + + case 0x0D: // CRT SECOND + CDR_LOG("cdvdRead0D(Sec) %x", itob((u8)((cdvd.Sector/75)%60)+2)); + return itob((u8)((cdvd.Sector/75)%60)+2); + break; + + case 0x0E: // CRT FRAME + CDR_LOG("cdvdRead0E(Frame) %x", itob((u8)(cdvd.Sector%75))); + return itob((u8)(cdvd.Sector%75)); + break; + + case 0x0F: // TYPE + CDR_LOG("cdvdRead0F(Disc Type) %x", cdvd.Type); + cdvdGetDiskType(); + return cdvd.Type; + break; + + case 0x13: // UNKNOWN + CDR_LOG("cdvdRead13(Unknown) %x", 4); + return 4; + break; + + case 0x15: // RSV + CDR_LOG("cdvdRead15(RSV)"); + return 0x01; // | 0x80 for ATAPI mode + break; + + case 0x16: // SCOMMAND + CDR_LOG("cdvdRead16(SCMD) %x", cdvd.sCommand); + return cdvd.sCommand; + break; + + case 0x17: // SREADY + CDR_LOG("cdvdRead17(SReady) %x", cdvd.sDataIn); + return cdvd.sDataIn; + break; + + case 0x18: + return cdvdRead18(); + break; + + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + { + int temp = key - 0x20; + + CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); + return cdvd.Key[temp]; + break; + } + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + { + int temp = key - 0x23; + + CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); + return cdvd.Key[temp]; + break; + } + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + { + int temp = key - 0x26; + + CDR_LOG("cdvdRead%d(Key%d) %x", key, temp, cdvd.Key[temp]); + return cdvd.Key[temp]; + break; + } + + case 0x38: // valid parts of key data (first and last are valid) + CDR_LOG("cdvdRead38(KeysValid) %x", cdvd.Key[15]); + + return cdvd.Key[15]; + break; + + case 0x39: // KEY-XOR + CDR_LOG("cdvdRead39(KeyXor) %x", cdvd.KeyXor); + + return cdvd.KeyXor; + break; + + case 0x3A: // DEC_SET + CDR_LOG("cdvdRead3A(DecSet) %x", cdvd.decSet); + + Console::WriteLn("DecSet Read: %02X", params cdvd.decSet); + return cdvd.decSet; + break; + + default: + // note: notify the console since this is a potentially serious emulation problem: + PSXHW_LOG("*Unknown 8bit read at address 0x1f4020%x", key); + Console::Error( "IOP Unknown 8bit read from addr 0x1f4020%x", params key ); + return 0; + break; + } +} + +static void cdvdWrite04(u8 rt) { // NCOMMAND + CDR_LOG("cdvdWrite04: NCMD %s (%x) (ParamP = %x)", nCmdName[rt], rt, cdvd.ParamP); + + cdvd.nCommand = rt; + cdvd.Status = CDVD_STATUS_NONE; + cdvd.PwOff = Irq_None; // good or bad? + + switch (rt) { + case N_CD_SYNC: // CdSync + case N_CD_NOP: // CdNop_ + cdvdSetIrq(); + break; + + case N_CD_STANDBY: // CdStandby + + // Seek to sector zero. The cdvdStartSeek function will simulate + // spinup times if needed. + + DevCon::Notice( "CdStandby : %d", params rt ); + cdvd.Action = cdvdAction_Standby; + cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); + CDVD_INT( cdvdStartSeek( 0, MODE_DVDROM ) ); + break; + + case N_CD_STOP: // CdStop + DevCon::Notice( "CdStop : %d", params rt ); + cdvd.Action = cdvdAction_Stop; + CDVD_INT( PSXCLK / 6 ); // 166ms delay? + break; + + // from an emulation point of view there is not much need to do anything for this one + case N_CD_PAUSE: // CdPause + cdvdSetIrq(); + break; + + case N_CD_SEEK: // CdSeek + cdvd.Action = cdvdAction_Seek; + cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); + CDVD_INT( cdvdStartSeek( *(uint*)(cdvd.Param+0), MODE_DVDROM ) ); + break; + + case N_CD_READ: // CdRead + cdvd.SeekToSector = *(uint*)(cdvd.Param+0); + cdvd.nSectors = *(int*)(cdvd.Param+4); + cdvd.RetryCnt = (cdvd.Param[8] == 0) ? 0x100 : cdvd.Param[8]; + cdvd.SpindlCtrl = cdvd.Param[9]; + cdvd.Speed = 24; + switch (cdvd.Param[10]) { + case 2: cdvd.ReadMode = CDVD_MODE_2340; cdvd.BlockSize = 2340; break; + case 1: cdvd.ReadMode = CDVD_MODE_2328; cdvd.BlockSize = 2328; break; + case 0: + default: cdvd.ReadMode = CDVD_MODE_2048; cdvd.BlockSize = 2048; break; + } + + CDR_LOG( "CdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)", + cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); + + if( Config.cdvdPrint ) + Console::WriteLn("CdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", + params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); + + cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); + CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector,MODE_CDROM ) ); + + // Read-ahead by telling the plugin about the track now. + // This helps improve performance on actual from-cd emulation + // (ie, not using the hard drive) + cdvd.RErr = DoCDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); + + // Set the reading block flag. If a seek is pending then Readed will + // take priority in the handler anyway. If the read is contiguous then + // this'll skip the seek delay. + cdvd.Reading = 1; + break; + + case N_CD_READ_CDDA: // CdReadCDDA + case N_CD_READ_XCDDA: // CdReadXCDDA + cdvd.SeekToSector = *(int*)(cdvd.Param+0); + cdvd.nSectors = *(int*)(cdvd.Param+4); + + if (cdvd.Param[8] == 0) + cdvd.RetryCnt = 0x100; + else + cdvd.RetryCnt = cdvd.Param[8]; + + cdvd.SpindlCtrl = cdvd.Param[9]; + + switch (cdvd.Param[9]) { + case 0x01: cdvd.Speed = 1; break; + case 0x02: cdvd.Speed = 2; break; + case 0x03: cdvd.Speed = 4; break; + case 0x04: cdvd.Speed = 12; break; + default: cdvd.Speed = 24; break; + } + + switch (cdvd.Param[10]) { + case 1: cdvd.ReadMode = CDVD_MODE_2368; cdvd.BlockSize = 2368; break; + case 2: + case 0: cdvd.ReadMode = CDVD_MODE_2352; cdvd.BlockSize = 2352; break; + } + + CDR_LOG( "CdReadCDDA > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%xx(%x), ReadMode=%x(%x) (1074=%x)", + cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); + + if( Config.cdvdPrint ) + Console::WriteLn("CdAudioRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", + params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); + + cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); + CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_CDROM ) ); + + // Read-ahead by telling the plugin about the track now. + // This helps improve performance on actual from-cd emulation + // (ie, not using the hard drive) + cdvd.RErr = DoCDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); + + // Set the reading block flag. If a seek is pending then Readed will + // take priority in the handler anyway. If the read is contiguous then + // this'll skip the seek delay. + cdvd.Reading = 1; + break; + + case N_DVD_READ: // DvdRead + cdvd.SeekToSector = *(int*)(cdvd.Param+0); + cdvd.nSectors = *(int*)(cdvd.Param+4); + + if (cdvd.Param[8] == 0) + cdvd.RetryCnt = 0x100; + else + cdvd.RetryCnt = cdvd.Param[8]; + + cdvd.SpindlCtrl = cdvd.Param[9]; + cdvd.Speed = 4; + cdvd.ReadMode = CDVD_MODE_2048; + cdvd.BlockSize = 2064; // Why oh why was it 2064 + + CDR_LOG( "DvdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)", + cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); + + if( Config.cdvdPrint ) + Console::WriteLn("DvdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx", + params cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed); + + cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); + CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_DVDROM ) ); + + // Read-ahead by telling the plugin about the track now. + // This helps improve performance on actual from-cd emulation + // (ie, not using the hard drive) + cdvd.RErr = DoCDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode ); + + // Set the reading block flag. If a seek is pending then Readed will + // take priority in the handler anyway. If the read is contiguous then + // this'll skip the seek delay. + cdvd.Reading = 1; + break; + + case N_CD_GET_TOC: // CdGetToc & cdvdman_call19 + //Param[0] is 0 for CdGetToc and any value for cdvdman_call19 + //the code below handles only CdGetToc! + //if(cdvd.Param[0]==0x01) + //{ + DevCon::WriteLn("CDGetToc Param[0]=%d, Param[1]=%d", params cdvd.Param[0],cdvd.Param[1]); + //} + cdvdGetToc( iopPhysMem( HW_DMA3_MADR ) ); + cdvdSetIrq( (1< remote key code + SetResultSize(5); + cdvd.Result[0] = 0x00; + cdvd.Result[1] = 0x14; + cdvd.Result[2] = 0x00; + cdvd.Result[3] = 0x00; + cdvd.Result[4] = 0x00; + break; + +// case 0x1F: // sceRemote2_7 (2:1) - cdvdman_call117 +// break; + + case 0x20: // sceRemote2_6 (0:3) // 00 01 00 + SetResultSize(3); + cdvd.Result[0] = 0x00; + cdvd.Result[1] = 0x01; + cdvd.Result[2] = 0x00; + break; + +// case 0x21: // sceCdWriteWakeUpTime (8:1) +// break; + + case 0x22: // sceCdReadWakeUpTime (0:10) + SetResultSize(10); + cdvd.Result[0] = 0; + cdvd.Result[1] = 0; + cdvd.Result[2] = 0; + cdvd.Result[3] = 0; + cdvd.Result[4] = 0; + cdvd.Result[5] = 0; + cdvd.Result[6] = 0; + cdvd.Result[7] = 0; + cdvd.Result[8] = 0; + cdvd.Result[9] = 0; + break; + + case 0x24: // sceCdRCBypassCtrl (1:1) - In V10 Bios + // FIXME: because PRId<0x23, the bit 0 of sio2 don't get updated 0xBF808284 + SetResultSize(1); + cdvd.Result[0] = 0; + break; + +// case 0x25: // cdvdman_call120 (1:1) - In V10 Bios +// break; + +// case 0x26: // cdvdman_call128 (0,3) - In V10 Bios +// break; + +// case 0x27: // cdvdman_call148 (0:13) - In V10 Bios +// break; + +// case 0x28: // cdvdman_call150 (1:1) - In V10 Bios +// break; + + case 0x29: //sceCdNoticeGameStart (1:1) + SetResultSize(1); + cdvd.Result[0] = 0; + break; + +// case 0x2C: //sceCdXBSPowerCtl (2:2) +// break; + +// case 0x2D: //sceCdXLEDCtl (2:2) +// break; + +// case 0x2E: //sceCdBuzzerCtl (0:1) +// break; + +// case 0x2F: //cdvdman_call167 (16:1) +// break; + +// case 0x30: //cdvdman_call169 (1:9) +// break; + + case 0x31: //sceCdSetMediumRemoval (1:1) + SetResultSize(1); + cdvd.Result[0] = 0; + break; + + case 0x32: //sceCdGetMediumRemoval (0:2) + SetResultSize(2); + cdvd.Result[0] = 0; + //cdvd.Result[0] = 0; // fixme: I'm pretty sure that the same variable shouldn't be set twice here. Perhaps cdvd.Result[1]? + break; + +// case 0x33: //sceCdXDVRPReset (1:1) +// break; + + case 0x36: //cdvdman_call189 [__sceCdReadRegionParams - made up name] (0:15) i think it is 16, not 15 + SetResultSize(15); + + cdvdGetMechaVer(&cdvd.Result[1]); + cdvd.Result[0] = cdvdReadRegionParams(&cdvd.Result[3]);//size==8 + Console::WriteLn("REGION PARAMS = %s %s", params mg_zones[cdvd.Result[1]], &cdvd.Result[3]); + cdvd.Result[1] = 1 << cdvd.Result[1]; //encryption zone; see offset 0x1C in encrypted headers + ////////////////////////////////////////// + cdvd.Result[2] = 0; //?? +// cdvd.Result[3] == ROMVER[4] == *0xBFC7FF04 +// cdvd.Result[4] == OSDVER[4] == CAP Jjpn, Aeng, Eeng, Heng, Reng, Csch, Kkor? +// cdvd.Result[5] == OSDVER[5] == small +// cdvd.Result[6] == OSDVER[6] == small +// cdvd.Result[7] == OSDVER[7] == small +// cdvd.Result[8] == VERSTR[0x22] == *0xBFC7FF52 +// cdvd.Result[9] == DVDID J U O E A R C M +// cdvd.Result[10]== 0; //?? + cdvd.Result[11] = 0; //?? + cdvd.Result[12] = 0; //?? + ////////////////////////////////////////// + cdvd.Result[13] = 0; //0xFF - 77001 + cdvd.Result[14] = 0; //?? + break; + + case 0x37: //called from EECONF [sceCdReadMAC - made up name] (0:9) + SetResultSize(9); + cdvd.Result[0] = cdvdReadMAC(&cdvd.Result[1]); + break; + + case 0x38: //used to fix the MAC back after accidentally trashed it :D [sceCdWriteMAC - made up name] (8:1) + SetResultSize(1); + cdvd.Result[0] = cdvdWriteMAC(&cdvd.Param[0]); + break; + + case 0x3E: //[__sceCdWriteRegionParams - made up name] (15:1) [Florin: hum, i was expecting 14:1] + SetResultSize(1); + cdvd.Result[0] = cdvdWriteRegionParams(&cdvd.Param[2]); + break; + + case 0x40: // CdOpenConfig (3:1) + SetResultSize(1); + cdvd.CReadWrite = cdvd.Param[0]; + cdvd.COffset = cdvd.Param[1]; + cdvd.CNumBlocks = cdvd.Param[2]; + cdvd.CBlockIndex= 0; + cdvd.Result[0] = 0; + break; + + case 0x41: // CdReadConfig (0:16) + SetResultSize(16); + cdvdReadConfig(&cdvd.Result[0]); + break; + + case 0x42: // CdWriteConfig (16:1) + SetResultSize(1); + cdvd.Result[0] = cdvdWriteConfig(&cdvd.Param[0]); + break; + + case 0x43: // CdCloseConfig (0:1) + SetResultSize(1); + cdvd.CReadWrite = 0; + cdvd.COffset = 0; + cdvd.CNumBlocks = 0; + cdvd.CBlockIndex= 0; + cdvd.Result[0] = 0; + break; + + case 0x80: // secrman: __mechacon_auth_0x80 + SetResultSize(1);//in:1 + cdvd.mg_datatype = 0;//data + cdvd.Result[0] = 0; + break; + + case 0x81: // secrman: __mechacon_auth_0x81 + SetResultSize(1);//in:1 + cdvd.mg_datatype = 0;//data + cdvd.Result[0] = 0; + break; + + case 0x82: // secrman: __mechacon_auth_0x82 + SetResultSize(1);//in:16 + cdvd.Result[0] = 0; + break; + + case 0x83: // secrman: __mechacon_auth_0x83 + SetResultSize(1);//in:8 + cdvd.Result[0] = 0; + break; + + case 0x84: // secrman: __mechacon_auth_0x84 + SetResultSize(1+8+4);//in:0 + cdvd.Result[0] = 0; + + cdvd.Result[1] = 0x21; + cdvd.Result[2] = 0xdc; + cdvd.Result[3] = 0x31; + cdvd.Result[4] = 0x96; + cdvd.Result[5] = 0xce; + cdvd.Result[6] = 0x72; + cdvd.Result[7] = 0xe0; + cdvd.Result[8] = 0xc8; + + cdvd.Result[9] = 0x69; + cdvd.Result[10] = 0xda; + cdvd.Result[11] = 0x34; + cdvd.Result[12] = 0x9b; + break; + + case 0x85: // secrman: __mechacon_auth_0x85 + SetResultSize(1+4+8);//in:0 + cdvd.Result[0] = 0; + + cdvd.Result[1] = 0xeb; + cdvd.Result[2] = 0x01; + cdvd.Result[3] = 0xc7; + cdvd.Result[4] = 0xa9; + + cdvd.Result[ 5] = 0x3f; + cdvd.Result[ 6] = 0x9c; + cdvd.Result[ 7] = 0x5b; + cdvd.Result[ 8] = 0x19; + cdvd.Result[ 9] = 0x31; + cdvd.Result[10] = 0xa0; + cdvd.Result[11] = 0xb3; + cdvd.Result[12] = 0xa3; + break; + + case 0x86: // secrman: __mechacon_auth_0x86 + SetResultSize(1);//in:16 + cdvd.Result[0] = 0; + break; + + case 0x87: // secrman: __mechacon_auth_0x87 + SetResultSize(1);//in:8 + cdvd.Result[0] = 0; + break; + + case 0x8D: // sceMgWriteData + SetResultSize(1);//in:length<=16 + if (cdvd.mg_size + cdvd.ParamC > cdvd.mg_maxsize) + { + cdvd.Result[0] = 0x80; + } + else + { + memcpy_fast(cdvd.mg_buffer + cdvd.mg_size, cdvd.Param, cdvd.ParamC); + cdvd.mg_size += cdvd.ParamC; + cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error + } + break; + + case 0x8E: // sceMgReadData + SetResultSize( std::min(16, cdvd.mg_size) ); + memcpy_fast(cdvd.Result, cdvd.mg_buffer, cdvd.ResultC); + cdvd.mg_size -= cdvd.ResultC; + memcpy_fast(cdvd.mg_buffer, cdvd.mg_buffer+cdvd.ResultC, cdvd.mg_size); + break; + + case 0x88: // secrman: __mechacon_auth_0x88 //for now it is the same; so, fall;) + case 0x8F: // secrman: __mechacon_auth_0x8F + SetResultSize(1);//in:0 + if (cdvd.mg_datatype == 1) // header data + { + u64* psrc, *pdst; + int bit_ofs, i; + + if ((cdvd.mg_maxsize != cdvd.mg_size)||(cdvd.mg_size < 0x20) || (cdvd.mg_size != *(u16*)&cdvd.mg_buffer[0x14])) + { + fail_pol_cal(); + break; + } + + Console::Write("[MG] ELF_size=0x%X Hdr_size=0x%X unk=0x%X flags=0x%X count=%d zones=", + params *(u32*)&cdvd.mg_buffer[0x10], *(u16*)&cdvd.mg_buffer[0x14], *(u16*)&cdvd.mg_buffer[0x16], + *(u16*)&cdvd.mg_buffer[0x18], *(u16*)&cdvd.mg_buffer[0x1A]); + for (i=0; i<8; i++) + { + if (cdvd.mg_buffer[0x1C] & (1<> 0) & 0xFF; + cdvd.Result[2] = (cdvd.mg_size >> 8) & 0xFF; + break; + } + case 0x92: // sceMgWriteDatainLength + SetResultSize(1);//in:2 + cdvd.mg_size = 0; + cdvd.mg_datatype = 0;//data (encrypted) + cdvd.mg_maxsize = cdvd.Param[0] | (((int)cdvd.Param[1])<<8); + cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error + break; + + case 0x93: // sceMgWriteDataoutLength + SetResultSize(1);//in:2 + if (((cdvd.Param[0] | (((int)cdvd.Param[1])<<8)) == cdvd.mg_size) && (cdvd.mg_datatype == 0)) + { + cdvd.mg_maxsize = 0; // don't allow any write + cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error + } + else + { + cdvd.Result[0] = 0x80; + } + break; + + case 0x94: // sceMgReadKbit - read first half of BIT key + SetResultSize(1+8);//in:0 + cdvd.Result[0] = 0; + + ((int*)(cdvd.Result+1))[0] = ((int*)cdvd.mg_kbit)[0]; + ((int*)(cdvd.Result+1))[1] = ((int*)cdvd.mg_kbit)[1]; + //memcpy(cdvd.Result+1, cdvd.mg_kbit, 8); + break; + + case 0x95: // sceMgReadKbit2 - read second half of BIT key + SetResultSize(1+8);//in:0 + cdvd.Result[0] = 0; + ((int*)(cdvd.Result+1))[0] = ((int*)(cdvd.mg_kbit+8))[0]; + ((int*)(cdvd.Result+1))[1] = ((int*)(cdvd.mg_kbit+8))[1]; + //memcpy(cdvd.Result+1, cdvd.mg_kbit+8, 8); + break; + + case 0x96: // sceMgReadKcon - read first half of content key + SetResultSize(1+8);//in:0 + cdvd.Result[0] = 0; + ((int*)(cdvd.Result+1))[0] = ((int*)cdvd.mg_kcon)[0]; + ((int*)(cdvd.Result+1))[1] = ((int*)cdvd.mg_kcon)[1]; + //memcpy(cdvd.Result+1, cdvd.mg_kcon, 8); + break; + + case 0x97: // sceMgReadKcon2 - read second half of content key + SetResultSize(1+8);//in:0 + cdvd.Result[0] = 0; + ((int*)(cdvd.Result+1))[0] = ((int*)(cdvd.mg_kcon+8))[0]; + ((int*)(cdvd.Result+1))[1] = ((int*)(cdvd.mg_kcon+8))[1]; + //memcpy(cdvd.Result+1, cdvd.mg_kcon+8, 8); + break; + + default: + // fake a 'correct' command + SetResultSize(1); //in:0 + cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error + Console::WriteLn("SCMD Unknown %x", params rt); + break; + } // end switch + + //Console::WriteLn("SCMD - 0x%x\n", params rt); + cdvd.ParamP = 0; + cdvd.ParamC = 0; +} + +static __forceinline void cdvdWrite17(u8 rt) { // SDATAIN + CDR_LOG("cdvdWrite17(SDataIn) %x", rt); + + if (cdvd.ParamP < 32) { + cdvd.Param[cdvd.ParamP++] = rt; + cdvd.ParamC++; + } +} + +static __forceinline void cdvdWrite18(u8 rt) { // SDATAOUT + CDR_LOG("cdvdWrite18(SDataOut) %x", rt); + Console::WriteLn("*PCSX2* SDATAOUT"); +} + +static __forceinline void cdvdWrite3A(u8 rt) { // DEC-SET + CDR_LOG("cdvdWrite3A(DecSet) %x", rt); + cdvd.decSet = rt; + Console::WriteLn("DecSet Write: %02X", params cdvd.decSet); +} + +void cdvdWrite(u8 key, u8 rt) +{ + switch (key) + { + case 0x04: cdvdWrite04(rt); break; + case 0x05: cdvdWrite05(rt); break; + case 0x06: cdvdWrite06(rt); break; + case 0x07: cdvdWrite07(rt); break; + case 0x08: cdvdWrite08(rt); break; + case 0x0A: cdvdWrite0A(rt); break; + case 0x0F: cdvdWrite0F(rt); break; + case 0x14: cdvdWrite14(rt); break; + case 0x16: cdvdWrite16(rt); break; + case 0x17: cdvdWrite17(rt); break; + case 0x18: cdvdWrite18(rt); break; + case 0x3A: cdvdWrite3A(rt); break; + default: + Console::Notice("IOP Unknown 8bit write to addr 0x1f4020%x = 0x%x", params key, rt); + break; + } +} diff --git a/pcsx2/CDVD/CDVD.h b/pcsx2/CDVD/CDVD.h index 0fd7822a38..a069da4a3a 100644 --- a/pcsx2/CDVD/CDVD.h +++ b/pcsx2/CDVD/CDVD.h @@ -18,7 +18,11 @@ #pragma once + #include "IopCommon.h" +#include "CDVD/CDVDaccess.h" + +extern char isoFileName[]; #define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ #define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ @@ -97,7 +101,11 @@ extern void cdvdActionInterrupt(); extern void cdvdReadInterrupt(); // We really should not have a function with the exact same name as a callback except for case! +extern void cdvdDetectDisk(); extern void cdvdNewDiskCB(); extern u8 cdvdRead(u8 key); extern void cdvdWrite(u8 key, u8 rt); +extern CDVDplugin CDVD; +extern CDVDplugin ISO; +extern CDVDplugin NODISC; diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp new file mode 100644 index 0000000000..da1242ab6a --- /dev/null +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -0,0 +1,534 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" + +// TODO: fix this for linux! (hardcoded as _WIN32 only) +#define ENABLE_TIMESTAMPS + +#ifdef _WIN32 +#include +#endif + +#include +#include + +#include "IopCommon.h" +#include "IsoFStools.h" +#include "IsoFSdrv.h" +#include "CDVDisoReader.h" + +static int diskTypeCached=-1; + +int lastReadSize; +static int plsn=0; // This never gets set, so it's always 0. + +static isoFile *blockDumpFile; + +///////////////////////////////////////////////// +// +// Disk Type detection stuff (from cdvdGigaherz) +// + +int CheckDiskTypeFS(int baseType) +{ + int f; + char buffer[256];//if a file is longer...it should be shorter :D + char *pos; + static struct TocEntry tocEntry; + + IsoFS_init(); + + // check if the file exists + if ((f=IsoFS_open("SYSTEM.CNF;1", 1)) >= 0) + { + int size = IsoFS_read(f, buffer, 256); + IsoFS_close(f); + + buffer[size]='\0'; + + pos = strstr(buffer, "BOOT2"); + if (pos == NULL) + { + pos = strstr(buffer, "BOOT"); + if (pos == NULL) return CDVD_TYPE_ILLEGAL; + return CDVD_TYPE_PSCD; + } + return (baseType==CDVD_TYPE_DETCTCD) ? CDVD_TYPE_PS2CD : CDVD_TYPE_PS2DVD; + } + + if (IsoFS_findFile("PSX.EXE;1", &tocEntry) == TRUE) + { + return CDVD_TYPE_PSCD; + } + + if (IsoFS_findFile("VIDEO_TS/VIDEO_TS.IFO;1", &tocEntry) == TRUE) + { + return CDVD_TYPE_DVDV; + } + + return CDVD_TYPE_ILLEGAL; // << Only for discs which aren't ps2 at all. +} + +static char bleh[2352]; + +int FindDiskType(int mType) +{ + int dataTracks = 0; + int audioTracks = 0; + + int iCDType = mType; + + cdvdTN tn; + + CDVD.getTN(&tn); + + if (tn.strack != tn.etrack) // multitrack == CD. + { + iCDType = CDVD_TYPE_DETCTCD; + } + else if (mType < 0) + { + cdvdTD td; + CDVD.getTD(0,&td); + if (td.lsn > 452849) + { + iCDType = CDVD_TYPE_DETCTDVDS; + } + else if (DoCDVDreadSector((u8*)bleh,16,CDVD_MODE_2048) == 0) + { + struct cdVolDesc* volDesc=(struct cdVolDesc *)bleh; + if (volDesc) + { + if(volDesc->rootToc.tocSize==2048) + iCDType = CDVD_TYPE_DETCTCD; + else + iCDType = CDVD_TYPE_DETCTDVDS; + } + } + } + + if (iCDType == CDVD_TYPE_DETCTDVDS) + { + s32 dlt = 0; + u32 l1s = 0; + + if(CDVD.getDualInfo(&dlt,&l1s)==0) + { + if (dlt > 0) iCDType = CDVD_TYPE_DETCTDVDD; + } + } + + switch(iCDType) + { + case CDVD_TYPE_DETCTCD: + Console::Status(" * CDVD Disk Open: CD, %d tracks (%d to %d):", params tn.etrack-tn.strack+1,tn.strack,tn.etrack); + break; + + case CDVD_TYPE_DETCTDVDS: + Console::Status(" * CDVD Disk Open: DVD, Single layer or unknown:"); + break; + + case CDVD_TYPE_DETCTDVDD: + Console::Status(" * CDVD Disk Open: DVD, Double layer:"); + break; + } + + audioTracks = dataTracks = 0; + for(int i = tn.strack; i <= tn.etrack; i++) + { + cdvdTD td,td2; + CDVD.getTD(i,&td); + + if (tn.etrack > i) + CDVD.getTD(i+1,&td2); + else + CDVD.getTD(0,&td2); + + int tlength = td2.lsn - td.lsn; + + if (td.type == CDVD_AUDIO_TRACK) + { + audioTracks++; + Console::Status(" * * Track %d: Audio (%d sectors)", params i,tlength); + } + else + { + dataTracks++; + Console::Status(" * * Track %d: Data (Mode %d) (%d sectors)", params i,((td.type==CDVD_MODE1_TRACK)?1:2),tlength); + } + } + + if (dataTracks > 0) + { + iCDType=CheckDiskTypeFS(iCDType); + } + + if (audioTracks > 0) + { + switch (iCDType) + { + case CDVD_TYPE_PS2CD: + iCDType=CDVD_TYPE_PS2CDDA; + break; + case CDVD_TYPE_PSCD: + iCDType=CDVD_TYPE_PSCDDA; + break; + default: + iCDType=CDVD_TYPE_CDDA; + break; + } + } + + return iCDType; +} + +void DetectDiskType() +{ + if (CDVD.getTrayStatus() == CDVD_TRAY_OPEN) + { + diskTypeCached = CDVD_TYPE_NODISC; + return; + } + + int baseMediaType = CDVD.getDiskType(); + int mType = -1; + + switch(baseMediaType) // Paranoid mode: do not trust the plugin's detection system to work correctly. + { + case CDVD_TYPE_CDDA: + case CDVD_TYPE_PSCD: + case CDVD_TYPE_PS2CD: + case CDVD_TYPE_PSCDDA: + case CDVD_TYPE_PS2CDDA: + mType = CDVD_TYPE_DETCTCD; + break; + + case CDVD_TYPE_DVDV: + case CDVD_TYPE_PS2DVD: + mType = CDVD_TYPE_DETCTDVDS; + break; + + case CDVD_TYPE_DETCTDVDS: + case CDVD_TYPE_DETCTDVDD: + case CDVD_TYPE_DETCTCD: + mType = baseMediaType; + break; + + case CDVD_TYPE_NODISC: + diskTypeCached = CDVD_TYPE_NODISC; + return; + } + + diskTypeCached = FindDiskType(mType); +} + +// +///////////////////////////////////////////////// + +s32 DoCDVDinit() +{ + diskTypeCached = -1; + + if(CDVD.initCount) *CDVD.initCount++; // used to handle the case where the plugin was inited at boot, but then iso takes over + return CDVD.init(); +} + +void DoCDVDshutdown() +{ + if(CDVD.initCount) *CDVD.initCount--; + CDVD.shutdown(); +} + +s32 DoCDVDopen(const char* pTitleFilename) +{ + int ret = CDVD.open(pTitleFilename); + int cdtype = DoCDVDdetectDiskType(); + + if((Config.Blockdump)&&(cdtype != CDVD_TYPE_NODISC)) + { + char fname_only[g_MaxPath]; + + if(CDVD.init == ISO.init) + { +#ifdef _WIN32 + char fname[MAX_PATH], ext[g_MaxPath]; + _splitpath(isoFileName, NULL, NULL, fname, ext); + _makepath(fname_only, NULL, NULL, fname, NULL); +#else + getcwd(fname_only, ArraySize(fname_only)); // Base it out of the current directory for now. + strcat(fname_only, Path::GetFilenameWithoutExt(isoFileName).c_str()); +#endif + } + else + { + strcpy(fname_only, "Untitled"); + } + +#ifdef ENABLE_TIMESTAMPS +#ifdef _WIN32 + SYSTEMTIME time; + GetLocalTime(&time); + + sprintf( + fname_only+strlen(fname_only), + " (%04d-%02d-%02d %02d-%02d-%02d).dump", + time.wYear, time.wMonth, time.wDay, + time.wHour, time.wMinute, time.wSecond); +#else + time_t rawtime; + struct tm * timeinfo; + + time(&rawtime); + timeinfo = localtime(&rawtime); + + sprintf( + fname_only+strlen(fname_only), + " (%04d-%02d-%02d %02d-%02d-%02d).dump", + timeinfo->tm_year + 1900, timeinfo->tm_mon, timeinfo->tm_mday, + timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); +#endif +#else + strcat(fname_only, ".dump"); +#endif + cdvdTD td; + CDVD.getTD(0, &td); + + int blockofs = 0; + int blocksize = 0; + int blocks = td.lsn; + + switch(cdtype) + { + case CDVD_TYPE_PS2DVD: + case CDVD_TYPE_DVDV: + case CDVD_TYPE_DETCTDVDS: + case CDVD_TYPE_DETCTDVDD: + blockofs = 24; + blocksize = 2048; + break; + + default: + blockofs = 0; + blocksize= 2352; + break; + } + + blockDumpFile = isoCreate(fname_only, ISOFLAGS_BLOCKDUMP); + if (blockDumpFile) isoSetFormat(blockDumpFile, blockofs, blocksize, blocks); + } + else + { + blockDumpFile = NULL; + } + + return ret; +} + +void DoCDVDclose() +{ + if(blockDumpFile) isoClose(blockDumpFile); + CDVD.close(); +} + +s32 DoCDVDreadSector(u8* buffer, u32 lsn, int mode) +{ + int ret = CDVD.readSector(buffer,lsn,mode); + + if(ret==0) + { + if (blockDumpFile != NULL) + { + isoWriteBlock(blockDumpFile, buffer, plsn); + } + } + return ret; +} + +s32 DoCDVDreadTrack(u32 lsn, int mode) +{ + // TEMP: until all the plugins use the new CDVDgetBuffer style + switch (mode) + { + case CDVD_MODE_2352: + lastReadSize = 2352; + break; + case CDVD_MODE_2340: + lastReadSize = 2340; + break; + case CDVD_MODE_2328: + lastReadSize = 2328; + break; + case CDVD_MODE_2048: + lastReadSize = 2048; + break; + } + + //DevCon::Notice("CDVD readTrack(lsn=%d,mode=%d)",params lsn, lastReadSize); + + return CDVD.readTrack(lsn,mode); +} + +// return can be NULL (for async modes) + +s32 DoCDVDgetBuffer(u8* buffer) +{ + int ret = CDVD.getBuffer2(buffer); + + if (ret == 0) + { + if (blockDumpFile != NULL) + { + isoWriteBlock(blockDumpFile, buffer, plsn); + } + } + + return ret; +} + +s32 DoCDVDdetectDiskType() +{ + if(diskTypeCached<0) DetectDiskType(); + + return diskTypeCached; +} + +void DoCDVDresetDiskTypeCache() +{ + diskTypeCached = -1; +} + +//////////////////////////////////////////////////////// +// +// CDVD null interface for Run BIOS menu + + +s32 CALLBACK NODISCinit() +{ + return 0; +} + +s32 CALLBACK NODISCopen(const char* pTitle) +{ + return 0; +} + +void CALLBACK NODISCclose() +{ +} + +void CALLBACK NODISCshutdown() +{ +} + +s32 CALLBACK NODISCreadTrack(u32 lsn, int mode) +{ + return -1; +} + +// return can be NULL (for async modes) +u8* CALLBACK NODISCgetBuffer() +{ + return NULL; +} + +s32 CALLBACK NODISCreadSubQ(u32 lsn, cdvdSubQ* subq) +{ + return -1; +} + +s32 CALLBACK NODISCgetTN(cdvdTN *Buffer) +{ + return -1; +} + +s32 CALLBACK NODISCgetTD(u8 Track, cdvdTD *Buffer) +{ + return -1; +} + +s32 CALLBACK NODISCgetTOC(void* toc) +{ + return -1; +} + +s32 CALLBACK NODISCgetDiskType() +{ + return CDVD_TYPE_NODISC; +} + +s32 CALLBACK NODISCgetTrayStatus() +{ + return CDVD_TRAY_CLOSE; +} + +s32 CALLBACK NODISCdummyS32() +{ + return 0; +} + +void CALLBACK NODISCdummyVOID() +{ +} + +void CALLBACK NODISCnewDiskCB(void(CALLBACK*)()) +{ +} + +s32 CALLBACK NODISCreadSector(u8* tempbuffer, u32 lsn, int mode) +{ + return -1; +} + +s32 CALLBACK NODISCgetBuffer2(u8* buffer) +{ + return -1; +} + +s32 CALLBACK NODISCgetDualInfo(s32* dualType, u32* _layer1start) +{ + return -1; +} + +CDVDplugin NODISC = { + NODISCinit, + NODISCopen, + NODISCclose, + NODISCshutdown, + NODISCreadTrack, + NODISCgetBuffer, + NODISCreadSubQ, + NODISCgetTN, + NODISCgetTD, + NODISCgetTOC, + NODISCgetDiskType, + NODISCgetTrayStatus, + NODISCdummyS32, + NODISCdummyS32, + + NODISCdummyVOID, + NODISCdummyS32, + NODISCdummyVOID, + NODISCnewDiskCB, + + NODISCreadSector, + NODISCgetBuffer2, + NODISCgetDualInfo, + + NULL +}; diff --git a/pcsx2/CDVD/CDVDaccess.h b/pcsx2/CDVD/CDVDaccess.h new file mode 100644 index 0000000000..ff4124dae1 --- /dev/null +++ b/pcsx2/CDVD/CDVDaccess.h @@ -0,0 +1,34 @@ +/* Pcsx2 - Pc Ps2 Emulator +* Copyright (C) 2002-2009 Pcsx2 Team +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#ifndef __CDVD_ACCESS_H__ +#define __CDVD_ACCESS_H__ + +extern s32 DoCDVDinit(); +extern s32 DoCDVDopen(const char* pTitleFilename); +extern void DoCDVDclose(); +extern void DoCDVDshutdown(); +extern s32 DoCDVDreadSector(u8* buffer, u32 lsn, int mode); +extern s32 DoCDVDreadTrack(u32 lsn, int mode); +extern s32 DoCDVDgetBuffer(u8* buffer); +extern s32 DoCDVDreadSubQ(u32 lsn, cdvdSubQ* subq); +extern void DoCDVDnewDiskCB(void (*callback)()); +extern s32 DoCDVDdetectDiskType(); +extern void DoCDVDresetDiskTypeCache(); + +#endif /* __CDVD_H__ */ diff --git a/pcsx2/CDVD/CDVDisoReader.cpp b/pcsx2/CDVD/CDVDisoReader.cpp new file mode 100644 index 0000000000..4b8f9b21b2 --- /dev/null +++ b/pcsx2/CDVD/CDVDisoReader.cpp @@ -0,0 +1,486 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * Original code from libcdvd by Hiryu & Sjeep (C) 2002 + * Modified by Florin for PCSX2 emu + * Fixed CdRead by linuzappz + */ + +#include "PrecompiledHeader.h" +#include +#include +#include + +#include "CDVDisoReader.h" + +char isoFileName[g_MaxPath]; + +u8 *pbuffer; +int cdtype; + +static int psize; + +isoFile *iso; + +FILE *cdvdLog = NULL; + +u8 cdbuffer[2352] = {0}; + +s32 msf_to_lba(u8 m, u8 s, u8 f) +{ + u32 lsn; + lsn = f; + lsn += (s - 2) * 75; + lsn += m * 75 * 60; + return lsn; +} + +void lba_to_msf(s32 lba, u8* m, u8* s, u8* f) +{ + lba += 150; + *m = lba / (60 * 75); + *s = (lba / 75) % 60; + *f = lba % 75; +} + +//#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ +//#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ + + +/*#ifdef PCSX2_DEBUG +void __Log(char *fmt, ...) +{ + va_list list; + + if (cdvdLog == NULL) return; + + va_start(list, fmt); + vfprintf(cdvdLog, fmt, list); + va_end(list); +} +#else +#define __Log 0&& +#endif*/ + +s32 CALLBACK ISOinit() +{ +/*#ifdef PCSX2_DEBUG + cdvdLog = fopen("logs/cdvdLog.txt", "w"); + if (cdvdLog == NULL) + { + cdvdLog = fopen("cdvdLog.txt", "w"); + if (cdvdLog == NULL) + { + Console::Error("Can't create cdvdLog.txt"); + return -1; + } + } + setvbuf(cdvdLog, NULL, _IONBF, 0);*/ + CDVD_LOG("CDVDinit\n"); +/*#endif*/ + + return 0; +} + +void CALLBACK ISOshutdown() +{ +/*#ifdef CDVD_LOG + if (cdvdLog != NULL) fclose(cdvdLog); +#endif*/ +} + +s32 CALLBACK ISOopen(const char* pTitle) +{ + //if (pTitle != NULL) strcpy(isoFileName, pTitle); + + iso = isoOpen(isoFileName); + if (iso == NULL) + { + Console::Error("Error loading %s\n", params isoFileName); + return -1; + } + + switch (iso->type) + { + case ISOTYPE_DVD: + cdtype = CDVD_TYPE_PS2DVD; + break; + case ISOTYPE_AUDIO: + cdtype = CDVD_TYPE_CDDA; + break; + default: + cdtype = CDVD_TYPE_PS2CD; + break; + } + + return 0; +} + +void CALLBACK ISOclose() +{ + isoClose(iso); +} + +s32 CALLBACK ISOreadSubQ(u32 lsn, cdvdSubQ* subq) +{ + // fake it + u8 min, sec, frm; + subq->ctrl = 4; + subq->mode = 1; + subq->trackNum = itob(1); + subq->trackIndex = itob(1); + + lba_to_msf(lsn, &min, &sec, &frm); + subq->trackM = itob(min); + subq->trackS = itob(sec); + subq->trackF = itob(frm); + + subq->pad = 0; + + lba_to_msf(lsn + (2*75), &min, &sec, &frm); + subq->discM = itob(min); + subq->discS = itob(sec); + subq->discF = itob(frm); + return 0; +} + +s32 CALLBACK ISOgetTN(cdvdTN *Buffer) +{ + Buffer->strack = 1; + Buffer->etrack = 1; + + return 0; +} + +s32 CALLBACK ISOgetTD(u8 Track, cdvdTD *Buffer) +{ + if (Track == 0) + { + Buffer->lsn = iso->blocks; + } + else + { + Buffer->type = CDVD_MODE1_TRACK; + Buffer->lsn = 0; + } + + return 0; +} + +static s32 layer1start = -1; + +static void FindLayer1Start() +{ + if ((layer1start == -1) && iso->blocks >= 2295104) + { + // search for it + int off = iso->blockofs; + u8 tempbuffer[2352]; + + Console::Status("CDVD ISO: searching for layer1..."); + //tempbuffer = (u8*)malloc(CD_FRAMESIZE_RAW); + for (layer1start = (iso->blocks / 2 - 0x10) & ~0xf; layer1start < 0x200010; layer1start += 16) + { + isoReadBlock(iso, tempbuffer+off, layer1start); + // CD001 + if ((tempbuffer[off+1] == 0x43) && + (tempbuffer[off+2] == 0x44) && + (tempbuffer[off+3] == 0x30) && + (tempbuffer[off+4] == 0x30) && + (tempbuffer[off+5] == 0x31) + ) + break; + } + //free(tempbuffer); + + if(layer1start == 0x200010) + { + Console::Status("Couldn't find second layer on dual layer... ignoring\n"); + layer1start=-2; + } + + if(layer1start>=0) Console::Status("found at 0x%8.8x\n", params layer1start); + } +} + +s32 CALLBACK ISOgetDualInfo(s32* dualType, u32* _layer1start) +{ + FindLayer1Start(); + + if(layer1start<0) + { + *dualType=0; + *_layer1start = iso->blocks; + } + else + { + *dualType = 1; + *_layer1start = layer1start; + } + return 1; +} + +s32 CALLBACK ISOgetDiskType() +{ + return cdtype; +} + +s32 CALLBACK ISOgetTOC(void* toc) +{ + u8 type = ISOgetDiskType(); + u8* tocBuff = (u8*)toc; + + //__Log("CDVDgetTOC\n"); + + if (type == CDVD_TYPE_DVDV || type == CDVD_TYPE_PS2DVD) + { + // get dvd structure format + // scsi command 0x43 + memset(tocBuff, 0, 2048); + + FindLayer1Start(); + + if (layer1start < 0) + { + // fake it + tocBuff[ 0] = 0x04; + tocBuff[ 1] = 0x02; + tocBuff[ 2] = 0xF2; + tocBuff[ 3] = 0x00; + tocBuff[ 4] = 0x86; + tocBuff[ 5] = 0x72; + + tocBuff[16] = 0x00; + tocBuff[17] = 0x03; + tocBuff[18] = 0x00; + tocBuff[19] = 0x00; + return 0; + } + else + { + // dual sided + tocBuff[ 0] = 0x24; + tocBuff[ 1] = 0x02; + tocBuff[ 2] = 0xF2; + tocBuff[ 3] = 0x00; + tocBuff[ 4] = 0x41; + tocBuff[ 5] = 0x95; + + tocBuff[14] = 0x60; // dual sided, ptp + + tocBuff[16] = 0x00; + tocBuff[17] = 0x03; + tocBuff[18] = 0x00; + tocBuff[19] = 0x00; + + s32 l1s = layer1start + 0x30000 - 1; + tocBuff[20] = (l1s >> 24); + tocBuff[21] = (l1s >> 16) & 0xff; + tocBuff[22] = (l1s >> 8) & 0xff; + tocBuff[23] = (l1s >> 0) & 0xff; + } + } + else if ((type == CDVD_TYPE_CDDA) || (type == CDVD_TYPE_PS2CDDA) || + (type == CDVD_TYPE_PS2CD) || (type == CDVD_TYPE_PSCDDA) || (type == CDVD_TYPE_PSCD)) + { + // cd toc + // (could be replaced by 1 command that reads the full toc) + u8 min, sec, frm; + s32 i, err; + cdvdTN diskInfo; + cdvdTD trackInfo; + memset(tocBuff, 0, 1024); + if (ISOgetTN(&diskInfo) == -1) + { + diskInfo.etrack = 0; + diskInfo.strack = 1; + } + if (ISOgetTD(0, &trackInfo) == -1) trackInfo.lsn = 0; + + tocBuff[0] = 0x41; + tocBuff[1] = 0x00; + + //Number of FirstTrack + tocBuff[2] = 0xA0; + tocBuff[7] = itob(diskInfo.strack); + + //Number of LastTrack + tocBuff[12] = 0xA1; + tocBuff[17] = itob(diskInfo.etrack); + + //DiskLength + lba_to_msf(trackInfo.lsn, &min, &sec, &frm); + tocBuff[22] = 0xA2; + tocBuff[27] = itob(min); + tocBuff[28] = itob(sec); + + for (i = diskInfo.strack; i <= diskInfo.etrack; i++) + { + err = ISOgetTD(i, &trackInfo); + lba_to_msf(trackInfo.lsn, &min, &sec, &frm); + tocBuff[i*10+30] = trackInfo.type; + tocBuff[i*10+32] = err == -1 ? 0 : itob(i); //number + tocBuff[i*10+37] = itob(min); + tocBuff[i*10+38] = itob(sec); + tocBuff[i*10+39] = itob(frm); + } + } + else + return -1; + + return 0; +} + +s32 CALLBACK ISOreadSector(u8* tempbuffer, u32 lsn, int mode) +{ + int _lsn = lsn; + + if (_lsn < 0) lsn = iso->blocks + _lsn; + if (lsn > iso->blocks) return -1; + + if(mode == CDVD_MODE_2352) + { + isoReadBlock(iso, tempbuffer, lsn); + return 0; + } + + isoReadBlock(iso, cdbuffer + iso->blockofs, lsn); + + pbuffer = cdbuffer; + switch (mode) + { + case CDVD_MODE_2352: + psize = 2352; + break; + case CDVD_MODE_2340: + pbuffer += 12; + psize = 2340; + break; + case CDVD_MODE_2328: + pbuffer += 24; + psize = 2328; + break; + case CDVD_MODE_2048: + pbuffer += 24; + psize = 2048; + break; + } + + memcpy_fast(tempbuffer,pbuffer,psize); + + return 0; +} + +s32 CALLBACK ISOreadTrack(u32 lsn, int mode) +{ + int _lsn = lsn; + + if (_lsn < 0) lsn = iso->blocks + _lsn; + if (lsn > iso->blocks) return -1; + + isoReadBlock(iso, cdbuffer + iso->blockofs, lsn); + + pbuffer = cdbuffer; + switch (mode) + { + case CDVD_MODE_2352: + psize = 2352; + break; + case CDVD_MODE_2340: + pbuffer += 12; + psize = 2340; + break; + case CDVD_MODE_2328: + pbuffer += 24; + psize = 2328; + break; + case CDVD_MODE_2048: + pbuffer += 24; + psize = 2048; + break; + } + + return 0; +} + +s32 CALLBACK ISOgetBuffer2(u8* buffer) +{ + memcpy_fast(buffer,pbuffer,psize); + return 0; +} + +u8* CALLBACK ISOgetBuffer() +{ + return pbuffer; +} + +s32 CALLBACK ISOgetTrayStatus() +{ + return CDVD_TRAY_CLOSE; +} + +s32 CALLBACK ISOctrlTrayOpen() +{ + return 0; +} +s32 CALLBACK ISOctrlTrayClose() +{ + return 0; +} + +s32 CALLBACK ISOdummyS32() +{ + return 0; +} + +void CALLBACK ISOdummyVOID() +{ +} + +void CALLBACK ISOnewDiskCB(void(CALLBACK*)()) +{ +} + +CDVDplugin ISO = { + ISOinit, + ISOopen, + ISOclose, + ISOshutdown, + ISOreadTrack, + ISOgetBuffer, // emu shouldn't use this one. + ISOreadSubQ, + ISOgetTN, + ISOgetTD, + ISOgetTOC, + ISOgetDiskType, + ISOdummyS32, + ISOdummyS32, + ISOdummyS32, + + ISOdummyVOID, + ISOdummyS32, + ISOdummyVOID, + ISOnewDiskCB, + + ISOreadSector, + ISOgetBuffer2, + ISOgetDualInfo, + + NULL +}; diff --git a/pcsx2/CDVD/CDVDisoReader.h b/pcsx2/CDVD/CDVDisoReader.h new file mode 100644 index 0000000000..cb0448d72a --- /dev/null +++ b/pcsx2/CDVD/CDVDisoReader.h @@ -0,0 +1,48 @@ +/* Pcsx2 - Pc Ps2 Emulator +* Copyright (C) 2002-2009 Pcsx2 Team +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#ifndef __CDVD_ISO_READER_H__ +#define __CDVD_ISO_READER_H__ + +#ifdef _MSC_VER +#pragma warning(disable:4018) +#endif + +#include + +#include "IopCommon.h" +#include "IsoFStools.h" +#include "IsoFileFormats.h" + +//#define CDVD_LOG __Log + +//#ifndef MAX_PATH +//#define MAX_PATH 255 +//#endif + +//extern FILE *cdvdLog; + +//void __Log(char *fmt, ...); + +//#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ +//#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ + +extern char isoFileName[g_MaxPath]; +extern isoFile *iso; + +#endif \ No newline at end of file diff --git a/pcsx2/CDVD/CDVDlib.h b/pcsx2/CDVD/CDVDlib.h deleted file mode 100644 index b942055fbf..0000000000 --- a/pcsx2/CDVD/CDVDlib.h +++ /dev/null @@ -1,171 +0,0 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2008 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ -/* - * Original code from libcdvd by Hiryu & Sjeep (C) 2002 - * Linux kernel headers - * Modified by Florin for PCSX2 emu - */ - -#ifndef _CDVDLIB_H -#define _CDVDLIB_H - -#include "Common.h" - -// Macros for READ Data pattan -#define CdSecS2048 0 // sector size 2048 -#define CdSecS2328 1 // sector size 2328 -#define CdSecS2340 2 // sector size 2340 - -//#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/ -//#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/ -//#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */ -//#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */ -//#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */ - -/* - * A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336, - * 2340, or 2352 bytes long. - * Sector types of the standard CD-ROM data formats: - * - * format sector type user data size (bytes) - * ----------------------------------------------------------------------------- - * 1 (Red Book) CD-DA 2352 (CD_FRAMESIZE_RAW) - * 2 (Yellow Book) Mode1 Form1 2048 (CD_FRAMESIZE) - * 3 (Yellow Book) Mode1 Form2 2336 (CD_FRAMESIZE_RAW0) - * 4 (Green Book) Mode2 Form1 2048 (CD_FRAMESIZE) - * 5 (Green Book) Mode2 Form2 2328 (2324+4 spare bytes) - * - * - * The layout of the standard CD-ROM data formats: - * ----------------------------------------------------------------------------- - * - audio (red): | audio_sample_bytes | - * | 2352 | - * - * - data (yellow, mode1): | sync - head - data - EDC - zero - ECC | - * | 12 - 4 - 2048 - 4 - 8 - 276 | - * - * - data (yellow, mode2): | sync - head - data | - * | 12 - 4 - 2336 | - * - * - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC | - * | 12 - 4 - 8 - 2048 - 4 - 276 | - * - * - XA data (green, mode2 form2): | sync - head - sub - data - Spare | - * | 12 - 4 - 8 - 2324 - 4 | - * - */ - -// Macros for Spindle control -#define CdSpinMax 0 -#define CdSpinNom 1 // Starts reading data at maximum rotational velocity and if a read error occurs, the rotational velocity is reduced. -#define CdSpinStm 0 // Recommended stream rotation speed. - -// Macros for TrayReq -#define CdTrayOpen 0 -#define CdTrayClose 1 -#define CdTrayCheck 2 - -/* - * Macros for sceCdGetDiskType() //comments translated from japanese;) - */ - -// These are already declared with different names in PS2Edefs.h. And aren't used. -#define SCECdIllgalMedia 0xff // ILIMEDIA (Illegal Media) A non-PS / non-PS2 Disc. -#define SCECdDVDV 0xfe // DVDV (DVD Video) A non-PS / non-PS2 Disc, but a DVD Video Disc -#define SCECdCDDA 0xfd // CDDA (CD DA) A non-PS / non-PS2 Disc that include a DA track -#define SCECdPS2DVD 0x14 // PS2DVD PS2 consumer DVD. -#define SCECdPS2CDDA 0x13 // PS2CDDA PS2 consumer CD that includes a DA track -#define SCECdPS2CD 0x12 // PS2CD PS2 consumer CD that does not include a DA track -#define SCECdPSCDDA 0x11 // PSCDDA PS CD that includes a DA track -#define SCECdPSCD 0x10 // PSCD PS CD that does not include a DA track -#define SCECdDETCT 0x01 // DETCT (Detecting) Disc distinction action -#define SCECdNODISC 0x00 // NODISC (No disc) No disc entered - -/* - * Media mode - */ -#define SCECdCD 1 -#define SCECdDVD 2 - -typedef struct { - u8 stat; // 0: normal. Any other: error - u8 second; // second (BCD value) - u8 minute; // minute (BCD value) - u8 hour; // hour (BCD value) - u8 week; // week (BCD value) - u8 day; // day (BCD value) - u8 month; // month (BCD value) - u8 year; // year (BCD value) -} CdCLOCK; - -typedef struct { - u32 lsn; // Logical sector number of file - u32 size; // File size (in bytes) - char name[16]; // Filename - u8 date[8]; // 1th: Seconds - // 2th: Minutes - // 3th: Hours - // 4th: Date - // 5th: Month - // 6th 7th: Year (4 digits) -} CdlFILE; - -typedef struct { - u8 minute; // Minutes - u8 second; // Seconds - u8 sector; // Sector - u8 track; // Track number -} CdlLOCCD; - -typedef struct { - u8 trycount; // Read try count (No. of error retries + 1) (0 - 255) - u8 spindlctrl; // SCECdSpinStm: Recommended stream rotation speed. - // SCECdSpinNom: Starts reading data at maximum rotational velocity and if a read error occurs, the rotational velocity is reduced. - u8 datapattern; // SCECdSecS2048: Data size 2048 bytes - // SCECdSecS2328: 2328 bytes - // SCECdSecS2340: 2340 bytes - u8 pad; // Padding data produced by alignment. -} CdRMode; - -#if defined(_MSC_VER) -#pragma pack(1) -#endif - -struct TocEntry -{ - u32 fileLBA; - u32 fileSize; - u8 fileProperties; - u8 padding1[3]; - char filename[128+1]; - u8 date[7]; -#if defined(_MSC_VER) -}; -#else -} __attribute__((packed)); -#endif - -#if defined(_MSC_VER) -#pragma pack() -#endif - -int CDVD_findfile(const char* fname, struct TocEntry* tocEntry); -int CdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode); -int DvdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode); - -#endif // _CDVDLIB_H diff --git a/pcsx2/CDVD/CdRom.cpp b/pcsx2/CDVD/CdRom.cpp index 7f5c940d9a..99ffd205ed 100644 --- a/pcsx2/CDVD/CdRom.cpp +++ b/pcsx2/CDVD/CdRom.cpp @@ -141,7 +141,7 @@ static void ReadTrack() { cdr.Prev[2] = itob(cdr.SetSector[2]); CDR_LOG("KEY *** %x:%x:%x", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); - cdr.RErr = CDVDreadTrack(MSFtoLSN(cdr.SetSector), CDVD_MODE_2352); + cdr.RErr = DoCDVDreadTrack(MSFtoLSN(cdr.SetSector), CDVD_MODE_2340); } // cdr.Stat: @@ -332,7 +332,7 @@ void cdrInterrupt() { SetResultSize(3); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; - if (CDVDgetTN(&cdr.ResultTN) == -1) { + if (CDVD.getTN(&cdr.ResultTN) == -1) { cdr.Stat = DiskError; cdr.Result[0]|= 0x01; } else { @@ -347,7 +347,7 @@ void cdrInterrupt() { cdr.Track = btoi(cdr.Param[0]); SetResultSize(4); cdr.StatP|= 0x2; - if (CDVDgetTD(cdr.Track, &trackInfo) == -1) { + if (CDVD.getTD(cdr.Track, &trackInfo) == -1) { cdr.Stat = DiskError; cdr.Result[0]|= 0x01; } else { @@ -496,7 +496,6 @@ void cdrInterrupt() { } void cdrReadInterrupt() { - u8 *buf; if (!cdr.Reading) return; @@ -514,10 +513,9 @@ void cdrReadInterrupt() { cdr.Result[0] = cdr.StatP; Console::Status("Reading From CDR"); - buf = CDVDgetBuffer(); - if (buf == NULL) cdr.RErr = -1; - - if (cdr.RErr == -1) { + cdr.RErr = DoCDVDgetBuffer(cdr.Transfer); + if (cdr.RErr == -1) + { CDR_LOG(" err\n"); memzero_ptr<2340>(cdr.Transfer); cdr.Stat = DiskError; @@ -526,7 +524,6 @@ void cdrReadInterrupt() { CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); return; } - memcpy_fast(cdr.Transfer, buf+12, 2340); cdr.Stat = DataReady; CDR_LOG(" %x:%x:%x", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); diff --git a/pcsx2/CDVD/IsoFScdvd.h b/pcsx2/CDVD/IsoFScdvd.h new file mode 100644 index 0000000000..65867db5ba --- /dev/null +++ b/pcsx2/CDVD/IsoFScdvd.h @@ -0,0 +1,54 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +/* + * Original code from libcdvd by Hiryu & Sjeep (C) 2002 + * Linux kernel headers + * Modified by Florin for PCSX2 emu + */ + +#ifndef _ISOFSCDVD_H +#define _ISOFSCDVD_H + +#include "Common.h" + +#if defined(_MSC_VER) +#pragma pack(1) +#endif + +struct TocEntry +{ + u32 fileLBA; + u32 fileSize; + u8 fileProperties; + u8 padding1[3]; + char filename[128+1]; + u8 date[7]; +#if defined(_MSC_VER) +}; +#else +} __attribute__((packed)); +#endif + +#if defined(_MSC_VER) +#pragma pack() +#endif + +int IsoFS_findFile(const char* fname, struct TocEntry* tocEntry); +int IsoFS_readSectors(u32 lsn, u32 sectors, void *buf); + +#endif // _ISOFSCDVD_H diff --git a/pcsx2/CDVD/CDVDisodrv.cpp b/pcsx2/CDVD/IsoFSdrv.cpp similarity index 63% rename from pcsx2/CDVD/CDVDisodrv.cpp rename to pcsx2/CDVD/IsoFSdrv.cpp index aaf2dff0ef..ce014f892b 100644 --- a/pcsx2/CDVD/CDVDisodrv.cpp +++ b/pcsx2/CDVD/IsoFSdrv.cpp @@ -15,6 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + /* * Original code from libcdvd by Hiryu & Sjeep (C) 2002 * Modified by Florin for PCSX2 emu @@ -22,10 +23,8 @@ #include "PrecompiledHeader.h" -#include "CDVDiso.h" -#include "CDVDisodrv.h" - -CdRMode cdReadMode; +#include "IsoFStools.h" +#include "IsoFSdrv.h" struct fdtable{ //int fd; @@ -46,22 +45,12 @@ static int inited=FALSE; ////////////////////////////////////////////////////////////////////// // CDVDFS_init -// called by 80000592 sceCdInit() ////////////////////////////////////////////////////////////////////// -void CDVDFS_init(){ +void IsoFS_init() +{ + if (inited) return; //might change in the future as a param; forceInit/Reset - if (inited) return;//might change in the future as a param; forceInit/Reset - - RPC_LOG("[CDVDisodrv:init] CDVD Filesystem v1.00"); - RPC_LOG("[CDVDisodrv ] \tby A.Lee (aka Hiryu) & Nicholas Van Veen (aka Sjeep)"); - RPC_LOG("[CDVDisodrv ] Initializing '%s' file driver.", "cdfs"); - - //CdInit(0); already called by plugin loading system ;) - - cdReadMode.trycount = 0; - cdReadMode.spindlctrl = CdSpinStm; - cdReadMode.datapattern = CdSecS2048; //isofs driver only needs - //2KB sectors + ISOFS_LOG("[IsoFSdrv:init] Initializing '%s' file driver.", "IsoFS"); memzero_obj( fd_table ); memzero_obj( fd_used ); @@ -73,14 +62,13 @@ void CDVDFS_init(){ ////////////////////////////////////////////////////////////////////// // CDVDFS_open -// called by 80000001 fileio_open for devices: "cdrom:", "cdrom0:" ////////////////////////////////////////////////////////////////////// -int CDVDFS_open(const char *name, int mode){ +int IsoFS_open(const char *name, int mode){ int j; static struct TocEntry tocEntry; // check if the file exists - if (CDVD_findfile(name, &tocEntry) != TRUE) + if (IsoFS_findFile(name, &tocEntry) != TRUE) return -1; if(mode != 1) return -2; //SCE_RDONLY @@ -92,24 +80,23 @@ int CDVDFS_open(const char *name, int mode){ fd_used[j] = 1; files_open++; - RPC_LOG("[CDVDisodrv:open] internal fd=%d", j); + ISOFS_LOG("[IsoFSdrv:open] internal fd=%d", j); fd_table[j].fileSize = tocEntry.fileSize; fd_table[j].LBA = tocEntry.fileLBA; fd_table[j].filePos = 0; - RPC_LOG("[CDVDisodrv ] tocEntry.fileSize = %d",tocEntry.fileSize); + ISOFS_LOG("[IsoFSdrv:open] tocEntry.fileSize = %d",tocEntry.fileSize); return j; } ////////////////////////////////////////////////////////////////////// // CDVDFS_lseek -// called by 80000001 fileio_lseek for devices: "cdrom:", "cdrom0:" ////////////////////////////////////////////////////////////////////// -int CDVDFS_lseek(int fd, int offset, int whence){ +int IsoFS_lseek(int fd, int offset, int whence){ if ((fd >= 16) || (fd_used[fd]==0)){ - RPC_LOG("[CDVDisodrv:lseek] ERROR: File does not appear to be open!"); + ISOFS_LOG("[IsoFSdrv:lseek] ERROR: File does not appear to be open!"); return -1; } @@ -141,28 +128,27 @@ int CDVDFS_lseek(int fd, int offset, int whence){ ////////////////////////////////////////////////////////////////////// // CDVDFS_read -// called by 80000001 fileio_read for devices: "cdrom:", "cdrom0:", "cdfs:" ////////////////////////////////////////////////////////////////////// -int CDVDFS_read( int fd, char *buffer, int size ){ -// int start_sector; +int IsoFS_read( int fd, char *buffer, int size ) +{ int off_sector; -// int num_sectors; - - //static char local_buffer[2024*2048]; //4MB static char lb[2048]; //2KB + //Start, Aligned, End int ssector, asector, esector; int ssize=0, asize, esize; - if ((fd >= 16) || (fd_used[fd]==0)){ - RPC_LOG("[CDVDisodrv:read] ERROR: File does not appear to be open!"); + if ((fd >= 16) || (fd_used[fd]==0)) + { + ISOFS_LOG("[IsoFSdrv:read] ERROR: File does not appear to be open!"); return -1; } // A few sanity checks - if (fd_table[fd].filePos > fd_table[fd].fileSize){ + if (fd_table[fd].filePos > fd_table[fd].fileSize) + { // We cant start reading from past the beginning of the file - return 0; // File exists but we couldnt read anything from it + return 0; // File exists but we couldn't read anything from it } if ((fd_table[fd].filePos + size) > fd_table[fd].fileSize) @@ -171,7 +157,8 @@ int CDVDFS_read( int fd, char *buffer, int size ){ // Now work out where we want to start reading from asector = ssector = fd_table[fd].LBA + (fd_table[fd].filePos >> 11); off_sector = (fd_table[fd].filePos & 0x7FF); - if (off_sector){ + if (off_sector) + { ssize = std::min(2048 - off_sector, size); size -= ssize; asector++; @@ -181,22 +168,27 @@ int CDVDFS_read( int fd, char *buffer, int size ){ esector=asector + (asize >> 11); size += ssize; - RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X", ssector, esector-(esize==0)); + ISOFS_LOG("[IsoFSdrv:read] read sectors 0x%08X to 0x%08X", ssector, esector-(esize==0)); - if (ssize){ - if (CdRead(ssector, 1, lb, &cdReadMode) != TRUE){ - RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason"); + if (ssize) + { + if (IsoFS_readSectors(ssector, 1, lb) != TRUE) + { + ISOFS_LOG("[IsoFSdrv:read] Couldn't Read from file for some reason"); return 0; } memcpy_fast(buffer, lb + off_sector, ssize); } - if (asize) if (CdRead(asector, asize >> 11, buffer+ssize, &cdReadMode) != TRUE){ - RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason"); + if (asize) if (IsoFS_readSectors(asector, asize >> 11, buffer+ssize) != TRUE) + { + ISOFS_LOG("[IsoFSdrv:read] Couldn't Read from file for some reason"); return 0; } - if (esize){ - if (CdRead(esector, 1, lb, &cdReadMode) != TRUE){ - RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason"); + if (esize) + { + if (IsoFS_readSectors(esector, 1, lb) != TRUE) + { + ISOFS_LOG("[IsoFSdrv:read] Couldn't Read from file for some reason"); return 0; } memcpy_fast(buffer+ssize+asize, lb, esize); @@ -207,13 +199,13 @@ int CDVDFS_read( int fd, char *buffer, int size ){ off_sector = (fd_table[fd].filePos & 0x7FF); num_sectors = ((off_sector + size) >> 11) + 1; - RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X",start_sector,start_sector+num_sectors); + RPC_LOG("[IsoFSdrv:read] read sectors 0x%08X to 0x%08X",start_sector,start_sector+num_sectors); // Read the data (we only ever get 16KB max request at once) if (CdRead(start_sector, num_sectors, local_buffer, &cdReadMode) != TRUE){ //RPC_LOG("sector = %d, start sector = %d",sector,start_sector); - RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason"); + RPC_LOG("[IsoFSdrv: ] Couldn't Read from file for some reason"); return 0; } //CdSync(0); hm, a wait function maybe... @@ -225,27 +217,18 @@ int CDVDFS_read( int fd, char *buffer, int size ){ return (size); } -////////////////////////////////////////////////////////////////////// -// CDVDFS_write -// called by 80000001 fileio_write for devices: "cdrom:", "cdrom0:" -// hehe, this ain't a CD writing option :D -////////////////////////////////////////////////////////////////////// -int CDVDFS_write( int fd, char * buffer, int size ){ - if(size == 0) return 0; - else return -1; -} - ////////////////////////////////////////////////////////////////////// // CDVDFS_close -// called by 80000001 fileio_close for devices: "cdrom:", "cdrom0:" ////////////////////////////////////////////////////////////////////// -int CDVDFS_close( int fd){ +int IsoFS_close( int fd) +{ - if ((fd >= 16) || (fd_used[fd]==0)){ - RPC_LOG("[CDVDisodrv:close] ERROR: File does not appear to be open!"); + if ((fd >= 16) || (fd_used[fd]==0)) + { + ISOFS_LOG("[IsoFSdrv:close] ERROR: File does not appear to be open!"); return -1; } - RPC_LOG("[CDVDisodrv:close] internal fd %d", fd); + ISOFS_LOG("[IsoFSdrv:close] internal fd %d", fd); fd_used[fd] = 0; files_open--; diff --git a/pcsx2/CDVD/CDVDisodrv.h b/pcsx2/CDVD/IsoFSdrv.h similarity index 71% rename from pcsx2/CDVD/CDVDisodrv.h rename to pcsx2/CDVD/IsoFSdrv.h index 59286272dd..c3af3055b4 100644 --- a/pcsx2/CDVD/CDVDisodrv.h +++ b/pcsx2/CDVD/IsoFSdrv.h @@ -20,19 +20,16 @@ * Modified by Florin for PCSX2 emu */ -#ifndef __CDVDISODRV_H__ -#define __CDVDISODRV_H__ +#ifndef __ISOFSDRV_H__ +#define __ISOFSDRV_H__ -#include "CDVDlib.h" - -extern CdRMode cdReadMode; +#include "IsoFScdvd.h" /* Filing-system exported functions */ -void CDVDFS_init(); -int CDVDFS_open(const char *name, int mode); -int CDVDFS_lseek(int fd, int offset, int whence); -int CDVDFS_read( int fd, char * buffer, int size ); -int CDVDFS_write( int fd, char * buffer, int size ); -int CDVDFS_close( int fd); +void IsoFS_init(); +int IsoFS_open(const char *name, int mode); +int IsoFS_lseek(int fd, int offset, int whence); +int IsoFS_read( int fd, char * buffer, int size ); +int IsoFS_close( int fd); -#endif//__CDVDISODRV_H__ +#endif//__ISOFSDRV_H__ diff --git a/pcsx2/CDVD/CDVDiso.cpp b/pcsx2/CDVD/IsoFStools.cpp similarity index 81% rename from pcsx2/CDVD/CDVDiso.cpp rename to pcsx2/CDVD/IsoFStools.cpp index 2eb1031d94..4ef2d6cac8 100644 --- a/pcsx2/CDVD/CDVDiso.cpp +++ b/pcsx2/CDVD/IsoFStools.cpp @@ -15,17 +15,20 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + /* * Original code from libcdvd by Hiryu & Sjeep (C) 2002 * Modified by Florin for PCSX2 emu * Fixed CdRead by linuzappz */ + #include "PrecompiledHeader.h" #include -#include "CDVDiso.h" -#include "CDVDisodrv.h" +#include "IsoFStools.h" +#include "IsoFSdrv.h" +#include "CDVDaccess.h" struct dir_toc_data { @@ -168,79 +171,35 @@ int TocEntryCompare(char* filename, char* extensions){ #define CD_FRAMES 75 /* frames per second */ #define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ -int CdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode){ +int IsoFS_readSectors(u32 lsn, u32 sectors, void *buf) +{ u32 i; - u8* buff; - int rmode; - - switch (mode->datapattern) { - case CdSecS2048: - rmode = CDVD_MODE_2048; break; - case CdSecS2328: - rmode = CDVD_MODE_2328; break; - case CdSecS2340: - rmode = CDVD_MODE_2340; break; - default: - return 0; - } - for (i=0; idatapattern){ - case CdSecS2048: - memcpy_fast((void*)((uptr)buf+2048*i), buff, 2048);break;//only data - case CdSecS2328: - memcpy_fast((void*)((uptr)buf+2328*i), buff, 2328);break;//without sync & head & sub - case CdSecS2340: - memcpy_fast((void*)((uptr)buf+2340*i), buff, 2340);break;//without sync - } + for (i=0; idatapattern){ -// case CdSecS2064: - ((u32*)buf)[0] = i + 0x30000; - memcpy_fast((u8*)buf+12, buff, 2048); - buf = (char*)buf + 2064; break; -// default: -// return 0; -// } - } - - return 1; -} - /************************************************************** * The functions below are not exported for normal file-system * * operations, but are used by the file-system operations, and * * may also be exported for use via RPC * **************************************************************/ -int CDVD_GetVolumeDescriptor(void){ +int IsoFS_getVolumeDescriptor(void) +{ // Read until we find the last valid Volume Descriptor int volDescSector; cdVolDesc localVolDesc; - DbgCon::WriteLn("CDVD_GetVolumeDescriptor called"); + DbgCon::WriteLn("IsoFS_GetVolumeDescriptor called"); for (volDescSector = 16; volDescSector<20; volDescSector++) { - CdRead(volDescSector,1,&localVolDesc,&cdReadMode); + IsoFS_readSectors(volDescSector,1,&localVolDesc); // CdSync(0x00); // If this is still a volume Descriptor @@ -267,7 +226,7 @@ int CDVD_GetVolumeDescriptor(void){ return TRUE; } -int CDVD_findfile(const char* fname, TocEntry* tocEntry){ +int IsoFS_findFile(const char* fname, TocEntry* tocEntry){ char filename[g_MaxPath+1]; char pathname[JolietMaxPath+1]; char toc[2048]; @@ -284,24 +243,20 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){ dirTocEntry* tocEntryPointer; - DbgCon::WriteLn("CDVD_findfile called"); - - //make sure we have good cdReadMode - cdReadMode.trycount = 0; - cdReadMode.spindlctrl = CdSpinStm; - cdReadMode.datapattern = CdSecS2048; + DbgCon::WriteLn("IsoFS_findfile(\"%s\") called", params fname); _splitpath2(fname, pathname, filename); // Find the TOC for a specific directory - if (CDVD_GetVolumeDescriptor() != TRUE){ - RPC_LOG("Could not get CD Volume Descriptor"); + if (IsoFS_getVolumeDescriptor() != TRUE) + { + ISOFS_LOG("Could not get CD Volume Descriptor"); return -1; } // Read the TOC of the root directory - if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ - RPC_LOG("Couldn't Read from CD !"); + if (IsoFS_readSectors(CDVolDesc.rootToc.tocLBA,1,toc) != TRUE){ + ISOFS_LOG("Couldn't Read from CD !"); return -1; } //CdSync(0x00); @@ -360,7 +315,7 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){ // then load another sector current_sector++; - if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE) + if (IsoFS_readSectors(current_sector,1,toc) != TRUE) { Console::Error("Couldn't Read from CD !"); return -1; @@ -398,7 +353,7 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){ // If we havent found the directory name we wanted then fail if (found_dir != TRUE) { - Console::Notice( "CDVD_findfile: could not find dir" ); + Console::Notice( "IsoFS_findfile: could not find dir" ); return -1; } @@ -406,7 +361,7 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){ dirname = strtok( NULL, "\\/" ); // Read the TOC of the found subdirectory - if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE) + if (IsoFS_readSectors(localTocEntry.fileLBA,1,toc) != TRUE) { Console::Error("Couldn't Read from CD !"); return -1; @@ -422,7 +377,7 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){ tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); } - RPC_LOG("[RPC:cdvd] findfile: found dir, now looking for file"); + ISOFS_LOG("[IsoFStools] findfile: found dir, now looking for file"); tocEntryPointer = (dirTocEntry*)toc; @@ -453,7 +408,7 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){ strcpy(tocEntry->filename, localTocEntry.filename); memcpy(tocEntry->date, localTocEntry.date, 7); - DbgCon::WriteLn("CDVD_findfile: found file"); + DbgCon::WriteLn("IsoFS_findfile: found file"); return TRUE; } @@ -467,7 +422,7 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){ { dir_lba++; - if (CdRead(dir_lba,1,toc,&cdReadMode) != TRUE){ + if (IsoFS_readSectors(dir_lba,1,toc) != TRUE){ Console::Error("Couldn't Read from CD !"); return -1; } @@ -477,13 +432,13 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){ } } - DbgCon::Notice("CDVD_findfile: could not find file"); + DbgCon::Notice("IsoFS_findfile: could not find file"); return FALSE; } // This is the RPC-ready function which takes the request to start the tocEntry retrieval -int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_dirs){ +int IsoFS_initDirectoryList(char* pathname, char* extensions, unsigned int inc_dirs){ // int dir_depth = 1; char toc[2048]; char* dirname; @@ -501,16 +456,16 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d getDirTocData.inc_dirs = inc_dirs; // Find the TOC for a specific directory - if (CDVD_GetVolumeDescriptor() != TRUE){ - RPC_LOG("[RPC:cdvd] Could not get CD Volume Descriptor"); + if (IsoFS_getVolumeDescriptor() != TRUE){ + ISOFS_LOG("[IsoFStools] Could not get CD Volume Descriptor"); return -1; } - RPC_LOG("[RPC:cdvd] Getting Directory Listing for: \"%s\"", pathname); + ISOFS_LOG("[IsoFStools] Getting Directory Listing for: \"%s\"", pathname); // Read the TOC of the root directory - if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ - RPC_LOG("[RPC: ] Couldn't Read from CD !"); + if (IsoFS_readSectors(CDVolDesc.rootToc.tocLBA,1,toc) != TRUE){ + ISOFS_LOG("[IsoFStools] Couldn't Read from CD !"); return -1; } //CdSync(0x00); @@ -526,12 +481,12 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d // use strtok to get the next dir name - // if there isnt one, then assume we want the LBA + // if there isn't one, then assume we want the LBA // for the current one, and exit the while loop // if there is another dir name then increment dir_depth // and look through dir table entries until we find the right name - // if we dont find the right name + // if we don't find the right name // before finding an entry at a higher level (lower num), then return nothing localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA; @@ -550,8 +505,8 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d // then load another sector current_sector++; - if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE){ - RPC_LOG("[RPC: ] Couldn't Read from CD !"); + if (IsoFS_readSectors(current_sector,1,toc) != TRUE){ + ISOFS_LOG("[IsoFStools] Couldn't Read from CD !"); return -1; } @@ -573,8 +528,8 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d if (strcmp(dirname,localTocEntry.filename) == 0){ // if the name matches then we've found the directory found_dir = TRUE; - RPC_LOG("[RPC: ] Found directory %s in subdir at sector %d",dirname,current_sector); - RPC_LOG("[RPC: ] LBA of found subdirectory = %d",localTocEntry.fileLBA); + ISOFS_LOG("[IsoFStools] Found directory %s in subdir at sector %d",dirname,current_sector); + ISOFS_LOG("[IsoFStools] LBA of found subdirectory = %d",localTocEntry.fileLBA); break; } @@ -592,8 +547,8 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d dirname = strtok( NULL, "\\/" ); // Read the TOC of the found subdirectory - if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE){ - RPC_LOG("[RPC: ] Couldn't Read from CD !"); + if (IsoFS_readSectors(localTocEntry.fileLBA,1,toc) != TRUE){ + ISOFS_LOG("[IsoFStools] Couldn't Read from CD !"); return -1; } //CdSync(0x00); @@ -644,8 +599,8 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d // then load another sector getDirTocData.current_sector++; - if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ - RPC_LOG("[RPC: ] Couldn't Read from CD !"); + if (IsoFS_readSectors(getDirTocData.current_sector,1,toc) != TRUE){ + ISOFS_LOG("[IsoFStools] Couldn't Read from CD !"); return -1; } //CdSync(0x00); @@ -703,14 +658,14 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d // This function can be called repeatedly after CDVD_GetDir_RPC_request to get the actual entries // buffer (tocEntry) must be 18KB in size, and this will be filled with a maximum of 128 entries in one go -int CDVD_GetDir_RPC_get_entries(TocEntry tocEntry[], int req_entries){ +int IsoFS_getDirectories(TocEntry tocEntry[], int req_entries){ char toc[2048]; int toc_entry_num; dirTocEntry* tocEntryPointer; - if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ - RPC_LOG("[RPC:cdvd] Couldn't Read from CD !"); + if (IsoFS_readSectors(getDirTocData.current_sector,1,toc) != TRUE){ + ISOFS_LOG("[IsoFStools] Couldn't Read from CD !"); return -1; } //CdSync(0x00); @@ -730,18 +685,21 @@ int CDVD_GetDir_RPC_get_entries(TocEntry tocEntry[], int req_entries){ if (req_entries > 128) req_entries = 128; - for (toc_entry_num=0; toc_entry_num < req_entries;){ - if ((tocEntryPointer->length == 0) || (getDirTocData.current_sector_offset >= 2048)){ + for (toc_entry_num=0; toc_entry_num < req_entries;) + { + if ((tocEntryPointer->length == 0) || (getDirTocData.current_sector_offset >= 2048)) + { // decrease the number of dirs remaining getDirTocData.num_sectors--; - if (getDirTocData.num_sectors > 0){ + if (getDirTocData.num_sectors > 0) + { // If we've run out of entries, but arent on the last sector // then load another sector getDirTocData.current_sector++; - if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ - RPC_LOG("[RPC:cdvd] Couldn't Read from CD !"); + if (IsoFS_readSectors(getDirTocData.current_sector,1,toc) != TRUE){ + ISOFS_LOG("[IsoFStools] Couldn't Read from CD !"); return -1; } //CdSync(0x00); @@ -751,7 +709,8 @@ int CDVD_GetDir_RPC_get_entries(TocEntry tocEntry[], int req_entries){ // continue; } - else{ + else + { return (toc_entry_num); } } @@ -792,27 +751,6 @@ int CDVD_GetDir_RPC_get_entries(TocEntry tocEntry[], int req_entries){ tocEntryPointer = (dirTocEntry*)(toc + getDirTocData.current_sector_offset); } } -/* - if (strlen(getDirTocData.extension_list) > 0) - { - if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE) - { - - // increment this here, rather than in the main for loop - // since this should count the number of matching entries - toc_entry_num++; - } - - getDirTocData.current_sector_offset += tocEntryPointer->length; - (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; - } - else - { - toc_entry_num++; - getDirTocData.current_sector_offset += tocEntryPointer->length; - (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; - } -*/ } return (toc_entry_num); } diff --git a/pcsx2/CDVD/CDVDiso.h b/pcsx2/CDVD/IsoFStools.h similarity index 92% rename from pcsx2/CDVD/CDVDiso.h rename to pcsx2/CDVD/IsoFStools.h index 1a160f7b6e..6c146e4abc 100644 --- a/pcsx2/CDVD/CDVDiso.h +++ b/pcsx2/CDVD/IsoFStools.h @@ -20,14 +20,13 @@ * Modified by Florin for PCSX2 emu */ -#ifndef __CDVDISO_H__ -#define __CDVDISO_H__ +#ifndef __ISOFSTOOLS_H__ +#define __ISOFSTOOLS_H__ -#include "CDVDlib.h" +#include "IsoFScdvd.h" -int CDVD_findfile(const char* fname, TocEntry* tocEntry); -int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_dirs); -int CDVD_GetDir_RPC_get_entries(TocEntry tocEntry[], int req_entries); +int IsoFS_initDirectoryList(char* pathname, char* extensions, unsigned int inc_dirs); +int IsoFS_getDirectories(TocEntry tocEntry[], int req_entries); #if defined(_MSC_VER) #pragma pack(1) @@ -146,4 +145,4 @@ struct dirTocEntry #pragma pack() #endif -#endif//__CDVDISO_H__ +#endif//__ISOFSTOOLS_H__ diff --git a/pcsx2/CDVD/IsoFileFormats.cpp b/pcsx2/CDVD/IsoFileFormats.cpp new file mode 100644 index 0000000000..f7b3d3cb5a --- /dev/null +++ b/pcsx2/CDVD/IsoFileFormats.cpp @@ -0,0 +1,555 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "IopCommon.h" +#include "IsoFStools.h" +#include "IsoFSdrv.h" +#include "IsoFileFormats.h" + +#include +#include +#include + +#ifdef _WIN32 +#include + +void *_openfile(const char *filename, int flags) +{ + HANDLE handle; + wxString fn( wxString::FromAscii( filename ) ); + +// Console::WriteLn("_openfile %s, %d", params filename, flags & O_RDONLY); + if (flags & O_WRONLY) + { + int _flags = CREATE_NEW; + if (flags & O_CREAT) _flags = CREATE_ALWAYS; + handle = CreateFile(fn.c_str(), GENERIC_WRITE, 0, NULL, _flags, 0, NULL); + } + else + { + handle = CreateFile(fn.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + } + + return handle == INVALID_HANDLE_VALUE ? NULL : handle; +} + +u64 _tellfile(void *handle) +{ + u64 ofs; + PLONG _ofs = (LONG*) & ofs; + _ofs[1] = 0; + _ofs[0] = SetFilePointer(handle, 0, &_ofs[1], FILE_CURRENT); + return ofs; +} + +int _seekfile(void *handle, u64 offset, int whence) +{ + u64 ofs = (u64)offset; + PLONG _ofs = (LONG*) & ofs; +// Console::WriteLn("_seekfile %p, %d_%d", params handle, _ofs[1], _ofs[0]); + if (whence == SEEK_SET) + { + SetFilePointer(handle, _ofs[0], &_ofs[1], FILE_BEGIN); + } + else + { + SetFilePointer(handle, _ofs[0], &_ofs[1], FILE_END); + } + return 0; +} + +int _readfile(void *handle, void *dst, int size) +{ + DWORD ret; + +// Console::WriteLn("_readfile %p %d", params handle, size); + ReadFile(handle, dst, size, &ret, NULL); +// Console::WriteLn("_readfile ret %d; %d", params ret, GetLastError()); + return ret; +} + +int _writefile(void *handle, void *src, int size) +{ + DWORD ret; + +// Console::WriteLn("_writefile %p, %d", params handle, size); +// _seekfile(handle, _tellfile(handle)); + WriteFile(handle, src, size, &ret, NULL); +// Console::WriteLn("_writefile ret %d", params ret); + return ret; +} + +void _closefile(void *handle) +{ + CloseHandle(handle); +} + +#else + +void *_openfile(const char *filename, int flags) +{ +// Console::WriteLn("_openfile %s %x", params filename, flags); + + if (flags & O_WRONLY) + return fopen64(filename, "wb"); + else + return fopen64(filename, "rb"); +} + +u64 _tellfile(void *handle) +{ + s64 cursize = ftell(handle); + + if (cursize == -1) + { + // try 64bit + cursize = ftello64(handle); + if (cursize < -1) + { + // zero top 32 bits + cursize &= 0xffffffff; + } + } + return cursize; +} + +int _seekfile(void *handle, u64 offset, int whence) +{ + int seekerr = fseeko64(handle, offset, whence); + + if (seekerr == -1) Console::Error("Failed to seek."); + + return seekerr; +} + +int _readfile(void *handle, void *dst, int size) +{ + return fread(dst, 1, size, handle); +} + +int _writefile(void *handle, void *src, int size) +{ + return fwrite(src, 1, size, handle); +} + +void _closefile(void *handle) +{ + fclose(handle); +} + +#endif + +int detect(isoFile *iso) +{ + u8 buf[2448]; + struct cdVolDesc *volDesc; + + if (isoReadBlock(iso, buf + iso->blockofs, 16) == -1) return -1; + + volDesc = (struct cdVolDesc *)(buf + 24); + + if (strncmp((char*)volDesc->volID, "CD001", 5)) return 0; + + if (volDesc->rootToc.tocSize == 2048) + iso->type = ISOTYPE_CD; + else + iso->type = ISOTYPE_DVD; + + return 1; +} + +int _isoReadDtable(isoFile *iso) +{ + int ret; + + _seekfile(iso->handle, 0, SEEK_END); + iso->dtablesize = (_tellfile(iso->handle) - 16) / (iso->blocksize + 4); + iso->dtable = (u32*)malloc(iso->dtablesize * 4); + + for (int i = 0; i < iso->dtablesize; i++) + { + _seekfile(iso->handle, 16 + (iso->blocksize + 4) * i, SEEK_SET); + ret = _readfile(iso->handle, &iso->dtable[i], 4); + if (ret < 4) return -1; + } + + return 0; +} + +bool tryIsoType(isoFile *iso, u32 size, u32 offset, u32 blockofs) +{ + iso->blocksize = size; + iso->offset = offset; + iso->blockofs = blockofs; + if (detect(iso) == 1) return true; + + return false; +} + +int isoDetect(isoFile *iso) // based on florin's CDVDbin detection code :) +{ + char buf[32]; + int len; + + iso->type = ISOTYPE_ILLEGAL; + + len = strlen(iso->filename); + + _seekfile(iso->handle, 0, SEEK_SET); + _readfile(iso->handle, buf, 4); + + if (strncmp(buf, "BDV2", 4) == 0) + { + iso->flags = ISOFLAGS_BLOCKDUMP; + _readfile(iso->handle, &iso->blocksize, 4); + _readfile(iso->handle, &iso->blocks, 4); + _readfile(iso->handle, &iso->blockofs, 4); + _isoReadDtable(iso); + return (detect(iso) == 1) ? 0 : -1; + } + else + { + iso->blocks = 16; + } + + if (tryIsoType(iso, 2048, 0, 24)) return 0; // ISO 2048 + if (tryIsoType(iso, 2336, 0, 16)) return 0; // RAW 2336 + if (tryIsoType(iso, 2352, 0, 0)) return 0; // RAW 2352 + if (tryIsoType(iso, 2448, 0, 0)) return 0; // RAWQ 2448 + if (tryIsoType(iso, 2048, 150 * 2048, 24)) return 0; // NERO ISO 2048 + if (tryIsoType(iso, 2352, 150 * 2048, 0)) return 0; // NERO RAW 2352 + if (tryIsoType(iso, 2448, 150 * 2048, 0)) return 0; // NERO RAWQ 2448 + if (tryIsoType(iso, 2048, -8, 24)) return 0; // ISO 2048 + if (tryIsoType(iso, 2352, -8, 0)) return 0; // RAW 2352 + if (tryIsoType(iso, 2448, -8, 0)) return 0; // RAWQ 2448 + + iso->offset = 0; + iso->blocksize = 2352; + iso->blockofs = 0; + iso->type = ISOTYPE_AUDIO; + return 0; +} + +isoFile *isoOpen(const char *filename) +{ + isoFile *iso; + + iso = (isoFile*)malloc(sizeof(isoFile)); + if (iso == NULL) return NULL; + + memset(iso, 0, sizeof(isoFile)); + strcpy(iso->filename, filename); + + iso->handle = _openfile(iso->filename, O_RDONLY); + if (iso->handle == NULL) + { + Console::Error("error loading %s", params iso->filename); + return NULL; + } + + if (isoDetect(iso) == -1) return NULL; + + Console::WriteLn("detected blocksize = %d", params iso->blocksize); + + if ((strlen(iso->filename) > 3) && strncmp(iso->filename + (strlen(iso->filename) - 3), "I00", 3) == 0) + { + int i; + + _closefile(iso->handle); + iso->flags |= ISOFLAGS_MULTI; + iso->blocks = 0; + + for (i = 0; i < 8; i++) + { + iso->filename[strlen(iso->filename) - 1] = '0' + i; + iso->multih[i].handle = _openfile(iso->filename, O_RDONLY); + + if (iso->multih[i].handle == NULL) + { + break; + } + + iso->multih[i].slsn = iso->blocks; + _seekfile(iso->multih[i].handle, 0, SEEK_END); + iso->blocks += (u32)((_tellfile(iso->multih[i].handle) - iso->offset) / (iso->blocksize)); + iso->multih[i].elsn = iso->blocks - 1; + } + + if (i == 0) + { + return NULL; + } + } + + if (iso->flags == 0) + { + _seekfile(iso->handle, 0, SEEK_END); + iso->blocks = (u32)((_tellfile(iso->handle) - iso->offset) / (iso->blocksize)); + } + + Console::WriteLn("isoOpen: %s ok", params iso->filename); + Console::WriteLn("offset = %d", params iso->offset); + Console::WriteLn("blockofs = %d", params iso->blockofs); + Console::WriteLn("blocksize = %d", params iso->blocksize); + Console::WriteLn("blocks = %d", params iso->blocks); + Console::WriteLn("type = %d", params iso->type); + + return iso; +} + +isoFile *isoCreate(const char *filename, int flags) +{ + isoFile *iso; + char Zfile[256]; + + iso = (isoFile*)malloc(sizeof(isoFile)); + if (iso == NULL) return NULL; + + memset(iso, 0, sizeof(isoFile)); + strcpy(iso->filename, filename); + + iso->flags = flags; + iso->offset = 0; + iso->blockofs = 24; + iso->blocksize = 2048; + + if (iso->flags & (ISOFLAGS_Z | ISOFLAGS_Z2 | ISOFLAGS_BZ2)) + { + sprintf(Zfile, "%s.table", iso->filename); + iso->htable = _openfile(Zfile, O_WRONLY); + + if (iso->htable == NULL) + { + return NULL; + } + } + + iso->handle = _openfile(iso->filename, O_WRONLY | O_CREAT); + + if (iso->handle == NULL) + { + Console::Error("Error loading %s", params iso->filename); + return NULL; + } + + Console::WriteLn("isoCreate: %s ok", params iso->filename); + Console::WriteLn("offset = %d", params iso->offset); + + return iso; +} + +int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks) +{ + iso->blocksize = blocksize; + iso->blocks = blocks; + iso->blockofs = blockofs; + + Console::WriteLn("blockofs = %d", params iso->blockofs); + Console::WriteLn("blocksize = %d", params iso->blocksize); + Console::WriteLn("blocks = %d", params iso->blocks); + + if (iso->flags & ISOFLAGS_BLOCKDUMP) + { + if (_writefile(iso->handle, "BDV2", 4) < 4) return -1; + if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; + if (_writefile(iso->handle, &blocks, 4) < 4) return -1; + if (_writefile(iso->handle, &blockofs, 4) < 4) return -1; + } + + return 0; +} + +s32 MSFtoLSN(u8 *Time) +{ + u32 lsn; + + lsn = Time[2]; + lsn += (Time[1] - 2) * 75; + lsn += Time[0] * 75 * 60; + return lsn; +} + +void LSNtoMSF(u8 *Time, s32 lsn) +{ + u8 m, s, f; + + lsn += 150; + m = lsn / 4500; // minuten + lsn = lsn - m * 4500; // minuten rest + s = lsn / 75; // sekunden + f = lsn - (s * 75); // sekunden rest + Time[0] = itob(m); + Time[1] = itob(s); + Time[2] = itob(f); +} + +int _isoReadBlock(isoFile *iso, u8 *dst, int lsn) +{ + u64 ofs = (u64)lsn * iso->blocksize + iso->offset; + int ret; + + memset(dst, 0, iso->blockofs); + _seekfile(iso->handle, ofs, SEEK_SET); + + ret = _readfile(iso->handle, dst, iso->blocksize); + + if (ret < iso->blocksize) + { + Console::Error("read error %d in _isoReadBlock", params ret); + return -1; + } + + return 0; +} + +int _isoReadBlockD(isoFile *iso, u8 *dst, int lsn) +{ + int ret; + +// Console::WriteLn("_isoReadBlockD %d, blocksize=%d, blockofs=%d\n", params lsn, iso->blocksize, iso->blockofs); + + memset(dst, 0, iso->blockofs); + for (int i = 0; i < iso->dtablesize;i++) + { + if (iso->dtable[i] != lsn) continue; + + _seekfile(iso->handle, 16 + i * (iso->blocksize + 4) + 4, SEEK_SET); + ret = _readfile(iso->handle, dst, iso->blocksize); + + if (ret < iso->blocksize) return -1; + + return 0; + } + Console::WriteLn("Block %d not found in dump", params lsn); + + return -1; +} + +int _isoReadBlockM(isoFile *iso, u8 *dst, int lsn) +{ + u64 ofs; + int ret, i; + + for (i = 0; i < 8; i++) + { + if ((lsn >= iso->multih[i].slsn) && (lsn <= iso->multih[i].elsn)) + { + break; + } + } + + if (i == 8) return -1; + + ofs = (u64)(lsn - iso->multih[i].slsn) * iso->blocksize + iso->offset; + +// Console::WriteLn("_isoReadBlock %d, blocksize=%d, blockofs=%d\n", params lsn, iso->blocksize, iso->blockofs); + + memset(dst, 0, iso->blockofs); + _seekfile(iso->multih[i].handle, ofs, SEEK_SET); + ret = _readfile(iso->multih[i].handle, dst, iso->blocksize); + + if (ret < iso->blocksize) + { + Console::WriteLn("read error %d in _isoReadBlockM", params ret); + return -1; + } + + return 0; +} + +int isoReadBlock(isoFile *iso, u8 *dst, int lsn) +{ + int ret; + + if (lsn > iso->blocks) + { + Console::WriteLn("isoReadBlock: %d > %d", params lsn, iso->blocks); + return -1; + } + + if (iso->flags & ISOFLAGS_BLOCKDUMP) + ret = _isoReadBlockD(iso, dst, lsn); + else if (iso->flags & ISOFLAGS_MULTI) + ret = _isoReadBlockM(iso, dst, lsn); + else + ret = _isoReadBlock(iso, dst, lsn); + + if (ret == -1) return ret; + + if (iso->type == ISOTYPE_CD) + { + LSNtoMSF(dst + 12, lsn); + dst[15] = 2; + } + + return 0; +} + + +int _isoWriteBlock(isoFile *iso, u8 *src, int lsn) +{ + int ret; + u64 ofs = (u64)lsn * iso->blocksize + iso->offset; + + _seekfile(iso->handle, ofs, SEEK_SET); + ret = _writefile(iso->handle, src, iso->blocksize); + if (ret < iso->blocksize) return -1; + + return 0; +} + +int _isoWriteBlockD(isoFile *iso, u8 *src, int lsn) +{ + int ret; + +// Console::WriteLn("_isoWriteBlock %d (ofs=%d)", params iso->blocksize, ofs); + + ret = _writefile(iso->handle, &lsn, 4); + if (ret < 4) return -1; + ret = _writefile(iso->handle, src, iso->blocksize); + +// Console::WriteLn("_isoWriteBlock %d", params ret); + + if (ret < iso->blocksize) return -1; + + return 0; +} + +int isoWriteBlock(isoFile *iso, u8 *src, int lsn) +{ + int ret; + + if (iso->flags & ISOFLAGS_BLOCKDUMP) + ret = _isoWriteBlockD(iso, src, lsn); + else + ret = _isoWriteBlock(iso, src, lsn); + + if (ret == -1) return ret; + return 0; +} + +void isoClose(isoFile *iso) +{ + if (iso->handle) _closefile(iso->handle); + if (iso->htable) _closefile(iso->htable); + if (iso->buffer) free(iso->buffer); + + free(iso); +} + diff --git a/pcsx2/CDVD/IsoFileFormats.h b/pcsx2/CDVD/IsoFileFormats.h new file mode 100644 index 0000000000..c7f33ca4ce --- /dev/null +++ b/pcsx2/CDVD/IsoFileFormats.h @@ -0,0 +1,109 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + #ifndef __LIBISO_H__ +#define __LIBISO_H__ + +#ifndef __USE_LARGEFILE64 +#define __USE_LARGEFILE64 +#endif + +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE_SOURCE +#endif + +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif + +#define __USE_FILE_OFFSET64 +#define _FILE_OFFSET_BITS 64 + +#ifdef _MSC_VER +#pragma warning(disable:4018) +#endif + +#include "CDVD.h" + +enum isoType +{ + ISOTYPE_ILLEGAL = 0, + ISOTYPE_CD, + ISOTYPE_DVD, + ISOTYPE_AUDIO, + ISOTYPE_DVDDL +}; + +enum isoFlags +{ + ISOFLAGS_Z = 0x0001, + ISOFLAGS_Z2 = 0x0002, + ISOFLAGS_BLOCKDUMP = 0x0004, + ISOFLAGS_MULTI = 0x0008, + ISOFLAGS_BZ2 = 0x0010 +}; + +#define CD_FRAMESIZE_RAW 2352 +#define DATA_SIZE (CD_FRAMESIZE_RAW-12) + +//#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ +//#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ + +typedef struct +{ + u32 slsn; + u32 elsn; + void *handle; +} _multih; + +typedef struct +{ + char filename[256]; + u32 type; + u32 flags; + u32 offset; + u32 blockofs; + u32 blocksize; + u32 blocks; + void *handle; + void *htable; + char *Ztable; + u32 *dtable; + int dtablesize; + _multih multih[8]; + int buflsn; + u8 *buffer; +} isoFile; + + +isoFile *isoOpen(const char *filename); +isoFile *isoCreate(const char *filename, int mode); +int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks); +int isoDetect(isoFile *iso); +int isoReadBlock(isoFile *iso, u8 *dst, int lsn); +int isoWriteBlock(isoFile *iso, u8 *src, int lsn); +void isoClose(isoFile *iso); + +void *_openfile(const char *filename, int flags); +u64 _tellfile(void *handle); +int _seekfile(void *handle, u64 offset, int whence); +int _readfile(void *handle, void *dst, int size); +int _writefile(void *handle, void *src, int size); +void _closefile(void *handle); + +#endif /* __LIBISO_H__ */ diff --git a/pcsx2/CDVD/Makefile.am b/pcsx2/CDVD/Makefile.am deleted file mode 100644 index be2de4296b..0000000000 --- a/pcsx2/CDVD/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -pcsx2_dir = $(top_srcdir)/.. -common_dir = $(pcsx2_dir)/common/include -third_dir = $(pcsx2_dir)/3rdparty -cdvd_dir = $(top_srcdir)/CDVD -x86_dir = $(top_srcdir)/x86 -rdebug_dir = $(top_srcdir)/RDebug -debugtools_dir = $(top_srcdir)/DebugTools -ipu_dir = $(top_srcdir)/IPU -linux_dir = $(top_srcdir)/Linux - -INCLUDES = -I$(top_srcdir) -I$(x86_dir) -I$(common_dir) -I$(third_dir) -noinst_LIBRARIES = libps2_cdvd.a - -libps2_cdvd_a_SOURCES = \ -CDVD.cpp CDVDiso.cpp CDVDisodrv.cpp CdRom.cpp \ -CDVD.h CDVD_internal.h CDVDiso.h CDVDisodrv.h CDVDlib.h CdRom.h - -#SUBDIRS = \ No newline at end of file diff --git a/pcsx2/DebugTools/Debug.h b/pcsx2/DebugTools/Debug.h index 89e54e6593..f864e7616d 100644 --- a/pcsx2/DebugTools/Debug.h +++ b/pcsx2/DebugTools/Debug.h @@ -83,6 +83,7 @@ struct LogSources DMA:1, Bios:1, ELF:1, + IsoFS:1, // Iso Filesystem support VU0:1, COP0:1, // TLB logs, PERF logs, Debug register logs VIF:1, @@ -140,6 +141,7 @@ extern bool SrcLog_PSXCNT( const char* fmt, ... ); extern bool SrcLog_MEMCARDS( const char* fmt, ... ); extern bool SrcLog_PAD( const char* fmt, ... ); extern bool SrcLog_CDR( const char* fmt, ... ); +extern bool SrcLog_CDVD( const char* fmt, ... ); extern bool SrcLog_GPU( const char* fmt, ... ); #define CPU_LOG (varLog.R5900) && SrcLog_CPU @@ -158,6 +160,7 @@ extern bool SrcLog_GPU( const char* fmt, ... ); #define VUM_LOG (varLog.VUMacro) && SrcLog_VUM #define RPC_LOG (varLog.RPC) && SrcLog_RPC #define EECNT_LOG (varLog.Counters) && SrcLog_EECNT +#define ISOFS_LOG (varLog.IsoFS) && SrcLog_RPC #define PSXCPU_LOG (varLog.R3000A) && SrcLog_PSXCPU #define PSXMEM_LOG (varLog.IopMemory) && SrcLog_PSXMEM @@ -171,6 +174,7 @@ extern bool SrcLog_GPU( const char* fmt, ... ); #define PAD_LOG (varLog.Pad) && SrcLog_PAD #define CDR_LOG (varLog.CDVD) && SrcLog_CDR #define GPU_LOG (varLog.GPU) && SrcLog_GPU +#define CDVD_LOG SrcLog_CDVD // fixme - currently we don't log cache #define CACHE_LOG 0&& @@ -195,7 +199,7 @@ extern bool SrcLog_GPU( const char* fmt, ... ); #define SIF_LOG 0&& #define IPU_LOG 0&& #define VUM_LOG 0&& -#define RPC_LOG 0&& +#define ISOFS_LOG 0&& #define PSXCPU_LOG 0&& #define PSXMEM_LOG 0&& @@ -205,6 +209,7 @@ extern bool SrcLog_GPU( const char* fmt, ... ); #define PAD_LOG 0&& #define CDR_LOG 0&& +#define CDVD_LOG 0&& #define GPU_LOG 0&& #define PSXCNT_LOG 0&& #define EECNT_LOG 0&& diff --git a/pcsx2/Elfheader.cpp b/pcsx2/Elfheader.cpp index 8be8701552..afa05d0184 100644 --- a/pcsx2/Elfheader.cpp +++ b/pcsx2/Elfheader.cpp @@ -19,7 +19,7 @@ #include "PrecompiledHeader.h" #include "Common.h" -#include "CDVD/CDVDisodrv.h" +#include "CDVD/IsoFSdrv.h" using namespace std; @@ -307,13 +307,13 @@ struct ElfObject if ((strnicmp( work.data(), "cdrom0:", strlen("cdromN:")) == 0) || (strnicmp( work.data(), "cdrom1:", strlen("cdromN:")) == 0)) { - int fi = CDVDFS_open(work.data() + strlen("cdromN:"), 1);//RDONLY - + int fi = IsoFS_open(work.data() + strlen("cdromN:"), 1);//RDONLY + if (fi < 0) throw Exception::FileNotFound( filename ); - CDVDFS_lseek( fi, 0, SEEK_SET ); - rsize = CDVDFS_read( fi, (char*)data.GetPtr(), data.GetSizeInBytes() ); - CDVDFS_close( fi ); + IsoFS_lseek( fi, 0, SEEK_SET ); + rsize = IsoFS_read( fi, (char*)data.GetPtr(), data.GetSizeInBytes() ); + IsoFS_close( fi ); } else { @@ -494,8 +494,8 @@ u32 loadElfCRC( const char* filename ) { TocEntry toc; - CDVDFS_init( ); - if ( CDVD_findfile( filename + strlen( "cdromN:" ), &toc ) == -1 ) + IsoFS_init( ); + if ( IsoFS_findFile( filename + strlen( "cdromN:" ), &toc ) == -1 ) return 0; DevCon::Status( "loadElfFile: %d bytes", params toc.fileSize ); @@ -537,8 +537,8 @@ int loadElfFile(const wxString& filename) { // Loading from a CD rom or CD image. TocEntry toc; - CDVDFS_init( ); - if ( CDVD_findfile( fnptr + strlen( "cdromN:" ), &toc ) == -1 ) + IsoFS_init( ); + if ( IsoFS_findFile( fnptr + strlen( "cdromN:" ), &toc ) == -1 ) return -1; elfsize = toc.fileSize; } diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index c711e9b415..a91f1f6ad0 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -175,6 +175,7 @@ void gsInit() // Opens the gsRingbuffer thread. s32 gsOpen() { + u32 curFrameLimit = Config.Options & PCSX2_FRAMELIMIT_MASK; if( m_gsOpened ) return 0; //video @@ -200,6 +201,16 @@ s32 gsOpen() UpdateVSyncRate() ); }*/ + + if(GSsetFrameLimit == NULL) + { + DevCon::Notice("Notice: GS Plugin does not implement GSsetFrameLimit."); + } + else + { + GSsetFrameLimit(curFrameLimit != PCSX2_FRAMELIMIT_NORMAL); + } + return !m_gsOpened; } diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index 8151099b1d..c0c093574b 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -85,17 +85,17 @@ enum HWaddress RCNT3_TARGET = 0x10001820, IPU_CMD = 0x10002000, - IPU_CTRL = 0x10002010, + IPU_CTRL = 0x10002010, IPU_BP = 0x10002020, IPU_TOP = 0x10002030, - GIF_CTRL = 0x10003000, + GIF_CTRL = 0x10003000, GIF_MODE = 0x10003010, - GIF_STAT = 0x10003020, - GIF_TAG0 = 0x10003040, - GIF_TAG1 = 0x10003050, - GIF_TAG2 = 0x10003060, - GIF_TAG3 = 0x10003070, + GIF_STAT = 0x10003020, + GIF_TAG0 = 0x10003040, + GIF_TAG1 = 0x10003050, + GIF_TAG2 = 0x10003060, + GIF_TAG3 = 0x10003070, GIF_CNT = 0x10003080, GIF_P3CNT = 0x10003090, GIF_P3TAG = 0x100030A0, @@ -103,16 +103,16 @@ enum HWaddress // Vif Memory Locations VIF0_STAT = 0x10003800, VIF0_FBRST = 0x10003810, - VIF0_ERR = 0x10003820, + VIF0_ERR = 0x10003820, VIF0_MARK = 0x10003830, VIF0_CYCLE = 0x10003840, VIF0_MODE = 0x10003850, - VIF0_NUM = 0x10003860, + VIF0_NUM = 0x10003860, VIF0_MASK = 0x10003870, VIF0_CODE = 0x10003880, VIF0_ITOPS = 0x10003890, VIF0_ITOP = 0x100038d0, - VIF0_TOP = 0x100038e0, + VIF0_TOP = 0x100038e0, VIF0_R0 = 0x10003900, VIF0_R1 = 0x10003910, VIF0_R2 = 0x10003920, @@ -124,11 +124,11 @@ enum HWaddress VIF1_STAT = 0x10003c00, VIF1_FBRST = 0x10003c10, - VIF1_ERR = 0x10003c20, + VIF1_ERR = 0x10003c20, VIF1_MARK = 0x10003c30, VIF1_CYCLE = 0x10003c40, VIF1_MODE = 0x10003c50, - VIF1_NUM = 0x10003c60, + VIF1_NUM = 0x10003c60, VIF1_MASK = 0x10003c70, VIF1_CODE = 0x10003c80, VIF1_ITOPS = 0x10003c90, @@ -136,7 +136,7 @@ enum HWaddress VIF1_OFST = 0x10003cb0, VIF1_TOPS = 0x10003cc0, VIF1_ITOP = 0x10003cd0, - VIF1_TOP = 0x10003ce0, + VIF1_TOP = 0x10003ce0, VIF1_R0 = 0x10003d00, VIF1_R1 = 0x10003d10, VIF1_R2 = 0x10003d20, @@ -148,7 +148,7 @@ enum HWaddress VIF0_FIFO = 0x10004000, VIF1_FIFO = 0x10005000, - GIF_FIFO = 0x10006000, + GIF_FIFO = 0x10006000, IPUout_FIFO = 0x10007000, IPUin_FIFO = 0x10007010, @@ -242,7 +242,7 @@ enum HWaddress SBUS_F260 = 0x1000F260, MCH_RICM = 0x1000F430, - MCH_DRD = 0x1000F440, + MCH_DRD = 0x1000F440, DMAC_ENABLER = 0x1000F520, DMAC_ENABLEW = 0x1000F590, diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.cpp b/pcsx2/IPU/mpeg2lib/Mpeg.cpp index 9832375ba9..6b5fcefd6e 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.cpp +++ b/pcsx2/IPU/mpeg2lib/Mpeg.cpp @@ -1131,6 +1131,7 @@ void __forceinline finishmpeg2sliceIDEC(decoder_t* &decoder) } // This fixes Mana Khemia if uncommented, but needs testing. +// Breaks Figital Devil Saga. //#define ALWAYS_RESUME_BEFORE_EXITING void mpeg2sliceIDEC(void* pdone) { @@ -1231,6 +1232,7 @@ void mpeg2sliceIDEC(void* pdone) { g_pIPU0Pointer += read * 16; g_nIPU0Data -= read; + } } @@ -1239,7 +1241,7 @@ void mpeg2sliceIDEC(void* pdone) NEEDBITS(decoder->bitstream_buf, decoder->bitstream_bits, decoder->bitstream_ptr); mba_inc = 0; - + while (1) { if (decoder->bitstream_buf >= 0x10000000) @@ -1269,7 +1271,7 @@ void mpeg2sliceIDEC(void* pdone) #ifdef ALWAYS_RESUME_BEFORE_EXITING if (!resumed) so_resume(); #endif - + finishmpeg2sliceIDEC(decoder); *(int*)pdone = 1; diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.h b/pcsx2/IPU/mpeg2lib/Mpeg.h index 43d2ddef0d..e31e2b6769 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.h +++ b/pcsx2/IPU/mpeg2lib/Mpeg.h @@ -25,32 +25,43 @@ #ifndef __MPEG_H__ #define __MPEG_H__ -/* macroblock modes */ -#define MACROBLOCK_INTRA 1 -#define MACROBLOCK_PATTERN 2 -#define MACROBLOCK_MOTION_BACKWARD 4 -#define MACROBLOCK_MOTION_FORWARD 8 -#define MACROBLOCK_QUANT 16 -#define DCT_TYPE_INTERLACED 32 -/* motion_type */ -#define MOTION_TYPE_SHIFT 6 -#define MOTION_TYPE_MASK (3*64) -#define MOTION_TYPE_BASE 64 -#define MC_FIELD (1*64) -#define MC_FRAME (2*64) -#define MC_16X8 (2*64) -#define MC_DMV (3*64) +enum macroblock_modes +{ + MACROBLOCK_INTRA = 1, + MACROBLOCK_PATTERN = 2, + MACROBLOCK_MOTION_BACKWARD = 4, + MACROBLOCK_MOTION_FORWARD = 8, + MACROBLOCK_QUANT = 16, + DCT_TYPE_INTERLACED = 32 +}; + +enum motion_type +{ + MOTION_TYPE_SHIFT = 6, + MOTION_TYPE_MASK = (3*64), + MOTION_TYPE_BASE = 64, + MC_FIELD = (1*64), + MC_FRAME = (2*64), + MC_16X8 = (2*64), + MC_DMV = (3*64) +}; /* picture structure */ -#define TOP_FIELD 1 -#define BOTTOM_FIELD 2 -#define FRAME_PICTURE 3 - +enum picture_structure +{ + TOP_FIELD = 1, + BOTTOM_FIELD = 2, + FRAME_PICTURE = 3 +}; + /* picture coding type */ -#define I_TYPE 1 -#define P_TYPE 2 -#define B_TYPE 3 -#define D_TYPE 4 +enum picture_coding_type +{ + I_TYPE =1, + P_TYPE = 2, + B_TYPE = 3, + D_TYPE = 4 +}; struct macroblock_8{ unsigned char Y[16][16]; //0 diff --git a/pcsx2/Linux/pcsx2.glade b/pcsx2/Linux/pcsx2.glade deleted file mode 100644 index 841d42da45..0000000000 --- a/pcsx2/Linux/pcsx2.glade +++ /dev/null @@ -1,8679 +0,0 @@ - - - - - - - True - Advanced Options - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - True - - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_SPREAD - - - - True - True - True - Defaults - True - GTK_RELIEF_NORMAL - True - 0 - - - - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - -6 - - - - - - 0 - False - True - GTK_PACK_END - - - - - - True - False - 0 - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - Nearest - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Negative - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_EE_Round_Near - - - 0 - False - False - - - - - - True - True - Positive - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_EE_Round_Near - - - 0 - False - False - - - - - - True - True - Chop/Zero - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_EE_Round_Near - - - 0 - False - False - - - - - - - - - - True - <b>Round Mode</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - None - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Normal - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_EE_Clamp_None - - - 0 - False - False - - - - - - True - True - Extra + Preserve Sign - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_EE_Clamp_None - - - 0 - False - False - - - - - - True - True - Full - True - GTK_RELIEF_NORMAL - True - True - False - True - radio_EE_Clamp_None - - - 0 - True - True - - - - - - - - - - True - <b>Clamp Mode</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - True - Flush to Zero - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Denormals are Zero - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - 0 - True - True - - - - - - - - - - True - <b>EE Recs Options</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - Nearest - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Negative - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_VU_Round_Near - - - 0 - False - False - - - - - - True - True - Positive - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_VU_Round_Near - - - 0 - False - False - - - - - - True - True - Zero - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_VU_Round_Near - - - 0 - False - False - - - - - - - - - - True - <b>Round Mode</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - None - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Normal - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_VU_Clamp_None - - - 0 - False - False - - - - - - True - True - Extra - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_VU_Clamp_None - - - 0 - False - False - - - - - - True - True - Extra + Preserve Sign - True - GTK_RELIEF_NORMAL - True - False - False - True - radio_VU_Clamp_None - - - 0 - False - False - - - - - - - - - - True - <b>Clamp Mode</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 2 - 2 - False - 0 - 0 - - - - True - False - True - Software Emulate DaZ - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 1 - 2 - 1 - 2 - - - - - - - - True - False - True - Set O & U Flags - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 1 - 2 - - - - - - - - True - True - Denormals are Zero - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 1 - 2 - 0 - 1 - - - - - - - - True - True - Flush to Zero - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 0 - 1 - - - - - - - 0 - True - True - - - - - - - - - - True - <b>VU Recs Options</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - These options specify how your CPU rounds floating point values. - -Try changing the roundmode for EE if your game hangs, it could make it work again. - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - - - - True - <b>Round Mode</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - False - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - These options specify how PCSX2's recompilers will clamp Infinities and NaN (Not a Number) values in the opcode instructions. - -None - No clamping. (Fastest Mode) -Normal - Clamps the result. -Extra - Clamps the operands, the result, and anywhere in between. -Extra + Preserve Sign - Same as ""Extra"", except preserves NaN's sign when clamping the operands. (Slowest Mode) - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - - - - True - <b>Clamp Mode</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - False - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - Flush to Zero - Your CPU makes Floating Point Underflows become Zero, so it does less work. (Speed Up) - -Denormals are Zero - Your CPU makes Floating Point Denormals become Zero, so it does less work. (Speed Up) - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - - - - - - True - <b>Other Options</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - False - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - - - True - PCSX2 Speed Hacks - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - True - - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - -6 - - - - - - 0 - False - True - GTK_PACK_END - - - - - - True - False - 0 - - - - True - These hacks will affect the speed of PCSX2 but possibly compromise compatibility. -If you have problems, Disable all of these and try again. - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - False - 0 - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 2 - - - - True - True - False - GTK_POS_TOP - 0 - GTK_UPDATE_CONTINUOUS - False - 0 0 2 1 0 0 - - - - 0 - False - False - - - - - - True - Most compatible option - recommended for everyone with high-end machines. - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - - - 0 - False - False - - - - - - True - Important: the X2 sync hack *will* cause choppy/skippy audio on many FMV movies. - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - - True - EmotionEngine (EE) Sync Hacks - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - False - GTK_POS_TOP - 0 - GTK_UPDATE_CONTINUOUS - False - 0 0 4 1 0 0 - - - - 0 - True - True - - - - - - True - 2: Moderate speedup, should work with most games with minor problems. - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - - True - VU Cycle Stealing (Speedup for 3d geometry) - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - Small speedup, and works well with most games. - True - Enable IOP x2 Cycle Rate - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - Small speedup. Works well with most games, but it may cause certain games to crash, or freeze up during bootup or stage changes. - True - WaitCycles Sync Hack - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks). - True - INTC Sync Hack - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - Speedup for a few games, including FFX with no known side effects. - True - Idle Loop Fast-Forward (experimental) - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - - - - - True - Misc Hacks - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - False - - - - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - Big Speedup and high compatiblity. SuperVU does something similar by default. - True - Status Flag Hack (microVU only) - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - Small Speedup. May cause SPS, hanging, graphical corruption, and missing geometry. - True - Min / Max Hack (microVU only) - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - - - - - True - Vertex Unit (VU) Hacks - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - False - - - - - 0 - False - False - - - - - 0 - True - True - - - - - 0 - False - False - - - - - - - - True - Game Special Fixes - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - True - - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - -6 - - - - - - 0 - False - True - GTK_PACK_END - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - FPU Compare Hack - Special fix for Digimon Rumble Arena 2. - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - VU Add / Sub Hack - Special fix for Tri-Ace games! - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - FPU Mul Hack - Special fix for Tales of Destiny (possibly other games). - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - True - - - - - - True - True - VU Clip Hack - Fixes missing ground geometry in Persona. - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - DMAExec Hack - Fixes Fatal Frame, possibly others. -Causes freezing in Gust games and crashing in some TriAce games - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - VU XGkick Hack - Fix for Erementar Gerad. -Adds more delay to VU XGkick instructions. Corrects the color of some graphics. - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - - - - - True - <b>Some games need special settings. -Configure them here.</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - - - 5 - True - memWrite32 - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - 5 - True - False - 5 - - - - 5 - True - False - 2 - - - - True - Address - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - 0x - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - Data - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - 0x - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 30 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - True - True - - - - - - - - 5 - True - Program arguments - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - True - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - 5 - True - False - 5 - - - - True - Fill in the command line arguments for the opened program: - False - False - GTK_JUSTIFY_CENTER - False - False - 0.10000000149 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - If you don't know what to write leave it blank - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - False - False - - - - - - True - Note: this is intended for developers only. - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 30 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - True - True - - - - - - - - 5 - True - Raw Dump - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - 5 - True - False - 5 - - - - True - Set Dump Addr (in Hex): - False - False - GTK_JUSTIFY_CENTER - False - False - 0.10000000149 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - From 0x - False - False - GTK_JUSTIFY_CENTER - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - To 0x - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - Dump File = "dump.txt" - False - False - GTK_JUSTIFY_LEFT - False - False - 0.10000000149 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 30 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - True - True - - - - - - - - 5 - True - Dump code - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - 5 - True - False - 5 - - - - True - Set Dump Addr (in Hex): - False - False - GTK_JUSTIFY_LEFT - False - False - 0.10000000149 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - From 0x - False - False - GTK_JUSTIFY_CENTER - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - To 0x - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - Dump File = "dump.txt" - False - False - GTK_JUSTIFY_LEFT - False - False - 0.10000000149 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 30 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - True - True - - - - - - - - 5 - True - SetBreakPoint Addr - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - 5 - True - False - 5 - - - - True - Set New BP Count (in Hex): - False - False - GTK_JUSTIFY_CENTER - False - False - 0.10000000149 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - 0x - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - False - False - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 30 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - True - True - - - - - - - - 5 - True - SetBreakPoint Addr - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - 5 - True - False - 5 - - - - True - Set New BP Address (in Hex): - False - False - GTK_JUSTIFY_CENTER - False - False - 0.10000000149 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - 0x - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - False - False - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 30 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - True - True - - - - - - - - 5 - True - SetPCDlg - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - 5 - True - False - 5 - - - - True - Set New PC Address (in Hex): - False - False - GTK_JUSTIFY_CENTER - False - False - 0.10000000149 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - 5 - True - False - 2 - - - - True - 0x - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - • - False - - - 0 - True - True - - - - - 0 - False - False - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 30 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - True - True - - - - - - - - 5 - True - PCSX2 Debugger - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - 5 - True - False - 0 - - - - True - False - 5 - - - - True - True - EE Debug Mode - True - GTK_RELIEF_NORMAL - True - False - False - True - - - - 0 - False - False - - - - - - True - True - IOP Debug Mode - True - GTK_RELIEF_NORMAL - True - False - False - True - GtkRadioButton_EE - - - - 0 - False - False - - - - - 0 - False - True - - - - - - 5 - True - False - 0 - - - - True - False - 0 - - - - True - GTK_POLICY_ALWAYS - GTK_POLICY_NEVER - GTK_SHADOW_NONE - GTK_CORNER_TOP_LEFT - - - - True - GTK_SHADOW_IN - - - - True - False - False - False - True - False - False - False - - - - - - - 0 - True - True - - - - - - True - GTK_UPDATE_CONTINUOUS - False - 0 0 412 1 20 2 - - - 0 - False - True - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Step - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Skip - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Go - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Log On/Off - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - False - True - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Set PC - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Set BP Addr - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Set BP Count - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Clear BPs - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - False - True - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Dump code - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Raw Dump - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Close - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - False - True - - - - - 0 - False - True - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 10 - - - - True - True - True - memWrite32 - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - False - True - - - - - 0 - True - True - - - - - - - - 10 - True - Conf - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - False - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - True - False - 0 - - - - 2 - True - 14 - 2 - False - 0 - 15 - - - - True - - False - True - - - 1 - 2 - 13 - 14 - - - - - - True - - False - True - - - 0 - 1 - 1 - 2 - - - - - - True - - False - True - - - 1 - 2 - 1 - 2 - - - - - - True - - False - True - - - 0 - 1 - 4 - 5 - - - - - - True - - False - True - - - 1 - 2 - 4 - 5 - - - - - - True - - False - True - - - 0 - 1 - 7 - 8 - - - - - - True - - False - True - - - 1 - 2 - 7 - 8 - - - - - - True - - False - True - - - 0 - 1 - 10 - 11 - - - - - - True - - False - True - - - 1 - 2 - 10 - 11 - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Configure - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Test - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - About - True - GTK_RELIEF_NORMAL - True - - - - - - 1 - 2 - 5 - 6 - - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Configure - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Test - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - About - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - 1 - 5 - 6 - - - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Configure - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Test - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - About - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - 1 - 2 - 3 - - - - - - - True - Graphics - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 0 - 1 - - - - - - - - True - First Controller - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 3 - 4 - - - - - - - - True - Second Controller - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 1 - 2 - 3 - 4 - - - - - - - - True - Sound - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 1 - 2 - 0 - 1 - - - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Configure - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Test - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - About - True - GTK_RELIEF_NORMAL - True - - - - - - 1 - 2 - 2 - 3 - - - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Configure - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Test - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - About - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - 1 - 8 - 9 - - - - - - - True - Dev9 - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 6 - 7 - - - - - - - - True - Cdvdrom - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 1 - 2 - 6 - 7 - - - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Configure - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Test - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - About - True - GTK_RELIEF_NORMAL - True - - - - - - 1 - 2 - 8 - 9 - - - - - - - - True - Usb - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - 1 - 9 - 10 - - - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Configure - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Test - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - About - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - 1 - 11 - 12 - - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - Configure - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Test - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - About - True - GTK_RELIEF_NORMAL - True - - - - - - 1 - 2 - 11 - 12 - - - - - - - - True - FireWire - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 1 - 2 - 9 - 10 - - - - - - - - True - Bios - False - False - GTK_JUSTIFY_CENTER - False - False - 0 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 1 - 2 - 12 - 13 - - - - - - - 0 - True - True - - - - - - True - False - 14 - - - - True - GTK_BUTTONBOX_START - 0 - - - - True - True - True - Select Plugins Dir - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - Select Bios Dir - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - False - True - - - - - - True - GTK_BUTTONBOX_DEFAULT_STYLE - 0 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - - - 10 - True - Pcsx About - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - True - False - 0 - - - - True - False - 0 - - - - True - PCSX2 - -Version x.x - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - 5 - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - 5 - True - False - 0 - - - - True - written by... - False - False - GTK_JUSTIFY_CENTER - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - 0 - False - False - - - - - 0 - True - True - - - - - - 5 - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - 5 - True - False - 0 - - - - True - greets to... - False - False - GTK_JUSTIFY_CENTER - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - 0 - False - False - - - - - - True - GTK_BUTTONBOX_EDGE - 0 - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - False - False - - - - - - - - True - PCSX - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_CENTER - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - False - - - - - - True - False - 0 - - - - True - GTK_PACK_DIRECTION_LTR - GTK_PACK_DIRECTION_LTR - - - - True - _File - True - - - - - - - True - _Run CD - True - - - - - - - True - _Load Elf - True - - - - - - - True - - - - - - True - States - True - - - - - - - True - Load - True - - - - - - - True - Slot 0 - True - - - - - - - True - Slot 1 - True - - - - - - - True - Slot 2 - True - - - - - - - True - Slot 3 - True - - - - - - - True - Slot 4 - True - - - - - - - True - Other... - True - - - - - - - - - - - True - Save - True - - - - - - - True - Slot 0 - True - - - - - - - True - Slot 1 - True - - - - - - - True - Slot 2 - True - - - - - - - True - Slot 3 - True - - - - - - - True - Slot 4 - True - - - - - - - True - Other... - True - - - - - - - - - - - - - - - True - E_xit - True - - - - - - - - - - - True - _Run - True - - - - - - - True - E_xecute - True - - - - - - - True - Re_set - True - - - - - - - - - - - True - _Config - True - - - - - - - True - _Configure - True - - - - - - - True - - - - - - True - _Graphics - True - - - - - - - True - C_ontrollers - True - - - - - - - True - _Sound - True - - - - - - - True - _Cdvdrom - True - - - - - - - True - D_ev9 - True - - - - - - - True - U_SB - True - - - - - - - True - Fire_Wire - True - - - - - - - True - - - - - - True - Memcards - True - - - - - - - True - C_pu - True - - - - - - - True - Game Fixes - True - - - - - - - True - Speed Hacks - True - - - - - - - True - Advanced - True - - - - - - - - - - - True - _Language - True - - - - - - True - _Misc - True - - - - - - - True - Patch _Browser - True - - - - - - - True - Patch _Finder - True - - - - - - - True - - - - - - True - Enable _Console - True - False - - - - - - - True - Enable _Patches - True - False - - - - - - - True - Print CDVD Info - True - False - - - - - - - - - - - True - _Debug - True - - - - - - - True - Enter Debugger ... - True - - - - - - - True - Logging - True - - - - - - - True - - - - - - True - _Arguments - True - - - - - - - - - - - True - _Help - True - - - - - - - True - About PCSX2... - True - - - - - - - - - - 0 - False - False - - - - - - True - pcsxAbout.bmp - 0.5 - 0.5 - 0 - 0 - - - 1 - True - True - - - - - - True - False - 0 - - - - - - - 0 - True - True - - - - - - - - Patch List - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - True - True - False - False - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - - - - True - False - 0 - - - - True - True - GTK_POLICY_ALWAYS - GTK_POLICY_ALWAYS - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - True - False - False - True - False - False - False - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - True - Enable / Diable - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - True - Add Patch - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - True - Edit Patch - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - True - Add GS2v3-4 - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - True - Add Raw - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - True - Pnach Writer - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - True - True - Skip Mpeg - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - - - - - - - - - - True - True - gtk-close - True - GTK_RELIEF_NORMAL - True - - - 0 - False - False - - - - - 0 - True - True - - - - - - - - True - Patch Finder - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - True - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - - - - True - False - 0 - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - EE RAM - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - IOP RAM - True - GTK_RELIEF_NORMAL - True - False - False - True - radiobutton1 - - - 0 - False - False - - - - - - - - - - True - <b>Search In</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - 3 - 2 - False - 0 - 0 - - - - True - True - Unsigned - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 2 - 3 - - - - - - - - True - True - 64 bits - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 1 - 2 - 1 - 2 - - - - - - - - True - True - 32 bits - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 1 - 2 - - - - - - - - True - True - 16 bits - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 1 - 2 - 0 - 1 - - - - - - - - True - True - 8 bits - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 0 - 1 - - - - - - - - - - - - True - <b>Values of Size</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - Equal - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Greater Then - True - GTK_RELIEF_NORMAL - True - False - False - True - radiobutton7 - - - 0 - False - False - - - - - - True - True - Less Then - True - GTK_RELIEF_NORMAL - True - False - False - True - radiobutton7 - - - 0 - False - False - - - - - - True - True - Greater Then or Equal - True - GTK_RELIEF_NORMAL - True - False - False - True - radiobutton7 - - - 0 - False - False - - - - - - True - True - Less Then or Equal - True - GTK_RELIEF_NORMAL - True - False - False - True - radiobutton7 - - - 0 - False - False - - - - - - True - True - Not Equal - True - GTK_RELIEF_NORMAL - True - False - False - True - radiobutton7 - - - 0 - False - False - - - - - - - - - - True - <b>Being</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - Old Value - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Specific Value - True - GTK_RELIEF_NORMAL - True - False - False - True - radiobutton13 - - - 0 - False - False - - - - - - True - True - True - True - 0 - - True - * - False - - - 0 - False - False - - - - - - - - - - True - <b>Compared To</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - False - 0 - - - - True - False - 0 - - - - True - Results: - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - %s - False - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - True - True - - - - - - True - Ready to Search - False - False - GTK_JUSTIFY_RIGHT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - True - False - - - - - 0 - False - False - - - - - - True - True - GTK_POLICY_ALWAYS - GTK_POLICY_ALWAYS - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - True - False - False - True - False - False - False - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - 2 - 2 - False - 0 - 0 - - - - True - True - gtk-close - True - GTK_RELIEF_NORMAL - True - - - 1 - 2 - 1 - 2 - - - - - - - True - True - gtk-add - True - GTK_RELIEF_NORMAL - True - - - 0 - 1 - 1 - 2 - - - - - - - True - True - gtk-find - True - GTK_RELIEF_NORMAL - True - - - 1 - 2 - 0 - 1 - - - - - - - True - True - gtk-clear - True - GTK_RELIEF_NORMAL - True - - - 0 - 1 - 0 - 1 - - - - - - 0 - False - True - - - - - 0 - True - True - - - - - - - - True - dialog1 - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - True - - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - 0 - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - 0 - - - - - - 0 - False - True - GTK_PACK_END - - - - - - True - False - 0 - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - CPU vendor - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - Family - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - Cpu Speed - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - Features - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - - True - - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - True - EERec - EE/IOP recompiler (Need MMX/SSE/SSE2) - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - 5 - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - 5 - True - False - 0 - - - - True - True - VU0rec - enable recompilers for VU0 unit - True - GTK_RELIEF_NORMAL - True - False - False - True - - - - 0 - False - False - - - - - - True - True - VU1rec - enable recompilers for VU1 unit - True - GTK_RELIEF_NORMAL - True - False - False - True - - - - 0 - False - False - - - - - - - - True - VU Recompilers - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - 5 - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - 5 - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 0 - 0 - - - - True - False - 0 - - - - True - True - microVU0 - Use microVU rec instead of VU0rec. ! Beta ! - True - GTK_RELIEF_NORMAL - True - False - False - True - - - - 0 - False - False - - - - - - True - True - microVU1 - Use microVU rec instead of VU1rec. ! Beta ! - True - GTK_RELIEF_NORMAL - True - False - False - True - - - - 0 - False - False - - - - - - - - - - True - microVU Recompilers - ! Beta ! - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - False - - - - - - True - True - Multi threaded GS mode (MTGS) - (faster on dual core/HT CPUs, requires pcsx2 restart) - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - Normal - All frames are rendered as fast as possible - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Limit - Force frames to normal speeds if too fast - True - GTK_RELIEF_NORMAL - True - False - False - True - GtkRadioButton_LimitNormal - - - 0 - False - False - - - - - - True - True - Frame Skip - In order to achieve normal speeds, - some frames are skipped (faster). - Fps displayed counts skipped frames too - True - GTK_RELIEF_NORMAL - True - False - False - True - GtkRadioButton_LimitNormal - - - 0 - False - False - - - - - - - - - - True - Frame Limiting (F4 switches in-game) - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - False - 0 - - - - True - Custom FPS Limit (0=auto): - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - True - True - - - - - - True - True - 1 - 0 - True - GTK_UPDATE_ALWAYS - False - False - 0 0 9999 1 0 0 - - - 0 - False - True - GTK_PACK_END - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - Skip Frames when slower than[1]: - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - True - True - - - - - - True - True - 1 - 0 - False - GTK_UPDATE_ALWAYS - False - False - 0 0 9999 1 0 0 - - - 0 - False - True - GTK_PACK_END - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - Consecutive Frames before skipping[2]: - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - True - True - - - - - - True - True - 1 - 0 - False - GTK_UPDATE_ALWAYS - False - False - 0 0 9999 1 0 0 - - - 0 - False - True - GTK_PACK_END - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - Consecutive Frames to skip[3]: - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - True - True - - - - - - True - True - 1 - 0 - False - GTK_UPDATE_ALWAYS - False - False - 0 0 9999 1 0 0 - - - 0 - False - True - GTK_PACK_END - - - - - 0 - True - True - - - - - - True - [1] Only skips when slower then this number(0 is auto; 9999 always skips). - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - [2] Renders this many frames before skipping (0 is default). - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - [3] Skips this many frames before continuing (0 is default). - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - - True - Detailed Settings - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - - - True - Logging - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - 200 - 450 - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - True - - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - -6 - - - - - - 0 - False - True - GTK_PACK_END - - - - - - True - True - GTK_POLICY_ALWAYS - GTK_POLICY_ALWAYS - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - GTK_SHADOW_IN - - - - True - False - 0 - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - Cpu Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Mem Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Hw Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Dma Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Bios Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Elf Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Fpu Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - MMI Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - VU0 Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Cop0 Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Vif Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - SPR Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - GIF Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Sif Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - IPU Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - VU Micro Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - RPC Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - - - - - True - <b>EE Logs</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - IOP Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Mem Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Hw Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Bios Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Dma Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Pad Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Gte Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Cdr Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - GPU Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - - - - - True - <b>IOP Logs</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_NONE - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - Log to STDOUT - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - SYMs Log - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - - - - - True - <b>Misc</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - - - - - 0 - True - True - - - - - - - - True - Memcards - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - True - - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - - - True - True - True - gtk-cancel - True - GTK_RELIEF_NORMAL - True - -6 - - - - - - 0 - False - True - GTK_PACK_END - - - - - - True - False - 0 - - - - True - False - 0 - - - - True - False - 0 - - - - True - False - 0 - - - - True - True - 0 - - - - True - True - Enabled - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - True - Enabled - True - GTK_RELIEF_NORMAL - True - True - False - True - - - 0 - False - False - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - False - 0 - - - - True - True - 0 - - - - True - Memcard 1 - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - True - True - - - - - - True - Memcard 2 - False - False - GTK_JUSTIFY_RIGHT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - 0 - True - True - - - - - - True - False - 0 - - - - True - False - True - - - 0 - True - True - - - - - - True - False - True - - - 0 - True - True - - - - - 0 - True - True - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - - - - 0 - True - True - - - - - - True - 0 - 0.5 - GTK_SHADOW_ETCHED_IN - - - - True - 0.5 - 0.5 - 1 - 1 - 0 - 0 - 12 - 0 - - - - True - False - 0 - - - - True - True - Eject Mcds when loading SaveStates - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - False - False - - - - - - True - This feature tells games when the mcd contents have changed so that they re-index the new Mcd contents. WARNING: Disabling this option is NOT recommended, and could lead to MemCard corruption if you also use SaveStates. - False - False - GTK_JUSTIFY_LEFT - True - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - - True - <b>Options</b> - False - True - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - True - True - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - - diff --git a/pcsx2/Misc.cpp b/pcsx2/Misc.cpp index b5e4ef9d83..243605abcb 100644 --- a/pcsx2/Misc.cpp +++ b/pcsx2/Misc.cpp @@ -30,7 +30,7 @@ #include "IopCommon.h" #include "HostGui.h" -#include "CDVD/CDVDisodrv.h" +#include "CDVD/IsoFSdrv.h" #include "VUmicro.h" #include "VU.h" #include "iCore.h" @@ -244,17 +244,17 @@ int GetPS2ElfName( wxString& name ) char *pos; TocEntry tocEntry; - CDVDFS_init(); + IsoFS_init(); // check if the file exists - if (CDVD_findfile("SYSTEM.CNF;1", &tocEntry) != TRUE){ + if (IsoFS_findFile("SYSTEM.CNF;1", &tocEntry) != TRUE){ Console::Error("Boot Error > SYSTEM.CNF not found"); return 0;//could not find; not a PS/PS2 cdvd } - f=CDVDFS_open("SYSTEM.CNF;1", 1); - CDVDFS_read(f, buffer, g_MaxPath); - CDVDFS_close(f); + f=IsoFS_open("SYSTEM.CNF;1", 1); + IsoFS_read(f, buffer, g_MaxPath); + IsoFS_close(f); buffer[tocEntry.fileSize]='\0'; @@ -422,6 +422,16 @@ void CycleFrameLimit(int dir) newOptions = (Config.Options & ~PCSX2_FRAMELIMIT_MASK) | newFrameLimit; gsResetFrameSkip(); + + // Allows sync to vblank only when framelimit is on, if GS can. + if(GSsetFrameLimit == NULL) + { + DevCon::Notice("Notice: GS Plugin does not implement GSsetFrameLimit."); + } + else + { + GSsetFrameLimit(newFrameLimit); + } switch(newFrameLimit) { case PCSX2_FRAMELIMIT_NORMAL: diff --git a/pcsx2/Plugins.cpp b/pcsx2/Plugins.cpp index c9fd76aad5..b6c34d68d9 100644 --- a/pcsx2/Plugins.cpp +++ b/pcsx2/Plugins.cpp @@ -22,6 +22,7 @@ #include "IopCommon.h" #include "GS.h" #include "HostGui.h" +#include "CDVD/CDVDisoReader.h" _GSinit GSinit; _GSopen GSopen; @@ -45,6 +46,7 @@ _GSprintf GSprintf; _GSsetBaseMem GSsetBaseMem; _GSsetGameCRC GSsetGameCRC; _GSsetFrameSkip GSsetFrameSkip; +_GSsetFrameLimit GSsetFrameLimit; _GSsetupRecording GSsetupRecording; _GSreset GSreset; _GSwriteCSR GSwriteCSR; @@ -137,25 +139,8 @@ _SPU2test SPU2test; _SPU2about SPU2about; // CDVD -_CDVDinit CDVDinit; -_CDVDopen CDVDopen; -_CDVDclose CDVDclose; -_CDVDshutdown CDVDshutdown; -_CDVDreadTrack CDVDreadTrack; -_CDVDgetBuffer CDVDgetBuffer; -_CDVDreadSubQ CDVDreadSubQ; -_CDVDgetTN CDVDgetTN; -_CDVDgetTD CDVDgetTD; -_CDVDgetTOC CDVDgetTOC; -_CDVDgetDiskType CDVDgetDiskType; -_CDVDgetTrayStatus CDVDgetTrayStatus; -_CDVDctrlTrayOpen CDVDctrlTrayOpen; -_CDVDctrlTrayClose CDVDctrlTrayClose; - -_CDVDconfigure CDVDconfigure; -_CDVDtest CDVDtest; -_CDVDabout CDVDabout; -_CDVDnewDiskCB CDVDnewDiskCB; +CDVDplugin CDVD_plugin = {0}; +CDVDplugin CDVD = {0}; // DEV9 _DEV9init DEV9init; @@ -247,18 +232,21 @@ void CloseGS() #ifdef _not_wxWidgets_Land_ -enum PluginTypes +namespace PluginTypes { - GS = 0, - PAD, - PAD1, - PAD2, - SPU2, - CDVD, - DEV9, - USB, - FW -}; + enum PluginTypes + { + GS = 0, + PAD, + PAD1, + PAD2, + SPU2, + CDVD, + DEV9, + USB, + FW + }; +} int PS2E_LT[9] = { PS2E_LT_GS, @@ -294,6 +282,10 @@ PS2E_FW_VERSION}; #define MapSymbol_Fallback(name,fallback) MapSymbolVar_Fallback(name,name,fallback) #define MapSymbol_Error(name) MapSymbolVar_Error(name,name) +#define MapSymbol2(base,name) MapSymbolVar(base##_plugin.name,base##name) +#define MapSymbol2_Fallback(base,name,fallback) MapSymbolVar_Fallback(base##_plugin.name,base##name,fallback) +#define MapSymbol2_Error(base,name) MapSymbolVar_Error(base##_plugin.name,base##name) + // for pad1/2 #define MapSymbolPAD(var,name) MapSymbolVar(var##name,PAD##name) #define MapSymbolPAD_Fallback(var,name) if((MapSymbolVarType(var##name,_PAD##name,PAD##name))==NULL) var##name = var##_##name @@ -321,7 +313,7 @@ static int _TestPS2Esyms(void* drv, int type, int expected_version, const wxStri return 0; } -static __forceinline bool TestPS2Esyms(void* &drv, PluginTypes type, const string& filename) +static __forceinline bool TestPS2Esyms(void* &drv, PluginTypes::PluginTypes type, const string& filename) { if (_TestPS2Esyms(drv, PS2E_LT[type],PS2E_VERSION[type],filename) < 0) return false; return true; @@ -353,7 +345,7 @@ int LoadGSplugin(const wxString& filename) GSplugin = SysLoadLibrary(filename.c_str()); if (GSplugin == NULL) { Msgbox::Alert ("Could Not Load GS Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = GSplugin; - if (!TestPS2Esyms(drv, GS, filename)) return -1; + if (!TestPS2Esyms(drv, PluginTypes::GS, filename)) return -1; MapSymbol_Error(GSinit); MapSymbol_Error(GSshutdown); MapSymbol_Error(GSopen); @@ -380,6 +372,7 @@ int LoadGSplugin(const wxString& filename) MapSymbol(GSgetDriverInfo); MapSymbol(GSsetFrameSkip); + MapSymbol(GSsetFrameLimit); MapSymbol(GSsetupRecording); #ifdef _WIN32 @@ -408,7 +401,7 @@ int LoadPAD1plugin(const wxString& filename) { PAD1plugin = SysLoadLibrary(filename.c_str()); if (PAD1plugin == NULL) { Msgbox::Alert("Could Not Load PAD1 Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = PAD1plugin; - if (!TestPS2Esyms(drv, PAD, filename)) return -1; + if (!TestPS2Esyms(drv, PluginTypes::PAD, filename)) return -1; MapSymbolPAD_Error(PAD1,init); MapSymbolPAD_Error(PAD1,shutdown); MapSymbolPAD_Error(PAD1,open); @@ -445,7 +438,7 @@ int LoadPAD2plugin(const wxString& filename) { PAD2plugin = SysLoadLibrary(filename.c_str()); if (PAD2plugin == NULL) { Msgbox::Alert("Could Not Load PAD2 Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = PAD2plugin; - if (!TestPS2Esyms(drv, PAD, filename)) return -1; + if (!TestPS2Esyms(drv, PluginTypes::PAD, filename)) return -1; MapSymbolPAD_Error(PAD2,init); MapSymbolPAD_Error(PAD2,shutdown); MapSymbolPAD_Error(PAD2,open); @@ -480,7 +473,7 @@ int LoadSPU2plugin(const wxString& filename) { SPU2plugin = SysLoadLibrary(filename.c_str()); if (SPU2plugin == NULL) { Msgbox::Alert("Could Not Load SPU2 Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = SPU2plugin; - if (!TestPS2Esyms(drv, SPU2, filename)) return -1; + if (!TestPS2Esyms(drv, PluginTypes::SPU2, filename)) return -1; MapSymbol_Error(SPU2init); MapSymbol_Error(SPU2shutdown); MapSymbol_Error(SPU2open); @@ -516,33 +509,117 @@ void *CDVDplugin; void CALLBACK CDVD_configure() {} void CALLBACK CDVD_about() {} s32 CALLBACK CDVD_test() { return 0; } +void CALLBACK CDVD_newDiskCB(void (*callback)()) {} +extern int lastReadSize; +s32 CALLBACK CDVD_getBuffer2(u8* buffer) +{ + int ret; + + + // TEMP: until I fix all the plugins to use this function style + u8* pb = CDVD.getBuffer(); + if(pb!=NULL) + { + memcpy(buffer,pb,lastReadSize); + ret=0; + } + else ret= -1; + + return ret; +} + + +s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode) +{ + if(CDVD.readTrack(lsn,mode)<0) + return -1; + + // TEMP: until all the plugins use the new CDVDgetBuffer style + switch (mode) + { + case CDVD_MODE_2352: + lastReadSize = 2352; + break; + case CDVD_MODE_2340: + lastReadSize = 2340; + break; + case CDVD_MODE_2328: + lastReadSize = 2328; + break; + case CDVD_MODE_2048: + lastReadSize = 2048; + break; + } + return CDVD.getBuffer2(buffer); +} + +s32 CALLBACK CDVD_getDualInfo(s32* dualType, u32* layer1Start) +{ + u8 toc[2064]; + + // if error getting toc, settle for single layer disc ;) + if(CDVD.getTOC(toc)) + return 0; + if(toc[14] & 0x60) + { + if(toc[14] & 0x10) + { + // otp dvd + *dualType = 2; + *layer1Start = (toc[25]<<16) + (toc[26]<<8) + (toc[27]) - 0x30000 + 1; + } + else + { + // ptp dvd + *dualType = 1; + *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; + } + } + else + { + // single layer dvd + *dualType = 0; + *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; + } + + return 1; +} + +int cdvdInitCount; int LoadCDVDplugin(const wxString& filename) { void *drv; CDVDplugin = SysLoadLibrary(filename.c_str()); if (CDVDplugin == NULL) { Msgbox::Alert("Could Not Load CDVD Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = CDVDplugin; - if (!TestPS2Esyms(drv, CDVD, filename)) return -1; - MapSymbol_Error(CDVDinit); - MapSymbol_Error(CDVDshutdown); - MapSymbol_Error(CDVDopen); - MapSymbol_Error(CDVDclose); - MapSymbol_Error(CDVDreadTrack); - MapSymbol_Error(CDVDgetBuffer); - MapSymbol_Error(CDVDreadSubQ); - MapSymbol_Error(CDVDgetTN); - MapSymbol_Error(CDVDgetTD); - MapSymbol_Error(CDVDgetTOC); - MapSymbol_Error(CDVDgetDiskType); - MapSymbol_Error(CDVDgetTrayStatus); - MapSymbol_Error(CDVDctrlTrayOpen); - MapSymbol_Error(CDVDctrlTrayClose); + if (!TestPS2Esyms(drv, PluginTypes::CDVD, filename)) return -1; + MapSymbol2_Error(CDVD,init); + MapSymbol2_Error(CDVD,shutdown); + MapSymbol2_Error(CDVD,open); + MapSymbol2_Error(CDVD,close); + MapSymbol2_Error(CDVD,readTrack); + MapSymbol2_Error(CDVD,getBuffer); + MapSymbol2_Error(CDVD,readSubQ); + MapSymbol2_Error(CDVD,getTN); + MapSymbol2_Error(CDVD,getTD); + MapSymbol2_Error(CDVD,getTOC); + MapSymbol2_Error(CDVD,getDiskType); + MapSymbol2_Error(CDVD,getTrayStatus); + MapSymbol2_Error(CDVD,ctrlTrayOpen); + MapSymbol2_Error(CDVD,ctrlTrayClose); - MapSymbol_Fallback(CDVDconfigure,CDVD_configure); - MapSymbol_Fallback(CDVDabout,CDVD_about); - MapSymbol_Fallback(CDVDtest,CDVD_test); - MapSymbol(CDVDnewDiskCB); + MapSymbol2_Fallback(CDVD,configure,CDVD_configure); + MapSymbol2_Fallback(CDVD,about,CDVD_about); + MapSymbol2_Fallback(CDVD,test,CDVD_test); + MapSymbol2_Fallback(CDVD,newDiskCB,CDVD_newDiskCB); + + MapSymbol2_Fallback(CDVD,readSector,CDVD_readSector); + MapSymbol2_Fallback(CDVD,getBuffer2,CDVD_getBuffer2); + MapSymbol2_Fallback(CDVD,getDualInfo,CDVD_getDualInfo); + + CDVD.initCount = &cdvdInitCount; + cdvdInitCount=0; return 0; } @@ -560,7 +637,7 @@ int LoadDEV9plugin(const wxString& filename) { DEV9plugin = SysLoadLibrary(filename.c_str()); if (DEV9plugin == NULL) { Msgbox::Alert("Could Not Load DEV9 Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = DEV9plugin; - if (!TestPS2Esyms(drv, DEV9, filename)) return -1; + if (!TestPS2Esyms(drv, PluginTypes::DEV9, filename)) return -1; MapSymbol_Error(DEV9init); MapSymbol_Error(DEV9shutdown); MapSymbol_Error(DEV9open); @@ -597,7 +674,7 @@ int LoadUSBplugin(const wxString& filename) { USBplugin = SysLoadLibrary(filename.c_str()); if (USBplugin == NULL) { Msgbox::Alert("Could Not Load USB Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = USBplugin; - if (!TestPS2Esyms(drv, USB, filename)) return -1; + if (!TestPS2Esyms(drv, PluginTypes::USB, filename)) return -1; MapSymbol_Error(USBinit); MapSymbol_Error(USBshutdown); MapSymbol_Error(USBopen); @@ -634,7 +711,7 @@ int LoadFWplugin(const wxString& filename) { FWplugin = SysLoadLibrary(filename.c_str()); if (FWplugin == NULL) { Msgbox::Alert("Could Not Load FW Plugin '%hs': %s", params &filename, SysLibError()); return -1; } drv = FWplugin; - if (!TestPS2Esyms(drv, FW, filename)) return -1; + if (!TestPS2Esyms(drv, PluginTypes::FW, filename)) return -1; MapSymbol_Error(FWinit); MapSymbol_Error(FWshutdown); MapSymbol_Error(FWopen); @@ -721,7 +798,9 @@ int InitPlugins() if (ReportError(PAD1init(1), "PAD1init")) return -1; if (ReportError(PAD2init(2), "PAD2init")) return -1; if (ReportError(SPU2init(), "SPU2init")) return -1; - if (ReportError(CDVDinit(), "CDVDinit")) return -1; + + if (ReportError(DoCDVDinit(), "CDVDinit")) return -1; + if (ReportError(DEV9init(), "DEV9init")) return -1; if (ReportError(USBinit(), "USBinit")) return -1; if (ReportError(FWinit(), "FWinit")) return -1; @@ -744,7 +823,14 @@ void ShutdownPlugins() if (PAD2shutdown != NULL) PAD2shutdown(); if (SPU2shutdown != NULL) SPU2shutdown(); - if (CDVDshutdown != NULL) CDVDshutdown(); + + //if (CDVDshutdown != NULL) CDVDshutdown(); + DoCDVDshutdown(); + + // safety measures, in case ISO is currently loaded. + if(cdvdInitCount>0) + CDVD_plugin.shutdown(); + if (DEV9shutdown != NULL) DEV9shutdown(); if (USBshutdown != NULL) USBshutdown(); if (FWshutdown != NULL) FWshutdown(); @@ -786,9 +872,9 @@ bool OpenCDVD(const char* pTitleFilename) if (!OpenStatus.CDVD && !only_loading_elf) { //First, we need the data. - if (CDVDnewDiskCB) CDVDnewDiskCB(cdvdNewDiskCB); + CDVD.newDiskCB(cdvdNewDiskCB); - if (CDVDopen(pTitleFilename) != 0) + if (DoCDVDopen(pTitleFilename) != 0) { if (g_Startup.BootMode != BootMode_Elf) { @@ -915,7 +1001,7 @@ int OpenPlugins(const char* pTitleFilename) (!OpenSPU2()) || (!OpenDEV9()) || (!OpenUSB()) || (!OpenFW())) return -1; - if (!only_loading_elf) cdvdNewDiskCB(); + if (!only_loading_elf) cdvdDetectDisk(); return 0; } @@ -926,6 +1012,12 @@ int OpenPlugins(const char* pTitleFilename) OpenStatus.name = false; \ } +#define CLOSE_PLUGIN2( name ) \ + if( OpenStatus.name ) { \ + name.close(); \ + OpenStatus.name = false; \ + } + void ClosePlugins( bool closegs ) { @@ -951,7 +1043,12 @@ void ClosePlugins( bool closegs ) } } - CLOSE_PLUGIN( CDVD ); + if( OpenStatus.CDVD ) + { + DoCDVDclose(); + OpenStatus.CDVD=false; + } + CLOSE_PLUGIN( DEV9 ); CLOSE_PLUGIN( USB ); CLOSE_PLUGIN( FW ); diff --git a/pcsx2/R5900.cpp b/pcsx2/R5900.cpp index bb9234e87d..faa5c3f7cc 100644 --- a/pcsx2/R5900.cpp +++ b/pcsx2/R5900.cpp @@ -50,7 +50,7 @@ R5900cpu *Cpu = NULL; u32 bExecBIOS = 0; // set if the BIOS has already been executed static bool cpuIsInitialized = false; -static uint eeWaitCycles = 1024; +static const uint eeWaitCycles = 3072; bool eeEventTestIsActive = false; @@ -80,12 +80,6 @@ void cpuReset() g_nextBranchCycle = cpuRegs.cycle + 4; EEsCycle = 0; EEoCycle = cpuRegs.cycle; - eeWaitCycles = Config.Hacks.WaitCycleExt ? 3072 : 768; - - // Cyclerate hacks effectively speed up the rate of event tests, so we can safely boost - // the WaitCycles value here for x2 and x3 modes: - if( Config.Hacks.EECycleRate > 1 ) - eeWaitCycles += 1024; hwReset(); vif0Reset(); diff --git a/pcsx2/SaveState.cpp b/pcsx2/SaveState.cpp index 73c08377af..e089ee4210 100644 --- a/pcsx2/SaveState.cpp +++ b/pcsx2/SaveState.cpp @@ -21,7 +21,7 @@ #include "IopCommon.h" #include "SaveState.h" -#include "CDVD/CDVDisodrv.h" +#include "CDVD/IsoFSdrv.h" #include "VUmicro.h" #include "VU.h" #include "iCore.h" diff --git a/pcsx2/SourceLog.cpp b/pcsx2/SourceLog.cpp index 4e5c46b5c6..a1c5a24cce 100644 --- a/pcsx2/SourceLog.cpp +++ b/pcsx2/SourceLog.cpp @@ -182,6 +182,7 @@ IMPLEMENT_SOURCE_LOG( MEMCARDS, 'I', 7 ) IMPLEMENT_SOURCE_LOG( PAD, 'I', 7 ) IMPLEMENT_SOURCE_LOG( GTE, 'I', 3 ) IMPLEMENT_SOURCE_LOG( CDR, 'I', 8 ) +IMPLEMENT_SOURCE_LOG( CDVD, 'I', 8 ) diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index 969b0b34c0..1ed97a0bb4 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -29,6 +29,8 @@ #include "R5900Exceptions.h" +#include "CDVD/CDVD.h" + using namespace std; // disable all session overrides by default... @@ -346,6 +348,10 @@ void SysEndExecution() // use_bios - forces the game to boot through the PS2 bios, instead of bypassing it. void SysPrepareExecution( const wxString& elf_file, bool use_bios ) { + // solve a little crash + if(CDVD.init == NULL) + CDVD = CDVD_plugin; + if( !g_EmulationInProgress ) { try diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index a8886e4d6f..72a3902baf 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -1776,6 +1776,26 @@ RelativePath="..\..\CDVD\CDVD_internal.h" > + + + + + + + + + + - - - - - - - - - - @@ -2181,6 +2181,34 @@ RelativePath="..\..\Elfheader.h" > + + + + + + + + + + + + + + 2) Config.Hacks.EECycleRate = 2; Entry("IOPCycleDouble", Config.Hacks.IOPCycleDouble); - Entry("WaitCycleExt", Config.Hacks.WaitCycleExt); + //Entry("WaitCycleExt", Config.Hacks.WaitCycleExt); Entry("INTCSTATSlow", Config.Hacks.INTCSTATSlow); Entry("VUCycleSteal", Config.Hacks.VUCycleSteal); Entry("vuFlagHack", Config.Hacks.vuFlagHack); diff --git a/pcsx2/x86/iR5900.h b/pcsx2/x86/iR5900.h index 5ae91988b1..21e28fe963 100644 --- a/pcsx2/x86/iR5900.h +++ b/pcsx2/x86/iR5900.h @@ -140,7 +140,7 @@ void _eeOnWriteReg(int reg, int signext); void _deleteEEreg(int reg, int flush); // allocates memory on the instruction size and returns the pointer -u32* recAllocStackMem(int size, int align); +u32* recGetImm64(u32 hi, u32 lo); void _vuRegsCOP22(VURegs * VU, _VURegsNum *VUregsn); diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index e7bb45986a..f81a046a6c 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -74,24 +74,24 @@ u32 g_cpuHasConstReg = 0, g_cpuFlushedConstReg = 0; // Static Private Variables - R5900 Dynarec #define X86 -static const int RECSTACK_SIZE = 0x00020000; +static const int RECCONSTBUF_SIZE = 16384 * 2; // 64 bit consts in 32 bit units static u8 *recMem = NULL; // the recompiled blocks will be here -static u8* recStack = NULL; // stack mem +static u32* recConstBuf = NULL; // 64-bit pseudo-immediates static BASEBLOCK *recRAM = NULL; // and the ptr to the blocks here static BASEBLOCK *recROM = NULL; // and here static BASEBLOCK *recROM1 = NULL; // also here static u32 *recRAMCopy = NULL; void JITCompile(); static BaseBlocks recBlocks((uptr)JITCompile); -static u8* recPtr = NULL, *recStackPtr = NULL; +static u8* recPtr = NULL; +static u32 *recConstBufPtr = NULL; EEINST* s_pInstCache = NULL; static u32 s_nInstCacheSize = 0; static BASEBLOCK* s_pCurBlock = NULL; static BASEBLOCKEX* s_pCurBlockEx = NULL; u32 s_nEndBlock = 0; // what pc the current block ends -static u32 s_nHasDelay = 0; static bool s_nBlockFF; // save states for branches @@ -208,13 +208,8 @@ u32* _eeGetConstReg(int reg) return &cpuRegs.GPR.r[ reg ].UL[0]; // if written in the future, don't flush - if( _recIsRegWritten(g_pCurInstInfo+1, (s_nEndBlock-pc)/4, XMMTYPE_GPRREG, reg) ) { - u32* ptempmem; - ptempmem = recAllocStackMem(8, 4); - ptempmem[0] = g_cpuConstRegs[ reg ].UL[0]; - ptempmem[1] = g_cpuConstRegs[ reg ].UL[1]; - return ptempmem; - } + if( _recIsRegWritten(g_pCurInstInfo+1, (s_nEndBlock-pc)/4, XMMTYPE_GPRREG, reg) ) + return recGetImm64(g_cpuConstRegs[reg].UL[1], g_cpuConstRegs[reg].UL[0]); _flushConstReg(reg); return &cpuRegs.GPR.r[ reg ].UL[0]; @@ -340,19 +335,44 @@ int _flushUnusedConstReg() return 0; } -// ------------------------------------------------------------------------ -// recAllocStackMem -- an optimization trick to write data to a location so that -// recompiled code can reference it later on during execution. -// -// Intended use is for setting up 64/128 bit SSE immediates, primarily. -// -u32* recAllocStackMem(int size, int align) +// Some of the generated MMX code needs 64-bit immediates but x86 doesn't +// provide this. One of the reasons we are probably better off not doing +// MMX register allocation for the EE. +u32* recGetImm64(u32 hi, u32 lo) { - jASSUME( align == 4 || align == 8 || align == 16 ); + u32 *imm64; // returned pointer + static u32 *imm64_cache[509]; + int cacheidx = lo % (sizeof imm64_cache / sizeof *imm64_cache); + //static int count; count++; - recStackPtr = (u8*) ( (((uptr)recStackPtr) + (align-1)) & ~(align-1) ); - recStackPtr += size; - return (u32*)(recStackPtr-size); + imm64 = imm64_cache[cacheidx]; + if (imm64 && imm64[0] == lo && imm64[1] == hi) + return imm64; + + if (recConstBufPtr >= recConstBuf + RECCONSTBUF_SIZE) { + // TODO: flag an error in recompilation which would reset the recompiler + // immediately and recompile the current block again. There is currently + // no way to do this, so have a last ditch attempt at making things sane + // and return some nonsense if that fails. + for (u32 *p = recConstBuf; p < recConstBuf + RECCONSTBUF_SIZE; p += 2) + if (p[0] == lo && p[1] == hi) { + imm64_cache[cacheidx] = p; + return p; + } + + return recConstBuf; + } + + imm64 = recConstBufPtr; + recConstBufPtr += 2; + imm64_cache[cacheidx] = imm64; + + imm64[0] = lo; + imm64[1] = hi; + + //Console::Notice("Consts allocated: %d of %u", params (recConstBufPtr - recConstBuf) / 2, count); + + return imm64; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -365,7 +385,7 @@ static u8* m_recBlockAlloc = NULL; static const uint m_recBlockAllocSize = (((Ps2MemSize::Base + Ps2MemSize::Rom + Ps2MemSize::Rom1) / 4) * sizeof(BASEBLOCK)) -+ RECSTACK_SIZE + Ps2MemSize::Base; ++ RECCONSTBUF_SIZE * sizeof(u32) + Ps2MemSize::Base; static void recAlloc() { @@ -407,7 +427,7 @@ static void recAlloc() recRAM = (BASEBLOCK*)curpos; curpos += (Ps2MemSize::Base / 4) * sizeof(BASEBLOCK); recROM = (BASEBLOCK*)curpos; curpos += (Ps2MemSize::Rom / 4) * sizeof(BASEBLOCK); recROM1 = (BASEBLOCK*)curpos; curpos += (Ps2MemSize::Rom1 / 4) * sizeof(BASEBLOCK); - recStack = (u8*)curpos; curpos += RECSTACK_SIZE; + recConstBuf = (u32*)curpos; curpos += RECCONSTBUF_SIZE * sizeof(u32); recRAMCopy = (u32*)curpos; if( s_pInstCache == NULL ) @@ -436,8 +456,10 @@ void recResetEE( void ) maxrecmem = 0; - memset_8<0xcc, REC_CACHEMEM>(recMem); // 0xcc is INT3 - memzero_ptr( m_recBlockAlloc ); + if (IsDevBuild) + memset_8<0xcc, REC_CACHEMEM>(recMem); // 0xcc is INT3 + memzero_ptr( m_recBlockAlloc ); // Excluding the 32mb ram copy + memzero_ptr(recConstBuf); memzero_obj( manual_page ); memzero_obj( manual_counter ); ClearRecLUT((BASEBLOCK*)m_recBlockAlloc, @@ -489,7 +511,7 @@ void recResetEE( void ) x86SetPtr(recMem); recPtr = recMem; - recStackPtr = recStack; + recConstBufPtr = recConstBuf; x86FpuState = FPU_STATE; branch = 0; @@ -504,7 +526,7 @@ static void recShutdown( void ) SafeSysMunmap( recMem, REC_CACHEMEM ); safe_aligned_free( m_recBlockAlloc ); recRAM = recROM = recROM1 = NULL; - recStack = NULL; + recConstBuf = NULL; recRAMCopy = NULL; safe_free( s_pInstCache ); @@ -1246,7 +1268,7 @@ void recRecompile( const u32 startpc ) if ( ( (uptr)recPtr - (uptr)recMem ) >= REC_CACHEMEM-0x40000 || dumplog == 0xffffffff) { recResetEE(); } - if ( ( (uptr)recStackPtr - (uptr)recStack ) >= RECSTACK_SIZE-0x100 ) { + if ( (recConstBufPtr - recConstBuf) >= RECCONSTBUF_SIZE - 64 ) { DevCon::WriteLn("EE recompiler stack reset"); recResetEE(); } @@ -1300,7 +1322,6 @@ void recRecompile( const u32 startpc ) // go until the next branch i = startpc; s_nEndBlock = 0xffffffff; - s_nHasDelay = 0; while(1) { BASEBLOCK* pblock = PC_GETBLOCK(i); @@ -1331,7 +1352,6 @@ void recRecompile( const u32 startpc ) case 0: // special if( _Funct_ == 8 || _Funct_ == 9 ) { // JR, JALR s_nEndBlock = i + 8; - s_nHasDelay = 1; goto StartRecomp; } break; @@ -1340,9 +1360,6 @@ void recRecompile( const u32 startpc ) if( _Rt_ < 4 || (_Rt_ >= 16 && _Rt_ < 20) ) { // branches - if( _Rt_ == 2 || _Rt_ == 3 || _Rt_ == 18 || _Rt_ == 19 ) s_nHasDelay = 1; - else s_nHasDelay = 2; - branchTo = _Imm_ * 4 + i + 4; if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; else s_nEndBlock = i+8; @@ -1353,17 +1370,12 @@ void recRecompile( const u32 startpc ) case 2: // J case 3: // JAL - s_nHasDelay = 1; s_nEndBlock = i + 8; goto StartRecomp; // branches case 4: case 5: case 6: case 7: case 20: case 21: case 22: case 23: - - if( (cpuRegs.code >> 26) >= 20 ) s_nHasDelay = 1; - else s_nHasDelay = 2; - branchTo = _Imm_ * 4 + i + 4; if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; else s_nEndBlock = i+8; @@ -1385,9 +1397,6 @@ void recRecompile( const u32 startpc ) if( _Rs_ == 8 ) { // BC1F, BC1T, BC1FL, BC1TL // BC2F, BC2T, BC2FL, BC2TL - if( _Rt_ >= 2 ) s_nHasDelay = 1; - else s_nHasDelay = 2; - branchTo = _Imm_ * 4 + i + 4; if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; else s_nEndBlock = i+8; @@ -1645,7 +1654,7 @@ StartRecomp: } assert( x86Ptr < recMem+REC_CACHEMEM ); - assert( recStackPtr < recStack+RECSTACK_SIZE ); + assert( recConstBufPtr < recConstBuf + RECCONSTBUF_SIZE ); assert( x86FpuState == 0 ); assert(x86Ptr - recPtr < 0x10000); diff --git a/pcsx2/x86/ix86-32/iR5900Arit.cpp b/pcsx2/x86/ix86-32/iR5900Arit.cpp index 2106347b60..90ac00fd46 100644 --- a/pcsx2/x86/ix86-32/iR5900Arit.cpp +++ b/pcsx2/x86/ix86-32/iR5900Arit.cpp @@ -1306,10 +1306,6 @@ void recSLTs_consts(int info, int sign) PSRLQItoR(EEREC_D, 63); } else { - u32* ptempmem = recAllocStackMem(8,4); - ptempmem[0] = g_cpuConstRegs[_Rs_].UL[0]^0x80000000; - ptempmem[1] = 0; - if( EEREC_D != EEREC_T ) { MOVDMtoMMX(EEREC_D, (u32)&s_sltconst); PXORRtoR(EEREC_D, EEREC_T); @@ -1318,7 +1314,7 @@ void recSLTs_consts(int info, int sign) PXORMtoR(EEREC_D, (u32)&s_sltconst); } - PCMPGTDMtoR(EEREC_D, (u32)ptempmem); + PCMPGTDMtoR(EEREC_D, (uptr)recGetImm64(0, g_cpuConstRegs[_Rs_].UL[0] ^ 0x80000000)); PUNPCKLDQRtoR(EEREC_D, EEREC_D); PSRLQItoR(EEREC_D, 63); @@ -1439,11 +1435,7 @@ void recSLTs_constt(int info, int sign) recSLTmemconstt(EEREC_D, EEREC_S, (u32)_eeGetConstReg(_Rt_), 1); } else { - u32* ptempmem = recAllocStackMem(8,4); - ptempmem[0] = g_cpuConstRegs[_Rt_].UL[0]^0x80000000; - ptempmem[1] = 0; - - recSLTmemconstt(EEREC_D, EEREC_S, (u32)ptempmem, 0); + recSLTmemconstt(EEREC_D, EEREC_S, (uptr)recGetImm64(0, g_cpuConstRegs[_Rt_].UL[0] ^ 0x80000000), 0); } return; diff --git a/pcsx2/x86/ix86-32/iR5900AritImm.cpp b/pcsx2/x86/ix86-32/iR5900AritImm.cpp index 7ae89bfe0a..5cb828d561 100644 --- a/pcsx2/x86/ix86-32/iR5900AritImm.cpp +++ b/pcsx2/x86/ix86-32/iR5900AritImm.cpp @@ -63,13 +63,8 @@ void recADDI_(int info) if ( info & PROCESS_EE_MMX ) { if ( _Imm_ != 0 ) { - - u32* ptempmem = recAllocStackMem(8, 8); - ptempmem[0] = (s32)_Imm_; - ptempmem[1] = 0; - if ( EEREC_T != EEREC_S ) MOVQRtoR(EEREC_T, EEREC_S); - PADDDMtoR(EEREC_T, (u32)ptempmem); + PADDDMtoR(EEREC_T, (uptr)recGetImm64(0, _Imm_)); if ( EEINST_ISLIVE1(_Rt_) ) _signExtendGPRtoMMX(EEREC_T, _Rt_, 0); else EEINST_RESETHASLIVE1(_Rt_); } @@ -89,12 +84,8 @@ void recADDI_(int info) SetMMXstate(); if ( _Imm_ != 0 ) { - u32* ptempmem = recAllocStackMem(8, 8); - ptempmem[0] = (s32)_Imm_; - ptempmem[1] = 0; - MOVDMtoMMX(rtreg, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]); - PADDDMtoR(rtreg, (u32)ptempmem); + PADDDMtoR(rtreg, (uptr)recGetImm64(0, _Imm_)); if ( EEINST_ISLIVE1(_Rt_) ) _signExtendGPRtoMMX(rtreg, _Rt_, 0); else EEINST_RESETHASLIVE1(_Rt_); @@ -162,13 +153,8 @@ void recDADDI_(int info) if( info & PROCESS_EE_MMX ) { if( _Imm_ != 0 ) { - - // flush - u32* ptempmem = recAllocStackMem(8, 8); - ptempmem[0] = _Imm_; - ptempmem[1] = _Imm_ >= 0 ? 0 : 0xffffffff; if( EEREC_T != EEREC_S ) MOVQRtoR(EEREC_T, EEREC_S); - PADDQMtoR(EEREC_T, (u32)ptempmem); + PADDQMtoR(EEREC_T, (uptr)recGetImm64(-(_Imm_ < 0), _Imm_)); } else { if( EEREC_T != EEREC_S ) MOVQRtoR(EEREC_T, EEREC_S); @@ -178,15 +164,12 @@ void recDADDI_(int info) if( (g_pCurInstInfo->regs[_Rt_]&EEINST_MMX) ) { int rtreg; - u32* ptempmem = recAllocStackMem(8, 8); - ptempmem[0] = _Imm_; - ptempmem[1] = _Imm_ >= 0 ? 0 : 0xffffffff; rtreg = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_WRITE); SetMMXstate(); MOVQMtoR(rtreg, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]); - PADDQMtoR(rtreg, (u32)ptempmem); + PADDQMtoR(rtreg, (uptr)recGetImm64(-(_Imm_ < 0), _Imm_)); } else { if( _Rt_ == _Rs_ ) { @@ -239,10 +222,7 @@ void recSLTIU_(int info) { if( info & PROCESS_EE_MMX ) { if( EEINST_ISSIGNEXT(_Rs_) ) { - u32* ptempmem = recAllocStackMem(8,4); - ptempmem[0] = ((s32)(_Imm_))^0x80000000; - ptempmem[1] = 0; - recSLTmemconstt(EEREC_T, EEREC_S, (u32)ptempmem, 0); + recSLTmemconstt(EEREC_T, EEREC_S, (uptr)recGetImm64(0, ((s32)_Imm_)^0x80000000), 0); EEINST_SETSIGNEXT(_Rt_); return; } @@ -292,10 +272,7 @@ void recSLTI_(int info) if( info & PROCESS_EE_MMX) { if( EEINST_ISSIGNEXT(_Rs_) ) { - u32* ptempmem = recAllocStackMem(8,4); - ptempmem[0] = _Imm_; - ptempmem[1] = 0; - recSLTmemconstt(EEREC_T, EEREC_S, (u32)ptempmem, 1); + recSLTmemconstt(EEREC_T, EEREC_S, (uptr)recGetImm64(0, _Imm_), 1); EEINST_SETSIGNEXT(_Rt_); return; } @@ -347,12 +324,8 @@ void recLogicalOpI(int info, int op) SetMMXstate(); if( _ImmU_ != 0 ) { - u32* ptempmem = recAllocStackMem(8, 8); - ptempmem[0] = _ImmU_; - ptempmem[1] = 0; - if( EEREC_T != EEREC_S ) MOVQRtoR(EEREC_T, EEREC_S); - LogicalOpMtoR(EEREC_T, (u32)ptempmem, op); + LogicalOpMtoR(EEREC_T, (uptr)recGetImm64(0, _ImmU_), op); } else { if( op == 0 ) PXORRtoR(EEREC_T, EEREC_T); @@ -367,21 +340,15 @@ void recLogicalOpI(int info, int op) if( op == 0 ) { if ( _ImmU_ != 0 ) { - u32* ptempmem = recAllocStackMem(8, 8); - ptempmem[0] = _ImmU_; - ptempmem[1] = 0; MOVDMtoMMX(rtreg, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]); - PANDMtoR(rtreg, (u32)ptempmem); + PANDMtoR(rtreg, (uptr)recGetImm64(0, _ImmU_)); } else PXORRtoR(rtreg, rtreg); } else { MOVQMtoR(rtreg, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ]); if ( _ImmU_ != 0 ) { - u32* ptempmem = recAllocStackMem(8, 8); - ptempmem[0] = _ImmU_; - ptempmem[1] = 0; - LogicalOpMtoR(rtreg, (u32)ptempmem, op); + LogicalOpMtoR(rtreg, (uptr)recGetImm64(0, _ImmU_), op); } } } diff --git a/pcsx2/x86/ix86-32/iR5900Move.cpp b/pcsx2/x86/ix86-32/iR5900Move.cpp index 0d1878e26b..b2ac05f58f 100644 --- a/pcsx2/x86/ix86-32/iR5900Move.cpp +++ b/pcsx2/x86/ix86-32/iR5900Move.cpp @@ -442,15 +442,12 @@ void recMOVZtemp_consts(int info) CMP8ItoR(EAX, 0xff); j8Ptr[ 0 ] = JNE8( 0 ); - if( g_cpuFlushedConstReg & (1<<_Rs_) ) mem = &cpuRegs.GPR.r[_Rs_].UL[0]; - else { - mem = recAllocStackMem(8,8); + if( g_cpuFlushedConstReg & (1<<_Rs_) ) + mem = &cpuRegs.GPR.r[_Rs_].UL[0]; + else + mem = recGetImm64(g_cpuConstRegs[_Rs_].UL[1], g_cpuConstRegs[_Rs_].UL[0]); - mem[0] = g_cpuConstRegs[_Rs_].UL[0]; - mem[1] = g_cpuConstRegs[_Rs_].UL[1]; - } - - MOVQMtoR(EEREC_D, (u32)mem); + MOVQMtoR(EEREC_D, (uptr)mem); x86SetJ8( j8Ptr[ 0 ] ); _freeMMXreg(t0reg); @@ -566,15 +563,12 @@ void recMOVNtemp_consts(int info) CMP8ItoR(EAX, 0xff); j8Ptr[ 0 ] = JE8( 0 ); - if( g_cpuFlushedConstReg & (1<<_Rs_) ) mem = &cpuRegs.GPR.r[_Rs_].UL[0]; - else { - mem = recAllocStackMem(8,8); + if( g_cpuFlushedConstReg & (1<<_Rs_) ) + mem = &cpuRegs.GPR.r[_Rs_].UL[0]; + else + mem = recGetImm64(g_cpuConstRegs[_Rs_].UL[1], g_cpuConstRegs[_Rs_].UL[0]); - mem[0] = g_cpuConstRegs[_Rs_].UL[0]; - mem[1] = g_cpuConstRegs[_Rs_].UL[1]; - } - - MOVQMtoR(EEREC_D, (u32)mem); + MOVQMtoR(EEREC_D, (uptr)mem); x86SetJ8( j8Ptr[ 0 ] ); _freeMMXreg(t0reg); diff --git a/pcsx2/x86/ix86-32/iR5900MultDiv.cpp b/pcsx2/x86/ix86-32/iR5900MultDiv.cpp index 95917a74d2..ec549f24c2 100644 --- a/pcsx2/x86/ix86-32/iR5900MultDiv.cpp +++ b/pcsx2/x86/ix86-32/iR5900MultDiv.cpp @@ -266,20 +266,15 @@ void recWritebackConstHILO(u64 res, int writed, int upper) if( g_pCurInstInfo->regs[XMMGPR_LO] & testlive ) { if( !upper && (reglo = _allocCheckGPRtoMMX(g_pCurInstInfo, XMMGPR_LO, MODE_WRITE)) >= 0 ) { - u32* ptr = recAllocStackMem(8, 8); - ptr[0] = res & 0xffffffff; - ptr[1] = (res&0x80000000)?0xffffffff:0; - MOVQMtoR(reglo, (u32)ptr); + MOVQMtoR(reglo, (uptr)recGetImm64(res & 0x80000000 ? -1 : 0, (u32)res)); } else { reglo = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_LO, MODE_WRITE|MODE_READ); if( reglo >= 0 ) { - u32* ptr = recAllocStackMem(8, 8); - ptr[0] = res & 0xffffffff; - ptr[1] = (res&0x80000000)?0xffffffff:0; - if( upper ) SSE_MOVHPS_M64_to_XMM(reglo, (u32)ptr); - else SSE_MOVLPS_M64_to_XMM(reglo, (u32)ptr); + u32* ptr = recGetImm64(res & 0x80000000 ? -1 : 0, (u32)res); + if( upper ) SSE_MOVHPS_M64_to_XMM(reglo, (uptr)ptr); + else SSE_MOVLPS_M64_to_XMM(reglo, (uptr)ptr); } else { MOV32ItoM(loaddr, res & 0xffffffff); @@ -291,18 +286,13 @@ void recWritebackConstHILO(u64 res, int writed, int upper) if( g_pCurInstInfo->regs[XMMGPR_HI] & testlive ) { if( !upper && (reghi = _allocCheckGPRtoMMX(g_pCurInstInfo, XMMGPR_HI, MODE_WRITE)) >= 0 ) { - u32* ptr = recAllocStackMem(8, 8); - ptr[0] = res >> 32; - ptr[1] = (res>>63)?0xffffffff:0; - MOVQMtoR(reghi, (u32)ptr); + MOVQMtoR(reghi, (uptr)recGetImm64(res >> 63 ? -1 : 0, res >> 32)); } else { reghi = _allocCheckGPRtoXMM(g_pCurInstInfo, XMMGPR_HI, MODE_WRITE|MODE_READ); if( reghi >= 0 ) { - u32* ptr = recAllocStackMem(8, 8); - ptr[0] = res >> 32; - ptr[1] = (res>>63)?0xffffffff:0; + u32* ptr = recGetImm64(res >> 63 ? -1 : 0, res >> 32); if( upper ) SSE_MOVHPS_M64_to_XMM(reghi, (u32)ptr); else SSE_MOVLPS_M64_to_XMM(reghi, (u32)ptr); } diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index d62eb6b963..404e725775 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -50,6 +50,7 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) { mVU->prog.max = mMaxProg - 1; mVU->prog.prog = (microProgram*)_aligned_malloc(sizeof(microProgram)*(mVU->prog.max+1), 64); mVU->prog.progList = new int[mMaxProg]; + mVU->regAlloc = new microRegAlloc(mVU->regs); mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init"); mVU->cache = SysMmapEx((vuIndex ? 0x5f240000 : 0x5e240000), mVU->cacheSize + 0x1000, 0, (vuIndex ? "Micro VU1" : "Micro VU0")); @@ -107,12 +108,13 @@ microVUt(void) mVUclose(mV) { if (mVU->prog.prog) { for (int i = 0; i <= mVU->prog.max; i++) { for (u32 j = 0; j < (mVU->progSize / 2); j++) { - microBlockManager::Delete(mVU->prog.prog[i].block[j]); + safe_delete(mVU->prog.prog[i].block[j]); } } safe_aligned_free(mVU->prog.prog); } safe_delete_array(mVU->prog.progList); + safe_delete(mVU->regAlloc); } // Clears Block Data in specified range @@ -139,7 +141,7 @@ microVUf(void) mVUclearProg(int progIndex) { mVUprogI.ranges.total = -1; } for (u32 i = 0; i < (mVU->progSize / 2); i++) { - microBlockManager::Delete(mVUprogI.block[i]); + safe_delete(mVUprogI.block[i]); } } diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h index 5fa6797bfe..39c6ec925c 100644 --- a/pcsx2/x86/microVU.h +++ b/pcsx2/x86/microVU.h @@ -39,12 +39,6 @@ private: int listI; public: - // Use instead of normal 'delete' - static void Delete(microBlockManager* &dead) { - if (!dead) return; - dead->~microBlockManager(); - safe_delete(dead); - } microBlockManager() { listI = -1; blockList.block = NULL; @@ -121,7 +115,7 @@ struct microProgram { #define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...) struct microProgManager { - microIR allocInfo; // IR information + microIR IRinfo; // IR information microProgram* prog; // Store MicroPrograms in memory int* progList; // List of program indexes ordered by age (ordered from newest to oldest) int max; // Max Number of MicroPrograms minus 1 @@ -150,7 +144,8 @@ struct microVU { u32 progSize; // VU Micro Memory Size (in u32's) u32 cacheSize; // VU Cache Size - microProgManager prog; // Micro Program Data + microProgManager prog; // Micro Program Data + microRegAlloc* regAlloc; // Reg Alloc Class FILE* logFile; // Log File Pointer VURegs* regs; // VU Regs Struct diff --git a/pcsx2/x86/microVU_Alloc.inl b/pcsx2/x86/microVU_Alloc.inl index 61fd7c593a..56fbdeea2c 100644 --- a/pcsx2/x86/microVU_Alloc.inl +++ b/pcsx2/x86/microVU_Alloc.inl @@ -22,614 +22,6 @@ // Micro VU - Pass 2 Functions //------------------------------------------------------------------ -//------------------------------------------------------------------ -// FMAC1 - Normal FMAC Opcodes -//------------------------------------------------------------------ - -#define getReg(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, _X_Y_Z_W); \ -} - -#define getZero(reg) { \ - if (_W) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], _X_Y_Z_W); } \ - else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ -} - -#define getReg6(reg, _reg_) { \ - if (!_reg_) { getZero(reg); } \ - else { getReg(reg, _reg_); } \ -} - -microVUt(void) mVUallocFMAC1a(mV, int& Fd, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmFs; - getReg6(Fs, _Fs_); - if (_Ft_ == _Fs_) { Ft = Fs; } - else { getReg6(Ft, _Ft_); } -} - -microVUt(void) mVUallocFMAC1b(mV, int& Fd) { - if (!_Fd_) return; - if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmT1, _X_Y_Z_W); - mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 1); -} - -//------------------------------------------------------------------ -// FMAC2 - ABS/FTOI/ITOF Opcodes -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC2a(mV, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFs; - getReg6(Fs, _Fs_); -} - -microVUt(void) mVUallocFMAC2b(mV, int& Ft) { - if (!_Ft_) return; - //if (CHECK_VU_OVERFLOW) mVUclamp1(Ft, xmmT1, _X_Y_Z_W); - mVUsaveReg(Ft, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W, 1); -} - -//------------------------------------------------------------------ -// FMAC3 - BC(xyzw) FMAC Opcodes -//------------------------------------------------------------------ - -#define getReg3SS(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _bc_))); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, (1 << (3 - _bc_))); \ -} - -#define getReg3(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _bc_))); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, (1 << (3 - _bc_))); \ - mVUunpack_xyzw(reg, reg, 0); \ -} - -#define getZero3SS(reg) { \ - if (_bc_w) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], 1); } \ - else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ -} - -#define getZero3(reg) { \ - if (_bc_w) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], 1); \ - mVUunpack_xyzw(reg, reg, 0); \ - } \ - else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ -} - -microVUt(void) mVUallocFMAC3a(mV, int& Fd, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmFs; - if (_XYZW_SS) { - getReg6(Fs, _Fs_); - if ( (_Ft_ == _Fs_) && ((_X && _bc_x) || (_Y && _bc_y) || (_Z && _bc_z) || (_W && _bc_w)) ) { - Ft = Fs; - } - else if (!_Ft_) { getZero3SS(Ft); } - else { getReg3SS(Ft, _Ft_); } - } - else { - getReg6(Fs, _Fs_); - if (!_Ft_) { getZero3(Ft); } - else { getReg3(Ft, _Ft_); } - } -} - -microVUt(void) mVUallocFMAC3b(mV, int& Fd) { - mVUallocFMAC1b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC4 - FMAC Opcodes Storing Result to ACC -//------------------------------------------------------------------ - -#define getReg4(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _xyzw_ACC); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, _xyzw_ACC); \ -} - -#define getZero4(reg) { \ - if (_W) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], _xyzw_ACC); } \ - else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ -} - -microVUt(void) mVUallocFMAC4a(mV, int& ACC, int& Fs, int& Ft) { - ACC = xmmACC; - Fs = (_X_Y_Z_W == 15) ? xmmACC : xmmFs; - Ft = xmmFt; - if (_X_Y_Z_W == 8) { - getReg6(Fs, _Fs_); - if (_Ft_ == _Fs_) { Ft = Fs; } - else { getReg6(Ft, _Ft_); } - } - else { - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (_Ft_ == _Fs_) { Ft = Fs; } - else if (!_Ft_) { getZero4(Ft); } - else { getReg4(Ft, _Ft_); } - } -} - -microVUt(void) mVUallocFMAC4b(mV, int& ACC, int& Fs) { - if (CHECK_VU_OVERFLOW) mVUclamp1(Fs, xmmT1, _xyzw_ACC); - mVUmergeRegs(ACC, Fs, _X_Y_Z_W); -} - -//------------------------------------------------------------------ -// FMAC5 - FMAC BC(xyzw) Opcodes Storing Result to ACC -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC5a(mV, int& ACC, int& Fs, int& Ft) { - ACC = xmmACC; - Fs = (_X_Y_Z_W == 15) ? xmmACC : xmmFs; - Ft = xmmFt; - if (_X_Y_Z_W == 8) { - getReg6(Fs, _Fs_); - if ((_Ft_ == _Fs_) && _bc_x) { Ft = Fs; } - else if (!_Ft_) { getZero3SS(Ft); } - else { getReg3SS(Ft, _Ft_); } - } - else { - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (!_Ft_) { getZero3(Ft); } - else { getReg3(Ft, _Ft_); } - } -} - -microVUt(void) mVUallocFMAC5b(mV, int& ACC, int& Fs) { - mVUallocFMAC4b(mVU, ACC, Fs); -} - -//------------------------------------------------------------------ -// FMAC6 - Normal FMAC Opcodes (I Reg) -//------------------------------------------------------------------ - -#define getIreg(reg, modXYZW) { \ - MOV32MtoR(gprT1, (uptr)&mVU->regs->VI[REG_I].UL); \ - SSE2_MOVD_R_to_XMM(reg, gprT1); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, 8); \ - if (!((_XYZW_SS && modXYZW) || (_X_Y_Z_W == 8))) { mVUunpack_xyzw(reg, reg, 0); } \ -} - -microVUt(void) mVUallocFMAC6a(mV, int& Fd, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmFs; - getIreg(Ft, 1); - getReg6(Fs, _Fs_); -} - -microVUt(void) mVUallocFMAC6b(mV, int& Fd) { - mVUallocFMAC1b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC7 - FMAC Opcodes Storing Result to ACC (I Reg) -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC7a(mV, int& ACC, int& Fs, int& Ft) { - ACC = xmmACC; - Fs = (_X_Y_Z_W == 15) ? xmmACC : xmmFs; - Ft = xmmFt; - getIreg(Ft, 0); - if (_X_Y_Z_W == 8) { getReg6(Fs, _Fs_); } - else if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } -} - -microVUt(void) mVUallocFMAC7b(mV, int& ACC, int& Fs) { - mVUallocFMAC4b(mVU, ACC, Fs); -} - -//------------------------------------------------------------------ -// FMAC8 - MADD FMAC Opcode Storing Result to Fd -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC8a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmFs; - ACC = xmmACC; - if (_X_Y_Z_W == 8) { - getReg6(Fs, _Fs_); - if (_Ft_ == _Fs_) { Ft = Fs; } - else { getReg6(Ft, _Ft_); } - } - else { - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (_Ft_ == _Fs_) { Ft = Fs; } - else if (!_Ft_) { getZero4(Ft); } - else { getReg4(Ft, _Ft_); } - } -} - -microVUt(void) mVUallocFMAC8b(mV, int& Fd) { - if (!_Fd_) return; - if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmT1, _xyzw_ACC); - mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 0); -} - -//------------------------------------------------------------------ -// FMAC9 - MSUB FMAC Opcode Storing Result to Fd -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC9a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmT1; - ACC = xmmT1; - if (_X_Y_Z_W == 8) { - getReg6(Fs, _Fs_); - if (_Ft_ == _Fs_) { Ft = Fs; } - else { getReg6(Ft, _Ft_); } - } - else { - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (_Ft_ == _Fs_) { Ft = Fs; } - else if (!_Ft_) { getZero4(Ft); } - else { getReg4(Ft, _Ft_); } - } - SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); -} - -microVUt(void) mVUallocFMAC9b(mV, int& Fd) { - if (!_Fd_) return; - if (CHECK_VU_OVERFLOW) mVUclamp1(Fd, xmmFt, _xyzw_ACC); - mVUsaveReg(Fd, (uptr)&mVU->regs->VF[_Fd_].UL[0], _X_Y_Z_W, 0); -} - -//------------------------------------------------------------------ -// FMAC10 - MADD FMAC BC(xyzw) Opcode Storing Result to Fd -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC10a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmFs; - ACC = xmmACC; - if (_X_Y_Z_W == 8) { - getReg6(Fs, _Fs_); - if ( (_Ft_ == _Fs_) && _bc_x) { Ft = Fs; } - else if (!_Ft_) { getZero3SS(Ft); } - else { getReg3SS(Ft, _Ft_); } - } - else { - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (!_Ft_) { getZero3(Ft); } - else { getReg3(Ft, _Ft_); } - } -} - -microVUt(void) mVUallocFMAC10b(mV, int& Fd) { - mVUallocFMAC8b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC11 - MSUB FMAC BC(xyzw) Opcode Storing Result to Fd -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC11a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmT1; - ACC = xmmT1; - if (_X_Y_Z_W == 8) { - getReg6(Fs, _Fs_); - if ( (_Ft_ == _Fs_) && _bc_x) { Ft = Fs; } - else if (!_Ft_) { getZero3SS(Ft); } - else { getReg3SS(Ft, _Ft_); } - } - else { - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (!_Ft_) { getZero3(Ft); } - else { getReg3(Ft, _Ft_); } - } - SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); -} - -microVUt(void) mVUallocFMAC11b(mV, int& Fd) { - mVUallocFMAC9b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC12 - MADD FMAC Opcode Storing Result to Fd (I Reg) -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC12a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmFs; - ACC = xmmACC; - getIreg(Ft, 0); - if (_X_Y_Z_W == 8) { getReg6(Fs, _Fs_); } - else if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } -} - -microVUt(void) mVUallocFMAC12b(mV, int& Fd) { - mVUallocFMAC8b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC13 - MSUB FMAC Opcode Storing Result to Fd (I Reg) -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC13a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmT1; - ACC = xmmT1; - getIreg(Ft, 0); - if (_X_Y_Z_W == 8) { getReg6(Fs, _Fs_); } - else if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); -} - -microVUt(void) mVUallocFMAC13b(mV, int& Fd) { - mVUallocFMAC9b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC14 - MADDA/MSUBA FMAC Opcodes -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC14a(mV, int& ACCw, int& ACCr, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - ACCw = xmmACC; - ACCr = ((_X_Y_Z_W == 15) || (_X_Y_Z_W == 8)) ? xmmACC : xmmT1; - - if (_X_Y_Z_W == 8) { - getReg6(Fs, _Fs_); - if (_Ft_ == _Fs_) { Ft = Fs; } - else { getReg6(Ft, _Ft_); } - } - else { - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (_Ft_ == _Fs_) { Ft = Fs; } - else if (!_Ft_) { getZero4(Ft); } - else { getReg4(Ft, _Ft_); } - } - SSE_MOVAPS_XMM_to_XMM(ACCr, xmmACC); -} - -microVUt(void) mVUallocFMAC14b(mV, int& ACCw, int& ACCr) { - if (CHECK_VU_OVERFLOW) mVUclamp1(ACCr, xmmFt, _xyzw_ACC); - mVUmergeRegs(ACCw, ACCr, _X_Y_Z_W); -} - -//------------------------------------------------------------------ -// FMAC15 - MADDA/MSUBA BC(xyzw) FMAC Opcode -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC15a(mV, int& ACCw, int& ACCr, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - ACCw = xmmACC; - ACCr = ((_X_Y_Z_W == 15) || (_X_Y_Z_W == 8)) ? xmmACC : xmmT1; - - if (_X_Y_Z_W == 8) { - getReg6(Fs, _Fs_); - if ((_Ft_ == _Fs_) && _bc_x) { Ft = Fs; } - else if (!_Ft_) { getZero3SS(Ft); } - else { getReg3SS(Ft, _Ft_); } - } - else { - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (!_Ft_) { getZero3(Ft); } - else { getReg3(Ft, _Ft_); } - } - SSE_MOVAPS_XMM_to_XMM(ACCr, xmmACC); -} - -microVUt(void) mVUallocFMAC15b(mV, int& ACCw, int& ACCr) { - mVUallocFMAC14b(mVU, ACCw, ACCr); -} - -//------------------------------------------------------------------ -// FMAC16 - MADDA/MSUBA FMAC Opcode (I Reg) -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC16a(mV, int& ACCw, int& ACCr, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - ACCw = xmmACC; - ACCr = ((_X_Y_Z_W == 15) || (_X_Y_Z_W == 8)) ? xmmACC : xmmT1; - getIreg(Ft, 0); - if (_X_Y_Z_W == 8) { getReg6(Fs, _Fs_); } - else if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - SSE_MOVAPS_XMM_to_XMM(ACCr, xmmACC); -} - -microVUt(void) mVUallocFMAC16b(mV, int& ACCw, int& ACCr) { - mVUallocFMAC14b(mVU, ACCw, ACCr); -} - -//------------------------------------------------------------------ -// FMAC17 - CLIP FMAC Opcode -//------------------------------------------------------------------ - -#define getReg9(reg, _reg_) { \ - mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], 1); \ - if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, 1); \ - mVUunpack_xyzw(reg, reg, 0); \ -} - -microVUt(void) mVUallocFMAC17a(mV, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - getReg6(Fs, _Fs_); - getReg9(Ft, _Ft_); -} - -//------------------------------------------------------------------ -// FMAC18 - OPMULA FMAC Opcode -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC18a(mV, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - ACC = xmmACC; - - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (!_Ft_) { getZero4(Ft); } - else { getReg4(Ft, _Ft_); } - - SSE2_PSHUFD_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY - SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ -} - -microVUt(void) mVUallocFMAC18b(mV, int& ACC, int& Fs) { - mVUallocFMAC4b(mVU, ACC, Fs); -} - -//------------------------------------------------------------------ -// FMAC19 - OPMSUB FMAC Opcode -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC19a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmT1; - ACC = xmmT1; - - if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - - if (!_Ft_) { getZero4(Ft); } - else { getReg4(Ft, _Ft_); } - - SSE2_PSHUFD_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY - SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ - SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); -} - -microVUt(void) mVUallocFMAC19b(mV, int& Fd) { - mVUallocFMAC9b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC22 - Normal FMAC Opcodes (Q Reg) -//------------------------------------------------------------------ - -#define getQreg(reg) { \ - mVUunpack_xyzw(reg, xmmPQ, mVUinfo.readQ); \ - /*if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 15);*/ \ -} - -microVUt(void) mVUallocFMAC22a(mV, int& Fd, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmFs; - getQreg(Ft); - getReg6(Fs, _Fs_); -} - -microVUt(void) mVUallocFMAC22b(mV, int& Fd) { - mVUallocFMAC1b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC23 - FMAC Opcodes Storing Result to ACC (Q Reg) -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC23a(mV, int& ACC, int& Fs, int& Ft) { - ACC = xmmACC; - Fs = (_X_Y_Z_W == 15) ? xmmACC : xmmFs; - Ft = xmmFt; - getQreg(Ft); - if (_X_Y_Z_W == 8) { getReg6(Fs, _Fs_); } - else if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } -} - -microVUt(void) mVUallocFMAC23b(mV, int& ACC, int& Fs) { - mVUallocFMAC4b(mVU, ACC, Fs); -} - -//------------------------------------------------------------------ -// FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg) -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC24a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmFs; - ACC = xmmACC; - getQreg(Ft); - if (_X_Y_Z_W == 8) { getReg6(Fs, _Fs_); } - else if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } -} - -microVUt(void) mVUallocFMAC24b(mV, int& Fd) { - mVUallocFMAC8b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC25 - MSUB FMAC Opcode Storing Result to Fd (Q Reg) -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC25a(mV, int& Fd, int& ACC, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - Fd = xmmT1; - ACC = xmmT1; - getQreg(Ft); - if (_X_Y_Z_W == 8) { getReg6(Fs, _Fs_); } - else if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC); -} - -microVUt(void) mVUallocFMAC25b(mV, int& Fd) { - mVUallocFMAC9b(mVU, Fd); -} - -//------------------------------------------------------------------ -// FMAC26 - MADDA/MSUBA FMAC Opcode (Q Reg) -//------------------------------------------------------------------ - -microVUt(void) mVUallocFMAC26a(mV, int& ACCw, int& ACCr, int& Fs, int& Ft) { - Fs = xmmFs; - Ft = xmmFt; - ACCw = xmmACC; - ACCr = ((_X_Y_Z_W == 15) || (_X_Y_Z_W == 8)) ? xmmACC : xmmT1; - getQreg(Ft); - if (_X_Y_Z_W == 8) { getReg6(Fs, _Fs_); } - else if (!_Fs_) { getZero4(Fs); } - else { getReg4(Fs, _Fs_); } - SSE_MOVAPS_XMM_to_XMM(ACCr, xmmACC); -} - -microVUt(void) mVUallocFMAC26b(mV, int& ACCw, int& ACCr) { - mVUallocFMAC14b(mVU, ACCw, ACCr); -} - //------------------------------------------------------------------ // Flag Allocators //------------------------------------------------------------------ @@ -707,9 +99,8 @@ microVUt(void) mVUallocCFLAGb(mV, int reg, int fInstance) { //------------------------------------------------------------------ microVUt(void) mVUallocVIa(mV, int GPRreg, int _reg_) { - if (!_reg_) { XOR32RtoR(GPRreg, GPRreg); } - else if (isMMX(_reg_)) { MOVD32MMXtoR(GPRreg, mmVI(_reg_)); } - else { MOVZX32Rm16toR(GPRreg, gprR, (_reg_ - 9) * 16); } + if (!_reg_) { XOR32RtoR(GPRreg, GPRreg); } + else { MOVZX32Rm16toR(GPRreg, gprR, (_reg_ - 9) * 16); } } microVUt(void) mVUallocVIb(mV, int GPRreg, int _reg_) { @@ -718,15 +109,26 @@ microVUt(void) mVUallocVIb(mV, int GPRreg, int _reg_) { MOV32RtoM((uptr)&mVU->VIbackup, gprR); MOV32ItoR(gprR, Roffset); } - if (_reg_ == 0) { return; } - else if (isMMX(_reg_)) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); } - else if (_reg_ < 16) { MOV16RtoRm(gprR, GPRreg, (_reg_ - 9) * 16); } + if (_reg_ == 0) { return; } + else if (_reg_ < 16) { MOV16RtoRm(gprR, GPRreg, (_reg_ - 9) * 16); } } //------------------------------------------------------------------ -// P Reg Allocator +// I/Q/P Reg Allocators //------------------------------------------------------------------ +#define getIreg(reg, modXYZW) { \ + MOV32MtoR(gprT1, (uptr)&mVU->regs->VI[REG_I].UL); \ + SSE2_MOVD_R_to_XMM(reg, gprT1); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, 8); \ + if (!((_XYZW_SS && modXYZW) || (_X_Y_Z_W == 8))) { mVUunpack_xyzw(reg, reg, 0); } \ +} + +#define getQreg(reg) { \ + mVUunpack_xyzw(reg, xmmPQ, mVUinfo.readQ); \ + /*if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 15);*/ \ +} + #define getPreg(reg) { \ mVUunpack_xyzw(reg, xmmPQ, (2 + mVUinfo.readP)); \ /*if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT1, 15);*/ \ @@ -736,6 +138,21 @@ microVUt(void) mVUallocVIb(mV, int GPRreg, int _reg_) { // Lower Instruction Allocator Helpers //------------------------------------------------------------------ +#define getReg(reg, _reg_) { \ + mVUloadReg(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); \ + if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2(reg, xmmT2, _X_Y_Z_W); \ +} + +#define getZero(reg) { \ + if (_W) { mVUloadReg(reg, (uptr)&mVU->regs->VF[0].UL[0], _X_Y_Z_W); } \ + else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ +} + +#define getReg6(reg, _reg_) { \ + if (!_reg_) { getZero(reg); } \ + else { getReg(reg, _reg_); } \ +} + #define getReg5(reg, _reg_, _fxf_) { \ if (!_reg_) { \ if (_fxf_ < 3) { SSE_XORPS_XMM_to_XMM(reg, reg); } \ diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index 74980bf408..46b43b95f9 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -174,6 +174,9 @@ microVUt(void) mVUsetupBranch(mV, int* xStatus, int* xMac, int* xClip, int xCycl // Shuffle P/Q regs since every block starts at instance #0 if (mVU->p || mVU->q) { SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, shufflePQ); } + + // Flush Allocated Regs + mVU->regAlloc->flushAll(); } microVUt(void) mVUincCycles(mV, int x) { @@ -367,6 +370,9 @@ microVUr(void*) mVUcompile(microVU* mVU, u32 startPC, uptr pState) { // Setup Program Bounds/Range mVUsetupRange(mVU, startPC, 1); + + // Reset regAlloc + mVU->regAlloc->reset(); // First Pass iPC = startPC / 4; @@ -512,8 +518,8 @@ microVUr(void*) mVUcompile(microVU* mVU, u32 startPC, uptr pState) { // Check if branch-block has already been compiled blockCreate(branchAddr/8); pBlock = mVUblocks[branchAddr/8]->search((microRegInfo*)&mVUregs); - if (pBlock) { xJMP( pBlock->x86ptrStart ); } - else { mVUblockFetch(mVU, branchAddr, (uptr)&mVUregs); } + if (pBlock) { xJMP( pBlock->x86ptrStart ); } + else { mVUblockFetch(mVU, branchAddr, (uptr)&mVUregs); } } else { uptr jumpAddr; diff --git a/pcsx2/x86/microVU_Execute.inl b/pcsx2/x86/microVU_Execute.inl index f9463dee9f..bfb2586174 100644 --- a/pcsx2/x86/microVU_Execute.inl +++ b/pcsx2/x86/microVU_Execute.inl @@ -68,17 +68,11 @@ void mVUdispatcherA(mV) { SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0); SSE_MOVAPS_XMM_to_M128((uptr)mVU->clipFlag, xmmT1); - SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]); - SSE_MOVAPS_M128_to_XMM(xmmMax, (uptr)mVU_maxvals); - SSE_MOVAPS_M128_to_XMM(xmmMin, (uptr)mVU_minvals); + //SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]); SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_P].UL); SSE_MOVAPS_M128_to_XMM(xmmPQ, (uptr)&mVU->regs->VI[REG_Q].UL); SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmT1, 0); // wzyx = PPQQ - for (int i = 1; i < 16; i++) { - if (isMMX(i)) { MOVQMtoR(mmVI(i), (uptr)&mVU->regs->VI[i].UL); } - } - // Jump to Recompiled Code Block JMPR(EAX); } @@ -91,11 +85,7 @@ void mVUdispatcherB(mV) { SSE_LDMXCSR((uptr)&g_sseMXCSR); // Save Regs (Other Regs Saved in mVUcompile) - SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC); - - for (int i = 1; i < 16; i++) { - if (isMMX(i)) { MOVDMMXtoM((uptr)&mVU->regs->VI[i].UL, mmVI(i)); } - } + //SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC); // __fastcall = The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left. if (!isVU1) { CALLFunc((uptr)mVUcleanUpVU0); } @@ -107,7 +97,6 @@ void mVUdispatcherB(mV) { POP32R(EBP); POP32R(EBX); - if (isMMX(1)) EMMS(); RET(); mVUcacheCheck(x86Ptr, mVU->cache, 0x1000); diff --git a/pcsx2/x86/microVU_IR.h b/pcsx2/x86/microVU_IR.h index 2d1beaf49c..7e0ba4e85e 100644 --- a/pcsx2/x86/microVU_IR.h +++ b/pcsx2/x86/microVU_IR.h @@ -156,3 +156,167 @@ struct microIR { u32 startPC; // Start PC for Cur Block u32 sFlagHack; // Optimize out all Status flag updates if microProgram doesn't use Status flags }; + +//------------------------------------------------------------------ +// Reg Alloc +//------------------------------------------------------------------ + +void mVUmergeRegs(int dest, int src, int xyzw, bool modXYZW); +void mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW); +void mVUloadReg(int reg, uptr offset, int xyzw); + +struct microXMM { + int reg; // VF Reg Number Stored (-1 = Temp; 0 = vf0 and will not be written back; 32 = ACC) + int xyzw; // xyzw to write back (0 = Don't write back anything AND cached vfReg has all vectors valid) + int count; // Count of when last used + bool isNeeded; // Is needed for current instruction +}; + +#define xmmTotal 7 // Don't allocate PQ? +class microRegAlloc { +private: + microXMM xmmReg[xmmTotal]; + VURegs* vuRegs; + int counter; + int findFreeRegRec(int startIdx) { + for (int i = startIdx; i < xmmTotal; i++) { + if (!xmmReg[i].isNeeded) { + if ((i+1) >= xmmTotal) return i; + int x = findFreeRegRec(i+1); + if (x == -1) return i; + return ((xmmReg[i].count < xmmReg[x].count) ? i : x); + } + } + return -1; + } + int findFreeReg() { + for (int i = 0; i < xmmTotal; i++) { + if (!xmmReg[i].isNeeded && (xmmReg[i].reg < 0)) { + return i; // Reg is not needed and was a temp reg + } + } + int x = findFreeRegRec(0); + if (x < 0) { DevCon::Error("microVU Allocation Error!"); return 0; } + return x; + } + +public: + microRegAlloc(VURegs* vuRegsPtr) { + vuRegs = vuRegsPtr; + reset(); + } + void reset() { + for (int i = 0; i < xmmTotal; i++) { + clearReg(i); + } + counter = 0; + } + void flushAll() { + for (int i = 0; i < xmmTotal; i++) { + writeBackReg(i); + } + } + void clearReg(int reg) { + xmmReg[reg].reg = -1; + xmmReg[reg].count = 0; + xmmReg[reg].xyzw = 0; + xmmReg[reg].isNeeded = 0; + } + void writeBackReg(int reg) { + if ((xmmReg[reg].reg > 0) && xmmReg[reg].xyzw) { // Reg was modified and not Temp or vf0 + if (xmmReg[reg].reg == 32) mVUsaveReg(reg, (uptr)&vuRegs->ACC.UL[0], xmmReg[reg].xyzw, 1); + else mVUsaveReg(reg, (uptr)&vuRegs->VF[xmmReg[reg].reg].UL[0], xmmReg[reg].xyzw, 1); + for (int i = 0; i < xmmTotal; i++) { + if (i == reg) continue; + if (xmmReg[i].reg == xmmReg[reg].reg) { + clearReg(i); // Invalidate any Cached Regs of same vf Reg + } + } + if (xmmReg[reg].xyzw == 0xf) { // Make Cached Reg if All Vectors were Modified + xmmReg[reg].count = counter; + xmmReg[reg].xyzw = 0; + xmmReg[reg].isNeeded = 0; + return; + } + } + clearReg(reg); // Clear Reg + } + void clearNeeded(int reg) { + xmmReg[reg].isNeeded = 0; + if (xmmReg[reg].xyzw) { // Reg was modified + if (xmmReg[reg].reg > 0) { + int mergeRegs = 0; + if (xmmReg[reg].xyzw < 0xf) { mergeRegs = 1; } // Try to merge partial writes + for (int i = 0; i < xmmTotal; i++) { // Invalidate any other read-only regs of same vfReg + if (i == reg) continue; + if (xmmReg[i].reg == xmmReg[reg].reg) { + if (xmmReg[i].xyzw && xmmReg[i].xyzw < 0xf) DevCon::Error("microVU Error: clearNeeded() [%d]", params xmmReg[i].reg); + if (mergeRegs == 1) { + mVUmergeRegs(i, reg, xmmReg[reg].xyzw, 1); + xmmReg[i].xyzw = 0xf; + xmmReg[i].count = counter; + mergeRegs = 2; + } + else clearReg(i); + } + } + if (mergeRegs == 2) clearReg(reg); // Clear Current Reg if Merged + else if (mergeRegs) writeBackReg(reg); // Write Back Partial Writes if couldn't merge + } + else clearReg(reg); // If Reg was temp or vf0, then invalidate itself + } + } + int allocReg(int vfLoadReg = -1, int vfWriteReg = -1, int xyzw = 0, bool cloneWrite = 1) { + counter++; + if (vfLoadReg >= 0) { // Search For Cached Regs + for (int i = 0; i < xmmTotal; i++) { + if ((xmmReg[i].reg == vfLoadReg) && (!xmmReg[i].xyzw // Reg Was Not Modified + || (/*!xmmReg[i].isNeeded &&*/ xmmReg[i].reg && (xmmReg[i].xyzw==0xf)))) { // Reg Had All Vectors Modified and != VF0 + int z = i; + if (vfWriteReg >= 0) { // Reg will be modified + if (cloneWrite) { // Clone Reg so as not to use the same Cached Reg + z = findFreeReg(); + writeBackReg(z); + if (z!=i && xyzw==8) SSE_MOVAPS_XMM_to_XMM (z, i); + else if (xyzw == 4) SSE2_PSHUFD_XMM_to_XMM(z, i, 1); + else if (xyzw == 2) SSE2_PSHUFD_XMM_to_XMM(z, i, 2); + else if (xyzw == 1) SSE2_PSHUFD_XMM_to_XMM(z, i, 3); + else if (z != i) SSE_MOVAPS_XMM_to_XMM (z, i); + xmmReg[i].count = counter; // Reg i was used, so update counter + } + else { // Don't clone reg, but shuffle to adjust for SS ops + if ((vfLoadReg != vfWriteReg) || (xyzw != 0xf)) { writeBackReg(z); } + else if (xyzw == 4) SSE2_PSHUFD_XMM_to_XMM(z, i, 1); + else if (xyzw == 2) SSE2_PSHUFD_XMM_to_XMM(z, i, 2); + else if (xyzw == 1) SSE2_PSHUFD_XMM_to_XMM(z, i, 3); + } + xmmReg[z].reg = vfWriteReg; + xmmReg[z].xyzw = xyzw; + } + xmmReg[z].count = counter; + xmmReg[z].isNeeded = 1; + return z; + } + } + } + int x = findFreeReg(); + writeBackReg(x); + + if (vfWriteReg >= 0) { // Reg Will Be Modified (allow partial reg loading) + if ((vfLoadReg == 0) && !(xyzw & 1)) { SSE2_PXOR_XMM_to_XMM(x, x); } + else if (vfLoadReg == 32) mVUloadReg(x, (uptr)&vuRegs->ACC.UL[0], xyzw); + else if (vfLoadReg >= 0) mVUloadReg(x, (uptr)&vuRegs->VF[vfLoadReg].UL[0], xyzw); + xmmReg[x].reg = vfWriteReg; + xmmReg[x].xyzw = xyzw; + } + else { // Reg Will Not Be Modified (always load full reg for caching) + if (vfLoadReg == 32) SSE_MOVAPS_M128_to_XMM(x, (uptr)&vuRegs->ACC.UL[0]); + else if (vfLoadReg >= 0) SSE_MOVAPS_M128_to_XMM(x, (uptr)&vuRegs->VF[vfLoadReg].UL[0]); + xmmReg[x].reg = vfLoadReg; + xmmReg[x].xyzw = 0; + } + xmmReg[x].count = counter; + xmmReg[x].isNeeded = 1; + return x; + } +}; diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index 0249729754..7bd2cdd09f 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -60,9 +60,9 @@ mVUop(mVU_DIV) { MOV32ItoM((uptr)&mVU->divFlag, divD); // Zero divide (only when not 0/0) x86SetJ8(bjmp); - SSE_XORPS_XMM_to_XMM(xmmFs, xmmFt); + SSE_XORPS_XMM_to_XMM (xmmFs, xmmFt); SSE_ANDPS_M128_to_XMM(xmmFs, (uptr)mVU_signbit); - SSE_ORPS_XMM_to_XMM(xmmFs, xmmMax); // If division by zero, then xmmFs = +/- fmax + SSE_ORPS_M128_to_XMM (xmmFs, (uptr)mVU_maxvals); // If division by zero, then xmmFs = +/- fmax djmp = JMP8(0); x86SetJ8(cjmp); @@ -87,7 +87,7 @@ mVUop(mVU_SQRT) { MOV32ItoM((uptr)&mVU->divFlag, 0); // Clear I/D flags testNeg(xmmFt, gprT1, ajmp); // Check for negative sqrt - if (CHECK_VU_OVERFLOW) SSE_MINSS_XMM_to_XMM(xmmFt, xmmMax); // Clamp infinities (only need to do positive clamp since xmmFt is positive) + if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(xmmFt, (uptr)mVU_maxvals); // Clamp infinities (only need to do positive clamp since xmmFt is positive) SSE_SQRTSS_XMM_to_XMM(xmmFt, xmmFt); if (mVUinfo.writeQ) SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe1); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFt); @@ -119,7 +119,7 @@ mVUop(mVU_RSQRT) { x86SetJ8(cjmp); SSE_ANDPS_M128_to_XMM(xmmFs, (uptr)mVU_signbit); - SSE_ORPS_XMM_to_XMM(xmmFs, xmmMax); // xmmFs = +/-Max + SSE_ORPS_M128_to_XMM (xmmFs, (uptr)mVU_maxvals); // xmmFs = +/-Max djmp = JMP8(0); x86SetJ8(ajmp); @@ -666,11 +666,10 @@ mVUop(mVU_ISUB) { SUB16RtoR(gprT1, gprT2); mVUallocVIb(mVU, gprT1, _Id_); } - else if (!isMMX(_Id_)) { + else { XOR32RtoR(gprT1, gprT1); mVUallocVIb(mVU, gprT1, _Id_); } - else { PXORRtoR(mmVI(_Id_), mmVI(_Id_)); } } pass3 { mVUlog("ISUB vi%02d, vi%02d, vi%02d", _Fd_, _Fs_, _Ft_); } } diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index 9778f07b68..4ca4f8843f 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -118,21 +118,12 @@ declareAllVariables #define xmmT1 0 // Temp Reg #define xmmFs 1 // Holds the Value of Fs (writes back result Fd) #define xmmFt 2 // Holds the Value of Ft -#define xmmACC 3 // Holds ACC -#define xmmMax 4 // Holds mVU_maxvals -#define xmmMin 5 // Holds mVU_minvals -#define xmmT2 6 // Temp Reg? +#define xmmT2 3 // Temp Reg? +#define xmmT3 4 // Temp Reg? +#define xmmT4 5 // Temp Reg? +#define xmmACC 6 // Holds ACC #define xmmPQ 7 // Holds the Value and Backup Values of P and Q regs -#define mmxVI1 0 // Holds VI 1 -#define mmxVI2 1 // Holds VI 2 -#define mmxVI3 2 // Holds VI 3 -#define mmxVI4 3 // Holds VI 4 -#define mmxVI5 4 // Holds VI 5 -#define mmxVI6 5 // Holds VI 6 -#define mmxVI7 6 // Holds VI 7 -#define mmxVI8 7 // Holds VI 8 - #define gprT1 0 // Temp Reg #define gprT2 1 // Temp Reg #define gprR 2 // VI Reg Offset @@ -150,7 +141,7 @@ declareAllVariables // Recursive Inline #ifndef __LINUX__ -#define __recInline __forceinline +#define __recInline __releaseinline #else #define __recInline inline #endif @@ -169,6 +160,12 @@ declareAllVariables #define pass3 if (recPass == 2) #define pass4 if (recPass == 3) +// Upper Opcode Cases +#define opCase1 if (opCase == 1) // Normal Opcodes +#define opCase2 if (opCase == 2) // BC Opcodes +#define opCase3 if (opCase == 3) // I Opcodes +#define opCase4 if (opCase == 4) // Q Opcodes + // Define mVUquickSearch #ifndef __LINUX__ PCSX2_ALIGNED16_EXTERN( u8 mVUsearchXMM[0x1000] ); @@ -187,25 +184,25 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); #define mVUprogI mVU->prog.prog[progIndex] #define mVUcurProg mVU->prog.prog[mVU->prog.cur] #define mVUblocks mVU->prog.prog[mVU->prog.cur].block -#define mVUallocInfo mVU->prog.allocInfo -#define mVUbranch mVUallocInfo.branch -#define mVUcycles mVUallocInfo.cycles -#define mVUcount mVUallocInfo.count -#define mVUpBlock mVUallocInfo.pBlock -#define mVUblock mVUallocInfo.block -#define mVUregs mVUallocInfo.block.pState -#define mVUregsTemp mVUallocInfo.regsTemp -#define iPC mVUallocInfo.curPC -#define mVUsFlagHack mVUallocInfo.sFlagHack -#define mVUinfo mVUallocInfo.info[iPC / 2] -#define mVUconstReg mVUallocInfo.constReg +#define mVUir mVU->prog.IRinfo +#define mVUbranch mVU->prog.IRinfo.branch +#define mVUcycles mVU->prog.IRinfo.cycles +#define mVUcount mVU->prog.IRinfo.count +#define mVUpBlock mVU->prog.IRinfo.pBlock +#define mVUblock mVU->prog.IRinfo.block +#define mVUregs mVU->prog.IRinfo.block.pState +#define mVUregsTemp mVU->prog.IRinfo.regsTemp +#define iPC mVU->prog.IRinfo.curPC +#define mVUsFlagHack mVU->prog.IRinfo.sFlagHack +#define mVUconstReg mVU->prog.IRinfo.constReg +#define mVUstartPC mVU->prog.IRinfo.startPC +#define mVUinfo mVU->prog.IRinfo.info[iPC / 2] #define mVUstall mVUinfo.stall #define mVUup mVUinfo.uOp #define mVUlow mVUinfo.lOp #define sFLAG mVUinfo.sFlag #define mFLAG mVUinfo.mFlag #define cFLAG mVUinfo.cFlag -#define mVUstartPC mVUallocInfo.startPC #define mVUflagInfo mVUregs.needExactMatch #define mVUrange mVUcurProg.ranges.range[mVUcurProg.ranges.total] #define xPC ((iPC / 2) * 8) @@ -220,6 +217,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); #define Rmem (uptr)&mVU->regs->VI[REG_R].UL #define Roffset (uptr)&mVU->regs->VI[9].UL #define aWrap(x, m) ((x > m) ? 0 : x) +#define shuffleSS(x) ((x==1)?(0x27):((x==2)?(0xc6):((x==4)?(0xe1):(0xe4)))) // Flag Info #define __Status (mVUflagInfo & (0xf<<0)) @@ -241,10 +239,6 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); #define mVUlogQ() { mVUlog(", Q"); } #define mVUlogCLIP() { mVUlog("w.xyz vf%02d, vf%02dw", _Fs_, _Ft_); } -// Store VI regs in mmx regs? -#define isMMX(_VIreg_) 0 //(_VIreg_ >= 1 && _VIreg_ <=8) -#define mmVI(_VIreg_) (_VIreg_ - 1) - // Debug Stuff... #ifdef mVUdebug #define mVUprint Console::Status diff --git a/pcsx2/x86/microVU_Misc.inl b/pcsx2/x86/microVU_Misc.inl index 81534987f1..44cd2e6557 100644 --- a/pcsx2/x86/microVU_Misc.inl +++ b/pcsx2/x86/microVU_Misc.inl @@ -26,12 +26,12 @@ void mVUclamp1(int reg, int regT1, int xyzw) { switch (xyzw) { case 1: case 2: case 4: case 8: - SSE_MINSS_XMM_to_XMM(reg, xmmMax); - SSE_MAXSS_XMM_to_XMM(reg, xmmMin); + SSE_MINSS_M32_to_XMM(reg, (uptr)mVU_maxvals); + SSE_MAXSS_M32_to_XMM(reg, (uptr)mVU_minvals); break; default: - SSE_MINPS_XMM_to_XMM(reg, xmmMax); - SSE_MAXPS_XMM_to_XMM(reg, xmmMin); + SSE_MINPS_M128_to_XMM(reg, (uptr)mVU_maxvals); + SSE_MAXPS_M128_to_XMM(reg, (uptr)mVU_minvals); break; } } @@ -43,15 +43,15 @@ void mVUclamp2(int reg, int regT1, int xyzw) { case 1: case 2: case 4: case 8: SSE_MOVSS_XMM_to_XMM(regT1, reg); SSE_ANDPS_M128_to_XMM(regT1, (uptr)mVU_signbit); - SSE_MINSS_XMM_to_XMM(reg, xmmMax); - SSE_MAXSS_XMM_to_XMM(reg, xmmMin); + SSE_MINSS_M32_to_XMM(reg, (uptr)mVU_maxvals); + SSE_MAXSS_M32_to_XMM(reg, (uptr)mVU_minvals); SSE_ORPS_XMM_to_XMM(reg, regT1); break; default: SSE_MOVAPS_XMM_to_XMM(regT1, reg); SSE_ANDPS_M128_to_XMM(regT1, (uptr)mVU_signbit); - SSE_MINPS_XMM_to_XMM(reg, xmmMax); - SSE_MAXPS_XMM_to_XMM(reg, xmmMin); + SSE_MINPS_M128_to_XMM(reg, (uptr)mVU_maxvals); + SSE_MAXPS_M128_to_XMM(reg, (uptr)mVU_minvals); SSE_ORPS_XMM_to_XMM(reg, regT1); break; } @@ -104,10 +104,16 @@ void mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW) { return;*/ switch ( xyzw ) { - case 5: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xe1); //WZXY - SSE_MOVSS_XMM_to_M32(offset+4, reg); - SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xff); //WWWW - SSE_MOVSS_XMM_to_M32(offset+12, reg); + case 5: if (cpucaps.hasStreamingSIMD4Extensions) { + SSE4_EXTRACTPS_XMM_to_M32(offset+4, reg, 1); + SSE4_EXTRACTPS_XMM_to_M32(offset+12, reg, 3); + } + else { + SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xe1); //WZXY + SSE_MOVSS_XMM_to_M32(offset+4, reg); + SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xff); //WWWW + SSE_MOVSS_XMM_to_M32(offset+12, reg); + } break; // YW case 6: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xc9); SSE_MOVLPS_XMM_to_M64(offset+4, reg); @@ -203,25 +209,33 @@ void mVUsaveReg2(int reg, int gprReg, u32 offset, int xyzw) { } } -// Modifies the Source Reg! -void mVUmergeRegs(int dest, int src, int xyzw) { +// Modifies the Source Reg! (ToDo: Optimize modXYZW = 1 cases) +void mVUmergeRegs(int dest, int src, int xyzw, bool modXYZW = 0) { xyzw &= 0xf; if ( (dest != src) && (xyzw != 0) ) { - if ( cpucaps.hasStreamingSIMD4Extensions && (xyzw != 0x8) && (xyzw != 0xf) ) { + if (cpucaps.hasStreamingSIMD4Extensions && (xyzw != 0x8) && (xyzw != 0xf)) { + if (modXYZW) { + if (xyzw == 1) { SSE4_INSERTPS_XMM_to_XMM(dest, src, _MM_MK_INSERTPS_NDX(0, 3, 0)); return; } + else if (xyzw == 2) { SSE4_INSERTPS_XMM_to_XMM(dest, src, _MM_MK_INSERTPS_NDX(0, 2, 0)); return; } + else if (xyzw == 4) { SSE4_INSERTPS_XMM_to_XMM(dest, src, _MM_MK_INSERTPS_NDX(0, 1, 0)); return; } + } xyzw = ((xyzw & 1) << 3) | ((xyzw & 2) << 1) | ((xyzw & 4) >> 1) | ((xyzw & 8) >> 3); SSE4_BLENDPS_XMM_to_XMM(dest, src, xyzw); } else { switch (xyzw) { - case 1: SSE_MOVHLPS_XMM_to_XMM(src, dest); - SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc4); + case 1: if (modXYZW) mVUunpack_xyzw(src, src, 0); + SSE_MOVHLPS_XMM_to_XMM(src, dest); // src = Sw Sz Dw Dz + SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc4); // 11 00 01 00 break; - case 2: SSE_MOVHLPS_XMM_to_XMM(src, dest); + case 2: if (modXYZW) mVUunpack_xyzw(src, src, 0); + SSE_MOVHLPS_XMM_to_XMM(src, dest); SSE_SHUFPS_XMM_to_XMM(dest, src, 0x64); break; case 3: SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); break; - case 4: SSE_MOVSS_XMM_to_XMM(src, dest); + case 4: if (modXYZW) mVUunpack_xyzw(src, src, 0); + SSE_MOVSS_XMM_to_XMM(src, dest); SSE2_MOVSD_XMM_to_XMM(dest, src); break; case 5: SSE_SHUFPS_XMM_to_XMM(dest, src, 0xd8); @@ -285,17 +299,14 @@ microVUt(void) mVUaddrFix(mV, int gprReg) { } // Backup Volatile Regs (EAX, ECX, EDX, MM0~7, XMM0~7, are all volatile according to 32bit Win/Linux ABI) -microVUt(void) mVUbackupRegs(mV) { - SSE_MOVAPS_XMM_to_M128((uptr)&mVU->regs->ACC.UL[0], xmmACC); +microVUt(void) mVUbackupRegs(microVU* mVU) { + mVU->regAlloc->flushAll(); SSE_MOVAPS_XMM_to_M128((uptr)&mVU->xmmPQb[0], xmmPQ); } // Restore Volatile Regs -microVUt(void) mVUrestoreRegs(mV) { - SSE_MOVAPS_M128_to_XMM(xmmACC, (uptr)&mVU->regs->ACC.UL[0]); +microVUt(void) mVUrestoreRegs(microVU* mVU) { SSE_MOVAPS_M128_to_XMM(xmmPQ, (uptr)&mVU->xmmPQb[0]); - SSE_MOVAPS_M128_to_XMM(xmmMax, (uptr)mVU_maxvals); - SSE_MOVAPS_M128_to_XMM(xmmMin, (uptr)mVU_minvals); MOV32ItoR(gprR, Roffset); // Restore gprR } @@ -335,8 +346,8 @@ void MIN_MAX_(x86SSERegType to, x86SSERegType from, bool min) { // Warning: Modifies from and to's upper 3 vectors void MIN_MAX_SS(x86SSERegType to, x86SSERegType from, bool min) { SSE_SHUFPS_XMM_to_XMM (to, from, 0); - SSE2_PAND_M128_to_XMM (to, (uptr)MIN_MAX_MASK1); - SSE2_POR_M128_to_XMM (to, (uptr)MIN_MAX_MASK2); + SSE2_PAND_M128_to_XMM (to, (uptr)MIN_MAX_MASK1); + SSE2_POR_M128_to_XMM (to, (uptr)MIN_MAX_MASK2); SSE2_PSHUFD_XMM_to_XMM(from, to, 0xee); if (min) SSE2_MINPD_XMM_to_XMM(to, from); else SSE2_MAXPD_XMM_to_XMM(to, from); diff --git a/pcsx2/x86/microVU_Tables.inl b/pcsx2/x86/microVU_Tables.inl index 65ed7e9559..de99062f58 100644 --- a/pcsx2/x86/microVU_Tables.inl +++ b/pcsx2/x86/microVU_Tables.inl @@ -238,7 +238,7 @@ mVUop(mVULowerOP_T3_11) { doTableStuff(mVULowerOP_T3_11_OPCODE, ((mVUgetCode >> mVUop(mVUopU) { doTableStuff(mVU_UPPER_OPCODE, (mVUgetCode & 0x3f)); } // Gets Upper Opcode mVUop(mVUopL) { doTableStuff(mVULOWER_OPCODE, (mVUgetCode >> 25)); } // Gets Lower Opcode mVUop(mVUunknown) { - pass2 { Console::Error("microVU%d: Unknown Micro VU opcode called (%08x)\n", params getIndex, mVUgetCode); } + pass2 { Console::Error("microVU%d: Unknown Micro VU opcode called (%x) [%04x]\n", params getIndex, mVUgetCode, xPC); } pass3 { mVUlog("Unknown", mVUgetCode); } } diff --git a/pcsx2/x86/microVU_Upper.inl b/pcsx2/x86/microVU_Upper.inl index 380a2a4727..1f46c8d7a4 100644 --- a/pcsx2/x86/microVU_Upper.inl +++ b/pcsx2/x86/microVU_Upper.inl @@ -27,30 +27,31 @@ #define SHIFT_XYZW(gprReg) { if (_XYZW_SS && modXYZW && !_W) { SHL32ItoR(gprReg, ADD_XYZW); } } // Note: If modXYZW is true, then it adjusts XYZW for Single Scalar operations -microVUt(void) mVUupdateFlags(mV, int reg, int regT1, int regT2, int xyzw, bool modXYZW) { - int sReg, mReg = gprT1; +microVUt(void) mVUupdateFlags(mV, int reg, int regT1, bool modXYZW = 1) { + int sReg, mReg = gprT1, xyzw = _X_Y_Z_W; static const u16 flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; //SysPrintf("Status = %d; Mac = %d\n", sFLAG.doFlag, mFLAG.doFlag); if (mVUsFlagHack) { sFLAG.doFlag = 0; } - if (!sFLAG.doFlag && !mFLAG.doFlag) { return; } - if (!mFLAG.doFlag || (_XYZW_SS && modXYZW)) { regT1 = reg; } - else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw + if (!sFLAG.doFlag && !mFLAG.doFlag) { return; } + if (!(!mFLAG.doFlag || (_XYZW_SS && modXYZW))) { + SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0x1B); // Flip wzyx to xyzw + } if (sFLAG.doFlag) { getFlagReg(sReg, sFLAG.write); // Set sReg to valid GPR by Cur Flag Instance mVUallocSFLAGa(sReg, sFLAG.lastWrite); // Get Prev Status Flag if (sFLAG.doNonSticky) AND32ItoR(sReg, 0xfffc00ff); // Clear O,U,S,Z flags } + if (regT1 < 0) { regT1 = mVU->regAlloc->allocReg(); } //-------------------------Check for Signed flags------------------------------ // The following code makes sure the Signed Bit isn't set with Negative Zero - SSE_XORPS_XMM_to_XMM(regT2, regT2); // Clear regT2 - SSE_CMPEQPS_XMM_to_XMM(regT2, regT1); // Set all F's if each vector is zero - SSE_MOVMSKPS_XMM_to_R32(gprT2, regT2); // Used for Zero Flag Calculation - SSE_ANDNPS_XMM_to_XMM(regT2, regT1); - - SSE_MOVMSKPS_XMM_to_R32(mReg, regT2); // Move the sign bits of the t1reg + SSE_XORPS_XMM_to_XMM (regT1, regT1); // Clear regT2 + SSE_CMPEQPS_XMM_to_XMM (regT1, reg); // Set all F's if each vector is zero + SSE_MOVMSKPS_XMM_to_R32(gprT2, regT1); // Used for Zero Flag Calculation + SSE_ANDNPS_XMM_to_XMM (regT1, reg); // Used for Sign Flag Calculation + SSE_MOVMSKPS_XMM_to_R32(mReg, regT1); // Move the Sign Bits of the t1reg AND32ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation SHL32ItoR(mReg, 4 + ADD_XYZW); @@ -63,6 +64,9 @@ microVUt(void) mVUupdateFlags(mV, int reg, int regT1, int regT2, int xyzw, bool //-------------------------Write back flags------------------------------ + if (!(!mFLAG.doFlag || (_XYZW_SS && modXYZW))) { + SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0x1B); // Flip wzyx to xyzw + } if (mFLAG.doFlag) mVUallocMFLAGb(mVU, mReg, mFLAG.write); // Set Mac Flag if (sFLAG.doFlag) { OR32RtoR (sReg, mReg); @@ -74,530 +78,332 @@ microVUt(void) mVUupdateFlags(mV, int reg, int regT1, int regT2, int xyzw, bool } //------------------------------------------------------------------ -// Helper Macros +// Helper Macros and Functions //------------------------------------------------------------------ -// FMAC1 - Normal FMAC Opcodes -#define mVU_FMAC1(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } \ - pass2 { \ - int Fd, Fs, Ft; \ - mVUallocFMAC1a(mVU, Fd, Fs, Ft); \ - if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ - else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ - mVUallocFMAC1b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \ -} -// FMAC3 - BC(xyzw) FMAC Opcodes -#define mVU_FMAC3(operation, OPname) { \ - pass1 { mVUanalyzeFMAC3(mVU, _Fd_, _Fs_, _Ft_); } \ - pass2 { \ - int Fd, Fs, Ft; \ - mVUallocFMAC3a(mVU, Fd, Fs, Ft); \ - if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ - else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ - mVUallocFMAC3b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \ -} -// FMAC4 - FMAC Opcodes Storing Result to ACC -#define mVU_FMAC4(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, _Ft_); } \ - pass2 { \ - int ACC, Fs, Ft; \ - mVUallocFMAC4a(mVU, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ - else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC4b(mVU, ACC, Fs); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \ -} -// FMAC5 - FMAC BC(xyzw) Opcodes Storing Result to ACC -#define mVU_FMAC5(operation, OPname) { \ - pass1 { mVUanalyzeFMAC3(mVU, 0, _Fs_, _Ft_); } \ - pass2 { \ - int ACC, Fs, Ft; \ - mVUallocFMAC5a(mVU, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ - else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC5b(mVU, ACC, Fs); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogBC(); } \ -} -// FMAC6 - Normal FMAC Opcodes (I Reg) -#define mVU_FMAC6(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ - pass2 { \ - int Fd, Fs, Ft; \ - mVUallocFMAC6a(mVU, Fd, Fs, Ft); \ - if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ - else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ - mVUallocFMAC6b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \ -} -// FMAC7 - FMAC Opcodes Storing Result to ACC (I Reg) -#define mVU_FMAC7(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, 0); } \ - pass2 { \ - int ACC, Fs, Ft; \ - mVUallocFMAC7a(mVU, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ - else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC7b(mVU, ACC, Fs); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogI(); } \ -} -// FMAC8 - MADD FMAC Opcode Storing Result to Fd -#define mVU_FMAC8(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC8a(mVU, Fd, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(Fs, ACC); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(Fs, ACC); \ - } \ - mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC8b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \ -} -// FMAC9 - MSUB FMAC Opcode Storing Result to Fd -#define mVU_FMAC9(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC9a(mVU, Fd, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(ACC, Fs); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ - } \ - mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC9b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \ -} -// FMAC10 - MADD FMAC BC(xyzw) Opcode Storing Result to Fd -#define mVU_FMAC10(operation, OPname) { \ - pass1 { mVUanalyzeFMAC3(mVU, _Fd_, _Fs_, _Ft_); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC10a(mVU, Fd, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(Fs, ACC); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(Fs, ACC); \ - } \ - mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC10b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \ -} -// FMAC11 - MSUB FMAC BC(xyzw) Opcode Storing Result to Fd -#define mVU_FMAC11(operation, OPname) { \ - pass1 { mVUanalyzeFMAC3(mVU, _Fd_, _Fs_, _Ft_); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC11a(mVU, Fd, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(ACC, Fs); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ - } \ - mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC11b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogBC(); } \ -} -// FMAC12 - MADD FMAC Opcode Storing Result to Fd (I Reg) -#define mVU_FMAC12(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC12a(mVU, Fd, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(Fs, ACC); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(Fs, ACC); \ - } \ - mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC12b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \ -} -// FMAC13 - MSUB FMAC Opcode Storing Result to Fd (I Reg) -#define mVU_FMAC13(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC13a(mVU, Fd, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(ACC, Fs); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ - } \ - mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC13b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogI(); } \ -} -// FMAC14 - MADDA/MSUBA FMAC Opcode -#define mVU_FMAC14(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, _Ft_); } \ - pass2 { \ - int ACCw, ACCr, Fs, Ft; \ - mVUallocFMAC14a(mVU, ACCw, ACCr, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(ACCr, Fs); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACCr, Fs); \ - } \ - mVUupdateFlags(mVU, ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC14b(mVU, ACCw, ACCr); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \ -} -// FMAC15 - MADDA/MSUBA BC(xyzw) FMAC Opcode -#define mVU_FMAC15(operation, OPname) { \ - pass1 { mVUanalyzeFMAC3(mVU, 0, _Fs_, _Ft_); } \ - pass2 { \ - int ACCw, ACCr, Fs, Ft; \ - mVUallocFMAC15a(mVU, ACCw, ACCr, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(ACCr, Fs); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACCr, Fs); \ - } \ - mVUupdateFlags(mVU, ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC15b(mVU, ACCw, ACCr); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogBC(); } \ -} -// FMAC16 - MADDA/MSUBA FMAC Opcode (I Reg) -#define mVU_FMAC16(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, 0); } \ - pass2 { \ - int ACCw, ACCr, Fs, Ft; \ - mVUallocFMAC16a(mVU, ACCw, ACCr, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(ACCr, Fs); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACCr, Fs); \ - } \ - mVUupdateFlags(mVU, ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC16b(mVU, ACCw, ACCr); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogI(); } \ -} -// FMAC18 - OPMULA FMAC Opcode -#define mVU_FMAC18(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, _Ft_); } \ - pass2 { \ - int ACC, Fs, Ft; \ - mVUallocFMAC18a(mVU, ACC, Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC18b(mVU, ACC, Fs); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogFt(); } \ -} -// FMAC19 - OPMSUB FMAC Opcode -#define mVU_FMAC19(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC19a(mVU, Fd, ACC, Fs, Ft); \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ - mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC19b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogFt(); } \ -} -// FMAC22 - Normal FMAC Opcodes (Q Reg) -#define mVU_FMAC22(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ - pass2 { \ - int Fd, Fs, Ft; \ - mVUallocFMAC22a(mVU, Fd, Fs, Ft); \ - if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ - else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 1); \ - mVUallocFMAC22b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \ -} -// FMAC23 - FMAC Opcodes Storing Result to ACC (Q Reg) -#define mVU_FMAC23(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, 0); } \ - pass2 { \ - int ACC, Fs, Ft; \ - mVUallocFMAC23a(mVU, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ - else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ - mVUupdateFlags(mVU, Fs, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC23b(mVU, ACC, Fs); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogQ();} \ -} -// FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg) -#define mVU_FMAC24(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC24a(mVU, Fd, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(Fs, ACC); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(Fs, ACC); \ - } \ - mVUupdateFlags(mVU, Fd, xmmT1, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC24b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \ -} -// FMAC25 - MSUB FMAC Opcode Storing Result to Fd (Q Reg) -#define mVU_FMAC25(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, 0); } \ - pass2 { \ - int Fd, ACC, Fs, Ft; \ - mVUallocFMAC25a(mVU, Fd, ACC, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(ACC, Fs); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ - } \ - mVUupdateFlags(mVU, Fd, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC25b(mVU, Fd); \ - } \ - pass3 { mVUlog(OPname); mVUlogFd(); mVUlogQ(); } \ -} -// FMAC26 - MADDA/MSUBA FMAC Opcode (Q Reg) -#define mVU_FMAC26(operation, OPname) { \ - pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, 0); } \ - pass2 { \ - int ACCw, ACCr, Fs, Ft; \ - mVUallocFMAC26a(mVU, ACCw, ACCr, Fs, Ft); \ - if (_X_Y_Z_W == 8) { \ - SSE_MULSS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##SS_XMM_to_XMM(ACCr, Fs); \ - } \ - else { \ - SSE_MULPS_XMM_to_XMM(Fs, Ft); \ - SSE_##operation##PS_XMM_to_XMM(ACCr, Fs); \ - } \ - mVUupdateFlags(mVU, ACCr, Fs, xmmT2, _X_Y_Z_W, 0); \ - mVUallocFMAC26b(mVU, ACCw, ACCr); \ - } \ - pass3 { mVUlog(OPname); mVUlogACC(); mVUlogQ(); } \ +static void (*SSE_PS[]) (x86SSERegType, x86SSERegType) = { + SSE_ADDPS_XMM_to_XMM, // 0 + SSE_SUBPS_XMM_to_XMM, // 1 + SSE_MULPS_XMM_to_XMM, // 2 + SSE_MAXPS_XMM_to_XMM, // 3 + SSE_MINPS_XMM_to_XMM // 4 +}; + +static void (*SSE_SS[]) (x86SSERegType, x86SSERegType) = { + SSE_ADDSS_XMM_to_XMM, // 0 + SSE_SUBSS_XMM_to_XMM, // 1 + SSE_MULSS_XMM_to_XMM, // 2 + SSE_MAXSS_XMM_to_XMM, // 3 + SSE_MINSS_XMM_to_XMM // 4 +}; + +// Prints Opcode to MicroProgram Logs +void mVU_printOP(microVU* mVU, int opCase, char* opName, bool isACC) { + mVUlog(opName); + opCase1 { if (isACC) { mVUlogACC(); } else { mVUlogFd(); } mVUlogFt(); } + opCase2 { if (isACC) { mVUlogACC(); } else { mVUlogFd(); } mVUlogBC(); } + opCase3 { if (isACC) { mVUlogACC(); } else { mVUlogFd(); } mVUlogI(); } + opCase4 { if (isACC) { mVUlogACC(); } else { mVUlogFd(); } mVUlogQ(); } } -// FMAC27~29 - MAX/MINI FMAC Opcodes -#define mVU_FMAC27(operation, OPname) { mVU_FMAC1 (operation, OPname); pass1 { sFLAG.doFlag = 0; } } -#define mVU_FMAC28(operation, OPname) { mVU_FMAC6 (operation, OPname); pass1 { sFLAG.doFlag = 0; } } -#define mVU_FMAC29(operation, OPname) { mVU_FMAC3 (operation, OPname); pass1 { sFLAG.doFlag = 0; } } +// Sets Up Pass1 Info for Normal, BC, I, and Q Cases +void setupPass1(microVU* mVU, int opCase, bool isACC, bool noFlagUpdate) { + opCase1 { mVUanalyzeFMAC1(mVU, ((isACC) ? 0 : _Fd_), _Fs_, _Ft_); } + opCase2 { mVUanalyzeFMAC3(mVU, ((isACC) ? 0 : _Fd_), _Fs_, _Ft_); } + opCase3 { mVUanalyzeFMAC1(mVU, ((isACC) ? 0 : _Fd_), _Fs_, 0); } + opCase4 { mVUanalyzeFMAC1(mVU, ((isACC) ? 0 : _Fd_), _Fs_, 0); } + if (noFlagUpdate) { sFLAG.doFlag = 0; } +} -//------------------------------------------------------------------ -// Micro VU Micromode Upper instructions -//------------------------------------------------------------------ +// Sets Up Ft Reg for Normal, BC, I, and Q Cases +void setupFtReg(microVU* mVU, int& Ft, int opCase) { + opCase1 { Ft = mVU->regAlloc->allocReg(_Ft_); } + opCase2 { + if (!_XYZW_SS) { + Ft = mVU->regAlloc->allocReg(_Ft_, 0, 0xf); + mVUunpack_xyzw(Ft, Ft, _bc_); + } + else Ft = mVU->regAlloc->allocReg(_Ft_); + } + opCase3 { Ft = mVU->regAlloc->allocReg(); getIreg(Ft, 1); } + opCase4 { Ft = mVU->regAlloc->allocReg(); getQreg(Ft); } +} +// Normal FMAC Opcodes +void mVU_FMACa(microVU* mVU, int recPass, int opCase, int opType, bool isACC, char* opName) { + pass1 { setupPass1(mVU, opCase, isACC, ((opType == 3) || (opType == 4))); } + pass2 { + int Fs, Ft, ACC; + mVU->regAlloc->reset(); // Reset for Testing + setupFtReg(mVU, Ft, opCase); + + if (isACC) { + ACC = mVU->regAlloc->allocReg((_X_Y_Z_W == 0xf) ? -1 : 32, 32, 0xf, 0); + Fs = mVU->regAlloc->allocReg(_Fs_, 0, _X_Y_Z_W); + if (_XYZW_SS && _X_Y_Z_W != 8) SSE2_PSHUFD_XMM_to_XMM(ACC, ACC, shuffleSS(_X_Y_Z_W)); + } + else { Fs = mVU->regAlloc->allocReg(_Fs_, _Fd_, _X_Y_Z_W); } + + opCase1 { if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS(_X_Y_Z_W)); } } + opCase2 { if (_XYZW_SS && (!_bc_x)) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS((1 << (3 - _bc_)))); } } + + if (_XYZW_SS) SSE_SS[opType](Fs, Ft); + else SSE_PS[opType](Fs, Ft); + + opCase1 { if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS(_X_Y_Z_W)); } } + opCase2 { if (_XYZW_SS && (!_bc_x)) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS((1 << (3 - _bc_)))); } } + + if (isACC) { + if (_XYZW_SS) SSE_MOVSS_XMM_to_XMM(ACC, Fs); + else mVUmergeRegs(ACC, Fs, _X_Y_Z_W); + mVUupdateFlags(mVU, ACC, Fs); + if (_XYZW_SS && _X_Y_Z_W != 8) SSE2_PSHUFD_XMM_to_XMM(ACC, ACC, shuffleSS(_X_Y_Z_W)); + mVU->regAlloc->clearNeeded(ACC); + } + else mVUupdateFlags(mVU, Fs, (((opCase==2)&&(!_XYZW_SS)) ? Ft : -1)); + + //if (isACC) SSE_MOVAPS_XMM_to_XMM(xmmACC, ACC); // For Testing + mVU->regAlloc->clearNeeded(Fs); // Always Clear Written Reg First + mVU->regAlloc->clearNeeded(Ft); + mVU->regAlloc->flushAll(); // Flush All for Testing + } + pass3 { mVU_printOP(mVU, opCase, opName, isACC); } +} + +// MADDA/MSUBA Opcodes +void mVU_FMACb(microVU* mVU, int recPass, int opCase, int opType, char* opName) { + pass1 { setupPass1(mVU, opCase, 1, 0); } + pass2 { + int Fs, Ft, ACC; + mVU->regAlloc->reset(); // Reset for Testing + setupFtReg(mVU, Ft, opCase); + + ACC = mVU->regAlloc->allocReg(32, 32, 0xf, 0); + Fs = mVU->regAlloc->allocReg(_Fs_, 0, _X_Y_Z_W); + + if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(ACC, ACC, shuffleSS(_X_Y_Z_W)); } + opCase1 { if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS(_X_Y_Z_W)); } } + opCase2 { if (_XYZW_SS && (!_bc_x)) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS((1 << (3 - _bc_)))); } } + + if (_XYZW_SS) SSE_SS[2](Fs, Ft); + else SSE_PS[2](Fs, Ft); + + opCase1 { if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS(_X_Y_Z_W)); } } + opCase2 { if (_XYZW_SS && (!_bc_x)) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS((1 << (3 - _bc_)))); } } + + if (_XYZW_SS || _X_Y_Z_W == 0xf) { + if (_XYZW_SS) SSE_SS[opType](ACC, Fs); + else SSE_PS[opType](ACC, Fs); + mVUupdateFlags(mVU, ACC, Fs); + if (_XYZW_SS && _X_Y_Z_W != 8) SSE2_PSHUFD_XMM_to_XMM(ACC, ACC, shuffleSS(_X_Y_Z_W)); + } + else { + int tempACC = mVU->regAlloc->allocReg(); + SSE_MOVAPS_XMM_to_XMM(tempACC, ACC); + SSE_PS[opType](tempACC, Fs); + mVUmergeRegs(ACC, tempACC, _X_Y_Z_W); + mVU->regAlloc->clearNeeded(tempACC); + } + + //SSE_MOVAPS_XMM_to_XMM(xmmACC, ACC); // For Testing + mVU->regAlloc->clearNeeded(ACC); + mVU->regAlloc->clearNeeded(Fs); + mVU->regAlloc->clearNeeded(Ft); + mVU->regAlloc->flushAll(); // Flush All for Testing + } + pass3 { mVU_printOP(mVU, opCase, opName, 1); } +} + +// MADD Opcodes +void mVU_FMACc(microVU* mVU, int recPass, int opCase, char* opName) { + pass1 { setupPass1(mVU, opCase, 0, 0); } + pass2 { + int Fs, Ft, ACC; + mVU->regAlloc->reset(); // Reset for Testing + setupFtReg(mVU, Ft, opCase); + + ACC = mVU->regAlloc->allocReg(32); + Fs = mVU->regAlloc->allocReg(_Fs_, _Fd_, _X_Y_Z_W); + + if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(ACC, ACC, shuffleSS(_X_Y_Z_W)); } + opCase1 { if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS(_X_Y_Z_W)); } } + opCase2 { if (_XYZW_SS && (!_bc_x)) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS((1 << (3 - _bc_)))); } } + + if (_XYZW_SS) { SSE_SS[2](Fs, Ft); SSE_SS[0](Fs, ACC); } + else { SSE_PS[2](Fs, Ft); SSE_PS[0](Fs, ACC); } + + mVUupdateFlags(mVU, Fs, -1); + + if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(ACC, ACC, shuffleSS(_X_Y_Z_W)); } + opCase1 { if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS(_X_Y_Z_W)); } } + opCase2 { if (_XYZW_SS && (!_bc_x)) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS((1 << (3 - _bc_)))); } } + + mVU->regAlloc->clearNeeded(ACC); + mVU->regAlloc->clearNeeded(Fs); // Always Clear Written Reg First + mVU->regAlloc->clearNeeded(Ft); + mVU->regAlloc->flushAll(); // Flush All for Testing + } + pass3 { mVU_printOP(mVU, opCase, opName, 0); } +} + +// MSUB Opcodes +void mVU_FMACd(microVU* mVU, int recPass, int opCase, char* opName) { + pass1 { setupPass1(mVU, opCase, 0, 0); } + pass2 { + int Fs, Ft, Fd; + mVU->regAlloc->reset(); // Reset for Testing + setupFtReg(mVU, Ft, opCase); + + Fs = mVU->regAlloc->allocReg(_Fs_, 0, _X_Y_Z_W); + Fd = mVU->regAlloc->allocReg(32, _Fd_, _X_Y_Z_W); + + opCase1 { if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS(_X_Y_Z_W)); } } + opCase2 { if (_XYZW_SS && (!_bc_x)) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS((1 << (3 - _bc_)))); } } + + if (_XYZW_SS) { SSE_SS[2](Fs, Ft); SSE_SS[1](Fd, Fs); } + else { SSE_PS[2](Fs, Ft); SSE_PS[1](Fd, Fs); } + + mVUupdateFlags(mVU, Fd, Fs); + + opCase1 { if (_XYZW_SS && _X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS(_X_Y_Z_W)); } } + opCase2 { if (_XYZW_SS && (!_bc_x)) { SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, shuffleSS((1 << (3 - _bc_)))); } } + + mVU->regAlloc->clearNeeded(Fd); // Always Clear Written Reg First + mVU->regAlloc->clearNeeded(Ft); + mVU->regAlloc->clearNeeded(Fs); + mVU->regAlloc->flushAll(); // Flush All for Testing + } + pass3 { mVU_printOP(mVU, opCase, opName, 0); } +} + +// ABS Opcode mVUop(mVU_ABS) { pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); } pass2 { - int Fs, Ft; - mVUallocFMAC2a(mVU, Fs, Ft); + if (!_Ft_) return; + mVU->regAlloc->reset(); // Reset for Testing + int Fs = mVU->regAlloc->allocReg(_Fs_, _Ft_, _X_Y_Z_W, ((_Fs_ == _Ft_) && (_X_Y_Z_W == 0xf))); SSE_ANDPS_M128_to_XMM(Fs, (uptr)mVU_absclip); - mVUallocFMAC2b(mVU, Ft); + mVU->regAlloc->clearNeeded(Fs); + mVU->regAlloc->flushAll(); // Flush All for Testing } pass3 { mVUlog("ABS"); mVUlogFtFs(); } } -mVUop(mVU_ADD) { mVU_FMAC1 (ADD, "ADD"); } -mVUop(mVU_ADDi) { mVU_FMAC6 (ADD2, "ADDi"); } -mVUop(mVU_ADDq) { mVU_FMAC22(ADD, "ADDq"); } -mVUop(mVU_ADDx) { mVU_FMAC3 (ADD, "ADDx"); } -mVUop(mVU_ADDy) { mVU_FMAC3 (ADD, "ADDy"); } -mVUop(mVU_ADDz) { mVU_FMAC3 (ADD, "ADDz"); } -mVUop(mVU_ADDw) { mVU_FMAC3 (ADD, "ADDw"); } -mVUop(mVU_ADDA) { mVU_FMAC4 (ADD, "ADDA"); } -mVUop(mVU_ADDAi) { mVU_FMAC7 (ADD, "ADDAi"); } -mVUop(mVU_ADDAq) { mVU_FMAC23(ADD, "ADDAq"); } -mVUop(mVU_ADDAx) { mVU_FMAC5 (ADD, "ADDAx"); } -mVUop(mVU_ADDAy) { mVU_FMAC5 (ADD, "ADDAy"); } -mVUop(mVU_ADDAz) { mVU_FMAC5 (ADD, "ADDAz"); } -mVUop(mVU_ADDAw) { mVU_FMAC5 (ADD, "ADDAw"); } -mVUop(mVU_SUB) { mVU_FMAC1 (SUB, "SUB"); } -mVUop(mVU_SUBi) { mVU_FMAC6 (SUB, "SUBi"); } -mVUop(mVU_SUBq) { mVU_FMAC22(SUB, "SUBq"); } -mVUop(mVU_SUBx) { mVU_FMAC3 (SUB, "SUBx"); } -mVUop(mVU_SUBy) { mVU_FMAC3 (SUB, "SUBy"); } -mVUop(mVU_SUBz) { mVU_FMAC3 (SUB, "SUBz"); } -mVUop(mVU_SUBw) { mVU_FMAC3 (SUB, "SUBw"); } -mVUop(mVU_SUBA) { mVU_FMAC4 (SUB, "SUBA"); } -mVUop(mVU_SUBAi) { mVU_FMAC7 (SUB, "SUBAi"); } -mVUop(mVU_SUBAq) { mVU_FMAC23(SUB, "SUBAq"); } -mVUop(mVU_SUBAx) { mVU_FMAC5 (SUB, "SUBAx"); } -mVUop(mVU_SUBAy) { mVU_FMAC5 (SUB, "SUBAy"); } -mVUop(mVU_SUBAz) { mVU_FMAC5 (SUB, "SUBAz"); } -mVUop(mVU_SUBAw) { mVU_FMAC5 (SUB, "SUBAw"); } -mVUop(mVU_MUL) { mVU_FMAC1 (MUL, "MUL"); } -mVUop(mVU_MULi) { mVU_FMAC6 (MUL, "MULi"); } -mVUop(mVU_MULq) { mVU_FMAC22(MUL, "MULq"); } -mVUop(mVU_MULx) { mVU_FMAC3 (MUL, "MULx"); } -mVUop(mVU_MULy) { mVU_FMAC3 (MUL, "MULy"); } -mVUop(mVU_MULz) { mVU_FMAC3 (MUL, "MULz"); } -mVUop(mVU_MULw) { mVU_FMAC3 (MUL, "MULw"); } -mVUop(mVU_MULA) { mVU_FMAC4 (MUL, "MULA"); } -mVUop(mVU_MULAi) { mVU_FMAC7 (MUL, "MULAi"); } -mVUop(mVU_MULAq) { mVU_FMAC23(MUL, "MULAq"); } -mVUop(mVU_MULAx) { mVU_FMAC5 (MUL, "MULAx"); } -mVUop(mVU_MULAy) { mVU_FMAC5 (MUL, "MULAy"); } -mVUop(mVU_MULAz) { mVU_FMAC5 (MUL, "MULAz"); } -mVUop(mVU_MULAw) { mVU_FMAC5 (MUL, "MULAw"); } -mVUop(mVU_MADD) { mVU_FMAC8 (ADD, "MADD"); } -mVUop(mVU_MADDi) { mVU_FMAC12(ADD, "MADDi"); } -mVUop(mVU_MADDq) { mVU_FMAC24(ADD, "MADDq"); } -mVUop(mVU_MADDx) { mVU_FMAC10(ADD, "MADDx"); } -mVUop(mVU_MADDy) { mVU_FMAC10(ADD, "MADDy"); } -mVUop(mVU_MADDz) { mVU_FMAC10(ADD, "MADDz"); } -mVUop(mVU_MADDw) { mVU_FMAC10(ADD, "MADDw"); } -mVUop(mVU_MADDA) { mVU_FMAC14(ADD, "MADDA"); } -mVUop(mVU_MADDAi) { mVU_FMAC16(ADD, "MADDAi"); } -mVUop(mVU_MADDAq) { mVU_FMAC26(ADD, "MADDAq"); } -mVUop(mVU_MADDAx) { mVU_FMAC15(ADD, "MADDAx"); } -mVUop(mVU_MADDAy) { mVU_FMAC15(ADD, "MADDAy"); } -mVUop(mVU_MADDAz) { mVU_FMAC15(ADD, "MADDAz"); } -mVUop(mVU_MADDAw) { mVU_FMAC15(ADD, "MADDAw"); } -mVUop(mVU_MSUB) { mVU_FMAC9 (SUB, "MSUB"); } -mVUop(mVU_MSUBi) { mVU_FMAC13(SUB, "MSUBi"); } -mVUop(mVU_MSUBq) { mVU_FMAC25(SUB, "MSUBq"); } -mVUop(mVU_MSUBx) { mVU_FMAC11(SUB, "MSUBx"); } -mVUop(mVU_MSUBy) { mVU_FMAC11(SUB, "MSUBy"); } -mVUop(mVU_MSUBz) { mVU_FMAC11(SUB, "MSUBz"); } -mVUop(mVU_MSUBw) { mVU_FMAC11(SUB, "MSUBw"); } -mVUop(mVU_MSUBA) { mVU_FMAC14(SUB, "MSUBA"); } -mVUop(mVU_MSUBAi) { mVU_FMAC16(SUB, "MSUBAi"); } -mVUop(mVU_MSUBAq) { mVU_FMAC26(SUB, "MSUBAq"); } -mVUop(mVU_MSUBAx) { mVU_FMAC15(SUB, "MSUBAx"); } -mVUop(mVU_MSUBAy) { mVU_FMAC15(SUB, "MSUBAy"); } -mVUop(mVU_MSUBAz) { mVU_FMAC15(SUB, "MSUBAz"); } -mVUop(mVU_MSUBAw) { mVU_FMAC15(SUB, "MSUBAw"); } -mVUop(mVU_MAX) { mVU_FMAC27(MAX2, "MAX"); } -mVUop(mVU_MAXi) { mVU_FMAC28(MAX2, "MAXi"); } -mVUop(mVU_MAXx) { mVU_FMAC29(MAX2, "MAXx"); } -mVUop(mVU_MAXy) { mVU_FMAC29(MAX2, "MAXy"); } -mVUop(mVU_MAXz) { mVU_FMAC29(MAX2, "MAXz"); } -mVUop(mVU_MAXw) { mVU_FMAC29(MAX2, "MAXw"); } -mVUop(mVU_MINI) { mVU_FMAC27(MIN2, "MINI"); } -mVUop(mVU_MINIi) { mVU_FMAC28(MIN2, "MINIi"); } -mVUop(mVU_MINIx) { mVU_FMAC29(MIN2, "MINIx"); } -mVUop(mVU_MINIy) { mVU_FMAC29(MIN2, "MINIy"); } -mVUop(mVU_MINIz) { mVU_FMAC29(MIN2, "MINIz"); } -mVUop(mVU_MINIw) { mVU_FMAC29(MIN2, "MINIw"); } -mVUop(mVU_OPMULA) { mVU_FMAC18(MUL, "OPMULA"); } -mVUop(mVU_OPMSUB) { mVU_FMAC19(SUB, "OPMSUB"); } -mVUop(mVU_NOP) { pass3 { mVUlog("NOP"); } } -void mVU_FTOIx(mP, uptr addr) { + +// OPMULA Opcode +mVUop(mVU_OPMULA) { + pass1 { mVUanalyzeFMAC1(mVU, 0, _Fs_, _Ft_); } + pass2 { + mVU->regAlloc->reset(); // Reset for Testing + int Fs = mVU->regAlloc->allocReg(_Fs_, 32, _X_Y_Z_W); + int Ft = mVU->regAlloc->allocReg(_Ft_, 0, _X_Y_Z_W); + + SSE2_PSHUFD_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY + SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ + SSE_MULPS_XMM_to_XMM(Fs, Ft); + mVUupdateFlags(mVU, Fs, Ft); + + mVU->regAlloc->clearNeeded(Fs); + mVU->regAlloc->clearNeeded(Ft); + mVU->regAlloc->flushAll(); // Flush All for Testing + } + pass3 { mVUlog("OPMULA"); mVUlogACC(); mVUlogFt(); } +} + +// OPMSUB Opcode +mVUop(mVU_OPMSUB) { + pass1 { mVUanalyzeFMAC1(mVU, _Fd_, _Fs_, _Ft_); } + pass2 { + mVU->regAlloc->reset(); // Reset for Testing + int Ft = mVU->regAlloc->allocReg(_Ft_); + int Fs = mVU->regAlloc->allocReg(_Fs_, 0, _X_Y_Z_W); + int ACC = mVU->regAlloc->allocReg(32, _Fd_, _X_Y_Z_W); + + SSE2_PSHUFD_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY + SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ + SSE_MULPS_XMM_to_XMM(Fs, Ft); + SSE_SUBPS_XMM_to_XMM(ACC, Fs); + mVUupdateFlags(mVU, ACC, Fs); + + mVU->regAlloc->clearNeeded(32); + mVU->regAlloc->clearNeeded(Fs); + mVU->regAlloc->clearNeeded(Ft); + mVU->regAlloc->flushAll(); // Flush All for Testing + + } + pass3 { mVUlog("OPMSUB"); mVUlogFd(); mVUlogFt(); } +} + +// FTOI0/FTIO4/FTIO12/FTIO15 Opcodes +void mVU_FTOIx(mP, uptr addr, char* opName) { pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); } pass2 { - int Fs, Ft; - mVUallocFMAC2a(mVU, Fs, Ft); + if (!_Ft_) return; + mVU->regAlloc->reset(); // Reset for Testing + int Fs = mVU->regAlloc->allocReg(_Fs_, _Ft_, _X_Y_Z_W, ((_Fs_ == _Ft_) && (_X_Y_Z_W == 0xf))); + int t1 = mVU->regAlloc->allocReg(); + int t2 = mVU->regAlloc->allocReg(); // Note: For help understanding this algorithm see recVUMI_FTOI_Saturate() - SSE_MOVAPS_XMM_to_XMM(xmmT1, Fs); + SSE_MOVAPS_XMM_to_XMM(t1, Fs); if (addr) { SSE_MULPS_M128_to_XMM(Fs, addr); } SSE2_CVTTPS2DQ_XMM_to_XMM(Fs, Fs); - SSE2_PXOR_M128_to_XMM(xmmT1, (uptr)mVU_signbit); - SSE2_PSRAD_I8_to_XMM(xmmT1, 31); - SSE_MOVAPS_XMM_to_XMM(xmmFt, Fs); - SSE2_PCMPEQD_M128_to_XMM(xmmFt, (uptr)mVU_signbit); - SSE_ANDPS_XMM_to_XMM(xmmT1, xmmFt); - SSE2_PADDD_XMM_to_XMM(Fs, xmmT1); + SSE2_PXOR_M128_to_XMM(t1, (uptr)mVU_signbit); + SSE2_PSRAD_I8_to_XMM (t1, 31); + SSE_MOVAPS_XMM_to_XMM(t2, Fs); + SSE2_PCMPEQD_M128_to_XMM(t2, (uptr)mVU_signbit); + SSE_ANDPS_XMM_to_XMM (t1, t2); + SSE2_PADDD_XMM_to_XMM(Fs, t1); - mVUallocFMAC2b(mVU, Ft); + mVU->regAlloc->clearNeeded(Fs); + mVU->regAlloc->clearNeeded(t1); + mVU->regAlloc->clearNeeded(t2); + mVU->regAlloc->flushAll(); // Flush All for Testing } + pass3 { mVUlog(opName); mVUlogFtFs(); } } -mVUop(mVU_FTOI0) { mVU_FTOIx(mX, (uptr)0); pass3 { mVUlog("FTOI0"); mVUlogFtFs(); } } -mVUop(mVU_FTOI4) { mVU_FTOIx(mX, (uptr)mVU_FTOI_4); pass3 { mVUlog("FTOI4"); mVUlogFtFs(); } } -mVUop(mVU_FTOI12) { mVU_FTOIx(mX, (uptr)mVU_FTOI_12); pass3 { mVUlog("FTOI12"); mVUlogFtFs(); } } -mVUop(mVU_FTOI15) { mVU_FTOIx(mX, (uptr)mVU_FTOI_15); pass3 { mVUlog("FTOI15"); mVUlogFtFs(); } } -void mVU_ITOFx(mP, uptr addr) { + +// ITOF0/ITOF4/ITOF12/ITOF15 Opcodes +void mVU_ITOFx(mP, uptr addr, char* opName) { pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); } pass2 { - int Fs, Ft; - mVUallocFMAC2a(mVU, Fs, Ft); - - SSE2_CVTDQ2PS_XMM_to_XMM(Ft, Fs); - if (addr) { SSE_MULPS_M128_to_XMM(Ft, addr); } - //mVUclamp2(Ft, xmmT1, 15); // Clamp (not sure if this is needed) + if (!_Ft_) return; + mVU->regAlloc->reset(); // Reset for Testing + int Fs = mVU->regAlloc->allocReg(_Fs_, _Ft_, _X_Y_Z_W, ((_Fs_ == _Ft_) && (_X_Y_Z_W == 0xf))); - mVUallocFMAC2b(mVU, Ft); + SSE2_CVTDQ2PS_XMM_to_XMM(Fs, Fs); + if (addr) { SSE_MULPS_M128_to_XMM(Fs, addr); } + //mVUclamp2(Fs, xmmT1, 15); // Clamp (not sure if this is needed) + + mVU->regAlloc->clearNeeded(Fs); + mVU->regAlloc->flushAll(); // Flush All for Testing } + pass3 { mVUlog(opName); mVUlogFtFs(); } } -mVUop(mVU_ITOF0) { mVU_ITOFx(mX, (uptr)0); pass3 { mVUlog("ITOF0"); mVUlogFtFs(); } } -mVUop(mVU_ITOF4) { mVU_ITOFx(mX, (uptr)mVU_ITOF_4); pass3 { mVUlog("ITOF4"); mVUlogFtFs(); } } -mVUop(mVU_ITOF12) { mVU_ITOFx(mX, (uptr)mVU_ITOF_12); pass3 { mVUlog("ITOF12"); mVUlogFtFs(); } } -mVUop(mVU_ITOF15) { mVU_ITOFx(mX, (uptr)mVU_ITOF_15); pass3 { mVUlog("ITOF15"); mVUlogFtFs(); } } + +// Clip Opcode mVUop(mVU_CLIP) { pass1 { mVUanalyzeFMAC4(mVU, _Fs_, _Ft_); } pass2 { - int Fs, Ft; - mVUallocFMAC17a(mVU, Fs, Ft); + mVU->regAlloc->reset(); // Reset for Testing + int Fs = mVU->regAlloc->allocReg(_Fs_); + int Ft = mVU->regAlloc->allocReg(_Ft_, 0, 1); + int t1 = mVU->regAlloc->allocReg(); + + mVUunpack_xyzw(Ft, Ft, 0); mVUallocCFLAGa(mVU, gprT1, cFLAG.lastWrite); SHL32ItoR(gprT1, 6); SSE_ANDPS_M128_to_XMM(Ft, (uptr)mVU_absclip); - SSE_MOVAPS_XMM_to_XMM(xmmT1, Ft); - SSE_ORPS_M128_to_XMM(xmmT1, (uptr)mVU_signbit); + SSE_MOVAPS_XMM_to_XMM(t1, Ft); + SSE_ORPS_M128_to_XMM(t1, (uptr)mVU_signbit); - SSE_CMPNLEPS_XMM_to_XMM(xmmT1, Fs); //-w, -z, -y, -x - SSE_CMPLTPS_XMM_to_XMM(Ft, Fs); //+w, +z, +y, +x + SSE_CMPNLEPS_XMM_to_XMM(t1, Fs); // -w, -z, -y, -x + SSE_CMPLTPS_XMM_to_XMM(Ft, Fs); // +w, +z, +y, +x - SSE_MOVAPS_XMM_to_XMM(Fs, Ft); //Fs = +w, +z, +y, +x - SSE_UNPCKLPS_XMM_to_XMM(Ft, xmmT1); //Ft = -y,+y,-x,+x - SSE_UNPCKHPS_XMM_to_XMM(Fs, xmmT1); //Fs = -w,+w,-z,+z + SSE_MOVAPS_XMM_to_XMM(Fs, Ft); // Fs = +w, +z, +y, +x + SSE_UNPCKLPS_XMM_to_XMM(Ft, t1); // Ft = -y,+y,-x,+x + SSE_UNPCKHPS_XMM_to_XMM(Fs, t1); // Fs = -w,+w,-z,+z SSE_MOVMSKPS_XMM_to_R32(gprT2, Fs); // -w,+w,-z,+z AND32ItoR(gprT2, 0x3); @@ -610,7 +416,106 @@ mVUop(mVU_CLIP) { AND32ItoR(gprT1, 0xffffff); mVUallocCFLAGb(mVU, gprT1, cFLAG.write); + mVU->regAlloc->clearNeeded(Fs); + mVU->regAlloc->clearNeeded(Ft); + mVU->regAlloc->clearNeeded(t1); + mVU->regAlloc->flushAll(); // Flush All for Testing } pass3 { mVUlog("CLIP"); mVUlogCLIP(); } } +//------------------------------------------------------------------ +// Micro VU Micromode Upper instructions +//------------------------------------------------------------------ + +mVUop(mVU_ADD) { mVU_FMACa(mVU, recPass, 1, 0, 0, "ADD"); } +mVUop(mVU_ADDi) { mVU_FMACa(mVU, recPass, 3, 0, 0, "ADDi"); } +mVUop(mVU_ADDq) { mVU_FMACa(mVU, recPass, 4, 0, 0, "ADDq"); } +mVUop(mVU_ADDx) { mVU_FMACa(mVU, recPass, 2, 0, 0, "ADDx"); } +mVUop(mVU_ADDy) { mVU_FMACa(mVU, recPass, 2, 0, 0, "ADDy"); } +mVUop(mVU_ADDz) { mVU_FMACa(mVU, recPass, 2, 0, 0, "ADDz"); } +mVUop(mVU_ADDw) { mVU_FMACa(mVU, recPass, 2, 0, 0, "ADDw"); } +mVUop(mVU_ADDA) { mVU_FMACa(mVU, recPass, 1, 0, 1, "ADDA"); } +mVUop(mVU_ADDAi) { mVU_FMACa(mVU, recPass, 3, 0, 1, "ADDAi"); } +mVUop(mVU_ADDAq) { mVU_FMACa(mVU, recPass, 4, 0, 1, "ADDAq"); } +mVUop(mVU_ADDAx) { mVU_FMACa(mVU, recPass, 2, 0, 1, "ADDAx"); } +mVUop(mVU_ADDAy) { mVU_FMACa(mVU, recPass, 2, 0, 1, "ADDAy"); } +mVUop(mVU_ADDAz) { mVU_FMACa(mVU, recPass, 2, 0, 1, "ADDAz"); } +mVUop(mVU_ADDAw) { mVU_FMACa(mVU, recPass, 2, 0, 1, "ADDAw"); } +mVUop(mVU_SUB) { mVU_FMACa(mVU, recPass, 1, 1, 0, "SUB"); } +mVUop(mVU_SUBi) { mVU_FMACa(mVU, recPass, 3, 1, 0, "SUBi"); } +mVUop(mVU_SUBq) { mVU_FMACa(mVU, recPass, 4, 1, 0, "SUBq"); } +mVUop(mVU_SUBx) { mVU_FMACa(mVU, recPass, 2, 1, 0, "SUBx"); } +mVUop(mVU_SUBy) { mVU_FMACa(mVU, recPass, 2, 1, 0, "SUBy"); } +mVUop(mVU_SUBz) { mVU_FMACa(mVU, recPass, 2, 1, 0, "SUBz"); } +mVUop(mVU_SUBw) { mVU_FMACa(mVU, recPass, 2, 1, 0, "SUBw"); } +mVUop(mVU_SUBA) { mVU_FMACa(mVU, recPass, 1, 1, 1, "SUBA"); } +mVUop(mVU_SUBAi) { mVU_FMACa(mVU, recPass, 3, 1, 1, "SUBAi"); } +mVUop(mVU_SUBAq) { mVU_FMACa(mVU, recPass, 4, 1, 1, "SUBAq"); } +mVUop(mVU_SUBAx) { mVU_FMACa(mVU, recPass, 2, 1, 1, "SUBAx"); } +mVUop(mVU_SUBAy) { mVU_FMACa(mVU, recPass, 2, 1, 1, "SUBAy"); } +mVUop(mVU_SUBAz) { mVU_FMACa(mVU, recPass, 2, 1, 1, "SUBAz"); } +mVUop(mVU_SUBAw) { mVU_FMACa(mVU, recPass, 2, 1, 1, "SUBAw"); } +mVUop(mVU_MUL) { mVU_FMACa(mVU, recPass, 1, 2, 0, "MUL"); } +mVUop(mVU_MULi) { mVU_FMACa(mVU, recPass, 3, 2, 0, "MULi"); } +mVUop(mVU_MULq) { mVU_FMACa(mVU, recPass, 4, 2, 0, "MULq"); } +mVUop(mVU_MULx) { mVU_FMACa(mVU, recPass, 2, 2, 0, "MULx"); } +mVUop(mVU_MULy) { mVU_FMACa(mVU, recPass, 2, 2, 0, "MULy"); } +mVUop(mVU_MULz) { mVU_FMACa(mVU, recPass, 2, 2, 0, "MULz"); } +mVUop(mVU_MULw) { mVU_FMACa(mVU, recPass, 2, 2, 0, "MULw"); } +mVUop(mVU_MULA) { mVU_FMACa(mVU, recPass, 1, 2, 1, "MULA"); } +mVUop(mVU_MULAi) { mVU_FMACa(mVU, recPass, 3, 2, 1, "MULAi"); } +mVUop(mVU_MULAq) { mVU_FMACa(mVU, recPass, 4, 2, 1, "MULAq"); } +mVUop(mVU_MULAx) { mVU_FMACa(mVU, recPass, 2, 2, 1, "MULAx"); } +mVUop(mVU_MULAy) { mVU_FMACa(mVU, recPass, 2, 2, 1, "MULAy"); } +mVUop(mVU_MULAz) { mVU_FMACa(mVU, recPass, 2, 2, 1, "MULAz"); } +mVUop(mVU_MULAw) { mVU_FMACa(mVU, recPass, 2, 2, 1, "MULAw"); } +mVUop(mVU_MADD) { mVU_FMACc(mVU, recPass, 1, "MADD"); } +mVUop(mVU_MADDi) { mVU_FMACc(mVU, recPass, 3, "MADDi"); } +mVUop(mVU_MADDq) { mVU_FMACc(mVU, recPass, 4, "MADDq"); } +mVUop(mVU_MADDx) { mVU_FMACc(mVU, recPass, 2, "MADDx"); } +mVUop(mVU_MADDy) { mVU_FMACc(mVU, recPass, 2, "MADDy"); } +mVUop(mVU_MADDz) { mVU_FMACc(mVU, recPass, 2, "MADDz"); } +mVUop(mVU_MADDw) { mVU_FMACc(mVU, recPass, 2, "MADDw"); } +mVUop(mVU_MADDA) { mVU_FMACb(mVU, recPass, 1, 0, "MADDA"); } +mVUop(mVU_MADDAi) { mVU_FMACb(mVU, recPass, 3, 0, "MADDAi"); } +mVUop(mVU_MADDAq) { mVU_FMACb(mVU, recPass, 4, 0, "MADDAq"); } +mVUop(mVU_MADDAx) { mVU_FMACb(mVU, recPass, 2, 0, "MADDAx"); } +mVUop(mVU_MADDAy) { mVU_FMACb(mVU, recPass, 2, 0, "MADDAy"); } +mVUop(mVU_MADDAz) { mVU_FMACb(mVU, recPass, 2, 0, "MADDAz"); } +mVUop(mVU_MADDAw) { mVU_FMACb(mVU, recPass, 2, 0, "MADDAw"); } +mVUop(mVU_MSUB) { mVU_FMACd(mVU, recPass, 1, "MSUB"); } +mVUop(mVU_MSUBi) { mVU_FMACd(mVU, recPass, 3, "MSUBi"); } +mVUop(mVU_MSUBq) { mVU_FMACd(mVU, recPass, 4, "MSUBq"); } +mVUop(mVU_MSUBx) { mVU_FMACd(mVU, recPass, 2, "MSUBx"); } +mVUop(mVU_MSUBy) { mVU_FMACd(mVU, recPass, 2, "MSUBy"); } +mVUop(mVU_MSUBz) { mVU_FMACd(mVU, recPass, 2, "MSUBz"); } +mVUop(mVU_MSUBw) { mVU_FMACd(mVU, recPass, 2, "MSUBw"); } +mVUop(mVU_MSUBA) { mVU_FMACb(mVU, recPass, 1, 1, "MSUBA"); } +mVUop(mVU_MSUBAi) { mVU_FMACb(mVU, recPass, 3, 1, "MSUBAi"); } +mVUop(mVU_MSUBAq) { mVU_FMACb(mVU, recPass, 4, 1, "MSUBAq"); } +mVUop(mVU_MSUBAx) { mVU_FMACb(mVU, recPass, 2, 1, "MSUBAx"); } +mVUop(mVU_MSUBAy) { mVU_FMACb(mVU, recPass, 2, 1, "MSUBAy"); } +mVUop(mVU_MSUBAz) { mVU_FMACb(mVU, recPass, 2, 1, "MSUBAz"); } +mVUop(mVU_MSUBAw) { mVU_FMACb(mVU, recPass, 2, 1, "MSUBAw"); } +mVUop(mVU_MAX) { mVU_FMACa(mVU, recPass, 1, 3, 0, "MAX"); } +mVUop(mVU_MAXi) { mVU_FMACa(mVU, recPass, 3, 3, 0, "MAXi"); } +mVUop(mVU_MAXx) { mVU_FMACa(mVU, recPass, 2, 3, 0, "MAXx"); } +mVUop(mVU_MAXy) { mVU_FMACa(mVU, recPass, 2, 3, 0, "MAXy"); } +mVUop(mVU_MAXz) { mVU_FMACa(mVU, recPass, 2, 3, 0, "MAXz"); } +mVUop(mVU_MAXw) { mVU_FMACa(mVU, recPass, 2, 3, 0, "MAXw"); } +mVUop(mVU_MINI) { mVU_FMACa(mVU, recPass, 1, 4, 0, "MINI"); } +mVUop(mVU_MINIi) { mVU_FMACa(mVU, recPass, 3, 4, 0, "MINIi"); } +mVUop(mVU_MINIx) { mVU_FMACa(mVU, recPass, 2, 4, 0, "MINIx"); } +mVUop(mVU_MINIy) { mVU_FMACa(mVU, recPass, 2, 4, 0, "MINIy"); } +mVUop(mVU_MINIz) { mVU_FMACa(mVU, recPass, 2, 4, 0, "MINIz"); } +mVUop(mVU_MINIw) { mVU_FMACa(mVU, recPass, 2, 4, 0, "MINIw"); } +mVUop(mVU_FTOI0) { mVU_FTOIx(mX, (uptr)0, "FTOI0"); } +mVUop(mVU_FTOI4) { mVU_FTOIx(mX, (uptr)mVU_FTOI_4, "FTOI4"); } +mVUop(mVU_FTOI12) { mVU_FTOIx(mX, (uptr)mVU_FTOI_12, "FTOI12"); } +mVUop(mVU_FTOI15) { mVU_FTOIx(mX, (uptr)mVU_FTOI_15, "FTOI15"); } +mVUop(mVU_ITOF0) { mVU_ITOFx(mX, (uptr)0, "ITOF0"); } +mVUop(mVU_ITOF4) { mVU_ITOFx(mX, (uptr)mVU_ITOF_4, "ITOF4"); } +mVUop(mVU_ITOF12) { mVU_ITOFx(mX, (uptr)mVU_ITOF_12, "ITOF12"); } +mVUop(mVU_ITOF15) { mVU_ITOFx(mX, (uptr)mVU_ITOF_15, "ITOF15"); } +mVUop(mVU_NOP) { pass3 { mVUlog("NOP"); } } diff --git a/plugins/GSdx/GPURenderer.cpp b/plugins/GSdx/GPURenderer.cpp index 9e3f5e1607..670c9d9c92 100644 --- a/plugins/GSdx/GPURenderer.cpp +++ b/plugins/GSdx/GPURenderer.cpp @@ -162,7 +162,7 @@ void GPURenderer::VSync() GetClientRect(m_hWnd, r); - m_dev->Present(r.fit(m_aspectratio), 0); + m_dev->Present(r.fit(m_aspectratio), 0, true); } bool GPURenderer::MakeSnapshot(const string& path) diff --git a/plugins/GSdx/GPUSettingsDlg.cpp b/plugins/GSdx/GPUSettingsDlg.cpp index 815a6d77f8..c0656c6cfb 100644 --- a/plugins/GSdx/GPUSettingsDlg.cpp +++ b/plugins/GSdx/GPUSettingsDlg.cpp @@ -81,7 +81,7 @@ void GPUSettingsDlg::OnInit() memset(&mode, 0, sizeof(mode)); m_modes.push_back(mode); - ComboBoxAppend(IDC_RESOLUTION, "Windowed", (LPARAM)&m_modes.back(), true); + ComboBoxAppend(IDC_RESOLUTION, "Please select...", (LPARAM)&m_modes.back(), true); if(CComPtr d3d = Direct3DCreate9(D3D_SDK_VERSION)) { @@ -124,6 +124,8 @@ void GPUSettingsDlg::OnInit() ComboBoxInit(IDC_ASPECTRATIO, g_aspectratio, countof(g_aspectratio), theApp.GetConfig("AspectRatio", 1)); ComboBoxInit(IDC_SCALE, g_scale, countof(g_scale), theApp.GetConfig("scale_x", 0) | (theApp.GetConfig("scale_y", 0) << 2)); + CheckDlgButton(m_hWnd, IDC_WINDOWED, theApp.GetConfig("windowed", 1)); + SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETRANGE, 0, MAKELPARAM(16, 1)); SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_SETPOS, 0, MAKELPARAM(theApp.GetConfig("swthreads", 1), 0)); @@ -176,6 +178,7 @@ bool GPUSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) } theApp.SetConfig("swthreads", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SWTHREADS), UDM_GETPOS, 0, 0)); + theApp.SetConfig("windowed", (int)IsDlgButtonChecked(m_hWnd, IDC_WINDOWED)); } return __super::OnCommand(hWnd, id, code); diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index f7751d5d33..20dc3aee96 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -139,7 +139,10 @@ static INT32 GSopen(void* dsp, char* title, int mt, int renderer) case 13: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceNull()); break; } - if(!s_gs->Create(title)) + int w = theApp.GetConfig("ModeWidth", 0); + int h = theApp.GetConfig("ModeHeight", 0); + + if(!s_gs->Create(title, w, h)) { GSclose(); @@ -291,7 +294,7 @@ EXPORT_C GSsetGameCRC(uint32 crc, int options) s_gs->SetGameCRC(crc, options); } -EXPORT_C GSgetLastTag(uint32* tag) +EXPORT_C GSgetLastTag(uint32* tag) { s_gs->GetLastTag(tag); } @@ -301,6 +304,11 @@ EXPORT_C GSsetFrameSkip(int frameskip) s_gs->SetFrameSkip(frameskip); } +EXPORT_C GSsetFrameLimit(int limit) +{ + s_gs->SetFrameLimit(limit != 0); +} + #ifdef _WINDOWS EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) @@ -527,11 +535,13 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow fprintf(file, "%6d %6d | ", (int)((float)trlen * n / (end - start) / 1000), (int)((float)(w * h) * n / (end - start) / 1000)); + const GSOffset* o = mem.GetOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM); + start = clock(); for(int j = 0; j < n; j++) { - (mem.*rtx)(r, ptr, w * 4, TEX0, TEXA); + (mem.*rtx)(o, r, ptr, w * 4, TEXA); } end = clock(); @@ -544,7 +554,7 @@ EXPORT_C GSBenchmark(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow for(int j = 0; j < n; j++) { - (mem.*rtxP)(r, ptr, w, TEX0, TEXA); + (mem.*rtxP)(o, r, ptr, w, TEXA); } end = clock(); diff --git a/plugins/GSdx/GS.h b/plugins/GSdx/GS.h index 885ae92db8..352e38da44 100644 --- a/plugins/GSdx/GS.h +++ b/plugins/GSdx/GS.h @@ -815,42 +815,11 @@ REG64_(GIFReg, TEX1) uint32 _PAD2:9; uint32 L:2; uint32 _PAD3:11; - uint32 K:12; + int32 K:12; // 1:7:4 uint32 _PAD4:20; REG_END2 - bool IsMinLinear() const {return (MMIN == 1) || (MMIN & 4);} bool IsMagLinear() const {return MMAG;} - - bool IsLinear() const - { - bool mmin = IsMinLinear(); - bool mmag = IsMagLinear(); - - return !LCM ? mmag || mmin : K <= 0 ? mmag : mmin; - } - - bool IsLinear(float qmin, float qmax) const - { - bool mmin = IsMinLinear(); - bool mmag = IsMagLinear(); - - if(mmag == mmin) return mmag; - - float LODmin = K; - float LODmax = K; - - if(!LCM) - { - float f = (float)(1 << L) / log(2.0f); - - LODmin += log(1.0f / abs(qmax)) * f; - LODmax += log(1.0f / abs(qmin)) * f; - } - - return LODmax <= 0 ? mmag : LODmin > 0 ? mmin : mmag || mmin; - } - REG_END2 REG64_(GIFReg, TEX2) diff --git a/plugins/GSdx/GSClut.cpp b/plugins/GSdx/GSClut.cpp index e147e82185..426e8ba153 100644 --- a/plugins/GSdx/GSClut.cpp +++ b/plugins/GSdx/GSClut.cpp @@ -168,16 +168,16 @@ void GSClut::WriteCLUT16S_I4_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& T template void GSClut::WriteCLUT32_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - GSLocalMemory::PixelOffset* po = m_mem->GetPixelOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT32); + GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT32); - uint32* RESTRICT s = &m_mem->m_vm32[po->row[TEXCLUT.COV]]; - int* RESTRICT o = &po->col[0][TEXCLUT.COU << 4]; + uint32* RESTRICT s = &m_mem->m_vm32[o->pixel.row[TEXCLUT.COV]]; + int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - uint32 c = s[o[i]]; + uint32 c = s[col[i]]; clut[i] = (uint16)(c & 0xffff); clut[i + 256] = (uint16)(c >> 16); @@ -186,31 +186,31 @@ template void GSClut::WriteCLUT32_CSM2(const GIFRegTEX0& TEX0, const GIFR template void GSClut::WriteCLUT16_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - GSLocalMemory::PixelOffset* po = m_mem->GetPixelOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16); + GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16); - uint16* RESTRICT s = &m_mem->m_vm16[po->row[TEXCLUT.COV]]; - int* RESTRICT o = &po->col[0][TEXCLUT.COU << 4]; + uint16* RESTRICT s = &m_mem->m_vm16[o->pixel.row[TEXCLUT.COV]]; + int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - clut[i] = s[o[i]]; + clut[i] = s[col[i]]; } } template void GSClut::WriteCLUT16S_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT) { - GSLocalMemory::PixelOffset* po = m_mem->GetPixelOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16S); + GSOffset* o = m_mem->GetOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16S); - uint16* RESTRICT s = &m_mem->m_vm16[po->row[TEXCLUT.COV]]; - int* RESTRICT o = &po->col[0][TEXCLUT.COU << 4]; + uint16* RESTRICT s = &m_mem->m_vm16[o->pixel.row[TEXCLUT.COV]]; + int* RESTRICT col = &o->pixel.col[0][TEXCLUT.COU << 4]; uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4); for(int i = 0; i < n; i++) { - clut[i] = s[o[i]]; + clut[i] = s[col[i]]; } } @@ -314,43 +314,56 @@ void GSClut::GetAlphaMinMax32(int& amin, int& amax) { m_read.adirty = false; - // uint32 bpp = GSLocalMemory::m_psm[m_read.TEX0.PSM].trbpp; - uint32 cbpp = GSLocalMemory::m_psm[m_read.TEX0.CPSM].trbpp; - uint32 pal = GSLocalMemory::m_psm[m_read.TEX0.PSM].pal; - - if(cbpp == 24 && m_read.TEXA.AEM == 0) + if(GSLocalMemory::m_psm[m_read.TEX0.CPSM].trbpp == 24 && m_read.TEXA.AEM == 0) { m_read.amin = m_read.TEXA.TA0; m_read.amax = m_read.TEXA.TA0; } else { - int amin = 255; - int amax = 0; - const GSVector4i* p = (const GSVector4i*)m_buff32; - for(int i = 0, j = pal >> 4; i < j; i++) + GSVector4i amin, amax; + + if(GSLocalMemory::m_psm[m_read.TEX0.PSM].pal == 256) { - GSVector4i v0 = (p[i * 4 + 0] >> 24).ps32(p[i * 4 + 1] >> 24); - GSVector4i v1 = (p[i * 4 + 2] >> 24).ps32(p[i * 4 + 3] >> 24); + amin = GSVector4i::xffffffff(); + amax = GSVector4i::zero(); - GSVector4i v2 = v0.min_i16(v1); - GSVector4i v3 = v0.max_i16(v1); + for(int i = 0; i < 16; i++) + { + GSVector4i v0 = (p[i * 4 + 0] >> 24).ps32(p[i * 4 + 1] >> 24); + GSVector4i v1 = (p[i * 4 + 2] >> 24).ps32(p[i * 4 + 3] >> 24); + GSVector4i v2 = v0.pu16(v1); - v2 = v2.min_i16(v2.zwxy()); - v3 = v3.max_i16(v3.zwxy()); - v2 = v2.min_i16(v2.zwxyl()); - v3 = v3.max_i16(v3.zwxyl()); - v2 = v2.min_i16(v2.yxwzl()); - v3 = v3.max_i16(v3.yxwzl()); + amin = amin.min_u8(v2); + amax = amax.max_u8(v2); + } + } + else + { + ASSERT(GSLocalMemory::m_psm[m_read.TEX0.PSM].pal == 16); - amin = min(amin, v2.extract16<0>()); - amax = max(amax, v3.extract16<0>()); + GSVector4i v0 = (p[0] >> 24).ps32(p[1] >> 24); + GSVector4i v1 = (p[2] >> 24).ps32(p[3] >> 24); + GSVector4i v2 = v0.pu16(v1); + + amin = v2; + amax = v2; } - m_read.amin = amin; - m_read.amax = amax; + amin = amin.min_u8(amin.zwxy()); + amax = amax.max_u8(amax.zwxy()); + amin = amin.min_u8(amin.zwxyl()); + amax = amax.max_u8(amax.zwxyl()); + amin = amin.min_u8(amin.yxwzl()); + amax = amax.max_u8(amax.yxwzl()); + + GSVector4i v0 = amin.upl8(amax).u8to16(); + GSVector4i v1 = v0.yxwz(); + + m_read.amin = v0.min_i16(v1).extract16<0>(); + m_read.amax = v0.max_i16(v1).extract16<1>(); } } @@ -381,14 +394,13 @@ __forceinline void GSClut::WriteCLUT_T32_I4_CSM1(const uint32* RESTRICT src, uin GSVector4i v2 = s[2]; GSVector4i v3 = s[3]; - GSVector4i::sw64(v0, v1, v2, v3); GSVector4i::sw16(v0, v1, v2, v3); + GSVector4i::sw32(v0, v1, v2, v3); GSVector4i::sw16(v0, v2, v1, v3); - GSVector4i::sw16(v0, v1, v2, v3); d[0] = v0; - d[1] = v1; - d[32] = v2; + d[1] = v2; + d[32] = v1; d[33] = v3; } diff --git a/plugins/GSdx/GSCrc.cpp b/plugins/GSdx/GSCrc.cpp index f95cabb957..09a7b756cb 100644 --- a/plugins/GSdx/GSCrc.cpp +++ b/plugins/GSdx/GSCrc.cpp @@ -88,7 +88,8 @@ CRC::Game CRC::m_games[] = {0xC19A374E, SoTC, US, 0}, {0x7D8F539A, SoTC, EU, 0}, {0x3122B508, OnePieceGrandAdventure, US, 0}, - {0x8DF14A24, OnePieceGrandAdventure, Unknown, 0}, + {0x8DF14A24, OnePieceGrandAdventure, EU, 0}, + {0xB049DD5E, OnePieceGrandBattle, US, 0}, {0x5D02CC5B, OnePieceGrandBattle, Unknown, 0}, {0x6F8545DB, ICO, US, 0}, {0xB01A4C95, ICO, JP, 0}, @@ -147,6 +148,7 @@ CRC::Game CRC::m_games[] = {0x04CCB600, ValkyrieProfile2, EU, 0}, {0x47B9B2FD, RadiataStories, US, 0}, {0xE8FCF8EC, SMTNocturne, US, ZWriteMustNotClear}, // saves/reloads z buffer around shadow drawing + {0x0B8AB37B, RozenMaidenGebetGarden, JP, 0}, }; hash_map CRC::m_map; diff --git a/plugins/GSdx/GSCrc.h b/plugins/GSdx/GSCrc.h index d6c1da82d9..1f0cb7f260 100644 --- a/plugins/GSdx/GSCrc.h +++ b/plugins/GSdx/GSCrc.h @@ -76,6 +76,7 @@ public: ValkyrieProfile2, RadiataStories, SMTNocturne, + RozenMaidenGebetGarden, TitleCount, }; @@ -91,7 +92,8 @@ public: DE, IT, ES, - ASIA + ASIA, + RegionCount, }; enum Flags @@ -102,8 +104,8 @@ public: struct Game { - uint32 crc; - Title title; + uint32 crc; + Title title; Region region; uint32 flags; }; diff --git a/plugins/GSdx/GSDevice.cpp b/plugins/GSdx/GSDevice.cpp index 38de81de65..648b44216b 100644 --- a/plugins/GSdx/GSDevice.cpp +++ b/plugins/GSdx/GSDevice.cpp @@ -75,14 +75,14 @@ bool GSDevice::Reset(int w, int h, int mode) return true; } -void GSDevice::Present(const GSVector4i& r, int shader) +void GSDevice::Present(const GSVector4i& r, int shader, bool limit) { GSVector4i cr = m_wnd->GetClientRect(); int w = std::max(cr.width(), 1); int h = std::max(cr.height(), 1); - if(!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h) + if(!m_backbuffer || m_backbuffer->m_size.x != w || m_backbuffer->m_size.y != h) { if(!Reset(w, h, DontCare)) { @@ -99,7 +99,7 @@ void GSDevice::Present(const GSVector4i& r, int shader) StretchRect(m_current, m_backbuffer, GSVector4(r), s_shader[shader]); } - Flip(); + Flip(limit); } GSTexture* GSDevice::Fetch(int type, int w, int h, int format) @@ -240,7 +240,7 @@ bool GSDevice::ResizeTexture(GSTexture** t, int w, int h) GSTexture* t2 = *t; - if(t2 == NULL || t2->GetWidth() != w || t2->GetHeight() != h) + if(t2 == NULL || t2->m_size.x != w || t2->m_size.y != h) { delete t2; @@ -251,3 +251,46 @@ bool GSDevice::ResizeTexture(GSTexture** t, int w, int h) return t2 != NULL; } + +bool GSDevice::SetFeatureLevel(D3D_FEATURE_LEVEL level, bool compat_mode) +{ + m_shader.level = level; + + switch(level) + { + case D3D_FEATURE_LEVEL_9_1: + case D3D_FEATURE_LEVEL_9_2: + m_shader.model = "0x200"; + m_shader.vs = compat_mode ? "vs_4_0_level_9_1" : "vs_2_0"; + m_shader.ps = compat_mode ? "ps_4_0_level_9_1" : "ps_2_0"; + break; + case D3D_FEATURE_LEVEL_9_3: + m_shader.model = "0x300"; + m_shader.vs = compat_mode ? "vs_4_0_level_9_3" : "vs_3_0"; + m_shader.ps = compat_mode ? "ps_4_0_level_9_3" : "ps_3_0"; + break; + case D3D_FEATURE_LEVEL_10_0: + m_shader.model = "0x400"; + m_shader.vs = "vs_4_0"; + m_shader.gs = "gs_4_0"; + m_shader.ps = "ps_4_0"; + break; + case D3D_FEATURE_LEVEL_10_1: + m_shader.model = "0x401"; + m_shader.vs = "vs_4_1"; + m_shader.gs = "gs_4_1"; + m_shader.ps = "ps_4_1"; + break; + case D3D_FEATURE_LEVEL_11_0: + m_shader.model = "0x500"; + m_shader.vs = "vs_5_0"; + m_shader.gs = "gs_5_0"; + m_shader.ps = "ps_5_0"; + break; + default: + ASSERT(0); + return false; + } + + return true; +} diff --git a/plugins/GSdx/GSDevice.h b/plugins/GSdx/GSDevice.h index 00540b907d..087e49edfc 100644 --- a/plugins/GSdx/GSDevice.h +++ b/plugins/GSdx/GSDevice.h @@ -62,6 +62,7 @@ protected: GSTexture* m_blend; GSTexture* m_1x1; GSTexture* m_current; + struct {D3D_FEATURE_LEVEL level; string model, vs, gs, ps;} m_shader; virtual GSTexture* Create(int type, int w, int h, int format) = 0; @@ -79,8 +80,8 @@ public: virtual bool Create(GSWnd* wnd, bool vsync); virtual bool Reset(int w, int h, int mode); virtual bool IsLost(bool update = false) {return false;} - virtual void Present(const GSVector4i& r, int shader); - virtual void Flip() {} + virtual void Present(const GSVector4i& r, int shader, bool limit); + virtual void Flip(bool limit) {} virtual void BeginScene() {} virtual void DrawPrimitive() {}; @@ -103,6 +104,9 @@ public: virtual void StretchRect(GSTexture* st, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true); virtual void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true) {} + virtual void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) {} + virtual void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL) {} + GSTexture* GetCurrent(); void Merge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, const GSVector2i& fs, bool slbg, bool mmod, const GSVector4& c); @@ -112,7 +116,7 @@ public: bool IsRBSwapped() {return m_rbswapped;} - template void PrepareShaderMacro(vector& dst, const T* src, const char* model) + template void PrepareShaderMacro(vector& dst, const T* src) { dst.clear(); @@ -124,7 +128,7 @@ public: T m; m.Name = "SHADER_MODEL"; - m.Definition = model; + m.Definition = m_shader.model.c_str(); dst.push_back(m); @@ -133,4 +137,6 @@ public: dst.push_back(m); } + + bool SetFeatureLevel(D3D_FEATURE_LEVEL level, bool compat_mode); // TODO: GSDeviceDX }; diff --git a/plugins/GSdx/GSDevice10.cpp b/plugins/GSdx/GSDevice10.cpp index 58e110aaf1..a8d832631b 100644 --- a/plugins/GSdx/GSDevice10.cpp +++ b/plugins/GSdx/GSDevice10.cpp @@ -87,12 +87,33 @@ bool GSDevice10::Create(GSWnd* wnd, bool vsync) scd.Windowed = TRUE; uint32 flags = 0; - + flags = D3D10_CREATE_DEVICE_SINGLETHREADED; //disables thread safety, should be fine (speedup) #ifdef DEBUG flags |= D3D10_CREATE_DEVICE_DEBUG; #endif - hr = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_SDK_VERSION, &scd, &m_swapchain, &m_dev); + D3D10_FEATURE_LEVEL1 levels[] = + { + D3D10_FEATURE_LEVEL_10_1, + D3D10_FEATURE_LEVEL_10_0 + }; + + for(int i = 0; i < countof(levels); i++) + { + hr = D3D10CreateDeviceAndSwapChain1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, levels[i], D3D10_1_SDK_VERSION, &scd, &m_swapchain, &m_dev); + + if(SUCCEEDED(hr)) + { + if(!SetFeatureLevel((D3D_FEATURE_LEVEL)levels[i], true)) + { + return false; + } + + break; + } + } + + // hr = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_SDK_VERSION, &scd, &m_swapchain, &m_dev); if(FAILED(hr)) return false; @@ -219,21 +240,24 @@ bool GSDevice10::Reset(int w, int h, int mode) if(!__super::Reset(w, h, mode)) return false; - DXGI_SWAP_CHAIN_DESC scd; - memset(&scd, 0, sizeof(scd)); - m_swapchain->GetDesc(&scd); - m_swapchain->ResizeBuffers(scd.BufferCount, w, h, scd.BufferDesc.Format, 0); - - CComPtr backbuffer; - m_swapchain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)&backbuffer); - m_backbuffer = new GSTexture10(backbuffer); + if(m_swapchain) + { + DXGI_SWAP_CHAIN_DESC scd; + memset(&scd, 0, sizeof(scd)); + m_swapchain->GetDesc(&scd); + m_swapchain->ResizeBuffers(scd.BufferCount, w, h, scd.BufferDesc.Format, 0); + + CComPtr backbuffer; + m_swapchain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)&backbuffer); + m_backbuffer = new GSTexture10(backbuffer); + } return true; } -void GSDevice10::Flip() +void GSDevice10::Flip(bool limit) { - m_swapchain->Present(m_vsync ? 1 : 0, 0); + m_swapchain->Present(m_vsync && limit ? 1 : 0, 0); } void GSDevice10::BeginScene() @@ -454,10 +478,6 @@ void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); PSSetShaderResources(st, NULL); - // rs - - RSSet(ds.x, ds.y); - // DrawPrimitive(); @@ -560,12 +580,12 @@ void GSDevice10::IASetVertexBuffer(ID3D10Buffer* vb, size_t stride) { if(m_vb != vb || m_vb_stride != stride) { + m_vb = vb; + m_vb_stride = stride; + uint32 offset = 0; m_dev->IASetVertexBuffers(0, 1, &vb, &stride, &offset); - - m_vb = vb; - m_vb_stride = stride; } } @@ -573,9 +593,9 @@ void GSDevice10::IASetInputLayout(ID3D10InputLayout* layout) { if(m_layout != layout) { - m_dev->IASetInputLayout(layout); - m_layout = layout; + + m_dev->IASetInputLayout(layout); } } @@ -583,9 +603,9 @@ void GSDevice10::IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY topology) { if(m_topology != topology) { - m_dev->IASetPrimitiveTopology(topology); - m_topology = topology; + + m_dev->IASetPrimitiveTopology(topology); } } @@ -593,16 +613,16 @@ void GSDevice10::VSSetShader(ID3D10VertexShader* vs, ID3D10Buffer* vs_cb) { if(m_vs != vs) { - m_dev->VSSetShader(vs); - m_vs = vs; + + m_dev->VSSetShader(vs); } if(m_vs_cb != vs_cb) { - m_dev->VSSetConstantBuffers(0, 1, &vs_cb); - m_vs_cb = vs_cb; + + m_dev->VSSetConstantBuffers(0, 1, &vs_cb); } } @@ -610,9 +630,9 @@ void GSDevice10::GSSetShader(ID3D10GeometryShader* gs) { if(m_gs != gs) { - m_dev->GSSetShader(gs); - m_gs = gs; + + m_dev->GSSetShader(gs); } } @@ -626,12 +646,12 @@ void GSDevice10::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) if(m_ps_srv[0] != srv0 || m_ps_srv[1] != srv1) { + m_ps_srv[0] = srv0; + m_ps_srv[1] = srv1; + ID3D10ShaderResourceView* srvs[] = {srv0, srv1}; m_dev->PSSetShaderResources(0, 2, srvs); - - m_ps_srv[0] = srv0; - m_ps_srv[1] = srv1; } } @@ -639,16 +659,16 @@ void GSDevice10::PSSetShader(ID3D10PixelShader* ps, ID3D10Buffer* ps_cb) { if(m_ps != ps) { - m_dev->PSSetShader(ps); - m_ps = ps; + + m_dev->PSSetShader(ps); } if(m_ps_cb != ps_cb) { - m_dev->PSSetConstantBuffers(0, 1, &ps_cb); - m_ps_cb = ps_cb; + + m_dev->PSSetConstantBuffers(0, 1, &ps_cb); } } @@ -656,42 +676,12 @@ void GSDevice10::PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState* { if(m_ps_ss[0] != ss0 || m_ps_ss[1] != ss1) { + m_ps_ss[0] = ss0; + m_ps_ss[1] = ss1; + ID3D10SamplerState* sss[] = {ss0, ss1}; m_dev->PSSetSamplers(0, 2, sss); - - m_ps_ss[0] = ss0; - m_ps_ss[1] = ss1; - } -} - -void GSDevice10::RSSet(int width, int height, const GSVector4i* scissor) -{ - if(m_viewport.x != width || m_viewport.y != height) - { - D3D10_VIEWPORT vp; - - memset(&vp, 0, sizeof(vp)); - - vp.TopLeftX = 0; - vp.TopLeftY = 0; - vp.Width = width; - vp.Height = height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - - m_dev->RSSetViewports(1, &vp); - - m_viewport = GSVector2i(width, height); - } - - GSVector4i r = scissor ? *scissor : GSVector4i(0, 0, width, height); - - if(!m_scissor.eq(r)) - { - m_dev->RSSetScissorRects(1, r); - - m_scissor = r; } } @@ -699,10 +689,10 @@ void GSDevice10::OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref { if(m_dss != dss || m_sref != sref) { - m_dev->OMSetDepthStencilState(dss, sref); - m_dss = dss; m_sref = sref; + + m_dev->OMSetDepthStencilState(dss, sref); } } @@ -710,16 +700,16 @@ void GSDevice10::OMSetBlendState(ID3D10BlendState* bs, float bf) { if(m_bs != bs || m_bf != bf) { + m_bs = bs; + m_bf = bf; + float BlendFactor[] = {bf, bf, bf, 0}; m_dev->OMSetBlendState(bs, BlendFactor, 0xffffffff); - - m_bs = bs; - m_bf = bf; } } -void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) +void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor) { ID3D10RenderTargetView* rtv = NULL; ID3D10DepthStencilView* dsv = NULL; @@ -729,10 +719,37 @@ void GSDevice10::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) if(m_rtv != rtv || m_dsv != dsv) { - m_dev->OMSetRenderTargets(1, &rtv, dsv); - m_rtv = rtv; m_dsv = dsv; + + m_dev->OMSetRenderTargets(1, &rtv, dsv); + } + + if(m_viewport != rt->m_size) + { + m_viewport = rt->m_size; + + D3D10_VIEWPORT vp; + + memset(&vp, 0, sizeof(vp)); + + vp.TopLeftX = 0; + vp.TopLeftY = 0; + vp.Width = rt->m_size.x; + vp.Height = rt->m_size.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + + m_dev->RSSetViewports(1, &vp); + } + + GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy(); + + if(!m_scissor.eq(r)) + { + m_scissor = r; + + m_dev->RSSetScissorRects(1, r); } } @@ -742,11 +759,11 @@ HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_M vector m; - PrepareShaderMacro(m, macro, "0x400"); + PrepareShaderMacro(m, macro); CComPtr shader, error; - hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), "vs_4_0", 0, 0, NULL, &shader, &error, NULL); + hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.vs.c_str(), 0, 0, NULL, &shader, &error, NULL); if(error) { @@ -781,11 +798,11 @@ HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_M vector m; - PrepareShaderMacro(m, macro, "0x400"); + PrepareShaderMacro(m, macro); CComPtr shader, error; - hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), "gs_4_0", 0, 0, NULL, &shader, &error, NULL); + hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.gs.c_str(), 0, 0, NULL, &shader, &error, NULL); if(error) { @@ -813,11 +830,11 @@ HRESULT GSDevice10::CompileShader(uint32 id, const string& entry, D3D10_SHADER_M vector m; - PrepareShaderMacro(m, macro, "0x400"); + PrepareShaderMacro(m, macro); CComPtr shader, error; - hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), "ps_4_0", 0, 0, NULL, &shader, &error, NULL); + hr = D3DX10CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry.c_str(), m_shader.ps.c_str(), 0, 0, NULL, &shader, &error, NULL); if(error) { diff --git a/plugins/GSdx/GSDevice10.h b/plugins/GSdx/GSDevice10.h index f6b75617aa..49fd700a2c 100644 --- a/plugins/GSdx/GSDevice10.h +++ b/plugins/GSdx/GSDevice10.h @@ -55,7 +55,7 @@ class GSDevice10 : public GSDevice // - CComPtr m_dev; + CComPtr m_dev; CComPtr m_swapchain; struct @@ -97,7 +97,7 @@ public: bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, int mode); - void Flip(); + void Flip(bool limit); void BeginScene(); void DrawPrimitive(); @@ -130,10 +130,9 @@ public: void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1); void PSSetShader(ID3D10PixelShader* ps, ID3D10Buffer* ps_cb); void PSSetSamplerState(ID3D10SamplerState* ss0, ID3D10SamplerState* ss1); - void RSSet(int width, int height, const GSVector4i* scissor = NULL); void OMSetDepthStencilState(ID3D10DepthStencilState* dss, uint8 sref); void OMSetBlendState(ID3D10BlendState* bs, float bf); - void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); + void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL); ID3D10Device* operator->() {return m_dev;} operator ID3D10Device*() {return m_dev;} diff --git a/plugins/GSdx/GSDevice11.cpp b/plugins/GSdx/GSDevice11.cpp index febf6ca108..aa6547dd45 100644 --- a/plugins/GSdx/GSDevice11.cpp +++ b/plugins/GSdx/GSDevice11.cpp @@ -87,53 +87,34 @@ bool GSDevice11::Create(GSWnd* wnd, bool vsync) scd.Windowed = TRUE; uint32 flags = 0; - + flags = D3D11_CREATE_DEVICE_SINGLETHREADED; //disables thread safety, should be fine (speedup) #ifdef DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif - hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &m_level, &m_ctx); - // hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &m_level, &m_ctx); + D3D_FEATURE_LEVEL levels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + }; + + D3D_FEATURE_LEVEL level; + + hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); + // hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); if(FAILED(hr)) return false; + if(!SetFeatureLevel(level, true)) + { + return false; + } + D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS options; hr = m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &options, sizeof(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS)); - switch(m_level) - { - case D3D_FEATURE_LEVEL_9_1: - case D3D_FEATURE_LEVEL_9_2: - m_shader.model = "0x200"; - m_shader.vs = "vs_4_0_level_9_1"; - m_shader.ps = "ps_4_0_level_9_1"; - break; - case D3D_FEATURE_LEVEL_9_3: - m_shader.model = "0x300"; - m_shader.vs = "vs_4_0_level_9_3"; - m_shader.ps = "ps_4_0_level_9_3"; - break; - case D3D_FEATURE_LEVEL_10_0: - case D3D_FEATURE_LEVEL_10_1: - m_shader.model = "0x400"; - m_shader.vs = "vs_4_0"; - m_shader.gs = "gs_4_0"; - m_shader.ps = "ps_4_0"; - break; - case D3D_FEATURE_LEVEL_11_0: - m_shader.model = "0x500"; - m_shader.vs = "vs_5_0"; - m_shader.gs = "gs_5_0"; - m_shader.ps = "ps_5_0"; - break; - } - - if(m_level < D3D_FEATURE_LEVEL_10_0) - { - return false; - } - // convert D3D11_INPUT_ELEMENT_DESC il_convert[] = @@ -256,21 +237,24 @@ bool GSDevice11::Reset(int w, int h, int mode) if(!__super::Reset(w, h, mode)) return false; - DXGI_SWAP_CHAIN_DESC scd; - memset(&scd, 0, sizeof(scd)); - m_swapchain->GetDesc(&scd); - m_swapchain->ResizeBuffers(scd.BufferCount, w, h, scd.BufferDesc.Format, 0); - - CComPtr backbuffer; - m_swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backbuffer); - m_backbuffer = new GSTexture11(backbuffer); + if(m_swapchain) + { + DXGI_SWAP_CHAIN_DESC scd; + memset(&scd, 0, sizeof(scd)); + m_swapchain->GetDesc(&scd); + m_swapchain->ResizeBuffers(scd.BufferCount, w, h, scd.BufferDesc.Format, 0); + + CComPtr backbuffer; + m_swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backbuffer); + m_backbuffer = new GSTexture11(backbuffer); + } return true; } -void GSDevice11::Flip() +void GSDevice11::Flip(bool limit) { - m_swapchain->Present(m_vsync ? 1 : 0, 0); + m_swapchain->Present(m_vsync && limit ? 1 : 0, 0); } void GSDevice11::BeginScene() @@ -491,10 +475,6 @@ void GSDevice11::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL); PSSetShaderResources(st, NULL); - // rs - - RSSet(ds.x, ds.y); - // DrawPrimitive(); @@ -597,12 +577,12 @@ void GSDevice11::IASetVertexBuffer(ID3D11Buffer* vb, size_t stride) { if(m_vb != vb || m_vb_stride != stride) { + m_vb = vb; + m_vb_stride = stride; + uint32 offset = 0; m_ctx->IASetVertexBuffers(0, 1, &vb, &stride, &offset); - - m_vb = vb; - m_vb_stride = stride; } } @@ -610,9 +590,9 @@ void GSDevice11::IASetInputLayout(ID3D11InputLayout* layout) { if(m_layout != layout) { - m_ctx->IASetInputLayout(layout); - m_layout = layout; + + m_ctx->IASetInputLayout(layout); } } @@ -620,9 +600,9 @@ void GSDevice11::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology) { if(m_topology != topology) { - m_ctx->IASetPrimitiveTopology(topology); - m_topology = topology; + + m_ctx->IASetPrimitiveTopology(topology); } } @@ -630,16 +610,16 @@ void GSDevice11::VSSetShader(ID3D11VertexShader* vs, ID3D11Buffer* vs_cb) { if(m_vs != vs) { - m_ctx->VSSetShader(vs, NULL, 0); - m_vs = vs; + + m_ctx->VSSetShader(vs, NULL, 0); } if(m_vs_cb != vs_cb) { - m_ctx->VSSetConstantBuffers(0, 1, &vs_cb); - m_vs_cb = vs_cb; + + m_ctx->VSSetConstantBuffers(0, 1, &vs_cb); } } @@ -663,12 +643,12 @@ void GSDevice11::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) if(m_ps_srv[0] != srv0 || m_ps_srv[1] != srv1) { + m_ps_srv[0] = srv0; + m_ps_srv[1] = srv1; + ID3D11ShaderResourceView* srvs[] = {srv0, srv1}; m_ctx->PSSetShaderResources(0, 2, srvs); - - m_ps_srv[0] = srv0; - m_ps_srv[1] = srv1; } } @@ -676,16 +656,16 @@ void GSDevice11::PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb) { if(m_ps != ps) { - m_ctx->PSSetShader(ps, NULL, 0); - m_ps = ps; + + m_ctx->PSSetShader(ps, NULL, 0); } if(m_ps_cb != ps_cb) { - m_ctx->PSSetConstantBuffers(0, 1, &ps_cb); - m_ps_cb = ps_cb; + + m_ctx->PSSetConstantBuffers(0, 1, &ps_cb); } } @@ -693,42 +673,12 @@ void GSDevice11::PSSetSamplerState(ID3D11SamplerState* ss0, ID3D11SamplerState* { if(m_ps_ss[0] != ss0 || m_ps_ss[1] != ss1) { + m_ps_ss[0] = ss0; + m_ps_ss[1] = ss1; + ID3D11SamplerState* sss[] = {ss0, ss1}; m_ctx->PSSetSamplers(0, 2, sss); - - m_ps_ss[0] = ss0; - m_ps_ss[1] = ss1; - } -} - -void GSDevice11::RSSet(int width, int height, const GSVector4i* scissor) -{ - if(m_viewport.x != width || m_viewport.y != height) - { - D3D11_VIEWPORT vp; - - memset(&vp, 0, sizeof(vp)); - - vp.TopLeftX = 0; - vp.TopLeftY = 0; - vp.Width = width; - vp.Height = height; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - - m_ctx->RSSetViewports(1, &vp); - - m_viewport = GSVector2i(width, height); - } - - GSVector4i r = scissor ? *scissor : GSVector4i(0, 0, width, height); - - if(!m_scissor.eq(r)) - { - m_ctx->RSSetScissorRects(1, r); - - m_scissor = r; } } @@ -756,7 +706,7 @@ void GSDevice11::OMSetBlendState(ID3D11BlendState* bs, float bf) } } -void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) +void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor) { ID3D11RenderTargetView* rtv = NULL; ID3D11DepthStencilView* dsv = NULL; @@ -766,10 +716,37 @@ void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) if(m_rtv != rtv || m_dsv != dsv) { - m_ctx->OMSetRenderTargets(1, &rtv, dsv); - m_rtv = rtv; m_dsv = dsv; + + m_ctx->OMSetRenderTargets(1, &rtv, dsv); + } + + if(m_viewport != rt->m_size) + { + m_viewport = rt->m_size; + + D3D11_VIEWPORT vp; + + memset(&vp, 0, sizeof(vp)); + + vp.TopLeftX = 0; + vp.TopLeftY = 0; + vp.Width = rt->m_size.x; + vp.Height = rt->m_size.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + + m_ctx->RSSetViewports(1, &vp); + } + + GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy(); + + if(!m_scissor.eq(r)) + { + m_scissor = r; + + m_ctx->RSSetScissorRects(1, r); } } @@ -779,7 +756,7 @@ HRESULT GSDevice11::CompileShader(uint32 id, const string& entry, D3D11_SHADER_M vector m; - PrepareShaderMacro(m, macro, m_shader.model.c_str()); + PrepareShaderMacro(m, macro); CComPtr shader, error; @@ -818,7 +795,7 @@ HRESULT GSDevice11::CompileShader(uint32 id, const string& entry, D3D11_SHADER_M vector m; - PrepareShaderMacro(m, macro, m_shader.model.c_str()); + PrepareShaderMacro(m, macro); CComPtr shader, error; @@ -850,7 +827,7 @@ HRESULT GSDevice11::CompileShader(uint32 id, const string& entry, D3D11_SHADER_M vector m; - PrepareShaderMacro(m, macro, m_shader.model.c_str()); + PrepareShaderMacro(m, macro); CComPtr shader, error; diff --git a/plugins/GSdx/GSDevice11.h b/plugins/GSdx/GSDevice11.h index 76595af0f4..523e7ba301 100644 --- a/plugins/GSdx/GSDevice11.h +++ b/plugins/GSdx/GSDevice11.h @@ -55,11 +55,9 @@ class GSDevice11 : public GSDevice // - D3D_FEATURE_LEVEL m_level; CComPtr m_dev; CComPtr m_ctx; CComPtr m_swapchain; - struct {string model, vs, gs, ps;} m_shader; struct { @@ -100,7 +98,7 @@ public: bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, int mode); - void Flip(); + void Flip(bool limit); void BeginScene(); void DrawPrimitive(); @@ -133,10 +131,9 @@ public: void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1); void PSSetShader(ID3D11PixelShader* ps, ID3D11Buffer* ps_cb); void PSSetSamplerState(ID3D11SamplerState* ss0, ID3D11SamplerState* ss1); - void RSSet(int width, int height, const GSVector4i* scissor = NULL); void OMSetDepthStencilState(ID3D11DepthStencilState* dss, uint8 sref); void OMSetBlendState(ID3D11BlendState* bs, float bf); - void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); + void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL); ID3D11Device* operator->() {return m_dev;} operator ID3D11Device*() {return m_dev;} diff --git a/plugins/GSdx/GSDevice7.cpp b/plugins/GSdx/GSDevice7.cpp index 255de0f331..1f769ec92d 100644 --- a/plugins/GSdx/GSDevice7.cpp +++ b/plugins/GSdx/GSDevice7.cpp @@ -136,7 +136,7 @@ bool GSDevice7::Reset(int w, int h, int mode) return true; } -void GSDevice7::Present(const GSVector4i& r, int shader) +void GSDevice7::Present(const GSVector4i& r, int shader, bool limit) { HRESULT hr; @@ -145,7 +145,7 @@ void GSDevice7::Present(const GSVector4i& r, int shader) int w = std::max(cr.width(), 1); int h = std::max(cr.height(), 1); - if(!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h) + if(!m_backbuffer || m_backbuffer->m_size.x != w || m_backbuffer->m_size.y != h) { if(!Reset(w, h, DontCare)) { @@ -177,7 +177,7 @@ void GSDevice7::Present(const GSVector4i& r, int shader) MapWindowPoints((HWND)m_wnd->GetHandle(), HWND_DESKTOP, (POINT*)&r2, 2); - if(m_vsync) + if(m_vsync && limit) { hr = m_dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL); } diff --git a/plugins/GSdx/GSDevice7.h b/plugins/GSdx/GSDevice7.h index 43bbf2a5b9..baa2caf9ad 100644 --- a/plugins/GSdx/GSDevice7.h +++ b/plugins/GSdx/GSDevice7.h @@ -43,5 +43,5 @@ public: bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, int mode); bool IsLost(bool update) {return m_lost;} - void Present(const GSVector4i& r, int shader); + void Present(const GSVector4i& r, int shader, bool limit); }; diff --git a/plugins/GSdx/GSDevice9.cpp b/plugins/GSdx/GSDevice9.cpp index c6e79069a6..0889fb51e1 100644 --- a/plugins/GSdx/GSDevice9.cpp +++ b/plugins/GSdx/GSDevice9.cpp @@ -108,13 +108,26 @@ bool GSDevice9::Create(GSWnd* wnd, bool vsync) m_d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_d3dcaps); - if(!Reset(1, 1, theApp.GetConfig("ModeWidth", 0) > 0 ? Fullscreen : Windowed)) return false; + // - m_dev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); + if(m_d3dcaps.VertexShaderVersion < (m_d3dcaps.PixelShaderVersion & ~0x10000)) + { + ASSERT(0); - // shaders + return false; + } - if(m_d3dcaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) + m_d3dcaps.VertexShaderVersion = m_d3dcaps.PixelShaderVersion & ~0x10000; + + if(m_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) + { + SetFeatureLevel(D3D_FEATURE_LEVEL_9_3, false); + } + else if(m_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) + { + SetFeatureLevel(D3D_FEATURE_LEVEL_9_2, false); + } + else { string s = format( "Supported pixel shader version is too low!\n\nSupported: %d.%d\nNeeded: 2.0 or higher", @@ -125,6 +138,15 @@ bool GSDevice9::Create(GSWnd* wnd, bool vsync) return false; } + // + + if(!Reset(1, 1, theApp.GetConfig("windowed", 1) ? Windowed : Fullscreen)) + { + return false; + } + + m_dev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); + // convert static const D3DVERTEXELEMENT9 il_convert[] = @@ -282,7 +304,8 @@ bool GSDevice9::Reset(int w, int h, int mode) if(!m_dev) { - uint32 flags = D3DCREATE_MULTITHREADED | (m_d3dcaps.VertexProcessingCaps ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING); + //D3DCREATE_MULTITHREADED flag shouldn't be needed + uint32 flags = m_d3dcaps.VertexProcessingCaps ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING; hr = m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, (HWND)m_wnd->GetHandle(), flags, &m_pp, &m_dev); @@ -348,7 +371,7 @@ bool GSDevice9::IsLost(bool update) return m_lost; } -void GSDevice9::Flip() +void GSDevice9::Flip(bool limit) { m_dev->EndScene(); @@ -427,7 +450,7 @@ void GSDevice9::ClearRenderTarget(GSTexture* rt, uint32 c) void GSDevice9::ClearDepth(GSTexture* t, float c) { - GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight()); + GSTexture* rt = CreateRenderTarget(t->m_size.x, t->m_size.y); CComPtr rtsurface; CComPtr dssurface; @@ -448,7 +471,7 @@ void GSDevice9::ClearDepth(GSTexture* t, float c) void GSDevice9::ClearStencil(GSTexture* t, uint8 c) { - GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight()); + GSTexture* rt = CreateRenderTarget(t->m_size.x, t->m_size.y); CComPtr rtsurface; CComPtr dssurface; @@ -635,10 +658,6 @@ void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, c PSSetSamplerState(linear ? &m_convert.ln : &m_convert.pt); PSSetShaderResources(st, NULL); - // rs - - RSSet(ds.x, ds.y); - // DrawPrimitive(); @@ -732,10 +751,10 @@ void GSDevice9::IASetVertexBuffer(IDirect3DVertexBuffer9* vb, size_t stride) { if(m_vb != vb || m_vb_stride != stride) { - m_dev->SetStreamSource(0, vb, 0, stride); - m_vb = vb; m_vb_stride = stride; + + m_dev->SetStreamSource(0, vb, 0, stride); } } @@ -743,9 +762,9 @@ void GSDevice9::IASetInputLayout(IDirect3DVertexDeclaration9* layout) { if(m_layout != layout) { - m_dev->SetVertexDeclaration(layout); - m_layout = layout; + + m_dev->SetVertexDeclaration(layout); } } @@ -758,9 +777,9 @@ void GSDevice9::VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int { if(m_vs != vs) { - m_dev->SetVertexShader(vs); - m_vs = vs; + + m_dev->SetVertexShader(vs); } if(vs_cb && vs_cb_len > 0) @@ -776,11 +795,11 @@ void GSDevice9::VSSetShader(IDirect3DVertexShader9* vs, const float* vs_cb, int m_vs_cb = (float*)_aligned_malloc(size, 16); } + m_vs_cb_len = vs_cb_len; + memcpy(m_vs_cb, vs_cb, size); m_dev->SetVertexShaderConstantF(0, vs_cb, vs_cb_len); - - m_vs_cb_len = vs_cb_len; } } } @@ -795,16 +814,16 @@ void GSDevice9::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) if(m_ps_srvs[0] != srv0) { - m_dev->SetTexture(0, srv0); - m_ps_srvs[0] = srv0; + + m_dev->SetTexture(0, srv0); } if(m_ps_srvs[1] != srv1) { - m_dev->SetTexture(1, srv1); - m_ps_srvs[1] = srv1; + + m_dev->SetTexture(1, srv1); } } @@ -812,9 +831,9 @@ void GSDevice9::PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int p { if(m_ps != ps) { - m_dev->SetPixelShader(ps); - m_ps = ps; + + m_dev->SetPixelShader(ps); } if(ps_cb && ps_cb_len > 0) @@ -830,11 +849,11 @@ void GSDevice9::PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int p m_ps_cb = (float*)_aligned_malloc(size, 16); } + m_ps_cb_len = ps_cb_len; + memcpy(m_ps_cb, ps_cb, size); m_dev->SetPixelShaderConstantF(0, ps_cb, ps_cb_len); - - m_ps_cb_len = ps_cb_len; } } } @@ -843,6 +862,7 @@ void GSDevice9::PSSetSamplerState(Direct3DSamplerState9* ss) { if(ss && m_ps_ss != ss) { + m_ps_ss = ss; m_dev->SetSamplerState(0, D3DSAMP_ADDRESSU, ss->AddressU); m_dev->SetSamplerState(0, D3DSAMP_ADDRESSV, ss->AddressV); @@ -860,20 +880,6 @@ void GSDevice9::PSSetSamplerState(Direct3DSamplerState9* ss) m_dev->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_POINT); m_dev->SetSamplerState(3, D3DSAMP_MINFILTER, D3DTEXF_POINT); m_dev->SetSamplerState(3, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - - m_ps_ss = ss; - } -} - -void GSDevice9::RSSet(int width, int height, const GSVector4i* scissor) -{ - GSVector4i r = scissor ? *scissor : GSVector4i(0, 0, width, height); - - if(!m_scissor.eq(r)) - { - m_dev->SetScissorRect(r); - - m_scissor = r; } } @@ -881,6 +887,8 @@ void GSDevice9::OMSetDepthStencilState(Direct3DDepthStencilState9* dss) { if(m_dss != dss) { + m_dss = dss; + m_dev->SetRenderState(D3DRS_ZENABLE, dss->DepthEnable); m_dev->SetRenderState(D3DRS_ZWRITEENABLE, dss->DepthWriteMask); @@ -901,8 +909,6 @@ void GSDevice9::OMSetDepthStencilState(Direct3DDepthStencilState9* dss) m_dev->SetRenderState(D3DRS_STENCILZFAIL, dss->StencilDepthFailOp); m_dev->SetRenderState(D3DRS_STENCILREF, dss->StencilRef); } - - m_dss = dss; } } @@ -910,6 +916,9 @@ void GSDevice9::OMSetBlendState(Direct3DBlendState9* bs, uint32 bf) { if(m_bs != bs || m_bf != bf) { + m_bs = bs; + m_bf = bf; + m_dev->SetRenderState(D3DRS_ALPHABLENDENABLE, bs->BlendEnable); if(bs->BlendEnable) @@ -925,13 +934,10 @@ void GSDevice9::OMSetBlendState(Direct3DBlendState9* bs, uint32 bf) } m_dev->SetRenderState(D3DRS_COLORWRITEENABLE, bs->RenderTargetWriteMask); - - m_bs = bs; - m_bf = bf; } } -void GSDevice9::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) +void GSDevice9::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor) { IDirect3DSurface9* rtv = NULL; IDirect3DSurface9* dsv = NULL; @@ -941,16 +947,25 @@ void GSDevice9::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) if(m_rtv != rtv) { - m_dev->SetRenderTarget(0, rtv); - m_rtv = rtv; + + m_dev->SetRenderTarget(0, rtv); } if(m_dsv != dsv) { - m_dev->SetDepthStencilSurface(dsv); - m_dsv = dsv; + + m_dev->SetDepthStencilSurface(dsv); + } + + GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy(); + + if(!m_scissor.eq(r)) + { + m_scissor = r; + + m_dev->SetScissorRect(r); } } @@ -979,27 +994,9 @@ static HRESULT LoadShader(uint32 id, LPCSTR& data, uint32& size) HRESULT GSDevice9::CompileShader(uint32 id, const string& entry, const D3DXMACRO* macro, IDirect3DVertexShader9** vs, const D3DVERTEXELEMENT9* layout, int count, IDirect3DVertexDeclaration9** il) { - const char* target; - const char* model; - - if(m_d3dcaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) - { - target = "vs_3_0"; - model = "0x300"; - } - else if(m_d3dcaps.VertexShaderVersion >= D3DVS_VERSION(2, 0)) - { - target = "vs_2_0"; - model = "0x200"; - } - else - { - return E_FAIL; - } - vector m; - PrepareShaderMacro(m, macro, model); + PrepareShaderMacro(m, macro); HRESULT hr; @@ -1014,7 +1011,7 @@ HRESULT GSDevice9::CompileShader(uint32 id, const string& entry, const D3DXMACRO if(FAILED(hr)) return E_FAIL; - hr = D3DXCompileShader(data, size, &m[0], NULL, entry.c_str(), target, 0, &shader, &error, NULL); + hr = D3DXCompileShader(data, size, &m[0], NULL, entry.c_str(), m_shader.vs.c_str(), 0, &shader, &error, NULL); if(SUCCEEDED(hr)) { @@ -1044,29 +1041,16 @@ HRESULT GSDevice9::CompileShader(uint32 id, const string& entry, const D3DXMACRO HRESULT GSDevice9::CompileShader(uint32 id, const string& entry, const D3DXMACRO* macro, IDirect3DPixelShader9** ps) { - const char* target = NULL; - const char* model; uint32 flags = 0; - if(m_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) + if(m_shader.level >= D3D_FEATURE_LEVEL_9_3) { - target = "ps_3_0"; - model = "0x300"; flags |= D3DXSHADER_AVOID_FLOW_CONTROL; } - else if(m_d3dcaps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) - { - target = "ps_2_0"; - model = "0x200"; - } - else - { - return false; - } vector m; - PrepareShaderMacro(m, macro, model); + PrepareShaderMacro(m, macro); HRESULT hr; @@ -1081,7 +1065,7 @@ HRESULT GSDevice9::CompileShader(uint32 id, const string& entry, const D3DXMACRO if(FAILED(hr)) return E_FAIL; - hr = D3DXCompileShader(data, size, &m[0], NULL, entry.c_str(), target, 0, &shader, &error, NULL); + hr = D3DXCompileShader(data, size, &m[0], NULL, entry.c_str(), m_shader.ps.c_str(), 0, &shader, &error, NULL); if(SUCCEEDED(hr)) { diff --git a/plugins/GSdx/GSDevice9.h b/plugins/GSdx/GSDevice9.h index ee9156b11b..bee59f70ea 100644 --- a/plugins/GSdx/GSDevice9.h +++ b/plugins/GSdx/GSDevice9.h @@ -135,7 +135,7 @@ public: bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, int mode); bool IsLost(bool update); - void Flip(); + void Flip(bool limit); void BeginScene(); void DrawPrimitive(); @@ -167,10 +167,9 @@ public: void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1); void PSSetShader(IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len); void PSSetSamplerState(Direct3DSamplerState9* ss); - void RSSet(int width, int height, const GSVector4i* scissor = NULL); void OMSetDepthStencilState(Direct3DDepthStencilState9* dss); void OMSetBlendState(Direct3DBlendState9* bs, uint32 bf); - void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); + void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL); IDirect3DDevice9* operator->() {return m_dev;} operator IDirect3DDevice9*() {return m_dev;} diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 7489fe0394..26c6e70139 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -185,16 +185,16 @@ bool GSDeviceOGL::Reset(int w, int h, int mode) return true; } -void GSDeviceOGL::Present(const GSVector4i& r, int shader) +void GSDeviceOGL::Present(const GSVector4i& r, int shader, bool limit) { glBindFramebuffer(GL_FRAMEBUFFER, 0); CheckError(); // TODO: m_current => backbuffer - Flip(); + Flip(limit); } -void GSDeviceOGL::Flip() +void GSDeviceOGL::Flip(bool limit) { #ifdef _WINDOWS @@ -406,10 +406,17 @@ void GSDeviceOGL::IASetPrimitiveTopology(int topology) m_topology = topology; } +void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1) +{ + // TODO +} + void GSDeviceOGL::PSSetSamplerState(SamplerStateOGL* ss) { if(ss && m_ps_ss != ss) { + m_ps_ss = ss; + glActiveTexture(GL_TEXTURE0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ss->wrap.s); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, ss->wrap.t); @@ -433,27 +440,6 @@ void GSDeviceOGL::PSSetSamplerState(SamplerStateOGL* ss) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_POINT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_POINT); - - m_ps_ss = ss; - } -} - -void GSDeviceOGL::RSSet(int width, int height, const GSVector4i* scissor) -{ - if(m_viewport.x != width || m_viewport.y != height) - { - glViewport(0, 0, width, height); CheckError(); - - m_viewport = GSVector2i(width, height); - } - - GSVector4i r = scissor ? *scissor : GSVector4i(0, 0, width, height); - - if(!m_scissor.eq(r)) - { - glScissor(r.left, r.top, r.width(), r.height()); CheckError(); - - m_scissor = r; } } @@ -461,6 +447,8 @@ void GSDeviceOGL::OMSetDepthStencilState(DepthStencilStateOGL* dss) { if(m_dss != dss) { + m_dss = dss; + if(dss->depth.enable) { glEnable(GL_DEPTH_TEST); CheckError(); @@ -483,8 +471,6 @@ void GSDeviceOGL::OMSetDepthStencilState(DepthStencilStateOGL* dss) { glDisable(GL_STENCIL_TEST); CheckError(); } - - m_dss = dss; } } @@ -492,6 +478,9 @@ void GSDeviceOGL::OMSetBlendState(BlendStateOGL* bs, float bf) { if(m_bs != bs || m_bf != bf) { + m_bs = bs; + m_bf = bf; + if(bs->enable) { glEnable(GL_BLEND); CheckError(); @@ -505,13 +494,10 @@ void GSDeviceOGL::OMSetBlendState(BlendStateOGL* bs, float bf) } glColorMask(bs->mask.r, bs->mask.g, bs->mask.b, bs->mask.a); CheckError(); - - m_bs = bs; - m_bf = bf; } } -void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) +void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor) { GLuint rti = 0; GLuint dsi = 0; @@ -521,15 +507,31 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds) if(m_rt != rti) { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rti); CheckError(); - m_rt = rti; + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rti); CheckError(); } if(m_ds != dsi) { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, dsi); CheckError(); - m_ds = dsi; + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, dsi); CheckError(); + } + + if(m_viewport != rt->m_size) + { + m_viewport = rt->m_size; + + glViewport(0, 0, rt->m_size.x, rt->m_size.y); CheckError(); + } + + GSVector4i r = scissor ? *scissor : GSVector4i(rt->m_size).zwxy(); + + if(!m_scissor.eq(r)) + { + m_scissor = r; + + glScissor(r.left, r.top, r.width(), r.height()); CheckError(); } } diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index 0dc5bba890..10d58a9138 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -111,8 +111,8 @@ public: bool Create(GSWnd* wnd, bool vsync); bool Reset(int w, int h, int mode); - void Present(const GSVector4i& r, int shader); - void Flip(); + void Present(const GSVector4i& r, int shader, bool limit); + void Flip(bool limit); void BeginScene(); void DrawPrimitive(); @@ -138,11 +138,11 @@ public: void IASetInputLayout(); // TODO void IASetPrimitiveTopology(int topology); + void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1); void PSSetSamplerState(SamplerStateOGL* ss); - void RSSet(int width, int height, const GSVector4i* scissor); void OMSetDepthStencilState(DepthStencilStateOGL* dss); void OMSetBlendState(BlendStateOGL* bs, float bf); - void OMSetRenderTargets(GSTexture* rt, GSTexture* ds); + void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL); static void CheckError() { diff --git a/plugins/GSdx/GSDrawScanline.cpp b/plugins/GSdx/GSDrawScanline.cpp index ac0e5da73d..152e6bc156 100644 --- a/plugins/GSdx/GSDrawScanline.cpp +++ b/plugins/GSdx/GSDrawScanline.cpp @@ -46,10 +46,10 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f) m_sel = p->sel; m_env.vm = p->vm; - m_env.fbr = p->fbo->row; - m_env.zbr = p->zbo->row; - m_env.fbc = p->fbo->col[0]; - m_env.zbc = p->zbo->col[0]; + m_env.fbr = p->fbo->pixel.row; + m_env.zbr = p->zbo->pixel.row; + m_env.fbc = p->fbo->pixel.col[0]; + m_env.zbc = p->zbo->pixel.col[0]; m_env.fzbr = p->fzbo->row; m_env.fzbc = p->fzbo->col; m_env.fm = GSVector4i(p->fm); diff --git a/plugins/GSdx/GSDrawingContext.h b/plugins/GSdx/GSDrawingContext.h index 75e4b73ce8..91f9e4ec92 100644 --- a/plugins/GSdx/GSDrawingContext.h +++ b/plugins/GSdx/GSDrawingContext.h @@ -51,8 +51,18 @@ public: GSVector4 ex; } scissor; + struct + { + GSOffset* fb; + GSOffset* zb; + GSOffset* tex; + GSPixelOffset4* fzb; + } offset; + GSDrawingContext() { + memset(&offset, 0, sizeof(offset)); + Reset(); } diff --git a/plugins/GSdx/GSLocalMemory.cpp b/plugins/GSdx/GSLocalMemory.cpp index d62a37b114..411c214c04 100644 --- a/plugins/GSdx/GSLocalMemory.cpp +++ b/plugins/GSdx/GSLocalMemory.cpp @@ -30,18 +30,17 @@ #define ASSERT_BLOCK(r, w, h) \ ASSERT((r).width() >= w && (r).height() >= h && !((r).left & (w - 1)) && !((r).top & (h - 1)) && !((r).right & (w - 1)) && !((r).bottom & (h - 1))); \ -#define FOREACH_BLOCK_START(r, w, h, bpp, psm) \ +#define FOREACH_BLOCK_START(r, w, h, bpp) \ ASSERT_BLOCK(r, w, h); \ - const GSLocalMemory::BlockOffset* RESTRICT _bo = GetBlockOffset(TEX0.TBP0, TEX0.TBW, psm); \ GSVector4i _r = r >> 3; \ uint8* _dst = dst - _r.left * bpp; \ int _offset = dstpitch * h; \ for(int y = _r.top; y < _r.bottom; y += h >> 3, _dst += _offset) \ { \ - uint32 _base = _bo->row[y]; \ + uint32 _base = o->block.row[y]; \ for(int x = _r.left; x < _r.right; x += w >> 3) \ { \ - const uint8* src = BlockPtr(_base + _bo->col[x]); \ + const uint8* src = BlockPtr(_base + o->block.col[x]); \ uint8* dst = &_dst[x * bpp]; \ #define FOREACH_BLOCK_END }} @@ -66,14 +65,14 @@ int GSLocalMemory::rowOffset16SZ[2048]; int GSLocalMemory::rowOffset8[2][2048]; int GSLocalMemory::rowOffset4[2][2048]; -int GSLocalMemory::blockOffset32[256]; -int GSLocalMemory::blockOffset32Z[256]; -int GSLocalMemory::blockOffset16[256]; -int GSLocalMemory::blockOffset16S[256]; -int GSLocalMemory::blockOffset16Z[256]; -int GSLocalMemory::blockOffset16SZ[256]; -int GSLocalMemory::blockOffset8[256]; -int GSLocalMemory::blockOffset4[256]; +short GSLocalMemory::blockOffset32[256]; +short GSLocalMemory::blockOffset32Z[256]; +short GSLocalMemory::blockOffset16[256]; +short GSLocalMemory::blockOffset16S[256]; +short GSLocalMemory::blockOffset16Z[256]; +short GSLocalMemory::blockOffset16SZ[256]; +short GSLocalMemory::blockOffset8[256]; +short GSLocalMemory::blockOffset4[256]; // @@ -159,42 +158,42 @@ GSLocalMemory::GSLocalMemory() for(int x = 0; x < countof(blockOffset32); x++) { - blockOffset32[x] = (int)BlockNumber32(x << 3, 0, 0, 32) - (int)BlockNumber32(0, 0, 0, 32); + blockOffset32[x] = (short)((int)BlockNumber32(x << 3, 0, 0, 32) - (int)BlockNumber32(0, 0, 0, 32)); } for(int x = 0; x < countof(blockOffset32Z); x++) { - blockOffset32Z[x] = (int)BlockNumber32Z(x << 3, 0, 0, 32) - (int)BlockNumber32Z(0, 0, 0, 32); + blockOffset32Z[x] = (short)((int)BlockNumber32Z(x << 3, 0, 0, 32) - (int)BlockNumber32Z(0, 0, 0, 32)); } for(int x = 0; x < countof(blockOffset16); x++) { - blockOffset16[x] = (int)BlockNumber16(x << 3, 0, 0, 32) - (int)BlockNumber16(0, 0, 0, 32); + blockOffset16[x] = (short)((int)BlockNumber16(x << 3, 0, 0, 32) - (int)BlockNumber16(0, 0, 0, 32)); } for(int x = 0; x < countof(blockOffset16S); x++) { - blockOffset16S[x] = (int)BlockNumber16S(x << 3, 0, 0, 32) - (int)BlockNumber16S(0, 0, 0, 32); + blockOffset16S[x] = (short)((int)BlockNumber16S(x << 3, 0, 0, 32) - (int)BlockNumber16S(0, 0, 0, 32)); } for(int x = 0; x < countof(blockOffset16Z); x++) { - blockOffset16Z[x] = (int)BlockNumber16Z(x << 3, 0, 0, 32) - (int)BlockNumber16Z(0, 0, 0, 32); + blockOffset16Z[x] = (short)((int)BlockNumber16Z(x << 3, 0, 0, 32) - (int)BlockNumber16Z(0, 0, 0, 32)); } for(int x = 0; x < countof(blockOffset16SZ); x++) { - blockOffset16SZ[x] = (int)BlockNumber16SZ(x << 3, 0, 0, 32) - (int)BlockNumber16SZ(0, 0, 0, 32); + blockOffset16SZ[x] = (short)((int)BlockNumber16SZ(x << 3, 0, 0, 32) - (int)BlockNumber16SZ(0, 0, 0, 32)); } for(int x = 0; x < countof(blockOffset8); x++) { - blockOffset8[x] = (int)BlockNumber8(x << 3, 0, 0, 32) - (int)BlockNumber8(0, 0, 0, 32); + blockOffset8[x] = (short)((int)BlockNumber8(x << 3, 0, 0, 32) - (int)BlockNumber8(0, 0, 0, 32)); } for(int x = 0; x < countof(blockOffset4); x++) { - blockOffset4[x] = (int)BlockNumber4(x << 3, 0, 0, 32) - (int)BlockNumber4(0, 0, 0, 32); + blockOffset4[x] = (short)((int)BlockNumber4(x << 3, 0, 0, 32) - (int)BlockNumber4(0, 0, 0, 32)); } for(int i = 0; i < countof(m_psm); i++) @@ -206,13 +205,11 @@ GSLocalMemory::GSLocalMemory() m_psm[i].wp = &GSLocalMemory::WritePixel32; m_psm[i].wpa = &GSLocalMemory::WritePixel32; m_psm[i].rt = &GSLocalMemory::ReadTexel32; - m_psm[i].rtNP = &GSLocalMemory::ReadTexel32; m_psm[i].rta = &GSLocalMemory::ReadTexel32; m_psm[i].wfa = &GSLocalMemory::WritePixel32; m_psm[i].wi = &GSLocalMemory::WriteImage; m_psm[i].ri = &GSLocalMemory::ReadImageX; // TODO m_psm[i].rtx = &GSLocalMemory::ReadTexture32; - m_psm[i].rtxNP = &GSLocalMemory::ReadTexture32; m_psm[i].rtxP = &GSLocalMemory::ReadTexture32; m_psm[i].rtxb = &GSLocalMemory::ReadTextureBlock32; m_psm[i].rtxbP = &GSLocalMemory::ReadTextureBlock32; @@ -328,18 +325,6 @@ GSLocalMemory::GSLocalMemory() m_psm[PSM_PSMZ16].wfa = &GSLocalMemory::WriteFrame16; m_psm[PSM_PSMZ16S].wfa = &GSLocalMemory::WriteFrame16; - m_psm[PSM_PSMCT16].rtNP = &GSLocalMemory::ReadTexel16NP; - m_psm[PSM_PSMCT16S].rtNP = &GSLocalMemory::ReadTexel16SNP; - m_psm[PSM_PSMT8].rtNP = &GSLocalMemory::ReadTexel8; - m_psm[PSM_PSMT4].rtNP = &GSLocalMemory::ReadTexel4; - m_psm[PSM_PSMT8H].rtNP = &GSLocalMemory::ReadTexel8H; - m_psm[PSM_PSMT4HL].rtNP = &GSLocalMemory::ReadTexel4HL; - m_psm[PSM_PSMT4HH].rtNP = &GSLocalMemory::ReadTexel4HH; - m_psm[PSM_PSMZ32].rtNP = &GSLocalMemory::ReadTexel32Z; - m_psm[PSM_PSMZ24].rtNP = &GSLocalMemory::ReadTexel24Z; - m_psm[PSM_PSMZ16].rtNP = &GSLocalMemory::ReadTexel16ZNP; - m_psm[PSM_PSMZ16S].rtNP = &GSLocalMemory::ReadTexel16SZNP; - m_psm[PSM_PSMCT24].wi = &GSLocalMemory::WriteImage24; // TODO m_psm[PSM_PSMCT16].wi = &GSLocalMemory::WriteImage; m_psm[PSM_PSMCT16S].wi = &GSLocalMemory::WriteImage; @@ -366,18 +351,6 @@ GSLocalMemory::GSLocalMemory() m_psm[PSM_PSMZ16].rtx = &GSLocalMemory::ReadTexture16Z; m_psm[PSM_PSMZ16S].rtx = &GSLocalMemory::ReadTexture16SZ; - m_psm[PSM_PSMCT16].rtxNP = &GSLocalMemory::ReadTexture16NP; - m_psm[PSM_PSMCT16S].rtxNP = &GSLocalMemory::ReadTexture16SNP; - m_psm[PSM_PSMT8].rtxNP = &GSLocalMemory::ReadTexture8NP; - m_psm[PSM_PSMT4].rtxNP = &GSLocalMemory::ReadTexture4NP; - m_psm[PSM_PSMT8H].rtxNP = &GSLocalMemory::ReadTexture8HNP; - m_psm[PSM_PSMT4HL].rtxNP = &GSLocalMemory::ReadTexture4HLNP; - m_psm[PSM_PSMT4HH].rtxNP = &GSLocalMemory::ReadTexture4HHNP; - m_psm[PSM_PSMZ32].rtxNP = &GSLocalMemory::ReadTexture32Z; - m_psm[PSM_PSMZ24].rtxNP = &GSLocalMemory::ReadTexture24Z; - m_psm[PSM_PSMZ16].rtxNP = &GSLocalMemory::ReadTexture16ZNP; - m_psm[PSM_PSMZ16S].rtxNP = &GSLocalMemory::ReadTexture16SZNP; - m_psm[PSM_PSMCT24].rtxP = &GSLocalMemory::ReadTexture24; m_psm[PSM_PSMCT16].rtxP = &GSLocalMemory::ReadTexture16; m_psm[PSM_PSMCT16S].rtxP = &GSLocalMemory::ReadTexture16S; @@ -417,9 +390,6 @@ GSLocalMemory::GSLocalMemory() m_psm[PSM_PSMZ16].rtxbP = &GSLocalMemory::ReadTextureBlock16Z; m_psm[PSM_PSMZ16S].rtxbP = &GSLocalMemory::ReadTextureBlock16SZ; - m_psm[PSM_PSMT8].pal = m_psm[PSM_PSMT8H].pal = 256; - m_psm[PSM_PSMT4].pal = m_psm[PSM_PSMT4HL].pal = m_psm[PSM_PSMT4HH].pal = 16; - m_psm[PSM_PSMCT16].bpp = m_psm[PSM_PSMCT16S].bpp = 16; m_psm[PSM_PSMT8].bpp = 8; m_psm[PSM_PSMT4].bpp = 4; @@ -432,6 +402,15 @@ GSLocalMemory::GSLocalMemory() m_psm[PSM_PSMZ24].trbpp = 24; m_psm[PSM_PSMZ16].trbpp = m_psm[PSM_PSMZ16S].trbpp = 16; + m_psm[PSM_PSMT8].pal = m_psm[PSM_PSMT8H].pal = 256; + m_psm[PSM_PSMT4].pal = m_psm[PSM_PSMT4HL].pal = m_psm[PSM_PSMT4HH].pal = 16; + + for(int i = 0; i < countof(m_psm); i++) m_psm[i].fmt = 3; + m_psm[PSM_PSMCT32].fmt = m_psm[PSM_PSMZ32].fmt = 0; + m_psm[PSM_PSMCT24].fmt = m_psm[PSM_PSMZ24].fmt = 1; + m_psm[PSM_PSMCT16].fmt = m_psm[PSM_PSMZ16].fmt = 2; + m_psm[PSM_PSMCT16S].fmt = m_psm[PSM_PSMZ16S].fmt = 2; + m_psm[PSM_PSMCT16].bs = m_psm[PSM_PSMCT16S].bs = GSVector2i(16, 8); m_psm[PSM_PSMT8].bs = GSVector2i(16, 16); m_psm[PSM_PSMT4].bs = GSVector2i(32, 16); @@ -465,23 +444,22 @@ GSLocalMemory::~GSLocalMemory() { VirtualFree(m_vm8, 0, MEM_RELEASE); - for_each(m_bomap.begin(), m_bomap.end(), aligned_free_second()); - for_each(m_pomap.begin(), m_pomap.end(), aligned_free_second()); + for_each(m_omap.begin(), m_omap.end(), aligned_free_second()); for_each(m_po4map.begin(), m_po4map.end(), aligned_free_second()); } -GSLocalMemory::BlockOffset* GSLocalMemory::GetBlockOffset(uint32 bp, uint32 bw, uint32 psm) +GSOffset* GSLocalMemory::GetOffset(uint32 bp, uint32 bw, uint32 psm) { uint32 hash = bp | (bw << 14) | (psm << 20); - hash_map::iterator i = m_bomap.find(hash); + hash_map::iterator i = m_omap.find(hash); - if(i != m_bomap.end()) + if(i != m_omap.end()) { return i->second; } - BlockOffset* o = (BlockOffset*)_aligned_malloc(sizeof(BlockOffset), 16); + GSOffset* o = (GSOffset*)_aligned_malloc(sizeof(GSOffset), 16); o->hash = hash; @@ -489,49 +467,29 @@ GSLocalMemory::BlockOffset* GSLocalMemory::GetBlockOffset(uint32 bp, uint32 bw, for(int i = 0; i < 256; i++) { - o->row[i] = (int)bn(0, i << 3, bp, bw); + o->block.row[i] = (short)bn(0, i << 3, bp, bw); } - o->col = m_psm[psm].blockOffset; - - m_bomap[hash] = o; - - return o; -} - -GSLocalMemory::PixelOffset* GSLocalMemory::GetPixelOffset(uint32 bp, uint32 bw, uint32 psm) -{ - uint32 hash = bp | (bw << 14) | (psm << 20); - - hash_map::iterator i = m_pomap.find(hash); - - if(i != m_pomap.end()) - { - return i->second; - } - - PixelOffset* o = (PixelOffset*)_aligned_malloc(sizeof(PixelOffset), 16); - - o->hash = hash; + o->block.col = m_psm[psm].blockOffset; pixelAddress pa = m_psm[psm].pa; for(int i = 0; i < 2048; i++) { - o->row[i] = (int)pa(0, i, bp, bw); + o->pixel.row[i] = (int)pa(0, i, bp, bw); } for(int i = 0; i < 8; i++) { - o->col[i] = m_psm[psm].rowOffset[i]; + o->pixel.col[i] = m_psm[psm].rowOffset[i]; } - m_pomap[hash] = o; + m_omap[hash] = o; return o; } -GSLocalMemory::PixelOffset4* GSLocalMemory::GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF) +GSPixelOffset4* GSLocalMemory::GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF) { uint32 fbp = FRAME.Block(); uint32 zbp = ZBUF.Block(); @@ -548,14 +506,14 @@ GSLocalMemory::PixelOffset4* GSLocalMemory::GetPixelOffset4(const GIFRegFRAME& F uint32 hash = (FRAME.FBP << 0) | (ZBUF.ZBP << 9) | (bw << 18) | (fpsm_hash << 24) | (zpsm_hash << 28); - hash_map::iterator i = m_po4map.find(hash); + hash_map::iterator i = m_po4map.find(hash); if(i != m_po4map.end()) { return i->second; } - PixelOffset4* o = (PixelOffset4*)_aligned_malloc(sizeof(PixelOffset4), 16); + GSPixelOffset4* o = (GSPixelOffset4*)_aligned_malloc(sizeof(GSPixelOffset4), 16); o->hash = hash; @@ -1449,20 +1407,20 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB /////////////////// -void GSLocalMemory::ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture32(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMCT32) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadBlock32(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture24(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { if(TEXA.AEM) { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMCT24) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } @@ -1470,7 +1428,7 @@ void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, } else { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMCT24) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } @@ -1478,11 +1436,11 @@ void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, } } -void GSLocalMemory::ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture16(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(r, 16, 8, 32, PSM_PSMCT16) + FOREACH_BLOCK_START(r, 16, 8, 32) { ReadBlock16(src, (uint8*)block, sizeof(block) / 8); @@ -1491,11 +1449,11 @@ void GSLocalMemory::ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture16S(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(r, 16, 8, 32, PSM_PSMCT16S) + FOREACH_BLOCK_START(r, 16, 8, 32) { ReadBlock16(src, (uint8*)block, sizeof(block) / 8); @@ -1504,75 +1462,75 @@ void GSLocalMemory::ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture8(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { const uint32* pal = m_clut; - FOREACH_BLOCK_START(r, 16, 16, 32, PSM_PSMT8) + FOREACH_BLOCK_START(r, 16, 16, 32) { ReadAndExpandBlock8_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture4(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { const uint64* pal = m_clut; - FOREACH_BLOCK_START(r, 32, 16, 32, PSM_PSMT4) + FOREACH_BLOCK_START(r, 32, 16, 32) { ReadAndExpandBlock4_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture8H(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { const uint32* pal = m_clut; - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT8H) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadAndExpandBlock8H_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture4HL(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { const uint32* pal = m_clut; - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT4HL) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadAndExpandBlock4HL_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture4HH(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { const uint32* pal = m_clut; - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT4HH) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadAndExpandBlock4HH_32(src, dst, dstpitch, pal); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture32Z(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMZ32) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadBlock32(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture24Z(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { if(TEXA.AEM) { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMZ24) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } @@ -1580,7 +1538,7 @@ void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch } else { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMZ24) + FOREACH_BLOCK_START(r, 8, 8, 32) { ReadAndExpandBlock24(src, dst, dstpitch, TEXA); } @@ -1588,11 +1546,11 @@ void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch } } -void GSLocalMemory::ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture16Z(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(r, 16, 8, 32, PSM_PSMZ16) + FOREACH_BLOCK_START(r, 16, 8, 32) { ReadBlock16(src, (uint8*)block, sizeof(block) / 8); @@ -1601,11 +1559,11 @@ void GSLocalMemory::ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture16SZ(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { __declspec(align(16)) uint16 block[16 * 8]; - FOREACH_BLOCK_START(r, 16, 8, 32, PSM_PSMZ16S) + FOREACH_BLOCK_START(r, 16, 8, 32) { ReadBlock16(src, (uint8*)block, sizeof(block) / 8); @@ -1731,286 +1689,125 @@ void GSLocalMemory::ReadTextureBlock16SZ(uint32 bp, uint8* dst, int dstpitch, co /////////////////// -void GSLocalMemory::ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { - readTexture rtx = m_psm[TEX0.PSM].rtx; - readTexel rt = m_psm[TEX0.PSM].rt; - GSVector2i bs = m_psm[TEX0.PSM].bs; + const psm_t& psm = m_psm[o->psm]; - if(r.width() < bs.x || r.height() < bs.y - || (r.left & (bs.x - 1)) || (r.top & (bs.y - 1)) - || (r.right & (bs.x - 1)) || (r.bottom & (bs.y - 1))) - { - ReadTexture(r, dst, dstpitch, TEX0, TEXA, rt, rtx); - } - else - { - (this->*rtx)(r, dst, dstpitch, TEX0, TEXA); - } -} -/////////////////// + readTexel rt = psm.rt; + readTexture rtx = psm.rtx; -void GSLocalMemory::ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - FOREACH_BLOCK_START(r, 16, 8, 16, PSM_PSMCT16) + if(r.width() < psm.bs.x || r.height() < psm.bs.y + || (r.left & (psm.bs.x - 1)) || (r.top & (psm.bs.y - 1)) + || (r.right & (psm.bs.x - 1)) || (r.bottom & (psm.bs.y - 1))) { - ReadBlock16(src, dst, dstpitch); - } - FOREACH_BLOCK_END -} + GIFRegTEX0 TEX0; -void GSLocalMemory::ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - FOREACH_BLOCK_START(r, 16, 8, 16, PSM_PSMCT16S) - { - ReadBlock16(src, dst, dstpitch); - } - FOREACH_BLOCK_END -} + TEX0.TBP0 = o->bp; + TEX0.TBW = o->bw; + TEX0.PSM = o->psm; -void GSLocalMemory::ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - const uint32* pal = m_clut; + GSVector4i cr = r.ralign(psm.bs); - if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) - { - FOREACH_BLOCK_START(r, 16, 16, 32, PSM_PSMT8) + bool aligned = ((DWORD_PTR)(dst + (cr.left - r.left) * sizeof(uint32)) & 0xf) == 0; + + if(cr.rempty() || !aligned) { - ReadAndExpandBlock8_32(src, dst, dstpitch, pal); + // TODO: expand r to block size, read into temp buffer + + if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n"); + + for(int y = r.top; y < r.bottom; y++, dst += dstpitch) + { + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + ((uint32*)dst)[i] = (this->*rt)(x, y, TEX0, TEXA); + } + } } - FOREACH_BLOCK_END - } - else - { - ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - - __declspec(align(16)) uint8 block[16 * 16]; - - FOREACH_BLOCK_START(r, 16, 16, 16, PSM_PSMT8) + else { - ReadBlock8(src, (uint8*)block, sizeof(block) / 16); + for(int y = r.top; y < cr.top; y++, dst += dstpitch) + { + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + ((uint32*)dst)[i] = (this->*rt)(x, y, TEX0, TEXA); + } + } - ExpandBlock8_16(block, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } -} + for(int y = cr.bottom; y < r.bottom; y++, dst += dstpitch) + { + for(int x = r.left, i = 0; x < r.right; x++, i++) + { + ((uint32*)dst)[i] = (this->*rt)(x, y, TEX0, TEXA); + } + } -void GSLocalMemory::ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - const uint64* pal = m_clut; + for(int y = cr.top; y < cr.bottom; y++, dst += dstpitch) + { + for(int x = r.left, i = 0; x < cr.left; x++, i++) + { + ((uint32*)dst)[i] = (this->*rt)(x, y, TEX0, TEXA); + } - if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) - { - FOREACH_BLOCK_START(r, 32, 16, 32, PSM_PSMT4) - { - ReadAndExpandBlock4_32(src, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } - else - { - ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); + for(int x = cr.right, i = x - r.left; x < r.right; x++, i++) + { + ((uint32*)dst)[i] = (this->*rt)(x, y, TEX0, TEXA); + } + } - __declspec(align(16)) uint8 block[(32 / 2) * 16]; - - FOREACH_BLOCK_START(r, 32, 16, 16, PSM_PSMT4) - { - ReadBlock4(src, (uint8*)block, sizeof(block) / 16); - - ExpandBlock4_16(block, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - const uint32* pal = m_clut; - - if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) - { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT8H) - { - ReadAndExpandBlock8H_32(src, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } - else - { - ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - - __declspec(align(16)) uint32 block[8 * 8]; - - FOREACH_BLOCK_START(r, 8, 8, 16, PSM_PSMT8H) - { - ReadBlock32(src, (uint8*)block, sizeof(block) / 8); - - ExpandBlock8H_16(block, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - const uint32* pal = m_clut; - - if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) - { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT4HL) - { - ReadAndExpandBlock4HL_32(src, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } - else - { - ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - - __declspec(align(16)) uint32 block[8 * 8]; - - FOREACH_BLOCK_START(r, 8, 8, 16, PSM_PSMT4HL) - { - ReadBlock32(src, (uint8*)block, sizeof(block) / 8); - - ExpandBlock4HL_16(block, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - const uint32* pal = m_clut; - - if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) - { - FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT4HH) - { - ReadAndExpandBlock4HH_32(src, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } - else - { - ASSERT(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S); - - __declspec(align(16)) uint32 block[8 * 8]; - - FOREACH_BLOCK_START(r, 8, 8, 16, PSM_PSMT4HH) - { - ReadBlock32(src, (uint8*)block, sizeof(block) / 8); - - ExpandBlock4HH_16(block, dst, dstpitch, pal); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - FOREACH_BLOCK_START(r, 16, 8, 16, PSM_PSMZ16) - { - ReadBlock16(src, dst, dstpitch); - } - FOREACH_BLOCK_END -} - -void GSLocalMemory::ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - FOREACH_BLOCK_START(r, 16, 8, 16, PSM_PSMZ16S) - { - ReadBlock16(src, dst, dstpitch); - } - FOREACH_BLOCK_END -} - -/////////////////// - -void GSLocalMemory::ReadTextureNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) -{ - readTexture rtx = m_psm[TEX0.PSM].rtxNP; - readTexel rt = m_psm[TEX0.PSM].rtNP; - GSVector2i bs = m_psm[TEX0.PSM].bs; - - if(r.width() < bs.x || r.height() < bs.y - || (r.left & (bs.x - 1)) || (r.top & (bs.y - 1)) - || (r.right & (bs.x - 1)) || (r.bottom & (bs.y - 1))) - { - uint32 psm = TEX0.PSM; - - switch(psm) - { - case PSM_PSMT8: - case PSM_PSMT8H: - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - psm = TEX0.CPSM; - break; - } - - switch(psm) - { - default: - case PSM_PSMCT32: - case PSM_PSMCT24: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, rt, rtx); - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, rt, rtx); - break; + if(!cr.rempty()) + { + (this->*rtx)(o, cr, dst + (cr.left - r.left) * sizeof(32), dstpitch, TEXA); + } } } else { - (this->*rtx)(r, dst, dstpitch, TEX0, TEXA); + (this->*rtx)(o, r, dst, dstpitch, TEXA); } } // 32/8 -void GSLocalMemory::ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture8P(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { - FOREACH_BLOCK_START(r, 16, 16, 8, PSM_PSMT8) + FOREACH_BLOCK_START(r, 16, 16, 8) { ReadBlock8(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture4P(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { - FOREACH_BLOCK_START(r, 32, 16, 8, PSM_PSMT4) + FOREACH_BLOCK_START(r, 32, 16, 8) { ReadBlock4P(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture8HP(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { - FOREACH_BLOCK_START(r, 8, 8, 8, PSM_PSMT8H) + FOREACH_BLOCK_START(r, 8, 8, 8) { ReadBlock8HP(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture4HLP(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { - FOREACH_BLOCK_START(r, 8, 8, 8, PSM_PSMT4HL) + FOREACH_BLOCK_START(r, 8, 8, 8) { ReadBlock4HLP(src, dst, dstpitch); } FOREACH_BLOCK_END } -void GSLocalMemory::ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) +void GSLocalMemory::ReadTexture4HHP(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) { - FOREACH_BLOCK_START(r, 8, 8, 8, PSM_PSMT4HH) + FOREACH_BLOCK_START(r, 8, 8, 8) { ReadBlock4HHP(src, dst, dstpitch); } @@ -2054,47 +1851,6 @@ void GSLocalMemory::ReadTextureBlock4HHP(uint32 bp, uint8* dst, int dstpitch, co // -template -void GSLocalMemory::ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, readTexel rt, readTexture rtx) -{ - GSVector4i cr = r.ralign(m_psm[TEX0.PSM].bs); - - bool aligned = ((DWORD_PTR)(dst + (cr.left - r.left) * sizeof(T)) & 0xf) == 0; - - if(cr.rempty() || !aligned) - { - // TODO: expand r to block size, read into temp buffer, copy to r (like above) - -if(!aligned) -printf("unaligned memory pointer passed to ReadTexture\n"); - - for(int y = r.top; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - } - else - { - for(int y = r.top; y < cr.top; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - - if(!cr.rempty()) - (this->*rtx)(cr, dst + (cr.left - r.left) * sizeof(T), dstpitch, TEX0, TEXA); - - for(int y = cr.top; y < cr.bottom; y++, dst += dstpitch) - { - for(int x = r.left, i = 0; x < cr.left; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - for(int x = cr.right, i = x - r.left; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - } - - for(int y = cr.bottom; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA); - } -} - HRESULT GSLocalMemory::SaveBMP(const string& fn, uint32 bp, uint32 bw, uint32 psm, int w, int h) { int pitch = w * 4; diff --git a/plugins/GSdx/GSLocalMemory.h b/plugins/GSdx/GSLocalMemory.h index fe0cab0f37..0c475a92c2 100644 --- a/plugins/GSdx/GSLocalMemory.h +++ b/plugins/GSdx/GSLocalMemory.h @@ -29,6 +29,32 @@ #include "GSBlock.h" #include "GSClut.h" +struct GSOffset +{ + struct + { + short row[256]; // yn (n = 0 8 16 ...) + short* col; // blockOffset* + } block; + + struct + { + int row[2048]; // yn (n = 0 1 2 ...) + int* col[8]; // rowOffset* + } pixel; + + union {uint32 hash; struct {uint32 bp:14, bw:6, psm:6;};}; +}; + +struct GSPixelOffset4 +{ + // 16 bit offsets (m_vm16[...]) + + GSVector2i row[2048]; // f yn | z yn (n = 0 1 2 ...) + GSVector2i col[512]; // f xn | z xn (n = 0 4 8 ...) + uint32 hash; +}; + class GSLocalMemory : public GSBlock { public: @@ -43,7 +69,7 @@ public: typedef uint32 (GSLocalMemory::*readTexelAddr)(uint32 addr, const GIFRegTEXA& TEXA) const; typedef void (GSLocalMemory::*writeImage)(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); typedef void (GSLocalMemory::*readImage)(int& tx, int& ty, uint8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const; - typedef void (GSLocalMemory::*readTexture)(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); + typedef void (GSLocalMemory::*readTexture)(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); typedef void (GSLocalMemory::*readTextureBlock)(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; typedef union @@ -55,18 +81,17 @@ public: readPixelAddr rpa; writePixel wp; writePixelAddr wpa; - readTexel rt, rtNP; + readTexel rt; readTexelAddr rta; writeFrameAddr wfa; writeImage wi; readImage ri; - readTexture rtx, rtxNP, rtxP; + readTexture rtx, rtxP; readTextureBlock rtxb, rtxbP; - short bpp, trbpp; - int pal; + uint16 bpp, trbpp, pal, fmt; GSVector2i bs, pgs; int* rowOffset[8]; - int* blockOffset; + short* blockOffset; }; uint8 dummy[128]; @@ -81,29 +106,6 @@ public: GSClut m_clut; - struct BlockOffset - { - int row[256]; // yn (n = 0 8 16 ...) - int* col; // blockOffset* - uint32 hash; - }; - - struct PixelOffset - { - int row[2048]; // yn (n = 0 1 2 ...) - int* col[8]; // rowOffset* - uint32 hash; - }; - - struct PixelOffset4 - { - // 16 bit offsets (m_vm16[...]) - - GSVector2i row[2048]; // f yn | z yn (n = 0 1 2 ...) - GSVector2i col[512]; // f xn | z xn (n = 0 4 8 ...) - uint32 hash; - }; - protected: static uint32 pageOffset32[32][32][64]; static uint32 pageOffset32Z[32][32][64]; @@ -123,14 +125,14 @@ protected: static int rowOffset8[2][2048]; static int rowOffset4[2][2048]; - static int blockOffset32[256]; - static int blockOffset32Z[256]; - static int blockOffset16[256]; - static int blockOffset16S[256]; - static int blockOffset16Z[256]; - static int blockOffset16SZ[256]; - static int blockOffset8[256]; - static int blockOffset4[256]; + static short blockOffset32[256]; + static short blockOffset32Z[256]; + static short blockOffset16[256]; + static short blockOffset16S[256]; + static short blockOffset16Z[256]; + static short blockOffset16SZ[256]; + static short blockOffset8[256]; + static short blockOffset4[256]; __forceinline static uint32 Expand24To32(uint32 c, const GIFRegTEXA& TEXA) { @@ -148,17 +150,15 @@ protected: // - hash_map m_bomap; - hash_map m_pomap; - hash_map m_po4map; + hash_map m_omap; + hash_map m_po4map; public: GSLocalMemory(); virtual ~GSLocalMemory(); - BlockOffset* GetBlockOffset(uint32 bp, uint32 bw, uint32 psm); - PixelOffset* GetPixelOffset(uint32 bp, uint32 bw, uint32 psm); - PixelOffset4* GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF); + GSOffset* GetOffset(uint32 bp, uint32 bw, uint32 psm); + GSPixelOffset4* GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF); // address @@ -635,73 +635,73 @@ public: WriteFrame16(PixelAddress16SZ(x, y, bp, bw), c); } - __forceinline void WritePixel32(uint8* RESTRICT src, uint32 pitch, PixelOffset* po, const GSVector4i& r) + __forceinline void WritePixel32(uint8* RESTRICT src, uint32 pitch, GSOffset* o, const GSVector4i& r) { src -= r.left * sizeof(uint32); for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - uint32* RESTRICT d = &m_vm32[po->row[y]]; - int* RESTRICT o = po->col[0]; + uint32* RESTRICT d = &m_vm32[o->pixel.row[y]]; + int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - d[o[x]] = s[x]; + d[col[x]] = s[x]; } } } - __forceinline void WritePixel24(uint8* RESTRICT src, uint32 pitch, PixelOffset* po, const GSVector4i& r) + __forceinline void WritePixel24(uint8* RESTRICT src, uint32 pitch, GSOffset* o, const GSVector4i& r) { src -= r.left * sizeof(uint32); for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - uint32* RESTRICT d = &m_vm32[po->row[y]]; - int* RESTRICT o = po->col[0]; + uint32* RESTRICT d = &m_vm32[o->pixel.row[y]]; + int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - d[o[x]] = (d[o[x]] & 0xff000000) | (s[x] & 0x00ffffff); + d[col[x]] = (d[col[x]] & 0xff000000) | (s[x] & 0x00ffffff); } } } - __forceinline void WritePixel16(uint8* RESTRICT src, uint32 pitch, PixelOffset* po, const GSVector4i& r) + __forceinline void WritePixel16(uint8* RESTRICT src, uint32 pitch, GSOffset* o, const GSVector4i& r) { src -= r.left * sizeof(uint16); for(int y = r.top; y < r.bottom; y++, src += pitch) { uint16* RESTRICT s = (uint16*)src; - uint16* RESTRICT d = &m_vm16[po->row[y]]; - int* RESTRICT o = po->col[0]; + uint16* RESTRICT d = &m_vm16[o->pixel.row[y]]; + int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { - d[o[x]] = s[x]; + d[col[x]] = s[x]; } } } - __forceinline void WriteFrame16(uint8* RESTRICT src, uint32 pitch, PixelOffset* po, const GSVector4i& r) + __forceinline void WriteFrame16(uint8* RESTRICT src, uint32 pitch, GSOffset* o, const GSVector4i& r) { src -= r.left * sizeof(uint32); for(int y = r.top; y < r.bottom; y++, src += pitch) { uint32* RESTRICT s = (uint32*)src; - uint16* RESTRICT d = &m_vm16[po->row[y]]; - int* RESTRICT o = po->col[0]; + uint16* RESTRICT d = &m_vm16[o->pixel.row[y]]; + int* RESTRICT col = o->pixel.col[0]; for(int x = r.left; x < r.right; x++) { uint32 rb = s[x] & 0x00f800f8; uint32 ga = s[x] & 0x8000f800; - d[o[x]] = (ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3); + d[col[x]] = (uint16)((ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3)); } } } @@ -811,26 +811,6 @@ public: return ReadTexel16(PixelAddress16SZ(x, y, TEX0.TBP0, TEX0.TBW), TEXA); } - __forceinline uint32 ReadTexel16NP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const - { - return ReadPixel16(x, y, TEX0.TBP0, TEX0.TBW); - } - - __forceinline uint32 ReadTexel16SNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const - { - return ReadPixel16S(x, y, TEX0.TBP0, TEX0.TBW); - } - - __forceinline uint32 ReadTexel16ZNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const - { - return ReadPixel16Z(x, y, TEX0.TBP0, TEX0.TBW); - } - - __forceinline uint32 ReadTexel16SZNP(int x, int y, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const - { - return ReadPixel16SZ(x, y, TEX0.TBP0, TEX0.TBW); - } - // template @@ -861,21 +841,21 @@ public: // * => 32 - void ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); + void ReadTexture32(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture24(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture16(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture16S(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture8(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture4(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture8H(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture4HL(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture4HH(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture32Z(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture24Z(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture16Z(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture16SZ(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); - void ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); + void ReadTexture(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); void ReadTextureBlock32(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; void ReadTextureBlock24(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; @@ -891,27 +871,13 @@ public: void ReadTextureBlock16Z(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; void ReadTextureBlock16SZ(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; - // * => 32/16 - - void ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - - void ReadTextureNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - // pal ? 8 : 32 - void ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); - void ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA); + void ReadTexture8P(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture4P(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture8HP(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture4HLP(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); + void ReadTexture4HHP(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); void ReadTextureBlock8P(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; void ReadTextureBlock4P(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const; @@ -921,7 +887,7 @@ public: // - template void ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, readTexel rt, readTexture rtx); + template void ReadTexture(const GSOffset* RESTRICT o, const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA); // diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index c263ba922e..f1030ee321 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -26,6 +26,7 @@ GSRenderer::GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev) : GSState(base, mt, irq) , m_dev(dev) , m_shader(0) + , m_vt(this) { m_interlace = theApp.GetConfig("interlace", 0); m_aspectratio = theApp.GetConfig("aspectratio", 1); @@ -54,9 +55,9 @@ GSRenderer::~GSRenderer() delete m_dev; } -bool GSRenderer::Create(const string& title) +bool GSRenderer::Create(const string& title, int w, int h) { - if(!m_wnd.Create(title.c_str())) + if(!m_wnd.Create(title.c_str(), w, h)) { return false; } @@ -325,7 +326,7 @@ void GSRenderer::VSync(int field) // present - m_dev->Present(m_wnd.GetClientRect().fit(m_aspectratio), m_shader); + m_dev->Present(m_wnd.GetClientRect().fit(m_aspectratio), m_shader, m_framelimit); // snapshot @@ -554,9 +555,7 @@ void GSRenderer::GetTextureMinMax(GSVector4i& r, bool linear) } } - GSVector2i bs = GSLocalMemory::m_psm[context->TEX0.PSM].bs; - - r = vr.ralign(bs).rintersect(tr); + r = vr.rintersect(tr); } void GSRenderer::GetAlphaMinMax() @@ -573,28 +572,25 @@ void GSRenderer::GetAlphaMinMax() if(PRIM->TME && context->TEX0.TCC) { - uint32 bpp = GSLocalMemory::m_psm[context->TEX0.PSM].trbpp; - uint32 cbpp = GSLocalMemory::m_psm[context->TEX0.CPSM].trbpp; - uint32 pal = GSLocalMemory::m_psm[context->TEX0.PSM].pal; - - if(bpp == 32) + switch(GSLocalMemory::m_psm[context->TEX0.PSM].fmt) { + case 0: a.y = 0; a.w = 0xff; - } - else if(bpp == 24) - { + break; + case 1: a.y = env.TEXA.AEM ? 0 : env.TEXA.TA0; a.w = env.TEXA.TA0; - } - else if(bpp == 16) - { + break; + case 2: a.y = env.TEXA.AEM ? 0 : min(env.TEXA.TA0, env.TEXA.TA1); a.w = max(env.TEXA.TA0, env.TEXA.TA1); - } - else - { + break; + case 3: m_mem.m_clut.GetAlphaMinMax32(a.y, a.w); + break; + default: + __assume(0); } switch(context->TEX0.TFX) @@ -708,17 +704,29 @@ bool GSRenderer::TryAlphaTest(uint32& fm, uint32& zm) bool GSRenderer::IsLinear() { - float qmin = m_vt.m_min.t.z; - float qmax = m_vt.m_max.t.z; + const GIFRegTEX1& TEX1 = m_context->TEX1; - if(PRIM->FST) + bool mmin = TEX1.IsMinLinear(); + bool mmag = TEX1.IsMagLinear(); + + if(mmag == mmin) return mmag; + + if(!TEX1.LCM && !PRIM->FST) // if FST => assume Q = 1.0f (should not, but Q is very often bogus, 0 or DEN) { - // assume Q = 1.0f => LOD > 0 (should not, but Q is very often bogus, 0 or DEN) + float K = (float)TEX1.K / 16; + float f = (float)(1 << TEX1.L) / log(2.0f); - qmin = qmax = 1.0f; + // TODO: abs(Qmin) may not be <= abs(Qmax), check the sign + + float LODmin = K + log(1.0f / abs(m_vt.m_max.t.z)) * f; + float LODmax = K + log(1.0f / abs(m_vt.m_min.t.z)) * f; + + return LODmax <= 0 ? mmag : LODmin > 0 ? mmin : mmag || mmin; + } + else + { + return TEX1.K <= 0 ? mmag : TEX1.K > 0 ? mmin : mmag || mmin; } - - return m_context->TEX1.IsLinear(qmin, qmax); } bool GSRenderer::IsOpaque() diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index e78f762e2b..d671bdc7ea 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -73,7 +73,7 @@ public: GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev); virtual ~GSRenderer(); - virtual bool Create(const string& title); + virtual bool Create(const string& title, int w, int h); virtual void VSync(int field); virtual bool MakeSnapshot(const string& path); virtual void KeyEvent(GSKeyEventData* e); @@ -107,37 +107,23 @@ protected: void FlushPrim() { - if(m_count > 0) + if(m_count == 0) return; + + if(GSLocalMemory::m_psm[m_context->FRAME.PSM].fmt < 3 && GSLocalMemory::m_psm[m_context->ZBUF.PSM].fmt < 3) { - /* - TRACE(_T("[%d] Draw f %05x (%d) z %05x (%d %d %d %d) t %05x %05x (%d)\n"), - (int)m_perfmon.GetFrame(), - (int)m_context->FRAME.Block(), - (int)m_context->FRAME.PSM, - (int)m_context->ZBUF.Block(), - (int)m_context->ZBUF.PSM, - m_context->TEST.ZTE, - m_context->TEST.ZTST, - m_context->ZBUF.ZMSK, - PRIM->TME ? (int)m_context->TEX0.TBP0 : 0xfffff, - PRIM->TME && m_context->TEX0.PSM > PSM_PSMCT16S ? (int)m_context->TEX0.CBP : 0xfffff, - PRIM->TME ? (int)m_context->TEX0.PSM : 0xff); - */ + // FIXME: berserk fpsm = 27 (8H) - if(GSUtil::EncodePSM(m_context->FRAME.PSM) != 3 && GSUtil::EncodePSM(m_context->ZBUF.PSM) != 3) + if(!m_dev->IsLost()) { - // FIXME: berserk fpsm = 27 (8H) + m_vt.Update(m_vertices, m_count, GSUtil::GetPrimClass(PRIM->PRIM)); - if(!m_dev->IsLost()) - { - Draw(); - } - - m_perfmon.Put(GSPerfMon::Draw, 1); + Draw(); } - m_count = 0; + m_perfmon.Put(GSPerfMon::Draw, 1); } + + m_count = 0; } void GrowVertexBuffer() diff --git a/plugins/GSdx/GSRendererDX.h b/plugins/GSdx/GSRendererDX.h index 5b46db326d..887e202f22 100644 --- a/plugins/GSdx/GSRendererDX.h +++ b/plugins/GSdx/GSRendererDX.h @@ -28,22 +28,22 @@ template class GSRendererDX : public GSRendererHW { GSTextureFX* m_tfx; + GSVector2 m_pixelcenter; bool m_logz; bool m_fba; protected: int m_topology; - GSVector2 m_pixelcenter; virtual void SetupDATE(GSTexture* rt, GSTexture* ds) {} virtual void UpdateFBA(GSTexture* rt) {} public: - GSRendererDX(uint8* base, bool mt, void (*irq)(), GSDevice* dev, GSTextureCache* tc, GSTextureFX* tfx) + GSRendererDX(uint8* base, bool mt, void (*irq)(), GSDevice* dev, GSTextureCache* tc, GSTextureFX* tfx, const GSVector2& pixelcenter = GSVector2(0, 0)) : GSRendererHW(base, mt, irq, dev, tc) , m_tfx(tfx) + , m_pixelcenter(pixelcenter) , m_topology(-1) - , m_pixelcenter(0, 0) { m_logz = !!theApp.GetConfig("logz", 0); m_fba = !!theApp.GetConfig("fba", 1); @@ -54,9 +54,9 @@ public: delete m_tfx; } - bool Create(const string& title) + bool Create(const string& title, int w, int h) { - if(!__super::Create(title)) + if(!__super::Create(title, w, h)) return false; if(!m_tfx->Create(m_dev)) @@ -65,7 +65,7 @@ public: return true; } - void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) + void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) { GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; @@ -82,9 +82,21 @@ public: GSTextureFX::OMDepthStencilSelector om_dssel; + if(context->TEST.ZTE) + { + om_dssel.ztst = context->TEST.ZTST; + om_dssel.zwe = !context->ZBUF.ZMSK; + } + else + { + om_dssel.ztst = ZTST_ALWAYS; + om_dssel.zwe = 0; + } +/* om_dssel.zte = context->TEST.ZTE; om_dssel.ztst = context->TEST.ZTST; om_dssel.zwe = !context->ZBUF.ZMSK; +*/ om_dssel.date = context->FRAME.PSM != PSM_PSMCT24 ? context->TEST.DATE : 0; om_dssel.fba = m_fba ? context->FBA.FBA : 0; @@ -115,22 +127,17 @@ public: } } - om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff; - om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00; - om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000; - om_bsel.wa = (context->FRAME.FBMSK & 0xff000000) != 0xff000000; + om_bsel.wrgba = ~GSVector4i::load((int)context->FRAME.FBMSK).eq8(GSVector4i::xffffffff()).mask(); // vs GSTextureFX::VSSelector vs_sel; - vs_sel.bppz = 0; vs_sel.tme = PRIM->TME; vs_sel.fst = PRIM->FST; vs_sel.logz = m_logz ? 1 : 0; - vs_sel.prim = primclass; - if(om_dssel.zte && om_dssel.ztst > 0 && om_dssel.zwe) + if(om_dssel.ztst >= ZTST_ALWAYS && om_dssel.zwe) { if(context->ZBUF.PSM == PSM_PSMZ24) { @@ -139,7 +146,7 @@ public: ASSERT(m_vt.m_min.p.z > 0xffffff); vs_sel.bppz = 1; - om_dssel.ztst = 1; + om_dssel.ztst = ZTST_ALWAYS; } } else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) @@ -149,76 +156,52 @@ public: ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo vs_sel.bppz = 2; - om_dssel.ztst = 1; + om_dssel.ztst = ZTST_ALWAYS; } } } GSTextureFX::VSConstantBuffer vs_cb; - float sx = 2.0f * rt->m_scale.x / (rt->GetWidth() * 16); - float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16); + float sx = 2.0f * rt->m_scale.x / (rt->m_size.x << 4); + float sy = 2.0f * rt->m_scale.y / (rt->m_size.y << 4); float ox = (float)(int)context->XYOFFSET.OFX; float oy = (float)(int)context->XYOFFSET.OFY; - float ox2 = 2.0f * m_pixelcenter.x / rt->GetWidth(); - float oy2 = 2.0f * m_pixelcenter.y / rt->GetHeight(); + float ox2 = 2.0f * m_pixelcenter.x / rt->m_size.x; + float oy2 = 2.0f * m_pixelcenter.y / rt->m_size.y; vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f); vs_cb.VertexOffset = GSVector4(ox * sx + ox2 + 1, -(oy * sy + oy2 + 1), 0.0f, -1.0f); - if(PRIM->TME) - { - if(PRIM->FST) - { - vs_cb.TextureScale.x = 1.0f / (16 << context->TEX0.TW); - vs_cb.TextureScale.y = 1.0f / (16 << context->TEX0.TH); - } - else - { - vs_cb.TextureScale = GSVector2(1.0f, 1.0f); - } - } - // gs GSTextureFX::GSSelector gs_sel; gs_sel.iip = PRIM->IIP; - gs_sel.prim = primclass; + gs_sel.prim = m_vt.m_primclass; // ps GSTextureFX::PSSelector ps_sel; - - ps_sel.fst = PRIM->FST; - ps_sel.wms = context->CLAMP.WMS; - ps_sel.wmt = context->CLAMP.WMT; - ps_sel.aem = env.TEXA.AEM; - ps_sel.tfx = context->TEX0.TFX; - ps_sel.tcc = context->TEX0.TCC; - ps_sel.ate = context->TEST.ATE; - ps_sel.atst = context->TEST.ATST; - ps_sel.fog = PRIM->FGE; - ps_sel.clr1 = om_bsel.abe && om_bsel.a == 1 && om_bsel.b == 2 && om_bsel.d == 1; - ps_sel.fba = context->FBA.FBA; - ps_sel.aout = context->FRAME.PSM == PSM_PSMCT16 || context->FRAME.PSM == PSM_PSMCT16S || (context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0; - ps_sel.ltf = m_filter == 2 ? IsLinear() : m_filter; - GSTextureFX::PSSamplerSelector ps_ssel; - - ps_ssel.tau = 0; - ps_ssel.tav = 0; - ps_ssel.ltf = ps_sel.ltf; - GSTextureFX::PSConstantBuffer ps_cb; - if(ps_sel.fog) + ps_sel.clr1 = om_bsel.IsCLR1(); + ps_sel.fba = context->FBA.FBA; + ps_sel.aout = context->FRAME.PSM == PSM_PSMCT16 || context->FRAME.PSM == PSM_PSMCT16S || (context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0; + + if(PRIM->FGE) { - ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, 0) / 255; + ps_sel.fog = 1; + + ps_cb.FogColor_AREF = GSVector4(env.FOGCOL.u32[0]) / 255; } - if(ps_sel.ate) + if(context->TEST.ATE) { + ps_sel.ate = 1; + ps_sel.atst = context->TEST.ATST; + switch(ps_sel.atst) { case ATST_LESS: @@ -235,62 +218,43 @@ public: if(tex) { + ps_sel.wms = context->CLAMP.WMS; + ps_sel.wmt = context->CLAMP.WMT; ps_sel.fmt = tex->m_fmt; + ps_sel.aem = env.TEXA.AEM; + ps_sel.tfx = context->TEX0.TFX; + ps_sel.tcc = context->TEX0.TCC; + ps_sel.ltf = m_filter == 2 ? IsLinear() : m_filter; ps_sel.rt = tex->m_target; - int w = tex->m_texture->GetWidth(); - int h = tex->m_texture->GetHeight(); + int w = tex->m_texture->m_size.x; + int h = tex->m_texture->m_size.y; - ps_cb.WH = GSVector4((int)(1 << context->TEX0.TW), (int)(1 << context->TEX0.TH), w, h); - ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / GSVector4(w, h).xyxy(); - ps_cb.MinF_TA.z = (float)(int)env.TEXA.TA0 / 255; - ps_cb.MinF_TA.w = (float)(int)env.TEXA.TA1 / 255; + int tw = (int)(1 << context->TEX0.TW); + int th = (int)(1 << context->TEX0.TH); - switch(context->CLAMP.WMS) + GSVector4 WH(tw, th, w, h); + + if(PRIM->FST) { - case CLAMP_REPEAT: - ps_ssel.tau = 1; - break; - case CLAMP_CLAMP: - ps_ssel.tau = 0; - break; - case CLAMP_REGION_CLAMP: - ps_cb.MinMax.x = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW); - ps_cb.MinMax.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW); - ps_cb.MinF_TA.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW); - ps_ssel.tau = 0; - break; - case CLAMP_REGION_REPEAT: - ps_cb.MskFix.x = context->CLAMP.MINU; - ps_cb.MskFix.z = context->CLAMP.MAXU; - ps_ssel.tau = 1; - break; - default: - __assume(0); + vs_cb.TextureScale = GSVector4(1.0f / 16) / WH.xyxy(); + + ps_sel.fst = 1; } - switch(context->CLAMP.WMT) - { - case CLAMP_REPEAT: - ps_ssel.tav = 1; - break; - case CLAMP_CLAMP: - ps_ssel.tav = 0; - break; - case CLAMP_REGION_CLAMP: - ps_cb.MinMax.y = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH); - ps_cb.MinMax.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH); - ps_cb.MinF_TA.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH); - ps_ssel.tav = 0; - break; - case CLAMP_REGION_REPEAT: - ps_cb.MskFix.y = context->CLAMP.MINV; - ps_cb.MskFix.w = context->CLAMP.MAXV; - ps_ssel.tav = 1; - break; - default: - __assume(0); - } + ps_cb.WH = WH; + ps_cb.HalfTexel = GSVector4(-0.5f, 0.5f).xxyy() / WH.zwzw(); + ps_cb.MskFix = GSVector4i(context->CLAMP.MINU, context->CLAMP.MINV, context->CLAMP.MAXU, context->CLAMP.MAXV); + + GSVector4 clamp(ps_cb.MskFix); + GSVector4 ta(env.TEXA & GSVector4i::x000000ff()); + + ps_cb.MinMax = clamp / WH.xyxy(); + ps_cb.MinF_TA = (clamp + 0.5f).xyxy(ta) / WH.xyxy(GSVector4(255, 255)); + + ps_ssel.tau = (context->CLAMP.WMS + 3) >> 1; + ps_ssel.tav = (context->CLAMP.WMT + 3) >> 1; + ps_ssel.ltf = ps_sel.ltf; } else { @@ -299,21 +263,18 @@ public: // rs - int w = rt->GetWidth(); - int h = rt->GetHeight(); + GSVector4i scissor = GSVector4i(GSVector4(rt->m_scale).xyxy() * context->scissor.in).rintersect(GSVector4i(rt->GetSize()).zwxy()); - GSVector4i scissor = GSVector4i(GSVector4(rt->m_scale).xyxy() * context->scissor.in).rintersect(GSVector4i(0, 0, w, h)); - - // + m_dev->OMSetRenderTargets(rt, ds, &scissor); + m_dev->PSSetShaderResources(tex ? tex->m_texture : NULL, tex ? tex->m_palette : NULL); uint8 afix = context->ALPHA.FIX; - m_tfx->SetupOM(om_dssel, om_bsel, afix, rt, ds); + m_tfx->SetupOM(om_dssel, om_bsel, afix); m_tfx->SetupIA(m_vertices, m_count, m_topology); m_tfx->SetupVS(vs_sel, &vs_cb); m_tfx->SetupGS(gs_sel); - m_tfx->SetupPS(ps_sel, &ps_cb, ps_ssel, tex ? tex->m_texture : NULL, tex ? tex->m_palette : NULL); - m_tfx->SetupRS(w, h, scissor); + m_tfx->SetupPS(ps_sel, &ps_cb, ps_ssel); // draw @@ -343,7 +304,7 @@ public: break; } - m_tfx->UpdatePS(ps_sel, &ps_cb, ps_ssel); + m_tfx->SetupPS(ps_sel, &ps_cb, ps_ssel); bool z = om_dssel.zwe; bool r = om_bsel.wr; @@ -368,7 +329,7 @@ public: om_bsel.wb = b; om_bsel.wa = a; - m_tfx->UpdateOM(om_dssel, om_bsel, afix); + m_tfx->SetupOM(om_dssel, om_bsel, afix); m_dev->DrawPrimitive(); } diff --git a/plugins/GSdx/GSRendererDX10.cpp b/plugins/GSdx/GSRendererDX10.cpp index 0bc018f78b..e4da9d823f 100644 --- a/plugins/GSdx/GSRendererDX10.cpp +++ b/plugins/GSdx/GSRendererDX10.cpp @@ -25,16 +25,14 @@ #include "resource.h" GSRendererDX10::GSRendererDX10(uint8* base, bool mt, void (*irq)()) - : GSRendererDX(base, mt, irq, new GSDevice10(), new GSTextureCache10(this), new GSTextureFX10()) + : GSRendererDX(base, mt, irq, new GSDevice10(), new GSTextureCache10(this), new GSTextureFX10(), GSVector2(-0.5f, -0.5f)) { InitVertexKick(); - - m_pixelcenter = GSVector2(-0.5f, -0.5f); } -bool GSRendererDX10::Create(const string& title) +bool GSRendererDX10::Create(const string& title, int w, int h) { - if(!__super::Create(title)) + if(!__super::Create(title, w, h)) return false; // @@ -88,9 +86,11 @@ void GSRendererDX10::VertexKick(bool skip) { GSVector4i scissor = m_context->scissor.dx10; + GSVector4i pmin, pmax; + #if _M_SSE >= 0x401 - GSVector4i pmin, pmax, v0, v1, v2; + GSVector4i v0, v1, v2; switch(prim) { @@ -118,59 +118,60 @@ void GSRendererDX10::VertexKick(bool skip) break; } + #else + + switch(prim) + { + case GS_POINTLIST: + pmin.x = v[0].p.x; + pmin.y = v[0].p.y; + pmax.x = v[0].p.x; + pmax.y = v[0].p.y; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + pmin.x = std::min(v[0].p.x, v[1].p.x); + pmin.y = std::min(v[0].p.y, v[1].p.y); + pmax.x = std::max(v[0].p.x, v[1].p.x); + pmax.y = std::max(v[0].p.y, v[1].p.y); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + pmin.x = std::min(std::min(v[0].p.x, v[1].p.x), v[2].p.x); + pmin.y = std::min(std::min(v[0].p.y, v[1].p.y), v[2].p.y); + pmax.x = std::max(std::max(v[0].p.x, v[1].p.x), v[2].p.x); + pmax.y = std::max(std::max(v[0].p.y, v[1].p.y), v[2].p.y); + break; + } + + #endif + GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); + switch(prim) + { + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + case GS_SPRITE: + test |= pmin == pmax; + break; + } + if(test.mask() & 0xff) { return; } - #else - - switch(prim) - { - case GS_POINTLIST: - if(v[0].p.x < scissor.x - || v[0].p.x > scissor.z - || v[0].p.y < scissor.y - || v[0].p.y > scissor.w) - { - return; - } - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w) - { - return; - } - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) - { - return; - } - break; - } - - #endif - m_count += count; } } -void GSRendererDX10::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +void GSRendererDX10::Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) { - switch(primclass) + switch(m_vt.m_primclass) { case GS_POINT_CLASS: m_topology = D3D10_PRIMITIVE_TOPOLOGY_POINTLIST; @@ -189,7 +190,7 @@ void GSRendererDX10::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, __assume(0); } - __super::Draw(primclass, rt, ds, tex); + __super::Draw(rt, ds, tex); } void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds) @@ -198,10 +199,9 @@ void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds) GSDevice10* dev = (GSDevice10*)m_dev; - int w = rt->GetWidth(); - int h = rt->GetHeight(); + const GSVector2i& size = rt->m_size; - if(GSTexture* t = dev->CreateRenderTarget(w, h)) + if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y)) { // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows @@ -217,7 +217,7 @@ void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds) // ia - GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 s = GSVector4(rt->m_scale.x / size.x, rt->m_scale.y / size.y); GSVector4 o = GSVector4(-1.0f, 1.0f); GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); @@ -249,11 +249,7 @@ void GSRendererDX10::SetupDATE(GSTexture* rt, GSTexture* ds) dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); dev->PSSetSamplerState(dev->m_convert.pt, NULL); - // rs - - dev->RSSet(w, h); - - // set + // dev->DrawPrimitive(); diff --git a/plugins/GSdx/GSRendererDX10.h b/plugins/GSdx/GSRendererDX10.h index 1465fff56e..7e08538891 100644 --- a/plugins/GSdx/GSRendererDX10.h +++ b/plugins/GSdx/GSRendererDX10.h @@ -35,13 +35,13 @@ protected: CComPtr bs; } m_date; - void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); + void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); void SetupDATE(GSTexture* rt, GSTexture* ds); public: GSRendererDX10(uint8* base, bool mt, void (*irq)()); - bool Create(const string& title); + bool Create(const string& title, int w, int h); template void VertexKick(bool skip); }; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX11.cpp b/plugins/GSdx/GSRendererDX11.cpp index 063c513a8e..ac14308100 100644 --- a/plugins/GSdx/GSRendererDX11.cpp +++ b/plugins/GSdx/GSRendererDX11.cpp @@ -25,16 +25,14 @@ #include "resource.h" GSRendererDX11::GSRendererDX11(uint8* base, bool mt, void (*irq)()) - : GSRendererDX(base, mt, irq, new GSDevice11(), new GSTextureCache11(this), new GSTextureFX11()) + : GSRendererDX(base, mt, irq, new GSDevice11(), new GSTextureCache11(this), new GSTextureFX11(), GSVector2(-0.5f, -0.5f)) { InitVertexKick(); - - m_pixelcenter = GSVector2(-0.5f, -0.5f); } -bool GSRendererDX11::Create(const string& title) +bool GSRendererDX11::Create(const string& title, int w, int h) { - if(!__super::Create(title)) + if(!__super::Create(title, w, h)) return false; // @@ -88,9 +86,11 @@ void GSRendererDX11::VertexKick(bool skip) { GSVector4i scissor = m_context->scissor.dx10; + GSVector4i pmin, pmax; + #if _M_SSE >= 0x401 - GSVector4i pmin, pmax, v0, v1, v2; + GSVector4i v0, v1, v2; switch(prim) { @@ -118,59 +118,60 @@ void GSRendererDX11::VertexKick(bool skip) break; } + #else + + switch(prim) + { + case GS_POINTLIST: + pmin.x = v[0].p.x; + pmin.y = v[0].p.y; + pmax.x = v[0].p.x; + pmax.y = v[0].p.y; + break; + case GS_LINELIST: + case GS_LINESTRIP: + case GS_SPRITE: + pmin.x = std::min(v[0].p.x, v[1].p.x); + pmin.y = std::min(v[0].p.y, v[1].p.y); + pmax.x = std::max(v[0].p.x, v[1].p.x); + pmax.y = std::max(v[0].p.y, v[1].p.y); + break; + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + pmin.x = std::min(std::min(v[0].p.x, v[1].p.x), v[2].p.x); + pmin.y = std::min(std::min(v[0].p.y, v[1].p.y), v[2].p.y); + pmax.x = std::max(std::max(v[0].p.x, v[1].p.x), v[2].p.x); + pmax.y = std::max(std::max(v[0].p.y, v[1].p.y), v[2].p.y); + break; + } + + #endif + GSVector4i test = (pmax < scissor) | (pmin > scissor.zwxy()); + switch(prim) + { + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + case GS_SPRITE: + test |= pmin == pmax; + break; + } + if(test.mask() & 0xff) { return; } - #else - - switch(prim) - { - case GS_POINTLIST: - if(v[0].p.x < scissor.x - || v[0].p.x > scissor.z - || v[0].p.y < scissor.y - || v[0].p.y > scissor.w) - { - return; - } - break; - case GS_LINELIST: - case GS_LINESTRIP: - case GS_SPRITE: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w) - { - return; - } - break; - case GS_TRIANGLELIST: - case GS_TRIANGLESTRIP: - case GS_TRIANGLEFAN: - if(v[0].p.x < scissor.x && v[1].p.x < scissor.x && v[2].p.x < scissor.x - || v[0].p.x > scissor.z && v[1].p.x > scissor.z && v[2].p.x > scissor.z - || v[0].p.y < scissor.y && v[1].p.y < scissor.y && v[2].p.y < scissor.y - || v[0].p.y > scissor.w && v[1].p.y > scissor.w && v[2].p.y > scissor.w) - { - return; - } - break; - } - - #endif - m_count += count; } } -void GSRendererDX11::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +void GSRendererDX11::Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) { - switch(primclass) + switch(m_vt.m_primclass) { case GS_POINT_CLASS: m_topology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; @@ -189,7 +190,7 @@ void GSRendererDX11::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, __assume(0); } - __super::Draw(primclass, rt, ds, tex); + __super::Draw(rt, ds, tex); } void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds) @@ -198,10 +199,9 @@ void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds) GSDevice11* dev = (GSDevice11*)m_dev; - int w = rt->GetWidth(); - int h = rt->GetHeight(); + const GSVector2i& size = rt->m_size; - if(GSTexture* t = dev->CreateRenderTarget(w, h)) + if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y)) { // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows @@ -217,7 +217,7 @@ void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds) // ia - GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 s = GSVector4(rt->m_scale.x / size.x, rt->m_scale.y / size.y); GSVector4 o = GSVector4(-1.0f, 1.0f); GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); @@ -249,11 +249,7 @@ void GSRendererDX11::SetupDATE(GSTexture* rt, GSTexture* ds) dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL); dev->PSSetSamplerState(dev->m_convert.pt, NULL); - // rs - - dev->RSSet(w, h); - - // set + // dev->DrawPrimitive(); diff --git a/plugins/GSdx/GSRendererDX11.h b/plugins/GSdx/GSRendererDX11.h index e30f2e7c07..1e26df8863 100644 --- a/plugins/GSdx/GSRendererDX11.h +++ b/plugins/GSdx/GSRendererDX11.h @@ -29,7 +29,7 @@ class GSRendererDX11 : public GSRendererDX { protected: - void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); + void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); struct { @@ -42,7 +42,7 @@ protected: public: GSRendererDX11(uint8* base, bool mt, void (*irq)()); - bool Create(const string& title); + bool Create(const string& title, int w, int h); template void VertexKick(bool skip); }; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX9.cpp b/plugins/GSdx/GSRendererDX9.cpp index b32a51c100..819c81d2e1 100644 --- a/plugins/GSdx/GSRendererDX9.cpp +++ b/plugins/GSdx/GSRendererDX9.cpp @@ -30,9 +30,9 @@ GSRendererDX9::GSRendererDX9(uint8* base, bool mt, void (*irq)()) InitVertexKick(); } -bool GSRendererDX9::Create(const string& title) +bool GSRendererDX9::Create(const string& title, int w, int h) { - if(!__super::Create(title)) + if(!__super::Create(title, w, h)) return false; // @@ -135,6 +135,16 @@ void GSRendererDX9::VertexKick(bool skip) GSVector4 test = (pmax < scissor) | (pmin > scissor.zwxy()); + switch(prim) + { + case GS_TRIANGLELIST: + case GS_TRIANGLESTRIP: + case GS_TRIANGLEFAN: + case GS_SPRITE: + test |= pmin == pmax; + break; + } + if(test.mask() & 3) { return; @@ -174,9 +184,9 @@ void GSRendererDX9::VertexKick(bool skip) } } -void GSRendererDX9::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +void GSRendererDX9::Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) { - switch(primclass) + switch(m_vt.m_primclass) { case GS_POINT_CLASS: m_topology = D3DPT_POINTLIST; @@ -197,7 +207,7 @@ void GSRendererDX9::Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, (*(GSDevice9*)m_dev)->SetRenderState(D3DRS_SHADEMODE, PRIM->IIP ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); // TODO - __super::Draw(primclass, rt, ds, tex); + __super::Draw(rt, ds, tex); } void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds) @@ -206,10 +216,9 @@ void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds) GSDevice9* dev = (GSDevice9*)m_dev; - int w = rt->GetWidth(); - int h = rt->GetHeight(); + const GSVector2i& size = rt->m_size; - if(GSTexture* t = dev->CreateRenderTarget(w, h)) + if(GSTexture* t = dev->CreateRenderTarget(size.x, size.y)) { // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows @@ -225,7 +234,7 @@ void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds) // ia - GSVector4 s = GSVector4(rt->m_scale.x / w, rt->m_scale.y / h); + GSVector4 s = GSVector4(rt->m_scale.x / size.x, rt->m_scale.y / size.y); GSVector4 o = GSVector4(-1.0f, 1.0f); GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); @@ -253,10 +262,6 @@ void GSRendererDX9::SetupDATE(GSTexture* rt, GSTexture* ds) dev->PSSetShader(dev->m_convert.ps[m_context->TEST.DATM ? 2 : 3], NULL, 0); dev->PSSetSamplerState(&dev->m_convert.pt); - // rs - - dev->RSSet(w, h); - // dev->DrawPrimitive(); @@ -282,7 +287,7 @@ void GSRendererDX9::UpdateFBA(GSTexture* rt) // ia - GSVector4 s = GSVector4(rt->m_scale.x / rt->GetWidth(), rt->m_scale.y / rt->GetHeight()); + GSVector4 s = GSVector4(rt->m_scale.x / rt->m_size.x, rt->m_scale.y / rt->m_size.y); GSVector4 o = GSVector4(-1.0f, 1.0f); GSVector4 src = ((m_vt.m_min.p.xyxy(m_vt.m_max.p) + o.xxyy()) * s.xyxy()).sat(o.zzyy()); @@ -308,10 +313,6 @@ void GSRendererDX9::UpdateFBA(GSTexture* rt) dev->PSSetShader(dev->m_convert.ps[4], NULL, 0); - // rs - - dev->RSSet(rt->GetWidth(), rt->GetHeight()); - // dev->DrawPrimitive(); diff --git a/plugins/GSdx/GSRendererDX9.h b/plugins/GSdx/GSRendererDX9.h index 1bebe4e490..5111d942f9 100644 --- a/plugins/GSdx/GSRendererDX9.h +++ b/plugins/GSdx/GSRendererDX9.h @@ -41,14 +41,14 @@ protected: Direct3DBlendState9 bs; } m_fba; - void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); + void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); void SetupDATE(GSTexture* rt, GSTexture* ds); void UpdateFBA(GSTexture* rt); public: GSRendererDX9(uint8* base, bool mt, void (*irq)()); - bool Create(const string& title); + bool Create(const string& title, int w, int h); template void VertexKick(bool skip); }; diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index d55a7f4d72..9e8459c500 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -24,6 +24,8 @@ #include "GSRenderer.h" #include "GSTextureCache.h" #include "GSCrc.h" +#include "GSFunctionMap.h" + template class GSRendererHW : public GSRendererT @@ -33,6 +35,418 @@ class GSRendererHW : public GSRendererT int m_skip; bool m_reset; + #pragma region hacks + + typedef bool (GSRendererHW::*OI_Ptr)(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); + typedef void (GSRendererHW::*OO_Ptr)(); + typedef bool (GSRendererHW::*CU_Ptr)(); + + bool OI_FFXII(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + { + static uint32* video = NULL; + static int lines = 0; + + if(lines == 0) + { + if(m_vt.m_primclass == GS_LINE_CLASS && (m_count == 448 * 2 || m_count == 512 * 2)) + { + lines = m_count / 2; + } + } + else + { + if(m_vt.m_primclass == GS_POINT_CLASS) + { + if(m_count >= 16 * 512) + { + // incoming pixels are stored in columns, one column is 16x512, total res 448x512 or 448x454 + + if(!video) video = new uint32[512 * 512]; + + int ox = m_context->XYOFFSET.OFX; + int oy = m_context->XYOFFSET.OFY; + + for(int i = 0; i < m_count; i++) + { + int x = ((int)m_vertices[i].p.x - ox) >> 4; + int y = ((int)m_vertices[i].p.y - oy) >> 4; + + // video[y * 448 + x] = m_vertices[i].c0; + video[(y << 8) + (y << 7) + (y << 6) + x] = m_vertices[i].c0; + } + + return false; + } + else + { + lines = 0; + } + } + else if(m_vt.m_primclass == GS_LINE_CLASS) + { + if(m_count == lines * 2) + { + // normally, this step would copy the video onto screen with 512 texture mapped horizontal lines, + // but we use the stored video data to create a new texture, and replace the lines with two triangles + + m_dev->Recycle(t->m_texture); + + t->m_texture = m_dev->CreateTexture(512, 512); + + t->m_texture->Update(GSVector4i(0, 0, 448, lines), video, 448 * 4); + + m_vertices[0] = m_vertices[0]; + m_vertices[1] = m_vertices[1]; + m_vertices[2] = m_vertices[m_count - 2]; + m_vertices[3] = m_vertices[1]; + m_vertices[4] = m_vertices[2]; + m_vertices[5] = m_vertices[m_count - 1]; + + m_count = 6; + + m_vt.Update(m_vertices, m_count, GS_TRIANGLE_CLASS); + } + else + { + lines = 0; + } + } + } + + return true; + } + + bool OI_FFX(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + { + uint32 FBP = m_context->FRAME.Block(); + uint32 ZBP = m_context->ZBUF.Block(); + uint32 TBP = m_context->TEX0.TBP0; + + if((FBP == 0x00d00 || FBP == 0x00000) && ZBP == 0x02100 && PRIM->TME && TBP == 0x01a00 && m_context->TEX0.PSM == PSM_PSMCT16S) + { + // random battle transition (z buffer written directly, clear it now) + + m_dev->ClearDepth(ds, 0); + } + + return true; + } + + bool OI_MetalSlug6(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + { + // missing red channel fix + + for(int i = 0, j = m_count; i < j; i++) + { + if(m_vertices[i].r == 0 && m_vertices[i].g != 0 && m_vertices[i].b != 0) + { + m_vertices[i].r = (m_vertices[i].g + m_vertices[i].b) / 2; + } + } + + m_vt.Update(m_vertices, m_count, m_vt.m_primclass); + + return true; + } + + bool OI_GodOfWar2(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + { + uint32 FBP = m_context->FRAME.Block(); + uint32 FBW = m_context->FRAME.FBW; + uint32 FPSM = m_context->FRAME.PSM; + + if((FBP == 0x00f00 || FBP == 0x00100) && FPSM == PSM_PSMZ24) // ntsc 0xf00, pal 0x100 + { + // z buffer clear + + GIFRegTEX0 TEX0; + + TEX0.TBP0 = FBP; + TEX0.TBW = FBW; + TEX0.PSM = FPSM; + + if(GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, true)) + { + m_dev->ClearDepth(ds->m_texture, 0); + } + + return false; + } + + return true; + } + + bool OI_SimpsonsGame(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + { + uint32 FBP = m_context->FRAME.Block(); + uint32 FBW = m_context->FRAME.FBW; + uint32 FPSM = m_context->FRAME.PSM; + + if(FBP == 0x01800 && FPSM == PSM_PSMZ24) + { + // instead of just simply drawing a full height 512x512 sprite to clear the z buffer, + // it uses a 512x256 sprite only, yet it is still able to fill the whole surface with zeros, + // how? by using a render target that overlaps with the lower half of the z buffer... + + m_dev->ClearDepth(ds, 0); + + return false; + } + + return true; + } + + bool OI_RozenMaidenGebetGarden(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + { + if(!PRIM->TME) + { + uint32 FBP = m_context->FRAME.Block(); + uint32 ZBP = m_context->ZBUF.Block(); + + if(FBP == 0x008c0 && ZBP == 0x01a40) + { + // frame buffer clear, atst = fail, afail = write z only, z buffer points to frame buffer + + GIFRegTEX0 TEX0; + + TEX0.TBP0 = ZBP; + TEX0.TBW = m_context->FRAME.FBW; + TEX0.PSM = m_context->FRAME.PSM; + + if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true)) + { + m_dev->ClearRenderTarget(rt->m_texture, 0); + } + + return false; + } + else if(FBP == 0x00000 && m_context->ZBUF.Block() == 0x01180) + { + // z buffer clear, frame buffer now points to the z buffer (how can they be so clever?) + + GIFRegTEX0 TEX0; + + TEX0.TBP0 = FBP; + TEX0.TBW = m_context->FRAME.FBW; + TEX0.PSM = m_context->ZBUF.PSM; + + if(GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, true)) + { + m_dev->ClearDepth(ds->m_texture, 0); + } + + return false; + } + } + + return true; + } + + bool OI_PointListPalette(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) + { + if(m_vt.m_primclass == GS_POINT_CLASS && !PRIM->TME) + { + uint32 FBP = m_context->FRAME.Block(); + uint32 FBW = m_context->FRAME.FBW; + + if(FBP >= 0x03f40 && (FBP & 0x1f) == 0) + { + if(m_count == 16) + { + for(int i = 0; i < 16; i++) + { + m_vertices[i].a = m_vertices[i].a >= 0x80 ? 0xff : m_vertices[i].a * 2; + + m_mem.WritePixel32(i & 7, i >> 3, m_vertices[i].c0, FBP, FBW); + } + + m_mem.m_clut.Invalidate(); + + return false; + } + else if(m_count == 256) + { + for(int i = 0; i < 256; i++) + { + m_vertices[i].a = m_vertices[i].a >= 0x80 ? 0xff : m_vertices[i].a * 2; + + m_mem.WritePixel32(i & 15, i >> 4, m_vertices[i].c0, FBP, FBW); + } + + m_mem.m_clut.Invalidate(); + + return false; + } + else + { + ASSERT(0); + } + } + } + + return true; + } + + void OO_DBZBT2() + { + // palette readback (cannot detect yet, when fetching the texture later) + + uint32 FBP = m_context->FRAME.Block(); + uint32 TBP0 = m_context->TEX0.TBP0; + + if(PRIM->TME && (FBP == 0x03c00 && TBP0 == 0x03c80 || FBP == 0x03ac0 && TBP0 == 0x03b40)) + { + GIFRegBITBLTBUF BITBLTBUF; + + BITBLTBUF.SBP = FBP; + BITBLTBUF.SBW = 1; + BITBLTBUF.SPSM = PSM_PSMCT32; + + InvalidateLocalMem(BITBLTBUF, GSVector4i(0, 0, 64, 64)); + } + } + + void OO_MajokkoALaMode2() + { + // palette readback + + uint32 FBP = m_context->FRAME.Block(); + + if(!PRIM->TME && FBP == 0x03f40) + { + GIFRegBITBLTBUF BITBLTBUF; + + BITBLTBUF.SBP = FBP; + BITBLTBUF.SBW = 1; + BITBLTBUF.SPSM = PSM_PSMCT32; + + InvalidateLocalMem(BITBLTBUF, GSVector4i(0, 0, 16, 16)); + } + } + + bool CU_DBZBT2() + { + // palette should stay 64 x 64 + + uint32 FBP = m_context->FRAME.Block(); + + return FBP != 0x03c00 && FBP != 0x03ac0; + } + + bool CU_MajokkoALaMode2() + { + // palette should stay 16 x 16 + + uint32 FBP = m_context->FRAME.Block(); + + return FBP != 0x03f40; + } + + bool CU_TalesOfAbyss() + { + // full image blur and brightening + + uint32 FBP = m_context->FRAME.Block(); + + return FBP != 0x036e0 && FBP != 0x03560 && FBP != 0x038e0; + } + + class Hacks + { + template struct HackEntry + { + CRC::Title title; + CRC::Region region; + T func; + + struct HackEntry(CRC::Title t, CRC::Region r, T f) + { + title = t; + region = r; + func = f; + } + }; + + template class FunctionMap : public GSFunctionMap + { + list >& m_tbl; + + T GetDefaultFunction(uint32 key) + { + CRC::Title title = (CRC::Title)(key & 0xffffff); + CRC::Region region = (CRC::Region)(key >> 24); + + for(list >::iterator i = m_tbl.begin(); i != m_tbl.end(); i++) + { + if(i->title == title && (i->region == CRC::RegionCount || i->region == region)) + { + return i->func; + } + } + + return NULL; + } + + public: + FunctionMap(list >& tbl) : m_tbl(tbl) {} + }; + + list > m_oi_list; + list > m_oo_list; + list > m_cu_list; + + FunctionMap m_oi_map; + FunctionMap m_oo_map; + FunctionMap m_cu_map; + + public: + OI_Ptr m_oi; + OO_Ptr m_oo; + CU_Ptr m_cu; + + Hacks() + : m_oi_map(m_oi_list) + , m_oo_map(m_oo_list) + , m_cu_map(m_cu_list) + , m_oi(NULL) + , m_oo(NULL) + , m_cu(NULL) + { + m_oi_list.push_back(HackEntry(CRC::FFXII, CRC::EU, &GSRendererHW::OI_FFXII)); + m_oi_list.push_back(HackEntry(CRC::FFX, CRC::RegionCount, &GSRendererHW::OI_FFX)); + m_oi_list.push_back(HackEntry(CRC::MetalSlug6, CRC::RegionCount, &GSRendererHW::OI_MetalSlug6)); + m_oi_list.push_back(HackEntry(CRC::GodOfWar2, CRC::RegionCount, &GSRendererHW::OI_GodOfWar2)); + m_oi_list.push_back(HackEntry(CRC::SimpsonsGame, CRC::RegionCount, &GSRendererHW::OI_SimpsonsGame)); + m_oi_list.push_back(HackEntry(CRC::RozenMaidenGebetGarden, CRC::RegionCount, &GSRendererHW::OI_RozenMaidenGebetGarden)); + + m_oo_list.push_back(HackEntry(CRC::DBZBT2, CRC::RegionCount, &GSRendererHW::OO_DBZBT2)); + m_oo_list.push_back(HackEntry(CRC::MajokkoALaMode2, CRC::RegionCount, &GSRendererHW::OO_MajokkoALaMode2)); + + m_cu_list.push_back(HackEntry(CRC::DBZBT2, CRC::RegionCount, &GSRendererHW::CU_DBZBT2)); + m_cu_list.push_back(HackEntry(CRC::MajokkoALaMode2, CRC::RegionCount, &GSRendererHW::CU_MajokkoALaMode2)); + m_cu_list.push_back(HackEntry(CRC::TalesOfAbyss, CRC::RegionCount, &GSRendererHW::CU_TalesOfAbyss)); + } + + void SetGame(const CRC::Game& game) + { + uint32 hash = (uint32)((game.region << 24) | game.title); + + m_oi = m_oi_map[hash]; + m_oo = m_oo_map[hash]; + m_cu = m_cu_map[hash]; + + if(game.flags & CRC::PointListPalette) + { + ASSERT(m_oi == NULL); + + m_oi = &GSRendererHW::OI_PointListPalette; + } + } + + } m_hacks; + + #pragma endregion + protected: GSTextureCache* m_tc; @@ -103,22 +517,20 @@ protected: { // printf("[%d] InvalidateVideoMem %d,%d - %d,%d %05x (%d)\n", (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.DBP, (int)BITBLTBUF.DPSM); - m_tc->InvalidateVideoMem(BITBLTBUF, r); + m_tc->InvalidateVideoMem(m_mem.GetOffset(BITBLTBUF.DBP, BITBLTBUF.DBW, BITBLTBUF.DPSM), r); } void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) { // printf("[%d] InvalidateLocalMem %d,%d - %d,%d %05x (%d)\n", (int)m_perfmon.GetFrame(), r.left, r.top, r.right, r.bottom, (int)BITBLTBUF.SBP, (int)BITBLTBUF.SPSM); - m_tc->InvalidateLocalMem(BITBLTBUF, r); + m_tc->InvalidateLocalMem(m_mem.GetOffset(BITBLTBUF.SBP, BITBLTBUF.SBW, BITBLTBUF.SPSM), r); } void Draw() { if(IsBadFrame(m_skip)) return; - m_vt.Update(m_vertices, m_count, GSUtil::GetPrimClass(PRIM->PRIM), PRIM, m_context); - GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; @@ -194,9 +606,7 @@ protected: s_n++; } - int prim = PRIM->PRIM; - - if(!OverrideInput(prim, rt->m_texture, ds->m_texture, tex)) + if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt->m_texture, ds->m_texture, tex)) { return; } @@ -223,7 +633,7 @@ protected: // - Draw(GSUtil::GetPrimClass(prim), rt->m_texture, ds->m_texture, tex); + Draw(rt->m_texture, ds->m_texture, tex); // @@ -235,29 +645,26 @@ protected: GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(m_context->scissor.in)); - GIFRegBITBLTBUF BITBLTBUF; - - BITBLTBUF.DBW = context->FRAME.FBW; - if(fm != 0xffffffff) { - BITBLTBUF.DBP = context->FRAME.Block(); - BITBLTBUF.DPSM = context->FRAME.PSM; + rt->m_valid = rt->m_valid.runion(r); - m_tc->InvalidateVideoMem(BITBLTBUF, r, false); + m_tc->InvalidateVideoMem(m_context->offset.fb, r, false); } if(zm != 0xffffffff) { - BITBLTBUF.DBP = context->ZBUF.Block(); - BITBLTBUF.DPSM = context->ZBUF.PSM; + ds->m_valid = ds->m_valid.runion(r); - m_tc->InvalidateVideoMem(BITBLTBUF, r, false); + m_tc->InvalidateVideoMem(m_context->offset.zb, r, false); } // - OverrideOutput(); + if(m_hacks.m_oo) + { + (this->*m_hacks.m_oo)(); + } if(s_dump) { @@ -283,297 +690,15 @@ protected: } } - virtual void Draw(GS_PRIM_CLASS primclass, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) = 0; - - virtual bool OverrideInput(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) - { - #pragma region ffxii pal video conversion - - if(m_game.title == CRC::FFXII && m_game.region == CRC::EU) - { - static uint32* video = NULL; - static bool ok = false; - - if(prim == GS_POINTLIST && m_count >= 448 * 448 && m_count <= 448 * 512) - { - // incoming pixels are stored in columns, one column is 16x512, total res 448x512 or 448x454 - - if(!video) video = new uint32[512 * 512]; - - for(int x = 0, i = 0, rows = m_count / 448; x < 448; x += 16) - { - uint32* dst = &video[x]; - - for(int y = 0; y < rows; y++, dst += 512) - { - for(int j = 0; j < 16; j++, i++) - { - dst[j] = m_vertices[i].c0; - } - } - } - - ok = true; - - return false; - } - else if(prim == GS_LINELIST && m_count == 512 * 2 && ok) - { - // normally, this step would copy the video onto screen with 512 texture mapped horizontal lines, - // but we use the stored video data to create a new texture, and replace the lines with two triangles - - ok = false; - - m_dev->Recycle(t->m_texture); - - t->m_texture = m_dev->CreateTexture(512, 512); - - t->m_texture->Update(GSVector4i(0, 0, 448, 512), video, 512 * 4); - - m_vertices[0] = m_vertices[0]; - m_vertices[1] = m_vertices[1]; - m_vertices[2] = m_vertices[m_count - 2]; - m_vertices[3] = m_vertices[1]; - m_vertices[4] = m_vertices[2]; - m_vertices[5] = m_vertices[m_count - 1]; - - prim = GS_TRIANGLELIST; - m_count = 6; - - return true; - } - } - - #pragma endregion - - #pragma region ffx random battle transition (z buffer written directly, clear it now) - - if(m_game.title == CRC::FFX) - { - uint32 FBP = m_context->FRAME.Block(); - uint32 ZBP = m_context->ZBUF.Block(); - uint32 TBP = m_context->TEX0.TBP0; - - if((FBP == 0x00d00 || FBP == 0x00000) && ZBP == 0x02100 && PRIM->TME && TBP == 0x01a00 && m_context->TEX0.PSM == PSM_PSMCT16S) - { - m_dev->ClearDepth(ds, 0); - } - - return true; - } - - #pragma endregion - - #pragma region metal slug missing red channel fix - - if(m_game.title == CRC::MetalSlug6) - { - for(int i = 0, j = m_count; i < j; i++) - { - if(m_vertices[i].r == 0 && m_vertices[i].g != 0 && m_vertices[i].b != 0) - { - m_vertices[i].r = (m_vertices[i].g + m_vertices[i].b) / 2; - } - } - - return true; - } - - #pragma endregion - - #pragma region palette uploaded in a point list, pure genius... - - if(m_game.flags & CRC::PointListPalette) - { - if(prim == GS_POINTLIST && !PRIM->TME) - { - uint32 bp = m_context->FRAME.Block(); - uint32 bw = m_context->FRAME.FBW; - - if(bp >= 0x03f40 && (bp & 0x1f) == 0) - { - if(m_count == 16) - { - for(int i = 0; i < 16; i++) - { - m_vertices[i].a = m_vertices[i].a >= 0x80 ? 0xff : m_vertices[i].a * 2; - - m_mem.WritePixel32(i & 7, i >> 3, m_vertices[i].c0, bp, bw); - } - - m_mem.m_clut.Invalidate(); - - return false; - } - else if(m_count == 256) - { - for(int i = 0; i < 256; i++) - { - m_vertices[i].a = m_vertices[i].a >= 0x80 ? 0xff : m_vertices[i].a * 2; - - m_mem.WritePixel32(i & 15, i >> 4, m_vertices[i].c0, bp, bw); - } - - m_mem.m_clut.Invalidate(); - - return false; - } - else - { - ASSERT(0); - } - } - } - - return true; - } - - #pragma endregion - - #pragma region GoW2 z buffer clear - - if(m_game.title == CRC::GodOfWar2) - { - uint32 FBP = m_context->FRAME.Block(); - uint32 FBW = m_context->FRAME.FBW; - uint32 FPSM = m_context->FRAME.PSM; - - if((FBP == 0x00f00 || FBP == 0x00100) && FPSM == PSM_PSMZ24) // ntsc 0xf00, pal 0x100 - { - GIFRegTEX0 TEX0; - - TEX0.TBP0 = FBP; - TEX0.TBW = FBW; - TEX0.PSM = FPSM; - - if(GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, true)) - { - m_dev->ClearDepth(ds->m_texture, 0); - } - - return false; - } - - return true; - } - - #pragma endregion - - #pragma region Simpsons Game z buffer clear - - if(m_game.title == CRC::SimpsonsGame) - { - uint32 FBP = m_context->FRAME.Block(); - uint32 FBW = m_context->FRAME.FBW; - uint32 FPSM = m_context->FRAME.PSM; - - if(FBP == 0x01800 && FPSM == PSM_PSMZ24) - { - // instead of just simply drawing a full height 512x512 sprite to clear the z buffer, - // it uses a 512x256 sprite only, yet it is still able to fill the whole surface with zeros, - // how? by using a render target that overlaps with the lower half of the z buffer... - - m_dev->ClearDepth(ds, 0); - - return false; - } - - return true; - } - - #pragma endregion - - return true; - } - - virtual void OverrideOutput() - { - #pragma region dbzbt2 palette readback (cannot detect yet, when fetching the texture later) - - if(m_game.title == CRC::DBZBT2) - { - uint32 FBP = m_context->FRAME.Block(); - uint32 TBP0 = m_context->TEX0.TBP0; - - if(PRIM->TME && (FBP == 0x03c00 && TBP0 == 0x03c80 || FBP == 0x03ac0 && TBP0 == 0x03b40)) - { - GIFRegBITBLTBUF BITBLTBUF; - - BITBLTBUF.SBP = FBP; - BITBLTBUF.SBW = 1; - BITBLTBUF.SPSM = PSM_PSMCT32; - - InvalidateLocalMem(BITBLTBUF, GSVector4i(0, 0, 64, 64)); - } - } - - #pragma endregion - - #pragma region MajokkoALaMode2 palette readback - - if(m_game.title == CRC::MajokkoALaMode2) - { - uint32 FBP = m_context->FRAME.Block(); - - if(!PRIM->TME && FBP == 0x03f40) - { - GIFRegBITBLTBUF BITBLTBUF; - - BITBLTBUF.SBP = FBP; - BITBLTBUF.SBW = 1; - BITBLTBUF.SPSM = PSM_PSMCT32; - - InvalidateLocalMem(BITBLTBUF, GSVector4i(0, 0, 16, 16)); - } - } - - #pragma endregion - } + virtual void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) = 0; bool CanUpscale() { - #pragma region dbzbt2 palette should stay 64 x 64 - - if(m_game.title == CRC::DBZBT2) + if(m_hacks.m_cu && !(this->*m_hacks.m_cu)()) { - uint32 FBP = m_context->FRAME.Block(); - - if(FBP == 0x03c00 || FBP == 0x03ac0) - { - return false; - } + return false; } - #pragma endregion - - #pragma region MajokkoALaMode2 palette should stay 16 x 16 - - if(m_game.title == CRC::MajokkoALaMode2) - { - uint32 FBP = m_context->FRAME.Block(); - - if(FBP == 0x03f40) - { - return false; - } - } - - #pragma endregion - - #pragma region TalesOfAbyss full image blur and brightening - - if(m_game.title == CRC::TalesOfAbyss) - { - uint32 FBP = m_context->FRAME.Block(); - - if(FBP == 0x036e0 || FBP == 0x03560 || FBP == 0x038e0) - { - return false; - } - } - - #pragma endregion - return __super::CanUpscale(); } @@ -602,6 +727,8 @@ public: { __super::SetGameCRC(crc, options); + m_hacks.SetGame(m_game); + if(m_game.title == CRC::JackieChanAdv) { m_width = 1280; // TODO: uses a 1280px wide 16 bit render target, but this only fixes half of the problem diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 107eea2bab..6ccaffa838 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -30,9 +30,9 @@ GSRendererOGL::GSRendererOGL(uint8* base, bool mt, void (*irq)()) InitVertexKick(); } -bool GSRendererOGL::Create(const string& title) +bool GSRendererOGL::Create(const string& title, int w, int h) { - if(!__super::Create(title)) + if(!__super::Create(title, w, h)) return false; // TODO @@ -64,7 +64,7 @@ void GSRendererOGL::VertexKick(bool skip) } } -void GSRendererOGL::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) +void GSRendererOGL::Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) { GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h index 9dc3587b93..14c6b84c21 100644 --- a/plugins/GSdx/GSRendererOGL.h +++ b/plugins/GSdx/GSRendererOGL.h @@ -29,12 +29,12 @@ class GSRendererOGL : public GSRendererHW { protected: - void Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); + void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); public: GSRendererOGL(uint8* base, bool mt, void (*irq)()); - bool Create(const string& title); + bool Create(const string& title, int w, int h); template void VertexKick(bool skip); }; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 0302b866de..fc6a4f7c0c 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -86,13 +86,7 @@ GSTexture* GSRendererSW::GetOutput(int i) { const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB; - GIFRegTEX0 TEX0; - - TEX0.TBP0 = DISPFB.Block(); - TEX0.TBW = DISPFB.FBW; - TEX0.PSM = DISPFB.PSM; - - int w = TEX0.TBW * 64; + int w = DISPFB.FBW * 64; int h = GetFrameRect(i).bottom; // TODO: round up bottom @@ -105,7 +99,9 @@ GSTexture* GSRendererSW::GetOutput(int i) GSVector4i r(0, 0, w, h); - m_mem.ReadTexture(r, buff, pitch, TEX0, m_env.TEXA); + const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[DISPFB.PSM]; + + (m_mem.*psm.rtx)(m_mem.GetOffset(DISPFB.Block(), DISPFB.FBW, DISPFB.PSM), r.ralign(psm.bs), buff, pitch, m_env.TEXA); m_texture[i]->Update(r, buff, pitch); @@ -113,7 +109,7 @@ GSTexture* GSRendererSW::GetOutput(int i) { if(s_save && s_n >= s_saven) { - m_texture[i]->Save(format("c:\\temp1\\_%05d_f%I64d_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM)); + m_texture[i]->Save(format("c:\\temp1\\_%05d_f%I64d_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)DISPFB.Block(), (int)DISPFB.PSM)); } s_n++; @@ -125,18 +121,14 @@ GSTexture* GSRendererSW::GetOutput(int i) void GSRendererSW::Draw() { - GS_PRIM_CLASS primclass = GSUtil::GetPrimClass(PRIM->PRIM); - - m_vt.Update(m_vertices, m_count, primclass, PRIM, m_context); - if(m_dump) { - m_dump.Object(m_vertices, m_count, primclass); + m_dump.Object(m_vertices, m_count, m_vt.m_primclass); } GSScanlineParam p; - GetScanlineParam(p, primclass); + GetScanlineParam(p, m_vt.m_primclass); if((p.fm & p.zm) == 0xffffffff) { @@ -179,7 +171,7 @@ void GSRendererSW::Draw() data.scissor = GSVector4i(m_context->scissor.in); data.scissor.z = min(data.scissor.z, (int)m_context->FRAME.FBW * 64); // TODO: find a game that overflows and check which one is the right behaviour - data.primclass = primclass; + data.primclass = m_vt.m_primclass; data.vertices = m_vertices; data.count = m_count; data.param = &p; @@ -190,30 +182,19 @@ void GSRendererSW::Draw() m_rl.GetStats(stats); - m_perfmon.Put(GSPerfMon::Draw, 1); m_perfmon.Put(GSPerfMon::Prim, stats.prims); m_perfmon.Put(GSPerfMon::Fillrate, stats.pixels); GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(data.scissor); - GIFRegBITBLTBUF BITBLTBUF; - - BITBLTBUF.DBW = m_context->FRAME.FBW; - if(p.fm != 0xffffffff) { - BITBLTBUF.DBP = m_context->FRAME.Block(); - BITBLTBUF.DPSM = m_context->FRAME.PSM; - - m_tc->InvalidateVideoMem(BITBLTBUF, r); + m_tc->InvalidateVideoMem(m_context->offset.fb, r); } if(p.zm != 0xffffffff) { - BITBLTBUF.DBP = m_context->ZBUF.Block(); - BITBLTBUF.DPSM = m_context->ZBUF.PSM; - - m_tc->InvalidateVideoMem(BITBLTBUF, r); + m_tc->InvalidateVideoMem(m_context->offset.zb, r); } if(s_dump) @@ -251,7 +232,7 @@ void GSRendererSW::Draw() void GSRendererSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) { - m_tc->InvalidateVideoMem(BITBLTBUF, r); + m_tc->InvalidateVideoMem(m_mem.GetOffset(BITBLTBUF.DBP, BITBLTBUF.DBW, BITBLTBUF.DPSM), r); } void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) @@ -261,9 +242,9 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) p.vm = m_mem.m_vm8; - p.fbo = m_mem.GetPixelOffset(context->FRAME.Block(), context->FRAME.FBW, context->FRAME.PSM); - p.zbo = m_mem.GetPixelOffset(context->ZBUF.Block(), context->FRAME.FBW, context->ZBUF.PSM); - p.fzbo = m_mem.GetPixelOffset4(context->FRAME, context->ZBUF); + p.fbo = context->offset.fb; + p.zbo = context->offset.zb; + p.fzbo = context->offset.fzb; p.sel.key = 0; @@ -305,7 +286,7 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) if(fwrite || ftest) { - p.sel.fpsm = GSUtil::EncodePSM(context->FRAME.PSM); + p.sel.fpsm = GSLocalMemory::m_psm[context->FRAME.PSM].fmt; if((primclass == GS_LINE_CLASS || primclass == GS_TRIANGLE_CLASS) && m_vt.m_eq.rgba != 0xffff) { @@ -322,7 +303,7 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) p.sel.wms = context->CLAMP.WMS; p.sel.wmt = context->CLAMP.WMT; - if(/*p.sel.iip == 0 &&*/ p.sel.tfx == TFX_MODULATE && p.sel.tcc && m_vt.m_eq.rgba == 0xffff && m_vt.m_min.c.eq(GSVector4i(128))) + if(p.sel.tfx == TFX_MODULATE && p.sel.tcc && m_vt.m_eq.rgba == 0xffff && m_vt.m_min.c.eq(GSVector4i(128))) { // modulate does not do anything when vertex color is 0x80 @@ -433,15 +414,15 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass) } bool zwrite = p.zm != 0xffffffff; - bool ztest = context->TEST.ZTE && context->TEST.ZTST > 1; + bool ztest = context->TEST.ZTE && context->TEST.ZTST > ZTST_ALWAYS; p.sel.zwrite = zwrite; p.sel.ztest = ztest; if(zwrite || ztest) { - p.sel.zpsm = GSUtil::EncodePSM(context->ZBUF.PSM); - p.sel.ztst = ztest ? context->TEST.ZTST : 1; + p.sel.zpsm = GSLocalMemory::m_psm[context->ZBUF.PSM].fmt; + p.sel.ztst = ztest ? context->TEST.ZTST : ZTST_ALWAYS; p.sel.zoverflow = GSVector4i(m_vt.m_max.p).z == 0x80000000; } } diff --git a/plugins/GSdx/GSScanlineEnvironment.h b/plugins/GSdx/GSScanlineEnvironment.h index bbe30b8eda..48abcc707c 100644 --- a/plugins/GSdx/GSScanlineEnvironment.h +++ b/plugins/GSdx/GSScanlineEnvironment.h @@ -108,9 +108,9 @@ __declspec(align(16)) struct GSScanlineParam const uint32* clut; uint32 tw; - GSLocalMemory::PixelOffset* fbo; - GSLocalMemory::PixelOffset* zbo; - GSLocalMemory::PixelOffset4* fzbo; + GSOffset* fbo; + GSOffset* zbo; + GSPixelOffset4* fzbo; uint32 fm, zm; }; diff --git a/plugins/GSdx/GSSettingsDlg.cpp b/plugins/GSdx/GSSettingsDlg.cpp index a897211214..2c9945b236 100644 --- a/plugins/GSdx/GSSettingsDlg.cpp +++ b/plugins/GSdx/GSSettingsDlg.cpp @@ -79,7 +79,7 @@ void GSSettingsDlg::OnInit() memset(&mode, 0, sizeof(mode)); m_modes.push_back(mode); - ComboBoxAppend(IDC_RESOLUTION, "Windowed", (LPARAM)&m_modes.back(), true); + ComboBoxAppend(IDC_RESOLUTION, "Please select...", (LPARAM)&m_modes.back(), true); if(CComPtr d3d = Direct3DCreate9(D3D_SDK_VERSION)) { @@ -120,6 +120,7 @@ void GSSettingsDlg::OnInit() ComboBoxInit(IDC_INTERLACE, g_interlace, countof(g_interlace), theApp.GetConfig("Interlace", 0)); ComboBoxInit(IDC_ASPECTRATIO, g_aspectratio, countof(g_aspectratio), theApp.GetConfig("AspectRatio", 1)); + CheckDlgButton(m_hWnd, IDC_WINDOWED, theApp.GetConfig("windowed", 1)); CheckDlgButton(m_hWnd, IDC_FILTER, theApp.GetConfig("filter", 2)); CheckDlgButton(m_hWnd, IDC_PALTEX, theApp.GetConfig("paltex", 1)); CheckDlgButton(m_hWnd, IDC_VSYNC, theApp.GetConfig("vsync", 0)); @@ -179,6 +180,7 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code) theApp.SetConfig("AspectRatio", (int)data); } + theApp.SetConfig("windowed", (int)IsDlgButtonChecked(m_hWnd, IDC_WINDOWED)); theApp.SetConfig("filter", (int)IsDlgButtonChecked(m_hWnd, IDC_FILTER)); theApp.SetConfig("paltex", (int)IsDlgButtonChecked(m_hWnd, IDC_PALTEX)); theApp.SetConfig("vsync", (int)IsDlgButtonChecked(m_hWnd, IDC_VSYNC)); @@ -215,7 +217,7 @@ void GSSettingsDlg::UpdateControls() // TODO: ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO11), dx11 ? SW_SHOW : SW_HIDE); // TODO: ShowWindow(GetDlgItem(m_hWnd, IDC_LOGO_OGL), ogl ? SW_SHOW : SW_HIDE); - EnableWindow(GetDlgItem(m_hWnd, IDC_RESOLUTION), dx9); + EnableWindow(GetDlgItem(m_hWnd, IDC_WINDOWED), dx9); EnableWindow(GetDlgItem(m_hWnd, IDC_RESX), hw && !native); EnableWindow(GetDlgItem(m_hWnd, IDC_RESX_EDIT), hw && !native); EnableWindow(GetDlgItem(m_hWnd, IDC_RESY), hw && !native); diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index a64b465165..4327a994cb 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -32,6 +32,7 @@ GSState::GSState(uint8* base, bool mt, void (*irq)()) , m_vprim(1) , m_version(5) , m_frameskip(0) + , m_framelimit(true) , m_vkf(NULL) { m_sssize = 0; @@ -421,7 +422,7 @@ void GSState::GIFRegHandlerPRIM(GIFReg* r) if(GSUtil::GetPrimClass(m_env.PRIM.PRIM) == GSUtil::GetPrimClass(r->PRIM.PRIM)) { - if(((m_env.PRIM.u64 ^ r->PRIM.u64) & ~7) != 0) + if((m_env.PRIM.u32[0] ^ r->PRIM.u32[0]) & 0x7f8) // all fields except PRIM { Flush(); } @@ -489,18 +490,23 @@ template void GSState::GIFRegHandlerTEX0(GIFReg* r) Flush(); } - m_env.CTXT[i].TEX0 = (GSVector4i)r->TEX0; + if(r->TEX0.TW > 10) r->TEX0.TW = 10; + if(r->TEX0.TH > 10) r->TEX0.TH = 10; - if(m_env.CTXT[i].TEX0.TW > 10) m_env.CTXT[i].TEX0.TW = 10; - if(m_env.CTXT[i].TEX0.TH > 10) m_env.CTXT[i].TEX0.TH = 10; + r->TEX0.CPSM &= 0xa; // 1010b - m_env.CTXT[i].TEX0.CPSM &= 0xa; // 1010b - - if((m_env.CTXT[i].TEX0.TBW & 1) && (m_env.CTXT[i].TEX0.PSM == PSM_PSMT8 || m_env.CTXT[i].TEX0.PSM == PSM_PSMT4)) + if((r->TEX0.TBW & 1) && (r->TEX0.PSM == PSM_PSMT8 || r->TEX0.PSM == PSM_PSMT4)) { - m_env.CTXT[i].TEX0.TBW &= ~1; // GS User 2.6 + r->TEX0.TBW &= ~1; // GS User 2.6 } + if((r->TEX0.u32[0] ^ m_env.CTXT[i].TEX0.u32[0]) & 0x3ffffff) // TBP0 TBW PSM + { + m_env.CTXT[i].offset.tex = m_mem.GetOffset(r->TEX0.TBP0, r->TEX0.TBW, r->TEX0.PSM); + } + + m_env.CTXT[i].TEX0 = (GSVector4i)r->TEX0; + if(wt) { m_mem.m_clut.Write(m_env.CTXT[i].TEX0, m_env.TEXCLUT); @@ -791,6 +797,13 @@ template void GSState::GIFRegHandlerFRAME(GIFReg* r) Flush(); } + if((m_env.CTXT[i].FRAME.u32[0] ^ r->FRAME.u32[0]) & 0x3f3f01ff) // FBP FBW PSM + { + m_env.CTXT[i].offset.fb = m_mem.GetOffset(r->FRAME.Block(), r->FRAME.FBW, r->FRAME.PSM); + m_env.CTXT[i].offset.zb = m_mem.GetOffset(m_env.CTXT[i].ZBUF.Block(), r->FRAME.FBW, m_env.CTXT[i].ZBUF.PSM); + m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset4(r->FRAME, m_env.CTXT[i].ZBUF); + } + m_env.CTXT[i].FRAME = (GSVector4i)r->FRAME; } @@ -805,20 +818,26 @@ template void GSState::GIFRegHandlerZBUF(GIFReg* r) r->ZBUF.PSM |= 0x30; + if(r->ZBUF.PSM != PSM_PSMZ32 + && r->ZBUF.PSM != PSM_PSMZ24 + && r->ZBUF.PSM != PSM_PSMZ16 + && r->ZBUF.PSM != PSM_PSMZ16S) + { + r->ZBUF.PSM = PSM_PSMZ32; + } + if(PRIM->CTXT == i && r->ZBUF != m_env.CTXT[i].ZBUF) { Flush(); } - m_env.CTXT[i].ZBUF = (GSVector4i)r->ZBUF; - - if(m_env.CTXT[i].ZBUF.PSM != PSM_PSMZ32 - && m_env.CTXT[i].ZBUF.PSM != PSM_PSMZ24 - && m_env.CTXT[i].ZBUF.PSM != PSM_PSMZ16 - && m_env.CTXT[i].ZBUF.PSM != PSM_PSMZ16S) + if((m_env.CTXT[i].ZBUF.u32[0] ^ r->ZBUF.u32[0]) & 0x3f0001ff) // ZBP PSM { - m_env.CTXT[i].ZBUF.PSM = PSM_PSMZ32; + m_env.CTXT[i].offset.zb = m_mem.GetOffset(r->ZBUF.Block(), m_env.CTXT[i].FRAME.FBW, r->ZBUF.PSM); + m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, r->ZBUF); } + + m_env.CTXT[i].ZBUF = (GSVector4i)r->ZBUF; } void GSState::GIFRegHandlerBITBLTBUF(GIFReg* r) @@ -1083,13 +1102,13 @@ void GSState::Move() // TODO: unroll inner loops (width has special size requirement, must be multiples of 1 << n, depending on the format) - GSLocalMemory::PixelOffset* RESTRICT spo = m_mem.GetPixelOffset(m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW, m_env.BITBLTBUF.SPSM); - GSLocalMemory::PixelOffset* RESTRICT dpo = m_mem.GetPixelOffset(m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM); + GSOffset* RESTRICT spo = m_mem.GetOffset(m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW, m_env.BITBLTBUF.SPSM); + GSOffset* RESTRICT dpo = m_mem.GetOffset(m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM); if(spsm.trbpp == dpsm.trbpp && spsm.trbpp >= 16) { - int* RESTRICT scol = &spo->col[0][sx]; - int* RESTRICT dcol = &dpo->col[0][dx]; + int* RESTRICT scol = &spo->pixel.col[0][sx]; + int* RESTRICT dcol = &dpo->pixel.col[0][dx]; if(spsm.trbpp == 32) { @@ -1097,8 +1116,8 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32* RESTRICT s = &m_mem.m_vm32[spo->row[sy]]; - uint32* RESTRICT d = &m_mem.m_vm32[dpo->row[dy]]; + uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; + uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; } @@ -1107,8 +1126,8 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32* RESTRICT s = &m_mem.m_vm32[spo->row[sy]]; - uint32* RESTRICT d = &m_mem.m_vm32[dpo->row[dy]]; + uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; + uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; } @@ -1120,8 +1139,8 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32* RESTRICT s = &m_mem.m_vm32[spo->row[sy]]; - uint32* RESTRICT d = &m_mem.m_vm32[dpo->row[dy]]; + uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; + uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; for(int x = 0; x < w; x++) d[dcol[x]] = (d[dcol[x]] & 0xff000000) | (s[scol[x]] & 0x00ffffff); } @@ -1130,8 +1149,8 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32* RESTRICT s = &m_mem.m_vm32[spo->row[sy]]; - uint32* RESTRICT d = &m_mem.m_vm32[dpo->row[dy]]; + uint32* RESTRICT s = &m_mem.m_vm32[spo->pixel.row[sy]]; + uint32* RESTRICT d = &m_mem.m_vm32[dpo->pixel.row[dy]]; for(int x = 0; x > -w; x--) d[dcol[x]] = (d[dcol[x]] & 0xff000000) | (s[scol[x]] & 0x00ffffff); } @@ -1143,8 +1162,8 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint16* RESTRICT s = &m_mem.m_vm16[spo->row[sy]]; - uint16* RESTRICT d = &m_mem.m_vm16[dpo->row[dy]]; + uint16* RESTRICT s = &m_mem.m_vm16[spo->pixel.row[sy]]; + uint16* RESTRICT d = &m_mem.m_vm16[dpo->pixel.row[dy]]; for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; } @@ -1153,8 +1172,8 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint16* RESTRICT s = &m_mem.m_vm16[spo->row[sy]]; - uint16* RESTRICT d = &m_mem.m_vm16[dpo->row[dy]]; + uint16* RESTRICT s = &m_mem.m_vm16[spo->pixel.row[sy]]; + uint16* RESTRICT d = &m_mem.m_vm16[dpo->pixel.row[dy]]; for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; } @@ -1167,11 +1186,11 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint8* RESTRICT s = &m_mem.m_vm8[spo->row[sy]]; - uint8* RESTRICT d = &m_mem.m_vm8[dpo->row[dy]]; + uint8* RESTRICT s = &m_mem.m_vm8[spo->pixel.row[sy]]; + uint8* RESTRICT d = &m_mem.m_vm8[dpo->pixel.row[dy]]; - int* RESTRICT scol = &spo->col[sy & 7][sx]; - int* RESTRICT dcol = &dpo->col[dy & 7][dx]; + int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; + int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]]; } @@ -1180,11 +1199,11 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint8* RESTRICT s = &m_mem.m_vm8[spo->row[sy]]; - uint8* RESTRICT d = &m_mem.m_vm8[dpo->row[dy]]; + uint8* RESTRICT s = &m_mem.m_vm8[spo->pixel.row[sy]]; + uint8* RESTRICT d = &m_mem.m_vm8[dpo->pixel.row[dy]]; - int* RESTRICT scol = &spo->col[sy & 7][sx]; - int* RESTRICT dcol = &dpo->col[dy & 7][dx]; + int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; + int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]]; } @@ -1196,11 +1215,11 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 sbase = spo->row[sy]; - uint32 dbase = dpo->row[dy]; + uint32 sbase = spo->pixel.row[sy]; + uint32 dbase = dpo->pixel.row[dy]; - int* RESTRICT scol = &spo->col[sy & 7][sx]; - int* RESTRICT dcol = &dpo->col[dy & 7][dx]; + int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; + int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; for(int x = 0; x < w; x++) m_mem.WritePixel4(dbase + dcol[x], m_mem.ReadPixel4(sbase + scol[x])); } @@ -1209,11 +1228,11 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 sbase = spo->row[sy]; - uint32 dbase = dpo->row[dy]; + uint32 sbase = spo->pixel.row[sy]; + uint32 dbase = dpo->pixel.row[dy]; - int* RESTRICT scol = &spo->col[sy & 7][sx]; - int* RESTRICT dcol = &dpo->col[dy & 7][dx]; + int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; + int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; for(int x = 0; x > -w; x--) m_mem.WritePixel4(dbase + dcol[x], m_mem.ReadPixel4(sbase + scol[x])); } @@ -1225,11 +1244,11 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 sbase = spo->row[sy]; - uint32 dbase = dpo->row[dy]; + uint32 sbase = spo->pixel.row[sy]; + uint32 dbase = dpo->pixel.row[dy]; - int* RESTRICT scol = &spo->col[sy & 7][sx]; - int* RESTRICT dcol = &dpo->col[dy & 7][dx]; + int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; + int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; for(int x = 0; x < w; x++) (m_mem.*dpsm.wpa)(dbase + dcol[x], (m_mem.*spsm.rpa)(sbase + scol[x])); } @@ -1238,11 +1257,11 @@ void GSState::Move() { for(int y = 0; y < h; y++, sy += yinc, dy += yinc) { - uint32 sbase = spo->row[sy]; - uint32 dbase = dpo->row[dy]; + uint32 sbase = spo->pixel.row[sy]; + uint32 dbase = dpo->pixel.row[dy]; - int* RESTRICT scol = &spo->col[sy & 7][sx]; - int* RESTRICT dcol = &dpo->col[dy & 7][dx]; + int* RESTRICT scol = &spo->pixel.col[sy & 7][sx]; + int* RESTRICT dcol = &dpo->pixel.col[dy & 7][dx]; for(int x = 0; x > -w; x--) (m_mem.*dpsm.wpa)(dbase + dcol[x], (m_mem.*spsm.rpa)(sbase + scol[x])); } @@ -1648,8 +1667,15 @@ int GSState::Defrost(const GSFreezeData* fd) m_env.UpdateDIMX(); - m_env.CTXT[0].UpdateScissor(); - m_env.CTXT[1].UpdateScissor(); + for(int i = 0; i < 2; i++) + { + m_env.CTXT[i].UpdateScissor(); + + m_env.CTXT[i].offset.fb = m_mem.GetOffset(m_env.CTXT[i].FRAME.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].FRAME.PSM); + m_env.CTXT[i].offset.zb = m_mem.GetOffset(m_env.CTXT[i].ZBUF.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].ZBUF.PSM); + m_env.CTXT[i].offset.tex = m_mem.GetOffset(m_env.CTXT[i].TEX0.TBP0, m_env.CTXT[i].TEX0.TBW, m_env.CTXT[i].TEX0.PSM); + m_env.CTXT[i].offset.fzb = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, m_env.CTXT[i].ZBUF); + } m_perfmon.SetFrame(5000); @@ -1663,13 +1689,13 @@ void GSState::SetGameCRC(uint32 crc, int options) m_game = CRC::Lookup(crc); } -void GSState::SetFrameSkip(int frameskip) +void GSState::SetFrameSkip(int skip) { - if(m_frameskip != frameskip) + if(m_frameskip != skip) { - m_frameskip = frameskip; + m_frameskip = skip; - if(frameskip) + if(skip) { m_fpGIFPackedRegHandlers[GIF_REG_PRIM] = &GSState::GIFPackedRegHandlerNOP; m_fpGIFPackedRegHandlers[GIF_REG_RGBA] = &GSState::GIFPackedRegHandlerNOP; @@ -1722,6 +1748,11 @@ void GSState::SetFrameSkip(int frameskip) } } +void GSState::SetFrameLimit(bool limit) +{ + m_framelimit = limit; +} + // GSTransferBuffer GSState::GSTransferBuffer::GSTransferBuffer() @@ -1941,9 +1972,9 @@ bool GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip) { if(skip == 0) { - if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00) && fi.TPSM == PSM_PSMCT16) + if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x00f00) && fi.TPSM == PSM_PSMCT16) { - skip = 3; + skip = 4; } } diff --git a/plugins/GSdx/GSState.h b/plugins/GSdx/GSState.h index 0f7163aa0b..071bb5bc5c 100644 --- a/plugins/GSdx/GSState.h +++ b/plugins/GSdx/GSState.h @@ -210,6 +210,7 @@ public: uint32 m_crc; int m_options; int m_frameskip; + bool m_framelimit; CRC::Game m_game; GSDump m_dump; @@ -247,6 +248,7 @@ public: int Defrost(const GSFreezeData* fd); void GetLastTag(uint32* tag) {*tag = m_path3hack; m_path3hack = 0;} virtual void SetGameCRC(uint32 crc, int options); - void SetFrameSkip(int frameskip); + void SetFrameSkip(int skip); + void SetFrameLimit(bool limit); }; diff --git a/plugins/GSdx/GSTexture.h b/plugins/GSdx/GSTexture.h index 41fa86f904..c661b28405 100644 --- a/plugins/GSdx/GSTexture.h +++ b/plugins/GSdx/GSTexture.h @@ -27,20 +27,19 @@ class GSTexture { public: GSVector2 m_scale; + GSVector2i m_size; struct GSMap {uint8* bits; int pitch;}; enum {None, RenderTarget, DepthStencil, Texture, Offscreen}; public: - GSTexture() : m_scale(1, 1) {} + GSTexture() : m_scale(1, 1), m_size(0, 0) {} virtual ~GSTexture() {} virtual operator bool() {ASSERT(0); return false;} virtual int GetType() const = 0; - virtual int GetWidth() const = 0; - virtual int GetHeight() const = 0; virtual int GetFormat() const = 0; virtual bool Update(const GSVector4i& r, const void* data, int pitch) = 0; @@ -48,5 +47,8 @@ public: virtual void Unmap() = 0; virtual bool Save(const string& fn, bool dds = false) = 0; - GSVector2i GetSize() const {return GSVector2i(GetWidth(), GetHeight());} + int GetWidth() const {return m_size.x;} + int GetHeight() const {return m_size.y;} + + GSVector2i GetSize() const {return m_size;} }; diff --git a/plugins/GSdx/GSTexture10.cpp b/plugins/GSdx/GSTexture10.cpp index 57f88bea4d..4d02646f42 100644 --- a/plugins/GSdx/GSTexture10.cpp +++ b/plugins/GSdx/GSTexture10.cpp @@ -29,6 +29,9 @@ GSTexture10::GSTexture10(ID3D10Texture2D* texture) m_texture->GetDevice(&m_dev); m_texture->GetDesc(&m_desc); + + m_size.x = (int)m_desc.Width; + m_size.y = (int)m_desc.Height; } int GSTexture10::GetType() const @@ -40,16 +43,6 @@ int GSTexture10::GetType() const return GSTexture::None; } -int GSTexture10::GetWidth() const -{ - return m_desc.Width; -} - -int GSTexture10::GetHeight() const -{ - return m_desc.Height; -} - int GSTexture10::GetFormat() const { return m_desc.Format; diff --git a/plugins/GSdx/GSTexture10.h b/plugins/GSdx/GSTexture10.h index 530ec3be3c..c98ebcd051 100644 --- a/plugins/GSdx/GSTexture10.h +++ b/plugins/GSdx/GSTexture10.h @@ -36,8 +36,6 @@ public: explicit GSTexture10(ID3D10Texture2D* texture); int GetType() const; - int GetWidth() const; - int GetHeight() const; int GetFormat() const; bool Update(const GSVector4i& r, const void* data, int pitch); diff --git a/plugins/GSdx/GSTexture11.cpp b/plugins/GSdx/GSTexture11.cpp index 991128f156..3b3073dacd 100644 --- a/plugins/GSdx/GSTexture11.cpp +++ b/plugins/GSdx/GSTexture11.cpp @@ -31,6 +31,9 @@ GSTexture11::GSTexture11(ID3D11Texture2D* texture) m_texture->GetDesc(&m_desc); m_dev->GetImmediateContext(&m_ctx); + + m_size.x = (int)m_desc.Width; + m_size.y = (int)m_desc.Height; } int GSTexture11::GetType() const @@ -42,16 +45,6 @@ int GSTexture11::GetType() const return GSTexture::None; } -int GSTexture11::GetWidth() const -{ - return m_desc.Width; -} - -int GSTexture11::GetHeight() const -{ - return m_desc.Height; -} - int GSTexture11::GetFormat() const { return m_desc.Format; diff --git a/plugins/GSdx/GSTexture11.h b/plugins/GSdx/GSTexture11.h index 6b3b16fb6c..fc2a7061b6 100644 --- a/plugins/GSdx/GSTexture11.h +++ b/plugins/GSdx/GSTexture11.h @@ -37,8 +37,6 @@ public: explicit GSTexture11(ID3D11Texture2D* texture); int GetType() const; - int GetWidth() const; - int GetHeight() const; int GetFormat() const; bool Update(const GSVector4i& r, const void* data, int pitch); diff --git a/plugins/GSdx/GSTexture7.cpp b/plugins/GSdx/GSTexture7.cpp index 8a9eb36691..a3055c014a 100644 --- a/plugins/GSdx/GSTexture7.cpp +++ b/plugins/GSdx/GSTexture7.cpp @@ -31,6 +31,9 @@ GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system) m_desc.dwSize = sizeof(m_desc); system->GetSurfaceDesc(&m_desc); + + m_size.x = (int)m_desc.dwWidth; + m_size.y = (int)m_desc.dwHeight; } GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface7* video) @@ -43,6 +46,9 @@ GSTexture7::GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface m_desc.dwSize = sizeof(m_desc); video->GetSurfaceDesc(&m_desc); + + m_size.x = (int)m_desc.dwWidth; + m_size.y = (int)m_desc.dwHeight; } int GSTexture7::GetType() const @@ -50,16 +56,6 @@ int GSTexture7::GetType() const return m_type; } -int GSTexture7::GetWidth() const -{ - return m_desc.dwWidth; -} - -int GSTexture7::GetHeight() const -{ - return m_desc.dwHeight; -} - int GSTexture7::GetFormat() const { return (int)m_desc.ddpfPixelFormat.dwFourCC; diff --git a/plugins/GSdx/GSTexture7.h b/plugins/GSdx/GSTexture7.h index c69b1a96b1..7d73cb0670 100644 --- a/plugins/GSdx/GSTexture7.h +++ b/plugins/GSdx/GSTexture7.h @@ -36,8 +36,6 @@ public: GSTexture7(int type, IDirectDrawSurface7* system, IDirectDrawSurface7* video); int GetType() const; - int GetWidth() const; - int GetHeight() const; int GetFormat() const; bool Update(const GSVector4i& r, const void* data, int pitch); diff --git a/plugins/GSdx/GSTexture9.cpp b/plugins/GSdx/GSTexture9.cpp index 1e6f9b1e7e..26106feb34 100644 --- a/plugins/GSdx/GSTexture9.cpp +++ b/plugins/GSdx/GSTexture9.cpp @@ -35,6 +35,9 @@ GSTexture9::GSTexture9(IDirect3DSurface9* surface) ASSERT(m_texture != NULL); } + + m_size.x = (int)m_desc.Width; + m_size.y = (int)m_desc.Height; } GSTexture9::GSTexture9(IDirect3DTexture9* texture) @@ -46,6 +49,9 @@ GSTexture9::GSTexture9(IDirect3DTexture9* texture) texture->GetSurfaceLevel(0, &m_surface); ASSERT(m_surface != NULL); + + m_size.x = (int)m_desc.Width; + m_size.y = (int)m_desc.Height; } GSTexture9::~GSTexture9() @@ -61,16 +67,6 @@ int GSTexture9::GetType() const return GSTexture::None; } -int GSTexture9::GetWidth() const -{ - return m_desc.Width; -} - -int GSTexture9::GetHeight() const -{ - return m_desc.Height; -} - int GSTexture9::GetFormat() const { return m_desc.Format; diff --git a/plugins/GSdx/GSTexture9.h b/plugins/GSdx/GSTexture9.h index be8bac79fe..a2a0297dba 100644 --- a/plugins/GSdx/GSTexture9.h +++ b/plugins/GSdx/GSTexture9.h @@ -36,8 +36,6 @@ public: virtual ~GSTexture9(); int GetType() const; - int GetWidth() const; - int GetHeight() const; int GetFormat() const; bool Update(const GSVector4i& r, const void* data, int pitch); diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 95afdf7038..a2d88f39a7 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -53,11 +53,11 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con Source* src = NULL; - hash_map& m = m_src.m_map[TEX0.TBP0 >> 5]; + list& m = m_src.m_map[TEX0.TBP0 >> 5]; - for(hash_map::iterator i = m.begin(); i != m.end(); i++) + for(list::iterator i = m.begin(); i != m.end(); i++) { - Source* s = i->first; + Source* s = *i; if(((TEX0.u32[0] ^ s->m_TEX0.u32[0]) | ((TEX0.u32[1] ^ s->m_TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH { @@ -69,11 +69,13 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con continue; } - if(s->m_palette == NULL && psm.pal > 0 && !GSVector4i::compare(clut, s->m_clut, psm.pal * sizeof(clut[0]))) + if(s->m_palette == NULL && psm.pal > 0 && !GSVector4i::compare64(clut, s->m_clut, psm.pal * sizeof(clut[0]))) { continue; } + m.splice(m.begin(), m, i); + src = s; break; @@ -118,7 +120,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con memcpy(src->m_clut, clut, psm.pal * sizeof(clut[0])); } - m_src.Add(src, TEX0, m_renderer->m_mem); + m_src.Add(src, TEX0, m_renderer->m_context->offset.tex); } if(psm.pal > 0) @@ -231,13 +233,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int return dst; } -void GSTextureCache::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& rect, bool target) +void GSTextureCache::InvalidateVideoMem(const GSOffset* o, const GSVector4i& rect, bool target) { - uint32 bp = BITBLTBUF.DBP; - uint32 bw = BITBLTBUF.DBW; - uint32 psm = BITBLTBUF.DPSM; - - const GSLocalMemory::BlockOffset* bo = m_renderer->m_mem.GetBlockOffset(bp, bw, psm); + uint32 bp = o->bp; + uint32 bw = o->bw; + uint32 psm = o->psm; GSVector2i bs = (bp & 31) == 0 ? GSLocalMemory::m_psm[psm].pgs : GSLocalMemory::m_psm[psm].bs; @@ -245,13 +245,13 @@ void GSTextureCache::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const if(!target) { - const hash_map& m = m_src.m_map[bp >> 5]; + const list& m = m_src.m_map[bp >> 5]; - for(hash_map::const_iterator i = m.begin(); i != m.end(); ) + for(list::const_iterator i = m.begin(); i != m.end(); ) { - hash_map::const_iterator j = i++; + list::const_iterator j = i++; - Source* s = j->first; + Source* s = *j; if(GSUtil::HasSharedBits(bp, psm, s->m_TEX0.TBP0, s->m_TEX0.PSM)) { @@ -264,21 +264,21 @@ void GSTextureCache::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const for(int y = r.top; y < r.bottom; y += bs.y) { - uint32 base = bo->row[y >> 3]; + uint32 base = o->block.row[y >> 3]; for(int x = r.left; x < r.right; x += bs.x) { - uint32 page = (base + bo->col[x >> 3]) >> 5; + uint32 page = (base + o->block.col[x >> 3]) >> 5; if(page < MAX_PAGES) { - const hash_map& m = m_src.m_map[page]; + const list& m = m_src.m_map[page]; - for(hash_map::const_iterator i = m.begin(); i != m.end(); ) + for(list::const_iterator i = m.begin(); i != m.end(); ) { - hash_map::const_iterator j = i++; + list::const_iterator j = i++; - Source* s = j->first; + Source* s = *j; if(GSUtil::HasSharedBits(psm, s->m_TEX0.PSM)) { @@ -353,10 +353,10 @@ void GSTextureCache::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const } } -void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) +void GSTextureCache::InvalidateLocalMem(const GSOffset* o, const GSVector4i& r) { - uint32 bp = BITBLTBUF.SBP; - uint32 psm = BITBLTBUF.SPSM; + uint32 bp = o->bp; + uint32 psm = o->psm; for(list::iterator i = m_dst[RenderTarget].begin(); i != m_dst[RenderTarget].end(); ) { @@ -368,7 +368,12 @@ void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const { if(GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM)) { - t->Read(r); + GSVector4i r2 = r.rintersect(t->m_valid); + + if(!r2.rempty()) + { + t->Read(r2); + } return; } @@ -376,7 +381,12 @@ void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const { // ffx-2 riku changing to her default (shoots some reflecting glass at the end), 16-bit rt read as 32-bit - t->Read(GSVector4i(r.left, r.top, r.right, r.top + (r.bottom - r.top) * 2)); + GSVector4i r2 = GSVector4i(r.left, r.top, r.right, r.top + (r.bottom - r.top) * 2).rintersect(t->m_valid); + + if(!r2.rempty()) + { + t->Read(r2); + } return; } @@ -433,11 +443,11 @@ void GSTextureCache::IncAge() { int maxage = m_src.m_used ? 3 : 30; - for(hash_map::iterator i = m_src.m_surfaces.begin(); i != m_src.m_surfaces.end(); ) + for(hash_set::iterator i = m_src.m_surfaces.begin(); i != m_src.m_surfaces.end(); ) { - hash_map::iterator j = i++; + hash_set::iterator j = i++; - Source* s = j->first; + Source* s = *j; if(++s->m_age > maxage) { @@ -447,7 +457,7 @@ void GSTextureCache::IncAge() m_src.m_used = false; - maxage = 3; + maxage = 4; // ffx intro scene changes leave the old image untouched for a couple of frames and only then start using it for(int type = 0; type < 2; type++) { @@ -661,8 +671,8 @@ bool GSTextureCache::Source::Create(Target* dst) } else { - sr.z /= st->GetWidth(); - sr.w /= st->GetHeight(); + sr.z /= st->m_size.x; + sr.w /= st->m_size.y; m_renderer->m_dev->StretchRect(st, sr, dt, dr); } @@ -721,14 +731,17 @@ void GSTextureCache::Source::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TE GSVector2i bs = GSLocalMemory::m_psm[m_TEX0.PSM].bs; - GSVector4i r = rect.ralign(bs); + int tw = std::max(1 << m_TEX0.TW, bs.x); + int th = std::max(1 << m_TEX0.TH, bs.y); - if(r.eq(GSVector4i(0, 0, 1 << m_TEX0.TW, 1 << m_TEX0.TH))) + GSVector4i r = rect.ralign(bs); + + if(r.eq(GSVector4i(0, 0, tw, th))) { m_complete = true; // lame, but better than nothing } - const GSLocalMemory::BlockOffset* bo = m_renderer->m_mem.GetBlockOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); + const GSOffset* o = m_renderer->m_context->offset.tex; bool repeating = m_TEX0.IsRepeating(); @@ -736,11 +749,11 @@ void GSTextureCache::Source::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TE for(int y = r.top; y < r.bottom; y += bs.y) { - uint32 base = bo->row[y >> 3]; + uint32 base = o->block.row[y >> 3]; for(int x = r.left; x < r.right; x += bs.x) { - uint32 block = base + bo->col[x >> 3]; + uint32 block = base + o->block.col[x >> 3]; if(block < MAX_BLOCKS) { @@ -768,11 +781,11 @@ void GSTextureCache::Source::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TE { for(int y = r.top; y < r.bottom; y += bs.y) { - uint32 base = bo->row[y >> 3]; + uint32 base = o->block.row[y >> 3]; for(int x = r.left; x < r.right; x += bs.x) { - uint32 block = base + bo->col[x >> 3]; + uint32 block = base + o->block.col[x >> 3]; if(block < MAX_BLOCKS) { @@ -785,7 +798,7 @@ void GSTextureCache::Source::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA& TE } } - m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, bs.x * bs.y * sizeof(uint32) * blocks); + m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, bs.x * bs.y * blocks << (m_fmt == GSTextureFX::FMT_32 ? 2 : 0)); Flush(m_write.count); } @@ -840,6 +853,8 @@ void GSTextureCache::Source::Flush(uint32 count) GSLocalMemory& mem = m_renderer->m_mem; + const GSOffset* o = m_renderer->m_context->offset.tex; + GSLocalMemory::readTexture rtx = psm.rtx; if(m_fmt == GSTextureFX::FMT_8) @@ -854,7 +869,7 @@ void GSTextureCache::Source::Flush(uint32 count) if((r > tr).mask() & 0xff00) { - (mem.*rtx)(r, buff, pitch, m_TEX0, m_TEXA); + (mem.*rtx)(o, r, buff, pitch, m_TEXA); m_texture->Update(r.rintersect(tr), buff, pitch); } @@ -864,13 +879,13 @@ void GSTextureCache::Source::Flush(uint32 count) if(m_texture->Map(m, &r)) { - (mem.*rtx)(r, m.bits, m.pitch, m_TEX0, m_TEXA); + (mem.*rtx)(o, r, m.bits, m.pitch, m_TEXA); m_texture->Unmap(); } else { - (mem.*rtx)(r, buff, pitch, m_TEX0, m_TEXA); + (mem.*rtx)(o, r, buff, pitch, m_TEXA); m_texture->Update(r, buff, pitch); } @@ -894,6 +909,7 @@ GSTextureCache::Target::Target(GSRenderer* r) , m_type(-1) , m_used(false) { + m_valid = GSVector4i::zero(); } bool GSTextureCache::Target::Create(int w, int h, int type) @@ -935,6 +951,8 @@ void GSTextureCache::Target::Update() if(GSTexture* t = m_renderer->m_dev->CreateTexture(w, h)) { + const GSOffset* o = m_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); // TODO: m_renderer->m_context->bo.tex; + GIFRegTEXA TEXA; TEXA.AEM = 1; @@ -945,7 +963,7 @@ void GSTextureCache::Target::Update() if(t->Map(m)) { - m_renderer->m_mem.ReadTexture(r, m.bits, m.pitch, m_TEX0, TEXA); + m_renderer->m_mem.ReadTexture(o, r, m.bits, m.pitch, TEXA); t->Unmap(); } @@ -955,7 +973,7 @@ void GSTextureCache::Target::Update() int pitch = ((w + 3) & ~3) * 4; - m_renderer->m_mem.ReadTexture(r, buff, pitch, m_TEX0, TEXA); + m_renderer->m_mem.ReadTexture(o, r, buff, pitch, TEXA); t->Update(r.rsize(), buff, pitch); } @@ -980,21 +998,19 @@ void GSTextureCache::Target::Update() // GSTextureCache::SourceMap -void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSLocalMemory& mem) +void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, const GSOffset* o) { - m_surfaces[s] = true; + m_surfaces.insert(s); if(s->m_target) { // TODO - m_map[TEX0.TBP0 >> 5][s] = true; + m_map[TEX0.TBP0 >> 5].push_front(s); return; } - const GSLocalMemory::BlockOffset* bo = mem.GetBlockOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM); - const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; GSVector2i bs = (TEX0.TBP0 & 31) == 0 ? psm.pgs : psm.bs; @@ -1004,11 +1020,11 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSLocalMe for(int y = 0; y < th; y += bs.y) { - uint32 base = bo->row[y >> 3]; + uint32 base = o->block.row[y >> 3]; for(int x = 0; x < tw; x += bs.x) { - uint32 page = (base + bo->col[x >> 3]) >> 5; + uint32 page = (base + o->block.col[x >> 3]) >> 5; if(page < MAX_PAGES) { @@ -1023,14 +1039,15 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSLocalMe { m_pages[i] = 0; - hash_map* m = &m_map[i << 5]; + list* m = &m_map[i << 5]; - for(int j = 0; j < 32; j++) + unsigned long j; + + while(_BitScanForward(&j, p)) { - if(p & (1 << j)) - { - m[j][s] = true; - } + p ^= 1 << j; + + m[j].push_front(s); } } } @@ -1038,7 +1055,7 @@ void GSTextureCache::SourceMap::Add(Source* s, const GIFRegTEX0& TEX0, GSLocalMe void GSTextureCache::SourceMap::RemoveAll() { - for_each(m_surfaces.begin(), m_surfaces.end(), delete_first()); + for_each(m_surfaces.begin(), m_surfaces.end(), delete_object()); m_surfaces.clear(); @@ -1052,19 +1069,15 @@ void GSTextureCache::SourceMap::RemoveAt(Source* s) { m_surfaces.erase(s); - uint32 page = s->m_TEX0.TBP0 >> 5; - - if(s->m_target) + for(uint32 start = s->m_TEX0.TBP0 >> 5, end = s->m_target ? start : countof(m_map) - 1; start <= end; start++) { - // TODO + list& m = m_map[start]; - m_map[page].erase(s); - } - else - { - for(uint32 i = page; i < countof(m_map); i++) + for(list::iterator i = m.begin(); i != m.end(); ) { - m_map[i].erase(s); + list::iterator j = i++; + + if(*j == s) {m.erase(j); break;} } } diff --git a/plugins/GSdx/GSTextureCache.h b/plugins/GSdx/GSTextureCache.h index f04624d432..af407edcaf 100644 --- a/plugins/GSdx/GSTextureCache.h +++ b/plugins/GSdx/GSTextureCache.h @@ -82,6 +82,7 @@ public: int m_type; bool m_used; GSDirtyRectList m_dirty; + GSVector4i m_valid; public: explicit Target(GSRenderer* r); @@ -97,14 +98,14 @@ protected: struct SourceMap { - hash_map m_surfaces; - hash_map m_map[MAX_PAGES]; + hash_set m_surfaces; + list m_map[MAX_PAGES]; uint32 m_pages[16]; bool m_used; SourceMap() : m_used(false) {memset(m_pages, 0, sizeof(m_pages));} - void Add(Source* s, const GIFRegTEX0& TEX0, GSLocalMemory& mem); + void Add(Source* s, const GIFRegTEX0& TEX0, const GSOffset* o); void RemoveAll(); void RemoveAt(Source* s); @@ -124,8 +125,8 @@ public: Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r); Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used, bool fb = false); - void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool target = true); - void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); + void InvalidateVideoMem(const GSOffset* o, const GSVector4i& r, bool target = true); + void InvalidateLocalMem(const GSOffset* o, const GSVector4i& r); void IncAge(); }; diff --git a/plugins/GSdx/GSTextureCache10.cpp b/plugins/GSdx/GSTextureCache10.cpp index 850e76bedf..b4819a17e8 100644 --- a/plugins/GSdx/GSTextureCache10.cpp +++ b/plugins/GSdx/GSTextureCache10.cpp @@ -76,19 +76,19 @@ void GSTextureCache10::Target10::Read(const GSVector4i& r) { // TODO: block level write - GSLocalMemory::PixelOffset* po = m_renderer->m_mem.GetPixelOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); + GSOffset* o = m_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); switch(m_TEX0.PSM) { case PSM_PSMCT32: - m_renderer->m_mem.WritePixel32(m.bits, m.pitch, po, r); + m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r); break; case PSM_PSMCT24: - m_renderer->m_mem.WritePixel24(m.bits, m.pitch, po, r); + m_renderer->m_mem.WritePixel24(m.bits, m.pitch, o, r); break; case PSM_PSMCT16: case PSM_PSMCT16S: - m_renderer->m_mem.WritePixel16(m.bits, m.pitch, po, r); + m_renderer->m_mem.WritePixel16(m.bits, m.pitch, o, r); break; default: ASSERT(0); diff --git a/plugins/GSdx/GSTextureCache11.cpp b/plugins/GSdx/GSTextureCache11.cpp index 4d3a3c1f07..99e1e70ff8 100644 --- a/plugins/GSdx/GSTextureCache11.cpp +++ b/plugins/GSdx/GSTextureCache11.cpp @@ -76,19 +76,19 @@ void GSTextureCache11::Target11::Read(const GSVector4i& r) { // TODO: block level write - GSLocalMemory::PixelOffset* po = m_renderer->m_mem.GetPixelOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); + GSOffset* o = m_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); switch(m_TEX0.PSM) { case PSM_PSMCT32: - m_renderer->m_mem.WritePixel32(m.bits, m.pitch, po, r); + m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r); break; case PSM_PSMCT24: - m_renderer->m_mem.WritePixel24(m.bits, m.pitch, po, r); + m_renderer->m_mem.WritePixel24(m.bits, m.pitch, o, r); break; case PSM_PSMCT16: case PSM_PSMCT16S: - m_renderer->m_mem.WritePixel16(m.bits, m.pitch, po, r); + m_renderer->m_mem.WritePixel16(m.bits, m.pitch, o, r); break; default: ASSERT(0); diff --git a/plugins/GSdx/GSTextureCache9.cpp b/plugins/GSdx/GSTextureCache9.cpp index de946a0f1a..ad9f2ddd18 100644 --- a/plugins/GSdx/GSTextureCache9.cpp +++ b/plugins/GSdx/GSTextureCache9.cpp @@ -74,19 +74,19 @@ void GSTextureCache9::Target9::Read(const GSVector4i& r) { // TODO: block level write - GSLocalMemory::PixelOffset* po = m_renderer->m_mem.GetPixelOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); + GSOffset* o = m_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); switch(m_TEX0.PSM) { case PSM_PSMCT32: - m_renderer->m_mem.WritePixel32(m.bits, m.pitch, po, r); + m_renderer->m_mem.WritePixel32(m.bits, m.pitch, o, r); break; case PSM_PSMCT24: - m_renderer->m_mem.WritePixel24(m.bits, m.pitch, po, r); + m_renderer->m_mem.WritePixel24(m.bits, m.pitch, o, r); break; case PSM_PSMCT16: case PSM_PSMCT16S: - m_renderer->m_mem.WriteFrame16(m.bits, m.pitch, po, r); + m_renderer->m_mem.WriteFrame16(m.bits, m.pitch, o, r); break; default: ASSERT(0); diff --git a/plugins/GSdx/GSTextureCacheSW.cpp b/plugins/GSdx/GSTextureCacheSW.cpp index 4921f6dd07..7c548f6672 100644 --- a/plugins/GSdx/GSTextureCacheSW.cpp +++ b/plugins/GSdx/GSTextureCacheSW.cpp @@ -39,11 +39,11 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE GSTexture* t = NULL; - const hash_map& map = m_map[TEX0.TBP0 >> 5]; + list& m = m_map[TEX0.TBP0 >> 5]; - for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) + for(list::iterator i = m.begin(); i != m.end(); i++) { - GSTexture* t2 = i->first; + GSTexture* t2 = *i; if(((TEX0.u32[0] ^ t2->m_TEX0.u32[0]) | ((TEX0.u32[1] ^ t2->m_TEX0.u32[1]) & 3)) != 0) // TBP0 TBW PSM TW TH { @@ -55,6 +55,8 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE continue; } + m.splice(m.begin(), m, i); + t = t2; t->m_age = 0; @@ -66,9 +68,9 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE { t = new GSTexture(m_state); - m_textures[t] = true; + m_textures.insert(t); - const GSLocalMemory::BlockOffset* bo = m_state->m_mem.GetBlockOffset(TEX0.TBP0, TEX0.TBW, TEX0.PSM); + const GSOffset* o = m_state->m_context->offset.tex; GSVector2i bs = (TEX0.TBP0 & 31) == 0 ? psm.pgs : psm.bs; @@ -77,11 +79,11 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE for(int y = 0; y < th; y += bs.y) { - uint32 base = bo->row[y >> 3]; + uint32 base = o->block.row[y >> 3]; for(int x = 0; x < tw; x += bs.x) { - uint32 page = (base + bo->col[x >> 3]) >> 5; + uint32 page = (base + o->block.col[x >> 3]) >> 5; if(page < MAX_PAGES) { @@ -96,14 +98,15 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE { m_pages[i] = 0; - hash_map* m = &m_map[i << 5]; + list* m = &m_map[i << 5]; - for(int j = 0; j < 32; j++) + unsigned long j; + + while(_BitScanForward(&j, p)) { - if(p & (1 << j)) - { - m[j][t] = true; - } + p ^= 1 << j; + + m[j].push_front(t); } } } @@ -113,24 +116,54 @@ const GSTextureCacheSW::GSTexture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TE { printf("!@#$%\n"); // memory allocation may fail if the game is too hungry - m_textures.erase(t); + RemoveAt(t); - for(int i = 0; i < MAX_PAGES; i++) - { - m_map[i].erase(t); - } - - delete t; - - return NULL; + t = NULL; } return t; } +void GSTextureCacheSW::InvalidateVideoMem(const GSOffset* o, const GSVector4i& rect) +{ + uint32 bp = o->bp; + uint32 bw = o->bw; + uint32 psm = o->psm; + + GSVector2i bs = (bp & 31) == 0 ? GSLocalMemory::m_psm[psm].pgs : GSLocalMemory::m_psm[psm].bs; + + GSVector4i r = rect.ralign(bs); + + for(int y = r.top; y < r.bottom; y += bs.y) + { + uint32 base = o->block.row[y >> 3]; + + for(int x = r.left; x < r.right; x += bs.x) + { + uint32 page = (base + o->block.col[x >> 3]) >> 5; + + if(page < MAX_PAGES) + { + const list& map = m_map[page]; + + for(list::const_iterator i = map.begin(); i != map.end(); i++) + { + GSTexture* t = *i; + + if(GSUtil::HasSharedBits(psm, t->m_TEX0.PSM)) + { + t->m_valid[page] = 0; + t->m_complete = false; + } + } + } + } + } +} + void GSTextureCacheSW::RemoveAll() { - for_each(m_textures.begin(), m_textures.end(), delete_first()); + for_each(m_textures.begin(), m_textures.end(), delete_object()); m_textures.clear(); @@ -140,63 +173,36 @@ void GSTextureCacheSW::RemoveAll() } } +void GSTextureCacheSW::RemoveAt(GSTexture* t) +{ + m_textures.erase(t); + + for(uint32 start = t->m_TEX0.TBP0 >> 5, end = countof(m_map) - 1; start <= end; start++) + { + list& m = m_map[start]; + + for(list::iterator i = m.begin(); i != m.end(); ) + { + list::iterator j = i++; + + if(*j == t) {m.erase(j); break;} + } + } + + delete t; +} + void GSTextureCacheSW::IncAge() { - for(hash_map::iterator i = m_textures.begin(); i != m_textures.end(); ) + for(hash_set::iterator i = m_textures.begin(); i != m_textures.end(); ) { - hash_map::iterator j = i++; + hash_set::iterator j = i++; - GSTexture* t = j->first; + GSTexture* t = *j; if(++t->m_age > 30) { - m_textures.erase(j); - - for(int i = 0; i < MAX_PAGES; i++) - { - m_map[i].erase(t); - } - - delete t; - } - } -} - -void GSTextureCacheSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& rect) -{ - uint32 bp = BITBLTBUF.DBP; - uint32 bw = BITBLTBUF.DBW; - uint32 psm = BITBLTBUF.DPSM; - - const GSLocalMemory::BlockOffset* bo = m_state->m_mem.GetBlockOffset(bp, bw, psm); - - GSVector2i bs = (bp & 31) == 0 ? GSLocalMemory::m_psm[psm].pgs : GSLocalMemory::m_psm[psm].bs; - - GSVector4i r = rect.ralign(bs); - - for(int y = r.top; y < r.bottom; y += bs.y) - { - uint32 base = bo->row[y >> 3]; - - for(int x = r.left; x < r.right; x += bs.x) - { - uint32 page = (base + bo->col[x >> 3]) >> 5; - - if(page < MAX_PAGES) - { - const hash_map& map = m_map[page]; - - for(hash_map::const_iterator i = map.begin(); i != map.end(); i++) - { - GSTexture* t = i->first; - - if(GSUtil::HasSharedBits(psm, t->m_TEX0.PSM)) - { - t->m_valid[page] = 0; - t->m_complete = false; - } - } - } + RemoveAt(t); } } } @@ -235,8 +241,8 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX GSVector2i bs = psm.bs; - int tw = max(1 << TEX0.TW, bs.x); - int th = max(1 << TEX0.TH, bs.y); + int tw = std::max(1 << TEX0.TW, bs.x); + int th = std::max(1 << TEX0.TH, bs.y); GSVector4i r = rect.ralign(bs); @@ -259,7 +265,7 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX GSLocalMemory& mem = m_state->m_mem; - const GSLocalMemory::BlockOffset* bo = mem.GetBlockOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); + const GSOffset* o = m_state->m_context->offset.tex; bool repeating = m_TEX0.IsRepeating(); @@ -273,13 +279,13 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX uint8* dst = (uint8*)m_buff + pitch * r.top; - for(int y = r.top, o = pitch * bs.y; y < r.bottom; y += bs.y, dst += o) + for(int y = r.top, block_pitch = pitch * bs.y; y < r.bottom; y += bs.y, dst += block_pitch) { - uint32 base = bo->row[y >> 3]; + uint32 base = o->block.row[y >> 3]; for(int x = r.left; x < r.right; x += bs.x) { - uint32 block = base + bo->col[x >> 3]; + uint32 block = base + o->block.col[x >> 3]; if(block < MAX_BLOCKS) { @@ -307,11 +313,11 @@ bool GSTextureCacheSW::GSTexture::Update(const GIFRegTEX0& TEX0, const GIFRegTEX { for(int y = r.top; y < r.bottom; y += bs.y) { - uint32 base = bo->row[y >> 3]; + uint32 base = o->block.row[y >> 3]; for(int x = r.left; x < r.right; x += bs.x) { - uint32 block = base + bo->col[x >> 3]; + uint32 block = base + o->block.col[x >> 3]; if(block < MAX_BLOCKS) { diff --git a/plugins/GSdx/GSTextureCacheSW.h b/plugins/GSdx/GSTextureCacheSW.h index 454637770f..94bb165863 100644 --- a/plugins/GSdx/GSTextureCacheSW.h +++ b/plugins/GSdx/GSTextureCacheSW.h @@ -46,8 +46,8 @@ public: protected: GSState* m_state; - hash_map m_textures; - hash_map m_map[MAX_PAGES]; + hash_set m_textures; + list m_map[MAX_PAGES]; uint32 m_pages[16]; public: @@ -56,7 +56,9 @@ public: const GSTexture* Lookup(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r); + void InvalidateVideoMem(const GSOffset* o, const GSVector4i& r); + void RemoveAll(); + void RemoveAt(GSTexture* t); void IncAge(); - void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); }; diff --git a/plugins/GSdx/GSTextureFX.h b/plugins/GSdx/GSTextureFX.h index 86b0c3c469..8e97f8d0a6 100644 --- a/plugins/GSdx/GSTextureFX.h +++ b/plugins/GSdx/GSTextureFX.h @@ -45,12 +45,13 @@ public: { GSVector4 VertexScale; GSVector4 VertexOffset; - GSVector2 TextureScale; - float _pad[2]; + GSVector4 TextureScale; struct VSConstantBuffer() { - memset(this, 0, sizeof(*this)); + VertexScale = GSVector4::zero(); + VertexOffset = GSVector4::zero(); + TextureScale = GSVector4::zero(); } __forceinline bool Update(const VSConstantBuffer* cb) @@ -85,13 +86,12 @@ public: uint32 tme:1; uint32 fst:1; uint32 logz:1; - uint32 prim:2; }; uint32 key; }; - operator uint32() {return key & 0x7f;} + operator uint32() {return key & 0x1f;} VSSelector() : key(0) {} }; @@ -107,7 +107,12 @@ public: struct PSConstantBuffer() { - memset(this, 0, sizeof(*this)); + FogColor_AREF = GSVector4::zero(); + HalfTexel = GSVector4::zero(); + WH = GSVector4::zero(); + MinMax = GSVector4::zero(); + MinF_TA = GSVector4::zero(); + MskFix = GSVector4i::zero(); } __forceinline bool Update(const PSConstantBuffer* cb) @@ -122,7 +127,7 @@ public: GSVector4i b4 = b[4]; GSVector4i b5 = b[5]; - if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2) & (a[3] == b3) & (a[4] == b4) & (a[5] == b5)).alltrue()) + if(!((a[0] == b0) /*& (a[1] == b1)*/ & (a[2] == b2) & (a[3] == b3) & (a[4] == b4) & (a[5] == b5)).alltrue()) // if WH matches HalfTexel does too { a[0] = b0; a[1] = b1; @@ -212,7 +217,6 @@ public: { struct { - uint32 zte:1; uint32 ztst:2; uint32 zwe:1; uint32 date:1; @@ -222,7 +226,7 @@ public: uint32 key; }; - operator uint32() {return key & 0x3f;} + operator uint32() {return key & 0x1f;} OMDepthStencilSelector() : key(0) {} }; @@ -244,12 +248,24 @@ public: uint32 wa:1; }; + struct + { + uint32 _pad:1; + uint32 abcd:8; + uint32 wrgba:4; + }; + uint32 key; }; operator uint32() {return key & 0x1fff;} OMBlendSelector() : key(0) {} + + bool IsCLR1() const + { + return (key & 0x19f) == 0x93; // abe == 1 && a == 1 && b == 2 && d == 1 + } }; #pragma pack(pop) @@ -266,9 +282,6 @@ public: virtual void SetupIA(const void* vertices, int count, int prim) = 0; virtual void SetupVS(VSSelector sel, const VSConstantBuffer* cb) = 0; virtual void SetupGS(GSSelector sel) = 0; - virtual void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) = 0; - virtual void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) = 0; - virtual void SetupRS(int w, int h, const GSVector4i& scissor) = 0; - virtual void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) = 0; - virtual void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) = 0; + virtual void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) = 0; + virtual void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) = 0; }; diff --git a/plugins/GSdx/GSTextureFX10.cpp b/plugins/GSdx/GSTextureFX10.cpp index 732edbfd17..b221f9e069 100644 --- a/plugins/GSdx/GSTextureFX10.cpp +++ b/plugins/GSdx/GSTextureFX10.cpp @@ -76,6 +76,13 @@ bool GSTextureFX10::Create(GSDevice* dev) if(FAILED(hr)) return false; + // create layout + + VSSelector sel; + VSConstantBuffer cb; + + SetupVS(sel, &cb); + // return true; @@ -98,19 +105,17 @@ void GSTextureFX10::SetupVS(VSSelector sel, const VSConstantBuffer* cb) if(i == m_vs.end()) { - string str[4]; + string str[3]; str[0] = format("%d", sel.bppz); str[1] = format("%d", sel.tme); str[2] = format("%d", sel.fst); - str[3] = format("%d", sel.prim); D3D10_SHADER_MACRO macro[] = { {"VS_BPPZ", str[0].c_str()}, {"VS_TME", str[1].c_str()}, {"VS_FST", str[2].c_str()}, - {"VS_PRIM", str[3].c_str()}, {NULL, NULL}, }; @@ -184,14 +189,7 @@ void GSTextureFX10::SetupGS(GSSelector sel) dev->GSSetShader(gs); } -void GSTextureFX10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) -{ - ((GSDevice10*)m_dev)->PSSetShaderResources(tex, pal); - - UpdatePS(sel, cb, ssel); -} - -void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) +void GSTextureFX10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { GSDevice10* dev = (GSDevice10*)m_dev; @@ -265,7 +263,7 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl if(i != m_ps_ss.end()) { - ss0 = (*i).second; + ss0 = i->second; } else { @@ -297,25 +295,18 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl dev->PSSetSamplerState(ss0, ss1); } -void GSTextureFX10::SetupRS(int w, int h, const GSVector4i& scissor) -{ - ((GSDevice10*)m_dev)->RSSet(w, h, &scissor); -} - -void GSTextureFX10::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) -{ - UpdateOM(dssel, bsel, afix); - - ((GSDevice10*)m_dev)->OMSetRenderTargets(rt, ds); -} - -void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) +void GSTextureFX10::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) { GSDevice10* dev = (GSDevice10*)m_dev; - +/* hash_map >::const_iterator i = m_om_dss.find(dssel); if(i == m_om_dss.end()) + { +*/ + CComPtr& om_dss = m_om_dss[dssel]; + + if(om_dss == NULL) { D3D10_DEPTH_STENCIL_DESC dsd; @@ -336,7 +327,7 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, dsd.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP; } - if(!(dssel.zte && dssel.ztst == 1 && !dssel.zwe)) + if(dssel.ztst != ZTST_ALWAYS || dssel.zwe) { static const D3D10_COMPARISON_FUNC ztst[] = { @@ -346,11 +337,11 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, D3D10_COMPARISON_GREATER }; - dsd.DepthEnable = dssel.zte; + dsd.DepthEnable = true; dsd.DepthWriteMask = dssel.zwe ? D3D10_DEPTH_WRITE_MASK_ALL : D3D10_DEPTH_WRITE_MASK_ZERO; dsd.DepthFunc = ztst[dssel.ztst]; } - +/* CComPtr dss; (*dev)->CreateDepthStencilState(&dsd, &dss); @@ -358,9 +349,13 @@ void GSTextureFX10::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, m_om_dss[dssel] = dss; i = m_om_dss.find(dssel); +*/ + (*dev)->CreateDepthStencilState(&dsd, &om_dss); } - dev->OMSetDepthStencilState((*i).second, 1); +// dev->OMSetDepthStencilState(i->second, 1); + + dev->OMSetDepthStencilState(om_dss, 1); hash_map >::const_iterator j = m_om_bs.find(bsel); diff --git a/plugins/GSdx/GSTextureFX10.h b/plugins/GSdx/GSTextureFX10.h index 566809a360..30af953735 100644 --- a/plugins/GSdx/GSTextureFX10.h +++ b/plugins/GSdx/GSTextureFX10.h @@ -34,8 +34,9 @@ class GSTextureFX10 : public GSTextureFX CComPtr m_ps_cb; hash_map > m_ps_ss; CComPtr m_palette_ss; - hash_map > m_om_dss; - hash_map > m_om_bs; + // hash_map > m_om_dss; + CComPtr m_om_dss[32]; + hash_map > m_om_bs; VSConstantBuffer m_vs_cb_cache; PSConstantBuffer m_ps_cb_cache; @@ -48,9 +49,6 @@ public: void SetupIA(const void* vertices, int count, int prim); void SetupVS(VSSelector sel, const VSConstantBuffer* cb); void SetupGS(GSSelector sel); - void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); - void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); - void SetupRS(int w, int h, const GSVector4i& scissor); - void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); - void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); }; diff --git a/plugins/GSdx/GSTextureFX11.cpp b/plugins/GSdx/GSTextureFX11.cpp index 0931d0b725..8ad8cf6cf6 100644 --- a/plugins/GSdx/GSTextureFX11.cpp +++ b/plugins/GSdx/GSTextureFX11.cpp @@ -76,6 +76,13 @@ bool GSTextureFX11::Create(GSDevice* dev) if(FAILED(hr)) return false; + // create layout + + VSSelector sel; + VSConstantBuffer cb; + + SetupVS(sel, &cb); + // return true; @@ -98,19 +105,17 @@ void GSTextureFX11::SetupVS(VSSelector sel, const VSConstantBuffer* cb) if(i == m_vs.end()) { - string str[4]; + string str[3]; str[0] = format("%d", sel.bppz); str[1] = format("%d", sel.tme); str[2] = format("%d", sel.fst); - str[3] = format("%d", sel.prim); D3D11_SHADER_MACRO macro[] = { {"VS_BPPZ", str[0].c_str()}, {"VS_TME", str[1].c_str()}, {"VS_FST", str[2].c_str()}, - {"VS_PRIM", str[3].c_str()}, {NULL, NULL}, }; @@ -186,14 +191,7 @@ void GSTextureFX11::SetupGS(GSSelector sel) dev->GSSetShader(gs); } -void GSTextureFX11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) -{ - ((GSDevice11*)m_dev)->PSSetShaderResources(tex, pal); - - UpdatePS(sel, cb, ssel); -} - -void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) +void GSTextureFX11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { GSDevice11* dev = (GSDevice11*)m_dev; @@ -301,19 +299,7 @@ void GSTextureFX11::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl dev->PSSetSamplerState(ss0, ss1); } -void GSTextureFX11::SetupRS(int w, int h, const GSVector4i& scissor) -{ - ((GSDevice11*)m_dev)->RSSet(w, h, &scissor); -} - -void GSTextureFX11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) -{ - UpdateOM(dssel, bsel, afix); - - ((GSDevice11*)m_dev)->OMSetRenderTargets(rt, ds); -} - -void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) +void GSTextureFX11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) { GSDevice11* dev = (GSDevice11*)m_dev; @@ -340,7 +326,7 @@ void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; } - if(!(dssel.zte && dssel.ztst == 1 && !dssel.zwe)) + if(dssel.ztst != ZTST_ALWAYS || dssel.zwe) { static const D3D11_COMPARISON_FUNC ztst[] = { @@ -350,7 +336,7 @@ void GSTextureFX11::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, D3D11_COMPARISON_GREATER }; - dsd.DepthEnable = dssel.zte; + dsd.DepthEnable = true; dsd.DepthWriteMask = dssel.zwe ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; dsd.DepthFunc = ztst[dssel.ztst]; } diff --git a/plugins/GSdx/GSTextureFX11.h b/plugins/GSdx/GSTextureFX11.h index 5c2b67bcc1..822798bd49 100644 --- a/plugins/GSdx/GSTextureFX11.h +++ b/plugins/GSdx/GSTextureFX11.h @@ -48,9 +48,6 @@ public: void SetupIA(const void* vertices, int count, int prim); void SetupVS(VSSelector sel, const VSConstantBuffer* cb); void SetupGS(GSSelector sel); - void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); - void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); - void SetupRS(int w, int h, const GSVector4i& scissor); - void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); - void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); }; diff --git a/plugins/GSdx/GSTextureFX9.cpp b/plugins/GSdx/GSTextureFX9.cpp index 28efb317fb..87c6849a56 100644 --- a/plugins/GSdx/GSTextureFX9.cpp +++ b/plugins/GSdx/GSTextureFX9.cpp @@ -148,17 +148,17 @@ void GSTextureFX9::SetupVS(VSSelector sel, const VSConstantBuffer* cb) dev->VSSetShader(i->second, (const float*)cb, sizeof(*cb) / sizeof(GSVector4)); } -void GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal) +void GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) { GSDevice9* dev = (GSDevice9*)m_dev; - dev->PSSetShaderResources(tex, pal); - - if(tex && (sel.wms == 3 || sel.wmt == 3)) + if(cb->WH.z > 0 && cb->WH.w > 0 && (sel.wms == 3 || sel.wmt == 3)) { + GSVector4i size(cb->WH); + if(sel.wms == 3) { - if(GSTexture* t = CreateMskFix(tex->GetWidth(), cb->MskFix.x, cb->MskFix.z)) + if(GSTexture* t = CreateMskFix(size.z, cb->MskFix.x, cb->MskFix.z)) { (*dev)->SetTexture(2, *(GSTexture9*)t); } @@ -166,20 +166,13 @@ void GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSampler if(sel.wmt == 3) { - if(GSTexture* t = CreateMskFix(tex->GetHeight(), cb->MskFix.y, cb->MskFix.w)) + if(GSTexture* t = CreateMskFix(size.w, cb->MskFix.y, cb->MskFix.w)) { (*dev)->SetTexture(3, *(GSTexture9*)t); } } } - UpdatePS(sel, cb, ssel); -} - -void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) -{ - GSDevice9* dev = (GSDevice9*)m_dev; - hash_map >::const_iterator i = m_ps.find(sel); if(i == m_ps.end()) @@ -265,19 +258,7 @@ void GSTextureFX9::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSample dev->PSSetSamplerState(ss); } -void GSTextureFX9::SetupRS(int w, int h, const GSVector4i& scissor) -{ - ((GSDevice9*)m_dev)->RSSet(w, h, &scissor); -} - -void GSTextureFX9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds) -{ - UpdateOM(dssel, bsel, afix); - - ((GSDevice9*)m_dev)->OMSetRenderTargets(rt, ds); -} - -void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) +void GSTextureFX9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) { GSDevice9* dev = (GSDevice9*)m_dev; @@ -303,7 +284,7 @@ void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, dss->StencilRef = 3; } - if(!(dssel.zte && dssel.ztst == 1 && !dssel.zwe)) + if(dssel.ztst != ZTST_ALWAYS || dssel.zwe) { static const D3DCMPFUNC ztst[] = { @@ -313,7 +294,7 @@ void GSTextureFX9::UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, D3DCMP_GREATER }; - dss->DepthEnable = dssel.zte; + dss->DepthEnable = true; dss->DepthWriteMask = dssel.zwe; dss->DepthFunc = ztst[dssel.ztst]; } diff --git a/plugins/GSdx/GSTextureFX9.h b/plugins/GSdx/GSTextureFX9.h index d20b5b1229..d20580b368 100644 --- a/plugins/GSdx/GSTextureFX9.h +++ b/plugins/GSdx/GSTextureFX9.h @@ -46,9 +46,6 @@ public: void SetupIA(const void* vertices, int count, int prim); void SetupVS(VSSelector sel, const VSConstantBuffer* cb); void SetupGS(GSSelector sel) {} - void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel, GSTexture* tex, GSTexture* pal); - void UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); - void SetupRS(int w, int h, const GSVector4i& scissor); - void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix, GSTexture* rt, GSTexture* ds); - void UpdateOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); + void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel); + void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix); }; diff --git a/plugins/GSdx/GSTextureNull.h b/plugins/GSdx/GSTextureNull.h index 68cf9b2843..988215d32f 100644 --- a/plugins/GSdx/GSTextureNull.h +++ b/plugins/GSdx/GSTextureNull.h @@ -32,9 +32,8 @@ public: GSTextureNull(int type, int w, int h, int format); int GetType() const {return m_desc.type;} - int GetWidth() const {return m_desc.w;} - int GetHeight() const {return m_desc.h;} int GetFormat() const {return m_desc.format;} + bool Update(const GSVector4i& r, const void* data, int pitch) {return true;} bool Map(GSMap& m, const GSVector4i* r) {return false;} void Unmap() {} diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index ca59491c72..49c4f7b2da 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -26,10 +26,11 @@ GSTextureOGL::GSTextureOGL(GLuint texture, int type, int width, int height, int format) : m_texture(texture) , m_type(type) - , m_width(width) - , m_height(height) , m_format(format) { + m_size.x = width; + m_size.y = height; + // TODO: offscreen type should be just a memory array, also returned in Map glGenBuffers(1, &m_pbo); GSDeviceOGL::CheckError(); @@ -61,16 +62,6 @@ int GSTextureOGL::GetType() const return m_type; } -int GSTextureOGL::GetWidth() const -{ - return m_width; -} - -int GSTextureOGL::GetHeight() const -{ - return m_height; -} - int GSTextureOGL::GetFormat() const { return m_format; diff --git a/plugins/GSdx/GSTextureOGL.h b/plugins/GSdx/GSTextureOGL.h index d69581a697..5a992223d1 100644 --- a/plugins/GSdx/GSTextureOGL.h +++ b/plugins/GSdx/GSTextureOGL.h @@ -29,8 +29,6 @@ class GSTextureOGL : public GSTexture GLuint m_pbo; int m_type; - int m_width; - int m_height; int m_format; public: @@ -38,8 +36,6 @@ public: virtual ~GSTextureOGL(); int GetType() const; - int GetWidth() const; - int GetHeight() const; int GetFormat() const; bool Update(const GSVector4i& r, const void* data, int pitch); diff --git a/plugins/GSdx/GSUtil.h b/plugins/GSdx/GSUtil.h index 8ab293b852..839cc70800 100644 --- a/plugins/GSdx/GSUtil.h +++ b/plugins/GSdx/GSUtil.h @@ -22,6 +22,7 @@ #pragma once #include "GS.h" +#include "GSLocalMemory.h" class GSUtil { @@ -32,26 +33,6 @@ public: static bool HasSharedBits(uint32 sbp, uint32 spsm, uint32 dbp, uint32 dpsm); static bool HasCompatibleBits(uint32 spsm, uint32 dpsm); - static uint32 EncodePSM(uint32 psm) - { - switch(psm) - { - case PSM_PSMCT32: - case PSM_PSMZ32: - return 0; - case PSM_PSMCT24: - case PSM_PSMZ24: - return 1; - case PSM_PSMCT16: - case PSM_PSMCT16S: - case PSM_PSMZ16: - case PSM_PSMZ16S: - return 2; - default: - return 3; - } - } - static bool CheckDirectX(); static bool CheckSSE(); diff --git a/plugins/GSdx/GSVector.h b/plugins/GSdx/GSVector.h index b3cbfc261b..8ffed0801b 100644 --- a/plugins/GSdx/GSVector.h +++ b/plugins/GSdx/GSVector.h @@ -28,6 +28,11 @@ public: { return x == v.x && y == v.y; } + + bool operator != (const GSVector2T& v) const + { + return x != v.x || y != v.y; + } }; typedef GSVector2T GSVector2; @@ -1800,7 +1805,7 @@ public: d = f.uph64(d); } - __forceinline static bool compare(const void* dst, const void* src, int size) + __forceinline static bool compare16(const void* dst, const void* src, int size) { ASSERT((size & 15) == 0); @@ -1809,19 +1814,43 @@ public: GSVector4i* s = (GSVector4i*)src; GSVector4i* d = (GSVector4i*)dst; - if(!d[0].eq(s[0])) - { - return false; - } - - GSVector4i v = GSVector4i::xffffffff(); - for(int i = 0; i < size; i++) { - v &= d[i] == s[i]; + if(!d[i].eq(s[i])) + { + return false; + } } - return v.alltrue(); + return true; + } + + __forceinline static bool compare64(const void* dst, const void* src, int size) + { + ASSERT((size & 63) == 0); + + size >>= 6; + + GSVector4i* s = (GSVector4i*)src; + GSVector4i* d = (GSVector4i*)dst; + + for(int i = 0; i < size; i += 4) + { + GSVector4i v0 = (d[i * 4 + 0] == s[i * 4 + 0]); + GSVector4i v1 = (d[i * 4 + 1] == s[i * 4 + 1]); + GSVector4i v2 = (d[i * 4 + 2] == s[i * 4 + 2]); + GSVector4i v3 = (d[i * 4 + 3] == s[i * 4 + 3]); + + v0 = v0 & v1; + v2 = v2 & v3; + + if(!(v0 & v2).alltrue()) + { + return false; + } + } + + return true; } __forceinline static bool update(const void* dst, const void* src, int size) diff --git a/plugins/GSdx/GSVertex.h b/plugins/GSdx/GSVertex.h index 9634a61aef..18d854be04 100644 --- a/plugins/GSdx/GSVertex.h +++ b/plugins/GSdx/GSVertex.h @@ -51,17 +51,6 @@ __declspec(align(16)) struct GSVertex GSVector4 GetUV() const {return GSVector4(GSVector4i::load(UV.u32[0]).upl16());} }; -struct GSVertexOld -{ - GIFRegRGBAQ RGBAQ; - GIFRegST ST; - GIFRegUV UV; - GIFRegXYZ XYZ; - GIFRegFOG FOG; - - GSVertexOld() {memset(this, 0, sizeof(*this));} -}; - struct GSVertexP { GSVector4 p; diff --git a/plugins/GSdx/GSVertexTrace.cpp b/plugins/GSdx/GSVertexTrace.cpp index 2f58e9a555..deb44bdc2d 100644 --- a/plugins/GSdx/GSVertexTrace.cpp +++ b/plugins/GSdx/GSVertexTrace.cpp @@ -23,33 +23,42 @@ #include "stdafx.h" #include "GSVertexTrace.h" +#include "GSUtil.h" +#include "GSState.h" -void GSVertexTrace::Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context) +GSVertexTrace::GSVertexTrace(const GSState* state) + : m_state(state) { - uint32 key = primclass | (PRIM->IIP << 2) | (PRIM->TME << 3) | (PRIM->FST << 4); +} - if(!(PRIM->TME && context->TEX0.TFX == TFX_DECAL && context->TEX0.TCC)) +uint32 GSVertexTrace::Hash(GS_PRIM_CLASS primclass) +{ + m_primclass = primclass; + + uint32 hash = m_primclass | (m_state->PRIM->IIP << 2) | (m_state->PRIM->TME << 3) | (m_state->PRIM->FST << 4); + + if(!(m_state->PRIM->TME && m_state->m_context->TEX0.TFX == TFX_DECAL && m_state->m_context->TEX0.TCC)) { - key |= 1 << 5; + hash |= 1 << 5; } - m_map_sw[key](v, count, m_min, m_max); + return hash; +} + +void GSVertexTrace::Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass) +{ + m_map_sw[Hash(primclass)](v, count, m_min, m_max); m_eq.value = (m_min.c == m_max.c).mask() | ((m_min.p == m_max.p).mask() << 16) | ((m_min.t == m_max.t).mask() << 20); m_alpha.valid = false; } -void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context) -{ - uint32 key = primclass | (PRIM->IIP << 2) | (PRIM->TME << 3) | (PRIM->FST << 4); +void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass) +{ + m_map_hw9[Hash(primclass)](v, count, m_min, m_max); - if(!(PRIM->TME && context->TEX0.TFX == TFX_DECAL && context->TEX0.TCC)) - { - key |= 1 << 5; - } - - m_map_hw9[key](v, count, m_min, m_max); + const GSDrawingContext* context = m_state->m_context; GSVector4 o(context->XYOFFSET); GSVector4 s(1.0f / 16, 1.0f / 16, 1.0f, 1.0f); @@ -57,9 +66,9 @@ void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primcl m_min.p = (m_min.p - o) * s; m_max.p = (m_max.p - o) * s; - if(PRIM->TME) + if(m_state->PRIM->TME) { - if(PRIM->FST) + if(m_state->PRIM->FST) { s = GSVector4(1 << (16 - 4), 1).xxyy(); } @@ -77,16 +86,11 @@ void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primcl m_alpha.valid = false; } -void GSVertexTrace::Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context) +void GSVertexTrace::Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass) { - uint32 key = primclass | (PRIM->IIP << 2) | (PRIM->TME << 3) | (PRIM->FST << 4); + m_map_hw10[Hash(primclass)](v, count, m_min, m_max); - if(!(PRIM->TME && context->TEX0.TFX == TFX_DECAL && context->TEX0.TCC)) - { - key |= 1 << 5; - } - - m_map_hw10[key](v, count, m_min, m_max); + const GSDrawingContext* context = m_state->m_context; GSVector4 o(context->XYOFFSET); GSVector4 s(1.0f / 16, 1.0f / 16, 2.0f, 1.0f); @@ -94,9 +98,9 @@ void GSVertexTrace::Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primc m_min.p = (m_min.p - o) * s; m_max.p = (m_max.p - o) * s; - if(PRIM->TME) + if(m_state->PRIM->TME) { - if(PRIM->FST) + if(m_state->PRIM->FST) { s = GSVector4(1 << (16 - 4), 1).xxyy(); } diff --git a/plugins/GSdx/GSVertexTrace.h b/plugins/GSdx/GSVertexTrace.h index 802513fe2a..eaed4bf267 100644 --- a/plugins/GSdx/GSVertexTrace.h +++ b/plugins/GSdx/GSVertexTrace.h @@ -22,12 +22,15 @@ #pragma once #include "GSDrawingContext.h" +#include "GSVertex.h" #include "GSVertexSW.h" #include "GSVertexHW.h" #include "GSFunctionMap.h" #include "xbyak/xbyak.h" #include "xbyak/xbyak_util.h" +class GSState; + __declspec(align(16)) class GSVertexTrace { struct Vertex {GSVector4i c; GSVector4 p, t;}; @@ -82,7 +85,12 @@ __declspec(align(16)) class GSVertexTrace GSVertexTraceMapHW9 m_map_hw9; GSVertexTraceMapHW10 m_map_hw10; + uint32 Hash(GS_PRIM_CLASS primclass); + + const GSState* m_state; + public: + GS_PRIM_CLASS m_primclass; Vertex m_min, m_max; // t.xy * 0x10000 VertexAlpha m_alpha; // source alpha range after tfx, GSRenderer::GetAlphaMinMax() updates it @@ -93,7 +101,10 @@ public: struct {uint32 rgba:16, xyzf:4, stq:4;}; } m_eq; - void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context); - void Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context); - void Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass, const GIFRegPRIM* PRIM, const GSDrawingContext* context); + GSVertexTrace(const GSState* state); + + void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass); + void Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass); + void Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass); + void Update(const GSVertexNull* v, int count, GS_PRIM_CLASS primclass) {} }; diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index 3f148dbc6b..c86edc1408 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -75,24 +75,8 @@ LRESULT GSWnd::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) return DefWindowProc(m_hWnd, message, wParam, lParam); } -bool GSWnd::Create(const string& title) +bool GSWnd::Create(const string& title, int w, int h) { - GSVector4i r; - - GetWindowRect(GetDesktopWindow(), r); - - int w = r.width() / 3; - int h = r.width() / 4; - - if(!GetSystemMetrics(SM_REMOTESESSION)) - { - w *= 2; - h *= 2; - } - - int x = (r.left + r.right - w) / 2; - int y = (r.top + r.bottom - h) / 2; - WNDCLASS wc; memset(&wc, 0, sizeof(wc)); @@ -115,7 +99,32 @@ bool GSWnd::Create(const string& title) DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW | WS_BORDER; - m_hWnd = CreateWindow(wc.lpszClassName, title.c_str(), style, x, y, w, h, NULL, NULL, wc.hInstance, (LPVOID)this); + GSVector4i r; + + GetWindowRect(GetDesktopWindow(), r); + + bool remote = !!GetSystemMetrics(SM_REMOTESESSION); + + if(w <= 0 || h <= 0 || remote) + { + w = r.width() / 3; + h = r.width() / 4; + + if(!remote) + { + w *= 2; + h *= 2; + } + } + + r.left = (r.left + r.right - w) / 2; + r.top = (r.top + r.bottom - h) / 2; + r.right = r.left + w; + r.bottom = r.top + h; + + AdjustWindowRect(r, style, FALSE); + + m_hWnd = CreateWindow(wc.lpszClassName, title.c_str(), style, r.left, r.top, r.width(), r.height(), NULL, NULL, wc.hInstance, (LPVOID)this); if(!m_hWnd) { diff --git a/plugins/GSdx/GSWnd.h b/plugins/GSdx/GSWnd.h index ce5a0bebcf..8f0a72a0d4 100644 --- a/plugins/GSdx/GSWnd.h +++ b/plugins/GSdx/GSWnd.h @@ -34,7 +34,7 @@ public: GSWnd(); virtual ~GSWnd(); - bool Create(const string& title); + bool Create(const string& title, int w, int h); bool Attach(HWND hWnd); void* GetHandle() {return m_hWnd;} diff --git a/plugins/GSdx/GSdx.def b/plugins/GSdx/GSdx.def index fd1bf9dbb5..ec872b0b12 100644 --- a/plugins/GSdx/GSdx.def +++ b/plugins/GSdx/GSdx.def @@ -30,7 +30,8 @@ EXPORTS GSreadFIFO2 GSirqCallback GSsetGameCRC - GSsetFrameSkip + GSsetFrameSkip + GSsetFrameLimit GSgetLastTag GSReplay GSBenchmark diff --git a/plugins/GSdx/GSdx.rc b/plugins/GSdx/GSdx.rc index 71d99ae1a6..db6665a698 100644 --- a/plugins/GSdx/GSdx.rc +++ b/plugins/GSdx/GSdx.rc @@ -82,7 +82,7 @@ IDB_LOGO10 BITMAP "res\\logo10.bmp" // Dialog // -IDD_CONFIG DIALOGEX 0, 0, 189, 253 +IDD_CONFIG DIALOGEX 0, 0, 189, 247 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Settings..." FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -110,11 +110,12 @@ BEGIN CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,153,58,10 CONTROL "Allow 8-bit textures",IDC_PALTEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,165,82,10 CONTROL "Alpha correction (FBA)",IDC_FBA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,166,93,10 - CONTROL "Wait vsync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,177,51,10 - CONTROL "Edge anti-aliasing (AA1, sw-mode only)",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,190,141,10 - CONTROL "Enable output merger blur effect",IDC_BLUR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,204,121,10 - DEFPUSHBUTTON "OK",IDOK,43,232,50,14 - PUSHBUTTON "Cancel",IDCANCEL,96,232,50,14 + CONTROL "Wait VSync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,179,51,10 + CONTROL "Windowed",IDC_WINDOWED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,179,93,10 + CONTROL "Edge anti-aliasing (AA1, sw-mode only)",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,193,141,10 + CONTROL "Enable output merger blur effect",IDC_BLUR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,207,121,10 + DEFPUSHBUTTON "OK",IDOK,43,226,50,14 + PUSHBUTTON "Cancel",IDCANCEL,96,226,50,14 END IDD_CAPTURE DIALOGEX 0, 0, 279, 71 @@ -149,14 +150,15 @@ BEGIN COMBOBOX IDC_DITHERING,78,102,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Aspect Ratio (PgDn):",IDC_STATIC,7,120,68,8 COMBOBOX IDC_ASPECTRATIO,78,117,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Rendering Threads:",IDC_STATIC,7,150,64,8 - EDITTEXT IDC_SWTHREADS_EDIT,78,148,35,13,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,154,11,14 + LTEXT "Rendering Threads:",IDC_STATIC,7,157,64,8 + EDITTEXT IDC_SWTHREADS_EDIT,78,155,35,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SWTHREADS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,99,161,11,14 DEFPUSHBUTTON "OK",IDOK,43,178,50,14 PUSHBUTTON "Cancel",IDCANCEL,96,178,50,14 CONTROL 2022,IDC_LOGO10,"Static",SS_BITMAP,7,7,173,42 LTEXT "Internal Resolution:",IDC_STATIC,7,135,64,8 COMBOBOX IDC_SCALE,78,132,104,98,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Windowed",IDC_WINDOWED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,129,157,49,10 END @@ -176,7 +178,7 @@ BEGIN VERTGUIDE, 89 VERTGUIDE, 182 TOPMARGIN, 7 - BOTTOMMARGIN, 246 + BOTTOMMARGIN, 240 HORZGUIDE, 49 END diff --git a/plugins/GSdx/res/convert.fx b/plugins/GSdx/res/convert.fx index 9749476e6d..5d1ef9fb59 100644 --- a/plugins/GSdx/res/convert.fx +++ b/plugins/GSdx/res/convert.fx @@ -12,18 +12,13 @@ struct VS_OUTPUT float2 t : TEXCOORD0; }; -VS_OUTPUT vs_main(VS_INPUT input) -{ - VS_OUTPUT output; - - output.p = input.p; - output.t = input.t; - - return output; -} - Texture2D Texture; -SamplerState Sampler; +SamplerState TextureSampler; + +float4 sample_c(float2 uv) +{ + return Texture.Sample(TextureSampler, uv); +} struct PS_INPUT { @@ -31,70 +26,10 @@ struct PS_INPUT float2 t : TEXCOORD0; }; -float4 ps_main0(PS_INPUT input) : SV_Target0 +struct PS_OUTPUT { - return Texture.Sample(Sampler, input.t); -} - -uint ps_main1(PS_INPUT input) : SV_Target0 -{ - float4 f = Texture.Sample(Sampler, input.t); - - f.a *= 256.0f/127; // hm, 0.5 won't give us 1.0 if we just multiply with 2 - - uint4 i = f * float4(0x001f, 0x03e0, 0x7c00, 0x8000); - - return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000); -} - -float4 ps_main2(PS_INPUT input) : SV_Target0 -{ - clip(Texture.Sample(Sampler, input.t).a - (0.5 - 0.9f/256)); - - return 0; -} - -float4 ps_main3(PS_INPUT input) : SV_Target0 -{ - clip((0.5 - 0.9f/256) - Texture.Sample(Sampler, input.t).a); - - return 0; -} - -float4 ps_main4(PS_INPUT input) : SV_Target0 -{ - float4 c = Texture.Sample(Sampler, input.t); - - return fmod(c * 255 + 0.5f, 256) / 255; -} - -float4 ps_crt(PS_INPUT input, uint i) -{ - float4 mask[4] = - { - float4(1, 0, 0, 0), - float4(0, 1, 0, 0), - float4(0, 0, 1, 0), - float4(1, 1, 1, 0) - }; - - return Texture.Sample(Sampler, input.t) * saturate(mask[i] + 0.5f); -} - -float4 ps_main5(PS_INPUT input) : SV_Target0 // triangular -{ - uint4 p = (uint4)input.p; - - // return ps_crt(input, ((p.x + (p.y & 1) * 3) >> 1) % 3); - return ps_crt(input, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3); -} - -float4 ps_main6(PS_INPUT input) : SV_Target0 // diagonal -{ - uint4 p = (uint4)input.p; - - return ps_crt(input, (p.x + (p.y % 3)) % 3); -} + float4 c : SV_Target0; +}; #elif SHADER_MODEL <= 0x300 @@ -110,6 +45,26 @@ struct VS_OUTPUT float2 t : TEXCOORD0; }; +struct PS_INPUT +{ + float4 p : VPOS; + float2 t : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 c : COLOR; +}; + +sampler Texture : register(s0); + +float4 sample_c(float2 uv) +{ + return tex2D(Texture, uv); +} + +#endif + VS_OUTPUT vs_main(VS_INPUT input) { VS_OUTPUT output; @@ -120,40 +75,16 @@ VS_OUTPUT vs_main(VS_INPUT input) return output; } -sampler Texture : register(s0); - -float4 ps_main0(float2 t : TEXCOORD0) : COLOR +PS_OUTPUT ps_main0(PS_INPUT input) { - return tex2D(Texture, t); + PS_OUTPUT output; + + output.c = sample_c(input.t); + + return output; } -float4 ps_main1(float2 t : TEXCOORD0) : COLOR -{ - float4 c = tex2D(Texture, t); - c.a *= 128.0f / 255; // *= 0.5f is no good here, need to do this in order to get 0x80 for 1.0f (instead of 0x7f) - return c; -} - -float4 ps_main2(float2 t : TEXCOORD0) : COLOR -{ - clip(tex2D(Texture, t).a - (1.0f - 0.9f/256)); - - return 0; -} - -float4 ps_main3(float2 t : TEXCOORD0) : COLOR -{ - clip((1.0f - 0.9f/256) - tex2D(Texture, t).a); - - return 0; -} - -float4 ps_main4() : COLOR -{ - return 1; -} - -float4 ps_crt(float2 t, int i) +float4 ps_crt(PS_INPUT input, int i) { float4 mask[4] = { @@ -163,22 +94,143 @@ float4 ps_crt(float2 t, int i) float4(1, 1, 1, 0) }; - return tex2D(Texture, t) * saturate(mask[i] + 0.5f); + return sample_c(input.t) * saturate(mask[i] + 0.5f); } -float4 ps_main5(float2 t : TEXCOORD0, float4 vPos : VPOS) : COLOR // triangular -{ - int4 p = (int4)vPos; +#if SHADER_MODEL >= 0x400 - // return ps_crt(t, ((p.x + (p.y % 2) * 3) / 2) % 3); - return ps_crt(t, ((p.x + ((p.y / 2) % 2) * 3) / 2) % 3); +uint ps_main1(PS_INPUT input) : SV_Target0 +{ + float4 c = sample_c(input.t); + + c.a *= 256.0f / 127; // hm, 0.5 won't give us 1.0 if we just multiply with 2 + + uint4 i = c * float4(0x001f, 0x03e0, 0x7c00, 0x8000); + + return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000); } -float4 ps_main6(float2 t : TEXCOORD0, float4 vPos : VPOS) : COLOR // diagonal +PS_OUTPUT ps_main2(PS_INPUT input) { - int4 p = (int4)vPos; + PS_OUTPUT output; + + clip(sample_c(input.t).a - 128.0f / 255); // >= 0x80 pass + + output.c = 0; - return ps_crt(t, (p.x + (p.y % 3)) % 3); + return output; +} + +PS_OUTPUT ps_main3(PS_INPUT input) +{ + PS_OUTPUT output; + + clip(127.95f / 255 - sample_c(input.t).a); // < 0x80 pass (== 0x80 should not pass) + + output.c = 0; + + return output; +} + +PS_OUTPUT ps_main4(PS_INPUT input) +{ + PS_OUTPUT output; + + output.c = fmod(sample_c(input.t) * 255 + 0.5f, 256) / 255; + + return output; +} + +PS_OUTPUT ps_main5(PS_INPUT input) // triangular +{ + PS_OUTPUT output; + + uint4 p = (uint4)input.p; + + // output.c = ps_crt(input, ((p.x + (p.y & 1) * 3) >> 1) % 3); + output.c = ps_crt(input, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3); + + return output; +} + +PS_OUTPUT ps_main6(PS_INPUT input) // diagonal +{ + PS_OUTPUT output; + + uint4 p = (uint4)input.p; + + output.c = ps_crt(input, (p.x + (p.y % 3)) % 3); + + return output; +} + +#elif SHADER_MODEL <= 0x300 + +PS_OUTPUT ps_main1(PS_INPUT input) +{ + PS_OUTPUT output; + + float4 c = sample_c(input.t); + + c.a *= 128.0f / 255; // *= 0.5f is no good here, need to do this in order to get 0x80 for 1.0f (instead of 0x7f) + + output.c = c; + + return output; +} + +PS_OUTPUT ps_main2(PS_INPUT input) +{ + PS_OUTPUT output; + + clip(sample_c(input.t).a - 255.0f / 255); // >= 0x80 pass + + output.c = 0; + + return output; +} + +PS_OUTPUT ps_main3(PS_INPUT input) +{ + PS_OUTPUT output; + + clip(254.95f / 255 - sample_c(input.t).a); // < 0x80 pass (== 0x80 should not pass) + + output.c = 0; + + return output; +} + +PS_OUTPUT ps_main4(PS_INPUT input) +{ + PS_OUTPUT output; + + output.c = 1; + + return output; +} + +PS_OUTPUT ps_main5(PS_INPUT input) // triangular +{ + PS_OUTPUT output; + + int4 p = (int4)input.p; + + // output.c = ps_crt(input, ((p.x + (p.y % 2) * 3) / 2) % 3); + output.c = ps_crt(input, ((p.x + ((p.y / 2) % 2) * 3) / 2) % 3); + + return output; +} + +PS_OUTPUT ps_main6(PS_INPUT input) // diagonal +{ + PS_OUTPUT output; + + int4 p = (int4)input.p; + + output.c = ps_crt(input, (p.x + (p.y % 3)) % 3); + + return output; } #endif \ No newline at end of file diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx index e36e97ea40..630fda80c8 100644 --- a/plugins/GSdx/res/tfx.fx +++ b/plugins/GSdx/res/tfx.fx @@ -12,7 +12,6 @@ #define VS_BPPZ 0 #define VS_TME 1 #define VS_FST 1 -#define VS_PRIM 0 #endif #ifndef GS_IIP @@ -34,7 +33,7 @@ #define PS_CLR1 0 #define PS_FBA 0 #define PS_AOUT 0 -#define PS_LTF 0 +#define PS_LTF 1 #endif struct VS_INPUT @@ -101,6 +100,15 @@ float4 sample_p(float u) return Palette.Sample(PaletteSampler, u); } +#if SHADER_MODEL >= 0x401 + +float4 gather_c(float2 uv) +{ + return Texture.Gather(TextureSampler, uv, int2(0, 0)); +} + +#endif + #elif SHADER_MODEL <= 0x300 #ifndef VS_BPPZ @@ -184,6 +192,7 @@ float4 wrapuv(float4 uv) { if(PS_WMS == PS_WMT) { +/* if(PS_WMS == 0) { uv = frac(uv); @@ -192,7 +201,9 @@ float4 wrapuv(float4 uv) { uv = saturate(uv); } - else if(PS_WMS == 2) + else +*/ + if(PS_WMS == 2) { uv = clamp(uv, MinMax.xyxy, MinMax.zwzw); } @@ -210,6 +221,7 @@ float4 wrapuv(float4 uv) } else { +/* if(PS_WMS == 0) { uv.xz = frac(uv.xz); @@ -218,7 +230,9 @@ float4 wrapuv(float4 uv) { uv.xz = saturate(uv.xz); } - else if(PS_WMS == 2) + else +*/ + if(PS_WMS == 2) { uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz); } @@ -231,7 +245,7 @@ float4 wrapuv(float4 uv) uv.z = tex1D(UMSKFIX, uv.z); #endif } - +/* if(PS_WMT == 0) { uv.yw = frac(uv.yw); @@ -240,7 +254,9 @@ float4 wrapuv(float4 uv) { uv.yw = saturate(uv.yw); } - else if(PS_WMT == 2) + else +*/ + if(PS_WMT == 2) { uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww); } @@ -288,17 +304,25 @@ float4x4 sample_4c(float4 uv) return c; } -float4 sample_4a(float4 uv) +float4 sample_4a(float4 uv, float2 st) { float4 c; - +/* + #if SHADER_MODEL >= 0x401 && PS_FMT == FMT_8 && PS_LTF && PS_WMS < 2 && PS_WMT < 2 + + c = gather_c(st); // the order of samples returned might not be the same as ours + + #else +*/ c.x = sample_c(uv.xy).a; c.y = sample_c(uv.zy).a; c.z = sample_c(uv.xw).a; c.w = sample_c(uv.zw).a; - +/* + #endif +*/ #if SHADER_MODEL <= 0x300 - if(PS_RT) c *= 0.5; + if(PS_RT) c *= 128.0f / 255; #endif return c; @@ -355,19 +379,19 @@ float4 sample(float2 st, float q) if(PS_FMT == FMT_8H) { - c = sample_4p(sample_4a(uv)); + c = sample_4p(sample_4a(uv, st.xy)); } else if(PS_FMT == FMT_4HL) { - c = sample_4p(fmod(sample_4a(uv), 1.0f / 16)); + c = sample_4p(fmod(sample_4a(uv, st.xy), 1.0f / 16)); } else if(PS_FMT == FMT_4HH) { - c = sample_4p(fmod(sample_4a(uv) * 16, 1.0f / 16)); + c = sample_4p(fmod(sample_4a(uv, st.xy) * 16, 1.0f / 16)); } else if(PS_FMT == FMT_8) { - c = sample_4p(sample_4a(uv)); + c = sample_4p(sample_4a(uv, st.xy)); } else { @@ -387,7 +411,7 @@ float4 sample(float2 st, float q) if(PS_FMT == FMT_32) { #if SHADER_MODEL <= 0x300 - if(PS_RT) t.a *= 0.5; + if(PS_RT) t.a *= 128.0f / 255; #endif } else if(PS_FMT == FMT_24) @@ -520,11 +544,6 @@ VS_OUTPUT vs_main(VS_INPUT input) input.z = input.z & 0xffff; } - if(VS_PRIM == 3) // sprite - { - //input.p.xy = (input.p.xy + 15) & ~15; // HACK - } - VS_OUTPUT output; // pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go) diff --git a/plugins/GSdx/resource.h b/plugins/GSdx/resource.h index a0e99b015b..7d291cdced 100644 --- a/plugins/GSdx/resource.h +++ b/plugins/GSdx/resource.h @@ -40,6 +40,7 @@ #define IDC_WIDTH 2036 #define IDC_HEIGHT 2037 #define IDC_CONFIGURE 2038 +#define IDC_WINDOWED 2039 #define IDR_CONVERT_FX 10000 #define IDR_TFX_FX 10001 #define IDR_MERGE_FX 10002 @@ -51,7 +52,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 10004 #define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 2039 +#define _APS_NEXT_CONTROL_VALUE 2040 #define _APS_NEXT_SYMED_VALUE 5000 #endif #endif diff --git a/plugins/GSdx/stdafx.h b/plugins/GSdx/stdafx.h index 510d2c3231..81cd131dff 100644 --- a/plugins/GSdx/stdafx.h +++ b/plugins/GSdx/stdafx.h @@ -53,6 +53,7 @@ #include #include #include +#include #include using namespace std; diff --git a/plugins/GSdx/vsprops/common.vsprops b/plugins/GSdx/vsprops/common.vsprops index 3a9d3ab82a..100fa0e3aa 100644 --- a/plugins/GSdx/vsprops/common.vsprops +++ b/plugins/GSdx/vsprops/common.vsprops @@ -18,9 +18,9 @@ /> GetJoy(), key_to_axis(cpad, i)); - - switch (i) - { - case PAD_LX: - case PAD_LY: - case PAD_RX: - case PAD_RY: - if (abs(value) > (pjoy)->GetDeadzone(value)) - Analog::ConfigurePad(i, pad, value); - else - Analog::ResetPad(i, pad); - break; - } - break; - } case PAD_HAT: { int value = SDL_JoystickGetHat((pjoy)->GetJoy(), key_to_axis(cpad, i)); @@ -158,12 +140,40 @@ EXPORT_C_(void) PADupdate(int pad) { int value = SDL_JoystickGetAxis((pjoy)->GetJoy(), key_to_axis(cpad, i)); + PAD_LOG("%s: %d (%d)\n", KeyName(cpad, i).c_str(), value, key_to_pov_sign(cpad, i)); if (key_to_pov_sign(cpad, i) && (value < -2048)) + { + //PAD_LOG("%s Released+.\n", KeyName(cpad, i).c_str()); clear_bit(status[pad], i); + } else if (!key_to_pov_sign(cpad, i) && (value > 2048)) + { + //PAD_LOG("%s Released-\n", KeyName(cpad, i).c_str()); clear_bit(status[pad], i); + } else + { + //PAD_LOG("%s Pressed.\n", KeyName(cpad, i).c_str()); set_bit(status[pad], i); + } + break; + } + case PAD_JOYSTICK: + { + int value = SDL_JoystickGetAxis((pjoy)->GetJoy(), key_to_axis(cpad, i)); + + switch (i) + { + case PAD_LX: + case PAD_LY: + case PAD_RX: + case PAD_RY: + if (abs(value) > (pjoy)->GetDeadzone(value)) + Analog::ConfigurePad(pad, i, value); + else + Analog::ResetPad(pad, i); + break; + } break; } default: break; diff --git a/plugins/onepad/analog.cpp b/plugins/onepad/analog.cpp index 2eef28a9fb..1e07f1c239 100644 --- a/plugins/onepad/analog.cpp +++ b/plugins/onepad/analog.cpp @@ -24,24 +24,24 @@ PADAnalog g_lanalog[NUM_OF_PADS], g_ranalog[NUM_OF_PADS]; namespace Analog { - u8 Pad(int padvalue, u8 i) + u8 Pad(int pad, u8 index) { - switch (padvalue) + switch (index) { case PAD_LX: - return g_lanalog[i].x; + return g_lanalog[pad].x; break; case PAD_RX: - return g_ranalog[i].x; + return g_ranalog[pad].x; break; case PAD_LY: - return g_lanalog[i].y; + return g_lanalog[pad].y; break; case PAD_RY: - return g_ranalog[i].y; + return g_ranalog[pad].y; break; default: @@ -50,24 +50,24 @@ namespace Analog } } - void SetPad(int padvalue, u8 i, u8 value) + void SetPad(u8 pad, int index, u8 value) { - switch (padvalue) + switch (index) { case PAD_LX: - g_lanalog[i].x = value; + g_lanalog[pad].x = value; break; case PAD_RX: - g_ranalog[i].x = value; + g_ranalog[ pad].x = value; break; case PAD_LY: - g_lanalog[i].y = value; + g_lanalog[ pad].y = value; break; case PAD_RY: - g_ranalog[i].y = value; + g_ranalog[pad].y = value; break; default: @@ -75,30 +75,30 @@ namespace Analog } } - void InvertPad(int padvalue, u8 i) + void InvertPad(u8 pad, int key) { - SetPad(padvalue, i, -Pad(padvalue, i)); + SetPad(pad, key, -Pad(pad, key)); } - void ResetPad(int padvalue, u8 i) + void ResetPad( u8 pad, int key) { - SetPad(padvalue, i, 0x80); + SetPad(pad, key, 0x80); } void Init() { - for (int i = 0; i < 2; ++i) + for (u8 pad = 0; pad < 2; ++pad) { - ResetPad(PAD_LX, i); - ResetPad(PAD_LY, i); - ResetPad(PAD_RX, i); - ResetPad(PAD_RY, i); + ResetPad(pad, PAD_LX); + ResetPad(pad, PAD_LY); + ResetPad(pad, PAD_RX); + ResetPad(pad, PAD_RY); } } - bool RevertPad(u8 padvalue) + bool RevertPad(u8 index) { - switch (padvalue) + switch (index) { case PAD_LX: return ((conf.options & PADOPTION_REVERTLX) != 0); @@ -122,18 +122,17 @@ namespace Analog } } - void ConfigurePad(int padvalue, u8 i, int value) + void ConfigurePad( u8 pad, int index, int value) { - int temp = Pad(padvalue, i); - SetPad(padvalue, i, value / 256); - if (RevertPad(padvalue)) InvertPad(padvalue, i); - SetPad(padvalue, i, Pad(padvalue, i) + 0x80); - - //PAD_LOG("Setting pad[%d]@%d to %d from %d\n", padvalue, i, value, temp); + int temp = Pad(pad, index); + SetPad(pad, index, value / 256); + if (RevertPad(index)) InvertPad(pad,index); + SetPad(pad, index, Pad(pad, index) + 0x80); } - int AnalogToPad(int padvalue) + + int AnalogToPad(int index) { - switch (padvalue) + switch (index) { case PAD_R_LEFT: return PAD_RX; diff --git a/plugins/onepad/analog.h b/plugins/onepad/analog.h index 62875cb1d0..ab3053ec14 100644 --- a/plugins/onepad/analog.h +++ b/plugins/onepad/analog.h @@ -25,12 +25,12 @@ namespace Analog { extern void Init(); - extern u8 Pad(int padvalue, u8 i); - extern void SetPad(int padvalue, u8 i, u8 value); - extern void InvertPad(int padvalue, u8 i); - extern bool RevertPad(u8 padvalue); - extern void ResetPad(int padvalue, u8 i); - extern void ConfigurePad(int padvalue, u8 i, int value); + extern u8 Pad(int pad, u8 index); + extern void SetPad(u8 pad, int index, u8 value); + extern void InvertPad(u8 pad, int key); + extern bool RevertPad(u8 index); + extern void ResetPad( u8 pad, int key); + extern void ConfigurePad( u8 pad, int index, int value); extern int KeypadToPad(u8 keypress); - extern int AnalogToPad(int padvalue); + extern int AnalogToPad(int index); } \ No newline at end of file diff --git a/plugins/onepad/keyboard.cpp b/plugins/onepad/keyboard.cpp index caf3d2f36c..e94bf03554 100644 --- a/plugins/onepad/keyboard.cpp +++ b/plugins/onepad/keyboard.cpp @@ -92,13 +92,13 @@ void PollForX11KeyboardInput(int pad) case PAD_R_UP: case PAD_L_LEFT: case PAD_L_UP: - Analog::ConfigurePad(Analog::AnalogToPad(i), pad, DEF_VALUE); + Analog::ConfigurePad(pad, Analog::AnalogToPad(i), DEF_VALUE); break; case PAD_R_RIGHT: case PAD_R_DOWN: case PAD_L_RIGHT: case PAD_L_DOWN: - Analog::ConfigurePad(Analog::AnalogToPad(i), pad, -DEF_VALUE); + Analog::ConfigurePad(pad, Analog::AnalogToPad(i), -DEF_VALUE); break; } i += 0xff00; @@ -123,7 +123,7 @@ void PollForX11KeyboardInput(int pad) // Analog Controls. if ((i > PAD_RY) && (i <= PAD_R_LEFT)) { - Analog::ResetPad(Analog::AnalogToPad(i), pad); + Analog::ResetPad(pad, Analog::AnalogToPad(i)); i += 0xff00; } diff --git a/plugins/onepad/onepad.cpp b/plugins/onepad/onepad.cpp index b443f0a903..585e3c7178 100644 --- a/plugins/onepad/onepad.cpp +++ b/plugins/onepad/onepad.cpp @@ -195,7 +195,6 @@ void __Log(const char *fmt, ...) { va_list list; - //if (padLog == NULL || !conf.log) return; if (padLog == NULL) return; va_start(list, fmt); vfprintf(padLog, fmt, list); @@ -393,10 +392,10 @@ u8 _PADpoll(u8 value) stdpar[curPad][2] = status[curPad] >> 8; stdpar[curPad][3] = status[curPad] & 0xff; - stdpar[curPad][4] = Analog::Pad(PAD_RX, curPad); - stdpar[curPad][5] = Analog::Pad(PAD_RY, curPad); - stdpar[curPad][6] = Analog::Pad(PAD_LX, curPad); - stdpar[curPad][7] = Analog::Pad(PAD_LY, curPad); + stdpar[curPad][4] = Analog::Pad(curPad, PAD_RX); + stdpar[curPad][5] = Analog::Pad(curPad, PAD_RY); + stdpar[curPad][6] = Analog::Pad(curPad, PAD_LX); + stdpar[curPad][7] = Analog::Pad(curPad, PAD_LY); if (padMode[curPad] == 1) cmdLen = 20; diff --git a/plugins/spu2-x/src/ADSR.cpp b/plugins/spu2-x/src/ADSR.cpp index e11925b2d0..a79142fa69 100644 --- a/plugins/spu2-x/src/ADSR.cpp +++ b/plugins/spu2-x/src/ADSR.cpp @@ -204,7 +204,7 @@ void V_VolumeSlide::Update() Value -= PsxRates[(Increment^0x7f)-0x1b+off+32]; } else - Value -= Increment; + Value -= Increment<<8; if (Value < 0) { @@ -221,7 +221,7 @@ void V_VolumeSlide::Update() if( (Mode & VOLFLAG_EXPONENTIAL) && (Value>=0x60000000)) Value += PsxRates[(Increment^0x7f)-0x18+32]; else - Value += Increment; + Value += Increment<<8; if( Value < 0 ) // wrapped around the "top"? { diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp index 066444f7e4..a81b90672c 100644 --- a/plugins/spu2-x/src/Mixer.cpp +++ b/plugins/spu2-x/src/Mixer.cpp @@ -313,7 +313,7 @@ static s32 __forceinline GetNoiseValues() // Data is expected to be 16 bit signed (typical stuff!). // volume is expected to be 32 bit signed (31 bits with reverse phase) -// Output is effectively 15 bit range, thanks to the signed volume. +// Data is shifted up by 1 bit to give the output an effective 16 bit range. static __forceinline s32 ApplyVolume(s32 data, s32 volume) { //return (volume * data) >> 15; @@ -513,6 +513,7 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx ) // Most games don't use much volume slide effects. So only call the UpdateVolume // methods when needed by checking the flag outside the method here... + // (Note: Ys 6 : Ark of Nephistm uses these effects) vc.Volume.Update(); @@ -573,7 +574,7 @@ struct VoiceMixSet } }; -const VoiceMixSet VoiceMixSet::Empty( StereoOut32::Empty, StereoOut32::Empty ); +const VoiceMixSet VoiceMixSet::Empty( StereoOut32(), StereoOut32() ); // Don't use SteroOut32::Empty because C++ doesn't make any dep/order checks on global initializers. static __forceinline void MixCoreVoices( VoiceMixSet& dest, const uint coreidx ) { @@ -584,7 +585,7 @@ static __forceinline void MixCoreVoices( VoiceMixSet& dest, const uint coreidx ) StereoOut32 VVal( MixVoice( coreidx, voiceidx ) ); // Note: Results from MixVoice are ranged at 16 bits. - + dest.Dry.Left += VVal.Left & thiscore.VoiceGates[voiceidx].DryL; dest.Dry.Right += VVal.Right & thiscore.VoiceGates[voiceidx].DryR; dest.Wet.Left += VVal.Left & thiscore.VoiceGates[voiceidx].WetL; diff --git a/plugins/spu2-x/src/Spu2.h b/plugins/spu2-x/src/Spu2.h index a96a589136..c9b3aadb74 100644 --- a/plugins/spu2-x/src/Spu2.h +++ b/plugins/spu2-x/src/Spu2.h @@ -34,7 +34,7 @@ namespace VersionInfo { static const u8 PluginApi = PS2E_SPU2_VERSION; static const u8 Release = 1; - static const u8 Revision = 1; // increase that with each version + static const u8 Revision = 2; // increase that with each version } #ifdef _MSC_VER