Talk:PSP Emulator Compatibility List: Difference between revisions

From PS4 Developer wiki
Jump to navigation Jump to search
(Created page with "=Jeanne D'Arc= <pre> # # A user thread receives a fatal signal # # signal: 11 (SIGSEGV) # thread ID: 100865 # thread name: emu # proc ID: 63 # proc name: eboot.bin # reason:...")
 
 
(45 intermediate revisions by 5 users not shown)
Line 1: Line 1:
=Jeanne D'Arc=
=General=
==Custom PSPemu Configuration Files ==


<pre>
<pre>
#
Configuration files created by users to improve PSP emulator compatibility on PS4.
# A user thread receives a fatal signal
</pre>
#
===God Of War - Ghost Of Sparta===
# signal: 11 (SIGSEGV)
'''config-title.txt'''
# thread ID: 100865
<br>UCUS98737
# thread name: emu
<pre>
# proc ID: 63
--antialias=off
# proc name: eboot.bin
--godofwarhack=true
# reason: page fault (user read data, page not present)
--forcenobilinear=true
# fault address: 0000001000000000
</pre>
#
'''LUA'''
# registers:
<br>UCUS98732
# rax: 0000000000000000 rbx: 0000000200878fe0
<pre>
# rcx: 0000001000000000 rdx: 00000002ed84efc0
local axObj = getAXObject()
# rsi: 0000000000000000 rdi: 00000002ed84eca0
local emuObj = getEmuObject()
# rbp: 00000007ef94b960 rsp: 00000007ef94b8e0
 
# r8 : 0000000000000001  r9 : 00000000000002d0
local patcher = function()
# r10: 0000000000000000  r11: 000000004a81c060
 
# r12: 0000000008911278  r13: 00000000000001c0
axObj.WriteMem32(0x08A15210,0x24020000)
# r14: 0000000000000009  r15: 00000002ed84eca0
end
# rip: 000000004a5f21ed  eflags: 00010287
 
# BrF: 000000004a5f0fcd  BrT: 000000004a5f2180
emuObj.AddVsyncHook(patcher)
#
</pre>
# backtrace:
<pre>
copyin: emu has nonsleeping lock
PPSSPP
# 000000004a5dc229
0881681C
# 000000004a4d1c54
</pre>
# 000000004a4cffcb
 
# 000000004a4c9975
===God of War: Chains of Olympus===
# 000000004a6da428
'''config-title.txt'''
# 000000004a6b4759
<br>UCUS98653
# 000000004a6afa17
<pre>
# 000000004a67fea8
--texclutmode=filter
# 000000004a6dff73
--bend-30hz-lock=1
# 00000008142a2d44
--godofwarhack=true
# 0000000000000000
</pre>
#
 
# dynamic libraries:
===Dante's Inferno===
# /app0/eboot.bin
'''config-title.txt'''
<br>ULUS10469
<pre>
--antialias=off
--texloadcores=48
--texclutmode=full
--vramcopyback=12
--locorocomeshsmooth=true
--texrecent=true
--umddelay=true
--depthscalehack=true
--forcenobilinear=true
--smoothlevel=0
</pre>
'''LUA'''
<br>UCUS98732
<pre>
-- Dantes Inferno
 
apiRequest(1.0) -- request version 1.0 API. Calling apiRequest() is mandatory.
 
local emuObj = getEmuObject() -- emulator
local axObj = getAXObject() -- allegrex
 
local patcher = function()
 
--30 FPS
local code_check1 = axObj.ReadMem16(0x001C239C)
 
local code_check2 = axObj.ReadMem16(0x103E4B40)
 
if code_check1 == 0x0064 and code_check2 == 0x001E then
 
 
axObj.WriteMem32(0x203E4B40,0x0000001E)
axObj.WriteMem32(0x20022EE4,0x3D088889) --1/30 = 0.03333
 
end
 
end
 
emuObj.AddVsyncHook(patcher)
</pre>
 
===Tekken 6===
'''config-title.txt'''
<br>ULUS10466
<pre>
--has-shown-start-select-help=0
--userui-settings-graphics=1
--globalgamedata-dir=global
--bend-30hz-lock=0
--replacementfilter=true
--depthscalehack=true
--texcachemode=patchworkheroes
--texloadcores=16
--present=vblankstart
--texclutmode=full
--texrecent=true
--force-dsf-present=1
--gputhread=true
--gpu-renderthread=20
--force-triangle-clip-off=true
--umddelay=true
 
# Emu used = Syphon Filter Dark Mirror
</pre>
 
===Soulcalibur: Broken Destiny===
'''config-title.txt'''
<br>ULUS10457
<pre>
--has-shown-start-select-help=0
--userui-settings-graphics=1
--globalgamedata-dir=global
--trophies=0
--umddelay=true
--bend-30hz-lock=0
--present=setframebuf #,setframebuf,drawsync
--texclutmode=filter  #,full
--texloadmode=launch  #ondemand_lz4
--depthscalehack=true
--texloadcores=8
--texrecent=true  #async, lastused
 
# Emu used = Syphon Filter Dark Mirror
</pre>
</pre>


r12: 0000000008911278 - sceAudioOutputBlocking
===Miami Vice: The Game===
'''config-title.txt'''
<br>ULUS10109
<pre>
--antialias=off
--texclutmode=full
--texloadcores=12
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true
--smoothlevel=0
</pre>
 
===Wild Arms XF===
'''config-title.txt'''
<br>ULUS10339
<pre>
--title-id=ULUS10339
--has-shown-start-select-help=0
--vms=/temp0/vms
--ms0=/temp0/ms0
--multisaves=true
--notrophies=true
 
--antialias="off" #ssaa4x off msaa4x
--texcachemode=rondo #drawbounds,drawboundsloco,patchworkheroes,locoroco2,rondo
--texloadcores=10
--present=drawsync
--gputhread=true
--texrecent=true
--texclutmode=full
</pre>
 
===Burnout Dominator===
'''config-title.txt'''
<br>ULUS10236
<pre>
---title-id=ULUS10236
--multisaves=true
--notrophies=true
--vms=/temp0/vms
--has-shown-start-select-help=1
--antialias="off"
--texclutmode=full
--texloadcores=12
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true
</pre>
'''ULUS10236_patches.lua'''
<br>ULUS10236
<pre>
-- Burnout Dominator
-- lua by Stayhye
 
apiRequest(1.0)  -- request version 1.0 API. Calling apiRequest() is mandatory.
 
local emuObj  = getEmuObject() -- emulator
local axObj  = getAXObject() -- allegrex
 
local patcher = function()
--30 FPS V.2 [Default]
local code_check1 = axObj.ReadMem16(0x02574C)
if code_check1 == 0x0000 then
axObj.WriteMem32(0x2002574C,0x14A0001A)
axObj.WriteMem32(0x201A0358,0xE60C0034)
axObj.WriteMem32(0x204F08BC,0x3D088888)
axObj.WriteMem32(0x2019AE90,0x3C043F80)
end
--[[
--60 FPS V.2
local code_check2 = axObj.ReadMem16(0x02574C)
if code_check2 == 0x001A then
axObj.WriteMem32(0x2002574C, 0x00000000)
axObj.WriteMem32(0x201A0358, 0x00000000)
axObj.WriteMem32(0x204F08BC, 0x3C888888)
axObj.WriteMem32(0x2019AE90, 0x3C043F00)
end
--]]
end
 
emuObj.AddVsyncHook(patcher)
 
emuObj.SetTextureHashMode("patchworkheroes")
</pre>
 
===Tom Clancy's Ghost Recon Advanced Warfighter 2===
'''config-title.txt'''
<br>ULUS10237
<pre>
# Ghost Recon: Advanced Warfighter 2 (all regions)
 
--has-shown-start-select-help=1
 
--antialias=off
 
--texclutmode=full
 
--bend-30hz-lock=0
 
--texloadcores=12
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true
--smoothlevel=0
 
--forcenobilinear=true
 
--active-sku="ULUS10237"
--title-id=ULUS10237
 
--psp-right-stick-action=1
--psp-right-stick-deadzone-x=15
--psp-right-stick-deadzone-y=15
--psp-right-stick-deadzone-semicircle-arc=40
 
#  Emu used = Syphon Filter Dark Mirror
</pre>
 
===Call of Duty: Roads to Victory===
'''config-title.txt'''
<br>ULES00643
<pre>
# Call of Duty: Roads to Victory (all regions)
 
--has-shown-start-select-help=1
 
--bend-30hz-lock=0
 
--antialias=off
--texclutmode=full
--texloadcores=12
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true
 
--forcenobilinear=true
 
--active-sku="ULES00643"
--title-id=ULES00643
 
--psp-right-stick-action=1
--psp-right-stick-deadzone-x=15
--psp-right-stick-deadzone-y=15
--psp-right-stick-deadzone-semicircle-arc=40
 
--app-volume=0.8
 
#  Emu used = Syphon Filter Dark Mirror
</pre>
 
===SpongeBob's Truth or Square===
'''config-title.txt'''
<br>ULUS10478
<pre>
# SpongeBob's Truth or Square (all regions)
 
--has-shown-start-select-help=1
--bend-30hz-lock=1
 
--force-dsf-present=1
 
--forcenobilinear=true
--depthscalehack=true
 
--active-sku="ULUS10478"
--title-id=ULUS10478
 
--antialias=off
--texloadcores=48
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true
--smoothlevel=0
--texclutmode=full 
--vramcopyback=12
--locorocomeshsmooth=true
--gpu-renderthread=20
 
# following settings are machine-generated
--region-dir=SIEA
--ps4-trophies=0
--ps5-uds=0
--trophies=0
 
--globalgamedata-dir=global
 
# Emu used = Syphon Filter Dark Mirror
</pre>
 
===Harvest Moon Hero of Leaf Valley===
'''config-title.txt'''
<br>ULUS10458
<pre>
# Harvest Moon Hero of Leaf Valley (all regions)
 
--has-shown-start-select-help=1
 
--bend-30hz-lock=0
--force-dsf-present=1
--depthscalehack=true
 
--gpu-renderthread=20
--antialias="msaa4x"
--anisolevel=4
 
--texclutmode=full
--texloadcores=48
--texcachemode=patchworkheroes
--present=vblankstart
--texrecent=true
--umddelay=true
--smoothlevel=0
--locorocomeshsmooth=true
 
--active-sku="ULUS10458"
--title-id=ULUS10458
 
# following settings are machine-generated
--region-dir=SIEA
--ps4-trophies=0
--ps5-uds=0
--trophies=0
 
--globalgamedata-dir=global
 
# Emu used = Syphon Filter Dark Mirror
</pre>
 
===Gurumin: A Monstrous Adventure===
'''config-title.txt'''
<br>ULUS10228
<pre>
# Gurumin: A Monstrous Adventure (all regions)
 
--image="data/USER_L0.IMG"
--title-id=ULUS10228
 
--gpu-renderthread=0
 
--antialias=ssaa4x
--texclutmode=full
--smoothlevel=0
--texcachemode=patchworkheroes
--present=vblankstart
 
--texrecent=true
--umddelay=true
--gputhread=true
 
--vramcopyback=45
--texloadcores=48
 
--locorocomeshsmooth=true
--depthscalehack=true
 
--multisaves=true
--notrophies=true
 
# Emu used = Ridge Racer 2
</pre>
 
==Incomplete configurations==
<pre>This is a list of configurations that were unsuccessful or were never completed, or information that might help people in the future.
A place for research and sharing useful info.</pre>
===Crash Tag Team Racing===
'''LUA'''
<br>ULUS10044
<pre>
Reaches 0x8A7292C jal zz_sceKernelLoadModule
Similarly to YU-GI-OH! 5D's Tag Force 4, and then crashes after 2 instructions.
</pre>
 
===YU-GI-OH! 5D's Tag Force 4===
'''LUA'''
<br>ULUS10481
<pre>
local axObj = getAXObject()
local emuObj = getEmuObject()
 
local patcher = function()
 
axObj.WriteMem32(0x8818780,0x10000025)
end
 
emuObj.AddVsyncHook(patcher)
</pre>
 
== Official PSPemu Configuration Files ==
<pre>Configuration files extracted from official packages to improve PSP emulator compatibility on PS4
</pre>
===Syphon Filter: Dark Mirror===
'''config-title.txt'''
<br>UCUS98641
<pre>
# SyphonFilterDarkMirror (all regions)
 
--texclutmode=filter
 
--bend-30hz-lock=1
 
--psp-right-stick-action=1
--psp-right-stick-deadzone-x=15
--psp-right-stick-deadzone-y=15
--psp-right-stick-deadzone-semicircle-arc=40
 
--app-volume=0.8
 
 
# following settings are machine-generated
--region-dir=SIEA
--ps4-trophies=1
--ps5-uds=1
--trophies=1
 
--globalgamedata-dir=global
</pre>
 
'''UCUS98641_patches.lua'''
<pre>
-- Lua 5.3
-- Title: Syphon Filter: Dark Mirror
 
-- Patches for fixing issues with post fx in games using the Syphon Filter/Resistance engine
 
apiRequest(1.0) -- request version 1.0 API. Calling apiRequest() is mandatory.
 
local emuObj = getEmuObject()
local cpu = getAXObject()
 
-- The bloom filter uses 1.5 pixel jitter to make a ghetto blur. When up-ressed, this doesn't look good.
-- To compensate, reduce the jitter amount before rendering.
function BloomJitterPlusAdjust()
-- 1.5 pixel "+" pattern
emuObj.AdjustUVJitter(0, 4, 0.0, 1.5)
emuObj.AdjustUVJitter(4, 4, 0.0, -1.5)
emuObj.AdjustUVJitter(8, 4, 1.5, 0.0)
emuObj.AdjustUVJitter(12, 4, -1.5, 0.0)
end
 
function BloomJitterCrossAdjust()
-- 1.5 pixel "x" pattern
emuObj.AdjustUVJitter(0, 4, 1.5, 1.5)
emuObj.AdjustUVJitter(4, 4, -1.5, 1.5)
emuObj.AdjustUVJitter(8, 4, 1.5, -1.5)
emuObj.AdjustUVJitter(12, 4, -1.5, -1.5)
end
 
local jitterFixPlus = emuObj.AddGPUHook(0x40dc000, 0, 16, 0x40d4000, BloomJitterPlusAdjust)
local jitterFixCross = emuObj.AddGPUHook(0x40d4000, 0, 16, 0x40dc000, BloomJitterCrossAdjust)
 
function depthquery()
local querystruct = 0x8eda968 -- this is always in a fixed location
-- the depth query struct is fixed to 24 entries
-- 0..15 seem to be always used for lights, 16..23 are for npcs
for i=0,23 do
local querytype = cpu.ReadMem32(querystruct+0)
local valid = cpu.ReadMem32(querystruct+1*4)
if valid ~= 0xffffffff then
--local queryx = cpu.ReadMem32(querystruct+2*4)
--local queryy = cpu.ReadMem32(querystruct+3*4)
--local querydepth = cpu.ReadMem32(querystruct+4*4)
--local querywidth = cpu.ReadMem32(querystruct+5*4)
--local queryheight = cpu.ReadMem32(querystruct+6*4)
--local param1c = cpu.ReadMem32(querystruct+7*4)
--local param20 = cpu.ReadMem32(querystruct+8*4)
local param24 = cpu.ReadMem32(querystruct+9*4)
--local result = cpu.ReadMemFloat(querystruct+10*4)
if param24 <= 0 then
cpu.WriteMem32(querystruct+1*4, 0xffffffff) -- to be removed from the list -> mark as invalid
else
if querytype == 3 then -- n x n coverage based occlusion used by lights. Object opacity is set to (visible_samples / total_samples)
cpu.WriteMemFloat(querystruct+10*4, 0.0) -- always hide lights
else -- Enemies use a 5-point (corners + center) occlusion check. Object is visible if any of the points is visible.
cpu.WriteMemFloat(querystruct+10*4, 1.0) -- set always visible
end
end
end
querystruct = querystruct + 0x2c
end
end
 
cpu.AddHook(0x8c163d4, 0x27bdff80, depthquery) -- = addiu sp, sp, -0x80
-- the hook code replaces the occlusion function, so just adjust the stack and return
cpu.InsnReplace(0x8c163d8, 0x34040000, 0x27bd0080) -- addiu sp, sp, 0x80
cpu.InsnReplace(0x8c163dc, 0xafa40048, 0x03e00008) -- jr ra
cpu.InsnReplace(0x8c163e0, 0x3c0408ee, 0x00000000) -- nop
</pre>
===Echochrome===
'''config-title.txt'''
<br>UCES01011
<pre>
# Echochrome (all regions)
 
# following settings are machine-generated
--region-dir=SIEA
--ps4-trophies=0
--ps5-uds=0
--trophies=0
</pre>
 
'''config-region.txt'''
<pre>
--image="data/USER_L0.IMG"
--antialias=SSAA4x
--multisaves=true
--notrophies=true
</pre>
 
'''NPUG80135_patches.lua'''
<pre>
-- Lua 5.3
-- Title: Echochrome  NPUG 80135  (US)
 
--  WBD  5/10/2022 prevent Console Msg about Memory Stick from being displayed
--  WBD  5/22/2022  remove Send and Receive menu options
 
apiRequest(1.0) -- request version 1.0 API. Calling apiRequest() is mandatory.
 
local gpr = require( "ax-gpr-alias" ) -- you can access Allegrex GPR by alias (gpr.a0 / gpr["a0"])
local emuObj = getEmuObject()
local cpu = getAXObject()
 
local hook = 0x88468f0
 
function SkipMsg()
local v1 = cpu.GetGpr(gpr.v1)
local v0 = cpu.GetGpr(gpr.v0)
cpu.SetGpr(gpr.a0, v1)
cpu.SetGpr(gpr.v0, 0)
cpu.WriteMem32(v1+4, v0)
cpu.SetPC(hook+0xc)
print "_NOTE: Skipping Memory Stick Message"
end
cpu.AddHook(hook, 0x00602021, SkipMsg)
 
 
function DisableSendReceive()
cpu.WriteMem32(0x8909940, 0) -- overwrite Send with 0
cpu.WriteMem32(0x890991c, 0) -- overwrite Receive with 0
end
cpu.AddHook(0x8846fb4, 0xae130090, DisableSendReceive)
</pre>
 
===LocoRoco Midnight Carnival===
'''config-title.txt'''
<br>NPEG00024
<pre>
# LocorocoMidnightCarnival (all regions)
 
--ps5-uds=0# following settings are machine-generated
--region-dir=SIEE
--ps4-trophies=0
--ps5-uds=0
--trophies=0
</pre>
'''config-region.txt'''
<pre>
; Windows configuration file for PSPHD
 
; Game Image
--image="data\USER_L0.IMG"
 
; Use this to run the automatic font dumper.
;--boot="host0:../tools/glyphdump.prx"
 
; Uncomment these to play around with font dumping.
;--fontsave="host0:fontdump"
;--fontreplace="host0:fontreplace"
 
; Scaling factor (Windows only - 1: 480x272, 2: 960x544, 3: 1440x816, 4: 1920x1088 ... 8: 3840x2176)
--scale=3
 
; Language selection (Windows only - the PS4 version auto-selects based on the PS4 language setting)
; Switch the PSP language to one of the following:
; "en": English (default)
; "jp": Japanese
; "fr": French
; "es": Spanish
; "de": German
; "it": Italian
; "nl": Dutch
; "pt": Portuguese
; "ru": Russian
; "ko": Korean
; "chs": Chinese Simplified
; "cht": Chinese Traditional
;--lang="en"
 
; Redirect host0: to a another directory (uncomment to enable).
; By default it's mapped to the working directory where the executable starts
;--host="D:\Sony\PSPHD"
 
; To dump the original video in PMF format, uncomment the --dumpvideos line
; For example, with the current setting, it will save them in a "D:\Sony\PSPHD\videos" directory (make sure the directory exists)
;--dumpvideos="host0:videos"
 
; To dump the original audio in Atrac3 format, uncomment the --dumpaudio line
; For example, with the current setting, it will save them in a "D:\Sony\PSPHD\audio" directory (make sure the directory exists)
;--dumpaudio="host0:audio"
 
; To save the in-game textures as the game runs, uncomment the --texsave line
; For example, with the current setting, it will save them in a "D:\Sony\PSPHD\texdump" directory (make sure the directory exists)
;--texsave="host0:texdump"
;--texmissingsave="host0:texdump"
 
; To replace specific textures as the game runs, uncomment the --texreplace line
; For example, with the current setting, it will load them from the "D:\Sony\PSPHD\texreplace" directory
; If the --scale setting is set to 4 or 8, the program will also look for replacement textures on '4x' or '8x' directories within this directory
;--texreplace="host0:texreplace"
 
; This forces alpha blending to on for replaced textures. (uncomment to enable)
; With this we can freely make use of a normal alpha channel on replacement textures
;--replacementalpha=true
 
; This enables bilinear filtering on replaced textures. (uncomment to enable)
;--replacementfilter=true
 
; Antialiasing mode. SSAA4x looks best, MSAA4x only smooths edges.
; Choices: off, SSAA4x, MSAA4x
--antialias=SSAA4x
 
; Allows to switch between replacement and original textures using L3 on the DS4 or the T key.
;--texswitch=true
 
; Turns on the auto-resampler. Assumes textures in texreplace are at 8x resolution and resamples them at load
;--autoresampler=true
 
; Turns on filtering of CLUT hashes to avoid repeat indexed textures
;--texclutmode=filter
 
; Enable Multiple Savegames
--multisaves=true
 
; Custom locoroco2 texture hasher
;--texcachemode="locoroco2"
</pre>
'''NPEG00024_patches.lua'''
<pre>
-- Lua 5.3
-- Title: Locoroco Midnight Carnival NPEG-00024  (EU)
 
--  WBD  5/25/2022 prevent RANKING option from being selected
 
apiRequest(1.0) -- request version 1.0 API. Calling apiRequest() is mandatory.
 
local gpr = require( "ax-gpr-alias" ) -- you can access Allegrex GPR by alias (gpr.a0 / gpr["a0"])
local emuObj = getEmuObject()
local cpu = getAXObject()
 
 
function DisableRanking()
local a2 = cpu.GetGpr(gpr.a2)
local a1 = cpu.GetGpr(gpr.a1)
local check = cpu.ReadMem8(a1+0x2c) -- make sure we're in the correct menu
local ptr = a1+a2+0x34
local new_indx = cpu.ReadMem8(ptr)
if (new_indx == 2) then
if (a2 == 2 and check == 0x2b) then -- moving right
cpu.WriteMem8(ptr, 3)
print "_NOTE: NEW changed to 3"
 
elseif (a2 == 3 and check == 0x3e) then -- moving left
cpu.WriteMem8(ptr, 1)
print "_NOTE: NEW changed to 1"
end
end
end
 
cpu.AddHook(0x8a205c4, 0x00c58821, DisableRanking)
</pre>
 
===Patapon 2===
'''LUA'''
<br>UCUS98732
<pre>
-- Lua 5.3
-- Title:  Patapon 2 PSP - UCUS-98732 (USA)
-- Author:  Ernesto Corvi
 
-- Changelog:
-- v1.1: US only.  Change the word "Paraget" to "Patagate" in two strings.
 
apiRequest(1.0) -- request version 1.0 API. Calling apiRequest() is mandatory.
 
local gpr = require( "ax-gpr-alias" ) -- you can access Allegrex GPR by alias (gpr.a0 / gpr["a0"])
local emuObj = getEmuObject() -- emulator
local axObj = getAXObject() -- allegrex
local pad = require("pad")
 
-- Hook memcpy to catch framebuffer effects
axFuncReplace(0x881D194, "patapon_memcpy")
 
-- Accelerate some functions
axFuncReplace(0x8804670, "__ptmf_scall")
axFuncReplace(0x8892230, "Renderer__makeWorldMatrix__4psysFv")
axFuncReplace(0x88209A8, "patapon_strcmp")
axFuncReplace(0x8815130, "sceGupSetStatus")
axFuncReplace(0x8851D84, "FMtx44__setRow__3PydFv")
axFuncReplace(0x88437F0, "Script__Talk__Controller__setDeltaTime__3PydFv")
axFuncReplace(0x8843B6C, "Script__Talk__Controller__setCmdId__3PydFv")
axFuncReplace(0x88441DC, "Script__Talk__Controller__getArgValuePtr__3PydFv_0")
axFuncReplace(0x89B25B0, "sceGmoCol4Multiply")
axFuncReplace(0x8910A60, "Gfx__CacheModel__getNodeMtx__6SystemFv")
axFuncReplace(0x8911440, "Gfx__StaticGmoModel__getNodeIdx__6SystemFv")
axFuncReplace(0x89114C8, "Gfx__StaticGmoModel__getNodeMtx__6SystemFv")
axFuncReplace(0x891157C, "Gfx__StaticGmoModel__getNodeMtx__6SystemFv_0")
axFuncReplace(0x881462C, "sceGuEnable", 0x8B3C050) -- param = gupbase pointer
axFuncReplace(0x8814684, "sceGuDisable", 0x8B3C050) -- param = gupbase pointer
axFuncReplace(0x89B2D84, "sceGmoFCurveEval_fastpath", 0x89B2D88) -- param = function entry if not fast path
--axFuncReplace(0x88D0788, "Game__Map__Weather__WindLocus__update__4LaboFv_loop", 0x88D0864) -- param = continue address
 
axFuncReplace(0x890FCBC, "convertLowerString__6SystemFv")
axFuncReplace(0x8877104, "convertLowerString__6SystemFv") -- convertLowerString__21@unnamed@BNDFile_cpp@Fv, same functionality
axFuncReplace(0x897927C, "__extendsfdf2")
axFuncReplace(0x8979AF8, "__muldf3")
axFuncReplace(0x8979A8C, "__adddf3")
axFuncReplace(0x897A750, "__truncdfsf2")
axFuncReplace(0x88CBD64, "RemapPacket", 0x8ACC394) -- param comes from RemapPacketAddr24 & RemapPacketAddr16
axFuncReplace(0x890FEA0, "patapon_strcmp") -- strcmpFast__6SystemFv ('fast' strcmp)
 
 
-- Switch Select command to "Options" button.
emuObj.PadSetButtonsMode(pad.BUTTONS_MODE_OPTION_IS_SELECT)
 
-- Remove "Transfer Patapon Saved Data" option from New Game option
--axInsnReplace(0x8A46660, 0x24070002, 0x24070001) -- li  a3,0x2  (change 2 menu options to 1)
emuObj.RemapSavedata("UCUS98711", "CUSA06171", "504e802b04a1838c32b616abbe0b475fbea1c823825ef0df06cc2bad129ce2f7")
 
-- Fix "Tree of Life" unaligned lines and shadows
axObj.AddHook(0x884600C, 0x8c850010, function() -- PSP::Gfx::PrimitiveContext::setVertex2f
local context = axObj.GetGpr(gpr.a0)
local cmdCount = axObj.ReadMem32(context + 0x14)
if (cmdCount & 1) == 1 then -- we have at least 2 commands
local cmdBuffer = axObj.ReadMem32(context + 0x10)
local cx = axObj.GetFpr(12)
local cy = axObj.GetFpr(13)
local ox = axObj.ReadMemFloat(cmdBuffer-12)
local oy = axObj.ReadMemFloat(cmdBuffer-8)
if cx == ox then
axObj.SetFpr(12, cx + 0.5)
axObj.WriteMemFloat(cmdBuffer-12, ox + 0.5)
elseif cy == oy then
axObj.SetFpr(13, cy + 0.5)
axObj.WriteMemFloat(cmdBuffer-8, oy + 0.5)
end
end
end)
 
-- LANGUAGES --
local langCode = "us" -- default
--local languageList = {"Japanese","English","UK","Italian","German","Spanish","French","Korean","Chinese","ns","nf","Dutch","Portuguese","gr","Belgium"}
--local gameLanguageCode = {"jp","us","uk","it","de","sp","fr","kr","cn","ns","nf","nl","pt","gr","be"}
local languageList = {"","English","","","","","","","","Spanish","French","","","",""}
local gameLanguageCode = {"","us","","","","","","","","ns","nf","","","",""}
 
-- US: english = 1, spanish = 9, french = 0xA (from Localize__Manager__setDefaultLangage)
-- EU: uk = 2, italian = 3, german = 4, spanish = 5, french = 6
-- JP: jp = 0
-- HP: ko = 7, ch = 8,
-- GLOBAL FUNCTIONS --
 
local GLOBAL = 0x8B7D088 -- reawakeDeathUnit - offset 0x88A95E8 in $v1
 
function getGlobalAddr() -- gets Global to user data.
-- address comes from: Labo::Bases::Camp::Controller::reawakeDeathUnit - offset 0x88A95E8 in $v1
-- add 0x20 to address to align it with the word "none"
local main = axObj.ReadMem32(GLOBAL) -- fixed Global address from: 0x88A95E8 -> 0x8c9fbc0
if main == 0xFFFFFFFF or main == 0 then
return 0xFFFFFFFF
end
local ptr = axObj.ReadMem32(main + 0x10c0) --> sets to: 0x8d07840
if ptr == 0xFFFFFFFF or ptr == 0 then
return 0xFFFFFFFF
end
 
return ptr
end
 
-- MAIN FUNCTIONS --
 
local H1 = function() -- Labo::Bases::Camp::Scene::updateTips
local v0 = axObj.GetGpr(gpr.v0)
if v0 > 0 then
emuObj.ThrottleMax()
else
emuObj.ThrottleNormal()
end
end
 
local H2 = function() -- GameSystem__SaveDataController__setStateMessage
local ptr = axObj.GetGpr(gpr.a2)
local str = axObj.ReadMemStr16(ptr)
local newStr = "Now loading. Do not turn off the power."
-- english: Now loading./Do not remove the Memory Stick Duo™ /or turn off the system power.
-- spanish: Cargando./No extraigas el Memory Stick Duo™ /ni apagues el sistema.
-- french: Chargement./Ne pas retirer le Memory Stick Duo™ /ou éteindre le système.
-- italian: Caricamento in corso.../Non rimuovere il Memory Stick Duo™ /e non spegnere il sistema.
-- german: Lädt./Bitte den Memory Stick Duo™ nicht entfernen /und das System nicht ausschalten.
-- japanese: システムデータをロード中です。/Memory Stick Duo™を抜き挿ししたり、/電源を切ったりしないでください。
-- chinese: 系統資料載入中。/請勿插拔Memory Stick Duo™/或是關閉主機的電源。
-- korean: 시스템 데이터를 불러오는 중입니다./Memory Stick Duo™를 빼거나/전원을 끄지 마십시오.
if string.find(str, "Now loading") then
newStr = "Now loading." -- English: Now loading./Do not remove the Memory Stick Duo™ /or turn off the system power.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Checking Memory Stick") then
newStr = "Please wait." -- English: Checking Memory Stick Duo™.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Now saving")then
newStr = "Now saving." -- English: Now saving./Do not remove the Memory Stick Duo™ /or turn off the system power.
axObj.WriteMemStr16Z(ptr, newStr)
--
elseif string.find(str, "Cargando.") then
newStr = "Cargando..." -- Spanish: Cargando./No extraigas el Memory Stick Duo™ /ni apagues el sistema.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Guardando...")then
newStr = "Espera..." -- Spanish: Guardando.../No extraigas el Memory Stick Duo™ /ni apagues el sistema.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Comprobando el Memory Stick") then
newStr = "Guardando..." -- Spanish: Comprobando el Memory Stick Duo™.
axObj.WriteMemStr16Z(ptr, newStr)
--
elseif string.find(str, "Chargement.") then
newStr = "Chargement." -- French: Chargement./Ne pas retirer le Memory Stick Duo™ /ou éteindre le système.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Vérification du Memory Stick")then
newStr = "Veuillez patienter." -- French: Vérification du Memory Stick Duo™.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Sauvegarde.") then
newStr = "Sauvegarde en cours." -- French: Sauvegarde./Ne pas retirer le Memory Stick Duo™ /ou éteindre le système.
axObj.WriteMemStr16Z(ptr, newStr)
--
elseif string.find(str, "Caricamento in corso") then
newStr = "Caricamento in corso." -- Italian: Caricamento in corso.../Non rimuovere il Memory Stick Duo™ /e non spegnere il sistema.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Controllo del Memory Stick")then
newStr = "Attendi." -- Italian: Controllo del Memory Stick Duo™.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Salvataggio in corso") then
newStr = "Salvataggio in corso." -- Italian: Salvataggio in corso.../Non rimuovere il Memory Stick Duo™ /e non spegnere il sistema.
axObj.WriteMemStr16Z(ptr, newStr)
--
elseif string.find(str, "Lädt") then
newStr = "Lädt." -- German: Lädt./Bitte den Memory Stick Duo™ nicht entfernen /und das System nicht ausschalten.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Memory Stick Duo™ wird überprüft")then
newStr = "Bitte warten." -- German: Memory Stick Duo™ wird überprüft.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Speichert.") then
newStr = "Speichert." -- German: Speichert./Bitte den Memory Stick Duo™ nicht entfernen und /das System nicht ausschalten.
axObj.WriteMemStr16Z(ptr, newStr)
--
elseif string.find(str, "システムデータをロード中です。") then
newStr = "ロード中。" -- Japanese: システムデータをロード中です。/Memory Stick Duo™を抜き挿ししたり、/電源を切ったりしないでください。
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Memory Stick Duo™のチェック中です。")then
newStr = "お待ちください。" -- Japanese: Memory Stick Duo™のチェック中です。
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "システムデータをセーブ中です。") then
newStr = "セーブ中。" -- Japanese: システムデータをセーブ中です。/Memory Stick Duo™を抜き挿ししたり、/電源を切ったりしないでください。
axObj.WriteMemStr16Z(ptr, newStr)
--
elseif string.find(str, "系統資料載入中。") then
newStr = "載入中。" -- Chinese: 系統資料載入中。/請勿插拔Memory Stick Duo™/或是關閉主機的電源。
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Memory Stick Duo™確認中。")then
newStr = "請稍候。" -- Chinese: Memory Stick Duo™確認中。
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "保存中。") then
newStr = "存檔中。" -- Chinese: 保存中。/請勿插拔Memory Stick Duo™/或是關閉主機的電源。
axObj.WriteMemStr16Z(ptr, newStr)
--
elseif string.find(str, "시스템 데이터를 불러오는 중입니다") then
newStr = "불러오는 중입니다." -- Korean: 시스템 데이터를 불러오는 중입니다./Memory Stick Duo™를 빼거나/전원을 끄지 마십시오.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "Memory Stick Duo™ 체크 중입니다")then
newStr = "잠시 기다려 주십시오." -- Korean: Memory Stick Duo™ 체크 중입니다.
axObj.WriteMemStr16Z(ptr, newStr)
elseif string.find(str, "시스템 데이터를 저장 중입니다") then
newStr = "저장 중입니다." -- Korean: 시스템 데이터를 저장 중입니다./Memory Stick Duo™를 빼거나,/전원을 끄지 마십시오.
axObj.WriteMemStr16Z(ptr, newStr)
end
end
 
local H3 = function() -- Localize__Manager__getLanguageName
local v0 = axObj.GetGpr(gpr.v0)
local langPtr = axObj.ReadMem32(v0)
langCode = axObj.ReadMemStr(langPtr)
end
 
local bundleFileName = ""
local H4 = function() -- System::Util__BNDFile__doNameCallback
local ptr = axObj.GetGpr(gpr.a0)
bundleFileName = axObj.ReadMemStr(ptr)
end
 
local H5 = function() -- Labo::GameSystem__callbackFunc_MemoryObject
local ptr = axObj.GetGpr(gpr.s5)
local dataPtr = axObj.ReadMem32(ptr)
if bundleFileName == "colony_data.pac" then
axObj.WriteMem16(dataPtr + 0x79ba, 4)
end
end
 
-- Black Smith - Remove "KeyGuide" bug when hit anvil head while quenching --
local blackSmithRunning = false
local H6 = function() -- Sound__SubGame__Blacksmith__Command__start__4LaboFv
blackSmithRunning = true
end
local H7 = function() -- Sound__BeatCommander__endSubGame__4LaboFv
if blackSmithRunning == true then
local a0 = axObj.GetGpr(gpr.a0)
axObj.WriteMem8(a0 + 0x19c, 1) -- set memory to 1 (instead of 0) otherwise brings up bad "KeyGuide"
end
blackSmithRunning = false
end
 
-- TIPS System hacks --
axInsnReplace(0x8A73A44, 0x3C0342A8, 0x3C0342A4) -- change required number of Tips from 84 to 82.
local H8 = function() -- GameSystem__Tips__Viewer__setup__4LaboFv
local global = getGlobalAddr()
if global == 0xFFFFFFFF then
return
end
 
local unitTable = axObj.ReadMem32(global + 0x1068) --> sets to: 0x8d13580 (unit table)
local tipsPtr = unitTable + 0x1F5E4
local badTips = axObj.ReadMem32(tipsPtr + 8)
badTips = badTips & 0xFFBBFFFF -- remove tips 0x53 and 0x57 as they referred to Multiplayer
axObj.WriteMem32(tipsPtr + 8, badTips)
end
 
-- Remove AutoSave menu from initial startup --
local H9 = function() -- GameSystem__SaveDataController__update__4LaboFv
local s3 = axObj.GetGpr(gpr.s3)
local flg = axObj.ReadMem32(s3 + 0x7eed)
local val = axObj.ReadMem32(s3 + 0x7efc)
if flg == 0 and val == 0x14 then
axObj.WriteMem32(s3 + 0x7efc, 0x13)
end
end
 
-- Change game save name to "Patapon 2 Remastered" --
local H10 = function() -- Utility__SaveDataUtility__setDataParamsfoString
local ptr = axObj.GetGpr(gpr.s1)
local strPtr = axObj.ReadMem32(ptr)
local newStr = "PATAPON™ 2 Remastered"
axObj.WriteMemStrZ(strPtr, newStr)
end
 
-- Change description for the "Friendship" weapon to remove game sharing text --
local itemsTable = {}
itemsTable[1] = "Proof of friendship establish" -- English
itemsTable[2] = "Prueba de la amistad establecida" -- Spanish
itemsTable[3] = "Preuve de l'amitié établie" -- French
itemsTable[4] = "Preuve d'une amitié" -- French alt
function changeStrings(strPtr) -- modify strings
local str = axObj.ReadMemStr16(strPtr) -- ptr to the string
local strFind = string.gsub(str, "/", " ") -- change any slash to space to strings can match.
strFind = string.gsub(strFind, "  ", " ") -- change any double spaces due to above change to only 1 space.
for i = 1, #itemsTable do
local startPos, endPos = string.find(strFind, itemsTable[i])
if startPos ~= nil then
str = string.sub(str, 1, (startPos-1) )
-- SPECIAL fixes --
str = string.gsub(str, "Un oiseau avec de bons HP et /une grosse attaque.","Un oiseau qui augmente vos/HP.") -- French incorrect grammar (bird)
str = string.gsub(str, "aumente","augmente") -- French incorrect grammar.
 
axObj.WriteMemStr16Z(strPtr, str)
end
end
end
local H11 = function() -- from Bases__Item__ExplanationWindow__setItemId
local ptr = axObj.GetGpr(gpr.a0)
local a2 = axObj.GetGpr(gpr.a2)
local valPtr = axObj.ReadMem32(ptr)
local v1 = valPtr + 8
local v0 = a2 * 4
v0 = v0 + v1
local strPtr = axObj.ReadMem32(v0)
strPtr = strPtr + valPtr
 
changeStrings(strPtr)
end
 
-- Skip Memory message when selecting "Delete Save Data" on "Save the adventure" dialogue.
local menuSkip = false
local H12 = function() -- Bases__Talk__CommandCamp__showDialog
menuSkip = true
end
local H13 = function() -- Bases__Talk__CommandCamp__showDialog
if menuSkip == true then
axObj.SetGpr(gpr.v1, 0)
menuSkip = false
end
end
local H14 = function() -- Bases__Talk__CommandCamp__showDialog
if menuSkip == true then
axObj.SetPC(0x88D908C)
end
end
 
 
-- HOOKS --
local hook1  = axObj.AddHook(0x88E9564, 0x0002102B, H1) -- Labo::Bases__Camp__Scene__updateTips
local hook2  = axObj.AddHook(0x899E718, 0x00403021, H2) -- GameSystem__SaveDataController__setStateMessage
local hook3  = axObj.AddHook(0x897771C, 0x00431021, H3) -- Localize__Manager__getLanguageName
local hook4  = axObj.AddHook(0x88774D0, 0x00402821, H4) -- System::Util__BNDFile__doNameCallback
local hook5  = axObj.AddHook(0x886889C, 0x02002021, H5) -- Labo::GameSystem__callbackFunc_MemoryObject
local hook6  = axObj.AddHook(0x898BCDC, 0x27BDFFE0, H6) -- Sound__SubGame__Blacksmith__Command__start__4LaboFv
local hook7  = axObj.AddHook(0x89220F8, 0xAC80019C, H7) -- Sound__BeatCommander__endSubGame__4LaboFv
local hook8  = axObj.AddHook(0x8A734DC, 0x27BDFFC0, H8) -- GameSystem__Tips__Viewer__setup__4LaboFv
local hook9  = axObj.AddHook(0x899CF4C, 0x92637EED, H9) -- GameSystem__SaveDataController__update__4LaboFv
local hook10 = axObj.AddHook(0x88E7E48, 0x2490009C, H10) -- Utility__SaveDataUtility__setDataParamsfoString
local hook11 = axObj.AddHook(0x897CF90, 0x26041718, H11) -- Bases__Item__ExplanationWindow__setItemId
local hook12 = axObj.AddHook(0x88D9114, 0xAEA00014, H12) -- Bases__Talk__CommandCamp__showDialog
local hook13 = axObj.AddHook(0x88D90B4, 0x9063C550, H13) -- Bases__Talk__CommandCamp__showDialog
local hook14 = axObj.AddHook(0x88D907C, 0x8FA2003C, H14) -- Bases__Talk__CommandCamp__showDialog
local hook15 = axObj.AddHook(0x8A394B4, 0x26241718, H11) -- Bases__Organization__Managed__ItemSelectWindow__onSlotChange (note uses H11)
 
 
-- US game bug fix.  "Paraget" -> "Patagate" --
axObj.AddHook(0x88DC5F4, 0x00409021, function() -- from Bases__Camp__Person__Behavior__Idle__update__4LaboFv
local strPtr = axObj.GetGpr(gpr.v0) + 0xE -- 0xE skip over X/Y positions.
local str = axObj.ReadMemStr16(strPtr)
if string.find(str, "The Paraget will") then
-- org string: The Paraget will teleport you to/another world…
local newStr = "The Patagate can teleport you to/another world…"
axObj.WriteMemStr16Z(strPtr, newStr)
elseif string.find(str, "Paraget Shrine") then
-- org string: This is the Paraget Shrine./Only <N0> and <N1> can/enter.
local newStr = "This is the Patagate Shrine/Only <N0> and <N1> can/enter."
axObj.WriteMemStr16Z(strPtr, newStr)
end
end)
 
--[[
axObj.AddHook(0x08982F48, 0x24070001, function()
if emuObj.NeoMode() then
axObj.SetGpr(gpr.a3, 0) -- turn on 60fps mode
end
end)
]]--
 
--- MOVIE FIX ---
local movieLastTime = 0.0
local movieFix = function() -- Labo::GameSystem__MovieModule__render
local t = axObj.GetFpr(0)
if t == 0 and movieLastTime > 0 then
local s0 = axObj.GetGpr(gpr.s0)
axObj.WriteMemFloat(s0 + 0x44, movieLastTime)
elseif t > 0 then
movieLastTime = t
end
end
 
axObj.AddHook(0x8A6A1DC, 0xe6000044, movieFix)
 
 
--- PAT2-16 FIX ---
axObj.AddHook(0x890E9E0, 0x02002021, function() -- Labo::Game__Gimmick__WindowAttacher__update
local ptr = axObj.GetGpr(gpr.sp) + 0x28
local posy = axObj.ReadMemFloat(ptr + 4)
if posy < -30 then
local obj = axObj.GetGpr(gpr.a0)
axObj.WriteMem8(obj + 0x2a8, 0)
end
end)
</pre>

Latest revision as of 04:29, 2 March 2024

General[edit source]

Custom PSPemu Configuration Files[edit source]

Configuration files created by users to improve PSP emulator compatibility on PS4.

God Of War - Ghost Of Sparta[edit source]

config-title.txt
UCUS98737

--antialias=off
--godofwarhack=true
--forcenobilinear=true

LUA
UCUS98732

local axObj = getAXObject()
local emuObj = getEmuObject()

local patcher = function()

axObj.WriteMem32(0x08A15210,0x24020000)
end

emuObj.AddVsyncHook(patcher)
PPSSPP
0881681C

God of War: Chains of Olympus[edit source]

config-title.txt
UCUS98653

--texclutmode=filter
--bend-30hz-lock=1
--godofwarhack=true

Dante's Inferno[edit source]

config-title.txt
ULUS10469

--antialias=off
--texloadcores=48
--texclutmode=full
--vramcopyback=12
--locorocomeshsmooth=true
--texrecent=true
--umddelay=true
--depthscalehack=true
--forcenobilinear=true
--smoothlevel=0

LUA
UCUS98732

-- Dantes Inferno

apiRequest(1.0)  -- request version 1.0 API. Calling apiRequest() is mandatory.

local emuObj  = getEmuObject() -- emulator
local axObj  = getAXObject() -- allegrex

local patcher = function()

--30 FPS
local code_check1 = axObj.ReadMem16(0x001C239C)

local code_check2 = axObj.ReadMem16(0x103E4B40)

if code_check1 == 0x0064 and  code_check2 == 0x001E then


axObj.WriteMem32(0x203E4B40,0x0000001E)
axObj.WriteMem32(0x20022EE4,0x3D088889) --1/30 = 0.03333

end

end

emuObj.AddVsyncHook(patcher)

Tekken 6[edit source]

config-title.txt
ULUS10466

--has-shown-start-select-help=0
--userui-settings-graphics=1
--globalgamedata-dir=global
--bend-30hz-lock=0
--replacementfilter=true
--depthscalehack=true
--texcachemode=patchworkheroes
--texloadcores=16
--present=vblankstart 
--texclutmode=full
--texrecent=true
--force-dsf-present=1
--gputhread=true
--gpu-renderthread=20
--force-triangle-clip-off=true
--umddelay=true

# Emu used = Syphon Filter Dark Mirror

Soulcalibur: Broken Destiny[edit source]

config-title.txt
ULUS10457

--has-shown-start-select-help=0
--userui-settings-graphics=1
--globalgamedata-dir=global
--trophies=0
--umddelay=true
--bend-30hz-lock=0
--present=setframebuf #,setframebuf,drawsync
--texclutmode=filter  #,full
--texloadmode=launch  #ondemand_lz4
--depthscalehack=true
--texloadcores=8
--texrecent=true  #async, lastused

# Emu used = Syphon Filter Dark Mirror

Miami Vice: The Game[edit source]

config-title.txt
ULUS10109

--antialias=off
--texclutmode=full
--texloadcores=12
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true
--smoothlevel=0

Wild Arms XF[edit source]

config-title.txt
ULUS10339

--title-id=ULUS10339
--has-shown-start-select-help=0
--vms=/temp0/vms
--ms0=/temp0/ms0
--multisaves=true
--notrophies=true

--antialias="off" #ssaa4x off msaa4x
--texcachemode=rondo #drawbounds,drawboundsloco,patchworkheroes,locoroco2,rondo
--texloadcores=10
--present=drawsync
--gputhread=true
--texrecent=true
--texclutmode=full

Burnout Dominator[edit source]

config-title.txt
ULUS10236

---title-id=ULUS10236
--multisaves=true
--notrophies=true
--vms=/temp0/vms
--has-shown-start-select-help=1
--antialias="off"
--texclutmode=full
--texloadcores=12
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true

ULUS10236_patches.lua
ULUS10236

-- Burnout Dominator
-- lua by Stayhye

apiRequest(1.0)  -- request version 1.0 API. Calling apiRequest() is mandatory.

local emuObj  = getEmuObject() -- emulator
local axObj  = getAXObject() -- allegrex

local patcher = function()
--30 FPS V.2 [Default]
local code_check1 = axObj.ReadMem16(0x02574C)
if code_check1 == 0x0000 then
axObj.WriteMem32(0x2002574C,0x14A0001A)
axObj.WriteMem32(0x201A0358,0xE60C0034)
axObj.WriteMem32(0x204F08BC,0x3D088888)
axObj.WriteMem32(0x2019AE90,0x3C043F80)
end
--[[
--60 FPS V.2
local code_check2 = axObj.ReadMem16(0x02574C)
if code_check2 == 0x001A then
axObj.WriteMem32(0x2002574C, 0x00000000)
axObj.WriteMem32(0x201A0358, 0x00000000)
axObj.WriteMem32(0x204F08BC, 0x3C888888)
axObj.WriteMem32(0x2019AE90, 0x3C043F00)
end
--]]
end

emuObj.AddVsyncHook(patcher)

emuObj.SetTextureHashMode("patchworkheroes")

Tom Clancy's Ghost Recon Advanced Warfighter 2[edit source]

config-title.txt
ULUS10237

# Ghost Recon: Advanced Warfighter 2 (all regions)

--has-shown-start-select-help=1

--antialias=off

--texclutmode=full

--bend-30hz-lock=0

--texloadcores=12
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true
--smoothlevel=0

--forcenobilinear=true

--active-sku="ULUS10237"
--title-id=ULUS10237

--psp-right-stick-action=1
--psp-right-stick-deadzone-x=15
--psp-right-stick-deadzone-y=15
--psp-right-stick-deadzone-semicircle-arc=40

#  Emu used = Syphon Filter Dark Mirror

Call of Duty: Roads to Victory[edit source]

config-title.txt
ULES00643

# Call of Duty: Roads to Victory (all regions)

--has-shown-start-select-help=1

--bend-30hz-lock=0

--antialias=off
--texclutmode=full
--texloadcores=12
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true

--forcenobilinear=true

--active-sku="ULES00643"
--title-id=ULES00643

--psp-right-stick-action=1
--psp-right-stick-deadzone-x=15
--psp-right-stick-deadzone-y=15
--psp-right-stick-deadzone-semicircle-arc=40

--app-volume=0.8

#  Emu used = Syphon Filter Dark Mirror

SpongeBob's Truth or Square[edit source]

config-title.txt
ULUS10478

# SpongeBob's Truth or Square (all regions)

--has-shown-start-select-help=1
--bend-30hz-lock=1

--force-dsf-present=1

--forcenobilinear=true
--depthscalehack=true

--active-sku="ULUS10478"
--title-id=ULUS10478

--antialias=off
--texloadcores=48
--texcachemode=patchworkheroes
--present=setframebuf
--texrecent=true
--umddelay=true
--smoothlevel=0
--texclutmode=full  
--vramcopyback=12
--locorocomeshsmooth=true
--gpu-renderthread=20

# following settings are machine-generated
--region-dir=SIEA
--ps4-trophies=0
--ps5-uds=0
--trophies=0

--globalgamedata-dir=global

# Emu used = Syphon Filter Dark Mirror

Harvest Moon Hero of Leaf Valley[edit source]

config-title.txt
ULUS10458

# Harvest Moon Hero of Leaf Valley (all regions)

--has-shown-start-select-help=1

--bend-30hz-lock=0
--force-dsf-present=1
--depthscalehack=true

--gpu-renderthread=20
--antialias="msaa4x"
--anisolevel=4

--texclutmode=full
--texloadcores=48
--texcachemode=patchworkheroes
--present=vblankstart
--texrecent=true
--umddelay=true
--smoothlevel=0
--locorocomeshsmooth=true

--active-sku="ULUS10458"
--title-id=ULUS10458

# following settings are machine-generated
--region-dir=SIEA
--ps4-trophies=0
--ps5-uds=0
--trophies=0

--globalgamedata-dir=global

# Emu used = Syphon Filter Dark Mirror

Gurumin: A Monstrous Adventure[edit source]

config-title.txt
ULUS10228

# Gurumin: A Monstrous Adventure (all regions)

--image="data/USER_L0.IMG"
--title-id=ULUS10228
   
--gpu-renderthread=0

--antialias=ssaa4x
--texclutmode=full
--smoothlevel=0
--texcachemode=patchworkheroes
--present=vblankstart

--texrecent=true
--umddelay=true
--gputhread=true

--vramcopyback=45
--texloadcores=48

--locorocomeshsmooth=true
--depthscalehack=true

--multisaves=true
--notrophies=true

# Emu used = Ridge Racer 2

Incomplete configurations[edit source]

This is a list of configurations that were unsuccessful or were never completed, or information that might help people in the future.
A place for research and sharing useful info.

Crash Tag Team Racing[edit source]

LUA
ULUS10044

Reaches 0x8A7292C 	jal	zz_sceKernelLoadModule
Similarly to YU-GI-OH! 5D's Tag Force 4, and then crashes after 2 instructions.

YU-GI-OH! 5D's Tag Force 4[edit source]

LUA
ULUS10481

local axObj = getAXObject()
local emuObj = getEmuObject()

local patcher = function()

axObj.WriteMem32(0x8818780,0x10000025)
end

emuObj.AddVsyncHook(patcher)

Official PSPemu Configuration Files[edit source]

Configuration files extracted from official packages to improve PSP emulator compatibility on PS4

Syphon Filter: Dark Mirror[edit source]

config-title.txt
UCUS98641

# SyphonFilterDarkMirror (all regions)

--texclutmode=filter

--bend-30hz-lock=1

--psp-right-stick-action=1
--psp-right-stick-deadzone-x=15
--psp-right-stick-deadzone-y=15
--psp-right-stick-deadzone-semicircle-arc=40

--app-volume=0.8


# following settings are machine-generated
--region-dir=SIEA
--ps4-trophies=1
--ps5-uds=1
--trophies=1

--globalgamedata-dir=global

UCUS98641_patches.lua

-- Lua 5.3
-- Title: Syphon Filter: Dark Mirror

-- Patches for fixing issues with post fx in games using the Syphon Filter/Resistance engine

apiRequest(1.0)	-- request version 1.0 API. Calling apiRequest() is mandatory.

local emuObj = getEmuObject()
local cpu = getAXObject() 

-- The bloom filter uses 1.5 pixel jitter to make a ghetto blur. When up-ressed, this doesn't look good.
-- To compensate, reduce the jitter amount before rendering.
function BloomJitterPlusAdjust()
	-- 1.5 pixel "+" pattern
	emuObj.AdjustUVJitter(0, 4, 0.0, 1.5)
	emuObj.AdjustUVJitter(4, 4, 0.0, -1.5)
	emuObj.AdjustUVJitter(8, 4, 1.5, 0.0)
	emuObj.AdjustUVJitter(12, 4, -1.5, 0.0)
end

function BloomJitterCrossAdjust()
	-- 1.5 pixel "x" pattern
	emuObj.AdjustUVJitter(0, 4, 1.5, 1.5)
	emuObj.AdjustUVJitter(4, 4, -1.5, 1.5)
	emuObj.AdjustUVJitter(8, 4, 1.5, -1.5)
	emuObj.AdjustUVJitter(12, 4, -1.5, -1.5)
end

local jitterFixPlus = emuObj.AddGPUHook(0x40dc000, 0, 16, 0x40d4000, BloomJitterPlusAdjust)
local jitterFixCross = emuObj.AddGPUHook(0x40d4000, 0, 16, 0x40dc000, BloomJitterCrossAdjust)

function depthquery()
	local querystruct = 0x8eda968		-- this is always in a fixed location
	-- the depth query struct is fixed to 24 entries
	-- 0..15 seem to be always used for lights, 16..23 are for npcs
	for i=0,23 do
		local querytype = cpu.ReadMem32(querystruct+0)
		local valid = cpu.ReadMem32(querystruct+1*4)
		if valid ~= 0xffffffff then
			--local queryx = cpu.ReadMem32(querystruct+2*4)
			--local queryy = cpu.ReadMem32(querystruct+3*4)
			--local querydepth = cpu.ReadMem32(querystruct+4*4)
			--local querywidth = cpu.ReadMem32(querystruct+5*4)
			--local queryheight = cpu.ReadMem32(querystruct+6*4)
			--local param1c = cpu.ReadMem32(querystruct+7*4)
			--local param20 = cpu.ReadMem32(querystruct+8*4)
			local param24 = cpu.ReadMem32(querystruct+9*4)
			--local result = cpu.ReadMemFloat(querystruct+10*4)
			if param24 <= 0 then
				cpu.WriteMem32(querystruct+1*4, 0xffffffff)		-- to be removed from the list -> mark as invalid
			else
				if querytype == 3 then		-- n x n coverage based occlusion used by lights. Object opacity is set to (visible_samples / total_samples)
					cpu.WriteMemFloat(querystruct+10*4, 0.0)	-- always hide lights
				else						-- Enemies use a 5-point (corners + center) occlusion check. Object is visible if any of the points is visible.
					cpu.WriteMemFloat(querystruct+10*4, 1.0)	-- set always visible
				end
			end
		end
		querystruct = querystruct + 0x2c
	end
end

cpu.AddHook(0x8c163d4, 0x27bdff80, depthquery)			-- = addiu sp, sp, -0x80
-- the hook code replaces the occlusion function, so just adjust the stack and return
cpu.InsnReplace(0x8c163d8, 0x34040000, 0x27bd0080)		-- addiu sp, sp, 0x80
cpu.InsnReplace(0x8c163dc, 0xafa40048, 0x03e00008)		-- jr ra
cpu.InsnReplace(0x8c163e0, 0x3c0408ee, 0x00000000)		-- nop

Echochrome[edit source]

config-title.txt
UCES01011

# Echochrome (all regions)

# following settings are machine-generated
--region-dir=SIEA
--ps4-trophies=0
--ps5-uds=0
--trophies=0

config-region.txt

--image="data/USER_L0.IMG"
--antialias=SSAA4x
--multisaves=true
--notrophies=true

NPUG80135_patches.lua

-- Lua 5.3
-- Title: Echochrome  NPUG 80135  (US)

--  WBD  5/10/2022	prevent Console Msg about Memory Stick from being displayed
--  WBD  5/22/2022  remove Send and Receive menu options

apiRequest(1.0)	-- request version 1.0 API. Calling apiRequest() is mandatory.

local gpr	= require( "ax-gpr-alias" ) -- you can access Allegrex GPR by alias (gpr.a0 / gpr["a0"])
local emuObj = getEmuObject()
local cpu = getAXObject()

local hook = 0x88468f0

function SkipMsg()
	local v1 = cpu.GetGpr(gpr.v1)
	local v0 = cpu.GetGpr(gpr.v0)
	
	cpu.SetGpr(gpr.a0, v1)
	cpu.SetGpr(gpr.v0, 0)
	cpu.WriteMem32(v1+4, v0)
	cpu.SetPC(hook+0xc)
	print "_NOTE: Skipping Memory Stick Message"
end
cpu.AddHook(hook, 0x00602021, SkipMsg)


function DisableSendReceive()
	cpu.WriteMem32(0x8909940, 0)		-- overwrite Send with 0
	cpu.WriteMem32(0x890991c, 0)		-- overwrite Receive with 0
end
cpu.AddHook(0x8846fb4, 0xae130090, DisableSendReceive)

LocoRoco Midnight Carnival[edit source]

config-title.txt
NPEG00024

# LocorocoMidnightCarnival (all regions)

--ps5-uds=0# following settings are machine-generated
--region-dir=SIEE
--ps4-trophies=0
--ps5-uds=0
--trophies=0

config-region.txt

; Windows configuration file for PSPHD

; Game Image
--image="data\USER_L0.IMG"

; Use this to run the automatic font dumper.
;--boot="host0:../tools/glyphdump.prx"

; Uncomment these to play around with font dumping.
;--fontsave="host0:fontdump"
;--fontreplace="host0:fontreplace"

; Scaling factor (Windows only - 1: 480x272, 2: 960x544, 3: 1440x816, 4: 1920x1088 ... 8: 3840x2176)
--scale=3

; Language selection (Windows only - the PS4 version auto-selects based on the PS4 language setting)
; Switch the PSP language to one of the following:
; "en": English (default)
; "jp": Japanese
; "fr": French
; "es": Spanish
; "de": German
; "it": Italian
; "nl": Dutch
; "pt": Portuguese
; "ru": Russian
; "ko": Korean
; "chs": Chinese Simplified
; "cht": Chinese Traditional
;--lang="en"

; Redirect host0: to a another directory (uncomment to enable).
; By default it's mapped to the working directory where the executable starts
;--host="D:\Sony\PSPHD"

; To dump the original video in PMF format, uncomment the --dumpvideos line
; For example, with the current setting, it will save them in a "D:\Sony\PSPHD\videos" directory (make sure the directory exists)
;--dumpvideos="host0:videos"

; To dump the original audio in Atrac3 format, uncomment the --dumpaudio line
; For example, with the current setting, it will save them in a "D:\Sony\PSPHD\audio" directory (make sure the directory exists)
;--dumpaudio="host0:audio"

; To save the in-game textures as the game runs, uncomment the --texsave line
; For example, with the current setting, it will save them in a "D:\Sony\PSPHD\texdump" directory (make sure the directory exists)
;--texsave="host0:texdump"
;--texmissingsave="host0:texdump"

; To replace specific textures as the game runs, uncomment the --texreplace line
; For example, with the current setting, it will load them from the "D:\Sony\PSPHD\texreplace" directory
; If the --scale setting is set to 4 or 8, the program will also look for replacement textures on '4x' or '8x' directories within this directory
;--texreplace="host0:texreplace"

; This forces alpha blending to on for replaced textures. (uncomment to enable)
; With this we can freely make use of a normal alpha channel on replacement textures
;--replacementalpha=true

; This enables bilinear filtering on replaced textures. (uncomment to enable)
;--replacementfilter=true

; Antialiasing mode. SSAA4x looks best, MSAA4x only smooths edges.
; Choices: off, SSAA4x, MSAA4x
--antialias=SSAA4x

; Allows to switch between replacement and original textures using L3 on the DS4 or the T key.
;--texswitch=true

; Turns on the auto-resampler. Assumes textures in texreplace are at 8x resolution and resamples them at load
;--autoresampler=true

; Turns on filtering of CLUT hashes to avoid repeat indexed textures
;--texclutmode=filter

; Enable Multiple Savegames
--multisaves=true

; Custom locoroco2 texture hasher
;--texcachemode="locoroco2"

NPEG00024_patches.lua

-- Lua 5.3
-- Title: Locoroco Midnight Carnival NPEG-00024  (EU)

--  WBD  5/25/2022	prevent RANKING option from being selected

apiRequest(1.0)	-- request version 1.0 API. Calling apiRequest() is mandatory.

local gpr	= require( "ax-gpr-alias" ) -- you can access Allegrex GPR by alias (gpr.a0 / gpr["a0"])
local emuObj = getEmuObject()
local cpu = getAXObject()


function DisableRanking()
	local a2 = cpu.GetGpr(gpr.a2)
	local a1 = cpu.GetGpr(gpr.a1)
	local check = cpu.ReadMem8(a1+0x2c)			-- make sure we're in the correct menu
	local ptr = a1+a2+0x34
	local new_indx = cpu.ReadMem8(ptr)
	if (new_indx == 2) then
		if (a2 == 2 and check == 0x2b) then		-- moving right
			cpu.WriteMem8(ptr, 3)
			print "_NOTE: NEW changed to 3"

		elseif (a2 == 3 and check == 0x3e) then		-- moving left
			cpu.WriteMem8(ptr, 1)
			print "_NOTE: NEW changed to 1"
		end
	end
end

cpu.AddHook(0x8a205c4, 0x00c58821, DisableRanking)

Patapon 2[edit source]

LUA
UCUS98732

-- Lua 5.3
-- Title:   Patapon 2 PSP - UCUS-98732 (USA)
-- Author:  Ernesto Corvi

-- Changelog:
-- v1.1: US only.  Change the word "Paraget" to "Patagate" in two strings.

apiRequest(1.0)	-- request version 1.0 API. Calling apiRequest() is mandatory.

local gpr		= require( "ax-gpr-alias" ) -- you can access Allegrex GPR by alias (gpr.a0 / gpr["a0"])
local emuObj	= getEmuObject() -- emulator
local axObj		= getAXObject() -- allegrex
local pad		= require("pad")

-- Hook memcpy to catch framebuffer effects
axFuncReplace(0x881D194, "patapon_memcpy")

-- Accelerate some functions
axFuncReplace(0x8804670, "__ptmf_scall")
axFuncReplace(0x8892230, "Renderer__makeWorldMatrix__4psysFv")
axFuncReplace(0x88209A8, "patapon_strcmp")
axFuncReplace(0x8815130, "sceGupSetStatus")
axFuncReplace(0x8851D84, "FMtx44__setRow__3PydFv")
axFuncReplace(0x88437F0, "Script__Talk__Controller__setDeltaTime__3PydFv")
axFuncReplace(0x8843B6C, "Script__Talk__Controller__setCmdId__3PydFv")
axFuncReplace(0x88441DC, "Script__Talk__Controller__getArgValuePtr__3PydFv_0")
axFuncReplace(0x89B25B0, "sceGmoCol4Multiply")
axFuncReplace(0x8910A60, "Gfx__CacheModel__getNodeMtx__6SystemFv")
axFuncReplace(0x8911440, "Gfx__StaticGmoModel__getNodeIdx__6SystemFv")
axFuncReplace(0x89114C8, "Gfx__StaticGmoModel__getNodeMtx__6SystemFv")
axFuncReplace(0x891157C, "Gfx__StaticGmoModel__getNodeMtx__6SystemFv_0")
axFuncReplace(0x881462C, "sceGuEnable", 0x8B3C050) -- param = gupbase pointer
axFuncReplace(0x8814684, "sceGuDisable", 0x8B3C050) -- param = gupbase pointer
axFuncReplace(0x89B2D84, "sceGmoFCurveEval_fastpath", 0x89B2D88) -- param = function entry if not fast path
--axFuncReplace(0x88D0788, "Game__Map__Weather__WindLocus__update__4LaboFv_loop", 0x88D0864) -- param = continue address

axFuncReplace(0x890FCBC, "convertLowerString__6SystemFv")
axFuncReplace(0x8877104, "convertLowerString__6SystemFv") -- convertLowerString__21@unnamed@BNDFile_cpp@Fv, same functionality
axFuncReplace(0x897927C, "__extendsfdf2")
axFuncReplace(0x8979AF8, "__muldf3")
axFuncReplace(0x8979A8C, "__adddf3")
axFuncReplace(0x897A750, "__truncdfsf2")
axFuncReplace(0x88CBD64, "RemapPacket", 0x8ACC394) -- param comes from RemapPacketAddr24 & RemapPacketAddr16
axFuncReplace(0x890FEA0, "patapon_strcmp") -- strcmpFast__6SystemFv ('fast' strcmp)


-- Switch Select command to "Options" button.
emuObj.PadSetButtonsMode(pad.BUTTONS_MODE_OPTION_IS_SELECT)

-- Remove "Transfer Patapon Saved Data" option from New Game option
--axInsnReplace(0x8A46660, 0x24070002, 0x24070001) -- li  a3,0x2  (change 2 menu options to 1)
emuObj.RemapSavedata("UCUS98711", "CUSA06171", "504e802b04a1838c32b616abbe0b475fbea1c823825ef0df06cc2bad129ce2f7")

-- Fix "Tree of Life" unaligned lines and shadows
axObj.AddHook(0x884600C, 0x8c850010, function() -- PSP::Gfx::PrimitiveContext::setVertex2f
	local context = axObj.GetGpr(gpr.a0)
	local cmdCount = axObj.ReadMem32(context + 0x14)
	if (cmdCount & 1) == 1 then -- we have at least 2 commands
		local cmdBuffer = axObj.ReadMem32(context + 0x10)
		local cx = axObj.GetFpr(12)
		local cy = axObj.GetFpr(13)
		local ox = axObj.ReadMemFloat(cmdBuffer-12)
		local oy = axObj.ReadMemFloat(cmdBuffer-8)
		
		if cx == ox then
			axObj.SetFpr(12, cx + 0.5)
			axObj.WriteMemFloat(cmdBuffer-12, ox + 0.5)
		elseif cy == oy then
			axObj.SetFpr(13, cy + 0.5)
			axObj.WriteMemFloat(cmdBuffer-8, oy + 0.5)
		end
	end
end)

-- LANGUAGES --
local langCode = "us" -- default
--local languageList = {"Japanese","English","UK","Italian","German","Spanish","French","Korean","Chinese","ns","nf","Dutch","Portuguese","gr","Belgium"}
--local gameLanguageCode = {"jp","us","uk","it","de","sp","fr","kr","cn","ns","nf","nl","pt","gr","be"}
local languageList = {"","English","","","","","","","","Spanish","French","","","",""}
local gameLanguageCode = {"","us","","","","","","","","ns","nf","","","",""}

-- US: english = 1, spanish = 9, french = 0xA (from Localize__Manager__setDefaultLangage)
-- EU: uk = 2, italian = 3, german = 4, spanish = 5, french = 6
-- JP: jp = 0
-- HP: ko = 7, ch = 8, 
	
-- GLOBAL FUNCTIONS --

local GLOBAL = 0x8B7D088 -- reawakeDeathUnit - offset 0x88A95E8 in $v1

function getGlobalAddr() -- gets Global to user data.
	-- address comes from: Labo::Bases::Camp::Controller::reawakeDeathUnit - offset 0x88A95E8 in $v1
	-- add 0x20 to address to align it with the word "none"
	
	local main = axObj.ReadMem32(GLOBAL)				-- fixed Global address from: 0x88A95E8 -> 0x8c9fbc0
	if main == 0xFFFFFFFF or main == 0 then
		return 0xFFFFFFFF
	end
	local ptr = axObj.ReadMem32(main + 0x10c0)			--> sets to: 0x8d07840
	if ptr == 0xFFFFFFFF or ptr == 0 then
		return 0xFFFFFFFF
	end

	return ptr
end

-- MAIN FUNCTIONS --

local H1 = function() -- Labo::Bases::Camp::Scene::updateTips
	local v0 = axObj.GetGpr(gpr.v0)
	if v0 > 0 then
		emuObj.ThrottleMax()
	else
		emuObj.ThrottleNormal()
	end
end

local H2 = function() -- GameSystem__SaveDataController__setStateMessage
	local ptr = axObj.GetGpr(gpr.a2)
	local str = axObj.ReadMemStr16(ptr)
	local newStr = "Now loading. Do not turn off the power."
	-- english: Now loading./Do not remove the Memory Stick Duo™ /or turn off the system power.
	-- spanish: Cargando./No extraigas el Memory Stick Duo™ /ni apagues el sistema.
	-- french: Chargement./Ne pas retirer le Memory Stick Duo™ /ou éteindre le système.
	-- italian: Caricamento in corso.../Non rimuovere il Memory Stick Duo™ /e non spegnere il sistema.
	-- german: Lädt./Bitte den Memory Stick Duo™ nicht entfernen /und das System nicht ausschalten.
	-- japanese: システムデータをロード中です。/Memory Stick Duo™を抜き挿ししたり、/電源を切ったりしないでください。
	-- chinese: 系統資料載入中。/請勿插拔Memory Stick Duo™/或是關閉主機的電源。
	-- korean: 시스템 데이터를 불러오는 중입니다./Memory Stick Duo™를 빼거나/전원을 끄지 마십시오.
	
	if string.find(str, "Now loading") then
		newStr = "Now loading."										-- English: Now loading./Do not remove the Memory Stick Duo™ /or turn off the system power.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Checking Memory Stick") then
		newStr = "Please wait."										-- English: Checking Memory Stick Duo™.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Now saving")then
		newStr = "Now saving."										-- English: Now saving./Do not remove the Memory Stick Duo™ /or turn off the system power.
		axObj.WriteMemStr16Z(ptr, newStr)
--
	elseif string.find(str, "Cargando.") then
		newStr = "Cargando..."										-- Spanish: Cargando./No extraigas el Memory Stick Duo™ /ni apagues el sistema.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Guardando...")then
		newStr = "Espera..."										-- Spanish: Guardando.../No extraigas el Memory Stick Duo™ /ni apagues el sistema.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Comprobando el Memory Stick") then
		newStr = "Guardando..."										-- Spanish: Comprobando el Memory Stick Duo™.
		axObj.WriteMemStr16Z(ptr, newStr)
--
	elseif string.find(str, "Chargement.") then
		newStr = "Chargement."										-- French: Chargement./Ne pas retirer le Memory Stick Duo™ /ou éteindre le système.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Vérification du Memory Stick")then
		newStr = "Veuillez patienter."								-- French: Vérification du Memory Stick Duo™.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Sauvegarde.") then
		newStr = "Sauvegarde en cours."								-- French: Sauvegarde./Ne pas retirer le Memory Stick Duo™ /ou éteindre le système.
		axObj.WriteMemStr16Z(ptr, newStr)
--
	elseif string.find(str, "Caricamento in corso") then
		newStr = "Caricamento in corso."							-- Italian: Caricamento in corso.../Non rimuovere il Memory Stick Duo™ /e non spegnere il sistema.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Controllo del Memory Stick")then
		newStr = "Attendi."											-- Italian: Controllo del Memory Stick Duo™.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Salvataggio in corso") then
		newStr = "Salvataggio in corso."							-- Italian: Salvataggio in corso.../Non rimuovere il Memory Stick Duo™ /e non spegnere il sistema.
		axObj.WriteMemStr16Z(ptr, newStr)
--
	elseif string.find(str, "Lädt") then
		newStr = "Lädt."											-- German: Lädt./Bitte den Memory Stick Duo™ nicht entfernen /und das System nicht ausschalten.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Memory Stick Duo™ wird überprüft")then
		newStr = "Bitte warten."									-- German: Memory Stick Duo™ wird überprüft.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Speichert.") then
		newStr = "Speichert."										-- German: Speichert./Bitte den Memory Stick Duo™ nicht entfernen und /das System nicht ausschalten.
		axObj.WriteMemStr16Z(ptr, newStr)
--
	elseif string.find(str, "システムデータをロード中です。") then
		newStr = "ロード中。"											-- Japanese: システムデータをロード中です。/Memory Stick Duo™を抜き挿ししたり、/電源を切ったりしないでください。
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Memory Stick Duo™のチェック中です。")then
		newStr = "お待ちください。"										-- Japanese: Memory Stick Duo™のチェック中です。
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "システムデータをセーブ中です。") then
		newStr = "セーブ中。"											-- Japanese: システムデータをセーブ中です。/Memory Stick Duo™を抜き挿ししたり、/電源を切ったりしないでください。
		axObj.WriteMemStr16Z(ptr, newStr)
--	
	elseif string.find(str, "系統資料載入中。") then
		newStr = "載入中。"											-- Chinese: 系統資料載入中。/請勿插拔Memory Stick Duo™/或是關閉主機的電源。
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Memory Stick Duo™確認中。")then
		newStr = "請稍候。"											-- Chinese: Memory Stick Duo™確認中。
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "保存中。") then
		newStr = "存檔中。"											-- Chinese: 保存中。/請勿插拔Memory Stick Duo™/或是關閉主機的電源。
		axObj.WriteMemStr16Z(ptr, newStr)
--
	elseif string.find(str, "시스템 데이터를 불러오는 중입니다") then
		newStr = "불러오는 중입니다."										-- Korean: 시스템 데이터를 불러오는 중입니다./Memory Stick Duo™를 빼거나/전원을 끄지 마십시오.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "Memory Stick Duo™ 체크 중입니다")then
		newStr = "잠시 기다려 주십시오."									-- Korean: Memory Stick Duo™ 체크 중입니다.
		axObj.WriteMemStr16Z(ptr, newStr)
	elseif string.find(str, "시스템 데이터를 저장 중입니다") then
		newStr = "저장 중입니다."										-- Korean: 시스템 데이터를 저장 중입니다./Memory Stick Duo™를 빼거나,/전원을 끄지 마십시오.
		axObj.WriteMemStr16Z(ptr, newStr)
	end
end

local H3 = function()	-- Localize__Manager__getLanguageName
	local v0 = axObj.GetGpr(gpr.v0)
	local langPtr = axObj.ReadMem32(v0)
	langCode = axObj.ReadMemStr(langPtr)
end

local bundleFileName = ""
local H4 = function() -- System::Util__BNDFile__doNameCallback
	local ptr = axObj.GetGpr(gpr.a0)
	bundleFileName = axObj.ReadMemStr(ptr)
end

local H5 = function() -- Labo::GameSystem__callbackFunc_MemoryObject
	local ptr = axObj.GetGpr(gpr.s5)
	local dataPtr = axObj.ReadMem32(ptr)
	
	if bundleFileName == "colony_data.pac" then
		axObj.WriteMem16(dataPtr + 0x79ba, 4)
	end
end

-- Black Smith - Remove "KeyGuide" bug when hit anvil head while quenching --
local blackSmithRunning = false
local H6 = function() -- Sound__SubGame__Blacksmith__Command__start__4LaboFv
	blackSmithRunning = true
end
local H7 = function() -- Sound__BeatCommander__endSubGame__4LaboFv
	if blackSmithRunning == true then
		local a0 = axObj.GetGpr(gpr.a0)
		axObj.WriteMem8(a0 + 0x19c, 1)	-- set memory to 1 (instead of 0) otherwise brings up bad "KeyGuide"
	end
	
	blackSmithRunning = false
end

-- TIPS System hacks --
axInsnReplace(0x8A73A44, 0x3C0342A8, 0x3C0342A4) -- change required number of Tips from 84 to 82.
local H8 = function() -- GameSystem__Tips__Viewer__setup__4LaboFv
	local global = getGlobalAddr()
	if global == 0xFFFFFFFF then
		return
	end

	local unitTable = axObj.ReadMem32(global + 0x1068)	--> sets to: 0x8d13580 (unit table)
	local tipsPtr = unitTable + 0x1F5E4
	
	local badTips = axObj.ReadMem32(tipsPtr + 8)
	badTips = badTips & 0xFFBBFFFF		-- remove tips 0x53 and 0x57 as they referred to Multiplayer
	axObj.WriteMem32(tipsPtr + 8, badTips)
end

-- Remove AutoSave menu from initial startup --
local H9 = function() -- GameSystem__SaveDataController__update__4LaboFv
	local s3 = axObj.GetGpr(gpr.s3)
	local flg = axObj.ReadMem32(s3 + 0x7eed)
	local val = axObj.ReadMem32(s3 + 0x7efc)
	
	if flg == 0 and val == 0x14 then
		axObj.WriteMem32(s3 + 0x7efc, 0x13)
	end
end

-- Change game save name to "Patapon 2 Remastered" --
local H10 = function() -- Utility__SaveDataUtility__setDataParamsfoString
	local ptr = axObj.GetGpr(gpr.s1)
	local strPtr = axObj.ReadMem32(ptr)
	local newStr = "PATAPON™ 2 Remastered"
	
	axObj.WriteMemStrZ(strPtr, newStr)
end

-- Change description for the "Friendship" weapon to remove game sharing text --
local	itemsTable = {}
		itemsTable[1] = "Proof of friendship establish"			-- English
		itemsTable[2] = "Prueba de la amistad establecida"		-- Spanish
		itemsTable[3] = "Preuve de l'amitié établie"			-- French
		itemsTable[4] = "Preuve d'une amitié"					-- French alt
		
function changeStrings(strPtr) -- modify strings
	local str = axObj.ReadMemStr16(strPtr) -- ptr to the string
	local strFind = string.gsub(str, "/", " ")	-- change any slash to space to strings can match.
	strFind = string.gsub(strFind, "  ", " ")	-- change any double spaces due to above change to only 1 space.
	
	for i = 1, #itemsTable do
		local startPos, endPos = string.find(strFind, itemsTable[i])
	
		if startPos ~= nil then
			str = string.sub(str, 1, (startPos-1) )
			-- SPECIAL fixes --
			str = string.gsub(str, "Un oiseau avec de bons HP et /une grosse attaque.","Un oiseau qui augmente vos/HP.") -- French incorrect grammar (bird)
			str = string.gsub(str, "aumente","augmente") -- French incorrect grammar.

			axObj.WriteMemStr16Z(strPtr, str)
		end
	end
end
		
local H11 = function() -- from Bases__Item__ExplanationWindow__setItemId
	local ptr = axObj.GetGpr(gpr.a0)
	local a2 = axObj.GetGpr(gpr.a2)
	local valPtr = axObj.ReadMem32(ptr)
	local v1 = valPtr + 8
	local v0 = a2 * 4
	v0 = v0 + v1
	local strPtr = axObj.ReadMem32(v0)
	strPtr = strPtr + valPtr

	changeStrings(strPtr)
end

-- Skip Memory message when selecting "Delete Save Data" on "Save the adventure" dialogue.
local menuSkip = false
local H12 = function()		-- Bases__Talk__CommandCamp__showDialog
	menuSkip = true
end
local H13 = function()		-- Bases__Talk__CommandCamp__showDialog
	if menuSkip == true then
		axObj.SetGpr(gpr.v1, 0)
		menuSkip = false
	end
end
local H14 = function()		-- Bases__Talk__CommandCamp__showDialog
	if menuSkip == true then
		axObj.SetPC(0x88D908C)
	end
end


-- HOOKS --
local hook1  = axObj.AddHook(0x88E9564, 0x0002102B, H1)		-- Labo::Bases__Camp__Scene__updateTips
local hook2  = axObj.AddHook(0x899E718, 0x00403021, H2)		-- GameSystem__SaveDataController__setStateMessage
local hook3  = axObj.AddHook(0x897771C, 0x00431021, H3)		-- Localize__Manager__getLanguageName
local hook4  = axObj.AddHook(0x88774D0, 0x00402821, H4)		-- System::Util__BNDFile__doNameCallback
local hook5  = axObj.AddHook(0x886889C, 0x02002021, H5)		-- Labo::GameSystem__callbackFunc_MemoryObject
local hook6  = axObj.AddHook(0x898BCDC, 0x27BDFFE0, H6)		-- Sound__SubGame__Blacksmith__Command__start__4LaboFv
local hook7  = axObj.AddHook(0x89220F8, 0xAC80019C, H7)		-- Sound__BeatCommander__endSubGame__4LaboFv
local hook8  = axObj.AddHook(0x8A734DC, 0x27BDFFC0, H8)		-- GameSystem__Tips__Viewer__setup__4LaboFv
local hook9  = axObj.AddHook(0x899CF4C, 0x92637EED, H9)		-- GameSystem__SaveDataController__update__4LaboFv
local hook10 = axObj.AddHook(0x88E7E48, 0x2490009C, H10)	-- Utility__SaveDataUtility__setDataParamsfoString
local hook11 = axObj.AddHook(0x897CF90, 0x26041718, H11)	-- Bases__Item__ExplanationWindow__setItemId
local hook12 = axObj.AddHook(0x88D9114, 0xAEA00014, H12)	-- Bases__Talk__CommandCamp__showDialog
local hook13 = axObj.AddHook(0x88D90B4, 0x9063C550, H13)	-- Bases__Talk__CommandCamp__showDialog
local hook14 = axObj.AddHook(0x88D907C, 0x8FA2003C, H14)	-- Bases__Talk__CommandCamp__showDialog
local hook15 = axObj.AddHook(0x8A394B4, 0x26241718, H11)	-- Bases__Organization__Managed__ItemSelectWindow__onSlotChange (note uses H11)


-- US game bug fix.  "Paraget" -> "Patagate" --
axObj.AddHook(0x88DC5F4, 0x00409021, function() -- from Bases__Camp__Person__Behavior__Idle__update__4LaboFv
	local strPtr = axObj.GetGpr(gpr.v0) + 0xE	-- 0xE skip over X/Y positions.
	local str = axObj.ReadMemStr16(strPtr)
	
	if string.find(str, "The Paraget will") then
		-- org string: The Paraget will teleport you to/another world…
		local newStr = "The Patagate can teleport you to/another world…"
		axObj.WriteMemStr16Z(strPtr, newStr)
	elseif string.find(str, "Paraget Shrine") then
		-- org string: This is the Paraget Shrine./Only <N0> and <N1> can/enter.
		local newStr = "This is the Patagate Shrine/Only <N0> and <N1> can/enter."
		axObj.WriteMemStr16Z(strPtr, newStr)
	end
end)

--[[
axObj.AddHook(0x08982F48, 0x24070001, function()
	if emuObj.NeoMode() then
		axObj.SetGpr(gpr.a3, 0) -- turn on 60fps mode
	end
end)
]]--

--- MOVIE FIX ---
local movieLastTime = 0.0
local movieFix = function() -- Labo::GameSystem__MovieModule__render
	local t = axObj.GetFpr(0)
	if t == 0 and movieLastTime > 0 then
		local s0 = axObj.GetGpr(gpr.s0)
		axObj.WriteMemFloat(s0 + 0x44, movieLastTime)
	elseif t > 0 then
		movieLastTime = t
	end
end

axObj.AddHook(0x8A6A1DC, 0xe6000044, movieFix)


--- PAT2-16 FIX ---
axObj.AddHook(0x890E9E0, 0x02002021, function() -- Labo::Game__Gimmick__WindowAttacher__update
	local ptr = axObj.GetGpr(gpr.sp) + 0x28
	local posy = axObj.ReadMemFloat(ptr + 4)
	
	if posy < -30 then
		local obj = axObj.GetGpr(gpr.a0)
		axObj.WriteMem8(obj + 0x2a8, 0)
	end
end)