mirror of
https://github.com/holub/mame
synced 2025-06-27 06:39:03 +03:00
Merge pull request #105 from lucab/lucab/mame-lua/misc
luaengine: expose more methods + misc fixes
This commit is contained in:
commit
f489a56fa3
@ -49,8 +49,9 @@ const UINT64 device_state_entry::k_decimal_divisor[] =
|
||||
// device_state_entry - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_state_entry::device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size)
|
||||
: m_next(NULL),
|
||||
device_state_entry::device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size, device_state_interface *dev)
|
||||
: m_device_state(dev),
|
||||
m_next(NULL),
|
||||
m_index(index),
|
||||
m_dataptr(dataptr),
|
||||
m_datamask(0),
|
||||
@ -86,8 +87,9 @@ device_state_entry::device_state_entry(int index, const char *symbol, void *data
|
||||
m_symbol.cpy("CURFLAGS");
|
||||
}
|
||||
|
||||
device_state_entry::device_state_entry(int index)
|
||||
: m_next(NULL),
|
||||
device_state_entry::device_state_entry(int index, device_state_interface *dev)
|
||||
: m_device_state(dev),
|
||||
m_next(NULL),
|
||||
m_index(index),
|
||||
m_dataptr(NULL),
|
||||
m_datamask(0),
|
||||
@ -523,7 +525,7 @@ device_state_entry &device_state_interface::state_add(int index, const char *sym
|
||||
assert(symbol != NULL);
|
||||
|
||||
// allocate new entry
|
||||
device_state_entry *entry = global_alloc(device_state_entry(index, symbol, data, size));
|
||||
device_state_entry *entry = global_alloc(device_state_entry(index, symbol, data, size, this));
|
||||
|
||||
// append to the end of the list
|
||||
m_state_list.append(*entry);
|
||||
@ -543,7 +545,7 @@ device_state_entry &device_state_interface::state_add(int index, const char *sym
|
||||
device_state_entry &device_state_interface::state_add_divider(int index)
|
||||
{
|
||||
// allocate new entry
|
||||
device_state_entry *entry = global_alloc(device_state_entry(index));
|
||||
device_state_entry *entry = global_alloc(device_state_entry(index, this));
|
||||
|
||||
// append to the end of the list
|
||||
m_state_list.append(*entry);
|
||||
|
@ -45,12 +45,11 @@ class device_state_entry
|
||||
{
|
||||
friend class device_state_interface;
|
||||
friend class simple_list<device_state_entry>;
|
||||
friend class lua_engine;
|
||||
|
||||
private:
|
||||
// construction/destruction
|
||||
device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size);
|
||||
device_state_entry(int index);
|
||||
device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size, device_state_interface *dev);
|
||||
device_state_entry(int index, device_state_interface *dev);
|
||||
|
||||
public:
|
||||
// post-construction modifiers
|
||||
@ -70,6 +69,7 @@ public:
|
||||
const char *symbol() const { return m_symbol; }
|
||||
bool visible() const { return ((m_flags & DSF_NOSHOW) == 0); }
|
||||
bool divider() const { return m_flags & DSF_DIVIDER; }
|
||||
device_state_interface *parent_state() const {return m_device_state;}
|
||||
|
||||
protected:
|
||||
// device state flags
|
||||
@ -98,6 +98,7 @@ protected:
|
||||
static const UINT64 k_decimal_divisor[20]; // divisors for outputting decimal values
|
||||
|
||||
// public state description
|
||||
device_state_interface *m_device_state; // link to parent device state
|
||||
device_state_entry * m_next; // link to next item
|
||||
UINT32 m_index; // index by which this item is referred
|
||||
generic_ptr m_dataptr; // pointer to where the data lives
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Miodrag Milanovic
|
||||
// copyright-holders:Miodrag Milanovic,Luca Bruno
|
||||
/***************************************************************************
|
||||
|
||||
luaengine.c
|
||||
@ -456,23 +456,33 @@ luabridge::LuaRef lua_engine::l_dev_get_states(const device_t *d)
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_get_value - return value of a devices state
|
||||
// state_get_value - return value of a device state entry
|
||||
// -> manager:machine().devices[":maincpu"].state["PC"].value
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT64 lua_engine::l_state_get_value(const device_state_entry *d)
|
||||
{
|
||||
return d->value();
|
||||
device_state_interface *state = d->parent_state();
|
||||
if(state) {
|
||||
luaThis->machine().save().dispatch_presave();
|
||||
return state->state_int(d->index());
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_set_value - set value of a devices state
|
||||
// state_set_value - set value of a device state entry
|
||||
// -> manager:machine().devices[":maincpu"].state["D0"].value = 0x0c00
|
||||
//-------------------------------------------------
|
||||
|
||||
void lua_engine::l_state_set_value(device_state_entry *d, UINT64 val)
|
||||
{
|
||||
d->set_value(val);
|
||||
device_state_interface *state = d->parent_state();
|
||||
if(state) {
|
||||
state->set_state_int(d->index(), val);
|
||||
luaThis->machine().save().dispatch_presave();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -526,6 +536,84 @@ int lua_engine::lua_addr_space::l_mem_read(lua_State *L)
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// mem_write - templated memory writer for <sign>,<size>
|
||||
// -> manager:machine().devices[":maincpu"].spaces["program"]:write_u16(0xC000, 0xF00D)
|
||||
//-------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
int lua_engine::lua_addr_space::l_mem_write(lua_State *L)
|
||||
{
|
||||
address_space &sp = luabridge::Stack<address_space &>::get(L, 1);
|
||||
luaL_argcheck(L, lua_isnumber(L, 2), 2, "address (integer) expected");
|
||||
luaL_argcheck(L, lua_isnumber(L, 3), 3, "value (integer) expected");
|
||||
offs_t address = lua_tounsigned(L, 2);
|
||||
T val = lua_tounsigned(L, 3);
|
||||
|
||||
switch(sizeof(val) * 8) {
|
||||
case 8:
|
||||
sp.write_byte(address, val);
|
||||
break;
|
||||
case 16:
|
||||
if ((address & 1) == 0) {
|
||||
sp.write_word(address, val);
|
||||
} else {
|
||||
sp.read_word_unaligned(address, val);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if ((address & 3) == 0) {
|
||||
sp.write_dword(address, val);
|
||||
} else {
|
||||
sp.write_dword_unaligned(address, val);
|
||||
}
|
||||
break;
|
||||
case 64:
|
||||
if ((address & 7) == 0) {
|
||||
sp.write_qword(address, val);
|
||||
} else {
|
||||
sp.write_qword_unaligned(address, val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// screen_height - return screen visible height
|
||||
// -> manager:machine().screens[":screen"]:height()
|
||||
//-------------------------------------------------
|
||||
|
||||
int lua_engine::lua_screen::l_height(lua_State *L)
|
||||
{
|
||||
screen_device *sc = luabridge::Stack<screen_device *>::get(L, 1);
|
||||
if(!sc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushunsigned(L, sc->visible_area().height());
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// screen_width - return screen visible width
|
||||
// -> manager:machine().screens[":screen"]:width()
|
||||
//-------------------------------------------------
|
||||
|
||||
int lua_engine::lua_screen::l_width(lua_State *L)
|
||||
{
|
||||
screen_device *sc = luabridge::Stack<screen_device *>::get(L, 1);
|
||||
if(!sc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushunsigned(L, sc->visible_area().width());
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// draw_box - draw a box on a screen container
|
||||
// -> manager:machine().screens[":screen"]:draw_box(x1, y1, x2, y2, bgcolor, linecolor)
|
||||
@ -548,10 +636,10 @@ int lua_engine::lua_screen::l_draw_box(lua_State *L)
|
||||
|
||||
// retrieve all parameters
|
||||
float x1, y1, x2, y2;
|
||||
x1 = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->width()) , 1.0f);
|
||||
y1 = MIN(lua_tounsigned(L, 3) / static_cast<float>(sc->height()), 1.0f);
|
||||
x2 = MIN(lua_tounsigned(L, 4) / static_cast<float>(sc->width()) , 1.0f);
|
||||
y2 = MIN(lua_tounsigned(L, 5) / static_cast<float>(sc->height()), 1.0f);
|
||||
x1 = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->visible_area().width()) , 1.0f);
|
||||
y1 = MIN(lua_tounsigned(L, 3) / static_cast<float>(sc->visible_area().height()), 1.0f);
|
||||
x2 = MIN(lua_tounsigned(L, 4) / static_cast<float>(sc->visible_area().width()) , 1.0f);
|
||||
y2 = MIN(lua_tounsigned(L, 5) / static_cast<float>(sc->visible_area().height()), 1.0f);
|
||||
UINT32 bgcolor = lua_tounsigned(L, 6);
|
||||
UINT32 fgcolor = lua_tounsigned(L, 7);
|
||||
|
||||
@ -584,10 +672,10 @@ int lua_engine::lua_screen::l_draw_line(lua_State *L)
|
||||
|
||||
// retrieve all parameters
|
||||
float x1, y1, x2, y2;
|
||||
x1 = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->width()) , 1.0f);
|
||||
y1 = MIN(lua_tounsigned(L, 3) / static_cast<float>(sc->height()), 1.0f);
|
||||
x2 = MIN(lua_tounsigned(L, 4) / static_cast<float>(sc->width()) , 1.0f);
|
||||
y2 = MIN(lua_tounsigned(L, 5) / static_cast<float>(sc->height()), 1.0f);
|
||||
x1 = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->visible_area().width()) , 1.0f);
|
||||
y1 = MIN(lua_tounsigned(L, 3) / static_cast<float>(sc->visible_area().height()), 1.0f);
|
||||
x2 = MIN(lua_tounsigned(L, 4) / static_cast<float>(sc->visible_area().width()) , 1.0f);
|
||||
y2 = MIN(lua_tounsigned(L, 5) / static_cast<float>(sc->visible_area().height()), 1.0f);
|
||||
UINT32 color = lua_tounsigned(L, 6);
|
||||
|
||||
// draw the line
|
||||
@ -613,8 +701,8 @@ int lua_engine::lua_screen::l_draw_text(lua_State *L)
|
||||
luaL_argcheck(L, lua_isstring(L, 4), 4, "message (string) expected");
|
||||
|
||||
// retrieve all parameters
|
||||
float x = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->width()) , 1.0f);
|
||||
float y = MIN(lua_tounsigned(L, 3) / static_cast<float>(sc->height()), 1.0f);
|
||||
float x = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->visible_area().width()) , 1.0f);
|
||||
float y = MIN(lua_tounsigned(L, 3) / static_cast<float>(sc->visible_area().height()), 1.0f);
|
||||
const char *msg = luaL_checkstring(L,4);
|
||||
// TODO: add optional parameters (colors, etc.)
|
||||
|
||||
@ -882,6 +970,14 @@ void lua_engine::initialize()
|
||||
.addCFunction ("read_u32", &lua_addr_space::l_mem_read<UINT32>)
|
||||
.addCFunction ("read_i64", &lua_addr_space::l_mem_read<INT64>)
|
||||
.addCFunction ("read_u64", &lua_addr_space::l_mem_read<UINT64>)
|
||||
.addCFunction ("write_i8", &lua_addr_space::l_mem_write<INT8>)
|
||||
.addCFunction ("write_u8", &lua_addr_space::l_mem_write<UINT8>)
|
||||
.addCFunction ("write_i16", &lua_addr_space::l_mem_write<INT16>)
|
||||
.addCFunction ("write_u16", &lua_addr_space::l_mem_write<UINT16>)
|
||||
.addCFunction ("write_i32", &lua_addr_space::l_mem_write<INT32>)
|
||||
.addCFunction ("write_u32", &lua_addr_space::l_mem_write<UINT32>)
|
||||
.addCFunction ("write_i64", &lua_addr_space::l_mem_write<INT64>)
|
||||
.addCFunction ("write_u64", &lua_addr_space::l_mem_write<UINT64>)
|
||||
.endClass()
|
||||
.deriveClass <address_space, lua_addr_space> ("addr_space")
|
||||
.addFunction("name", &address_space::name)
|
||||
@ -890,13 +986,14 @@ void lua_engine::initialize()
|
||||
.addCFunction ("draw_box", &lua_screen::l_draw_box)
|
||||
.addCFunction ("draw_line", &lua_screen::l_draw_line)
|
||||
.addCFunction ("draw_text", &lua_screen::l_draw_text)
|
||||
.addCFunction ("height", &lua_screen::l_height)
|
||||
.addCFunction ("width", &lua_screen::l_width)
|
||||
.endClass()
|
||||
.deriveClass <screen_device, lua_screen> ("screen_dev")
|
||||
.addFunction ("frame_number", &screen_device::frame_number)
|
||||
.addFunction ("name", &screen_device::name)
|
||||
.addFunction ("shortname", &screen_device::shortname)
|
||||
.addFunction ("tag", &screen_device::tag)
|
||||
.addFunction ("height", &screen_device::height)
|
||||
.addFunction ("width", &screen_device::width)
|
||||
.endClass()
|
||||
.beginClass <device_state_entry> ("dev_space")
|
||||
.addFunction ("name", &device_state_entry::symbol)
|
||||
|
@ -112,9 +112,12 @@ private:
|
||||
static luabridge::LuaRef l_dev_get_memspaces(const device_t *d);
|
||||
struct lua_addr_space {
|
||||
template<typename T> int l_mem_read(lua_State *L);
|
||||
template<typename T> int l_mem_write(lua_State *L);
|
||||
};
|
||||
static luabridge::LuaRef l_machine_get_screens(const running_machine *r);
|
||||
struct lua_screen {
|
||||
int l_height(lua_State *L);
|
||||
int l_width(lua_State *L);
|
||||
int l_draw_box(lua_State *L);
|
||||
int l_draw_line(lua_State *L);
|
||||
int l_draw_text(lua_State *L);
|
||||
|
@ -213,6 +213,17 @@ save_error save_manager::check_file(running_machine &machine, emu_file &file, co
|
||||
return validate_header(header, gamename, sig, errormsg, "");
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// dispatch_postload - invoke all registered
|
||||
// postload callbacks for updates
|
||||
//-------------------------------------------------
|
||||
|
||||
|
||||
void save_manager::dispatch_postload()
|
||||
{
|
||||
for (state_callback *func = m_postload_list.first(); func != NULL; func = func->next())
|
||||
func->m_func();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// read_file - read the data from a file
|
||||
@ -253,12 +264,22 @@ save_error save_manager::read_file(emu_file &file)
|
||||
}
|
||||
|
||||
// call the post-load functions
|
||||
for (state_callback *func = m_postload_list.first(); func != NULL; func = func->next())
|
||||
func->m_func();
|
||||
dispatch_postload();
|
||||
|
||||
return STATERR_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// dispatch_presave - invoke all registered
|
||||
// presave callbacks for updates
|
||||
//-------------------------------------------------
|
||||
|
||||
|
||||
void save_manager::dispatch_presave()
|
||||
{
|
||||
for (state_callback *func = m_presave_list.first(); func != NULL; func = func->next())
|
||||
func->m_func();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_file - writes the data to a file
|
||||
@ -287,8 +308,7 @@ save_error save_manager::write_file(emu_file &file)
|
||||
file.compress(FCOMPRESS_MEDIUM);
|
||||
|
||||
// call the pre-save functions
|
||||
for (state_callback *func = m_presave_list.first(); func != NULL; func = func->next())
|
||||
func->m_func();
|
||||
dispatch_presave();
|
||||
|
||||
// then write all the data
|
||||
for (state_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next())
|
||||
|
@ -99,6 +99,10 @@ public:
|
||||
void register_presave(save_prepost_delegate func);
|
||||
void register_postload(save_prepost_delegate func);
|
||||
|
||||
// callback dispatching
|
||||
void dispatch_presave();
|
||||
void dispatch_postload();
|
||||
|
||||
// generic memory registration
|
||||
void save_memory(const char *module, const char *tag, UINT32 index, const char *name, void *val, UINT32 valsize, UINT32 valcount = 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user