Native module fuckery

This commit is contained in:
Empathic Qubit 2021-04-28 04:01:22 -04:00
parent 36d945cf47
commit 1718aa1b8b
12 changed files with 1409 additions and 24 deletions

1
.gitignore vendored
View file

@ -7,3 +7,4 @@ crashsave*
*.lsvs
config.lua
*.sfc
luaenv/

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule ".\\3rdparty\\luasocket"]
path = .\\3rdparty\\luasocket
url = https://github.com/diegonehab/luasocket

21
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,21 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "launch-lua",
"type": "lua",
"request": "launch",
"workingDirectory": "${workspaceRoot}",
"sourceBasePath": "${workspaceRoot}",
"executable": "lsnes-bsnes.exe",
"arguments": "--lua=${workspaceFolder}/neat-donk.lua",
"listenPublicly": false,
"listenPort": 56789,
"encoding": "UTF-8",
"env": {}
}
]
}

1
3rdparty/luasocket vendored Submodule

@ -0,0 +1 @@
Subproject commit 5b18e475f38fcf28429b1cc4b17baee3b9793a62

95
install.lua Normal file
View file

@ -0,0 +1,95 @@
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local Promise = dofile(base.."/promise.lua")
local makeproxy = dofile(base.."/makeproxy.lua")
local util = dofile(base.."/util.lua")
--- Echo a command, run it, and display its results
--- @param cmd string The command to execute
--- @param workdir string The working directory
local function doCmd(cmd, workdir)
local poppet = util.doCmd(cmd, workdir)
print(poppet:read("*a"))
poppet:close()
end
--- Timer loop that triggers promises
local function timer()
Promise.update()
set_timer_timeout(1)
end
callback.register('timer', timer)
set_timer_timeout(1)
--- Create directory
--- @param dir string Path of directory to create
local function mkdir (dir)
local poppet = util.mkdir(dir)
print(poppet:read("*a"))
poppet:close()
end
local waitKeyDownQueue = {}
--- Triggers on pressing a key, but only once
--- @param key string Key to monitor
--- @return Promise Promise A Promise that resolves when the key is pressed
local function waitKeyDown(key)
input.keyhook(key, true)
local item = {
promise = Promise.new(),
key = key,
}
table.insert(waitKeyDownQueue, item)
return item.promise
end
local function keyhook(key, state)
for i=#waitKeyDownQueue,1,-1 do
local hook = waitKeyDownQueue[i]
if hook.key == key and state.value == 1 then
table.remove(waitKeyDownQueue, i).promise:resolve(key)
end
end
end
callback.register('keyhook', keyhook)
local luabase = util.luaenv.."/lua"
local luabin = luabase.."/bin"
local lualib = luabase.."/lib"
local luazip = util.luaenv.."/lua.zip"
local lualibzip = util.luaenv.."/lua_lib.zip"
if util.isWin then
print("Creating luaenv directory...")
mkdir(util.luaenv)
local xzzip = util.luaenv..'/xz.zip'
local xz = util.luaenv..'/xz'
print("Downloading xz...")
util.downloadFile("https://tukaani.org/xz/xz-5.2.5-windows.zip", xzzip)
mkdir(xz)
util.unzip(xzzip, xz)
print("Downloading Lua...")
util.downloadFile("https://downloads.sourceforge.net/project/luabinaries/5.2.4/Tools%20Executables/lua-5.2.4_Win32_bin.zip", luazip)
util.downloadFile("https://versaweb.dl.sourceforge.net/project/luabinaries/5.2.4/Windows%20Libraries/Dynamic/lua-5.2.4_Win32_dllw6_lib.zip", lualibzip)
mkdir(luabase)
mkdir(luabin)
util.unzip(luazip, luabin)
util.unzip(lualibzip, luabase)
mkdir(lualib)
os.rename(luabase.."/lua52.dll", lualib.."/lua52.dll")
-- FIXME Linux will still need this tho?
makeproxy()
else
-- FIXME
print('Please install lua and xz manually...')
end

103
makeproxy.lua Normal file
View file

@ -0,0 +1,103 @@
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local util = dofile(base.."/util.lua")
local CFILE = util.luaenv.."/luaproxy.c" -- Name of the C file for the proxy DLL
local SYMBOLS = util.luaenv.."/luasymbols.h" -- Name of the file of Lua symbols
local LUADLL = util.luaenv.."/lua/lib/lua52.dll" -- Name of a real Lua DLL (to get exported symbols)
----------------------------------------------------------------------
return function()
local cfile = assert(io.open(CFILE, "w"))
cfile:write [=[
#include <windows.h>
static struct {
#define SYMBOL(name) FARPROC name;
#include "luasymbols.h"
#undef SYMBOL
}
s_funcs;
/* Macro for defining a proxy function.
This is a direct jump (single "jmp" assembly instruction"),
preserving stack and return address.
The following uses MSVC inline assembly which may not be
portable with other compilers.
*/
#define SYMBOL(name) \
void __declspec(dllexport,naked) name() { __asm { jmp s_funcs.name } }
#include "luasymbols.h"
#undef SYMBOL
BOOL APIENTRY
DllMain(HANDLE module, DWORD reason, LPVOID reserved)
{
HANDLE h = GetModuleHandle(NULL);
#define SYMBOL(name) s_funcs.name = GetProcAddress(h, #name);
#include "luasymbols.h"
#undef SYMBOL
return TRUE;
}
]=]
cfile:close()
local pexportstar = util.luaenv.."/pexports.tar.xz"
util.downloadFile('https://downloads.sourceforge.net/project/mingw/MinGW/Extension/pexports/pexports-0.47/pexports-0.47-mingw32-bin.tar.xz', pexportstar)
util.unzip(pexportstar, util.luaenv)
local pexports = util.luaenv.."/bin/pexports.exe"
local symbols = util.doCmd('"'..pexports..'" "'..LUADLL..'"', base)
local symfile = io.open(SYMBOLS, "w")
for sym in symbols:lines() do
-- Skip the LIBRARY and EXPORTS lines
local start = sym:sub(1,3)
if start ~= "LIB" and start ~= "EXP" then
symfile:write("SYMBOL("..sym..")\n")
end
end
symbols:close()
symfile:close()
local hostArch = os.getenv('PROCESSOR_ARCHITECTURE'):gsub("AMD", "x")
local arch = ""
if hostArch == 'x86' then
arch = 'x86'
else
arch = 'x64_x86'
end
local vswhere = util.luaenv..'/vswhere.exe'
util.downloadFile('https://github.com/microsoft/vswhere/releases/download/2.8.4/vswhere.exe', vswhere)
local poppet = util.doCmd('"'..vswhere..'" -products "*" -latest -property installationPath', util.luaenv)
local vsPath = poppet:read("*l")
poppet:read("*a")
poppet:close()
print("Visual Studio Installation path: "..vsPath)
local poppet = util.doCmd([[powershell "(Get-ChildItem -Recurse ']]..vsPath..[[' -Filter 'vcvarsall.bat').FullName"]])
local vcvarsallPath = poppet:read("*l")
poppet:close()
print("vcvarsall.bat Path: "..vcvarsallPath)
poppet = util.doCmd(
'"'..vcvarsallPath..'" '..arch..' 2>&1 && "cl.exe" /O2 /LD /GS- "'..
CFILE..'" /link /out:"'..
util.luaenv..'/lua52.dll" /nodefaultlib /entry:DllMain kernel32.lib 2>&1',
base,
{
VSCMD_ARG_HOST_ARCH = hostArch,
VSCMD_ARG_TGT_ARCH = 'x86'
}
)
print(poppet:read("*a"))
poppet:close()
end

View file

@ -5,7 +5,11 @@ local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local game = dofile(base.."/game.lua")
local config = dofile(base.."/config.lua")
local pool = dofile(base.."/pool.lua")
local util = dofile(base.."/util.lua")
local json = require 'dkjson'
local debuggee = dofile(base..'/vscode-debuggee.lua')
local startResult, breakerType = debuggee.start(json)
print('debuggee start ->', startResult, breakerType)
local statusLine = nil
local statusColor = 0x0000ff00
@ -31,4 +35,4 @@ pool.onRenderForm(function(form)
gui.text(-500, guiHeight - 20, statusLine, 0x00000000)
end
end)
pool.run()
pool.run()

View file

@ -770,4 +770,4 @@ function _M.run(reset)
end
end
return _M
return _M

View file

@ -129,4 +129,4 @@ return function()
end
return _M
end
end

View file

@ -1,20 +1,3 @@
PARTY_X = 0x7e0a2a
TILE_SIZE = 32
print(memory.readword(PARTY_X))
function on_post_rewind()
print("Async?")
print(memory.readword(PARTY_X))
end
function movement(addr, val)
if memory.readword(addr) > TILE_SIZE * 20 then
local rew = movie.to_rewind("pool/PiratePanic.lsmv")
movie.unsafe_rewind(rew)
print("Sync?")
print(memory.readword(PARTY_X))
end
end
memory2.WRAM:registerwrite(0x0a2a, movement)
for k,v in pairs(_SYSTEM._G) do
print(k)
end

View file

@ -1,5 +1,77 @@
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local _M = {}
_M.isWin = package.config:sub(1,1) == "\\"
_M.luaenv = base.."/luaenv"
--- Echo a command, run it, and return the file handle
--- @param cmd string The command to execute
--- @param workdir string The working directory
function _M.doCmd(cmd, workdir, env)
local cmdParts = {}
if workdir ~= nil then
if _M.isWin then
table.insert(cmdParts, 'cd /d "'..workdir..'" &&')
else
table.insert(cmdParts, 'cd "'..workdir..'" &&')
end
end
if env ~= nil then
for k,v in pairs(env) do
if _M.isWin then
table.insert(cmdParts, string.format("set %s=%s&&", k, v))
else
table.insert(cmdParts, string.format("%s='%s'", k, v))
end
end
end
table.insert(cmdParts, cmd)
local fullCmd = table.concat(cmdParts, " ")
print(fullCmd)
return io.popen(fullCmd, 'r')
end
--- Create directory
--- @param dir string Path of directory to create
function _M.mkdir (dir)
return _M.doCmd('mkdir "'..dir..'" 2>&1')
end
--- Unzip a ZIP file with unzip or tar
--- @param zipfile string The ZIP file path
--- @param dest string Where to unzip the ZIP file. Beware ZIP bombs.
function _M.unzip (zipfile, dest)
local xzPath = 'xz'
if _M.isWin then
xzPath = _M.luaenv..'/xz/bin_i686-sse2/xz.exe'
end
local poppet = nil
if zipfile:sub(-3):upper() == '.XZ' then
poppet = _M.doCmd('"'..xzPath..'" -d "'..zipfile..'"', dest)
print(poppet:read("*a"))
poppet:close()
zipfile = zipfile:sub(1, -3)
print(zipfile)
end
poppet = _M.doCmd('unzip "'..zipfile..'" -d "'..dest..
'" 2>&1 || tar -C "'..dest..'" -xvf "'..zipfile..
'" 2>&1', nil)
print(poppet:read("*a"))
poppet:close()
end
--- Download a url
--- @param url string URI of resource to download
--- @param dest string File to save resource to
function _M.downloadFile (url, dest)
local poppet = _M.doCmd('curl -sL "'..url..'" > "'..dest..'" || wget -qO- "'..url..'" > "'..dest..'"')
print(poppet:read("*a"))
poppet:close()
end
function _M.table_to_string(tbl)
local result = "{"
local keys = {}

1102
vscode-debuggee.lua Normal file

File diff suppressed because it is too large Load diff