Upload UI
[lsnes.git] / src / lua / core.cpp
blob75d9d83a4c82cc08fa5d8b6531ea2f886005b483
1 #include "core/command.hpp"
2 #include "lua/internal.hpp"
3 #include "core/framerate.hpp"
4 #include "core/moviefile.hpp"
5 #include "core/moviedata.hpp"
6 #include "core/window.hpp"
7 #include "interface/romtype.hpp"
8 #include "library/string.hpp"
9 #include <sstream>
11 namespace
13 std::string luavalue_to_string(lua_state& L, int index, std::set<const void*>& printed, bool quote)
15 switch(L.type(index)) {
16 case LUA_TNONE:
17 return "none";
18 case LUA_TNIL:
19 return "nil";
20 case LUA_TBOOLEAN:
21 return L.toboolean(index) ? "true" : "false";
22 case LUA_TNUMBER:
23 return (stringfmt() << L.tonumber(index)).str();
24 case LUA_TSTRING: {
25 const char* tmp2;
26 size_t len;
27 tmp2 = L.tolstring(index, &len);
28 if(quote)
29 return "\"" + std::string(tmp2, tmp2 + len) + "\"";
30 else
31 return std::string(tmp2, tmp2 + len);
33 case LUA_TLIGHTUSERDATA:
34 return (stringfmt() << "Lightuserdata:" << L.touserdata(index)).str();
35 case LUA_TFUNCTION:
36 return (stringfmt() << "Function:" << L.topointer(index)).str();
37 case LUA_TTHREAD:
38 return (stringfmt() << "Thread:" << L.topointer(index)).str();
39 break;
40 case LUA_TUSERDATA:
41 return (stringfmt() << "Userdata<" << try_recognize_userdata(L, index) << "@"
42 << L.touserdata(index) << ">:[" << try_print_userdata(L, index) << "]").str();
43 case LUA_TTABLE: {
44 //Fun with recursion.
45 const void* ptr = L.topointer(index);
46 if(printed.count(ptr))
47 return (stringfmt() << "<table:" << ptr << ">").str();
48 printed.insert(ptr);
49 std::ostringstream s;
50 s << "<" << ptr << ">{";
51 L.pushnil();
52 bool first = true;
53 while(L.next(index)) {
54 if(!first)
55 s << ", ";
56 int stacktop = L.gettop();
57 s << "[" << luavalue_to_string(L, stacktop - 1, printed, true) << "]="
58 << luavalue_to_string(L, stacktop, printed, true);
59 first = false;
60 L.pop(1);
62 s << "}";
63 return s.str();
65 default:
66 return (stringfmt() << "???:" << L.topointer(index)).str();
70 function_ptr_luafun lua_tostringx(lua_func_misc, "tostringx", [](lua_state& L, const std::string& fname) ->
71 int {
72 std::set<const void*> tmp2;
73 std::string y = luavalue_to_string(L, 1, tmp2, false);
74 L.pushlstring(y.c_str(), y.length());
75 return 1;
76 });
78 function_ptr_luafun lua_print(lua_func_misc, "print2", [](lua_state& L, const std::string& fname) -> int {
79 int stacksize = 0;
80 while(!L.isnone(stacksize + 1))
81 stacksize++;
82 std::string toprint;
83 bool first = true;
84 for(int i = 0; i < stacksize; i++) {
85 std::set<const void*> tmp2;
86 std::string tmp = luavalue_to_string(L, i + 1, tmp2, false);
87 if(first)
88 toprint = tmp;
89 else
90 toprint = toprint + "\t" + tmp;
91 first = false;
93 platform::message(toprint);
94 return 0;
95 });
97 function_ptr_luafun lua_exec(lua_func_misc, "exec", [](lua_state& L, const std::string& fname) -> int {
98 std::string text = L.get_string(1, fname.c_str());
99 lsnes_cmd.invoke(text);
100 return 0;
103 function_ptr_luafun lua_booted(lua_func_misc, "emulator_ready", [](lua_state& L, const std::string& fname)
104 -> int {
105 L.pushboolean(lua_booted_flag ? 1 : 0);
106 return 1;
109 function_ptr_luafun lua_utime(lua_func_misc, "utime", [](lua_state& L, const std::string& fname) -> int {
110 uint64_t t = get_utime();
111 L.pushnumber(t / 1000000);
112 L.pushnumber(t % 1000000);
113 return 2;
116 function_ptr_luafun lua_idle_time(lua_func_misc, "set_idle_timeout", [](lua_state& L,
117 const std::string& fname) -> int {
118 lua_idle_hook_time = get_utime() + L.get_numeric_argument<uint64_t>(1, fname.c_str());
119 return 0;
122 function_ptr_luafun lua_timer_time(lua_func_misc, "set_timer_timeout", [](lua_state& L,
123 const std::string& fname) -> int {
124 lua_timer_hook_time = get_utime() + L.get_numeric_argument<uint64_t>(1, fname.c_str());
125 return 0;
128 function_ptr_luafun lua_busaddr(lua_func_misc, "bus_address", [](lua_state& L, const std::string& fname)
129 -> int {
130 uint64_t addr = L.get_numeric_argument<uint64_t>(1, fname.c_str());
131 auto busrange = our_rom.rtype->get_bus_map();
132 if(!busrange.second)
133 throw std::runtime_error("This platform does not have bus mapping");
134 L.pushnumber(busrange.first + (addr % busrange.second));
135 return 1;
138 function_ptr_luafun mgetlagflag(lua_func_misc, "memory.get_lag_flag", [](lua_state& L,
139 const std::string& fname) -> int {
140 L.pushboolean(!(our_rom.rtype && our_rom.rtype->get_pflag()));
141 return 1;
144 function_ptr_luafun msetlagflag(lua_func_misc, "memory.set_lag_flag", [](lua_state& L,
145 const std::string& fname) -> int {
146 if(our_rom.rtype)
147 our_rom.rtype->set_pflag(!L.get_bool(1, fname.c_str()));
148 return 0;