Allow binding commands to class instance
This commit is contained in:
parent
5ee7962cb9
commit
3b2298180a
43 changed files with 1221 additions and 650 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -15,3 +15,5 @@ lsnes
|
|||
/gambatte
|
||||
src/fonts/font.cpp
|
||||
src/core/version.cpp
|
||||
src/cmdhelp/*.cpp
|
||||
include/cmdhelp/*.hpp
|
||||
|
|
2
include/cmdhelp/inverselist.hpp
Normal file
2
include/cmdhelp/inverselist.hpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#pragma once
|
||||
namespace STUBS { extern const char* inverse_cmd_list[]; }
|
|
@ -4,6 +4,7 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
#include "library/dispatch.hpp"
|
||||
#include "library/command.hpp"
|
||||
|
||||
struct project_info;
|
||||
struct controller_state;
|
||||
|
@ -65,7 +66,7 @@ public:
|
|||
* Ctor.
|
||||
*/
|
||||
button_mapping(controller_state& _controls, keyboard::mapper& mapper, keyboard::keyboard& keyboard,
|
||||
emu_framebuffer& fbuf, emulator_dispatch& _dispatch, lua_state& _lua2);
|
||||
emu_framebuffer& fbuf, emulator_dispatch& _dispatch, lua_state& _lua2, command::group& _cmd);
|
||||
/**
|
||||
* Dtor.
|
||||
*/
|
||||
|
@ -98,13 +99,10 @@ public:
|
|||
* Map of button keys.
|
||||
*/
|
||||
std::map<std::string, std::string> button_keys;
|
||||
/**
|
||||
* Do button/axis action.
|
||||
*/
|
||||
void do_action(const std::string& name, short state, int mode);
|
||||
private:
|
||||
void do_analog_action(const std::string& a);
|
||||
void do_autofire_action(const std::string& a, int mode);
|
||||
private:
|
||||
void do_action(const std::string& name, short state, int mode);
|
||||
void promote_key(keyboard::ctrlrkey& k);
|
||||
void add_button(const std::string& name, const controller_bind& binding);
|
||||
void process_controller(portctrl::controller& controller, unsigned number);
|
||||
|
@ -129,7 +127,17 @@ private:
|
|||
emu_framebuffer& fbuf;
|
||||
emulator_dispatch& edispatch;
|
||||
lua_state& lua2;
|
||||
command::group& cmd;
|
||||
struct dispatch::target<> ncore;
|
||||
command::_fnptr<const std::string&> button_p;
|
||||
command::_fnptr<const std::string&> button_r;
|
||||
command::_fnptr<const std::string&> button_h;
|
||||
command::_fnptr<const std::string&> button_t;
|
||||
command::_fnptr<const std::string&> button_d;
|
||||
command::_fnptr<const std::string&> button_ap;
|
||||
command::_fnptr<const std::string&> button_ar;
|
||||
command::_fnptr<const std::string&> button_at;
|
||||
command::_fnptr<const std::string&> button_a;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <map>
|
||||
#include <list>
|
||||
#include "library/portctrl-data.hpp"
|
||||
#include "library/command.hpp"
|
||||
#include "library/threads.hpp"
|
||||
|
||||
class project_state;
|
||||
|
@ -34,7 +35,7 @@ public:
|
|||
* Constructor.
|
||||
*/
|
||||
controller_state(project_state& _project, movie_logic& _mlogic, button_mapping& _buttons,
|
||||
emulator_dispatch& _dispatch, status_updater& _supdater) throw();
|
||||
emulator_dispatch& _dispatch, status_updater& _supdater, command::group& _cmd) throw();
|
||||
/**
|
||||
* Convert lcid (Logical Controller ID) into pcid (Physical Controler ID).
|
||||
*
|
||||
|
@ -205,12 +206,12 @@ public:
|
|||
void set_macro(const std::string& macro, const portctrl::macro& m);
|
||||
void apply_macro(portctrl::frame& f);
|
||||
void rename_macro(const std::string& old, const std::string& newn);
|
||||
void do_macro(const std::string& a, int mode);
|
||||
std::set<std::string> active_macro_set();
|
||||
void advance_macros();
|
||||
std::map<std::string, uint64_t> get_macro_frames();
|
||||
void set_macro_frames(const std::map<std::string, uint64_t>& f);
|
||||
private:
|
||||
void do_macro(const std::string& a, int mode);
|
||||
struct autofire_info
|
||||
{
|
||||
uint64_t first_frame;
|
||||
|
@ -240,6 +241,10 @@ private:
|
|||
button_mapping& buttons;
|
||||
emulator_dispatch& edispatch;
|
||||
status_updater& supdater;
|
||||
command::group& cmd;
|
||||
command::_fnptr<const std::string&> macro_p;
|
||||
command::_fnptr<const std::string&> macro_r;
|
||||
command::_fnptr<const std::string&> macro_t;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <cstdint>
|
||||
#include "library/command.hpp"
|
||||
#include "library/dispatch.hpp"
|
||||
|
||||
class emulator_dispatch;
|
||||
|
@ -15,7 +16,7 @@ class loaded_rom;
|
|||
class debug_context
|
||||
{
|
||||
public:
|
||||
debug_context(emulator_dispatch& _dispatch, loaded_rom& _rom);
|
||||
debug_context(emulator_dispatch& _dispatch, loaded_rom& _rom, command::group& _cmd);
|
||||
/**
|
||||
* Type of event.
|
||||
*/
|
||||
|
@ -154,14 +155,21 @@ public:
|
|||
std::map<uint64_t, cb_list> trace_cb;
|
||||
std::map<uint64_t, cb_list> frame_cb;
|
||||
private:
|
||||
void do_showhooks();
|
||||
void do_genevent(const std::string& a);
|
||||
void do_tracecmd(const std::string& a);
|
||||
cb_list dummy_cb; //Always empty.
|
||||
uint64_t xmask = 1;
|
||||
std::function<void()> tracelog_change_cb;
|
||||
emulator_dispatch& edispatch;
|
||||
loaded_rom& rom;
|
||||
command::group& cmd;
|
||||
struct dispatch::target<> corechange;
|
||||
bool corechange_r = false;
|
||||
bool requesting_break = false;
|
||||
command::_fnptr<> showhooks;
|
||||
command::_fnptr<const std::string&> genevent;
|
||||
command::_fnptr<const std::string&> tracecmd;
|
||||
|
||||
struct tracelog_file : public callback_base
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _framebuffer__hpp__included__
|
||||
|
||||
#include "core/window.hpp"
|
||||
#include "library/command.hpp"
|
||||
#include "library/framebuffer.hpp"
|
||||
#include "library/triplebuffer.hpp"
|
||||
|
||||
|
@ -30,7 +31,7 @@ class emu_framebuffer
|
|||
public:
|
||||
emu_framebuffer(subtitle_commentary& _subtitles, settingvar::group& _settings, memwatch_set& _mwatch,
|
||||
keyboard::keyboard& _keyboard, emulator_dispatch& _dispatch, lua_state& _lua2, loaded_rom& _rom,
|
||||
status_updater& _supdater);
|
||||
status_updater& _supdater, command::group& _cmd);
|
||||
/**
|
||||
* The main framebuffer.
|
||||
*/
|
||||
|
@ -83,6 +84,7 @@ public:
|
|||
framebuffer::raw& render_get_latest_screen();
|
||||
void render_get_latest_screen_end();
|
||||
private:
|
||||
void do_screenshot(command::arg_filename a);
|
||||
struct render_info
|
||||
{
|
||||
framebuffer::raw fbuf;
|
||||
|
@ -107,6 +109,8 @@ private:
|
|||
lua_state& lua2;
|
||||
loaded_rom& rom;
|
||||
status_updater& supdater;
|
||||
command::group& cmd;
|
||||
command::_fnptr<command::arg_filename> screenshot;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include "library/threads.hpp"
|
||||
#include "library/command.hpp"
|
||||
|
||||
#define FRAMERATE_HISTORY_FRAMES 10
|
||||
|
||||
|
@ -12,7 +13,7 @@
|
|||
class framerate_regulator
|
||||
{
|
||||
public:
|
||||
framerate_regulator();
|
||||
framerate_regulator(command::group& _cmd);
|
||||
/**
|
||||
* Set the target speed multiplier.
|
||||
*
|
||||
|
@ -96,7 +97,10 @@ private:
|
|||
double nominal_framerate;
|
||||
double multiplier_framerate;
|
||||
threads::lock framerate_lock;
|
||||
|
||||
command::group& cmd;
|
||||
command::_fnptr<> turbo_p;
|
||||
command::_fnptr<> turbo_r;
|
||||
command::_fnptr<> turbo_t;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <list>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "library/command.hpp"
|
||||
|
||||
class emulator_dispatch;
|
||||
|
||||
|
@ -28,7 +29,8 @@ public:
|
|||
uint64_t length;
|
||||
};
|
||||
|
||||
voice_commentary(settingvar::group& _settings, emulator_dispatch& _dispatch, audioapi_instance& _audio);
|
||||
voice_commentary(settingvar::group& _settings, emulator_dispatch& _dispatch, audioapi_instance& _audio,
|
||||
command::group& _cmd);
|
||||
~voice_commentary();
|
||||
void init();
|
||||
void kill();
|
||||
|
@ -53,6 +55,9 @@ private:
|
|||
settingvar::group& settings;
|
||||
emulator_dispatch& edispatch;
|
||||
audioapi_instance& audio;
|
||||
command::group& cmd;
|
||||
command::_fnptr<> tangentp;
|
||||
command::_fnptr<> tangentr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
/**
|
||||
* Ctor.
|
||||
*/
|
||||
save_jukebox(settingvar::group& _settings);
|
||||
save_jukebox(settingvar::group& _settings, command::group& _cmd);
|
||||
/**
|
||||
* Dtor.
|
||||
*/
|
||||
|
@ -73,11 +73,16 @@ public:
|
|||
*/
|
||||
void unset_update();
|
||||
private:
|
||||
void do_slotsel(const std::string& arg);
|
||||
settingvar::group& settings;
|
||||
size_t current_slot;
|
||||
size_t current_size;
|
||||
std::function<void()> update;
|
||||
save_jukebox_listener* listener;
|
||||
command::group& cmd;
|
||||
command::_fnptr<const std::string&> slotsel;
|
||||
command::_fnptr<> cycleprev;
|
||||
command::_fnptr<> cyclenext;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
MT_XOR
|
||||
};
|
||||
multitrack_edit(movie_logic& _mlogic, controller_state& _controls, emulator_dispatch& _dispatch,
|
||||
status_updater& _supdater);
|
||||
status_updater& _supdater, button_mapping& _buttons, command::group& _cmd);
|
||||
void enable(bool state);
|
||||
void set(unsigned port, unsigned controller, state s);
|
||||
void set_and_notify(unsigned port, unsigned controller, state s);
|
||||
|
@ -30,6 +30,9 @@ public:
|
|||
void process_frame(portctrl::frame& input);
|
||||
bool any_records();
|
||||
private:
|
||||
void do_mt_fwd();
|
||||
void do_mt_bw();
|
||||
void do_mt_set(const std::string& args);
|
||||
threads::lock mlock;
|
||||
bool enabled;
|
||||
std::map<std::pair<unsigned, unsigned>, state> controllerstate;
|
||||
|
@ -37,6 +40,11 @@ private:
|
|||
controller_state& controls;
|
||||
emulator_dispatch& edispatch;
|
||||
status_updater& supdater;
|
||||
button_mapping& buttons;
|
||||
command::group& cmd;
|
||||
command::_fnptr<> mt_f;
|
||||
command::_fnptr<> mt_b;
|
||||
command::_fnptr<const std::string&> mt_s;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <list>
|
||||
#include <vector>
|
||||
#include "core/rom-small.hpp"
|
||||
#include "library/command.hpp"
|
||||
#include "library/json.hpp"
|
||||
|
||||
class voice_commentary;
|
||||
|
@ -15,14 +16,7 @@ class button_mapping;
|
|||
class emulator_dispatch;
|
||||
class input_queue;
|
||||
class status_updater;
|
||||
namespace command
|
||||
{
|
||||
class group;
|
||||
}
|
||||
namespace settingvar
|
||||
{
|
||||
class cache;
|
||||
}
|
||||
namespace settingvar { class cache; }
|
||||
|
||||
//A branch.
|
||||
struct project_branch_info
|
||||
|
@ -226,6 +220,13 @@ public:
|
|||
*/
|
||||
void copy_macros(project_info& p, controller_state& s);
|
||||
private:
|
||||
void recursive_list_branch(uint64_t bid, std::set<unsigned>& dset, unsigned depth, bool last_of);
|
||||
void do_branch_ls();
|
||||
void do_branch_mk(const std::string& a);
|
||||
void do_branch_rm(const std::string& a);
|
||||
void do_branch_set(const std::string& a);
|
||||
void do_branch_rp(const std::string& a);
|
||||
void do_branch_mv(const std::string& a);
|
||||
project_info* active_project;
|
||||
voice_commentary& commentary;
|
||||
memwatch_set& mwatch;
|
||||
|
@ -237,6 +238,12 @@ private:
|
|||
input_queue& iqueue;
|
||||
loaded_rom& rom;
|
||||
status_updater& supdater;
|
||||
command::_fnptr<> branch_ls;
|
||||
command::_fnptr<const std::string&> branch_mk;
|
||||
command::_fnptr<const std::string&> branch_rm;
|
||||
command::_fnptr<const std::string&> branch_set;
|
||||
command::_fnptr<const std::string&> branch_rp;
|
||||
command::_fnptr<const std::string&> branch_mv;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <cstdint>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "library/command.hpp"
|
||||
|
||||
namespace lua { class render_context; }
|
||||
|
||||
|
@ -30,7 +31,8 @@ class emulator_dispatch;
|
|||
struct subtitle_commentary
|
||||
{
|
||||
public:
|
||||
subtitle_commentary(movie_logic& _mlogic, emu_framebuffer& _fbuf, emulator_dispatch& _dispatch);
|
||||
subtitle_commentary(movie_logic& _mlogic, emu_framebuffer& _fbuf, emulator_dispatch& _dispatch,
|
||||
command::group& _cmd);
|
||||
std::set<std::pair<uint64_t, uint64_t>> get_all();
|
||||
std::string get(uint64_t f, uint64_t l);
|
||||
void set(uint64_t f, uint64_t l, const std::string& x);
|
||||
|
@ -38,9 +40,16 @@ public:
|
|||
static std::string s_escape(std::string x);
|
||||
void render(lua::render_context& ctx);
|
||||
private:
|
||||
void do_editsub(const std::string& a);
|
||||
void do_listsub();
|
||||
void do_savesub(const std::string& a);
|
||||
movie_logic& mlogic;
|
||||
emu_framebuffer& fbuf;
|
||||
emulator_dispatch& edispatch;
|
||||
command::group& cmd;
|
||||
command::_fnptr<const std::string&> editsub;
|
||||
command::_fnptr<> listsub;
|
||||
command::_fnptr<command::arg_filename> savesub;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
@ -245,6 +246,25 @@ private:
|
|||
set* in_set;
|
||||
};
|
||||
|
||||
/**
|
||||
* Name, Description and help for command.
|
||||
*/
|
||||
struct stub
|
||||
{
|
||||
/**
|
||||
* The command name.
|
||||
*/
|
||||
const char* name;
|
||||
/**
|
||||
* The short description.
|
||||
*/
|
||||
const char* desc;
|
||||
/**
|
||||
* The long help.
|
||||
*/
|
||||
const char* help;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mandatory filename
|
||||
*/
|
||||
|
@ -269,7 +289,7 @@ struct arg_filename
|
|||
* parameter a: The arguments to pass.
|
||||
*/
|
||||
template<typename... args>
|
||||
void invoke_fn(void (*fn)(args... arguments), const std::string& a);
|
||||
void invoke_fn(std::function<void(args... arguments)> fn, const std::string& a);
|
||||
|
||||
/**
|
||||
* Warp function pointer as command.
|
||||
|
@ -292,10 +312,25 @@ public:
|
|||
const std::string& _help, void (*_fn)(args... arguments), bool dynamic = false) throw(std::bad_alloc)
|
||||
: base(group, name, dynamic)
|
||||
{
|
||||
description = _description;
|
||||
shorthelp = _description;
|
||||
help = _help;
|
||||
fn = _fn;
|
||||
}
|
||||
/**
|
||||
* Create a new command.
|
||||
*
|
||||
* parameter _set: The set command will be part of.
|
||||
* parameter name: Name of the command
|
||||
* parameter fn: Function to call on command.
|
||||
* parameter description Description&Help for the command
|
||||
*/
|
||||
_fnptr(group& _group, stub _name, std::function<void(args... arguments)> _fn) throw(std::bad_alloc)
|
||||
: base(_group, _name.name, false)
|
||||
{
|
||||
shorthelp = _name.desc;
|
||||
help = _name.help;
|
||||
fn = _fn;
|
||||
}
|
||||
/**
|
||||
* Destroy a commnad.
|
||||
*/
|
||||
|
@ -319,7 +354,7 @@ public:
|
|||
*/
|
||||
std::string get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return description;
|
||||
return shorthelp;
|
||||
}
|
||||
/**
|
||||
* Get long help.
|
||||
|
@ -332,8 +367,8 @@ public:
|
|||
return help;
|
||||
}
|
||||
private:
|
||||
void (*fn)(args... arguments);
|
||||
std::string description;
|
||||
std::function<void(args... arguments)> fn;
|
||||
std::string shorthelp;
|
||||
std::string help;
|
||||
};
|
||||
|
||||
|
@ -344,6 +379,21 @@ template<typename... args>
|
|||
class fnptr : public factory_base
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new command.
|
||||
*
|
||||
* parameter _set: The set command will be part of.
|
||||
* parameter desc: Command descriptor.
|
||||
* parameter fn: Function to call on command.
|
||||
*/
|
||||
fnptr(set& _set, stub _name, void (*_fn)(args... arguments)) throw(std::bad_alloc)
|
||||
{
|
||||
shorthelp = _name.desc;
|
||||
name = _name.name;
|
||||
help = _name.help;
|
||||
fn = _fn;
|
||||
_factory_base(_set, name);
|
||||
}
|
||||
/**
|
||||
* Create a new command.
|
||||
*
|
||||
|
@ -356,7 +406,7 @@ public:
|
|||
fnptr(set& _set, const std::string& _name, const std::string& _description,
|
||||
const std::string& _help, void (*_fn)(args... arguments)) throw(std::bad_alloc)
|
||||
{
|
||||
description = _description;
|
||||
shorthelp = _description;
|
||||
name = _name;
|
||||
help = _help;
|
||||
fn = _fn;
|
||||
|
@ -373,11 +423,11 @@ public:
|
|||
*/
|
||||
base* make(group& grp) throw(std::bad_alloc)
|
||||
{
|
||||
return new _fnptr<args...>(grp, name, description, help, fn, true);
|
||||
return new _fnptr<args...>(grp, name, shorthelp, help, fn, true);
|
||||
}
|
||||
private:
|
||||
void (*fn)(args... arguments);
|
||||
std::string description;
|
||||
std::string shorthelp;
|
||||
std::string help;
|
||||
std::string name;
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@ CFLAGS += -DOPUS_SUPPORTS_SURROUND
|
|||
endif
|
||||
endif
|
||||
|
||||
COMMON_LIBRARY=core lua fonts library interface video emulation
|
||||
COMMON_LIBRARY=core lua fonts library interface video emulation cmdhelp
|
||||
ALLFILES=__all__.files
|
||||
ALLFLAGS=__all__.ldflags
|
||||
COMMON_LIBRARY_FILES=$(patsubst %,%/$(ALLFILES),$(COMMON_LIBRARY))
|
||||
|
@ -37,7 +37,7 @@ __all_common__.files: $(COMMON_LIBRARY_FILES)
|
|||
__all_platform__.files: $(PLATFORM_LIBRARY_FILES)
|
||||
lua genfilelist.lua $^ >$@
|
||||
|
||||
core/$(ALLFILES): forcelook
|
||||
core/$(ALLFILES): forcelook cmdhelp/$(ALLFILES)
|
||||
$(MAKE) -C core
|
||||
|
||||
emulation/$(ALLFILES): forcelook
|
||||
|
@ -58,6 +58,9 @@ lua/$(ALLFILES): forcelook
|
|||
platform/$(ALLFILES): forcelook
|
||||
$(MAKE) -C platform
|
||||
|
||||
cmdhelp/$(ALLFILES): forcelook
|
||||
$(MAKE) -C cmdhelp
|
||||
|
||||
util/__all_files__: forcelook
|
||||
$(MAKE) -C util
|
||||
|
||||
|
@ -85,6 +88,7 @@ precheck:
|
|||
$(MAKE) -C platform precheck
|
||||
$(MAKE) -C util precheck
|
||||
$(MAKE) -C video precheck
|
||||
$(MAKE) -C cmdhelp precheck
|
||||
|
||||
platclean:
|
||||
$(MAKE) -C emulation clean
|
||||
|
@ -101,6 +105,7 @@ clean:
|
|||
$(MAKE) -C platform clean
|
||||
$(MAKE) -C util clean
|
||||
$(MAKE) -C video clean
|
||||
$(MAKE) -C cmdhelp clean
|
||||
|
||||
forcelook:
|
||||
@true
|
||||
|
|
39
src/cmdhelp/Makefile
Normal file
39
src/cmdhelp/Makefile
Normal file
|
@ -0,0 +1,39 @@
|
|||
ALLFILES=__all__.files
|
||||
ALLFLAGS=__all__.ldflags
|
||||
|
||||
JSON_FILES=$(wildcard *.json)
|
||||
JSON_SRC=$(patsubst %.json,%.cpp,$(JSON_FILES))
|
||||
JSON_OBJECTS=$(patsubst %.json,%.$(OBJECT_SUFFIX),$(JSON_FILES))
|
||||
|
||||
__all__.files: $(JSON_OBJECTS) inverselist.$(OBJECT_SUFFIX)
|
||||
lua ../genfilelist.lua $^ >$@
|
||||
touch $(ALLFLAGS)
|
||||
|
||||
mkstubs.exe: mkstubs.cpp ../library/json.cpp ../library/utf8.cpp ../library/string.cpp ../library/hex.cpp ../library/eatarg.cpp ../library/int24.cpp
|
||||
$(HOSTCC) -g -std=gnu++0x -I../../include/library -o $@ $^ -lboost_regex$(HOST_BOOST_POSTFIX) -lboost_system$(HOST_BOOST_POSTFIX) -Wall
|
||||
|
||||
mkstubsi.exe: mkstubsi.cpp ../library/json.cpp ../library/utf8.cpp ../library/string.cpp ../library/hex.cpp ../library/eatarg.cpp ../library/int24.cpp
|
||||
$(HOSTCC) -g -std=gnu++0x -I../../include/library -o $@ $^ -lboost_regex$(HOST_BOOST_POSTFIX) -lboost_system$(HOST_BOOST_POSTFIX) -Wall
|
||||
|
||||
inverselist.cpp: $(JSON_FILES) mkstubsi.exe
|
||||
./mkstubsi.exe $^
|
||||
|
||||
%.cpp: %.json mkstubs.exe
|
||||
./mkstubs.exe $<
|
||||
mv *.hpp ../../include/cmdhelp
|
||||
|
||||
%.$(OBJECT_SUFFIX): %.cpp
|
||||
$(REALCC) $(CFLAGS) -c -o $@ $< -I../../include -Wall
|
||||
|
||||
|
||||
.PRECIOUS: %.$(OBJECT_SUFFIX) %.files
|
||||
|
||||
precheck:
|
||||
@true
|
||||
|
||||
clean:
|
||||
rm -f *.$(OBJECT_SUFFIX) $(JSON_SRC) inverselist.cpp __all__.ldflags __all__.files
|
||||
rm -f mkstubs.exe
|
||||
|
||||
forcelook:
|
||||
@true
|
56
src/cmdhelp/button.json
Normal file
56
src/cmdhelp/button.json
Normal file
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"btnp":{
|
||||
"__class":"button",
|
||||
"__name":"+controller",
|
||||
"__description":"Press a button",
|
||||
"<button>":"Press button <button>"
|
||||
},
|
||||
"btnr":{
|
||||
"__class":"button",
|
||||
"__name":"-controller",
|
||||
"__description":"Release a button",
|
||||
"<button>":"Release button <button>"
|
||||
},
|
||||
"btnh":{
|
||||
"__class":"button",
|
||||
"__name":"hold-controller",
|
||||
"__description":"Autohold a button",
|
||||
"<button>":"Autohold button <button>"
|
||||
},
|
||||
"btnt":{
|
||||
"__class":"button",
|
||||
"__name":"type-controller",
|
||||
"__description":"Type a button",
|
||||
"<button>":"Type button <button>"
|
||||
},
|
||||
"btnd":{
|
||||
"__class":"button",
|
||||
"__name":"designate-position",
|
||||
"__description":"Set postion",
|
||||
"<button>":"Designate position for an axis"
|
||||
},
|
||||
"btnap":{
|
||||
"__class":"button",
|
||||
"__name":"+autofire-controller",
|
||||
"__description":"Start autofire",
|
||||
"<button> [[<duty> ]<cyclelen>]":"Autofire button <button> with duty <duty> out of <cyclelen>"
|
||||
},
|
||||
"btnar":{
|
||||
"__class":"button",
|
||||
"__name":"-autofire-controller",
|
||||
"__description":"End autofire",
|
||||
"<button> [[<duty> ]<cyclelen>]":"End Autofire on button <button>"
|
||||
},
|
||||
"btnat":{
|
||||
"__class":"button",
|
||||
"__name":"autofire-controller",
|
||||
"__description":"Toggle autofire",
|
||||
"<button> [[<duty> ]<cyclelen>]":"Toggle Autofire on button <button> with duty <duty> out of <cyclelen>"
|
||||
},
|
||||
"btna":{
|
||||
"__class":"button",
|
||||
"__name":"controller-analog",
|
||||
"__description":"Analog action",
|
||||
"<button> <axisvalue>":"Analog action on <button> with value <axisvalue>"
|
||||
}
|
||||
}
|
15
src/cmdhelp/commentary.json
Normal file
15
src/cmdhelp/commentary.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"tangentp":{
|
||||
"__class":"commentary",
|
||||
"__name":"+tangent",
|
||||
"__description":"Voice tangent",
|
||||
"":"Voice tangent",
|
||||
"__inverse":{"":"Movie‣Voice tangent"}
|
||||
},
|
||||
"tangentr":{
|
||||
"__class":"commentary",
|
||||
"__name":"-tangent",
|
||||
"__description":"Voice tangent",
|
||||
"":"Voice tangent."
|
||||
}
|
||||
}
|
21
src/cmdhelp/debug.json
Normal file
21
src/cmdhelp/debug.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"showhooks":{
|
||||
"__class":"debug",
|
||||
"__name":"show-callbacks",
|
||||
"__description":"Show debug callbacks",
|
||||
"":"Shows debugging callbacks"
|
||||
},
|
||||
"genevent":{
|
||||
"__class":"debug",
|
||||
"__name":"generate-memory-event",
|
||||
"__description":"Inject a debugging event",
|
||||
"<type> <addr> <value>":"Inject a debugging event with given <type>, <addr> and <value>"
|
||||
},
|
||||
"trace":{
|
||||
"__class":"debug",
|
||||
"__name":"tracelog",
|
||||
"__description":"Trace log control",
|
||||
"<cpuid> <file>":"Start tracing <cpuid> to <file>",
|
||||
"<cpuid>":"End tracing <cpuid>"
|
||||
}
|
||||
}
|
7
src/cmdhelp/framebuffer.json
Normal file
7
src/cmdhelp/framebuffer.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"screenshot":{
|
||||
"__name":"take-screenshot",
|
||||
"__description":"Takes a screenshot",
|
||||
"<file>":"Save a screenshot to PNG file <file>"
|
||||
}
|
||||
}
|
56
src/cmdhelp/jukebox.json
Normal file
56
src/cmdhelp/jukebox.json
Normal file
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"slotselect":{
|
||||
"__class":"jukebox",
|
||||
"__name":"set-jukebox-slot",
|
||||
"__description":"Set jukebox slot",
|
||||
"<slot>":"Set jukebox slot to <slot>\n",
|
||||
"__inverse":{
|
||||
"1":"Slot select‣Slot 1",
|
||||
"2":"Slot select‣Slot 2",
|
||||
"3":"Slot select‣Slot 3",
|
||||
"4":"Slot select‣Slot 4",
|
||||
"5":"Slot select‣Slot 5",
|
||||
"6":"Slot select‣Slot 6",
|
||||
"7":"Slot select‣Slot 7",
|
||||
"8":"Slot select‣Slot 8",
|
||||
"9":"Slot select‣Slot 9",
|
||||
"10":"Slot select‣Slot 10",
|
||||
"11":"Slot select‣Slot 11",
|
||||
"12":"Slot select‣Slot 12",
|
||||
"13":"Slot select‣Slot 13",
|
||||
"14":"Slot select‣Slot 14",
|
||||
"15":"Slot select‣Slot 15",
|
||||
"16":"Slot select‣Slot 16",
|
||||
"17":"Slot select‣Slot 17",
|
||||
"18":"Slot select‣Slot 18",
|
||||
"19":"Slot select‣Slot 19",
|
||||
"20":"Slot select‣Slot 20",
|
||||
"21":"Slot select‣Slot 21",
|
||||
"22":"Slot select‣Slot 22",
|
||||
"23":"Slot select‣Slot 23",
|
||||
"24":"Slot select‣Slot 24",
|
||||
"25":"Slot select‣Slot 25",
|
||||
"26":"Slot select‣Slot 26",
|
||||
"27":"Slot select‣Slot 27",
|
||||
"28":"Slot select‣Slot 28",
|
||||
"29":"Slot select‣Slot 29",
|
||||
"30":"Slot select‣Slot 30",
|
||||
"31":"Slot select‣Slot 31",
|
||||
"32":"Slot select‣Slot 32"
|
||||
}
|
||||
},
|
||||
"slotprev":{
|
||||
"__class":"jukebox",
|
||||
"__name":"cycle-jukebox-backward",
|
||||
"__description":"Cycle save jukebox backwards",
|
||||
"":"Cycle save jukebox backwards",
|
||||
"__inverse":{"":"Slot select‣Cycle backwards"}
|
||||
},
|
||||
"slotnext":{
|
||||
"__class":"jukebox",
|
||||
"__name":"cycle-jukebox-forward",
|
||||
"__description":"Cycle save jukebox forwards",
|
||||
"":"Cycle save jukebox forwards",
|
||||
"__inverse":{"":"Slot select‣Cycle forwards"}
|
||||
}
|
||||
}
|
82
src/cmdhelp/loadsave.json
Normal file
82
src/cmdhelp/loadsave.json
Normal file
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"load":{
|
||||
"__class":"loadsave",
|
||||
"__name":"load",
|
||||
"__description":"Load savestate (current mode)",
|
||||
"<file>":"Loads SNES state from <file> in current mode",
|
||||
"__inverse":{
|
||||
"$SLOT:1":"Load‣Slot 1",
|
||||
"$SLOT:2":"Load‣Slot 2",
|
||||
"$SLOT:3":"Load‣Slot 3",
|
||||
"$SLOT:4":"Load‣Slot 4",
|
||||
"$SLOT:5":"Load‣Slot 5",
|
||||
"$SLOT:6":"Load‣Slot 6",
|
||||
"$SLOT:7":"Load‣Slot 7",
|
||||
"$SLOT:8":"Load‣Slot 8",
|
||||
"$SLOT:9":"Load‣Slot 9",
|
||||
"$SLOT:10":"Load‣Slot 10",
|
||||
"$SLOT:11":"Load‣Slot 11",
|
||||
"$SLOT:12":"Load‣Slot 12",
|
||||
"$SLOT:13":"Load‣Slot 13",
|
||||
"$SLOT:14":"Load‣Slot 14",
|
||||
"$SLOT:15":"Load‣Slot 15",
|
||||
"$SLOT:16":"Load‣Slot 16",
|
||||
"$SLOT:17":"Load‣Slot 17",
|
||||
"$SLOT:18":"Load‣Slot 18",
|
||||
"$SLOT:19":"Load‣Slot 19",
|
||||
"$SLOT:20":"Load‣Slot 20",
|
||||
"$SLOT:21":"Load‣Slot 21",
|
||||
"$SLOT:22":"Load‣Slot 22",
|
||||
"$SLOT:23":"Load‣Slot 23",
|
||||
"$SLOT:24":"Load‣Slot 24",
|
||||
"$SLOT:25":"Load‣Slot 25",
|
||||
"$SLOT:26":"Load‣Slot 26",
|
||||
"$SLOT:27":"Load‣Slot 27",
|
||||
"$SLOT:28":"Load‣Slot 28",
|
||||
"$SLOT:29":"Load‣Slot 29",
|
||||
"$SLOT:30":"Load‣Slot 30",
|
||||
"$SLOT:31":"Load‣Slot 31",
|
||||
"$SLOT:32":"Load‣Slot 32"
|
||||
}
|
||||
},
|
||||
"savestate":{
|
||||
"__class":"loadsave",
|
||||
"__name":"save-state",
|
||||
"__description":"Save state",
|
||||
"<file>":"Saves SNES state to <file>",
|
||||
"__inverse":{
|
||||
"$SLOT:1":"Save‣Slot 1",
|
||||
"$SLOT:2":"Save‣Slot 2",
|
||||
"$SLOT:3":"Save‣Slot 3",
|
||||
"$SLOT:4":"Save‣Slot 4",
|
||||
"$SLOT:5":"Save‣Slot 5",
|
||||
"$SLOT:6":"Save‣Slot 6",
|
||||
"$SLOT:7":"Save‣Slot 7",
|
||||
"$SLOT:8":"Save‣Slot 8",
|
||||
"$SLOT:9":"Save‣Slot 9",
|
||||
"$SLOT:10":"Save‣Slot 10",
|
||||
"$SLOT:11":"Save‣Slot 11",
|
||||
"$SLOT:12":"Save‣Slot 12",
|
||||
"$SLOT:13":"Save‣Slot 13",
|
||||
"$SLOT:14":"Save‣Slot 14",
|
||||
"$SLOT:15":"Save‣Slot 15",
|
||||
"$SLOT:16":"Save‣Slot 16",
|
||||
"$SLOT:17":"Save‣Slot 17",
|
||||
"$SLOT:18":"Save‣Slot 18",
|
||||
"$SLOT:19":"Save‣Slot 19",
|
||||
"$SLOT:20":"Save‣Slot 20",
|
||||
"$SLOT:21":"Save‣Slot 21",
|
||||
"$SLOT:22":"Save‣Slot 22",
|
||||
"$SLOT:23":"Save‣Slot 23",
|
||||
"$SLOT:24":"Save‣Slot 24",
|
||||
"$SLOT:25":"Save‣Slot 25",
|
||||
"$SLOT:26":"Save‣Slot 26",
|
||||
"$SLOT:27":"Save‣Slot 27",
|
||||
"$SLOT:28":"Save‣Slot 28",
|
||||
"$SLOT:29":"Save‣Slot 29",
|
||||
"$SLOT:30":"Save‣Slot 30",
|
||||
"$SLOT:31":"Save‣Slot 31",
|
||||
"$SLOT:32":"Save‣Slot 32"
|
||||
}
|
||||
}
|
||||
}
|
20
src/cmdhelp/macro.json
Normal file
20
src/cmdhelp/macro.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"macrot":{
|
||||
"__class":"macro",
|
||||
"__name":"macro",
|
||||
"__description":"Toggle a macro",
|
||||
"<macroname>":"Toggle macro <macroname>."
|
||||
},
|
||||
"macrop":{
|
||||
"__class":"macro",
|
||||
"__name":"+macro",
|
||||
"__description":"Enable a macro",
|
||||
"<macroname>":"Enable macro <macroname>."
|
||||
},
|
||||
"macror":{
|
||||
"__class":"macro",
|
||||
"__name":"-macro",
|
||||
"__description":"Disable a macro",
|
||||
"<macroname>":"Disable macro <macroname>."
|
||||
}
|
||||
}
|
22
src/cmdhelp/mhold.json
Normal file
22
src/cmdhelp/mhold.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"mholdp":{
|
||||
"__class":"mhold",
|
||||
"__name":"+hold-macro",
|
||||
"__description":"Hold macro (hold)",
|
||||
"":"Hold macros enable",
|
||||
"__inverse":{"":"Macro‣Hold all macros"}
|
||||
},
|
||||
"mholdr":{
|
||||
"__class":"mhold",
|
||||
"__name":"-hold-macro",
|
||||
"__description":"Hold macro (hold)",
|
||||
"":"Hold macros disable"
|
||||
},
|
||||
"mholdt":{
|
||||
"__class":"mhold",
|
||||
"__name":"hold-macro",
|
||||
"__description":"Hold macro (typed)",
|
||||
"":"Hold macros typed",
|
||||
"__inverse":{"":"Macro‣Hold all macros (typed)"}
|
||||
}
|
||||
}
|
144
src/cmdhelp/mkstubs.cpp
Normal file
144
src/cmdhelp/mkstubs.cpp
Normal file
|
@ -0,0 +1,144 @@
|
|||
#include "json.hpp"
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
|
||||
const char* hexes = "0123456789abcdef";
|
||||
|
||||
std::string quote_c_string(const std::string& raw, bool hiraw = false);
|
||||
|
||||
std::string quote_c_string(const std::string& raw, bool hiraw)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "\"";
|
||||
for(auto i : raw) {
|
||||
unsigned char ch = i;
|
||||
if(ch == '\n')
|
||||
out << "\\n";
|
||||
else if(ch == '\"')
|
||||
out << "\\\"";
|
||||
else if(ch == '\\')
|
||||
out << "\\\\";
|
||||
else if(ch < 32 || ch == 127 || (ch > 127 && !hiraw))
|
||||
out << "\\x" << hexes[ch / 16] << hexes[ch % 16];
|
||||
else
|
||||
out << ch;
|
||||
}
|
||||
out << "\"";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string quote_help(const std::u32string& raw)
|
||||
{
|
||||
const size_t initial_width = 8;
|
||||
const size_t break_width = 80;
|
||||
std::ostringstream out;
|
||||
//Compute split positions.
|
||||
std::set<size_t> splits;
|
||||
size_t last_word = 0;
|
||||
size_t last_word_width = initial_width;
|
||||
size_t width = initial_width;
|
||||
for(size_t i = 0; i < raw.length(); i++) {
|
||||
if(raw[i] == U'\n') {
|
||||
splits.insert(i);
|
||||
width = initial_width;
|
||||
last_word = i;
|
||||
last_word_width = initial_width;
|
||||
}
|
||||
if(raw[i] == U' ') {
|
||||
width++;
|
||||
if(width > break_width && last_word_width > initial_width) {
|
||||
//Wordwrap at last word.
|
||||
splits.insert(last_word);
|
||||
width = width - last_word_width + initial_width;
|
||||
}
|
||||
last_word = i;
|
||||
last_word_width = width;
|
||||
} else {
|
||||
//FIXME: Handle double-width characters.
|
||||
width++;
|
||||
}
|
||||
}
|
||||
out << "\t\"\\t";
|
||||
for(size_t i = 0; i < raw.length(); i++) {
|
||||
if(splits.count(i)) {
|
||||
out << "\\n\"\n\t\"";
|
||||
} else {
|
||||
char32_t z[2] = {raw[i]};
|
||||
if(z[0] == U'\"')
|
||||
out << "\\\"";
|
||||
else if(z[0] == U'\n')
|
||||
out << "\\n";
|
||||
else if(z[0] < 32 || z[0] == 127)
|
||||
out << "\\x" << hexes[z[0] / 16] << hexes[z[0] % 16];
|
||||
else
|
||||
out << utf8::to8(z);
|
||||
}
|
||||
}
|
||||
out << "\\n\"\n";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void process_command(const std::string& name, JSON::node& n, std::ostream& hdr, std::ostream& imp)
|
||||
{
|
||||
hdr << "extern command::stub " << name << ";" << std::endl;
|
||||
imp << "command::stub " << name << " = {" << std::endl;
|
||||
std::string cmdname = n["__name"].as_string8();
|
||||
std::string desc = n.field_exists("__description") ? n["__description"].as_string8() :
|
||||
"No description available";
|
||||
imp << "\t" << quote_c_string(cmdname) << ", " << quote_c_string(desc) << "," << std::endl;
|
||||
bool first = true;
|
||||
for(auto i = n.begin(); i != n.end(); i++) {
|
||||
std::string hleafname = i.key8();
|
||||
if(hleafname == "__name" || hleafname == "__description" || hleafname == "__inverse" ||
|
||||
hleafname == "__class")
|
||||
continue;
|
||||
std::u32string hleafc = i->as_string();
|
||||
if(!first)
|
||||
imp << "\t\"\\n\"" << std::endl;
|
||||
first = false;
|
||||
imp << "\t" << quote_c_string(std::string("Syntax: ") + cmdname + " " + hleafname + "\n")
|
||||
<< std::endl;
|
||||
imp << quote_help(hleafc);
|
||||
}
|
||||
if(first) imp << "\t\"No help available for '" << cmdname << "'\"" << std::endl;
|
||||
imp << "};" << std::endl;
|
||||
imp << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if(argc != 2) {
|
||||
std::cerr << "Need one filename base" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::string fname = argv[1];
|
||||
|
||||
if(fname.length() > 5 && fname.substr(fname.length() - 5) == ".json")
|
||||
fname = fname.substr(0, fname.length() - 5);
|
||||
|
||||
std::ifstream infile(fname + std::string(".json"));
|
||||
std::string in_json;
|
||||
std::string tmp;
|
||||
while(infile) {
|
||||
std::getline(infile, tmp);
|
||||
in_json = in_json + tmp + "\n";
|
||||
}
|
||||
JSON::node n(in_json);
|
||||
|
||||
std::ofstream hdr(fname + std::string(".hpp"));
|
||||
std::ofstream impl(fname + std::string(".cpp"));
|
||||
impl << "#include \"cmdhelp/" << fname << ".hpp\"" << std::endl;
|
||||
impl << "namespace STUBS" << std::endl;
|
||||
impl << "{" << std::endl;
|
||||
hdr << "#pragma once" << std::endl;
|
||||
hdr << "#include \"library/command.hpp\"" << std::endl;
|
||||
hdr << "namespace STUBS" << std::endl;
|
||||
hdr << "{" << std::endl;
|
||||
for(auto i = n.begin(); i != n.end(); i++)
|
||||
process_command(i.key8(), *i, hdr, impl);
|
||||
impl << "}" << std::endl;
|
||||
hdr << "}" << std::endl;
|
||||
return 0;
|
||||
}
|
77
src/cmdhelp/mkstubsi.cpp
Normal file
77
src/cmdhelp/mkstubsi.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "json.hpp"
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
|
||||
const char* hexes = "0123456789abcdef";
|
||||
|
||||
std::string quote_c_string(const std::string& raw, bool hiraw = false);
|
||||
|
||||
std::string quote_c_string(const std::string& raw, bool hiraw)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "\"";
|
||||
for(auto i : raw) {
|
||||
unsigned char ch = i;
|
||||
if(ch == '\n')
|
||||
out << "\\n";
|
||||
else if(ch == '\"')
|
||||
out << "\\\"";
|
||||
else if(ch == '\\')
|
||||
out << "\\\\";
|
||||
else if(ch < 32 || ch == 127 || (ch > 127 && !hiraw))
|
||||
out << "\\x" << hexes[ch / 16] << hexes[ch % 16];
|
||||
else
|
||||
out << ch;
|
||||
}
|
||||
out << "\"";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void process_command_inverse(JSON::node& n, std::ostream& imp)
|
||||
{
|
||||
if(!n.field_exists("__inverse"))
|
||||
return;
|
||||
auto& inv = n["__inverse"];
|
||||
auto name = n["__name"].as_string8();
|
||||
for(auto i = inv.begin(); i != inv.end(); i++) {
|
||||
std::string args = i.key8();
|
||||
std::string desc = i->as_string8();
|
||||
if(args != "")
|
||||
imp << "\t" << quote_c_string(name + " " + args) << ", " << quote_c_string(desc, true) << ","
|
||||
<< std::endl;
|
||||
else
|
||||
imp << "\t" << quote_c_string(name) << ", " << quote_c_string(desc, true) << "," << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ofstream impl("inverselist.cpp");
|
||||
impl << "#include \"cmdhelp/inverselist.hpp\"" << std::endl;
|
||||
impl << "namespace STUBS" << std::endl;
|
||||
impl << "{" << std::endl;
|
||||
impl << "const char* inverse_cmd_list[] = {" << std::endl;
|
||||
|
||||
for(int i = 1; i < argc; i++) {
|
||||
//Hack, skip crap.
|
||||
if(argv[i][0] == 0 || argv[i][strlen(argv[i])-1] == 'e')
|
||||
continue;
|
||||
std::ifstream infile(argv[i]);
|
||||
std::string in_json;
|
||||
std::string tmp;
|
||||
while(infile) {
|
||||
std::getline(infile, tmp);
|
||||
in_json = in_json + tmp + "\n";
|
||||
}
|
||||
JSON::node n(in_json);
|
||||
for(auto j = n.begin(); j != n.end(); j++)
|
||||
process_command_inverse(*j, impl);
|
||||
}
|
||||
|
||||
impl << "\t0\n};" << std::endl;
|
||||
impl << "}" << std::endl;
|
||||
return 0;
|
||||
}
|
19
src/cmdhelp/multitrack.json
Normal file
19
src/cmdhelp/multitrack.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"multitrackf":{
|
||||
"__name":"rotate-multitrack",
|
||||
"__description":"Rotate multitrack",
|
||||
"":"Rotate multitrack state",
|
||||
"__inverse":{"":"Multitrack‣Rotate forward"}
|
||||
},
|
||||
"multitrackb":{
|
||||
"__name":"rotate-multitrack-backwards",
|
||||
"__description":"Rotate multitrack backwards",
|
||||
"":"Rotate multitrack state backwards",
|
||||
"__inverse":{"":"Multitrack‣Rotate backwards"}
|
||||
},
|
||||
"multitracks":{
|
||||
"__name":"set-multitrack",
|
||||
"__description":"Set multitrack mode",
|
||||
"<controller> <mode>":"Set multitrack mode for <controller> to <mode>"
|
||||
}
|
||||
}
|
38
src/cmdhelp/project.json
Normal file
38
src/cmdhelp/project.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"branch_ls":{
|
||||
"__class":"project",
|
||||
"__name":"list-branches",
|
||||
"__description":"List all slot branches",
|
||||
"":"List all slot branches."
|
||||
},
|
||||
"branch_mk":{
|
||||
"__class":"project",
|
||||
"__name":"create-branch",
|
||||
"__description":"Create a new slot branch",
|
||||
"<parentid> <name>":"Create new branch named <name> under <parentid>."
|
||||
},
|
||||
"branch_rm":{
|
||||
"__class":"project",
|
||||
"__name":"delete-branch",
|
||||
"__description":"Delete a slot branch",
|
||||
"<id>":"Delete slot branch with id <id>."
|
||||
},
|
||||
"branch_set":{
|
||||
"__class":"project",
|
||||
"__name":"set-branch",
|
||||
"__description":"Set current slot branch",
|
||||
"<id>":"Set current branch to <id>."
|
||||
},
|
||||
"branch_rp":{
|
||||
"__class":"project",
|
||||
"__name":"reparent-branch",
|
||||
"__description":"Reparent a slot branch",
|
||||
"<id> <newpid>":"Reparent branch <id> to be child of <newpid>."
|
||||
},
|
||||
"branch_mv":{
|
||||
"__class":"project",
|
||||
"__name":"rename-branch",
|
||||
"__description":"Rename a slot branch",
|
||||
"<id> <name>":"Rename branch <id> to <name>."
|
||||
}
|
||||
}
|
18
src/cmdhelp/subtitles.json
Normal file
18
src/cmdhelp/subtitles.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"editsub":{
|
||||
"__name":"edit-subtitle",
|
||||
"__description":"Edit a subtitle",
|
||||
"<first> <length> <text>":"Add/Edit subtitle",
|
||||
"<first> <length>":"Delete subtitle"
|
||||
},
|
||||
"listsub":{
|
||||
"__name":"list-subtitle",
|
||||
"__description":"List the subtitles",
|
||||
"":"List the subtitles."
|
||||
},
|
||||
"savesub":{
|
||||
"__name":"save-subtitle",
|
||||
"__description":"Save subtitles in .sub format",
|
||||
"<file>":"Saves subtitles in .sub format to <file>"
|
||||
}
|
||||
}
|
22
src/cmdhelp/turbo.json
Normal file
22
src/cmdhelp/turbo.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"turbot":{
|
||||
"__class":"turbo",
|
||||
"__name":"toggle-turbo",
|
||||
"__description":"Toggle turbo",
|
||||
"":"Toggle turbo mode.",
|
||||
"__inverse":{"":"Speed‣Turbo toggle"}
|
||||
},
|
||||
"turbop":{
|
||||
"__class":"turbo",
|
||||
"__name":"+turbo",
|
||||
"__description":"Activate turbo",
|
||||
"":"Activate turbo mode.",
|
||||
"__inverse":{"":"Speed‣Turbo hold"}
|
||||
},
|
||||
"turbor":{
|
||||
"__class":"turbo",
|
||||
"__name":"-turbo",
|
||||
"__description":"Deactivate turbo",
|
||||
"":"Deactivate turbo mode."
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#include "lsnes.hpp"
|
||||
|
||||
#include "cmdhelp/button.hpp"
|
||||
#include "cmdhelp/macro.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
|
@ -27,84 +29,21 @@ namespace
|
|||
else
|
||||
return ++map[key];
|
||||
}
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_p(lsnes_cmds, "+controller", "Press a button",
|
||||
"Syntax: +controller<button>...\nPress a button\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_action(a, 1, 0);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_r(lsnes_cmds, "-controller", "Release a button",
|
||||
"Syntax: -controller<button>...\nRelease a button\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_action(a, 0, 0);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_h(lsnes_cmds, "hold-controller", "Autohold a button",
|
||||
"Syntax: hold-controller<button>...\nAutohold a button\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_action(a, 1, 1);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_t(lsnes_cmds, "type-controller", "Type a button",
|
||||
"Syntax: type-controller<button>...\nType a button\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_action(a, 1, 2);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_d(lsnes_cmds, "designate-position", "Set postion",
|
||||
"Syntax: designate-position <button>...\nDesignate position for an axis\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_action(a, 0, 3);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_ap(lsnes_cmds, "+autofire-controller", "Start autofire",
|
||||
"Syntax: +autofire-controller<button> [[<duty> ]<cyclelen>]...\nAutofire a button\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_autofire_action(a, 1);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_an(lsnes_cmds, "-autofire-controller", "End autofire",
|
||||
"Syntax: -autofire-controller<button> [[<duty> ]<cyclelen>]...\nEnd Autofire on a button\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_autofire_action(a, 0);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_at(lsnes_cmds, "autofire-controller", "Toggle autofire",
|
||||
"Syntax: autofire-controller<button> [[<duty> ]<cyclelen>]...\nToggle Autofire on a button\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_autofire_action(a, -1);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_button_a(lsnes_cmds, "controller-analog", "Analog action",
|
||||
"Syntax: controller-analog <button> <axis>\nAnalog action\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().buttons->do_analog_action(a);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_macro_t(lsnes_cmds, "macro", "Toggle a macro",
|
||||
"Syntax: macro <macroname>\nToggle a macro.\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().controls->do_macro(a, 7);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_macro_e(lsnes_cmds, "+macro", "Enable a macro",
|
||||
"Syntax: +macro <macroname>\nEnable a macro.\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().controls->do_macro(a, 5);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_macro_d(lsnes_cmds, "-macro", "Disable a macro",
|
||||
"Syntax: -macro <macroname>\nDisable a macro.\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().controls->do_macro(a, 2);
|
||||
});
|
||||
}
|
||||
|
||||
button_mapping::button_mapping(controller_state& _controls, keyboard::mapper& _mapper, keyboard::keyboard& _keyboard,
|
||||
emu_framebuffer& _fbuf, emulator_dispatch& _dispatch, lua_state& _lua2)
|
||||
emu_framebuffer& _fbuf, emulator_dispatch& _dispatch, lua_state& _lua2, command::group& _cmd)
|
||||
: controls(_controls), mapper(_mapper), keyboard(_keyboard), fbuf(_fbuf), edispatch(_dispatch),
|
||||
lua2(_lua2)
|
||||
lua2(_lua2), cmd(_cmd),
|
||||
button_p(cmd, STUBS::btnp, [this](const std::string& a) { this->do_action(a, 1, 0); }),
|
||||
button_r(cmd, STUBS::btnr, [this](const std::string& a) { this->do_action(a, 0, 0); }),
|
||||
button_h(cmd, STUBS::btnh, [this](const std::string& a) { this->do_action(a, 1, 1); }),
|
||||
button_t(cmd, STUBS::btnt, [this](const std::string& a) { this->do_action(a, 1, 2); }),
|
||||
button_d(cmd, STUBS::btnd, [this](const std::string& a) { this->do_action(a, 0, 3); }),
|
||||
button_ap(cmd, STUBS::btnap, [this](const std::string& a) { this->do_autofire_action(a, 1); }),
|
||||
button_ar(cmd, STUBS::btnar, [this](const std::string& a) { this->do_autofire_action(a, 0); }),
|
||||
button_at(cmd, STUBS::btnat, [this](const std::string& a) { this->do_autofire_action(a, -1); }),
|
||||
button_a(cmd, STUBS::btna, [this](const std::string& a) { this->do_analog_action(a); })
|
||||
{
|
||||
ncore.set(notify_new_core, [this]() { this->init(); });
|
||||
}
|
||||
|
@ -170,10 +109,10 @@ void button_mapping::load(controller_state& ctrlstate)
|
|||
for(auto i : s) {
|
||||
if(!macro_binds.count(i)) {
|
||||
//New macro, create inverse bind.
|
||||
macro_binds[i] = new keyboard::invbind(mapper, "macro " + i , "Macro‣" + i +
|
||||
macro_binds[i] = new keyboard::invbind(mapper, STUBS::macrot.name + (" " + i) , "Macro‣" + i +
|
||||
" (toggle)");
|
||||
macro_binds2[i] = new keyboard::invbind(mapper, "+macro " + i , "Macro‣" + i +
|
||||
" (hold)");
|
||||
macro_binds2[i] = new keyboard::invbind(mapper, STUBS::macrop.name + (" " + i) , "Macro‣" +
|
||||
i + " (hold)");
|
||||
}
|
||||
}
|
||||
for(auto i : macro_binds) {
|
||||
|
@ -245,33 +184,33 @@ void button_mapping::add_button(const std::string& name, const button_mapping::c
|
|||
{
|
||||
keyboard::ctrlrkey* k;
|
||||
if(binding.mode == 0) {
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << "+controller "
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << STUBS::btnp.name << " "
|
||||
<< name).str(), (stringfmt() << "Controller‣" << binding.cclass << "‣#"
|
||||
<< binding.number << "‣" << binding.name).str());
|
||||
promote_key(*k);
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << "hold-controller "
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << STUBS::btnh.name << " "
|
||||
<< name).str(), (stringfmt() << "Controller‣" << binding.cclass << "‣#"
|
||||
<< binding.number << "‣" << binding.name << "‣hold").str());
|
||||
promote_key(*k);
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << "type-controller "
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << STUBS::btnt.name << " "
|
||||
<< name).str(), (stringfmt() << "Controller‣" << binding.cclass << "‣#"
|
||||
<< binding.number << "‣" << binding.name << "‣type").str());
|
||||
promote_key(*k);
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << "+autofire-controller "
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << STUBS::btnap.name << " "
|
||||
<< name).str(), (stringfmt() << "Controller‣" << binding.cclass << "‣#"
|
||||
<< binding.number << "‣" << binding.name << "‣autofire").str());
|
||||
promote_key(*k);
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << "autofire-controller "
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << STUBS::btnat.name << " "
|
||||
<< name).str(), (stringfmt() << "Controller‣" << binding.cclass << "‣#"
|
||||
<< binding.number << "‣" << binding.name << "‣autofire toggle").str());
|
||||
promote_key(*k);
|
||||
} else if(binding.mode == 1) {
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << "designate-position "
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << STUBS::btnd.name << " "
|
||||
<< name).str(), (stringfmt() << "Controller‣" << binding.cclass << "‣#"
|
||||
<< binding.number << "‣" << binding.name).str());
|
||||
promote_key(*k);
|
||||
} else if(binding.mode == 2) {
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << "controller-analog "
|
||||
k = new keyboard::ctrlrkey(mapper, (stringfmt() << STUBS::btna.name << " "
|
||||
<< name).str(), (stringfmt() << "Controller‣" << binding.cclass << "‣#"
|
||||
<< binding.number << "‣" << binding.name << " (axis)").str(), true);
|
||||
promote_key(*k);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "cmdhelp/macro.hpp"
|
||||
#include "core/controllerframe.hpp"
|
||||
#include "core/controller.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
|
@ -15,8 +16,12 @@ namespace
|
|||
}
|
||||
|
||||
controller_state::controller_state(project_state& _project, movie_logic& _mlogic, button_mapping& _buttons,
|
||||
emulator_dispatch& _dispatch, status_updater& _supdater) throw()
|
||||
: project(_project), mlogic(_mlogic), buttons(_buttons), edispatch(_dispatch), supdater(_supdater)
|
||||
emulator_dispatch& _dispatch, status_updater& _supdater, command::group& _cmd) throw()
|
||||
: project(_project), mlogic(_mlogic), buttons(_buttons), edispatch(_dispatch), supdater(_supdater),
|
||||
cmd(_cmd),
|
||||
macro_p(cmd, STUBS::macrop, [this](const std::string& a) { this->do_macro(a, 5); }),
|
||||
macro_r(cmd, STUBS::macror, [this](const std::string& a) { this->do_macro(a, 2); }),
|
||||
macro_t(cmd, STUBS::macrot, [this](const std::string& a) { this->do_macro(a, 7); })
|
||||
{
|
||||
types = &dummytypes;
|
||||
tasinput_enaged = false;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "cmdhelp/debug.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/debug.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
|
@ -48,8 +49,11 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
debug_context::debug_context(emulator_dispatch& _dispatch, loaded_rom& _rom)
|
||||
: edispatch(_dispatch), rom(_rom)
|
||||
debug_context::debug_context(emulator_dispatch& _dispatch, loaded_rom& _rom, command::group& _cmd)
|
||||
: edispatch(_dispatch), rom(_rom), cmd(_cmd),
|
||||
showhooks(cmd, STUBS::showhooks, [this]() { this->do_showhooks(); }),
|
||||
genevent(cmd, STUBS::genevent, [this](const std::string& a) { this->do_genevent(a); }),
|
||||
tracecmd(cmd, STUBS::trace, [this](const std::string& a) { this->do_tracecmd(a); })
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -286,69 +290,62 @@ void debug_context::tracelog(uint64_t proc, const std::string& filename)
|
|||
if(tracelog_change_cb) tracelog_change_cb();
|
||||
}
|
||||
|
||||
namespace
|
||||
void debug_context::do_showhooks()
|
||||
{
|
||||
command::fnptr<> CMD_callbacks_show(lsnes_cmds, "show-callbacks", "", "",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
for(auto& i : core.dbg->read_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "READ addr=" << i.first << " handle=" << &j << std::endl;
|
||||
for(auto& i : core.dbg->write_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "WRITE addr=" << i.first << " handle=" << &j << std::endl;
|
||||
for(auto& i : core.dbg->exec_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "EXEC addr=" << i.first << " handle=" << &j << std::endl;
|
||||
for(auto& i : core.dbg->trace_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "TRACE proc=" << i.first << " handle=" << &j << std::endl;
|
||||
for(auto& i : core.dbg->frame_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "FRAME handle=" << &j << std::endl;
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_generate_event(lsnes_cmds, "generate-memory-event", "", "",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
regex_results r = regex("([^ \t]+) ([^ \t]+) (.+)", args);
|
||||
if(!r) throw std::runtime_error("generate-memory-event: Bad arguments");
|
||||
if(r[1] == "r") {
|
||||
uint64_t addr = parse_value<uint64_t>(r[2]);
|
||||
uint64_t val = parse_value<uint64_t>(r[3]);
|
||||
CORE().dbg->do_callback_read(addr, val);
|
||||
} else if(r[1] == "w") {
|
||||
uint64_t addr = parse_value<uint64_t>(r[2]);
|
||||
uint64_t val = parse_value<uint64_t>(r[3]);
|
||||
CORE().dbg->do_callback_write(addr, val);
|
||||
} else if(r[1] == "x") {
|
||||
uint64_t addr = parse_value<uint64_t>(r[2]);
|
||||
uint64_t val = parse_value<uint64_t>(r[3]);
|
||||
CORE().dbg->do_callback_exec(addr, val);
|
||||
} else if(r[1] == "t") {
|
||||
uint64_t proc = parse_value<uint64_t>(r[2]);
|
||||
std::string str = r[3];
|
||||
CORE().dbg->do_callback_trace(proc, str.c_str());
|
||||
} else
|
||||
throw std::runtime_error("Invalid operation");
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_tracelog(lsnes_cmds, "tracelog", "Trace log control",
|
||||
"Trace log control\nSyntax: tracelog <cpuid> <file> Start tracing\nSyntax: tracelog <cpuid> "
|
||||
"End tracing", [](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
regex_results r = regex("([^ \t]+)([ \t]+(.+))?", args);
|
||||
if(!r) throw std::runtime_error("tracelog: Bad arguments");
|
||||
auto& core = CORE();
|
||||
std::string cpu = r[1];
|
||||
std::string filename = r[3];
|
||||
uint64_t _cpu = 0;
|
||||
for(auto i : core.rom->get_trace_cpus()) {
|
||||
if(cpu == i)
|
||||
goto out;
|
||||
_cpu++;
|
||||
}
|
||||
throw std::runtime_error("tracelog: Invalid CPU");
|
||||
out:
|
||||
core.dbg->tracelog(_cpu, filename);
|
||||
});
|
||||
|
||||
for(auto& i : read_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "READ addr=" << i.first << " handle=" << &j << std::endl;
|
||||
for(auto& i : write_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "WRITE addr=" << i.first << " handle=" << &j << std::endl;
|
||||
for(auto& i : exec_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "EXEC addr=" << i.first << " handle=" << &j << std::endl;
|
||||
for(auto& i : trace_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "TRACE proc=" << i.first << " handle=" << &j << std::endl;
|
||||
for(auto& i : frame_cb)
|
||||
for(auto& j : i.second)
|
||||
messages << "FRAME handle=" << &j << std::endl;
|
||||
}
|
||||
|
||||
void debug_context::do_genevent(const std::string& args)
|
||||
{
|
||||
regex_results r = regex("([^ \t]+) ([^ \t]+) (.+)", args);
|
||||
if(!r) throw std::runtime_error("generate-memory-event: Bad arguments");
|
||||
if(r[1] == "r") {
|
||||
uint64_t addr = parse_value<uint64_t>(r[2]);
|
||||
uint64_t val = parse_value<uint64_t>(r[3]);
|
||||
do_callback_read(addr, val);
|
||||
} else if(r[1] == "w") {
|
||||
uint64_t addr = parse_value<uint64_t>(r[2]);
|
||||
uint64_t val = parse_value<uint64_t>(r[3]);
|
||||
do_callback_write(addr, val);
|
||||
} else if(r[1] == "x") {
|
||||
uint64_t addr = parse_value<uint64_t>(r[2]);
|
||||
uint64_t val = parse_value<uint64_t>(r[3]);
|
||||
do_callback_exec(addr, val);
|
||||
} else if(r[1] == "t") {
|
||||
uint64_t proc = parse_value<uint64_t>(r[2]);
|
||||
std::string str = r[3];
|
||||
do_callback_trace(proc, str.c_str());
|
||||
} else
|
||||
throw std::runtime_error("Invalid operation");
|
||||
}
|
||||
|
||||
void debug_context::do_tracecmd(const std::string& args)
|
||||
{
|
||||
regex_results r = regex("([^ \t]+)([ \t]+(.+))?", args);
|
||||
if(!r) throw std::runtime_error("tracelog: Bad arguments");
|
||||
std::string cpu = r[1];
|
||||
std::string filename = r[3];
|
||||
uint64_t _cpu = 0;
|
||||
for(auto i : rom.get_trace_cpus()) {
|
||||
if(cpu == i)
|
||||
goto out;
|
||||
_cpu++;
|
||||
}
|
||||
throw std::runtime_error("tracelog: Invalid CPU");
|
||||
out:
|
||||
tracelog(_cpu, filename);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "cmdhelp/framebuffer.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
#include "core/emustatus.hpp"
|
||||
|
@ -77,13 +78,6 @@ namespace
|
|||
draw_special_screen(target, rl_corrupt);
|
||||
}
|
||||
|
||||
command::fnptr<command::arg_filename> CMD_take_screenshot(lsnes_cmds, "take-screenshot", "Takes a screenshot",
|
||||
"Syntax: take-screenshot <file>\nSaves screenshot to PNG file <file>\n",
|
||||
[](command::arg_filename file) throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().fbuf->take_screenshot(file);
|
||||
messages << "Saved PNG screenshot" << std::endl;
|
||||
});
|
||||
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> SET_dtb(lsnes_setgrp, "top-border",
|
||||
"UI‣Top padding", 0);
|
||||
settingvar::supervariable<settingvar::model_int<0, 8191>> SET_dbb(lsnes_setgrp, "bottom-border",
|
||||
|
@ -98,13 +92,21 @@ framebuffer::raw emu_framebuffer::screen_corrupt;
|
|||
|
||||
emu_framebuffer::emu_framebuffer(subtitle_commentary& _subtitles, settingvar::group& _settings, memwatch_set& _mwatch,
|
||||
keyboard::keyboard& _keyboard, emulator_dispatch& _dispatch, lua_state& _lua2, loaded_rom& _rom,
|
||||
status_updater& _supdater)
|
||||
status_updater& _supdater, command::group& _cmd)
|
||||
: buffering(buffer1, buffer2, buffer3), subtitles(_subtitles), settings(_settings), mwatch(_mwatch),
|
||||
keyboard(_keyboard), edispatch(_dispatch), lua2(_lua2), rom(_rom), supdater(_supdater)
|
||||
keyboard(_keyboard), edispatch(_dispatch), lua2(_lua2), rom(_rom), supdater(_supdater), cmd(_cmd),
|
||||
screenshot(cmd, STUBS::screenshot, [this](command::arg_filename a) { this->do_screenshot(a); })
|
||||
{
|
||||
last_redraw_no_lua = false;
|
||||
}
|
||||
|
||||
void emu_framebuffer::do_screenshot(command::arg_filename file)
|
||||
{
|
||||
std::string fn = file;
|
||||
take_screenshot(fn);
|
||||
messages << "Saved PNG screenshot to '" << fn << "'" << std::endl;
|
||||
}
|
||||
|
||||
void emu_framebuffer::take_screenshot(const std::string& file) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
render_info& ri = buffering.get_read();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "core/command.hpp"
|
||||
#include "core/framerate.hpp"
|
||||
#include "cmdhelp/turbo.hpp"
|
||||
#include "core/instance.hpp"
|
||||
#include "core/keymapper.hpp"
|
||||
#include "core/moviedata.hpp"
|
||||
|
@ -16,32 +17,11 @@
|
|||
|
||||
bool graphics_driver_is_dummy();
|
||||
|
||||
namespace
|
||||
{
|
||||
command::fnptr<> CMD_tturbo(lsnes_cmds, "toggle-turbo", "Toggle turbo",
|
||||
"Syntax: toggle-turbo\nToggle turbo mode.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().framerate->turboed = !CORE().framerate->turboed;
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_pturbo(lsnes_cmds, "+turbo", "Activate turbo",
|
||||
"Syntax: +turbo\nActivate turbo mode.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().framerate->turboed = true;
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_nturbo(lsnes_cmds, "-turbo", "Deactivate turbo",
|
||||
"Syntax: -turbo\nDeactivate turbo mode.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().framerate->turboed = false;
|
||||
});
|
||||
|
||||
keyboard::invbind_info IBIND_turboh(lsnes_invbinds, "+turbo", "Speed‣Turbo hold");
|
||||
keyboard::invbind_info IBIND_turbot(lsnes_invbinds, "toggle-turbo", "Speed‣Turbo toggle");
|
||||
}
|
||||
|
||||
|
||||
framerate_regulator::framerate_regulator()
|
||||
framerate_regulator::framerate_regulator(command::group& _cmd)
|
||||
: cmd(_cmd),
|
||||
turbo_p(cmd, STUBS::turbop, [this]() { this->turboed = true; }),
|
||||
turbo_r(cmd, STUBS::turbor, [this]() { this->turboed = false; }),
|
||||
turbo_t(cmd, STUBS::turbot, [this]() { this->turboed = !this->turboed; })
|
||||
{
|
||||
last_time_update = 0;
|
||||
time_at_last_update = 0;
|
||||
|
|
|
@ -85,19 +85,19 @@ emulator_instance::emulator_instance()
|
|||
D.init(lua2, *lua, *command);
|
||||
D.init(mwatch, *memory, *project, *fbuf, *rom);
|
||||
D.init(settings);
|
||||
D.init(jukebox, *settings);
|
||||
D.init(jukebox, *settings, *command);
|
||||
D.init(setcache, *settings);
|
||||
D.init(audio);
|
||||
D.init(commentary, *settings, *dispatch, *audio);
|
||||
D.init(subtitles, *mlogic, *fbuf, *dispatch);
|
||||
D.init(commentary, *settings, *dispatch, *audio, *command);
|
||||
D.init(subtitles, *mlogic, *fbuf, *dispatch, *command);
|
||||
D.init(mbranch, *mlogic, *dispatch, *supdater);
|
||||
D.init(controls, *project, *mlogic, *buttons, *dispatch, *supdater);
|
||||
D.init(controls, *project, *mlogic, *buttons, *dispatch, *supdater, *command);
|
||||
D.init(keyboard);
|
||||
D.init(mapper, *keyboard, *command);
|
||||
D.init(rom);
|
||||
D.init(fbuf, *subtitles, *settings, *mwatch, *keyboard, *dispatch, *lua2, *rom, *supdater);
|
||||
D.init(buttons, *controls, *mapper, *keyboard, *fbuf, *dispatch, *lua2);
|
||||
D.init(mteditor, *mlogic, *controls, *dispatch, *supdater);
|
||||
D.init(fbuf, *subtitles, *settings, *mwatch, *keyboard, *dispatch, *lua2, *rom, *supdater, *command);
|
||||
D.init(buttons, *controls, *mapper, *keyboard, *fbuf, *dispatch, *lua2, *command);
|
||||
D.init(mteditor, *mlogic, *controls, *dispatch, *supdater, *buttons, *command);
|
||||
D.init(status_A);
|
||||
D.init(status_B);
|
||||
D.init(status_C);
|
||||
|
@ -107,8 +107,8 @@ emulator_instance::emulator_instance()
|
|||
D.init(cmapper, *memory, *mlogic, *rom);
|
||||
D.init(project, *commentary, *mwatch, *command, *controls, *setcache, *buttons, *dispatch, *iqueue, *rom,
|
||||
*supdater);
|
||||
D.init(dbg, *dispatch, *rom);
|
||||
D.init(framerate);
|
||||
D.init(dbg, *dispatch, *rom, *command);
|
||||
D.init(framerate, *command);
|
||||
D.init(mdumper, *lua2);
|
||||
D.init(runmode);
|
||||
D.init(supdater, *project, *mlogic, *commentary, *status, *runmode, *mdumper, *jukebox, *slotcache,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "lsnes.hpp"
|
||||
|
||||
#include "cmdhelp/commentary.hpp"
|
||||
#include "core/audioapi.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
|
@ -1715,24 +1716,13 @@ out:
|
|||
voicesub_state& internal;
|
||||
audioapi_instance& audio;
|
||||
};
|
||||
|
||||
//The tangent function.
|
||||
command::fnptr<> CMD_ptangent(lsnes_cmds, "+tangent", "Voice tangent",
|
||||
"Syntax: +tangent\nVoice tangent.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().commentary->set_active_flag(true);
|
||||
});
|
||||
command::fnptr<> CMD_ntangent(lsnes_cmds, "-tangent", "Voice tangent",
|
||||
"Syntax: -tangent\nVoice tangent.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
CORE().commentary->set_active_flag(false);
|
||||
});
|
||||
keyboard::invbind_info IBIND_itangent(lsnes_invbinds, "+tangent", "Movie‣Voice tangent");
|
||||
}
|
||||
|
||||
voice_commentary::voice_commentary(settingvar::group& _settings, emulator_dispatch& _dispatch,
|
||||
audioapi_instance& _audio)
|
||||
: settings(_settings), edispatch(_dispatch), audio(_audio)
|
||||
audioapi_instance& _audio, command::group& _cmd)
|
||||
: settings(_settings), edispatch(_dispatch), audio(_audio), cmd(_cmd),
|
||||
tangentp(cmd, STUBS::tangentp, [this]() { this->set_active_flag(true); }),
|
||||
tangentr(cmd, STUBS::tangentr, [this]() { this->set_active_flag(false); })
|
||||
{
|
||||
internal = NULL;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "cmdhelp/jukebox.hpp"
|
||||
#include "core/jukebox.hpp"
|
||||
#include "core/settings.hpp"
|
||||
#include "library/settingvar.hpp"
|
||||
|
@ -30,8 +31,11 @@ private:
|
|||
save_jukebox& jukebox;
|
||||
};
|
||||
|
||||
save_jukebox::save_jukebox(settingvar::group& _settings)
|
||||
: settings(_settings)
|
||||
save_jukebox::save_jukebox(settingvar::group& _settings, command::group& _cmd)
|
||||
: settings(_settings), cmd(_cmd),
|
||||
slotsel(cmd, STUBS::slotselect, [this](const std::string& a) { this->do_slotsel(a); }),
|
||||
cycleprev(cmd, STUBS::slotprev, [this]() { this->cycle_prev(); }),
|
||||
cyclenext(cmd, STUBS::slotnext, [this]() { this->cycle_next(); })
|
||||
{
|
||||
listener = new save_jukebox_listener(_settings, *this);
|
||||
}
|
||||
|
@ -104,3 +108,11 @@ void save_jukebox::unset_update()
|
|||
{
|
||||
update = std::function<void()>();
|
||||
}
|
||||
|
||||
void save_jukebox::do_slotsel(const std::string& args)
|
||||
{
|
||||
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);
|
||||
set_slot(slot - 1);
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#include "lsnes.hpp"
|
||||
|
||||
#include "cmdhelp/loadsave.hpp"
|
||||
#include "cmdhelp/mhold.hpp"
|
||||
#include "core/advdumper.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
|
@ -379,30 +381,6 @@ namespace
|
|||
}
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_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) {
|
||||
auto& core = CORE();
|
||||
core.jukebox->cycle_prev();
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_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) {
|
||||
auto& core = CORE();
|
||||
core.jukebox->cycle_next();
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_save_jukebox_set(lsnes_cmds, "set-jukebox-slot", "Set jukebox slot",
|
||||
"Syntax: set-jukebox-slot\nSet jukebox slot\n", [](const std::string& args)
|
||||
throw(std::bad_alloc, std::runtime_error) {
|
||||
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);
|
||||
auto& core = CORE();
|
||||
core.jukebox->set_slot(slot - 1);
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_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) {
|
||||
|
@ -519,8 +497,7 @@ namespace
|
|||
core.rom->execute_action(hreset_action, std::vector<interface_action_paramval>());
|
||||
});
|
||||
|
||||
command::fnptr<command::arg_filename> CMD_load_c(lsnes_cmds, "load", "Load savestate (current mode)",
|
||||
"Syntax: load <file>\nLoads SNES state from <file> in current mode\n",
|
||||
command::fnptr<command::arg_filename> CMD_load_c(lsnes_cmds, STUBS::load,
|
||||
[](command::arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_load(args, LOAD_STATE_CURRENT);
|
||||
});
|
||||
|
@ -564,8 +541,7 @@ namespace
|
|||
mark_pending_load(args, LOAD_STATE_ALLBRANCH);
|
||||
});
|
||||
|
||||
command::fnptr<command::arg_filename> CMD_save_state(lsnes_cmds, "save-state", "Save state",
|
||||
"Syntax: save-state <file>\nSaves SNES state to <file>\n",
|
||||
command::fnptr<command::arg_filename> CMD_save_state(lsnes_cmds, STUBS::savestate,
|
||||
[](command::arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_save(args, SAVE_STATE, -1);
|
||||
});
|
||||
|
@ -679,30 +655,23 @@ namespace
|
|||
CORE().slotcache->flush();
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_mhold1(lsnes_cmds, "+hold-macro", "Hold macro (hold)",
|
||||
"Hold macros enable\n", []() throw(std::bad_alloc, std::runtime_error) {
|
||||
macro_hold_1 = true;
|
||||
});
|
||||
command::fnptr<> CMD_mhold1(lsnes_cmds, STUBS::mholdp, []() throw(std::bad_alloc, std::runtime_error) {
|
||||
macro_hold_1 = true;
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_mhold2(lsnes_cmds, "-hold-macro", "Hold macro (hold)",
|
||||
"Hold macros disable\n", []() throw(std::bad_alloc, std::runtime_error) {
|
||||
macro_hold_1 = false;
|
||||
});
|
||||
command::fnptr<> CMD_mhold2(lsnes_cmds, STUBS::mholdr, []() throw(std::bad_alloc, std::runtime_error) {
|
||||
macro_hold_1 = false;
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_mhold3(lsnes_cmds, "hold-macro", "Hold macro (toggle)",
|
||||
"Hold macros toggle\n", []() throw(std::bad_alloc, std::runtime_error) {
|
||||
macro_hold_2 = !macro_hold_2;
|
||||
if(macro_hold_2)
|
||||
messages << "Macros are held for next frame." << std::endl;
|
||||
else
|
||||
messages << "Macros are not held for next frame." << std::endl;
|
||||
});
|
||||
command::fnptr<> CMD_mhold3(lsnes_cmds, STUBS::mholdt, []() throw(std::bad_alloc, std::runtime_error) {
|
||||
macro_hold_2 = !macro_hold_2;
|
||||
if(macro_hold_2)
|
||||
messages << "Macros are held for next frame." << std::endl;
|
||||
else
|
||||
messages << "Macros are not held for next frame." << std::endl;
|
||||
});
|
||||
|
||||
keyboard::invbind_info IBIND_imhold1(lsnes_invbinds, "+hold-macro", "Macro‣Hold all macros");
|
||||
keyboard::invbind_info IBIND_imhold2(lsnes_invbinds, "hold-macro", "Macro‣Hold all macros (typed)");
|
||||
keyboard::invbind_info IBIND_ipause_emulator(lsnes_invbinds, "pause-emulator", "Speed‣(Un)pause");
|
||||
keyboard::invbind_info IBIND_ijback(lsnes_invbinds, "cycle-jukebox-backward", "Slot select‣Cycle backwards");
|
||||
keyboard::invbind_info IBIND_ijforward(lsnes_invbinds, "cycle-jukebox-forward", "Slot select‣Cycle forwards");
|
||||
keyboard::invbind_info IBIND_iloadj(lsnes_invbinds, "load-jukebox", "Load‣Selected slot");
|
||||
keyboard::invbind_info IBIND_iloadjrw(lsnes_invbinds, "load-jukebox-readwrite",
|
||||
"Load‣Selected slot (recording mode)");
|
||||
|
@ -723,102 +692,6 @@ namespace
|
|||
keyboard::invbind_info IBIND_itogglepause(lsnes_invbinds, "toggle-pause-on-end", "Movie‣Toggle pause-on-end");
|
||||
keyboard::invbind_info IBIND_irewind_movie(lsnes_invbinds, "rewind-movie", "Movie‣Rewind movie");
|
||||
keyboard::invbind_info IBIND_icancel_saves(lsnes_invbinds, "cancel-saves", "Save‣Cancel pending saves");
|
||||
keyboard::invbind_info IBIND_iload1(lsnes_invbinds, "load $SLOT:1", "Load‣Slot 1");
|
||||
keyboard::invbind_info IBIND_iload2(lsnes_invbinds, "load $SLOT:2", "Load‣Slot 2");
|
||||
keyboard::invbind_info IBIND_iload3(lsnes_invbinds, "load $SLOT:3", "Load‣Slot 3");
|
||||
keyboard::invbind_info IBIND_iload4(lsnes_invbinds, "load $SLOT:4", "Load‣Slot 4");
|
||||
keyboard::invbind_info IBIND_iload5(lsnes_invbinds, "load $SLOT:5", "Load‣Slot 5");
|
||||
keyboard::invbind_info IBIND_iload6(lsnes_invbinds, "load $SLOT:6", "Load‣Slot 6");
|
||||
keyboard::invbind_info IBIND_iload7(lsnes_invbinds, "load $SLOT:7", "Load‣Slot 7");
|
||||
keyboard::invbind_info IBIND_iload8(lsnes_invbinds, "load $SLOT:8", "Load‣Slot 8");
|
||||
keyboard::invbind_info IBIND_iload9(lsnes_invbinds, "load $SLOT:9", "Load‣Slot 9");
|
||||
keyboard::invbind_info IBIND_iload10(lsnes_invbinds, "load $SLOT:10", "Load‣Slot 10");
|
||||
keyboard::invbind_info IBIND_iload11(lsnes_invbinds, "load $SLOT:11", "Load‣Slot 11");
|
||||
keyboard::invbind_info IBIND_iload12(lsnes_invbinds, "load $SLOT:12", "Load‣Slot 12");
|
||||
keyboard::invbind_info IBIND_iload13(lsnes_invbinds, "load $SLOT:13", "Load‣Slot 13");
|
||||
keyboard::invbind_info IBIND_iload14(lsnes_invbinds, "load $SLOT:14", "Load‣Slot 14");
|
||||
keyboard::invbind_info IBIND_iload15(lsnes_invbinds, "load $SLOT:15", "Load‣Slot 15");
|
||||
keyboard::invbind_info IBIND_iload16(lsnes_invbinds, "load $SLOT:16", "Load‣Slot 16");
|
||||
keyboard::invbind_info IBIND_iload17(lsnes_invbinds, "load $SLOT:17", "Load‣Slot 17");
|
||||
keyboard::invbind_info IBIND_iload18(lsnes_invbinds, "load $SLOT:18", "Load‣Slot 18");
|
||||
keyboard::invbind_info IBIND_iload19(lsnes_invbinds, "load $SLOT:19", "Load‣Slot 19");
|
||||
keyboard::invbind_info IBIND_iload20(lsnes_invbinds, "load $SLOT:20", "Load‣Slot 20");
|
||||
keyboard::invbind_info IBIND_iload21(lsnes_invbinds, "load $SLOT:21", "Load‣Slot 21");
|
||||
keyboard::invbind_info IBIND_iload22(lsnes_invbinds, "load $SLOT:22", "Load‣Slot 22");
|
||||
keyboard::invbind_info IBIND_iload23(lsnes_invbinds, "load $SLOT:23", "Load‣Slot 23");
|
||||
keyboard::invbind_info IBIND_iload24(lsnes_invbinds, "load $SLOT:24", "Load‣Slot 24");
|
||||
keyboard::invbind_info IBIND_iload25(lsnes_invbinds, "load $SLOT:25", "Load‣Slot 25");
|
||||
keyboard::invbind_info IBIND_iload26(lsnes_invbinds, "load $SLOT:26", "Load‣Slot 26");
|
||||
keyboard::invbind_info IBIND_iload27(lsnes_invbinds, "load $SLOT:27", "Load‣Slot 27");
|
||||
keyboard::invbind_info IBIND_iload28(lsnes_invbinds, "load $SLOT:28", "Load‣Slot 28");
|
||||
keyboard::invbind_info IBIND_iload29(lsnes_invbinds, "load $SLOT:29", "Load‣Slot 29");
|
||||
keyboard::invbind_info IBIND_iload30(lsnes_invbinds, "load $SLOT:30", "Load‣Slot 30");
|
||||
keyboard::invbind_info IBIND_iload31(lsnes_invbinds, "load $SLOT:31", "Load‣Slot 31");
|
||||
keyboard::invbind_info IBIND_iload32(lsnes_invbinds, "load $SLOT:32", "Load‣Slot 32");
|
||||
keyboard::invbind_info IBIND_isave1(lsnes_invbinds, "save-state $SLOT:1", "Save‣Slot 1");
|
||||
keyboard::invbind_info IBIND_isave2(lsnes_invbinds, "save-state $SLOT:2", "Save‣Slot 2");
|
||||
keyboard::invbind_info IBIND_isave3(lsnes_invbinds, "save-state $SLOT:3", "Save‣Slot 3");
|
||||
keyboard::invbind_info IBIND_isave4(lsnes_invbinds, "save-state $SLOT:4", "Save‣Slot 4");
|
||||
keyboard::invbind_info IBIND_isave5(lsnes_invbinds, "save-state $SLOT:5", "Save‣Slot 5");
|
||||
keyboard::invbind_info IBIND_isave6(lsnes_invbinds, "save-state $SLOT:6", "Save‣Slot 6");
|
||||
keyboard::invbind_info IBIND_isave7(lsnes_invbinds, "save-state $SLOT:7", "Save‣Slot 7");
|
||||
keyboard::invbind_info IBIND_isave8(lsnes_invbinds, "save-state $SLOT:8", "Save‣Slot 8");
|
||||
keyboard::invbind_info IBIND_isave9(lsnes_invbinds, "save-state $SLOT:9", "Save‣Slot 9");
|
||||
keyboard::invbind_info IBIND_isave10(lsnes_invbinds, "save-state $SLOT:10", "Save‣Slot 10");
|
||||
keyboard::invbind_info IBIND_isave11(lsnes_invbinds, "save-state $SLOT:11", "Save‣Slot 11");
|
||||
keyboard::invbind_info IBIND_isave12(lsnes_invbinds, "save-state $SLOT:12", "Save‣Slot 12");
|
||||
keyboard::invbind_info IBIND_isave13(lsnes_invbinds, "save-state $SLOT:13", "Save‣Slot 13");
|
||||
keyboard::invbind_info IBIND_isave14(lsnes_invbinds, "save-state $SLOT:14", "Save‣Slot 14");
|
||||
keyboard::invbind_info IBIND_isave15(lsnes_invbinds, "save-state $SLOT:15", "Save‣Slot 15");
|
||||
keyboard::invbind_info IBIND_isave16(lsnes_invbinds, "save-state $SLOT:16", "Save‣Slot 16");
|
||||
keyboard::invbind_info IBIND_isave17(lsnes_invbinds, "save-state $SLOT:17", "Save‣Slot 17");
|
||||
keyboard::invbind_info IBIND_isave18(lsnes_invbinds, "save-state $SLOT:18", "Save‣Slot 18");
|
||||
keyboard::invbind_info IBIND_isave19(lsnes_invbinds, "save-state $SLOT:19", "Save‣Slot 19");
|
||||
keyboard::invbind_info IBIND_isave20(lsnes_invbinds, "save-state $SLOT:20", "Save‣Slot 20");
|
||||
keyboard::invbind_info IBIND_isave21(lsnes_invbinds, "save-state $SLOT:21", "Save‣Slot 21");
|
||||
keyboard::invbind_info IBIND_isave22(lsnes_invbinds, "save-state $SLOT:22", "Save‣Slot 22");
|
||||
keyboard::invbind_info IBIND_isave23(lsnes_invbinds, "save-state $SLOT:23", "Save‣Slot 23");
|
||||
keyboard::invbind_info IBIND_isave24(lsnes_invbinds, "save-state $SLOT:24", "Save‣Slot 24");
|
||||
keyboard::invbind_info IBIND_isave25(lsnes_invbinds, "save-state $SLOT:25", "Save‣Slot 25");
|
||||
keyboard::invbind_info IBIND_isave26(lsnes_invbinds, "save-state $SLOT:26", "Save‣Slot 26");
|
||||
keyboard::invbind_info IBIND_isave27(lsnes_invbinds, "save-state $SLOT:27", "Save‣Slot 27");
|
||||
keyboard::invbind_info IBIND_isave28(lsnes_invbinds, "save-state $SLOT:28", "Save‣Slot 28");
|
||||
keyboard::invbind_info IBIND_isave29(lsnes_invbinds, "save-state $SLOT:29", "Save‣Slot 29");
|
||||
keyboard::invbind_info IBIND_isave30(lsnes_invbinds, "save-state $SLOT:30", "Save‣Slot 30");
|
||||
keyboard::invbind_info IBIND_isave31(lsnes_invbinds, "save-state $SLOT:31", "Save‣Slot 31");
|
||||
keyboard::invbind_info IBIND_isave32(lsnes_invbinds, "save-state $SLOT:32", "Save‣Slot 32");
|
||||
keyboard::invbind_info IBIND_islot1(lsnes_invbinds, "set-jukebox-slot 1", "Slot select‣Slot 1");
|
||||
keyboard::invbind_info IBIND_islot2(lsnes_invbinds, "set-jukebox-slot 2", "Slot select‣Slot 2");
|
||||
keyboard::invbind_info IBIND_islot3(lsnes_invbinds, "set-jukebox-slot 3", "Slot select‣Slot 3");
|
||||
keyboard::invbind_info IBIND_islot4(lsnes_invbinds, "set-jukebox-slot 4", "Slot select‣Slot 4");
|
||||
keyboard::invbind_info IBIND_islot5(lsnes_invbinds, "set-jukebox-slot 5", "Slot select‣Slot 5");
|
||||
keyboard::invbind_info IBIND_islot6(lsnes_invbinds, "set-jukebox-slot 6", "Slot select‣Slot 6");
|
||||
keyboard::invbind_info IBIND_islot7(lsnes_invbinds, "set-jukebox-slot 7", "Slot select‣Slot 7");
|
||||
keyboard::invbind_info IBIND_islot8(lsnes_invbinds, "set-jukebox-slot 8", "Slot select‣Slot 8");
|
||||
keyboard::invbind_info IBIND_islot9(lsnes_invbinds, "set-jukebox-slot 9", "Slot select‣Slot 9");
|
||||
keyboard::invbind_info IBIND_islot10(lsnes_invbinds, "set-jukebox-slot 10", "Slot select‣Slot 10");
|
||||
keyboard::invbind_info IBIND_islot11(lsnes_invbinds, "set-jukebox-slot 11", "Slot select‣Slot 11");
|
||||
keyboard::invbind_info IBIND_islot12(lsnes_invbinds, "set-jukebox-slot 12", "Slot select‣Slot 12");
|
||||
keyboard::invbind_info IBIND_islot13(lsnes_invbinds, "set-jukebox-slot 13", "Slot select‣Slot 13");
|
||||
keyboard::invbind_info IBIND_islot14(lsnes_invbinds, "set-jukebox-slot 14", "Slot select‣Slot 14");
|
||||
keyboard::invbind_info IBIND_islot15(lsnes_invbinds, "set-jukebox-slot 15", "Slot select‣Slot 15");
|
||||
keyboard::invbind_info IBIND_islot16(lsnes_invbinds, "set-jukebox-slot 16", "Slot select‣Slot 16");
|
||||
keyboard::invbind_info IBIND_islot17(lsnes_invbinds, "set-jukebox-slot 17", "Slot select‣Slot 17");
|
||||
keyboard::invbind_info IBIND_islot18(lsnes_invbinds, "set-jukebox-slot 18", "Slot select‣Slot 18");
|
||||
keyboard::invbind_info IBIND_islot19(lsnes_invbinds, "set-jukebox-slot 19", "Slot select‣Slot 19");
|
||||
keyboard::invbind_info IBIND_islot20(lsnes_invbinds, "set-jukebox-slot 20", "Slot select‣Slot 20");
|
||||
keyboard::invbind_info IBIND_islot21(lsnes_invbinds, "set-jukebox-slot 21", "Slot select‣Slot 21");
|
||||
keyboard::invbind_info IBIND_islot22(lsnes_invbinds, "set-jukebox-slot 22", "Slot select‣Slot 22");
|
||||
keyboard::invbind_info IBIND_islot23(lsnes_invbinds, "set-jukebox-slot 23", "Slot select‣Slot 23");
|
||||
keyboard::invbind_info IBIND_islot24(lsnes_invbinds, "set-jukebox-slot 24", "Slot select‣Slot 24");
|
||||
keyboard::invbind_info IBIND_islot25(lsnes_invbinds, "set-jukebox-slot 25", "Slot select‣Slot 25");
|
||||
keyboard::invbind_info IBIND_islot26(lsnes_invbinds, "set-jukebox-slot 26", "Slot select‣Slot 26");
|
||||
keyboard::invbind_info IBIND_islot27(lsnes_invbinds, "set-jukebox-slot 27", "Slot select‣Slot 27");
|
||||
keyboard::invbind_info IBIND_islot28(lsnes_invbinds, "set-jukebox-slot 28", "Slot select‣Slot 28");
|
||||
keyboard::invbind_info IBIND_islot29(lsnes_invbinds, "set-jukebox-slot 29", "Slot select‣Slot 29");
|
||||
keyboard::invbind_info IBIND_islot30(lsnes_invbinds, "set-jukebox-slot 30", "Slot select‣Slot 30");
|
||||
keyboard::invbind_info IBIND_islot31(lsnes_invbinds, "set-jukebox-slot 31", "Slot select‣Slot 31");
|
||||
keyboard::invbind_info IBIND_islot32(lsnes_invbinds, "set-jukebox-slot 32", "Slot select‣Slot 32");
|
||||
|
||||
class mywindowcallbacks : public master_dumper::notifier
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "cmdhelp/multitrack.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
|
@ -11,8 +12,12 @@
|
|||
#include <string>
|
||||
|
||||
multitrack_edit::multitrack_edit(movie_logic& _mlogic, controller_state& _controls, emulator_dispatch& _dispatch,
|
||||
status_updater& _supdater)
|
||||
: mlogic(_mlogic), controls(_controls), edispatch(_dispatch), supdater(_supdater)
|
||||
status_updater& _supdater, button_mapping& _buttons, command::group& _cmd)
|
||||
: mlogic(_mlogic), controls(_controls), edispatch(_dispatch), supdater(_supdater), buttons(_buttons),
|
||||
cmd(_cmd),
|
||||
mt_f(cmd, STUBS::multitrackf, [this]() { this->do_mt_fwd(); }),
|
||||
mt_b(cmd, STUBS::multitrackb, [this]() { this->do_mt_bw(); }),
|
||||
mt_s(cmd, STUBS::multitracks, [this](const std::string& a) { this->do_mt_set(a); })
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -172,51 +177,41 @@ bool multitrack_edit::any_records()
|
|||
return any_need;
|
||||
}
|
||||
|
||||
void multitrack_edit::do_mt_set(const std::string& args)
|
||||
{
|
||||
regex_results r = regex("(.*)[ \t]+(.*)", args);
|
||||
if(!r)
|
||||
throw std::runtime_error("Bad arguments");
|
||||
auto c = buttons.byname(r[1]);
|
||||
if(c.first < 0)
|
||||
throw std::runtime_error("No such controller");
|
||||
if(r[2] == "keep")
|
||||
set_and_notify(c.first, c.second, multitrack_edit::MT_PRESERVE);
|
||||
else if(r[2] == "rewrite")
|
||||
set_and_notify(c.first, c.second, multitrack_edit::MT_OVERWRITE);
|
||||
else if(r[2] == "or")
|
||||
set_and_notify(c.first, c.second, multitrack_edit::MT_OR);
|
||||
else if(r[2] == "xor")
|
||||
set_and_notify(c.first, c.second, multitrack_edit::MT_XOR);
|
||||
else
|
||||
throw std::runtime_error("Invalid mode (keep, rewrite, or, xor)");
|
||||
supdater.update();
|
||||
}
|
||||
|
||||
void multitrack_edit::do_mt_fwd()
|
||||
{
|
||||
rotate(true);
|
||||
supdater.update();
|
||||
}
|
||||
|
||||
void multitrack_edit::do_mt_bw()
|
||||
{
|
||||
rotate(false);
|
||||
supdater.update();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
command::fnptr<> CMD_rotate_forward(lsnes_cmds, "rotate-multitrack", "Rotate multitrack",
|
||||
"Syntax: rotate-multitrack\nRotate multitrack\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
core.mteditor->rotate(true);
|
||||
core.supdater->update();
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_rotate_backward(lsnes_cmds, "rotate-multitrack-backwards", "Rotate multitrack backwards",
|
||||
"Syntax: rotate-multitrack-backwards\nRotate multitrack backwards\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
core.mteditor->rotate(false);
|
||||
core.supdater->update();
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_set_mt(lsnes_cmds, "set-multitrack", "Set multitrack mode",
|
||||
"Syntax: set-multitrack <controller> <mode>\nSet multitrack mode\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
regex_results r = regex("(.*)[ \t]+(.*)", args);
|
||||
if(!r)
|
||||
throw std::runtime_error("Bad arguments");
|
||||
auto c = core.buttons->byname(r[1]);
|
||||
if(c.first < 0)
|
||||
throw std::runtime_error("No such controller");
|
||||
if(r[2] == "keep")
|
||||
core.mteditor->set_and_notify(c.first, c.second, multitrack_edit::MT_PRESERVE);
|
||||
else if(r[2] == "rewrite")
|
||||
core.mteditor->set_and_notify(c.first, c.second, multitrack_edit::MT_OVERWRITE);
|
||||
else if(r[2] == "or")
|
||||
core.mteditor->set_and_notify(c.first, c.second, multitrack_edit::MT_OR);
|
||||
else if(r[2] == "xor")
|
||||
core.mteditor->set_and_notify(c.first, c.second, multitrack_edit::MT_XOR);
|
||||
else
|
||||
throw std::runtime_error("Invalid mode (keep, rewrite, or, xor)");
|
||||
core.supdater->update();
|
||||
});
|
||||
|
||||
keyboard::invbind_info IBIND_mtback(lsnes_invbinds, "rotate-multitrack-backwards",
|
||||
"Multitrack‣Rotate backwards");
|
||||
keyboard::invbind_info IBIND_mtfwd(lsnes_invbinds, "rotate-multitrack", "Multitrack‣Rotate forward");
|
||||
|
||||
int multitrack_state(lua::state& L, lua::parameters& P)
|
||||
{
|
||||
unsigned port, controller;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "cmdhelp/project.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/controller.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
|
@ -193,7 +194,13 @@ project_state::project_state(voice_commentary& _commentary, memwatch_set& _mwatc
|
|||
controller_state& _controls, settingvar::cache& _setcache, button_mapping& _buttons,
|
||||
emulator_dispatch& _edispatch, input_queue& _iqueue, loaded_rom& _rom, status_updater& _supdater)
|
||||
: commentary(_commentary), mwatch(_mwatch), command(_command), controls(_controls), setcache(_setcache),
|
||||
buttons(_buttons), edispatch(_edispatch), iqueue(_iqueue), rom(_rom), supdater(_supdater)
|
||||
buttons(_buttons), edispatch(_edispatch), iqueue(_iqueue), rom(_rom), supdater(_supdater),
|
||||
branch_ls(command, STUBS::branch_ls, [this]() { this->do_branch_ls(); }),
|
||||
branch_mk(command, STUBS::branch_mk, [this](const std::string& a) { this->do_branch_mk(a); }),
|
||||
branch_rm(command, STUBS::branch_rm, [this](const std::string& a) { this->do_branch_rm(a); }),
|
||||
branch_set(command, STUBS::branch_set, [this](const std::string& a) { this->do_branch_set(a); }),
|
||||
branch_rp(command, STUBS::branch_rp, [this](const std::string& a) { this->do_branch_rp(a); }),
|
||||
branch_mv(command, STUBS::branch_mv, [this](const std::string& a) { this->do_branch_mv(a); })
|
||||
{
|
||||
active_project = NULL;
|
||||
}
|
||||
|
@ -700,150 +707,137 @@ void project_info::write(std::ostream& s)
|
|||
s << "branchnext=" << next_branch << std::endl;
|
||||
}
|
||||
|
||||
namespace
|
||||
void project_state::do_branch_mk(const std::string& args)
|
||||
{
|
||||
void recursive_list_branch(uint64_t bid, std::set<unsigned>& dset, unsigned depth, bool last_of)
|
||||
{
|
||||
auto prj = CORE().project->get();
|
||||
if(!prj) {
|
||||
messages << "Not in project context." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::set<uint64_t> children = prj->branch_children(bid);
|
||||
std::string prefix;
|
||||
for(unsigned i = 0; i + 1 < depth; i++)
|
||||
prefix += (dset.count(i) ? "\u2502" : " ");
|
||||
prefix += (dset.count(depth - 1) ? (last_of ? "\u2514" : "\u251c") : " ");
|
||||
if(last_of) dset.erase(depth - 1);
|
||||
messages << prefix
|
||||
<< ((bid == prj->get_current_branch()) ? "*" : "")
|
||||
<< bid << ":" << prj->get_branch_name(bid) << std::endl;
|
||||
dset.insert(depth);
|
||||
size_t c = 0;
|
||||
for(auto i : children) {
|
||||
bool last = (++c == children.size());
|
||||
recursive_list_branch(i, dset, depth + 1, last);
|
||||
}
|
||||
dset.erase(depth);
|
||||
regex_results r = regex("([0-9]+)[ \t]+(.*)", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: create-branch <parentid> <name>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = get();
|
||||
uint64_t pbid = parse_value<uint64_t>(r[1]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
uint64_t bid = prj->create_branch(pbid, r[2]);
|
||||
messages << "Created branch #" << bid << std::endl;
|
||||
prj->flush();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't create new branch: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
command::fnptr<> CMD_list_branches(lsnes_cmds, "list-branches", "List all slot branches",
|
||||
"Syntax: list-branches\nList all slot branches.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
std::set<unsigned> dset;
|
||||
recursive_list_branch(0, dset, 0, false);
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_create_branch(lsnes_cmds, "create-branch", "Create a new slot branch",
|
||||
"Syntax: create-branch <parentid> <name>\nCreate new branch named <name> under <parentid>.\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
regex_results r = regex("([0-9]+)[ \t]+(.*)", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: create-branch <parentid> <name>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = CORE().project->get();
|
||||
uint64_t pbid = parse_value<uint64_t>(r[1]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
uint64_t bid = prj->create_branch(pbid, r[2]);
|
||||
messages << "Created branch #" << bid << std::endl;
|
||||
prj->flush();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't create new branch: " << e.what() << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_delete_branch(lsnes_cmds, "delete-branch", "Delete a slot branch",
|
||||
"Syntax: delete-branch <id>\nDelete slot branch with id <id>.\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
regex_results r = regex("([0-9]+)[ \t]*", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: delete-branch <id>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = CORE().project->get();
|
||||
uint64_t bid = parse_value<uint64_t>(r[1]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
prj->delete_branch(bid);
|
||||
messages << "Deleted branch #" << bid << std::endl;
|
||||
prj->flush();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't delete branch: " << e.what() << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_set_branch(lsnes_cmds, "set-branch", "Set current slot branch",
|
||||
"Syntax: set-branch <id>\nSet current branch to <id>.\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
regex_results r = regex("([0-9]+)[ \t]*", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: set-branch <id>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = core.project->get();
|
||||
uint64_t bid = parse_value<uint64_t>(r[1]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
prj->set_current_branch(bid);
|
||||
messages << "Set current branch to #" << bid << std::endl;
|
||||
prj->flush();
|
||||
core.supdater->update();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't set branch: " << e.what() << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_reparent_branch(lsnes_cmds, "reparent-branch",
|
||||
"Reparent a slot branch",
|
||||
"Syntax: reparent-branch <id> <newpid>\nReparent branch <id> to be child of <newpid>.\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
regex_results r = regex("([0-9]+)[ \t]+([0-9]+)[ \t]*", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: reparent-branch <id> <newpid>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = core.project->get();
|
||||
uint64_t bid = parse_value<uint64_t>(r[1]);
|
||||
uint64_t pbid = parse_value<uint64_t>(r[2]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
prj->set_parent_branch(bid, pbid);
|
||||
messages << "Reparented branch #" << bid << std::endl;
|
||||
prj->flush();
|
||||
core.supdater->update();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't reparent branch: " << e.what() << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
command::fnptr<const std::string&> CMD_rename_branch(lsnes_cmds, "rename-branch", "Rename a slot branch",
|
||||
"Syntax: rename-branch <id> <name>\nRename branch <id> to <name>.\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
regex_results r = regex("([0-9]+)[ \t]+(.*)", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: rename-branch <id> <name>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = core.project->get();
|
||||
uint64_t bid = parse_value<uint64_t>(r[1]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
prj->set_branch_name(bid, r[2]);
|
||||
messages << "Renamed branch #" << bid << std::endl;
|
||||
prj->flush();
|
||||
core.supdater->update();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't rename branch: " << e.what() << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void project_state::do_branch_rm(const std::string& args)
|
||||
{
|
||||
regex_results r = regex("([0-9]+)[ \t]*", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: delete-branch <id>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = get();
|
||||
uint64_t bid = parse_value<uint64_t>(r[1]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
prj->delete_branch(bid);
|
||||
messages << "Deleted branch #" << bid << std::endl;
|
||||
prj->flush();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't delete branch: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void project_state::do_branch_set(const std::string& args)
|
||||
{
|
||||
regex_results r = regex("([0-9]+)[ \t]*", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: set-branch <id>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = get();
|
||||
uint64_t bid = parse_value<uint64_t>(r[1]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
prj->set_current_branch(bid);
|
||||
messages << "Set current branch to #" << bid << std::endl;
|
||||
prj->flush();
|
||||
supdater.update();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't set branch: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void project_state::do_branch_rp(const std::string& args)
|
||||
{
|
||||
regex_results r = regex("([0-9]+)[ \t]+([0-9]+)[ \t]*", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: reparent-branch <id> <newpid>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = get();
|
||||
uint64_t bid = parse_value<uint64_t>(r[1]);
|
||||
uint64_t pbid = parse_value<uint64_t>(r[2]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
prj->set_parent_branch(bid, pbid);
|
||||
messages << "Reparented branch #" << bid << std::endl;
|
||||
prj->flush();
|
||||
supdater.update();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't reparent branch: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void project_state::do_branch_mv(const std::string& args)
|
||||
{
|
||||
regex_results r = regex("([0-9]+)[ \t]+(.*)", args);
|
||||
if(!r) {
|
||||
messages << "Syntax: rename-branch <id> <name>" << std::endl;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto prj = get();
|
||||
uint64_t bid = parse_value<uint64_t>(r[1]);
|
||||
if(!prj)
|
||||
throw std::runtime_error("Not in project context");
|
||||
prj->set_branch_name(bid, r[2]);
|
||||
messages << "Renamed branch #" << bid << std::endl;
|
||||
prj->flush();
|
||||
supdater.update();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Can't rename branch: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void project_state::do_branch_ls()
|
||||
{
|
||||
std::set<unsigned> dset;
|
||||
recursive_list_branch(0, dset, 0, false);
|
||||
}
|
||||
|
||||
void project_state::recursive_list_branch(uint64_t bid, std::set<unsigned>& dset, unsigned depth, bool last_of)
|
||||
{
|
||||
auto prj = get();
|
||||
if(!prj) {
|
||||
messages << "Not in project context." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::set<uint64_t> children = prj->branch_children(bid);
|
||||
std::string prefix;
|
||||
for(unsigned i = 0; i + 1 < depth; i++)
|
||||
prefix += (dset.count(i) ? "\u2502" : " ");
|
||||
prefix += (dset.count(depth - 1) ? (last_of ? "\u2514" : "\u251c") : " ");
|
||||
if(last_of) dset.erase(depth - 1);
|
||||
messages << prefix
|
||||
<< ((bid == prj->get_current_branch()) ? "*" : "")
|
||||
<< bid << ":" << prj->get_branch_name(bid) << std::endl;
|
||||
dset.insert(depth);
|
||||
size_t c = 0;
|
||||
for(auto i : children) {
|
||||
bool last = (++c == children.size());
|
||||
recursive_list_branch(i, dset, depth + 1, last);
|
||||
}
|
||||
dset.erase(depth);
|
||||
}
|
||||
|
|
29
src/core/reginverse.cpp
Normal file
29
src/core/reginverse.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include "library/keyboard.hpp"
|
||||
#include "cmdhelp/inverselist.hpp"
|
||||
#include "core/keymapper.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class register_command_inverses
|
||||
{
|
||||
public:
|
||||
register_command_inverses()
|
||||
{
|
||||
const char** ptr = STUBS::inverse_cmd_list;
|
||||
while(*ptr) {
|
||||
ib.insert(new keyboard::invbind_info(lsnes_invbinds, ptr[0], ptr[1]));
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
~register_command_inverses()
|
||||
{
|
||||
for(auto i : ib)
|
||||
delete i;
|
||||
ib.clear();
|
||||
}
|
||||
private:
|
||||
std::set<keyboard::invbind_info*> ib;
|
||||
};
|
||||
|
||||
register_command_inverses x;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
#include "cmdhelp/subtitles.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
#include "core/framebuffer.hpp"
|
||||
|
@ -99,74 +100,14 @@ namespace
|
|||
framebuffer::color fg;
|
||||
framebuffer::color bg;
|
||||
};
|
||||
|
||||
|
||||
command::fnptr<const std::string&> CMD_edit_subtitle(lsnes_cmds, "edit-subtitle", "Edit a subtitle",
|
||||
"Syntax: edit-subtitle <first> <length> <text>\nAdd/Edit subtitle\n"
|
||||
"Syntax: edit-subtitle <first> <length>\nADelete subtitle\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
auto r = regex("([0-9]+)[ \t]+([0-9]+)([ \t]+(.*))?", args, "Bad syntax");
|
||||
uint64_t frame = parse_value<uint64_t>(r[1]);
|
||||
uint64_t length = parse_value<uint64_t>(r[2]);
|
||||
std::string text = r[4];
|
||||
moviefile_subtiming key(frame, length);
|
||||
if(text == "")
|
||||
core.mlogic->get_mfile().subtitles.erase(key);
|
||||
else
|
||||
core.mlogic->get_mfile().subtitles[key] =
|
||||
subtitle_commentary::s_unescape(text);
|
||||
core.dispatch->subtitle_change();
|
||||
core.fbuf->redraw_framebuffer();
|
||||
});
|
||||
|
||||
command::fnptr<> CMD_list_subtitle(lsnes_cmds, "list-subtitle", "List the subtitles",
|
||||
"Syntax: list-subtitle\nList the subtitles.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
for(auto i = core.mlogic->get_mfile().subtitles.rbegin(); i !=
|
||||
core.mlogic->get_mfile().subtitles.rend();
|
||||
i++) {
|
||||
messages << i->first.get_frame() << " " << i->first.get_length() << " "
|
||||
<< subtitle_commentary::s_escape(i->second) << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
command::fnptr<command::arg_filename> CMD_save_s(lsnes_cmds, "save-subtitle", "Save subtitles in .sub format",
|
||||
"Syntax: save-subtitle <file>\nSaves subtitles in .sub format to <file>\n",
|
||||
[](command::arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto& core = CORE();
|
||||
if(core.mlogic->get_mfile().subtitles.empty())
|
||||
return;
|
||||
auto i = core.mlogic->get_mfile().subtitles.begin();
|
||||
uint64_t lastframe = i->first.get_frame() + i->first.get_length();
|
||||
std::ofstream y(std::string(args).c_str());
|
||||
if(!y)
|
||||
throw std::runtime_error("Can't open output file");
|
||||
std::string lasttxt = "";
|
||||
uint64_t since = 0;
|
||||
for(uint64_t i = 1; i < lastframe; i++) {
|
||||
moviefile_subtiming posmarker(i);
|
||||
auto j = core.mlogic->get_mfile().subtitles.upper_bound(posmarker);
|
||||
if(j == core.mlogic->get_mfile().subtitles.end())
|
||||
continue;
|
||||
if(lasttxt != j->second || !j->first.inrange(i)) {
|
||||
if(lasttxt != "")
|
||||
y << "{" << since << "}{" << i - 1 << "}" << s_subescape(lasttxt)
|
||||
<< std::endl;
|
||||
since = i;
|
||||
lasttxt = j->first.inrange(i) ? j->second : "";
|
||||
}
|
||||
}
|
||||
if(lasttxt != "")
|
||||
y << "{" << since << "}{" << lastframe - 1 << "}" << s_subescape(lasttxt)
|
||||
<< std::endl;
|
||||
messages << "Saved subtitles to " << std::string(args) << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
subtitle_commentary::subtitle_commentary(movie_logic& _mlogic, emu_framebuffer& _fbuf, emulator_dispatch& _dispatch)
|
||||
: mlogic(_mlogic), fbuf(_fbuf), edispatch(_dispatch)
|
||||
subtitle_commentary::subtitle_commentary(movie_logic& _mlogic, emu_framebuffer& _fbuf, emulator_dispatch& _dispatch,
|
||||
command::group& _cmd)
|
||||
: mlogic(_mlogic), fbuf(_fbuf), edispatch(_dispatch), cmd(_cmd),
|
||||
editsub(cmd, STUBS::editsub, [this](const std::string& a) { this->do_editsub(a); }),
|
||||
listsub(cmd, STUBS::listsub, [this]() { this->do_listsub(); }),
|
||||
savesub(cmd, STUBS::savesub, [this](command::arg_filename a) { this->do_savesub(a); })
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -257,3 +198,59 @@ void subtitle_commentary::set(uint64_t f, uint64_t l, const std::string& x)
|
|||
edispatch.subtitle_change();
|
||||
fbuf.redraw_framebuffer();
|
||||
}
|
||||
|
||||
void subtitle_commentary::do_editsub(const std::string& args)
|
||||
{
|
||||
auto r = regex("([0-9]+)[ \t]+([0-9]+)([ \t]+(.*))?", args, "Bad syntax");
|
||||
uint64_t frame = parse_value<uint64_t>(r[1]);
|
||||
uint64_t length = parse_value<uint64_t>(r[2]);
|
||||
std::string text = r[4];
|
||||
moviefile_subtiming key(frame, length);
|
||||
if(text == "")
|
||||
mlogic.get_mfile().subtitles.erase(key);
|
||||
else
|
||||
mlogic.get_mfile().subtitles[key] =
|
||||
subtitle_commentary::s_unescape(text);
|
||||
edispatch.subtitle_change();
|
||||
fbuf.redraw_framebuffer();
|
||||
}
|
||||
|
||||
void subtitle_commentary::do_listsub()
|
||||
{
|
||||
for(auto i = mlogic.get_mfile().subtitles.rbegin(); i !=
|
||||
mlogic.get_mfile().subtitles.rend();
|
||||
i++) {
|
||||
messages << i->first.get_frame() << " " << i->first.get_length() << " "
|
||||
<< subtitle_commentary::s_escape(i->second) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void subtitle_commentary::do_savesub(const std::string& args)
|
||||
{
|
||||
if(mlogic.get_mfile().subtitles.empty())
|
||||
return;
|
||||
auto i = mlogic.get_mfile().subtitles.begin();
|
||||
uint64_t lastframe = i->first.get_frame() + i->first.get_length();
|
||||
std::ofstream y(std::string(args).c_str());
|
||||
if(!y)
|
||||
throw std::runtime_error("Can't open output file");
|
||||
std::string lasttxt = "";
|
||||
uint64_t since = 0;
|
||||
for(uint64_t i = 1; i < lastframe; i++) {
|
||||
moviefile_subtiming posmarker(i);
|
||||
auto j = mlogic.get_mfile().subtitles.upper_bound(posmarker);
|
||||
if(j == mlogic.get_mfile().subtitles.end())
|
||||
continue;
|
||||
if(lasttxt != j->second || !j->first.inrange(i)) {
|
||||
if(lasttxt != "")
|
||||
y << "{" << since << "}{" << i - 1 << "}" << s_subescape(lasttxt)
|
||||
<< std::endl;
|
||||
since = i;
|
||||
lasttxt = j->first.inrange(i) ? j->second : "";
|
||||
}
|
||||
}
|
||||
if(lasttxt != "")
|
||||
y << "{" << since << "}{" << lastframe - 1 << "}" << s_subescape(lasttxt)
|
||||
<< std::endl;
|
||||
messages << "Saved subtitles to " << std::string(args) << std::endl;
|
||||
}
|
||||
|
|
|
@ -468,13 +468,13 @@ void group::listener::kill(set& s)
|
|||
}
|
||||
|
||||
template<>
|
||||
void invoke_fn(void (*fn)(const std::string& args), const std::string& args)
|
||||
void invoke_fn(std::function<void(const std::string& args)> fn, const std::string& args)
|
||||
{
|
||||
fn(args);
|
||||
}
|
||||
|
||||
template<>
|
||||
void invoke_fn(void (*fn)(), const std::string& args)
|
||||
void invoke_fn(std::function<void()> fn, const std::string& args)
|
||||
{
|
||||
if(args != "")
|
||||
throw std::runtime_error("This command does not take arguments");
|
||||
|
@ -482,7 +482,7 @@ void invoke_fn(void (*fn)(), const std::string& args)
|
|||
}
|
||||
|
||||
template<>
|
||||
void invoke_fn(void (*fn)(struct arg_filename a), const std::string& args)
|
||||
void invoke_fn(std::function<void(struct arg_filename a)> fn, const std::string& args)
|
||||
{
|
||||
if(args == "")
|
||||
throw std::runtime_error("Filename required");
|
||||
|
|
Loading…
Add table
Reference in a new issue