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