2012-01-09 21:55:55 +02:00
|
|
|
#include "core/controllerframe.hpp"
|
2012-01-11 23:07:31 +02:00
|
|
|
#include "core/dispatch.hpp"
|
|
|
|
#include "core/misc.hpp"
|
2013-03-14 00:15:43 +02:00
|
|
|
#include "core/moviedata.hpp"
|
2013-01-06 23:06:08 +02:00
|
|
|
#include "interface/romtype.hpp"
|
2012-01-09 21:55:55 +02:00
|
|
|
|
2012-01-11 17:31:25 +02:00
|
|
|
#include <cstdio>
|
2012-01-10 01:11:53 +02:00
|
|
|
#include <iostream>
|
|
|
|
|
2012-01-09 21:55:55 +02:00
|
|
|
namespace
|
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
port_type_set dummytypes;
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
controller_state::controller_state() throw()
|
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
types = &dummytypes;
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 20:06:40 +03:00
|
|
|
std::pair<int,int> controller_state::lcid_to_pcid(unsigned lcid) throw()
|
2012-01-11 23:07:31 +02:00
|
|
|
{
|
2012-10-17 09:32:51 +03:00
|
|
|
if(lcid >= types->number_of_controllers())
|
|
|
|
return std::make_pair(-1, -1);
|
|
|
|
auto k = types->lcid_to_pcid(lcid);
|
|
|
|
return std::make_pair(k.first, k.second);
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
2012-10-19 19:53:15 +03:00
|
|
|
std::pair<int, int> controller_state::legacy_pcid_to_pair(unsigned pcid) throw()
|
|
|
|
{
|
|
|
|
if(pcid >= types->number_of_legacy_pcids())
|
|
|
|
return std::make_pair(-1, -1);
|
|
|
|
auto k = types->legacy_pcid_to_pair(pcid);
|
|
|
|
return std::make_pair(k.first, k.second);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-01-11 23:07:31 +02:00
|
|
|
controller_frame controller_state::get(uint64_t framenum) throw()
|
|
|
|
{
|
2013-03-14 00:15:43 +02:00
|
|
|
controller_frame tmp = _input ^ _framehold ^ _autohold;
|
|
|
|
for(auto i : _autofire)
|
|
|
|
if(i.second.eval_at(framenum))
|
|
|
|
tmp.axis2(i.first, tmp.axis2(i.first) ^ 1);
|
|
|
|
return tmp;
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
2013-01-04 20:41:11 +02:00
|
|
|
void controller_state::analog(unsigned port, unsigned controller, unsigned control, short x) throw()
|
2012-01-11 23:07:31 +02:00
|
|
|
{
|
2013-01-04 20:41:11 +02:00
|
|
|
_input.axis3(port, controller, control, x);
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 20:06:40 +03:00
|
|
|
void controller_state::autohold2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw()
|
2012-01-11 23:07:31 +02:00
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
_autohold.axis3(port, controller, pbid, newstate ? 1 : 0);
|
|
|
|
information_dispatch::do_autohold_update(port, controller, pbid, newstate);
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 20:06:40 +03:00
|
|
|
bool controller_state::autohold2(unsigned port, unsigned controller, unsigned pbid) throw()
|
2012-01-11 23:07:31 +02:00
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
return (_autohold.axis3(port, controller, pbid) != 0);
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
2013-03-14 00:15:43 +02:00
|
|
|
void controller_state::autofire2(unsigned port, unsigned controller, unsigned pbid, unsigned duty, unsigned cyclelen)
|
|
|
|
throw()
|
|
|
|
{
|
|
|
|
unsigned idx = _input.porttypes().triple_to_index(port, controller, pbid);
|
|
|
|
if(duty) {
|
|
|
|
_autofire[idx].first_frame = movb.get_movie().get_current_frame();
|
|
|
|
_autofire[idx].duty = duty;
|
|
|
|
_autofire[idx].cyclelen = cyclelen;
|
|
|
|
} else
|
|
|
|
_autofire.erase(idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<unsigned, unsigned> controller_state::autofire2(unsigned port, unsigned controller, unsigned pbid) throw()
|
|
|
|
{
|
|
|
|
unsigned idx = _input.porttypes().triple_to_index(port, controller, pbid);
|
|
|
|
if(!_autofire.count(idx))
|
|
|
|
return std::make_pair(0, 1);
|
|
|
|
else
|
|
|
|
return std::make_pair(_autofire[idx].duty, _autofire[idx].cyclelen);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool controller_state::autofire_info::eval_at(uint64_t frame)
|
|
|
|
{
|
|
|
|
if(frame < first_frame) {
|
|
|
|
uint64_t diff = first_frame - frame;
|
|
|
|
frame += ((diff / cyclelen) + 1) * cyclelen;
|
|
|
|
}
|
|
|
|
uint64_t diff2 = frame - first_frame;
|
|
|
|
return frame % cyclelen < duty;
|
|
|
|
}
|
|
|
|
|
2012-05-11 19:37:06 +03:00
|
|
|
void controller_state::reset_framehold() throw()
|
|
|
|
{
|
|
|
|
_framehold = _framehold.blank_frame();
|
|
|
|
}
|
|
|
|
|
2012-10-11 20:06:40 +03:00
|
|
|
void controller_state::framehold2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw()
|
2012-05-11 19:37:06 +03:00
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
_framehold.axis3(port, controller, pbid, newstate ? 1 : 0);
|
2012-05-11 19:37:06 +03:00
|
|
|
}
|
|
|
|
|
2012-10-11 20:06:40 +03:00
|
|
|
bool controller_state::framehold2(unsigned port, unsigned controller, unsigned pbid) throw()
|
2012-05-11 19:37:06 +03:00
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
return (_framehold.axis3(port, controller, pbid) != 0);
|
2012-05-11 19:37:06 +03:00
|
|
|
}
|
|
|
|
|
2012-10-11 20:06:40 +03:00
|
|
|
void controller_state::button2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw()
|
2012-01-11 23:07:31 +02:00
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
_input.axis3(port, controller, pbid, newstate ? 1 : 0);
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 20:06:40 +03:00
|
|
|
bool controller_state::button2(unsigned port, unsigned controller, unsigned pbid) throw()
|
2012-01-11 23:07:31 +02:00
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
return (_input.axis3(port, controller, pbid) != 0);
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
|
|
|
|
2013-01-04 20:41:11 +02:00
|
|
|
void reread_active_buttons();
|
2012-01-11 23:07:31 +02:00
|
|
|
|
2013-01-05 09:19:09 +02:00
|
|
|
void controller_state::set_ports(const port_type_set& ptype) throw(std::runtime_error)
|
2012-01-11 23:07:31 +02:00
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
const port_type_set* oldtype = types;
|
|
|
|
types = &ptype;
|
|
|
|
if(oldtype != types) {
|
|
|
|
_input.set_types(ptype);
|
|
|
|
_autohold.set_types(ptype);
|
|
|
|
_committed.set_types(ptype);
|
|
|
|
_framehold.set_types(ptype);
|
2012-01-11 23:07:31 +02:00
|
|
|
//The old autofire pattern no longer applies.
|
|
|
|
_autofire.clear();
|
2013-01-04 20:41:11 +02:00
|
|
|
_autohold = _autohold.blank_frame();
|
2012-01-11 23:07:31 +02:00
|
|
|
}
|
2013-01-04 20:41:11 +02:00
|
|
|
reread_active_buttons();
|
2012-01-11 23:07:31 +02:00
|
|
|
information_dispatch::do_autohold_reconfigure();
|
|
|
|
}
|
|
|
|
|
|
|
|
controller_frame controller_state::get_blank() throw()
|
|
|
|
{
|
|
|
|
return _input.blank_frame();
|
|
|
|
}
|
|
|
|
|
2012-01-13 06:51:47 +02:00
|
|
|
controller_frame controller_state::commit(uint64_t framenum) throw()
|
|
|
|
{
|
|
|
|
controller_frame f = get(framenum);
|
|
|
|
_committed = f;
|
|
|
|
return _committed;
|
|
|
|
}
|
|
|
|
|
|
|
|
controller_frame controller_state::get_committed() throw()
|
|
|
|
{
|
|
|
|
return _committed;
|
|
|
|
}
|
|
|
|
|
|
|
|
controller_frame controller_state::commit(controller_frame controls) throw()
|
|
|
|
{
|
|
|
|
_committed = controls;
|
|
|
|
return _committed;
|
|
|
|
}
|
2012-01-17 23:48:13 +02:00
|
|
|
|
2012-10-11 20:06:40 +03:00
|
|
|
bool controller_state::is_present(unsigned port, unsigned controller) throw()
|
2012-07-08 12:57:22 +03:00
|
|
|
{
|
2012-10-11 20:06:40 +03:00
|
|
|
return _input.is_present(port, controller);
|
2012-07-08 12:57:22 +03:00
|
|
|
}
|