diff options
Diffstat (limited to 'src')
36 files changed, 529 insertions, 459 deletions
diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp index c3994efbd2f..a32405c4aa8 100644 --- a/src/osd/modules/debugger/debugwin.cpp +++ b/src/osd/modules/debugger/debugwin.cpp @@ -236,7 +236,7 @@ void debugger_windows::show_all() void debugger_windows::hide_all() { - SetForegroundWindow(win_window_list->platform_window<HWND>()); + SetForegroundWindow(win_window_list.front()->platform_window<HWND>()); for (debugwin_info &info : m_window_list) info.hide(); } diff --git a/src/osd/modules/debugger/win/debugwininfo.cpp b/src/osd/modules/debugger/win/debugwininfo.cpp index 8c02ee17e1c..1e75b464b72 100644 --- a/src/osd/modules/debugger/win/debugwininfo.cpp +++ b/src/osd/modules/debugger/win/debugwininfo.cpp @@ -35,7 +35,7 @@ debugwin_info::debugwin_info(debugger_windows_interface &debugger, bool is_main_ register_window_class(); m_wnd = win_create_window_ex_utf8(DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE, - 0, 0, 100, 100, win_window_list->platform_window<HWND>(), create_standard_menubar(), GetModuleHandleUni(), this); + 0, 0, 100, 100, win_window_list.front()->platform_window<HWND>(), create_standard_menubar(), GetModuleHandleUni(), this); if (m_wnd == NULL) return; diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp index ca3bad08026..dfb63482570 100644 --- a/src/osd/modules/input/input_dinput.cpp +++ b/src/osd/modules/input/input_dinput.cpp @@ -564,7 +564,7 @@ public: dinput_joystick_device *devinfo; int result = 0; - if (win_window_list != nullptr && win_window_list->win_has_menu()) + if (!win_window_list.empty() && win_window_list.front()->win_has_menu()) cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; // allocate and link in a new device diff --git a/src/osd/modules/input/input_dinput.h b/src/osd/modules/input/input_dinput.h index f339bef561e..f06520cb285 100644 --- a/src/osd/modules/input/input_dinput.h +++ b/src/osd/modules/input/input_dinput.h @@ -103,7 +103,7 @@ public: } // set the cooperative level - result = devinfo->dinput.device->SetCooperativeLevel(win_window_list->platform_window<HWND>(), cooperative_level); + result = devinfo->dinput.device->SetCooperativeLevel(win_window_list.front()->platform_window<HWND>(), cooperative_level); if (result != DI_OK) goto error; diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp index 20ed82cc4a1..7476fea24a6 100644 --- a/src/osd/modules/input/input_rawinput.cpp +++ b/src/osd/modules/input/input_rawinput.cpp @@ -475,7 +475,7 @@ public: registration.usUsagePage = usagepage(); registration.usUsage = usage(); registration.dwFlags = m_global_inputs_enabled ? 0x00000100 : 0; - registration.hwndTarget = win_window_list->platform_window<HWND>(); + registration.hwndTarget = win_window_list.front()->platform_window<HWND>(); // register the device register_rawinput_devices(®istration, 1, sizeof(registration)); diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp index 8814cfe3876..996221f57e6 100644 --- a/src/osd/modules/input/input_sdl.cpp +++ b/src/osd/modules/input/input_sdl.cpp @@ -115,7 +115,7 @@ public: } protected: - sdl_window_info * focus_window() + std::shared_ptr<sdl_window_info> focus_window() { return sdl_event_manager::instance().focus_window(); } @@ -144,7 +144,7 @@ public: case SDL_KEYDOWN: keyboard.state[OSD_SDL_INDEX_KEYSYM(&sdlevent.key.keysym)] = 0x80; if (sdlevent.key.keysym.sym < 0x20) - machine().ui_input().push_char_event(sdl_window_list->target(), sdlevent.key.keysym.sym); + machine().ui_input().push_char_event(sdl_window_list.front()->target(), sdlevent.key.keysym.sym); break; case SDL_KEYUP: @@ -154,7 +154,7 @@ public: case SDL_TEXTINPUT: if (*sdlevent.text.text) { - sdl_window_info *window = GET_FOCUS_WINDOW(&event.text); + auto window = GET_FOCUS_WINDOW(&event.text); //printf("Focus window is %p - wl %p\n", window, sdl_window_list); unicode_char result; if (window != NULL) @@ -210,7 +210,7 @@ public: { int cx = -1, cy = -1; - sdl_window_info *window = GET_FOCUS_WINDOW(&sdlevent.motion); + auto window = GET_FOCUS_WINDOW(&sdlevent.motion); if (window != NULL && window->xy_to_render_target(sdlevent.motion.x, sdlevent.motion.y, &cx, &cy)) machine().ui_input().push_mouse_move_event(window->target(), cx, cy); @@ -228,7 +228,7 @@ public: static int last_y = 0; int cx, cy; osd_ticks_t click = osd_ticks() * 1000 / osd_ticks_per_second(); - sdl_window_info *window = GET_FOCUS_WINDOW(&sdlevent.button); + auto window = GET_FOCUS_WINDOW(&sdlevent.button); if (window != NULL && window->xy_to_render_target(sdlevent.button.x, sdlevent.button.y, &cx, &cy)) { machine().ui_input().push_mouse_down_event(window->target(), cx, cy); @@ -252,7 +252,7 @@ public: else if (sdlevent.button.button == 3) { int cx, cy; - sdl_window_info *window = GET_FOCUS_WINDOW(&sdlevent.button); + auto window = GET_FOCUS_WINDOW(&sdlevent.button); if (window != NULL && window->xy_to_render_target(sdlevent.button.x, sdlevent.button.y, &cx, &cy)) { @@ -268,7 +268,7 @@ public: if (sdlevent.button.button == 1) { int cx, cy; - sdl_window_info *window = GET_FOCUS_WINDOW(&sdlevent.button); + auto window = GET_FOCUS_WINDOW(&sdlevent.button); if (window != NULL && window->xy_to_render_target(sdlevent.button.x, sdlevent.button.y, &cx, &cy)) { @@ -278,7 +278,7 @@ public: else if (sdlevent.button.button == 3) { int cx, cy; - sdl_window_info *window = GET_FOCUS_WINDOW(&sdlevent.button); + auto window = GET_FOCUS_WINDOW(&sdlevent.button); if (window != NULL && window->xy_to_render_target(sdlevent.button.x, sdlevent.button.y, &cx, &cy)) { @@ -288,7 +288,7 @@ public: break; case SDL_MOUSEWHEEL: - sdl_window_info *window = GET_FOCUS_WINDOW(&sdlevent.wheel); + auto window = GET_FOCUS_WINDOW(&sdlevent.wheel); if (window != NULL) machine().ui_input().push_mouse_wheel_event(window->target(), 0, 0, sdlevent.wheel.y, 3); break; diff --git a/src/osd/modules/input/input_sdlcommon.cpp b/src/osd/modules/input/input_sdlcommon.cpp index 85febac18f6..6f2794e3ac5 100644 --- a/src/osd/modules/input/input_sdlcommon.cpp +++ b/src/osd/modules/input/input_sdlcommon.cpp @@ -35,12 +35,11 @@ #define GET_WINDOW(ev) window_from_id((ev)->windowID) //#define GET_WINDOW(ev) ((ev)->windowID) -static inline sdl_window_info * window_from_id(Uint32 windowID) +static inline std::shared_ptr<sdl_window_info> window_from_id(Uint32 windowID) { - sdl_window_info *w; SDL_Window *window = SDL_GetWindowFromID(windowID); - for (w = sdl_window_list; w != NULL; w = w->m_next) + for (auto w : sdl_window_list) { //printf("w->window_id: %d\n", w->window_id); if (w->platform_window<SDL_Window*>() == window) @@ -72,7 +71,7 @@ void sdl_event_manager::process_events(running_machine &machine) void sdl_event_manager::process_window_event(running_machine &machine, SDL_Event &sdlevent) { - sdl_window_info *window = GET_WINDOW(&sdlevent.window); + std::shared_ptr<sdl_window_info> window = GET_WINDOW(&sdlevent.window); if (window == NULL) return; @@ -273,7 +272,9 @@ void sdl_osd_interface::poll_inputs(running_machine &machine) void sdl_osd_interface::release_keys() { - downcast<input_module_base*>(m_keyboard_input)->devicelist()->reset_devices(); + auto keybd = dynamic_cast<input_module_base*>(m_keyboard_input); + if (keybd != nullptr) + keybd->devicelist()->reset_devices(); } bool sdl_osd_interface::should_hide_mouse() diff --git a/src/osd/modules/input/input_sdlcommon.h b/src/osd/modules/input/input_sdlcommon.h index feecf23f975..2e40199c556 100644 --- a/src/osd/modules/input/input_sdlcommon.h +++ b/src/osd/modules/input/input_sdlcommon.h @@ -118,7 +118,7 @@ class sdl_event_manager : public event_manager_t<sdl_event_subscriber> private: bool m_mouse_over_window; bool m_has_focus; - sdl_window_info * m_focus_window; + std::shared_ptr<sdl_window_info> m_focus_window; sdl_event_manager() : m_mouse_over_window(true), @@ -129,8 +129,8 @@ private: public: bool mouse_over_window() const { return m_mouse_over_window; } - bool has_focus() const { return m_focus_window; } - sdl_window_info * focus_window() { return m_focus_window; } + bool has_focus() const { return m_focus_window != nullptr; } + std::shared_ptr<sdl_window_info> focus_window() { return m_focus_window; } static sdl_event_manager& instance() { diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp index 5bef565beed..0b44c510fa0 100644 --- a/src/osd/modules/input/input_win32.cpp +++ b/src/osd/modules/input/input_win32.cpp @@ -152,7 +152,7 @@ public: mouse.lY = (cursor_info.ptScreenPos.y - win32_mouse.last_point.y) * INPUT_RELATIVE_PER_PIXEL; RECT window_pos = {0}; - GetWindowRect(win_window_list->platform_window<HWND>(), &window_pos); + GetWindowRect(win_window_list.front()->platform_window<HWND>(), &window_pos); // We reset the cursor position to the middle of the window each frame win32_mouse.last_point.x = window_pos.left + (window_pos.right - window_pos.left) / 2; @@ -269,13 +269,13 @@ public: // get the cursor position and transform into final results GetCursorPos(&mousepos); - if (win_window_list != NULL) + if (!win_window_list.empty()) { RECT client_rect; // get the position relative to the window - GetClientRect(win_window_list->platform_window<HWND>(), &client_rect); - ScreenToClient(win_window_list->platform_window<HWND>(), &mousepos); + GetClientRect(win_window_list.front()->platform_window<HWND>(), &client_rect); + ScreenToClient(win_window_list.front()->platform_window<HWND>(), &mousepos); // convert to absolute coordinates xpos = normalize_absolute_axis(mousepos.x, client_rect.left, client_rect.right); @@ -335,10 +335,10 @@ private: POINT mousepos; // get the position relative to the window - GetClientRect(win_window_list->platform_window<HWND>(), &client_rect); + GetClientRect(win_window_list.front()->platform_window<HWND>(), &client_rect); mousepos.x = args.xpos; mousepos.y = args.ypos; - ScreenToClient(win_window_list->platform_window<HWND>(), &mousepos); + ScreenToClient(win_window_list.front()->platform_window<HWND>(), &mousepos); // convert to absolute coordinates mouse.lX = normalize_absolute_axis(mousepos.x, client_rect.left, client_rect.right); diff --git a/src/osd/modules/input/input_windows.h b/src/osd/modules/input/input_windows.h index 85ad2c63326..d9dd28bac58 100644 --- a/src/osd/modules/input/input_windows.h +++ b/src/osd/modules/input/input_windows.h @@ -52,7 +52,7 @@ public: virtual bool should_hide_mouse() { if (winwindow_has_focus() // has focus - && (!video_config.windowed || !win_window_list->win_has_menu()) // not windowed or doesn't have a menu + && (!video_config.windowed || !win_window_list.front()->win_has_menu()) // not windowed or doesn't have a menu && (input_enabled() && !input_paused()) // input enabled and not paused && (mouse_enabled() || lightgun_enabled())) // either mouse or lightgun enabled in the core { diff --git a/src/osd/modules/input/input_winhybrid.cpp b/src/osd/modules/input/input_winhybrid.cpp index 538abe38da4..c74eb730b71 100644 --- a/src/osd/modules/input/input_winhybrid.cpp +++ b/src/osd/modules/input/input_winhybrid.cpp @@ -164,7 +164,7 @@ public: goto exit; } - if (win_window_list != nullptr && win_window_list->win_has_menu()) + if (!win_window_list.empty() && win_window_list.front()->win_has_menu()) cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; // allocate and link in a new device diff --git a/src/osd/modules/osdwindow.cpp b/src/osd/modules/osdwindow.cpp index cde83c3fe7f..b9afc8047cd 100644 --- a/src/osd/modules/osdwindow.cpp +++ b/src/osd/modules/osdwindow.cpp @@ -21,33 +21,34 @@ #include "render/drawsdl.h" #endif -osd_renderer* osd_renderer::make_for_type(int mode, osd_window* window, int extra_flags) +osd_window::~osd_window() +{ +} + +std::unique_ptr<osd_renderer> osd_renderer::make_for_type(int mode, std::shared_ptr<osd_window> window, int extra_flags) { switch(mode) { #ifdef OSD_WINDOWS case VIDEO_MODE_NONE: - return new renderer_none(window); + return std::make_unique<renderer_none>(window); #endif case VIDEO_MODE_BGFX: - return new renderer_bgfx(window); + return std::make_unique<renderer_bgfx>(window); #if (USE_OPENGL) case VIDEO_MODE_OPENGL: - return new renderer_ogl(window); + return std::make_unique<renderer_ogl>(window); #endif #ifdef OSD_WINDOWS case VIDEO_MODE_GDI: - return new renderer_gdi(window); + return std::make_unique<renderer_gdi>(window); case VIDEO_MODE_D3D: - { - osd_renderer *renderer = new renderer_d3d9(window); - return renderer; - } + return std::make_unique<renderer_d3d9>(window); #else case VIDEO_MODE_SDL2ACCEL: - return new renderer_sdl2(window, extra_flags); + return std::make_unique<renderer_sdl2>(window, extra_flags); case VIDEO_MODE_SOFT: - return new renderer_sdl1(window, extra_flags); + return std::make_unique<renderer_sdl1>(window, extra_flags); #endif default: return nullptr; diff --git a/src/osd/modules/osdwindow.h b/src/osd/modules/osdwindow.h index 428d821413c..4996cce002d 100644 --- a/src/osd/modules/osdwindow.h +++ b/src/osd/modules/osdwindow.h @@ -106,7 +106,9 @@ public: int refresh; // decoded refresh }; -class osd_window +class osd_renderer; + +class osd_window : public std::enable_shared_from_this<osd_window> { public: osd_window() @@ -116,16 +118,24 @@ public: #endif m_primlist(nullptr), m_index(0), - m_main(nullptr), m_prescale(1), - m_platform_window(nullptr) + m_platform_window(nullptr), + m_renderer(nullptr), + m_main(nullptr) {} - virtual ~osd_window() { } + + virtual ~osd_window(); virtual render_target *target() = 0; virtual int fullscreen() const = 0; virtual running_machine &machine() const = 0; + osd_renderer &renderer() const { return *m_renderer; } + void set_renderer(std::unique_ptr<osd_renderer> renderer) + { + m_renderer = std::move(renderer); + } + int prescale() const { return m_prescale; }; float pixel_aspect() const { return monitor()->pixel_aspect(); } @@ -152,6 +162,9 @@ public: m_platform_window = window; } + std::shared_ptr<osd_window> main_window() { return m_main; } + void set_main_window(std::shared_ptr<osd_window> main) { m_main = main; } + // Clips the pointer to the bounds of this window virtual void capture_pointer() = 0; @@ -173,12 +186,13 @@ public: render_primitive_list *m_primlist; osd_window_config m_win_config; - int m_index; - osd_window *m_main; + int m_index; protected: int m_prescale; private: - void *m_platform_window; + void *m_platform_window; + std::unique_ptr<osd_renderer> m_renderer; + std::shared_ptr<osd_window> m_main; }; class osd_renderer @@ -194,12 +208,23 @@ public: static const int FLAG_NEEDS_DOUBLEBUF = 0x0100; static const int FLAG_NEEDS_ASYNCBLIT = 0x0200; - osd_renderer(osd_window *window, const int flags) + osd_renderer(std::shared_ptr<osd_window> window, const int flags) : m_sliders_dirty(false), m_window(window), m_flags(flags) { } virtual ~osd_renderer() { } - osd_window &window() { return *m_window; } + std::shared_ptr<osd_window> assert_window() const + { + auto win = m_window.lock(); + assert_always(win != nullptr, "Window weak_ptr is not available!"); + return win; + } + + std::shared_ptr<osd_window> try_getwindow() const + { + return m_window.lock(); + } + bool has_flags(const int flag) { return ((m_flags & flag)) == flag; } void set_flags(int aflag) { m_flags |= aflag; } void clear_flags(int aflag) { m_flags &= ~aflag; } @@ -220,7 +245,7 @@ public: virtual void toggle_fsfx() { }; virtual bool sliders_dirty() { return m_sliders_dirty; } - static osd_renderer* make_for_type(int mode, osd_window *window, int extra_flags = FLAG_NONE); + static std::unique_ptr<osd_renderer> make_for_type(int mode, std::shared_ptr<osd_window> window, int extra_flags = FLAG_NONE); protected: virtual void build_slider_list() { } @@ -231,7 +256,7 @@ protected: std::vector<ui_menu_item> m_sliders; private: - osd_window *m_window; + std::weak_ptr<osd_window> m_window; int m_flags; }; diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index d8ce75c06db..4ce87b3e29c 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -1612,6 +1612,8 @@ void shaders::render_quad(poly_info *poly, int vertnum) curr_texture = poly->get_texture(); curr_poly = poly; + auto win = d3d->assert_window(); + if (PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && curr_texture != nullptr) { curr_screen = curr_screen < num_screens ? curr_screen : 0; @@ -1663,7 +1665,7 @@ void shaders::render_quad(poly_info *poly, int vertnum) { lines_pending = true; - bool swap_xy = d3d->window().swap_xy(); + bool swap_xy = win->swap_xy(); int source_width = swap_xy ? (float)d3d->get_height() : (float)d3d->get_width(); int source_height = swap_xy ? (float)d3d->get_width() : (float)d3d->get_height(); @@ -1690,7 +1692,7 @@ void shaders::render_quad(poly_info *poly, int vertnum) { curr_screen = curr_screen < num_screens ? curr_screen : 0; - bool swap_xy = d3d->window().swap_xy(); + bool swap_xy = win->swap_xy(); int source_width = swap_xy ? (float)d3d->get_height() : (float)d3d->get_width(); int source_height = swap_xy ? (float)d3d->get_width() : (float)d3d->get_height(); @@ -1805,7 +1807,9 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_i return nullptr; } - bool swap_xy = d3d->window().swap_xy(); + auto win = d3d->assert_window(); + + bool swap_xy = win->swap_xy(); int target_width = swap_xy ? static_cast<int>(prim->get_quad_height() + 0.5f) : static_cast<int>(prim->get_quad_width() + 0.5f); @@ -1835,7 +1839,9 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim) return nullptr; } - bool swap_xy = d3d->window().swap_xy(); + auto win = d3d->assert_window(); + + bool swap_xy = win->swap_xy(); int target_width = swap_xy ? static_cast<int>(prim->get_quad_height() + 0.5f) : static_cast<int>(prim->get_quad_width() + 0.5f); @@ -1862,7 +1868,9 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim) void shaders::create_vector_target(render_primitive *prim) { - bool swap_xy = d3d->window().swap_xy(); + auto win = d3d->assert_window(); + + bool swap_xy = win->swap_xy(); int target_width = swap_xy ? static_cast<int>(prim->get_quad_height() + 0.5f) : static_cast<int>(prim->get_quad_width() + 0.5f); @@ -1974,7 +1982,9 @@ bool shaders::register_texture(render_primitive *prim, texture_info *texture) return false; } - bool swap_xy = d3d->window().swap_xy(); + auto win = d3d->assert_window(); + + bool swap_xy = win->swap_xy(); int target_width = swap_xy ? static_cast<int>(prim->get_quad_height() + 0.5f) : static_cast<int>(prim->get_quad_width() + 0.5f); @@ -2614,6 +2624,8 @@ void uniform::update() hlsl_options *options = shadersys->options; renderer_d3d9 *d3d = shadersys->d3d; + auto win = d3d->assert_window(); + switch (m_id) { case CU_SCREEN_DIMS: @@ -2625,7 +2637,7 @@ void uniform::update() case CU_SOURCE_DIMS: { bool vector_screen = - d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR; + win->machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR; if (vector_screen) { if (shadersys->curr_render_target) @@ -2673,13 +2685,13 @@ void uniform::update() case CU_SWAP_XY: { - m_shader->set_bool("SwapXY", d3d->window().swap_xy()); + m_shader->set_bool("SwapXY", win->swap_xy()); break; } case CU_VECTOR_SCREEN: { bool vector_screen = - d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR; + win->machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR; m_shader->set_bool("VectorScreen", vector_screen); break; } diff --git a/src/osd/modules/render/draw13.cpp b/src/osd/modules/render/draw13.cpp index b4326ff2bdf..24bf22c3b27 100644 --- a/src/osd/modules/render/draw13.cpp +++ b/src/osd/modules/render/draw13.cpp @@ -60,7 +60,7 @@ static inline bool is_transparent(const float &a) // CONSTRUCTOR & DESTRUCTOR //============================================================ -renderer_sdl2::renderer_sdl2(osd_window *window, int extra_flags) +renderer_sdl2::renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags) : osd_renderer(window, FLAG_NEEDS_OPENGL | extra_flags) , m_sdl_renderer(nullptr) , m_blittimer(0) @@ -434,10 +434,12 @@ int renderer_sdl2::create() SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); } + auto win = assert_window(); + if (video_config.waitvsync) - m_sdl_renderer = SDL_CreateRenderer(window().platform_window<SDL_Window*>(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); + m_sdl_renderer = SDL_CreateRenderer(win->platform_window<SDL_Window*>(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); else - m_sdl_renderer = SDL_CreateRenderer(window().platform_window<SDL_Window*>(), -1, SDL_RENDERER_ACCELERATED); + m_sdl_renderer = SDL_CreateRenderer(win->platform_window<SDL_Window*>(), -1, SDL_RENDERER_ACCELERATED); if (!m_sdl_renderer) { @@ -481,11 +483,15 @@ int renderer_sdl2::xy_to_render_target(int x, int y, int *xt, int *yt) void renderer_sdl2::destroy_all_textures() { - if(window().m_primlist) + auto win = assert_window(); + if (win == nullptr) + return; + + if(win->m_primlist) { - window().m_primlist->acquire_lock(); + win->m_primlist->acquire_lock(); m_texlist.reset(); - window().m_primlist->release_lock(); + win->m_primlist->release_lock(); } else m_texlist.reset(); @@ -506,7 +512,8 @@ int renderer_sdl2::draw(int update) return 0; } - osd_dim wdim = window().get_size(); + auto win = assert_window(); + osd_dim wdim = win->get_size(); if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height)) { @@ -553,10 +560,10 @@ int renderer_sdl2::draw(int update) m_last_hofs = hofs; m_last_vofs = vofs; - window().m_primlist->acquire_lock(); + win->m_primlist->acquire_lock(); // now draw - for (render_primitive &prim : *window().m_primlist) + for (render_primitive &prim : *win->m_primlist) { Uint8 sr, sg, sb, sa; @@ -586,7 +593,7 @@ int renderer_sdl2::draw(int update) } } - window().m_primlist->release_lock(); + win->m_primlist->release_lock(); m_last_blit_pixels = blit_pixels; m_last_blit_time = -osd_ticks(); @@ -930,7 +937,8 @@ texture_info * renderer_sdl2::texture_update(const render_primitive &prim) quad_setup_data setup; texture_info *texture; - setup.compute(prim, window().prescale()); + auto win = assert_window(); + setup.compute(prim, win->prescale()); texture = texture_find(prim, setup); @@ -957,12 +965,16 @@ texture_info * renderer_sdl2::texture_update(const render_primitive &prim) render_primitive_list *renderer_sdl2::get_primitives() { - osd_dim nd = window().get_size(); + auto win = assert_window(); + if (win == nullptr) + return nullptr; + + osd_dim nd = win->get_size(); if (nd != m_blit_dim) { m_blit_dim = nd; notify_changed(); } - window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect()); - return &window().target()->get_primitives(); + win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect()); + return &win->target()->get_primitives(); } diff --git a/src/osd/modules/render/draw13.h b/src/osd/modules/render/draw13.h index 634c1debf6f..e242749ba10 100644 --- a/src/osd/modules/render/draw13.h +++ b/src/osd/modules/render/draw13.h @@ -149,7 +149,7 @@ struct copy_info_t class renderer_sdl2 : public osd_renderer { public: - renderer_sdl2(osd_window *window, int extra_flags); + renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags); virtual ~renderer_sdl2() { diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 479cea4f3b2..84f1ff0bd6f 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -77,7 +77,7 @@ uint32_t renderer_bgfx::s_current_view = 0; // renderer_bgfx - constructor //============================================================ -renderer_bgfx::renderer_bgfx(osd_window *w) +renderer_bgfx::renderer_bgfx(std::shared_ptr<osd_window> w) : osd_renderer(w, FLAG_NONE) , m_options(downcast<osd_options &>(w->machine().options())) , m_dimensions(0, 0) @@ -85,7 +85,7 @@ renderer_bgfx::renderer_bgfx(osd_window *w) , m_avi_writer(nullptr) , m_avi_target(nullptr) { - m_options = downcast<osd_options &>(window().machine().options()); + m_options = downcast<osd_options &>(assert_window()->machine().options()); } //============================================================ @@ -146,10 +146,11 @@ static void* sdlNativeWindowHandle(SDL_Window* _window) int renderer_bgfx::create() { // create renderer - osd_dim wdim = window().get_size(); - m_width[window().m_index] = wdim.width(); - m_height[window().m_index] = wdim.height(); - if (window().m_index == 0) + auto win = assert_window(); + osd_dim wdim = win->get_size(); + m_width[win->m_index] = wdim.width(); + m_height[win->m_index] = wdim.height(); + if (win->m_index == 0) { if (!s_window_set) { @@ -164,9 +165,9 @@ int renderer_bgfx::create() bgfx::setPlatformData(blank_pd); } #ifdef OSD_WINDOWS - bgfx::winSetHwnd(window().platform_window<HWND>()); + bgfx::winSetHwnd(win->platform_window<HWND>()); #else - bgfx::sdlSetWindow(window().platform_window<SDL_Window*>()); + bgfx::sdlSetWindow(win->platform_window<SDL_Window*>()); #endif std::string backend(m_options.bgfx_backend()); if (backend == "auto") @@ -198,7 +199,7 @@ int renderer_bgfx::create() printf("Unknown backend type '%s', going with auto-detection\n", backend.c_str()); bgfx::init(); } - bgfx::reset(m_width[window().m_index], m_height[window().m_index], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); + bgfx::reset(m_width[win->m_index], m_height[win->m_index], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); // Enable debug text. bgfx::setDebug(m_options.bgfx_debug() ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT); m_dimensions = osd_dim(m_width[0], m_height[0]); @@ -210,14 +211,14 @@ int renderer_bgfx::create() m_shaders = new shader_manager(m_options); m_effects = new effect_manager(m_options, *m_shaders); - if (window().m_index != 0) + if (win->m_index != 0) { #ifdef OSD_WINDOWS - m_framebuffer = m_targets->create_backbuffer(window().platform_window<HWND>(), m_width[window().m_index], m_height[window().m_index]); + m_framebuffer = m_targets->create_backbuffer(win->platform_window<HWND>(), m_width[win->m_index], m_height[win->m_index]); #else - m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(window().platform_window<SDL_Window*>()), m_width[window().m_index], m_height[window().m_index]); + m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(win->platform_window<SDL_Window*>()), m_width[win->m_index], m_height[win->m_index]); #endif - bgfx::touch(window().m_index); + bgfx::touch(win->m_index); } // Create program from shaders. @@ -231,7 +232,7 @@ int renderer_bgfx::create() m_screen_effect[2] = m_effects->effect("screen_multiply"); m_screen_effect[3] = m_effects->effect("screen_add"); - m_chains = new chain_manager(window().machine(), m_options, *m_textures, *m_targets, *m_effects, window().m_index, *this); + m_chains = new chain_manager(win->machine(), m_options, *m_textures, *m_targets, *m_effects, win->m_index, *this); m_sliders_dirty = true; uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; @@ -251,7 +252,8 @@ int renderer_bgfx::create() void renderer_bgfx::record() { - if (m_avi_writer == nullptr || window().m_index > 0) + auto win = assert_window(); + if (m_avi_writer == nullptr || win->m_index > 0) { return; } @@ -648,15 +650,16 @@ uint32_t renderer_bgfx::u32Color(uint32_t r, uint32_t g, uint32_t b, uint32_t a int renderer_bgfx::draw(int update) { - int window_index = window().m_index; + auto win = assert_window(); + int window_index = win->m_index; if (window_index == 0) { s_current_view = 0; if (m_avi_writer == nullptr) { - uint32_t width = window().get_size().width(); - uint32_t height = window().get_size().height(); - m_avi_writer = new avi_write(window().machine(), width, height); + uint32_t width = win->get_size().width(); + uint32_t height = win->get_size().height(); + m_avi_writer = new avi_write(win->machine(), width, height); m_avi_data = new uint8_t[width * height * 4]; m_avi_bitmap.allocate(width, height); } @@ -666,13 +669,13 @@ int renderer_bgfx::draw(int update) m_ui_view = -1; // Set view 0 default viewport. - osd_dim wdim = window().get_size(); + osd_dim wdim = win->get_size(); m_width[window_index] = wdim.width(); m_height[window_index] = wdim.height(); - window().m_primlist->acquire_lock(); - s_current_view += m_chains->handle_screen_chains(s_current_view, window().m_primlist->first(), window()); - window().m_primlist->release_lock(); + win->m_primlist->acquire_lock(); + s_current_view += m_chains->handle_screen_chains(s_current_view, win->m_primlist->first(), *win.get()); + win->m_primlist->release_lock(); bool skip_frame = update_dimensions(); if (skip_frame) @@ -689,12 +692,12 @@ int renderer_bgfx::draw(int update) s_current_view = m_max_view; } - window().m_primlist->acquire_lock(); + win->m_primlist->acquire_lock(); // Mark our texture atlas as dirty if we need to do so bool atlas_valid = update_atlas(); - render_primitive *prim = window().m_primlist->first(); + render_primitive *prim = win->m_primlist->first(); std::vector<void*> sources; while (prim != nullptr) { @@ -734,7 +737,7 @@ int renderer_bgfx::draw(int update) } } - window().m_primlist->release_lock(); + win->m_primlist->release_lock(); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. @@ -774,7 +777,8 @@ void renderer_bgfx::update_recording() void renderer_bgfx::add_audio_to_recording(const INT16 *buffer, int samples_this_frame) { - if (m_avi_writer != nullptr && m_avi_writer->recording() && window().m_index == 0) + auto win = assert_window(); + if (m_avi_writer != nullptr && m_avi_writer->recording() && win->m_index == 0) { m_avi_writer->audio_frame(buffer, samples_this_frame); } @@ -782,7 +786,9 @@ void renderer_bgfx::add_audio_to_recording(const INT16 *buffer, int samples_this bool renderer_bgfx::update_dimensions() { - const uint32_t window_index = window().m_index; + auto win = assert_window(); + + const uint32_t window_index = win->m_index; const uint32_t width = m_width[window_index]; const uint32_t height = m_height[window_index]; @@ -798,14 +804,14 @@ bool renderer_bgfx::update_dimensions() { if ((m_dimensions != osd_dim(width, height))) { - bgfx::reset(window().m_main->get_size().width(), window().m_main->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); + bgfx::reset(win->main_window()->get_size().width(), win->main_window()->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); m_dimensions = osd_dim(width, height); delete m_framebuffer; #ifdef OSD_WINDOWS - m_framebuffer = m_targets->create_backbuffer(window().platform_window<HWND>(), width, height); + m_framebuffer = m_targets->create_backbuffer(win->platform_window<HWND>(), width, height); #else - m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(window().platform_window<SDL_Window*>()), width, height); + m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(win->platform_window<SDL_Window*>()), width, height); #endif bgfx::setViewFrameBuffer(s_current_view, m_framebuffer->target()); @@ -820,7 +826,9 @@ bool renderer_bgfx::update_dimensions() void renderer_bgfx::setup_view(uint32_t view_index, bool screen) { - const uint32_t window_index = window().m_index; + auto win = assert_window(); + + const uint32_t window_index = win->m_index; const uint32_t width = m_width[window_index]; const uint32_t height = m_height[window_index]; @@ -845,7 +853,7 @@ void renderer_bgfx::setup_view(uint32_t view_index, bool screen) { m_seen_views[view_index] = true; #endif - if (m_avi_writer != nullptr && m_avi_writer->recording() && window().m_index == 0) + if (m_avi_writer != nullptr && m_avi_writer->recording() && win->m_index == 0) { bgfx::setViewFrameBuffer(view_index, m_avi_target->target()); } @@ -857,7 +865,8 @@ void renderer_bgfx::setup_view(uint32_t view_index, bool screen) void renderer_bgfx::setup_matrices(uint32_t view_index, bool screen) { - const uint32_t window_index = window().m_index; + auto win = assert_window(); + const uint32_t window_index = win->m_index; const uint32_t width = m_width[window_index]; const uint32_t height = m_height[window_index]; @@ -1064,8 +1073,9 @@ bool renderer_bgfx::check_for_dirty_atlas() { bool atlas_dirty = false; + auto win = assert_window(); std::map<UINT32, rectangle_packer::packable_rectangle> acquired_infos; - for (render_primitive &prim : *window().m_primlist) + for (render_primitive &prim : *win->m_primlist) { bool pack = prim.packable(PACKABLE_SIZE); if (prim.type == render_primitive::QUAD && prim.texture.base != nullptr && pack) diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h index 1a21b5c8259..7cc3bab9e47 100644 --- a/src/osd/modules/render/drawbgfx.h +++ b/src/osd/modules/render/drawbgfx.h @@ -32,7 +32,7 @@ class avi_write; class renderer_bgfx : public osd_renderer, public slider_dirty_notifier { public: - renderer_bgfx(osd_window *w); + renderer_bgfx(std::shared_ptr<osd_window> w); virtual ~renderer_bgfx(); static void init(running_machine &machine) { } @@ -55,6 +55,10 @@ public: virtual render_primitive_list *get_primitives() override { + auto win = try_getwindow(); + if (win == nullptr) + return nullptr; + // determines whether the screen container is transformed by the chain's shaders bool chain_transform = false; @@ -65,10 +69,10 @@ public: chain_transform = chain->transform(); } - osd_dim wdim = window().get_size(); - window().target()->set_bounds(wdim.width(), wdim.height(), window().pixel_aspect()); - window().target()->set_transform_container(!chain_transform); - return &window().target()->get_primitives(); + osd_dim wdim = win->get_size(); + win->target()->set_bounds(wdim.width(), wdim.height(), win->pixel_aspect()); + win->target()->set_transform_container(!chain_transform); + return &win->target()->get_primitives(); } static const char* WINDOW_PREFIX; diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp index e28c3e7928a..6c682a80409 100644 --- a/src/osd/modules/render/drawd3d.cpp +++ b/src/osd/modules/render/drawd3d.cpp @@ -199,19 +199,22 @@ void renderer_d3d9::save() render_primitive_list *renderer_d3d9::get_primitives() { RECT client; + auto win = try_getwindow(); + if (win == nullptr) + return nullptr; - GetClientRectExceptMenu(window().platform_window<HWND>(), &client, window().fullscreen()); + GetClientRectExceptMenu(win->platform_window<HWND>(), &client, win->fullscreen()); if (rect_width(&client) > 0 && rect_height(&client) > 0) { - window().target()->set_bounds(rect_width(&client), rect_height(&client), window().pixel_aspect()); - window().target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh()); + win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect()); + win->target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh()); } if (m_shaders != nullptr) { // do not transform primitives (scale, offset) if shaders are enabled, the shaders will handle the transformation - window().target()->set_transform_container(!m_shaders->enabled()); + win->target()->set_transform_container(!m_shaders->enabled()); } - return &window().target()->get_primitives(); + return &win->target()->get_primitives(); } @@ -410,8 +413,10 @@ d3d_texture_manager::d3d_texture_manager(renderer_d3d9 *d3d) } osd_printf_verbose("Direct3D: YUV format = %s\n", (m_yuv_format == D3DFMT_YUY2) ? "YUY2" : (m_yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB"); + auto win = d3d->assert_window(); + // set the max texture size - d3d->window().target()->set_max_texture_size(m_texture_max_width, m_texture_max_height); + win->target()->set_max_texture_size(m_texture_max_width, m_texture_max_height); osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height); } @@ -421,9 +426,11 @@ d3d_texture_manager::~d3d_texture_manager() void d3d_texture_manager::create_resources() { + auto win = m_renderer->assert_window(); + // experimental: load a PNG to use for vector rendering; it is treated // as a brightness map - emu_file file(m_renderer->window().machine().options().art_path(), OPEN_FLAG_READ); + emu_file file(win->machine().options().art_path(), OPEN_FLAG_READ); render_load_png(m_vector_bitmap, file, nullptr, "vector.png"); if (m_vector_bitmap.valid()) { @@ -447,7 +454,7 @@ void d3d_texture_manager::create_resources() texture.seqid = 0; // now create it - m_default_texture = global_alloc(texture_info(this, &texture, m_renderer->window().prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32))); + m_default_texture = global_alloc(texture_info(this, &texture, win->prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32))); } // experimental: if we have a vector bitmap, create a texture for it @@ -464,7 +471,7 @@ void d3d_texture_manager::create_resources() texture.seqid = 0; // now create it - m_vector_texture = global_alloc(texture_info(this, &texture, m_renderer->window().prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32))); + m_vector_texture = global_alloc(texture_info(this, &texture, win->prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32))); } } @@ -564,7 +571,7 @@ texture_info *d3d_texture_manager::find_texinfo(const render_texinfo *texinfo, U return nullptr; } -renderer_d3d9::renderer_d3d9(osd_window *window) +renderer_d3d9::renderer_d3d9(std::shared_ptr<osd_window> window) : osd_renderer(window, FLAG_NONE), m_adapter(0), m_width(0), m_height(0), m_refresh(0), m_create_error_count(0), m_device(nullptr), m_gamma_supported(0), m_pixformat(), m_vertexbuf(nullptr), m_lockedbuf(nullptr), m_numverts(0), m_vectorbatch(nullptr), m_batchindex(0), m_numpolys(0), m_restarting(false), m_mod2x_supported(0), m_mod4x_supported(0), m_screen_format(), m_last_texture(nullptr), m_last_texture_flags(0), m_last_blendenable(0), m_last_blendop(0), m_last_blendsrc(0), m_last_blenddst(0), m_last_filter(0), @@ -581,7 +588,8 @@ int renderer_d3d9::initialize() } // create the device immediately for the full screen case (defer for window mode) - if (window().fullscreen() && device_create(window().m_main->platform_window<HWND>())) + auto win = assert_window(); + if (win->fullscreen() && device_create(win->main_window()->platform_window<HWND>())) { return false; } @@ -591,8 +599,10 @@ int renderer_d3d9::initialize() int renderer_d3d9::pre_window_draw_check() { + auto win = assert_window(); + // if we're in the middle of resizing, leave things alone - if (window().m_resize_state == RESIZE_STATE_RESIZING) + if (win->m_resize_state == RESIZE_STATE_RESIZING) return 0; // if we're restarting the renderer, leave things alone @@ -614,7 +624,7 @@ int renderer_d3d9::pre_window_draw_check() } // in window mode, we need to track the window size - if (!window().fullscreen() || m_device == nullptr) + if (!win->fullscreen() || m_device == nullptr) { // if the size changes, skip this update since the render target will be out of date if (update_window_size()) @@ -630,7 +640,9 @@ int renderer_d3d9::pre_window_draw_check() void d3d_texture_manager::update_textures() { - for (render_primitive &prim : *m_renderer->window().m_primlist) + auto win = m_renderer->assert_window(); + + for (render_primitive &prim : *win->m_primlist) { if (prim.texture.base != nullptr) { @@ -645,7 +657,7 @@ void d3d_texture_manager::update_textures() else { // if there isn't one, create a new texture - texture = global_alloc(texture_info(this, &prim.texture, m_renderer->window().prescale(), prim.flags)); + texture = global_alloc(texture_info(this, &prim.texture, win->prescale(), prim.flags)); } } else @@ -681,12 +693,14 @@ void d3d_texture_manager::update_textures() void renderer_d3d9::begin_frame() { + auto win = assert_window(); + HRESULT result = (*d3dintf->device.clear)(m_device, 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); m_shaders->begin_frame(); - window().m_primlist->acquire_lock(); + win->m_primlist->acquire_lock(); // first update any textures m_texture_manager->update_textures(); @@ -706,7 +720,7 @@ void renderer_d3d9::begin_frame() // loop over line primitives m_line_count = 0; - for (render_primitive &prim : *window().m_primlist) + for (render_primitive &prim : *win->m_primlist) { if (prim.type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim.flags)) { @@ -717,8 +731,10 @@ void renderer_d3d9::begin_frame() void renderer_d3d9::process_primitives() { + auto win = assert_window(); + // Rotating index for vector time offsets - for (render_primitive &prim : *window().m_primlist) + for (render_primitive &prim : *win->m_primlist) { switch (prim.type) { @@ -748,7 +764,9 @@ void renderer_d3d9::process_primitives() void renderer_d3d9::end_frame() { - window().m_primlist->release_lock(); + auto win = assert_window(); + + win->m_primlist->release_lock(); // flush any pending polygons primitive_flush_pending(); @@ -819,6 +837,8 @@ try_again: } } + auto win = assert_window(); + // initialize the D3D presentation parameters memset(&m_presentation, 0, sizeof(m_presentation)); m_presentation.BackBufferWidth = m_width; @@ -827,13 +847,13 @@ try_again: m_presentation.BackBufferCount = video_config.triplebuf ? 2 : 1; m_presentation.MultiSampleType = D3DMULTISAMPLE_NONE; m_presentation.SwapEffect = D3DSWAPEFFECT_DISCARD; - m_presentation.hDeviceWindow = window().platform_window<HWND>(); - m_presentation.Windowed = !window().fullscreen() || window().win_has_menu(); + m_presentation.hDeviceWindow = win->platform_window<HWND>(); + m_presentation.Windowed = !win->fullscreen() || win->win_has_menu(); m_presentation.EnableAutoDepthStencil = FALSE; m_presentation.AutoDepthStencilFormat = D3DFMT_D16; m_presentation.Flags = 0; m_presentation.FullScreen_RefreshRateInHz = m_refresh; - m_presentation.PresentationInterval = ((video_config.triplebuf && window().fullscreen()) || + m_presentation.PresentationInterval = ((video_config.triplebuf && win->fullscreen()) || video_config.waitvsync || video_config.syncrefresh) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; @@ -861,10 +881,10 @@ try_again: osd_printf_verbose("Direct3D: Device created at %dx%d\n", m_width, m_height); // set the gamma if we need to - if (window().fullscreen()) + if (win->fullscreen()) { // only set the gamma if it's not 1.0f - windows_options &options = downcast<windows_options &>(window().machine().options()); + windows_options &options = downcast<windows_options &>(win->machine().options()); float brightness = options.full_screen_brightness(); float contrast = options.full_screen_contrast(); float gamma = options.full_screen_gamma(); @@ -896,7 +916,7 @@ try_again: } m_shaders = (shaders*)global_alloc_clear<shaders>(); - m_shaders->init(d3dintf, &window().machine(), this); + m_shaders->init(d3dintf, &win->machine(), this); m_sliders.clear(); int failed = m_shaders->create_resources(false, m_sliders); @@ -1194,13 +1214,15 @@ int renderer_d3d9::config_adapter_mode() return 1; } + auto win = assert_window(); + // choose a resolution: window mode case - if (!window().fullscreen() || !video_config.switchres || window().win_has_menu()) + if (!win->fullscreen() || !video_config.switchres || win->win_has_menu()) { RECT client; // bounds are from the window client rect - GetClientRectExceptMenu(window().platform_window<HWND>(), &client, window().fullscreen()); + GetClientRectExceptMenu(win->platform_window<HWND>(), &client, win->fullscreen()); m_width = client.right - client.left; m_height = client.bottom - client.top; @@ -1211,7 +1233,7 @@ int renderer_d3d9::config_adapter_mode() // make sure it's a pixel format we can get behind if (m_pixformat != D3DFMT_X1R5G5B5 && m_pixformat != D3DFMT_R5G6B5 && m_pixformat != D3DFMT_X8R8G8B8) { - osd_printf_error("Device %s currently in an unsupported mode\n", window().monitor()->devicename()); + osd_printf_error("Device %s currently in an unsupported mode\n", win->monitor()->devicename()); return 1; } } @@ -1231,10 +1253,10 @@ int renderer_d3d9::config_adapter_mode() } // see if we can handle the device type - result = (*d3dintf->d3d.check_device_type)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !window().fullscreen()); + result = (*d3dintf->d3d.check_device_type)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !win->fullscreen()); if (result != D3D_OK) { - osd_printf_error("Proposed video mode not supported on device %s\n", window().monitor()->devicename()); + osd_printf_error("Proposed video mode not supported on device %s\n", win->monitor()->devicename()); return 1; } return 0; @@ -1249,6 +1271,8 @@ int renderer_d3d9::get_adapter_for_monitor() { int maxadapter = (*d3dintf->d3d.get_adapter_count)(d3dintf); + auto win = assert_window(); + // iterate over adapters until we error or find a match for (int adapternum = 0; adapternum < maxadapter; adapternum++) { @@ -1256,7 +1280,7 @@ int renderer_d3d9::get_adapter_for_monitor() HMONITOR curmonitor = (*d3dintf->d3d.get_adapter_monitor)(d3dintf, adapternum); // if we match the proposed monitor, this is it - if (curmonitor == *((HMONITOR *)window().monitor()->oshandle())) + if (curmonitor == *((HMONITOR *)win->monitor()->oshandle())) { return adapternum; } @@ -1277,8 +1301,10 @@ void renderer_d3d9::pick_best_mode() INT32 minwidth, minheight; float best_score = 0.0f; + auto win = assert_window(); + // determine the refresh rate of the primary screen - const screen_device *primary_screen = window().machine().config().first_screen(); + const screen_device *primary_screen = win->machine().config().first_screen(); if (primary_screen != nullptr) { target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds()); @@ -1288,7 +1314,7 @@ void renderer_d3d9::pick_best_mode() // note: technically we should not be calling this from an alternate window // thread; however, it is only done during init time, and the init code on // the main thread is waiting for us to finish, so it is safe to do so here - window().target()->compute_minimum_size(minwidth, minheight); + win->target()->compute_minimum_size(minwidth, minheight); // use those as the target for now INT32 target_width = minwidth; @@ -1323,7 +1349,7 @@ void renderer_d3d9::pick_best_mode() size_score *= 0.1f; // if we're looking for a particular mode, that's a winner - if (mode.Width == window().m_win_config.width && mode.Height == window().m_win_config.height) + if (mode.Width == win->m_win_config.width && mode.Height == win->m_win_config.height) size_score = 2.0f; // compute refresh score @@ -1334,7 +1360,7 @@ void renderer_d3d9::pick_best_mode() refresh_score *= 0.1f; // if we're looking for a particular refresh, make sure it matches - if (mode.RefreshRate == window().m_win_config.refresh) + if (mode.RefreshRate == win->m_win_config.refresh) refresh_score = 2.0f; // weight size and refresh equally @@ -1361,31 +1387,33 @@ void renderer_d3d9::pick_best_mode() int renderer_d3d9::update_window_size() { + auto win = assert_window(); + // get the current window bounds RECT client; - GetClientRectExceptMenu(window().platform_window<HWND>(), &client, window().fullscreen()); + GetClientRectExceptMenu(win->platform_window<HWND>(), &client, win->fullscreen()); // if we have a device and matching width/height, nothing to do if (m_device != nullptr && rect_width(&client) == m_width && rect_height(&client) == m_height) { // clear out any pending resizing if the area didn't change - if (window().m_resize_state == RESIZE_STATE_PENDING) - window().m_resize_state = RESIZE_STATE_NORMAL; + if (win->m_resize_state == RESIZE_STATE_PENDING) + win->m_resize_state = RESIZE_STATE_NORMAL; return FALSE; } // if we're in the middle of resizing, leave it alone as well - if (window().m_resize_state == RESIZE_STATE_RESIZING) + if (win->m_resize_state == RESIZE_STATE_RESIZING) return FALSE; // set the new bounds and create the device again m_width = rect_width(&client); m_height = rect_height(&client); - if (window().m_main != nullptr && device_create(window().m_main->platform_window<HWND>())) + if (device_create(win->main_window()->platform_window<HWND>())) return FALSE; // reset the resize state to normal, and indicate we made a change - window().m_resize_state = RESIZE_STATE_NORMAL; + win->m_resize_state = RESIZE_STATE_NORMAL; return TRUE; } @@ -1396,7 +1424,9 @@ int renderer_d3d9::update_window_size() void renderer_d3d9::batch_vectors() { - windows_options &options = downcast<windows_options &>(window().machine().options()); + auto win = assert_window(); + + windows_options &options = downcast<windows_options &>(win->machine().options()); float quad_width = 0.0f; float quad_height = 0.0f; @@ -1409,7 +1439,7 @@ void renderer_d3d9::batch_vectors() int line_index = 0; float period = options.screen_vector_time_period(); UINT32 cached_flags = 0; - for (render_primitive &prim : *window().m_primlist) + for (render_primitive &prim : *win->m_primlist) { switch (prim.type) { @@ -1447,15 +1477,15 @@ void renderer_d3d9::batch_vectors() if (m_shaders->enabled()) { bool orientation_swap_xy = - (window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; + (win->machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; bool rotation_swap_xy = - (window().target()->orientation() & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; + (win->target()->orientation() & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; bool swap_xy = orientation_swap_xy ^ rotation_swap_xy; - bool rotation_0 = window().target()->orientation() == ROT0; - bool rotation_90 = window().target()->orientation() == ROT90; - bool rotation_180 = window().target()->orientation() == ROT180; - bool rotation_270 = window().target()->orientation() == ROT270; + bool rotation_0 = win->target()->orientation() == ROT0; + bool rotation_90 = win->target()->orientation() == ROT90; + bool rotation_180 = win->target()->orientation() == ROT180; + bool rotation_270 = win->target()->orientation() == ROT270; bool flip_x = ((rotation_0 || rotation_270) && orientation_swap_xy) || ((rotation_180 || rotation_270) && !orientation_swap_xy); @@ -2074,7 +2104,9 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t m_yprescale--; } - int prescale = m_renderer->window().prescale(); + auto win = m_renderer->assert_window(); + + int prescale = win->prescale(); if (m_xprescale != prescale || m_yprescale != prescale) { osd_printf_verbose("Direct3D: adjusting prescale from %dx%d to %dx%d\n", prescale, prescale, m_xprescale, m_yprescale); @@ -2941,7 +2973,7 @@ bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_w } bool vector_screen = - d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR; + d3d->assert_window()->machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR; float scale_factor = 0.75f; int scale_count = vector_screen ? MAX_BLOOM_COUNT : MAX_BLOOM_COUNT / 2; diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h index 672ff6482bb..0777da977b0 100644 --- a/src/osd/modules/render/drawd3d.h +++ b/src/osd/modules/render/drawd3d.h @@ -40,7 +40,7 @@ class poly_info; class renderer_d3d9 : public osd_renderer { public: - renderer_d3d9(osd_window *window); + renderer_d3d9(std::shared_ptr<osd_window> window); virtual ~renderer_d3d9(); static bool init(running_machine &machine); diff --git a/src/osd/modules/render/drawgdi.cpp b/src/osd/modules/render/drawgdi.cpp index bfc949e5296..6d6b98218b6 100644 --- a/src/osd/modules/render/drawgdi.cpp +++ b/src/osd/modules/render/drawgdi.cpp @@ -45,10 +45,14 @@ int renderer_gdi::create() render_primitive_list *renderer_gdi::get_primitives() { + auto win = try_getwindow(); + if (win == nullptr) + return nullptr; + RECT client; - GetClientRect(window().platform_window<HWND>(), &client); - window().target()->set_bounds(rect_width(&client), rect_height(&client), window().pixel_aspect()); - return &window().target()->get_primitives(); + GetClientRect(win->platform_window<HWND>(), &client); + win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect()); + return &win->target()->get_primitives(); } //============================================================ @@ -57,13 +61,15 @@ render_primitive_list *renderer_gdi::get_primitives() int renderer_gdi::draw(const int update) { + auto win = assert_window(); + // we don't have any special resize behaviors - if (window().m_resize_state == RESIZE_STATE_PENDING) - window().m_resize_state = RESIZE_STATE_NORMAL; + if (win->m_resize_state == RESIZE_STATE_PENDING) + win->m_resize_state = RESIZE_STATE_NORMAL; // get the target bounds RECT bounds; - GetClientRect(window().platform_window<HWND>(), &bounds); + GetClientRect(win->platform_window<HWND>(), &bounds); // compute width/height/pitch of target int width = rect_width(&bounds); @@ -79,16 +85,16 @@ int renderer_gdi::draw(const int update) } // draw the primitives to the bitmap - window().m_primlist->acquire_lock(); - software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, m_bmdata, width, height, pitch); - window().m_primlist->release_lock(); + win->m_primlist->acquire_lock(); + software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, m_bmdata, width, height, pitch); + win->m_primlist->release_lock(); // fill in bitmap-specific info m_bminfo.bmiHeader.biWidth = pitch; m_bminfo.bmiHeader.biHeight = -height; // blit to the screen - StretchDIBits(window().m_dc, 0, 0, width, height, + StretchDIBits(win->m_dc, 0, 0, width, height, 0, 0, width, height, m_bmdata, &m_bminfo, DIB_RGB_COLORS, SRCCOPY); return 0; diff --git a/src/osd/modules/render/drawgdi.h b/src/osd/modules/render/drawgdi.h index 7606bf14738..319ef9802e6 100644 --- a/src/osd/modules/render/drawgdi.h +++ b/src/osd/modules/render/drawgdi.h @@ -29,7 +29,7 @@ class renderer_gdi : public osd_renderer { public: - renderer_gdi(osd_window *window) + renderer_gdi(std::shared_ptr<osd_window> window) : osd_renderer(window, FLAG_NONE) , m_bmdata(nullptr) , m_bmsize(0) diff --git a/src/osd/modules/render/drawnone.cpp b/src/osd/modules/render/drawnone.cpp index 5e261daafe2..f6bde9d868f 100644 --- a/src/osd/modules/render/drawnone.cpp +++ b/src/osd/modules/render/drawnone.cpp @@ -21,8 +21,12 @@ render_primitive_list *renderer_none::get_primitives() { + auto win = try_getwindow(); + if (win == nullptr) + return nullptr; + RECT client; - GetClientRect(window().platform_window<HWND>(), &client); - window().target()->set_bounds(rect_width(&client), rect_height(&client), window().pixel_aspect()); - return &window().target()->get_primitives(); + GetClientRect(win->platform_window<HWND>(), &client); + win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect()); + return &win->target()->get_primitives(); } diff --git a/src/osd/modules/render/drawnone.h b/src/osd/modules/render/drawnone.h index 08873860e61..1fc4a50b689 100644 --- a/src/osd/modules/render/drawnone.h +++ b/src/osd/modules/render/drawnone.h @@ -17,7 +17,7 @@ class renderer_none : public osd_renderer { public: - renderer_none(osd_window *window) + renderer_none(std::shared_ptr<osd_window> window) : osd_renderer(window, FLAG_NONE) { } virtual ~renderer_none() { } diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp index a7ffe24a5df..01d8085efd7 100644 --- a/src/osd/modules/render/drawogl.cpp +++ b/src/osd/modules/render/drawogl.cpp @@ -559,11 +559,13 @@ void renderer_ogl::initialize_gl() int renderer_ogl::create() { + auto win = assert_window(); + // create renderer #if defined(OSD_WINDOWS) - m_gl_context = global_alloc(win_gl_context(window().platform_window<HWND>())); + m_gl_context = global_alloc(win_gl_context(win->platform_window<HWND>())); #else - m_gl_context = global_alloc(sdl_gl_context(window().platform_window<SDL_Window*>())); + m_gl_context = global_alloc(sdl_gl_context(win->platform_window<SDL_Window*>())); #endif if (m_gl_context->LastErrorMsg() != nullptr) { @@ -627,12 +629,19 @@ void renderer_ogl::destroy_all_textures() if ( !m_initialized ) return; + auto win = try_getwindow(); + + // During destroy this can get called + // and the window is no longer available + if (win == nullptr) + return; + m_gl_context->MakeCurrent(); - if(window().m_primlist) + if(win->m_primlist) { lock=TRUE; - window().m_primlist->acquire_lock(); + win->m_primlist->acquire_lock(); } glFinish(); @@ -694,7 +703,7 @@ void renderer_ogl::destroy_all_textures() m_initialized = 0; if (lock) - window().m_primlist->release_lock(); + win->m_primlist->release_lock(); } //============================================================ // loadGLExtensions @@ -914,7 +923,7 @@ void renderer_ogl::loadGLExtensions() if ( m_useglsl ) { - if ( window().prescale() != 1 ) + if (assert_window()->prescale() != 1 ) { m_useglsl = 0; if (_once) @@ -1023,7 +1032,9 @@ int renderer_ogl::draw(const int update) } #endif - osd_dim wdim = window().get_size(); + auto win = assert_window(); + + osd_dim wdim = win->get_size(); if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height)) { @@ -1074,7 +1085,7 @@ int renderer_ogl::draw(const int update) // we're doing nothing 3d, so the Z-buffer is currently not interesting glDisable(GL_DEPTH_TEST); - if (window().machine().options().antialias()) + if (win->machine().options().antialias()) { // enable antialiasing for lines glEnable(GL_LINE_SMOOTH); @@ -1154,10 +1165,10 @@ int renderer_ogl::draw(const int update) m_last_hofs = hofs; m_last_vofs = vofs; - window().m_primlist->acquire_lock(); + win->m_primlist->acquire_lock(); // now draw - for (render_primitive &prim : *window().m_primlist) + for (render_primitive &prim : *win->m_primlist) { int i; @@ -1373,7 +1384,7 @@ int renderer_ogl::draw(const int update) pendingPrimitive=GL_NO_PRIMITIVE; } - window().m_primlist->release_lock(); + win->m_primlist->release_lock(); m_init_context = 0; m_gl_context->SwapBuffer(); @@ -1508,8 +1519,10 @@ void renderer_ogl::texture_compute_size_subroutine(ogl_texture_info *texture, UI texture->xprescale--; while (texture->yprescale > 1 && height_create * texture->yprescale > m_texture_max_height) texture->yprescale--; - if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != window().prescale() || texture->yprescale != window().prescale())) - osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", window().prescale(), window().prescale(), texture->xprescale, texture->yprescale); + + auto win = assert_window(); + if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != win->prescale() || texture->yprescale != win->prescale())) + osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", win->prescale(), win->prescale(), texture->xprescale, texture->yprescale); width *= texture->xprescale; height *= texture->yprescale; @@ -1871,8 +1884,9 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource, texture->texinfo.seqid = -1; // force set data if (PRIMFLAG_GET_SCREENTEX(flags)) { - texture->xprescale = window().prescale(); - texture->yprescale = window().prescale(); + auto win = assert_window(); + texture->xprescale = win->prescale(); + texture->yprescale = win->prescale(); } else { diff --git a/src/osd/modules/render/drawogl.h b/src/osd/modules/render/drawogl.h index 7b89040e925..6b959f1da35 100644 --- a/src/osd/modules/render/drawogl.h +++ b/src/osd/modules/render/drawogl.h @@ -95,7 +95,7 @@ public: class renderer_ogl : public osd_renderer { public: - renderer_ogl(osd_window *window) + renderer_ogl(std::shared_ptr<osd_window> window) : osd_renderer(window, FLAG_NEEDS_OPENGL) , m_blittimer(0) , m_width(0) @@ -141,14 +141,18 @@ public: #endif virtual render_primitive_list *get_primitives() override { - osd_dim nd = window().get_size(); + auto win = try_getwindow(); + if (win == nullptr) + return nullptr; + + osd_dim nd = win->get_size(); if (nd != m_blit_dim) { m_blit_dim = nd; notify_changed(); } - window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect()); - return &window().target()->get_primitives(); + win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect()); + return &win->target()->get_primitives(); } #ifdef OSD_WINDOWS diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp index af597516633..72d2f4c4c91 100644 --- a/src/osd/modules/render/drawsdl.cpp +++ b/src/osd/modules/render/drawsdl.cpp @@ -105,8 +105,10 @@ void renderer_sdl1::setup_texture(const osd_dim &size) SDL_DisplayMode mode; UINT32 fmt; + auto win = assert_window(); + // Determine preferred pixelformat and set up yuv if necessary - SDL_GetCurrentDisplayMode(*((UINT64 *)window().monitor()->oshandle()), &mode); + SDL_GetCurrentDisplayMode(*((UINT64 *)win->monitor()->oshandle()), &mode); if (m_yuv_bitmap) { @@ -121,11 +123,11 @@ void renderer_sdl1::setup_texture(const osd_dim &size) int m_hw_scale_width = 0; int m_hw_scale_height = 0; - window().target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height); - if (window().prescale()) + win->target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height); + if (win->prescale()) { - m_hw_scale_width *= window().prescale(); - m_hw_scale_height *= window().prescale(); + m_hw_scale_width *= win->prescale(); + m_hw_scale_height *= win->prescale(); /* This must be a multiple of 2 */ m_hw_scale_width = (m_hw_scale_width + 1) & ~1; @@ -185,6 +187,7 @@ int renderer_sdl1::create() { const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode]; + auto win = assert_window(); // create renderer /* set hints ... */ @@ -192,16 +195,16 @@ int renderer_sdl1::create() if (video_config.waitvsync) - m_sdl_renderer = SDL_CreateRenderer(window().platform_window<SDL_Window*>(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); + m_sdl_renderer = SDL_CreateRenderer(win->platform_window<SDL_Window*>(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); else - m_sdl_renderer = SDL_CreateRenderer(window().platform_window<SDL_Window*>(), -1, SDL_RENDERER_ACCELERATED); + m_sdl_renderer = SDL_CreateRenderer(win->platform_window<SDL_Window*>(), -1, SDL_RENDERER_ACCELERATED); if (!m_sdl_renderer) { if (video_config.waitvsync) - m_sdl_renderer = SDL_CreateRenderer(window().platform_window<SDL_Window*>(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE); + m_sdl_renderer = SDL_CreateRenderer(win->platform_window<SDL_Window*>(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE); else - m_sdl_renderer = SDL_CreateRenderer(window().platform_window<SDL_Window*>(), -1, SDL_RENDERER_SOFTWARE); + m_sdl_renderer = SDL_CreateRenderer(win->platform_window<SDL_Window*>(), -1, SDL_RENDERER_SOFTWARE); } if (!m_sdl_renderer) @@ -311,7 +314,9 @@ int renderer_sdl1::draw(int update) return 0; } - osd_dim wdim = window().get_size(); + auto win = assert_window(); + + osd_dim wdim = win->get_size(); if (has_flags(FI_CHANGED) || (wdim != m_last_dim)) { destroy_all_textures(); @@ -378,7 +383,7 @@ int renderer_sdl1::draw(int update) m_last_hofs = hofs; m_last_vofs = vofs; - window().m_primlist->acquire_lock(); + win->m_primlist->acquire_lock(); int mamewidth, mameheight; @@ -396,7 +401,7 @@ int renderer_sdl1::draw(int update) // FIXME: this could be a lot easier if we get the primlist here! // Bounds would be set fit for purpose and done! - for (render_primitive &prim : *window().m_primlist) + for (render_primitive &prim : *win->m_primlist) { prim.bounds.x0 = floor(fw * prim.bounds.x0 + 0.5f); prim.bounds.x1 = floor(fw * prim.bounds.x1 + 0.5f); @@ -410,23 +415,23 @@ int renderer_sdl1::draw(int update) switch (rmask) { case 0x0000ff00: - software_renderer<UINT32, 0,0,0, 8,16,24>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4); + software_renderer<UINT32, 0,0,0, 8,16,24>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0x00ff0000: - software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4); + software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0x000000ff: - software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4); + software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0xf800: - software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2); + software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 2); break; case 0x7c00: - software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2); + software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 2); break; default: @@ -438,11 +443,11 @@ int renderer_sdl1::draw(int update) { assert (m_yuv_bitmap != nullptr); assert (surfptr != nullptr); - software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, m_yuv_bitmap, mamewidth, mameheight, mamewidth); + software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*win->m_primlist, m_yuv_bitmap, mamewidth, mameheight, mamewidth); sm->yuv_blit((UINT16 *)m_yuv_bitmap, surfptr, pitch, m_yuv_lookup, mamewidth, mameheight); } - window().m_primlist->release_lock(); + win->m_primlist->release_lock(); // unlock and flip SDL_UnlockTexture(m_texture_id); @@ -671,12 +676,16 @@ static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, render_primitive_list *renderer_sdl1::get_primitives() { - osd_dim nd = window().get_size(); + auto win = try_getwindow(); + if (win == nullptr) + return nullptr; + + osd_dim nd = win->get_size(); if (nd != m_blit_dim) { m_blit_dim = nd; notify_changed(); } - window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect()); - return &window().target()->get_primitives(); + win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect()); + return &win->target()->get_primitives(); } diff --git a/src/osd/modules/render/drawsdl.h b/src/osd/modules/render/drawsdl.h index 2958dbf265a..4bdceb69ab7 100644 --- a/src/osd/modules/render/drawsdl.h +++ b/src/osd/modules/render/drawsdl.h @@ -20,7 +20,7 @@ class renderer_sdl1 : public osd_renderer { public: - renderer_sdl1(osd_window *w, int extra_flags) + renderer_sdl1(std::shared_ptr<osd_window> w, int extra_flags) : osd_renderer(w, FLAG_NEEDS_OPENGL | extra_flags) , m_sdl_renderer(nullptr) , m_texture_id(nullptr) diff --git a/src/osd/modules/sound/direct_sound.cpp b/src/osd/modules/sound/direct_sound.cpp index 83b7edd65ca..5b20cfb61fa 100644 --- a/src/osd/modules/sound/direct_sound.cpp +++ b/src/osd/modules/sound/direct_sound.cpp @@ -404,10 +404,10 @@ HRESULT sound_direct_sound::dsound_init() #ifdef SDLMAME_WIN32 SDL_SysWMinfo wminfo; SDL_VERSION(&wminfo.version); - SDL_GetWindowWMInfo(sdl_window_list->platform_window<SDL_Window*>(), &wminfo); + SDL_GetWindowWMInfo(sdl_window_list.front()->platform_window<SDL_Window*>(), &wminfo); HWND const window = wminfo.info.win.window; #else // SDLMAME_WIN32 - HWND const window = win_window_list->platform_window<HWND>(); + HWND const window = win_window_list.front()->platform_window<HWND>(); #endif // SDLMAME_WIN32 result = m_dsound->SetCooperativeLevel(window, DSSCL_PRIORITY); } diff --git a/src/osd/sdl/video.cpp b/src/osd/sdl/video.cpp index 099c4bccfc9..3aafee31dcc 100644 --- a/src/osd/sdl/video.cpp +++ b/src/osd/sdl/video.cpp @@ -82,7 +82,7 @@ bool sdl_osd_interface::video_init() get_resolution(options().resolution(), options().resolution(index), &conf, TRUE); // create window ... - sdl_window_info *win = global_alloc(sdl_window_info(machine(), index, osd_monitor_info::pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf)); + std::shared_ptr<sdl_window_info> win = std::make_shared<sdl_window_info>(machine(), index, osd_monitor_info::pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf); if (win->window_init()) return false; @@ -140,7 +140,7 @@ void sdl_osd_interface::update(bool skip_redraw) if (!skip_redraw) { // profiler_mark(PROFILER_BLIT); - for (sdl_window_info *window = sdl_window_list; window != NULL; window = window->m_next) + for (auto window : sdl_window_list) window->update(); // profiler_mark(PROFILER_END); } @@ -270,20 +270,14 @@ finishit: static void check_osd_inputs(running_machine &machine) { - sdl_window_info *window = sdl_window_list; - // check for toggling fullscreen mode if (machine.ui_input().pressed(IPT_OSD_1)) { - sdl_window_info *curwin = sdl_window_list; - - while (curwin != (sdl_window_info *)NULL) - { + for (auto curwin : sdl_window_list) curwin->toggle_full_screen(); - curwin = curwin->m_next; - } } + auto window = sdl_window_list.front(); if (machine.ui_input().pressed(IPT_OSD_2)) { //FIXME: on a per window basis diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp index ea3843515f7..0f6b94abaaf 100644 --- a/src/osd/sdl/window.cpp +++ b/src/osd/sdl/window.cpp @@ -23,6 +23,8 @@ #ifndef _MSC_VER #include <unistd.h> #endif +#include <list> +#include <memory> // MAME headers @@ -80,14 +82,7 @@ // GLOBAL VARIABLES //============================================================ -sdl_window_info *sdl_window_list; - - -//============================================================ -// LOCAL VARIABLES -//============================================================ - -static sdl_window_info **last_window_ptr; +std::list<std::shared_ptr<sdl_window_info>> sdl_window_list; class SDL_DM_Wrapper { @@ -104,31 +99,33 @@ static SDL_threadID window_threadid; // debugger //static int in_background; -struct worker_param { +class worker_param +{ +public: worker_param() : m_window(nullptr), m_list(nullptr), m_resize_new_width(0), m_resize_new_height(0) { } - worker_param(sdl_window_info *awindow, render_primitive_list &alist) + worker_param(std::shared_ptr<sdl_window_info> awindow, render_primitive_list &alist) : m_window(awindow), m_list(&alist), m_resize_new_width(0), m_resize_new_height(0) { } - worker_param(sdl_window_info *awindow, int anew_width, int anew_height) + worker_param(std::shared_ptr<sdl_window_info> awindow, int anew_width, int anew_height) : m_window(awindow), m_list(nullptr), m_resize_new_width(anew_width), m_resize_new_height(anew_height) { } - worker_param(sdl_window_info *awindow) + worker_param(std::shared_ptr<sdl_window_info> awindow) : m_window(awindow), m_list(nullptr), m_resize_new_width(0), m_resize_new_height(0) { } - sdl_window_info *window() const { assert(m_window != nullptr); return m_window; } + std::shared_ptr<sdl_window_info> window() const { assert(m_window != nullptr); return m_window; } render_primitive_list *list() const { return m_list; } int new_width() const { return m_resize_new_width; } int new_height() const { return m_resize_new_height; } // FIXME: only needed for window set-up which returns an error. - void set_window(sdl_window_info *window) { m_window = window; } + void set_window(std::shared_ptr<sdl_window_info> window) { m_window = window; } private: - sdl_window_info *m_window; + std::shared_ptr<sdl_window_info> m_window; render_primitive_list *m_list; int m_resize_new_width; int m_resize_new_height; @@ -145,20 +142,15 @@ static void sdlwindow_sync(void); // execute_async //============================================================ - -static inline void execute_async(osd_work_callback callback, const worker_param &wp) +// The idea of using unique_ptr here is to make sure the caller isn't holding onto a copy +static inline void execute_async(osd_work_callback callback, std::unique_ptr<worker_param> wp) { - worker_param *wp_temp = (worker_param *) osd_malloc(sizeof(worker_param)); - *wp_temp = wp; - callback((void *) wp_temp, 0); + callback(wp.release(), 0); } -static inline void execute_sync(osd_work_callback callback, const worker_param &wp) +static inline void execute_sync(osd_work_callback callback, std::unique_ptr<worker_param> wp) { - worker_param *wp_temp = (worker_param *) osd_malloc(sizeof(worker_param)); - *wp_temp = wp; - - callback((void *) wp_temp, 0); + callback(wp.release(), 0); } @@ -166,9 +158,9 @@ static inline void execute_sync(osd_work_callback callback, const worker_param & // execute_async_wait //============================================================ -static inline void execute_async_wait(osd_work_callback callback, const worker_param &wp) +static inline void execute_async_wait(osd_work_callback callback, std::unique_ptr<worker_param> wp) { - execute_async(callback, wp); + execute_async(callback, std::move(wp)); sdlwindow_sync(); } @@ -254,7 +246,6 @@ bool sdl_osd_interface::window_init() osd_printf_verbose("\t%-40s %s\n", hints[i], SDL_GetHint(hints[i])); // set up the window list - last_window_ptr = &sdl_window_list; osd_printf_verbose("Leave sdlwindow_init\n"); return true; } @@ -272,10 +263,10 @@ static void sdlwindow_sync(void) void sdl_osd_interface::update_slider_list() { - for (sdl_window_info *window = sdl_window_list; window != nullptr; window = window->m_next) + for (auto window : sdl_window_list) { // check if any window has dirty sliders - if (&window->renderer() && window->renderer().sliders_dirty()) + if (window->renderer().sliders_dirty()) { build_slider_list(); return; @@ -287,7 +278,7 @@ void sdl_osd_interface::build_slider_list() { m_sliders.clear(); - for (sdl_window_info *window = sdl_window_list; window != nullptr; window = window->m_next) + for (auto window : sdl_window_list) { std::vector<ui_menu_item> window_sliders = window->renderer().get_slider_list(); m_sliders.insert(m_sliders.end(), window_sliders.begin(), window_sliders.end()); @@ -309,20 +300,19 @@ static OSDWORK_CALLBACK( sdlwindow_exit_wt ) void sdl_osd_interface::window_exit() { - worker_param wp_dummy; + std::unique_ptr<worker_param> wp_dummy(nullptr); ASSERT_MAIN_THREAD(); osd_printf_verbose("Enter sdlwindow_exit\n"); // free all the windows - while (sdl_window_list != nullptr) + while (!sdl_window_list.empty()) { - sdl_window_info *temp = sdl_window_list; - sdl_window_list = temp->m_next; - temp->destroy(); - // free the window itself - global_free(temp); + auto window = sdl_window_list.front(); + + // Part of destroy removes the window from the list + window->destroy(); } switch(video_config.mode) @@ -345,7 +335,7 @@ void sdl_osd_interface::window_exit() break; } - execute_async_wait(&sdlwindow_exit_wt, wp_dummy); + execute_async_wait(&sdlwindow_exit_wt, std::move(wp_dummy)); osd_printf_verbose("Leave sdlwindow_exit\n"); @@ -384,8 +374,8 @@ void sdl_window_info::show_pointer() OSDWORK_CALLBACK( sdl_window_info::sdlwindow_resize_wt ) { - worker_param * wp = (worker_param *) param; - sdl_window_info * window = wp->window(); + auto wp = std::unique_ptr<worker_param>(static_cast<worker_param*>(param)); + auto window = wp->window(); int width = wp->new_width(); int height = wp->new_height(); @@ -394,7 +384,6 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_resize_wt ) SDL_SetWindowSize(window->platform_window<SDL_Window*>(), width, height); window->renderer().notify_changed(); - osd_free(wp); return nullptr; } @@ -405,7 +394,10 @@ void sdl_window_info::resize(INT32 width, INT32 height) osd_dim cd = get_size(); if (width != cd.width() || height != cd.height()) - execute_async_wait(&sdlwindow_resize_wt, worker_param(this, width, height)); + { + auto wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this()), width, height); + execute_async_wait(&sdlwindow_resize_wt, std::move(wp)); + } } @@ -416,26 +408,24 @@ void sdl_window_info::resize(INT32 width, INT32 height) OSDWORK_CALLBACK( sdl_window_info::notify_changed_wt ) { - worker_param *wp = (worker_param *) param; - sdl_window_info *window = wp->window(); + auto wp = std::unique_ptr<worker_param>(static_cast<worker_param*>(param)); + auto window = wp->window(); ASSERT_WINDOW_THREAD(); window->renderer().notify_changed(); - osd_free(wp); return nullptr; } void sdl_window_info::notify_changed() { - worker_param wp; - + auto wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this())); if (SDL_ThreadID() == main_threadid) { - execute_async_wait(¬ify_changed_wt, worker_param(this)); + execute_async_wait(¬ify_changed_wt, std::move(wp)); } else - execute_sync(¬ify_changed_wt, worker_param(this)); + execute_sync(¬ify_changed_wt, std::move(wp)); } @@ -446,8 +436,8 @@ void sdl_window_info::notify_changed() OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) { - worker_param *wp = (worker_param *) param; - sdl_window_info *window = wp->window(); + auto wp = std::unique_ptr<worker_param>(static_cast<worker_param*>(param)); + auto window = wp->window(); ASSERT_WINDOW_THREAD(); @@ -461,12 +451,6 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) window->m_windowed_dim = window->get_size(); } - if (window->m_renderer != nullptr) - { - delete window->m_renderer; - window->m_renderer = nullptr; - } - bool is_osx = false; #ifdef SDLMAME_MACOSX // FIXME: This is weird behaviour and certainly a bug in SDL @@ -482,7 +466,7 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) downcast<sdl_osd_interface &>(window->machine().osd()).release_keys(); - window->set_renderer(osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(window))); + window->set_renderer(osd_renderer::make_for_type(video_config.mode, window->shared_from_this())); // toggle the window mode window->set_fullscreen(!window->fullscreen()); @@ -495,13 +479,12 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) void sdl_window_info::toggle_full_screen() { ASSERT_MAIN_THREAD(); - - execute_async_wait(&sdlwindow_toggle_full_screen_wt, worker_param(this)); + auto wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this())); + execute_async_wait(&sdlwindow_toggle_full_screen_wt, std::move(wp)); } void sdl_window_info::modify_prescale(int dir) { - worker_param wp = worker_param(this); int new_prescale = prescale(); if (dir > 0 && prescale() < 3) @@ -513,11 +496,13 @@ void sdl_window_info::modify_prescale(int dir) { if (m_fullscreen && video_config.switchres) { - execute_async_wait(&sdlwindow_video_window_destroy_wt, wp); + auto wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this())); + execute_async_wait(&sdlwindow_video_window_destroy_wt, std::move(wp)); m_prescale = new_prescale; - execute_async_wait(&complete_create_wt, wp); + wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this())); + execute_async_wait(&complete_create_wt, std::move(wp)); } else @@ -570,12 +555,11 @@ void sdl_window_info::update_cursor_state() OSDWORK_CALLBACK( sdl_window_info::update_cursor_state_wt ) { - worker_param * wp = (worker_param *) param; - sdl_window_info * window = wp->window(); + auto wp = std::unique_ptr<worker_param>(static_cast<worker_param*>(param)); + auto window = wp->window(); window->update_cursor_state(); - osd_free(wp); return nullptr; } @@ -591,7 +575,6 @@ int sdl_window_info::xy_to_render_target(int x, int y, int *xt, int *yt) int sdl_window_info::window_init() { - worker_param *wp = (worker_param *) osd_malloc(sizeof(worker_param)); int result; ASSERT_MAIN_THREAD(); @@ -602,10 +585,9 @@ int sdl_window_info::window_init() m_startmaximized = options.maximize(); // add us to the list - *last_window_ptr = this; - last_window_ptr = &this->m_next; + sdl_window_list.push_back(std::static_pointer_cast<sdl_window_info>(shared_from_this())); - set_renderer(osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(this))); + set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast<osd_window*>(this)->shared_from_this())); // load the layout m_target = m_machine.render().target_alloc(); @@ -619,9 +601,9 @@ int sdl_window_info::window_init() else sprintf(m_title, "%s: %s [%s] - Screen %d", emulator_info::get_appname(), m_machine.system().description, m_machine.system().name, m_index); - wp->set_window(this); + auto wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this())); - result = *((int *) sdl_window_info::complete_create_wt((void *) wp, 0)); + result = *((int *) sdl_window_info::complete_create_wt(wp.release(), 0)); // handle error conditions if (result == 1) @@ -642,15 +624,11 @@ error: OSDWORK_CALLBACK( sdl_window_info::sdlwindow_video_window_destroy_wt ) { - worker_param * wp = (worker_param *) param; - sdl_window_info * window = wp->window(); + auto wp = std::unique_ptr<worker_param>(static_cast<worker_param*>(param)); + auto window = wp->window(); ASSERT_WINDOW_THREAD(); - // free the textures etc - global_free(window->m_renderer); - window->m_renderer = nullptr; - if (window->fullscreen() && video_config.switchres) { SDL_SetWindowFullscreen(window->platform_window<SDL_Window*>(), 0); // Try to set mode @@ -661,28 +639,21 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_video_window_destroy_wt ) // release all keys ... downcast<sdl_osd_interface &>(window->machine().osd()).release_keys(); - osd_free(wp); return nullptr; } void sdl_window_info::destroy() { - sdl_window_info **prevptr; - ASSERT_MAIN_THREAD(); //osd_event_wait(window->rendered_event, osd_ticks_per_second()*10); // remove us from the list - for (prevptr = &sdl_window_list; *prevptr != nullptr; prevptr = &(*prevptr)->m_next) - if (*prevptr == this) - { - *prevptr = this->m_next; - break; - } + sdl_window_list.remove(std::static_pointer_cast<sdl_window_info>(shared_from_this())); // free the textures etc - execute_async_wait(&sdlwindow_video_window_destroy_wt, worker_param(this)); + auto wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this())); + execute_async_wait(&sdlwindow_video_window_destroy_wt, std::move(wp)); // free the render target, after the textures! this->machine().render().target_free(m_target); @@ -776,7 +747,8 @@ void sdl_window_info::update() // adjust the cursor state //sdlwindow_update_cursor_state(machine, window); - execute_async(&update_cursor_state_wt, worker_param(this)); + auto wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this())); + execute_async(&update_cursor_state_wt, std::move(wp)); // if we're visible and running and not in the middle of a resize, draw if (m_target != nullptr) @@ -810,11 +782,11 @@ void sdl_window_info::update() { // ensure the target bounds are up-to-date, and then get the primitives - render_primitive_list &primlist = *m_renderer->get_primitives(); + render_primitive_list &primlist = *renderer().get_primitives(); // and redraw now - - execute_async(&draw_video_contents_wt, worker_param(this, primlist)); + auto wp = std::make_unique<worker_param>(std::static_pointer_cast<sdl_window_info>(shared_from_this()), primlist); + execute_async(&draw_video_contents_wt, std::move(wp)); } } } @@ -850,14 +822,13 @@ void sdl_window_info::set_starting_view(int index, const char *defview, const ch OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) { - worker_param * wp = (worker_param *) param; - sdl_window_info * window = wp->window(); + auto wp = std::unique_ptr<worker_param>(static_cast<worker_param*>(param)); + auto window = wp->window(); osd_dim temp(0,0); static int result[2] = {0,1}; ASSERT_WINDOW_THREAD(); - osd_free(wp); // clear out original mode. Needed on OSX if (window->fullscreen()) @@ -981,14 +952,19 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) // set main window if (window->m_index > 0) { - for (auto w = sdl_window_list; w != nullptr; w = w->m_next) + for (auto w : sdl_window_list) { if (w->m_index == 0) - { - window->m_main = w; + { + window->set_main_window(std::dynamic_pointer_cast<osd_window>(w)); break; + } + } } - } + else + { + // We must be the main window + window->set_main_window(window); } // update monitor resolution after mode change to ensure proper pixel aspect @@ -1058,8 +1034,8 @@ void sdl_window_info::measure_fps(int update) OSDWORK_CALLBACK( sdl_window_info::draw_video_contents_wt ) { int update = 1; - worker_param *wp = (worker_param *) param; - sdl_window_info *window = wp->window(); + auto wp = std::unique_ptr<worker_param>(static_cast<worker_param*>(param)); + auto window = wp->window(); ASSERT_REDRAW_THREAD(); @@ -1096,7 +1072,6 @@ OSDWORK_CALLBACK( sdl_window_info::draw_video_contents_wt ) /* all done, ready for next */ window->m_rendered_event.set(); - osd_free(wp); return nullptr; } @@ -1363,6 +1338,5 @@ sdl_window_info::sdl_window_info(running_machine &a_machine, int index, osd_moni sdl_window_info::~sdl_window_info() { - global_free(m_renderer); global_free(m_original_mode); } diff --git a/src/osd/sdl/window.h b/src/osd/sdl/window.h index 14ee6e3c19a..403c12a8e46 100644 --- a/src/osd/sdl/window.h +++ b/src/osd/sdl/window.h @@ -17,6 +17,8 @@ #include "modules/osdwindow.h" #include <cstdint> +#include <memory> +#include <list> //============================================================ @@ -65,7 +67,6 @@ public: render_target *target() override { return m_target; } int prescale() const { return m_prescale; } - osd_renderer &renderer() const { return *m_renderer; } // Pointer to next window sdl_window_info * m_next; @@ -88,11 +89,6 @@ private: int m_extra_flags; - void set_renderer(osd_renderer *renderer) - { - m_renderer = renderer; - } - static OSDWORK_CALLBACK( complete_create_wt ); private: @@ -111,7 +107,6 @@ private: // monitor info osd_monitor_info * m_monitor; int m_fullscreen; - osd_renderer * m_renderer; // static callbacks ... @@ -136,7 +131,7 @@ struct osd_draw_callbacks //============================================================ // window - list -extern sdl_window_info *sdl_window_list; +extern std::list<std::shared_ptr<sdl_window_info>> sdl_window_list; //============================================================ // PROTOTYPES diff --git a/src/osd/windows/video.cpp b/src/osd/windows/video.cpp index c4ee864389a..d394a3e1821 100644 --- a/src/osd/windows/video.cpp +++ b/src/osd/windows/video.cpp @@ -81,7 +81,7 @@ bool windows_osd_interface::video_init() } if (video_config.mode != VIDEO_MODE_NONE) - SetForegroundWindow(win_window_list->platform_window<HWND>()); + SetForegroundWindow(win_window_list.front()->platform_window<HWND>()); return true; } @@ -170,7 +170,7 @@ void windows_osd_interface::update(bool skip_redraw) if (!skip_redraw) { // profiler_mark(PROFILER_BLIT); - for (win_window_info *window = win_window_list; window != NULL; window = window->m_next) + for (auto window : win_window_list) window->update(); // profiler_mark(PROFILER_END); } diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp index 1bae62625f3..f5534a13544 100644 --- a/src/osd/windows/window.cpp +++ b/src/osd/windows/window.cpp @@ -17,6 +17,8 @@ #include <atomic> #include <chrono> +#include <list> +#include <memory> // MAME headers #include "emu.h" @@ -87,8 +89,7 @@ using namespace Windows::UI::Core; // GLOBAL VARIABLES //============================================================ -win_window_info *win_window_list; -static win_window_info **last_window_ptr; +std::list<std::shared_ptr<win_window_info>> win_window_list; static DWORD main_threadid; // actual physical resolution @@ -250,15 +251,12 @@ bool windows_osd_interface::window_init() } 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) + for (auto window : win_window_list) { // check if any window has dirty sliders if (window->m_renderer && window->m_renderer->sliders_dirty()) @@ -271,19 +269,14 @@ void windows_osd_interface::update_slider_list() int windows_osd_interface::window_count() { - int count = 0; - for (win_window_info *info = win_window_list; info != nullptr; info = info->m_next) - { - count++; - } - return count; + return win_window_list.size(); } void windows_osd_interface::build_slider_list() { m_sliders.clear(); - for (win_window_info *window = win_window_list; window != nullptr; window = window->m_next) + for (auto window : win_window_list) { // take the sliders of the first window std::vector<ui_menu_item> window_sliders = window->m_renderer->get_slider_list(); @@ -293,7 +286,7 @@ void windows_osd_interface::build_slider_list() void windows_osd_interface::add_audio_to_recording(const INT16 *buffer, int samples_this_frame) { - win_window_info *window = win_window_list; // We only record on the first window + auto window = win_window_list.front(); // We only record on the first window if (window != nullptr && window->m_renderer != nullptr) { window->m_renderer->add_audio_to_recording(buffer, samples_this_frame); @@ -310,15 +303,16 @@ void windows_osd_interface::window_exit() assert(GetCurrentThreadId() == main_threadid); // if we hid the cursor during the emulation, show it - win_window_list->show_pointer(); + if (!win_window_list.empty()) + win_window_list.front()->show_pointer(); // free all the windows - while (win_window_list != nullptr) + while (!win_window_list.empty()) { - win_window_info *temp = win_window_list; - win_window_list = temp->m_next; - temp->destroy(); - global_free(temp); + auto window = win_window_list.front(); + + // Destroy removes it from the list also + window->destroy(); } switch(video_config.mode) @@ -353,14 +347,18 @@ void windows_osd_interface::window_exit() CloseHandle(window_thread_ready_event); } -win_window_info::win_window_info(running_machine &machine) - : osd_window(), m_next(nullptr), +win_window_info::win_window_info( + running_machine &machine, + int index, + osd_monitor_info *monitor, + const osd_window_config *config) : osd_window(), + m_next(nullptr), m_init_state(0), m_startmaximized(0), m_isminimized(0), m_ismaximized(0), - m_monitor(nullptr), - m_fullscreen(0), + m_monitor(monitor), + //m_fullscreen(0), m_fullscreen_safe(0), m_aspect(0), m_target(nullptr), @@ -378,14 +376,12 @@ win_window_info::win_window_info(running_machine &machine) m_non_fullscreen_bounds.right = 0; m_non_fullscreen_bounds.bottom = 0; m_prescale = video_config.prescale; + + } win_window_info::~win_window_info() { - if (m_renderer != nullptr) - { - delete m_renderer; - } } POINT win_window_info::s_saved_cursor_pos = { -1, -1 }; @@ -480,7 +476,7 @@ void winwindow_process_events_periodic(running_machine &machine) static BOOL is_mame_window(HWND hwnd) { - for (win_window_info *window = win_window_list; window != nullptr; window = window->m_next) + for (auto window : win_window_list) if (window->platform_window<HWND>() == hwnd) return TRUE; @@ -655,12 +651,10 @@ void winwindow_dispatch_message(running_machine &machine, MSG *message) void winwindow_take_snap(void) { - win_window_info *window; - assert(GetCurrentThreadId() == main_threadid); // iterate over windows and request a snap - for (window = win_window_list; window != nullptr; window = window->m_next) + for (auto window : win_window_list) { window->m_renderer->save(); } @@ -675,12 +669,10 @@ void winwindow_take_snap(void) void winwindow_toggle_fsfx(void) { - win_window_info *window; - assert(GetCurrentThreadId() == main_threadid); // iterate over windows and request a snap - for (window = win_window_list; window != nullptr; window = window->m_next) + for (auto window : win_window_list) { window->m_renderer->toggle_fsfx(); } @@ -695,12 +687,10 @@ void winwindow_toggle_fsfx(void) void winwindow_take_video(void) { - win_window_info *window; - assert(GetCurrentThreadId() == main_threadid); // iterate over windows and request a snap - for (window = win_window_list; window != nullptr; window = window->m_next) + for (auto window : win_window_list) { window->m_renderer->record(); } @@ -715,12 +705,10 @@ void winwindow_take_video(void) void winwindow_toggle_full_screen(void) { - win_window_info *window; - assert(GetCurrentThreadId() == main_threadid); // if we are in debug mode, never go full screen - for (window = win_window_list; window != nullptr; window = window->m_next) + for (auto window : win_window_list) if (window->machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) return; @@ -728,9 +716,11 @@ 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 != nullptr; window = window->m_next) + for (auto window : win_window_list) SendMessage(window->platform_window<HWND>(), WM_USER_SET_FULLSCREEN, !video_config.windowed, 0); - SetForegroundWindow(win_window_list->platform_window<HWND>()); + + // Set the first window as foreground + SetForegroundWindow(win_window_list.front()->platform_window<HWND>()); } @@ -743,10 +733,9 @@ void winwindow_toggle_full_screen(void) BOOL winwindow_has_focus(void) { HWND focuswnd = GetFocus(); - win_window_info *window; // see if one of the video windows has focus - for (window = win_window_list; window != nullptr; window = window->m_next) + for (auto window : win_window_list) if (focuswnd == window->platform_window<HWND>()) return TRUE; @@ -763,19 +752,21 @@ void winwindow_update_cursor_state(running_machine &machine) { assert(GetCurrentThreadId() == main_threadid); - win_window_info *window = win_window_list; - - // If no window yet, just return - if (window == nullptr) + // If no windows, just return + if (win_window_list.empty()) return; + auto window = win_window_list.front(); + // if we should hide the mouse cursor, then do it // rules are: // 1. we must have focus before hiding the cursor // 2. we also hide the cursor in full screen mode and when tshe window doesn't have a menu // 3. we also hide the cursor in windowed mode if we're not paused and // the input system requests it - if (winwindow_has_focus() && ((!video_config.windowed && !window->win_has_menu()) || (!machine.paused() && downcast<windows_osd_interface&>(machine.osd()).should_hide_mouse()))) + if (winwindow_has_focus() && ( + (window->fullscreen() && !window->win_has_menu()) + || (!machine.paused() && WINOSD(machine)->should_hide_mouse()))) { // hide cursor window->hide_pointer(); @@ -802,44 +793,37 @@ 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 *win; - assert(GetCurrentThreadId() == main_threadid); // allocate a new window object - 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; - window->m_index = index; + auto window = std::make_shared<win_window_info>(machine, index, monitor, config); // set main window - if (index > 0) + if (window->m_index > 0) { - for (auto w = win_window_list; w != nullptr; w = w->m_next) + for (auto w : win_window_list) { if (w->m_index == 0) { - window->m_main = w; + window->set_main_window(std::dynamic_pointer_cast<osd_window>(w)); break; } } } else { - // Give the main window a reference to itself - window->m_main = window; + // We must be the main window + window->set_main_window(window); } // see if we are safe for fullscreen window->m_fullscreen_safe = TRUE; - for (win = win_window_list; win != nullptr; win = win->m_next) + for (auto win : win_window_list) if (win->m_monitor == monitor) window->m_fullscreen_safe = FALSE; // add us to the list - *last_window_ptr = window; - last_window_ptr = &window->m_next; + win_window_list.push_back(window); // load the layout window->m_target = machine.render().target_alloc(); @@ -880,17 +864,10 @@ void win_window_info::create(running_machine &machine, int index, osd_monitor_in void win_window_info::destroy() { - win_window_info **prevptr; - assert(GetCurrentThreadId() == main_threadid); // remove us from the list - for (prevptr = &win_window_list; *prevptr != nullptr; prevptr = &(*prevptr)->m_next) - if (*prevptr == this) - { - *prevptr = this->m_next; - break; - } + win_window_list.remove(std::static_pointer_cast<win_window_info>(shared_from_this())); // destroy the window if (platform_window<HWND>() != nullptr) @@ -927,7 +904,7 @@ void win_window_info::update() m_targetlayerconfig = targetlayerconfig; // in window mode, reminimize/maximize - if (!m_fullscreen) + if (!fullscreen()) { if (m_isminimized) SendMessage(platform_window<HWND>(), WM_USER_SET_MINSIZE, 0, 0); @@ -985,7 +962,7 @@ osd_monitor_info *win_window_info::winwindow_video_window_monitor(const osd_rect osd_monitor_info *monitor; // in window mode, find the nearest - if (!m_fullscreen) + if (!fullscreen()) { if (proposed != nullptr) { @@ -1159,7 +1136,7 @@ int winwindow_ui_is_paused(running_machine &machine) int win_window_info::wnd_extra_width() { RECT temprect = { 100, 100, 200, 200 }; - if (m_fullscreen) + if (fullscreen()) return 0; AdjustWindowRectEx(&temprect, WINDOW_STYLE, win_has_menu(), WINDOW_STYLE_EX); return rect_width(&temprect) - 100; @@ -1175,7 +1152,7 @@ int win_window_info::wnd_extra_width() int win_window_info::wnd_extra_height() { RECT temprect = { 100, 100, 200, 200 }; - if (m_fullscreen) + if (fullscreen()) return 0; AdjustWindowRectEx(&temprect, WINDOW_STYLE, win_has_menu(), WINDOW_STYLE_EX); return rect_height(&temprect) - 100; @@ -1304,10 +1281,10 @@ int win_window_info::complete_create() // create the window, but don't show it yet HWND hwnd = win_create_window_ex_utf8( - m_fullscreen ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX, + fullscreen() ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX, "MAME", m_title, - m_fullscreen ? FULLSCREEN_STYLE : WINDOW_STYLE, + fullscreen() ? FULLSCREEN_STYLE : WINDOW_STYLE, monitorbounds.left() + 20, monitorbounds.top() + 20, monitorbounds.left() + 100, monitorbounds.top() + 100, nullptr,//(win_window_list != nullptr) ? win_window_list->m_hwnd : nullptr, @@ -1343,14 +1320,9 @@ int win_window_info::complete_create() adjust_window_position_after_major_change(); // show the window - if (!m_fullscreen || m_fullscreen_safe) + if (!fullscreen() || m_fullscreen_safe) { - // finish off by trying to initialize DirectX; if we fail, ignore it - if (m_renderer != nullptr) - { - delete m_renderer; - } - m_renderer = osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(this)); + m_renderer = osd_renderer::make_for_type(video_config.mode, std::static_pointer_cast<win_window_info>(shared_from_this())); if (m_renderer->create()) return 1; @@ -1401,7 +1373,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR // non-client paint: punt if full screen case WM_NCPAINT: - if (!window->m_fullscreen || window->win_has_menu()) + if (!window->fullscreen() || window->win_has_menu()) return DefWindowProc(wnd, message, wparam, lparam); break; @@ -1547,8 +1519,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR // destroy: clean up all attached rendering bits and nullptr out our hwnd case WM_DESTROY: - global_free(window->m_renderer); - window->m_renderer = nullptr; + window->m_renderer.reset(); window->set_platform_window(nullptr); return DefWindowProc(wnd, message, wparam, lparam); @@ -1718,7 +1689,7 @@ osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad propheight = MAX(propheight, minheight); // clamp against the maximum (fit on one screen for full screen mode) - if (m_fullscreen) + if (fullscreen()) { maxwidth = monitor->position_size().width() - extrawidth; maxheight = monitor->position_size().height() - extraheight; @@ -1878,7 +1849,7 @@ void win_window_info::update_minmax_state() { assert(GetCurrentThreadId() == window_threadid); - if (!m_fullscreen) + if (!fullscreen()) { RECT bounds; @@ -1963,7 +1934,7 @@ void win_window_info::adjust_window_position_after_major_change() osd_rect newrect = RECT_to_osd_rect(oldrect); // adjust the window size so the client area is what we want - if (!m_fullscreen) + if (!fullscreen()) { // constrain the existing size to the aspect ratio if (video_config.keepaspect) @@ -1980,12 +1951,12 @@ void win_window_info::adjust_window_position_after_major_change() // adjust the position if different if (oldrect.left != newrect.left() || oldrect.top != newrect.top() || oldrect.right != newrect.right() || oldrect.bottom != newrect.bottom()) - SetWindowPos(platform_window<HWND>(), m_fullscreen ? HWND_TOPMOST : HWND_TOP, + SetWindowPos(platform_window<HWND>(), fullscreen() ? HWND_TOPMOST : HWND_TOP, newrect.left(), newrect.top(), newrect.width(), newrect.height(), 0); // take note of physical window size (used for lightgun coordinate calculation) - if (this == win_window_list) + if (m_index == 0) { win_physical_width = newrect.width(); win_physical_height = newrect.height(); @@ -2004,13 +1975,12 @@ void win_window_info::set_fullscreen(int fullscreen) assert(GetCurrentThreadId() == window_threadid); // if we're in the right state, punt - if (m_fullscreen == fullscreen) + if (this->fullscreen() == fullscreen) return; - m_fullscreen = fullscreen; + video_config.windowed = !fullscreen; // kill off the drawers - delete m_renderer; - m_renderer = nullptr; + m_renderer.reset(); // hide ourself ShowWindow(platform_window<HWND>(), SW_HIDE); @@ -2062,12 +2032,12 @@ void win_window_info::set_fullscreen(int fullscreen) adjust_window_position_after_major_change(); // show ourself - if (!m_fullscreen || m_fullscreen_safe) + if (!this->fullscreen() || m_fullscreen_safe) { if (video_config.mode != VIDEO_MODE_NONE) ShowWindow(platform_window<HWND>(), SW_SHOW); - m_renderer = reinterpret_cast<osd_renderer *>(osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(this))); + m_renderer = osd_renderer::make_for_type(video_config.mode, std::static_pointer_cast<win_window_info>(shared_from_this())); if (m_renderer->create()) exit(1); } diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h index a8d1fbffdb6..47eae45d034 100644 --- a/src/osd/windows/window.h +++ b/src/osd/windows/window.h @@ -17,6 +17,9 @@ #include <chrono> #include <mutex> +#include <memory> +#include <list> + #include "video.h" #include "render.h" @@ -44,13 +47,13 @@ class win_window_info : public osd_window { public: - win_window_info(running_machine &machine); + win_window_info(running_machine &machine, int index, osd_monitor_info *monitor, const osd_window_config *config); virtual ~win_window_info(); running_machine &machine() const override { return m_machine; } virtual render_target *target() override { return m_target; } - int fullscreen() const override { return m_fullscreen; } + int fullscreen() const override { return !video_config.windowed; } void update(); @@ -108,7 +111,7 @@ public: // monitor info osd_monitor_info * m_monitor; - int m_fullscreen; + //int m_fullscreen; int m_fullscreen_safe; float m_aspect; @@ -125,7 +128,7 @@ public: int m_lastclicky; // drawing data - osd_renderer * m_renderer; + std::unique_ptr<osd_renderer> m_renderer; private: void draw_video_contents(HDC dc, int update); @@ -162,7 +165,7 @@ struct osd_draw_callbacks //============================================================ // windows -extern win_window_info *win_window_list; +extern std::list<std::shared_ptr<win_window_info>> win_window_list; diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index 7edb996fb0a..14243c67fd7 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -69,11 +69,11 @@ public: char buffer[1024]; // if we are in fullscreen mode, go to windowed mode - if ((video_config.windowed == 0) && (win_window_list != nullptr)) + if ((video_config.windowed == 0) && !win_window_list.empty()) winwindow_toggle_full_screen(); vsnprintf(buffer, ARRAY_LENGTH(buffer), msg, args); - win_message_box_utf8(win_window_list ? win_window_list->platform_window<HWND>() : nullptr, buffer, emulator_info::get_appname(), MB_OK); + win_message_box_utf8(!win_window_list.empty() ? win_window_list.front()->platform_window<HWND>() : nullptr, buffer, emulator_info::get_appname(), MB_OK); } else chain_output(channel, msg, args); @@ -515,7 +515,7 @@ void windows_osd_interface::init(running_machine &machine) osd_common_t::init_subsystems(); // notify listeners of screen configuration - for (win_window_info *info = win_window_list; info != nullptr; info = info->m_next) + for (auto info : win_window_list) { machine.output().set_value(string_format("Orientation(%s)", info->m_monitor->devicename()).c_str(), info->m_targetorient); } |