1 #include "controller-data.hpp"
2 #include "threadtypes.hpp"
4 #include "globalwrap.hpp"
5 #include "serialization.hpp"
17 port_controller simple_controller
= {"(system)", "system", {}};
18 port_controller_set simple_port
= {"system", "system", "system", {simple_controller
},{0}};
20 struct porttype_basecontrol
: public port_type
22 porttype_basecontrol() : port_type("basecontrol", "basecontrol", 1)
24 write
= [](const port_type
* _this
, unsigned char* buffer
, unsigned idx
, unsigned ctrl
,
26 if(idx
> 0 || ctrl
> 0) return;
27 buffer
[0] = x
? 1 : 0;
29 read
= [](const port_type
* _this
, const unsigned char* buffer
, unsigned idx
, unsigned ctrl
) ->
31 if(idx
> 0 || ctrl
> 0) return 0;
32 return buffer
[0] ? 1 : 0;
34 serialize
= [](const port_type
* _this
, const unsigned char* buffer
, char* textbuf
) -> size_t {
35 textbuf
[0] = buffer
[0] ? 'F' : '-';
39 deserialize
= [](const port_type
* _this
, unsigned char* buffer
, const char* textbuf
) ->
43 if(read_button_value(textbuf
, ptr
))
45 skip_rest_of_field(textbuf
, ptr
, false);
48 controller_info
= &simple_port
;
52 unsigned macro_random_bit()
54 static unsigned char state
[32];
55 static unsigned extracted
= 256;
56 if(extracted
== 256) {
58 gettimeofday(&tv
, NULL
);
59 unsigned char buffer
[48];
60 memcpy(buffer
, state
, 32);
61 write64ube(buffer
+ 32, tv
.tv_sec
);
62 write64ube(buffer
+ 40, tv
.tv_usec
);
63 sha256::hash(state
, buffer
, 48);
66 unsigned bit
= extracted
++;
67 return ((state
[bit
/ 8] >> (bit
% 8)) & 1);
71 port_type
& get_default_system_port_type()
73 static porttype_basecontrol x
;
77 port_type::port_type(const std::string
& iname
, const std::string
& _hname
, size_t ssize
) throw(std::bad_alloc
)
78 : hname(_hname
), storage_size(ssize
), name(iname
)
82 port_type::~port_type() throw()
86 bool port_type::is_present(unsigned controller
) const throw()
88 return controller_info
->controllers
.size() > controller
;
93 size_t dummy_offset
= 0;
94 port_type
* dummy_type
= &get_default_system_port_type();
95 unsigned dummy_index
= 0;
98 std::vector
<port_type
*> types
;
100 bool matches(const std::vector
<class port_type
*>& x
)
102 if(x
.size() != types
.size())
104 for(size_t i
= 0; i
< x
.size(); i
++)
110 std::list
<binding
>& bindings()
112 static std::list
<binding
> x
;
117 port_type_set::port_type_set() throw()
120 port_offsets
= &dummy_offset
;
121 port_types
= &dummy_type
;
125 _indices
[0].valid
= true;
126 _indices
[0].port
= 0;
127 _indices
[0].controller
= 0;
128 _indices
[0].control
= 0;
131 controller_multiplier
= 1;
133 indices_tab
= &dummy_index
;
136 port_type_set
& port_type_set::make(std::vector
<class port_type
*> types
, struct port_index_map control_map
)
137 throw(std::bad_alloc
, std::runtime_error
)
139 for(auto i
: bindings())
142 //Not found, create new.
143 port_type_set
& ret
= *new port_type_set(types
, control_map
);
147 bindings().push_back(b
);
151 port_type_set::port_type_set(std::vector
<class port_type
*> types
, struct port_index_map control_map
)
153 port_count
= types
.size();
154 //Verify legality of port types.
155 for(size_t i
= 0; i
< port_count
; i
++)
156 if(!types
[i
] || !types
[i
]->legal(i
))
157 throw std::runtime_error("Illegal port types");
158 //Count maximum number of controller indices to determine the controller multiplier.
159 controller_multiplier
= 1;
160 for(size_t i
= 0; i
< port_count
; i
++)
161 for(unsigned j
= 0; j
< types
[i
]->controller_info
->controllers
.size(); j
++)
162 controller_multiplier
= max(controller_multiplier
, (size_t)types
[i
]->used_indices(j
));
163 //Count maximum number of controllers to determine the port multiplier.
165 for(size_t i
= 0; i
< port_count
; i
++)
166 port_multiplier
= max(port_multiplier
, controller_multiplier
*
167 (size_t)types
[i
]->controller_info
->controllers
.size());
168 //Allocate the per-port tables.
169 port_offsets
= new size_t[types
.size()];
170 port_types
= new class port_type
*[types
.size()];
171 //Determine the total size and offsets.
173 for(size_t i
= 0; i
< port_count
; i
++) {
174 port_offsets
[i
] = offset
;
175 offset
+= types
[i
]->storage_size
;
176 port_types
[i
] = types
[i
];
179 //Determine the index size and allocate it.
180 indices_size
= port_multiplier
* port_count
;
181 indices_tab
= new unsigned[indices_size
];
182 for(size_t i
= 0; i
< indices_size
; i
++)
183 indices_tab
[i
] = 0xFFFFFFFFUL
;
184 //Copy the index data (and reverse it).
185 controllers
= control_map
.logical_map
;
186 legacy_pcids
= control_map
.pcid_map
;
187 _indices
= control_map
.indices
;
188 for(size_t j
= 0; j
< _indices
.size(); j
++) {
189 auto& i
= _indices
[j
];
191 indices_tab
[i
.port
* port_multiplier
+ i
.controller
* controller_multiplier
+ i
.control
] = j
;
195 short read_axis_value(const char* buf
, size_t& idx
) throw()
199 while(is_nonterminator(buf
[idx
])) {
201 if(ch
!= ' ' && ch
!= '\t')
205 //Read the sign if any.
207 if(!is_nonterminator(ch
))
209 bool negative
= false;
217 //Read numeric value.
219 while(is_nonterminator(buf
[idx
]) && isdigit(static_cast<unsigned char>(ch
= buf
[idx
]))) {
220 numval
= numval
* 10 + (ch
- '0');
226 return static_cast<short>(numval
);
231 port_type_set
& dummytypes()
233 static port_type_set x
;
237 size_t writeu32val(char32_t
* buf
, int val
)
241 sprintf(c
, "%d", val
);
242 for(i
= 0; c
[i
]; i
++)
248 void controller_frame::display(unsigned port
, unsigned controller
, char32_t
* buf
) throw()
250 if(port
>= types
->ports()) {
255 uint8_t* backingmem
= backing
+ types
->port_offset(port
);
256 const port_type
& ptype
= types
->port_type(port
);
257 if(controller
>= ptype
.controller_info
->controllers
.size()) {
262 const port_controller
& pc
= ptype
.controller_info
->controllers
[controller
];
263 bool need_space
= false;
265 for(unsigned i
= 0; i
< pc
.buttons
.size(); i
++) {
266 const port_controller_button
& pcb
= pc
.buttons
[i
];
267 if(need_space
&& pcb
.type
!= port_controller_button::TYPE_NULL
) {
272 case port_controller_button::TYPE_NULL
:
274 case port_controller_button::TYPE_BUTTON
:
275 *(buf
++) = ptype
.read(&ptype
, backingmem
, controller
, i
) ? pcb
.symbol
: U
'-';
277 case port_controller_button::TYPE_AXIS
:
278 case port_controller_button::TYPE_RAXIS
:
279 case port_controller_button::TYPE_TAXIS
:
280 case port_controller_button::TYPE_LIGHTGUN
:
281 val
= ptype
.read(&ptype
, backingmem
, controller
, i
);
282 buf
+= writeu32val(buf
, val
);
290 pollcounter_vector::pollcounter_vector() throw(std::bad_alloc
)
292 types
= &dummytypes();
293 ctrs
= new uint32_t[types
->indices()];
297 pollcounter_vector::pollcounter_vector(const port_type_set
& p
) throw(std::bad_alloc
)
300 ctrs
= new uint32_t[types
->indices()];
304 pollcounter_vector::pollcounter_vector(const pollcounter_vector
& p
) throw(std::bad_alloc
)
306 ctrs
= new uint32_t[p
.types
->indices()];
308 memcpy(ctrs
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
309 framepflag
= p
.framepflag
;
312 pollcounter_vector
& pollcounter_vector::operator=(const pollcounter_vector
& p
) throw(std::bad_alloc
)
316 uint32_t* n
= new uint32_t[p
.types
->indices()];
318 memcpy(n
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
321 framepflag
= p
.framepflag
;
325 pollcounter_vector::~pollcounter_vector() throw()
330 void pollcounter_vector::clear() throw()
332 memset(ctrs
, 0, sizeof(uint32_t) * types
->indices());
336 void pollcounter_vector::set_all_DRDY() throw()
338 for(size_t i
= 0; i
< types
->indices(); i
++)
339 ctrs
[i
] |= 0x80000000UL
;
342 void pollcounter_vector::clear_DRDY(unsigned idx
) throw()
344 ctrs
[idx
] &= 0x7FFFFFFFUL
;
347 bool pollcounter_vector::get_DRDY(unsigned idx
) throw()
349 return ((ctrs
[idx
] & 0x80000000UL
) != 0);
352 bool pollcounter_vector::has_polled() throw()
355 for(size_t i
= 0; i
< types
->indices() ; i
++)
357 return ((res
& 0x7FFFFFFFUL
) != 0);
360 uint32_t pollcounter_vector::get_polls(unsigned idx
) throw()
362 return ctrs
[idx
] & 0x7FFFFFFFUL
;
365 uint32_t pollcounter_vector::increment_polls(unsigned idx
) throw()
367 uint32_t x
= ctrs
[idx
] & 0x7FFFFFFFUL
;
372 uint32_t pollcounter_vector::max_polls() throw()
375 for(unsigned i
= 0; i
< types
->indices(); i
++) {
376 uint32_t tmp
= ctrs
[i
] & 0x7FFFFFFFUL
;
377 max
= (max
< tmp
) ? tmp
: max
;
382 void pollcounter_vector::save_state(std::vector
<uint32_t>& mem
) throw(std::bad_alloc
)
384 mem
.resize(types
->indices());
386 for(size_t i
= 0; i
< types
->indices(); i
++)
390 void pollcounter_vector::load_state(const std::vector
<uint32_t>& mem
) throw()
392 for(size_t i
= 0; i
< types
->indices(); i
++)
396 bool pollcounter_vector::check(const std::vector
<uint32_t>& mem
) throw()
398 return (mem
.size() == types
->indices());
402 void pollcounter_vector::set_framepflag(bool value
) throw()
407 bool pollcounter_vector::get_framepflag() const throw()
412 controller_frame::controller_frame(const port_type_set
& p
) throw(std::runtime_error
)
414 memset(memory
, 0, sizeof(memory
));
419 controller_frame::controller_frame(unsigned char* mem
, const port_type_set
& p
) throw(std::runtime_error
)
422 throw std::runtime_error("NULL backing memory not allowed");
423 memset(memory
, 0, sizeof(memory
));
428 controller_frame::controller_frame(const controller_frame
& obj
) throw()
430 memset(memory
, 0, sizeof(memory
));
433 memcpy(backing
, obj
.backing
, types
->size());
436 controller_frame
& controller_frame::operator=(const controller_frame
& obj
) throw(std::runtime_error
)
438 if(backing
!= memory
&& types
!= obj
.types
)
439 throw std::runtime_error("Port types do not match");
441 memcpy(backing
, obj
.backing
, types
->size());
445 size_t controller_frame_vector::walk_helper(size_t frame
, bool sflag
) throw()
447 size_t ret
= sflag
? frame
: 0;
452 size_t page
= frame
/ frames_per_page
;
453 size_t offset
= frame_size
* (frame
% frames_per_page
);
454 size_t index
= frame
% frames_per_page
;
455 if(cache_page_num
!= page
) {
456 cache_page
= &pages
[page
];
457 cache_page_num
= page
;
459 while(frame
< frames
) {
460 if(index
== frames_per_page
) {
462 cache_page
= &pages
[page
];
463 cache_page_num
= page
;
465 if(controller_frame::sync(cache_page
->content
+ offset
))
468 offset
+= frame_size
;
475 size_t controller_frame_vector::count_frames() throw()
481 cache_page
= &pages
[0];
484 for(size_t i
= 0; i
< frames
; i
++) {
485 if(index
== frames_per_page
) {
487 cache_page
= &pages
[cache_page_num
];
491 if(controller_frame::sync(cache_page
->content
+ offset
))
494 offset
+= frame_size
;
500 void controller_frame_vector::clear(const port_type_set
& p
) throw(std::runtime_error
)
502 frame_size
= p
.size();
503 frames_per_page
= CONTROLLER_PAGE_SIZE
/ frame_size
;
510 controller_frame_vector::~controller_frame_vector() throw()
516 controller_frame_vector::controller_frame_vector() throw()
521 controller_frame_vector::controller_frame_vector(const port_type_set
& p
) throw()
526 void controller_frame_vector::append(controller_frame frame
) throw(std::bad_alloc
, std::runtime_error
)
528 controller_frame
check(*types
);
529 if(!check
.types_match(frame
))
530 throw std::runtime_error("controller_frame_vector::append: Type mismatch");
531 if(frames
% frames_per_page
== 0) {
533 pages
[frames
/ frames_per_page
];
536 size_t page
= frames
/ frames_per_page
;
537 size_t offset
= frame_size
* (frames
% frames_per_page
);
538 if(cache_page_num
!= page
) {
539 cache_page_num
= page
;
540 cache_page
= &pages
[page
];
542 controller_frame(cache_page
->content
+ offset
, *types
) = frame
;
546 controller_frame_vector::controller_frame_vector(const controller_frame_vector
& vector
) throw(std::bad_alloc
)
548 clear(*vector
.types
);
552 controller_frame_vector
& controller_frame_vector::operator=(const controller_frame_vector
& v
)
553 throw(std::bad_alloc
)
561 frame_size
= v
.frame_size
;
562 frames_per_page
= v
.frames_per_page
;
565 //This can't fail anymore. Copy the raw page contents.
566 size_t pagecount
= (frames
+ frames_per_page
- 1) / frames_per_page
;
567 for(size_t i
= 0; i
< pagecount
; i
++) {
569 const page
& pg2
= v
.pages
.find(i
)->second
;
579 void controller_frame_vector::resize(size_t newsize
) throw(std::bad_alloc
)
584 } else if(newsize
< frames
) {
586 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
587 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
588 for(size_t i
= pages_needed
; i
< current_pages
; i
++)
590 //Now zeroize the excess memory.
591 if(newsize
< pages_needed
* frames_per_page
) {
592 size_t offset
= frame_size
* (newsize
% frames_per_page
);
593 memset(pages
[pages_needed
- 1].content
+ offset
, 0, CONTROLLER_PAGE_SIZE
- offset
);
596 } else if(newsize
> frames
) {
598 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
599 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
600 //Create the needed pages.
601 for(size_t i
= current_pages
; i
< pages_needed
; i
++) {
605 for(size_t i
= current_pages
; i
< pages_needed
; i
++)
615 controller_frame::controller_frame() throw()
617 memset(memory
, 0, sizeof(memory
));
619 types
= &dummytypes();
622 unsigned port_controller::analog_actions() const
624 unsigned r
= 0, s
= 0;
625 for(unsigned i
= 0; i
< buttons
.size(); i
++) {
626 if(buttons
[i
].shadow
)
628 switch(buttons
[i
].type
) {
629 case port_controller_button::TYPE_AXIS
:
630 case port_controller_button::TYPE_RAXIS
:
631 case port_controller_button::TYPE_LIGHTGUN
:
634 case port_controller_button::TYPE_TAXIS
:
639 return (r
+ 1)/ 2 + s
;
642 std::pair
<unsigned, unsigned> port_controller::analog_action(unsigned k
) const
644 unsigned x1
= std::numeric_limits
<unsigned>::max();
645 unsigned x2
= std::numeric_limits
<unsigned>::max();
648 bool selecting
= false;
649 for(unsigned i
= 0; i
< buttons
.size(); i
++) {
650 if(buttons
[i
].shadow
)
652 switch(buttons
[i
].type
) {
653 case port_controller_button::TYPE_AXIS
:
654 case port_controller_button::TYPE_RAXIS
:
655 case port_controller_button::TYPE_LIGHTGUN
:
660 if(r
== k
&& !second
) {
661 //This and following.
669 case port_controller_button::TYPE_TAXIS
:
681 return std::make_pair(x1
, x2
);
686 std::string
macro_field_as_string(const JSON::node
& parent
, const std::string
& path
)
688 const JSON::node
& n
= parent
.follow(path
);
689 if(n
.type() != JSON::string
)
690 (stringfmt() << "Expected string as field '" << path
<< "'").throwex();
691 return n
.as_string8();
694 bool macro_field_as_boolean(const JSON::node
& parent
, const std::string
& path
)
696 const JSON::node
& n
= parent
.follow(path
);
697 if(n
.type() != JSON::boolean
)
698 (stringfmt() << "Expected boolean as field '" << path
<< "'").throwex();
702 const JSON::node
& macro_field_as_array(const JSON::node
& parent
, const std::string
& path
)
704 const JSON::node
& n
= parent
.follow(path
);
705 if(n
.type() != JSON::array
)
706 (stringfmt() << "Expected array as field '" << path
<< "'").throwex();
711 controller_macro_data::controller_macro_data(const std::string
& spec
, const JSON::node
& desc
, unsigned inum
)
715 std::map
<std::string
, unsigned> symbols
;
716 if(desc
.type() != JSON::array
)
717 (stringfmt() << "Expected controller descriptor " << (inum
+ 1) << " to be an array");
718 for(auto i
= desc
.begin(); i
!= desc
.end(); ++i
) {
719 if(i
->type() == JSON::string
) {
720 symbols
[i
->as_string8()] = btnnum
++;
721 btnmap
.push_back(i
.index());
722 } else if(i
->type() == JSON::number
) {
723 uint64_t anum
= i
->as_uint();
724 if(anum
> aaxes
.size())
725 (stringfmt() << "Descriptor axis number " << anum
<< " out of range in descriptor "
726 << (inum
+ 1)).throwex();
727 else if(anum
== aaxes
.size())
728 aaxes
.push_back(std::make_pair(i
.index(), std::numeric_limits
<unsigned>::max()));
730 aaxes
[anum
].second
= i
.index();
732 (stringfmt() << "Controller descriptor " << (inum
+ 1) << " contains element of unknown"
733 << "kind").throwex();
735 buttons
= symbols
.size();
738 autoterminate
= false;
740 std::deque
<size_t> stack
;
741 bool in_sparen
= false;
743 bool btn_token
= false;
744 bool btn_token_next
= false;
746 size_t last_size
= 0;
747 size_t astride
= aaxes
.size();
748 size_t stride
= get_stride();
750 size_t len
= spec
.length();
753 btn_token
= btn_token_next
;
754 btn_token_next
= false;
755 unsigned char ch
= spec
[idx
];
757 throw std::runtime_error("Asterisk must be the last thing");
760 throw std::runtime_error("Parentheses in square brackets not allowed");
761 stack
.push_back(data
.size());
762 } else if(ch
== ')') {
764 throw std::runtime_error("Parentheses in square brackets not allowed");
766 throw std::runtime_error("Unmatched right parenthesis");
767 size_t x
= stack
.back();
769 last_size
= (data
.size() - x
) / stride
;
770 } else if(ch
== '*') {
771 autoterminate
= true;
772 } else if(ch
== '?') {
774 throw std::runtime_error("? needs button to apply to");
776 throw std::runtime_error("? needs to be in brackets");
777 data
[data
.size() - stride
+ last_bit
] |= 2;
778 } else if(ch
== '[') {
780 throw std::runtime_error("Nested square brackets not allowed");
782 data
.resize(data
.size() + stride
);
783 adata
.resize(adata
.size() + astride
);
785 } else if(ch
== ']') {
787 throw std::runtime_error("Unmatched right square bracket");
789 } else if(ch
== '.') {
791 data
.resize(data
.size() + stride
);
792 adata
.resize(adata
.size() + astride
);
795 } else if(spec
[idx
] >= '0' && spec
[idx
] <= '9') {
798 while(spec
[idx
+ i
] >= '0' && spec
[idx
+ i
] <= '9') {
799 rep
= 10 * rep
+ (spec
[idx
+ i
] - '0');
803 //This has special meaning: Axis transform.
804 //Rep is the axis pair to operate on.
805 if(spec
[idx
+ i
] != ':')
806 throw std::runtime_error("Expected ':' in axis transform");
808 while(idx
+ i
< len
&& spec
[idx
+ i
] != '@')
811 throw std::runtime_error("Expected '@' in axis transform");
812 std::string aexpr
= spec
.substr(idx
+ sep
+ 1, i
- sep
- 1);
814 throw std::runtime_error("Axis transform refers to invalid axis");
815 adata
[adata
.size() - astride
+ rep
] = axis_transform(aexpr
);
819 throw std::runtime_error("Repeat not allowed without frame to "
821 size_t o
= data
.size();
822 size_t ao
= adata
.size();
823 data
.resize(o
+ (rep
- 1) * last_size
* stride
);
824 adata
.resize(ao
+ (rep
- 1) * last_size
* astride
);
825 for(unsigned i
= 1; i
< rep
; i
++) {
826 memcpy(&data
[o
+ (i
- 1) * last_size
* stride
], &data
[o
- last_size
*
827 stride
], last_size
* stride
);
828 memcpy(&data
[ao
+ (i
- 1) * last_size
* astride
], &data
[ao
-
829 last_size
* astride
], last_size
* astride
);
831 last_size
= last_size
* rep
;
836 for(auto k
: symbols
) {
837 std::string key
= k
.first
;
839 for(j
= 0; idx
+ j
< len
&& j
< key
.length(); j
++)
840 if(spec
[idx
+ j
] != key
[j
])
842 if(j
== key
.length()) {
843 idx
+= key
.length() - 1;
846 data
.resize(data
.size() + stride
);
847 adata
.resize(adata
.size() + astride
);
850 data
[data
.size() - stride
+ k
.second
] |= 1;
856 throw std::runtime_error("Unknown character or button");
857 btn_token_next
= true;
863 throw std::runtime_error("Unmatched left square bracket");
865 throw std::runtime_error("Unmatched left parenthesis");
866 } catch(std::exception
& e
) {
867 (stringfmt() << "Error parsing macro for controller " << (inum
+ 1) << ": " << e
.what()).throwex();
871 bool controller_macro_data::syntax_check(const std::string
& spec
, const JSON::node
& desc
)
873 unsigned buttons
= 0;
875 if(desc
.type() != JSON::array
)
877 for(auto i
= desc
.begin(); i
!= desc
.end(); ++i
) {
878 if(i
->type() == JSON::string
)
880 else if(i
->type() == JSON::number
) {
881 uint64_t anum
= i
->as_uint();
884 else if(anum
== astride
)
889 bool autoterminate
= false;
891 bool in_sparen
= false;
893 bool btn_token
= false;
894 bool btn_token_next
= false;
896 size_t len
= spec
.length();
898 btn_token
= btn_token_next
;
899 btn_token_next
= false;
900 unsigned char ch
= spec
[idx
];
907 } else if(ch
== ')') {
913 } else if(ch
== '*') {
914 autoterminate
= true;
915 } else if(ch
== '?') {
916 if(!btn_token
|| !in_sparen
)
918 } else if(ch
== '[') {
922 } else if(ch
== ']') {
926 } else if(ch
== '.') {
927 } else if(spec
[idx
] >= '0' && spec
[idx
] <= '9') {
930 while(spec
[idx
+ i
] >= '0' && spec
[idx
+ i
] <= '9') {
931 rep
= 10 * rep
+ (spec
[idx
+ i
] - '0');
935 //This has special meaning: Axis transform.
936 //Rep is the axis pair to operate on.
937 if(spec
[idx
+ i
] != ':')
940 while(idx
+ i
< len
&& spec
[idx
+ i
] != '@')
947 std::string aexpr
= spec
.substr(idx
+ sep
+ 1, i
- sep
- 1);
948 axis_transform
x(aexpr
);
960 for(auto i
= desc
.begin(); i
!= desc
.end(); ++i
) {
961 if(i
->type() != JSON::string
)
963 std::string key
= i
->as_string8();
965 for(j
= 0; idx
+ j
< len
&& j
< key
.length(); j
++)
966 if(spec
[idx
+ j
] != key
[j
])
968 if(j
== key
.length()) {
969 idx
+= key
.length() - 1;
975 btn_token_next
= true;
987 void controller_macro_data::write(controller_frame
& frame
, unsigned port
, unsigned controller
, int64_t nframe
,
992 if(autoterminate
&& (nframe
< 0 || nframe
>= get_frames()))
995 nframe
+= ((-nframe
/ get_frames()) + 3) * get_frames();
996 nframe
%= get_frames();
997 for(size_t i
= 0; i
< buttons
; i
++) {
998 unsigned lb
= btnmap
[i
];
999 unsigned st
= data
[nframe
* get_stride() + i
];
1001 st
= macro_random_bit();
1006 frame
.axis3(port
, controller
, lb
, 1);
1009 frame
.axis3(port
, controller
, lb
, frame
.axis3(port
, controller
, lb
) ^ 1);
1015 frame
.axis3(port
, controller
, lb
, 0);
1019 const port_controller
* _ctrl
= frame
.porttypes().port_type(port
).controller_info
->get(controller
);
1022 size_t abuttons
= aaxes
.size();
1023 for(size_t i
= 0; i
< abuttons
; i
++) {
1024 unsigned ax
= aaxes
[i
].first
;
1025 unsigned ay
= aaxes
[i
].second
;
1026 if(ay
!= std::numeric_limits
<unsigned>::max()) {
1027 if(ax
> _ctrl
->buttons
.size()) continue;
1028 if(ay
> _ctrl
->buttons
.size()) continue;
1029 auto g
= adata
[nframe
* abuttons
+ i
].transform(_ctrl
->buttons
[ax
], _ctrl
->buttons
[ay
],
1030 frame
.axis3(port
, controller
, ax
), frame
.axis3(port
, controller
, ay
));
1031 frame
.axis3(port
, controller
, ax
, g
.first
);
1032 frame
.axis3(port
, controller
, ay
, g
.second
);
1034 if(ax
> _ctrl
->buttons
.size()) continue;
1035 int16_t g
= adata
[nframe
* abuttons
+ i
].transform(_ctrl
->buttons
[ax
],
1036 frame
.axis3(port
, controller
, ax
));
1037 frame
.axis3(port
, controller
, ax
, g
);
1042 std::string
controller_macro_data::dump(const port_controller
& ctrl
)
1044 std::ostringstream o
;
1045 for(size_t i
= 0; i
< get_frames(); i
++) {
1047 for(size_t j
= 0; j
< aaxes
.size(); j
++) {
1048 controller_macro_data::axis_transform
& t
= adata
[i
* aaxes
.size() + j
];
1050 o
<< t
.coeffs
[0] << "," << t
.coeffs
[1] << "," << t
.coeffs
[2] << ",";
1051 o
<< t
.coeffs
[3] << "," << t
.coeffs
[4] << "," << t
.coeffs
[5] << "@";
1053 for(size_t j
= 0; j
< buttons
&& j
< ctrl
.buttons
.size(); j
++) {
1054 unsigned st
= data
[i
* get_stride() + j
];
1055 if(ctrl
.buttons
[j
].macro
== "")
1058 o
<< ctrl
.buttons
[j
].macro
;
1060 o
<< ctrl
.buttons
[j
].macro
<< "?";
1069 void controller_macro::write(controller_frame
& frame
, int64_t nframe
)
1071 for(auto& i
: macros
) {
1073 unsigned controller
;
1075 auto g
= frame
.porttypes().lcid_to_pcid(i
.first
);
1077 controller
= g
.second
;
1081 i
.second
.write(frame
, port
, controller
, nframe
, amode
);
1085 int16_t controller_macro_data::axis_transform::transform(const port_controller_button
& b
, int16_t v
)
1087 return scale_axis(b
, coeffs
[0] * unscale_axis(b
, v
) + coeffs
[4]);
1090 std::pair
<int16_t, int16_t> controller_macro_data::axis_transform::transform(const port_controller_button
& b1
,
1091 const port_controller_button
& b2
, int16_t v1
, int16_t v2
)
1093 double x
, y
, u
, v
, au
, av
, s
;
1094 x
= unscale_axis(b1
, v1
);
1095 y
= unscale_axis(b2
, v2
);
1096 u
= coeffs
[0] * x
+ coeffs
[1] * y
+ coeffs
[4];
1097 v
= coeffs
[2] * x
+ coeffs
[3] * y
+ coeffs
[5];
1100 s
= max(max(au
, 1.0), max(av
, 1.0));
1101 //If u and v exceed nominal range of [-1,1], those need to be projected to the edge.
1106 auto g
= std::make_pair(scale_axis(b1
, u
), scale_axis(b2
, v
));
1110 double controller_macro_data::axis_transform::unscale_axis(const port_controller_button
& b
, int16_t v
)
1113 int32_t center
= ((int32_t)b
.rmin
+ (int32_t)b
.rmax
) / 2;
1117 return -(center
- (double)v
) / (center
- b
.rmin
);
1121 return ((double)v
- center
) / (b
.rmax
- center
);
1128 return ((double)v
- b
.rmin
) / (b
.rmax
- b
.rmin
);
1132 int16_t controller_macro_data::axis_transform::scale_axis(const port_controller_button
& b
, double v
)
1135 int32_t center
= ((int32_t)b
.rmin
+ (int32_t)b
.rmax
) / 2;
1139 double v2
= v
* (center
- b
.rmin
) + center
;
1144 double v2
= v
* (b
.rmax
- center
) + center
;
1149 double v2
= v
* (b
.rmax
- b
.rmin
) + b
.rmin
;
1160 std::complex<double> parse_complex(const std::string
& expr
)
1163 if(r
= regex("\\((.*),(.*)\\)", expr
)) {
1165 return std::complex<double>(parse_value
<double>(r
[1]), parse_value
<double>(r
[2]));
1166 } else if(r
= regex("\\((.*)<(.*)\\)", expr
)) {
1167 return std::polar(parse_value
<double>(r
[1]), parse_value
<double>(r
[2]) * M_PI
/ 180);
1169 return std::complex<double>(parse_value
<double>(expr
), 0.0);
1174 controller_macro_data::axis_transform::axis_transform(const std::string
& expr
)
1177 if(r
= regex("\\*(.*)\\+(.*)", expr
)) {
1179 std::complex<double> a
= parse_complex(r
[1]);
1180 std::complex<double> b
= parse_complex(r
[2]);
1181 coeffs
[0] = a
.real();
1182 coeffs
[1] = -a
.imag();
1183 coeffs
[2] = a
.imag();
1184 coeffs
[3] = a
.real();
1185 coeffs
[4] = b
.real();
1186 coeffs
[5] = b
.imag();
1187 } else if(r
= regex("\\*(.*)", expr
)) {
1189 std::complex<double> a
= parse_complex(r
[1]);
1190 coeffs
[0] = a
.real();
1191 coeffs
[1] = -a
.imag();
1192 coeffs
[2] = a
.imag();
1193 coeffs
[3] = a
.real();
1196 } else if(r
= regex("\\+(.*)", expr
)) {
1198 std::complex<double> b
= parse_complex(r
[1]);
1203 coeffs
[4] = b
.real();
1204 coeffs
[5] = b
.imag();
1205 } else if(r
= regex("(.*),(.*),(.*),(.*),(.*),(.*)", expr
)) {
1207 coeffs
[0] = parse_value
<double>(r
[1]);
1208 coeffs
[1] = parse_value
<double>(r
[2]);
1209 coeffs
[2] = parse_value
<double>(r
[3]);
1210 coeffs
[3] = parse_value
<double>(r
[4]);
1211 coeffs
[4] = parse_value
<double>(r
[5]);
1212 coeffs
[5] = parse_value
<double>(r
[6]);
1215 std::complex<double> b
= parse_complex(expr
);
1220 coeffs
[4] = b
.real();
1221 coeffs
[5] = b
.imag();
1225 JSON::node
controller_macro::serialize()
1227 JSON::node
v(JSON::object
);
1229 case controller_macro_data::AM_OVERWRITE
: v
.insert("mode", JSON::s("overwrite")); break;
1230 case controller_macro_data::AM_OR
: v
.insert("mode", JSON::s("or")); break;
1231 case controller_macro_data::AM_XOR
: v
.insert("mode", JSON::s("xor")); break;
1233 JSON::node
& c
= v
.insert("data", JSON::array());
1234 for(auto& i
: macros
) {
1235 while(i
.first
> c
.index_count())
1236 c
.append(JSON::n());
1237 i
.second
.serialize(c
.append(JSON::n()));
1242 void controller_macro_data::serialize(JSON::node
& v
)
1245 v
.insert("enable", JSON::b(enabled
));
1246 v
.insert("expr", JSON::s(orig
));
1247 v
.insert("desc", _descriptor
);
1250 JSON::node
controller_macro_data::make_descriptor(const port_controller
& ctrl
)
1252 JSON::node
n(JSON::array
);
1253 for(size_t i
= 0; i
< ctrl
.buttons
.size(); i
++) {
1254 if(ctrl
.buttons
[i
].macro
!= "")
1255 n
.append(JSON::s(ctrl
.buttons
[i
].macro
));
1257 n
.append(JSON::n()); //Placeholder.
1259 for(size_t i
= 0; i
< ctrl
.analog_actions(); i
++) {
1260 auto g
= ctrl
.analog_action(i
);
1261 n
.index(g
.first
) = JSON::u(i
);
1262 if(g
.second
!= std::numeric_limits
<unsigned>::max())
1263 n
.index(g
.second
) = JSON::u(i
);
1268 controller_macro::controller_macro(const JSON::node
& v
)
1270 if(v
.type() != JSON::object
)
1271 throw std::runtime_error("Expected macro to be JSON object");
1272 std::string mode
= macro_field_as_string(v
, "mode");
1273 if(mode
== "overwrite") amode
= controller_macro_data::AM_OVERWRITE
;
1274 else if(mode
== "or") amode
= controller_macro_data::AM_OR
;
1275 else if(mode
== "xor") amode
= controller_macro_data::AM_XOR
;
1276 else (stringfmt() << "Unknown button mode '" << mode
<< "'").throwex();
1277 const JSON::node
& c
= macro_field_as_array(v
, "data");
1278 for(auto i
= c
.begin(); i
!= c
.end(); ++i
) {
1279 if(i
->type() == JSON::object
)
1280 macros
[i
.index()] = controller_macro_data(*i
, i
.index());
1282 (stringfmt() << "Expected object as field 'data/" << i
.index() << "'").throwex();
1286 controller_macro_data::controller_macro_data(const JSON::node
& v
, unsigned i
)
1287 : controller_macro_data(macro_field_as_string(v
, "expr"), macro_field_as_array(v
, "desc"), i
)
1289 enabled
= macro_field_as_boolean(v
, "enable");