1 #ifndef _library__controller_data__hpp__included__
2 #define _library__controller_data__hpp__included__
21 * Memory to allocate for controller frame.
23 #define MAXIMUM_CONTROLLER_FRAME_SIZE 128
25 * Maximum amount of data controller_frame::display() can write.
27 #define MAX_DISPLAY_LENGTH 128
29 * Maximum amount of data controller_frame::serialize() can write.
31 #define MAX_SERIALIZED_SIZE 256
33 * Size of controller page.
35 #define CONTROLLER_PAGE_SIZE 65500
37 * Special return value for deserialize() indicating no input was taken.
39 #define DESERIALIZE_SPECIAL_BLANK 0xFFFFFFFFUL
42 * Is not field terminator.
44 * Parameter ch: The character.
45 * Returns: True if character is not terminator, false if character is terminator.
47 inline bool is_nonterminator(char ch
) throw()
49 return (ch
!= '|' && ch
!= '\r' && ch
!= '\n' && ch
!= '\0');
55 * Parameter buf: Buffer to read from.
56 * Parameter idx: Index to buffer. Updated.
57 * Returns: The read value.
59 inline bool read_button_value(const char* buf
, size_t& idx
) throw()
62 if(is_nonterminator(ch
))
64 return (ch
!= '|' && ch
!= '\r' && ch
!= '\n' && ch
!= '\0' && ch
!= '.' && ch
!= ' ' && ch
!= '\t');
70 * Parameter buf: Buffer to read from.
71 * Parameter idx: Index to buffer. Updated.
72 * Returns: The read value.
74 short read_axis_value(const char* buf
, size_t& idx
) throw();
79 * Parameter buf: Buffer to read from.
80 * Parameter idx: Index to buffer. Updated.
82 inline void skip_field_whitespace(const char* buf
, size_t& idx
) throw()
84 while(buf
[idx
] == ' ' || buf
[idx
] == '\t')
89 * Skip rest of the field.
91 * Parameter buf: Buffer to read from.
92 * Parameter idx: Index to buffer. Updated.
93 * Parameter include_pipe: If true, also skip the '|'.
95 inline void skip_rest_of_field(const char* buf
, size_t& idx
, bool include_pipe
) throw()
97 while(is_nonterminator(buf
[idx
]))
99 if(include_pipe
&& buf
[idx
] == '|')
106 inline void serialize_short(unsigned char* buf
, short val
)
108 buf
[0] = static_cast<unsigned short>(val
) >> 8;
109 buf
[1] = static_cast<unsigned short>(val
);
115 inline short unserialize_short(const unsigned char* buf
)
117 return static_cast<short>((static_cast<unsigned short>(buf
[0]) << 8) | static_cast<unsigned short>(buf
[1]));
123 * Group of port types.
125 class port_type_group
131 * Throws std::bad_alloc: Not enough memory.
133 port_type_group() throw(std::bad_alloc
);
137 ~port_type_group() throw();
139 * Get port type with specified name.
141 * Parameter name: The name of port type.
142 * Returns: The port type structure.
143 * Throws std::runtime_error: Specified port type unknown.
145 port_type
& get_type(const std::string
& name
) const throw(std::runtime_error
);
147 * Get set of all port types.
149 * Returns: The set of all port types.
150 * Throws std::bad_alloc: Not enough memory.
152 std::set
<port_type
*> get_types() const throw(std::bad_alloc
);
154 * Get default port type for specified port.
156 * Parameter port: The port.
157 * Returns: The default port type.
158 * Throws std::runtime_error: Bad port.
160 port_type
& get_default_type(unsigned port
) const throw(std::runtime_error
);
164 * Parameter type: Name of the type.
165 * Parameter port: The port type structure.
166 * Throws std::bad_alloc: Not enough memory.
168 void register_type(const std::string
& type
, port_type
& port
);
170 * Remove a port type.
172 * Parameter type: Name of the type.
173 * Throws std::bad_alloc: Not enough memory.
175 void unregister_type(const std::string
& type
);
177 * Set default type for port.
179 * Parameter port: The port.
180 * Parameter ptype: The port type to make default.
182 void set_default(unsigned port
, port_type
& ptype
);
184 std::map
<std::string
, port_type
*> types
;
185 std::map
<unsigned, port_type
*> defaults
;
189 * Type of controller.
195 * Create a new port type.
197 * Parameter group: The group the type will belong to.
198 * Parameter iname: Internal name of the port type.
199 * Parameter hname: Human-readable name of the port type.
200 * Parameter id: Identifier.
201 * Parameter ssize: The storage size in bytes.
202 * Throws std::bad_alloc: Not enough memory.
204 port_type(port_type_group
& group
, const std::string
& iname
, const std::string
& hname
, unsigned id
,
205 size_t ssize
) throw(std::bad_alloc
);
207 * Unregister a port type.
209 virtual ~port_type() throw();
211 * Writes controller data into compressed representation.
213 * Parameter buffer: The buffer storing compressed representation of controller state.
214 * Parameter idx: Index of controller.
215 * Parameter ctrl: The control to manipulate.
216 * Parameter x: New value for control. Only zero/nonzero matters for buttons.
218 void (*write
)(unsigned char* buffer
, unsigned idx
, unsigned ctrl
, short x
);
220 * Read controller data from compressed representation.
222 * Parameter buffer: The buffer storing compressed representation of controller state.
223 * Parameter idx: Index of controller.
224 * Parameter ctrl: The control to query.
225 * Returns: The value of control. Buttons return 0 or 1.
227 short (*read
)(const unsigned char* buffer
, unsigned idx
, unsigned ctrl
);
229 * Format compressed controller data into input display.
231 * Parameter buffer: The buffer storing compressed representation of controller state.
232 * Parameter idx: Index of controller.
233 * Parameter buf: The buffer to write NUL-terminated display string to. Assumed to be MAX_DISPLAY_LENGTH bytes in size.
235 void (*display
)(const unsigned char* buffer
, unsigned idx
, char* buf
);
237 * Take compressed controller data and serialize it into textual representation.
239 * - The initial '|' is also written.
241 * Parameter buffer: The buffer storing compressed representation of controller state.
242 * Parameter textbuf: The text buffer to write to.
243 * Returns: Number of bytes written.
245 size_t (*serialize
)(const unsigned char* buffer
, char* textbuf
);
247 * Unserialize textual representation into compressed controller state.
249 * - Only stops reading on '|', NUL, CR or LF in the final read field. That byte is not read.
251 * Parameter buffer: The buffer storing compressed representation of controller state.
252 * Parameter textbuf: The text buffer to read.
253 * Returns: Number of bytes read.
254 * Throws std::runtime_error: Bad serialization.
256 size_t (*deserialize
)(unsigned char* buffer
, const char* textbuf
);
258 * Get device flags for given index.
260 * Parameter idx: The index of controller.
261 * Returns: The device flags.
263 * Bit 1: Has absolute analog axes 0 and 1.
264 * Bit 2: Has relative analog axes 0 and 1.
266 unsigned (*deviceflags
)(unsigned idx
);
268 * Is the device legal for port?
270 * Parameter port: Port to query.
271 * Returns: Nonzero if legal, zero if illegal.
273 int (*legal
)(unsigned port
);
275 * Number of controllers connected to this port.
277 unsigned controllers
;
279 * Translate controller and logical button id pair into physical button id.
281 * Parameter controller: The number of controller.
282 * Parameter lbid: Logigal button ID.
283 * Returns: The physical button ID, or -1 if no such button exists.
285 int (*button_id
)(unsigned controller
, unsigned lbid
);
287 * Set this controller as core controller.
289 * Parameter port: Port to set to.
291 void (*set_core_controller
)(unsigned port
);
293 * Does the controller exist?
295 * Parameter controller: Controller number.
297 bool is_present(unsigned controller
) const throw();
299 * Does the controller have analog function?
301 * Parameter controller: Controller number.
303 bool is_analog(unsigned controller
) const throw();
305 * Does the controller have mouse-type function?
307 * Parameter controller: Controller number.
309 bool is_mouse(unsigned controller
) const throw();
311 * Number of control indices claimed.
313 unsigned index_count
;
315 * Number of control indices used per controller.
317 unsigned* controller_indices
;
319 * Human-readable name.
323 * Number of bytes it takes to store this.
331 * Name of controller.
333 std::string ctrlname
;
343 * Group this port is in.
345 port_type_group
& ingroup
;
347 port_type(const port_type
&);
348 port_type
& operator=(const port_type
&);
352 * A set of port types.
358 * Controller index triplet.
363 triplet(unsigned p
, unsigned c
, unsigned i
) : port(p
), controller(c
), control(i
) {}
369 * Create empty port type set.
371 port_type_set() throw();
373 * Make a port type set with specified types. If called again with the same parameters, returns the same object.
375 * Parameter types: The types.
376 * Throws std::bad_alloc: Not enough memory.
377 * Throws std::runtime_error: Illegal port types.
379 static port_type_set
& make(std::vector
<port_type
*> types
) throw(std::bad_alloc
, std::runtime_error
);
381 * Compare sets for equality.
383 bool operator==(const port_type_set
& s
) const throw() { return this == &s
; }
385 * Compare sets for non-equality.
387 bool operator!=(const port_type_set
& s
) const throw() { return this != &s
; }
389 * Get offset of specified port.
391 * Parameter port: The number of port.
392 * Returns: The offset of port.
393 * Throws std::runtime_error: Bad port number.
395 size_t port_offset(unsigned port
) const throw(std::runtime_error
)
397 if(port
>= port_count
)
398 throw std::runtime_error("Invalid port index");
399 return port_offsets
[port
];
402 * Get type of specified port.
404 * Parameter port: The number of port.
405 * Returns: The port type.
406 * Throws std::runtime_error: Bad port number.
408 const class port_type
& port_type(unsigned port
) const throw(std::runtime_error
)
410 if(port
>= port_count
)
411 throw std::runtime_error("Invalid port index");
412 return *(port_types
[port
]);
415 * Get number of ports.
417 * Returns: The port count.
419 unsigned ports() const throw()
424 * Get total size of controller data.
428 unsigned size() const throw()
433 * Get total index count.
435 unsigned indices() const throw()
440 * Look up the triplet for given control.
442 * Parameter index: The index to look up.
443 * Returns: The triplet (may have out of range indices)
444 * Throws std::runtime_error: Index out of range.
446 triplet
index_to_triple(unsigned index
) const throw(std::runtime_error
)
448 if(index
>= index_count
)
449 throw std::runtime_error("Invalid index");
450 return triples
[index
];
453 * Translate triplet into index.
455 * Parameter port: The port.
456 * Parameter controller: The controller.
457 * Parameter index: The control index.
458 * Returns: The index.
459 * Throws std::runtime_error: No such triplet.
461 unsigned triple_to_index(unsigned port
, unsigned controller
, unsigned index
) const throw(std::runtime_error
)
463 size_t i
= port
* triple_port_m
+ controller
* triple_controller_m
+ index
;
464 if(i
>= indexes_size
|| indexes_tab
[i
] == 0xFFFFFFFFUL
)
466 return indexes_tab
[i
];
469 port_type_set(std::vector
<class port_type
*> types
);
470 size_t* port_offsets
;
471 class port_type
** port_types
;
473 unsigned index_count
;
475 size_t triple_port_m
;
476 size_t triple_controller_m
;
478 unsigned* indexes_tab
;
483 * Poll counter vector.
485 class pollcounter_vector
489 * Create new pollcounter vector filled with all zeroes and all DRDY bits clear.
491 * Throws std::bad_alloc: Not enough memory.
493 pollcounter_vector() throw(std::bad_alloc
);
495 * Create new pollcounter vector suitably sized for given type set.
497 * Parameter p: The port types.
498 * Throws std::bad_alloc: Not enough memory.
500 pollcounter_vector(const port_type_set
& p
) throw(std::bad_alloc
);
504 ~pollcounter_vector() throw();
506 * Copy the pollcounter_vector.
508 pollcounter_vector(const pollcounter_vector
& v
) throw(std::bad_alloc
);
510 * Assign the pollcounter_vector.
512 pollcounter_vector
& operator=(const pollcounter_vector
& v
) throw(std::bad_alloc
);
514 * Zero all poll counters and clear all DRDY bits. System flag is cleared.
516 void clear() throw();
520 void set_all_DRDY() throw();
522 * Clear specified DRDY bit.
524 * Parameter port: The port.
525 * Parameter controller: The controller
526 * Parameter ctrl: The control id.
528 void clear_DRDY(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
530 unsigned i
= types
->triple_to_index(port
, controller
, ctrl
);
535 * Clear state of DRDY bit.
537 * Parameter idx: The control index.
539 void clear_DRDY(unsigned idx
) throw();
541 * Get state of DRDY bit.
543 * Parameter port: The port.
544 * Parameter controller: The controller
545 * Parameter ctrl: The control id.
546 * Returns: The DRDY state.
548 bool get_DRDY(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
550 unsigned i
= types
->triple_to_index(port
, controller
, ctrl
);
557 * Get state of DRDY bit.
559 * Parameter idx: The control index.
560 * Returns: The DRDY state.
562 bool get_DRDY(unsigned idx
) throw();
564 * Is any poll count nonzero or is system flag set?
566 * Returns: True if at least one poll count is nonzero or if system flag is set. False otherwise.
568 bool has_polled() throw();
570 * Read the actual poll count on specified control.
572 * Parameter port: The port.
573 * Parameter controller: The controller
574 * Parameter ctrl: The control id.
575 * Return: The poll count.
577 uint32_t get_polls(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
579 unsigned i
= types
->triple_to_index(port
, controller
, ctrl
);
586 * Read the actual poll count on specified control.
588 * Parameter idx: The control index.
589 * Return: The poll count.
591 uint32_t get_polls(unsigned idx
) throw();
593 * Increment poll count on specified control.
595 * Parameter port: The port.
596 * Parameter controller: The controller
597 * Parameter ctrl: The control id.
598 * Return: The poll count pre-increment.
600 uint32_t increment_polls(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
602 unsigned i
= types
->triple_to_index(port
, controller
, ctrl
);
604 return increment_polls(i
);
609 * Increment poll count on specified index.
611 * Parameter idx: The index.
612 * Return: The poll count pre-increment.
614 uint32_t increment_polls(unsigned idx
) throw();
616 * Get highest poll counter value.
618 * - System flag counts as 1 poll.
620 * Returns: The maximum poll count (at least 1 if system flag is set).
622 uint32_t max_polls() throw();
624 * Save state to memory block.
626 * Parameter mem: The memory block to save to.
627 * Throws std::bad_alloc: Not enough memory.
629 void save_state(std::vector
<uint32_t>& mem
) throw(std::bad_alloc
);
631 * Load state from memory block.
633 * Parameter mem: The block from restore from.
635 void load_state(const std::vector
<uint32_t>& mem
) throw();
637 * Check if state can be loaded without errors.
639 * Returns: True if load is possible, false otherwise.
641 bool check(const std::vector
<uint32_t>& mem
) throw();
644 const port_type_set
* types
;
648 * Single (sub)frame of controls.
650 class controller_frame
654 * Default constructor. Invalid port types, dedicated memory.
656 controller_frame() throw();
658 * Create subframe of controls with specified controller types and dedicated memory.
660 * Parameter p: Types of ports.
662 controller_frame(const port_type_set
& p
) throw(std::runtime_error
);
664 * Create subframe of controls with specified controller types and specified memory.
666 * Parameter memory: The backing memory.
667 * Parameter p: Types of ports.
669 * Throws std::runtime_error: NULL memory.
671 controller_frame(unsigned char* memory
, const port_type_set
& p
) throw(std::runtime_error
);
673 * Copy construct a frame. The memory will be dedicated.
675 * Parameter obj: The object to copy.
677 controller_frame(const controller_frame
& obj
) throw();
679 * Assign a frame. The types must either match or memory must be dedicated.
681 * Parameter obj: The object to copy.
682 * Returns: Reference to this.
683 * Throws std::runtime_error: The types don't match and memory is not dedicated.
685 controller_frame
& operator=(const controller_frame
& obj
) throw(std::runtime_error
);
689 * Parameter port: Number of port.
690 * Returns: The type of port.
692 const port_type
& get_port_type(unsigned port
) throw()
694 return types
->port_type(port
);
699 unsigned get_port_count() throw()
701 return types
->ports();
706 unsigned get_index_count() throw()
708 return types
->indices();
711 * Set types of ports.
713 * Parameter ptype: New port types.
714 * Throws std::runtime_error: Memory is mapped.
716 void set_types(const port_type_set
& ptype
) throw(std::runtime_error
)
718 if(memory
!= backing
)
719 throw std::runtime_error("Can't change type of mapped controller_frame");
723 * Get blank dedicated frame of same port types.
725 * Return blank frame.
727 controller_frame
blank_frame() throw()
729 return controller_frame(*types
);
732 * Check that types match.
734 * Parameter obj: Another object.
735 * Returns: True if types match, false otherwise.
737 bool types_match(const controller_frame
& obj
) const throw()
739 return types
== obj
.types
;
742 * Perform XOR between controller frames.
744 * Parameter another: The another object.
745 * Returns: The XOR result (dedicated memory).
746 * Throws std::runtime_error: Type mismatch.
748 controller_frame
operator^(const controller_frame
& another
) throw(std::runtime_error
)
750 controller_frame
x(*this);
751 if(types
!= another
.types
)
752 throw std::runtime_error("controller_frame::operator^: Type mismatch");
753 for(size_t i
= 0; i
< types
->size(); i
++)
754 x
.backing
[i
] ^= another
.backing
[i
];
760 * Parameter x: The value to set the sync flag to.
762 void sync(bool x
) throw()
772 * Return value: Value of sync flag.
776 return ((backing
[0] & 1) != 0);
779 * Quick get sync flag for buffer.
781 static bool sync(const unsigned char* mem
) throw()
783 return ((mem
[0] & 1) != 0);
788 * Returns: The number of bytes it takes to store frame of this type.
792 return types
->size();
795 * Set axis/button value.
797 * Parameter port: The port.
798 * Parameter controller: The controllre
799 * Parameter ctrl: The control id.
800 * Parameter x: The new value.
802 void axis3(unsigned port
, unsigned controller
, unsigned ctrl
, short x
) throw()
804 if(port
>= types
->ports())
806 types
->port_type(port
).write(backing
+ types
->port_offset(port
), controller
, ctrl
, x
);
809 * Set axis/button value.
811 * Parameter idx: Control index.
812 * Parameter x: The new value.
814 void axis2(unsigned idx
, short x
) throw()
816 port_type_set::triplet t
= types
->index_to_triple(idx
);
817 axis3(t
.port
, t
.controller
, t
.control
, x
);
820 * Get axis/button value.
822 * Parameter port: The port.
823 * Parameter controller: The controller
824 * Parameter ctrl: The control id.
825 * Return value: The axis value.
827 short axis3(unsigned port
, unsigned controller
, unsigned ctrl
) throw()
829 if(port
>= types
->ports())
831 return types
->port_type(port
).read(backing
+ types
->port_offset(port
), controller
, ctrl
);
835 * Get axis/button value.
837 * Parameter idx: Index of control.
838 * Return value: The axis value.
840 short axis2(unsigned idx
) throw()
842 port_type_set::triplet t
= types
->index_to_triple(idx
);
843 return axis3(t
.port
, t
.controller
, t
.control
);
846 * Get controller display.
848 * Parameter port: The port.
849 * Parameter controller: The controller
850 * Parameter buf: Buffer to write nul-terminated display to.
852 void display(unsigned port
, unsigned controller
, char* buf
) throw()
854 if(port
>= types
->ports()) {
858 types
->port_type(port
).display(backing
+ types
->port_offset(port
), controller
, buf
);
863 * Parameter port: The port.
864 * Parameter controller: The controller
865 * Returns: True if present, false if not.
867 bool is_present(unsigned port
, unsigned controller
) throw()
869 if(port
>= types
->ports())
871 return types
->port_type(port
).is_present(controller
);
874 * Deserialize frame from text format.
876 * Parameter buf: The buffer containing text representation. Terminated by NUL, CR or LF.
877 * Throws std::runtime_error: Bad serialized representation.
879 void deserialize(const char* buf
) throw(std::runtime_error
)
882 for(size_t i
= 0; i
< types
->ports(); i
++) {
884 s
= types
->port_type(i
).deserialize(backing
+ types
->port_offset(i
), buf
+ offset
);
885 if(s
!= DESERIALIZE_SPECIAL_BLANK
) {
887 while(is_nonterminator(buf
[offset
]))
889 if(buf
[offset
] == '|')
895 * Serialize frame to text format.
897 * Parameter buf: The buffer to write NUL-terminated text representation to.
899 void serialize(char* buf
) throw()
902 for(size_t i
= 0; i
< types
->ports(); i
++)
903 offset
+= types
->port_type(i
).serialize(backing
+ types
->port_offset(i
), buf
+ offset
);
904 buf
[offset
++] = '\0';
907 * Return copy with dedicated memory.
909 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
910 * Returns: Copy of this frame.
912 controller_frame
copy(bool sync
)
914 controller_frame
c(*this);
919 * Compare two frames.
921 * Parameter obj: Another frame.
922 * Returns: True if equal, false if not.
924 bool operator==(const controller_frame
& obj
) const throw()
926 if(!types_match(obj
))
928 return !memcmp(backing
, obj
.backing
, types
->size());
931 * Compare two frames.
933 * Parameter obj: Another frame.
934 * Returns: True if not equal, false if equal.
936 bool operator!=(const controller_frame
& obj
) const throw()
938 return !(*this == obj
);
941 * Get physical button ID for physical controller ID and logical button ID.
943 * Parameter port: The port.
944 * Parameter controller: The controller
945 * Parameter lbid: Logical button id.
946 * Returns: The physical button id, or -1 if no such button.
948 int button_id(unsigned port
, unsigned controller
, unsigned lbid
)
950 if(port
>= types
->ports())
952 return types
->port_type(port
).button_id(controller
, lbid
);
955 * Does the specified controller have analog function.
957 * Parameter port: The port.
958 * Parameter controller: The controller
960 bool is_analog(unsigned port
, unsigned controller
)
962 if(port
>= types
->ports())
964 return types
->port_type(port
).is_analog(controller
);
967 * Does the specified controller have mouse-type function.
969 * Parameter port: The port.
970 * Parameter controller: The controller
972 bool is_mouse(unsigned port
, unsigned controller
)
974 if(port
>= types
->ports())
976 return types
->port_type(port
).is_mouse(controller
);
979 unsigned char memory
[MAXIMUM_CONTROLLER_FRAME_SIZE
];
980 unsigned char* backing
;
981 const port_type_set
* types
;
985 * Vector of controller frames.
987 class controller_frame_vector
991 * Construct new controller frame vector.
993 controller_frame_vector() throw();
995 * Construct new controller frame vector.
997 * Parameter p: The port types.
999 controller_frame_vector(const port_type_set
& p
) throw();
1001 * Destroy controller frame vector
1003 ~controller_frame_vector() throw();
1005 * Copy controller frame vector.
1007 * Parameter obj: The object to copy.
1008 * Throws std::bad_alloc: Not enough memory.
1010 controller_frame_vector(const controller_frame_vector
& vector
) throw(std::bad_alloc
);
1012 * Assign controller frame vector.
1014 * Parameter obj: The object to copy.
1015 * Returns: Reference to this.
1016 * Throws std::bad_alloc: Not enough memory.
1018 controller_frame_vector
& operator=(const controller_frame_vector
& vector
) throw(std::bad_alloc
);
1020 * Blank vector and change the type of ports.
1022 * Parameter p: The port types.
1024 void clear(const port_type_set
& p
) throw(std::runtime_error
);
1028 void clear() throw()
1033 * Get number of subframes.
1042 const port_type_set
& get_types()
1047 * Access specified subframe.
1049 * Parameter x: The frame number.
1050 * Returns: The controller frame.
1051 * Throws std::runtime_error: Invalid frame index.
1053 controller_frame
operator[](size_t x
)
1055 size_t page
= x
/ frames_per_page
;
1056 size_t pageoffset
= frame_size
* (x
% frames_per_page
);
1058 throw std::runtime_error("controller_frame_vector::operator[]: Illegal index");
1059 if(page
!= cache_page_num
) {
1060 cache_page
= &pages
[page
];
1061 cache_page_num
= page
;
1063 return controller_frame(cache_page
->content
+ pageoffset
, *types
);
1066 * Append a subframe.
1068 * Parameter frame: The frame to append.
1069 * Throws std::bad_alloc: Not enough memory.
1070 * Throws std::runtime_error: Port type mismatch.
1072 void append(controller_frame frame
) throw(std::bad_alloc
, std::runtime_error
);
1074 * Change length of vector.
1076 * - Reducing length of vector will discard extra elements.
1077 * - Extending length of vector will add all-zero elements.
1079 * Parameter newsize: New size of vector.
1080 * Throws std::bad_alloc: Not enough memory.
1082 void resize(size_t newsize
) throw(std::bad_alloc
);
1084 * Walk the indexes of sync subframes.
1086 * - If frame is in range and there is at least one more sync subframe after it, the index of first sync subframe
1087 * after given frame.
1088 * - If frame is in range, but there are no more sync subframes after it, the length of vector is returned.
1089 * - If frame is out of range, the given frame is returned.
1091 * Parameter frame: The frame number to start search from.
1092 * Returns: Index of next sync frame.
1094 size_t walk_sync(size_t frame
) throw()
1096 return walk_helper(frame
, true);
1099 * Get number of subframes in frame. The given subframe is assumed to be sync subframe.
1101 * - The return value is the same as (walk_sync(frame) - frame).
1103 * Parameter frame: The frame number to start search from.
1104 * Returns: Number of subframes in this frame.
1106 size_t subframe_count(size_t frame
) throw()
1108 return walk_helper(frame
, false);
1111 * Count number of subframes in vector with sync flag set.
1113 * Returns: The number of frames.
1115 size_t count_frames() throw();
1117 * Return blank controller frame with correct type and dedicated memory.
1119 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
1120 * Returns: Blank frame.
1122 controller_frame
blank_frame(bool sync
)
1124 controller_frame
c(*types
);
1132 page() { memset(content
, 0, CONTROLLER_PAGE_SIZE
); }
1133 unsigned char content
[CONTROLLER_PAGE_SIZE
];
1135 size_t frames_per_page
;
1138 const port_type_set
* types
;
1139 size_t cache_page_num
;
1141 std::map
<size_t, page
> pages
;
1142 size_t walk_helper(size_t frame
, bool sflag
) throw();
1152 * Get a dummy port type.
1154 * Return value: Dummy port type.
1156 port_type
& get_dummy_port_type() throw(std::bad_alloc
);
1159 * Generic port write function.
1161 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
>
1162 inline void generic_port_write(unsigned char* buffer
, unsigned idx
, unsigned ctrl
, short x
) throw()
1164 if(idx
>= controllers
)
1166 if(ctrl
< analog_axis
) {
1167 buffer
[2 * idx
* analog_axis
+ 2 * ctrl
] = (x
>> 8);
1168 buffer
[2 * idx
* analog_axis
+ 2 * ctrl
+ 1] = x
;
1169 } else if(ctrl
< analog_axis
+ buttons
) {
1170 size_t bit
= 16 * controllers
* analog_axis
+ idx
* buttons
+ ctrl
- analog_axis
;
1172 buffer
[bit
/ 8] |= (1 << (bit
% 8));
1174 buffer
[bit
/ 8] &= ~(1 << (bit
% 8));
1179 * Generic port read function.
1181 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
>
1182 inline short generic_port_read(const unsigned char* buffer
, unsigned idx
, unsigned ctrl
) throw()
1184 if(idx
>= controllers
)
1186 if(ctrl
< analog_axis
) {
1187 uint16_t a
= buffer
[2 * idx
* analog_axis
+ 2 * ctrl
];
1188 uint16_t b
= buffer
[2 * idx
* analog_axis
+ 2 * ctrl
+ 1];
1189 return static_cast<short>(256 * a
+ b
);
1190 } else if(ctrl
< analog_axis
+ buttons
) {
1191 size_t bit
= 16 * controllers
* analog_axis
+ idx
* buttons
+ ctrl
- analog_axis
;
1192 return ((buffer
[bit
/ 8] & (1 << (bit
% 8))) != 0);
1197 extern const char* button_symbols
;
1200 * Generic port display function.
1202 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
, unsigned sidx
>
1203 inline void generic_port_display(const unsigned char* buffer
, unsigned idx
, char* buf
) throw()
1205 if(idx
> controllers
) {
1210 for(unsigned i
= 0; i
< analog_axis
; i
++) {
1211 uint16_t a
= buffer
[2 * idx
* analog_axis
+ 2 * i
];
1212 uint16_t b
= buffer
[2 * idx
* analog_axis
+ 2 * i
+ 1];
1213 ptr
+= sprintf(buf
+ ptr
, "%i ", static_cast<short>(256 * a
+ b
));
1215 for(unsigned i
= 0; i
< buttons
; i
++) {
1216 size_t bit
= 16 * controllers
* analog_axis
+ idx
* buttons
+ i
;
1217 buf
[ptr
++] = ((buffer
[bit
/ 8] & (1 << (bit
% 8))) != 0) ? button_symbols
[i
+ sidx
] : '-';
1223 * Generic port serialization function.
1225 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
, unsigned sidx
>
1226 inline size_t generic_port_serialize(const unsigned char* buffer
, char* textbuf
) throw()
1229 for(unsigned j
= 0; j
< controllers
; j
++) {
1230 textbuf
[ptr
++] = '|';
1231 for(unsigned i
= 0; i
< buttons
; i
++) {
1232 size_t bit
= 16 * controllers
* analog_axis
+ j
* buttons
+ i
;
1233 textbuf
[ptr
++] = ((buffer
[bit
/ 8] & (1 << (bit
% 8))) != 0) ? button_symbols
[i
+ sidx
] : '.';
1235 for(unsigned i
= 0; i
< analog_axis
; i
++) {
1236 uint16_t a
= buffer
[2 * j
* analog_axis
+ 2 * i
];
1237 uint16_t b
= buffer
[2 * j
* analog_axis
+ 2 * i
+ 1];
1238 ptr
+= sprintf(textbuf
+ ptr
, " %i", static_cast<short>(256 * a
+ b
));
1245 * Generic port size function.
1247 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
>
1248 inline size_t generic_port_size()
1250 return 2 * controllers
* analog_axis
+ (controllers
* buttons
+ 7) / 8;
1254 * Generic port deserialization function.
1256 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
>
1257 inline size_t generic_port_deserialize(unsigned char* buffer
, const char* textbuf
) throw()
1260 return DESERIALIZE_SPECIAL_BLANK
;
1261 memset(buffer
, 0, generic_port_size
<controllers
, analog_axis
, buttons
>());
1263 for(unsigned j
= 0; j
< controllers
; j
++) {
1264 for(unsigned i
= 0; i
< buttons
; i
++) {
1265 size_t bit
= 16 * controllers
* analog_axis
+ j
* buttons
+ i
;
1266 if(read_button_value(textbuf
, ptr
))
1267 buffer
[bit
/ 8] |= (1 << (bit
% 8));
1269 for(unsigned i
= 0; i
< analog_axis
; i
++) {
1270 short v
= read_axis_value(textbuf
, ptr
);
1271 buffer
[2 * j
* analog_axis
+ 2 * i
] = v
>> 8;
1272 buffer
[2 * j
* analog_axis
+ 2 * i
+ 1] = v
;
1274 skip_rest_of_field(textbuf
, ptr
, j
+ 1 < controllers
);
1279 template<unsigned mask
>
1280 inline int generic_port_legal(unsigned port
) throw()
1282 if(port
>= CHAR_BIT
* sizeof(unsigned))
1283 port
= CHAR_BIT
* sizeof(unsigned) - 1;
1284 return ((mask
>> port
) & 1);
1288 * Generic port type function.
1290 template<unsigned controllers
, unsigned flags
>
1291 inline unsigned generic_port_deviceflags(unsigned idx
) throw()
1293 return (idx
< controllers
) ? flags
: 0;