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"
11 void update_movie_state();
15 port_type_set dummytypes
;
18 controller_state::controller_state() throw()
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);
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
);
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
)
77 unsigned idx
= _input
.porttypes().triple_to_index(port
, controller
, pbid
);
79 _autofire
[idx
].first_frame
= movb
.get_movie().get_current_frame();
80 _autofire
[idx
].duty
= duty
;
81 _autofire
[idx
].cyclelen
= cyclelen
;
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);
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();
154 for(unsigned i
= 0; i
< indices
; i
++) {
155 auto t
= ptype
.index_to_triple(i
);
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
)
163 const port_controller
& pc
= pci
.controllers
[t
.controller
];
164 if(pc
.buttons
.size() <= t
.control
)
166 const port_controller_button
& pcb
= pc
.buttons
[t
.control
];
169 if(pcb
.type
== port_controller_button::TYPE_BUTTON
)
170 _tasinput
[i
].mode
= 0;
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
;
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.
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()
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
))
221 auto m
= &all_macros
[macro
];
222 for(auto i
= active_macros
.begin(); i
!= active_macros
.end(); i
++) {
224 active_macros
.erase(i
);
228 all_macros
.erase(macro
);
229 project_info
* p
= project_get();
231 p
->macros
.erase(macro
);
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
)
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
];
269 project_info
* p
= project_get();
271 p
->macros
[macro
] = all_macros
[macro
].serialize();
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
)
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
;
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
;
310 if(all_macros
.count(i
.first
))
311 new_active_macros
.push_back(std::make_pair(i
.second
, &all_macros
[i
.first
]));
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");
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
];
336 project_info
* p
= project_get();
338 p
->macros
[newn
] = p
->macros
[old
];
339 p
->macros
.erase(old
);
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
;
352 controller_macro
* m
= &all_macros
[a
];
353 for(auto i
= active_macros
.begin(); i
!= active_macros
.end(); i
++) {
355 if(mode
& 2) active_macros
.erase(i
);
359 if(mode
& 4) active_macros
.push_back(std::make_pair(0, m
));
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
) {