Previous 199869 Revisions Next

r30926 Tuesday 10th June, 2014 at 11:59:55 UTC by Miodrag Milanović
Lua overhaul [Olivier Galibert, Miodrag Milanovic]
[src/emu]ioport.c ioport.h luaengine.c luaengine.h machine.c mame.c mame.h webengine.h

trunk/src/emu/machine.c
r30925r30926
195195TIMER_CALLBACK_MEMBER(running_machine::autoboot_callback)
196196{
197197   if (strlen(options().autoboot_script())!=0) {
198      manager().lua()->execute(options().autoboot_script());
198      manager().lua()->load_script(options().autoboot_script());
199199   }
200   if (strlen(options().autoboot_command())!=0) {
200   else if (strlen(options().autoboot_command())!=0) {
201201      astring cmd = astring(options().autoboot_command());
202202      cmd.replace("'","\\'");
203203      astring val = astring("emu.keypost('",cmd,"')");
204      manager().lua()->execute_string(val);
204      manager().lua()->load_string(val);
205205   }
206206}
207207
r30925r30926
292292
293293   // allocate autoboot timer
294294   m_autoboot_timer = scheduler().timer_alloc(timer_expired_delegate(FUNC(running_machine::autoboot_callback), this));
295   
296   manager().update_machine();
295297}
296298
297299
trunk/src/emu/ioport.c
r30925r30926
14601460      m_name(name),
14611461      m_read_param(NULL),
14621462      m_write_param(NULL),
1463      m_digital_value(false),
14631464      m_min(0),
14641465      m_max(maskbits),
14651466      m_sensitivity(0),
r30925r30926
14931494   }
14941495}
14951496
1497void ioport_field::set_value(ioport_value value)
1498{
1499   m_digital_value = value != 0;
1500}
14961501
1502
14971503//-------------------------------------------------
14981504//  ~ioport_field - destructor
14991505//-------------------------------------------------
r30925r30926
18961902      return;
18971903
18981904   // if the state changed, look for switch down/switch up
1899   bool curstate = mouse_down || machine().input().seq_pressed(seq());
1905   bool curstate = mouse_down || machine().input().seq_pressed(seq()) || m_digital_value;
19001906   bool changed = false;
19011907   if (curstate != m_live->last)
19021908   {
trunk/src/emu/ioport.h
r30925r30926
10141014   ioport_condition &condition() { return m_condition; }
10151015   ioport_type type() const { return m_type; }
10161016   UINT8 player() const { return m_player; }
1017   void set_value(ioport_value value);
10171018
10181019   bool unused() const { return ((m_flags & FIELD_FLAG_UNUSED) != 0); }
10191020   bool cocktail() const { return ((m_flags & FIELD_FLAG_COCKTAIL) != 0); }
r30925r30926
11101111   ioport_field_write_delegate m_write;            // write callback routine
11111112   void *                      m_write_param;      // parameter for write callback routine
11121113
1114   // data relevant to digital control types
1115   bool                        m_digital_value;    // externally set value
1116
11131117   // data relevant to analog control types
11141118   ioport_value                m_min;              // minimum value for absolute axes
11151119   ioport_value                m_max;              // maximum value for absolute axes
trunk/src/emu/webengine.h
r30925r30926
2626   void push_message(const char *message);
2727   void close();
2828
29   void set_machine(running_machine &machine) { m_machine = &machine; }
29   void set_machine(running_machine *machine) { m_machine = machine; }
3030   int begin_request_handler(struct mg_connection *conn);
3131protected:
3232   // getters
trunk/src/emu/mame.c
r30925r30926
148148/***************************************************************************
149149    CORE IMPLEMENTATION
150150***************************************************************************/
151void machine_manager::update_machine()
152{   
153   m_lua.set_machine(m_machine);
154   m_web.set_machine(m_machine);
155   if (m_machine!=NULL) m_web.push_message("update_machine");
156}
151157
152158/*-------------------------------------------------
153159    execute - run the core emulation
r30925r30926
205211
206212      set_machine(&machine);
207213
208      m_web.set_machine(machine);
209      m_web.push_message("update_machine");
210
211214      // run the machine
212215      error = machine.run(firstrun);
213216      firstrun = false;
trunk/src/emu/mame.h
r30925r30926
9797
9898   void set_machine(running_machine *machine) { m_machine = machine; }
9999   
100   void update_machine();
101   
100102   /* execute as configured by the OPTION_SYSTEMNAME option on the specified options */
101103   int execute();
102104   void schedule_new_driver(const game_driver &driver);
trunk/src/emu/luaengine.c
r30925r30926
3939#define luai_writestring(s,l)   fwrite((s), sizeof(char), (l), stdout)
4040#define luai_writeline()    (luai_writestring("\n", 1), fflush(stdout))
4141
42const char *const lua_engine::tname_ioport = "lua.ioport";
43lua_engine* lua_engine::luaThis = NULL;
44
45
4246static void lstop(lua_State *L, lua_Debug *ar)
4347{
4448   (void)ar;  /* unused arg. */
r30925r30926
115119   return 0;  /* else... */
116120}
117121
118int emu_gamename(lua_State *L)
122lua_engine::hook::hook()
119123{
120   lua_pushstring(L, machine_manager::instance()->machine()->system().description);
124   L = NULL;
125   cb = -1;
126}
127
128void lua_engine::hook::set(lua_State *_L, int idx)
129{
130   if (L)
131      luaL_unref(L, LUA_REGISTRYINDEX, cb);
132
133   if (lua_isnil(_L, idx)) {
134      L = NULL;
135      cb = -1;
136
137   } else {
138      L = _L;
139      lua_pushvalue(_L, idx);
140      cb = luaL_ref(_L, LUA_REGISTRYINDEX);
141   }
142}
143
144lua_State *lua_engine::hook::precall()
145{
146   lua_State *T = lua_newthread(L);
147   lua_rawgeti(T, LUA_REGISTRYINDEX, cb);
148   return T;
149}
150
151void lua_engine::hook::call(lua_engine *engine, lua_State *T, int nparam)
152{
153   engine->resume(T, nparam, L);
154}
155
156void lua_engine::resume(lua_State *L, int nparam, lua_State *root)
157{
158   int s = lua_resume(L, NULL, nparam);
159   switch(s) {
160   case LUA_OK:
161      if(!root) {
162         std::map<lua_State *, std::pair<lua_State *, int> >::iterator i = thread_registry.find(L);
163         if(i != thread_registry.end()) {
164            luaL_unref(i->second.first, LUA_REGISTRYINDEX, i->second.second);
165            thread_registry.erase(i);
166         }
167      } else
168         lua_pop(root, 1);
169      break;
170
171   case LUA_YIELD:
172      if(root) {
173         int id = luaL_ref(root, LUA_REGISTRYINDEX);
174         thread_registry[L] = std::pair<lua_State *, int>(root, id);
175      }
176      break;
177
178   default:
179      osd_printf_error("[LUA ERROR] %s\n", lua_tostring(L, -1));
180      lua_pop(L, 1);
181      break;
182   }
183}
184
185void lua_engine::resume(void *_L, INT32 param)
186{
187   resume(static_cast<lua_State *>(_L));
188}
189
190int lua_engine::l_ioport_write(lua_State *L)
191{
192   ioport_field *field = static_cast<ioport_field *>(getparam(L, 1, tname_ioport));
193   luaL_argcheck(L, lua_isnumber(L, 2), 2, "value expected");
194    field->set_value(lua_tointeger(L, 2));
195   return 0;
196}
197
198//-------------------------------------------------
199//  emu_gamename - returns game full name
200//-------------------------------------------------
201
202int lua_engine::l_emu_gamename(lua_State *L)
203{
204   lua_pushstring(L, luaThis->machine().system().description);
121205   return 1;
122206}
123207
r30925r30926
125209//  emu_keypost - post keys to natural keyboard
126210//-------------------------------------------------
127211
128int emu_keypost(lua_State *L)
212int lua_engine::l_emu_keypost(lua_State *L)
129213{
130214   const char *keys = luaL_checkstring(L,1);
131   machine_manager::instance()->machine()->ioport().natkeyboard().post_utf8(keys);
215   luaThis->machine().ioport().natkeyboard().post_utf8(keys);
132216   return 1;
133217}
134218
135int emu_exit(lua_State *L)
219int lua_engine::l_emu_time(lua_State *L)
136220{
137   machine_manager::instance()->machine()->schedule_exit();
221   lua_pushnumber(L, luaThis->machine().time().as_double());
138222   return 1;
139223}
140224
141int emu_start(lua_State *L)
225void lua_engine::emu_after_done(void *_h, INT32 param)
142226{
227    hook *h = static_cast<hook *>(_h);
228    h->call(this, h->precall(), 0);
229    delete h;
230}
231
232int lua_engine::emu_after(lua_State *L)
233{
234   luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected");
235    struct hook *h = new hook;
236    h->set(L, 2);
237   machine().scheduler().timer_set(attotime::from_double(lua_tonumber(L, 1)), timer_expired_delegate(FUNC(lua_engine::emu_after_done), this), 0, h);
238   return 0;
239}
240
241int lua_engine::l_emu_after(lua_State *L)
242{
243   return luaThis->emu_after(L);
244}
245
246int lua_engine::emu_wait(lua_State *L)
247{
248   luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected");
249   machine().scheduler().timer_set(attotime::from_double(lua_tonumber(L, 1)), timer_expired_delegate(FUNC(lua_engine::resume), this), 0, L);
250   return lua_yieldk(L, 0, 0, 0);
251}
252
253int lua_engine::l_emu_wait(lua_State *L)
254{
255   return luaThis->emu_wait(L);
256}
257
258void lua_engine::output_notifier(const char *outname, INT32 value)
259{
260   if (hook_output_cb.active()) {
261      lua_State *L = hook_output_cb.precall();
262      lua_pushstring(L, outname);
263      lua_pushnumber(L, value);
264      hook_output_cb.call(this, L, 2);
265   }
266}
267
268void lua_engine::s_output_notifier(const char *outname, INT32 value, void *param)
269{
270   static_cast<lua_engine *>(param)->output_notifier(outname, value);
271}
272
273void lua_engine::emu_hook_output(lua_State *L)
274{
275   luaL_argcheck(L, lua_isfunction(L, 1), 1, "callback function expected");
276   hook_output_cb.set(L, 1);
277
278   if (!output_notifier_set) {
279      output_set_notifier(NULL, s_output_notifier, this);
280      output_notifier_set = true;
281   }
282}
283
284int lua_engine::l_emu_hook_output(lua_State *L)
285{
286   luaThis->emu_hook_output(L);
287   return 0;
288}
289
290
291void *lua_engine::checkparam(lua_State *L, int idx, const char *tname)
292{
293  const char *name;
294
295  if(!lua_getmetatable(L, idx))
296    return 0;
297
298  lua_rawget(L, LUA_REGISTRYINDEX);
299  name = lua_tostring(L, -1);
300  if(!name || strcmp(name, tname)) {
301    lua_pop(L, 1);
302    return 0;
303  }
304  lua_pop(L, 1);
305
306  return *static_cast<void **>(lua_touserdata(L, idx));
307}
308
309void *lua_engine::getparam(lua_State *L, int idx, const char *tname)
310{
311   void *p = checkparam(L, idx, tname);
312  char msg[256];
313  sprintf(msg, "%s expected", tname);
314  luaL_argcheck(L, p, idx, msg);
315  return p;
316}
317
318void lua_engine::push(lua_State *L, void *p, const char *tname)
319{
320  void **pp = static_cast<void **>(lua_newuserdata(L, sizeof(void *)));
321  *pp = p;
322  luaL_getmetatable(L, tname);
323  lua_setmetatable(L, -2);
324}
325
326int lua_engine::l_emu_exit(lua_State *L)
327{
328   luaThis->machine().schedule_exit();
329   return 1;
330}
331
332int lua_engine::l_emu_start(lua_State *L)
333{
143334   const char *system_name = luaL_checkstring(L,1);
144335   
145336   int index = driver_list::find(system_name);
146337   if (index != -1) {
147338      machine_manager::instance()->schedule_new_driver(driver_list::driver(index));   
148      machine_manager::instance()->machine()->schedule_hard_reset();
339      luaThis->machine().schedule_hard_reset();
149340   }
150341   return 1;
151342}
152343
153static const struct luaL_Reg emu_funcs [] =
154{
155   { "gamename", emu_gamename },
156   { "keypost", emu_keypost },
157   { "exit", emu_exit },
158   { "start", emu_start },
159   { NULL, NULL }  /* sentinel */
160};
161
162344//-------------------------------------------------
163345//  luaopen_emu - connect emu section lib
164346//-------------------------------------------------
165347
166static int luaopen_emu ( lua_State * L )
348int lua_engine::luaopen_emu(lua_State *L)
167349{
350   static const struct luaL_Reg emu_funcs [] = {
351      { "gamename",    l_emu_gamename },
352      { "keypost",     l_emu_keypost },
353      { "hook_output", l_emu_hook_output },
354      { "time",        l_emu_time },
355      { "wait",        l_emu_wait },
356      { "after",       l_emu_after },
357      { "exit",       l_emu_exit },
358      { "start",        l_emu_start },
359      { NULL, NULL }  /* sentinel */
360   };
361
168362   luaL_newlib(L, emu_funcs);
169363   return 1;
170364}
171365
366int lua_engine::luaopen_ioport(lua_State *L)
367{
368   static const struct luaL_Reg ioport_funcs [] = {
369      { "write",       l_ioport_write },
370      { NULL, NULL }  /* sentinel */
371   };
172372
373   luaL_newmetatable(L, tname_ioport);
374   lua_pushvalue(L, -1);
375   lua_pushstring(L, tname_ioport);
376   lua_rawset(L, LUA_REGISTRYINDEX);
377   lua_pushstring(L, "__index");
378   lua_pushvalue(L, -2);
379   lua_settable(L, -3);
380   luaL_setfuncs(L, ioport_funcs, 0);
381   return 1;
382}
383
173384struct msg {
174385   astring text;
175386   int ready;
r30925r30926
245456
246457lua_engine::lua_engine()
247458{
459   m_machine = NULL;
460   luaThis = this;
248461   m_lua_state = luaL_newstate();  /* create state */
462   output_notifier_set = false;
463   
249464   luaL_checkversion(m_lua_state);
250465   lua_gc(m_lua_state, LUA_GCSTOP, 0);  /* stop collector during initialization */
251466   luaL_openlibs(m_lua_state);  /* open libraries */
252467   
253468   luaopen_lsqlite3(m_lua_state);
254469   luaL_requiref(m_lua_state, "emu", luaopen_emu, 1);
255     
470   
471   luaopen_ioport(m_lua_state);
472
256473   lua_gc(m_lua_state, LUA_GCRESTART, 0);     
257474   msg.ready = 0;
258475   msg.status = 0;
r30925r30926
269486   close();
270487}
271488
489
490void lua_engine::update_machine()
491{   
492   lua_newtable(m_lua_state);
493   if (m_machine!=NULL)
494   {
495      // Create the ioport array
496      ioport_port *port = machine().ioport().first_port();
497      while(port) {
498         ioport_field *field = port->first_field();
499         while(field) {
500            if(field->name()) {
501               push(m_lua_state, field, tname_ioport);
502               lua_setfield(m_lua_state, -2, field->name());
503            }
504            field = field->next();
505         }
506         port = port->next();
507      }
508   }
509   lua_setglobal(m_lua_state, "ioport");
510}
511
272512//-------------------------------------------------
273513//  initialize - initialize lua hookup to emu engine
274514//-------------------------------------------------
r30925r30926
326566//  execute - load and execute script
327567//-------------------------------------------------
328568
329void lua_engine::execute(const char *filename)
569void lua_engine::load_script(const char *filename)
330570{
331571   int s = luaL_loadfile(m_lua_state, filename);
332   s = docall(0, 0);   
333572   report(s);   
334   lua_settop(m_lua_state, 0);
573   start();
335574}
336575
337576//-------------------------------------------------
338577//  execute_string - execute script from string
339578//-------------------------------------------------
340579
341void lua_engine::execute_string(const char *value)
580void lua_engine::load_string(const char *value)
342581{
343582   int s = luaL_loadstring(m_lua_state, value);
344   s = docall(0, 0);
345583   report(s);   
346   lua_settop(m_lua_state, 0);
584   start();
347585}
586
587//-------------------------------------------------
588//  start - execute the loaded script
589//-------------------------------------------------
590
591void lua_engine::start()
592{
593   resume(m_lua_state);
594}
595
trunk/src/emu/luaengine.h
r30925r30926
1717#ifndef __LUA_ENGINE_H__
1818#define __LUA_ENGINE_H__
1919
20#include <map>
21
2022struct lua_State;
2123
2224class lua_engine
r30925r30926
2729   ~lua_engine();
2830
2931   void initialize();
30   void execute(const char *filename);
31   void execute_string(const char *value);
32   void close();
32   void load_script(const char *filename);
33   void load_string(const char *value);
3334
3435   void serve_lua();
3536   void periodic_check();
36private:   
37
38   void resume(lua_State *L, int nparam = 0, lua_State *root = NULL);
39   void set_machine(running_machine *machine) { m_machine = machine; update_machine(); }
40private:
41   struct hook {
42      lua_State *L;
43      int cb;
44
45      hook();
46       void set(lua_State *L, int idx);
47      lua_State *precall();
48      void call(lua_engine *engine, lua_State *T, int nparam);
49      bool active() const { return L != NULL; }
50   };
51   
52   static const char *const tname_ioport;
53
54   // internal state
55   lua_State          *m_lua_state;
56   running_machine *   m_machine;
57
58   hook hook_output_cb;
59   bool output_notifier_set;
60   
61   static lua_engine*  luaThis;
62
63   std::map<lua_State *, std::pair<lua_State *, int> > thread_registry;
64
65   running_machine &machine() const { return *m_machine; }
66
67   void update_machine();
68   void output_notifier(const char *outname, INT32 value);
69   static void s_output_notifier(const char *outname, INT32 value, void *param);
70
71   void emu_after_done(void *_h, INT32 param);
72   int emu_after(lua_State *L);
73   int emu_wait(lua_State *L);
74   void emu_hook_output(lua_State *L);
75
76   static int l_ioport_write(lua_State *L);
77   static int l_emu_after(lua_State *L);
78   static int l_emu_wait(lua_State *L);
79   static int l_emu_time(lua_State *L);
80   static int l_emu_gamename(lua_State *L);
81   static int l_emu_keypost(lua_State *L);
82   static int l_emu_hook_output(lua_State *L);
83   static int l_emu_exit(lua_State *L);
84   static int l_emu_start(lua_State *L);
85
86   void resume(void *L, INT32 param);
87   void report_errors(int status);
88   void start();
89   static int luaopen_emu(lua_State *L);
90   static int luaopen_ioport(lua_State *L);
91   void close();
92
93   static void *checkparam(lua_State *L, int idx, const char *tname);
94   static void *getparam(lua_State *L, int idx, const char *tname);
95   static void push(lua_State *L, void *p, const char *tname);
96   
3797   int report(int status);
3898   int docall(int narg, int nres);
3999   int incomplete(int status) ;
40private:
41   // internal state
42   lua_State*          m_lua_state;
43100};
44101
45102#endif  /* __LUA_ENGINE_H__ */

Previous 199869 Revisions Next


© 1997-2024 The MAME Team