lua: ui bindings

This commit is contained in:
Flyinghead 2021-10-04 19:42:45 +02:00
parent 3c2c7b379d
commit 1072235b1a
4 changed files with 158 additions and 7 deletions

72
core/lua/flycast.lua Normal file
View File

@ -0,0 +1,72 @@
function cbStart()
local s = flycast.state
print("Game started: " .. s.media)
print("Game Id: " .. s.gameId)
print("Display: " .. s.display.width .. "x" .. s.display.height)
end
function cbPause()
print("Game paused")
end
function cbResume()
print("Game resumed")
flycast.emulator.displayNotification("Lua rules", 2000)
local maple = flycast.config.maple
print("Maple 1: " .. maple.getDeviceType(1),
maple.getSubDeviceType(1, 1), maple.getSubDeviceType(1, 2))
end
function cbTerminate()
print("Game terminated")
end
function cbLoadState()
print("State loaded")
end
function cbVBlank()
-- print("vblank x,y=", flycast.input.getAbsCoordinates(1))
end
function cbOverlay()
f = f + 1
local ui = flycast.ui
ui.beginWindow("Lua", 10, 10, 150, 0)
ui.text("Hello world")
ui.rightText(f)
ui.bargraph(f / 3600)
ui.button("Reset", function()
f = 0
end)
ui.text("Stick")
local input = flycast.input
local ax = input.getAxis(1, 1)
local ay = input.getAxis(1, 2)
ui.bargraph((ax + 128) / 255)
ui.bargraph((ay + 128) / 255)
input.releaseButtons(1, 0x8)
ui.button("Test", function()
input.pressButtons(1, 0x8)
end)
ui.text("Mouse")
local x, y = input.getAbsCoordinates(1)
ui.bargraph(x / 640)
ui.bargraph(y / 480)
ui.endWindow()
end
flycast_callbacks = {
start = cbStart,
pause = cbPause,
resume = cbResume,
terminate = cbTerminate,
loadState = cbLoadState,
vblank = cbVBlank,
overlay = cbOverlay
}
print("Callback set")
f = 0
flycast.emulator.startGame("pstone2.zip")

View File

@ -29,6 +29,7 @@
#include "hw/maple/maple_devs.h"
#include "hw/maple/maple_if.h"
#include "stdclass.h"
#include "imgui/imgui.h"
namespace lua
{
@ -70,19 +71,32 @@ static void emuEventCallback(Event event)
}
}
void vblank()
template<const char *Tag>
void eventCallback()
{
if (L == nullptr)
return;
try {
LuaRef v = LuaRef::getGlobal(L, CallbackTable);
if (v.isTable() && v["vblank"].isFunction())
v["vblank"]();
if (v.isTable() && v[Tag].isFunction())
v[Tag]();
} catch (const LuaException& e) {
WARN_LOG(COMMON, "Lua exception: %s", e.what());
WARN_LOG(COMMON, "Lua exception[%s]: %s", Tag, e.what());
}
}
const char VBlankEvent[] { "vblank" };
void vblank()
{
eventCallback<VBlankEvent>();
}
const char OverlayEvent[] { "overlay" };
void overlay()
{
eventCallback<OverlayEvent>();
}
template<typename T>
static LuaRef readMemoryTable(u32 address, int count, lua_State* L)
{
@ -343,6 +357,58 @@ static void setRelCoordinates(int player, float x, float y, lua_State *L)
SetRelativeMousePosition(x, y, player - 1);
}
// UI
static void beginWindow(const char *title, int x, int y, int w, int h)
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0);
ImGui::SetNextWindowPos(ImVec2(x, y));
ImGui::SetNextWindowSize(ImVec2(w * scaling, h * scaling));
ImGui::SetNextWindowBgAlpha(0.7f);
ImGui::Begin(title, NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus);
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.557f, 0.268f, 0.965f, 1.f));
}
static void endWindow()
{
ImGui::PopStyleColor();
ImGui::End();
ImGui::PopStyleVar(2);
}
static void uiText(const char *text)
{
ImGui::Text("%s", text);
}
static void uiTextRightAligned(const char *text)
{
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(text).x);
uiText(text);
}
static void uiBargraph(float v)
{
ImGui::ProgressBar(v, ImVec2(-1, 10.f * scaling), "");
}
static int uiButton(lua_State *L)
{
const char *label = luaL_checkstring(L, 1);
if (ImGui::Button(label))
{
try {
LuaRef callback = LuaRef::fromStack(L, 2);
if (callback.isFunction())
callback();
} catch (const LuaException& e) {
WARN_LOG(COMMON, "Lua exception: %s", e.what());
}
}
return 0;
}
static void luaRegister(lua_State *L)
{
getGlobalNamespace(L)
@ -389,8 +455,6 @@ static void luaRegister(lua_State *L)
CONFIG_PROPERTY(Region, int)
CONFIG_PROPERTY(Broadcast, int)
CONFIG_PROPERTY(Language, int)
CONFIG_PROPERTY(FullMMU, bool)
CONFIG_PROPERTY(ForceWindowsCE, bool)
CONFIG_PROPERTY(AutoLoadState, bool)
CONFIG_PROPERTY(AutoSaveState, bool)
CONFIG_PROPERTY(SavestateSlot, int)
@ -445,6 +509,8 @@ static void luaRegister(lua_State *L)
CONFIG_PROPERTY(UseReios, bool)
CONFIG_PROPERTY(FastGDRomLoad, bool)
CONFIG_PROPERTY(OpenGlChecks, bool)
CONFIG_PROPERTY(FullMMU, bool)
CONFIG_PROPERTY(ForceWindowsCE, bool)
.endNamespace()
.beginNamespace("network")
@ -503,6 +569,15 @@ static void luaRegister(lua_State *L)
.addProperty("height", &settings.display.height, false)
.endNamespace()
.endNamespace()
.beginNamespace("ui")
.addFunction("beginWindow", beginWindow)
.addFunction("endWindow", endWindow)
.addFunction("text", uiText)
.addFunction("rightText", uiTextRightAligned)
.addFunction("bargraph", uiBargraph)
.addFunction("button", uiButton)
.endNamespace()
.endNamespace();
}

View File

@ -27,6 +27,7 @@ void init();
void term();
void exec(const std::string& path);
void vblank();
void overlay();
#else
@ -34,6 +35,7 @@ inline static void init() {}
inline static void term() {}
inline static void exec(const std::string& path) {}
inline static void vblank() {}
inline static void overlay() {}
#endif
}

View File

@ -41,6 +41,7 @@
#include "log/LogManager.h"
#include "emulator.h"
#include "rend/mainui.h"
#include "lua/lua.h"
static bool game_started;
@ -2392,7 +2393,7 @@ void gui_display_osd()
if (message.empty())
message = getFPSNotification();
if (!message.empty() || config::FloatVMUs || crosshairsNeeded() || (ggpo::active() && config::NetworkStats))
// if (!message.empty() || config::FloatVMUs || crosshairsNeeded() || (ggpo::active() && config::NetworkStats))
{
ImGui_Impl_NewFrame();
ImGui::NewFrame();
@ -2415,6 +2416,7 @@ void gui_display_osd()
// gui_plot_render_time(settings.display.width, settings.display.height);
if (ggpo::active() && config::NetworkStats)
ggpo::displayStats();
lua::overlay();
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData());