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 } | |||
-- fade skip Bug#8359. skip FadeSet if skip_fade_flag meets the requirement. | |||
eeObj.AddHook( 0x13c464, 0x8e0500c0, function() | |||
-- 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 | local eeObj = getEEObject() | ||
local emuObj = getEmuObject() | |||
local gpr = require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"]) | |||
if | -- 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 | ||
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 | local eeObj = getEEObject() | ||
local emuObj = getEmuObject() | |||
local gpr = require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"]) | |||
if | -- 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 | ||
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) | |||
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 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. | |||
-- Full | -- 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 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 | |||
-- Bug#8285 | |||
-- This patch changes the color of background on : | |||
-- - Language selection | |||
-- - Company logo | |||
-- - Start screen | |||
-- - 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) | |||
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 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 | 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() | |||
local | -- 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 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 | ||
end | |||
if found == true then | |||
offs = x | |||
break | |||
end | end | ||
end | end | ||
end | end | ||
return offs | |||
end | end | ||
eeObj.AddHook( | eeObj.AddHook(0x2812b0, 0x27bdfff0, function() -- QDT::VM::BYTE_CODE::BYTE_CODE | ||
eeObj. | local obj = eeObj.GetGpr(gpr.a1) | ||
</pre> | local bytecode = eeObj.ReadMem32(obj+0x18) | ||
local count = eeObj.ReadMem32(obj+0x20) | |||
==== | |||
<br>SCES- | 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> | |||
====Fantavision==== | |||
'''CLI''' | |||
<br>SCES-50002 | |||
<pre> | <pre> | ||
--gs-kernel-cl-up="fantavision" | |||
--gs-motion-factor=1 | |||
--gs-kernel-cl-up=" | |||
--gs- | |||
</pre> | </pre> | ||
<br>SCES- | '''LUA''' | ||
<br>SCES-50002 | |||
<pre> | <pre> | ||
require("ee-gpr-alias") | |||
require( "ee-hwaddr" ) | 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() | |||
-- -- | -- | ||
-- | -- 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) | |||
-- 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> | |||
====Fatal Fury: Battle Archives volume 2==== | |||
ALL | |||
<br>CLI | |||
<pre>--gs-uprender=none | |||
--gs-upscale=point | |||
--host-audio-latency=0.010 | |||
--force-frame-blend=1 | |||
#Graphical fix.</pre> | |||
< | SLUS_217.23 | ||
<br>SLUS-21723_features.lua | |||
<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> | <br>CLI | ||
<pre> | <pre>--gs-uprender=2x2 | ||
--gs- | --gs-upscale=point | ||
-- | --host-audio-latency=0.3 | ||
-- | --ee-hook=0x127050,AdvanceClock,0x2403002b,0x4000 | ||
</pre> | --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") | require("ee-gpr-alias") | ||
eeObj = getEEObject() | local eeObj = getEEObject() | ||
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>-- | <pre>--vu1-no-clamping=0 | ||
-- | --gs-check-trans-rejection=1 | ||
--gs- | --gs-kernel-cl-up="up2x2tc" | ||
-- | --gs-optimize-30fps=1 | ||
--ee-hook=0x27cea8,FastForwardClock | |||
--ee-hook= | #Performance and graphical fix.</pre> | ||
SLUS_200.62 | |||
<br>LUA | <br>LUA | ||
<pre>apiRequest(0.1) | <pre> | ||
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory. | |||
-- | -- Performace fix | ||
local emuObj = getEmuObject() | local emuObj = getEmuObject() | ||
local thresholdArea = 600 | local thresholdArea = 600 | ||
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha= | 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-20062_features.lua | |||
<pre>-- Lua 5.3 | |||
-- Title: Grand Theft Auto III PS2 - SLUS-20062 (USA) v1.40 | |||
-- 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) -- need widescreen support | |||
-- | |||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
local | 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() | |||
local isWidescreen = eeObj.GetGpr(gpr.v0) | |||
eeObj. | |||
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- | <br>SLUS-20946_features.lua | ||
<pre>-- Lua 5.3 | <pre>-- Lua 5.3 | ||
-- Title: | -- Title: Grand Theft Auto: San Andreas - SLUS-20946 (USA) v3.00 | ||
-- Author: | -- 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) -- | apiRequest(0.7) -- need widescreen support | ||
local eeObj = getEEObject() | local eeObj = getEEObject() | ||
local emuObj = getEmuObject() | local emuObj = getEmuObject() | ||
local USEWIDESCREEN_ADDRESS = 0x7004ef | |||
local H1 = -- init widescreen flag | |||
function() | |||
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen | |||
end | end | ||
eeObj. | local H2 = -- main game loop | ||
function() | |||
end | 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. | |||
-- 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. | ||
</pre> | -- 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>SLUS-20552_features.lua | |||
<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 | |||
if | 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 | 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 DH8 = function() | |||
local s0 = eeObj.GetGpr(gpr.s0) | |||
local linkblock = eeObj.ReadMem32(s0+0x5c) | |||
-- | --print( string.format("--> PRELOAD %08x %08x",s0, linkblock) ) | ||
local linkblock_allocate_length = eeObj.ReadMem32 (linkblock + 0x00) | |||
eeObj. | 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) | |||
end | 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> | |||
- | 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> | |||
====Harvest Moon®: A Wonderful Life Special Edition==== | |||
CUSA06584 | |||
<br>CLI | |||
<pre> | |||
--ee-cycle-scalar=0.78 | |||
</pre> | </pre> | ||
<br>LUA | |||
CUSA06584 | |||
<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 | |||
if sign then | |||
local | eeObj.SetPc(0x3ce118) | ||
end | |||
end) | |||
</pre> | </pre> | ||
====Jak 3==== | |||
==== | |||
'''LUA''' | '''LUA''' | ||
<br> | <br>SCUS-97330 | ||
<pre> | <pre> | ||
apiRequest(2.3) | |||
apiRequest( | |||
eeObj = getEEObject() | 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 | |||
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) ) | |||
end | |||
eeOverlay.Register(filename .. ".main", main, mainSize, false) | |||
eeOverlay.Register(filename .. ".top", top, topSize, true ) | |||
-- | --local debugObj = getDebugObject() | ||
local | --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 | |||
local | |||
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.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. | |||
-- 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 | 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 | 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 | 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 | end | ||
-- 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 | 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 | end | ||
if | 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 | end | ||
-- hooked in link_control::finish(void)>: | |||
function install_c_hooks(offset) | |||
eeObj.AddHook(0x1085a0 + offset , 0x0080c825, DH8) | |||
end | |||
local Ready = 0 | |||
local | local DetectFunc = function() | ||
if Ready == 0 then | |||
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) | |||
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 | 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 | 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) | |||
-- --------------------------------------------------------------------------------- | |||
-- 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 | |||
-- 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 | |||
-- 01309c64 : (1000012f) beq $zero,$zero,0x0130a124 => nop | |||
if filename == "lobby-menu-manager.main" then | |||
local adr = start + 0x1224 | |||
-- | assert (eeObj.ReadMem32(adr) == 0x1000012f) | ||
eeObj.WriteMem32(adr, 0) | |||
local | |||
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 | |||
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.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(start + 0x006370, 0x00000000) | |||
eeObj.WriteMem32(start + 0x0063fc, 0x00000000) | |||
eeObj.WriteMem32(start + 0x006484, 0x00000000) | |||
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() | |||
-- Original value when actually processing syncDCache was 3300 | |||
-- Boosting to 8000 helps reduce bottleneck | |||
eeObj.AdvanceClock(8000) | |||
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 | |||
-- 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 | local checkNeedsSpeedHack = function() | ||
local | 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 | end | ||
if currentMpgCycles ~= newMpgCycles then | |||
-- print ( string.format("################### Setting mpg-cycles = %d", newMpgCycles) ) | |||
eeObj.Vu1MpgCycles(newMpgCycles) | |||
if | currentMpgCycles = newMpgCycles | ||
end | end | ||
end | end | ||
eeObj.AddHookJT(0x15ca2c,0x27bdff20,checkNeedsSpeedHack) | |||
</pre> | |||
====The King of Fighters Collection: The Orochi Saga==== | |||
<br>CLI | |||
<br>SLUS-21554 | |||
<pre> | |||
--host-audio-latency=0.010 | |||
--force-frame-blend=1 | |||
</pre> | |||
<br>LUA | |||
<pre> | |||
-- Lua 5.3 | |||
-- Titles: The King of Fighters Collection - The Orochi Saga | |||
-- Features version: 1.00 | |||
-- | -- Author: David Haywood, Warren Davis | ||
-- Date: March/April 2017 | |||
--[[ | |||
Notes: | |||
The intro sequence (SNK logo, movie) only plays ONCE, on startup, never again, no matter how long you leave things in attract mode | |||
this works to our advantage. For this reason it's probably easiest to have the current scanlines / bezel options kick in immediately | |||
after the SNK logo. | |||
FEATURE SCRIPT : Rom Base is is set to 0 as soon as you select 'return to main menu' although any music that is playing at the time | |||
continues to play until you confirm the 'save to memory card' choice, this might not work to our advantage. | |||
Rom base is set to 00020000 then the actual value as soon as you select a game from the main menu. | |||
text base and RAM base get set as soon as the actual emulation starts for each game. | |||
Sprites | |||
0 SNK logo | |||
1 Bezel | |||
2 Art Mode notification | |||
3 Scan Mode notification | |||
4 Fight stick notification | |||
5 Fight stick notification | |||
6 Fight stick notification | |||
7 Fight stick notification | |||
Requested volume adjustments | |||
Intro 100% -> 79.43% | |||
Games 100% -> 70.79% | |||
--]] | |||
-- 1 for US | |||
-- 2 for Europe | |||
local Region = 1 | |||
apiRequest(2.0) -- request version 2.0 API. Calling apiRequest() is mandatory. | |||
local eeObj = getEEObject() | |||
local emuObj = getEmuObject() | |||
local gsObj = getGsObject() | |||
-- | -- hangs on black screen with some other language settings (eg Japanese) | ||
emuObj.SetPs2Lang(1) | |||
-- | local gpr = require("ee-gpr-alias") | ||
local | local kFilterMode, kWrapMode, kBlendMultiplier, kBlendFunc = require("sprite") | ||
local PadConnectType = require("pad-connect-type") | |||
HIDPad_Enable() | |||
-- NEEDS HOOKING UP | |||
local OptionsMenuActive = 0 | |||
local RestoreNewMenus = false -- WBD keep new menus from reappearing when Player Control menu goes away | |||
-- | -- should these be 1-x ? | ||
local | local INTROVOLUME = 0.375 --WBD adjusted, was 0.7943 | ||
local | local GAMEVOLUME = 0.39 --WBD adjusted, was 0.7079 | ||
local SaveData = emuObj.LoadConfig(0) | |||
if SaveData.vid_mode == nil then | |||
SaveData.vid_mode = 0 | |||
end | |||
if SaveData.vid_scanlines == nil then | |||
SaveData.vid_scanlines = 0 | |||
end | |||
local vid_modeOptions = {"NONE", "ART1", "ART2"} | |||
local vid_scanlineOptions = {"OFF", "ON"} | |||
local vid_mode = SaveData.vid_mode | |||
local vid_scanlines = SaveData.vid_scanlines | |||
local snklogo = 0 | |||
--print (string.format("_NOTE: STARTING Region %d", Region)) | |||
----------------------- | |||
-- Video Options | |||
----------------------- | |||
local sprite_snklogo = getSpriteObject(0) | |||
local sprite_bezel = getSpriteObject(1) | |||
local sprite_artmenu = getSpriteObject(2) | |||
local sprite_scanmenu = getSpriteObject(3) | |||
local | -- Notifications should be assigned to two unused sprite slots. Since we want them to | ||
-- be displayed on top of everything else, they should be the highest sprites in the list. | |||
local spr_p1_notify = getSpriteObject(4) | |||
local spr_p2_notify = getSpriteObject(5) | |||
local spr_p1d_notify = getSpriteObject(6) | |||
local spr_p2d_notify = getSpriteObject(7) | |||
local | -- note: Texture 0 is fixed as the PS2 scanout. | ||
local texture1 = getTextureObject(1) | |||
local texture2 = getTextureObject(2) | |||
local texture3 = getTextureObject(3) | |||
local texture4 = getTextureObject(4) | |||
local texture5 = getTextureObject(5) | |||
local texture6 = getTextureObject(6) | |||
local texture7 = getTextureObject(7) | |||
--local texture8 = getTextureObject(8) -- WBD not needed | |||
-- ------------------------------------------------------------ | |||
local STATE_STOPPED = 0 | |||
local STATE_RUNNING = 1 | |||
local | local notify_ypos = 24 | ||
local notify_p1_xsize = 0 | |||
local notify_p2_xsize = 0 | |||
local notify_p1d_xsize = 0 | |||
local notify_p2d_xsize = 0 | |||
local notify_ysize = 0 | |||
local | local notify_frames_p1 = 0 | ||
local | local notify_frames_p2 = 0 | ||
local notify_animstate_p1 = STATE_STOPPED | |||
local notify_animstate_p2 = STATE_STOPPED | |||
= | local connected_p1 = 47 | ||
local connected_p2 = 47 | |||
local blink_on_p1 = true | |||
local blink_on_p2 = true | |||
--[[ Menu notifications --]] | |||
local texture9 = getTextureObject(9) | |||
local texture10 = getTextureObject(10) | |||
local texture11 = getTextureObject(11) | |||
local texture12 = getTextureObject(12) | |||
local texture13 = getTextureObject(13) | |||
local extra_menu_h = 0 | |||
local | local extra_menu_w = 0 | ||
local | |||
-- adjust these? | |||
local artmenu_ypos = 770 -- adjusted by WBD | |||
local scanmenu_ypos = artmenu_ypos + 36 | |||
-- | |||
-- | |||
local menu_xpos = 600 -- adjusted by WBD | |||
HideArtMenu = function() | |||
sprite_artmenu.Disable() | |||
--[[ WBD added Disable rather than position offscreen | |||
sprite_artmenu.SetPosXY(-1 - extra_menu_w, artmenu_ypos) -- full obscured | |||
sprite_artmenu.SetSizeXY(extra_menu_w,extra_menu_h) | |||
sprite_artmenu.SetPosUV(0,0) | |||
sprite_artmenu.SetSizeUV(extra_menu_w,extra_menu_h) | |||
sprite_artmenu.SetBlendColorEquation(blendDefaultEquation) | |||
--]] | |||
end | |||
HideScanMenu = function() | |||
sprite_scanmenu.Disable() | |||
--[[ WBD added Disable rather than position offscreen | |||
sprite_scanmenu.SetPosXY(-1 - extra_menu_w, scanmenu_ypos) -- full obscured | |||
sprite_scanmenu.SetSizeXY(extra_menu_w,extra_menu_h) | |||
sprite_scanmenu.SetPosUV(0,0) | |||
sprite_scanmenu.SetSizeUV(extra_menu_w,extra_menu_h) | |||
sprite_scanmenu.SetBlendColorEquation(blendDefaultEquation) | |||
--]] | |||
end | |||
= | ShowArtMenu = function() | ||
sprite_artmenu.BindTexture(SaveData.vid_mode+9) | |||
sprite_artmenu.SetPosXY(menu_xpos, artmenu_ypos) | |||
sprite_artmenu.SetSizeXY(extra_menu_w,extra_menu_h) | |||
sprite_artmenu.SetPosUV(0,0) | |||
sprite_artmenu.SetSizeUV(extra_menu_w,extra_menu_h) | |||
sprite_artmenu.SetBlendColorEquation(blendDefaultEquation) | |||
sprite_artmenu.Enable() | |||
end | |||
ShowScanMenu = function() | |||
sprite_scanmenu.BindTexture(SaveData.vid_scanlines+12) | |||
sprite_scanmenu.SetPosXY(menu_xpos, scanmenu_ypos) | |||
sprite_scanmenu.SetSizeXY(extra_menu_w,extra_menu_h) | |||
sprite_scanmenu.SetPosUV(0,0) | |||
sprite_scanmenu.SetSizeUV(extra_menu_w,extra_menu_h) | |||
sprite_scanmenu.SetBlendColorEquation(blendDefaultEquation) | |||
sprite_scanmenu.Enable() | |||
end | |||
local update_notifications_p1 = function() | |||
if notify_animstate_p1 == STATE_STOPPED then | |||
spr_p1_notify.Disable() | |||
spr_p1d_notify.Disable() | |||
return | |||
end | |||
-- L2() | |||
local keyframe = 15 | |||
local | |||
notify_frames_p1 = notify_frames_p1 + 1 | |||
if math.ceil(notify_frames_p1/keyframe) == notify_frames_p1/keyframe then blink_on_p1 = not blink_on_p1 end | |||
if blink_on_p1 == true then notify_ypos = 24 end | |||
if blink_on_p1 == false then notify_ypos = -84 end | |||
-- print(string.format("FEATURE SCRIPT : rounded %s, floating %s, blink %s ypos %s", math.ceil(notify_frames_p1/keyframe), notify_frames_p1/keyframe, blink_on_p1, notify_ypos)) | |||
-- print(string.format("FEATURE SCRIPT : notify_frames_p1 %s", notify_frames_p1)) | |||
if notify_frames_p1 >= 225 then | |||
notify_animstate_p1 = STATE_STOPPED | |||
notify_frames_p1 = 0 | |||
connected_p1 = 47 | |||
end | end | ||
if connected_p1 == true then | |||
spr_p1_notify.SetBlendColor(1.0,1.0,1.0,1.0) | |||
spr_p1_notify.SetPosXY(math.floor((1920-notify_p1_xsize)/2), notify_ypos) | |||
spr_p1_notify.Enable() | |||
end | end | ||
if connected_p1 == false then | |||
spr_p1d_notify.SetBlendColor(1.0,1.0,1.0,1.0) | |||
spr_p1d_notify.SetPosXY(math.floor((1920-notify_p1d_xsize)/2), notify_ypos) | |||
spr_p1d_notify.Enable() | |||
end | |||
end | |||
local | local update_notifications_p2 = function() | ||
if notify_animstate_p2 == STATE_STOPPED then | |||
spr_p2_notify.Disable() | |||
spr_p2d_notify.Disable() | |||
return | |||
end | |||
-- | -- L2() | ||
local keyframe = 15 | |||
notify_frames_p2 = notify_frames_p2 + 1 | |||
-- | if math.ceil(notify_frames_p2/keyframe) == notify_frames_p2/keyframe then blink_on_p2 = not blink_on_p2 end | ||
if blink_on_p2 == true then notify_ypos = 24 + notify_ysize + 8 end | |||
if blink_on_p2 == false then notify_ypos = -84 - notify_ysize - 8 end | |||
-- | -- print(string.format("FEATURE SCRIPT : rounded %s, floating %s, blink %s ypos %s", math.ceil(notify_frames_p2/keyframe), notify_frames_p2/keyframe, blink_on_p2, notify_ypos)) | ||
if notify_frames_p2 >= 225 then | |||
notify_animstate_p2 = STATE_STOPPED | |||
notify_frames_p2 = 0 | |||
connected_p2 = 47 | |||
end | |||
-- | -- print(string.format("FEATURE SCRIPT : connected_p1 %s, connected_p2 %s", connected_p1, connected_p2)) | ||
if connected_p2 == true then | |||
spr_p2_notify.SetBlendColor(1.0,1.0,1.0,1.0) | |||
spr_p2_notify.SetPosXY(math.floor((1920-notify_p2_xsize)/2), notify_ypos) | |||
end | spr_p2_notify.Enable() | ||
end | |||
if connected_p2 == false then | |||
spr_p2d_notify.SetBlendColor(1.0,1.0,1.0,1.0) | |||
spr_p2d_notify.SetPosXY(math.floor((1920-notify_p2d_xsize)/2), notify_ypos) | |||
spr_p2d_notify.Enable() | |||
end | end | ||
end | |||
-- slot can range from 0 to 3, for users 1 thru 4. | |||
-- pad_type can be either: DS4, REMOTE_DS4, REMOTE_VITA, or HID | |||
local onHIDPadEvent = function(slot, connected, pad_type) | |||
if | spr_p1_notify.Disable() | ||
spr_p1d_notify.Disable() | |||
spr_p2_notify.Disable() | |||
spr_p2d_notify.Disable() | |||
-- print(string.format("FEATURE SCRIPT : slot %s, connected %s, pad_type %s", slot, connected, pad_type)) | |||
if pad_type == PadConnectType.HID then | |||
notify_frames_p1 = 0 | |||
notify_frames_p2 = 0 | |||
blink_on_p1 = true | |||
blink_on_p2 = true | |||
if slot == 0 then | |||
connected_p1 = connected | |||
notify_animstate_p1 = STATE_RUNNING | |||
end | |||
if slot == 1 then | |||
connected_p2 = connected | |||
notify_animstate_p2 = STATE_RUNNING | |||
end | |||
end | end | ||
end | end | ||
local scanlineParams = { | |||
240.0, -- float scanlineCount | |||
0.7, -- float scanlineHeight; | |||
1.5, -- float scanlineBrightScale; | |||
0.5, -- float scanlineAlpha; | |||
0.5 -- float vignetteStrength; | |||
} | |||
-- --------------------------------------------------- | |||
-- Full Screen (480p) NoFX | |||
-- --------------------------------------------------- | |||
if ( | local original_mode = function() | ||
- | if snklogo == 1 then | ||
sprite_snklogo.BindTexture(3) | |||
sprite_snklogo.SetPosXY(0,0) | |||
sprite_snklogo.SetSizeXY(1920,1080) | |||
sprite_snklogo.SetPosUV(0,0) | |||
sprite_snklogo.SetSizeUV(1920,1080) | |||
else | |||
sprite_snklogo.BindTexture(0) | |||
sprite_snklogo.BindFragmentShader(0) | |||
sprite_snklogo.SetPosXY((1920-1440)/2,0) | |||
sprite_snklogo.SetSizeXY(1440,1080) | |||
end | end | ||
sprite_snklogo.Enable() | |||
sprite_bezel.Disable() | |||
end | end | ||
-- | -- --------------------------------------------------- | ||
-- Full Screen + ScanLines (480p) | |||
-- --------------------------------------------------- | |||
local scanlines_mode = function() | |||
if snklogo == 1 then | |||
sprite_snklogo.BindTexture(3) | |||
sprite_snklogo.SetPosXY(0,0) | |||
sprite_snklogo.SetSizeXY(1920,1080) | |||
sprite_snklogo.SetPosUV(0,0) | |||
sprite_snklogo.SetSizeUV(1920,1080) | |||
else | |||
sprite_snklogo.BindTexture(0) | |||
sprite_snklogo.SetPosXY((1920-1440)/2,0) | |||
sprite_snklogo.SetSizeXY(1440,1080) | |||
sprite_snklogo.BindFragmentShader(2) | |||
sprite_snklogo.SetShaderParams(scanlineParams) | |||
end | |||
sprite_snklogo.Enable() | |||
sprite_bezel.Disable() | |||
end | |||
=== | -- --------------------------------------------------- | ||
-- Bezel NoFX | |||
-- --------------------------------------------------- | |||
local bezel_mode = function(bezel) | |||
-- | if snklogo == 1 then | ||
sprite_snklogo.BindTexture(3) | |||
sprite_snklogo.SetPosXY(0,0) | |||
sprite_snklogo.SetSizeXY(1920,1080) | |||
sprite_snklogo.SetPosUV(0,0) | |||
sprite_snklogo.SetSizeUV(1920,1080) | |||
else | |||
sprite_snklogo.BindTexture(0) | |||
sprite_snklogo.BindFragmentShader(0) | |||
sprite_snklogo.SetPosXY((1920-1280)/2, (1080-896)/2) | |||
sprite_snklogo.SetSizeXY(1280,896) | |||
end | |||
sprite_snklogo.Enable() | |||
sprite_bezel.BindTexture(bezel) | |||
sprite_bezel.SetPosXY(0,0) | |||
sprite_bezel.SetSizeXY(1920,1080) | |||
sprite_bezel.SetPosUV(0,0) | |||
sprite_bezel.SetSizeUV(1920,1080) | |||
sprite_bezel.Enable() | |||
end | |||
-- --------------------------------------------------- | |||
-- Bezel + ScanLines (480p) | |||
-- --------------------------------------------------- | |||
local bezel_scanlines_mode = function(bezel) | |||
if snklogo == 1 then | |||
sprite_snklogo.BindTexture(3) | |||
sprite_snklogo.SetPosXY(0,0) | |||
sprite_snklogo.SetSizeXY(1920,1080) | |||
sprite_snklogo.SetPosUV(0,0) | |||
sprite_snklogo.SetSizeUV(1920,1080) | |||
else | |||
sprite_snklogo.BindTexture(0) | |||
sprite_snklogo.SetPosXY((1920-1280)/2, (1080-896)/2) | |||
sprite_snklogo.SetSizeXY(1280,896) | |||
sprite_snklogo.BindFragmentShader(2) | |||
sprite_snklogo.SetShaderParams(scanlineParams) | |||
end | |||
sprite_snklogo.Enable() | |||
sprite_bezel.BindTexture(bezel) | |||
sprite_bezel.SetPosXY(0,0) | |||
sprite_bezel.SetSizeXY(1920,1080) | |||
sprite_bezel.SetPosUV(0,0) | |||
sprite_bezel.SetSizeUV(1920,1080) | |||
sprite_bezel.Enable() | |||
end | |||
local updateMode = function(mode, scanlines) | |||
if scanlines == 0 then | |||
if mode == 0 then | |||
original_mode() | |||
else | |||
end | bezel_mode(mode) | ||
end | |||
else | |||
if mode == 0 then | |||
scanlines_mode() | |||
else | |||
bezel_scanlines_mode(mode) | |||
end | |||
end | |||
local needsSave = (SaveData.vid_mode ~= mode or SaveData.vid_scanlines ~= scanlines) | |||
if needsSave == true then | |||
SaveData.vid_mode = mode | |||
SaveData.vid_scanlines = scanlines | |||
emuObj.SaveConfig(0, SaveData) | |||
end | |||
end | |||
-- Fight stick | |||
local pad = function() | |||
updateMode(SaveData.vid_mode, SaveData.vid_scanlines) | |||
emuObj.AddVsyncHook(update_notifications_p1) | |||
emuObj.AddVsyncHook(update_notifications_p2) | |||
end | |||
emuObj.AddPadHook(onHIDPadEvent) | |||
emuObj.AddEntryPointHook(pad) | |||
-- | --[[################################################################################################################### | ||
####################################################################################################################### | |||
Adjusted Memory Read/Write operations | |||
when data stored in memory differs by a common offset between regions these functions are handy | |||
###################################################################################################################--]] | |||
-- | -- Initial offsets based on European version | ||
local AdjustForRegion = 0 | |||
function Adjusted_WM32(base, data) | |||
eeObj.WriteMem32(base + AdjustForRegion, data) | |||
end | |||
function Adjusted_WM16(base, data) | |||
eeObj.WriteMem16(base + AdjustForRegion, data) | |||
end | end | ||
function Adjusted_WM8(base, data) | |||
eeObj.WriteMem8(base + AdjustForRegion, data) | |||
end | |||
function Adjusted_WMFloat(base, data) | |||
eeObj.WriteMemFloat(base + AdjustForRegion, data) | |||
end | |||
function Adjusted_RM32(base) | |||
return eeObj.ReadMem32(base + AdjustForRegion) | |||
end | |||
function Adjusted_RM16(base) | |||
return eeObj.ReadMem16(base + AdjustForRegion) | |||
end | |||
function Adjusted_RM8(base) | |||
return eeObj.ReadMem8(base + AdjustForRegion) | |||
end | end | ||
eeObj. | function Adjusted_RMStr(base) | ||
return eeObj.ReadMemStr(base + AdjustForRegion) | |||
end | |||
function Adjusted_RMFloat(base) | |||
return eeObj.ReadMemFloat(base + AdjustForRegion) | |||
end | |||
function Adjusted_W_bitset_8(base, bit) | |||
local u8val = eeObj.ReadMem8(base + AdjustForRegion) | |||
local bitmask = 1 << bit | |||
u8val = u8val | bitmask | |||
eeObj.WriteMem8(base + AdjustForRegion, u8val) | |||
end | |||
function Adjusted_W_bitclear_8(base, bit) | |||
local u8val = eeObj.ReadMem8(base + AdjustForRegion) | |||
local bitmask = 1 << bit | |||
bitmask = bitmask ~0xff | |||
u8val = u8val & bitmask | |||
eeObj.WriteMem8(base + AdjustForRegion, u8val) | |||
end | |||
function Adjusted_R_bit_8(base, bit) | |||
local u8val = eeObj.ReadMem8(base + AdjustForRegion) | |||
local bitmask = 1 << bit | |||
u8val = u8val & bitmask | |||
u8val = u8val >> bit | |||
return u8val | |||
end | |||
function NeoGeo_WM8(address, data) | |||
local tempaddress = address & ~3 | |||
address = address & 3 | |||
if (address==0) then | |||
tempaddress = tempaddress + 1 | |||
elseif (address==1) then | |||
tempaddress = tempaddress + 0 | |||
elseif (address==2) then | |||
tempaddress = tempaddress + 3 | |||
elseif (address==3) then | |||
tempaddress = tempaddress + 2 | |||
end | end | ||
eeObj.WriteMem8(tempaddress, data) | |||
end | |||
function NeoGeo_RM8(address) | |||
local tempaddress = address & ~3 | |||
address = address & 3 | |||
if (address==0) then | |||
tempaddress = tempaddress + 1 | |||
elseif (address==1) then | |||
tempaddress = tempaddress + 0 | |||
elseif (address==2) then | |||
tempaddress = tempaddress + 3 | |||
elseif (address==3) then | |||
tempaddress = tempaddress + 2 | |||
end | |||
return eeObj.ReadMem8(tempaddress) | |||
end | end | ||
local | local currentGame = -1 | ||
local | local lastRomBase = -1 | ||
local | local textVramBase = -1 -- address of text VRAM for emulated NeoGeo | ||
local | local RamBase = -1; -- address of main ram for emulated NeoGeo | ||
local ActivateOptionsMenu = function() | |||
OptionsMenuActive = 1 | |||
ShowArtMenu() | |||
ShowScanMenu() | |||
end | |||
local DeActivateOptionsMenu = function() | |||
OptionsMenuActive = 0 | |||
HideArtMenu() | |||
HideScanMenu() | |||
end | |||
-- | --[[ The Player Control menus don't have room for our new bezel and scanline options, | ||
so remove them if they are present. (They should be present for the main Options screen | |||
but not for the gameplay options screens) | |||
--]] | |||
local PlayerCtrlMenuOn = function() | |||
if (OptionsMenuActive == 1) then | |||
RestoreNewMenus = true | |||
DeActivateOptionsMenu() | |||
end | |||
end | end | ||
local | --[[ When a Player Control menu goes away, we may need to restore our new bezel and scanline | ||
local | options. | ||
--]] | |||
local PlayerCtrlMenuOff = function() | |||
if (RestoreNewMenus == true) then | |||
ActivateOptionsMenu() | |||
end | |||
RestoreNewMenus = false | |||
end | |||
local lastR1 = -1 | |||
local lastL1 = -1 | |||
local lastR2 = -1 | |||
local lastL2 = -1 | |||
local CheckInputs = function() | |||
-- This entire piece of code needs to be blocked out unless the menu is active and displayed | |||
if OptionsMenuActive ~= 1 then | |||
return | |||
end | |||
local | local pad_bits = emuObj.GetPad() | ||
local | local UP = pad_bits & 0x0010 | ||
local | local DOWN = pad_bits & 0x0040 | ||
local | local LEFT = pad_bits & 0x0080 | ||
local | local RIGHT = pad_bits & 0x0020 | ||
local Triangle = pad_bits & 0x1000 | |||
local | local Cross = pad_bits & 0x4000 | ||
local | local Square = pad_bits & 0x8000 | ||
local | local Circle = pad_bits & 0x2000 | ||
local | local L1 = pad_bits & 0x0400 | ||
local L2 = pad_bits & 0x0100 | |||
local | local L3 = pad_bits & 0x0002 | ||
local | local R1 = pad_bits & 0x0800 | ||
local | local R2 = pad_bits & 0x0200 | ||
local | local R3 = pad_bits & 0x0004 | ||
local Select = pad_bits & 0x0001 | |||
local Start = pad_bits & 0x0008 | |||
if | if (L2 ~= 0) and (L2 ~= lastL2) then | ||
print( string.format(" | --print( string.format("L2 Pressed\n" ) ) | ||
vid_mode = vid_mode - 1 | |||
if (vid_mode<0) then vid_mode = 2 end | |||
updateMode(vid_mode, vid_scanlines) | |||
ShowArtMenu() | |||
--print( string.format("FEATURE SCRIPT: VIDEO MODE IS NOW %d\n", vid_mode ) ) | |||
-- | |||
end | end | ||
end | |||
if (R2 ~= 0) and (R2 ~= lastR2) then | |||
--print( string.format("R2 Pressed\n" ) ) | |||
vid_mode = vid_mode + 1 | |||
if (vid_mode>2) then vid_mode = 0 end | |||
updateMode(vid_mode, vid_scanlines) | |||
ShowArtMenu() | |||
--print( string.format("FEATURE SCRIPT: VIDEO MODE IS NOW %d\n", vid_mode ) ) | |||
end | |||
if (L1 ~= 0) and (L1 ~= lastL1) then | |||
--print( string.format("L1 Pressed\n" ) ) | |||
vid_scanlines = vid_scanlines - 1 | |||
if (vid_scanlines<0) then vid_scanlines = 1 end | |||
updateMode(vid_mode, vid_scanlines) | |||
ShowScanMenu() | |||
--print( string.format("FEATURE SCRIPT: SCANLINES MODE IS NOW %d\n", vid_scanlines ) ) | |||
end | |||
if (R1 ~= 0) and (R1 ~= lastR1) then | |||
--print( string.format("R1 Pressed\n" ) ) | |||
vid_scanlines = vid_scanlines + 1 | |||
if (vid_scanlines>1) then vid_scanlines = 0 end | |||
updateMode(vid_mode, vid_scanlines) | |||
ShowScanMenu() | |||
--print( string.format("FEATURE SCRIPT: SCANLINES MODE IS NOW %d\n", vid_scanlines ) ) | |||
end | |||
lastL1 = L1 | |||
lastR1 = R1 | |||
lastL2 = L2 | |||
lastR2 = R2 | |||
end | end | ||
local VsyncFunc = function() | |||
function | |||
CheckInputs() | |||
local | local romBase = -1 | ||
if Region == 1 then | |||
romBase = Adjusted_RM32(0x02d89bc) | |||
elseif Region == 2 then | |||
romBase = Adjusted_RM32(0x02d89bc + 0x700) | |||
end | |||
if (romBase ~= lastRomBase) then | |||
lastRomBase = romBase | |||
--print( string.format("FEATURE SCRIPT : Rom Base %08x\n", romBase ) ) | |||
if (romBase == 0) then | |||
currentGame = -1 | |||
textVramBase = -1 | |||
RamBase = -1 | |||
--print( string.format("FEATURE SCRIPT : unloaded game, disable game specific trophies\n", romBase ) ) | |||
end | |||
if (romBase == 0) then | |||
--print( string.format("------------------- SETTING VOLUME FOR INTRO\n" ) ) | |||
emuObj.SetVolumes(INTROVOLUME, 1.0, 1.0); | |||
end | end | ||
end | if (romBase == 0x0020000) then | ||
end | --print( string.format("------------------- SETTING VOLUME FOR GAMES\n" ) ) | ||
emuObj.SetVolumes(GAMEVOLUME, 1.0, 1.0); | |||
end | |||
end | |||
if (currentGame == -1) then | |||
if (romBase ~= 0) then | |||
local checkString1 = eeObj.ReadMem32(romBase+0x100+0x0) | |||
local checkString2 = eeObj.ReadMem32(romBase+0x100+0x4) | |||
local checkString3 = eeObj.ReadMem32(romBase+0x100+0x8) | |||
--print( string.format("FEATURE SCRIPT : %08x %08x %08x", checkString1, checkString2, checkString3 ) ) | |||
if (checkString1 == 0x4f2d4e45) and (checkString2 == 0x4f004745) and (checkString3 == 0x00100055) then | |||
--print( string.format("FEATURE SCRIPT : 1994 1994 1994\n" ) ) | |||
currentGame = 94 | |||
end | |||
if (checkString1 == 0x4f2d4e45) and (checkString2 == 0x4f004745) and (checkString3 == 0x00100084) then | |||
--print( string.format("FEATURE SCRIPT : looks like we're KOF'95ing\n" ) ) | |||
currentGame = 95 | |||
end | |||
==== | if (checkString1 == 0x4f2d4e45) and (checkString2 == 0x4f104745) and (checkString3 == 0x00300214) then | ||
--print( string.format("FEATURE SCRIPT : Once upon a 1996\n" ) ) | |||
currentGame = 96 | |||
end | |||
-- | |||
if (checkString1 == 0x4f2d4e45) and (checkString2 == 0x4f104745) and (checkString3 == 0x00400232) then | |||
--print( string.format("FEATURE SCRIPT : it's 1997!\n" ) ) | |||
currentGame = 97 | |||
end | |||
if (checkString1 == 0x4f2d4e45) and (checkString2 == 0x4f104745) and (checkString3 == 0x00500242) then | |||
--print( string.format("FEATURE SCRIPT : Slugfest of '98!\n" ) ) | |||
currentGame = 98 | |||
end | |||
end | |||
end | |||
end | |||
local TextFunc = function() | |||
-- | if (currentGame ~= -1) then | ||
if (textVramBase == -1) then | |||
local base = eeObj.GetGPR(gpr.s0); | |||
local newText = base + 0xe000 | |||
if (newText ~= textVramBase) then | |||
--print( string.format("FEATURE SCRIPT : text base is %08x?!\n", newText ) ) | |||
textVramBase = newText | |||
if Region==1 then | |||
RamBase = Adjusted_RM32(0x002d89b0) | |||
elseif Region==2 then | |||
RamBase = Adjusted_RM32(0x002d89b0+0x700) | |||
end | |||
--print( string.format("FEATURE SCRIPT : RAM base is 0x%08x\n", RamBase ) ) | |||
end | |||
end | |||
end | |||
end | end | ||
if | local TurnOnScaleAndInterp = function() | ||
print | local game = eeObj.ReadMem32(0x32e7f4) | ||
if (game == 0xffffffff) then -- can get here from within challenge mode, don't turn on | |||
--print "_NOTE: Turning On Scale and Interp" | |||
gsObj.SetUprenderMode("2x2") | |||
gsObj.SetUpscaleMode("EdgeSmooth") | |||
end | end | ||
end | |||
if ( | local TurnOffScaleAndInterp = function() | ||
-- | local s2 = eeObj.GetGpr(gpr.s2) | ||
local choice = eeObj.ReadMem16(s2+0xe8) -- if choice is to return to main menu, no need to turn off | |||
if (choice < 3) then | |||
--print "_NOTE: Turning OFF Scale and Interp" | |||
gsObj.SetUprenderMode("none") | |||
gsObj.SetUpscaleMode("point") | |||
end | end | ||
end | end | ||
local EnterChallengeMode = function() | |||
TurnOffScaleAndInterp() | |||
end | |||
-- ---------- | if Region == 1 then -- US | ||
-- | -- set Default AutoSave to ON | ||
-- | eeInsnReplace(0x20f1d0, 0xae200014, 0xae250014) | ||
-- | |||
TextHook = eeObj.AddHook(0x001e0280+8,0x8c648a4c,TextFunc) | |||
OptOnHook1 = eeObj.AddHook(0x208d0c,0xffb20010,ActivateOptionsMenu) -- Options menu On | |||
-- | OptOffHook1 = eeObj.AddHook(0x208d8c,0xffb00000,DeActivateOptionsMenu) -- Options menu Off | ||
PlCtrlOnHook = eeObj.AddHook(0x1fc8fc,0xffb20010,PlayerCtrlMenuOn) -- Plyr Ctrl menu On | |||
PlCtrlOffHook = eeObj.AddHook(0x1fcbb4,0xffb00000,PlayerCtrlMenuOff) -- Plyr Ctrl menu Off | |||
SclIntrpOffHook = eeObj.AddHook(0x211980,0x26b0e7f4,TurnOffScaleAndInterp) -- Scale and Interp Off | |||
-- SclIntrpOnHook = eeObj.AddHook(0x21a1a4,0xffb00000,TurnOnScaleAndInterp) -- This is now called from LoadMainMenu_done | |||
eeObj.AddHook(0x210250, 0x24030001, EnterChallengeMode) | |||
elseif Region == 2 then -- EU | |||
eeInsnReplace(0x2107d8, 0xae200014, 0xae250014) | |||
TextHook = eeObj.AddHook(0x001e09a0+8,0x8c64914c,TextFunc) | |||
OptOnHook1 = eeObj.AddHook(0x20a10c,0xffb20010,ActivateOptionsMenu) | |||
OptOffHook1 = eeObj.AddHook(0x20a18c,0xffb00000,DeActivateOptionsMenu) | |||
PlCtrlOnHook = eeObj.AddHook(0x1fdb84,0xffb20010,PlayerCtrlMenuOn) -- Plyr Ctrl menu On | |||
PlCtrlOffHook = eeObj.AddHook(0x1fde3c,0xffb00000,PlayerCtrlMenuOff) -- Plyr Ctrl menu Off | |||
SclIntrpOffHook = eeObj.AddHook(0x212fc8,0x26b0eef4,TurnOffScaleAndInterp) -- Scale and Interp Off | |||
SclIntrpOnHook = eeObj.AddHook(0x21b9f4,0xffb00000,TurnOnScaleAndInterp) -- Scale and Interp On | |||
end | |||
MainHook = emuObj.AddVsyncHook(VsyncFunc) | |||
local StartSNK = function() | |||
--print( string.format("FEATURE SCRIPT : ================== BEGIN SNK LOGO DISPLAY ===============\n" ) ) | |||
snklogo = 1 | |||
updateMode(SaveData.vid_mode, SaveData.vid_scanlines) | |||
-- | --print( string.format("------------------- SETTING VOLUME FOR INTRO\n" ) ) | ||
emuObj.SetVolumes(INTROVOLUME, 1.0, 1.0); | |||
emuObj.ThrottleNorm() -- end of initial load, restore to normal speed | |||
--print "_NOTE: End of boot load, ThrottleNorm" | |||
end | |||
local StartVideo = function() | |||
--print( string.format("FEATURE SCRIPT : ================== BEGIN VIDEO ===============\n" ) ) | |||
snklogo = 0 | |||
updateMode(SaveData.vid_mode, SaveData.vid_scanlines) | |||
end | |||
if Region == 1 then | |||
emuObj.AddSectorReadHook(776480, 32, StartSNK) | |||
emuObj.AddSectorReadHook(200000, 16, StartVideo) | |||
elseif Region == 2 then | |||
emuObj.AddSectorReadHook(9696, 32, StartSNK) | |||
emuObj.AddSectorReadHook(580324, 16, StartVideo) | |||
end | end | ||
'' | -- --------------------------------------------------- | ||
-- the global function 'Global_InitGpuResources()' is invoked by the emulator after | |||
-- the GS has been initialized. Textures and Shaders must be loaded here. | |||
-- | |||
Global_InitGpuResources = function() | |||
-- # Fragment Shader 0 is fixed as the default no-thrills as-is renderer. | |||
emuObj.LoadFsShader(1, "./shader_scanlines_any_p.sb") -- (1) = Scanlines for SNK logo | |||
emuObj.LoadFsShader(2, "./shader_SL480_p.sb") -- (2) = 480P ScanLine Sim | |||
texture1.Load("./PS2_Classics_for_PS4_KOF98_OROCHI_1.png") | |||
texture2.Load("./PS2_Classics_for_PS4_KOF98_OROCHI_2.png") | |||
texture3.Load("./SNK_LOGO.png") | |||
texture4.Load("./p1.png") | |||
texture5.Load("./p2.png") | |||
texture6.Load("./p1d.png") | |||
texture7.Load("./p2d.png") | |||
-- texture8.Load("./SNK_LOGO_sl.png") WBD not needed | |||
local | local p1_w,p1_h = texture4.GetSize() | ||
local | local p2_w,p2_h = texture5.GetSize() | ||
local p1d_w,p1d_h = texture6.GetSize() | |||
local p2d_w,p2d_h = texture7.GetSize() | |||
notify_p1_xsize = p1_w | |||
notify_p2_xsize = p2_w | |||
notify_p1d_xsize = p1d_w | |||
notify_p2d_xsize = p2d_w | |||
notify_ysize = p1_h | |||
-- | spr_p1_notify.BindTexture(4) | ||
-- | spr_p1_notify.SetPosXY(-1 - notify_p1_xsize, notify_ypos) -- default position is fully obscured from view | ||
spr_p1_notify.SetSizeXY(p1_w,p1_h) | |||
spr_p1_notify.SetPosUV(0,0) | |||
spr_p1_notify.SetSizeUV(p1_w,p1_h) | |||
spr_p1_notify.SetBlendColorEquation(blendDefaultEquation) | |||
-- | spr_p2_notify.BindTexture(5) | ||
-- | spr_p2_notify.SetPosXY(-1 - notify_p2_xsize, notify_ypos) -- default position is fully obscured from view | ||
spr_p2_notify.SetSizeXY(p2_w,p1_h) | |||
spr_p2_notify.SetPosUV(0,0) | |||
spr_p2_notify.SetSizeUV(p2_w,p1_h) | |||
spr_p2_notify.SetBlendColorEquation(blendDefaultEquation) | |||
-- | spr_p1d_notify.BindTexture(6) | ||
spr_p1d_notify.SetPosXY(-1 - notify_p1d_xsize, notify_ypos) -- default position is fully obscured from view | |||
local | spr_p1d_notify.SetSizeXY(p1d_w,p1_h) | ||
-- | spr_p1d_notify.SetPosUV(0,0) | ||
-- | spr_p1d_notify.SetSizeUV(p1d_w,p1_h) | ||
spr_p1d_notify.SetBlendColorEquation(blendDefaultEquation) | |||
spr_p2d_notify.BindTexture(7) | |||
spr_p2d_notify.SetPosXY(-1 - notify_p2d_xsize, notify_ypos) -- default position is fully obscured from view | |||
spr_p2d_notify.SetSizeXY(p2d_w,p1_h) | |||
spr_p2d_notify.SetPosUV(0,0) | |||
spr_p2d_notify.SetSizeUV(p2d_w,p1_h) | |||
spr_p2d_notify.SetBlendColorEquation(blendDefaultEquation) | |||
--[[ Additional graphics for Menu Notifications --]] | |||
texture9.Load("./menuart0.png") | |||
texture10.Load("./menuart1.png") | |||
texture11.Load("./menuart2.png") | |||
texture12.Load("./menuscanoff.png") | |||
texture13.Load("./menuscanonn.png") | |||
-- all menu text replacement files are 720x34 at the moment.. | |||
local menu_w,menu_h = texture9.GetSize() | |||
extra_menu_h = menu_h | |||
extra_menu_w = menu_w | |||
sprite_artmenu.BindTexture(9) -- default | |||
sprite_scanmenu.BindTexture(12) -- default | |||
--HideArtMenu() WBD not needed | |||
--HideScanMenu() WBD not needed | |||
DeActivateOptionsMenu() | |||
end | end | ||
--[[************************************************************************************ | |||
Attempt to speed up some load times | |||
**************************************************************************************** --]] | |||
-- | |||
local | -- called when initial "Loading..." message is displayed onscreen (after Playstation 2 logo) | ||
local | -- | ||
local BootLoad_start = function() | |||
local a1 = eeObj.GetGpr(gpr.a1) | |||
if (a1 == 0x389c90) then | |||
emuObj.ThrottleFast() | |||
--print "_NOTE: Start of boot load, Throttle Fast" | |||
end | |||
end | |||
local | --[[ | ||
-- no longer needed, as this is called from StartSNK when the SNK logo is displayed | |||
-- | |||
local BootLoad_done = function() | |||
emuObj.ThrottleNorm() | |||
--print "_NOTE: End of boot load, ThrottleNorm" | |||
end | |||
]]-- | |||
-- called when the introductory video is killed and the Main Menu is loaded | |||
-- | |||
local LoadMainMenu_start = function() | |||
emuObj.ThrottleFast() | |||
--print "_NOTE: Start of main menu load, Throttle Fast" | |||
end | |||
-- called when load of Main Menu is done | |||
-- | |||
local LoadMainMenu_done = function() | |||
TurnOnScaleAndInterp() -- preserve pre-existing hook at this same location | |||
emuObj.ThrottleNorm() | |||
--print "_NOTE: End of main menu load, Throttle Normal" | |||
end | |||
-- | -- called when a game is selected from the main menu | ||
-- | |||
-- | local LoadGameFromMainMenu_start = function() | ||
-- | emuObj.ThrottleFast() | ||
--print "_NOTE: Start game load, Throttle Fast" | |||
end | |||
local LoadGameFromMainMenu_done = function() | |||
emuObj.ThrottleNorm() | |||
--print "_NOTE: End of game load, Throttle Normal" | |||
end | |||
-- called after Player Selection when the match is loaded | |||
-- For most games, there will be music playing and the call to ThrottleMax will be ignored. | |||
-- However for KOF09 and Challenge mode, which have some of the longest load times, the music will | |||
-- be killed after Player Selection. | |||
-- | |||
local LoadIntoGameplay_start = function() | |||
local ra = eeObj.GetGpr(gpr.ra) -- only speed up for a particular calling function | |||
if (ra == 0x1c11a0) then | |||
--print "_NOTE: Throttle Max" | |||
emuObj.ThrottleMax() | |||
end | |||
end | |||
local music_to_kill = 0xffffffff -- will contain a handle to bg music that we want to kill during loading | |||
-- | -- This will detect if the Player Selection music is running for KOF98 or Challenge mode | ||
-- We want to allow the music to play during player selection, but be killed before the match is loaded | |||
-- | |||
local CheckMusic = function() | |||
music_to_kill = 0xffffffff | |||
local s0 = eeObj.GetGpr(gpr.s0) -- s0 is a pointer to the music filename | |||
if (s0 ~= 0) then | |||
local music = eeObj.ReadMemStr(s0) | |||
--print (string.format("_NOTE: Music starting... %s", music)) | |||
if (music == "kof98_bgm_23.at3") then | |||
music_to_kill = eeObj.GetGpr(gpr.v0) -- save the bg handle for this music | |||
--print (string.format("_NOTE: We will kill this handle (%x) later", music_to_kill)) | |||
end | |||
end | |||
end | |||
local | -- When the game issues a call to fade out the Player Selection music, it usually takes a very long time. This | ||
local | -- will kill it quickly so we can use ThrottleMax. | ||
local | -- | ||
local KillMusic = function() | |||
local a1 = eeObj.GetGpr(gpr.a1) | |||
local bgmh = eeObj.ReadMem32(0x32e394) | |||
--print (string.format("_NOTE: should we kill this? bgmh = %x a1 = %x", bgmh, a1)) | |||
if ((bgmh == a1) and (a1 == music_to_kill)) then | |||
--print (string.format("_NOTE: Killing BG Music, handle = %x", bgmh)) | |||
eeObj.SetFpr(13, 0.0) -- kill this sound immediately | |||
end | |||
end | |||
eeObj.AddHook(0x18acac, 0x27bdfb40, BootLoad_start) -- initial load | |||
--eeObj.AddHook(0x1f641c, 0x8e220034, BootLoad_done) -- this is done in StartSNK (logo is displayed) | |||
eeObj.AddHook(0x1ced34, 0xffb00000, LoadMainMenu_start) -- load main menu from start screen | |||
eeObj.AddHook(0x21a1a4, 0xffb00000, LoadMainMenu_done) | |||
-- | |||
eeObj.AddHook(0x20befc, 0xffb00000, LoadGameFromMainMenu_start) -- load game from main menu | |||
eeObj.AddHook(0x218d2c, 0x3c040033, LoadGameFromMainMenu_done) | |||
eeObj.AddHook(0x195b68, 0xae42e394, CheckMusic) -- see if we're starting music we may need to kill later | |||
eeObj.AddHook(0x196134, 0x24060001, KillMusic) -- force kill player selection music | |||
eeObj.AddHook(0x1ec944, 0x3c030035, LoadIntoGameplay_start) -- between player selection and gameplay | |||
--[[ | |||
-- Fix vertical lines (by forcing gCurrentGamePIXX to be 320). This constant is natively 304, which | |||
-- when divided into 640 gives you not exactly 2. This is apparently causing some rounding errors when | |||
-- blitting sprites. Forcing the screen width to 320 removes the problem. The side effect is that the | |||
-- screen is horizontally compressed by a very very small amount. | |||
local forceHorzScrnRes = function() | |||
eeObj.SetGpr(gpr.a3, 0x140) | |||
print "_NOTE: *******************************> Forcing Horz Scrn Res" | |||
end | end | ||
eeObj.AddHook(0x1dc3dc, 0x3c050033, forceHorzScrnRes) | |||
eeObj. | ]]-- | ||
</pre> | </pre> | ||
==== | ====King of Fighters 98 Ultimate Match==== | ||
ALL | |||
<br>CLI | <br>CLI | ||
<pre>--force-frame-blend=1 | |||
<pre> | --gs-use-deferred-l2h=0 | ||
#Graphical fix.</pre> | |||
--force-frame-blend=1 | |||
-- | |||
-- | |||
- | SLES_552.80 | ||
<br>SLES-55280_features.lua | |||
<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 3,251: | ||
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 4,513: | ||
-- 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> | ||