Merge branch 'rr1-maint'
This commit is contained in:
commit
48dbce5bfa
10 changed files with 264 additions and 7 deletions
|
@ -386,7 +386,6 @@ private:
|
||||||
std::map<size_t, page> memory;
|
std::map<size_t, page> memory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clip range inside another.
|
* Clip range inside another.
|
||||||
*
|
*
|
||||||
|
|
|
@ -38,6 +38,12 @@
|
||||||
#define SPECIAL_LEFT 0x4000000CUL
|
#define SPECIAL_LEFT 0x4000000CUL
|
||||||
//Right.
|
//Right.
|
||||||
#define SPECIAL_RIGHT 0x4000000DUL
|
#define SPECIAL_RIGHT 0x4000000DUL
|
||||||
|
//Left word.
|
||||||
|
#define SPECIAL_LEFT_WORD 0x4000000EUL
|
||||||
|
//Right word.
|
||||||
|
#define SPECIAL_RIGHT_WORD 0x4000000FUL
|
||||||
|
//Delete word.
|
||||||
|
#define SPECIAL_DELETE_WORD 0x40000010UL
|
||||||
//Pressed mask.
|
//Pressed mask.
|
||||||
#define PRESSED_MASK 0x80000000UL
|
#define PRESSED_MASK 0x80000000UL
|
||||||
|
|
||||||
|
@ -193,6 +199,12 @@ struct commandline_model
|
||||||
* Enable command line.
|
* Enable command line.
|
||||||
*/
|
*/
|
||||||
void enable() throw();
|
void enable() throw();
|
||||||
|
/**
|
||||||
|
* Enable command line with specific command.
|
||||||
|
*
|
||||||
|
* Parameter cmd: The command template.
|
||||||
|
*/
|
||||||
|
void enable(const std::string& cmd) throw();
|
||||||
/**
|
/**
|
||||||
* Repaint to SDL surface.
|
* Repaint to SDL surface.
|
||||||
*
|
*
|
||||||
|
@ -421,6 +433,8 @@ void notify_emulator_exit();
|
||||||
* The user interface loop. Call in UI thread. notify_emulator_exit() causes this to return.
|
* The user interface loop. Call in UI thread. notify_emulator_exit() causes this to return.
|
||||||
*/
|
*/
|
||||||
void ui_loop();
|
void ui_loop();
|
||||||
|
/**
|
||||||
|
* Save the config.
|
||||||
|
*/
|
||||||
|
void lsnes_sdl_save_config();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1565,6 +1565,14 @@ scroll-down
|
||||||
Scroll messages window forward one screenful.
|
Scroll messages window forward one screenful.
|
||||||
\end_layout
|
\end_layout
|
||||||
|
|
||||||
|
\begin_layout Subsubsection
|
||||||
|
prompt-command <command>
|
||||||
|
\end_layout
|
||||||
|
|
||||||
|
\begin_layout Standard
|
||||||
|
Enter command prompt, with prompt prepopulated with specified command.
|
||||||
|
\end_layout
|
||||||
|
|
||||||
\begin_layout Section
|
\begin_layout Section
|
||||||
Settings
|
Settings
|
||||||
\end_layout
|
\end_layout
|
||||||
|
|
|
@ -765,6 +765,11 @@ Scroll messages window back one screenful.
|
||||||
|
|
||||||
Scroll messages window forward one screenful.
|
Scroll messages window forward one screenful.
|
||||||
|
|
||||||
|
6.12.7 prompt-command <command>
|
||||||
|
|
||||||
|
Enter command prompt, with prompt prepopulated with specified
|
||||||
|
command.
|
||||||
|
|
||||||
7 Settings
|
7 Settings
|
||||||
|
|
||||||
7.1 Core settings
|
7.1 Core settings
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
ifeq ($(GRAPHICS), SDL)
|
ifeq ($(GRAPHICS), SDL)
|
||||||
OBJECTS = commandline.$(OBJECT_SUFFIX) drawprim.$(OBJECT_SUFFIX) graphicsfn.$(OBJECT_SUFFIX) keyboard.$(OBJECT_SUFFIX) main.$(OBJECT_SUFFIX) thread.$(OBJECT_SUFFIX) status.$(OBJECT_SUFFIX)
|
OBJECTS = commandline.$(OBJECT_SUFFIX) drawprim.$(OBJECT_SUFFIX) graphicsfn.$(OBJECT_SUFFIX) keyboard.$(OBJECT_SUFFIX) main.$(OBJECT_SUFFIX) thread.$(OBJECT_SUFFIX) status.$(OBJECT_SUFFIX) savesettings.$(OBJECT_SUFFIX)
|
||||||
SDL_CFLAGS += $(shell $(CROSS_PREFIX)sdl-config --cflags)
|
SDL_CFLAGS += $(shell $(CROSS_PREFIX)sdl-config --cflags)
|
||||||
SDL_LDFLAGS += $(shell $(CROSS_PREFIX)sdl-config --libs)
|
SDL_LDFLAGS += $(shell $(CROSS_PREFIX)sdl-config --libs)
|
||||||
else
|
else
|
||||||
|
|
|
@ -7,6 +7,34 @@ namespace
|
||||||
{
|
{
|
||||||
volatile uint32_t autorepeat_first = 10;
|
volatile uint32_t autorepeat_first = 10;
|
||||||
volatile uint32_t autorepeat_subsequent = 4;
|
volatile uint32_t autorepeat_subsequent = 4;
|
||||||
|
|
||||||
|
bool is_whitespace(uint32_t cp)
|
||||||
|
{
|
||||||
|
switch(cp) {
|
||||||
|
case 12:
|
||||||
|
case 32:
|
||||||
|
case 9:
|
||||||
|
case 0x1680:
|
||||||
|
case 0x180E:
|
||||||
|
case 0x2000:
|
||||||
|
case 0x2001:
|
||||||
|
case 0x2002:
|
||||||
|
case 0x2003:
|
||||||
|
case 0x2004:
|
||||||
|
case 0x2005:
|
||||||
|
case 0x2006:
|
||||||
|
case 0x2007:
|
||||||
|
case 0x2008:
|
||||||
|
case 0x2009:
|
||||||
|
case 0x200A:
|
||||||
|
case 0x2028:
|
||||||
|
case 0x205F:
|
||||||
|
case 0x3000:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commandline_model::commandline_model() throw()
|
commandline_model::commandline_model() throw()
|
||||||
|
@ -91,6 +119,31 @@ std::string commandline_model::key(uint32_t k) throw(std::bad_alloc)
|
||||||
return "";
|
return "";
|
||||||
delete_codepoint(cursor_pos);
|
delete_codepoint(cursor_pos);
|
||||||
return "";
|
return "";
|
||||||
|
case SPECIAL_LEFT_WORD:
|
||||||
|
while(cursor_pos > 0 && (cursor_pos == codepoints.size() || isspace(codepoints[cursor_pos])))
|
||||||
|
cursor_pos--;
|
||||||
|
while(cursor_pos > 0 && (cursor_pos == codepoints.size() || !isspace(codepoints[cursor_pos])))
|
||||||
|
cursor_pos--;
|
||||||
|
//If the previous position is whitespace, back off to it.
|
||||||
|
while(cursor_pos > 0 && isspace(codepoints[cursor_pos - 1]))
|
||||||
|
cursor_pos--;
|
||||||
|
return "";
|
||||||
|
case SPECIAL_RIGHT_WORD:
|
||||||
|
while(cursor_pos < codepoints.size() && isspace(codepoints[cursor_pos]))
|
||||||
|
cursor_pos++;
|
||||||
|
while(cursor_pos < codepoints.size() && !isspace(codepoints[cursor_pos]))
|
||||||
|
cursor_pos++;
|
||||||
|
return "";
|
||||||
|
case SPECIAL_DELETE_WORD:
|
||||||
|
while(cursor_pos > 0 && !isspace(codepoints[cursor_pos - 1])) {
|
||||||
|
delete_codepoint(cursor_pos - 1);
|
||||||
|
cursor_pos--;
|
||||||
|
}
|
||||||
|
while(cursor_pos > 0 && isspace(codepoints[cursor_pos - 1])) {
|
||||||
|
delete_codepoint(cursor_pos - 1);
|
||||||
|
cursor_pos--;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
case 0:
|
case 0:
|
||||||
case PRESSED_MASK:
|
case PRESSED_MASK:
|
||||||
//Eh?
|
//Eh?
|
||||||
|
@ -145,6 +198,35 @@ bool commandline_model::overwriting() throw()
|
||||||
return overwrite_mode;
|
return overwrite_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void commandline_model::enable(const std::string& cmd) throw()
|
||||||
|
{
|
||||||
|
enable();
|
||||||
|
unsigned left = 0;
|
||||||
|
unsigned tmp = 0;
|
||||||
|
for(size_t itr = 0; itr < cmd.length(); itr++) {
|
||||||
|
unsigned char ch = cmd[itr];
|
||||||
|
if(ch < 128)
|
||||||
|
codepoints.push_back(ch);
|
||||||
|
else if(left) {
|
||||||
|
left--;
|
||||||
|
tmp = tmp * 64 + (ch & 0x3F);
|
||||||
|
if(!left)
|
||||||
|
codepoints.push_back(tmp);
|
||||||
|
} else if(ch < 192) {
|
||||||
|
} else if(ch < 224) {
|
||||||
|
left = 1;
|
||||||
|
tmp = ch & 0x1F;
|
||||||
|
} else if(ch < 240) {
|
||||||
|
left = 2;
|
||||||
|
tmp = ch & 0x0F;
|
||||||
|
} else if(ch < 248) {
|
||||||
|
left = 3;
|
||||||
|
tmp = ch & 0x07;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor_pos = codepoints.size();
|
||||||
|
}
|
||||||
|
|
||||||
void commandline_model::enable() throw()
|
void commandline_model::enable() throw()
|
||||||
{
|
{
|
||||||
if(enabled_flag)
|
if(enabled_flag)
|
||||||
|
|
|
@ -69,6 +69,9 @@ namespace
|
||||||
SDL_TimerID timer_id;
|
SDL_TimerID timer_id;
|
||||||
//Timer IRQ counter. Used by identify key stuff.
|
//Timer IRQ counter. Used by identify key stuff.
|
||||||
volatile unsigned timer_irq_counter;
|
volatile unsigned timer_irq_counter;
|
||||||
|
//Delayed command to start.
|
||||||
|
bool delayed_cmd_active;
|
||||||
|
std::string delayed_cmd;
|
||||||
|
|
||||||
void sigalrm_handler(int s)
|
void sigalrm_handler(int s)
|
||||||
{
|
{
|
||||||
|
@ -270,6 +273,13 @@ namespace
|
||||||
platform::queue(emu_handle_identify, NULL, false);
|
platform::queue(emu_handle_identify, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function_ptr_command<const std::string&> exec_command_prefix("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;
|
||||||
|
delayed_cmd_active = true;
|
||||||
|
});
|
||||||
|
|
||||||
//Handle QUIT in normal state.
|
//Handle QUIT in normal state.
|
||||||
void ui_handle_quit_signal()
|
void ui_handle_quit_signal()
|
||||||
{
|
{
|
||||||
|
@ -307,7 +317,7 @@ void ui_loop()
|
||||||
{
|
{
|
||||||
ui_mutex->lock();
|
ui_mutex->lock();
|
||||||
int r = SDL_PollEvent(&e);
|
int r = SDL_PollEvent(&e);
|
||||||
if(!repaint_in_flight && !timer_triggered && !r) {
|
if(!repaint_in_flight && !timer_triggered && !delayed_cmd_active && !r) {
|
||||||
ui_mutex->unlock();
|
ui_mutex->unlock();
|
||||||
usleep(2000);
|
usleep(2000);
|
||||||
continue;
|
continue;
|
||||||
|
@ -386,9 +396,13 @@ void ui_loop()
|
||||||
switch(special_mode) {
|
switch(special_mode) {
|
||||||
case SPECIALMODE_NORMAL:
|
case SPECIALMODE_NORMAL:
|
||||||
//Enable command line if needed.
|
//Enable command line if needed.
|
||||||
if(iskbd && kbdkey == SDLK_ESCAPE) {
|
if((iskbd && kbdkey == SDLK_ESCAPE) || delayed_cmd_active) {
|
||||||
if(!cmdline.enabled() && !polarity) {
|
if(!cmdline.enabled() && !polarity) {
|
||||||
cmdline.enable();
|
if(delayed_cmd_active)
|
||||||
|
cmdline.enable(delayed_cmd);
|
||||||
|
else
|
||||||
|
cmdline.enable();
|
||||||
|
delayed_cmd_active = false;
|
||||||
commandline_updated = true;
|
commandline_updated = true;
|
||||||
special_mode = SPECIALMODE_COMMAND;
|
special_mode = SPECIALMODE_COMMAND;
|
||||||
platform::set_modal_pause(true);
|
platform::set_modal_pause(true);
|
||||||
|
|
|
@ -306,6 +306,46 @@ uint32_t get_command_edit_operation(SDL_Event& e, bool enable)
|
||||||
//Everything except keyboard is no-op.
|
//Everything except keyboard is no-op.
|
||||||
if(e.type != SDL_KEYDOWN && e.type != SDL_KEYUP)
|
if(e.type != SDL_KEYDOWN && e.type != SDL_KEYUP)
|
||||||
return SPECIAL_NOOP;
|
return SPECIAL_NOOP;
|
||||||
|
//Keys with CTRL held.
|
||||||
|
if(e.key.keysym.mod & KMOD_CTRL) {
|
||||||
|
switch(e.key.keysym.sym) {
|
||||||
|
case 'A': case 'a':
|
||||||
|
return SPECIAL_HOME | press;
|
||||||
|
case 'B': case 'b':
|
||||||
|
return SPECIAL_LEFT | press;
|
||||||
|
case 'D': case 'd':
|
||||||
|
return SPECIAL_DELETE | press;
|
||||||
|
case 'E': case 'e':
|
||||||
|
return SPECIAL_END | press;
|
||||||
|
case 'F': case 'f':
|
||||||
|
return SPECIAL_RIGHT | press;
|
||||||
|
case 'P': case 'p':
|
||||||
|
return SPECIAL_UP | press;
|
||||||
|
case 'N': case 'n':
|
||||||
|
return SPECIAL_DOWN | press;
|
||||||
|
case SDLK_LEFT:
|
||||||
|
return SPECIAL_LEFT_WORD | press;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
return SPECIAL_RIGHT_WORD | press;
|
||||||
|
case 'W': case 'w':
|
||||||
|
return SPECIAL_DELETE_WORD | press;
|
||||||
|
default:
|
||||||
|
return SPECIAL_NOOP;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//Keys with ALT held.
|
||||||
|
if(e.key.keysym.mod & KMOD_ALT) {
|
||||||
|
switch(e.key.keysym.sym) {
|
||||||
|
case 'B': case 'b':
|
||||||
|
return SPECIAL_LEFT_WORD | press;
|
||||||
|
case 'D': case 'd':
|
||||||
|
return SPECIAL_DELETE_WORD | press;
|
||||||
|
case 'F': case 'f':
|
||||||
|
return SPECIAL_RIGHT_WORD | press;
|
||||||
|
default:
|
||||||
|
return SPECIAL_NOOP;
|
||||||
|
};
|
||||||
|
}
|
||||||
//Escape is special.
|
//Escape is special.
|
||||||
if(e.key.keysym.sym == SDLK_ESCAPE)
|
if(e.key.keysym.sym == SDLK_ESCAPE)
|
||||||
return (e.type == SDL_KEYUP) ? SPECIAL_NAK : SPECIAL_NOOP;
|
return (e.type == SDL_KEYUP) ? SPECIAL_NAK : SPECIAL_NOOP;
|
||||||
|
|
|
@ -210,6 +210,7 @@ int main(int argc, char** argv)
|
||||||
fatal_error();
|
fatal_error();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
lsnes_sdl_save_config();
|
||||||
rrdata::close();
|
rrdata::close();
|
||||||
platform::quit();
|
platform::quit();
|
||||||
quit_lua();
|
quit_lua();
|
||||||
|
|
94
src/platform/sdl/savesettings.cpp
Normal file
94
src/platform/sdl/savesettings.cpp
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#include "core/command.hpp"
|
||||||
|
#include "core/controller.hpp"
|
||||||
|
#include "core/dispatch.hpp"
|
||||||
|
#include "core/framerate.hpp"
|
||||||
|
#include "lua/lua.hpp"
|
||||||
|
#include "core/mainloop.hpp"
|
||||||
|
#include "core/misc.hpp"
|
||||||
|
#include "core/moviedata.hpp"
|
||||||
|
#include "core/rom.hpp"
|
||||||
|
#include "core/rrdata.hpp"
|
||||||
|
#include "core/settings.hpp"
|
||||||
|
#include "core/window.hpp"
|
||||||
|
#include "library/zip.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void write_configuration(const std::string& cfg)
|
||||||
|
{
|
||||||
|
std::ofstream cfgfile(cfg.c_str());
|
||||||
|
//Joystick axis.
|
||||||
|
for(auto i : keygroup::get_axis_set()) {
|
||||||
|
keygroup* k = keygroup::lookup_by_name(i);
|
||||||
|
auto p = k->get_parameters();
|
||||||
|
cfgfile << "set-axis " << i << " ";
|
||||||
|
switch(p.ktype) {
|
||||||
|
case keygroup::KT_DISABLED: cfgfile << "disabled"; break;
|
||||||
|
case keygroup::KT_AXIS_PAIR: cfgfile << "axis"; break;
|
||||||
|
case keygroup::KT_AXIS_PAIR_INVERSE: cfgfile << "axis-inverse"; break;
|
||||||
|
case keygroup::KT_PRESSURE_M0: cfgfile << "pressure-0"; break;
|
||||||
|
case keygroup::KT_PRESSURE_MP: cfgfile << "pressure-+"; break;
|
||||||
|
case keygroup::KT_PRESSURE_0M: cfgfile << "pressure0-"; break;
|
||||||
|
case keygroup::KT_PRESSURE_0P: cfgfile << "pressure0+"; break;
|
||||||
|
case keygroup::KT_PRESSURE_PM: cfgfile << "pressure+-"; break;
|
||||||
|
case keygroup::KT_PRESSURE_P0: cfgfile << "pressure+0"; break;
|
||||||
|
};
|
||||||
|
cfgfile << " minus=" << p.cal_left << " zero=" << p.cal_center << " plus=" << p.cal_right
|
||||||
|
<< " tolerance=" << p.cal_tolerance << std::endl;
|
||||||
|
}
|
||||||
|
//Settings.
|
||||||
|
for(auto i : setting::get_settings_set()) {
|
||||||
|
if(!setting::is_set(i))
|
||||||
|
cfgfile << "unset-setting " << i << std::endl;
|
||||||
|
else
|
||||||
|
cfgfile << "set-setting " << i << " " << setting::get(i) << std::endl;
|
||||||
|
}
|
||||||
|
//Aliases.
|
||||||
|
for(auto i : command::get_aliases()) {
|
||||||
|
std::string old_alias_value = command::get_alias_for(i);
|
||||||
|
while(old_alias_value != "") {
|
||||||
|
std::string aliasline;
|
||||||
|
size_t s = old_alias_value.find_first_of("\n");
|
||||||
|
if(s < old_alias_value.length()) {
|
||||||
|
aliasline = old_alias_value.substr(0, s);
|
||||||
|
old_alias_value = old_alias_value.substr(s + 1);
|
||||||
|
} else {
|
||||||
|
aliasline = old_alias_value;
|
||||||
|
old_alias_value = "";
|
||||||
|
}
|
||||||
|
cfgfile << "alias-command " << i << " " << aliasline << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Keybindings.
|
||||||
|
for(auto i : keymapper::get_bindings()) {
|
||||||
|
std::string i2 = i;
|
||||||
|
size_t s = i2.find_first_of("|");
|
||||||
|
size_t s2 = i2.find_first_of("/");
|
||||||
|
if(s > i2.length() || s2 > s)
|
||||||
|
continue;
|
||||||
|
std::string key = i2.substr(s + 1);
|
||||||
|
std::string mod = i2.substr(0, s2);
|
||||||
|
std::string modspec = i2.substr(s2 + 1, s - s2 - 1);
|
||||||
|
std::string old_command_value = keymapper::get_command_for(i);
|
||||||
|
if(mod != "" || modspec != "")
|
||||||
|
cfgfile << "bind-key " << mod << "/" << modspec << " " << key << " "
|
||||||
|
<< old_command_value << std::endl;
|
||||||
|
else
|
||||||
|
cfgfile << "bind-key " << key << " " << old_command_value << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsnes_sdl_save_config()
|
||||||
|
{
|
||||||
|
std::string cfg = get_config_path() + "/lsnes.rc";
|
||||||
|
std::string cfgn = cfg + ".new";
|
||||||
|
write_configuration(cfg + ".new");
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(TEST_WIN32_CODE)
|
||||||
|
//Grumble, Windows seemingly can't do this atomically.
|
||||||
|
remove(cfg.c_str());
|
||||||
|
#endif
|
||||||
|
rename(cfgn.c_str(), cfg.c_str());
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue