All pastes #1364116 Raw Edit

sonic_mousecontrol.lua

public lua v1 · immutable
#1364116 ·published 2009-03-18 07:29 UTC
rendered paste body
-- Sonic - Mouse Control-- Adds the ability to move game objects using the mouse.-- Written by: deltaphcif not gens.emulating() then	error("ROM must be loaded first.")endchecksum = memory.readword(0x18E)if checksum == 0x264A or checksum == 0xAFC7 then -- Sonic 1	print("Detected Sonic 1.")	ostentry = "s1s2"	addr_xcamera = 0xFFF700	addr_ycamera = 0xFFF616	addr_startedflag = 0xFFFE02	addr_dirtyflag = 0xFFF72C	addr_levellayout = 0xFFA400	addr_ost = 0xFFD000	addr_ostend = 0xFFEFFF	ost_length = 0x40	ost_x = 0x08	ost_y = 0x0C	ost_xspeed = 0x10	ost_yspeed = 0x12	level_rowlength = 0x40	level_tilesize = 256elseif checksum == 0xD951 then -- Sonic 2	print("Detected Sonic 2.")	ostentry = "s1s2"	addr_xcamera = 0xFFEE00	addr_ycamera = 0xFFEE04	addr_startedflag = 0xFFF711	addr_dirtyflag = 0xFFF72C	addr_levellayout = 0xFF8000	addr_ost = 0xFFB000	addr_ostend = 0xFFD5FF	ost_length = 0x40	ost_x = 0x08	ost_y = 0x0C	ost_xspeed = 0x10	ost_yspeed = 0x12	level_rowlength = 0x80	level_tilesize = 128elseif checksum == 0xA8F2 or checksum == 0xDFB3 then -- Sonic 3/K	print("Detected Sonic 3/K.")	ostentry = "s3sk"	addr_xcamera = 0xFFEE78	addr_ycamera = 0xFFEE7C	addr_startedflag = 0xFFF711	addr_dirtyflag = 0xFFF72C	addr_levellayout = 0xFF8000	addr_ost = 0xFFB000	addr_ostend = 0xFFCFCB	ost_length = 0x4A	ost_x = 0x10	ost_y = 0x14	ost_xspeed = 0x18	ost_yspeed = 0x1A	level_rowlength = 0 -- varies per level	level_tilesize = 128else	error("Unable to detect game. Make sure it's a clean Sonic 1/2/3/K ROM.")enddragobject = nilxmouse = 0ymouse = 0xmousedelta = 0ymousedelta = 0leftclickdown = falserightclickdown = falseinput_state = {}draw_queue = {}pinned = {}memory.register(addr_startedflag, function()	if memory.readbyte(addr_startedflag) == 0 then		pinned = {}	endend)gui.register( function()	local item = draw_queue[1]	while item do		item[1](item[2], item[3], item[4], item[5], item[6], item[7])				table.remove(draw_queue, 1)		item = draw_queue[1]	end		input_state = input.get()		if do_button("Objects", 0, 216, 30, 7) then		workfunc = work_objects	end		if ostentry == s1s2_ostentry then		if do_button("Tiles", 35, 216, 22, 7) then			workfunc = work_tiles		end	endend)gens.registerbefore( function()	local xcamera = memory.readword(addr_xcamera)	local ycamera = memory.readword(addr_ycamera)		xmousedelta = input_state.xmouse - xmouse	ymousedelta = input_state.ymouse - ymouse	xmouse = input_state.xmouse	ymouse = input_state.ymouse		workfunc(xcamera, ycamera)end)function work_tiles(xcamera, ycamera)	local xtile1, ytile1, tilepos, tilenum, x1, y1, x2, y2	xtile1 = math.floor((xcamera + xmouse) / level_tilesize)	ytile1 = math.floor((ycamera + ymouse) / level_tilesize)	tilepos = addr_levellayout + (((ytile1 * level_rowlength) * 2) + xtile1)	tilenum = memory.readbyte(tilepos)		x1 = (xtile1 * level_tilesize) - xcamera	y1 = (ytile1 * level_tilesize) - ycamera	x2 = x1 + level_tilesize	y2 = y1 + level_tilesize		table.insert(draw_queue, {gui.box, x1, y1, x2, y2, {0,0,0,0}, {255, 255, 255, 255}})	table.insert(draw_queue, {gui.text, x1 + 2, y1 + 2, string.format("%02X", tilenum)})		if do_button("-", x2 - 17, y1 + 2, 7, 9) then		memory.writebyte(tilepos, tilenum - 1)		memory.writebyte(addr_dirtyflag, 1)	end		if do_button("+", x2 - 9, y1 + 2, 7, 9) then		memory.writebyte(tilepos, tilenum + 1)		memory.writebyte(addr_dirtyflag, 1)	endendfunction work_objects(xcamera, ycamera)	local i, entry, x1, y1, x2, y2, outline_color	for i=addr_ost,addr_ostend,ost_length do		entry = ostentry(i)		if entry then			local width, height						if entry.widthhalf > 0 then				width = entry.widthhalf			elseif entry.width > 0 then				width = entry.width			else				width = 8			end						if ostentry == s1s2_ostentry then				if entry.heighthalf > 0 then					height = entry.heighthalf				else					height = 8				end			elseif ostentry == s3sk_ostentry then								if entry.heighthalf > 0 then					height = entry.heighthalf				elseif entry.height > 0 then					height = entry.height				else					height = 8				end			end						if pinned[tostring(entry.baseaddr)] == nil then				x1 = (entry.x - width) - xcamera				y1 = (entry.y - height) - ycamera				x2 = (entry.x + width) - xcamera				y2 = (entry.y + height) - ycamera			else				local x = pinned[tostring(entry.baseaddr)][1]				local y = pinned[tostring(entry.baseaddr)][2]							x1 = x - width				y1 = y - height				x2 = x + width				y2 = y + height								memory.writeword(i + ost_x, xcamera + x)				memory.writeword(i + ost_y, ycamera + y)				memory.writeword(i + ost_xspeed, 0)				memory.writeword(i + ost_yspeed, 0)			end			    			if (xmouse >= x1 and ymouse >= y1) and				(xmouse <= x2 and ymouse <= y2) then				outline_color = {255, 0, 0, 255}								if input_state.leftclick then					if pinned[tostring(entry.baseaddr)] ~= nil then						pinned[tostring(entry.baseaddr)][1] = xmouse						pinned[tostring(entry.baseaddr)][2] = ymouse					end										if not leftclickdown then						dragobject = entry.baseaddr						leftclickdown = true					end				else					leftclickdown = false					dragobject = nil				end								if input_state.rightclick then					if not rightclickdown then						if pinned[tostring(entry.baseaddr)] == nil then							pinned[tostring(entry.baseaddr)] = {xmouse, ymouse}						else							pinned[tostring(entry.baseaddr)] = nil						end												rightclickdown = true					end				else					rightclickdown = false				end			else				if pinned[tostring(entry.baseaddr)] ~= nil then					outline_color = {0, 255, 0, 255}				else					outline_color = {255, 255, 255, 255}				end			end						if dragobject ~= nil then				if pinned[tostring(dragobject)] ~= nil then					pinned[tostring(dragobject)][1] = xmouse					pinned[tostring(dragobject)][2] = ymouse				end							memory.writeword(dragobject + ost_x, xcamera + xmouse)				memory.writeword(dragobject + ost_y, ycamera + ymouse)				memory.writeword(dragobject + ost_xspeed, xmousedelta * 100)				memory.writeword(dragobject + ost_yspeed, ymousedelta * 100)			end						table.insert(draw_queue, {gui.box, x1, y1, x2, y2, {0,0,0,0}, outline_color})		end	endendfunction s1s2_ostentry(address)	local entry = {}		entry.baseaddr = address		entry.id          = memory.readbyte(address)	if entry.id == 0 or entry.id == nil then return nil end		entry.renderflags = memory.readbyte(address + 0x01)	entry.artindex    = memory.readword(address + 0x02)	entry.mappings    = memory.readdword(address + 0x04)	entry.x           = memory.readword(address + 0x08)	entry.xsub        = memory.readword(address + 0x0A)	entry.y           = memory.readword(address + 0x0C)	entry.ysub        = memory.readword(address + 0x0E)	entry.xspeed      = memory.readword(address + 0x10)	entry.yspeed      = memory.readword(address + 0x12)	entry.inertia     = memory.readword(address + 0x14)	entry.heighthalf  = memory.readbyte(address + 0x16)	entry.widthhalf   = memory.readbyte(address + 0x17)	entry.priority    = memory.readbyte(address + 0x18)	entry.width       = memory.readbyte(address + 0x19)	entry.dispframe   = memory.readbyte(address + 0x1A)	entry.animframe   = memory.readbyte(address + 0x1B)	entry.animnum     = memory.readbyte(address + 0x1C)	entry.animrestart = memory.readbyte(address + 0x1D)	entry.animtime    = memory.readbyte(address + 0x1E)	entry.collision   = memory.readbyte(address + 0x20)	entry.colcustom   = memory.readbyte(address + 0x21)	entry.status      = memory.readbyte(address + 0x22)	entry.respawn     = memory.readbyte(address + 0x23)	entry.counter     = memory.readbyte(address + 0x24)	entry.counter2    = memory.readbyte(address + 0x25)	entry.angle       = memory.readbyte(address + 0x26)	entry.angle2      = memory.readbyte(address + 0x27)	entry.subtype     = memory.readbyte(address + 0x28)	entry.parent      = memory.readword(address + 0x3E)		return entryendfunction s3sk_ostentry(address)	local entry = {}		entry.baseaddr = address		entry.pointer     = memory.readdword(address)	if entry.pointer == 0 or entry.pointer == nil then return nil end		entry.renderflags = memory.readbyte(address + 0x04)	entry.routine     = memory.readbyte(address + 0x05)	entry.height      = memory.readbyte(address + 0x06)	entry.width       = memory.readbyte(address + 0x07)	entry.priority    = memory.readword(address + 0x08)	entry.artindex    = memory.readword(address + 0x0A)	entry.mappings    = memory.readdword(address + 0x0C)	entry.x           = memory.readword(address + 0x10)	entry.xsub        = memory.readword(address + 0x12)	entry.y           = memory.readword(address + 0x14)	entry.ysub        = memory.readword(address + 0x16)	entry.xspeed      = memory.readword(address + 0x18)	entry.yspeed      = memory.readword(address + 0x1A)	entry.inertia     = memory.readword(address + 0x1C)	entry.heighthalf  = memory.readbyte(address + 0x1E)	entry.widthhalf   = memory.readbyte(address + 0x1F)	entry.animnum     = memory.readbyte(address + 0x20)	entry.animrestart = memory.readbyte(address + 0x21)	entry.dispframe   = memory.readbyte(address + 0x22)	entry.animframe   = memory.readbyte(address + 0x23)	entry.animtime    = memory.readbyte(address + 0x24)	entry.animcounter = memory.readbyte(address + 0x25)	entry.angle       = memory.readbyte(address + 0x26)	entry.angle2      = memory.readbyte(address + 0x27)	entry.collision   = memory.readbyte(address + 0x28)	entry.colcustom   = memory.readbyte(address + 0x29)	entry.status      = memory.readbyte(address + 0x2A)	entry.shieldreact = memory.readbyte(address + 0x2B)	entry.subtype     = memory.readbyte(address + 0x2C)	entry.respawn     = memory.readword(address + 0x48)		return entryendfunction do_button(text, x, y, width, height)	local return_value, fill_color, outline_color		if (input_state.xmouse >= x and input_state.ymouse >= y) and		(input_state.xmouse <= x + width and input_state.ymouse <= y + height) then		outline_color = {255, 255, 255, 255}				if input_state.leftclick then			if not leftclickdown then				return_value = true				leftclickdown = true			end						fill_color = {127, 0, 0, 255}		else			leftclickdown = false			fill_color = {0, 0, 192, 255}		end	else		fill_color = {0, 0, 127, 255}		outline_color = {0, 0, 255, 255}	end	gui.box(x, y, x + width, y + height, fill_color, outline_color)	gui.text(x + 2, y + 2, text, {255, 255, 255, 255}, {0, 0, 0, 0})		return return_valueendif ostentry == "s1s2" then	ostentry = s1s2_ostentryelseif ostentry == "s3sk" then	ostentry = s3sk_ostentryendworkfunc = work_objects