1 #ifndef _controllerframe__hpp__included__
2 #define _controllerframe__hpp__included__
19 * For now, reserve 20 bytes, for:
21 * - 5 bytes for system.
22 * - 6 bytes for port 1 (multitap).
23 * - 9 bytes for port 2 (justifiers).
25 #define MAXIMUM_CONTROLLER_FRAME_SIZE 20
28 * Maximum amount of data controller_frame::display() can write.
30 #define MAX_DISPLAY_LENGTH 128
32 * Maximum amount of data controller_frame::serialize() can write.
34 #define MAX_SERIALIZED_SIZE 256
36 * Maximum number of ports.
40 * Maximum number of controllers per one port.
42 #define MAX_CONTROLLERS_PER_PORT 4
44 * Maximum numbers of controls per one controller.
46 #define MAX_CONTROLS_PER_CONTROLLER 12
48 * Number of button controls.
50 #define MAX_BUTTONS MAX_PORTS * MAX_CONTROLLERS_PER_PORT * MAX_CONTROLS_PER_CONTROLLER
52 * Size of controller page.
54 #define CONTROLLER_PAGE_SIZE 65500
56 * Special return value for deserialize() indicating no input was taken.
58 #define DESERIALIZE_SPECIAL_BLANK 0xFFFFFFFFUL
66 #define LOGICAL_BUTTON_LEFT 0
67 #define LOGICAL_BUTTON_RIGHT 1
68 #define LOGICAL_BUTTON_UP 2
69 #define LOGICAL_BUTTON_DOWN 3
70 #define LOGICAL_BUTTON_A 4
71 #define LOGICAL_BUTTON_B 5
72 #define LOGICAL_BUTTON_X 6
73 #define LOGICAL_BUTTON_Y 7
74 #define LOGICAL_BUTTON_L 8
75 #define LOGICAL_BUTTON_R 9
76 #define LOGICAL_BUTTON_SELECT 10
77 #define LOGICAL_BUTTON_START 11
78 #define LOGICAL_BUTTON_TRIGGER 12
79 #define LOGICAL_BUTTON_CURSOR 13
80 #define LOGICAL_BUTTON_TURBO 14
81 #define LOGICAL_BUTTON_PAUSE 15
82 #define MAX_LOGICAL_BUTTONS 16
85 * Get name of logical button.
87 * Parameter lbid: ID of logical button.
88 * Returns: The name of button.
89 * Throws std::bad_alloc: Not enough memory.
91 std::string
get_logical_button_name(unsigned lbid
) throw(std::bad_alloc
);
94 * This enumeration gives the type of port.
101 PT_NONE
= 0, //Nothing connected to port.
107 * Multitap (with 4 gamepads connected)
115 * Superscope (only allowed for port 2).
119 * Justifier (only allowed for port 2).
123 * 2 Justifiers (only allowed for port 2).
127 * Number of controller types.
131 * Invalid controller type.
133 PT_INVALID
= PT_LAST_CTYPE
+ 1
137 * This enumeration gives the type of device.
146 * Gamepad (note that multitap controllers are gamepads)
160 * Is not field terminator.
162 * Parameter ch: The character.
163 * Returns: True if character is not terminator, false if character is terminator.
165 inline bool is_nonterminator(char ch
) throw()
167 return (ch
!= '|' && ch
!= '\r' && ch
!= '\n' && ch
!= '\0');
173 * Parameter buf: Buffer to read from.
174 * Parameter idx: Index to buffer. Updated.
175 * Returns: The read value.
177 inline bool read_button_value(const char* buf
, size_t& idx
) throw()
180 if(is_nonterminator(ch
))
182 return (ch
!= '|' && ch
!= '\r' && ch
!= '\n' && ch
!= '\0' && ch
!= '.' && ch
!= ' ' && ch
!= '\t');
188 * Parameter buf: Buffer to read from.
189 * Parameter idx: Index to buffer. Updated.
190 * Returns: The read value.
192 short read_axis_value(const char* buf
, size_t& idx
) throw();
197 * Parameter buf: Buffer to read from.
198 * Parameter idx: Index to buffer. Updated.
200 inline void skip_field_whitespace(const char* buf
, size_t& idx
) throw()
202 while(buf
[idx
] == ' ' || buf
[idx
] == '\t')
207 * Skip rest of the field.
209 * Parameter buf: Buffer to read from.
210 * Parameter idx: Index to buffer. Updated.
211 * Parameter include_pipe: If true, also skip the '|'.
213 inline void skip_rest_of_field(const char* buf
, size_t& idx
, bool include_pipe
) throw()
215 while(is_nonterminator(buf
[idx
]))
217 if(include_pipe
&& buf
[idx
] == '|')
224 inline void serialize_short(unsigned char* buf
, short val
)
226 buf
[0] = static_cast<unsigned short>(val
) >> 8;
227 buf
[1] = static_cast<unsigned short>(val
);
233 inline short unserialize_short(const unsigned char* buf
)
235 return static_cast<short>((static_cast<unsigned short>(buf
[0]) << 8) | static_cast<unsigned short>(buf
[1]));
239 * Information about port type.
244 * Look up information about port type.
246 * Parameter p: The port type.
247 * Returns: Infor about port type.
248 * Throws std::runtime_error: Invalid port type.
250 static const porttype_info
& lookup(porttype_t p
) throw(std::runtime_error
);
252 * Look up information about port type.
254 * Parameter p: The port type string.
255 * Returns: Infor about port type.
256 * Throws std::runtime_error: Invalid port type.
258 static const porttype_info
& lookup(const std::string
& p
) throw(std::runtime_error
);
260 * Register port type.
262 * Parameter ptype: Type value for port type.
263 * Parameter pname: The name of port type.
264 * Parameter psize: The size of storage for this type.
265 * Throws std::bad_alloc: Not enough memory.
267 porttype_info(porttype_t ptype
, const std::string
& pname
, size_t psize
) throw(std::bad_alloc
);
269 * Unregister port type.
271 ~porttype_info() throw();
273 * Writes controller data into compressed representation.
275 * Parameter buffer: The buffer storing compressed representation of controller state.
276 * Parameter idx: Index of controller.
277 * Parameter ctrl: The control to manipulate.
278 * Parameter x: New value for control. Only zero/nonzero matters for buttons.
280 void (*write
)(unsigned char* buffer
, unsigned idx
, unsigned ctrl
, short x
);
282 * Read controller data from compressed representation.
284 * Parameter buffer: The buffer storing compressed representation of controller state.
285 * Parameter idx: Index of controller.
286 * Parameter ctrl: The control to query.
287 * Returns: The value of control. Buttons return 0 or 1.
289 short (*read
)(const unsigned char* buffer
, unsigned idx
, unsigned ctrl
);
291 * Format compressed controller data into input display.
293 * Parameter buffer: The buffer storing compressed representation of controller state.
294 * Parameter idx: Index of controller.
295 * Parameter buf: The buffer to write NUL-terminated display string to. Assumed to be MAX_DISPLAY_LENGTH bytes in size.
297 void (*display
)(const unsigned char* buffer
, unsigned idx
, char* buf
);
299 * Take compressed controller data and serialize it into textual representation.
301 * - The initial '|' is also written.
303 * Parameter buffer: The buffer storing compressed representation of controller state.
304 * Parameter textbuf: The text buffer to write to.
305 * Returns: Number of bytes written.
307 size_t (*serialize
)(const unsigned char* buffer
, char* textbuf
);
309 * Unserialize textual representation into compressed controller state.
311 * - Only stops reading on '|', NUL, CR or LF in the final read field. That byte is not read.
313 * Parameter buffer: The buffer storing compressed representation of controller state.
314 * Parameter textbuf: The text buffer to read.
315 * Returns: Number of bytes read.
316 * Throws std::runtime_error: Bad serialization.
318 size_t (*deserialize
)(unsigned char* buffer
, const char* textbuf
);
320 * Return device type for given index.
322 * Parameter idx: The index of controller.
323 * Returns: The type of device.
325 devicetype_t (*devicetype
)(unsigned idx
);
327 * Number of controllers connected to this port.
329 unsigned controllers
;
331 * Internal type value for port.
333 unsigned internal_type
;
335 * Return if type is legal for port.
337 * Parameter port: Number of port.
338 * Returns: True if legal, false if not.
340 bool (*legal
)(unsigned port
);
342 * Translate controller and logical button id pair into physical button id.
344 * Parameter controller: The number of controller.
345 * Parameter lbid: Logigal button ID.
346 * Returns: The physical button ID, or -1 if no such button exists.
348 virtual int button_id(unsigned controller
, unsigned lbid
) const throw() = 0;
350 * Set this controller as core controller.
352 * Parameter port: Port to set to.
354 void (*set_core_controller
)(unsigned port
);
356 * Does the controller have analog function?
358 * Parameter controller: Controller number.
360 bool is_analog(unsigned controller
) const throw();
362 * Does the controller have mouse-type function?
364 * Parameter controller: Controller number.
366 bool is_mouse(unsigned controller
) const throw();
372 * Number of bytes it takes to store this.
380 porttype_info(const porttype_info
&);
381 porttype_info
& operator=(const porttype_info
&);
385 * Poll counter vector.
387 class pollcounter_vector
391 * Create new pollcounter vector filled with all zeroes and all DRDY bits clear.
393 pollcounter_vector() throw();
395 * Zero all poll counters and clear all DRDY bits. System flag is cleared.
397 void clear() throw();
401 void set_all_DRDY() throw();
403 * Clear specified DRDY bit.
405 * Parameter pcid: The physical controller id.
406 * Parameter ctrl: The control id.
408 void clear_DRDY(unsigned pcid
, unsigned ctrl
) throw();
410 * Get state of DRDY bit.
412 * Parameter pcid: The physical controller id.
413 * Parameter ctrl: The control id.
414 * Returns: The DRDY state.
416 bool get_DRDY(unsigned pcid
, unsigned ctrl
) throw();
418 * Get state of DRDY bit.
420 * Parameter idx: The control index.
421 * Returns: The DRDY state.
423 bool get_DRDY(unsigned idx
) throw()
425 return get_DRDY(idx
/ MAX_CONTROLS_PER_CONTROLLER
, idx
% MAX_CONTROLS_PER_CONTROLLER
);
428 * Is any poll count nonzero or is system flag set?
430 * Returns: True if at least one poll count is nonzero or if system flag is set. False otherwise.
432 bool has_polled() throw();
434 * Read the actual poll count on specified control.
436 * Parameter pcid: The physical controller id.
437 * Parameter ctrl: The control id.
438 * Return: The poll count.
440 uint32_t get_polls(unsigned pcid
, unsigned ctrl
) throw();
442 * Read the actual poll count on specified control.
444 * Parameter idx: The control index.
445 * Return: The poll count.
447 uint32_t get_polls(unsigned idx
) throw()
449 return get_polls(idx
/ MAX_CONTROLS_PER_CONTROLLER
, idx
% MAX_CONTROLS_PER_CONTROLLER
);
452 * Increment poll count on specified control.
454 * Parameter pcid: The physical controller id.
455 * Parameter ctrl: The control id.
456 * Return: The poll count pre-increment.
458 uint32_t increment_polls(unsigned pcid
, unsigned ctrl
) throw();
460 * Set the system flag.
462 void set_system() throw();
464 * Get the system flag.
466 * Returns: The state of system flag.
468 bool get_system() throw();
470 * Get highest poll counter value.
472 * - System flag counts as 1 poll.
474 * Returns: The maximum poll count (at least 1 if system flag is set).
476 uint32_t max_polls() throw();
478 * Save state to memory block.
480 * Parameter mem: The memory block to save to.
481 * Throws std::bad_alloc: Not enough memory.
483 void save_state(std::vector
<uint32_t>& mem
) throw(std::bad_alloc
);
485 * Load state from memory block.
487 * Parameter mem: The block from restore from.
489 void load_state(const std::vector
<uint32_t>& mem
) throw();
491 * Check if state can be loaded without errors.
493 * Returns: True if load is possible, false otherwise.
495 bool check(const std::vector
<uint32_t>& mem
) throw();
497 uint32_t ctrs
[MAX_BUTTONS
];
502 * Single (sub)frame of controls.
504 class controller_frame
508 * Default constructor. Invalid port types, dedicated memory.
510 controller_frame() throw();
512 * Create subframe of controls with specified controller types and dedicated memory.
514 * Parameter p1: Type of port1.
515 * Parameter p2: Type of port2.
517 * Throws std::runtime_error: Invalid port type.
519 controller_frame(porttype_t p1
, porttype_t p2
) throw(std::runtime_error
);
521 * Create subframe of controls with specified controller types and specified memory.
523 * Parameter memory: The backing memory.
524 * Parameter p1: Type of port1.
525 * Parameter p2: Type of port2.
527 * Throws std::runtime_error: Invalid port type or NULL memory.
529 controller_frame(unsigned char* memory
, porttype_t p1
= PT_GAMEPAD
, porttype_t p2
= PT_NONE
)
530 throw(std::runtime_error
);
532 * Copy construct a frame. The memory will be dedicated.
534 * Parameter obj: The object to copy.
536 controller_frame(const controller_frame
& obj
) throw();
538 * Assign a frame. The types must either match or memory must be dedicated.
540 * Parameter obj: The object to copy.
541 * Returns: Reference to this.
542 * Throws std::runtime_error: The types don't match and memory is not dedicated.
544 controller_frame
& operator=(const controller_frame
& obj
) throw(std::runtime_error
);
548 * Parameter port: Number of port.
549 * Returns: The type of port.
551 porttype_t
get_port_type(unsigned port
) throw()
553 return (port
< MAX_PORTS
) ? types
[port
] : PT_NONE
;
556 * Get blank dedicated frame of same port types.
558 * Return blank frame.
560 controller_frame
blank_frame() throw()
562 return controller_frame(types
[0], types
[1]);
565 * Set type of port. Input for that port is zeroized.
567 * Parameter port: Number of port.
568 * Parameter type: The new type.
569 * Throws std::runtime_error: Bad port type or non-dedicated memory.
571 void set_port_type(unsigned port
, porttype_t ptype
) throw(std::runtime_error
);
573 * Check that types match.
575 * Parameter obj: Another object.
576 * Returns: True if types match, false otherwise.
578 bool types_match(const controller_frame
& obj
) const throw()
580 for(size_t i
= 0; i
< MAX_PORTS
; i
++)
581 if(types
[i
] != obj
.types
[i
])
586 * Perform XOR between controller frames.
588 * Parameter another: The another object.
589 * Returns: The XOR result (dedicated memory).
590 * Throws std::runtime_error: Type mismatch.
592 controller_frame
operator^(const controller_frame
& another
) throw(std::runtime_error
)
594 controller_frame
x(*this);
595 for(size_t i
= 0; i
< MAX_PORTS
; i
++)
596 if(types
[i
] != another
.types
[i
])
597 throw std::runtime_error("controller_frame::operator^: Type mismatch");
598 for(size_t i
= 0; i
< totalsize
; i
++)
599 x
.backing
[i
] ^= another
.backing
[i
];
605 * Parameter x: The value to set the sync flag to.
607 void sync(bool x
) throw()
617 * Return value: Value of sync flag.
621 return ((backing
[0] & 1) != 0);
624 * Quick get sync flag for buffer.
626 static bool sync(const unsigned char* mem
) throw()
628 return ((mem
[0] & 1) != 0);
631 * Set the reset flag.
633 * Parameter x: The value to set the reset flag to.
635 void reset(bool x
) throw()
643 * Get the reset flag.
645 * Return value: Value of resset flag.
649 return ((backing
[0] & 2) != 0);
652 * Set the reset delay.
654 * Parameter x: The value to set reset delay to.
656 void delay(std::pair
<short, short> x
) throw()
658 backing
[1] = static_cast<unsigned short>(x
.first
) >> 8;
659 backing
[2] = static_cast<unsigned short>(x
.first
);
660 backing
[3] = static_cast<unsigned short>(x
.second
) >> 8;
661 backing
[4] = static_cast<unsigned short>(x
.second
);
664 * Get the reset delay.
666 * Return value: Value of reset delay.
668 std::pair
<short, short> delay() throw()
671 x
= static_cast<short>(static_cast<unsigned short>(backing
[1]) << 8);
672 x
|= static_cast<short>(static_cast<unsigned short>(backing
[2]));
673 y
= static_cast<short>(static_cast<unsigned short>(backing
[3]) << 8);
674 y
|= static_cast<short>(static_cast<unsigned short>(backing
[4]));
675 return std::make_pair(x
, y
);
680 * Returns: The number of bytes it takes to store frame of this type.
687 * Set axis/button value.
689 * Parameter pcid: Physical controller id.
690 * Parameter ctrl: The control id.
691 * Parameter x: The new value.
693 void axis(unsigned pcid
, unsigned ctrl
, short x
) throw()
695 unsigned port
= (pcid
/ MAX_CONTROLLERS_PER_PORT
) % MAX_PORTS
;
696 pinfo
[port
]->write(backing
+ offsets
[port
], pcid
% MAX_CONTROLLERS_PER_PORT
, ctrl
, x
);
699 * Set axis/button value.
701 * Parameter idx: Control index.
702 * Parameter x: The new value.
704 void axis2(unsigned idx
, short x
) throw()
706 axis(idx
/ MAX_CONTROLS_PER_CONTROLLER
, idx
% MAX_CONTROLS_PER_CONTROLLER
, x
);
709 * Get axis/button value.
711 * Parameter pcid: Physical controller id.
712 * Parameter ctrl: The control id.
713 * Return value: The axis value.
715 short axis(unsigned pcid
, unsigned ctrl
) throw()
717 unsigned port
= (pcid
/ MAX_CONTROLLERS_PER_PORT
) % MAX_PORTS
;
718 return pinfo
[port
]->read(backing
+ offsets
[port
], pcid
% MAX_CONTROLLERS_PER_PORT
, ctrl
);
722 * Get axis/button value.
724 * Parameter idx: Index of control.
725 * Return value: The axis value.
727 short axis2(unsigned idx
) throw()
729 return axis(idx
/ MAX_CONTROLS_PER_CONTROLLER
, idx
% MAX_CONTROLS_PER_CONTROLLER
);
732 * Get controller display.
734 * Parameter pcid: Physical controller id.
735 * Parameter buf: Buffer to write nul-terminated display to.
737 void display(unsigned pcid
, char* buf
) throw()
739 unsigned port
= (pcid
/ MAX_CONTROLLERS_PER_PORT
) % MAX_PORTS
;
740 return pinfo
[port
]->display(backing
+ offsets
[port
], pcid
% MAX_CONTROLLERS_PER_PORT
, buf
);
745 * Parameter pcid: Physical controller id.
746 * Returns: Device type.
748 devicetype_t
devicetype(unsigned pcid
) throw()
750 unsigned port
= (pcid
/ MAX_CONTROLLERS_PER_PORT
) % MAX_PORTS
;
751 return pinfo
[port
]->devicetype(pcid
% MAX_CONTROLLERS_PER_PORT
);
754 * Deserialize frame from text format.
756 * Parameter buf: The buffer containing text representation. Terminated by NUL, CR or LF.
757 * Throws std::runtime_error: Bad serialized representation.
759 void deserialize(const char* buf
) throw(std::runtime_error
)
762 offset
+= system_deserialize(backing
, buf
);
763 if(buf
[offset
] == '|')
765 for(size_t i
= 0; i
< MAX_PORTS
; i
++) {
766 size_t s
= pinfo
[i
]->deserialize(backing
+ offsets
[i
], buf
+ offset
);
767 if(s
!= DESERIALIZE_SPECIAL_BLANK
) {
769 if(buf
[offset
] == '|')
775 * Serialize frame to text format.
777 * Parameter buf: The buffer to write NUL-terminated text representation to.
779 void serialize(char* buf
) throw()
782 offset
+= system_serialize(backing
, buf
);
783 for(size_t i
= 0; i
< MAX_PORTS
; i
++)
784 offset
+= pinfo
[i
]->serialize(backing
+ offsets
[i
], buf
+ offset
);
785 buf
[offset
++] = '\0';
788 * Return copy with dedicated memory.
790 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
791 * Returns: Copy of this frame.
793 controller_frame
copy(bool sync
)
795 controller_frame
c(*this);
800 * Compare two frames.
802 * Parameter obj: Another frame.
803 * Returns: True if equal, false if not.
805 bool operator==(const controller_frame
& obj
) const throw()
807 if(!types_match(obj
))
809 return !memcmp(backing
, obj
.backing
, totalsize
);
812 * Compare two frames.
814 * Parameter obj: Another frame.
815 * Returns: True if not equal, false if equal.
817 bool operator!=(const controller_frame
& obj
) const throw()
819 return !(*this == obj
);
822 * Get physical button ID for physical controller ID and logical button ID.
824 * Parameter pcid: Physical controller id.
825 * Parameter lbid: Logical button id.
826 * Returns: The physical button id, or -1 if no such button.
828 int button_id(unsigned pcid
, unsigned lbid
)
830 unsigned port
= (pcid
/ MAX_CONTROLLERS_PER_PORT
) % MAX_PORTS
;
831 return pinfo
[port
]->button_id(pcid
% MAX_CONTROLLERS_PER_PORT
, lbid
);
834 * Does the specified controller have analog function.
836 * Parameter pcid: Physical controller id.
838 bool is_analog(unsigned pcid
)
840 unsigned port
= (pcid
/ MAX_CONTROLLERS_PER_PORT
) % MAX_PORTS
;
841 return pinfo
[port
]->is_analog(pcid
% MAX_CONTROLLERS_PER_PORT
);
844 * Does the specified controller have mouse-type function.
846 * Parameter pcid: Physical controller id.
848 bool is_mouse(unsigned pcid
)
850 unsigned port
= (pcid
/ MAX_CONTROLLERS_PER_PORT
) % MAX_PORTS
;
851 return pinfo
[port
]->is_mouse(pcid
% MAX_CONTROLLERS_PER_PORT
);
855 unsigned char memory
[MAXIMUM_CONTROLLER_FRAME_SIZE
];
856 unsigned char* backing
;
857 porttype_t types
[MAX_PORTS
];
858 size_t offsets
[MAX_PORTS
];
859 const porttype_info
* pinfo
[MAX_PORTS
];
860 static size_t system_serialize(const unsigned char* buffer
, char* textbuf
);
861 static size_t system_deserialize(unsigned char* buffer
, const char* textbuf
);
862 void set_types(const porttype_t
* tarr
);
866 * Vector of controller frames.
868 class controller_frame_vector
872 * Construct new controller frame vector.
874 * Parameter p1: Type of port 1.
875 * Parameter p2: Type of port 2.
876 * Throws std::runtime_error: Illegal port types.
878 controller_frame_vector(enum porttype_t p1
= PT_INVALID
, enum porttype_t p2
= PT_INVALID
)
879 throw(std::runtime_error
);
881 * Destroy controller frame vector
883 ~controller_frame_vector() throw();
885 * Copy controller frame vector.
887 * Parameter obj: The object to copy.
888 * Throws std::bad_alloc: Not enough memory.
890 controller_frame_vector(const controller_frame_vector
& vector
) throw(std::bad_alloc
);
892 * Assign controller frame vector.
894 * Parameter obj: The object to copy.
895 * Returns: Reference to this.
896 * Throws std::bad_alloc: Not enough memory.
898 controller_frame_vector
& operator=(const controller_frame_vector
& vector
) throw(std::bad_alloc
);
900 * Blank vector and change the type of ports.
902 * Parameter p1: Type of port 1.
903 * Parameter p2: Type of port 2.
904 * Throws std::runtime_error: Illegal port types.
906 void clear(enum porttype_t p1
, enum porttype_t p2
) throw(std::runtime_error
);
912 clear(types
[0], types
[1]);
915 * Get number of subframes.
922 * Access specified subframe.
924 * Parameter x: The frame number.
925 * Returns: The controller frame.
926 * Throws std::runtime_error: Invalid frame index.
928 controller_frame
operator[](size_t x
)
930 size_t page
= x
/ frames_per_page
;
931 size_t pageoffset
= frame_size
* (x
% frames_per_page
);
933 throw std::runtime_error("controller_frame_vector::operator[]: Illegal index");
934 if(page
!= cache_page_num
) {
935 cache_page
= &pages
[page
];
936 cache_page_num
= page
;
938 return controller_frame(cache_page
->content
+ pageoffset
, types
[0], types
[1]);
943 * Parameter frame: The frame to append.
944 * Throws std::bad_alloc: Not enough memory.
945 * Throws std::runtime_error: Port type mismatch.
947 void append(controller_frame frame
) throw(std::bad_alloc
, std::runtime_error
);
949 * Change length of vector.
951 * - Reducing length of vector will discard extra elements.
952 * - Extending length of vector will add all-zero elements.
954 * Parameter newsize: New size of vector.
955 * Throws std::bad_alloc: Not enough memory.
957 void resize(size_t newsize
) throw(std::bad_alloc
);
959 * Walk the indexes of sync subframes.
961 * - If frame is in range and there is at least one more sync subframe after it, the index of first sync subframe
963 * - If frame is in range, but there are no more sync subframes after it, the length of vector is returned.
964 * - If frame is out of range, the given frame is returned.
966 * Parameter frame: The frame number to start search from.
967 * Returns: Index of next sync frame.
969 size_t walk_sync(size_t frame
) throw()
971 return walk_helper(frame
, true);
974 * Get number of subframes in frame. The given subframe is assumed to be sync subframe.
976 * - The return value is the same as (walk_sync(frame) - frame).
978 * Parameter frame: The frame number to start search from.
979 * Returns: Number of subframes in this frame.
981 size_t subframe_count(size_t frame
) throw()
983 return walk_helper(frame
, false);
986 * Count number of subframes in vector with sync flag set.
988 * Returns: The number of frames.
990 size_t count_frames() throw();
992 * Return blank controller frame with correct type and dedicated memory.
994 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
995 * Returns: Blank frame.
997 controller_frame
blank_frame(bool sync
)
999 controller_frame
c(types
[0], types
[1]);
1007 page() { memset(content
, 0, CONTROLLER_PAGE_SIZE
); }
1008 unsigned char content
[CONTROLLER_PAGE_SIZE
];
1010 size_t frames_per_page
;
1013 porttype_t types
[MAX_PORTS
];
1014 size_t cache_page_num
;
1016 std::map
<size_t, page
> pages
;
1017 size_t walk_helper(size_t frame
, bool sflag
) throw();
1027 * Controllers state.
1029 class controller_state
1035 controller_state() throw();
1037 * Convert lcid (Logical Controller ID) into pcid (Physical Controler ID).
1039 * Parameter lcid: The logical controller ID.
1040 * Return: The physical controller ID, or -1 if no such controller exists.
1042 int lcid_to_pcid(unsigned lcid
) throw();
1044 * Convert acid (Analog Controller ID) into pcid.
1046 * Parameter acid: The analog controller ID.
1047 * Return: The physical controller ID, or -1 if no such controller exists.
1049 int acid_to_pcid(unsigned acid
) throw();
1051 * Is given acid a mouse?
1053 * Parameter acid: The analog controller ID.
1054 * Returns: True if given acid is mouse, false otherwise.
1056 bool acid_is_mouse(unsigned acid
) throw();
1058 * Look up device type type of given pcid.
1060 * Parameter pcid: The physical controller id.
1061 * Returns: The type of device.
1063 devicetype_t
pcid_to_type(unsigned pcid
) throw();
1067 * Parameter port: The port to set.
1068 * Parameter ptype: The new type for port.
1069 * Parameter set_core: If true, set the core port type too, otherwise don't do that.
1070 * Throws std::runtime_error: Illegal port type.
1072 void set_port(unsigned port
, porttype_t ptype
, bool set_core
) throw(std::runtime_error
);
1074 * Get status of current controls (with autohold/autofire factored in).
1076 * Parameter framenum: Number of current frame (for evaluating autofire).
1077 * Returns: The current controls.
1079 controller_frame
get(uint64_t framenum
) throw();
1081 * Commit given controls (autohold/autofire is factored in).
1083 * Parameter framenum: Number of current frame (for evaluating autofire).
1084 * Returns: The committed controls.
1086 controller_frame
commit(uint64_t framenum
) throw();
1088 * Commit given controls (autohold/autofire is ignored).
1090 * Parameter controls: The controls to commit
1091 * Returns: The committed controls.
1093 controller_frame
commit(controller_frame controls
) throw();
1095 * Get status of committed controls.
1096 * Returns: The committed controls.
1098 controller_frame
get_committed() throw();
1102 controller_frame
get_blank() throw();
1104 * Send analog input to given acid.
1106 * Parameter acid: The acid to send input to.
1107 * Parameter x: The x coordinate to send.
1108 * Parameter y: The x coordinate to send.
1110 void analog(unsigned acid
, int x
, int y
) throw();
1112 * Manipulate the reset flag.
1114 * Parameter delay: Delay for reset (-1 for no reset)
1116 void reset(int32_t delay
) throw();
1118 * Manipulate autohold.
1120 * Parameter pcid: The physical controller ID to manipulate.
1121 * Parameter pbid: The physical button ID to manipulate.
1122 * Parameter newstate: The new state for autohold.
1124 void autohold(unsigned pcid
, unsigned pbid
, bool newstate
) throw();
1128 * Parameter pcid: The physical controller ID to query.
1129 * Parameter pbid: The physical button ID to query.
1130 * Returns: The state of autohold.
1132 bool autohold(unsigned pcid
, unsigned pbid
) throw();
1134 * Manipulate button.
1136 * Parameter pcid: The physical controller ID to manipulate.
1137 * Parameter pbid: The physical button ID to manipulate.
1138 * Parameter newstate: The new state for button.
1140 void button(unsigned pcid
, unsigned pbid
, bool newstate
) throw();
1144 * Parameter pcid: The physical controller ID to query.
1145 * Parameter pbid: The physical button ID to query.
1146 * Returns: The state of button.
1148 bool button(unsigned pcid
, unsigned pbid
) throw();
1150 * Set autofire pattern.
1152 * Parameter pattern: The new pattern.
1153 * Throws std::bad_alloc: Not enough memory.
1155 void autofire(std::vector
<controller_frame
> pattern
) throw(std::bad_alloc
);
1157 * Get physical button ID for physical controller ID and logical button ID.
1159 * Parameter pcid: Physical controller id.
1160 * Parameter lbid: Logical button id.
1161 * Returns: The physical button id, or -1 if no such button.
1163 int button_id(unsigned pcid
, unsigned lbid
) throw();
1167 bool is_analog(unsigned pcid
) throw();
1171 bool is_mouse(unsigned pcid
) throw();
1173 const porttype_info
* porttypeinfo
[MAX_PORTS
];
1174 porttype_t porttypes
[MAX_PORTS
];
1175 int analog_indices
[MAX_ANALOG
];
1176 bool analog_mouse
[MAX_ANALOG
];
1177 controller_frame _input
;
1178 controller_frame _autohold
;
1179 controller_frame _committed
;
1180 std::vector
<controller_frame
> _autofire
;
1184 * Generic port write function.
1186 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
>
1187 inline void generic_port_write(unsigned char* buffer
, unsigned idx
, unsigned ctrl
, short x
) throw()
1189 if(idx
>= controllers
)
1191 if(ctrl
< analog_axis
) {
1192 buffer
[2 * idx
* analog_axis
+ 2 * ctrl
] = (x
>> 8);
1193 buffer
[2 * idx
* analog_axis
+ 2 * ctrl
+ 1] = x
;
1194 } else if(ctrl
< analog_axis
+ buttons
) {
1195 size_t bit
= 16 * controllers
* analog_axis
+ idx
* buttons
+ ctrl
- analog_axis
;
1197 buffer
[bit
/ 8] |= (1 << (bit
% 8));
1199 buffer
[bit
/ 8] &= ~(1 << (bit
% 8));
1204 * Generic port read function.
1206 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
>
1207 inline short generic_port_read(const unsigned char* buffer
, unsigned idx
, unsigned ctrl
) throw()
1209 if(idx
>= controllers
)
1211 if(ctrl
< analog_axis
) {
1212 uint16_t a
= buffer
[2 * idx
* analog_axis
+ 2 * ctrl
];
1213 uint16_t b
= buffer
[2 * idx
* analog_axis
+ 2 * ctrl
+ 1];
1214 return static_cast<short>(256 * a
+ b
);
1215 } else if(ctrl
< analog_axis
+ buttons
) {
1216 size_t bit
= 16 * controllers
* analog_axis
+ idx
* buttons
+ ctrl
- analog_axis
;
1217 return ((buffer
[bit
/ 8] & (1 << (bit
% 8))) != 0);
1223 * Generic port display function.
1225 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
, unsigned sidx
>
1226 inline void generic_port_display(const unsigned char* buffer
, unsigned idx
, char* buf
) throw()
1228 const char sym
[] = "BYsSudlrAXLRTSTCUP";
1229 if(idx
> controllers
) {
1234 for(unsigned i
= 0; i
< analog_axis
; i
++) {
1235 uint16_t a
= buffer
[2 * idx
* analog_axis
+ 2 * i
];
1236 uint16_t b
= buffer
[2 * idx
* analog_axis
+ 2 * i
+ 1];
1237 ptr
+= sprintf(buf
+ ptr
, "%i ", static_cast<short>(256 * a
+ b
));
1239 for(unsigned i
= 0; i
< buttons
; i
++) {
1240 size_t bit
= 16 * controllers
* analog_axis
+ idx
* buttons
+ i
;
1241 buf
[ptr
++] = ((buffer
[bit
/ 8] & (1 << (bit
% 8))) != 0) ? sym
[i
+ sidx
] : '-';
1247 * Generic port serialization function.
1249 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
, unsigned sidx
>
1250 inline size_t generic_port_serialize(const unsigned char* buffer
, char* textbuf
) throw()
1252 const char sym
[] = "BYsSudlrAXLRTSTCUP";
1254 for(unsigned j
= 0; j
< controllers
; j
++) {
1255 textbuf
[ptr
++] = '|';
1256 for(unsigned i
= 0; i
< buttons
; i
++) {
1257 size_t bit
= 16 * controllers
* analog_axis
+ j
* buttons
+ i
;
1258 textbuf
[ptr
++] = ((buffer
[bit
/ 8] & (1 << (bit
% 8))) != 0) ? sym
[i
+ sidx
] : '.';
1260 for(unsigned i
= 0; i
< analog_axis
; i
++) {
1261 uint16_t a
= buffer
[2 * j
* analog_axis
+ 2 * i
];
1262 uint16_t b
= buffer
[2 * j
* analog_axis
+ 2 * i
+ 1];
1263 ptr
+= sprintf(textbuf
+ ptr
, " %i", static_cast<short>(256 * a
+ b
));
1270 * Generic port size function.
1272 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
>
1273 inline size_t generic_port_size()
1275 return 2 * controllers
* analog_axis
+ (controllers
* buttons
+ 7) / 8;
1279 * Generic port deserialization function.
1281 template<unsigned controllers
, unsigned analog_axis
, unsigned buttons
>
1282 inline size_t generic_port_deserialize(unsigned char* buffer
, const char* textbuf
) throw()
1285 return DESERIALIZE_SPECIAL_BLANK
;
1286 memset(buffer
, 0, generic_port_size
<controllers
, analog_axis
, buttons
>());
1288 for(unsigned j
= 0; j
< controllers
; j
++) {
1289 for(unsigned i
= 0; i
< buttons
; i
++) {
1290 size_t bit
= 16 * controllers
* analog_axis
+ j
* buttons
+ i
;
1291 if(read_button_value(textbuf
, ptr
))
1292 buffer
[bit
/ 8] |= (1 << (bit
% 8));
1294 for(unsigned i
= 0; i
< analog_axis
; i
++) {
1295 short v
= read_axis_value(textbuf
, ptr
);
1296 buffer
[2 * j
* analog_axis
+ 2 * i
] = v
>> 8;
1297 buffer
[2 * j
* analog_axis
+ 2 * i
+ 1] = v
;
1299 skip_rest_of_field(textbuf
, ptr
, j
+ 1 < controllers
);
1304 template<unsigned mask
>
1305 inline bool generic_port_legal(unsigned port
) throw()
1307 if(port
>= CHAR_BIT
* sizeof(unsigned))
1308 port
= CHAR_BIT
* sizeof(unsigned) - 1;
1309 return ((mask
>> port
) & 1);
1313 * Generic port type function.
1315 template<unsigned controllers
, devicetype_t dtype
>
1316 inline devicetype_t
generic_port_devicetype(unsigned idx
) throw()
1318 return (idx
< controllers
) ? dtype
: DT_NONE
;