diff --git a/generic/messagebuffer.cpp b/generic/messagebuffer.cpp new file mode 100644 index 00000000..7885b310 --- /dev/null +++ b/generic/messagebuffer.cpp @@ -0,0 +1,213 @@ +#include "messagebuffer.hpp" + +messagebuffer::update_handler::~update_handler() throw() +{ +} + +messagebuffer::messagebuffer(size_t maxmessages, size_t windowsize) throw(std::bad_alloc, std::logic_error) +{ + if(windowsize > maxmessages) + throw std::logic_error("Invalid window size"); + if(maxmessages == 0) + throw std::logic_error("Invalid max message count"); + first_present_message = 0; + next_message_number = 0; + window_start = 0; + max_messages = maxmessages; + window_size = windowsize; + scroll_frozen = false; + updates_frozen = false; + window_start_at_freeze = 0; + window_size_at_freeze = 0; + next_message_number_at_freeze = 0; +} + +void messagebuffer::add_message(const std::string& msg) throw(std::bad_alloc, std::runtime_error) +{ + messages[next_message_number++] = msg; + //If too many messages, erase one. + if(messages.size() > max_messages) + messages.erase(first_present_message++); + //Force scrolling if message in window got erased. + if(window_start < first_present_message) { + window_start = first_present_message; + send_notifications(); + } + //Autoscrolling at the end. + if(!scroll_frozen && window_start + window_size + 1 == next_message_number) { + window_start++; + send_notifications(); + } +} + +const std::string& messagebuffer::get_message(size_t msgnum) throw(std::bad_alloc, std::logic_error) +{ + if(!messages.count(msgnum)) + throw std::logic_error("Invalid message number"); + return messages[msgnum]; +} + +size_t messagebuffer::get_msg_first() throw() +{ + return first_present_message; +} + +size_t messagebuffer::get_msg_count() throw() +{ + return next_message_number - first_present_message; +} + +size_t messagebuffer::get_visible_first() throw() +{ + return window_start; +} + +size_t messagebuffer::get_visible_count() throw() +{ + if(window_start + window_size > next_message_number) + return next_message_number - window_start; + else + return window_size; +} + +bool messagebuffer::is_more_messages() throw() +{ + return (window_start + window_size < next_message_number); +} + +void messagebuffer::freeze_scrolling() throw() +{ + scroll_frozen = true; +} + +void messagebuffer::unfreeze_scrolling() throw() +{ + scroll_frozen = false; +} + +void messagebuffer::freeze_updates() throw() +{ + updates_frozen = true; + window_size_at_freeze = window_size; + window_start_at_freeze = window_start; + next_message_number_at_freeze = next_message_number; +} + +bool messagebuffer::unfreeze_updates() throw() +{ + updates_frozen = false; + if(window_start_at_freeze < first_present_message) + return true; + uint64_t messages_visible_at_freeze; + uint64_t messages_visible_now; + if(window_start_at_freeze + window_size_at_freeze >= next_message_number_at_freeze) + messages_visible_at_freeze = next_message_number_at_freeze - window_start_at_freeze; + else + messages_visible_at_freeze = window_size_at_freeze; + messages_visible_now = get_visible_count(); + if(messages_visible_now != messages_visible_at_freeze) + return true; + if(window_start_at_freeze != window_start) + return true; + return false; +} + +void messagebuffer::scroll_beginning() throw(std::bad_alloc, std::runtime_error) +{ + if(window_start == first_present_message) + return; + window_start = first_present_message; + send_notifications(); +} + +void messagebuffer::scroll_up_page() throw(std::bad_alloc, std::runtime_error) +{ + if(window_start == first_present_message) + return; + if(window_start < first_present_message + window_size) + window_start = first_present_message; + else + window_start -= window_size; + send_notifications(); +} + +void messagebuffer::scroll_up_line() throw(std::bad_alloc, std::runtime_error) +{ + if(window_start == first_present_message) + return; + window_start--; + send_notifications(); +} + +void messagebuffer::scroll_down_line() throw(std::bad_alloc, std::runtime_error) +{ + if(window_start + window_size >= next_message_number) + return; + window_start++; + send_notifications(); +} + +void messagebuffer::scroll_down_page() throw(std::bad_alloc, std::runtime_error) +{ + if(window_start + window_size >= next_message_number) + return; + window_start += window_size; + if(window_start + window_size >= next_message_number) + window_start = next_message_number - window_size; + send_notifications(); +} + +void messagebuffer::scroll_end() throw(std::bad_alloc, std::runtime_error) +{ + if(first_present_message + window_size > next_message_number) + return; + window_start = next_message_number - window_size; + send_notifications(); +} + +void messagebuffer::register_handler(messagebuffer::update_handler& handler) throw(std::bad_alloc) +{ + handlers.insert(&handler); +} + +void messagebuffer::unregister_handler(messagebuffer::update_handler& handler) throw() +{ + handlers.erase(&handler); +} + +void messagebuffer::set_max_window_size(size_t windowsize) throw(std::bad_alloc, std::logic_error) +{ + if(windowsize > max_messages) + throw std::logic_error("Invalid window size"); + if(window_size > windowsize) { + //Shrink window. + size_t shrinkage = window_size - windowsize; + bool autoscrolling = !scroll_frozen && (window_start + window_size >= next_message_number); + if(autoscrolling && window_start + windowsize < next_message_number) + window_start = next_message_number - windowsize; + window_size = windowsize; + send_notifications(); + } else if(window_size < windowsize) { + //Enlarge window. + size_t enlargement = windowsize - window_size; + if(first_present_message + windowsize >= next_message_number) + window_start = first_present_message; + else if(window_start + windowsize >= next_message_number) + window_start = next_message_number - windowsize; + window_size = windowsize; + send_notifications(); + } +} + +size_t messagebuffer::get_max_window_size() throw() +{ + return window_size; +} + +void messagebuffer::send_notifications() +{ + if(updates_frozen) + return; + for(auto i : handlers) + i->messagebuffer_update(); +} diff --git a/generic/messagebuffer.hpp b/generic/messagebuffer.hpp new file mode 100644 index 00000000..527cf473 --- /dev/null +++ b/generic/messagebuffer.hpp @@ -0,0 +1,207 @@ +#ifndef _messagebuffer__hpp__included__ +#define _messagebuffer__hpp__included__ + +#include +#include +#include +#include +#include + +class messagebuffer +{ +public: +/** + * Update handler. + */ + class update_handler + { + public: +/** + * Destructor. + */ + virtual ~update_handler() throw(); +/** + * Handle update. + */ + virtual void messagebuffer_update() throw(std::bad_alloc, std::runtime_error) = 0; + }; +/** + * Create new message buffer with specified maximum message count. + * + * Parameter maxmessages: The maximum number of messages. + * Parameter windowsize: The initial window size. + * Throws std::bad_alloc: Not enough memory. + * Throws std::logic_error: Windowsize is greater than maxmessages or maxmessages is zero. + */ + messagebuffer(size_t maxmessages, size_t windowsize) throw(std::bad_alloc, std::logic_error); + +/** + * Add a new message to the buffer. + * + * Parameter msg: The new message to add. + * Throws std::bad_alloc: Not enough memory. + * Throws std::runtime_error: Thrown through from update handler. + */ + void add_message(const std::string& msg) throw(std::bad_alloc, std::runtime_error); + +/** + * Read a message. + * + * Parameter msgnum: Number of message to read. + * Returns: The read message. + * Throws std::bad_alloc: Not enough memory. + * Throws std::logic_error: Invalid message number. + */ + const std::string& get_message(size_t msgnum) throw(std::bad_alloc, std::logic_error); + +/** + * Get the number of first message present. + * + * Returns: The number of first message present. + */ + size_t get_msg_first() throw(); + +/** + * Get the number of messages present. + * + * Returns: The number of messages present. + */ + size_t get_msg_count() throw(); + +/** + * Get the number of first message visible. + * + * Returns: The number of first message visible. + */ + size_t get_visible_first() throw(); + +/** + * Get the number of messages visible. + * + * Returns: The number of messages visible. + */ + size_t get_visible_count() throw(); + +/** + * Is there more messages after the current window? + * + * Returns: True if there is, false if not. + */ + bool is_more_messages() throw(); + +/** + * Freeze scrolling + */ + void freeze_scrolling() throw(); + +/** + * Unfreeze scrolling + */ + void unfreeze_scrolling() throw(); + +/** + * Freeze updates + */ + void freeze_updates() throw(); + +/** + * Unfreeze updates + * + * Returns: True if update is needed. + */ + bool unfreeze_updates() throw(); + +/** + * Scroll to beginning. + * + * Throws std::bad_alloc: Not enough memory. + * Throws std::runtime_error: Thrown through from update handler. + */ + void scroll_beginning() throw(std::bad_alloc, std::runtime_error); + +/** + * Scroll up one page. + * + * Throws std::bad_alloc: Not enough memory. + * Throws std::runtime_error: Thrown through from update handler. + */ + void scroll_up_page() throw(std::bad_alloc, std::runtime_error); + +/** + * Scroll up one line. + * + * Throws std::bad_alloc: Not enough memory. + * Throws std::runtime_error: Thrown through from update handler. + */ + void scroll_up_line() throw(std::bad_alloc, std::runtime_error); + +/** + * Scroll down one line. + * + * Throws std::bad_alloc: Not enough memory. + * Throws std::runtime_error: Thrown through from update handler. + */ + void scroll_down_line() throw(std::bad_alloc, std::runtime_error); + +/** + * Scroll down one page. + * + * Throws std::bad_alloc: Not enough memory. + * Throws std::runtime_error: Thrown through from update handler. + */ + void scroll_down_page() throw(std::bad_alloc, std::runtime_error); + +/** + * Scroll to beginning. + * + * Throws std::bad_alloc: Not enough memory. + * Throws std::runtime_error: Thrown through from update handler. + */ + void scroll_end() throw(std::bad_alloc, std::runtime_error); + +/** + * Register an update handler. + * + * Parameter handler: The new handler. + * Throws std::bad_alloc: Not enough memory. + */ + void register_handler(update_handler& handler) throw(std::bad_alloc); + +/** + * Unregister an update handler. + * + * Parameter handler: The handler to remove. + * Throws std::bad_alloc: Not enough memory. + */ + void unregister_handler(update_handler& handler) throw(); + +/** + * Change the window size. + * + * Parameter windowsize: The new window size. + * Throws std::bad_alloc: Not enough memory. + * Throws std::logic_error: Windowsize is greater than maxmessages or maxmessages is zero. + */ + void set_max_window_size(size_t windowsize) throw(std::bad_alloc, std::logic_error); + +/** + * Read the window size. + */ + size_t get_max_window_size() throw(); +private: + void send_notifications(); + std::map messages; + uint64_t first_present_message; + uint64_t next_message_number; + uint64_t window_start; + size_t max_messages; + size_t window_size; + bool scroll_frozen; + bool updates_frozen; + uint64_t window_start_at_freeze; + uint64_t window_size_at_freeze; + uint64_t next_message_number_at_freeze; + std::set handlers; +}; + +#endif diff --git a/generic/window.cpp b/generic/window.cpp index c99f2993..7de94485 100644 --- a/generic/window.cpp +++ b/generic/window.cpp @@ -1,5 +1,7 @@ #include "window.hpp" #include "command.hpp" +#include "misc.hpp" +#include #include #include #include @@ -9,6 +11,10 @@ #include #include +#define MAXMESSAGES 5000 +#define INIT_WIN_SIZE 6 + + namespace { function_ptr_command<> identify_key("show-plugins", "Show plugins in use", @@ -117,6 +123,17 @@ namespace std::vector stream; }; + class msgcallback : public messagebuffer::update_handler + { + public: + ~msgcallback() throw() {}; + void messagebuffer_update() throw(std::bad_alloc, std::runtime_error) + { + window::notify_message(); + } + } msg_callback_obj; + + std::ofstream system_log; window_callback* wcb = NULL; uint32_t vc_xoffset; uint32_t vc_yoffset; @@ -131,6 +148,15 @@ std::map& window::get_emustatus() throw() void window::init() { + msgbuf.register_handler(msg_callback_obj); + system_log.open("lsnes.log", std::ios_base::out | std::ios_base::app); + time_t curtime = __real_time(NULL); + struct tm* tm = localtime(&curtime); + char buffer[1024]; + strftime(buffer, 1023, "%Y-%m-%d %H:%M:%S %Z", tm); + system_log << "-----------------------------------------------------------------------" << std::endl; + system_log << "lsnes started at " << buffer << std::endl; + system_log << "-----------------------------------------------------------------------" << std::endl; graphics_init(); sound_init(); joystick_init(); @@ -141,6 +167,15 @@ void window::quit() joystick_quit(); sound_quit(); graphics_quit(); + msgbuf.unregister_handler(msg_callback_obj); + time_t curtime = __real_time(NULL); + struct tm* tm = localtime(&curtime); + char buffer[1024]; + strftime(buffer, 1023, "%Y-%m-%d %H:%M:%S %Z", tm); + system_log << "-----------------------------------------------------------------------" << std::endl; + system_log << "lsnes shutting down at " << buffer << std::endl; + system_log << "-----------------------------------------------------------------------" << std::endl; + system_log.close(); } std::ostream& window::out() throw(std::bad_alloc) @@ -160,6 +195,43 @@ void window::set_window_compensation(uint32_t xoffset, uint32_t yoffset, uint32_ vc_vscl = vscl; } +messagebuffer window::msgbuf(MAXMESSAGES, INIT_WIN_SIZE); + + +void window::message(const std::string& msg) throw(std::bad_alloc) +{ + std::string msg2 = msg; + while(msg2 != "") { + size_t s = msg2.find_first_of("\n"); + std::string forlog; + if(s >= msg2.length()) { + msgbuf.add_message(forlog = msg2); + if(system_log) + system_log << forlog << std::endl; + break; + } else { + msgbuf.add_message(forlog = msg2.substr(0, s)); + if(system_log) + system_log << forlog << std::endl; + msg2 = msg2.substr(s + 1); + } + } +} + +void window::fatal_error() throw() +{ + time_t curtime = __real_time(NULL); + struct tm* tm = localtime(&curtime); + char buffer[1024]; + strftime(buffer, 1023, "%Y-%m-%d %H:%M:%S %Z", tm); + system_log << "-----------------------------------------------------------------------" << std::endl; + system_log << "lsnes paniced at " << buffer << std::endl; + system_log << "-----------------------------------------------------------------------" << std::endl; + system_log.close(); + fatal_error2(); + exit(1); +} + window_callback::~window_callback() throw() { } diff --git a/generic/window.hpp b/generic/window.hpp index c9e0703b..74305e77 100644 --- a/generic/window.hpp +++ b/generic/window.hpp @@ -2,6 +2,7 @@ #define _window__hpp__included__ #include "render.hpp" +#include "messagebuffer.hpp" #include #include #include @@ -113,17 +114,38 @@ public: */ static void set_window_compensation(uint32_t xoffset, uint32_t yoffset, uint32_t hscl, uint32_t vscl); -/******************************** GRAPHICS PLUGIN **********************************/ +/** + * Message buffer. + * + * Implemented by the generic window code. + */ + static messagebuffer msgbuf; + /** * Adds a messages to mesage queue to be shown. * - * Needs to be implemented by the graphics plugin. + * Implemented by the generic window code. * * parameter msg: The messages to add (split by '\n'). * throws std::bad_alloc: Not enough memory. */ static void message(const std::string& msg) throw(std::bad_alloc); +/** + * Displays fatal error message, quitting after the user acks it (called by fatal_error()). + * + * Needs to be implemented by the graphics plugin. + */ + static void fatal_error() throw(); + +/******************************** GRAPHICS PLUGIN **********************************/ +/** + * Notification when messages get updated. + * + * Needs to be implemented by the graphics plugin. + */ + static void notify_message() throw(std::bad_alloc, std::runtime_error); + /** * Displays a modal message, not returning until the message is acknowledged. Keybindings are not available, but * should quit be generated somehow, modal message will be closed and command callback triggered. @@ -138,11 +160,11 @@ public: static bool modal_message(const std::string& msg, bool confirm = false) throw(std::bad_alloc); /** - * Displays fatal error message, quitting after the user acks it. + * Displays fatal error message, quitting after the user acks it (called by fatal_error()). * * Needs to be implemented by the graphics plugin. */ - static void fatal_error() throw(); + static void fatal_error2() throw(); /** * Processes inputs. If in non-modal mode (normal mode without pause), this returns quickly. Otherwise it waits @@ -268,6 +290,7 @@ private: window& operator==(const window&); }; + /** * Names of plugins. */ diff --git a/platform/SDL/window-sdl.cpp b/platform/SDL/window-sdl.cpp index fd7d94fb..fd8a01b7 100644 --- a/platform/SDL/window-sdl.cpp +++ b/platform/SDL/window-sdl.cpp @@ -14,10 +14,9 @@ #include #include -#define WATCHDOG_TIMEOUT 15 -#define MAXMESSAGES 6 -#define MSGHISTORY 1000 #define MAXHISTORY 1000 +#define MAXMESSAGES 6 +#define WATCHDOG_TIMEOUT 15 #include #include @@ -471,12 +470,7 @@ namespace unsigned old_screen_w; unsigned old_screen_h; unsigned state; - std::map messagebuffer; - uint64_t messagebuffer_next_seq; - uint64_t messagebuffer_first_seq; - uint64_t messagebuffer_first_show; bool console_mode; - uint32_t maxmessages; std::list commandhistory; std::list::iterator commandhistory_itr; screen* current_screen; @@ -986,14 +980,6 @@ void graphics_init() alarm(WATCHDOG_TIMEOUT); #endif init_keys(); - system_log.open("lsnes.log", std::ios_base::out | std::ios_base::app); - time_t curtime = __real_time(NULL); - struct tm* tm = localtime(&curtime); - char buffer[1024]; - strftime(buffer, 1023, "%Y-%m-%d %H:%M:%S %Z", tm); - system_log << "-----------------------------------------------------------------------" << std::endl; - system_log << "lsnes started at " << buffer << std::endl; - system_log << "-----------------------------------------------------------------------" << std::endl; if(!sdl_init) { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_TIMER); SDL_EnableUNICODE(true); @@ -1009,11 +995,7 @@ void graphics_init() old_screen_w = 0; modal_return_flag = false; delayed_close_flag = false; - messagebuffer_next_seq = 0; - messagebuffer_first_seq = 0; - messagebuffer_first_show = 0; console_mode = false; - maxmessages = MAXMESSAGES; window::notify_screen_update(); std::string windowname = "lsnes-" + lsnes_version + "[" + bsnes_core_version + "]"; @@ -1024,14 +1006,6 @@ void graphics_init() void graphics_quit() { - time_t curtime = time(NULL); - struct tm* tm = localtime(&curtime); - char buffer[1024]; - strftime(buffer, 1023, "%Y-%m-%d %H:%M:%S %Z", tm); - system_log << "-----------------------------------------------------------------------" << std::endl; - system_log << "lsnes shutting down at " << buffer << std::endl; - system_log << "-----------------------------------------------------------------------" << std::endl; - system_log.close(); if(sdl_init) { SDL_RemoveTimer(tid); SDL_Quit(); @@ -1055,38 +1029,8 @@ bool window::modal_message(const std::string& msg, bool confirm) throw(std::bad_ return ret; } -void window::message(const std::string& msg) throw(std::bad_alloc) +void window::notify_message() throw(std::bad_alloc, std::runtime_error) { - std::string msg2 = msg; - bool locked_mode = (messagebuffer_next_seq - messagebuffer_first_show <= maxmessages) ; - while(msg2 != "") { - size_t s = msg2.find_first_of("\n"); - std::string forlog; - if(s >= msg2.length()) { - if(SDL_initialized) { - messagebuffer[messagebuffer_next_seq++] = (forlog = msg2); - system_log << forlog << std::endl; - } else - std::cerr << msg2 << std::endl; - break; - } else { - if(SDL_initialized) { - messagebuffer[messagebuffer_next_seq++] = (forlog = msg2.substr(0, s)); - system_log << forlog << std::endl; - } else - std::cerr << msg2.substr(0, s) << std::endl; - msg2 = msg2.substr(s + 1); - } - - } - if(locked_mode && messagebuffer_first_show + maxmessages < messagebuffer_next_seq) - messagebuffer_first_show = messagebuffer_next_seq - maxmessages; - - while(messagebuffer.size() > MSGHISTORY) { - messagebuffer.erase(messagebuffer_first_seq++); - if(messagebuffer_first_show < messagebuffer_first_seq) - messagebuffer_first_show = messagebuffer_first_seq; - } notify_screen_update(); } @@ -1219,17 +1163,19 @@ namespace message_y = screensize.second + 16; else message_y = 6; + size_t maxmessages = window::msgbuf.get_max_window_size(); + size_t msgnum = window::msgbuf.get_visible_first(); + size_t visible = window::msgbuf.get_visible_count(); for(size_t j = 0; j < maxmessages; j++) try { std::ostringstream o; - if(messagebuffer_first_show + j < messagebuffer_next_seq) - o << (messagebuffer_first_show + j + 1) << ": " - << messagebuffer[messagebuffer_first_show + j]; + if(j < visible) + o << (msgnum + j + 1) << ": " << window::msgbuf.get_message(msgnum + j); draw_string(reinterpret_cast(swsurf->pixels), swsurf->pitch, o.str(), 6, message_y + 16 * j, windowsize.first - 12); } catch(...) { } - if(messagebuffer_next_seq - messagebuffer_first_show > maxmessages) + if(window::msgbuf.is_more_messages()) try { draw_string(reinterpret_cast(swsurf->pixels), swsurf->pitch, "--More--", windowsize.first - 76, message_y + 16 * maxmessages - 16, 64); @@ -1357,41 +1303,25 @@ namespace function_ptr_command<> scroll_up("scroll-up", "Scroll messages a page up", "Syntax: scroll-up\nScrolls message console backward one page.\n", []() throw(std::bad_alloc, std::runtime_error) { - if(messagebuffer_first_show > maxmessages) - messagebuffer_first_show -= maxmessages; - else - messagebuffer_first_show = 0; - if(messagebuffer_first_show < messagebuffer_first_seq) - messagebuffer_first_show = messagebuffer_first_seq; - window::notify_screen_update(); + window::msgbuf.scroll_up_page(); }); function_ptr_command<> scroll_fullup("scroll-fullup", "Scroll messages to beginning", "Syntax: scroll-fullup\nScrolls message console to its beginning.\n", []() throw(std::bad_alloc, std::runtime_error) { - messagebuffer_first_show = messagebuffer_first_seq; - window::notify_screen_update(); + window::msgbuf.scroll_beginning(); }); function_ptr_command<> scroll_fulldown("scroll-fulldown", "Scroll messages to end", "Syntax: scroll-fulldown\nScrolls message console to its end.\n", []() throw(std::bad_alloc, std::runtime_error) { - if(messagebuffer_next_seq < maxmessages) - messagebuffer_first_show = 0; - else - messagebuffer_first_show = messagebuffer_next_seq - maxmessages; - window::notify_screen_update(); + window::msgbuf.scroll_end(); }); function_ptr_command<> scrolldown("scroll-down", "Scroll messages a page down", "Syntax: scroll-up\nScrolls message console forward one page.\n", []() throw(std::bad_alloc, std::runtime_error) { - messagebuffer_first_show += maxmessages; - if(messagebuffer_next_seq < maxmessages) - messagebuffer_first_show = 0; - else if(messagebuffer_next_seq < messagebuffer_first_show + maxmessages) - messagebuffer_first_show = messagebuffer_next_seq - maxmessages; - window::notify_screen_update(); + window::msgbuf.scroll_down_page(); }); function_ptr_command<> toggle_console("toggle-console", "Toggle console between small and full window", @@ -1399,13 +1329,9 @@ namespace []() throw(std::bad_alloc, std::runtime_error) { console_mode = !console_mode; if(console_mode) - maxmessages = hwsurf ? (hwsurf->h - 38) / 16 : 36; + window::msgbuf.set_max_window_size(hwsurf ? (hwsurf->h - 38) / 16 : 36); else - maxmessages = MAXMESSAGES; - if(messagebuffer_next_seq < maxmessages) - messagebuffer_first_show = 0; - else - messagebuffer_first_show = messagebuffer_next_seq - maxmessages; + window::msgbuf.set_max_window_size(MAXMESSAGES); window::notify_screen_update(true); }); } @@ -1430,7 +1356,7 @@ void window::wait_usec(uint64_t usec) throw(std::bad_alloc) wait_canceled = false; } -void window::fatal_error() throw() +void window::fatal_error2() throw() { try { message("PANIC: Cannot continue, press ESC or close window to exit."); @@ -1440,14 +1366,6 @@ void window::fatal_error() throw() //Just crash. exit(1); } - time_t curtime = time(NULL); - struct tm* tm = localtime(&curtime); - char buffer[1024]; - strftime(buffer, 1023, "%Y-%m-%d %H:%M:%S %Z", tm); - system_log << "-----------------------------------------------------------------------" << std::endl; - system_log << "lsnes paniced at " << buffer << std::endl; - system_log << "-----------------------------------------------------------------------" << std::endl; - system_log.close(); while(true) { SDL_Event e; if(SDL_WaitEvent(&e)) { diff --git a/platform/dummy/window-dummy.cpp b/platform/dummy/window-dummy.cpp index a4125750..82f79221 100644 --- a/platform/dummy/window-dummy.cpp +++ b/platform/dummy/window-dummy.cpp @@ -2,6 +2,11 @@ #include #include +namespace +{ + uint64_t next_message_to_print = 0; +} + void graphics_init() {} void graphics_quit() {} void window::poll_inputs() throw(std::bad_alloc) {} @@ -17,18 +22,20 @@ bool window::modal_message(const std::string& msg, bool confirm) throw(std::bad_ return confirm; } -void window::fatal_error() throw() +void window::fatal_error2() throw() { std::cerr << "Exiting on fatal error." << std::endl; exit(1); } -void window::message(const std::string& msg) throw(std::bad_alloc) +void window::notify_message() throw(std::bad_alloc, std::runtime_error) { - if(msg[msg.length() - 1] == '\n') - std::cout << msg; - else - std::cout << msg << std::endl; + while(msgbuf.get_msg_first() + msgbuf.get_msg_count() > next_message_to_print) { + if(msgbuf.get_msg_first() > next_message_to_print) + next_message_to_print = msgbuf.get_msg_first(); + else + std::cout << msgbuf.get_message(next_message_to_print++) << std::endl; + } } const char* graphics_plugin_name = "Dummy graphics plugin";