Talk:PSP Emulator Compatibility List: Difference between revisions
Jump to navigation
Jump to search
JSimesenmac (talk | contribs) |
|||
(35 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
=General= | =General= | ||
== | ==Custom PSPemu Configuration Files == | ||
<pre>Configuration files | |||
<pre> | |||
Configuration files created by users to improve PSP emulator compatibility on PS4. | |||
</pre> | |||
===God Of War - Ghost Of Sparta=== | |||
'''config-title.txt''' | |||
<br>UCUS98737 | |||
<pre> | |||
--antialias=off | |||
--godofwarhack=true | |||
--forcenobilinear=true | |||
</pre> | |||
'''LUA''' | |||
<br>UCUS98732 | |||
<pre> | |||
local axObj = getAXObject() | |||
local emuObj = getEmuObject() | |||
local patcher = function() | |||
axObj.WriteMem32(0x08A15210,0x24020000) | |||
end | |||
emuObj.AddVsyncHook(patcher) | |||
</pre> | |||
<pre> | |||
PPSSPP | |||
0881681C | |||
</pre> | |||
===God of War: Chains of Olympus=== | |||
'''config-title.txt''' | |||
<br>UCUS98653 | |||
<pre> | |||
--texclutmode=filter | |||
--bend-30hz-lock=1 | |||
--godofwarhack=true | |||
</pre> | |||
===Dante's Inferno=== | |||
'''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> | |||
===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> | </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> | <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> | </pre> | ||
Line 13: | Line 399: | ||
<pre>This is a list of configurations that were unsuccessful or were never completed, or information that might help people in the future. | <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> | 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=== | ===YU-GI-OH! 5D's Tag Force 4=== | ||
'''LUA''' | |||
<br>ULUS10481 | <br>ULUS10481 | ||
<pre> | <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> | </pre> |
Latest revision as of 03: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)