require(GlobalDependencys:GetDependency("StandardBase"):GetPackageName())

--GAME VARS
fAdditionalFOV = 0
fDefaultAspectRatio = 1.777777791
fFOV = 0
fDOF = 0
fDefaultFOV = 90
fFactor1 = 0.01745329238
fFactor2 = 0.5
fcbIndex = 0
fAspectRatio = DisplayInfo:GetWidth() / DisplayInfo:GetHeight()
fDefaultPhotoFOV = 0
fPhotoFOV = 0

--ControlVars
bFixEnabled = true
bFOV = true
bPhotoFOV = true
bAspect = true
bAspectRatio = true
bDOF = true
bFringe = true
bBarrelDistortion = true

--PROCESS VARS
Process_FriendlyName = Module:GetFriendlyName()
Process_WindowName = "Uncharted: Legacy of Thieves Collection"
Process_ClassName = "Uncharted: Legacy of Thieves Collection"
Process_EXEName = "u4.exe;tll.exe"

--INJECTION BEHAVIOUR
InjectDelay = 500
WriteInterval = 500
SearchInterval = 500
SuspendThread = true

NearToAddress = 0

--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("Header_FixesEnableDisable","Individual Fixes",245,70,210,17)
	
	DefaultControls.AddHeader("Header_FOV","FOV fine adjustment",15,70,215,17)	
	DefaultControls.AddFOVSlider("FOVSlider","FOVSlider_Changed",55,90,125,35)
	DefaultControls.AddFixToggle("CKFOVFix_Enable","FOV fix","CKFOVFix_Changed",255,101,180,14)
	DefaultControls.AddFixToggle("CKPHOTOFOVFix_Enable","Photo FOV fix","CKPHOTOFOVFix_Changed",255,121,180,14)
	DefaultControls.AddFixToggle("CKAspectFix_Enable","Cinematics aspect fix","CKAspectFix_Changed",255,141,180,14)
	DefaultControls.AddFixToggle("CKARatioFix_Enable","Aspect ratio fix","CKARatioFix_Changed",255,161,180,14)
	DefaultControls.AddFixToggle("CKDOFFix_Enable","Depth of field fix","CKDOFFix_Changed",255,181,180,14)
	DefaultControls.AddFixToggle("CKFRINGEFix_Enable","Chromatic aberrations fix","CKFRINGEFix_Changed",255,201,180,14)
	DefaultControls.AddFixToggle("CKBARRELFix_Enable","Barrel distortion fix","CKBARRELFix_Changed",255,221,180,14)

	DefaultControls.AddHeader("Header_PHOTOFOV","Photo mode FOV fine adjustment",15,150,215,17)	
	DefaultControls.AddFixedFOVSlider("PHOTOFOVSlider","PhotoFOVSlider_Changed",55,170,125,35,10,170,0,1)
	PHOTOFOVSlider:SetTickFrequency(20)
	PHOTOFOVSlider:SetLabel1Text("10")
	PHOTOFOVSlider:SetLabel2Text("170")
	
	DefaultControls.AddHeader("HeaderAspectRatio","Game aspect ratio",15,230,215,17)	
	AspectScalingOptions = {"Automatic detection","Custom value"}
    DefaultControls.AddComboBox("AspectScalingCombo","AspectScalingCombo_Changed",AspectScalingOptions,15,255,140,250)
	DefaultControls.AddParameterBox("ARatio",DisplayInfo:GetWidth() / DisplayInfo:GetHeight(),"ARatio_Changed",170,257,50,20)

end

function Configure_SignatureScan() 

	NearToAddress = HackTool:GetBaseAddress()

	local tAddress = HackTool:AddAddress("FOV")
	
	if HackTool:SignatureScan("C6 83 ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? C5 8A",tAddress,PAGE_EXECUTE_READ,0x07,Process_EXEName) == 0 then
		if HackTool:SignatureScan("C5 F2 ?? ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? C5 92",tAddress,PAGE_EXECUTE_READ,0x08,Process_EXEName) == 0 then
			return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
		else
			print( tAddress:GetInfo(TYPE_ADDRESS) )
			--C5 FA 59 0D 8C 08 4C 01  - vmulss xmm1,xmm0,[tll.exe+2BF3384]
			--C5 F2 59 05 3C 0C 4C 01  - vmulss xmm0,xmm1,[tll.exe+2BF373C]
			--E8 53 39 DC 00           - call tll.exe+24F6458
			--C5 92 5E C8              - vdivss xmm1,xmm13,xmm0
			--C5 FA 10 05 53 0C 4C 01  - vmovss xmm0,[tll.exe+2BF3764]
		end
	else	
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		--C5 7A 11 AB D0 03 00 00     - vmovss [rbx+000003D0],xmm13
		--C6 83 20 04 00 00 00        - mov byte ptr [rbx+00000420],00
		--E8 A4 6F D7 00              - call u4.exe+23B6418
		--C5 8A 5E C8                 - vdivss xmm1,xmm14,xmm0
		--C5 FA 10 05 DC B6 45 01     - vmovss xmm0,[u4.exe+2A9AB5C]
	end	
	
	local tAddress = HackTool:AddAddress("PHOTOFOV")
	
	if HackTool:SignatureScan("C5 FA ?? ?? ?? ?? ?? ?? C5 FA ?? ?? ?? ?? ?? ?? 41 ?? ?? ?? ?? ?? 48 8B ?? ?? ?? ?? ?? 48 83",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then							   
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		--C5 FA 11 3D 25 D4 A5 02    - vmovss [tll.exe+36732FC],xmm7
		--C5 FA 11 3D 19 D4 A5 02    - vmovss [tll.exe+36732F8],xmm7
		--C5 FA 10 05 2D C7 2A 03    - vmovss xmm0,[tll.exe+3EC2614]
		--C5 FA 11 05 BD D3 A5 02    - vmovss [tll.exe+36732AC],xmm0
		--41 BF 01 00 00 00        	 - mov r15d,00000001
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		
		local PhotoDefaultFOV = HackTool:AddAddress("PhotoDefaultFOV", tAddress)
		PhotoDefaultFOV:AcquireAddress(0x4)
		print( PhotoDefaultFOV:GetInfo(TYPE_FLOAT) )
	end
	

	local tAddress = HackTool:AddAddress("ASPECT")
	
	if HackTool:SignatureScan("48 8B ?? ?? ?? ?? ?? 4C 8B ?? ?? ?? ?? ?? ?? 4C 8B ?? 49 C1",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		--u4.exe+152D5D2 - C6 87 A9 14 01 00 01     - mov byte ptr [rdi+000114A9],01
		--u4.exe+152D5D9 - C6 87 B8 11 01 00 01     - mov byte ptr [rdi+000111B8],01
		--u4.exe+152D5E0 - 48 8B 0D 99 0A 01 05     - mov rcx,[u4.exe+653E080]
		--u4.exe+152D5E7 - 4C 8B AC 24 A0 00 00 00  - mov r13,[rsp+000000A0]
		--u4.exe+152D5EF - 4C 8B C1              	- mov r8,rcx		
	end
	
	local tAddress = HackTool:AddAddress("ARATIO")
	
	if HackTool:SignatureScan("44 8B ?? ?? ?? ?? ?? 48 ?? ?? 48 89 ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? C5",tAddress,PAGE_EXECUTE_READ,0x11,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end

	local tAddress = HackTool:AddAddress("DOF")
	
	if HackTool:SignatureScan("41 8B 87 ?? ?? ?? ?? 41 89 86 ?? ?? ?? ?? 41 C7 86",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		--41 8B 87 BC 0C 00 00              - mov eax,[r15+00000CBC]
		--41 89 86 D0 27 01 00              - mov [r14+000127D0],eax
		--41 8B 87 B0 0C 00 00              - mov eax,[r15+00000CB0]
		--41 89 86 D8 27 01 00              - mov [r14+000127D8],eax
		--41 C7 86 D4 27 01 00 33 33 33 3F  - mov [r14+000127D4],3F333333
	end

	local tAddress = HackTool:AddAddress("EFFECTS")
	
	if HackTool:SignatureScan("41 8B 86 ?? ?? ?? ?? 89 86 ?? ?? ?? ?? 41 8B 86 ?? ?? ?? ?? 89 86 ?? ?? ?? ?? 41 8B 86 ?? ?? ?? ?? 89 86 ?? ?? ?? ?? 41 8B 87",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then
		if HackTool:SignatureScan("41 8B 87 ?? ?? ?? ?? 89 86 ?? ?? ?? ?? 41 8B 87 ?? ?? ?? ?? 89 86 ?? ?? ?? ?? 41 8B 87 ?? ?? ?? ?? 89 86 ?? ?? ?? ?? 41 8B 86",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then
			return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
		else
			local Barrel_Distortion_1 = HackTool:AddAddress("BARREL1", tAddress)
			local Barrel_Distortion_2 = HackTool:AddAddress("BARREL2", tAddress)
			local Fringe = HackTool:AddAddress("FRINGE", tAddress)
			Barrel_Distortion_2:OffsetAddress(0x0d)
			Fringe:OffsetAddress(0x1a)

			print( Barrel_Distortion_1:GetInfo(TYPE_ADDRESS) )	
			print( Barrel_Distortion_2:GetInfo(TYPE_ADDRESS) )
			print( Fringe:GetInfo(TYPE_ADDRESS) )
		end
	else
		local Barrel_Distortion_1 = HackTool:AddAddress("BARREL1", tAddress)
		local Barrel_Distortion_2 = HackTool:AddAddress("BARREL2", tAddress)
		local Fringe = HackTool:AddAddress("FRINGE", tAddress)
		Barrel_Distortion_2:OffsetAddress(0x0d)
		Fringe:OffsetAddress(0x1a)

		print( Barrel_Distortion_1:GetInfo(TYPE_ADDRESS) )	
		print( Barrel_Distortion_2:GetInfo(TYPE_ADDRESS) )
		print( Fringe:GetInfo(TYPE_ADDRESS) )
		--u4.exe+1733F80 - 41 8B 86 4C 0D 00 00     - mov eax,[r14+00000D4C]
		--u4.exe+1733F87 - 89 86 3C 01 00 00        - mov [rsi+0000013C],eax
		--u4.exe+1733F8D - 41 8B 86 50 0D 00 00     - mov eax,[r14+00000D50]
		--u4.exe+1733F94 - 89 86 40 01 00 00        - mov [rsi+00000140],eax
		--u4.exe+1733F9A - 41 8B 87 A8 10 01 00     - mov eax,[r15+000110A8]
	end
	
	return true

end

function Enable_Inject() 

	local Variables = HackTool:AllocateMemory("Variables",0)
	Variables:PushFloat("FOVInGame")
	Variables:PushFloat("PhotoFOV")
	Variables:PushFloat("AdditionalFOV")
	Variables:PushFloat("Factor1")
	Variables:PushFloat("Factor2")
	Variables:PushFloat("DOF")
	Variables:PushFloat("AspectRatio")
	Variables:Allocate(NearToAddress)
	Variables["FOVInGame"]:WriteFloat(fDefaultFOV)
	Variables["AdditionalFOV"]:WriteFloat(fAdditionalFOV)
	Variables["Factor1"]:WriteFloat(fFactor1)
	Variables["Factor2"]:WriteFloat(fFactor2)
	Variables["DOF"]:WriteFloat(fDOF)
	Variables["AspectRatio"]:WriteFloat(fAspectRatio)

	local asm = [[
	
		(codecave:jmp)FOV,FOV_cc:
		vmovss xmm0,[rbx+0x30]
		vmovss [(allocation)Variables->FOVInGame],xmm0
		vaddss xmm0,xmm0,[(allocation)Variables->AdditionalFOV]
		vmulss xmm1,xmm0,[(allocation)Variables->Factor1]
		vmulss xmm0,xmm1,[(allocation)Variables->Factor2]
		%originalcode%
		jmp %returnaddress%
		%end%		

		(codecave:jmp)ARATIO,ARATIO_cc:
		%originalcode%
		vmovss xmm0,[(allocation)Variables->AspectRatio]
		jmp %returnaddress%
		%end%
		
		(codecave)PHOTOFOV,PHOTOFOV_cc:
		vmovss xmm0,[(allocation)Variables->PhotoFOV]
		%end%

		(codecave)ASPECT,ASPECT_cc:
		$$0 $$1,[$$2-0x10]								$ctx=1
		%end%
		
		(codecave)DOF,DOF_cc:
		mov $$1,0x7F800000								$ctx=1
		nop
		nop
		%end%
		
		(codecave)BARREL1,BARREL1_cc:
		xor $$1,$$1										$ctx=1
		nop
		nop
		nop
		nop
		nop
		%end%
		
		(codecave)BARREL2,BARREL2_cc:
		$$0 $$1,(float)1.00								$ctx=1
		nop
		nop
		%end%
		
		(codecave)FRINGE,FRINGE_cc:
		xor $$1,$$1										$ctx=1
		nop
		nop
		nop
		nop
		nop
		%end%
		
	]]
	

	if HackTool:CompileAssembly(asm,"Fixes",NearToAddress) == nil then
		return ErrorOccurred("Assembly compilation failed...")
	else
		Toggle_CodeCave("FOV_cc",bFOV)
		Toggle_CodeCave("PHOTOFOV_cc",bPhotoFOV)
		Toggle_CodeCave("ASPECT_cc",bAspect)
		Toggle_CodeCave("ARATIO_cc",bAspectRatio)
		Toggle_CodeCave("DOF_cc",bDOF)
		Toggle_CodeCave("FRINGE_cc",bFringe)
		Toggle_CodeCave("BARREL1_cc",bBarrelDistortion)
		Toggle_CodeCave("BARREL2_cc",bBarrelDistortion)
	end
	
	Write_FOV()
	Write_PhotoFOV()
	Write_AspectRatio()
	
end

function Periodic()

	local Variables = HackTool:GetAllocation("Variables")
	
	if Variables and Variables["FOVInGame"] and Variables["AdditionalFOV"] then
		fFOVInGame = Variables["FOVInGame"]:ReadFloat() + Variables["AdditionalFOV"]:ReadFloat()
		PluginViewport:AppendStatusMessage( string.format("\r\n===== Fix informations =====\r\nFOV In: %0.f, FOV Out: %.0f\r\nPhoto mode default FOV: %.2f",Variables["FOVInGame"]:ReadFloat(), fFOVInGame, fDefaultPhotoFOV))
	end

end

function Write_FOV()

	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["AdditionalFOV"] then
		Variables["AdditionalFOV"]:WriteFloat(fFOV)
	end

end

function Write_PhotoFOV()

	local FOV = 0
	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["PhotoFOV"] then
		if bFOV then
			FOV = fFOV
		end
		Variables["PhotoFOV"]:WriteFloat(fPhotoFOV - FOV)
	end

end

function Write_DOF()

	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["DOF"] then
		Variables["DOF"]:WriteFloat(fDOF)
	end

end

function FOVSlider_Changed(Sender)

	fFOV = (Sender:GetScaledFloat(2)) + 7 
	lblFOVSlider.Caption:SetCaption( string.format("Additional FOV : %.2f",fFOV) )
	Write_FOV()
	ForceUpdate()
	
end

function PhotoFOVSlider_Changed(Sender)

	fPhotoFOV = Sender:GetPosition()
	lblPHOTOFOVSlider.Caption:SetCaption( string.format("Value: %.2f",fPhotoFOV) )
	Write_PhotoFOV()
	ForceUpdate()

end

function ARatio_Changed()

	fAspectRatio = ARatio:GetText()
	Write_AspectRatio()
	ForceUpdate()
	
end

function Write_AspectRatio()

	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["AspectRatio"] then
		Variables["AspectRatio"]:WriteFloat(fAspectRatio)
	end	

end

function DOFSlider_Changed(Sender)

	fDOF = ((Sender:GetScaledFloat(2)) + 50) / 3
	lblDOFSlider.Caption:SetCaption( string.format("Additional FOV : %.2f",fDOF) )
	Write_DOF()
	ForceUpdate()
	
end

function CKFOVFix_Changed(Sender)

	bFOV = Toggle_CheckFix(Sender)
	Toggle_CodeCave("FOV_cc",bFOV)
	Write_PhotoFOV()
	ForceUpdate()
	
end

function CKPHOTOFOVFix_Changed(Sender)

	bPhotoFOV = Toggle_CheckFix(Sender)
	local PhotoDefaultFOV = HackTool:GetAddress("PhotoDefaultFOV")

	if PhotoDefaultFOV then
		fDefaultPhotoFOV = PhotoDefaultFOV:ReadFloat()
	end
	
	Toggle_CodeCave("PHOTOFOV_cc",bPhotoFOV)
	ForceUpdate()
end

function CKAspectFix_Changed(Sender)

	bAspect= Toggle_CheckFix(Sender)
	Toggle_CodeCave("ASPECT_cc",bAspect)
	ForceUpdate()
	
end

function CKDOFFix_Changed(Sender)

	bDOF = Toggle_CheckFix(Sender)
	Toggle_CodeCave("DOF_cc",bDOF)
	ForceUpdate()
	
end

function CKARatioFix_Changed(Sender)

	bAspectRatio = Toggle_CheckFix(Sender)
	Toggle_CodeCave("ARATIO_cc",bAspectRatio)
	AspectScalingCombo:SetEnabled(bAspectRatio)
	fcbIndex = AspectScalingCombo:GetSelectedIndex()
	
	if bAspectRatio == false or fcbIndex == 1 then
		ARatio:SetEnabled(bAspectRatio)
	end
	
end

function CKFRINGEFix_Changed(Sender)

	bFringe = Toggle_CheckFix(Sender)
	Toggle_CodeCave("FRINGE_cc",bFringe)
	ForceUpdate()
	
end

function CKBARRELFix_Changed(Sender)

	bBarrelDistortion = Toggle_CheckFix(Sender)
	Toggle_CodeCave("BARREL1_cc",bBarrelDistortion)
	Toggle_CodeCave("BARREL2_cc",bBarrelDistortion)
	ForceUpdate()

end

function AspectScalingCombo_Changed(Sender)

	fcbIndex = AspectScalingCombo:GetSelectedIndex()
	
	if fcbIndex == 0 then
		ARatio:SetEnabled(false)
		ARatio:SetText(DisplayInfo:GetWidth() / DisplayInfo:GetHeight())
	else 
		ARatio:SetEnabled(true)
	end
	
	fAspectRatio = ARatio:GetText()
	Write_AspectRatio()
	ForceUpdate()
	
end

function ResolutionChanged() 

	SyncDisplayDetection()
	
end

function Disable_Inject()
	
	CleanUp()
	
end

function Init()	
	Init_BaseControls()
	Init_Controls()
end

function DeInit()
	DisableFix()
end
