Merge branch 'rr1-maint'
[lsnes.git] / src / library / controller-data.cpp
blobfc1c1480bf6dff5cb33b856b3c2d76d3bcf4d722
1 #include "controller-data.hpp"
2 #include "portfn.hpp"
3 #include "threadtypes.hpp"
4 #include "minmax.hpp"
5 #include "globalwrap.hpp"
6 #include <iostream>
7 #include <list>
9 namespace
11 const char* basecontrol_chars = "F";
13 port_controller_button* null_buttons[] = {};
14 port_controller simple_controller = {"(system)", "system", 0, null_buttons};
15 port_controller* simple_controllers[] = {&simple_controller};
16 port_controller_set simple_port = {1, simple_controllers};
18 struct porttype_basecontrol : public port_type
20 porttype_basecontrol() : port_type("basecontrol", "basecontrol", 999998, 0)
22 write = generic_port_write<1, 0, 1>;
23 read = generic_port_read<1, 0, 1>;
24 display = generic_port_display<1, 0, 1, &basecontrol_chars>;
25 serialize = generic_port_serialize<1, 0, 1, &basecontrol_chars>;
26 deserialize = generic_port_deserialize<1, 0, 1>;
27 legal = generic_port_legal<1>;
28 controller_info = &simple_port;
29 used_indices = generic_used_indices<1, 1>;
31 static port_type& get()
33 static porttype_basecontrol x;
34 return x;
39 port_type::port_type(const std::string& iname, const std::string& _hname, unsigned id,
40 size_t ssize) throw(std::bad_alloc)
41 : hname(_hname), storage_size(ssize), name(iname), pt_id(id)
45 port_type::~port_type() throw()
49 bool port_type::is_present(unsigned controller) const throw()
51 return controller_info->controller_count > controller;
54 namespace
56 size_t dummy_offset = 0;
57 port_type* dummy_type = &porttype_basecontrol::get();
58 unsigned dummy_index = 0;
59 struct binding
61 std::vector<port_type*> types;
62 port_type_set* stype;
63 bool matches(const std::vector<class port_type*>& x)
65 if(x.size() != types.size())
66 return false;
67 for(size_t i = 0; i < x.size(); i++)
68 if(x[i] != types[i])
69 return false;
70 return true;
73 std::list<binding>& bindings()
75 static std::list<binding> x;
76 return x;
80 port_type_set::port_type_set() throw()
83 port_offsets = &dummy_offset;
84 port_types = &dummy_type;
85 port_count = 1;
86 total_size = 1;
87 _indices.resize(1);
88 _indices[0].valid = true;
89 _indices[0].port = 0;
90 _indices[0].controller = 0;
91 _indices[0].control = 0;
93 port_multiplier = 1;
94 controller_multiplier = 1;
95 indices_size = 1;
96 indices_tab = &dummy_index;
99 port_type_set& port_type_set::make(std::vector<class port_type*> types, struct port_index_map control_map)
100 throw(std::bad_alloc, std::runtime_error)
102 for(auto i : bindings())
103 if(i.matches(types))
104 return *(i.stype);
105 //Not found, create new.
106 port_type_set& ret = *new port_type_set(types, control_map);
107 binding b;
108 b.types = types;
109 b.stype = &ret;
110 bindings().push_back(b);
111 return ret;
114 port_type_set::port_type_set(std::vector<class port_type*> types, struct port_index_map control_map)
116 port_count = types.size();
117 //Verify legality of port types.
118 for(size_t i = 0; i < port_count; i++)
119 if(!types[i] || !types[i]->legal(i))
120 throw std::runtime_error("Illegal port types");
121 //Count maximum number of controller indices to determine the controller multiplier.
122 controller_multiplier = 1;
123 for(size_t i = 0; i < port_count; i++)
124 for(unsigned j = 0; j < types[i]->controller_info->controller_count; j++)
125 controller_multiplier = max(controller_multiplier, (size_t)types[i]->used_indices(j));
126 //Count maximum number of controllers to determine the port multiplier.
127 port_multiplier = 1;
128 for(size_t i = 0; i < port_count; i++)
129 port_multiplier = max(port_multiplier, controller_multiplier *
130 (size_t)types[i]->controller_info->controller_count);
131 //Allocate the per-port tables.
132 port_offsets = new size_t[types.size()];
133 port_types = new class port_type*[types.size()];
134 //Determine the total size and offsets.
135 size_t offset = 0;
136 for(size_t i = 0; i < port_count; i++) {
137 port_offsets[i] = offset;
138 offset += types[i]->storage_size;
139 port_types[i] = types[i];
141 total_size = offset;
142 //Determine the index size and allocate it.
143 indices_size = port_multiplier * port_count;
144 indices_tab = new unsigned[indices_size];
145 for(size_t i = 0; i < indices_size; i++)
146 indices_tab[i] = 0xFFFFFFFFUL;
147 //Copy the index data (and reverse it).
148 controllers = control_map.logical_map;
149 legacy_pcids = control_map.pcid_map;
150 _indices = control_map.indices;
151 for(size_t j = 0; j < _indices.size(); j++) {
152 auto& i = _indices[j];
153 if(i.valid)
154 indices_tab[i.port * port_multiplier + i.controller * controller_multiplier + i.control] = j;
158 short read_axis_value(const char* buf, size_t& idx) throw()
160 char ch;
161 //Skip ws.
162 while(is_nonterminator(buf[idx])) {
163 char ch = buf[idx];
164 if(ch != ' ' && ch != '\t')
165 break;
166 idx++;
168 //Read the sign if any.
169 ch = buf[idx];
170 if(!is_nonterminator(ch))
171 return 0;
172 bool negative = false;
173 if(ch == '-') {
174 negative = true;
175 idx++;
177 if(ch == '+')
178 idx++;
180 //Read numeric value.
181 int numval = 0;
182 while(is_nonterminator(buf[idx]) && isdigit(static_cast<unsigned char>(ch = buf[idx]))) {
183 numval = numval * 10 + (ch - '0');
184 idx++;
186 if(negative)
187 numval = -numval;
189 return static_cast<short>(numval);
192 namespace
194 port_type_set& dummytypes()
196 static port_type_set x;
197 return x;
201 pollcounter_vector::pollcounter_vector() throw(std::bad_alloc)
203 types = &dummytypes();
204 ctrs = new uint32_t[types->indices()];
205 clear();
208 pollcounter_vector::pollcounter_vector(const port_type_set& p) throw(std::bad_alloc)
210 types = &p;
211 ctrs = new uint32_t[types->indices()];
212 clear();
215 pollcounter_vector::pollcounter_vector(const pollcounter_vector& p) throw(std::bad_alloc)
217 ctrs = new uint32_t[p.types->indices()];
218 types = p.types;
219 memcpy(ctrs, p.ctrs, sizeof(uint32_t) * p.types->indices());
222 pollcounter_vector& pollcounter_vector::operator=(const pollcounter_vector& p) throw(std::bad_alloc)
224 if(this == &p)
225 return *this;
226 uint32_t* n = new uint32_t[p.types->indices()];
227 types = p.types;
228 memcpy(n, p.ctrs, sizeof(uint32_t) * p.types->indices());
229 delete[] ctrs;
230 ctrs = n;
231 return *this;
234 pollcounter_vector::~pollcounter_vector() throw()
236 delete[] ctrs;
239 void pollcounter_vector::clear() throw()
241 memset(ctrs, 0, sizeof(uint32_t) * types->indices());
244 void pollcounter_vector::set_all_DRDY() throw()
246 for(size_t i = 0; i < types->indices(); i++)
247 ctrs[i] |= 0x80000000UL;
250 void pollcounter_vector::clear_DRDY(unsigned idx) throw()
252 ctrs[idx] &= 0x7FFFFFFFUL;
255 bool pollcounter_vector::get_DRDY(unsigned idx) throw()
257 return ((ctrs[idx] & 0x80000000UL) != 0);
260 bool pollcounter_vector::has_polled() throw()
262 uint32_t res = 0;
263 for(size_t i = 0; i < types->indices() ; i++)
264 res |= ctrs[i];
265 return ((res & 0x7FFFFFFFUL) != 0);
268 uint32_t pollcounter_vector::get_polls(unsigned idx) throw()
270 return ctrs[idx] & 0x7FFFFFFFUL;
273 uint32_t pollcounter_vector::increment_polls(unsigned idx) throw()
275 uint32_t x = ctrs[idx] & 0x7FFFFFFFUL;
276 ++ctrs[idx];
277 return x;
280 uint32_t pollcounter_vector::max_polls() throw()
282 uint32_t max = 0;
283 for(unsigned i = 0; i < types->indices(); i++) {
284 uint32_t tmp = ctrs[i] & 0x7FFFFFFFUL;
285 max = (max < tmp) ? tmp : max;
287 return max;
290 void pollcounter_vector::save_state(std::vector<uint32_t>& mem) throw(std::bad_alloc)
292 mem.resize(types->indices());
293 //Compatiblity fun.
294 for(size_t i = 0; i < types->indices(); i++)
295 mem[i] = ctrs[i];
298 void pollcounter_vector::load_state(const std::vector<uint32_t>& mem) throw()
300 for(size_t i = 0; i < types->indices(); i++)
301 ctrs[i] = mem[i];
304 bool pollcounter_vector::check(const std::vector<uint32_t>& mem) throw()
306 return (mem.size() == types->indices());
310 controller_frame::controller_frame(const port_type_set& p) throw(std::runtime_error)
312 memset(memory, 0, sizeof(memory));
313 backing = memory;
314 types = &p;
317 controller_frame::controller_frame(unsigned char* mem, const port_type_set& p) throw(std::runtime_error)
319 if(!mem)
320 throw std::runtime_error("NULL backing memory not allowed");
321 memset(memory, 0, sizeof(memory));
322 backing = mem;
323 types = &p;
326 controller_frame::controller_frame(const controller_frame& obj) throw()
328 memset(memory, 0, sizeof(memory));
329 backing = memory;
330 types = obj.types;
331 memcpy(backing, obj.backing, types->size());
334 controller_frame& controller_frame::operator=(const controller_frame& obj) throw(std::runtime_error)
336 if(backing != memory && types != obj.types)
337 throw std::runtime_error("Port types do not match");
338 types = obj.types;
339 memcpy(backing, obj.backing, types->size());
340 return *this;
343 size_t controller_frame_vector::walk_helper(size_t frame, bool sflag) throw()
345 size_t ret = sflag ? frame : 0;
346 if(frame >= frames)
347 return ret;
348 frame++;
349 ret++;
350 size_t page = frame / frames_per_page;
351 size_t offset = frame_size * (frame % frames_per_page);
352 size_t index = frame % frames_per_page;
353 if(cache_page_num != page) {
354 cache_page = &pages[page];
355 cache_page_num = page;
357 while(frame < frames) {
358 if(index == frames_per_page) {
359 page++;
360 cache_page = &pages[page];
361 cache_page_num = page;
363 if(controller_frame::sync(cache_page->content + offset))
364 break;
365 index++;
366 offset += frame_size;
367 frame++;
368 ret++;
370 return ret;
373 size_t controller_frame_vector::count_frames() throw()
375 size_t ret = 0;
376 if(!frames)
377 return 0;
378 cache_page_num = 0;
379 cache_page = &pages[0];
380 size_t offset = 0;
381 size_t index = 0;
382 for(size_t i = 0; i < frames; i++) {
383 if(index == frames_per_page) {
384 cache_page_num++;
385 cache_page = &pages[cache_page_num];
386 index = 0;
387 offset = 0;
389 if(controller_frame::sync(cache_page->content + offset))
390 ret++;
391 index++;
392 offset += frame_size;
395 return ret;
398 void controller_frame_vector::clear(const port_type_set& p) throw(std::runtime_error)
400 frame_size = p.size();
401 frames_per_page = CONTROLLER_PAGE_SIZE / frame_size;
402 frames = 0;
403 types = &p;
404 clear_cache();
405 pages.clear();
408 controller_frame_vector::~controller_frame_vector() throw()
410 pages.clear();
411 cache_page = NULL;
414 controller_frame_vector::controller_frame_vector() throw()
416 clear(dummytypes());
419 controller_frame_vector::controller_frame_vector(const port_type_set& p) throw()
421 clear(p);
424 void controller_frame_vector::append(controller_frame frame) throw(std::bad_alloc, std::runtime_error)
426 controller_frame check(*types);
427 if(!check.types_match(frame))
428 throw std::runtime_error("controller_frame_vector::append: Type mismatch");
429 if(frames % frames_per_page == 0) {
430 //Create new page.
431 pages[frames / frames_per_page];
433 //Write the entry.
434 size_t page = frames / frames_per_page;
435 size_t offset = frame_size * (frames % frames_per_page);
436 if(cache_page_num != page) {
437 cache_page_num = page;
438 cache_page = &pages[page];
440 controller_frame(cache_page->content + offset, *types) = frame;
441 frames++;
444 controller_frame_vector::controller_frame_vector(const controller_frame_vector& vector) throw(std::bad_alloc)
446 clear(*vector.types);
447 *this = vector;
450 controller_frame_vector& controller_frame_vector::operator=(const controller_frame_vector& v)
451 throw(std::bad_alloc)
453 if(this == &v)
454 return *this;
455 resize(v.frames);
456 clear_cache();
458 //Copy the fields.
459 frame_size = v.frame_size;
460 frames_per_page = v.frames_per_page;
461 types = v.types;
463 //This can't fail anymore. Copy the raw page contents.
464 size_t pagecount = (frames + frames_per_page - 1) / frames_per_page;
465 for(size_t i = 0; i < pagecount; i++) {
466 page& pg = pages[i];
467 const page& pg2 = v.pages.find(i)->second;
468 pg = pg2;
471 return *this;
477 void controller_frame_vector::resize(size_t newsize) throw(std::bad_alloc)
479 clear_cache();
480 if(newsize == 0) {
481 clear();
482 } else if(newsize < frames) {
483 //Shrink movie.
484 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
485 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
486 for(size_t i = pages_needed; i < current_pages; i++)
487 pages.erase(i);
488 //Now zeroize the excess memory.
489 if(newsize < pages_needed * frames_per_page) {
490 size_t offset = frame_size * (newsize % frames_per_page);
491 memset(pages[pages_needed - 1].content + offset, 0, CONTROLLER_PAGE_SIZE - offset);
493 frames = newsize;
494 } else if(newsize > frames) {
495 //Enlarge movie.
496 size_t current_pages = (frames + frames_per_page - 1) / frames_per_page;
497 size_t pages_needed = (newsize + frames_per_page - 1) / frames_per_page;
498 //Create the needed pages.
499 for(size_t i = current_pages; i < pages_needed; i++) {
500 try {
501 pages[i];
502 } catch(...) {
503 for(size_t i = current_pages; i < pages_needed; i++)
504 if(pages.count(i))
505 pages.erase(i);
506 throw;
509 frames = newsize;
513 controller_frame::controller_frame() throw()
515 memset(memory, 0, sizeof(memory));
516 backing = memory;
517 types = &dummytypes();
520 unsigned port_controller::analog_actions() const
522 unsigned r = 0;
523 for(unsigned i = 0; i < button_count; i++)
524 if(buttons[i]->is_analog() && !buttons[i]->shadow)
525 r++;
526 return (r + 1)/ 2;
529 std::pair<unsigned, unsigned> port_controller::analog_action(unsigned k) const
531 unsigned x1 = std::numeric_limits<unsigned>::max();
532 unsigned x2 = std::numeric_limits<unsigned>::max();
533 unsigned r = 0;
534 for(unsigned i = 0; i < button_count; i++)
535 if(buttons[i]->is_analog() && !buttons[i]->shadow) {
536 if(r == 2 * k)
537 x1 = i;
538 if(r == 2 * k + 1)
539 x2 = i;
540 r++;
542 return std::make_pair(x1, x2);