Editing Official Configuration Files

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

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 48 here?
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
'''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>
-- ps2isd_hash=5c8433ad15a27ffa : GENERATED BY SCRIPT FOR LOCAL RUNENV USE ONLY (  
local gpr = require("ee-gpr-alias")
-- Title:  ADK Tamashii PS2 - SLPS-25906 (JPN)
require( "ee-hwaddr" )
-- Author:  Ernesto Corvi
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.


-- Changelog:
local eeObj = getEEObject()
-- v1.1: Added video mode support
 
-- v1.4: Adjusted SNK logo timing
-- -- never gonna die
-- v1.5: Adjusted Main Volume
-- eeInsnReplace(  0x2bd0a0, 0x27bdfff0, 0x03e00008) -- addiu sp,sp,-16
-- v2.0: Fixed Bug 10184
-- eeInsnReplace(  0x2bd0a4, 0x3c02003e, 0x00000000) -- lui v0,0x3e


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


local eeObj = getEEObject()
-- performance fix bug #9789
local emuObj = getEmuObject()
local emuObj = getEmuObject()
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { } )
emuObj.SetGsTitleFix( "includeAreaUpdate", "reserved" , {alpha = 0x80000048 } )
emuObj.SetGsTitleFix( "ignoreUpRender", 50 , { } )


local gpr = require("ee-gpr-alias")
local kFilterMode, kWrapMode, kBlendMultiplier, kBlendFunc = require("sprite")
local PadConnectType = require("pad-connect-type")


HIDPad_Enable()


emuObj.SetVolumes(0.3, 1.0, 1.0);
</pre>


local snklogo = 0
local scanlogos = 0


local L1 = function()
local flag = eeObj.GetGpr(gpr.a2)
if flag ~= 0 then
emuObj.ThrottleMax()
end
end


local L2 = function()
====Arc the Lad: Twilight of the Spirits™====
emuObj.ThrottleNorm()
SCUS 972.31
end
<br>Cli
<pre>
--gs-force-bilinear=1
--gs-kernel-cl-up="up2x2Simple"
--lopnor-config=1
</pre>


eeObj.AddHook(0x175a40, 0x8c468650, L1)
SCUS 972.31
eeObj.AddHook(0x19af40, 0x27bdfff0, L2)
<br>lua
<pre>
require("ee-gpr-alias")
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.


-----------------------
eeObj = getEEObject()
-- Video Options
-----------------------


local SaveData = emuObj.LoadConfig(0)
-- Bug#8359 (see bugzilla for the detail)
-- Skip FadeSet call if map is 'Scrappe Plateau' and the latest loaded script file is 'evt03B_07_0.moc'.
-- This game seems to have a problem (sensitive) with frame count on the script engine.
-- On our emulator, frame counting is slightly different from the original.
-- therefore it reads out 'overun' script command, which is 'cmd_fade' to fade-in.
-- At here, we will skip FADE-IN command if the situation meets the requirement.
skip_fade_flag = { map_name = false, file_name = false }


if SaveData.vid_mode == nil then
-- fade skip Bug#8359. skip FadeSet if skip_fade_flag meets the requirement.
SaveData.vid_mode      = 1
eeObj.AddHook(  0x13c464, 0x8e0500c0, function()
end
  -- print(skip_fade_flag.map_name)
  -- print(skip_fade_flag.file_name)
  if skip_fade_flag.map_name and skip_fade_flag.file_name then
  -- print("SKIP FADE")
  eeObj.SetPc(0x13c470)
  skip_fade_flag.map_name = false
  skip_fade_flag.file_name = false
  end
end)


if SaveData.vid_scanlines == nil then
-- cmd_read_file(const char* filename)
SaveData.vid_scanlines  = 1
eeObj.AddHook(0x13dad0, 0x27bdffc0, function()
end
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)


local sprite0 = getSpriteObject(0)
-- cmd_map_name(const char* mapname)
local sprite1 = getSpriteObject(1)
eeObj.AddHook(0x13f138, 0x0080282d, function()
local sprite2 = getSpriteObject(2)
local mapname = eeObj.ReadMemStr(eeObj.GetGpr(gpr.a0))
local sprite3 = getSpriteObject(3)
-- 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)


-- Notifications should be assigned to two unused sprite slots.  Since we want them to
</pre>
-- 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)


-- note: Texture 0 is fixed as the PS2 scanout.
====Canis Canem Edit (Bully)====
local texture1 = getTextureObject(1)
<br>CLI
local texture2 = getTextureObject(2)
<pre>--fpu-accurate-mul-fast=1
local texture3 = getTextureObject(3)
--fpu-muldiv-range=0x3fa5c0,0x3fa5c0
local texture4 = getTextureObject(4)
--gs-flush-ad-xyz=SafeZWrite
local texture5 = getTextureObject(5)
--vu1-opt-vf00=2
local texture6 = getTextureObject(6)
--vu1-di-bits=0
local texture7 = getTextureObject(7)
--ee-hook=0x001f3ef4,FastForwardClock
local texture8 = getTextureObject(8)
--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
local STATE_STOPPED = 0
<br>LUA
local STATE_RUNNING = 1
<pre>apiRequest(0.1)


local notify_ypos = 24
-- EA sports cricket 07 bug 9392
local notify_p1_xsize = 0
-- Performance fix
local notify_p2_xsize = 0
local emuObj = getEmuObject()
local notify_p1d_xsize = 0
local thresholdArea = 600
local notify_p2d_xsize = 0
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80000044 , zmsk=1 , tw=4, th=4  } )</pre>
local notify_ysize = 0


local notify_frames_p1 = 0
local notify_frames_p2 = 0
local notify_animstate_p1 = STATE_STOPPED
local notify_animstate_p2 = STATE_STOPPED


local connected_p1 = 47
SLUS-21269
local connected_p2 = 47
<br>SLUS-21269_features.lua
local blink_on_p1 = true
<pre>This is a substantial file. Over 150 lines with an extensive performance fix. I'm sharing the file itself as a download link.
local blink_on_p2 = true


-- ---------------------------------------------------
https://drive.google.com/file/d/12gt2fONqMP1rmEB9UMw3rIpEYbz1dQq8/view
-- 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("./ART1.png")
texture2.Load("./ART2.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")


local p1_w,p1_h = texture4.GetSize()
#Official widescreen support.</pre>
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)
====Destroy All Humans====
spr_p1_notify.SetPosXY(-1 - notify_p1_xsize, notify_ypos)  -- default position is fully obscured from view
SLUS_209.45
    spr_p1_notify.SetSizeXY(p1_w,p1_h)
<br>CLI
spr_p1_notify.SetPosUV(0,0)
<pre>--gs-use-mipmap=1
    spr_p1_notify.SetSizeUV(p1_w,p1_h)
--gs-kernel-cl="mipmap"
spr_p1_notify.SetBlendColorEquation(blendDefaultEquation)
--gs-kernel-cl-up="mipmap2x2"
--gs-ignore-dirty-page-border=1
--fpu-accurate-addsub-range=0x28bf00,0x28c100
#Fix for graphical glitches.</pre>


spr_p2_notify.BindTexture(5)
SLUS_209.45
spr_p2_notify.SetPosXY(-1 - notify_p2_xsize, notify_ypos)   -- default position is fully obscured from view
<br>SLUS-20945_features.lua
    spr_p2_notify.SetSizeXY(p2_w,p1_h)
<pre>-- Lua 5.3
spr_p2_notify.SetPosUV(0,0)
-- Title:   Destroy All Humans! PS2 - SLUS-20945 (USA)
    spr_p2_notify.SetSizeUV(p2_w,p1_h)
-- Author:  Ernesto Corvi, Adam McInnis
spr_p2_notify.SetBlendColorEquation(blendDefaultEquation)


spr_p1d_notify.BindTexture(6)
-- Changelog:
spr_p1d_notify.SetPosXY(-1 - notify_p1d_xsize, notify_ypos)  -- default position is fully obscured from view
    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)
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
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)
end


local update_notifications_p1 = function()
local eeObj = getEEObject()
local emuObj = getEmuObject()
local gpr = require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])


if notify_animstate_p1 == STATE_STOPPED then
-- Widescreen
spr_p1_notify.Disable()
eeObj.AddHook(0x308270, 0x3c0336c5, function() -- Graphics::Script::SetScreenRatio
spr_p1d_notify.Disable()
local mode = eeObj.GetGpr(gpr.v0)
return
end
-- print(string.format("mode: %08x", mode))
 
L2()
if mode == 0x36c59d2b then -- widescreen
 
emuObj.SetDisplayAspectWide()
local keyframe = 15
elseif mode == 0x855a87ef then -- standard
 
emuObj.SetDisplayAspectNormal()
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("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("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
end)


if connected_p1 == true then
eeObj.AddHook(0x3078F4, 0xae0000f4, function() -- Graphics::Renderer::Renderer
spr_p1_notify.SetBlendColor(1.0,1.0,1.0,1.0)
local renderer = eeObj.GetGpr(gpr.s0)
spr_p1_notify.SetPosXY(math.floor((1920-notify_p1_xsize)/2), notify_ypos)
eeObj.WriteMemFloat(renderer+0x200, 1.3333333)
spr_p1_notify.Enable()
eeObj.WriteMemFloat(renderer+0x204, 1.7777777)
end
eeObj.WriteMem32(renderer+0x208, 2)
end)


if connected_p1 == false then
emuObj.SetDisplayAspectWide()
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 update_notifications_p2 = function()
-- CRC "settings.display.widescreen" = 0xbcf14d81
-- $s2 = SaveType (1 = new save)


if notify_animstate_p2 == STATE_STOPPED then
local overlay = InsnOverlay({
spr_p2_notify.Disable()
0x27bdffe0, -- addiu $sp, -0x20
spr_p2d_notify.Disable()
0xffbf0010, -- sd $ra, 0x10($sp)
return
0x0c0d49d8, -- jal Core::Memset(void *,int,uint)
end
0x00000000, -- nop
 
0x24030001, -- li $v1, 1
L2()
0x1472000b, -- bne $s2, $v1, +11
 
0x00000000, -- nop
local keyframe = 15
0x0c09dacc, -- jal UFO::Progress::Get(void)
 
0x00000000, -- nop
notify_frames_p2 = notify_frames_p2 + 1
0x3c01bcf1, -- lui $at, 0xbcf1
 
0x34214d81, -- ori $at, $at, 0x4d81
if math.ceil(notify_frames_p2/keyframe) == notify_frames_p2/keyframe then blink_on_p2 = not blink_on_p2 end
0xafa10000, -- sw $at, 0($sp)
if blink_on_p2 == true then notify_ypos = 24 + notify_ysize + 8 end
0x24030001, -- li $v1, 1
if blink_on_p2 == false then notify_ypos = -84 - notify_ysize - 8 end
0xa3a30004, -- sb $v1, 4($sp)
 
0x03a0282d, -- move $a1, $sp
-- print(string.format("rounded %s, floating %s, blink %s ypos %s", math.ceil(notify_frames_p2/keyframe), notify_frames_p2/keyframe, blink_on_p2, notify_ypos))
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>


if notify_frames_p2 >= 225 then
====Destroy All Humans 2====
notify_animstate_p2 = STATE_STOPPED
SLUS_214.39
notify_frames_p2 = 0
<br>CLI
connected_p2 = 47
<pre>--gs-use-mipmap=1
end
--gs-kernel-cl="mipmap"
--gs-kernel-cl-up="mipmap2x2"
#Fix for graphical glitches.</pre>


-- print(string.format("connected_p1 %s, connected_p2 %s", connected_p1, connected_p2))
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


if connected_p2 == true then
-- Changelog:
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)
spr_p2_notify.Enable()
end


if connected_p2 == false then
apiRequest(0.7) -- request version 0.1 API. Calling apiRequest() is mandatory.
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
local eeObj = getEEObject()
local emuObj = getEmuObject()
local gpr = require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])


-- slot can range from 0 to 3, for users 1 thru 4.
-- Widescreen
-- pad_type can be either:  DS4, REMOTE_DS4, REMOTE_VITA, or HID
eeObj.AddHook(0x33ca98, 0x3c0436c5, function() -- Graphics::Script::SetScreenRatio
local onHIDPadEvent = function(slot, connected, pad_type)
local mode = eeObj.GetGpr(gpr.v0)
spr_p1_notify.Disable()
spr_p1d_notify.Disable()
-- print(string.format("mode: %08x", mode))
spr_p2_notify.Disable()
spr_p2d_notify.Disable()
if mode == 0x36c59d2b then -- widescreen
-- print(string.format("slot %s, connected %s, pad_type %s", slot, connected, pad_type))
emuObj.SetDisplayAspectWide()
if pad_type == PadConnectType.HID then
elseif mode == 0x855a87ef then -- standard
notify_frames_p1 = 0
emuObj.SetDisplayAspectNormal()
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 = {
eeObj.AddHook(0x33afac, 0x0000282d, function() -- Graphics::Renderer::Renderer
240.0, -- float scanlineCount
eeObj.SetGpr(gpr.a1, 2)
  0.7, -- float scanlineHeight;
end)
1.5,        -- float scanlineBrightScale;
0.5,       -- float scanlineAlpha;
0.5        -- float vignetteStrength;
}


-- ---------------------------------------------------
emuObj.SetDisplayAspectWide()
-- Full Screen (480p) NoFX
-- ---------------------------------------------------


local original_mode = function()
-- CRC "settings.display.anamorphic" = 0x8b36afe9
if snklogo == 1 then
-- $s2 = SaveType (1 = new save)
sprite0.BindTexture(3)
sprite0.SetPosXY(0,0)
sprite0.SetSizeXY(1920,1080)
sprite0.SetPosUV(0,0)
sprite0.SetSizeUV(1920,1080)
else
sprite0.BindTexture(0)
sprite0.BindFragmentShader(0)
sprite0.SetPosXY((1920-1440)/2,0)
sprite0.SetSizeXY(1440,1080)
end
sprite0.Enable()
sprite1.Disable()
end


-- ---------------------------------------------------
local overlay = InsnOverlay({
-- Full Screen + ScanLines (480p)
0x27bdffe0, -- addiu $sp, -0x20
-- ---------------------------------------------------
0xffbf0010, -- sd $ra, 0x10($sp)
 
0x0c059d02, -- memset
local scanlines_mode = function()
0x00000000, -- nop
if snklogo == 1 then
0x24030001, -- li $v1, 1
sprite0.BindTexture(8)
0x1472000b, -- bne $s2, $v1, +11
sprite0.SetPosXY(0,0)
0x00000000, -- nop
sprite0.SetSizeXY(1920,1080)
0x0c09b400, -- jal UFO::Progress::Get(void)
sprite0.SetPosUV(0,0)
0x00000000, -- nop
sprite0.SetSizeUV(1920,1080)
0x3c01bcf1, -- lui $at, 0x8b36
sprite0.BindFragmentShader(1)
0x34214d81, -- ori $at, $at, 0xafe9
sprite0.SetShaderParams(scanlineParams)
0xafa10000, -- sw $at, 0($sp)
else
0x24030001, -- li $v1, 1
sprite0.BindTexture(0)
0xa3a30004, -- sb $v1, 4($sp)
sprite0.SetPosXY((1920-1440)/2,0)
0x03a0282d, -- move $a1, $sp
sprite0.SetSizeXY(1440,1080)
0x0c09dd4c, -- jal UFO::Progress::Record::AddKey(UFO::Progress::Content const&)
sprite0.BindFragmentShader(2)
0x0040202d, -- move $a0, $v0
sprite0.SetShaderParams(scanlineParams)
0xdfbf0010, -- ld $ra, 0x10($sp)
end
0x03e00008, -- jr $ra
sprite0.Enable()
0x27bd0020  -- addiu $sp, 0x20
sprite1.Disable()
})
end
local call_overlay = 0x0c000000 | (overlay >> 2)
 
eeInsnReplace(0x271AD0, 0x0c059d02, call_overlay) -- UFO::Progress::Storage::PrepareWrite
-- ---------------------------------------------------
-- Bezel NoFX
-- ---------------------------------------------------
local bezel_mode = function(bezel)
if snklogo == 1 then
sprite0.BindTexture(3)
sprite0.SetPosXY(0,0)
sprite0.SetSizeXY(1920,1080)
sprite0.SetPosUV(0,0)
sprite0.SetSizeUV(1920,1080)
else
sprite0.BindTexture(0)
sprite0.BindFragmentShader(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
end
sprite0.Enable()
 
sprite1.BindTexture(bezel)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end


-- ---------------------------------------------------
-- Disable Progressive Scan and Adjust Screen Position
-- Bezel + ScanLines (480p)
-- ---------------------------------------------------


local bezel_scanlines_mode = function(bezel)
local overlay2 = InsnOverlay({
if snklogo == 1 then
0x27bdfff0, -- addiu $sp, -0x10
sprite0.BindTexture(8)
0xffbf0000, -- sd $ra, 0(sp)
sprite0.SetPosXY(0,0)
0xffb00008, -- sd $s0, 8(sp)
sprite0.SetSizeXY(1920,1080)
0x3c05000f, -- lui $a1, 0x000f
sprite0.SetPosUV(0,0)
0x34a57000, -- ori $a1, 0x7000
sprite0.SetSizeUV(1920,1080)
0x0c0db8b6, -- jal Script::State::DoString
sprite0.BindFragmentShader(1)
0x0080802d, -- move $s0, $a0
sprite0.SetShaderParams(scanlineParams)
0x24050001, -- li $a1, 1
else
0x0c0dba4c, -- jal Script::State::IsNull(int)
sprite0.BindTexture(0)
0x0200202d, -- move $a0, $s0
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
0xdfb00008, -- ld $s0, 8(sp)
sprite0.SetSizeXY(1280,896)
0xdfbf0000, -- ld $ra, 0(sp)
sprite0.BindFragmentShader(2)
0x03e00008, -- jr ra
sprite0.SetShaderParams(scanlineParams)
0x27bd0010  -- addiu $sp, 0x10
end
})
sprite0.Enable()
local call_overlay2 = 0x0c000000 | (overlay2 >> 2)
eeInsnReplace(0x2e5a14, 0x0c0dba4c, call_overlay2) -- Sim::Manager::ProcessScript near Sim::Manager::SetPauseFlag


sprite1.BindTexture(bezel)
eeObj.AddHook(0x2e5a10, 0x0240202d, function() -- Sim::Manager::ProcessScript near Sim::Manager::SetPauseFlag
sprite1.SetPosXY(0,0)
local luaString = [[
sprite1.SetSizeXY(1920,1080)
-- disable progressive scan and adjust screen
sprite1.SetPosUV(0,0)
gui.i.SMOptionsDisplay.table.slots[3] = nil
sprite1.SetSizeUV(1920,1080)
gui.i.SMOptionsDisplay.table.slots[4] = nil
sprite1.Enable()
]]
end
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")


local updateMode = function(mode, scanlines)
apiRequest(1.5)
if scanlines == 1 then
if mode == 1 then
original_mode()
else
bezel_mode(mode - 1)
end
else
if mode == 1 then
scanlines_mode()
else
bezel_scanlines_mode(mode - 1)
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


local eeObj = getEEObject()
local emuObj = getEmuObject()


local vid_modeOptions = {"NONE", "ART1", "ART2"}
local patcher = function()
local vid_scanlineOptions = {"OFF", "ON"}
local vid_mode = SaveData.vid_mode
local vid_scanlines = SaveData.vid_scanlines


local updateVideoMode = function(mode)
--X-Fov - ELF hack
if mode > 32 then
--803f013c 00a88144 0045013c
vid_mode = vid_mode - 1
eeObj.WriteMem32(0x00100fcc,0x3c013f40) --3c013f80
elseif mode ~= 0 then
vid_mode = vid_mode + 1
end
if vid_mode < 1 then
vid_mode = #vid_modeOptions
elseif vid_mode > #vid_modeOptions then
vid_mode = 1
end
if mode ~= 0 then
updateMode(vid_mode, vid_scanlines)
end
end


local updateScanlineMode = function(mode)
--Memory hack
if mode > 32 then
--eeObj.WriteMem32(0x201FF100,0x43c00000)
vid_scanlines = vid_scanlines - 1
elseif mode ~= 0 then
vid_scanlines = vid_scanlines + 1
end
if vid_scanlines < 1 then
vid_scanlines = #vid_scanlineOptions
elseif vid_scanlines > #vid_scanlineOptions then
vid_scanlines = 1
end
if mode ~= 0 then
updateMode(vid_mode, vid_scanlines)
end
end


local V1 = function()
local data = eeObj.GetGpr(gpr.v1)
local menu = eeObj.GetGpr(gpr.a3)
local buf = eeObj.GetGpr(gpr.a2)
if menu == 17 then -- Position X (Artwork)
local mode = eeObj.ReadMem32(data + 0x10)
updateVideoMode(mode)
eeObj.WriteMemStrZ(buf, vid_modeOptions[vid_mode])
eeObj.SetGpr(gpr.a3, 0)
if mode ~= 0 then
eeObj.WriteMem32(data + 0x10, 0)
end
elseif menu == 18 then -- Position Y (Scanlines)
local mode = eeObj.ReadMem32(data + 0x14)
updateScanlineMode(mode)
eeObj.WriteMemStrZ(buf, vid_scanlineOptions[vid_scanlines])
eeObj.SetGpr(gpr.a3, 0)
if mode ~= 0 then
eeObj.WriteMem32(data + 0x14, 0)
end
end
end
end


eeObj.AddHook(0x16c13c, 0x268300a0, V1)
emuObj.AddVsyncHook(patcher)


eeInsnReplace(0x16BB64, 0x8e420010, 0x0040202d) -- move $a0, $v0
if 1 then
eeInsnReplace(0x16BC0C, 0x8e420014, 0x0040202d) -- move $a0, $v0
-- bug#10361 (intro slowdown) & bug#9823 (conveyor belt effect)
-- Use Deferred L2H except for conveyor belt effect.


eeObj.AddHook(0x180f40, 0x26300010, function()
-- Unsure if other convery or similar effects are present, so use permissive match for bypassing deferral.
local addr = eeObj.GetGpr(gpr.s0)
L2H_SetNonDeferred({TRXREG=0x0000000900000080}) -- match any TRXPOS or BITBLTBUF
local posx = {0x07, 0x00, 0x00, 0x03, 0x01, 0x82, 0x6f, 0x82, 0x6e, 0x82, 0x72, 0x82, 0x68, 0x82, 0x73, 0x82, 0x68, 0x82, 0x6e, 0x82, 0x6d, 0x81, 0x40, 0x82, 0x77}
local posy = {0x07, 0x00, 0x00, 0x03, 0x01, 0x82, 0x6f, 0x82, 0x6e, 0x82, 0x72, 0x82, 0x68, 0x82, 0x73, 0x82, 0x68, 0x82, 0x6e, 0x82, 0x6d, 0x81, 0x40, 0x82, 0x78}
local artw = {0x07, 0x00, 0x00, 0x03, 0x01, 0x81, 0x40, 0x82, 0x60, 0x82, 0x71, 0x82, 0x73, 0x82, 0x76, 0x82, 0x6e, 0x82, 0x71, 0x82, 0x6a, 0x81, 0x40, 0x81, 0x40}
local scan = {0x07, 0x00, 0x00, 0x03, 0x01, 0x82, 0x72, 0x82, 0x62, 0x82, 0x60, 0x82, 0x6d, 0x82, 0x6b, 0x82, 0x68, 0x82, 0x6d, 0x82, 0x64, 0x82, 0x72, 0x81, 0x40}
local found = true
for x = 1, #posx - 1 do
if eeObj.ReadMem8(addr+x-1) ~= posx[x] then
found = false
break
end
end
if found == true then
local repl
if eeObj.ReadMem8(addr+#posx-1) == posx[#posx] then
repl = artw
else
repl = scan
end
for x = 1, #repl do
eeObj.WriteMem8(addr+x-1, repl[x])
end
end
end)


 
-- Full specification of conveyor belt effect.
-- Fight stick
-- L2H_SetNonDeferred({BITBLTBUF=0x0000000013023240,TRXPOS=0x0000000000770000,TRXREG=0x0000000900000080})
local pad = function()
updateMode(SaveData.vid_mode, SaveData.vid_scanlines)
emuObj.AddVsyncHook(update_notifications_p1)
emuObj.AddVsyncHook(update_notifications_p2)
end
end


emuObj.AddPadHook(onHIDPadEvent)
emuObj.AddEntryPointHook(pad)


-- replace SNK logo
local PadStickRemap_EternalRing_Default = {
 
LR=PadStick.AxisRX_Pos,
local scanlogos_on = function()
LL=PadStick.AxisRX_Neg,
scanlogos = 1
LU=PadStick.AxisLY_Neg,
updateMode(SaveData.vid_mode, SaveData.vid_scanlines)
LD=PadStick.AxisLY_Pos,
end
 
L1=PadStick.AxisLX_Neg,
R1=PadStick.AxisLX_Pos,
L2=PadStick.AxisRY_Neg,
R2=PadStick.AxisRY_Pos,
}


local logos_anim = function()
local PadStickRemap_EternalRing_InvertY = {
if scanlogos == 1 then
L2=PadStick.AxisRY_Pos,
local a0 = eeObj.GetGpr(gpr.a0)
R2=PadStick.AxisRY_Neg,
local a1 = eeObj.GetGpr(gpr.a1)
}
-- print(string.format("anim: %08x, %08x", a0, a1))
if a1 == 2 then
local a040 = eeObj.ReadMem32(a0+0x40)
local a050 = eeObj.ReadMem32(a0+0x50)
-- print(string.format("stage 2: %08x, %08x", a040, a050))
if a050 == 0 and a040 ~= 0 then
local curFrame = eeObj.ReadMem32(a040+0x50)
-- print(string.format("stage 3: %08x", curFrame))
if curFrame == 0x9e then
print("SNK logo on")
snklogo = 1
updateMode(SaveData.vid_mode, SaveData.vid_scanlines)
end
elseif a050 == 2 then
print("SNK logo off")
snklogo = 0
updateMode(SaveData.vid_mode, SaveData.vid_scanlines)
scanlogos = 0
end
end
end
end


eeObj.AddHook(0x10026C, 0x0220202d, scanlogos_on)
emuObj.PadPressureStickRemap(0, PadStickRemap_EternalRing_Default)
eeObj.AddHook(0x16EAF0, 0x27bdff80, logos_anim)
</pre>


====Ape Escape 2====
-- Supporting Inverted Y Axis requires smoe menu changes, and should be done via features.lua
<br>SCES-50885
--emuObj.PadPressureStickRemap(0, PadStickRemap_EternalRing_InvertY) </pre>
====Everybody's Tennis/Hot Shots Tennis====
SCES_545.35
<br>CLI
<br>CLI
<pre>
<pre>--gs-use-deferred-l2h=0
--gs-use-mipmap=1
--l2h-2d-params=0x0000000800000010,0x00000000300a1400,256
--gs-kernel-cl="mipmap"
--gs-motion-factor=50
--gs-kernel-cl-up="mipmap2x2"
--mtap1=always
--gs-scanout-offsetx=27
--gs-opt-frbuff-switch=1
--vu1-injection=1
--gs-ignore-dirty-page-border=1
--gs-packed15-fmv-opt=1
--gs-ignore-rect-correction=1
--gs-skip-dirty-flush-on-mipmap=1
--ee-native-function=memcpy,0x11e328
--cop2-accurate-addsub-range=0x3151e8,0x315414
--ee-native-function=memset,0x11e4e0
</pre>
#performance and visual fix(?)</pre>
<br>SCES-50885
 
SCES_545.35
<br>LUA
<br>LUA
<pre>
<pre>local gpr = require("ee-gpr-alias")
local gpr = require("ee-gpr-alias")
require( "ee-hwaddr" )
require( "ee-hwaddr" )
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
apiRequest(1.4)


local eeObj = getEEObject()
local eeObj = getEEObject()


-- -- never gonna die
-- function dump(addr)
-- eeInsnReplace( 0x2bd0a0, 0x27bdfff0, 0x03e00008) -- addiu sp,sp,-16
--    print(string.format("=== dump %x ===", addr))
-- eeInsnReplace( 0x2bd0a4, 0x3c02003e, 0x00000000) -- lui v0,0x3e
--   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
-- performance fix bug #9789
-- This patch changes the color of background on :
local emuObj = getEmuObject()
-- - Language selection
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { } )
-- - Company logo
emuObj.SetGsTitleFix( "includeAreaUpdate", "reserved" , {alpha = 0x80000048 } )
-- - Start screen
emuObj.SetGsTitleFix( "ignoreUpRender", 50 , { } )
-- - 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
</pre>
-- 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>


====Arc the Lad: Twilight of the Spirits™====
====Fahrenheit/Indigo Prophecy====
SCUS 972.31
SLES_535.39
<br>Cli
<br>CLI
<pre>
<pre>--ee-hook=0x002097d0,FastForwardClock,0x8c6261fc
--gs-force-bilinear=1
--ee-hook=0x1a5570,AdvanceClock,,500000
--gs-kernel-cl-up="up2x2Simple"
--ee-hook=0x00223c48,AdvanceClock,0x0080382d,8000
--lopnor-config=1
--gs-kernel-cl="h2lpool"
</pre>
--gs-kernel-cl-up="h2lpool2x2"
#Performance fix.</pre>


SCUS 972.31
SLES_535.39
<br>lua
<br>LUA
<pre>
<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.
require("ee-gpr-alias")
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.


eeObj = getEEObject()
https://drive.google.com/file/d/1L2YxondID65KIAybKVCBH9KgFegqqOeQ/view


-- Bug#8359 (see bugzilla for the detail)
-- Performace fix (bug #9785 )
-- Skip FadeSet call if map is 'Scrappe Plateau' and the latest loaded script file is 'evt03B_07_0.moc'.
-- bug#8571
-- This game seems to have a problem (sensitive) with frame count on the script engine.
-- ignore 'no wait vsync' case.
-- On our emulator, frame counting is slightly different from the original.
-- unsyncv causes major slowness on loading screen, because the game pushes LOTS of identical frame data to GS.</pre>
-- 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.
SLES_535.39
eeObj.AddHook(  0x13c464, 0x8e0500c0, function()
<br>SLES-53539_features.lua
  -- print(skip_fade_flag.map_name)
<pre>-- Lua 5.3
  -- print(skip_fade_flag.file_name)
-- Title:  Fahrenheit PS2 - SLES-53539 (EUR)
  if skip_fade_flag.map_name and skip_fade_flag.file_name then
-- Author:  Ernesto Corvi, Adam McInnis
  -- 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)
-- Changelog:
eeObj.AddHook(0x13dad0, 0x27bdffc0, function()
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)
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
eeObj.AddHook(0x13f138, 0x0080282d, function()
require( "ee-cpr0-alias" ) -- for EE CPR
local mapname = eeObj.ReadMemStr(eeObj.GetGpr(gpr.a0))
-- 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>
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.


====Canis Canem Edit (Bully)====
local eeObj = getEEObject()
<br>CLI
local emuObj = getEmuObject()
<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
local L1 = function() -- QDT::SINT::SCRIPT_LOADING_SCREEN::EM::Run
<br>LUA
emuObj.ThrottleMax()
<pre>apiRequest(0.1)
end
local L2 = function() -- QDT::SINT::SCRIPT_LOADING_SCREEN::EM::Stop
emuObj.ThrottleNorm()
end
local load1 = eeObj.AddHook(0x387040, 0x3c02004b, L1) -- QDT::SINT::SCRIPT_LOADING_SCREEN::Run
local load2 = eeObj.AddHook(0x387090, 0x3c02004b, L2) -- QDT::SINT::SCRIPT_LOADING_SCREEN::Stop


-- EA sports cricket 07 bug 9392
-- Widescreen
-- Performance fix
eeInsnReplace(0x20a7c0, 0x3c013faa, 0x3c013fe3)
local emuObj = getEmuObject()
eeInsnReplace(0x20a7c4, 0x3421aaab, 0x34218e39)
local thresholdArea = 600
emuObj.SetDisplayAspectWide()
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80000044 , zmsk=1 , tw=4, th=4  } )</pre>


-- 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 }


SLUS-21269
-- locates src chunk on (dst,cnt). -1 if not found, offset if found
<br>SLUS-21269_features.lua
local locateChunk = function(src, dst, count)
<pre>This is a substantial file. Over 150 lines with an extensive performance fix. I'm sharing the file itself as a download link.
local offs = -1
for x = 0, count - #src do
if eeObj.ReadMem8(dst+x) == src[1] then
local found = true
for y = 1, #src do
if eeObj.ReadMem8(dst+x+y-1) ~= src[y] then
found = false
break
end
end
if found == true then
offs = x
break
end
end
end
return offs
end


https://drive.google.com/file/d/12gt2fONqMP1rmEB9UMw3rIpEYbz1dQq8/view
eeObj.AddHook(0x2812b0, 0x27bdfff0, function() -- QDT::VM::BYTE_CODE::BYTE_CODE
local obj = eeObj.GetGpr(gpr.a1)
local bytecode = eeObj.ReadMem32(obj+0x18)
local count = eeObj.ReadMem32(obj+0x20)
if count > #videomenuVM then
local offs = locateChunk(videomenuVM, bytecode, count)
if offs >= 0 then
print("Skipping video mode menu")
eeObj.WriteMem8(bytecode+offs+4, 8) -- beq 0x44 -> beq 0x8
end
end
if count > #visualmenuVM then
local offs = locateChunk(visualmenuVM, bytecode, count)
if offs >= 0 then
print("Skipping visual mode video menu")
eeObj.WriteMem8(bytecode+offs+1, 2) -- beq 0xa2 -> bne 0xa2
end
end
end)


#Official widescreen support.</pre>
-- Force 60hz
eeInsnReplace(0x207ae0, 0x00a0802d, 0x24100001) -- move $s0, $a1 -> li $s0, 1


====Destroy All Humans====
-- Fix for bug 9716, which is a bug in the game.
SLUS_209.45
-- Trying to retrieve a COM handle in the game will cause an infinite
<br>CLI
-- loop if the handle has been deallocated and the debug server is not
<pre>--gs-use-mipmap=1
-- connected. There's apparently a small race condition in the Asylum
--gs-kernel-cl="mipmap"
-- level that sometimes can trigger the bug.
--gs-kernel-cl-up="mipmap2x2"
-- The fix involves getting out of the loop.
--gs-ignore-dirty-page-border=1
-- It causes a small visual glitch but otherwise the game continues to work fine.
--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:


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>
--gs-kernel-cl-up="fantavision"
--gs-motion-factor=1
</pre>
'''LUA'''
<br>SCES-50002
<pre>
require("ee-gpr-alias")
require( "ee-hwaddr" )
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.


local eeObj = getEEObject()
eeObj = getEEObject()
local emuObj = getEmuObject()
local gpr = require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])


-- Widescreen
--
eeObj.AddHook(0x308270, 0x3c0336c5, function() -- Graphics::Script::SetScreenRatio
-- Bug#93709 (JP Bugzilla)
local mode = eeObj.GetGpr(gpr.v0)
-- 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.
-- print(string.format("mode: %08x", mode))
-- Game kicks  : PATH3(Context1) PATH1(Rendering using Context1&2) PATH3(Context2)
-- Game expects: PATH3(Context1) PATH3(Context2) PATH1(Rendering using Context1&2)
if mode == 0x36c59d2b then -- widescreen
-- Hence VIF1 DMA needs to be delayed.
emuObj.SetDisplayAspectWide()
eeObj.AddHook(0x1b1468, 0xae020000, function()
elseif mode == 0x855a87ef then -- standard
local ee = eeObj
emuObj.SetDisplayAspectNormal()
local s0 = ee.GetGpr(gpr.s0)
end
end)


eeObj.AddHook(0x3078F4, 0xae0000f4, function() -- Graphics::Renderer::Renderer
if s0 == vif1_hw.CHCR then
local renderer = eeObj.GetGpr(gpr.s0)
local chcr = ee.GetGpr(gpr.v0)
eeObj.WriteMemFloat(renderer+0x200, 1.3333333)
if (chcr & 0x05) == 0x05 then
eeObj.WriteMemFloat(renderer+0x204, 1.7777777)
  local tadr = ee.ReadMem32(vif1_hw.TADR)
eeObj.WriteMem32(renderer+0x208, 2)
  if tadr == 0x8883e0 or tadr == 0x9f6b60 then
  ee.SchedulerDelayEvent("vif1.dma", 0x5000)
  end
end
end
end)
end)


emuObj.SetDisplayAspectWide()


-- CRC "settings.display.widescreen" = 0xbcf14d81
-- Performace fix
-- $s2 = SaveType (1 = new save)
local emuObj = getEmuObject()
-- twIsLess=5 - texture width is less or eq. than 32
emuObj.SetGsTitleFix( "forcePointSampling", "reserved", {alpha = 0x80000048, twIsLess=5, thIsLess=5 } )
</pre>


local overlay = InsnOverlay({
====Fatal Fury: Battle Archives volume 2====
0x27bdffe0, -- addiu $sp, -0x20
ALL
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
<br>CLI
<pre>--gs-use-mipmap=1
<pre>--gs-uprender=none
--gs-kernel-cl="mipmap"
--gs-upscale=point
--gs-kernel-cl-up="mipmap2x2"
--host-audio-latency=0.010
#Fix for graphical glitches.</pre>
--force-frame-blend=1
#Graphical fix.</pre>


SLUS_214.39
SLUS_217.23
<br>SLUS-21439_features.lua
<br>SLUS-21723_features.lua
<pre>-- Lua 5.3
<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.
-- Title:  Destroy All Humans! 2 PS2 - SLUS-21439 (USA)
-- Author:  Ernesto Corvi, Adam McInnis


-- Changelog:
https://drive.google.com/file/d/1FPPPJiHOazTXaD-H6K3kLACYDSdDeAE1/view


apiRequest(0.7) -- request version 0.1 API. Calling apiRequest() is mandatory.
#official widescreen support in the form of screen bezels, along with expanded fightstick support and scanline shaders.</pre>


local eeObj = getEEObject()
====Fu'un Super Combo!!!====
local emuObj = getEmuObject()
SLPS_257.81
local gpr = require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
<br>CLI
<pre>--gs-uprender=2x2
--gs-upscale=point
--host-audio-latency=0.3
--ee-hook=0x127050,AdvanceClock,0x2403002b,0x4000
--ee-hook=0x106734,FastForwardClock,0x0c04149c
--ee-native-function=memcpy,0x11fa9c,0x0080402d
--force-frame-blend=1
--vif1-ignore-cmd-ints=1
#Graphical and performance fixes.</pre>


-- Widescreen
SLPS_257.81
eeObj.AddHook(0x33ca98, 0x3c0436c5, function() -- Graphics::Script::SetScreenRatio
<br>LUA
local mode = eeObj.GetGpr(gpr.v0)
<pre>
apiRequest(1.4)
-- print(string.format("mode: %08x", mode))
if mode == 0x36c59d2b then -- widescreen
emuObj.SetDisplayAspectWide()
elseif mode == 0x855a87ef then -- standard
emuObj.SetDisplayAspectNormal()
end
end)


eeObj.AddHook(0x33afac, 0x0000282d, function() -- Graphics::Renderer::Renderer
eeNativeFunction(0x11fa9c, 0x0080402d, 'memcpy')
eeObj.SetGpr(gpr.a1, 2)
eeNativeFunction(0x11fb48, 0x2cc20008, 'memset')
end)
 
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)


emuObj.SetDisplayAspectWide()
require("ee-gpr-alias")


-- CRC "settings.display.anamorphic" = 0x8b36afe9
local eeObj = getEEObject()
-- $s2 = SaveType (1 = new save)
local emuObj = getEmuObject()


local overlay = InsnOverlay({
-- *** viBufBeginPut (1)
0x27bdffe0, -- addiu $sp, -0x20
--eeInsnReplace(0x105628, 0x0c049c78, 0) -- jal 1271e0 <WaitSema>
0xffbf0010, -- sd $ra, 0x10($sp)
eeInsnReplace(0x1056c8, 0x0c049c70, 0) -- jal 1271c0 <SignalSema>
0x0c059d02, -- memset
-- *** viBufEndPut (1)
0x00000000, -- nop
eeInsnReplace(0x105708, 0x0c049c78, 0) -- jal 1271e0 <WaitSema>
0x24030001, -- li $v1, 1
--eeInsnReplace(0x105730, 0x0c049c70, 0) -- jal 1271c0 <SignalSema>
0x1472000b, -- bne $s2, $v1, +11
-- *** viBufFlush (1)
0x00000000, -- nop
--eeInsnReplace(0x105a88, 0x0c049c78, 0) -- jal 1271e0 <WaitSema>
0x0c09b400, -- jal UFO::Progress::Get(void)
--eeInsnReplace(0x105ab8, 0x0c049c70, 0) -- jal 1271c0 <SignalSema>
0x00000000, -- nop
-- *** viBufPutTs (1)
0x3c01bcf1, -- lui $at, 0x8b36
eeInsnReplace(0x105c10, 0x0c049c78, 0) -- jal 1271e0 <WaitSema>
0x34214d81, -- ori $at, $at, 0xafe9
eeInsnReplace(0x105cf4, 0x0c049c70, 0) -- jal 1271c0 <SignalSema>
0xafa10000, -- sw $at, 0($sp)
 
0x24030001, -- li $v1, 1
-- it's redundant calling of _waitIpuIdle in libmpeg... not so huge impact tho.
0xa3a30004, -- sb $v1, 4($sp)
eeInsnReplace(0x118620, 0x0c04672a, 0) -- jal 119ca8 <_waitIpuIdle>
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
-- bug# 9972
local emuObj = getEmuObject()
emuObj.SetGsTitleFix( "ignoreSubBuffCov", "reserved", { } )
#Crash/stall fixes.</pre>


local overlay2 = InsnOverlay({
====Grand Theft Auto III====
0x27bdfff0, -- addiu $sp, -0x10
SLUS_200.62
0xffbf0000, -- sd $ra, 0(sp)
<br>CLI
0xffb00008, -- sd $s0, 8(sp)
<pre>--vu1-no-clamping=0
0x3c05000f, -- lui $a1, 0x000f
--gs-check-trans-rejection=1
0x34a57000, -- ori $a1, 0x7000
--gs-kernel-cl-up="up2x2tc"
0x0c0db8b6, -- jal Script::State::DoString
--gs-optimize-30fps=1
0x0080802d, -- move $s0, $a0
--ee-hook=0x27cea8,FastForwardClock
0x24050001, -- li $a1, 1
#Performance and graphical fix.</pre>
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
SLUS_200.62
local luaString = [[
<br>LUA
-- disable progressive scan and adjust screen
<pre>
gui.i.SMOptionsDisplay.table.slots[3] = nil
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
gui.i.SMOptionsDisplay.table.slots[4] = nil
 
]]
-- Performace fix
eeObj.WriteMemStrZ(0xf7000, luaString)
local emuObj = getEmuObject()
end)
local thresholdArea = 600
#Official widescreen support.</pre>
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80008068 , zmsk=1 } )


====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)
-- 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>


local eeObj = getEEObject()
SLUS_200.62
local emuObj = getEmuObject()
<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


local patcher = function()


--X-Fov - ELF hack
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
--803f013c 00a88144 0045013c
eeObj.WriteMem32(0x00100fcc,0x3c013f40) --3c013f80


--Memory hack
apiRequest(0.7) -- need widescreen support
--eeObj.WriteMem32(0x201FF100,0x43c00000)


end
local eeObj = getEEObject()
local emuObj = getEmuObject()


emuObj.AddVsyncHook(patcher)


if 1 then
local USEWIDESCREEN_ADDRESS = 0x416748
-- 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.
local H1 = -- start of main()
L2H_SetNonDeferred({TRXREG=0x0000000900000080}) -- match any TRXPOS or BITBLTBUF
function()
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen
end


-- Full specification of conveyor belt effect.
local H2 = -- change widescreen flag
-- L2H_SetNonDeferred({BITBLTBUF=0x0000000013023240,TRXPOS=0x0000000000770000,TRXREG=0x0000000900000080})
function()
end
local isWidescreen = eeObj.GetGpr(gpr.v0)
if isWidescreen == 0 then
emuObj.SetDisplayAspectNormal()
else
emuObj.SetDisplayAspectWide()
end
end


local hook1 = eeObj.AddHook(0x27ed04, 0x7fbf0000, H1) -- <main>:
local hook2 = eeObj.AddHook(0x270e50, 0xa382b8d8, H2) -- <CMenuManager::AnaliseMenuContents(void)>:
#Official widescreen support.</pre>


local PadStickRemap_EternalRing_Default = {
====Grand Theft Auto: San Andreas====
LR=PadStick.AxisRX_Pos,
SLUS_209.46
LL=PadStick.AxisRX_Neg,
<br>CLI
LU=PadStick.AxisLY_Neg,
<pre>--gs-optimize-30fps=1
LD=PadStick.AxisLY_Pos,
--ee-hook=0x34dee8,FastForwardClock
 
--ee-hook=0x00245ee0,FastForwardClock
L1=PadStick.AxisLX_Neg,
--cop2-no-clamping=1
R1=PadStick.AxisLX_Pos,
--gs-flush-ad-xyz=safe
L2=PadStick.AxisRY_Neg,
--vu1-clamp-range=0x04a,0x069
R2=PadStick.AxisRY_Pos,
--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.


local PadStickRemap_EternalRing_InvertY = {
-- bug#8979
L2=PadStick.AxisRY_Pos,
-- The game bugged.
R2=PadStick.AxisRY_Neg,
-- 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


emuObj.PadPressureStickRemap(0, PadStickRemap_EternalRing_Default)
-- 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>


-- Supporting Inverted Y Axis requires smoe menu changes, and should be done via features.lua
-- Performace fix
--emuObj.PadPressureStickRemap(0, PadStickRemap_EternalRing_InvertY) </pre>
local emuObj = getEmuObject()
====Everybody's Tennis/Hot Shots Tennis====
local thresholdArea = 700
SCES_545.35
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80000044 , zmsk=1 } )
<br>CLI
#Performance and rendering fixes.</pre>
<pre>--gs-use-deferred-l2h=0
 
--l2h-2d-params=0x0000000800000010,0x00000000300a1400,256
SLUS_209.46
--gs-motion-factor=50
<br>SLUS-20946_features.lua
--mtap1=always
<pre>-- Lua 5.3
--gs-opt-frbuff-switch=1
-- Title: Grand Theft Auto: San Andreas - SLUS-20946 (USA) v3.00
--gs-ignore-dirty-page-border=1
-- Author: Nicola Salmoria
--gs-ignore-rect-correction=1
-- Date:  November 5, 2015
--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 eeObj = getEEObject()
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])


-- function dump(addr)
apiRequest(0.7) -- need widescreen support
--    print(string.format("=== dump %x ===", addr))
 
--   for i=0,0x1e do
local eeObj = getEEObject()
--   print(string.format("  %08x : %08x %08x %08x %08x",
local emuObj = getEmuObject()
--   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)


local USEWIDESCREEN_ADDRESS = 0x7004ef


eeInsnReplace(0x103d58, 0x27bdffc0, 0x03e00008)                -- <SyncDCache>
local H1 = -- init widescreen flag
eeInsnReplace(0x103d5c, 0xffb20020, 0x00000000)
function()
eeNativeHook (0x103d58, 0x03e00008,'AdvanceClock',0x600)
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen
eeInsnReplace(0x103dd8, 0x3c02ffff, 0x03e00008)                -- <iSyncDCache>
end
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====
local H2 = -- main game loop
SLES_535.39
function()
<br>CLI
local isWidescreen = eeObj.ReadMem8(USEWIDESCREEN_ADDRESS)
<pre>--ee-hook=0x002097d0,FastForwardClock,0x8c6261fc
--ee-hook=0x1a5570,AdvanceClock,,500000
if isWidescreen == 0 then
--ee-hook=0x00223c48,AdvanceClock,0x0080382d,8000
emuObj.SetDisplayAspectNormal()
--gs-kernel-cl="h2lpool"
else
--gs-kernel-cl-up="h2lpool2x2"
emuObj.SetDisplayAspectWide()
</pre>
end
<br>LUA(config.lua)
end
<pre>


-- indigo_prophecy


apiRequest(1.2) -- request version 0.1 API. Calling apiRequest() is mandatory.
local hook1 = eeObj.AddHook(0x233584, 0xa200004f, H1) -- <CMenuManager::__ct(void)>:
local hook2 = eeObj.AddHook(0x246750, 0x24040012, H2) -- <TheGame(void)>:
#Official widescreen support.</pre>


-- Performace fix (bug #9785 )
====Grand Theft Auto: Vice City====
local emuObj = getEmuObject()
SLUS_205.52
emuObj.SetGsTitleFix( "globalSet",  "reserved", { waveThreshold = 90000} )
<br>CLI
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { } )
<pre>--gs-check-trans-rejection=1
-- Accumulate fill area only when conditions are met
--gs-kernel-cl-up="up2x2tc"
emuObj.SetGsTitleFix( "includeAreaUpdate", "reserved" , {alphaIsNot = 0, zmsk = 1, tw = 6, th = 6 , tbp = 0x00302000} )
--gs-optimize-30fps=1
emuObj.SetGsTitleFix( "ignoreUpRender", 130 , { totalArea= 700} )
--ee-hook=0x277b88,FastForwardClock
--ee-hook=0x279a18,FastForwardClock
</pre>


 
SLUS_205.52
-- bug#8571
<br>LUA
-- ignore 'no wait vsync' case.
-- unsyncv causes major slowness on loading screen, because the game pushes LOTS of identical frame data to GS.
eeInsnReplace(0x2097b8, 0x1040000c, 0) -- beqz v0,2097ec <QDT::KCORE::RENDER_CONTEXT::DoSwapStuff(void)+0x1a4>
 
-- bug#9727
require("utils")
local eeObj = getEEObject()
local PrecompileAddrs = Queue.new(
  {
0x3b92ec,
0x1f23d0,
0x2bad48,
0x2b9718,
0x14d6c4,
0x14d7fc,
0x1b5a44,
0x14fbf4,
0x1b7aac,
0x195e38,
0x14f4f4,
0x2f54d0,
0x3a7a50,
0x1528a4,
0x1f50a0,
0x152c54,
0x1f6b20,
0x14ffe0,
0x114db0,
0x3cb4e4,
0x21ae90,
0x21b2f8,
0x2218a8,
0x20fa80,
0x20fcf4,
0x20c438,
0x20cb98,
0x20cd40,
0x20cdb0,
0x20b498,
0x20d054,
0x20d0d4,
0x1d910c,
0x1da700,
0x1da81c,
0x331048,
0x1b6ca8,
0x1b7230,
0x3ddf04,
0x1e5b30,
0x2e4668,
0x3ba020,
0x3b1d7c,
0x3b2074,
0x18c13c,
0x3bc678,
0x3bbf60,
0x3bbf7c,
0x3bbfc4,
0x24cfb0,
0x24cfc4,
0x24cfd8,
0x24cfe0,
0x24d014,
0x275dd0,
0x1d7398,
0x1ccf24,
0x1ca534,
0x1ca468,
0x1cb1f0,
0x1cb2d4,
0x1ca478,
0x1ca53c,
0x1ca548,
0x1ca498,
0x1ca4ac,
0x1ca550,
0x1ca55c,
0x1ca564,
0x1ca570,
0x1d73bc,
0x1d73c4,
0x1d73dc,
0x1d73e8,
0x1d73f4,
0x1d7580,
0x237810,
0x1d7588,
0x1d7404,
0x1d73e0,
0x1d7598,
0x1d7418,
0x275de0,
0x24d05c,
0x3bbfcc,
0x24d080,
0x24d090,
0x275f20,
0x1d7d88,
0x1d7ddc,
0x275f3c,
0x24d0a4,
0x3bbfd4,
0x3bc688,
0x2fcfe0,
0x2f9c10,
0x2f9c2c,
0x2f9c40,
0x2f9c48,
0x275a80,
0x275a94,
0x274570,
0x1fea88,
0x1fea98,
0x1feaa8,
0x1feab0,
0x274580,
0x275a9c,
0x275ab0,
0x2f9c54,
0x2f9c60,
0x2fcfe8,
0x2fcff0,
0x2fdb58,
0x2fdba0,
0x2fdbb0,
0x2fdbc4,
0x2fdbcc,
0x2fdbdc,
0x2fdbf4,
0x2fdc00,
0x2fd768,
0x2fcd08,
0x2fd784,
0x2fd790,
0x2fccf0,
0x2fd798,
0x2fd7a0,
0x2fd7ac,
0x2fd7b4,
0x2fd7bc,
0x2fd7c4,
0x2fd7cc,
0x2fd7d4,
0x2fd7ec,
0x2fd7f4,
0x2fd808,
0x2fdc08,
0x2fdc1c,
0x2fdcb4,
0x2fdcbc,
0x2fdd58,
0x2fdd68,
0x2fdd70,
0x2fdd88,
0x2fde1c,
0x2fde4c,
0x2fd6a0,
0x2fd6c0,
0x2fd6cc,
0x2fd6e0,
0x2fd6ec,
0x2fd6f4,
0x2fd6fc,
0x2fd714,
0x2fd744,
0x2fd74c,
0x2fde54,
0x2fcff8,
0x2fd0c0,
0x1fee40,
0x1fee48,
0x1fee6c,
0x1fee74,
0x1fee94,
0x1fef1c,
0x1fef44,
0x3bbae0,
0x3bbc60,
0x3bbc7c,
0x3bbc84,
0x3b7c10,
0x3b7c28,
0x3b7c30,
0x3b7c7c,
0x3b7c88,
0x3b7c90,
0x3b7c98,
0x3b7ca4,
0x3bbc8c,
0x3b8c70,
0x3b8c84,
0x3b8c8c,
0x3b8c94,
0x3b8c9c,
0x3b8ca4,
0x3bbc94,
0x3b19b0,
0x3b19d4,
0x3bbc9c,
0x3b1af8,
0x3bbca4,
0x3b1a50,
0x3bbcac,
0x3bbb08,
0x3bc7e0,
0x3b1950,
0x3bc80c,
0x24c8e8,
0x24c914,
0x2378d0,
0x23794c,
0x237958,
0x237960,
0x24c938,
0x3bc818,
0x3bbb14,
0x3103c4,
0x3103cc,
0x310f98,
0x3103d8,
0x3103ec,
0x2f3764,
0x2f3768,
0x2f37a0,
0x2f37a8,
0x2f3874,
0x2f3920,
0x2f3870,
0x2f391c,
0x2f8de8,
0x2f8df0,
0x3ca7bc,
0x3ca7c8,
0x3adb70,
0x3adb84,
0x3adb8c,
0x3adb94,
0x3afef0,
0x3afd60,
0x3aff18,
0x3aff5c,
0x3adbac,
0x3afec0,
0x3adbb8,
0x3af370,
0x3aeea0,
0x3af3b4,
0x3af3c0,
0x3aeeb8,
0x3af3d0,
0x267a38,
0x267870,
0x267888,
0x267250,
0x267288,
0x21a4e0,
0x21a4ec,
0x267298,
0x2672a0,
0x21a500,
0x21a50c,
0x2672a8,
0x2672bc,
0x267890,
0x267a48,
0x3af3e0,
0x3af3e8,
0x2679d8,
0x2678a0,
0x2678cc,
0x2678d4,
0x267038,
0x267068,
0x2674d8,
0x267074,
0x267080,
0x267538,
0x267090,
0x267550,
0x2670a4,
0x307118,
0x301208,
0x301274,
0x303e48,
0x303e5c,
0x303e74,
0x30127c,
0x3012a4,
0x3012e8,
0x3012fc,
0x30132c,
0x3013d8,
0x30140c,
0x301488,
0x301648,
0x30165c,
0x301674,
0x303c00,
0x301688,
0x301694,
0x3014a4,
0x3014ec,
0x30133c,
0x307134,
0x2670b8,
0x267088,
0x36ce68,
0x36ce90,
0x36cef8,
0x36cf28,
0x36cf38,
0x300d30,
0x36cf50,
0x36cf5c,
0x36cfac,
0x36cfb4,
0x36cfdc,
0x36ce9c,
0x36cff8,
0x36d01c,
0x36d264,
0x36d270,
0x36d290,
0x370a60,
0x370a7c,
0x36d2d0,
0x36d300,
0x36d308,
0x36d310,
0x352890,
0x36d328,
0x36d3d8,
0x370a94,
0x36d29c,
0x36d2a8,
0x36d2c0,
0x36ceb0,
0x36ced8,
0x2670c4,
0x2678f0,
0x2679e8,
0x3af3fc,
0x3af3c8,
0x285388,
0x2853c8,
0x285394,
0x2853b0,
0x27e4bc,
0x27e4c4,
0x27e4cc,
0x27e4d8,
0x27e4f4,
0x27e508,
0x27e510,
0x27e518,
0x2881c0,
0x2881d0,
0x27e524,
0x27e534,
0x27e544,
0x27e54c,
0x27e558,
0x27e574,
0x27e57c,
0x27e588,
0x27e594,
0x27e5a8,
0x27e5b0,
0x27e5c4,
0x3dd3b0,
0x3dd3e0,
0x27e5cc,
0x27e5d4,
0x27e5ec,
0x27e5f8,
0x27e604,
0x27e614,
0x27e62c,
0x27e634,
0x27e640,
0x289c80,
0x289ca4,
0x289cf0,
0x289cf8,
0x289d08,
0x289d18,
0x289d24,
0x289d30,
0x27e654,
0x27e65c,
0x27e674,
0x27e680,
0x27e68c,
0x27e698,
0x27e6a4,
0x3dd208,
0x27e6ac,
0x27d920,
0x27e6b4,
0x28d820,
0x28d840,
0x28d868,
0x28dcf8,
0x28dd34,
0x293580,
0x2935ac,
0x2935d4,
0x2935fc,
0x290720,
0x290748,
0x29076c,
0x290788,
0x290638,
0x290670,
0x290694,
0x2906b0,
0x2906d4,
0x29070c,
0x2911a0,
0x2911d0,
0x2911f8,
0x291188,
0x291208,
0x28d8c8,
0x28d8f8,
0x28d908,
0x28b994,
0x27e6c0,
0x27e6c8,
0x27e0f8,
0x27e6d0,
0x27e6ec,
0x27e6f4,
0x27e72c,
0x27e734,
0x355898,
0x267270,
0x2672b8,
0x36b4f0,
0x36b518,
0x36b3c8,
0x36b3e4,
0x36b3f0,
0x36b3fc,
0x36b414,
0x36b420,
0x36b428,
0x36b43c,
0x36b520,
0x36b528,
0x36b540,
0x36d3d4,
0x36b554,
0x368d78,
0x368d8c,
0x368d94,
0x368d9c,
0x36b574,
0x2ff6c8,
0x2ff6e4,
0x3aff78,
0x2ff6ec,
0x2ff724,
0x2ff780,
0x2ff7c8,
0x3af40c,
0x3adbcc,
0x285fa4,
0x285fac,
0x334a1c,
0x2ff800,
0x334a38,
0x334a40,
0x334a48,
0x334a50,
0x2ff860,
0x334a5c,
0x334a70,
0x334a7c,
0x334ab0,
0x2ff878,
0x334ab8,
0x334ad4,
0x334b20,
0x3e5eb8,
0x3e6078,
0x3e6098,
0x3e60b0,
0x3e60cc,
0x334b28,
0x334b64,
0x3e6080,
0x334b6c,
0x334b78,
0x334a30,
0x334aac,
0x334b04,
0x38de50,
0x38de60,
0x38de7c,
0x334c2c,
0x334c38,
0x334ccc,
0x334c30,
0x334cd8,
0x334868,
0x38d850,
0x38d884,
0x38d924,
0x38da00,
0x38dad4,
0x38dbb0,
0x38dc80,
0x334898,
0x334900,
0x334870,
0x2ff1fc,
0x2ff200,
0x3adb98,
0x301464,
0x3015f8,
0x30160c,
0x301618,
0x303c08,
0x30162c,
0x301638,
0x301480,
0x3014a8,
0x36d27c,
0x36d288,
0x370aa8,
0x370ac4,
0x36d3f0,
0x36d428,
0x36d430,
0x36d438,
0x36d450,
0x36d514,
0x370adc,
0x36d510,
0x2ff5b0,
0x2ff5f0,
0x3aff80,
0x2ff5f8,
0x2ff668,
0x2ff6b0,
0x3349a0,
0x334b48,
0x334b74,
0x334a84,
0x334a90,
0x334a98,
0x334aa4,
0x334abc,
0x38dd48,
0x3a68e0,
0x3a7c30,
0x3a7c6c,
0x3a7c84,
0x3a7c9c,
0x3a7cd8,
0x3a7d08,
0x3a7e18,
0x3a7e20,
0x3a7e40,
0x3a7e50,
0x3a7e68,
0x3a6370,
0x3a7e70,
0x3a7e80,
0x3a7e88,
0x3a7eb0,
0x3a7f0c,
0x3a6904,
0x3a6918,
0x3a6920,
0x3a6928,
0x3a6930,
0x3a6938,
0x3a69ec,
0x38dd50,
0x38dd60,
0x38ddd0,
0x38dde0,
0x38ddfc,
0x38d894,
0x38d89c,
0x38d8bc,
0x38d8dc,
0x38d8fc,
0x38dc84,
0x3348a4,
0x3348ac,
0x3348b8,
0x3348d0,
0x3348d8,
0x3348e4,
0x334910,
0x3331fc,
0x3335d8,
0x33360c,
0x33364c,
0x333610,
0x333618,
0x333620,
0x32eef0,
0x32ef28,
0x32ef3c,
0x32ef50,
0x32ef58,
0x32ef64,
0x32ef78,
0x32ef88,
0x32efa0,
0x32efb0,
0x31e4f0,
0x31e57c,
0x31e598,
0x31e5c8,
0x31e5fc,
0x31e604,
0x31e614,
0x31e5a0,
0x31e5b4,
0x32efc8,
0x32efa8,
0x32efd4,
0x32efe0,
0x32efe8,
0x31f418,
0x31f434,
0x31f440,
0x32effc,
0x333628,
0x333634,
0x333644,
0x33365c,
0x333668,
0x33367c,
0x333694,
0x3336a4,
0x32fa28,
0x32fa44,
0x3e5818,
0x3e5834,
0x3e5720,
0x3e5734,
0x3e57c0,
0x3e57c8,
0x3e55d0,
0x3e5634,
0x3e57e4,
0x3e5808,
0x3e583c,
0x32fa50,
0x3cdbe0,
0x3cdc0c,
0x3cdc38,
0x3cdc40,
0x3cdc74,
0x3cdcb0,
0x3cdcc4,
0x3cdb80,
0x3cdba4,
0x3cdbb4,
0x3cdbc0,
0x3cdcd8,
0x3cdd0c,
0x3cdd60,
0x3cde40,
0x32fa5c,
0x32fa80,
0x32fa9c,
0x3cdd70,
0x3cdd84,
0x3cddb4,
0x3cde44,
0x32faa8,
0x32fab4,
0x32fac0,
0x3336b0,
0x3336c0,
0x32cf80,
0x3336c8,
0x3336dc,
0x32cf88,
0x3336e4,
0x32cf28,
0x32cf40,
0x32cf6c,
0x3336f4,
0x333704,
0x333204,
0x333214,
0x333588,
0x33359c,
0x3335b8,
0x3335c0,
0x33321c,
0x333230,
0x333240,
0x32d5a8,
0x32d614,
0x32d634,
0x32f090,
0x32f0dc,
0x32f0e8,
0x32f0f0,
0x32f0fc,
0x32f118,
0x32f144,
0x32f15c,
0x32f16c,
0x32f184,
0x32f1c4,
0x32f204,
0x32f2f4,
0x32d664,
0x32d67c,
0x32d684,
0x32d690,
0x32d698,
0x32d648,
0x32f174,
0x32f130,
0x32f22c,
0x32f238,
0x38ccf8,
0x38cd08,
0x38cd48,
0x38ce50,
0x32f250,
0x32f258,
0x32f278,
0x32f2f0,
0x32d5f4,
0x32da40,
0x337430,
0x32da5c,
0x338520,
0x32da64,
0x32da70,
0x32da78,
0x338088,
0x3380c0,
0x3380d4,
0x3380e0,
0x3380ec,
0x2978e0,
0x297910,
0x297938,
0x297954,
0x297964,
0x333da8,
0x333dc4,
0x1e57b0,
0x1e57b8,
0x1e57c4,
0x1e57d0,
0x1e57e0,
0x1e57e8,
0x1e57f8,
0x1e5804,
0x1e5820,
0x2932a8,
0x2932fc,
0x287bb4,
0x338100,
0x33810c,
0x32da88,
0x32d5fc,
0x32d6a8,
0x32d6b4,
0x32d6bc,
0x32d6c4,
0x32d730,
0x33325c,
0x33326c,
0x337660,
0x337718,
0x32397c,
0x323ca8,
0x323d5c,
0x323f08,
0x323f24,
0x323f58,
0x323f64,
0x323f74,
0x174438,
0x174450,
0x174460,
0x323f80,
0x323d78,
0x323d28,
0x323d54,
0x323d64,
0x323d8c,
0x323da0,
0x31e4dc,
0x337698,
0x3376a8,
0x3376b0,
0x32c668,
0x32c680,
0x32c790,
0x32c7d8,
0x32c814,
0x32d330,
0x32d348,
0x32c824,
0x32c82c,
0x32c838,
0x32c860,
0x32c870,
0x32c904,
0x32d768,
0x32d794,
0x32d7ac,
0x32d7b4,
0x32d7c0,
0x32d7c8,
0x2934e0,
0x29350c,
0x293534,
0x29355c,
0x290058,
0x290088,
0x2900b0,
0x290048,
0x2900c0,
0x28f470,
0x28f4a8,
0x28f4c8,
0x28f4e4,
0x28f508,
0x28f52c,
0x28f538,
0x28f544,
0x28f550,
0x28f564,
0x28f574,
0x28f580,
0x28f590,
0x28f5bc,
0x28f5d4,
0x28f624,
0x28f630,
0x28f664,
0x28f698,
0x28f6ec,
0x2dc768,
0x2dc77c,
0x2c8c80,
0x2d6118,
0x2d612c,
0x2d6138,
0x2d6140,
0x2d6148,
0x2d615c,
0x2d6164,
0x2d616c,
0x15b6a8,
0x15b6bc,
0x188320,
0x18833c,
0x188344,
0x18834c,
0x18bf48,
0x18bf64,
0x18bf70,
0x18bf90,
0x18bed8,
0x18b648,
0x18bf00,
0x18bf0c,
0x18bf38,
0x18bfa0,
0x18bfac,
0x188354,
0x187e60,
0x187e68,
0x18be50,
0x18be6c,
0x18be78,
0x18e950,
0x18e970,
0x18e97c,
0x1baf88,
0x1baf9c,
0x1bafa8,
0x18e990,
0x18e99c,
0x18e9ac,
0x18e9b8,
0x18e9c4,
0x18e9d4,
0x1a1b90,
0x1a1bd8,
0x1a1bf0,
0x18e9e0,
0x18e9ec,
0x18be8c,
0x1ba220,
0x1ba25c,
0x1ba268,
0x1ba2a8,
0x1ba2c0,
0x1ba2cc,
0x1ba2d8,
0x1ba2e4,
0x18be94,
0x18bea8,
0x187e74,
0x187e80,
0x188d84,
0x188db4,
0x187e88,
0x18835c,
0x18836c,
0x15b6c4,
0x2d6174,
0x2c8c90,
0x2dc790,
0x312438,
0x31244c,
0x312454,
0x286d84,
0x2dd440,
0x2dd45c,
0x2dcfe8,
0x2dd004,
0x2dd01c,
0x2dcc18,
0x2dcc34,
0x32d7d8,
0x32d7ec,
0x330ae0,
0x330b20,
0x330b28,
0x330b44,
0x330b5c,
0x32fee0,
0x32ff00,
0x330b68,
0x32ffa8,
0x32ff68,
0x32feb0,
0x32fed0,
0x32ff78,
0x32ffb8,
0x32ffc8,
0x330b78,
0x32ffd8,
0x32ffe8,
0x330b88,
0x330b94,
0x330b9c,
0x330bd4,
0x2c7440,
0x2bfff8,
0x2c001c,
0x2c02c8,
0x2c02d0,
0x2c745c,
0x330be8,
0x330c80,
0x332298,
0x3322b0,
0x330c8c,
0x2d5eb8,
0x2a2df8,
0x2a2648,
0x2a2678,
0x2a8c78,
0x2a8ca8,
0x2a8cb4,
0x2a8cc0,
0x2a8ccc,
0x2a2684,
0x2a2e08,
0x2d5ee4,
0x2d5ef4,
0x2d5f00,
0x2a2730,
0x1a08e0,
0x1a0908,
0x1a1898,
0x1a18dc,
0x1a18f0,
0x1a18f8,
0x1a192c,
0x1a196c,
0x1a19b0,
0x1a19e4,
0x1a19f0,
0x1a0918,
0x1a0924,
0x1a0930,
0x1a093c,
0x1a0948,
0x2a275c,
0x2a276c,
0x18e598,
0x18e5b8,
0x18e5d8,
0x18e610,
0x18e634,
0x18e650,
0x18e658,
0x18e664,
0x18e670,
0x1baaf0,
0x1bab20,
0x1bab38,
0x1bb0c8,
0x19ead0,
0x19eaf4,
0x1bb0f4,
0x1bab58,
0x1bab40,
0x1bab64,
0x1bab70,
0x1bab80,
0x19ea80,
0x19ea9c,
0x19eaa4,
0x1bab8c,
0x18e688,
0x18e690,
0x1baaa0,
0x19ea68,
0x1baab4,
0x1baad8,
0x18e698,
0x1babe0,
0x1babfc,
0x1bac08,
0x1bac10,
0x195be0,
0x1bac1c,
0x195be8,
0x1bac28,
0x1bac48,
0x1bac78,
0x1bacd0,
0x1bacd8,
0x1bacf4,
0x1bad04,
0x1bb070,
0x19eab8,
0x1bb084,
0x19ea08,
0x1bb0a8,
0x1bad14,
0x1bad08,
0x1bad20,
0x1bad30,
0x1bad44,
0x1bb308,
0x1bad54,
0x1bad6c,
0x1bad7c,
0x1bad38,
0x1bad8c,
0x1bac34,
0x18e6b4,
0x18e7c0,
0x18dcb8,
0x18e7e4,
0x18e7f4,
0x18b538,
0x18b558,
0x18b560,
0x18dcd8,
0x18b56c,
0x18b574,
0x191920,
0x18b590,
0x18b5d4,
0x18e808,
0x18e818,
0x18e824,
0x18e830,
0x1babb0,
0x18e848,
0x18e860,
0x191c20,
0x191cac,
0x18e86c,
0x1baba8,
0x18e888,
0x18e8bc,
0x18c930,
0x18c954,
0x18c960,
0x18c974,
0x18c990,
0x18c9ac,
0x18e8c8,
0x1baed8,
0x18e8e4,
0x18e8f4,
0x18dd18,
0x18dd3c,
0x18e900,
0x18e6bc,
0x18e6cc,
0x18e5e4,
0x18e5fc,
0x2a277c,
0x18bcd0,
0x18bcd8,
0x2a2798,
0x18bcf8,
0x18bd00,
0x2a27b4,
0x18bd48,
0x18bd50,
0x2a27d0,
0x18bd20,
0x18bd34,
0x2a27ec,
0x18c6a0,
0x18c6b0,
0x2a27f8,
0x18bca0,
0x2a2814,
0x18bc78,
0x2a2830,
0x18bc70,
0x2a284c,
0x18bc00,
0x2a2868,
0x18bdb0,
0x2a2890,
0x18c668,
0x18c670,
0x2a28b8,
0x2a28dc,
0x2a2900,
0x2a2908,
0x2a2914,
0x2a2920,
0x2d5f1c,
0x2d5f2c,
0x18c920,
0x2d5f40,
0x2d5f48,
0x2d5f58,
0x2d5e8c,
0x2d5e9c,
0x2d5eac,
0x2d5f60,
0x3d3980,
0x2d5f78,
0x1556f8,
0x155724,
0x1a0978,
0x1a09a0,
0x19ef80,
0x19efc4,
0x19efd8,
0x19efe4,
0x1881a8,
0x188204,
0x19eff0,
0x19f008,
0x19f01c,
0x19f110,
0x19f144,
0x19f150,
0x19f15c,
0x19f180,
0x19f1b0,
0x19f1b8,
0x18dc60,
0x18dc7c,
0x18dc88,
0x3d3938,
0x18dc94,
0x19f1c4,
0x18b5f8,
0x18b60c,
0x19f1dc,
0x18ba38,
0x18ba5c,
0x18ba80,
0x18bb50,
0x18ba64,
0x18c858,
0x18c874,
0x18ec58,
0x1bb108,
0x1bb12c,
0x3d3b30,
0x1bb134,
0x18ec84,
0x1bb170,
0x1bb1a0,
0x18eca0,
0x18c888,
0x18ba6c,
0x19f1f4,
0x19f200,
0x188690,
0x19f20c,
0x19f02c,
0x19fdb0,
0x19fde4,
0x19fe18,
0x19fe5c,
0x19fe8c,
0x19fed4,
0x19fee4,
0x19fef0,
0x19feb8,
0x19fec4,
0x19ff00,
0x19ff30,
0x19ff60,
0x19ff8c,
0x1a0010,
0x19f03c,
0x15dff8,
0x19f050,
0x19f0e0,
0x1a09c0,
0x1a09cc,
0x155738,
0x155744,
0x2d5f84,
0x2a8db0,
0x2a8dd4,
0x2a8dec,
0x2a8e20,
0x2d5f8c,
0x2d5f9c,
0x2d5fa4,
0x330cac,
0x2d6640,
0x2d6b18,
0x2d6b30,
0x155758,
0x15577c,
0x1557a8,
0x188480,
0x1557b0,
0x1557bc,
0x1557c8,
0x1557d4,
0x2d6b3c,
0x2d6668,
0x2d667c,
0x2d6684,
0x2d6690,
0x2d66a0,
0x2d66b0,
0x1919c0,
0x1917a8,
0x1919d4,
0x2d66bc,
0x2d66e8,
0x2d66fc,
0x2d6704,
0x191bf0,
0x191c04,
0x191af8,
0x191828,
0x19183c,
0x191858,
0x191844,
0x191ba4,
0x191c0c,
0x2d6714,
0x2d6728,
0x191a68,
0x1917f8,
0x19181c,
0x191a88,
0x191aa0,
0x2d6734,
0x330cc4,
0x330ccc,
0x15d420,
0x155d30,
0x155d54,
0x191d54,
0x191d70,
0x191d98,
0x19217c,
0x191db8,
0x18c730,
0x18c73c,
0x18c0d8,
0x18c11c,
0x18c4bc,
0x18c760,
0x1f2c38,
0x1f2c80,
0x3d4658,
0x1f2ca8,
0x1f2cbc,
0x1f2cd4,
0x1f2cdc,
0x1f2cf0,
0x1f2a80,
0x1f2aa8,
0x1f2af8,
0x1f2cfc,
0x1f2d04,
0x1f2d14,
0x1f2d30,
0x1f2d3c,
0x3d85f8,
0x1f2d48,
0x3d28b8,
0x1f2d54,
0x1f2d68,
0x1f2d7c,
0x1f2d90,
0x18c774,
0x18c780,
0x18c7a0,
0x18c804,
0x18c838,
0x18d378,
0x18d3a0,
0x18d404,
0x18ca68,
0x18ca98,
0x18caa8,
0x18cac4,
0x18caf0,
0x18cafc,
0x187ffc,
0x188008,
0x188074,
0x188114,
0x188124,
0x18812c,
0x18815c,
0x157f90,
0x157fa4,
0x157fb4,
0x158074,
0x150d98,
0x15117c,
0x151190,
0x1511a4,
0x1511b0,
0x1511bc,
0x1511c8,
0x1511d4,
0x1511e4,
0x1511f0,
0x151208,
0x132eb0,
0x15b7e0,
0x15b7f8,
0x15b82c,
0x15b874,
0x15b8a4,
0x15b8ec,
0x15b8fc,
0x15b908,
0x15b8d0,
0x15b918,
0x132ed8,
0x132ee0,
0x132f10,
0x132f3c,
0x132f4c,
0x151210,
0x151220,
0x15122c,
0x151240,
0x108018,
0x108034,
0x108068,
0x108094,
0x10812c,
0x108174,
0x108180,
0x10818c,
0x108158,
0x1080b4,
0x1080f0,
0x108198,
0x151250,
0x15125c,
0x1283b4,
0x151268,
0x151274,
0x1505a4,
0x150964,
0x150970,
0x15097c,
0x150988,
0x150994,
0x1509a8,
0x1509b4,
0x1509c0,
0x1509cc,
0x1509e4,
0x132350,
0x15b904,
0x15b914,
0x13237c,
0x132384,
0x1323b4,
0x1323e4,
0x1323f0,
0x13241c,
0x1509ec,
0x1509f8,
0x150a04,
0x150a18,
0x107e68,
0x107e8c,
0x107ec0,
0x107eec,
0x107f1c,
0x107f64,
0x107f78,
0x107f88,
0x107fb0,
0x107fc8,
0x150a28,
0x150a34,
0x150a40,
0x150a4c,
0x150cb8,
0x155d5c,
0x155db4,
0x15d434,
0x15d454,
0x15d45c,
0x330ce4,
0x330d20,
0x330d2c,
0x330d38,
0x32d7f4,
0x32d800,
0x32e2b0,
0x32d814,
0x32d820,
0x32d830,
0x32d840,
0x330028,
0x330828,
0x330884,
0x3e5868,
0x3e5894,
0x3e58c8,
0x3e59bc,
0x3e59c4,
0x3e59f4,
0x3e5a24,
0x3e5a4c,
0x3e5a58,
0x3e5a60,
0x3e5a90,
0x3e5ae8,
0x3e5af0,
0x3e5b1c,
0x3e5b4c,
0x3e5b58,
0x3e5b8c,
0x3308a4,
0x3308c0,
0x3308d0,
0x3308e0,
0x3308f0,
0x330928,
0x330950,
0x33095c,
0x3e5bf8,
0x3e5c1c,
0x3e5c28,
0x3e5c5c,
0x3e5cc0,
0x3e5cc8,
0x3e5cf4,
0x3e5d20,
0x3e5c98,
0x3e5d24,
0x3e5d30,
0x33096c,
0x3309c4,
0x3309d4,
0x3309fc,
0x330a0c,
0x32fb10,
0x32fb24,
0x32fb3c,
0x330a18,
0x330ab0,
0x33003c,
0x330088,
0x3300c8,
0x32fff8,
0x330008,
0x330018,
0x3300e0,
0x3300ec,
0x3300f8,
0x33010c,
0x330118,
0x330128,
0x330138,
0x330144,
0x330154,
0x330168,
0x2a2940,
0x2a295c,
0x2a296c,
0x2a2974,
0x33017c,
0x330198,
0x3301b4,
0x3301d0,
0x3301ec,
0x330204,
0x330214,
0x330044,
0x330240,
0x330288,
0x330290,
0x3302b4,
0x3302e4,
0x330300,
0x330308,
0x330314,
0x32fb2c,
0x33031c,
0x33032c,
0x330340,
0x330348,
0x330358,
0x330364,
0x330398,
0x3303a8,
0x2f5d00,
0x2f5d30,
0x2f5d48,
0x2f5d5c,
0x2f6820,
0x2f5d64,
0x2f5da8,
0x2f5db0,
0x2f5dcc,
0x2f5ef4,
0x3303b4,
0x2f5138,
0x2f5198,
0x2f51b4,
0x2f51c8,
0x2f51d0,
0x2f5234,
0x2f53b4,
0x2f53bc,
0x2f53cc,
0x2f57fc,
0x2f5810,
0x2f5844,
0x2f59b4,
0x2f5a14,
0x3303c8,
0x2f5a58,
0x2f5a8c,
0x2f5aa8,
0x2f5abc,
0x2f5b20,
0x2f5c6c,
0x2f5c74,
0x2f5c84,
0x2f5c94,
0x2f5c9c,
0x2f5ce8,
0x3303dc,
0x3303e8,
0x330400,
0x33040c,
0x33004c,
0x330430,
0x330588,
0x330054,
0x3305b0,
0x33068c,
0x33005c,
0x3306a8,
0x330800,
0x330064,
0x32d850,
0x32c918,
0x32c688,
0x32c6a4,
0x3376c8,
0x126a68,
0x126a7c,
0x21a118,
0x21a168,
0x21a180,
0x126a88,
0x126ac0,
0x126ae4,
0x126af0,
0x126b00,
0x126b0c,
0x126b18,
0x126b20,
0x126b30,
0x126ad0,
0x126b38,
0x126b3c,
0x126b5c,
0x126b68,
0x126b7c,
0x126b88,
0x126b94,
0x1f4ee0,
0x1f4fe4,
0x1f4f80,
0x3e5a20,
0x3e5a30,
0x3e5b48,
0x3e5ac8,
0x330a20,
0x330a28,
0x330a38,
0x330a60,
0x330a70,
0x330a98,
0x330aa8,
0x2f5dd4,
0x2f5e10,
0x2f5e3c,
0x2f5e60,
0x2f5e90,
0x2f5e08,
0x2f5eb0,
0x2f524c,
0x2f5258,
0x2f5278,
0x3a6f58,
0x3a8878,
0x3a88d8,
0x3a88e8,
0x3a88fc,
0x3a8954,
0x3a89a0,
0x3a89cc,
0x3a89d4,
0x3a90dc,
0x3a6f90,
0x3a6fa0,
0x3a6fa8,
0x3a6fb0,
0x3a6fb8,
0x3a7048,
0x3a7160,
0x3aa430,
0x3a7168,
0x3a736c,
0x3a7434,
0x2f5338,
0x3a7058,
0x3a70c0,
0x3a70c8,
0x3a70d0,
0x2f534c,
0x2f5370,
0x2f5380,
0x2f5394,
0x2f5818,
0x2f585c,
0x2f5888,
0x2f58ac,
0x2f58e0,
0x2f5854,
0x2f5900,
0x2f5958,
0x2f597c,
0x2f5b38,
0x2f5b40,
0x2f5b64,
0x2f5b98,
0x2f5c44,
0x3adba4,
0x2ff708,
0x2ff710,
0x3cd7b4,
0x3cb718,
0x3cb588,
0x3cb5d4,
0x3cb6f8,
0x3cb738,
0x3cb74c,
0x3cb780,
0x3cb79c,
0x3cd7c4,
0x323d94,
0x323e40,
0x323e78,
0x323e88,
0x323e90,
0x323ea4,
0x323eb0,
0x323e70,
0x323ebc,
0x323d9c,
0x337770,
0x1f4f30,
0x3e5900,
0x3e5958,
0x3e598c,
0x1f5000,
0x1f504c,
0x14a838,
0x3309d8,
0x32c818,
0x32c87c,
0x330a74,
0x2f5e00,
0x2f5840,
0x32c864,
0x32c884,
0x32c88c,
0x32c89c,
0x330dd0,
0x330de8,
0x2d6b50,
0x2d6b6c,
0x2d6b7c,
0x2d6b88,
0x2d6b94,
0x2d6ba4,
0x2d6bb0,
0x2d6bbc,
0x2d6bc8,
0x330df8,
0x330e04,
0x330e10,
0x330e1c,
0x330e28,
0x330e3c,
0x330e48,
0x2d65c8,
0x2d65e8,
0x2d65f8,
0x330e50,
0x330e64,
0x330eb8,
0x330ec4,
0x3e54c8,
0x3e54d0,
0x32c8a4,
0x32c8b4,
0x32fcf0,
0x32fd28,
0x32fd54,
0x32fd60,
0x32fd70,
0x32fdb0,
0x32fdd0,
0x32fde0,
0x32fdf0,
0x32fe30,
0x32fe70,
0x32c8bc,
0x32c8d0,
0x32e2b8,
0x32e2cc,
0x32d870,
0x32e2e0,
0x32c8e4,
0x32c8f0,
0x335cd8,
0x335cec,
0x32cc98,
0x334668,
0x33468c,
0x3346e8,
0x32ccb8,
0x32ccc8,
0x32ccd0,
0x32cce8,
0x32ccf0,
0x323df0,
0x31e510,
0x31e518,
0x32ccfc,
0x32cd08,
0x32cd10,
0x335d00,
0x370d68,
0x370d84,
0x36cc80,
0x36ccac,
0x36ccb4,
0x36ccbc,
0x36ccc8,
0x34f450,
0x34f46c,
0x34f47c,
0x36ccd0,
0x36ccdc,
0x2bbca0,
0x36ccf0,
0x36ccf8,
0x36cd04,
0x2bbca8,
0x2bbd0c,
0x155938,
0x1f24b8,
0x1ef428,
0x1ef430,
0x1ef470,
0x1ef57c,
0x1ef5ac,
0x1ef5c8,
0x1ef5e4,
0x1ef608,
0x1ef6a8,
0x1ef6c0,
0x1f24ec,
0x1f2524,
0x1f2554,
0x1f255c,
0x1f257c,
0x1f25b0,
0x1f25c0,
0x1f25dc,
0x1f25e8,
0x1f2674,
0x155948,
0x2bbd2c,
0x2bbd3c,
0x2bbd54,
0x2bbd6c,
0x2bbd84,
0x2bd3f0,
0x2bd404,
0x1559a0,
0x1559b8,
0x1559cc,
0x1559dc,
0x1559f0,
0x2bd410,
0x2bbdac,
0x36cd10,
0x36cd20,
0x370d9c,
0x333d70,
0x333d8c,
0x332bf0,
0x332c10,
0x332eb8,
0x332c18,
0x332c24,
0x332c34,
0x332c3c,
0x332c48,
0x31e5b8,
0x332c50,
0x332c5c,
0x332c6c,
0x332c74,
0x332c80,
0x332c90,
0x32bd00,
0x32bd18,
0x331438,
0x33148c,
0x3314d8,
0x331784,
0x33188c,
0x33189c,
0x3318ac,
0x3318b8,
0x3318c0,
0x32bd20,
0x332c98,
0x332cac,
0x332cc4,
0x332d0c,
0x332d28,
0x332d70,
0x332d9c,
0x332db8,
0x332de0,
0x332e08,
0x332e10,
0x332e2c,
0x332e48,
0x334408,
0x334440,
0x334448,
0x334460,
0x334468,
0x33447c,
0x334504,
0x334514,
0x334524,
0x334534,
0x334548,
0x332e94,
0x333d98,
0x292918,
0x292940,
0x292968,
0x297b98,
0x297bd0,
0x297bec,
0x297c00,
0x297c08,
0x297c18,
0x297c20,
0x297c74,
0x297c7c,
0x332d50,
0x332d64,
0x2879d4,
0x3ddff8,
0x3de068,
0x3de088,
0x3de0bc,
0x3de0f8,
0x3de10c,
0x3de124,
0x3de154,
0x3de1ac,
0x3de16c,
0x3de188,
0x2bad64,
0x2b9a78,
0x2b9ab0,
0x2b9a10,
0x2b9a30,
0x2b9a44,
0x1ad1b8,
0x1ad1d0,
0x2b9a4c,
0x2b9a58,
0x2b9ab8,
0x2b9ac8,
0x2b9ae4,
0x2b9af8,
0x2b9b04,
0x2b9b14,
0x2adc00,
0x2adc40,
0x2adc50,
0x2adc70,
0x2adc84,
0x2ad8e0,
0x2ad908,
0x2ad918,
0x2adc8c,
0x2ad930,
0x2ad958,
0x2ad968,
0x2adc98,
0x2ad980,
0x2ad9a4,
0x2ad9cc,
0x2ad9dc,
0x2adca4,
0x2ad9f0,
0x2ada14,
0x2ada3c,
0x2ada4c,
0x2adcb0,
0x2adcf0,
0x2b9b54,
0x2b9540,
0x2b9580,
0x2b95a0,
0x2b95b4,
0x2b95c4,
0x2b95d8,
0x2b95e4,
0x2b95f8,
0x2b9604,
0x2b9618,
0x2b9624,
0x2b9638,
0x2b9650,
0x2b965c,
0x2b9670,
0x2b967c,
0x2b9690,
0x2b96a8,
0x2b96b4,
0x2b96d8,
0x2b9700,
0x2b9760,
0x1ad748,
0x1ad78c,
0x1ad7a4,
0x2b976c,
0x2b9b68,
0x2b9b74,
0x2b9af0,
0x2ada1c,
0x2ada40,
0x2b9b80,
0x2b9b94,
0x2bad74,
0x2b8230,
0x2b824c,
0x2adf18,
0x2ada60,
0x2ada84,
0x2adaa4,
0x2adab0,
0x2adf44,
0x2adac8,
0x2adaec,
0x2adb0c,
0x2adb18,
0x2adf50,
0x2adb30,
0x2adb54,
0x2adb74,
0x2adb80,
0x2adf5c,
0x2adb98,
0x2adbbc,
0x2adbdc,
0x2adbe8,
0x2adf68,
0x2b8264,
0x2b82c0,
0x2b82dc,
0x2b830c,
0x2b7978,
0x2b7998,
0x2b79ac,
0x2b79c0,
0x2b8590,
0x2b85b0,
0x2b85c4,
0x2b8540,
0x2b8560,
0x2b8574,
0x2b86c0,
0x2b86e0,
0x2b86f4,
0x2b8758,
0x2b8778,
0x2b878c,
0x2b8628,
0x2b8648,
0x2b865c,
0x2b8438,
0x2b8458,
0x2b846c,
0x2b8474,
0x2b8498,
0x2bf068,
0x2bcff8,
0x2bd018,
0x2bd04c,
0x10f708,
0x2bd074,
0x10f718,
0x10ee20,
0x10ee40,
0x10ee98,
0x10eeb0,
0x10eebc,
0x10eed0,
0x1ae8b8,
0x1ae934,
0x1ae928,
0x1ae940,
0x1ae994,
0x1ae988,
0x1ae9a0,
0x1ae9d8,
0x1ae9e4,
0x1ae9f0,
0x1ae9fc,
0x1aea40,
0x10eed8,
0x10eee4,
0x10f728,
0x2bd080,
0x2bd088,
0x2bd098,
0x2bd0ac,
0x2bf078,
0x2b60b8,
0x2b60d4,
0x2b60e0,
0x2bf110,
0x2bd1a0,
0x2bd1d4,
0x2bd1ec,
0x2bd1f4,
0x10f7c0,
0x10eef8,
0x10ef24,
0x1aeae8,
0x1aeb38,
0x1aeb50,
0x1aebc0,
0x1aec10,
0x1aec18,
0x1aec64,
0x1aecb0,
0x1aed08,
0x1aed14,
0x1aed20,
0x1aed28,
0x1aed34,
0x1aed44,
0x1aed38,
0x1aed50,
0x1aed58,
0x1aed60,
0x1aed74,
0x1aed68,
0x1aed80,
0x1aed8c,
0x1aed94,
0x10ef2c,
0x10ef38,
0x10ef44,
0x10f7d0,
0x2bd200,
0x2bf120,
0x2e6738,
0x2e6754,
0x2e2668,
0x2e26a0,
0x2e26b8,
0x2e2708,
0x2e2724,
0x2e274c,
0x2e2770,
0x2e27ac,
0x2e27c8,
0x2e2998,
0x2e6760,
0x2b6080,
0x2b609c,
0x2ad868,
0x2ad888,
0x2ad894,
0x2ad8a0,
0x2ad8b4,
0x2ad8c0,
0x2ad8cc,
0x2b60a8,
0x2b7368,
0x2b7388,
0x2b739c,
0x2b73a4,
0x2b73bc,
0x2b76b8,
0x2b76d8,
0x2b76ec,
0x2b7708,
0x2b7720,
0x2b7588,
0x2b75a8,
0x2b75bc,
0x2b7848,
0x2b7868,
0x2b787c,
0x2b78e0,
0x2b7900,
0x2b7914,
0x2b7620,
0x2b7640,
0x2b7654,
0x2b7428,
0x2b7448,
0x2b745c,
0x2b7464,
0x2b747c,
0x2b74e8,
0x2b7508,
0x2b751c,
0x2b7528,
0x2b7780,
0x2b77a0,
0x2b77b4,
0x2b77d0,
0x2b77e8,
0x2b8328,
0x2b8348,
0x2b8358,
0x2b8364,
0x2b8378,
0x1ac600,
0x1ac650,
0x2b8380,
0x2b8390,
0x1ac360,
0x1ac39c,
0x1ac3a4,
0x2b839c,
0x316818,
0x315f60,
0x316048,
0x316094,
0x315f9c,
0x315fa4,
0x388700,
0x38872c,
0x388738,
0x388744,
0x388750,
0x315fac,
0x315fbc,
0x315fcc,
0x388c10,
0x388c30,
0x388c3c,
0x388c48,
0x388c68,
0x388e30,
0x388e84,
0x388e9c,
0x2b9510,
0x2b9d48,
0x2b9d7c,
0x2b9d88,
0x2b94f0,
0x2bae90,
0x2baea4,
0x2baeb0,
0x2baebc,
0x2baec8,
0x2baed8,
0x2b9500,
0x2b9d90,
0x2b9d80,
0x2b9d98,
0x2b9da8,
0x2b9528,
0x388ea8,
0x388ec0,
0x388ec8,
0x388ee4,
0x388eec,
0x388f00,
0x388f08,
0x388f24,
0x388f40,
0x388f4c,
0x388f5c,
0x388f6c,
0x388f74,
0x388f80,
0x388f8c,
0x2b9dd0,
0x2b9e1c,
0x2b9e24,
0x2b9e30,
0x2b9e38,
0x2b9e40,
0x2b9e48,
0x2b9e54,
0x2b9e60,
0x2b9e6c,
0x2b9e9c,
0x388f9c,
0x388fa8,
0x388fb4,
0x388ff8,
0x389004,
0x389010,
0x389020,
0x38903c,
0x2b9bc8,
0x2b9bec,
0x2b9c0c,
0x2b9c14,
0x2b9c20,
0x2b9c2c,
0x2b9c38,
0x38904c,
0x38905c,
0x389070,
0x389084,
0x389098,
0x3890a4,
0x3890b8,
0x3890c8,
0x3890d4,
0x3890e4,
0x3890f8,
0x389110,
0x389128,
0x389140,
0x389158,
0x389170,
0x389188,
0x3891a0,
0x3891b4,
0x3891bc,
0x3891d0,
0x3891dc,
0x3891e8,
0x389200,
0x3892f0,
0x38932c,
0x3e8918,
0x3e8988,
0x3e89a8,
0x3e89dc,
0x3e8a18,
0x3e8a2c,
0x3e8a44,
0x3e8a74,
0x3e8acc,
0x389338,
0x389344,
0x389388,
0x389398,
0x3893a4,
0x3893b4,
0x3893c0,
0x3893c8,
0x3893d8,
0x3893e4,
0x3893f0,
0x389404,
0x38940c,
0x389418,
0x389428,
0x2b9c50,
0x2b9c9c,
0x2b9ca4,
0x2b9cb0,
0x2b9cb8,
0x2b9cf8,
0x2b9ca8,
0x2b9cf4,
0x2b9cc0,
0x2b9cc8,
0x2b9cd4,
0x2b9ce0,
0x2b9cec,
0x2b9d1c,
0x389438,
0x389444,
0x389450,
0x389460,
0x389474,
0x2b94a0,
0x2b94bc,
0x2b94cc,
0x2b94dc,
0x389480,
0x389498,
0x3894b0,
0x3894c8,
0x3894e0,
0x3894f4,
0x389500,
0x389510,
0x38957c,
0x389588,
0x389590,
0x38968c,
0x3898ec,
0x389904,
0x389938,
0x389948,
0x389984,
0x3e8a8c,
0x3e8aa8,
0x389990,
0x38999c,
0x3899ac,
0x3899b8,
0x389380,
0x3899c8,
0x389a30,
0x389ae8,
0x389b14,
0x3899e8,
0x3899f4,
0x388c70,
0x389b20,
0x389be8,
0x389c08,
0x389c90,
0x389cf4,
0x389d08,
0x389d2c,
0x389d38,
0x389d50,
0x389d68,
0x389d70,
0x389d7c,
0x389d8c,
0x389d98,
0x389e54,
0x389f08,
0x389f14,
0x389f1c,
0x389f3c,
0x389f80,
0x389f88,
0x2adcbc,
0x2ae238,
0x2ae250,
0x2adcc4,
0x2adcd8,
0x2adce0,
0x2bd260,
0x2bd274,
0x2bd284,
0x10f2ec,
0x10f2f4,
0x2bd290,
0x2adcec,
0x389f9c,
0x389fac,
0x38aa18,
0x38aa24,
0x38aa30,
0x38aa3c,
0x389c30,
0x389c10,
0x389da0,
0x389c3c,
0x389c58,
0x389c70,
0x388c7c,
0x315ed0,
0x315eec,
0x315ef8,
0x315f04,
0x315f18,
0x315f50,
0x388c8c,
0x315ff8,
0x316028,
0x316840,
0x2fb908,
0x2f9398,
0x2f93b8,
0x2f93d0,
0x2f93d8,
0x2f9404,
0x2fb918,
0x2bae10,
0x2bae2c,
0x2bae38,
0x2fbdd8,
0x2fbdf4,
0x2fe068,
0x2fe084,
0x2fe08c,
0x2fe09c,
0x2fe0ac,
0x2fbdfc,
0x2fb9b0,
0x2f9420,
0x2f9474,
0x2fdad0,
0x2fdaf0,
0x2fdb40,
0x2f947c,
0x2fda58,
0x2fda78,
0x2fda84,
0x2fda90,
0x2fdaac,
0x2fdab8,
0x2f9484,
0x2f9490,
0x2f949c,
0x2f94a8,
0x2f94b4,
0x2fb9c0,
0x296478,
0x2964a0,
0x2964c8,
0x2964e0,
0x296508,
0x296530,
0x296548,
0x296570,
0x296598,
0x2b60f0,
0x2b610c,
0x2b611c,
0x2e69c0,
0x2e69dc,
0x2e69e8,
0x2dd014,
0x2dd024,
0x2dcbe0,
0x2dcbfc,
0x2de898,
0x2de8e0,
0x2de8f0,
0x2de8f8,
0x2de3c8,
0x2de3f0,
0x2de4f0,
0x2de518,
0x2de550,
0x2de3f8,
0x2de404,
0x2de560,
0x2de57c,
0x2de594,
0x1bf320,
0x1bf7f0,
0x1bf804,
0x1bf338,
0x2de59c,
0x2de5ac,
0x2de5bc,
0x2de40c,
0x2de414,
0x2de41c,
0x2e6a60,
0x2e6a84,
0x2e6ab8,
0x2e6b08,
0x2e6b38,
0x2e6b7c,
0x2e6b94,
0x2e6ba4,
0x2e6bc8,
0x2e6bf8,
0x2e6c28,
0x2e6c34,
0x2e6c58,
0x2de424,
0x2de904,
0x2dcc08,
0x28ad68,
0x28ad90,
0x370ea8,
0x370ec4,
0x36e060,
0x370ed0,
0x370c58,
0x370c74,
0x3649c0,
0x36c918,
0x36c954,
0x36c960,
0x36c96c,
0x36c9b8,
0x36cb50,
0x36cb80,
0x36cb88,
0x36cb90,
0x36cb98,
0x36cbb4,
0x36cbf4,
0x36cbfc,
0x36cc08,
0x34f360,
0x34f388,
0x34f394,
0x34f39c,
0x34f3ac,
0x2d7380,
0x2d72b8,
0x2d72dc,
0x2d72e4,
0x2d72f4,
0x2d7304,
0x2d7314,
0x2d7328,
0x2a6df8,
0x2a6e5c,
0x2a6e78,
0x2a6e8c,
0x2a6e9c,
0x2a6ea8,
0x2a6ec4,
0x2a6ed4,
0x2a6ee4,
0x2a6ef0,
0x2a6fd4,
0x2a6ff4,
0x2a7124,
0x2a7130,
0x2a71b4,
0x2a71c0,
0x2d7330,
0x2d7364,
0x2d73a0,
0x2d73a8,
0x2d73b4,
0x2d73c4,
0x34f3b4,
0x34f3fc,
0x36cc20,
0x36cc54,
0x36cd38,
0x36cdd0,
0x36cc68,
0x36c9e0,
0x36c9f8,
0x36ca10,
0x36ca28,
0x36ca30,
0x36ca3c,
0x36ca44,
0x36ca4c,
0x36ca5c,
0x36ca6c,
0x2c6de0,
0x2c6e00,
0x1b60f0,
0x1b6110,
0x1b6120,
0x1b6148,
0x1b6198,
0x2c6e10,
0x2c6e1c,
0x2c6e40,
0x183918,
0x183950,
0x1839c8,
0x183a10,
0x183a40,
0x14d620,
0x14cc00,
0x14cc18,
0x14d644,
0x14d94c,
0x183a50,
0x183b10,
0x183a28,
0x14cc20,
0x14cc34,
0x14cc68,
0x14cc4c,
0x14cc60,
0x14d64c,
0x14d6bc,
0x14d7ac,
0x14d910,
0x14d920,
0x14d934,
0x14d6f8,
0x14d6ac,
0x183a58,
0x183a70,
0x183a80,
0x183a8c,
0x1b5e70,
0x1b5ed0,
0x1b5ee4,
0x1b5efc,
0x1b5f10,
0x1b5f58,
0x1b5f94,
0x1b5b80,
0x1b5c10,
0x1b5c28,
0x1b5c4c,
0x1b5c68,
0x1b5c70,
0x1b5c8c,
0x1b5890,
0x1b58e0,
0x1b5918,
0x1b5978,
0x1b5980,
0x1b6508,
0x1b652c,
0x1b6540,
0x1b59a8,
0x1b59b8,
0x1b5adc,
0x1b5b18,
0x1b5b44,
0x1b5cb8,
0x1b5ccc,
0x1b5e3c,
0x1b5fbc,
0x1b5fc4,
0x1b5ffc,
0x1b601c,
0x1b5f88,
0x1b6490,
0x1b64b4,
0x1b647c,
0x1b59c0,
0x1b5930,
0x1b59d0,
0x1b5ab4,
0x1b5b30,
0x1b6544,
0x1b5c90,
0x1b5cd4,
0x1b5cdc,
0x1b5d00,
0x1b5d30,
0x1b5d08,
0x1b5d40,
0x1b5d4c,
0x1b5d74,
0x1b5da4,
0x1b5d80,
0x1b5dbc,
0x1b5dc8,
0x1b5df8,
0x1b5e24,
0x1b5e00,
0x1b5fec,
0x1b6024,
0x1b6030,
0x1b60bc,
0x183aa0,
0x183aa8,
0x183ab4,
0x183abc,
0x183b00,
0x183b1c,
0x183b24,
0x183b2c,
0x183980,
0x183988,
0x183990,
0x15ddc0,
0x14fbbc,
0x14fbc4,
0x15ddd4,
0x15ddf4,
0x15ddfc,
0x18399c,
0x1839a8,
0x2c6e50,
0x36ca74,
0x36cabc,
0x36cac8,
0x2bfcf8,
0x36cae0,
0x36caec,
0x36cafc,
0x2c1aa8,
0x2c1ac0,
0x1845b8,
0x1b6bb0,
0x1b6bf8,
0x184604,
0x1b7530,
0x15de10,
0x1b7568,
0x1b75c4,
0x184618,
0x184634,
0x184640,
0x184664,
0x18469c,
0x1846c8,
0x1843b8,
0x1843e0,
0x184408,
0x184414,
0x18441c,
0x184428,
0x184430,
0x18443c,
0x184454,
0x18445c,
0x184464,
0x184474,
0x184484,
0x1846dc,
0x1846e4,
0x1846f0,
0x1b75e0,
0x1b7620,
0x1b7648,
0x1b7678,
0x1b7848,
0x1b7878,
0x1b7970,
0x1b7690,
0x1b7708,
0x1b780c,
0x184708,
0x184758,
0x1846d0,
0x1b7880,
0x1b788c,
0x1b78c8,
0x1b78d8,
0x1b78e0,
0x1b7900,
0x1b791c,
0x1b7928,
0x1b7998,
0x1b7a4c,
0x1b7bc0,
0x1b7bd0,
0x1b7bf4,
0x1b7958,
0x1b7960,
0x1b7930,
0x1b7be4,
0x1b7bf8,
0x1b78f8,
0x1b7974,
0x1b7710,
0x1b7728,
0x1b7744,
0x1b779c,
0x1b77b4,
0x1b781c,
0x184714,
0x18471c,
0x184754,
0x184760,
0x184768,
0x184774,
0x1847a0,
0x1847b0,
0x184804,
0x1846a0,
0x184808,
0x18481c,
0x184828,
0x184834,
0x184858,
0x2c1adc,
0x2c1af0,
0x36cb04,
0x157374,
0x157384,
0x1573b0,
0x36cb14,
0x36cb2c,
0x36cb34,
0x3649e4,
0x3649ec,
0x3649f8,
0x364a00,
0x364a08,
0x2d6d58,
0x2d6d78,
0x2d6d80,
0x2d6d90,
0x2d6dac,
0x2d6dbc,
0x2a4218,
0x2a4240,
0x2a6c98,
0x2a6ce4,
0x2a6cf8,
0x1e5dd4,
0x2a6d04,
0x2a6d14,
0x2a6d1c,
0x2a6ce8,
0x3bd9c4,
0x3bd9e4,
0x3bd9cc,
0x2a6d30,
0x2a4250,
0x2a4260,
0x2a7710,
0x2a775c,
0x2a779c,
0x2a77b8,
0x2a77d4,
0x2a77f8,
0x2a780c,
0x2a7824,
0x2a790c,
0x2a7818,
0x2a7840,
0x2a7860,
0x2a7874,
0x2a78dc,
0x2a78fc,
0x3cc34c,
0x2a7908,
0x2a7918,
0x2a4270,
0x2a4278,
0x2a7210,
0x2a725c,
0x2a7274,
0x2a7280,
0x2a72a8,
0x2a72b8,
0x2a72c8,
0x2a72d8,
0x2a72e4,
0x2a7300,
0x2a7310,
0x18bce4,
0x18bd28,
0x18c6a8,
0x18c6b8,
0x18b608,
0x18c88c,
0x2a732c,
0x2a7344,
0x195e7c,
0x195e88,
0x195ebc,
0x195ec4,
0x195ecc,
0x195ee4,
0x19e5a8,
0x3d3c40,
0x19e5bc,
0x19e5c8,
0x19e994,
0x195ef8,
0x195f08,
0x195f34,
0x195f68,
0x195f80,
0x1ef8b0,
0x1ef904,
0x1ef94c,
0x1ef9a0,
0x1ef9fc,
0x195f90,
0x2a735c,
0x195eb8,
0x19e5f8,
0x3d3cc0,
0x19e604,
0x2a7370,
0x2a7384,
0x2a4284,
0x2a4298,
0x2a42a8,
0x2a42b8,
0x2a42c0,
0x191e98,
0x191ea4,
0x191898,
0x1918d0,
0x1918dc,
0x191938,
0x191984,
0x19199c,
0x1918f0,
0x191908,
0x191eb8,
0x191ecc,
0x191f9c,
0x18cd74,
0x3d3ae0,
0x18cd7c,
0x19e2f4,
0x18ca34,
0x18cf20,
0x18cf7c,
0x18cf84,
0x18d288,
0x18ca3c,
0x18ca50,
0x2a42d8,
0x2d6dc4,
0x364a10,
0x364a34,
0x364a3c,
0x366408,
0x364a50,
0x370c8c,
0x2bc650,
0x2bbb28,
0x2bd0c0,
0x2bd0d4,
0x2bd108,
0x2bd130,
0x2bd13c,
0x2bd144,
0x2bd154,
0x2bd168,
0x2bd170,
0x2bbb48,
0x2bbbc4,
0x2bbbe0,
0x2bc660,
0x3708b0,
0x3708cc,
0x3708d8,
0x3510a8,
0x3510c4,
0x34f438,
0x3510cc,
0x3510d8,
0x2bc670,
0x2bbbf8,
0x2bc7f8,
0x2bc830,
0x2bc934,
0x2bc840,
0x2bc854,
0x2bc864,
0x2bc880,
0x2bc904,
0x2bc948,
0x2bbc20,
0x2bbc2c,
0x2bc680,
0x2bc6d0,
0x2bc6e4,
0x2bc6f4,
0x2c63a0,
0x2bf9a8,
0x2bf9d0,
0x2bf9e8,
0x2bf9f4,
0x2bfa04,
0x2bfa14,
0x2bfa20,
0x2bfa2c,
0x2bfa38,
0x2bfa44,
0x2bfa50,
0x2bfa5c,
0x2bfa68,
0x1b3678,
0x1b36b8,
0x1b36d0,
0x1b3720,
0x1b372c,
0x1b3738,
0x1b3754,
0x1b3760,
0x1b3768,
0x1b3770,
0x1b37a8,
0x1b37c0,
0x1b37c8,
0x1b37e0,
0x2bfa80,
0x2bfa90,
0x2bfa9c,
0x2bfaf8,
0x15c8d0,
0x2bfb28,
0x15d250,
0x15c798,
0x14f470,
0x14f48c,
0x14f4b4,
0x14f4c0,
0x15c7c8,
0x1b2a00,
0x1b2a10,
0x1b2a28,
0x15c7e4,
0x15c7f0,
0x15c80c,
0x15d260,
0x2bfb34,
0x2bfb40,
0x2bfb50,
0x2bfb5c,
0x2bfac0,
0x2c63b0,
0x2c6448,
0x2bfb70,
0x2bfbb0,
0x2bfbd0,
0x2c09a8,
0x2c9968,
0x2c997c,
0x2c9984,
0x2d6188,
0x2d61a4,
0x2d61ac,
0x2d61b4,
0x2d61c8,
0x2d61d0,
0x2d61d8,
0x15b638,
0x15b694,
0x2d61e0,
0x2c998c,
0x2c09dc,
0x2c7548,
0x2c7558,
0x2c7564,
0x2c7570,
0x2c7584,
0x2c09e4,
0x2c09f4,
0x2c09fc,
0x2c0a08,
0x2c0a10,
0x2c0a3c,
0x14f758,
0x14f790,
0x14f7a0,
0x14f8cc,
0x14f9f0,
0x151d00,
0x151d14,
0x151d50,
0x14fa00,
0x14f8d4,
0x2c0a44,
0x2c0a88,
0x2c0a9c,
0x2c0aa8,
0x2c0ab0,
0x2c0ac0,
0x2c0af4,
0x2c0b28,
0x2c0b54,
0x2c99a0,
0x2c9a50,
0x2c0b5c,
0x2c0b68,
0x2bfbd8,
0x2bfbe4,
0x2bfbf0,
0x1b3990,
0x183580,
0x1835a4,
0x1835ac,
0x1835a0,
0x1835f8,
0x1b39c0,
0x1b39cc,
0x1b39e4,
0x1b39f0,
0x1b39fc,
0x1b3a08,
0x1b3a14,
0x1b3a20,
0x1b3a38,
0x2bfbfc,
0x2bfc54,
0x2bfc60,
0x2bfc6c,
0x2bfc78,
0x2bfc84,
0x2bfc90,
0x2bfc9c,
0x2bfca8,
0x2bfcb4,
0x2bfcc0,
0x2bfccc,
0x2bfcd8,
0x15d2f8,
0x15c838,
0x15e5c8,
0x15e624,
0x1a0690,
0x1a06a8,
0x1a06c4,
0x1a06f8,
0x1a0740,
0x1a0770,
0x1a07b4,
0x1a07c4,
0x1a07d0,
0x1a0798,
0x1a07a4,
0x1a07cc,
0x1a07dc,
0x1a0810,
0x1a0840,
0x1a0870,
0x1a08d4,
0x15e63c,
0x15e644,
0x15e660,
0x15c868,
0x15c874,
0x15c880,
0x15c888,
0x1b2a40,
0x1b2aa4,
0x1b2ab8,
0x15c89c,
0x15c8a8,
0x15c8b4,
0x15d308,
0x2bfce4,
0x2c6458,
0x382a20,
0x382a40,
0x382a4c,
0x382a5c,
0x382a64,
0x382a74,
0x382a84,
0x184dc0,
0x183b68,
0x183b74,
0x183b88,
0x183b78,
0x183b80,
0x184dd4,
0x184ddc,
0x1b6ba8,
0x184de4,
0x184e00,
0x382a94,
0x2fbc40,
0x2fbc60,
0x2fbc94,
0x2fbc9c,
0x2fbcc4,
0x274a40,
0x274a7c,
0x1ff960,
0x1ff99c,
0x1ff9d0,
0x1ffa08,
0x1ffa94,
0x1ffae8,
0x1ffafc,
0x1ffb0c,
0x274a88,
0x274a94,
0x274aa0,
0x274ae0,
0x274b70,
0x2fbce0,
0x291030,
0x291060,
0x291088,
0x291020,
0x291098,
0x2fbda0,
0x2fbdbc,
0x2fbf48,
0x2fbf5c,
0x2fbf70,
0x24d340,
0x2fbf78,
0x2fbdc8,
0x2fc2b0,
0x2fc2d0,
0x2fc2dc,
0x3ab5e8,
0x2fc2f4,
0x3ab4c0,
0x3ab4d4,
0x3ab4dc,
0x2fc300,
0x2fc30c,
0x28f670,
0x28f678,
0x2c7e90,
0x2c7eac,
0x2c15a8,
0x2c15c8,
0x2c15e0,
0x2c7578,
0x2c15f0,
0x2c15f8,
0x2c1600,
0x2c160c,
0x2c161c,
0x2c1624,
0x2c1638,
0x2c1644,
0x2c1650,
0x2c165c,
0x2c1668,
0x2c1670,
0x131b48,
0x15b6d8,
0x15b6e8,
0x15b700,
0x15b74c,
0x15b768,
0x15b7bc,
0x131b74,
0x131b8c,
0x131ba8,
0x131bd0,
0x131be4,
0x131c08,
0x2c1678,
0x2c168c,
0x2c7eb8,
0x3511a8,
0x3511c4,
0x3511d0,
0x28eb40,
0x28eb68,
0x28eb90,
0x294354,
0x294360,
0x1e56b0,
0x1e56b8,
0x1e56ec,
0x1e56f4,
0x294374,
0x2943a0,
0x2943b8,
0x1e549c,
0x1e54a4,
0x1e54b4,
0x29440c,
0x351628,
0x351644,
0x358210,
0x34f148,
0x34e1f8,
0x34e21c,
0x34e224,
0x34e22c,
0x34e240,
0x34f16c,
0x34f180,
0x34f18c,
0x355738,
0x34e374,
0x34e37c,
0x34e390,
0x34e39c,
0x34e3a4,
0x34e3ac,
0x34e3bc,
0x355754,
0x34f440,
0x35575c,
0x355768,
0x35577c,
0x355790,
0x3557a0,
0x2d7580,
0x2a6efc,
0x2a6f08,
0x2a6f14,
0x2a6f20,
0x191ab0,
0x191acc,
0x191adc,
0x2a6f30,
0x2a6f3c,
0x2a6f48,
0x2a6f5c,
0x2a6f64,
0x2a87c0,
0x2a87f8,
0x2a881c,
0x2a8834,
0x2a8800,
0x2a882c,
0x2a8844,
0x2a6f6c,
0x2a6f7c,
0x3d3988,
0x2a6f88,
0x2a85c8,
0x2a8608,
0x2a85d8,
0x2a85e8,
0x2a85fc,
0x2a6f98,
0x2a6fb8,
0x2a6fc4,
0x2d7340,
0x2d734c,
0x2a8620,
0x2d7358,
0x2d7368,
0x2d7590,
0x3557a8,
0x3557c0,
0x3557d8,
0x3557e4,
0x1844a0,
0x1844ec,
0x184504,
0x18450c,
0x184518,
0x18452c,
0x184564,
0x1844f8,
0x184534,
0x18454c,
0x18455c,
0x184570,
0x184588,
0x35580c,
0x3558a8,
0x355910,
0x3e55c8,
0x355928,
0x355934,
0x355948,
0x355968,
0x355970,
0x355990,
0x357d50,
0x357d84,
0x357d98,
0x357da4,
0x2a7000,
0x2a713c,
0x2a717c,
0x2a71b8,
0x2d73c0,
0x357dac,
0x357dcc,
0x3556d8,
0x3556f0,
0x357ddc,
0x357df0,
0x357e00,
0x357e08,
0x357e10,
0x357e20,
0x357e28,
0x357e30,
0x3559a4,
0x356538,
0x35657c,
0x356590,
0x3565f0,
0x356600,
0x356610,
0x356620,
0x3566a4,
0x3566bc,
0x356704,
0x3567a0,
0x35680c,
0x356854,
0x3568d0,
0x3568d8,
0x342ef8,
0x3435f8,
0x342f48,
0x342f64,
0x342f78,
0x342f94,
0x342fc0,
0x344198,
0x342fd0,
0x342fd8,
0x3456a8,
0x1ed548,
0x1ed5c8,
0x1ed5d8,
0x1ed5e8,
0x1ed5f4,
0x1ed674,
0x1ed684,
0x1ed694,
0x1ed74c,
0x1ed7ac,
0x1ed800,
0x3456dc,
0x3456ec,
0x38b578,
0x1ec980,
0x1eca00,
0x1eca08,
0x1eca14,
0x1eca20,
0x1eca2c,
0x1eca38,
0x1eca44,
0x1eca64,
0x38b5ec,
0x38b650,
0x38b6a4,
0x38b734,
0x38b754,
0x38b770,
0x38b790,
0x38b808,
0x38b838,
0x38b8d0,
0x38b910,
0x2f53d8,
0x2f53ec,
0x38b950,
0x2f53f4,
0x2f542c,
0x2f5458,
0x2f547c,
0x2f54b0,
0x2f5424,
0x2f56c0,
0x2f56e4,
0x2f56ec,
0x2f5710,
0x2f5738,
0x2f575c,
0x2f5784,
0x2f57a8,
0x38b960,
0x38b9a4,
0x38ba20,
0x38ba2c,
0x1e76a8,
0x1e7598,
0x1ed158,
0x1ed198,
0x1e75d0,
0x1e7614,
0x1e766c,
0x1e7688,
0x1e76c8,
0x1e76d4,
0x38ba58,
0x38ba60,
0x38bac0,
0x38bb3c,
0x38b940,
0x38bae0,
0x38baf8,
0x38bb10,
0x1e7694,
0x1e7718,
0x2f54c0,
0x2f5488,
0x38bb60,
0x38b818,
0x345700,
0x345710,
0x342ff4,
0x342ffc,
0x343014,
0x343030,
0x342f80,
0x38ba00,
0x38ba24,
0x1e7690,
0x2f58f0,
0x2f58b8,
0x38ba10,
0x343040,
0x3568f4,
0x3568fc,
0x356980,
0x344f08,
0x344f80,
0x3431f0,
0x343214,
0x344fa4,
0x344fb4,
0x344fd4,
0x1ed2d0,
0x1ed310,
0x1ed33c,
0x345030,
0x34515c,
0x38bb98,
0x38bbb0,
0x38bbc8,
0x38bc78,
0x345164,
0x345170,
0x345178,
0x345180,
0x345198,
0x345220,
0x344f88,
0x1ed340,
0x345038,
0x343690,
0x3436a4,
0x3436b4,
0x345060,
0x345070,
0x345084,
0x345094,
0x3450e0,
0x345154,
0x34524c,
0x345210,
0x345254,
0x35698c,
0x3569c4,
0x3569e8,
0x3569f0,
0x356a0c,
0x356a20,
0x356a34,
0x356a4c,
0x356a70,
0x356aa4,
0x356ab4,
0x356ac4,
0x356af8,
0x356b08,
0x356ad4,
0x356afc,
0x356b18,
0x356b20,
0x356bd0,
0x356bdc,
0x356bf0,
0x356c40,
0x356d18,
0x356d28,
0x356d30,
0x356d3c,
0x34f850,
0x34f864,
0x34f874,
0x356d6c,
0x356d7c,
0x356d90,
0x356d98,
0x356da4,
0x34f798,
0x34f7b8,
0x34f7d8,
0x356db0,
0x356dc8,
0x356dd0,
0x3a74fc,
0x3a787c,
0x1f1c94,
0x1f1ca4,
0x1f1dd0,
0x1f1e08,
0x356de0,
0x3559b8,
0x3559c4,
0x356e20,
0x3571b8,
0x3571e0,
0x3571f0,
0x3571fc,
0x3572b4,
0x3572c0,
0x1eefc8,
0x1ef01c,
0x1ef030,
0x3572d4,
0x356e38,
0x3572f0,
0x357314,
0x357324,
0x357334,
0x357340,
0x357350,
0x357358,
0x357360,
0x357378,
0x356e44,
0x3559d4,
0x356e58,
0x34ef30,
0x34efa8,
0x34eff8,
0x34f028,
0x34f030,
0x356ef4,
0x356f20,
0x356f48,
0x356f74,
0x357030,
0x34e3d0,
0x357054,
0x357074,
0x3570c0,
0x3570fc,
0x357114,
0x35719c,
0x3559e8,
0x3559f0,
0x355a00,
0x34f2a8,
0x355a08,
0x355a14,
0x355a1c,
0x34f2b8,
0x34f2d0,
0x355a24,
0x355a50,
0x34b9b0,
0x34ba04,
0x34ba18,
0x3484a0,
0x348510,
0x3482e0,
0x348300,
0x348520,
0x34a1f8,
0x3d1198,
0x3d11a8,
0x34a23c,
0x34a248,
0x34a254,
0x34a260,
0x34a26c,
0x34a278,
0x34a294,
0x34a2b0,
0x34a2d8,
0x34a328,
0x34a33c,
0x3d2650,
0x34a368,
0x34a374,
0x1e7a80,
0x1e7b54,
0x1e7bd0,
0x1e7958,
0x1e78b0,
0x1e7758,
0x1e782c,
0x1e78cc,
0x1e78ec,
0x1e78fc,
0x1e7940,
0x1e7978,
0x1e7bd8,
0x1e7d14,
0x34a3a8,
0x34a444,
0x34a350,
0x1e793c,
0x34a458,
0x348540,
0x3485e8,
0x348518,
0x1e7adc,
0x3485f4,
0x348648,
0x34baac,
0x34bca8,
0x348680,
0x3486c0,
0x3486d0,
0x34a498,
0x34a510,
0x3486e8,
0x3486f8,
0x3486c8,
0x348708,
0x34bcc4,
0x34bf44,
0x34bf5c,
0x34c1b4,
0x34c234,
0x34c28c,
0x34c2c0,
0x34c30c,
0x34c340,
0x34c394,
0x355a60,
0x355a94,
0x355aa0,
0x355abc,
0x355ac4,
0x355ad4,
0x355ae0,
0x355ae8,
0x2bd4e8,
0x2bd4fc,
0x2bd508,
0x355af4,
0x355b00,
0x355b08,
0x34e538,
0x34e550,
0x355b18,
0x355b28,
0x3e7668,
0x355b88,
0x355b90,
0x355b98,
0x355ba4,
0x355bb0,
0x355bd4,
0x34e878,
0x34e8ac,
0x2bd320,
0x2bd330,
0x2bd340,
0x34e8b8,
0x34e8c8,
0x2bd380,
0x2bd390,
0x2bd3a0,
0x34e8d4,
0x2bd350,
0x2bd360,
0x2bd370,
0x34e8e4,
0x34e900,
0x34e910,
0x34e934,
0x34e9a8,
0x34ea0c,
0x34ea3c,
0x355bf0,
0x355c0c,
0x355c74,
0x355c7c,
0x34e518,
0x34e52c,
0x355c8c,
0x355c94,
0x355cb4,
0x355cbc,
0x355cc4,
0x355ccc,
0x355cd4,
0x355cf0,
0x355d0c,
0x355d28,
0x3564d8,
0x357390,
0x3573c0,
0x3573c8,
0x3575f4,
0x357650,
0x34ea60,
0x34eac8,
0x34eae0,
0x34eaf8,
0x34eb04,
0x34eb10,
0x34eb34,
0x34eb68,
0x34eb70,
0x34eb80,
0x34eb94,
0x34eb9c,
0x1297e8,
0x129824,
0x129830,
0x129838,
0x129870,
0x1298cc,
0x1298e8,
0x129908,
0x12994c,
0x1f6900,
0x129964,
0x34ebac,
0x34ebb4,
0x34ebc0,
0x2bd3b0,
0x2bd3c0,
0x2bd3d0,
0x34ebcc,
0x34ebd8,
0x1f0ce8,
0x1f0d60,
0x34ebf0,
0x34ebfc,
0x34ec08,
0x34ec40,
0x34ec54,
0x34ec68,
0x34ec9c,
0x34ed3c,
0x34ed7c,
0x34edac,
0x34edd8,
0x34ee04,
0x34ee18,
0x34ecc8,
0x34eddc,
0x34ee08,
0x34edb0,
0x34ed80,
0x34ee2c,
0x34ee50,
0x34ee68,
0x34ee80,
0x34ee98,
0x34eea8,
0x34eed8,
0x34eef4,
0x357658,
0x3576e0,
0x3576ec,
0x357700,
0x3564e8,
0x355828,
0x34f1a0,
0x358238,
0x35165c,
0x35c0c0,
0x35c0d4,
0x35bc08,
0x35bc78,
0x35bca4,
0x35bc1c,
0x35bc5c,
0x3e7698,
0x3e7708,
0x3e7728,
0x3e775c,
0x3e7798,
0x3e77ac,
0x3e77c4,
0x3e77f4,
0x3e784c,
0x35bc64,
0x35c0dc,
0x32c8fc,
0x32c91c,
0x3376d0,
0x3333f0,
0x33340c,
0x333428,
0x33343c,
0x333444,
0x33345c,
0x33350c,
0x32f4a0,
0x32e780,
0x31f808,
0x31f258,
0x31f28c,
0x31f29c,
0x1748f8,
0x174140,
0x16e988,
0x16d018,
0x16d048,
0x1cddd8,
0x16d058,
0x16d064,
0x108468,
0x1084b0,
0x16d070,
0x16b588,
0x16b5b8,
0x16b5c4,
0x16d080,
0x16e998,
0x174170,
0x17417c,
0x174908,
0x31f2a8,
0x31f070,
0x31f08c,
0x31f2b4,
0x31f818,
0x32e7b0,
0x32e7bc,
0x336130,
0x32a7b0,
0x32a718,
0x32a748,
0x32a754,
0x32a7c0,
0x336170,
0x336184,
0x336190,
0x3247a8,
0x323850,
0x323888,
0x32389c,
0x3238a8,
0x3238a0,
0x3238b8,
0x3238d0,
0x3238ec,
0x324b70,
0x324bd0,
0x324c28,
0x324c34,
0x323918,
0x3247b8,
0x33619c,
0x3361ac,
0x3361c4,
0x3361e0,
0x336218,
0x31edd8,
0x31e1a8,
0x31e1dc,
0x31e1ec,
0x31e1f4,
0x31e204,
0x31e210,
0x31e21c,
0x31ede8,
0x336228,
0x336220,
0x336238,
0x336250,
0x33626c,
0x33629c,
0x32e7c8,
0x32f4b0,
0x333524,
0x3333f8,
0x1084a0,
0x1084a8,
0x1084bc,
0x35be7c,
0x35bd58,
0x35bd70,
0x35bd80,
0x35bd8c,
0x35bdec,
0x35beac,
0x3160bc,
0x389c60,
0x388ca0,
0x388cd8,
0x388ce4,
0x388cf0,
0x388d00,
0x388d14,
0x388d48,
0x388d90,
0x388cf8,
0x388d50,
0x388d78,
0x388d8c,
0x388d24,
0x388d30,
0x2b99a0,
0x2b99cc,
0x2bb280,
0x2bb2b4,
0x2bb2e8,
0x2bb330,
0x2bb360,
0x2bb3a4,
0x2bb3b4,
0x2bb3c0,
0x2bb388,
0x2bb394,
0x2bb3d0,
0x2bb400,
0x2bb430,
0x2bb45c,
0x2bb474,
0x2bb4b4,
0x2b99dc,
0x2b99ec,
0x1ad7f8,
0x1ad82c,
0x1ad860,
0x1ad8a8,
0x1ad8d8,
0x1ad91c,
0x1ad92c,
0x1ad938,
0x1ad900,
0x1ad90c,
0x1ad948,
0x1ad978,
0x1ad9a8,
0x1ad9d4,
0x1ad9ec,
0x1ada2c,
0x2b99f8,
0x388d40,
0x388d9c,
0x388dac,
0x2b9b88,
0x388dbc,
0x389c68,
0x3160c4,
0x3160cc,
0x3160d8,
0x388788,
0x3887e4,
0x388804,
0x38880c,
0x388814,
0x38881c,
0x3887e8,
0x38882c,
0x388838,
0x388850,
0x38887c,
0x388898,
0x3888c8,
0x3888d8,
0x3888e4,
0x3888f0,
0x3888fc,
0x388904,
0x388918,
0x388930,
0x388958,
0x388974,
0x3cca6c,
0x3cca88,
0x3cca78,
0x1a52a8,
0x1a52b8,
0x1a52e0,
0x1a52fc,
0x3889a4,
0x3889b0,
0x3889bc,
0x3889c4,
0x3889cc,
0x3160ec,
0x35672c,
0x35720c,
0x35721c,
0x357234,
0x357758,
0x3577a8,
0x3577e0,
0x3577f0,
0x3577fc,
0x357828,
0x357834,
0x357840,
0x35786c,
0x357878,
0x357884,
0x3578b0,
0x3579f0,
0x3579fc,
0x357b50,
0x3572a8,
0x3570d0,
0x355a38,
0x355a40,
0x355d30,
0x355dd0,
0x355de0,
0x355e38,
0x355e44,
0x355e60,
0x355e68,
0x355e74,
0x355e7c,
0x355e84,
0x355e94,
0x355eb4,
0x355ed0,
0x355eec,
0x355ef4,
0x355f00,
0x355f0c,
0x356010,
0x356024,
0x35602c,
0x356034,
0x356040,
0x3560e8,
0x356130,
0x356170,
0x356180,
0x356190,
0x3561a4,
0x3563c4,
0x3563cc,
0x3563d8,
0x3564bc,
0x3564d4,
0x3573d8,
0x3573ec,
0x357404,
0x357414,
0x357428,
0x35743c,
0x35749c,
0x1573bc,
0x1573ec,
0x1573f4,
0x1574c4,
0x3574a8,
0x3574b0,
0x3574bc,
0x3574c4,
0x3574cc,
0x3574d4,
0x3574e0,
0x3574ec,
0x357514,
0x357530,
0x357588,
0x3575f0,
0x357724,
0x36c1f0,
0x370f68,
0x36c1f8,
0x36c200,
0x364e70,
0x364eb0,
0x370ee0,
0x370ef8,
0x370f04,
0x370f10,
0x370f1c,
0x370f24,
0x370f2c,
0x370f40,
0x364ec8,
0x364ed0,
0x36cdf0,
0x36ce0c,
0x36ce48,
0x36ce54,
0x364ed8,
0x364ee4,
0x364f0c,
0x364f14,
0x3657a0,
0x3657dc,
0x3657fc,
0x365808,
0x365820,
0x365828,
0x365830,
0x36583c,
0x365844,
0x36584c,
0x36585c,
0x365870,
0x365884,
0x365954,
0x36595c,
0x36596c,
0x36597c,
0x365984,
0x365990,
0x36599c,
0x3659a8,
0x3659b4,
0x3659c0,
0x3659cc,
0x3659e4,
0x365bc4,
0x365bdc,
0x365be4,
0x365bf0,
0x365bfc,
0x365cec,
0x365d58,
0x366378,
0x364f28,
0x364d70,
0x364db0,
0x364dcc,
0x364e04,
0x364e20,
0x364e40,
0x364e54,
0x364f34,
0x364f4c,
0x2d6930,
0x2d6950,
0x2d695c,
0x2d6968,
0x2d6974,
0x2d6988,
0x2d699c,
0x18a8a0,
0x18a8c0,
0x2d69ac,
0x2d69b8,
0x364f64,
0x36516c,
0x36517c,
0x183d28,
0x183d3c,
0x183d44,
0x36518c,
0x36521c,
0x365224,
0x365230,
0x3652c0,
0x3655d0,
0x3655f8,
0x365608,
0x2d6dd8,
0x2d6e00,
0x2d6e08,
0x2d6e1c,
0x2d6e24,
0x2d6e34,
0x2d6e50,
0x2d6e60,
0x2a47c0,
0x2a4190,
0x2a41b4,
0x2a41c4,
0x2a41d4,
0x2a41f8,
0x2a47e8,
0x2a47f8,
0x2a4820,
0x2a482c,
0x2a4850,
0x2a486c,
0x2a488c,
0x2a4ac0,
0x2a4acc,
0x2a5758,
0x2a5824,
0x2a5830,
0x2a583c,
0x2a5848,
0x2a5858,
0x2a5860,
0x2a5868,
0x2a5880,
0x2a40f8,
0x2a412c,
0x2a5888,
0x2a58b0,
0x2a58d0,
0x2a5958,
0x2a59b0,
0x2a59e4,
0x2a5a18,
0x2a5a28,
0x2a5a38,
0x2d6570,
0x2d6588,
0x2d65ac,
0x2d65b4,
0x2a5a48,
0x1efb68,
0x2a5a54,
0x2a5ab0,
0x2a5ac0,
0x2a5ad0,
0x2a5ae8,
0x2a5b10,
0x2a5c38,
0x2a5c40,
0x2a5c50,
0x2a5c60,
0x2a5c84,
0x2a4ae0,
0x2d6e6c,
0x365610,
0x365640,
0x3652c8,
0x3652e8,
0x36c214,
0x36c240,
0x36c24c,
0x36c254,
0x36c260,
0x36c26c,
0x36c274,
0x36c280,
0x36c28c,
0x36c298,
0x36c2b0,
0x36c2bc,
0x36c300,
0x36c324,
0x36c330,
0x36c33c,
0x36c344,
0x36c390,
0x3e06e0,
0x36c398,
0x36c3d0,
0x2bc418,
0x36c424,
0x36c430,
0x36c43c,
0x36c450,
0x36c458,
0x36c460,
0x36c478,
0x36c498,
0x36c4dc,
0x36c4e8,
0x36c504,
0x36c548,
0x36c550,
0x36c55c,
0x36c3b8,
0x36c2d0,
0x2bbe04,
0x2bbe10,
0x2bbe18,
0x2bbe44,
0x2bbe58,
0x2bbe78,
0x2bbec4,
0x2bbf14,
0x3d28f0,
0x2bbf28,
0x2bbf5c,
0x1f1f40,
0x1f1f90,
0x1f1fc0,
0x3a67e0,
0x3a7890,
0x3a78f0,
0x3a7914,
0x3a7928,
0x3a7938,
0x3a795c,
0x3a7c0c,
0x3a67fc,
0x3a6810,
0x3a6818,
0x3a6820,
0x3a6828,
0x3a68c0,
0x1f1fc8,
0x1f1fe0,
0x1f201c,
0x1f2058,
0x1f2088,
0x3a7a48,
0x3a7b34,
0x3a7b84,
0x3a7c08,
0x1f2090,
0x1f20ac,
0x1f20dc,
0x1f2124,
0x1f215c,
0x1f218c,
0x1f2194,
0x1f21b0,
0x1f2260,
0x1f22bc,
0x1f22ec,
0x1f22fc,
0x1f232c,
0x1f233c,
0x1f236c,
0x1f237c,
0x2bbf68,
0x3d2918,
0x2bbf90,
0x3d28f8,
0x2bbf9c,
0x2bbfd4,
0x2bbfdc,
0x2bc088,
0x2bc14c,
0x2bc188,
0x2bc1bc,
0x2bc224,
0x2bc290,
0x2bc2bc,
0x2bc2f4,
0x1effe8,
0x1f0034,
0x1f0074,
0x1f0084,
0x1f0090,
0x1f00bc,
0x1f00c8,
0x1f00d4,
0x1f0100,
0x1f010c,
0x1f0118,
0x1f0144,
0x1f0284,
0x1f0290,
0x1f0450,
0x2bc32c,
0x2bc344,
0x2bc354,
0x2bc36c,
0x2bc384,
0x2bc39c,
0x2bc3cc,
0x2bc3e4,
0x108540,
0x108554,
0x108588,
0x1085b4,
0x1085e4,
0x108734,
0x108748,
0x108618,
0x10865c,
0x108714,
0x108744,
0x1f7e4c,
0x152644,
0x152660,
0x15266c,
0x152678,
0x12ceb0,
0x12ced4,
0x12cedc,
0x12cef0,
0x12cf50,
0x1526c8,
0x152728,
0x152744,
0x152760,
0x1527a0,
0x1527bc,
0x1527ec,
0x152824,
0x152838,
0x152850,
0x152870,
0x15289c,
0x152964,
0x152958,
0x152970,
0x152978,
0x152980,
0x152990,
0x152998,
0x1529a0,
0x1529b8,
0x1529c4,
0x1f5168,
0x1f51d0,
0x1f51fc,
0x1f5270,
0x1f529c,
0x1f531c,
0x1f53a4,
0x1f53f0,
0x1f5ed0,
0x1529e0,
0x1529e8,
0x152a50,
0x152a58,
0x15315c,
0x152818,
0x152a60,
0x152a78,
0x152a8c,
0x152ab4,
0x152ac0,
0x152bb4,
0x1f3058,
0x1f309c,
0x1f3088,
0x1f30a8,
0x152c08,
0x152cfc,
0x152d28,
0x152d38,
0x152d40,
0x152f38,
0x1f6988,
0x1f69e0,
0x1f69f8,
0x1f6a08,
0x1f6a20,
0x1f6a30,
0x1f6a8c,
0x1f6ac0,
0x1f6bb4,
0x1f6bf0,
0x1f6b68,
0x1f6be4,
0x1f6bfc,
0x1f6c3c,
0x1f6c90,
0x1f6cc0,
0x1f6c88,
0x1f6cc4,
0x1f6cd0,
0x1f6cf8,
0x1f6d28,
0x1f6d30,
0x1f6d50,
0x1f6d98,
0x1f6dd0,
0x152f60,
0x152f7c,
0x152fb4,
0x152fa8,
0x152fc0,
0x152fc8,
0x152fe4,
0x152ff4,
0x153018,
0x220128,
0x220038,
0x220040,
0x2200b4,
0x2200c8,
0x2200e8,
0x220140,
0x153038,
0x153048,
0x153078,
0x153084,
0x1530a0,
0x14c5e0,
0x14c5f0,
0x1530bc,
0x153088,
0x153894,
0x1538c0,
0x119430,
0x119460,
0x119470,
0x119494,
0x11949c,
0x1194bc,
0x1194f0,
0x1538d8,
0x153a18,
0x1530cc,
0x1530d8,
0x1530e4,
0x153108,
0x153158,
0x153174,
0x153180,
0x12cf7c,
0x152698,
0x14bc28,
0x14bc38,
0x14bc50,
0x14bc60,
0x14bd80,
0x125fc8,
0x125ff0,
0x193b0c,
0x193b34,
0x119f10,
0x11a384,
0x11a38c,
0x11a3a0,
0x11a3e0,
0x11a3e8,
0x11a3f8,
0x11a434,
0x11a454,
0x11a478,
0x11a4a4,
0x11a4c0,
0x11a4d0,
0x11a4f4,
0x11a518,
0x11a53c,
0x11a574,
0x11a5a4,
0x11a5d0,
0x119510,
0x11a5ec,
0x11a614,
0x11a628,
0x11a65c,
0x11a684,
0x11a690,
0x11afc0,
0x11afe4,
0x11b00c,
0x11aff8,
0x11b028,
0x11b048,
0x11a6a4,
0x11a6c8,
0x11a6e8,
0x11a718,
0x11a724,
0x11a754,
0x11a75c,
0x11a77c,
0x11a7f4,
0x11acb4,
0x1169c8,
0x1169fc,
0x116a04,
0x116a0c,
0x116a14,
0x3ce6d8,
0x116a20,
0x114da8,
0x14ff84,
0x14ff8c,
0x14ff94,
0x220de4,
0x220dfc,
0x2211d8,
0x221220,
0x221238,
0x221240,
0x21ae24,
0x21ae40,
0x21ae30,
0x21e320,
0x21e338,
0x21e35c,
0x21e368,
0x21e440,
0x21e370,
0x21e450,
0x21e464,
0x21e478,
0x21ae6c,
0x21af60,
0x21af78,
0x21ae80,
0x21af68,
0x21af74,
0x21af94,
0x21b190,
0x21b198,
0x22125c,
0x221324,
0x221228,
0x22132c,
0x221334,
0x22138c,
0x220e04,
0x220e1c,
0x220e48,
0x220e54,
0x21016c,
0x220e84,
0x220ea4,
0x220eb4,
0x220ec0,
0x220edc,
0x220f08,
0x2217c4,
0x2217e4,
0x21b280,
0x21b2cc,
0x21b3c8,
0x21b3e0,
0x21b2e8,
0x21b3d0,
0x21b3dc,
0x21b3fc,
0x21b418,
0x21b428,
0x21b438,
0x21b44c,
0x21b498,
0x21a528,
0x21b4a0,
0x21b4c4,
0x21b51c,
0x21b564,
0x21b5c0,
0x21b604,
0x21b610,
0x21b64c,
0x21b690,
0x211404,
0x211444,
0x21b6a0,
0x21b6ac,
0x21b6b8,
0x21b6c8,
0x21b70c,
0x21b728,
0x21b740,
0x2217fc,
0x221808,
0x221838,
0x221850,
0x21b458,
0x21b460,
0x21b484,
0x21b668,
0x21b680,
0x221860,
0x221874,
0x2219bc,
0x221810,
0x221840,
0x22187c,
0x221978,
0x221990,
0x221898,
0x221980,
0x22198c,
0x2219ac,
0x20fbcc,
0x20fbd4,
0x20fc00,
0x20fc9c,
0x20fcc8,
0x20fcec,
0x20fe0c,
0x220f34,
0x220f40,
0x220638,
0x220684,
0x220694,
0x2206bc,
0x2206cc,
0x2206dc,
0x220734,
0x20bff8,
0x20c170,
0x20c17c,
0x20c1b8,
0x20c1e0,
0x20c1ec,
0x20c218,
0x20c220,
0x20c228,
0x20c354,
0x20c414,
0x20c418,
0x20c73c,
0x20c758,
0x20c79c,
0x220788,
0x220798,
0x2207e8,
0x20c7e0,
0x20c85c,
0x20c890,
0x20c8a8,
0x20c8e4,
0x20c914,
0x20c924,
0x20c944,
0x20c970,
0x20c978,
0x20c990,
0x20c9c0,
0x20ca00,
0x20cad0,
0x20cb74,
0x20cb78,
0x20cd08,
0x20cd30,
0x20cee8,
0x20cee0,
0x20cef8,
0x20cf68,
0x20cf80,
0x20cfc4,
0x220834,
0x220844,
0x220874,
0x20c918,
0x20c954,
0x20c980,
0x20c994,
0x2208c0,
0x2208d0,
0x2208f0,
0x220918,
0x220938,
0x20c22c,
0x220978,
0x20b87c,
0x220994,
0x2209a0,
0x2209b0,
0x220f48,
0x210088,
0x220f58,
0x2213b8,
0x2213f4,
0x221428,
0x221434,
0x21b968,
0x21b98c,
0x21b9c8,
0x21219c,
0x21bc50,
0x21bc84,
0x221444,
0x221400,
0x221418,
0x21b9c4,
0x221460,
0x2214d8,
0x220f74,
0x220f7c,
0x220f8c,
0x220f94,
0x184124,
0x1848a8,
0x1848f4,
0x1849b0,
0x1849c0,
0x1849cc,
0x1849dc,
0x184a20,
0x184a58,
0x184a88,
0x184a9c,
0x184aa4,
0x184ab0,
0x184ac8,
0x184ae8,
0x184b4c,
0x184a90,
0x1b7764,
0x1b7780,
0x1b7798,
0x1b77bc,
0x1b77d8,
0x1b77e4,
0x184adc,
0x184af0,
0x184b08,
0x184b10,
0x184b48,
0x184b54,
0x184b5c,
0x184b64,
0x184bb8,
0x184bd8,
0x184be8,
0x184c34,
0x184a60,
0x184bf4,
0x184c04,
0x184c38,
0x184c4c,
0x184c54,
0x184c5c,
0x184c74,
0x1b7370,
0x1b73b4,
0x1b73d0,
0x1b73f4,
0x1b741c,
0x1b7464,
0x1b7470,
0x3822d8,
0x382310,
0x38231c,
0x38232c,
0x2dbfb0,
0x2dbfcc,
0x2dbfd4,
0x2dbfe0,
0x2fbe58,
0x2fbe74,
0x2fbe7c,
0x275f68,
0x275f84,
0x275f8c,
0x3b1be0,
0x275fa0,
0x275fa8,
0x275fbc,
0x2fbe84,
0x2fba70,
0x2fba8c,
0x2f96f8,
0x2f9720,
0x2f979c,
0x2f97a8,
0x2f97c0,
0x2f97c8,
0x2757b0,
0x276048,
0x2757e4,
0x2757f4,
0x1be960,
0x1c0960,
0x1be970,
0x275800,
0x27587c,
0x2746f0,
0x1ff138,
0x1ff6c8,
0x1ff180,
0x1ff1cc,
0x1ff1d8,
0x3b16d8,
0x3b16f0,
0x3ba8d8,
0x24d140,
0x3ba8ec,
0x3ba9a8,
0x3ba9c4,
0x3ba9cc,
0x2756d8,
0x3ba9f4,
0x3b1a70,
0x3b1a7c,
0x3b1a88,
0x3b1ab0,
0x3b1abc,
0x3b1ad4,
0x3b1ac8,
0x3b1a9c,
0x3b1aec,
0x3baa1c,
0x3baa28,
0x3baa3c,
0x3baa88,
0x3ba928,
0x3b16fc,
0x1ff1f4,
0x24d250,
0x1ff204,
0x1fdf28,
0x1fdf58,
0x3b16d0,
0x1fdf70,
0x1fdf9c,
0x1fdfe0,
0x3d8c38,
0x3d8d0c,
0x3d8d38,
0x3d8d6c,
0x3d8da8,
0x3d8db8,
0x3d8c00,
0x3d8c08,
0x3d8c2c,
0x3d8dcc,
0x3d8df8,
0x3d8e10,
0x3d8e30,
0x3d8e54,
0x3d8e74,
0x1fdfe8,
0x1ff218,
0x3bae28,
0x3bae60,
0x24d258,
0x3bae7c,
0x3bae88,
0x3bae94,
0x3baea8,
0x3baec8,
0x3baed0,
0x3baee4,
0x3baf04,
0x3baf0c,
0x276030,
0x3baf20,
0x3baf28,
0x3baf30,
0x200cb8,
0x3baf38,
0x3baf98,
0x3bafd0,
0x3bae54,
0x1ff230,
0x24d208,
0x1ff23c,
0x1ff25c,
0x3baaa0,
0x3bac28,
0x3bac30,
0x3baca0,
0x3baca8,
0x3b7768,
0x3b77b4,
0x3b77dc,
0x3b77e8,
0x3b781c,
0x3b7834,
0x3b783c,
0x3b7844,
0x3b7850,
0x3b785c,
0x3b7868,
0x3b7874,
0x3b7880,
0x3b788c,
0x3b7894,
0x3b789c,
0x3b78b0,
0x3baccc,
0x3bace0,
0x3bacec,
0x1ff270,
0x27472c,
0x275894,
0x2758b8,
0x2f97e4,
0x2fc758,
0x2fc76c,
0x1fedc4,
0x1fedb0,
0x2fc774,
0x2fc780,
0x2fc788,
0x2fc790,
0x2fc798,
0x2fc7a0,
0x2fc8d0,
0x2fe0c0,
0x2fe0e0,
0x2fe0ec,
0x2fe0f8,
0x2fe10c,
0x2fe118,
0x2fc8e4,
0x2fc8f8,
0x2fc900,
0x2fc918,
0x2fc930,
0x2fc944,
0x2fc960,
0x2fc7dc,
0x2f97f0,
0x2f9834,
0x2f9710,
0x2fbaa8,
0x2fda88,
0x382340,
0x38234c,
0x382358,
0x382364,
0x15e120,
0x15e41c,
0x382380,
0x38238c,
0x1b748c,
0x1b7498,
0x1b7430,
0x3d8e18,
0x2fe0f0,
0x2fc958,
0x3e2c20,
0x3e2c90,
0x3e2cb0,
0x3e2ce4,
0x3e2d20,
0x3e2d34,
0x3e2d4c,
0x3e2d7c,
0x3e2d94,
0x3e2db0,
0x286804,
0x1b74b0,
0x1b74b8,
0x1b6550,
0x1b6654,
0x1b665c,
0x157408,
0x157414,
0x15741c,
0x15742c,
0x15743c,
0x1574a8,
0x1574b0,
0x1b666c,
0x1b74cc,
0x1b7500,
0x184c84,
0x184c90,
0x1b3af0,
0x1b3bfc,
0x1b3c0c,
0x1b3c18,
0x1b3c24,
0x1b3c2c,
0x14f0b0,
0x1b3d1c,
0x1b3d2c,
0x1b3d38,
0x1b3d48,
0x1b3d64,
0x1b3d74,
0x1b3d80,
0x1b3d90,
0x1b3d98,
0x1b3dc8,
0x1b3dd0,
0x1b3fe0,
0x1b46dc,
0x1b46ec,
0x1b46f8,
0x1b4708,
0x1b4724,
0x1b4734,
0x1b4740,
0x1b4750,
0x1b4758,
0x1b4760,
0x1fa080,
0x1fa094,
0x1b4768,
0x1b47a0,
0x1b3fc8,
0x1b4614,
0x1b4624,
0x1b4630,
0x1b4640,
0x1b465c,
0x1b466c,
0x1b4678,
0x1b4688,
0x1b4690,
0x1b4698,
0x1b46a0,
0x1b49b0,
0x1b49b8,
0x1b49c8,
0x1b49d8,
0x1b49f8,
0x1b4a00,
0x1b4a08,
0x1b4a14,
0x1b5010,
0x1b5048,
0x1b5060,
0x1b5098,
0x1b50ac,
0x1b50c4,
0x1b50e4,
0x1b50fc,
0x1b5134,
0x1b514c,
0x1b5158,
0x1b5204,
0x1b4a28,
0x1b4a3c,
0x1b4a58,
0x1b4a68,
0x1b4ab4,
0x2dd880,
0x2dd89c,
0x2d7460,
0x2a7020,
0x1962a0,
0x19630c,
0x196318,
0x1963e0,
0x1963f0,
0x2a703c,
0x2a7060,
0x2a708c,
0x2a70ac,
0x2a70c8,
0x2a70dc,
0x2a7100,
0x2d7480,
0x2d7488,
0x2d7494,
0x2d749c,
0x2d74a8,
0x2d74b0,
0x2d74bc,
0x2d74cc,
0x2dd8a4,
0x2dd848,
0x2dd864,
0x2d73d8,
0x2d73f8,
0x2d7400,
0x2d740c,
0x2d7414,
0x2d7420,
0x2d7428,
0x2d7434,
0x2d7444,
0x2dd86c,
0x29a320,
0x29a348,
0x29a36c,
0x29a388,
0x29a39c,
0x297eb0,
0x297ee8,
0x297f04,
0x297f18,
0x297f20,
0x297f30,
0x297f38,
0x297f88,
0x297f90,
0x297fbc,
0x297fc4,
0x1bec50,
0x1beca8,
0x1becbc,
0x1becc8,
0x1becd4,
0x1c0930,
0x1bece8,
0x1bea30,
0x1bea38,
0x1bea70,
0x1d9500,
0x1d9098,
0x1d90f8,
0x1da49c,
0x1da4d4,
0x1da514,
0x1da568,
0x1da584,
0x1da58c,
0x1da610,
0x1da61c,
0x1da628,
0x1da634,
0x1da6b4,
0x1c0918,
0x1da6cc,
0x1beea8,
0x1beecc,
0x1beed4,
0x1beedc,
0x1beee4,
0x1c0958,
0x1beef4,
0x1bef68,
0x1da6d8,
0x1da6e4,
0x1da570,
0x2a2ef0,
0x2a2f0c,
0x2aa980,
0x2aa99c,
0x2aa9a8,
0x2aa9b4,
0x2a2f14,
0x1beefc,
0x1bef64,
0x3325e0,
0x1beb28,
0x3325fc,
0x332608,
0x332614,
0x332620,
0x2f83e0,
0x2f8410,
0x1c0f80,
0x1c0fd8,
0x2f8418,
0x2f8430,
0x2f8438,
0x2f8450,
0x2f8468,
0x2f8484,
0x2f84d4,
0x2f84d8,
0x2f84f0,
0x2f8508,
0x2f8524,
0x2f8558,
0x2f8560,
0x2f8578,
0x2f8590,
0x2f85ac,
0x2f85e0,
0x2f85e8,
0x2f8600,
0x2f8618,
0x2f8634,
0x2f8668,
0x2f8670,
0x2f8688,
0x2f86a0,
0x2f86bc,
0x2f86f0,
0x2f86f8,
0x2f8710,
0x2f8728,
0x2f8744,
0x2f8770,
0x2f877c,
0x2f8788,
0x38e178,
0x38e18c,
0x331d50,
0x331d9c,
0x331db4,
0x331dc0,
0x331df4,
0x331e0c,
0x331e18,
0x331e58,
0x331e98,
0x331ed8,
0x331ee4,
0x331ef0,
0x3e5e18,
0x3e5e2c,
0x331ef8,
0x16ee30,
0x16ce50,
0x16ce6c,
0x16ce94,
0x16ceb8,
0x16ee40,
0x174ae8,
0x174afc,
0x324910,
0x324940,
0x32495c,
0x324948,
0x324968,
0x325890,
0x3258e8,
0x324970,
0x31eeb8,
0x31eecc,
0x276fe8,
0x277004,
0x233028,
0x233058,
0x277018,
0x27703c,
0x163c78,
0x163ca0,
0x163cac,
0x163cb8,
0x163cc4,
0x163cd0,
0x163d10,
0x163d50,
0x164038,
0x164054,
0x164060,
0x164070,
0x164078,
0x164084,
0x161e40,
0x161e88,
0x161eb4,
0x161ed4,
0x161ee4,
0x161ef4,
0x161f1c,
0x161f30,
0x161f48,
0x161f60,
0x161f6c,
0x161f78,
0x161f80,
0x164170,
0x164180,
0x231748,
0x231794,
0x164198,
0x161f8c,
0x161ff0,
0x162028,
0x2022c0,
0x2022f8,
0x202340,
0x162034,
0x1620ac,
0x164098,
0x1c0fb0,
0x1c0fcc,
0x1640a0,
0x1640dc,
0x16412c,
0x163d58,
0x16cea8,
0x16ceb4,
0x32e810,
0x32e82c,
0x32e838,
0x337110,
0x337148,
0x337168,
0x33717c,
0x337188,
0x3371a4,
0x3371bc,
0x3371a8,
0x3371c8,
0x3371d4,
0x32e840,
0x32c430,
0x32e4f0,
0x32e50c,
0x335ee0,
0x335f10,
0x335f2c,
0x335f38,
0x338450,
0x337b48,
0x337cbc,
0x337b58,
0x337c78,
0x338468,
0x338474,
0x335f40,
0x32e514,
0x32c440,
0x1da598,
0x1da5c0,
0x1da640,
0x1da664,
0x2e00d8,
0x35e198,
0x279fa0,
0x35e1a8,
0x2e00fc,
0x3bd9dc,
0x2e0108,
0x2e0128,
0x2e0134,
0x2e0110,
0x2df598,
0x2dfe90,
0x2dff2c,
0x2dff7c,
0x2dffa0,
0x2df5bc,
0x2df5c4,
0x2dffb0,
0x2e004c,
0x2df5cc,
0x2df6a4,
0x2e0118,
0x1d6d80,
0x1d5018,
0x1d4be8,
0x1d4c3c,
0x1d5028,
0x1d6da0,
0x1d77c8,
0x2e0148,
0x2e0158,
0x1d7800,
0x1d7808,
0x1d7820,
0x1d7850,
0x1d786c,
0x1d78d0,
0x1d78e8,
0x1d794c,
0x1d7954,
0x1d7960,
0x1d7bd0,
0x1d7968,
0x1d7974,
0x1d797c,
0x1d7994,
0x1d799c,
0x1d79ac,
0x1d6af0,
0x1d79b8,
0x1d79cc,
0x1d79d8,
0x1d5830,
0x1d79e0,
0x1d7a0c,
0x1d6da8,
0x1d6db4,
0x1d6dcc,
0x1d6de4,
0x1d6df0,
0x2e0120,
0x1d6e68,
0x1d5078,
0x1d5094,
0x1d50cc,
0x1d511c,
0x1d6e88,
0x1d6e94,
0x1d6eb0,
0x1d6ecc,
0x1d6ee8,
0x1d6f40,
0x279dd0,
0x279e00,
0x27bfa0,
0x27bfdc,
0x27c000,
0x27c008,
0x279e1c,
0x279e08,
0x279e28,
0x2e1f58,
0x2e1f74,
0x2e1f80,
0x2e1f8c,
0x2e1fe4,
0x2e1ff0,
0x2e1ffc,
0x309348,
0x30935c,
0x15d338,
0x15b130,
0x15b170,
0x15b190,
0x15b198,
0x15b268,
0x15b270,
0x15b2ac,
0x15b344,
0x15b34c,
0x15b358,
0x15b364,
0x15b39c,
0x15b3ec,
0x15b3f4,
0x15b414,
0x15d34c,
0x15d358,
0x2c69f0,
0x2c6a14,
0x2de4a8,
0x2de4c4,
0x2de4cc,
0x2de4e0,
0x2c6a1c,
0x2c6a30,
0x2c6b8c,
0x2c6b94,
0x2c6ba8,
0x2c9790,
0x2c97b0,
0x2c97bc,
0x2c97c8,
0x2c97d4,
0x2c97e0,
0x2c97e8,
0x2c97f0,
0x2c97fc,
0x2c9808,
0x2c9814,
0x12cdf8,
0x12ce14,
0x12ce20,
0x12ce28,
0x12ce34,
0x12ce40,
0x12ce54,
0x12ce60,
0x12ce6c,
0x12cea4,
0x2c981c,
0x2c9838,
0x2c9840,
0x2c6bb0,
0x2c9ac0,
0x2c9ad4,
0x2c9ae0,
0x2c9aec,
0x2c9af8,
0x2c9b04,
0x2c9b10,
0x2c9b1c,
0x2c9b28,
0x2c9b34,
0x2c9b40,
0x2c9b4c,
0x2c9b58,
0x1b8990,
0x1b89b8,
0x1b89c4,
0x1b89d0,
0x1b89dc,
0x1b89e8,
0x2c9b60,
0x2c6bb8,
0x2c6c10,
0x2c6c1c,
0x2c6c28,
0x1bef1c,
0x1bef24,
0x1bef2c,
0x1bef34,
0x1bef3c,
0x1bef10,
0x1bef18,
0x1bef44,
0x1bef4c,
0x1bef58,
0x37f648,
0x37f65c,
0x30b2b8,
0x30b2cc,
0x313d38,
0x313d7c,
0x313d8c,
0x313d94,
0x313da0,
0x313dfc,
0x313480,
0x3134b4,
0x313e04,
0x312dc0,
0x312dd4,
0x312df4,
0x312dfc,
0x313e0c,
0x313e18,
0x313e28,
0x313e38,
0x313e4c,
0x313e58,
0x313e70,
0x313e90,
0x313e9c,
0x313eb4,
0x313ebc,
0x313ee4,
0x313fdc,
0x313ec8,
0x313fe8,
0x313ff0,
0x315428,
0x315440,
0x31544c,
0x31400c,
0x313ff8,
0x314018,
0x314034,
0x3157c8,
0x3157d8,
0x31404c,
0x314038,
0x314058,
0x33e340,
0x33e35c,
0x340370,
0x3403a0,
0x3403bc,
0x3403c8,
0x33e364,
0x33d660,
0x33d67c,
0x33d688,
0x33e628,
0x33e680,
0x33d690,
0x33d6a4,
0x33fad0,
0x33fb00,
0x33fb1c,
0x33fb28,
0x33fb34,
0x33fb40,
0x33d6ac,
0x2f8454,
0x2f84a4,
0x2f8544,
0x2f857c,
0x2f85cc,
0x2f8604,
0x2f8654,
0x2f868c,
0x2f86dc,
0x2f8714,
0x2f8764,
0x2f8474,
0x2f847c,
0x2f84a8,
0x2f8514,
0x2f851c,
0x2f8548,
0x309770,
0x309784,
0x312ddc,
0x312de4,
0x1a8ca0,
0x1a8cc0,
0x1a8cf4,
0x1a8d20,
0x1a8dbc,
0x1a8e04,
0x1a8e10,
0x1a8e1c,
0x1a8de8,
0x1a8df4,
0x1a8e18,
0x1a8e28,
0x312df0,
0x313e78,
0x1da6f4,
0x1da804,
0x1da7a8,
0x275338,
0x275358,
0x275364,
0x275374,
0x27537c,
0x2753c8,
0x2753d4,
0x2753e0,
0x274d00,
0x274d20,
0x274480,
0x1fe310,
0x1fe498,
0x1fe4c4,
0x1fe5ec,
0x1fe4d8,
0x1fe5f8,
0x274490,
0x274d2c,
0x274e18,
0x2753f4,
0x1d7d9c,
0x1d7de0,
0x1d7908,
0x1d7914,
0x1d791c,
0x1d6df4,
0x2753fc,
0x2754e8,
0x1d6eec,
0x2754f8,
0x275404,
0x1da7c4,
0x1da7d0,
0x1da7dc,
0x1da800,
0x1da810,
0x1da91c,
0x1da8c0,
0x1da8dc,
0x1da8e8,
0x1da8f4,
0x1da918,
0x1da928,
0x1da93c,
0x1da990,
0x1da9c4,
0x1da9fc,
0x1daaac,
0x1dab3c,
0x1dab4c,
0x1dab58,
0x1daae0,
0x1daaec,
0x1dab14,
0x1dab20,
0x1daa1c,
0x1daa64,
0x1daa94,
0x1dab68,
0x1dab84,
0x1dab90,
0x1dab98,
0x1dabac,
0x1dabc0,
0x3d7a98,
0x3d7aa8,
0x3d7ab0,
0x3d7acc,
0x1dabc8,
0x1dabe0,
0x1d9118,
0x1d9180,
0x1d91c8,
0x1d91d0,
0x1d91d8,
0x1d9214,
0x1d9264,
0x1d929c,
0x1d92ec,
0x1d92f8,
0x1d9510,
0x1becf4,
0x1bed0c,
0x1bed14,
0x297fcc,
0x27cffc,
0x30fec8,
0x2f90e0,
0x2e77a0,
0x2e77ac,
0x2e75e0,
0x2e75e8,
0x2e75f8,
0x2e7604,
0x2e7610,
0x2e7618,
0x2e7624,
0x2c9a68,
0x2c9a88,
0x2c9a94,
0x2c9aa4,
0x2e763c,
0x158440,
0x158470,
0x1ef910,
0x1ef940,
0x1ef948,
0x1ef964,
0x1ef974,
0x1ef9a4,
0x1ef9d8,
0x158480,
0x2e7644,
0x2e7654,
0x2e7688,
0x2e76bc,
0x2e76ec,
0x2e773c,
0x2e7764,
0x2e7720,
0x2d4698,
0x2d46dc,
0x2d46e4,
0x2d3c38,
0x2d3150,
0x2d3160,
0x2d3170,
0x2d3c64,
0x12d428,
0x12d808,
0x12d854,
0x12d464,
0x12d474,
0x12d47c,
0x12d49c,
0x12db48,
0x12db74,
0x12d968,
0x12db7c,
0x12dba0,
0x1f3008,
0x12dba8,
0x1f5f88,
0x12dbe8,
0x12dbf0,
0x12d988,
0x12dc00,
0x1f3ae8,
0x1f3b40,
0x1f3b5c,
0x1f3b78,
0x1f3bb4,
0x1f3bc4,
0x1f3c08,
0x1f3c30,
0x1f3c40,
0x1f3c80,
0x1f3c90,
0x1f3ce0,
0x1f3cfc,
0x1f3d0c,
0x1f3d50,
0x1f3fc4,
0x12dc0c,
0x12dc28,
0x12dc34,
0x12dc40,
0x12d4ac,
0x12d5e4,
0x2d3c7c,
0x2d46fc,
0x2d4724,
0x2d4744,
0x2e7728,
0x1f3b6c,
0x1f3c24,
0x1f3d18,
0x1f3b50,
0x1f3bb8,
0x1f3b34,
0x1f3c84,
0x1f3c14,
0x1f3c4c,
0x1f3cd4,
0x1f3d4c,
0x1f3d5c,
0x1f3da0,
0x1f3dc8,
0x1f3dd8,
0x1f3e18,
0x1f3e28,
0x1f3e78,
0x1f3e88,
0x1f3eb0,
0x1f3ee4,
0x1f3ef4,
0x1f3f44,
0x1f3f60,
0x1f3f7c,
0x1f3fb0,
0x1f3fc0,
0x12dc14,
0x12dc20,
0x12dc44,
0x12d4b4,
0x12d348,
0x12d4bc,
0x1f251c,
0x1f2560,
0x12d4c8,
0x12d358,
0x12d3a8,
0x12d3b8,
0x12d3cc,
0x12d3e0,
0x12d40c,
0x12d4d8,
0x12d4f4,
0x12d610,
0x12d654,
0x3d0618,
0x3d06bc,
0x3d06dc,
0x3d0710,
0x3d074c,
0x3d0760,
0x3d05e8,
0x3d060c,
0x3d0774,
0x3d0798,
0x3d07d4,
0x3d0824,
0x12d65c,
0x12d500,
0x2d4734,
0x2d47a0,
0x2d47cc,
0x2d47dc,
0x2d47e8,
0x2d47f8,
0x2d4808,
0x2d483c,
0x3e0a18,
0x3e0a88,
0x3e0aa8,
0x3e0adc,
0x3e0b18,
0x3e0b2c,
0x3e0b44,
0x3e0b74,
0x3e0bcc,
0x2d4844,
0x2d4740,
0x1f3cf0,
0x1f3dac,
0x1f3de4,
0x1f3e6c,
0x1f3ea4,
0x12d410,
0x12d4e0,
0x12d4ec,
0x3e0b8c,
0x3e0ba8,
0x1f3f38,
0x1f3fb4,
0x1f3f54,
0x1f3f70,
0x12dbf8,
0x2d4828,
0x2e7760,
0x2e7770,
0x2e777c,
0x2d4a24,
0x2d4788,
0x2d4a30,
0x2d4a4c,
0x2d4a90,
0x2d4ab4,
0x2d4ae4,
0x2d2828,
0x2d2858,
0x2d28a0,
0x2d28b0,
0x2d28bc,
0x2d4af0,
0x2d4b50,
0x2d4a5c,
0x2d4a28,
0x2d4ad0,
0x2d4adc,
0x2d4afc,
0x2d2788,
0x2d27a8,
0x38dcc0,
0x363804,
0x331020,
0x32fba0,
0x32fbc0,
0x331038,
0x331224,
0x331254,
0x331030,
0x331144,
0x331150,
0x3310d8,
0x33115c,
0x3311a8,
0x3312a4,
0x3313d0,
0x331360,
0x32b450,
0x32b470,
0x32b480,
0x32b490,
0x32b4a0,
0x32b4a8,
0x274af0,
0x1d95a0,
0x274af8,
0x274b00,
0x1d7c10,
0x1d7c4c,
0x1d7c54,
0x1d7c5c,
0x1d7d80,
0x1d7c68,
0x1d7c74,
0x1d7c98,
0x1d7ca0,
0x1d7ca8,
0x1d7c80,
0x1d54b4,
0x3d70b0,
0x3d7214,
0x3d7234,
0x3d7268,
0x3d72a4,
0x3d72b8,
0x3d7050,
0x3d70a4,
0x3d72cc,
0x3d7320,
0x3d735c,
0x3d73ac,
0x1d7c90,
0x1d7cb4,
0x274b14,
0x274b20,
0x274b74,
0x32b4c8,
0x32b4d8,
0x32b4e8,
0x331368,
0x1d2d24,
0x1d4a60,
0x1d2d38,
0x1d2dc0,
0x1d4670,
0x1d46b8,
0x1d46c8,
0x1d46d0,
0x1d46d8,
0x1d46e0,
0x1d46c0,
0x1d46f4,
0x1d46fc,
0x1d4708,
0x1d4714,
0x1d475c,
0x1d2dc8,
0x3e5d80,
0x3e5d88,
0x3342d8,
0x3342e0,
0x2bc700,
0x2bc714,
0x36cd1c,
0x2d27bc,
0x2d27c8,
0x2d4b04,
0x2d4918,
0x2d4928,
0x2d4934,
0x2d4940,
0x2d4948,
0x2d495c,
0x38d61c,
0x355f78,
0x355f80,
0x355f9c,
0x355fec,
0x35600c,
0x3659bc,
0x36c568,
0x10869c,
0x1086a8,
0x223fd0,
0x224000,
0x22400c,
0x224014,
0x224020,
0x224028,
0x224090,
0x22d710,
0x22d78c,
0x22d798,
0x1e157c,
0x22d7a4,
0x224098,
0x1086bc,
0x10871c,
0x221b78,
0x15b95c,
0x15b964,
0x20c988,
0x3bb158,
0x3bb160,
0x3bb16c,
0x3bb180,
0x1fef88,
0x3a13cc,
0x3a1380,
0x1b6bc8,
0x1b6bd0,
0x1b6be4,
0x1b6bf0,
0x1b6c00,
0x184900,
0x184920,
0x1b6d3c,
0x1b6d64,
0x184928,
0x184938,
0x184944,
0x1b6c10,
0x1b6c2c,
0x18494c,
0x18495c,
0x18496c,
0x184974,
0x18497c,
0x18498c,
0x184994,
0x1849a0,
0x1b7280,
0x1b72a0,
0x1b72c4,
0x1b731c,
0x1b7348,
0x1b7354,
0x1849a8,
0x1849d4,
0x184bc0,
0x184bd0,
0x1b743c,
0x1b7454,
0x1b745c,
0x1b3f20,
0x1b869c,
0x28a450,
0x3870e0,
0x3874d0,
0x3870fc,
0x28bd10,
0x28bd50,
0x28bd78,
0x28bd84,
0x28bda4,
0x28bdac,
0x28bdb8,
0x28bdcc,
0x28be68,
0x28be9c,
0x28bec8,
0x28bef4,
0x28bf20,
0x28bf4c,
0x28bf68,
0x28bf70,
0x28a7b4,
0x287ca0,
0x287cd4,
0x287cdc,
0x28a7c0,
0x287084,
0x3ddd68,
0x3dde4c,
0x3dde6c,
0x3ddea0,
0x3ddedc,
0x3ddef0,
0x3ddd5c,
0x3ddf38,
0x3ddf74,
0x3ddfc4,
0x276d50,
0x276420,
0x276440,
0x276d60,
0x287cc0,
0x3de098,
0x3de0a4,
0x3de178,
0x3de180,
0x3de1b0,
0x276df8,
0x276468,
0x276494,
0x2764a8,
0x2764c8,
0x2764e8,
0x2764f4,
0x276e08,
0x298780,
0x2987c0,
0x2987e4,
0x2987f8,
0x298804,
0x29880c,
0x298814,
0x298820,
0x29885c,
0x2881f0,
0x288220,
0x288254,
0x2882a4,
0x2882d4,
0x28831c,
0x288334,
0x288344,
0x288368,
0x288398,
0x2883c8,
0x288414,
0x288438,
0x298864,
0x293f90,
0x293fc0,
0x293fe8,
0x294004,
0x294018,
0x294024,
0x29402c,
0x294034,
0x294040,
0x294058,
0x292b28,
0x292b64,
0x292b88,
0x292ad8,
0x292afc,
0x3c3c60,
0x3c3cc4,
0x3c3ce4,
0x292b10,
0x292b9c,
0x28832c,
0x288338,
0x288300,
0x28830c,
0x292ba8,
0x293ed0,
0x293f0c,
0x293f30,
0x293f54,
0x293f64,
0x293ea8,
0x1e5a40,
0x1e5a60,
0x1e5aa0,
0x1e5acc,
0x1e5ad4,
0x1e5adc,
0x1e5ae8,
0x1e5afc,
0x1e6ab8,
0x1e6acc,
0x1e5b08,
0x1e5b14,
0x1e5b24,
0x1e5a6c,
0x1e5a78,
0x1e5a84,
0x293ec0,
0x293f74,
0x294ae0,
0x294470,
0x26bd60,
0x26bd8c,
0x26bd98,
0x26c6e8,
0x26d318,
0x269720,
0x26d334,
0x2699e8,
0x2694e0,
0x269500,
0x269518,
0x26bc00,
0x26952c,
0x2699f8,
0x26d340,
0x26d34c,
0x26eaa8,
0x26eac0,
0x26eacc,
0x26d354,
0x269ae0,
0x269af0,
0x26d360,
0x26d36c,
0x1e3ba0,
0x26d374,
0x26d37c,
0x269d38,
0x269d60,
0x1e3ec0,
0x1e3bd8,
0x1e3c04,
0x1e3c60,
0x1e3c8c,
0x1e3c10,
0x1e3c9c,
0x1e3ef0,
0x269d7c,
0x1e6968,
0x1e699c,
0x1e69ac,
0x1e69c4,
0x1e69d0,
0x1e4c78,
0x1e4c9c,
0x1e4cac,
0x1e4cd8,
0x1e4cb8,
0x1e4ce0,
0x1e69e4,
0x269d88,
0x269c40,
0x269d90,
0x269dac,
0x269de0,
0x26d388,
0x270940,
0x27095c,
0x270964,
0x1e0f38,
0x1e1148,
0x1e1178,
0x1e1184,
0x1e119c,
0x24a9a0,
0x24a9c8,
0x1e11ac,
0x1e11d4,
0x1e11ec,
0x24aa80,
0x24aaa0,
0x1e11fc,
0x1e11f0,
0x1e1220,
0x1e1140,
0x1e123c,
0x1e139c,
0x1e0f6c,
0x270978,
0x26d390,
0x26c6f8,
0x26bda8,
0x28abe8,
0x280788,
0x28ac08,
0x28ac10,
0x28ac18,
0x28ac24,
0x28ac4c,
0x297fe0,
0x298014,
0x29801c,
0x2c9360,
0x26c9d0,
0x26c9b0,
0x26ea48,
0x26ebb8,
0x26ea5c,
0x26ea64,
0x26ea6c,
0x26ea98,
0x26c9c0,
0x26c9f8,
0x26ca04,
0x26ca10,
0x26ca1c,
0x269c78,
0x269b00,
0x269b74,
0x269c8c,
0x269c9c,
0x269cb0,
0x26ca2c,
0x26ca38,
0x26ca40,
0x269c00,
0x269b98,
0x269bb0,
0x2709c8,
0x2709e0,
0x269bb8,
0x269be4,
0x3dbb60,
0x3dbbd0,
0x3dbbf0,
0x3dbc24,
0x3dbc60,
0x3dbc74,
0x3dbc8c,
0x3dbcbc,
0x3dbd14,
0x269bec,
0x269c18,
0x270ca8,
0x270cb8,
0x269c28,
0x26ca48,
0x26ca58,
0x2c9390,
0x2c939c,
0x1e4ed8,
0x1e4ef4,
0x2c93a4,
0x2c9458,
0x2c9470,
0x2c9498,
0x1e3e78,
0x1e3ea8,
0x2c94ac,
0x2c94cc,
0x1f0f58,
0x1e40b8,
0x1e40e8,
0x1f0f90,
0x3d84b8,
0x1f0fb0,
0x1f0fc8,
0x1f0fe0,
0x1f0ff8,
0x1f1010,
0x1f1028,
0x1f1048,
0x1f1060,
0x1f1078,
0x1f1090,
0x1f10a8,
0x1f10c0,
0x1f10d8,
0x1f10f0,
0x1f1108,
0x1f1120,
0x1f1138,
0x1f1150,
0x1f1168,
0x1f1180,
0x1f1198,
0x1f11b0,
0x1f11c8,
0x1f11e0,
0x1f11f8,
0x1f1210,
0x1f1228,
0x1f1240,
0x1f1258,
0x1f1270,
0x1f1288,
0x2c94d4,
0x2c93c0,
0x270e90,
0x1e4a68,
0x270ec8,
0x1e3bb8,
0x1e3bd0,
0x270edc,
0x2708c8,
0x2708e4,
0x2707a8,
0x1e3a78,
0x1e3ad0,
0x2707cc,
0x1e3b98,
0x2707d8,
0x2708f0,
0x270ee4,
0x270f04,
0x270f1c,
0x1e4d00,
0x1e4d2c,
0x1e4d44,
0x1e4d5c,
0x1e3ae8,
0x1e3af8,
0x1e4d74,
0x1e4d88,
0x1e3b08,
0x1e3b1c,
0x1e4d94,
0x1e4db4,
0x1e4dcc,
0x270f2c,
0x270f54,
0x3dc140,
0x3dc1b0,
0x3dc1d0,
0x3dc204,
0x3dc240,
0x3dc254,
0x3dc26c,
0x3dc29c,
0x3dc2f4,
0x270f5c,
0x2c93d0,
0x298038,
0x298060,
0x290320,
0x1e5df0,
0x1e5e0c,
0x1e5e14,
0x1e5e1c,
0x3bdf28,
0x3bdf38,
0x3bdf7c,
0x3be060,
0x3be040,
0x3be068,
0x1e5e28,
0x1e5e34,
0x290360,
0x269b38,
0x270ca0,
0x269b50,
0x269b5c,
0x269b78,
0x269ca4,
0x26ca50,
0x290374,
0x29037c,
0x270df8,
0x270e1c,
0x270e5c,
0x3dc2b4,
0x3dc2d0,
0x270e64,
0x290388,
0x2903b0,
0x293308,
0x269b64,
0x3dbcd4,
0x3dbcf0,
0x29334c,
0x293354,
0x270cc8,
0x270cec,
0x270d28,
0x270d30,
0x293360,
0x293388,
0x269b40,
0x3bd970,
0x3bd97c,
0x3bd9a8,
0x270d14,
0x2de280,
0x1c0938,
0x2e4588,
0x1e3a10,
0x1e3a54,
0x2e45c8,
0x1d95b8,
0x2e45e0,
0x2e4608,
0x1dac98,
0x1dacf8,
0x1dad2c,
0x1dad64,
0x1dad94,
0x1db0e0,
0x1db0f0,
0x1db0fc,
0x1dadd0,
0x1dae38,
0x1dae40,
0x1dae4c,
0x1dae8c,
0x1daec0,
0x1daef4,
0x1daf24,
0x1dafdc,
0x1daff4,
0x1db004,
0x1db048,
0x1db064,
0x1dafec,
0x1daff8,
0x1daf68,
0x1daf74,
0x1db008,
0x1db038,
0x1db040,
0x1db054,
0x1db0f8,
0x1db108,
0x1db12c,
0x1db160,
0x1db194,
0x1db1c4,
0x1db370,
0x1db384,
0x1db208,
0x1db220,
0x1db228,
0x1db280,
0x1db29c,
0x1db318,
0x1db380,
0x1db390,
0x1db3a4,
0x1db3b0,
0x1db40c,
0x1db428,
0x1db4a4,
0x2e464c,
0x1e3fe0,
0x1e4010,
0x2e48a8,
0x2e47c0,
0x2e47cc,
0x2e47d4,
0x1bf0e8,
0x1bf114,
0x1bf12c,
0x2e47e0,
0x2e47f8,
0x2e4844,
0x2e48a4,
0x2e48b4,
0x2e48d0,
0x2e48d8,
0x1d95d0,
0x1d95ec,
0x1d9620,
0x1d9650,
0x1d9678,
0x2e48e0,
0x2e48f0,
0x1d9628,
0x1d9630,
0x2e48fc,
0x2e4914,
0x2e4920,
0x2e2608,
0x2e2628,
0x2e4930,
0x2e4944,
0x2e495c,
0x2e4968,
0x2e4974,
0x2e497c,
0x1bf1a8,
0x1bf1d0,
0x1e5c48,
0x1e5c6c,
0x1e6a48,
0x1e6a60,
0x1e5c78,
0x1e5c84,
0x1e5c90,
0x1bf1dc,
0x1e5b58,
0x1e5b80,
0x1e5b90,
0x1e5b98,
0x1e5bac,
0x1e5bb8,
0x1e5bc8,
0x1e5bd4,
0x1bf1ec,
0x1bf1f8,
0x2e4988,
0x2e4994,
0x2eabc8,
0x2eabf0,
0x2eabfc,
0x2eac10,
0x2eac1c,
0x2eac28,
0x2eac30,
0x2eac3c,
0x2eac48,
0x2eac58,
0x2eac60,
0x2eac6c,
0x2eac78,
0x2ead88,
0x2eadb8,
0x2eadc4,
0x2eadcc,
0x2eadd8,
0x2eadec,
0x2eac90,
0x2eaca0,
0x2eacb0,
0x27e5f4,
0x270e48,
0x2967f8,
0x296844,
0x296850,
0x296858,
0x1fd388,
0x1fd3b8,
0x3d84c8,
0x1fd3d0,
0x1fd3e8,
0x1fd400,
0x1fd418,
0x1fd430,
0x1fd448,
0x1fd460,
0x1fd478,
0x1fd490,
0x1fd4a8,
0x1fd4c0,
0x1fd4d8,
0x296868,
0x270f40,
0x296878,
0x2968a0,
0x295170,
0x2951bc,
0x2951c8,
0x2951d0,
0x2951e0,
0x2951f0,
0x295218,
0x3dc1e0,
0x3dc1ec,
0x291380,
0x2913c4,
0x2913cc,
0x270d60,
0x270d84,
0x270db0,
0x270dcc,
0x2913d8,
0x291400,
0x2d4080,
0x2d40ac,
0x2d40b8,
0x2d0698,
0x2d06a8,
0x12de18,
0x2d06b0,
0x2d40c0,
0x2d40d0,
0x35c2a8,
0x35c2d8,
0x35c2e4,
0x35c2ec,
0x35c308,
0x35c334,
0x35c344,
0x2eacd8,
0x2ea4d8,
0x2ea4ec,
0x2ea4fc,
0x2ea50c,
0x2eace0,
0x2eacec,
0x2eacf8,
0x2ead08,
0x2ead10,
0x2ead1c,
0x2ead28,
0x2acda0,
0x2acdbc,
0x269bd0,
0x3dc2c0,
0x3dc2c8,
0x3dc2f8,
0x2acde4,
0x2acdf0,
0x2ead44,
0x2ead50,
0x2ead5c,
0x2ead68,
0x2e49b0,
0x2e49bc,
0x2e49cc,
0x2e49d4,
0x2e49dc,
0x2e49e4,
0x2e49f0,
0x2e49f8,
0x2e4a04,
0x2e4a10,
0x2e4a1c,
0x2e4a28,
0x2c95b0,
0x2c95e0,
0x2e4a34,
0x2e4a40,
0x2e4a48,
0x2e4a50,
0x2e4a5c,
0x2c95f8,
0x2c9614,
0x2c962c,
0x2e4a64,
0x2e4a90,
0x2e4a98,
0x2e4aa4,
0x2fe130,
0x2fe170,
0x2fe178,
0x2fe184,
0x2fe190,
0x2fe19c,
0x2fe1a4,
0x2fe1b4,
0x2fe1bc,
0x2fe1cc,
0x2fe188,
0x2fe1e8,
0x2fe204,
0x2fe20c,
0x2fe218,
0x2fe224,
0x2fe234,
0x2fe244,
0x2fe24c,
0x2fe25c,
0x2fe264,
0x2fe274,
0x2fe284,
0x3ab830,
0x3ab860,
0x1e4070,
0x1e40a0,
0x3ab878,
0x3ab890,
0x1e3f98,
0x1e3fc8,
0x3ab8a8,
0x3ab8c0,
0x3ab8d8,
0x3ab8f0,
0x3ab908,
0x3ab920,
0x3ab938,
0x3ab950,
0x2fe290,
0x2fe29c,
0x2fe2b8,
0x2fe2d4,
0x2fe2ec,
0x2fe2fc,
0x2fe314,
0x2fe324,
0x2fe33c,
0x2fe354,
0x2fe36c,
0x2fe384,
0x2fe210,
0x2fe388,
0x2fe394,
0x2fe3a0,
0x2e4aac,
0x2e4ac4,
0x2e4acc,
0x2e4ad8,
0x2e4ae4,
0x2e4af0,
0x2e4afc,
0x3d7af0,
0x3d7b1c,
0x3d7b38,
0x3d7b28,
0x3d7b50,
0x2e4b04,
0x1e3b58,
0x1e3b14,
0x1e3b7c,
0x2e4b28,
0x3be054,
0x2dd0a8,
0x2dd0c4,
0x2dd0d0,
0x2a80a8,
0x2a80c4,
0x2a80d0,
0x298110,
0x298144,
0x298168,
0x298178,
0x294390,
0x294398,
0x2943ac,
0x270dc4,
0x3bdff4,
0x292eb0,
0x292edc,
0x292f08,
0x292f30,
0x292f78,
0x2926e0,
0x292710,
0x292738,
0x292760,
0x2926c8,
0x292770,
0x2885cc,
0x3dc228,
0x3dc238,
0x3dbc00,
0x3dbc0c,
0x26c208,
0x26c230,
0x26c8f8,
0x3b53d8,
0x3b4550,
0x3bd380,
0x3bd3d4,
0x3bd3e0,
0x3bd3f0,
0x3bd40c,
0x3bd41c,
0x3bd424,
0x3bd438,
0x3bd440,
0x3bd454,
0x3bd47c,
0x3bd4ac,
0x3bd4c4,
0x3b45a0,
0x3bd260,
0x3bd2a0,
0x3bd2ac,
0x3bd2b4,
0x3bd2bc,
0x3bd328,
0x3bd33c,
0x3bd354,
0x3bd36c,
0x3bd2c4,
0x3bd2d4,
0x3bd2dc,
0x3bd2e4,
0x3bd2fc,
0x3b45b0,
0x3b45d0,
0x3b45e0,
0x3b4600,
0x3b460c,
0x3b461c,
0x3b4634,
0x3b53ec,
0x26c918,
0x26c240,
0x26c254,
0x291a48,
0x291a70,
0x291a94,
0x291ab0,
0x26c268,
0x26c284,
0x26c930,
0x3b53f8,
0x3b4b70,
0x3b3de8,
0x201560,
0x3b3dfc,
0x3b4b80,
0x3b3e78,
0x3b4470,
0x21a2e0,
0x3b448c,
0x3b4498,
0x3bdc58,
0x3bdc70,
0x3bdd10,
0x3bdd30,
0x3bdd50,
0x3bdd54,
0x3bdd6c,
0x3be074,
0x3be16c,
0x3be184,
0x3bdd74,
0x3b44e4,
0x3b4538,
0x3b3e9c,
0x2015e0,
0x3b3eac,
0x3b3eb4,
0x2015f0,
0x3b3ec0,
0x3b3ecc,
0x3b41f0,
0x3bd298,
0x3bd300,
0x3b4220,
0x3b423c,
0x3b4248,
0x3b4258,
0x3b4264,
0x3b4290,
0x3b42ac,
0x3bcc20,
0x3bcc6c,
0x3bcc78,
0x3bcc80,
0x3bcc88,
0x3bcca4,
0x3be650,
0x3be7c8,
0x3be7d0,
0x3be7ec,
0x3be7f8,
0x3be810,
0x3bccb8,
0x3bccfc,
0x3bcd14,
0x3b42c0,
0x3b4360,
0x3b442c,
0x3b3ef0,
0x3b3ee0,
0x3bd2cc,
0x3b422c,
0x3b4240,
0x3b42c8,
0x3b42d0,
0x3bcc08,
0x3b42d8,
0x3b4300,
0x3b430c,
0x3bce40,
0x3bce80,
0x3bce8c,
0x3bce9c,
0x3bcedc,
0x3bcef4,
0x3b4314,
0x3b4428,
0x3b4320,
0x3b4328,
0x3b4330,
0x2015c0,
0x3b433c,
0x3b4348,
0x3b4354,
0x3bcd80,
0x3bcdb0,
0x3bcdbc,
0x3bcdcc,
0x3bce00,
0x3bce18,
0x3b435c,
0x3b4384,
0x3b43e0,
0x3b4408,
0x3b4410,
0x3b4418,
0x3b3ef8,
0x3b3f08,
0x3b4b98,
0x3b4ba0,
0x3b3f20,
0x3b3f38,
0x3b3f44,
0x201600,
0x3b3f50,
0x3b4ba8,
0x3b4bb0,
0x3b4bbc,
0x3b4bd4,
0x3b4bf0,
0x3b4bf8,
0x3b4c00,
0x3b3e50,
0x201590,
0x2015b4,
0x3b3e6c,
0x3b4c0c,
0x3b4c20,
0x3b540c,
0x26c944,
0x26c290,
0x12d820,
0x12d834,
0x12d48c,
0x12d578,
0x12d588,
0x12d594,
0x12d59c,
0x12d5a8,
0x12d5b8,
0x12d508,
0x12d518,
0x12d520,
0x12d528,
0x12d534,
0x12d544,
0x12d54c,
0x3cc468,
0x3cc478
  }
)
eeObj.AddHook(0x100568, 0x3c020045, function()
for i=1,5 do
if not PrecompileAddrs:isEmpty() then
  local addr = PrecompileAddrs:dequeue()
  --print(string.format("Precompile %x", addr))
  eeObj.Precompile(addr)
end
end
end)
 
</pre>
<br>LUA(features.lua)
<pre>
<pre>
-- Lua 5.3
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
-- Title:  Indigo Prophecy PS2 - SLUS-21196 (USA)
-- Author:  Ernesto Corvi, Adam McInnis


-- Changelog:


require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
-- Performance fix
require( "ee-cpr0-alias" ) -- for EE CPR
local emuObj = getEmuObject()
local thresholdArea = 600
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80008068 , zmsk=1 } )


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


local eeObj = getEEObject()
-- Bug#9147
local emuObj = getEmuObject()
-- workaround ... -2104(gp) value is something wrong. the value comes from CCamera::Process().
--                unfortunately accurate math or any other flags don't help for this problem,
--   even though it should be calculation error issue.
--   for here, it's just given 0 radian for CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension()
--   actually the cloud is a billboard, so it should have 0 degree in view-space.
--   so given 0 degree must be OK.... but could cause some corruption (wrong perspective or something)
eeInsnReplace(0x334d64, 0xc792f7c8, 0x44809000) -- lwc1 $f18,-2104(gp)
#Performance fix.</pre>
 
SLUS_205.52
<br>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


local L1 = function() -- QDT::SINT::SCRIPT_LOADING_SCREEN::EM::Run
emuObj.ThrottleMax()
end
local L2 = function() -- QDT::SINT::SCRIPT_LOADING_SCREEN::EM::Stop
emuObj.ThrottleNorm()
end
local load1 = eeObj.AddHook(0x387040, 0x3c02004b, L1) -- QDT::SINT::SCRIPT_LOADING_SCREEN::EM::Run
local load2 = eeObj.AddHook(0x387090, 0x3c02004b, L2) -- QDT::SINT::SCRIPT_LOADING_SCREEN::EM::Stop


-- Widescreen
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
eeInsnReplace(0x20A7C0, 0x3c013faa, 0x3c013fe3)
eeInsnReplace(0x20A7C4, 0x3421aaab, 0x34218e39)
emuObj.SetDisplayAspectWide()


-- Fix for bug 9716, which is a bug in the game.
apiRequest(0.7) -- need widescreen support
-- 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
local eeObj = getEEObject()
eeInsnReplace(0x1c5b6c, 0x10400005, 0) -- QDT::KCOM::COM_SERVICE::RetrieveComHandle
local emuObj = getEmuObject()
eeInsnReplace(0x1c5d24, 0x10400005, 0) -- QDT::KCOM::COM_SERVICE::RetrieveComHandle


</pre>


====Fantavision====
local USEWIDESCREEN_ADDRESS = 0x4ba7bc
'''CLI'''
 
<br>SCES-50002
local H1 = -- start of main()
<pre>
function()
--gs-kernel-cl-up="fantavision"
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen
--gs-motion-factor=1
end
</pre>
'''LUA'''
<br>SCES-50002
<pre>
require("ee-gpr-alias")
require( "ee-hwaddr" )
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.


eeObj = getEEObject()
local H2 = -- main game loop
function()
local isWidescreen = eeObj.ReadMem8(USEWIDESCREEN_ADDRESS)
if isWidescreen == 0 then
emuObj.SetDisplayAspectNormal()
else
emuObj.SetDisplayAspectWide()
end
end


--
-- 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 hook1 = eeObj.AddHook(0x279384, 0xffbf0000, H1) -- <main>:
local chcr = ee.GetGpr(gpr.v0)
local hook2 = eeObj.AddHook(0x277784, 0x00000000, H2) -- <TheGame(void)>:
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
-- Fix for bug #9161. The 'flying cars' cheat causes crashes when attempting to
local emuObj = getEmuObject()
-- fly an helicopter. We avoid that by disabling recognition of the cheat altogether.
-- twIsLess=5 - texture width is less or eq. than 32
-- The SLPM version comes with the cheat disabled out of the box.
emuObj.SetGsTitleFix( "forcePointSampling", "reserved", {alpha = 0x80000048, twIsLess=5, thIsLess=5 } )
eeInsnReplace(0x27db2c, 0x14400015, 0x10000015) -- bnez -> b
</pre>
#Official widescreen support and removal of "flying cars" cheat due to game crash.</pre>


====Fatal Fury: Battle Archives volume 2====
SCES_503.61
ALL
<br>CLI
<pre>--gs-uprender=none
--gs-upscale=point
--host-audio-latency=0.010
--force-frame-blend=1
</pre>
<br>LUA
<br>LUA
<pre>
<pre>-- Jak EU
-- Lua 5.3
apiRequest(2.2)
-- Title: Fatal Fury: Battle Archives Volume 2 - SLUS-21723 (USA) v1.00
-- Author:  Nicola Salmoria
-- Date: February 3, 2017


local gpr    = require("ee-gpr-alias")
local emuObj = getEmuObject()vi
local eeObj = getEEObject()
local gsObj = getGsObject()
local eeOverlay = eeObj.getOverlayObject()


apiRequest(1.6)
-- Disable internal field shift compensation, part of post-process removal feature.
 
gsObj.SetDeinterlaceShift(0)
local gpr = require( "ee-gpr-alias" )
local kFilterMode, kWrapMode, kBlendMultiplier, kBlendFunc = require("sprite")
local PadConnectType = require("pad-connect-type")


local eeObj = getEEObject()
-- Fix shadow
local emuObj = getEmuObject()
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1  } )


-- Reduce flush count
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1  } )


local sprite0 = getSpriteObject(0)
-- Disable post-processing
local sprite1 = getSpriteObject(1)
-- update: removed due to occasional regression (bug#10608).  post-processing is now skipped in the EE via 'depth-cue'
local sprite2 = getSpriteObject(2)
-- emuObj.SetGsTitleFix( "ignoreSprite", "reserved", {  texType=1 , tw=5 , th=8, zmsk=1 , alpha=0x80000044  } )
local sprite3 = getSpriteObject(3)


-- Notifications should be assigned to two unused sprite slots.  Since we want them to
-- ------------------------- OVERLAY MANAGER --------------------------
-- be displayed on top of everything else, they should be the highest sprites in the list.
g_OnOverlayRegistered = function(filename, start, size)
local spr_p1_notify = getSpriteObject(4)
-- global function provided for adding per-overlay callback handlers.
local spr_p2_notify = getSpriteObject(5)
end
local spr_p1d_notify = getSpriteObject(6)
local spr_p2d_notify = getSpriteObject(7)


-- note: Texture 0 is fixed as the PS2 scanout.
local DH8 = function()
local texture1 = getTextureObject(1)
local s0 = eeObj.GetGpr(gpr.s0)
local texture2 = getTextureObject(2)
local linkblock = eeObj.ReadMem32(s0+0x5c)
local texture3 = getTextureObject(3)
local texture4 = getTextureObject(4)
--print( string.format("--> PRELOAD %08x %08x",s0, linkblock) )
local texture5 = getTextureObject(5)
local texture6 = getTextureObject(6)
local texture7 = getTextureObject(7)
 
-- ------------------------------------------------------------
local STATE_STOPPED = 0
local STATE_RUNNING = 1
 
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 notify_frames_p1 = 0
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
 
-- ---------------------------------------------------
-- 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_SL480_p.sb") -- (1) = 480P ScanLine Sim
 
texture1.Load("./ART1.png")
texture2.Load("./ART2.png")
texture3.Load("./SNK_LOGO.png")
texture4.Load("./p1.png")
texture5.Load("./p2.png")
texture6.Load("./p1d.png")
texture7.Load("./p2d.png")
 
local p1_w,p1_h = texture4.GetSize()
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
local linkblock_allocate_length = eeObj.ReadMem32 (linkblock + 0x00)
notify_p2_xsize = p2_w
local linkblock_allocate_version = eeObj.ReadMem32 (linkblock + 0x04)
notify_p1d_xsize = p1d_w
local linkblock_allocate_segment_count = eeObj.ReadMem32 (linkblock + 0x08)
notify_p2d_xsize = p2d_w
local linkblock_allocate_name = eeObj.ReadMemStr(linkblock + 0x0c)
notify_ysize = p1_h
 
local linkblock_allocate_seg1_linkptr = eeObj.ReadMem32 (linkblock + 0x4C)
spr_p1_notify.BindTexture(4)
local linkblock_allocate_seg1_dataptr = eeObj.ReadMem32 (linkblock + 0x50)
spr_p1_notify.SetPosXY(-1 - notify_p1_xsize, notify_ypos)  -- default position is fully obscured from view
local linkblock_allocate_seg1_size = eeObj.ReadMem32 (linkblock + 0x54)
    spr_p1_notify.SetSizeXY(p1_w,p1_h)
local linkblock_allocate_seg1_flags = eeObj.ReadMem32 (linkblock + 0x58)
spr_p1_notify.SetPosUV(0,0)
                                                             
    spr_p1_notify.SetSizeUV(p1_w,p1_h)
local linkblock_allocate_seg2_linkptr = eeObj.ReadMem32 (linkblock + 0x5C)
spr_p1_notify.SetBlendColorEquation(blendDefaultEquation)
local linkblock_allocate_seg2_dataptr = eeObj.ReadMem32 (linkblock + 0x60)
 
local linkblock_allocate_seg2_size = eeObj.ReadMem32 (linkblock + 0x64)
spr_p2_notify.BindTexture(5)
local linkblock_allocate_seg2_flags = eeObj.ReadMem32 (linkblock + 0x68)
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)
local linkblock_allocate_seg3_linkptr = eeObj.ReadMem32 (linkblock + 0x6C)
spr_p2_notify.SetPosUV(0,0)
local linkblock_allocate_seg3_dataptr = eeObj.ReadMem32 (linkblock + 0x70)
    spr_p2_notify.SetSizeUV(p2_w,p1_h)
local linkblock_allocate_seg3_size = eeObj.ReadMem32 (linkblock + 0x74)
spr_p2_notify.SetBlendColorEquation(blendDefaultEquation)
local linkblock_allocate_seg3_flags = eeObj.ReadMem32 (linkblock + 0x78)
 
spr_p1d_notify.BindTexture(6)
-- seg1 is equiv to main in Jak3
spr_p1d_notify.SetPosXY(-1 - notify_p1d_xsize, notify_ypos)  -- default position is fully obscured from view
-- seg3 is equiv to top  in Jak3
    spr_p1d_notify.SetSizeXY(p1d_w,p1_h)
-- seg2 appears to be unused ... ?  --jstine
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)
end


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


local update_notifications_p1 = function()
if (g_OnOverlayRegistered ~= nil) then
 
-- Make sure to execute any previously registered OnOverlay handler
if notify_animstate_p1 == STATE_STOPPED then  
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg1", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size) end
spr_p1_notify.Disable()
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg3", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size) end
spr_p1d_notify.Disable()
return
end
end
end


emuObj.ThrottleNorm()
assert(g_OnOverlayRegistered ~= nil)
local prev_OnOverlayRegistered = g_OnOverlayRegistered


local keyframe = 15
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


notify_frames_p1 = notify_frames_p1 + 1
eeObj.WriteMem32(start + 0x39c, 0x03E00008)
 
eeObj.WriteMem32(start + 0x3a0, 0x00000000)
if math.ceil(notify_frames_p1/keyframe) == notify_frames_p1/keyframe then blink_on_p1 = not blink_on_p1 end
eeObj.WriteMem32(start + 0x004, 0x03E00008)
if blink_on_p1 == true then notify_ypos = 24 end
eeObj.WriteMem32(start + 0x008, 0x00000000)
if blink_on_p1 == false then notify_ypos = -84 end
 
-- print(string.format("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("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
if (prev_OnOverlayRegistered ~= nil) then
spr_p1_notify.SetBlendColor(1.0,1.0,1.0,1.0)
-- Make sure to execute any previously registered OnOverlay handler
spr_p1_notify.SetPosXY(math.floor((1920-notify_p1_xsize)/2), notify_ypos)
prev_OnOverlayRegistered(filename, start, size)
spr_p1_notify.Enable()
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
end
end


local update_notifications_p2 = function()
-- 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>


if notify_animstate_p2 == STATE_STOPPED then
SCES-50361
spr_p2_notify.Disable()
<br>SCES-50361_features.lua
spr_p2d_notify.Disable()
<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.
return
end


emuObj.ThrottleNorm()
https://drive.google.com/file/d/1KppgZpiK5bgESrpSRKo6kKPTysZ-NAC9/view


local keyframe = 15
#Shadows fix, control scheme changes, forced 60Hz/NTSC/Widescreen.</pre>


notify_frames_p2 = notify_frames_p2 + 1
====Harvest Moon®: A Wonderful Life Special Edition====
 
CUSA06584
if math.ceil(notify_frames_p2/keyframe) == notify_frames_p2/keyframe then blink_on_p2 = not blink_on_p2 end
<br>CLI
if blink_on_p2 == true then notify_ypos = 24 + notify_ysize + 8 end
<pre>
if blink_on_p2 == false then notify_ypos = -84 - notify_ysize - 8 end
--ee-cycle-scalar=0.78
 
</pre>
-- print(string.format("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
CUSA06584
notify_animstate_p2 = STATE_STOPPED
<br>LUA
notify_frames_p2 = 0
<pre>
connected_p2 = 47
apiRequest (1.7)
end


-- print(string.format("connected_p1 %s, connected_p2 %s", connected_p1, connected_p2))
local eeObj = getEEObject()
local gpr = require("ee-gpr-alias")


if connected_p2 == true then
-- 00107be0 <syncV>: idle loop on vsync
spr_p2_notify.SetBlendColor(1.0,1.0,1.0,1.0)
eeNativeHook (0x107c14, 0x3c03005d,"FastForwardClock", 0)
spr_p2_notify.SetPosXY(math.floor((1920-notify_p2_xsize)/2), notify_ypos)
spr_p2_notify.Enable()
end


if connected_p2 == false then
eeNativeFunction(0x44f3f8, 0x27bdffd0, 'ieee754_acosf')
spr_p2d_notify.SetBlendColor(1.0,1.0,1.0,1.0)
eeNativeFunction(0x44f820, 0x27bdffd0, 'ieee754_asinf')
spr_p2d_notify.SetPosXY(math.floor((1920-notify_p2d_xsize)/2), notify_ypos)
eeNativeFunction(0x450930, 0x44036000, 'ieee754_sqrtf')
spr_p2d_notify.Enable()
eeNativeFunction(0x452848, 0x0080102d, 'fabs')
end
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')


end
eeInsnReplace(0x4443e0, 0x24030064, 0x03e00008)                -- <FlushCache>
 
eeInsnReplace(0x4443e4, 0x0000000c, 0x00000000)
-- slot can range from 0 to 3, for users 1 thru 4.
eeNativeHook (0x4443e0, 0x03e00008,'AdvanceClock',0x800)
-- pad_type can be either:  DS4, REMOTE_DS4, REMOTE_VITA, or HID
eeInsnReplace(0x444410, 0x2403ff98, 0x03e00008)                -- <iFlushCache>
local onHIDPadEvent = function(slot, connected, pad_type)
eeInsnReplace(0x444414, 0x0000000c, 0x00000000)
spr_p1_notify.Disable()
eeNativeHook (0x444410, 0x03e00008,'AdvanceClock',0x800)
spr_p1d_notify.Disable()
eeInsnReplace(0x444a58, 0x27bdffc0, 0x03e00008)                 -- <SyncDCache>
spr_p2_notify.Disable()
eeInsnReplace(0x444a5c, 0xffb20020, 0x00000000)
spr_p2d_notify.Disable()
eeNativeHook (0x444a58, 0x03e00008,'AdvanceClock',0x800)
-- print(string.format("slot %s, connected %s, pad_type %s", slot, connected, pad_type))
eeInsnReplace(0x444b98, 0x27bdffc0, 0x03e00008)                 -- <InvalidDCache>
if pad_type == PadConnectType.HID then
eeInsnReplace(0x444b9c, 0xffb20020, 0x00000000)
notify_frames_p1 = 0
eeNativeHook (0x444b98, 0x03e00008,'AdvanceClock',0x800)
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


-- bug#10318 : workaround...
eeObj.AddHook(0x3ce0fc, 0x0200202d, function()
local sign = (eeObj.GetGpr(gpr.v1) >> 31) & 1
if sign then
eeObj.SetPc(0x3ce118)
end
end)


local scanlineParams = {
240.0, -- float scanlineCount
  0.7, -- float scanlineHeight;
1.5,        -- float scanlineBrightScale;
0.5,        -- float scanlineAlpha;
0.5        -- float vignetteStrength;
}


-- ---------------------------------------------------
</pre>
-- Full Screen (480p) NoFX
====Jak 3====
-- ---------------------------------------------------
'''LUA'''
<br>SCUS-97330
<pre>
apiRequest(2.3)


local original = function()
local gpr    = require("ee-gpr-alias")
sprite0.BindTexture(0)
local emuObj = getEmuObject()
sprite0.BindFragmentShader(0)
local eeObj = getEEObject()
sprite0.SetPosXY((1920-1440)/2,0)
local gsObj = getGsObject()
sprite0.SetSizeXY(1440,1080)
local eeOverlay = eeObj.getOverlayObject()
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()


sprite1.Disable()
-- Fix shadow
end
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1  } )


-- ---------------------------------------------------
-- Reduce flush count
-- Full Screen + ScanLines (480p)
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1  } )
-- ---------------------------------------------------


local scanlines = function()
-- Disabled due to embossing effect problem --jstine
sprite0.BindTexture(0)
--emuObj.SetGsTitleFix( "trianglesAsParticles", "reserved", { hasClut=1,zmsk=1 } )
sprite0.SetPosXY((1920-1440)/2,0)
sprite0.SetSizeXY(1440,1080)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()


sprite1.Disable()
end


-- ---------------------------------------------------
-- All JAK titles have a silly way of obtaining the PS2 Timestamp Counter. A binary code snippet is written
-- SNK Overlay NoFX
-- into a NON-CONST array, like so:  static u32 getTSC[] = { 0x40024800, 0x03E00008 }; and then that snippet is
-- ---------------------------------------------------
-- called via:  ((u32 (*)())getTSC)()
local bezel = function()
--
sprite0.BindTexture(0)
-- Actual disasm of snippet:
sprite0.BindFragmentShader(0)
--   129780:40024800    mfc0        $v0,$count
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
--   129784:03E00008    jr          $ra
sprite0.SetSizeXY(1280,896)
--
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
-- Because the code is right next to data in the .data section of the process, the emulator's page fault protection
sprite0.Enable()
-- 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


sprite1.BindTexture(1)
-- Replace four separate instances:
sprite1.SetPosXY(0,0)
eeInsnReplace(0x108a78, 0x8c629790, 0x40024800) --  lw     v0,-26736(v1) -> mfc0      $v0,$count
sprite1.SetSizeXY(1920,1080)
eeInsnReplace(0x108a7c, 0x0040f809, 0x00000000) --  jalr v0          -> jr        $ra
sprite1.SetPosUV(0,0)
eeInsnReplace(0x108c80, 0x8c629790, 0x40024800) --  lw     v0,-26736(v1) -> mfc0      $v0,$count
sprite1.SetSizeUV(1920,1080)
eeInsnReplace(0x108c84, 0x0040f809, 0x00000000) --  jalr v0          -> jr        $ra
sprite1.Enable()
eeInsnReplace(0x108ea4, 0x8c629790, 0x40024800) --  lw     v0,-26736(v1) -> mfc0      $v0,$count
end
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 --------------------------
-- SNK Overlay + ScanLines (480p)
g_OnOverlayRegistered = function(filename, start, size)
-- ---------------------------------------------------
-- global function provided for adding per-overlay callback handlers.
 
local bezel_scanlines = function()
sprite0.BindTexture(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()
 
sprite1.BindTexture(1)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
end


-- ---------------------------------------------------
local DH8 = function()
-- Arcade Overlay NoFX
local s1 = eeObj.GetGpr    (gpr.s1)
-- ---------------------------------------------------
local filename = eeObj.ReadMemStr(s1 + 17)
local bezel2 = function()
local segment = eeObj.ReadMem32 (s1 +  8)
sprite0.BindTexture(0)
local main = eeObj.ReadMem32 (segment +  4)
sprite0.BindFragmentShader(0)
local mainSize = eeObj.ReadMem32 (segment +  8)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
local top = eeObj.ReadMem32 (segment + 36)
sprite0.SetSizeXY(1280,896)
local topSize = eeObj.ReadMem32 (segment + 40)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()
 
sprite1.BindTexture(2)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end


-- ---------------------------------------------------
if emuObj.IsToolingVerbose() then
-- Arcade Overlay + ScanLines (480p)
print( string.format("--> LOADED SEGMENT \"%s\" MAIN %08x size %x TOP %08x size %x", filename, main, mainSize, top, topSize) )
-- ---------------------------------------------------
end


local bezel2_scanlines = function()
eeOverlay.Register(filename .. ".main", main, mainSize, false)
sprite0.BindTexture(0)
eeOverlay.Register(filename .. ".top", top, topSize, true )
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()


sprite1.BindTexture(2)
--local debugObj = getDebugObject()
sprite1.SetPosXY(0,0)
--debugObj.eDumpDisasmToFile ("./DisasmGoal/Jak3/" .. filename .. ".main.dasm", main, mainSize, 0)
sprite1.SetSizeXY(1920,1080)
--debugObj.eDumpDisasmToFile ("./DisasmGoal/Jak3/" .. filename .. ".top.dasm",  top, topSize,  0)
sprite1.SetPosUV(0,0)
--debugObj.eDumpAotToFile    ("./DisasmGoal/Jak3/" .. filename .. ".main.aot",  main, mainSize, 0)
sprite1.SetSizeUV(1920,1080)
--debugObj.eDumpAotToFile    ("./DisasmGoal/Jak3/" .. filename .. ".top.aot",  top,  topSize, 0)
sprite1.Enable()
end


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


local VIDEOMODE_ORIGINAL = 0*2 + 0
end
local VIDEOMODE_SCANLINES = 0*2 + 1
local VIDEOMODE_ART1 = 1*2 + 0
local VIDEOMODE_ART1_SCANLINES = 1*2 + 1
local VIDEOMODE_ART2 = 2*2 + 0
local VIDEOMODE_ART2_SCANLINES = 2*2 + 1
local VIDEOMODE_LOGO = 127


local lastVideoMode = nil
eeObj.AddHook(0x1091d4, 0x0080c825, DH8)    --    <ndi::link_control::finish(void)>:


local function switchVideoMode(mode)
-- --------------------------------------------------------------------
if lastVideoMode ~= mode then
assert(g_OnOverlayRegistered ~= nil)
lastVideoMode = mode
local prev_OnOverlayRegistered = g_OnOverlayRegistered


emuObj.ThrottleNorm()
g_OnOverlayRegistered = function(filename, start, size)
if (prev_OnOverlayRegistered ~= nil) then
if mode == VIDEOMODE_ORIGINAL then
-- Make sure to execute any previously registered OnOverlay handler
original()
prev_OnOverlayRegistered(filename, start, size)
elseif mode == VIDEOMODE_SCANLINES then
scanlines()
elseif mode == VIDEOMODE_ART1 then
bezel()
elseif mode == VIDEOMODE_ART1_SCANLINES then
bezel_scanlines()
elseif mode == VIDEOMODE_ART2 then
bezel2()
elseif mode == VIDEOMODE_ART2_SCANLINES then
bezel2_scanlines()
end
end
end
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


local logoON = function(fade)
assert(eeObj.ReadMem32(start + 0x005de4) == 0x4be1043d) -- vrget.wxyz  vf01,r
lastVideoMode = VIDEOMODE_LOGO
assert(eeObj.ReadMem32(start + 0x005de8) == 0x4a0103bd) -- vsqrt        q,vf01x
assert(eeObj.ReadMem32(start + 0x005df0) == 0x4b0000a0) -- vaddq.x      vf02,vf00,q


sprite0.BindTexture(3)
assert(eeObj.ReadMem32(start + 0x005e4c) == 0x4a00143f) -- vrxor        r,vf02x
sprite0.SetPosXY(0,0)
assert(eeObj.ReadMem32(start + 0x005ef8) == 0x4a00143f) -- vrxor        r,vf02x
sprite0.SetSizeXY(1920,1080)
assert(eeObj.ReadMem32(start + 0x005f80) == 0x4a00143f) -- vrxor        r,vf02x
sprite0.SetPosUV(0,0)
assert(eeObj.ReadMem32(start + 0x006018) == 0x4a00143f) -- vrxor        r,vf02x
sprite0.SetSizeUV(1920,1080)
sprite0.SetBlendColor(fade,fade,fade,fade)
sprite0.SetBlendColorEquation(blendConstFadeEquation)
sprite0.Enable()


sprite1.Disable()
eeObj.WriteMem32(start + 0x005de4, 0x00000000)
end
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)
-- convert unsigned int to signed
eeObj.WriteMem32(start + 0x006018, 0x00000000)
local function asSigned(n)
end
local MAXINT = 0x80000000
return (n >= MAXINT and n - 2*MAXINT) or n
end
end


-- --------------------------------------------------------------------------------------
-- diagnostic for checking the Jak engine's internal frame skipping mechanism.
-- $fp30 contains a ratio of time-taken-to-16ms to render the scene, eg. 18 ms is approx 1.15.
-- The engine will proceed to make a series of logical decisions according to this value.
-- The value read out here will be affected by both EE cycle rates and adaptive GS penalties.
-- I tried modifiying this value directly but it gives somewhat unsatisfactory results.


local TH1 = -- LoadingScreen constructor
-- eeOverlay.AddPreHook("drawable.main",0x208+8, 0x461E0034, function()
function()
-- local v1 = eeObj.GetGpr(gpr.v1)
emuObj.ThrottleMax()
-- print(string.format("fpuCompare fpr0=%f fpr30=%f", eeObj.GetFpr(0), eeObj.GetFpr(30)))
end
-- end)
-- --------------------------------------------------------------------------------------
</pre>


local TH2 = -- LoadingScreen destructor
====Jak 2====
function()
'''CLI'''
emuObj.ThrottleNorm()
<br>SCUS-97265
end
<pre>
--ee-jit-pagefault-threshold=20
--gs-frontend-opt-mode=1
--gs-use-mipmap=1
--gs-kernel-cl="mipmap"
--gs-kernel-cl-up="mipmap2x2"
--cop2-no-clamping=1
--cop2-clamp-range=0x2A18,0x2a20,joint.seg1
--vu1-mpg-cycles=250
</pre>
'''LUA'''
<br>SCUS-97265
<pre>
apiRequest(2.2)


local gpr    = require("ee-gpr-alias")
local emuObj = getEmuObject()
local eeObj = getEEObject()
local eeOverlay = eeObj.getOverlayObject()
local iopObj    = getIOPObject()
local gsObj = getGsObject()


local LH1 = -- update splash screen
function()
local base = eeObj.GetGpr(gpr.s0)
local fade = eeObj.GetGpr(gpr.a1)
local splashNum = eeObj.ReadMem32(base + 12)
if splashNum == 4 then
logoON(fade / 128.0)
elseif splashNum == 5 then
switchVideoMode(VIDEOMODE_ORIGINAL)
end
end


-- Fix shadow
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1  } )


local FH1 = -- initialize autosave flag
-- Reduce flush count
function()
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1  } )
local base = eeObj.GetGpr(gpr.a0)


eeObj.WriteMem8(base + 8, 1) -- ON
---------------------------------------------------------------------------------
end
-- Basic Block breakers for EE AOT Injection
eeOverlay.AddPreHook("traffic-engine.seg1", 0x004474, 0x0080e025, "nop" )
eeOverlay.AddPreHook("spatial-hash.seg1", 0x004474, 0x0080e025, "nop" )


---------------------------------------------------------------------------------


local FH2A = -- prepare Display Settings menu
-- ------------------------- OVERLAY MANAGER --------------------------
function()
g_OnOverlayRegistered = function(filename, start, size)
local artwork = "ARTWORK"
-- global function provided for adding per-overlay callback handlers.
local scanlines = "SCANLINES"
 
eeObj.WriteMemStrZ(0x1b8d07, artwork)
eeObj.WriteMemStrZ(0x1b8d12, scanlines)
end
 
local FH2B = -- update Position X (now Artwork) description
function()
local base = eeObj.GetGpr(gpr.s2)
local buffer = eeObj.GetGpr(gpr.a1)
 
local pos = asSigned(eeObj.ReadMem32(base + 256))
-- limit to valid range
pos = pos % 3
eeObj.WriteMem32(base + 256, pos)
 
local options = {"NONE", "ART1", "ART2"}
eeObj.WriteMemStrZ(buffer, options[pos + 1])
end
 
local FH2C = -- update Position Y (now Scanlines) description
function()
local base = eeObj.GetGpr(gpr.s2)
local buffer = eeObj.GetGpr(gpr.a1)
 
local pos = asSigned(eeObj.ReadMem32(base + 260))
-- limit to valid range
pos = pos % 2
eeObj.WriteMem32(base + 260, pos)
 
local options = {"OFF", "ON"}
eeObj.WriteMemStrZ(buffer, options[pos + 1])
end
 
 
local FH3 = -- apply display position x/y settings (now Artwork/Scanlines)
function()
local posX = asSigned(eeObj.GetGpr(gpr.a0))
local posY = asSigned(eeObj.GetGpr(gpr.a1))
 
eeObj.SetGpr(gpr.a0, 0) -- force pos X to 0
eeObj.SetGpr(gpr.a1, 0) -- force pos Y to 0
 
-- limit to valid range
posX = posX % 3
posY = posY % 2
 
switchVideoMode(posX * 2 + posY)
end
 
 
 
-- register hooks
 
local elfChkSelect = function(opcode, pc, expectedOpcode)
local checkValue = eeObj.ReadMem32(0x100120)
 
if checkValue == 0x3c030026 then
assert(opcode == expectedOpcode, string.format("Overlay opcode mismatch @ 0x%06x: expected 0x%08x, found %08x", pc, expectedOpcode, opcode))
return true
else
return false
end
end
end


local elfChkBoot = function(opcode, pc, expectedOpcode)
local DH8 = function()
local checkValue = eeObj.ReadMem32(0x100120)
local s0 = eeObj.GetGpr(gpr.s0)
 
if checkValue == 0xffb00000 then
local linkblock = eeObj.ReadMem32(s0+0x60) -- was 0x5c on Jak1
assert(opcode == expectedOpcode, string.format("Overlay opcode mismatch @ 0x%06x: expected 0x%08x, found %08x", pc, expectedOpcode, opcode))
return true
--print( string.format("--> PRELOAD %08x %08x",s0, linkblock) )
else
return false
local linkblock_allocate_length = eeObj.ReadMem32 (linkblock + 0x00)
end
local linkblock_allocate_version = eeObj.ReadMem32 (linkblock + 0x04)
end
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


local hooks = {
if emuObj.IsToolingVerbose() then
-- Loading screen
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) )
eeObj.AddHook(0x105fa8, function(op, pc) return elfChkSelect(op, pc, 0x27bdfff0) end, TH1), -- <LoadingScreen::LoadingScreen(void)>:
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) )
eeObj.AddHook(0x106090, function(op, pc) return elfChkSelect(op, pc, 0x27bdffd0) end, TH2), -- <LoadingScreen::~LoadingScreen(void)>:
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


-- SNK logo
-- local debugObj = getDebugObject()
eeObj.AddHook(0x100964, function(op, pc) return elfChkBoot(op, pc, 0x8e050090) end, LH1), -- <_ZN25_GLOBAL__N_logo.cppFOxZrb8LogoPlay4stepEv>:
-- 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)


-- turn on auto save
if linkblock_allocate_seg1_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg1", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, false) end
eeObj.AddHook(0x108778, function(op, pc) return elfChkSelect(op, pc, 0xa0800008) end, FH1), -- <__0o5LMenuContentISaveLoadctv>:
if linkblock_allocate_seg3_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg3", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, true) end


-- patch Position x/y options to show Artwork/Scanlines options
if (g_OnOverlayRegistered ~= nil) then
eeObj.AddHook(0x110f50, function(op, pc) return elfChkSelect(op, pc, 0x34050005) end, FH2A), -- <__0o5X__N_8_menu_cpp_761e2d17TMenuDispSettingItemctv>:
-- Make sure to execute any previously registered OnOverlay handler
eeObj.AddHook(0x110d88, function(op, pc) return elfChkSelect(op, pc, 0x02802825) end, FH2B), -- <__0f5X__N_8_menu_cpp_761e2d17XMenuDispSettingPropertyEstepv>:
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg1", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size) end
eeObj.AddHook(0x110dc4, function(op, pc) return elfChkSelect(op, pc, 0x02802825) end, FH2C), -- <__0f5X__N_8_menu_cpp_761e2d17XMenuDispSettingPropertyEstepv>:
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg3", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size) end
 
end
-- apply artwork / scanlines settings
end
eeObj.AddHook(0x1084d4, function(op, pc) return elfChkSelect(op, pc, 0x8e050104) end, FH3), -- <__0FTapplyDisplaySettingv>:
}


-- disallow skipping splash screens
assert(g_OnOverlayRegistered ~= nil)
eeInsnReplace(0x1009a0, 0xae000014, 0x00000000) -- nop
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


-- Fight stick
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


HIDPad_Enable()
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


local addedHooks = false
assert(eeObj.ReadMem32(start + 0x00454c) == 0x4a00143f) -- vrxor        r,vf02x
local pad = function()
assert(eeObj.ReadMem32(start + 0x0045f8) == 0x4a00143f) -- vrxor        r,vf02x
if addedHooks == false then
assert(eeObj.ReadMem32(start + 0x004680) == 0x4a00143f) -- vrxor        r,vf02x
addedHooks = true
assert(eeObj.ReadMem32(start + 0x004718) == 0x4a00143f) -- vrxor        r,vf02x
switchVideoMode(VIDEOMODE_ORIGINAL)
emuObj.AddVsyncHook(update_notifications_p1)
emuObj.AddVsyncHook(update_notifications_p2)


-- test message on boot
eeObj.WriteMem32(start + 0x0044ec, 0x00000000)
-- onHIDPadEvent(0, true, PadConnectType.HID)
eeObj.WriteMem32(start + 0x0044f0, 0x00000000)
eeObj.WriteMem32(start + 0x0044f8, 0x00000000)


-- bug report:
eeObj.WriteMem32(start + 0x00454c, 0x00000000)
-- please decrease the following title sound volume to the PS4 recommendation.
eeObj.WriteMem32(start + 0x0045f8, 0x00000000)
-- REALBOUT FATAL FURY -11.49LKFS
eeObj.WriteMem32(start + 0x004680, 0x00000000)
-- REALBOUT FATAL FURY SPECIAL -10.95LKFS
eeObj.WriteMem32(start + 0x004718, 0x00000000)
-- RB2 THE NEWCOMERS -10.04LKFS
-- PS4 recommendation:-24LKFS(±2)
--
-- that's an average of -10.83
-- So set main volume to 0.3162 i.e. about 10dB attenuation.
emuObj.SetVolumes(0.3162, 1.0, 1.0)
end
end
end
end


emuObj.AddPadHook(onHIDPadEvent)
-- hooked in link_control::finish(void)>:
emuObj.AddEntryPointHook(pad)
function install_c_hooks(offset)
eeObj.AddHook(0x1085a0 + offset , 0x0080c825, DH8)  
end


</pre>


====Fu'un Super Combo!!!====
local Ready = 0
SLPS_257.81
 
<br>CLI
local DetectFunc = function()
<pre>--gs-uprender=2x2
if Ready == 0 then
--gs-upscale=point
--host-audio-latency=0.3
local discID = eeObj.ReadMemStr(0x0012fc8)
--ee-hook=0x127050,AdvanceClock,0x2403002b,0x4000
--ee-hook=0x106734,FastForwardClock,0x0c04149c
if (discID ~= "") then
--ee-native-function=memcpy,0x11fa9c,0x0080402d
--force-frame-blend=1
if (discID == "cdrom0:\\SCUS_972.65;1") or (discID == "cdrom0:\\SCPS_150.57;1") then
--vif1-ignore-cmd-ints=1
-- US or Japan Disc
#Graphical and performance fixes.</pre>
Ready = 1
 
install_c_hooks(0)
SLPS_257.81
<br>LUA
print( string.format("********************* DETECTED USA, JAPAN DISC ********************" ) )
<pre>
apiRequest(1.4)
elseif (discID == "cdrom0:\\SCKA_200.10;1") then
 
Ready = 1
eeNativeFunction(0x11fa9c, 0x0080402d, 'memcpy')
install_c_hooks(0x08)
eeNativeFunction(0x11fb48, 0x2cc20008, 'memset')
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


eeInsnReplace(0x1279d0, 0x27bdffc0, 0x03e00008)                -- <SyncDCache>
emuObj.AddVsyncHook(DetectFunc)
eeInsnReplace(0x1279d4, 0xffb20020, 0x00000000)
</pre>
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")
====Jak X====
 
'''CLI'''
local eeObj = getEEObject()
<br>SCUS-97429
local emuObj = getEmuObject()
<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>


-- *** viBufBeginPut (1)
'''LUA'''
--eeInsnReplace(0x105628, 0x0c049c78, 0) -- jal 1271e0 <WaitSema>
<br>SCUS-97429
eeInsnReplace(0x1056c8, 0x0c049c70, 0) -- jal 1271c0 <SignalSema>
<pre>
-- *** viBufEndPut (1)
-- Jak X Combat Racing  [US]
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.
apiRequest(2.2)
eeInsnReplace(0x118620, 0x0c04672a, 0) -- jal 119ca8 <_waitIpuIdle>


-- bug# 9972
local gpr = require("ee-gpr-alias")
local emuObj = getEmuObject()
local eeObj = getEEObject()
emuObj.SetGsTitleFix( "ignoreSubBuffCov", "reserved", { } )
local emuObj = getEmuObject()
#Crash/stall fixes.</pre>
local gsObj = getGsObject()
local eeOverlay = eeObj.getOverlayObject()


====Grand Theft Auto III====
SLUS_200.62
<br>CLI
<pre>--vu1-no-clamping=0
--gs-check-trans-rejection=1
--gs-kernel-cl-up="up2x2tc"
--gs-optimize-30fps=1
--ee-hook=0x27cea8,FastForwardClock
#Performance and graphical fix.</pre>


SLUS_200.62
-- Bug 10697
<br>LUA
emuObj.SetGsTitleFix( "ignoreSubBuffCov", "reserved", { texMode=2 , tw=6 , th=5} )
<pre>
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.


-- Performace fix
-- Fix shadow
local emuObj = getEmuObject()
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1 } )
local thresholdArea = 600
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80008068 , zmsk=1 } )


-- Reduce flush count
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1  } )


-- Bug#9133
-- ------------------------- OVERLAY MANAGER --------------------------
-- workaround ... -16020(gp) value is something wrong. the value comes from CCamera::Process().
g_OnOverlayRegistered = function(filename, start, size)
--               unfortunately accurate math or any other flags don't help for this problem,
-- global function provided for adding per-overlay callback handlers.
--   even though it should be calculation error issue.
-- See code for bug#10141 below, as example of this usage.
--   for here, it's just given 0 radian for CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension()
end
--   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
-- -- this hooks at the moment of loading the relocatable code and patch it only on the target segment.
<br>SLUS-20062_features.lua
eeObj.AddHook(0x0026ff90, 0x03207825, function()
<pre>-- Lua 5.3
local s1 = eeObj.GetGpr    (gpr.s1)
-- Title:  Grand Theft Auto III PS2 - SLUS-20062 (USA) v1.40
local filename = eeObj.ReadMemStr(s1 + 17)
-- Author: Nicola Salmoria
local segment = eeObj.ReadMem32 (s1 + 8)
-- Date:  November 3, 2015
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 )


require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
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)


apiRequest(0.7) -- need widescreen support


local eeObj = getEEObject()
-- ---------------------------------------------------------------------------------
local emuObj = getEmuObject()
-- 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:
 
--
local USEWIDESCREEN_ADDRESS = 0x416748
-- 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


local H1 = -- start of main()
g_OnOverlayRegistered = function(filename, start, size)
function()
if (prev_OnOverlayRegistered ~= nil) then
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen
-- Make sure to execute any previously registered OnOverlay handler
prev_OnOverlayRegistered(filename, start, size)
end
end


local H2 = -- change widescreen flag
-- bug#10141  workaround
function()
-- the problem is actually on a block 0x013090bc - 0x01309188.
local isWidescreen = eeObj.GetGpr(gpr.v0)
-- the block is expected to loop 8 times (s4 is the loop counter),
-- the game falls into freezing state once it reaches at 0x01309170.
if isWidescreen == 0 then
-- it seems it's OK just to avoid to go into this 'freeze' state, eliminated the branch.
emuObj.SetDisplayAspectNormal()
else
emuObj.SetDisplayAspectWide()
end
end


local hook1 = eeObj.AddHook(0x27ed04, 0x7fbf0000, H1) -- <main>:
-- this doesn't take into account relocatable code.
local hook2 = eeObj.AddHook(0x270e50, 0xa382b8d8, H2) -- <CMenuManager::AnaliseMenuContents(void)>:
-- eeInsnReplace(0x01309174, 0x1000012f, 0) -- beq    $zero,$zero,0x01309634   
#Official widescreen support.</pre>


====Grand Theft Auto: San Andreas====
-- 01309c64 : (1000012f) beq    $zero,$zero,0x0130a124    => nop
SLUS_209.46
if filename == "lobby-menu-manager.main" then
<br>CLI
local adr    = start + 0x1224
<pre>--gs-optimize-30fps=1
assert (eeObj.ReadMem32(adr) == 0x1000012f)
--ee-hook=0x34dee8,FastForwardClock
eeObj.WriteMem32(adr, 0)
--ee-hook=0x00245ee0,FastForwardClock
end
--cop2-no-clamping=1
--gs-flush-ad-xyz=safe
-- bug#10720 - title has a bugged RNG which does an SQRT of the current seed and xor the
--vu1-clamp-range=0x04a,0x069
-- result back into the seed.  This breaks the prime factorial pattern of the RNG and causes
--gs-use-deferred-l2h=0
-- it to fall into a repeating loop with disturbing regularity.  NOP'ing out the sqrt/xor
#Performance optimisation/fix.</pre>
-- 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
-- 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


SLUS_209.46
if filename == "sparticle-launcher.main" then
<br>LUA
assert(eeObj.ReadMem32(start + 0x00630c) == 0x4be1043d) -- vrget.wxyz  vf01,r
<pre>apiRequest(0.6) -- request version 0.1 API. Calling apiRequest() is mandatory.
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


-- bug#8979
eeObj.WriteMem32(start + 0x00630c, 0x00000000)
-- The game bugged.
eeObj.WriteMem32(start + 0x006310, 0x00000000)
-- CStreaming::StreamPedsIntoRandomSlots(int*) expects 8 integers arrray to process,
eeObj.WriteMem32(start + 0x006318, 0x00000000)
-- but CCheat::LoveConquersAllCheat() function copies just only 6 integers to the stack.
eeObj.WriteMem32(start + 0x006370, 0x00000000)
-- it seems the table of the source is correct, so using lq/sq instead of ld/sd to copy
eeObj.WriteMem32(start + 0x0063fc, 0x00000000)
-- the contents of the table correctly.
eeObj.WriteMem32(start + 0x006484, 0x00000000)
eeInsnReplace(0x59fbb0, 0xdca20010, 0x78a20010) -- ld v0,16(a1) => lq
eeObj.WriteMem32(start + 0x00651c, 0x00000000)
eeInsnReplace(0x59fbb8, 0xfc820010, 0x7c820010) -- sd v0,16(a0) => sq
end
end
-- ---------------------------------------------------------------------------------


-- bug#8979, actually different one
</pre>
-- 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>


-- Performace fix
====Kinetica====
local emuObj = getEmuObject()
'''CLI'''
local thresholdArea = 700
<br>SCUS-97132
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80000044 , zmsk=1 } )
<pre>
#Performance and rendering fixes.</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>


SLUS_209.46
'''LUA'''
<br>SLUS-20946_features.lua
<br>SCUS-97132
<pre>-- Lua 5.3
<pre>
-- Title: Grand Theft Auto: San Andreas - SLUS-20946 (USA) v3.00
local gpr = require("ee-gpr-alias")
-- Author: Nicola Salmoria
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
-- Date:  November 5, 2015


local emuObj  = getEmuObject()
local eeObj        = getEEObject()


require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
-- require("debughooks")
-- local iopObj = getIOPObject()
-- iopObj.AddHook(0x000135ac, 0x27bdffe0, DebugHooks.h_IOP_ioman_write)


apiRequest(0.7) -- need widescreen support
-- bug#8123
 
-- Skip resetting VAG stream which happens on an error.
local eeObj = getEEObject()
iopInsnReplace(0x00090028, 0x16220009, 0x08024014) -- bne $s1,$v0,0x00090050 => j 0x00090050
local emuObj = getEmuObject()


-- 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)


local USEWIDESCREEN_ADDRESS = 0x7004ef
-- 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)


local H1 = -- init widescreen flag
-- to work skipping frame mechanism correctly...
function()
-- the game checks a flag set by INTC GS whether GS still does his job or not to
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen
-- determine whether it should skip a frame or not.
end
-- 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 H2 = -- main game loop
local ee_frequency = 294912000
function()
local vsync_frequency = 59.94 -- use interlace freq.  
local isWidescreen = eeObj.ReadMem8(USEWIDESCREEN_ADDRESS)
if isWidescreen == 0 then
emuObj.SetDisplayAspectNormal()
else
emuObj.SetDisplayAspectWide()
end
end


local one_vsync_clock_on_ntsc = math.floor(ee_frequency / vsync_frequency)


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====
-- Kinetica has some inconsistency among frames -- some frames take unusually long, possibly due
SLUS_205.52
-- to AI updates.  In these cases, it is necessary to skip multiple frames to catch the game's
<br>CLI
-- clock back up to realtime.  To do so, we track 'expected_clock' over time, so that especially
<pre>--gs-check-trans-rejection=1
-- slow frames are compensated for over time.
--gs-kernel-cl-up="up2x2tc"
--gs-optimize-30fps=1
--ee-hook=0x277b88,FastForwardClock
--ee-hook=0x279a18,FastForwardClock
</pre>


SLUS_205.52
local prev_clock = 0
<br>LUA
local expected_clock = 0
<pre>
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.


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))


-- Performance fix
--prev_clock    = eeObj.GetClock() -- just update the clock.
local emuObj = getEmuObject()
expected_clock = expected_clock + one_vsync_clock_on_ntsc
local thresholdArea = 600
end)
emuObj.SetGsTitleFix( "ignoreUpRender", thresholdArea , {alpha=0x80008068 , zmsk=1 } )
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)




-- Bug#9147
-- Applies a cycle rate hack to what I presume is the game logic pipeline, for roughly per-frame updates.
-- workaround ... -2104(gp) value is something wrong. the value comes from CCamera::Process().
--                unfortunately accurate math or any other flags don't help for this problem,
--   even though it should be calculation error issue.
--   for here, it's just given 0 radian for CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension()
--   actually the cloud is a billboard, so it should have 0 degree in view-space.
--   so given 0 degree must be OK.... but could cause some corruption (wrong perspective or something)
eeInsnReplace(0x334d64, 0xc792f7c8, 0x44809000) -- lwc1 $f18,-2104(gp)
#Performance fix.</pre>


SLUS_205.52
local mpgCycles_default = 900
<br>SLUS-20552_features.lua
local currentMpgCycles = mpgCycles_default
<pre>-- Lua 5.3
-- Title: Grand Theft Auto: Vice City - SLUS-20552 (USA) v3.00
-- Author: Nicola Salmoria
-- Date:  November 4, 2015


local checkNeedsSpeedHack = function()
local stageId    = eeObj.ReadMem32(0x01fce8c)
local numPlayers = eeObj.ReadMem32(0x01ffd78) -- 0x01ffd7c seems to always match this one...


require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
-- 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


apiRequest(0.7) -- need widescreen support
-- 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


local eeObj = getEEObject()
end
local emuObj = getEmuObject()


if currentMpgCycles ~= newMpgCycles then
-- print ( string.format("################### Setting mpg-cycles = %d", newMpgCycles) )
eeObj.Vu1MpgCycles(newMpgCycles)
currentMpgCycles = newMpgCycles
end
end


local USEWIDESCREEN_ADDRESS = 0x4ba7bc
eeObj.AddHookJT(0x15ca2c,0x27bdff20,checkNeedsSpeedHack)


local H1 = -- start of main()
</pre>
function()
eeObj.WriteMem8(USEWIDESCREEN_ADDRESS, 1) -- enable widescreen
end


local H2 = -- main game loop
====The King of Fighters Collection: The Orochi Saga====
function()
<br>CLI
local isWidescreen = eeObj.ReadMem8(USEWIDESCREEN_ADDRESS)
<br>SLUS-21554
<pre>
if isWidescreen == 0 then
--host-audio-latency=0.010
emuObj.SetDisplayAspectNormal()
--force-frame-blend=1
else
</pre>
emuObj.SetDisplayAspectWide()
end
end


====King of Fighters 98 Ultimate Match====
ALL
<br>CLI
<pre>--force-frame-blend=1
--gs-use-deferred-l2h=0
#Graphical fix.</pre>


local hook1 = eeObj.AddHook(0x279384, 0xffbf0000, H1) -- <main>:
SLES_552.80
local hook2 = eeObj.AddHook(0x277784, 0x00000000, H2) -- <TheGame(void)>:
<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


-- Fix for bug #9161. The 'flying cars' cheat causes crashes when attempting to
#More stick support, shaders, bezels, widescreen fix.</pre>
-- 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.
====King of Fighters 2000====
eeInsnReplace(0x27db2c, 0x14400015, 0x10000015) -- bnez -> b
ALL
#Official widescreen support and removal of "flying cars" cheat due to game crash.</pre>
<br>CLI
<pre>--gs-uprender=none
--gs-upscale=point
--host-audio-latency=0.01
--hid-pad=1
#graphical fixes and support for further fightsticks.</pre>


SCES_503.61
SLUS_208.34
<br>LUA
<br>LUA
<pre>-- Jak EU
<pre>-- The King of Fighters 2000
apiRequest(2.2)


local gpr    = require("ee-gpr-alias")
apiRequest(1.1)
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
local emuObj = getEmuObject()
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=} )
--will fix sprite rendering artifact
ndx = 28
val = 0x86
-- spriteCorrectionTab[ndx] = val
emuObj.SetGsTitleFix( "globalSet", "reserved", { fixSpriteDivTab = val | ( ndx<<16) })
#graphical fixes.</pre>


-- Reduce flush count
SLUS_208.34
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1  } )
<br>SLUS-20834_features.lua
<pre>This is a substantial file. Over 700 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/1FsPnuxgEa0ymnGdU6w2tdy-eamRN6l3e/view
 
#More stick support, shaders, bezels, widescreen fix.</pre>


-- Disable post-processing
====Manhunt====
-- update: removed due to occasional regression (bug#10608).  post-processing is now skipped in the EE via 'depth-cue'
SLUS_208.27
-- emuObj.SetGsTitleFix( "ignoreSprite", "reserved", {  texType=1 , tw=5 , th=8, zmsk=1 , alpha=0x80000044  } )
<br>CLI
<pre>--ee-hook=0x4329e0,FastForwardClock,0x1600fff1
--gs-uv-shift-pointsampling=1
--ee-hook=0x1d1d60,AdvanceClock,0x27bdffb0,225
--ee-hook=0x1d71e0,AdvanceClock,0x0c09a4d0,100
#Fix crane issue, and probably fixing lightsourcing.</pre>


-- ------------------------- OVERLAY MANAGER --------------------------
SLUS_208.27
g_OnOverlayRegistered = function(filename, start, size)
<br>Lua
-- global function provided for adding per-overlay callback handlers.
<pre>-- Manhunt [US]
end


local DH8 = function()
local gpr = require('ee-gpr-alias')
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)
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


if emuObj.IsToolingVerbose() then
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
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
local emuObj = getEmuObject()
if linkblock_allocate_seg3_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg3",  linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, true) end
local eeObj  = getEEObject()


if (g_OnOverlayRegistered ~= nil) then
-- Bug #9413
-- Make sure to execute any previously registered OnOverlay handler
-- Disable uprender on the draw command which samples the framebuffer (0x3200) using bilinear sampling (texMode=2)
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg1", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size) end
-- All lighting effects use TriFan prim type, so use that as well to filter against.
if linkblock_allocate_seg1_size ~= 0 then g_OnOverlayRegistered(linkblock_allocate_name .. ".seg3", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size) end
end
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", {prim=5, texMode=2, tbp=0x320000} )
end


assert(g_OnOverlayRegistered ~= nil)
-- Bug#9277
local prev_OnOverlayRegistered = g_OnOverlayRegistered
-- Shorten the timeout period for some particular execution command(s).
-- When entering the crane, some instruction is executed with a wait period of 0x7333.
-- Shortening the wait period to 0x4000 it.  Note that 0x5000 is enough to fix entering the
-- crane once, but a more aggressive value was needed for subsequent entry into the crane.


g_OnOverlayRegistered = function(filename, start, size)
local FixBug9277 = function()
local s0 = eeObj.GetGpr(gpr.s0)
if filename == "depth-cue.seg1" then
--local v0 = eeObj.GetGpr(gpr.v0)
-- Disable full-screen post process via depth-cue.
--print( string.format("-------- v0=0x%08x s0=0x%08x", v0, s0) )
-- This also removes half-pixel shift during interlacing.
if s0 == 0x7333 then  
-- <depth-cue.seg1+00039c>
eeObj.SetGpr(gpr.s0, 0x5800)
-- 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
end
end


-- hooked in link_control::finish(void)>:
-- No longer seems necessary, when FastForwardClock is applied here instead (see _cli.conf)
eeObj.AddHook(0x0010ACF8, 0x040C825, DH8) -- this is address US:0010abe0 JP:0010abd8 EU:0010ACF8
eeObj.AddHookJT(0x1d71f8, 0x10000036, FixBug9277)
#Graphical fix, removal of intensive post process effects.</pre>
#Further bug fixes as well as fixing bloom/overglare from lightsources.</pre>
====Max Payne====
SLES_503.26
<br>CLI
<pre>--gs-use-clut-merge=1
--gs-kernel-cl="clutmerge"
--gs-kernel-cl-up="clutmerge2x2"
--vu1-no-clamping=1
--vu0-no-clamping=1
--fpu-no-clamping=1
--force-pal-60hz=1
--vu1-mpg-cycles=1000
--safe-area-min=1.0
--fpu-accurate-mul-fast=1
--fpu-accurate-muldiv-range=0x2acce0,0x2acce0


SCES-50361
#Graphics clean-up</pre>
<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
SLES_503.26
<br> Features Lua
<pre>-- Max Payne [US]


#Shadows fix, control scheme changes, forced 60Hz/NTSC/Widescreen.</pre>
-- Lua 5.3
-- Title: Max Payne - SLES-50326 (Europe FIGS) v1.00


====Harvest Moon®: A Wonderful Life Special Edition====
CUSA06584
<br>CLI
<pre>
--ee-cycle-scalar=0.78
</pre>


CUSA06584
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
<br>LUA
<pre>
apiRequest (1.7)


local eeObj = getEEObject()
apiRequest(0.2) -- request version 0.2 API for throttling control.
local gpr = require("ee-gpr-alias")


-- 00107be0 <syncV>: idle loop on vsync
local eeObj = getEEObject()
eeNativeHook (0x107c14, 0x3c03005d,"FastForwardClock", 0)
local emuObj = getEmuObject()


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...
local TH1A = -- start of main()
eeObj.AddHook(0x3ce0fc, 0x0200202d, function()
function()
local sign = (eeObj.GetGpr(gpr.v1) >> 31) & 1
emuObj.ThrottleMax()
if sign then
end
eeObj.SetPc(0x3ce118)
end
end)


local TH1B = -- init loading screen
function()
local mode = eeObj.GetGpr(gpr.a0)


</pre>
if mode ~= 4 then -- not sure what mode 4 is, but doesn't precede a real loading
====Jak 3====
emuObj.ThrottleMax()
'''CLI'''
end
<br>SCUS-97330
end
<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
--gs-adaptive-frameskip=1
</pre>
'''LUA'''
<br>SCUS-97330
<pre>
apiRequest(2.3)


local gpr    = require("ee-gpr-alias")
local TH1C = -- advance progress bar
local emuObj = getEmuObject()
function()
local eeObj = getEEObject()
local pct = eeObj.GetFpr(2)
local gsObj = getGsObject()
local eeOverlay = eeObj.getOverlayObject()


-- Fix shadow
if pct >= 1.0 then
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1  } )
emuObj.ThrottleNorm()
end
end


-- 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 } )


-- register hooks


-- All JAK titles have a silly way of obtaining the PS2 Timestamp Counter. A binary code snippet is written
local registeredHooks = {}
-- 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:
maxpayne_features_unregisterHooks = function() -- global function (called by trophy_data)
eeInsnReplace(0x108a78, 0x8c629790, 0x40024800) -- lw     v0,-26736(v1) -> mfc0      $v0,$count
for _, hook in pairs(registeredHooks) do
eeInsnReplace(0x108a7c, 0x0040f809, 0x00000000) --  jalr v0          -> jr        $ra
eeObj.RemoveHook(hook)
eeInsnReplace(0x108c80, 0x8c629790, 0x40024800) --  lw     v0,-26736(v1) -> mfc0      $v0,$count
end
eeInsnReplace(0x108c84, 0x0040f809, 0x00000000) --  jalr v0          -> jr        $ra
eeInsnReplace(0x108ea4, 0x8c629790, 0x40024800) --  lw     v0,-26736(v1) -> mfc0      $v0,$count
registeredHooks = {}
eeInsnReplace(0x108ea8, 0x0040f809, 0x00000000) --  jalr v0          -> jr        $ra
eeInsnReplace(0x10902c, 0x8c629790, 0x40024800) --  lw     v0,-26736(v1) -> mfc0      $v0,$count
eeInsnReplace(0x109030, 0x0040f809, 0x00000000) --  jalr v0          -> jr        $ra
 
-- ------------------------- OVERLAY MANAGER --------------------------
g_OnOverlayRegistered = function(filename, start, size)
-- global function provided for adding per-overlay callback handlers.
end
end


local DH8 = function()
maxpayne_features_registerHooks = function() -- global function (called by trophy_data)
local s1 = eeObj.GetGpr    (gpr.s1)
registeredHooks = {
local filename = eeObj.ReadMemStr(s1 + 17)
eeObj.AddHook(0x133dc8, 0x24030001, TH1A), -- <main>:
local segment = eeObj.ReadMem32 (s1 +  8)
eeObj.AddHook(0x15ed7c, 0x24030003, TH1B), -- <MaxPayne_GameMode::initLoadingScreen(void)>:
local main = eeObj.ReadMem32 (segment +  4)
eeObj.AddHook(0x133078, 0xc4a20000, TH1C), -- <UpdateProgressBarKH(void)>:
local mainSize = eeObj.ReadMem32 (segment +  8)
}
local top = eeObj.ReadMem32 (segment + 36)
end</pre>
local topSize = eeObj.ReadMem32 (segment + 40)


if emuObj.IsToolingVerbose() then
====Metal Slug Anthology====
print( string.format("--> LOADED SEGMENT \"%s\" MAIN %08x size %x TOP %08x size %x", filename, main, mainSize, top, topSize) )
ALL
end
<br>CLI
<pre>--host-audio-latency=0.010
--gs-upscale=point
--gs-uprender=none
#fix for graphical glitches.</pre>


eeOverlay.Register(filename .. ".main", main, mainSize, false)
SLUS_215.50
eeOverlay.Register(filename .. ".top",  top,  topSize,  true )
<br>LUA
<pre>
-- Metal Slug Anthology PS2 - SLUS-21550 (USA)


--local debugObj = getDebugObject()
apiRequest(1.2) -- request version 0.1 API. Calling apiRequest() is mandatory.
--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
local eeObj = getEEObject()
-- Make sure to execute any previously registered OnOverlay handler
local emuObj = getEmuObject()
g_OnOverlayRegistered(filename .. ".main", main, mainSize)
g_OnOverlayRegistered(filename .. ".top",  top,  topSize )
end


end
-- Fix for black screen booting an elf. This is a game bug.
-- The v1.0 of the game suffered from an intermittent bug on the real PS2
-- where sometimes it would hang on a black screen trying to launch a new elf.
-- This is apparently due to a bad IOP state, which caused sceCdInit to hang.
-- Later versions of the game (1.1, 1.2) attempted to fix this in different ways.
-- On Olympus, v1.0 (USA) hangs always, while v1.2 (EUR/JPN) works always.
-- The fix implemented here replaces a call to FlushCache() to loadImageAndReboot(),
-- which is a function that reboots the IOP and resolves the hang.


eeObj.AddHook(0x1091d4, 0x0080c825, DH8)   --     <ndi::link_control::finish(void)>:
eeInsnReplace(0x189c24, 0x0c08f7f8, 0x0c061dd2) -- FlushCache() -> loadImageAndReboot()
eeInsnReplace(0x117804, 0x0c0c1e08, 0x0c045e20) -- FlushCache() -> loadImageAndReboot()
</pre>


-- --------------------------------------------------------------------
====Okage====
assert(g_OnOverlayRegistered ~= nil)
'''TXT'''
local prev_OnOverlayRegistered = g_OnOverlayRegistered
<br>SCUS-97129
<pre>
--vu1-mpg-cycles=50
--vu1-mpg-cycles=850,$037,$7b3
--vu1-mpg-cycles=150,$2b4,$7c4
</pre>
'''LUA'''
<br>SCUS-97129
<pre>
require("ee-gpr-alias")
require("ps2")
apiRequest(0.6) -- request version 0.1 API. Calling apiRequest() is mandatory.


g_OnOverlayRegistered = function(filename, start, size)
local eeObj = getEEObject()
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
-- bug#8740
-- this RNG-sqrt instance is removed for performance. Additionally, not corrupting the RNG seed with
-- SPSetDirect(addr, char-pos, char-pos, x-coord, y-coord, width, height)
-- bad sqrt math is always a good thing in my book --jstine
-- reduce width just 1 pix.
local Replace_1a1fb0 = InsnOverlay( {
0x0806720a, --        j      0x19c828
0x2529ffff, --       addiu  t1,t1,-1
})
eeInsnReplace(0x1a1fb0, 0x0c06720a, 0x0c000000 | (Replace_1a1fb0>>2)) -- jal 19c828 <SPSetDirect>


assert(eeObj.ReadMem32(start + 0x005de4) == 0x4be1043d) -- vrget.wxyz  vf01,r
</pre>
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
====Parappa the Rapper 2====
assert(eeObj.ReadMem32(start + 0x005ef8) == 0x4a00143f) -- vrxor        r,vf02x
ALL
assert(eeObj.ReadMem32(start + 0x005f80) == 0x4a00143f) -- vrxor        r,vf02x
<br>CLI
assert(eeObj.ReadMem32(start + 0x006018) == 0x4a00143f) -- vrxor        r,vf02x
<pre>--host-audio-latency=0.01
 
#fix for audio off sync.</pre>
 
SCUS_971.67
<br>LUA
<pre>


eeObj.WriteMem32(start + 0x005de4, 0x00000000)
-- Parappa the Rapper 2  [SCUS-97167]
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


-- --------------------------------------------------------------------------------------
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
-- 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()
require( "ee-gpr-alias" )
-- local v1 = eeObj.GetGpr(gpr.v1)
require( "ee-hwaddr" )
-- print(string.format("fpuCompare fpr0=%f fpr30=%f", eeObj.GetFpr(0), eeObj.GetFpr(30)))
-- end)
-- --------------------------------------------------------------------------------------
</pre>


====Jak 2====
local eeObj = getEEObject()
'''CLI'''
<br>SCUS-97265
<pre>
--ee-jit-pagefault-threshold=20
--gs-frontend-opt-mode=1
--gs-use-mipmap=1
--gs-kernel-cl="mipmap"
--gs-kernel-cl-up="mipmap2x2"
--cop2-no-clamping=1
--cop2-clamp-range=0x2A18,0x2a20,joint.seg1
--vu1-mpg-cycles=250
</pre>
'''LUA'''
<br>SCUS-97265
<pre>
apiRequest(2.2)


local gpr    = require("ee-gpr-alias")
-- ================================================================================================
local emuObj = getEmuObject()
-- Title issues racy combination of VIF1 and GIF transfers.  It expects GIF to finish ahead of VU
local eeObj = getEEObject()
-- XGKICK (via VIF1), which is atypical among PS2 titles (XGKICK has HW priority over GIF, and so
local eeOverlay = eeObj.getOverlayObject()
-- GIF can only finish ahead of XGKICK in certain extreme cases).
local iopObj    = getIOPObject()
--
local gsObj = getGsObject()
-- Fixed by delaying the specific VIF1 transfer (identified by MADR) for a long time to ensure GIF
-- gains arbitration and finishes ahead of XGKICKs.
--
local fix01_dma_vif1 =  
function()
local ee = eeObj
local tgtaddr = ee.GetGpr(gpr.s0)


-- print( string.format("success pt.1 : %x %x", vif1_hw.CHCR, tgtaddr ) )


-- Fix shadow
if tgtaddr == vif1_hw.CHCR then
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1  } )


-- Reduce flush count
-- expected:
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1  } )
--  # DIR==1 and MOD==1  (chain)
--  # TADR==0x01C76AA0


---------------------------------------------------------------------------------
local chcr = ee.GetGPR(gpr.v0)
-- Basic Block breakers for EE AOT Injection
eeOverlay.AddPreHook("traffic-engine.seg1", 0x004474, 0x0080e025, "nop" )
eeOverlay.AddPreHook("spatial-hash.seg1", 0x004474, 0x0080e025, "nop" )


---------------------------------------------------------------------------------
if (chcr & 0x05) == 0x05 then
local tadr = ee.ReadMem32(vif1_hw.TADR);
if tadr == 0x01C76AA0 then
-- 0x6000 works fine, 0x6500 adds a little extra cushion.
ee.SchedulerDelayEvent("vif1.dma", 0x6500)
-- print( "Parappa fix applied!" )
end
end
end
end
-- ================================================================================================


-- ------------------------- OVERLAY MANAGER --------------------------
eeObj.AddHook(0x0015A008, 0xAE020000, fix01_dma_vif1)
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)
-- Our emulator has accuracy problems on so many places. In this title, we have problems on VU.
-- To be accurate on VU is quite painful (we won't be able to get reasonable performance with it)
local linkblock = eeObj.ReadMem32(s0+0x60) -- was 0x5c on Jak1
-- So as workaround, we just disable bilinear textures on Render-To-Texture drawing.
-- Bug#8122
--print( string.format("--> PRELOAD %08x %08x",s0, linkblock) )
eeInsnReplace(0x118084, 0xde260008, 0x24060000) -- ld a2,8(s1)
eeInsnReplace(0x118798, 0xde260008, 0x24060000) -- ld a2,8(s1)
local linkblock_allocate_length = eeObj.ReadMem32 (linkblock + 0x00)
eeInsnReplace(0x118868, 0xde660008, 0x24060000) -- ld a2,8(s3)
local linkblock_allocate_version = eeObj.ReadMem32 (linkblock + 0x04)
eeInsnReplace(0x119d18, 0xdc460008, 0x24060000) -- ld a2,8(v0)
local linkblock_allocate_segment_count = eeObj.ReadMem32 (linkblock + 0x08)
eeInsnReplace(0x119d18, 0xdc460008, 0x24060000) -- ld a2,8(v0)
local linkblock_allocate_name = eeObj.ReadMemStr(linkblock + 0x0c)
local linkblock_allocate_seg1_linkptr = eeObj.ReadMem32 (linkblock + 0x4C)
local linkblock_allocate_seg1_dataptr = eeObj.ReadMem32 (linkblock + 0x50)
local linkblock_allocate_seg1_size = eeObj.ReadMem32 (linkblock + 0x54)
local linkblock_allocate_seg1_flags = eeObj.ReadMem32 (linkblock + 0x58)
                                                             
local linkblock_allocate_seg2_linkptr = eeObj.ReadMem32 (linkblock + 0x5C)
local linkblock_allocate_seg2_dataptr = eeObj.ReadMem32 (linkblock + 0x60)
local linkblock_allocate_seg2_size = eeObj.ReadMem32 (linkblock + 0x64)
local linkblock_allocate_seg2_flags = eeObj.ReadMem32 (linkblock + 0x68)
                                                             
local linkblock_allocate_seg3_linkptr = eeObj.ReadMem32 (linkblock + 0x6C)
local linkblock_allocate_seg3_dataptr = eeObj.ReadMem32 (linkblock + 0x70)
local linkblock_allocate_seg3_size = eeObj.ReadMem32 (linkblock + 0x74)
local linkblock_allocate_seg3_flags = eeObj.ReadMem32 (linkblock + 0x78)
-- seg1 is equiv to main in Jak3
-- seg3 is equiv to top  in Jak3
-- seg2 appears to be unused ... ?  --jstine (it's a debug segment, so likely unused on retail) DH


if emuObj.IsToolingVerbose() then
</pre>
print( string.format("--> LOADED SEGMENT alloc_len %08x ver %08x segcount %08x  name:\"%s\"", linkblock_allocate_length, linkblock_allocate_version, linkblock_allocate_segment_count, linkblock_allocate_name) )
print( string.format("    seg1linkptr %08x seg1dataptr %08x seg1size %08x seg1flags %08x", linkblock_allocate_seg1_linkptr, linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, linkblock_allocate_seg1_flags) )
print( string.format("    seg2linkptr %08x seg2dataptr %08x seg2size %08x seg2flags %08x", linkblock_allocate_seg2_linkptr, linkblock_allocate_seg2_dataptr, linkblock_allocate_seg2_size, linkblock_allocate_seg2_flags) )
print( string.format("    seg3linkptr %08x seg3dataptr %08x seg3size %08x seg3flags %08x", linkblock_allocate_seg3_linkptr, linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, linkblock_allocate_seg3_flags) )
end


-- local debugObj = getDebugObject()
====Primal====
-- debugObj.eDumpDisasmToFile("./DisasmGoal/JakII/" .. linkblock_allocate_name .. ".seg1.dasm", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, 0)
CLI
-- debugObj.eDumpDisasmToFile("./DisasmGoal/JakII/" .. linkblock_allocate_name .. ".seg3.dasm", linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, 0)
<pre>
-- debugObj.eDumpAotToFile  ("./DisasmGoal/JakII/" .. linkblock_allocate_name .. ".seg1.aot", linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, 0)
--vu1-mul0fix-range=0x22f,0x22f
-- debugObj.eDumpAotToFile  ("./DisasmGoal/JakII/" .. linkblock_allocate_name .. ".seg3.aot",  linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, 0)
--vu1-mul0fix-range=0x298,0x29c
--vu1-native-patch=1
--ee-hook=0x2f76c0,FastForwardClock,0x1200ffbf
--vu1-mpg-cycles=700
--gs-kernel-cl-up="up2x2Simple"
--cop2-no-clamp-range=0x37bd78,0x37c514    ;; CMatrix functions         
--cop2-no-clamp-range=0x38c0e0,0x38c174    ;; CModel::CalcSkinningMatrices
--cop2-no-clamp-range=0x391cf0,0x392084    ;; CSkelton::Update           
</pre>


if linkblock_allocate_seg1_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg1",  linkblock_allocate_seg1_dataptr, linkblock_allocate_seg1_size, false) end
LUA
if linkblock_allocate_seg3_size ~= 0 then eeOverlay.Register(linkblock_allocate_name .. ".seg3",  linkblock_allocate_seg3_dataptr, linkblock_allocate_seg3_size, true) end
<pre>
-- Primal [EU]


if (g_OnOverlayRegistered ~= nil) then
apiRequest(1.1)
-- 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 eeObj = getEEObject()
local prev_OnOverlayRegistered = g_OnOverlayRegistered
local emuObj = getEmuObject()
 
-- Bug 9094 - Title exhibits poor performance due to VU0 spin loops.
-- The spin loops are meant to be an optimizaion on PS2 and the best way of handling them is
-- to remove them from the original code.  This can be done since the VF09 register is unsed by
-- the first portion of the VU0 mpg.
--
-- Insn replacements Summarized:
--  1. NOP the spin loop from VU0.
--  2. NOP the setup code for VI05, which is the reg tested by the VU0 spin loop
--  3. Reorder the vcallms and qmtc2.


g_OnOverlayRegistered = function(filename, start, size)
if (prev_OnOverlayRegistered ~= nil) then
-- Make sure to execute any previously registered OnOverlay handler
prev_OnOverlayRegistered(filename, start, size)
end


if filename == "sparticle-launcher.seg1" then
-- [$167:520507ff] IBNE vi05, vi00, [$167]
-- this RNG-sqrt instance is removed for performance.  Additionally, not corrupting the RNG seed with
-- [$167:000002ff] NOP
-- bad sqrt math is always a good thing in my book --jstine
local orig = (0x000002ff << 32) | 0x520507ff


assert(eeObj.ReadMem32(start + 0x0044ec) == 0x4be1043d) -- vrget.wxyz  vf01,r
vuInsnReplace(0, 0x167, orig, 0x8000033c | (0x000002ff << 32)) -- NOP / NOP2
assert(eeObj.ReadMem32(start + 0x0044f0) == 0x4a0103bd) -- vsqrt        q,vf01x
vuInsnReplace(0, 0x172, orig, 0x8000033c | (0x000002ff << 32)) -- NOP / NOP2
assert(eeObj.ReadMem32(start + 0x0044f8) == 0x4b0000a0) -- vaddq.x      vf02,vf00,q


assert(eeObj.ReadMem32(start + 0x00454c) == 0x4a00143f) -- vrxor        r,vf02x
local region_base = 0x399c5c
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)
eeInsnReplace(region_base + 0x000, 0x24040001, 0x00000000)  -- li a0,1 -> NOP
eeObj.WriteMem32(start + 0x0044f0, 0x00000000)
eeInsnReplace(region_base + 0x010, 0x48c42800, 0x00000000)   -- ctc2.ni a0,$5      -> NOP
eeObj.WriteMem32(start + 0x0044f8, 0x00000000)
eeInsnReplace(region_base + 0x090, 0x24040001, 0x00000000)   -- li a0,1            -> NOP
eeInsnReplace(region_base + 0x0a0, 0x48c42800, 0x00000000)   -- ctc2.ni a0,$5      -> NOP


eeObj.WriteMem32(start + 0x00454c, 0x00000000)
eeInsnReplace(region_base + 0x05c, 0x48c02800, 0x00000000) -- ctc2.ni zero,$5 -> NOP
eeObj.WriteMem32(start + 0x0045f8, 0x00000000)
eeInsnReplace(region_base + 0x114, 0x48c02800, 0x00000000) -- ctc2.ni zero,$5 -> NOP
eeObj.WriteMem32(start + 0x004680, 0x00000000)
eeObj.WriteMem32(start + 0x004718, 0x00000000)
end
end


-- hooked in link_control::finish(void)>:
eeInsnReplace(region_base + 0x054,  0x4a00d839, 0x48a44800) -- vcallmsr vi27 -> qmtc2 a0,vf9
function install_c_hooks(offset)
eeInsnReplace(region_base + 0x058,  0x48a44800, 0x4a00d839) -- qmtc2 a0,vf9 -> vcallmsr vi27
eeObj.AddHook(0x1085a0 + offset , 0x0080c825, DH8)  
eeInsnReplace(region_base + 0x10c, 0x4a00d839, 0x48a44800) -- vcallmsr vi27 -> qmtc2 a0,vf9
end
eeInsnReplace(region_base + 0x110, 0x48a44800, 0x4a00d839) -- qmtc2 a0,vf9 -> vcallmsr vi27


-- remove heat haze distortion ( for performance reason Bug#8827 )
--  reg = 0x42  packedFlags = 3( iip, tme, fst)  packedPrim  = 5(SCE_GS_PRIM_TRIFAN)
emuObj.SetGsTitleFix( "globalSet",  "reserved", { packedRegsLo = 0x42,packedRegsHi = 0, packedRegsNum = 2, packedFlags = 3, packedPrim = 5})
emuObj.SetGsTitleFix( "skipPacked", "reserved", { alpha = 0x80000044, tbp = 0x3a4000 , zmsk=1 })
emuObj.SetGsTitleFix( "skipPacked", "reserved", { alpha = 0x80000044, tbp = 0x348000 , zmsk=1 })


local Ready = 0


local DetectFunc = function()
-- NOP out cacheline prefetch instructions.
if Ready == 0 then
-- Prefetch might have been a good idea on PS2, but it is entirely unhelpful on the PS4 target.
if 1 then  
local discID = eeObj.ReadMemStr(0x0012fc8)
eeInsnReplace(0x381e60, 0x78400040, 0x00000000) -- lq zero,64(v0)
eeInsnReplace(0x3822c0, 0x78400040, 0x00000000) -- lq zero,64(v0)
if (discID ~= "") then
eeInsnReplace(0x38ec7c, 0x78800040, 0x00000000) -- lq zero,64(a0)
eeInsnReplace(0x38ed78, 0x78600040, 0x00000000) -- lq zero,64(v1)
if (discID == "cdrom0:\\SCUS_972.65;1") or (discID == "cdrom0:\\SCPS_150.57;1") then
eeInsnReplace(0x38eec0, 0x78a00040, 0x00000000) -- lq zero,64(a1)
-- US or Japan Disc
eeInsnReplace(0x38fe28, 0x7a600040, 0x00000000) -- lq zero,64(s3)
Ready = 1
eeInsnReplace(0x38fea4, 0x78800040, 0x00000000) -- lq zero,64(a0)
install_c_hooks(0)
eeInsnReplace(0x390da8, 0x78400040, 0x00000000) -- lq zero,64(v0)
eeInsnReplace(0x391020, 0x78400040, 0x00000000) -- lq zero,64(v0)
print( string.format("********************* DETECTED USA, JAPAN DISC ********************" ) )
eeInsnReplace(0x391174, 0x78a00040, 0x00000000) -- lq zero,64(a1)
eeInsnReplace(0x3912b0, 0x78a00040, 0x00000000) -- lq zero,64(a1)
elseif (discID == "cdrom0:\\SCKA_200.10;1") then
eeInsnReplace(0x398790, 0x7a000040, 0x00000000) -- lq zero,64(s0)
Ready = 1
eeInsnReplace(0x399e60, 0x78400050, 0x00000000) -- lq zero,80(v0)
install_c_hooks(0x08)
eeInsnReplace(0x399ee8, 0x78400050, 0x00000000) -- lq zero,80(v0)
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)
-- NOP out an idle loop meant to flush some cache lines...
</pre>
if 1 then
 
eeInsnReplace(0x331038, 0x18a00009, 0x00000000) -- blez a1,331060 <CDMAStreamIterator::AllocateBlock(unsigned int)+0x110>
====Jak X====
eeInsnReplace(0x33103c, 0x00d41821, 0x00000000) -- addu v1,a2,s4
'''CLI'''
eeInsnReplace(0x331040, 0xbc5a0000, 0x00000000) -- cache 0x1a,0(v0)
<br>SCUS-97429
eeInsnReplace(0x331044, 0x24a5ffff, 0x00000000) -- addiu a1,a1,-1
<pre>
eeInsnReplace(0x331054, 0x1ca0fffa, 0x00000000) -- bgtz a1,331040 <CDMAStreamIterator::AllocateBlock(unsigned int)+0xf0>
--ee-jit-pagefault-threshold=30
eeInsnReplace(0x331058, 0x24420040, 0x00000000) -- addiu v0,v0,64
--gs-frontend-opt-mode=1
end
--gs-use-mipmap=1
 
--gs-kernel-cl="mipmap"
-- perf. fix bug 9094
--gs-kernel-cl-up="mipmap2x2"
emuObj.SetGsTitleFix( "globalSet", "reserved", {ignoreUpRenderTimeout=2} )
--cop2-no-clamping=1
emuObj.SetGsTitleFix( "ignoreUpRender",  230, {} )
--vu1-mpg-cycles=250
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { alpha=0x00000000 } )
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { alpha=0x80000048 } )
 
</pre>
</pre>


'''LUA'''
====Red Dead Revolver====
<br>SCUS-97429
<br>SLUS-20500
<br>CLI
<pre>
<pre>
-- Jak X Combat Racing  [US]
--gs-kernel-cl-up="up2x2skipInterp"
 
--fpu-rsqrt-fast-estimate=0
apiRequest(2.2)
--mtap1=Always
 
--vif1-ignore-cmd-ints=1
local gpr = require("ee-gpr-alias")
--iop-cycle-scalar=0.80
local eeObj = getEEObject()
--iop-hook=0x0086ac,FastForwardClock
local emuObj = getEmuObject()
--ee-sif0-cycle-scalar=2.0
local gsObj = getGsObject()
--ee-sif1-cycle-scalar=2.0
local eeOverlay = eeObj.getOverlayObject()
--iop-sif1-cycle-scalar=5.0
--iop-sif0-cycle-scalar=5.0
--iop-tight-slice-count=12
--cdvd-sector-read-cycles=5000
--ee-hook=0x352dd0,AdvanceClock,0x0c0ef9a2,4500
--ee-hook=0x3b5068,FastForwardClock,0x00481024
--ee-hook=0x46fb68,FastForwardClock,0x8ca30000
--ee-hook=0x46fb38,FastForwardClock,0x8c620000
--ee-hook=0x46fb68,MfifoDrain,0x8ca30000
--ee-hook=0x46fb38,MfifoDrain,0x8c620000
--mfifo-manual-drain=0.30
--mfifo-chunk-drain-cycles=210000
</pre>
<br>SLUS-20500
<br>LUA
<pre>
-- red_dead_revolver
local gpr = require("ee-gpr-alias")


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


-- Bug 10697
-- Bug 9309
emuObj.SetGsTitleFix( "ignoreSubBuffCov", "reserved", { texMode=2 , tw=6 , th=5} )
local emuObj = getEmuObject()
-- psm= SCE_GS_PSMCT32 (0)
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", {psm=0} )
emuObj.SetGsTitleFix( "fetchFromCurrBuff", "reserved", {psm=0} )


-- Fix shadow
-- bug#9490 - Disable post-processing effect - <imgImageryDeriver<fxDistort>::Draw(void)>
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", { texMode=1  } )
eeInsnReplace(0x4c4b78, 0x27bdfff0, 0x03e00008) -- JR $ra
eeInsnReplace(0x4c4b7c, 0xffbf0000, 0x00000000) -- NOP


-- Reduce flush count
-- gfxState class writes bytes and then reads them back as words later on.
emuObj.SetGsTitleFix( "SetSelfRender", "reserved", { fbmask= 0x00FFFFFF , renderSelf=1 , zmsk=1 , alpha=0 , texMode=1 } )
-- This replaces most of the word readbacks with lbu equivalents to avoid STLF.
-- 003c0950 <gfxState::Update_TEST(void)>:
eeInsnReplace(0x3c0970, 0x8ce6efd8, 0x90e6efd8) -- lw a2,-4136(a3)
eeInsnReplace(0x3c09a0, 0x8ce3f37c, 0x90e3f37c) -- lw v1,-3204(a3)
 
-- 0032aa70 <fxFloatPropGrid::Get(Vector2 const &) const>:
--  The original  compiler couldn't assume that Vector2 was an aligned object, so it generated
--    ldr/sdr instructions to access it. The lack of assumption seems to have also caused it to
--    spill FPU registers to memory needlessly.


-- ------------------------- OVERLAY MANAGER --------------------------
if true then
g_OnOverlayRegistered = function(filename, start, size)
eeInsnReplace(0x32aa74, 0x68a20007, 0x00000000)
-- global function provided for adding per-overlay callback handlers.
eeInsnReplace(0x32aa78, 0x6ca20000, 0x00000000)
-- See code for bug#10141 below, as example of this usage.
eeInsnReplace(0x32aa7c, 0xb3a20017, 0xc4a00000) -- lwc1 $f0,0(a1)
end
eeInsnReplace(0x32aa80, 0xb7a20010, 0xc4a10004) -- lwc1 $f1,4(a1)


-- -- this hooks at the moment of loading the relocatable code and patch it only on the target segment.
eeInsnReplace(0x32aa8c, 0xc7a00010, 0x00000000) -- nop
eeObj.AddHook(0x0026ff90, 0x03207825, function()
eeInsnReplace(0x32aa9c, 0xc7a10014, 0x00000000) -- nop
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
eeInsnReplace(0x32aaa8, 0xe7a00010, 0x00000000) -- nop
print(string.format("LOAD SEGMENT \"%s\" MAIN %08x size %x TOP %08x size %x",
eeInsnReplace(0x32aaac, 0x46020082, 0x46020002) -- mul.s $f0,$f0,$f2 
filename, main, mainSize, top, topSize))
eeInsnReplace(0x32aab0, 0x3c014480, 0x3c014480) -- lui at,0x4480
end
eeInsnReplace(0x32aab4, 0x34211000, 0x34211000) -- ori at,at,0x1000
eeInsnReplace(0x32aab8, 0x44812000, 0x44812000) -- mtc1 at,$f4
eeOverlay.Register(filename .. ".main", main, mainSize, false)
eeInsnReplace(0x32aabc, 0xe7a10014, 0x00000000) -- nop
eeOverlay.Register(filename .. ".top", top, topSize, true )
eeInsnReplace(0x32aac0, 0x460308c2, 0x46030842) -- mul.s $f1,$f1,$f3
eeInsnReplace(0x32aac4, 0xe7a20010, 0xe7a00000) -- swc1 $f0,0(sp)
eeInsnReplace(0x32aac8, 0x90a4001c, 0x90a4001c) -- lbu $a0,28($a1)
eeInsnReplace(0x32aacc, 0xe7a30014, 0xe7a10004) -- swc1 $f1,4(sp)
 
eeInsnReplace(0x32aad0, 0x6baa0017, 0x00000000) -- nop
eeInsnReplace(0x32aad4, 0x6faa0010, 0x00000000) -- nop
eeInsnReplace(0x32aad8, 0xb3aa0007, 0x00000000) -- nop
eeInsnReplace(0x32aadc, 0xb7aa0000, 0x00000000) -- nop
eeInsnReplace(0x32aae0, 0xc7a00000, 0x00000000) -- nop
eeInsnReplace(0x32aae4, 0xc7a10004, 0x00000000) -- nop
end


if (g_OnOverlayRegistered ~= nil) then
</pre>
-- Make sure to execute any previously registered OnOverlay handler
<br>Features.lua
g_OnOverlayRegistered(filename .. ".main", main, mainSize)
<br>SLUS-20500
g_OnOverlayRegistered(filename .. ".top", top, topSize )
<br>Even though it's features.lua, it's still a very good example for learning
end
<pre>
end)
-- Lua 5.3
-- Title: Red Dead Revolver - SLUS-20500 (USA) v1.03
-- Author: Nicola Salmoria
-- Date: March 23, 2016




-- ---------------------------------------------------------------------------------
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
-- 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:
apiRequest(0.7) -- need widescreen support
--
-- 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 eeObj = getEEObject()
local prev_OnOverlayRegistered = g_OnOverlayRegistered
local emuObj = getEmuObject()


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
local GFXPIPELINE_16BY9_ADDRESS = 0x79eeec
-- the problem is actually on a block 0x013090bc - 0x01309188.
local GLOBALS_UNIVERSALDATA_ADDRESS = 0x742120
-- 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
local TH1A = -- start loading screen
if filename == "lobby-menu-manager.main" then
function()
local adr    = start + 0x1224
emuObj.ThrottleMax()
assert (eeObj.ReadMem32(adr) == 0x1000012f)
eeObj.WriteMem32(adr, 0)
end
end
 
-- bug#10720 - title has a bugged RNG which does an SQRT of the current seed and xor the
local TH1B = -- switch to threaded loading (over cutscene etc.)
-- result back into the seed.  This breaks the prime factorial pattern of the RNG and causes
function()
-- it to fall into a repeating loop with disturbing regularity.  NOP'ing out the sqrt/xor
emuObj.ThrottleNorm()
-- 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)
local TH2A = -- start flashing loading message
eeObj.WriteMem32(start + 0x006310, 0x00000000)
function()
eeObj.WriteMem32(start + 0x006318, 0x00000000)
emuObj.ThrottleMax()
eeObj.WriteMem32(start + 0x006370, 0x00000000)
end
eeObj.WriteMem32(start + 0x0063fc, 0x00000000)
 
eeObj.WriteMem32(start + 0x006484, 0x00000000)
local TH2B = -- pause loading message
eeObj.WriteMem32(start + 0x00651c, 0x00000000)
function()
emuObj.ThrottleNorm()
end
end
end
-- ---------------------------------------------------------------------------------


</pre>
local TH2C = -- unpause loading message
function()
emuObj.ThrottleMax()
end


====Kinetica====
local TH2D = -- end loading message
'''CLI'''
function()
<br>SCUS-97132
emuObj.ThrottleNorm()
<pre>
end
--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 showdownLoading = false
-- local iopObj = getIOPObject()
-- iopObj.AddHook(0x000135ac, 0x27bdffe0, DebugHooks.h_IOP_ioman_write)


-- bug#8123
local TH3A = -- draw "Loading" on Showdown info screen
-- Skip resetting VAG stream which happens on an error.
function()
iopInsnReplace(0x00090028, 0x16220009, 0x08024014) -- bne $s1,$v0,0x00090050 => j 0x00090050
if showdownLoading == false then
emuObj.ThrottleMax()
showdownLoading = true
end
end


-- bug#9405 - advance EE clock according to spinning-loop SIF activity.
local TH3B = -- draw "Press START" on Showdown info screen
function()
local skip_syncDCache = function()
if showdownLoading == true then
-- Original value when actually processing syncDCache was 3300
emuObj.ThrottleNorm()
-- Boosting to 8000 helps reduce bottleneck
showdownLoading = false
eeObj.AdvanceClock(8000)
end
end
end


eeInsnReplace(0x1ca9e0, 0x27bdffe0, 0x03e00008)
eeInsnReplace(0x1ca9e4, 0x0080302d, 0x00000000)
eeObj.AddHookJT(0x1ca9e0, 0x03e00008, skip_syncDCache)


-- gametime to be from realtim....
local WH1 = -- update 16:9 flag
-- # this causes the time elapses even while in pause. so bugged
function()
-- # also maybe this causes 'negative' race time as well.
local isWidescreen = eeObj.GetGpr(gpr.a0)
-- we should be OK even without this because skipping frame works (mostly).
--
if isWidescreen == 0 then
-- local prevtime = 0.0
emuObj.SetDisplayAspectNormal()
-- eeObj.AddHook(0x12350c, 0x27bdfec0, function()
else
-- local curtime = os.clock()
emuObj.SetDisplayAspectWide()
-- if prevtime ~= 0.0 then
end
-- eeObj.WriteMemFloat(eeObj.GetGpr(gpr.gp)-31776, curtime - prevtime)
end
-- end
-- prevtime = curtime
-- end)


-- to work skipping frame mechanism correctly...
local WH2 = -- init universal data
-- the game checks a flag set by INTC GS whether GS still does his job or not to
function()
-- determine whether it should skip a frame or not.
local v1 = eeObj.GetGpr(gpr.v1)
-- Unfortunately we don't have the actual timing of GS FINISH signal.
eeObj.SetGpr(gpr.v1, v1 | 1) -- enable widescreen
-- Instead of that, we check EE clock to determine to skip or not.
end


local ee_frequency = 294912000
local WH3 = -- end of boot up sequence
local vsync_frequency = 59.94 -- use interlace freq.  
function()
local universalData = eeObj.ReadMem32(GLOBALS_UNIVERSALDATA_ADDRESS)
local isWidescreen = eeObj.ReadMem32(universalData + 92) & 1


local one_vsync_clock_on_ntsc = math.floor(ee_frequency / vsync_frequency)
eeObj.WriteMem8(GFXPIPELINE_16BY9_ADDRESS, isWidescreen)
 
if isWidescreen == 0 then
emuObj.SetDisplayAspectNormal()
else
emuObj.SetDisplayAspectWide()
end
end




-- 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()
-- unthrottle loading screens
-- It hits here when it skips a frame.
local thr1a = eeObj.AddHook(0x21e02c, 0x0080982d, TH1A) -- <staNewLoadShow::Enter(void)>:
--local diff = eeObj.GetClock() - prev_clock
local thr1b = eeObj.AddHook(0x220100, 0x27bdfff0, TH1B) -- <staNewLoadShow::DoThreadedLoadShow(void)>:
local thr2a = eeObj.AddHook(0x233970, 0x27bdfff0, TH2A) -- <ThreadedLoadingMessage::Start(void)>:
local clock = eeObj.GetClock()
local thr2b = eeObj.AddHook(0x233a30, 0x27bdfff0, TH2B) -- <ThreadedLoadingMessage::Pause(void)>:
--local diff  = clock - expected_clock
local thr2c = eeObj.AddHook(0x233a80, 0x3c02004f, TH2C) -- <ThreadedLoadingMessage::Unpause(void)>:
--print(string.format("SKIP FRAME: diff=%7d", diff))
local thr2d = eeObj.AddHook(0x2339d8, 0x27bdfff0, TH2D) -- <ThreadedLoadingMessage::Stop(void)>:
local thr3a = eeObj.AddHook(0x226110, 0x8e850008, TH3A) -- <staNewLoadShow::DrawMultiplayerInfo(void)>:
local thr3b = eeObj.AddHook(0x226058, 0x8e650008, TH3B) -- <staNewLoadShow::DrawMultiplayerInfo(void)>:


--prev_clock    = eeObj.GetClock() -- just update the clock.
-- widescreen support
expected_clock = expected_clock + one_vsync_clock_on_ntsc
local wide1 = eeObj.AddHook(0x3b9050, 0x46010003, WH1) -- <gfxPipeline::Set16By9(bool)>:
end)
local wide2 = eeObj.AddHook(0x180f90, 0x00641824, WH2) -- <swcSaveUniversalData::swcSaveUniversalData(void)>:
eeObj.AddHook(0x18202c, 0x8f84bf54, function()
local wide3 = eeObj.AddHook(0x102b70, 0x24040003, WH3) -- <gmGame::DoBootUpSequence(void)>:
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)


</pre>


-- Applies a cycle rate hack to what I presume is the game logic pipeline, for roughly per-frame updates.
====Psychonauts====
 
SLUS_211.20
local mpgCycles_default = 900
<br>CLI
local currentMpgCycles = mpgCycles_default
<pre>--vu1-jr-cache-policy=sameprog
 
--vu1-jalr-cache-policy=sameprog
local checkNeedsSpeedHack = function()
--ee-hook=0x101fc0,FastForwardClock,0x3c0f0036
local stageId    = eeObj.ReadMem32(0x01fce8c)
--ee-hook=0x110390,FastForwardClock,0x8d8f0000
local numPlayers = eeObj.ReadMem32(0x01ffd78) -- 0x01ffd7c seems to always match this one...
--ee-hook=0x101c10,FastForwardClock,0x51cf0052
 
--gs-vert-precision=8
-- print(string.format("stageId = %d, numPlayers = %d", stageId, numPlayers))
--gs-kernel-cl="h2lpool"
--gs-kernel-cl-up="h2lpool2x2"
-- 3 = Electrica
--gs-render-tile-threshold=300000
-- 7 = Electrica II
--vu-custom-min-max=0
-- 8 = Cliffhanger
--vu1-di-bits=0
--vu0-di-bits=0
local newMpgCycles = mpgCycles_default
--vu1-opt-vf00=2
if (stageId == 3 or stageId == 7 or stageId == 8) then
--vu0-opt-vf00=2
--vu1-injection=1
--vu1-mpg-cycles=666
--vu1-mpg-cycles=1166,$000
--vu1-mpg-cycles=950,0xffffffff
--vu0-mpg-cycles=300,0xfc
--ee-hook=0x127630,AdvanceClock,0x27bdffd0,2100
--cdvd-sector-read-cycles=4000
--iop-cycle-scalar=1.6
#Seems like substantial performance fixes</pre>
 
SLUS_211.20
<br>LUA
<pre>-- psychonauts_slus21120
local gpr    = require("ee-gpr-alias")
local emuObj = getEmuObject()
 
apiRequest(1.0) -- request version 0.1 API. Calling apiRequest() is mandatory.


-- note: this will also apply to demo loops (0 players)
-- Bug#9174 -
newMpgCycles = newMpgCycles + 120
emuObj.SetGsTitleFix( "ignoreSubBuffCov", "reserved", { } )
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
-- Bug#9240 (Light maps uprender)
-- Copy z-buffer for future use with light maps. psm = SCE_GS_PSMZ24 (49)
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", {tw=9, th=9, psm=49, zmsk=1 } )


if currentMpgCycles ~= newMpgCycles then
-- Apply light maps texMode=2 (bilinear)  psm= SCE_GS_PSMCT32 (0)
-- print ( string.format("################### Setting mpg-cycles = %d", newMpgCycles) )
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", {tw=8, th=8, psm=0, ztst=1, texMode=2 } )
eeObj.Vu1MpgCycles(newMpgCycles)
currentMpgCycles = newMpgCycles
end
end


eeObj.AddHookJT(0x15ca2c,0x27bdff20,checkNeedsSpeedHack)
-- Bug#9176
 
--
</pre>
-- This bug seems GPUGS interpolation problem.
 
-- The game draws clouds as undiscovered area on the map, but
====The King of Fighters Collection: The Orochi Saga====
-- Z value is unstable --- sometimes 0x320, sometimes 0x321.
<br>CLI
-- On drawing 'Highlight' object (which is missing one), it uses z=0x320 with
<br>SLUS-21554
-- ZTST=GEQUAL. Therefore if the cloud renders with z=0x321, this highlighted object
<pre>
-- doesn't appear. But it's OK on the real PS2 because of no-drawing right edge,
--host-audio-latency=0.010
-- z=0x321 won't be available on the packet (interpolation differences between
--force-frame-blend=1
-- the real PS2 and our gs)
</pre>
-- it gives some values (50.0f) to get +1 on Z value for the highlighted object.
<br>LUA
-- this value will be used later to create the packet in _sprite_ps2_push_data(ESprite*).
<pre>
--
-- Lua 5.3
-- This old one causes a problem on some other scenes.
-- Titles: The King of Fighters Collection - The Orochi Saga
-- local eeObj = getEEObject()
-- Features version: 1.00
-- eeObj.AddHook(0x1b276c, 0xe4400024, function()
-- Author: David Haywood, Warren Davis
-- local v0 = eeObj.GetGpr(gpr.v0)
-- Date: March/April 2017
-- local z  = eeObj.ReadMemFloat(v0+32)
-- eeObj.WriteMemFloat(v0+32, z+50.0)
-- end)
-- New one by Ernesto :
-- The idea is to apply the offset only on the marker.
local eeObj = getEEObject()
local adjustMapZHook = function() -- EMapRenderWindow::drawHighlightSprites
    eeObj.SetFpr(14, eeObj.GetFpr(14) + 50.0)
end
eeObj.AddHook(0x25d654, 0x8de40068, adjustMapZHook) -- \/
eeObj.AddHook(0x25d714, 0xe7b500cc, adjustMapZHook) -- /\
eeObj.AddHook(0x25d7d0, 0xe7b500cc, adjustMapZHook) -- <
eeObj.AddHook(0x25d894, 0x46000386, adjustMapZHook) -- >


--[[ 


Notes:
-- bug#9423 - menus render 20+ times over again, causing very low fps.
-- The whole game in general has no concept of pacing and will re-draw frames multiple times
-- between vsync refreshes.  Hook placed on GameApp::EndFrame() measures time between frames and
-- if it's too short, the EE clock is advanced significantly to compensate.


The intro sequence (SNK logo, movie) only plays ONCE, on startup, never again, no matter how long you leave things in attract mode
local last_time = 0
this works to our advantageFor this reason it's probably easiest to have the current scanlines / bezel options kick in immediately
local last_diff = 0
after the SNK logo.
local advanceClockForAny = function()
local thistime = eeObj.GetClock()
local diff = thistime - last_time
local adv = 0


if diff <= 0 then
-- sanity check, mostly for snapshot restore.
last_diff = diff
last_time = thistime
return
end
-- EE @ 30fps == roughly 10 million cycles
-- bug#9555 - We need to make a reasonable tally of VIF cycles across game display swaps.
--  Use a combination heuristic of EE and VIF1 cycles to gues at whether the title should
--  lock to 45fps, 30fps, or something worse.
local fastminEE = 1600000 -- less than this it's safe to run > 30 fps
local fastminVIF_30 = 2200000 -- VU1 total that merits 30hz throttle
local fastminVIF_45 = 1700000 -- VU1 total that merit 45hz throttle.
local baremin_wo_vif= 6100000 -- EE values below this get promoted to this value  (~50hz)
local forced30hz = 9330000
local forced45hz = 7820000
local vif1_cycles = eeObj.GetVif1Cycles()
if (vif1_cycles > forced30hz) then
vif1_cycles = forced30hz
end


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
local diff_vif = diff + vif1_cycles
continues to play until you confirm the 'save to memory card' choice, this might not work to our advantage.
adv = adv + vif1_cycles


Rom base is set to 00020000 then the actual value as soon as you select a game from the main menu.
-- Lock anything that seems like "Real Work" to either 30 or 45 FPS:
if diff_vif < fastminEE then
adv = adv + (fastminEE*2 - diff_vif)
elseif vif1_cycles > fastminVIF_30 and (diff+(fastminVIF_30)//2) < forced30hz then
adv = adv + (forced30hz  - diff - (fastminVIF_30)//2)
elseif vif1_cycles > fastminVIF_45 and (diff+(fastminVIF_45)//2) < forced45hz then
adv = adv + (forced45hz  - diff - (fastminVIF_45)//2)
elseif diff < baremin_wo_vif then
adv = adv + (baremin_wo_vif  - diff)
end


text base and RAM base get set as soon as the actual emulation starts for each game.
-- print (string.format("DELTA: %d  ADV: %d  VIF1: %d", diff, adv, vif1_cycles))


if adv ~= 0 then
eeObj.AdvanceClock(adv)
end


Sprites
-- Ensure next frame's delta time takes into consideration this frame's advancement.
0 SNK logo
-- Otherwise each fraem delta time would get progressively worse.
1 Bezel


2 Art Mode notification
thistime = thistime + adv
3 Scan Mode notification
last_time = thistime
last_diff = diff
end


4 Fight stick notification
local advanceClockForGame = function() advanceClockForAny(5300000, 2700000) end
5 Fight stick notification
eeObj.AddHookJT(0x207cf8, 0x27bdfff0, advanceClockForGame)   -- <GameApp::EndFrame()>:
6 Fight stick notification
#Performance and optimisations</pre>
7 Fight stick notification


====Red Faction====
SLUS_200.73
<br>CLI
<pre>--gs-use-deferred-l2h=1
--l2h-2d-params=0x0000000800000001,0x000000003a0a2300,512,2
--vu1=jit-sync
--ee-cycle-scalar=1.02
--ee-hook=0x00213370,FastForwardClock,0x8F8293A8
--ee-hook=0x24ce30,AdvanceClock,0x8c620000,20000
--ee-hook=0x272b44,FastForwardClock,0x3c0201ee
--ee-hook=0x272bc4,FastForwardClock,0x3c0201ee
--ee-hook=0x21b354,AdvanceClock,0x3c031000,0x1240
#performance fixes.</pre>


Requested volume adjustments
SLUS_200.73
<br>LUA
<pre>-- Red Faction [US]


Intro 100% -> 79.43%
apiRequest(1.6)
Games 100% -> 70.79%
local gpr = require("ee-gpr-alias")


--]]
-- title uses memcpy() to write to VU1 memory, so some instances will be hotfixed to
-- use slowpath_memcpy() at runtime.


-- 1 for US
eeNativeFunction(0x259820, 0x0080402d, 'memcpy')
-- 2 for Europe
eeNativeFunction(0x2599d8, 0x2cc20008, 'memset')
local Region = 1


eeNativeFunction(0x253870, 0x27bdffd0, 'ieee754_acosf')
eeNativeFunction(0x254620, 0x44026000, 'ieee754_sqrtf')
eeNativeFunction(0x255a50, 0x44026000, 'cosf')
eeNativeFunction(0x255df0, 0x44026000, 'sinf')
eeNativeFunction(0x256318, 0x27bdffa0, 'acosf')


apiRequest(2.0) -- request version 2.0 API. Calling apiRequest() is mandatory.
eeInsnReplace(0x24d7e0, 0x24030064, 0x03e00008)                 -- <FlushCache>
eeInsnReplace(0x24d7e4, 0x0000000c, 0x00000000)
eeNativeHook (0x24d7e0, 0x03e00008,'AdvanceClock',0xa00)
eeInsnReplace(0x24d810, 0x2403ff98, 0x03e00008)                -- <iFlushCache>
eeInsnReplace(0x24d814, 0x0000000c, 0x00000000)
eeNativeHook (0x24d810, 0x03e00008,'AdvanceClock',0xa00)


local eeObj = getEEObject()
eeInsnReplace(0x24de20, 0x27bdffe0, 0x03e00008)                 -- <SyncDCache>
local emuObj = getEmuObject()
eeInsnReplace(0x24de24, 0x0080302d, 0x00000000)
local gsObj    = getGsObject()
eeNativeHook (0x24de20, 0x03e00008,'AdvanceClock',0x600)
eeInsnReplace(0x24de98, 0x3c02ffff, 0x03e00008)                -- <iSyncDCache>
eeInsnReplace(0x24de9c, 0x3442ffc0, 0x00000000)
eeNativeHook (0x24de98, 0x03e00008,'AdvanceClock',0x600)
eeInsnReplace(0x24df58, 0x27bdffe0, 0x03e00008)                -- <InvalidDCache>
eeInsnReplace(0x24df5c, 0x0080302d, 0x00000000)
eeNativeHook (0x24df58, 0x03e00008,'AdvanceClock',0x600)
eeInsnReplace(0x24dfd0, 0x3c02ffff, 0x03e00008)                -- <iInvalidDCache>
eeInsnReplace(0x24dfd4, 0x3442ffc0, 0x00000000)
eeNativeHook (0x24dfd0, 0x03e00008,'AdvanceClock',0x600)


-- hangs on black screen with some other language settings (eg Japanese)
local emuObj = getEmuObject()
emuObj.SetPs2Lang(1)
local eeObj = getEEObject()


local gpr = require("ee-gpr-alias")
-- bug#10159 workaround
local kFilterMode, kWrapMode, kBlendMultiplier, kBlendFunc = require("sprite")
-- slowdown the jeep speed....
local PadConnectType = require("pad-connect-type")


HIDPad_Enable()
local jeepObj = 0
eeObj.AddHook(0x1376f0, 0xc6600174, function()
jeepObj = eeObj.GetGpr(gpr.s1)
end)
eeObj.AddHook(0x137a48, 0xc7ac00bc, function()
local s1 = eeObj.GetGpr(gpr.s1)
if s1 == jeepObj then
eeObj.SetFpr(12, eeObj.GetFpr(12)*0.90)
end
end)


-- NEEDS HOOKING UP
-- bug#10249 workaround
local OptionsMenuActive = 0
-- forcibly calculate the jeep's suspension.
local RestoreNewMenus = false -- WBD keep new menus from reappearing when Player Control menu goes away
eeObj.AddHook(0x19ee08, 0x8ec2120c, function()
 
if jeepObj - 624 == eeObj.GetGpr(gpr.s6) then
-- should these be 1-x ?
eeObj.SetGpr(gpr.v0, 1)
local INTROVOLUME = 0.375                  --WBD adjusted, was 0.7943 
end
local GAMEVOLUME = 0.39                    --WBD adjusted, was 0.7079
end)


local SaveData = emuObj.LoadConfig(0)
-- debug code for jeep movment target.
-- local px = 0.0
-- local pz = 0.0
-- eeObj.AddHook(0x1375bc, 0x26650174, function()
-- local s1 = eeObj.GetGpr(gpr.s1)
-- if s1 == jeepObj then
-- local s3 = eeObj.GetGpr(gpr.s3)
-- px = eeObj.ReadMemFloat(s3 + 372)
-- pz = eeObj.ReadMemFloat(s3 + 380)
-- end
-- end)
-- eeObj.AddHook(0x1375c8, 0xa2620170, function()
-- local s1 = eeObj.GetGpr(gpr.s1)
-- if s1 == 0x19a7a00 then
-- local s3 = eeObj.GetGpr(gpr.s3)
-- local x = eeObj.ReadMemFloat(s3 + 372)
-- local z = eeObj.ReadMemFloat(s3 + 380)
-- if px ~= x or pz ~= z then
--   print(string.format("[%f %f] => [%f %f] v0=%d",
--   px, pz, x, z, eeObj.GetGpr(gpr.v0)))
-- end
--  end
-- end)
#physics calculations and performance fix.</pre>


if SaveData.vid_mode == nil then
SLUS_200.73
SaveData.vid_mode      = 0
<br>SLUS-20073_features.lua
end
<pre>-- Lua 5.3
-- Title:  Red Faction PS2 - SLUS-20073 (USA)
-- Author:  Ernesto Corvi, Adam McInnis


if SaveData.vid_scanlines == nil then
-- Changelog:
SaveData.vid_scanlines  = 0
end


local vid_modeOptions = {"NONE", "ART1", "ART2"}
apiRequest(1.1) -- request version 1.1 API. Calling apiRequest() is mandatory.
local vid_scanlineOptions = {"OFF", "ON"}
local vid_mode = SaveData.vid_mode
local vid_scanlines = SaveData.vid_scanlines


local snklogo = 0
local eeObj = getEEObject()
local emuObj = getEmuObject()


--print (string.format("_NOTE: STARTING Region %d", Region))
local L1 =  -- main
function()
emuObj.ThrottleMax()
end
local L2 =  -- main
function()
emuObj.ThrottleNorm()
end
local load1 = eeObj.AddHook(0x165590, 0x27bdffb0, L1) -- game_load_level
local load2 = eeObj.AddHook(0x16578C, 0x7bb10010, L2) -- game_load_level


-----------------------
-- Widescreen support --
-- Video Options
eeInsnReplace(0x2071c4, 0x00000000, 0x3c013f40) -- gr_setup_3d
-----------------------
eeInsnReplace(0x2071d0, 0x00000000, 0x4481f000) -- gr_setup_3d
eeInsnReplace(0x2072e0, 0x00000000, 0x461ea502) -- gr_setup_3d
eeInsnReplace(0x2072e8, 0x00000000, 0x461ead43) -- gr_setup_3d
eeInsnReplace(0x23a34c, 0x44826000, 0x461e0303) -- shadow_ngps_render_and_copy
eeInsnReplace(0x23a444, 0x3c024334, 0x3c024309) -- shadow_ngps_render_and_copy
emuObj.SetDisplayAspectWide()
#Official widescreen support.</pre>


local sprite_snklogo = getSpriteObject(0)
====Red faction II====
local sprite_bezel = getSpriteObject(1)
CUSA06356
local sprite_artmenu = getSpriteObject(2)
<br>CLI
local sprite_scanmenu = getSpriteObject(3)
<pre>
--gs-use-deferred-l2h=0
--l2h-2d-params=0x0000000800000001,0x000000003a083000,612,2
--mtap1=disabled
--mtap2=disabled
</pre>
====Resident Evil Code: Veronica X====
ALL
<br>CLI
<pre>--ee-jit-pagefault-threshold=30
#crash fix.</pre>


-- Notifications should be assigned to two unused sprite slots. Since we want them to
ALL
-- be displayed on top of everything else, they should be the highest sprites in the list.
<br>LUA
local spr_p1_notify = getSpriteObject(4)
<pre>-- VeronicaX
local spr_p2_notify = getSpriteObject(5)
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
local spr_p1d_notify = getSpriteObject(6)
local spr_p2d_notify = getSpriteObject(7)


-- note: Texture 0 is fixed as the PS2 scanout.
-- Bug# 9976
local texture1 = getTextureObject(1)
local emuObj = getEmuObject()
local texture2 = getTextureObject(2)
emuObj.SetGsTitleFix( "clipScissors", "reserved", {alpha = 0 , frameW = 4 , psm = 0} )
local texture3 = getTextureObject(3)
#graphical fix.</pre>
local texture4 = getTextureObject(4)
local texture5 = getTextureObject(5)
local texture6 = getTextureObject(6)
local texture7 = getTextureObject(7)
--local texture8 = getTextureObject(8) -- WBD not needed


-- ------------------------------------------------------------
====Rogue Galaxy====
local STATE_STOPPED = 0
ALL
local STATE_RUNNING = 1
<br>CLI
<pre>--gs-kernel-cl-up="up2x2skipinterp"
--gs-optimize-30fps=1
#visual fixes and performance optimisation.</pre>


local notify_ypos = 24
SCUS_974_90
local notify_p1_xsize = 0
<br>LUA
local notify_p2_xsize = 0
<pre>require("ee-gpr-alias")
local notify_p1d_xsize = 0
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
local notify_p2d_xsize = 0
local notify_ysize = 0


local notify_frames_p1 = 0
-- Bug#8404 WORKAROUND
local notify_frames_p2 = 0
-- See https://pss.usrd.scea.com/bugzilla/show_bug.cgi?id=8404
local notify_animstate_p1 = STATE_STOPPED
eeInsnReplace(0x124898, 0x3442ffff, 0x3442fffe) -- ori v0,v0,0xffff
local notify_animstate_p2 = STATE_STOPPED
#unsure what this fixes.</pre>


local connected_p1 = 47
====Rise of the Kasai====
local connected_p2 = 47
'''CLI'''
local blink_on_p1 = true
<br>SCUS-97416
local blink_on_p2 = true
<pre>
--gs-kernel-cl-up="up2x2skipinterp"
--cdvd-sector-read-cycles=31000
--iop-cycle-scalar=0.7
</pre>


--[[ Menu notifications --]]


local texture9 = getTextureObject(9)
'''LUA'''
local texture10 = getTextureObject(10)
<br>SCUS-97416
local texture11 = getTextureObject(11)
<pre>
local texture12 = getTextureObject(12)
-- rise_of_kasai
local texture13 = getTextureObject(13)
require("ee-gpr-alias")


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


local extra_menu_h = 0
local extra_menu_w = 0


-- adjust these?
local emuObj = getEmuObject()
local artmenu_ypos = 770 -- adjusted by WBD
local eeObj  = getEEObject()
local scanmenu_ypos = artmenu_ypos + 36


local menu_xpos = 600 -- adjusted by WBD
-- bug #9037.
 
-- Force point sampling when max mip map > 0 and min filter is set to nearest( 0).  
 
-- This is done generically when mipmaping is On , however we prefer to disable mip maps for this title.
HideArtMenu = function()
emuObj.SetGsTitleFix( "forcePoint", "reserved", {mipIsGt=0, mmin=0} )
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)
--]]


-- bug#9241
-- SwapMemCard to Mark of Kri
-- bug#136347 (SCEI bugzilla)
-- we re-use US image for Rise of Kasai EU package and want to let use be able to have Mark of Kri completion bonus.
-- unfortunately we don't have any ways to distinguish which PS4 package we are working on.
-- instead of US => EU reading out modification, let the game retry EU saved data when it fails.
--
-- NOTE: you can write down the filepath directly(onto strptr) at boot time if we can distinguish the differences of the packages.
local first_attempt = true
local buffer = -1
local strptr = -1
local write_str = function (ptr, str)
  for i=1,string.len(str) do
  eeObj.WriteMem8(ptr + i - 1, string.byte(str, i, i))
  end
end
end
eeObj.AddHook(0x1aa904, 0x0040382d, function()
strptr = eeObj.GetGpr(gpr.a2)
local fname = eeObj.ReadMemStr(strptr)
-- print(string.format("%s", fname))
if fname == "BASCUS-97140/BASCUS-97140" then
if first_attempt then
  buffer = eeObj.GetGpr(gpr.a3)
  --print("Trying to read out SCUS-97140 Mark of Kri US saved data");
  --print(string.format("%x:ReadFile(%x, %x, %x)", eeObj.GetGpr(gpr.a0), 0, eeObj.GetGpr(gpr.a2), eeObj.GetGpr(gpr.a3)))
  emuObj.SwapMemCard(0, 0, "SCUS-97140") -- 2nd argument, user-id isn't used in the current implementation.
else
  -- this is the case of re-trying : reading out EU mark of kri
  --print("Trying to read out SCES-51164 Mark of Kri EU saved data");
  write_str(strptr, "BESCES-51164/BESCES-51164")
  eeObj.SetGpr(gpr.a3, buffer);
  --print(string.format("%x:ReadFile(%x, %x, %x)", eeObj.GetGpr(gpr.a0), 0, eeObj.GetGpr(gpr.a2), eeObj.GetGpr(gpr.a3)))
  emuObj.SwapMemCard(0, 0, "SCES-51164")
end
end
end)
eeInsnReplace(0x1aa910, 0x10400020, 0x00000000)
eeObj.AddHook(0x1aa910, 0x00000000, function()
local v0 = eeObj.GetGpr(gpr.v0)
if v0 == 0 then -- failed
--print("File Load Failed")
if first_attempt then
  first_attempt = false
  eeObj.SetPc(0x1aa8fc)
else
  first_attempt = true
  eeObj.SetPc(0x1aa994)
end
end
end)
-- SwapMemCard to Rise of Kasai
eeObj.AddHook(0x1aa9e8, 0xdfbf0000, function()
emuObj.SwapMemCard(0, 0, "SCUS-97416")
write_str(strptr, "BASCUS-97140/BASCUS-97140") -- write back the original string to the place.
strptr = -1
buffer = -1
end)
</pre>


 
====Samurai Shodown Anthology====
 
SLUS_216.29
HideScanMenu = function()
<br>CLI
sprite_scanmenu.Disable()
<pre>--gs-upscale=point
--[[ WBD  added Disable rather than position offscreen
--gs-uprender=2x2
sprite_scanmenu.SetPosXY(-1 - extra_menu_w, scanmenu_ypos)  -- full obscured
--gs-motion-factor=25
    sprite_scanmenu.SetSizeXY(extra_menu_w,extra_menu_h)
--host-audio-latency=0.01
sprite_scanmenu.SetPosUV(0,0)
--gs-ignore-dirty-page-border=1
    sprite_scanmenu.SetSizeUV(extra_menu_w,extra_menu_h)
--gs-kernel-cl="h2lpool"
sprite_scanmenu.SetBlendColorEquation(blendDefaultEquation)
--gs-kernel-cl-up="h2lpool2x2"
--]]
--gs-h2l-list-opt=1
end
--gs-h2l-accurate-hash=1
 
#fix for substantial slowdown during combat.</pre>
 
 
 
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
 
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
 
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
 
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 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)
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
 
-- 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)
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
 
 
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
-- ---------------------------------------------------
 
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
sprite_snklogo.Enable()
sprite_bezel.Disable()
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
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
 
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
 
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
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
 
 
 
 
local currentGame = -1
local lastRomBase = -1
local textVramBase = -1 -- address of text VRAM for emulated NeoGeo
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
 
--[[ When a Player Control menu goes away, we may need to restore our new bezel and scanline
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 pad_bits = emuObj.GetPad()
local UP = pad_bits &  0x0010
local DOWN = pad_bits &  0x0040
local LEFT = pad_bits &  0x0080
local RIGHT = pad_bits &  0x0020
local Triangle = pad_bits &  0x1000
local Cross = pad_bits &  0x4000
local Square = pad_bits &  0x8000
local Circle = pad_bits &  0x2000
local L1 = pad_bits &  0x0400
local L2 = pad_bits &  0x0100
local L3 = pad_bits &  0x0002
local R1 = pad_bits &  0x0800
local R2 = pad_bits &  0x0200
local R3 = pad_bits &  0x0004
local Select = pad_bits &  0x0001
local Start = pad_bits &  0x0008
 
if (L2 ~= 0) and (L2 ~= lastL2) then
--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
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
 
local VsyncFunc = function()
 
CheckInputs()
 
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
if (romBase == 0x0020000) then
--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
 
 
local TurnOnScaleAndInterp = function()
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
 
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
 
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
 
 
 
-- ---------------------------------------------------
-- 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 p1_w,p1_h = texture4.GetSize()
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
    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
 
--[[************************************************************************************
 
Attempt to speed up some load times
****************************************************************************************  --]]
 
 
-- called when initial "Loading..." message is displayed onscreen (after Playstation 2 logo)
--
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
 
--[[
-- 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
 
 
-- When the game issues a call to fade out the Player Selection music, it usually takes a very long time. This
-- will kill it quickly so we can use ThrottleMax.
--
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
eeObj.AddHook(0x1dc3dc, 0x3c050033, forceHorzScrnRes)
]]--
 
</pre>
 
====King of Fighters 98 Ultimate Match====
ALL
<br>CLI
<pre>--force-frame-blend=1
--gs-use-deferred-l2h=0
</pre>
<br>LUA
<pre>
-- Lua 5.3
-- Title: The King of Fighters '98 Ultimate Match - SLES-55280 (Europe) v1.01
-- Author: Nicola Salmoria
-- Date: April 4, 2017
 
 
apiRequest(2.0)
 
local gpr = require( "ee-gpr-alias" )
local kFilterMode, kWrapMode, kBlendMultiplier, kBlendFunc = require("sprite")
local PadConnectType = require("pad-connect-type")
 
local eeObj = getEEObject()
local emuObj = getEmuObject()
local gsObj = getGsObject()
 
 
local GRAPHIC_SETTING_ADDRESS = 0x52f1f0
local AUTO_SAVE_ADDRESS = 0x52f200
local PROGRE_FLG_ADDRESS = 0x542ab0
 
 
local sprite0 = getSpriteObject(0)
local sprite1 = getSpriteObject(1)
local sprite2 = getSpriteObject(2)
local sprite3 = getSpriteObject(3)
 
-- 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)
 
-- 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 STATE_STOPPED = 0
local STATE_RUNNING = 1
 
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 notify_frames_p1 = 0
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
 
-- ---------------------------------------------------
-- 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_SL480_p.sb") -- (1) = 480P ScanLine Sim
 
texture1.Load("./ART1.png")
texture2.Load("./ART2.png")
texture3.Load("./SNK_LOGO.png")
texture4.Load("./p1.png")
texture5.Load("./p2.png")
texture6.Load("./p1d.png")
texture7.Load("./p2d.png")
 
local p1_w,p1_h = texture4.GetSize()
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
    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)
end
 
 
 
local update_notifications_p1 = function()
 
if notify_animstate_p1 == STATE_STOPPED then
spr_p1_notify.Disable()
spr_p1d_notify.Disable()
return
end
 
emuObj.ThrottleNorm()
 
local keyframe = 15
 
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("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("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
 
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
 
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 update_notifications_p2 = function()
 
if notify_animstate_p2 == STATE_STOPPED then
spr_p2_notify.Disable()
spr_p2d_notify.Disable()
return
end
 
emuObj.ThrottleNorm()
 
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("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("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)
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
 
-- 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)
spr_p1_notify.Disable()
spr_p1d_notify.Disable()
spr_p2_notify.Disable()
spr_p2d_notify.Disable()
-- print(string.format("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
 
 
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
-- ---------------------------------------------------
 
local original = function()
sprite0.BindTexture(0)
sprite0.BindFragmentShader(0)
sprite0.SetPosXY((1920-1440)/2,0)
sprite0.SetSizeXY(1440,1080)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()
 
sprite1.Disable()
end
 
-- ---------------------------------------------------
-- Full Screen + ScanLines (480p)
-- ---------------------------------------------------
 
local scanlines = function()
sprite0.BindTexture(0)
sprite0.SetPosXY((1920-1440)/2,0)
sprite0.SetSizeXY(1440,1080)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()
 
sprite1.Disable()
end
 
-- ---------------------------------------------------
-- SNK Overlay NoFX
-- ---------------------------------------------------
local bezel = function()
sprite0.BindTexture(0)
sprite0.BindFragmentShader(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()
 
sprite1.BindTexture(1)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
 
-- ---------------------------------------------------
-- SNK Overlay + ScanLines (480p)
-- ---------------------------------------------------
 
local bezel_scanlines = function()
sprite0.BindTexture(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()
 
sprite1.BindTexture(1)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
 
-- ---------------------------------------------------
-- Arcade Overlay NoFX
-- ---------------------------------------------------
local bezel2 = function()
sprite0.BindTexture(0)
sprite0.BindFragmentShader(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()
 
sprite1.BindTexture(2)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
 
-- ---------------------------------------------------
-- Arcade Overlay + ScanLines (480p)
-- ---------------------------------------------------
 
local bezel2_scanlines = function()
sprite0.BindTexture(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.SetBlendColor(1.0,1.0,1.0,1.0)
sprite0.Enable()
 
sprite1.BindTexture(2)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
 
 
local VIDEOMODE_ORIGINAL = 0*2 + 0
local VIDEOMODE_SCANLINES = 0*2 + 1
local VIDEOMODE_ART1 = 1*2 + 0
local VIDEOMODE_ART1_SCANLINES = 1*2 + 1
local VIDEOMODE_ART2 = 2*2 + 0
local VIDEOMODE_ART2_SCANLINES = 2*2 + 1
local VIDEOMODE_LOGO = 127
 
local lastVideoMode = nil
 
local function switchVideoMode(mode)
if lastVideoMode ~= mode then
lastVideoMode = mode
 
emuObj.ThrottleNorm()
if mode == VIDEOMODE_ORIGINAL then
original()
elseif mode == VIDEOMODE_SCANLINES then
scanlines()
elseif mode == VIDEOMODE_ART1 then
bezel()
elseif mode == VIDEOMODE_ART1_SCANLINES then
bezel_scanlines()
elseif mode == VIDEOMODE_ART2 then
bezel2()
elseif mode == VIDEOMODE_ART2_SCANLINES then
bezel2_scanlines()
end
end
end
 
 
local logoON = function(fade)
lastVideoMode = VIDEOMODE_LOGO
 
sprite0.BindTexture(3)
sprite0.SetPosXY(0,0)
sprite0.SetSizeXY(1920,1080)
sprite0.SetPosUV(0,0)
sprite0.SetSizeUV(1920,1080)
sprite0.SetBlendColor(fade,fade,fade,fade)
sprite0.SetBlendColorEquation(blendConstFadeEquation)
sprite0.Enable()
 
sprite1.Disable()
end
 
 
 
 
-- convert unsigned int to signed
local function asSigned(n)
local MAXINT = 0x80000000
return (n >= MAXINT and n - 2*MAXINT) or n
end
 
 
local LH1 = -- update splash screen
function()
local splashNum = eeObj.GetGpr(gpr.s1)
if splashNum == 3 then
local counter = eeObj.GetGpr(gpr.s0)
local fade = 128
if counter < 32 then
fade = counter * 4
elseif counter >= 192 then
fade = 0
elseif counter > 160 then
fade = (192 - counter) * 4
end
logoON(fade / 128.0)
elseif splashNum == 4 then
switchVideoMode(VIDEOMODE_ORIGINAL)
end
end
 
 
local FH1 = -- initialize options
function()
eeObj.WriteMem8(AUTO_SAVE_ADDRESS, 1) -- ON
end
 
 
local elementPatches = {
[0x960] = -1000, -- move "+" out of view
[0x96e] = -1000, -- move "-" out of view
[0x97c] = -1000, -- move "+" out of view (scroll-in)
[0x98a] = -1000, -- move "-" out of view (scroll-in)
[0x998] = -1000, -- move "+" out of view (scroll-out)
[0x9a6] = -1000, -- move "-" out of view (scroll-out)
[0x9b4] = -1000, -- move "0" out of view
[0x9c2] = -1000, -- move "1" out of view
[0x9d0] = -1000, -- move "2" out of view
[0x9de] = -1000, -- move "0" out of view (scroll-in)
[0x9ec] = -1000, -- move "1" out of view (scroll-in)
[0x9fa] = -1000, -- move "2" out of view (scroll-in)
[0xa08] = -1000, -- move "0" out of view (scroll-out)
[0xa16] = -1000, -- move "1" out of view (scroll-out)
[0xa24] = -1000, -- move "2" out of view (scroll-out)
[0xa38] = 0x25, -- replace "0" with "OFF"
[0xa32] = 0xfe, -- adjust "OFF" x position
[0xa46] = 0x0f, -- replace "1" with "TYPE A"
[0xa40] = 0xfe, -- adjust "TYPE A" x position
[0xa54] = 0x10, -- replace "2" with "TYPE B"
[0xa4e] = 0xfe, -- adjust "TYPE B" x position
[0xac4] = 0x1f, -- replace "0" with "OFF" (scroll-in)
[0xabe] = 0xffae, -- adjust "OFF" x position (scroll-in)
[0xad2] = 0x09, -- replace "1" with "TYPE A" (scroll-in)
[0xacc] = 0xffae, -- adjust "TYPE A" x position (scroll-in)
[0xae0] = 0x0a, -- replace "2" with "TYPE B" (scroll-in)
[0xada] = 0xffae, -- adjust "TYPE B" x position (scroll-in)
[0xb50] = 0x58, -- replace "0" with "OFF" (scroll-out)
[0xb4a] = 0xfe, -- adjust "OFF" x position (scroll-out)
[0xb5e] = 0x42, -- replace "1" with "TYPE A" (scroll-out)
[0xb58] = 0xfe, -- adjust "TYPE A" x position (scroll-out)
[0xb6c] = 0x43, -- replace "2" with "TYPE B" (scroll-out)
[0xb66] = 0xfe, -- adjust "TYPE B" x position (scroll-out)
 
[0xcee] = -1000, -- move "+" out of view
[0xcfc] = -1000, -- move "-" out of view
[0xd0a] = -1000, -- move "+" out of view (scroll-in)
[0xd18] = -1000, -- move "-" out of view (scroll-in)
[0xd26] = -1000, -- move "+" out of view (scroll-out)
[0xd34] = -1000, -- move "-" out of view (scroll-out)
[0xd48] = 0x23, -- replace "0"  with "ON OFF"
[0xd42] = 0xfd, -- adjust "ON OFF" x position
[0xd50] = -1000, -- move "1" out of view
[0xd5e] = -1000, -- move "2" out of view
[0xd72] = 0x1d, -- replace "0"  with "ON OFF" (scroll-in)
[0xd6c] = 0xffad, -- adjust "ON OFF" x position (scroll-in)
[0xd7a] = -1000, -- move "1" out of view (scroll-in)
[0xd88] = -1000, -- move "2" out of view (scroll-in)
[0xd9c] = 0x56, -- replace "0"  with "ON OFF" (scroll-out)
[0xd96] = 0xfd, -- adjust "ON OFF" x position (scroll-out)
[0xda4] = -1000, -- move "1" out of view (scroll-out)
[0xdb2] = -1000, -- move "2" out of view (scroll-out)
[0xdc6] = 0x25, -- replace "0" with "OFF"
[0xdc0] = 0x114, -- adjust "OFF" x position
[0xdd4] = 0x24, -- replace "1" with "ON"
[0xdce] = 0xe3, -- adjust "ON" x position
[0xe52] = 0x1f, -- replace "0" with "OFF" (scroll-in)
[0xe4c] = 0xffc4, -- adjust "OFF" x position (scroll-in)
[0xe60] = 0x1e, -- replace "1" with "ON" (scroll-in)
[0xe5a] = 0xff93, -- adjust "ON" x position (scroll-in)
[0xede] = 0x58, -- replace "0" with "OFF" (scroll-out)
[0xed8] = 0x114, -- adjust "OFF" x position (scroll-out)
[0xeec] = 0x57, -- replace "1" with "ON" (scroll-out)
[0xee6] = 0xe3, -- adjust "ON" x position (scroll-out)
}
 
local atlasPatches = {
-- "POSITION X" -> "ARTWORK"
[0x18e] = 0xffda, -- adjust X offset
[0x192] = 0, -- no other quads after this
 
-- highlighted "POSITION X" -> "ARTWORK"
[0x10e] = 0xffda, -- adjust X offset
[0x112] = 0, -- no other quads after this
 
-- "POSITION Y" -> "SCANLINES"
[0x6a6] = 0x80, -- adjust texture U
[0x6a8] = 0x70, -- adjust texture V
[0x6aa] = 0x78, -- adjust texture width
[0x6ae] = 0xffc2, -- adjust X offset
[0x6b2] = 0, -- no other quads after this
 
-- highlighted "POSITION Y" -> "SCANLINES"
[0x688] = 0x60, -- adjust texture V
[0x68a] = 0x78, -- adjust texture width
[0x68e] = 0xffc2, -- adjust X offset
[0x692] = 0, -- no other quads after this
}
 
local texturePatches = {
-- "POSITION" -> "ARTWORK"
[0x5099] = "02222222222200222222222222002222222222202222200022222002222222222200222222222222002222200022222",
[0x5199] = "22444444444220244444444442202444444444202444200024442022444444444220244444444442202444200024442",
[0x5299] = "24442222244420244422222444202222444222202444200024442024442222244420244422222444202444200024442",
[0x5399] = "24442000244420244420002444200002444200002444200024442024442000244420244420002444202444200024442",
[0x5499] = "24442000244420244420002444200002444200002444222224442024442000244420244420002444202444200024442",
[0x5599] = "24442000244420244420002444200002444200002444244424442024442000244420244420002444202444200024442",
[0x5699] = "24442222244420244422222444200002444200002444244424442024442000244420244422222444202444222224442",
[0x5799] = "24444444444420244444444422200002444200002444244424442024442000244420244444444422202444444444422",
[0x5899] = "24442222244420244422222444200002444200002244444444422024442000244420244422222444202444222224442",
[0x5999] = "24442000244420244420002444200002444200000244422244420024442000244420244420002444202444200024442",
[0x5a99] = "24442000244420244420002444200002444200000244420244420024442000244420244420002444202444200024442",
[0x5b99] = "24442000244420244420002444200002444200000244420244420024442000244420244420002444202444200024442",
[0x5c99] = "24442000244420244420002444200002444200000244420244420024442222244420244420002444202444200024442",
[0x5d99] = "24442000244420244420002444200002444200000244420244420022444444444220244420002444202444200024442",
[0x5e99] = "22222000222220222220002222200002222200000222220222220002222222222200222220002222202222200022222",
 
-- highlighted "POSITION" -> "ARTWORK"
[0x1001] = "09999999999900999999999999009999999999909999900099999009999999999900999999999999009999900099999",
[0x1101] = "99333333333990933333333339909333333333909333900093339099333333333990933333333339909333900093339",
[0x1201] = "93339999933390933399999333909999333999909333900093339093339999933390933399999333909333900093339",
[0x1301] = "93339000933390933390009333900009333900009333900093339093339000933390933390009333909333900093339",
[0x1401] = "93339000933390933390009333900009333900009333999993339093339000933390933390009333909333900093339",
[0x1501] = "93339000933390933390009333900009333900009333933393339093339000933390933390009333909333900093339",
[0x1601] = "93339999933390933399999333900009333900009333933393339093339000933390933399999333909333999993339",
[0x1701] = "93333333333390933333333339900009333900009333933393339093339000933390933333333339909333333333399",
[0x1801] = "93339999933390933399999333900009333900009933333333399093339000933390933399999333909333999993339",
[0x1901] = "93339000933390933390009333900009333900000933399933390093339000933390933390009333909333900093339",
[0x1a01] = "93339000933390933390009333900009333900000933390933390093339000933390933390009333909333900093339",
[0x1b01] = "93339000933390933390009333900009333900000933390933390093339000933390933390009333909333900093339",
[0x1c01] = "93339000933390933390009333900009333900000933390933390093339999933390933390009333909333900093339",
[0x1d01] = "93339000933390933390009333900009333900000933390933390099333333333990933390009333909333900093339",
[0x1e01] = "99999000999990999990009999900009999900000999990999990009999999999900999990009999909999900099999",
 
-- "DEMO CUT" (unused) -> "SCANLINES"
[0x7083] = "022222222222000222222222220002222222222200222222002222202222200000000022222022222200222220022222222222200222222222220",
[0x7183] = "224444444442202244444444422022444444444220244442202444202444200000000024442024444220244420224444444444202244444444422",
[0x7283] = "244422222444202444222224442024442222244420244449202444202444200000000024442024444920244420244422222222202444222224442",
[0x7383] = "244420002444202444200024442024442000244420244444222444202444200000000024442024444422244420244420000000002444200024442",
[0x7483] = "244420002222202444200022222024442000244420244444922444202444200000000024442024444492244420244420000000002444200022222",
[0x7583] = "244420000000002444200000000024442000244420244444422444202444200000000024442024444442244420244420000000002444200000000",
[0x7683] = "244422222222002444200000000024442222244420244494492444202444200000000024442024449449244420244422222220002444222222220",
[0x7783] = "224444444442202444200000000024444444444420244424442444202444200000000024442024442444244420244444444420002244444444422",
[0x7883] = "022222222444202444200000000024442222244420244429449444202444200000000024442024442944944420244422222220000222222224442",
[0x7983] = "000000002444202444200000000024442000244420244422444444202444200022222024442024442244444420244420000000000000000024442",
[0x7a83] = "222220002444202444200022222024442000244420244422944444202444200024442024442024442294444420244420000000002222200024442",
[0x7b83] = "244420002444202444200024442024442000244420244422244444202444200024442024442024442224444420244420000000002444200024442",
[0x7c83] = "244422222444202444222224442024442000244420244420294444202444222224442024442024442029444420244422222222202444222224442",
[0x7d83] = "224444444442202244444444422024442000244420244420224444202444444444442024442024442022444420224444444444202244444444422",
[0x7e83] = "022222222222000222222222220022222000222220222220022222202222222222222022222022222002222220022222222222200222222222220",
 
-- highlighted "DEMO CUT" (unused) -> "SCANLINES"
[0x6002] = "0099999999999000999999999990009999999999900999999009999909999900000000099999099999900999990099999999999900999999999990",
[0x6102] = "0993333333339909933333333399099333333333990933339909333909333900000000093339093333990933390993333333333909933333333399",
[0x6202] = "0933399999333909333999993339093339999933390933332909333909333900000000093339093333290933390933399999999909333999993339",
[0x6302] = "0933390009333909333900093339093339000933390933333999333909333900000000093339093333399933390933390000000009333900093339",
[0x6402] = "0933390009999909333900099999093339000933390933333299333909333900000000093339093333329933390933390000000009333900099999",
[0x6502] = "0933390000000009333900000000093339000933390933333399333909333900000000093339093333339933390933390000000009333900000000",
[0x6602] = "0933399999999009333900000000093339999933390933323329333909333900000000093339093332332933390933399999990009333999999990",
[0x6702] = "0993333333339909333900000000093333333333390933393339333909333900000000093339093339333933390933333333390009933333333399",
[0x6802] = "0099999999333909333900000000093339999933390933392332333909333900000000093339093339233233390933399999990000999999993339",
[0x6902] = "0000000009333909333900000000093339000933390933399333333909333900099999093339093339933333390933390000000000000000093339",
[0x6a02] = "0999990009333909333900099999093339000933390933399233333909333900093339093339093339923333390933390000000009999900093339",
[0x6b02] = "0933390009333909333900093339093339000933390933399933333909333900093339093339093339993333390933390000000009333900093339",
[0x6c02] = "0933399999333909333999993339093339000933390933390923333909333999993339093339093339092333390933399999999909333999993339",
[0x6d02] = "0993333333339909933333333399093339000933390933390993333909333333333339093339093339099333390993333333333909933333333399",
[0x6e02] = "0099999999999000999999999990099999000999990999990099999909999999999999099999099999009999990099999999999900999999999990",
}
 
local FH2A = -- initialize display options screen layout
function()
local layout = eeObj.GetGpr(gpr.a1)
local elements = layout + eeObj.ReadMem32(layout + 12)
 
for offset, value in pairs(elementPatches) do
eeObj.WriteMem16(elements + offset, value)
end
 
local atlas = layout + eeObj.ReadMem32(layout + 4)
for offset, value in pairs(atlasPatches) do
eeObj.WriteMem16(atlas + offset, value)
end
 
local bitmap = layout + eeObj.ReadMem32(layout) + 0x440
for offset, str in pairs(texturePatches) do
local l = string.len(str)
for i = 1, l do
local c = string.sub(str, i, i)
eeObj.WriteMem8(bitmap + offset + i - 1, string.byte(c) - 0x30)
end
end
end
 
 
local FH2B = -- adjust Position X (now Artwork) setting
function()
local posX = asSigned(eeObj.GetGpr(gpr.a0))
eeObj.SetGpr(gpr.a0, posX % 3) -- limit to valid range
end
 
 
local FH2C = -- adjust Position Y (now Scanlines) setting
function()
local posX = asSigned(eeObj.GetGpr(gpr.a0))
eeObj.SetGpr(gpr.a0, posX % 2) -- limit to valid range
end
 
 
local finishedSplashScreens = false
 
local settingPosX = 0
local FH3A = -- apply display position x/y settings (now Artwork/Scanlines)
function()
settingPosX = eeObj.GetGpr(gpr.a1)
eeObj.SetGpr(gpr.a1, 0) -- force pos X to 0
end
local FH3B =
function()
local settingPosY = eeObj.GetGpr(gpr.v1)
eeObj.SetGpr(gpr.v1, 0) -- force pos Y to 0
 
-- limit to valid range
settingPosX = settingPosX % 3
settingPosY = settingPosY % 2
 
if finishedSplashScreens == true then
switchVideoMode(settingPosX * 2 + settingPosY)
end
end
 
local FH3C =
function()
eeObj.SetGpr(gpr.a2, 0) -- force pos Y to 0
end
 
local FH3D = -- finish splash screens
function()
finishedSplashScreens = true
end
 
 
local FH4A = -- init display
function()
-- force progressive mode
eeObj.SetGpr(gpr.a1, 0)
eeObj.SetGpr(gpr.a2, 80)
eeObj.SetGpr(gpr.a3, 1)
eeObj.WriteMem8(PROGRE_FLG_ADDRESS, 1) -- ON
end
 
 
local FH4B = -- check X + Triangle on boot
function()
eeObj.SetGpr(gpr.v0, 0) -- always ignore
end
 
 
 
-- register hooks
 
local hooks = {
-- SNK logo
eeObj.AddHook(0x464f18, 0x0000202d, LH1), -- <logo_task>:
 
-- turn on auto save
eeObj.AddHook(0x329b34, 0x0000282d, FH1), -- <init_option>:
 
-- patch Position x/y options to show Artwork/Scanlines options
eeObj.AddHook(0x4453a4, 0x0200282d, FH2A), -- <UM_GRAPHIC_SETTING>:
eeObj.AddHook(0x445558, 0x24a40001, FH2B), -- <UM_GRAPHIC_SETTING_2000>:
eeObj.AddHook(0x4457c0, 0x24a4ffff, FH2B), -- <UM_GRAPHIC_SETTING_2000>:
eeObj.AddHook(0x445594, 0x24a40001, FH2C), -- <UM_GRAPHIC_SETTING_2000>:
eeObj.AddHook(0x4457fc, 0x24a4ffff, FH2C), -- <UM_GRAPHIC_SETTING_2000>:
 
-- apply artwork / scanlines settings
eeObj.AddHook(0x329bcc, 0x8065f1f3, FH3A), -- <DisplayPositionSet>:
eeObj.AddHook(0x329bec, 0x8063f1f4, FH3B), -- <DisplayPositionSet>:
eeObj.AddHook(0x329c18, 0x8046f1f4, FH3C), -- <DisplayPositionSet>:
eeObj.AddHook(0x464fa8, 0x7bb00000, FH3D), -- <logo_task>:
 
-- force Progressive mode
eeObj.AddHook(0x100290, 0x27bdffb0, FH4A), -- <sceGsResetGraph>:
eeObj.AddHook(0x1b5e98, 0x90422a98, FH4B), -- <DEMO_INIT_200>:
}
 
-- force 60Hz mode
eeInsnReplace(0x47a9c0, 0x0c11e9e4, 0x24020002) -- li $v0,2
eeInsnReplace(0x47a9b8, 0x0c11e934, 0x00000000) -- nop
eeInsnReplace(0x47a9e8, 0x0c11e950, 0x00000000) -- nop
eeInsnReplace(0x3290e0, 0x5440000c, 0x00000000) -- nop
 
 
-- Fight stick
 
HIDPad_Enable()
 
local addedHooks = false
local pad = function()
if addedHooks == false then
addedHooks = true
switchVideoMode(VIDEOMODE_ORIGINAL)
emuObj.AddVsyncHook(update_notifications_p1)
emuObj.AddVsyncHook(update_notifications_p2)
 
-- test message on boot
-- onHIDPadEvent(0, true, PadConnectType.HID)
 
-- disable interpolation
gsObj.SetUprenderMode("none")
gsObj.SetUpscaleMode("point")
 
-- bug report:
-- The sound volume is too loud and could you please decrease to -24LKF (�2) as PS4 recommended?
-- The current sound volume: -10.21LKFS
--
-- So set main volume to 10^(-14/20) ~= 0.2 i.e. about 14dB attenuation.
emuObj.SetVolumes(0.2, 1.0, 1.0)
end
end
 
emuObj.AddPadHook(onHIDPadEvent)
emuObj.AddEntryPointHook(pad)
 
 
--=======================================  WBD addition 11/29/2017
 
-- Fix bug 10414 - large stretched polygons block view of player characters
 
local FixPointTable = function()
-- local pPtTbl = eeObj.ReadMem32(p5Tbl+0x114) -- ptr to source points DEBUG ONLY
local s6 = eeObj.GetGpr(gpr.s6) -- obj in question
local p5Tbl = eeObj.ReadMem32(s6+0x10) -- ptr to object's data
local numPts = eeObj.ReadMem32(p5Tbl+0x110) -- num points in list
local pTbl = 0x1bd6ce0 -- bg_point_buff (we need to scan this)
for i = 1, numPts do
local stat = eeObj.ReadMem32(pTbl + 0xc) -- check 4th word, should be 0
if (stat ~= 0) then -- if not, we need to fix
 
--[[ DEBUG ONLY, print source point
local w1 = eeObj.ReadMemFloat(pPtTbl)
local w2 = eeObj.ReadMemFloat(pPtTbl+4)
local w3 = eeObj.ReadMemFloat(pPtTbl+8)
local w4 = eeObj.ReadMemFloat(pPtTbl+12)
print (string.format("_NOTE: Point %d, %x (%f, %f, %f, %f) needs fixing", i, pPtTbl, w1,w2,w3,w4))
--]]
if (i > 1) then -- if this is any but the first entry
stat = eeObj.ReadMem64(pTbl-0x10) -- fix by replacing the x, y with
eeObj.WriteMem64(pTbl, stat) -- the previous entry's x and y.
-- stat = eeObj.ReadMem64(pTbl-8)
stat = 0x0000000080000000 -- replace the z with 0x80000000
eeObj.WriteMem64(pTbl+8, stat) -- replace the 4th word with 0
-- print "_NOTE: Fixed with previous entry"
else
stat = eeObj.ReadMem32(pTbl + 0x1c) -- if this is the first entry
if (stat == 0) then -- make sure the second entry is kosher
stat = eeObj.ReadMem64(pTbl+0x10)
eeObj.WriteMem64(pTbl, stat) -- if it is, use the x, y from that entry.
-- stat = eeObj.ReadMem64(pTbl+0x18)
stat = 0x0000000080000000 -- replace the z with 0x80000000
eeObj.WriteMem64(pTbl+8, stat) -- replace the 4th word with 0
-- print "_NOTE: Fixed with next entry"
else
eeObj.WriteMem64(pTbl, 0) -- if the 2nd entry is not kosher
eeObj.WriteMem64(pTbl+8, 0x0000000080000000) -- write 0, 0, 0x80000000, 0
-- print "_NOTE: Fixed with (0, 0, 0x80000000, 0)"
end
end
else -- check if Z value is between 0 and 0x8000
stat = eeObj.ReadMem32(pTbl + 8) -- if so, overwrite Z with 0x80000000
if (stat <= 0x8000) then
eeObj.WriteMem32(pTbl+8, 0x80000000)
-- print (string.format("_NOTE: Fixed positive Z = %x", stat))
end
end
pTbl = pTbl + 0x10
-- pPtTbl = pPtTbl + 0x10 -- DEBUG ONLY
end
end
 
eeObj.AddHook(0x439dc8, 0x008e150180, FixPointTable)
 
eeInsnReplace(0x3298ac, 0xa064f1f2, 0xa060f1f2)  -- Change default Focus setting from Soft to Normal
 
</pre>
 
====King of Fighters 2000====
ALL
<br>CLI
<pre>--gs-uprender=none
--gs-upscale=point
--host-audio-latency=0.01
--hid-pad=1
#graphical fixes and support for further fightsticks.</pre>
 
SLUS_208.34
<br>LUA
<pre>-- The King of Fighters 2000
 
apiRequest(1.1)
 
 
local emuObj = getEmuObject()
--will fix sprite rendering artifact
ndx = 28
val = 0x86
-- spriteCorrectionTab[ndx] = val
emuObj.SetGsTitleFix( "globalSet",  "reserved", { fixSpriteDivTab = val | ( ndx<<16) })
#graphical fixes.</pre>
 
SLUS_208.34
<br>SLUS-20834_features.lua
<pre>This is a substantial file. Over 700 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/1FsPnuxgEa0ymnGdU6w2tdy-eamRN6l3e/view
 
#More stick support, shaders, bezels, widescreen fix.</pre>
 
====Manhunt====
SLUS_208.27
<br>CLI
<pre>--ee-hook=0x4329e0,FastForwardClock,0x1600fff1
--gs-uv-shift-pointsampling=1
--ee-hook=0x1d1d60,AdvanceClock,0x27bdffb0,225
--ee-hook=0x1d71e0,AdvanceClock,0x0c09a4d0,100
#Fix crane issue, and probably fixing lightsourcing.</pre>
 
SLUS_208.27
<br>Lua
<pre>-- Manhunt [US]
 
local gpr = require('ee-gpr-alias')
 
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
local emuObj = getEmuObject()
local eeObj  = getEEObject()
 
-- Bug #9413
-- Disable uprender on the draw command which samples the framebuffer (0x3200) using bilinear sampling (texMode=2)
-- All lighting effects use TriFan prim type, so use that as well to filter against.
emuObj.SetGsTitleFix( "forceSimpleFetch",  "reserved", {prim=5, texMode=2, tbp=0x320000} )
 
-- Bug#9277
-- Shorten the timeout period for some particular execution command(s).
-- When entering the crane, some instruction is executed with a wait period of 0x7333.
-- Shortening the wait period to 0x4000 it.  Note that 0x5000 is enough to fix entering the
-- crane once, but a more aggressive value was needed for subsequent entry into the crane.
 
local FixBug9277 = function()
local s0 = eeObj.GetGpr(gpr.s0)
--local v0 = eeObj.GetGpr(gpr.v0)
--print( string.format("-------- v0=0x%08x s0=0x%08x", v0, s0) )
if s0 == 0x7333 then
eeObj.SetGpr(gpr.s0, 0x5800)
end
end
 
-- No longer seems necessary, when FastForwardClock is applied here instead (see _cli.conf)
eeObj.AddHookJT(0x1d71f8, 0x10000036, FixBug9277)
#Further bug fixes as well as fixing bloom/overglare from lightsources.</pre>
====Max Payne====
SLES_503.26
<br>CLI
<pre>--gs-use-clut-merge=1
--gs-kernel-cl="clutmerge"
--gs-kernel-cl-up="clutmerge2x2"
--vu1-no-clamping=1
--vu0-no-clamping=1
--fpu-no-clamping=1
--force-pal-60hz=1
--vu1-mpg-cycles=1000
--safe-area-min=1.0
--fpu-accurate-mul-fast=1
--fpu-accurate-muldiv-range=0x2acce0,0x2acce0
 
#Graphics clean-up</pre>
 
SLES_503.26
<br> Features Lua
<pre>-- Max Payne [US]
 
-- Lua 5.3
-- Title: Max Payne - SLES-50326 (Europe FIGS) v1.00
 
 
require( "ee-gpr-alias" ) -- you can access EE GPR by alias (gpr.a0 / gpr["a0"])
 
apiRequest(0.2) -- request version 0.2 API for throttling control.
 
local eeObj = getEEObject()
local emuObj = getEmuObject()
 
 
 
local TH1A = -- start of main()
function()
emuObj.ThrottleMax()
end
 
local TH1B = -- init loading screen
function()
local mode = eeObj.GetGpr(gpr.a0)
 
if mode ~= 4 then -- not sure what mode 4 is, but doesn't precede a real loading
emuObj.ThrottleMax()
end
end
 
local TH1C = -- advance progress bar
function()
local pct = eeObj.GetFpr(2)
 
if pct >= 1.0 then
emuObj.ThrottleNorm()
end
end
 
 
 
-- register hooks
 
local registeredHooks = {}
 
maxpayne_features_unregisterHooks = function() -- global function (called by trophy_data)
for _, hook in pairs(registeredHooks) do
eeObj.RemoveHook(hook)
end
registeredHooks = {}
end
 
maxpayne_features_registerHooks = function() -- global function (called by trophy_data)
registeredHooks = {
eeObj.AddHook(0x133dc8, 0x24030001, TH1A), -- <main>:
eeObj.AddHook(0x15ed7c, 0x24030003, TH1B), -- <MaxPayne_GameMode::initLoadingScreen(void)>:
eeObj.AddHook(0x133078, 0xc4a20000, TH1C), -- <UpdateProgressBarKH(void)>:
}
end</pre>
 
====Metal Slug Anthology====
ALL
<br>CLI
<pre>--host-audio-latency=0.010
--gs-upscale=point
--gs-uprender=none
#fix for graphical glitches.</pre>
 
SLUS_215.50
<br>LUA
<pre>
-- Metal Slug Anthology PS2 - SLUS-21550 (USA)
 
apiRequest(1.2) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
local eeObj = getEEObject()
local emuObj = getEmuObject()
 
-- Fix for black screen booting an elf. This is a game bug.
-- The v1.0 of the game suffered from an intermittent bug on the real PS2
-- where sometimes it would hang on a black screen trying to launch a new elf.
-- This is apparently due to a bad IOP state, which caused sceCdInit to hang.
-- Later versions of the game (1.1, 1.2) attempted to fix this in different ways.
-- On Olympus, v1.0 (USA) hangs always, while v1.2 (EUR/JPN) works always.
-- The fix implemented here replaces a call to FlushCache() to loadImageAndReboot(),
-- which is a function that reboots the IOP and resolves the hang.
 
eeInsnReplace(0x189c24, 0x0c08f7f8, 0x0c061dd2) -- FlushCache() -> loadImageAndReboot()
eeInsnReplace(0x117804, 0x0c0c1e08, 0x0c045e20) -- FlushCache() -> loadImageAndReboot()
</pre>
 
====Okage====
'''TXT'''
<br>SCUS-97129
<pre>
--vu1-mpg-cycles=50
--vu1-mpg-cycles=850,$037,$7b3
--vu1-mpg-cycles=150,$2b4,$7c4
</pre>
'''LUA'''
<br>SCUS-97129
<pre>
require("ee-gpr-alias")
require("ps2")
apiRequest(0.6) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
local eeObj = getEEObject()
 
-- bug#8740
-- SPSetDirect(addr, char-pos, char-pos, x-coord, y-coord, width, height)
-- reduce width just 1 pix.
local Replace_1a1fb0 = InsnOverlay( {
0x0806720a, --        j      0x19c828
0x2529ffff, --        addiu  t1,t1,-1
})
eeInsnReplace(0x1a1fb0, 0x0c06720a, 0x0c000000 | (Replace_1a1fb0>>2)) -- jal 19c828 <SPSetDirect>
 
</pre>
 
====Parappa the Rapper 2====
ALL
<br>CLI
<pre>--host-audio-latency=0.01
 
#fix for audio off sync.</pre>
 
SCUS_971.67
<br>LUA
<pre>
 
-- Parappa the Rapper 2  [SCUS-97167]
 
 
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
require( "ee-gpr-alias" )
require( "ee-hwaddr" )
 
local eeObj = getEEObject()
 
-- ================================================================================================
-- Title issues racy combination of VIF1 and GIF transfers.  It expects GIF to finish ahead of VU
-- XGKICK (via VIF1), which is atypical among PS2 titles (XGKICK has HW priority over GIF, and so
-- GIF can only finish ahead of XGKICK in certain extreme cases).
--
-- Fixed by delaying the specific VIF1 transfer (identified by MADR) for a long time to ensure GIF
-- gains arbitration and finishes ahead of XGKICKs.
--
local fix01_dma_vif1 =
function()
local ee = eeObj
local tgtaddr = ee.GetGpr(gpr.s0)
 
-- print( string.format("success pt.1 : %x %x", vif1_hw.CHCR, tgtaddr ) )
 
if tgtaddr == vif1_hw.CHCR then
 
-- expected:
--  # DIR==1 and MOD==1  (chain)
--  # TADR==0x01C76AA0
 
local chcr = ee.GetGPR(gpr.v0)
 
if (chcr & 0x05) == 0x05 then
local tadr = ee.ReadMem32(vif1_hw.TADR);
if tadr == 0x01C76AA0 then
-- 0x6000 works fine, 0x6500 adds a little extra cushion.
ee.SchedulerDelayEvent("vif1.dma", 0x6500)
-- print( "Parappa fix applied!" )
end
end
end
end
-- ================================================================================================
 
eeObj.AddHook(0x0015A008, 0xAE020000, fix01_dma_vif1)
 
-- ================================================================================================
-- Our emulator has accuracy problems on so many places. In this title, we have problems on VU.
-- To be accurate on VU is quite painful (we won't be able to get reasonable performance with it)
-- So as workaround, we just disable bilinear textures on Render-To-Texture drawing.
-- Bug#8122
eeInsnReplace(0x118084, 0xde260008, 0x24060000) -- ld a2,8(s1)
eeInsnReplace(0x118798, 0xde260008, 0x24060000) -- ld a2,8(s1)
eeInsnReplace(0x118868, 0xde660008, 0x24060000) -- ld a2,8(s3)
eeInsnReplace(0x119d18, 0xdc460008, 0x24060000) -- ld a2,8(v0)
eeInsnReplace(0x119d18, 0xdc460008, 0x24060000) -- ld a2,8(v0)
 
</pre>
 
====Primal====
CLI
<pre>
--vu1-mul0fix-range=0x22f,0x22f
--vu1-mul0fix-range=0x298,0x29c
--vu1-native-patch=1
--ee-hook=0x2f76c0,FastForwardClock,0x1200ffbf
--vu1-mpg-cycles=700
--gs-kernel-cl-up="up2x2Simple"
--cop2-no-clamp-range=0x37bd78,0x37c514    ;; CMatrix functions         
--cop2-no-clamp-range=0x38c0e0,0x38c174    ;; CModel::CalcSkinningMatrices
--cop2-no-clamp-range=0x391cf0,0x392084    ;; CSkelton::Update           
</pre>
 
LUA
<pre>
-- Primal  [EU]
 
apiRequest(1.1)
 
local eeObj = getEEObject()
local emuObj = getEmuObject()
 
-- Bug 9094 - Title exhibits poor performance due to VU0 spin loops.
-- The spin loops are meant to be an optimizaion on PS2 and the best way of handling them is
-- to remove them from the original code.  This can be done since the VF09 register is unsed by
-- the first portion of the VU0 mpg.
--
-- Insn replacements Summarized:
--  1. NOP the spin loop from VU0.
--  2. NOP the setup code for VI05, which is the reg tested by the VU0 spin loop
--  3. Reorder the vcallms and qmtc2.
 
 
-- [$167:520507ff] IBNE vi05, vi00, [$167]
-- [$167:000002ff] NOP
local orig = (0x000002ff << 32) | 0x520507ff
 
vuInsnReplace(0, 0x167, orig, 0x8000033c | (0x000002ff << 32)) -- NOP / NOP2
vuInsnReplace(0, 0x172, orig, 0x8000033c | (0x000002ff << 32)) -- NOP / NOP2
 
local region_base = 0x399c5c
 
eeInsnReplace(region_base + 0x000, 0x24040001, 0x00000000)  -- li a0,1 -> NOP
eeInsnReplace(region_base + 0x010, 0x48c42800, 0x00000000)  -- ctc2.ni a0,$5      -> NOP
eeInsnReplace(region_base + 0x090, 0x24040001, 0x00000000)  -- li a0,1            -> NOP
eeInsnReplace(region_base + 0x0a0, 0x48c42800, 0x00000000)  -- ctc2.ni a0,$5      -> NOP
 
eeInsnReplace(region_base + 0x05c, 0x48c02800, 0x00000000) -- ctc2.ni zero,$5 -> NOP
eeInsnReplace(region_base + 0x114, 0x48c02800, 0x00000000) -- ctc2.ni zero,$5 -> NOP
 
eeInsnReplace(region_base + 0x054,  0x4a00d839, 0x48a44800) -- vcallmsr vi27 -> qmtc2 a0,vf9
eeInsnReplace(region_base + 0x058,  0x48a44800, 0x4a00d839) -- qmtc2 a0,vf9 -> vcallmsr vi27
eeInsnReplace(region_base + 0x10c, 0x4a00d839, 0x48a44800) -- vcallmsr vi27 -> qmtc2 a0,vf9
eeInsnReplace(region_base + 0x110, 0x48a44800, 0x4a00d839) -- qmtc2 a0,vf9 -> vcallmsr vi27
 
-- remove heat haze distortion ( for performance reason Bug#8827 )
--  reg = 0x42  packedFlags = 3( iip, tme, fst)  packedPrim  = 5(SCE_GS_PRIM_TRIFAN)
emuObj.SetGsTitleFix( "globalSet",  "reserved", { packedRegsLo = 0x42,packedRegsHi = 0, packedRegsNum = 2, packedFlags = 3, packedPrim = 5})
emuObj.SetGsTitleFix( "skipPacked", "reserved", { alpha = 0x80000044, tbp = 0x3a4000 , zmsk=1 })
emuObj.SetGsTitleFix( "skipPacked", "reserved", { alpha = 0x80000044, tbp = 0x348000 , zmsk=1 })
 
 
-- NOP out cacheline prefetch instructions.
-- Prefetch might have been a good idea on PS2, but it is entirely unhelpful on the PS4 target.
if 1 then
eeInsnReplace(0x381e60, 0x78400040, 0x00000000) -- lq zero,64(v0)
eeInsnReplace(0x3822c0, 0x78400040, 0x00000000) -- lq zero,64(v0)
eeInsnReplace(0x38ec7c, 0x78800040, 0x00000000) -- lq zero,64(a0)
eeInsnReplace(0x38ed78, 0x78600040, 0x00000000) -- lq zero,64(v1)
eeInsnReplace(0x38eec0, 0x78a00040, 0x00000000) -- lq zero,64(a1)
eeInsnReplace(0x38fe28, 0x7a600040, 0x00000000) -- lq zero,64(s3)
eeInsnReplace(0x38fea4, 0x78800040, 0x00000000) -- lq zero,64(a0)
eeInsnReplace(0x390da8, 0x78400040, 0x00000000) -- lq zero,64(v0)
eeInsnReplace(0x391020, 0x78400040, 0x00000000) -- lq zero,64(v0)
eeInsnReplace(0x391174, 0x78a00040, 0x00000000) -- lq zero,64(a1)
eeInsnReplace(0x3912b0, 0x78a00040, 0x00000000) -- lq zero,64(a1)
eeInsnReplace(0x398790, 0x7a000040, 0x00000000) -- lq zero,64(s0)
eeInsnReplace(0x399e60, 0x78400050, 0x00000000) -- lq zero,80(v0)
eeInsnReplace(0x399ee8, 0x78400050, 0x00000000) -- lq zero,80(v0)
end
 
-- NOP out an idle loop meant to flush some cache lines...
if 1 then
eeInsnReplace(0x331038, 0x18a00009, 0x00000000) --  blez a1,331060 <CDMAStreamIterator::AllocateBlock(unsigned int)+0x110>
eeInsnReplace(0x33103c, 0x00d41821, 0x00000000) --  addu v1,a2,s4
eeInsnReplace(0x331040, 0xbc5a0000, 0x00000000) --  cache 0x1a,0(v0)
eeInsnReplace(0x331044, 0x24a5ffff, 0x00000000) --  addiu a1,a1,-1
eeInsnReplace(0x331054, 0x1ca0fffa, 0x00000000) --  bgtz a1,331040 <CDMAStreamIterator::AllocateBlock(unsigned int)+0xf0>
eeInsnReplace(0x331058, 0x24420040, 0x00000000) --  addiu v0,v0,64
end
 
-- perf. fix bug 9094
emuObj.SetGsTitleFix( "globalSet", "reserved", {ignoreUpRenderTimeout=2} )
emuObj.SetGsTitleFix( "ignoreUpRender",  230, {} )
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { alpha=0x00000000 } )
emuObj.SetGsTitleFix( "ignoreAreaUpdate", 0, { alpha=0x80000048 } )
 
</pre>
====Puzzle Quest====
<br>LUA
<br>SLUS-21692
<pre>
require("ee-gpr-alias")
require( "ee-hwaddr" )
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
eeObj = getEEObject()
 
-- Bug#8536
-- the game has a discrepancy between PATH1+2(for env+polygon) and PATH3(tex)
-- At here, we will replace VIF packet including MSKPATH3 just only the first one in a frame.
-- The packet sits at 0x35cbd0 statically and the game uses CALL tag to refer it for each draw-calls.
-- Because it's shared among all drawcalls, we can't rewrite it directly.
-- Instead of that, changing the address of CALL tag and placing our own packet excluding MSKPATH3=OFF on Overlay area.
 
-- Strategy
-- - Create our special packet on Overlay area
-- - just before kicking Ch1DMA, replace CALL tag's address to our own one.
--
-- the original packets at 0x35cbd0
-- 6000001f 00000000 11000000 50000002 : RET QWC=1f
-- 00008001 10000000 0000000e 00000000
-- 00000000 00000000 0000007f 00000000
-- 00000000 00000000 13000000 50000002
-- 00008001 10000000 0000000e 00000000
-- 00000000 00000000 0000003f 00000000
-- 00000000 00000000 00000000 06000000 : MSKPATH3=OFF
-- 00000000 00000000 00000000 00000000 x 23 qword
 
-- Reserve memory area for our packet.
-- Because InsnOverlay is for instructions, we can't use directly the API for 'data'.
local addrReplacePacket = InsnOverlay( {
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0
})
 
-- Create our packet at the top of 'main'
eeObj.AddHook( 0x205be0, 0x27bdff80, function()
  local addr = addrReplacePacket
  -- create replace packet on the reserved area.
  eeObj.WriteMem128(addr + 0x00, 0x60000006, 0x00000000, 0x11000000, 0x50000002)
  eeObj.WriteMem128(addr + 0x10, 0x00008001, 0x10000000, 0x0000000e, 0x00000000)
  eeObj.WriteMem128(addr + 0x20, 0x00000000, 0x00000000, 0x0000007f, 0x00000000)
  eeObj.WriteMem128(addr + 0x30, 0x00000000, 0x00000000, 0x13000000, 0x50000002)
  eeObj.WriteMem128(addr + 0x40, 0x00008001, 0x10000000, 0x0000000e, 0x00000000)
  eeObj.WriteMem128(addr + 0x50, 0x00000000, 0x00000000, 0x0000003f, 0x00000000)
  eeObj.WriteMem128(addr + 0x60, 0x00000000, 0x00000000, 0x00000000, 0x00000000)
end)
 
-- Replace the address of CALL to our own packet.
eeObj.AddHook( 0x1faff0, 0x24030145, function()
  local ee  = eeObj
  local tadr = ee.ReadMem32(vif1_hw.TADR)
  local addr_openClosePATH3Chain = 0x35cbd0
  -- the first VIF tag of the chain must be 'CALL 0x35cbd0'.
  if ee.ReadMem32(tadr) ~= 0x50000000 or ee.ReadMem32(tadr+4) ~= addr_openClosePATH3Chain then
-- print(stirng.format("***** UNEXPECTED PACKET *****"))
return
  end
  -- change call address to our own no-mskpath3 packets.
  ee.WriteMem32(tadr+4, addrReplacePacket)
  -- print(string.format("=== replace packet %08x ===", addrReplacePacket))
  -- for i=0,6 do
  -- print(string.format("  %08x %08x %08x %08x", ee.ReadMem128(addrReplacePacket + i*16)))
  -- end
end)
 
</pre>
 
====Red Dead Revolver====
<br>SLUS-20500
<br>CLI
<pre>
--gs-kernel-cl-up="up2x2skipInterp"
--fpu-rsqrt-fast-estimate=0
--mtap1=Always
--vif1-ignore-cmd-ints=1
--iop-cycle-scalar=0.80
--iop-hook=0x0086ac,FastForwardClock
--ee-sif0-cycle-scalar=2.0
--ee-sif1-cycle-scalar=2.0
--iop-sif1-cycle-scalar=5.0
--iop-sif0-cycle-scalar=5.0
--iop-tight-slice-count=12
--cdvd-sector-read-cycles=5000
--ee-hook=0x352dd0,AdvanceClock,0x0c0ef9a2,4500
--ee-hook=0x3b5068,FastForwardClock,0x00481024
--ee-hook=0x46fb68,FastForwardClock,0x8ca30000
--ee-hook=0x46fb38,FastForwardClock,0x8c620000
--ee-hook=0x46fb68,MfifoDrain,0x8ca30000
--ee-hook=0x46fb38,MfifoDrain,0x8c620000
--mfifo-manual-drain=0.30
--mfifo-chunk-drain-cycles=210000
</pre>
<br>SLUS-20500
<br>LUA
<pre>
-- red_dead_revolver
local gpr = require("ee-gpr-alias")
 
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
-- Bug 9309
local emuObj = getEmuObject()
-- psm= SCE_GS_PSMCT32 (0)
emuObj.SetGsTitleFix( "forceSimpleFetch",  "reserved", {psm=0} )
emuObj.SetGsTitleFix( "fetchFromCurrBuff", "reserved", {psm=0} )
 
-- bug#9490 - Disable post-processing effect - <imgImageryDeriver<fxDistort>::Draw(void)>
eeInsnReplace(0x4c4b78, 0x27bdfff0, 0x03e00008) -- JR $ra
eeInsnReplace(0x4c4b7c, 0xffbf0000, 0x00000000) -- NOP
 
-- gfxState class writes bytes and then reads them back as words later on.
-- This replaces most of the word readbacks with lbu equivalents to avoid STLF.
-- 003c0950 <gfxState::Update_TEST(void)>:
eeInsnReplace(0x3c0970, 0x8ce6efd8, 0x90e6efd8) -- lw a2,-4136(a3)
eeInsnReplace(0x3c09a0, 0x8ce3f37c, 0x90e3f37c) -- lw v1,-3204(a3)
 
-- 0032aa70 <fxFloatPropGrid::Get(Vector2 const &) const>:
--  The original  compiler couldn't assume that Vector2 was an aligned object, so it generated
--    ldr/sdr instructions to access it.  The lack of assumption seems to have also caused it to
--    spill FPU registers to memory needlessly.
 
if true then
eeInsnReplace(0x32aa74, 0x68a20007, 0x00000000)
eeInsnReplace(0x32aa78, 0x6ca20000, 0x00000000)
eeInsnReplace(0x32aa7c, 0xb3a20017, 0xc4a00000) -- lwc1 $f0,0(a1)
eeInsnReplace(0x32aa80, 0xb7a20010, 0xc4a10004) -- lwc1 $f1,4(a1)
 
eeInsnReplace(0x32aa8c, 0xc7a00010, 0x00000000) -- nop
eeInsnReplace(0x32aa9c, 0xc7a10014, 0x00000000) -- nop
 
eeInsnReplace(0x32aaa8, 0xe7a00010, 0x00000000) -- nop
eeInsnReplace(0x32aaac, 0x46020082, 0x46020002) -- mul.s $f0,$f0,$f2 
eeInsnReplace(0x32aab0, 0x3c014480, 0x3c014480) -- lui at,0x4480
eeInsnReplace(0x32aab4, 0x34211000, 0x34211000) -- ori at,at,0x1000
eeInsnReplace(0x32aab8, 0x44812000, 0x44812000) -- mtc1 at,$f4
eeInsnReplace(0x32aabc, 0xe7a10014, 0x00000000) -- nop
eeInsnReplace(0x32aac0, 0x460308c2, 0x46030842) -- mul.s $f1,$f1,$f3
eeInsnReplace(0x32aac4, 0xe7a20010, 0xe7a00000) -- swc1 $f0,0(sp)
eeInsnReplace(0x32aac8, 0x90a4001c, 0x90a4001c) -- lbu $a0,28($a1)
eeInsnReplace(0x32aacc, 0xe7a30014, 0xe7a10004) -- swc1 $f1,4(sp)
 
eeInsnReplace(0x32aad0, 0x6baa0017, 0x00000000) -- nop
eeInsnReplace(0x32aad4, 0x6faa0010, 0x00000000) -- nop
eeInsnReplace(0x32aad8, 0xb3aa0007, 0x00000000) -- nop
eeInsnReplace(0x32aadc, 0xb7aa0000, 0x00000000) -- nop
eeInsnReplace(0x32aae0, 0xc7a00000, 0x00000000) -- nop
eeInsnReplace(0x32aae4, 0xc7a10004, 0x00000000) -- nop
end
 
</pre>
<br>Features.lua
<br>SLUS-20500
<br>Even though it's features.lua, it's still a very good example for learning
<pre>
-- Lua 5.3
-- Title: Red Dead Revolver - SLUS-20500 (USA) v1.03
-- Author:  Nicola Salmoria
-- Date: March 23, 2016
 
 
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 GFXPIPELINE_16BY9_ADDRESS = 0x79eeec
local GLOBALS_UNIVERSALDATA_ADDRESS = 0x742120
 
 
local TH1A = -- start loading screen
function()
emuObj.ThrottleMax()
end
 
local TH1B = -- switch to threaded loading (over cutscene etc.)
function()
emuObj.ThrottleNorm()
end
 
 
local TH2A = -- start flashing loading message
function()
emuObj.ThrottleMax()
end
 
local TH2B = -- pause loading message
function()
emuObj.ThrottleNorm()
end
 
local TH2C = -- unpause loading message
function()
emuObj.ThrottleMax()
end
 
local TH2D = -- end loading message
function()
emuObj.ThrottleNorm()
end
 
 
 
local showdownLoading = false
 
local TH3A = -- draw "Loading" on Showdown info screen
function()
if showdownLoading == false then
emuObj.ThrottleMax()
showdownLoading = true
end
end
 
local TH3B = -- draw "Press START" on Showdown info screen
function()
if showdownLoading == true then
emuObj.ThrottleNorm()
showdownLoading = false
end
end
 
 
local WH1 = -- update 16:9 flag
function()
local isWidescreen = eeObj.GetGpr(gpr.a0)
if isWidescreen == 0 then
emuObj.SetDisplayAspectNormal()
else
emuObj.SetDisplayAspectWide()
end
end
 
local WH2 = -- init universal data
function()
local v1 = eeObj.GetGpr(gpr.v1)
eeObj.SetGpr(gpr.v1, v1 | 1) -- enable widescreen
end
 
local WH3 = -- end of boot up sequence
function()
local universalData = eeObj.ReadMem32(GLOBALS_UNIVERSALDATA_ADDRESS)
local isWidescreen = eeObj.ReadMem32(universalData + 92) & 1
 
eeObj.WriteMem8(GFXPIPELINE_16BY9_ADDRESS, isWidescreen)
 
if isWidescreen == 0 then
emuObj.SetDisplayAspectNormal()
else
emuObj.SetDisplayAspectWide()
end
end
 
 
 
-- unthrottle loading screens
local thr1a = eeObj.AddHook(0x21e02c, 0x0080982d, TH1A) -- <staNewLoadShow::Enter(void)>:
local thr1b = eeObj.AddHook(0x220100, 0x27bdfff0, TH1B) -- <staNewLoadShow::DoThreadedLoadShow(void)>:
local thr2a = eeObj.AddHook(0x233970, 0x27bdfff0, TH2A) -- <ThreadedLoadingMessage::Start(void)>:
local thr2b = eeObj.AddHook(0x233a30, 0x27bdfff0, TH2B) -- <ThreadedLoadingMessage::Pause(void)>:
local thr2c = eeObj.AddHook(0x233a80, 0x3c02004f, TH2C) -- <ThreadedLoadingMessage::Unpause(void)>:
local thr2d = eeObj.AddHook(0x2339d8, 0x27bdfff0, TH2D) -- <ThreadedLoadingMessage::Stop(void)>:
local thr3a = eeObj.AddHook(0x226110, 0x8e850008, TH3A) -- <staNewLoadShow::DrawMultiplayerInfo(void)>:
local thr3b = eeObj.AddHook(0x226058, 0x8e650008, TH3B) -- <staNewLoadShow::DrawMultiplayerInfo(void)>:
 
-- widescreen support
local wide1 = eeObj.AddHook(0x3b9050, 0x46010003, WH1) -- <gfxPipeline::Set16By9(bool)>:
local wide2 = eeObj.AddHook(0x180f90, 0x00641824, WH2) -- <swcSaveUniversalData::swcSaveUniversalData(void)>:
local wide3 = eeObj.AddHook(0x102b70, 0x24040003, WH3) -- <gmGame::DoBootUpSequence(void)>:
 
</pre>
 
====Psychonauts====
SLUS_211.20
<br>CLI
<pre>--vu1-jr-cache-policy=sameprog
--vu1-jalr-cache-policy=sameprog
--ee-hook=0x101fc0,FastForwardClock,0x3c0f0036
--ee-hook=0x110390,FastForwardClock,0x8d8f0000
--ee-hook=0x101c10,FastForwardClock,0x51cf0052
--gs-vert-precision=8
--gs-kernel-cl="h2lpool"
--gs-kernel-cl-up="h2lpool2x2"
--gs-render-tile-threshold=300000
--vu-custom-min-max=0
--vu1-di-bits=0
--vu0-di-bits=0
--vu1-opt-vf00=2
--vu0-opt-vf00=2
--vu1-injection=1
--vu1-mpg-cycles=666
--vu1-mpg-cycles=1166,$000
--vu1-mpg-cycles=950,0xffffffff
--vu0-mpg-cycles=300,0xfc
--ee-hook=0x127630,AdvanceClock,0x27bdffd0,2100
--cdvd-sector-read-cycles=4000
--iop-cycle-scalar=1.6
#Seems like substantial performance fixes</pre>
 
SLUS_211.20
<br>LUA
<pre>-- psychonauts_slus21120
local gpr    = require("ee-gpr-alias")
local emuObj = getEmuObject()
 
apiRequest(1.0) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
-- Bug#9174 -
emuObj.SetGsTitleFix( "ignoreSubBuffCov", "reserved", { } )
 
-- Bug#9240 (Light maps uprender)
-- Copy z-buffer for future use with light maps. psm = SCE_GS_PSMZ24 (49)
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", {tw=9, th=9, psm=49, zmsk=1 } )
 
-- Apply light maps texMode=2 (bilinear)  psm= SCE_GS_PSMCT32 (0)
emuObj.SetGsTitleFix( "forceSimpleFetch", "reserved", {tw=8, th=8, psm=0, ztst=1, texMode=2 } )
 
-- Bug#9176
--
-- This bug seems GPUGS interpolation problem.
-- The game draws clouds as undiscovered area on the map, but
-- Z value is unstable --- sometimes 0x320, sometimes 0x321.
-- On drawing 'Highlight' object (which is missing one), it uses z=0x320 with
-- ZTST=GEQUAL. Therefore if the cloud renders with z=0x321, this highlighted object
-- doesn't appear. But it's OK on the real PS2 because of no-drawing right edge,
-- z=0x321 won't be available on the packet (interpolation differences between
-- the real PS2 and our gs)
-- it gives some values (50.0f) to get +1 on Z value for the highlighted object.
-- this value will be used later to create the packet in _sprite_ps2_push_data(ESprite*).
--
-- This old one causes a problem on some other scenes.
-- local eeObj = getEEObject()
-- eeObj.AddHook(0x1b276c, 0xe4400024, function()
-- local v0 = eeObj.GetGpr(gpr.v0)
-- local z  = eeObj.ReadMemFloat(v0+32)
-- eeObj.WriteMemFloat(v0+32, z+50.0)
-- end)
-- New one by Ernesto :
-- The idea is to apply the offset only on the marker.
local eeObj = getEEObject()
local adjustMapZHook = function() -- EMapRenderWindow::drawHighlightSprites
    eeObj.SetFpr(14, eeObj.GetFpr(14) + 50.0)
end
eeObj.AddHook(0x25d654, 0x8de40068, adjustMapZHook) -- \/
eeObj.AddHook(0x25d714, 0xe7b500cc, adjustMapZHook) -- /\
eeObj.AddHook(0x25d7d0, 0xe7b500cc, adjustMapZHook) -- <
eeObj.AddHook(0x25d894, 0x46000386, adjustMapZHook) -- >
 
 
-- bug#9423 - menus render 20+ times over again, causing very low fps.
-- The whole game in general has no concept of pacing and will re-draw frames multiple times
-- between vsync refreshes.  Hook placed on GameApp::EndFrame() measures time between frames and
-- if it's too short, the EE clock is advanced significantly to compensate.
 
local last_time = 0
local last_diff = 0
local advanceClockForAny = function()
local thistime = eeObj.GetClock()
local diff = thistime - last_time
local adv  = 0
 
if diff <= 0 then
-- sanity check, mostly for snapshot restore.
last_diff = diff
last_time = thistime
return
end
-- EE @ 30fps == roughly 10 million cycles
-- bug#9555 - We need to make a reasonable tally of VIF cycles across game display swaps.
--  Use a combination heuristic of EE and VIF1 cycles to gues at whether the title should
--  lock to 45fps, 30fps, or something worse.
local fastminEE = 1600000 -- less than this it's safe to run > 30 fps
local fastminVIF_30 = 2200000 -- VU1 total that merits 30hz throttle
local fastminVIF_45 = 1700000 -- VU1 total that merit 45hz throttle.
local baremin_wo_vif= 6100000 -- EE values below this get promoted to this value  (~50hz)
local forced30hz = 9330000
local forced45hz = 7820000
local vif1_cycles = eeObj.GetVif1Cycles()
if (vif1_cycles > forced30hz) then
vif1_cycles = forced30hz
end
 
local diff_vif = diff + vif1_cycles
adv = adv + vif1_cycles
 
-- Lock anything that seems like "Real Work" to either 30 or 45 FPS:
if diff_vif < fastminEE then
adv = adv + (fastminEE*2 - diff_vif)
elseif vif1_cycles > fastminVIF_30 and (diff+(fastminVIF_30)//2) < forced30hz then
adv = adv + (forced30hz  - diff - (fastminVIF_30)//2)
elseif vif1_cycles > fastminVIF_45 and (diff+(fastminVIF_45)//2) < forced45hz then
adv = adv + (forced45hz  - diff - (fastminVIF_45)//2)
elseif diff < baremin_wo_vif then
adv = adv + (baremin_wo_vif  - diff)
end
 
-- print (string.format("DELTA: %d  ADV: %d  VIF1: %d", diff, adv, vif1_cycles))
 
if adv ~= 0 then
eeObj.AdvanceClock(adv)
end
 
-- Ensure next frame's delta time takes into consideration this frame's advancement.
-- Otherwise each fraem delta time would get progressively worse.
 
thistime = thistime + adv
last_time = thistime
last_diff = diff
end
 
local advanceClockForGame = function() advanceClockForAny(5300000, 2700000) end
eeObj.AddHookJT(0x207cf8, 0x27bdfff0, advanceClockForGame)   -- <GameApp::EndFrame()>:
#Performance and optimisations</pre>
 
====Red Faction====
SLUS_200.73
<br>CLI
<pre>--gs-use-deferred-l2h=1
--l2h-2d-params=0x0000000800000001,0x000000003a0a2300,512,2
--vu1=jit-sync
--ee-cycle-scalar=1.02
--ee-hook=0x00213370,FastForwardClock,0x8F8293A8
--ee-hook=0x24ce30,AdvanceClock,0x8c620000,20000
--ee-hook=0x272b44,FastForwardClock,0x3c0201ee
--ee-hook=0x272bc4,FastForwardClock,0x3c0201ee
--ee-hook=0x21b354,AdvanceClock,0x3c031000,0x1240
#performance fixes.</pre>
 
SLUS_200.73
<br>LUA
<pre>-- Red Faction [US]
 
apiRequest(1.6)
local gpr = require("ee-gpr-alias")
 
-- title uses memcpy() to write to VU1 memory, so some instances will be hotfixed to
-- use slowpath_memcpy() at runtime.
 
eeNativeFunction(0x259820, 0x0080402d, 'memcpy')
eeNativeFunction(0x2599d8, 0x2cc20008, 'memset')
 
eeNativeFunction(0x253870, 0x27bdffd0, 'ieee754_acosf')
eeNativeFunction(0x254620, 0x44026000, 'ieee754_sqrtf')
eeNativeFunction(0x255a50, 0x44026000, 'cosf')
eeNativeFunction(0x255df0, 0x44026000, 'sinf')
eeNativeFunction(0x256318, 0x27bdffa0, 'acosf')
 
eeInsnReplace(0x24d7e0, 0x24030064, 0x03e00008)                -- <FlushCache>
eeInsnReplace(0x24d7e4, 0x0000000c, 0x00000000)
eeNativeHook (0x24d7e0, 0x03e00008,'AdvanceClock',0xa00)
eeInsnReplace(0x24d810, 0x2403ff98, 0x03e00008)                -- <iFlushCache>
eeInsnReplace(0x24d814, 0x0000000c, 0x00000000)
eeNativeHook (0x24d810, 0x03e00008,'AdvanceClock',0xa00)
 
eeInsnReplace(0x24de20, 0x27bdffe0, 0x03e00008)                -- <SyncDCache>
eeInsnReplace(0x24de24, 0x0080302d, 0x00000000)
eeNativeHook (0x24de20, 0x03e00008,'AdvanceClock',0x600)
eeInsnReplace(0x24de98, 0x3c02ffff, 0x03e00008)                -- <iSyncDCache>
eeInsnReplace(0x24de9c, 0x3442ffc0, 0x00000000)
eeNativeHook (0x24de98, 0x03e00008,'AdvanceClock',0x600)
eeInsnReplace(0x24df58, 0x27bdffe0, 0x03e00008)                -- <InvalidDCache>
eeInsnReplace(0x24df5c, 0x0080302d, 0x00000000)
eeNativeHook (0x24df58, 0x03e00008,'AdvanceClock',0x600)
eeInsnReplace(0x24dfd0, 0x3c02ffff, 0x03e00008)                -- <iInvalidDCache>
eeInsnReplace(0x24dfd4, 0x3442ffc0, 0x00000000)
eeNativeHook (0x24dfd0, 0x03e00008,'AdvanceClock',0x600)
 
local emuObj = getEmuObject()
local eeObj = getEEObject()
 
-- bug#10159 workaround
-- slowdown the jeep speed....
 
local jeepObj = 0
eeObj.AddHook(0x1376f0, 0xc6600174, function()
jeepObj = eeObj.GetGpr(gpr.s1)
end)
eeObj.AddHook(0x137a48, 0xc7ac00bc, function()
local s1 = eeObj.GetGpr(gpr.s1)
if s1 == jeepObj then
eeObj.SetFpr(12, eeObj.GetFpr(12)*0.90)
end
end)
 
-- bug#10249 workaround
-- forcibly calculate the jeep's suspension.
eeObj.AddHook(0x19ee08, 0x8ec2120c, function()
if jeepObj - 624 == eeObj.GetGpr(gpr.s6) then
eeObj.SetGpr(gpr.v0, 1)
end
end)
 
-- debug code for jeep movment target.
-- local px = 0.0
-- local pz = 0.0
-- eeObj.AddHook(0x1375bc, 0x26650174, function()
-- local s1 = eeObj.GetGpr(gpr.s1)
-- if s1 == jeepObj then
-- local s3 = eeObj.GetGpr(gpr.s3)
-- px = eeObj.ReadMemFloat(s3 + 372)
-- pz = eeObj.ReadMemFloat(s3 + 380)
-- end
-- end)
-- eeObj.AddHook(0x1375c8, 0xa2620170, function()
-- local s1 = eeObj.GetGpr(gpr.s1)
-- if s1 == 0x19a7a00 then
-- local s3 = eeObj.GetGpr(gpr.s3)
-- local x = eeObj.ReadMemFloat(s3 + 372)
-- local z = eeObj.ReadMemFloat(s3 + 380)
-- if px ~= x or pz ~= z then
--   print(string.format("[%f %f] => [%f %f] v0=%d",
--   px, pz, x, z, eeObj.GetGpr(gpr.v0)))
-- end
--  end
-- end)
#physics calculations and performance fix.</pre>
 
SLUS_200.73
<br>SLUS-20073_features.lua
<pre>-- Lua 5.3
-- Title:  Red Faction PS2 - SLUS-20073 (USA)
-- Author:  Ernesto Corvi, Adam McInnis
 
-- Changelog:
 
apiRequest(1.1) -- request version 1.1 API. Calling apiRequest() is mandatory.
 
local eeObj = getEEObject()
local emuObj = getEmuObject()
 
local L1 =  -- main
function()
emuObj.ThrottleMax()
end
local L2 =  -- main
function()
emuObj.ThrottleNorm()
end
local load1 = eeObj.AddHook(0x165590, 0x27bdffb0, L1) -- game_load_level
local load2 = eeObj.AddHook(0x16578C, 0x7bb10010, L2) -- game_load_level
 
-- Widescreen support --
eeInsnReplace(0x2071c4, 0x00000000, 0x3c013f40) -- gr_setup_3d
eeInsnReplace(0x2071d0, 0x00000000, 0x4481f000) -- gr_setup_3d
eeInsnReplace(0x2072e0, 0x00000000, 0x461ea502) -- gr_setup_3d
eeInsnReplace(0x2072e8, 0x00000000, 0x461ead43) -- gr_setup_3d
eeInsnReplace(0x23a34c, 0x44826000, 0x461e0303) -- shadow_ngps_render_and_copy
eeInsnReplace(0x23a444, 0x3c024334, 0x3c024309) -- shadow_ngps_render_and_copy
emuObj.SetDisplayAspectWide()
#Official widescreen support.</pre>
 
====Red faction II====
CUSA06356
<br>CLI
<pre>
--gs-use-deferred-l2h=0
--l2h-2d-params=0x0000000800000001,0x000000003a083000,612,2
--mtap1=disabled
--mtap2=disabled
</pre>
====Resident Evil Code: Veronica X====
ALL
<br>CLI
<pre>--ee-jit-pagefault-threshold=30
#crash fix.</pre>
 
ALL
<br>LUA
<pre>-- VeronicaX
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
-- Bug# 9976
local emuObj = getEmuObject()
emuObj.SetGsTitleFix( "clipScissors", "reserved", {alpha = 0 , frameW = 4 , psm = 0} )
#graphical fix.</pre>
 
====Rogue Galaxy====
ALL
<br>CLI
<pre>--gs-kernel-cl-up="up2x2skipinterp"
--gs-optimize-30fps=1
#visual fixes and performance optimisation.</pre>
 
SCUS_974_90
<br>LUA
<pre>require("ee-gpr-alias")
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
-- Bug#8404 WORKAROUND
-- See https://pss.usrd.scea.com/bugzilla/show_bug.cgi?id=8404
eeInsnReplace(0x124898, 0x3442ffff, 0x3442fffe) -- ori v0,v0,0xffff
#unsure what this fixes.</pre>
 
====Rise of the Kasai====
'''CLI'''
<br>SCUS-97416
<pre>
--gs-kernel-cl-up="up2x2skipinterp"
--cdvd-sector-read-cycles=31000
--iop-cycle-scalar=0.7
</pre>
 
 
'''LUA'''
<br>SCUS-97416
<pre>
-- rise_of_kasai
require("ee-gpr-alias")
 
apiRequest(0.1) -- request version 0.1 API. Calling apiRequest() is mandatory.
 
 
local emuObj = getEmuObject()
local eeObj  = getEEObject()
 
-- bug #9037.
-- Force point sampling when max mip map > 0 and min filter is set to nearest( 0). 
-- This is done generically when mipmaping is On , however  we prefer to disable mip maps for this title.
emuObj.SetGsTitleFix( "forcePoint", "reserved", {mipIsGt=0,  mmin=0} )
 
-- bug#9241
-- SwapMemCard to Mark of Kri
-- bug#136347 (SCEI bugzilla)
-- we re-use US image for Rise of Kasai EU package and want to let use be able to have Mark of Kri completion bonus.
-- unfortunately we don't have any ways to distinguish which PS4 package we are working on.
-- instead of US => EU reading out modification, let the game retry EU saved data when it fails.
--
-- NOTE: you can write down the filepath directly(onto strptr) at boot time if we can distinguish the differences of the packages.
local first_attempt = true
local buffer = -1
local strptr = -1
local write_str = function (ptr, str)
  for i=1,string.len(str) do
  eeObj.WriteMem8(ptr + i - 1, string.byte(str, i, i))
  end
end
eeObj.AddHook(0x1aa904, 0x0040382d, function()
strptr = eeObj.GetGpr(gpr.a2)
local fname = eeObj.ReadMemStr(strptr)
-- print(string.format("%s", fname))
if fname == "BASCUS-97140/BASCUS-97140" then
if first_attempt then
  buffer = eeObj.GetGpr(gpr.a3)
  --print("Trying to read out SCUS-97140 Mark of Kri US saved data");
  --print(string.format("%x:ReadFile(%x, %x, %x)", eeObj.GetGpr(gpr.a0), 0, eeObj.GetGpr(gpr.a2), eeObj.GetGpr(gpr.a3)))
  emuObj.SwapMemCard(0, 0, "SCUS-97140") -- 2nd argument, user-id isn't used in the current implementation.
else
  -- this is the case of re-trying : reading out EU mark of kri
  --print("Trying to read out SCES-51164 Mark of Kri EU saved data");
  write_str(strptr, "BESCES-51164/BESCES-51164")
  eeObj.SetGpr(gpr.a3, buffer);
  --print(string.format("%x:ReadFile(%x, %x, %x)", eeObj.GetGpr(gpr.a0), 0, eeObj.GetGpr(gpr.a2), eeObj.GetGpr(gpr.a3)))
  emuObj.SwapMemCard(0, 0, "SCES-51164")
end
end
end)
eeInsnReplace(0x1aa910, 0x10400020, 0x00000000)
eeObj.AddHook(0x1aa910, 0x00000000, function()
local v0 = eeObj.GetGpr(gpr.v0)
if v0 == 0 then -- failed
--print("File Load Failed")
if first_attempt then
  first_attempt = false
  eeObj.SetPc(0x1aa8fc)
else
  first_attempt = true
  eeObj.SetPc(0x1aa994)
end
end
end)
-- SwapMemCard to Rise of Kasai
eeObj.AddHook(0x1aa9e8, 0xdfbf0000, function()
emuObj.SwapMemCard(0, 0, "SCUS-97416")
write_str(strptr, "BASCUS-97140/BASCUS-97140") -- write back the original string to the place.
strptr = -1
buffer = -1
end)
</pre>
 
====Samurai Shodown Anthology====
SLUS_216.29
<br>CLI
<pre>--gs-upscale=point
--gs-uprender=2x2
--gs-motion-factor=25
--host-audio-latency=0.01
--gs-ignore-dirty-page-border=1
--gs-kernel-cl="h2lpool"
--gs-kernel-cl-up="h2lpool2x2"
--gs-h2l-list-opt=1
--gs-h2l-accurate-hash=1
</pre>
<br>LUA
<pre>-- Lua 5.3
-- Title: Samurai Shodown Anthology - SLUS-21629 (USA) v1.01
-- Author: Nicola Salmoria
-- Date: October 12, 2016
 
 
local gpr = require( "ee-gpr-alias" )
 
apiRequest(1.6)
 
local eeObj = getEEObject()
local emuObj = getEmuObject()
 
local kFilterMode, kWrapMode, kBlendMultiplier, kBlendFunc = require("sprite")
local PadConnectType = require("pad-connect-type")
 
 
local BRIGHT_ADDRESS = 0x7803fc
local BRIGHT_DESCRIPTION_ADDRESS = 0x4d8380
local SETTINGS_ADDRESS = 0x756900
 
-- a free memory location for our perusal
local DISPLAYMODE_STRING_ADDRESS = 0xf7000
 
local sprite0 = getSpriteObject(0)
local sprite1 = getSpriteObject(1)
 
-- 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(2)
local spr_p2_notify = getSpriteObject(3)
local spr_p1d_notify = getSpriteObject(4)
local spr_p2d_notify = getSpriteObject(5)
 
-- 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 STATE_STOPPED = 0
local STATE_RUNNING = 1
 
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 notify_frames_p1 = 0
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
 
-- ---------------------------------------------------
-- 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_SL480_p.sb") -- (1) = 480P ScanLine Sim
 
texture1.Load("./ART1.png")
texture2.Load("./ART2.png")
texture3.Load("./SNK_LOGO.png")
texture4.Load("./p1.png")
texture5.Load("./p2.png")
texture6.Load("./p1d.png")
texture7.Load("./p2d.png")
 
local p1_w,p1_h = texture4.GetSize()
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
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)
end
 
 
local update_notifications_p1 = function()
 
if notify_animstate_p1 == STATE_STOPPED then
spr_p1_notify.Disable()
spr_p1d_notify.Disable()
return
end
 
emuObj.ThrottleNorm()
 
local keyframe = 15
 
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("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("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
 
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
 
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 update_notifications_p2 = function()
 
if notify_animstate_p2 == STATE_STOPPED then
spr_p2_notify.Disable()
spr_p2d_notify.Disable()
return
end
 
emuObj.ThrottleNorm()
 
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("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("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)
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
 
-- 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)
spr_p1_notify.Disable()
spr_p1d_notify.Disable()
spr_p2_notify.Disable()
spr_p2d_notify.Disable()
-- print(string.format("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
 
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
-- ---------------------------------------------------
 
local original = function()
sprite0.BindTexture(0)
sprite0.BindFragmentShader(0)
sprite0.SetPosXY((1920-1440)/2,0)
sprite0.SetSizeXY(1440,1080)
sprite0.Enable()
 
sprite1.Disable()
end
 
-- ---------------------------------------------------
-- Full Screen + ScanLines (480p)
-- ---------------------------------------------------
 
local scanlines = function()
sprite0.BindTexture(0)
sprite0.SetPosXY((1920-1440)/2,0)
sprite0.SetSizeXY(1440,1080)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.Enable()
 
sprite1.Disable()
end
 
-- ---------------------------------------------------
-- SNK Overlay NoFX
-- ---------------------------------------------------
local bezel = function()
sprite0.BindTexture(0)
sprite0.BindFragmentShader(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.Enable()
 
sprite1.BindTexture(1)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
 
-- ---------------------------------------------------
-- SNK Overlay + ScanLines (480p)
-- ---------------------------------------------------
 
local bezel_scanlines = function()
sprite0.BindTexture(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.Enable()
 
sprite1.BindTexture(1)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
 
-- ---------------------------------------------------
-- Arcade Overlay NoFX
-- ---------------------------------------------------
local bezel2 = function()
sprite0.BindTexture(0)
sprite0.BindFragmentShader(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.Enable()
 
sprite1.BindTexture(2)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
 
-- ---------------------------------------------------
-- Arcade Overlay + ScanLines (480p)
-- ---------------------------------------------------
 
local bezel2_scanlines = function()
sprite0.BindTexture(0)
sprite0.SetPosXY((1920-1280)/2, (1080-896)/2)
sprite0.SetSizeXY(1280,896)
sprite0.BindFragmentShader(1)
sprite0.SetShaderParams(scanlineParams)
sprite0.Enable()
 
sprite1.BindTexture(2)
sprite1.SetPosXY(0,0)
sprite1.SetSizeXY(1920,1080)
sprite1.SetPosUV(0,0)
sprite1.SetSizeUV(1920,1080)
sprite1.Enable()
end
 
 
local logoON = function()
emuObj.ThrottleMax()
 
sprite0.BindTexture(3)
sprite0.SetPosXY(0,0)
sprite0.SetSizeXY(1920,1080)
sprite0.SetPosUV(0,0)
sprite0.SetSizeUV(1920,1080)
sprite0.Enable()
 
sprite1.Disable()
end
 
 
local VIDEOMODE_ORIGINAL = 256
local VIDEOMODE_SCANLINES = 251
local VIDEOMODE_ART1 = 252
local VIDEOMODE_ART1_SCANLINES = 253
local VIDEOMODE_ART2 = 254
local VIDEOMODE_ART2_SCANLINES = 255
 
local videoModes = {
[VIDEOMODE_ORIGINAL ] = "ORIGINAL",
[VIDEOMODE_SCANLINES ] = "SCANLINES",
[VIDEOMODE_ART1 ] = "ART1",
[VIDEOMODE_ART1_SCANLINES ] = "ART1 + SCANLINES",
[VIDEOMODE_ART2 ] = "ART2",
[VIDEOMODE_ART2_SCANLINES ] = "ART2 + SCANLINES",
}
 
local lastVideoMode = nil
 
local function switchVideoMode(mode)
if lastVideoMode ~= mode then
lastVideoMode = mode
 
emuObj.ThrottleNorm()
if mode == VIDEOMODE_ORIGINAL then
original()
elseif mode == VIDEOMODE_SCANLINES then
scanlines()
elseif mode == VIDEOMODE_ART1 then
bezel()
elseif mode == VIDEOMODE_ART1_SCANLINES then
bezel_scanlines()
elseif mode == VIDEOMODE_ART2 then
bezel2()
elseif mode == VIDEOMODE_ART2_SCANLINES then
bezel2_scanlines()
end
end
end
 
 
 
local FH1 = -- printf
function()
eeObj.SetGpr(gpr.ra, 0x11afd0) -- <LoadExecPS2>:
eeObj.SetGpr(gpr.a0, 0x348710) -- "cdrom0:\S6\NO1_E.ELF;1"
eeObj.SetGpr(gpr.a1, 0)
eeObj.SetGpr(gpr.a2, 0)
 
-- also turn on the SNK logo (it will be implicitly tuned off after video mode settings are applied)
logoON()
end
 
local FH2A = -- increment main menu option
function()
local v1 = eeObj.GetGpr(gpr.v1)
if v1 == 7 then
eeObj.SetGpr(gpr.v1, 8) -- skip "exit to main menu"
end
end
 
local FH2B = -- decrement main menu option
function()
local v1 = eeObj.GetGpr(gpr.v1)
if v1 == 7 then
eeObj.SetGpr(gpr.v1, 6) -- skip "exit to main menu"
end
end
 
local FH2C = -- get pointer of "exit to main menu" string
function()
local strPtr = eeObj.GetFprHex(0)
eeObj.WriteMem8(strPtr, 0) -- erase the string
end
 
 
local FH3 =
function()
local msgId = eeObj.GetGpr(gpr.a0)
if msgId == 5 then
eeObj.SetGpr(gpr.v1, 9) -- skip message
end
end
 
 
local FH4A = -- increment the BRIGHT value
function()
local bright = eeObj.ReadMem32(BRIGHT_ADDRESS)
 
local next = bright + 1
if next > 256 then
next = 251
end
 
eeObj.SetGpr(gpr.a0, next)
end
 
local FH4B = -- decrement the BRIGHT value
function()
local bright = eeObj.ReadMem32(BRIGHT_ADDRESS)
 
local next = bright - 1
if next < 251 then
next = 256
end
 
eeObj.SetGpr(gpr.a0, next)
end
 
 
local function forceBright(register)
local bright = eeObj.GetGpr(register)
 
-- update the video mode
switchVideoMode(bright)
 
-- force brightness to 100%
eeObj.SetGpr(register, 256)
end
 
local FH5A = -- read BRIGHT setting
function()
forceBright(gpr.a2)
end
local FH5B = -- read BRIGHT setting
function()
forceBright(gpr.a0)
end
local FH5C = -- read BRIGHT setting
function()
forceBright(gpr.v1)
end
local FH5D = -- read BRIGHT setting
function()
forceBright(gpr.t4)
end
 
 
local FH6 = -- get label for game option
function()
local v1 = eeObj.GetGpr(gpr.v1)
 
if v1 == 8 then
eeObj.WriteMemStrZ(DISPLAYMODE_STRING_ADDRESS, "DISPLAY")
eeObj.SetGpr(gpr.v0, DISPLAYMODE_STRING_ADDRESS)
 
eeObj.WriteMemStrZ(BRIGHT_DESCRIPTION_ADDRESS, "The display mode can be changed")
end
end
 
 
local FH7 = -- get description for BRIGHT option
function()
local bright = eeObj.ReadMem32(BRIGHT_ADDRESS)
local sp = eeObj.GetGpr(gpr.sp)
eeObj.WriteMemStrZ(sp + 128, videoModes[bright])
end
 
 
local FH8 = -- initialize settings
function()
eeObj.WriteMem32(SETTINGS_ADDRESS + 0xafe8, 1) -- auto save enabled
end
 
 
-- register hooks
 
local CHKDATA_MAIN = 0x3c04001d
local CHKDATA_SS6  = 0x3c040056
 
local elfChkMain = function(opcode, pc, expectedOpcode)
local chkData = eeObj.ReadMem32(0x100198)
 
if chkData == CHKDATA_MAIN then
assert(opcode == expectedOpcode, string.format("Overlay opcode mismatch @ 0x%06x: expected 0x%08x, found %08x", pc, expectedOpcode, opcode))
return true
else
return false
end
end
 
local elfChkSS6 = function(opcode, pc, expectedOpcode)
local chkData = eeObj.ReadMem32(0x100198)
 
if chkData == CHKDATA_SS6 then
assert(opcode == expectedOpcode, string.format("Overlay opcode mismatch @ 0x%06x: expected 0x%08x, found %08x", pc, expectedOpcode, opcode))
return true
else
return false
end
end
 
local hooks = {
-- load Samurai Shodown VI on startup
eeObj.AddHook(0x100850, function(op, pc) return elfChkMain(op, pc, 0xdfbf0030) end, FH1),
 
-- skip "exit to main menu" menu option
eeObj.AddHook(0x24bd84, function(op, pc) return elfChkSS6(op, pc, 0x00001810) end, FH2A),
eeObj.AddHook(0x24bf90, function(op, pc) return elfChkSS6(op, pc, 0x00001810) end, FH2B),
-- hide "exit to main menu" menu option
eeObj.AddHook(0x1cae4c, function(op, pc) return elfChkSS6(op, pc, 0xe7a00080) end, FH2C),
 
-- skip "There is no SAMURAI SHODOWN -ANTHOLOGY- data on the memory card" message
eeObj.AddHook(0x2a4d3c, function(op, pc) return elfChkSS6(op, pc, 0x24030007) end, FH3),
 
-- increment/decrement BRIGHT setting: replace with clamp to range 251-256
eeObj.AddHook(0x27ba2c, function(op, pc) return elfChkSS6(op, pc, 0x00642021) end, FH4A),
eeObj.AddHook(0x27bc34, function(op, pc) return elfChkSS6(op, pc, 0x00642021) end, FH4B),
 
-- force screen brightness to max
eeObj.AddHook(0x2aa740, function(op, pc) return elfChkSS6(op, pc, 0x8c6603fc) end, FH5A),
eeObj.AddHook(0x2aaab8, function(op, pc) return elfChkSS6(op, pc, 0x8c6403fc) end, FH5B),
eeObj.AddHook(0x2ad2f0, function(op, pc) return elfChkSS6(op, pc, 0x8c4303fc) end, FH5C),
eeObj.AddHook(0x2ad950, function(op, pc) return elfChkSS6(op, pc, 0x8c4303fc) end, FH5C),
eeObj.AddHook(0x2addb4, function(op, pc) return elfChkSS6(op, pc, 0x8c4303fc) end, FH5C),
eeObj.AddHook(0x2ae2c8, function(op, pc) return elfChkSS6(op, pc, 0x8c6c03fc) end, FH5D),
eeObj.AddHook(0x2ae4e4, function(op, pc) return elfChkSS6(op, pc, 0x8c6c03fc) end, FH5D),
 
-- patch BRIGHT label
eeObj.AddHook(0x1c8dec, function(op, pc) return elfChkSS6(op, pc, 0x2463ffff) end, FH6),
eeObj.AddHook(0x1c9dc4, function(op, pc) return elfChkSS6(op, pc, 0x2463ffff) end, FH6),
 
-- patch BRIGHT description
eeObj.AddHook(0x1c958c, function(op, pc) return elfChkSS6(op, pc, 0x24020006) end, FH7),
 
-- enable AUTO SAVE on first boot
eeObj.AddHook(0x2a5ebc, function(op, pc) return elfChkSS6(op, pc, 0x3c040076) end, FH8),
}
 
 
-- Fight stick
 
HIDPad_Enable()
 
local addedHooks = false
local pad = function()
if addedHooks == false then
addedHooks = true
emuObj.AddVsyncHook(update_notifications_p1)
emuObj.AddVsyncHook(update_notifications_p2)
 
-- bug report:
-- Sound volume: The sound is extremely louder than previous titles.
-- <PS4 recommendation>      -24LKFS(±2)
-- <The current game sound> -11.59LUFS
--
-- So set main volume to 0.25 i.e. about 12dB attenuation.
emuObj.SetVolumes(0.25, 1.0, 1.0)
end
end
emuObj.AddPadHook(onHIDPadEvent)
emuObj.AddEntryPointHook(pad)
 
 
 
 
-- Credits
 
-- Trophy design and development by SCEA ISD SpecOps
-- David Thach Senior Director
-- George Weising Executive Producer
-- Tim Lindquist Senior Technical PM
-- Clay Cowgill Engineering
-- Nicola Salmoria Engineering
-- Jenny Murphy Producer
-- David Alonzo Assistant Producer
-- Tyler Chan Associate Producer
-- Karla Quiros Manager Business Finance & Ops
-- Special thanks to A-R&D
</pre>
====Forbidden Siren====
<br>CLI
<pre>
--ee-context-switch-cycles=1440
</pre>


====Star Ocean 3====
====Star Ocean 3====
Please note that all contributions to PS4 Developer wiki are considered to be released under the GNU Free Documentation License 1.2 (see PS4 Developer wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:

Cancel Editing help (opens in new window)