Actually call on_reset callback
[lsnes.git] / src / library / portctrl-data.cpp
blobde49f145a2be29a10325173ad285e6010eafe495
1 #include "binarystream.hpp"
2 #include "portctrl-data.hpp"
3 #include "threads.hpp"
4 #include "minmax.hpp"
5 #include "globalwrap.hpp"
6 #include "serialization.hpp"
7 #include "string.hpp"
8 #include "sha256.hpp"
9 #include <iostream>
10 #include <sys/time.h>
11 #include <sstream>
12 #include <list>
13 #include <deque>
14 #include <complex>
16 namespace portctrl
18 const char* movie_page_id = "Input tracks";
19 namespace
21 controller simple_controller = {"(system)", "system", {}};
22 controller_set simple_port = {"system", "system", "system", {simple_controller},{0}};
24 struct porttype_basecontrol : public type
26 porttype_basecontrol() : type("basecontrol", "basecontrol", 1)
28 write = [](const type* _this, unsigned char* buffer, unsigned idx, unsigned ctrl,
29 short x) -> void {
30 if(idx > 0 || ctrl > 0) return;
31 buffer[0] = x ? 1 : 0;
33 read = [](const type* _this, const unsigned char* buffer, unsigned idx, unsigned ctrl) ->
34 short {
35 if(idx > 0 || ctrl > 0) return 0;
36 return buffer[0] ? 1 : 0;
38 serialize = [](const type* _this, const unsigned char* buffer, char* textbuf) -> size_t {
39 textbuf[0] = buffer[0] ? 'F' : '-';
40 textbuf[1] = '\0';
41 return 1;
43 deserialize = [](const type* _this, unsigned char* buffer, const char* textbuf) ->
44 size_t {
45 size_t ptr = 0;
46 buffer[0] = 0;
47 if(read_button_value(textbuf, ptr))
48 buffer[0] = 1;
49 skip_rest_of_field(textbuf, ptr, false);
50 return ptr;
52 controller_info = &simple_port;
56 unsigned macro_random_bit()
58 static unsigned char state[32];
59 static unsigned extracted = 256;
60 if(extracted == 256) {
61 timeval tv;
62 gettimeofday(&tv, NULL);
63 unsigned char buffer[48];
64 memcpy(buffer, state, 32);
65 serialization::u64b(buffer + 32, tv.tv_sec);
66 serialization::u64b(buffer + 40, tv.tv_usec);
67 sha256::hash(state, buffer, 48);
68 extracted = 0;
70 unsigned bit = extracted++;
71 return ((state[bit / 8] >> (bit % 8)) & 1);
75 type& get_default_system_port_type()
77 static porttype_basecontrol x;
78 return x;
81 type::type(const std::string& iname, const std::string& _hname, size_t ssize)
82 : hname(_hname), storage_size(ssize), name(iname)
86 type::~type() throw()
90 bool type::is_present(unsigned controller) const throw()
92 return controller_info->controllers.size() > controller;
95 namespace
97 size_t dummy_offset = 0;
98 type* dummy_type = &get_default_system_port_type();
99 unsigned dummy_index = 0;
100 struct binding
102 std::vector<type*> types;
103 type_set* stype;
104 bool matches(const std::vector<class type*>& x)
106 if(x.size() != types.size())
107 return false;
108 for(size_t i = 0; i < x.size(); i++)
109 if(x[i] != types[i])
110 return false;
111 return true;
114 std::list<binding>& bindings()
116 static std::list<binding> x;
117 return x;
121 type_set::type_set() throw()
124 port_offsets = &dummy_offset;
125 port_types = &dummy_type;
126 port_count = 1;
127 total_size = 1;
128 _indices.resize(1);
129 _indices[0].valid = true;
130 _indices[0].port = 0;
131 _indices[0].controller = 0;
132 _indices[0].control = 0;
134 port_multiplier = 1;
135 controller_multiplier = 1;
136 indices_size = 1;
137 indices_tab = &dummy_index;
140 type_set& type_set::make(std::vector<class type*> types, struct index_map control_map)
142 for(auto i : bindings())
143 if(i.matches(types))
144 return *(i.stype);
145 //Not found, create new.
146 type_set& ret = *new type_set(types, control_map);
147 binding b;
148 b.types = types;
149 b.stype = &ret;
150 bindings().push_back(b);
151 return ret;
154 type_set::type_set(std::vector<class type*> types, struct index_map control_map)
156 port_count = types.size();
157 //Verify legality of port types.
158 for(size_t i = 0; i < port_count; i++)
159 if(!types[i] || !types[i]->legal(i))
160 throw std::runtime_error("Illegal port types");
161 //Count maximum number of controller indices to determine the controller multiplier.
162 controller_multiplier = 1;
163 for(size_t i = 0; i < port_count; i++)
164 for(unsigned j = 0; j < types[i]->controller_info->controllers.size(); j++)
165 controller_multiplier = max(controller_multiplier, (size_t)types[i]->used_indices(j));
166 //Count maximum number of controllers to determine the port multiplier.
167 port_multiplier = 1;
168 for(size_t i = 0; i < port_count; i++)
169 port_multiplier = max(port_multiplier, controller_multiplier *
170 (size_t)types[i]->controller_info->controllers.size());
171 //Allocate the per-port tables.
172 port_offsets = new size_t[types.size()];
173 port_types = new class type*[types.size()];
174 //Determine the total size and offsets.
175 size_t offset = 0;
176 for(size_t i = 0; i < port_count; i++) {
177 port_offsets[i] = offset;
178 offset += types[i]->storage_size;
179 port_types[i] = types[i];
181 total_size = offset;
182 //Determine the index size and allocate it.
183 indices_size = port_multiplier * port_count;
184 indices_tab = new unsigned[indices_size];
185 for(size_t i = 0; i < indices_size; i++)
186 indices_tab[i] = 0xFFFFFFFFUL;
187 //Copy the index data (and reverse it).
188 controllers = control_map.logical_map;
189 legacy_pcids = control_map.pcid_map;
190 _indices = control_map.indices;
191 for(size_t j = 0; j < _indices.size(); j++) {
192 auto& i = _indices[j];
193 if(i.valid)
194 indices_tab[i.port * port_multiplier + i.controller * controller_multiplier + i.control] = j;
198 short read_axis_value(const char* buf, size_t& idx) throw()
200 char ch;
201 //Skip ws.
202 while(is_nonterminator(buf[idx])) {
203 char ch = buf[idx];
204 if(ch != ' ' && ch != '\t')
205 break;
206 idx++;
208 //Read the sign if any.
209 ch = buf[idx];
210 if(!is_nonterminator(ch))
211 return 0;
212 bool negative = false;
213 if(ch == '-') {
214 negative = true;
215 idx++;
217 if(ch == '+')
218 idx++;
220 //Read numeric value.
221 int numval = 0;
222 while(is_nonterminator(buf[idx]) && isdigit(static_cast<unsigned char>(ch = buf[idx]))) {
223 numval = numval * 10 + (ch - '0');
224 idx++;
226 if(negative)
227 numval = -numval;
229 return static_cast<short>(numval);
232 size_t write_axis_value(char* buf, short _v)
234 int v = _v;
235 size_t r = 0;
236 buf[r++] = ' ';
237 if(v < 0) { buf[r++] = '-'; v = -v; }
238 if(v >= 10000) buf[r++] = '0' + (v / 10000 % 10);
239 if(v >= 1000) buf[r++] = '0' + (v / 1000 % 10);
240 if(v >= 100) buf[r++] = '0' + (v / 100 % 10);
241 if(v >= 10) buf[r++] = '0' + (v / 10 % 10);
242 buf[r++] = '0' + (v % 10);
243 return r;
246 namespace
248 type_set& dummytypes()
250 static type_set x;
251 return x;
254 size_t writeu32val(char32_t* buf, int val)
256 char c[12];
257 size_t i;
258 sprintf(c, "%d", val);
259 for(i = 0; c[i]; i++)
260 buf[i] = c[i];
261 return i;
264 uint64_t find_next_sync(frame_vector& movie, uint64_t after)
266 if(after >= movie.size())
267 return after;
268 do {
269 after++;
270 } while(after < movie.size() && !movie[after].sync());
271 return after;
275 void frame::display(unsigned port, unsigned controller_n, char32_t* buf) throw()
277 if(port >= types->ports()) {
278 //Bad port.
279 *buf = '\0';
280 return;
282 uint8_t* backingmem = backing + types->port_offset(port);
283 const type& ptype = types->port_type(port);
284 if(controller_n >= ptype.controller_info->controllers.size()) {
285 //Bad controller.
286 *buf = '\0';
287 return;
289 const controller& pc = ptype.controller_info->controllers[controller_n];
290 bool need_space = false;
291 short val;
292 for(unsigned i = 0; i < pc.buttons.size(); i++) {
293 const button& pcb = pc.buttons[i];
294 if(need_space && pcb.type != button::TYPE_NULL) {
295 need_space = false;
296 *(buf++) = ' ';
298 switch(pcb.type) {
299 case button::TYPE_NULL:
300 break;
301 case button::TYPE_BUTTON:
302 *(buf++) = ptype.read(&ptype, backingmem, controller_n, i) ? pcb.symbol : U'-';
303 break;
304 case button::TYPE_AXIS:
305 case button::TYPE_RAXIS:
306 case button::TYPE_TAXIS:
307 case button::TYPE_LIGHTGUN:
308 val = ptype.read(&ptype, backingmem, controller_n, i);
309 buf += writeu32val(buf, val);
310 need_space = true;
311 break;
314 *buf = '\0';
317 counters::counters()
319 types = &dummytypes();
320 ctrs = new uint32_t[types->indices()];
321 clear();
324 counters::counters(const type_set& p)
326 types = &p;
327 ctrs = new uint32_t[types->indices()];
328 clear();
331 counters::counters(const counters& p)
333 ctrs = new uint32_t[p.types->indices()];
334 types = p.types;
335 memcpy(ctrs, p.ctrs, sizeof(uint32_t) * p.types->indices());
336 framepflag = p.framepflag;
339 counters& counters::operator=(const counters& p)
341 if(this == &p)
342 return *this;
343 uint32_t* n = new uint32_t[p.types->indices()];
344 types = p.types;
345 memcpy(n, p.ctrs, sizeof(uint32_t) * p.types->indices());
346 delete[] ctrs;
347 ctrs = n;
348 framepflag = p.framepflag;
349 return *this;
352 counters::~counters() throw()
354 delete[] ctrs;
357 void counters::clear() throw()
359 memset(ctrs, 0, sizeof(uint32_t) * types->indices());
360 framepflag = false;
363 void counters::set_all_DRDY() throw()
365 for(size_t i = 0; i < types->indices(); i++)
366 ctrs[i] |= 0x80000000UL;
369 void counters::clear_DRDY(unsigned idx) throw()
371 ctrs[idx] &= 0x7FFFFFFFUL;
374 bool counters::get_DRDY(unsigned idx) throw()
376 return ((ctrs[idx] & 0x80000000UL) != 0);
379 bool counters::has_polled() throw()
381 uint32_t res = 0;
382 for(size_t i = 0; i < types->indices() ; i++)
383 res |= ctrs[i];
384 return ((res & 0x7FFFFFFFUL) != 0);
387 uint32_t counters::get_polls(unsigned idx) throw()
389 return ctrs[idx] & 0x7FFFFFFFUL;
392 uint32_t counters::increment_polls(unsigned idx) throw()
394 uint32_t x = ctrs[idx] & 0x7FFFFFFFUL;
395 ++ctrs[idx];
396 return x;
399 uint32_t counters::max_polls() throw()
401 uint32_t max = 0;
402 for(unsigned i = 0; i < types->indices(); i++) {
403 uint32_t tmp = ctrs[i] & 0x7FFFFFFFUL;
404 max = (max < tmp) ? tmp : max;
406 return max;
409 void counters::save_state(std::vector<uint32_t>& mem)
411 mem.resize(types->indices());
412 //Compatiblity fun.
413 for(size_t i = 0; i < types->indices(); i++)
414 mem[i] = ctrs[i];
417 void counters::load_state(const std::vector<uint32_t>& mem) throw()
419 for(size_t i = 0; i < types->indices(); i++)
420 ctrs[i] = mem[i];
423 bool counters::check(const std::vector<uint32_t>& mem) throw()
425 return (mem.size() == types->indices());
429 void counters::set_framepflag(bool value) throw()
431 framepflag = value;
434 bool counters::get_framepflag() const throw()
436 return framepflag;
439 frame::frame(const type_set& p)
441 memset(memory, 0, sizeof(memory));
442 backing = memory;
443 types = &p;
444 host = NULL;
447 frame::frame(unsigned char* mem, const type_set& p, frame_vector* _host)
449 if(!mem)
450 throw std::runtime_error("NULL backing memory not allowed");
451 memset(memory, 0, sizeof(memory));
452 backing = mem;
453 types = &p;
454 host = _host;
457 frame::frame(const frame& obj) throw()
459 memset(memory, 0, sizeof(memory));
460 backing = memory;
461 types = obj.types;
462 memcpy(backing, obj.backing, types->size());
463 host = NULL;
466 frame& frame::operator=(const frame& obj)
468 if(backing != memory && types != obj.types)
469 throw std::runtime_error("Port types do not match");
470 types = obj.types;
471 short old = sync();
472 memcpy(backing, obj.backing, types->size());
473 if(host) host->notify_sync_change(sync() - old);
474 return *this;
477 frame_vector::fchange_listener::~fchange_listener()
481 size_t frame_vector::walk_helper(size_t frame, bool sflag) throw()
483 size_t ret = sflag ? frame : 0;
484 if(frame >= frames)
485 return ret;
486 frame++;
487 ret++;
488 size_t page = frame / frames_per_page;
489 size_t offset = frame_size * (frame % frames_per_page);
490 size_t index = frame % frames_per_page;
491 if(cache_page_num != page) {
492 cache_page = &pages[page];
493 cache_page_num = page;
495 while(frame < frames) {
496 if(index == frames_per_page) {
497 page++;
498 cache_page = &pages[page];
499 cache_page_num = page;
500 index = 0;
501 offset = 0;
503 if(frame::sync(cache_page->content + offset))
504 break;
505 index++;
506 offset += frame_size;
507 frame++;
508 ret++;
510 return ret;
513 size_t frame_vector::recount_frames() throw()
515 uint64_t old_frame_count = real_frame_count;
516 size_t ret = 0;
517 if(!frames)
518 return 0;
519 cache_page_num = 0;
520 cache_page = &pages[0];
521 size_t offset = 0;
522 size_t index = 0;
523 for(size_t i = 0; i < frames; i++) {
524 if(index == frames_per_page) {
525 cache_page_num++;
526 cache_page = &pages[cache_page_num];
527 index = 0;
528 offset = 0;
530 if(frame::sync(cache_page->content + offset))
531 ret++;
532 index++;
533 offset += frame_size;
536 real_frame_count = ret;
537 call_framecount_notification(old_frame_count);
538 return ret;
541 void frame_vector::clear(const type_set& p)
543 uint64_t old_frame_count = real_frame_count;
544 frame_size = p.size();
545 frames_per_page = CONTROLLER_PAGE_SIZE / frame_size;
546 frames = 0;
547 types = &p;
548 clear_cache();
549 pages.clear();
550 real_frame_count = 0;
551 call_framecount_notification(old_frame_count);
554 frame_vector::~frame_vector() throw()
556 pages.clear();
557 cache_page = NULL;
560 frame_vector::frame_vector() throw()
561 : tracker(memtracker::singleton(), movie_page_id, sizeof(*this))
563 real_frame_count = 0;
564 freeze_count = 0;
565 clear(dummytypes());
568 frame_vector::frame_vector(const type_set& p) throw()
569 : tracker(memtracker::singleton(), movie_page_id, sizeof(*this))
571 real_frame_count = 0;
572 freeze_count = 0;
573 clear(p);
576 void frame_vector::append(frame cframe)
578 frame check(*types);
579 if(!check.types_match(cframe))
580 throw std::runtime_error("frame_vector::append: Type mismatch");
581 if(frames % frames_per_page == 0) {
582 //Create new page.
583 pages[frames / frames_per_page];
585 //Write the entry.
586 size_t page = frames / frames_per_page;
587 size_t offset = frame_size * (frames % frames_per_page);
588 if(cache_page_num != page) {
589 cache_page_num = page;
590 cache_page = &pages[page];
592 frame(cache_page->content + offset, *types) = cframe;
593 if(cframe.sync()) real_frame_count++;
594 frames++;
597 frame_vector::frame_vector(const frame_vector& vector)
598 : tracker(memtracker::singleton(), movie_page_id, sizeof(*this))
600 real_frame_count = 0;
601 freeze_count = 0;
602 clear(*vector.types);
603 *this = vector;
606 frame_vector& frame_vector::operator=(const frame_vector& v)
608 if(this == &v)
609 return *this;
610 uint64_t old_frame_count = real_frame_count;
611 resize(v.frames);
612 clear_cache();
614 //Copy the fields.
615 frame_size = v.frame_size;
616 frames_per_page = v.frames_per_page;
617 types = v.types;
618 real_frame_count = v.real_frame_count;
620 //This can't fail anymore. Copy the raw page contents.
621 size_t pagecount = (frames + frames_per_page - 1) / frames_per_page;
622 for(size_t i = 0; i < pagecount; i++) {
623 page& pg = pages[i];
624 const page& pg2 = v.pages.find(i)->second;
625 pg = pg2;
627 call_framecount_notification(old_frame_count);
628 return *this;
631 void frame_vector::resize(size_t newsize)
633 clear_cache();
634 if(newsize == 0) {
635 clear();
636 } else if(newsize < frames) {
637 //Shrink movie.
638 uint64_t old_frame_count = real_frame_count;
639 for(size_t i = newsize; i < frames; i++)
640 if((*this)[i].sync()) real_frame_count--;
641 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
642 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
643 for(size_t i = pages_needed; i < current_pages; i++)
644 pages.erase(i);
645 //Now zeroize the excess memory.
646 if(newsize < pages_needed * frames_per_page) {
647 size_t offset = frame_size * (newsize % frames_per_page);
648 memset(pages[pages_needed - 1].content + offset, 0, CONTROLLER_PAGE_SIZE - offset);
650 frames = newsize;
651 call_framecount_notification(old_frame_count);
652 } else if(newsize > frames) {
653 //Enlarge movie.
654 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
655 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
656 //Create the needed pages.
657 for(size_t i = current_pages; i < pages_needed; i++) {
658 try {
659 pages[i];
660 } catch(...) {
661 for(size_t i = current_pages; i < pages_needed; i++)
662 if(pages.count(i))
663 pages.erase(i);
664 throw;
667 frames = newsize;
668 //This can use real_frame_count, because the real frame count won't change.
669 call_framecount_notification(real_frame_count);
673 bool frame_vector::compatible(frame_vector& with, uint64_t nframe, const uint32_t* polls)
675 //Types have to match.
676 if(get_types() != with.get_types())
677 return false;
678 const type_set& pset = with.get_types();
679 //If new movie is before first frame, anything with same project_id is compatible.
680 if(nframe == 0)
681 return true;
682 //Scan both movies until frame syncs are seen. Out of bounds reads behave as all neutral but frame
683 //sync done.
684 uint64_t syncs_seen = 0;
685 uint64_t frames_read = 0;
686 size_t old_size = size();
687 size_t new_size = with.size();
688 size_t pagenum = 0;
689 size_t ocomplete_pages = old_size / frames_per_page; //Round DOWN
690 size_t ncomplete_pages = new_size / frames_per_page; //Round DOWN
691 size_t complete_pages = min(ocomplete_pages, ncomplete_pages);
692 while(syncs_seen + frames_per_page < nframe - 1 && pagenum < complete_pages) {
693 //Fast process page. The above condition guarantees that these pages are completely used.
694 auto opagedata = pages[pagenum].content;
695 auto npagedata = with.pages[pagenum].content;
696 size_t pagedataamt = frames_per_page * frame_size;
697 if(memcmp(opagedata, npagedata, pagedataamt))
698 return false;
699 frames_read += frames_per_page;
700 pagenum++;
701 for(size_t i = 0; i < pagedataamt; i += frame_size)
702 if(opagedata[i] & 1) syncs_seen++;
704 while(syncs_seen < nframe - 1) {
705 frame oldc = blank_frame(true), newc = with.blank_frame(true);
706 if(frames_read < old_size)
707 oldc = (*this)[frames_read];
708 if(frames_read < new_size)
709 newc = with[frames_read];
710 if(oldc != newc)
711 return false; //Mismatch.
712 frames_read++;
713 if(newc.sync())
714 syncs_seen++;
716 //We increment the counter one time too many.
717 frames_read--;
718 //Current frame. We need to compare each control up to poll counter.
719 uint64_t readable_old_subframes = 0, readable_new_subframes = 0;
720 uint64_t oldlen = find_next_sync(*this, frames_read);
721 uint64_t newlen = find_next_sync(with, frames_read);
722 if(frames_read < oldlen)
723 readable_old_subframes = oldlen - frames_read;
724 if(frames_read < newlen)
725 readable_new_subframes = newlen - frames_read;
726 //Then rest of the stuff.
727 for(unsigned i = 0; i < pset.indices(); i++) {
728 uint32_t p = polls[i] & 0x7FFFFFFFUL;
729 short ov = 0, nv = 0;
730 for(uint32_t j = 0; j < p; j++) {
731 if(j < readable_old_subframes)
732 ov = (*this)[j + frames_read].axis2(i);
733 if(j < readable_new_subframes)
734 nv = with[j + frames_read].axis2(i);
735 if(ov != nv)
736 return false;
739 return true;
742 uint64_t frame_vector::binary_size() const throw()
744 return size() * get_stride();
747 void frame_vector::save_binary(binarystream::output& stream) const
749 uint64_t stride = get_stride();
750 uint64_t pageframes = get_frames_per_page();
751 uint64_t vsize = size();
752 size_t pagenum = 0;
753 while(vsize > 0) {
754 uint64_t count = (vsize > pageframes) ? pageframes : vsize;
755 size_t bytes = count * stride;
756 const unsigned char* content = get_page_buffer(pagenum++);
757 stream.raw(content, bytes);
758 vsize -= count;
762 void frame_vector::load_binary(binarystream::input& stream)
764 uint64_t stride = get_stride();
765 uint64_t pageframes = get_frames_per_page();
766 uint64_t vsize = 0;
767 size_t pagenum = 0;
768 uint64_t pagesize = stride * pageframes;
769 while(stream.get_left()) {
770 resize(vsize + pageframes);
771 unsigned char* contents = get_page_buffer(pagenum++);
772 uint64_t gcount = min(pagesize, stream.get_left());
773 stream.raw(contents, gcount);
774 vsize += (gcount / stride);
776 resize(vsize);
777 recount_frames();
780 void frame_vector::swap_data(frame_vector& v) throw()
782 uint64_t toldsize = real_frame_count;
783 uint64_t voldsize = v.real_frame_count;
784 std::swap(pages, v.pages);
785 std::swap(frames_per_page, v.frames_per_page);
786 std::swap(frame_size, v.frame_size);
787 std::swap(frames, v.frames);
788 std::swap(types, v.types);
789 std::swap(cache_page_num, v.cache_page_num);
790 std::swap(cache_page, v.cache_page);
791 std::swap(real_frame_count, v.real_frame_count);
792 if(!freeze_count)
793 call_framecount_notification(toldsize);
794 if(!v.freeze_count)
795 v.call_framecount_notification(voldsize);
798 int64_t frame_vector::find_frame(uint64_t n)
800 if(!n) return -1;
801 uint64_t stride = get_stride();
802 uint64_t pageframes = get_frames_per_page();
803 uint64_t vsize = size();
804 size_t pagenum = 0;
805 while(vsize > 0) {
806 uint64_t count = (vsize > pageframes) ? pageframes : vsize;
807 const unsigned char* content = get_page_buffer(pagenum++);
808 size_t offset = 0;
809 for(unsigned i = 0; i < count; i++) {
810 if(frame::sync(content + offset)) n--;
811 if(n == 0) return (pagenum - 1) * pageframes + i;
812 offset += stride;
814 vsize -= count;
816 return -1;
819 int64_t frame_vector::subframe_to_frame(uint64_t n)
821 int64_t ret = 1;
822 uint64_t stride = get_stride();
823 uint64_t pageframes = get_frames_per_page();
824 uint64_t vsize = size();
825 if(n >= vsize) return -1;
826 size_t pagenum = 0;
827 size_t cpage = n / pageframes;
828 for(uint64_t p = 0; p < cpage; p++) {
829 const unsigned char* content = get_page_buffer(pagenum++);
830 size_t offset = 0;
831 for(unsigned i = 0; i < pageframes; i++) {
832 if(frame::sync(content + offset)) ret++;
833 offset += stride;
837 const unsigned char* content = get_page_buffer(pagenum++);
838 size_t offset = 0;
839 unsigned idx = n % pageframes;
840 for(unsigned i = 0; i < idx; i++) {
841 if(frame::sync(content + offset)) ret++;
842 offset += stride;
845 return ret;
848 frame::frame() throw()
850 memset(memory, 0, sizeof(memory));
851 backing = memory;
852 types = &dummytypes();
853 host = NULL;
856 unsigned controller::analog_actions() const
858 unsigned r = 0, s = 0;
859 for(unsigned i = 0; i < buttons.size(); i++) {
860 if(buttons[i].shadow)
861 continue;
862 switch(buttons[i].type) {
863 case button::TYPE_AXIS:
864 case button::TYPE_RAXIS:
865 case button::TYPE_LIGHTGUN:
866 r++;
867 break;
868 case button::TYPE_TAXIS:
869 s++;
870 break;
871 case button::TYPE_NULL:
872 case button::TYPE_BUTTON:
876 return (r + 1)/ 2 + s;
879 std::pair<unsigned, unsigned> controller::analog_action(unsigned k) const
881 unsigned x1 = std::numeric_limits<unsigned>::max();
882 unsigned x2 = std::numeric_limits<unsigned>::max();
883 unsigned r = 0;
884 bool second = false;
885 bool selecting = false;
886 for(unsigned i = 0; i < buttons.size(); i++) {
887 if(buttons[i].shadow)
888 continue;
889 switch(buttons[i].type) {
890 case button::TYPE_AXIS:
891 case button::TYPE_RAXIS:
892 case button::TYPE_LIGHTGUN:
893 if(selecting) {
894 x2 = i;
895 goto out;
897 if(r == k && !second) {
898 //This and following.
899 x1 = i;
900 selecting = true;
902 if(!second)
903 r++;
904 second = !second;
905 break;
906 case button::TYPE_TAXIS:
907 if(selecting)
908 break;
909 if(r == k) {
910 x1 = i;
911 goto out;
913 r++;
914 break;
915 case button::TYPE_NULL:
916 case button::TYPE_BUTTON:
920 out:
921 return std::make_pair(x1, x2);
924 namespace
926 std::string macro_field_as_string(const JSON::node& parent, const std::string& path)
928 const JSON::node& n = parent.follow(path);
929 if(n.type() != JSON::string)
930 (stringfmt() << "Expected string as field '" << path << "'").throwex();
931 return n.as_string8();
934 bool macro_field_as_boolean(const JSON::node& parent, const std::string& path)
936 const JSON::node& n = parent.follow(path);
937 if(n.type() != JSON::boolean)
938 (stringfmt() << "Expected boolean as field '" << path << "'").throwex();
939 return n.as_bool();
942 const JSON::node& macro_field_as_array(const JSON::node& parent, const std::string& path)
944 const JSON::node& n = parent.follow(path);
945 if(n.type() != JSON::array)
946 (stringfmt() << "Expected array as field '" << path << "'").throwex();
947 return n;
951 macro_data::macro_data(const std::string& spec, const JSON::node& desc, unsigned inum)
953 _descriptor = desc;
954 unsigned btnnum = 0;
955 std::map<std::string, unsigned> symbols;
956 if(desc.type() != JSON::array)
957 (stringfmt() << "Expected controller descriptor " << (inum + 1) << " to be an array");
958 for(auto i = desc.begin(); i != desc.end(); ++i) {
959 if(i->type() == JSON::string) {
960 symbols[i->as_string8()] = btnnum++;
961 btnmap.push_back(i.index());
962 } else if(i->type() == JSON::number) {
963 uint64_t anum = i->as_uint();
964 if(anum > aaxes.size())
965 (stringfmt() << "Descriptor axis number " << anum << " out of range in descriptor "
966 << (inum + 1)).throwex();
967 else if(anum == aaxes.size())
968 aaxes.push_back(std::make_pair(i.index(), std::numeric_limits<unsigned>::max()));
969 else
970 aaxes[anum].second = i.index();
971 } else
972 (stringfmt() << "Controller descriptor " << (inum + 1) << " contains element of unknown"
973 << "kind").throwex();
975 buttons = symbols.size();
976 orig = spec;
977 enabled = true;
978 autoterminate = false;
980 std::deque<size_t> stack;
981 bool in_sparen = false;
982 bool first = true;
983 bool btn_token = false;
984 bool btn_token_next = false;
985 size_t last_bit = 0;
986 size_t last_size = 0;
987 size_t astride = aaxes.size();
988 size_t stride = get_stride();
989 size_t idx = 0;
990 size_t len = spec.length();
991 try {
992 while(idx < len) {
993 btn_token = btn_token_next;
994 btn_token_next = false;
995 unsigned char ch = spec[idx];
996 if(autoterminate)
997 throw std::runtime_error("Asterisk must be the last thing");
998 if(ch == '(') {
999 if(in_sparen)
1000 throw std::runtime_error("Parentheses in square brackets not allowed");
1001 stack.push_back(data.size());
1002 } else if(ch == ')') {
1003 if(in_sparen)
1004 throw std::runtime_error("Parentheses in square brackets not allowed");
1005 if(stack.empty())
1006 throw std::runtime_error("Unmatched right parenthesis");
1007 size_t x = stack.back();
1008 stack.pop_back();
1009 last_size = (data.size() - x) / stride;
1010 } else if(ch == '*') {
1011 autoterminate = true;
1012 } else if(ch == '?') {
1013 if(!btn_token)
1014 throw std::runtime_error("? needs button to apply to");
1015 if(!in_sparen)
1016 throw std::runtime_error("? needs to be in brackets");
1017 data[data.size() - stride + last_bit] |= 2;
1018 } else if(ch == '[') {
1019 if(in_sparen)
1020 throw std::runtime_error("Nested square brackets not allowed");
1021 in_sparen = true;
1022 data.resize(data.size() + stride);
1023 adata.resize(adata.size() + astride);
1024 last_size = 1;
1025 } else if(ch == ']') {
1026 if(!in_sparen)
1027 throw std::runtime_error("Unmatched right square bracket");
1028 in_sparen = false;
1029 } else if(ch == '.') {
1030 if(!in_sparen) {
1031 data.resize(data.size() + stride);
1032 adata.resize(adata.size() + astride);
1033 last_size = 1;
1035 } else if(spec[idx] >= '0' && spec[idx] <= '9') {
1036 size_t rep = 0;
1037 unsigned i = 0;
1038 while(spec[idx + i] >= '0' && spec[idx + i] <= '9') {
1039 rep = 10 * rep + (spec[idx + i] - '0');
1040 i++;
1042 if(in_sparen) {
1043 //This has special meaning: Axis transform.
1044 //Rep is the axis pair to operate on.
1045 if(spec[idx + i] != ':')
1046 throw std::runtime_error("Expected ':' in axis transform");
1047 size_t sep = i;
1048 while(idx + i < len && spec[idx + i] != '@')
1049 i++;
1050 if(idx + i >= len)
1051 throw std::runtime_error("Expected '@' in axis transform");
1052 std::string aexpr = spec.substr(idx + sep + 1, i - sep - 1);
1053 if(rep >= astride)
1054 throw std::runtime_error("Axis transform refers to invalid axis");
1055 adata[adata.size() - astride + rep] = axis_transform(aexpr);
1056 i++;
1057 } else {
1058 if(first)
1059 throw std::runtime_error("Repeat not allowed without frame to "
1060 "repeat");
1061 size_t o = data.size();
1062 size_t ao = adata.size();
1063 data.resize(o + (rep - 1) * last_size * stride);
1064 adata.resize(ao + (rep - 1) * last_size * astride);
1065 for(unsigned i = 1; i < rep; i++) {
1066 memcpy(&data[o + (i - 1) * last_size * stride], &data[o - last_size *
1067 stride], last_size * stride);
1068 memcpy(&data[ao + (i - 1) * last_size * astride], &data[ao -
1069 last_size * astride], last_size * astride);
1071 last_size = last_size * rep;
1073 idx = idx + (i - 1);
1074 } else { //Symbol.
1075 bool found = false;
1076 for(auto k : symbols) {
1077 std::string key = k.first;
1078 size_t j;
1079 for(j = 0; idx + j < len && j < key.length(); j++)
1080 if(spec[idx + j] != key[j])
1081 break;
1082 if(j == key.length()) {
1083 idx += key.length() - 1;
1084 found = true;
1085 if(!in_sparen) {
1086 data.resize(data.size() + stride);
1087 adata.resize(adata.size() + astride);
1089 last_bit = k.second;
1090 data[data.size() - stride + k.second] |= 1;
1091 if(!in_sparen)
1092 last_size = 1;
1095 if(!found)
1096 throw std::runtime_error("Unknown character or button");
1097 btn_token_next = true;
1099 idx++;
1100 first = false;
1102 if(in_sparen)
1103 throw std::runtime_error("Unmatched left square bracket");
1104 if(!stack.empty())
1105 throw std::runtime_error("Unmatched left parenthesis");
1106 } catch(std::exception& e) {
1107 (stringfmt() << "Error parsing macro for controller " << (inum + 1) << ": " << e.what()).throwex();
1111 bool macro_data::syntax_check(const std::string& spec, const JSON::node& desc)
1113 unsigned buttons = 0;
1114 size_t astride = 0;
1115 if(desc.type() != JSON::array)
1116 return false;
1117 for(auto i = desc.begin(); i != desc.end(); ++i) {
1118 if(i->type() == JSON::string)
1119 buttons++;
1120 else if(i->type() == JSON::number) {
1121 uint64_t anum = i->as_uint();
1122 if(anum > astride)
1123 return false;
1124 else if(anum == astride)
1125 astride++;
1126 } else
1127 return false;
1129 bool autoterminate = false;
1130 size_t depth = 0;
1131 bool in_sparen = false;
1132 bool first = true;
1133 bool btn_token = false;
1134 bool btn_token_next = false;
1135 size_t idx = 0;
1136 size_t len = spec.length();
1137 while(idx < len) {
1138 btn_token = btn_token_next;
1139 btn_token_next = false;
1140 unsigned char ch = spec[idx];
1141 if(autoterminate)
1142 return false;
1143 if(ch == '(') {
1144 if(in_sparen)
1145 return false;
1146 depth++;
1147 } else if(ch == ')') {
1148 if(in_sparen)
1149 return false;
1150 if(!depth)
1151 return false;
1152 depth--;
1153 } else if(ch == '*') {
1154 autoterminate = true;
1155 } else if(ch == '?') {
1156 if(!btn_token || !in_sparen)
1157 return false;
1158 } else if(ch == '[') {
1159 if(in_sparen)
1160 return false;
1161 in_sparen = true;
1162 } else if(ch == ']') {
1163 if(!in_sparen)
1164 return false;
1165 in_sparen = false;
1166 } else if(ch == '.') {
1167 } else if(spec[idx] >= '0' && spec[idx] <= '9') {
1168 size_t rep = 0;
1169 unsigned i = 0;
1170 while(spec[idx + i] >= '0' && spec[idx + i] <= '9') {
1171 rep = 10 * rep + (spec[idx + i] - '0');
1172 i++;
1174 if(in_sparen) {
1175 //This has special meaning: Axis transform.
1176 //Rep is the axis pair to operate on.
1177 if(spec[idx + i] != ':')
1178 return false;
1179 size_t sep = i;
1180 while(idx + i < len && spec[idx + i] != '@')
1181 i++;
1182 if(idx + i >= len)
1183 return false;
1184 if(rep >= astride)
1185 return false;
1186 try {
1187 std::string aexpr = spec.substr(idx + sep + 1, i - sep - 1);
1188 axis_transform x(aexpr);
1189 } catch(...) {
1190 return false;
1192 i++;
1193 } else {
1194 if(first)
1195 return false;
1197 idx = idx + (i - 1);
1198 } else { //Symbol.
1199 bool found = false;
1200 for(auto i = desc.begin(); i != desc.end(); ++i) {
1201 if(i->type() != JSON::string)
1202 continue;
1203 std::string key = i->as_string8();
1204 size_t j;
1205 for(j = 0; idx + j < len && j < key.length(); j++)
1206 if(spec[idx + j] != key[j])
1207 break;
1208 if(j == key.length()) {
1209 idx += key.length() - 1;
1210 found = true;
1213 if(!found)
1214 return false;
1215 btn_token_next = true;
1217 idx++;
1218 first = false;
1220 if(in_sparen)
1221 return false;
1222 if(depth)
1223 return false;
1224 return true;
1227 void macro_data::write(frame& frame, unsigned port, unsigned controller_n, int64_t nframe,
1228 apply_mode amode)
1230 if(!enabled)
1231 return;
1232 if(autoterminate && (nframe < 0 || nframe >= (int64_t)get_frames()))
1233 return;
1234 if(nframe < 0)
1235 nframe += ((-nframe / get_frames()) + 3) * get_frames();
1236 nframe %= get_frames();
1237 for(size_t i = 0; i < buttons; i++) {
1238 unsigned lb = btnmap[i];
1239 unsigned st = data[nframe * get_stride() + i];
1240 if(st == 3)
1241 st = macro_random_bit();
1242 if(st == 1)
1243 switch(amode) {
1244 case AM_OVERWRITE:
1245 case AM_OR:
1246 frame.axis3(port, controller_n, lb, 1);
1247 break;
1248 case AM_XOR:
1249 frame.axis3(port, controller_n, lb, frame.axis3(port, controller_n, lb) ^ 1);
1250 break;
1252 else
1253 switch(amode) {
1254 case AM_OVERWRITE:
1255 frame.axis3(port, controller_n, lb, 0);
1256 break;
1257 case AM_OR:
1258 case AM_XOR:
1262 const controller* _ctrl = frame.porttypes().port_type(port).controller_info->get(controller_n);
1263 if(!_ctrl)
1264 return;
1265 size_t abuttons = aaxes.size();
1266 for(size_t i = 0; i < abuttons; i++) {
1267 unsigned ax = aaxes[i].first;
1268 unsigned ay = aaxes[i].second;
1269 if(ay != std::numeric_limits<unsigned>::max()) {
1270 if(ax > _ctrl->buttons.size()) continue;
1271 if(ay > _ctrl->buttons.size()) continue;
1272 auto g = adata[nframe * abuttons + i].transform(_ctrl->buttons[ax], _ctrl->buttons[ay],
1273 frame.axis3(port, controller_n, ax), frame.axis3(port, controller_n, ay));
1274 frame.axis3(port, controller_n, ax, g.first);
1275 frame.axis3(port, controller_n, ay, g.second);
1276 } else {
1277 if(ax > _ctrl->buttons.size()) continue;
1278 int16_t g = adata[nframe * abuttons + i].transform(_ctrl->buttons[ax],
1279 frame.axis3(port, controller_n, ax));
1280 frame.axis3(port, controller_n, ax, g);
1285 std::string macro_data::dump(const controller& ctrl)
1287 std::ostringstream o;
1288 for(size_t i = 0; i < get_frames(); i++) {
1289 o << "[";
1290 for(size_t j = 0; j < aaxes.size(); j++) {
1291 macro_data::axis_transform& t = adata[i * aaxes.size() + j];
1292 o << j << ":";
1293 o << t.coeffs[0] << "," << t.coeffs[1] << "," << t.coeffs[2] << ",";
1294 o << t.coeffs[3] << "," << t.coeffs[4] << "," << t.coeffs[5] << "@";
1296 for(size_t j = 0; j < buttons && j < ctrl.buttons.size(); j++) {
1297 unsigned st = data[i * get_stride() + j];
1298 if(ctrl.buttons[j].macro == "")
1299 continue;
1300 if(st == 1)
1301 o << ctrl.buttons[j].macro;
1302 if(st == 3)
1303 o << ctrl.buttons[j].macro << "?";
1305 o << "]";
1307 if(autoterminate)
1308 o << "*";
1309 return o.str();
1312 void macro::write(frame& frame, int64_t nframe)
1314 for(auto& i : macros) {
1315 unsigned port;
1316 unsigned controller;
1317 try {
1318 auto g = frame.porttypes().lcid_to_pcid(i.first);
1319 port = g.first;
1320 controller = g.second;
1321 } catch(...) {
1322 continue;
1324 i.second.write(frame, port, controller, nframe, amode);
1328 int16_t macro_data::axis_transform::transform(const button& b, int16_t v)
1330 return scale_axis(b, coeffs[0] * unscale_axis(b, v) + coeffs[4]);
1333 std::pair<int16_t, int16_t> macro_data::axis_transform::transform(const button& b1,
1334 const button& b2, int16_t v1, int16_t v2)
1336 double x, y, u, v, au, av, s;
1337 x = unscale_axis(b1, v1);
1338 y = unscale_axis(b2, v2);
1339 u = coeffs[0] * x + coeffs[1] * y + coeffs[4];
1340 v = coeffs[2] * x + coeffs[3] * y + coeffs[5];
1341 au = abs(u);
1342 av = abs(v);
1343 s = max(max(au, 1.0), max(av, 1.0));
1344 //If u and v exceed nominal range of [-1,1], those need to be projected to the edge.
1345 if(s > 1) {
1346 u /= s;
1347 v /= s;
1349 auto g = std::make_pair(scale_axis(b1, u), scale_axis(b2, v));
1350 return g;
1353 double macro_data::axis_transform::unscale_axis(const button& b, int16_t v)
1355 if(b.centers) {
1356 int32_t center = ((int32_t)b.rmin + (int32_t)b.rmax) / 2;
1357 if(v <= b.rmin)
1358 return -1;
1359 if(v < center)
1360 return -(center - (double)v) / (center - b.rmin);
1361 if(v == center)
1362 return 0;
1363 if(v < b.rmax)
1364 return ((double)v - center) / (b.rmax - center);
1365 return 1;
1366 } else {
1367 if(v <= b.rmin)
1368 return 0;
1369 if(v >= b.rmax)
1370 return 1;
1371 return ((double)v - b.rmin) / (b.rmax - b.rmin);
1375 int16_t macro_data::axis_transform::scale_axis(const button& b, double v)
1377 if(b.centers) {
1378 int32_t center = ((int32_t)b.rmin + (int32_t)b.rmax) / 2;
1379 if(v == 0)
1380 return center;
1381 if(v < 0) {
1382 double v2 = v * (center - b.rmin) + center;
1383 if(v2 < b.rmin)
1384 return b.rmin;
1385 return v2;
1387 double v2 = v * (b.rmax - center) + center;
1388 if(v2 > b.rmax)
1389 return b.rmax;
1390 return v2;
1391 } else {
1392 double v2 = v * (b.rmax - b.rmin) + b.rmin;
1393 if(v2 < b.rmin)
1394 return b.rmin;
1395 if(v2 > b.rmax)
1396 return b.rmax;
1397 return v2;
1401 namespace
1403 std::complex<double> parse_complex(const std::string& expr)
1405 regex_results r;
1406 if(r = regex("\\((.*),(.*)\\)", expr)) {
1407 //Real,Imaginary.
1408 return std::complex<double>(parse_value<double>(r[1]), parse_value<double>(r[2]));
1409 } else if(r = regex("\\((.*)<(.*)\\)", expr)) {
1410 return std::polar(parse_value<double>(r[1]), parse_value<double>(r[2]) * M_PI / 180);
1411 } else {
1412 return std::complex<double>(parse_value<double>(expr), 0.0);
1417 macro_data::axis_transform::axis_transform(const std::string& expr)
1419 regex_results r;
1420 if(r = regex("\\*(.*)\\+(.*)", expr)) {
1421 //Affine transform.
1422 std::complex<double> a = parse_complex(r[1]);
1423 std::complex<double> b = parse_complex(r[2]);
1424 coeffs[0] = a.real();
1425 coeffs[1] = -a.imag();
1426 coeffs[2] = a.imag();
1427 coeffs[3] = a.real();
1428 coeffs[4] = b.real();
1429 coeffs[5] = b.imag();
1430 } else if(r = regex("\\*(.*)", expr)) {
1431 //Linear transform.
1432 std::complex<double> a = parse_complex(r[1]);
1433 coeffs[0] = a.real();
1434 coeffs[1] = -a.imag();
1435 coeffs[2] = a.imag();
1436 coeffs[3] = a.real();
1437 coeffs[4] = 0;
1438 coeffs[5] = 0;
1439 } else if(r = regex("\\+(.*)", expr)) {
1440 //Relative
1441 std::complex<double> b = parse_complex(r[1]);
1442 coeffs[0] = 1;
1443 coeffs[1] = 0;
1444 coeffs[2] = 0;
1445 coeffs[3] = 1;
1446 coeffs[4] = b.real();
1447 coeffs[5] = b.imag();
1448 } else if(r = regex("(.*),(.*),(.*),(.*),(.*),(.*)", expr)) {
1449 //Full affine.
1450 coeffs[0] = parse_value<double>(r[1]);
1451 coeffs[1] = parse_value<double>(r[2]);
1452 coeffs[2] = parse_value<double>(r[3]);
1453 coeffs[3] = parse_value<double>(r[4]);
1454 coeffs[4] = parse_value<double>(r[5]);
1455 coeffs[5] = parse_value<double>(r[6]);
1456 } else {
1457 //Absolute.
1458 std::complex<double> b = parse_complex(expr);
1459 coeffs[0] = 0;
1460 coeffs[1] = 0;
1461 coeffs[2] = 0;
1462 coeffs[3] = 0;
1463 coeffs[4] = b.real();
1464 coeffs[5] = b.imag();
1468 JSON::node macro::serialize()
1470 JSON::node v(JSON::object);
1471 switch(amode) {
1472 case macro_data::AM_OVERWRITE: v.insert("mode", JSON::s("overwrite")); break;
1473 case macro_data::AM_OR: v.insert("mode", JSON::s("or")); break;
1474 case macro_data::AM_XOR: v.insert("mode", JSON::s("xor")); break;
1476 JSON::node& c = v.insert("data", JSON::array());
1477 for(auto& i : macros) {
1478 while(i.first > c.index_count())
1479 c.append(JSON::n());
1480 i.second.serialize(c.append(JSON::n()));
1482 return v;
1485 void macro_data::serialize(JSON::node& v)
1487 v = JSON::object();
1488 v.insert("enable", JSON::b(enabled));
1489 v.insert("expr", JSON::s(orig));
1490 v.insert("desc", _descriptor);
1493 JSON::node macro_data::make_descriptor(const controller& ctrl)
1495 JSON::node n(JSON::array);
1496 for(size_t i = 0; i < ctrl.buttons.size(); i++) {
1497 if(ctrl.buttons[i].macro != "")
1498 n.append(JSON::s(ctrl.buttons[i].macro));
1499 else
1500 n.append(JSON::n()); //Placeholder.
1502 for(size_t i = 0; i < ctrl.analog_actions(); i++) {
1503 auto g = ctrl.analog_action(i);
1504 n.index(g.first) = JSON::u(i);
1505 if(g.second != std::numeric_limits<unsigned>::max())
1506 n.index(g.second) = JSON::u(i);
1508 return n;
1511 macro::macro(const JSON::node& v)
1513 if(v.type() != JSON::object)
1514 throw std::runtime_error("Expected macro to be JSON object");
1515 std::string mode = macro_field_as_string(v, "mode");
1516 if(mode == "overwrite") amode = macro_data::AM_OVERWRITE;
1517 else if(mode == "or") amode = macro_data::AM_OR;
1518 else if(mode == "xor") amode = macro_data::AM_XOR;
1519 else (stringfmt() << "Unknown button mode '" << mode << "'").throwex();
1520 const JSON::node& c = macro_field_as_array(v, "data");
1521 for(auto i = c.begin(); i != c.end(); ++i) {
1522 if(i->type() == JSON::object)
1523 macros[i.index()] = macro_data(*i, i.index());
1524 else
1525 (stringfmt() << "Expected object as field 'data/" << i.index() << "'").throwex();
1529 macro_data::macro_data(const JSON::node& v, unsigned i)
1530 : macro_data(macro_field_as_string(v, "expr"), macro_field_as_array(v, "desc"), i)
1532 enabled = macro_field_as_boolean(v, "enable");