lsnes rr2-β24
[lsnes.git] / src / lua / movie.cpp
blobc0963fdcd940469196fde590e5eaff5c503db113
1 #include "lua/internal.hpp"
2 #include "lua/unsaferewind.hpp"
3 #include "core/instance.hpp"
4 #include "core/moviedata.hpp"
5 #include "core/mainloop.hpp"
7 namespace
9 int currentframe(lua::state& L, lua::parameters& P)
11 auto& m = CORE().mlogic->get_movie();
12 L.pushnumber(m.get_current_frame());
13 return 1;
16 int lagcounter(lua::state& L, lua::parameters& P)
18 auto& m = CORE().mlogic->get_movie();
19 L.pushnumber(m.get_lag_frames());
20 return 1;
23 int framecount(lua::state& L, lua::parameters& P)
25 auto& m = CORE().mlogic->get_movie();
26 L.pushnumber(m.get_frame_count());
27 return 1;
30 int rerecords(lua::state& L, lua::parameters& P)
32 L.pushnumber(CORE().mlogic->get_rrdata().count());
33 return 1;
36 int readonly(lua::state& L, lua::parameters& P)
38 auto& m = CORE().mlogic->get_movie();
39 L.pushboolean(m.readonly_mode() ? 1 : 0);
40 return 1;
43 int readwrite(lua::state& L, lua::parameters& P)
45 auto& m = CORE().mlogic->get_movie();
46 m.readonly_mode(false);
47 return 0;
50 int frame_subframes(lua::state& L, lua::parameters& P)
52 uint64_t frame;
54 P(frame);
56 auto& m = CORE().mlogic->get_movie();
57 L.pushnumber(m.frame_subframes(frame));
58 return 1;
61 int read_subframes(lua::state& L, lua::parameters& P)
63 uint64_t frame, subframe;
65 P(frame, subframe);
67 auto& m = CORE().mlogic->get_movie();
68 portctrl::frame r = m.read_subframe(frame, subframe);
69 L.newtable();
71 for(size_t i = 0; i < r.get_index_count(); i++) {
72 L.pushnumber(i);
73 L.pushnumber(r.axis2(i));
74 L.settable(-3);
76 return 1;
79 int read_rtc(lua::state& L, lua::parameters& P)
81 auto& core = CORE();
82 L.pushnumber(core.mlogic->get_mfile().dyn.rtc_second);
83 L.pushnumber(core.mlogic->get_mfile().dyn.rtc_subsecond);
84 return 2;
87 int unsafe_rewind(lua::state& L, lua::parameters& P)
89 if(P.is_novalue()) {
90 //Start process to mark save.
91 mainloop_signal_need_rewind(NULL);
92 } else if(P.is<lua_unsaferewind>()) {
93 //Load the save.
94 lua::objpin<lua_unsaferewind> pin;
96 P(pin);
98 mainloop_signal_need_rewind(new lua::objpin<lua_unsaferewind>(pin));
99 } else
100 P.expected("UNSAFEREWIND or nil");
101 return 0;
104 int to_rewind(lua::state& L, lua::parameters& P)
106 auto& core = CORE();
107 std::string filename;
109 P(filename);
111 moviefile mfile(filename, core.rom->get_internal_rom_type());
112 if(!mfile.dyn.save_frame)
113 throw std::runtime_error("movie.to_rewind only allows savestates");
114 lua_unsaferewind* u2 = lua::_class<lua_unsaferewind>::create(L);
115 u2->console_state = mfile.dyn;
116 //Cut off the hash.
117 if(u2->console_state.savestate.size() >= 32)
118 u2->console_state.savestate.resize(u2->console_state.savestate.size() - 32);
119 //Now the remaining field ptr is somewhat nastier.
120 uint64_t f = 0;
121 uint64_t s = mfile.input->size();
122 u2->ptr = 0;
123 while(++f < u2->console_state.save_frame) {
124 if(u2->ptr < s)
125 u2->ptr++;
126 while(u2->ptr < s && !(*mfile.input)[u2->ptr].sync())
127 u2->ptr++;
129 return 1;
132 int rom_loaded(lua::state& L, lua::parameters& P)
134 auto& core = CORE();
135 L.pushboolean(!core.rom->get_internal_rom_type().isnull());
136 return 1;
139 int get_rom_info(lua::state& L, lua::parameters& P)
141 auto& core = CORE();
142 auto& rom = *(core.rom);
143 bool any_loaded = false;
145 L.newtable();
146 for(unsigned i = 0; i < ROM_SLOT_COUNT; i++) {
147 auto img = &rom.get_rom(i);
148 auto xml = &rom.get_markup(i);
149 if(img->sha_256.read() == "") img = NULL; //Trivial image.
150 if(xml->sha_256.read() == "") xml = NULL; //Trivial image.
151 if(!img && !xml) continue;
152 any_loaded = true;
153 L.pushnumber(i+1);
154 L.newtable();
155 if(img) {
156 L.pushstring("filename");
157 L.pushlstring(img->filename);
158 L.rawset(-3);
159 L.pushstring("hint");
160 L.pushlstring(img->namehint);
161 L.rawset(-3);
162 L.pushstring("sha256");
163 L.pushlstring(img->sha_256.read());
164 L.rawset(-3);
166 if(xml) {
167 L.pushstring("xml_filename");
168 L.pushlstring(xml->filename);
169 L.rawset(-3);
170 L.pushstring("xml_hint");
171 L.pushlstring(xml->namehint);
172 L.rawset(-3);
173 L.pushstring("xml_sha256");
174 L.pushlstring(xml->sha_256.read());
175 L.rawset(-3);
177 L.rawset(-3);
179 if(!any_loaded) {
180 L.pop(1);
181 return 0;
183 return 1;
186 int get_game_info(lua::state& L, lua::parameters& P)
188 uint64_t framemagic[4];
189 auto& core = CORE();
190 auto& rom = core.rom->get_internal_rom_type();
191 auto& sysreg = rom.combine_region(rom.get_region());
193 sysreg.fill_framerate_magic(framemagic);
195 L.newtable();
197 L.pushstring("core");
198 L.pushlstring(rom.get_core_identifier());
199 L.rawset(-3);
200 L.pushstring("core_short");
201 L.pushlstring(rom.get_core_shortname());
202 L.rawset(-3);
203 L.pushstring("type");
204 L.pushlstring(rom.get_iname());
205 L.rawset(-3);
206 L.pushstring("type_long");
207 L.pushlstring(rom.get_hname());
208 L.rawset(-3);
209 L.pushstring("region");
210 L.pushlstring(rom.get_region().get_iname());
211 L.rawset(-3);
212 L.pushstring("region_long");
213 L.pushlstring(rom.get_region().get_hname());
214 L.rawset(-3);
215 L.pushstring("gametype");
216 L.pushlstring(sysreg.get_name());
217 L.rawset(-3);
218 L.pushstring("fps_n");
219 L.pushnumber(framemagic[1]);
220 L.rawset(-3);
221 L.pushstring("fps_d");
222 L.pushnumber(framemagic[0]);
223 L.rawset(-3);
224 L.pushstring("fps");
225 L.pushnumber(1.0 * framemagic[1] / framemagic[0]);
226 L.rawset(-3);
228 return 1;
231 int get_last_movie(lua::state& L, lua::parameters& P)
233 auto m = CORE().mlogic->get_mfile().get_filename();
234 if(m != "")
235 L.pushlstring(m);
236 else
237 L.pushnil();
238 return 1;
241 lua::functions LUA_movie_fns(lua_func_misc, "movie", {
242 {"currentframe", currentframe},
243 {"lagcount", lagcounter},
244 {"framecount", framecount},
245 {"rerecords", rerecords},
246 {"readonly", readonly},
247 {"readwrite", readwrite},
248 {"frame_subframes", frame_subframes},
249 {"read_subframes", read_subframes},
250 {"read_rtc", read_rtc},
251 {"unsafe_rewind", unsafe_rewind},
252 {"to_rewind", to_rewind},
253 {"rom_loaded", rom_loaded},
254 {"get_rom_info", get_rom_info},
255 {"get_game_info", get_game_info},
256 {"get_last_movie", get_last_movie},