Fix SA1 open bus
[lsnes.git] / src / core / controllerframe.cpp
blobe47ce0a51ce9d8a18d8d76bff1b6f9795eba9d94
1 #include "core/controller.hpp"
2 #include "core/controllerframe.hpp"
3 #include "core/dispatch.hpp"
4 #include "core/misc.hpp"
5 #include "core/moviedata.hpp"
6 #include "interface/romtype.hpp"
8 #include <cstdio>
9 #include <iostream>
11 void update_movie_state();
13 namespace
15 port_type_set dummytypes;
18 controller_state::controller_state() throw()
20 types = &dummytypes;
21 tasinput_enaged = false;
24 std::pair<int,int> controller_state::lcid_to_pcid(unsigned lcid) throw()
26 if(lcid >= types->number_of_controllers())
27 return std::make_pair(-1, -1);
28 auto k = types->lcid_to_pcid(lcid);
29 return std::make_pair(k.first, k.second);
32 std::pair<int, int> controller_state::legacy_pcid_to_pair(unsigned pcid) throw()
34 if(pcid >= types->number_of_legacy_pcids())
35 return std::make_pair(-1, -1);
36 auto k = types->legacy_pcid_to_pair(pcid);
37 return std::make_pair(k.first, k.second);
41 controller_frame controller_state::get(uint64_t framenum) throw()
43 controller_frame tmp = _input ^ _framehold ^ _autohold;
44 for(auto i : _autofire)
45 if(i.second.eval_at(framenum))
46 tmp.axis2(i.first, tmp.axis2(i.first) ^ 1);
47 if(tasinput_enaged)
48 for(auto i : _tasinput) {
49 if(i.second.mode == 0 && i.second.state)
50 tmp.axis2(i.first, tmp.axis2(i.first) ^ 1);
51 else if(i.second.mode == 1)
52 tmp.axis2(i.first, i.second.state);
54 apply_macro(tmp);
55 return tmp;
58 void controller_state::analog(unsigned port, unsigned controller, unsigned control, short x) throw()
60 _input.axis3(port, controller, control, x);
63 void controller_state::autohold2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw()
65 _autohold.axis3(port, controller, pbid, newstate ? 1 : 0);
66 notify_autohold_update(port, controller, pbid, newstate);
69 bool controller_state::autohold2(unsigned port, unsigned controller, unsigned pbid) throw()
71 return (_autohold.axis3(port, controller, pbid) != 0);
74 void controller_state::autofire2(unsigned port, unsigned controller, unsigned pbid, unsigned duty, unsigned cyclelen)
75 throw()
77 unsigned idx = _input.porttypes().triple_to_index(port, controller, pbid);
78 if(duty) {
79 _autofire[idx].first_frame = movb.get_movie().get_current_frame();
80 _autofire[idx].duty = duty;
81 _autofire[idx].cyclelen = cyclelen;
82 } else
83 _autofire.erase(idx);
86 std::pair<unsigned, unsigned> controller_state::autofire2(unsigned port, unsigned controller, unsigned pbid) throw()
88 unsigned idx = _input.porttypes().triple_to_index(port, controller, pbid);
89 if(!_autofire.count(idx))
90 return std::make_pair(0, 1);
91 else
92 return std::make_pair(_autofire[idx].duty, _autofire[idx].cyclelen);
95 bool controller_state::autofire_info::eval_at(uint64_t frame)
97 if(frame < first_frame) {
98 uint64_t diff = first_frame - frame;
99 frame += ((diff / cyclelen) + 1) * cyclelen;
101 return frame % cyclelen < duty;
104 void controller_state::reset_framehold() throw()
106 _framehold = _framehold.blank_frame();
109 void controller_state::framehold2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw()
111 _framehold.axis3(port, controller, pbid, newstate ? 1 : 0);
114 bool controller_state::framehold2(unsigned port, unsigned controller, unsigned pbid) throw()
116 return (_framehold.axis3(port, controller, pbid) != 0);
119 void controller_state::button2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw()
121 _input.axis3(port, controller, pbid, newstate ? 1 : 0);
124 bool controller_state::button2(unsigned port, unsigned controller, unsigned pbid) throw()
126 return (_input.axis3(port, controller, pbid) != 0);
129 void controller_state::tasinput(unsigned port, unsigned controller, unsigned pbid, int16_t state) throw()
131 unsigned idx = _input.porttypes().triple_to_index(port, controller, pbid);
132 if(!_tasinput.count(idx))
133 _tasinput[idx].mode = 0; //Just to be sure.
134 _tasinput[idx].state = state;
137 int16_t controller_state::tasinput(unsigned port, unsigned controller, unsigned pbid) throw()
139 unsigned idx = _input.porttypes().triple_to_index(port, controller, pbid);
140 return _tasinput.count(idx) ? _tasinput[idx].state : 0;
143 void controller_state::tasinput_enable(bool enabled)
145 tasinput_enaged = enabled;
148 void reread_active_buttons();
150 void controller_state::reread_tasinput_mode(const port_type_set& ptype)
152 unsigned indices = ptype.indices();
153 _tasinput.clear();
154 for(unsigned i = 0; i < indices; i++) {
155 auto t = ptype.index_to_triple(i);
156 if(!t.valid)
157 continue;
158 //See what the heck that is...
159 const port_type& pt = ptype.port_type(t.port);
160 const port_controller_set& pci = *(pt.controller_info);
161 if(pci.controllers.size() <= t.controller)
162 continue;
163 const port_controller& pc = pci.controllers[t.controller];
164 if(pc.buttons.size() <= t.control)
165 continue;
166 const port_controller_button& pcb = pc.buttons[t.control];
167 if(pcb.shadow)
168 continue;
169 if(pcb.type == port_controller_button::TYPE_BUTTON)
170 _tasinput[i].mode = 0;
171 else
172 _tasinput[i].mode = 1;
173 _tasinput[i].state = 0;
177 void controller_state::set_ports(const port_type_set& ptype) throw(std::runtime_error)
179 const port_type_set* oldtype = types;
180 types = &ptype;
181 if(oldtype != types) {
182 _input.set_types(ptype);
183 _autohold.set_types(ptype);
184 _committed.set_types(ptype);
185 _framehold.set_types(ptype);
186 //The old autofire pattern no longer applies.
187 _autofire.clear();
188 reread_tasinput_mode(ptype);
189 _autohold = _autohold.blank_frame();
191 reread_active_buttons();
192 notify_autohold_reconfigure();
195 controller_frame controller_state::get_blank() throw()
197 return _input.blank_frame();
200 controller_frame controller_state::get_committed() throw()
202 return _committed;
205 void controller_state::commit(controller_frame controls) throw()
207 _committed = controls;
210 bool controller_state::is_present(unsigned port, unsigned controller) throw()
212 return _input.is_present(port, controller);
215 void controller_state::erase_macro(const std::string& macro)
218 threads::alock h(macro_lock);
219 if(!all_macros.count(macro))
220 return;
221 auto m = &all_macros[macro];
222 for(auto i = active_macros.begin(); i != active_macros.end(); i++) {
223 if(i->second == m) {
224 active_macros.erase(i);
225 break;
228 all_macros.erase(macro);
229 project_info* p = project_get();
230 if(p) {
231 p->macros.erase(macro);
232 p->flush();
235 load_macros(*this);
238 std::set<std::string> controller_state::enumerate_macro()
240 threads::alock h(macro_lock);
241 std::set<std::string> r;
242 for(auto i : all_macros)
243 r.insert(i.first);
244 return r;
247 controller_macro& controller_state::get_macro(const std::string& macro)
249 threads::alock h(macro_lock);
250 if(!all_macros.count(macro))
251 throw std::runtime_error("No such macro");
252 return all_macros[macro];
255 void controller_state::set_macro(const std::string& macro, const controller_macro& m)
258 threads::alock h(macro_lock);
259 controller_macro* old = NULL;
260 if(all_macros.count(macro))
261 old = &all_macros[macro];
262 all_macros[macro] = m;
263 for(auto i = active_macros.begin(); i != active_macros.end(); i++) {
264 if(i->second == old) {
265 i->second = &all_macros[macro];
266 break;
269 project_info* p = project_get();
270 if(p) {
271 p->macros[macro] = all_macros[macro].serialize();
272 p->flush();
275 load_macros(*this);
278 void controller_state::apply_macro(controller_frame& f)
280 threads::alock h(macro_lock);
281 for(auto i : active_macros)
282 i.second->write(f, i.first);
285 void controller_state::advance_macros()
287 threads::alock h(macro_lock);
288 for(auto& i : active_macros)
289 i.first++;
292 std::map<std::string, uint64_t> controller_state::get_macro_frames()
294 threads::alock h(macro_lock);
295 std::map<std::string, uint64_t> r;
296 for(auto i : active_macros) {
297 for(auto& j : all_macros)
298 if(i.second == &j.second) {
299 r[j.first] = i.first;
302 return r;
305 void controller_state::set_macro_frames(const std::map<std::string, uint64_t>& f)
307 threads::alock h(macro_lock);
308 std::list<std::pair<uint64_t, controller_macro*>> new_active_macros;
309 for(auto i : f)
310 if(all_macros.count(i.first))
311 new_active_macros.push_back(std::make_pair(i.second, &all_macros[i.first]));
312 else
313 messages << "Warning: Can't find defintion for '" << i.first << "'" << std::endl;
314 std::swap(active_macros, new_active_macros);
317 void controller_state::rename_macro(const std::string& old, const std::string& newn)
320 threads::alock h(macro_lock);
321 if(!all_macros.count(old))
322 throw std::runtime_error("Old macro doesn't exist");
323 if(all_macros.count(newn))
324 throw std::runtime_error("Target name already exists");
325 if(old == newn)
326 return;
327 all_macros[newn] = all_macros[old];
328 controller_macro* _old = &all_macros[old];
329 all_macros.erase(old);
330 for(auto i = active_macros.begin(); i != active_macros.end(); i++) {
331 if(i->second == _old) {
332 i->second = &all_macros[newn];
333 break;
336 project_info* p = project_get();
337 if(p) {
338 p->macros[newn] = p->macros[old];
339 p->macros.erase(old);
342 load_macros(*this);
345 void controller_state::do_macro(const std::string& a, int mode) {
347 threads::alock h(macro_lock);
348 if(!all_macros.count(a)) {
349 if(mode & 1) messages << "No such macro '" << a << "'" << std::endl;
350 return;
352 controller_macro* m = &all_macros[a];
353 for(auto i = active_macros.begin(); i != active_macros.end(); i++) {
354 if(i->second == m) {
355 if(mode & 2) active_macros.erase(i);
356 goto end;
359 if(mode & 4) active_macros.push_back(std::make_pair(0, m));
361 end:
362 update_movie_state();
363 notify_status_update();
366 std::set<std::string> controller_state::active_macro_set()
368 threads::alock h(macro_lock);
369 std::set<std::string> r;
370 for(auto i : active_macros) {
371 for(auto& j : all_macros)
372 if(i.second == &j.second) {
373 r.insert(j.first);
376 return r;