Refactor dynamic state to its own subobject
[lsnes.git] / src / lua / movie.cpp
blobc40277ff27a4c5920bb4598c2f183d96e2bdc7db
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.is_savestate)
113 throw std::runtime_error("movie.to_rewind only allows savestates");
114 lua_unsaferewind* u2 = lua::_class<lua_unsaferewind>::create(L);
115 u2->state = mfile.dyn.savestate;
116 if(u2->state.size() >= 32)
117 u2->state.resize(u2->state.size() - 32);
118 u2->secs = mfile.dyn.rtc_second;
119 u2->ssecs = mfile.dyn.rtc_subsecond;
120 u2->pollcounters = mfile.dyn.pollcounters;
121 u2->lag = mfile.dyn.lagged_frames;
122 u2->frame = mfile.dyn.save_frame;
123 u2->hostmemory = mfile.dyn.host_memory;
124 //Now the remaining field ptr is somewhat nastier.
125 uint64_t f = 0;
126 uint64_t s = mfile.input->size();
127 u2->ptr = 0;
128 while(++f < u2->frame) {
129 if(u2->ptr < s)
130 u2->ptr++;
131 while(u2->ptr < s && !(*mfile.input)[u2->ptr].sync())
132 u2->ptr++;
134 return 1;
137 int rom_loaded(lua::state& L, lua::parameters& P)
139 auto& core = CORE();
140 L.pushboolean(!core.rom->get_internal_rom_type().isnull());
141 return 1;
144 int get_rom_info(lua::state& L, lua::parameters& P)
146 auto& core = CORE();
147 auto& rom = *(core.rom);
148 bool any_loaded = false;
150 L.newtable();
151 for(unsigned i = 0; i < ROM_SLOT_COUNT; i++) {
152 auto img = &rom.get_rom(i);
153 auto xml = &rom.get_markup(i);
154 if(img->sha_256.read() == "") img = NULL; //Trivial image.
155 if(xml->sha_256.read() == "") xml = NULL; //Trivial image.
156 if(!img && !xml) continue;
157 any_loaded = true;
158 L.pushnumber(i+1);
159 L.newtable();
160 if(img) {
161 L.pushstring("filename");
162 L.pushlstring(img->filename);
163 L.rawset(-3);
164 L.pushstring("hint");
165 L.pushlstring(img->namehint);
166 L.rawset(-3);
167 L.pushstring("sha256");
168 L.pushlstring(img->sha_256.read());
169 L.rawset(-3);
171 if(xml) {
172 L.pushstring("xml_filename");
173 L.pushlstring(xml->filename);
174 L.rawset(-3);
175 L.pushstring("xml_hint");
176 L.pushlstring(xml->namehint);
177 L.rawset(-3);
178 L.pushstring("xml_sha256");
179 L.pushlstring(xml->sha_256.read());
180 L.rawset(-3);
182 L.rawset(-3);
184 if(!any_loaded) {
185 L.pop(1);
186 return 0;
188 return 1;
191 int get_game_info(lua::state& L, lua::parameters& P)
193 uint64_t framemagic[4];
194 auto& core = CORE();
195 auto& rom = core.rom->get_internal_rom_type();
196 auto& sysreg = rom.combine_region(rom.get_region());
198 sysreg.fill_framerate_magic(framemagic);
200 L.newtable();
202 L.pushstring("core");
203 L.pushlstring(rom.get_core_identifier());
204 L.rawset(-3);
205 L.pushstring("core_short");
206 L.pushlstring(rom.get_core_shortname());
207 L.rawset(-3);
208 L.pushstring("type");
209 L.pushlstring(rom.get_iname());
210 L.rawset(-3);
211 L.pushstring("type_long");
212 L.pushlstring(rom.get_hname());
213 L.rawset(-3);
214 L.pushstring("region");
215 L.pushlstring(rom.get_region().get_iname());
216 L.rawset(-3);
217 L.pushstring("region_long");
218 L.pushlstring(rom.get_region().get_hname());
219 L.rawset(-3);
220 L.pushstring("gametype");
221 L.pushlstring(sysreg.get_name());
222 L.rawset(-3);
223 L.pushstring("fps_n");
224 L.pushnumber(framemagic[1]);
225 L.rawset(-3);
226 L.pushstring("fps_d");
227 L.pushnumber(framemagic[0]);
228 L.rawset(-3);
229 L.pushstring("fps");
230 L.pushnumber(1.0 * framemagic[1] / framemagic[0]);
231 L.rawset(-3);
233 return 1;
236 lua::functions LUA_movie_fns(lua_func_misc, "movie", {
237 {"currentframe", currentframe},
238 {"lagcount", lagcounter},
239 {"framecount", framecount},
240 {"rerecords", rerecords},
241 {"readonly", readonly},
242 {"readwrite", readwrite},
243 {"frame_subframes", frame_subframes},
244 {"read_subframes", read_subframes},
245 {"read_rtc", read_rtc},
246 {"unsafe_rewind", unsafe_rewind},
247 {"to_rewind", to_rewind},
248 {"rom_loaded", rom_loaded},
249 {"get_rom_info", get_rom_info},
250 {"get_game_info", get_game_info},