Editing PS1 Emulation
Jump to navigation
Jump to search
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 1: | Line 1: | ||
== | == Description == | ||
Playstation 1 emulator called internally ps1hd. Emulation on PS4 is handled differently comparing to PS3. Each PS1 game PS4 package file (.pkg) include emulator itself, so there is no included emulator in PS4 firmware. | |||
Fact that emulator is now included in game pkg, is slightly complicating providing [[PS1_Classics_Emulator_Compatibility_List|compatibility list]], as emulators include some per title patches, and different default settings. | |||
Next difference is that BIOS/ROM in external file is included in .pkg, emu need different region bios for different region titles. This time bios is not any special version, standard SCPH-550X is used. | |||
PS1 Emulator supports LUA scripting by "Lua Bridge", is powerful interface that provide many possibilities to improve compatibility. | |||
Memory card is created at first run of emulator, so you don't need to include one in pkg. | |||
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-emu-ps4.txt === | |||
=== 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;" | ||
! 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 | ||
|- | |||
| --state-restore|| || || | |||
|- | |- | ||
| --wait|| || || | | --wait|| || || | ||
|- | |- | ||
| --bios|| path || Need to match region of game, relative to sandbox root || --bios= | | --mcd0|| || || | ||
|- | |||
| --bios|| path || Need to match region of game, relative to sandbox root || --bios="BIOS/SCPH5502.bin" | |||
|- | |||
| --mcd1|| || || | |||
|- | |- | ||
| --configpath|| || || | | --configpath|| || || | ||
Line 146: | Line 87: | ||
| --texrecent|| true , false || Optimize texture hashes Leading To better Performance || --texrecent=true | | --texrecent|| true , false || Optimize texture hashes Leading To better Performance || --texrecent=true | ||
|- | |- | ||
| | |} | ||
=== patches.lua === | |||
Lua patches are split between 2 categories R3K (r3000 mips), and EM (emulator). Called by getXXXObject. Only exception from that is apiRequest. | |||
====Apirequest==== | |||
{| cellspacing="0" cellpadding="2" border="1" class="wikitable" style="text-align: center;" | |||
! Command !! Usage !! Notes | |||
| | |||
|- | |- | ||
| | | apiRequest || apiRequest(<api version>) || example: apiRequest(0.1) | ||
Different emu versions support different highest api. Medievil emu support api up to 1.0 | |||
Calling api is mandatory. | |||
|- | |- | ||
|} | |} | ||
====R3000 Commands==== | |||
==== R3000 | |||
{| 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 | ! Command !! Usage !! Notes | ||
|- | |||
|r3kObject || local r3kobj = getr3kObject() || | |||
|- | |- | ||
|GetPC || | |GetPC || r3kobj.GetPC() || Return current Program counter. | ||
|- | |- | ||
|SetPC || | |SetPC || r3kobj.SetPC(address) || Set current Program counter to address. | ||
|- | |- | ||
|GetHi || | |GetHi || r3kobj.GetHi || Return Hi register value. | ||
|- | |- | ||
|SetHi || | |SetHi || r3kobj.SetHi(value) || Set Hi register value. | ||
|- | |- | ||
|GetLo || | |GetLo || r3kobj.GetLo || Return Lo register value. | ||
|- | |- | ||
|SetLo || | |SetLo || r3kobj.SetLo(value) || Set Lo register value. | ||
|- | |- | ||
|GetGpr || | |GetGpr || r3kobj.GetGpr(reg) || Return register value, require formatting like here: r3k.GetGpr(gpr.a0). | ||
|- | |- | ||
|SetGpr || | |SetGpr || r3kobj.SetGpr(reg, value) || Set register value, require formatting like here: r3k.GetGpr(gpr.a0, value). | ||
|- | |- | ||
|ReadMem8 || | |ReadMem8 || r3kobj.ReadMem8(address) || Read/return byte from address. | ||
|- | |- | ||
|ReadMem16 || | |ReadMem16 || r3kobj.ReadMem16(address) || Read/return half from address. | ||
|- | |- | ||
|ReadMem32 || | |ReadMem32 || r3kobj.ReadMem32(address) || Read/return word from address. | ||
|- | |- | ||
|ReadMemFloat || | |ReadMemFloat || r3kobj.ReadMemFloat(address) || Read/return float from address. | ||
|- | |- | ||
|ReadMemStr || | |ReadMemStr || r3kobj.ReadMemStr(address) || Read/return string from address. | ||
|- | |- | ||
|WriteMem8 || | |WriteMem8 || r3kobj.WriteMem8(address, value) || Write/set selected memory as byte to value. | ||
|- | |- | ||
|WriteMem16 || | |WriteMem16 || r3kobj.WriteMem16(address, value) || Write/set selected memory as half to value. | ||
|- | |- | ||
|WriteMem32 || | |WriteMem32 || r3kobj.WriteMem32(address, value) || Write/set selected memory as word to value. | ||
|- | |- | ||
|WriteMemFloat || | |WriteMemFloat || r3kobj.WriteMemFloat(address, value) || Write/set selected memory as float to value. | ||
|- | |- | ||
|WriteMemStr || | |WriteMemStr || r3kobj.WriteMemStr(address, value) || Write/set selected memory as string to value. | ||
|- | |- | ||
|WriteMemStrZ || | |WriteMemStrZ || r3kobj.WriteMemStrZ(address, value) || | ||
|- | |- | ||
|AddHook || | |AddHook || r3kobj.AddHook(address, original opcode, function/hook) || Add hook into mips code. | ||
|- | |- | ||
|RemoveHook|| | |RemoveHook|| r3kobj.RemoveHook(?) || Remove hook from mips code. | ||
|- | |- | ||
|InsnReplace || | |InsnReplace || r3kobj.InsnReplace(address, original opcode, replace opcode) || similar to pcsx2 pnach, but additionally use original opcode as a check. | ||
|- | |- | ||
|FuncReplace || | |FuncReplace || r3kobj.FuncReplace(address, original opcode, function name) || Hook/replace function in mips code with predefinied one. | ||
|- | |- | ||
|BurnCycles || | |BurnCycles || r3kobj.BurnCycles()|| | ||
|- | |- | ||
|FlushCache || | |FlushCache || r3kobj.FlushCache() || Flush mips instruction cache. | ||
|- | |- | ||
|} | |} | ||
==== Emulator | ====Emulator 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 | ! Command !! Usage !! Notes | ||
|- | |- | ||
| | | getEmuObject || local emuobj = getEmuObject() || | ||
|- | |- | ||
| | |PadRead || emuobj.PadRead() || Return pad state (pushed buttons). | ||
|- | |- | ||
| | |PadReadLeftStick || emuobj.PadReadLeftStick() || Return pad left stick state. | ||
|- | |- | ||
| | |PadReadRightStick || emuobj.PadReadRightStick() || Return pad right stick state. | ||
|- | |- | ||
| | |PadSetButtonsMode || emuobj.PadSetButtonMode(value) || Set some pad mode, in one of official configs described as "switch Select/Start -> Touchpad/Options mode" with used value 2. | ||
|- | |- | ||
| | |AddVsyncHook || emuobj.AddVsyncHook(anything) || Add hook that trigger on every vsync, param usually will be previously prepared function. | ||
|- | |- | ||
| | |RemoveVsyncHook|| emuobj.RemoveVsyncHook()|| Remove hook that trigger on every vsync. | ||
|- | |- | ||
| | |ThrottleMax || emuobj.ThrottleMax() || Remove framelimiter, used frequently for loadings. | ||
|- | |- | ||
| | |ThrottleNormal || emuobj.ThrottleNormal() || Set framelimiter to default game value. | ||
|- | |- | ||
| | |Log || emuobj.Log(value) || Print debug messages to usermode console, ex. emu.Log(string.format("Overlay: %02x", overlay)). | ||
|- | |- | ||
| | |GetNativeLanguage|| emuobj.GetNativeLanguage() || Return used PS4 language. | ||
|- | |- | ||
| | |LoadConfig||emuobj.LoadConfig() || | ||
|- | |- | ||
| | |SaveConfig||emuobj.SaveConfig() || | ||
|- | |- | ||
| | |LoadState|| emuobj.LoadState()|| Load savestate, seems to be disabled in Medievil emu. | ||
|- | |- | ||
| | |SaveState||emuobj.SaveState() || Save savestate, seems to be disabled in Medievil emu. | ||
|- | |- | ||
| | |PostEffect|| emuobj.PostEffect() || | ||
|- | |- | ||
| | |PostEffectParams|| emuobj.PostEffectParams()|| | ||
|- | |- | ||
| | |NeoMode|| emuobj.NeoMode() || Return 1 if PS4 PRO, 0 otherwise. | ||
|- | |- | ||
| | |CRC32 || || | ||
|- | |- | ||
| | |AddFBMapping|| emuobj.AddFBMapping( , , , ) || Add framebffer mapping, in Medievil used with emuobj.AddFBMapping(768, 256, 180, 256) values. | ||
|- | |- | ||
| | |RemoveFBMapping|| emuobj.RemoveFBMapping( , ) || Remove framebffer mapping, in Medievil used with emuobj.RemoveFBMapping(768, 256) values. | ||
|- | |- | ||
| | |Launch || emuobj.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. | ||
|- | |- | ||
|} | |} | ||
== 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 [http://wiki.redump.org/index.php?title=PlayStation_1:_LibCrypt_protection_(Old) cause issues for emulators.] | ||
===List=== | |||
=== List === | |||
* Actua Ice Hockey 2 (Europe) | * Actua Ice Hockey 2 (Europe) | ||
Line 403: | Line 317: | ||
* 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) | ||
* 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. | |||
The exact effects of libcrypt depend on the game. However, they usually render the game unplayable in some form. Here is list of libcrypt-caused issues known to the community. Be sure to patch these games before creating a pkg, or try to fix them by using the --libcrypt command in the | Here is list of libcrypt-caused issues known to the community. | ||
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 451: | Line 365: | ||
|Vagrant Story (PAL) || | |Vagrant Story (PAL) || | ||
Will hang on the "now loading"-screen, after choosing "new game" on the main menu. | Will hang on the "now loading"-screen, after choosing "new game" on the main menu. | ||
|- | |- | ||
|Wip3out (PAL) || | |Wip3out (PAL) || | ||
Line 460: | Line 371: | ||
|} | |} | ||
* Libcrypt | * Libcrypt info mostly taken from: https://github.com/Kippykip/SBITools#libcrypt-failed-check-causes-and-effects | ||
== Multi-Disc support == | == Multi-Disc support == | ||
This needs more [[User talk:139.47.102.134|testing]] but in theory it should work as follows. | This needs more [[User talk:139.47.102.134|testing]] but in theory it should work as follows. | ||
=== On Real PS1 Hardware, PS2, PSP, | === On Real PS1 Hardware, PS2, PSP, PSV, PS3 === | ||
Example Game: '''Final Fantasy VII''' containing 3 Discs: | Example Game: '''Final Fantasy VII''' containing 3 Discs: | ||
* Before the Game asks you to change Discs, it will ask you if you wish to save the Game. | * Before the Game asks you to change Discs, it will ask you if you wish to save the Game. | ||
Line 479: | Line 388: | ||
=== So how to do this on a PS4? === | === So how to do this on a PS4? === | ||
Since as mentioned [[PS1 Emulation#Description|above]] the problematic we have is that every PKG contains not only the Game as an Image-File, but also the [[PS1 Emulation|Emulator]] and a Save File itself. So a workaround is needed: | Since as mentioned [[PS1 Emulation#Description|above]] the problematic we have is that every PKG contains not only the Game as an Image-File, but also the [[PS1 Emulation|Emulator]] and a Save File itself. So a workaround is needed: | ||
* 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'''). | ||
Line 489: | Line 397: | ||
* 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. | ||
==Converting psx cheats for the ps4== | |||
'''Psx cheats into a shn''' | |||
== Converting | |||
''' | |||
<pre> | <pre> | ||
Only tested in Syphon | Only tested in Syphon filter's emulator | ||
1. Get an offset | 1. Get an offset from Gamehacking.org Example: 0x80060000 | ||
2. Remove the first | 2. Remove the first number from the offset 0x0060000 | ||
3. Increase the offset by 0xEB2A0 using a hex calculator and add it to your shn | 3. Increase the offset by 0xEB2A0 using a hex calculator and add it to your shn 0x14B2A0 | ||
</pre> | </pre> | ||
'''For ps4cheater''' | '''For ps4cheater''' | ||
<pre> | <pre> | ||
Only tested in Syphon filter's emulator | Only tested in Syphon filter's emulator | ||
1. Get an offset | 1. Get an offset from Gamehacking.org Example: 0x80060000 | ||
2. Remove the first number from the offset 0x0060000 | |||
3. Increase the offset by 0x2000EB2A0 using a hex calculator and use it in ps4 cheater 0x20014B2A0 | |||
</pre> | </pre> | ||
== | == Links == | ||
* 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 | ||
Line 756: | Line 426: | ||
* https://www.youtube.com/watch?v=04EY7huZq9M | * https://www.youtube.com/watch?v=04EY7huZq9M | ||
* For getting cheats: https://gamehacking.org/system/psx | * For getting cheats: https://gamehacking.org/system/psx | ||
{{Reverse Engineering}} | {{Reverse Engineering}} | ||
<noinclude> | <noinclude>[[Category:Main]]</noinclude> | ||
[[Category:Main]] | |||
</noinclude> |