Lua: Fix type confusion between signed and unsigned
[lsnes.git] / include / library / portctrl-data.hpp
blob9eea48918a8057d8349aeb1da231598fe1eac904
1 #ifndef _library__portctrl_data__hpp__included__
2 #define _library__portctrl_data__hpp__included__
4 #include <cstring>
5 #include <climits>
6 #include <cstdio>
7 #include <cstdlib>
8 #include <cstdio>
9 #include <cstdint>
10 #include <sstream>
11 #include <iomanip>
12 #include <iostream>
13 #include <stdexcept>
14 #include <string>
15 #include <vector>
16 #include <map>
17 #include <list>
18 #include <set>
19 #include "json.hpp"
20 #include "threads.hpp"
21 #include "memtracker.hpp"
23 namespace binarystream
25 class input;
26 class output;
29 /**
30 * Memory to allocate for controller frame.
32 #define MAXIMUM_CONTROLLER_FRAME_SIZE 128
33 /**
34 * Maximum amount of data frame::display() can write.
36 #define MAX_DISPLAY_LENGTH 128
37 /**
38 * Maximum amount of data frame::serialize() can write.
40 #define MAX_SERIALIZED_SIZE 256
41 /**
42 * Size of controller page.
44 #define CONTROLLER_PAGE_SIZE 65500
45 /**
46 * Special return value for deserialize() indicating no input was taken.
48 #define DESERIALIZE_SPECIAL_BLANK 0xFFFFFFFFUL
50 namespace portctrl
52 extern const char* movie_page_id;
53 /**
54 * Is not field terminator.
56 * Parameter ch: The character.
57 * Returns: True if character is not terminator, false if character is terminator.
59 inline bool is_nonterminator(char ch) throw()
61 return (ch != '|' && ch != '\r' && ch != '\n' && ch != '\0');
64 /**
65 * Read button value.
67 * Parameter buf: Buffer to read from.
68 * Parameter idx: Index to buffer. Updated.
69 * Returns: The read value.
71 inline bool read_button_value(const char* buf, size_t& idx) throw()
73 char ch = buf[idx];
74 if(is_nonterminator(ch))
75 idx++;
76 return (ch != '|' && ch != '\r' && ch != '\n' && ch != '\0' && ch != '.' && ch != ' ' && ch != '\t');
79 /**
80 * Read axis value.
82 * Parameter buf: Buffer to read from.
83 * Parameter idx: Index to buffer. Updated.
84 * Returns: The read value.
86 short read_axis_value(const char* buf, size_t& idx) throw();
88 /**
89 * Write axis value.
91 * Parameter buf: The buffer to write to.
92 * Parameter _v: The axis value.
93 * Returns: Number of bytes written.
95 size_t write_axis_value(char* buf, short _v);
98 /**
99 * Skip whitespace.
101 * Parameter buf: Buffer to read from.
102 * Parameter idx: Index to buffer. Updated.
104 inline void skip_field_whitespace(const char* buf, size_t& idx) throw()
106 while(buf[idx] == ' ' || buf[idx] == '\t')
107 idx++;
111 * Skip rest of the field.
113 * Parameter buf: Buffer to read from.
114 * Parameter idx: Index to buffer. Updated.
115 * Parameter include_pipe: If true, also skip the '|'.
117 inline void skip_rest_of_field(const char* buf, size_t& idx, bool include_pipe) throw()
119 while(is_nonterminator(buf[idx]))
120 idx++;
121 if(include_pipe && buf[idx] == '|')
122 idx++;
126 * Serialize short.
128 inline void serialize_short(unsigned char* buf, short val)
130 buf[0] = static_cast<unsigned short>(val) >> 8;
131 buf[1] = static_cast<unsigned short>(val);
135 * Serialize short.
137 inline short unserialize_short(const unsigned char* buf)
139 return static_cast<short>((static_cast<unsigned short>(buf[0]) << 8) | static_cast<unsigned short>(buf[1]));
142 class type;
145 * Index triple.
147 * Note: The index 0 has to be mapped to triple (0, 0, 0).
149 struct index_triple
152 * If true, the other parameters are valid. Otherwise this index doesn't correspond to anything valid, but still
153 * exists. The reason for having invalid entries is to be backward-compatible.
155 bool valid;
157 * The port number.
159 unsigned port;
161 * The controller number.
163 unsigned controller;
165 * The control number.
167 unsigned control;
171 * Controller index mappings
173 struct index_map
176 * The poll indices.
178 std::vector<index_triple> indices;
180 * The logical controller mappings.
182 std::vector<std::pair<unsigned, unsigned>> logical_map;
184 * Legacy PCID mappings.
186 std::vector<std::pair<unsigned, unsigned>> pcid_map;
190 class type_set;
193 * A button or axis on controller
195 struct button
198 * Type of button
200 enum _type
202 TYPE_NULL, //Nothing (except takes the slot).
203 TYPE_BUTTON, //Button.
204 TYPE_AXIS, //Axis.
205 TYPE_RAXIS, //Relative Axis (mouse).
206 TYPE_TAXIS, //Throttle Axis (does not pair).
207 TYPE_LIGHTGUN, //Lightgun axis.
209 enum _type type;
210 char32_t symbol;
211 std::string name;
212 bool shadow;
213 int16_t rmin; //Range min.
214 int16_t rmax; //Range max.
215 bool centers;
216 std::string macro; //Name in macro (must be prefix-free).
217 char msymbol; //Symbol in movie.
219 * Is analog?
221 bool is_analog() const throw() { return type == (TYPE_AXIS) || (type == TYPE_RAXIS) || (type == TYPE_TAXIS)
222 || (type == TYPE_LIGHTGUN); }
226 * A controller.
228 struct controller
230 std::string cclass; //Controller class.
231 std::string type; //Controller type.
232 std::vector<button> buttons; //Buttons.
234 * Count number of analog actions on this controller.
236 unsigned analog_actions() const;
238 * Get the axis numbers of specified analog action. If no valid axis exists, returns UINT_MAX.
240 std::pair<unsigned, unsigned> analog_action(unsigned i) const;
242 * Get specified button, or NULL if it doesn't exist.
244 struct button* get(unsigned i)
246 if(i >= buttons.size())
247 return NULL;
248 return &buttons[i];
253 * A port controller set
255 struct controller_set
257 std::string iname;
258 std::string hname;
259 std::string symbol;
260 std::vector<controller> controllers; //Controllers.
261 std::set<unsigned> legal_for; //Ports this is legal for
263 * Get specified controller, or NULL if it doesn't exist.
265 struct controller* get(unsigned c) throw()
267 if(c >= controllers.size())
268 return NULL;
269 return &controllers[c];
272 * Get specified button, or NULL if it doesn't exist.
274 struct button* get(unsigned c, unsigned i) throw();
278 * Type of controller.
280 class type
282 public:
284 * Create a new port type.
286 * Parameter iname: Internal name of the port type.
287 * Parameter hname: Human-readable name of the port type.
288 * Parameter ssize: The storage size in bytes.
289 * Throws std::bad_alloc: Not enough memory.
291 type(const std::string& iname, const std::string& hname, size_t ssize) throw(std::bad_alloc);
293 * Unregister a port type.
295 virtual ~type() throw();
297 * Writes controller data into compressed representation.
299 * Parameter buffer: The buffer storing compressed representation of controller state.
300 * Parameter idx: Index of controller.
301 * Parameter ctrl: The control to manipulate.
302 * Parameter x: New value for control. Only zero/nonzero matters for buttons.
304 void (*write)(const type* _this, unsigned char* buffer, unsigned idx, unsigned ctrl, short x);
306 * Read controller data from compressed representation.
308 * Parameter buffer: The buffer storing compressed representation of controller state.
309 * Parameter idx: Index of controller.
310 * Parameter ctrl: The control to query.
311 * Returns: The value of control. Buttons return 0 or 1.
313 short (*read)(const type* _this, const unsigned char* buffer, unsigned idx, unsigned ctrl);
315 * Take compressed controller data and serialize it into textual representation.
317 * - The initial '|' is also written.
319 * Parameter buffer: The buffer storing compressed representation of controller state.
320 * Parameter textbuf: The text buffer to write to.
321 * Returns: Number of bytes written.
323 size_t (*serialize)(const type* _this, const unsigned char* buffer, char* textbuf);
325 * Unserialize textual representation into compressed controller state.
327 * - Only stops reading on '|', NUL, CR or LF in the final read field. That byte is not read.
329 * Parameter buffer: The buffer storing compressed representation of controller state.
330 * Parameter textbuf: The text buffer to read.
331 * Returns: Number of bytes read.
332 * Throws std::runtime_error: Bad serialization.
334 size_t (*deserialize)(const type* _this, unsigned char* buffer, const char* textbuf);
336 * Is the device legal for port?
338 * Parameter port: Port to query.
339 * Returns: Nonzero if legal, zero if illegal.
341 int legal(unsigned port)
343 return controller_info->legal_for.count(port) ? 1 : 0;
346 * Controller info.
348 controller_set* controller_info;
350 * Get number of used control indices on controller.
352 * Parameter controller: Number of controller.
353 * Returns: Number of used control indices.
355 unsigned used_indices(unsigned controller)
357 auto c = controller_info->get(controller);
358 return c ? c->buttons.size() : 0;
361 * Human-readable name.
363 std::string hname;
365 * Number of bytes it takes to store this.
367 size_t storage_size;
369 * Name of port type.
371 std::string name;
373 * Is given controller present?
375 bool is_present(unsigned controller) const throw();
376 private:
377 type(const type&);
378 type& operator=(const type&);
382 * A set of port types.
384 class type_set
386 public:
388 * Create empty port type set.
390 type_set() throw();
392 * Make a port type set with specified types. If called again with the same parameters, returns the same object.
394 * Parameter types: The types.
395 * Parameter control_map: The control map
396 * Throws std::bad_alloc: Not enough memory.
397 * Throws std::runtime_error: Illegal port types.
399 static type_set& make(std::vector<type*> types, struct index_map control_map)
400 throw(std::bad_alloc, std::runtime_error);
402 * Compare sets for equality.
404 bool operator==(const type_set& s) const throw() { return this == &s; }
406 * Compare sets for non-equality.
408 bool operator!=(const type_set& s) const throw() { return this != &s; }
410 * Get offset of specified port.
412 * Parameter port: The number of port.
413 * Returns: The offset of port.
414 * Throws std::runtime_error: Bad port number.
416 size_t port_offset(unsigned port) const throw(std::runtime_error)
418 if(port >= port_count)
419 throw std::runtime_error("Invalid port index");
420 return port_offsets[port];
423 * Get type of specified port.
425 * Parameter port: The number of port.
426 * Returns: The port type.
427 * Throws std::runtime_error: Bad port number.
429 const class type& port_type(unsigned port) const throw(std::runtime_error)
431 if(port >= port_count)
432 throw std::runtime_error("Invalid port index");
433 return *(port_types[port]);
436 * Get number of ports.
438 * Returns: The port count.
440 unsigned ports() const throw()
442 return port_count;
445 * Get total size of controller data.
447 * Returns the size.
449 unsigned size() const throw()
451 return total_size;
454 * Get total index count.
456 unsigned indices() const throw()
458 return _indices.size();
461 * Look up the triplet for given control.
463 * Parameter index: The index to look up.
464 * Returns: The triplet (may not be valid).
465 * Throws std::runtime_error: Index out of range.
467 index_triple index_to_triple(unsigned index) const throw(std::runtime_error)
469 if(index >= _indices.size())
470 throw std::runtime_error("Invalid index");
471 return _indices[index];
474 * Translate triplet into index.
476 * Parameter port: The port.
477 * Parameter controller: The controller.
478 * Parameter _index: The control index.
479 * Returns: The index, or 0xFFFFFFFFUL if specified triple is not valid.
481 unsigned triple_to_index(unsigned port, unsigned controller, unsigned _index) const throw(std::runtime_error)
483 size_t place = port * port_multiplier + controller * controller_multiplier + _index;
484 if(place >= indices_size)
485 return 0xFFFFFFFFUL;
486 unsigned pindex = indices_tab[place];
487 if(pindex == 0xFFFFFFFFUL)
488 return 0xFFFFFFFFUL;
489 const struct index_triple& t = _indices[pindex];
490 if(!t.valid || t.port != port || t.controller != controller || t.control != _index)
491 return 0xFFFFFFFFUL;
492 return pindex;
495 * Return number of controllers connected.
497 * Returns: Number of controllers.
499 unsigned number_of_controllers() const throw()
501 return controllers.size();
504 * Lookup physical controller index corresponding to logical one.
506 * Parameter lcid: Logical controller id.
507 * Returns: Physical controller index (port, controller).
508 * Throws std::runtime_error: No such controller.
510 std::pair<unsigned, unsigned> lcid_to_pcid(unsigned lcid) const throw(std::runtime_error)
512 if(lcid >= controllers.size())
513 throw std::runtime_error("Bad logical controller");
514 return controllers[lcid];
517 * Return number of legacy PCIDs.
519 unsigned number_of_legacy_pcids() const throw()
521 return legacy_pcids.size();
524 * Lookup (port,controller) pair corresponding to given legacy pcid.
526 * Parameter pcid: The legacy pcid.
527 * Returns: The controller index.
528 * Throws std::runtime_error: No such controller.
530 std::pair<unsigned, unsigned> legacy_pcid_to_pair(unsigned pcid) const throw(std::runtime_error)
532 if(pcid >= legacy_pcids.size())
533 throw std::runtime_error("Bad legacy PCID");
534 return legacy_pcids[pcid];
536 private:
537 type_set(std::vector<class type*> types, struct index_map control_map);
538 size_t* port_offsets;
539 class type** port_types;
540 unsigned port_count;
541 size_t total_size;
542 std::vector<index_triple> _indices;
543 std::vector<std::pair<unsigned, unsigned>> controllers;
544 std::vector<std::pair<unsigned, unsigned>> legacy_pcids;
546 size_t port_multiplier;
547 size_t controller_multiplier;
548 size_t indices_size;
549 unsigned* indices_tab;
553 * Poll counter vector.
555 class counters
557 public:
559 * Create new pollcounter vector filled with all zeroes and all DRDY bits clear.
561 * Throws std::bad_alloc: Not enough memory.
563 counters() throw(std::bad_alloc);
565 * Create new pollcounter vector suitably sized for given type set.
567 * Parameter p: The port types.
568 * Throws std::bad_alloc: Not enough memory.
570 counters(const type_set& p) throw(std::bad_alloc);
572 * Destructor.
574 ~counters() throw();
576 * Copy the counters.
578 counters(const counters& v) throw(std::bad_alloc);
580 * Assign the counters.
582 counters& operator=(const counters& v) throw(std::bad_alloc);
584 * Zero all poll counters and clear all DRDY bits. System flag is cleared.
586 void clear() throw();
588 * Set all DRDY bits.
590 void set_all_DRDY() throw();
592 * Clear specified DRDY bit.
594 * Parameter port: The port.
595 * Parameter controller: The controller
596 * Parameter ctrl: The control id.
598 void clear_DRDY(unsigned port, unsigned controller, unsigned ctrl) throw()
600 unsigned i = types->triple_to_index(port, controller, ctrl);
601 if(i != 0xFFFFFFFFU)
602 clear_DRDY(i);
605 * Clear state of DRDY bit.
607 * Parameter idx: The control index.
609 void clear_DRDY(unsigned idx) throw();
611 * Get state of DRDY bit.
613 * Parameter port: The port.
614 * Parameter controller: The controller
615 * Parameter ctrl: The control id.
616 * Returns: The DRDY state.
618 bool get_DRDY(unsigned port, unsigned controller, unsigned ctrl) throw()
620 unsigned i = types->triple_to_index(port, controller, ctrl);
621 if(i != 0xFFFFFFFFU)
622 return get_DRDY(i);
623 else
624 return true;
627 * Get state of DRDY bit.
629 * Parameter idx: The control index.
630 * Returns: The DRDY state.
632 bool get_DRDY(unsigned idx) throw();
634 * Is any poll count nonzero or is system flag set?
636 * Returns: True if at least one poll count is nonzero or if system flag is set. False otherwise.
638 bool has_polled() throw();
640 * Read the actual poll count on specified control.
642 * Parameter port: The port.
643 * Parameter controller: The controller
644 * Parameter ctrl: The control id.
645 * Return: The poll count.
647 uint32_t get_polls(unsigned port, unsigned controller, unsigned ctrl) throw()
649 unsigned i = types->triple_to_index(port, controller, ctrl);
650 if(i != 0xFFFFFFFFU)
651 return get_polls(i);
652 else
653 return 0;
656 * Read the actual poll count on specified control.
658 * Parameter idx: The control index.
659 * Return: The poll count.
661 uint32_t get_polls(unsigned idx) throw();
663 * Increment poll count on specified control.
665 * Parameter port: The port.
666 * Parameter controller: The controller
667 * Parameter ctrl: The control id.
668 * Return: The poll count pre-increment.
670 uint32_t increment_polls(unsigned port, unsigned controller, unsigned ctrl) throw()
672 unsigned i = types->triple_to_index(port, controller, ctrl);
673 if(i != 0xFFFFFFFFU)
674 return increment_polls(i);
675 else
676 return 0;
679 * Increment poll count on specified index.
681 * Parameter idx: The index.
682 * Return: The poll count pre-increment.
684 uint32_t increment_polls(unsigned idx) throw();
686 * Get highest poll counter value.
688 * - System flag counts as 1 poll.
690 * Returns: The maximum poll count (at least 1 if system flag is set).
692 uint32_t max_polls() throw();
694 * Save state to memory block.
696 * Parameter mem: The memory block to save to.
697 * Throws std::bad_alloc: Not enough memory.
699 void save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc);
701 * Load state from memory block.
703 * Parameter mem: The block from restore from.
705 void load_state(const std::vector<uint32_t>& mem) throw();
707 * Check if state can be loaded without errors.
709 * Returns: True if load is possible, false otherwise.
711 bool check(const std::vector<uint32_t>& mem) throw();
713 * Set/Clear the frame parameters polled flag.
715 void set_framepflag(bool value) throw();
717 * Get the frame parameters polled flag.
719 bool get_framepflag() const throw();
721 * Get raw pollcounter data.
723 const uint32_t* rawdata() const throw() { return ctrs; }
724 private:
725 uint32_t* ctrs;
726 const type_set* types;
727 bool framepflag;
730 class frame_vector;
733 * Single (sub)frame of controls.
735 class frame
737 public:
739 * Default constructor. Invalid port types, dedicated memory.
741 frame() throw();
743 * Create subframe of controls with specified controller types and dedicated memory.
745 * Parameter p: Types of ports.
747 frame(const type_set& p) throw(std::runtime_error);
749 * Create subframe of controls with specified controller types and specified memory.
751 * Parameter memory: The backing memory.
752 * Parameter p: Types of ports.
753 * Parameter host: Host frame vector.
755 * Throws std::runtime_error: NULL memory.
757 frame(unsigned char* memory, const type_set& p, frame_vector* host = NULL)
758 throw(std::runtime_error);
760 * Copy construct a frame. The memory will be dedicated.
762 * Parameter obj: The object to copy.
764 frame(const frame& obj) throw();
766 * Assign a frame. The types must either match or memory must be dedicated.
768 * Parameter obj: The object to copy.
769 * Returns: Reference to this.
770 * Throws std::runtime_error: The types don't match and memory is not dedicated.
772 frame& operator=(const frame& obj) throw(std::runtime_error);
774 * Get type of port.
776 * Parameter port: Number of port.
777 * Returns: The type of port.
779 const type& get_port_type(unsigned port) throw()
781 return types->port_type(port);
784 * Get port count.
786 unsigned get_port_count() throw()
788 return types->ports();
791 * Get index count.
793 unsigned get_index_count() throw()
795 return types->indices();
798 * Set types of ports.
800 * Parameter ptype: New port types.
801 * Throws std::runtime_error: Memory is mapped.
803 void set_types(const type_set& ptype) throw(std::runtime_error)
805 if(memory != backing)
806 throw std::runtime_error("Can't change type of mapped frame");
807 types = &ptype;
810 * Get blank dedicated frame of same port types.
812 * Return blank frame.
814 frame blank_frame() throw()
816 return frame(*types);
819 * Check that types match.
821 * Parameter obj: Another object.
822 * Returns: True if types match, false otherwise.
824 bool types_match(const frame& obj) const throw()
826 return types == obj.types;
829 * Perform XOR between controller frames.
831 * Parameter another: The another object.
832 * Returns: The XOR result (dedicated memory).
833 * Throws std::runtime_error: Type mismatch.
835 frame operator^(const frame& another) throw(std::runtime_error)
837 frame x(*this);
838 if(types != another.types)
839 throw std::runtime_error("frame::operator^: Type mismatch");
840 for(size_t i = 0; i < types->size(); i++)
841 x.backing[i] ^= another.backing[i];
842 return x;
845 * Set the sync flag.
847 * Parameter x: The value to set the sync flag to.
849 inline void sync(bool x) throw();
851 * Get the sync flag.
853 * Return value: Value of sync flag.
855 bool sync() throw()
857 return ((backing[0] & 1) != 0);
860 * Quick get sync flag for buffer.
862 static bool sync(const unsigned char* mem) throw()
864 return ((mem[0] & 1) != 0);
867 * Get size of frame.
869 * Returns: The number of bytes it takes to store frame of this type.
871 size_t size()
873 return types->size();
876 * Set axis/button value.
878 * Parameter port: The port.
879 * Parameter controller: The controller
880 * Parameter ctrl: The control id.
881 * Parameter x: The new value.
883 void axis3(unsigned port, unsigned controller, unsigned ctrl, short x) throw()
885 if(port >= types->ports())
886 return;
887 auto& t = types->port_type(port);
888 if(!port && !controller && !ctrl && host)
889 sync(x != 0);
890 else
891 t.write(&t, backing + types->port_offset(port), controller, ctrl, x);
894 * Set axis/button value.
896 * Parameter idx: Control index.
897 * Parameter x: The new value.
899 void axis2(unsigned idx, short x) throw()
901 index_triple t = types->index_to_triple(idx);
902 if(t.valid)
903 axis3(t.port, t.controller, t.control, x);
906 * Get axis/button value.
908 * Parameter port: The port.
909 * Parameter controller: The controller
910 * Parameter ctrl: The control id.
911 * Return value: The axis value.
913 short axis3(unsigned port, unsigned controller, unsigned ctrl) throw()
915 if(port >= types->ports())
916 return 0;
917 auto& t = types->port_type(port);
918 return t.read(&t, backing + types->port_offset(port), controller, ctrl);
922 * Get axis/button value.
924 * Parameter idx: Index of control.
925 * Return value: The axis value.
927 short axis2(unsigned idx) throw()
929 index_triple t = types->index_to_triple(idx);
930 if(t.valid)
931 return axis3(t.port, t.controller, t.control);
932 else
933 return 0;
936 * Get controller display.
938 * Parameter port: The port.
939 * Parameter controller: The controller
940 * Parameter buf: Buffer to write nul-terminated display to.
942 void display(unsigned port, unsigned controller, char32_t* buf) throw();
944 * Is device present?
946 * Parameter port: The port.
947 * Parameter controller: The controller
948 * Returns: True if present, false if not.
950 bool is_present(unsigned port, unsigned controller) throw()
952 if(port >= types->ports())
953 return false;
954 return types->port_type(port).is_present(controller);
957 * Deserialize frame from text format.
959 * Parameter buf: The buffer containing text representation. Terminated by NUL, CR or LF.
960 * Throws std::runtime_error: Bad serialized representation.
962 inline void deserialize(const char* buf) throw(std::runtime_error);
964 * Serialize frame to text format.
966 * Parameter buf: The buffer to write NUL-terminated text representation to.
968 void serialize(char* buf) throw()
970 size_t offset = 0;
971 for(size_t i = 0; i < types->ports(); i++) {
972 auto& t = types->port_type(i);
973 offset += t.serialize(&t, backing + types->port_offset(i), buf + offset);
975 buf[offset++] = '\0';
978 * Return copy with dedicated memory.
980 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
981 * Returns: Copy of this frame.
983 frame copy(bool sync)
985 frame c(*this);
986 c.sync(sync);
987 return c;
990 * Compare two frames.
992 * Parameter obj: Another frame.
993 * Returns: True if equal, false if not.
995 bool operator==(const frame& obj) const throw()
997 if(!types_match(obj))
998 return false;
999 return !memcmp(backing, obj.backing, types->size());
1002 * Compare two frames.
1004 * Parameter obj: Another frame.
1005 * Returns: True if not equal, false if equal.
1007 bool operator!=(const frame& obj) const throw()
1009 return !(*this == obj);
1012 * Get the port type set.
1014 const type_set& porttypes()
1016 return *types;
1018 private:
1019 unsigned char memory[MAXIMUM_CONTROLLER_FRAME_SIZE];
1020 unsigned char* backing;
1021 frame_vector* host;
1022 const type_set* types;
1026 * Vector of controller frames.
1028 class frame_vector
1030 public:
1032 * Framecount change listener.
1034 class fchange_listener
1036 public:
1038 * Destructor.
1040 virtual ~fchange_listener();
1042 * Notify a change.
1044 virtual void notify(frame_vector& src, uint64_t old) = 0;
1047 * Construct new controller frame vector.
1049 frame_vector() throw();
1051 * Construct new controller frame vector.
1053 * Parameter p: The port types.
1055 frame_vector(const type_set& p) throw();
1057 * Destroy controller frame vector
1059 ~frame_vector() throw();
1061 * Copy controller frame vector.
1063 * Parameter obj: The object to copy.
1064 * Throws std::bad_alloc: Not enough memory.
1066 frame_vector(const frame_vector& vector) throw(std::bad_alloc);
1068 * Assign controller frame vector.
1070 * Parameter obj: The object to copy.
1071 * Returns: Reference to this.
1072 * Throws std::bad_alloc: Not enough memory.
1074 frame_vector& operator=(const frame_vector& vector) throw(std::bad_alloc);
1076 * Blank vector and change the type of ports.
1078 * Parameter p: The port types.
1080 void clear(const type_set& p) throw(std::runtime_error);
1082 * Blank vector.
1084 void clear() throw()
1086 clear(*types);
1089 * Get number of subframes.
1091 size_t size() const
1093 return frames;
1096 * Get the typeset.
1098 const type_set& get_types()
1100 return *types;
1103 * Access specified subframe.
1105 * Parameter x: The frame number.
1106 * Returns: The controller frame.
1107 * Throws std::runtime_error: Invalid frame index.
1109 frame operator[](size_t x)
1111 size_t page = x / frames_per_page;
1112 size_t pageoffset = frame_size * (x % frames_per_page);
1113 if(x >= frames)
1114 throw std::runtime_error("frame_vector::operator[]: Illegal index");
1115 if(page != cache_page_num) {
1116 cache_page = &pages[page];
1117 cache_page_num = page;
1119 return frame(cache_page->content + pageoffset, *types, this);
1122 * Append a subframe.
1124 * Parameter frame: The frame to append.
1125 * Throws std::bad_alloc: Not enough memory.
1126 * Throws std::runtime_error: Port type mismatch.
1128 void append(frame frame) throw(std::bad_alloc, std::runtime_error);
1130 * Change length of vector.
1132 * - Reducing length of vector will discard extra elements.
1133 * - Extending length of vector will add all-zero elements.
1135 * Parameter newsize: New size of vector.
1136 * Throws std::bad_alloc: Not enough memory.
1138 void resize(size_t newsize) throw(std::bad_alloc);
1140 * Walk the indexes of sync subframes.
1142 * - If frame is in range and there is at least one more sync subframe after it, the index of first sync subframe
1143 * after given frame.
1144 * - If frame is in range, but there are no more sync subframes after it, the length of vector is returned.
1145 * - If frame is out of range, the given frame is returned.
1147 * Parameter frame: The frame number to start search from.
1148 * Returns: Index of next sync frame.
1150 size_t walk_sync(size_t frame) throw()
1152 return walk_helper(frame, true);
1155 * Get number of subframes in frame. The given subframe is assumed to be sync subframe.
1157 * - The return value is the same as (walk_sync(frame) - frame).
1159 * Parameter frame: The frame number to start search from.
1160 * Returns: Number of subframes in this frame.
1162 size_t subframe_count(size_t frame) throw()
1164 return walk_helper(frame, false);
1167 * Count number of subframes in vector with sync flag set.
1169 * Returns: The number of frames.
1171 size_t count_frames() throw() { return real_frame_count; }
1173 * Recount number of frames.
1175 * This is to be used after direct editing of pointers obtained by get_page_buffer().
1177 * Returns: The number of frames.
1179 size_t recount_frames() throw();
1181 * Return blank controller frame with correct type and dedicated memory.
1183 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
1184 * Returns: Blank frame.
1186 frame blank_frame(bool sync)
1188 frame c(*types);
1189 c.sync(sync);
1190 return c;
1193 * Return number of pages in movie.
1195 size_t get_page_count() const { return pages.size(); }
1197 * Return the stride.
1199 size_t get_stride() const { return frame_size; }
1201 * Return number of frames per page.
1203 size_t get_frames_per_page() const { return frames_per_page; }
1205 * Get content of given page.
1207 unsigned char* get_page_buffer(size_t page) { return pages[page].content; }
1209 * Get content of given page.
1211 const unsigned char* get_page_buffer(size_t page) const { return pages.find(page)->second.content; }
1213 * Get binary save size.
1215 * Returns: The number of bytes for binary save.
1217 uint64_t binary_size() const throw();
1219 * Save in binary form.
1221 * Parameter stream: The stream to save to.
1222 * Throws std::runtime_error: Error saving.
1224 void save_binary(binarystream::output& stream) const throw(std::runtime_error);
1226 * Load from binary form. May partially overwrite on failure.
1228 * Parameter stream: The stream to load from.
1229 * Throws std::bad_alloc: Not enough memory.
1230 * Throws std::runtime_error: Error saving.
1232 void load_binary(binarystream::input& stream) throw(std::bad_alloc, std::runtime_error);
1234 * Check that the movies are compatible up to a point.
1236 * Parameter with: The 2nd frame vector to check.
1237 * Parameter frame: The frame number (1-based) to check to.
1238 * Parameter polls: The poll counters within frame to check to.
1239 * Returns: True if compatible, false if not.
1241 bool compatible(frame_vector& with, uint64_t frame, const uint32_t* polls);
1243 * Find subframe number corresponding to given frame (1-based).
1245 int64_t find_frame(uint64_t n);
1247 * Find frame number corresponding to given subframe (0-based).
1249 int64_t subframe_to_frame(uint64_t n);
1251 * Notify sync flag polarity change.
1253 * Parameter polarity: 1 if positive edge, -1 if negative edge. 0 is ignored.
1255 void notify_sync_change(short polarity) {
1256 uint64_t old_frame_count = real_frame_count;
1257 real_frame_count = real_frame_count + polarity;
1258 if(!freeze_count) call_framecount_notification(old_frame_count);
1261 * Set where to deliver frame count change notifications to.
1263 * Parameter cb: Callback to register.
1264 * Returns: Handle for callback.
1266 void set_framecount_notification(fchange_listener& cb)
1268 threads::alock h(mlock);
1269 on_framecount_change.insert(&cb);
1272 * Clear framecount change notification.
1274 * Parameter handle: Handle to clear.
1276 void clear_framecount_notification(fchange_listener& cb)
1278 threads::alock h(mlock);
1279 on_framecount_change.erase(&cb);
1282 * Call framecount change notification.
1284 void call_framecount_notification(uint64_t oldcount)
1286 std::set<fchange_listener*> tmp;
1288 threads::alock h(mlock);
1289 tmp = on_framecount_change;
1291 for(auto i : tmp)
1292 try { i->notify(*this, oldcount); } catch(...) {}
1295 * Swap frame data.
1297 * Only the frame data is swapped, not the notifications.
1299 void swap_data(frame_vector& v) throw();
1302 * Freeze framecount notifications.
1304 struct notify_freeze
1306 notify_freeze(frame_vector& parent)
1307 : frozen(parent)
1309 frozen.freeze_count++;
1310 if(frozen.freeze_count == 1)
1311 frozen.frame_count_at_freeze = frozen.real_frame_count;
1313 ~notify_freeze()
1315 frozen.freeze_count--;
1316 if(frozen.freeze_count == 0)
1317 frozen.call_framecount_notification(frozen.frame_count_at_freeze);
1319 private:
1320 notify_freeze(const notify_freeze&);
1321 notify_freeze& operator=(const notify_freeze&);
1322 frame_vector& frozen;
1324 private:
1325 friend class notify_freeze;
1326 class page
1328 public:
1329 page() {
1330 memtracker::singleton()(movie_page_id, CONTROLLER_PAGE_SIZE + 36);
1331 memset(content, 0, CONTROLLER_PAGE_SIZE);
1333 ~page() { memtracker::singleton()(movie_page_id, -CONTROLLER_PAGE_SIZE - 36); }
1334 unsigned char content[CONTROLLER_PAGE_SIZE];
1336 size_t frames_per_page;
1337 size_t frame_size;
1338 size_t frames;
1339 const type_set* types;
1340 size_t cache_page_num;
1341 page* cache_page;
1342 std::map<size_t, page> pages;
1343 uint64_t real_frame_count;
1344 uint64_t frame_count_at_freeze;
1345 size_t freeze_count;
1346 std::set<fchange_listener*> on_framecount_change;
1347 size_t walk_helper(size_t frame, bool sflag) throw();
1348 threads::lock mlock;
1349 void clear_cache()
1351 cache_page_num = 0;
1352 cache_page_num--;
1353 cache_page = NULL;
1355 memtracker::autorelease tracker;
1358 void frame::sync(bool x) throw()
1360 short old = (backing[0] & 1);
1361 if(x)
1362 backing[0] |= 1;
1363 else
1364 backing[0] &= ~1;
1365 if(host) host->notify_sync_change((backing[0] & 1) - old);
1368 void frame::deserialize(const char* buf) throw(std::runtime_error)
1370 short old = sync();
1371 size_t offset = 0;
1372 for(size_t i = 0; i < types->ports(); i++) {
1373 size_t s;
1374 auto& t = types->port_type(i);
1375 s = t.deserialize(&t, backing + types->port_offset(i), buf + offset);
1376 if(s != DESERIALIZE_SPECIAL_BLANK) {
1377 offset += s;
1378 while(is_nonterminator(buf[offset]))
1379 offset++;
1380 if(buf[offset] == '|')
1381 offset++;
1384 if(host) host->notify_sync_change(sync() - old);
1388 //Parse a controller macro.
1389 struct macro_data
1391 struct axis_transform
1393 axis_transform() { coeffs[0] = coeffs[3] = 1; coeffs[1] = coeffs[2] = coeffs[4] = coeffs[5] = 0; }
1394 axis_transform(const std::string& expr);
1395 double coeffs[6];
1396 int16_t transform(const button& b, int16_t v);
1397 std::pair<int16_t, int16_t> transform(const button& b1,
1398 const button& b2, int16_t v1, int16_t v2);
1399 static double unscale_axis(const button& b, int16_t v);
1400 static int16_t scale_axis(const button& b, double v);
1402 enum apply_mode
1404 AM_OVERWRITE,
1405 AM_OR,
1406 AM_XOR
1408 macro_data() { buttons = 0; }
1409 macro_data(const std::string& spec, const JSON::node& desc, unsigned i);
1410 macro_data(const JSON::node& ser, unsigned i);
1411 void serialize(JSON::node& v);
1412 static JSON::node make_descriptor(const controller& ctrl);
1413 const JSON::node& get_descriptor() { return _descriptor; }
1414 static bool syntax_check(const std::string& spec, const JSON::node& ctrl);
1415 void write(frame& frame, unsigned port, unsigned controller, int64_t nframe, apply_mode amode);
1416 std::string dump(const controller& ctrl); //Mainly for debugging.
1417 size_t get_frames() { return data.size() / get_stride(); }
1418 size_t get_stride() { return buttons; }
1419 size_t buttons;
1420 std::vector<unsigned char> data;
1421 std::vector<std::pair<unsigned, unsigned>> aaxes;
1422 std::vector<unsigned> btnmap;
1423 std::vector<axis_transform> adata;
1424 std::string orig;
1425 JSON::node _descriptor;
1426 bool enabled;
1427 bool autoterminate;
1430 struct macro
1432 macro_data::apply_mode amode;
1433 std::map<unsigned, macro_data> macros;
1434 void write(frame& frame, int64_t nframe);
1435 macro() { amode = macro_data::AM_XOR; }
1436 macro(const JSON::node& ser);
1437 JSON::node serialize();
1442 * Get generic default system port type.
1444 type& get_default_system_port_type();
1447 #endif