Make mouse be ordinary keys instead of being special
[lsnes.git] / include / core / controllerframe.hpp
blob4533ae6bf5fe1b3cfc008ac64bd5761877db3420
1 #ifndef _controllerframe__hpp__included__
2 #define _controllerframe__hpp__included__
4 #include <cstring>
5 #include <cstdlib>
6 #include <cstdint>
7 #include <stdexcept>
8 #include <string>
9 #include <vector>
10 #include <map>
11 #include <set>
13 /**
14 * For now, reserve 20 bytes, for:
16 * - 5 bytes for system.
17 * - 6 bytes for port 1 (multitap).
18 * - 9 bytes for port 2 (justifiers).
20 #define MAXIMUM_CONTROLLER_FRAME_SIZE 20
22 /**
23 * Maximum amount of data controller_frame::display() can write.
25 #define MAX_DISPLAY_LENGTH 128
26 /**
27 * Maximum amount of data controller_frame::serialize() can write.
29 #define MAX_SERIALIZED_SIZE 256
30 /**
31 * Maximum number of ports.
33 #define MAX_PORTS 2
34 /**
35 * Maximum number of controllers per one port.
37 #define MAX_CONTROLLERS_PER_PORT 4
38 /**
39 * Maximum numbers of controls per one controller.
41 #define MAX_CONTROLS_PER_CONTROLLER 12
42 /**
43 * Number of button controls.
45 #define MAX_BUTTONS MAX_PORTS * MAX_CONTROLLERS_PER_PORT * MAX_CONTROLS_PER_CONTROLLER
46 /**
47 * Size of controller page.
49 #define CONTROLLER_PAGE_SIZE 65500
50 /**
51 * Special return value for deserialize() indicating no input was taken.
53 #define DESERIALIZE_SPECIAL_BLANK 0xFFFFFFFFUL
54 /**
55 * Analog indices.
57 #define MAX_ANALOG 3
58 /**
59 * Logical button IDs.
61 #define LOGICAL_BUTTON_LEFT 0
62 #define LOGICAL_BUTTON_RIGHT 1
63 #define LOGICAL_BUTTON_UP 2
64 #define LOGICAL_BUTTON_DOWN 3
65 #define LOGICAL_BUTTON_A 4
66 #define LOGICAL_BUTTON_B 5
67 #define LOGICAL_BUTTON_X 6
68 #define LOGICAL_BUTTON_Y 7
69 #define LOGICAL_BUTTON_L 8
70 #define LOGICAL_BUTTON_R 9
71 #define LOGICAL_BUTTON_SELECT 10
72 #define LOGICAL_BUTTON_START 11
73 #define LOGICAL_BUTTON_TRIGGER 12
74 #define LOGICAL_BUTTON_CURSOR 13
75 #define LOGICAL_BUTTON_TURBO 14
76 #define LOGICAL_BUTTON_PAUSE 15
77 #define MAX_LOGICAL_BUTTONS 16
79 /**
80 * Get name of logical button.
82 * Parameter lbid: ID of logical button.
83 * Returns: The name of button.
84 * Throws std::bad_alloc: Not enough memory.
86 std::string get_logical_button_name(unsigned lbid) throw(std::bad_alloc);
88 /**
89 * This enumeration gives the type of port.
91 enum porttype_t
93 /**
94 * No device
96 PT_NONE = 0, //Nothing connected to port.
97 /**
98 * Gamepad
100 PT_GAMEPAD = 1,
102 * Multitap (with 4 gamepads connected)
104 PT_MULTITAP = 2,
106 * Mouse
108 PT_MOUSE = 3,
110 * Superscope (only allowed for port 2).
112 PT_SUPERSCOPE = 4,
114 * Justifier (only allowed for port 2).
116 PT_JUSTIFIER = 5,
118 * 2 Justifiers (only allowed for port 2).
120 PT_JUSTIFIERS = 6,
122 * Number of controller types.
124 PT_LAST_CTYPE = 6,
126 * Invalid controller type.
128 PT_INVALID = PT_LAST_CTYPE + 1
132 * This enumeration gives the type of device.
134 enum devicetype_t
137 * No device
139 DT_NONE = 0,
141 * Gamepad (note that multitap controllers are gamepads)
143 DT_GAMEPAD = 1,
145 * Mouse
147 DT_MOUSE = 3,
149 * Superscope
151 DT_SUPERSCOPE = 4,
153 * Justifier (note that justifiers is two of these).
155 DT_JUSTIFIER = 5
159 * Is not field terminator.
161 * Parameter ch: The character.
162 * Returns: True if character is not terminator, false if character is terminator.
164 inline bool is_nonterminator(char ch) throw()
166 return (ch != '|' && ch != '\r' && ch != '\n' && ch != '\0');
170 * Read button value.
172 * Parameter buf: Buffer to read from.
173 * Parameter idx: Index to buffer. Updated.
174 * Returns: The read value.
176 inline bool read_button_value(const char* buf, size_t& idx) throw()
178 char ch = buf[idx];
179 if(is_nonterminator(ch))
180 idx++;
181 return (ch != '|' && ch != '\r' && ch != '\n' && ch != '\0' && ch != '.' && ch != ' ' && ch != '\t');
185 * Read axis value.
187 * Parameter buf: Buffer to read from.
188 * Parameter idx: Index to buffer. Updated.
189 * Returns: The read value.
191 short read_axis_value(const char* buf, size_t& idx) throw();
194 * Skip whitespace.
196 * Parameter buf: Buffer to read from.
197 * Parameter idx: Index to buffer. Updated.
199 inline void skip_field_whitespace(const char* buf, size_t& idx) throw()
201 while(buf[idx] == ' ' || buf[idx] == '\t')
202 idx++;
206 * Skip rest of the field.
208 * Parameter buf: Buffer to read from.
209 * Parameter idx: Index to buffer. Updated.
210 * Parameter include_pipe: If true, also skip the '|'.
212 inline void skip_rest_of_field(const char* buf, size_t& idx, bool include_pipe) throw()
214 while(is_nonterminator(buf[idx]))
215 idx++;
216 if(include_pipe && buf[idx] == '|')
217 idx++;
221 * Serialize short.
223 inline void serialize_short(unsigned char* buf, short val)
225 buf[0] = static_cast<unsigned short>(val) >> 8;
226 buf[1] = static_cast<unsigned short>(val);
230 * Serialize short.
232 inline short unserialize_short(const unsigned char* buf)
234 return static_cast<short>((static_cast<unsigned short>(buf[0]) << 8) | static_cast<unsigned short>(buf[1]));
238 * Information about port type.
240 struct porttype_info
243 * Look up information about port type.
245 * Parameter p: The port type.
246 * Returns: Infor about port type.
247 * Throws std::runtime_error: Invalid port type.
249 static const porttype_info& lookup(porttype_t p) throw(std::runtime_error);
251 * Look up information about port type.
253 * Parameter p: The port type string.
254 * Returns: Infor about port type.
255 * Throws std::runtime_error: Invalid port type.
257 static const porttype_info& lookup(const std::string& p) throw(std::runtime_error);
259 * Register port type.
261 * Parameter ptype: Type value for port type.
262 * Parameter pname: The name of port type.
263 * Parameter psize: The size of storage for this type.
264 * Throws std::bad_alloc: Not enough memory.
266 porttype_info(porttype_t ptype, const std::string& pname, size_t psize) throw(std::bad_alloc);
268 * Unregister port type.
270 ~porttype_info() throw();
272 * Writes controller data into compressed representation.
274 * Parameter buffer: The buffer storing compressed representation of controller state.
275 * Parameter idx: Index of controller.
276 * Parameter ctrl: The control to manipulate.
277 * Parameter x: New value for control. Only zero/nonzero matters for buttons.
279 virtual void write(unsigned char* buffer, unsigned idx, unsigned ctrl, short x) const throw() = 0;
281 * Read controller data from compressed representation.
283 * Parameter buffer: The buffer storing compressed representation of controller state.
284 * Parameter idx: Index of controller.
285 * Parameter ctrl: The control to query.
286 * Returns: The value of control. Buttons return 0 or 1.
288 virtual short read(const unsigned char* buffer, unsigned idx, unsigned ctrl) const throw() = 0;
290 * Format compressed controller data into input display.
292 * Parameter buffer: The buffer storing compressed representation of controller state.
293 * Parameter idx: Index of controller.
294 * Parameter buf: The buffer to write NUL-terminated display string to. Assumed to be MAX_DISPLAY_LENGTH bytes in size.
296 virtual void display(const unsigned char* buffer, unsigned idx, char* buf) const throw() = 0;
298 * Take compressed controller data and serialize it into textual representation.
300 * - The initial '|' is also written.
302 * Parameter buffer: The buffer storing compressed representation of controller state.
303 * Parameter textbuf: The text buffer to write to.
304 * Returns: Number of bytes written.
306 virtual size_t serialize(const unsigned char* buffer, char* textbuf) const throw() = 0;
308 * Unserialize textual representation into compressed controller state.
310 * - Only stops reading on '|', NUL, CR or LF in the final read field. That byte is not read.
312 * Parameter buffer: The buffer storing compressed representation of controller state.
313 * Parameter textbuf: The text buffer to read.
314 * Returns: Number of bytes read.
315 * Throws std::runtime_error: Bad serialization.
317 virtual size_t deserialize(unsigned char* buffer, const char* textbuf) const throw() = 0;
319 * Return device type for given index.
321 * Parameter idx: The index of controller.
322 * Returns: The type of device.
324 virtual devicetype_t devicetype(unsigned idx) const throw() = 0;
326 * Number of controllers connected to this port.
328 virtual unsigned controllers() const throw() = 0;
330 * Internal type value for port.
332 virtual unsigned internal_type() const throw() = 0;
334 * Return if type is legal for port.
336 * Parameter port: Number of port.
337 * Returns: True if legal, false if not.
339 virtual bool legal(unsigned port) const throw() = 0;
341 * Translate controller and logical button id pair into physical button id.
343 * Parameter controller: The number of controller.
344 * Parameter lbid: Logigal button ID.
345 * Returns: The physical button ID, or -1 if no such button exists.
347 virtual int button_id(unsigned controller, unsigned lbid) const throw() = 0;
349 * Set this controller as core controller.
351 * Parameter port: Port to set to.
353 virtual void set_core_controller(unsigned port) const throw() = 0;
355 * Does the controller have analog function?
357 * Parameter controller: Controller number.
359 virtual bool is_analog(unsigned controller) const throw() = 0;
361 * Does the controller have mouse-type function?
363 * Parameter controller: Controller number.
365 virtual bool is_mouse(unsigned controller) const throw() = 0;
367 * Port type value.
369 porttype_t value;
371 * Number of bytes it takes to store this.
373 size_t storage_size;
375 * Name of port type.
377 std::string name;
378 private:
379 porttype_info(const porttype_info&);
380 porttype_info& operator=(const porttype_info&);
384 * Poll counter vector.
386 class pollcounter_vector
388 public:
390 * Create new pollcounter vector filled with all zeroes and all DRDY bits clear.
392 pollcounter_vector() throw();
394 * Zero all poll counters and clear all DRDY bits. System flag is cleared.
396 void clear() throw();
398 * Set all DRDY bits.
400 void set_all_DRDY() throw();
402 * Clear specified DRDY bit.
404 * Parameter pcid: The physical controller id.
405 * Parameter ctrl: The control id.
407 void clear_DRDY(unsigned pcid, unsigned ctrl) throw();
409 * Get state of DRDY bit.
411 * Parameter pcid: The physical controller id.
412 * Parameter ctrl: The control id.
413 * Returns: The DRDY state.
415 bool get_DRDY(unsigned pcid, unsigned ctrl) throw();
417 * Get state of DRDY bit.
419 * Parameter idx: The control index.
420 * Returns: The DRDY state.
422 bool get_DRDY(unsigned idx) throw()
424 return get_DRDY(idx / MAX_CONTROLS_PER_CONTROLLER, idx % MAX_CONTROLS_PER_CONTROLLER);
427 * Is any poll count nonzero or is system flag set?
429 * Returns: True if at least one poll count is nonzero or if system flag is set. False otherwise.
431 bool has_polled() throw();
433 * Read the actual poll count on specified control.
435 * Parameter pcid: The physical controller id.
436 * Parameter ctrl: The control id.
437 * Return: The poll count.
439 uint32_t get_polls(unsigned pcid, unsigned ctrl) throw();
441 * Read the actual poll count on specified control.
443 * Parameter idx: The control index.
444 * Return: The poll count.
446 uint32_t get_polls(unsigned idx) throw()
448 return get_polls(idx / MAX_CONTROLS_PER_CONTROLLER, idx % MAX_CONTROLS_PER_CONTROLLER);
451 * Increment poll count on specified control.
453 * Parameter pcid: The physical controller id.
454 * Parameter ctrl: The control id.
455 * Return: The poll count pre-increment.
457 uint32_t increment_polls(unsigned pcid, unsigned ctrl) throw();
459 * Set the system flag.
461 void set_system() throw();
463 * Get the system flag.
465 * Returns: The state of system flag.
467 bool get_system() throw();
469 * Get highest poll counter value.
471 * - System flag counts as 1 poll.
473 * Returns: The maximum poll count (at least 1 if system flag is set).
475 uint32_t max_polls() throw();
477 * Save state to memory block.
479 * Parameter mem: The memory block to save to.
480 * Throws std::bad_alloc: Not enough memory.
482 void save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc);
484 * Load state from memory block.
486 * Parameter mem: The block from restore from.
488 void load_state(const std::vector<uint32_t>& mem) throw();
490 * Check if state can be loaded without errors.
492 * Returns: True if load is possible, false otherwise.
494 bool check(const std::vector<uint32_t>& mem) throw();
495 private:
496 uint32_t ctrs[MAX_BUTTONS];
497 bool system_flag;
501 * Single (sub)frame of controls.
503 class controller_frame
505 public:
507 * Default constructor. Invalid port types, dedicated memory.
509 controller_frame() throw();
511 * Create subframe of controls with specified controller types and dedicated memory.
513 * Parameter p1: Type of port1.
514 * Parameter p2: Type of port2.
516 * Throws std::runtime_error: Invalid port type.
518 controller_frame(porttype_t p1, porttype_t p2) throw(std::runtime_error);
520 * Create subframe of controls with specified controller types and specified memory.
522 * Parameter memory: The backing memory.
523 * Parameter p1: Type of port1.
524 * Parameter p2: Type of port2.
526 * Throws std::runtime_error: Invalid port type or NULL memory.
528 controller_frame(unsigned char* memory, porttype_t p1 = PT_GAMEPAD, porttype_t p2 = PT_NONE)
529 throw(std::runtime_error);
531 * Copy construct a frame. The memory will be dedicated.
533 * Parameter obj: The object to copy.
535 controller_frame(const controller_frame& obj) throw();
537 * Assign a frame. The types must either match or memory must be dedicated.
539 * Parameter obj: The object to copy.
540 * Returns: Reference to this.
541 * Throws std::runtime_error: The types don't match and memory is not dedicated.
543 controller_frame& operator=(const controller_frame& obj) throw(std::runtime_error);
545 * Get type of port.
547 * Parameter port: Number of port.
548 * Returns: The type of port.
550 porttype_t get_port_type(unsigned port) throw()
552 return (port < MAX_PORTS) ? types[port] : PT_NONE;
555 * Get blank dedicated frame of same port types.
557 * Return blank frame.
559 controller_frame blank_frame() throw()
561 return controller_frame(types[0], types[1]);
564 * Set type of port. Input for that port is zeroized.
566 * Parameter port: Number of port.
567 * Parameter type: The new type.
568 * Throws std::runtime_error: Bad port type or non-dedicated memory.
570 void set_port_type(unsigned port, porttype_t ptype) throw(std::runtime_error);
572 * Check that types match.
574 * Parameter obj: Another object.
575 * Returns: True if types match, false otherwise.
577 bool types_match(const controller_frame& obj) const throw()
579 for(size_t i = 0; i < MAX_PORTS; i++)
580 if(types[i] != obj.types[i])
581 return false;
582 return true;
585 * Perform XOR between controller frames.
587 * Parameter another: The another object.
588 * Returns: The XOR result (dedicated memory).
589 * Throws std::runtime_error: Type mismatch.
591 controller_frame operator^(const controller_frame& another) throw(std::runtime_error)
593 controller_frame x(*this);
594 for(size_t i = 0; i < MAX_PORTS; i++)
595 if(types[i] != another.types[i])
596 throw std::runtime_error("controller_frame::operator^: Type mismatch");
597 for(size_t i = 0; i < totalsize; i++)
598 x.backing[i] ^= another.backing[i];
599 return x;
602 * Set the sync flag.
604 * Parameter x: The value to set the sync flag to.
606 void sync(bool x) throw()
608 if(x)
609 backing[0] |= 1;
610 else
611 backing[0] &= ~1;
614 * Get the sync flag.
616 * Return value: Value of sync flag.
618 bool sync() throw()
620 return ((backing[0] & 1) != 0);
623 * Quick get sync flag for buffer.
625 static bool sync(const unsigned char* mem) throw()
627 return ((mem[0] & 1) != 0);
630 * Set the reset flag.
632 * Parameter x: The value to set the reset flag to.
634 void reset(bool x) throw()
636 if(x)
637 backing[0] |= 2;
638 else
639 backing[0] &= ~2;
642 * Get the reset flag.
644 * Return value: Value of resset flag.
646 bool reset() throw()
648 return ((backing[0] & 2) != 0);
651 * Set the reset delay.
653 * Parameter x: The value to set reset delay to.
655 void delay(std::pair<short, short> x) throw()
657 backing[1] = static_cast<unsigned short>(x.first) >> 8;
658 backing[2] = static_cast<unsigned short>(x.first);
659 backing[3] = static_cast<unsigned short>(x.second) >> 8;
660 backing[4] = static_cast<unsigned short>(x.second);
663 * Get the reset delay.
665 * Return value: Value of reset delay.
667 std::pair<short, short> delay() throw()
669 short x, y;
670 x = static_cast<short>(static_cast<unsigned short>(backing[1]) << 8);
671 x |= static_cast<short>(static_cast<unsigned short>(backing[2]));
672 y = static_cast<short>(static_cast<unsigned short>(backing[3]) << 8);
673 y |= static_cast<short>(static_cast<unsigned short>(backing[4]));
674 return std::make_pair(x, y);
677 * Get size of frame.
679 * Returns: The number of bytes it takes to store frame of this type.
681 size_t size()
683 return totalsize;
686 * Set axis/button value.
688 * Parameter pcid: Physical controller id.
689 * Parameter ctrl: The control id.
690 * Parameter x: The new value.
692 void axis(unsigned pcid, unsigned ctrl, short x) throw()
694 unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
695 pinfo[port]->write(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, ctrl, x);
698 * Set axis/button value.
700 * Parameter idx: Control index.
701 * Parameter x: The new value.
703 void axis2(unsigned idx, short x) throw()
705 axis(idx / MAX_CONTROLS_PER_CONTROLLER, idx % MAX_CONTROLS_PER_CONTROLLER, x);
708 * Get axis/button value.
710 * Parameter pcid: Physical controller id.
711 * Parameter ctrl: The control id.
712 * Return value: The axis value.
714 short axis(unsigned pcid, unsigned ctrl) throw()
716 unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
717 return pinfo[port]->read(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, ctrl);
721 * Get axis/button value.
723 * Parameter idx: Index of control.
724 * Return value: The axis value.
726 short axis2(unsigned idx) throw()
728 return axis(idx / MAX_CONTROLS_PER_CONTROLLER, idx % MAX_CONTROLS_PER_CONTROLLER);
731 * Get controller display.
733 * Parameter pcid: Physical controller id.
734 * Parameter buf: Buffer to write nul-terminated display to.
736 void display(unsigned pcid, char* buf) throw()
738 unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
739 return pinfo[port]->display(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, buf);
742 * Get device type.
744 * Parameter pcid: Physical controller id.
745 * Returns: Device type.
747 devicetype_t devicetype(unsigned pcid) throw()
749 unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
750 return pinfo[port]->devicetype(pcid % MAX_CONTROLLERS_PER_PORT);
753 * Deserialize frame from text format.
755 * Parameter buf: The buffer containing text representation. Terminated by NUL, CR or LF.
756 * Throws std::runtime_error: Bad serialized representation.
758 void deserialize(const char* buf) throw(std::runtime_error)
760 size_t offset = 0;
761 offset += system_deserialize(backing, buf);
762 if(buf[offset] == '|')
763 offset++;
764 for(size_t i = 0; i < MAX_PORTS; i++) {
765 size_t s = pinfo[i]->deserialize(backing + offsets[i], buf + offset);
766 if(s != DESERIALIZE_SPECIAL_BLANK) {
767 offset += s;
768 if(buf[offset] == '|')
769 offset++;
774 * Serialize frame to text format.
776 * Parameter buf: The buffer to write NUL-terminated text representation to.
778 void serialize(char* buf) throw()
780 size_t offset = 0;
781 offset += system_serialize(backing, buf);
782 for(size_t i = 0; i < MAX_PORTS; i++) {
783 offset += pinfo[i]->serialize(backing + offsets[i], buf + offset);
784 buf[offset++] = (i < MAX_PORTS - 1) ? '|' : '\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 lcid (Logical Controller ID) into type string.
1046 * Parameter lcid: The logical controller ID.
1047 * Return: The type of controller
1049 std::string lcid_to_typestring(unsigned lcid) throw(std::bad_alloc);
1051 * Convert acid (Analog Controller ID) into pcid.
1053 * Parameter acid: The analog controller ID.
1054 * Return: The physical controller ID, or -1 if no such controller exists.
1056 int acid_to_pcid(unsigned acid) throw();
1058 * Is given acid a mouse?
1060 * Parameter acid: The analog controller ID.
1061 * Returns: True if given acid is mouse, false otherwise.
1063 bool acid_is_mouse(unsigned acid) throw();
1065 * Look up device type type of given pcid.
1067 * Parameter pcid: The physical controller id.
1068 * Returns: The type of device.
1070 devicetype_t pcid_to_type(unsigned pcid) throw();
1072 * Set type of port.
1074 * Parameter port: The port to set.
1075 * Parameter ptype: The new type for port.
1076 * Parameter set_core: If true, set the core port type too, otherwise don't do that.
1077 * Throws std::runtime_error: Illegal port type.
1079 void set_port(unsigned port, porttype_t ptype, bool set_core) throw(std::runtime_error);
1081 * Get status of current controls (with autohold/autofire factored in).
1083 * Parameter framenum: Number of current frame (for evaluating autofire).
1084 * Returns: The current controls.
1086 controller_frame get(uint64_t framenum) throw();
1088 * Commit given controls (autohold/autofire is factored in).
1090 * Parameter framenum: Number of current frame (for evaluating autofire).
1091 * Returns: The committed controls.
1093 controller_frame commit(uint64_t framenum) throw();
1095 * Commit given controls (autohold/autofire is ignored).
1097 * Parameter controls: The controls to commit
1098 * Returns: The committed controls.
1100 controller_frame commit(controller_frame controls) throw();
1102 * Get status of committed controls.
1103 * Returns: The committed controls.
1105 controller_frame get_committed() throw();
1107 * Get blank frame.
1109 controller_frame get_blank() throw();
1111 * Send analog input to given acid.
1113 * Parameter acid: The acid to send input to.
1114 * Parameter x: The x coordinate to send.
1115 * Parameter y: The x coordinate to send.
1117 void analog(unsigned acid, int x, int y) throw();
1119 * Manipulate the reset flag.
1121 * Parameter delay: Delay for reset (-1 for no reset)
1123 void reset(int32_t delay) throw();
1125 * Manipulate autohold.
1127 * Parameter pcid: The physical controller ID to manipulate.
1128 * Parameter pbid: The physical button ID to manipulate.
1129 * Parameter newstate: The new state for autohold.
1131 void autohold(unsigned pcid, unsigned pbid, bool newstate) throw();
1133 * Query autohold.
1135 * Parameter pcid: The physical controller ID to query.
1136 * Parameter pbid: The physical button ID to query.
1137 * Returns: The state of autohold.
1139 bool autohold(unsigned pcid, unsigned pbid) throw();
1141 * Manipulate button.
1143 * Parameter pcid: The physical controller ID to manipulate.
1144 * Parameter pbid: The physical button ID to manipulate.
1145 * Parameter newstate: The new state for button.
1147 void button(unsigned pcid, unsigned pbid, bool newstate) throw();
1149 * Query button.
1151 * Parameter pcid: The physical controller ID to query.
1152 * Parameter pbid: The physical button ID to query.
1153 * Returns: The state of button.
1155 bool button(unsigned pcid, unsigned pbid) throw();
1157 * Set autofire pattern.
1159 * Parameter pattern: The new pattern.
1160 * Throws std::bad_alloc: Not enough memory.
1162 void autofire(std::vector<controller_frame> pattern) throw(std::bad_alloc);
1164 * Get physical button ID for physical controller ID and logical button ID.
1166 * Parameter pcid: Physical controller id.
1167 * Parameter lbid: Logical button id.
1168 * Returns: The physical button id, or -1 if no such button.
1170 int button_id(unsigned pcid, unsigned lbid) throw();
1172 * TODO: Document.
1174 bool is_analog(unsigned pcid) throw();
1176 * TODO: Document.
1178 bool is_mouse(unsigned pcid) throw();
1179 private:
1180 const porttype_info* porttypeinfo[MAX_PORTS];
1181 porttype_t porttypes[MAX_PORTS];
1182 int analog_indices[MAX_ANALOG];
1183 bool analog_mouse[MAX_ANALOG];
1184 controller_frame _input;
1185 controller_frame _autohold;
1186 controller_frame _committed;
1187 std::vector<controller_frame> _autofire;
1190 #endif