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

--GAME VARS
fDefaultFOV = 85
fAdditionalFOV = 0
fAdditionalWeaponFOV = 0
fAspectRatio = DisplayInfo:GetWidth() / DisplayInfo:GetHeight()
fAspectRatio219 = 2.333333254
fAspectRatio169 = 1.777777791
fFactor = 0.00872665
fNullFOV = 1
fcbAAIndex = 2

--ControlVars
bFixEnabled = true
bFOV = true
bAspect = true
bDOF = true

--PROCESS VARS
Process_FriendlyName = Module:GetFriendlyName()
Process_WindowName = "*"
Process_ClassName = "*"
Process_EXEName = "RoboCop-Win64-Shipping.exe"

--INJECTION BEHAVIOUR
InjectDelay = 500
WriteInterval = 100
SearchInterval = 100
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("Header_FixesEnableDisable","Individual Fixes",245,70,210,17)
	
	DefaultControls.AddHeader("Header_WeaponFOV","FOV fine adjustment",15,70,210,17)	
	DefaultControls.AddFixedFOVSlider("FOVSlider","FOVSlider_Changed",55,100,125,35,0,90,0,1)
	
	FOVSlider:SetTickFrequency(10)
	FOVSlider:SetLabel1Text("-20")
	FOVSlider:SetLabel2Text("+70")

	DefaultControls.AddHeader("Header_FOV","Weapon FOV fine adjustment",15,160,210,17)	
	DefaultControls.AddFixedFOVSlider("WeaponFOVSlider","WeaponFOVSlider_Changed",55,190,125,35,0,90,0,1)
	
	WeaponFOVSlider:SetTickFrequency(10)
	WeaponFOVSlider:SetLabel1Text("-20")
	WeaponFOVSlider:SetLabel2Text("+70")
	
	DefaultControls.AddFixToggle("CKFOVFix_Enable","FOV fix","CKFOVFix_Changed",255,101,180,14)
	DefaultControls.AddFixToggle("CKWeaponFOVFix_Enable","Weapon FOV fix","CKWeaponFOVFix_Changed",255,121,180,14)
	DefaultControls.AddFixToggle("CKARFix_Enable","Aspect ratio fix","CKARFix_Changed",255,141,180,14)
	DefaultControls.AddFixToggle("CKDOFFix_Enable","Depth of field disable","CKDOFFix_Changed",255,161,180,14)
	DefaultControls.AddFixToggle("CKAAFix_Enable","Anti aliasing selection","CKAAFix_Changed",255,181,180,14)
	
	DefaultControls.AddHeader("HeaderAntialiasing","Anti Aliasing Method",15,250,210,17)	
	AspectScalingOptions = {"Off","FXAA - Fast Approximate Anti-Aliasing","TAA - Temporal Anti-Aliasing","MSAA - Multisample Anti-Aliasing","TSR - Temporal Super-Resolution"}
    DefaultControls.AddComboBox("AACombo","AACombo_Changed",AspectScalingOptions,15,275,210,250)

end

function Configure_SignatureScan() 
	

	local tAddress = HackTool:AddAddress("FOV")
	
	if HackTool:SignatureScan("F3 0F ?? ?? ?? 48 8B ?? 48 8B ?? 4C 8D ?? ?? 48 8B ??",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else	
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		--RoboCop-Win64-Shipping.exe+46A1A84 - 48 8B 01              - mov rax,[rcx] 
		--RoboCop-Win64-Shipping.exe+46A1A87 - FF 90 28 07 00 00     - call qword ptr [rax+00000728]
		--RoboCop-Win64-Shipping.exe+46A1A8D - F3 0F 10 40 30        - movss xmm0,[rax+30]
		--RoboCop-Win64-Shipping.exe+46A1A92 - 48 83 C4 28           - add rsp,28
		--RoboCop-Win64-Shipping.exe+46A1A96 - C3                    - ret 
	end
	
	local tAddress = HackTool:AddAddress("FOV2")
	
	if HackTool:SignatureScan("F3 0F ?? ?? ?? ?? ?? ?? ?? 0F ?? ?? 74 ?? F3 0F ?? ?? E9 ?? ?? ?? ??",tAddress,PAGE_EXECUTE_READ,0x0,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else	
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		--RoboCop-Win64-Shipping.exe+41219BF - 0F 29 45 F0            - movaps [rbp-10],xmm0
		--RoboCop-Win64-Shipping.exe+41219C3 - F3 0F 10 07            - movss xmm0,[rdi]
		--RoboCop-Win64-Shipping.exe+41219C7 - F2 0F 11 4D 00         - movsd [rbp+00],xmm1
		--RoboCop-Win64-Shipping.exe+41219CC - 0F 28 CF               - movaps xmm1,xmm7
		--RoboCop-Win64-Shipping.exe+41219CF - 48 89 74 24 30         - mov [rsp+30],rsi
	end
	
	local tAddress = HackTool:AddAddress("DOF")
	
	if HackTool:SignatureScan("75 ?? BF 04 ?? ?? ?? 8B ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? 0F",tAddress,PAGE_EXECUTE_READ,0x07,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else	
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		--RoboCop-Win64-Shipping.exe+2E85C94 - BF 04 00 00 00        - mov edi,00000004
		--RoboCop-Win64-Shipping.exe+2E85C99 - 8B 3C 37              - mov edi,[rdi+rsi]
		--RoboCop-Win64-Shipping.exe+2E85C9C - 48 8B CB              - mov rcx,rbx
		--RoboCop-Win64-Shipping.exe+2E85C9F - E8 BC CE 8F 01        - call RoboCop-Win64-Shipping.exe+4782B60
		--RoboCop-Win64-Shipping.exe+2E85CA4 - 0F B7 C8              - movzx ecx,ax
	end

	local tAddress = HackTool:AddAddress("ANTIALIASING")
	
	--if HackTool:SignatureScan("79 ?? 33 ?? EB ?? BF ? ?? ? ?? 3B ?? 0F ?? ?? 65",tAddress,PAGE_EXECUTE_READ,0x06,Process_EXEName) == 0 then	
	if HackTool:SignatureScan("79 ?? 33 ?? EB ?? BF ?? ?? ?? ?? 3B ?? 0F ?? ?? 65",tAddress,PAGE_EXECUTE_READ,0x06,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else	
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		--RoboCop-Win64-Shipping.exe+4780CE7 - 33 FF                 - xor edi,edi
		--RoboCop-Win64-Shipping.exe+4780CE9 - EB 0A                 - jmp RoboCop-Win64-Shipping.exe+4780CF5
		--RoboCop-Win64-Shipping.exe+4780CEB - BF 05 00 00 00        - mov edi,00000005
		--RoboCop-Win64-Shipping.exe+4780CF0 - 3B C7                 - cmp eax,edi
		--RoboCop-Win64-Shipping.exe+4780CF2 - 0F 4C F8              - cmovl edi,eax
	end

	return true
end

function Enable_Inject()

	local Variables = HackTool:AllocateMemory("Variables",0)
	Variables:PushFloat("CompensatedFOV")
	Variables:PushFloat("FOVIn")
	Variables:PushFloat("FOVOut")
	Variables:PushFloat("WeaponFOVIn")
	Variables:PushFloat("WeaponFOVOut")
	Variables:PushFloat("AdditionalFOV")
	Variables:PushFloat("AdditionalWeaponFOV")
	Variables:PushFloat("AspectRatio")
	Variables:PushFloat("ScreenRatio")
	Variables:PushFloat("factor")
	Variables:PushFloat("NullFOV")
	Variables:PushFloat("AntiAliasing")
	Variables:Allocate()
	Variables["FOVIn"]:WriteFloat(fDefaultFOV)
	Variables["FOVOut"]:WriteFloat(fDefaultFOV)
	Variables["AdditionalFOV"]:WriteFloat(fAdditionalFOV)
	Variables["AdditionalWeaponFOV"]:WriteFloat(fAdditionalWeaponFOV)
	Variables["AspectRatio"]:WriteFloat(fAspectRatio169)
	Variables["ScreenRatio"]:WriteFloat(fAspectRatio)
	Variables["factor"]:WriteFloat(fFactor)
	Variables["NullFOV"]:WriteFloat(fNullFOV)
	Variables["AntiAliasing"]:WriteFloat(fcbAAIndex)
	
	ResolutionChanged()	

	local asm = [[	
									
		(codecave:jmp)FOV,FOV_cc:
		    $$0 [(allocation)Variables->FOVIn],$$2					$ctx=1
		    fld dword ptr [(allocation)Variables->FOVIn]
		    fmul dword ptr [(allocation)Variables->factor]
		    fptan
		    fstp st0
		    fld dword ptr [(allocation)Variables->ScreenRatio]			
		    fdiv dword ptr [(allocation)Variables->AspectRatio]
		    fmulp st1,st0
		    fld1
		    fpatan
		    fdiv dword ptr [(allocation)Variables->factor]
		    fst dword ptr [(allocation)Variables->CompensatedFOV]
		    fadd dword ptr [(allocation)Variables->AdditionalFOV]
		    fstp dword ptr [(allocation)Variables->FOVOut]
			$$0 $$2,[(allocation)Variables->FOVOut]					$ctx=1
			%originalcode%
			jmp %returnaddress%
			%end%			
			
		(codecave:jmp)FOV2,FOV2_cc:									; weapon fov
			%originalcode%
		    $$0 [(allocation)Variables->WeaponFOVIn],$$1			$ctx=1
			addss $$1,[(allocation)Variables->AdditionalWeaponFOV]	$ctx=1			
		    $$0 [(allocation)Variables->WeaponFOVOut],$$1			$ctx=1
			jmp %returnaddress%
			%end%
			
		(codecave:jmp)DOF,DOF_cc:
			%originalcode%
			$$0 edi,0												$ctx=1
			jmp %returnaddress%
			%end%
			
		(codecave:jmp)ANTIALIASING,ANTIALIASING_cc:
			$$0 $$1,[(allocation)Variables->AntiAliasing]			$ctx=1
			jmp %returnaddress%
			%end%
	
	%end%
	]]

	if HackTool:CompileAssembly(asm,"Fixes") == nil then
		return ErrorOccurred("Assembly compilation failed...")
	else
		Toggle_CodeCave("FOV_cc",bFixEnabled)
		Toggle_CodeCave("FOV2_cc",bFixEnabled)
		Toggle_CodeCave("DOF_cc",bDOF)
		Toggle_CodeCave("ANTIALIASING_cc",bAntiAliasing)
	end	
			
	Write_FOV()
	Write_WeaponFOV()
	Write_Aspect()
	Write_AntiAliasing()
	
end

function Periodic()
	local Variables = HackTool:GetAllocation("Variables")
	
	if Variables and Variables["FOVIn"] and Variables["AdditionalFOV"] then
		local fCompensatedFOV = Variables["CompensatedFOV"]:ReadFloat()
		local fFOVIn = Variables["FOVIn"]:ReadFloat()
		local fFOVOut = Variables["FOVOut"]:ReadFloat()
		local fWeaponFOVIn = Variables["WeaponFOVIn"]:ReadFloat()
		local fWeaponFOVOut = Variables["WeaponFOVOut"]:ReadFloat()
		
		PluginViewport:AppendStatusMessage( string.format("\r\n===== Fix informations =====\r\nFOV In : %0.2f, Compensated FOV : %0.2f, FOV Out : %.02f\r\nWeapon FOV In : %0.2f, FOV In : %0.2f", fFOVIn, fCompensatedFOV, fFOVOut, fWeaponFOVIn, fWeaponFOVOut))
	end
end

function FOVSlider_Changed(Sender)

	fAdditionalFOV = Sender:GetPosition() - 20
	lblFOVSlider.Caption:SetCaption( string.format("Value: +%.0f",fAdditionalFOV) )
		
	Write_FOV()
	
	ForceUpdate()

end

function WeaponFOVSlider_Changed(Sender)

	fAdditionalWeaponFOV = Sender:GetPosition() - 20
	lblWeaponFOVSlider.Caption:SetCaption( string.format("Value: +%.0f",fAdditionalWeaponFOV) )
		
	Write_WeaponFOV()
	
	ForceUpdate()

end

function Write_FOV()

	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["AdditionalFOV"] then
		if bFOV == true then
			Variables["AdditionalFOV"]:WriteFloat(fAdditionalFOV)
		else
			Variables["AdditionalFOV"]:WriteFloat(0)
		end
	end

end

function Write_WeaponFOV()

	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["AdditionalWeaponFOV"] then
		if bFOV == true then
			Variables["AdditionalWeaponFOV"]:WriteFloat(fAdditionalWeaponFOV)
		else
			Variables["AdditionalWeaponFOV"]:WriteFloat(0)
		end
	end
	
end

function Write_Aspect()

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

end

function Write_AntiAliasing()

	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["AntiAliasing"] then
		if bAntiAliasing == true then
			Variables["AntiAliasing"]:WriteFloat(fcbAAIndex)
		else
			Variables["AntiAliasing"]:WriteFloat(2)
		end
	end
	
end

function Disable_Inject()
	
	CleanUp()
	
end

function CKFOVFix_Changed(Sender)

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

function CKWeaponFOVFix_Changed(Sender)

	bFOV = Toggle_CheckFix(Sender)
	Write_WeaponFOV()
	Toggle_CodeCave("FOV2_cc",bFixEnabled)
	ForceUpdate()
	
end

function CKARFix_Changed(Sender)

	bAspect = Toggle_CheckFix(Sender)
		
	ForceUpdate()

	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["AspectRatio"] then
		if bAspect == false then
			Variables["AspectRatio"]:WriteFloat(fAspectRatio)
			Variables["ScreenRatio"]:WriteFloat(fAspectRatio)
		else 
			Variables["AspectRatio"]:WriteFloat(fAspectRatio169)
		end
	end
	
end

function CKDOFFix_Changed(Sender)

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

end

function CKAAFix_Changed(Sender)

	bAntiAliasing = Toggle_CheckFix(Sender)
	Toggle_CodeCave("ANTIALIASING_cc",bAntiAliasing)
	ForceUpdate()

end

function AACombo_Changed(Sender)

	fcbAAIndex = AACombo:GetSelectedIndex()	
	Write_AntiAliasing()
	ForceUpdate()

end

function ResolutionChanged() 

	SyncDisplayDetection()
	
end

function Init()

	Init_BaseControls()
	Init_Controls()

end

function DeInit()

	DisableFix()

end
