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

--GAME VARS
fDefaultAspectRatio = 1.777777791
fDefaultLBAspectRatio = 2.6
fAdditionalFOV = 0
fFOVMax = 150

--ControlVars
bFixEnabled = true
bAspectFix = true
bLetterBoxFix = true
bMoviesFix = true
bHUDLetterBoxFix = true
bHUDFix = true
bFOVFix = true
bBloomFix = true

--PROCESS VARS
Process_FriendlyName = Module:GetFriendlyName()
Process_WindowName = "The Evil Within"
Process_ClassName = "The Evil Within"
Process_EXEName = "EvilWithin.exe"

--INJECTION BEHAVIOUR
InjectDelay = 1000
WriteInterval = 25
SearchInterval = 250
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.AddFixToggle("CKAspectFix_Enable","Aspect Fix","CKAspectFix_Changed",255,101,180,14)
	DefaultControls.AddFixToggle("CKLetterBoxFix_Enable","LetterBox Fix","CKLetterBoxFix_Changed",255,120,180,14)
	DefaultControls.AddFixToggle("CKMoviesFix_Enable","Movies Fix","CKMoviesFix_Changed",255,139,180,14)
	DefaultControls.AddFixToggle("CKHUDBlackscreenFix_Enable","HUD Blackscreen Fix","CKHUDBlackscreenFix_Changed",255,158,180,14)
	DefaultControls.AddFixToggle("CKHUDFix_Enable","HUD Fix","CKHUDFix_Changed",255,177,180,14)
	DefaultControls.AddFixToggle("CKFOVFix_Enable","FOV Fix","CKFOVFix_Changed",255,196,180,14)
	DefaultControls.AddFixToggle("CKBloomFix_Enable","Bloom Fix","CKBloomFix_Changed",255,215,180,14)
	
	DefaultControls.AddHeader("Header_FOV","FOV Fine adjustment",15,70,210,17)
	DefaultControls.AddFOVSlider("FOVSlider","FOVSlider_Changed",55,100,125,35)
end


function Configure_SignatureScan() 

	local tAddress = HackTool:AddAddress("BloomFix")
	if HackTool:SignatureScan("F3 0F ?? ?? ?? ?? ?? ?? F3 0F ?? ?? ?? ?? ?? ?? 75 ?? F3 0F ?? ?? ?? ?? ?? ?? EB ?? F3",tAddress,PAGE_EXECUTE_READ,0,Process_EXEName) == 0 then
		if HackTool:SignatureScan("80 ?? ?? ?? ?? ?? F0 66 41 39 ?? ?? ?? ?? ?? 4C 89 ?? ?? ?? ?? ?? F3 0F",tAddress,PAGE_EXECUTE_READ,0x16,Process_EXEName) == 0 then	
			return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
		else
			print( tAddress:GetInfo(TYPE_ADDRESS) )
		end				
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end	

	local tAddress = HackTool:AddAddress("LetterBoxFix1")
	if HackTool:SignatureScan("0F 5B ?? F3 0F 5E ?? F3 0F 10 05 ?? ?? ?? ?? 41",tAddress,PAGE_EXECUTE_READ,0x7,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		
		local OriginalAddress = HackTool:AddAddress("OriginalLetterBox",tAddress)
		OriginalAddress:AcquireAddress(0x4)
		print( OriginalAddress:GetInfo(TYPE_FLOAT) )
	end	
	
	local tAddress = HackTool:AddAddress("LetterBoxFix2")
	if HackTool:SignatureScan("F3 0F 59 05 ?? ?? ?? ?? F3 0F 59 05 ?? ?? ?? ?? F3 0F 11 ?? ?? F3 0F 10 ?? ?? ?? ?? ?? 0F 57",tAddress,PAGE_EXECUTE_READ,0x15,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end		
	
	local tAddress = HackTool:AddAddress("LetterBoxFix3")
	if HackTool:SignatureScan("F3 0F ?? ?? F3 0F 59 ?? ?? ?? ?? ?? 0F 2F ?? 72 ?? C7 ?? 00 00 00 00",tAddress,PAGE_EXECUTE_READ,0xF,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
	end		
	
	local tAddress = HackTool:AddAddress("MoviesFix")
	if HackTool:SignatureScan("0F 28 ?? 0F 28 ?? 41 0F 28 ?? F3 0F 59 ?? ?? ?? ?? ?? 0F 28",tAddress,PAGE_EXECUTE_READ,0xA,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		
		local OriginalAddress = HackTool:AddAddress("OriginalMovies",tAddress)
		OriginalAddress:AcquireAddress(0x4)
		print( OriginalAddress:GetInfo(TYPE_FLOAT) )
	end	
	
	local tAddress = HackTool:AddAddress("GameAspectFix")
	if HackTool:SignatureScan("C3 F3 0F 59 ?? ?? ?? ?? ?? 0F 28 ?? F3 0F 59 ?? ?? ?? ?? ?? 0F 28 ?? F3",tAddress,PAGE_EXECUTE_READ,0xC,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		
		local OriginalAddress = HackTool:AddAddress("OriginalGameAspect",tAddress)
		OriginalAddress:AcquireAddress(0x4)
		print( OriginalAddress:GetInfo(TYPE_FLOAT) )
	end			
	
	local tAddress = HackTool:AddAddress("HUDLetterBox")
	if HackTool:SignatureScan("4C ?? ?? 66 0F ?? ?? 0F 5B ?? F3 0F 59 0D ?? ?? ?? ?? F3",tAddress,PAGE_EXECUTE_READ,0xA,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		
		local OriginalAddress = HackTool:AddAddress("OriginalHUDLetterBox",tAddress)
		OriginalAddress:AcquireAddress(0x4)
		print( OriginalAddress:GetInfo(TYPE_FLOAT) )
	end	
	
	local tAddress = HackTool:AddAddress("HUDFix1")
	if HackTool:SignatureScan("F3 0F 59 ?? ?? ?? ?? ?? F3 0F 59 ?? F3 0F 59 ?? 76 ?? 0F 28 ?? F3",tAddress,PAGE_EXECUTE_READ,0x10,Process_EXEName) == 0 then	
		return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
	else
		print( tAddress:GetInfo(TYPE_ADDRESS) )
		
		local HUDFix3 = HackTool:AddAddress("HUDFix3",tAddress)
		HUDFix3:OffsetAddress(0x13)
		print( HUDFix3:GetInfo(TYPE_ADDRESS) )
		
		local HUDFix2 = HackTool:AddAddress("HUDFix2",HUDFix3)
		HUDFix2:OffsetAddress(0xB)		
		print( HUDFix2:GetInfo(TYPE_ADDRESS) )
 
	end	
	
	local tAddress = HackTool:AddAddress("FOVFix")
	if HackTool:SignatureScan("66 48 0F ?? ?? E8 ?? ?? ?? ?? F3 0F 10 ?? ?? ?? ?? ?? F3 0F 11",tAddress,PAGE_EXECUTE_READ,0x12,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("MoviesAspect")
	Variables:PushFloat("LetterBoxAspect")
	Variables:PushFloat("GameAspect")
	Variables:PushFloat("HUDAspect")	
	Variables:PushFloat("HUDLetterBox")
	Variables:PushFloat("BloomScale")
	Variables:Allocate()	
	
	ResolutionChanged()

	local asm = [[	

		(codecave:jmp)BloomFix,BloomFix_cc:
			divss $$1, [(allocation)Variables->BloomScale]
			%originalcode%			
			jmp %returnaddress%
			%end%	
	
		(codecave:jmp)FOVFix,FOVFix_cc:
			%originalcode%
			movss [tempFOV], $$2					$context=1
			fld dword ptr [tempFOV]
			call (allocation)FOVCalculator
			fstp dword ptr [tempFOV]
			movss $$2, [tempFOV]				$context=1			
			jmp %returnaddress%
			%end%
			
		tempFOV: (float)0
	
		(codecave)LetterBoxFix1,LetterBoxFix1_cc:
			$$0 $$1, [(allocation)Variables->LetterBoxAspect]
			%end%
			
		(codecave)LetterBoxFix2,LetterBoxFix2_cc:
			$$0 $$1, [(allocation)Variables->LetterBoxAspect]
			%end%	

		(codecave)LetterBoxFix3,LetterBoxFix3_cc:
			jmp $$1
			%end%				
			
		(codecave)MoviesFix,MoviesFix_cc:
			$$0 $$1, [(allocation)Variables->MoviesAspect]
			%end%		

		(codecave)GameAspectFix,GameAspectFix_cc:
			$$0 $$1, [(allocation)Variables->GameAspect]
			%end%		

		(codecave)HUDLetterBox,HUDLetterBox_cc:
			$$0 $$1, [(allocation)Variables->HUDLetterBox]
			%end%			
			
		(codecave)HUDFix1,HUDFix1_cc:
			jmp $$1
			%end%	

		(codecave)HUDFix2,HUDFix2_cc:
			nop
			nop
			%end%	
			
		(codecave)HUDFix3,HUDFix3_cc:
			$$0 $$1, [(allocation)Variables->HUDAspect]
			%end%				

	]]
	
	if HackTool:CompileAssembly(asm,"Fixes") == nil then
		return ErrorOccurred("Assembly compilation failed...")
	else
		Toggle_CodeCave("LetterBoxFix1_cc",bLetterBoxFix)
		Toggle_CodeCave("LetterBoxFix2_cc",bLetterBoxFix)
		Toggle_CodeCave("LetterBoxFix3_cc",bLetterBoxFix)
		Toggle_CodeCave("MoviesFix_cc",bMoviesFix)
		Toggle_CodeCave("GameAspectFix_cc",bAspectFix)
		Toggle_CodeCave("HUDLetterBox_cc",bHUDLetterBoxFix)
		Toggle_CodeCave("HUDFix1_cc",bHUDFix)
		Toggle_CodeCave("HUDFix2_cc",bHUDFix)
		Toggle_CodeCave("HUDFix3_cc",bHUDFix)
		Toggle_CodeCave("FOVFix_cc",bFOVFix)
		Toggle_CodeCave("BloomFix_cc",bBloomFix)
	end		

end

function Periodic()

	PluginViewport:AppendStatusMessage("\r\n")

	local OriginalLetterBox = HackTool:GetAddress("OriginalLetterBox")
	local OriginalMovies = HackTool:GetAddress("OriginalMovies")
	local OriginalGameAspect = HackTool:GetAddress("OriginalGameAspect")
	local OriginalHUDLetterBox = HackTool:GetAddress("OriginalHUDLetterBox")
	
	local Variables = HackTool:GetAllocation("Variables")
	if Variables then
	
		if bLetterBoxFix and OriginalLetterBox then
			PluginViewport:AppendStatusMessage( string.format("     (LetterBoxFix) Default=%.2f, New=%.2f",OriginalLetterBox:ReadFloat(),Variables["LetterBoxAspect"]:ReadFloat()) )		
		end
		
		if bMoviesFix and OriginalMovies then
			PluginViewport:AppendStatusMessage( string.format("     (MoviesFix) Default=%.2f, New=%.2f",OriginalMovies:ReadFloat(),Variables["MoviesAspect"]:ReadFloat()) )		
		end		

		if bAspectFix and OriginalGameAspect then
			PluginViewport:AppendStatusMessage( string.format("     (AspectFix) Default=%.2f, New=%.2f",OriginalGameAspect:ReadFloat(),Variables["GameAspect"]:ReadFloat()) )		
		end	
		
		PluginViewport:AppendStatusMessage("\r\n")
		
		if bHUDLetterBoxFix and OriginalHUDLetterBox then
			PluginViewport:AppendStatusMessage( string.format("     (HUDBlankscreenFix) Default=%.2f, New=%.2f",OriginalHUDLetterBox:ReadFloat(),Variables["HUDLetterBox"]:ReadFloat()) )		
		end		
		
		
	end
	
	if bFOVFix then
		PluginViewport:AppendStatusMessage(	string.format("\r\n%s",FOVCalculatorSummary("FOVCalculator","General",bFOVFix)) )		
	end

end

function Disable_Inject()

	CleanUp()

end


function ResolutionChanged() 

	UpdateFOVCalculator("FOVCalculator",fDefaultLBAspectRatio/fDefaultAspectRatio,fAdditionalFOV,fFOVMax)

	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["MoviesAspect"] and Variables["LetterBoxAspect"] and Variables["GameAspect"] and Variables["HUDAspect"] and Variables["HUDLetterBox"] then	
		local HUDAspect = DisplayInfo:GetiOffsetWidth() / DisplayInfo:GetiOffsetHeight()			
		Variables["MoviesAspect"]:WriteFloat(HUDAspect)
		Variables["LetterBoxAspect"]:WriteFloat(0)
		Variables["GameAspect"]:WriteFloat(DisplayInfo:GetAspectRatio())
		Variables["HUDAspect"]:WriteFloat(HUDAspect)
		Variables["HUDLetterBox"]:WriteFloat(0) 	
		Variables["BloomScale"]:WriteFloat(DisplayInfo:GetAspectRatio() / fDefaultAspectRatio) 	
	end
	
end

function CKBloomFix_Changed(Sender)

	bBloomFix = Toggle_CheckFix(Sender)
	Toggle_CodeCave("BloomFix_cc",bBloomFix)
	ForceUpdate()		
	
end

function CKMoviesFix_Changed(Sender)

	bMoviesFix = Toggle_CheckFix(Sender)
	Toggle_CodeCave("MoviesFix_cc",bMoviesFix)
	ForceUpdate()		
	
end

function CKAspectFix_Changed(Sender)

	bAspectFix = Toggle_CheckFix(Sender)
	Toggle_CodeCave("GameAspectFix_cc",bAspectFix)
	ForceUpdate()		
	
end

function CKLetterBoxFix_Changed(Sender)

	bLetterBoxFix = Toggle_CheckFix(Sender)
	Toggle_CodeCave("LetterBoxFix1_cc",bLetterBoxFix)
	Toggle_CodeCave("LetterBoxFix2_cc",bLetterBoxFix)
	Toggle_CodeCave("LetterBoxFix3_cc",bLetterBoxFix)
	ForceUpdate()		
	
end

function CKHUDBlackscreenFix_Changed(Sender)

	bHUDLetterBoxFix = Toggle_CheckFix(Sender)
	Toggle_CodeCave("HUDLetterBox_cc",bHUDLetterBoxFix)
	ForceUpdate()		
	
end

function CKHUDFix_Changed(Sender)

	bHUDFix = Toggle_CheckFix(Sender)
	Toggle_CodeCave("HUDFix1_cc",bHUDFix)
	Toggle_CodeCave("HUDFix2_cc",bHUDFix)
	Toggle_CodeCave("HUDFix3_cc",bHUDFix)
	ForceUpdate()		
	
end

function CKFOVFix_Changed(Sender)

	bFOVFix = Toggle_CheckFix(Sender)
	Toggle_CodeCave("FOVFix_cc",bFOVFix)
	ForceUpdate()

end

function HK_IncreaseFOV()	
	FOVSlider:OffsetPosition(1)
end

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

function FOVSlider_Changed(Sender)

	fAdditionalFOV = Sender:GetScaledFloat(4)
	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