Fix saving of movie data for port2
[lsnes.git] / include / core / controllerframe.hpp
blob134dbdc4374993a1de7f3216bb0740631ec697f9
1 #ifndef _controllerframe__hpp__included__
2 #define _controllerframe__hpp__included__
4 #include <cstring>
5 #include <climits>
6 #include <cstdlib>
7 #include <cstdio>
8 #include <cstdint>
9 #include <sstream>
10 #include <iomanip>
11 #include <iostream>
12 #include <stdexcept>
13 #include <string>
14 #include <vector>
15 #include <map>
16 #include <set>
18 /**
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
27 /**
28 * Maximum amount of data controller_frame::display() can write.
30 #define MAX_DISPLAY_LENGTH 128
31 /**
32 * Maximum amount of data controller_frame::serialize() can write.
34 #define MAX_SERIALIZED_SIZE 256
35 /**
36 * Maximum number of ports.
38 #define MAX_PORTS 2
39 /**
40 * Maximum number of controllers per one port.
42 #define MAX_CONTROLLERS_PER_PORT 4
43 /**
44 * Maximum numbers of controls per one controller.
46 #define MAX_CONTROLS_PER_CONTROLLER 12
47 /**
48 * Number of button controls.
50 #define MAX_BUTTONS MAX_PORTS * MAX_CONTROLLERS_PER_PORT * MAX_CONTROLS_PER_CONTROLLER
51 /**
52 * Size of controller page.
54 #define CONTROLLER_PAGE_SIZE 65500
55 /**
56 * Special return value for deserialize() indicating no input was taken.
58 #define DESERIALIZE_SPECIAL_BLANK 0xFFFFFFFFUL
59 /**
60 * Analog indices.
62 #define MAX_ANALOG 3
63 /**
64 * Logical button IDs.
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
84 /**
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);
93 /**
94 * This enumeration gives the type of port.
96 enum porttype_t
98 /**
99 * No device
101 PT_NONE = 0, //Nothing connected to port.
103 * Gamepad
105 PT_GAMEPAD = 1,
107 * Multitap (with 4 gamepads connected)
109 PT_MULTITAP = 2,
111 * Mouse
113 PT_MOUSE = 3,
115 * Superscope (only allowed for port 2).
117 PT_SUPERSCOPE = 4,
119 * Justifier (only allowed for port 2).
121 PT_JUSTIFIER = 5,
123 * 2 Justifiers (only allowed for port 2).
125 PT_JUSTIFIERS = 6,
127 * Number of controller types.
129 PT_LAST_CTYPE = 6,
131 * Invalid controller type.
133 PT_INVALID = PT_LAST_CTYPE + 1
137 * This enumeration gives the type of device.
139 enum devicetype_t
142 * No device
144 DT_NONE = 0,
146 * Gamepad (note that multitap controllers are gamepads)
148 DT_GAMEPAD = 1,
150 * Mouse
152 DT_MOUSE = 2,
154 * Lightgun
156 DT_LIGHTGUN = 3,
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');
171 * Read button value.
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()
179 char ch = buf[idx];
180 if(is_nonterminator(ch))
181 idx++;
182 return (ch != '|' && ch != '\r' && ch != '\n' && ch != '\0' && ch != '.' && ch != ' ' && ch != '\t');
186 * Read axis value.
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();
195 * Skip whitespace.
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')
203 idx++;
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]))
216 idx++;
217 if(include_pipe && buf[idx] == '|')
218 idx++;
222 * Serialize short.
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);
231 * Serialize short.
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.
241 struct porttype_info
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();
368 * Port type value.
370 porttype_t value;
372 * Number of bytes it takes to store this.
374 size_t storage_size;
376 * Name of port type.
378 std::string name;
379 private:
380 porttype_info(const porttype_info&);
381 porttype_info& operator=(const porttype_info&);
385 * Poll counter vector.
387 class pollcounter_vector
389 public:
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();
399 * Set all DRDY bits.
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();
496 private:
497 uint32_t ctrs[MAX_BUTTONS];
498 bool system_flag;
502 * Single (sub)frame of controls.
504 class controller_frame
506 public:
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);
546 * Get type of port.
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])
582 return false;
583 return true;
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];
600 return x;
603 * Set the sync flag.
605 * Parameter x: The value to set the sync flag to.
607 void sync(bool x) throw()
609 if(x)
610 backing[0] |= 1;
611 else
612 backing[0] &= ~1;
615 * Get the sync flag.
617 * Return value: Value of sync flag.
619 bool sync() throw()
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()
637 if(x)
638 backing[0] |= 2;
639 else
640 backing[0] &= ~2;
643 * Get the reset flag.
645 * Return value: Value of resset flag.
647 bool reset() throw()
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()
670 short x, y;
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);
678 * Get size of frame.
680 * Returns: The number of bytes it takes to store frame of this type.
682 size_t size()
684 return totalsize;
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);
743 * Get device type.
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)
761 size_t offset = 0;
762 offset += system_deserialize(backing, buf);
763 if(buf[offset] == '|')
764 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) {
768 offset += s;
769 if(buf[offset] == '|')
770 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()
781 size_t offset = 0;
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);
796 c.sync(sync);
797 return c;
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))
808 return false;
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);
853 private:
854 size_t totalsize;
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
870 public:
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);
908 * Blank vector.
910 void clear() throw()
912 clear(types[0], types[1]);
915 * Get number of subframes.
917 size_t size()
919 return frames;
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);
932 if(x >= frames)
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]);
941 * Append a subframe.
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
962 * after given frame.
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]);
1000 c.sync(sync);
1001 return c;
1003 private:
1004 class page
1006 public:
1007 page() { memset(content, 0, CONTROLLER_PAGE_SIZE); }
1008 unsigned char content[CONTROLLER_PAGE_SIZE];
1010 size_t frames_per_page;
1011 size_t frame_size;
1012 size_t frames;
1013 porttype_t types[MAX_PORTS];
1014 size_t cache_page_num;
1015 page* cache_page;
1016 std::map<size_t, page> pages;
1017 size_t walk_helper(size_t frame, bool sflag) throw();
1018 void clear_cache()
1020 cache_page_num = 0;
1021 cache_page_num--;
1022 cache_page = NULL;
1027 * Controllers state.
1029 class controller_state
1031 public:
1033 * Constructor.
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();
1065 * Set type of port.
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();
1100 * Get blank frame.
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();
1126 * Query autohold.
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();
1142 * Query button.
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();
1165 * TODO: Document.
1167 bool is_analog(unsigned pcid) throw();
1169 * TODO: Document.
1171 bool is_mouse(unsigned pcid) throw();
1172 private:
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)
1190 return;
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;
1196 if(x)
1197 buffer[bit / 8] |= (1 << (bit % 8));
1198 else
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)
1210 return 0;
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);
1218 } else
1219 return 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) {
1230 buf[0] = '\0';
1231 return;
1233 size_t ptr = 0;
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] : '-';
1243 buf[ptr] = '\0';
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";
1253 size_t ptr = 0;
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));
1266 return ptr;
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()
1284 if(!controllers)
1285 return DESERIALIZE_SPECIAL_BLANK;
1286 memset(buffer, 0, generic_port_size<controllers, analog_axis, buttons>());
1287 size_t ptr = 0;
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);
1301 return ptr;
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;
1321 #endif