1 #include "core/command.hpp"
2 #include "lua/internal.hpp"
3 #include "core/framerate.hpp"
4 #include "core/instance.hpp"
5 #include "core/moviefile.hpp"
6 #include "core/moviedata.hpp"
7 #include "core/rom.hpp"
8 #include "core/runmode.hpp"
9 #include "core/window.hpp"
10 #include "interface/romtype.hpp"
11 #include "library/directory.hpp"
12 #include "library/zip.hpp"
13 #include "library/string.hpp"
18 std::string
luavalue_to_string(lua::state
& L
, int index
, std::set
<const void*>& printed
, bool quote
)
20 switch(L
.type(index
)) {
26 return L
.toboolean(index
) ? "true" : "false";
28 if(L
.isinteger(index
))
29 return (stringfmt() << L
.tointeger(index
)).str();
31 return (stringfmt() << L
.tonumber(index
)).str();
35 tmp2
= L
.tolstring(index
, &len
);
37 return "\"" + std::string(tmp2
, tmp2
+ len
) + "\"";
39 return std::string(tmp2
, tmp2
+ len
);
41 case LUA_TLIGHTUSERDATA
:
42 return (stringfmt() << "Lightuserdata:" << L
.touserdata(index
)).str();
44 return (stringfmt() << "Function:" << L
.topointer(index
)).str();
46 return (stringfmt() << "Thread:" << L
.topointer(index
)).str();
49 return (stringfmt() << "Userdata<" << try_recognize_userdata(L
, index
) << "@"
50 << L
.touserdata(index
) << ">:[" << try_print_userdata(L
, index
) << "]").str();
53 const void* ptr
= L
.topointer(index
);
54 if(printed
.count(ptr
))
55 return (stringfmt() << "<table:" << ptr
<< ">").str();
58 s
<< "<" << ptr
<< ">{";
61 while(L
.next(index
)) {
64 int stacktop
= L
.gettop();
65 s
<< "[" << luavalue_to_string(L
, stacktop
- 1, printed
, true) << "]="
66 << luavalue_to_string(L
, stacktop
, printed
, true);
74 return (stringfmt() << "???:" << L
.topointer(index
)).str();
78 int identify_class(lua::state
& L
, lua::parameters
& P
)
82 L
.pushlstring(try_recognize_userdata(L
, 1));
86 int tostringx(lua::state
& L
, lua::parameters
& P
)
88 std::set
<const void*> tmp2
;
89 std::string y
= luavalue_to_string(L
, 1, tmp2
, false);
94 int print2(lua::state
& L
, lua::parameters
& P
)
100 std::set
<const void*> tmp2
;
101 std::string tmp
= luavalue_to_string(L
, i
, tmp2
, false);
105 toprint
= toprint
+ "\t" + tmp
;
108 platform::message(toprint
);
112 int exec(lua::state
& L
, lua::parameters
& P
)
118 CORE().command
->invoke(text
);
122 int lookup_class(lua::state
& L
, lua::parameters
& P
)
128 return lua::class_base::lookup_and_push(L
, clazz
) ? 1 : 0;
131 int all_classes(lua::state
& L
, lua::parameters
& P
)
133 auto c
= lua::class_base::all_classes(L
);
142 int emulator_ready(lua::state
& L
, lua::parameters
& P
)
148 int utime(lua::state
& L
, lua::parameters
& P
)
150 uint64_t t
= framerate_regulator::get_utime();
151 L
.pushnumber(t
/ 1000000);
152 L
.pushnumber(t
% 1000000);
156 int set_idle_timeout(lua::state
& L
, lua::parameters
& P
)
163 core
.lua2
->idle_hook_time
= framerate_regulator::get_utime() + dt
;
167 int set_timer_timeout(lua::state
& L
, lua::parameters
& P
)
174 core
.lua2
->timer_hook_time
= framerate_regulator::get_utime() + dt
;
178 int bus_address(lua::state
& L
, lua::parameters
& P
)
185 auto busrange
= core
.rom
->get_bus_map();
187 throw std::runtime_error("This platform does not have bus mapping");
188 L
.pushnumber(busrange
.first
+ (addr
% busrange
.second
));
192 int get_lag_flag(lua::state
& L
, lua::parameters
& P
)
195 L
.pushboolean(!core
.rom
->get_pflag());
199 int set_lag_flag(lua::state
& L
, lua::parameters
& P
)
206 core
.rom
->set_pflag(!flag
);
210 int get_lua_memory_use(lua::state
& L
, lua::parameters
& P
)
212 L
.pushnumber(L
.get_memory_use());
213 L
.pushnumber(L
.get_memory_limit());
217 int get_runmode(lua::state
& L
, lua::parameters
& P
)
220 auto m
= core
.runmode
->get();
221 if(m
== emulator_runmode::QUIT
) L
.pushstring("quit");
222 else if(m
== emulator_runmode::NORMAL
) L
.pushstring("normal");
223 else if(m
== emulator_runmode::LOAD
) L
.pushstring("load");
224 else if(m
== emulator_runmode::ADVANCE_FRAME
) L
.pushstring("advance_frame");
225 else if(m
== emulator_runmode::ADVANCE_SUBFRAME
) L
.pushstring("advance_subframe");
226 else if(m
== emulator_runmode::SKIPLAG
) L
.pushstring("skiplag");
227 else if(m
== emulator_runmode::SKIPLAG_PENDING
) L
.pushstring("skiplag_pending");
228 else if(m
== emulator_runmode::PAUSE
) L
.pushstring("pause");
229 else if(m
== emulator_runmode::PAUSE_BREAK
) L
.pushstring("pause_break");
230 else if(m
== emulator_runmode::CORRUPT
) L
.pushstring("corrupt");
231 else L
.pushstring("unknown");
235 int lsnes_features(lua::state
& L
, lua::parameters
& P
)
240 if(arg
== "text-halos") ok
= true;
245 int get_directory_contents(lua::state
& L
, lua::parameters
& P
)
247 std::string arg1
, arg2
, pattern
;
248 P(arg1
, P
.optional(arg2
, ""), P
.optional(pattern
, ".*"));
249 std::string arg
= zip::resolverel(arg1
, arg2
);
250 auto dirlist
= directory::enumerate(arg
, pattern
);
253 for(auto i
: dirlist
) {
261 int get_file_type(lua::state
& L
, lua::parameters
& P
)
263 std::string arg
, type
;
265 if(!directory::exists(arg
)) {
267 } else if(directory::is_regular(arg
)) {
268 L
.pushstring("regular");
269 } else if(directory::is_directory(arg
)) {
270 L
.pushstring("directory");
272 L
.pushstring("unknown");
277 lua::functions
LUA_misc_fns(lua_func_misc
, "", {
280 {"emulator_ready", emulator_ready
},
282 {"set_idle_timeout", set_idle_timeout
},
283 {"set_timer_timeout", set_timer_timeout
},
284 {"bus_address", bus_address
},
285 {"get_lua_memory_use", get_lua_memory_use
},
286 {"get_directory_contents", get_directory_contents
},
287 {"get_file_type", get_file_type
},
288 {"lsnes_features", lsnes_features
},
289 {"memory.get_lag_flag", get_lag_flag
},
290 {"memory.set_lag_flag", set_lag_flag
},
291 {"gui.get_runmode", get_runmode
},
294 lua::functions
LUA_pure_fns(lua_func_bit
, "", {
295 {"identify_class", identify_class
},
296 {"tostringx", tostringx
},
297 {"lookup_class", lookup_class
},
298 {"all_classes", all_classes
},