Some non-instance variables cleanup
[lsnes.git] / src / lua / core.cpp
blobef0e409ae967a0922ca2e5f6384c2a922b912b10
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/window.hpp"
8 #include "interface/romtype.hpp"
9 #include "library/string.hpp"
10 #include <sstream>
12 namespace
14 std::string luavalue_to_string(lua::state& L, int index, std::set<const void*>& printed, bool quote)
16 switch(L.type(index)) {
17 case LUA_TNONE:
18 return "none";
19 case LUA_TNIL:
20 return "nil";
21 case LUA_TBOOLEAN:
22 return L.toboolean(index) ? "true" : "false";
23 case LUA_TNUMBER:
24 return (stringfmt() << L.tonumber(index)).str();
25 case LUA_TSTRING: {
26 const char* tmp2;
27 size_t len;
28 tmp2 = L.tolstring(index, &len);
29 if(quote)
30 return "\"" + std::string(tmp2, tmp2 + len) + "\"";
31 else
32 return std::string(tmp2, tmp2 + len);
34 case LUA_TLIGHTUSERDATA:
35 return (stringfmt() << "Lightuserdata:" << L.touserdata(index)).str();
36 case LUA_TFUNCTION:
37 return (stringfmt() << "Function:" << L.topointer(index)).str();
38 case LUA_TTHREAD:
39 return (stringfmt() << "Thread:" << L.topointer(index)).str();
40 break;
41 case LUA_TUSERDATA:
42 return (stringfmt() << "Userdata<" << try_recognize_userdata(L, index) << "@"
43 << L.touserdata(index) << ">:[" << try_print_userdata(L, index) << "]").str();
44 case LUA_TTABLE: {
45 //Fun with recursion.
46 const void* ptr = L.topointer(index);
47 if(printed.count(ptr))
48 return (stringfmt() << "<table:" << ptr << ">").str();
49 printed.insert(ptr);
50 std::ostringstream s;
51 s << "<" << ptr << ">{";
52 L.pushnil();
53 bool first = true;
54 while(L.next(index)) {
55 if(!first)
56 s << ", ";
57 int stacktop = L.gettop();
58 s << "[" << luavalue_to_string(L, stacktop - 1, printed, true) << "]="
59 << luavalue_to_string(L, stacktop, printed, true);
60 first = false;
61 L.pop(1);
63 s << "}";
64 return s.str();
66 default:
67 return (stringfmt() << "???:" << L.topointer(index)).str();
71 int identify_class(lua::state& L, lua::parameters& P)
73 if(!P.is_userdata())
74 return 0;
75 L.pushlstring(try_recognize_userdata(L, 1));
76 return 1;
79 int tostringx(lua::state& L, lua::parameters& P)
81 std::set<const void*> tmp2;
82 std::string y = luavalue_to_string(L, 1, tmp2, false);
83 L.pushlstring(y);
84 return 1;
87 int print2(lua::state& L, lua::parameters& P)
89 std::string toprint;
90 bool first = true;
91 while(P.more()) {
92 int i = P.skip();
93 std::set<const void*> tmp2;
94 std::string tmp = luavalue_to_string(L, i, tmp2, false);
95 if(first)
96 toprint = tmp;
97 else
98 toprint = toprint + "\t" + tmp;
99 first = false;
101 platform::message(toprint);
102 return 0;
105 int exec(lua::state& L, lua::parameters& P)
107 std::string text;
109 P(text);
111 CORE().command->invoke(text);
112 return 0;
115 int lookup_class(lua::state& L, lua::parameters& P)
117 std::string clazz;
119 P(clazz);
121 return lua::class_base::lookup_and_push(L, clazz) ? 1 : 0;
124 int all_classes(lua::state& L, lua::parameters& P)
126 auto c = lua::class_base::all_classes(L);
127 int count = 0;
128 for(auto& i : c) {
129 L.pushlstring(i);
130 count++;
132 return count;
135 int emulator_ready(lua::state& L, lua::parameters& P)
137 L.pushboolean(true);
138 return 1;
141 int utime(lua::state& L, lua::parameters& P)
143 uint64_t t = framerate_regulator::get_utime();
144 L.pushnumber(t / 1000000);
145 L.pushnumber(t % 1000000);
146 return 2;
149 int set_idle_timeout(lua::state& L, lua::parameters& P)
151 auto& core = CORE();
152 uint64_t dt;
154 P(dt);
156 core.lua2->idle_hook_time = framerate_regulator::get_utime() + dt;
157 return 0;
160 int set_timer_timeout(lua::state& L, lua::parameters& P)
162 auto& core = CORE();
163 uint64_t dt;
165 P(dt);
167 core.lua2->timer_hook_time = framerate_regulator::get_utime() + dt;
168 return 0;
171 int bus_address(lua::state& L, lua::parameters& P)
173 uint64_t addr;
175 P(addr);
177 auto busrange = our_rom.rtype->get_bus_map();
178 if(!busrange.second)
179 throw std::runtime_error("This platform does not have bus mapping");
180 L.pushnumber(busrange.first + (addr % busrange.second));
181 return 1;
184 int get_lag_flag(lua::state& L, lua::parameters& P)
186 L.pushboolean(!(our_rom.rtype && our_rom.rtype->get_pflag()));
187 return 1;
190 int set_lag_flag(lua::state& L, lua::parameters& P)
192 bool flag;
194 P(flag);
196 if(our_rom.rtype)
197 our_rom.rtype->set_pflag(!flag);
198 return 0;
201 lua::functions LUA_misc_fns(lua_func_misc, "", {
202 {"print2", print2},
203 {"exec", exec},
204 {"emulator_ready", emulator_ready},
205 {"utime", utime},
206 {"set_idle_timeout", set_idle_timeout},
207 {"set_timer_timeout", set_timer_timeout},
208 {"bus_address", bus_address},
209 {"memory.get_lag_flag", get_lag_flag},
210 {"memory.set_lag_flag", set_lag_flag},
213 lua::functions LUA_pure_fns(lua_func_bit, "", {
214 {"identify_class", identify_class},
215 {"tostringx", tostringx},
216 {"lookup_class", lookup_class},
217 {"all_classes", all_classes},