Extern references in library/controller-data.hpp are no-no
[lsnes.git] / include / library / controller-data.hpp
blob5a5e8af890e21635f82fc1dd7468cf27baa38b30
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 * Index triple.
125 * Note: The index 0 has to be mapped to triple (0, 0, 0).
127 struct port_index_triple
130 * If true, the other parameters are valid. Otherwise this index doesn't correspond to anything valid, but still
131 * exists. The reason for having invalid entries is to be backward-compatible.
133 bool valid;
135 * The port number.
137 unsigned port;
139 * The controller number.
141 unsigned controller;
143 * The control number.
145 unsigned control;
147 * Does neutral poll of this index count as non-lag frame (non-neutral polls always do)?
149 bool marks_nonlag;
153 * Controller index mappings
155 struct port_index_map
158 * The poll indices.
160 std::vector<port_index_triple> indices;
162 * The logical controller mappings.
164 std::vector<std::pair<unsigned, unsigned>> logical_map;
166 * Legacy PCID mappings.
168 std::vector<std::pair<unsigned, unsigned>> pcid_map;
172 * Group of port types.
174 class port_type_group
176 public:
178 * Construct a group.
180 * Throws std::bad_alloc: Not enough memory.
182 port_type_group() throw(std::bad_alloc);
184 * Destroy a group.
186 ~port_type_group() throw();
188 * Get port type with specified name.
190 * Parameter name: The name of port type.
191 * Returns: The port type structure.
192 * Throws std::runtime_error: Specified port type unknown.
194 port_type& get_type(const std::string& name) const throw(std::runtime_error);
196 * Get set of all port types.
198 * Returns: The set of all port types.
199 * Throws std::bad_alloc: Not enough memory.
201 std::set<port_type*> get_types() const throw(std::bad_alloc);
203 * Get default port type for specified port.
205 * Parameter port: The port.
206 * Returns: The default port type.
207 * Throws std::runtime_error: Bad port.
209 port_type& get_default_type(unsigned port) const throw(std::runtime_error);
211 * Add a port type.
213 * Parameter type: Name of the type.
214 * Parameter port: The port type structure.
215 * Throws std::bad_alloc: Not enough memory.
217 void register_type(const std::string& type, port_type& port);
219 * Remove a port type.
221 * Parameter type: Name of the type.
222 * Throws std::bad_alloc: Not enough memory.
224 void unregister_type(const std::string& type);
226 * Set default type for port.
228 * Parameter port: The port.
229 * Parameter ptype: The port type to make default.
231 void set_default(unsigned port, port_type& ptype);
232 private:
233 std::map<std::string, port_type*> types;
234 std::map<unsigned, port_type*> defaults;
237 class port_type_set;
240 * Type of controller.
242 class port_type
244 public:
246 * Create a new port type.
248 * Parameter group: The group the type will belong to.
249 * Parameter iname: Internal name of the port type.
250 * Parameter hname: Human-readable name of the port type.
251 * Parameter id: Identifier.
252 * Parameter ssize: The storage size in bytes.
253 * Throws std::bad_alloc: Not enough memory.
255 port_type(port_type_group& group, const std::string& iname, const std::string& hname, unsigned id,
256 size_t ssize) throw(std::bad_alloc);
258 * Unregister a port type.
260 virtual ~port_type() throw();
262 * Writes controller data into compressed representation.
264 * Parameter buffer: The buffer storing compressed representation of controller state.
265 * Parameter idx: Index of controller.
266 * Parameter ctrl: The control to manipulate.
267 * Parameter x: New value for control. Only zero/nonzero matters for buttons.
269 void (*write)(unsigned char* buffer, unsigned idx, unsigned ctrl, short x);
271 * Read controller data from compressed representation.
273 * Parameter buffer: The buffer storing compressed representation of controller state.
274 * Parameter idx: Index of controller.
275 * Parameter ctrl: The control to query.
276 * Returns: The value of control. Buttons return 0 or 1.
278 short (*read)(const unsigned char* buffer, unsigned idx, unsigned ctrl);
280 * Format compressed controller data into input display.
282 * Parameter buffer: The buffer storing compressed representation of controller state.
283 * Parameter idx: Index of controller.
284 * Parameter buf: The buffer to write NUL-terminated display string to. Assumed to be MAX_DISPLAY_LENGTH bytes in size.
286 void (*display)(const unsigned char* buffer, unsigned idx, char* buf);
288 * Take compressed controller data and serialize it into textual representation.
290 * - The initial '|' is also written.
292 * Parameter buffer: The buffer storing compressed representation of controller state.
293 * Parameter textbuf: The text buffer to write to.
294 * Returns: Number of bytes written.
296 size_t (*serialize)(const unsigned char* buffer, char* textbuf);
298 * Unserialize textual representation into compressed controller state.
300 * - Only stops reading on '|', NUL, CR or LF in the final read field. That byte is not read.
302 * Parameter buffer: The buffer storing compressed representation of controller state.
303 * Parameter textbuf: The text buffer to read.
304 * Returns: Number of bytes read.
305 * Throws std::runtime_error: Bad serialization.
307 size_t (*deserialize)(unsigned char* buffer, const char* textbuf);
309 * Get device flags for given index.
311 * Parameter idx: The index of controller.
312 * Returns: The device flags.
313 * Bit 0: Present.
314 * Bit 1: Has absolute analog axes 0 and 1.
315 * Bit 2: Has relative analog axes 0 and 1.
317 unsigned (*deviceflags)(unsigned idx);
319 * Is the device legal for port?
321 * Parameter port: Port to query.
322 * Returns: Nonzero if legal, zero if illegal.
324 int (*legal)(unsigned port);
326 * Number of controllers connected to this port.
328 unsigned controllers;
330 * Translate controller and logical button id pair into physical button id.
332 * Parameter controller: The number of controller.
333 * Parameter lbid: Logigal button ID.
334 * Returns: The physical button ID, or -1 if no such button exists.
336 int (*button_id)(unsigned controller, unsigned lbid);
338 * Set this controller as core controller.
340 * Parameter port: Port to set to.
342 void (*set_core_controller)(unsigned port);
344 * Get number of used control indices on controller.
346 * Parameter controller: Number of controller.
347 * Returns: Number of used control indices.
349 unsigned (*used_indices)(unsigned controller);
351 * Get name of controller type on controller.
353 * Parameter controller: Number of controller.
354 * Returns: The name of controller.
356 const char* (*controller_name)(unsigned controller);
358 * Construct index map. Only called for port0.
360 * Parameter types: The port types to construct the map for.
361 * Returns: The index map.
363 struct port_index_map (*construct_map)(std::vector<port_type*> types);
365 * Does the controller exist?
367 * Parameter controller: Controller number.
369 bool is_present(unsigned controller) const throw();
371 * Does the controller have analog function?
373 * Parameter controller: Controller number.
375 bool is_analog(unsigned controller) const throw();
377 * Does the controller have mouse-type function?
379 * Parameter controller: Controller number.
381 bool is_mouse(unsigned controller) const throw();
383 * Human-readable name.
385 std::string hname;
387 * Number of bytes it takes to store this.
389 size_t storage_size;
391 * Name of port type.
393 std::string name;
395 * Id of the port.
397 unsigned pt_id;
399 * Group this port is in.
401 port_type_group& ingroup;
402 private:
403 port_type(const port_type&);
404 port_type& operator=(const port_type&);
408 * A set of port types.
410 class port_type_set
412 public:
414 * Create empty port type set.
416 port_type_set() throw();
418 * Make a port type set with specified types. If called again with the same parameters, returns the same object.
420 * Parameter types: The types.
421 * Throws std::bad_alloc: Not enough memory.
422 * Throws std::runtime_error: Illegal port types.
424 static port_type_set& make(std::vector<port_type*> types) throw(std::bad_alloc, std::runtime_error);
426 * Compare sets for equality.
428 bool operator==(const port_type_set& s) const throw() { return this == &s; }
430 * Compare sets for non-equality.
432 bool operator!=(const port_type_set& s) const throw() { return this != &s; }
434 * Get offset of specified port.
436 * Parameter port: The number of port.
437 * Returns: The offset of port.
438 * Throws std::runtime_error: Bad port number.
440 size_t port_offset(unsigned port) const throw(std::runtime_error)
442 if(port >= port_count)
443 throw std::runtime_error("Invalid port index");
444 return port_offsets[port];
447 * Get type of specified port.
449 * Parameter port: The number of port.
450 * Returns: The port type.
451 * Throws std::runtime_error: Bad port number.
453 const class port_type& port_type(unsigned port) const throw(std::runtime_error)
455 if(port >= port_count)
456 throw std::runtime_error("Invalid port index");
457 return *(port_types[port]);
460 * Get number of ports.
462 * Returns: The port count.
464 unsigned ports() const throw()
466 return port_count;
469 * Get total size of controller data.
471 * Returns the size.
473 unsigned size() const throw()
475 return total_size;
478 * Get total index count.
480 unsigned indices() const throw()
482 return _indices.size();
485 * Look up the triplet for given control.
487 * Parameter index: The index to look up.
488 * Returns: The triplet (may not be valid).
489 * Throws std::runtime_error: Index out of range.
491 port_index_triple index_to_triple(unsigned index) const throw(std::runtime_error)
493 if(index >= _indices.size())
494 throw std::runtime_error("Invalid index");
495 return _indices[index];
498 * Translate triplet into index.
500 * Parameter port: The port.
501 * Parameter controller: The controller.
502 * Parameter _index: The control index.
503 * Returns: The index, or 0xFFFFFFFFUL if specified triple is not valid.
505 unsigned triple_to_index(unsigned port, unsigned controller, unsigned _index) const throw(std::runtime_error)
507 size_t place = port * port_multiplier + controller * controller_multiplier + _index;
508 if(place >= indices_size)
509 return 0xFFFFFFFFUL;
510 unsigned pindex = indices_tab[place];
511 if(pindex == 0xFFFFFFFFUL)
512 return 0xFFFFFFFFUL;
513 const struct port_index_triple& t = _indices[pindex];
514 if(!t.valid || t.port != port || t.controller != controller || t.control != _index)
515 return 0xFFFFFFFFUL;
516 return indices_tab[place];
519 * Return number of controllers connected.
521 * Returns: Number of controllers.
523 unsigned number_of_controllers() const throw()
525 return controllers.size();
528 * Lookup physical controller index corresponding to logical one.
530 * Parameter lcid: Logical controller id.
531 * Returns: Physical controller index (port, controller).
532 * Throws std::runtime_error: No such controller.
534 std::pair<unsigned, unsigned> lcid_to_pcid(unsigned lcid) const throw(std::runtime_error)
536 if(lcid >= controllers.size())
537 throw std::runtime_error("Bad logical controller");
538 return controllers[lcid];
541 * Return number of legacy PCIDs.
543 unsigned number_of_legacy_pcids() const throw()
545 return legacy_pcids.size();
548 * Lookup (port,controller) pair corresponding to given legacy pcid.
550 * Parameter pcid: The legacy pcid.
551 * Returns: The controller index.
552 * Throws std::runtime_error: No such controller.
554 std::pair<unsigned, unsigned> legacy_pcid_to_pair(unsigned pcid) const throw(std::runtime_error)
556 if(pcid >= legacy_pcids.size())
557 throw std::runtime_error("Bad legacy PCID");
558 return legacy_pcids[pcid];
561 * Get "marks nonlag even if neutral" flag for specified index.
563 * Parameter index: The index.
564 * Returns: The flag.
566 bool marks_nonlag(unsigned index) const throw()
568 try {
569 index_to_triple(index).marks_nonlag;
570 } catch(...) {
571 return false;
575 * Get "marks nonlag even if neutral" flag for specified triplet.
577 * Parameter port: The port
578 * Parameter controller: The controller.
579 * Parameter index: The index.
580 * Returns: The flag.
582 bool marks_nonlag(unsigned port, unsigned controller, unsigned index) const throw()
584 try {
585 index_to_triple(triple_to_index(port, controller, index)).marks_nonlag;
586 } catch(...) {
587 return false;
590 private:
591 port_type_set(std::vector<class port_type*> types);
592 size_t* port_offsets;
593 class port_type** port_types;
594 unsigned port_count;
595 size_t total_size;
596 std::vector<port_index_triple> _indices;
597 std::vector<std::pair<unsigned, unsigned>> controllers;
598 std::vector<std::pair<unsigned, unsigned>> legacy_pcids;
600 size_t port_multiplier;
601 size_t controller_multiplier;
602 size_t indices_size;
603 unsigned* indices_tab;
607 * Poll counter vector.
609 class pollcounter_vector
611 public:
613 * Create new pollcounter vector filled with all zeroes and all DRDY bits clear.
615 * Throws std::bad_alloc: Not enough memory.
617 pollcounter_vector() throw(std::bad_alloc);
619 * Create new pollcounter vector suitably sized for given type set.
621 * Parameter p: The port types.
622 * Throws std::bad_alloc: Not enough memory.
624 pollcounter_vector(const port_type_set& p) throw(std::bad_alloc);
626 * Destructor.
628 ~pollcounter_vector() throw();
630 * Copy the pollcounter_vector.
632 pollcounter_vector(const pollcounter_vector& v) throw(std::bad_alloc);
634 * Assign the pollcounter_vector.
636 pollcounter_vector& operator=(const pollcounter_vector& v) throw(std::bad_alloc);
638 * Zero all poll counters and clear all DRDY bits. System flag is cleared.
640 void clear() throw();
642 * Set all DRDY bits.
644 void set_all_DRDY() throw();
646 * Clear specified DRDY bit.
648 * Parameter port: The port.
649 * Parameter controller: The controller
650 * Parameter ctrl: The control id.
652 void clear_DRDY(unsigned port, unsigned controller, unsigned ctrl) throw()
654 unsigned i = types->triple_to_index(port, controller, ctrl);
655 if(i != 0xFFFFFFFFU)
656 clear_DRDY(i);
659 * Clear state of DRDY bit.
661 * Parameter idx: The control index.
663 void clear_DRDY(unsigned idx) throw();
665 * Get state of DRDY bit.
667 * Parameter port: The port.
668 * Parameter controller: The controller
669 * Parameter ctrl: The control id.
670 * Returns: The DRDY state.
672 bool get_DRDY(unsigned port, unsigned controller, unsigned ctrl) throw()
674 unsigned i = types->triple_to_index(port, controller, ctrl);
675 if(i != 0xFFFFFFFFU)
676 return get_DRDY(i);
677 else
678 return true;
681 * Get state of DRDY bit.
683 * Parameter idx: The control index.
684 * Returns: The DRDY state.
686 bool get_DRDY(unsigned idx) throw();
688 * Is any poll count nonzero or is system flag set?
690 * Returns: True if at least one poll count is nonzero or if system flag is set. False otherwise.
692 bool has_polled() throw();
694 * Read the actual poll count on specified control.
696 * Parameter port: The port.
697 * Parameter controller: The controller
698 * Parameter ctrl: The control id.
699 * Return: The poll count.
701 uint32_t get_polls(unsigned port, unsigned controller, unsigned ctrl) throw()
703 unsigned i = types->triple_to_index(port, controller, ctrl);
704 if(i != 0xFFFFFFFFU)
705 return get_polls(i);
706 else
707 return 0;
710 * Read the actual poll count on specified control.
712 * Parameter idx: The control index.
713 * Return: The poll count.
715 uint32_t get_polls(unsigned idx) throw();
717 * Increment poll count on specified control.
719 * Parameter port: The port.
720 * Parameter controller: The controller
721 * Parameter ctrl: The control id.
722 * Return: The poll count pre-increment.
724 uint32_t increment_polls(unsigned port, unsigned controller, unsigned ctrl) throw()
726 unsigned i = types->triple_to_index(port, controller, ctrl);
727 if(i != 0xFFFFFFFFU)
728 return increment_polls(i);
729 else
730 return 0;
733 * Increment poll count on specified index.
735 * Parameter idx: The index.
736 * Return: The poll count pre-increment.
738 uint32_t increment_polls(unsigned idx) throw();
740 * Get highest poll counter value.
742 * - System flag counts as 1 poll.
744 * Returns: The maximum poll count (at least 1 if system flag is set).
746 uint32_t max_polls() throw();
748 * Save state to memory block.
750 * Parameter mem: The memory block to save to.
751 * Throws std::bad_alloc: Not enough memory.
753 void save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc);
755 * Load state from memory block.
757 * Parameter mem: The block from restore from.
759 void load_state(const std::vector<uint32_t>& mem) throw();
761 * Check if state can be loaded without errors.
763 * Returns: True if load is possible, false otherwise.
765 bool check(const std::vector<uint32_t>& mem) throw();
766 private:
767 uint32_t* ctrs;
768 const port_type_set* types;
772 * Single (sub)frame of controls.
774 class controller_frame
776 public:
778 * Default constructor. Invalid port types, dedicated memory.
780 controller_frame() throw();
782 * Create subframe of controls with specified controller types and dedicated memory.
784 * Parameter p: Types of ports.
786 controller_frame(const port_type_set& p) throw(std::runtime_error);
788 * Create subframe of controls with specified controller types and specified memory.
790 * Parameter memory: The backing memory.
791 * Parameter p: Types of ports.
793 * Throws std::runtime_error: NULL memory.
795 controller_frame(unsigned char* memory, const port_type_set& p) throw(std::runtime_error);
797 * Copy construct a frame. The memory will be dedicated.
799 * Parameter obj: The object to copy.
801 controller_frame(const controller_frame& obj) throw();
803 * Assign a frame. The types must either match or memory must be dedicated.
805 * Parameter obj: The object to copy.
806 * Returns: Reference to this.
807 * Throws std::runtime_error: The types don't match and memory is not dedicated.
809 controller_frame& operator=(const controller_frame& obj) throw(std::runtime_error);
811 * Get type of port.
813 * Parameter port: Number of port.
814 * Returns: The type of port.
816 const port_type& get_port_type(unsigned port) throw()
818 return types->port_type(port);
821 * Get port count.
823 unsigned get_port_count() throw()
825 return types->ports();
828 * Get index count.
830 unsigned get_index_count() throw()
832 return types->indices();
835 * Set types of ports.
837 * Parameter ptype: New port types.
838 * Throws std::runtime_error: Memory is mapped.
840 void set_types(const port_type_set& ptype) throw(std::runtime_error)
842 if(memory != backing)
843 throw std::runtime_error("Can't change type of mapped controller_frame");
844 types = &ptype;
847 * Get blank dedicated frame of same port types.
849 * Return blank frame.
851 controller_frame blank_frame() throw()
853 return controller_frame(*types);
856 * Check that types match.
858 * Parameter obj: Another object.
859 * Returns: True if types match, false otherwise.
861 bool types_match(const controller_frame& obj) const throw()
863 return types == obj.types;
866 * Perform XOR between controller frames.
868 * Parameter another: The another object.
869 * Returns: The XOR result (dedicated memory).
870 * Throws std::runtime_error: Type mismatch.
872 controller_frame operator^(const controller_frame& another) throw(std::runtime_error)
874 controller_frame x(*this);
875 if(types != another.types)
876 throw std::runtime_error("controller_frame::operator^: Type mismatch");
877 for(size_t i = 0; i < types->size(); i++)
878 x.backing[i] ^= another.backing[i];
879 return x;
882 * Set the sync flag.
884 * Parameter x: The value to set the sync flag to.
886 void sync(bool x) throw()
888 if(x)
889 backing[0] |= 1;
890 else
891 backing[0] &= ~1;
894 * Get the sync flag.
896 * Return value: Value of sync flag.
898 bool sync() throw()
900 return ((backing[0] & 1) != 0);
903 * Quick get sync flag for buffer.
905 static bool sync(const unsigned char* mem) throw()
907 return ((mem[0] & 1) != 0);
910 * Get size of frame.
912 * Returns: The number of bytes it takes to store frame of this type.
914 size_t size()
916 return types->size();
919 * Set axis/button value.
921 * Parameter port: The port.
922 * Parameter controller: The controller
923 * Parameter ctrl: The control id.
924 * Parameter x: The new value.
926 void axis3(unsigned port, unsigned controller, unsigned ctrl, short x) throw()
928 if(port >= types->ports())
929 return;
930 types->port_type(port).write(backing + types->port_offset(port), controller, ctrl, x);
933 * Set axis/button value.
935 * Parameter idx: Control index.
936 * Parameter x: The new value.
938 void axis2(unsigned idx, short x) throw()
940 port_index_triple t = types->index_to_triple(idx);
941 axis3(t.port, t.controller, t.control, x);
944 * Get axis/button value.
946 * Parameter port: The port.
947 * Parameter controller: The controller
948 * Parameter ctrl: The control id.
949 * Return value: The axis value.
951 short axis3(unsigned port, unsigned controller, unsigned ctrl) throw()
953 if(port >= types->ports())
954 return 0;
955 return types->port_type(port).read(backing + types->port_offset(port), controller, ctrl);
959 * Get axis/button value.
961 * Parameter idx: Index of control.
962 * Return value: The axis value.
964 short axis2(unsigned idx) throw()
966 port_index_triple t = types->index_to_triple(idx);
967 return axis3(t.port, t.controller, t.control);
970 * Get controller display.
972 * Parameter port: The port.
973 * Parameter controller: The controller
974 * Parameter buf: Buffer to write nul-terminated display to.
976 void display(unsigned port, unsigned controller, char* buf) throw()
978 if(port >= types->ports()) {
979 *buf = '\0';
980 return;
982 types->port_type(port).display(backing + types->port_offset(port), controller, buf);
985 * Is device present?
987 * Parameter port: The port.
988 * Parameter controller: The controller
989 * Returns: True if present, false if not.
991 bool is_present(unsigned port, unsigned controller) throw()
993 if(port >= types->ports())
994 return false;
995 return types->port_type(port).is_present(controller);
998 * Deserialize frame from text format.
1000 * Parameter buf: The buffer containing text representation. Terminated by NUL, CR or LF.
1001 * Throws std::runtime_error: Bad serialized representation.
1003 void deserialize(const char* buf) throw(std::runtime_error)
1005 size_t offset = 0;
1006 for(size_t i = 0; i < types->ports(); i++) {
1007 size_t s;
1008 s = types->port_type(i).deserialize(backing + types->port_offset(i), buf + offset);
1009 if(s != DESERIALIZE_SPECIAL_BLANK) {
1010 offset += s;
1011 while(is_nonterminator(buf[offset]))
1012 offset++;
1013 if(buf[offset] == '|')
1014 offset++;
1019 * Serialize frame to text format.
1021 * Parameter buf: The buffer to write NUL-terminated text representation to.
1023 void serialize(char* buf) throw()
1025 size_t offset = 0;
1026 for(size_t i = 0; i < types->ports(); i++)
1027 offset += types->port_type(i).serialize(backing + types->port_offset(i), buf + offset);
1028 buf[offset++] = '\0';
1031 * Return copy with dedicated memory.
1033 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
1034 * Returns: Copy of this frame.
1036 controller_frame copy(bool sync)
1038 controller_frame c(*this);
1039 c.sync(sync);
1040 return c;
1043 * Compare two frames.
1045 * Parameter obj: Another frame.
1046 * Returns: True if equal, false if not.
1048 bool operator==(const controller_frame& obj) const throw()
1050 if(!types_match(obj))
1051 return false;
1052 return !memcmp(backing, obj.backing, types->size());
1055 * Compare two frames.
1057 * Parameter obj: Another frame.
1058 * Returns: True if not equal, false if equal.
1060 bool operator!=(const controller_frame& obj) const throw()
1062 return !(*this == obj);
1065 * Get physical button ID for physical controller ID and logical button ID.
1067 * Parameter port: The port.
1068 * Parameter controller: The controller
1069 * Parameter lbid: Logical button id.
1070 * Returns: The physical button id, or -1 if no such button.
1072 int button_id(unsigned port, unsigned controller, unsigned lbid)
1074 if(port >= types->ports())
1075 return -1;
1076 return types->port_type(port).button_id(controller, lbid);
1079 * Does the specified controller have analog function.
1081 * Parameter port: The port.
1082 * Parameter controller: The controller
1084 bool is_analog(unsigned port, unsigned controller)
1086 if(port >= types->ports())
1087 return false;
1088 return types->port_type(port).is_analog(controller);
1091 * Does the specified controller have mouse-type function.
1093 * Parameter port: The port.
1094 * Parameter controller: The controller
1096 bool is_mouse(unsigned port, unsigned controller)
1098 if(port >= types->ports())
1099 return false;
1100 return types->port_type(port).is_mouse(controller);
1103 * Get the port type set.
1105 const port_type_set& porttypes()
1107 return *types;
1109 private:
1110 unsigned char memory[MAXIMUM_CONTROLLER_FRAME_SIZE];
1111 unsigned char* backing;
1112 const port_type_set* types;
1116 * Vector of controller frames.
1118 class controller_frame_vector
1120 public:
1122 * Construct new controller frame vector.
1124 controller_frame_vector() throw();
1126 * Construct new controller frame vector.
1128 * Parameter p: The port types.
1130 controller_frame_vector(const port_type_set& p) throw();
1132 * Destroy controller frame vector
1134 ~controller_frame_vector() throw();
1136 * Copy controller frame vector.
1138 * Parameter obj: The object to copy.
1139 * Throws std::bad_alloc: Not enough memory.
1141 controller_frame_vector(const controller_frame_vector& vector) throw(std::bad_alloc);
1143 * Assign controller frame vector.
1145 * Parameter obj: The object to copy.
1146 * Returns: Reference to this.
1147 * Throws std::bad_alloc: Not enough memory.
1149 controller_frame_vector& operator=(const controller_frame_vector& vector) throw(std::bad_alloc);
1151 * Blank vector and change the type of ports.
1153 * Parameter p: The port types.
1155 void clear(const port_type_set& p) throw(std::runtime_error);
1157 * Blank vector.
1159 void clear() throw()
1161 clear(*types);
1164 * Get number of subframes.
1166 size_t size()
1168 return frames;
1171 * Get the typeset.
1173 const port_type_set& get_types()
1175 return *types;
1178 * Access specified subframe.
1180 * Parameter x: The frame number.
1181 * Returns: The controller frame.
1182 * Throws std::runtime_error: Invalid frame index.
1184 controller_frame operator[](size_t x)
1186 size_t page = x / frames_per_page;
1187 size_t pageoffset = frame_size * (x % frames_per_page);
1188 if(x >= frames)
1189 throw std::runtime_error("controller_frame_vector::operator[]: Illegal index");
1190 if(page != cache_page_num) {
1191 cache_page = &pages[page];
1192 cache_page_num = page;
1194 return controller_frame(cache_page->content + pageoffset, *types);
1197 * Append a subframe.
1199 * Parameter frame: The frame to append.
1200 * Throws std::bad_alloc: Not enough memory.
1201 * Throws std::runtime_error: Port type mismatch.
1203 void append(controller_frame frame) throw(std::bad_alloc, std::runtime_error);
1205 * Change length of vector.
1207 * - Reducing length of vector will discard extra elements.
1208 * - Extending length of vector will add all-zero elements.
1210 * Parameter newsize: New size of vector.
1211 * Throws std::bad_alloc: Not enough memory.
1213 void resize(size_t newsize) throw(std::bad_alloc);
1215 * Walk the indexes of sync subframes.
1217 * - If frame is in range and there is at least one more sync subframe after it, the index of first sync subframe
1218 * after given frame.
1219 * - If frame is in range, but there are no more sync subframes after it, the length of vector is returned.
1220 * - If frame is out of range, the given frame is returned.
1222 * Parameter frame: The frame number to start search from.
1223 * Returns: Index of next sync frame.
1225 size_t walk_sync(size_t frame) throw()
1227 return walk_helper(frame, true);
1230 * Get number of subframes in frame. The given subframe is assumed to be sync subframe.
1232 * - The return value is the same as (walk_sync(frame) - frame).
1234 * Parameter frame: The frame number to start search from.
1235 * Returns: Number of subframes in this frame.
1237 size_t subframe_count(size_t frame) throw()
1239 return walk_helper(frame, false);
1242 * Count number of subframes in vector with sync flag set.
1244 * Returns: The number of frames.
1246 size_t count_frames() throw();
1248 * Return blank controller frame with correct type and dedicated memory.
1250 * Parameter sync: If set, the frame will have sync flag set, otherwise it will have sync flag clear.
1251 * Returns: Blank frame.
1253 controller_frame blank_frame(bool sync)
1255 controller_frame c(*types);
1256 c.sync(sync);
1257 return c;
1259 private:
1260 class page
1262 public:
1263 page() { memset(content, 0, CONTROLLER_PAGE_SIZE); }
1264 unsigned char content[CONTROLLER_PAGE_SIZE];
1266 size_t frames_per_page;
1267 size_t frame_size;
1268 size_t frames;
1269 const port_type_set* types;
1270 size_t cache_page_num;
1271 page* cache_page;
1272 std::map<size_t, page> pages;
1273 size_t walk_helper(size_t frame, bool sflag) throw();
1274 void clear_cache()
1276 cache_page_num = 0;
1277 cache_page_num--;
1278 cache_page = NULL;
1283 * Get a dummy port type.
1285 * Return value: Dummy port type.
1287 port_type& get_dummy_port_type() throw(std::bad_alloc);
1290 * Generic port write function.
1292 template<unsigned controllers, unsigned analog_axis, unsigned buttons>
1293 inline void generic_port_write(unsigned char* buffer, unsigned idx, unsigned ctrl, short x) throw()
1295 if(idx >= controllers)
1296 return;
1297 if(ctrl < analog_axis) {
1298 buffer[2 * idx * analog_axis + 2 * ctrl] = (x >> 8);
1299 buffer[2 * idx * analog_axis + 2 * ctrl + 1] = x;
1300 } else if(ctrl < analog_axis + buttons) {
1301 size_t bit = 16 * controllers * analog_axis + idx * buttons + ctrl - analog_axis;
1302 if(x)
1303 buffer[bit / 8] |= (1 << (bit % 8));
1304 else
1305 buffer[bit / 8] &= ~(1 << (bit % 8));
1310 * Generic port read function.
1312 template<unsigned controllers, unsigned analog_axis, unsigned buttons>
1313 inline short generic_port_read(const unsigned char* buffer, unsigned idx, unsigned ctrl) throw()
1315 if(idx >= controllers)
1316 return 0;
1317 if(ctrl < analog_axis) {
1318 uint16_t a = buffer[2 * idx * analog_axis + 2 * ctrl];
1319 uint16_t b = buffer[2 * idx * analog_axis + 2 * ctrl + 1];
1320 return static_cast<short>(256 * a + b);
1321 } else if(ctrl < analog_axis + buttons) {
1322 size_t bit = 16 * controllers * analog_axis + idx * buttons + ctrl - analog_axis;
1323 return ((buffer[bit / 8] & (1 << (bit % 8))) != 0);
1324 } else
1325 return 0;
1329 * Generic port control index function.
1331 template<unsigned controllers, unsigned indices>
1332 inline unsigned generic_used_indices(unsigned controller)
1334 if(controller >= controllers)
1335 return 0;
1336 return indices;
1341 * Generic port size function.
1343 template<unsigned controllers, unsigned analog_axis, unsigned buttons>
1344 inline size_t generic_port_size()
1346 return 2 * controllers * analog_axis + (controllers * buttons + 7) / 8;
1350 * Generic port deserialization function.
1352 template<unsigned controllers, unsigned analog_axis, unsigned buttons>
1353 inline size_t generic_port_deserialize(unsigned char* buffer, const char* textbuf) throw()
1355 if(!controllers)
1356 return DESERIALIZE_SPECIAL_BLANK;
1357 memset(buffer, 0, generic_port_size<controllers, analog_axis, buttons>());
1358 size_t ptr = 0;
1359 for(unsigned j = 0; j < controllers; j++) {
1360 for(unsigned i = 0; i < buttons; i++) {
1361 size_t bit = 16 * controllers * analog_axis + j * buttons + i;
1362 if(read_button_value(textbuf, ptr))
1363 buffer[bit / 8] |= (1 << (bit % 8));
1365 for(unsigned i = 0; i < analog_axis; i++) {
1366 short v = read_axis_value(textbuf, ptr);
1367 buffer[2 * j * analog_axis + 2 * i] = v >> 8;
1368 buffer[2 * j * analog_axis + 2 * i + 1] = v;
1370 skip_rest_of_field(textbuf, ptr, j + 1 < controllers);
1372 return ptr;
1375 template<unsigned mask>
1376 inline int generic_port_legal(unsigned port) throw()
1378 if(port >= CHAR_BIT * sizeof(unsigned))
1379 port = CHAR_BIT * sizeof(unsigned) - 1;
1380 return ((mask >> port) & 1);
1384 * Generic port type function.
1386 template<unsigned controllers, unsigned flags>
1387 inline unsigned generic_port_deviceflags(unsigned idx) throw()
1389 return (idx < controllers) ? flags : 0;
1392 #endif