Merge pull request #105 from lucab/lucab/mame-lua/misc

luaengine: expose more methods + misc fixes
This commit is contained in:
Olivier Galibert 2015-01-18 20:49:10 +01:00
commit f489a56fa3
6 changed files with 157 additions and 30 deletions

View File

@ -49,8 +49,9 @@ const UINT64 device_state_entry::k_decimal_divisor[] =
// device_state_entry - constructor // device_state_entry - constructor
//------------------------------------------------- //-------------------------------------------------
device_state_entry::device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size) device_state_entry::device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size, device_state_interface *dev)
: m_next(NULL), : m_device_state(dev),
m_next(NULL),
m_index(index), m_index(index),
m_dataptr(dataptr), m_dataptr(dataptr),
m_datamask(0), m_datamask(0),
@ -86,8 +87,9 @@ device_state_entry::device_state_entry(int index, const char *symbol, void *data
m_symbol.cpy("CURFLAGS"); m_symbol.cpy("CURFLAGS");
} }
device_state_entry::device_state_entry(int index) device_state_entry::device_state_entry(int index, device_state_interface *dev)
: m_next(NULL), : m_device_state(dev),
m_next(NULL),
m_index(index), m_index(index),
m_dataptr(NULL), m_dataptr(NULL),
m_datamask(0), m_datamask(0),
@ -523,7 +525,7 @@ device_state_entry &device_state_interface::state_add(int index, const char *sym
assert(symbol != NULL); assert(symbol != NULL);
// allocate new entry // 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 // append to the end of the list
m_state_list.append(*entry); 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) device_state_entry &device_state_interface::state_add_divider(int index)
{ {
// allocate new entry // 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 // append to the end of the list
m_state_list.append(*entry); m_state_list.append(*entry);

View File

@ -45,12 +45,11 @@ class device_state_entry
{ {
friend class device_state_interface; friend class device_state_interface;
friend class simple_list<device_state_entry>; friend class simple_list<device_state_entry>;
friend class lua_engine;
private: private:
// construction/destruction // construction/destruction
device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size); device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size, device_state_interface *dev);
device_state_entry(int index); device_state_entry(int index, device_state_interface *dev);
public: public:
// post-construction modifiers // post-construction modifiers
@ -70,6 +69,7 @@ public:
const char *symbol() const { return m_symbol; } const char *symbol() const { return m_symbol; }
bool visible() const { return ((m_flags & DSF_NOSHOW) == 0); } bool visible() const { return ((m_flags & DSF_NOSHOW) == 0); }
bool divider() const { return m_flags & DSF_DIVIDER; } bool divider() const { return m_flags & DSF_DIVIDER; }
device_state_interface *parent_state() const {return m_device_state;}
protected: protected:
// device state flags // device state flags
@ -98,6 +98,7 @@ protected:
static const UINT64 k_decimal_divisor[20]; // divisors for outputting decimal values static const UINT64 k_decimal_divisor[20]; // divisors for outputting decimal values
// public state description // public state description
device_state_interface *m_device_state; // link to parent device state
device_state_entry * m_next; // link to next item device_state_entry * m_next; // link to next item
UINT32 m_index; // index by which this item is referred UINT32 m_index; // index by which this item is referred
generic_ptr m_dataptr; // pointer to where the data lives generic_ptr m_dataptr; // pointer to where the data lives

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic // copyright-holders:Miodrag Milanovic,Luca Bruno
/*************************************************************************** /***************************************************************************
luaengine.c 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 // -> manager:machine().devices[":maincpu"].state["PC"].value
//------------------------------------------------- //-------------------------------------------------
UINT64 lua_engine::l_state_get_value(const device_state_entry *d) 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 // -> manager:machine().devices[":maincpu"].state["D0"].value = 0x0c00
//------------------------------------------------- //-------------------------------------------------
void lua_engine::l_state_set_value(device_state_entry *d, UINT64 val) 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 // draw_box - draw a box on a screen container
// -> manager:machine().screens[":screen"]:draw_box(x1, y1, x2, y2, bgcolor, linecolor) // -> 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 // retrieve all parameters
float x1, y1, x2, y2; float x1, y1, x2, y2;
x1 = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->width()) , 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->height()), 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->width()) , 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->height()), 1.0f); y2 = MIN(lua_tounsigned(L, 5) / static_cast<float>(sc->visible_area().height()), 1.0f);
UINT32 bgcolor = lua_tounsigned(L, 6); UINT32 bgcolor = lua_tounsigned(L, 6);
UINT32 fgcolor = lua_tounsigned(L, 7); UINT32 fgcolor = lua_tounsigned(L, 7);
@ -584,10 +672,10 @@ int lua_engine::lua_screen::l_draw_line(lua_State *L)
// retrieve all parameters // retrieve all parameters
float x1, y1, x2, y2; float x1, y1, x2, y2;
x1 = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->width()) , 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->height()), 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->width()) , 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->height()), 1.0f); y2 = MIN(lua_tounsigned(L, 5) / static_cast<float>(sc->visible_area().height()), 1.0f);
UINT32 color = lua_tounsigned(L, 6); UINT32 color = lua_tounsigned(L, 6);
// draw the line // 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"); luaL_argcheck(L, lua_isstring(L, 4), 4, "message (string) expected");
// retrieve all parameters // retrieve all parameters
float x = MIN(lua_tounsigned(L, 2) / static_cast<float>(sc->width()) , 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->height()), 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); const char *msg = luaL_checkstring(L,4);
// TODO: add optional parameters (colors, etc.) // 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_u32", &lua_addr_space::l_mem_read<UINT32>)
.addCFunction ("read_i64", &lua_addr_space::l_mem_read<INT64>) .addCFunction ("read_i64", &lua_addr_space::l_mem_read<INT64>)
.addCFunction ("read_u64", &lua_addr_space::l_mem_read<UINT64>) .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() .endClass()
.deriveClass <address_space, lua_addr_space> ("addr_space") .deriveClass <address_space, lua_addr_space> ("addr_space")
.addFunction("name", &address_space::name) .addFunction("name", &address_space::name)
@ -890,13 +986,14 @@ void lua_engine::initialize()
.addCFunction ("draw_box", &lua_screen::l_draw_box) .addCFunction ("draw_box", &lua_screen::l_draw_box)
.addCFunction ("draw_line", &lua_screen::l_draw_line) .addCFunction ("draw_line", &lua_screen::l_draw_line)
.addCFunction ("draw_text", &lua_screen::l_draw_text) .addCFunction ("draw_text", &lua_screen::l_draw_text)
.addCFunction ("height", &lua_screen::l_height)
.addCFunction ("width", &lua_screen::l_width)
.endClass() .endClass()
.deriveClass <screen_device, lua_screen> ("screen_dev") .deriveClass <screen_device, lua_screen> ("screen_dev")
.addFunction ("frame_number", &screen_device::frame_number)
.addFunction ("name", &screen_device::name) .addFunction ("name", &screen_device::name)
.addFunction ("shortname", &screen_device::shortname) .addFunction ("shortname", &screen_device::shortname)
.addFunction ("tag", &screen_device::tag) .addFunction ("tag", &screen_device::tag)
.addFunction ("height", &screen_device::height)
.addFunction ("width", &screen_device::width)
.endClass() .endClass()
.beginClass <device_state_entry> ("dev_space") .beginClass <device_state_entry> ("dev_space")
.addFunction ("name", &device_state_entry::symbol) .addFunction ("name", &device_state_entry::symbol)

View File

@ -112,9 +112,12 @@ private:
static luabridge::LuaRef l_dev_get_memspaces(const device_t *d); static luabridge::LuaRef l_dev_get_memspaces(const device_t *d);
struct lua_addr_space { struct lua_addr_space {
template<typename T> int l_mem_read(lua_State *L); 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); static luabridge::LuaRef l_machine_get_screens(const running_machine *r);
struct lua_screen { 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_box(lua_State *L);
int l_draw_line(lua_State *L); int l_draw_line(lua_State *L);
int l_draw_text(lua_State *L); int l_draw_text(lua_State *L);

View File

@ -213,6 +213,17 @@ save_error save_manager::check_file(running_machine &machine, emu_file &file, co
return validate_header(header, gamename, sig, errormsg, ""); 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 // 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 // call the post-load functions
for (state_callback *func = m_postload_list.first(); func != NULL; func = func->next()) dispatch_postload();
func->m_func();
return STATERR_NONE; 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 // 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); file.compress(FCOMPRESS_MEDIUM);
// call the pre-save functions // call the pre-save functions
for (state_callback *func = m_presave_list.first(); func != NULL; func = func->next()) dispatch_presave();
func->m_func();
// then write all the data // then write all the data
for (state_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next()) for (state_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next())

View File

@ -99,6 +99,10 @@ public:
void register_presave(save_prepost_delegate func); void register_presave(save_prepost_delegate func);
void register_postload(save_prepost_delegate func); void register_postload(save_prepost_delegate func);
// callback dispatching
void dispatch_presave();
void dispatch_postload();
// generic memory registration // generic memory registration
void save_memory(const char *module, const char *tag, UINT32 index, const char *name, void *val, UINT32 valsize, UINT32 valcount = 1); void save_memory(const char *module, const char *tag, UINT32 index, const char *name, void *val, UINT32 valsize, UINT32 valcount = 1);