summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/windows/window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/windows/window.cpp')
-rw-r--r--src/osd/windows/window.cpp251
1 files changed, 159 insertions, 92 deletions
diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp
index 0fbfae9c481..bbf59077f8f 100644
--- a/src/osd/windows/window.cpp
+++ b/src/osd/windows/window.cpp
@@ -12,12 +12,6 @@
// Needed for RAW Input
#define WM_INPUT 0x00FF
-// standard windows headers
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <windowsx.h>
-#include <mmsystem.h>
-
// standard C headers
#include <process.h>
@@ -34,12 +28,12 @@
#include "winutil.h"
-extern int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks);
-extern int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks);
-extern int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks);
-extern int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks);
+#include "modules/render/drawbgfx.h"
+#include "modules/render/drawnone.h"
+#include "modules/render/drawd3d.h"
+#include "modules/render/drawgdi.h"
#if (USE_OPENGL)
-extern int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks);
+#include "modules/render/drawogl.h"
#endif
//============================================================
@@ -107,8 +101,6 @@ static DWORD window_threadid;
static DWORD last_update_time;
-static osd_draw_callbacks draw;
-
static HANDLE ui_pause_event;
static HANDLE window_thread_ready_event;
@@ -183,7 +175,7 @@ bool windows_osd_interface::window_init()
create_window_class();
// create an event to signal UI pausing
- ui_pause_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ ui_pause_event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
if (!ui_pause_event)
fatalerror("Failed to create pause event\n");
@@ -191,14 +183,14 @@ bool windows_osd_interface::window_init()
if (multithreading_enabled)
{
// create an event to signal when the window thread is ready
- window_thread_ready_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ window_thread_ready_event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
if (!window_thread_ready_event)
fatalerror("Failed to create window thread ready event\n");
// create a thread to run the windows from
- temp = _beginthreadex(NULL, 0, win_window_info::thread_entry, NULL, 0, (unsigned *)&window_threadid);
+ temp = _beginthreadex(nullptr, 0, win_window_info::thread_entry, nullptr, 0, (unsigned *)&window_threadid);
window_thread = (HANDLE)temp;
- if (window_thread == NULL)
+ if (window_thread == nullptr)
fatalerror("Failed to create window thread\n");
// set the thread priority equal to the main MAME thread
@@ -212,29 +204,108 @@ bool windows_osd_interface::window_init()
window_threadid = main_threadid;
}
- // initialize the drawers
- if (video_config.mode == VIDEO_MODE_D3D)
+ const int fallbacks[VIDEO_MODE_COUNT] = {
+ -1, // NONE -> no fallback
+ VIDEO_MODE_NONE, // GDI -> NONE
+ VIDEO_MODE_D3D, // BGFX -> D3D
+#if (USE_OPENGL)
+ VIDEO_MODE_GDI, // OPENGL -> GDI
+#endif
+ -1, // No SDL2ACCEL on Windows OSD
+#if (USE_OPENGL)
+ VIDEO_MODE_OPENGL, // D3D -> OPENGL
+#else
+ VIDEO_MODE_GDI, // D3D -> GDI
+#endif
+ -1 // No SOFT on Windows OSD
+ };
+
+ int current_mode = video_config.mode;
+ while (current_mode != VIDEO_MODE_NONE)
{
- if (drawd3d_init(machine(), &draw))
- video_config.mode = VIDEO_MODE_GDI;
- }
- if (video_config.mode == VIDEO_MODE_GDI)
- drawgdi_init(machine(), &draw);
- if (video_config.mode == VIDEO_MODE_BGFX)
- drawbgfx_init(machine(), &draw);
- if (video_config.mode == VIDEO_MODE_NONE)
- drawnone_init(machine(), &draw);
+ bool error = false;
+ switch(current_mode)
+ {
+ case VIDEO_MODE_NONE:
+ error = renderer_none::init(machine());
+ break;
+ case VIDEO_MODE_GDI:
+ error = renderer_gdi::init(machine());
+ break;
+ case VIDEO_MODE_BGFX:
+ error = renderer_bgfx::init(machine());
+ break;
#if (USE_OPENGL)
- if (video_config.mode == VIDEO_MODE_OPENGL)
- drawogl_init(machine(), &draw);
+ case VIDEO_MODE_OPENGL:
+ error = renderer_ogl::init(machine());
+ break;
#endif
+ case VIDEO_MODE_SDL2ACCEL:
+ fatalerror("SDL2-Accel renderer unavailable on Windows OSD.");
+ break;
+ case VIDEO_MODE_D3D:
+ error = renderer_d3d9::init(machine());
+ break;
+ case VIDEO_MODE_SOFT:
+ fatalerror("SDL1 renderer unavailable on Windows OSD.");
+ break;
+ default:
+ fatalerror("Unknown video mode.");
+ break;
+ }
+ if (error)
+ {
+ current_mode = fallbacks[current_mode];
+ }
+ else
+ {
+ break;
+ }
+ }
+ video_config.mode = current_mode;
+
// set up the window list
last_window_ptr = &win_window_list;
return true;
}
+void windows_osd_interface::update_slider_list()
+{
+ for (win_window_info *window = win_window_list; window != nullptr; window = window->m_next)
+ {
+ if (window->m_renderer->sliders_dirty())
+ {
+ build_slider_list();
+ return;
+ }
+ }
+}
+void windows_osd_interface::build_slider_list()
+{
+ m_sliders = nullptr;
+ slider_state *curr = m_sliders;
+ for (win_window_info *info = win_window_list; info != nullptr; info = info->m_next)
+ {
+ slider_state *window_sliders = info->m_renderer->get_slider_list();
+ if (window_sliders != nullptr)
+ {
+ if (m_sliders == nullptr)
+ {
+ m_sliders = curr = window_sliders;
+ }
+ else
+ {
+ while (curr->next != nullptr)
+ {
+ curr = curr->next;
+ }
+ curr->next = window_sliders;
+ }
+ }
+ }
+}
//============================================================
// winwindow_exit
@@ -246,7 +317,7 @@ void windows_osd_interface::window_exit()
assert(GetCurrentThreadId() == main_threadid);
// free all the windows
- while (win_window_list != NULL)
+ while (win_window_list != nullptr)
{
win_window_info *temp = win_window_list;
win_window_list = temp->m_next;
@@ -254,9 +325,6 @@ void windows_osd_interface::window_exit()
global_free(temp);
}
- // kill the drawers
- (*draw.exit)();
-
// if we're multithreaded, clean up the window thread
if (multithreading_enabled)
{
@@ -278,24 +346,23 @@ void windows_osd_interface::window_exit()
while (ShowCursor(TRUE) < 0) ;
}
-
win_window_info::win_window_info(running_machine &machine)
- : osd_window(), m_next(NULL),
+ : osd_window(), m_next(nullptr),
m_init_state(0),
m_startmaximized(0),
m_isminimized(0),
m_ismaximized(0),
- m_monitor(NULL),
+ m_monitor(nullptr),
m_fullscreen(0),
m_fullscreen_safe(0),
m_aspect(0),
- m_target(NULL),
+ m_target(nullptr),
m_targetview(0),
m_targetorient(0),
m_lastclicktime(0),
m_lastclickx(0),
m_lastclicky(0),
- m_renderer(NULL),
+ m_renderer(nullptr),
m_machine(machine)
{
memset(m_title,0,sizeof(m_title));
@@ -336,9 +403,7 @@ void winwindow_process_events_periodic(running_machine &machine)
static BOOL is_mame_window(HWND hwnd)
{
- win_window_info *window;
-
- for (window = win_window_list; window != NULL; window = window->m_next)
+ for (win_window_info *window = win_window_list; window != nullptr; window = window->m_next)
if (window->m_hwnd == hwnd)
return TRUE;
@@ -368,12 +433,12 @@ void winwindow_process_events(running_machine &machine, int ingame, bool nodispa
WaitMessage();
// loop over all messages in the queue
- while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
+ while (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE))
{
// prevent debugger windows from getting messages during reset
int dispatch = TRUE && !nodispatch;
- if (message.hwnd == NULL || is_mame_window(message.hwnd))
+ if (message.hwnd == nullptr || is_mame_window(message.hwnd))
{
dispatch = TRUE;
switch (message.message)
@@ -485,7 +550,7 @@ void winwindow_take_snap(void)
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
- for (window = win_window_list; window != NULL; window = window->m_next)
+ for (window = win_window_list; window != nullptr; window = window->m_next)
{
window->m_renderer->save();
}
@@ -505,7 +570,7 @@ void winwindow_toggle_fsfx(void)
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
- for (window = win_window_list; window != NULL; window = window->m_next)
+ for (window = win_window_list; window != nullptr; window = window->m_next)
{
window->m_renderer->toggle_fsfx();
}
@@ -525,7 +590,7 @@ void winwindow_take_video(void)
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
- for (window = win_window_list; window != NULL; window = window->m_next)
+ for (window = win_window_list; window != nullptr; window = window->m_next)
{
window->m_renderer->record();
}
@@ -545,7 +610,7 @@ void winwindow_toggle_full_screen(void)
assert(GetCurrentThreadId() == main_threadid);
// if we are in debug mode, never go full screen
- for (window = win_window_list; window != NULL; window = window->m_next)
+ for (window = win_window_list; window != nullptr; window = window->m_next)
if (window->machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)
return;
@@ -553,7 +618,7 @@ void winwindow_toggle_full_screen(void)
video_config.windowed = !video_config.windowed;
// iterate over windows and toggle their fullscreen state
- for (window = win_window_list; window != NULL; window = window->m_next)
+ for (window = win_window_list; window != nullptr; window = window->m_next)
SendMessage(window->m_hwnd, WM_USER_SET_FULLSCREEN, !video_config.windowed, 0);
SetForegroundWindow(win_window_list->m_hwnd);
}
@@ -571,7 +636,7 @@ BOOL winwindow_has_focus(void)
win_window_info *window;
// see if one of the video windows has focus
- for (window = win_window_list; window != NULL; window = window->m_next)
+ for (window = win_window_list; window != nullptr; window = window->m_next)
if (focuswnd == window->m_hwnd)
return TRUE;
@@ -621,7 +686,7 @@ void winwindow_update_cursor_state(running_machine &machine)
ShowCursor(FALSE);
// allow cursor to move freely
- ClipCursor(NULL);
+ ClipCursor(nullptr);
if (saved_cursor_pos.x != -1 || saved_cursor_pos.y != -1)
{
SetCursorPos(saved_cursor_pos.x, saved_cursor_pos.y);
@@ -639,13 +704,12 @@ void winwindow_update_cursor_state(running_machine &machine)
void win_window_info::create(running_machine &machine, int index, osd_monitor_info *monitor, const osd_window_config *config)
{
- win_window_info *window, *win;
+ win_window_info *win;
assert(GetCurrentThreadId() == main_threadid);
// allocate a new window object
- window = global_alloc(win_window_info(machine));
- //printf("%d, %d\n", config->width, config->height);
+ win_window_info *window = global_alloc(win_window_info(machine));
window->m_win_config = *config;
window->m_monitor = monitor;
window->m_fullscreen = !video_config.windowed;
@@ -654,7 +718,7 @@ void win_window_info::create(running_machine &machine, int index, osd_monitor_in
// set main window
if (index > 0)
{
- for (auto w = win_window_list; w != NULL; w = w->m_next)
+ for (auto w = win_window_list; w != nullptr; w = w->m_next)
{
if (w->m_index == 0)
{
@@ -665,7 +729,7 @@ void win_window_info::create(running_machine &machine, int index, osd_monitor_in
}
// see if we are safe for fullscreen
window->m_fullscreen_safe = TRUE;
- for (win = win_window_list; win != NULL; win = win->m_next)
+ for (win = win_window_list; win != nullptr; win = win->m_next)
if (win->m_monitor == monitor)
window->m_fullscreen_safe = FALSE;
@@ -731,7 +795,7 @@ void win_window_info::destroy()
assert(GetCurrentThreadId() == main_threadid);
// remove us from the list
- for (prevptr = &win_window_list; *prevptr != NULL; prevptr = &(*prevptr)->m_next)
+ for (prevptr = &win_window_list; *prevptr != nullptr; prevptr = &(*prevptr)->m_next)
if (*prevptr == this)
{
*prevptr = this->m_next;
@@ -739,7 +803,7 @@ void win_window_info::destroy()
}
// destroy the window
- if (m_hwnd != NULL)
+ if (m_hwnd != nullptr)
SendMessage(m_hwnd, WM_USER_SELF_TERMINATE, 0, 0);
// free the render target
@@ -783,7 +847,7 @@ void win_window_info::update()
}
// if we're visible and running and not in the middle of a resize, draw
- if (m_hwnd != NULL && m_target != NULL && m_renderer != NULL)
+ if (m_hwnd != nullptr && m_target != nullptr && m_renderer != nullptr)
{
bool got_lock = true;
@@ -836,7 +900,7 @@ osd_monitor_info *win_window_info::winwindow_video_window_monitor(const osd_rect
// in window mode, find the nearest
if (!m_fullscreen)
{
- if (proposed != NULL)
+ if (proposed != nullptr)
{
RECT p;
p.top = proposed->top();
@@ -879,7 +943,7 @@ static void create_window_class(void)
wc.lpszClassName = TEXT("MAME");
wc.hInstance = GetModuleHandleUni();
wc.lpfnWndProc = winwindow_video_window_proc_ui;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hIcon = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2));
UnregisterClass(wc.lpszClassName, wc.hInstance);
@@ -1053,8 +1117,6 @@ int win_window_info::wnd_extra_height()
return rect_height(&temprect) - 100;
}
-
-
//============================================================
// thread_entry
// (window thread)
@@ -1065,7 +1127,7 @@ unsigned __stdcall win_window_info::thread_entry(void *param)
MSG message;
// make a bogus user call to make us a message thread
- PeekMessage(&message, NULL, 0, 0, PM_NOREMOVE);
+ PeekMessage(&message, nullptr, 0, 0, PM_NOREMOVE);
// attach our input to the main thread
AttachThreadInput(main_threadid, window_threadid, TRUE);
@@ -1074,11 +1136,11 @@ unsigned __stdcall win_window_info::thread_entry(void *param)
SetEvent(window_thread_ready_event);
// run the message pump
- while (GetMessage(&message, NULL, 0, 0))
+ while (GetMessage(&message, nullptr, 0, 0))
{
int dispatch = TRUE;
- if ((message.hwnd == NULL) || is_mame_window(message.hwnd))
+ if ((message.hwnd == nullptr) || is_mame_window(message.hwnd))
{
switch (message.message)
{
@@ -1160,7 +1222,7 @@ int win_window_info::complete_create()
{
RECT client;
int tempwidth, tempheight;
- HMENU menu = NULL;
+ HMENU menu = nullptr;
HDC dc;
assert(GetCurrentThreadId() == window_threadid);
@@ -1183,11 +1245,11 @@ int win_window_info::complete_create()
m_fullscreen ? FULLSCREEN_STYLE : WINDOW_STYLE,
monitorbounds.left() + 20, monitorbounds.top() + 20,
monitorbounds.left() + 100, monitorbounds.top() + 100,
- NULL,//(win_window_list != NULL) ? win_window_list->m_hwnd : NULL,
+ nullptr,//(win_window_list != nullptr) ? win_window_list->m_hwnd : nullptr,
menu,
GetModuleHandleUni(),
- NULL);
- if (m_hwnd == NULL)
+ nullptr);
+ if (m_hwnd == nullptr)
return 1;
// set window #0 as the focus window for all windows, required for D3D & multimonitor
@@ -1203,7 +1265,7 @@ int win_window_info::complete_create()
// adjust the window position to the initial width/height
tempwidth = (m_win_config.width != 0) ? m_win_config.width : 640;
tempheight = (m_win_config.height != 0) ? m_win_config.height : 480;
- SetWindowPos(m_hwnd, NULL, monitorbounds.left() + 20, monitorbounds.top() + 20,
+ SetWindowPos(m_hwnd, nullptr, monitorbounds.left() + 20, monitorbounds.top() + 20,
monitorbounds.left() + tempwidth + wnd_extra_width(),
monitorbounds.top() + tempheight + wnd_extra_height(),
SWP_NOZORDER);
@@ -1219,9 +1281,14 @@ int win_window_info::complete_create()
if (!m_fullscreen || m_fullscreen_safe)
{
// finish off by trying to initialize DirectX; if we fail, ignore it
- m_renderer = draw.create(this);
+ if (m_renderer != nullptr)
+ {
+ global_free(m_renderer);
+ }
+ m_renderer = osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(this));
if (m_renderer->create())
return 1;
+
ShowWindow(m_hwnd, SW_SHOW);
}
@@ -1246,7 +1313,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
win_window_info *window = (win_window_info *)ptr;
// we may get called before SetWindowLongPtr is called
- if (window != NULL)
+ if (window != nullptr)
{
assert(GetCurrentThreadId() == window_threadid);
window->update_minmax_state();
@@ -1342,7 +1409,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
window->m_resize_state = RESIZE_STATE_PENDING;
case WM_EXITMENULOOP:
winwindow_ui_pause_from_window_thread(window->machine(), FALSE);
- InvalidateRect(wnd, NULL, FALSE);
+ InvalidateRect(wnd, nullptr, FALSE);
break;
// get min/max info: set the minimum window size
@@ -1366,7 +1433,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
rect->bottom = r.bottom();
rect->right = r.right();
}
- InvalidateRect(wnd, NULL, FALSE);
+ InvalidateRect(wnd, nullptr, FALSE);
break;
}
@@ -1380,7 +1447,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
return 1;
// most SYSCOMMANDs require us to invalidate the window
- InvalidateRect(wnd, NULL, FALSE);
+ InvalidateRect(wnd, nullptr, FALSE);
// handle maximize
if (cmd == SC_MAXIMIZE)
@@ -1408,15 +1475,11 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
window->machine().schedule_exit();
break;
- // destroy: clean up all attached rendering bits and NULL out our hwnd
+ // destroy: clean up all attached rendering bits and nullptr out our hwnd
case WM_DESTROY:
- if (!(window->m_renderer == NULL))
- {
- window->m_renderer->destroy();
global_free(window->m_renderer);
- window->m_renderer = NULL;
- }
- window->m_hwnd = NULL;
+ window->m_renderer = nullptr;
+ window->m_hwnd = nullptr;
return DefWindowProc(wnd, message, wparam, lparam);
// self redraw: draw ourself in a non-painty way
@@ -1467,7 +1530,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
// set focus: if we're not the primary window, switch back
// commented out ATM because this prevents us from resizing secondary windows
// case WM_SETFOCUS:
-// if (window != win_window_list && win_window_list != NULL)
+// if (window != win_window_list && win_window_list != nullptr)
// SetFocus(win_window_list->m_hwnd);
// break;
@@ -1497,10 +1560,10 @@ void win_window_info::draw_video_contents(HDC dc, int update)
mtlog_add("draw_video_contents: render lock acquired");
// if we're iconic, don't bother
- if (m_hwnd != NULL && !IsIconic(m_hwnd))
+ if (m_hwnd != nullptr && !IsIconic(m_hwnd))
{
// if no bitmap, just fill
- if (m_primlist == NULL)
+ if (m_primlist == nullptr)
{
RECT fill;
GetClientRect(m_hwnd, &fill);
@@ -1786,7 +1849,7 @@ void win_window_info::minimize_window()
osd_rect newrect(bounds.left, bounds.top, newsize );
- SetWindowPos(m_hwnd, NULL, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER);
+ SetWindowPos(m_hwnd, nullptr, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER);
}
@@ -1808,7 +1871,7 @@ void win_window_info::maximize_window()
work.top() + (work.height() - newsize.height()) / 2,
newsize);
- SetWindowPos(m_hwnd, NULL, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER);
+ SetWindowPos(m_hwnd, nullptr, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER);
}
@@ -1839,7 +1902,7 @@ void win_window_info::adjust_window_position_after_major_change()
// in full screen, make sure it covers the primary display
else
{
- osd_monitor_info *monitor = winwindow_video_window_monitor(NULL);
+ osd_monitor_info *monitor = winwindow_video_window_monitor(nullptr);
newrect = monitor->position_size();
}
@@ -1875,9 +1938,8 @@ void win_window_info::set_fullscreen(int fullscreen)
m_fullscreen = fullscreen;
// kill off the drawers
- m_renderer->destroy();
global_free(m_renderer);
- m_renderer = NULL;
+ m_renderer = nullptr;
// hide ourself
ShowWindow(m_hwnd, SW_HIDE);
@@ -1933,7 +1995,12 @@ void win_window_info::set_fullscreen(int fullscreen)
{
if (video_config.mode != VIDEO_MODE_NONE)
ShowWindow(m_hwnd, SW_SHOW);
- m_renderer = draw.create(this);
+
+ if (m_renderer != nullptr)
+ {
+ delete m_renderer;
+ }
+ m_renderer = reinterpret_cast<osd_renderer *>(osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(this)));
if (m_renderer->create())
exit(1);
}