Skip to content

Commit

Permalink
Merge pull request #281 from wheremyfoodat/lua
Browse files Browse the repository at this point in the history
Hook memory RW to Lua
  • Loading branch information
wheremyfoodat authored Sep 17, 2023
2 parents 30cf9df + 74026d2 commit d3b9e50
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
10 changes: 10 additions & 0 deletions include/lua.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "helpers.hpp"
#include "memory.hpp"

#ifdef PANDA3DS_ENABLE_LUA
extern "C" {
Expand All @@ -15,15 +16,24 @@ class LuaManager {
bool initialized = false;

public:
// For Lua we must have some global pointers to our emulator objects to use them in script code via thunks. See the thunks in lua.cpp as an
// example
static Memory* g_memory;

LuaManager(Memory& mem) { g_memory = &mem; }

void close();
void initialize();
void initializeThunks();
void loadFile(const char* path);
void reset();
};

#elif // Lua not enabled, Lua manager does nothing
class LuaManager {
public:
LuaManager(Memory& mem) {}

void close() {}
void initialize() {}
void loadFile(const char* path) {}
Expand Down
2 changes: 1 addition & 1 deletion src/emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1;

Emulator::Emulator()
: config(std::filesystem::current_path() / "config.toml"), kernel(cpu, memory, gpu, config), cpu(memory, kernel), gpu(memory, config),
memory(cpu.getTicksRef(), config), cheats(memory, kernel.getServiceManager().getHID()), running(false), programRunning(false)
memory(cpu.getTicksRef(), config), cheats(memory, kernel.getServiceManager().getHID()), lua(memory), running(false), programRunning(false)
#ifdef PANDA3DS_ENABLE_HTTP_SERVER
, httpServer(this)
#endif
Expand Down
43 changes: 41 additions & 2 deletions src/lua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@

void LuaManager::initialize() {
L = luaL_newstate(); // Open Lua

if (!L) {
printf("Lua initialization failed, continuing without Lua");
initialized = false;
initialized = false;
return;
}

luaL_openlibs(L);
initializeThunks();

initialized = true;
}

Expand All @@ -34,4 +36,41 @@ void LuaManager::loadFile(const char* path) {
void LuaManager::reset() {
// Reset scripts
}

// Initialize C++ thunks for Lua code to call here
// All code beyond this point is terrible and full of global state, don't judge

Memory* LuaManager::g_memory = nullptr;

#define MAKE_MEMORY_FUNCTIONS(size) \
static int read##size##Thunk(lua_State* L) { \
const u32 vaddr = (u32)lua_tonumber(L, 1); \
lua_pushnumber(L, LuaManager::g_memory->read##size(vaddr)); \
return 1; \
} \
static int write##size##Thunk(lua_State* L) { \
const u32 vaddr = (u32)lua_tonumber(L, 1); \
const u##size value = (u##size)lua_tonumber(L, 2); \
LuaManager::g_memory->write##size(vaddr, value); \
return 0; \
}


MAKE_MEMORY_FUNCTIONS(8)
MAKE_MEMORY_FUNCTIONS(16)
MAKE_MEMORY_FUNCTIONS(32)
MAKE_MEMORY_FUNCTIONS(64)
#undef MAKE_MEMORY_FUNCTIONS

void LuaManager::initializeThunks() {
lua_register(L, "read8", read8Thunk);
lua_register(L, "read16", read16Thunk);
lua_register(L, "read32", read32Thunk);
lua_register(L, "read64", read64Thunk);
lua_register(L, "write8", write8Thunk);
lua_register(L, "write16", write16Thunk);
lua_register(L, "write32", write32Thunk);
lua_register(L, "write64", write64Thunk);
}

#endif

0 comments on commit d3b9e50

Please sign in to comment.