User File #30274265400688966

Upload All User Files

#30274265400688966 - BBLiT.lua v2

bblit.lua
1106 downloads
Uploaded 4/16/2016 9:24 AM by Noxxa (see all 118)
BBLiT.lua v2
--local module definitions first
local bblitGUI = {}
do
	local areaX, areaY
	
	function bblitGUI.SetArea(x, y)
		areaX = x
		areaY = y
	end
	
	function bblitGUI.DrawValue(token, value)
		gui.text(areaX, areaY, string.format("%s: %d", token, value))
		areaY = areaY + 20
	end
	
	function bblitGUI.DrawVector3(token, value1, value2, value3)
		gui.text(areaX,areaY, string.format("%s: (%6d,%6d,%6d)", token, value1, value2, value3))
		areaY = areaY + 20
	end
end

local bblitAngle = {}
do
	-- Conversion as per: http://electronicstechnician.tpub.com/14091/css/14091_316.htm
	function bblitAngle.DegreesToBAMS(degrees)
		-- no conversion necessary
		if degrees == 360 or deg == 0 then
			return 0
		end
		-- need to convert
		local returnValue = 0
		
		local BAMSbits = 0x800
		local angularDegrees = 180
		
		while BAMSbits > 0 do
			if degrees >= angularDegrees then
				returnValue = returnValue + BAMSbits
				degrees = degrees - angularDegrees
			end
			
			BAMSbits = math.floor(BAMSbits / 2)
			angularDegrees = angularDegrees / 2
		end
		
		return returnValue
	end
	
	--TODO!
	function bblitAngle.BAMStoDegrees(bams)
		console.log("Function not implemented! bblitAngle.BAMStoDegrees")
	end
	
	function bblitAngle.ClampBAMS(bams)
		if bams < 0 then
			bams = bams + 4096
		end
		if bams == 4096 then
			bams = 0
		end
		return bams
	end
	
	function bblitAngle.Vector2ToDegrees(x, y)
		local angle = math.atan2(x, y)
		if angle < 0 then
			angle = angle + (math.pi * 2)
		end
		angle = math.deg(angle)
		return angle
	end
end

local bblitKeyboard = {}
do
	local keysToCheck = {"J", "K", "L"}
	local keys = {}
	local keysPrev = {}
	local keysDown = {}

	function bblitKeyboard.GetInput()
		keys = input.get()
		
		for i, v in ipairs(keysToCheck) do
			
			if keys[v] == true and keysPrev[v] ~= true then
				keysDown[v] = true
			else
				keysDown[v] = false
			end
			
		end
		
		keysPrev = keys
	end
	
	function bblitKeyboard.GetKey(token)
		return keys[token] == true
	end
	
	function bblitKeyboard.GetKeyDown(token)
		return keysDown[token] == true
	end
end

local bblitJoypad = {}
do
	function bblitJoypad.SetAnalog(x, y)
		local analogInput = {}
		analogInput["LStick X"] = x
		analogInput["LStick Y"] = y
		joypad.setanalog(analogInput, 1)
	end
end

local gui = bblitGUI
local angle = bblitAngle
local keyboard = bblitKeyboard
local joypad = bblitJoypad

-----------------------
-----------------------
------modules end------
-----------------------
-----------------------

local function CheckModule(name,mod)
	if mod ~= nil and mod ~= true then
		console.log("Module " .. name .. " successfully loaded.")
	else
		console.log("Module " .. name .. " failed to load! (value = " .. mod .. ")")
	end
end

do
	--Due to that the game internally runs at 30 fps despite rendering at 60 fps
	--the speed values cannot be updated each frame.
	--Apply some simpler logic to only update this once per 2 frames by using an
	--address that increments at 30 fps.
	--The updated flag solves an issue caused by using emu.yield()

	local Counter30FPS = 0
	local Counter30FPSOld = 0
	
	function CheckDoUpdate()
		Counter30FPS = memory.read_u32_le(0x00076010)
		if Counter30FPS == Counter30FPSOld then
			return false
		end
		Counter30FPSOld = Counter30FPS
		return true
	end
end

local Xpos, Ypos, Zpos =  0, 0, 0
local XposOld, YposOld, ZposOld = 0, 0, 0
local Xspeed, Yspeed, Zspeed = 0, 0, 0
local XZspeed, XYZspeed = 0, 0
local Xwaypoint, Ywaypoint, Zwaypoint = 0, 0, 0
local waypointActive,autowalkActive = false, false
local camAngle, bugsAngle, waypointAngle = 0, 0, 0
local diffAngle = 0

local inputX, inputY = 0, 0

local function SetWaypoint()
	--disable waypoints by 'double tapping' on the same spot
	if waypointActive == true and Xwaypoint == Xpos and Ywaypoint == Ypos and Zwaypoint == Zpos then
		waypointActive = false
	else
		waypointActive = true
		Xwaypoint = Xpos
		Ywaypoint = Ypos
		Zwaypoint = Zpos
	end
end

local function SetAutowalk()
	autowalkActive = not autowalkActive
	if not autowalkActive then
		inputX = 128
		inputY = 128
		joypad.SetAnalog(inputX, inputY)
		console.log("Autowalk disabled.")
	else
		console.log("Autowalk enabled.")
	end
end

local function CalculateAutowalk()

	local Xdistance = Xpos - Xwaypoint
	local Zdistance = Zpos - Zwaypoint

	if diffAngle <= 0 and diffAngle > -256 then
		local d = -diffAngle / 1.25
		--if d < 64 then d = d * 2 end
		inputX = 128 + d
		inputY = 0
	end
	if diffAngle >= 0 and diffAngle < 256 then
		local d = diffAngle / 1.25
		--if d < 64 then d = d * 2 end
		inputX = 128 - d
		inputY = 0
	end
	
	if diffAngle <= -256 and diffAngle > -512 then
		local d = -diffAngle / 4
		--if d < 64 then d = d * 2 end
		inputX = 128 + d
		inputY = 0
	end
	if diffAngle >= 256 and diffAngle < 512 then
		local d = diffAngle / 4
		--if d < 64 then d = d * 2 end
		inputX = 128 - d
		inputY = 0
	end
	
	if diffAngle <= -512 and diffAngle > -1024 then
		local d = -(diffAngle + 512) / 4
		inputX = 255
		inputY = 128 + d
	end
	if diffAngle >= 512 and diffAngle < 1024 then
		local d = (diffAngle - 512) / 4
		inputX = 0
		inputY = 128 + d
	end
	
	if diffAngle <= -1024 and diffAngle > -1536 then
		local d = -(diffAngle + 1024) / 4
		inputX = 255
		inputY = 128 + d
	end
	if diffAngle >= 1024 and diffAngle < 1536 then
		local d = (diffAngle - 1024) / 4
		inputX = 0
		inputY = 128 + d
	end
	
	if diffAngle <= -1536 and diffAngle > -2048 then
		local d = -(diffAngle + 1536) / 4
		inputX = 128 + d
		inputY = 255
	end
	if diffAngle >= 1536 and diffAngle < 2048 then
		local d = (diffAngle - 1536) / 4
		inputX = 128 + d
		inputY = 255
	end
	
	if math.sqrt(Xdistance*Xdistance + Zdistance*Zdistance) < 150 then
		inputX = 128
		inputY = 128
	end
	
	if inputX < 0 then inputX = 0 end
	if inputX > 255 then inputX = 255 end
	if inputY < 0 then inputY = 0 end
	if inputY > 255 then inputY = 255 end
	
	inputX = math.floor(inputX)
	inputY = math.floor(inputY)
end

local function Update()

	if not CheckDoUpdate() then return end
	
	--Actual speed vector addresses:
	--addr 00069D30 X Speed [signed dword]
	--addr 00069D34 Y Speed(?)  [signed dword]
	--addr 00069D38 Z Speed [signed dword]
	--This is not reliable as it shows the speed Bugs want to travel at,
	--not the actual speed that he moves at.
	--Use position as a source for speed instead

	Xpos = memory.read_s32_le(0x00069DC0)
	Ypos = memory.read_s32_le(0x00069DC4)
	Zpos = memory.read_s32_le(0x00069DC8)
	
	Xspeed = Xpos - XposOld
	Yspeed = Ypos - YposOld
	Zspeed = Zpos - ZposOld
	
	XZspeed = math.sqrt(Xspeed*Xspeed + Zspeed*Zspeed)
	XYZspeed = math.sqrt(Xspeed*Xspeed + Yspeed*Yspeed + Zspeed*Zspeed)
	
	camAngle = angle.ClampBAMS(-2048 + memory.read_s16_le(0x00069402))
	if XZspeed > 10 then
		bugsAngle = angle.DegreesToBAMS(angle.Vector2ToDegrees(Xspeed, Zspeed))
	end
	
	--bugsAngle = angle.ClampBAMS(memory.read_s16_le(0x000B8AAA))
	
	if waypointActive then
		local Xdistance = Xpos - Xwaypoint
		local Zdistance = Zpos - Zwaypoint
		waypointAngle = angle.ClampBAMS(-2048 + angle.DegreesToBAMS(angle.Vector2ToDegrees(Xdistance, Zdistance)))
		
		diffAngle = camAngle - waypointAngle
		if diffAngle < -2048 then diffAngle = diffAngle + 4096 end
		
		if autowalkActive == true then
			CalculateAutowalk()
			
			--console.log("Attempting to set input " .. inputX .. " " .. inputY)
			
			joypad.SetAnalog(inputX, inputY)
		end
	end
	
	

	XposOld = Xpos
	YposOld = Ypos
	ZposOld = Zpos
end

local function main()

	CheckModule("GUI", gui)
	CheckModule("Angle", angle)
	CheckModule("Keyboard", keyboard)
	
	joypad.SetAnalog(128, 128)

	while true do
		keyboard.GetInput()
		Update()
		
		if keyboard.GetKeyDown("J") == true then
			SetWaypoint()
		end
		if keyboard.GetKeyDown("K") == true then
			SetAutowalk()
		end
	
		gui.SetArea(20, 56)
		gui.DrawVector3("Position ", Xpos, Ypos, Zpos)
		gui.DrawVector3("Speed    ", Xspeed, Yspeed, Zspeed)
		gui.DrawValue(  "XZ Speed ", XZspeed)
		gui.DrawValue(  "XYZ Speed", XYZspeed)
		gui.DrawValue(  "Camera BAM Angle", camAngle)
		gui.DrawValue(  "Bugs BAM Angle  ", bugsAngle)
		if waypointActive then
			gui.DrawVector3("Waypoint ", Xwaypoint, Ywaypoint, Zwaypoint)
			gui.DrawValue(  "Waypoint BAM angle", waypointAngle)
			gui.DrawValue(  "Diff BAM angle", diffAngle)
		end
		if autowalkActive then
			local Xdistance = Xpos - Xwaypoint
			local Zdistance = Zpos - Zwaypoint
			gui.DrawValue(  "Autowalk X", inputX)
			gui.DrawValue(  "Autowalk Y", inputY)
			gui.DrawValue(  "Autowalk distance", math.sqrt(Xdistance*Xdistance + Zdistance*Zdistance))
		end
	
		emu.frameadvance()
	end
end

main()