Concentrate inter-component communication to one place

This commit is contained in:
Ilari Liusvaara 2011-11-08 21:22:30 +02:00
parent ed2d4e846c
commit d04999ae89
24 changed files with 167 additions and 947 deletions

View file

@ -1,254 +0,0 @@
#ifndef _avsnoop__hpp__included__
#define _avsnoop__hpp__included__
#include "render.hpp"
#include <list>
#include <string>
#include <set>
#include <stdexcept>
/**
* Video data region is NTSC.
*/
#define SNOOP_REGION_NTSC 0
/**
* Video data region is PAL.
*/
#define SNOOP_REGION_PAL 1
/**
* Information about run.
*/
struct gameinfo_struct
{
public:
/**
* Construct game info.
*/
gameinfo_struct() throw(std::bad_alloc);
/**
* Game name.
*/
std::string gamename;
/**
* Run length in seconds.
*/
double length;
/**
* Rerecord count (base 10 ASCII)
*/
std::string rerecords;
/**
* Authors. The first components are real names, the second components are nicknames. Either (but not both) may be
* blank.
*/
std::vector<std::pair<std::string, std::string>> authors;
/**
* Format human-redable representation of the length.
*
* Parameter digits: Number of sub-second digits to use.
* Returns: The time formated.
* Throws std::bad_alloc: Not enough memory.
*/
std::string get_readable_time(unsigned digits) const throw(std::bad_alloc);
/**
* Get number of authors.
*
* Returns: Number of authors.
*/
size_t get_author_count() const throw();
/**
* Get short name of author (nickname if present, otherwise full name).
*
* Parameter idx: Index of author (0-based).
* Returns: The short name.
* Throws std::bad_alloc: Not enough memory.
*/
std::string get_author_short(size_t idx) const throw(std::bad_alloc);
/**
* Get rerecord count as a number. If rerecord count is too high, returns the maximum representatible count.
*
* Returns: The rerecord count.
*/
uint64_t get_rerecords() const throw();
};
/**
* A/V snooper. A/V snoopers allow code to snoop on audio samples and video frames, usually for purpose of dumping
* them to video file.
*/
class av_snooper
{
public:
/**
* Create new A/V snooper, registering it for receiving callbacks.
*
* Parameter name: Name of the dumper.
*
* Throws std::bad_alloc: Not enough memory.
*/
av_snooper(const std::string& name) throw(std::bad_alloc);
/**
* Destroy A/V snooper, deregistering it. This will not call end() method.
*/
~av_snooper() throw();
/**
* Dump a frame.
*
* Parameter _frame: The frame to dump.
* Parameter fps_n: Current fps numerator.
* Parameter fps_d: Current fps denomerator.
* Parameter raw: Raw frame data from bsnes.
* Parameter hires: True if bsnes signals hires mode, false otherwise.
* Parameter interlaced: True if bsnes signals interlaced mode, false otherwise.
* Parameter overscan: True if bsnes signals overscan mode, false otherwise.
* Parameter region: The region video data is for.
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Error dumping frame.
*/
virtual void frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d, const uint32_t* raw, bool hires,
bool interlaced, bool overscan, unsigned region) throw(std::bad_alloc, std::runtime_error);
/**
* Call frame() on all known A/V snoopers.
*
* Parameter _frame: The frame to dump.
* Parameter fps_n: Current fps numerator.
* Parameter fps_d: Current fps denomerator.
* Parameter raw: Raw frame data from bsnes.
* Parameter hires: True if bsnes signals hires mode, false otherwise.
* Parameter interlaced: True if bsnes signals interlaced mode, false otherwise.
* Parameter overscan: True if bsnes signals overscan mode, false otherwise.
* Parameter region: The region video data is for.
* throws std::bad_alloc: Not enough memory.
*/
static void _frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d, const uint32_t* raw, bool hires,
bool interlaced, bool overscan, unsigned region) throw(std::bad_alloc);
/**
* Dump a sample.
*
* parameter l: Left channel sample.
* parameter r: Right channel sample.
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Error dumping sample.
*/
virtual void sample(short l, short r) throw(std::bad_alloc, std::runtime_error);
/**
* Call sample() on all known A/V snoopers.
*
* parameter l: Left channel sample.
* parameter r: Right channel sample.
* throws std::bad_alloc: Not enough memory.
*/
static void _sample(short l, short r) throw(std::bad_alloc);
/**
* End dump.
*
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Error dumping sample.
*/
virtual void end() throw(std::bad_alloc, std::runtime_error);
/**
* Call end() on all known A/V snoopers.
*
* throws std::bad_alloc: Not enough memory.
*/
static void _end() throw(std::bad_alloc);
/**
* Set sound sampling rate.
*
* parameter rate_n: Numerator of sampling rate.
* parameter rate_d: Denomerator of sampling rate.
*/
virtual void sound_rate(uint32_t rate_n, uint32_t rate_d) throw(std::bad_alloc, std::runtime_error);
/**
* Call set_sound_rate() on all known A/V snoopers (and record the rate).
*
* parameter rate_n: Numerator of sampling rate.
* parameter rate_d: Denomerator of sampling rate.
*/
static void _sound_rate(uint32_t rate_n, uint32_t rate_d);
/**
* Get the sound rate most recently set by _set_sound_rate().
*
* Returns: The first component is numerator of the sampling rate, the second component is the denomerator.
*/
std::pair<uint32_t, uint32_t> get_sound_rate() throw();
/**
* Notify game information.
*
* parameter gi: The information. Not guaranteed to remain stable after the call.
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Error recording this info.
*/
virtual void gameinfo(const struct gameinfo_struct& gi) throw(std::bad_alloc, std::runtime_error);
/**
* Call gameinfo() on all known A/V snoopers. Also records the gameinfo.
*
* parameter gi: The information. Not guaranteed to remain stable after the call.
* throws std::bad_alloc Not enough memory.
*/
static void _gameinfo(const struct gameinfo_struct& gi) throw(std::bad_alloc);
/**
* Get the last recorded game information.
*
* Returns: The last recorded gameinfo.
*/
const struct gameinfo_struct& get_gameinfo() throw(std::bad_alloc);
/**
* Is there at least one known A/V snooper?
*
* returns: True if there is at least one known A/V snooper, false if there are none.
*/
static bool dump_in_progress() throw();
/**
* Get the names of the active dumpers.
*/
static const std::set<std::string>& active_dumpers();
/**
* Notifier for dumps starting/ending.
*/
class dump_notification
{
public:
/**
* Register dump notifier.
*
* Throws std::bad_alloc: Not enough memory.
*/
dump_notification() throw(std::bad_alloc);
/**
* Destructor. Deregister notifier.
*/
virtual ~dump_notification() throw();
/**
* Called on new dump starting.
*
* Parameter type: The type of new dumper.
*/
virtual void dump_starting(const std::string& type) throw();
/**
* Called on dump ending.
*
* Parameter type: The type of dumper going away.
*/
virtual void dump_ending(const std::string& type) throw();
};
private:
std::string s_name;
};
#endif

View file

@ -278,45 +278,6 @@ public:
* Get set of all keys (including subkeys).
*/
static std::set<std::string> get_keys() throw(std::bad_alloc);
/**
* Keyboard key listener.
*/
struct key_listener
{
/**
* Invoked on key.
*
* parameter modifiers: The modifiers pressed during the transition.
* parameter keygroup: The key group key is in.
* parameter subkey: Key index within the key group (identifies individual key).
* parameter polarity: True if key is going down, false if going up.
* parameter name: The name of the individual key.
*/
virtual void key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned subkey,
bool polarity, const std::string& name) = 0;
};
/**
* Add key listener.
*
* parameter l: The new key listener.
* throw std::bad_alloc: Not enough memory.
*/
void add_key_listener(key_listener& l) throw(std::bad_alloc);
/**
* Remove key listener.
*
* parameter l: The key listener to remove.
* throw std::bad_alloc: Not enough memory.
*/
void remove_key_listener(key_listener& l) throw(std::bad_alloc);
/**
* Set exclusive key listener.
*
* When exclusive key listener is active, all keys are sent to it and not to normal key listeners.
*
* parameter l: The new exclusive key listener or NULL if exclusive key listener is to be removed.
*/
static void set_exclusive_key_listener(key_listener* l) throw();
/**
* Key group parameters.
@ -358,9 +319,7 @@ private:
double compensate(short value);
double compensate2(double value);
void run_listeners(const modifier_set& modifiers, unsigned subkey, bool polarity, bool really, double x);
std::list<key_listener*> listeners;
std::string keyname;
static key_listener* exclusive;
};
/**

View file

@ -15,97 +15,6 @@
class window;
/**
* Some backnotifications.
*/
class window_callback
{
public:
/**
* Register a callback
*/
window_callback() throw();
/**
* Unregister a callback.
*/
virtual ~window_callback() throw();
/**
* Called when user tries to close the window.
*/
virtual void on_close() throw();
/**
* Called when user clicks on the screen.
*/
virtual void on_click(int32_t x, int32_t y, uint32_t buttonmask) throw();
/**
* Called when sound mute/unmute gets (possibly) changed.
*/
virtual void on_sound_unmute(bool unmuted) throw();
/**
* Called when sound device gets (possibly) changed.
*/
virtual void on_sound_change(const std::string& dev) throw();
/**
* Called when mode gets (possibly) changed.
*/
virtual void on_mode_change(bool readonly) throw();
/**
* Called when autohold (possibly) changes.
*/
virtual void on_autohold_update(unsigned pid, unsigned ctrlnum, bool newstate);
/**
* Called when controllers (possibly) change.
*/
virtual void on_autohold_reconfigure();
/**
* Called when setting is changed.
*/
virtual void on_setting_change(const std::string& setting, const std::string& value);
/**
* Called when setting is cleared.
*/
virtual void on_setting_clear(const std::string& setting);
/**
* Do try to close the window.
*/
static void do_close() throw();
/**
* Do click on the screen.
*/
static void do_click(int32_t x, int32_t y, uint32_t buttonmask) throw();
/**
* Do on_sound_unmute.
*/
static void do_sound_unmute(bool unmuted) throw();
/**
* Do on_sound_change
*/
static void do_sound_change(const std::string& dev) throw();
/**
* Do on_mode_change
*/
static void do_mode_change(bool readonly) throw();
/**
* Do on_autohold_update
*/
static void do_autohold_update(unsigned pid, unsigned ctrlnum, bool newstate);
/**
* Do on_autohold_reconfigure
*/
static void do_autohold_reconfigure();
/**
* Do on_setting_change
*/
static void do_setting_change(const std::string& setting, const std::string& value);
/**
* Do on_setting_clear
*/
static void do_setting_clear(const std::string& setting);
private:
window_callback(window_callback&);
window_callback& operator=(window_callback&);
};
/**
* Sound/Graphics init/quit functions. Sound init is called after graphics init, and vice versa for quit.
*
@ -164,18 +73,6 @@ public:
*/
static std::map<std::string, std::string>& get_emustatus() throw();
/**
* Set window main screen compensation parameters. This is used for mouse click reporting.
*
* Implemented by the generic window code.
*
* parameter xoffset: X coordinate of origin.
* parameter yoffset: Y coordinate of origin.
* parameter hscl: Horizontal scaling factor.
* parameter vscl: Vertical scaling factor.
*/
static void set_window_compensation(uint32_t xoffset, uint32_t yoffset, uint32_t hscl, uint32_t vscl);
/**
* Message buffer.
*
@ -323,16 +220,6 @@ public:
*/
static void play_audio_sample(uint16_t left, uint16_t right) throw();
/**
* Set sound sampling rate.
*
* Needs to be implemented by the sound plugin.
*
* parameter rate_n: Numerator of sampling rate.
* parameter rate_d: Denomerator of sampling rate.
*/
static void set_sound_rate(uint32_t rate_n, uint32_t rate_d);
/**
* Has the sound system been successfully initialized?
*

View file

@ -1,7 +1,7 @@
#ifndef _wxwidgets_settingseditor__hpp__included__
#define _wxwidgets_settingseditor__hpp__included__
#include "core/window.hpp"
#include "core/dispatch.hpp"
#include <vector>
#include <string>
@ -29,7 +29,7 @@ private:
class wx_settings_editor;
class wx_settings_editor_listener : public window_callback
class wx_settings_editor_listener : public information_dispatch
{
public:
wx_settings_editor_listener(wx_settings_editor* _editor);

View file

@ -1,8 +1,8 @@
#include "cscd.hpp"
#include "sox.hpp"
#include "core/avsnoop.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/lua.hpp"
#include "core/misc.hpp"
#include "core/settings.hpp"
@ -30,11 +30,11 @@ namespace
numeric_setting drb("avi-right-border", 0, 8191, 0);
numeric_setting max_frames_per_segment("avi-maxframes", 0, 999999999, 0);
class avi_avsnoop : public av_snooper
class avi_avsnoop : public information_dispatch
{
public:
avi_avsnoop(const std::string& prefix, struct avi_info parameters) throw(std::bad_alloc)
: av_snooper("AVI")
: information_dispatch("dump-avi-cscd")
{
_parameters = parameters;
avi_cscd_dumper::global_parameters gp;
@ -53,7 +53,7 @@ namespace
sp.deflate_level = parameters.compression_level;
sp.max_segment_frames = parameters.max_frames_per_segment;
vid_dumper = new avi_cscd_dumper(prefix, gp, sp);
soundrate = av_snooper::get_sound_rate();
soundrate = get_sound_rate();
audio_record_rate = parameters.audio_sampling_rate;
soxdumper = new sox_dumper(prefix + ".sox", static_cast<double>(soundrate.first) /
soundrate.second, 2);
@ -67,8 +67,7 @@ namespace
delete soxdumper;
}
void frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d, const uint32_t* raw, bool hires,
bool interlaced, bool overscan, unsigned region) throw(std::bad_alloc, std::runtime_error)
void on_frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d)
{
uint32_t hscl = 1;
uint32_t vscl = 1;
@ -114,7 +113,7 @@ namespace
vid_dumper->wait_frame_processing();
}
void sample(short l, short r) throw(std::bad_alloc, std::runtime_error)
void on_sample(short l, short r)
{
dcounter += soundrate.first;
while(dcounter < soundrate.second * audio_record_rate + soundrate.first) {
@ -127,11 +126,16 @@ namespace
soxdumper->sample(l, r);
}
void end() throw(std::bad_alloc, std::runtime_error)
void on_dump_end()
{
vid_dumper->end();
soxdumper->close();
}
bool get_dumper_flag() throw()
{
return true;
}
private:
avi_cscd_dumper* vid_dumper;
sox_dumper* soxdumper;
@ -190,7 +194,7 @@ namespace
if(!vid_dumper)
throw std::runtime_error("No AVI(CSCD) video dump in progress");
try {
vid_dumper->end();
vid_dumper->on_dump_end();
messages << "AVI(CSCD) Dump finished" << std::endl;
} catch(std::bad_alloc& e) {
throw;

View file

@ -1,256 +0,0 @@
#include "core/avsnoop.hpp"
#include "core/globalwrap.hpp"
#include "core/misc.hpp"
#include <sstream>
#include <iomanip>
#include <cmath>
gameinfo_struct::gameinfo_struct() throw(std::bad_alloc)
{
length = 0;
rerecords = "0";
}
std::string gameinfo_struct::get_readable_time(unsigned digits) const throw(std::bad_alloc)
{
double bias = 0.5 * pow(10, -static_cast<int>(digits));
double len = length + bias;
std::ostringstream str;
if(length >= 3600) {
double hours = floor(len / 3600);
str << hours << ":";
len -= hours * 3600;
}
double minutes = floor(len / 60);
len -= minutes * 60;
double seconds = floor(len);
len -= seconds;
str << std::setw(2) << std::setfill('0') << minutes << ":" << seconds;
if(digits > 0)
str << ".";
while(digits > 0) {
len = 10 * len;
str << '0' + static_cast<int>(len);
len -= floor(len);
digits--;
}
}
size_t gameinfo_struct::get_author_count() const throw()
{
return authors.size();
}
std::string gameinfo_struct::get_author_short(size_t idx) const throw(std::bad_alloc)
{
if(idx >= authors.size())
return "";
const std::pair<std::string, std::string>& x = authors[idx];
if(x.second != "")
return x.second;
else
return x.first;
}
uint64_t gameinfo_struct::get_rerecords() const throw()
{
uint64_t v = 0;
uint64_t max = 0xFFFFFFFFFFFFFFFFULL;
for(size_t i = 0; i < rerecords.length(); i++) {
if(v < max / 10)
//No risk of overflow.
v = v * 10 + static_cast<unsigned>(rerecords[i] - '0');
else if(v == max / 10) {
//THis may overflow.
v = v * 10;
if(v + static_cast<unsigned>(rerecords[i] - '0') < v)
return max;
v = v + static_cast<unsigned>(rerecords[i] - '0');
} else
//Definite overflow.
return max;
}
return v;
}
namespace
{
globalwrap<std::list<av_snooper*>> snoopers;
globalwrap<std::list<av_snooper::dump_notification*>> notifiers;
uint32_t srate_n = 32000;
uint32_t srate_d = 1;
gameinfo_struct sgi;
globalwrap<std::set<std::string>> sactive_dumpers;
}
av_snooper::av_snooper(const std::string& name) throw(std::bad_alloc)
{
snoopers().push_back(this);
for(auto i : notifiers())
i->dump_starting(name);
sactive_dumpers().insert(s_name = name);
}
av_snooper::~av_snooper() throw()
{
sactive_dumpers().erase(s_name);
for(auto i = snoopers().begin(); i != snoopers().end(); i++)
if(*i == this) {
snoopers().erase(i);
break;
}
for(auto i : notifiers())
i->dump_ending(s_name);
}
void av_snooper::frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d, const uint32_t* raw, bool hires,
bool interlaced, bool overscan, unsigned region) throw(std::bad_alloc, std::runtime_error)
{
//Nothing.
}
void av_snooper::_frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d, const uint32_t* raw, bool hires,
bool interlaced, bool overscan, unsigned region) throw(std::bad_alloc)
{
for(auto i : snoopers())
try {
i->frame(_frame, fps_n, fps_d, raw, hires, interlaced, overscan, region);
} catch(std::bad_alloc& e) {
throw;
} catch(std::exception& e) {
try {
messages << "Error dumping frame: " << e.what() << std::endl;
} catch(...) {
}
}
}
void av_snooper::sample(short l, short r) throw(std::bad_alloc, std::runtime_error)
{
//Nothing.
}
void av_snooper::_sample(short l, short r) throw(std::bad_alloc)
{
for(auto i : snoopers())
try {
i->sample(l, r);
} catch(std::bad_alloc& e) {
throw;
} catch(std::exception& e) {
try {
messages << "Error dumping sample: " << e.what() << std::endl;
} catch(...) {
}
}
}
void av_snooper::end() throw(std::bad_alloc, std::runtime_error)
{
//Nothing.
}
void av_snooper::_end() throw(std::bad_alloc)
{
for(auto i : snoopers())
try {
i->end();
} catch(std::bad_alloc& e) {
throw;
} catch(std::exception& e) {
try {
messages << "Error ending dump: " << e.what() << std::endl;
} catch(...) {
}
}
}
void av_snooper::sound_rate(uint32_t rate_n, uint32_t rate_d) throw(std::bad_alloc, std::runtime_error)
{
std::ostringstream str;
str << s_name << " dumper does not support variable samping rate.";
throw std::runtime_error(str.str());
}
void av_snooper::_sound_rate(uint32_t rate_n, uint32_t rate_d)
{
uint32_t g = gcd(rate_n, rate_d);
srate_n = rate_n / g;
srate_d = rate_d / g;
for(auto i : snoopers())
try {
i->sound_rate(srate_n, srate_d);
} catch(std::bad_alloc& e) {
throw;
} catch(std::exception& e) {
try {
messages << "Error setting sound frequency: " << e.what() << std::endl;
} catch(...) {
}
}
}
std::pair<uint32_t, uint32_t> av_snooper::get_sound_rate() throw()
{
return std::make_pair(srate_n, srate_d);
}
void av_snooper::gameinfo(const struct gameinfo_struct& gi) throw(std::bad_alloc, std::runtime_error)
{
//Nothing.
}
void av_snooper::_gameinfo(const struct gameinfo_struct& gi) throw(std::bad_alloc)
{
sgi = gi;
for(auto i : snoopers())
try {
i->gameinfo(gi);
} catch(std::bad_alloc& e) {
throw;
} catch(std::exception& e) {
try {
messages << "Error sending game info: " << e.what() << std::endl;
} catch(...) {
}
}
}
const struct gameinfo_struct& av_snooper::get_gameinfo() throw(std::bad_alloc)
{
return sgi;
}
bool av_snooper::dump_in_progress() throw()
{
return !snoopers().empty();
}
av_snooper::dump_notification::dump_notification() throw(std::bad_alloc)
{
notifiers().push_back(this);
}
av_snooper::dump_notification::~dump_notification() throw()
{
for(auto i = notifiers().begin(); i != notifiers().end(); i++)
if(*i == this) {
notifiers().erase(i);
return;
}
}
void av_snooper::dump_notification::dump_starting(const std::string& type) throw()
{
}
void av_snooper::dump_notification::dump_ending(const std::string& type) throw()
{
}
const std::set<std::string>& av_snooper::active_dumpers()
{
return sactive_dumpers();
}

View file

@ -1,10 +1,13 @@
#include "lsnes.hpp"
#include <snes/snes.hpp>
#include <ui-libsnes/libsnes.hpp>
#include "core/command.hpp"
#include "core/controller.hpp"
#include "core/dispatch.hpp"
#include "core/framebuffer.hpp"
#include "core/mainloop.hpp"
#include "core/misc.hpp"
#include "core/window.hpp"
#include <map>
@ -90,7 +93,7 @@ namespace
int bid = -1;
switch(p) {
case DT_NONE:
window::out() << "No such controller #" << (ui_id + 1) << std::endl;
messages << "No such controller #" << (ui_id + 1) << std::endl;
return;
case DT_GAMEPAD:
switch(button) {
@ -107,7 +110,7 @@ namespace
case BUTTON_SELECT: bid = SNES_DEVICE_ID_JOYPAD_SELECT; break;
case BUTTON_START: bid = SNES_DEVICE_ID_JOYPAD_START; break;
default:
window::out() << "Invalid button for gamepad" << std::endl;
messages << "Invalid button for gamepad" << std::endl;
return;
};
break;
@ -116,7 +119,7 @@ namespace
case BUTTON_L: bid = SNES_DEVICE_ID_MOUSE_LEFT; break;
case BUTTON_R: bid = SNES_DEVICE_ID_MOUSE_RIGHT; break;
default:
window::out() << "Invalid button for mouse" << std::endl;
messages << "Invalid button for mouse" << std::endl;
return;
};
break;
@ -125,7 +128,7 @@ namespace
case BUTTON_START: bid = SNES_DEVICE_ID_JUSTIFIER_START; break;
case BUTTON_TRIGGER: bid = SNES_DEVICE_ID_JUSTIFIER_TRIGGER; break;
default:
window::out() << "Invalid button for justifier" << std::endl;
messages << "Invalid button for justifier" << std::endl;
return;
};
break;
@ -136,7 +139,7 @@ namespace
case BUTTON_PAUSE: bid = SNES_DEVICE_ID_SUPER_SCOPE_PAUSE; break;
case BUTTON_TURBO: bid = SNES_DEVICE_ID_SUPER_SCOPE_TURBO; break;
default:
window::out() << "Invalid button for superscope" << std::endl;
messages << "Invalid button for superscope" << std::endl;
return;
};
break;
@ -156,7 +159,7 @@ namespace
enum devicetype_t p = controller_type_by_logical(ui_id);
int y = get_physcial_id_for_control(p, button);
if(x >= 0 && y >= 0)
window_callback::do_autohold_update(x, y, get_autohold(x, y));
information_dispatch::do_autohold_update(x, y, get_autohold(x, y));
} else
do_button_action(ui_id, button, newstate, do_xor, curcontrols);
}
@ -321,7 +324,7 @@ void controller_set_port_type(unsigned port, porttype_t ptype, bool set_core) th
snes_set_controller_port_device(port != 0, port_types[ptype].bsnes_type);
porttypes[port] = ptype;
update_analog_indices();
window_callback::do_autohold_reconfigure();
information_dispatch::do_autohold_reconfigure();
}
controls_t get_current_controls(uint64_t frame)
@ -344,7 +347,7 @@ void send_analog_input(int32_t x, int32_t y, unsigned index)
}
int aindex = controller_index_by_analog(index);
if(aindex < 0) {
window::out() << "No analog controller in slot #" << (index + 1) << std::endl;
messages << "No analog controller in slot #" << (index + 1) << std::endl;
return;
}
curcontrols(aindex >> 2, aindex & 3, 0) = x;
@ -370,7 +373,7 @@ void change_autohold(unsigned pid, unsigned idx, bool newstate)
if(pid >= MAX_PORTS * MAX_CONTROLLERS_PER_PORT || idx >= CONTROLLER_CONTROLS)
return;
autoheld_controls(pid / MAX_CONTROLLERS_PER_PORT, pid % MAX_CONTROLLERS_PER_PORT, idx) = (newstate ? 1 : 0);
window_callback::do_autohold_update(pid, idx, newstate);
information_dispatch::do_autohold_update(pid, idx, newstate);
update_movie_state();
window::notify_screen_update();
}

View file

@ -1,4 +1,5 @@
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/framebuffer.hpp"
#include "core/lua.hpp"
#include "core/misc.hpp"
@ -131,7 +132,7 @@ void redraw_framebuffer()
lrc.top_gap + lrc.bottom_gap, lrc.left_gap, lrc.top_gap);
main_screen.copy_from(framebuffer, hscl, vscl);
//We would want divide by 2, but we'll do it ourselves in order to do mouse.
window::set_window_compensation(lrc.left_gap, lrc.top_gap, 1, 1);
information_dispatch::do_click_compensation(lrc.left_gap, lrc.top_gap, 1, 1);
rq.run(main_screen);
window::notify_screen_update();
}

View file

@ -1,7 +1,7 @@
#include "jmd.hpp"
#include "core/avsnoop.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/lua.hpp"
#include "core/misc.hpp"
#include "core/settings.hpp"
@ -14,11 +14,11 @@
namespace
{
class jmd_avsnoop : public av_snooper
class jmd_avsnoop : public information_dispatch
{
public:
jmd_avsnoop(const std::string& filename, unsigned level) throw(std::bad_alloc)
: av_snooper("JMD")
: information_dispatch("dump-jmd")
{
vid_dumper = new jmd_dumper(filename, level);
have_dumped_frame = false;
@ -27,9 +27,9 @@ namespace
video_w = 0;
video_n = 0;
maxtc = 0;
soundrate = av_snooper::get_sound_rate();
soundrate = get_sound_rate();
try {
gameinfo(av_snooper::get_gameinfo());
on_gameinfo(get_gameinfo());
} catch(std::exception& e) {
messages << "Can't write gameinfo: " << e.what() << std::endl;
}
@ -40,8 +40,7 @@ namespace
delete vid_dumper;
}
void frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d, const uint32_t* raw, bool hires,
bool interlaced, bool overscan, unsigned region) throw(std::bad_alloc, std::runtime_error)
void on_frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d)
{
struct lua_render_context lrc;
render_queue rq;
@ -63,19 +62,19 @@ namespace
have_dumped_frame = true;
}
void sample(short l, short r) throw(std::bad_alloc, std::runtime_error)
void on_sample(short l, short r)
{
uint64_t ts = get_next_audio_ts();
if(have_dumped_frame)
vid_dumper->audio(ts, l, r);
}
void end() throw(std::bad_alloc, std::runtime_error)
void on_dump_end()
{
vid_dumper->end(maxtc);
}
void gameinfo(const struct gameinfo_struct& gi) throw(std::bad_alloc, std::runtime_error)
void on_gameinfo(const struct gameinfo_struct& gi)
{
std::string authstr;
for(size_t i = 0; i < gi.get_author_count(); i++) {
@ -85,6 +84,11 @@ namespace
}
vid_dumper->gameinfo(gi.gamename, authstr, 1000000000ULL * gi.length, gi.get_rerecords());
}
bool get_dumper_flag() throw()
{
return true;
}
private:
uint64_t get_next_video_ts(uint32_t fps_n, uint32_t fps_d)
{
@ -165,7 +169,7 @@ namespace
if(!vid_dumper)
throw std::runtime_error("No JMD video dump in progress");
try {
vid_dumper->end();
vid_dumper->on_dump_end();
messages << "JMD Dump finished" << std::endl;
} catch(std::bad_alloc& e) {
throw;

View file

@ -1,4 +1,5 @@
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/globalwrap.hpp"
#include "core/keymapper.hpp"
#include "core/lua.hpp"
@ -445,20 +446,6 @@ void keygroup::set_position(short pos, const modifier_set& modifiers) throw()
}
}
void keygroup::add_key_listener(key_listener& l) throw(std::bad_alloc)
{
listeners.push_back(&l);
}
void keygroup::remove_key_listener(key_listener& l) throw(std::bad_alloc)
{
for(auto i = listeners.begin(); i != listeners.end(); ++i)
if(*i == &l) {
listeners.erase(i);
return;
}
}
void keygroup::run_listeners(const modifier_set& modifiers, unsigned subkey, bool polarity, bool really, double x)
{
if(!really)
@ -476,19 +463,7 @@ void keygroup::run_listeners(const modifier_set& modifiers, unsigned subkey, boo
name = name + "s";
if(ktype == KT_HAT && subkey == 3)
name = name + "w";
if(exclusive) {
exclusive->key_event(modifiers, *this, subkey, polarity, name);
return;
}
for(auto i : listeners)
i->key_event(modifiers, *this, subkey, polarity, name);
}
keygroup::key_listener* keygroup::exclusive;
void keygroup::set_exclusive_key_listener(key_listener* l) throw()
{
exclusive = l;
information_dispatch::do_key_event(modifiers, *this, subkey, polarity, name);
}
keygroup* keygroup::lookup_by_name(const std::string& name) throw()
@ -728,20 +703,25 @@ namespace
return x;
}
};
struct keybind_data : public keygroup::key_listener
struct keybind_data : public information_dispatch
{
modifier_set mod;
modifier_set modmask;
keygroup* group;
unsigned subkey;
std::string command;
void key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned _subkey, bool polarity,
keybind_data() : information_dispatch("keybind-listener") {}
void on_key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned _subkey, bool polarity,
const std::string& name)
{
if(!modifier_set::triggers(modifiers, mod, modmask))
return;
if(subkey != _subkey)
return;
if(&keygroup != group)
return;
std::string cmd = fixup_command_polarity(command, polarity);
if(cmd == "")
return;
@ -763,7 +743,7 @@ namespace
return k;
}
std::map<triple, keybind_data> keybindings;
std::map<triple, keybind_data*> keybindings;
}
void keymapper::bind(std::string mod, std::string modmask, std::string keyname, std::string command)
@ -776,13 +756,13 @@ void keymapper::bind(std::string mod, std::string modmask, std::string keyname,
throw std::runtime_error("Invalid modifiers");
auto g = keygroup::lookup(keyname);
if(!keybindings.count(k)) {
keybindings[k].mod = _mod;
keybindings[k].modmask = _modmask;
keybindings[k].group = g.first;
keybindings[k].subkey = g.second;
g.first->add_key_listener(keybindings[k]);
keybindings[k] = new keybind_data;
keybindings[k]->mod = _mod;
keybindings[k]->modmask = _modmask;
keybindings[k]->group = g.first;
keybindings[k]->subkey = g.second;
}
keybindings[k].command = command;
keybindings[k]->command = command;
}
void keymapper::unbind(std::string mod, std::string modmask, std::string keyname) throw(std::bad_alloc,
std::runtime_error)
@ -790,7 +770,7 @@ void keymapper::unbind(std::string mod, std::string modmask, std::string keyname
triple k(mod, modmask, keyname);
if(!keybindings.count(k))
throw std::runtime_error("Key is not bound");
keybindings[k].group->remove_key_listener(keybindings[k]);
delete keybindings[k];
keybindings.erase(k);
}
@ -822,7 +802,7 @@ std::string keymapper::get_command_for(const std::string& keyspec) throw(std::ba
}
if(!keybindings.count(k))
return "";
return keybindings[k].command;
return keybindings[k]->command;
}
void keymapper::bind_for(const std::string& keyspec, const std::string& cmd) throw(std::bad_alloc, std::runtime_error)

View file

@ -2,9 +2,9 @@
#include <snes/snes.hpp>
#include <ui-libsnes/libsnes.hpp>
#include "core/avsnoop.hpp"
#include "core/command.hpp"
#include "core/controller.hpp"
#include "core/dispatch.hpp"
#include "core/framebuffer.hpp"
#include "core/framerate.hpp"
#include "core/lua.hpp"
@ -196,18 +196,6 @@ namespace
window::message("Pending save on '" + filename + "'");
}
class dump_watch : public av_snooper::dump_notification
{
void dump_starting(const std::string& n) throw()
{
update_movie_state();
}
void dump_ending(const std::string& n) throw()
{
update_movie_state();
}
} dumpwatch;
uint32_t lpalette[0x80000];
void init_palette()
{
@ -262,7 +250,7 @@ void update_movie_state()
{
std::ostringstream x;
x << (system_corrupt ? "C" : "-");
x << (av_snooper::dump_in_progress() ? "D" : "-");
x << (information_dispatch::get_dumper_count() ? "D" : "-");
x << (last_hires ? "H" : "-");
x << (last_interlace ? "I" : "-");
if(!system_corrupt)
@ -353,6 +341,8 @@ class my_interface : public SNES::Interface
window::message("Got video refresh in runtosave, expect desyncs!");
video_refresh_done = true;
bool region = (SNES::system.region() == SNES::System::Region::PAL);
information_dispatch::do_raw_frame(data, hires, interlace, overscan, region ? VIDEO_REGION_PAL :
VIDEO_REGION_NTSC);
//std::cerr << "Frame: hires flag is " << (hires ? " " : "un") << "set." << std::endl;
//std::cerr << "Frame: interlace flag is " << (interlace ? " " : "un") << "set." << std::endl;
//std::cerr << "Frame: overscan flag is " << (overscan ? " " : "un") << "set." << std::endl;
@ -373,8 +363,7 @@ class my_interface : public SNES::Interface
uint32_t g = gcd(fps_n, fps_d);
fps_n /= g;
fps_d /= g;
av_snooper::_frame(ls, fps_n, fps_d, data, hires, interlace, overscan, region ? SNOOP_REGION_PAL :
SNOOP_REGION_NTSC);
information_dispatch::do_frame(ls, fps_n, fps_d);
}
void audioSample(int16_t l_sample, int16_t r_sample)
@ -382,7 +371,7 @@ class my_interface : public SNES::Interface
uint16_t _l = l_sample;
uint16_t _r = r_sample;
window::play_audio_sample(_l + 32768, _r + 32768);
av_snooper::_sample(l_sample, r_sample);
information_dispatch::do_sample(l_sample, r_sample);
//The SMP emits a sample every 768 ticks of its clock. Use this in order to keep track of time.
our_movie.rtc_subsecond += 768;
while(our_movie.rtc_subsecond >= SNES::system.apu_frequency()) {
@ -585,7 +574,7 @@ namespace
"Syntax: set-rwmode\nSwitches to read/write mode\n",
[]() throw(std::bad_alloc, std::runtime_error) {
movb.get_movie().readonly_mode(false);
window_callback::do_mode_change(false);
information_dispatch::do_mode_change(false);
lua_callback_do_readwrite();
update_movie_state();
window::notify_screen_update();
@ -595,7 +584,7 @@ namespace
"Syntax: set-romode\nSwitches to read-only mode\n",
[]() throw(std::bad_alloc, std::runtime_error) {
movb.get_movie().readonly_mode(true);
window_callback::do_mode_change(true);
information_dispatch::do_mode_change(true);
update_movie_state();
window::notify_screen_update();
});
@ -605,7 +594,7 @@ namespace
[]() throw(std::bad_alloc, std::runtime_error) {
bool c = movb.get_movie().readonly_mode();
movb.get_movie().readonly_mode(!c);
window_callback::do_mode_change(!c);
information_dispatch::do_mode_change(!c);
if(c)
lua_callback_do_readwrite();
update_movie_state();
@ -639,9 +628,18 @@ namespace
bool on_quit_prompt = false;
class mywindowcallbacks : public window_callback
class mywindowcallbacks : public information_dispatch
{
public:
mywindowcallbacks() : information_dispatch("mainloop-window-callbacks") {}
void on_new_dumper(const std::string& n)
{
update_movie_state();
}
void on_destroy_dumper(const std::string& n)
{
update_movie_state();
}
void on_close() throw()
{
if(on_quit_prompt) {
@ -883,6 +881,6 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
window::wait_usec(to_wait_frame(get_utime()));
first_round = false;
}
av_snooper::_end();
information_dispatch::do_dump_end();
SNES::interface = old_inteface;
}

View file

@ -4,6 +4,7 @@
#include "core/command.hpp"
#include "core/controller.hpp"
#include "core/dispatch.hpp"
#include "core/framebuffer.hpp"
#include "core/framerate.hpp"
#include "core/lua.hpp"
@ -11,7 +12,6 @@
#include "core/moviedata.hpp"
#include "core/rrdata.hpp"
#include "core/settings.hpp"
#include "core/window.hpp"
#include <iomanip>
@ -265,7 +265,7 @@ void do_load_state(struct moviefile& _movie, int lmode)
movb.get_movie().readonly_mode(false);
if(lmode == LOAD_STATE_CURRENT && !current_mode)
movb.get_movie().readonly_mode(false);
window_callback::do_mode_change(movb.get_movie().readonly_mode());
information_dispatch::do_mode_change(movb.get_movie().readonly_mode());
messages << "ROM Type ";
switch(our_rom->rtype) {
case ROMTYPE_SNES:

View file

@ -2,8 +2,8 @@
#include <snes/snes.hpp>
#include <ui-libsnes/libsnes.hpp>
#include "core/avsnoop.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/framerate.hpp"
#include "core/memorymanip.hpp"
#include "core/misc.hpp"
@ -497,8 +497,7 @@ void loaded_rom::load() throw(std::bad_alloc, std::runtime_error)
set_nominal_framerate(SNES::system.cpu_frequency() / DURATION_PAL_FRAME);
else
set_nominal_framerate(SNES::system.cpu_frequency() / DURATION_NTSC_FRAME);
window::set_sound_rate(SNES::system.apu_frequency(), 768);
av_snooper::_sound_rate(SNES::system.apu_frequency(), 768);
information_dispatch::do_sound_rate(SNES::system.apu_frequency(), 768);
current_rom_type = rtype;
current_region = region;
refresh_cart_mappings();

View file

@ -1,6 +1,6 @@
#include "sdmp.hpp"
#include "core/avsnoop.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/lua.hpp"
#include "core/misc.hpp"
#include "core/settings.hpp"
@ -13,11 +13,11 @@
namespace
{
class sdmp_avsnoop : public av_snooper
class sdmp_avsnoop : public information_dispatch
{
public:
sdmp_avsnoop(const std::string& prefix, bool ssflag) throw(std::bad_alloc)
: av_snooper("SDMP")
: information_dispatch("dump-sdmp")
{
dumper = new sdump_dumper(prefix, ssflag);
}
@ -27,24 +27,28 @@ namespace
delete dumper;
}
void frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d, const uint32_t* raw, bool hires,
bool interlaced, bool overscan, unsigned region) throw(std::bad_alloc, std::runtime_error)
void on_raw_frame(const uint32_t* raw, bool hires, bool interlaced, bool overscan, unsigned region)
{
unsigned flags = 0;
dumper->frame(raw, (hires ? SDUMP_FLAG_HIRES : 0) | (interlaced ? SDUMP_FLAG_INTERLACED : 0) |
(overscan ? SDUMP_FLAG_OVERSCAN : 0) | (region == SNOOP_REGION_PAL ? SDUMP_FLAG_PAL :
(overscan ? SDUMP_FLAG_OVERSCAN : 0) | (region == VIDEO_REGION_PAL ? SDUMP_FLAG_PAL :
0));
}
void sample(short l, short r) throw(std::bad_alloc, std::runtime_error)
void on_sample(short l, short r)
{
dumper->sample(l, r);
}
void end() throw(std::bad_alloc, std::runtime_error)
void on_dump_end()
{
dumper->end();
}
bool get_dumper_flag() throw()
{
return true;
}
private:
sdump_dumper* dumper;
};
@ -95,7 +99,7 @@ namespace
if(!vid_dumper)
throw std::runtime_error("No SDMP video dump in progress");
try {
vid_dumper->end();
vid_dumper->on_dump_end();
messages << "SDMP Dump finished" << std::endl;
} catch(std::bad_alloc& e) {
throw;

View file

@ -1,8 +1,8 @@
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/globalwrap.hpp"
#include "core/misc.hpp"
#include "core/settings.hpp"
#include "core/window.hpp"
#include <map>
#include <sstream>
@ -72,7 +72,7 @@ void setting::set(const std::string& _setting, const std::string& value) throw(s
throw std::runtime_error("No such setting '" + _setting + "'");
try {
settings()[_setting]->set(value);
window_callback::do_setting_change(_setting, value);
information_dispatch::do_setting_change(_setting, value);
} catch(std::bad_alloc& e) {
throw;
} catch(std::exception& e) {
@ -86,7 +86,7 @@ void setting::blank(const std::string& _setting) throw(std::bad_alloc, std::runt
throw std::runtime_error("No such setting '" + _setting + "'");
try {
settings()[_setting]->blank();
window_callback::do_setting_clear(_setting);
information_dispatch::do_setting_clear(_setting);
} catch(std::bad_alloc& e) {
throw;

View file

@ -1,4 +1,5 @@
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/misc.hpp"
#include "core/render.hpp"
#include "core/window.hpp"
@ -136,11 +137,6 @@ namespace
} msg_callback_obj;
std::ofstream system_log;
window_callback* wcb = NULL;
uint32_t vc_xoffset;
uint32_t vc_yoffset;
uint32_t vc_hscl = 1;
uint32_t vc_vscl = 1;
bool sounds_enabled = true;
}
@ -153,7 +149,7 @@ void window::sound_enable(bool enable) throw()
{
_sound_enable(enable);
sounds_enabled = enable;
window_callback::do_sound_unmute(enable);
information_dispatch::do_sound_unmute(enable);
}
void window::set_sound_device(const std::string& dev) throw()
@ -163,11 +159,8 @@ void window::set_sound_device(const std::string& dev) throw()
} catch(std::exception& e) {
out() << "Error changing sound device: " << e.what() << std::endl;
}
try {
//After failed change, we don't know what is selected.
window_callback::do_sound_change(get_current_sound_device());
} catch(...) {
}
//After failed change, we don't know what is selected.
information_dispatch::do_sound_change(get_current_sound_device());
}
bool window::is_sound_enabled() throw()
@ -218,14 +211,6 @@ std::ostream& window::out() throw(std::bad_alloc)
return *cached;
}
void window::set_window_compensation(uint32_t xoffset, uint32_t yoffset, uint32_t hscl, uint32_t vscl)
{
vc_xoffset = xoffset;
vc_yoffset = yoffset;
vc_hscl = hscl;
vc_vscl = vscl;
}
messagebuffer window::msgbuf(MAXMESSAGES, INIT_WIN_SIZE);
@ -262,115 +247,3 @@ void window::fatal_error() throw()
fatal_error2();
exit(1);
}
namespace
{
static std::set<window_callback*>& wcbs()
{
static std::set<window_callback*> s;
return s;
}
}
window_callback::window_callback() throw()
{
wcbs().insert(this);
}
window_callback::~window_callback() throw()
{
wcbs().erase(this);
}
void window_callback::on_close() throw()
{
}
void window_callback::on_click(int32_t x, int32_t y, uint32_t buttonmask) throw()
{
}
void window_callback::on_sound_unmute(bool unmute) throw()
{
}
void window_callback::on_mode_change(bool readonly) throw()
{
}
void window_callback::on_autohold_update(unsigned pid, unsigned ctrlnum, bool newstate)
{
}
void window_callback::on_autohold_reconfigure()
{
}
void window_callback::on_sound_change(const std::string& dev) throw()
{
}
void window_callback::do_close() throw()
{
for(auto i : wcbs())
i->on_close();
}
void window_callback::do_click(int32_t x, int32_t y, uint32_t buttonmask) throw()
{
x = (x - vc_xoffset) / vc_hscl;
y = (y - vc_yoffset) / vc_vscl;
for(auto i : wcbs())
i->on_click(x, y, buttonmask);
}
void window_callback::do_sound_unmute(bool unmute) throw()
{
for(auto i : wcbs())
i->on_sound_unmute(unmute);
}
void window_callback::do_sound_change(const std::string& dev) throw()
{
for(auto i : wcbs())
i->on_sound_change(dev);
}
void window_callback::do_mode_change(bool readonly) throw()
{
for(auto i : wcbs())
i->on_mode_change(readonly);
}
void window_callback::do_autohold_update(unsigned pid, unsigned ctrlnum, bool newstate)
{
for(auto i : wcbs())
i->on_autohold_update(pid, ctrlnum, newstate);
}
void window_callback::do_autohold_reconfigure()
{
for(auto i : wcbs())
i->on_autohold_reconfigure();
}
void window_callback::do_setting_change(const std::string& _setting, const std::string& value)
{
for(auto i : wcbs())
i->on_setting_change(_setting, value);
}
void window_callback::do_setting_clear(const std::string& _setting)
{
for(auto i : wcbs())
i->on_setting_clear(_setting);
}
void window_callback::on_setting_change(const std::string& setting, const std::string& value)
{
}
void window_callback::on_setting_clear(const std::string& setting)
{
}

View file

@ -8,7 +8,6 @@ void sound_init() {}
void sound_quit() {}
void window::_sound_enable(bool enable) throw() {}
void window::play_audio_sample(uint16_t left, uint16_t right) throw() {}
void window::set_sound_rate(uint32_t rate_n, uint32_t rate_d) {}
bool window::sound_initialized()
{

View file

@ -1,6 +1,7 @@
#include "lsnes.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/framerate.hpp"
#include "core/misc.hpp"
#include "core/framerate.hpp"
@ -224,15 +225,20 @@ void window::play_audio_sample(uint16_t left, uint16_t right) throw()
sampledup_ctr -= sampledup_mod;
}
void window::set_sound_rate(uint32_t rate_n, uint32_t rate_d)
class sound_change_listener : public information_dispatch
{
if(!init_flag)
return;
uint32_t g = gcd(rate_n, rate_d);
use_rate_n = rate_n / g;
use_rate_d = rate_d / g;
calculate_sampledup(use_rate_n, use_rate_d);
}
public:
sound_change_listener() : information_dispatch("portaudio-sound-change-listener") {}
void on_sound_rate(uint32_t rate_n, uint32_t rate_d)
{
if(!init_flag)
return;
uint32_t g = gcd(rate_n, rate_d);
use_rate_n = rate_n / g;
use_rate_d = rate_d / g;
calculate_sampledup(use_rate_n, use_rate_d);
}
} sndchgl;
bool window::sound_initialized()
{

View file

@ -2,6 +2,7 @@
#include "lsnes.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/framerate.hpp"
#include "core/keymapper.hpp"
#include "core/misc.hpp"
@ -383,9 +384,10 @@ namespace
#endif
}
struct identify_helper : public keygroup::key_listener
struct identify_helper : public information_dispatch
{
void key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned subkey,
identify_helper() : information_dispatch("sdl-identify-helper") {}
void on_key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned subkey,
bool polarity, const std::string& name)
{
if(!polarity)
@ -402,9 +404,10 @@ namespace
std::string _keys;
};
struct key_eater : public keygroup::key_listener
struct key_eater : public information_dispatch
{
void key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned subkey,
key_eater() : information_dispatch("sdl-key-eater") {}
void on_key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned subkey,
bool polarity, const std::string& name)
{
//Just eat it.
@ -880,7 +883,7 @@ namespace
return;
}
if(e.type == SDL_QUIT) {
window_callback::do_close();
information_dispatch::do_close();
state = WINSTATE_NORMAL;
return;
}
@ -910,7 +913,7 @@ namespace
else
mouse_mask &= ~4;
}
window_callback::do_click(xc, yc, mouse_mask);
information_dispatch::do_click(xc, yc, mouse_mask);
}
if(e.type == SDL_KEYDOWN && key == SDLK_ESCAPE)
return;
@ -930,9 +933,9 @@ namespace
break;
case WINSTATE_MODAL:
//Send the key and eat it (prevent input from getting confused).
keygroup::set_exclusive_key_listener(&keyeater);
process_input_event(&e),
keygroup::set_exclusive_key_listener(NULL);
keyeater.grab_keys();
process_input_event(&e);
keyeater.ungrab_keys();
if(e.type == SDL_KEYUP && key == SDLK_ESCAPE) {
state = WINSTATE_NORMAL;
modconfirm = false;
@ -951,9 +954,9 @@ namespace
break;
case WINSTATE_COMMAND:
//Send the key and eat it (prevent input from getting confused).
keygroup::set_exclusive_key_listener(&keyeater);
process_input_event(&e),
keygroup::set_exclusive_key_listener(NULL);
keyeater.grab_keys();
process_input_event(&e);
keyeater.ungrab_keys();
if(e.type == SDL_KEYUP && e.key.keysym.sym == SDLK_ESCAPE) {
state = WINSTATE_NORMAL;
command_buf = "";
@ -1052,7 +1055,7 @@ bool window::modal_message(const std::string& msg, bool confirm) throw(std::bad_
bool ret = modconfirm;
if(delayed_close_flag) {
delayed_close_flag = false;
window_callback::do_close();
information_dispatch::do_close();
}
return ret;
}
@ -1280,7 +1283,7 @@ void poll_inputs_internal() throw(std::bad_alloc)
SDL_Event e;
identify_helper h;
if(state == WINSTATE_IDENTIFY)
keygroup::set_exclusive_key_listener(&h);
h.grab_keys();
while(state != WINSTATE_NORMAL) {
window::poll_joysticks();
if(SDL_PollEvent(&e))
@ -1288,11 +1291,12 @@ void poll_inputs_internal() throw(std::bad_alloc)
::wait_usec(10000);
if(delayed_close_flag) {
state = WINSTATE_NORMAL;
h.ungrab_keys();
return;
}
if(h.got_it()) {
window::modal_message(h.keys(), false);
keygroup::set_exclusive_key_listener(NULL);
h.ungrab_keys();
}
}
}

View file

@ -1,6 +1,7 @@
#include "lsnes.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/framerate.hpp"
#include "core/keymapper.hpp"
#include "core/misc.hpp"
@ -131,13 +132,15 @@ void sound_init()
window::message("Audio can't be initialized, audio playback disabled");
//Disable audio.
audio_playback_freq = 0;
calculate_sampledup(32000, 1);
auto g = information_dispatch::get_sound_rate();
calculate_sampledup(g.first, g.second);
return;
}
//Fill the parameters.
audio_playback_freq = obtained->freq;
calculate_sampledup(32000, 1);
auto g = information_dispatch::get_sound_rate();
calculate_sampledup(g.first, g.second);
format = obtained->format;
stereo = (obtained->channels == 2);
//GO!!!
@ -163,11 +166,16 @@ void window::play_audio_sample(uint16_t left, uint16_t right) throw()
sampledup_ctr -= sampledup_mod;
}
void window::set_sound_rate(uint32_t rate_n, uint32_t rate_d)
class sound_change_listener : public information_dispatch
{
uint32_t g = gcd(rate_n, rate_d);
calculate_sampledup(rate_n / g, rate_d / g);
}
public:
sound_change_listener() : information_dispatch("sdl-sound-change-listener") {}
void on_sound_rate(uint32_t rate_n, uint32_t rate_d)
{
uint32_t g = gcd(rate_n, rate_d);
calculate_sampledup(rate_n / g, rate_d / g);
}
} sndchgl;
bool window::sound_initialized()
{

View file

@ -212,7 +212,7 @@ void autohold_menu::update(unsigned pid, unsigned ctrlnum, bool newstate)
class emulator_main_window;
class sound_listener : public window_callback
class sound_listener : public information_dispatch
{
public:
sound_listener(emulator_main_window* w);
@ -718,7 +718,7 @@ loop:
mask |= 4;
if(e.RightUp())
mask &= ~4;
window_callback::do_click(e.GetX(), e.GetY(), mask);
information_dispatch::do_click(e.GetX(), e.GetY(), mask);
}
}
@ -1427,6 +1427,7 @@ void emulator_main_window::menu_scripting(wxCommandEvent& e)
}
sound_listener::sound_listener(emulator_main_window* w)
: information_dispatch("wx-emufn-sound-listener")
{
win = w;
}

View file

@ -2,7 +2,7 @@
#include <snes/snes.hpp>
#include <ui-libsnes/libsnes.hpp>
#include "core/avsnoop.hpp"
#include "core/dispatch.hpp"
#include "core/framerate.hpp"
#include "core/lua.hpp"
#include "core/misc.hpp"
@ -63,7 +63,7 @@ bool lsnes_app::OnInit()
int lsnes_app::OnExit()
{
av_snooper::_end();
information_dispatch::do_dump_end();
rrdata::close();
window::quit();
return 0;

View file

@ -130,6 +130,7 @@ void wx_settings_editor::clear_setting(const std::string& _setting)
}
wx_settings_editor_listener::wx_settings_editor_listener(wx_settings_editor* _editor)
: information_dispatch("wx-settings-editor-listener")
{
editor = _editor;
}

View file

@ -2,8 +2,8 @@
#include <snes/snes.hpp>
#include <ui-libsnes/libsnes.hpp>
#include "core/avsnoop.hpp"
#include "core/command.hpp"
#include "core/dispatch.hpp"
#include "core/framerate.hpp"
#include "core/keymapper.hpp"
#include "core/lua.hpp"
@ -19,11 +19,11 @@
namespace
{
class myavsnoop : public av_snooper
class myavsnoop : public information_dispatch
{
public:
myavsnoop(uint64_t frames_to_dump)
: av_snooper("myavsnoop-monitor")
: information_dispatch("myavsnoop-monitor")
{
frames_dumped = 0;
total = frames_to_dump;
@ -33,8 +33,7 @@ namespace
{
}
void frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d, const uint32_t* raw, bool hires,
bool interlaced, bool overscan, unsigned region) throw(std::bad_alloc, std::runtime_error)
void on_frame(struct lcscreen& _frame, uint32_t fps_n, uint32_t fps_d)
{
frames_dumped++;
if(frames_dumped % 100 == 0) {
@ -43,12 +42,12 @@ namespace
}
if(frames_dumped == total) {
//Rough way to end it.
av_snooper::_end();
exit(1);
information_dispatch::do_dump_end();
exit(0);
}
}
void end() throw(std::bad_alloc, std::runtime_error)
void on_dump_end()
{
std::cout << "Finished!" << std::endl;
}
@ -113,7 +112,7 @@ namespace
else
cmd << "dump-avi " << level << " " << prefix;
command::invokeC(cmd.str());
if(av_snooper::dump_in_progress()) {
if(information_dispatch::get_dumper_count()) {
std::cout << "Dumper attach confirmed" << std::endl;
} else {
std::cout << "Can't start dumper!" << std::endl;