Allow on_input to veto/force system controls (including reset line)

This commit is contained in:
Ilari Liusvaara 2013-03-13 00:36:44 +02:00
parent b53fb1fe75
commit 00f5754ef7
7 changed files with 38 additions and 9 deletions

View file

@ -94,6 +94,7 @@ struct core_core_params
port_type** port_types;
framebuffer_raw& (*draw_cover)();
std::string (*get_core_shortname)();
void (*pre_emulate_frame)(controller_frame& cf);
};
struct core_region
@ -165,6 +166,7 @@ struct core_core
framebuffer_raw& draw_cover();
port_type** get_port_types() { return port_types; }
std::string get_core_shortname();
void pre_emulate_frame(controller_frame& cf);
static std::set<core_core*> all_cores();
static void install_all_handlers();
static void uninstall_all_handlers();
@ -194,6 +196,7 @@ private:
port_type** port_types;
framebuffer_raw& (*_draw_cover)();
std::string (*_get_core_shortname)();
void (*_pre_emulate_frame)(controller_frame& cf);
bool hidden;
};
@ -252,6 +255,7 @@ public:
void request_reset(long delay, bool hard) { core->request_reset(delay, hard); }
framebuffer_raw& draw_cover() { return core->draw_cover(); }
bool is_hidden() { return core->is_hidden(); }
void pre_emulate_frame(controller_frame& cf) { return core->pre_emulate_frame(cf); }
private:
core_type(const core_type&);
core_type& operator=(const core_type&);

View file

@ -187,6 +187,7 @@ controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_allo
information_dispatch::do_status_update();
platform::flush_command_queue();
controller_frame tmp = controls.commit(movb.get_movie().get_current_frame());
our_rom->rtype->pre_emulate_frame(tmp); //Preset controls, the lua will override if needed.
lua_callback_do_input(tmp, subframe);
return tmp;
}

View file

@ -747,13 +747,13 @@ namespace
if(!internal_rom)
return;
bool was_delay_reset = false;
int16_t reset = ecore_callbacks->set_input(0, 0, 1, (do_reset_flag >= 0) ? 1 : 0);
int16_t reset = ecore_callbacks->get_input(0, 0, 1);
int16_t hreset = 0;
if(support_hreset)
hreset = ecore_callbacks->set_input(0, 0, 4, do_hreset_flag ? 1 : 0);
hreset = ecore_callbacks->get_input(0, 0, 4);
if(reset) {
long hi = ecore_callbacks->set_input(0, 0, 2, do_reset_flag / 10000);
long lo = ecore_callbacks->set_input(0, 0, 3, do_reset_flag % 10000);
long hi = ecore_callbacks->get_input(0, 0, 2);
long lo = ecore_callbacks->get_input(0, 0, 3);
long delay = 10000 * hi + lo;
if(delay > 0) {
was_delay_reset = true;
@ -861,6 +861,20 @@ again2:
#else
return (stringfmt() << "bsnes" << BSNES_VERSION << "a").str();
#endif
},
//Pre-emulate frame.
[](controller_frame& cf) -> void
{
cf.axis3(0, 0, 1, (do_reset_flag >= 0) ? 1 : 0);
if(support_hreset)
cf.axis3(0, 0, 4, do_hreset_flag ? 1 : 0);
if(do_reset_flag >= 0) {
cf.axis3(0, 0, 2, do_reset_flag / 10000);
cf.axis3(0, 0, 3, do_reset_flag % 10000);
} else {
cf.axis3(0, 0, 2, 0);
cf.axis3(0, 0, 3, 0);
}
}
};

View file

@ -381,7 +381,7 @@ namespace
[]() -> void {
if(!internal_rom)
return;
int16_t reset = ecore_callbacks->set_input(0, 0, 1, do_reset_flag ? 1 : 0);
int16_t reset = ecore_callbacks->get_input(0, 0, 1);
if(reset) {
instance->reset();
messages << "GB(C) reset" << std::endl;
@ -451,6 +451,10 @@ namespace
},
//short identifier.
[]() -> std::string { return "gambatte"+gambatte::GB::version(); },
//Pre-emulate frame.
[](controller_frame& cf) -> void {
cf.axis3(0, 0, 1, do_reset_flag ? 1 : 0);
}
};
core_core gambatte_core(_gambatte_core);

View file

@ -218,9 +218,9 @@ namespace sky
gsfx(sound_beep);
}
//Distance gauge.
uint32_t res = s.curlevel.apparent_length() / 88;
uint32_t res = s.curlevel.apparent_length() / (29 * FB_SCALE + 1);
size_t tmp = (s.p.lpos - 3 * 65536) / res;
for(unsigned i = s.distind; i < tmp && i < 88; i++)
for(unsigned i = s.distind; i < tmp && i < (29 * FB_SCALE + 1); i++)
draw_distance_column(i, dashpalette[4]);
s.distind = tmp;
s.beep_phase = timermod;

View file

@ -348,7 +348,8 @@ namespace sky
static framebuffer_raw x(cover_fbinfo);
return x;
},
[]() -> std::string { return "sky"; }
[]() -> std::string { return "sky"; },
[](controller_frame& cf) -> void {}
};
struct core_core sky_core(sky_core_params);

View file

@ -285,7 +285,6 @@ std::set<std::string> core_type::srams()
return _srams();
}
core_sysregion::core_sysregion(const std::string& _name, core_type& _type, core_region& _region)
: name(_name), type(_type), region(_region)
{
@ -354,6 +353,7 @@ core_core::core_core(core_core_params& params)
port_types = params.port_types;
_draw_cover = params.draw_cover;
_get_core_shortname = params.get_core_shortname;
_pre_emulate_frame = params.pre_emulate_frame;
hidden = false;
all_cores_set().insert(this);
if(install_handlers_automatically)
@ -501,6 +501,11 @@ framebuffer_raw& core_core::draw_cover()
return _draw_cover();
}
void core_core::pre_emulate_frame(controller_frame& cf)
{
_pre_emulate_frame(cf);
}
emucore_callbacks::~emucore_callbacks() throw()
{
}