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_ost = 0xFFD000 addr_ostend = 0xFFEFFF ost_length = 0x40 ost_x = 0x08 ost_y = 0x0C ost_xspeed = 0x10 ost_yspeed = 0x12elseif checksum == 0xD951 then -- Sonic 2 print("Detected Sonic 2.") ostentry = "s1s2" addr_xcamera = 0xFFEE00 addr_ycamera = 0xFFEE04 addr_startedflag = 0xFFF711 addr_ost = 0xFFB000 addr_ostend = 0xFFD5FF ost_length = 0x40 ost_x = 0x08 ost_y = 0x0C ost_xspeed = 0x10 ost_yspeed = 0x12elseif 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_ost = 0xFFB000 addr_ostend = 0xFFCFCB ost_length = 0x4A ost_x = 0x10 ost_y = 0x14 ost_xspeed = 0x18 ost_yspeed = 0x1Aelse error("Unable to detect game. Make sure it's a clean Sonic 1/2/3/K ROM.")endxmouse = 0ymouse = 0xmousedelta = 0ymousedelta = 0draw_queue = {}pinned = {}rightclickdown = falsememory.register(addr_startedflag, function() if memory.readbyte(addr_startedflag) == 0 then pinned = {} endend)gui.register( function() local item = draw_queue[1] while item do gui.box(item[1], item[2], item[3], item[4], item[5], item[6]) table.remove(draw_queue, 1) item = draw_queue[1] endend)gens.registerbefore( function() local xcamera = memory.readword(addr_xcamera) local ycamera = memory.readword(addr_ycamera) local input_state = input.get() xmousedelta = input_state.xmouse - xmouse ymousedelta = input_state.ymouse - ymouse xmouse = input_state.xmouse ymouse = input_state.ymouse 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 memory.writeword(i + ost_x, xcamera + xmouse) memory.writeword(i + ost_y, ycamera + ymouse) memory.writeword(i + ost_xspeed, xmousedelta * 100) memory.writeword(i + ost_yspeed, ymousedelta * 100) 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 table.insert(draw_queue, {x1, y1, x2, y2, {0,0,0,0}, outline_color}) end endend)function 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 entryendif ostentry == "s1s2" then ostentry = s1s2_ostentryelseif ostentry == "s3sk" then ostentry = s3sk_ostentryend