Fix race between killing object and drawing object
[lsnes.git] / include / library / portctrl-data.hpp
blob61b262f1959d016f3523f1f984d4b1b2e0faf0d1
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"
22 namespace binarystream
24 class input;
25 class output;
28 /**
29 * Memory to allocate for controller frame.
31 #define MAXIMUM_CONTROLLER_FRAME_SIZE 128
32 /**
33 * Maximum amount of data frame::display() can write.
35 #define MAX_DISPLAY_LENGTH 128
36 /**
37 * Maximum amount of data frame::serialize() can write.
39 #define MAX_SERIALIZED_SIZE 256
40 /**
41 * Size of controller page.
43 #define CONTROLLER_PAGE_SIZE 65500
44 /**
45 * Special return value for deserialize() indicating no input was taken.
47 #define DESERIALIZE_SPECIAL_BLANK 0xFFFFFFFFUL
49 namespace portctrl
51 /**
52 * Is not field terminator.
54 * Parameter ch: The character.
55 * Returns: True if character is not terminator, false if character is terminator.
57 inline bool is_nonterminator(char ch) throw()
59 return (ch != '|' && ch != '\r' && ch != '\n' && ch != '\0');
62 /**
63 * Read button value.
65 * Parameter buf: Buffer to read from.
66 * Parameter idx: Index to buffer. Updated.
67 * Returns: The read value.
69 inline bool read_button_value(const char* buf, size_t& idx) throw()
71 char ch = buf[idx];
72 if(is_nonterminator(ch))
73 idx++;
74 return (ch != '|' && ch != '\r' && ch != '\n' && ch != '\0' && ch != '.' && ch != ' ' && ch != '\t');
77 /**
78 * Read axis value.
80 * Parameter buf: Buffer to read from.
81 * Parameter idx: Index to buffer. Updated.
82 * Returns: The read value.
84 short read_axis_value(const char* buf, size_t& idx) throw();
86 /**
87 * Write axis value.
89 * Parameter buf: The buffer to write to.
90 * Parameter _v: The axis value.
91 * Returns: Number of bytes written.
93 size_t write_axis_value(char* buf, short _v);
96 /**
97 * Skip whitespace.
99 * Parameter buf: Buffer to read from.
100 * Parameter idx: Index to buffer. Updated.
102 inline void skip_field_whitespace(const char* buf, size_t& idx) throw()
104 while(buf[idx] == ' ' || buf[idx] == '\t')
105 idx++;
109 * Skip rest of the field.
111 * Parameter buf: Buffer to read from.
112 * Parameter idx: Index to buffer. Updated.
113 * Parameter include_pipe: If true, also skip the '|'.
115 inline void skip_rest_of_field(const char* buf, size_t& idx, bool include_pipe) throw()
117 while(is_nonterminator(buf[idx]))
118 idx++;
119 if(include_pipe && buf[idx] == '|')
120 idx++;
124 * Serialize short.
126 inline void serialize_short(unsigned char* buf, short val)
128 buf[0] = static_cast<unsigned short>(val) >> 8;
129 buf[1] = static_cast<unsigned short>(val);
133 * Serialize short.
135 inline short unserialize_short(const unsigned char* buf)
137 return static_cast<short>((static_cast<unsigned short>(buf[0]) << 8) | static_cast<unsigned short>(buf[1]));
140 class type;
143 * Index triple.
145 * Note: The index 0 has to be mapped to triple (0, 0, 0).
147 struct index_triple
150 * If true, the other parameters are valid. Otherwise this index doesn't correspond to anything valid, but still
151 * exists. The reason for having invalid entries is to be backward-compatible.
153 bool valid;
155 * The port number.
157 unsigned port;
159 * The controller number.
161 unsigned controller;
163 * The control number.
165 unsigned control;
169 * Controller index mappings
171 struct index_map
174 * The poll indices.
176 std::vector<index_triple> indices;
178 * The logical controller mappings.
180 std::vector<std::pair<unsigned, unsigned>> logical_map;
182 * Legacy PCID mappings.
184 std::vector<std::pair<unsigned, unsigned>> pcid_map;
188 class type_set;
191 * A button or axis on controller
193 struct button
196 * Type of button
198 enum _type
200 TYPE_NULL, //Nothing (except takes the slot).
201 TYPE_BUTTON, //Button.
202 TYPE_AXIS, //Axis.
203 TYPE_RAXIS, //Relative Axis (mouse).
204 TYPE_TAXIS, //Throttle Axis (does not pair).
205 TYPE_LIGHTGUN, //Lightgun axis.
207 enum _type type;
208 char32_t symbol;
209 std::string name;
210 bool shadow;
211 int16_t rmin; //Range min.
212 int16_t rmax; //Range max.
213 bool centers;
214 std::string macro; //Name in macro (must be prefix-free).
215 char msymbol; //Symbol in movie.
217 * Is analog?
219 bool is_analog() const throw() { return type == (TYPE_AXIS) || (type == TYPE_RAXIS) || (type == TYPE_TAXIS)
220 || (type == TYPE_LIGHTGUN); }
224 * A controller.
226 struct controller
228 std::string cclass; //Controller class.
229 std::string type; //Controller type.
230 std::vector<button> buttons; //Buttons.
232 * Count number of analog actions on this controller.
234 unsigned analog_actions() const;
236 * Get the axis numbers of specified analog action. If no valid axis exists, returns UINT_MAX.
238 std::pair<unsigned, unsigned> analog_action(unsigned i) const;
240 * Get specified button, or NULL if it doesn't exist.
242 struct button* get(unsigned i)
244 if(i >= buttons.size())
245 return NULL;
246 return &buttons[i];
251 * A port controller set
253 struct controller_set
255 std::string iname;
256 std::string hname;
257 std::string symbol;
258 std::vector<controller> controllers; //Controllers.
259 std::set<unsigned> legal_for; //Ports this is legal for
261 * Get specified controller, or NULL if it doesn't exist.
263 struct controller* get(unsigned c) throw()
265 if(c >= controllers.size())
266 return NULL;
267 return &controllers[c];
270 * Get specified button, or NULL if it doesn't exist.
272 struct button* get(unsigned c, unsigned i) throw();
276 * Type of controller.
278 class type
280 public:
282 * Create a new port type.
284 * Parameter iname: Internal name of the port type.
285 * Parameter hname: Human-readable name of the port type.
286 * Parameter ssize: The storage size in bytes.
287 * Throws std::bad_alloc: Not enough memory.
289 type(const std::string& iname, const std::string& hname, size_t ssize) throw(std::bad_alloc);
291 * Unregister a port type.
293 virtual ~type() throw();
295 * Writes controller data into compressed representation.
297 * Parameter buffer: The buffer storing compressed representation of controller state.
298 * Parameter idx: Index of controller.
299 * Parameter ctrl: The control to manipulate.
300 * Parameter x: New value for control. Only zero/nonzero matters for buttons.
302 void (*write)(const type* _this, unsigned char* buffer, unsigned idx, unsigned ctrl, short x);
304 * Read controller data from compressed representation.
306 * Parameter buffer: The buffer storing compressed representation of controller state.
307 * Parameter idx: Index of controller.
308 * Parameter ctrl: The control to query.
309 * Returns: The value of control. Buttons return 0 or 1.
311 short (*read)(const type* _this, const unsigned char* buffer, unsigned idx, unsigned ctrl);
313 * Take compressed controller data and serialize it into textual representation.
315 * - The initial '|' is also written.
317 * Parameter buffer: The buffer storing compressed representation of controller state.
318 * Parameter textbuf: The text buffer to write to.
319 * Returns: Number of bytes written.
321 size_t (*serialize)(const type* _this, const unsigned char* buffer, char* textbuf);
323 * Unserialize textual representation into compressed controller state.
325 * - Only stops reading on '|', NUL, CR or LF in the final read field. That byte is not read.
327 * Parameter buffer: The buffer storing compressed representation of controller state.
328 * Parameter textbuf: The text buffer to read.
329 * Returns: Number of bytes read.
330 * Throws std::runtime_error: Bad serialization.
332 size_t (*deserialize)(const type* _this, unsigned char* buffer, const char* textbuf);
334 * Is the device legal for port?
336 * Parameter port: Port to query.
337 * Returns: Nonzero if legal, zero if illegal.
339 int legal(unsigned port)
341 return controller_info->legal_for.count(port) ? 1 : 0;
344 * Controller info.
346 controller_set* controller_info;
348 * Get number of used control indices on controller.
350 * Parameter controller: Number of controller.
351 * Returns: Number of used control indices.
353 unsigned used_indices(unsigned controller)
355 auto c = controller_info->get(controller);
356 return c ? c->buttons.size() : 0;
359 * Human-readable name.
361 std::string hname;
363 * Number of bytes it takes to store this.
365 size_t storage_size;
367 * Name of port type.
369 std::string name;
371 * Is given controller present?
373 bool is_present(unsigned controller) const throw();
374 private:
375 type(const type&);
376 type& operator=(const type&);
380 * A set of port types.
382 class type_set
384 public:
386 * Create empty port type set.
388 type_set() throw();
390 * Make a port type set with specified types. If called again with the same parameters, returns the same object.
392 * Parameter types: The types.
393 * Parameter control_map: The control map
394 * Throws std::bad_alloc: Not enough memory.
395 * Throws std::runtime_error: Illegal port types.
397 static type_set& make(std::vector<type*> types, struct index_map control_map)
398 throw(std::bad_alloc, std::runtime_error);
400 * Compare sets for equality.
402 bool operator==(const type_set& s) const throw() { return this == &s; }
404 * Compare sets for non-equality.
406 bool operator!=(const type_set& s) const throw() { return this != &s; }
408 * Get offset of specified port.
410 * Parameter port: The number of port.
411 * Returns: The offset of port.
412 * Throws std::runtime_error: Bad port number.
414 size_t port_offset(unsigned port) const throw(std::runtime_error)
416 if(port >= port_count)
417 throw std::runtime_error("Invalid port index");
418 return port_offsets[port];
421 * Get type of specified port.
423 * Parameter port: The number of port.
424 * Returns: The port type.
425 * Throws std::runtime_error: Bad port number.
427 const class type& port_type(unsigned port) const throw(std::runtime_error)
429 if(port >= port_count)
430 throw std::runtime_error("Invalid port index");
431 return *(port_types[port]);
434 * Get number of ports.
436 * Returns: The port count.
438 unsigned ports() const throw()
440 return port_count;
443 * Get total size of controller data.
445 * Returns the size.
447 unsigned size() const throw()
449 return total_size;
452 * Get total index count.
454 unsigned indices() const throw()
456 return _indices.size();
459 * Look up the triplet for given control.
461 * Parameter index: The index to look up.
462 * Returns: The triplet (may not be valid).
463 * Throws std::runtime_error: Index out of range.
465 index_triple index_to_triple(unsigned index) const throw(std::runtime_error)
467 if(index >= _indices.size())
468 throw std::runtime_error("Invalid index");
469 return _indices[index];
472 * Translate triplet into index.
474 * Parameter port: The port.
475 * Parameter controller: The controller.
476 * Parameter _index: The control index.
477 * Returns: The index, or 0xFFFFFFFFUL if specified triple is not valid.
479 unsigned triple_to_index(unsigned port, unsigned controller, unsigned _index) const throw(std::runtime_error)
481 size_t place = port * port_multiplier + controller * controller_multiplier + _index;
482 if(place >= indices_size)
483 return 0xFFFFFFFFUL;
484 unsigned pindex = indices_tab[place];
485 if(pindex == 0xFFFFFFFFUL)
486 return 0xFFFFFFFFUL;
487 const struct index_triple& t = _indices[pindex];
488 if(!t.valid || t.port != port || t.controller != controller || t.control != _index)
489 return 0xFFFFFFFFUL;
490 return pindex;
493 * Return number of controllers connected.
495 * Returns: Number of controllers.
497 unsigned number_of_controllers() const throw()
499 return controllers.size();
502 * Lookup physical controller index corresponding to logical one.
504 * Parameter lcid: Logical controller id.
505 * Returns: Physical controller index (port, controller).
506 * Throws std::runtime_error: No such controller.
508 std::pair<unsigned, unsigned> lcid_to_pcid(unsigned lcid) const throw(std::runtime_error)
510 if(lcid >= controllers.size())
511 throw std::runtime_error("Bad logical controller");
512 return controllers[lcid];
515 * Return number of legacy PCIDs.
517 unsigned number_of_legacy_pcids() const throw()
519 return legacy_pcids.size();
522 * Lookup (port,controller) pair corresponding to given legacy pcid.
524 * Parameter pcid: The legacy pcid.
525 * Returns: The controller index.
526 * Throws std::runtime_error: No such controller.
528 std::pair<unsigned, unsigned> legacy_pcid_to_pair(unsigned pcid) const throw(std::runtime_error)
530 if(pcid >= legacy_pcids.size())
531 throw std::runtime_error("Bad legacy PCID");
532 return legacy_pcids[pcid];
534 private:
535 type_set(std::vector<class type*> types, struct index_map control_map);
536 size_t* port_offsets;
537 class type** port_types;
538 unsigned port_count;
539 size_t total_size;
540 std::vector<index_triple> _indices;
541 std::vector<std::pair<unsigned, unsigned>> controllers;
542 std::vector<std::pair<unsigned, unsigned>> legacy_pcids;
544 size_t port_multiplier;
545 size_t controller_multiplier;
546 size_t indices_size;
547 unsigned* indices_tab;
551 * Poll counter vector.
553 class counters
555 public:
557 * Create new pollcounter vector filled with all zeroes and all DRDY bits clear.
559 * Throws std::bad_alloc: Not enough memory.
561 counters() throw(std::bad_alloc);
563 * Create new pollcounter vector suitably sized for given type set.
565 * Parameter p: The port types.
566 * Throws std::bad_alloc: Not enough memory.
568 counters(const type_set& p) throw(std::bad_alloc);
570 * Destructor.
572 ~counters() throw();
574 * Copy the counters.
576 counters(const counters& v) throw(std::bad_alloc);
578 * Assign the counters.
580 counters& operator=(const counters& v) throw(std::bad_alloc);
582 * Zero all poll counters and clear all DRDY bits. System flag is cleared.
584 void clear() throw();
586 * Set all DRDY bits.
588 void set_all_DRDY() throw();
590 * Clear specified DRDY bit.
592 * Parameter port: The port.
593 * Parameter controller: The controller
594 * Parameter ctrl: The control id.
596 void clear_DRDY(unsigned port, unsigned controller, unsigned ctrl) throw()
598 unsigned i = types->triple_to_index(port, controller, ctrl);
599 if(i != 0xFFFFFFFFU)
600 clear_DRDY(i);
603 * Clear state of DRDY bit.
605 * Parameter idx: The control index.
607 void clear_DRDY(unsigned idx) throw();
609 * Get state of DRDY bit.
611 * Parameter port: The port.
612 * Parameter controller: The controller
613 * Parameter ctrl: The control id.
614 * Returns: The DRDY state.
616 bool get_DRDY(unsigned port, unsigned controller, unsigned ctrl) throw()
618 unsigned i = types->triple_to_index(port, controller, ctrl);
619 if(i != 0xFFFFFFFFU)
620 return get_DRDY(i);
621 else
622 return true;
625 * Get state of DRDY bit.
627 * Parameter idx: The control index.
628 * Returns: The DRDY state.
630 bool get_DRDY(unsigned idx) throw();
632 * Is any poll count nonzero or is system flag set?
634 * Returns: True if at least one poll count is nonzero or if system flag is set. False otherwise.
636 bool has_polled() throw();
638 * Read the actual poll count on specified control.
640 * Parameter port: The port.
641 * Parameter controller: The controller
642 * Parameter ctrl: The control id.
643 * Return: The poll count.
645 uint32_t get_polls(unsigned port, unsigned controller, unsigned ctrl) throw()
647 unsigned i = types->triple_to_index(port, controller, ctrl);
648 if(i != 0xFFFFFFFFU)
649 return get_polls(i);
650 else
651 return 0;
654 * Read the actual poll count on specified control.
656 * Parameter idx: The control index.
657 * Return: The poll count.
659 uint32_t get_polls(unsigned idx) throw();
661 * Increment poll count on specified control.
663 * Parameter port: The port.
664 * Parameter controller: The controller
665 * Parameter ctrl: The control id.
666 * Return: The poll count pre-increment.
668 uint32_t increment_polls(unsigned port, unsigned controller, unsigned ctrl) throw()
670 unsigned i = types->triple_to_index(port, controller, ctrl);
671 if(i != 0xFFFFFFFFU)
672 return increment_polls(i);
673 else
674 return 0;
677 * Increment poll count on specified index.
679 * Parameter idx: The index.
680 * Return: The poll count pre-increment.
682 uint32_t increment_polls(unsigned idx) throw();
684 * Get highest poll counter value.
686 * - System flag counts as 1 poll.
688 * Returns: The maximum poll count (at least 1 if system flag is set).
690 uint32_t max_polls() throw();
692 * Save state to memory block.
694 * Parameter mem: The memory block to save to.
695 * Throws std::bad_alloc: Not enough memory.
697 void save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc);
699 * Load state from memory block.
701 * Parameter mem: The block from restore from.
703 void load_state(const std::vector<uint32_t>& mem) throw();
705 * Check if state can be loaded without errors.
707 * Returns: True if load is possible, false otherwise.
709 bool check(const std::vector<uint32_t>& mem) throw();
711 * Set/Clear the frame parameters polled flag.
713 void set_framepflag(bool value) throw();
715 * Get the frame parameters polled flag.
717 bool get_framepflag() const throw();
719 * Get raw pollcounter data.
721 const uint32_t* rawdata() const throw() { return ctrs; }
722 private:
723 uint32_t* ctrs;
724 const type_set* types;
725 bool framepflag;
728 class frame_vector;
731 * Single (sub)frame of controls.
733 class frame
735 public:
737 * Default constructor. Invalid port types, dedicated memory.
739 frame() throw();
741 * Create subframe of controls with specified controller types and dedicated memory.
743 * Parameter p: Types of ports.
745 frame(const type_set& p) throw(std::runtime_error);
747 * Create subframe of controls with specified controller types and specified memory.
749 * Parameter memory: The backing memory.
750 * Parameter p: Types of ports.
751 * Parameter host: Host frame vector.
753 * Throws std::runtime_error: NULL memory.
755 frame(unsigned char* memory, const type_set& p, frame_vector* host = NULL)
756 throw(std::runtime_error);
758 * Copy construct a frame. The memory will be dedicated.
760 * Parameter obj: The object to copy.
762 frame(const frame& obj) throw();
764 * Assign a frame. The types must either match or memory must be dedicated.
766 * Parameter obj: The object to copy.
767 * Returns: Reference to this.
768 * Throws std::runtime_error: The types don't match and memory is not dedicated.
770 frame& operator=(const frame& obj) throw(std::runtime_error);
772 * Get type of port.
774 * Parameter port: Number of port.
775 * Returns: The type of port.
777 const type& get_port_type(unsigned port) throw()
779 return types->port_type(port);
782 * Get port count.
784 unsigned get_port_count() throw()
786 return types->ports();
789 * Get index count.
791 unsigned get_index_count() throw()
793 return types->indices();
796 * Set types of ports.
798 * Parameter ptype: New port types.
799 * Throws std::runtime_error: Memory is mapped.
801 void set_types(const type_set& ptype) throw(std::runtime_error)
803 if(memory != backing)
804 throw std::runtime_error("Can't change type of mapped frame");
805 types = &ptype;
808 * Get blank dedicated frame of same port types.
810 * Return blank frame.
812 frame blank_frame() throw()
814 return frame(*types);
817 * Check that types match.
819 * Parameter obj: Another object.
820 * Returns: True if types match, false otherwise.
822 bool types_match(const frame& obj) const throw()
824 return types == obj.types;
827 * Perform XOR between controller frames.
829 * Parameter another: The another object.
830 * Returns: The XOR result (dedicated memory).
831 * Throws std::runtime_error: Type mismatch.
833 frame operator^(const frame& another) throw(std::runtime_error)
835 frame x(*this);
836 if(types != another.types)
837 throw std::runtime_error("frame::operator^: Type mismatch");
838 for(size_t i = 0; i < types->size(); i++)
839 x.backing[i] ^= another.backing[i];
840 return x;
843 * Set the sync flag.
845 * Parameter x: The value to set the sync flag to.
847 inline void sync(bool x) throw();
849 * Get the sync flag.
851 * Return value: Value of sync flag.
853 bool sync() throw()
855 return ((backing[0] & 1) != 0);
858 * Quick get sync flag for buffer.
860 static bool sync(const unsigned char* mem) throw()
862 return ((mem[0] & 1) != 0);
865 * Get size of frame.
867 * Returns: The number of bytes it takes to store frame of this type.
869 size_t size()
871 return types->size();
874 * Set axis/button value.
876 * Parameter port: The port.
877 * Parameter controller: The controller
878 * Parameter ctrl: The control id.
879 * Parameter x: The new value.
881 void axis3(unsigned port, unsigned controller, unsigned ctrl, short x) throw()
883 if(port >= types->ports())
884 return;
885 auto& t = types->port_type(port);
886 if(!port && !controller && !ctrl && host)
887 sync(x != 0);
888 else
889 t.write(&t, backing + types->port_offset(port), controller, ctrl, x);
892 * Set axis/button value.
894 * Parameter idx: Control index.
895 * Parameter x: The new value.
897 void axis2(unsigned idx, short x) throw()
899 index_triple t = types->index_to_triple(idx);
900 if(t.valid)
901 axis3(t.port, t.controller, t.control, x);
904 * Get axis/button value.
906 * Parameter port: The port.
907 * Parameter controller: The controller
908 * Parameter ctrl: The control id.
909 * Return value: The axis value.
911 short axis3(unsigned port, unsigned controller, unsigned ctrl) throw()
913 if(port >= types->ports())
914 return 0;
915 auto& t = types->port_type(port);
916 return t.read(&t, backing + types->port_offset(port), controller, ctrl);
920 * Get axis/button value.
922 * Parameter idx: Index of control.
923 * Return value: The axis value.
925 short axis2(unsigned idx) throw()
927 index_triple t = types->index_to_triple(idx);
928 if(t.valid)
929 return axis3(t.port, t.controller, t.control);
930 else
931 return 0;
934 * Get controller display.
936 * Parameter port: The port.
937 * Parameter controller: The controller
938 * Parameter buf: Buffer to write nul-terminated display to.
940 void display(unsigned port, unsigned controller, char32_t* buf) throw();
942 * Is device present?
944 * Parameter port: The port.
945 * Parameter controller: The controller
946 * Returns: True if present, false if not.
948 bool is_present(unsigned port, unsigned controller) throw()
950 if(port >= types->ports())
951 return false;
952 return types->port_type(port).is_present(controller);
955 * Deserialize frame from text format.
957 * Parameter buf: The buffer containing text representation. Terminated by NUL, CR or LF.
958 * Throws std::runtime_error: Bad serialized representation.
960 inline void deserialize(const char* buf) throw(std::runtime_error);
962 * Serialize frame to text format.
964 * Parameter buf: The buffer to write NUL-terminated text representation to.
966 void serialize(char* buf) throw()
968 size_t offset = 0;
969 for(size_t i = 0; i < types->ports(); i++) {
970 auto& t = types->port_type(i);
971 offset += t.serialize(&t, backing + types->port_offset(i), buf + offset);
973 buf[offset++] = '\0';
976 * Return copy with dedicated memory.
978 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
979 * Returns: Copy of this frame.
981 frame copy(bool sync)
983 frame c(*this);
984 c.sync(sync);
985 return c;
988 * Compare two frames.
990 * Parameter obj: Another frame.
991 * Returns: True if equal, false if not.
993 bool operator==(const frame& obj) const throw()
995 if(!types_match(obj))
996 return false;
997 return !memcmp(backing, obj.backing, types->size());
1000 * Compare two frames.
1002 * Parameter obj: Another frame.
1003 * Returns: True if not equal, false if equal.
1005 bool operator!=(const frame& obj) const throw()
1007 return !(*this == obj);
1010 * Get the port type set.
1012 const type_set& porttypes()
1014 return *types;
1016 private:
1017 unsigned char memory[MAXIMUM_CONTROLLER_FRAME_SIZE];
1018 unsigned char* backing;
1019 frame_vector* host;
1020 const type_set* types;
1024 * Vector of controller frames.
1026 class frame_vector
1028 public:
1030 * Framecount change listener.
1032 class fchange_listener
1034 public:
1036 * Destructor.
1038 virtual ~fchange_listener();
1040 * Notify a change.
1042 virtual void notify(frame_vector& src, uint64_t old) = 0;
1045 * Construct new controller frame vector.
1047 frame_vector() throw();
1049 * Construct new controller frame vector.
1051 * Parameter p: The port types.
1053 frame_vector(const type_set& p) throw();
1055 * Destroy controller frame vector
1057 ~frame_vector() throw();
1059 * Copy controller frame vector.
1061 * Parameter obj: The object to copy.
1062 * Throws std::bad_alloc: Not enough memory.
1064 frame_vector(const frame_vector& vector) throw(std::bad_alloc);
1066 * Assign controller frame vector.
1068 * Parameter obj: The object to copy.
1069 * Returns: Reference to this.
1070 * Throws std::bad_alloc: Not enough memory.
1072 frame_vector& operator=(const frame_vector& vector) throw(std::bad_alloc);
1074 * Blank vector and change the type of ports.
1076 * Parameter p: The port types.
1078 void clear(const type_set& p) throw(std::runtime_error);
1080 * Blank vector.
1082 void clear() throw()
1084 clear(*types);
1087 * Get number of subframes.
1089 size_t size() const
1091 return frames;
1094 * Get the typeset.
1096 const type_set& get_types()
1098 return *types;
1101 * Access specified subframe.
1103 * Parameter x: The frame number.
1104 * Returns: The controller frame.
1105 * Throws std::runtime_error: Invalid frame index.
1107 frame operator[](size_t x)
1109 size_t page = x / frames_per_page;
1110 size_t pageoffset = frame_size * (x % frames_per_page);
1111 if(x >= frames)
1112 throw std::runtime_error("frame_vector::operator[]: Illegal index");
1113 if(page != cache_page_num) {
1114 cache_page = &pages[page];
1115 cache_page_num = page;
1117 return frame(cache_page->content + pageoffset, *types, this);
1120 * Append a subframe.
1122 * Parameter frame: The frame to append.
1123 * Throws std::bad_alloc: Not enough memory.
1124 * Throws std::runtime_error: Port type mismatch.
1126 void append(frame frame) throw(std::bad_alloc, std::runtime_error);
1128 * Change length of vector.
1130 * - Reducing length of vector will discard extra elements.
1131 * - Extending length of vector will add all-zero elements.
1133 * Parameter newsize: New size of vector.
1134 * Throws std::bad_alloc: Not enough memory.
1136 void resize(size_t newsize) throw(std::bad_alloc);
1138 * Walk the indexes of sync subframes.
1140 * - If frame is in range and there is at least one more sync subframe after it, the index of first sync subframe
1141 * after given frame.
1142 * - If frame is in range, but there are no more sync subframes after it, the length of vector is returned.
1143 * - If frame is out of range, the given frame is returned.
1145 * Parameter frame: The frame number to start search from.
1146 * Returns: Index of next sync frame.
1148 size_t walk_sync(size_t frame) throw()
1150 return walk_helper(frame, true);
1153 * Get number of subframes in frame. The given subframe is assumed to be sync subframe.
1155 * - The return value is the same as (walk_sync(frame) - frame).
1157 * Parameter frame: The frame number to start search from.
1158 * Returns: Number of subframes in this frame.
1160 size_t subframe_count(size_t frame) throw()
1162 return walk_helper(frame, false);
1165 * Count number of subframes in vector with sync flag set.
1167 * Returns: The number of frames.
1169 size_t count_frames() throw() { return real_frame_count; }
1171 * Recount number of frames.
1173 * This is to be used after direct editing of pointers obtained by get_page_buffer().
1175 * Returns: The number of frames.
1177 size_t recount_frames() throw();
1179 * Return blank controller frame with correct type and dedicated memory.
1181 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
1182 * Returns: Blank frame.
1184 frame blank_frame(bool sync)
1186 frame c(*types);
1187 c.sync(sync);
1188 return c;
1191 * Return number of pages in movie.
1193 size_t get_page_count() const { return pages.size(); }
1195 * Return the stride.
1197 size_t get_stride() const { return frame_size; }
1199 * Return number of frames per page.
1201 size_t get_frames_per_page() const { return frames_per_page; }
1203 * Get content of given page.
1205 unsigned char* get_page_buffer(size_t page) { return pages[page].content; }
1207 * Get content of given page.
1209 const unsigned char* get_page_buffer(size_t page) const { return pages.find(page)->second.content; }
1211 * Get binary save size.
1213 * Returns: The number of bytes for binary save.
1215 uint64_t binary_size() const throw();
1217 * Save in binary form.
1219 * Parameter stream: The stream to save to.
1220 * Throws std::runtime_error: Error saving.
1222 void save_binary(binarystream::output& stream) const throw(std::runtime_error);
1224 * Load from binary form. May partially overwrite on failure.
1226 * Parameter stream: The stream to load from.
1227 * Throws std::bad_alloc: Not enough memory.
1228 * Throws std::runtime_error: Error saving.
1230 void load_binary(binarystream::input& stream) throw(std::bad_alloc, std::runtime_error);
1232 * Check that the movies are compatible up to a point.
1234 * Parameter with: The 2nd frame vector to check.
1235 * Parameter frame: The frame number (1-based) to check to.
1236 * Parameter polls: The poll counters within frame to check to.
1237 * Returns: True if compatible, false if not.
1239 bool compatible(frame_vector& with, uint64_t frame, const uint32_t* polls);
1241 * Find subframe number corresponding to given frame (1-based).
1243 int64_t find_frame(uint64_t n);
1245 * Notify sync flag polarity change.
1247 * Parameter polarity: 1 if positive edge, -1 if negative edge. 0 is ignored.
1249 void notify_sync_change(short polarity) {
1250 uint64_t old_frame_count = real_frame_count;
1251 real_frame_count = real_frame_count + polarity;
1252 if(!freeze_count) call_framecount_notification(old_frame_count);
1255 * Set where to deliver frame count change notifications to.
1257 * Parameter cb: Callback to register.
1258 * Returns: Handle for callback.
1260 void set_framecount_notification(fchange_listener& cb)
1262 threads::alock h(mlock);
1263 on_framecount_change.insert(&cb);
1266 * Clear framecount change notification.
1268 * Parameter handle: Handle to clear.
1270 void clear_framecount_notification(fchange_listener& cb)
1272 threads::alock h(mlock);
1273 on_framecount_change.erase(&cb);
1276 * Call framecount change notification.
1278 void call_framecount_notification(uint64_t oldcount)
1280 std::set<fchange_listener*> tmp;
1282 threads::alock h(mlock);
1283 tmp = on_framecount_change;
1285 for(auto i : tmp)
1286 try { i->notify(*this, oldcount); } catch(...) {}
1289 * Swap frame data.
1291 * Only the frame data is swapped, not the notifications.
1293 void swap_data(frame_vector& v) throw();
1296 * Freeze framecount notifications.
1298 struct notify_freeze
1300 notify_freeze(frame_vector& parent)
1301 : frozen(parent)
1303 frozen.freeze_count++;
1304 if(frozen.freeze_count == 1)
1305 frozen.frame_count_at_freeze = frozen.real_frame_count;
1307 ~notify_freeze()
1309 frozen.freeze_count--;
1310 if(frozen.freeze_count == 0)
1311 frozen.call_framecount_notification(frozen.frame_count_at_freeze);
1313 private:
1314 notify_freeze(const notify_freeze&);
1315 notify_freeze& operator=(const notify_freeze&);
1316 frame_vector& frozen;
1318 private:
1319 friend class notify_freeze;
1320 class page
1322 public:
1323 page() { memset(content, 0, CONTROLLER_PAGE_SIZE); }
1324 unsigned char content[CONTROLLER_PAGE_SIZE];
1326 size_t frames_per_page;
1327 size_t frame_size;
1328 size_t frames;
1329 const type_set* types;
1330 size_t cache_page_num;
1331 page* cache_page;
1332 std::map<size_t, page> pages;
1333 uint64_t real_frame_count;
1334 uint64_t frame_count_at_freeze;
1335 size_t freeze_count;
1336 std::set<fchange_listener*> on_framecount_change;
1337 size_t walk_helper(size_t frame, bool sflag) throw();
1338 threads::lock mlock;
1339 void clear_cache()
1341 cache_page_num = 0;
1342 cache_page_num--;
1343 cache_page = NULL;
1347 void frame::sync(bool x) throw()
1349 short old = (backing[0] & 1);
1350 if(x)
1351 backing[0] |= 1;
1352 else
1353 backing[0] &= ~1;
1354 if(host) host->notify_sync_change((backing[0] & 1) - old);
1357 void frame::deserialize(const char* buf) throw(std::runtime_error)
1359 short old = sync();
1360 size_t offset = 0;
1361 for(size_t i = 0; i < types->ports(); i++) {
1362 size_t s;
1363 auto& t = types->port_type(i);
1364 s = t.deserialize(&t, backing + types->port_offset(i), buf + offset);
1365 if(s != DESERIALIZE_SPECIAL_BLANK) {
1366 offset += s;
1367 while(is_nonterminator(buf[offset]))
1368 offset++;
1369 if(buf[offset] == '|')
1370 offset++;
1373 if(host) host->notify_sync_change(sync() - old);
1377 //Parse a controller macro.
1378 struct macro_data
1380 struct axis_transform
1382 axis_transform() { coeffs[0] = coeffs[3] = 1; coeffs[1] = coeffs[2] = coeffs[4] = coeffs[5] = 0; }
1383 axis_transform(const std::string& expr);
1384 double coeffs[6];
1385 int16_t transform(const button& b, int16_t v);
1386 std::pair<int16_t, int16_t> transform(const button& b1,
1387 const button& b2, int16_t v1, int16_t v2);
1388 static double unscale_axis(const button& b, int16_t v);
1389 static int16_t scale_axis(const button& b, double v);
1391 enum apply_mode
1393 AM_OVERWRITE,
1394 AM_OR,
1395 AM_XOR
1397 macro_data() { buttons = 0; }
1398 macro_data(const std::string& spec, const JSON::node& desc, unsigned i);
1399 macro_data(const JSON::node& ser, unsigned i);
1400 void serialize(JSON::node& v);
1401 static JSON::node make_descriptor(const controller& ctrl);
1402 const JSON::node& get_descriptor() { return _descriptor; }
1403 static bool syntax_check(const std::string& spec, const JSON::node& ctrl);
1404 void write(frame& frame, unsigned port, unsigned controller, int64_t nframe, apply_mode amode);
1405 std::string dump(const controller& ctrl); //Mainly for debugging.
1406 size_t get_frames() { return data.size() / get_stride(); }
1407 size_t get_stride() { return buttons; }
1408 size_t buttons;
1409 std::vector<unsigned char> data;
1410 std::vector<std::pair<unsigned, unsigned>> aaxes;
1411 std::vector<unsigned> btnmap;
1412 std::vector<axis_transform> adata;
1413 std::string orig;
1414 JSON::node _descriptor;
1415 bool enabled;
1416 bool autoterminate;
1419 struct macro
1421 macro_data::apply_mode amode;
1422 std::map<unsigned, macro_data> macros;
1423 void write(frame& frame, int64_t nframe);
1424 macro() { amode = macro_data::AM_XOR; }
1425 macro(const JSON::node& ser);
1426 JSON::node serialize();
1431 * Get generic default system port type.
1433 type& get_default_system_port_type();
1436 #endif