bsnes: redump sprite/palette functions
[lsnes.git] / src / library / controller-data.cpp
blob42f8d67f4d7cf0eed3b90e791a28961e02736f4c
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 serialization::u64b(buffer + 32, tv.tv_sec);
62 serialization::u64b(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;
247 uint64_t find_next_sync(controller_frame_vector& movie, uint64_t after)
249 if(after >= movie.size())
250 return after;
251 do {
252 after++;
253 } while(after < movie.size() && !movie[after].sync());
254 return after;
258 void controller_frame::display(unsigned port, unsigned controller, char32_t* buf) throw()
260 if(port >= types->ports()) {
261 //Bad port.
262 *buf = '\0';
263 return;
265 uint8_t* backingmem = backing + types->port_offset(port);
266 const port_type& ptype = types->port_type(port);
267 if(controller >= ptype.controller_info->controllers.size()) {
268 //Bad controller.
269 *buf = '\0';
270 return;
272 const port_controller& pc = ptype.controller_info->controllers[controller];
273 bool need_space = false;
274 short val;
275 for(unsigned i = 0; i < pc.buttons.size(); i++) {
276 const port_controller_button& pcb = pc.buttons[i];
277 if(need_space && pcb.type != port_controller_button::TYPE_NULL) {
278 need_space = false;
279 *(buf++) = ' ';
281 switch(pcb.type) {
282 case port_controller_button::TYPE_NULL:
283 break;
284 case port_controller_button::TYPE_BUTTON:
285 *(buf++) = ptype.read(&ptype, backingmem, controller, i) ? pcb.symbol : U'-';
286 break;
287 case port_controller_button::TYPE_AXIS:
288 case port_controller_button::TYPE_RAXIS:
289 case port_controller_button::TYPE_TAXIS:
290 case port_controller_button::TYPE_LIGHTGUN:
291 val = ptype.read(&ptype, backingmem, controller, i);
292 buf += writeu32val(buf, val);
293 need_space = true;
294 break;
297 *buf = '\0';
300 pollcounter_vector::pollcounter_vector() throw(std::bad_alloc)
302 types = &dummytypes();
303 ctrs = new uint32_t[types->indices()];
304 clear();
307 pollcounter_vector::pollcounter_vector(const port_type_set& p) throw(std::bad_alloc)
309 types = &p;
310 ctrs = new uint32_t[types->indices()];
311 clear();
314 pollcounter_vector::pollcounter_vector(const pollcounter_vector& p) throw(std::bad_alloc)
316 ctrs = new uint32_t[p.types->indices()];
317 types = p.types;
318 memcpy(ctrs, p.ctrs, sizeof(uint32_t) * p.types->indices());
319 framepflag = p.framepflag;
322 pollcounter_vector& pollcounter_vector::operator=(const pollcounter_vector& p) throw(std::bad_alloc)
324 if(this == &p)
325 return *this;
326 uint32_t* n = new uint32_t[p.types->indices()];
327 types = p.types;
328 memcpy(n, p.ctrs, sizeof(uint32_t) * p.types->indices());
329 delete[] ctrs;
330 ctrs = n;
331 framepflag = p.framepflag;
332 return *this;
335 pollcounter_vector::~pollcounter_vector() throw()
337 delete[] ctrs;
340 void pollcounter_vector::clear() throw()
342 memset(ctrs, 0, sizeof(uint32_t) * types->indices());
343 framepflag = false;
346 void pollcounter_vector::set_all_DRDY() throw()
348 for(size_t i = 0; i < types->indices(); i++)
349 ctrs[i] |= 0x80000000UL;
352 void pollcounter_vector::clear_DRDY(unsigned idx) throw()
354 ctrs[idx] &= 0x7FFFFFFFUL;
357 bool pollcounter_vector::get_DRDY(unsigned idx) throw()
359 return ((ctrs[idx] & 0x80000000UL) != 0);
362 bool pollcounter_vector::has_polled() throw()
364 uint32_t res = 0;
365 for(size_t i = 0; i < types->indices() ; i++)
366 res |= ctrs[i];
367 return ((res & 0x7FFFFFFFUL) != 0);
370 uint32_t pollcounter_vector::get_polls(unsigned idx) throw()
372 return ctrs[idx] & 0x7FFFFFFFUL;
375 uint32_t pollcounter_vector::increment_polls(unsigned idx) throw()
377 uint32_t x = ctrs[idx] & 0x7FFFFFFFUL;
378 ++ctrs[idx];
379 return x;
382 uint32_t pollcounter_vector::max_polls() throw()
384 uint32_t max = 0;
385 for(unsigned i = 0; i < types->indices(); i++) {
386 uint32_t tmp = ctrs[i] & 0x7FFFFFFFUL;
387 max = (max < tmp) ? tmp : max;
389 return max;
392 void pollcounter_vector::save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc)
394 mem.resize(types->indices());
395 //Compatiblity fun.
396 for(size_t i = 0; i < types->indices(); i++)
397 mem[i] = ctrs[i];
400 void pollcounter_vector::load_state(const std::vector<uint32_t>& mem) throw()
402 for(size_t i = 0; i < types->indices(); i++)
403 ctrs[i] = mem[i];
406 bool pollcounter_vector::check(const std::vector<uint32_t>& mem) throw()
408 return (mem.size() == types->indices());
412 void pollcounter_vector::set_framepflag(bool value) throw()
414 framepflag = value;
417 bool pollcounter_vector::get_framepflag() const throw()
419 return framepflag;
422 controller_frame::controller_frame(const port_type_set& p) throw(std::runtime_error)
424 memset(memory, 0, sizeof(memory));
425 backing = memory;
426 types = &p;
427 host = NULL;
430 controller_frame::controller_frame(unsigned char* mem, const port_type_set& p, controller_frame_vector* _host)
431 throw(std::runtime_error)
433 if(!mem)
434 throw std::runtime_error("NULL backing memory not allowed");
435 memset(memory, 0, sizeof(memory));
436 backing = mem;
437 types = &p;
438 host = _host;
441 controller_frame::controller_frame(const controller_frame& obj) throw()
443 memset(memory, 0, sizeof(memory));
444 backing = memory;
445 types = obj.types;
446 memcpy(backing, obj.backing, types->size());
447 host = NULL;
450 controller_frame& controller_frame::operator=(const controller_frame& obj) throw(std::runtime_error)
452 if(backing != memory && types != obj.types)
453 throw std::runtime_error("Port types do not match");
454 types = obj.types;
455 short old = sync();
456 memcpy(backing, obj.backing, types->size());
457 if(host) host->notify_sync_change(sync() - old);
458 return *this;
461 size_t controller_frame_vector::walk_helper(size_t frame, bool sflag) throw()
463 size_t ret = sflag ? frame : 0;
464 if(frame >= frames)
465 return ret;
466 frame++;
467 ret++;
468 size_t page = frame / frames_per_page;
469 size_t offset = frame_size * (frame % frames_per_page);
470 size_t index = frame % frames_per_page;
471 if(cache_page_num != page) {
472 cache_page = &pages[page];
473 cache_page_num = page;
475 while(frame < frames) {
476 if(index == frames_per_page) {
477 page++;
478 cache_page = &pages[page];
479 cache_page_num = page;
480 index = 0;
481 offset = 0;
483 if(controller_frame::sync(cache_page->content + offset))
484 break;
485 index++;
486 offset += frame_size;
487 frame++;
488 ret++;
490 return ret;
493 size_t controller_frame_vector::recount_frames() throw()
495 uint64_t old_frame_count = real_frame_count;
496 size_t ret = 0;
497 if(!frames)
498 return 0;
499 cache_page_num = 0;
500 cache_page = &pages[0];
501 size_t offset = 0;
502 size_t index = 0;
503 for(size_t i = 0; i < frames; i++) {
504 if(index == frames_per_page) {
505 cache_page_num++;
506 cache_page = &pages[cache_page_num];
507 index = 0;
508 offset = 0;
510 if(controller_frame::sync(cache_page->content + offset))
511 ret++;
512 index++;
513 offset += frame_size;
516 real_frame_count = ret;
517 call_framecount_notification(old_frame_count);
518 return ret;
521 void controller_frame_vector::clear(const port_type_set& p) throw(std::runtime_error)
523 uint64_t old_frame_count = real_frame_count;
524 frame_size = p.size();
525 frames_per_page = CONTROLLER_PAGE_SIZE / frame_size;
526 frames = 0;
527 types = &p;
528 clear_cache();
529 pages.clear();
530 real_frame_count = 0;
531 call_framecount_notification(old_frame_count);
534 controller_frame_vector::~controller_frame_vector() throw()
536 pages.clear();
537 cache_page = NULL;
540 controller_frame_vector::controller_frame_vector() throw()
542 real_frame_count = 0;
543 freeze_count = 0;
544 clear(dummytypes());
547 controller_frame_vector::controller_frame_vector(const port_type_set& p) throw()
549 real_frame_count = 0;
550 freeze_count = 0;
551 clear(p);
554 void controller_frame_vector::append(controller_frame frame) throw(std::bad_alloc, std::runtime_error)
556 controller_frame check(*types);
557 if(!check.types_match(frame))
558 throw std::runtime_error("controller_frame_vector::append: Type mismatch");
559 if(frames % frames_per_page == 0) {
560 //Create new page.
561 pages[frames / frames_per_page];
563 //Write the entry.
564 size_t page = frames / frames_per_page;
565 size_t offset = frame_size * (frames % frames_per_page);
566 if(cache_page_num != page) {
567 cache_page_num = page;
568 cache_page = &pages[page];
570 controller_frame(cache_page->content + offset, *types) = frame;
571 if(frame.sync()) real_frame_count++;
572 frames++;
575 controller_frame_vector::controller_frame_vector(const controller_frame_vector& vector) throw(std::bad_alloc)
577 real_frame_count = 0;
578 freeze_count = 0;
579 clear(*vector.types);
580 *this = vector;
583 controller_frame_vector& controller_frame_vector::operator=(const controller_frame_vector& v)
584 throw(std::bad_alloc)
586 if(this == &v)
587 return *this;
588 uint64_t old_frame_count = real_frame_count;
589 resize(v.frames);
590 clear_cache();
592 //Copy the fields.
593 frame_size = v.frame_size;
594 frames_per_page = v.frames_per_page;
595 types = v.types;
596 real_frame_count = v.real_frame_count;
598 //This can't fail anymore. Copy the raw page contents.
599 size_t pagecount = (frames + frames_per_page - 1) / frames_per_page;
600 for(size_t i = 0; i < pagecount; i++) {
601 page& pg = pages[i];
602 const page& pg2 = v.pages.find(i)->second;
603 pg = pg2;
605 call_framecount_notification(old_frame_count);
606 return *this;
609 void controller_frame_vector::resize(size_t newsize) throw(std::bad_alloc)
611 clear_cache();
612 if(newsize == 0) {
613 clear();
614 } else if(newsize < frames) {
615 //Shrink movie.
616 uint64_t old_frame_count = real_frame_count;
617 for(size_t i = newsize; i < frames; i++)
618 if((*this)[i].sync()) real_frame_count--;
619 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
620 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
621 for(size_t i = pages_needed; i < current_pages; i++)
622 pages.erase(i);
623 //Now zeroize the excess memory.
624 if(newsize < pages_needed * frames_per_page) {
625 size_t offset = frame_size * (newsize % frames_per_page);
626 memset(pages[pages_needed - 1].content + offset, 0, CONTROLLER_PAGE_SIZE - offset);
628 frames = newsize;
629 call_framecount_notification(old_frame_count);
630 } else if(newsize > frames) {
631 //Enlarge movie.
632 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
633 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
634 //Create the needed pages.
635 for(size_t i = current_pages; i < pages_needed; i++) {
636 try {
637 pages[i];
638 } catch(...) {
639 for(size_t i = current_pages; i < pages_needed; i++)
640 if(pages.count(i))
641 pages.erase(i);
642 throw;
645 frames = newsize;
646 //This can use real_frame_count, because the real frame count won't change.
647 call_framecount_notification(real_frame_count);
651 bool controller_frame_vector::compatible(controller_frame_vector& with, uint64_t frame, const uint32_t* polls)
653 //Types have to match.
654 if(get_types() != with.get_types())
655 return false;
656 const port_type_set& pset = with.get_types();
657 //If new movie is before first frame, anything with same project_id is compatible.
658 if(frame == 0)
659 return true;
660 //Scan both movies until frame syncs are seen. Out of bounds reads behave as all neutral but frame
661 //sync done.
662 uint64_t syncs_seen = 0;
663 uint64_t frames_read = 0;
664 size_t old_size = size();
665 size_t new_size = with.size();
666 size_t pagenum = 0;
667 size_t ocomplete_pages = old_size / frames_per_page; //Round DOWN
668 size_t ncomplete_pages = new_size / frames_per_page; //Round DOWN
669 size_t complete_pages = min(ocomplete_pages, ncomplete_pages);
670 while(syncs_seen + frames_per_page < frame - 1 && pagenum < complete_pages) {
671 //Fast process page. The above condition guarantees that these pages are completely used.
672 auto opagedata = pages[pagenum].content;
673 auto npagedata = with.pages[pagenum].content;
674 size_t pagedataamt = frames_per_page * frame_size;
675 if(memcmp(opagedata, npagedata, pagedataamt))
676 return false;
677 frames_read += frames_per_page;
678 pagenum++;
679 for(size_t i = 0; i < pagedataamt; i += frame_size)
680 if(opagedata[i] & 1) syncs_seen++;
682 while(syncs_seen < frame - 1) {
683 controller_frame oldc = blank_frame(true), newc = with.blank_frame(true);
684 if(frames_read < old_size)
685 oldc = (*this)[frames_read];
686 if(frames_read < new_size)
687 newc = with[frames_read];
688 if(oldc != newc)
689 return false; //Mismatch.
690 frames_read++;
691 if(newc.sync())
692 syncs_seen++;
694 //We increment the counter one time too many.
695 frames_read--;
696 //Current frame. We need to compare each control up to poll counter.
697 uint64_t readable_old_subframes = 0, readable_new_subframes = 0;
698 uint64_t oldlen = find_next_sync(*this, frames_read);
699 uint64_t newlen = find_next_sync(with, frames_read);
700 if(frames_read < oldlen)
701 readable_old_subframes = oldlen - frames_read;
702 if(frames_read < newlen)
703 readable_new_subframes = newlen - frames_read;
704 //Then rest of the stuff.
705 for(unsigned i = 0; i < pset.indices(); i++) {
706 uint32_t p = polls[i] & 0x7FFFFFFFUL;
707 short ov = 0, nv = 0;
708 for(uint32_t j = 0; j < p; j++) {
709 if(j < readable_old_subframes)
710 ov = (*this)[j + frames_read].axis2(i);
711 if(j < readable_new_subframes)
712 nv = with[j + frames_read].axis2(i);
713 if(ov != nv)
714 return false;
717 return true;
720 uint64_t controller_frame_vector::binary_size() const throw()
722 return size() * get_stride();
725 void controller_frame_vector::save_binary(binarystream::output& stream) const throw(std::runtime_error)
727 uint64_t pages = get_page_count();
728 uint64_t stride = get_stride();
729 uint64_t pageframes = get_frames_per_page();
730 uint64_t vsize = size();
731 size_t pagenum = 0;
732 while(vsize > 0) {
733 uint64_t count = (vsize > pageframes) ? pageframes : vsize;
734 size_t bytes = count * stride;
735 const unsigned char* content = get_page_buffer(pagenum++);
736 stream.raw(content, bytes);
737 vsize -= count;
741 void controller_frame_vector::load_binary(binarystream::input& stream) throw(std::bad_alloc, std::runtime_error)
743 uint64_t stride = get_stride();
744 uint64_t pageframes = get_frames_per_page();
745 uint64_t vsize = 0;
746 size_t pagenum = 0;
747 uint64_t pagesize = stride * pageframes;
748 while(stream.get_left()) {
749 resize(vsize + pageframes);
750 unsigned char* contents = get_page_buffer(pagenum++);
751 uint64_t gcount = min(pagesize, stream.get_left());
752 stream.raw(contents, gcount);
753 vsize += (gcount / stride);
755 resize(vsize);
756 recount_frames();
759 void controller_frame_vector::swap_data(controller_frame_vector& v) throw()
761 uint64_t toldsize = real_frame_count;
762 uint64_t voldsize = v.real_frame_count;
763 std::swap(pages, v.pages);
764 std::swap(frames_per_page, v.frames_per_page);
765 std::swap(frame_size, v.frame_size);
766 std::swap(frames, v.frames);
767 std::swap(types, v.types);
768 std::swap(cache_page_num, v.cache_page_num);
769 std::swap(cache_page, v.cache_page);
770 std::swap(real_frame_count, v.real_frame_count);
771 if(!freeze_count)
772 call_framecount_notification(toldsize);
773 if(!v.freeze_count)
774 v.call_framecount_notification(voldsize);
777 controller_frame::controller_frame() throw()
779 memset(memory, 0, sizeof(memory));
780 backing = memory;
781 types = &dummytypes();
782 host = NULL;
785 unsigned port_controller::analog_actions() const
787 unsigned r = 0, s = 0;
788 for(unsigned i = 0; i < buttons.size(); i++) {
789 if(buttons[i].shadow)
790 continue;
791 switch(buttons[i].type) {
792 case port_controller_button::TYPE_AXIS:
793 case port_controller_button::TYPE_RAXIS:
794 case port_controller_button::TYPE_LIGHTGUN:
795 r++;
796 break;
797 case port_controller_button::TYPE_TAXIS:
798 s++;
799 break;
802 return (r + 1)/ 2 + s;
805 std::pair<unsigned, unsigned> port_controller::analog_action(unsigned k) const
807 unsigned x1 = std::numeric_limits<unsigned>::max();
808 unsigned x2 = std::numeric_limits<unsigned>::max();
809 unsigned r = 0;
810 bool second = false;
811 bool selecting = false;
812 for(unsigned i = 0; i < buttons.size(); i++) {
813 if(buttons[i].shadow)
814 continue;
815 switch(buttons[i].type) {
816 case port_controller_button::TYPE_AXIS:
817 case port_controller_button::TYPE_RAXIS:
818 case port_controller_button::TYPE_LIGHTGUN:
819 if(selecting) {
820 x2 = i;
821 goto out;
823 if(r == k && !second) {
824 //This and following.
825 x1 = i;
826 selecting = true;
828 if(!second)
829 r++;
830 second = !second;
831 break;
832 case port_controller_button::TYPE_TAXIS:
833 if(selecting)
834 break;
835 if(r == k) {
836 x1 = i;
837 goto out;
839 r++;
840 break;
843 out:
844 return std::make_pair(x1, x2);
847 namespace
849 std::string macro_field_as_string(const JSON::node& parent, const std::string& path)
851 const JSON::node& n = parent.follow(path);
852 if(n.type() != JSON::string)
853 (stringfmt() << "Expected string as field '" << path << "'").throwex();
854 return n.as_string8();
857 bool macro_field_as_boolean(const JSON::node& parent, const std::string& path)
859 const JSON::node& n = parent.follow(path);
860 if(n.type() != JSON::boolean)
861 (stringfmt() << "Expected boolean as field '" << path << "'").throwex();
862 return n.as_bool();
865 const JSON::node& macro_field_as_array(const JSON::node& parent, const std::string& path)
867 const JSON::node& n = parent.follow(path);
868 if(n.type() != JSON::array)
869 (stringfmt() << "Expected array as field '" << path << "'").throwex();
870 return n;
874 controller_macro_data::controller_macro_data(const std::string& spec, const JSON::node& desc, unsigned inum)
876 _descriptor = desc;
877 unsigned btnnum = 0;
878 std::map<std::string, unsigned> symbols;
879 if(desc.type() != JSON::array)
880 (stringfmt() << "Expected controller descriptor " << (inum + 1) << " to be an array");
881 for(auto i = desc.begin(); i != desc.end(); ++i) {
882 if(i->type() == JSON::string) {
883 symbols[i->as_string8()] = btnnum++;
884 btnmap.push_back(i.index());
885 } else if(i->type() == JSON::number) {
886 uint64_t anum = i->as_uint();
887 if(anum > aaxes.size())
888 (stringfmt() << "Descriptor axis number " << anum << " out of range in descriptor "
889 << (inum + 1)).throwex();
890 else if(anum == aaxes.size())
891 aaxes.push_back(std::make_pair(i.index(), std::numeric_limits<unsigned>::max()));
892 else
893 aaxes[anum].second = i.index();
894 } else
895 (stringfmt() << "Controller descriptor " << (inum + 1) << " contains element of unknown"
896 << "kind").throwex();
898 buttons = symbols.size();
899 orig = spec;
900 enabled = true;
901 autoterminate = false;
903 std::deque<size_t> stack;
904 bool in_sparen = false;
905 bool first = true;
906 bool btn_token = false;
907 bool btn_token_next = false;
908 size_t last_bit = 0;
909 size_t last_size = 0;
910 size_t astride = aaxes.size();
911 size_t stride = get_stride();
912 size_t idx = 0;
913 size_t len = spec.length();
914 try {
915 while(idx < len) {
916 btn_token = btn_token_next;
917 btn_token_next = false;
918 unsigned char ch = spec[idx];
919 if(autoterminate)
920 throw std::runtime_error("Asterisk must be the last thing");
921 if(ch == '(') {
922 if(in_sparen)
923 throw std::runtime_error("Parentheses in square brackets not allowed");
924 stack.push_back(data.size());
925 } else if(ch == ')') {
926 if(in_sparen)
927 throw std::runtime_error("Parentheses in square brackets not allowed");
928 if(stack.empty())
929 throw std::runtime_error("Unmatched right parenthesis");
930 size_t x = stack.back();
931 stack.pop_back();
932 last_size = (data.size() - x) / stride;
933 } else if(ch == '*') {
934 autoterminate = true;
935 } else if(ch == '?') {
936 if(!btn_token)
937 throw std::runtime_error("? needs button to apply to");
938 if(!in_sparen)
939 throw std::runtime_error("? needs to be in brackets");
940 data[data.size() - stride + last_bit] |= 2;
941 } else if(ch == '[') {
942 if(in_sparen)
943 throw std::runtime_error("Nested square brackets not allowed");
944 in_sparen = true;
945 data.resize(data.size() + stride);
946 adata.resize(adata.size() + astride);
947 last_size = 1;
948 } else if(ch == ']') {
949 if(!in_sparen)
950 throw std::runtime_error("Unmatched right square bracket");
951 in_sparen = false;
952 } else if(ch == '.') {
953 if(!in_sparen) {
954 data.resize(data.size() + stride);
955 adata.resize(adata.size() + astride);
956 last_size = 1;
958 } else if(spec[idx] >= '0' && spec[idx] <= '9') {
959 size_t rep = 0;
960 unsigned i = 0;
961 while(spec[idx + i] >= '0' && spec[idx + i] <= '9') {
962 rep = 10 * rep + (spec[idx + i] - '0');
963 i++;
965 if(in_sparen) {
966 //This has special meaning: Axis transform.
967 //Rep is the axis pair to operate on.
968 if(spec[idx + i] != ':')
969 throw std::runtime_error("Expected ':' in axis transform");
970 size_t sep = i;
971 while(idx + i < len && spec[idx + i] != '@')
972 i++;
973 if(idx + i >= len)
974 throw std::runtime_error("Expected '@' in axis transform");
975 std::string aexpr = spec.substr(idx + sep + 1, i - sep - 1);
976 if(rep >= astride)
977 throw std::runtime_error("Axis transform refers to invalid axis");
978 adata[adata.size() - astride + rep] = axis_transform(aexpr);
979 i++;
980 } else {
981 if(first)
982 throw std::runtime_error("Repeat not allowed without frame to "
983 "repeat");
984 size_t o = data.size();
985 size_t ao = adata.size();
986 data.resize(o + (rep - 1) * last_size * stride);
987 adata.resize(ao + (rep - 1) * last_size * astride);
988 for(unsigned i = 1; i < rep; i++) {
989 memcpy(&data[o + (i - 1) * last_size * stride], &data[o - last_size *
990 stride], last_size * stride);
991 memcpy(&data[ao + (i - 1) * last_size * astride], &data[ao -
992 last_size * astride], last_size * astride);
994 last_size = last_size * rep;
996 idx = idx + (i - 1);
997 } else { //Symbol.
998 bool found = false;
999 for(auto k : symbols) {
1000 std::string key = k.first;
1001 size_t j;
1002 for(j = 0; idx + j < len && j < key.length(); j++)
1003 if(spec[idx + j] != key[j])
1004 break;
1005 if(j == key.length()) {
1006 idx += key.length() - 1;
1007 found = true;
1008 if(!in_sparen) {
1009 data.resize(data.size() + stride);
1010 adata.resize(adata.size() + astride);
1012 last_bit = k.second;
1013 data[data.size() - stride + k.second] |= 1;
1014 if(!in_sparen)
1015 last_size = 1;
1018 if(!found)
1019 throw std::runtime_error("Unknown character or button");
1020 btn_token_next = true;
1022 idx++;
1023 first = false;
1025 if(in_sparen)
1026 throw std::runtime_error("Unmatched left square bracket");
1027 if(!stack.empty())
1028 throw std::runtime_error("Unmatched left parenthesis");
1029 } catch(std::exception& e) {
1030 (stringfmt() << "Error parsing macro for controller " << (inum + 1) << ": " << e.what()).throwex();
1034 bool controller_macro_data::syntax_check(const std::string& spec, const JSON::node& desc)
1036 unsigned buttons = 0;
1037 size_t astride = 0;
1038 if(desc.type() != JSON::array)
1039 return false;
1040 for(auto i = desc.begin(); i != desc.end(); ++i) {
1041 if(i->type() == JSON::string)
1042 buttons++;
1043 else if(i->type() == JSON::number) {
1044 uint64_t anum = i->as_uint();
1045 if(anum > astride)
1046 return false;
1047 else if(anum == astride)
1048 astride++;
1049 } else
1050 return false;
1052 bool autoterminate = false;
1053 size_t depth = 0;
1054 bool in_sparen = false;
1055 bool first = true;
1056 bool btn_token = false;
1057 bool btn_token_next = false;
1058 size_t idx = 0;
1059 size_t len = spec.length();
1060 while(idx < len) {
1061 btn_token = btn_token_next;
1062 btn_token_next = false;
1063 unsigned char ch = spec[idx];
1064 if(autoterminate)
1065 return false;
1066 if(ch == '(') {
1067 if(in_sparen)
1068 return false;
1069 depth++;
1070 } else if(ch == ')') {
1071 if(in_sparen)
1072 return false;
1073 if(!depth)
1074 return false;
1075 depth--;
1076 } else if(ch == '*') {
1077 autoterminate = true;
1078 } else if(ch == '?') {
1079 if(!btn_token || !in_sparen)
1080 return false;
1081 } else if(ch == '[') {
1082 if(in_sparen)
1083 return false;
1084 in_sparen = true;
1085 } else if(ch == ']') {
1086 if(!in_sparen)
1087 return false;
1088 in_sparen = false;
1089 } else if(ch == '.') {
1090 } else if(spec[idx] >= '0' && spec[idx] <= '9') {
1091 size_t rep = 0;
1092 unsigned i = 0;
1093 while(spec[idx + i] >= '0' && spec[idx + i] <= '9') {
1094 rep = 10 * rep + (spec[idx + i] - '0');
1095 i++;
1097 if(in_sparen) {
1098 //This has special meaning: Axis transform.
1099 //Rep is the axis pair to operate on.
1100 if(spec[idx + i] != ':')
1101 return false;
1102 size_t sep = i;
1103 while(idx + i < len && spec[idx + i] != '@')
1104 i++;
1105 if(idx + i >= len)
1106 return false;
1107 if(rep >= astride)
1108 return false;
1109 try {
1110 std::string aexpr = spec.substr(idx + sep + 1, i - sep - 1);
1111 axis_transform x(aexpr);
1112 } catch(...) {
1113 return false;
1115 i++;
1116 } else {
1117 if(first)
1118 return false;
1120 idx = idx + (i - 1);
1121 } else { //Symbol.
1122 bool found = false;
1123 for(auto i = desc.begin(); i != desc.end(); ++i) {
1124 if(i->type() != JSON::string)
1125 continue;
1126 std::string key = i->as_string8();
1127 size_t j;
1128 for(j = 0; idx + j < len && j < key.length(); j++)
1129 if(spec[idx + j] != key[j])
1130 break;
1131 if(j == key.length()) {
1132 idx += key.length() - 1;
1133 found = true;
1136 if(!found)
1137 return false;
1138 btn_token_next = true;
1140 idx++;
1141 first = false;
1143 if(in_sparen)
1144 return false;
1145 if(depth)
1146 return false;
1147 return true;
1150 void controller_macro_data::write(controller_frame& frame, unsigned port, unsigned controller, int64_t nframe,
1151 apply_mode amode)
1153 if(!enabled)
1154 return;
1155 if(autoterminate && (nframe < 0 || nframe >= get_frames()))
1156 return;
1157 if(nframe < 0)
1158 nframe += ((-nframe / get_frames()) + 3) * get_frames();
1159 nframe %= get_frames();
1160 for(size_t i = 0; i < buttons; i++) {
1161 unsigned lb = btnmap[i];
1162 unsigned st = data[nframe * get_stride() + i];
1163 if(st == 3)
1164 st = macro_random_bit();
1165 if(st == 1)
1166 switch(amode) {
1167 case AM_OVERWRITE:
1168 case AM_OR:
1169 frame.axis3(port, controller, lb, 1);
1170 break;
1171 case AM_XOR:
1172 frame.axis3(port, controller, lb, frame.axis3(port, controller, lb) ^ 1);
1173 break;
1175 else
1176 switch(amode) {
1177 case AM_OVERWRITE:
1178 frame.axis3(port, controller, lb, 0);
1179 break;
1182 const port_controller* _ctrl = frame.porttypes().port_type(port).controller_info->get(controller);
1183 if(!_ctrl)
1184 return;
1185 size_t abuttons = aaxes.size();
1186 for(size_t i = 0; i < abuttons; i++) {
1187 unsigned ax = aaxes[i].first;
1188 unsigned ay = aaxes[i].second;
1189 if(ay != std::numeric_limits<unsigned>::max()) {
1190 if(ax > _ctrl->buttons.size()) continue;
1191 if(ay > _ctrl->buttons.size()) continue;
1192 auto g = adata[nframe * abuttons + i].transform(_ctrl->buttons[ax], _ctrl->buttons[ay],
1193 frame.axis3(port, controller, ax), frame.axis3(port, controller, ay));
1194 frame.axis3(port, controller, ax, g.first);
1195 frame.axis3(port, controller, ay, g.second);
1196 } else {
1197 if(ax > _ctrl->buttons.size()) continue;
1198 int16_t g = adata[nframe * abuttons + i].transform(_ctrl->buttons[ax],
1199 frame.axis3(port, controller, ax));
1200 frame.axis3(port, controller, ax, g);
1205 std::string controller_macro_data::dump(const port_controller& ctrl)
1207 std::ostringstream o;
1208 for(size_t i = 0; i < get_frames(); i++) {
1209 o << "[";
1210 for(size_t j = 0; j < aaxes.size(); j++) {
1211 controller_macro_data::axis_transform& t = adata[i * aaxes.size() + j];
1212 o << j << ":";
1213 o << t.coeffs[0] << "," << t.coeffs[1] << "," << t.coeffs[2] << ",";
1214 o << t.coeffs[3] << "," << t.coeffs[4] << "," << t.coeffs[5] << "@";
1216 for(size_t j = 0; j < buttons && j < ctrl.buttons.size(); j++) {
1217 unsigned st = data[i * get_stride() + j];
1218 if(ctrl.buttons[j].macro == "")
1219 continue;
1220 if(st == 1)
1221 o << ctrl.buttons[j].macro;
1222 if(st == 3)
1223 o << ctrl.buttons[j].macro << "?";
1225 o << "]";
1227 if(autoterminate)
1228 o << "*";
1229 return o.str();
1232 void controller_macro::write(controller_frame& frame, int64_t nframe)
1234 for(auto& i : macros) {
1235 unsigned port;
1236 unsigned controller;
1237 try {
1238 auto g = frame.porttypes().lcid_to_pcid(i.first);
1239 port = g.first;
1240 controller = g.second;
1241 } catch(...) {
1242 continue;
1244 i.second.write(frame, port, controller, nframe, amode);
1248 int16_t controller_macro_data::axis_transform::transform(const port_controller_button& b, int16_t v)
1250 return scale_axis(b, coeffs[0] * unscale_axis(b, v) + coeffs[4]);
1253 std::pair<int16_t, int16_t> controller_macro_data::axis_transform::transform(const port_controller_button& b1,
1254 const port_controller_button& b2, int16_t v1, int16_t v2)
1256 double x, y, u, v, au, av, s;
1257 x = unscale_axis(b1, v1);
1258 y = unscale_axis(b2, v2);
1259 u = coeffs[0] * x + coeffs[1] * y + coeffs[4];
1260 v = coeffs[2] * x + coeffs[3] * y + coeffs[5];
1261 au = abs(u);
1262 av = abs(v);
1263 s = max(max(au, 1.0), max(av, 1.0));
1264 //If u and v exceed nominal range of [-1,1], those need to be projected to the edge.
1265 if(s > 1) {
1266 u /= s;
1267 v /= s;
1269 auto g = std::make_pair(scale_axis(b1, u), scale_axis(b2, v));
1270 return g;
1273 double controller_macro_data::axis_transform::unscale_axis(const port_controller_button& b, int16_t v)
1275 if(b.centers) {
1276 int32_t center = ((int32_t)b.rmin + (int32_t)b.rmax) / 2;
1277 if(v <= b.rmin)
1278 return -1;
1279 if(v < center)
1280 return -(center - (double)v) / (center - b.rmin);
1281 if(v == center)
1282 return 0;
1283 if(v < b.rmax)
1284 return ((double)v - center) / (b.rmax - center);
1285 return 1;
1286 } else {
1287 if(v <= b.rmin)
1288 return 0;
1289 if(v >= b.rmax)
1290 return 1;
1291 return ((double)v - b.rmin) / (b.rmax - b.rmin);
1295 int16_t controller_macro_data::axis_transform::scale_axis(const port_controller_button& b, double v)
1297 if(b.centers) {
1298 int32_t center = ((int32_t)b.rmin + (int32_t)b.rmax) / 2;
1299 if(v == 0)
1300 return center;
1301 if(v < 0) {
1302 double v2 = v * (center - b.rmin) + center;
1303 if(v2 < b.rmin)
1304 return b.rmin;
1305 return v2;
1307 double v2 = v * (b.rmax - center) + center;
1308 if(v2 > b.rmax)
1309 return b.rmax;
1310 return v2;
1311 } else {
1312 double v2 = v * (b.rmax - b.rmin) + b.rmin;
1313 if(v2 < b.rmin)
1314 return b.rmin;
1315 if(v2 > b.rmax)
1316 return b.rmax;
1317 return v2;
1321 namespace
1323 std::complex<double> parse_complex(const std::string& expr)
1325 regex_results r;
1326 if(r = regex("\\((.*),(.*)\\)", expr)) {
1327 //Real,Imaginary.
1328 return std::complex<double>(parse_value<double>(r[1]), parse_value<double>(r[2]));
1329 } else if(r = regex("\\((.*)<(.*)\\)", expr)) {
1330 return std::polar(parse_value<double>(r[1]), parse_value<double>(r[2]) * M_PI / 180);
1331 } else {
1332 return std::complex<double>(parse_value<double>(expr), 0.0);
1337 controller_macro_data::axis_transform::axis_transform(const std::string& expr)
1339 regex_results r;
1340 if(r = regex("\\*(.*)\\+(.*)", expr)) {
1341 //Affine transform.
1342 std::complex<double> a = parse_complex(r[1]);
1343 std::complex<double> b = parse_complex(r[2]);
1344 coeffs[0] = a.real();
1345 coeffs[1] = -a.imag();
1346 coeffs[2] = a.imag();
1347 coeffs[3] = a.real();
1348 coeffs[4] = b.real();
1349 coeffs[5] = b.imag();
1350 } else if(r = regex("\\*(.*)", expr)) {
1351 //Linear transform.
1352 std::complex<double> a = parse_complex(r[1]);
1353 coeffs[0] = a.real();
1354 coeffs[1] = -a.imag();
1355 coeffs[2] = a.imag();
1356 coeffs[3] = a.real();
1357 coeffs[4] = 0;
1358 coeffs[5] = 0;
1359 } else if(r = regex("\\+(.*)", expr)) {
1360 //Relative
1361 std::complex<double> b = parse_complex(r[1]);
1362 coeffs[0] = 1;
1363 coeffs[1] = 0;
1364 coeffs[2] = 0;
1365 coeffs[3] = 1;
1366 coeffs[4] = b.real();
1367 coeffs[5] = b.imag();
1368 } else if(r = regex("(.*),(.*),(.*),(.*),(.*),(.*)", expr)) {
1369 //Full affine.
1370 coeffs[0] = parse_value<double>(r[1]);
1371 coeffs[1] = parse_value<double>(r[2]);
1372 coeffs[2] = parse_value<double>(r[3]);
1373 coeffs[3] = parse_value<double>(r[4]);
1374 coeffs[4] = parse_value<double>(r[5]);
1375 coeffs[5] = parse_value<double>(r[6]);
1376 } else {
1377 //Absolute.
1378 std::complex<double> b = parse_complex(expr);
1379 coeffs[0] = 0;
1380 coeffs[1] = 0;
1381 coeffs[2] = 0;
1382 coeffs[3] = 0;
1383 coeffs[4] = b.real();
1384 coeffs[5] = b.imag();
1388 JSON::node controller_macro::serialize()
1390 JSON::node v(JSON::object);
1391 switch(amode) {
1392 case controller_macro_data::AM_OVERWRITE: v.insert("mode", JSON::s("overwrite")); break;
1393 case controller_macro_data::AM_OR: v.insert("mode", JSON::s("or")); break;
1394 case controller_macro_data::AM_XOR: v.insert("mode", JSON::s("xor")); break;
1396 JSON::node& c = v.insert("data", JSON::array());
1397 for(auto& i : macros) {
1398 while(i.first > c.index_count())
1399 c.append(JSON::n());
1400 i.second.serialize(c.append(JSON::n()));
1402 return v;
1405 void controller_macro_data::serialize(JSON::node& v)
1407 v = JSON::object();
1408 v.insert("enable", JSON::b(enabled));
1409 v.insert("expr", JSON::s(orig));
1410 v.insert("desc", _descriptor);
1413 JSON::node controller_macro_data::make_descriptor(const port_controller& ctrl)
1415 JSON::node n(JSON::array);
1416 for(size_t i = 0; i < ctrl.buttons.size(); i++) {
1417 if(ctrl.buttons[i].macro != "")
1418 n.append(JSON::s(ctrl.buttons[i].macro));
1419 else
1420 n.append(JSON::n()); //Placeholder.
1422 for(size_t i = 0; i < ctrl.analog_actions(); i++) {
1423 auto g = ctrl.analog_action(i);
1424 n.index(g.first) = JSON::u(i);
1425 if(g.second != std::numeric_limits<unsigned>::max())
1426 n.index(g.second) = JSON::u(i);
1428 return n;
1431 controller_macro::controller_macro(const JSON::node& v)
1433 if(v.type() != JSON::object)
1434 throw std::runtime_error("Expected macro to be JSON object");
1435 std::string mode = macro_field_as_string(v, "mode");
1436 if(mode == "overwrite") amode = controller_macro_data::AM_OVERWRITE;
1437 else if(mode == "or") amode = controller_macro_data::AM_OR;
1438 else if(mode == "xor") amode = controller_macro_data::AM_XOR;
1439 else (stringfmt() << "Unknown button mode '" << mode << "'").throwex();
1440 const JSON::node& c = macro_field_as_array(v, "data");
1441 for(auto i = c.begin(); i != c.end(); ++i) {
1442 if(i->type() == JSON::object)
1443 macros[i.index()] = controller_macro_data(*i, i.index());
1444 else
1445 (stringfmt() << "Expected object as field 'data/" << i.index() << "'").throwex();
1449 controller_macro_data::controller_macro_data(const JSON::node& v, unsigned i)
1450 : controller_macro_data(macro_field_as_string(v, "expr"), macro_field_as_array(v, "desc"), i)
1452 enabled = macro_field_as_boolean(v, "enable");