Editing Official Configuration Files
Jump to navigation
Jump to search
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 4: | Line 4: | ||
| type = style | | type = style | ||
| text = To Do: | | text = To Do: | ||
There should be something between 50 and 60 <nowiki>{{official}}</nowiki> <span class="plainlinks">[{{ps3wikiurl}}User_talk:Roxanne#Notebook "PS2 Classics"]</span> {{InvertibleImage|Icon_ps3.png|24px|This Article leads towards PS3 Developer Wiki}} released by Sony.<br>Are there duplicates used for several releases or why we list only | There should be something between 50 and 60 <nowiki>{{official}}</nowiki> <span class="plainlinks">[{{ps3wikiurl}}User_talk:Roxanne#Notebook "PS2 Classics"]</span> {{InvertibleImage|Icon_ps3.png|24px|This Article leads towards PS3 Developer Wiki}} released by Sony.<br>Are there duplicates used for several releases or why we list only 41 here? | ||
Please take a look. Thank you. | Please take a look. Thank you. | ||
}} | }} | ||
Line 10: | Line 10: | ||
====ADK Damashii==== | ====ADK Damashii==== | ||
<br> | '''CLI''' | ||
<br>SLPS-25906 | |||
<pre> | <pre> | ||
--gs-uprender=none | --gs-uprender=none | ||
Line 16: | Line 17: | ||
--force-frame-blend=1 | --force-frame-blend=1 | ||
</pre> | </pre> | ||
====Ape Escape 2==== | |||
<br>SCES-50885 | |||
<br>CLI | |||
<pre> | |||
--gs-use-mipmap=1 | |||
--gs-kernel-cl="mipmap" | |||
--gs-kernel-cl-up="mipmap2x2" | |||
--gs-scanout-offsetx=27 | |||
--vu1-injection=1 | |||
--gs-packed15-fmv-opt=1 | |||
--gs-skip-dirty-flush-on-mipmap=1 | |||
--cop2-accurate-addsub-range=0x3151e8,0x315414 | |||
</pre> | |||
<br>SCES-50885 | |||
<br>LUA | <br>LUA | ||
<pre> | <pre> | ||
local gpr = require("ee-gpr-alias") | |||
-- | require( "ee-hwaddr" ) | ||
-- | apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | ||
local eeObj = getEEObject() | |||
-- -- never gonna die | |||
-- eeInsnReplace( 0x2bd0a0, 0x27bdfff0, 0x03e00008) -- addiu sp,sp,-16 | |||
-- eeInsnReplace( 0x2bd0a4, 0x3c02003e, 0x00000000) -- lui v0,0x3e | |||
local | -- performance fix bug #9789 | ||
local emuObj = getEmuObject() | |||
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { } ) | |||
emuObj.SetGsTitleFix( "includeAreaUpdate", "reserved" , {alpha = 0x80000048 } ) | |||
emuObj.SetGsTitleFix( "ignoreUpRender", 50 , { } ) | |||
</pre> | |||
====Arc the Lad: Twilight of the Spirits™==== | |||
SCUS 972.31 | |||
<br>Cli | |||
<pre> | |||
--gs-force-bilinear=1 | |||
--gs-kernel-cl-up="up2x2Simple" | |||
--lopnor-config=1 | |||
</pre> | |||
SCUS 972.31 | |||
-- | <br>lua | ||
-- | <pre> | ||
require("ee-gpr-alias") | |||
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
eeObj = getEEObject() | |||
if | -- Bug#8359 (see bugzilla for the detail) | ||
-- Skip FadeSet call if map is 'Scrappe Plateau' and the latest loaded script file is 'evt03B_07_0.moc'. | |||
-- This game seems to have a problem (sensitive) with frame count on the script engine. | |||
-- On our emulator, frame counting is slightly different from the original. | |||
-- therefore it reads out 'overun' script command, which is 'cmd_fade' to fade-in. | |||
-- At here, we will skip FADE-IN command if the situation meets the requirement. | |||
skip_fade_flag = { map_name = false, file_name = false } | |||
if | -- fade skip Bug#8359. skip FadeSet if skip_fade_flag meets the requirement. | ||
eeObj.AddHook( 0x13c464, 0x8e0500c0, function() | |||
end | -- print(skip_fade_flag.map_name) | ||
-- print(skip_fade_flag.file_name) | |||
if skip_fade_flag.map_name and skip_fade_flag.file_name then | |||
-- print("SKIP FADE") | |||
eeObj.SetPc(0x13c470) | |||
skip_fade_flag.map_name = false | |||
skip_fade_flag.file_name = false | |||
end | |||
end) | |||
-- cmd_read_file(const char* filename) | |||
eeObj.AddHook(0x13dad0, 0x27bdffc0, function() | |||
local | local filename = eeObj.ReadMemStr(eeObj.GetGpr(gpr.a0)) | ||
-- print(string.format("cmd_read_file %s", filename)) | |||
if "chara/evt_camera/evt03B_07_0.moc" == filename then | |||
-- print("skip_fade!") | |||
-- | skip_fade_flag.file_name = true | ||
else | |||
skip_fade_flag.file_name = false | |||
end | |||
end) | |||
-- | -- cmd_map_name(const char* mapname) | ||
eeObj.AddHook(0x13f138, 0x0080282d, function() | |||
local mapname = eeObj.ReadMemStr(eeObj.GetGpr(gpr.a0)) | |||
local | -- print(string.format("cmd_map_name %s", mapname)) | ||
if "Scrappe Plateau" == mapname then | |||
-- print("skip_fade!") | |||
skip_fade_flag.map_name = true | |||
else | |||
skip_fade_flag.map_name = false | |||
end | |||
end) | |||
</pre> | |||
====Canis Canem Edit (Bully)==== | |||
<br>CLI | |||
<pre>--fpu-accurate-mul-fast=1 | |||
--fpu-muldiv-range=0x3fa5c0,0x3fa5c0 | |||
--gs-flush-ad-xyz=SafeZWrite | |||
--vu1-opt-vf00=2 | |||
--vu1-di-bits=0 | |||
--ee-hook=0x001f3ef4,FastForwardClock | |||
--gs-use-deferred-l2h=0 | |||
--vu1-injection=1 | |||
--vu1-mpg-cycles=2500 | |||
--fpu-rsqrt-fast-estimate=0 | |||
--safe-area-min=1.0</pre> | |||
SLES 535.61 | |||
<br>LUA | |||
<pre>apiRequest(0.1) | |||
local | -- EA sports cricket 07 bug 9392 | ||
local | -- Performance fix | ||
local emuObj = getEmuObject() | |||
local thresholdArea = 600 | |||
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80000044 , zmsk=1 , tw=4, th=4 } )</pre> | |||
SLUS-21269 | |||
<br>SLUS-21269_features.lua | |||
<pre>This is a substantial file. Over 150 lines with an extensive performance fix. I'm sharing the file itself as a download link. | |||
https://drive.google.com/file/d/12gt2fONqMP1rmEB9UMw3rIpEYbz1dQq8/view | |||
#Official widescreen support.</pre> | |||
====Destroy All Humans==== | |||
SLUS_209.45 | |||
<br>CLI | |||
<pre>--gs-use-mipmap=1 | |||
--gs-kernel-cl="mipmap" | |||
--gs-kernel-cl-up="mipmap2x2" | |||
--gs-ignore-dirty-page-border=1 | |||
--fpu-accurate-addsub-range=0x28bf00,0x28c100 | |||
#Fix for graphical glitches.</pre> | |||
SLUS_209.45 | |||
<br>SLUS-20945_features.lua | |||
<pre>-- Lua 5.3 | |||
-- Title: Destroy All Humans! PS2 - SLUS-20945 (USA) | |||
-- Author: Ernesto Corvi, Adam McInnis | |||
-- Changelog: | |||
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
local gpr = require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"]) | |||
local | -- Widescreen | ||
eeObj.AddHook(0x308270, 0x3c0336c5, function() -- Graphics::Script::SetScreenRatio | |||
local mode = eeObj.GetGpr(gpr.v0) | |||
-- print(string.format("mode: %08x", mode)) | |||
if mode == 0x36c59d2b then -- widescreen | |||
emuObj.SetDisplayAspectWide() | |||
elseif mode == 0x855a87ef then -- standard | |||
emuObj.SetDisplayAspectNormal() | |||
end | |||
end) | |||
eeObj.AddHook(0x3078F4, 0xae0000f4, function() -- Graphics::Renderer::Renderer | |||
local renderer = eeObj.GetGpr(gpr.s0) | |||
eeObj.WriteMemFloat(renderer+0x200, 1.3333333) | |||
eeObj.WriteMemFloat(renderer+0x204, 1.7777777) | |||
eeObj.WriteMem32(renderer+0x208, 2) | |||
end) | |||
emuObj.SetDisplayAspectWide() | |||
-- | -- CRC "settings.display.widescreen" = 0xbcf14d81 | ||
-- | -- $s2 = SaveType (1 = new save) | ||
local overlay = InsnOverlay({ | |||
0x27bdffe0, -- addiu $sp, -0x20 | |||
0xffbf0010, -- sd $ra, 0x10($sp) | |||
0x0c0d49d8, -- jal Core::Memset(void *,int,uint) | |||
0x00000000, -- nop | |||
0x24030001, -- li $v1, 1 | |||
0x1472000b, -- bne $s2, $v1, +11 | |||
0x00000000, -- nop | |||
0x0c09dacc, -- jal UFO::Progress::Get(void) | |||
0x00000000, -- nop | |||
0x3c01bcf1, -- lui $at, 0xbcf1 | |||
0x34214d81, -- ori $at, $at, 0x4d81 | |||
0xafa10000, -- sw $at, 0($sp) | |||
0x24030001, -- li $v1, 1 | |||
0xa3a30004, -- sb $v1, 4($sp) | |||
0x03a0282d, -- move $a1, $sp | |||
0x0c09dd4c, -- jal UFO::Progress::Record::AddKey(UFO::Progress::Content const&) | |||
0x0040202d, -- move $a0, $v0 | |||
0xdfbf0010, -- ld $ra, 0x10($sp) | |||
0x03e00008, -- jr $ra | |||
0x27bd0020 -- addiu $sp, 0x20 | |||
}) | |||
local call_overlay = 0x0c000000 | (overlay >> 2) | |||
eeInsnReplace(0x2789F8, 0x0c0d49d8, call_overlay) -- UFO::Progress::Storage::PrepareWrite | |||
#Official widescreen support.</pre> | |||
====Destroy All Humans 2==== | |||
SLUS_214.39 | |||
<br>CLI | |||
<pre>--gs-use-mipmap=1 | |||
--gs-kernel-cl="mipmap" | |||
--gs-kernel-cl-up="mipmap2x2" | |||
#Fix for graphical glitches.</pre> | |||
SLUS_214.39 | |||
<br>SLUS-21439_features.lua | |||
<pre>-- Lua 5.3 | |||
-- Title: Destroy All Humans! 2 PS2 - SLUS-21439 (USA) | |||
-- Author: Ernesto Corvi, Adam McInnis | |||
-- Changelog: | |||
apiRequest(0.7) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
local gpr = require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"]) | |||
local | -- Widescreen | ||
eeObj.AddHook(0x33ca98, 0x3c0436c5, function() -- Graphics::Script::SetScreenRatio | |||
local mode = eeObj.GetGpr(gpr.v0) | |||
-- print(string.format("mode: %08x", mode)) | |||
if mode == 0x36c59d2b then -- widescreen | |||
emuObj.SetDisplayAspectWide() | |||
elseif mode == 0x855a87ef then -- standard | |||
emuObj.SetDisplayAspectNormal() | |||
end | |||
end) | |||
eeObj.AddHook(0x33afac, 0x0000282d, function() -- Graphics::Renderer::Renderer | |||
eeObj.SetGpr(gpr.a1, 2) | |||
end) | |||
emuObj.SetDisplayAspectWide() | |||
-- | -- CRC "settings.display.anamorphic" = 0x8b36afe9 | ||
-- $s2 = SaveType (1 = new save) | |||
local overlay = InsnOverlay({ | |||
0x27bdffe0, -- addiu $sp, -0x20 | |||
0xffbf0010, -- sd $ra, 0x10($sp) | |||
0x0c059d02, -- memset | |||
0x00000000, -- nop | |||
0x24030001, -- li $v1, 1 | |||
0x1472000b, -- bne $s2, $v1, +11 | |||
0x00000000, -- nop | |||
0x0c09b400, -- jal UFO::Progress::Get(void) | |||
0x00000000, -- nop | |||
0x3c01bcf1, -- lui $at, 0x8b36 | |||
0x34214d81, -- ori $at, $at, 0xafe9 | |||
0xafa10000, -- sw $at, 0($sp) | |||
0x24030001, -- li $v1, 1 | |||
0xa3a30004, -- sb $v1, 4($sp) | |||
0x03a0282d, -- move $a1, $sp | |||
0x0c09dd4c, -- jal UFO::Progress::Record::AddKey(UFO::Progress::Content const&) | |||
0x0040202d, -- move $a0, $v0 | |||
0xdfbf0010, -- ld $ra, 0x10($sp) | |||
0x03e00008, -- jr $ra | |||
0x27bd0020 -- addiu $sp, 0x20 | |||
}) | |||
local call_overlay = 0x0c000000 | (overlay >> 2) | |||
eeInsnReplace(0x271AD0, 0x0c059d02, call_overlay) -- UFO::Progress::Storage::PrepareWrite | |||
-- | -- Disable Progressive Scan and Adjust Screen Position | ||
local overlay2 = InsnOverlay({ | |||
0x27bdfff0, -- addiu $sp, -0x10 | |||
0xffbf0000, -- sd $ra, 0(sp) | |||
0xffb00008, -- sd $s0, 8(sp) | |||
end | 0x3c05000f, -- lui $a1, 0x000f | ||
0x34a57000, -- ori $a1, 0x7000 | |||
0x0c0db8b6, -- jal Script::State::DoString | |||
0x0080802d, -- move $s0, $a0 | |||
0x24050001, -- li $a1, 1 | |||
0x0c0dba4c, -- jal Script::State::IsNull(int) | |||
0x0200202d, -- move $a0, $s0 | |||
0xdfb00008, -- ld $s0, 8(sp) | |||
0xdfbf0000, -- ld $ra, 0(sp) | |||
0x03e00008, -- jr ra | |||
0x27bd0010 -- addiu $sp, 0x10 | |||
}) | |||
local call_overlay2 = 0x0c000000 | (overlay2 >> 2) | |||
eeInsnReplace(0x2e5a14, 0x0c0dba4c, call_overlay2) -- Sim::Manager::ProcessScript near Sim::Manager::SetPauseFlag | |||
eeObj.AddHook(0x2e5a10, 0x0240202d, function() -- Sim::Manager::ProcessScript near Sim::Manager::SetPauseFlag | |||
local luaString = [[ | |||
-- disable progressive scan and adjust screen | |||
gui.i.SMOptionsDisplay.table.slots[3] = nil | |||
gui.i.SMOptionsDisplay.table.slots[4] = nil | |||
]] | |||
eeObj.WriteMemStrZ(0xf7000, luaString) | |||
end) | |||
#Official widescreen support.</pre> | |||
====Eternal ring==== | |||
'''CLI''' | |||
<pre> | |||
--pad-analog-to-digital=0 | |||
--gs-use-deferred-l2h=1 | |||
--host-display-mode=16:9 | |||
</pre> | |||
'''LUA''' | |||
<pre> | |||
local gpr = require("ee-gpr-alias") | |||
local PadStick = require("PadStick") | |||
apiRequest(1.5) | |||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
local | |||
local patcher = function() | |||
--X-Fov - ELF hack | |||
--803f013c 00a88144 0045013c | |||
eeObj.WriteMem32(0x00100fcc,0x3c013f40) --3c013f80 | |||
-- | --Memory hack | ||
-- | --eeObj.WriteMem32(0x201FF100,0x43c00000) | ||
end | end | ||
emuObj.AddVsyncHook(patcher) | |||
if 1 then | |||
-- bug#10361 (intro slowdown) & bug#9823 (conveyor belt effect) | |||
-- Use Deferred L2H except for conveyor belt effect. | |||
-- | -- Unsure if other convery or similar effects are present, so use permissive match for bypassing deferral. | ||
L2H_SetNonDeferred({TRXREG=0x0000000900000080}) -- match any TRXPOS or BITBLTBUF | |||
-- Full specification of conveyor belt effect. | |||
-- L2H_SetNonDeferred({BITBLTBUF=0x0000000013023240,TRXPOS=0x0000000000770000,TRXREG=0x0000000900000080}) | |||
end | end | ||
local | local PadStickRemap_EternalRing_Default = { | ||
LR=PadStick.AxisRX_Pos, | |||
LL=PadStick.AxisRX_Neg, | |||
LU=PadStick.AxisLY_Neg, | |||
LD=PadStick.AxisLY_Pos, | |||
L1=PadStick.AxisLX_Neg, | |||
R1=PadStick.AxisLX_Pos, | |||
L2=PadStick.AxisRY_Neg, | |||
R2=PadStick.AxisRY_Pos, | |||
} | |||
local | local PadStickRemap_EternalRing_InvertY = { | ||
L2=PadStick.AxisRY_Pos, | |||
R2=PadStick.AxisRY_Neg, | |||
} | |||
emuObj.PadPressureStickRemap(0, PadStickRemap_EternalRing_Default) | |||
-- Supporting Inverted Y Axis requires smoe menu changes, and should be done via features.lua | |||
--emuObj.PadPressureStickRemap(0, PadStickRemap_EternalRing_InvertY) </pre> | |||
====Everybody's Tennis/Hot Shots Tennis==== | |||
SCES_545.35 | |||
<br>CLI | |||
<pre>--gs-use-deferred-l2h=0 | |||
--l2h-2d-params=0x0000000800000010,0x00000000300a1400,256 | |||
--gs-motion-factor=50 | |||
--mtap1=always | |||
--gs-opt-frbuff-switch=1 | |||
--gs-ignore-dirty-page-border=1 | |||
--gs-ignore-rect-correction=1 | |||
--ee-native-function=memcpy,0x11e328 | |||
--ee-native-function=memset,0x11e4e0 | |||
#performance and visual fix(?)</pre> | |||
SCES_545.35 | |||
<br>LUA | |||
<pre>local gpr = require("ee-gpr-alias") | |||
require( "ee-hwaddr" ) | |||
apiRequest(1.4) | |||
local | local eeObj = getEEObject() | ||
-- function dump(addr) | |||
-- print(string.format("=== dump %x ===", addr)) | |||
-- for i=0,0x1e do | |||
-- print(string.format(" %08x : %08x %08x %08x %08x", | |||
-- addr + i*16, | |||
-- eeObj.ReadMem32(addr + i*16 + 0), | |||
-- eeObj.ReadMem32(addr + i*16 + 4), | |||
-- eeObj.ReadMem32(addr + i*16 + 8), | |||
-- eeObj.ReadMem32(addr + i*16 +12))) | |||
-- end | |||
-- end | |||
end | |||
-- Bug#8285 | |||
-- This patch changes the color of background on : | |||
-- - Language selection | |||
-- - Company logo | |||
-- - Start screen | |||
eeObj. | -- - Some menu | ||
-- which are in menu.bin overlay. Nothing affected in the actual game. | |||
eeObj.DmaAddHook( 1, function() | |||
if eeObj.ReadMem32(vif1_hw.TADR) == 0x1fd1c0 then | |||
-- On language select | |||
if eeObj.ReadMem32(0x4c8ef0) == 0x00ff9090 then | |||
eeObj.WriteMem32(0x4c8ef0, 0) | |||
end | |||
if eeObj.ReadMem32(0x548f30) == 0x00ff9090 then | |||
eeObj.WriteMem32(0x548f30, 0) | |||
end | |||
-- On company logo | |||
if eeObj.ReadMem32(0x4c6d70) == 0x00ff9090 then | |||
eeObj.WriteMem32(0x4c6d70, 0) | |||
end | |||
if eeObj.ReadMem32(0x546db0) == 0x00ff9090 then | |||
eeObj.WriteMem32(0x546db0, 0) | |||
end | |||
end | |||
end) | end) | ||
-- | eeInsnReplace(0x103d58, 0x27bdffc0, 0x03e00008) -- <SyncDCache> | ||
eeInsnReplace(0x103d5c, 0xffb20020, 0x00000000) | |||
eeNativeHook (0x103d58, 0x03e00008,'AdvanceClock',0x600) | |||
eeInsnReplace(0x103dd8, 0x3c02ffff, 0x03e00008) -- <iSyncDCache> | |||
eeInsnReplace(0x103ddc, 0x3442ffc0, 0x00000000) | |||
eeNativeHook (0x103dd8, 0x03e00008,'AdvanceClock',0x600) | |||
eeInsnReplace(0x103e98, 0x27bdffc0, 0x03e00008) -- <InvalidDCache> | |||
eeInsnReplace(0x103e9c, 0xffb20020, 0x00000000) | |||
eeNativeHook (0x103e98, 0x03e00008,'AdvanceClock',0x600) | |||
eeInsnReplace(0x103f18, 0x3c02ffff, 0x03e00008) -- <iInvalidDCache> | |||
eeInsnReplace(0x103f1c, 0x3442ffc0, 0x00000000) | |||
eeNativeHook (0x103f18, 0x03e00008,'AdvanceClock',0x600) | |||
eeInsnReplace(0x106970, 0x3c19ffff, 0x03e00008) -- <sceSifWriteBackDCache> | |||
eeInsnReplace(0x106974, 0x3739ffc0, 0x00000000) | |||
eeNativeHook (0x106970, 0x03e00008,'AdvanceClock',0x1700) | |||
</pre> | |||
====Fahrenheit/Indigo Prophecy==== | |||
SLES_535.39 | |||
<br>CLI | |||
<pre>--ee-hook=0x002097d0,FastForwardClock,0x8c6261fc | |||
--ee-hook=0x1a5570,AdvanceClock,,500000 | |||
--ee-hook=0x00223c48,AdvanceClock,0x0080382d,8000 | |||
--gs-kernel-cl="h2lpool" | |||
--gs-kernel-cl-up="h2lpool2x2" | |||
#Performance fix.</pre> | |||
SLES_535.39 | |||
<br>LUA | |||
<pre>This is a substantial file. Over 20,000 lines with an extensive performance fix. I'm sharing the file itself as a download link. | |||
https://drive.google.com/file/d/1L2YxondID65KIAybKVCBH9KgFegqqOeQ/view | |||
-- Performace fix (bug #9785 ) | |||
-- bug#8571 | |||
-- ignore 'no wait vsync' case. | |||
-- unsyncv causes major slowness on loading screen, because the game pushes LOTS of identical frame data to GS.</pre> | |||
-- | SLES_535.39 | ||
<br>SLES-53539_features.lua | |||
<pre>-- Lua 5.3 | |||
-- Title: Fahrenheit PS2 - SLES-53539 (EUR) | |||
-- Author: Ernesto Corvi, Adam McInnis | |||
-- Changelog: | |||
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"]) | |||
require( "ee-cpr0-alias" ) -- for EE CPR | |||
-- | |||
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
local | |||
local eeObj = | local L1 = function() -- QDT::SINT::SCRIPT_LOADING_SCREEN::EM::Run | ||
emuObj.ThrottleMax() | |||
end | |||
local L2 = function() -- QDT::SINT::SCRIPT_LOADING_SCREEN::EM::Stop | |||
emuObj.ThrottleNorm() | |||
end | |||
local load1 = eeObj.AddHook(0x387040, 0x3c02004b, L1) -- QDT::SINT::SCRIPT_LOADING_SCREEN::Run | |||
local load2 = eeObj.AddHook(0x387090, 0x3c02004b, L2) -- QDT::SINT::SCRIPT_LOADING_SCREEN::Stop | |||
-- | -- Widescreen | ||
eeInsnReplace(0x20a7c0, 0x3c013faa, 0x3c013fe3) | |||
eeInsnReplace(0x20a7c4, 0x3421aaab, 0x34218e39) | |||
emuObj.SetDisplayAspectWide() | |||
-- Skip video mode options | |||
local videomenuVM = { 0x04, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, | |||
0x3B, 0x0D, 0x00, 0x00, 0x3B, 0x0B, 0x00, 0x00, | |||
0x3B, 0x26, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 } | |||
local visualmenuVM = { 0x04, 0x01, 0x00, 0x00, 0xA2, 0x00, 0x00, 0x00, | |||
0x3B, 0x19, 0x00, 0x00, 0x3B, 0x18, 0x00, 0x00 } | |||
-- | -- locates src chunk on (dst,cnt). -1 if not found, offset if found | ||
local | local locateChunk = function(src, dst, count) | ||
local offs = -1 | |||
for x = 0, count - #src do | |||
if eeObj.ReadMem8(dst+x) == src[1] then | |||
local found = true | |||
for y = 1, #src do | |||
if eeObj.ReadMem8(dst+x+y-1) ~= src[y] then | |||
found = false | |||
break | |||
end | |||
end | |||
if found == true then | |||
offs = x | |||
break | |||
end | |||
end | |||
end | |||
return offs | |||
end | |||
eeObj.AddHook(0x2812b0, 0x27bdfff0, function() -- QDT::VM::BYTE_CODE::BYTE_CODE | |||
local obj = eeObj.GetGpr(gpr.a1) | |||
local bytecode = eeObj.ReadMem32(obj+0x18) | |||
local count = eeObj.ReadMem32(obj+0x20) | |||
if count > #videomenuVM then | |||
local offs = locateChunk(videomenuVM, bytecode, count) | |||
if offs >= 0 then | |||
print("Skipping video mode menu") | |||
eeObj.WriteMem8(bytecode+offs+4, 8) -- beq 0x44 -> beq 0x8 | |||
end | |||
end | |||
if count > #visualmenuVM then | |||
local offs = locateChunk(visualmenuVM, bytecode, count) | |||
if offs >= 0 then | |||
print("Skipping visual mode video menu") | |||
eeObj.WriteMem8(bytecode+offs+1, 2) -- beq 0xa2 -> bne 0xa2 | |||
end | |||
end | |||
end) | |||
-- Force 60hz | |||
eeInsnReplace(0x207ae0, 0x00a0802d, 0x24100001) -- move $s0, $a1 -> li $s0, 1 | |||
-- Fix for bug 9716, which is a bug in the game. | |||
-- Trying to retrieve a COM handle in the game will cause an infinite | |||
-- loop if the handle has been deallocated and the debug server is not | |||
-- connected. There's apparently a small race condition in the Asylum | |||
-- level that sometimes can trigger the bug. | |||
-- The fix involves getting out of the loop. | |||
-- It causes a small visual glitch but otherwise the game continues to work fine. | |||
eeInsnReplace(0x1c5958, 0x10400005, 0) -- QDT::KCOM::COM_SERVICE::RetrieveComHandle | |||
eeInsnReplace(0x1c5b6c, 0x10400005, 0) -- QDT::KCOM::COM_SERVICE::RetrieveComHandle | |||
==== | eeInsnReplace(0x1c5d24, 0x10400005, 0) -- QDT::KCOM::COM_SERVICE::RetrieveComHandle | ||
#Official widescreen support, forced 60Hz/NTSC, along with a game crash bug fix.</pre> | |||
<br> | ====Fantavision==== | ||
'''CLI''' | |||
<br>SCES-50002 | |||
<pre> | <pre> | ||
--gs-kernel-cl-up="fantavision" | |||
--gs-kernel-cl-up=" | --gs-motion-factor=1 | ||
-- | |||
</pre> | </pre> | ||
'''LUA''' | |||
<br>SCES-50002 | |||
<br> | |||
<pre> | <pre> | ||
require("ee-gpr-alias") | require("ee-gpr-alias") | ||
require( "ee-hwaddr" ) | |||
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | ||
eeObj = getEEObject() | eeObj = getEEObject() | ||
-- Bug# | -- | ||
-- | -- Bug#93709 (JP Bugzilla) | ||
-- | -- Same as Parappa the Rapper 2, it's VIF1 vs GIF xfer timing issue. | ||
-- | -- The game expects PATH3 happens before VU1 xgkick, but actually Olympus doesn't do like that. | ||
-- | -- Game kicks : PATH3(Context1) PATH1(Rendering using Context1&2) PATH3(Context2) | ||
-- Game expects: PATH3(Context1) PATH3(Context2) PATH1(Rendering using Context1&2) | |||
-- Hence VIF1 DMA needs to be delayed. | |||
eeObj.AddHook(0x1b1468, 0xae020000, function() | |||
local ee = eeObj | |||
local s0 = ee.GetGpr(gpr.s0) | |||
if s0 == vif1_hw.CHCR then | |||
local chcr = ee.GetGpr(gpr.v0) | |||
if (chcr & 0x05) == 0x05 then | |||
local tadr = ee.ReadMem32(vif1_hw.TADR) | |||
if tadr == 0x8883e0 or tadr == 0x9f6b60 then | |||
ee.SchedulerDelayEvent("vif1.dma", 0x5000) | |||
end | |||
end | |||
end | |||
end) | end) | ||
-- Performace fix | |||
local emuObj = getEmuObject() | |||
-- twIsLess=5 - texture width is less or eq. than 32 | |||
emuObj.SetGsTitleFix( "forcePointSampling", "reserved", {alpha = 0x80000048, twIsLess=5, thIsLess=5 } ) | |||
</pre> | </pre> | ||
==== | ====Fatal Fury: Battle Archives volume 2==== | ||
ALL | |||
<br>CLI | <br>CLI | ||
<pre>-- | <pre>--gs-uprender=none | ||
--gs-upscale=point | |||
--gs- | --host-audio-latency=0.010 | ||
-- | --force-frame-blend=1 | ||
#Graphical fix.</pre> | |||
-- | |||
- | |||
SLUS_217.23 | |||
<br> | <br>SLUS-21723_features.lua | ||
<pre> | <pre>This is a substantial file. Over 500 lines with additional controller/fightstick support and various shader/bezel files. I'm sharing the file itself as a download link. | ||
- | https://drive.google.com/file/d/1FPPPJiHOazTXaD-H6K3kLACYDSdDeAE1/view | ||
#official widescreen support in the form of screen bezels, along with expanded fightstick support and scanline shaders.</pre> | |||
====Fu'un Super Combo!!!==== | |||
SLPS_257.81 | |||
==== | |||
<br>CLI | <br>CLI | ||
<pre>--gs- | <pre>--gs-uprender=2x2 | ||
-- | --gs-upscale=point | ||
-- | --host-audio-latency=0.3 | ||
-- | --ee-hook=0x127050,AdvanceClock,0x2403002b,0x4000 | ||
-- | --ee-hook=0x106734,FastForwardClock,0x0c04149c | ||
# | --ee-native-function=memcpy,0x11fa9c,0x0080402d | ||
--force-frame-blend=1 | |||
--vif1-ignore-cmd-ints=1 | |||
#Graphical and performance fixes.</pre> | |||
SLPS_257.81 | |||
<br> | <br>LUA | ||
<pre> | <pre> | ||
apiRequest(1.4) | |||
eeNativeFunction(0x11fa9c, 0x0080402d, 'memcpy') | |||
eeNativeFunction(0x11fb48, 0x2cc20008, 'memset') | |||
eeInsnReplace(0x1279d0, 0x27bdffc0, 0x03e00008) -- <SyncDCache> | |||
eeInsnReplace(0x1279d4, 0xffb20020, 0x00000000) | |||
eeNativeHook (0x1279d0, 0x03e00008,'AdvanceClock',0xa00) | |||
eeInsnReplace(0x127b00, 0x27bdffc0, 0x03e00008) -- <InvalidDCache> | |||
eeInsnReplace(0x127b04, 0xffb20020, 0x00000000) | |||
eeNativeHook (0x127b00, 0x03e00008,'AdvanceClock',0xa00) | |||
eeInsnReplace(0x12a258, 0x3c19ffff, 0x03e00008) -- <sceSifWriteBackDCache> | |||
eeInsnReplace(0x12a25c, 0x3739ffc0, 0x00000000) | |||
eeNativeHook (0x12a258, 0x03e00008,'AdvanceClock',0x1700) | |||
require("ee-gpr-alias") | |||
local eeObj = getEEObject() | |||
eeObj | local emuObj = getEmuObject() | ||
-- *** viBufBeginPut (1) | |||
--eeInsnReplace(0x105628, 0x0c049c78, 0) -- jal 1271e0 <WaitSema> | |||
eeInsnReplace(0x1056c8, 0x0c049c70, 0) -- jal 1271c0 <SignalSema> | |||
-- *** viBufEndPut (1) | |||
eeInsnReplace(0x105708, 0x0c049c78, 0) -- jal 1271e0 <WaitSema> | |||
--eeInsnReplace(0x105730, 0x0c049c70, 0) -- jal 1271c0 <SignalSema> | |||
-- *** viBufFlush (1) | |||
--eeInsnReplace(0x105a88, 0x0c049c78, 0) -- jal 1271e0 <WaitSema> | |||
--eeInsnReplace(0x105ab8, 0x0c049c70, 0) -- jal 1271c0 <SignalSema> | |||
-- *** viBufPutTs (1) | |||
eeInsnReplace(0x105c10, 0x0c049c78, 0) -- jal 1271e0 <WaitSema> | |||
eeInsnReplace(0x105cf4, 0x0c049c70, 0) -- jal 1271c0 <SignalSema> | |||
-- it's redundant calling of _waitIpuIdle in libmpeg... not so huge impact tho. | |||
eeInsnReplace(0x118620, 0x0c04672a, 0) -- jal 119ca8 <_waitIpuIdle> | |||
-- | -- bug# 9972 | ||
local emuObj = getEmuObject() | |||
emuObj.SetGsTitleFix( "ignoreSubBuffCov", "reserved", { } ) | |||
#Crash/stall fixes.</pre> | |||
====Grand Theft Auto III==== | |||
SLUS_200.62 | |||
==== | |||
<br>CLI | <br>CLI | ||
<pre>--gs- | <pre>--vu1-no-clamping=0 | ||
--gs-kernel-cl=" | --gs-check-trans-rejection=1 | ||
--gs- | --gs-kernel-cl-up="up2x2tc" | ||
# | --gs-optimize-30fps=1 | ||
--ee-hook=0x27cea8,FastForwardClock | |||
#Performance and graphical fix.</pre> | |||
SLUS_200.62 | |||
<br>LUA | |||
<pre> | |||
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
-- Performace fix | |||
local emuObj = getEmuObject() | |||
local thresholdArea = 600 | |||
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80008068 , zmsk=1 } ) | |||
-- Bug#9133 | |||
-- workaround ... -16020(gp) value is something wrong. the value comes from CCamera::Process(). | |||
-- unfortunately accurate math or any other flags don't help for this problem, | |||
-- even though it should be calculation error issue. | |||
-- for here, it's just given 0 radian for CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension() | |||
-- actually the cloud is a billboard, so it should have 0 degree in view-space. | |||
-- so given 0 degree must be OK.... but could cause some corruption (wrong perspective or something) | |||
eeInsnReplace(0x318344, 0xc792c16c, 0x44809000) -- lwc1 $f18,-16020(gp) | |||
#Performance fix.</pre> | |||
SLUS_200.62 | |||
<br>SLUS- | <br>SLUS-20062_features.lua | ||
<pre>-- Lua 5.3 | <pre>-- Lua 5.3 | ||
-- Title: | -- Title: Grand Theft Auto III PS2 - SLUS-20062 (USA) v1.40 | ||
-- Author: | -- Author: Nicola Salmoria | ||
-- Date: November 3, 2015 | |||
-- | require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"]) | ||
apiRequest(0.7) -- | apiRequest(0.7) -- need widescreen support | ||
local eeObj = getEEObject() | local eeObj = getEEObject() | ||
local emuObj = getEmuObject() | local emuObj = getEmuObject() | ||
local USEWIDESCREEN_ADDRESS = 0x416748 | |||
local H1 = -- start of main() | |||
-- | function() | ||
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen | |||
end | end | ||
local H2 = -- change widescreen flag | |||
function() | |||
end | local isWidescreen = eeObj.GetGpr(gpr.v0) | ||
if isWidescreen == 0 then | |||
emuObj.SetDisplayAspectNormal() | |||
else | |||
emuObj.SetDisplayAspectWide() | |||
end | |||
end | |||
local hook1 = eeObj.AddHook(0x27ed04, 0x7fbf0000, H1) -- <main>: | |||
local hook2 = eeObj.AddHook(0x270e50, 0xa382b8d8, H2) -- <CMenuManager::AnaliseMenuContents(void)>: | |||
#Official widescreen support.</pre> | |||
====Grand Theft Auto: San Andreas==== | |||
SLUS_209.46 | |||
<br>CLI | |||
<pre>--gs-optimize-30fps=1 | |||
--ee-hook=0x34dee8,FastForwardClock | |||
--ee-hook=0x00245ee0,FastForwardClock | |||
--cop2-no-clamping=1 | |||
--gs-flush-ad-xyz=safe | |||
--vu1-clamp-range=0x04a,0x069 | |||
--gs-use-deferred-l2h=0 | |||
#Performance optimisation/fix.</pre> | |||
-- | SLUS_209.46 | ||
<br>LUA | |||
<pre>apiRequest(0.6) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
-- bug#8979 | |||
-- The game bugged. | |||
-- CStreaming::StreamPedsIntoRandomSlots(int*) expects 8 integers arrray to process, | |||
-- but CCheat::LoveConquersAllCheat() function copies just only 6 integers to the stack. | |||
-- it seems the table of the source is correct, so using lq/sq instead of ld/sd to copy | |||
-- the contents of the table correctly. | |||
eeInsnReplace(0x59fbb0, 0xdca20010, 0x78a20010) -- ld v0,16(a1) => lq | |||
eeInsnReplace(0x59fbb8, 0xfc820010, 0x7c820010) -- sd v0,16(a0) => sq | |||
-- bug#8979, actually different one | |||
-- the game has another bug... see https://pss.usrd.scea.com/bugzilla/show_bug.cgi?id=8979 | |||
eeInsnReplace(0x1abdd8, 0x102000d9, 0x102000cf) -- beqz at,1ac140 <CPopulation::AddPed(ePedType, unsigned int, CVector const &, bool)+0x3a0> | |||
eeInsnReplace( | |||
-- Performace fix | |||
local emuObj = getEmuObject() | |||
local thresholdArea = 700 | |||
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80000044 , zmsk=1 } ) | |||
#Performance and rendering fixes.</pre> | |||
# | |||
SLUS_209.46 | |||
<br>SLUS-20946_features.lua | |||
<pre> | <pre>-- Lua 5.3 | ||
-- Title: Grand Theft Auto: San Andreas - SLUS-20946 (USA) v3.00 | |||
-- | -- Author: Nicola Salmoria | ||
-- | -- Date: November 5, 2015 | ||
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"]) | |||
apiRequest(0.7) -- need widescreen support | |||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
local USEWIDESCREEN_ADDRESS = 0x7004ef | |||
local H1 = -- init widescreen flag | |||
function() | |||
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen | |||
end | |||
local H2 = -- main game loop | |||
function() | |||
local isWidescreen = eeObj.ReadMem8(USEWIDESCREEN_ADDRESS) | |||
if isWidescreen == 0 then | |||
emuObj.SetDisplayAspectNormal() | |||
else | |||
emuObj.SetDisplayAspectWide() | |||
end | |||
end | |||
local hook1 = eeObj.AddHook(0x233584, 0xa200004f, H1) -- <CMenuManager::__ct(void)>: | |||
local hook2 = eeObj.AddHook(0x246750, 0x24040012, H2) -- <TheGame(void)>: | |||
#Official widescreen support.</pre> | |||
====Grand Theft Auto: Vice City==== | |||
SLUS_205.52 | |||
<br>CLI | |||
<pre>--gs-check-trans-rejection=1 | |||
--gs-kernel-cl-up="up2x2tc" | |||
--gs-optimize-30fps=1 | |||
--ee-hook=0x277b88,FastForwardClock | |||
--ee-hook=0x279a18,FastForwardClock | |||
</pre> | |||
SLUS_205.52 | |||
<br>LUA | |||
<pre> | |||
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
emuObj. | -- Performance fix | ||
local emuObj = getEmuObject() | |||
local thresholdArea = 600 | |||
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80008068 , zmsk=1 } ) | |||
-- | -- Bug#9147 | ||
-- | -- workaround ... -2104(gp) value is something wrong. the value comes from CCamera::Process(). | ||
-- unfortunately accurate math or any other flags don't help for this problem, | |||
-- even though it should be calculation error issue. | |||
-- for here, it's just given 0 radian for CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension() | |||
-- actually the cloud is a billboard, so it should have 0 degree in view-space. | |||
-- so given 0 degree must be OK.... but could cause some corruption (wrong perspective or something) | |||
-- | eeInsnReplace(0x334d64, 0xc792f7c8, 0x44809000) -- lwc1 $f18,-2104(gp) | ||
-- | #Performance fix.</pre> | ||
-- | |||
-- | |||
-- | |||
- | |||
# | |||
SLUS_205.52 | |||
<br> | <br>SLUS-20552_features.lua | ||
<pre> | <pre>-- Lua 5.3 | ||
-- Title: Grand Theft Auto: Vice City - SLUS-20552 (USA) v3.00 | |||
-- Author: Nicola Salmoria | |||
-- Date: November 4, 2015 | |||
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"]) | |||
-- | |||
-- | apiRequest(0.7) -- need widescreen support | ||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
-- | |||
local USEWIDESCREEN_ADDRESS = 0x4ba7bc | |||
local H1 = -- start of main() | |||
function() | |||
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen | |||
end | |||
local H2 = -- main game loop | |||
function() | |||
local isWidescreen = eeObj.ReadMem8(USEWIDESCREEN_ADDRESS) | |||
if isWidescreen == 0 then | |||
emuObj.SetDisplayAspectNormal() | |||
else | |||
emuObj.SetDisplayAspectWide() | |||
end | |||
end | |||
-- | local hook1 = eeObj.AddHook(0x279384, 0xffbf0000, H1) -- <main>: | ||
local hook2 = eeObj.AddHook(0x277784, 0x00000000, H2) -- <TheGame(void)>: | |||
-- | -- Fix for bug #9161. The 'flying cars' cheat causes crashes when attempting to | ||
-- fly an helicopter. We avoid that by disabling recognition of the cheat altogether. | |||
-- The SLPM version comes with the cheat disabled out of the box. | |||
eeInsnReplace(0x27db2c, 0x14400015, 0x10000015) -- bnez -> b | |||
-- | #Official widescreen support and removal of "flying cars" cheat due to game crash.</pre> | ||
SCES_503.61 | |||
<br>LUA | |||
<pre>-- Jak EU | |||
apiRequest(2.2) | |||
-- | local gpr = require("ee-gpr-alias") | ||
local emuObj = getEmuObject()vi | |||
local eeObj = getEEObject() | |||
local gsObj = getGsObject() | |||
local eeOverlay = eeObj.getOverlayObject() | |||
-- | -- Disable internal field shift compensation, part of post-process removal feature. | ||
gsObj.SetDeinterlaceShift(0) | |||
-- Fix shadow | |||
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1 } ) | |||
-- | |||
-- | -- Reduce flush count | ||
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1 } ) | |||
-- Disable post-processing | |||
-- update: removed due to occasional regression (bug#10608). post-processing is now skipped in the EE via 'depth-cue' | |||
-- emuObj.SetGsTitleFix( "ignoreSprite", "reserved", { texType=1 , tw=5 , th=8, zmsk=1 , alpha=0x80000044 } ) | |||
-- ------------------------- OVERLAY MANAGER -------------------------- | |||
g_OnOverlayRegistered = function(filename, start, size) | |||
-- global function provided for adding per-overlay callback handlers. | |||
end | |||
local eeObj = | local DH8 = function() | ||
local | local s0 = eeObj.GetGpr(gpr.s0) | ||
local linkblock = eeObj.ReadMem32(s0+0x5c) | |||
local | |||
--print( string.format("--> PRELOAD %08x %08x",s0, linkblock) ) | |||
local linkblock_allocate_length = eeObj.ReadMem32 (linkblock + 0x00) | |||
local linkblock_allocate_version = eeObj.ReadMem32 (linkblock + 0x04) | |||
local linkblock_allocate_segment_count = eeObj.ReadMem32 (linkblock + 0x08) | |||
local linkblock_allocate_name = eeObj.ReadMemStr(linkblock + 0x0c) | |||
local | local linkblock_allocate_seg1_linkptr = eeObj.ReadMem32 (linkblock + 0x4C) | ||
local linkblock_allocate_seg1_dataptr = eeObj.ReadMem32 (linkblock + 0x50) | |||
local linkblock_allocate_seg1_size = eeObj.ReadMem32 (linkblock + 0x54) | |||
local linkblock_allocate_seg1_flags = eeObj.ReadMem32 (linkblock + 0x58) | |||
local linkblock_allocate_seg2_linkptr = eeObj.ReadMem32 (linkblock + 0x5C) | |||
local linkblock_allocate_seg2_dataptr = eeObj.ReadMem32 (linkblock + 0x60) | |||
local linkblock_allocate_seg2_size = eeObj.ReadMem32 (linkblock + 0x64) | |||
local linkblock_allocate_seg2_flags = eeObj.ReadMem32 (linkblock + 0x68) | |||
local linkblock_allocate_seg3_linkptr = eeObj.ReadMem32 (linkblock + 0x6C) | |||
local linkblock_allocate_seg3_dataptr = eeObj.ReadMem32 (linkblock + 0x70) | |||
local linkblock_allocate_seg3_size = eeObj.ReadMem32 (linkblock + 0x74) | |||
local linkblock_allocate_seg3_flags = eeObj.ReadMem32 (linkblock + 0x78) | |||
-- seg1 is equiv to main in Jak3 | |||
-- seg3 is equiv to top in Jak3 | |||
-- seg2 appears to be unused ... ? --jstine | |||
-- | if emuObj.IsToolingVerbose() then | ||
print( string.format("--> LOADED SEGMENT alloc_len %08x ver %08x segcount %08x name:\"%s\"", linkblock_allocate_length, linkblock_allocate_version, linkblock_allocate_segment_count, linkblock_allocate_name) ) | |||
print( string.format(" seg1linkptr %08x seg1dataptr %08x seg1size %08x seg1flags %08x", linkblock_allocate_seg1_linkptr, linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, linkblock_allocate_seg1_flags) ) | |||
print( string.format(" seg2linkptr %08x seg2dataptr %08x seg2size %08x seg2flags %08x", linkblock_allocate_seg2_linkptr, linkblock_allocate_seg2_dataptr, linkblock_allocate_seg2_size, linkblock_allocate_seg2_flags) ) | |||
print( string.format(" seg3linkptr %08x seg3dataptr %08x seg3size %08x seg3flags %08x", linkblock_allocate_seg3_linkptr, linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, linkblock_allocate_seg3_flags) ) | |||
end | |||
if linkblock_allocate_seg1_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg1", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, false) end | |||
-- | if linkblock_allocate_seg3_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg3", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, true) end | ||
if (g_OnOverlayRegistered ~= nil) then | |||
-- Make sure to execute any previously registered OnOverlay handler | |||
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg1", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size) end | |||
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg3", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size) end | |||
end | |||
end | |||
assert(g_OnOverlayRegistered ~= nil) | |||
local prev_OnOverlayRegistered = g_OnOverlayRegistered | |||
< | g_OnOverlayRegistered = function(filename, start, size) | ||
if filename == "depth-cue.seg1" then | |||
-- Disable full-screen post process via depth-cue. | |||
-- This also removes half-pixel shift during interlacing. | |||
-- <depth-cue.seg1+00039c> | |||
-- 00701DFC:67BDFFF0 daddiu $sp,$sp,-0x10 (0xfffffff0) -> 03E00008 jr $ra | |||
-- 00701E00:FFBE0008 sd $fp,8($sp) -> 00000000 nop | |||
eeObj.WriteMem32(start + 0x39c, 0x03E00008) | |||
eeObj.WriteMem32(start + 0x3a0, 0x00000000) | |||
eeObj.WriteMem32(start + 0x004, 0x03E00008) | |||
eeObj.WriteMem32(start + 0x008, 0x00000000) | |||
end | |||
if (prev_OnOverlayRegistered ~= nil) then | |||
-- Make sure to execute any previously registered OnOverlay handler | |||
prev_OnOverlayRegistered(filename, start, size) | |||
end | |||
end | |||
-- | -- hooked in link_control::finish(void)>: | ||
eeObj.AddHook(0x0010ACF8, 0x040C825, DH8) -- this is address US:0010abe0 JP:0010abd8 EU:0010ACF8 | |||
#Graphical fix, removal of intensive post process effects.</pre> | |||
eeObj.AddHook( | |||
SCES-50361 | |||
<br>SCES-50361_features.lua | |||
<pre>This is a substantial file. Over 700 lines with an extensive graphical and control fix. I'm sharing the file itself as a download link. | |||
https://drive.google.com/file/d/1KppgZpiK5bgESrpSRKo6kKPTysZ-NAC9/view | |||
#Shadows fix, control scheme changes, forced 60Hz/NTSC/Widescreen.</pre> | |||
</pre> | |||
==== | ====Harvest Moon®: A Wonderful Life Special Edition==== | ||
CUSA06584 | |||
<br>CLI | <br>CLI | ||
<pre> | <pre> | ||
-- | --ee-cycle-scalar=0.78 | ||
</pre> | </pre> | ||
CUSA06584 | |||
<br>LUA | <br>LUA | ||
<pre> | <pre> | ||
apiRequest (1.7) | |||
local eeObj = getEEObject() | |||
local gpr = require("ee-gpr-alias") | |||
-- 00107be0 <syncV>: idle loop on vsync | |||
eeNativeHook (0x107c14, 0x3c03005d,"FastForwardClock", 0) | |||
eeNativeFunction(0x44f3f8, 0x27bdffd0, 'ieee754_acosf') | |||
eeNativeFunction(0x44f820, 0x27bdffd0, 'ieee754_asinf') | |||
eeNativeFunction(0x450930, 0x44036000, 'ieee754_sqrtf') | |||
eeNativeFunction(0x452848, 0x0080102d, 'fabs') | |||
eeNativeFunction(0x453080, 0x27bdffd0, 'cosf') | |||
eeNativeFunction(0x453158, 0x27bdfff0, 'fabsf') | |||
eeNativeFunction(0x453320, 0x27bdffd0, 'sinf') | |||
eeNativeFunction(0x4534b0, 0x27bdfff0, 'acosf') | |||
eeNativeFunction(0x4534c8, 0x27bdfff0, 'asinf') | |||
eeNativeFunction(0x453510, 0x27bdfff0, 'sqrtf') | |||
eeNativeFunction(0x4552d8, 0x27bdffd0, 'fptoui') | |||
eeNativeFunction(0x455298, 0x27bdffd0, 'fptodp') | |||
eeNativeFunction(0x455d48, 0x27bdffd0, 'litodp') | |||
eeNativeFunction(0x455e00, 0x27bdffc0, 'dptoli') | |||
eeNativeFunction(0x455ed0, 0x27bdffc0, 'dptofp') | |||
eeNativeFunction(0x45d580, 0x0080402d, 'memcpy') | |||
eeNativeFunction(0x45d738, 0x2cc20008, 'memset') | |||
eeNativeFunction(0x45fde8, 0x30820007, 'strlen') | |||
eeInsnReplace(0x4443e0, 0x24030064, 0x03e00008) -- <FlushCache> | |||
eeInsnReplace(0x4443e4, 0x0000000c, 0x00000000) | |||
eeNativeHook (0x4443e0, 0x03e00008,'AdvanceClock',0x800) | |||
eeInsnReplace(0x444410, 0x2403ff98, 0x03e00008) -- <iFlushCache> | |||
eeInsnReplace(0x444414, 0x0000000c, 0x00000000) | |||
eeNativeHook (0x444410, 0x03e00008,'AdvanceClock',0x800) | |||
eeInsnReplace(0x444a58, 0x27bdffc0, 0x03e00008) -- <SyncDCache> | |||
eeInsnReplace(0x444a5c, 0xffb20020, 0x00000000) | |||
eeNativeHook (0x444a58, 0x03e00008,'AdvanceClock',0x800) | |||
eeInsnReplace(0x444b98, 0x27bdffc0, 0x03e00008) -- <InvalidDCache> | |||
eeInsnReplace(0x444b9c, 0xffb20020, 0x00000000) | |||
eeNativeHook (0x444b98, 0x03e00008,'AdvanceClock',0x800) | |||
-- | -- bug#10318 : workaround... | ||
eeObj.AddHook(0x3ce0fc, 0x0200202d, function() | |||
local sign = (eeObj.GetGpr(gpr.v1) >> 31) & 1 | |||
local | if sign then | ||
eeObj.SetPc(0x3ce118) | |||
end | |||
end) | |||
-- - | </pre> | ||
local | ====Jak 3==== | ||
local | '''LUA''' | ||
<br>SCUS-97330 | |||
<pre> | |||
apiRequest(2.3) | |||
local gpr = require("ee-gpr-alias") | |||
local emuObj = getEmuObject() | |||
local eeObj = getEEObject() | |||
local gsObj = getGsObject() | |||
local eeOverlay = eeObj.getOverlayObject() | |||
-- Fix shadow | |||
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1 } ) | |||
-- Reduce flush count | |||
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1 } ) | |||
-- Disabled due to embossing effect problem --jstine | |||
--emuObj.SetGsTitleFix( "trianglesAsParticles", "reserved", { hasClut=1,zmsk=1 } ) | |||
-- All JAK titles have a silly way of obtaining the PS2 Timestamp Counter. A binary code snippet is written | |||
-- into a NON-CONST array, like so: static u32 getTSC[] = { 0x40024800, 0x03E00008 }; and then that snippet is | |||
-- called via: ((u32 (*)())getTSC)() | |||
-- | |||
-- Actual disasm of snippet: | |||
-- 129780:40024800 mfc0 $v0,$count | |||
-- 129784:03E00008 jr $ra | |||
-- | |||
-- Because the code is right next to data in the .data section of the process, the emulator's page fault protection | |||
-- gets tripped up constantly and the code must be re-validated on every invocation. Interesting aside: had the devs | |||
-- marked the array as 'const' and thus had it placed in .ro_data, there wouldn't be a perf issue in the emu since | |||
-- page invalidations only occur on writes. | |||
-- | |||
-- Solution: rewrite the code which calls this function to simply execute mfc0 inline instead. Typical pattern which | |||
-- invokes the PS2 TSC read: | |||
-- 108c80:8c629790 lw v0,-26736(v1) | |||
-- 108c84:0040f809 jalr v0 | |||
-- Replace four separate instances: | |||
eeInsnReplace(0x108a78, 0x8c629790, 0x40024800) -- lw v0,-26736(v1) -> mfc0 $v0,$count | |||
eeInsnReplace(0x108a7c, 0x0040f809, 0x00000000) -- jalr v0 -> jr $ra | |||
eeInsnReplace(0x108c80, 0x8c629790, 0x40024800) -- lw v0,-26736(v1) -> mfc0 $v0,$count | |||
eeInsnReplace(0x108c84, 0x0040f809, 0x00000000) -- jalr v0 -> jr $ra | |||
eeInsnReplace(0x108ea4, 0x8c629790, 0x40024800) -- lw v0,-26736(v1) -> mfc0 $v0,$count | |||
eeInsnReplace(0x108ea8, 0x0040f809, 0x00000000) -- jalr v0 -> jr $ra | |||
eeInsnReplace(0x10902c, 0x8c629790, 0x40024800) -- lw v0,-26736(v1) -> mfc0 $v0,$count | |||
eeInsnReplace(0x109030, 0x0040f809, 0x00000000) -- jalr v0 -> jr $ra | |||
-- ------------------------- OVERLAY MANAGER -------------------------- | |||
g_OnOverlayRegistered = function(filename, start, size) | |||
-- global function provided for adding per-overlay callback handlers. | |||
end | end | ||
local DH8 = function() | |||
local s1 = eeObj.GetGpr (gpr.s1) | |||
local filename = eeObj.ReadMemStr(s1 + 17) | |||
local segment = eeObj.ReadMem32 (s1 + 8) | |||
local main = eeObj.ReadMem32 (segment + 4) | |||
local mainSize = eeObj.ReadMem32 (segment + 8) | |||
local top = eeObj.ReadMem32 (segment + 36) | |||
local topSize = eeObj.ReadMem32 (segment + 40) | |||
if emuObj.IsToolingVerbose() then | |||
print( string.format("--> LOADED SEGMENT \"%s\" MAIN %08x size %x TOP %08x size %x", filename, main, mainSize, top, topSize) ) | |||
if | |||
end | end | ||
eeOverlay.Register(filename .. ".main", main, mainSize, false) | |||
eeOverlay.Register(filename .. ".top", top, topSize, true ) | |||
local | --local debugObj = getDebugObject() | ||
--debugObj.eDumpDisasmToFile ("./DisasmGoal/Jak3/" .. filename .. ".main.dasm", main, mainSize, 0) | |||
--debugObj.eDumpDisasmToFile ("./DisasmGoal/Jak3/" .. filename .. ".top.dasm", top, topSize, 0) | |||
--debugObj.eDumpAotToFile ("./DisasmGoal/Jak3/" .. filename .. ".main.aot", main, mainSize, 0) | |||
--debugObj.eDumpAotToFile ("./DisasmGoal/Jak3/" .. filename .. ".top.aot", top, topSize, 0) | |||
if (g_OnOverlayRegistered ~= nil) then | |||
-- Make sure to execute any previously registered OnOverlay handler | |||
g_OnOverlayRegistered(filename .. ".main", main, mainSize) | |||
g_OnOverlayRegistered(filename .. ".top", top, topSize ) | |||
end | |||
end | |||
eeObj.AddHook(0x1091d4, 0x0080c825, DH8) -- <ndi::link_control::finish(void)>: | |||
-- | -- -------------------------------------------------------------------- | ||
-- | assert(g_OnOverlayRegistered ~= nil) | ||
local prev_OnOverlayRegistered = g_OnOverlayRegistered | |||
if | g_OnOverlayRegistered = function(filename, start, size) | ||
if (prev_OnOverlayRegistered ~= nil) then | |||
-- Make sure to execute any previously registered OnOverlay handler | |||
prev_OnOverlayRegistered(filename, start, size) | |||
end | end | ||
if | if filename == "sparticle-launcher.main" then | ||
-- this RNG-sqrt instance is removed for performance. Additionally, not corrupting the RNG seed with | |||
-- bad sqrt math is always a good thing in my book --jstine | |||
assert(eeObj.ReadMem32(start + 0x005de4) == 0x4be1043d) -- vrget.wxyz vf01,r | |||
assert(eeObj.ReadMem32(start + 0x005de8) == 0x4a0103bd) -- vsqrt q,vf01x | |||
assert(eeObj.ReadMem32(start + 0x005df0) == 0x4b0000a0) -- vaddq.x vf02,vf00,q | |||
assert(eeObj.ReadMem32(start + 0x005e4c) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x005ef8) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x005f80) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x006018) == 0x4a00143f) -- vrxor r,vf02x | |||
eeObj.WriteMem32(start + 0x005de4, 0x00000000) | |||
eeObj.WriteMem32(start + 0x005de8, 0x00000000) | |||
eeObj.WriteMem32(start + 0x005df0, 0x00000000) | |||
eeObj.WriteMem32(start + 0x005e4c, 0x00000000) | |||
eeObj.WriteMem32(start + 0x005ef8, 0x00000000) | |||
eeObj.WriteMem32(start + 0x005f80, 0x00000000) | |||
eeObj.WriteMem32(start + 0x006018, 0x00000000) | |||
end | end | ||
end | |||
-- -------------------------------------------------------------------------------------- | |||
-- diagnostic for checking the Jak engine's internal frame skipping mechanism. | |||
-- $fp30 contains a ratio of time-taken-to-16ms to render the scene, eg. 18 ms is approx 1.15. | |||
-- The engine will proceed to make a series of logical decisions according to this value. | |||
-- The value read out here will be affected by both EE cycle rates and adaptive GS penalties. | |||
-- I tried modifiying this value directly but it gives somewhat unsatisfactory results. | |||
local | -- eeOverlay.AddPreHook("drawable.main",0x208+8, 0x461E0034, function() | ||
-- local v1 = eeObj.GetGpr(gpr.v1) | |||
-- print(string.format("fpuCompare fpr0=%f fpr30=%f", eeObj.GetFpr(0), eeObj.GetFpr(30))) | |||
-- end) | |||
-- -------------------------------------------------------------------------------------- | |||
</pre> | |||
====Jak 2==== | |||
'''CLI''' | |||
<br>SCUS-97265 | |||
<pre> | |||
--ee-jit-pagefault-threshold=20 | |||
--gs-frontend-opt-mode=1 | |||
--gs-use-mipmap=1 | |||
--gs-kernel-cl="mipmap" | |||
--gs-kernel-cl-up="mipmap2x2" | |||
--cop2-no-clamping=1 | |||
--cop2-clamp-range=0x2A18,0x2a20,joint.seg1 | |||
--vu1-mpg-cycles=250 | |||
</pre> | |||
'''LUA''' | |||
<br>SCUS-97265 | |||
<pre> | |||
apiRequest(2.2) | |||
-- | local gpr = require("ee-gpr-alias") | ||
local emuObj = getEmuObject() | |||
local eeObj = getEEObject() | |||
local eeOverlay = eeObj.getOverlayObject() | |||
local iopObj = getIOPObject() | |||
local gsObj = getGsObject() | |||
-- | -- Fix shadow | ||
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1 } ) | |||
-- Reduce flush count | |||
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1 } ) | |||
--------------------------------------------------------------------------------- | |||
-- Basic Block breakers for EE AOT Injection | |||
eeOverlay.AddPreHook("traffic-engine.seg1", 0x004474, 0x0080e025, "nop" ) | |||
eeOverlay.AddPreHook("spatial-hash.seg1", 0x004474, 0x0080e025, "nop" ) | |||
--------------------------------------------------------------------------------- | |||
-- | -- ------------------------- OVERLAY MANAGER -------------------------- | ||
-- | g_OnOverlayRegistered = function(filename, start, size) | ||
-- global function provided for adding per-overlay callback handlers. | |||
-- | |||
end | end | ||
local DH8 = function() | |||
local s0 = eeObj.GetGpr(gpr.s0) | |||
local linkblock = eeObj.ReadMem32(s0+0x60) -- was 0x5c on Jak1 | |||
--print( string.format("--> PRELOAD %08x %08x",s0, linkblock) ) | |||
local linkblock_allocate_length = eeObj.ReadMem32 (linkblock + 0x00) | |||
local linkblock_allocate_version = eeObj.ReadMem32 (linkblock + 0x04) | |||
local linkblock_allocate_segment_count = eeObj.ReadMem32 (linkblock + 0x08) | |||
local linkblock_allocate_name = eeObj.ReadMemStr(linkblock + 0x0c) | |||
local linkblock_allocate_seg1_linkptr = eeObj.ReadMem32 (linkblock + 0x4C) | |||
local linkblock_allocate_seg1_dataptr = eeObj.ReadMem32 (linkblock + 0x50) | |||
local linkblock_allocate_seg1_size = eeObj.ReadMem32 (linkblock + 0x54) | |||
local linkblock_allocate_seg1_flags = eeObj.ReadMem32 (linkblock + 0x58) | |||
local linkblock_allocate_seg2_linkptr = eeObj.ReadMem32 (linkblock + 0x5C) | |||
local linkblock_allocate_seg2_dataptr = eeObj.ReadMem32 (linkblock + 0x60) | |||
local linkblock_allocate_seg2_size = eeObj.ReadMem32 (linkblock + 0x64) | |||
local linkblock_allocate_seg2_flags = eeObj.ReadMem32 (linkblock + 0x68) | |||
local linkblock_allocate_seg3_linkptr = eeObj.ReadMem32 (linkblock + 0x6C) | |||
local linkblock_allocate_seg3_dataptr = eeObj.ReadMem32 (linkblock + 0x70) | |||
local linkblock_allocate_seg3_size = eeObj.ReadMem32 (linkblock + 0x74) | |||
local linkblock_allocate_seg3_flags = eeObj.ReadMem32 (linkblock + 0x78) | |||
-- seg1 is equiv to main in Jak3 | |||
-- seg3 is equiv to top in Jak3 | |||
-- seg2 appears to be unused ... ? --jstine (it's a debug segment, so likely unused on retail) DH | |||
if emuObj.IsToolingVerbose() then | |||
print( string.format("--> LOADED SEGMENT alloc_len %08x ver %08x segcount %08x name:\"%s\"", linkblock_allocate_length, linkblock_allocate_version, linkblock_allocate_segment_count, linkblock_allocate_name) ) | |||
print( string.format(" seg1linkptr %08x seg1dataptr %08x seg1size %08x seg1flags %08x", linkblock_allocate_seg1_linkptr, linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, linkblock_allocate_seg1_flags) ) | |||
print( string.format(" seg2linkptr %08x seg2dataptr %08x seg2size %08x seg2flags %08x", linkblock_allocate_seg2_linkptr, linkblock_allocate_seg2_dataptr, linkblock_allocate_seg2_size, linkblock_allocate_seg2_flags) ) | |||
print( string.format(" seg3linkptr %08x seg3dataptr %08x seg3size %08x seg3flags %08x", linkblock_allocate_seg3_linkptr, linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, linkblock_allocate_seg3_flags) ) | |||
end | |||
local | -- local debugObj = getDebugObject() | ||
-- debugObj.eDumpDisasmToFile("./DisasmGoal/JakII/" .. linkblock_allocate_name .. ".seg1.dasm", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, 0) | |||
-- debugObj.eDumpDisasmToFile("./DisasmGoal/JakII/" .. linkblock_allocate_name .. ".seg3.dasm", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, 0) | |||
-- debugObj.eDumpAotToFile ("./DisasmGoal/JakII/" .. linkblock_allocate_name .. ".seg1.aot", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, 0) | |||
-- debugObj.eDumpAotToFile ("./DisasmGoal/JakII/" .. linkblock_allocate_name .. ".seg3.aot", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, 0) | |||
if linkblock_allocate_seg1_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg1", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, false) end | |||
if linkblock_allocate_seg3_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg3", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, true) end | |||
if (g_OnOverlayRegistered ~= nil) then | |||
-- Make sure to execute any previously registered OnOverlay handler | |||
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg1", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size) end | |||
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg3", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size) end | |||
end | |||
end | end | ||
assert(g_OnOverlayRegistered ~= nil) | |||
local prev_OnOverlayRegistered = g_OnOverlayRegistered | |||
g_OnOverlayRegistered = function(filename, start, size) | |||
if (prev_OnOverlayRegistered ~= nil) then | |||
-- Make sure to execute any previously registered OnOverlay handler | |||
prev_OnOverlayRegistered(filename, start, size) | |||
end | |||
if filename == "sparticle-launcher.seg1" then | |||
-- this RNG-sqrt instance is removed for performance. Additionally, not corrupting the RNG seed with | |||
-- bad sqrt math is always a good thing in my book --jstine | |||
-- ---- | assert(eeObj.ReadMem32(start + 0x0044ec) == 0x4be1043d) -- vrget.wxyz vf01,r | ||
assert(eeObj.ReadMem32(start + 0x0044f0) == 0x4a0103bd) -- vsqrt q,vf01x | |||
-- | assert(eeObj.ReadMem32(start + 0x0044f8) == 0x4b0000a0) -- vaddq.x vf02,vf00,q | ||
assert(eeObj.ReadMem32(start + 0x00454c) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x0045f8) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x004680) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x004718) == 0x4a00143f) -- vrxor r,vf02x | |||
eeObj.WriteMem32(start + 0x0044ec, 0x00000000) | |||
eeObj.WriteMem32(start + 0x0044f0, 0x00000000) | |||
eeObj.WriteMem32(start + 0x0044f8, 0x00000000) | |||
eeObj.WriteMem32(start + 0x00454c, 0x00000000) | |||
eeObj.WriteMem32(start + 0x0045f8, 0x00000000) | |||
eeObj.WriteMem32(start + 0x004680, 0x00000000) | |||
eeObj.WriteMem32(start + 0x004718, 0x00000000) | |||
end | |||
end | end | ||
-- | -- hooked in link_control::finish(void)>: | ||
function install_c_hooks(offset) | |||
eeObj.AddHook(0x1085a0 + offset , 0x0080c825, DH8) | |||
end | |||
local Ready = 0 | |||
local DetectFunc = function() | |||
if Ready == 0 then | |||
local | local discID = eeObj.ReadMemStr(0x0012fc8) | ||
if (discID ~= "") then | |||
if (discID == "cdrom0:\\SCUS_972.65;1") or (discID == "cdrom0:\\SCPS_150.57;1") then | |||
-- US or Japan Disc | |||
Ready = 1 | |||
install_c_hooks(0) | |||
print( string.format("********************* DETECTED USA, JAPAN DISC ********************" ) ) | |||
elseif (discID == "cdrom0:\\SCKA_200.10;1") then | |||
Ready = 1 | |||
install_c_hooks(0x08) | |||
end | print( string.format("********************* KOREA DISC ********************" ) ) | ||
elseif (discID == "cdrom0:\\SCES_516.08;1") then | |||
-- European Disc | |||
Ready = 1 | |||
install_c_hooks(0xb8) | |||
print( string.format("********************* DETECTED EUROPE DISC (SCES-51608) ********************" ) ) | |||
elseif (discID == "rom0:PS2LOGO") then | |||
-- loading PS2 logo | |||
elseif (discID == "EELOAD") then | |||
-- loading? | |||
elseif (discID == "rom0:OSDSYS") then | |||
-- loading initial boot | |||
else | |||
print( string.format("--> DISC ID \"%s\"", discID ) ) | |||
end | |||
end | |||
end | |||
end | |||
emuObj.AddVsyncHook(DetectFunc) | |||
</pre> | |||
====Jak X==== | |||
'''CLI''' | |||
<br>SCUS-97429 | |||
<pre> | |||
--ee-jit-pagefault-threshold=30 | |||
--gs-frontend-opt-mode=1 | |||
--gs-use-mipmap=1 | |||
--gs-kernel-cl="mipmap" | |||
--gs-kernel-cl-up="mipmap2x2" | |||
--cop2-no-clamping=1 | |||
--vu1-mpg-cycles=250 | |||
</pre> | |||
'''LUA''' | |||
<br>SCUS-97429 | |||
<pre> | |||
-- Jak X Combat Racing [US] | |||
apiRequest(2.2) | |||
local gpr = require("ee-gpr-alias") | |||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
local gsObj = getGsObject() | |||
local eeOverlay = eeObj.getOverlayObject() | |||
-- Bug 10697 | |||
emuObj.SetGsTitleFix( "ignoreSubBuffCov", "reserved", { texMode=2 , tw=6 , th=5} ) | |||
-- Fix shadow | |||
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1 } ) | |||
-- Reduce flush count | |||
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1 } ) | |||
-- ------------------------- OVERLAY MANAGER -------------------------- | |||
g_OnOverlayRegistered = function(filename, start, size) | |||
-- global function provided for adding per-overlay callback handlers. | |||
-- See code for bug#10141 below, as example of this usage. | |||
end | end | ||
-- -- this hooks at the moment of loading the relocatable code and patch it only on the target segment. | |||
eeObj.AddHook(0x0026ff90, 0x03207825, function() | |||
local s1 = eeObj.GetGpr (gpr.s1) | |||
local filename = eeObj.ReadMemStr(s1 + 17) | |||
local segment = eeObj.ReadMem32 (s1 + 8) | |||
local main = eeObj.ReadMem32 (segment + 4) | |||
local mainSize = eeObj.ReadMem32 (segment + 8) | |||
local top = eeObj.ReadMem32 (segment + 36) | |||
local topSize = eeObj.ReadMem32 (segment + 40) | |||
if emuObj.IsToolingVerbose() then | |||
print(string.format("LOAD SEGMENT \"%s\" MAIN %08x size %x TOP %08x size %x", | |||
filename, main, mainSize, top, topSize)) | |||
end | |||
eeOverlay.Register(filename .. ".main", main, mainSize, false) | |||
eeOverlay.Register(filename .. ".top", top, topSize, true ) | |||
if (g_OnOverlayRegistered ~= nil) then | |||
-- Make sure to execute any previously registered OnOverlay handler | |||
g_OnOverlayRegistered(filename .. ".main", main, mainSize) | |||
g_OnOverlayRegistered(filename .. ".top", top, topSize ) | |||
end | end | ||
end) | |||
-- --------------------------------------------------------------------------------- | |||
-- This code serves as both a working patch for Jak X and as a sample for implementing | |||
-- overlay-relative code patches in trophy or feature lua scripts. The process described: | |||
-- | |||
-- 1. store local copy of current global variable instance. if g_OnOverlayRegistered is | |||
-- nil then we have a problem. The universal overlay hook is missing for some reason. | |||
-- | |||
-- 2. Bind our own function to g_OnOverlayRegistered. Since it's a global, the hook code | |||
-- in config.lua will execute our handler when the hook is invoked. | |||
assert(g_OnOverlayRegistered ~= nil) | |||
local prev_OnOverlayRegistered = g_OnOverlayRegistered | |||
g_OnOverlayRegistered = function(filename, start, size) | |||
if (prev_OnOverlayRegistered ~= nil) then | |||
-- Make sure to execute any previously registered OnOverlay handler | |||
prev_OnOverlayRegistered(filename, start, size) | |||
end | end | ||
-- bug#10141 workaround | |||
-- the problem is actually on a block 0x013090bc - 0x01309188. | |||
-- the block is expected to loop 8 times (s4 is the loop counter), | |||
-- the game falls into freezing state once it reaches at 0x01309170. | |||
-- it seems it's OK just to avoid to go into this 'freeze' state, eliminated the branch. | |||
-- this doesn't take into account relocatable code. | |||
-- eeInsnReplace(0x01309174, 0x1000012f, 0) -- beq $zero,$zero,0x01309634 | |||
eeObj. | -- 01309c64 : (1000012f) beq $zero,$zero,0x0130a124 => nop | ||
eeObj. | if filename == "lobby-menu-manager.main" then | ||
local adr = start + 0x1224 | |||
assert (eeObj.ReadMem32(adr) == 0x1000012f) | |||
eeObj.WriteMem32(adr, 0) | |||
end | end | ||
-- bug#10720 - title has a bugged RNG which does an SQRT of the current seed and xor the | |||
-- result back into the seed. This breaks the prime factorial pattern of the RNG and causes | |||
-- it to fall into a repeating loop with disturbing regularity. NOP'ing out the sqrt/xor | |||
-- hack seems to fix the title. --jstine | |||
if filename == "math.main" then | |||
assert(eeObj.ReadMem32(start + 0x0005e4) == 0x4be1043d) -- vrget.wxyz vf01,r | |||
assert(eeObj.ReadMem32(start + 0x0005e8) == 0x4a0103bd) -- vsqrt q,vf01x | |||
eeObj.WriteMem32( | assert(eeObj.ReadMem32(start + 0x0005ec) == 0x4b0000a0) -- vaddq.x vf02,vf00,q | ||
assert(eeObj.ReadMem32(start + 0x0005f0) == 0x4a00143f) -- vrxor r,vf02x | |||
eeObj.WriteMem32(start + 0x0005e4, 0x00000000) | |||
eeObj. | eeObj.WriteMem32(start + 0x0005e8, 0x00000000) | ||
eeObj.WriteMem32(start + 0x0005ec, 0x00000000) | |||
eeObj.WriteMem32(start + 0x0005f0, 0x00000000) | |||
end | end | ||
-- this RNG-sqrt instance is removed more for performance than for RNG corruption. the particle | |||
-- launcher iterates over the sqrt quite often. In any case, not corrupting the RNG seed with | |||
-- bad sqrt math is always a good thing in my book --jstine | |||
if filename == "sparticle-launcher.main" then | |||
assert(eeObj.ReadMem32(start + 0x00630c) == 0x4be1043d) -- vrget.wxyz vf01,r | |||
assert(eeObj.ReadMem32(start + 0x006310) == 0x4a0103bd) -- vsqrt q,vf01x | |||
assert(eeObj.ReadMem32(start + 0x006318) == 0x4b0000a0) -- vaddq.x vf02,vf00,q | |||
assert(eeObj.ReadMem32(start + 0x006370) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x0063fc) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x006484) == 0x4a00143f) -- vrxor r,vf02x | |||
assert(eeObj.ReadMem32(start + 0x00651c) == 0x4a00143f) -- vrxor r,vf02x | |||
eeObj.WriteMem32(start + 0x00630c, 0x00000000) | |||
eeObj.WriteMem32(start + 0x006310, 0x00000000) | |||
eeObj.WriteMem32(start + 0x006318, 0x00000000) | |||
eeObj.WriteMem32( | eeObj.WriteMem32(start + 0x006370, 0x00000000) | ||
eeObj.WriteMem32(start + 0x0063fc, 0x00000000) | |||
eeObj.WriteMem32(start + 0x006484, 0x00000000) | |||
eeObj. | eeObj.WriteMem32(start + 0x00651c, 0x00000000) | ||
end | end | ||
end | |||
-- --------------------------------------------------------------------------------- | |||
</pre> | |||
====Kinetica==== | |||
'''CLI''' | |||
<br>SCUS-97132 | |||
<pre> | |||
--vu1-clamp-range=0x386,0x386 | |||
--vu1-clamp-range=0x5e0,0x5f0 # another gritches | |||
--gs-kernel-cl-up="up2x2skipinterp" | |||
--vu1-injection=1 | |||
--vu1-jr-cache-policy=sameprog | |||
--vu1-jalr-cache-policy=sameprog | |||
--vu1-mpg-cycles=900 | |||
--host-audio-latency=0.10 | |||
--cdvd-sector-read-cycles=40000 | |||
</pre> | |||
'''LUA''' | |||
<br>SCUS-97132 | |||
<pre> | |||
local gpr = require("ee-gpr-alias") | |||
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
local emuObj = getEmuObject() | |||
local eeObj = getEEObject() | |||
-- require("debughooks") | |||
-- local iopObj = getIOPObject() | |||
-- iopObj.AddHook(0x000135ac, 0x27bdffe0, DebugHooks.h_IOP_ioman_write) | |||
-- bug#8123 | |||
-- Skip resetting VAG stream which happens on an error. | |||
iopInsnReplace(0x00090028, 0x16220009, 0x08024014) -- bne $s1,$v0,0x00090050 => j 0x00090050 | |||
-- bug#9405 - advance EE clock according to spinning-loop SIF activity. | |||
-- | |||
local skip_syncDCache = function() | |||
local | -- Original value when actually processing syncDCache was 3300 | ||
-- Boosting to 8000 helps reduce bottleneck | |||
eeObj.AdvanceClock(8000) | |||
end | end | ||
eeInsnReplace(0x1ca9e0, 0x27bdffe0, 0x03e00008) | |||
eeInsnReplace(0x1ca9e4, 0x0080302d, 0x00000000) | |||
eeObj.AddHookJT(0x1ca9e0, 0x03e00008, skip_syncDCache) | |||
-- gametime to be from realtim.... | |||
-- # this causes the time elapses even while in pause. so bugged | |||
-- # also maybe this causes 'negative' race time as well. | |||
-- we should be OK even without this because skipping frame works (mostly). | |||
-- | |||
-- local prevtime = 0.0 | |||
end | -- eeObj.AddHook(0x12350c, 0x27bdfec0, function() | ||
-- local curtime = os.clock() | |||
-- if prevtime ~= 0.0 then | |||
-- eeObj.WriteMemFloat(eeObj.GetGpr(gpr.gp)-31776, curtime - prevtime) | |||
-- end | |||
-- prevtime = curtime | |||
-- end) | |||
-- to work skipping frame mechanism correctly... | |||
-- the game checks a flag set by INTC GS whether GS still does his job or not to | |||
-- determine whether it should skip a frame or not. | |||
-- Unfortunately we don't have the actual timing of GS FINISH signal. | |||
-- Instead of that, we check EE clock to determine to skip or not. | |||
local ee_frequency = 294912000 | |||
local vsync_frequency = 59.94 -- use interlace freq. | |||
local one_vsync_clock_on_ntsc = math.floor(ee_frequency / vsync_frequency) | |||
-- Kinetica has some inconsistency among frames -- some frames take unusually long, possibly due | |||
-- to AI updates. In these cases, it is necessary to skip multiple frames to catch the game's | |||
-- clock back up to realtime. To do so, we track 'expected_clock' over time, so that especially | |||
-- slow frames are compensated for over time. | |||
local prev_clock = 0 | |||
local expected_clock = 0 | |||
eeObj.AddHook(0x181f7c, 0x8f82bf54, function() | |||
-- It hits here when it skips a frame. | |||
--local diff = eeObj.GetClock() - prev_clock | |||
local clock = eeObj.GetClock() | |||
--local diff = clock - expected_clock | |||
--print(string.format("SKIP FRAME: diff=%7d", diff)) | |||
-- | --prev_clock = eeObj.GetClock() -- just update the clock. | ||
expected_clock = expected_clock + one_vsync_clock_on_ntsc | |||
end) | |||
eeObj.AddHook(0x18202c, 0x8f84bf54, function() | |||
local clock = eeObj.GetClock() | |||
--local diff = clock - prev_clock | |||
--print(string.format("diff=%d vsync_term=%f %s", diff, one_vsync_clock_on_ntsc, diff > one_vsync_clock_on_ntsc and "SKIP" or "")) | |||
local diff = clock - expected_clock | |||
-- Sanity correction -- to handle cases where expected_clock contents is | |||
-- zero or out-dated. | |||
if (math.abs(diff) > (one_vsync_clock_on_ntsc * 6)) then | |||
expected_clock = clock | |||
end | |||
-- print(string.format("diff=%7d %s", diff, diff > 17000 and "SKIP" or "")) | |||
if diff > 17000 then | |||
eeObj.SetGpr(gpr.a0, 1) | |||
end | |||
-- update clock | |||
--prev_clock = clock | |||
expected_clock = expected_clock + one_vsync_clock_on_ntsc | |||
end) | |||
-- Applies a cycle rate hack to what I presume is the game logic pipeline, for roughly per-frame updates. | |||
local mpgCycles_default = 900 | |||
local currentMpgCycles = mpgCycles_default | |||
local checkNeedsSpeedHack = function() | |||
local stageId = eeObj.ReadMem32(0x01fce8c) | |||
local numPlayers = eeObj.ReadMem32(0x01ffd78) -- 0x01ffd7c seems to always match this one... | |||
-- print(string.format("stageId = %d, numPlayers = %d", stageId, numPlayers)) | |||
-- 3 = Electrica | |||
-- 7 = Electrica II | |||
-- 8 = Cliffhanger | |||
local newMpgCycles = mpgCycles_default | |||
if (stageId == 3 or stageId == 7 or stageId == 8) then | |||
-- note: this will also apply to demo loops (0 players) | |||
newMpgCycles = newMpgCycles + 120 | |||
if stageId == 7 then | |||
-- Electrica 2 is extra-special slow in some areas. | |||
-- (and 2-player mode on this map runs enough mpgs that extra penalty isn't needed) | |||
if numPlayers == 2 then | |||
newMpgCycles = newMpgCycles - 100 | |||
else | |||
newMpgCycles = newMpgCycles + 275 | |||
end | |||
elseif numPlayers == 2 then | |||
-- increment is not so big here because two player mode already runs many more VU programs. | |||
newMpgCycles = newMpgCycles + 100 | |||
end | |||
==== | end | ||
if currentMpgCycles ~= newMpgCycles then | |||
-- print ( string.format("################### Setting mpg-cycles = %d", newMpgCycles) ) | |||
eeObj.Vu1MpgCycles(newMpgCycles) | |||
currentMpgCycles = newMpgCycles | |||
end | |||
end | |||
eeObj.AddHookJT(0x15ca2c,0x27bdff20,checkNeedsSpeedHack) | |||
</pre> | |||
====The King of Fighters Collection: The Orochi Saga==== | |||
<br>CLI | <br>CLI | ||
< | <br>SLUS-21554 | ||
<pre> | |||
--host-audio-latency=0. | --host-audio-latency=0.010 | ||
--force-frame-blend=1 | --force-frame-blend=1 | ||
-- | </pre> | ||
#Graphical | |||
====King of Fighters 98 Ultimate Match==== | |||
ALL | |||
<br>CLI | |||
<pre>--force-frame-blend=1 | |||
--gs-use-deferred-l2h=0 | |||
#Graphical fix.</pre> | |||
SLES_552.80 | |||
<br> | <br>SLES-55280_features.lua | ||
<pre> | <pre>This is a substantial file. Over 800 lines with additional controller/fightstick support and various shader/bezel files. I'm sharing the file itself as a download link. | ||
https://drive.google.com/file/d/1-lArL1Yqe079Ni3G-ZtHr8hqNPUsjQJy/view | |||
#More stick support, shaders, bezels, widescreen fix.</pre> | |||
</pre> | |||
====King of Fighters 2000==== | ====King of Fighters 2000==== | ||
Line 12,319: | Line 2,132: | ||
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { alpha=0x00000000 } ) | emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { alpha=0x00000000 } ) | ||
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { alpha=0x80000048 } ) | emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { alpha=0x80000048 } ) | ||
</pre> | </pre> | ||
Line 13,656: | Line 3,394: | ||
-- Karla Quiros Manager Business Finance & Ops | -- Karla Quiros Manager Business Finance & Ops | ||
-- Special thanks to A-R&D | -- Special thanks to A-R&D | ||
</pre> | </pre> | ||