mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
luaengine: add plugin options menu [Carl]
This commit is contained in:
parent
0d217bb97c
commit
817f19fcc1
@ -17,6 +17,17 @@ function dummy.startplugin()
|
||||
emu.register_stop(function()
|
||||
print("Exiting " .. emu.gamename())
|
||||
end)
|
||||
|
||||
local function menu_populate()
|
||||
return {{ "This is a", "test", 32 }, { "Also a", "test", 0 }} -- 32 is MENU_FLAG_DISABLE
|
||||
end
|
||||
|
||||
local function menu_callback(index, event)
|
||||
print("index: " .. index .. " event: " .. event)
|
||||
return false
|
||||
end
|
||||
|
||||
emu.register_menu(menu_callback, menu_populate, "Dummy")
|
||||
end
|
||||
|
||||
return exports
|
||||
|
@ -216,6 +216,8 @@ files {
|
||||
MAME_DIR .. "src/emu/ui/barcode.h",
|
||||
MAME_DIR .. "src/emu/ui/cheatopt.cpp",
|
||||
MAME_DIR .. "src/emu/ui/cheatopt.h",
|
||||
MAME_DIR .. "src/emu/ui/pluginopt.cpp",
|
||||
MAME_DIR .. "src/emu/ui/pluginopt.h",
|
||||
MAME_DIR .. "src/emu/ui/devopt.cpp",
|
||||
MAME_DIR .. "src/emu/ui/devopt.h",
|
||||
MAME_DIR .. "src/emu/ui/filemngr.cpp",
|
||||
|
@ -1274,6 +1274,82 @@ lua_engine::~lua_engine()
|
||||
close();
|
||||
}
|
||||
|
||||
std::vector<lua_engine::menu_item> &lua_engine::menu_populate(std::string &menu)
|
||||
{
|
||||
std::vector<menu_item> &menu_list = *global_alloc(std::vector<menu_item>);
|
||||
std::string field = "menu_pop_" + menu;
|
||||
lua_settop(m_lua_state, 0);
|
||||
lua_getfield(m_lua_state, LUA_REGISTRYINDEX, field.c_str());
|
||||
|
||||
if(!lua_isfunction(m_lua_state, -1))
|
||||
{
|
||||
lua_pop(m_lua_state, 1);
|
||||
return menu_list;
|
||||
}
|
||||
lua_pcall(m_lua_state, 0, 1, 0);
|
||||
if(!lua_istable(m_lua_state, -1))
|
||||
{
|
||||
lua_pop(m_lua_state, 1);
|
||||
return menu_list;
|
||||
}
|
||||
|
||||
lua_pushnil(m_lua_state);
|
||||
while(lua_next(m_lua_state, -2))
|
||||
{
|
||||
if(lua_istable(m_lua_state, -1))
|
||||
{
|
||||
menu_item item;
|
||||
lua_rawgeti(m_lua_state, -1, 1);
|
||||
item.text = lua_tostring(m_lua_state, -1);
|
||||
lua_pop(m_lua_state, 1);
|
||||
lua_rawgeti(m_lua_state, -1, 2);
|
||||
item.subtext = lua_tostring(m_lua_state, -1);
|
||||
lua_pop(m_lua_state, 1);
|
||||
lua_rawgeti(m_lua_state, -1, 3);
|
||||
item.flags = lua_tointeger(m_lua_state, -1);
|
||||
lua_pop(m_lua_state, 1);
|
||||
menu_list.push_back(item);
|
||||
}
|
||||
lua_pop(m_lua_state, 1);
|
||||
}
|
||||
lua_pop(m_lua_state, 1);
|
||||
return menu_list;
|
||||
}
|
||||
|
||||
bool lua_engine::menu_callback(std::string &menu, int index, std::string event)
|
||||
{
|
||||
std::string field = "menu_cb_" + menu;
|
||||
bool ret = false;
|
||||
lua_settop(m_lua_state, 0);
|
||||
lua_getfield(m_lua_state, LUA_REGISTRYINDEX, field.c_str());
|
||||
|
||||
if(lua_isfunction(m_lua_state, -1))
|
||||
{
|
||||
lua_pushinteger(m_lua_state, index);
|
||||
lua_pushstring(m_lua_state, event.c_str());
|
||||
lua_pcall(m_lua_state, 2, 1, 0);
|
||||
ret = lua_toboolean(m_lua_state, -1);
|
||||
lua_pop(m_lua_state, 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lua_engine::l_emu_register_menu(lua_State *L)
|
||||
{
|
||||
luaL_argcheck(L, lua_isfunction(L, 1), 1, "callback function expected");
|
||||
luaL_argcheck(L, lua_isfunction(L, 2), 2, "callback function expected");
|
||||
luaL_argcheck(L, lua_isstring(L, 3), 3, "message (string) expected");
|
||||
std::string name = luaL_checkstring(L, 3);
|
||||
std::string cbfield = "menu_cb_" + name;
|
||||
std::string popfield = "menu_pop_" + name;
|
||||
luaThis->m_menu.push_back(std::string(name));
|
||||
lua_pushvalue(L, 1);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, cbfield.c_str());
|
||||
lua_pushvalue(L, 2);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, popfield.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
void lua_engine::execute_function(const char *id)
|
||||
{
|
||||
lua_settop(m_lua_state, 0);
|
||||
@ -1286,7 +1362,12 @@ void lua_engine::execute_function(const char *id)
|
||||
{
|
||||
if (lua_isfunction(m_lua_state, -1))
|
||||
{
|
||||
lua_pcall(m_lua_state, 0, 0, 0);
|
||||
if(int error = lua_pcall(m_lua_state, 0, 0, 0))
|
||||
{
|
||||
if(error == 2)
|
||||
printf("%s\n", lua_tostring(m_lua_state, -1));
|
||||
lua_pop(m_lua_state, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1453,7 +1534,8 @@ void lua_engine::initialize()
|
||||
.addCFunction ("register_pause", l_emu_register_pause )
|
||||
.addCFunction ("register_resume",l_emu_register_resume )
|
||||
.addCFunction ("register_frame", l_emu_register_frame )
|
||||
.beginClass <machine_manager> ("manager")
|
||||
.addCFunction ("register_menu", l_emu_register_menu )
|
||||
.beginClass <machine_manager> ("manager")
|
||||
.addFunction ("machine", &machine_manager::machine)
|
||||
.addFunction ("options", &machine_manager::options)
|
||||
.addFunction ("plugins", &machine_manager::plugins)
|
||||
|
@ -49,9 +49,19 @@ public:
|
||||
bool frame_hook();
|
||||
void execute_function(const char *id);
|
||||
|
||||
struct menu_item {
|
||||
std::string text;
|
||||
std::string subtext;
|
||||
int flags;
|
||||
};
|
||||
std::vector<menu_item> &menu_populate(std::string &menu);
|
||||
bool menu_callback(std::string &menu, int index, std::string event);
|
||||
|
||||
void resume(lua_State *L, int nparam = 0, lua_State *root = nullptr);
|
||||
void set_machine(running_machine *machine) { m_machine = machine; update_machine(); }
|
||||
std::vector<std::string> &get_menu() { return m_menu; }
|
||||
void attach_notifiers();
|
||||
|
||||
private:
|
||||
struct hook {
|
||||
lua_State *L;
|
||||
@ -70,6 +80,8 @@ private:
|
||||
lua_State *m_lua_state;
|
||||
running_machine * m_machine;
|
||||
|
||||
std::vector<std::string> m_menu;
|
||||
|
||||
hook hook_output_cb;
|
||||
bool output_notifier_set;
|
||||
|
||||
@ -121,6 +133,7 @@ private:
|
||||
static int l_emu_register_pause(lua_State *L);
|
||||
static int l_emu_register_resume(lua_State *L);
|
||||
static int l_emu_register_frame(lua_State *L);
|
||||
static int l_emu_register_menu(lua_State *L);
|
||||
static int register_function(lua_State *L, const char *id);
|
||||
|
||||
// "emu.machine" namespace
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "ui/datfile.h"
|
||||
#include "ui/inifile.h"
|
||||
#include "ui/datmenu.h"
|
||||
#include "ui/pluginopt.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
@ -131,6 +132,9 @@ void ui_menu_main::populate()
|
||||
if (machine().options().cheat())
|
||||
item_append(_("Cheat"), nullptr, 0, (void *)CHEAT);
|
||||
|
||||
if (machine().options().plugins())
|
||||
item_append(_("Plugin Options"), nullptr, 0, (void *)PLUGINS);
|
||||
|
||||
// add dats menu
|
||||
if (machine().ui().options().enabled_dats() && machine().datfile().has_data())
|
||||
item_append(_("External DAT View"), nullptr, 0, (void *)EXTERNAL_DATS);
|
||||
@ -241,6 +245,10 @@ void ui_menu_main::handle()
|
||||
ui_menu::stack_push(global_alloc_clear<ui_menu_cheat>(machine(), container));
|
||||
break;
|
||||
|
||||
case PLUGINS:
|
||||
ui_menu::stack_push(global_alloc_clear<ui_menu_plugin>(machine(), container));
|
||||
break;
|
||||
|
||||
case SELECT_GAME:
|
||||
if (strcmp(machine().options().ui(),"simple")==0) {
|
||||
ui_menu::stack_push(global_alloc_clear<ui_simple_menu_select_game>(machine(), container, nullptr));
|
||||
|
@ -42,6 +42,7 @@ private:
|
||||
VIDEO_OPTIONS,
|
||||
CROSSHAIR,
|
||||
CHEAT,
|
||||
PLUGINS,
|
||||
SELECT_GAME,
|
||||
BIOS_SELECTION,
|
||||
BARCODE_READ,
|
||||
|
100
src/emu/ui/pluginopt.cpp
Normal file
100
src/emu/ui/pluginopt.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
|
||||
/*********************************************************************
|
||||
|
||||
ui/pluginopt.cpp
|
||||
|
||||
Internal menu for the plugin interface.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "luaengine.h"
|
||||
|
||||
#include "ui/pluginopt.h"
|
||||
|
||||
void ui_menu_plugin::handle()
|
||||
{
|
||||
const ui_menu_event *menu_event = process(0);
|
||||
|
||||
if (menu_event != nullptr && menu_event->itemref != nullptr)
|
||||
{
|
||||
if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
ui_menu::stack_push(global_alloc_clear<ui_menu_plugin_opt>(machine(), container, (char *)menu_event->itemref));
|
||||
}
|
||||
}
|
||||
|
||||
ui_menu_plugin::ui_menu_plugin(running_machine &machine, render_container *container) :
|
||||
ui_menu(machine, container),
|
||||
m_plugins(machine.manager().lua()->get_menu())
|
||||
{
|
||||
}
|
||||
|
||||
void ui_menu_plugin::populate()
|
||||
{
|
||||
for (auto &curplugin : m_plugins)
|
||||
item_append(curplugin.c_str(), 0, 0, (void *)curplugin.c_str());
|
||||
item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
ui_menu_plugin::~ui_menu_plugin()
|
||||
{
|
||||
}
|
||||
|
||||
ui_menu_plugin_opt::ui_menu_plugin_opt(running_machine &machine, render_container *container, char *menu) :
|
||||
ui_menu(machine, container),
|
||||
m_menu(menu)
|
||||
{
|
||||
}
|
||||
|
||||
void ui_menu_plugin_opt::handle()
|
||||
{
|
||||
const ui_menu_event *menu_event = process(0);
|
||||
|
||||
if (menu_event != nullptr && (FPTR)menu_event->itemref)
|
||||
{
|
||||
std::string key;
|
||||
switch(menu_event->iptkey)
|
||||
{
|
||||
case IPT_UI_UP:
|
||||
key = "up";
|
||||
break;
|
||||
case IPT_UI_DOWN:
|
||||
key = "down";
|
||||
break;
|
||||
case IPT_UI_LEFT:
|
||||
key = "left";
|
||||
break;
|
||||
case IPT_UI_RIGHT:
|
||||
key = "right";
|
||||
break;
|
||||
case IPT_UI_SELECT:
|
||||
key = "select";
|
||||
break;
|
||||
case IPT_UI_DISPLAY_COMMENT:
|
||||
key = "comment";
|
||||
break;
|
||||
case IPT_UI_CLEAR:
|
||||
key = "clear";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if(machine().manager().lua()->menu_callback(m_menu, (FPTR)menu_event->itemref, key))
|
||||
reset(UI_MENU_RESET_REMEMBER_REF);
|
||||
}
|
||||
}
|
||||
|
||||
void ui_menu_plugin_opt::populate()
|
||||
{
|
||||
std::vector<lua_engine::menu_item> &menu_list = machine().manager().lua()->menu_populate(m_menu);
|
||||
FPTR i = 1;
|
||||
for(auto &item : menu_list)
|
||||
item_append(item.text.c_str(), item.subtext.c_str(), item.flags, (void *)i++);
|
||||
item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
|
||||
global_free(&menu_list);
|
||||
}
|
||||
|
||||
ui_menu_plugin_opt::~ui_menu_plugin_opt()
|
||||
{
|
||||
}
|
38
src/emu/ui/pluginopt.h
Normal file
38
src/emu/ui/pluginopt.h
Normal file
@ -0,0 +1,38 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods, Carl
|
||||
/***************************************************************************
|
||||
|
||||
ui/pluginopt.h
|
||||
|
||||
Internal menu for the plugin interface.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UI_PLUGINOPT_H__
|
||||
#define __UI_PLUGINOPT_H__
|
||||
|
||||
#include "ui/ui.h"
|
||||
#include "ui/menu.h"
|
||||
|
||||
class ui_menu_plugin : public ui_menu {
|
||||
public:
|
||||
ui_menu_plugin(running_machine &machine, render_container *container);
|
||||
virtual ~ui_menu_plugin();
|
||||
virtual void populate() override;
|
||||
virtual void handle() override;
|
||||
private:
|
||||
std::vector<std::string> &m_plugins;
|
||||
};
|
||||
|
||||
class ui_menu_plugin_opt : public ui_menu {
|
||||
public:
|
||||
ui_menu_plugin_opt(running_machine &machine, render_container *container, char *menu);
|
||||
virtual ~ui_menu_plugin_opt();
|
||||
virtual void populate() override;
|
||||
virtual void handle() override;
|
||||
private:
|
||||
std::string m_menu;
|
||||
};
|
||||
#endif /* __UI_PLUGINOPT_H__ */
|
Loading…
Reference in New Issue
Block a user