I have the gist of how the LUA works but am entirely out of my depth with acquiring 64bit addresses. FWS hack-injects into a game to change the UI & FOV values to support ultrawide resolutions.
I've pointed this LUA for Skyrim LE to look for Speacial Edition but the addresses it grabs are not correct for Special Edition which is the section that needs updating. Whoever figures it out, this would obviously go to the gaming community to use for FWS.
Code: Select all
require(GlobalDependencys:GetDependency("StandardBase"):GetPackageName())
--GAME VARS
fWorldAdditionalFOV = 10
fHandsAdditionalFOV = 15
fDefaultHandsFOV = 65
fDefaultWorldFOV = 65
fDefaultAspectRatio = 1.777777791
fDefaultScaleValue = 0.133333333
fDefaultModelScale = 75
fDefaultRaceSexMenu = 100
fNewScaleValue = 0
fMouseSensitivity = 0.75
fFOVMax = 110
bDefaultItemScale = false
fDefaultSkyUIMagicItem_PosX = -29
fDefaultSkyUIMagicItem_PosY = 12
fDefaultSkyUIMagicItem_Scale = 1.5
fDefaultMagicItem_PosX = 22
fDefaultMagicItem_PosY = 12
fDefaultMagicItem_Scale = 1.5
fDefaultSkyUIInventoryItem_PosX = -29
fDefaultSkyUIInventoryItem_PosY = 12
fDefaultSkyUIInventoryItem_Scale = 1.5
fDefaultSkyUIInventoryItem_ZoomedScale = 2.25
fDefaultInventoryItem_PosX = -22
fDefaultInventoryItem_PosY = 12
fDefaultInventoryItem_Scale = 1.5
fDefaultInventoryItem_ZoomedScale = 2.25
--ControlVars
FOVWriteThreshold = 0
FOVChanging = false
bHandsFOV = true
bSkyUI = false
bWorldFOV = true
bMouseSensitivity = true
bHUDFix = true
bFixEnabled = true
--PROCESS VARS
Process_FriendlyName = Module:GetFriendlyName()
Process_WindowName = "Skyrim"
Process_ClassName = "Skyrim Special Edition"
Process_EXEName = "SkyrimSE.exe"
--INJECTION BEHAVIOUR
InjectDelay = 250
WriteInterval = 200
SearchInterval = 10
SuspendThread = true
--Name Manual/Auto/Hybrid Steam/Origin/Any IncludeFile:Configure;Enable;Periodic;Disable;
SupportedVersions = {
{"Automatically Detect", "Hybrid", "Any", "Configure_SignatureScan;Enable_Inject;Periodic;Disable_Inject;"},
}
function Init_Controls()
DefaultControls.AddHeader("HeaderWorld_FOV","World FOV Fine adjustment",15,70,210,17)
DefaultControls.AddFOVSlider("WorldFOVSlider","WorldFOVSlider_Changed",55,100,125,35,145)
DefaultControls.AddHeader("HeaderHands_FOV","Hands FOV Fine adjustment",15,160,210,17)
DefaultControls.AddFOVSlider("HandsFOVSlider","HandsFOVSlider_Changed",55,190,125,35,145)
DefaultControls.AddHeader("HeaderMouseSense","Mouse Sensitivity",15,250,210,17)
DefaultControls.AddFOVSlider("MouseSenseSlider","MouseSenseSlider_Changed",55,280,125,35,75)
DefaultControls.AddHeader("Header_FixesEnableDisable","Individual Fixes",245,70,210,17)
DefaultControls.AddFixToggle("CKFOVFix_World_Enable","World FOV","CKFOVFix_World_Changed",255,101,180,14)
DefaultControls.AddFixToggle("CKFOVFix_Hands_Enable","Hands FOV","CKFOVFix_Hands_Changed",255,120,180,14)
DefaultControls.AddFixToggle("CKMouseSensitivity_Enable","Mouse Sensitivity","CKMouseSensitivity_Changed",255,139,180,14)
DefaultControls.AddFixToggle("CKHUDFix_Enable","HUD Fix","CKHUDFix_Changed",255,158,180,14)
DefaultControls.AddFixToggle("CKSkyUI_Enable","Using SkyUI","CKSkyUI_Changed",255,177,180,14,false)
end
function Configure_SignatureScan()
local tAddress = HackTool:AddAddress("HUDFix")
if HackTool:SignatureScan("89??????89??????8D??????FF??83????C2??00",tAddress,PAGE_EXECUTE_READ,0x8,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("ReferenceResolution")
if HackTool:SignatureScan("C644??????E8????????DB05????????83????DA35",tAddress,PAGE_EXECUTE_READ,0xA,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
tAddress:AcquireAddress(0x2)
tAddress:OffsetAddress(-0x4)
tAddress:AddSubOffset("Width",0x0)
tAddress:AddSubOffset("Height",0x4)
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("MouseValues")
if HackTool:SignatureScan("CC8B0D????????????A3",tAddress,PAGE_EXECUTE_READ,0x9,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
tAddress:AcquireAddress(0x1)
tAddress:AddSubOffset("MousePosX",0)
tAddress:AddSubOffset("MousePosY",0x4)
tAddress:AddSubOffset("Unknown1",0x8)
tAddress:AddSubOffset("Unknown2",0xC)
tAddress:AddSubOffset("Width",0x10)
tAddress:AddSubOffset("Height",0x14)
tAddress:AddSubOffset("XSensitivity",0x18)
tAddress:AddSubOffset("YSensitivity",0x1C)
tAddress:AddSubOffset("Unknown3",0x20)
tAddress:AddSubOffset("Unknown4",0x24)
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("UnscaleDialogs")
if HackTool:SignatureScan("83????0F85??000000D9??????D8",tAddress,PAGE_EXECUTE_READ,0x9,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("MapDetectOn")
if HackTool:SignatureScan("A1????????8D????89????E8????????8D",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("MapDetectOff")
if HackTool:SignatureScan("89????E8????????FF????8B??????C2",tAddress,PAGE_EXECUTE_READ,0x3,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("SkillsMouseHack")
if HackTool:SignatureScan("D9??????89??????D9??????????C6",tAddress,PAGE_EXECUTE_READ,0x8,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("RaceSexMenu")
if HackTool:SignatureScan("CC83??????????????83????89??????C7",tAddress,PAGE_EXECUTE_READ,0x4,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
tAddress:AcquireAddress(0x1)
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("MagicItems")
if HackTool:SignatureScan("89??????38??????????74??B9????????E8",tAddress,PAGE_EXECUTE_READ,0xC,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
tAddress:AcquireAddress(0x1)
tAddress:OffsetAddress(0x4)
tAddress:AddSubOffset("PosX",0)
tAddress:AddSubOffset("PosY",0x18)
tAddress:AddSubOffset("Scale",0x24)
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("InventoryItems")
if HackTool:SignatureScan("8B??????????74??A1????????8B??????????8B??????????8B??????????89",tAddress,PAGE_EXECUTE_READ,0x8,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
tAddress:AcquireAddress(0x1)
tAddress:AddSubOffset("PosX",0)
tAddress:AddSubOffset("PosY",0x18)
tAddress:AddSubOffset("Scale",0x24)
tAddress:AddSubOffset("ZoomedScale",0x60)
print( tAddress:GetInfo(TYPE_ADDRESS) )
end
local tAddress = HackTool:AddAddress("ModelScale")
if HackTool:SignatureScan("E8??????????8B??????????89????8B??????????E8????????8B??????????89",tAddress,PAGE_EXECUTE_READ,0x6,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
tAddress:AcquireAddress(0x2)
print( tAddress:GetInfo(TYPE_FLOAT) )
end
local tAddress = HackTool:AddAddress("FOV")
if HackTool:SignatureScan("8B0D????????8B????????0083????8B??80",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
local Offset = tAddress:ReadInt(0x8)
tAddress:AcquireAddress(0x2)
local tPointerChain = HackTool:AddPointerChain("FOV",tAddress)
tPointerChain:PushOffset(Offset)
tPointerChain:AddSubOffset("HandsFOV",0x0)
tPointerChain:AddSubOffset("WorldFOV",-0x4)
print( tPointerChain:GetInfo(TYPE_FLOAT) )
end
local tAddress = HackTool:AddAddress("nonRTFOV")
if HackTool:SignatureScan("E9????????8B0D????????8B????????00A1",tAddress,PAGE_EXECUTE_READ,0x11,Process_EXEName) == 0 then
return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
else
tAddress:AcquireAddress(0x1)
print( tAddress:GetInfo(TYPE_FLOAT) )
end
return true
end
function Enable_Inject()
local Variables = HackTool:AllocateMemory("Variables",0)
Variables:PushInt("HUDLeft")
Variables:PushInt("HUDTop")
Variables:PushInt("HUDWidth")
Variables:PushInt("HUDHeight")
Variables:PushFloat("MouseSenseX")
Variables:PushFloat("MouseSenseY")
Variables:PushInt("MouseCheckByte")
Variables:Allocate()
ResolutionChanged()
local asm = [[
(codecave:jmp)SkillsMouseHack,SkillsMouseHack_cc:
fild dword ptr [(allocation)Variables->HUDWidth]
fstp dword ptr [$$2+4h] $context=1
%originalcode%
jmp %returnaddress%
%end%
(codecave:jmp)MapDetectOff,MapDetectOff_cc:
cmp byte ptr [(allocation)Variables->MouseCheckByte], 0
je skipmdreset
mov byte ptr [(allocation)Variables->MouseCheckByte], 0
call ResetMousePosition
call SetMouseConstraints
skipmdreset:
%originalcode%
jmp %returnaddress%
%end%
(codecave:jmp)MapDetectOn,MapDetectOn_cc:
mov byte ptr [(allocation)Variables->MouseCheckByte], 1
%originalcode%
jmp %returnaddress%
%end%
(codecave:jmp)HUDFix,HUDFix_cc:
push ecx
cmp dword ptr [$$2+0Ch], 0h $context=1
jne skipleftoffset
cmp byte ptr [(allocation)Variables->MouseCheckByte], 0
jg skipwidth
mov ecx, [(allocation)Variables->HUDLeft]
mov [$$2+0Ch], ecx $context=1
skipleftoffset:
mov eax, [(address)ReferenceResolution->Width]
cmp dword ptr [$$2+04h], eax $context=1
jne skipwidth
mov ecx, [(allocation)Variables->HUDWidth]
mov [$$2+04h], ecx $context=1
mov ecx, [(allocation)Variables->HUDWidth]
mov [$$2+14h], ecx $context=1
call SetMouseConstraints
skipwidth:
next:
cmp dword ptr [varFirstRun], 0
je final
call FirstRun
mov byte ptr [varFirstRun], 0
final:
pop ecx
%originalcode%
jmp %returnaddress%
%end%
FirstRun:
call SetMouseConstraints
call CenterMousePosition
ret
SetMouseConstraints:
fild dword ptr [(allocation)Variables->HUDWidth]
fstp dword ptr [(address)MouseValues->Width]
fild dword ptr [(allocation)Variables->HUDHeight]
fstp dword ptr [(address)MouseValues->Height]
ret
CenterMousePosition:
fild dword ptr [(allocation)Variables->HUDWidth]
fdiv dword ptr [MouseDevider]
fstp dword ptr [(address)MouseValues->MousePosX]
fild dword ptr [(allocation)Variables->HUDHeight]
fdiv dword ptr [MouseDevider]
fstp dword ptr [(address)MouseValues->MousePosY]
ret
ResetMousePosition:
fld dword ptr [(address)MouseValues->MousePosX]
fisub dword ptr [(allocation)Variables->HUDLeft]
fstp dword ptr [(address)MouseValues->MousePosX]
fld dword ptr [(address)MouseValues->MousePosY]
fisub dword ptr [(allocation)Variables->HUDTop]
fstp dword ptr [(address)MouseValues->MousePosY]
ret
MouseDevider: (float)2.0f
ItemScaleDevider: (float)0.0f
varFirstRun: (int)1
(codecave)UnscaleDialogs,UnscaleDialogs_cc:
fldz
nop
nop
%end%
]]
if HackTool:CompileAssembly(asm,"FOVFix") == nil then
return ErrorOccurred("Assembly compilation failed...")
else
Toggle_CodeCave("HUDFix_cc",bHUDFix)
Toggle_CodeCave("MapDetectOn_cc",bHUDFix)
Toggle_CodeCave("MapDetectOff_cc",bHUDFix)
Toggle_CodeCave("UnscaleDialogs_cc",bHUDFix)
Toggle_CodeCave("SkillsMouseHack_cc",bHUDFix)
end
end
function Periodic()
if bHUDFix == true then
local Variables = HackTool:GetAllocation("Variables")
if Variables then
PluginViewport:AppendStatusMessage( string.format("\r\n (HUDScaling) HUDLeft=%d, HUDTop=%d, HUDWidth=%d, HUDHeight=%d",
Variables["HUDLeft"]:ReadInt(),Variables["HUDTop"]:ReadInt(),Variables["HUDWidth"]:ReadInt(),Variables["HUDHeight"]:ReadInt()) )
end
local ModelScale = HackTool:GetAddress("ModelScale")
if ModelScale then
ModelScale:WriteFloat(fDefaultModelScale * fNewScaleValue)
end
local MagicItems = HackTool:GetAddress("MagicItems")
if MagicItems then
if bSkyUI == true then
MagicItems["PosX"]:WriteFloat(fDefaultSkyUIMagicItem_PosX / fNewScaleValue)
MagicItems["PosY"]:WriteFloat(fDefaultSkyUIMagicItem_PosY / fNewScaleValue)
MagicItems["Scale"]:WriteFloat(fDefaultSkyUIMagicItem_Scale / fNewScaleValue)
else
MagicItems["PosX"]:WriteFloat(fDefaultMagicItem_PosX / fNewScaleValue)
MagicItems["PosY"]:WriteFloat(fDefaultMagicItem_PosY / fNewScaleValue)
MagicItems["Scale"]:WriteFloat(fDefaultMagicItem_Scale / fNewScaleValue)
end
end
local InventoryItems = HackTool:GetAddress("InventoryItems")
if InventoryItems then
if bSkyUI == true then
InventoryItems["PosX"]:WriteFloat(fDefaultSkyUIInventoryItem_PosX / fNewScaleValue)
InventoryItems["PosY"]:WriteFloat(fDefaultSkyUIInventoryItem_PosY / fNewScaleValue)
InventoryItems["Scale"]:WriteFloat(fDefaultSkyUIInventoryItem_Scale / fNewScaleValue)
InventoryItems["ZoomedScale"]:WriteFloat(fDefaultSkyUIInventoryItem_ZoomedScale / fNewScaleValue)
else
InventoryItems["PosX"]:WriteFloat(fDefaultInventoryItem_PosX / fNewScaleValue)
InventoryItems["PosY"]:WriteFloat(fDefaultInventoryItem_PosY / fNewScaleValue)
InventoryItems["Scale"]:WriteFloat(fDefaultInventoryItem_Scale / fNewScaleValue)
InventoryItems["ZoomedScale"]:WriteFloat(fDefaultInventoryItem_ZoomedScale / fNewScaleValue)
end
end
local RaceSexMenu = HackTool:GetAddress("RaceSexMenu")
if RaceSexMenu then
RaceSexMenu:WriteFloat(fDefaultRaceSexMenu * fNewScaleValue)
end
end
if bHandsFOV or bWorldFOV then
PluginViewport:AppendStatusMessage("\r\n")
end
if bHandsFOV == true then
local FOV = HackTool:GetPointerChain("FOV")
if FOV then
FOV["HandsFOV"]:WriteFloat(fDefaultHandsFOV + fHandsAdditionalFOV)
PluginViewport:AppendStatusMessage( string.format(" (HandsFOV) Value=%.2f",FOV["HandsFOV"]:ReadFloat()) )
end
end
if bWorldFOV == true then
local nonRTFOV = HackTool:GetAddress("nonRTFOV")
local FOV = HackTool:GetPointerChain("FOV")
if FOV and nonRTFOV then
PluginViewport:AppendStatusMessage( string.format(" (WorldFOV) Value=%.2f",FOV["WorldFOV"]:ReadFloat()) )
if FOVChanging == true then
nonRTFOV:WriteFloat(fDefaultWorldFOV + fWorldAdditionalFOV)
FOV["WorldFOV"]:WriteFloat(fDefaultWorldFOV + fWorldAdditionalFOV)
FOVChanging = false
else
local CurrentRT = Round(FOV["WorldFOV"]:ReadFloat(),1)
local CurrentNonRT = Round(fDefaultWorldFOV + fWorldAdditionalFOV,1)
if CurrentRT ~= (CurrentNonRT + 10.0) and CurrentRT ~= CurrentNonRT then
FOVWriteThreshold = FOVWriteThreshold + 1
if FOVWriteThreshold > 5 then
nonRTFOV:WriteFloat(fDefaultWorldFOV + fWorldAdditionalFOV)
FOV["WorldFOV"]:WriteFloat(fDefaultWorldFOV + fWorldAdditionalFOV)
end
else
FOVWriteThreshold = 0
end
end
end
end
if bMouseSensitivity == true then
local MouseValues = HackTool:GetAddress("MouseValues")
if MouseValues then
MouseValues["Unknown3"]:WriteFloat(fMouseSensitivity)
MouseValues["Unknown4"]:WriteFloat(fMouseSensitivity)
end
end
end
function Disable_Inject()
CleanUp()
end
function ResolutionChanged()
SyncDisplayDetection()
fNewScaleValue = DisplayInfo:GetAspectRatio() / fDefaultAspectRatio
local Variables = HackTool:GetAllocation("Variables")
if Variables and Variables["HUDLeft"] and Variables["HUDTop"] and Variables["HUDWidth"] and Variables["HUDHeight"] then
Variables["HUDLeft"]:WriteInt(DisplayInfo:GetiOffsetX(0))
Variables["HUDTop"]:WriteInt(DisplayInfo:GetiOffsetY(0))
Variables["HUDWidth"]:WriteInt(DisplayInfo:GetiOffsetWidth(0,0))
Variables["HUDHeight"]:WriteInt(DisplayInfo:GetiOffsetHeight(0,0))
end
end
function CKFOVFix_World_Changed(Sender)
bWorldFOV = Toggle_CheckFix(Sender)
if bWorldFOV == false then
local nonRTFOV = HackTool:GetAddress("nonRTFOV")
local FOV = HackTool:GetPointerChain("FOV")
if FOV and nonRTFOV then
nonRTFOV:WriteFloat(fDefaultWorldFOV)
FOV["WorldFOV"]:WriteFloat(fDefaultWorldFOV)
end
end
ForceUpdate()
end
function CKFOVFix_Hands_Changed(Sender)
bHandsFOV = Toggle_CheckFix(Sender)
if bHandsFOV == false then
local FOV = HackTool:GetPointerChain("FOV")
if FOV then
FOV["HandsFOV"]:WriteFloat(fDefaultHandsFOV)
end
end
ForceUpdate()
end
function CKMouseSensitivity_Changed(Sender)
bMouseSensitivity = Toggle_CheckFix(Sender)
ForceUpdate()
end
function CKSkyUI_Changed(Sender)
bSkyUI = Toggle_CheckFix(Sender)
ForceUpdate()
end
function CKHUDFix_Changed(Sender)
bHUDFix = Toggle_CheckFix(Sender)
Toggle_CodeCave("HUDFix_cc",bHUDFix)
Toggle_CodeCave("MapDetectOn_cc",bHUDFix)
Toggle_CodeCave("MapDetectOff_cc",bHUDFix)
Toggle_CodeCave("UnscaleDialogs_cc",bHUDFix)
Toggle_CodeCave("SkillsMouseHack_cc",bHUDFix)
ForceUpdate()
end
function HK_IncreaseFOV()
WorldFOVSlider:OffsetPosition(1)
end
function HK_DecreaseFOV()
WorldFOVSlider:OffsetPosition(-1)
end
function WorldFOVSlider_Changed(Sender)
FOVChanging = true
fWorldAdditionalFOV = Sender:GetScaledFloat(3)
lblWorldFOVSlider.Caption:SetCaption( string.format("Value: %.2f",fWorldAdditionalFOV) )
ForceUpdate()
end
function MouseSenseSlider_Changed(Sender)
fMouseSensitivity = Sender:GetPosition()/100
lblMouseSenseSlider.Caption:SetCaption( string.format("Value: %.2f",fMouseSensitivity) )
end
function HandsFOVSlider_Changed(Sender)
fHandsAdditionalFOV = Sender:GetScaledFloat(3)
lblHandsFOVSlider.Caption:SetCaption( string.format("Value: %.2f",fHandsAdditionalFOV) )
ForceUpdate()
end
function Init()
Init_BaseControls()
Init_Controls()
end
function DeInit()
DisableFix()
end