When showing input in readwrite mode, show last sent input
[lsnes.git] / src / core / controllerframe.cpp
blobf5f96899eb32154e9b7804a99336d99eeb3ddaa8
1 #include "core/controllerframe.hpp"
2 #include "core/dispatch.hpp"
3 #include "core/misc.hpp"
5 #include <cstdio>
6 #include <iostream>
8 #define SYSTEM_BYTES 5
10 namespace
12 std::set<porttype_info*>& porttypes()
14 static std::set<porttype_info*> p;
15 return p;
18 const char* buttonnames[MAX_LOGICAL_BUTTONS] = {
19 "left", "right", "up", "down", "A", "B", "X", "Y", "L", "R", "select", "start", "trigger",
20 "cursor", "turbo", "pause"
24 /**
25 * Get name of logical button.
27 * Parameter lbid: ID of logical button.
28 * Returns: The name of button.
29 * Throws std::bad_alloc: Not enough memory.
31 std::string get_logical_button_name(unsigned lbid) throw(std::bad_alloc)
33 if(lbid >= MAX_LOGICAL_BUTTONS)
34 return "";
35 return buttonnames[lbid];
38 const porttype_info& porttype_info::lookup(porttype_t p) throw(std::runtime_error)
40 for(auto i : porttypes())
41 if(p == i->value)
42 return *i;
43 throw std::runtime_error("Bad port type");
46 const porttype_info& porttype_info::lookup(const std::string& p) throw(std::runtime_error)
48 for(auto i : porttypes())
49 if(p == i->name)
50 return *i;
51 throw std::runtime_error("Bad port type");
54 porttype_info::~porttype_info() throw()
56 porttypes().erase(this);
59 porttype_info::porttype_info(porttype_t ptype, const std::string& pname, size_t psize) throw(std::bad_alloc)
61 value = ptype;
62 name = pname;
63 storage_size = psize;
64 porttypes().insert(this);
67 pollcounter_vector::pollcounter_vector() throw()
69 clear();
72 void pollcounter_vector::clear() throw()
74 system_flag = false;
75 memset(ctrs, 0, sizeof(ctrs));
78 void pollcounter_vector::set_all_DRDY() throw()
80 for(size_t i = 0; i < MAX_BUTTONS ; i++)
81 ctrs[i] |= 0x80000000UL;
84 #define INDEXOF(pcid, ctrl) ((pcid) * MAX_CONTROLS_PER_CONTROLLER + (ctrl))
86 void pollcounter_vector::clear_DRDY(unsigned pcid, unsigned ctrl) throw()
88 ctrs[INDEXOF(pcid, ctrl)] &= 0x7FFFFFFFUL;
91 bool pollcounter_vector::get_DRDY(unsigned pcid, unsigned ctrl) throw()
93 return ((ctrs[INDEXOF(pcid, ctrl)] & 0x80000000UL) != 0);
96 bool pollcounter_vector::has_polled() throw()
98 uint32_t res = system_flag ? 1 : 0;
99 for(size_t i = 0; i < MAX_BUTTONS ; i++)
100 res |= ctrs[i];
101 return ((res & 0x7FFFFFFFUL) != 0);
104 uint32_t pollcounter_vector::get_polls(unsigned pcid, unsigned ctrl) throw()
106 return ctrs[INDEXOF(pcid, ctrl)] & 0x7FFFFFFFUL;
109 uint32_t pollcounter_vector::increment_polls(unsigned pcid, unsigned ctrl) throw()
111 size_t i = INDEXOF(pcid, ctrl);
112 uint32_t x = ctrs[i] & 0x7FFFFFFFUL;
113 ++ctrs[i];
114 return x;
117 void pollcounter_vector::set_system() throw()
119 system_flag = true;
122 bool pollcounter_vector::get_system() throw()
124 return system_flag;
127 uint32_t pollcounter_vector::max_polls() throw()
129 uint32_t max = system_flag ? 1 : 0;
130 for(unsigned i = 0; i < MAX_BUTTONS; i++) {
131 uint32_t tmp = ctrs[i] & 0x7FFFFFFFUL;
132 max = (max < tmp) ? tmp : max;
134 return max;
137 void pollcounter_vector::save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc)
139 mem.resize(4 + MAX_BUTTONS );
140 //Compatiblity fun.
141 mem[0] = 0x80000000UL;
142 mem[1] = system_flag ? 1 : 0x80000000UL;
143 mem[2] = system_flag ? 1 : 0x80000000UL;
144 mem[3] = system_flag ? 1 : 0x80000000UL;
145 for(size_t i = 0; i < MAX_BUTTONS ; i++)
146 mem[4 + i] = ctrs[i];
149 void pollcounter_vector::load_state(const std::vector<uint32_t>& mem) throw()
151 system_flag = (mem[1] | mem[2] | mem[3]) & 0x7FFFFFFFUL;
152 for(size_t i = 0; i < MAX_BUTTONS ; i++)
153 ctrs[i] = mem[i + 4];
156 bool pollcounter_vector::check(const std::vector<uint32_t>& mem) throw()
158 return (mem.size() == MAX_BUTTONS + 4);
162 controller_frame::controller_frame(porttype_t p1, porttype_t p2) throw(std::runtime_error)
164 memset(memory, 0, sizeof(memory));
165 backing = memory;
166 types[0] = p1;
167 types[1] = p2;
168 set_types(types);
171 controller_frame::controller_frame(unsigned char* mem, porttype_t p1, porttype_t p2) throw(std::runtime_error)
173 if(!mem)
174 throw std::runtime_error("NULL backing memory not allowed");
175 memset(memory, 0, sizeof(memory));
176 backing = mem;
177 types[0] = p1;
178 types[1] = p2;
179 set_types(types);
182 controller_frame::controller_frame(const controller_frame& obj) throw()
184 memset(memory, 0, sizeof(memory));
185 backing = memory;
186 set_types(obj.types);
187 memcpy(backing, obj.backing, totalsize);
190 controller_frame& controller_frame::operator=(const controller_frame& obj) throw(std::runtime_error)
192 set_types(obj.types);
193 memcpy(backing, obj.backing, totalsize);
196 void controller_frame::set_types(const porttype_t* tarr)
198 for(unsigned i = 0; i < MAX_PORTS; i++) {
199 if(memory != backing && types[i] != tarr[i])
200 throw std::runtime_error("Controller_frame: Type mismatch");
201 if(!porttype_info::lookup(tarr[i]).legal(i))
202 throw std::runtime_error("Illegal port type for port index");
204 size_t offset = SYSTEM_BYTES;
205 for(unsigned i = 0; i < MAX_PORTS; i++) {
206 offsets[i] = offset;
207 types[i] = tarr[i];
208 pinfo[i] = &porttype_info::lookup(tarr[i]);
209 offset += pinfo[i]->storage_size;
211 totalsize = offset;
214 size_t controller_frame_vector::walk_helper(size_t frame, bool sflag) throw()
216 size_t ret = sflag ? frame : 0;
217 if(frame >= frames)
218 return ret;
219 frame++;
220 ret++;
221 size_t page = frame / frames_per_page;
222 size_t offset = frame_size * (frame % frames_per_page);
223 size_t index = frame % frames_per_page;
224 if(cache_page_num != page) {
225 cache_page = &pages[page];
226 cache_page_num = page;
228 while(frame < frames) {
229 if(index == frames_per_page) {
230 page++;
231 cache_page = &pages[page];
232 cache_page_num = page;
234 if(controller_frame::sync(cache_page->content + offset))
235 break;
236 index++;
237 offset += frame_size;
238 frame++;
239 ret++;
241 return ret;
244 size_t controller_frame_vector::count_frames() throw()
246 size_t ret = 0;
247 if(!frames)
248 return 0;
249 cache_page_num = 0;
250 cache_page = &pages[0];
251 size_t offset = 0;
252 size_t index = 0;
253 for(size_t i = 0; i < frames; i++) {
254 if(index == frames_per_page) {
255 cache_page_num++;
256 cache_page = &pages[cache_page_num];
257 index = 0;
258 offset = 0;
260 if(controller_frame::sync(cache_page->content + offset))
261 ret++;
262 index++;
263 offset += frame_size;
266 return ret;
269 void controller_frame_vector::clear(enum porttype_t p1, enum porttype_t p2) throw(std::runtime_error)
271 controller_frame check(p1, p2);
272 frame_size = check.size();
273 frames_per_page = CONTROLLER_PAGE_SIZE / frame_size;
274 frames = 0;
275 types[0] = p1;
276 types[1] = p2;
277 clear_cache();
278 pages.clear();
281 controller_frame_vector::~controller_frame_vector() throw()
283 pages.clear();
284 cache_page = NULL;
287 controller_frame_vector::controller_frame_vector(enum porttype_t p1, enum porttype_t p2) throw(std::runtime_error)
289 clear(p1, p2);
292 void controller_frame_vector::append(controller_frame frame) throw(std::bad_alloc, std::runtime_error)
294 controller_frame check(types[0], types[1]);
295 if(!check.types_match(frame))
296 throw std::runtime_error("controller_frame_vector::append: Type mismatch");
297 if(frames % frames_per_page == 0) {
298 //Create new page.
299 pages[frames / frames_per_page];
301 //Write the entry.
302 size_t page = frames / frames_per_page;
303 size_t offset = frame_size * (frames % frames_per_page);
304 if(cache_page_num != page) {
305 cache_page_num = page;
306 cache_page = &pages[page];
308 controller_frame(cache_page->content + offset, types[0], types[1]) = frame;
309 frames++;
312 controller_frame_vector::controller_frame_vector(const controller_frame_vector& vector) throw(std::bad_alloc)
314 clear(vector.types[0], vector.types[1]);
315 *this = vector;
318 controller_frame_vector& controller_frame_vector::operator=(const controller_frame_vector& v)
319 throw(std::bad_alloc)
321 if(this == &v)
322 return *this;
323 resize(v.frames);
324 clear_cache();
326 //Copy the fields.
327 frame_size = v.frame_size;
328 frames_per_page = v.frames_per_page;
329 for(size_t i = 0; i < MAX_PORTS; i++)
330 types[i] = v.types[i];
332 //This can't fail anymore. Copy the raw page contents.
333 size_t pagecount = (frames + frames_per_page - 1) / frames_per_page;
334 for(size_t i = 0; i < pagecount; i++) {
335 page& pg = pages[i];
336 const page& pg2 = v.pages.find(i)->second;
337 pg = pg2;
340 return *this;
343 size_t controller_frame::system_serialize(const unsigned char* buffer, char* textbuf)
345 char tmp[128];
346 if(buffer[1] || buffer[2] || buffer[3] || buffer[4])
347 sprintf(tmp, "%c%c %i %i", ((buffer[0] & 1) ? 'F' : '.'), ((buffer[0] & 2) ? 'R' : '.'),
348 unserialize_short(buffer + 1), unserialize_short(buffer + 3));
349 else
350 sprintf(tmp, "%c%c", ((buffer[0] & 1) ? 'F' : '.'), ((buffer[0] & 2) ? 'R' : '.'));
351 size_t len = strlen(tmp);
352 memcpy(textbuf, tmp, len);
353 return len;
356 size_t controller_frame::system_deserialize(unsigned char* buffer, const char* textbuf)
358 buffer[0] = 0;
359 size_t idx = 0;
360 if(read_button_value(textbuf, idx))
361 buffer[0] |= 1;
362 if(read_button_value(textbuf, idx))
363 buffer[0] |= 2;
364 serialize_short(buffer + 1, read_axis_value(textbuf, idx));
365 serialize_short(buffer + 3, read_axis_value(textbuf, idx));
366 skip_rest_of_field(textbuf, idx, false);
367 return idx;
370 short read_axis_value(const char* buf, size_t& idx) throw()
372 char ch;
373 //Skip ws.
374 while(is_nonterminator(buf[idx])) {
375 char ch = buf[idx];
376 if(ch != ' ' && ch != '\t')
377 break;
378 idx++;
380 //Read the sign if any.
381 if(!is_nonterminator(buf[idx]))
382 return 0;
383 bool negative = false;
384 if(ch == '-') {
385 negative = true;
386 idx++;
388 if(ch == '+')
389 idx++;
391 //Read numeric value.
392 int numval = 0;
393 while(!is_nonterminator(buf[idx]) && isdigit(static_cast<unsigned char>(ch = buf[idx]))) {
394 numval = numval * 10 + (ch - '0');
395 idx++;
397 if(negative)
398 numval = -numval;
400 return static_cast<short>(numval);
403 void controller_frame_vector::resize(size_t newsize) throw(std::bad_alloc)
405 clear_cache();
406 if(newsize == 0) {
407 clear();
408 } else if(newsize < frames) {
409 //Shrink movie.
410 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
411 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
412 for(size_t i = pages_needed; i < current_pages; i++)
413 pages.erase(i);
414 //Now zeroize the excess memory.
415 size_t offset = frame_size * (newsize % frames_per_page);
416 memset(pages[pages_needed - 1].content + offset, 0, CONTROLLER_PAGE_SIZE - offset);
417 frames = newsize;
418 } else if(newsize > frames) {
419 //Enlarge movie.
420 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
421 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
422 //Create the needed pages.
423 for(size_t i = current_pages; i < pages_needed; i++) {
424 try {
425 pages[i];
426 } catch(...) {
427 for(size_t i = current_pages; i < pages_needed; i++)
428 if(pages.count(i))
429 pages.erase(i);
430 throw;
433 frames = newsize;
437 controller_frame::controller_frame() throw()
439 memset(memory, 0, sizeof(memory));
440 backing = memory;
441 for(unsigned i = 0; i < MAX_PORTS; i++) {
442 offsets[i] = SYSTEM_BYTES;
443 types[i] = PT_INVALID;
444 pinfo[i] = NULL;
446 totalsize = SYSTEM_BYTES;
449 void controller_frame::set_port_type(unsigned port, porttype_t ptype) throw(std::runtime_error)
451 char tmp[MAXIMUM_CONTROLLER_FRAME_SIZE] = {0};
452 if(!porttype_info::lookup(ptype).legal(port))
453 throw std::runtime_error("Illegal port type for port index");
454 if(memory != backing)
455 throw std::runtime_error("Can't set port type on non-dedicated controller frame");
456 if(port >= MAX_PORTS)
457 return;
458 const porttype_info* newpinfo[MAX_PORTS];
459 size_t newoffsets[MAX_PORTS];
460 size_t offset = SYSTEM_BYTES;
461 for(size_t i = 0; i < MAX_PORTS; i++) {
462 if(i != port)
463 newpinfo[i] = pinfo[i];
464 else
465 newpinfo[i] = &porttype_info::lookup(ptype);
466 newoffsets[i] = offset;
467 if(newpinfo[i])
468 offset += newpinfo[i]->storage_size;
469 if(i != port && newpinfo[i] && newpinfo[i]->storage_size)
470 memcpy(tmp + newoffsets[i], backing + offsets[i], newpinfo[i]->storage_size);
472 memcpy(memory, tmp, MAXIMUM_CONTROLLER_FRAME_SIZE);
473 types[port] = ptype;
474 pinfo[port] = newpinfo[port];
475 for(size_t i = 0; i < MAX_PORTS; i++)
476 offsets[i] = newoffsets[i];
477 totalsize = offset;
480 controller_state::controller_state() throw()
482 for(size_t i = 0; i < MAX_ANALOG; i++) {
483 analog_indices[i] = -1;
484 analog_mouse[i] = false;
486 for(size_t i = 0; i < MAX_PORTS; i++) {
487 porttypes[i] = PT_INVALID;
488 porttypeinfo[i] = NULL;
492 int controller_state::lcid_to_pcid(unsigned lcid) throw()
494 if(!porttypeinfo[0] || !porttypeinfo[1])
495 return -1;
496 unsigned p1devs = porttypeinfo[0]->controllers();
497 unsigned p2devs = porttypeinfo[1]->controllers();
498 if(lcid >= p1devs + p2devs)
499 return -1;
500 //Exceptional: If p1 is none, map all to p2.
501 if(!p1devs)
502 return lcid + MAX_CONTROLLERS_PER_PORT;
503 //LID 0 Is always PID 0 unless out of range.
504 if(lcid == 0)
505 return 0;
506 //LID 1-n are on port 2.
507 else if(lcid < 1 + p2devs)
508 return lcid - 1 + MAX_CONTROLLERS_PER_PORT;
509 //From there, those are on port 1 (except for the first).
510 else
511 return lcid - p2devs;
514 int controller_state::acid_to_pcid(unsigned acid) throw()
516 if(acid > MAX_ANALOG)
517 return -1;
518 return analog_indices[acid];
521 bool controller_state::acid_is_mouse(unsigned acid) throw()
523 if(acid > MAX_ANALOG)
524 return -1;
525 return analog_mouse[acid];
529 devicetype_t controller_state::pcid_to_type(unsigned pcid) throw()
531 size_t port = pcid / MAX_CONTROLLERS_PER_PORT;
532 if(port >= MAX_PORTS)
533 return DT_NONE;
534 return porttypeinfo[port]->devicetype(pcid % MAX_CONTROLLERS_PER_PORT);
537 controller_frame controller_state::get(uint64_t framenum) throw()
539 if(_autofire.size())
540 return _input ^ _autohold ^ _autofire[framenum % _autofire.size()];
541 else
542 return _input ^ _autohold;
545 void controller_state::analog(unsigned acid, int x, int y) throw()
547 if(acid >= MAX_ANALOG || analog_indices[acid] < 0) {
548 messages << "No analog controller #" << acid << std::endl;
549 return;
551 _input.axis(analog_indices[acid], 0, x);
552 _input.axis(analog_indices[acid], 1, y);
555 void controller_state::reset(int32_t delay) throw()
557 if(delay >= 0) {
558 _input.reset(true);
559 _input.delay(std::make_pair(delay / 10000, delay % 10000));
560 } else {
561 _input.reset(false);
562 _input.delay(std::make_pair(0, 0));
566 void controller_state::autohold(unsigned pcid, unsigned pbid, bool newstate) throw()
568 _autohold.axis(pcid, pbid, newstate ? 1 : 0);
569 information_dispatch::do_autohold_update(pcid, pbid, newstate);
572 bool controller_state::autohold(unsigned pcid, unsigned pbid) throw()
574 return (_autohold.axis(pcid, pbid) != 0);
577 void controller_state::button(unsigned pcid, unsigned pbid, bool newstate) throw()
579 _input.axis(pcid, pbid, newstate ? 1 : 0);
582 bool controller_state::button(unsigned pcid, unsigned pbid) throw()
584 return (_input.axis(pcid, pbid) != 0);
587 void controller_state::autofire(std::vector<controller_frame> pattern) throw(std::bad_alloc)
589 _autofire = pattern;
592 int controller_state::button_id(unsigned pcid, unsigned lbid) throw()
594 size_t port = pcid / MAX_CONTROLLERS_PER_PORT;
595 if(port >= MAX_PORTS)
596 return -1;
597 return porttypeinfo[port]->button_id(pcid % MAX_CONTROLLERS_PER_PORT, lbid);
600 void controller_state::set_port(unsigned port, porttype_t ptype, bool set_core) throw(std::runtime_error)
602 if(port >= MAX_PORTS)
603 throw std::runtime_error("Port number invalid");
604 const porttype_info* info = &porttype_info::lookup(ptype);
605 if(!info->legal(port))
606 throw std::runtime_error("Port type not valid for port");
607 if(set_core)
608 info->set_core_controller(port);
609 porttype_t oldtype = porttypes[port];
610 if(oldtype != ptype) {
611 _input.set_port_type(port, ptype);
612 _autohold.set_port_type(port, ptype);
613 _committed.set_port_type(port, ptype);
614 //The old autofire pattern no longer applies.
615 _autofire.clear();
617 porttypes[port] = ptype;
618 porttypeinfo[port] = info;
619 int i = 0;
620 for(unsigned j = 0; j < MAX_ANALOG; j++)
621 analog_indices[j] = -1;
622 for(unsigned j = 0; j < MAX_PORTS * MAX_CONTROLLERS_PER_PORT; j++) {
623 if(!porttypeinfo[j / MAX_CONTROLLERS_PER_PORT])
624 continue;
625 devicetype_t d = porttypeinfo[j / MAX_CONTROLLERS_PER_PORT]->devicetype(j % MAX_CONTROLLERS_PER_PORT);
626 switch(d) {
627 case DT_NONE:
628 case DT_GAMEPAD:
629 break;
630 case DT_MOUSE:
631 analog_mouse[i] = true;
632 analog_indices[i++] = j;
633 break;
634 case DT_SUPERSCOPE:
635 case DT_JUSTIFIER:
636 analog_mouse[i] = false;
637 analog_indices[i++] = j;
638 break;
640 if(i == MAX_ANALOG)
641 break;
643 information_dispatch::do_autohold_reconfigure();
646 controller_frame controller_state::get_blank() throw()
648 return _input.blank_frame();
651 std::string controller_state::lcid_to_typestring(unsigned lcid) throw(std::bad_alloc)
653 int pcid = lcid_to_pcid(lcid);
654 devicetype_t dtype = DT_NONE;
655 if(pcid >= 0)
656 dtype = pcid_to_type(pcid);
657 switch(dtype) {
658 case DT_NONE: return "disconnected";
659 case DT_GAMEPAD: return "gamepad";
660 case DT_MOUSE: return "mouse";
661 case DT_SUPERSCOPE: return "superscope";
662 case DT_JUSTIFIER: return "justifier";
663 default: return "unknown";
667 controller_frame controller_state::commit(uint64_t framenum) throw()
669 controller_frame f = get(framenum);
670 _committed = f;
671 return _committed;
674 controller_frame controller_state::get_committed() throw()
676 return _committed;
679 controller_frame controller_state::commit(controller_frame controls) throw()
681 _committed = controls;
682 return _committed;