JSON-based controller descriptions
[lsnes.git] / src / library / controller-data.cpp
blob5d79ae7b454afbebbeb08406b151287ce1fabc9f
1 #include "controller-data.hpp"
2 #include "threadtypes.hpp"
3 #include "minmax.hpp"
4 #include "globalwrap.hpp"
5 #include "serialization.hpp"
6 #include "string.hpp"
7 #include "sha256.hpp"
8 #include <iostream>
9 #include <sys/time.h>
10 #include <sstream>
11 #include <list>
12 #include <deque>
13 #include <complex>
15 namespace
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,
25 short x) -> void {
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) ->
30 short {
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' : '-';
36 textbuf[1] = '\0';
37 return 1;
39 deserialize = [](const port_type* _this, unsigned char* buffer, const char* textbuf) ->
40 size_t {
41 size_t ptr = 0;
42 buffer[0] = 0;
43 if(read_button_value(textbuf, ptr))
44 buffer[0] = 1;
45 skip_rest_of_field(textbuf, ptr, false);
46 return ptr;
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) {
57 timeval tv;
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);
64 extracted = 0;
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;
74 return 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;
91 namespace
93 size_t dummy_offset = 0;
94 port_type* dummy_type = &get_default_system_port_type();
95 unsigned dummy_index = 0;
96 struct binding
98 std::vector<port_type*> types;
99 port_type_set* stype;
100 bool matches(const std::vector<class port_type*>& x)
102 if(x.size() != types.size())
103 return false;
104 for(size_t i = 0; i < x.size(); i++)
105 if(x[i] != types[i])
106 return false;
107 return true;
110 std::list<binding>& bindings()
112 static std::list<binding> x;
113 return x;
117 port_type_set::port_type_set() throw()
120 port_offsets = &dummy_offset;
121 port_types = &dummy_type;
122 port_count = 1;
123 total_size = 1;
124 _indices.resize(1);
125 _indices[0].valid = true;
126 _indices[0].port = 0;
127 _indices[0].controller = 0;
128 _indices[0].control = 0;
130 port_multiplier = 1;
131 controller_multiplier = 1;
132 indices_size = 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())
140 if(i.matches(types))
141 return *(i.stype);
142 //Not found, create new.
143 port_type_set& ret = *new port_type_set(types, control_map);
144 binding b;
145 b.types = types;
146 b.stype = &ret;
147 bindings().push_back(b);
148 return ret;
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.
164 port_multiplier = 1;
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.
172 size_t offset = 0;
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];
178 total_size = offset;
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];
190 if(i.valid)
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()
197 char ch;
198 //Skip ws.
199 while(is_nonterminator(buf[idx])) {
200 char ch = buf[idx];
201 if(ch != ' ' && ch != '\t')
202 break;
203 idx++;
205 //Read the sign if any.
206 ch = buf[idx];
207 if(!is_nonterminator(ch))
208 return 0;
209 bool negative = false;
210 if(ch == '-') {
211 negative = true;
212 idx++;
214 if(ch == '+')
215 idx++;
217 //Read numeric value.
218 int numval = 0;
219 while(is_nonterminator(buf[idx]) && isdigit(static_cast<unsigned char>(ch = buf[idx]))) {
220 numval = numval * 10 + (ch - '0');
221 idx++;
223 if(negative)
224 numval = -numval;
226 return static_cast<short>(numval);
229 namespace
231 port_type_set& dummytypes()
233 static port_type_set x;
234 return x;
237 size_t writeu32val(char32_t* buf, int val)
239 char c[12];
240 size_t i;
241 sprintf(c, "%d", val);
242 for(i = 0; c[i]; i++)
243 buf[i] = c[i];
244 return i;
248 void controller_frame::display(unsigned port, unsigned controller, char32_t* buf) throw()
250 if(port >= types->ports()) {
251 //Bad port.
252 *buf = '\0';
253 return;
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()) {
258 //Bad controller.
259 *buf = '\0';
260 return;
262 const port_controller& pc = ptype.controller_info->controllers[controller];
263 bool need_space = false;
264 short val;
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) {
268 need_space = false;
269 *(buf++) = ' ';
271 switch(pcb.type) {
272 case port_controller_button::TYPE_NULL:
273 break;
274 case port_controller_button::TYPE_BUTTON:
275 *(buf++) = ptype.read(&ptype, backingmem, controller, i) ? pcb.symbol : U'-';
276 break;
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);
283 need_space = true;
284 break;
287 *buf = '\0';
290 pollcounter_vector::pollcounter_vector() throw(std::bad_alloc)
292 types = &dummytypes();
293 ctrs = new uint32_t[types->indices()];
294 clear();
297 pollcounter_vector::pollcounter_vector(const port_type_set& p) throw(std::bad_alloc)
299 types = &p;
300 ctrs = new uint32_t[types->indices()];
301 clear();
304 pollcounter_vector::pollcounter_vector(const pollcounter_vector& p) throw(std::bad_alloc)
306 ctrs = new uint32_t[p.types->indices()];
307 types = p.types;
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)
314 if(this == &p)
315 return *this;
316 uint32_t* n = new uint32_t[p.types->indices()];
317 types = p.types;
318 memcpy(n, p.ctrs, sizeof(uint32_t) * p.types->indices());
319 delete[] ctrs;
320 ctrs = n;
321 framepflag = p.framepflag;
322 return *this;
325 pollcounter_vector::~pollcounter_vector() throw()
327 delete[] ctrs;
330 void pollcounter_vector::clear() throw()
332 memset(ctrs, 0, sizeof(uint32_t) * types->indices());
333 framepflag = false;
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()
354 uint32_t res = 0;
355 for(size_t i = 0; i < types->indices() ; i++)
356 res |= ctrs[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;
368 ++ctrs[idx];
369 return x;
372 uint32_t pollcounter_vector::max_polls() throw()
374 uint32_t max = 0;
375 for(unsigned i = 0; i < types->indices(); i++) {
376 uint32_t tmp = ctrs[i] & 0x7FFFFFFFUL;
377 max = (max < tmp) ? tmp : max;
379 return max;
382 void pollcounter_vector::save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc)
384 mem.resize(types->indices());
385 //Compatiblity fun.
386 for(size_t i = 0; i < types->indices(); i++)
387 mem[i] = ctrs[i];
390 void pollcounter_vector::load_state(const std::vector<uint32_t>& mem) throw()
392 for(size_t i = 0; i < types->indices(); i++)
393 ctrs[i] = mem[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()
404 framepflag = value;
407 bool pollcounter_vector::get_framepflag() const throw()
409 return framepflag;
412 controller_frame::controller_frame(const port_type_set& p) throw(std::runtime_error)
414 memset(memory, 0, sizeof(memory));
415 backing = memory;
416 types = &p;
419 controller_frame::controller_frame(unsigned char* mem, const port_type_set& p) throw(std::runtime_error)
421 if(!mem)
422 throw std::runtime_error("NULL backing memory not allowed");
423 memset(memory, 0, sizeof(memory));
424 backing = mem;
425 types = &p;
428 controller_frame::controller_frame(const controller_frame& obj) throw()
430 memset(memory, 0, sizeof(memory));
431 backing = memory;
432 types = obj.types;
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");
440 types = obj.types;
441 memcpy(backing, obj.backing, types->size());
442 return *this;
445 size_t controller_frame_vector::walk_helper(size_t frame, bool sflag) throw()
447 size_t ret = sflag ? frame : 0;
448 if(frame >= frames)
449 return ret;
450 frame++;
451 ret++;
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) {
461 page++;
462 cache_page = &pages[page];
463 cache_page_num = page;
465 if(controller_frame::sync(cache_page->content + offset))
466 break;
467 index++;
468 offset += frame_size;
469 frame++;
470 ret++;
472 return ret;
475 size_t controller_frame_vector::count_frames() throw()
477 size_t ret = 0;
478 if(!frames)
479 return 0;
480 cache_page_num = 0;
481 cache_page = &pages[0];
482 size_t offset = 0;
483 size_t index = 0;
484 for(size_t i = 0; i < frames; i++) {
485 if(index == frames_per_page) {
486 cache_page_num++;
487 cache_page = &pages[cache_page_num];
488 index = 0;
489 offset = 0;
491 if(controller_frame::sync(cache_page->content + offset))
492 ret++;
493 index++;
494 offset += frame_size;
497 return ret;
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;
504 frames = 0;
505 types = &p;
506 clear_cache();
507 pages.clear();
510 controller_frame_vector::~controller_frame_vector() throw()
512 pages.clear();
513 cache_page = NULL;
516 controller_frame_vector::controller_frame_vector() throw()
518 clear(dummytypes());
521 controller_frame_vector::controller_frame_vector(const port_type_set& p) throw()
523 clear(p);
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) {
532 //Create new page.
533 pages[frames / frames_per_page];
535 //Write the entry.
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;
543 frames++;
546 controller_frame_vector::controller_frame_vector(const controller_frame_vector& vector) throw(std::bad_alloc)
548 clear(*vector.types);
549 *this = vector;
552 controller_frame_vector& controller_frame_vector::operator=(const controller_frame_vector& v)
553 throw(std::bad_alloc)
555 if(this == &v)
556 return *this;
557 resize(v.frames);
558 clear_cache();
560 //Copy the fields.
561 frame_size = v.frame_size;
562 frames_per_page = v.frames_per_page;
563 types = v.types;
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++) {
568 page& pg = pages[i];
569 const page& pg2 = v.pages.find(i)->second;
570 pg = pg2;
573 return *this;
579 void controller_frame_vector::resize(size_t newsize) throw(std::bad_alloc)
581 clear_cache();
582 if(newsize == 0) {
583 clear();
584 } else if(newsize < frames) {
585 //Shrink movie.
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++)
589 pages.erase(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);
595 frames = newsize;
596 } else if(newsize > frames) {
597 //Enlarge movie.
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++) {
602 try {
603 pages[i];
604 } catch(...) {
605 for(size_t i = current_pages; i < pages_needed; i++)
606 if(pages.count(i))
607 pages.erase(i);
608 throw;
611 frames = newsize;
615 controller_frame::controller_frame() throw()
617 memset(memory, 0, sizeof(memory));
618 backing = 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)
627 continue;
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:
632 r++;
633 break;
634 case port_controller_button::TYPE_TAXIS:
635 s++;
636 break;
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();
646 unsigned r = 0;
647 bool second = false;
648 bool selecting = false;
649 for(unsigned i = 0; i < buttons.size(); i++) {
650 if(buttons[i].shadow)
651 continue;
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:
656 if(selecting) {
657 x2 = i;
658 goto out;
660 if(r == k && !second) {
661 //This and following.
662 x1 = i;
663 selecting = true;
665 if(!second)
666 r++;
667 second = !second;
668 break;
669 case port_controller_button::TYPE_TAXIS:
670 if(selecting)
671 break;
672 if(r == k) {
673 x1 = i;
674 goto out;
676 r++;
677 break;
680 out:
681 return std::make_pair(x1, x2);
684 namespace
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();
699 return n.as_bool();
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();
707 return n;
711 controller_macro_data::controller_macro_data(const std::string& spec, const JSON::node& desc, unsigned inum)
713 _descriptor = desc;
714 unsigned btnnum = 0;
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()));
729 else
730 aaxes[anum].second = i.index();
731 } else
732 (stringfmt() << "Controller descriptor " << (inum + 1) << " contains element of unknown"
733 << "kind").throwex();
735 buttons = symbols.size();
736 orig = spec;
737 enabled = true;
738 autoterminate = false;
740 std::deque<size_t> stack;
741 bool in_sparen = false;
742 bool first = true;
743 bool btn_token = false;
744 bool btn_token_next = false;
745 size_t last_bit = 0;
746 size_t last_size = 0;
747 size_t astride = aaxes.size();
748 size_t stride = get_stride();
749 size_t idx = 0;
750 size_t len = spec.length();
751 try {
752 while(idx < len) {
753 btn_token = btn_token_next;
754 btn_token_next = false;
755 unsigned char ch = spec[idx];
756 if(autoterminate)
757 throw std::runtime_error("Asterisk must be the last thing");
758 if(ch == '(') {
759 if(in_sparen)
760 throw std::runtime_error("Parentheses in square brackets not allowed");
761 stack.push_back(data.size());
762 } else if(ch == ')') {
763 if(in_sparen)
764 throw std::runtime_error("Parentheses in square brackets not allowed");
765 if(stack.empty())
766 throw std::runtime_error("Unmatched right parenthesis");
767 size_t x = stack.back();
768 stack.pop_back();
769 last_size = (data.size() - x) / stride;
770 } else if(ch == '*') {
771 autoterminate = true;
772 } else if(ch == '?') {
773 if(!btn_token)
774 throw std::runtime_error("? needs button to apply to");
775 if(!in_sparen)
776 throw std::runtime_error("? needs to be in brackets");
777 data[data.size() - stride + last_bit] |= 2;
778 } else if(ch == '[') {
779 if(in_sparen)
780 throw std::runtime_error("Nested square brackets not allowed");
781 in_sparen = true;
782 data.resize(data.size() + stride);
783 adata.resize(adata.size() + astride);
784 last_size = 1;
785 } else if(ch == ']') {
786 if(!in_sparen)
787 throw std::runtime_error("Unmatched right square bracket");
788 in_sparen = false;
789 } else if(ch == '.') {
790 if(!in_sparen) {
791 data.resize(data.size() + stride);
792 adata.resize(adata.size() + astride);
793 last_size = 1;
795 } else if(spec[idx] >= '0' && spec[idx] <= '9') {
796 size_t rep = 0;
797 unsigned i = 0;
798 while(spec[idx + i] >= '0' && spec[idx + i] <= '9') {
799 rep = 10 * rep + (spec[idx + i] - '0');
800 i++;
802 if(in_sparen) {
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");
807 size_t sep = i;
808 while(idx + i < len && spec[idx + i] != '@')
809 i++;
810 if(idx + i >= len)
811 throw std::runtime_error("Expected '@' in axis transform");
812 std::string aexpr = spec.substr(idx + sep + 1, i - sep - 1);
813 if(rep >= astride)
814 throw std::runtime_error("Axis transform refers to invalid axis");
815 adata[adata.size() - astride + rep] = axis_transform(aexpr);
816 i++;
817 } else {
818 if(first)
819 throw std::runtime_error("Repeat not allowed without frame to "
820 "repeat");
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;
833 idx = idx + (i - 1);
834 } else { //Symbol.
835 bool found = false;
836 for(auto k : symbols) {
837 std::string key = k.first;
838 size_t j;
839 for(j = 0; idx + j < len && j < key.length(); j++)
840 if(spec[idx + j] != key[j])
841 break;
842 if(j == key.length()) {
843 idx += key.length() - 1;
844 found = true;
845 if(!in_sparen) {
846 data.resize(data.size() + stride);
847 adata.resize(adata.size() + astride);
849 last_bit = k.second;
850 data[data.size() - stride + k.second] |= 1;
851 if(!in_sparen)
852 last_size = 1;
855 if(!found)
856 throw std::runtime_error("Unknown character or button");
857 btn_token_next = true;
859 idx++;
860 first = false;
862 if(in_sparen)
863 throw std::runtime_error("Unmatched left square bracket");
864 if(!stack.empty())
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;
874 size_t astride = 0;
875 if(desc.type() != JSON::array)
876 return false;
877 for(auto i = desc.begin(); i != desc.end(); ++i) {
878 if(i->type() == JSON::string)
879 buttons++;
880 else if(i->type() == JSON::number) {
881 uint64_t anum = i->as_uint();
882 if(anum > astride)
883 return false;
884 else if(anum == astride)
885 astride++;
886 } else
887 return false;
889 bool autoterminate = false;
890 size_t depth = 0;
891 bool in_sparen = false;
892 bool first = true;
893 bool btn_token = false;
894 bool btn_token_next = false;
895 size_t idx = 0;
896 size_t len = spec.length();
897 while(idx < len) {
898 btn_token = btn_token_next;
899 btn_token_next = false;
900 unsigned char ch = spec[idx];
901 if(autoterminate)
902 return false;
903 if(ch == '(') {
904 if(in_sparen)
905 return false;
906 depth++;
907 } else if(ch == ')') {
908 if(in_sparen)
909 return false;
910 if(!depth)
911 return false;
912 depth--;
913 } else if(ch == '*') {
914 autoterminate = true;
915 } else if(ch == '?') {
916 if(!btn_token || !in_sparen)
917 return false;
918 } else if(ch == '[') {
919 if(in_sparen)
920 return false;
921 in_sparen = true;
922 } else if(ch == ']') {
923 if(!in_sparen)
924 return false;
925 in_sparen = false;
926 } else if(ch == '.') {
927 } else if(spec[idx] >= '0' && spec[idx] <= '9') {
928 size_t rep = 0;
929 unsigned i = 0;
930 while(spec[idx + i] >= '0' && spec[idx + i] <= '9') {
931 rep = 10 * rep + (spec[idx + i] - '0');
932 i++;
934 if(in_sparen) {
935 //This has special meaning: Axis transform.
936 //Rep is the axis pair to operate on.
937 if(spec[idx + i] != ':')
938 return false;
939 size_t sep = i;
940 while(idx + i < len && spec[idx + i] != '@')
941 i++;
942 if(idx + i >= len)
943 return false;
944 if(rep >= astride)
945 return false;
946 try {
947 std::string aexpr = spec.substr(idx + sep + 1, i - sep - 1);
948 axis_transform x(aexpr);
949 } catch(...) {
950 return false;
952 i++;
953 } else {
954 if(first)
955 return false;
957 idx = idx + (i - 1);
958 } else { //Symbol.
959 bool found = false;
960 for(auto i = desc.begin(); i != desc.end(); ++i) {
961 if(i->type() != JSON::string)
962 continue;
963 std::string key = i->as_string8();
964 size_t j;
965 for(j = 0; idx + j < len && j < key.length(); j++)
966 if(spec[idx + j] != key[j])
967 break;
968 if(j == key.length()) {
969 idx += key.length() - 1;
970 found = true;
973 if(!found)
974 return false;
975 btn_token_next = true;
977 idx++;
978 first = false;
980 if(in_sparen)
981 return false;
982 if(depth)
983 return false;
984 return true;
987 void controller_macro_data::write(controller_frame& frame, unsigned port, unsigned controller, int64_t nframe,
988 apply_mode amode)
990 if(!enabled)
991 return;
992 if(autoterminate && (nframe < 0 || nframe >= get_frames()))
993 return;
994 if(nframe < 0)
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];
1000 if(st == 3)
1001 st = macro_random_bit();
1002 if(st == 1)
1003 switch(amode) {
1004 case AM_OVERWRITE:
1005 case AM_OR:
1006 frame.axis3(port, controller, lb, 1);
1007 break;
1008 case AM_XOR:
1009 frame.axis3(port, controller, lb, frame.axis3(port, controller, lb) ^ 1);
1010 break;
1012 else
1013 switch(amode) {
1014 case AM_OVERWRITE:
1015 frame.axis3(port, controller, lb, 0);
1016 break;
1019 const port_controller* _ctrl = frame.porttypes().port_type(port).controller_info->get(controller);
1020 if(!_ctrl)
1021 return;
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);
1033 } else {
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++) {
1046 o << "[";
1047 for(size_t j = 0; j < aaxes.size(); j++) {
1048 controller_macro_data::axis_transform& t = adata[i * aaxes.size() + j];
1049 o << 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 == "")
1056 continue;
1057 if(st == 1)
1058 o << ctrl.buttons[j].macro;
1059 if(st == 3)
1060 o << ctrl.buttons[j].macro << "?";
1062 o << "]";
1064 if(autoterminate)
1065 o << "*";
1066 return o.str();
1069 void controller_macro::write(controller_frame& frame, int64_t nframe)
1071 for(auto& i : macros) {
1072 unsigned port;
1073 unsigned controller;
1074 try {
1075 auto g = frame.porttypes().lcid_to_pcid(i.first);
1076 port = g.first;
1077 controller = g.second;
1078 } catch(...) {
1079 continue;
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];
1098 au = abs(u);
1099 av = abs(v);
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.
1102 if(s > 1) {
1103 u /= s;
1104 v /= s;
1106 auto g = std::make_pair(scale_axis(b1, u), scale_axis(b2, v));
1107 return g;
1110 double controller_macro_data::axis_transform::unscale_axis(const port_controller_button& b, int16_t v)
1112 if(b.centers) {
1113 int32_t center = ((int32_t)b.rmin + (int32_t)b.rmax) / 2;
1114 if(v <= b.rmin)
1115 return -1;
1116 if(v < center)
1117 return -(center - (double)v) / (center - b.rmin);
1118 if(v == center)
1119 return 0;
1120 if(v < b.rmax)
1121 return ((double)v - center) / (b.rmax - center);
1122 return 1;
1123 } else {
1124 if(v <= b.rmin)
1125 return 0;
1126 if(v >= b.rmax)
1127 return 1;
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)
1134 if(b.centers) {
1135 int32_t center = ((int32_t)b.rmin + (int32_t)b.rmax) / 2;
1136 if(v == 0)
1137 return center;
1138 if(v < 0) {
1139 double v2 = v * (center - b.rmin) + center;
1140 if(v2 < b.rmin)
1141 return b.rmin;
1142 return v2;
1144 double v2 = v * (b.rmax - center) + center;
1145 if(v2 > b.rmax)
1146 return b.rmax;
1147 return v2;
1148 } else {
1149 double v2 = v * (b.rmax - b.rmin) + b.rmin;
1150 if(v2 < b.rmin)
1151 return b.rmin;
1152 if(v2 > b.rmax)
1153 return b.rmax;
1154 return v2;
1158 namespace
1160 std::complex<double> parse_complex(const std::string& expr)
1162 regex_results r;
1163 if(r = regex("\\((.*),(.*)\\)", expr)) {
1164 //Real,Imaginary.
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);
1168 } else {
1169 return std::complex<double>(parse_value<double>(expr), 0.0);
1174 controller_macro_data::axis_transform::axis_transform(const std::string& expr)
1176 regex_results r;
1177 if(r = regex("\\*(.*)\\+(.*)", expr)) {
1178 //Affine transform.
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)) {
1188 //Linear transform.
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();
1194 coeffs[4] = 0;
1195 coeffs[5] = 0;
1196 } else if(r = regex("\\+(.*)", expr)) {
1197 //Relative
1198 std::complex<double> b = parse_complex(r[1]);
1199 coeffs[0] = 1;
1200 coeffs[1] = 0;
1201 coeffs[2] = 0;
1202 coeffs[3] = 1;
1203 coeffs[4] = b.real();
1204 coeffs[5] = b.imag();
1205 } else if(r = regex("(.*),(.*),(.*),(.*),(.*),(.*)", expr)) {
1206 //Full affine.
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]);
1213 } else {
1214 //Absolute.
1215 std::complex<double> b = parse_complex(expr);
1216 coeffs[0] = 0;
1217 coeffs[1] = 0;
1218 coeffs[2] = 0;
1219 coeffs[3] = 0;
1220 coeffs[4] = b.real();
1221 coeffs[5] = b.imag();
1225 JSON::node controller_macro::serialize()
1227 JSON::node v(JSON::object);
1228 switch(amode) {
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()));
1239 return v;
1242 void controller_macro_data::serialize(JSON::node& v)
1244 v = JSON::object();
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));
1256 else
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);
1265 return n;
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());
1281 else
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");