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::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);

View File

@ -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

View File

@ -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)

View File

@ -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);

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, "");
}
//-------------------------------------------------
// 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())

View File

@ -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);