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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clip range inside another.
|
||||
*
|
||||
|
|
|
@ -38,6 +38,12 @@
|
|||
#define SPECIAL_LEFT 0x4000000CUL
|
||||
//Right.
|
||||
#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.
|
||||
#define PRESSED_MASK 0x80000000UL
|
||||
|
||||
|
@ -193,6 +199,12 @@ struct commandline_model
|
|||
* Enable command line.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -421,6 +433,8 @@ void notify_emulator_exit();
|
|||
* The user interface loop. Call in UI thread. notify_emulator_exit() causes this to return.
|
||||
*/
|
||||
void ui_loop();
|
||||
|
||||
|
||||
/**
|
||||
* Save the config.
|
||||
*/
|
||||
void lsnes_sdl_save_config();
|
||||
#endif
|
||||
|
|
|
@ -1565,6 +1565,14 @@ scroll-down
|
|||
Scroll messages window forward one screenful.
|
||||
\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
|
||||
Settings
|
||||
\end_layout
|
||||
|
|
|
@ -765,6 +765,11 @@ Scroll messages window back 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.1 Core settings
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_LDFLAGS += $(shell $(CROSS_PREFIX)sdl-config --libs)
|
||||
else
|
||||
|
|
|
@ -7,6 +7,34 @@ namespace
|
|||
{
|
||||
volatile uint32_t autorepeat_first = 10;
|
||||
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()
|
||||
|
@ -91,6 +119,31 @@ std::string commandline_model::key(uint32_t k) throw(std::bad_alloc)
|
|||
return "";
|
||||
delete_codepoint(cursor_pos);
|
||||
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 PRESSED_MASK:
|
||||
//Eh?
|
||||
|
@ -145,6 +198,35 @@ bool commandline_model::overwriting() throw()
|
|||
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()
|
||||
{
|
||||
if(enabled_flag)
|
||||
|
|
|
@ -69,6 +69,9 @@ namespace
|
|||
SDL_TimerID timer_id;
|
||||
//Timer IRQ counter. Used by identify key stuff.
|
||||
volatile unsigned timer_irq_counter;
|
||||
//Delayed command to start.
|
||||
bool delayed_cmd_active;
|
||||
std::string delayed_cmd;
|
||||
|
||||
void sigalrm_handler(int s)
|
||||
{
|
||||
|
@ -270,6 +273,13 @@ namespace
|
|||
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.
|
||||
void ui_handle_quit_signal()
|
||||
{
|
||||
|
@ -307,7 +317,7 @@ void ui_loop()
|
|||
{
|
||||
ui_mutex->lock();
|
||||
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();
|
||||
usleep(2000);
|
||||
continue;
|
||||
|
@ -386,9 +396,13 @@ void ui_loop()
|
|||
switch(special_mode) {
|
||||
case SPECIALMODE_NORMAL:
|
||||
//Enable command line if needed.
|
||||
if(iskbd && kbdkey == SDLK_ESCAPE) {
|
||||
if((iskbd && kbdkey == SDLK_ESCAPE) || delayed_cmd_active) {
|
||||
if(!cmdline.enabled() && !polarity) {
|
||||
if(delayed_cmd_active)
|
||||
cmdline.enable(delayed_cmd);
|
||||
else
|
||||
cmdline.enable();
|
||||
delayed_cmd_active = false;
|
||||
commandline_updated = true;
|
||||
special_mode = SPECIALMODE_COMMAND;
|
||||
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.
|
||||
if(e.type != SDL_KEYDOWN && e.type != SDL_KEYUP)
|
||||
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.
|
||||
if(e.key.keysym.sym == SDLK_ESCAPE)
|
||||
return (e.type == SDL_KEYUP) ? SPECIAL_NAK : SPECIAL_NOOP;
|
||||
|
|
|
@ -210,6 +210,7 @@ int main(int argc, char** argv)
|
|||
fatal_error();
|
||||
return 1;
|
||||
}
|
||||
lsnes_sdl_save_config();
|
||||
rrdata::close();
|
||||
platform::quit();
|
||||
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