1 #ifndef _library__portctrl_data__hpp__included__
2 #define _library__portctrl_data__hpp__included__
20 #include "threads.hpp"
21 #include "memtracker.hpp"
23 namespace binarystream
30 * Memory to allocate for controller frame.
32 #define MAXIMUM_CONTROLLER_FRAME_SIZE 128
34 * Maximum amount of data frame::display() can write.
36 #define MAX_DISPLAY_LENGTH 128
38 * Maximum amount of data frame::serialize() can write.
40 #define MAX_SERIALIZED_SIZE 256
42 * Size of controller page.
44 #define CONTROLLER_PAGE_SIZE 65500
46 * Special return value for deserialize() indicating no input was taken.
48 #define DESERIALIZE_SPECIAL_BLANK 0xFFFFFFFFUL
52 extern const char* movie_page_id
;
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');
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()
74 if(is_nonterminator(ch
))
76 return (ch
!= '|' && ch
!= '\r' && ch
!= '\n' && ch
!= '\0' && ch
!= '.' && ch
!= ' ' && ch
!= '\t');
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();
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
);
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')
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
]))
121 if(include_pipe
&& buf
[idx
] == '|')
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
);
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]));
147 * Note: The index 0 has to be mapped to triple (0, 0, 0).
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.
161 * The controller number.
165 * The control number.
171 * Controller index mappings
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
;
193 * A button or axis on controller
202 TYPE_NULL
, //Nothing (except takes the slot).
203 TYPE_BUTTON
, //Button.
205 TYPE_RAXIS
, //Relative Axis (mouse).
206 TYPE_TAXIS
, //Throttle Axis (does not pair).
207 TYPE_LIGHTGUN
, //Lightgun axis.
213 int16_t rmin
; //Range min.
214 int16_t rmax
; //Range max.
216 std::string macro
; //Name in macro (must be prefix-free).
217 char msymbol
; //Symbol in movie.
221 bool is_analog() const throw() { return type
== (TYPE_AXIS
) || (type
== TYPE_RAXIS
) || (type
== TYPE_TAXIS
)
222 || (type
== TYPE_LIGHTGUN
); }
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())
253 * A port controller set
255 struct controller_set
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())
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.
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
);
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;
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.
365 * Number of bytes it takes to store this.
373 * Is given controller present?
375 bool is_present(unsigned controller
) const throw();
378 type
& operator=(const type
&);
382 * A set of port types.
388 * Create empty port type set.
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
);
401 * Compare sets for equality.
403 bool operator==(const type_set
& s
) const throw() { return this == &s
; }
405 * Compare sets for non-equality.
407 bool operator!=(const type_set
& s
) const throw() { return this != &s
; }
409 * Get offset of specified port.
411 * Parameter port: The number of port.
412 * Returns: The offset of port.
413 * Throws std::runtime_error: Bad port number.
415 size_t port_offset(unsigned port
) const
417 if(port
>= port_count
)
418 throw std::runtime_error("Invalid port index");
419 return port_offsets
[port
];
422 * Get type of specified port.
424 * Parameter port: The number of port.
425 * Returns: The port type.
426 * Throws std::runtime_error: Bad port number.
428 const class type
& port_type(unsigned port
) const
430 if(port
>= port_count
)
431 throw std::runtime_error("Invalid port index");
432 return *(port_types
[port
]);
435 * Get number of ports.
437 * Returns: The port count.
439 unsigned ports() const throw()
444 * Get total size of controller data.
448 unsigned size() const throw()
453 * Get total index count.
455 unsigned indices() const throw()
457 return _indices
.size();
460 * Look up the triplet for given control.
462 * Parameter index: The index to look up.
463 * Returns: The triplet (may not be valid).
464 * Throws std::runtime_error: Index out of range.
466 index_triple
index_to_triple(unsigned index
) const
468 if(index
>= _indices
.size())
469 throw std::runtime_error("Invalid index");
470 return _indices
[index
];
473 * Translate triplet into index.
475 * Parameter port: The port.
476 * Parameter controller: The controller.
477 * Parameter _index: The control index.
478 * Returns: The index, or 0xFFFFFFFFUL if specified triple is not valid.
480 unsigned triple_to_index(unsigned port
, unsigned controller
, unsigned _index
) const
482 size_t place
= port
* port_multiplier
+ controller
* controller_multiplier
+ _index
;
483 if(place
>= indices_size
)
485 unsigned pindex
= indices_tab
[place
];
486 if(pindex
== 0xFFFFFFFFUL
)
488 const struct index_triple
& t
= _indices
[pindex
];
489 if(!t
.valid
|| t
.port
!= port
|| t
.controller
!= controller
|| t
.control
!= _index
)
494 * Return number of controllers connected.
496 * Returns: Number of controllers.
498 unsigned number_of_controllers() const throw()
500 return controllers
.size();
503 * Lookup physical controller index corresponding to logical one.
505 * Parameter lcid: Logical controller id.
506 * Returns: Physical controller index (port, controller).
507 * Throws std::runtime_error: No such controller.
509 std::pair
<unsigned, unsigned> lcid_to_pcid(unsigned lcid
) const
511 if(lcid
>= controllers
.size())
512 throw std::runtime_error("Bad logical controller");
513 return controllers
[lcid
];
516 * Return number of legacy PCIDs.
518 unsigned number_of_legacy_pcids() const throw()
520 return legacy_pcids
.size();
523 * Lookup (port,controller) pair corresponding to given legacy pcid.
525 * Parameter pcid: The legacy pcid.
526 * Returns: The controller index.
527 * Throws std::runtime_error: No such controller.
529 std::pair
<unsigned, unsigned> legacy_pcid_to_pair(unsigned pcid
) const
531 if(pcid
>= legacy_pcids
.size())
532 throw std::runtime_error("Bad legacy PCID");
533 return legacy_pcids
[pcid
];
536 type_set(std::vector
<class type
*> types
, struct index_map control_map
);
537 size_t* port_offsets
;
538 class type
** port_types
;
541 std::vector
<index_triple
> _indices
;
542 std::vector
<std::pair
<unsigned, unsigned>> controllers
;
543 std::vector
<std::pair
<unsigned, unsigned>> legacy_pcids
;
545 size_t port_multiplier
;
546 size_t controller_multiplier
;
548 unsigned* indices_tab
;
552 * Poll counter vector.
558 * Create new pollcounter vector filled with all zeroes and all DRDY bits clear.
560 * Throws std::bad_alloc: Not enough memory.
564 * Create new pollcounter vector suitably sized for given type set.
566 * Parameter p: The port types.
567 * Throws std::bad_alloc: Not enough memory.
569 counters(const type_set
& p
);
577 counters(const counters
& v
);
579 * Assign the counters.
581 counters
& operator=(const counters
& v
);
583 * Zero all poll counters and clear all DRDY bits. System flag is cleared.
585 void clear() throw();
589 void set_all_DRDY() throw();
591 * Clear specified DRDY bit.
593 * Parameter port: The port.
594 * Parameter controller: The controller
595 * Parameter ctrl: The control id.
597 void clear_DRDY(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
599 unsigned i
= types
->triple_to_index(port
, controller
, ctrl
);
604 * Clear state of DRDY bit.
606 * Parameter idx: The control index.
608 void clear_DRDY(unsigned idx
) throw();
610 * Get state of DRDY bit.
612 * Parameter port: The port.
613 * Parameter controller: The controller
614 * Parameter ctrl: The control id.
615 * Returns: The DRDY state.
617 bool get_DRDY(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
619 unsigned i
= types
->triple_to_index(port
, controller
, ctrl
);
626 * Get state of DRDY bit.
628 * Parameter idx: The control index.
629 * Returns: The DRDY state.
631 bool get_DRDY(unsigned idx
) throw();
633 * Is any poll count nonzero or is system flag set?
635 * Returns: True if at least one poll count is nonzero or if system flag is set. False otherwise.
637 bool has_polled() throw();
639 * Read the actual poll count on specified control.
641 * Parameter port: The port.
642 * Parameter controller: The controller
643 * Parameter ctrl: The control id.
644 * Return: The poll count.
646 uint32_t get_polls(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
648 unsigned i
= types
->triple_to_index(port
, controller
, ctrl
);
655 * Read the actual poll count on specified control.
657 * Parameter idx: The control index.
658 * Return: The poll count.
660 uint32_t get_polls(unsigned idx
) throw();
662 * Increment poll count on specified control.
664 * Parameter port: The port.
665 * Parameter controller: The controller
666 * Parameter ctrl: The control id.
667 * Return: The poll count pre-increment.
669 uint32_t increment_polls(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
671 unsigned i
= types
->triple_to_index(port
, controller
, ctrl
);
673 return increment_polls(i
);
678 * Increment poll count on specified index.
680 * Parameter idx: The index.
681 * Return: The poll count pre-increment.
683 uint32_t increment_polls(unsigned idx
) throw();
685 * Get highest poll counter value.
687 * - System flag counts as 1 poll.
689 * Returns: The maximum poll count (at least 1 if system flag is set).
691 uint32_t max_polls() throw();
693 * Save state to memory block.
695 * Parameter mem: The memory block to save to.
696 * Throws std::bad_alloc: Not enough memory.
698 void save_state(std::vector
<uint32_t>& mem
);
700 * Load state from memory block.
702 * Parameter mem: The block from restore from.
704 void load_state(const std::vector
<uint32_t>& mem
) throw();
706 * Check if state can be loaded without errors.
708 * Returns: True if load is possible, false otherwise.
710 bool check(const std::vector
<uint32_t>& mem
) throw();
712 * Set/Clear the frame parameters polled flag.
714 void set_framepflag(bool value
) throw();
716 * Get the frame parameters polled flag.
718 bool get_framepflag() const throw();
720 * Get raw pollcounter data.
722 const uint32_t* rawdata() const throw() { return ctrs
; }
725 const type_set
* types
;
732 * Single (sub)frame of controls.
738 * Default constructor. Invalid port types, dedicated memory.
742 * Create subframe of controls with specified controller types and dedicated memory.
744 * Parameter p: Types of ports.
746 frame(const type_set
& p
);
748 * Create subframe of controls with specified controller types and specified memory.
750 * Parameter memory: The backing memory.
751 * Parameter p: Types of ports.
752 * Parameter host: Host frame vector.
754 * Throws std::runtime_error: NULL memory.
756 frame(unsigned char* memory
, const type_set
& p
, frame_vector
* host
= NULL
);
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
);
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
);
784 unsigned get_port_count() throw()
786 return types
->ports();
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
)
803 if(memory
!= backing
)
804 throw std::runtime_error("Can't change type of mapped frame");
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
)
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
];
845 * Parameter x: The value to set the sync flag to.
847 inline void sync(bool x
) throw();
851 * Return value: Value of sync flag.
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);
867 * Returns: The number of bytes it takes to store frame of this type.
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())
885 auto& t
= types
->port_type(port
);
886 if(!port
&& !controller
&& !ctrl
&& host
)
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
);
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())
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
);
929 return axis3(t
.port
, t
.controller
, t
.control
);
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();
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())
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
);
962 * Serialize frame to text format.
964 * Parameter buf: The buffer to write NUL-terminated text representation to.
966 void serialize(char* buf
) throw()
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
)
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
))
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()
1017 unsigned char memory
[MAXIMUM_CONTROLLER_FRAME_SIZE
];
1018 unsigned char* backing
;
1020 const type_set
* types
;
1024 * Vector of controller frames.
1030 * Framecount change listener.
1032 class fchange_listener
1038 virtual ~fchange_listener();
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
);
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
);
1074 * Blank vector and change the type of ports.
1076 * Parameter p: The port types.
1078 void clear(const type_set
& p
);
1082 void clear() throw()
1087 * Get number of subframes.
1096 const type_set
& get_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
);
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
);
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
);
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
)
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;
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
);
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 * Find frame number corresponding to given subframe (0-based).
1247 int64_t subframe_to_frame(uint64_t n
);
1249 * Notify sync flag polarity change.
1251 * Parameter polarity: 1 if positive edge, -1 if negative edge. 0 is ignored.
1253 void notify_sync_change(short polarity
) {
1254 uint64_t old_frame_count
= real_frame_count
;
1255 real_frame_count
= real_frame_count
+ polarity
;
1256 if(!freeze_count
) call_framecount_notification(old_frame_count
);
1259 * Set where to deliver frame count change notifications to.
1261 * Parameter cb: Callback to register.
1262 * Returns: Handle for callback.
1264 void set_framecount_notification(fchange_listener
& cb
)
1266 threads::alock
h(mlock
);
1267 on_framecount_change
.insert(&cb
);
1270 * Clear framecount change notification.
1272 * Parameter handle: Handle to clear.
1274 void clear_framecount_notification(fchange_listener
& cb
)
1276 threads::alock
h(mlock
);
1277 on_framecount_change
.erase(&cb
);
1280 * Call framecount change notification.
1282 void call_framecount_notification(uint64_t oldcount
)
1284 std::set
<fchange_listener
*> tmp
;
1286 threads::alock
h(mlock
);
1287 tmp
= on_framecount_change
;
1290 try { i
->notify(*this, oldcount
); } catch(...) {}
1295 * Only the frame data is swapped, not the notifications.
1297 void swap_data(frame_vector
& v
) throw();
1300 * Freeze framecount notifications.
1302 struct notify_freeze
1304 notify_freeze(frame_vector
& parent
)
1307 frozen
.freeze_count
++;
1308 if(frozen
.freeze_count
== 1)
1309 frozen
.frame_count_at_freeze
= frozen
.real_frame_count
;
1313 frozen
.freeze_count
--;
1314 if(frozen
.freeze_count
== 0)
1315 frozen
.call_framecount_notification(frozen
.frame_count_at_freeze
);
1318 notify_freeze(const notify_freeze
&);
1319 notify_freeze
& operator=(const notify_freeze
&);
1320 frame_vector
& frozen
;
1323 friend class notify_freeze
;
1328 memtracker::singleton()(movie_page_id
, CONTROLLER_PAGE_SIZE
+ 36);
1329 memset(content
, 0, CONTROLLER_PAGE_SIZE
);
1331 ~page() { memtracker::singleton()(movie_page_id
, -CONTROLLER_PAGE_SIZE
- 36); }
1332 unsigned char content
[CONTROLLER_PAGE_SIZE
];
1334 size_t frames_per_page
;
1337 const type_set
* types
;
1338 size_t cache_page_num
;
1340 std::map
<size_t, page
> pages
;
1341 uint64_t real_frame_count
;
1342 uint64_t frame_count_at_freeze
;
1343 size_t freeze_count
;
1344 std::set
<fchange_listener
*> on_framecount_change
;
1345 size_t walk_helper(size_t frame
, bool sflag
) throw();
1346 threads::lock mlock
;
1353 memtracker::autorelease tracker
;
1356 void frame::sync(bool x
) throw()
1358 short old
= (backing
[0] & 1);
1363 if(host
) host
->notify_sync_change((backing
[0] & 1) - old
);
1366 void frame::deserialize(const char* buf
)
1370 for(size_t i
= 0; i
< types
->ports(); i
++) {
1372 auto& t
= types
->port_type(i
);
1373 s
= t
.deserialize(&t
, backing
+ types
->port_offset(i
), buf
+ offset
);
1374 if(s
!= DESERIALIZE_SPECIAL_BLANK
) {
1376 while(is_nonterminator(buf
[offset
]))
1378 if(buf
[offset
] == '|')
1382 if(host
) host
->notify_sync_change(sync() - old
);
1386 //Parse a controller macro.
1389 struct axis_transform
1391 axis_transform() { coeffs
[0] = coeffs
[3] = 1; coeffs
[1] = coeffs
[2] = coeffs
[4] = coeffs
[5] = 0; }
1392 axis_transform(const std::string
& expr
);
1394 int16_t transform(const button
& b
, int16_t v
);
1395 std::pair
<int16_t, int16_t> transform(const button
& b1
,
1396 const button
& b2
, int16_t v1
, int16_t v2
);
1397 static double unscale_axis(const button
& b
, int16_t v
);
1398 static int16_t scale_axis(const button
& b
, double v
);
1406 macro_data() { buttons
= 0; }
1407 macro_data(const std::string
& spec
, const JSON::node
& desc
, unsigned i
);
1408 macro_data(const JSON::node
& ser
, unsigned i
);
1409 void serialize(JSON::node
& v
);
1410 static JSON::node
make_descriptor(const controller
& ctrl
);
1411 const JSON::node
& get_descriptor() { return _descriptor
; }
1412 static bool syntax_check(const std::string
& spec
, const JSON::node
& ctrl
);
1413 void write(frame
& frame
, unsigned port
, unsigned controller
, int64_t nframe
, apply_mode amode
);
1414 std::string
dump(const controller
& ctrl
); //Mainly for debugging.
1415 size_t get_frames() { return data
.size() / get_stride(); }
1416 size_t get_stride() { return buttons
; }
1418 std::vector
<unsigned char> data
;
1419 std::vector
<std::pair
<unsigned, unsigned>> aaxes
;
1420 std::vector
<unsigned> btnmap
;
1421 std::vector
<axis_transform
> adata
;
1423 JSON::node _descriptor
;
1430 macro_data::apply_mode amode
;
1431 std::map
<unsigned, macro_data
> macros
;
1432 void write(frame
& frame
, int64_t nframe
);
1433 macro() { amode
= macro_data::AM_XOR
; }
1434 macro(const JSON::node
& ser
);
1435 JSON::node
serialize();
1440 * Get generic default system port type.
1442 type
& get_default_system_port_type();