lsnes rr2-β24
[lsnes.git] / src / library / portctrl-data.cpp
blob479138a7f04135e06a816cc0dded7b84aebd8d9b
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) throw(std::bad_alloc)
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)
141 throw(std::bad_alloc, std::runtime_error)
143 for(auto i : bindings())
144 if(i.matches(types))
145 return *(i.stype);
146 //Not found, create new.
147 type_set& ret = *new type_set(types, control_map);
148 binding b;
149 b.types = types;
150 b.stype = &ret;
151 bindings().push_back(b);
152 return ret;
155 type_set::type_set(std::vector<class type*> types, struct index_map control_map)
157 port_count = types.size();
158 //Verify legality of port types.
159 for(size_t i = 0; i < port_count; i++)
160 if(!types[i] || !types[i]->legal(i))
161 throw std::runtime_error("Illegal port types");
162 //Count maximum number of controller indices to determine the controller multiplier.
163 controller_multiplier = 1;
164 for(size_t i = 0; i < port_count; i++)
165 for(unsigned j = 0; j < types[i]->controller_info->controllers.size(); j++)
166 controller_multiplier = max(controller_multiplier, (size_t)types[i]->used_indices(j));
167 //Count maximum number of controllers to determine the port multiplier.
168 port_multiplier = 1;
169 for(size_t i = 0; i < port_count; i++)
170 port_multiplier = max(port_multiplier, controller_multiplier *
171 (size_t)types[i]->controller_info->controllers.size());
172 //Allocate the per-port tables.
173 port_offsets = new size_t[types.size()];
174 port_types = new class type*[types.size()];
175 //Determine the total size and offsets.
176 size_t offset = 0;
177 for(size_t i = 0; i < port_count; i++) {
178 port_offsets[i] = offset;
179 offset += types[i]->storage_size;
180 port_types[i] = types[i];
182 total_size = offset;
183 //Determine the index size and allocate it.
184 indices_size = port_multiplier * port_count;
185 indices_tab = new unsigned[indices_size];
186 for(size_t i = 0; i < indices_size; i++)
187 indices_tab[i] = 0xFFFFFFFFUL;
188 //Copy the index data (and reverse it).
189 controllers = control_map.logical_map;
190 legacy_pcids = control_map.pcid_map;
191 _indices = control_map.indices;
192 for(size_t j = 0; j < _indices.size(); j++) {
193 auto& i = _indices[j];
194 if(i.valid)
195 indices_tab[i.port * port_multiplier + i.controller * controller_multiplier + i.control] = j;
199 short read_axis_value(const char* buf, size_t& idx) throw()
201 char ch;
202 //Skip ws.
203 while(is_nonterminator(buf[idx])) {
204 char ch = buf[idx];
205 if(ch != ' ' && ch != '\t')
206 break;
207 idx++;
209 //Read the sign if any.
210 ch = buf[idx];
211 if(!is_nonterminator(ch))
212 return 0;
213 bool negative = false;
214 if(ch == '-') {
215 negative = true;
216 idx++;
218 if(ch == '+')
219 idx++;
221 //Read numeric value.
222 int numval = 0;
223 while(is_nonterminator(buf[idx]) && isdigit(static_cast<unsigned char>(ch = buf[idx]))) {
224 numval = numval * 10 + (ch - '0');
225 idx++;
227 if(negative)
228 numval = -numval;
230 return static_cast<short>(numval);
233 size_t write_axis_value(char* buf, short _v)
235 int v = _v;
236 size_t r = 0;
237 buf[r++] = ' ';
238 if(v < 0) { buf[r++] = '-'; v = -v; }
239 if(v >= 10000) buf[r++] = '0' + (v / 10000 % 10);
240 if(v >= 1000) buf[r++] = '0' + (v / 1000 % 10);
241 if(v >= 100) buf[r++] = '0' + (v / 100 % 10);
242 if(v >= 10) buf[r++] = '0' + (v / 10 % 10);
243 buf[r++] = '0' + (v % 10);
244 return r;
247 namespace
249 type_set& dummytypes()
251 static type_set x;
252 return x;
255 size_t writeu32val(char32_t* buf, int val)
257 char c[12];
258 size_t i;
259 sprintf(c, "%d", val);
260 for(i = 0; c[i]; i++)
261 buf[i] = c[i];
262 return i;
265 uint64_t find_next_sync(frame_vector& movie, uint64_t after)
267 if(after >= movie.size())
268 return after;
269 do {
270 after++;
271 } while(after < movie.size() && !movie[after].sync());
272 return after;
276 void frame::display(unsigned port, unsigned controller_n, char32_t* buf) throw()
278 if(port >= types->ports()) {
279 //Bad port.
280 *buf = '\0';
281 return;
283 uint8_t* backingmem = backing + types->port_offset(port);
284 const type& ptype = types->port_type(port);
285 if(controller_n >= ptype.controller_info->controllers.size()) {
286 //Bad controller.
287 *buf = '\0';
288 return;
290 const controller& pc = ptype.controller_info->controllers[controller_n];
291 bool need_space = false;
292 short val;
293 for(unsigned i = 0; i < pc.buttons.size(); i++) {
294 const button& pcb = pc.buttons[i];
295 if(need_space && pcb.type != button::TYPE_NULL) {
296 need_space = false;
297 *(buf++) = ' ';
299 switch(pcb.type) {
300 case button::TYPE_NULL:
301 break;
302 case button::TYPE_BUTTON:
303 *(buf++) = ptype.read(&ptype, backingmem, controller_n, i) ? pcb.symbol : U'-';
304 break;
305 case button::TYPE_AXIS:
306 case button::TYPE_RAXIS:
307 case button::TYPE_TAXIS:
308 case button::TYPE_LIGHTGUN:
309 val = ptype.read(&ptype, backingmem, controller_n, i);
310 buf += writeu32val(buf, val);
311 need_space = true;
312 break;
315 *buf = '\0';
318 counters::counters() throw(std::bad_alloc)
320 types = &dummytypes();
321 ctrs = new uint32_t[types->indices()];
322 clear();
325 counters::counters(const type_set& p) throw(std::bad_alloc)
327 types = &p;
328 ctrs = new uint32_t[types->indices()];
329 clear();
332 counters::counters(const counters& p) throw(std::bad_alloc)
334 ctrs = new uint32_t[p.types->indices()];
335 types = p.types;
336 memcpy(ctrs, p.ctrs, sizeof(uint32_t) * p.types->indices());
337 framepflag = p.framepflag;
340 counters& counters::operator=(const counters& p) throw(std::bad_alloc)
342 if(this == &p)
343 return *this;
344 uint32_t* n = new uint32_t[p.types->indices()];
345 types = p.types;
346 memcpy(n, p.ctrs, sizeof(uint32_t) * p.types->indices());
347 delete[] ctrs;
348 ctrs = n;
349 framepflag = p.framepflag;
350 return *this;
353 counters::~counters() throw()
355 delete[] ctrs;
358 void counters::clear() throw()
360 memset(ctrs, 0, sizeof(uint32_t) * types->indices());
361 framepflag = false;
364 void counters::set_all_DRDY() throw()
366 for(size_t i = 0; i < types->indices(); i++)
367 ctrs[i] |= 0x80000000UL;
370 void counters::clear_DRDY(unsigned idx) throw()
372 ctrs[idx] &= 0x7FFFFFFFUL;
375 bool counters::get_DRDY(unsigned idx) throw()
377 return ((ctrs[idx] & 0x80000000UL) != 0);
380 bool counters::has_polled() throw()
382 uint32_t res = 0;
383 for(size_t i = 0; i < types->indices() ; i++)
384 res |= ctrs[i];
385 return ((res & 0x7FFFFFFFUL) != 0);
388 uint32_t counters::get_polls(unsigned idx) throw()
390 return ctrs[idx] & 0x7FFFFFFFUL;
393 uint32_t counters::increment_polls(unsigned idx) throw()
395 uint32_t x = ctrs[idx] & 0x7FFFFFFFUL;
396 ++ctrs[idx];
397 return x;
400 uint32_t counters::max_polls() throw()
402 uint32_t max = 0;
403 for(unsigned i = 0; i < types->indices(); i++) {
404 uint32_t tmp = ctrs[i] & 0x7FFFFFFFUL;
405 max = (max < tmp) ? tmp : max;
407 return max;
410 void counters::save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc)
412 mem.resize(types->indices());
413 //Compatiblity fun.
414 for(size_t i = 0; i < types->indices(); i++)
415 mem[i] = ctrs[i];
418 void counters::load_state(const std::vector<uint32_t>& mem) throw()
420 for(size_t i = 0; i < types->indices(); i++)
421 ctrs[i] = mem[i];
424 bool counters::check(const std::vector<uint32_t>& mem) throw()
426 return (mem.size() == types->indices());
430 void counters::set_framepflag(bool value) throw()
432 framepflag = value;
435 bool counters::get_framepflag() const throw()
437 return framepflag;
440 frame::frame(const type_set& p) throw(std::runtime_error)
442 memset(memory, 0, sizeof(memory));
443 backing = memory;
444 types = &p;
445 host = NULL;
448 frame::frame(unsigned char* mem, const type_set& p, frame_vector* _host)
449 throw(std::runtime_error)
451 if(!mem)
452 throw std::runtime_error("NULL backing memory not allowed");
453 memset(memory, 0, sizeof(memory));
454 backing = mem;
455 types = &p;
456 host = _host;
459 frame::frame(const frame& obj) throw()
461 memset(memory, 0, sizeof(memory));
462 backing = memory;
463 types = obj.types;
464 memcpy(backing, obj.backing, types->size());
465 host = NULL;
468 frame& frame::operator=(const frame& obj) throw(std::runtime_error)
470 if(backing != memory && types != obj.types)
471 throw std::runtime_error("Port types do not match");
472 types = obj.types;
473 short old = sync();
474 memcpy(backing, obj.backing, types->size());
475 if(host) host->notify_sync_change(sync() - old);
476 return *this;
479 frame_vector::fchange_listener::~fchange_listener()
483 size_t frame_vector::walk_helper(size_t frame, bool sflag) throw()
485 size_t ret = sflag ? frame : 0;
486 if(frame >= frames)
487 return ret;
488 frame++;
489 ret++;
490 size_t page = frame / frames_per_page;
491 size_t offset = frame_size * (frame % frames_per_page);
492 size_t index = frame % frames_per_page;
493 if(cache_page_num != page) {
494 cache_page = &pages[page];
495 cache_page_num = page;
497 while(frame < frames) {
498 if(index == frames_per_page) {
499 page++;
500 cache_page = &pages[page];
501 cache_page_num = page;
502 index = 0;
503 offset = 0;
505 if(frame::sync(cache_page->content + offset))
506 break;
507 index++;
508 offset += frame_size;
509 frame++;
510 ret++;
512 return ret;
515 size_t frame_vector::recount_frames() throw()
517 uint64_t old_frame_count = real_frame_count;
518 size_t ret = 0;
519 if(!frames)
520 return 0;
521 cache_page_num = 0;
522 cache_page = &pages[0];
523 size_t offset = 0;
524 size_t index = 0;
525 for(size_t i = 0; i < frames; i++) {
526 if(index == frames_per_page) {
527 cache_page_num++;
528 cache_page = &pages[cache_page_num];
529 index = 0;
530 offset = 0;
532 if(frame::sync(cache_page->content + offset))
533 ret++;
534 index++;
535 offset += frame_size;
538 real_frame_count = ret;
539 call_framecount_notification(old_frame_count);
540 return ret;
543 void frame_vector::clear(const type_set& p) throw(std::runtime_error)
545 uint64_t old_frame_count = real_frame_count;
546 frame_size = p.size();
547 frames_per_page = CONTROLLER_PAGE_SIZE / frame_size;
548 frames = 0;
549 types = &p;
550 clear_cache();
551 pages.clear();
552 real_frame_count = 0;
553 call_framecount_notification(old_frame_count);
556 frame_vector::~frame_vector() throw()
558 pages.clear();
559 cache_page = NULL;
562 frame_vector::frame_vector() throw()
563 : tracker(memtracker::singleton(), movie_page_id, sizeof(*this))
565 real_frame_count = 0;
566 freeze_count = 0;
567 clear(dummytypes());
570 frame_vector::frame_vector(const type_set& p) throw()
571 : tracker(memtracker::singleton(), movie_page_id, sizeof(*this))
573 real_frame_count = 0;
574 freeze_count = 0;
575 clear(p);
578 void frame_vector::append(frame cframe) throw(std::bad_alloc, std::runtime_error)
580 frame check(*types);
581 if(!check.types_match(cframe))
582 throw std::runtime_error("frame_vector::append: Type mismatch");
583 if(frames % frames_per_page == 0) {
584 //Create new page.
585 pages[frames / frames_per_page];
587 //Write the entry.
588 size_t page = frames / frames_per_page;
589 size_t offset = frame_size * (frames % frames_per_page);
590 if(cache_page_num != page) {
591 cache_page_num = page;
592 cache_page = &pages[page];
594 frame(cache_page->content + offset, *types) = cframe;
595 if(cframe.sync()) real_frame_count++;
596 frames++;
599 frame_vector::frame_vector(const frame_vector& vector) throw(std::bad_alloc)
600 : tracker(memtracker::singleton(), movie_page_id, sizeof(*this))
602 real_frame_count = 0;
603 freeze_count = 0;
604 clear(*vector.types);
605 *this = vector;
608 frame_vector& frame_vector::operator=(const frame_vector& v)
609 throw(std::bad_alloc)
611 if(this == &v)
612 return *this;
613 uint64_t old_frame_count = real_frame_count;
614 resize(v.frames);
615 clear_cache();
617 //Copy the fields.
618 frame_size = v.frame_size;
619 frames_per_page = v.frames_per_page;
620 types = v.types;
621 real_frame_count = v.real_frame_count;
623 //This can't fail anymore. Copy the raw page contents.
624 size_t pagecount = (frames + frames_per_page - 1) / frames_per_page;
625 for(size_t i = 0; i < pagecount; i++) {
626 page& pg = pages[i];
627 const page& pg2 = v.pages.find(i)->second;
628 pg = pg2;
630 call_framecount_notification(old_frame_count);
631 return *this;
634 void frame_vector::resize(size_t newsize) throw(std::bad_alloc)
636 clear_cache();
637 if(newsize == 0) {
638 clear();
639 } else if(newsize < frames) {
640 //Shrink movie.
641 uint64_t old_frame_count = real_frame_count;
642 for(size_t i = newsize; i < frames; i++)
643 if((*this)[i].sync()) real_frame_count--;
644 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
645 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
646 for(size_t i = pages_needed; i < current_pages; i++)
647 pages.erase(i);
648 //Now zeroize the excess memory.
649 if(newsize < pages_needed * frames_per_page) {
650 size_t offset = frame_size * (newsize % frames_per_page);
651 memset(pages[pages_needed - 1].content + offset, 0, CONTROLLER_PAGE_SIZE - offset);
653 frames = newsize;
654 call_framecount_notification(old_frame_count);
655 } else if(newsize > frames) {
656 //Enlarge movie.
657 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
658 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
659 //Create the needed pages.
660 for(size_t i = current_pages; i < pages_needed; i++) {
661 try {
662 pages[i];
663 } catch(...) {
664 for(size_t i = current_pages; i < pages_needed; i++)
665 if(pages.count(i))
666 pages.erase(i);
667 throw;
670 frames = newsize;
671 //This can use real_frame_count, because the real frame count won't change.
672 call_framecount_notification(real_frame_count);
676 bool frame_vector::compatible(frame_vector& with, uint64_t nframe, const uint32_t* polls)
678 //Types have to match.
679 if(get_types() != with.get_types())
680 return false;
681 const type_set& pset = with.get_types();
682 //If new movie is before first frame, anything with same project_id is compatible.
683 if(nframe == 0)
684 return true;
685 //Scan both movies until frame syncs are seen. Out of bounds reads behave as all neutral but frame
686 //sync done.
687 uint64_t syncs_seen = 0;
688 uint64_t frames_read = 0;
689 size_t old_size = size();
690 size_t new_size = with.size();
691 size_t pagenum = 0;
692 size_t ocomplete_pages = old_size / frames_per_page; //Round DOWN
693 size_t ncomplete_pages = new_size / frames_per_page; //Round DOWN
694 size_t complete_pages = min(ocomplete_pages, ncomplete_pages);
695 while(syncs_seen + frames_per_page < nframe - 1 && pagenum < complete_pages) {
696 //Fast process page. The above condition guarantees that these pages are completely used.
697 auto opagedata = pages[pagenum].content;
698 auto npagedata = with.pages[pagenum].content;
699 size_t pagedataamt = frames_per_page * frame_size;
700 if(memcmp(opagedata, npagedata, pagedataamt))
701 return false;
702 frames_read += frames_per_page;
703 pagenum++;
704 for(size_t i = 0; i < pagedataamt; i += frame_size)
705 if(opagedata[i] & 1) syncs_seen++;
707 while(syncs_seen < nframe - 1) {
708 frame oldc = blank_frame(true), newc = with.blank_frame(true);
709 if(frames_read < old_size)
710 oldc = (*this)[frames_read];
711 if(frames_read < new_size)
712 newc = with[frames_read];
713 if(oldc != newc)
714 return false; //Mismatch.
715 frames_read++;
716 if(newc.sync())
717 syncs_seen++;
719 //We increment the counter one time too many.
720 frames_read--;
721 //Current frame. We need to compare each control up to poll counter.
722 uint64_t readable_old_subframes = 0, readable_new_subframes = 0;
723 uint64_t oldlen = find_next_sync(*this, frames_read);
724 uint64_t newlen = find_next_sync(with, frames_read);
725 if(frames_read < oldlen)
726 readable_old_subframes = oldlen - frames_read;
727 if(frames_read < newlen)
728 readable_new_subframes = newlen - frames_read;
729 //Then rest of the stuff.
730 for(unsigned i = 0; i < pset.indices(); i++) {
731 uint32_t p = polls[i] & 0x7FFFFFFFUL;
732 short ov = 0, nv = 0;
733 for(uint32_t j = 0; j < p; j++) {
734 if(j < readable_old_subframes)
735 ov = (*this)[j + frames_read].axis2(i);
736 if(j < readable_new_subframes)
737 nv = with[j + frames_read].axis2(i);
738 if(ov != nv)
739 return false;
742 return true;
745 uint64_t frame_vector::binary_size() const throw()
747 return size() * get_stride();
750 void frame_vector::save_binary(binarystream::output& stream) const throw(std::runtime_error)
752 uint64_t stride = get_stride();
753 uint64_t pageframes = get_frames_per_page();
754 uint64_t vsize = size();
755 size_t pagenum = 0;
756 while(vsize > 0) {
757 uint64_t count = (vsize > pageframes) ? pageframes : vsize;
758 size_t bytes = count * stride;
759 const unsigned char* content = get_page_buffer(pagenum++);
760 stream.raw(content, bytes);
761 vsize -= count;
765 void frame_vector::load_binary(binarystream::input& stream) throw(std::bad_alloc, std::runtime_error)
767 uint64_t stride = get_stride();
768 uint64_t pageframes = get_frames_per_page();
769 uint64_t vsize = 0;
770 size_t pagenum = 0;
771 uint64_t pagesize = stride * pageframes;
772 while(stream.get_left()) {
773 resize(vsize + pageframes);
774 unsigned char* contents = get_page_buffer(pagenum++);
775 uint64_t gcount = min(pagesize, stream.get_left());
776 stream.raw(contents, gcount);
777 vsize += (gcount / stride);
779 resize(vsize);
780 recount_frames();
783 void frame_vector::swap_data(frame_vector& v) throw()
785 uint64_t toldsize = real_frame_count;
786 uint64_t voldsize = v.real_frame_count;
787 std::swap(pages, v.pages);
788 std::swap(frames_per_page, v.frames_per_page);
789 std::swap(frame_size, v.frame_size);
790 std::swap(frames, v.frames);
791 std::swap(types, v.types);
792 std::swap(cache_page_num, v.cache_page_num);
793 std::swap(cache_page, v.cache_page);
794 std::swap(real_frame_count, v.real_frame_count);
795 if(!freeze_count)
796 call_framecount_notification(toldsize);
797 if(!v.freeze_count)
798 v.call_framecount_notification(voldsize);
801 int64_t frame_vector::find_frame(uint64_t n)
803 if(!n) return -1;
804 uint64_t stride = get_stride();
805 uint64_t pageframes = get_frames_per_page();
806 uint64_t vsize = size();
807 size_t pagenum = 0;
808 while(vsize > 0) {
809 uint64_t count = (vsize > pageframes) ? pageframes : vsize;
810 const unsigned char* content = get_page_buffer(pagenum++);
811 size_t offset = 0;
812 for(unsigned i = 0; i < count; i++) {
813 if(frame::sync(content + offset)) n--;
814 if(n == 0) return (pagenum - 1) * pageframes + i;
815 offset += stride;
817 vsize -= count;
819 return -1;
822 int64_t frame_vector::subframe_to_frame(uint64_t n)
824 int64_t ret = 1;
825 uint64_t stride = get_stride();
826 uint64_t pageframes = get_frames_per_page();
827 uint64_t vsize = size();
828 if(n >= vsize) return -1;
829 size_t pagenum = 0;
830 size_t cpage = n / pageframes;
831 for(uint64_t p = 0; p < cpage; p++) {
832 const unsigned char* content = get_page_buffer(pagenum++);
833 size_t offset = 0;
834 for(unsigned i = 0; i < pageframes; i++) {
835 if(frame::sync(content + offset)) ret++;
836 offset += stride;
840 const unsigned char* content = get_page_buffer(pagenum++);
841 size_t offset = 0;
842 unsigned idx = n % pageframes;
843 for(unsigned i = 0; i < idx; i++) {
844 if(frame::sync(content + offset)) ret++;
845 offset += stride;
848 return ret;
851 frame::frame() throw()
853 memset(memory, 0, sizeof(memory));
854 backing = memory;
855 types = &dummytypes();
856 host = NULL;
859 unsigned controller::analog_actions() const
861 unsigned r = 0, s = 0;
862 for(unsigned i = 0; i < buttons.size(); i++) {
863 if(buttons[i].shadow)
864 continue;
865 switch(buttons[i].type) {
866 case button::TYPE_AXIS:
867 case button::TYPE_RAXIS:
868 case button::TYPE_LIGHTGUN:
869 r++;
870 break;
871 case button::TYPE_TAXIS:
872 s++;
873 break;
874 case button::TYPE_NULL:
875 case button::TYPE_BUTTON:
879 return (r + 1)/ 2 + s;
882 std::pair<unsigned, unsigned> controller::analog_action(unsigned k) const
884 unsigned x1 = std::numeric_limits<unsigned>::max();
885 unsigned x2 = std::numeric_limits<unsigned>::max();
886 unsigned r = 0;
887 bool second = false;
888 bool selecting = false;
889 for(unsigned i = 0; i < buttons.size(); i++) {
890 if(buttons[i].shadow)
891 continue;
892 switch(buttons[i].type) {
893 case button::TYPE_AXIS:
894 case button::TYPE_RAXIS:
895 case button::TYPE_LIGHTGUN:
896 if(selecting) {
897 x2 = i;
898 goto out;
900 if(r == k && !second) {
901 //This and following.
902 x1 = i;
903 selecting = true;
905 if(!second)
906 r++;
907 second = !second;
908 break;
909 case button::TYPE_TAXIS:
910 if(selecting)
911 break;
912 if(r == k) {
913 x1 = i;
914 goto out;
916 r++;
917 break;
918 case button::TYPE_NULL:
919 case button::TYPE_BUTTON:
923 out:
924 return std::make_pair(x1, x2);
927 namespace
929 std::string macro_field_as_string(const JSON::node& parent, const std::string& path)
931 const JSON::node& n = parent.follow(path);
932 if(n.type() != JSON::string)
933 (stringfmt() << "Expected string as field '" << path << "'").throwex();
934 return n.as_string8();
937 bool macro_field_as_boolean(const JSON::node& parent, const std::string& path)
939 const JSON::node& n = parent.follow(path);
940 if(n.type() != JSON::boolean)
941 (stringfmt() << "Expected boolean as field '" << path << "'").throwex();
942 return n.as_bool();
945 const JSON::node& macro_field_as_array(const JSON::node& parent, const std::string& path)
947 const JSON::node& n = parent.follow(path);
948 if(n.type() != JSON::array)
949 (stringfmt() << "Expected array as field '" << path << "'").throwex();
950 return n;
954 macro_data::macro_data(const std::string& spec, const JSON::node& desc, unsigned inum)
956 _descriptor = desc;
957 unsigned btnnum = 0;
958 std::map<std::string, unsigned> symbols;
959 if(desc.type() != JSON::array)
960 (stringfmt() << "Expected controller descriptor " << (inum + 1) << " to be an array");
961 for(auto i = desc.begin(); i != desc.end(); ++i) {
962 if(i->type() == JSON::string) {
963 symbols[i->as_string8()] = btnnum++;
964 btnmap.push_back(i.index());
965 } else if(i->type() == JSON::number) {
966 uint64_t anum = i->as_uint();
967 if(anum > aaxes.size())
968 (stringfmt() << "Descriptor axis number " << anum << " out of range in descriptor "
969 << (inum + 1)).throwex();
970 else if(anum == aaxes.size())
971 aaxes.push_back(std::make_pair(i.index(), std::numeric_limits<unsigned>::max()));
972 else
973 aaxes[anum].second = i.index();
974 } else
975 (stringfmt() << "Controller descriptor " << (inum + 1) << " contains element of unknown"
976 << "kind").throwex();
978 buttons = symbols.size();
979 orig = spec;
980 enabled = true;
981 autoterminate = false;
983 std::deque<size_t> stack;
984 bool in_sparen = false;
985 bool first = true;
986 bool btn_token = false;
987 bool btn_token_next = false;
988 size_t last_bit = 0;
989 size_t last_size = 0;
990 size_t astride = aaxes.size();
991 size_t stride = get_stride();
992 size_t idx = 0;
993 size_t len = spec.length();
994 try {
995 while(idx < len) {
996 btn_token = btn_token_next;
997 btn_token_next = false;
998 unsigned char ch = spec[idx];
999 if(autoterminate)
1000 throw std::runtime_error("Asterisk must be the last thing");
1001 if(ch == '(') {
1002 if(in_sparen)
1003 throw std::runtime_error("Parentheses in square brackets not allowed");
1004 stack.push_back(data.size());
1005 } else if(ch == ')') {
1006 if(in_sparen)
1007 throw std::runtime_error("Parentheses in square brackets not allowed");
1008 if(stack.empty())
1009 throw std::runtime_error("Unmatched right parenthesis");
1010 size_t x = stack.back();
1011 stack.pop_back();
1012 last_size = (data.size() - x) / stride;
1013 } else if(ch == '*') {
1014 autoterminate = true;
1015 } else if(ch == '?') {
1016 if(!btn_token)
1017 throw std::runtime_error("? needs button to apply to");
1018 if(!in_sparen)
1019 throw std::runtime_error("? needs to be in brackets");
1020 data[data.size() - stride + last_bit] |= 2;
1021 } else if(ch == '[') {
1022 if(in_sparen)
1023 throw std::runtime_error("Nested square brackets not allowed");
1024 in_sparen = true;
1025 data.resize(data.size() + stride);
1026 adata.resize(adata.size() + astride);
1027 last_size = 1;
1028 } else if(ch == ']') {
1029 if(!in_sparen)
1030 throw std::runtime_error("Unmatched right square bracket");
1031 in_sparen = false;
1032 } else if(ch == '.') {
1033 if(!in_sparen) {
1034 data.resize(data.size() + stride);
1035 adata.resize(adata.size() + astride);
1036 last_size = 1;
1038 } else if(spec[idx] >= '0' && spec[idx] <= '9') {
1039 size_t rep = 0;
1040 unsigned i = 0;
1041 while(spec[idx + i] >= '0' && spec[idx + i] <= '9') {
1042 rep = 10 * rep + (spec[idx + i] - '0');
1043 i++;
1045 if(in_sparen) {
1046 //This has special meaning: Axis transform.
1047 //Rep is the axis pair to operate on.
1048 if(spec[idx + i] != ':')
1049 throw std::runtime_error("Expected ':' in axis transform");
1050 size_t sep = i;
1051 while(idx + i < len && spec[idx + i] != '@')
1052 i++;
1053 if(idx + i >= len)
1054 throw std::runtime_error("Expected '@' in axis transform");
1055 std::string aexpr = spec.substr(idx + sep + 1, i - sep - 1);
1056 if(rep >= astride)
1057 throw std::runtime_error("Axis transform refers to invalid axis");
1058 adata[adata.size() - astride + rep] = axis_transform(aexpr);
1059 i++;
1060 } else {
1061 if(first)
1062 throw std::runtime_error("Repeat not allowed without frame to "
1063 "repeat");
1064 size_t o = data.size();
1065 size_t ao = adata.size();
1066 data.resize(o + (rep - 1) * last_size * stride);
1067 adata.resize(ao + (rep - 1) * last_size * astride);
1068 for(unsigned i = 1; i < rep; i++) {
1069 memcpy(&data[o + (i - 1) * last_size * stride], &data[o - last_size *
1070 stride], last_size * stride);
1071 memcpy(&data[ao + (i - 1) * last_size * astride], &data[ao -
1072 last_size * astride], last_size * astride);
1074 last_size = last_size * rep;
1076 idx = idx + (i - 1);
1077 } else { //Symbol.
1078 bool found = false;
1079 for(auto k : symbols) {
1080 std::string key = k.first;
1081 size_t j;
1082 for(j = 0; idx + j < len && j < key.length(); j++)
1083 if(spec[idx + j] != key[j])
1084 break;
1085 if(j == key.length()) {
1086 idx += key.length() - 1;
1087 found = true;
1088 if(!in_sparen) {
1089 data.resize(data.size() + stride);
1090 adata.resize(adata.size() + astride);
1092 last_bit = k.second;
1093 data[data.size() - stride + k.second] |= 1;
1094 if(!in_sparen)
1095 last_size = 1;
1098 if(!found)
1099 throw std::runtime_error("Unknown character or button");
1100 btn_token_next = true;
1102 idx++;
1103 first = false;
1105 if(in_sparen)
1106 throw std::runtime_error("Unmatched left square bracket");
1107 if(!stack.empty())
1108 throw std::runtime_error("Unmatched left parenthesis");
1109 } catch(std::exception& e) {
1110 (stringfmt() << "Error parsing macro for controller " << (inum + 1) << ": " << e.what()).throwex();
1114 bool macro_data::syntax_check(const std::string& spec, const JSON::node& desc)
1116 unsigned buttons = 0;
1117 size_t astride = 0;
1118 if(desc.type() != JSON::array)
1119 return false;
1120 for(auto i = desc.begin(); i != desc.end(); ++i) {
1121 if(i->type() == JSON::string)
1122 buttons++;
1123 else if(i->type() == JSON::number) {
1124 uint64_t anum = i->as_uint();
1125 if(anum > astride)
1126 return false;
1127 else if(anum == astride)
1128 astride++;
1129 } else
1130 return false;
1132 bool autoterminate = false;
1133 size_t depth = 0;
1134 bool in_sparen = false;
1135 bool first = true;
1136 bool btn_token = false;
1137 bool btn_token_next = false;
1138 size_t idx = 0;
1139 size_t len = spec.length();
1140 while(idx < len) {
1141 btn_token = btn_token_next;
1142 btn_token_next = false;
1143 unsigned char ch = spec[idx];
1144 if(autoterminate)
1145 return false;
1146 if(ch == '(') {
1147 if(in_sparen)
1148 return false;
1149 depth++;
1150 } else if(ch == ')') {
1151 if(in_sparen)
1152 return false;
1153 if(!depth)
1154 return false;
1155 depth--;
1156 } else if(ch == '*') {
1157 autoterminate = true;
1158 } else if(ch == '?') {
1159 if(!btn_token || !in_sparen)
1160 return false;
1161 } else if(ch == '[') {
1162 if(in_sparen)
1163 return false;
1164 in_sparen = true;
1165 } else if(ch == ']') {
1166 if(!in_sparen)
1167 return false;
1168 in_sparen = false;
1169 } else if(ch == '.') {
1170 } else if(spec[idx] >= '0' && spec[idx] <= '9') {
1171 size_t rep = 0;
1172 unsigned i = 0;
1173 while(spec[idx + i] >= '0' && spec[idx + i] <= '9') {
1174 rep = 10 * rep + (spec[idx + i] - '0');
1175 i++;
1177 if(in_sparen) {
1178 //This has special meaning: Axis transform.
1179 //Rep is the axis pair to operate on.
1180 if(spec[idx + i] != ':')
1181 return false;
1182 size_t sep = i;
1183 while(idx + i < len && spec[idx + i] != '@')
1184 i++;
1185 if(idx + i >= len)
1186 return false;
1187 if(rep >= astride)
1188 return false;
1189 try {
1190 std::string aexpr = spec.substr(idx + sep + 1, i - sep - 1);
1191 axis_transform x(aexpr);
1192 } catch(...) {
1193 return false;
1195 i++;
1196 } else {
1197 if(first)
1198 return false;
1200 idx = idx + (i - 1);
1201 } else { //Symbol.
1202 bool found = false;
1203 for(auto i = desc.begin(); i != desc.end(); ++i) {
1204 if(i->type() != JSON::string)
1205 continue;
1206 std::string key = i->as_string8();
1207 size_t j;
1208 for(j = 0; idx + j < len && j < key.length(); j++)
1209 if(spec[idx + j] != key[j])
1210 break;
1211 if(j == key.length()) {
1212 idx += key.length() - 1;
1213 found = true;
1216 if(!found)
1217 return false;
1218 btn_token_next = true;
1220 idx++;
1221 first = false;
1223 if(in_sparen)
1224 return false;
1225 if(depth)
1226 return false;
1227 return true;
1230 void macro_data::write(frame& frame, unsigned port, unsigned controller_n, int64_t nframe,
1231 apply_mode amode)
1233 if(!enabled)
1234 return;
1235 if(autoterminate && (nframe < 0 || nframe >= (int64_t)get_frames()))
1236 return;
1237 if(nframe < 0)
1238 nframe += ((-nframe / get_frames()) + 3) * get_frames();
1239 nframe %= get_frames();
1240 for(size_t i = 0; i < buttons; i++) {
1241 unsigned lb = btnmap[i];
1242 unsigned st = data[nframe * get_stride() + i];
1243 if(st == 3)
1244 st = macro_random_bit();
1245 if(st == 1)
1246 switch(amode) {
1247 case AM_OVERWRITE:
1248 case AM_OR:
1249 frame.axis3(port, controller_n, lb, 1);
1250 break;
1251 case AM_XOR:
1252 frame.axis3(port, controller_n, lb, frame.axis3(port, controller_n, lb) ^ 1);
1253 break;
1255 else
1256 switch(amode) {
1257 case AM_OVERWRITE:
1258 frame.axis3(port, controller_n, lb, 0);
1259 break;
1260 case AM_OR:
1261 case AM_XOR:
1265 const controller* _ctrl = frame.porttypes().port_type(port).controller_info->get(controller_n);
1266 if(!_ctrl)
1267 return;
1268 size_t abuttons = aaxes.size();
1269 for(size_t i = 0; i < abuttons; i++) {
1270 unsigned ax = aaxes[i].first;
1271 unsigned ay = aaxes[i].second;
1272 if(ay != std::numeric_limits<unsigned>::max()) {
1273 if(ax > _ctrl->buttons.size()) continue;
1274 if(ay > _ctrl->buttons.size()) continue;
1275 auto g = adata[nframe * abuttons + i].transform(_ctrl->buttons[ax], _ctrl->buttons[ay],
1276 frame.axis3(port, controller_n, ax), frame.axis3(port, controller_n, ay));
1277 frame.axis3(port, controller_n, ax, g.first);
1278 frame.axis3(port, controller_n, ay, g.second);
1279 } else {
1280 if(ax > _ctrl->buttons.size()) continue;
1281 int16_t g = adata[nframe * abuttons + i].transform(_ctrl->buttons[ax],
1282 frame.axis3(port, controller_n, ax));
1283 frame.axis3(port, controller_n, ax, g);
1288 std::string macro_data::dump(const controller& ctrl)
1290 std::ostringstream o;
1291 for(size_t i = 0; i < get_frames(); i++) {
1292 o << "[";
1293 for(size_t j = 0; j < aaxes.size(); j++) {
1294 macro_data::axis_transform& t = adata[i * aaxes.size() + j];
1295 o << j << ":";
1296 o << t.coeffs[0] << "," << t.coeffs[1] << "," << t.coeffs[2] << ",";
1297 o << t.coeffs[3] << "," << t.coeffs[4] << "," << t.coeffs[5] << "@";
1299 for(size_t j = 0; j < buttons && j < ctrl.buttons.size(); j++) {
1300 unsigned st = data[i * get_stride() + j];
1301 if(ctrl.buttons[j].macro == "")
1302 continue;
1303 if(st == 1)
1304 o << ctrl.buttons[j].macro;
1305 if(st == 3)
1306 o << ctrl.buttons[j].macro << "?";
1308 o << "]";
1310 if(autoterminate)
1311 o << "*";
1312 return o.str();
1315 void macro::write(frame& frame, int64_t nframe)
1317 for(auto& i : macros) {
1318 unsigned port;
1319 unsigned controller;
1320 try {
1321 auto g = frame.porttypes().lcid_to_pcid(i.first);
1322 port = g.first;
1323 controller = g.second;
1324 } catch(...) {
1325 continue;
1327 i.second.write(frame, port, controller, nframe, amode);
1331 int16_t macro_data::axis_transform::transform(const button& b, int16_t v)
1333 return scale_axis(b, coeffs[0] * unscale_axis(b, v) + coeffs[4]);
1336 std::pair<int16_t, int16_t> macro_data::axis_transform::transform(const button& b1,
1337 const button& b2, int16_t v1, int16_t v2)
1339 double x, y, u, v, au, av, s;
1340 x = unscale_axis(b1, v1);
1341 y = unscale_axis(b2, v2);
1342 u = coeffs[0] * x + coeffs[1] * y + coeffs[4];
1343 v = coeffs[2] * x + coeffs[3] * y + coeffs[5];
1344 au = abs(u);
1345 av = abs(v);
1346 s = max(max(au, 1.0), max(av, 1.0));
1347 //If u and v exceed nominal range of [-1,1], those need to be projected to the edge.
1348 if(s > 1) {
1349 u /= s;
1350 v /= s;
1352 auto g = std::make_pair(scale_axis(b1, u), scale_axis(b2, v));
1353 return g;
1356 double macro_data::axis_transform::unscale_axis(const button& b, int16_t v)
1358 if(b.centers) {
1359 int32_t center = ((int32_t)b.rmin + (int32_t)b.rmax) / 2;
1360 if(v <= b.rmin)
1361 return -1;
1362 if(v < center)
1363 return -(center - (double)v) / (center - b.rmin);
1364 if(v == center)
1365 return 0;
1366 if(v < b.rmax)
1367 return ((double)v - center) / (b.rmax - center);
1368 return 1;
1369 } else {
1370 if(v <= b.rmin)
1371 return 0;
1372 if(v >= b.rmax)
1373 return 1;
1374 return ((double)v - b.rmin) / (b.rmax - b.rmin);
1378 int16_t macro_data::axis_transform::scale_axis(const button& b, double v)
1380 if(b.centers) {
1381 int32_t center = ((int32_t)b.rmin + (int32_t)b.rmax) / 2;
1382 if(v == 0)
1383 return center;
1384 if(v < 0) {
1385 double v2 = v * (center - b.rmin) + center;
1386 if(v2 < b.rmin)
1387 return b.rmin;
1388 return v2;
1390 double v2 = v * (b.rmax - center) + center;
1391 if(v2 > b.rmax)
1392 return b.rmax;
1393 return v2;
1394 } else {
1395 double v2 = v * (b.rmax - b.rmin) + b.rmin;
1396 if(v2 < b.rmin)
1397 return b.rmin;
1398 if(v2 > b.rmax)
1399 return b.rmax;
1400 return v2;
1404 namespace
1406 std::complex<double> parse_complex(const std::string& expr)
1408 regex_results r;
1409 if(r = regex("\\((.*),(.*)\\)", expr)) {
1410 //Real,Imaginary.
1411 return std::complex<double>(parse_value<double>(r[1]), parse_value<double>(r[2]));
1412 } else if(r = regex("\\((.*)<(.*)\\)", expr)) {
1413 return std::polar(parse_value<double>(r[1]), parse_value<double>(r[2]) * M_PI / 180);
1414 } else {
1415 return std::complex<double>(parse_value<double>(expr), 0.0);
1420 macro_data::axis_transform::axis_transform(const std::string& expr)
1422 regex_results r;
1423 if(r = regex("\\*(.*)\\+(.*)", expr)) {
1424 //Affine transform.
1425 std::complex<double> a = parse_complex(r[1]);
1426 std::complex<double> b = parse_complex(r[2]);
1427 coeffs[0] = a.real();
1428 coeffs[1] = -a.imag();
1429 coeffs[2] = a.imag();
1430 coeffs[3] = a.real();
1431 coeffs[4] = b.real();
1432 coeffs[5] = b.imag();
1433 } else if(r = regex("\\*(.*)", expr)) {
1434 //Linear transform.
1435 std::complex<double> a = parse_complex(r[1]);
1436 coeffs[0] = a.real();
1437 coeffs[1] = -a.imag();
1438 coeffs[2] = a.imag();
1439 coeffs[3] = a.real();
1440 coeffs[4] = 0;
1441 coeffs[5] = 0;
1442 } else if(r = regex("\\+(.*)", expr)) {
1443 //Relative
1444 std::complex<double> b = parse_complex(r[1]);
1445 coeffs[0] = 1;
1446 coeffs[1] = 0;
1447 coeffs[2] = 0;
1448 coeffs[3] = 1;
1449 coeffs[4] = b.real();
1450 coeffs[5] = b.imag();
1451 } else if(r = regex("(.*),(.*),(.*),(.*),(.*),(.*)", expr)) {
1452 //Full affine.
1453 coeffs[0] = parse_value<double>(r[1]);
1454 coeffs[1] = parse_value<double>(r[2]);
1455 coeffs[2] = parse_value<double>(r[3]);
1456 coeffs[3] = parse_value<double>(r[4]);
1457 coeffs[4] = parse_value<double>(r[5]);
1458 coeffs[5] = parse_value<double>(r[6]);
1459 } else {
1460 //Absolute.
1461 std::complex<double> b = parse_complex(expr);
1462 coeffs[0] = 0;
1463 coeffs[1] = 0;
1464 coeffs[2] = 0;
1465 coeffs[3] = 0;
1466 coeffs[4] = b.real();
1467 coeffs[5] = b.imag();
1471 JSON::node macro::serialize()
1473 JSON::node v(JSON::object);
1474 switch(amode) {
1475 case macro_data::AM_OVERWRITE: v.insert("mode", JSON::s("overwrite")); break;
1476 case macro_data::AM_OR: v.insert("mode", JSON::s("or")); break;
1477 case macro_data::AM_XOR: v.insert("mode", JSON::s("xor")); break;
1479 JSON::node& c = v.insert("data", JSON::array());
1480 for(auto& i : macros) {
1481 while(i.first > c.index_count())
1482 c.append(JSON::n());
1483 i.second.serialize(c.append(JSON::n()));
1485 return v;
1488 void macro_data::serialize(JSON::node& v)
1490 v = JSON::object();
1491 v.insert("enable", JSON::b(enabled));
1492 v.insert("expr", JSON::s(orig));
1493 v.insert("desc", _descriptor);
1496 JSON::node macro_data::make_descriptor(const controller& ctrl)
1498 JSON::node n(JSON::array);
1499 for(size_t i = 0; i < ctrl.buttons.size(); i++) {
1500 if(ctrl.buttons[i].macro != "")
1501 n.append(JSON::s(ctrl.buttons[i].macro));
1502 else
1503 n.append(JSON::n()); //Placeholder.
1505 for(size_t i = 0; i < ctrl.analog_actions(); i++) {
1506 auto g = ctrl.analog_action(i);
1507 n.index(g.first) = JSON::u(i);
1508 if(g.second != std::numeric_limits<unsigned>::max())
1509 n.index(g.second) = JSON::u(i);
1511 return n;
1514 macro::macro(const JSON::node& v)
1516 if(v.type() != JSON::object)
1517 throw std::runtime_error("Expected macro to be JSON object");
1518 std::string mode = macro_field_as_string(v, "mode");
1519 if(mode == "overwrite") amode = macro_data::AM_OVERWRITE;
1520 else if(mode == "or") amode = macro_data::AM_OR;
1521 else if(mode == "xor") amode = macro_data::AM_XOR;
1522 else (stringfmt() << "Unknown button mode '" << mode << "'").throwex();
1523 const JSON::node& c = macro_field_as_array(v, "data");
1524 for(auto i = c.begin(); i != c.end(); ++i) {
1525 if(i->type() == JSON::object)
1526 macros[i.index()] = macro_data(*i, i.index());
1527 else
1528 (stringfmt() << "Expected object as field 'data/" << i.index() << "'").throwex();
1532 macro_data::macro_data(const JSON::node& v, unsigned i)
1533 : macro_data(macro_field_as_string(v, "expr"), macro_field_as_array(v, "desc"), i)
1535 enabled = macro_field_as_boolean(v, "enable");