From efbc60d494463e3252132b5e549f8c306fb7dcc1 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Wed, 1 May 2013 18:06:24 +0300 Subject: [PATCH] Allow button display symbols to be Unicode characters --- include/library/controller-data.hpp | 4 +-- include/library/emustatus.hpp | 15 ++++++-- include/library/luabase.hpp | 3 ++ include/platform/wxwidgets/window_mainwindow.hpp | 2 +- src/core/mainloop.cpp | 2 +- src/emulation/make-ports.lua | 6 ++-- src/library/controller-data.cpp | 18 ++++++++-- src/library/emustatus.cpp | 12 +++++-- src/platform/wxwidgets/editor-movie.cpp | 6 ++-- src/platform/wxwidgets/mainwindow.cpp | 46 ++++++++++++------------ src/platform/wxwidgets/status.cpp | 4 +-- 11 files changed, 74 insertions(+), 44 deletions(-) diff --git a/include/library/controller-data.hpp b/include/library/controller-data.hpp index 8befa8db..7f7b3d48 100644 --- a/include/library/controller-data.hpp +++ b/include/library/controller-data.hpp @@ -184,7 +184,7 @@ struct port_controller_button TYPE_TAXIS //Throttle Axis (does not pair). }; enum _type type; - char symbol; + char32_t symbol; const char* name; bool shadow; int16_t rmin; //Range min. @@ -884,7 +884,7 @@ public: * Parameter controller: The controller * Parameter buf: Buffer to write nul-terminated display to. */ - void display(unsigned port, unsigned controller, char* buf) throw(); + void display(unsigned port, unsigned controller, char32_t* buf) throw(); /** * Is device present? * diff --git a/include/library/emustatus.hpp b/include/library/emustatus.hpp index ac2633b5..18d84f71 100644 --- a/include/library/emustatus.hpp +++ b/include/library/emustatus.hpp @@ -5,6 +5,7 @@ #include #include +#include "utf8.hpp" class emulator_status { @@ -28,6 +29,14 @@ public: */ void set(const std::string& key, const std::string& value) throw(std::bad_alloc); /** + * Insert/Replace key. + * + * Parameter key: Key to insert/replace. + * Parameter value: The value to assign. + * Throws std::bad_alloc: Not enough memory. + */ + void set(const std::string& key, const std::u32string& value) throw(std::bad_alloc); +/** * Has key? * * Parameter key: Key to check. @@ -46,7 +55,7 @@ public: * Parameter key: The key to read. * Returns: The value of key ("" if not found). */ - std::string get(const std::string& key) throw(std::bad_alloc); + std::u32string get(const std::string& key) throw(std::bad_alloc); /** * Iterator. */ @@ -63,7 +72,7 @@ public: /** * Value. */ - std::string value; + std::u32string value; }; /** * Get first iterator @@ -84,7 +93,7 @@ private: emulator_status(const emulator_status&); emulator_status& operator=(const emulator_status&); mutex_class lock; - std::map content; + std::map content; }; #endif diff --git a/include/library/luabase.hpp b/include/library/luabase.hpp index c7d796ef..6d5dbf7e 100644 --- a/include/library/luabase.hpp +++ b/include/library/luabase.hpp @@ -6,6 +6,7 @@ #include #include #include "string.hpp" +#include "utf8.hpp" extern "C" { #include @@ -276,6 +277,8 @@ public: const char* tostring(int index) { return lua_tostring(lua_handle, index); } const char* tolstring(int index, size_t& len) { return lua_tolstring(lua_handle, index, &len); } void pushlstring(const char* s, size_t len) { lua_pushlstring(lua_handle, s, len); } + void pushlstring(const std::string& s) { lua_pushlstring(lua_handle, s.c_str(), s.length()); } + void pushlstring(const char32_t* s, size_t len) { pushlstring(to_u8string(std::u32string(s, len))); } int pcall(int nargs, int nresults, int errfunc) { return lua_pcall(lua_handle, nargs, nresults, errfunc); } int next(int index) { return lua_next(lua_handle, index); } int isnoneornil(int index) { return lua_isnoneornil(lua_handle, index); } diff --git a/include/platform/wxwidgets/window_mainwindow.hpp b/include/platform/wxwidgets/window_mainwindow.hpp index 9de7fd96..2b299341 100644 --- a/include/platform/wxwidgets/window_mainwindow.hpp +++ b/include/platform/wxwidgets/window_mainwindow.hpp @@ -42,7 +42,7 @@ public: void menu_check(int id, bool newstate); void menu_separator(); void handle_menu_click(wxCommandEvent& e); - void update_statusbar(const std::map& vars); + void update_statusbar(const std::map& vars); recent_menu* recent_roms; recent_menu* recent_movies; private: diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index 9bc0697c..9b9bc74c 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -400,7 +400,7 @@ void update_movie_state() last_controllers = i; break; } - char buffer[MAX_DISPLAY_LENGTH]; + char32_t buffer[MAX_DISPLAY_LENGTH]; c.display(pindex.first, pindex.second, buffer); _status.set((stringfmt() << "P" << (i + 1)).str(), buffer); } diff --git a/src/emulation/make-ports.lua b/src/emulation/make-ports.lua index 3440030d..152b6ae4 100644 --- a/src/emulation/make-ports.lua +++ b/src/emulation/make-ports.lua @@ -38,7 +38,7 @@ for i = 1,#ports do if xbutton[1] == button then table.insert(bsyms, bsym); print("\tport_controller_button "..bsym.." = {port_controller_button::TYPE_BUTTON, ".. - "'" .. xbutton[2] .. "', \""..xbutton[3].."\", false, 0, 0, false};"); + "U'" .. xbutton[2] .. "', \""..xbutton[3].."\", false, 0, 0, false};"); bits = bits + 1; end if xbutton[1] == axis then @@ -65,7 +65,7 @@ for i = 1,#ports do if xbutton[1] == shadow then table.insert(bsyms, bsym); print("\tport_controller_button "..bsym.." = {port_controller_button::TYPE_BUTTON, ".. - "'" .. xbutton[2] .. "', \""..xbutton[3].."\", true};"); + "U'" .. xbutton[2] .. "', \""..xbutton[3].."\", true};"); bits = bits + 1; end if xbutton[1] == shadow_axis then @@ -189,7 +189,7 @@ for i = 1,#ports do local bidx = math.floor(bit_l / 8); local bmask = math.pow(2, bit_l % 8); print("\t\t\ttextbuf[ptr++] = (buffer["..bidx.."] & "..bmask..") ? '".. - xbutton[2].."' : '.';"); + (xbutton[4] or xbutton[2]).."' : '.';"); bit_l = bit_l + 1; end end diff --git a/src/library/controller-data.cpp b/src/library/controller-data.cpp index 413c2c0e..b534ab45 100644 --- a/src/library/controller-data.cpp +++ b/src/library/controller-data.cpp @@ -212,9 +212,19 @@ namespace static port_type_set x; return x; } + + size_t writeu32val(char32_t* buf, int val) + { + char c[12]; + size_t i; + sprintf(c, "%d", val); + for(i = 0; c[i]; i++) + buf[i] = c[i]; + return i; + } } -void controller_frame::display(unsigned port, unsigned controller, char* buf) throw() +void controller_frame::display(unsigned port, unsigned controller, char32_t* buf) throw() { if(port >= types->ports()) { //Bad port. @@ -230,6 +240,7 @@ void controller_frame::display(unsigned port, unsigned controller, char* buf) th } const port_controller* pc = ptype.controller_info->controllers[controller]; bool need_space = false; + short val; for(unsigned i = 0; i < pc->button_count; i++) { const port_controller_button* pcb = pc->buttons[i]; if(need_space && pcb->type != port_controller_button::TYPE_NULL) { @@ -240,12 +251,13 @@ void controller_frame::display(unsigned port, unsigned controller, char* buf) th case port_controller_button::TYPE_NULL: break; case port_controller_button::TYPE_BUTTON: - *(buf++) = ptype.read(backingmem, controller, i) ? pcb->symbol : '-'; + *(buf++) = ptype.read(backingmem, controller, i) ? pcb->symbol : U'-'; break; case port_controller_button::TYPE_AXIS: case port_controller_button::TYPE_RAXIS: case port_controller_button::TYPE_TAXIS: - buf += sprintf(buf, "%d", ptype.read(backingmem, controller, i)); + val = ptype.read(backingmem, controller, i); + buf += writeu32val(buf, val); need_space = true; break; } diff --git a/src/library/emustatus.cpp b/src/library/emustatus.cpp index 4ec53a47..53ec7265 100644 --- a/src/library/emustatus.cpp +++ b/src/library/emustatus.cpp @@ -11,6 +11,12 @@ emulator_status::~emulator_status() throw() void emulator_status::set(const std::string& key, const std::string& value) throw(std::bad_alloc) { umutex_class h(lock); + content[key] = to_u32string(value); +} + +void emulator_status::set(const std::string& key, const std::u32string& value) throw(std::bad_alloc) +{ + umutex_class h(lock); content[key] = value; } @@ -26,7 +32,7 @@ void emulator_status::erase(const std::string& key) throw() content.erase(key); } -std::string emulator_status::get(const std::string& key) throw(std::bad_alloc) +std::u32string emulator_status::get(const std::string& key) throw(std::bad_alloc) { umutex_class h(lock); return content[key]; @@ -42,7 +48,7 @@ emulator_status::iterator emulator_status::first() throw(std::bad_alloc) bool emulator_status::next(iterator& itr) throw(std::bad_alloc) { umutex_class h(lock); - std::map::iterator j; + std::map::iterator j; if(itr.not_valid) j = content.lower_bound(""); else @@ -50,7 +56,7 @@ bool emulator_status::next(iterator& itr) throw(std::bad_alloc) if(j == content.end()) { itr.not_valid = true; itr.key = ""; - itr.value = ""; + itr.value = U""; return false; } else { itr.not_valid = false; diff --git a/src/platform/wxwidgets/editor-movie.cpp b/src/platform/wxwidgets/editor-movie.cpp index 68d07b64..6a8d7a54 100644 --- a/src/platform/wxwidgets/editor-movie.cpp +++ b/src/platform/wxwidgets/editor-movie.cpp @@ -63,13 +63,13 @@ struct control_info unsigned reserved; //Must be at least 6 for axes. unsigned index; //Index in poll vector. int type; //-2 => Port, -1 => Fixed, 0 => Button, 1 => axis. - char ch; + char32_t ch; std::u32string title; unsigned port; unsigned controller; static control_info portinfo(unsigned& p, unsigned port, unsigned controller); static control_info fixedinfo(unsigned& p, const std::u32string& str); - static control_info buttoninfo(unsigned& p, char character, const std::u32string& title, unsigned idx); + static control_info buttoninfo(unsigned& p, char32_t character, const std::u32string& title, unsigned idx); static control_info axisinfo(unsigned& p, const std::u32string& title, unsigned idx); }; @@ -103,7 +103,7 @@ control_info control_info::fixedinfo(unsigned& p, const std::u32string& str) return i; } -control_info control_info::buttoninfo(unsigned& p, char character, const std::u32string& title, unsigned idx) +control_info control_info::buttoninfo(unsigned& p, char32_t character, const std::u32string& title, unsigned idx) { control_info i; i.position_left = p; diff --git a/src/platform/wxwidgets/mainwindow.cpp b/src/platform/wxwidgets/mainwindow.cpp index e730e372..a481a17c 100644 --- a/src/platform/wxwidgets/mainwindow.cpp +++ b/src/platform/wxwidgets/mainwindow.cpp @@ -782,45 +782,45 @@ void wxwin_mainwindow::notify_exit() throw() Destroy(); } -std::string read_variable_map(const std::map& vars, const std::string& key) +std::u32string read_variable_map(const std::map& vars, const std::string& key) { if(!vars.count(key)) - return ""; + return U""; return vars.find(key)->second; } -void wxwin_mainwindow::update_statusbar(const std::map& vars) +void wxwin_mainwindow::update_statusbar(const std::map& vars) { if(vars.empty()) return; try { - std::ostringstream s; - bool recording = (read_variable_map(vars, "!mode") == "R"); + std::basic_ostringstream s; + bool recording = (read_variable_map(vars, "!mode") == U"R"); if(recording) - s << "Frame: " << read_variable_map(vars, "!frame"); + s << U"Frame: " << read_variable_map(vars, "!frame"); else - s << "Frame: " << read_variable_map(vars, "!frame") << "/" << + s << U"Frame: " << read_variable_map(vars, "!frame") << "/" << read_variable_map(vars, "!length"); - s << " Lag: " << read_variable_map(vars, "!lag"); - s << " Subframe: " << read_variable_map(vars, "!subframe"); + s << U" Lag: " << read_variable_map(vars, "!lag"); + s << U" Subframe: " << read_variable_map(vars, "!subframe"); if(vars.count("!saveslot")) - s << " Slot: " << read_variable_map(vars, "!saveslot"); + s << U" Slot: " << read_variable_map(vars, "!saveslot"); if(vars.count("!saveslotinfo")) - s << " [" << read_variable_map(vars, "!saveslotinfo") << "]"; - s << " Speed: " << read_variable_map(vars, "!speed") << "%"; + s << U" [" << read_variable_map(vars, "!saveslotinfo") << U"]"; + s << U" Speed: " << read_variable_map(vars, "!speed") << "%"; s << " "; - if(read_variable_map(vars, "!dumping") != "") - s << " Dumping"; - if(read_variable_map(vars, "!mode") == "C") - s << " Corrupt"; - else if(read_variable_map(vars, "!mode") == "R") - s << " Recording"; - else if(read_variable_map(vars, "!mode") == "P") - s << " Playback"; - else if(read_variable_map(vars, "!mode") == "F") - s << " Finished"; + if(read_variable_map(vars, "!dumping") != U"") + s << U" Dumping"; + if(read_variable_map(vars, "!mode") == U"C") + s << U" Corrupt"; + else if(read_variable_map(vars, "!mode") == U"R") + s << U" Recording"; + else if(read_variable_map(vars, "!mode") == U"P") + s << U" Playback"; + else if(read_variable_map(vars, "!mode") == U"F") + s << U" Finished"; else - s << " Unknown"; + s << U" Unknown"; statusbar->SetStatusText(towxstring(s.str())); } catch(std::exception& e) { } diff --git a/src/platform/wxwidgets/status.cpp b/src/platform/wxwidgets/status.cpp index e02a6628..ea73cf99 100644 --- a/src/platform/wxwidgets/status.cpp +++ b/src/platform/wxwidgets/status.cpp @@ -73,7 +73,7 @@ void wxwin_status::panel::on_paint(wxPaintEvent& e) { //Quickly copy the status area. auto& s = platform::get_emustatus(); - std::map newstatus; + std::map newstatus; emulator_status::iterator i = s.first(); while(s.next(i)) newstatus[i.key] = i.value; @@ -139,7 +139,7 @@ void wxwin_status::panel::on_paint(wxPaintEvent& e) } { - std::map specials; + std::map specials; for(auto i : newstatus) if(i.first.length() > 0 && i.first[0] == '!') specials[i.first] = i.second; -- 2.11.4.GIT