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

--GAME VARS
fAdditionalFOV = 0
fDefaultAspectRatio = 1.777777791

--ControlVars
bHandsFOVFix = true
bFixEnabled = true
bHUDScaling = true

--PROCESS VARS
Process_FriendlyName = Module:GetFriendlyName()
Process_WindowName = "Rage"
Process_ClassName = "Rage"
Process_EXEName = "*"

--INJECTION BEHAVIOUR
InjectDelay = 6000
WriteInterval = 500
SearchInterval = 0
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_FOV","FOV Fine adjustment",15,70,210,17)
	DefaultControls.AddFOVSlider("FOVSlider","FOVSlider_Changed",55,100,125,35)
	DefaultControls.AddHeader("Header_FixesEnableDisable","Individual Fixes",245,70,210,17)
	DefaultControls.AddFixToggle("CKHandsFOVFix_Enable","Hands FOV Fix","CKHandsFOVFix_Changed",255,101,180,14)	
	DefaultControls.AddFixToggle("CKHUDScaling_Enable","HUD Scaling","CKHUDScaling_Changed",255,120,180,14)
end

function Configure_SignatureScan() 

	local tAddress = HackTool:AddAddress("topLeft")
	if HackTool:SignatureScan("7519D9461CD8",tAddress,PAGE_EXECUTE_READ,0x5,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end		

	local tAddress = HackTool:AddAddress("topRight")
	if HackTool:SignatureScan("8B????D9420CD8661CD8450CD80F",tAddress,PAGE_EXECUTE_READ,0x6,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end		
	
	local tAddress = HackTool:AddAddress("bottomLeft")
	if HackTool:SignatureScan("8B????D9????D9461CD8450CD80FD9????D9",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("bottomRight")
	if HackTool:SignatureScan("8B????D8661CD8450CD80F",tAddress,PAGE_EXECUTE_READ,0x6,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end	

	local tAddress = HackTool:AddAddress("Left")
	if HackTool:SignatureScan("D9????D9????D9461CD8450CD80FD9????D9",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("Right")
	if HackTool:SignatureScan("D9410CD8????D8450CD80FDEE9E9",tAddress,PAGE_EXECUTE_READ,0x6,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end		

	local tAddress = HackTool:AddAddress("absLeft")
	if HackTool:SignatureScan("D9????D9????D9461CD80FD9",tAddress,PAGE_EXECUTE_READ,0x6,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end		
	
	local tAddress = HackTool:AddAddress("absRight")
	if HackTool:SignatureScan("D9????E8????????8B????D9????D8661CD80FDEE9",tAddress,PAGE_EXECUTE_READ,0xE,Process_EXEName) == 0 then
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end		
	
	return true

end


function Enable_Inject() 

	FOVCalculator = HackTool:InjectFOVCalculator("FOVCalculator")	
	
	local Variables = HackTool:AllocateMemory("Variables",0)
	Variables:PushFloat("hud_left")
	Variables:PushFloat("hud_top")
	Variables:PushFloat("hud_right")
	Variables:PushFloat("hud_bottom")
	Variables:Allocate()

	ResolutionChanged()
	
	local asm = [[	
	
		(codecave:jmp)topLeft,topLeft_cc:
			fmul dword ptr [edi]
			fadd dword ptr [(allocation)Variables->hud_left]			
			jmp %returnaddress%		
			%end%
			
		(codecave:jmp)topRight,topRight_cc:
			fsub dword ptr [esi+1Ch]
			fmul dword ptr [edi]
			fadd dword ptr [(allocation)Variables->hud_right]			
			jmp %returnaddress%		
			%end%	

		(codecave:jmp)bottomLeft,bottomLeft_cc:
			fmul dword ptr [edi]
			fadd dword ptr [(allocation)Variables->hud_left]				
			jmp %returnaddress%		
			%end%	

		(codecave:jmp)bottomRight,bottomRight_cc:
			fmul dword ptr [edi]
			fadd dword ptr [(allocation)Variables->hud_right]				
			jmp %returnaddress%		
			%end%	

		(codecave:jmp)Left,Left_cc:
			fmul dword ptr [edi]
			fadd dword ptr [(allocation)Variables->hud_left]			
			jmp %returnaddress%		
			%end%	

		(codecave:jmp)Right,Right_cc:
			fmul dword ptr [edi]
			fadd dword ptr [(allocation)Variables->hud_right]			
			jmp %returnaddress%		
			%end%	

		(codecave:jmp)absLeft,absLeft_cc:
			fmul dword ptr [edi]
			fadd dword ptr [(allocation)Variables->hud_left]			
			jmp %returnaddress%		
			%end%		

		(codecave:jmp)absRight,absRight_cc:
			fsub dword ptr [esi+1Ch]
			fmul dword ptr [edi]
			fadd dword ptr [(allocation)Variables->hud_right]			
			jmp %returnaddress%		
			%end%	

	]]

	if HackTool:CompileAssembly(asm,"HUDFix") == nil then
		return ErrorOccurred("Assembly compilation failed...")
	else
		Toggle_CodeCave("topLeft_cc",bHUDScaling)
		Toggle_CodeCave("topRight_cc",bHUDScaling)
		Toggle_CodeCave("bottomLeft_cc",bHUDScaling)
		Toggle_CodeCave("bottomRight_cc",bHUDScaling)
		Toggle_CodeCave("Left_cc",bHUDScaling)
		Toggle_CodeCave("Right_cc",bHUDScaling)
		Toggle_CodeCave("absLeft_cc",bHUDScaling)
		Toggle_CodeCave("absRight_cc",bHUDScaling)
	end	
		
end

function Periodic()

	PluginViewport:AppendStatusMessage(	string.format("\r\n%s",FOVCalculatorSummary("FOVCalculator","Hands",bHandsFOVFix)) )	

	if bHUDScaling == true then
		local Variables = HackTool:GetAllocation("Variables")
		if Variables and Variables["hud_left"] and Variables["hud_top"] and Variables["hud_right"] and Variables["hud_bottom"] then
			PluginViewport:AppendStatusMessage( string.format("\r\n     (HUD Fix) HUD Left: %.0f, HUD Top: %.0f, HUD Right: %.0f, HUD Bottom: %0.f",
												Variables["hud_left"]:ReadFloat(),Variables["hud_top"]:ReadFloat(),Variables["hud_right"]:ReadFloat(),Variables["hud_bottom"]:ReadFloat()) )	
		end
	end	
	
end

function Disable_Inject()
	CleanUp()	
end

function ResolutionChanged() 

	local FOVMax = DisplayInfo:GetAdjustedFOV(110,fDefaultAspectRatio,fAdditionalFOV,179)
	UpdateFOVCalculator("FOVCalculator",DisplayInfo:GetAspectRatio()/fDefaultAspectRatio,fAdditionalFOV,FOVMax)
	
	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["hud_left"] and Variables["hud_right"] then
		Variables["hud_left"]:WriteFloat(DisplayInfo:GetfOffsetX(0)-1)
		Variables["hud_right"]:WriteFloat(DisplayInfo:GetfOffsetX(0)-1)
	end	

end

function CKHandsFOVFix_Changed(Sender)

	bHandsFOVFix = Toggle_CheckFix(Sender)
	Toggle_CodeCave("HandsFOVFix_cc",bHandsFOVFix)	
	ForceUpdate()
	
end

function CKHUDScaling_Changed(Sender)

	bHUDScaling = Toggle_CheckFix(Sender)
	Toggle_CodeCave("topLeft_cc",bHUDScaling)
	Toggle_CodeCave("topRight_cc",bHUDScaling)
	Toggle_CodeCave("bottomLeft_cc",bHUDScaling)
	Toggle_CodeCave("bottomRight_cc",bHUDScaling)
	Toggle_CodeCave("Left_cc",bHUDScaling)
	Toggle_CodeCave("Right_cc",bHUDScaling)
	Toggle_CodeCave("absLeft_cc",bHUDScaling)
	Toggle_CodeCave("absRight_cc",bHUDScaling)	
	ForceUpdate()		
	
end

function HK_IncreaseFOV()	
	FOVSlider:OffsetPosition(1)
end

function HK_DecreaseFOV()	
	FOVSlider:OffsetPosition(-1)
end

function FOVSlider_Changed(Sender)

	fAdditionalFOV = Sender:GetScaledFloat(5)
	UpdateFOVCalculator_AdditionalFOV("FOVCalculator",fAdditionalFOV)
	lblFOVSlider.Caption:SetCaption( string.format("Value: %.2f",fAdditionalFOV) )	
	ForceUpdate()	
		
end

function Init()	
	Init_BaseControls()
	Init_Controls()
end

function DeInit()
	DisableFix()
end