ZSNES mouse: Lemmings

Danoz

New member
Has anybody done this? I'm assuming that Lemmings was a game that allowed for the mouse (if not, I'm surpised). I've tried to enable it on either port and it still doesn't work to let me move the cursor on the Lemmings screen. thanks!
 
I'm not 100% certain, but I think Lemmings was released well before Mario Paint (and therefore the SNES Mouse as well).
 
> Has anybody done this? I'm assuming that Lemmings was a game
> that allowed for the mouse (if not, I'm surpised). I've
> tried to enable it on either port and it still doesn't work
> to let me move the cursor on the Lemmings screen. thanks!

It doesn't support the SNES mouse.
 
SNES Lemmings with mouse

Hello,

very old thread, but I have a solution.

1. Save the following code as lemmmouse.lua

Code:
function LEMMINGSMouse()
	inp = input.get()
	pad = joypad.get(1)
	offset = -4
	--cursorx = memory.readbyte(0x7E0071)
	--cursory = memory.readbyte(0x7E0073)

    --gui.text(2, 60, cursorx)
	if(inp.xmouse+offset >= 0 and inp.xmouse+offset <= 246) then
		memory.writebyte(0x7E0071,inp.xmouse+offset)
	elseif(inp.xmouse+offset < 0) then
		memory.writebyte(0x7E0071,0)
	elseif(inp.xmouse+offset > 246) then
		memory.writebyte(0x7E0071,246)
	end
	--gui.text(2, 70, inp.xmouse+offset)

	
	--gui.text(2, 100, cursory)
		
	if(inp.ymouse+offset >= 0 and inp.ymouse+offset <= 214) then
		memory.writebyte(0x7E0073,inp.ymouse+offset)
	elseif(inp.ymouse+offset < 0) then
		memory.writebyte(0x7E0073,0)
	elseif(inp.ymouse+offset > 214) then
		memory.writebyte(0x7E0073,214)
	end
	--gui.text(2, 110, inp.ymouse+offset)

		
	if (inp.xmouse+offset > 245) then
        pad.right = true
		joypad.set(1,pad)		
	end
		
	if (inp.xmouse+offset < 1) then
        pad.left = true
		joypad.set(1,pad)		
	end
	
	if (inp.leftclick) then
		pad.A = true
		joypad.set(1,pad)
	end
	
	if (inp.rightclick) then
		pad.X = true
		joypad.set(1,pad)
	end	
	
end
gui.register(LEMMINGSMouse)



2. Use snes9x with LUA support.
hxxps:..github.com/gocha/snes9x/releases

3. Load Lemmings (Europe).zip (MD5 e51730370bf2b04a426b2a55b3f1972c)

4. Load my LUAscript and enjoy Lemmings with mouse :)

Have fun !
 
Sim City with mouse

I <3 the internet

If you like mouse supporton lemmings, maybe you like SimCity with mouse, too ;-)

lua is not very popular by newer emulators. It's a pity.
I would vote for it :)

Code:
print("SimCity grid viewer, for snes9x-rr 1.43 ~ 1.51")
print("written by Dammit, 2/21/2009 ~ 6/2/2011") --dammit9x at hotmail dot com
print("mouse support by crazygerry 2018")
print("tested with: https://github.com/gocha/snes9x/ 1.53 ~ 1.55")
--(old) use with: http://code.google.com/p/snes9x-rr/
--purpose: display land values and other parameters on the playfield for the SimCity game
--discussion: http://tasvideos.org/forum/viewtopic.php?p=192582#192582

local hotkey = { --hotkey settings
	mode_inc    = {"K", "cycle view modes forward (or middleclick)"},
	mode_dec    = {"L", "cycle view modes backward"},
	show_values = {"U", "show/hide grid values"},
	show_grid   = {"I", "show/hide the grid"},
	show_coords = {"O", "show/hide the map coordinates and city center"},
	num_format  = {"P", "switch between decimal & hex numbers"},
}

local globals = { --initial settings
	view_mode   = 1,
	show_values = true,
	show_grid   = true,
	show_coords = false,
	hex_numbers = false,
	use_mouse = true,
}

local label_x, label_y = 128, 216 --where to draw the view mode label
local coord_x, coord_y = 216, 216 --where to draw the map coordinates

local color = {
	["level 8"]     = 0xFF0000, --these are the in-game map colors
	["level 7"]     = 0xFF6300,
	["level 6"]     = 0xFFB500,
	["level 5"]     = 0xFFFF00,
	["level 4"]     = 0x00FF00,
	["level 3"]     = 0x00BD00,
	["level 2"]     = 0x008C00,
	["level 1"]     = 0x005A00,
	["powered"]     = 0xFF8400,
	["unpowered"]   = 0x00B500,
	["city center"] = 0xFF00FF,
	["dec text"]    = 0xFFFFFF, --grid values in decimal mode
	["hex text"]    = 0xFFFF00, --grid values in hexadecimal mode
	["label text"]  = 0x00FF00, --view mode label text
	["coord text"]  = 0x00FFFF, --coordinate text
}

local opacity = {
	fill    = 0x20, --inside of boxes
	outline = 0xA0, --outside of boxes
	text    = 0xFF,
}

--------------------------------------------------------------------------------

--prepare color settings
local fill, outline = {}, {}
local function map_colors(index, name)
	fill[index]    = bit.lshift(color[name], 8) + opacity.fill
	outline[index] = bit.lshift(color[name], 8) + opacity.outline
end

for i = 0xFF, 0, -1 do
	if i > 0xE0 then map_colors(i, "level 8")
	elseif i > 0xC0 then map_colors(i, "level 7")
	elseif i > 0xA0 then map_colors(i, "level 6")
	elseif i > 0x80 then map_colors(i, "level 5")
	elseif i > 0x60 then map_colors(i, "level 4")
	elseif i > 0x40 then map_colors(i, "level 3")
	elseif i > 0x20 then map_colors(i, "level 2")
	elseif i > 0x00 then map_colors(i, "level 1")
	else
		fill[i]    = 0 --blank/transparent
		outline[i] = 0
	end
end
map_colors(true, "powered")
map_colors(false, "unpowered")
map_colors("city center", "city center")
fill["dec text"]   = bit.lshift(color["dec text"], 8) + opacity.text
fill["hex text"]   = bit.lshift(color["hex text"], 8) + opacity.text
fill["label text"] = bit.lshift(color["label text"], 8) + opacity.text
fill["coord text"] = bit.lshift(color["coord text"], 8) + opacity.text

--memory addresses
local address = {
	x_tile   = 0x7E01BD, --camera position by upper-left tile
	y_tile   = 0x7E01BF,
	x_center = 0x7E0BA9, --coordinate of the city center
	y_center = 0x7E0BAA,
	playing  = 0x7E0012, --a game is in progress: draw coords
	hud      = 0x7E2210, --in-game HUD is shown: don't draw grid
	dark     = 0x7E90FF, --darkened BG: don't draw grid
	magnify  = 0x7E019B, --magnifier tool is open: draw grid
	time     = 0x7E0B51, --increments four times per game month; currently unused
	x_cursor = 0x7E01EB,
	y_cursor = 0x7E01ED,
	taxind   = 0x7E2016, -- holds some values to identify tax screen
}

--parameter values are stored here
local view = {
	{address = 0x7F6B00, sqsize = 2, bytes = 1, name = "Land value"},
	{address = 0x7F76B8, sqsize = 2, bytes = 1, name = "Crime"},
	{address = 0x7F8270, sqsize = 2, bytes = 1, name = "Pollution"},
	{address = 0x7F8E28, sqsize = 2, bytes = 1, name = "Population density"},
	{address = 0x7F99E0, sqsize = 2, bytes = 1, name = "Traffic"},
	{address = 0x7FA598, sqsize = 1, bytes = 1/8, name = "Power"},
	{address = 0x7FAB74, sqsize = 4, bytes = 1, name = "Land value modifier"},
	{address = 0x7FAE62, sqsize = 8, bytes = 2, name = "Growth rate"},
	{address = 0x7FAFE8, sqsize = 8, bytes = 1, name = "Police coverage"},
	{address = 0x7FB0AB, sqsize = 8, bytes = 1, name = "Fire coverage"},
}

local screenwidth, screenheight, tilesize = 256, 224, 8 --size in pixels
local mapwidth, mapheight = 120, 100 --size in tiles
local pressing_old = {} --array for keyboard input

for _, mode in ipairs(view) do
	mode.y_step = mapwidth / mode.sqsize
	mode.read = mode.bytes == 2 and memory.readwordsigned or memory.readbyte
end

print()
print("To enable the grid, hide the HUD with button Y or open the magnifier.")
print()
for _, v in pairs(hotkey) do
	print("Press the '" .. v[1] .. "' key to " .. v[2] .. ".")
end

function bit(p) --http://lua-users.org/wiki/BitwiseOperators
	return 2 ^ (p - 1)
end

function hasbit(x, p)
	return x % (p + p) >= p
end

local function draw_boxes()
	local x_tile, y_tile, mode = globals.x_tile, globals.y_tile, view[globals.view_mode]
	local y = 0
	while y < screenheight do
		local y_next = y + mode.sqsize * tilesize
		if y == 0 then
			y_next = (mode.sqsize - y_tile % mode.sqsize) * tilesize
		end
		if y_next > screenheight then
			y_next = screenheight
		end
		local x = 0
		while x < screenwidth do
			local x_next = x + mode.sqsize * tilesize
			if x == 0 then
				x_next = (mode.sqsize - x_tile % mode.sqsize) * tilesize
			end
			if x_next > screenwidth then
				x_next = screenwidth
			end
			if x_tile + x/tilesize >= 0 and y_tile + y/tilesize >= 0 --check the map boundaries
			and x_tile + x/tilesize < mapwidth and y_tile + y/tilesize < mapheight then
				local value = mode.read(mode.address + math.floor(
				(math.floor((x_tile + x/tilesize) / mode.sqsize)
				+ math.floor((y_tile + y/tilesize) / mode.sqsize) * mode.y_step) * mode.bytes))

				if globals.show_grid then
					if mode.read == memory.readwordsigned then
						if value > 0xFF then value = 0xFF end
						if value < -0xFF then value = -0xFF end
						value = math.floor((value + 0xFF) / 2)
					end
					if mode.bytes < 1 then
						value = hasbit(value, bit(8 - (x_tile + x/tilesize + (y_tile + y/tilesize) * mode.y_step) % 8))
					end
					gui.box(x, y, x_next-1, y_next-1, fill[value], outline[value])
				end

				if globals.show_values and value ~= 0 and mode.sqsize > 1 and
					x_next >= 2 * tilesize and y_next >= 2 * tilesize and
					x + 2 * tilesize <= screenwidth and y + 2 * tilesize <= screenheight then
					local color
					if globals.hex_numbers then
						value, color = string.format("%02X", value), fill["hex text"]
					else
						value, color = string.format("%d", value), fill["dec text"]
					end
					gui.text(x_next - value:len() * 4 - 1, y + 1, value, color)
				end

			end
			x = x_next
		end
		y = y_next
	end

	if globals.show_grid or globals.show_values then --show the label only with the grid or values active
		gui.text(label_x, label_y, mode.name, fill["label text"])
	end
end

local function draw_data()
	local x_tile, y_tile, x_center, y_center = globals.x_tile, globals.y_tile, globals.x_center, globals.y_center
	if globals.grid_ok then
		draw_boxes()
	end

	if globals.show_coords then --show the coordinates & city center
		if globals.use_mouse == false then
			gui.text(coord_x, coord_y, "(" .. x_tile .. ", " .. y_tile .. ")", fill["coord text"])
		end

		local xdraw, ydraw = (x_center - x_tile) * tilesize, (y_center - y_tile) * tilesize
		if x_center < x_tile then
			xdraw = 0
		end
		if x_center >= x_tile + screenwidth/tilesize then
			xdraw = screenwidth - tilesize
		end
		if y_center < y_tile then
			ydraw = 0
		end
		if y_center >= y_tile + screenheight/tilesize then
			ydraw = screenheight - tilesize
		end
		gui.box(xdraw, ydraw, xdraw + 7, ydraw + 7, fill["city center"], outline["city center"])
	end
end

local function mouse_support(inp)
	local taxscreenindicatorvalue = memory.readbyte(address.taxind)
	local taxscreenindicatorvalues = {131,133,135,137,139,141,195,197,199,201}
	local taxscreenvisible, movemap = false, false
	local pad = joypad.get(1)
	local x_mousepos, y_mousepos = math.floor(inp.xmouse/8), math.floor(inp.ymouse/8)
	local x_mouseonmap, y_mouseonmap = x_mousepos + memory.readbytesigned(address.x_tile), y_mousepos + memory.readbytesigned(address.y_tile)
	for i = 1, 10 do
		if taxscreenindicatorvalues[i] == taxscreenindicatorvalue then taxscreenvisible = true break end
	end
	if taxscreenvisible == false then	
		if(x_mouseonmap >= 0 and x_mouseonmap < mapwidth and y_mouseonmap >= 0 and y_mouseonmap < mapheight) then
			gui.text(coord_x, coord_y, "(" .. x_mouseonmap+1 .. ", " .. y_mouseonmap+1 .. ")", fill["coord text"])		
		end
		if(x_mouseonmap >= -6 and x_mouseonmap < mapwidth+6 and y_mouseonmap >= -6 and y_mouseonmap < mapheight+6) then
			memory.writebyte(address.x_cursor,x_mousepos*8)
			memory.writebyte(address.y_cursor,y_mousepos*8)			
		end
		if(inp.xmouse > 232) then memory.writebyte(address.x_cursor,232) end
		if(inp.xmouse < 16) then memory.writebyte(address.x_cursor,16) end
		if(inp.ymouse > 192) then memory.writebyte(address.y_cursor,192) end
		if(inp.ymouse < 24) then memory.writebyte(address.y_cursor,24) end
	end
	if (inp.xmouse >= screenwidth-1) then movemap, pad.right = true, true joypad.set(1,pad) end
	if (inp.xmouse <= 0) then movemap, pad.left = true, true joypad.set(1,pad) end
	if (inp.ymouse >= screenheight-1) then movemap, pad.down = true, true joypad.set(1,pad) end
	if (inp.ymouse <= 0) then movemap, pad.up = true, true joypad.set(1,pad) end
	if (movemap and inp.leftclick == false) then pad.Y = true end
	if (inp.leftclick) then pad.B = true joypad.set(1,pad) end
	if (inp.rightclick) then pad.X = true joypad.set(1,pad) end
end

emu.registerafter(function()
	globals.game_playing = memory.readbyte(address.playing) > 0
	if not globals.game_playing then
		pressing_old = {}
		return
	end

	globals.grid_ok = memory.readbyte(address.dark) == 0 and 
		(memory.readword(address.hud) == 0x5555 or memory.readbyte(address.magnify) > 0)
	globals.x_tile, globals.y_tile = memory.readbytesigned(address.x_tile), memory.readbytesigned(address.y_tile)
	globals.x_center, globals.y_center = memory.readbyte(address.x_center), memory.readbyte(address.y_center)
	
	local pressing = input.get()
	
	if (globals.show_grid or globals.show_values) and globals.grid_ok then
		if (pressing[hotkey.mode_inc[1]] or pressing.middleclick) and not (pressing_old[hotkey.mode_inc[1]] or pressing_old.middleclick) then
			globals.view_mode = globals.view_mode >= #view and 1 or globals.view_mode + 1
		elseif pressing[hotkey.mode_dec[1]] and not pressing_old[hotkey.mode_dec[1]] then
			globals.view_mode = globals.view_mode == 1 and #view or globals.view_mode - 1
		end
	end
	if pressing[hotkey.show_values[1]] and not pressing_old[hotkey.show_values[1]] and globals.grid_ok then
		globals.show_values = not globals.show_values
	end
	if pressing[hotkey.show_grid[1]] and not pressing_old[hotkey.show_grid[1]] and globals.grid_ok then
		globals.show_grid = not globals.show_grid
	end
	if pressing[hotkey.show_coords[1]] and not pressing_old[hotkey.show_coords[1]] then
		globals.show_coords = not globals.show_coords
	end
	if pressing[hotkey.num_format[1]] and not pressing_old[hotkey.num_format[1]] and globals.show_values then
		globals.hex_numbers = not globals.hex_numbers
	end

	pressing_old = pressing
end)

gui.register(function()
	if globals.game_playing then
		draw_data()
		if globals.use_mouse then
			mouse_support(input.get())
		end
	end
end)

Have fun !
 
Back
Top Bottom