Editing PS1 Emulation

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 8: Line 8:
Emulator have some leftovers from PSP emulator (like axinsnreplace), so core of non PS1 specific functions is the same as in PSP emu. Rest of emu seems to be "inspired" by mednafen.  
Emulator have some leftovers from PSP emulator (like axinsnreplace), so core of non PS1 specific functions is the same as in PSP emu. Rest of emu seems to be "inspired" by mednafen.  


== Folder/File layout ==
Example: Medievil internal emulator, standalone pkg can differ.
<pre>
├──bios
│  ├── scph5500.bin
│  ├── scph5501.bin
│  └── scph5502.bin
├──config-emu-ps4.txt
├──data
│  └── image.bin
├──eboot.bin
├──sce_module
│  ├── libc.prx
│  ├── libSceAudioLatencyEstimation.prx
│  ├── libSceFace.prx
│  ├── libSceFaceTracker.prx
│  ├── libSceFios2.prx
│  ├── libSceHand.prx
│  ├── libSceHandTracker.prx
│  ├── libSceHeadTracker.prx
│  ├── libSceJobManager.prx
│  ├── libSceNpToolkit2.prx
│  └── libSceS3DConversion.prx
├──sce_sys
│  └── param.sfo
├──scripts
│  └── patches.lua
</pre>


== Configuration Files ==
== Configuration Files ==
=== config-title.txt ===
=== config-emu-ps4.txt ===
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
! style="width:10%" | Command !! style="width:15%" | Values !! Notes !! style="width:20%" | Usage  
! style="width:10%" | Command !! style="width:15%" | Values !! Notes !! style="width:20%" | Usage  
|-
| --wait|| || ||
|-
| --bios|| path || Need to match region of game, relative to sandbox root || --bios=SCPH101.bin
|-
| --configpath|| || ||
|-
| --texdump|| || ||
|-
| --texreplace|| || || 
|-
|-
| --region|| SCEE SCEA SCEI || Image/Bios region || --region="SCEE"
| --region|| SCEE SCEA SCEI || Image/Bios region || --region="SCEE"
Line 28: Line 47:
| --image|| path || game image path, sandbox root relative || "data/MyGame.bin"
| --image|| path || game image path, sandbox root relative || "data/MyGame.bin"
|-
|-
| --libcrypt|| "CRC16" || Libcrypt magic, unknown what is really hashed. required for many PAL games, Without it a lot of games will either crash or produce glitches || --libcrypt="0xAB34"
| --libcrypt|| CRC16 || Libcrypt magic, unknown what is really hashed. required for many PAL games || --libcrypt="0xAB34"
|-
|-
| --scale|| 1 , 2 , 4, 6, auto || 1 = 1280x720, 2 = 1920x1080, 4 = 3840x2160, auto= same as ps4 video settings(?) please keep in mind that even using scale=1 can cause upscaling glitches || scale=2
| --scale|| 1 , 2 , 4, auto || 1 = 1280x720, 2 = 1920x1080, 4 = 3840x2160, auto= same as ps4 video settings(?) please keep in mind that even using scale=1 can cause upscaling glitches || scale=2
|-
|-
| --antialias|| off?, SSAA4x , MSAA4x || same as above, using this can cause visual glitches on games that scales bad || --antialias=SSAA4x
| --antialias|| SSAA4x , MSAA4x || same as above, using this can cause visual glitches on games that scales bad || --antialias=SSAA4x
|-
|-
| --gpu-scanout-fps-override || ntsc, pal? || || --gpu-scanout-fps-override=ntsc
| --softgpu|| || ||
|-
|-
| --remap || ? || Remap Buttons ? || ?
| --state-restore|| || ||  
|-
|-
| --multitap || on,off || Enables multitap for games like Crash Bash || --multitap=true
| --wait|| || ||  
|-
|-
| --metal-gear-solid || 0,1 || Specific Command for MGS1|| --metal-gear-solid=1
| --mcd0|| || ||  
|-
|-
| --vram-read-frame-delay || True? False? || Speedhack??  || ?
| --mcd1|| || ||  
|-
|-
| --sim-analog-pad || || Enable joysticks to work instead of d-pad? || --sim-analog-pad=0x2020
| --bios|| path || Need to match region of game, relative to sandbox root || --bios="BIOS/SCPH5502.bin"
|-
|-
| --cdrom-cmd-time || 0,100? || Can be used to fix black screens || --cdrom-cmd-time=100
| --configpath|| || ||  
|-
|-
| --cdrom-max-seek || true, false || Can be used to fix black screens || --cdrom-max-seek=true
| --texdump|| || ||  
|-
|-
| --texrecent|| true , false || Optimize texture hashes Leading To better Performance || --texrecent=true
| --texreplace|| || ||
|-
|-
| --use-lopnor-spu|| 1, 0 || like this is FiX for sound || --use-lopnor-spu=1
| --texrecent|| true , false || unk || --texrecent=true
|-
|-
| --userui-settings-graphics|| 1, 0 ||
|}
'''filter'''
 
>> None,Bicubic,Lanczos,Cubic
=== patches.lua ===
'''Anti-Aliasing''' >> FXAA,CMAA
Lua patches are split between 3 categories R3K (r3000 mips), and EM (emulator), TR (trophies). Called by getXXXObject. Only exception from that is apiRequest.
'''Upscale Factor''' >>2x,3x,4x,5x,6x Scale
 
|| --userui-settings-graphics=1
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
! Command !! Usage !! Notes
|-
|-
| --enable-user-color-adjustment || 1, 0 || it can change your brightness,contrast, gamma etc. || --enable-user-color-adjustment=1
| apiRequest || apiRequest(<api version>) || example: apiRequest(1.0)
Different emu versions support different highest api. Medievil emu support api up to 1.0
Calling api is mandatory.
|-
|-
|}
|}


===XXXXYYYYY.LUA===  
==== getR3KObject() ====
<br>'''scripts/XXXXYYYYY.LUA'''
For usage examples lets declare getR3KObject() as r3k [ local r3k = getR3KObject() ] to make things closer to official configs.
<br>Lua patches are split between 2 categories R3K (r3000 mips), and EM (emulator). Objects do not need to be called in order for their commands to be usable, contrary to the PS2's emulator.
====R3000 commands====
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
! Command !! Usage !! Example !! Notes
! Command !! style="width:40%" | Usage !! Notes
|-
|-
|GetPC   || R3K_GetPC() || ||Return current Program counter.
|GetPC   || r3k.GetPC() || Return current PC.
|-
|-
|SetPC   || R3K_SetPC(address) || ||Set current Program counter to address.  
|SetPC   || r3k.SetPC(address) || Set current PC to address.  
|-
|-
|GetHi   || R3K_GetHi || ||Return Hi register value.
|GetHi   || r3k.GetHi || Return Hi register value.
|-
|-
|SetHi   || R3K_SetHi(value) || ||Set Hi register value.
|SetHi   || r3k.SetHi(value) || Set Hi register value.
|-
|-
|GetLo   || R3K_GetLo || ||Return Lo register value.
|GetLo   || r3k.GetLo || Return Lo register value.
|-             
|-             
|SetLo   || R3K_SetLo(value) || ||Set Lo register value.
|SetLo   || r3k.SetLo(value) || Set Lo register value.
|-
|-
|GetGpr   || R3K_GetGpr(reg) || ||Return register value, require formatting like here: r3k.GetGpr(gpr.a0).
|GetGpr   || r3k.GetGpr(reg) || Return register value, require formatting like here: r3k.GetGpr(gpr.a0).
|-             
|-             
|SetGpr   || R3K_SetGpr(reg, value) || ||Set register value, require formatting like here: r3k.GetGpr(gpr.a0, value).
|SetGpr   || r3k.SetGpr(reg, value) || Set register value, require formatting like here: r3k.GetGpr(gpr.a0, value).
|-
|-
|ReadMem8   || R3K_ReadMem8(address) || ||Read/return byte from address.
|ReadMem8   || r3k.ReadMem8(address) || Read/return byte from address.
|-
|-
|ReadMem16   || R3K_ReadMem16(address) ||  ||Read/return half from address.
|ReadMem16   || r3k.ReadMem16(address) || Read/return half from address.
|-
|-
|ReadMem32   || R3K_ReadMem32(address) || ||Read/return word from address.
|ReadMem32   || r3k.ReadMem32(address) || Read/return word from address.
|-
|-
|ReadMemFloat  || R3K_ReadMemFloat(address) || ||Read/return float from address.
|ReadMemFloat  || r3k.ReadMemFloat(address) || Read/return float from address.
|-
|-
|ReadMemStr   || R3K_ReadMemStr(address) || ||Read/return string from address.
|ReadMemStr   || r3k.ReadMemStr(address) || Read/return string from address.
|-
|-
|WriteMem8   || R3K_WriteMem8(address, value) || ||Write/set selected memory as byte to value.  
|WriteMem8   || r3k.WriteMem8(address, value) || Write/set selected memory as byte to value.  
|-
|-
|WriteMem16   || R3K_WriteMem16(address, value) || ||Write/set selected memory as half to value.  
|WriteMem16   || r3k.WriteMem16(address, value) || Write/set selected memory as half to value.  
|-
|-
|WriteMem32   || R3K_WriteMem32(address, value) || R3K_WriteMem16(0x0006c71c,0x0900) || Write/set selected memory as word to value.
|WriteMem32   || r3k.WriteMem32(address, value) || Write/set selected memory as word to value.
|-
|-
|WriteMemFloat || R3K_WriteMemFloat(address, value) || ||Write/set selected memory as float to value.
|WriteMemFloat || r3k.WriteMemFloat(address, value) || Write/set selected memory as float to value.
|-
|-
|WriteMemStr   || R3K_WriteMemStr(address, value) || ||Write/set selected memory as string to value.
|WriteMemStr   || r3k.WriteMemStr(address, value) || Write/set selected memory as string to value.
|-
|-
|WriteMemStrZ  || R3K_WriteMemStrZ(address, value) || ||
|WriteMemStrZ  || r3k.WriteMemStrZ(address, value) ||  
|-
|-
|AddHook || R3K_AddHook(address, original opcode, function/hook) || ||Add hook into mips code.
|AddHook   || r3k.AddHook(address, original opcode, function/hook) || Add hook into mips code.
|-
|-
|RemoveHook|| R3K_RemoveHook(?) || || Remove hook from mips code.
|RemoveHook   || r3k.RemoveHook(?) || Remove hook from mips code.
|-
|-
|InsnReplace   || R3K_InsnReplace(address, original opcode, replace opcode) || || similar to pcsx2 pnach, but additionally use original opcode as a check.
|InsnReplace   || r3k.InsnReplace(address, original opcode, replace opcode) || similar to pcsx2 pnach, but additionally use original opcode as a check.
|-
|-
|FuncReplace   || R3K_FuncReplace(address, original opcode, function name) || || Hook/replace function in mips code with predefinied one.  
|FuncReplace   || r3k.FuncReplace(address, original opcode, function name) || Hook/replace function in mips code with predefinied one.  
|-
|-
|BurnCycles   || R3K_BurnCycles()||  ||
|BurnCycles   || ||  
|-
|-
|FlushCache   || R3K_FlushCache() || || Flush mips instruction cache.  
|FlushCache   || r3k.FlushCache() || Flush mips cache (D + I ?).
|-
|-
|}
|}


====Emulator commands====
==== getEmuObject() ====
For usage examples lets declare getEmuObject() as emu [ local emu = getEmuObject() ] to make things closer to official configs.
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
! Command !! Usage !! Example !! Notes
! Command !! Usage !! Notes
|-
|-
|PadRead || EM_PadRead() || ||Return pad state (pushed buttons).
|PadRead || emu.PadRead() || Return pad state (pushed buttons).
|-
|-
|PadReadLeftStick || EM_PadReadLeftStick() || ||Return pad left stick state.
|PadReadLeftStick || emu.PadReadLeftStick() || Return pad left stick state.
|-
|-
|PadReadRightStick || EM_PadReadRightStick() || ||Return pad right stick state.
|PadReadRightStick || emu.PadReadRightStick() || Return pad right stick state.
|-
|-
|PadSetButtonsMode || EM_PadSetButtonMode(value) || ||Set some pad mode, in one of official configs described as "switch Select/Start -> Touchpad/Options mode" with used value 2.
|PadSetButtonsMode || emu.PadSetButtonMode(value) || Set some pad mode, in one of official configs described as "switch Select/Start -> Touchpad/Options mode" with used value 2.
|-
|-
|AddVsyncHook || EM_AddVsyncHook(anything) || ||Add hook that trigger on every vsync, param usually will be previously prepared function.
|AddVsyncHook || ||
|-
|-
|RemoveVsyncHook|| EM_RemoveVsyncHook()|| ||Remove hook that trigger on every vsync.
|RemoveVsyncHook || ||
|-
|-
|ThrottleMax || EM_ThrottleMax() || ||Remove framelimiter, used frequently for loadings.
|ThrottleMax || emu.ThrottleMax() || Remove framelimiter, used frequently for loadings.
|-
|-
|ThrottleNormal || EM_ThrottleNormal() || ||Set framelimiter to default game value.
|ThrottleNormal || emu.ThrottleNormal() || Set framelimiter to default game value.
|-
|-
|Log || EM_Log(value) || ||Print debug messages to usermode console, ex. emu.Log(string.format("Overlay: %02x", overlay)).
|Log || emu.Log(value) || Print debug messages to userland console, ex. emu.Log(string.format("Overlay: %02x", overlay)).
|-
|-
|GetNativeLanguage|| EM_GetNativeLanguage() || ||Return used PS4 language.
|GetNativeLanguage || emu.GetNativeLanguage() || Return used PS4 language.
|-
|-
|LoadConfig||EM_LoadConfig() || ||
|LoadConfig || ||
|-
|-
|SaveConfig||EM_SaveConfig() || ||
|SaveConfig || ||
|-
|-
|LoadState|| EM_LoadState()|| ||Load savestate, seems to be disabled in Medievil emu.
|LoadState || ||
|-
|-
|SaveState||EM_SaveState() || ||Save savestate, seems to be disabled in Medievil emu.
|SaveState || ||
|-
|-
|PostEffect|| EM_PostEffect() || ||
|PostEffect || ||
|-
|-
|PostEffectParams|| EM_PostEffectParams()|| ||
|PostEffectParams || ||
|-
|-
|NeoMode|| EM_NeoMode() || || Return 1 if PS4 PRO, 0 otherwise.
|NeoMode || emu.NeoMode() || Return ps4 mode.
|-
|-
|CRC32 || || ||
|CRC32 || ||
|-
|-
|AddFBMapping|| EM_AddFBMapping( , , , ) || || Add framebffer mapping, in Medievil used with EM_AddFBMapping(768, 256, 180, 256) values.
|AddFBMapping || emu.AddFBMapping( , , , ) || Add framebffer mapping, in Medievil used with emu.AddFBMapping(768, 256, 180, 256) values.
|-
|-
|RemoveFBMapping|| EM_RemoveFBMapping( , ) || || Remove framebffer mapping, in Medievil used with EM_RemoveFBMapping(768, 256) values.
|RemoveFBMapping || emu.RemoveFBMapping( , ) || Remove framebffer mapping, in Medievil used with emu.RemoveFBMapping(768, 256) values.
|-
|-
|Launch || EM_Launch("path") || || Emulator is able to launch selfs in own sandbox, require full path (for example "/app0/folder/my_self.bin"), can be used for multidisc games.
|Launch || emu.Launch("path") || Emulator is able to launch selfs in own sandbox (or maybe more? ;) ), require full path (for example "/app0/folder/my_self.bin"), can be used for multidisc games.
|-
|-
|}
|}
<br>'''''LUA example:'''''
<pre>
local patcher = function()
R3K_WriteMem16(0x0006c71c,0x0900)
end
EM_AddVsyncHook(patcher)
</pre>


== Emulators ==
==== getTrophyObject() ====
<pre>Every emulator is programmed in a different way, sometimes choosing the right emulator is the only possible way to fix a game. Emulators are not provided pre-installed on the ps4, they have to be unpacked from a backup that's downloaded from the ps store from that specific game. this list includes The typical usage of some of The emulators.</pre>
For usage examples lets declare getTrophyObject() as trp [ local trp = getYtophyObject() ] to make things closer to official configs.
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
! Emulator !! Usage !! API Version !! Similar emulators (Usage)
! Command !! Usage !! Notes
|-
| Syphon filter || Most popular emulator so far and the one with the highest compatibility, It's used in PSXFPKG v0.3 as the default emulator ||  ? || ?
|-
|-
| Medievil || An unofficial emulator made by sony that's very bad emulator in terms of compatibility. || ? || ?
| Unlock || trp.Unlock(trophy id) || Unlock trophy by id
|-
|-
|}
|}


== PAL Libcrypt games ==
== PAL Libcrypt games ==
Some PAL PSX games include libcrypt protection, those are known to [http://wiki.redump.org/index.php?title=PlayStation_1:_LibCrypt_protection_(Old) cause issues for emulators.]
Some PAL PSX games include libcrypt protection, those are known to cause issues for emulators.
===List===
</br>More info here: http://wiki.redump.org/index.php?title=PlayStation_1:_LibCrypt_protection_(Old)
==List==


* Actua Ice Hockey 2 (Europe)
* Actua Ice Hockey 2 (Europe)
Line 301: Line 312:
* Vagrant Story (Europe) , (France) , (Germany)
* Vagrant Story (Europe) , (France) , (Germany)
* Walt Disney World Quest - Magical Racing Tour (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da)
* Walt Disney World Quest - Magical Racing Tour (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da)
* Wonderworld 2: Arena Of Courage (Europe) (En,Es,Fr,De,It,Da)
* Wip3out (Europe) (En,Fr,De,Es,It)
* Wip3out (Europe) (En,Fr,De,Es,It)


=== Known Issues ===  
=== Known Issues ===  
The exact effects of libcrypt depend on the game. However, they usually render the game unplayable in some form.
Some libcrypt issues are known to community. Here is list of them.  
Here is list of libcrypt-caused issues known to the community.  
All that can be patched before creating pkg, or fixed by using --libcrypt command in emu config.
Be sure to patch these games before creating a pkg, or try to fix them by using the --libcrypt command in the emu config.


{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
Line 316: Line 325:
|-
|-
|Crash Team Racing (PAL) ||
|Crash Team Racing (PAL) ||
Game will hang at the end of the loading screen, when trying to use a warp from the main level to any race track.
Game will hang once at the end of the loading screen (for the level itself).
|-
|Final Fantasy VIII (PAL) ||
Game immediately hangs on a black screen. It doesn't even play any intros.
|-
|-
|Legacy of Kain: Soul Reaver (PAL) ||
|Legacy of Kain: Soul Reaver (PAL) ||
Line 347: Line 353:
|V-Rally: Championship Edition 2 (PAL) ||
|V-Rally: Championship Edition 2 (PAL) ||
The game will endlessly load on the heartbeat loading screen (with no disc activity).
The game will endlessly load on the heartbeat loading screen (with no disc activity).
|-
|Vagrant Story (PAL) ||
Will hang on the "now loading"-screen, after choosing "new game" on the main menu.
|-
|Wonderworld 2: Arena Of Courage (PAL) ||
Still hangs on the "Loading, please wait..."-screen, when you start the mission.
|-
|-
|Wip3out (PAL) ||
|Wip3out (PAL) ||
Line 359: Line 359:
|}
|}


* Libcrypt info mostly taken from: https://github.com/Kippykip/SBITools#libcrypt-failed-check-causes-and-effects
* Libcrypt info took from: https://github.com/Kippykip/SBITools#libcrypt-failed-check-causes-and-effects


== Multi-Disc support ==
== Multi-Disc support ==
Line 373: Line 373:
*** So when loading the same Save File on next day, it will already ask in the beginning for the next Disc.
*** So when loading the same Save File on next day, it will already ask in the beginning for the next Disc.
**** If the next Disc is already inserted, then it will load the Game immediately.
**** If the next Disc is already inserted, then it will load the Game immediately.
**** If not then it will ask again for switching Discs (same when inserting a wrong Disc like "Disc 3" for instance but "Disc 2" is needed).
**** If not then it will ask again for switching Discs (same when inserting a wrong Disc like "Disc 3" for instance but "Disc 2" is needed for instance).


=== So how to do this on a PS4? ===
=== So how to do this on a PS4? ===
Line 379: Line 379:
* You create a FPKG containing '''Disc 1''' of Final Fantasy VII '''only''' (Example [[Content ID]] = CUSAFF7'''D1''').
* You create a FPKG containing '''Disc 1''' of Final Fantasy VII '''only''' (Example [[Content ID]] = CUSAFF7'''D1''').
* You play the Game normally until it asks you to save the Game before it will ask you to change the Disc.
* You play the Game normally until it asks you to save the Game before it will ask you to change the Disc.
* Save the Game and close the Application.
* Save the Game and close the Application
* On your PS4 [[Harddrive]], there should be ''theoretically'' the Save File somewhere (within the Game Files from the Game itself ???).
* On your PS4 [[Harddrive]], there should be ''theoretically'' the Save File somewhere (within the Game Files from the Game itself ???).
* Dump the Save File and edit the "Parameters" (PARAM.SFO ???) so ''CUSAFF7'''D1''''' gets into ''CUSAFF7'''D2'''''.
* Dump the Save File and edit the "Parameters" (PARAM.SFO ???) so ''CUSAFF7'''D1''''' gets into ''CUSAFF7'''D2'''''.
Line 385: Line 385:
* Start the new FPKG created and it should recognize your Save File and load the Game from the beginning of Disc 2
* Start the new FPKG created and it should recognize your Save File and load the Game from the beginning of Disc 2
* Do the same process for every other additional Disc.
* Do the same process for every other additional Disc.
=== Alternative solution - Disc Merge ===
Alternatively ps1 discs can be merged into single bin/cue. There could be potential limitations in file size because MM:SS:FF can only go up to 99:99:99 which translates to around 870MB. For sure this will be problem for games with CDDA tracks. For now there is no confirmation that this limit apply to data only games. How hard is disc merging depends highly on game we want to use. Parasite Eve is one of easiest games to do that since second disc check is triggered only if files from disc 2 are not present on current disc, which they are since discs are merged. Game also use the same EXE and PE file on both discs, and do not use lba based tables. So merging discs is literally repacking them into single disc. But different games use different approaches, games like MGS need additional patches to few files to skip shell open checks, and lba adjustments. For now Chinese Parasite Eve fan translation is only confirmed game that works (thx 苏宇 for playing whole game to test it).
==Memory mapping==
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;"
! Offset From !! Offset To !! Name !! Memory Name (PS4)
|-
| 0x200000000 || 0x208000000  ||  R3000 Memory || HeapDirectMem[0]
|-
|}
==Converting psx cheats for the ps4==
'''Psx cheats into a shn'''
<pre>
Only tested in Syphon filter's emulator
1. Get an offset    [You can get them from Gamehacking.org / Duckstation / Epsxe]
2. Remove the first 2 numbers from the offset
3. Increase the offset by 0xEB2A0 using a hex calculator and add it to your shn
</pre>
'''For ps4cheater'''
<pre>
Only tested in Syphon filter's emulator
1. Get an offset    [You can get them from Gamehacking.org / Duckstation / Epsxe]
2. Remove the first 2 numbers from the offset
3. Increase the offset by 0x2000EB2A0 using a hex calculator and use it in ps4 cheater
</pre>
===PC register script (Syphon Filter 1)===
<br>For the usage in PS4cheater.
<br>'''PSX.cht'''
<pre>
1.5|eboot.bin|ID:|VER:|FM:505
simple pointer|pointer|4 bytes|@A3A2B0_2_3A2B0+C4|data|4 bytes|2147848120|0|PC|
</pre>
===PC register script (Syphon Filter 3)===
<pre>
1.5|eboot.bin|ID:|VER:01.00|FM:505
simple pointer|pointer|4 bytes|@A51220_2_51220+C4|data|4 bytes|2147752604|0|RA|
simple pointer|pointer|4 bytes|@A51220_2_51220+D4|data|4 bytes|2147825396|0|PC|
</pre>
==TOC file layout==
For multi bin images, probably require emu from ps plus.
<br>
Track entry structure:
{| class="wikitable"
|-
! Entry Nº !! Offset !! Length !! Name !! Example !! Notes
|-
| rowspan="10" style="background-color:#DDDDDD;" | 1 || 0x00 || 0x01 (1 byte) || '''TYPE''' || 0x41/0x01 || entry flags
|-
| 0x01 || 0x01 (1 byte) || '''TNO''' || 00 || Track number, usually 00, bcd
|-
| 0x02 || 0x01 (1 byte) || '''POINT''' || 0xA0/0xA1/0xA2/0x01/0x02/0x03/etc || bcd + special case A0-A2.
|-
| 0x03 || 0x01 (1 byte) || '''MIN''' || varies || absolute, bcd
|-
| 0x04 || 0x01 (1 byte) || '''SEC''' || varies || absolute, bcd
|-
| 0x05 || 0x01 (1 byte) || '''FRAME''' || varies || absolute, bcd
|-
| 0x06 || 0x01 (1 byte) || '''ZERO''' || 00  || always zero
|-
| 0x07 || 0x01 (1 byte) || '''PMIN''' || varies || bcd
|-
| 0x08 || 0x01 (1 byte) || '''PSEC''' || varies || bcd
|-
| 0x09 || 0x01 (1 byte) || '''PFRAME''' || varies || bcd
|-
| style="background-color:#DDDDDD;" | Up to 102 || || || || || same structure than the previous entry
|}
POINT indicates successive track numbers, and PMIN, PSEC and PFRAME indicate the starting time of that track.<br>
POINT = A0, PMIN gives the physical track number of the first piece of data (PSEC and PFRAME are zero).<br>
POINT = A1, PMIN indicates the last track on the disc<br>
POINT = A2, the starting point of the lead-out track is given in PMIN, PSEC and PFRAME.<br>
POINT = 01 - 99 Index number within track.<br>
POINT = 00, Pause (2sec?, Also pregap?)
== Folder/File layout ==
Example: Medievil internal emulator, standalone pkg can differ.
<pre>
├──assets
│  ├──common
│  │  ├──gamespec
│  │  │  └──icon.png
│  │  ├──localization
│  │  │  ├──ar-AR.json
│  │  │  ├──cs-CZ.json
│  │  │  ├──da-DK.json
│  │  │  ├──de-DE.json
│  │  │  ├──el-GR.json
│  │  │  ├──en-GB.json
│  │  │  ├──en-US.json
│  │  │  ├──es-ES.json
│  │  │  ├──es-MX.json
│  │  │  ├──fi-FI.json
│  │  │  ├──fr-CA.json
│  │  │  ├──fr-FR.json
│  │  │  ├──hu-HU.json
│  │  │  ├──id-ID.json
│  │  │  ├──it-IT.json
│  │  │  ├──ja-JP.json
│  │  │  ├──ko-KR.json
│  │  │  ├──nl-NL.json
│  │  │  ├──no-NO.json
│  │  │  ├──pl-PL.json
│  │  │  ├──pt-BR.json
│  │  │  ├──pt-PT.json
│  │  │  ├──ro-RO.json
│  │  │  ├──ru-RU.json
│  │  │  ├──sv-SE.json
│  │  │  ├──th-TH.json
│  │  │  ├──tr-TR.json
│  │  │  ├──uk-UA.json
│  │  │  ├──vi-VN.json
│  │  │  ├──zh-CHS.json
│  │  │  └──zh-CHT.json
│  │  ├──msdf
│  │  │  └──icon.png
│  │  ├──SFX
│  │  │  ├──Browse.ogg
│  │  │  ├──BROWSE_DOWN.ogg
│  │  │  ├──Browse_UP.ogg
│  │  │  ├──CloseWindow.ogg
│  │  │  ├──CloseWindow2.ogg
│  │  │  ├──OpenWindow.ogg
│  │  │  ├──OpenWindow2.ogg
│  │  │  ├──Slider.ogg
│  │  │  ├──TimelineSlideDown.ogg
│  │  │  └──TimelineSlideUp.ogg
│  │  │
│  │  ├──arrow_left.png
│  │  ├──arrow_right.png
│  │  ├──checkmark.png
│  │  ├──consola.ttf
│  │  ├──DPad-Down.png
│  │  ├──DPad-Left.png
│  │  ├──DPad-Right.png
│  │  ├──DPad-UP.png
│  │  ├──forbidden.png
│  │  ├──fpd.png
│  │  ├──L1.png
│  │  ├──L2.png
│  │  ├──R1.png
│  │  ├──R2.png
│  │  ├──select.png
│  │  ├──start.png
│  │  ├──start_select_controls_embedded_ps4.png
│  │  ├──start_select_controls_embedded_ps5.png
│  │  ├──start_select_controls_ps4.png
│  │  ├──start_select_controls_ps5.png
│  │  ├──Touchpad.png
│  │  ├──Touchpad_left.png
│  │  ├──Touchpad_right.png
│  │  ├──ui_ps_circle.png
│  │  ├──ui_ps_cross.png
│  │  ├──ui_ps_dpad_left.png
│  │  ├──ui_ps_dpad_right.png
│  │  ├──ui_ps_l1.png
│  │  ├──ui_ps_r1.png
│  │  ├──ui_ps_square.png
│  │  ├──ui_ps_touchpad.png
│  │  └──ui_ps_triangle.png
│  │
│  └──PS1HD
│      └──bios
│          ├── SCPH5500.bin
│          ├── SCPH5501.bin
│          └── SCPH5502.bin
├──conf
│  └── PS1HD
│        ├── dev-pc.conf
│        ├── dev-ps4.conf
│        ├── dev-ps5.conf
│        ├── package-pc.conf
│        ├── package-ps4.conf
│        └── package-ps5.conf
├──data
│  ├── image.toc
│  └── image.bin
├──global
│  ├──presets
│  │  ├── Default.json
│  │  ├── Modern.json
│  │  ├── RetroClassic.json
│  │  └── RetroModern.json
│  └──scripts
│      └──lua_include
│          ├── disc-selection.lua
│          └── sce-locale.lua
├──sce_module
│  ├── libc.prx
│  ├── libSceFios2.prx
│  └── libSceNpToolkit2.prx
├──sce_sys
│  ├── icon0.png
│  ├── pic0.png
│  ├── pic1.png
│  ├── save_data.png
│  └── param.sfo
├──scripts
│  ├── discswap.lua
│  ├── speedup.lua
│  ├── trophies.lua
│  ├── patches.lua
│  └── XXXXYYYYY.lua
├──SIEA
│  ├── config-region.txt
│  ├── config-region.json
│  ├── regional_icon.png
│  └── app_boot.lua
├──config-title.txt
├──eboot.bin
├──revision.conf
</pre>
== Emulator patches ==
=== Syphon Filter 3 emu ===
Emu build from 2023-Feb-17
=== The Legend Of Dragoon emu ===
Emu build from 2023-Feb-21
==== Remove dithering ====
Universal dithering removal patch, works with every single game. PS1 cheats/patches are no longer required to disable dither pattern. To apply unself self file, edit, and sign it again after that. Alternatively you can use cheat engine, offset need to be adjusted to emu base then.<br>
''Replaces *and ecx, 7FFh* with *and ecx, 5FFh* to always remove dither enable bit on E1 write.''
*Emu memory offset: 0x50EA2
*Elf memory offset: 0x54EA2
Original bytes:
81 E1 FF 07 00 00
Replace to:
81 E1 FF 05 00 00


== Links ==
== Links ==
* https://www.psdevwiki.com/ps4/Talk:PS1_Classics_Emulator_Compatibility_List
* https://www.psx-place.com/threads/psx-fpkg-0-2-by-jabu-new-tool-to-convert-ps1-games-for-ps4.30498/
* https://www.psx-place.com/threads/psx-fpkg-0-2-by-jabu-new-tool-to-convert-ps1-games-for-ps4.30498/
* https://twitter.com/Vitt0x_Lar_YT/status/1284239865027198976
* https://twitter.com/Vitt0x_Lar_YT/status/1284239865027198976
* https://github.com/Zcor3x/Ps1HDemu-for-Playstation-4
* https://github.com/Zcor3x/Ps1HDemu-for-Playstation-4
* https://www.youtube.com/watch?v=04EY7huZq9M
* https://www.youtube.com/watch?v=04EY7huZq9M
* For getting cheats: https://gamehacking.org/system/psx
 
* https://github.com/Goatman13/Cue2toc
* https://forums.pcsx2.net/Thread-PSOne-Dithering-OFF-patches
* https://ps1hd.pages.dev
{{Reverse Engineering}}
{{Reverse Engineering}}
<noinclude>
<noinclude>[[Category:Main]]</noinclude>
[[Category:Main]]
</noinclude>
Please note that all contributions to PS4 Developer wiki are considered to be released under the GNU Free Documentation License 1.2 (see PS4 Developer wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:

Cancel Editing help (opens in new window)