lsnes/include/core/window.hpp

479 lines
10 KiB
C++
Raw Normal View History

#ifndef _window__hpp__included__
#define _window__hpp__included__
2012-01-06 17:28:01 +02:00
#include "core/keymapper.hpp"
2012-10-13 15:55:00 +03:00
#include "library/messagebuffer.hpp"
2012-10-13 16:03:29 +03:00
#include "library/emustatus.hpp"
2012-06-20 17:40:27 +03:00
#include "library/framebuffer.hpp"
#include <string>
#include <map>
#include <list>
#include <stdexcept>
2012-01-06 17:28:01 +02:00
class emulator_status;
2012-01-06 17:28:01 +02:00
/**
* Mutex.
*/
struct mutex
{
/**
* Hold mutex RAII-style.
*/
struct holder
{
holder(mutex& m) throw();
~holder() throw();
private:
mutex& mut;
};
/**
* Create a mutex. The returned mutex can be deleted using delete.
*/
static mutex& aquire() throw(std::bad_alloc);
/**
* Create a recursive mutex. The returned mutex can be deleted using delete.
*/
static mutex& aquire_rec() throw(std::bad_alloc);
2012-01-06 17:28:01 +02:00
/**
* Destroy a mutex.
*/
virtual ~mutex() throw();
/**
* Lock a mutex.
*/
virtual void lock() throw() = 0;
/**
* Lock a mutex.
*/
virtual void unlock() throw() = 0;
protected:
mutex() throw();
};
/**
* Condition variable.
*/
struct condition
{
/**
* Create a condition variable. The returned condition can be freed using delete.
*/
static condition& aquire(mutex& m) throw(std::bad_alloc);
/**
* Destroy a condition.
*/
virtual ~condition() throw();
/**
* Return associated mutex.
*/
mutex& associated() throw();
/**
* Wait for condition. The associate mutex must be locked.
*/
virtual bool wait(uint64_t max_usec) throw() = 0;
/**
* Signal a condition. The associated mutex should be locked.
*/
virtual void signal() throw() = 0;
protected:
condition(mutex& m);
mutex& assoc;
};
/**
* Thread ID.
*/
struct thread_id
{
/**
* Return thread id for this thread. Can be freed with delete.
*/
static thread_id& me() throw(std::bad_alloc);
/**
* Destructor.
*/
virtual ~thread_id() throw();
/**
* Is this thread me?
*/
virtual bool is_me() throw() = 0;
protected:
thread_id() throw();
};
/**
* Thread.
*/
struct thread
{
/**
* Create a thread, jumping to specified starting point.
*/
static thread& create(void* (*entrypoint)(void* arg), void* arg) throw(std::bad_alloc, std::runtime_error);
/**
* Destroy a thread, first joining it (if not already joined).
*/
virtual ~thread() throw();
/**
* Is this thread still alive?
*/
bool is_alive() throw();
/**
* Join a thread.
*/
void* join() throw();
protected:
thread() throw();
/**
* Notify that this thread has quit.
*/
void notify_quit(void* retval) throw();
/**
* Join a thread.
*/
virtual void _join() throw() = 0;
private:
bool alive;
bool joined;
void* returns;
};
/**
* Information about keypress.
*/
struct keypress
{
/**
* Create null keypress (no modifiers, NULL key and released).
*/
keypress();
/**
* Create new keypress.
*/
keypress(keyboard_modifier_set mod, keygroup& _key, short _value);
2012-01-06 17:28:01 +02:00
/**
* Create new keypress (two keys).
*/
keypress(keyboard_modifier_set mod, keygroup& _key, keygroup& _key2, short _value);
2012-01-06 17:28:01 +02:00
/**
* Modifier set.
*/
keyboard_modifier_set modifiers;
2012-01-06 17:28:01 +02:00
/**
* The actual key (first)
*/
keygroup* key1;
/**
* The actual key (second)
*/
keygroup* key2;
/**
* Value for the press
*/
short value;
};
/**
2012-01-06 17:28:01 +02:00
* Functions implemented by the graphics plugin.
*
* Unless explicitly noted otherwise, all the methods are to be called from emulation thread if that exists, otherwise
* from the main thread.
*/
struct graphics_plugin
{
/**
* Graphics initialization function.
2011-10-31 21:05:54 +02:00
*
2012-01-06 17:28:01 +02:00
* - The first initialization function to be called by platform::init().
*/
static void init() throw();
/**
* Graphics quit function.
*
* - The last quit function to be called by platform::quit().
*/
static void quit() throw();
/**
* Notification when messages get updated.
*/
static void notify_message() throw();
/**
* Notification when status gets updated.
*/
2012-01-06 17:28:01 +02:00
static void notify_status() throw();
/**
* Notification when main screen gets updated.
*/
static void notify_screen() throw();
/**
* Show modal message dialog.
*
* Parameter text: The text for dialog.
* Parameter confirm: If true, display confirmation dialog, if false, display notification dialog.
* Returns: True if confirmation dialog was confirmed, otherwise false.
*/
static bool modal_message(const std::string& text, bool confirm = false) throw();
/**
* Displays fatal error message.
*
* - After this routine returns, the program will quit.
* - The call can occur in any thread.
*/
static void fatal_error() throw();
/**
* Identification for graphics plugin.
*/
static const char* name;
};
/**
2012-09-23 19:16:30 +03:00
* Functions implemented by the joystick plugin.
2012-01-06 17:28:01 +02:00
*
* Unless explicitly noted otherwise, all the methods are to be called from emulation thread if that exists, otherwise
* from the main thread.
*/
struct joystick_plugin
{
/**
* Joystick initialization function.
2011-10-31 21:05:54 +02:00
*
2012-01-06 17:28:01 +02:00
* - The third initialization function to be called by window_init().
* - The call occurs in the main thread.
* - Implemented by the joystick plugin.
*/
static void init() throw();
/**
* Joystick quit function.
*
* - The third last quit function to be called by window_quit().
* - The call occurs in the main thread.
* - Implemented by the joystick plugin.
*/
static void quit() throw();
/**
* This thread becomes the joystick polling thread.
*
* - Called in joystick polling thread.
*/
static void thread_fn() throw();
/**
* Signal the joystick thread to quit.
*/
static void signal() throw();
/**
* Identification for joystick plugin.
*/
static const char* name;
};
/**
* Platform-specific-related functions.
*/
struct platform
{
/**
* Initialize the system.
2011-09-15 15:12:26 +03:00
*/
static void init();
2011-09-15 15:12:26 +03:00
/**
2012-01-06 17:28:01 +02:00
* Shut down the system.
2011-09-15 15:12:26 +03:00
*/
static void quit();
/**
2011-10-31 21:05:54 +02:00
* Get output stream printing into message queue.
2011-09-15 22:56:33 +03:00
*
2011-10-31 21:05:54 +02:00
* Note that lines printed there should be terminated by '\n'.
*
* Implemented by the generic window code.
*
* returns: The output stream.
2011-09-15 15:12:26 +03:00
* throws std::bad_alloc: Not enough memory.
*/
2011-10-31 21:05:54 +02:00
static std::ostream& out() throw(std::bad_alloc);
/**
2011-10-31 21:05:54 +02:00
* Get emulator status area
2011-09-15 22:56:33 +03:00
*
2011-10-31 21:05:54 +02:00
* returns: Emulator status area.
*/
2012-01-06 17:28:01 +02:00
static emulator_status& get_emustatus() throw();
/**
* Message buffer.
*/
static messagebuffer msgbuf;
2012-01-06 17:28:01 +02:00
/**
* Get message buffer lock.
*/
static mutex& msgbuf_lock() throw();
/**
* Set palette used on screen.
*/
static void screen_set_palette(unsigned rshift, unsigned gshift, unsigned bshift) throw();
2011-10-31 21:05:54 +02:00
/**
* Adds a messages to mesage queue to be shown.
2011-09-15 22:56:33 +03:00
*
* Implemented by the generic window code.
2011-10-31 21:05:54 +02:00
*
* parameter msg: The messages to add (split by '\n').
2011-09-15 15:12:26 +03:00
* throws std::bad_alloc: Not enough memory.
*/
2011-10-31 21:05:54 +02:00
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();
/**
* Enable or disable sound.
*
* Implemented by the generic window code.
*
* parameter enable: Enable sounds if true, otherwise disable sounds.
*/
static void sound_enable(bool enable) throw();
/**
* Are sounds enabled?
*/
static bool is_sound_enabled() throw();
/**
* Set sound device.
*/
static void set_sound_device(const std::string& dev) throw();
/**
2012-01-06 17:28:01 +02:00
* Show modal message dialog.
2011-10-31 21:05:54 +02:00
*
2012-01-06 17:28:01 +02:00
* Parameter text: The text for dialog.
* Parameter confirm: If true, display confirmation dialog, if false, display notification dialog.
* Returns: True, if confirmation dialog was confirmed, otherwise false.
*/
2012-01-06 17:28:01 +02:00
static bool modal_message(const std::string& text, bool confirm = false) throw()
{
return graphics_plugin::modal_message(text, confirm);
}
/**
2012-01-06 17:28:01 +02:00
* Process command and keypress queues.
2011-11-03 17:57:46 +02:00
*
2012-01-06 17:28:01 +02:00
* - If emulating normally, this routine returns fast.
* - If emulator is in pause mode, this routine will block until emulator has left pause mode.
* - If emulator is in some special mode, this routine can block until said mode is left.
*/
2012-01-06 17:28:01 +02:00
static void flush_command_queue() throw();
/**
2011-09-15 15:12:26 +03:00
* Enable/Disable pause mode.
2011-09-15 22:56:33 +03:00
*
2012-01-06 17:28:01 +02:00
* - This function doesn't actually block. For actual paused blocking, use flush_command_queue().
2011-10-31 21:05:54 +02:00
*
2012-01-06 17:28:01 +02:00
* Parameter enable: Enable pause mode if true, disable pause mode if false.
*/
2012-01-06 17:28:01 +02:00
static void set_paused(bool enable) throw();
/**
2012-01-06 17:28:01 +02:00
* Wait specified number of milliseconds before returning.
2011-09-15 22:56:33 +03:00
*
2012-01-06 17:28:01 +02:00
* - The command and keypresses queues are processed while waiting.
2011-11-03 17:57:46 +02:00
*
2012-01-06 17:28:01 +02:00
* Parameter usec: The number of microseconds to wait.
*/
2012-01-06 17:28:01 +02:00
static void wait(uint64_t usec) throw();
/**
2012-01-06 17:28:01 +02:00
* Cause call to wait() to return immediately.
2011-09-15 15:12:26 +03:00
*/
static void cancel_wait() throw();
2011-09-15 15:12:26 +03:00
/**
2012-01-06 17:28:01 +02:00
* Notify received message.
*/
2012-01-06 17:28:01 +02:00
static void notify_message() throw()
{
graphics_plugin::notify_message();
}
/**
* Notify changed status.
*/
static void notify_status() throw()
{
graphics_plugin::notify_status();
}
/**
* Notify changed screen.
*/
static void notify_screen() throw()
{
graphics_plugin::notify_screen();
}
/**
2012-01-06 17:28:01 +02:00
* Set modal pause mode.
2011-10-31 21:05:54 +02:00
*
2012-01-06 17:28:01 +02:00
* - Modal pause works like ordinary pause, except it uses a separate flag.
*
* Parameter enable: If true, enable modal pause, else disable it.
*/
2012-01-06 17:28:01 +02:00
static void set_modal_pause(bool enable) throw();
/**
2012-01-06 17:28:01 +02:00
* Queue keypress.
*
* - Can be called from any thread.
2011-10-31 21:05:54 +02:00
*
2012-01-06 17:28:01 +02:00
* Parameter k: The keypress to queue.
*/
2012-01-06 17:28:01 +02:00
static void queue(const keypress& k) throw(std::bad_alloc);
/**
2012-01-06 17:28:01 +02:00
* Queue command.
*
* - Can be called from any thread.
2011-10-31 21:05:54 +02:00
*
2012-01-06 17:28:01 +02:00
* Parameter c: The command to queue.
*/
2012-01-06 17:28:01 +02:00
static void queue(const std::string& c) throw(std::bad_alloc);
/**
2012-01-06 17:28:01 +02:00
* Queue function to be called in emulation thread.
2011-10-31 21:05:54 +02:00
*
2012-01-06 17:28:01 +02:00
* - Can be called from any thread (exception: Synchronous mode can not be used from emulation nor main threads).
*
* Parameter f: The function to execute.
* Parameter arg: Argument to pass to the function.
* Parameter sync: If true, execute function call synchronously, else asynchronously.
*/
2012-01-06 17:28:01 +02:00
static void queue(void (*f)(void* arg), void* arg, bool sync) throw(std::bad_alloc);
2011-10-31 21:05:54 +02:00
/**
2012-01-06 17:28:01 +02:00
* Run all queues.
2011-10-31 21:05:54 +02:00
*/
2012-01-06 17:28:01 +02:00
static void run_queues() throw();
2012-01-23 01:30:24 +02:00
static bool pausing_allowed;
2012-03-26 21:55:02 +03:00
static double global_volume;
static volatile bool do_exit_dummy_event_loop;
static void dummy_event_loop() throw();
static void exit_dummy_event_loop() throw();
};
2012-01-20 14:09:38 +02:00
class modal_pause_holder
{
public:
modal_pause_holder();
~modal_pause_holder();
private:
modal_pause_holder(const modal_pause_holder&);
modal_pause_holder& operator=(const modal_pause_holder&);
};
2012-01-06 17:28:01 +02:00
template<typename T>
void functor_call_helper(void* args)
{
(*reinterpret_cast<T*>(args))();
}
template<typename T>
void runemufn(T fn)
{
platform::queue(functor_call_helper<T>, &fn, true);
}
/**
* If set, queueing synchronous function produces a warning.
*/
extern volatile bool queue_synchronous_fn_warning;
2011-10-28 21:01:29 +03:00
#endif