gmod-lcpu/native/projects/lcpu/src/LuaDevice.cpp

112 lines
3.0 KiB
C++
Raw Normal View History

#include "LuaDevice.hpp"
2023-07-27 16:55:29 -04:00
namespace lcpu {
void LuaDevice::RegisterClass(GarrysMod::Lua::ILuaBase* LUA) {
RegisterClassStart(LUA);
2023-07-27 16:30:59 -04:00
2023-07-27 16:55:29 -04:00
RegisterGetter("Base", [](GarrysMod::Lua::ILuaBase* LUA) {
auto self = LuaDevice::FromLua(LUA, 1);
LUA->PushNumber(static_cast<double>(self->base));
});
2023-07-27 16:30:59 -04:00
2023-07-27 16:55:29 -04:00
RegisterGetter("Size", [](GarrysMod::Lua::ILuaBase* LUA) {
auto self = LuaDevice::FromLua(LUA, 1);
LUA->PushNumber(static_cast<double>(self->size));
});
}
2023-07-27 16:55:29 -04:00
bool LuaDevice::Clocked() const {
// no real good rationale for checking here,
// since function calling does bail out properly
return true;
}
2023-07-25 06:46:52 -04:00
2023-07-27 16:55:29 -04:00
void LuaDevice::Clock() {
// clang-format off
lua->ReferencePush(GetTableReference());
lua->GetField(-1,"Clock");
if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) {
lua->Push(-2); // 'self' argument
lua->Call(1, 0);
} else {
lua->Pop(); // pop the Clock function off the stack
}
lua->Pop(); // pop the reference
// clang-format on
}
2023-07-25 06:46:52 -04:00
2023-07-27 16:55:29 -04:00
riscv::Address LuaDevice::Base() const {
return base;
}
2023-07-25 06:46:52 -04:00
2023-07-27 16:55:29 -04:00
riscv::Address LuaDevice::Size() const {
return size;
2023-07-27 16:55:29 -04:00
}
2023-07-25 06:46:52 -04:00
2023-07-27 16:55:29 -04:00
u32 LuaDevice::Peek(riscv::Address address) {
// clang-format off
lua->ReferencePush(GetTableReference());
lua->GetField(-1,"Peek");
if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) {
lua->Push(-2); // 'self' argument
lua->PushNumber(static_cast<double>(address));
lua->Call(2, 1);
auto result = static_cast<u32>(lua->GetNumber(-1));
lua->Pop(2); // pop result and the table off
return result;
} else {
lua->Pop(); // pop whatever Peek is off the stack
}
lua->Pop(); // pop the table reference
// clang-format on
return 0xffffffff;
}
2023-07-25 06:46:52 -04:00
2023-07-27 16:55:29 -04:00
void LuaDevice::Poke(riscv::Address address, u32 value) {
// clang-format off
lua->ReferencePush(GetTableReference());
lua->GetField(-1,"Poke");
if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) {
lua->Push(-2); // 'self' argument
lua->PushNumber(static_cast<double>(address));
lua->PushNumber(static_cast<double>(value));
lua->Call(3, 0);
} else {
lua->Pop(); // pop whatever Peek is
}
lua->Pop(); // pop the table reference
// clang-format on
}
void LuaDevice::Reset() {
// clang-format off
lua->ReferencePush(GetTableReference());
lua->GetField(-1,"Reset");
2023-07-27 16:30:59 -04:00
if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) {
lua->Push(-2); // 'self' argument
2023-07-27 16:55:29 -04:00
lua->Call(1, 0);
} else {
2023-07-27 16:55:29 -04:00
lua->Pop(); // pop whatever reset is
}
2023-07-27 16:55:29 -04:00
lua->Pop(); // pop the reference
// clang-format on
}
2023-07-25 06:46:52 -04:00
2023-07-27 16:55:29 -04:00
LuaDevice::LuaDevice(riscv::Address base, riscv::Address size) : base(base), size(size) {
}
2023-07-27 16:55:29 -04:00
void LuaDevice::AfterLuaInit() {
// Our Lua callbacks only get the table, not the actual userdata,
// ao we have to mirror things :( kinda sucks, but meh
// clang-format off
lua->ReferencePush(GetTableReference());
lua->PushNumber(static_cast<double>(base));
lua->SetField(-2, "Base");
lua->PushNumber(static_cast<double>(base));
lua->SetField(-2, "Size");
lua->Pop();
// clang-format on
}
} // namespace lcpu