1 #include "lua/internal.hpp"
2 #include "library/string.hpp"
3 #include "library/minmax.hpp"
4 #include "core/movie.hpp"
5 #include "core/moviedata.hpp"
6 #include "core/window.hpp"
9 void update_movie_state();
17 friend class lua_inputmovie
;
19 lua_inputframe(lua::state
& L
, controller_frame _f
);
20 int get_button(lua::state
& L
, lua::parameters
& P
)
22 unsigned port
, controller
, button
;
24 P(P
.skipped(), port
, controller
, button
);
26 short value
= getbutton(port
, controller
, button
);
27 L
.pushboolean(value
? 1 : 0);
30 int get_axis(lua::state
& L
, lua::parameters
& P
)
32 unsigned port
, controller
, button
;
34 P(P
.skipped(), port
, controller
, button
);
36 short value
= getbutton(port
, controller
, button
);
40 int set_axis(lua::state
& L
, lua::parameters
& P
)
42 unsigned port
, controller
, button
;
45 P(P
.skipped(), port
, controller
, button
);
46 if(P
.is_boolean()) value
= P
.arg
<bool>() ? 1 : 0;
47 else if(P
.is_number()) value
= P
.arg
<short>();
49 P
.expected("number or boolean");
51 setbutton(port
, controller
, button
, value
);
54 int serialize(lua::state
& L
, lua::parameters
& P
)
56 char buf
[MAX_SERIALIZED_SIZE
];
61 int unserialize(lua::state
& L
, lua::parameters
& P
)
67 f
.deserialize(buf
.c_str());
70 int get_stride(lua::state
& L
, lua::parameters
& P
)
72 L
.pushnumber(f
.size());
75 controller_frame
& get_frame()
81 char buf
[MAX_SERIALIZED_SIZE
];
86 short getbutton(unsigned port
, unsigned controller
, unsigned index
)
88 return f
.axis3(port
, controller
, index
);
90 void setbutton(unsigned port
, unsigned controller
, unsigned index
, short value
)
92 return f
.axis3(port
, controller
, index
, value
);
97 int32_t get_pc_for(unsigned port
, unsigned controller
, unsigned button
, bool extra0
= false);
98 int32_t get_pc_for(unsigned port
, unsigned controller
, unsigned button
, bool extra0
)
100 movie
& m
= movb
.get_movie();
101 if(port
== 0 && controller
== 0 && button
== 0)
102 return m
.get_pollcounters().max_polls() + (extra0
? 1 : 0);
103 if(port
== 0 && controller
== 0 && m
.get_pollcounters().get_framepflag())
104 return max(m
.get_pollcounters().get_polls(port
, controller
, button
), (uint32_t)1);
105 return m
.get_pollcounters().get_polls(port
, controller
, button
);
108 void check_can_edit(unsigned port
, unsigned controller
, unsigned button
, uint64_t frame
,
109 bool allow_past_end
= false);
111 void check_can_edit(unsigned port
, unsigned controller
, unsigned button
, uint64_t frame
,
114 movie
& m
= movb
.get_movie();
115 if(!m
.readonly_mode())
116 throw std::runtime_error("Not in read-only mode");
117 if(!allow_past_end
&& frame
>= movb
.get_mfile().input
->size())
118 throw std::runtime_error("Index out of movie");
119 int32_t pc
= get_pc_for(port
, controller
, button
, true);
121 throw std::runtime_error("Invalid control to edit");
122 uint64_t firstframe
= m
.get_current_frame_first_subframe();
123 uint64_t minframe
= firstframe
+ pc
;
124 uint64_t msize
= movb
.get_mfile().input
->size();
125 if(minframe
> msize
|| firstframe
>= msize
)
126 throw std::runtime_error("Can not edit finished movie");
128 throw std::runtime_error("Can not edit past");
131 int current_first_subframe(lua::state
& L
, lua::parameters
& P
)
133 movie
& m
= movb
.get_movie();
134 L
.pushnumber(m
.get_current_frame_first_subframe());
138 int pollcounter(lua::state
& L
, lua::parameters
& P
)
140 unsigned port
, controller
, button
;
142 P(port
, controller
, button
);
145 ret
= get_pc_for(port
, controller
, button
);
150 controller_frame_vector
& framevector(lua::state
& L
, lua::parameters
& P
);
152 int _copy_movie(lua::state
& L
, lua::parameters
& P
)
154 controller_frame_vector
& v
= framevector(L
, P
);
156 lua_inputmovie
* m
= lua::_class
<lua_inputmovie
>::create(L
, v
);
160 int _get_frame(lua::state
& L
, lua::parameters
& P
)
163 controller_frame_vector
& v
= framevector(L
, P
);
168 throw std::runtime_error("Requested frame outside movie");
169 controller_frame _f
= v
[n
];
170 lua_inputframe
* f
= lua::_class
<lua_inputframe
>::create(L
, _f
);
174 int _set_frame(lua::state
& L
, lua::parameters
& P
)
178 controller_frame_vector
& v
= framevector(L
, P
);
183 throw std::runtime_error("Requested frame outside movie");
184 //Checks if requested frame is from movie.
185 if(&v
== movb
.get_mfile().input
)
186 check_can_edit(0, 0, 0, n
);
188 v
[n
] = f
->get_frame();
190 if(&v
== movb
.get_mfile().input
) {
191 //This can't add frames, so no need to adjust the movie.
192 update_movie_state();
193 platform::notify_status();
198 int _get_size(lua::state
& L
, lua::parameters
& P
)
201 controller_frame_vector
& v
= framevector(L
, P
);
203 L
.pushnumber(v
.size());
207 int _count_frames(lua::state
& L
, lua::parameters
& P
)
210 controller_frame_vector
& v
= framevector(L
, P
);
212 L
.pushnumber(v
.count_frames());
216 int _find_frame(lua::state
& L
, lua::parameters
& P
)
219 controller_frame_vector
& v
= framevector(L
, P
);
228 uint64_t s
= v
.size();
229 for(uint64_t i
= 0; i
< s
; i
++)
230 if(v
[i
].sync() && ++c
== n
) {
238 int _blank_frame(lua::state
& L
, lua::parameters
& P
)
241 controller_frame_vector
& v
= framevector(L
, P
);
243 controller_frame _f
= v
.blank_frame(true);
244 lua_inputframe
* f
= lua::_class
<lua_inputframe
>::create(L
, _f
);
248 int _append_frames(lua::state
& L
, lua::parameters
& P
)
251 controller_frame_vector
& v
= framevector(L
, P
);
256 controller_frame_vector::notify_freeze
freeze(v
);
257 for(uint64_t i
= 0; i
< count
; i
++)
258 v
.append(v
.blank_frame(true));
260 if(&v
== movb
.get_mfile().input
) {
261 update_movie_state();
262 platform::notify_status();
267 int _append_frame(lua::state
& L
, lua::parameters
& P
)
270 controller_frame_vector
& v
= framevector(L
, P
);
274 v
.append(v
.blank_frame(true));
275 if(&v
== movb
.get_mfile().input
) {
276 update_movie_state();
277 platform::notify_status();
278 check_can_edit(0, 0, 0, v
.size() - 1);
280 v
[v
.size() - 1] = f
->get_frame();
281 if(&v
== movb
.get_mfile().input
) {
282 if(!v
[v
.size() - 1].sync()) {
283 update_movie_state();
285 platform::notify_status();
290 int _truncate(lua::state
& L
, lua::parameters
& P
)
293 controller_frame_vector
& v
= framevector(L
, P
);
298 throw std::runtime_error("Requested truncate length longer than existing");
299 if(&v
== movb
.get_mfile().input
)
300 check_can_edit(0, 0, 0, n
);
302 if(&v
== movb
.get_mfile().input
) {
303 update_movie_state();
304 platform::notify_status();
309 int _edit(lua::state
& L
, lua::parameters
& P
)
312 unsigned port
, controller
, button
;
314 controller_frame_vector
& v
= framevector(L
, P
);
316 P(frame
, port
, controller
, button
);
317 if(P
.is_boolean()) value
= P
.arg
<bool>() ? 1 : 0;
318 else if(P
.is_number()) P(value
);
320 P
.expected("number or boolean");
322 movie
& m
= movb
.get_movie();
323 if(&v
== movb
.get_mfile().input
)
324 check_can_edit(port
, controller
, button
, frame
);
325 v
[frame
].axis3(port
, controller
, button
, value
);
327 if(&v
== movb
.get_mfile().input
) {
328 update_movie_state();
329 platform::notify_status();
335 int _copy_frames(lua::state
& L
, lua::parameters
& P
)
337 uint64_t dst
, src
, count
;
338 bool backwards
= same
;
340 controller_frame_vector
& dstv
= framevector(L
, P
);
342 controller_frame_vector
& srcv
= same
? dstv
: framevector(L
, P
);
344 if(same
) P(backwards
);
346 if(src
>= srcv
.size() || src
+ count
< src
)
347 throw std::runtime_error("Source index out of movie");
348 if(dst
> dstv
.size() || dst
+ count
< dst
)
349 throw std::runtime_error("Destination index out of movie");
351 movie
& m
= movb
.get_movie();
352 if(&dstv
== movb
.get_mfile().input
)
353 check_can_edit(0, 0, 0, dst
, true);
356 controller_frame_vector::notify_freeze
freeze(dstv
);
357 //Add enough blank frames to make the copy.
358 while(dst
+ count
> dstv
.size())
359 dstv
.append(dstv
.blank_frame(false));
361 for(uint64_t i
= backwards
? (count
- 1) : 0; i
< count
; i
= backwards
? (i
- 1) : (i
+ 1))
362 dstv
[dst
+ i
] = srcv
[src
+ i
];
364 if(&dstv
== movb
.get_mfile().input
) {
365 update_movie_state();
366 platform::notify_status();
371 int _serialize(lua::state
& L
, lua::parameters
& P
)
373 std::string filename
;
376 controller_frame_vector
& v
= framevector(L
, P
);
380 std::ofstream
file(filename
, binary
? std::ios_base::binary
: std::ios_base::out
);
382 throw std::runtime_error("Can't open file to write output to");
384 uint64_t pages
= v
.get_page_count();
385 uint64_t stride
= v
.get_stride();
386 uint64_t pageframes
= v
.get_frames_per_page();
387 uint64_t vsize
= v
.size();
390 uint64_t count
= (vsize
> pageframes
) ? pageframes
: vsize
;
391 size_t bytes
= count
* stride
;
392 unsigned char* content
= v
.get_page_buffer(pagenum
++);
393 file
.write(reinterpret_cast<char*>(content
), bytes
);
397 char buf
[MAX_SERIALIZED_SIZE
];
398 for(uint64_t i
= 0; i
< v
.size(); i
++) {
400 file
<< buf
<< std::endl
;
409 lua_inputmovie(lua::state
& L
, const controller_frame_vector
& _v
);
410 lua_inputmovie(lua::state
& L
, controller_frame
& _f
);
411 int copy_movie(lua::state
& L
, lua::parameters
& P
)
413 return _copy_movie(L
, P
);
415 int get_frame(lua::state
& L
, lua::parameters
& P
)
417 return _get_frame(L
, P
);
419 int set_frame(lua::state
& L
, lua::parameters
& P
)
421 return _set_frame(L
, P
);
423 int get_size(lua::state
& L
, lua::parameters
& P
)
425 return _get_size(L
, P
);
427 int count_frames(lua::state
& L
, lua::parameters
& P
)
429 return _count_frames(L
, P
);
431 int find_frame(lua::state
& L
, lua::parameters
& P
)
433 return _find_frame(L
, P
);
435 int blank_frame(lua::state
& L
, lua::parameters
& P
)
437 return _blank_frame(L
, P
);
439 int append_frames(lua::state
& L
, lua::parameters
& P
)
441 return _append_frames(L
, P
);
443 int append_frame(lua::state
& L
, lua::parameters
& P
)
445 return _append_frame(L
, P
);
447 int truncate(lua::state
& L
, lua::parameters
& P
)
449 return _truncate(L
, P
);
451 int edit(lua::state
& L
, lua::parameters
& P
)
455 int copy_frames(lua::state
& L
, lua::parameters
& P
)
457 return _copy_frames
<true>(L
, P
);
459 int serialize(lua::state
& L
, lua::parameters
& P
)
461 return _serialize(L
, P
);
463 int debugdump(lua::state
& L
, lua::parameters
& P
)
465 char buf
[MAX_SERIALIZED_SIZE
];
466 for(uint64_t i
= 0; i
< v
.size(); i
++) {
468 messages
<< buf
<< std::endl
;
472 controller_frame_vector
* get_frame_vector()
479 return (stringfmt() << s
<< " " << ((s
!= 1) ? "frames" : "frame")).str();
482 void common_init(lua::state
& L
);
483 controller_frame_vector v
;
486 int copy_movie(lua::state
& L
, lua::parameters
& P
)
488 return _copy_movie(L
, P
);
491 int get_frame(lua::state
& L
, lua::parameters
& P
)
493 return _get_frame(L
, P
);
496 int set_frame(lua::state
& L
, lua::parameters
& P
)
498 return _set_frame(L
, P
);
501 int get_size(lua::state
& L
, lua::parameters
& P
)
503 return _get_size(L
, P
);
506 int count_frames(lua::state
& L
, lua::parameters
& P
)
508 return _count_frames(L
, P
);
511 int find_frame(lua::state
& L
, lua::parameters
& P
)
513 return _find_frame(L
, P
);
516 int blank_frame(lua::state
& L
, lua::parameters
& P
)
518 return _blank_frame(L
, P
);
521 int append_frames(lua::state
& L
, lua::parameters
& P
)
523 return _append_frames(L
, P
);
526 int append_frame(lua::state
& L
, lua::parameters
& P
)
528 return _append_frame(L
, P
);
531 int truncate(lua::state
& L
, lua::parameters
& P
)
533 return _truncate(L
, P
);
536 int edit(lua::state
& L
, lua::parameters
& P
)
541 int copy_frames2(lua::state
& L
, lua::parameters
& P
)
543 return _copy_frames
<false>(L
, P
);
546 int copy_frames(lua::state
& L
, lua::parameters
& P
)
548 return _copy_frames
<true>(L
, P
);
551 int serialize(lua::state
& L
, lua::parameters
& P
)
553 return _serialize(L
, P
);
556 int unserialize(lua::state
& L
, lua::parameters
& P
)
559 std::string filename
;
562 P(f
, filename
, binary
);
564 std::ifstream
file(filename
, binary
? std::ios_base::binary
: std::ios_base::in
);
566 throw std::runtime_error("Can't open file to read input from");
567 lua_inputmovie
* m
= lua::_class
<lua_inputmovie
>::create(L
, f
->get_frame());
568 controller_frame_vector
& v
= *m
->get_frame_vector();
569 controller_frame_vector::notify_freeze
freeze(v
);
571 uint64_t stride
= v
.get_stride();
572 uint64_t pageframes
= v
.get_frames_per_page();
575 size_t pagesize
= stride
* pageframes
;
577 v
.resize(vsize
+ pageframes
);
578 unsigned char* contents
= v
.get_page_buffer(pagenum
++);
579 file
.read(reinterpret_cast<char*>(contents
), pagesize
);
580 vsize
+= (file
.gcount() / stride
);
585 controller_frame tmpl
= v
.blank_frame(false);
587 std::getline(file
, line
);
589 if(line
.length() == 0)
591 tmpl
.deserialize(line
.c_str());
598 int current_branch(lua::state
& L
, lua::parameters
& P
)
600 L
.pushlstring(movb
.get_mfile().current_branch());
604 int get_branches(lua::state
& L
, lua::parameters
& P
)
606 for(auto& i
: movb
.get_mfile().branches
)
607 L
.pushlstring(i
.first
);
608 return movb
.get_mfile().branches
.size();
611 controller_frame_vector
& framevector(lua::state
& L
, lua::parameters
& P
)
615 return *movb
.get_mfile().input
;
616 } else if(P
.is_string()) {
619 if(!movb
.get_mfile().branches
.count(x
))
620 throw std::runtime_error("No such branch");
621 return movb
.get_mfile().branches
[x
];
622 } else if(P
.is
<lua_inputmovie
>())
623 return *(P
.arg
<lua_inputmovie
*>()->get_frame_vector());
625 return *movb
.get_mfile().input
;
628 lua::_class
<lua_inputmovie
> class_inputmovie(lua_class_movie
, "INPUTMOVIE", {}, {
629 {"copy_movie", &lua_inputmovie::copy_movie
},
630 {"get_frame", &lua_inputmovie::get_frame
},
631 {"set_frame", &lua_inputmovie::set_frame
},
632 {"get_size", &lua_inputmovie::get_size
},
633 {"count_frames", &lua_inputmovie::count_frames
},
634 {"find_frame", &lua_inputmovie::find_frame
},
635 {"blank_frame", &lua_inputmovie::blank_frame
},
636 {"append_frames", &lua_inputmovie::append_frames
},
637 {"append_frame", &lua_inputmovie::append_frame
},
638 {"truncate", &lua_inputmovie::truncate
},
639 {"edit", &lua_inputmovie::edit
},
640 {"debugdump", &lua_inputmovie::debugdump
},
641 {"copy_frames", &lua_inputmovie::copy_frames
},
642 {"serialize", &lua_inputmovie::serialize
},
643 }, &lua_inputmovie::print
);
645 lua::_class
<lua_inputframe
> class_inputframe(lua_class_movie
, "INPUTFRAME", {}, {
646 {"get_button", &lua_inputframe::get_button
},
647 {"get_axis", &lua_inputframe::get_axis
},
648 {"set_axis", &lua_inputframe::set_axis
},
649 {"set_button", &lua_inputframe::set_axis
},
650 {"serialize", &lua_inputframe::serialize
},
651 {"unserialize", &lua_inputframe::unserialize
},
652 {"get_stride", &lua_inputframe::get_stride
},
653 }, &lua_inputframe::print
);
655 lua::functions
inputmovie_fns(lua_func_misc
, "movie", {
656 {"current_first_subframe", current_first_subframe
},
657 {"pollcounter", pollcounter
},
658 {"copy_movie", copy_movie
},
659 {"get_frame", get_frame
},
660 {"set_frame", set_frame
},
661 {"get_size", get_size
},
662 {"count_frames", count_frames
},
663 {"find_frame", find_frame
},
664 {"blank_frame", blank_frame
},
665 {"append_frames", append_frames
},
666 {"append_frame", append_frame
},
667 {"truncate", truncate
},
669 {"copy_frames2", copy_frames2
},
670 {"copy_frames", copy_frames
},
671 {"serialize", serialize
},
672 {"unserialize", unserialize
},
673 {"current_branch", current_branch
},
674 {"get_branches", get_branches
},
677 lua_inputframe::lua_inputframe(lua::state
& L
, controller_frame _f
)
682 void lua_inputmovie::common_init(lua::state
& L
)
686 lua_inputmovie::lua_inputmovie(lua::state
& L
, const controller_frame_vector
& _v
)
692 lua_inputmovie::lua_inputmovie(lua::state
& L
, controller_frame
& f
)
694 v
.clear(f
.porttypes());