Refactor command handling to library/
This commit is contained in:
parent
924047524a
commit
32039006f5
32 changed files with 828 additions and 553 deletions
|
@ -4,161 +4,8 @@
|
|||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "library/commands.hpp"
|
||||
|
||||
|
||||
/**
|
||||
* A command.
|
||||
*/
|
||||
class command
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Register a new command.
|
||||
*
|
||||
* parameter cmd: The command to register.
|
||||
* throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
command(const std::string& cmd) throw(std::bad_alloc);
|
||||
|
||||
/**
|
||||
* Deregister a command.
|
||||
*/
|
||||
virtual ~command() throw();
|
||||
|
||||
/**
|
||||
* Invoke a command.
|
||||
*
|
||||
* parameter arguments: Arguments to command.
|
||||
* throws std::bad_alloc: Not enough memory.
|
||||
* throws std::runtime_error: Command execution failed.
|
||||
*/
|
||||
virtual void invoke(const std::string& arguments) throw(std::bad_alloc, std::runtime_error) = 0;
|
||||
|
||||
/**
|
||||
* Look up and invoke a command. The command will undergo alias expansion and recursion checking.
|
||||
*
|
||||
* parameter cmd: Command to exeucte.
|
||||
*/
|
||||
static void invokeC(const std::string& cmd) throw();
|
||||
/**
|
||||
* Get set of aliases.
|
||||
*/
|
||||
static std::set<std::string> get_aliases() throw(std::bad_alloc);
|
||||
/**
|
||||
* Get alias
|
||||
*/
|
||||
static std::string get_alias_for(const std::string& aname) throw(std::bad_alloc);
|
||||
/**
|
||||
* Set alias
|
||||
*/
|
||||
static void set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc);
|
||||
/**
|
||||
* Is alias name valid.
|
||||
*/
|
||||
static bool valid_alias_name(const std::string& aname) throw(std::bad_alloc);
|
||||
/**
|
||||
* Get short help for command.
|
||||
*/
|
||||
virtual std::string get_short_help() throw(std::bad_alloc);
|
||||
|
||||
/**
|
||||
* Get long help for command.
|
||||
*/
|
||||
virtual std::string get_long_help() throw(std::bad_alloc);
|
||||
private:
|
||||
command(const command&);
|
||||
command& operator=(const command&);
|
||||
std::string commandname;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mandatory filename
|
||||
*/
|
||||
struct arg_filename
|
||||
{
|
||||
/**
|
||||
* The filename itself.
|
||||
*/
|
||||
std::string v;
|
||||
/**
|
||||
* Return the filename.
|
||||
*
|
||||
* returns: The filename.
|
||||
*/
|
||||
operator std::string() { return v; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Run command function helper.
|
||||
*
|
||||
* parameter fn: Function pointer to invoke.
|
||||
* parameter a: The arguments to pass.
|
||||
*/
|
||||
template<typename... args>
|
||||
void invoke_command_fn(void (*fn)(args... arguments), const std::string& a);
|
||||
|
||||
/**
|
||||
* Warp function pointer as command.
|
||||
*/
|
||||
template<typename... args>
|
||||
class function_ptr_command : public command
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new command.
|
||||
*
|
||||
* parameter name: Name of the command
|
||||
* parameter description Description for the command
|
||||
* parameter help: Help for the command.
|
||||
* parameter fn: Function to call on command.
|
||||
*/
|
||||
function_ptr_command(const std::string& name, const std::string& _description, const std::string& _help,
|
||||
void (*_fn)(args... arguments)) throw(std::bad_alloc)
|
||||
: command(name)
|
||||
{
|
||||
description = _description;
|
||||
help = _help;
|
||||
fn = _fn;
|
||||
}
|
||||
/**
|
||||
* Destroy a commnad.
|
||||
*/
|
||||
~function_ptr_command() throw()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Invoke a command.
|
||||
*
|
||||
* parameter a: Arguments to function.
|
||||
*/
|
||||
void invoke(const std::string& a) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
invoke_command_fn(fn, a);
|
||||
}
|
||||
/**
|
||||
* Get short description.
|
||||
*
|
||||
* returns: Description.
|
||||
* throw std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::string get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return description;
|
||||
}
|
||||
/**
|
||||
* Get long help.
|
||||
*
|
||||
* returns: help.
|
||||
* throw std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::string get_long_help() throw(std::bad_alloc)
|
||||
{
|
||||
return help;
|
||||
}
|
||||
private:
|
||||
void (*fn)(args... arguments);
|
||||
std::string description;
|
||||
std::string help;
|
||||
};
|
||||
extern command_group lsnes_cmd;
|
||||
|
||||
#endif
|
||||
|
|
209
include/library/commands.hpp
Normal file
209
include/library/commands.hpp
Normal file
|
@ -0,0 +1,209 @@
|
|||
#ifndef _library_commands__hpp__included__
|
||||
#define _library_commands__hpp__included__
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include "library/workthread.hpp"
|
||||
|
||||
class command;
|
||||
|
||||
/**
|
||||
* A group of commands (with aliases).
|
||||
*/
|
||||
class command_group
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new command group. This also places some builtin commands in that new group.
|
||||
*/
|
||||
command_group() throw(std::bad_alloc);
|
||||
/**
|
||||
* Destroy a group.
|
||||
*/
|
||||
~command_group() throw();
|
||||
/**
|
||||
* Look up and invoke a command. The command will undergo alias expansion and recursion checking.
|
||||
*
|
||||
* parameter cmd: Command to exeucte.
|
||||
*/
|
||||
void invoke(const std::string& cmd) throw();
|
||||
/**
|
||||
* Get set of aliases.
|
||||
*/
|
||||
std::set<std::string> get_aliases() throw(std::bad_alloc);
|
||||
/**
|
||||
* Get alias
|
||||
*/
|
||||
std::string get_alias_for(const std::string& aname) throw(std::bad_alloc);
|
||||
/**
|
||||
* Set alias
|
||||
*/
|
||||
void set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc);
|
||||
/**
|
||||
* Is alias name valid.
|
||||
*/
|
||||
bool valid_alias_name(const std::string& aname) throw(std::bad_alloc);
|
||||
/**
|
||||
* Register a command.
|
||||
*/
|
||||
void register_command(const std::string& name, command& cmd) throw(std::bad_alloc);
|
||||
/**
|
||||
* Unregister a command.
|
||||
*/
|
||||
void unregister_command(const std::string& name) throw(std::bad_alloc);
|
||||
/**
|
||||
* Set the output stream.
|
||||
*/
|
||||
void set_output(std::ostream& s);
|
||||
/**
|
||||
* Set the OOM panic routine.
|
||||
*/
|
||||
void set_oom_panic(void (*fn)());
|
||||
private:
|
||||
std::map<std::string, command*> commands;
|
||||
std::set<std::string> command_stack;
|
||||
std::map<std::string, std::list<std::string>> aliases;
|
||||
mutex_class int_mutex;
|
||||
std::ostream* output;
|
||||
void (*oom_panic_routine)();
|
||||
};
|
||||
|
||||
/**
|
||||
* A command.
|
||||
*/
|
||||
class command
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Register a new command.
|
||||
*
|
||||
* parameter group: The group command will be part of.
|
||||
* parameter cmd: The command to register.
|
||||
* throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
command(command_group& group, const std::string& cmd) throw(std::bad_alloc);
|
||||
|
||||
/**
|
||||
* Deregister a command.
|
||||
*/
|
||||
virtual ~command() throw();
|
||||
|
||||
/**
|
||||
* Invoke a command.
|
||||
*
|
||||
* parameter arguments: Arguments to command.
|
||||
* throws std::bad_alloc: Not enough memory.
|
||||
* throws std::runtime_error: Command execution failed.
|
||||
*/
|
||||
virtual void invoke(const std::string& arguments) throw(std::bad_alloc, std::runtime_error) = 0;
|
||||
/**
|
||||
* Get short help for command.
|
||||
*/
|
||||
virtual std::string get_short_help() throw(std::bad_alloc);
|
||||
|
||||
/**
|
||||
* Get long help for command.
|
||||
*/
|
||||
virtual std::string get_long_help() throw(std::bad_alloc);
|
||||
private:
|
||||
command(const command&);
|
||||
command& operator=(const command&);
|
||||
std::string commandname;
|
||||
command_group& in_group;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mandatory filename
|
||||
*/
|
||||
struct arg_filename
|
||||
{
|
||||
/**
|
||||
* The filename itself.
|
||||
*/
|
||||
std::string v;
|
||||
/**
|
||||
* Return the filename.
|
||||
*
|
||||
* returns: The filename.
|
||||
*/
|
||||
operator std::string() { return v; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Run command function helper.
|
||||
*
|
||||
* parameter fn: Function pointer to invoke.
|
||||
* parameter a: The arguments to pass.
|
||||
*/
|
||||
template<typename... args>
|
||||
void invoke_command_fn(void (*fn)(args... arguments), const std::string& a);
|
||||
|
||||
/**
|
||||
* Warp function pointer as command.
|
||||
*/
|
||||
template<typename... args>
|
||||
class function_ptr_command : public command
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new command.
|
||||
*
|
||||
* parameter group: The group command will be part of.
|
||||
* parameter name: Name of the command
|
||||
* parameter description Description for the command
|
||||
* parameter help: Help for the command.
|
||||
* parameter fn: Function to call on command.
|
||||
*/
|
||||
function_ptr_command(command_group& group, const std::string& name, const std::string& _description,
|
||||
const std::string& _help, void (*_fn)(args... arguments)) throw(std::bad_alloc)
|
||||
: command(group, name)
|
||||
{
|
||||
description = _description;
|
||||
help = _help;
|
||||
fn = _fn;
|
||||
}
|
||||
/**
|
||||
* Destroy a commnad.
|
||||
*/
|
||||
~function_ptr_command() throw()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Invoke a command.
|
||||
*
|
||||
* parameter a: Arguments to function.
|
||||
*/
|
||||
void invoke(const std::string& a) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
invoke_command_fn(fn, a);
|
||||
}
|
||||
/**
|
||||
* Get short description.
|
||||
*
|
||||
* returns: Description.
|
||||
* throw std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::string get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return description;
|
||||
}
|
||||
/**
|
||||
* Get long help.
|
||||
*
|
||||
* returns: help.
|
||||
* throw std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::string get_long_help() throw(std::bad_alloc)
|
||||
{
|
||||
return help;
|
||||
}
|
||||
private:
|
||||
void (*fn)(args... arguments);
|
||||
std::string description;
|
||||
std::string help;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -21,7 +21,7 @@ namespace
|
|||
throw std::runtime_error("Unknown dumper");
|
||||
}
|
||||
|
||||
function_ptr_command<const std::string&> start_dump("start-dump", "Start dumping",
|
||||
function_ptr_command<const std::string&> start_dump(lsnes_cmd, "start-dump", "Start dumping",
|
||||
"Syntax: start-dump <dumper> <prefix/filename>\nSyntax: start-dump <dumper> <mode> <prefix/filename>\n"
|
||||
"Start dumping using <dumper> in mode <mode> to <prefix/filename>\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
|
@ -41,7 +41,7 @@ namespace
|
|||
d.start(mode, t2);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> end_dump("end-dump", "End dumping",
|
||||
function_ptr_command<const std::string&> end_dump(lsnes_cmd, "end-dump", "End dumping",
|
||||
"Syntax: end-dump <dumper>\nEnd dumping using dumper <dumper>\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("([^ \t]+)[ \t]*", t, "Command syntax error");
|
||||
|
@ -49,7 +49,7 @@ namespace
|
|||
d.end();
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> dumpersc("show-dumpers", "Show dumpers",
|
||||
function_ptr_command<const std::string&> dumpersc(lsnes_cmd, "show-dumpers", "Show dumpers",
|
||||
"Syntax: show-dumpers\nSyntax: show-dumpers <dumper>\nShow dumpers or dumper modes for <dumper>\n",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto a = adv_dumper::get_dumper_set();
|
||||
|
|
|
@ -1153,7 +1153,7 @@ std::pair<uint64_t, uint64_t> core_get_bus_map()
|
|||
return std::make_pair(0x1000000, 0x1000000);
|
||||
}
|
||||
|
||||
function_ptr_command<arg_filename> dump_core("dump-core", "No description available",
|
||||
function_ptr_command<arg_filename> dump_core(lsnes_cmd, "dump-core", "No description available",
|
||||
"No description available\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
std::vector<char> out;
|
||||
|
|
|
@ -2,266 +2,8 @@
|
|||
#include "library/globalwrap.hpp"
|
||||
#include "core/misc.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "library/zip.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace
|
||||
{
|
||||
globalwrap<std::map<std::string, command*>> commands;
|
||||
std::set<std::string> command_stack;
|
||||
std::map<std::string, std::list<std::string>> aliases;
|
||||
|
||||
//Return the recursive mutex.
|
||||
mutex& cmlock()
|
||||
{
|
||||
static mutex& m = mutex::aquire_rec();
|
||||
return m;
|
||||
}
|
||||
|
||||
class cmlock_hold
|
||||
{
|
||||
public:
|
||||
cmlock_hold() { cmlock().lock(); }
|
||||
~cmlock_hold() { cmlock().unlock(); }
|
||||
private:
|
||||
cmlock_hold(const cmlock_hold& k);
|
||||
cmlock_hold& operator=(const cmlock_hold& k);
|
||||
};
|
||||
|
||||
|
||||
function_ptr_command<arg_filename> run_script("run-script", "run file as a script",
|
||||
"Syntax: run-script <file>\nRuns file <file> just as it would have been entered in the command line\n",
|
||||
[](arg_filename filename) throw(std::bad_alloc, std::runtime_error) {
|
||||
std::istream* o = NULL;
|
||||
try {
|
||||
o = &open_file_relative(filename, "");
|
||||
messages << "Running '" << std::string(filename) << "'" << std::endl;
|
||||
std::string line;
|
||||
while(std::getline(*o, line))
|
||||
command::invokeC(line);
|
||||
delete o;
|
||||
} catch(std::exception& e) {
|
||||
delete o;
|
||||
throw;
|
||||
}
|
||||
});
|
||||
|
||||
function_ptr_command<> show_aliases("show-aliases", "show aliases",
|
||||
"Syntax: show-aliases\nShow expansions of all aliases\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
cmlock_hold lck;
|
||||
for(auto i : aliases)
|
||||
for(auto j : i.second)
|
||||
messages << "alias " << i.first << " " << j << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> unalias_command("unalias-command", "unalias a command",
|
||||
"Syntax: unalias-command <aliasname>\nClear expansion of alias <aliasname>\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("([^ \t]+)[ \t]*", t, "This command only takes one argument");
|
||||
if(!command::valid_alias_name(r[1]))
|
||||
throw std::runtime_error("Illegal alias name");
|
||||
cmlock_hold lck;
|
||||
aliases[r[1]].clear();
|
||||
messages << "Command '" << r[1] << "' unaliased" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> alias_command("alias-command", "alias a command",
|
||||
"Syntax: alias-command <aliasname> <command>\nAppend <command> to expansion of alias <aliasname>\n"
|
||||
"Valid alias names can't be empty nor start with '*' or '?'\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("([^ \t]+)[ \t]+([^ \t].*)", t, "Alias name and command needed");
|
||||
if(!command::valid_alias_name(r[1]))
|
||||
throw std::runtime_error("Illegal alias name");
|
||||
cmlock_hold lck;
|
||||
aliases[r[1]].push_back(r[2]);
|
||||
messages << "Command '" << r[1] << "' aliased to '" << r[2] << "'" << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
command::command(const std::string& cmd) throw(std::bad_alloc)
|
||||
{
|
||||
cmlock_hold lck;
|
||||
if(commands().count(cmd))
|
||||
std::cerr << "WARNING: Command collision for " << cmd << "!" << std::endl;
|
||||
commands()[commandname = cmd] = this;
|
||||
}
|
||||
|
||||
command::~command() throw()
|
||||
{
|
||||
cmlock_hold lck;
|
||||
commands().erase(commandname);
|
||||
}
|
||||
|
||||
void command::invokeC(const std::string& cmd) throw()
|
||||
{
|
||||
try {
|
||||
std::string cmd2 = strip_CR(cmd);
|
||||
if(cmd2 == "?") {
|
||||
//The special ? command.
|
||||
cmlock_hold lck;
|
||||
for(auto i : commands())
|
||||
messages << i.first << ": " << i.second->get_short_help() << std::endl;
|
||||
return;
|
||||
}
|
||||
if(firstchar(cmd2) == '?') {
|
||||
//?command.
|
||||
cmlock_hold lck;
|
||||
std::string rcmd = cmd2.substr(1, min(cmd2.find_first_of(" \t"), cmd2.length()));
|
||||
if(firstchar(rcmd) != '*') {
|
||||
//This may be an alias.
|
||||
if(aliases.count(rcmd)) {
|
||||
//Yup.
|
||||
messages << rcmd << " is an alias for: " << std::endl;
|
||||
size_t j = 0;
|
||||
for(auto i : aliases[rcmd])
|
||||
messages << "#" << (++j) << ": " << i << std::endl;
|
||||
return;
|
||||
}
|
||||
} else
|
||||
rcmd = rcmd.substr(1);
|
||||
if(!commands().count(rcmd))
|
||||
messages << "Unknown command '" << rcmd << "'" << std::endl;
|
||||
else
|
||||
messages << commands()[rcmd]->get_long_help() << std::endl;
|
||||
return;
|
||||
}
|
||||
bool may_be_alias_expanded = true;
|
||||
if(firstchar(cmd2) == '*') {
|
||||
may_be_alias_expanded = false;
|
||||
cmd2 = cmd2.substr(1);
|
||||
}
|
||||
//Now this gets painful as command handlers must not be invoked with lock held.
|
||||
if(may_be_alias_expanded) {
|
||||
std::list<std::string> aexp;
|
||||
{
|
||||
cmlock_hold lck;
|
||||
if(!aliases.count(cmd))
|
||||
goto not_alias;
|
||||
aexp = aliases[cmd2];
|
||||
}
|
||||
for(auto i : aexp)
|
||||
invokeC(i);
|
||||
return;
|
||||
}
|
||||
not_alias:
|
||||
try {
|
||||
size_t split = cmd2.find_first_of(" \t");
|
||||
std::string rcmd = cmd2.substr(0, min(split, cmd2.length()));
|
||||
std::string args = cmd2.substr(min(cmd2.find_first_not_of(" \t", split), cmd2.length()));
|
||||
command* cmdh = NULL;
|
||||
{
|
||||
cmlock_hold lck;
|
||||
if(!commands().count(rcmd)) {
|
||||
messages << "Unknown command '" << rcmd << "'" << std::endl;
|
||||
return;
|
||||
}
|
||||
cmdh = commands()[rcmd];
|
||||
}
|
||||
if(command_stack.count(cmd2))
|
||||
throw std::runtime_error("Recursive command invocation");
|
||||
command_stack.insert(cmd2);
|
||||
cmdh->invoke(args);
|
||||
command_stack.erase(cmd2);
|
||||
return;
|
||||
} catch(std::bad_alloc& e) {
|
||||
OOM_panic();
|
||||
} catch(std::exception& e) {
|
||||
messages << "Error: " << e.what() << std::endl;
|
||||
command_stack.erase(cmd2);
|
||||
return;
|
||||
}
|
||||
} catch(std::bad_alloc& e) {
|
||||
OOM_panic();
|
||||
}
|
||||
}
|
||||
|
||||
std::string command::get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "No description available";
|
||||
}
|
||||
|
||||
std::string command::get_long_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "No help available on command " + commandname;
|
||||
}
|
||||
|
||||
std::set<std::string> command::get_aliases() throw(std::bad_alloc)
|
||||
{
|
||||
cmlock_hold lck;
|
||||
std::set<std::string> r;
|
||||
for(auto i : aliases)
|
||||
r.insert(i.first);
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string command::get_alias_for(const std::string& aname) throw(std::bad_alloc)
|
||||
{
|
||||
cmlock_hold lck;
|
||||
if(!valid_alias_name(aname))
|
||||
return "";
|
||||
if(aliases.count(aname)) {
|
||||
std::string x;
|
||||
for(auto i : aliases[aname])
|
||||
x = x + i + "\n";
|
||||
return x;
|
||||
} else
|
||||
return "";
|
||||
}
|
||||
|
||||
void command::set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc)
|
||||
{
|
||||
cmlock_hold lck;
|
||||
if(!valid_alias_name(aname))
|
||||
return;
|
||||
std::list<std::string> newlist;
|
||||
size_t avitr = 0;
|
||||
while(avitr < avalue.length()) {
|
||||
size_t nextsplit = min(avalue.find_first_of("\n", avitr), avalue.length());
|
||||
std::string x = strip_CR(avalue.substr(avitr, nextsplit - avitr));
|
||||
if(x.length() > 0)
|
||||
newlist.push_back(x);
|
||||
avitr = nextsplit + 1;
|
||||
}
|
||||
if(newlist.empty())
|
||||
aliases.erase(aname);
|
||||
else
|
||||
aliases[aname] = newlist;
|
||||
}
|
||||
|
||||
bool command::valid_alias_name(const std::string& aliasname) throw(std::bad_alloc)
|
||||
{
|
||||
if(aliasname.length() == 0 || aliasname[0] == '?' || aliasname[0] == '*')
|
||||
return false;
|
||||
if(aliasname.find_first_of(" \t") < aliasname.length())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
void invoke_command_fn(void (*fn)(const std::string& args), const std::string& args)
|
||||
{
|
||||
fn(args);
|
||||
}
|
||||
|
||||
template<>
|
||||
void invoke_command_fn(void (*fn)(), const std::string& args)
|
||||
{
|
||||
if(args != "")
|
||||
throw std::runtime_error("This command does not take arguments");
|
||||
fn();
|
||||
}
|
||||
|
||||
template<>
|
||||
void invoke_command_fn(void (*fn)(struct arg_filename a), const std::string& args)
|
||||
{
|
||||
if(args == "")
|
||||
throw std::runtime_error("Filename required");
|
||||
arg_filename b;
|
||||
b.v = args;
|
||||
fn(b);
|
||||
}
|
||||
command_group lsnes_cmd;
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace
|
|||
controls.analog(pcid.first, pcid.second, x / 2 , y / 2);
|
||||
}
|
||||
|
||||
function_ptr_command<const std::string&> autofire("autofire", "Set autofire pattern",
|
||||
function_ptr_command<const std::string&> autofire(lsnes_cmd, "autofire", "Set autofire pattern",
|
||||
"Syntax: autofire <buttons|->...\nSet autofire pattern\n",
|
||||
[](const std::string& a) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex(".*[^ \t].*", a, "Need at least one frame for autofire");
|
||||
|
@ -129,7 +129,7 @@ namespace
|
|||
public:
|
||||
button_action(const std::string& cmd, int _type, unsigned _controller, std::string _button)
|
||||
throw(std::bad_alloc)
|
||||
: command(cmd)
|
||||
: command(lsnes_cmd, cmd)
|
||||
{
|
||||
commandn = cmd;
|
||||
type = _type;
|
||||
|
@ -176,7 +176,7 @@ namespace
|
|||
public:
|
||||
analog_action(const std::string& cmd, unsigned _controller)
|
||||
throw(std::bad_alloc)
|
||||
: command(cmd)
|
||||
: command(lsnes_cmd, cmd)
|
||||
{
|
||||
controller = _controller;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace
|
|||
draw_special_screen(target, rl_corrupt);
|
||||
}
|
||||
|
||||
function_ptr_command<arg_filename> take_screenshot_cmd("take-screenshot", "Takes a screenshot",
|
||||
function_ptr_command<arg_filename> take_screenshot_cmd(lsnes_cmd, "take-screenshot", "Takes a screenshot",
|
||||
"Syntax: take-screenshot <file>\nSaves screenshot to PNG file <file>\n",
|
||||
[](arg_filename file) throw(std::bad_alloc, std::runtime_error) {
|
||||
take_screenshot(file);
|
||||
|
|
|
@ -137,19 +137,19 @@ namespace
|
|||
|
||||
bool turboed = false;
|
||||
|
||||
function_ptr_command<> tturbo("toggle-turbo", "Toggle turbo",
|
||||
function_ptr_command<> tturbo(lsnes_cmd, "toggle-turbo", "Toggle turbo",
|
||||
"Syntax: toggle-turbo\nToggle turbo mode.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
turboed = !turboed;
|
||||
});
|
||||
|
||||
function_ptr_command<> pturbo("+turbo", "Activate turbo",
|
||||
function_ptr_command<> pturbo(lsnes_cmd, "+turbo", "Activate turbo",
|
||||
"Syntax: +turbo\nActivate turbo mode.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
turboed = true;
|
||||
});
|
||||
|
||||
function_ptr_command<> nturbo("-turbo", "Deactivate turbo",
|
||||
function_ptr_command<> nturbo(lsnes_cmd, "-turbo", "Deactivate turbo",
|
||||
"Syntax: -turbo\nDeactivate turbo mode.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
turboed = false;
|
||||
|
|
|
@ -601,13 +601,13 @@ void core_set_poll_flag(unsigned pflag)
|
|||
|
||||
std::vector<char> cmp_save;
|
||||
|
||||
function_ptr_command<> cmp_save1("set-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) {
|
||||
function_ptr_command<> cmp_save1(lsnes_cmd, "set-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(!internal_rom)
|
||||
return;
|
||||
instance->saveState(cmp_save);
|
||||
});
|
||||
|
||||
function_ptr_command<> cmp_save2("do-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) {
|
||||
function_ptr_command<> cmp_save2(lsnes_cmd, "do-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) {
|
||||
std::vector<char> x;
|
||||
if(!internal_rom)
|
||||
return;
|
||||
|
|
|
@ -1297,12 +1297,12 @@ out_parsing:
|
|||
};
|
||||
|
||||
//The tangent function.
|
||||
function_ptr_command<> ptangent("+tangent", "Voice tangent",
|
||||
function_ptr_command<> ptangent(lsnes_cmd, "+tangent", "Voice tangent",
|
||||
"Syntax: +tangent\nVoice tangent.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
active_flag = true;
|
||||
});
|
||||
function_ptr_command<> ntangent("-tangent", "Voice tangent",
|
||||
function_ptr_command<> ntangent(lsnes_cmd, "-tangent", "Voice tangent",
|
||||
"Syntax: -tangent\nVoice tangent.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
active_flag = false;
|
||||
|
@ -1339,7 +1339,8 @@ uint64_t voicesub_parse_timebase(const std::string& n)
|
|||
|
||||
namespace
|
||||
{
|
||||
function_ptr_command<> list_streams("list-streams", "List streams ", "list-streams\nList known voice streams",
|
||||
function_ptr_command<> list_streams(lsnes_cmd, "list-streams", "List streams ", "list-streams\n"
|
||||
"List known voice streams",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
umutex_class m2(current_collection_lock);
|
||||
if(!current_collection) {
|
||||
|
@ -1359,7 +1360,7 @@ namespace
|
|||
messages << "-----------------------" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> delete_stream("delete-stream", "Delete a stream",
|
||||
function_ptr_command<const std::string&> delete_stream(lsnes_cmd, "delete-stream", "Delete a stream",
|
||||
"delete-stream <id>\nDelete a voice stream with given ID.",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
umutex_class m2(current_collection_lock);
|
||||
|
@ -1378,8 +1379,8 @@ namespace
|
|||
messages << "Deleted stream #" << id << "." << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> play_stream("play-stream", "Play a stream", "play-stream <id>\n"
|
||||
"Play a voice stream with given ID.",
|
||||
function_ptr_command<const std::string&> play_stream(lsnes_cmd, "play-stream", "Play a stream",
|
||||
"play-stream <id>\nPlay a voice stream with given ID.",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
umutex_class m2(current_collection_lock);
|
||||
uint64_t id = parse_value<uint64_t>(x);
|
||||
|
@ -1402,8 +1403,8 @@ namespace
|
|||
messages << "Playing stream #" << id << "." << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> change_timebase("change-timebase", "Change stream timebase",
|
||||
"change-timebase <id> <newbase>\nChange timebase of given stream",
|
||||
function_ptr_command<const std::string&> change_timebase(lsnes_cmd, "change-timebase",
|
||||
"Change stream timebase", "change-timebase <id> <newbase>\nChange timebase of given stream",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
umutex_class m2(current_collection_lock);
|
||||
if(!current_collection) {
|
||||
|
@ -1459,15 +1460,16 @@ namespace
|
|||
messages << "Imported stream (" << st->length() / 48000.0 << "s) as ID #" << id << std::endl;
|
||||
}
|
||||
|
||||
function_ptr_command<const std::string&> import_stream_c("import-stream-opus", "Import a opus stream",
|
||||
"import-stream-opus <timebase> <filename>\nImport opus stream from <filename>, starting at "
|
||||
function_ptr_command<const std::string&> import_stream_c(lsnes_cmd, "import-stream-opus", "Import a opus "
|
||||
"stream", "import-stream-opus <timebase> <filename>\nImport opus stream from <filename>, starting at "
|
||||
"<timebase>",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
import_cmd_common(x, "opus", true);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> import_stream_p("import-stream-pcm", "Import a PCM stream",
|
||||
"import-stream-pcm <timebase> <filename>\nImport PCM stream from <filename>, starting at <timebase>",
|
||||
function_ptr_command<const std::string&> import_stream_p(lsnes_cmd, "import-stream-pcm", "Import a PCM "
|
||||
"stream", "import-stream-pcm <timebase> <filename>\nImport PCM stream from <filename>, starting at "
|
||||
"<timebase>",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
import_cmd_common(x, "pcm", false);
|
||||
});
|
||||
|
@ -1505,19 +1507,19 @@ namespace
|
|||
st->put_ref();
|
||||
}
|
||||
|
||||
function_ptr_command<const std::string&> export_stream_c("export-stream-opus", "Export a opus stream",
|
||||
"export-stream-opus <id> <filename>\nExport opus stream <id> to <filename>",
|
||||
function_ptr_command<const std::string&> export_stream_c(lsnes_cmd, "export-stream-opus", "Export a opus "
|
||||
"stream", "export-stream-opus <id> <filename>\nExport opus stream <id> to <filename>",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
export_cmd_common(x, "opus", true);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> export_stream_p("export-stream-pcm", "Export a PCM stream",
|
||||
"export-stream-pcm <id> <filename>\nExport PCM stream <id> to <filename>",
|
||||
function_ptr_command<const std::string&> export_stream_p(lsnes_cmd, "export-stream-pcm",
|
||||
"Export a PCM stream", "export-stream-pcm <id> <filename>\nExport PCM stream <id> to <filename>",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
export_cmd_common(x, "pcm", false);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> export_sstream("export-superstream", "Export superstream",
|
||||
function_ptr_command<const std::string&> export_sstream(lsnes_cmd, "export-superstream", "Export superstream",
|
||||
"export-superstream <filename>\nExport PCM superstream to <filename>",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
umutex_class m2(current_collection_lock);
|
||||
|
@ -1532,8 +1534,9 @@ namespace
|
|||
messages << "Superstream exported." << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> load_collection("load-collection", "Load voice subtitling "
|
||||
"collection", "load-collection <filename>\nLoad voice subtitling collection from <filename>",
|
||||
function_ptr_command<const std::string&> load_collection(lsnes_cmd, "load-collection",
|
||||
"Load voice subtitling collection", "load-collection <filename>\nLoad voice subtitling collection "
|
||||
"from <filename>",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
umutex_class m2(current_collection_lock);
|
||||
filesystem_ref newfs;
|
||||
|
@ -1551,7 +1554,7 @@ namespace
|
|||
messages << "Loaded '" << x << "'" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<> unload_collection("unload-collection", "Unload voice subtitling collection",
|
||||
function_ptr_command<> unload_collection(lsnes_cmd, "unload-collection", "Unload voice subtitling collection",
|
||||
"unload-collection\nUnload voice subtitling collection",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
umutex_class m2(current_collection_lock);
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace
|
|||
std::map<std::pair<uint64_t, unsigned>, keygroup*> hats;
|
||||
unsigned joystick_count = 0;
|
||||
|
||||
function_ptr_command<> show_joysticks("show-joysticks", "Show joysticks",
|
||||
function_ptr_command<> show_joysticks(lsnes_cmd, "show-joysticks", "Show joysticks",
|
||||
"Syntax: show-joysticks\nShow joystick data.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
messages << "Driver: " << joystick_plugin::name << std::endl;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
function_ptr_command<const std::string&> bind_key("bind-key", "Bind a (pseudo-)key",
|
||||
function_ptr_command<const std::string&> bind_key(lsnes_cmd, "bind-key", "Bind a (pseudo-)key",
|
||||
"Syntax: bind-key [<mod>/<modmask>] <key> <command>\nBind command to specified key (with specified "
|
||||
" modifiers)\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
|
@ -30,7 +30,7 @@ namespace
|
|||
messages << r[4] << " bound to '" << r[5] << "'" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> unbind_key("unbind-key", "Unbind a (pseudo-)key",
|
||||
function_ptr_command<const std::string&> unbind_key(lsnes_cmd, "unbind-key", "Unbind a (pseudo-)key",
|
||||
"Syntax: unbind-key [<mod>/<modmask>] <key>\nUnbind specified key (with specified modifiers)\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("(([^ /\t]*)/([^ /\t]*)[ \t]+)?([^ \t]+)[ \t]*", t, "Key required");
|
||||
|
@ -40,13 +40,13 @@ namespace
|
|||
messages << r[4] << " unbound" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<> show_bindings("show-bindings", "Show active bindings",
|
||||
function_ptr_command<> show_bindings(lsnes_cmd, "show-bindings", "Show active bindings",
|
||||
"Syntax: show-bindings\nShow bindings that are currently active.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
keymapper::dumpbindings();
|
||||
});
|
||||
|
||||
function_ptr_command<> show_inverse("show-inverse", "Show inverse bindings",
|
||||
function_ptr_command<> show_inverse(lsnes_cmd, "show-inverse", "Show inverse bindings",
|
||||
"Syntax: show-inverse\nShow inversebindings that are currently active.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
for(auto i : inverse_key::get_ikeys())
|
||||
|
@ -604,7 +604,7 @@ signed keygroup::get_value()
|
|||
|
||||
namespace
|
||||
{
|
||||
function_ptr_command<const std::string&> set_axis("set-axis", "Set mode of Joystick axis",
|
||||
function_ptr_command<const std::string&> set_axis(lsnes_cmd, "set-axis", "Set mode of Joystick axis",
|
||||
"Syntax: set-axis <axis> <options>...\nKnown options: disabled, axis, axis-inverse, pressure0-\n"
|
||||
"pressure0+, pressure-0, pressure-+, pressure+0, pressure+-\nminus=<val>, zero=<val>, plus=<val>\n"
|
||||
"tolerance=<val>\n",
|
||||
|
@ -684,7 +684,7 @@ namespace
|
|||
keygroups()[r[1]]->change_calibration(p.cal_left, p.cal_center, p.cal_right, p.cal_tolerance);
|
||||
});
|
||||
|
||||
function_ptr_command<> set_axismode("show-axes", "Show all joystick axes",
|
||||
function_ptr_command<> set_axismode(lsnes_cmd, "show-axes", "Show all joystick axes",
|
||||
"Syntax: show-axes\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
for(auto i = keygroups().begin(); i != keygroups().end(); ++i) {
|
||||
|
@ -753,7 +753,7 @@ namespace
|
|||
std::string cmd = fixup_command_polarity(command, polarity);
|
||||
if(cmd == "")
|
||||
return;
|
||||
command::invokeC(cmd);
|
||||
lsnes_cmd.invoke(cmd);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
function_ptr_command<arg_filename> load_lib("load-library", "Load a library",
|
||||
function_ptr_command<arg_filename> load_lib(lsnes_cmd, "load-library", "Load a library",
|
||||
"Syntax: load-library <file>\nLoad library <file>\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
try {
|
||||
|
|
|
@ -369,7 +369,7 @@ namespace
|
|||
}
|
||||
} _jukebox_size_listener;
|
||||
|
||||
function_ptr_command<> count_rerecords("count-rerecords", "Count rerecords",
|
||||
function_ptr_command<> count_rerecords(lsnes_cmd, "count-rerecords", "Count rerecords",
|
||||
"Syntax: count-rerecords\nCounts rerecords.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
std::vector<char> tmp;
|
||||
|
@ -377,7 +377,7 @@ namespace
|
|||
messages << x << " rerecord(s)" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> quit_emulator("quit-emulator", "Quit the emulator",
|
||||
function_ptr_command<const std::string&> quit_emulator(lsnes_cmd, "quit-emulator", "Quit the emulator",
|
||||
"Syntax: quit-emulator [/y]\nQuits emulator (/y => don't ask for confirmation).\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
amode = ADVANCE_QUIT;
|
||||
|
@ -385,7 +385,7 @@ namespace
|
|||
platform::cancel_wait();
|
||||
});
|
||||
|
||||
function_ptr_command<> unpause_emulator("unpause-emulator", "Unpause the emulator",
|
||||
function_ptr_command<> unpause_emulator(lsnes_cmd, "unpause-emulator", "Unpause the emulator",
|
||||
"Syntax: unpause-emulator\nUnpauses the emulator.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
amode = ADVANCE_AUTO;
|
||||
|
@ -394,7 +394,7 @@ namespace
|
|||
messages << "Unpaused" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<> pause_emulator("pause-emulator", "(Un)pause the emulator",
|
||||
function_ptr_command<> pause_emulator(lsnes_cmd, "pause-emulator", "(Un)pause the emulator",
|
||||
"Syntax: pause-emulator\n(Un)pauses the emulator.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(amode != ADVANCE_AUTO) {
|
||||
|
@ -410,7 +410,7 @@ namespace
|
|||
}
|
||||
});
|
||||
|
||||
function_ptr_command<> save_jukebox_prev("cycle-jukebox-backward", "Cycle save jukebox backwards",
|
||||
function_ptr_command<> save_jukebox_prev(lsnes_cmd, "cycle-jukebox-backward", "Cycle save jukebox backwards",
|
||||
"Syntax: cycle-jukebox-backward\nCycle save jukebox backwards\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
|
@ -425,7 +425,7 @@ namespace
|
|||
information_dispatch::do_status_update();
|
||||
});
|
||||
|
||||
function_ptr_command<> save_jukebox_next("cycle-jukebox-forward", "Cycle save jukebox forwards",
|
||||
function_ptr_command<> save_jukebox_next(lsnes_cmd, "cycle-jukebox-forward", "Cycle save jukebox forwards",
|
||||
"Syntax: cycle-jukebox-forward\nCycle save jukebox forwards\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
|
@ -440,7 +440,7 @@ namespace
|
|||
information_dispatch::do_status_update();
|
||||
});
|
||||
|
||||
function_ptr_command<> load_jukebox("load-jukebox", "Load save from jukebox",
|
||||
function_ptr_command<> load_jukebox(lsnes_cmd, "load-jukebox", "Load save from jukebox",
|
||||
"Syntax: load-jukebox\nLoad save from jukebox\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
|
@ -448,7 +448,7 @@ namespace
|
|||
mark_pending_load(save_jukebox_name(save_jukebox_pointer), LOAD_STATE_CURRENT);
|
||||
});
|
||||
|
||||
function_ptr_command<> save_jukebox_c("save-jukebox", "Save save to jukebox",
|
||||
function_ptr_command<> save_jukebox_c(lsnes_cmd, "save-jukebox", "Save save to jukebox",
|
||||
"Syntax: save-jukebox\nSave save to jukebox\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(jukebox_size == 0)
|
||||
|
@ -456,7 +456,7 @@ namespace
|
|||
mark_pending_save(save_jukebox_name(save_jukebox_pointer), SAVE_STATE);
|
||||
});
|
||||
|
||||
function_ptr_command<> padvance_frame("+advance-frame", "Advance one frame",
|
||||
function_ptr_command<> padvance_frame(lsnes_cmd, "+advance-frame", "Advance one frame",
|
||||
"Syntax: +advance-frame\nAdvances the emulation by one frame.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
amode = ADVANCE_FRAME;
|
||||
|
@ -466,7 +466,7 @@ namespace
|
|||
platform::set_paused(false);
|
||||
});
|
||||
|
||||
function_ptr_command<> nadvance_frame("-advance-frame", "Advance one frame",
|
||||
function_ptr_command<> nadvance_frame(lsnes_cmd, "-advance-frame", "Advance one frame",
|
||||
"No help available\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
cancel_advance = true;
|
||||
|
@ -474,7 +474,7 @@ namespace
|
|||
platform::set_paused(false);
|
||||
});
|
||||
|
||||
function_ptr_command<> padvance_poll("+advance-poll", "Advance one subframe",
|
||||
function_ptr_command<> padvance_poll(lsnes_cmd, "+advance-poll", "Advance one subframe",
|
||||
"Syntax: +advance-poll\nAdvances the emulation by one subframe.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
amode = ADVANCE_SUBFRAME;
|
||||
|
@ -484,7 +484,7 @@ namespace
|
|||
platform::set_paused(false);
|
||||
});
|
||||
|
||||
function_ptr_command<> nadvance_poll("-advance-poll", "Advance one subframe",
|
||||
function_ptr_command<> nadvance_poll(lsnes_cmd, "-advance-poll", "Advance one subframe",
|
||||
"No help available\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
cancel_advance = true;
|
||||
|
@ -492,7 +492,7 @@ namespace
|
|||
platform::set_paused(false);
|
||||
});
|
||||
|
||||
function_ptr_command<> advance_skiplag("advance-skiplag", "Skip to next poll",
|
||||
function_ptr_command<> advance_skiplag(lsnes_cmd, "advance-skiplag", "Skip to next poll",
|
||||
"Syntax: advance-skiplag\nAdvances the emulation to the next poll.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
amode = ADVANCE_SKIPLAG_PENDING;
|
||||
|
@ -500,7 +500,7 @@ namespace
|
|||
platform::set_paused(false);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> reset_c("reset", "Reset the SNES",
|
||||
function_ptr_command<const std::string&> reset_c(lsnes_cmd, "reset", "Reset the SNES",
|
||||
"Syntax: reset\nReset <delay>\nResets the SNES in beginning of the next frame.\n",
|
||||
[](const std::string& x) throw(std::bad_alloc, std::runtime_error) {
|
||||
if(x == "")
|
||||
|
@ -509,56 +509,56 @@ namespace
|
|||
pending_reset_cycles = parse_value<uint32_t>(x);
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> load_c("load", "Load savestate (current mode)",
|
||||
function_ptr_command<arg_filename> load_c(lsnes_cmd, "load", "Load savestate (current mode)",
|
||||
"Syntax: load <file>\nLoads SNES state from <file> in current mode\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_load(args, LOAD_STATE_CURRENT);
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> load_smart_c("load-smart", "Load savestate (heuristic mode)",
|
||||
function_ptr_command<arg_filename> load_smart_c(lsnes_cmd, "load-smart", "Load savestate (heuristic mode)",
|
||||
"Syntax: load <file>\nLoads SNES state from <file> in heuristic mode\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_load(args, LOAD_STATE_DEFAULT);
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> load_state_c("load-state", "Load savestate (R/W)",
|
||||
function_ptr_command<arg_filename> load_state_c(lsnes_cmd, "load-state", "Load savestate (R/W)",
|
||||
"Syntax: load-state <file>\nLoads SNES state from <file> in Read/Write mode\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_load(args, LOAD_STATE_RW);
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> load_readonly("load-readonly", "Load savestate (RO)",
|
||||
function_ptr_command<arg_filename> load_readonly(lsnes_cmd, "load-readonly", "Load savestate (RO)",
|
||||
"Syntax: load-readonly <file>\nLoads SNES state from <file> in read-only mode\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_load(args, LOAD_STATE_RO);
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> load_preserve("load-preserve", "Load savestate (preserve input)",
|
||||
"Syntax: load-preserve <file>\nLoads SNES state from <file> preserving input\n",
|
||||
function_ptr_command<arg_filename> load_preserve(lsnes_cmd, "load-preserve", "Load savestate (preserve "
|
||||
"input)", "Syntax: load-preserve <file>\nLoads SNES state from <file> preserving input\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_load(args, LOAD_STATE_PRESERVE);
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> load_movie_c("load-movie", "Load movie",
|
||||
function_ptr_command<arg_filename> load_movie_c(lsnes_cmd, "load-movie", "Load movie",
|
||||
"Syntax: load-movie <file>\nLoads SNES movie from <file>\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_load(args, LOAD_STATE_MOVIE);
|
||||
});
|
||||
|
||||
|
||||
function_ptr_command<arg_filename> save_state("save-state", "Save state",
|
||||
function_ptr_command<arg_filename> save_state(lsnes_cmd, "save-state", "Save state",
|
||||
"Syntax: save-state <file>\nSaves SNES state to <file>\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_save(args, SAVE_STATE);
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> save_movie("save-movie", "Save movie",
|
||||
function_ptr_command<arg_filename> save_movie(lsnes_cmd, "save-movie", "Save movie",
|
||||
"Syntax: save-movie <file>\nSaves SNES movie to <file>\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_save(args, SAVE_MOVIE);
|
||||
});
|
||||
|
||||
function_ptr_command<> set_rwmode("set-rwmode", "Switch to read/write mode",
|
||||
function_ptr_command<> set_rwmode(lsnes_cmd, "set-rwmode", "Switch to read/write mode",
|
||||
"Syntax: set-rwmode\nSwitches to read/write mode\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
movb.get_movie().readonly_mode(false);
|
||||
|
@ -568,7 +568,7 @@ namespace
|
|||
information_dispatch::do_status_update();
|
||||
});
|
||||
|
||||
function_ptr_command<> set_romode("set-romode", "Switch to read-only mode",
|
||||
function_ptr_command<> set_romode(lsnes_cmd, "set-romode", "Switch to read-only mode",
|
||||
"Syntax: set-romode\nSwitches to read-only mode\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
movb.get_movie().readonly_mode(true);
|
||||
|
@ -577,7 +577,7 @@ namespace
|
|||
information_dispatch::do_status_update();
|
||||
});
|
||||
|
||||
function_ptr_command<> toggle_rwmode("toggle-rwmode", "Toggle read/write mode",
|
||||
function_ptr_command<> toggle_rwmode(lsnes_cmd, "toggle-rwmode", "Toggle read/write mode",
|
||||
"Syntax: toggle-rwmode\nToggles read/write mode\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
bool c = movb.get_movie().readonly_mode();
|
||||
|
@ -589,50 +589,50 @@ namespace
|
|||
information_dispatch::do_status_update();
|
||||
});
|
||||
|
||||
function_ptr_command<> repaint("repaint", "Redraw the screen",
|
||||
function_ptr_command<> repaint(lsnes_cmd, "repaint", "Redraw the screen",
|
||||
"Syntax: repaint\nRedraws the screen\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
redraw_framebuffer();
|
||||
});
|
||||
|
||||
function_ptr_command<> tpon("toggle-pause-on-end", "Toggle pause on end", "Toggle pause on end\n",
|
||||
function_ptr_command<> tpon(lsnes_cmd, "toggle-pause-on-end", "Toggle pause on end", "Toggle pause on end\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
bool newstate = !static_cast<bool>(pause_on_end);
|
||||
pause_on_end.set(newstate ? "1" : "0");
|
||||
messages << "Pause-on-end is now " << (newstate ? "ON" : "OFF") << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<> rewind_movie("rewind-movie", "Rewind movie to the beginning",
|
||||
function_ptr_command<> rewind_movie(lsnes_cmd, "rewind-movie", "Rewind movie to the beginning",
|
||||
"Syntax: rewind-movie\nRewind movie to the beginning\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
mark_pending_load("SOME NONBLANK NAME", LOAD_STATE_BEGINNING);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> reload_rom2("reload-rom", "Reload the ROM image",
|
||||
function_ptr_command<const std::string&> reload_rom2(lsnes_cmd, "reload-rom", "Reload the ROM image",
|
||||
"Syntax: reload-rom [<file>]\nReload the ROM image from <file>\n",
|
||||
[](const std::string& filename) throw(std::bad_alloc, std::runtime_error) {
|
||||
if(reload_rom(filename))
|
||||
mark_pending_load("SOME NONBLANK NAME", LOAD_STATE_ROMRELOAD);
|
||||
});
|
||||
|
||||
function_ptr_command<> cancel_save("cancel-saves", "Cancel all pending saves", "Syntax: cancel-save\n"
|
||||
"Cancel pending saves\n",
|
||||
function_ptr_command<> cancel_save(lsnes_cmd, "cancel-saves", "Cancel all pending saves", "Syntax: "
|
||||
"cancel-save\nCancel pending saves\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
queued_saves.clear();
|
||||
messages << "Pending saves canceled." << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<> test1("test-1", "no description available", "No help available\n",
|
||||
function_ptr_command<> test1(lsnes_cmd, "test-1", "no description available", "No help available\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
redraw_framebuffer(screen_nosignal);
|
||||
});
|
||||
|
||||
function_ptr_command<> test2("test-2", "no description available", "No help available\n",
|
||||
function_ptr_command<> test2(lsnes_cmd, "test-2", "no description available", "No help available\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
redraw_framebuffer(screen_corrupt);
|
||||
});
|
||||
|
||||
function_ptr_command<> test3("test-3", "no description available", "No help available\n",
|
||||
function_ptr_command<> test3(lsnes_cmd, "test-3", "no description available", "No help available\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
while(1);
|
||||
});
|
||||
|
|
|
@ -971,7 +971,7 @@ namespace
|
|||
{
|
||||
public:
|
||||
memorymanip_command(const std::string& cmd) throw(std::bad_alloc)
|
||||
: command(cmd)
|
||||
: command(lsnes_cmd, cmd)
|
||||
{
|
||||
_command = cmd;
|
||||
}
|
||||
|
|
|
@ -400,14 +400,14 @@ void do_watch_memory()
|
|||
|
||||
namespace
|
||||
{
|
||||
function_ptr_command<const std::string&> add_watch("add-watch", "Add a memory watch",
|
||||
function_ptr_command<const std::string&> add_watch(lsnes_cmd, "add-watch", "Add a memory watch",
|
||||
"Syntax: add-watch <name> <expression>\nAdds a new memory watch\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("([^ \t]+)[ \t]+(|[^ \t].*)", t, "Name and expression required.");
|
||||
set_watchexpr_for(r[1], r[2]);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> remove_watch("remove-watch", "Remove a memory watch",
|
||||
function_ptr_command<const std::string&> remove_watch(lsnes_cmd, "remove-watch", "Remove a memory watch",
|
||||
"Syntax: remove-watch <name>\nRemoves a memory watch\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("([^ \t]+)[ \t]*", t, "Name required.");
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "lsnes.hpp"
|
||||
|
||||
#include "core/command.hpp"
|
||||
#include "core/memorymanip.hpp"
|
||||
#include "core/misc.hpp"
|
||||
#include "core/rom.hpp"
|
||||
|
@ -243,6 +244,8 @@ void reached_main()
|
|||
{
|
||||
reached_main_flag = true;
|
||||
init_threaded_malloc();
|
||||
lsnes_cmd.set_oom_panic(OOM_panic);
|
||||
lsnes_cmd.set_output(_messages());
|
||||
}
|
||||
|
||||
std::string bsnes_core_version;
|
||||
|
|
|
@ -98,20 +98,20 @@ namespace
|
|||
}
|
||||
} mprefix;
|
||||
|
||||
function_ptr_command<> get_gamename("get-gamename", "Get the game name",
|
||||
function_ptr_command<> get_gamename(lsnes_cmd, "get-gamename", "Get the game name",
|
||||
"Syntax: get-gamename\nPrints the game name\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
messages << "Game name is '" << our_movie.gamename << "'" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> set_gamename("set-gamename", "Set the game name",
|
||||
function_ptr_command<const std::string&> set_gamename(lsnes_cmd, "set-gamename", "Set the game name",
|
||||
"Syntax: set-gamename <name>\nSets the game name to <name>\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
our_movie.gamename = args;
|
||||
messages << "Game name changed to '" << our_movie.gamename << "'" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<> show_authors("show-authors", "Show the run authors",
|
||||
function_ptr_command<> show_authors(lsnes_cmd, "show-authors", "Show the run authors",
|
||||
"Syntax: show-authors\nShows the run authors\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
|
@ -122,7 +122,7 @@ namespace
|
|||
messages << "End of authors list" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> add_author("add-author", "Add an author",
|
||||
function_ptr_command<const std::string&> add_author(lsnes_cmd, "add-author", "Add an author",
|
||||
"Syntax: add-author <fullname>\nSyntax: add-author |<nickname>\n"
|
||||
"Syntax: add-author <fullname>|<nickname>\nAdds a new author\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
|
@ -131,7 +131,7 @@ namespace
|
|||
messages << (our_movie.authors.size() - 1) << ": " << g.first << "|" << g.second << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> remove_author("remove-author", "Remove an author",
|
||||
function_ptr_command<const std::string&> remove_author(lsnes_cmd, "remove-author", "Remove an author",
|
||||
"Syntax: remove-author <id>\nRemoves author with ID <id>\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
uint64_t index = parse_value<uint64_t>(t);
|
||||
|
@ -140,7 +140,7 @@ namespace
|
|||
our_movie.authors.erase(our_movie.authors.begin() + index);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> edit_author("edit-author", "Edit an author",
|
||||
function_ptr_command<const std::string&> edit_author(lsnes_cmd, "edit-author", "Edit an author",
|
||||
"Syntax: edit-author <authorid> <fullname>\nSyntax: edit-author <authorid> |<nickname>\n"
|
||||
"Syntax: edit-author <authorid> <fullname>|<nickname>\nEdits author name\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
|
@ -152,7 +152,7 @@ namespace
|
|||
our_movie.authors[index] = g;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> dump_coresave("dump-coresave", "Dump bsnes core state",
|
||||
function_ptr_command<const std::string&> dump_coresave(lsnes_cmd, "dump-coresave", "Dump bsnes core state",
|
||||
"Syntax: dump-coresave <name>\nDumps core save to <name>\n",
|
||||
[](const std::string& name) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto x = save_core_state();
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace
|
|||
{
|
||||
globalwrap<std::map<std::string, setting*>> settings;
|
||||
|
||||
function_ptr_command<const std::string&> set_setting("set-setting", "set a setting",
|
||||
function_ptr_command<const std::string&> set_setting(lsnes_cmd, "set-setting", "set a setting",
|
||||
"Syntax: set-setting <setting> [<value>]\nSet setting to a new value. Omit <value> to set to ''\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("([^ \t]+)([ \t]+(|[^ \t].*))?", t, "Setting name required.");
|
||||
|
@ -21,7 +21,7 @@ namespace
|
|||
messages << "Setting '" << r[1] << "' set to '" << r[3] << "'" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> unset_setting("unset-setting", "unset a setting",
|
||||
function_ptr_command<const std::string&> unset_setting(lsnes_cmd, "unset-setting", "unset a setting",
|
||||
"Syntax: unset-setting <setting>\nTry to unset a setting. Note that not all settings can be unset\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("([^ \t]+)[ \t]*", t, "Expected setting name and nothing else");
|
||||
|
@ -29,7 +29,7 @@ namespace
|
|||
messages << "Setting '" << r[1] << "' unset" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> get_command("get-setting", "get value of a setting",
|
||||
function_ptr_command<const std::string&> get_command(lsnes_cmd, "get-setting", "get value of a setting",
|
||||
"Syntax: get-setting <setting>\nShow value of setting\n",
|
||||
[](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
|
||||
auto r = regex("([^ \t]+)[ \t]*", t, "Expected setting name and nothing else");
|
||||
|
@ -40,7 +40,7 @@ namespace
|
|||
messages << "Setting '" << r[1] << "' is unset" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<> show_settings("show-settings", "Show values of all settings",
|
||||
function_ptr_command<> show_settings(lsnes_cmd, "show-settings", "Show values of all settings",
|
||||
"Syntax: show-settings\nShow value of all settings\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
for(auto i : setting::get_settings_set()) {
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace
|
|||
};
|
||||
|
||||
|
||||
function_ptr_command<const std::string&> edit_subtitle("edit-subtitle", "Edit a subtitle",
|
||||
function_ptr_command<const std::string&> edit_subtitle(lsnes_cmd, "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) {
|
||||
|
@ -111,7 +111,7 @@ namespace
|
|||
our_movie.subtitles[key] = s_unescape(text);
|
||||
});
|
||||
|
||||
function_ptr_command<> list_subtitle("list-subtitle", "List the subtitles",
|
||||
function_ptr_command<> list_subtitle(lsnes_cmd, "list-subtitle", "List the subtitles",
|
||||
"Syntax: list-subtitle\nList the subtitles.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
for(auto i = our_movie.subtitles.rbegin(); i != our_movie.subtitles.rend(); i++) {
|
||||
|
@ -120,7 +120,7 @@ namespace
|
|||
}
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> save_s("save-subtitle", "Save subtitles in .sub format",
|
||||
function_ptr_command<arg_filename> save_s(lsnes_cmd, "save-subtitle", "Save subtitles in .sub format",
|
||||
"Syntax: save-subtitle <file>\nSaves subtitles in .sub format to <file>\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error) {
|
||||
if(our_movie.subtitles.empty())
|
||||
|
|
|
@ -127,7 +127,7 @@ namespace
|
|||
{
|
||||
bool queue_function_run = false;
|
||||
|
||||
function_ptr_command<> identify_key("show-plugins", "Show plugins in use",
|
||||
function_ptr_command<> identify_key(lsnes_cmd, "show-plugins", "Show plugins in use",
|
||||
"Syntax: show-plugins\nShows plugins in use.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
messages << "Graphics:\t" << graphics_plugin::name << std::endl;
|
||||
|
@ -135,7 +135,7 @@ namespace
|
|||
messages << "Joystick:\t" << joystick_plugin::name << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> enable_sound("enable-sound", "Enable/Disable sound",
|
||||
function_ptr_command<const std::string&> enable_sound(lsnes_cmd, "enable-sound", "Enable/Disable sound",
|
||||
"Syntax: enable-sound <on/off>\nEnable or disable sound.\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
switch(string_to_bool(args)) {
|
||||
|
@ -156,7 +156,7 @@ namespace
|
|||
inverse_key ienable_sound("enable-sound on", "Sound‣Enable");
|
||||
inverse_key idisable_sound("enable-sound off", "Sound‣Disable");
|
||||
|
||||
function_ptr_command<const std::string&> set_sound_device("set-sound-device", "Set sound device",
|
||||
function_ptr_command<const std::string&> set_sound_device(lsnes_cmd, "set-sound-device", "Set sound device",
|
||||
"Syntax: set-sound-device <id>\nSet sound device to <id>.\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
if(!audioapi_driver_initialized())
|
||||
|
@ -164,7 +164,7 @@ namespace
|
|||
platform::set_sound_device(args);
|
||||
});
|
||||
|
||||
function_ptr_command<> get_sound_devices("show-sound-devices", "Show sound devices",
|
||||
function_ptr_command<> get_sound_devices(lsnes_cmd, "show-sound-devices", "Show sound devices",
|
||||
"Syntax: show-sound-devices\nShow listing of available sound devices\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
if(!audioapi_driver_initialized())
|
||||
|
@ -181,7 +181,7 @@ namespace
|
|||
<< dname << ")" << std::endl;
|
||||
});
|
||||
|
||||
function_ptr_command<> get_sound_status("show-sound-status", "Show sound status",
|
||||
function_ptr_command<> get_sound_status(lsnes_cmd, "show-sound-status", "Show sound status",
|
||||
"Syntax: show-sound-status\nShow current sound status\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
messages << "Sound plugin: " << audioapi_driver_name << std::endl;
|
||||
|
@ -197,7 +197,7 @@ namespace
|
|||
}
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> set_volume("set-volume", "Set sound volume",
|
||||
function_ptr_command<const std::string&> set_volume(lsnes_cmd, "set-volume", "Set sound volume",
|
||||
"Syntax: set-volume <scale>\nset-volume <scale>%\nset-volume <scale>dB\nSet sound volume\n",
|
||||
[](const std::string& value) throw(std::bad_alloc, std::runtime_error) {
|
||||
regex_results r;
|
||||
|
@ -215,8 +215,8 @@ namespace
|
|||
audioapi_music_volume(parsed);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> set_volume2("set-voice-volume", "Set voice playback volume",
|
||||
"Syntax: set-voice-volume <scale>\nset-voice-volume <scale>%\nset-voice-volume <scale>dB\n"
|
||||
function_ptr_command<const std::string&> set_volume2(lsnes_cmd, "set-voice-volume", "Set voice playback "
|
||||
"volume", "Syntax: set-voice-volume <scale>\nset-voice-volume <scale>%\nset-voice-volume <scale>dB\n"
|
||||
"Set voice volume\n",
|
||||
[](const std::string& value) throw(std::bad_alloc, std::runtime_error) {
|
||||
regex_results r;
|
||||
|
@ -234,9 +234,9 @@ namespace
|
|||
audioapi_voicep_volume(parsed);
|
||||
});
|
||||
|
||||
function_ptr_command<const std::string&> set_volume3("set-record-volume", "Set voice record volume",
|
||||
"Syntax: set-record-volume <scale>\nset-record-volume <scale>%\nset-record-volume <scale>dB\n"
|
||||
"Set record volume\n",
|
||||
function_ptr_command<const std::string&> set_volume3(lsnes_cmd, "set-record-volume", "Set voice record "
|
||||
"volume", "Syntax: set-record-volume <scale>\nset-record-volume <scale>%\nset-record-volume "
|
||||
"<scale>dB\nSet record volume\n",
|
||||
[](const std::string& value) throw(std::bad_alloc, std::runtime_error) {
|
||||
regex_results r;
|
||||
double parsed = 1;
|
||||
|
@ -457,7 +457,7 @@ namespace
|
|||
std::string c = commands.front();
|
||||
commands.pop_front();
|
||||
queue_lock->unlock();
|
||||
command::invokeC(c);
|
||||
lsnes_cmd.invoke(c);
|
||||
queue_lock->lock();
|
||||
queue_function_run = true;
|
||||
}
|
||||
|
|
471
src/library/commands.cpp
Normal file
471
src/library/commands.cpp
Normal file
|
@ -0,0 +1,471 @@
|
|||
#include "library/commands.hpp"
|
||||
#include "library/globalwrap.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "library/zip.hpp"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct run_script : public command
|
||||
{
|
||||
run_script(command_group& group, std::ostream*& _output)
|
||||
: command(group, "run-script"), in_group(group), output(_output)
|
||||
{
|
||||
}
|
||||
|
||||
~run_script() throw()
|
||||
{
|
||||
}
|
||||
|
||||
void invoke(const std::string& filename) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
if(filename == "") {
|
||||
(*output) << "Syntax: run-script <scriptfile>" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::istream* o = NULL;
|
||||
try {
|
||||
o = &open_file_relative(filename, "");
|
||||
(*output) << "Running '" << std::string(filename) << "'" << std::endl;
|
||||
std::string line;
|
||||
while(std::getline(*o, line))
|
||||
in_group.invoke(line);
|
||||
delete o;
|
||||
} catch(std::exception& e) {
|
||||
delete o;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "Run file as a script";
|
||||
}
|
||||
|
||||
std::string get_long_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "Syntax: run-script <file>\nRuns file <file> just as it would have been entered in "
|
||||
"the command line\n";
|
||||
}
|
||||
|
||||
command_group& in_group;
|
||||
std::ostream*& output;
|
||||
};
|
||||
|
||||
struct show_aliases : public command
|
||||
{
|
||||
show_aliases(command_group& group, std::ostream*& _output)
|
||||
: command(group, "show-aliases"), in_group(group), output(_output)
|
||||
{
|
||||
}
|
||||
|
||||
~show_aliases() throw()
|
||||
{
|
||||
}
|
||||
|
||||
void invoke(const std::string& filename) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
if(filename != "") {
|
||||
(*output) << "Syntax: show-aliases" << std::endl;
|
||||
return;
|
||||
}
|
||||
auto aliases = in_group.get_aliases();
|
||||
for(auto i : aliases) {
|
||||
std::string acmd = in_group.get_alias_for(i);
|
||||
while(acmd != "") {
|
||||
std::string j;
|
||||
extract_token(acmd, j, "\n");
|
||||
if(j != "")
|
||||
(*output) << "alias " << i << " " << j << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "Show aliases";
|
||||
}
|
||||
|
||||
std::string get_long_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "Syntax: show-aliases\nShow expansions of all aliases\n";
|
||||
}
|
||||
|
||||
command_group& in_group;
|
||||
std::ostream*& output;
|
||||
};
|
||||
|
||||
struct unalias_command : public command
|
||||
{
|
||||
unalias_command(command_group& group, std::ostream*& _output)
|
||||
: command(group, "unalias-command"), in_group(group), output(_output)
|
||||
{
|
||||
}
|
||||
|
||||
~unalias_command() throw()
|
||||
{
|
||||
}
|
||||
|
||||
void invoke(const std::string& t) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
auto r = regex("([^ \t]+)[ \t]*", t, "This command only takes one argument");
|
||||
if(!in_group.valid_alias_name(r[1]))
|
||||
throw std::runtime_error("Illegal alias name");
|
||||
in_group.set_alias_for(r[1], "");
|
||||
(*output) << "Command '" << r[1] << "' unaliased" << std::endl;
|
||||
}
|
||||
|
||||
std::string get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "Unalias a command";
|
||||
}
|
||||
|
||||
std::string get_long_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "Syntax: unalias-command <aliasname>\nClear expansion of alias <aliasname>\n";
|
||||
}
|
||||
|
||||
command_group& in_group;
|
||||
std::ostream*& output;
|
||||
};
|
||||
|
||||
struct alias_command : public command
|
||||
{
|
||||
alias_command(command_group& group, std::ostream*& _output)
|
||||
: command(group, "alias-command"), in_group(group), output(_output)
|
||||
{
|
||||
}
|
||||
|
||||
~alias_command() throw()
|
||||
{
|
||||
}
|
||||
|
||||
void invoke(const std::string& t) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
auto r = regex("([^ \t]+)[ \t]+([^ \t].*)", t, "Alias name and command needed");
|
||||
if(!in_group.valid_alias_name(r[1]))
|
||||
throw std::runtime_error("Illegal alias name");
|
||||
std::string tmp = in_group.get_alias_for(r[1]);
|
||||
tmp = tmp + r[2] + "\n";
|
||||
in_group.set_alias_for(r[1], tmp);
|
||||
(*output) << "Command '" << r[1] << "' aliased to '" << r[2] << "'" << std::endl;
|
||||
}
|
||||
|
||||
std::string get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "Alias a command";
|
||||
}
|
||||
|
||||
std::string get_long_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "Syntax: alias-command <aliasname> <command>\nAppend <command> to expansion of alias "
|
||||
"<aliasname>\nValid alias names can't be empty nor start with '*' or '?'\n";
|
||||
}
|
||||
|
||||
command_group& in_group;
|
||||
std::ostream*& output;
|
||||
};
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void default_oom_panic()
|
||||
{
|
||||
std::cerr << "PANIC: Fatal error, can't continue: Out of memory." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct pending_registration
|
||||
{
|
||||
command_group* group;
|
||||
std::string name;
|
||||
command* toreg;
|
||||
};
|
||||
|
||||
globalwrap<mutex_class> reg_mutex;
|
||||
globalwrap<std::set<command_group*>> ready_groups;
|
||||
globalwrap<std::list<pending_registration>> pending_registrations;
|
||||
|
||||
void run_pending_registrations()
|
||||
{
|
||||
umutex_class m(reg_mutex());
|
||||
auto i = pending_registrations().begin();
|
||||
while(i != pending_registrations().end()) {
|
||||
auto entry = i++;
|
||||
if(ready_groups().count(entry->group)) {
|
||||
entry->group->register_command(entry->name, *entry->toreg);
|
||||
pending_registrations().erase(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add_registration(command_group& group, const std::string& name, command& type)
|
||||
{
|
||||
{
|
||||
umutex_class m(reg_mutex());
|
||||
if(ready_groups().count(&group)) {
|
||||
group.register_command(name, type);
|
||||
return;
|
||||
}
|
||||
pending_registration p;
|
||||
p.group = &group;
|
||||
p.name = name;
|
||||
p.toreg = &type;
|
||||
pending_registrations().push_back(p);
|
||||
}
|
||||
run_pending_registrations();
|
||||
}
|
||||
|
||||
void delete_registration(command_group& group, const std::string& name)
|
||||
{
|
||||
{
|
||||
umutex_class m(reg_mutex());
|
||||
if(ready_groups().count(&group))
|
||||
group.unregister_command(name);
|
||||
else {
|
||||
auto i = pending_registrations().begin();
|
||||
while(i != pending_registrations().end()) {
|
||||
auto entry = i++;
|
||||
if(entry->group == &group && entry->name == name)
|
||||
pending_registrations().erase(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
command::command(command_group& group, const std::string& cmd) throw(std::bad_alloc)
|
||||
: in_group(group)
|
||||
{
|
||||
add_registration(in_group, commandname = cmd, *this);
|
||||
}
|
||||
|
||||
command::~command() throw()
|
||||
{
|
||||
delete_registration(in_group, commandname);
|
||||
}
|
||||
|
||||
|
||||
std::string command::get_short_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "No description available";
|
||||
}
|
||||
|
||||
std::string command::get_long_help() throw(std::bad_alloc)
|
||||
{
|
||||
return "No help available on command " + commandname;
|
||||
}
|
||||
|
||||
command_group::command_group() throw(std::bad_alloc)
|
||||
{
|
||||
oom_panic_routine = default_oom_panic;
|
||||
output = &std::cerr;
|
||||
{
|
||||
umutex_class m(reg_mutex());
|
||||
ready_groups().insert(this);
|
||||
}
|
||||
run_pending_registrations();
|
||||
//The builtin commands.
|
||||
new run_script(*this, output);
|
||||
new show_aliases(*this, output);
|
||||
new unalias_command(*this, output);
|
||||
new alias_command(*this, output);
|
||||
}
|
||||
|
||||
command_group::~command_group() throw()
|
||||
{
|
||||
{
|
||||
umutex_class m(reg_mutex());
|
||||
ready_groups().erase(this);
|
||||
}
|
||||
}
|
||||
|
||||
void command_group::invoke(const std::string& cmd) throw()
|
||||
{
|
||||
try {
|
||||
std::string cmd2 = strip_CR(cmd);
|
||||
if(cmd2 == "?") {
|
||||
//The special ? command.
|
||||
umutex_class lock(int_mutex);
|
||||
for(auto i : commands)
|
||||
(*output) << i.first << ": " << i.second->get_short_help() << std::endl;
|
||||
return;
|
||||
}
|
||||
if(firstchar(cmd2) == '?') {
|
||||
//?command.
|
||||
umutex_class lock(int_mutex);
|
||||
std::string rcmd = cmd2.substr(1, min(cmd2.find_first_of(" \t"), cmd2.length()));
|
||||
if(firstchar(rcmd) != '*') {
|
||||
//This may be an alias.
|
||||
if(aliases.count(rcmd)) {
|
||||
//Yup.
|
||||
(*output) << rcmd << " is an alias for: " << std::endl;
|
||||
size_t j = 0;
|
||||
for(auto i : aliases[rcmd])
|
||||
(*output) << "#" << (++j) << ": " << i << std::endl;
|
||||
return;
|
||||
}
|
||||
} else
|
||||
rcmd = rcmd.substr(1);
|
||||
if(!commands.count(rcmd))
|
||||
(*output) << "Unknown command '" << rcmd << "'" << std::endl;
|
||||
else
|
||||
(*output) << commands[rcmd]->get_long_help() << std::endl;
|
||||
return;
|
||||
}
|
||||
bool may_be_alias_expanded = true;
|
||||
if(firstchar(cmd2) == '*') {
|
||||
may_be_alias_expanded = false;
|
||||
cmd2 = cmd2.substr(1);
|
||||
}
|
||||
//Now this gets painful as command handlers must not be invoked with lock held.
|
||||
if(may_be_alias_expanded) {
|
||||
std::list<std::string> aexp;
|
||||
{
|
||||
umutex_class lock(int_mutex);
|
||||
if(!aliases.count(cmd))
|
||||
goto not_alias;
|
||||
aexp = aliases[cmd2];
|
||||
}
|
||||
for(auto i : aexp)
|
||||
invoke(i);
|
||||
return;
|
||||
}
|
||||
not_alias:
|
||||
try {
|
||||
size_t split = cmd2.find_first_of(" \t");
|
||||
std::string rcmd = cmd2.substr(0, min(split, cmd2.length()));
|
||||
std::string args = cmd2.substr(min(cmd2.find_first_not_of(" \t", split), cmd2.length()));
|
||||
command* cmdh = NULL;
|
||||
{
|
||||
umutex_class lock(int_mutex);
|
||||
if(!commands.count(rcmd)) {
|
||||
(*output) << "Unknown command '" << rcmd << "'" << std::endl;
|
||||
return;
|
||||
}
|
||||
cmdh = commands[rcmd];
|
||||
}
|
||||
if(command_stack.count(cmd2))
|
||||
throw std::runtime_error("Recursive command invocation");
|
||||
command_stack.insert(cmd2);
|
||||
cmdh->invoke(args);
|
||||
command_stack.erase(cmd2);
|
||||
return;
|
||||
} catch(std::bad_alloc& e) {
|
||||
oom_panic_routine();
|
||||
} catch(std::exception& e) {
|
||||
(*output) << "Error: " << e.what() << std::endl;
|
||||
command_stack.erase(cmd2);
|
||||
return;
|
||||
}
|
||||
} catch(std::bad_alloc& e) {
|
||||
oom_panic_routine();
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> command_group::get_aliases() throw(std::bad_alloc)
|
||||
{
|
||||
umutex_class lock(int_mutex);
|
||||
std::set<std::string> r;
|
||||
for(auto i : aliases)
|
||||
r.insert(i.first);
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string command_group::get_alias_for(const std::string& aname) throw(std::bad_alloc)
|
||||
{
|
||||
umutex_class lock(int_mutex);
|
||||
if(!valid_alias_name(aname))
|
||||
return "";
|
||||
if(aliases.count(aname)) {
|
||||
std::string x;
|
||||
for(auto i : aliases[aname])
|
||||
x = x + i + "\n";
|
||||
return x;
|
||||
} else
|
||||
return "";
|
||||
}
|
||||
|
||||
void command_group::set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc)
|
||||
{
|
||||
umutex_class lock(int_mutex);
|
||||
if(!valid_alias_name(aname))
|
||||
return;
|
||||
std::list<std::string> newlist;
|
||||
size_t avitr = 0;
|
||||
while(avitr < avalue.length()) {
|
||||
size_t nextsplit = min(avalue.find_first_of("\n", avitr), avalue.length());
|
||||
std::string x = strip_CR(avalue.substr(avitr, nextsplit - avitr));
|
||||
if(x.length() > 0)
|
||||
newlist.push_back(x);
|
||||
avitr = nextsplit + 1;
|
||||
}
|
||||
if(newlist.empty())
|
||||
aliases.erase(aname);
|
||||
else
|
||||
aliases[aname] = newlist;
|
||||
}
|
||||
|
||||
bool command_group::valid_alias_name(const std::string& aliasname) throw(std::bad_alloc)
|
||||
{
|
||||
if(aliasname.length() == 0 || aliasname[0] == '?' || aliasname[0] == '*')
|
||||
return false;
|
||||
if(aliasname.find_first_of(" \t") < aliasname.length())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void command_group::register_command(const std::string& name, command& cmd) throw(std::bad_alloc)
|
||||
{
|
||||
umutex_class lock(int_mutex);
|
||||
if(commands.count(name))
|
||||
std::cerr << "WARNING: Command collision for " << name << "!" << std::endl;
|
||||
commands[name] = &cmd;
|
||||
}
|
||||
|
||||
void command_group::unregister_command(const std::string& name) throw(std::bad_alloc)
|
||||
{
|
||||
umutex_class lock(int_mutex);
|
||||
commands.erase(name);
|
||||
}
|
||||
|
||||
void command_group::set_output(std::ostream& s)
|
||||
{
|
||||
output = &s;
|
||||
}
|
||||
|
||||
void command_group::set_oom_panic(void (*fn)())
|
||||
{
|
||||
if(fn)
|
||||
oom_panic_routine = fn;
|
||||
else
|
||||
oom_panic_routine = default_oom_panic;
|
||||
}
|
||||
|
||||
template<>
|
||||
void invoke_command_fn(void (*fn)(const std::string& args), const std::string& args)
|
||||
{
|
||||
fn(args);
|
||||
}
|
||||
|
||||
template<>
|
||||
void invoke_command_fn(void (*fn)(), const std::string& args)
|
||||
{
|
||||
if(args != "")
|
||||
throw std::runtime_error("This command does not take arguments");
|
||||
fn();
|
||||
}
|
||||
|
||||
template<>
|
||||
void invoke_command_fn(void (*fn)(struct arg_filename a), const std::string& args)
|
||||
{
|
||||
if(args == "")
|
||||
throw std::runtime_error("Filename required");
|
||||
arg_filename b;
|
||||
b.v = args;
|
||||
fn(b);
|
||||
}
|
|
@ -44,7 +44,7 @@ namespace
|
|||
|
||||
function_ptr_luafun lua_exec("exec", [](lua_State* LS, const std::string& fname) -> int {
|
||||
std::string text = get_string_argument(LS, 1, fname.c_str());
|
||||
command::invokeC(text);
|
||||
lsnes_cmd.invoke(text);
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ namespace
|
|||
}
|
||||
if(lua_requests_repaint) {
|
||||
lua_requests_repaint = false;
|
||||
command::invokeC("repaint");
|
||||
lsnes_cmd.invoke("repaint");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ namespace
|
|||
}
|
||||
if(lua_requests_repaint) {
|
||||
lua_requests_repaint = false;
|
||||
command::invokeC("repaint");
|
||||
lsnes_cmd.invoke("repaint");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,22 +499,22 @@ void lua_callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index
|
|||
|
||||
namespace
|
||||
{
|
||||
function_ptr_command<const std::string&> evaluate_lua("evaluate-lua", "Evaluate expression in Lua VM",
|
||||
"Syntax: evaluate-lua <expression>\nEvaluates <expression> in Lua VM.\n",
|
||||
function_ptr_command<const std::string&> evaluate_lua(lsnes_cmd, "evaluate-lua", "Evaluate expression in "
|
||||
"Lua VM", "Syntax: evaluate-lua <expression>\nEvaluates <expression> in Lua VM.\n",
|
||||
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
|
||||
if(args == "")
|
||||
throw std::runtime_error("Expected expression to evaluate");
|
||||
do_eval_lua(args);
|
||||
});
|
||||
|
||||
function_ptr_command<arg_filename> run_lua("run-lua", "Run Lua script in Lua VM",
|
||||
function_ptr_command<arg_filename> run_lua(lsnes_cmd, "run-lua", "Run Lua script in Lua VM",
|
||||
"Syntax: run-lua <file>\nRuns <file> in Lua VM.\n",
|
||||
[](arg_filename args) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
do_run_lua(args);
|
||||
});
|
||||
|
||||
function_ptr_command<> reset_lua("reset-lua", "Reset the Lua VM",
|
||||
function_ptr_command<> reset_lua(lsnes_cmd, "reset-lua", "Reset the Lua VM",
|
||||
"Syntax: reset-lua\nReset the Lua VM.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace
|
|||
return true;
|
||||
}
|
||||
|
||||
function_ptr_command<const std::string&> x("libao-set-id", "", "",
|
||||
function_ptr_command<const std::string&> x(lsnes_cmd, "libao-set-id", "", "",
|
||||
[](const std::string& value) throw(std::bad_alloc, std::runtime_error) {
|
||||
driver_id = parse_value<int>(value);
|
||||
});
|
||||
|
|
|
@ -186,7 +186,7 @@ namespace
|
|||
return true;
|
||||
}
|
||||
|
||||
function_ptr_command<const std::string&> x("portaudio", "", "",
|
||||
function_ptr_command<const std::string&> x(lsnes_cmd, "portaudio", "", "",
|
||||
[](const std::string& value) throw(std::bad_alloc, std::runtime_error) {
|
||||
messages << "Load: " << Pa_GetStreamCpuLoad(s) << std::endl;
|
||||
messages << "Rate: " << 1000000.0 * frames / (get_utime() - first_ts) << std::endl;
|
||||
|
|
|
@ -131,43 +131,43 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
function_ptr_command<> identify_key("identify-key", "Identify a key",
|
||||
function_ptr_command<> identify_key(lsnes_cmd, "identify-key", "Identify a key",
|
||||
"Syntax: identify-key\nIdentifies a (pseudo-)key.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
identify_requested = true;
|
||||
wake_ui();
|
||||
});
|
||||
|
||||
function_ptr_command<> scroll_up("scroll-up", "Scroll messages a page up",
|
||||
function_ptr_command<> scroll_up(lsnes_cmd, "scroll-up", "Scroll messages a page up",
|
||||
"Syntax: scroll-up\nScrolls message console backward one page.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
mutex::holder h(platform::msgbuf_lock());
|
||||
platform::msgbuf.scroll_up_page();
|
||||
});
|
||||
|
||||
function_ptr_command<> scroll_fullup("scroll-fullup", "Scroll messages to beginning",
|
||||
function_ptr_command<> scroll_fullup(lsnes_cmd, "scroll-fullup", "Scroll messages to beginning",
|
||||
"Syntax: scroll-fullup\nScrolls message console to its beginning.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
mutex::holder h(platform::msgbuf_lock());
|
||||
platform::msgbuf.scroll_beginning();
|
||||
});
|
||||
|
||||
function_ptr_command<> scroll_fulldown("scroll-fulldown", "Scroll messages to end",
|
||||
function_ptr_command<> scroll_fulldown(lsnes_cmd, "scroll-fulldown", "Scroll messages to end",
|
||||
"Syntax: scroll-fulldown\nScrolls message console to its end.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
mutex::holder h(platform::msgbuf_lock());
|
||||
platform::msgbuf.scroll_end();
|
||||
});
|
||||
|
||||
function_ptr_command<> scrolldown("scroll-down", "Scroll messages a page down",
|
||||
function_ptr_command<> scrolldown(lsnes_cmd, "scroll-down", "Scroll messages a page down",
|
||||
"Syntax: scroll-up\nScrolls message console forward one page.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
mutex::holder h(platform::msgbuf_lock());
|
||||
platform::msgbuf.scroll_down_page();
|
||||
});
|
||||
|
||||
function_ptr_command<> toggle_console("toggle-console", "Toggle console between small and full window",
|
||||
"Syntax: toggle-console\nToggles console between small and large.\n",
|
||||
function_ptr_command<> toggle_console(lsnes_cmd, "toggle-console", "Toggle console between small and full "
|
||||
"window", "Syntax: toggle-console\nToggles console between small and large.\n",
|
||||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
fullscreen_console = !fullscreen_console;
|
||||
wake_ui();
|
||||
|
@ -272,7 +272,7 @@ namespace
|
|||
platform::queue(emu_handle_identify, NULL, false);
|
||||
}
|
||||
|
||||
function_ptr_command<const std::string&> exec_command_prefix("prompt-command",
|
||||
function_ptr_command<const std::string&> exec_command_prefix(lsnes_cmd, "prompt-command",
|
||||
"Prompt for command", "Syntax: prompt-command <prefix>\nPrompts command with specified text.\n",
|
||||
[](const std::string& line) throw(std::bad_alloc, std::runtime_error) {
|
||||
delayed_cmd = line;
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace
|
|||
if(o.length() >= 6 && o.substr(0, 6) == "--run=") {
|
||||
std::string file = o.substr(6);
|
||||
messages << "--- Running " << file << " --- " << std::endl;
|
||||
command::invokeC("run-script " + file);
|
||||
lsnes_cmd.invoke("run-script " + file);
|
||||
messages << "--- End running " << file << " --- " << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ int main(int argc, char** argv)
|
|||
messages << "Saving per-user data to: " << get_config_path() << std::endl;
|
||||
messages << "--- Running lsnesrc --- " << std::endl;
|
||||
setting::set_storage_mode(true);
|
||||
command::invokeC("run-script " + cfgpath + "/lsnes.rc");
|
||||
lsnes_cmd.invoke("run-script " + cfgpath + "/lsnes.rc");
|
||||
setting::set_storage_mode(false);
|
||||
messages << "--- End running lsnesrc --- " << std::endl;
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ namespace
|
|||
for(auto i : setting::get_invalid_values())
|
||||
cfgfile << "set-setting " << i.first << " " << i.second << std::endl;
|
||||
//Aliases.
|
||||
for(auto i : command::get_aliases()) {
|
||||
std::string old_alias_value = command::get_alias_for(i);
|
||||
for(auto i : lsnes_cmd.get_aliases()) {
|
||||
std::string old_alias_value = lsnes_cmd.get_alias_for(i);
|
||||
while(old_alias_value != "") {
|
||||
std::string aliasline;
|
||||
size_t s = old_alias_value.find_first_of("\n");
|
||||
|
|
|
@ -200,8 +200,8 @@ end:
|
|||
for(auto i : setting::get_invalid_values())
|
||||
cfgfile << "set-setting " << i.first << " " << i.second << std::endl;
|
||||
//Aliases.
|
||||
for(auto i : command::get_aliases()) {
|
||||
std::string old_alias_value = command::get_alias_for(i);
|
||||
for(auto i : lsnes_cmd.get_aliases()) {
|
||||
std::string old_alias_value = lsnes_cmd.get_alias_for(i);
|
||||
while(old_alias_value != "") {
|
||||
std::string aliasline;
|
||||
size_t s = old_alias_value.find_first_of("\n");
|
||||
|
@ -378,7 +378,7 @@ bool lsnes_app::OnInit()
|
|||
messages << "Saving per-user data to: " << get_config_path() << std::endl;
|
||||
messages << "--- Running lsnesrc --- " << std::endl;
|
||||
setting::set_storage_mode(true);
|
||||
command::invokeC("run-script " + cfgpath + "/lsneswxw.rc");
|
||||
lsnes_cmd.invoke("run-script " + cfgpath + "/lsneswxw.rc");
|
||||
setting::set_storage_mode(false);
|
||||
messages << "--- End running lsnesrc --- " << std::endl;
|
||||
|
||||
|
|
|
@ -1088,14 +1088,14 @@ void wxeditor_esettings_aliases::on_add(wxCommandEvent& e)
|
|||
{
|
||||
try {
|
||||
std::string name = pick_text(this, "Enter alias name", "Enter name for the new alias:");
|
||||
if(!command::valid_alias_name(name)) {
|
||||
if(!lsnes_cmd.valid_alias_name(name)) {
|
||||
show_message_ok(this, "Error", "Not a valid alias name: " + name, wxICON_EXCLAMATION);
|
||||
throw canceled_exception();
|
||||
}
|
||||
std::string old_alias_value = command::get_alias_for(name);
|
||||
std::string old_alias_value = lsnes_cmd.get_alias_for(name);
|
||||
std::string newcmd = pick_text(this, "Edit alias", "Enter new commands for '" + name + "':",
|
||||
old_alias_value, true);
|
||||
command::set_alias_for(name, newcmd);
|
||||
lsnes_cmd.set_alias_for(name, newcmd);
|
||||
} catch(...) {
|
||||
}
|
||||
refresh();
|
||||
|
@ -1109,10 +1109,10 @@ void wxeditor_esettings_aliases::on_edit(wxCommandEvent& e)
|
|||
return;
|
||||
}
|
||||
try {
|
||||
std::string old_alias_value = command::get_alias_for(name);
|
||||
std::string old_alias_value = lsnes_cmd.get_alias_for(name);
|
||||
std::string newcmd = pick_text(this, "Edit alias", "Enter new commands for '" + name + "':",
|
||||
old_alias_value, true);
|
||||
command::set_alias_for(name, newcmd);
|
||||
lsnes_cmd.set_alias_for(name, newcmd);
|
||||
} catch(...) {
|
||||
}
|
||||
refresh();
|
||||
|
@ -1125,7 +1125,7 @@ void wxeditor_esettings_aliases::on_delete(wxCommandEvent& e)
|
|||
refresh();
|
||||
return;
|
||||
}
|
||||
command::set_alias_for(name, "");
|
||||
lsnes_cmd.set_alias_for(name, "");
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
@ -1134,7 +1134,7 @@ void wxeditor_esettings_aliases::refresh()
|
|||
int n = select->GetSelection();
|
||||
std::set<std::string> bind;
|
||||
std::vector<wxString> choices;
|
||||
bind = command::get_aliases();
|
||||
bind = lsnes_cmd.get_aliases();
|
||||
for(auto i : bind) {
|
||||
numbers[choices.size()] = i;
|
||||
choices.push_back(towxstring(i));
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace
|
|||
for(auto i = cmdline.begin(); i != cmdline.end(); i++) {
|
||||
std::string a = *i;
|
||||
if(a.length() > 6 && a.substr(0, 6) == "--lua=") {
|
||||
command::invokeC("run-lua " + a.substr(6));
|
||||
lsnes_cmd.invoke("run-lua " + a.substr(6));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue