osd: Turned video modules into actual modules, fixed various issues.

Don't ignore the return status of OSD module initialisation.  Attempt to
fall back to an alternate module if the selected module fails to
initialise.  Log more useful diagnostic information at verbose level.

Fixed BGFX crash on exit after toggling fullscreen.  Also persist more
settings than just the selected chains across toggling fullscreen.

Turned video modules into OSD modules in the same sense as all the other
OSD modules.  They now use the same selection/fallback mechanism as all
the other modules without special extra code in the OSD implementations.

Untangled some object ownership mess.  Windows own renderers, OSD
objects own windows.  Fixed a refrence loop that caused the first window
object to always leak.

Don't create renderer object until after underlying window has been
created.  Fixed issues with order of creation/destruction when toggling
fullscreen or changing prescale in fullscreen with -switchres in SDL
builds.

Use more smart pointers in BGFX and Direct3D render modules.  Most of
the code now reutrns a smart pointer when handing over ownership or a
naked pointer when retaining ownership.  Fixed a few leaks and
simplified cleanup code.

Encapsulated various OSD modules better.
This commit is contained in:
Vas Crabb 2023-01-30 06:23:19 +11:00
parent 12e5fa3906
commit 2810c9d91b
73 changed files with 3302 additions and 3791 deletions

View File

@ -59,69 +59,76 @@ function osdmodulesbuild()
MAME_DIR .. "src/osd/interface/inputseq.cpp",
MAME_DIR .. "src/osd/interface/inputseq.h",
MAME_DIR .. "src/osd/modules/debugger/debug_module.h",
MAME_DIR .. "src/osd/modules/font/font_module.h",
MAME_DIR .. "src/osd/modules/midi/midi_module.h",
MAME_DIR .. "src/osd/modules/netdev/netdev_module.h",
MAME_DIR .. "src/osd/modules/sound/sound_module.h",
MAME_DIR .. "src/osd/modules/diagnostics/diagnostics_module.h",
MAME_DIR .. "src/osd/modules/monitor/monitor_module.h",
MAME_DIR .. "src/osd/modules/lib/osdobj_common.cpp",
MAME_DIR .. "src/osd/modules/lib/osdobj_common.h",
MAME_DIR .. "src/osd/modules/diagnostics/none.cpp",
MAME_DIR .. "src/osd/modules/diagnostics/diagnostics_win32.cpp",
MAME_DIR .. "src/osd/modules/debugger/none.cpp",
MAME_DIR .. "src/osd/modules/debugger/debugwin.cpp",
MAME_DIR .. "src/osd/modules/debugger/debugimgui.cpp",
MAME_DIR .. "src/osd/modules/debugger/debuggdbstub.cpp",
MAME_DIR .. "src/osd/modules/debugger/debugimgui.cpp",
MAME_DIR .. "src/osd/modules/debugger/debugwin.cpp",
MAME_DIR .. "src/osd/modules/debugger/none.cpp",
MAME_DIR .. "src/osd/modules/debugger/xmlconfig.cpp",
MAME_DIR .. "src/osd/modules/debugger/xmlconfig.h",
MAME_DIR .. "src/osd/modules/diagnostics/diagnostics_module.h",
MAME_DIR .. "src/osd/modules/diagnostics/diagnostics_win32.cpp",
MAME_DIR .. "src/osd/modules/diagnostics/none.cpp",
MAME_DIR .. "src/osd/modules/font/font_dwrite.cpp",
MAME_DIR .. "src/osd/modules/font/font_module.h",
MAME_DIR .. "src/osd/modules/font/font_none.cpp",
MAME_DIR .. "src/osd/modules/font/font_osx.cpp",
MAME_DIR .. "src/osd/modules/font/font_sdl.cpp",
MAME_DIR .. "src/osd/modules/font/font_windows.cpp",
MAME_DIR .. "src/osd/modules/font/font_dwrite.cpp",
MAME_DIR .. "src/osd/modules/font/font_osx.cpp",
MAME_DIR .. "src/osd/modules/font/font_none.cpp",
MAME_DIR .. "src/osd/modules/netdev/taptun.cpp",
MAME_DIR .. "src/osd/modules/netdev/pcap.cpp",
MAME_DIR .. "src/osd/modules/netdev/none.cpp",
MAME_DIR .. "src/osd/modules/midi/portmidi.cpp",
MAME_DIR .. "src/osd/modules/midi/none.cpp",
MAME_DIR .. "src/osd/modules/sound/js_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/direct_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/pa_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/pulse_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/coreaudio_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/sdl_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/xaudio2_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/none.cpp",
MAME_DIR .. "src/osd/modules/input/input_module.h",
MAME_DIR .. "src/osd/modules/input/input_common.cpp",
MAME_DIR .. "src/osd/modules/input/input_common.h",
MAME_DIR .. "src/osd/modules/input/input_dinput.cpp",
MAME_DIR .. "src/osd/modules/input/input_dinput.h",
MAME_DIR .. "src/osd/modules/input/input_mac.cpp",
MAME_DIR .. "src/osd/modules/input/input_module.h",
MAME_DIR .. "src/osd/modules/input/input_none.cpp",
MAME_DIR .. "src/osd/modules/input/input_rawinput.cpp",
MAME_DIR .. "src/osd/modules/input/input_win32.cpp",
MAME_DIR .. "src/osd/modules/input/input_sdl.cpp",
MAME_DIR .. "src/osd/modules/input/input_x11.cpp",
MAME_DIR .. "src/osd/modules/input/input_win32.cpp",
MAME_DIR .. "src/osd/modules/input/input_wincommon.h",
MAME_DIR .. "src/osd/modules/input/input_windows.cpp",
MAME_DIR .. "src/osd/modules/input/input_windows.h",
MAME_DIR .. "src/osd/modules/input/input_winhybrid.cpp",
MAME_DIR .. "src/osd/modules/input/input_x11.cpp",
MAME_DIR .. "src/osd/modules/input/input_xinput.cpp",
MAME_DIR .. "src/osd/modules/input/input_xinput.h",
MAME_DIR .. "src/osd/modules/input/input_winhybrid.cpp",
MAME_DIR .. "src/osd/modules/input/input_mac.cpp",
MAME_DIR .. "src/osd/modules/output/output_module.h",
MAME_DIR .. "src/osd/modules/output/none.cpp",
MAME_DIR .. "src/osd/modules/lib/osdobj_common.cpp",
MAME_DIR .. "src/osd/modules/lib/osdobj_common.h",
MAME_DIR .. "src/osd/modules/midi/midi_module.h",
MAME_DIR .. "src/osd/modules/midi/none.cpp",
MAME_DIR .. "src/osd/modules/midi/portmidi.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_common.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_common.h",
MAME_DIR .. "src/osd/modules/monitor/monitor_dxgi.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_mac.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_module.h",
MAME_DIR .. "src/osd/modules/monitor/monitor_sdl.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_win32.cpp",
MAME_DIR .. "src/osd/modules/netdev/netdev_module.h",
MAME_DIR .. "src/osd/modules/netdev/none.cpp",
MAME_DIR .. "src/osd/modules/netdev/pcap.cpp",
MAME_DIR .. "src/osd/modules/netdev/taptun.cpp",
MAME_DIR .. "src/osd/modules/output/console.cpp",
MAME_DIR .. "src/osd/modules/output/network.cpp",
MAME_DIR .. "src/osd/modules/output/none.cpp",
MAME_DIR .. "src/osd/modules/output/output_module.h",
MAME_DIR .. "src/osd/modules/output/win32_output.cpp",
MAME_DIR .. "src/osd/modules/output/win32_output.h",
MAME_DIR .. "src/osd/modules/monitor/monitor_common.h",
MAME_DIR .. "src/osd/modules/monitor/monitor_common.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_win32.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_dxgi.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_sdl.cpp",
MAME_DIR .. "src/osd/modules/monitor/monitor_mac.cpp",
MAME_DIR .. "src/osd/modules/render/blit13.ipp",
MAME_DIR .. "src/osd/modules/render/draw13.cpp",
MAME_DIR .. "src/osd/modules/render/drawgdi.cpp",
MAME_DIR .. "src/osd/modules/render/drawnone.cpp",
MAME_DIR .. "src/osd/modules/render/drawogl.cpp",
MAME_DIR .. "src/osd/modules/render/drawsdl.cpp",
MAME_DIR .. "src/osd/modules/render/render_module.h",
MAME_DIR .. "src/osd/modules/sound/coreaudio_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/direct_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/js_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/none.cpp",
MAME_DIR .. "src/osd/modules/sound/pa_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/pulse_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/sdl_sound.cpp",
MAME_DIR .. "src/osd/modules/sound/sound_module.h",
MAME_DIR .. "src/osd/modules/sound/xaudio2_sound.cpp",
}
includedirs {
MAME_DIR .. "src/osd",
@ -152,7 +159,6 @@ function osdmodulesbuild()
}
else
files {
MAME_DIR .. "src/osd/modules/render/drawogl.cpp",
MAME_DIR .. "src/osd/modules/opengl/gl_shader_tool.cpp",
MAME_DIR .. "src/osd/modules/opengl/gl_shader_mgr.cpp",
MAME_DIR .. "src/osd/modules/opengl/gl_shader_mgr.h",

View File

@ -430,7 +430,6 @@ project ("osd_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/osdepend.h",
MAME_DIR .. "src/osd/modules/osdwindow.cpp",
MAME_DIR .. "src/osd/modules/osdwindow.h",
MAME_DIR .. "src/osd/modules/render/drawsdl.cpp",
MAME_DIR .. "src/osd/sdl/osdsdl.cpp",
MAME_DIR .. "src/osd/sdl/osdsdl.h",
MAME_DIR .. "src/osd/sdl/sdlmain.cpp",
@ -441,10 +440,6 @@ project ("osd_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/sdl/window.cpp",
MAME_DIR .. "src/osd/sdl/window.h",
}
files {
MAME_DIR .. "src/osd/modules/render/draw13.cpp",
MAME_DIR .. "src/osd/modules/render/blit13.h",
}
project ("ocore_" .. _OPTIONS["osd"])

View File

@ -132,10 +132,6 @@ project ("osd_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/modules/render/d3d/d3dhlsl.h",
MAME_DIR .. "src/osd/modules/render/drawd3d.cpp",
MAME_DIR .. "src/osd/modules/render/drawd3d.h",
MAME_DIR .. "src/osd/modules/render/drawgdi.cpp",
MAME_DIR .. "src/osd/modules/render/drawgdi.h",
MAME_DIR .. "src/osd/modules/render/drawnone.cpp",
MAME_DIR .. "src/osd/modules/render/drawnone.h",
MAME_DIR .. "src/osd/windows/video.cpp",
MAME_DIR .. "src/osd/windows/video.h",
MAME_DIR .. "src/osd/windows/window.cpp",

View File

@ -74,10 +74,12 @@ bool mac_osd_interface::video_init()
get_resolution(options().resolution(), options().resolution(index), &conf, true);
// create window ...
std::shared_ptr<mac_window_info> win = std::make_shared<mac_window_info>(machine(), index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf);
auto win = std::make_unique<mac_window_info>(machine(), *m_render, index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf);
if (win->window_init())
return false;
s_window_list.emplace_back(std::move(win));
}
return true;
@ -104,7 +106,7 @@ void mac_osd_interface::update(bool skip_redraw)
if (!skip_redraw)
{
// profiler_mark(PROFILER_BLIT);
for (auto window : osd_common_t::s_window_list)
for (auto const &window : osd_common_t::window_list())
window->update();
// profiler_mark(PROFILER_END);
}
@ -135,11 +137,11 @@ static void check_osd_inputs(running_machine &machine)
// check for toggling fullscreen mode
if (machine.ui_input().pressed(IPT_OSD_1))
{
for (auto curwin : osd_common_t::s_window_list)
std::static_pointer_cast<mac_window_info>(curwin)->toggle_full_screen();
for (auto const &curwin : osd_common_t::window_list())
dynamic_cast<mac_window_info &>(*curwin).toggle_full_screen();
}
auto window = osd_common_t::s_window_list.front();
auto const &window = osd_common_t::window_list().front();
//FIXME: on a per window basis
if (machine.ui_input().pressed(IPT_OSD_5))
@ -149,10 +151,10 @@ static void check_osd_inputs(running_machine &machine)
}
if (machine.ui_input().pressed(IPT_OSD_6))
std::static_pointer_cast<mac_window_info>(window)->modify_prescale(-1);
dynamic_cast<mac_window_info &>(*window).modify_prescale(-1);
if (machine.ui_input().pressed(IPT_OSD_7))
std::static_pointer_cast<mac_window_info>(window)->modify_prescale(1);
dynamic_cast<mac_window_info &>(*window).modify_prescale(1);
if (machine.ui_input().pressed(IPT_OSD_8))
window->renderer().record();
@ -164,8 +166,6 @@ static void check_osd_inputs(running_machine &machine)
void mac_osd_interface::extract_video_config()
{
const char *stemp;
// global options: extract the data
video_config.windowed = options().window();
video_config.prescale = options().prescale();
@ -176,37 +176,6 @@ void mac_osd_interface::extract_video_config()
if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)
video_config.windowed = true;
// default to working video please
video_config.novideo = 0;
// d3d options: extract the data
stemp = options().video();
if (strcmp(stemp, "auto") == 0)
{
stemp = "opengl";
}
if (strcmp(stemp, OSDOPTVAL_NONE) == 0)
{
video_config.mode = VIDEO_MODE_SOFT;
video_config.novideo = 1;
if (!emulator_info::standalone() && options().seconds_to_run() == 0)
osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
}
else if (strcmp(stemp, MACOPTVAL_OPENGL) == 0)
video_config.mode = VIDEO_MODE_OPENGL;
else if (strcmp(stemp, MACOPTVAL_BGFX) == 0)
{
video_config.mode = VIDEO_MODE_BGFX;
}
else
{
osd_printf_warning("Invalid video value %s; reverting to OpenGL\n", stemp);
video_config.mode = VIDEO_MODE_OPENGL;
}
video_config.switchres = options().switch_res();
video_config.waitvsync = options().wait_vsync();
video_config.syncrefresh = options().sync_refresh();
@ -222,57 +191,6 @@ void mac_osd_interface::extract_video_config()
video_config.prescale = 1;
}
// default to working video please
video_config.forcepow2texture = options().gl_force_pow2_texture();
video_config.allowtexturerect = !(options().gl_no_texture_rect());
video_config.vbo = options().gl_vbo();
video_config.pbo = options().gl_pbo();
video_config.glsl = options().gl_glsl();
if ( video_config.glsl )
{
int i;
video_config.glsl_filter = options().glsl_filter();
video_config.glsl_shader_mamebm_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
stemp = options().shader_mame(i);
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
{
video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1);
strcpy(video_config.glsl_shader_mamebm[i], stemp);
video_config.glsl_shader_mamebm_num++;
} else {
video_config.glsl_shader_mamebm[i] = nullptr;
}
}
video_config.glsl_shader_scrn_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
stemp = options().shader_screen(i);
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
{
video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1);
strcpy(video_config.glsl_shader_scrn[i], stemp);
video_config.glsl_shader_scrn_num++;
} else {
video_config.glsl_shader_scrn[i] = nullptr;
}
}
} else {
int i;
video_config.glsl_filter = 0;
video_config.glsl_shader_mamebm_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
video_config.glsl_shader_mamebm[i] = nullptr;
}
video_config.glsl_shader_scrn_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
video_config.glsl_shader_scrn[i] = nullptr;
}
}
// misc options: sanity check values
// global options: sanity check values

View File

@ -27,8 +27,6 @@
#include "window.h"
#include "osdmac.h"
#include "modules/render/drawbgfx.h"
#include "modules/render/drawogl.h"
#include "modules/monitor/monitor_common.h"
//============================================================
@ -115,7 +113,7 @@ bool mac_osd_interface::window_init()
void mac_osd_interface::update_slider_list()
{
for (auto window : osd_common_t::s_window_list)
for (auto const &window : osd_common_t::window_list())
{
// check if any window has dirty sliders
if (window->renderer().sliders_dirty())
@ -130,7 +128,7 @@ void mac_osd_interface::build_slider_list()
{
m_sliders.clear();
for (auto window : osd_common_t::s_window_list)
for (auto const &window : osd_common_t::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());
@ -149,23 +147,11 @@ void mac_osd_interface::window_exit()
// free all the windows
while (!osd_common_t::s_window_list.empty())
{
auto window = osd_common_t::s_window_list.front();
// Part of destroy removes the window from the list
auto window = std::move(osd_common_t::s_window_list.back());
s_window_list.pop_back();
window->destroy();
}
switch(video_config.mode)
{
case VIDEO_MODE_BGFX:
renderer_bgfx::exit();
break;
case VIDEO_MODE_OPENGL:
renderer_ogl::exit();
break;
default:
break;
}
osd_printf_verbose("Leave macwindow_exit\n");
}
@ -256,7 +242,7 @@ void mac_window_info::toggle_full_screen()
downcast<mac_osd_interface &>(machine().osd()).release_keys();
set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
renderer_create();
// toggle the window mode
set_fullscreen(!fullscreen());
@ -338,7 +324,7 @@ int mac_window_info::window_init()
create_target();
set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast<osd_window*>(this)->shared_from_this()));
renderer_create();
result = complete_create();
@ -586,24 +572,6 @@ int mac_window_info::complete_create()
set_platform_window(window);
// set main window
if (index() > 0)
{
for (auto w : osd_common_t::s_window_list)
{
if (w->index() == 0)
{
set_main_window(std::dynamic_pointer_cast<osd_window>(w));
break;
}
}
}
else
{
// We must be the main window
set_main_window(shared_from_this());
}
// update monitor resolution after mode change to ensure proper pixel aspect
monitor()->refresh();
if (fullscreen() && video_config.switchres)
@ -909,10 +877,11 @@ osd_dim mac_window_info::get_max_bounds(int constrain)
mac_window_info::mac_window_info(
running_machine &a_machine,
render_module &renderprovider,
int index,
std::shared_ptr<osd_monitor_info> a_monitor,
const osd_window_config *config)
: osd_window_t(a_machine, index, a_monitor, *config)
: osd_window_t(a_machine, renderprovider, index, a_monitor, *config)
, m_startmaximized(0)
// Following three are used by input code to defer resizes
, m_minimum_dim(0, 0)

View File

@ -8,8 +8,10 @@
//
//============================================================
#ifndef __MACWINDOW__
#define __MACWINDOW__
#ifndef MAME_OSD_MAC_WINDOW_H
#define MAME_OSD_MAC_WINDOW_H
#pragma once
#include "osdmac.h"
#include "osdsync.h"
@ -90,25 +92,4 @@ private:
void measure_fps(int update);
};
struct osd_draw_callbacks
{
osd_renderer *(*create)(osd_window *window);
};
//============================================================
// PROTOTYPES
//============================================================
//============================================================
// PROTOTYPES - drawogl.c
//============================================================
int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks);
//============================================================
// PROTOTYPES - drawbgfx.c
//============================================================
int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks);
#endif /* __MACWINDOW__ */
#endif // MAME_OSD_MAC_WINDOW_H

View File

@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
// debugwin.c - Win32 debug window handling
// debugwin.cpp - Win32 debug window handling
//
//============================================================
@ -156,7 +156,7 @@ void debugger_windows::wait_for_debugger(device_t &device, bool firststop)
// set the starting position for new auxiliary windows
HMONITOR const nearest_monitor = MonitorFromWindow(
std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(),
dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window(),
MONITOR_DEFAULTTONEAREST);
if (nearest_monitor)
{
@ -321,7 +321,7 @@ void debugger_windows::show_all()
void debugger_windows::hide_all()
{
SetForegroundWindow(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window());
SetForegroundWindow(dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window());
for (auto &info : m_window_list)
info->hide();
}

View File

@ -47,7 +47,7 @@ debugwin_info::debugwin_info(debugger_windows_interface &debugger, bool is_main_
m_wnd = win_create_window_ex_utf8(
DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
0, 0, 100, 100,
std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(),
dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window(),
create_standard_menubar(),
GetModuleHandleUni(),
this);

View File

@ -24,7 +24,7 @@
class font_module
{
public:
virtual ~font_module() { }
virtual ~font_module() = default;
/** attempt to allocate a font instance */
virtual osd_font::ptr font_alloc() = 0;

View File

@ -625,11 +625,11 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a
HWND window_handle;
DWORD di_cooperative_level;
#if defined(OSD_WINDOWS)
auto const window = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front());
bool const standalone_window = window && !window->attached_mode();
auto const &window = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front());
bool const standalone_window = !window.attached_mode();
#elif defined(SDLMAME_WIN32)
auto const window = std::static_pointer_cast<sdl_window_info>(osd_common_t::s_window_list.front());
bool const standalone_window = bool(window);
auto const &window = dynamic_cast<sdl_window_info &>(*osd_common_t::window_list().front());
bool const standalone_window = true;
#endif
if (!standalone_window)
{
@ -640,12 +640,13 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a
else
{
#if defined(OSD_WINDOWS)
window_handle = window->platform_window();
window_handle = window.platform_window();
#elif defined(SDLMAME_WIN32)
auto const sdlwindow = window->platform_window();
auto const sdlwindow = window.platform_window();
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
SDL_GetWindowWMInfo(sdlwindow, &info);
if (!SDL_GetWindowWMInfo(sdlwindow, &info))
return std::make_pair(nullptr, nullptr);
window_handle = info.info.win.window;
#endif
switch (cooperative_level)

View File

@ -595,7 +595,7 @@ public:
registration.dwFlags = RIDEV_DEVNOTIFY;
if (background_input())
registration.dwFlags |= RIDEV_INPUTSINK;
registration.hwndTarget = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
registration.hwndTarget = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
// register the device
RegisterRawInputDevices(&registration, 1, sizeof(registration));

View File

@ -154,7 +154,9 @@ public:
m_mouse.lY = (cursor_info.ptScreenPos.y - m_win32_mouse.last_point.y) * INPUT_RELATIVE_PER_PIXEL;
RECT window_pos = {0};
GetWindowRect(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(), &window_pos);
GetWindowRect(
dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window(),
&window_pos);
// We reset the cursor position to the middle of the window each frame
m_win32_mouse.last_point.x = window_pos.left + (window_pos.right - window_pos.left) / 2;
@ -326,10 +328,10 @@ public:
// get the cursor position and transform into final results
POINT mousepos;
GetCursorPos(&mousepos);
if (!osd_common_t::s_window_list.empty())
if (!osd_common_t::window_list().empty())
{
// get the position relative to the window
HWND const hwnd = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
HWND const hwnd = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
RECT client_rect;
GetClientRect(hwnd, &client_rect);
ScreenToClient(hwnd, &mousepos);
@ -390,7 +392,7 @@ protected:
if (args.keydown)
{
// get the position relative to the window
HWND const hwnd = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
HWND const hwnd = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
RECT client_rect;
GetClientRect(hwnd, &client_rect);

View File

@ -10,12 +10,14 @@
#include "osdobj_common.h"
#include "modules/osdwindow.h"
#include "modules/debugger/debug_module.h"
#include "modules/font/font_module.h"
#include "modules/input/input_module.h"
#include "modules/midi/midi_module.h"
#include "modules/monitor/monitor_module.h"
#include "modules/netdev/netdev_module.h"
#include "modules/render/render_module.h"
#include "modules/sound/sound_module.h"
#include "osdnet.h"
@ -66,7 +68,6 @@ const options_entry osd_options::s_option_entries[] =
{ OSDOPTION_BENCH, "0", core_options::option_type::INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" },
{ nullptr, nullptr, core_options::option_type::HEADER, "OSD VIDEO OPTIONS" },
// OS X can be trusted to have working hardware OpenGL, so default to it on for the best user experience
{ OSDOPTION_VIDEO, OSDOPTVAL_AUTO, core_options::option_type::STRING, "video output method: " },
{ OSDOPTION_NUMSCREENS "(1-4)", "1", core_options::option_type::INTEGER, "number of output screens/windows to create; usually, you want just one" },
{ OSDOPTION_WINDOW ";w", "0", core_options::option_type::BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" },
@ -181,7 +182,7 @@ const options_entry osd_options::s_option_entries[] =
{ OSDOPTION_BGFX_LUT, "lut-default.png", core_options::option_type::STRING, "LUT texture name" },
{ OSDOPTION_BGFX_AVI_NAME, OSDOPTVAL_AUTO, core_options::option_type::PATH, "filename for BGFX output logging" },
// End of list
// End of list
{ nullptr }
};
@ -192,7 +193,7 @@ osd_options::osd_options()
}
// Window list
std::list<std::shared_ptr<osd_window>> osd_common_t::s_window_list;
std::list<std::unique_ptr<osd_window> > osd_common_t::s_window_list;
//-------------------------------------------------
// osd_interface - constructor
@ -237,6 +238,26 @@ void osd_common_t::register_options()
REGISTER_MODULE(m_mod_man, FONT_SDL);
REGISTER_MODULE(m_mod_man, FONT_NONE);
#if defined(SDLMAME_EMSCRIPTEN)
REGISTER_MODULE(m_mod_man, RENDERER_SDL1); // don't bother trying to use video acceleration in browsers
#endif
#if defined(OSD_WINDOWS)
REGISTER_MODULE(m_mod_man, RENDERER_D3D); // this is only built for OSD=windows, there's no dummy stub
#endif
#if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
REGISTER_MODULE(m_mod_man, RENDERER_BGFX); // try BGFX before GDI on windows to get DirectX 10/11 acceleration
#endif
REGISTER_MODULE(m_mod_man, RENDERER_GDI); // GDI ahead of OpenGL as there's a chance Windows has no OpenGL
REGISTER_MODULE(m_mod_man, RENDERER_OPENGL);
#if !defined(OSD_WINDOWS) && !defined(SDLMAME_WIN32)
REGISTER_MODULE(m_mod_man, RENDERER_BGFX); // try BGFX after OpenGL on other operating systems for now
#endif
REGISTER_MODULE(m_mod_man, RENDERER_SDL2);
#if !defined(SDLMAME_EMSCRIPTEN)
REGISTER_MODULE(m_mod_man, RENDERER_SDL1);
#endif
REGISTER_MODULE(m_mod_man, RENDERER_NONE);
REGISTER_MODULE(m_mod_man, SOUND_DSOUND);
REGISTER_MODULE(m_mod_man, SOUND_XAUDIO2);
REGISTER_MODULE(m_mod_man, SOUND_COREAUDIO);
@ -306,23 +327,18 @@ void osd_common_t::register_options()
// after initialization we know which modules are supported
update_option(OSD_MONITOR_PROVIDER, m_mod_man.get_module_names(OSD_MONITOR_PROVIDER));
update_option(OSD_FONT_PROVIDER, m_mod_man.get_module_names(OSD_FONT_PROVIDER));
update_option(OSD_RENDERER_PROVIDER, m_mod_man.get_module_names(OSD_RENDERER_PROVIDER));
update_option(OSD_SOUND_PROVIDER, m_mod_man.get_module_names(OSD_SOUND_PROVIDER));
update_option(OSD_MONITOR_PROVIDER, m_mod_man.get_module_names(OSD_MONITOR_PROVIDER));
update_option(OSD_KEYBOARDINPUT_PROVIDER, m_mod_man.get_module_names(OSD_KEYBOARDINPUT_PROVIDER));
update_option(OSD_MOUSEINPUT_PROVIDER, m_mod_man.get_module_names(OSD_MOUSEINPUT_PROVIDER));
update_option(OSD_LIGHTGUNINPUT_PROVIDER, m_mod_man.get_module_names(OSD_LIGHTGUNINPUT_PROVIDER));
update_option(OSD_JOYSTICKINPUT_PROVIDER, m_mod_man.get_module_names(OSD_JOYSTICKINPUT_PROVIDER));
update_option(OSD_SOUND_PROVIDER, m_mod_man.get_module_names(OSD_SOUND_PROVIDER));
update_option(OSD_MIDI_PROVIDER, m_mod_man.get_module_names(OSD_MIDI_PROVIDER));
update_option(OSD_NETDEV_PROVIDER, m_mod_man.get_module_names(OSD_NETDEV_PROVIDER));
update_option(OSD_DEBUG_PROVIDER, m_mod_man.get_module_names(OSD_DEBUG_PROVIDER));
update_option(OSD_OUTPUT_PROVIDER, m_mod_man.get_module_names(OSD_OUTPUT_PROVIDER));
// Register video options and update options
video_options_add("none", nullptr);
video_register();
update_option(OSDOPTION_VIDEO, m_video_names);
}
void osd_common_t::update_option(const std::string &key, std::vector<std::string_view> const &values)
@ -575,28 +591,18 @@ bool osd_common_t::execute_command(const char *command)
{
if (strcmp(command, OSDCOMMAND_LIST_NETWORK_ADAPTERS) == 0)
{
osd_module *om = select_module_options(options(), OSD_NETDEV_PROVIDER);
if (om->probe())
{
om->init(*this, options());
osd_list_network_adapters();
om->exit();
}
osd_module &om = select_module_options<osd_module>(OSD_NETDEV_PROVIDER);
osd_list_network_adapters();
om.exit();
return true;
}
else if (strcmp(command, OSDCOMMAND_LIST_MIDI_DEVICES) == 0)
{
osd_module *om = select_module_options(options(), OSD_MIDI_PROVIDER);
auto *pm = select_module_options<midi_module *>(options(), OSD_MIDI_PROVIDER);
osd_module &om = select_module_options<osd_module>(OSD_MIDI_PROVIDER);
dynamic_cast<midi_module &>(om).list_midi_devices();
om.exit();
if (om->probe())
{
om->init(*this, options());
pm->list_midi_devices();
om->exit();
}
return true;
}
@ -612,10 +618,10 @@ static void output_notifier_callback(const char *outname, int32_t value, void *p
void osd_common_t::init_subsystems()
{
// monitors have to be initialized before video init
m_monitor_module = select_module_options<monitor_module *>(options(), OSD_MONITOR_PROVIDER);
assert(m_monitor_module != nullptr);
m_monitor_module->init(*this, options());
m_monitor_module = &select_module_options<monitor_module>(OSD_MONITOR_PROVIDER);
// various modules depend on having a window handle
m_render = &select_module_options<render_module>(OSD_RENDERER_PROVIDER);
if (!video_init())
{
video_exit();
@ -625,28 +631,23 @@ void osd_common_t::init_subsystems()
exit(-1);
}
m_keyboard_input = select_module_options<input_module *>(options(), OSD_KEYBOARDINPUT_PROVIDER);
m_mouse_input = select_module_options<input_module *>(options(), OSD_MOUSEINPUT_PROVIDER);
m_lightgun_input = select_module_options<input_module *>(options(), OSD_LIGHTGUNINPUT_PROVIDER);
m_joystick_input = select_module_options<input_module *>(options(), OSD_JOYSTICKINPUT_PROVIDER);
m_keyboard_input = &select_module_options<input_module>(OSD_KEYBOARDINPUT_PROVIDER);
m_mouse_input = &select_module_options<input_module>(OSD_MOUSEINPUT_PROVIDER);
m_lightgun_input = &select_module_options<input_module>(OSD_LIGHTGUNINPUT_PROVIDER);
m_joystick_input = &select_module_options<input_module>(OSD_JOYSTICKINPUT_PROVIDER);
m_font_module = select_module_options<font_module *>(options(), OSD_FONT_PROVIDER);
m_sound = select_module_options<sound_module *>(options(), OSD_SOUND_PROVIDER);
m_sound->m_sample_rate = options().sample_rate();
m_sound->m_audio_latency = options().audio_latency();
m_font_module = &select_module_options<font_module>(OSD_FONT_PROVIDER);
m_sound = &select_module_options<sound_module>(OSD_SOUND_PROVIDER);
m_debugger = select_module_options<debug_module *>(options(), OSD_DEBUG_PROVIDER);
m_debugger = &select_module_options<debug_module>(OSD_DEBUG_PROVIDER);
select_module_options<netdev_module *>(options(), OSD_NETDEV_PROVIDER);
select_module_options<netdev_module>(OSD_NETDEV_PROVIDER);
m_midi = select_module_options<midi_module *>(options(), OSD_MIDI_PROVIDER);
m_midi = &select_module_options<midi_module>(OSD_MIDI_PROVIDER);
m_output = select_module_options<output_module *>(options(), OSD_OUTPUT_PROVIDER);
m_output->set_machine(&machine());
m_output = &select_module_options<output_module>(OSD_OUTPUT_PROVIDER);
machine().output().set_global_notifier(output_notifier_callback, this);
m_mod_man.init(*this, options());
input_init();
}
@ -665,10 +666,6 @@ bool osd_common_t::no_sound()
return (strcmp(options().sound(),"none")==0) ? true : false;
}
void osd_common_t::video_register()
{
}
bool osd_common_t::input_init()
{
m_keyboard_input->input_init(machine());
@ -693,17 +690,15 @@ void osd_common_t::window_exit()
void osd_common_t::osd_exit()
{
// destroy the renderers before shutting down their parent module
for (auto const &window : s_window_list)
window->renderer_reset();
m_mod_man.exit();
exit_subsystems();
}
void osd_common_t::video_options_add(const char *name, void *type)
{
//m_video_options.add(name, type, false);
m_video_names.push_back(name);
}
osd_font::ptr osd_common_t::font_alloc()
{
return m_font_module->font_alloc();

View File

@ -190,15 +190,16 @@ public:
// ======================> osd_interface
class font_module;
class sound_module;
class debug_module;
class midi_module;
class font_module;
class input_module;
class output_module;
class midi_module;
class monitor_module;
class osd_watchdog;
class osd_window;
class output_module;
class render_module;
class sound_module;
// description of the currently-running machine
class osd_common_t : public osd_interface, osd_output
@ -250,7 +251,6 @@ public:
virtual void init_subsystems();
virtual bool video_init();
virtual void video_register();
virtual bool window_init();
virtual void exit_subsystems();
@ -259,8 +259,6 @@ public:
virtual void osd_exit();
virtual void video_options_add(const char *name, void *type);
virtual osd_options &options() { return m_options; }
// osd_output interface ...
@ -273,7 +271,7 @@ public:
virtual void process_events() = 0;
virtual bool has_focus() const = 0;
static std::list<std::shared_ptr<osd_window> > s_window_list;
static const std::list<std::unique_ptr<osd_window> > &window_list() { return s_window_list; }
protected:
virtual bool input_init();
@ -281,6 +279,8 @@ protected:
virtual void build_slider_list() { }
virtual void update_slider_list() { }
static std::list<std::unique_ptr<osd_window> > s_window_list;
private:
// internal state
running_machine * m_machine;
@ -293,26 +293,24 @@ private:
void update_option(const std::string &key, std::vector<std::string_view> const &values);
// FIXME: should be elsewhere
osd_module *select_module_options(const core_options &opts, const std::string &opt_name)
template<class C>
C &select_module_options(const std::string &opt_name)
{
std::string opt_val = opts.exists(opt_name) ? opts.value(opt_name) : "";
if (opt_val.compare("auto")==0)
std::string opt_val = options().exists(opt_name) ? options().value(opt_name) : "";
if (opt_val == "auto")
{
opt_val = "";
}
else if (!m_mod_man.type_has_name(opt_name.c_str(), opt_val.c_str()))
{
osd_printf_warning("Value %s not supported for option %s - falling back to auto\n", opt_val, opt_name);
opt_val = "";
}
return m_mod_man.select_module(opt_name.c_str(), opt_val.c_str());
}
template<class C>
C select_module_options(const core_options &opts, const std::string &opt_name)
{
return dynamic_cast<C>(select_module_options(opts, opt_name));
return m_mod_man.select_module<C>(*this, options(), opt_name.c_str(), opt_val.c_str());
}
protected:
render_module* m_render;
sound_module* m_sound;
debug_module* m_debugger;
midi_module* m_midi;
@ -326,7 +324,6 @@ protected:
std::vector<ui::menu_item> m_sliders;
private:
std::vector<std::string_view> m_video_names;
std::unordered_map<std::string, std::string> m_option_descs;
};

View File

@ -7,6 +7,8 @@
#include "modules/osdmodule.h"
#include "emucore.h"
#include "osdcore.h"
#include <algorithm>
@ -48,20 +50,62 @@ osd_module *osd_module_manager::get_module_generic(const char *type, const char
return nullptr;
}
osd_module *osd_module_manager::select_module(const char *type, const char *name)
osd_module &osd_module_manager::select_module(osd_interface &osd, const osd_options &options, const char *type, const char *name)
{
osd_module *m = get_module_generic(type, name);
// see if a module of this type has already been already selected
for (osd_module &existing : m_selected)
{
if (existing.type() == type)
{
osd_printf_warning(
"Attempt to select %s module %s after selecting module %s\n",
type,
(name && *name) ? name : "<default>",
existing.name());
return existing;
}
}
// FIXME: check if already exists!
// try to start the selected module
osd_module *const m = get_module_generic(type, name);
if (m)
m_selected.emplace_back(*m);
return m;
}
{
//osd_printf_verbose("Attempting to initialize %s module %s\n", type, m->name());
if (!m->init(osd, options))
{
m_selected.emplace_back(*m);
return *m;
}
osd_printf_verbose("Initializing %s module %s failed\n", type, m->name());
}
else
{
osd_printf_verbose("Could not find %s module %s\n", type, name ? name : "<default>");
}
void osd_module_manager::init(osd_interface &osd, const osd_options &options)
{
for (osd_module &m : m_selected)
m.init(osd, options);
// walk down the list until something works
for (auto const &fallback : m_modules)
{
if ((fallback->type() == type) && (fallback.get() != m))
{
osd_printf_verbose("Attempting to initialize %s module %s\n", type, fallback->name());
if (!fallback->init(osd, options))
{
osd_printf_warning(
m
? "Initializing %s module %s failed, falling back to %s\n"
: "Could not find %s module %s, falling back to %s\n",
type,
m ? m->name() : (name && *name) ? name : "<default>",
fallback->name());
m_selected.emplace_back(*fallback);
return *fallback;
}
}
}
// can't deal with absence of a module, and at least the "none" module should have worked
throw emu_fatalerror("All %s modules failed to initialize", type);
}
void osd_module_manager::exit()

View File

@ -78,17 +78,15 @@ public:
osd_module *get_module_generic(const char *type, const char *name);
template<class C>
C select_module(const char *type, const char *name = "")
C &select_module(osd_interface &osd, const osd_options &options, const char *type, const char *name = "")
{
return dynamic_cast<C>(select_module(type, name));
return dynamic_cast<C &>(select_module(osd, options, type, name));
}
osd_module *select_module(const char *type, const char *name = "");
osd_module &select_module(osd_interface &osd, const osd_options &options, const char *type, const char *name = "");
std::vector<std::string_view> get_module_names(const char *type) const;
void init(osd_interface &osd, const osd_options &options);
void exit();
private:

View File

@ -12,25 +12,19 @@
// osd/modules
#include "lib/osdobj_common.h"
#include "monitor/monitor_module.h"
#include "render/drawnone.h"
#include "render/drawbgfx.h"
#if (USE_OPENGL)
#include "render/drawogl.h"
#endif
#if defined(OSD_WINDOWS)
#include "render/drawgdi.h"
#include "render/drawd3d.h"
#elif defined(OSD_SDL)
#include "render/draw13.h"
#include "render/drawsdl.h"
#endif
#include "render/render_module.h"
// emu
#include "main.h"
#include "render.h"
osd_window::osd_window(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config &config) :
osd_window::osd_window(
running_machine &machine,
render_module &renderprovider,
int index,
const std::shared_ptr<osd_monitor_info> &monitor,
const osd_window_config &config) :
#ifdef OSD_WINDOWS
m_dc(nullptr), m_resize_state(0),
#endif
@ -41,22 +35,26 @@ osd_window::osd_window(running_machine &machine, int index, std::shared_ptr<osd_
m_fullscreen(false),
m_prescale(1),
m_machine(machine),
m_renderprovider(renderprovider),
m_monitor(std::move(monitor)),
m_renderer(nullptr),
m_main(nullptr),
m_title(
util::string_format(
(video_config.numscreens > 1)
? "%3$s [%4$s] screen %5$d - %1$s %2$s (%6$s%7$sP%8$d)"
: "%3$s [%4$s] - %1$s %2$s (%6$s%7$sP%8$d)",
emulator_info::get_appname(),
emulator_info::get_bare_build_version(),
machine.system().type.fullname(),
machine.system().name,
index,
(sizeof(int) == sizeof(void *)) ? "I" : "",
(sizeof(long) == sizeof(void *)) ? "L" : (sizeof(long long) == sizeof(void *)) ? "LL" : "",
sizeof(void *) * 8))
emulator_info::get_appname(),
emulator_info::get_bare_build_version(),
machine.system().type.fullname(),
machine.system().name,
index,
(sizeof(int) == sizeof(void *)) ? "I" : "",
(sizeof(long) == sizeof(void *)) ? "L" : (sizeof(long long) == sizeof(void *)) ? "LL" : "",
sizeof(void *) * 8))
{
}
osd_window::~osd_window()
{
}
@ -82,36 +80,6 @@ bool osd_window::keepaspect() const
return false;
}
std::unique_ptr<osd_renderer> osd_renderer::make_for_type(int mode, std::shared_ptr<osd_window> window, int extra_flags)
{
switch(mode)
{
#if defined(OSD_WINDOWS)
case VIDEO_MODE_NONE:
return std::make_unique<renderer_none>(window);
#endif
case VIDEO_MODE_BGFX:
return std::make_unique<renderer_bgfx>(window);
#if (USE_OPENGL)
case VIDEO_MODE_OPENGL:
return std::make_unique<renderer_ogl>(window);
#endif
#if defined(OSD_WINDOWS)
case VIDEO_MODE_GDI:
return std::make_unique<renderer_gdi>(window);
case VIDEO_MODE_D3D:
return std::make_unique<renderer_d3d9>(window);
#elif defined(OSD_SDL)
case VIDEO_MODE_SDL2ACCEL:
return std::make_unique<renderer_sdl2>(window, extra_flags);
case VIDEO_MODE_SOFT:
return std::make_unique<renderer_sdl1>(window, extra_flags);
#endif
default:
return nullptr;
}
}
std::shared_ptr<osd_monitor_info> osd_window::monitor_from_rect(const osd_rect *proposed) const
{
std::shared_ptr<osd_monitor_info> monitor;
@ -128,9 +96,6 @@ std::shared_ptr<osd_monitor_info> osd_window::monitor_from_rect(const osd_rect *
void osd_window::create_target()
{
// add us to the list
osd_common_t::s_window_list.push_back(shared_from_this());
// load the layout
m_target = m_machine.render().target_alloc();
@ -139,6 +104,21 @@ void osd_window::create_target()
set_starting_view(m_index, options.view(), options.view(m_index));
}
bool osd_window::renderer_interactive() const
{
return m_renderprovider.is_interactive();
}
bool osd_window::renderer_sdl_needs_opengl() const
{
return m_renderprovider.sdl_needs_opengl();
}
void osd_window::renderer_create()
{
m_renderer = m_renderprovider.create(*this);
}
void osd_window::set_starting_view(int index, const char *defview, const char *view)
{
// choose non-auto over auto
@ -154,9 +134,6 @@ void osd_window::set_starting_view(int index, const char *defview, const char *v
void osd_window::destroy()
{
// remove us from the list
osd_common_t::s_window_list.remove(shared_from_this());
// free the textures etc
complete_destroy();

View File

@ -6,13 +6,19 @@
//
//============================================================
#ifndef __OSDWINDOW__
#define __OSDWINDOW__
#ifndef MAME_OSD_MODULES_OSDWINDOW_H
#define MAME_OSD_MODULES_OSDWINDOW_H
#pragma once
#include "emucore.h"
#include "osdhelper.h"
#include "../frontend/mame/ui/menuitem.h"
#include <memory>
#include <string>
#include <vector>
// standard windows headers
#ifdef OSD_WINDOWS
#include <windows.h>
@ -24,23 +30,12 @@
// TYPE DEFINITIONS
//============================================================
class osd_options;
class osd_monitor_info;
class render_module;
class render_primitive_list;
enum
{
VIDEO_MODE_NONE = 0,
VIDEO_MODE_GDI,
VIDEO_MODE_BGFX,
#if defined(USE_OPENGL) && USE_OPENGL
VIDEO_MODE_OPENGL,
#endif
VIDEO_MODE_SDL2ACCEL,
VIDEO_MODE_D3D,
VIDEO_MODE_SOFT,
class osd_renderer;
VIDEO_MODE_COUNT
};
class osd_window_config
{
@ -54,15 +49,11 @@ public:
int refresh; // decoded refresh
};
class osd_renderer;
class osd_monitor_info;
class osd_window : public std::enable_shared_from_this<osd_window>
class osd_window
{
public:
osd_window(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config &config);
virtual ~osd_window() { }
virtual ~osd_window();
render_target *target() const { return m_target; }
int fullscreen() const { return m_fullscreen; }
@ -71,11 +62,7 @@ public:
bool has_renderer() const { return m_renderer != nullptr; }
osd_renderer &renderer() const { return *m_renderer; }
void set_renderer(std::unique_ptr<osd_renderer> renderer)
{
m_renderer = std::move(renderer);
}
void renderer_reset() { m_renderer.reset(); }
void renderer_reset() { m_renderer.reset(); } // public because OSD object calls it directly during teardown
int index() const { return m_index; }
int prescale() const { return m_prescale; }
@ -91,9 +78,6 @@ public:
osd_monitor_info *monitor() const { return m_monitor.get(); }
std::shared_ptr<osd_monitor_info> monitor_from_rect(const osd_rect *proposed) const;
std::shared_ptr<osd_window> main_window() const { return m_main; }
void set_main_window(std::shared_ptr<osd_window> main) { m_main = main; }
void create_target();
void destroy();
@ -109,6 +93,18 @@ public:
virtual void update() = 0;
virtual void complete_destroy() = 0;
protected:
osd_window(
running_machine &machine,
render_module &renderprovider,
int index,
const std::shared_ptr<osd_monitor_info> &monitor,
const osd_window_config &config);
bool renderer_interactive() const;
bool renderer_sdl_needs_opengl() const;
void renderer_create();
private:
void set_starting_view(int index, const char *defview, const char *view);
@ -127,33 +123,32 @@ private:
protected:
bool m_fullscreen;
int m_prescale;
private:
running_machine &m_machine;
std::shared_ptr<osd_monitor_info> m_monitor;
std::unique_ptr<osd_renderer> m_renderer;
std::shared_ptr<osd_window> m_main;
const std::string m_title;
running_machine &m_machine;
render_module &m_renderprovider;
std::shared_ptr<osd_monitor_info> m_monitor;
std::unique_ptr<osd_renderer> m_renderer;
const std::string m_title;
};
template <class TWindowHandle>
class osd_window_t : public osd_window
{
private:
TWindowHandle m_platform_window;
public:
osd_window_t(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config &config)
: osd_window(machine, index, std::move(monitor), config),
m_platform_window(nullptr)
{
}
TWindowHandle platform_window() const { return m_platform_window; }
protected:
using osd_window::osd_window;
void set_platform_window(TWindowHandle window)
{
assert(window == nullptr || m_platform_window == nullptr);
m_platform_window = window;
}
private:
TWindowHandle m_platform_window = nullptr;
};
@ -163,31 +158,13 @@ public:
/* Generic flags */
static const int FLAG_NONE = 0x0000;
static const int FLAG_NEEDS_OPENGL = 0x0001;
static const int FLAG_HAS_VECTOR_SCREEN = 0x0002;
static const int FLAG_HAS_VECTOR_SCREEN = 0x0001;
/* SDL 1.2 flags */
static const int FLAG_NEEDS_DOUBLEBUF = 0x0100;
static const int FLAG_NEEDS_ASYNCBLIT = 0x0200;
osd_renderer(std::shared_ptr<osd_window> window, const int flags)
: m_sliders_dirty(false), m_window(window), m_flags(flags)
{ }
osd_renderer(osd_window &window) : m_sliders_dirty(false), m_window(window), m_flags(0) { }
virtual ~osd_renderer() { }
std::shared_ptr<osd_window> assert_window() const
{
auto win = m_window.lock();
if (!win)
throw emu_fatalerror("osd_renderer::assert_window: Window weak_ptr is not available!");
return win;
}
std::shared_ptr<osd_window> try_getwindow() const
{
return m_window.lock();
}
osd_window &window() const { return m_window; }
bool has_flags(const int flag) const { return ((m_flags & flag)) == flag; }
void set_flags(int aflag) { m_flags |= aflag; }
@ -209,8 +186,6 @@ public:
virtual void toggle_fsfx() { }
virtual bool sliders_dirty() { return m_sliders_dirty; }
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() { }
@ -220,7 +195,7 @@ protected:
std::vector<ui::menu_item> m_sliders;
private:
std::weak_ptr<osd_window> m_window;
osd_window &m_window;
int m_flags;
};
@ -232,10 +207,6 @@ private:
#define MAX_VIDEO_WINDOWS (4)
#define VIDEO_SCALE_MODE_NONE (0)
#define GLSL_SHADER_MAX 10
//============================================================
// TYPE DEFINITIONS
@ -249,35 +220,19 @@ struct osd_video_config
int numscreens; // number of screens
// hardware options
int mode; // output mode
int waitvsync; // spin until vsync
int syncrefresh; // sync only to refresh rate
int switchres; // switch resolutions
// d3d, accel, opengl
int filter; // enable filtering
//int filter; // enable filtering, disabled if glsl_filter>0
// OpenGL options
int glsl;
int glsl_filter; // glsl filtering, >0 disables filter
char * glsl_shader_mamebm[GLSL_SHADER_MAX]; // custom glsl shader set, mame bitmap
int glsl_shader_mamebm_num; // custom glsl shader set number, mame bitmap
char * glsl_shader_scrn[GLSL_SHADER_MAX]; // custom glsl shader set, screen bitmap
int glsl_shader_scrn_num; // custom glsl shader number, screen bitmap
int pbo;
int vbo;
int allowtexturerect; // allow GL_ARB_texture_rectangle, default: no
int forcepow2texture; // force power of two textures, default: no
// dd, d3d
// d3d
int triplebuf; // triple buffer
//============================================================
// SDL - options
//============================================================
int novideo; // don't draw, for pure CPU benchmarking
int centerh;
int centerv;
@ -289,9 +244,6 @@ struct osd_video_config
// X11 options
int restrictonemonitor; // in fullscreen, confine to Xinerama monitor 0
// YUV options
int scale_mode;
};
//============================================================
@ -300,4 +252,4 @@ struct osd_video_config
extern osd_video_config video_config;
#endif /* __OSDWINDOW__ */
#endif // MAME_OSD_MODULES_OSDWINDOW_H

View File

@ -10,6 +10,7 @@
#include "output_module.h"
#include "modules/lib/osdobj_common.h"
#include "modules/osdmodule.h"
#include "emu.h"
@ -25,6 +26,7 @@
#include <set>
#include <thread>
namespace osd {
namespace {
@ -193,8 +195,7 @@ public:
output_network() :
osd_module(OSD_OUTPUT_PROVIDER, "network"),
output_module(),
m_io_context(nullptr),
m_server(nullptr)
m_machine(nullptr)
{
}
@ -204,6 +205,7 @@ public:
virtual int init(osd_interface &osd, const osd_options &options) override
{
m_machine = &downcast<osd_common_t &>(osd).machine();
m_working_thread = std::thread([] (output_network* self) { self->process_output(); }, this);
return 0;
}
@ -214,8 +216,9 @@ public:
notify("mame_stop", 1);
m_io_context->stop();
m_working_thread.join();
delete m_server;
delete m_io_context;
m_server.reset();
m_io_context.reset();
m_machine = nullptr;
}
// output_module
@ -230,15 +233,18 @@ public:
// implementation
void process_output()
{
m_io_context = new asio::io_context();
m_server = new output_network_server(*m_io_context, 8000, machine());
m_io_context.reset(new asio::io_context);
m_server.reset(new output_network_server(*m_io_context, 8000, machine()));
m_io_context->run();
}
private:
running_machine &machine() { return *m_machine; }
std::thread m_working_thread;
asio::io_context *m_io_context;
output_network_server *m_server;
std::unique_ptr<asio::io_context> m_io_context;
std::unique_ptr<output_network_server> m_server;
running_machine *m_machine;
};
} // anonymous namespace

View File

@ -26,17 +26,9 @@ public:
static inline constexpr unsigned IM_MAME_PAUSE = 0;
static inline constexpr unsigned IM_MAME_SAVESTATE = 1;
output_module(): m_machine(nullptr) { }
virtual ~output_module() = default;
virtual void notify(const char *outname, int32_t value) = 0;
void set_machine(running_machine *machine) { m_machine = machine; }
running_machine &machine() const { return *m_machine; }
private:
running_machine *m_machine;
};
#endif // MAME_OSD_OUTPUT_OUTPUT_MODULE_H

View File

@ -14,12 +14,12 @@
#include "win32_output.h"
// MAME headers
#include "emu.h"
#include "winmain.h"
#include "winutil.h"
// MAME headers
#include "emu.h"
// standard windows headers
#include <windows.h>
@ -71,7 +71,11 @@ class output_win32 : public osd_module, public output_module
{
public:
output_win32()
: osd_module(OSD_OUTPUT_PROVIDER, "windows"), output_module(), m_output_hwnd(nullptr), m_clientlist(nullptr)
: osd_module(OSD_OUTPUT_PROVIDER, "windows")
, output_module()
, m_output_hwnd(nullptr)
, m_clientlist(nullptr)
, m_machine(nullptr)
{
}
virtual ~output_win32() { }
@ -80,21 +84,23 @@ public:
virtual void exit() override;
// output_module
virtual void notify(const char *outname, int32_t value) override;
int create_window_class();
running_machine &machine() { return *m_machine; }
LRESULT register_client(HWND hwnd, LPARAM id);
LRESULT unregister_client(HWND hwnd, LPARAM id);
LRESULT send_id_string(HWND hwnd, LPARAM id);
private:
int create_window_class();
// our HWND
HWND m_output_hwnd;
// client list
registered_client * m_clientlist;
running_machine * m_machine;
};
@ -104,6 +110,8 @@ private:
int output_win32::init(osd_interface &osd, const osd_options &options)
{
m_machine = &downcast<osd_common_t &>(osd).machine();
int result;
// reset globals

View File

@ -6,15 +6,22 @@
//
//============================================================
#ifndef MAME_RENDER_AVIWRITE_H
#define MAME_RENDER_AVIWRITE_H
#pragma once
#ifndef __RENDER_AVIWRITE__
#define __RENDER_AVIWRITE__
#include "eminline.h" // attotime.h needs this - add it to attotime.h on the next emu.h update
// emu
#include "attotime.h"
// lib/util
#include "aviio.h"
#include <string_view>
class running_machine;
class avi_write
@ -49,4 +56,4 @@ private:
attotime m_next_frame_time;
};
#endif // __RENDER_AVIWRITE__
#endif // MAME_RENDER_AVIWRITE_H

View File

@ -44,9 +44,6 @@
using namespace rapidjson;
int32_t chain_manager::s_old_chain_selections[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
bool chain_manager::s_reinit_cookie = false;
chain_manager::screen_prim::screen_prim(render_primitive *prim)
{
m_prim = prim;
@ -61,8 +58,16 @@ chain_manager::screen_prim::screen_prim(render_primitive *prim)
m_flags = prim->flags;
}
chain_manager::chain_manager(running_machine& machine, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index,
slider_dirty_notifier& slider_notifier, uint16_t user_prescale, uint16_t max_prescale_size)
chain_manager::chain_manager(
running_machine& machine,
const osd_options& options,
texture_manager& textures,
target_manager& targets,
effect_manager& effects,
uint32_t window_index,
slider_dirty_notifier& slider_notifier,
uint16_t user_prescale,
uint16_t max_prescale_size)
: m_machine(machine)
, m_options(options)
, m_textures(textures)
@ -79,23 +84,10 @@ chain_manager::chain_manager(running_machine& machine, osd_options& options, tex
refresh_available_chains();
parse_chain_selections(options.bgfx_screen_chains());
init_texture_converters();
if (s_reinit_cookie)
{
for (uint32_t i = 0; i < std::size(s_old_chain_selections); i++)
{
set_current_chain(i, s_old_chain_selections[i]);
}
}
}
chain_manager::~chain_manager()
{
for (uint32_t i = 0; i < std::size(s_old_chain_selections); i++)
{
s_old_chain_selections[i] = i < m_current_chain.size() ? m_current_chain[i] : -1;
}
s_reinit_cookie = true;
destroy_chains();
}

View File

@ -70,7 +70,7 @@ public:
uint32_t m_flags = 0;
};
chain_manager(running_machine& machine, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index,
chain_manager(running_machine& machine, const osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index,
slider_dirty_notifier& slider_notifier, uint16_t user_prescale, uint16_t max_prescale_size);
~chain_manager();
@ -79,7 +79,7 @@ public:
// Getters
running_machine& machine() const { return m_machine; }
osd_options& options() const { return m_options; }
const osd_options& options() const { return m_options; }
texture_manager& textures() const { return m_textures; }
target_manager& targets() const { return m_targets; }
effect_manager& effects() const { return m_effects; }
@ -123,7 +123,7 @@ private:
void process_screen_quad(uint32_t view, uint32_t screen, screen_prim &prim, osd_window& window);
running_machine& m_machine;
osd_options& m_options;
const osd_options& m_options;
texture_manager& m_textures;
target_manager& m_targets;
effect_manager& m_effects;
@ -146,9 +146,6 @@ private:
std::vector<screen_prim> m_screen_prims;
std::vector<uint8_t> m_palette_temp;
static int32_t s_old_chain_selections[16];
static bool s_reinit_cookie;
static inline constexpr uint32_t CHAIN_NONE = 0;
};

View File

@ -13,40 +13,40 @@
#include "modules/osdmodule.h"
#include "osdcore.h"
bgfx_effect::bgfx_effect(std::string name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms)
: m_name(name)
#include <utility>
bgfx_effect::bgfx_effect(std::string &&name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<std::unique_ptr<bgfx_uniform> > &uniforms)
: m_name(std::move(name))
, m_state(state)
{
m_program_handle = bgfx::createProgram(vertex_shader, fragment_shader, false);
for (int i = 0; i < uniforms.size(); i++)
for (auto &uniform : uniforms)
{
if (m_uniforms[uniforms[i]->name()] != nullptr)
const auto existing = m_uniforms.find(uniform->name());
if (existing != m_uniforms.end())
{
osd_printf_verbose("Uniform %s appears to be duplicated in one or more effects, please double-check the effect JSON files.\n", uniforms[i]->name());
delete uniforms[i];
osd_printf_verbose("Uniform %s appears to be duplicated in one or more effects, please double-check the effect JSON files.\n", uniform->name());
uniform.reset();
continue;
}
uniforms[i]->create();
m_uniforms[uniforms[i]->name()] = uniforms[i];
uniform->create();
m_uniforms.emplace(uniform->name(), std::move(uniform));
}
}
bgfx_effect::~bgfx_effect()
{
for (std::pair<std::string, bgfx_uniform*> uniform : m_uniforms)
{
delete uniform.second;
}
m_uniforms.clear();
bgfx::destroy(m_program_handle);
}
void bgfx_effect::submit(int view, uint64_t blend)
{
for (std::pair<std::string, bgfx_uniform*> uniform_pair : m_uniforms)
for (auto &[name, uniform] : m_uniforms)
{
(uniform_pair.second)->upload();
uniform->upload();
}
const uint64_t final_state = (blend != ~0ULL) ? ((m_state & ~BGFX_STATE_BLEND_MASK) | blend) : m_state;
@ -55,8 +55,8 @@ void bgfx_effect::submit(int view, uint64_t blend)
bgfx::submit(view, m_program_handle);
}
bgfx_uniform* bgfx_effect::uniform(std::string name)
bgfx_uniform* bgfx_effect::uniform(const std::string &name)
{
auto iter = m_uniforms.find(name);
return iter != m_uniforms.end() ? iter->second : nullptr;
const auto iter = m_uniforms.find(name);
return (iter != m_uniforms.end()) ? iter->second.get() : nullptr;
}

View File

@ -6,34 +6,36 @@
//
//============================================================
#pragma once
#ifndef MAME_RENDER_BGFX_EFFECT_H
#define MAME_RENDER_BGFX_EFFECT_H
#ifndef __DRAWBGFX_EFFECT__
#define __DRAWBGFX_EFFECT__
#pragma once
#include <bgfx/bgfx.h>
#include <vector>
#include <map>
#include <memory>
#include <string>
#include <vector>
class bgfx_uniform;
class bgfx_effect
{
public:
bgfx_effect(std::string name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms);
bgfx_effect(std::string &&name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<std::unique_ptr<bgfx_uniform> > &uniforms);
~bgfx_effect();
void submit(int view, uint64_t blend = ~0ULL);
bgfx_uniform *uniform(std::string name);
bool is_valid() { return m_program_handle.idx != bgfx::kInvalidHandle; }
bgfx_uniform *uniform(const std::string &name);
bool is_valid() const { return m_program_handle.idx != bgfx::kInvalidHandle; }
private:
std::string m_name;
uint64_t m_state;
bgfx::ProgramHandle m_program_handle;
std::map<std::string, bgfx_uniform*> m_uniforms;
std::map<std::string, std::unique_ptr<bgfx_uniform> > m_uniforms;
};
#endif // __DRAWBGFX_EFFECT__
#endif // MAME_RENDER_BGFX_EFFECT_H

View File

@ -11,8 +11,11 @@
#include "effectmanager.h"
#include "effectreader.h"
#include "effect.h"
#include "effectreader.h"
#include "shadermanager.h"
#include "path.h"
#include "osdfile.h"
#include "modules/lib/osdobj_common.h"
@ -25,16 +28,18 @@
#include <bgfx/bgfx.h>
static bool prepare_effect_document(std::string &name, osd_options &options, rapidjson::Document &document)
#include <utility>
static bool prepare_effect_document(const std::string &name, const osd_options &options, rapidjson::Document &document)
{
std::string full_name = name;
if (full_name.length() < 5 || (full_name.compare(full_name.length() - 5, 5, ".json") != 0))
{
full_name = full_name + ".json";
full_name += ".json";
}
std::string path = util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, options.bgfx_path());
path += full_name;
const std::string path = util::path_concat(options.bgfx_path(), "effects", full_name);
bx::FileReader reader;
if (!bx::open(&reader, path.c_str()))
@ -43,49 +48,55 @@ static bool prepare_effect_document(std::string &name, osd_options &options, rap
return false;
}
const int32_t size = bx::getSize(&reader);
std::unique_ptr<char []> data(new (std::nothrow) char [size + 1]);
if (!data)
{
osd_printf_error("Out of memory reading effect file %s\n", path);
bx::close(&reader);
return false;
}
bx::ErrorAssert err;
int32_t size (bx::getSize(&reader));
char* data = new char[size + 1];
bx::read(&reader, reinterpret_cast<void*>(data), size, &err);
bx::read(&reader, reinterpret_cast<void*>(data.get()), size, &err);
bx::close(&reader);
data[size] = 0;
document.Parse<rapidjson::kParseCommentsFlag>(data);
delete [] data;
document.Parse<rapidjson::kParseCommentsFlag>(data.get());
data.reset();
if (document.HasParseError())
{
std::string error(rapidjson::GetParseError_En(document.GetParseError()));
osd_printf_error("Unable to parse effect %s. Errors returned:\n", path);
osd_printf_error("%s\n", error);
osd_printf_error("Unable to parse effect %s. Errors returned:\n%s\n", path, error);
return false;
}
return true;
}
effect_manager::~effect_manager()
// keep constructor and destructor out-of-line so the header works with forward declarations
effect_manager::effect_manager(shader_manager& shaders) : m_shaders(shaders)
{
for (std::pair<std::string, bgfx_effect*> effect : m_effects)
{
delete effect.second;
}
m_effects.clear();
}
bgfx_effect* effect_manager::get_or_load_effect(osd_options &options, std::string name)
effect_manager::~effect_manager()
{
std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name);
// the map will automatically dispose of the effects
}
bgfx_effect* effect_manager::get_or_load_effect(const osd_options &options, const std::string &name)
{
const auto iter = m_effects.find(name);
if (iter != m_effects.end())
{
return iter->second;
}
return iter->second.get();
return load_effect(options, name);
}
bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name)
bgfx_effect* effect_manager::load_effect(const osd_options &options, const std::string &name)
{
rapidjson::Document document;
if (!prepare_effect_document(name, options, document))
@ -93,20 +104,18 @@ bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name)
return nullptr;
}
bgfx_effect* effect = effect_reader::read_from_value(name, document, "Effect '" + name + "': ", options, m_shaders);
std::unique_ptr<bgfx_effect> effect = effect_reader::read_from_value(name, document, "Effect '" + name + "': ", options, m_shaders);
if (effect == nullptr)
if (!effect)
{
osd_printf_error("Unable to load effect %s\n", name);
return nullptr;
}
m_effects[name] = effect;
return effect;
return m_effects.emplace(name, std::move(effect)).first->second.get();
}
bool effect_manager::validate_effect(osd_options &options, std::string name)
bool effect_manager::validate_effect(const osd_options &options, const std::string &name)
{
rapidjson::Document document;
if (!prepare_effect_document(name, options, document))

View File

@ -9,34 +9,35 @@
//
//============================================================
#ifndef MAME_RENDER_BGFX_EFFECTMANAGER_H
#define MAME_RENDER_BGFX_EFFECTMANAGER_H
#pragma once
#ifndef __DRAWBGFX_EFFECT_MANAGER__
#define __DRAWBGFX_EFFECT_MANAGER__
#include <map>
#include <memory>
#include <string>
#include <bgfx/bgfx.h>
#include "shadermanager.h"
class bgfx_effect;
class osd_options;
class shader_manager;
class effect_manager {
class effect_manager
{
public:
effect_manager(shader_manager& shaders) : m_shaders(shaders) { }
effect_manager(shader_manager& shaders);
~effect_manager();
// Getters
bgfx_effect* get_or_load_effect(osd_options &options, std::string name);
static bool validate_effect(osd_options &options, std::string name);
bgfx_effect* get_or_load_effect(const osd_options &options, const std::string &name);
static bool validate_effect(const osd_options &options, const std::string &name);
private:
bgfx_effect* load_effect(osd_options& options, std::string name);
bgfx_effect* load_effect(const osd_options &options, const std::string &name);
shader_manager& m_shaders;
std::map<std::string, bgfx_effect*> m_effects;
shader_manager &m_shaders;
std::map<std::string, std::unique_ptr<bgfx_effect> > m_effects;
};
#endif // __DRAWBGFX_EFFECT_MANAGER__
#endif // MAME_RENDER_BGFX_EFFECTMANAGER_H

View File

@ -8,80 +8,79 @@
#include "effectreader.h"
#include "effect.h"
#include "blendreader.h"
#include "depthreader.h"
#include "cullreader.h"
#include "writereader.h"
#include "depthreader.h"
#include "effect.h"
#include "shadermanager.h"
#include "uniformreader.h"
#include "uniform.h"
#include "uniformreader.h"
#include "writereader.h"
bgfx_effect *effect_reader::read_from_value(std::string name, const Value& value, const std::string &prefix, osd_options &options, shader_manager& shaders)
#include <utility>
std::unique_ptr<bgfx_effect> effect_reader::read_from_value(
const std::string &name,
const Value &value,
const std::string &prefix,
const osd_options &options,
shader_manager &shaders)
{
uint64_t flags = 0;
std::string vertex_name;
std::string fragment_name;
bgfx::ShaderHandle vertex_shader = BGFX_INVALID_HANDLE;
bgfx::ShaderHandle fragment_shader = BGFX_INVALID_HANDLE;
std::vector<bgfx_uniform *> uniforms;
std::vector<std::unique_ptr<bgfx_uniform> > uniforms;
if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms))
{
return nullptr;
}
bgfx::ShaderHandle vertex_shader = BGFX_INVALID_HANDLE;
bgfx::ShaderHandle fragment_shader = BGFX_INVALID_HANDLE;
if (!get_shader_data(value, options, shaders, vertex_name, vertex_shader, fragment_name, fragment_shader))
{
clear_uniform_list(uniforms);
return nullptr;
}
bgfx_effect *effect = new bgfx_effect(name, flags, vertex_shader, fragment_shader, uniforms);
if (effect->is_valid())
{
return effect;
}
std::unique_ptr<bgfx_effect> effect(new bgfx_effect(std::string(name), flags, vertex_shader, fragment_shader, uniforms));
if (!effect->is_valid())
return nullptr;
delete effect;
return nullptr;
return effect;
}
bool effect_reader::validate_value(const Value& value, const std::string &prefix, osd_options &options)
bool effect_reader::validate_value(const Value& value, const std::string &prefix, const osd_options &options)
{
if (!validate_parameters(value, prefix))
{
return false;
}
uint64_t flags = 0;
std::string vertex_name;
std::string fragment_name;
std::vector<bgfx_uniform *> uniforms;
std::vector<std::unique_ptr<bgfx_uniform> > uniforms;
if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms))
{
return false;
}
if (!shader_manager::is_shader_present(options, vertex_name))
{
clear_uniform_list(uniforms);
return false;
}
if (!shader_manager::is_shader_present(options, fragment_name))
{
clear_uniform_list(uniforms);
return false;
}
return true;
}
bool effect_reader::get_base_effect_data(const Value& value, const std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
std::vector<bgfx_uniform *> &uniforms)
bool effect_reader::get_base_effect_data(
const Value& value,
const std::string &prefix,
uint64_t &flags,
std::string &vertex_name,
std::string &fragment_name,
std::vector<std::unique_ptr<bgfx_uniform> > &uniforms)
{
if (!validate_parameters(value, prefix))
{
@ -101,12 +100,12 @@ bool effect_reader::get_base_effect_data(const Value& value, const std::string &
const Value& uniform_array = value["uniforms"];
for (uint32_t i = 0; i < uniform_array.Size(); i++)
{
bgfx_uniform *uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
if (uniform == nullptr)
auto uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
if (!uniform)
{
return false;
}
uniforms.push_back(uniform);
uniforms.emplace_back(std::move(uniform));
}
vertex_name = value["vertex"].GetString();
@ -127,8 +126,14 @@ bool effect_reader::get_base_effect_data(const Value& value, const std::string &
return true;
}
bool effect_reader::get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
std::string &fragment_name, bgfx::ShaderHandle &fragment_shader)
bool effect_reader::get_shader_data(
const Value &value,
const osd_options &options,
shader_manager &shaders,
std::string &vertex_name,
bgfx::ShaderHandle &vertex_shader,
std::string &fragment_name,
bgfx::ShaderHandle &fragment_shader)
{
vertex_shader = shaders.load_shader(options, vertex_name);
if (vertex_shader.idx == bgfx::kInvalidHandle)
@ -145,14 +150,6 @@ bool effect_reader::get_shader_data(const Value& value, osd_options &options, sh
return true;
}
void effect_reader::clear_uniform_list(std::vector<bgfx_uniform *> &uniforms)
{
for (bgfx_uniform *uniform : uniforms)
{
delete uniform;
}
}
bool effect_reader::validate_parameters(const Value& value, const std::string &prefix)
{
if (!READER_CHECK(value.HasMember("depth"), "%sMust have object value 'depth' (what are our Z-buffer settings?)\n", prefix)) return false;

View File

@ -15,26 +15,28 @@
#include <bgfx/bgfx.h>
#include <memory>
#include <string>
#include <vector>
class bgfx_effect;
class bgfx_uniform;
class osd_options;
class shader_manager;
class effect_reader : public state_reader
{
public:
static bgfx_effect *read_from_value(std::string name, const Value& value, const std::string &prefix, osd_options &options, shader_manager& shaders);
static bool validate_value(const Value& value, const std::string &prefix, osd_options &options);
static std::unique_ptr<bgfx_effect> read_from_value(const std::string &name, const Value& value, const std::string &prefix, const osd_options &options, shader_manager& shaders);
static bool validate_value(const Value& value, const std::string &prefix, const osd_options &options);
private:
static bool get_base_effect_data(const Value& value, const std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
std::vector<bgfx_uniform *> &uniforms);
static bool get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
std::vector<std::unique_ptr<bgfx_uniform> > &uniforms);
static bool get_shader_data(const Value& value, const osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
std::string &fragment_name, bgfx::ShaderHandle &fragment_shader);
static void clear_uniform_list(std::vector<bgfx_uniform *> &uniforms);
static bool validate_parameters(const Value& value, const std::string &prefix);
};

View File

@ -16,11 +16,10 @@
#include "osdfile.h"
#include "modules/lib/osdobj_common.h"
#include <bx/file.h>
#include <bx/math.h>
#include <bx/readerwriter.h>
#include <bx/file.h>
#include <bgfx/bgfx.h>
shader_manager::~shader_manager()
{
@ -31,7 +30,7 @@ shader_manager::~shader_manager()
m_shaders.clear();
}
bgfx::ShaderHandle shader_manager::get_or_load_shader(osd_options &options, const std::string &name)
bgfx::ShaderHandle shader_manager::get_or_load_shader(const osd_options &options, const std::string &name)
{
std::map<std::string, bgfx::ShaderHandle>::iterator iter = m_shaders.find(name);
if (iter != m_shaders.end())
@ -48,7 +47,7 @@ bgfx::ShaderHandle shader_manager::get_or_load_shader(osd_options &options, cons
return handle;
}
bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, const std::string &name)
bgfx::ShaderHandle shader_manager::load_shader(const osd_options &options, const std::string &name)
{
std::string shader_path = make_path_string(options, name);
const bgfx::Memory* mem = load_mem(shader_path + name + ".bin");
@ -60,7 +59,7 @@ bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, const std::
return BGFX_INVALID_HANDLE;
}
bool shader_manager::is_shader_present(osd_options &options, const std::string &name)
bool shader_manager::is_shader_present(const osd_options &options, const std::string &name)
{
std::string shader_path = make_path_string(options, name);
std::string file_name = shader_path + name + ".bin";
@ -80,7 +79,7 @@ bool shader_manager::is_shader_present(osd_options &options, const std::string &
return false;
}
std::string shader_manager::make_path_string(osd_options &options, const std::string &name)
std::string shader_manager::make_path_string(const osd_options &options, const std::string &name)
{
std::string shader_path(options.bgfx_path());
shader_path += PATH_SEPARATOR "shaders" PATH_SEPARATOR;

View File

@ -22,21 +22,23 @@
class osd_options;
class shader_manager {
class shader_manager
{
public:
shader_manager() { }
~shader_manager();
// Getters
bgfx::ShaderHandle get_or_load_shader(osd_options &options, const std::string &name);
static bgfx::ShaderHandle load_shader(osd_options &options, const std::string &name);
static bool is_shader_present(osd_options &options, const std::string &name);
bgfx::ShaderHandle get_or_load_shader(const osd_options &options, const std::string &name);
static bgfx::ShaderHandle load_shader(const osd_options &options, const std::string &name);
static bool is_shader_present(const osd_options &options, const std::string &name);
private:
static std::string make_path_string(osd_options &options, const std::string &name);
static std::string make_path_string(const osd_options &options, const std::string &name);
static const bgfx::Memory* load_mem(const std::string &name);
std::map<std::string, bgfx::ShaderHandle> m_shaders;
std::map<std::string, bgfx::ShaderHandle> m_shaders;
};
#endif // MAME_RENDER_BGFX_SHADERMANAGER_H

View File

@ -10,6 +10,9 @@
#include "uniform.h"
#include <cstdlib>
const uniform_reader::string_to_enum uniform_reader::TYPE_NAMES[uniform_reader::TYPE_COUNT] = {
{ "int", bgfx::UniformType::Sampler },
{ "vec4", bgfx::UniformType::Vec4 },
@ -17,7 +20,7 @@ const uniform_reader::string_to_enum uniform_reader::TYPE_NAMES[uniform_reader::
{ "mat4", bgfx::UniformType::Mat4 }
};
bgfx_uniform* uniform_reader::read_from_value(const Value& value, const std::string &prefix)
std::unique_ptr<bgfx_uniform> uniform_reader::read_from_value(const Value& value, const std::string &prefix)
{
if (!validate_parameters(value, prefix))
{
@ -31,23 +34,18 @@ bgfx_uniform* uniform_reader::read_from_value(const Value& value, const std::str
const Value& value_array = value["values"];
const size_t array_size = value_array.Size() * sizeof(float);
const size_t alloc_size = (type_size > array_size) ? type_size : array_size;
auto* data = reinterpret_cast<float*>(new char[alloc_size]);
auto* data = reinterpret_cast<float*>(std::malloc(std::max(type_size, array_size)));
unsigned int index = 0;
for (; index < type_size / 4 && index < value_array.Size(); index++)
{
data[index] = float(value_array[index].GetDouble());
}
for (; index < type_size / 4; index++)
{
data[index] = 0.0f;
}
bgfx_uniform* uniform = new bgfx_uniform(name, type);
uniform->set((void*)data, type_size);
delete [] data;
auto uniform = std::make_unique<bgfx_uniform>(name, type);
uniform->set(data, type_size);
std::free(data);
return uniform;
}

View File

@ -13,12 +13,16 @@
#include "statereader.h"
#include <memory>
#include <string>
class bgfx_uniform;
class uniform_reader : public state_reader
{
public:
static bgfx_uniform* read_from_value(const Value& value, const std::string &prefix);
static std::unique_ptr<bgfx_uniform> read_from_value(const Value& value, const std::string &prefix);
private:
static bool validate_parameters(const Value& value, const std::string &prefix);

View File

@ -13,9 +13,7 @@
#include "target.h"
void bgfx_view::update() {
std::shared_ptr<osd_window> win = m_renderer->assert_window();
const uint32_t window_index = win->index();
const uint32_t window_index = m_renderer->window().index();
const uint32_t width = m_renderer->get_window_width(window_index);
const uint32_t height = m_renderer->get_window_height(window_index);

View File

@ -4,12 +4,14 @@
#pragma once
#include "window.h"
#include <climits>
class renderer_bgfx;
class bgfx_target;
class bgfx_view {
class bgfx_view
{
public:
bgfx_view(renderer_bgfx *renderer, uint32_t index, bgfx_target *backbuffer, std::vector<uint32_t> &seen_views)
: m_renderer(renderer)

View File

@ -6,8 +6,22 @@
//
//============================================================
#ifndef __WIN_D3DCOMM__
#define __WIN_D3DCOMM__
#ifndef MAME_RENDER_D3D_D3DCOMM_H
#define MAME_RENDER_D3D_D3DCOMM_H
#pragma once
// lib/util
#include "bitmap.h"
#include <windows.h>
#include <d3d9.h>
#include <wrl/client.h>
#include <cstring>
#include <memory>
#include <vector>
//============================================================
// CONSTANTS
@ -60,10 +74,7 @@ public:
class d3d_texture_manager
{
public:
d3d_texture_manager(): m_renderer(nullptr), m_yuv_format(), m_texture_caps(0), m_texture_max_aspect(0), m_texture_max_width(0), m_texture_max_height(0), m_default_texture(nullptr)
{ }
d3d_texture_manager(renderer_d3d9 *d3d);
d3d_texture_manager(renderer_d3d9 &d3d, IDirect3D9 *d3dobj);
void update_textures();
@ -82,12 +93,12 @@ public:
texture_info * get_default_texture() const { return m_default_texture; }
renderer_d3d9 * get_d3d() const { return m_renderer; }
renderer_d3d9 & get_d3d() const { return m_renderer; }
std::vector<std::unique_ptr<texture_info>> m_texture_list; // list of active textures
std::vector<std::unique_ptr<texture_info> > m_texture_list; // list of active textures
private:
renderer_d3d9 * m_renderer;
renderer_d3d9 & m_renderer;
D3DFORMAT m_yuv_format; // format to use for YUV textures
DWORD m_texture_caps; // textureCaps field
@ -104,7 +115,7 @@ private:
class texture_info
{
public:
texture_info(d3d_texture_manager *manager, const render_texinfo *texsource, int prescale, uint32_t flags);
texture_info(d3d_texture_manager &manager, const render_texinfo *texsource, int prescale, uint32_t flags);
~texture_info();
render_texinfo & get_texinfo() { return m_texinfo; }
@ -125,15 +136,16 @@ public:
int get_cur_frame() const { return m_cur_frame; }
IDirect3DTexture9 * get_tex() const { return m_d3dtex; }
IDirect3DSurface9 * get_surface() const { return m_d3dsurface; }
IDirect3DTexture9 * get_finaltex() const { return m_d3dfinaltex; }
IDirect3DTexture9 * get_finaltex() const { return m_d3dfinaltex.Get(); }
vec2f & get_uvstart() { return m_start; }
vec2f & get_uvstop() { return m_stop; }
vec2f & get_rawdims() { return m_rawdims; }
private:
using IDirect3DTexture9Ptr = Microsoft::WRL::ComPtr<IDirect3DTexture9>;
using IDirect3DSurface9Ptr = Microsoft::WRL::ComPtr<IDirect3DSurface9>;
void prescale();
void compute_size(int texwidth, int texheight);
void compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height);
@ -145,23 +157,23 @@ private:
inline void copyline_yuy16_to_uyvy(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette);
inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette);
d3d_texture_manager * m_texture_manager; // texture manager pointer
d3d_texture_manager & m_texture_manager; // texture manager pointer
renderer_d3d9 * m_renderer; // renderer pointer
renderer_d3d9 & m_renderer; // renderer pointer
uint32_t m_hash; // hash value for the texture
uint32_t m_flags; // rendering flags
const uint32_t m_hash; // hash value for the texture
const uint32_t m_flags; // rendering flags
render_texinfo m_texinfo; // copy of the texture info
const int m_type; // what type of texture are we?
vec2f m_start; // beggining UV coordinates
vec2f m_stop; // ending UV coordinates
vec2f m_rawdims; // raw dims of the texture
int m_type; // what type of texture are we?
int m_xprescale, m_yprescale; // X/Y prescale factor
int m_xborderpix, m_yborderpix; // X/Y border pixels
int m_cur_frame; // what is our current frame?
IDirect3DTexture9 * m_d3dtex; // Direct3D texture pointer
IDirect3DSurface9 * m_d3dsurface; // Direct3D offscreen plain surface pointer
IDirect3DTexture9 * m_d3dfinaltex; // Direct3D final (post-scaled) texture
IDirect3DTexture9Ptr m_d3dtex; // Direct3D texture pointer
IDirect3DSurface9Ptr m_d3dsurface; // Direct3D offscreen plain surface pointer
IDirect3DTexture9Ptr m_d3dfinaltex; // Direct3D final (post-scaled) texture
};
/* poly_info holds information about a single polygon/d3d primitive */
@ -227,24 +239,14 @@ class d3d_render_target
{
public:
// construction/destruction
d3d_render_target(): target_width(0), target_height(0), width(0), height(0), screen_index(0), bloom_count(0)
d3d_render_target()
: target_width(0)
, target_height(0)
, width(0)
, height(0)
, screen_index(0)
, bloom_count(0)
{
for (int index = 0; index < MAX_BLOOM_COUNT; index++)
{
bloom_texture[index] = nullptr;
bloom_surface[index] = nullptr;
}
for (int index = 0; index < 2; index++)
{
source_texture[index] = nullptr;
source_surface[index] = nullptr;
target_texture[index] = nullptr;
target_surface[index] = nullptr;
}
cache_texture = nullptr;
cache_surface = nullptr;
}
~d3d_render_target();
@ -262,20 +264,20 @@ public:
int screen_index;
IDirect3DSurface9 *target_surface[2];
IDirect3DTexture9 *target_texture[2];
IDirect3DSurface9 *source_surface[2];
IDirect3DTexture9 *source_texture[2];
Microsoft::WRL::ComPtr<IDirect3DSurface9> target_surface[2];
Microsoft::WRL::ComPtr<IDirect3DTexture9> target_texture[2];
Microsoft::WRL::ComPtr<IDirect3DSurface9> source_surface[2];
Microsoft::WRL::ComPtr<IDirect3DTexture9> source_texture[2];
IDirect3DSurface9 *cache_surface;
IDirect3DTexture9 *cache_texture;
Microsoft::WRL::ComPtr<IDirect3DSurface9> cache_surface;
Microsoft::WRL::ComPtr<IDirect3DTexture9> cache_texture;
IDirect3DSurface9 *bloom_surface[MAX_BLOOM_COUNT];
IDirect3DTexture9 *bloom_texture[MAX_BLOOM_COUNT];
Microsoft::WRL::ComPtr<IDirect3DSurface9> bloom_surface[MAX_BLOOM_COUNT];
Microsoft::WRL::ComPtr<IDirect3DTexture9> bloom_texture[MAX_BLOOM_COUNT];
float bloom_dims[MAX_BLOOM_COUNT][2];
int bloom_count;
};
#endif
#endif // MAME_RENDER_D3D_D3DCOMM_H

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,11 @@
#include "../frontend/mame/ui/slider.h"
#include "modules/lib/osdlib.h"
#include <vector>
#include <wrl/client.h>
#include <map>
#include <memory>
#include <vector>
//============================================================
// TYPE DEFINITIONS
@ -308,9 +311,9 @@ public:
shaders();
~shaders();
bool init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer);
bool init(IDirect3D9 *d3dobj, running_machine *machine, renderer_d3d9 *renderer);
bool enabled() { return post_fx_enable && d3dintf->post_fx_available; }
bool enabled() { return post_fx_enable && d3d->post_fx_available(); }
void toggle() { post_fx_enable = initialized && !post_fx_enable; }
void begin_frame(render_primitive_list *primlist);
@ -348,6 +351,10 @@ public:
void *get_slider_option(int id, int index = 0);
private:
using IDirect3D9Ptr = Microsoft::WRL::ComPtr<IDirect3D9>;
using IDirect3DTexture9Ptr = Microsoft::WRL::ComPtr<IDirect3DTexture9>;
using IDirect3DSurface9Ptr = Microsoft::WRL::ComPtr<IDirect3DSurface9>;
void set_curr_effect(effect *curr_effect);
void blit(IDirect3DSurface9 *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, uint32_t prim_index, uint32_t prim_count);
@ -376,7 +383,7 @@ private:
int screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
void ui_pass(poly_info *poly, int vertnum);
d3d_base * d3dintf; // D3D interface
IDirect3D9Ptr d3dobj; // D3D interface
running_machine * machine;
renderer_d3d9 * d3d; // D3D renderer
@ -398,43 +405,43 @@ private:
texture_info * ui_lut_texture;
hlsl_options * options; // current options
IDirect3DSurface9 * black_surface; // black dummy surface
IDirect3DTexture9 * black_texture; // black dummy texture
IDirect3DSurface9Ptr black_surface; // black dummy surface
IDirect3DTexture9Ptr black_texture; // black dummy texture
bool recording_movie; // ongoing movie recording
std::unique_ptr<movie_recorder> recorder; // HLSL post-render movie recorder
bool render_snap; // whether or not to take HLSL post-render snapshot
IDirect3DSurface9 * snap_copy_target; // snapshot destination surface in system memory
IDirect3DTexture9 * snap_copy_texture; // snapshot destination surface in system memory
IDirect3DSurface9 * snap_target; // snapshot upscaled surface
IDirect3DTexture9 * snap_texture; // snapshot upscaled texture
IDirect3DSurface9Ptr snap_copy_target; // snapshot destination surface in system memory
IDirect3DTexture9Ptr snap_copy_texture; // snapshot destination surface in system memory
IDirect3DSurface9Ptr snap_target; // snapshot upscaled surface
IDirect3DTexture9Ptr snap_texture; // snapshot upscaled texture
int snap_width; // snapshot width
int snap_height; // snapshot height
bool initialized; // whether or not we're initialized
// HLSL effects
IDirect3DSurface9 * backbuffer; // pointer to our device's backbuffer
IDirect3DSurface9Ptr backbuffer; // pointer to our device's backbuffer
effect * curr_effect; // pointer to the currently active effect object
effect * default_effect; // pointer to the primary-effect object
effect * ui_effect; // pointer to the UI-element effect object
effect * ui_wrap_effect; // pointer to the UI-element effect object with texture wrapping
effect * vector_buffer_effect; // pointer to the vector-buffering effect object
effect * prescale_effect; // pointer to the prescale-effect object
effect * prescale_point_effect; // pointer to the prescale-effect object with point filtering
effect * post_effect; // pointer to the post-effect object
effect * distortion_effect; // pointer to the distortion-effect object
effect * scanline_effect;
effect * focus_effect; // pointer to the focus-effect object
effect * phosphor_effect; // pointer to the phosphor-effect object
effect * deconverge_effect; // pointer to the deconvergence-effect object
effect * color_effect; // pointer to the color-effect object
effect * ntsc_effect; // pointer to the NTSC effect object
effect * bloom_effect; // pointer to the bloom composite effect
effect * downsample_effect; // pointer to the bloom downsample effect
effect * vector_effect; // pointer to the vector-effect object
effect * chroma_effect;
std::unique_ptr<effect> default_effect; // pointer to the primary-effect object
std::unique_ptr<effect> ui_effect; // pointer to the UI-element effect object
std::unique_ptr<effect> ui_wrap_effect; // pointer to the UI-element effect object with texture wrapping
std::unique_ptr<effect> vector_buffer_effect; // pointer to the vector-buffering effect object
std::unique_ptr<effect> prescale_effect; // pointer to the prescale-effect object
std::unique_ptr<effect> prescale_point_effect; // pointer to the prescale-effect object with point filtering
std::unique_ptr<effect> post_effect; // pointer to the post-effect object
std::unique_ptr<effect> distortion_effect; // pointer to the distortion-effect object
std::unique_ptr<effect> scanline_effect;
std::unique_ptr<effect> focus_effect; // pointer to the focus-effect object
std::unique_ptr<effect> phosphor_effect; // pointer to the phosphor-effect object
std::unique_ptr<effect> deconverge_effect; // pointer to the deconvergence-effect object
std::unique_ptr<effect> color_effect; // pointer to the color-effect object
std::unique_ptr<effect> ntsc_effect; // pointer to the NTSC effect object
std::unique_ptr<effect> bloom_effect; // pointer to the bloom composite effect
std::unique_ptr<effect> downsample_effect; // pointer to the bloom downsample effect
std::unique_ptr<effect> vector_effect; // pointer to the vector-effect object
std::unique_ptr<effect> chroma_effect;
texture_info * diffuse_texture;
bool filter_screens;
@ -444,9 +451,9 @@ private:
std::vector<std::unique_ptr<d3d_render_target>> m_render_target_list;
std::vector<slider*> internal_sliders;
std::vector<std::unique_ptr<slider> > internal_sliders;
std::vector<ui::menu_item> m_sliders;
std::vector<std::unique_ptr<slider_state>> m_core_sliders;
std::vector<std::unique_ptr<slider_state> > m_core_sliders;
static slider_desc s_sliders[];
static hlsl_options last_options; // last used options

View File

@ -2,7 +2,7 @@
// copyright-holders: Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
// draw13.c - SDL 2.0 drawing implementation
// draw13.cpp - SDL 2.0 drawing implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
@ -10,8 +10,11 @@
//
//============================================================
#include "emu.h"
#include "draw13.h"
#include "render_module.h"
#include "modules/osdmodule.h"
#if defined(OSD_SDL)
// OSD headers
#include "sdlopts.h"
@ -20,9 +23,190 @@
// lib/util
#include "options.h"
// emu
#include "emucore.h"
#include "render.h"
// standard SDL headers
#include <SDL2/SDL.h>
// standard C headers
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iterator>
namespace osd {
namespace {
struct quad_setup_data
{
quad_setup_data() = default;
void compute(const render_primitive &prim, const int prescale);
int32_t dudx = 0, dvdx = 0, dudy = 0, dvdy = 0;
int32_t startu = 0, startv = 0;
int32_t rotwidth = 0, rotheight = 0;
};
//============================================================
// Textures
//============================================================
class renderer_sdl2;
struct copy_info_t;
/* texture_info holds information about a texture */
class texture_info
{
friend class simple_list<texture_info>;
public:
texture_info(renderer_sdl2 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const uint32_t flags);
~texture_info();
void set_data(const render_texinfo &texsource, const uint32_t flags);
void render_quad(const render_primitive &prim, const int x, const int y);
bool matches(const render_primitive &prim, const quad_setup_data &setup);
copy_info_t const *compute_size_type();
void *m_pixels; // pixels for the texture
int m_pitch;
copy_info_t const *m_copyinfo;
quad_setup_data m_setup;
osd_ticks_t m_last_access;
int raw_width() const { return m_texinfo.width; }
int raw_height() const { return m_texinfo.height; }
texture_info *next() { return m_next; }
const render_texinfo &texinfo() const { return m_texinfo; }
render_texinfo &texinfo() { return m_texinfo; }
HashT hash() const { return m_hash; }
uint32_t flags() const { return m_flags; }
// FIXME:
bool is_pixels_owned() const;
private:
void set_coloralphamode(SDL_Texture *texture_id, const render_color *color);
Uint32 m_sdl_access;
renderer_sdl2 * m_renderer;
render_texinfo m_texinfo; // copy of the texture info
HashT m_hash; // hash value for the texture (must be >= pointer size)
uint32_t m_flags; // rendering flags
SDL_Texture * m_texture_id;
bool m_is_rotated;
int m_format; // texture format
SDL_BlendMode m_sdl_blendmode;
texture_info * m_next; // next texture in the list
};
// inline functions and macros
#include "blit13.ipp"
//============================================================
// TEXCOPY FUNCS
//============================================================
enum SDL_TEXFORMAT_E
{
SDL_TEXFORMAT_ARGB32 = 0,
SDL_TEXFORMAT_RGB32,
SDL_TEXFORMAT_RGB32_PALETTED,
SDL_TEXFORMAT_YUY16,
SDL_TEXFORMAT_YUY16_PALETTED,
SDL_TEXFORMAT_PALETTE16,
SDL_TEXFORMAT_RGB15,
SDL_TEXFORMAT_RGB15_PALETTED,
SDL_TEXFORMAT_PALETTE16A,
SDL_TEXFORMAT_PALETTE16_ARGB1555,
SDL_TEXFORMAT_RGB15_ARGB1555,
SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555,
SDL_TEXFORMAT_LAST = SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555
};
struct copy_info_t
{
int src_fmt;
Uint32 dst_fmt;
const blit_base *blitter;
Uint32 bm_mask;
const char *srcname;
const char *dstname;
/* Statistics */
mutable uint64_t pixel_count;
mutable int64_t time;
mutable int samples;
mutable int perf;
/* list */
copy_info_t *next;
};
/* renderer_sdl2 is the information about SDL for the current screen */
class renderer_sdl2 : public osd_renderer
{
public:
renderer_sdl2(
osd_window &window,
copy_info_t const *const (&blit_info)[SDL_TEXFORMAT_LAST + 1]);
virtual ~renderer_sdl2()
{
destroy_all_textures();
SDL_DestroyRenderer(m_sdl_renderer);
m_sdl_renderer = nullptr;
}
virtual int create() override;
virtual int draw(const int update) override;
virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
virtual render_primitive_list *get_primitives() override;
int RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat);
SDL_Renderer *m_sdl_renderer;
copy_info_t const *const (&m_blit_info)[SDL_TEXFORMAT_LAST + 1];
private:
void render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y);
texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
texture_info *texture_update(const render_primitive &prim);
void destroy_all_textures();
int32_t m_blittimer;
simple_list<texture_info> m_texlist; // list of active textures
float m_last_hofs;
float m_last_vofs;
int m_width;
int m_height;
osd_dim m_blit_dim;
struct
{
Uint32 format;
int status;
} fmt_support[30];
// Stats
int64_t m_last_blit_time;
int64_t m_last_blit_pixels;
};
//============================================================
@ -57,9 +241,12 @@ static inline bool is_transparent(const float &a)
// CONSTRUCTOR & DESTRUCTOR
//============================================================
renderer_sdl2::renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags)
: osd_renderer(window, FLAG_NEEDS_OPENGL | extra_flags)
renderer_sdl2::renderer_sdl2(
osd_window &window,
copy_info_t const *const (&blit_info)[SDL_TEXFORMAT_LAST + 1])
: osd_renderer(window)
, m_sdl_renderer(nullptr)
, m_blit_info(blit_info)
, m_blittimer(0)
, m_last_hofs(0)
, m_last_vofs(0)
@ -74,112 +261,8 @@ renderer_sdl2::renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags
fmt_support[i].format = 0;
fmt_support[i].status = 0;
}
if (!s_blit_info_initialized)
{
/* On OSX, calling this from drawsdl2_init will
* prohibit fullscreen toggling. It is than not possible
* to toggle from fullscreen to window mode.
*/
expand_copy_info(s_blit_info_default);
s_blit_info_initialized = true;
}
}
//============================================================
// STATIC VARIABLES
//============================================================
#define BM_ALL (UINT32_MAX)
//( SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD)
#define ENTRY(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, 0}
#define ENTRY_BM(a,b,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0}
#define ENTRY_LR(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1}
const copy_info_t renderer_sdl2::s_blit_info_default[] =
{
/* no rotation */
ENTRY(ARGB32, ARGB8888, argb32_argb32),
ENTRY_LR(ARGB32, RGB888, argb32_rgb32),
/* Entry primarily for directfb */
ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_ADD),
ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_MOD),
ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_NONE),
ENTRY(RGB32, ARGB8888, rgb32_argb32),
ENTRY(RGB32, RGB888, rgb32_rgb32),
ENTRY(RGB32_PALETTED, ARGB8888, rgb32pal_argb32),
ENTRY(RGB32_PALETTED, RGB888, rgb32pal_argb32),
ENTRY(YUY16, UYVY, yuv16_uyvy),
ENTRY(YUY16, YUY2, yuv16_yuy2),
ENTRY(YUY16, YVYU, yuv16_yvyu),
ENTRY(YUY16, ARGB8888, yuv16_argb32),
ENTRY(YUY16, RGB888, yuv16_argb32),
ENTRY(YUY16_PALETTED, UYVY, yuv16pal_uyvy),
ENTRY(YUY16_PALETTED, YUY2, yuv16pal_yuy2),
ENTRY(YUY16_PALETTED, YVYU, yuv16pal_yvyu),
ENTRY(YUY16_PALETTED, ARGB8888, yuv16pal_argb32),
ENTRY(YUY16_PALETTED, RGB888, yuv16pal_argb32),
ENTRY(PALETTE16, ARGB8888, pal16_argb32),
ENTRY(PALETTE16, RGB888, pal16_argb32),
ENTRY(RGB15, RGB555, rgb15_rgb555),
ENTRY(RGB15, ARGB1555, rgb15_argb1555),
ENTRY(RGB15, ARGB8888, rgb15_argb32),
ENTRY(RGB15, RGB888, rgb15_argb32),
ENTRY(RGB15_PALETTED, ARGB8888, rgb15pal_argb32),
ENTRY(RGB15_PALETTED, RGB888, rgb15pal_argb32),
ENTRY(PALETTE16A, ARGB8888, pal16a_argb32),
ENTRY(PALETTE16A, RGB888, pal16a_rgb32),
/* rotation */
ENTRY(ARGB32, ARGB8888, rot_argb32_argb32),
ENTRY_LR(ARGB32, RGB888, rot_argb32_rgb32),
/* Entry primarily for directfb */
ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_ADD),
ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_MOD),
ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_NONE),
ENTRY(RGB32, ARGB8888, rot_rgb32_argb32),
ENTRY(RGB32, RGB888, rot_argb32_argb32),
ENTRY(RGB32_PALETTED, ARGB8888, rot_rgb32pal_argb32),
ENTRY(RGB32_PALETTED, RGB888, rot_rgb32pal_argb32),
ENTRY(YUY16, ARGB8888, rot_yuv16_argb32rot),
ENTRY(YUY16, RGB888, rot_yuv16_argb32rot),
ENTRY(YUY16_PALETTED, ARGB8888, rot_yuv16pal_argb32rot),
ENTRY(YUY16_PALETTED, RGB888, rot_yuv16pal_argb32rot),
ENTRY(PALETTE16, ARGB8888, rot_pal16_argb32),
ENTRY(PALETTE16, RGB888, rot_pal16_argb32),
ENTRY(RGB15, RGB555, rot_rgb15_argb1555),
ENTRY(RGB15, ARGB1555, rot_rgb15_argb1555),
ENTRY(RGB15, ARGB8888, rot_rgb15_argb32),
ENTRY(RGB15, RGB888, rot_rgb15_argb32),
ENTRY(RGB15_PALETTED, ARGB8888, rot_rgb15pal_argb32),
ENTRY(RGB15_PALETTED, RGB888, rot_rgb15pal_argb32),
ENTRY(PALETTE16A, ARGB8888, rot_pal16a_argb32),
ENTRY(PALETTE16A, RGB888, rot_pal16a_rgb32),
{ -1 },
};
copy_info_t* renderer_sdl2::s_blit_info[SDL_TEXFORMAT_LAST+1] = { nullptr };
bool renderer_sdl2::s_blit_info_initialized = false;
//============================================================
// INLINES
//============================================================
@ -274,7 +357,7 @@ void renderer_sdl2::render_quad(texture_info *texture, const render_primitive &p
if (texture)
{
copy_info_t *copyinfo = texture->m_copyinfo;
copy_info_t const *copyinfo = texture->m_copyinfo;
copyinfo->time -= osd_ticks();
texture->render_quad(prim, x, y);
copyinfo->time += osd_ticks();
@ -326,59 +409,6 @@ int renderer_sdl2::RendererSupportsFormat(Uint32 format, Uint32 access, const ch
return 0;
}
//============================================================
// drawsdl_init
//============================================================
void renderer_sdl2::add_list(copy_info_t **head, const copy_info_t *element, Uint32 bm)
{
copy_info_t *newci = new copy_info_t;
*newci = *element;
newci->bm_mask = bm;
newci->next = *head;
*head = newci;
}
void renderer_sdl2::expand_copy_info(const copy_info_t *list)
{
for (const copy_info_t *bi = list; bi->src_fmt != -1; bi++)
{
if (bi->bm_mask == BM_ALL)
{
add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_NONE);
add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_ADD);
add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_MOD);
add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_BLEND);
}
else
{
add_list(&s_blit_info[bi->src_fmt], bi, bi->bm_mask);
}
}
}
// FIXME: machine only used to access options.
void renderer_sdl2::init(running_machine &machine)
{
osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n");
#if USE_OPENGL
// Load the GL library now - else MT will fail
const char *stemp = downcast<sdl_options &>(machine.options()).gl_lib();
#else
const char *stemp = nullptr;
#endif
if (stemp != nullptr && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
stemp = nullptr;
// No fatalerror here since not all video drivers support GL !
if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==nullptr
osd_printf_warning("Warning: Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
else
osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
}
//============================================================
// sdl_info::create
@ -431,12 +461,10 @@ 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(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
else
m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_ACCELERATED);
m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_ACCELERATED);
if (!m_sdl_renderer)
{
@ -480,15 +508,11 @@ int renderer_sdl2::xy_to_render_target(int x, int y, int *xt, int *yt)
void renderer_sdl2::destroy_all_textures()
{
auto win = assert_window();
if (win == nullptr)
return;
if(win->m_primlist)
if (window().m_primlist)
{
win->m_primlist->acquire_lock();
window().m_primlist->acquire_lock();
m_texlist.reset();
win->m_primlist->release_lock();
window().m_primlist->release_lock();
}
else
m_texlist.reset();
@ -504,13 +528,7 @@ int renderer_sdl2::draw(int update)
float vofs, hofs;
int blit_pixels = 0;
if (video_config.novideo)
{
return 0;
}
auto win = assert_window();
osd_dim wdim = win->get_size();
osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
{
@ -557,10 +575,10 @@ int renderer_sdl2::draw(int update)
m_last_hofs = hofs;
m_last_vofs = vofs;
win->m_primlist->acquire_lock();
window().m_primlist->acquire_lock();
// now draw
for (render_primitive &prim : *win->m_primlist)
for (render_primitive &prim : *window().m_primlist)
{
Uint8 sr, sg, sb, sa;
@ -590,7 +608,7 @@ int renderer_sdl2::draw(int update)
}
}
win->m_primlist->release_lock();
window().m_primlist->release_lock();
m_last_blit_pixels = blit_pixels;
m_last_blit_time = -osd_ticks();
@ -609,22 +627,23 @@ int renderer_sdl2::draw(int update)
// texture_compute_size and type
//============================================================
copy_info_t *texture_info::compute_size_type()
copy_info_t const *texture_info::compute_size_type()
{
copy_info_t *result = nullptr;
copy_info_t const *result = nullptr;
int maxperf = 0;
for (copy_info_t *bi = renderer_sdl2::s_blit_info[m_format]; bi != nullptr; bi = bi->next)
for (copy_info_t const *bi = m_renderer->m_blit_info[m_format]; bi != nullptr; bi = bi->next)
{
if ((m_is_rotated == bi->blitter->m_is_rot)
&& (m_sdl_blendmode == bi->bm_mask))
if ((m_is_rotated == bi->blitter->m_is_rot) && (m_sdl_blendmode == bi->bm_mask))
{
if (m_renderer->RendererSupportsFormat(bi->dst_fmt, m_sdl_access, bi->dstname))
{
int perf = bi->perf;
int const perf = bi->perf;
if (perf == 0)
{
return bi;
else if (perf > (maxperf * 102) / 100)
}
else if (perf > ((maxperf * 102) / 100))
{
result = bi;
maxperf = perf;
@ -636,15 +655,14 @@ copy_info_t *texture_info::compute_size_type()
if (result)
return result;
/* try last resort handlers */
for (copy_info_t *bi = renderer_sdl2::s_blit_info[m_format]; bi != nullptr; bi = bi->next)
// try last resort handlers
for (copy_info_t const *bi = m_renderer->m_blit_info[m_format]; bi != nullptr; bi = bi->next)
{
if ((m_is_rotated == bi->blitter->m_is_rot)
&& (m_sdl_blendmode == bi->bm_mask))
if ((m_is_rotated == bi->blitter->m_is_rot) && (m_sdl_blendmode == bi->bm_mask))
if (m_renderer->RendererSupportsFormat(bi->dst_fmt, m_sdl_access, bi->dstname))
return bi;
}
//FIXME: crash implement a -do nothing handler */
//FIXME: crash implement a -do nothing handler
return nullptr;
}
@ -896,32 +914,6 @@ texture_info *renderer_sdl2::texture_find(const render_primitive &prim, const qu
return nullptr;
}
//============================================================
// exit
//============================================================
void renderer_sdl2::exit()
{
if (s_blit_info_initialized)
{
for (int i = 0; i <= SDL_TEXFORMAT_LAST; i++)
{
for (copy_info_t *bi = s_blit_info[i]; bi != nullptr; )
{
if (bi->pixel_count)
osd_printf_verbose("%s -> %s %s blendmode 0x%02x, %d samples: %d KPixel/sec\n", bi->srcname, bi->dstname,
bi->blitter->m_is_rot ? "rot" : "norot", bi->bm_mask, bi->samples,
(int) bi->perf);
copy_info_t *freeme = bi;
bi = bi->next;
delete freeme;
}
s_blit_info[i] = nullptr;
}
s_blit_info_initialized = false;
}
}
//============================================================
// texture_update
//============================================================
@ -931,8 +923,7 @@ texture_info * renderer_sdl2::texture_update(const render_primitive &prim)
quad_setup_data setup;
texture_info *texture;
auto win = assert_window();
setup.compute(prim, win->prescale());
setup.compute(prim, window().prescale());
texture = texture_find(prim, setup);
@ -959,16 +950,251 @@ texture_info * renderer_sdl2::texture_update(const render_primitive &prim)
render_primitive_list *renderer_sdl2::get_primitives()
{
auto win = assert_window();
if (win == nullptr)
return nullptr;
osd_dim nd = win->get_size();
osd_dim nd = window().get_size();
if (nd != m_blit_dim)
{
m_blit_dim = nd;
notify_changed();
}
win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
return &win->target()->get_primitives();
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
return &window().target()->get_primitives();
}
class video_sdl2 : public osd_module, public render_module
{
public:
video_sdl2()
: osd_module(OSD_RENDERER_PROVIDER, "accel")
, m_blit_info_initialized(false)
, m_gllib_loaded(false)
{
std::fill(std::begin(m_blit_info), std::end(m_blit_info), nullptr);
}
~video_sdl2()
{
free_copy_info();
}
virtual int init(osd_interface &osd, osd_options const &options) override;
virtual void exit() override { free_copy_info(); }
virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
protected:
virtual unsigned flags() const override { return FLAG_INTERACTIVE | FLAG_SDL_NEEDS_OPENGL; }
private:
static inline constexpr Uint32 BM_ALL = UINT32_MAX; // SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD
void expand_copy_info();
void free_copy_info();
static void add_list(copy_info_t *&head, copy_info_t const &element, Uint32 bm);
copy_info_t *m_blit_info[SDL_TEXFORMAT_LAST + 1];
bool m_blit_info_initialized;
bool m_gllib_loaded;
static copy_info_t const s_blit_info_default[];
};
int video_sdl2::init(osd_interface &osd, osd_options const &options)
{
osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n");
// Load the GL library now - else MT will fail
char const *libname = nullptr;
#if USE_OPENGL
libname = dynamic_cast<sdl_options const &>(options).gl_lib();
if (libname && (!*libname || !std::strcmp(libname, OSDOPTVAL_AUTO)))
libname = nullptr;
#endif
if (!m_gllib_loaded)
{
// No fatalerror here since not all video drivers support GL!
if (SDL_GL_LoadLibrary(libname) != 0)
{
osd_printf_error("Unable to load OpenGL shared library: %s\n", libname ? libname : "<default>");
m_gllib_loaded = true;
}
else
{
osd_printf_verbose("Loaded OpenGL shared library: %s\n", libname ? libname : "<default>");
}
}
return 0;
}
std::unique_ptr<osd_renderer> video_sdl2::create(osd_window &window)
{
if (!m_blit_info_initialized)
{
// On macOS, calling this from drawsdl2_init will prohibit fullscreen toggling.
// It is than not possible to toggle from fullscreen to window mode.
expand_copy_info();
m_blit_info_initialized = true;
}
return std::make_unique<renderer_sdl2>(window, m_blit_info);
}
void video_sdl2::expand_copy_info()
{
for (const copy_info_t *bi = s_blit_info_default; bi->src_fmt != -1; bi++)
{
if (bi->bm_mask == BM_ALL)
{
add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_NONE);
add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_ADD);
add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_MOD);
add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_BLEND);
}
else
{
add_list(m_blit_info[bi->src_fmt], *bi, bi->bm_mask);
}
}
}
void video_sdl2::free_copy_info()
{
if (m_blit_info_initialized)
{
for (int i = 0; i <= SDL_TEXFORMAT_LAST; i++)
{
for (copy_info_t *bi = m_blit_info[i]; bi != nullptr; )
{
if (bi->pixel_count)
{
osd_printf_verbose(
"%s -> %s %s blendmode 0x%02x, %d samples: %d KPixel/sec\n",
bi->srcname,
bi->dstname,
bi->blitter->m_is_rot ? "rot" : "norot",
bi->bm_mask,
bi->samples,
bi->perf);
}
copy_info_t *freeme = bi;
bi = bi->next;
delete freeme;
}
m_blit_info[i] = nullptr;
}
m_blit_info_initialized = false;
}
}
void video_sdl2::add_list(copy_info_t *&head, copy_info_t const &element, Uint32 bm)
{
copy_info_t *const newci = new copy_info_t(element);
newci->bm_mask = bm;
newci->next = head;
head = newci;
}
//============================================================
// STATIC VARIABLES
//============================================================
#define ENTRY(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, 0}
#define ENTRY_BM(a,b,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0}
#define ENTRY_LR(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1}
copy_info_t const video_sdl2::s_blit_info_default[] =
{
/* no rotation */
ENTRY(ARGB32, ARGB8888, argb32_argb32),
ENTRY_LR(ARGB32, RGB888, argb32_rgb32),
/* Entry primarily for directfb */
ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_ADD),
ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_MOD),
ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_NONE),
ENTRY(RGB32, ARGB8888, rgb32_argb32),
ENTRY(RGB32, RGB888, rgb32_rgb32),
ENTRY(RGB32_PALETTED, ARGB8888, rgb32pal_argb32),
ENTRY(RGB32_PALETTED, RGB888, rgb32pal_argb32),
ENTRY(YUY16, UYVY, yuv16_uyvy),
ENTRY(YUY16, YUY2, yuv16_yuy2),
ENTRY(YUY16, YVYU, yuv16_yvyu),
ENTRY(YUY16, ARGB8888, yuv16_argb32),
ENTRY(YUY16, RGB888, yuv16_argb32),
ENTRY(YUY16_PALETTED, UYVY, yuv16pal_uyvy),
ENTRY(YUY16_PALETTED, YUY2, yuv16pal_yuy2),
ENTRY(YUY16_PALETTED, YVYU, yuv16pal_yvyu),
ENTRY(YUY16_PALETTED, ARGB8888, yuv16pal_argb32),
ENTRY(YUY16_PALETTED, RGB888, yuv16pal_argb32),
ENTRY(PALETTE16, ARGB8888, pal16_argb32),
ENTRY(PALETTE16, RGB888, pal16_argb32),
ENTRY(RGB15, RGB555, rgb15_rgb555),
ENTRY(RGB15, ARGB1555, rgb15_argb1555),
ENTRY(RGB15, ARGB8888, rgb15_argb32),
ENTRY(RGB15, RGB888, rgb15_argb32),
ENTRY(RGB15_PALETTED, ARGB8888, rgb15pal_argb32),
ENTRY(RGB15_PALETTED, RGB888, rgb15pal_argb32),
ENTRY(PALETTE16A, ARGB8888, pal16a_argb32),
ENTRY(PALETTE16A, RGB888, pal16a_rgb32),
/* rotation */
ENTRY(ARGB32, ARGB8888, rot_argb32_argb32),
ENTRY_LR(ARGB32, RGB888, rot_argb32_rgb32),
/* Entry primarily for directfb */
ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_ADD),
ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_MOD),
ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_NONE),
ENTRY(RGB32, ARGB8888, rot_rgb32_argb32),
ENTRY(RGB32, RGB888, rot_argb32_argb32),
ENTRY(RGB32_PALETTED, ARGB8888, rot_rgb32pal_argb32),
ENTRY(RGB32_PALETTED, RGB888, rot_rgb32pal_argb32),
ENTRY(YUY16, ARGB8888, rot_yuv16_argb32rot),
ENTRY(YUY16, RGB888, rot_yuv16_argb32rot),
ENTRY(YUY16_PALETTED, ARGB8888, rot_yuv16pal_argb32rot),
ENTRY(YUY16_PALETTED, RGB888, rot_yuv16pal_argb32rot),
ENTRY(PALETTE16, ARGB8888, rot_pal16_argb32),
ENTRY(PALETTE16, RGB888, rot_pal16_argb32),
ENTRY(RGB15, RGB555, rot_rgb15_argb1555),
ENTRY(RGB15, ARGB1555, rot_rgb15_argb1555),
ENTRY(RGB15, ARGB8888, rot_rgb15_argb32),
ENTRY(RGB15, RGB888, rot_rgb15_argb32),
ENTRY(RGB15_PALETTED, ARGB8888, rot_rgb15pal_argb32),
ENTRY(RGB15_PALETTED, RGB888, rot_rgb15pal_argb32),
ENTRY(PALETTE16A, ARGB8888, rot_pal16a_argb32),
ENTRY(PALETTE16A, RGB888, rot_pal16a_rgb32),
{ -1 },
};
} // anonymous namespace
} // namespace osd
#else // defined(OSD_SDL)
namespace osd { namespace { MODULE_NOT_SUPPORTED(video_sdl2, OSD_RENDERER_PROVIDER, "accel") } }
#endif // defined(OSD_SDL)
MODULE_DEFINITION(RENDERER_SDL2, osd::video_sdl2)

View File

@ -1,215 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
// draw13.h - SDL 2.0 drawing implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
//============================================================
#ifndef MAME_OSD_MODULES_RENDER_DRAW13_H
#define MAME_OSD_MODULES_RENDER_DRAW13_H
#pragma once
// OSD headers
#ifndef OSD_WINDOWS
#include "window.h"
#else
#include "../windows/window.h"
typedef uint64_t HashT;
#endif
// standard SDL headers
#include <SDL2/SDL.h>
#include "emucore.h"
#include "render.h"
struct quad_setup_data
{
quad_setup_data()
: dudx(0)
, dvdx(0)
, dudy(0)
, dvdy(0)
, startu(0)
, startv(0)
, rotwidth(0)
, rotheight(0)
{
}
void compute(const render_primitive &prim, const int prescale);
int32_t dudx, dvdx, dudy, dvdy;
int32_t startu, startv;
int32_t rotwidth, rotheight;
};
//============================================================
// Textures
//============================================================
class renderer_sdl2;
struct copy_info_t;
/* texture_info holds information about a texture */
class texture_info
{
friend class simple_list<texture_info>;
public:
texture_info(renderer_sdl2 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const uint32_t flags);
~texture_info();
void set_data(const render_texinfo &texsource, const uint32_t flags);
void render_quad(const render_primitive &prim, const int x, const int y);
bool matches(const render_primitive &prim, const quad_setup_data &setup);
copy_info_t *compute_size_type();
void *m_pixels; // pixels for the texture
int m_pitch;
copy_info_t *m_copyinfo;
quad_setup_data m_setup;
osd_ticks_t m_last_access;
int raw_width() const { return m_texinfo.width; }
int raw_height() const { return m_texinfo.height; }
texture_info *next() { return m_next; }
const render_texinfo &texinfo() const { return m_texinfo; }
render_texinfo &texinfo() { return m_texinfo; }
HashT hash() const { return m_hash; }
uint32_t flags() const { return m_flags; }
// FIXME:
bool is_pixels_owned() const;
private:
void set_coloralphamode(SDL_Texture *texture_id, const render_color *color);
Uint32 m_sdl_access;
renderer_sdl2 * m_renderer;
render_texinfo m_texinfo; // copy of the texture info
HashT m_hash; // hash value for the texture (must be >= pointer size)
uint32_t m_flags; // rendering flags
SDL_Texture * m_texture_id;
bool m_is_rotated;
int m_format; // texture format
SDL_BlendMode m_sdl_blendmode;
texture_info * m_next; // next texture in the list
};
//============================================================
// TEXCOPY FUNCS
//============================================================
enum SDL_TEXFORMAT_E
{
SDL_TEXFORMAT_ARGB32 = 0,
SDL_TEXFORMAT_RGB32,
SDL_TEXFORMAT_RGB32_PALETTED,
SDL_TEXFORMAT_YUY16,
SDL_TEXFORMAT_YUY16_PALETTED,
SDL_TEXFORMAT_PALETTE16,
SDL_TEXFORMAT_RGB15,
SDL_TEXFORMAT_RGB15_PALETTED,
SDL_TEXFORMAT_PALETTE16A,
SDL_TEXFORMAT_PALETTE16_ARGB1555,
SDL_TEXFORMAT_RGB15_ARGB1555,
SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555,
SDL_TEXFORMAT_LAST = SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555
};
#include "blit13.h"
struct copy_info_t
{
int src_fmt;
Uint32 dst_fmt;
const blit_base *blitter;
Uint32 bm_mask;
const char *srcname;
const char *dstname;
/* Statistics */
uint64_t pixel_count;
int64_t time;
int samples;
int perf;
/* list */
copy_info_t *next;
};
/* renderer_sdl2 is the information about SDL for the current screen */
class renderer_sdl2 : public osd_renderer
{
public:
renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags);
virtual ~renderer_sdl2()
{
destroy_all_textures();
SDL_DestroyRenderer(m_sdl_renderer);
m_sdl_renderer = nullptr;
}
static void init(running_machine &machine);
static void exit();
virtual int create() override;
virtual int draw(const int update) override;
virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
virtual render_primitive_list *get_primitives() override;
int RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat);
SDL_Renderer * m_sdl_renderer;
static copy_info_t* s_blit_info[SDL_TEXFORMAT_LAST+1];
private:
void expand_copy_info(const copy_info_t *list);
void add_list(copy_info_t **head, const copy_info_t *element, Uint32 bm);
void render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y);
texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
texture_info *texture_update(const render_primitive &prim);
void destroy_all_textures();
int32_t m_blittimer;
simple_list<texture_info> m_texlist; // list of active textures
float m_last_hofs;
float m_last_vofs;
int m_width;
int m_height;
osd_dim m_blit_dim;
struct
{
Uint32 format;
int status;
} fmt_support[30];
// Stats
int64_t m_last_blit_time;
int64_t m_last_blit_pixels;
static bool s_blit_info_initialized;
static const copy_info_t s_blit_info_default[];
};
#endif // MAME_OSD_MODULES_RENDER_DRAW13_H

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,6 @@
#pragma once
#include <bgfx/bgfx.h>
#include "binpacker.h"
#include "bgfx/chain.h"
#include "bgfx/chainmanager.h"
@ -15,6 +13,10 @@
#include "modules/osdwindow.h"
#include "notifier.h"
#include <bgfx/bgfx.h>
#include <map>
#include <memory>
#include <vector>
@ -35,12 +37,15 @@ class avi_write;
class renderer_bgfx : public osd_renderer, public slider_dirty_notifier
{
public:
renderer_bgfx(std::shared_ptr<osd_window> w);
renderer_bgfx(
osd_window &window,
const osd_options &options,
util::notifier<util::xml::data_node const &> &load_notifier,
util::notifier<util::xml::data_node &> &save_notifier,
util::xml::data_node &persistent_settings,
uint32_t max_texsize);
virtual ~renderer_bgfx();
static bool init(running_machine &machine);
static void exit();
virtual int create() override;
virtual int draw(const int update) override;
@ -73,8 +78,6 @@ private:
BUFFER_DONE
};
void init_bgfx_library();
void vertex(ScreenVertex* vertex, float x, float y, float z, uint32_t rgba, float u, float v);
void render_avi_quad();
void update_recording();
@ -103,11 +106,11 @@ private:
void process_atlas_packs(std::vector<std::vector<rectangle_packer::packed_rectangle>>& packed);
uint32_t get_texture_hash(render_primitive *prim);
void load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void save_config(config_type cfg_type, util::xml::data_node *parentnode);
void load_config(util::xml::data_node const &parentnode);
void save_config(util::xml::data_node &parentnode);
osd_options& m_options;
bgfx::PlatformData m_platform_data;
const osd_options& m_options;
const uint32_t m_max_texture_size;
bgfx_target *m_framebuffer;
bgfx_texture *m_texture_cache;
@ -115,11 +118,11 @@ private:
// Original display_mode
osd_dim m_dimensions;
texture_manager *m_textures;
target_manager *m_targets;
shader_manager *m_shaders;
effect_manager *m_effects;
chain_manager *m_chains;
std::unique_ptr<texture_manager> m_textures;
std::unique_ptr<target_manager> m_targets;
std::unique_ptr<shader_manager> m_shaders;
std::unique_ptr<effect_manager> m_effects;
std::unique_ptr<chain_manager> m_chains;
bgfx_effect *m_gui_effect[4];
bgfx_effect *m_screen_effect[4];
@ -130,7 +133,7 @@ private:
rectangle_packer m_packer;
uint32_t m_white[16*16];
bgfx_view *m_ortho_view;
std::unique_ptr<bgfx_view> m_ortho_view;
uint32_t m_max_view;
uint16_t m_view_width;
uint16_t m_view_height;
@ -141,17 +144,19 @@ private:
bgfx::TextureHandle m_avi_texture;
bitmap_rgb32 m_avi_bitmap;
uint8_t *m_avi_data;
std::unique_ptr<util::xml::file> m_config;
const util::notifier_subscription m_load_sub;
const util::notifier_subscription m_save_sub;
util::xml::data_node &m_persistent_settings;
static const uint16_t CACHE_SIZE;
static const uint32_t PACKABLE_SIZE;
static const uint32_t WHITE_HASH;
static uint32_t s_current_view;
static bool s_bgfx_library_initialized;
static uint32_t s_width[16];
static uint32_t s_height[16];
static uint32_t s_max_texture_size;
};
#endif // MAME_RENDER_DRAWBGFX_H

File diff suppressed because it is too large Load Diff

View File

@ -10,20 +10,24 @@
#pragma once
#include "d3d/d3dcomm.h"
#ifdef OSD_WINDOWS
#include "modules/lib/osdlib.h"
#include "modules/osdwindow.h"
#include "sliderdirtynotifier.h"
#include <windows.h>
#include <tchar.h>
#include <mmsystem.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <cmath>
#undef interface
#include "d3d/d3dcomm.h"
#include "sliderdirtynotifier.h"
#include "modules/lib/osdlib.h"
#include <memory>
#include <vector>
#include <cmath>
//============================================================
// CONSTANTS
@ -36,15 +40,6 @@
// TYPE DEFINITIONS
//============================================================
struct d3d_base
{
// internal objects
IDirect3D9 *d3dobj;
bool post_fx_available;
osd::dynamic_module::ptr d3d9_dll;
};
class shaders;
struct hlsl_options;
@ -52,11 +47,10 @@ struct hlsl_options;
class renderer_d3d9 : public osd_renderer, public slider_dirty_notifier
{
public:
renderer_d3d9(std::shared_ptr<osd_window> window);
virtual ~renderer_d3d9();
using IDirect3D9Ptr = Microsoft::WRL::ComPtr<IDirect3D9>;
static bool init(running_machine &machine);
static void exit();
renderer_d3d9(osd_window &window, const IDirect3D9Ptr &d3dobj);
virtual ~renderer_d3d9();
virtual int create() override;
virtual render_primitive_list *get_primitives() override;
@ -113,11 +107,13 @@ public:
vec2f get_dims() const { return vec2f(m_width, m_height); }
int get_height() const { return m_height; }
int get_refresh() const { return m_refresh; }
bool post_fx_available() const { return m_post_fx_available; }
void set_post_fx_unavailable() { m_post_fx_available = false; }
IDirect3DDevice9 * get_device() const { return m_device; }
IDirect3DDevice9 * get_device() const { return m_device.Get(); }
D3DPRESENT_PARAMETERS * get_presentation() { return &m_presentation; }
IDirect3DVertexBuffer9 *get_vertex_buffer() const { return m_vertexbuf; }
IDirect3DVertexBuffer9 *get_vertex_buffer() const { return m_vertexbuf.Get(); }
void set_toggle(bool toggle) { m_toggle = toggle; }
@ -125,27 +121,32 @@ public:
D3DFORMAT get_pixel_format() const { return m_pixformat; }
D3DDISPLAYMODE get_origmode() const { return m_origmode; }
uint32_t get_last_texture_flags() const { return m_last_texture_flags; }
uint32_t get_last_texture_flags() const { return m_last_texture_flags; }
d3d_texture_manager * get_texture_manager() const { return m_texture_manager.get(); }
texture_info * get_default_texture();
shaders * get_shaders() const { return m_shaders; }
shaders * get_shaders() const { return m_shaders.get(); }
private:
using IDirect3DDevice9Ptr = Microsoft::WRL::ComPtr<IDirect3DDevice9>;
using IDirect3DVertexBuffer9Ptr = Microsoft::WRL::ComPtr<IDirect3DVertexBuffer9>;
const IDirect3D9Ptr m_d3dobj; // Direct3D 9 API object
int m_adapter; // ordinal adapter number
int m_width; // current width
int m_height; // current height
int m_refresh; // current refresh rate
int m_create_error_count; // number of consecutive create errors
bool m_post_fx_available;
IDirect3DDevice9 * m_device; // pointer to the Direct3DDevice object
IDirect3DDevice9Ptr m_device; // pointer to the Direct3DDevice object
int m_gamma_supported; // is full screen gamma supported?
D3DPRESENT_PARAMETERS m_presentation; // set of presentation parameters
D3DDISPLAYMODE m_origmode; // original display mode for the adapter
D3DFORMAT m_pixformat; // pixel format we are using
IDirect3DVertexBuffer9 *m_vertexbuf; // pointer to the vertex buffer object
IDirect3DVertexBuffer9Ptr m_vertexbuf; // pointer to the vertex buffer object
vertex * m_lockedbuf; // pointer to the locked vertex buffer
int m_numverts; // number of accumulated vertices
@ -160,20 +161,18 @@ private:
D3DFORMAT m_screen_format; // format to use for screen textures
texture_info * m_last_texture; // previous texture
uint32_t m_last_texture_flags; // previous texture flags
uint32_t m_last_texture_flags; // previous texture flags
int m_last_blendenable; // previous blendmode
int m_last_blendop; // previous blendmode
int m_last_blendsrc; // previous blendmode
int m_last_blenddst; // previous blendmode
int m_last_filter; // previous texture filter
uint32_t m_last_wrap; // previous wrap state
uint32_t m_last_wrap; // previous wrap state
int m_last_modmode; // previous texture modulation
shaders * m_shaders; // HLSL interface
std::unique_ptr<shaders> m_shaders; // HLSL interface
std::unique_ptr<d3d_texture_manager> m_texture_manager; // texture manager
};
#endif // OSD_WINDOWS
#endif // MAME_OSD_MODULES_RENDER_DRAWD3D_H

View File

@ -2,21 +2,53 @@
// copyright-holders:Aaron Giles
//============================================================
//
// drawgdi.c - Win32 GDI drawing
// drawgdi.cpp - Win32 GDI drawing
//
//============================================================
#include "render_module.h"
#include "modules/osdmodule.h"
#if defined(OSD_WINDOWS)
#include "window.h"
// emu
#include "emu.h"
#include "drawgdi.h"
#include "rendersw.hxx"
//============================================================
// destructor
//============================================================
// standard windows headers
#include <windows.h>
renderer_gdi::~renderer_gdi()
namespace osd {
namespace {
// renderer_gdi is the information for the current screen
class renderer_gdi : public osd_renderer
{
}
public:
renderer_gdi(osd_window &window)
: osd_renderer(window)
, m_bmdata(nullptr)
, m_bmsize(0)
{
}
virtual int create() override;
virtual render_primitive_list *get_primitives() override;
virtual int draw(const int update) override;
virtual void save() override {}
virtual void record() override {}
virtual void toggle_fsfx() override {}
private:
BITMAPINFO m_bminfo;
std::unique_ptr<uint8_t []> m_bmdata;
size_t m_bmsize;
};
//============================================================
// renderer_gdi::create
@ -34,6 +66,7 @@ int renderer_gdi::create()
m_bminfo.bmiHeader.biYPelsPerMeter = 0;
m_bminfo.bmiHeader.biClrUsed = 0;
m_bminfo.bmiHeader.biClrImportant = 0;
return 0;
}
@ -43,16 +76,12 @@ int renderer_gdi::create()
render_primitive_list *renderer_gdi::get_primitives()
{
auto win = try_getwindow();
if (win == nullptr)
osd_dim const dimensions = window().get_size();
if ((dimensions.width() <= 0) || (dimensions.height() <= 0))
return nullptr;
RECT client;
GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client);
if ((rect_width(&client) == 0) || (rect_height(&client) == 0))
return nullptr;
win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect());
return &win->target()->get_primitives();
window().target()->set_bounds(dimensions.width(), dimensions.height(), window().pixel_aspect());
return &window().target()->get_primitives();
}
//============================================================
@ -61,23 +90,22 @@ 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 (win->m_resize_state == RESIZE_STATE_PENDING)
win->m_resize_state = RESIZE_STATE_NORMAL;
if (window().m_resize_state == RESIZE_STATE_PENDING)
window().m_resize_state = RESIZE_STATE_NORMAL;
// get the target bounds
RECT bounds;
GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &bounds);
GetClientRect(dynamic_cast<win_window_info &>(window()).platform_window(), &bounds);
// compute width/height/pitch of target
int width = rect_width(&bounds);
int height = rect_height(&bounds);
int pitch = (width + 3) & ~3;
osd_dim const dimensions = window().get_size();
int const width = dimensions.width();
int const height = dimensions.height();
int const pitch = (width + 3) & ~3;
// make sure our temporary bitmap is big enough
if (pitch * height * 4 > m_bmsize)
if ((pitch * height * 4) > m_bmsize)
{
m_bmsize = pitch * height * 4 * 2;
m_bmdata.reset();
@ -85,9 +113,9 @@ int renderer_gdi::draw(const int update)
}
// draw the primitives to the bitmap
win->m_primlist->acquire_lock();
software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, m_bmdata.get(), width, height, pitch);
win->m_primlist->release_lock();
window().m_primlist->acquire_lock();
software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, m_bmdata.get(), width, height, pitch);
window().m_primlist->release_lock();
// fill in bitmap-specific info
m_bminfo.bmiHeader.biWidth = pitch;
@ -95,8 +123,43 @@ int renderer_gdi::draw(const int update)
// blit to the screen
StretchDIBits(
win->m_dc, 0, 0, width, height,
window().m_dc, 0, 0, width, height,
0, 0, width, height,
m_bmdata.get(), &m_bminfo, DIB_RGB_COLORS, SRCCOPY);
return 0;
}
class video_gdi : public osd_module, public render_module
{
public:
video_gdi() : osd_module(OSD_RENDERER_PROVIDER, "gdi") { }
virtual int init(osd_interface &osd, osd_options const &options) override { return 0; }
virtual void exit() override { }
virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
protected:
virtual unsigned flags() const override { return FLAG_INTERACTIVE; }
};
std::unique_ptr<osd_renderer> video_gdi::create(osd_window &window)
{
return std::make_unique<renderer_gdi>(window);
}
} // anonymous namespace
} // namespace osd
#else // defined(OSD_WINDOWS)
namespace osd { namespace { MODULE_NOT_SUPPORTED(video_gdi, OSD_RENDERER_PROVIDER, "gdi") } }
#endif // defined(OSD_WINDOWS)
MODULE_DEFINITION(RENDERER_GDI, osd::video_gdi)

View File

@ -1,55 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
//============================================================
//
// drawgdi.h - Win32 GDI drawing
//
//============================================================
#ifndef MAME_OSD_MODULES_RENDER_DRAWGDI_H
#define MAME_OSD_MODULES_RENDER_DRAWGDI_H
#pragma once
// standard windows headers
#include <windows.h>
// MAME headers
// MAMEOS headers
#include "window.h"
//============================================================
// TYPE DEFINITIONS
//============================================================
/* renderer_gdi is the information for the current screen */
class renderer_gdi : public osd_renderer
{
public:
renderer_gdi(std::shared_ptr<osd_window> window)
: osd_renderer(window, FLAG_NONE)
, m_bmdata(nullptr)
, m_bmsize(0)
{
}
virtual ~renderer_gdi();
static bool init(running_machine &machine) { return false; }
static void exit() { }
virtual int create() override;
virtual render_primitive_list *get_primitives() override;
virtual int draw(const int update) override;
virtual void save() override {}
virtual void record() override {}
virtual void toggle_fsfx() override {}
private:
BITMAPINFO m_bminfo;
std::unique_ptr<uint8_t []> m_bmdata;
size_t m_bmsize;
};
#endif // MAME_OSD_MODULES_RENDER_DRAWGDI_H

View File

@ -6,25 +6,77 @@
//
//============================================================
// standard windows headers
#include <windows.h>
#include "render_module.h"
#include "drawnone.h"
#include "modules/lib/osdobj_common.h"
#include "modules/osdmodule.h"
#include "modules/osdwindow.h"
//============================================================
// drawnone_window_get_primitives
//============================================================
#include "emu.h" // FIXME: only here for main.h, won't be necessary soon
#include "main.h"
#include "render.h"
#include <memory>
namespace osd {
namespace {
class renderer_none : public osd_renderer
{
public:
renderer_none(osd_window &window) : osd_renderer(window) { }
virtual int create() override { return 0; }
virtual render_primitive_list *get_primitives() override;
virtual int draw(const int update) override { return 0; }
virtual void save() override { }
virtual void record() override { }
virtual void toggle_fsfx() override { }
};
render_primitive_list *renderer_none::get_primitives()
{
auto win = try_getwindow();
if (win == nullptr)
osd_dim const dimensions = window().get_size();
if ((dimensions.width() <= 0) || (dimensions.height() <= 0))
return nullptr;
RECT client;
GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client);
if ((rect_width(&client) == 0) || (rect_height(&client) == 0))
return nullptr;
win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect());
return &win->target()->get_primitives();
window().target()->set_bounds(dimensions.width(), dimensions.height(), window().pixel_aspect());
return &window().target()->get_primitives();
}
class video_none : public osd_module, public render_module
{
public:
video_none() : osd_module(OSD_RENDERER_PROVIDER, "none") { }
virtual int init(osd_interface &osd, osd_options const &options) override;
virtual void exit() override { }
virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
protected:
virtual unsigned flags() const override { return 0; }
};
int video_none::init(osd_interface &osd, osd_options const &options)
{
if (!emulator_info::standalone() && (options.seconds_to_run() == 0))
osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
return 0;
}
std::unique_ptr<osd_renderer> video_none::create(osd_window &window)
{
return std::make_unique<renderer_none>(window);
}
} // anonymous namespace
} // namespace osd
MODULE_DEFINITION(RENDERER_NONE, osd::video_none)

View File

@ -1,33 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
//============================================================
//
// drawnone.h - stub "nothing" drawer
//
//============================================================
#ifndef __DRAWNONE__
#define __DRAWNONE__
#include "window.h"
class renderer_none : public osd_renderer
{
public:
renderer_none(std::shared_ptr<osd_window> window)
: osd_renderer(window, FLAG_NONE) { }
virtual ~renderer_none() { }
static bool init(running_machine &machine) { return false; }
static void exit() { }
virtual int create() override { return 0; }
virtual render_primitive_list *get_primitives() override;
virtual int draw(const int update) override { return 0; }
virtual void save() override { }
virtual void record() override { }
virtual void toggle_fsfx() override { }
};
#endif // __DRAWNONE__

File diff suppressed because it is too large Load Diff

View File

@ -1,244 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont
//============================================================
//
// drawogl.h - SDL software and OpenGL implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
//============================================================
#ifndef MAME_OSD_MODULES_RENDER_DRAWOGL_H
#define MAME_OSD_MODULES_RENDER_DRAWOGL_H
#pragma once
// OSD headers
#ifndef OSD_WINDOWS
#ifdef OSD_MAC
#include "osdmac.h"
#else
#include "osdsdl.h"
#endif
#include "window.h"
#else
#include "../windows/window.h"
typedef uint64_t HashT;
#endif
#if defined(OSD_WINDOWS)
#include "winglcontext.h"
#elif defined (OSD_MAC)
#else
#include "sdlglcontext.h"
#endif
#include "modules/opengl/gl_shader_mgr.h"
#include "emucore.h"
#include "render.h"
//============================================================
// Textures
//============================================================
/* ogl_texture_info holds information about a texture */
class ogl_texture_info
{
public:
ogl_texture_info()
: hash(0), flags(0), rawwidth(0), rawheight(0),
rawwidth_create(0), rawheight_create(0),
type(0), format(0), borderpix(0), xprescale(0), yprescale(0), nocopy(0),
texture(0), texTarget(0), texpow2(0), mpass_dest_idx(0), pbo(0), data(nullptr),
data_own(0), texCoordBufferName(0)
{
for (int i=0; i<2; i++)
{
mpass_textureunit[i] = 0;
mpass_texture_mamebm[i] = 0;
mpass_fbo_mamebm[i] = 0;
mpass_texture_scrn[i] = 0;
mpass_fbo_scrn[i] = 0;
}
for (int i=0; i<8; i++)
texCoord[i] = 0.0f;
}
HashT hash; // hash value for the texture (must be >= pointer size)
uint32_t flags; // rendering flags
render_texinfo texinfo; // copy of the texture info
int rawwidth, rawheight; // raw width/height of the texture
int rawwidth_create; // raw width/height, pow2 compatible, if needed
int rawheight_create; // (create and initial set the texture, not for copy!)
int type; // what type of texture are we?
int format; // texture format
int borderpix; // do we have a 1 pixel border?
int xprescale; // what is our X prescale factor?
int yprescale; // what is our Y prescale factor?
int nocopy; // must the texture date be copied?
uint32_t texture; // OpenGL texture "name"/ID
GLenum texTarget; // OpenGL texture target
int texpow2; // Is this texture pow2
uint32_t mpass_dest_idx; // Multipass dest idx [0..1]
uint32_t mpass_textureunit[2]; // texture unit names for GLSL
uint32_t mpass_texture_mamebm[2];// Multipass OpenGL texture "name"/ID for the shader
uint32_t mpass_fbo_mamebm[2]; // framebuffer object for this texture, multipass
uint32_t mpass_texture_scrn[2]; // Multipass OpenGL texture "name"/ID for the shader
uint32_t mpass_fbo_scrn[2]; // framebuffer object for this texture, multipass
uint32_t pbo; // pixel buffer object for this texture (DYNAMIC only!)
uint32_t *data; // pixels for the texture
int data_own; // do we own / allocated it ?
GLfloat texCoord[8];
GLuint texCoordBufferName;
};
/* renderer_ogl is the information about OpenGL for the current screen */
class renderer_ogl : public osd_renderer
{
public:
renderer_ogl(std::shared_ptr<osd_window> window)
: osd_renderer(window, FLAG_NEEDS_OPENGL)
, m_blittimer(0)
, m_width(0)
, m_height(0)
, m_blit_dim(0, 0)
, m_gl_context(nullptr)
, m_initialized(0)
, m_last_blendmode(0)
, m_texture_max_width(0)
, m_texture_max_height(0)
, m_texpoweroftwo(0)
, m_usevbo(0)
, m_usepbo(0)
, m_usefbo(0)
, m_useglsl(0)
, m_glsl(nullptr)
, m_glsl_program_num(0)
, m_glsl_program_mb2sc(0)
, m_usetexturerect(0)
, m_init_context(0)
, m_last_hofs(0.0f)
, m_last_vofs(0.0f)
, m_surf_w(0)
, m_surf_h(0)
{
for (int i=0; i < HASH_SIZE + OVERFLOW_SIZE; i++)
m_texhash[i] = nullptr;
for (int i=0; i < 2*GLSL_SHADER_MAX; i++)
m_glsl_program[i] = 0;
for (int i=0; i < 8; i++)
m_texVerticex[i] = 0.0f;
}
virtual ~renderer_ogl();
static void init(running_machine &machine);
static void exit();
virtual int create() override;
virtual int draw(const int update) override;
#ifndef OSD_WINDOWS
virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
#endif
virtual render_primitive_list *get_primitives() override
{
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();
}
if ((m_blit_dim.width() == 0) || (m_blit_dim.height() == 0))
return nullptr;
win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
return &win->target()->get_primitives();
}
#ifdef OSD_WINDOWS
virtual void save() override { }
virtual void record() override { }
virtual void toggle_fsfx() override { }
#endif
private:
static const uint32_t HASH_SIZE = ((1 << 10) + 1);
static const uint32_t OVERFLOW_SIZE = (1 << 10);
void destroy_all_textures();
static void load_gl_lib(running_machine &machine);
void loadGLExtensions();
void initialize_gl();
void set_blendmode(int blendmode);
HashT texture_compute_hash(const render_texinfo *texture, uint32_t flags);
void texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
void texture_compute_size_subroutine(ogl_texture_info *texture, uint32_t flags,
uint32_t width, uint32_t height,
int* p_width, int* p_height, int* p_width_create, int* p_height_create);
void texture_compute_size_type(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
ogl_texture_info *texture_create(const render_texinfo *texsource, uint32_t flags);
int texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
ogl_texture_info *texture_find(const render_primitive *prim);
void texture_coord_update(ogl_texture_info *texture, const render_primitive *prim, int shaderIdx);
void texture_mpass_flip(ogl_texture_info *texture, int shaderIdx);
void texture_shader_update(ogl_texture_info *texture, render_container *container, int shaderIdx);
ogl_texture_info * texture_update(const render_primitive *prim, int shaderIdx);
void texture_disable(ogl_texture_info * texture);
void texture_all_disable();
int32_t m_blittimer;
int m_width;
int m_height;
osd_dim m_blit_dim;
osd_gl_context *m_gl_context;
int m_initialized; // is everything well initialized, i.e. all GL stuff etc.
// 3D info (GL mode only)
ogl_texture_info * m_texhash[HASH_SIZE + OVERFLOW_SIZE];
int m_last_blendmode; // previous blendmode
int32_t m_texture_max_width; // texture maximum width
int32_t m_texture_max_height; // texture maximum height
int m_texpoweroftwo; // must textures be power-of-2 sized?
int m_usevbo; // runtime check if VBO is available
int m_usepbo; // runtime check if PBO is available
int m_usefbo; // runtime check if FBO is available
int m_useglsl; // runtime check if GLSL is available
glsl_shader_info *m_glsl; // glsl_shader_info
GLhandleARB m_glsl_program[2*GLSL_SHADER_MAX]; // GLSL programs, or 0
int m_glsl_program_num; // number of GLSL programs
int m_glsl_program_mb2sc; // GLSL program idx, which transforms
// the mame-bitmap. screen-bitmap (size/rotation/..)
// All progs <= glsl_program_mb2sc using the mame bitmap
// as input, otherwise the screen bitmap.
// All progs >= glsl_program_mb2sc using the screen bitmap
// as output, otherwise the mame bitmap.
int m_usetexturerect; // use ARB_texture_rectangle for non-power-of-2, general use
int m_init_context; // initialize context before next draw
float m_last_hofs;
float m_last_vofs;
// Static vars from draogl_window_dra
int32_t m_surf_w;
int32_t m_surf_h;
GLfloat m_texVerticex[8];
static bool s_shown_video_info;
static bool s_dll_loaded;
};
#endif // MAME_OSD_MODULES_RENDER_DRAWOGL_H

View File

@ -2,7 +2,7 @@
// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
// drawsdl.c - SDL software and OpenGL implementation
// drawsdl.cpp - SDL software and OpenGL implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
@ -10,25 +10,37 @@
//
//============================================================
#include "drawsdl.h"
#include "render_module.h"
#include "modules/osdmodule.h"
#if defined(OSD_SDL)
// from specific OSD implementation
#include "sdlopts.h"
#include "window.h"
// general OSD headers
#include "modules/monitor/monitor_module.h"
// MAME headers
#include "emucore.h"
#include "render.h"
#include "rendersw.hxx"
#include "ui/uimain.h"
//#include "ui/uimain.h"
// osd headers
#include "modules/monitor/monitor_module.h"
#include <SDL2/SDL.h>
// standard C headers
#include <cmath>
#include <cstdio>
#include <memory>
//============================================================
// DEBUGGING
//============================================================
namespace osd {
namespace {
//============================================================
// CONSTANTS
@ -38,6 +50,76 @@
#define DRAW2_SCALEMODE_LINEAR "1"
#define DRAW2_SCALEMODE_BEST "2"
struct sdl_scale_mode
{
const char *name;
int is_scale; /* Scale mode? */
int is_yuv; /* Yuv mode? */
int mult_w; /* Width multiplier */
int mult_h; /* Height multiplier */
const char *sdl_scale_mode_hint; /* what to use as a hint ? */
int pixel_format; /* Pixel/Overlay format */
void (*yuv_blit)(const uint16_t *bitmap, uint8_t *ptr, const int pitch, const uint32_t *lookup, const int width, const int height);
};
// renderer_sdl1 is the information about SDL for the current screen
class renderer_sdl1 : public osd_renderer
{
public:
renderer_sdl1(osd_window &w, sdl_scale_mode const &scale_mode)
: osd_renderer(w)
, m_scale_mode(scale_mode)
, m_sdl_renderer(nullptr)
, m_texture_id(nullptr)
, m_yuv_lookup()
, m_yuv_bitmap()
//, m_hw_scale_width(0)
//, m_hw_scale_height(0)
, m_last_hofs(0)
, m_last_vofs(0)
, m_blit_dim(0, 0)
, m_last_dim(0, 0)
{
}
virtual ~renderer_sdl1();
virtual int create() override;
virtual int draw(const int update) override;
virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
virtual render_primitive_list *get_primitives() override;
private:
void show_info(struct SDL_RendererInfo *render_info);
void destroy_all_textures();
void yuv_init();
void setup_texture(const osd_dim &size);
void yuv_lookup_set(unsigned int pen, unsigned char red,
unsigned char green, unsigned char blue);
int32_t m_blittimer;
sdl_scale_mode const &m_scale_mode;
SDL_Renderer *m_sdl_renderer;
SDL_Texture *m_texture_id;
// YUV overlay
std::unique_ptr<uint32_t []> m_yuv_lookup;
std::unique_ptr<uint16_t []> m_yuv_bitmap;
// if we leave scaling to SDL and the underlying driver, this
// is the render_target_width/height to use
int m_last_hofs;
int m_last_vofs;
osd_dim m_blit_dim;
osd_dim m_last_dim;
};
//============================================================
// PROTOTYPES
//============================================================
@ -53,84 +135,41 @@ static void yuv_RGB_to_YUY2(const uint16_t *bitmap, uint8_t *ptr, const int pitc
static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
const uint32_t *lookup, const int width, const int height);
// Static declarations
static const sdl_scale_mode scale_modes[] =
{
{ "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, nullptr },
{ "hwblit", 1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, nullptr },
{ "hwbest", 1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, nullptr },
/* SDL1.2 uses interpolation as well */
{ "yv12", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
{ "yv12x2", 1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
{ "yuy2", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
{ "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
{ nullptr }
};
int drawsdl_scale_mode(const char *s)
{
const sdl_scale_mode *sm = scale_modes;
int index;
index = 0;
while (sm->name != nullptr)
{
if (strcmp(sm->name, s) == 0)
return index;
index++;
sm++;
}
return -1;
}
//============================================================
// drawsdl_init
//============================================================
void renderer_sdl1::init(running_machine &machine)
{
osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
}
//============================================================
// setup_texture for window
//============================================================
void renderer_sdl1::setup_texture(const osd_dim &size)
{
const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
SDL_DisplayMode mode;
uint32_t fmt;
auto win = assert_window();
// Determine preferred pixelformat and set up yuv if necessary
SDL_GetCurrentDisplayMode(win->monitor()->oshandle(), &mode);
SDL_GetCurrentDisplayMode(window().monitor()->oshandle(), &mode);
m_yuv_bitmap.reset();
fmt = (sdl_sm->pixel_format ? sdl_sm->pixel_format : mode.format);
fmt = (m_scale_mode.pixel_format ? m_scale_mode.pixel_format : mode.format);
if (sdl_sm->is_scale)
if (m_scale_mode.is_scale)
{
int m_hw_scale_width = 0;
int m_hw_scale_height = 0;
win->target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
if (win->prescale())
window().target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
if (window().prescale())
{
m_hw_scale_width *= win->prescale();
m_hw_scale_height *= win->prescale();
m_hw_scale_width *= window().prescale();
m_hw_scale_height *= window().prescale();
/* This must be a multiple of 2 */
m_hw_scale_width = (m_hw_scale_width + 1) & ~1;
}
if (sdl_sm->is_yuv)
if (m_scale_mode.is_yuv)
m_yuv_bitmap = std::make_unique<uint16_t []>(m_hw_scale_width * m_hw_scale_height);
int w = m_hw_scale_width * sdl_sm->mult_w;
int h = m_hw_scale_height * sdl_sm->mult_h;
int w = m_hw_scale_width * m_scale_mode.mult_w;
int h = m_hw_scale_height * m_scale_mode.mult_h;
m_texture_id = SDL_CreateTexture(m_sdl_renderer, fmt, SDL_TEXTUREACCESS_STREAMING, w, h);
@ -179,26 +218,23 @@ void renderer_sdl1::show_info(struct SDL_RendererInfo *render_info)
int renderer_sdl1::create()
{
const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
auto win = assert_window();
// create renderer
/* set hints ... */
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, sm->sdl_scale_mode_hint);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, m_scale_mode.sdl_scale_mode_hint);
if (video_config.waitvsync)
m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
else
m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_ACCELERATED);
m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_ACCELERATED);
if (!m_sdl_renderer)
{
if (video_config.waitvsync)
m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE);
m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE);
else
m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_SOFTWARE);
m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_SOFTWARE);
}
if (!m_sdl_renderer)
@ -213,18 +249,18 @@ int renderer_sdl1::create()
// Check scale mode
if (sm->pixel_format)
if (m_scale_mode.pixel_format)
{
int i;
int found = 0;
for (i=0; i < render_info.num_texture_formats; i++)
if (sm->pixel_format == render_info.texture_formats[i])
if (m_scale_mode.pixel_format == render_info.texture_formats[i])
found = 1;
if (!found)
{
fatalerror("window: Scale mode %s not supported!", sm->name);
fatalerror("window: Scale mode %s not supported!", m_scale_mode.name);
}
}
@ -285,7 +321,6 @@ void renderer_sdl1::destroy_all_textures()
int renderer_sdl1::draw(int update)
{
const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
uint8_t *surfptr;
int32_t pitch;
Uint32 rmask, gmask, bmask;
@ -293,14 +328,7 @@ int renderer_sdl1::draw(int update)
int32_t vofs, hofs, blitwidth, blitheight, ch, cw;
int bpp;
if (video_config.novideo)
{
return 0;
}
auto win = assert_window();
osd_dim wdim = win->get_size();
osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim != m_last_dim))
{
destroy_all_textures();
@ -367,15 +395,15 @@ int renderer_sdl1::draw(int update)
m_last_hofs = hofs;
m_last_vofs = vofs;
win->m_primlist->acquire_lock();
window().m_primlist->acquire_lock();
int mamewidth, mameheight;
Uint32 fmt = 0;
int access = 0;
SDL_QueryTexture(m_texture_id, &fmt, &access, &mamewidth, &mameheight);
mamewidth /= sm->mult_w;
mameheight /= sm->mult_h;
mamewidth /= m_scale_mode.mult_w;
mameheight /= m_scale_mode.mult_h;
//printf("w h %d %d %d %d\n", mamewidth, mameheight, blitwidth, blitheight);
// rescale bounds
@ -385,7 +413,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 : *win->m_primlist)
for (render_primitive &prim : *window().m_primlist)
{
prim.bounds.x0 = floor(fw * prim.bounds.x0 + 0.5f);
prim.bounds.x1 = floor(fw * prim.bounds.x1 + 0.5f);
@ -394,32 +422,32 @@ int renderer_sdl1::draw(int update)
}
// render to it
if (!sm->is_yuv)
if (!m_scale_mode.is_yuv)
{
switch (rmask)
{
case 0xff000000:
software_renderer<uint32_t, 0,0,0, 24,16,8>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
software_renderer<uint32_t, 0,0,0, 24,16,8>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x0000ff00:
software_renderer<uint32_t, 0,0,0, 8,16,24>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
software_renderer<uint32_t, 0,0,0, 8,16,24>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x00ff0000:
software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x000000ff:
software_renderer<uint32_t, 0,0,0, 0,8,16>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
software_renderer<uint32_t, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0xf800:
software_renderer<uint16_t, 3,2,3, 11,5,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
software_renderer<uint16_t, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
break;
case 0x7c00:
software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
break;
default:
@ -431,11 +459,11 @@ int renderer_sdl1::draw(int update)
{
assert (m_yuv_bitmap != nullptr);
assert (surfptr != nullptr);
software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*win->m_primlist, m_yuv_bitmap.get(), mamewidth, mameheight, mamewidth);
sm->yuv_blit(m_yuv_bitmap.get(), surfptr, pitch, m_yuv_lookup.get(), mamewidth, mameheight);
software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, m_yuv_bitmap.get(), mamewidth, mameheight, mamewidth);
m_scale_mode.yuv_blit(m_yuv_bitmap.get(), surfptr, pitch, m_yuv_lookup.get(), mamewidth, mameheight);
}
win->m_primlist->release_lock();
window().m_primlist->release_lock();
// unlock and flip
SDL_UnlockTexture(m_texture_id);
@ -663,16 +691,98 @@ static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pi
render_primitive_list *renderer_sdl1::get_primitives()
{
auto win = try_getwindow();
if (win == nullptr)
return nullptr;
osd_dim nd = win->get_size();
osd_dim nd = window().get_size();
if (nd != m_blit_dim)
{
m_blit_dim = nd;
notify_changed();
}
win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
return &win->target()->get_primitives();
window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
return &window().target()->get_primitives();
}
class video_sdl1 : public osd_module, public render_module
{
public:
video_sdl1()
: osd_module(OSD_RENDERER_PROVIDER, "soft")
, m_scale_mode(-1)
{
}
virtual int init(osd_interface &osd, osd_options const &options) override;
virtual void exit() override { }
virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
protected:
virtual unsigned flags() const override { return FLAG_INTERACTIVE | FLAG_SDL_NEEDS_OPENGL; }
private:
static int get_scale_mode(char const *modestr);
int m_scale_mode;
static sdl_scale_mode const s_scale_modes[];
};
int video_sdl1::init(osd_interface &osd, osd_options const &options)
{
osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
// yuv settings ...
char const *const modestr = dynamic_cast<sdl_options const &>(options).scale_mode();
m_scale_mode = get_scale_mode(modestr);
if (m_scale_mode < 0)
{
osd_printf_warning("Invalid yuvmode value %s; reverting to none\n", modestr);
m_scale_mode = 0;
}
return 0;
}
std::unique_ptr<osd_renderer> video_sdl1::create(osd_window &window)
{
return std::make_unique<renderer_sdl1>(window, s_scale_modes[m_scale_mode]);
}
int video_sdl1::get_scale_mode(char const *modestr)
{
const sdl_scale_mode *sm = s_scale_modes;
int index = 0;
while (sm->name)
{
if (!strcmp(sm->name, modestr))
return index;
index++;
sm++;
}
return -1;
}
sdl_scale_mode const video_sdl1::s_scale_modes[] = {
{ "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, nullptr },
{ "hwblit", 1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, nullptr },
{ "hwbest", 1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, nullptr },
/* SDL1.2 uses interpolation as well */
{ "yv12", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
{ "yv12x2", 1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
{ "yuy2", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
{ "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
{ nullptr } };
} // anonymous namespace
} // namespace osd
#else // defined(OSD_SDL)
namespace osd { namespace { MODULE_NOT_SUPPORTED(video_sdl1, OSD_RENDERER_PROVIDER, "soft") } }
#endif // defined(OSD_SDL)
MODULE_DEFINITION(RENDERER_SDL1, osd::video_sdl1)

View File

@ -1,94 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
// drawsdl.h - SDL software and OpenGL implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
// yuvmodes by Couriersud
//
//============================================================
#ifndef MAME_OSD_MODULES_RENDER_DRAWSDL_H
#define MAME_OSD_MODULES_RENDER_DRAWSDL_H
#pragma once
// OSD headers
#include "window.h"
#include <SDL2/SDL.h>
#include <memory>
/* renderer_sdl1 is the information about SDL for the current screen */
class renderer_sdl1 : public osd_renderer
{
public:
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)
, m_yuv_lookup()
, m_yuv_bitmap()
//, m_hw_scale_width(0)
//, m_hw_scale_height(0)
, m_last_hofs(0)
, m_last_vofs(0)
, m_blit_dim(0, 0)
, m_last_dim(0, 0)
{
}
virtual ~renderer_sdl1();
static void init(running_machine &machine);
static void exit() { }
virtual int create() override;
virtual int draw(const int update) override;
virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
virtual render_primitive_list *get_primitives() override;
private:
void show_info(struct SDL_RendererInfo *render_info);
void destroy_all_textures();
void yuv_init();
void setup_texture(const osd_dim &size);
void yuv_lookup_set(unsigned int pen, unsigned char red,
unsigned char green, unsigned char blue);
int32_t m_blittimer;
SDL_Renderer *m_sdl_renderer;
SDL_Texture *m_texture_id;
// YUV overlay
std::unique_ptr<uint32_t []> m_yuv_lookup;
std::unique_ptr<uint16_t []> m_yuv_bitmap;
// if we leave scaling to SDL and the underlying driver, this
// is the render_target_width/height to use
int m_last_hofs;
int m_last_vofs;
osd_dim m_blit_dim;
osd_dim m_last_dim;
};
struct sdl_scale_mode
{
const char *name;
int is_scale; /* Scale mode? */
int is_yuv; /* Yuv mode? */
int mult_w; /* Width multiplier */
int mult_h; /* Height multiplier */
const char *sdl_scale_mode_hint; /* what to use as a hint ? */
int pixel_format; /* Pixel/Overlay format */
void (*yuv_blit)(const uint16_t *bitmap, uint8_t *ptr, const int pitch, const uint32_t *lookup, const int width, const int height);
};
#endif // MAME_OSD_MODULES_RENDER_DRAWSDL_H

View File

@ -0,0 +1,38 @@
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
#ifndef MAME_OSD_MODULES_RENDER_RENDER_MODULE_H
#define MAME_OSD_MODULES_RENDER_RENDER_MODULE_H
#pragma once
#include "osdepend.h"
#include "modules/osdmodule.h"
#include <memory>
#define OSD_RENDERER_PROVIDER "video"
class osd_renderer;
class osd_window;
class render_module
{
public:
virtual ~render_module() = default;
virtual std::unique_ptr<osd_renderer> create(osd_window &window) = 0;
bool is_interactive() const { return flags() & FLAG_INTERACTIVE; }
bool sdl_needs_opengl() const { return flags() & FLAG_SDL_NEEDS_OPENGL; }
protected:
static inline constexpr unsigned FLAG_INTERACTIVE = 1;
static inline constexpr unsigned FLAG_SDL_NEEDS_OPENGL = 2;
virtual unsigned flags() const = 0;
};
#endif // MAME_OSD_MODULES_RENDER_RENDER_MODULE_H

View File

@ -8,10 +8,11 @@
#include "sound_module.h"
#include "modules/osdmodule.h"
#include "modules/lib/osdobj_common.h"
#ifdef SDLMAME_MACOSX
#include "modules/lib/osdobj_common.h"
#include <AvailabilityMacros.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioUnit/AudioUnit.h>
@ -36,6 +37,8 @@ public:
sound_module(),
m_graph(nullptr),
m_node_count(0),
m_sample_rate(0),
m_audio_latency(0),
m_sample_bytes(0),
m_headroom(0),
m_buffer_size(0),
@ -166,14 +169,16 @@ private:
unsigned m_node_count;
node_detail m_node_details[EFFECT_COUNT_MAX + 2];
uint32_t m_sample_bytes;
uint32_t m_headroom;
uint32_t m_buffer_size;
int m_sample_rate;
int m_audio_latency;
uint32_t m_sample_bytes;
uint32_t m_headroom;
uint32_t m_buffer_size;
std::unique_ptr<int8_t []> m_buffer;
uint32_t m_playpos;
uint32_t m_writepos;
uint32_t m_playpos;
uint32_t m_writepos;
bool m_in_underrun;
int32_t m_scale;
int32_t m_scale;
unsigned m_overflows;
unsigned m_underflows;
};
@ -184,7 +189,9 @@ int sound_coreaudio::init(osd_interface &osd, const osd_options &options)
OSStatus err;
// Don't bother with any of this if sound is disabled
if (sample_rate() == 0)
m_sample_rate = options.sample_rate();
m_audio_latency = options.audio_latency();
if (m_sample_rate == 0)
return 0;
// Create the output graph
@ -194,7 +201,7 @@ int sound_coreaudio::init(osd_interface &osd, const osd_options &options)
// Set audio stream format for two-channel native-endian 16-bit packed linear PCM
AudioStreamBasicDescription format;
format.mSampleRate = sample_rate();
format.mSampleRate = m_sample_rate;
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kAudioFormatFlagsNativeEndian
| kLinearPCMFormatFlagIsSignedInteger
@ -219,8 +226,8 @@ int sound_coreaudio::init(osd_interface &osd, const osd_options &options)
m_sample_bytes = format.mBytesPerFrame;
// Allocate buffer
m_headroom = m_sample_bytes * (clamped_latency() * sample_rate() / 40);
m_buffer_size = m_sample_bytes * std::max<uint32_t>(sample_rate() * (clamped_latency() + 3) / 40, 256U);
m_headroom = m_sample_bytes * (clamped_latency() * m_sample_rate / 40);
m_buffer_size = m_sample_bytes * std::max<uint32_t>(m_sample_rate * (clamped_latency() + 3) / 40, 256U);
try
{
m_buffer = std::make_unique<int8_t []>(m_buffer_size);
@ -285,7 +292,7 @@ void sound_coreaudio::exit()
void sound_coreaudio::update_audio_stream(bool is_throttled, int16_t const *buffer, int samples_this_frame)
{
if ((sample_rate() == 0) || !m_buffer)
if ((m_sample_rate == 0) || !m_buffer)
return;
uint32_t const bytes_this_frame = samples_this_frame * m_sample_bytes;
@ -1010,10 +1017,10 @@ OSStatus sound_coreaudio::render_callback(
} // namespace osd
#else /* SDLMAME_MACOSX */
#else // SDLMAME_MACOSX
namespace osd { namespace { MODULE_NOT_SUPPORTED(sound_coreaudio, OSD_SOUND_PROVIDER, "coreaudio") } }
#endif
#endif // SDLMAME_MACOSX
MODULE_DEFINITION(SOUND_COREAUDIO, osd::sound_coreaudio)

View File

@ -15,11 +15,11 @@
#include "emuopts.h"
// osd headers
#include "modules/lib/osdobj_common.h"
#include "osdepend.h"
#include "osdcore.h"
#ifdef SDLMAME_WIN32
#include "modules/lib/osdobj_common.h"
#include "sdl/window.h"
#include <SDL2/SDL_syswm.h>
#else
@ -207,10 +207,11 @@ private:
class sound_direct_sound : public osd_module, public sound_module
{
public:
sound_direct_sound() :
osd_module(OSD_SOUND_PROVIDER, "dsound"),
sound_module(),
m_sample_rate(0),
m_audio_latency(0),
m_bytes_per_sample(0),
m_primary_buffer(),
m_stream_buffer(),
@ -219,7 +220,6 @@ public:
m_buffer_overflows(0)
{
}
virtual ~sound_direct_sound() { }
virtual int init(osd_interface &osd, osd_options const &options) override;
virtual void exit() override;
@ -237,6 +237,10 @@ private:
// DirectSound objects
Microsoft::WRL::ComPtr<IDirectSound> m_dsound;
// configuration
int m_sample_rate;
int m_audio_latency;
// descriptors and formats
uint32_t m_bytes_per_sample;
@ -257,10 +261,14 @@ private:
int sound_direct_sound::init(osd_interface &osd, osd_options const &options)
{
// attempt to initialize DirectSound
// don't make it fatal if we can't -- we'll just run without sound
dsound_init();
m_sample_rate = options.sample_rate();
m_audio_latency = options.audio_latency();
m_buffer_underflows = m_buffer_overflows = 0;
// attempt to initialize DirectSound
if (dsound_init() != DS_OK)
return -1;
return 0;
}
@ -407,10 +415,14 @@ HRESULT sound_direct_sound::dsound_init()
#ifdef SDLMAME_WIN32
SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version);
SDL_GetWindowWMInfo(std::dynamic_pointer_cast<sdl_window_info>(osd_common_t::s_window_list.front())->platform_window(), &wminfo);
if (!SDL_GetWindowWMInfo(dynamic_cast<sdl_window_info &>(*osd_common_t::window_list().front()).platform_window(), &wminfo))
{
result = DSERR_UNSUPPORTED; // just so it has something to return
goto error;
}
HWND const window = wminfo.info.win.window;
#else // SDLMAME_WIN32
HWND const window = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
HWND const window = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
#endif // SDLMAME_WIN32
result = m_dsound->SetCooperativeLevel(window, DSSCL_PRIORITY);
}
@ -426,7 +438,7 @@ HRESULT sound_direct_sound::dsound_init()
stream_format.wBitsPerSample = 16;
stream_format.wFormatTag = WAVE_FORMAT_PCM;
stream_format.nChannels = 2;
stream_format.nSamplesPerSec = sample_rate();
stream_format.nSamplesPerSec = m_sample_rate;
stream_format.nBlockAlign = stream_format.wBitsPerSample * stream_format.nChannels / 8;
stream_format.nAvgBytesPerSec = stream_format.nSamplesPerSec * stream_format.nBlockAlign;
@ -567,4 +579,5 @@ namespace osd { namespace { MODULE_NOT_SUPPORTED(sound_direct_sound, OSD_SOUND_P
#endif // defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
MODULE_DEFINITION(SOUND_DSOUND, osd::sound_direct_sound)

View File

@ -11,7 +11,7 @@
#include "sound_module.h"
#include "modules/osdmodule.h"
#if (defined(SDLMAME_EMSCRIPTEN))
#if defined(SDLMAME_EMSCRIPTEN)
#include "emscripten.h"
@ -19,8 +19,7 @@ class sound_js : public osd_module, public sound_module
{
public:
sound_js()
: osd_module(OSD_SOUND_PROVIDER, "js"), sound_module()
sound_js() : osd_module(OSD_SOUND_PROVIDER, "js"), sound_module()
{
}
virtual ~sound_js() { }
@ -32,23 +31,28 @@ public:
virtual void update_audio_stream(bool is_throttled, const int16_t *buffer, int samples_this_frame)
{
EM_ASM_ARGS({
// Forward audio stream update on to JS backend implementation.
jsmame_update_audio_stream($0, $1);
}, (unsigned int)buffer, samples_this_frame);
EM_ASM_ARGS(
{
// Forward audio stream update on to JS backend implementation.
jsmame_update_audio_stream($0, $1);
},
(unsigned int)buffer,
samples_this_frame);
}
virtual void set_mastervolume(int attenuation)
{
EM_ASM_ARGS({
// Forward volume update on to JS backend implementation.
jsmame_set_mastervolume($0);
}, attenuation);
EM_ASM_ARGS(
{
// Forward volume update on to JS backend implementation.
jsmame_set_mastervolume($0);
},
attenuation);
}
};
#else /* SDLMAME_EMSCRIPTEN */
#else // SDLMAME_EMSCRIPTEN
MODULE_NOT_SUPPORTED(sound_js, OSD_SOUND_PROVIDER, "js")
#endif
#endif // SDLMAME_EMSCRIPTEN
MODULE_DEFINITION(SOUND_JS, sound_js)

View File

@ -157,6 +157,8 @@ private:
PaStream* m_pa_stream;
PaError err;
int m_sample_rate;
int m_audio_latency;
int m_attenuation;
audio_buffer<s16>* m_ab;
@ -179,6 +181,10 @@ private:
int sound_pa::init(osd_interface &osd, osd_options const &options)
{
m_sample_rate = options.sample_rate();
if (!m_sample_rate)
return 0;
PaStreamParameters stream_params;
const PaStreamInfo* stream_info;
const PaHostApiInfo* api_info;
@ -187,9 +193,6 @@ int sound_pa::init(osd_interface &osd, osd_options const &options)
unsigned long frames_per_callback = paFramesPerBufferUnspecified;
double callback_interval;
if (!sample_rate())
return 0;
m_attenuation = options.volume();
m_underflows = 0;
m_overflows = 0;
@ -199,7 +202,7 @@ int sound_pa::init(osd_interface &osd, osd_options const &options)
m_skip_threshold_ticks = 0;
m_osd_tps = osd_ticks_per_second();
m_buffer_min_ct = INT_MAX;
m_audio_latency = std::clamp<int>(m_audio_latency, LATENCY_MIN, LATENCY_MAX);
m_audio_latency = std::clamp<int>(options.audio_latency(), LATENCY_MIN, LATENCY_MAX);
try {
m_ab = new audio_buffer<s16>(m_sample_rate, 2);
@ -371,7 +374,7 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples)
int adjust = m_buffer_min_ct - m_skip_threshold / 2;
// if adjustment is less than two milliseconds, don't bother
if (adjust / 2 > sample_rate() / 500) {
if (adjust / 2 > m_sample_rate / 500) {
m_ab->increment_playpos(adjust);
m_has_overflowed = true;
}
@ -398,7 +401,7 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples)
void sound_pa::update_audio_stream(bool is_throttled, const s16 *buffer, int samples_this_frame)
{
if (!sample_rate())
if (!m_sample_rate)
return;
#if LOG_BUFCNT
@ -433,7 +436,7 @@ void sound_pa::set_mastervolume(int attenuation)
void sound_pa::exit()
{
if (!sample_rate())
if (!m_sample_rate)
return;
#if LOG_BUFCNT

View File

@ -296,24 +296,26 @@ int sound_pulse::init(osd_interface &osd, osd_options const &options)
if(res != 'r')
return 1;
const int sample_rate = options.sample_rate();
pa_sample_spec ss;
#ifdef LSB_FIRST
ss.format = PA_SAMPLE_S16LE;
#else
ss.format = PA_SAMPLE_S16BE;
#endif
ss.rate = sample_rate();
ss.rate = sample_rate;
ss.channels = 2;
m_stream = pa_stream_new(m_context, "main output", &ss, nullptr);
pa_stream_set_state_callback(m_stream, i_stream_notify, this);
pa_stream_set_write_callback(m_stream, i_stream_write_request, this);
pa_buffer_attr battr;
battr.fragsize = sample_rate() / 1000;
battr.fragsize = sample_rate / 1000;
battr.maxlength = uint32_t(-1);
battr.minreq = sample_rate() / 1000;
battr.minreq = sample_rate / 1000;
battr.prebuf = uint32_t(-1);
battr.tlength = sample_rate() / 1000;
battr.tlength = sample_rate / 1000;
err = pa_stream_connect_playback(m_stream, nullptr, &battr, PA_STREAM_ADJUST_LATENCY, nullptr, nullptr);
if(err)

View File

@ -14,6 +14,7 @@
#if (defined(OSD_SDL) || defined(USE_SDL_SOUND))
#include "modules/lib/osdobj_common.h"
#include "osdcore.h"
// standard sdl header
@ -50,10 +51,16 @@ public:
sound_sdl() :
osd_module(OSD_SOUND_PROVIDER, "sdl"), sound_module(),
sample_rate(0),
sdl_xfer_samples(SDL_XFER_SAMPLES),
stream_in_initialized(0),
attenuation(0), buf_locked(0), stream_buffer(nullptr), stream_buffer_size(0), buffer_underflows(0), buffer_overflows(0)
attenuation(0),
buf_locked(0),
stream_buffer(nullptr),
stream_buffer_size(0),
buffer_underflows(0),
buffer_overflows(0)
{
sdl_xfer_samples = SDL_XFER_SAMPLES;
}
virtual ~sound_sdl() { }
@ -91,6 +98,7 @@ private:
int sdl_create_buffers();
void sdl_destroy_buffers();
int sample_rate;
int sdl_xfer_samples;
int stream_in_initialized;
int attenuation;
@ -244,10 +252,9 @@ void sound_sdl::copy_sample_data(bool is_throttled, const int16_t *data, int byt
void sound_sdl::update_audio_stream(bool is_throttled, const int16_t *buffer, int samples_this_frame)
{
// if nothing to do, don't do it
if (sample_rate() == 0 || !stream_buffer)
if (sample_rate == 0 || !stream_buffer)
return;
if (!stream_in_initialized)
{
// Fill in some zeros to prevent an initial buffer underflow
@ -345,7 +352,8 @@ int sound_sdl::init(osd_interface &osd, const osd_options &options)
sound_log = std::make_unique<std::ofstream>(SDLMAME_SOUND_LOG);
// skip if sound disabled
if (sample_rate() != 0)
sample_rate = options.sample_rate();
if (sample_rate != 0)
{
if (SDL_InitSubSystem(SDL_INIT_AUDIO))
{
@ -361,7 +369,7 @@ int sound_sdl::init(osd_interface &osd, const osd_options &options)
stream_in_initialized = 0;
// set up the audio specs
aspec.freq = sample_rate();
aspec.freq = sample_rate;
aspec.format = AUDIO_S16SYS; // keep endian independent
aspec.channels = n_channels;
aspec.samples = sdl_xfer_samples;
@ -377,10 +385,10 @@ int sound_sdl::init(osd_interface &osd, const osd_options &options)
sdl_xfer_samples = obtained.samples;
// pin audio latency
audio_latency = std::clamp(m_audio_latency, 1, MAX_AUDIO_LATENCY);
audio_latency = std::clamp(options.audio_latency(), 1, MAX_AUDIO_LATENCY);
// compute the buffer sizes
stream_buffer_size = (sample_rate() * 2 * sizeof(int16_t) * (2 + audio_latency)) / 30;
stream_buffer_size = (sample_rate * 2 * sizeof(int16_t) * (2 + audio_latency)) / 30;
stream_buffer_size = (stream_buffer_size / 1024) * 1024;
if (stream_buffer_size < 1024)
stream_buffer_size = 1024;
@ -414,7 +422,7 @@ int sound_sdl::init(osd_interface &osd, const osd_options &options)
void sound_sdl::exit()
{
// if nothing to do, don't do it
if (sample_rate() == 0)
if (sample_rate == 0)
return;
osd_printf_verbose("sdl_kill: closing audio\n");

View File

@ -20,18 +20,10 @@
class sound_module
{
public:
sound_module() : m_sample_rate(0), m_audio_latency(1) { }
virtual ~sound_module() = default;
virtual void update_audio_stream(bool is_throttled, const int16_t *buffer, int samples_this_frame) = 0;
virtual void set_mastervolume(int attenuation) = 0;
int sample_rate() const { return m_sample_rate; }
// FIXME: these should be set by the implementation on initialisation, not by the OSD object
int m_sample_rate;
int m_audio_latency;
};
#endif // MAME_OSD_SOUND_SOUND_MODULE_H

View File

@ -10,14 +10,14 @@
#include "modules/osdmodule.h"
#if defined(OSD_WINDOWS)
// MAME headers
#include "winutil.h"
#if defined(OSD_WINDOWS) | defined(SDLMAME_WIN32)
// OSD headers
#include "modules/lib/osdlib.h"
#include "modules/lib/osdobj_common.h"
#include "osdcore.h"
#include "osdepend.h"
#include "windows/winutil.h"
// stdlib includes
#include <algorithm>
@ -34,8 +34,6 @@
// XAudio2 include
#include <xaudio2.h>
#undef interface
namespace osd {
@ -186,29 +184,6 @@ public:
// The main class for the XAudio2 sound module implementation
class sound_xaudio2 : public osd_module, public sound_module, public IXAudio2VoiceCallback
{
private:
Microsoft::WRL::ComPtr<IXAudio2> m_xAudio2;
mastering_voice_ptr m_masterVoice;
src_voice_ptr m_sourceVoice;
DWORD m_sample_bytes;
std::unique_ptr<BYTE[]> m_buffer;
DWORD m_buffer_size;
DWORD m_buffer_count;
DWORD m_writepos;
std::mutex m_buffer_lock;
HANDLE m_hEventBufferCompleted;
HANDLE m_hEventDataAvailable;
HANDLE m_hEventExiting;
std::thread m_audioThread;
std::queue<xaudio2_buffer> m_queue;
std::unique_ptr<bufferpool> m_buffer_pool;
uint32_t m_overflows;
uint32_t m_underflows;
BOOL m_in_underflow;
BOOL m_initialized;
OSD_DYNAMIC_API(xaudio2, "XAudio2_9.dll", "XAudio2_8.dll");
OSD_DYNAMIC_API_FN(xaudio2, HRESULT, WINAPI, XAudio2Create, IXAudio2 **, uint32_t, XAUDIO2_PROCESSOR);
public:
sound_xaudio2() :
osd_module(OSD_SOUND_PROVIDER, "xaudio2"),
@ -216,6 +191,8 @@ public:
m_xAudio2(nullptr),
m_masterVoice(nullptr),
m_sourceVoice(nullptr),
m_sample_rate(0),
m_audio_latency(0),
m_sample_bytes(0),
m_buffer(nullptr),
m_buffer_size(0),
@ -232,8 +209,6 @@ public:
{
}
virtual ~sound_xaudio2() { }
bool probe() override;
int init(osd_interface &osd, osd_options const &options) override;
void exit() override;
@ -242,6 +217,7 @@ public:
void update_audio_stream(bool is_throttled, int16_t const *buffer, int samples_this_frame) override;
void set_mastervolume(int attenuation) override;
private:
// Xaudio callbacks
void STDAPICALLTYPE OnVoiceProcessingPassStart(uint32_t bytes_required) override;
void STDAPICALLTYPE OnVoiceProcessingPassEnd() override {}
@ -251,7 +227,6 @@ public:
void STDAPICALLTYPE OnVoiceError(void* pBufferContext, HRESULT error) override {}
void STDAPICALLTYPE OnBufferEnd(void *pBufferContext) override;
private:
void create_buffers(const WAVEFORMATEX &format);
HRESULT create_voices(const WAVEFORMATEX &format);
void process_audio();
@ -259,6 +234,31 @@ private:
void submit_needed();
void roll_buffer();
BOOL submit_next_queued();
Microsoft::WRL::ComPtr<IXAudio2> m_xAudio2;
mastering_voice_ptr m_masterVoice;
src_voice_ptr m_sourceVoice;
int m_sample_rate;
int m_audio_latency;
DWORD m_sample_bytes;
std::unique_ptr<BYTE[]> m_buffer;
DWORD m_buffer_size;
DWORD m_buffer_count;
DWORD m_writepos;
std::mutex m_buffer_lock;
HANDLE m_hEventBufferCompleted;
HANDLE m_hEventDataAvailable;
HANDLE m_hEventExiting;
std::thread m_audioThread;
std::queue<xaudio2_buffer> m_queue;
std::unique_ptr<bufferpool> m_buffer_pool;
uint32_t m_overflows;
uint32_t m_underflows;
BOOL m_in_underflow;
BOOL m_initialized;
OSD_DYNAMIC_API(xaudio2, "XAudio2_9.dll", "XAudio2_8.dll");
OSD_DYNAMIC_API_FN(xaudio2, HRESULT, WINAPI, XAudio2Create, IXAudio2 **, uint32_t, XAUDIO2_PROCESSOR);
};
//============================================================
@ -276,12 +276,7 @@ bool sound_xaudio2::probe()
int sound_xaudio2::init(osd_interface &osd, osd_options const &options)
{
HRESULT result;
WAVEFORMATEX format = {0};
auto init_start = std::chrono::system_clock::now();
std::chrono::milliseconds init_time;
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
auto const init_start = std::chrono::system_clock::now();
// Make sure our XAudio2Create entrypoint is bound
if (!OSD_DYNAMIC_API_TEST(XAudio2Create))
@ -290,6 +285,15 @@ int sound_xaudio2::init(osd_interface &osd, osd_options const &options)
return 1;
}
HRESULT result;
std::chrono::milliseconds init_time;
WAVEFORMATEX format = { 0 };
m_sample_rate = options.sample_rate();
m_audio_latency = options.audio_latency();
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
// Create the IXAudio2 object
HR_GOERR(OSD_DYNAMIC_CALL(XAudio2Create, m_xAudio2.GetAddressOf(), 0, XAUDIO2_DEFAULT_PROCESSOR));
@ -297,7 +301,7 @@ int sound_xaudio2::init(osd_interface &osd, osd_options const &options)
format.wBitsPerSample = 16;
format.wFormatTag = WAVE_FORMAT_PCM;
format.nChannels = 2;
format.nSamplesPerSec = sample_rate();
format.nSamplesPerSec = m_sample_rate;
format.nBlockAlign = format.wBitsPerSample * format.nChannels / 8;
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
@ -316,10 +320,10 @@ int sound_xaudio2::init(osd_interface &osd, osd_options const &options)
HR_GOERR(m_sourceVoice->Start());
// Start the thread listening
m_audioThread = std::thread([](sound_xaudio2* self) { self->process_audio(); }, this);
m_audioThread = std::thread([] (sound_xaudio2 *self) { self->process_audio(); }, this);
init_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - init_start);
osd_printf_verbose("Sound: XAudio2 initialized. %d ms.\n", static_cast<int>(init_time.count()));
osd_printf_verbose("Sound: XAudio2 initialized. %d ms.\n", init_time.count());
m_initialized = TRUE;
return 0;
@ -382,7 +386,7 @@ void sound_xaudio2::update_audio_stream(
int16_t const *buffer,
int samples_this_frame)
{
if (!m_initialized || sample_rate() == 0 || !m_buffer)
if (!m_initialized || m_sample_rate == 0 || !m_buffer)
return;
uint32_t const bytes_this_frame = samples_this_frame * m_sample_bytes;
@ -533,7 +537,7 @@ HRESULT sound_xaudio2::create_voices(const WAVEFORMATEX &format)
m_xAudio2->CreateMasteringVoice(
&temp_master_voice,
format.nChannels,
sample_rate()));
m_sample_rate));
m_masterVoice = mastering_voice_ptr(temp_master_voice);

View File

@ -134,23 +134,22 @@ void osd_sdl_info()
}
std::shared_ptr<sdl_window_info> window_from_id(Uint32 id)
sdl_window_info *window_from_id(Uint32 id)
{
SDL_Window const *const sdl_window = SDL_GetWindowFromID(id);
auto &windows = osd_common_t::s_window_list;
auto const window = std::find_if(
windows.begin(),
windows.end(),
[sdl_window] (std::shared_ptr<osd_window> w)
osd_common_t::window_list().begin(),
osd_common_t::window_list().end(),
[sdl_window] (std::unique_ptr<osd_window> const &w)
{
return std::static_pointer_cast<sdl_window_info>(w)->platform_window() == sdl_window;
return dynamic_cast<sdl_window_info &>(*w).platform_window() == sdl_window;
});
if (window == windows.end())
if (window == osd_common_t::window_list().end())
return nullptr;
return std::static_pointer_cast<sdl_window_info>(*window);
return &static_cast<sdl_window_info &>(**window);
}
} // anonymous namespace
@ -164,7 +163,7 @@ std::shared_ptr<sdl_window_info> window_from_id(Uint32 id)
sdl_osd_interface::sdl_osd_interface(sdl_options &options) :
osd_common_t(options),
m_options(options),
m_focus_window(),
m_focus_window(nullptr),
m_mouse_over_window(0),
m_modifier_keys(0),
m_last_click_time(std::chrono::steady_clock::time_point::min()),
@ -422,18 +421,6 @@ void sdl_osd_interface::customize_input_type_list(std::vector<input_type_entry>
}
void sdl_osd_interface::video_register()
{
video_options_add("soft", nullptr);
video_options_add("accel", nullptr);
#if USE_OPENGL
video_options_add("opengl", nullptr);
#endif
video_options_add("bgfx", nullptr);
//video_options_add("auto", nullptr); // making d3d video default one
}
void sdl_osd_interface::poll_inputs()
{
m_keyboard_input->poll_if_necessary();
@ -501,21 +488,21 @@ void sdl_osd_interface::process_events()
if (event.key.keysym.sym < 0x20)
{
// push control characters - they don't arrive as text input events
machine().ui_input().push_char_event(osd_common_t::s_window_list.front()->target(), event.key.keysym.sym);
machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), event.key.keysym.sym);
}
else if (m_modifier_keys & MODIFIER_KEY_CTRL)
{
// SDL filters out control characters for text input, so they are decoded here
if (event.key.keysym.sym >= 0x40 && event.key.keysym.sym < 0x7f)
{
machine().ui_input().push_char_event(osd_common_t::s_window_list.front()->target(), event.key.keysym.sym & 0x1f);
machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), event.key.keysym.sym & 0x1f);
}
else if (m_modifier_keys & MODIFIER_KEY_SHIFT)
{
if (event.key.keysym.sym == SDLK_6) // Ctrl-^ (RS)
machine().ui_input().push_char_event(osd_common_t::s_window_list.front()->target(), 0x1e);
machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), 0x1e);
else if (event.key.keysym.sym == SDLK_MINUS) // Ctrl-_ (US)
machine().ui_input().push_char_event(osd_common_t::s_window_list.front()->target(), 0x1f);
machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), 0x1f);
}
}
break;
@ -688,7 +675,7 @@ void sdl_osd_interface::process_textinput_event(SDL_Event const &event)
if (*event.text.text)
{
auto const window = focus_window(event.text);
//printf("Focus window is %p - wl %p\n", window, osd_common_t::s_window_list);
//printf("Focus window is %p - wl %p\n", window, osd_common_t::window_list().front().get());
if (window != nullptr)
{
auto ptr = event.text.text;
@ -716,11 +703,11 @@ void sdl_osd_interface::check_osd_inputs()
// check for toggling fullscreen mode
if (machine().ui_input().pressed(IPT_OSD_1))
{
for (auto curwin : osd_common_t::s_window_list)
std::static_pointer_cast<sdl_window_info>(curwin)->toggle_full_screen();
for (auto const &curwin : osd_common_t::window_list())
dynamic_cast<sdl_window_info &>(*curwin).toggle_full_screen();
}
auto window = osd_common_t::s_window_list.front();
auto const &window = osd_common_t::window_list().front();
if (USE_OPENGL)
{
@ -733,10 +720,10 @@ void sdl_osd_interface::check_osd_inputs()
}
if (machine().ui_input().pressed(IPT_OSD_6))
std::static_pointer_cast<sdl_window_info>(window)->modify_prescale(-1);
dynamic_cast<sdl_window_info &>(*window).modify_prescale(-1);
if (machine().ui_input().pressed(IPT_OSD_7))
std::static_pointer_cast<sdl_window_info>(window)->modify_prescale(1);
dynamic_cast<sdl_window_info &>(*window).modify_prescale(1);
if (machine().ui_input().pressed(IPT_OSD_8))
window->renderer().record();
@ -748,7 +735,7 @@ sdl_window_info *sdl_osd_interface::focus_window(T const &event) const
{
// FIXME: SDL does not properly report the window for certain OS.
if (false)
return window_from_id(event.windowID).get();
return window_from_id(event.windowID);
else
return m_focus_window.get();
return m_focus_window;
}

View File

@ -150,8 +150,6 @@ public:
// input overridables
virtual void customize_input_type_list(std::vector<input_type_entry> &typelist) override;
virtual void video_register() override;
virtual bool video_init() override;
virtual bool window_init() override;
@ -199,7 +197,7 @@ private:
template <typename T> sdl_window_info *focus_window(T const &event) const;
sdl_options &m_options;
std::shared_ptr<sdl_window_info> m_focus_window;
sdl_window_info *m_focus_window;
int m_mouse_over_window;
uint8_t m_modifier_keys;

View File

@ -14,6 +14,7 @@
#include "osdsdl.h"
#include "modules/lib/osdlib.h"
#include "modules/monitor/monitor_module.h"
#include "modules/render/render_module.h"
// MAME headers
#include "emu.h"
@ -65,12 +66,16 @@ bool sdl_osd_interface::video_init()
get_resolution(options().resolution(), options().resolution(index), &conf, true);
// create window ...
std::shared_ptr<sdl_window_info> win = std::make_shared<sdl_window_info>(machine(), index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf);
auto win = std::make_unique<sdl_window_info>(machine(), *m_render, index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf);
if (win->window_init())
return false;
s_window_list.emplace_back(std::move(win));
}
if (m_render->is_interactive())
SDL_RaiseWindow(dynamic_cast<sdl_window_info &>(*osd_common_t::s_window_list.front()).platform_window());
return true;
}
@ -95,7 +100,7 @@ void sdl_osd_interface::update(bool skip_redraw)
if (!skip_redraw)
{
// profiler_mark(PROFILER_BLIT);
for (auto window : osd_common_t::s_window_list)
for (auto const &window : osd_common_t::window_list())
window->update();
// profiler_mark(PROFILER_END);
}
@ -111,8 +116,6 @@ void sdl_osd_interface::update(bool skip_redraw)
void sdl_osd_interface::extract_video_config()
{
const char *stemp;
video_config.perftest = options().video_fps();
// global options: extract the data
@ -128,47 +131,6 @@ void sdl_osd_interface::extract_video_config()
if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)
video_config.windowed = true;
// default to working video please
video_config.novideo = 0;
// video options: extract the data
stemp = options().video();
if (strcmp(stemp, "auto") == 0)
{
#if (defined SDLMAME_EMSCRIPTEN)
stemp = "soft";
#else
stemp = "bgfx";
#endif
}
if (strcmp(stemp, SDLOPTVAL_SOFT) == 0)
video_config.mode = VIDEO_MODE_SOFT;
else if (strcmp(stemp, OSDOPTVAL_NONE) == 0)
{
video_config.mode = VIDEO_MODE_SOFT;
video_config.novideo = 1;
if (!emulator_info::standalone() && options().seconds_to_run() == 0)
osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
}
#if (USE_OPENGL)
else if (strcmp(stemp, SDLOPTVAL_OPENGL) == 0)
video_config.mode = VIDEO_MODE_OPENGL;
#endif
else if ((strcmp(stemp, SDLOPTVAL_SDL2ACCEL) == 0))
{
video_config.mode = VIDEO_MODE_SDL2ACCEL;
}
else if (strcmp(stemp, SDLOPTVAL_BGFX) == 0)
{
video_config.mode = VIDEO_MODE_BGFX;
}
else
{
osd_printf_warning("Invalid video value %s; reverting to software\n", stemp);
video_config.mode = VIDEO_MODE_SOFT;
}
video_config.switchres = options().switch_res();
video_config.centerh = options().centerh();
video_config.centerv = options().centerv();
@ -185,64 +147,7 @@ void sdl_osd_interface::extract_video_config()
osd_printf_warning("Invalid prescale option, reverting to '1'\n");
video_config.prescale = 1;
}
#if (USE_OPENGL)
// default to working video please
video_config.forcepow2texture = options().gl_force_pow2_texture();
video_config.allowtexturerect = !(options().gl_no_texture_rect());
video_config.vbo = options().gl_vbo();
video_config.pbo = options().gl_pbo();
video_config.glsl = options().gl_glsl();
if ( video_config.glsl )
{
int i;
video_config.glsl_filter = options().glsl_filter();
video_config.glsl_shader_mamebm_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
stemp = options().shader_mame(i);
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
{
video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1);
strcpy(video_config.glsl_shader_mamebm[i], stemp);
video_config.glsl_shader_mamebm_num++;
} else {
video_config.glsl_shader_mamebm[i] = nullptr;
}
}
video_config.glsl_shader_scrn_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
stemp = options().shader_screen(i);
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
{
video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1);
strcpy(video_config.glsl_shader_scrn[i], stemp);
video_config.glsl_shader_scrn_num++;
} else {
video_config.glsl_shader_scrn[i] = nullptr;
}
}
} else {
int i;
video_config.glsl_filter = 0;
video_config.glsl_shader_mamebm_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
video_config.glsl_shader_mamebm[i] = nullptr;
}
video_config.glsl_shader_scrn_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
video_config.glsl_shader_scrn[i] = nullptr;
}
}
#endif /* USE_OPENGL */
// misc options: sanity check values
// global options: sanity check values
@ -251,19 +156,6 @@ void sdl_osd_interface::extract_video_config()
osd_printf_warning("Invalid numscreens value %d; reverting to 1\n", video_config.numscreens);
video_config.numscreens = 1;
}
// yuv settings ...
stemp = options().scale_mode();
video_config.scale_mode = drawsdl_scale_mode(stemp);
if (video_config.scale_mode < 0)
{
osd_printf_warning("Invalid yuvmode value %s; reverting to none\n", stemp);
video_config.scale_mode = VIDEO_SCALE_MODE_NONE;
}
if ( (video_config.mode != VIDEO_MODE_SOFT) && (video_config.scale_mode != VIDEO_SCALE_MODE_NONE) )
{
osd_printf_warning("scalemode is only for -video soft, overriding\n");
video_config.scale_mode = VIDEO_SCALE_MODE_NONE;
}
}

View File

@ -18,13 +18,7 @@
// OSD headers
#include "window.h"
#include "osdsdl.h"
#include "modules/render/drawbgfx.h"
#include "modules/render/drawsdl.h"
#include "modules/render/draw13.h"
#include "modules/monitor/monitor_common.h"
#if (USE_OPENGL)
#include "modules/render/drawogl.h"
#endif
// standard SDL headers
#include <SDL2/SDL.h>
@ -83,60 +77,10 @@ bool sdl_osd_interface::window_init()
{
osd_printf_verbose("Enter sdlwindow_init\n");
// initialize the renderer
const int fallbacks[VIDEO_MODE_COUNT] = {
-1, // NONE -> no fallback
-1, // No GDI on Linux
#if defined(USE_OPENGL) && USE_OPENGL
VIDEO_MODE_OPENGL, // BGFX -> OpenGL
-1, // OpenGL -> no fallback
#else
VIDEO_MODE_SDL2ACCEL, // BGFX -> SDL2Accel
#endif
-1, // SDL2ACCEL -> no fallback
-1, // No D3D on Linux
-1, // SOFT -> no fallback
};
int current_mode = video_config.mode;
while (current_mode != VIDEO_MODE_NONE)
{
bool error = false;
switch(current_mode)
{
case VIDEO_MODE_BGFX:
error = renderer_bgfx::init(machine());
break;
#if defined(USE_OPENGL) && USE_OPENGL
case VIDEO_MODE_OPENGL:
renderer_ogl::init(machine());
break;
#endif
case VIDEO_MODE_SDL2ACCEL:
renderer_sdl2::init(machine());
break;
case VIDEO_MODE_SOFT:
renderer_sdl1::init(machine());
break;
default:
fatalerror("Unknown video mode.");
break;
}
if (error)
{
current_mode = fallbacks[current_mode];
}
else
{
break;
}
}
video_config.mode = current_mode;
/* We may want to set a number of the hints SDL2 provides.
* The code below will document which hints were set.
*/
const char * hints[] = { SDL_HINT_FRAMEBUFFER_ACCELERATION,
// We may want to set a number of the hints SDL2 provides.
// The code below will document which hints were set.
char const *const hints[] = {
SDL_HINT_FRAMEBUFFER_ACCELERATION,
SDL_HINT_RENDER_DRIVER, SDL_HINT_RENDER_OPENGL_SHADERS,
SDL_HINT_RENDER_SCALE_QUALITY,
SDL_HINT_RENDER_VSYNC,
@ -158,14 +102,13 @@ bool sdl_osd_interface::window_init()
SDL_HINT_WINRT_PRIVACY_POLICY_URL, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL,
SDL_HINT_WINRT_HANDLE_BACK_BUTTON,
#endif
nullptr
};
};
osd_printf_verbose("\nHints:\n");
for (int i = 0; hints[i] != nullptr; i++)
for (auto const hintname : hints)
{
char const *const hint(SDL_GetHint(hints[i]));
osd_printf_verbose("\t%-40s %s\n", hints[i], hint ? hint : "(NULL)");
char const *const hintvalue(SDL_GetHint(hintname));
osd_printf_verbose("\t%-40s %s\n", hintname, hintvalue ? hintvalue : "(NULL)");
}
// set up the window list
@ -176,7 +119,7 @@ bool sdl_osd_interface::window_init()
void sdl_osd_interface::update_slider_list()
{
for (auto window : osd_common_t::s_window_list)
for (auto const &window : osd_common_t::window_list())
{
// check if any window has dirty sliders
if (window->renderer().sliders_dirty())
@ -191,7 +134,7 @@ void sdl_osd_interface::build_slider_list()
{
m_sliders.clear();
for (auto window : osd_common_t::s_window_list)
for (auto const &window : osd_common_t::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());
@ -208,33 +151,14 @@ void sdl_osd_interface::window_exit()
osd_printf_verbose("Enter sdlwindow_exit\n");
// free all the windows
m_focus_window = nullptr;
while (!osd_common_t::s_window_list.empty())
{
auto window = osd_common_t::s_window_list.front();
// Part of destroy removes the window from the list
auto window = std::move(osd_common_t::s_window_list.back());
s_window_list.pop_back();
window->destroy();
}
switch (video_config.mode)
{
case VIDEO_MODE_SDL2ACCEL:
renderer_sdl1::exit();
break;
case VIDEO_MODE_SOFT:
renderer_sdl1::exit();
break;
case VIDEO_MODE_BGFX:
renderer_bgfx::exit();
break;
#if (USE_OPENGL)
case VIDEO_MODE_OPENGL:
renderer_ogl::exit();
break;
#endif
default:
break;
}
osd_printf_verbose("Leave sdlwindow_exit\n");
}
@ -336,11 +260,8 @@ void sdl_window_info::toggle_full_screen()
}
SDL_DestroyWindow(platform_window());
set_platform_window(nullptr);
downcast<sdl_osd_interface &>(machine().osd()).release_keys();
set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
// toggle the window mode
set_fullscreen(!fullscreen());
@ -368,8 +289,8 @@ void sdl_window_info::modify_prescale(int dir)
}
else
{
notify_changed();
m_prescale = new_prescale;
notify_changed();
}
machine().ui().popup_time(1, "Prescale %d", prescale());
}
@ -432,8 +353,6 @@ int sdl_window_info::window_init()
create_target();
set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast<osd_window*>(this)->shared_from_this()));
int result = complete_create();
// handle error conditions
@ -465,8 +384,9 @@ void sdl_window_info::complete_destroy()
SDL_SetWindowFullscreen(platform_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode
}
renderer_reset();
SDL_DestroyWindow(platform_window());
// release all keys ...
set_platform_window(nullptr);
downcast<sdl_osd_interface &>(machine().osd()).release_keys();
}
@ -666,13 +586,15 @@ int sdl_window_info::complete_create()
*
*/
osd_printf_verbose("Enter sdl_info::create\n");
if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL) && !video_config.novideo)
if (renderer_sdl_needs_opengl())
{
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
m_extra_flags = SDL_WINDOW_OPENGL;
}
else
{
m_extra_flags = 0;
}
// We need to workaround an issue in SDL 2.0.4 for OS X where setting the
// relative mode on the mouse in fullscreen mode makes mouse events stop
@ -771,7 +693,7 @@ int sdl_window_info::complete_create()
if (sdlwindow == nullptr )
{
if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL))
if (renderer_sdl_needs_opengl())
osd_printf_error("OpenGL not supported on this driver: %s\n", SDL_GetError());
else
osd_printf_error("Window creation failed: %s\n", SDL_GetError());
@ -779,6 +701,7 @@ int sdl_window_info::complete_create()
}
set_platform_window(sdlwindow);
renderer_create();
if (fullscreen() && video_config.switchres)
{
@ -817,24 +740,6 @@ int sdl_window_info::complete_create()
SDL_SetWindowGrab(platform_window(), SDL_TRUE);
#endif
// set main window
if (index() > 0)
{
for (auto w : osd_common_t::s_window_list)
{
if (w->index() == 0)
{
set_main_window(std::dynamic_pointer_cast<osd_window>(w));
break;
}
}
}
else
{
// We must be the main window
set_main_window(shared_from_this());
}
// update monitor resolution after mode change to ensure proper pixel aspect
monitor()->refresh();
if (fullscreen() && video_config.switchres)
@ -1146,10 +1051,11 @@ osd_dim sdl_window_info::get_max_bounds(int constrain)
sdl_window_info::sdl_window_info(
running_machine &a_machine,
render_module &renderprovider,
int index,
std::shared_ptr<osd_monitor_info> a_monitor,
const std::shared_ptr<osd_monitor_info> &a_monitor,
const osd_window_config *config)
: osd_window_t(a_machine, index, std::move(a_monitor), *config)
: osd_window_t(a_machine, renderprovider, index, std::move(a_monitor), *config)
, m_startmaximized(0)
// Following three are used by input code to defer resizes
, m_minimum_dim(0, 0)

View File

@ -37,7 +37,11 @@ typedef uintptr_t HashT;
class sdl_window_info : public osd_window_t<SDL_Window*>
{
public:
sdl_window_info(running_machine &a_machine, int index, std::shared_ptr<osd_monitor_info> a_monitor,
sdl_window_info(
running_machine &a_machine,
render_module &renderprovider,
int index,
const std::shared_ptr<osd_monitor_info> &a_monitor,
const osd_window_config *config);
~sdl_window_info();
@ -98,37 +102,4 @@ private:
};
struct osd_draw_callbacks
{
osd_renderer *(*create)(osd_window *window);
};
//============================================================
// PROTOTYPES
//============================================================
//============================================================
// PROTOTYPES - drawsdl.c
//============================================================
int drawsdl_scale_mode(const char *s);
//============================================================
// PROTOTYPES - drawogl.c
//============================================================
int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks);
//============================================================
// PROTOTYPES - draw13.c
//============================================================
int drawsdl2_init(running_machine &machine, osd_draw_callbacks *callbacks);
//============================================================
// PROTOTYPES - drawbgfx.c
//============================================================
int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks);
#endif // MAME_OSD_SDL_WINDOW_H

View File

@ -6,8 +6,9 @@
//
//============================================================
#include "modules/monitor/monitor_module.h"
#include "modules/osdwindow.h"
#include "modules/monitor/monitor_module.h"
#include "modules/render/render_module.h"
// MAME headers
#include "emu.h"
@ -62,11 +63,17 @@ bool windows_osd_interface::video_init()
auto &options = downcast<windows_options &>(machine().options());
for (int index = 0; index < video_config.numscreens; index++)
{
win_window_info::create(machine(), index, m_monitor_module->pick_monitor(options, index), &windows[index]);
auto window = win_window_info::create(
machine(),
*m_render,
index,
m_monitor_module->pick_monitor(options, index),
&windows[index]);
s_window_list.emplace_back(std::move(window));
}
if (video_config.mode != VIDEO_MODE_NONE)
SetForegroundWindow(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window());
if (m_render->is_interactive())
SetForegroundWindow(dynamic_cast<win_window_info &>(*osd_common_t::s_window_list.front()).platform_window());
return true;
}
@ -146,8 +153,6 @@ void windows_osd_interface::check_osd_inputs()
void windows_osd_interface::extract_video_config()
{
const char *stemp;
// global options: extract the data
video_config.windowed = options().window();
video_config.prescale = options().prescale();
@ -165,31 +170,6 @@ void windows_osd_interface::extract_video_config()
get_resolution(default_resolution, options().resolution(2), &windows[2], TRUE);
get_resolution(default_resolution, options().resolution(3), &windows[3], TRUE);
// video options: extract the data
stemp = options().video();
if (strcmp(stemp, "d3d") == 0)
video_config.mode = VIDEO_MODE_D3D;
else if (strcmp(stemp, "auto") == 0)
video_config.mode = VIDEO_MODE_D3D;
else if (strcmp(stemp, "gdi") == 0)
video_config.mode = VIDEO_MODE_GDI;
else if (strcmp(stemp, "bgfx") == 0)
video_config.mode = VIDEO_MODE_BGFX;
else if (strcmp(stemp, "none") == 0)
{
video_config.mode = VIDEO_MODE_NONE;
if (!emulator_info::standalone() && options().seconds_to_run() == 0)
osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
}
#if (USE_OPENGL)
else if (strcmp(stemp, "opengl") == 0)
video_config.mode = VIDEO_MODE_OPENGL;
#endif
else
{
osd_printf_warning("Invalid video value %s; reverting to gdi\n", stemp);
video_config.mode = VIDEO_MODE_GDI;
}
video_config.waitvsync = options().wait_vsync();
video_config.syncrefresh = options().sync_refresh();
video_config.triplebuf = options().triple_buffer();
@ -200,65 +180,6 @@ void windows_osd_interface::extract_video_config()
osd_printf_warning("Invalid prescale option, reverting to '1'\n");
video_config.prescale = 1;
}
#if (USE_OPENGL)
// default to working video please
video_config.forcepow2texture = options().gl_force_pow2_texture();
video_config.allowtexturerect = !(options().gl_no_texture_rect());
video_config.vbo = options().gl_vbo();
video_config.pbo = options().gl_pbo();
video_config.glsl = options().gl_glsl();
if ( video_config.glsl )
{
int i;
video_config.glsl_filter = options().glsl_filter();
video_config.glsl_shader_mamebm_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
stemp = options().shader_mame(i);
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
{
video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1);
strcpy(video_config.glsl_shader_mamebm[i], stemp);
video_config.glsl_shader_mamebm_num++;
} else {
video_config.glsl_shader_mamebm[i] = nullptr;
}
}
video_config.glsl_shader_scrn_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
stemp = options().shader_screen(i);
if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
{
video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1);
strcpy(video_config.glsl_shader_scrn[i], stemp);
video_config.glsl_shader_scrn_num++;
} else {
video_config.glsl_shader_scrn[i] = nullptr;
}
}
} else {
int i;
video_config.glsl_filter = 0;
video_config.glsl_shader_mamebm_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
video_config.glsl_shader_mamebm[i] = nullptr;
}
video_config.glsl_shader_scrn_num=0;
for(i=0; i<GLSL_SHADER_MAX; i++)
{
video_config.glsl_shader_scrn[i] = nullptr;
}
}
#endif /* USE_OPENGL */
}

View File

@ -31,14 +31,6 @@
#include "modules/monitor/monitor_common.h"
#include "modules/render/drawbgfx.h"
#include "modules/render/drawnone.h"
#include "modules/render/drawd3d.h"
#include "modules/render/drawgdi.h"
#if (USE_OPENGL)
#include "modules/render/drawogl.h"
#endif
#define NOT_ALREADY_DOWN(x) (x & 0x40000000) == 0
#define SCAN_CODE(x) ((x >> 16) & 0xff)
#define IS_EXTENDED(x) (0x01000000 & x)
@ -128,73 +120,12 @@ bool windows_osd_interface::window_init()
window_thread = GetCurrentThread();
window_threadid = main_threadid;
// initialize the renderer
const int fallbacks[VIDEO_MODE_COUNT] = {
-1, // NONE -> no fallback
VIDEO_MODE_NONE, // GDI -> NONE
VIDEO_MODE_D3D, // BGFX -> D3D
#if (USE_OPENGL)
-1, // OPENGL -> no fallback
#endif
-1, // No SDL2ACCEL on Windows OSD
#if (USE_OPENGL)
VIDEO_MODE_OPENGL, // D3D -> OPENGL
#else
VIDEO_MODE_GDI, // D3D -> GDI
#endif
-1 // No SOFT on Windows OSD
};
int current_mode = video_config.mode;
while (current_mode != VIDEO_MODE_NONE)
{
bool error = false;
switch(current_mode)
{
case VIDEO_MODE_NONE:
error = renderer_none::init(machine());
break;
case VIDEO_MODE_GDI:
error = renderer_gdi::init(machine());
break;
case VIDEO_MODE_BGFX:
error = renderer_bgfx::init(machine());
break;
#if (USE_OPENGL)
case VIDEO_MODE_OPENGL:
renderer_ogl::init(machine());
break;
#endif
case VIDEO_MODE_SDL2ACCEL:
fatalerror("SDL2-Accel renderer unavailable on Windows OSD.");
break;
case VIDEO_MODE_D3D:
error = renderer_d3d9::init(machine());
break;
case VIDEO_MODE_SOFT:
fatalerror("SDL1 renderer unavailable on Windows OSD.");
break;
default:
fatalerror("Unknown video mode.");
break;
}
if (error)
{
current_mode = fallbacks[current_mode];
}
else
{
break;
}
}
video_config.mode = current_mode;
return true;
}
void windows_osd_interface::update_slider_list()
{
for (const auto &window : osd_common_t::s_window_list)
for (const auto &window : osd_common_t::window_list())
{
// check if any window has dirty sliders
if (window->has_renderer() && window->renderer().sliders_dirty())
@ -207,14 +138,14 @@ void windows_osd_interface::update_slider_list()
int windows_osd_interface::window_count()
{
return osd_common_t::s_window_list.size();
return osd_common_t::window_list().size();
}
void windows_osd_interface::build_slider_list()
{
m_sliders.clear();
for (const auto &window : osd_common_t::s_window_list)
for (const auto &window : osd_common_t::window_list())
{
if (window->has_renderer())
{
@ -227,11 +158,9 @@ void windows_osd_interface::build_slider_list()
void windows_osd_interface::add_audio_to_recording(const int16_t *buffer, int samples_this_frame)
{
auto window = osd_common_t::s_window_list.front(); // We only record on the first window
if (window != nullptr)
{
auto const &window = osd_common_t::window_list().front(); // We only record on the first window
if (window)
window->renderer().add_audio_to_recording(buffer, samples_this_frame);
}
}
//============================================================
@ -250,35 +179,11 @@ void windows_osd_interface::window_exit()
// free all the windows
while (!osd_common_t::s_window_list.empty())
{
auto window = osd_common_t::s_window_list.front();
// Destroy removes it from the list also
auto window = std::move(osd_common_t::s_window_list.back());
s_window_list.pop_back();
window->destroy();
}
switch(video_config.mode)
{
case VIDEO_MODE_NONE:
renderer_none::exit();
break;
case VIDEO_MODE_GDI:
renderer_gdi::exit();
break;
case VIDEO_MODE_BGFX:
renderer_bgfx::exit();
break;
#if (USE_OPENGL)
case VIDEO_MODE_OPENGL:
renderer_ogl::exit();
break;
#endif
case VIDEO_MODE_D3D:
renderer_d3d9::exit();
break;
default:
break;
}
// kill the UI pause event
if (ui_pause_event)
CloseHandle(ui_pause_event);
@ -287,10 +192,11 @@ void windows_osd_interface::window_exit()
win_window_info::win_window_info(
running_machine &machine,
render_module &renderprovider,
int index,
std::shared_ptr<osd_monitor_info> monitor,
const std::shared_ptr<osd_monitor_info> &monitor,
const osd_window_config *config)
: osd_window_t(machine, index, std::move(monitor), *config)
: osd_window_t(machine, renderprovider, index, std::move(monitor), *config)
, m_init_state(0)
, m_startmaximized(0)
, m_isminimized(0)
@ -306,6 +212,7 @@ win_window_info::win_window_info(
, m_lastclickx(0)
, m_lastclicky(0)
, m_last_surrogate(0)
, m_main(nullptr)
, m_attached_mode(false)
{
m_non_fullscreen_bounds.left = 0;
@ -396,8 +303,8 @@ static LRESULT CALLBACK winwindow_video_window_proc_ui(HWND wnd, UINT message, W
static bool is_mame_window(HWND hwnd)
{
for (const auto &window : osd_common_t::s_window_list)
if (std::static_pointer_cast<win_window_info>(window)->platform_window() == hwnd)
for (const auto &window : osd_common_t::window_list())
if (dynamic_cast<win_window_info &>(*window).platform_window() == hwnd)
return true;
return false;
@ -560,10 +467,8 @@ void winwindow_take_snap()
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
for (const auto &window : osd_common_t::s_window_list)
{
for (const auto &window : osd_common_t::window_list())
window->renderer().save();
}
}
@ -578,10 +483,8 @@ void winwindow_toggle_fsfx()
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
for (const auto &window : osd_common_t::s_window_list)
{
for (const auto &window : osd_common_t::window_list())
window->renderer().toggle_fsfx();
}
}
@ -596,10 +499,8 @@ void winwindow_take_video()
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
for (const auto &window : osd_common_t::s_window_list)
{
for (const auto &window : osd_common_t::window_list())
window->renderer().record();
}
}
@ -614,19 +515,27 @@ void winwindow_toggle_full_screen()
assert(GetCurrentThreadId() == main_threadid);
// if we are in debug mode, never go full screen
for (const auto &window : osd_common_t::s_window_list)
for (const auto &window : osd_common_t::window_list())
{
if (window->machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)
return;
}
// toggle the window mode
video_config.windowed = !video_config.windowed;
// iterate over windows and toggle their fullscreen state
for (const auto &window : osd_common_t::s_window_list)
SendMessage(std::static_pointer_cast<win_window_info>(window)->platform_window(), WM_USER_SET_FULLSCREEN, !video_config.windowed, 0);
for (const auto &window : osd_common_t::window_list())
{
SendMessage(
dynamic_cast<win_window_info &>(*window).platform_window(),
WM_USER_SET_FULLSCREEN,
!video_config.windowed,
0);
}
// Set the first window as foreground
SetForegroundWindow(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window());
SetForegroundWindow(dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window());
}
@ -639,9 +548,9 @@ void winwindow_toggle_full_screen()
bool winwindow_has_focus()
{
// see if one of the video windows has focus
for (const auto &window : osd_common_t::s_window_list)
for (const auto &window : osd_common_t::window_list())
{
switch (std::static_pointer_cast<win_window_info>(window)->focus())
switch (dynamic_cast<win_window_info &>(*window).focus())
{
case win_window_focus::NONE:
break;
@ -682,10 +591,10 @@ void winwindow_update_cursor_state(running_machine &machine)
assert(GetCurrentThreadId() == main_threadid);
// If no windows, just return
if (osd_common_t::s_window_list.empty())
if (osd_common_t::window_list().empty())
return;
auto &window = static_cast<win_window_info &>(*osd_common_t::s_window_list.front());
auto &window = static_cast<win_window_info &>(*osd_common_t::window_list().front());
// if we should hide the mouse cursor, then do it
// rules are:
@ -720,21 +629,26 @@ void winwindow_update_cursor_state(running_machine &machine)
// (main thread)
//============================================================
void win_window_info::create(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config *config)
std::unique_ptr<win_window_info> win_window_info::create(
running_machine &machine,
render_module &renderprovider,
int index,
const std::shared_ptr<osd_monitor_info> &monitor,
const osd_window_config *config)
{
assert(GetCurrentThreadId() == main_threadid);
// allocate a new window object
auto window = std::make_shared<win_window_info>(machine, index, monitor, config);
auto window = std::make_unique<win_window_info>(machine, renderprovider, index, monitor, config);
// set main window
if (window->index() > 0)
{
for (const auto &w : osd_common_t::s_window_list)
for (const auto &w : osd_common_t::window_list())
{
if (w->index() == 0)
{
window->set_main_window(std::static_pointer_cast<osd_window>(w));
window->set_main_window(dynamic_cast<win_window_info &>(*w));
break;
}
}
@ -742,12 +656,12 @@ void win_window_info::create(running_machine &machine, int index, std::shared_pt
else
{
// We must be the main window
window->set_main_window(window);
window->set_main_window(*window);
}
// see if we are safe for fullscreen
window->m_fullscreen_safe = TRUE;
for (const auto &win : osd_common_t::s_window_list)
for (const auto &win : osd_common_t::window_list())
if (win->monitor() == monitor.get())
window->m_fullscreen_safe = FALSE;
@ -767,6 +681,8 @@ void win_window_info::create(running_machine &machine, int index, std::shared_pt
// handle error conditions
if (window->m_init_state == -1)
fatalerror("Unable to complete window creation\n");
return window;
}
//============================================================
@ -1016,16 +932,16 @@ int win_window_info::complete_create()
{
// create the window, but don't show it yet
hwnd = win_create_window_ex_utf8(
fullscreen() ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX,
"MAME",
title().c_str(),
fullscreen() ? FULLSCREEN_STYLE : WINDOW_STYLE,
monitorbounds.left() + 20, monitorbounds.top() + 20,
monitorbounds.left() + 100, monitorbounds.top() + 100,
nullptr,//(osd_common_t::s_window_list != nullptr) ? osd_common_t::s_window_list->m_hwnd : nullptr,
nullptr,
GetModuleHandleUni(),
nullptr);
fullscreen() ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX,
"MAME",
title().c_str(),
fullscreen() ? FULLSCREEN_STYLE : WINDOW_STYLE,
monitorbounds.left() + 20, monitorbounds.top() + 20,
monitorbounds.left() + 100, monitorbounds.top() + 100,
nullptr,//(osd_common_t::s_window_list != nullptr) ? osd_common_t::s_window_list->m_hwnd : nullptr,
nullptr,
GetModuleHandleUni(),
nullptr);
}
if (hwnd == nullptr)
@ -1038,9 +954,9 @@ int win_window_info::complete_create()
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
// skip the positioning stuff for '-video none' or '-attach_window'
if (video_config.mode == VIDEO_MODE_NONE || attached_mode())
if (!renderer_interactive() || attached_mode())
{
set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
renderer_create();
if (renderer().create())
return 1;
return 0;
@ -1064,7 +980,7 @@ int win_window_info::complete_create()
// show the window
if (!fullscreen() || m_fullscreen_safe)
{
set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
renderer_create();
if (renderer().create())
return 1;
@ -1301,13 +1217,13 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
{
if ((wparam == WA_ACTIVE) || (wparam == WA_CLICKACTIVE))
{
for (const auto &w : osd_common_t::s_window_list)
ShowWindow(std::static_pointer_cast<win_window_info>(w)->platform_window(), SW_RESTORE);
for (const auto &w : osd_common_t::window_list())
ShowWindow(dynamic_cast<win_window_info &>(*w).platform_window(), SW_RESTORE);
}
else if ((wparam == WA_INACTIVE) && !is_mame_window(HWND(lparam)))
{
for (const auto &w : osd_common_t::s_window_list)
ShowWindow(std::static_pointer_cast<win_window_info>(w)->platform_window(), SW_MINIMIZE);
for (const auto &w : osd_common_t::window_list())
ShowWindow(dynamic_cast<win_window_info &>(*w).platform_window(), SW_MINIMIZE);
}
}
@ -1809,17 +1725,19 @@ void win_window_info::set_fullscreen(int fullscreen)
// reset UI to main menu
// FIXME: this cause crash if called when running_machine.m_ui not yet initialised. e.g. when trying to show error/warning messagebox at startup (during auto-switch from full screen to windowed mode).
// the menus need to be able to survive a fullscreen toggle anyway
machine().ui().menu_reset();
// kill off the drawers
// kill off the renderer
renderer_reset();
// hide ourself
ShowWindow(platform_window(), SW_HIDE);
// configure the window if non-fullscreen
if (!fullscreen)
{
// configure the window if non-fullscreen
// adjust the style
SetWindowLong(platform_window(), GWL_STYLE, WINDOW_STYLE);
SetWindowLong(platform_window(), GWL_EXSTYLE, WINDOW_STYLE_EX);
@ -1844,10 +1762,10 @@ void win_window_info::set_fullscreen(int fullscreen)
maximize_window();
}
}
// configure the window if fullscreen
else
{
// configure the window if fullscreen
// save the bounds
GetWindowRect(platform_window(), &m_non_fullscreen_bounds);
@ -1866,12 +1784,12 @@ void win_window_info::set_fullscreen(int fullscreen)
// show ourself
if (!this->fullscreen() || m_fullscreen_safe)
{
if (video_config.mode != VIDEO_MODE_NONE)
if (renderer_interactive())
ShowWindow(platform_window(), SW_SHOW);
set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
renderer_create();
if (renderer().create())
exit(1);
exit(1); // FIXME: better error handling than just silently exiting on failure
}
// ensure we're still adjusted correctly
@ -1930,7 +1848,7 @@ bool winwindow_qt_filter(void *message)
if(msg->hwnd) // get the machine associated with this window
ptr = GetWindowLongPtr(msg->hwnd, GWLP_USERDATA);
else // any one will have to do
ptr = (LONG_PTR)osd_common_t::s_window_list.front().get();
ptr = (LONG_PTR)osd_common_t::window_list().front().get();
winwindow_dispatch_message(((win_window_info *)ptr)->machine(), msg);
return true;

View File

@ -54,7 +54,7 @@ enum class win_window_focus
class win_window_info : public osd_window_t<HWND>
{
public:
win_window_info(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config *config);
win_window_info(running_machine &machine, render_module &renderprovider, int index, const std::shared_ptr<osd_monitor_info> &monitor, const osd_window_config *config);
bool attached_mode() const { return m_attached_mode; }
win_window_focus focus() const;
@ -68,6 +68,9 @@ public:
return osd_dim(client.right - client.left, client.bottom - client.top);
}
win_window_info *main_window() const { return m_main; }
void set_main_window(win_window_info &main) { m_main = &main; }
void capture_pointer() override;
void release_pointer() override;
void show_pointer() override;
@ -77,7 +80,12 @@ public:
// static
static void create(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config *config);
static std::unique_ptr<win_window_info> create(
running_machine &machine,
render_module &renderprovider,
int index,
const std::shared_ptr<osd_monitor_info> &monitor,
const osd_window_config *config);
// static callbacks
@ -126,15 +134,10 @@ private:
void adjust_window_position_after_major_change();
void set_fullscreen(int fullscreen);
static POINT s_saved_cursor_pos;
win_window_info * m_main;
bool m_attached_mode;
};
struct osd_draw_callbacks
{
osd_renderer *(*create)(osd_window *window);
void (*exit)(void);
static POINT s_saved_cursor_pos;
};

View File

@ -89,7 +89,7 @@ public:
if (channel == OSD_OUTPUT_CHANNEL_ERROR)
{
// if we are in fullscreen mode, go to windowed mode
if ((video_config.windowed == 0) && !osd_common_t::s_window_list.empty())
if ((video_config.windowed == 0) && !osd_common_t::window_list().empty())
winwindow_toggle_full_screen();
auto &state(get_state());
@ -283,21 +283,6 @@ windows_osd_interface::~windows_osd_interface()
}
//============================================================
// video_register
//============================================================
void windows_osd_interface::video_register()
{
video_options_add("gdi", nullptr);
video_options_add("d3d", nullptr);
#if USE_OPENGL
video_options_add("opengl", nullptr);
#endif
video_options_add("bgfx", nullptr);
//video_options_add("auto", nullptr); // making d3d video default one
}
//============================================================
// init
//============================================================
@ -352,9 +337,9 @@ void windows_osd_interface::init(running_machine &machine)
osd_common_t::init_subsystems();
// notify listeners of screen configuration
for (const auto &info : osd_common_t::s_window_list)
for (const auto &info : osd_common_t::window_list())
{
machine.output().set_value(string_format("Orientation(%s)", info->monitor()->devicename()), std::static_pointer_cast<win_window_info>(info)->m_targetorient);
machine.output().set_value(string_format("Orientation(%s)", info->monitor()->devicename()), dynamic_cast<win_window_info &>(*info).m_targetorient);
}
// hook up the debugger log

View File

@ -67,8 +67,6 @@ public:
// video overridables
virtual void add_audio_to_recording(const int16_t *buffer, int samples_this_frame) override;
virtual void video_register() override;
virtual bool video_init() override;
virtual bool window_init() override;