mirror of
https://github.com/holub/mame
synced 2025-06-03 11:26:56 +03:00
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:
parent
12e5fa3906
commit
2810c9d91b
@ -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",
|
||||
|
@ -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"])
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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(®istration, 1, sizeof(registration));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
@ -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
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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
@ -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
|
@ -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)
|
||||
|
@ -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
|
38
src/osd/modules/render/render_module.h
Normal file
38
src/osd/modules/render/render_module.h
Normal 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
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user