User File #34528685310587594

Upload All User Files

#34528685310587594 - Lua for making TAS of DKC2

DKC2.lua
1058 downloads
Uploaded 10/24/2016 11:47 PM by hidaigai (see all 8)
--Donkey Kong Country 2 BizHawk TAS script
def_txt_color = 0x80ffffff
def_txt_color_deep = 0xc0ffffff

spr_data_size = 94
xm = client.screenwidth() / 256
ym = client.screenheight() / 224

-- FORM
local hndl=forms.newform(300,250,"Donkey Kong Country 2")
local hide_spr_data = forms.checkbox(hndl,"hide sprite data",10,0)
local spr_num_label = forms.label(hndl,"num:",140,7,30,15)
local disp_spr_num = forms.textbox(hndl,"7",30,20,"UNSIGNED",170,5)
forms.setproperty(hide_spr_data, "Checked",false)

local disp_all_spr_data = forms.label(hndl,"display all data of selected sprite",10,30,190,15)
local selected_spr = forms.textbox(hndl,"",30,20,"UNSIGNED",200,30)
local disp_spr_data = {
	forms.label(hndl,"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",10,50,300,15),
	forms.label(hndl,"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",10,70,300,15),
	forms.label(hndl,"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",10,90,300,15),
	forms.label(hndl,"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",10,110,300,15),
	forms.label(hndl,"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",10,130,300,15),
	forms.label(hndl,"00 00 00 00 00 00 00 00 00 00 00 00 00 00",10,150,300,15)
}

local hide_pos_data = forms.checkbox(hndl,"hide position data",10,170)
forms.setproperty(hide_pos_data,"Checked",false)

local ghost_display = forms.checkbox(hndl,"display ghost",10,190)
forms.setproperty(ghost_display,"Checked",false)

--forms.destroy(hndl)

-- LAG
local cur_lag
local prev_lag = 0
local laglength = 0
local laglength_display = 0
local lag_frame = {0,0,0}
local lag_frame_idx = 0

-- for GHOST
local filepath='ghosts/DKC2 1.1 Any% TAS - Comicalflop - Dooty - Umihoshi.dump'
local ddposepath='ghosts/DDtp.png'
local dxposepath='ghosts/DXtp.png'
local in_game_frame=0
local action_frame=0
local level=0
local room=0
local change_igframe = 0
local file_open = 0

local function draw_hitbox(boxid, direct, xpos, ypos, cam_x, cam_y, type)

--	memory.usememorydomain("System Bus")
--	local offset = memory.read_u16_le(0xbcb600 + bit.rshift(boxid, 1))
--	local xoff = memory.read_s16_le(0xbc0000 + offset)
--	local yoff = memory.read_s16_le(0xbc0002 + offset)
--	local width = memory.read_s16_le(0xbc0004 + offset)
--	local height = memory.read_s16_le(0xbc0006 + offset)
	memory.usememorydomain("CARTROM")
	local offset = memory.read_u16_le(0x3cb600 + bit.rshift(boxid, 1))
	local xoff = memory.read_s16_le(0x3c0000 + offset)
	local yoff = memory.read_s16_le(0x3c0002 + offset)
	local width = memory.read_s16_le(0x3c0004 + offset)
	local height = memory.read_s16_le(0x3c0006 + offset)
	memory.usememorydomain("WRAM")
	if bit.check(direct, 6) == true then
		xoff = - xoff
		width = - width
	end
	if bit.check(direct, 7) == true then
		yoff = - yoff
		height = - height
	end

	local x_screen = xpos - cam_x
	local y_screen = ypos - cam_y
	local color
	if type == 0xFFFF then
		color = 0x0000FF
	elseif type == 0x02fe or
	       type == 0x0302 then
		color = 0x00FF00
	else
		color = 0xFF0000
	end

--	gui.drawBox((x_screen + xoff)*xm, (y_screen + yoff)*ym, (x_screen + xoff + width)*xm, (y_screen + yoff + height)*ym, 0xFF000000+color, 0x40000000+color)
	gui.drawBox((x_screen + xoff), (y_screen + yoff), (x_screen + xoff + width), (y_screen + yoff + height), 0xFF000000+color, 0x40000000+color)

end

x = memory.read_u16_le(0x000A2A)
y = memory.read_u16_le(0x000A2C)
while true do

	spr_count = 0
	camera_x_prev = camera_x
	camera_y_prev = camera_y
	camera_x = memory.read_s16_le(0x0017BA)
	camera_y = memory.read_s16_le(0x0017C0)
	hold = memory.read_u16_le(0x000D7A)
	-- rope = memory.read_u8(0x000AEB)

--memory.write_u16_le(0x000D7A, 0x000E9E + spr_data_size * ?SpriteID?)

	-- sprite info
	for id = 0, 21 do
		base = 0x000E9E + spr_data_size * id
		stat = memory.read_u16_le(base)
		pos_x = memory.read_u16_le(base+0x6)
		pos_y = memory.read_u16_le(base+0xA)
		spd_x = memory.read_s16_le(base+0x20)
		spd_y = memory.read_s16_le(base+0x24)
		num = memory.read_u16_le(base+0x36)

		-- sprite info (type, x-pos, y-pos)
		if forms.ischecked(hide_spr_data) == false then
			disp_num = forms.gettext(disp_spr_num)
			if disp_num == "" then
				disp_num = "4"
			end
			if id < tonumber(disp_num) then
				disp_y = 80+id*15
				if (hold ~= 0) and ((hold-3742) / spr_data_size == id) then
					gui.text(2, disp_y, "+", def_txt_color_deep, 0x00000000)
				end
				if stat ~= 0 then
					gui.text(15, disp_y, "*", def_txt_color_deep, 0x00000000)
				end
				gui.text(30, disp_y, string.format("%d(%04x,%5d,%5d,%5d,%5d)", id, num, pos_x, pos_y, spd_x, spd_y), def_txt_color, 0x00000000)
			end
		end

		if stat ~= 0 then
			if forms.ischecked(hide_spr_data) == false then
				gui.text(xm * (pos_x - camera_x), ym * (pos_y - camera_y), string.format("%d(%x)", id, num), def_txt_color, 0x00000000)
			end
			draw_hitbox(memory.read_u16_le(base + 0x1A), memory.read_u16_le(base + 0x13), pos_x, pos_y, camera_x, camera_y, num)

			spr_count = spr_count + 1
		end

		selected_spr_num = forms.gettext(selected_spr)
		if selected_spr_num ~= "" then
			selected_spr_num = tonumber(selected_spr_num)
			if selected_spr_num == id then
				spr_data_line = ""
				for id_data = 0, spr_data_size-1 do
					if (id_data % 16 == 0) and (id_data ~= 0) then
						forms.setproperty(disp_spr_data[id_data/16], "Text", spr_data_line)
						spr_data_line = ""
					end
					spr_data_line = spr_data_line .. string.format("%02x ", memory.read_u8(base+id_data))
				end
				forms.setproperty(disp_spr_data[6], "Text", spr_data_line)
			end
		end
	end
	if forms.ischecked(hide_spr_data) == false then
		gui.text(2, 68, string.format("Count of Spr:%02d", spr_count), def_txt_color, 0x00000000)
	end

	-- Diddy & Dixie info
	x_prev = x
	y_prev = y
	--x = memory.read_u16_le(0x000A2A)
	--y = memory.read_u16_le(0x000A2C)
	x = memory.read_u32_le(0x000ABE)
	y = memory.read_u32_le(0x000AC2)
	x1 = memory.read_u16_le(0x000DE8)
	y1 = memory.read_u16_le(0x000DEC)
	x2 = memory.read_u16_le(0x000DE8 + spr_data_size)
	y2 = memory.read_u16_le(0x000DEC + spr_data_size)
	spx = memory.read_s16_le(0x000A30)
	spy = memory.read_s16_le(0x000A34)
	spx1 = memory.read_s16_le(0x000E02)
	spy1 = memory.read_s16_le(0x000E06)
	spx2 = memory.read_s16_le(0x000E02 + spr_data_size)
	spy2 = memory.read_s16_le(0x000E06 + spr_data_size)
	saru = memory.read_u8(0x0008A4)

	base = 0x000DE2
	draw_hitbox(memory.read_u16_le(base + 0x1A), memory.read_u16_le(base + 0x13), x1, y1, camera_x, camera_y, 0xFFFF)
	base = 0x000DE2 + spr_data_size
	draw_hitbox(memory.read_u16_le(base + 0x1A), memory.read_u16_le(base + 0x13), x2, y2, camera_x, camera_y, 0xFFFF)

	-- position info
	if forms.ischecked(hide_pos_data) == false then
		if hold == 3554 then
			gui.text(3, 400, "+", def_txt_color_deep, 0x00000000)
		elseif hold == 3648 then
			gui.text(3, 420, "+", def_txt_color_deep, 0x00000000)
		end
		if saru == 0 then
			gui.text(14, 400, "*", def_txt_color_deep, 0x00000000)
		else
			gui.text(14, 420, "*", def_txt_color_deep, 0x00000000)
		end
		gui.text(15, 380, string.format("(X:%5d/%3d, Y:%5d/%3d), (dX:%5d, dY:%5d)", bit.rshift(x,8), bit.band(x,0x000000FF), bit.rshift(y,8), bit.band(y,0x000000FF), x-x_prev, y-y_prev ), def_txt_color_deep, 0x00000000)
		gui.text(25, 400, string.format("Diddy (X:%5d, Y:%5d),(spX:%5d, spY:%5d)", x1, y1, spx1, spy1 ), def_txt_color_deep, 0x00000000)
		gui.text(25, 420, string.format("Dixie (X:%5d, Y:%5d),(spX:%5d, spY:%5d)", x2, y2, spx2, spy2 ), def_txt_color_deep, 0x00000000)
	end

	-- lag info
	cur_lag = emu.lagcount()
	if cur_lag ~= prev_lag then
		lag_frame_idx = ((lag_frame_idx+1)%3)
		lag_frame[lag_frame_idx+1] = emu.framecount()
		laglength = laglength+1
		laglength_display = laglength
	else
		laglength = 0
	end
	gui.text(180, 10, "LAG:", def_txt_color, 0x00000000)
	for i = 0, 2 do
		if lag_frame[i+1] ~= 0 then
			if lag_frame_idx == i then
				warn_color = 0xFFFF0000
			else
				warn_color = def_txt_color
			end
			gui.text((240+75*i), 10, lag_frame[i+1], warn_color, 0x00000000)
		end
	end
	if (laglength_display == laglength) and (laglength ~= 0) then
		gui.text(180, 25, "(LAG LENGTH:"..laglength_display..")", 0xFFFF0000, 0x00000000)
	else
		gui.text(180, 25, "(LAG LENGTH:"..laglength_display..")", def_txt_color, 0x00000000)
	end
	prev_lag = cur_lag

	-- level info
	level_prev = level
	room_prev = room
	level = memory.read_u8(0x0006AB)
	room = memory.read_u8(0x000D3)
	if forms.ischecked(hide_pos_data) == false then
		gui.text(5, 360, string.format("Level:%02X(%02X)", level, room), def_txt_color_deep, 0x00000000)
		gui.text(2, 50, string.format("Camera:(%d,%d)", camera_x, camera_y), def_txt_color, 0x00000000)
		--gui.text(2, 50, string.format("Camera (X:%5d, Y:%5d),(dX:%5d, dY:%5d)", camera_x, camera_y, camera_x-camera_x_prev, camera_y-camera_y_prev ), def_txt_color, 0x00000000)
	end

	-- display ghost
	if forms.ischecked(ghost_display) == true then

		in_game_frame_prev = in_game_frame
		in_game_frame = memory.read_u16_le(0x0002C)
		action_frame_prev = action_frame
		action_frame = memory.read_u32_le(0x000D5)

		--debug info
		--gui.text(5, 345, line, def_txt_color, 0x00000000)
		--gui.text(140, 360, string.format("Time:%d(%d)", in_game_frame, action_frame), def_txt_color, 0x00000000)

		if (level ~= level_prev) then
			io.input(filepath)
			file_open = 1

			-- skip first 1024 frame
			for i=1,1024 do
				io.read()
			end

			-- search first frame of current place
			while true do
				line = io.read()
				if not line then
					break
				end
				_,_,area_g = string.find(line, "^%d+ (%x+ %x+).+")
				if string.format("%02X %02X",level,room) == area_g then
					break
				end
			end

			-- skip frame for level 5-6
			if (level == 0x33) and (room == 0x0D) then
				for i=1,32 do
					io.read()
				end
			end

		end
		if (level == level_prev) and (room ~= room_prev) then
			for i=1,32 do
				io.read()
			end
		end

		if file_open == 1 then
			if in_game_frame == in_game_frame_prev then
				change_igframe = 0
			else
				if change_igframe == 0 then
					-- search first in-game frame of current room
					line = io.read()
					_,_,ig_g_prev = string.find(line, "^%d+ %x+ %x+ (%d+).+")
					while true do
						line = io.read()
						if not line then
							break
						end
						_,_,ig_g = string.find(line, "^%d+ %x+ %x+ (%d+).+")
						if ig_g ~= ig_g_prev then
							break
						end
					end
					change_igframe = 1
				else
					if change_igframe == 1 then
						change_igframe = 2
						max_cnt = 1
						if (level == 0x1C and room == 0x01) or (level == 0x20) or
						   (level == 0x2A) or
						   (level == 0x34) then
							max_cnt = 2
						end
						if (level == 0x1B) then
							max_cnt = 3
						end
						for i=1,max_cnt do
							io.read()
						end
					else
						line = io.read()
					end
				end
			end

			if action_frame ~= action_frame_prev then
				gui.text(xm * (x1 - camera_x) - 8, ym * (y1 - camera_y) - 24, "DD", 0xFF0000FF, 0x00000000)
				gui.text(xm * (x2 - camera_x) - 8, ym * (y2 - camera_y) - 24, "DX", 0xFF0000FF, 0x00000000)

				_,_, frame_g, area_g, ig_g, x1_g, y1_g, x2_g, y2_g = string.find(line, "^(%d+) (%x+ %x+) (%d+) (%d+) (%d+) (%d+) (%d+)")
				gui.text(xm * (x1_g - camera_x) - 8, ym * (y1_g - camera_y) - 24, "DD", 0xFF00FF00, 0x00000000)
				gui.text(xm * (x2_g - camera_x) - 8, ym * (y2_g - camera_y) - 24, "DX", 0xFF00FF00, 0x00000000)

				-- display when active kong motion differ
				threshold = 10
				if (saru==0 and (math.abs(x1-x1_g)>threshold or math.abs(y1-y1_g)>threshold)) or
				   (saru~=0 and (math.abs(x2-x2_g)>threshold or math.abs(y2-y2_g)>threshold)) then
					gui.drawImage(ddposepath, x1_g-camera_x-20, y1_g-camera_y-38, 48, 40)
					gui.drawImage(dxposepath, x2_g-camera_x-16, y2_g-camera_y-36, 32, 38)
				end
			end
		end
	end

	emu.frameadvance()
end