Setting sets
This commit is contained in:
parent
66839ba82f
commit
6f35061747
21 changed files with 544 additions and 155 deletions
|
@ -21,6 +21,7 @@ struct emulator_instance
|
|||
memory_space memory;
|
||||
lua::state lua;
|
||||
lsnes_memorywatch_set mwatch;
|
||||
settingvar::group settings;
|
||||
settingvar::cache setcache;
|
||||
voice_commentary commentary;
|
||||
subtitle_commentary subtitles;
|
||||
|
|
|
@ -34,8 +34,8 @@ void reload_current_rom();
|
|||
void do_break_pause();
|
||||
void convert_break_to_pause();
|
||||
|
||||
extern settingvar::variable<settingvar::model_bool<settingvar::yes_no>> jukebox_dflt_binary;
|
||||
extern settingvar::variable<settingvar::model_bool<settingvar::yes_no>> movie_dflt_binary;
|
||||
extern settingvar::variable<settingvar::model_bool<settingvar::yes_no>> save_dflt_binary;
|
||||
extern settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> jukebox_dflt_binary;
|
||||
extern settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> movie_dflt_binary;
|
||||
extern settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> save_dflt_binary;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
#include "library/settingvar.hpp"
|
||||
|
||||
extern settingvar::group lsnes_vset;
|
||||
extern settingvar::set lsnes_setgrp;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,10 @@ namespace settingvar
|
|||
class base;
|
||||
class group;
|
||||
class description;
|
||||
class set;
|
||||
class superbase;
|
||||
|
||||
threads::rlock& get_setting_lock();
|
||||
|
||||
/**
|
||||
* A settings listener.
|
||||
|
@ -29,6 +33,64 @@ struct listener
|
|||
virtual void on_setting_change(group& _group, const base& val) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set add/drop listener.
|
||||
*/
|
||||
class set_listener
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Dtor.
|
||||
*/
|
||||
virtual ~set_listener();
|
||||
/**
|
||||
* New item in set.
|
||||
*/
|
||||
virtual void create(set& s, const std::string& name, superbase& svar) = 0;
|
||||
/**
|
||||
* Deleted item from set.
|
||||
*/
|
||||
virtual void destroy(set& s, const std::string& name) = 0;
|
||||
/**
|
||||
* Destroyed the entiere set.
|
||||
*/
|
||||
virtual void kill(set& s) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A set of setting variables.
|
||||
*/
|
||||
class set
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a set.
|
||||
*/
|
||||
set();
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~set();
|
||||
/**
|
||||
* Register a supervariable.
|
||||
*/
|
||||
void do_register(const std::string& name, superbase& info);
|
||||
/**
|
||||
* Unregister a supervariable.
|
||||
*/
|
||||
void do_unregister(const std::string& name, superbase& info);
|
||||
/**
|
||||
* Add a callback on new supervariable.
|
||||
*/
|
||||
void add_callback(set_listener& listener) throw(std::bad_alloc);
|
||||
/**
|
||||
* Drop a callback on new supervariable.
|
||||
*/
|
||||
void drop_callback(set_listener& listener);
|
||||
private:
|
||||
char dummy;
|
||||
};
|
||||
|
||||
/**
|
||||
* Group of setting variables.
|
||||
*/
|
||||
|
@ -71,10 +133,30 @@ public:
|
|||
* Fire listener.
|
||||
*/
|
||||
void fire_listener(base& var) throw();
|
||||
/**
|
||||
* Add a set of settings.
|
||||
*/
|
||||
void add_set(set& s) throw(std::bad_alloc);
|
||||
/**
|
||||
* Remove a set of settings.
|
||||
*/
|
||||
void drop_set(set& s);
|
||||
private:
|
||||
class xlistener : public set_listener
|
||||
{
|
||||
public:
|
||||
xlistener(group& _grp);
|
||||
~xlistener();
|
||||
void create(set& s, const std::string& name, superbase& sb);
|
||||
void destroy(set& s, const std::string& name);
|
||||
void kill(set& s);
|
||||
private:
|
||||
group& grp;
|
||||
} _listener;
|
||||
std::map<std::string, class base*> settings;
|
||||
std::set<struct listener*> listeners;
|
||||
threads::lock lock;
|
||||
std::set<struct set*> sets_listened;
|
||||
bool dtor_running;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -134,7 +216,6 @@ public:
|
|||
std::string get_hname(const std::string& name) throw(std::bad_alloc, std::runtime_error);
|
||||
private:
|
||||
group& grp;
|
||||
threads::lock lock;
|
||||
std::map<std::string, std::string> badcache;
|
||||
};
|
||||
|
||||
|
@ -181,6 +262,33 @@ struct description
|
|||
*/
|
||||
template<class T> static class description& description_get(T dummy);
|
||||
|
||||
/**
|
||||
* Supervariable.
|
||||
*/
|
||||
class superbase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
void _superbase(set& _s, const std::string& iname) throw(std::bad_alloc);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~superbase() throw();
|
||||
/**
|
||||
* Make a variable.
|
||||
*/
|
||||
virtual base* make(group& grp) = 0;
|
||||
/**
|
||||
* Notify set death.
|
||||
*/
|
||||
void set_died();
|
||||
private:
|
||||
set* s;
|
||||
std::string iname;
|
||||
};
|
||||
|
||||
/**
|
||||
* Setting variable.
|
||||
*/
|
||||
|
@ -190,8 +298,7 @@ public:
|
|||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
base(group& _group, const std::string& iname, const std::string& hname)
|
||||
throw(std::bad_alloc);
|
||||
base(group& _group, const std::string& iname, const std::string& hname, bool dynamic) throw(std::bad_alloc);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
|
@ -213,13 +320,17 @@ public:
|
|||
* Get setting description.
|
||||
*/
|
||||
virtual const description& get_description() const throw() = 0;
|
||||
/**
|
||||
* Notify group death.
|
||||
*/
|
||||
void group_died();
|
||||
protected:
|
||||
base(const base&);
|
||||
base& operator=(const base&);
|
||||
group& sgroup;
|
||||
group* sgroup;
|
||||
std::string iname;
|
||||
std::string hname;
|
||||
mutable threads::lock lock;
|
||||
bool is_dynamic;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -235,8 +346,8 @@ public:
|
|||
* Constructor.
|
||||
*/
|
||||
variable(group& sgroup, const std::string& iname, const std::string& hname,
|
||||
valtype_t defaultvalue)
|
||||
: base(sgroup, iname, hname)
|
||||
valtype_t defaultvalue, bool dynamic = false)
|
||||
: base(sgroup, iname, hname, dynamic)
|
||||
{
|
||||
value = defaultvalue;
|
||||
}
|
||||
|
@ -252,17 +363,17 @@ public:
|
|||
void str(const std::string& val) throw(std::runtime_error, std::bad_alloc)
|
||||
{
|
||||
{
|
||||
threads::alock h(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
value = model::read(val);
|
||||
}
|
||||
sgroup.fire_listener(*this);
|
||||
sgroup->fire_listener(*this);
|
||||
}
|
||||
/**
|
||||
* Get setting.
|
||||
*/
|
||||
std::string str() const throw(std::runtime_error, std::bad_alloc)
|
||||
{
|
||||
threads::alock h(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
return model::write(value);
|
||||
}
|
||||
/**
|
||||
|
@ -271,19 +382,19 @@ public:
|
|||
void set(valtype_t _value) throw(std::runtime_error, std::bad_alloc)
|
||||
{
|
||||
{
|
||||
threads::alock h(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
if(!model::valid(value))
|
||||
throw std::runtime_error("Invalid value");
|
||||
value = _value;
|
||||
}
|
||||
sgroup.fire_listener(*this);
|
||||
sgroup->fire_listener(*this);
|
||||
}
|
||||
/**
|
||||
* Get setting.
|
||||
*/
|
||||
valtype_t get() throw(std::bad_alloc)
|
||||
{
|
||||
threads::alock h(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
return model::transform(value);
|
||||
}
|
||||
/**
|
||||
|
@ -305,6 +416,69 @@ private:
|
|||
model dummy;
|
||||
};
|
||||
|
||||
/**
|
||||
* Supervariable with model.
|
||||
*/
|
||||
template<class model> class supervariable : public superbase
|
||||
{
|
||||
typedef typename model::valtype_t valtype_t;
|
||||
supervariable(const supervariable<model>&);
|
||||
supervariable<model>& operator=(const supervariable<model>&);
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
supervariable(set& _s, const std::string& _iname, const std::string& _hname, valtype_t _defaultvalue)
|
||||
throw(std::bad_alloc)
|
||||
: s(_s)
|
||||
{
|
||||
iname = _iname;
|
||||
hname = _hname;
|
||||
defaultvalue = _defaultvalue;
|
||||
_superbase(_s, iname);
|
||||
}
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~supervariable() throw()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Make a variable.
|
||||
*/
|
||||
base* make(group& grp)
|
||||
{
|
||||
return new variable<model>(grp, iname, hname, defaultvalue, true);
|
||||
}
|
||||
/**
|
||||
* Read value in instance.
|
||||
*/
|
||||
valtype_t operator()(group& grp)
|
||||
{
|
||||
base* b = &grp[iname];
|
||||
variable<model>* m = dynamic_cast<variable<model>*>(b);
|
||||
if(!m)
|
||||
throw std::runtime_error("No such setting in target group");
|
||||
return m->get();
|
||||
}
|
||||
/**
|
||||
* Write value in instance.
|
||||
*/
|
||||
void operator()(group& grp, valtype_t val)
|
||||
{
|
||||
base* b = &grp[iname];
|
||||
variable<model>* m = dynamic_cast<variable<model>*>(b);
|
||||
if(!m)
|
||||
throw std::runtime_error("No such setting in target group");
|
||||
m->set(val);
|
||||
}
|
||||
private:
|
||||
set& s;
|
||||
std::string iname;
|
||||
std::string hname;
|
||||
valtype_t defaultvalue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Yes-no.
|
||||
*/
|
||||
|
|
|
@ -105,13 +105,14 @@ namespace
|
|||
messages << "Saved PNG screenshot" << std::endl;
|
||||
});
|
||||
|
||||
settingvar::variable<settingvar::model_int<0, 8191>> dtb(lsnes_vset, "top-border", "UI‣Top padding", 0);
|
||||
settingvar::variable<settingvar::model_int<0, 8191>> dbb(lsnes_vset, "bottom-border",
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> dtb(lsnes_setgrp, "top-border",
|
||||
"UI‣Top padding", 0);
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> dbb(lsnes_setgrp, "bottom-border",
|
||||
"UI‣Bottom padding", 0);
|
||||
settingvar::variable<settingvar::model_int<0, 8191>> dlb(lsnes_vset, "left-border",
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> dlb(lsnes_setgrp, "left-border",
|
||||
"UI‣Left padding", 0);
|
||||
settingvar::variable<settingvar::model_int<0, 8191>> drb(lsnes_vset, "right-border", "UI‣Right padding",
|
||||
0);
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> drb(lsnes_setgrp, "right-border",
|
||||
"UI‣Right padding", 0);
|
||||
|
||||
bool last_redraw_no_lua = false;
|
||||
}
|
||||
|
@ -170,10 +171,10 @@ void redraw_framebuffer(framebuffer::raw& todraw, bool no_lua, bool spontaneous)
|
|||
ri.fbuf = todraw;
|
||||
ri.hscl = hscl;
|
||||
ri.vscl = vscl;
|
||||
ri.lgap = max(lrc.left_gap, (unsigned)dlb);
|
||||
ri.rgap = max(lrc.right_gap, (unsigned)drb);
|
||||
ri.tgap = max(lrc.top_gap, (unsigned)dtb);
|
||||
ri.bgap = max(lrc.bottom_gap, (unsigned)dbb);
|
||||
ri.lgap = max(lrc.left_gap, (unsigned)dlb(CORE().settings));
|
||||
ri.rgap = max(lrc.right_gap, (unsigned)drb(CORE().settings));
|
||||
ri.tgap = max(lrc.top_gap, (unsigned)dtb(CORE().settings));
|
||||
ri.bgap = max(lrc.bottom_gap, (unsigned)dbb(CORE().settings));
|
||||
CORE().mwatch.watch(ri.rq);
|
||||
buffering.put_write();
|
||||
notify_screen_update();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "core/keymapper.hpp"
|
||||
|
||||
emulator_instance::emulator_instance()
|
||||
: setcache(lsnes_vset), subtitles(&mlogic), mbranch(&mlogic), mteditor(&mlogic),
|
||||
: setcache(settings), subtitles(&mlogic), mbranch(&mlogic), mteditor(&mlogic),
|
||||
status(status_A, status_B, status_C), mapper(keyboard, command)
|
||||
{
|
||||
status_A.valid = false;
|
||||
|
@ -12,6 +12,7 @@ emulator_instance::emulator_instance()
|
|||
status_C.valid = false;
|
||||
command.add_set(lsnes_cmds);
|
||||
mapper.add_invbind_set(lsnes_invbinds);
|
||||
settings.add_set(lsnes_setgrp);
|
||||
}
|
||||
|
||||
emulator_instance lsnes_instance;
|
||||
|
|
|
@ -65,10 +65,10 @@ namespace
|
|||
class bitrate_tracker;
|
||||
class inthread_th;
|
||||
|
||||
settingvar::variable<settingvar::model_int<OPUS_MIN_BITRATE,OPUS_MAX_BITRATE>> opus_bitrate(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_int<OPUS_MIN_BITRATE,OPUS_MAX_BITRATE>> opus_bitrate(lsnes_setgrp,
|
||||
"opus-bitrate", "commentary‣Bitrate", OPUS_BITRATE);
|
||||
settingvar::variable<settingvar::model_int<OPUS_MIN_BITRATE,OPUS_MAX_BITRATE>> opus_max_bitrate(lsnes_vset,
|
||||
"opus-max-bitrate", "commentary‣Max bitrate", OPUS_MAX_BITRATE);
|
||||
settingvar::supervariable<settingvar::model_int<OPUS_MIN_BITRATE,OPUS_MAX_BITRATE>> opus_max_bitrate(
|
||||
lsnes_setgrp, "opus-max-bitrate", "commentary‣Max bitrate", OPUS_MAX_BITRATE);
|
||||
|
||||
struct voicesub_state
|
||||
{
|
||||
|
@ -588,7 +588,7 @@ out:
|
|||
throw std::runtime_error("Only mono streams are supported");
|
||||
uint64_t samples = serialization::u64l(header + 8);
|
||||
opus::encoder enc(opus::samplerate::r48k, false, opus::application::voice);
|
||||
enc.ctl(opus::bitrate(opus_bitrate.get()));
|
||||
enc.ctl(opus::bitrate(opus_bitrate(lsnes_instance.settings)));
|
||||
int32_t pregap = enc.ctl(opus::lookahead);
|
||||
pregap_length = pregap;
|
||||
for(uint64_t i = 0; i < samples + pregap; i += OPUS_BLOCK_SIZE) {
|
||||
|
@ -615,7 +615,8 @@ out:
|
|||
for(size_t j = bs; j < OPUS_BLOCK_SIZE; j++)
|
||||
tmp[j] = 0;
|
||||
try {
|
||||
const size_t opus_out_max2 = opus_max_bitrate.get() * OPUS_BLOCK_SIZE / 384000;
|
||||
const size_t opus_out_max2 = opus_max_bitrate(lsnes_instance.settings) *
|
||||
OPUS_BLOCK_SIZE / 384000;
|
||||
size_t r = enc.encode(tmp, OPUS_BLOCK_SIZE, tmpi, opus_out_max2);
|
||||
write(OPUS_BLOCK_SIZE / 120, tmpi, r);
|
||||
brtrack.submit(r, bs);
|
||||
|
@ -1446,7 +1447,7 @@ out:
|
|||
cblock = 120;
|
||||
else
|
||||
return; //No valid data to compress.
|
||||
const size_t opus_out_max2 = opus_max_bitrate.get() * cblock / 384000;
|
||||
const size_t opus_out_max2 = opus_max_bitrate(lsnes_instance.settings) * cblock / 384000;
|
||||
try {
|
||||
size_t c = e.encode(buf, cblock, opus_output, opus_out_max2);
|
||||
//Successfully compressed a block.
|
||||
|
@ -1529,7 +1530,7 @@ out:
|
|||
return;
|
||||
try {
|
||||
e.ctl(opus::reset);
|
||||
e.ctl(opus::bitrate(opus_bitrate.get()));
|
||||
e.ctl(opus::bitrate(opus_bitrate(lsnes_instance.settings)));
|
||||
brtrack.reset();
|
||||
uint64_t ctime;
|
||||
{
|
||||
|
@ -1621,7 +1622,7 @@ out:
|
|||
return;
|
||||
|
||||
opus::encoder oenc(opus::samplerate::r48k, false, opus::application::voice);
|
||||
oenc.ctl(opus::bitrate(opus_bitrate.get()));
|
||||
oenc.ctl(opus::bitrate(opus_bitrate(lsnes_instance.settings)));
|
||||
audioapi_resampler rin;
|
||||
audioapi_resampler rout;
|
||||
const unsigned buf_max = 6144; //These buffers better be large.
|
||||
|
|
|
@ -47,22 +47,22 @@
|
|||
void update_movie_state();
|
||||
time_t random_seed_value = 0;
|
||||
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> jukebox_dflt_binary(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> jukebox_dflt_binary(lsnes_setgrp,
|
||||
"jukebox-default-binary", "Movie‣Saving‣Saveslots binary", true);
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> movie_dflt_binary(lsnes_vset, "movie-default-binary",
|
||||
"Movie‣Saving‣Movies binary", false);
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> save_dflt_binary(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> movie_dflt_binary(lsnes_setgrp,
|
||||
"movie-default-binary", "Movie‣Saving‣Movies binary", false);
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> save_dflt_binary(lsnes_setgrp,
|
||||
"savestate-default-binary", "Movie‣Saving‣Savestates binary", false);
|
||||
|
||||
namespace
|
||||
{
|
||||
settingvar::variable<settingvar::model_int<0,999999>> advance_timeout_first(lsnes_vset, "advance-timeout",
|
||||
"Delays‣First frame advance", 500);
|
||||
settingvar::variable<settingvar::model_int<0,999999>> advance_timeout_subframe(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_int<0,999999>> advance_timeout_first(lsnes_setgrp,
|
||||
"advance-timeout", "Delays‣First frame advance", 500);
|
||||
settingvar::supervariable<settingvar::model_int<0,999999>> advance_timeout_subframe(lsnes_setgrp,
|
||||
"advance-subframe-timeout", "Delays‣Subframe advance", 100);
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> pause_on_end(lsnes_vset, "pause-on-end",
|
||||
"Movie‣Pause on end", false);
|
||||
settingvar::variable<settingvar::model_int<0,999999999>> jukebox_size(lsnes_vset, "jukebox-size",
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> pause_on_end(lsnes_setgrp,
|
||||
"pause-on-end", "Movie‣Pause on end", false);
|
||||
settingvar::supervariable<settingvar::model_int<0,999999999>> jukebox_size(lsnes_setgrp, "jukebox-size",
|
||||
"Movie‣Number of save slots", 12);
|
||||
|
||||
enum advance_mode
|
||||
|
@ -175,9 +175,9 @@ controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_allo
|
|||
if(amode == ADVANCE_SUBFRAME) {
|
||||
if(!cancel_advance) {
|
||||
if(!advanced_once)
|
||||
platform::wait(advance_timeout_first * 1000);
|
||||
platform::wait(advance_timeout_first(CORE().settings) * 1000);
|
||||
else
|
||||
platform::wait(advance_timeout_subframe * 1000);
|
||||
platform::wait(advance_timeout_subframe(CORE().settings) * 1000);
|
||||
advanced_once = true;
|
||||
}
|
||||
if(cancel_advance) {
|
||||
|
@ -205,9 +205,9 @@ controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_allo
|
|||
if(!cancel_advance) {
|
||||
uint64_t wait = 0;
|
||||
if(!advanced_once)
|
||||
wait = advance_timeout_first * 1000;
|
||||
wait = advance_timeout_first(CORE().settings) * 1000;
|
||||
else if(amode == ADVANCE_SUBFRAME)
|
||||
wait = advance_timeout_subframe * 1000;
|
||||
wait = advance_timeout_subframe(CORE().settings) * 1000;
|
||||
else
|
||||
wait = to_wait_frame(get_utime());
|
||||
platform::wait(wait);
|
||||
|
@ -220,7 +220,7 @@ controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_allo
|
|||
}
|
||||
platform::set_paused(amode == ADVANCE_PAUSE);
|
||||
} else if(amode == ADVANCE_AUTO && CORE().mlogic.get_movie().readonly_mode() &&
|
||||
pause_on_end && !stop_at_frame_active) {
|
||||
pause_on_end(CORE().settings) && !stop_at_frame_active) {
|
||||
if(CORE().mlogic.get_movie().get_current_frame() ==
|
||||
CORE().mlogic.get_movie().get_frame_count()) {
|
||||
stop_at_frame_active = false;
|
||||
|
@ -286,16 +286,18 @@ namespace
|
|||
|
||||
struct jukebox_size_listener : public settingvar::listener
|
||||
{
|
||||
jukebox_size_listener() { lsnes_vset.add_listener(*this); }
|
||||
~jukebox_size_listener() throw() {lsnes_vset.remove_listener(*this); };
|
||||
void on_setting_change(settingvar::group& grp, const settingvar::base& val)
|
||||
jukebox_size_listener(settingvar::group& _grp) : grp(_grp) { grp.add_listener(*this); }
|
||||
~jukebox_size_listener() throw() { grp.remove_listener(*this); };
|
||||
void on_setting_change(settingvar::group& _grp, const settingvar::base& val)
|
||||
{
|
||||
if(val.get_iname() == "jukebox-size") {
|
||||
if(save_jukebox_pointer >= (size_t)jukebox_size)
|
||||
if(save_jukebox_pointer >= (size_t)jukebox_size(_grp))
|
||||
save_jukebox_pointer = 0;
|
||||
}
|
||||
update_movie_state();
|
||||
}
|
||||
private:
|
||||
settingvar::group& grp;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -353,7 +355,7 @@ void update_movie_state()
|
|||
else
|
||||
_status.mode = 'F';
|
||||
}
|
||||
if(jukebox_size > 0) {
|
||||
if(jukebox_size(CORE().settings) > 0) {
|
||||
_status.saveslot_valid = true;
|
||||
int tmp = -1;
|
||||
std::string sfilen = translate_name_mprefix(save_jukebox_name(save_jukebox_pointer), tmp, -1);
|
||||
|
@ -593,13 +595,14 @@ namespace
|
|||
command::fnptr<> save_jukebox_prev(lsnes_cmds, "cycle-jukebox-backward", "Cycle save jukebox backwards",
|
||||
"Syntax: cycle-jukebox-backward\nCycle save jukebox backwards\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
size_t jbsize = jukebox_size(CORE().settings);
|
||||
if(jbsize == 0)
|
||||
return;
|
||||
if(save_jukebox_pointer == 0)
|
||||
save_jukebox_pointer = jukebox_size - 1;
|
||||
save_jukebox_pointer = jbsize - 1;
|
||||
else
|
||||
save_jukebox_pointer--;
|
||||
if(save_jukebox_pointer >= (size_t)jukebox_size)
|
||||
if(save_jukebox_pointer >= (size_t)jbsize)
|
||||
save_jukebox_pointer = 0;
|
||||
update_movie_state();
|
||||
});
|
||||
|
@ -607,13 +610,14 @@ namespace
|
|||
command::fnptr<> save_jukebox_next(lsnes_cmds, "cycle-jukebox-forward", "Cycle save jukebox forwards",
|
||||
"Syntax: cycle-jukebox-forward\nCycle save jukebox forwards\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
size_t jbsize = jukebox_size(CORE().settings);
|
||||
if(jbsize == 0)
|
||||
return;
|
||||
if(save_jukebox_pointer + 1 >= (size_t)jukebox_size)
|
||||
if(save_jukebox_pointer + 1 >= (size_t)jbsize)
|
||||
save_jukebox_pointer = 0;
|
||||
else
|
||||
save_jukebox_pointer++;
|
||||
if(save_jukebox_pointer >= (size_t)jukebox_size)
|
||||
if(save_jukebox_pointer >= (size_t)jbsize)
|
||||
save_jukebox_pointer = 0;
|
||||
update_movie_state();
|
||||
});
|
||||
|
@ -624,7 +628,7 @@ namespace
|
|||
if(!regex_match("[1-9][0-9]{0,8}", args))
|
||||
throw std::runtime_error("Bad slot number");
|
||||
uint32_t slot = parse_value<uint32_t>(args);
|
||||
if(slot >= (size_t)jukebox_size)
|
||||
if(slot >= (size_t)jukebox_size(CORE().settings))
|
||||
throw std::runtime_error("Bad slot number");
|
||||
save_jukebox_pointer = slot - 1;
|
||||
update_movie_state();
|
||||
|
@ -633,7 +637,7 @@ namespace
|
|||
command::fnptr<> load_jukebox(lsnes_cmds, "load-jukebox", "Load save from jukebox",
|
||||
"Syntax: load-jukebox\nLoad save from jukebox\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
if(jukebox_size(CORE().settings) == 0)
|
||||
throw std::runtime_error("No slot selected");
|
||||
mark_pending_load(save_jukebox_name(save_jukebox_pointer), LOAD_STATE_CURRENT);
|
||||
});
|
||||
|
@ -641,7 +645,7 @@ namespace
|
|||
command::fnptr<> load_jukebox_readwrite(lsnes_cmds, "load-jukebox-readwrite", "Load save from jukebox in"
|
||||
" read-write mode", "Syntax: load-jukebox-readwrite\nLoad save from jukebox in read-write mode\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
if(jukebox_size(CORE().settings) == 0)
|
||||
throw std::runtime_error("No slot selected");
|
||||
mark_pending_load(save_jukebox_name(save_jukebox_pointer), LOAD_STATE_RW);
|
||||
});
|
||||
|
@ -649,7 +653,7 @@ namespace
|
|||
command::fnptr<> load_jukebox_readonly(lsnes_cmds, "load-jukebox-readonly", "Load save from jukebox in "
|
||||
"read-only mode", "Syntax: load-jukebox-readonly\nLoad save from jukebox in read-only mode\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
if(jukebox_size(CORE().settings) == 0)
|
||||
throw std::runtime_error("No slot selected");
|
||||
mark_pending_load(save_jukebox_name(save_jukebox_pointer), LOAD_STATE_RO);
|
||||
});
|
||||
|
@ -657,7 +661,7 @@ namespace
|
|||
command::fnptr<> load_jukebox_preserve(lsnes_cmds, "load-jukebox-preserve", "Load save from jukebox, "
|
||||
"preserving input", "Syntax: load-jukebox-preserve\nLoad save from jukebox, preserving input\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
if(jukebox_size(CORE().settings) == 0)
|
||||
throw std::runtime_error("No slot selected");
|
||||
mark_pending_load(save_jukebox_name(save_jukebox_pointer), LOAD_STATE_PRESERVE);
|
||||
});
|
||||
|
@ -665,7 +669,7 @@ namespace
|
|||
command::fnptr<> load_jukebox_movie(lsnes_cmds, "load-jukebox-movie", "Load save from jukebox as movie",
|
||||
"Syntax: load-jukebox-movie\nLoad save from jukebox as movie\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
if(jukebox_size(CORE().settings) == 0)
|
||||
throw std::runtime_error("No slot selected");
|
||||
mark_pending_load(save_jukebox_name(save_jukebox_pointer), LOAD_STATE_MOVIE);
|
||||
});
|
||||
|
@ -673,7 +677,7 @@ namespace
|
|||
command::fnptr<> save_jukebox_c(lsnes_cmds, "save-jukebox", "Save save to jukebox",
|
||||
"Syntax: save-jukebox\nSave save to jukebox\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
if(jukebox_size(CORE().settings) == 0)
|
||||
throw std::runtime_error("No slot selected");
|
||||
mark_pending_save(save_jukebox_name(save_jukebox_pointer), SAVE_STATE, -1);
|
||||
});
|
||||
|
@ -873,20 +877,20 @@ namespace
|
|||
|
||||
command::fnptr<> tpon(lsnes_cmds, "toggle-pause-on-end", "Toggle pause on end", "Toggle pause on end\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
bool tmp = pause_on_end;
|
||||
pause_on_end.set(!tmp);
|
||||
bool tmp = pause_on_end(CORE().settings);
|
||||
pause_on_end(CORE().settings, !tmp);
|
||||
messages << "Pause-on-end is now " << (tmp ? "OFF" : "ON") << std::endl;
|
||||
});
|
||||
|
||||
command::fnptr<> spon(lsnes_cmds, "set-pause-on-end", "Set pause on end", "Set pause on end\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
pause_on_end.set(true);
|
||||
pause_on_end(CORE().settings, true);
|
||||
messages << "Pause-on-end is now ON" << std::endl;
|
||||
});
|
||||
|
||||
command::fnptr<> cpon(lsnes_cmds, "clear-pause-on-end", "Clear pause on end", "Clear pause on end\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
pause_on_end.set(false);
|
||||
pause_on_end(CORE().settings, false);
|
||||
messages << "Pause-on-end is now OFF" << std::endl;
|
||||
});
|
||||
|
||||
|
@ -1226,7 +1230,7 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
|
|||
//Basic initialization.
|
||||
dispatch_set_error_streams(&messages.getstream());
|
||||
emulation_thread = threads::this_id();
|
||||
jukebox_size_listener jlistener;
|
||||
jukebox_size_listener jlistener(CORE().settings);
|
||||
CORE().commentary.init();
|
||||
init_special_screens();
|
||||
our_rom = rom;
|
||||
|
|
|
@ -31,9 +31,9 @@ void update_movie_state();
|
|||
|
||||
namespace
|
||||
{
|
||||
settingvar::variable<settingvar::model_int<0, 9>> savecompression(lsnes_vset, "savecompression",
|
||||
settingvar::supervariable<settingvar::model_int<0, 9>> savecompression(lsnes_setgrp, "savecompression",
|
||||
"Movie‣Saving‣Compression", 7);
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> readonly_load_preserves(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> readonly_load_preserves(lsnes_setgrp,
|
||||
"preserve_on_readonly_load", "Movie‣Loading‣Preserve on readonly load", true);
|
||||
threads::lock mprefix_lock;
|
||||
std::string mprefix;
|
||||
|
@ -140,7 +140,7 @@ std::string translate_name_mprefix(std::string original, int& binary, int save)
|
|||
regex_results r = regex("\\$SLOT:(.*)", original);
|
||||
if(r) {
|
||||
if(binary < 0)
|
||||
binary = jukebox_dflt_binary ? 1 : 0;
|
||||
binary = jukebox_dflt_binary(lsnes_instance.settings) ? 1 : 0;
|
||||
if(p) {
|
||||
uint64_t branch = p->get_current_branch();
|
||||
std::string branch_str;
|
||||
|
@ -161,7 +161,8 @@ std::string translate_name_mprefix(std::string original, int& binary, int save)
|
|||
}
|
||||
} else {
|
||||
if(binary < 0)
|
||||
binary = (save ? save_dflt_binary : movie_dflt_binary) ? 1 : 0;
|
||||
binary = (save ? save_dflt_binary(lsnes_instance.settings) :
|
||||
movie_dflt_binary(lsnes_instance.settings)) ? 1 : 0;
|
||||
return original;
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +227,8 @@ void do_save_state(const std::string& filename, int binary) throw(std::bad_alloc
|
|||
target.authors = prj->authors;
|
||||
}
|
||||
target.active_macros = controls.get_macro_frames();
|
||||
target.save(filename2, savecompression, binary > 0, lsnes_instance.mlogic.get_rrdata());
|
||||
target.save(filename2, savecompression(CORE().settings), binary > 0,
|
||||
lsnes_instance.mlogic.get_rrdata());
|
||||
uint64_t took = get_utime() - origtime;
|
||||
std::string kind = (binary > 0) ? "(binary format)" : "(zip format)";
|
||||
messages << "Saved state " << kind << " '" << filename2 << "' in " << took << " microseconds."
|
||||
|
@ -267,7 +269,8 @@ void do_save_movie(const std::string& filename, int binary) throw(std::bad_alloc
|
|||
target.authors = prj->authors;
|
||||
}
|
||||
target.active_macros.clear();
|
||||
target.save(filename2, savecompression, binary > 0, lsnes_instance.mlogic.get_rrdata());
|
||||
target.save(filename2, savecompression(lsnes_instance.settings), binary > 0,
|
||||
lsnes_instance.mlogic.get_rrdata());
|
||||
uint64_t took = get_utime() - origtime;
|
||||
std::string kind = (binary > 0) ? "(binary format)" : "(zip format)";
|
||||
messages << "Saved movie " << kind << " '" << filename2 << "' in " << took << " microseconds."
|
||||
|
@ -644,7 +647,7 @@ void do_load_state(struct moviefile& _movie, int lmode, bool& used)
|
|||
warn_roms(_movie, our_rom, will_load_state);
|
||||
|
||||
//In certain conditions, trun LOAD_STATE_CURRENT into LOAD_STATE_PRESERVE.
|
||||
if(lmode == LOAD_STATE_CURRENT && current_mode && readonly_load_preserves)
|
||||
if(lmode == LOAD_STATE_CURRENT && current_mode && readonly_load_preserves(CORE().settings))
|
||||
lmode = LOAD_STATE_PRESERVE;
|
||||
//If movie file changes, turn LOAD_STATE_CURRENT into LOAD_STATE_RO
|
||||
if(lmode == LOAD_STATE_CURRENT && lsnes_instance.mlogic.get_mfile().projectid != _movie.projectid)
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace
|
|||
{
|
||||
uint16_t null_cover_fbmem[512 * 448];
|
||||
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> savestate_no_check(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> savestate_no_check(lsnes_setgrp,
|
||||
"dont-check-savestate", "Movie‣Loading‣Don't check savestates", false);
|
||||
|
||||
//Framebuffer.
|
||||
|
@ -675,7 +675,7 @@ void loaded_rom::load_core_state(const std::vector<char>& buf, bool nochecksum)
|
|||
|
||||
if(buf.size() < 32)
|
||||
throw std::runtime_error("Savestate corrupt");
|
||||
if(!savestate_no_check) {
|
||||
if(!savestate_no_check(CORE().settings)) {
|
||||
unsigned char tmp[32];
|
||||
#ifdef USE_LIBGCRYPT_SHA256
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA256, tmp, &buf[0], buf.size() - 32);
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#include "core/command.hpp"
|
||||
#include "core/settings.hpp"
|
||||
|
||||
settingvar::group lsnes_vset;
|
||||
settingvar::set lsnes_setgrp;
|
||||
|
||||
namespace
|
||||
{
|
||||
settingvar::variable<settingvar::model_path> rompath(lsnes_vset, "rompath", "Paths‣ROMs", "");
|
||||
settingvar::variable<settingvar::model_path> moviepath(lsnes_vset, "moviepath", "Paths‣Movies", "");
|
||||
settingvar::variable<settingvar::model_path> firmwarepath(lsnes_vset, "firmwarepath", "Paths‣Firmware", "");
|
||||
settingvar::variable<settingvar::model_path> slotpath(lsnes_vset, "slotpath", "Paths‣Save slots", "");
|
||||
settingvar::supervariable<settingvar::model_path> rompath(lsnes_setgrp, "rompath", "Paths‣ROMs", "");
|
||||
settingvar::supervariable<settingvar::model_path> moviepath(lsnes_setgrp, "moviepath", "Paths‣Movies", "");
|
||||
settingvar::supervariable<settingvar::model_path> firmwarepath(lsnes_setgrp, "firmwarepath",
|
||||
"Paths‣Firmware", "");
|
||||
settingvar::supervariable<settingvar::model_path> slotpath(lsnes_setgrp, "slotpath", "Paths‣Save slots", "");
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "core/dispatch.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "core/framebuffer.hpp"
|
||||
#include "core/instance.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "interface/callbacks.hpp"
|
||||
#include "interface/cover.hpp"
|
||||
|
@ -51,9 +52,9 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> output_native(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> output_native(lsnes_setgrp,
|
||||
"gambatte-native-sound", "Gambatte‣Sound Output at native rate", false);
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> gbchawk_timings(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> gbchawk_timings(lsnes_setgrp,
|
||||
"gambatte-gbchawk-fuckup", "Gambatte‣Use Fucked up GBCHawk timings", false);
|
||||
|
||||
bool do_reset_flag = false;
|
||||
|
@ -560,7 +561,7 @@ namespace
|
|||
std::pair<uint32_t, uint32_t> c_video_rate() { return std::make_pair(262144, 4389); }
|
||||
double c_get_PAR() { return 1.0; }
|
||||
std::pair<uint32_t, uint32_t> c_audio_rate() {
|
||||
if(output_native)
|
||||
if(output_native(CORE().settings))
|
||||
return std::make_pair(2097152, 1);
|
||||
else
|
||||
return std::make_pair(32768, 1);
|
||||
|
@ -636,8 +637,8 @@ namespace
|
|||
void c_emulate() {
|
||||
if(!internal_rom)
|
||||
return;
|
||||
bool timings_fucked_up = gbchawk_timings;
|
||||
bool native_rate = output_native;
|
||||
bool timings_fucked_up = gbchawk_timings(CORE().settings);
|
||||
bool native_rate = output_native(CORE().settings);
|
||||
int16_t reset = ecore_callbacks->get_input(0, 0, 1);
|
||||
if(reset) {
|
||||
instance->reset();
|
||||
|
|
|
@ -165,6 +165,7 @@ keyboard& mapper::get_keyboard() throw()
|
|||
mapper::mapper(keyboard& _kbd, command::group& _domain) throw(std::bad_alloc)
|
||||
: _listener(*this), kbd(_kbd), domain(_domain)
|
||||
{
|
||||
dtor_running = false;
|
||||
register_queue<mapper, invbind>::do_ready(*this, true);
|
||||
register_queue<mapper, ctrlrkey>::do_ready(*this, true);
|
||||
}
|
||||
|
|
|
@ -1,30 +1,58 @@
|
|||
#include "settingvar.hpp"
|
||||
#include "register-queue.hpp"
|
||||
#include "stateobject.hpp"
|
||||
|
||||
namespace settingvar
|
||||
{
|
||||
namespace
|
||||
{
|
||||
threads::rlock* global_lock;
|
||||
typedef register_queue<group, base> regqueue_t;
|
||||
|
||||
struct set_internal
|
||||
{
|
||||
std::map<std::string, superbase*> supervars;
|
||||
std::set<set_listener*> callbacks;
|
||||
};
|
||||
|
||||
typedef stateobject::type<set, set_internal> set_internal_t;
|
||||
}
|
||||
|
||||
threads::rlock& get_setting_lock()
|
||||
{
|
||||
if(!global_lock) global_lock = new threads::rlock;
|
||||
return *global_lock;
|
||||
}
|
||||
|
||||
listener::~listener() throw()
|
||||
{
|
||||
}
|
||||
|
||||
group::group() throw(std::bad_alloc)
|
||||
set_listener::~set_listener() throw()
|
||||
{
|
||||
}
|
||||
|
||||
group::group() throw(std::bad_alloc)
|
||||
: _listener(*this)
|
||||
{
|
||||
dtor_running = false;
|
||||
regqueue_t::do_ready(*this, true);
|
||||
}
|
||||
|
||||
group::~group() throw()
|
||||
{
|
||||
dtor_running = true;
|
||||
threads::arlock h(get_setting_lock());
|
||||
regqueue_t::do_ready(*this, false);
|
||||
for(auto i : settings)
|
||||
i.second->group_died();
|
||||
for(auto i : sets_listened)
|
||||
i->drop_callback(_listener);
|
||||
}
|
||||
|
||||
std::set<std::string> group::get_settings_set() throw(std::bad_alloc)
|
||||
{
|
||||
threads::alock(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
std::set<std::string> x;
|
||||
for(auto i : settings)
|
||||
x.insert(i.first);
|
||||
|
@ -33,7 +61,7 @@ std::set<std::string> group::get_settings_set() throw(std::bad_alloc)
|
|||
|
||||
base& group::operator[](const std::string& name)
|
||||
{
|
||||
threads::alock(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
if(!settings.count(name))
|
||||
throw std::runtime_error("No such setting");
|
||||
return *settings[name];
|
||||
|
@ -43,7 +71,7 @@ void group::fire_listener(base& var) throw()
|
|||
{
|
||||
std::set<listener*> l;
|
||||
{
|
||||
threads::alock h(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
for(auto i : listeners)
|
||||
l.insert(i);
|
||||
}
|
||||
|
@ -56,38 +84,187 @@ void group::fire_listener(base& var) throw()
|
|||
|
||||
void group::add_listener(struct listener& listener) throw(std::bad_alloc)
|
||||
{
|
||||
threads::alock(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
listeners.insert(&listener);
|
||||
}
|
||||
|
||||
void group::remove_listener(struct listener& listener) throw(std::bad_alloc)
|
||||
{
|
||||
threads::alock(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
listeners.erase(&listener);
|
||||
}
|
||||
|
||||
void group::do_register(const std::string& name, base& _setting) throw(std::bad_alloc)
|
||||
{
|
||||
threads::alock h(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
settings[name] = &_setting;
|
||||
}
|
||||
|
||||
void group::do_unregister(const std::string& name, base* dummy) throw(std::bad_alloc)
|
||||
{
|
||||
threads::alock h(lock);
|
||||
threads::arlock h(get_setting_lock());
|
||||
settings.erase(name);
|
||||
}
|
||||
|
||||
base::base(group& _group, const std::string& _iname, const std::string& _hname)
|
||||
throw(std::bad_alloc)
|
||||
: sgroup(_group), iname(_iname), hname(_hname)
|
||||
void group::add_set(set& s) throw(std::bad_alloc)
|
||||
{
|
||||
regqueue_t::do_register(sgroup, iname, *this);
|
||||
threads::arlock u(get_setting_lock());
|
||||
if(sets_listened.count(&s)) return;
|
||||
try {
|
||||
sets_listened.insert(&s);
|
||||
s.add_callback(_listener);
|
||||
} catch(...) {
|
||||
sets_listened.erase(&s);
|
||||
}
|
||||
}
|
||||
|
||||
void group::drop_set(set& s)
|
||||
{
|
||||
threads::arlock h(get_setting_lock());
|
||||
//Drop the callback. This unregisters all.
|
||||
s.drop_callback(_listener);
|
||||
sets_listened.erase(&s);
|
||||
}
|
||||
|
||||
group::xlistener::xlistener(group& _grp)
|
||||
: grp(_grp)
|
||||
{
|
||||
}
|
||||
|
||||
group::xlistener::~xlistener()
|
||||
{
|
||||
}
|
||||
|
||||
void group::xlistener::create(set& s, const std::string& name, superbase& sb)
|
||||
{
|
||||
threads::arlock h(get_setting_lock());
|
||||
sb.make(grp);
|
||||
}
|
||||
|
||||
void group::xlistener::destroy(set& s, const std::string& name)
|
||||
{
|
||||
threads::arlock h(get_setting_lock());
|
||||
if(grp.dtor_running) return;
|
||||
grp.settings.erase(name);
|
||||
}
|
||||
|
||||
void group::xlistener::kill(set& s)
|
||||
{
|
||||
threads::arlock h(get_setting_lock());
|
||||
if(grp.dtor_running) return;
|
||||
grp.sets_listened.erase(&s);
|
||||
}
|
||||
|
||||
set::set()
|
||||
{
|
||||
}
|
||||
|
||||
set::~set()
|
||||
{
|
||||
auto state = set_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
threads::arlock u(get_setting_lock());
|
||||
//Call all DCBs on all factories.
|
||||
for(auto i : state->supervars)
|
||||
for(auto j : state->callbacks)
|
||||
j->destroy(*this, i.first);
|
||||
//Call all TCBs.
|
||||
for(auto j : state->callbacks)
|
||||
j->kill(*this);
|
||||
//Notify all factories that base set died.
|
||||
for(auto i : state->supervars)
|
||||
i.second->set_died();
|
||||
//We assume factories look after themselves, so we don't destroy those.
|
||||
set_internal_t::clear(this);
|
||||
}
|
||||
|
||||
void set::do_register(const std::string& name, superbase& info)
|
||||
{
|
||||
threads::arlock u(get_setting_lock());
|
||||
auto& state = set_internal_t::get(this);
|
||||
if(state.supervars.count(name)) {
|
||||
std::cerr << "WARNING: Command collision for " << name << "!" << std::endl;
|
||||
return;
|
||||
}
|
||||
state.supervars[name] = &info;
|
||||
//Call all CCBs on this.
|
||||
for(auto i : state.callbacks)
|
||||
i->create(*this, name, info);
|
||||
}
|
||||
|
||||
void set::do_unregister(const std::string& name, superbase& info)
|
||||
{
|
||||
threads::arlock u(get_setting_lock());
|
||||
auto state = set_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
if(!state->supervars.count(name) || state->supervars[name] != &info) return; //Not this.
|
||||
state->supervars.erase(name);
|
||||
//Call all DCBs on this.
|
||||
for(auto i : state->callbacks)
|
||||
i->destroy(*this, name);
|
||||
}
|
||||
|
||||
void set::add_callback(set_listener& listener) throw(std::bad_alloc)
|
||||
{
|
||||
threads::arlock u(get_setting_lock());
|
||||
auto& state = set_internal_t::get(this);
|
||||
state.callbacks.insert(&listener);
|
||||
//To avoid races, call CCBs on all factories for this.
|
||||
for(auto j : state.supervars)
|
||||
listener.create(*this, j.first, *j.second);
|
||||
}
|
||||
|
||||
void set::drop_callback(set_listener& listener)
|
||||
{
|
||||
threads::arlock u(get_setting_lock());
|
||||
auto state = set_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
if(state->callbacks.count(&listener)) {
|
||||
//To avoid races, call DCBs on all factories for this.
|
||||
for(auto j : state->supervars)
|
||||
listener.destroy(*this, j.first);
|
||||
state->callbacks.erase(&listener);
|
||||
}
|
||||
}
|
||||
|
||||
base::base(group& _group, const std::string& _iname, const std::string& _hname, bool dynamic)
|
||||
throw(std::bad_alloc)
|
||||
: sgroup(&_group), iname(_iname), hname(_hname), is_dynamic(dynamic)
|
||||
{
|
||||
regqueue_t::do_register(*sgroup, iname, *this);
|
||||
}
|
||||
|
||||
base::~base() throw()
|
||||
{
|
||||
regqueue_t::do_unregister(sgroup, iname);
|
||||
threads::arlock u(get_setting_lock());
|
||||
if(sgroup)
|
||||
regqueue_t::do_unregister(*sgroup, iname);
|
||||
}
|
||||
|
||||
void base::group_died()
|
||||
{
|
||||
threads::arlock u(get_setting_lock());
|
||||
sgroup = NULL;
|
||||
if(is_dynamic) delete this;
|
||||
}
|
||||
|
||||
void superbase::_superbase(set& _s, const std::string& _iname) throw(std::bad_alloc)
|
||||
{
|
||||
s = &_s;
|
||||
iname = _iname;
|
||||
s->do_register(iname, *this);
|
||||
}
|
||||
|
||||
superbase::~superbase() throw()
|
||||
{
|
||||
threads::arlock u(get_setting_lock());
|
||||
if(s)
|
||||
s->do_unregister(iname, *this);
|
||||
}
|
||||
|
||||
void superbase::set_died()
|
||||
{
|
||||
s = NULL;
|
||||
}
|
||||
|
||||
cache::cache(group& _grp)
|
||||
|
@ -116,13 +293,13 @@ void cache::set(const std::string& name, const std::string& value, bool allow_in
|
|||
{
|
||||
try {
|
||||
grp[name].str(value);
|
||||
threads::alock h(lock);
|
||||
threads::arlock u(get_setting_lock());
|
||||
badcache.erase(name);
|
||||
} catch(std::bad_alloc& e) {
|
||||
throw;
|
||||
} catch(std::exception& e) {
|
||||
if(allow_invalid) {
|
||||
threads::alock h(lock);
|
||||
threads::arlock u(get_setting_lock());
|
||||
badcache[name] = value;
|
||||
} else
|
||||
throw;
|
||||
|
|
|
@ -175,7 +175,7 @@ namespace
|
|||
threads::thread* emulation_thread;
|
||||
bool status_updated = false;
|
||||
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> background_audio(lsnes_vset,
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> background_audio(lsnes_instance.settings,
|
||||
"background-audio", "GUI‣Enable background audio", true);
|
||||
|
||||
class _status_timer : public wxTimer
|
||||
|
@ -1412,7 +1412,8 @@ namespace
|
|||
p.types.push_back(filedialog_type_entry("Savestates [all branches]", "*." + ext +
|
||||
";*." + ext + ".backup", ext));
|
||||
}
|
||||
p.default_type = save ? (state ? save_dflt_binary : movie_dflt_binary) : 0;
|
||||
p.default_type = save ? (state ? save_dflt_binary(lsnes_instance.settings) :
|
||||
movie_dflt_binary(lsnes_instance.settings)) : 0;
|
||||
return p;
|
||||
}
|
||||
std::pair<std::string, std::string> output(const filedialog_output_params& p, bool save) const
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace
|
|||
};
|
||||
|
||||
wxeditor_esettings_advanced::wxeditor_esettings_advanced(wxWindow* parent)
|
||||
: settings_tab(parent), _listener(lsnes_vset, *this)
|
||||
: settings_tab(parent), _listener(lsnes_instance.settings, *this)
|
||||
{
|
||||
wxSizer* top_s = new wxBoxSizer(wxVERTICAL);
|
||||
SetSizer(top_s);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "library/minmax.hpp"
|
||||
#include "library/workthread.hpp"
|
||||
#include "core/misc.hpp"
|
||||
#include "core/instance.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "core/moviedata.hpp"
|
||||
#include "core/moviefile.hpp"
|
||||
|
@ -82,30 +83,31 @@ namespace
|
|||
return 48000;
|
||||
}
|
||||
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> dump_large(lsnes_vset, "avi-large",
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> dump_large(lsnes_setgrp, "avi-large",
|
||||
"AVI‣Large dump", false);
|
||||
settingvar::variable<settingvar::model_int<0, 32>> fixed_xfact(lsnes_vset, "avi-xfactor",
|
||||
settingvar::supervariable<settingvar::model_int<0, 32>> fixed_xfact(lsnes_setgrp, "avi-xfactor",
|
||||
"AVI‣Fixed X factor", 0);
|
||||
settingvar::variable<settingvar::model_int<0, 32>> fixed_yfact(lsnes_vset, "avi-yfactor",
|
||||
settingvar::supervariable<settingvar::model_int<0, 32>> fixed_yfact(lsnes_setgrp, "avi-yfactor",
|
||||
"AVI‣Fixed Y factor", 0);
|
||||
settingvar::variable<settingvar::model_int<0, 8191>> dtb(lsnes_vset, "avi-top-border", "AVI‣Top padding", 0);
|
||||
settingvar::variable<settingvar::model_int<0, 8191>> dbb(lsnes_vset, "avi-bottom-border",
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> dtb(lsnes_setgrp, "avi-top-border",
|
||||
"AVI‣Top padding", 0);
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> dbb(lsnes_setgrp, "avi-bottom-border",
|
||||
"AVI‣Bottom padding", 0);
|
||||
settingvar::variable<settingvar::model_int<0, 8191>> dlb(lsnes_vset, "avi-left-border",
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> dlb(lsnes_setgrp, "avi-left-border",
|
||||
"AVI‣Left padding", 0);
|
||||
settingvar::variable<settingvar::model_int<0, 8191>> drb(lsnes_vset, "avi-right-border", "AVI‣Right padding",
|
||||
0);
|
||||
settingvar::variable<settingvar::model_int<0, 999999999>> max_frames_per_segment(lsnes_vset, "avi-maxframes",
|
||||
"AVI‣Max frames per segment", 0);
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> drb(lsnes_setgrp, "avi-right-border",
|
||||
"AVI‣Right padding", 0);
|
||||
settingvar::supervariable<settingvar::model_int<0, 999999999>> max_frames_per_segment(lsnes_setgrp,
|
||||
"avi-maxframes", "AVI‣Max frames per segment", 0);
|
||||
#ifdef WITH_SECRET_RABBIT_CODE
|
||||
settingvar::enumeration soundrates {"nearest-common", "round-down", "round-up", "multiply",
|
||||
"High quality 44.1kHz", "High quality 48kHz"};
|
||||
settingvar::variable<settingvar::model_enumerated<&soundrates>> soundrate_setting(lsnes_vset, "avi-soundrate",
|
||||
"AVI‣Sound mode", 5);
|
||||
settingvar::supervariable<settingvar::model_enumerated<&soundrates>> soundrate_setting(lsnes_setgrp,
|
||||
"avi-soundrate", "AVI‣Sound mode", 5);
|
||||
#else
|
||||
settingvar::enumeration soundrates {"nearest-common", "round-down", "round-up", "multiply"};
|
||||
settingvar::variable<settingvar::model_enumerated<&soundrates>> soundrate_setting(lsnes_vset, "avi-soundrate",
|
||||
"AVI‣Sound mode", 2);
|
||||
settingvar::supervariable<settingvar::model_enumerated<&soundrates>> soundrate_setting(lsnes_setgrp,
|
||||
"avi-soundrate", "AVI‣Sound mode", 2);
|
||||
#endif
|
||||
|
||||
std::pair<avi_video_codec_type*, avi_audio_codec_type*> find_codecs(const std::string& mode)
|
||||
|
@ -332,17 +334,18 @@ again:
|
|||
: information_dispatch("dump-avi-int")
|
||||
{
|
||||
enable_send_sound();
|
||||
unsigned srate_setting = soundrate_setting(CORE().settings);
|
||||
chans = info.audio_chans = 2;
|
||||
soundrate = get_sound_rate();
|
||||
audio_record_rate = info.sample_rate = get_rate(soundrate.first, soundrate.second,
|
||||
soundrate_setting);
|
||||
srate_setting);
|
||||
worker = new avi_worker(info);
|
||||
soxdumper = new sox_dumper(info.prefix + ".sox", static_cast<double>(soundrate.first) /
|
||||
soundrate.second, 2);
|
||||
dcounter = 0;
|
||||
have_dumped_frame = false;
|
||||
resampler_w = NULL;
|
||||
if(soundrate_setting == 4 || soundrate_setting == 5) {
|
||||
if(srate_setting == 4 || srate_setting == 5) {
|
||||
double ratio = 1.0 * audio_record_rate * soundrate.second / soundrate.first;
|
||||
sbuffer_fill = 0;
|
||||
sbuffer.resize(RESAMPLE_BUFFER * chans);
|
||||
|
@ -361,14 +364,17 @@ again:
|
|||
void on_frame(struct framebuffer::raw& _frame, uint32_t fps_n, uint32_t fps_d)
|
||||
{
|
||||
uint32_t hscl = 1, vscl = 1;
|
||||
if(fixed_xfact != 0 && fixed_yfact != 0) {
|
||||
hscl = fixed_xfact;
|
||||
vscl = fixed_yfact;
|
||||
} else if(dump_large) {
|
||||
unsigned fxfact = fixed_xfact(CORE().settings);
|
||||
unsigned fyfact = fixed_yfact(CORE().settings);
|
||||
if(fxfact != 0 && fyfact != 0) {
|
||||
hscl = fxfact;
|
||||
vscl = fyfact;
|
||||
} else if(dump_large(CORE().settings)) {
|
||||
rpair(hscl, vscl) = our_rom.rtype->get_scale_factors(_frame.get_width(),
|
||||
_frame.get_height());
|
||||
}
|
||||
if(!render_video_hud(dscr, _frame, hscl, vscl, dlb, dtb, drb, dbb, waitfn)) {
|
||||
if(!render_video_hud(dscr, _frame, hscl, vscl, dlb(CORE().settings), dtb(CORE().settings),
|
||||
drb(CORE().settings), dbb(CORE().settings), waitfn)) {
|
||||
akill += killed_audio_length(fps_n, fps_d, akillfrac);
|
||||
return;
|
||||
}
|
||||
|
@ -504,7 +510,7 @@ again:
|
|||
struct avi_info info;
|
||||
info.audio_chans = 2;
|
||||
info.sample_rate = 32000;
|
||||
info.max_frames = max_frames_per_segment;
|
||||
info.max_frames = max_frames_per_segment(CORE().settings);
|
||||
info.prefix = prefix;
|
||||
rpair(vcodec, acodec) = find_codecs(mode);
|
||||
info.vcodec = vcodec->get_instance();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "video/avi/codec.hpp"
|
||||
#include "core/instance.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "library/zlibstream.hpp"
|
||||
#include <limits>
|
||||
|
@ -10,9 +11,9 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
settingvar::variable<settingvar::model_int<0,9>> clvl(lsnes_vset, "avi-cscd-compression",
|
||||
settingvar::supervariable<settingvar::model_int<0,9>> clvl(lsnes_setgrp, "avi-cscd-compression",
|
||||
"AVI‣CSCD‣Compression", 7);
|
||||
settingvar::variable<settingvar::model_int<0,999999999>> kint(lsnes_vset, "avi-cscd-keyint",
|
||||
settingvar::supervariable<settingvar::model_int<0,999999999>> kint(lsnes_setgrp, "avi-cscd-keyint",
|
||||
"AVI‣CSCD‣Keyframe interval", 0);
|
||||
|
||||
struct avi_codec_cscd : public avi_video_codec
|
||||
|
@ -135,5 +136,7 @@ namespace
|
|||
}
|
||||
|
||||
avi_video_codec_type rgb("cscd", "Camstudio video codec",
|
||||
[]() -> avi_video_codec* { return new avi_codec_cscd(clvl, kint);});
|
||||
[]() -> avi_video_codec* {
|
||||
return new avi_codec_cscd(clvl(CORE().settings), kint(CORE().settings));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "video/avi/codec.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
#include "library/zlibstream.hpp"
|
||||
#include "core/instance.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include <limits>
|
||||
#include <cassert>
|
||||
|
@ -14,9 +15,9 @@ const void* check;
|
|||
|
||||
namespace
|
||||
{
|
||||
settingvar::variable<settingvar::model_int<0,9>> clvl(lsnes_vset, "avi-tscc-compression",
|
||||
settingvar::supervariable<settingvar::model_int<0,9>> clvl(lsnes_setgrp, "avi-tscc-compression",
|
||||
"AVI‣TSCC‣Compression", 7);
|
||||
settingvar::variable<settingvar::model_int<0,999999999>> kint(lsnes_vset, "avi-tscc-keyint",
|
||||
settingvar::supervariable<settingvar::model_int<0,999999999>> kint(lsnes_setgrp, "avi-tscc-keyint",
|
||||
"AVI‣TSCC‣Keyframe interval", 299);
|
||||
|
||||
struct msrle_compressor
|
||||
|
@ -176,7 +177,7 @@ namespace
|
|||
|
||||
struct avi_codec_tscc : public avi_video_codec
|
||||
{
|
||||
avi_codec_tscc(unsigned level);
|
||||
avi_codec_tscc(unsigned level, unsigned _keyint);
|
||||
~avi_codec_tscc();
|
||||
avi_video_codec::format reset(uint32_t width, uint32_t height, uint32_t fps_n, uint32_t fps_d);
|
||||
void frame(uint32_t* data, uint32_t stride);
|
||||
|
@ -206,9 +207,10 @@ namespace
|
|||
return _level;
|
||||
}
|
||||
|
||||
avi_codec_tscc::avi_codec_tscc(unsigned compression)
|
||||
avi_codec_tscc::avi_codec_tscc(unsigned compression, unsigned _keyint)
|
||||
: z(getzlevel(compression))
|
||||
{
|
||||
max_pframes = _keyint;
|
||||
frameno = 0;
|
||||
}
|
||||
|
||||
|
@ -307,5 +309,7 @@ namespace
|
|||
}
|
||||
|
||||
avi_video_codec_type rgb("tscc", "TSCC video codec",
|
||||
[]() -> avi_video_codec* { return new avi_codec_tscc(clvl);});
|
||||
[]() -> avi_video_codec* {
|
||||
return new avi_codec_tscc(clvl(CORE().settings), kint(CORE().settings));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "video/avi/codec.hpp"
|
||||
#include "core/instance.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "library/zlibstream.hpp"
|
||||
#include <zlib.h>
|
||||
|
@ -12,15 +13,15 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
settingvar::variable<settingvar::model_int<0,9>> clvl(lsnes_vset, "avi-zmbv-compression",
|
||||
settingvar::supervariable<settingvar::model_int<0,9>> clvl(lsnes_setgrp, "avi-zmbv-compression",
|
||||
"AVI‣ZMBV‣Compression", 7);
|
||||
settingvar::variable<settingvar::model_int<0,999999999>> kint(lsnes_vset, "avi-zmbv-keyint",
|
||||
settingvar::supervariable<settingvar::model_int<0,999999999>> kint(lsnes_setgrp, "avi-zmbv-keyint",
|
||||
"AVI‣ZMBV‣Keyframe interval", 299);
|
||||
settingvar::variable<settingvar::model_int<8,64>> bwv(lsnes_vset, "avi-zmbv-blockw", "AVI‣ZMBV‣Block width",
|
||||
16);
|
||||
settingvar::variable<settingvar::model_int<8,64>> bhv(lsnes_vset, "avi-zmbv-blockh", "AVI‣ZMBV‣Block height",
|
||||
16);
|
||||
settingvar::variable<settingvar::model_bool<settingvar::yes_no>> fullsearch(lsnes_vset,
|
||||
settingvar::supervariable<settingvar::model_int<8,64>> bwv(lsnes_setgrp, "avi-zmbv-blockw",
|
||||
"AVI‣ZMBV‣Block width", 16);
|
||||
settingvar::supervariable<settingvar::model_int<8,64>> bhv(lsnes_setgrp, "avi-zmbv-blockh",
|
||||
"AVI‣ZMBV‣Block height", 16);
|
||||
settingvar::supervariable<settingvar::model_bool<settingvar::yes_no>> fsrch(lsnes_setgrp,
|
||||
"avi-zmbv-fullsearch", "AVI‣ZMBV‣Full search (slow)", false);
|
||||
|
||||
//Motion vector.
|
||||
|
@ -37,7 +38,7 @@ namespace
|
|||
//The main ZMBV decoder state.
|
||||
struct avi_codec_zmbv : public avi_video_codec
|
||||
{
|
||||
avi_codec_zmbv(uint32_t _level, uint32_t maxpframes, uint32_t _bw, uint32_t _bh);
|
||||
avi_codec_zmbv(uint32_t _level, uint32_t maxpframes, uint32_t _bw, uint32_t _bh, bool _fullsearch);
|
||||
~avi_codec_zmbv();
|
||||
avi_video_codec::format reset(uint32_t width, uint32_t height, uint32_t fps_n, uint32_t fps_d);
|
||||
void frame(uint32_t* data, uint32_t stride);
|
||||
|
@ -61,6 +62,8 @@ namespace
|
|||
//Size of one block.
|
||||
uint32_t bw;
|
||||
uint32_t bh;
|
||||
//Full search flag.
|
||||
bool fullsearch;
|
||||
//Motion vector buffer, one motion vector for each block, in left-to-right, top-to-bottom order.
|
||||
std::vector<motion> mv;
|
||||
//Pixel buffer (2 full frames and one block).
|
||||
|
@ -241,12 +244,14 @@ compress:
|
|||
return _level;
|
||||
}
|
||||
|
||||
avi_codec_zmbv::avi_codec_zmbv(uint32_t _level, uint32_t maxpframes, uint32_t _bw, uint32_t _bh)
|
||||
avi_codec_zmbv::avi_codec_zmbv(uint32_t _level, uint32_t maxpframes, uint32_t _bw, uint32_t _bh,
|
||||
bool _fullsearch)
|
||||
: z(getzlevel(_level))
|
||||
{
|
||||
bh = _bh;
|
||||
bw = _bw;
|
||||
max_pframes = maxpframes;
|
||||
fullsearch = _fullsearch;
|
||||
}
|
||||
|
||||
avi_video_codec::format avi_codec_zmbv::reset(uint32_t width, uint32_t height, uint32_t fps_n, uint32_t fps_d)
|
||||
|
@ -345,5 +350,8 @@ compress:
|
|||
|
||||
//ZMBV encoder factory object.
|
||||
avi_video_codec_type rgb("zmbv", "Zip Motion Blocks Video codec",
|
||||
[]() -> avi_video_codec* { return new avi_codec_zmbv(clvl, kint, bwv, bhv);});
|
||||
[]() -> avi_video_codec* {
|
||||
return new avi_codec_zmbv(clvl(CORE().settings), kint(CORE().settings), bwv(CORE().settings),
|
||||
bhv(CORE().settings), fsrch(CORE().settings));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "core/advdumper.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
#include "core/instance.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "library/serialization.hpp"
|
||||
|
@ -19,7 +20,8 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
settingvar::variable<settingvar::model_int<0,9>> clevel(lsnes_vset, "jmd-compression", "JMD‣Compression", 7);
|
||||
settingvar::supervariable<settingvar::model_int<0,9>> clevel(lsnes_setgrp, "jmd-compression",
|
||||
"JMD‣Compression", 7);
|
||||
uint64_t akill = 0;
|
||||
double akillfrac = 0;
|
||||
|
||||
|
@ -35,7 +37,7 @@ namespace
|
|||
: information_dispatch("dump-jmd")
|
||||
{
|
||||
enable_send_sound();
|
||||
complevel = clevel;
|
||||
complevel = clevel(CORE().settings);
|
||||
if(tcp_flag) {
|
||||
jmd = &(socket_address(filename).connect());
|
||||
deleter = socket_address::deleter();
|
||||
|
@ -424,7 +426,7 @@ namespace
|
|||
x << "Error starting JMD dump: " << e.what();
|
||||
throw std::runtime_error(x.str());
|
||||
}
|
||||
messages << "Dumping to " << prefix << " at level " << clevel << std::endl;
|
||||
messages << "Dumping to " << prefix << " at level " << clevel(CORE().settings) << std::endl;
|
||||
information_dispatch::do_dumper_update();
|
||||
akill = 0;
|
||||
akillfrac = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue