Fix build on GCC 4.9
[lsnes.git] / src / platform / wxwidgets / status.cpp
blob7ed77f81136184654b067002e18f5e4d79c4671f
1 #include "core/emustatus.hpp"
2 #include "core/instance.hpp"
3 #include "core/window.hpp"
4 #include "platform/wxwidgets/platform.hpp"
5 #include "platform/wxwidgets/window_status.hpp"
6 #include "platform/wxwidgets/window_mainwindow.hpp"
7 #include "library/string.hpp"
8 #include "library/minmax.hpp"
9 #include <iostream>
11 #define STATWIDTH 40
12 #define MAXSTATUS 15
14 wxwin_status::panel::panel(wxWindow* _parent, emulator_instance& _inst, wxWindow* focuswin, unsigned lines)
15 : text_framebuffer_panel(_parent, STATWIDTH, lines ? lines : MAXSTATUS, wxID_ANY, focuswin), inst(_inst)
17 watch_flag = 0;
20 wxwin_status::wxwin_status(int flag, emulator_instance& _inst, const std::string& title)
21 : wxFrame(NULL, wxID_ANY, towxstring(title), wxDefaultPosition, wxSize(-1, -1),
22 wxMINIMIZE_BOX | wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN), inst(_inst)
24 wxBoxSizer* top_s = new wxBoxSizer(wxVERTICAL);
25 top_s->Add(spanel = new wxwin_status::panel(this, inst, NULL, MAXSTATUS), 1, wxGROW);
26 spanel->set_watch_flag(flag);
27 top_s->SetSizeHints(this);
28 SetSizer(top_s);
29 Fit();
32 wxwin_status::~wxwin_status()
36 namespace
38 void register_entry(size_t& count, size_t& width, const std::string& text)
40 width = max(width, text_framebuffer::text_width(text));
41 count++;
44 void show_entry(text_framebuffer_panel& tp, bool& sofar, size_t& line, size_t width, const std::string& name,
45 const std::u32string& text)
47 size_t n = tp.write(name, width + 1, 0, line, 0, 0xFFFFFF);
48 tp.write(text, 0, n, line++, 0, 0xFFFFFF);
49 sofar = true;
52 void draw_split(text_framebuffer_panel& tp, size_t& line)
54 auto s = tp.get_characters();
55 for(unsigned i = 0; i < s.first; i++)
56 tp.write(U"\u2500", 0, i, line, 0, 0xFFFFFF);
57 line++;
60 int num_nonzeroes() { return 0; }
61 template<typename T, typename... U> int num_nonzeroes(T hd, U... tl) {
62 return (hd ? 1 : 0) + num_nonzeroes(tl...);
64 template<typename... T> bool one_nonzero(T... args) { return (num_nonzeroes(args...) == 1); }
67 void wxwin_status::panel::prepare_paint()
69 clear();
71 auto& newstatus = inst.status->get_read();
72 try {
73 bool entry_so_far = false;
74 size_t mem_width = 0;
75 size_t oth_width = 0;
76 size_t lua_width = 0;
77 size_t mem_count = 0;
78 size_t oth_count = 0;
79 size_t lua_count = 0;
80 bool single = false;
81 for(auto& i : newstatus.mvars) register_entry(mem_count, mem_width, i.first);
82 if(newstatus.rtc_valid) register_entry(oth_count, oth_width, "RTC");
83 for(size_t j = 0; j < newstatus.inputs.size(); j++)
84 register_entry(oth_count, oth_width, (stringfmt() << "P" << (j + 1)).str());
85 for(auto& i : newstatus.lvars) register_entry(lua_count, lua_width, i.first);
87 if(watch_flag < 0) {
88 oth_count = 0;
89 lua_count = 0;
91 if(watch_flag > 0)
92 mem_count = 0;
93 single = one_nonzero(mem_count, oth_count, lua_count);
95 regex_results r;
96 size_t p = 0;
97 if(mem_count) {
98 if(entry_so_far) draw_split(*this, p);
99 if(!single) write("Memory watches:", 0, 0, p++, 0, 0xFFFFFF);
100 for(auto i : newstatus.mvars) show_entry(*this, entry_so_far, p, mem_width, i.first,
101 i.second);
104 if(oth_count) {
105 if(entry_so_far) draw_split(*this, p);
106 if(!single) write("Status:", 0, 0, p++, 0, 0xFFFFFF);
107 if(newstatus.rtc_valid) show_entry(*this, entry_so_far, p, oth_width, "RTC", newstatus.rtc);
108 for(size_t j = 0; j < newstatus.inputs.size(); j++)
109 show_entry(*this, entry_so_far, p, oth_width, (stringfmt() << "P" << (j + 1)).str(),
110 newstatus.inputs[j]);
113 if(lua_count) {
114 if(entry_so_far) draw_split(*this, p);
115 if(!single) write("From Lua:", 0, 0, p++, 0, 0xFFFFFF);
116 for(auto i : newstatus.lvars) show_entry(*this, entry_so_far, p, lua_width, i.first,
117 i.second);
119 } catch(...) {
121 inst.status->put_read();
124 void wxwin_status::notify_update() throw()
126 spanel->request_paint();
129 bool wxwin_status::ShouldPreventAppExit() const
131 return false;