diff options
128 files changed, 3431 insertions, 2320 deletions
diff --git a/.gitignore b/.gitignore index f942210406a..f27ad311907 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ !/3rdparty/ !/benchmarks/ !/artwork/ +!/bgfx/ !/docs/ !/hash/ !/hlsl/ diff --git a/bgfx/effects/gui_add.json b/bgfx/effects/gui_add.json new file mode 100644 index 00000000000..d8672a0f026 --- /dev/null +++ b/bgfx/effects/gui_add.json @@ -0,0 +1,22 @@ +{ + "blend": { + "equation": "add", + "srcColor": "srcAlpha", + "dstColor": "1", + "srcAlpha": "srcAlpha", + "dstAlpha": "1" + }, + "depth": { + "function": "always" + }, + "cull": { "mode": "none" }, + "write": { + "rgb": "true", + "alpha": "true" + }, + "vertex": "vs_gui", + "fragment": "fs_gui", + "uniforms": [ + { "name": "s_tex", "type": "int", "values": [ 1.0 ] } + ] +}
\ No newline at end of file diff --git a/bgfx/effects/gui_blend.json b/bgfx/effects/gui_blend.json new file mode 100644 index 00000000000..d8cfda51672 --- /dev/null +++ b/bgfx/effects/gui_blend.json @@ -0,0 +1,22 @@ +{ + "blend": { + "equation": "add", + "srcColor": "srcAlpha", + "dstColor": "1-srcAlpha", + "srcAlpha": "srcAlpha", + "dstAlpha": "1-srcAlpha" + }, + "depth": { + "function": "always" + }, + "cull": { "mode": "none" }, + "write": { + "rgb": "true", + "alpha": "true" + }, + "vertex": "vs_gui", + "fragment": "fs_gui", + "uniforms": [ + { "name": "s_tex", "type": "int", "values": [ 1.0 ] } + ] +}
\ No newline at end of file diff --git a/bgfx/effects/gui_multiply.json b/bgfx/effects/gui_multiply.json new file mode 100644 index 00000000000..fa70d303aec --- /dev/null +++ b/bgfx/effects/gui_multiply.json @@ -0,0 +1,22 @@ +{ + "blend": { + "equation": "add", + "srcColor": "dstColor", + "dstColor": "0", + "srcAlpha": "dstAlpha", + "dstAlpha": "0" + }, + "depth": { + "function": "always" + }, + "cull": { "mode": "none" }, + "write": { + "rgb": "true", + "alpha": "true" + }, + "vertex": "vs_gui", + "fragment": "fs_gui", + "uniforms": [ + { "name": "s_tex", "type": "int", "values": [ 1.0 ] } + ] +}
\ No newline at end of file diff --git a/bgfx/effects/gui_opaque.json b/bgfx/effects/gui_opaque.json new file mode 100644 index 00000000000..58d1a324d2d --- /dev/null +++ b/bgfx/effects/gui_opaque.json @@ -0,0 +1,22 @@ +{ + "blend": { + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" + }, + "depth": { + "function": "always" + }, + "cull": { "mode": "none" }, + "write": { + "rgb": "true", + "alpha": "true" + }, + "vertex": "vs_gui", + "fragment": "fs_gui", + "uniforms": [ + { "name": "s_tex", "type": "int", "values": [ 1.0 ] } + ] +}
\ No newline at end of file diff --git a/bgfx/effects/screen_add.json b/bgfx/effects/screen_add.json new file mode 100644 index 00000000000..43d110fc2d1 --- /dev/null +++ b/bgfx/effects/screen_add.json @@ -0,0 +1,23 @@ +{ + "blend": { + "equation": "add", + "srcColor": "srcAlpha", + "dstColor": "1", + "srcAlpha": "srcAlpha", + "dstAlpha": "1" + }, + "depth": { + "function": "always" + }, + "cull": { "mode": "none" }, + "write": { + "rgb": "true", + "alpha": "true" + }, + "vertex": "vs_screen", + "fragment": "fs_screen", + "uniforms": [ + { "name": "s_tex", "type": "int", "values": [ 1.0 ] }, + { "name": "u_tint", "type": "vec4", "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] +}
\ No newline at end of file diff --git a/bgfx/effects/screen_blend.json b/bgfx/effects/screen_blend.json new file mode 100644 index 00000000000..37da6abf24f --- /dev/null +++ b/bgfx/effects/screen_blend.json @@ -0,0 +1,23 @@ +{ + "blend": { + "equation": "add", + "srcColor": "srcAlpha", + "dstColor": "1-srcAlpha", + "srcAlpha": "srcAlpha", + "dstAlpha": "1-srcAlpha" + }, + "depth": { + "function": "always" + }, + "cull": { "mode": "none" }, + "write": { + "rgb": "true", + "alpha": "true" + }, + "vertex": "vs_screen", + "fragment": "fs_screen", + "uniforms": [ + { "name": "s_tex", "type": "int", "values": [ 1.0 ] }, + { "name": "u_tint", "type": "vec4", "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] +}
\ No newline at end of file diff --git a/bgfx/effects/screen_multiply.json b/bgfx/effects/screen_multiply.json new file mode 100644 index 00000000000..cd37b997954 --- /dev/null +++ b/bgfx/effects/screen_multiply.json @@ -0,0 +1,23 @@ +{ + "blend": { + "equation": "add", + "srcColor": "dstColor", + "dstColor": "0", + "srcAlpha": "dstAlpha", + "dstAlpha": "0" + }, + "depth": { + "function": "always" + }, + "cull": { "mode": "none" }, + "write": { + "rgb": "true", + "alpha": "true" + }, + "vertex": "vs_screen", + "fragment": "fs_screen", + "uniforms": [ + { "name": "s_tex", "type": "int", "values": [ 1.0 ] }, + { "name": "u_tint", "type": "vec4", "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] +}
\ No newline at end of file diff --git a/bgfx/effects/screen_opaque.json b/bgfx/effects/screen_opaque.json new file mode 100644 index 00000000000..e3ac55387c3 --- /dev/null +++ b/bgfx/effects/screen_opaque.json @@ -0,0 +1,23 @@ +{ + "blend": { + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" + }, + "depth": { + "function": "always" + }, + "cull": { "mode": "none" }, + "write": { + "rgb": "true", + "alpha": "true" + }, + "vertex": "vs_screen", + "fragment": "fs_screen", + "uniforms": [ + { "name": "s_tex", "type": "int", "values": [ 1.0 ] }, + { "name": "u_tint", "type": "vec4", "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] +}
\ No newline at end of file diff --git a/scripts/src/osd/modules.lua b/scripts/src/osd/modules.lua index ea70ca132de..3e18ee72050 100644 --- a/scripts/src/osd/modules.lua +++ b/scripts/src/osd/modules.lua @@ -103,6 +103,23 @@ function osdmodulesbuild() files { MAME_DIR .. "src/osd/modules/render/drawbgfx.cpp", MAME_DIR .. "src/osd/modules/render/binpacker.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/blendreader.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/cullreader.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/depthreader.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/effect.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/effectmanager.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/effectreader.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/pass.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/passreader.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/shadermanager.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/statereader.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/target.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/targetmanager.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/texture.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/texturemanager.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/uniform.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/uniformreader.cpp", + MAME_DIR .. "src/osd/modules/render/bgfx/writereader.cpp", } includedirs { MAME_DIR .. "3rdparty/bgfx/include", diff --git a/scripts/src/osd/sdl.lua b/scripts/src/osd/sdl.lua index b89a25814ad..cb5bd6debdc 100644 --- a/scripts/src/osd/sdl.lua +++ b/scripts/src/osd/sdl.lua @@ -384,6 +384,7 @@ project ("osd_" .. _OPTIONS["osd"]) MAME_DIR .. "src/osd/sdl/video.h", MAME_DIR .. "src/osd/sdl/window.cpp", MAME_DIR .. "src/osd/sdl/window.h", + MAME_DIR .. "src/osd/modules/osdwindow.cpp", MAME_DIR .. "src/osd/modules/osdwindow.h", MAME_DIR .. "src/osd/sdl/output.cpp", MAME_DIR .. "src/osd/sdl/watchdog.cpp", diff --git a/scripts/src/osd/windows.lua b/scripts/src/osd/windows.lua index 54464477e24..154d4732bc1 100644 --- a/scripts/src/osd/windows.lua +++ b/scripts/src/osd/windows.lua @@ -152,15 +152,17 @@ project ("osd_" .. _OPTIONS["osd"]) } files { - MAME_DIR .. "src/osd/modules/render/drawd3d.cpp", - MAME_DIR .. "src/osd/modules/render/drawd3d.h", MAME_DIR .. "src/osd/modules/render/d3d/d3d9intf.cpp", + MAME_DIR .. "src/osd/modules/render/d3d/d3dintf.h", MAME_DIR .. "src/osd/modules/render/d3d/d3dhlsl.cpp", MAME_DIR .. "src/osd/modules/render/d3d/d3dcomm.h", MAME_DIR .. "src/osd/modules/render/d3d/d3dhlsl.h", - MAME_DIR .. "src/osd/modules/render/d3d/d3dintf.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/input.cpp", MAME_DIR .. "src/osd/windows/input.h", MAME_DIR .. "src/osd/windows/output.cpp", @@ -169,6 +171,7 @@ project ("osd_" .. _OPTIONS["osd"]) MAME_DIR .. "src/osd/windows/video.h", MAME_DIR .. "src/osd/windows/window.cpp", MAME_DIR .. "src/osd/windows/window.h", + MAME_DIR .. "src/osd/modules/osdwindow.cpp", MAME_DIR .. "src/osd/modules/osdwindow.h", MAME_DIR .. "src/osd/windows/winmenu.cpp", MAME_DIR .. "src/osd/windows/winmain.cpp", diff --git a/shaders/dx11/fs_quad_texture.bin b/shaders/dx11/fs_gui.bin Binary files differindex 80d85fb1107..80d85fb1107 100644 --- a/shaders/dx11/fs_quad_texture.bin +++ b/shaders/dx11/fs_gui.bin diff --git a/shaders/dx11/fs_line.bin b/shaders/dx11/fs_line.bin Binary files differdeleted file mode 100644 index 5bd281a0889..00000000000 --- a/shaders/dx11/fs_line.bin +++ /dev/null diff --git a/shaders/dx11/fs_quad.bin b/shaders/dx11/fs_quad.bin Binary files differdeleted file mode 100644 index 5bd281a0889..00000000000 --- a/shaders/dx11/fs_quad.bin +++ /dev/null diff --git a/shaders/dx11/fs_screen.bin b/shaders/dx11/fs_screen.bin Binary files differnew file mode 100644 index 00000000000..802d22a89ff --- /dev/null +++ b/shaders/dx11/fs_screen.bin diff --git a/shaders/dx11/vs_quad_texture.bin b/shaders/dx11/vs_gui.bin Binary files differindex b0bebf9da4c..b0bebf9da4c 100644 --- a/shaders/dx11/vs_quad_texture.bin +++ b/shaders/dx11/vs_gui.bin diff --git a/shaders/dx11/vs_line.bin b/shaders/dx11/vs_line.bin Binary files differdeleted file mode 100644 index 24d50eb25ac..00000000000 --- a/shaders/dx11/vs_line.bin +++ /dev/null diff --git a/shaders/dx11/vs_quad.bin b/shaders/dx11/vs_quad.bin Binary files differdeleted file mode 100644 index 24d50eb25ac..00000000000 --- a/shaders/dx11/vs_quad.bin +++ /dev/null diff --git a/shaders/dx11/vs_screen.bin b/shaders/dx11/vs_screen.bin Binary files differnew file mode 100644 index 00000000000..b0bebf9da4c --- /dev/null +++ b/shaders/dx11/vs_screen.bin diff --git a/shaders/dx9/fs_quad_texture.bin b/shaders/dx9/fs_gui.bin Binary files differindex ef8fa0730c3..ee2b018cae8 100644 --- a/shaders/dx9/fs_quad_texture.bin +++ b/shaders/dx9/fs_gui.bin diff --git a/shaders/dx9/fs_line.bin b/shaders/dx9/fs_line.bin Binary files differdeleted file mode 100644 index 5bfd5497f0b..00000000000 --- a/shaders/dx9/fs_line.bin +++ /dev/null diff --git a/shaders/dx9/fs_quad.bin b/shaders/dx9/fs_quad.bin Binary files differdeleted file mode 100644 index 5bfd5497f0b..00000000000 --- a/shaders/dx9/fs_quad.bin +++ /dev/null diff --git a/shaders/dx9/fs_screen.bin b/shaders/dx9/fs_screen.bin Binary files differnew file mode 100644 index 00000000000..cd32f845f00 --- /dev/null +++ b/shaders/dx9/fs_screen.bin diff --git a/shaders/dx9/vs_quad_texture.bin b/shaders/dx9/vs_gui.bin Binary files differindex ea94c83e62d..c071222605b 100644 --- a/shaders/dx9/vs_quad_texture.bin +++ b/shaders/dx9/vs_gui.bin diff --git a/shaders/dx9/vs_line.bin b/shaders/dx9/vs_line.bin Binary files differdeleted file mode 100644 index 9bd4a9797e0..00000000000 --- a/shaders/dx9/vs_line.bin +++ /dev/null diff --git a/shaders/dx9/vs_quad.bin b/shaders/dx9/vs_quad.bin Binary files differdeleted file mode 100644 index 9bd4a9797e0..00000000000 --- a/shaders/dx9/vs_quad.bin +++ /dev/null diff --git a/shaders/dx9/vs_screen.bin b/shaders/dx9/vs_screen.bin Binary files differnew file mode 100644 index 00000000000..c071222605b --- /dev/null +++ b/shaders/dx9/vs_screen.bin diff --git a/shaders/gles/fs_quad_texture.bin b/shaders/gles/fs_gui.bin Binary files differindex 22e2f0c23d0..22e2f0c23d0 100644 --- a/shaders/gles/fs_quad_texture.bin +++ b/shaders/gles/fs_gui.bin diff --git a/shaders/gles/fs_line.bin b/shaders/gles/fs_line.bin Binary files differdeleted file mode 100644 index de509a3eeb5..00000000000 --- a/shaders/gles/fs_line.bin +++ /dev/null diff --git a/shaders/gles/fs_quad.bin b/shaders/gles/fs_quad.bin Binary files differdeleted file mode 100644 index de509a3eeb5..00000000000 --- a/shaders/gles/fs_quad.bin +++ /dev/null diff --git a/shaders/gles/fs_screen.bin b/shaders/gles/fs_screen.bin Binary files differnew file mode 100644 index 00000000000..e61cd98570a --- /dev/null +++ b/shaders/gles/fs_screen.bin diff --git a/shaders/gles/vs_quad_texture.bin b/shaders/gles/vs_gui.bin Binary files differindex 9dd618de8a0..9dd618de8a0 100644 --- a/shaders/gles/vs_quad_texture.bin +++ b/shaders/gles/vs_gui.bin diff --git a/shaders/gles/vs_line.bin b/shaders/gles/vs_line.bin Binary files differdeleted file mode 100644 index db0ff91e152..00000000000 --- a/shaders/gles/vs_line.bin +++ /dev/null diff --git a/shaders/gles/vs_quad.bin b/shaders/gles/vs_screen.bin Binary files differindex db0ff91e152..9dd618de8a0 100644 --- a/shaders/gles/vs_quad.bin +++ b/shaders/gles/vs_screen.bin diff --git a/shaders/glsl/fs_quad_texture.bin b/shaders/glsl/fs_gui.bin Binary files differindex db0fe2b487b..db0fe2b487b 100644 --- a/shaders/glsl/fs_quad_texture.bin +++ b/shaders/glsl/fs_gui.bin diff --git a/shaders/glsl/fs_line.bin b/shaders/glsl/fs_line.bin Binary files differdeleted file mode 100644 index 6f8e3df8290..00000000000 --- a/shaders/glsl/fs_line.bin +++ /dev/null diff --git a/shaders/glsl/fs_quad.bin b/shaders/glsl/fs_quad.bin Binary files differdeleted file mode 100644 index 6f8e3df8290..00000000000 --- a/shaders/glsl/fs_quad.bin +++ /dev/null diff --git a/shaders/glsl/fs_screen.bin b/shaders/glsl/fs_screen.bin Binary files differnew file mode 100644 index 00000000000..2dd75acfc5e --- /dev/null +++ b/shaders/glsl/fs_screen.bin diff --git a/shaders/glsl/vs_quad_texture.bin b/shaders/glsl/vs_gui.bin Binary files differindex af6c9349f41..af6c9349f41 100644 --- a/shaders/glsl/vs_quad_texture.bin +++ b/shaders/glsl/vs_gui.bin diff --git a/shaders/glsl/vs_quad.bin b/shaders/glsl/vs_quad.bin Binary files differdeleted file mode 100644 index 7c8490550c7..00000000000 --- a/shaders/glsl/vs_quad.bin +++ /dev/null diff --git a/shaders/glsl/vs_line.bin b/shaders/glsl/vs_screen.bin Binary files differindex 7c8490550c7..af6c9349f41 100644 --- a/shaders/glsl/vs_line.bin +++ b/shaders/glsl/vs_screen.bin diff --git a/shaders/metal/fs_quad_texture.bin b/shaders/metal/fs_gui.bin Binary files differindex 6a3da392480..6a3da392480 100644 --- a/shaders/metal/fs_quad_texture.bin +++ b/shaders/metal/fs_gui.bin diff --git a/shaders/metal/fs_line.bin b/shaders/metal/fs_line.bin Binary files differdeleted file mode 100644 index fb726f353c0..00000000000 --- a/shaders/metal/fs_line.bin +++ /dev/null diff --git a/shaders/metal/fs_quad.bin b/shaders/metal/fs_quad.bin Binary files differdeleted file mode 100644 index fb726f353c0..00000000000 --- a/shaders/metal/fs_quad.bin +++ /dev/null diff --git a/shaders/metal/fs_screen.bin b/shaders/metal/fs_screen.bin Binary files differnew file mode 100644 index 00000000000..c0c34d2553f --- /dev/null +++ b/shaders/metal/fs_screen.bin diff --git a/shaders/metal/vs_quad_texture.bin b/shaders/metal/vs_gui.bin Binary files differindex 122b7dee5c3..122b7dee5c3 100644 --- a/shaders/metal/vs_quad_texture.bin +++ b/shaders/metal/vs_gui.bin diff --git a/shaders/metal/vs_quad.bin b/shaders/metal/vs_quad.bin Binary files differdeleted file mode 100644 index d2eeed80dfd..00000000000 --- a/shaders/metal/vs_quad.bin +++ /dev/null diff --git a/shaders/metal/vs_line.bin b/shaders/metal/vs_screen.bin Binary files differindex d2eeed80dfd..122b7dee5c3 100644 --- a/shaders/metal/vs_line.bin +++ b/shaders/metal/vs_screen.bin diff --git a/src/emu/ui/sliders.cpp b/src/emu/ui/sliders.cpp index e494213aa1b..d53ad402943 100644 --- a/src/emu/ui/sliders.cpp +++ b/src/emu/ui/sliders.cpp @@ -17,9 +17,9 @@ #include "ui/sliders.h" -ui_menu_sliders::ui_menu_sliders(running_machine &machine, render_container *container, bool _menuless_mode) : ui_menu(machine, container) +ui_menu_sliders::ui_menu_sliders(running_machine &machine, render_container *container, bool menuless_mode) : ui_menu(machine, container) { - menuless_mode = hidden = _menuless_mode; + m_menuless_mode = m_hidden = menuless_mode; } ui_menu_sliders::~ui_menu_sliders() @@ -35,7 +35,7 @@ void ui_menu_sliders::handle() const ui_menu_event *menu_event; /* process the menu */ - menu_event = process(UI_MENU_PROCESS_LR_REPEAT | (hidden ? UI_MENU_PROCESS_CUSTOM_ONLY : 0)); + menu_event = process(UI_MENU_PROCESS_LR_REPEAT | (m_hidden ? UI_MENU_PROCESS_CUSTOM_ONLY : 0)); if (menu_event != nullptr) { /* handle keys if there is a valid item selected */ @@ -49,10 +49,10 @@ void ui_menu_sliders::handle() { /* toggle visibility */ case IPT_UI_ON_SCREEN_DISPLAY: - if (menuless_mode) + if (m_menuless_mode) ui_menu::stack_pop(machine()); else - hidden = !hidden; + m_hidden = !m_hidden; break; /* decrease value */ @@ -103,19 +103,25 @@ void ui_menu_sliders::handle() } /* if we are selecting an invalid item and we are hidden, skip to the next one */ - else if (hidden) + else if (m_hidden) { /* if we got here via up or page up, select the previous item */ if (menu_event->iptkey == IPT_UI_UP || menu_event->iptkey == IPT_UI_PAGE_UP) { - selected = (selected + item.size() - 1) % item.size(); + do + { + selected = (selected + item.size() - 1) % item.size(); + } while(((slider_state&)item[selected]).hidden); validate_selection(-1); } /* otherwise select the next item */ else if (menu_event->iptkey == IPT_UI_DOWN || menu_event->iptkey == IPT_UI_PAGE_DOWN) { - selected = (selected + 1) % item.size(); + do + { + selected = (selected + 1) % item.size(); + } while(((slider_state&)item[selected]).hidden); validate_selection(1); } } @@ -252,5 +258,5 @@ UINT32 ui_menu_sliders::ui_handler(running_machine &machine, render_container *c ui_menu::stack_pop(machine); ui_menu_sliders *uim = dynamic_cast<ui_menu_sliders *>(menu_stack); - return uim && uim->menuless_mode ? 0 : UI_HANDLER_CANCEL; + return uim && uim->m_menuless_mode ? 0 : UI_HANDLER_CANCEL; } diff --git a/src/emu/ui/sliders.h b/src/emu/ui/sliders.h index d76a24c1671..c21555dc336 100644 --- a/src/emu/ui/sliders.h +++ b/src/emu/ui/sliders.h @@ -13,6 +13,8 @@ #ifndef __UI_SLIDERS_H__ #define __UI_SLIDERS_H__ +#include <map> + class ui_menu_sliders : public ui_menu { public: ui_menu_sliders(running_machine &machine, render_container *container, bool menuless_mode = false); @@ -25,7 +27,8 @@ public: static UINT32 ui_handler(running_machine &machine, render_container *container, UINT32 state); private: - bool menuless_mode, hidden; + bool m_menuless_mode; + bool m_hidden; }; diff --git a/src/emu/ui/ui.h b/src/emu/ui/ui.h index 71e21e02b64..8e0f81da9d2 100644 --- a/src/emu/ui/ui.h +++ b/src/emu/ui/ui.h @@ -103,7 +103,8 @@ struct slider_state INT32 defval; /* default value */ INT32 maxval; /* maximum value */ INT32 incval; /* increment value */ - char description[1]; /* textual description */ + bool hidden; /* hidden or not */ + char description[1]; /* textual description */ }; @@ -121,7 +122,7 @@ public: running_machine &machine() const { return m_machine; } bool single_step() const { return m_single_step; } ui_options &options() { return m_ui_options; } - + // setters void set_single_step(bool single_step) { m_single_step = single_step; } diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp index b36bbf60df3..03ec77a2c27 100644 --- a/src/osd/modules/lib/osdobj_common.cpp +++ b/src/osd/modules/lib/osdobj_common.cpp @@ -15,32 +15,32 @@ const options_entry osd_options::s_option_entries[] = { - { NULL, NULL, OPTION_HEADER, "OSD KEYBOARD MAPPING OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD KEYBOARD MAPPING OPTIONS" }, #ifdef SDLMAME_MACOSX { OSDOPTION_UIMODEKEY, "DEL", OPTION_STRING, "Key to toggle keyboard mode" }, #else { OSDOPTION_UIMODEKEY, "SCRLOCK", OPTION_STRING, "Key to toggle keyboard mode" }, #endif // SDLMAME_MACOSX - { NULL, NULL, OPTION_HEADER, "OSD FONT OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD FONT OPTIONS" }, { OSD_FONT_PROVIDER, OSDOPTVAL_AUTO, OPTION_STRING, "provider for ui font: " }, - { NULL, NULL, OPTION_HEADER, "OSD CLI OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD CLI OPTIONS" }, { OSDCOMMAND_LIST_MIDI_DEVICES ";mlist", "0", OPTION_COMMAND, "list available MIDI I/O devices" }, { OSDCOMMAND_LIST_NETWORK_ADAPTERS ";nlist", "0", OPTION_COMMAND, "list available network adapters" }, - { NULL, NULL, OPTION_HEADER, "OSD DEBUGGING OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD DEBUGGING OPTIONS" }, { OSDOPTION_DEBUGGER, OSDOPTVAL_AUTO, OPTION_STRING, "debugger used: " }, { OSDOPTION_DEBUGGER_FONT ";dfont", OSDOPTVAL_AUTO, OPTION_STRING, "specifies the font to use for debugging" }, { OSDOPTION_DEBUGGER_FONT_SIZE ";dfontsize", "0", OPTION_FLOAT, "specifies the font size to use for debugging" }, { OSDOPTION_WATCHDOG ";wdog", "0", OPTION_INTEGER, "force the program to terminate if no updates within specified number of seconds" }, - { NULL, NULL, OPTION_HEADER, "OSD PERFORMANCE OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD PERFORMANCE OPTIONS" }, { OSDOPTION_MULTITHREADING ";mt", "0", OPTION_BOOLEAN, "enable multithreading; this enables rendering and blitting on a separate thread" }, { OSDOPTION_NUMPROCESSORS ";np", OSDOPTVAL_AUTO, OPTION_STRING, "number of processors; this overrides the number the system reports" }, { OSDOPTION_BENCH, "0", OPTION_INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" }, - { NULL, NULL, OPTION_HEADER, "OSD VIDEO OPTIONS" }, + { nullptr, nullptr, OPTION_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, OPTION_STRING, "video output method: " }, { OSDOPTION_NUMSCREENS "(1-4)", "1", OPTION_INTEGER, "number of screens to create; usually, you want just one" }, @@ -52,7 +52,7 @@ const options_entry osd_options::s_option_entries[] = { OSDOPTION_SYNCREFRESH ";srf", "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" }, // per-window options - { NULL, NULL, OPTION_HEADER, "OSD PER-WINDOW VIDEO OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD PER-WINDOW VIDEO OPTIONS" }, { OSDOPTION_SCREEN, OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, { OSDOPTION_ASPECT ";screen_aspect", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, { OSDOPTION_RESOLUTION ";r", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, @@ -79,15 +79,15 @@ const options_entry osd_options::s_option_entries[] = { OSDOPTION_VIEW "3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the fourth screen" }, // full screen options - { NULL, NULL, OPTION_HEADER, "OSD FULL SCREEN OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD FULL SCREEN OPTIONS" }, { OSDOPTION_SWITCHRES, "0", OPTION_BOOLEAN, "enable resolution switching" }, - { NULL, NULL, OPTION_HEADER, "OSD ACCELERATED VIDEO OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD ACCELERATED VIDEO OPTIONS" }, { OSDOPTION_FILTER ";glfilter;flt", "1", OPTION_BOOLEAN, "enable bilinear filtering on screen output" }, { OSDOPTION_PRESCALE, "1", OPTION_INTEGER, "scale screen rendering by this amount in software" }, #if USE_OPENGL - { NULL, NULL, OPTION_HEADER, "OpenGL-SPECIFIC OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OpenGL-SPECIFIC OPTIONS" }, { OSDOPTION_GL_FORCEPOW2TEXTURE, "0", OPTION_BOOLEAN, "force power of two textures (default no)" }, { OSDOPTION_GL_NOTEXTURERECT, "0", OPTION_BOOLEAN, "don't use OpenGL GL_ARB_texture_rectangle (default on)" }, { OSDOPTION_GL_VBO, "1", OPTION_BOOLEAN, "enable OpenGL VBO, if available (default on)" }, @@ -116,12 +116,12 @@ const options_entry osd_options::s_option_entries[] = { OSDOPTION_SHADER_SCREEN "9", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 9" }, #endif - { NULL, NULL, OPTION_HEADER, "OSD SOUND OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "OSD SOUND OPTIONS" }, { OSDOPTION_SOUND, OSDOPTVAL_AUTO, OPTION_STRING, "sound output method: " }, { OSDOPTION_AUDIO_LATENCY "(1-5)", "2", OPTION_INTEGER, "set audio latency (increase to reduce glitches, decrease for responsiveness)" }, #ifdef SDLMAME_MACOSX - { NULL, NULL, OPTION_HEADER, "CoreAudio-SPECIFIC OPTIONS" }, + { nullptr, nullptr, OPTION_HEADER, "CoreAudio-SPECIFIC OPTIONS" }, { OSDOPTION_AUDIO_OUTPUT, OSDOPTVAL_AUTO, OPTION_STRING, "Audio output device" }, { OSDOPTION_AUDIO_EFFECT "0", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 0" }, { OSDOPTION_AUDIO_EFFECT "1", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 1" }, @@ -136,7 +136,7 @@ const options_entry osd_options::s_option_entries[] = #endif // End of list - { NULL } + { nullptr } }; osd_options::osd_options() @@ -151,11 +151,11 @@ osd_options::osd_options() //------------------------------------------------- osd_common_t::osd_common_t(osd_options &options) - : osd_output(), m_machine(NULL), + : osd_output(), m_machine(nullptr), m_options(options), m_print_verbose(false), - m_sound(NULL), - m_debugger(NULL) + m_sound(nullptr), + m_debugger(nullptr) { osd_output::push(this); } @@ -240,7 +240,7 @@ void osd_common_t::register_options() update_option(OSD_DEBUG_PROVIDER, dnames); // Register video options and update options - video_options_add("none", NULL); + video_options_add("none", nullptr); video_register(); update_option(OSDOPTION_VIDEO, m_video_names); } @@ -426,7 +426,7 @@ void osd_common_t::set_mastervolume(int attenuation) // while (attenuation++ < 0) // volume /= 1.122018454; // = (10 ^ (1/20)) = 1dB // - if (m_sound != NULL) + if (m_sound != nullptr) m_sound->set_mastervolume(attenuation); } @@ -458,7 +458,7 @@ void osd_common_t::customize_input_type_list(simple_list<input_type_entry> &type osd_font *osd_common_t::font_open(const char *name, int &height) { - return NULL; + return nullptr; } @@ -490,9 +490,9 @@ bool osd_common_t::font_get_bitmap(osd_font *font, unicode_char chnum, bitmap_ar // list of OS-dependent slider values. //------------------------------------------------- -void *osd_common_t::get_slider_list() +slider_state* osd_common_t::get_slider_list() { - return NULL; + return nullptr; } //------------------------------------------------- diff --git a/src/osd/modules/lib/osdobj_common.h b/src/osd/modules/lib/osdobj_common.h index a73931f3fa1..d4fba565964 100644 --- a/src/osd/modules/lib/osdobj_common.h +++ b/src/osd/modules/lib/osdobj_common.h @@ -187,7 +187,7 @@ public: virtual bool font_get_bitmap(osd_font *font, unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs); // video overridables - virtual void *get_slider_list() override; + virtual slider_state *get_slider_list() override; // command option overrides virtual bool execute_command(const char *command) override; diff --git a/src/osd/modules/osdwindow.cpp b/src/osd/modules/osdwindow.cpp new file mode 100644 index 00000000000..0f81a8a9ce7 --- /dev/null +++ b/src/osd/modules/osdwindow.cpp @@ -0,0 +1,57 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont, Couriersud +//============================================================ +// +// osdwindow.cpp - SDL window handling +// +//============================================================ + +// standard windows headers +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <windowsx.h> +#include <mmsystem.h> + +#include "osdwindow.h" + +#include "render/drawnone.h" +#include "render/drawbgfx.h" +#include "render/drawogl.h" +#if OSD_WINDOWS +#include "render/drawgdi.h" +#include "render/drawd3d.h" +#else +#include "render/draw13.h" +#include "render/drawsdl.h" +#endif + +osd_renderer* osd_renderer::make_for_type(int mode, osd_window* window, int extra_flags) +{ + switch(mode) + { + case VIDEO_MODE_NONE: + return new renderer_none(window); + case VIDEO_MODE_BGFX: + return new renderer_bgfx(window); +#if (USE_OPENGL) + case VIDEO_MODE_OPENGL: + return new renderer_ogl(window); +#endif +#if OSD_WINDOWS + case VIDEO_MODE_GDI: + return new renderer_gdi(window); + case VIDEO_MODE_D3D: + { + osd_renderer *renderer = new renderer_d3d9(window); + return renderer; + } +#else + case VIDEO_MODE_SDL2ACCEL: + return new renderer_sdl2(window, extra_flags); + case VIDEO_MODE_SOFT: + return new renderer_sdl1(window, extra_flags); +#endif + default: + return nullptr; + } +}
\ No newline at end of file diff --git a/src/osd/modules/osdwindow.h b/src/osd/modules/osdwindow.h index d4c2a4101cc..69f3675d4d0 100644 --- a/src/osd/modules/osdwindow.h +++ b/src/osd/modules/osdwindow.h @@ -9,13 +9,122 @@ #ifndef __OSDWINDOW__ #define __OSDWINDOW__ -#include "video.h" -#include "render.h" +#include "emu.h" //============================================================ // TYPE DEFINITIONS //============================================================ +class osd_options; +class render_primitive_list; + +enum +{ + VIDEO_MODE_NONE, + VIDEO_MODE_GDI, + VIDEO_MODE_BGFX, +#if (USE_OPENGL) + VIDEO_MODE_OPENGL, +#endif + VIDEO_MODE_SDL2ACCEL, + VIDEO_MODE_D3D, + VIDEO_MODE_SOFT +}; + +class osd_dim +{ +public: + osd_dim(const int &w, const int &h) + : m_w(w), m_h(h) + { + } + int width() const { return m_w; } + int height() const { return m_h; } + + bool operator!=(const osd_dim &other) { return (m_w != other.width()) || (m_h != other.height()); } + bool operator==(const osd_dim &other) { return (m_w == other.width()) && (m_h == other.height()); } +private: + int m_w; + int m_h; +}; + +class osd_rect +{ +public: + osd_rect() + : m_x(0), m_y(0), m_d(0,0) + { + } + osd_rect(const int x, const int y, const int &w, const int &h) + : m_x(x), m_y(y), m_d(w,h) + { + } + osd_rect(const int x, const int y, const osd_dim &d) + : m_x(x), m_y(y), m_d(d) + { + } + int top() const { return m_y; } + int left() const { return m_x; } + int width() const { return m_d.width(); } + int height() const { return m_d.height(); } + + osd_dim dim() const { return m_d; } + + int bottom() const { return m_y + m_d.height(); } + int right() const { return m_x + m_d.width(); } + + osd_rect move_by(int dx, int dy) const { return osd_rect(m_x + dx, m_y + dy, m_d); } + osd_rect resize(int w, int h) const { return osd_rect(m_x, m_y, w, h); } + +private: + int m_x; + int m_y; + osd_dim m_d; +}; + +class osd_monitor_info +{ +public: + osd_monitor_info(void *handle, const char *monitor_device, float aspect) + : m_next(NULL), m_handle(handle), m_aspect(aspect) + { + strncpy(m_name, monitor_device, ARRAY_LENGTH(m_name) - 1); + } + + virtual ~osd_monitor_info() { } + + virtual void refresh() = 0; + + const void *oshandle() { return m_handle; } + + const osd_rect &position_size() { return m_pos_size; } + const osd_rect &usuable_position_size() { return m_usuable_pos_size; } + + const char *devicename() { return m_name[0] ? m_name : "UNKNOWN"; } + + float aspect(); + + void set_aspect(const float a) { m_aspect = a; } + bool is_primary() { return m_is_primary; } + + osd_monitor_info * next() { return m_next; } // pointer to next monitor in list + + static osd_monitor_info *pick_monitor(osd_options &options, int index); + static osd_monitor_info *list; + + // FIXME: should be private! + osd_monitor_info *m_next; // pointer to next monitor in list +protected: + osd_rect m_pos_size; + osd_rect m_usuable_pos_size; + bool m_is_primary; + char m_name[64]; +private: + + void * m_handle; // handle to the monitor + float m_aspect; // computed/configured aspect ratio of the physical device +}; + class osd_window_config { public: @@ -33,8 +142,7 @@ class osd_window public: osd_window() : -#ifdef OSD_SDL -#else +#ifndef OSD_SDL m_hwnd(0), m_dc(0), m_focus_hwnd(0), m_resize_state(0), #endif m_primlist(nullptr), @@ -110,27 +218,24 @@ public: /* Interface to be implemented by render code */ virtual int create() = 0; + virtual int init(running_machine &machine) = 0; virtual render_primitive_list *get_primitives() = 0; virtual int draw(const int update) = 0; -#ifdef OSD_SDL - virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) = 0; -#else - virtual void save() = 0; - virtual void record() = 0; - virtual void toggle_fsfx() = 0; -#endif + virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) { return 0; }; + virtual void save() { }; + virtual void record() { }; + virtual void toggle_fsfx() { }; - virtual void destroy() = 0; + static osd_renderer* make_for_type(int mode, osd_window *window, int extra_flags = FLAG_NONE); protected: /* Internal flags */ static const int FI_CHANGED = 0x010000; private: - - osd_window *m_window; - int m_flags; + osd_window *m_window; + int m_flags; }; diff --git a/src/osd/modules/render/bgfx/blendreader.cpp b/src/osd/modules/render/bgfx/blendreader.cpp new file mode 100644 index 00000000000..ce4547879ef --- /dev/null +++ b/src/osd/modules/render/bgfx/blendreader.cpp @@ -0,0 +1,43 @@ +#include <bgfx/bgfx.h> + +#include "blendreader.h" + +const blend_reader::string_to_enum blend_reader::EQUATION_NAMES[blend_reader::EQUATION_COUNT] = { + { "add", BGFX_STATE_BLEND_EQUATION_ADD }, + { "sub", BGFX_STATE_BLEND_EQUATION_SUB }, + { "subtract", BGFX_STATE_BLEND_EQUATION_SUB }, + { "revSub", BGFX_STATE_BLEND_EQUATION_REVSUB }, + { "revSubtract", BGFX_STATE_BLEND_EQUATION_REVSUB }, + { "min", BGFX_STATE_BLEND_EQUATION_MIN }, + { "max", BGFX_STATE_BLEND_EQUATION_MAX } +}; + +const blend_reader::string_to_enum blend_reader::FUNCTION_NAMES[blend_reader::FUNCTION_COUNT] = { + { "0", BGFX_STATE_BLEND_ZERO }, + { "zero", BGFX_STATE_BLEND_ZERO }, + { "1", BGFX_STATE_BLEND_ONE }, + { "one", BGFX_STATE_BLEND_ONE }, + { "srcColor", BGFX_STATE_BLEND_SRC_COLOR }, + { "1-srcColor", BGFX_STATE_BLEND_INV_SRC_COLOR }, + { "invSrcColor", BGFX_STATE_BLEND_INV_SRC_COLOR }, + { "dstColor", BGFX_STATE_BLEND_DST_COLOR }, + { "1-dstColor", BGFX_STATE_BLEND_INV_DST_COLOR }, + { "invDstColor", BGFX_STATE_BLEND_INV_DST_COLOR }, + { "srcAlpha", BGFX_STATE_BLEND_SRC_ALPHA }, + { "1-srcAlpha", BGFX_STATE_BLEND_INV_SRC_ALPHA }, + { "invSrcAlpha", BGFX_STATE_BLEND_INV_SRC_ALPHA }, + { "dstAlpha", BGFX_STATE_BLEND_DST_ALPHA }, + { "1-dstAlpha", BGFX_STATE_BLEND_INV_DST_ALPHA }, + { "invDstAlpha", BGFX_STATE_BLEND_INV_DST_ALPHA } +}; + +uint64_t blend_reader::read_from_value(const Value& value) +{ + uint64_t equation = get_enum_from_value(value, "equation", BGFX_STATE_BLEND_EQUATION_ADD, EQUATION_NAMES, EQUATION_COUNT); + uint64_t srccolor = get_enum_from_value(value, "srcColor", BGFX_STATE_BLEND_ONE, FUNCTION_NAMES, FUNCTION_COUNT); + uint64_t dstcolor = get_enum_from_value(value, "dstColor", BGFX_STATE_BLEND_ZERO, FUNCTION_NAMES, FUNCTION_COUNT); + uint64_t srcalpha = get_enum_from_value(value, "srcAlpha", BGFX_STATE_BLEND_ONE, FUNCTION_NAMES, FUNCTION_COUNT); + uint64_t dstalpha = get_enum_from_value(value, "dstAlpha", BGFX_STATE_BLEND_ZERO, FUNCTION_NAMES, FUNCTION_COUNT); + + return BGFX_STATE_BLEND_EQUATION(equation) | BGFX_STATE_BLEND_FUNC_SEPARATE(srccolor, dstcolor, srcalpha, dstalpha); +} diff --git a/src/osd/modules/render/bgfx/blendreader.h b/src/osd/modules/render/bgfx/blendreader.h new file mode 100644 index 00000000000..dac233aba92 --- /dev/null +++ b/src/osd/modules/render/bgfx/blendreader.h @@ -0,0 +1,23 @@ +#pragma once + +#ifndef __DRAWBGFX_BLEND_READER__ +#define __DRAWBGFX_BLEND_READER__ + +#include <bgfx/bgfx.h> + +#include "statereader.h" + +using namespace rapidjson; + +class blend_reader : public state_reader { +public: + static uint64_t read_from_value(const Value& value); + +private: + static const int EQUATION_COUNT = 7; + static const string_to_enum EQUATION_NAMES[EQUATION_COUNT]; + static const int FUNCTION_COUNT = 16; + static const string_to_enum FUNCTION_NAMES[FUNCTION_COUNT]; +}; + +#endif // __DRAWBGFX_BLEND_READER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/cullreader.cpp b/src/osd/modules/render/bgfx/cullreader.cpp new file mode 100644 index 00000000000..727474f9e81 --- /dev/null +++ b/src/osd/modules/render/bgfx/cullreader.cpp @@ -0,0 +1,14 @@ +#include <bgfx/bgfx.h> + +#include "cullreader.h" + +const cull_reader::string_to_enum cull_reader::MODE_NAMES[cull_reader::MODE_COUNT] = { + { "none", 0 }, + { "cw", BGFX_STATE_CULL_CW }, + { "ccw", BGFX_STATE_CULL_CCW } +}; + +uint64_t cull_reader::read_from_value(const Value& value) +{ + return get_enum_from_value(value, "mode", BGFX_STATE_CULL_CCW, MODE_NAMES, MODE_COUNT); +} diff --git a/src/osd/modules/render/bgfx/cullreader.h b/src/osd/modules/render/bgfx/cullreader.h new file mode 100644 index 00000000000..bf247fb8635 --- /dev/null +++ b/src/osd/modules/render/bgfx/cullreader.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef __DRAWBGFX_CULL_READER__ +#define __DRAWBGFX_CULL_READER__ + +#include "statereader.h" + +class cull_reader : public state_reader { +public: + static uint64_t read_from_value(const Value& value); + +private: + static const int MODE_COUNT = 3; + static const string_to_enum MODE_NAMES[MODE_COUNT]; +}; + +#endif // __DRAWBGFX_CULL_READER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/depthreader.cpp b/src/osd/modules/render/bgfx/depthreader.cpp new file mode 100644 index 00000000000..1f2c3abbc9f --- /dev/null +++ b/src/osd/modules/render/bgfx/depthreader.cpp @@ -0,0 +1,28 @@ +#include <bgfx/bgfx.h> + +#include "depthreader.h" + +const depth_reader::string_to_enum depth_reader::FUNCTION_NAMES[depth_reader::FUNCTION_COUNT] = { + { "never", BGFX_STATE_DEPTH_TEST_NEVER }, + { "less", BGFX_STATE_DEPTH_TEST_LESS }, + { "equal", BGFX_STATE_DEPTH_TEST_EQUAL }, + { "lequal", BGFX_STATE_DEPTH_TEST_LEQUAL }, + { "greater", BGFX_STATE_DEPTH_TEST_GREATER }, + { "notequal", BGFX_STATE_DEPTH_TEST_NOTEQUAL }, + { "gequal", BGFX_STATE_DEPTH_TEST_GEQUAL }, + { "always", BGFX_STATE_DEPTH_TEST_ALWAYS } +}; + +uint64_t depth_reader::read_from_value(const Value& value) +{ + uint64_t write_enable = 0; + if (value.HasMember("writeEnable")) + { + assert(value["writeEnable"].IsBool()); + write_enable = value["writeEnable"].GetBool() ? BGFX_STATE_DEPTH_WRITE: 0; + } + + uint64_t function = get_enum_from_value(value, "function", BGFX_STATE_DEPTH_TEST_ALWAYS, FUNCTION_NAMES, FUNCTION_COUNT); + + return write_enable | function; +} diff --git a/src/osd/modules/render/bgfx/depthreader.h b/src/osd/modules/render/bgfx/depthreader.h new file mode 100644 index 00000000000..6dad9d9d7c8 --- /dev/null +++ b/src/osd/modules/render/bgfx/depthreader.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef __DRAWBGFX_DEPTH_READER__ +#define __DRAWBGFX_DEPTH_READER__ + +#include "statereader.h" + +class depth_reader : public state_reader { +public: + static uint64_t read_from_value(const Value& value); + +private: + static const int FUNCTION_COUNT = 8; + static const string_to_enum FUNCTION_NAMES[FUNCTION_COUNT]; +}; + +#endif // __DRAWBGFX_DEPTH_READER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/effect.cpp b/src/osd/modules/render/bgfx/effect.cpp new file mode 100644 index 00000000000..76092fd13f9 --- /dev/null +++ b/src/osd/modules/render/bgfx/effect.cpp @@ -0,0 +1,44 @@ +#include "effect.h" + +bgfx_effect::bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms) + : m_state(state) +{ + m_program_handle = bgfx::createProgram(vertex_shader, fragment_shader, false); + + for (int i = 0; i < uniforms.size(); i++) + { + m_uniforms[uniforms[i]->name()] = uniforms[i]; + } +} + +bgfx_effect::~bgfx_effect() +{ + for (std::pair<std::string, bgfx_uniform*> uniform : m_uniforms) + { + delete uniform.second; + } + m_uniforms.clear(); + bgfx::destroyProgram(m_program_handle); +} + +void bgfx_effect::submit(int view) +{ + for (std::pair<std::string, bgfx_uniform*> uniform_pair : m_uniforms) + { + (uniform_pair.second)->upload(); + } + bgfx::setState(m_state); + bgfx::submit(view, m_program_handle); +} + +bgfx_uniform* bgfx_effect::uniform(std::string name) +{ + std::map<std::string, bgfx_uniform*>::iterator iter = m_uniforms.find(name); + + if (iter != m_uniforms.end()) + { + return iter->second; + } + + return nullptr; +}
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/effect.h b/src/osd/modules/render/bgfx/effect.h new file mode 100644 index 00000000000..440a38252ce --- /dev/null +++ b/src/osd/modules/render/bgfx/effect.h @@ -0,0 +1,32 @@ +#pragma once + +#ifndef __DRAWBGFX_EFFECT__ +#define __DRAWBGFX_EFFECT__ + +#include <bgfx/bgfx.h> + +#include <string> +#include <vector> +#include <map> + +#include "uniform.h" + +class bgfx_effect +{ +public: + bgfx_effect(uint64_t state, bgfx::ShaderHandle vertexShader, bgfx::ShaderHandle fragmentShader, std::vector<bgfx_uniform*> uniforms); + ~bgfx_effect(); + + void submit(int view); + + // Getters + bgfx_uniform* uniform(std::string name); + bgfx::ProgramHandle get_program() const { return m_program_handle; } + +private: + uint64_t m_state; + bgfx::ProgramHandle m_program_handle; + std::map<std::string, bgfx_uniform*> m_uniforms; +}; + +#endif // __DRAWBGFX_EFFECT__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp new file mode 100644 index 00000000000..094abb66b5b --- /dev/null +++ b/src/osd/modules/render/bgfx/effectmanager.cpp @@ -0,0 +1,55 @@ +#include "emu.h" + +#include <rapidjson/document.h> + +#include <bgfx/bgfxplatform.h> +#include <bgfx/bgfx.h> +#include <bx/readerwriter.h> + +#include "effectmanager.h" +#include "effectreader.h" +#include "effect.h" + +using namespace rapidjson; + +effect_manager::~effect_manager() +{ + for (std::pair<std::string, bgfx_effect*> effect : m_effects) + { + delete effect.second; + } + m_effects.clear(); +} + +bgfx_effect* effect_manager::effect(std::string name) +{ + std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name); + if (iter != m_effects.end()) + { + return iter->second; + } + + return load_effect(name); +} + +bgfx_effect* effect_manager::load_effect(std::string name) { + std::string path = "bgfx/effects/" + name + ".json"; + + bx::CrtFileReader reader; + bx::open(&reader, path.c_str()); + + int32_t size = (uint32_t)bx::getSize(&reader); + + char* data = new char[size + 1]; + bx::read(&reader, reinterpret_cast<void*>(data), size); + bx::close(&reader); + data[size] = 0; + + Document document; + document.Parse<0>(data); + bgfx_effect* effect = effect_reader::read_from_value(m_shaders, document); + + m_effects[name] = effect; + + return effect; +} diff --git a/src/osd/modules/render/bgfx/effectmanager.h b/src/osd/modules/render/bgfx/effectmanager.h new file mode 100644 index 00000000000..f91035b9c87 --- /dev/null +++ b/src/osd/modules/render/bgfx/effectmanager.h @@ -0,0 +1,30 @@ +#pragma once + +#ifndef __DRAWBGFX_EFFECT_MANAGER__ +#define __DRAWBGFX_EFFECT_MANAGER__ + +#include <map> +#include <string> + +#include <bgfx/bgfx.h> + +#include "shadermanager.h" + +class bgfx_effect; + +class effect_manager { +public: + effect_manager(shader_manager& shaders) : m_shaders(shaders) { } + ~effect_manager(); + + // Getters + bgfx_effect* effect(std::string name); + +private: + bgfx_effect* load_effect(std::string name); + + shader_manager& m_shaders; + std::map<std::string, bgfx_effect*> m_effects; +}; + +#endif // __DRAWBGFX_EFFECT_MANAGER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/effectreader.cpp b/src/osd/modules/render/bgfx/effectreader.cpp new file mode 100644 index 00000000000..0fe24ec92dc --- /dev/null +++ b/src/osd/modules/render/bgfx/effectreader.cpp @@ -0,0 +1,69 @@ +#include <string> + +#include <bgfx/bgfx.h> + +#include "emu.h" + +#include "effect.h" +#include "blendreader.h" +#include "depthreader.h" +#include "cullreader.h" +#include "writereader.h" +#include "shadermanager.h" +#include "uniformreader.h" + +#include "effectreader.h" + +bgfx_effect* effect_reader::read_from_value(shader_manager& shaders, const Value& value) +{ + validate_parameters(value); + + uint64_t blend = blend_reader::read_from_value(value["blend"]); + uint64_t depth = depth_reader::read_from_value(value["depth"]); + uint64_t cull = cull_reader::read_from_value(value["cull"]); + uint64_t write = write_reader::read_from_value(value["write"]); + + std::vector<bgfx_uniform*> uniforms; + const Value& uniform_array = value["uniforms"]; + for (UINT32 i = 0; i < uniform_array.Size(); i++) + { + uniforms.push_back(uniform_reader::read_from_value(uniform_array[i])); + } + + std::string vertex_name(value["vertex"].GetString()); + bgfx::ShaderHandle vertex_shader = shaders.shader(vertex_name); + + std::string fragment_name(""); + if (value.HasMember("fragment")) + { + fragment_name = value["fragment"].GetString(); + } + else if (value.HasMember("pixel")) + { + fragment_name = value["pixel"].GetString(); + } + bgfx::ShaderHandle fragment_shader = shaders.shader(fragment_name); + + return new bgfx_effect(blend | depth | cull | write, vertex_shader, fragment_shader, uniforms); +} + +void effect_reader::validate_parameters(const Value& value) +{ + assert(value.HasMember("blend")); + assert(value.HasMember("depth")); + assert(value.HasMember("cull")); + assert(value.HasMember("write")); + assert(value.HasMember("vertex")); + assert(value["vertex"].IsString()); + assert(value.HasMember("fragment") || value.HasMember("pixel")); + if (value.HasMember("fragment")) + { + assert(value["fragment"].IsString()); + } + if (value.HasMember("pixel")) + { + assert(value["pixel"].IsString()); + } + assert(value.HasMember("uniform")); + assert(value["uniform"].IsArray()); +}
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/effectreader.h b/src/osd/modules/render/bgfx/effectreader.h new file mode 100644 index 00000000000..ea353d7256b --- /dev/null +++ b/src/osd/modules/render/bgfx/effectreader.h @@ -0,0 +1,20 @@ +#pragma once + +#ifndef __DRAWBGFX_EFFECT_READER__ +#define __DRAWBGFX_EFFECT_READER__ + +#include "statereader.h" + +class bgfx_effect; +class shader_manager; + +class effect_reader : public state_reader +{ +public: + static bgfx_effect* read_from_value(shader_manager& shaders, const Value& value); + +private: + static void validate_parameters(const Value& value); +}; + +#endif // __DRAWBGFX_EFFECT_READER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/fs_quad_texture.sc b/src/osd/modules/render/bgfx/fs_gui.sc index 5a45a056171..28a1438d189 100644 --- a/src/osd/modules/render/bgfx/fs_quad_texture.sc +++ b/src/osd/modules/render/bgfx/fs_gui.sc @@ -5,7 +5,7 @@ $input v_color0, v_texcoord0 #include "../../../../../3rdparty/bgfx/examples/common/common.sh" -SAMPLER2D(s_tex, 0); +SAMPLER2D(s_tex, 0); void main() { diff --git a/src/osd/modules/render/bgfx/fs_line.sc b/src/osd/modules/render/bgfx/fs_line.sc deleted file mode 100644 index 1fcd3b27284..00000000000 --- a/src/osd/modules/render/bgfx/fs_line.sc +++ /dev/null @@ -1,11 +0,0 @@ -$input v_color0 - -// license:BSD-3-Clause -// copyright-holders:Dario Manesku - -#include "../../../../../3rdparty/bgfx/examples/common/common.sh" - -void main() -{ - gl_FragColor = v_color0; -} diff --git a/src/osd/modules/render/bgfx/fs_quad.sc b/src/osd/modules/render/bgfx/fs_quad.sc deleted file mode 100644 index 1fcd3b27284..00000000000 --- a/src/osd/modules/render/bgfx/fs_quad.sc +++ /dev/null @@ -1,11 +0,0 @@ -$input v_color0 - -// license:BSD-3-Clause -// copyright-holders:Dario Manesku - -#include "../../../../../3rdparty/bgfx/examples/common/common.sh" - -void main() -{ - gl_FragColor = v_color0; -} diff --git a/src/osd/modules/render/bgfx/fs_screen.sc b/src/osd/modules/render/bgfx/fs_screen.sc new file mode 100644 index 00000000000..59c2916039e --- /dev/null +++ b/src/osd/modules/render/bgfx/fs_screen.sc @@ -0,0 +1,16 @@ +$input v_color0, v_texcoord0 + +// license:BSD-3-Clause +// copyright-holders:Dario Manesku + +#include "../../../../../3rdparty/bgfx/examples/common/common.sh" + +SAMPLER2D(s_tex, 0); + +uniform vec4 u_tint; + +void main() +{ + vec4 texel = texture2D(s_tex, v_texcoord0); + gl_FragColor = texel * v_color0 * u_tint; +} diff --git a/src/osd/modules/render/bgfx/pass.cpp b/src/osd/modules/render/bgfx/pass.cpp new file mode 100644 index 00000000000..246399eeebd --- /dev/null +++ b/src/osd/modules/render/bgfx/pass.cpp @@ -0,0 +1,33 @@ +#include "emu.h" + +#include <bgfx/bgfx.h> + +#include "effect.h" +#include "texture.h" +#include "target.h" +#include "pass.h" + +bgfx_pass::bgfx_pass(std::string name, bgfx_effect* effect, std::vector<bgfx_texture*>& inputs, bgfx_target* output) + : m_name(name) + , m_effect(effect) + , m_output(output) +{ + for (bgfx_texture* input : inputs) + { + m_inputs.push_back(input); + } +} + +bgfx_pass::~bgfx_pass() +{ +} + +void bgfx_pass::submit(render_primitive* prim, int view) +{ + for (int index = 0; index < m_inputs.size(); index++) + { + bgfx::setTexture(index, m_effect->uniform(m_inputs[index]->name())->handle(), m_inputs[index]->handle()); + } + bgfx::setViewFrameBuffer(view, m_output->target()); + m_effect->submit(view); +} diff --git a/src/osd/modules/render/bgfx/pass.h b/src/osd/modules/render/bgfx/pass.h new file mode 100644 index 00000000000..30c0b88a991 --- /dev/null +++ b/src/osd/modules/render/bgfx/pass.h @@ -0,0 +1,32 @@ +#pragma once + +#ifndef __DRAWBGFX_PASS__ +#define __DRAWBGFX_PASS__ + +#include <string> +#include <vector> + +class render_primitive; +class bgfx_effect; +class bgfx_texture; +class bgfx_target; + +class bgfx_pass +{ +public: + bgfx_pass(std::string name, bgfx_effect* effect, std::vector<bgfx_texture*>& inputs, bgfx_target* output); + ~bgfx_pass(); + + void submit(render_primitive* prim, int view); + + // Getters + std::string name() const { return m_name; } + +private: + std::string m_name; + bgfx_effect* m_effect; + std::vector<bgfx_texture*> m_inputs; + bgfx_target* m_output; +}; + +#endif // __DRAWBGFX_PASS__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/passreader.cpp b/src/osd/modules/render/bgfx/passreader.cpp new file mode 100644 index 00000000000..723a3f1f3f3 --- /dev/null +++ b/src/osd/modules/render/bgfx/passreader.cpp @@ -0,0 +1,49 @@ +#include <string> + +#include "emu.h" + +#include "passreader.h" + +#include "texturemanager.h" +#include "targetmanager.h" +#include "effectmanager.h" +#include "pass.h" + +bgfx_pass* pass_reader::read_from_value(const Value& value, texture_manager& textures, target_manager& targets, effect_manager& effects) +{ + validate_parameters(value); + + bgfx_effect* effect = effects.effect(value["effect"].GetString()); + + std::vector<bgfx_texture*> inputs; + if (value.HasMember("input")) + { + const Value& input_array = value["input"]; + for (UINT32 i = 0; i < input_array.Size(); i++) + { + inputs.push_back(textures.texture(input_array[i].GetString())); + } + } + + bgfx_target* output = targets.target(value["output"].GetString()); + + return new bgfx_pass(value["name"].GetString(), effect, inputs, output); +} + +void pass_reader::validate_parameters(const Value& value) +{ + assert(value.HasMember("name")); + assert(value["name"].IsString()); + assert(value.HasMember("output")); + assert(value["output"].IsString()); + assert(value.HasMember("effect")); + assert(value["effect"].IsString()); + if (value.HasMember("input")) + { + const Value& input_array = value["input"]; + for (int i = 0; i < input_array.Size(); i++) + { + assert(uniform_array[i].IsString()); + } + } +}
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/passreader.h b/src/osd/modules/render/bgfx/passreader.h new file mode 100644 index 00000000000..dfda1323eac --- /dev/null +++ b/src/osd/modules/render/bgfx/passreader.h @@ -0,0 +1,22 @@ +#pragma once + +#ifndef __DRAWBGFX_PASS_READER__ +#define __DRAWBGFX_PASS_READER__ + +#include "statereader.h" + +class bgfx_pass; +class texture_manager; +class target_manager; +class effect_manager; + +class pass_reader : public state_reader +{ +public: + static bgfx_pass* read_from_value(const Value& value, texture_manager& textures, target_manager& targets, effect_manager& effects); + +private: + static void validate_parameters(const Value& value); +}; + +#endif // __DRAWBGFX_PASS_READER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp new file mode 100644 index 00000000000..0629bd210e3 --- /dev/null +++ b/src/osd/modules/render/bgfx/shadermanager.cpp @@ -0,0 +1,73 @@ +#include "emu.h" + +#include <bgfx/bgfxplatform.h> +#include <bgfx/bgfx.h> +#include <bx/fpumath.h> +#include <bx/readerwriter.h> + +#include "shadermanager.h" + +shader_manager::~shader_manager() +{ + for (std::pair<std::string, bgfx::ShaderHandle> shader : m_shaders) + { + bgfx::destroyShader(shader.second); + } + m_shaders.clear(); +} + +bgfx::ShaderHandle shader_manager::shader(std::string name) +{ + std::map<std::string, bgfx::ShaderHandle>::iterator iter = m_shaders.find(name); + if (iter != m_shaders.end()) + { + return iter->second; + } + + return load_shader(name); +} + +bgfx::ShaderHandle shader_manager::load_shader(std::string name) { + std::string shader_path = "shaders/dx9/"; + switch (bgfx::getRendererType()) + { + case bgfx::RendererType::Direct3D11: + case bgfx::RendererType::Direct3D12: + shader_path = "shaders/dx11/"; + break; + + case bgfx::RendererType::OpenGL: + shader_path = "shaders/glsl/"; + break; + + case bgfx::RendererType::Metal: + shader_path = "shaders/metal/"; + break; + + case bgfx::RendererType::OpenGLES: + shader_path = "shaders/gles/"; + break; + + default: + break; + } + + bgfx::ShaderHandle handle = bgfx::createShader(load_mem(shader_path + name + ".bin")); + + m_shaders[name] = handle; + + return handle; +} + +const bgfx::Memory* shader_manager::load_mem(std::string name) { + bx::CrtFileReader reader; + bx::open(&reader, name.c_str()); + + uint32_t size = (uint32_t)bx::getSize(&reader); + const bgfx::Memory* mem = bgfx::alloc(size + 1); + bx::read(&reader, mem->data, size); + bx::close(&reader); + + mem->data[mem->size - 1] = '\0'; + return mem; +} diff --git a/src/osd/modules/render/bgfx/shadermanager.h b/src/osd/modules/render/bgfx/shadermanager.h new file mode 100644 index 00000000000..2697581884d --- /dev/null +++ b/src/osd/modules/render/bgfx/shadermanager.h @@ -0,0 +1,26 @@ +#pragma once + +#ifndef __DRAWBGFX_SHADER_MANAGER__ +#define __DRAWBGFX_SHADER_MANAGER__ + +#include <map> +#include <string> + +#include <bgfx/bgfx.h> + +class shader_manager { +public: + shader_manager() {} + ~shader_manager(); + + // Getters + bgfx::ShaderHandle shader(std::string name); + +private: + bgfx::ShaderHandle load_shader(std::string name); + static const bgfx::Memory* load_mem(std::string name); + + std::map<std::string, bgfx::ShaderHandle> m_shaders; +}; + +#endif // __DRAWBGFX_SHADER_MANAGER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/statereader.cpp b/src/osd/modules/render/bgfx/statereader.cpp new file mode 100644 index 00000000000..2f222b19bdf --- /dev/null +++ b/src/osd/modules/render/bgfx/statereader.cpp @@ -0,0 +1,107 @@ +#include "statereader.h" + +uint64_t state_reader::get_enum_from_value(const Value& value, std::string name, const uint64_t default_value, const string_to_enum* enums, const int count) +{ + if (value.HasMember(name.c_str())) + { + assert(value[name.c_str()].IsString()); + return get_param_from_string(value[name.c_str()].GetString(), enums, count); + } + else + { + return default_value; + } +} + +uint64_t state_reader::get_param_from_string(std::string value, const string_to_enum* enums, const int count) +{ + for (int i = 0; i < count; i++) + { + if (value == enums[i].m_string) + { + return enums[i].m_enum; + } + } + assert(false); + return 0; +} + +void state_reader::validate_array_parameter(const Value& value, std::string typeName, std::string paramName, const int count) +{ + const char* name = paramName.c_str(); + if (value.HasMember(name)) + { + assert(value[name].IsArray()); + assert(value[name].Size() == count); + } +} + +void state_reader::validate_double_parameter(const Value& value, std::string typeName, std::string name) +{ + if (value.HasMember(name.c_str())) + { + assert(value[name.c_str()].IsDouble()); + } +} + +void state_reader::validate_string_parameter(const Value& value, std::string typeName, std::string name) +{ + if (value.HasMember(name.c_str())) + { + assert(value[name.c_str()].IsString()); + } +} + +void state_reader::validate_boolean_parameter(const Value& value, std::string typeName, std::string name) +{ + if (value.HasMember(name.c_str())) + { + assert(value[name.c_str()].IsBool()); + } +} + +bool state_reader::get_bool(const Value& value, const std::string name, const bool default_value) +{ + if (value.HasMember(name.c_str())) + { + return value[name.c_str()].GetBool(); + } + return default_value; +} + +void state_reader::get_float(const Value& value, const std::string name, float* out, float* default_value, int count) +{ + if (value.HasMember(name.c_str())) + { + if (count == 1) + { + *out = (float) value[name.c_str()].GetDouble(); + return; + } + else + { + get_vec_values(value[name.c_str()], out, count); + } + } + for (int def = 0; def < count; def++) + { + out[def] = default_value[def]; + } +} + +void state_reader::get_vec_values(const Value& value_array, float* data, const unsigned int count) +{ + for (unsigned int i = 0; i < count && i < value_array.Size(); i++) + { + data[i] = (float) value_array[i].GetDouble(); + } +} + +std::string state_reader::get_string(const Value& value, const std::string name, const std::string default_value) +{ + if (value.HasMember(name.c_str())) + { + return std::string(value[name.c_str()].GetString()); + } + return default_value; +} diff --git a/src/osd/modules/render/bgfx/statereader.h b/src/osd/modules/render/bgfx/statereader.h new file mode 100644 index 00000000000..57edea1d28e --- /dev/null +++ b/src/osd/modules/render/bgfx/statereader.h @@ -0,0 +1,38 @@ +#pragma once + +#ifndef __DRAWBGFX_STATE_READER__ +#define __DRAWBGFX_STATE_READER__ + +#include "emu.h" + +#include <string> +#include "rapidjson/document.h" + +using namespace rapidjson; + +class state_reader +{ +protected: + struct string_to_enum + { + std::string m_string; + const UINT64 m_enum; + }; + + static void validate_array_parameter(const Value& value, std::string type_name, std::string name, const int count); + static void validate_double_parameter(const Value& value, std::string type_name, std::string name); + static void validate_string_parameter(const Value& value, std::string type_name, std::string name); + static void validate_boolean_parameter(const Value& value, std::string type_name, std::string name); + + static bool get_bool(const Value& value, const std::string name, const bool default_value); + static void get_float(const Value& value, const std::string name, float* out, float* default_value, const int count = 1); + static std::string get_string(const Value& value, const std::string name, const std::string default_value); + + static uint64_t get_enum_from_value(const Value& value, std::string name, const uint64_t default_value, const string_to_enum* enums, const int count); + static uint64_t get_param_from_string(std::string value, const string_to_enum* enums, const int count); + +private: + static void get_vec_values(const Value& value_array, float* data, const unsigned int count); +}; + +#endif // __DRAWBGFX_STATE_READER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/target.cpp b/src/osd/modules/render/bgfx/target.cpp new file mode 100644 index 00000000000..b45ccde519e --- /dev/null +++ b/src/osd/modules/render/bgfx/target.cpp @@ -0,0 +1,12 @@ +#include "target.h" + +bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, bool filter) + : bgfx_texture(name, format, width, height, nullptr, BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | (filter ? 0 : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT))) +{ + m_target = bgfx::createFrameBuffer(1, &m_handle, false); +} + +bgfx_target::~bgfx_target() +{ + bgfx::destroyFrameBuffer(m_target); +} diff --git a/src/osd/modules/render/bgfx/target.h b/src/osd/modules/render/bgfx/target.h new file mode 100644 index 00000000000..e00b965bb57 --- /dev/null +++ b/src/osd/modules/render/bgfx/target.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef __DRAWBGFX_TARGET__ +#define __DRAWBGFX_TARGET__ + +#include "texture.h" + +class bgfx_target : public bgfx_texture +{ +public: + bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, bool filter = false); + virtual ~bgfx_target(); + + // Getters + bgfx::FrameBufferHandle target() const { return m_target; } + +private: + bgfx::FrameBufferHandle m_target; +}; + +#endif // __DRAWBGFX_TARGET__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/targetmanager.cpp b/src/osd/modules/render/bgfx/targetmanager.cpp new file mode 100644 index 00000000000..8f9a0a6bf8b --- /dev/null +++ b/src/osd/modules/render/bgfx/targetmanager.cpp @@ -0,0 +1,33 @@ +#include <bgfx/bgfx.h> + +#include "targetmanager.h" +#include "target.h" + +target_manager::~target_manager() +{ + for (std::pair<std::string, bgfx_target*> target : m_targets) + { + delete target.second; + } + m_targets.clear(); +} + +bgfx_target* target_manager::create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, bool filter) +{ + bgfx_target* target = new bgfx_target(name, format, width, height, filter); + m_targets[name] = target; + + m_textures.add_texture(name, target); + return target; +} + +bgfx_target* target_manager::target(std::string name) +{ + std::map<std::string, bgfx_target*>::iterator iter = m_targets.find(name); + if (iter != m_targets.end()) + { + return iter->second; + } + + return nullptr; +} diff --git a/src/osd/modules/render/bgfx/targetmanager.h b/src/osd/modules/render/bgfx/targetmanager.h new file mode 100644 index 00000000000..4cf3fea3637 --- /dev/null +++ b/src/osd/modules/render/bgfx/targetmanager.h @@ -0,0 +1,32 @@ +#pragma once + +#ifndef __DRAWBGFX_TARGET_MANAGER__ +#define __DRAWBGFX_TARGET_MANAGER__ + +#include <map> +#include <string> + +#include <bgfx/bgfx.h> + +#include "texturemanager.h" + +class bgfx_target; + +class target_manager { +public: + target_manager(texture_manager& textures) : m_textures(textures) { } + ~target_manager(); + + bgfx_target* create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, bool filter = false); + + // Getters + bgfx_target* target(std::string name); + +private: + bgfx_target* create_target(std::string name); + + std::map<std::string, bgfx_target*> m_targets; + texture_manager& m_textures; +}; + +#endif // __DRAWBGFX_TARGET_MANAGER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/texture.cpp b/src/osd/modules/render/bgfx/texture.cpp new file mode 100644 index 00000000000..bf2668bc68b --- /dev/null +++ b/src/osd/modules/render/bgfx/texture.cpp @@ -0,0 +1,30 @@ +#include "emu.h" + +#include "texture.h" + +bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data, uint32_t flags) + : m_name(name) + , m_format(format) + , m_width(width) + , m_height(height) +{ + bgfx::TextureInfo info; + bgfx::calcTextureSize(info, width, height, 1, false, 1, format); + if (data != nullptr) + { + m_handle = bgfx::createTexture2D(width, height, 1, format, flags, bgfx::copy(data, info.storageSize)); + } + else + { + m_handle = bgfx::createTexture2D(width, height, 1, format, flags); + + const bgfx::Memory* memory = bgfx::alloc(info.storageSize); + memset(memory->data, 0, info.storageSize); + bgfx::updateTexture2D(m_handle, 0, 0, 0, width, height, memory, info.storageSize / height); + } +} + +bgfx_texture::~bgfx_texture() +{ + bgfx::destroyTexture(m_handle); +} diff --git a/src/osd/modules/render/bgfx/texture.h b/src/osd/modules/render/bgfx/texture.h new file mode 100644 index 00000000000..a612b6e8dbf --- /dev/null +++ b/src/osd/modules/render/bgfx/texture.h @@ -0,0 +1,31 @@ +#pragma once + +#ifndef __DRAWBGFX_TEXTURE__ +#define __DRAWBGFX_TEXTURE__ + +#include <bgfx/bgfx.h> + +#include <string> + +class bgfx_texture +{ +public: + bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data = nullptr, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP); + virtual ~bgfx_texture(); + + // Getters + std::string name() const { return m_name; } + bgfx::TextureFormat::Enum format() const { return m_format; } + uint32_t width() const { return m_width; } + uint32_t height() const { return m_height; } + bgfx::TextureHandle handle() const { return m_handle; } + +protected: + std::string m_name; + bgfx::TextureFormat::Enum m_format; + uint32_t m_width; + uint32_t m_height; + bgfx::TextureHandle m_handle; +}; + +#endif // __DRAWBGFX_TEXTURE__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/texturemanager.cpp b/src/osd/modules/render/bgfx/texturemanager.cpp new file mode 100644 index 00000000000..8bbfd593cf0 --- /dev/null +++ b/src/osd/modules/render/bgfx/texturemanager.cpp @@ -0,0 +1,36 @@ +#include <bgfx/bgfx.h> + +#include "texturemanager.h" +#include "texture.h" + +texture_manager::~texture_manager() +{ + for (std::pair<std::string, bgfx_texture*> texture : m_textures) + { + delete texture.second; + } + m_textures.clear(); +} + +void texture_manager::add_texture(std::string name, bgfx_texture* texture) +{ + m_textures[name] = texture; +} + +bgfx_texture* texture_manager::create_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data, uint32_t flags) +{ + bgfx_texture* texture = new bgfx_texture(name, format, width, height, data, flags); + m_textures[name] = texture; + return texture; +} + +bgfx_texture* texture_manager::texture(std::string name) +{ + std::map<std::string, bgfx_texture*>::iterator iter = m_textures.find(name); + if (iter != m_textures.end()) + { + return iter->second; + } + + return nullptr; +} diff --git a/src/osd/modules/render/bgfx/texturemanager.h b/src/osd/modules/render/bgfx/texturemanager.h new file mode 100644 index 00000000000..ae3ffd9bc97 --- /dev/null +++ b/src/osd/modules/render/bgfx/texturemanager.h @@ -0,0 +1,30 @@ +#pragma once + +#ifndef __DRAWBGFX_TEXTURE_MANAGER__ +#define __DRAWBGFX_TEXTURE_MANAGER__ + +#include <map> +#include <string> + +#include <bgfx/bgfx.h> + +class bgfx_texture; + +class texture_manager { +public: + texture_manager() { } + ~texture_manager(); + + bgfx_texture* create_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data = nullptr, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP); + void add_texture(std::string name, bgfx_texture* texture); + + // Getters + bgfx_texture* texture(std::string name); + +private: + bgfx_texture* create_texture(std::string name); + + std::map<std::string, bgfx_texture*> m_textures; +}; + +#endif // __DRAWBGFX_TEXTURE_MANAGER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/uniform.cpp b/src/osd/modules/render/bgfx/uniform.cpp new file mode 100644 index 00000000000..a0ee1d174da --- /dev/null +++ b/src/osd/modules/render/bgfx/uniform.cpp @@ -0,0 +1,72 @@ +#include "uniform.h" + +bgfx_uniform::bgfx_uniform(std::string name, bgfx::UniformType::Enum type) + : m_name(name) + , m_type(type) +{ + m_handle = bgfx::createUniform(m_name.c_str(), m_type); + m_data_size = get_size_for_type(type); + if (m_data_size > 0) + { + m_data = new uint8_t[m_data_size]; + } +} + +bgfx_uniform::~bgfx_uniform() +{ + bgfx::destroyUniform(m_handle); + delete [] m_data; +} + +void bgfx_uniform::upload() +{ + bgfx::setUniform(m_handle, m_data); +} + +bgfx_uniform* bgfx_uniform::set(float* value) +{ + return set(value, get_size_for_type(bgfx::UniformType::Vec4)); +} + +bgfx_uniform* bgfx_uniform::set_int(int value) +{ + return set(&value, get_size_for_type(bgfx::UniformType::Int1)); +} + +bgfx_uniform* bgfx_uniform::set_mat3(float* value) +{ + return set(value, get_size_for_type(bgfx::UniformType::Mat3)); +} + +bgfx_uniform* bgfx_uniform::set_mat4(float* value) +{ + return set(value, get_size_for_type(bgfx::UniformType::Mat4)); +} + +bgfx_uniform* bgfx_uniform::set(void* data, size_t size) +{ + int min_size = (size < m_data_size) ? size : m_data_size; + memcpy(m_data, data, min_size); + return this; +} + +size_t bgfx_uniform::get_size_for_type(bgfx::UniformType::Enum type) +{ + switch (type) + { + case bgfx::UniformType::Vec4: + return sizeof(float) * 4; + + case bgfx::UniformType::Int1: + return sizeof(int); + + case bgfx::UniformType::Mat3: + return sizeof(float) * 3 * 3; + + case bgfx::UniformType::Mat4: + return sizeof(float) * 4 * 4; + + default: + return 0; + } +}
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/uniform.h b/src/osd/modules/render/bgfx/uniform.h new file mode 100644 index 00000000000..5ff8f6fb3d8 --- /dev/null +++ b/src/osd/modules/render/bgfx/uniform.h @@ -0,0 +1,40 @@ +#pragma once + +#ifndef __DRAWBGFX_UNIFORM__ +#define __DRAWBGFX_UNIFORM__ + +#include <bgfx/bgfx.h> + +#include <string> + +class bgfx_uniform +{ +public: + bgfx_uniform(std::string name, bgfx::UniformType::Enum type); + virtual ~bgfx_uniform(); + + virtual void upload(); + + // Getters + std::string name() { return m_name; } + bgfx::UniformType::Enum type() const { return m_type; } + bgfx::UniformHandle handle() const { return m_handle; } + + // Setters + bgfx_uniform* set(float* value); + bgfx_uniform* set_int(int value); + bgfx_uniform* set_mat3(float* value); + bgfx_uniform* set_mat4(float* value); + bgfx_uniform* set(void* data, size_t size); + + static size_t get_size_for_type(bgfx::UniformType::Enum type); + +protected: + bgfx::UniformHandle m_handle; + std::string m_name; + bgfx::UniformType::Enum m_type; + uint8_t* m_data; + size_t m_data_size; +}; + +#endif // __DRAWBGFX_UNIFORM__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/uniformreader.cpp b/src/osd/modules/render/bgfx/uniformreader.cpp new file mode 100644 index 00000000000..f1447be7696 --- /dev/null +++ b/src/osd/modules/render/bgfx/uniformreader.cpp @@ -0,0 +1,45 @@ +#include "uniformreader.h" +#include "uniform.h" + +const uniform_reader::string_to_enum uniform_reader::TYPE_NAMES[uniform_reader::TYPE_COUNT] = { + { "int", bgfx::UniformType::Int1 }, + { "vec4", bgfx::UniformType::Vec4 }, + { "mat3", bgfx::UniformType::Mat3 }, + { "mat4", bgfx::UniformType::Mat4 }, + { "camera", bgfx::UniformType::Mat4 } +}; + +bgfx_uniform* uniform_reader::read_from_value(const Value& value) +{ + assert(value.HasMember("name")); + assert(value["name"].IsString()); + const char* name = value["name"].GetString(); + + assert(value.HasMember("type")); + bgfx::UniformType::Enum type = bgfx::UniformType::Enum(get_enum_from_value(value, "type", bgfx::UniformType::Vec4, TYPE_NAMES, TYPE_COUNT)); + const size_t type_size = bgfx_uniform::get_size_for_type(type); + + assert(value.HasMember("values")); + assert(value["values"].IsArray()); + 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; + float* data = reinterpret_cast<float*>(new char[alloc_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; + + return uniform; +} diff --git a/src/osd/modules/render/bgfx/uniformreader.h b/src/osd/modules/render/bgfx/uniformreader.h new file mode 100644 index 00000000000..850508fa6da --- /dev/null +++ b/src/osd/modules/render/bgfx/uniformreader.h @@ -0,0 +1,33 @@ +#pragma once + +#ifndef __DRAWBGFX_UNIFORM_READER__ +#define __DRAWBGFX_UNIFORM_READER__ + +#include <bgfx/bgfx.h> + +#include "statereader.h" + +class bgfx_uniform; + +enum uniform_type +{ + TYPE_INT1 = bgfx::UniformType::Int1, + TYPE_VEC4 = bgfx::UniformType::Vec4, + TYPE_MAT3 = bgfx::UniformType::Mat3, + TYPE_MAT4 = bgfx::UniformType::Mat4, + TYPE_CAMERA, // Alias for the current ortho camera, used to auto-bind on material load + + TYPE_COUNT = 5 +}; + +class uniform_reader : public state_reader +{ +public: + static bgfx_uniform* read_from_value(const Value& value); + +private: + static const int TYPE_COUNT = uniform_type::TYPE_COUNT; + static const string_to_enum TYPE_NAMES[TYPE_COUNT]; +}; + +#endif // __DRAWBGFX_UNIFORM_READER__
\ No newline at end of file diff --git a/src/osd/modules/render/bgfx/vs_quad_texture.sc b/src/osd/modules/render/bgfx/vs_gui.sc index c3699f6fbd9..c3699f6fbd9 100644 --- a/src/osd/modules/render/bgfx/vs_quad_texture.sc +++ b/src/osd/modules/render/bgfx/vs_gui.sc diff --git a/src/osd/modules/render/bgfx/vs_quad.sc b/src/osd/modules/render/bgfx/vs_quad.sc deleted file mode 100644 index 84e23c5a09b..00000000000 --- a/src/osd/modules/render/bgfx/vs_quad.sc +++ /dev/null @@ -1,13 +0,0 @@ -$input a_position, a_color0 -$output v_color0 - -// license:BSD-3-Clause -// copyright-holders:Dario Manesku - -#include "../../../../../3rdparty/bgfx/examples/common/common.sh" - -void main() -{ - gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0)); - v_color0 = a_color0; -} diff --git a/src/osd/modules/render/bgfx/vs_line.sc b/src/osd/modules/render/bgfx/vs_screen.sc index 874ffcf46ac..c3699f6fbd9 100644 --- a/src/osd/modules/render/bgfx/vs_line.sc +++ b/src/osd/modules/render/bgfx/vs_screen.sc @@ -1,5 +1,5 @@ -$input a_position, a_color0 -$output v_color0 +$input a_position, a_texcoord0, a_color0 +$output v_texcoord0, v_color0 // license:BSD-3-Clause // copyright-holders:Dario Manesku @@ -9,5 +9,6 @@ $output v_color0 void main() { gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0)); + v_texcoord0 = a_texcoord0; v_color0 = a_color0; } diff --git a/src/osd/modules/render/bgfx/writereader.cpp b/src/osd/modules/render/bgfx/writereader.cpp new file mode 100644 index 00000000000..b10220908c8 --- /dev/null +++ b/src/osd/modules/render/bgfx/writereader.cpp @@ -0,0 +1,24 @@ +#include <bgfx/bgfx.h> + +#include "writereader.h" + +const write_reader::string_to_enum write_reader::RGB_NAMES[write_reader::RGB_COUNT] = { + { "true", BGFX_STATE_RGB_WRITE }, + { "false", 0 }, + { "1", BGFX_STATE_RGB_WRITE }, + { "0", 0 } +}; + +const write_reader::string_to_enum write_reader::ALPHA_NAMES[write_reader::ALPHA_COUNT] = { + { "true", BGFX_STATE_ALPHA_WRITE }, + { "false", 0 }, + { "1", BGFX_STATE_ALPHA_WRITE }, + { "0", 0 } +}; + +uint64_t write_reader::read_from_value(const Value& value) +{ + uint64_t rgb = get_enum_from_value(value, "rgb", 0, RGB_NAMES, RGB_COUNT); + uint64_t alpha = get_enum_from_value(value, "alpha", 0, ALPHA_NAMES, ALPHA_COUNT); + return rgb | alpha; +} diff --git a/src/osd/modules/render/bgfx/writereader.h b/src/osd/modules/render/bgfx/writereader.h new file mode 100644 index 00000000000..854505bc9cf --- /dev/null +++ b/src/osd/modules/render/bgfx/writereader.h @@ -0,0 +1,19 @@ +#pragma once + +#ifndef __DRAWBGFX_WRITE_READER__ +#define __DRAWBGFX_WRITE_READER__ + +#include "statereader.h" + +class write_reader : public state_reader { +public: + static uint64_t read_from_value(const Value& value); + +private: + static const int RGB_COUNT = 4; + static const int ALPHA_COUNT = 4; + static const string_to_enum RGB_NAMES[RGB_COUNT]; + static const string_to_enum ALPHA_NAMES[ALPHA_COUNT]; +}; + +#endif // __DRAWBGFX_WRITE_READER__
\ No newline at end of file diff --git a/src/osd/modules/render/d3d/d3d9intf.cpp b/src/osd/modules/render/d3d/d3d9intf.cpp index e4f5e08db3b..435ec7ef64c 100644 --- a/src/osd/modules/render/d3d/d3d9intf.cpp +++ b/src/osd/modules/render/d3d/d3d9intf.cpp @@ -27,13 +27,11 @@ typedef IDirect3D9 *(WINAPI *direct3dcreate9_ptr)(UINT SDKVersion); -namespace d3d -{ //============================================================ // PROTOTYPES //============================================================ -static void set_interfaces(base *d3dptr); +static void set_interfaces(d3d_base *d3dptr); //============================================================ // INLINES @@ -64,7 +62,7 @@ static inline void convert_present_params(const present_parameters *params, D3DP // drawd3d9_init //============================================================ -base *drawd3d9_init(void) +d3d_base *drawd3d9_init(void) { bool post_available = true; @@ -119,7 +117,7 @@ base *drawd3d9_init(void) } // allocate an object to hold our data - auto d3dptr = global_alloc(base); + auto d3dptr = global_alloc(d3d_base); d3dptr->version = 9; d3dptr->d3dobj = d3d9; d3dptr->dllhandle = dllhandle; @@ -137,20 +135,20 @@ base *drawd3d9_init(void) // Direct3D interfaces //============================================================ -static HRESULT check_device_format(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format) +static HRESULT check_device_format(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; return IDirect3D9_CheckDeviceFormat(d3d9, adapter, devtype, adapterformat, usage, restype, format); } -static HRESULT check_device_type(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed) +static HRESULT check_device_type(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; return IDirect3D9_CheckDeviceType(d3d9, adapter, devtype, format, backformat, windowed); } -static HRESULT create_device(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev) +static HRESULT create_device(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; D3DPRESENT_PARAMETERS d3d9params; @@ -158,28 +156,28 @@ static HRESULT create_device(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWN return IDirect3D9_CreateDevice(d3d9, adapter, devtype, focus, behavior, &d3d9params, (IDirect3DDevice9 **)dev); } -static HRESULT enum_adapter_modes(base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode) +static HRESULT enum_adapter_modes(d3d_base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; return IDirect3D9_EnumAdapterModes(d3d9, adapter, format, index, mode); } -static UINT get_adapter_count(base *d3dptr) +static UINT get_adapter_count(d3d_base *d3dptr) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; return IDirect3D9_GetAdapterCount(d3d9); } -static HRESULT get_adapter_display_mode(base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode) +static HRESULT get_adapter_display_mode(d3d_base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; return IDirect3D9_GetAdapterDisplayMode(d3d9, adapter, mode); } -static HRESULT get_adapter_identifier(base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier) +static HRESULT get_adapter_identifier(d3d_base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; D3DADAPTER_IDENTIFIER9 id; @@ -197,21 +195,21 @@ static HRESULT get_adapter_identifier(base *d3dptr, UINT adapter, DWORD flags, a } -static UINT get_adapter_mode_count(base *d3dptr, UINT adapter, D3DFORMAT format) +static UINT get_adapter_mode_count(d3d_base *d3dptr, UINT adapter, D3DFORMAT format) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; return IDirect3D9_GetAdapterModeCount(d3d9, adapter, format); } -static HMONITOR get_adapter_monitor(base *d3dptr, UINT adapter) +static HMONITOR get_adapter_monitor(d3d_base *d3dptr, UINT adapter) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; return IDirect3D9_GetAdapterMonitor(d3d9, adapter); } -static HRESULT get_caps_dword(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value) +static HRESULT get_caps_dword(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; D3DCAPS9 caps; @@ -237,7 +235,7 @@ static HRESULT get_caps_dword(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, ca } -static ULONG release(base *d3dptr) +static ULONG release(d3d_base *d3dptr) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; ULONG result = IDirect3D9_Release(d3d9); @@ -469,7 +467,7 @@ static HRESULT device_test_cooperative_level(device *dev) } -static const device_interface d3d9_device_interface = +static const d3d_device_interface d3d9_device_interface = { device_begin_scene, device_clear, @@ -611,7 +609,7 @@ static const vertex_buffer_interface d3d9_vertex_buffer_interface = // set_interfaces //============================================================ -static void set_interfaces(base *d3dptr) +static void set_interfaces(d3d_base *d3dptr) { d3dptr->d3d = d3d9_interface; d3dptr->device = d3d9_device_interface; @@ -619,5 +617,3 @@ static void set_interfaces(base *d3dptr) d3dptr->texture = d3d9_texture_interface; d3dptr->vertexbuf = d3d9_vertex_buffer_interface; } - -} diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h index 58a51eaf1cf..95934f0098a 100644 --- a/src/osd/modules/render/d3d/d3dcomm.h +++ b/src/osd/modules/render/d3d/d3dcomm.h @@ -13,10 +13,9 @@ // FORWARD DECLARATIONS //============================================================ -namespace d3d -{ class texture_info; -class renderer; +class renderer_d3d9; +struct d3d_base; //============================================================ // TYPE DEFINITIONS @@ -51,12 +50,12 @@ public: } c; }; -class texture_manager +class d3d_texture_manager { public: - texture_manager() { } - texture_manager(renderer *d3d); - ~texture_manager(); + d3d_texture_manager() { } + d3d_texture_manager(renderer_d3d9 *d3d); + ~d3d_texture_manager(); void update_textures(); @@ -81,10 +80,10 @@ public: texture_info * get_default_texture() { return m_default_texture; } texture_info * get_vector_texture() { return m_vector_texture; } - renderer * get_d3d() { return m_renderer; } + renderer_d3d9 * get_d3d() { return m_renderer; } private: - renderer * m_renderer; + renderer_d3d9 * m_renderer; texture_info * m_texlist; // list of active textures int m_dynamic_supported; // are dynamic textures supported? @@ -108,7 +107,7 @@ private: class texture_info { public: - texture_info(texture_manager *manager, const render_texinfo *texsource, int prescale, UINT32 flags); + texture_info(d3d_texture_manager *manager, const render_texinfo *texsource, int prescale, UINT32 flags); ~texture_info(); render_texinfo & get_texinfo() { return m_texinfo; } @@ -151,9 +150,9 @@ private: void compute_size(int texwidth, int texheight); void compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height); - texture_manager * m_texture_manager; // texture manager pointer + d3d_texture_manager * m_texture_manager; // texture manager pointer - renderer * m_renderer; // renderer pointer + renderer_d3d9 * m_renderer; // renderer pointer texture_info * m_next; // next texture in the list texture_info * m_prev; // prev texture in the list @@ -174,17 +173,17 @@ private: texture * m_d3dfinaltex; // Direct3D final (post-scaled) texture }; -/* d3d::poly_info holds information about a single polygon/d3d primitive */ +/* poly_info holds information about a single polygon/d3d primitive */ class poly_info { public: poly_info() { } void init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts, - UINT32 flags, d3d::texture_info *texture, UINT32 modmode, + UINT32 flags, texture_info *texture, UINT32 modmode, float prim_width, float prim_height); void init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts, - UINT32 flags, d3d::texture_info *texture, UINT32 modmode, + UINT32 flags, texture_info *texture, UINT32 modmode, float line_time, float line_length, float prim_width, float prim_height); @@ -193,7 +192,7 @@ public: UINT32 get_vertcount() { return m_numverts; } UINT32 get_flags() { return m_flags; } - d3d::texture_info * get_texture() { return m_texture; } + texture_info * get_texture() { return m_texture; } DWORD get_modmode() { return m_modmode; } float get_line_time() { return m_line_time; } @@ -219,16 +218,14 @@ private: float m_prim_height; // used by quads }; -} // d3d - /* vertex describes a single vertex */ struct vertex { - float x, y, z; // X,Y,Z coordinates - float rhw; // RHW when no HLSL, padding when HLSL - D3DCOLOR color; // diffuse color - float u0, v0; // texture stage 0 coordinates - float u1, v1; // additional info for vector data + float x, y, z; // X,Y,Z coordinates + float rhw; // RHW when no HLSL, padding when HLSL + D3DCOLOR color; // diffuse color + float u0, v0; // texture stage 0 coordinates + float u1, v1; // additional info for vector data }; @@ -239,5 +236,64 @@ struct line_aa_step float weight; // weight contribution }; +/* cache_target is a simple linked list containing only a rednerable target and texture, used for phosphor effects */ +class cache_target +{ +public: + // construction/destruction + cache_target() { } + ~cache_target(); + + bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y); + + surface *last_target; + texture *last_texture; + + int target_width; + int target_height; + + int width; + int height; + + int screen_index; + + cache_target *next; + cache_target *prev; +}; + +/* render_target is the information about a Direct3D render target chain */ +class d3d_render_target +{ +public: + // construction/destruction + d3d_render_target() { } + ~d3d_render_target(); + + bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y); + int next_index(int index) { return ++index > 1 ? 0 : index; } + + int target_width; + int target_height; + + int prescale_x; + int prescale_y; + + int width; + int height; + + int screen_index; + int page_index; + + surface *prescale_target[2]; + texture *prescale_texture[2]; + surface *native_target[2]; + texture *native_texture[2]; + + d3d_render_target *next; + d3d_render_target *prev; + + surface *bloom_target[11]; + texture *bloom_texture[11]; +}; #endif diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index 4cc53f2e41d..621db1a46ff 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -14,16 +14,6 @@ // Windows NT shipped with DirectX 3.0a // Windows 95 shipped with DirectX 2 -// standard windows headers -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <tchar.h> -#include <mmsystem.h> -#include <d3d9.h> -#include <d3dx9.h> -#include <math.h> -#undef interface - // MAME headers #include "emu.h" #include "render.h" @@ -35,12 +25,12 @@ #include "screen.h" // MAMEOS headers -#include "d3dintf.h" #include "winmain.h" #include "window.h" -#include "d3dcomm.h" #include "modules/render/drawd3d.h" +#include "d3dcomm.h" #include "strconv.h" +#include "d3dhlsl.h" //============================================================ @@ -48,10 +38,8 @@ //============================================================ static slider_state *g_slider_list; -static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *templ, const char *extension, int idx); +static file_error open_next(renderer_d3d9 *d3d, emu_file &file, const char *templ, const char *extension, int idx); -namespace d3d -{ //============================================================ // PROTOTYPES //============================================================ @@ -108,7 +96,7 @@ shaders::~shaders() currcache = cachehead; } - render_target *currtarget = targethead; + d3d_render_target *currtarget = targethead; while(targethead != NULL) { targethead = currtarget->next; @@ -565,14 +553,14 @@ void shaders::remove_render_target(texture_info *texture) void shaders::remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index) { - render_target *target = find_render_target(width, height, screen_index, page_index); + d3d_render_target *target = find_render_target(width, height, screen_index, page_index); if (target != NULL) { remove_render_target(target); } } -void shaders::remove_render_target(render_target *rt) +void shaders::remove_render_target(d3d_render_target *rt) { if (rt != NULL) { @@ -645,7 +633,7 @@ void shaders::set_texture(texture_info *texture) // shaders::init //============================================================ -void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *renderer) +void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer) { if (!d3dintf->post_fx_available) { @@ -1165,13 +1153,13 @@ void shaders::init_effect_info(poly_info *poly) // shaders::find_render_target //============================================================ -render_target* shaders::find_render_target(texture_info *info) +d3d_render_target* shaders::find_render_target(texture_info *info) { UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata; UINT32 screen_index = screen_index_data >> 1; UINT32 page_index = screen_index_data & 1; - render_target *curr = targethead; + d3d_render_target *curr = targethead; while (curr != NULL && ( curr->screen_index != screen_index || curr->page_index != page_index || @@ -1189,9 +1177,9 @@ render_target* shaders::find_render_target(texture_info *info) // shaders::find_render_target //============================================================ -render_target* shaders::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index) +d3d_render_target* shaders::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index) { - render_target *curr = targethead; + d3d_render_target *curr = targethead; while (curr != NULL && ( curr->width != width || curr->height != height || @@ -1223,7 +1211,7 @@ cache_target* shaders::find_cache_target(UINT32 screen_index, int width, int hei return curr; } -int shaders::ntsc_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::ntsc_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1290,7 +1278,7 @@ rgb_t shaders::apply_color_convolution(rgb_t color) MAX(0, MIN(255, static_cast<int>(b * 255.0f)))); } -int shaders::color_convolution_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1305,7 +1293,7 @@ int shaders::color_convolution_pass(render_target *rt, int source_index, poly_in return next_index; } -int shaders::prescale_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::prescale_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1319,7 +1307,7 @@ int shaders::prescale_pass(render_target *rt, int source_index, poly_info *poly, return next_index; } -int shaders::deconverge_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::deconverge_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1342,7 +1330,7 @@ int shaders::deconverge_pass(render_target *rt, int source_index, poly_info *pol return next_index; } -int shaders::defocus_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1362,7 +1350,7 @@ int shaders::defocus_pass(render_target *rt, int source_index, poly_info *poly, return next_index; } -int shaders::phosphor_pass(render_target *rt, cache_target *ct, int source_index, poly_info *poly, int vertnum) +int shaders::phosphor_pass(d3d_render_target *rt, cache_target *ct, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1393,7 +1381,7 @@ int shaders::phosphor_pass(render_target *rt, cache_target *ct, int source_index return next_index; } -int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom) +int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom) { int next_index = source_index; @@ -1440,7 +1428,7 @@ int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int return next_index; } -int shaders::downsample_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::downsample_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1485,7 +1473,7 @@ int shaders::downsample_pass(render_target *rt, int source_index, poly_info *pol return next_index; } -int shaders::bloom_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1557,7 +1545,7 @@ int shaders::bloom_pass(render_target *rt, int source_index, poly_info *poly, in return next_index; } -int shaders::distortion_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::distortion_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1601,7 +1589,7 @@ int shaders::distortion_pass(render_target *rt, int source_index, poly_info *pol return next_index; } -int shaders::vector_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::vector_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1618,7 +1606,7 @@ int shaders::vector_pass(render_target *rt, int source_index, poly_info *poly, i return next_index; } -int shaders::vector_buffer_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::vector_buffer_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1635,7 +1623,7 @@ int shaders::vector_buffer_pass(render_target *rt, int source_index, poly_info * return next_index; } -int shaders::screen_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; @@ -1698,7 +1686,7 @@ void shaders::render_quad(poly_info *poly, int vertnum) curr_render_target = find_render_target(curr_texture); - render_target *rt = curr_render_target; + d3d_render_target *rt = curr_render_target; if (rt == NULL) { return; @@ -1744,7 +1732,7 @@ void shaders::render_quad(poly_info *poly, int vertnum) { curr_render_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); - render_target *rt = curr_render_target; + d3d_render_target *rt = curr_render_target; if (rt == NULL) { return; @@ -1766,7 +1754,7 @@ void shaders::render_quad(poly_info *poly, int vertnum) { curr_render_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); - render_target *rt = curr_render_target; + d3d_render_target *rt = curr_render_target; if (rt == NULL) { return; @@ -1844,7 +1832,7 @@ bool shaders::register_prescaled_texture(texture_info *texture) //============================================================ // shaders::add_cache_target - register a cache target //============================================================ -bool shaders::add_cache_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index) +bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index) { cache_target* target = (cache_target*)global_alloc_clear<cache_target>(); @@ -1879,7 +1867,7 @@ bool shaders::add_cache_target(renderer* d3d, texture_info* info, int width, int return true; } -render_target* shaders::get_vector_target() +d3d_render_target* shaders::get_vector_target() { if (!vector_enable) { @@ -1902,13 +1890,13 @@ void shaders::create_vector_target(render_primitive *prim) // shaders::add_render_target - register a render target //============================================================ -bool shaders::add_render_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale) +bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale) { UINT32 screen_index = 0; UINT32 page_index = 0; if (info != NULL) { - render_target *existing_target = find_render_target(info); + d3d_render_target *existing_target = find_render_target(info); if (existing_target != NULL) { remove_render_target(existing_target); @@ -1920,14 +1908,14 @@ bool shaders::add_render_target(renderer* d3d, texture_info* info, int width, in } else { - render_target *existing_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); + d3d_render_target *existing_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); if (existing_target != NULL) { remove_render_target(existing_target); } } - render_target* target = (render_target*)global_alloc_clear<render_target>(); + d3d_render_target* target = (d3d_render_target*)global_alloc_clear<d3d_render_target>(); if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale)) { @@ -2069,7 +2057,7 @@ void shaders::delete_resources(bool reset) currcache = cachehead; } - render_target *currtarget = targethead; + d3d_render_target *currtarget = targethead; while(targethead != NULL) { targethead = currtarget->next; @@ -2229,6 +2217,7 @@ static slider_state *slider_alloc(running_machine &machine, const char *title, I state->incval = incval; state->update = update; state->arg = arg; + state->hidden = false; strcpy(state->description, title); return state; @@ -3040,7 +3029,7 @@ void uniform::update() shaders *shadersys = m_shader->m_shaders; hlsl_options *options = shadersys->options; - renderer *d3d = shadersys->d3d; + renderer_d3d9 *d3d = shadersys->d3d; switch (m_id) { @@ -3531,16 +3520,14 @@ ULONG effect::release() return m_effect->Release(); } -} - //============================================================ // get_slider_list //============================================================ -void *windows_osd_interface::get_slider_list() +slider_state *windows_osd_interface::get_slider_list() { - return (void*)g_slider_list; + return g_slider_list; } @@ -3551,7 +3538,7 @@ void *windows_osd_interface::get_slider_list() // scheme //------------------------------------------------- -static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *templ, const char *extension, int idx) +static file_error open_next(renderer_d3d9 *d3d, emu_file &file, const char *templ, const char *extension, int idx) { UINT32 origflags = file.openflags(); diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index d949c1417c8..a86505a1c96 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -22,8 +22,6 @@ struct slider_state; -namespace d3d -{ class effect; class shaders; @@ -181,9 +179,9 @@ private: bool m_valid; }; -class render_target; +class d3d_render_target; class cache_target; -class renderer; +class renderer_d3d9; /* hlsl_options is the information about runtime-mutable Direct3D HLSL options */ /* in the future this will be moved into an OSD/emu shared buffer */ @@ -273,13 +271,13 @@ public: shaders(); ~shaders(); - void init(base *d3dintf, running_machine *machine, d3d::renderer *renderer); + void init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer); bool enabled() { return master_enable; } void toggle(); bool vector_enabled() { return master_enable && vector_enable; } - render_target* get_vector_target(); + d3d_render_target* get_vector_target(); void create_vector_target(render_primitive *prim); void begin_frame(); @@ -293,8 +291,8 @@ public: bool register_texture(texture_info *texture); bool register_prescaled_texture(texture_info *texture); - bool add_render_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale); - bool add_cache_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index); + bool add_render_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale); + bool add_cache_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index); void window_save(); void window_record(); @@ -306,10 +304,10 @@ public: void init_fsfx_quad(void *vertbuf); void set_texture(texture_info *texture); - render_target * find_render_target(texture_info *info); + d3d_render_target * find_render_target(texture_info *info); void remove_render_target(texture_info *texture); void remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index); - void remove_render_target(render_target *rt); + void remove_render_target(d3d_render_target *rt); int create_resources(bool reset); void delete_resources(bool reset); @@ -345,32 +343,32 @@ private: bool register_texture(texture_info *texture, int width, int height, int xscale, int yscale); - render_target* find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index); + d3d_render_target* find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index); cache_target * find_cache_target(UINT32 screen_index, int width, int height); void remove_cache_target(cache_target *cache); rgb_t apply_color_convolution(rgb_t color); // Shader passes - int ntsc_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int color_convolution_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int prescale_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int deconverge_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int defocus_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int phosphor_pass(render_target *rt, cache_target *ct, int source_index, poly_info *poly, int vertnum); - int post_pass(render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom); - int downsample_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int bloom_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int distortion_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int vector_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int vector_buffer_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); - int screen_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int ntsc_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int prescale_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int deconverge_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int defocus_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int phosphor_pass(d3d_render_target *rt, cache_target *ct, int source_index, poly_info *poly, int vertnum); + int post_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom); + int downsample_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int distortion_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int vector_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int vector_buffer_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); + int screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); void menu_pass(poly_info *poly, int vertnum); - base * d3dintf; // D3D interface + d3d_base * d3dintf; // D3D interface running_machine * machine; - d3d::renderer * d3d; // D3D renderer + renderer_d3d9 * d3d; // D3D renderer bool master_enable; // overall enable flag bool vector_enable; // vector post-processing enable flag @@ -436,15 +434,13 @@ private: vertex * fsfx_vertices; // pointer to our full-screen-quad object texture_info * curr_texture; - render_target * curr_render_target; + d3d_render_target * curr_render_target; poly_info * curr_poly; - render_target * targethead; + d3d_render_target * targethead; cache_target * cachehead; static slider_desc s_sliders[]; static hlsl_options last_options; // last used options }; -} - #endif diff --git a/src/osd/modules/render/d3d/d3dintf.h b/src/osd/modules/render/d3d/d3dintf.h index 9155f620545..3e0a90a46f5 100644 --- a/src/osd/modules/render/d3d/d3dintf.h +++ b/src/osd/modules/render/d3d/d3dintf.h @@ -9,6 +9,15 @@ #ifndef __WIN_D3DINTF__ #define __WIN_D3DINTF__ +// standard windows headers +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <tchar.h> +#include <mmsystem.h> +#include <d3d9.h> +#include <d3dx9.h> +#include <math.h> +#undef interface //============================================================ // CONSTANTS @@ -33,13 +42,11 @@ #define D3DTSS_MAXMIPLEVEL 20 #define D3DTSS_MAXANISOTROPY 21 -namespace d3d -{ //============================================================ // TYPE DEFINITIONS //============================================================ -struct base; +struct d3d_base; struct device; struct surface; struct texture; @@ -118,17 +125,17 @@ enum caps_index struct interface { - HRESULT (*check_device_format)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format); - HRESULT (*check_device_type)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed); - HRESULT (*create_device)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev); - HRESULT (*enum_adapter_modes)(base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode); - UINT (*get_adapter_count)(base *d3dptr); - HRESULT (*get_adapter_display_mode)(base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode); - HRESULT (*get_adapter_identifier)(base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier); - UINT (*get_adapter_mode_count)(base *d3dptr, UINT adapter, D3DFORMAT format); - HMONITOR (*get_adapter_monitor)(base *d3dptr, UINT adapter); - HRESULT (*get_caps_dword)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value); - ULONG (*release)(base *d3dptr); + HRESULT (*check_device_format)(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format); + HRESULT (*check_device_type)(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed); + HRESULT (*create_device)(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev); + HRESULT (*enum_adapter_modes)(d3d_base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode); + UINT (*get_adapter_count)(d3d_base *d3dptr); + HRESULT (*get_adapter_display_mode)(d3d_base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode); + HRESULT (*get_adapter_identifier)(d3d_base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier); + UINT (*get_adapter_mode_count)(d3d_base *d3dptr, UINT adapter, D3DFORMAT format); + HMONITOR (*get_adapter_monitor)(d3d_base *d3dptr, UINT adapter); + HRESULT (*get_caps_dword)(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value); + ULONG (*release)(d3d_base *d3dptr); }; @@ -136,7 +143,7 @@ struct interface // Direct3DDevice interfaces //============================================================ -struct device_interface +struct d3d_device_interface { HRESULT (*begin_scene)(device *dev); HRESULT (*clear)(device *dev, DWORD count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil); @@ -205,7 +212,7 @@ struct vertex_buffer_interface // Core D3D object //============================================================ -struct base +struct d3d_base { // internal objects int version; @@ -216,7 +223,7 @@ struct base // interface pointers interface d3d; - device_interface device; + d3d_device_interface device; surface_interface surface; texture_interface texture; vertex_buffer_interface vertexbuf; @@ -227,8 +234,6 @@ struct base // PROTOTYPES //============================================================ -base *drawd3d9_init(void); - -} +d3d_base *drawd3d9_init(void); #endif diff --git a/src/osd/modules/render/d3dtarget.h b/src/osd/modules/render/d3dtarget.h new file mode 100644 index 00000000000..9179b2d43ba --- /dev/null +++ b/src/osd/modules/render/d3dtarget.h @@ -0,0 +1,14 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +//============================================================ +// +// d3dtarget.h - Direct3D HLSL targets +// +//============================================================ + +#pragma once + +#ifndef __D3DTARGET__ +#define __D3DTARGET__ + +#endif // __D3DTARGET__
\ No newline at end of file diff --git a/src/osd/modules/render/draw13.cpp b/src/osd/modules/render/draw13.cpp index 320cc9f3a62..e210d2044df 100644 --- a/src/osd/modules/render/draw13.cpp +++ b/src/osd/modules/render/draw13.cpp @@ -18,13 +18,11 @@ #include "emu.h" #include "options.h" -// standard SDL headers -#include "sdlinc.h" - // OSD headers #include "osdsdl.h" #include "window.h" +#include "draw13.h" //============================================================ // DEBUGGING @@ -59,196 +57,38 @@ static inline bool is_transparent(const float &a) } //============================================================ -// TYPES -//============================================================ - - -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 dudx, dvdx, dudy, dvdy; - INT32 startu, startv; - INT32 rotwidth, rotheight; -}; - -//============================================================ -// Textures -//============================================================ - -class sdl_info13; -struct copy_info_t; - -/* texture_info holds information about a texture */ -class texture_info -{ - friend class simple_list<texture_info>; -public: - texture_info(sdl_info13 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const UINT32 flags); - ~texture_info(); - - void set_data(const render_texinfo &texsource, const UINT32 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 flags() const { return m_flags; } - // FIXME: - bool is_pixels_owned() const; - -private: - Uint32 m_sdl_access; - sdl_info13 * m_renderer; - render_texinfo m_texinfo; // copy of the texture info - HashT m_hash; // hash value for the texture (must be >= pointer size) - UINT32 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 +// CONSTRUCTOR & DESTRUCTOR //============================================================ -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" - -/* sdl_info is the information about SDL for the current screen */ -class sdl_info13 : public osd_renderer +renderer_sdl1::renderer_sdl1(osd_window *window, int extra_flags) + : osd_renderer(window, extra_flags) + , m_sdl_renderer(NULL) + , m_blittimer(0) + , m_last_hofs(0) + , m_last_vofs(0) + , m_width(0) + , m_height(0) + , m_blit_dim(0, 0) + , m_last_blit_time(0) + , m_last_blit_pixels(0) { -public: - sdl_info13(osd_window *w, int extra_flags) - : osd_renderer(w, extra_flags), m_sdl_renderer(NULL), m_blittimer(0), - m_last_hofs(0), m_last_vofs(0), - m_width(0), m_height(0), - m_blit_dim(0,0), - m_last_blit_time(0), m_last_blit_pixels(0) + for (int i = 0; i < 30; i++) { - for (int i=0; i < 30; i++) - { - fmt_support[i].format = 0; - fmt_support[i].status = 0; - } + fmt_support[i].format = 0; + fmt_support[i].status = 0; } - /* 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 */ void destroy() override; - /* virtual */ render_primitive_list *get_primitives() override + if (!s_blit_info_initialized) { - osd_dim nd = window().blit_surface_size(); - if (nd != m_blit_dim) - { - m_blit_dim = nd; - notify_changed(); - } - window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect()); - return &window().target()->get_primitives(); + /* 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(blit_info_default); + s_blit_info_initialized = true; } - int RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat); - - SDL_Renderer * m_sdl_renderer; - -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 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 m_last_blit_time; - INT64 m_last_blit_pixels; -}; - -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 pixel_count; - INT64 time; - int samples; - int perf; - /* list */ - copy_info_t *next; -}; - - -//============================================================ -// PROTOTYPES -//============================================================ - -// core functions +} -static void drawsdl2_exit(void); //============================================================ // STATIC VARIABLES @@ -261,7 +101,7 @@ static void drawsdl2_exit(void); #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} -static copy_info_t blit_info_default[] = +const copy_info_t renderer_sdl1::s_blit_info_default[] = { /* no rotation */ ENTRY(ARGB32, ARGB8888, argb32_argb32), @@ -340,8 +180,8 @@ static copy_info_t blit_info_default[] = { -1 }, }; -static copy_info_t *blit_info[SDL_TEXFORMAT_LAST+1] = { NULL }; -static bool blit_info_initialized = false; +copy_info_t* renderer_sdl::s_blit_info[SDL_TEXFORMAT_LAST+1] = { NULL }; +bool renderer_sdl1::s_blit_info_initialized = false; //============================================================ // INLINES @@ -376,7 +216,7 @@ static inline SDL_BlendMode map_blendmode(const int blendmode) return SDL_BLENDMODE_NONE; } -static inline void set_coloralphamode(SDL_Texture *texture_id, const render_color *color) +void renderer_sdl1::set_coloralphamode(SDL_Texture *texture_id, const render_color *color) { UINT32 sr = (UINT32)(255.0f * color->r); UINT32 sg = (UINT32)(255.0f * color->g); @@ -426,7 +266,7 @@ void texture_info::render_quad(const render_primitive *prim, const int x, const //SDL_RenderCopyEx(m_renderer->m_sdl_renderer, m_texture_id, NULL, NULL, 0, NULL, SDL_FLIP_NONE); } -void sdl_info13::render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y) +void renderer_sdl1::render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y) { SDL_Rect target_rect; @@ -463,11 +303,10 @@ void sdl_info13::render_quad(texture_info *texture, const render_primitive *prim } } -int sdl_info13::RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat) +int renderer_sdl1::RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat) { int i; - SDL_Texture *texid; - for (i=0; fmt_support[i].format != 0; i++) + for (i = 0; fmt_support[i].format != 0; i++) { if (format == fmt_support[i].format) { @@ -477,7 +316,7 @@ int sdl_info13::RendererSupportsFormat(Uint32 format, Uint32 access, const char /* not tested yet */ fmt_support[i].format = format; fmt_support[i + 1].format = 0; - texid = SDL_CreateTexture(m_sdl_renderer, format, access, 16, 16); + SDL_Texture *texid = SDL_CreateTexture(m_sdl_renderer, format, access, 16, 16); if (texid) { fmt_support[i].status = 1; @@ -512,38 +351,24 @@ static void expand_copy_info(copy_info_t *list) { if (bi->bm_mask == BM_ALL) { - add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_NONE); - add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_ADD); - add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_MOD); - add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_BLEND); + 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(&blit_info[bi->src_fmt], bi, bi->bm_mask); + add_list(&s_blit_info[bi->src_fmt], bi, bi->bm_mask); } } static osd_renderer *drawsdl2_create(osd_window *window) { - if (!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(blit_info_default); - blit_info_initialized = true; - - } - return global_alloc(sdl_info13(window, osd_renderer::FLAG_NONE)); + return global_alloc(renderer_sdl1(window, osd_renderer::FLAG_NONE)); } // FIXME: machine only used to access options. -int drawsdl2_init(running_machine &machine, osd_draw_callbacks *callbacks) +int renderer_sdl1::init(running_machine &machine) { - // fill in the callbacks - callbacks->exit = drawsdl2_exit; - callbacks->create = drawsdl2_create; - osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n"); #if USE_OPENGL @@ -566,34 +391,6 @@ int drawsdl2_init(running_machine &machine, osd_draw_callbacks *callbacks) //============================================================ -// drawsdl_exit -//============================================================ - -static void drawsdl2_exit(void) -{ - int i; - copy_info_t *bi, *freeme; - if (blit_info_initialized) - { - for (i = 0; i <= SDL_TEXFORMAT_LAST; i++) - { - for (bi = blit_info[i]; bi != NULL; ) - { - 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); - freeme = bi; - bi = bi->next; - global_free(freeme); - } - blit_info[i] = NULL; - } - blit_info_initialized = false; - } -} - -//============================================================ // sdl_info::create //============================================================ @@ -627,7 +424,7 @@ static void drawsdl_show_info(struct SDL_RendererInfo *render_info) } -int sdl_info13::create() +int renderer_sdl1::create() { // create renderer @@ -659,7 +456,7 @@ int sdl_info13::create() m_blittimer = 3; //SDL_RenderPresent(m_sdl_renderer); - osd_printf_verbose("Leave sdl_info13::create\n"); + osd_printf_verbose("Leave renderer_sdl1::create\n"); struct SDL_RendererInfo render_info; @@ -671,22 +468,10 @@ int sdl_info13::create() //============================================================ -// sdl_info::destroy -//============================================================ - -void sdl_info13::destroy() -{ - destroy_all_textures(); - SDL_DestroyRenderer(m_sdl_renderer); - m_sdl_renderer = NULL; -} - - -//============================================================ // drawsdl_xy_to_render_target //============================================================ -int sdl_info13::xy_to_render_target(int x, int y, int *xt, int *yt) +int renderer_sdl1::xy_to_render_target(int x, int y, int *xt, int *yt) { *xt = x - m_last_hofs; *yt = y - m_last_vofs; @@ -701,7 +486,7 @@ int sdl_info13::xy_to_render_target(int x, int y, int *xt, int *yt) // drawsdl_destroy_all_textures //============================================================ -void sdl_info13::destroy_all_textures() +void renderer_sdl1::destroy_all_textures() { if(window().m_primlist) { @@ -717,7 +502,7 @@ void sdl_info13::destroy_all_textures() // sdl_info::draw //============================================================ -int sdl_info13::draw(int update) +int renderer_sdl1::draw(int update) { render_primitive *prim; texture_info *texture=NULL; @@ -896,7 +681,7 @@ bool texture_info::matches(const render_primitive &prim, const quad_setup_data & // texture_create //============================================================ -texture_info::texture_info(sdl_info13 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, UINT32 flags) +texture_info::texture_info(renderer_sdl1 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, UINT32 flags) { // fill in the core data m_renderer = renderer; @@ -1084,7 +869,7 @@ void quad_setup_data::compute(const render_primitive &prim, const int prescale) // texture_find //============================================================ -texture_info *sdl_info13::texture_find(const render_primitive &prim, const quad_setup_data &setup) +texture_info *renderer_sdl1::texture_find(const render_primitive &prim, const quad_setup_data &setup) { HashT texhash = texture_compute_hash(prim.texture, prim.flags); texture_info *texture; @@ -1121,7 +906,7 @@ texture_info *sdl_info13::texture_find(const render_primitive &prim, const quad_ // texture_update //============================================================ -texture_info * sdl_info13::texture_update(const render_primitive &prim) +texture_info * renderer_sdl3::texture_update(const render_primitive &prim) { quad_setup_data setup; texture_info *texture; @@ -1150,3 +935,15 @@ texture_info * sdl_info13::texture_update(const render_primitive &prim) } return texture; } + +render_primitive_list *renderer_sdl13::get_primitives() +{ + osd_dim nd = window().blit_surface_size(); + if (nd != m_blit_dim) + { + m_blit_dim = nd; + notify_changed(); + } + window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect()); + return &window().target()->get_primitives(); +} diff --git a/src/osd/modules/render/draw13.h b/src/osd/modules/render/draw13.h new file mode 100644 index 00000000000..584820ab2d9 --- /dev/null +++ b/src/osd/modules/render/draw13.h @@ -0,0 +1,224 @@ +// 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 +// +//============================================================ + +#pragma once + +#ifndef __DRAW13__ +#define __DRAW13__ + +// OSD headers +#ifndef OSD_WINDOWS +#include "osdsdl.h" +#include "window.h" +#else +#include "../windows/window.h" +typedef UINT64 HashT; +#endif + +// standard SDL headers +#include "sdl/sdlinc.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 dudx, dvdx, dudy, dvdy; + INT32 startu, startv; + INT32 rotwidth, rotheight; +}; + +//============================================================ +// Textures +//============================================================ + +class renderer_sdl1; +struct copy_info_t; + +/* texture_info holds information about a texture */ +class texture_info +{ + friend class simple_list<texture_info>; +public: + texture_info(renderer_sdl1 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const UINT32 flags); + ~texture_info(); + + void set_data(const render_texinfo &texsource, const UINT32 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 flags() const { return m_flags; } + // FIXME: + bool is_pixels_owned() const; + +private: + Uint32 m_sdl_access; + renderer_sdl1 * m_renderer; + render_texinfo m_texinfo; // copy of the texture info + HashT m_hash; // hash value for the texture (must be >= pointer size) + UINT32 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 pixel_count; + INT64 time; + int samples; + int perf; + /* list */ + copy_info_t *next; +}; + +/* sdl_info is the information about SDL for the current screen */ +class renderer_sdl1 : public osd_renderer +{ +public: + renderer_sdl1(osd_window *window, int extra_flags); + + virtual ~renderer_sdl1() + { + destroy_all_textures(); + SDL_DestroyRenderer(m_sdl_renderer); + m_sdl_renderer = nullptr; + + if (s_blit_info_initialized) + { + for (int i = 0; i <= SDL_TEXFORMAT_LAST; i++) + { + for (copy_info_t *bi = s_blit_info[i]; bi != NULL; ) + { + 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; + global_free(freeme); + } + s_blit_info[i] = NULL; + } + s_blit_info_initialized = false; + } + } + + virtual int create() override; + virtual int init(running_machine &machine) 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; + +private: + void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y); + void set_coloralphamode(SDL_Texture *texture_id, const render_color *color); + + 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 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 m_last_blit_time; + INT64 m_last_blit_pixels; + + static copy_info_t* s_blit_info[SDL_TEXFORMAT_LAST+1]; + static bool s_blit_info_initialized; + static const copy_info_t s_blit_info_default[]; +}; + +#endif // __DRAW13__
\ No newline at end of file diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 9d751c9f816..73c4b336434 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -31,6 +31,11 @@ #include <algorithm> #include "drawbgfx.h" +#include "bgfx/texturemanager.h" +#include "bgfx/shadermanager.h" +#include "bgfx/effectmanager.h" +#include "bgfx/effect.h" +#include "bgfx/texture.h" //============================================================ // DEBUGGING @@ -57,50 +62,8 @@ //============================================================ -// PROTOTYPES -//============================================================ - -// core functions -static void drawbgfx_exit(void); - -//============================================================ -// drawnone_create -//============================================================ - -static osd_renderer *drawbgfx_create(osd_window *window) -{ - return global_alloc(renderer_bgfx(window)); -} - -//============================================================ -// drawbgfx_init -//============================================================ - -int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks) -{ - // fill in the callbacks - //memset(callbacks, 0, sizeof(*callbacks)); - callbacks->exit = drawbgfx_exit; - callbacks->create = drawbgfx_create; - - return 0; -} - -//============================================================ -// drawbgfx_exit -//============================================================ - -static void drawbgfx_exit(void) -{ - // Shutdown bgfx. - bgfx::shutdown(); -} - -//============================================================ // renderer_bgfx::create //============================================================ -bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName); - #ifdef OSD_SDL static void* sdlNativeWindowHandle(SDL_Window* _window) @@ -147,26 +110,32 @@ int renderer_bgfx::create() else { #ifdef OSD_WINDOWS - fbh = bgfx::createFrameBuffer(window().m_hwnd, wdim.width(), wdim.height()); + m_framebuffer = bgfx::createFrameBuffer(window().m_hwnd, wdim.width(), wdim.height()); #else - fbh = bgfx::createFrameBuffer(sdlNativeWindowHandle(window().sdl_window()), wdim.width(), wdim.height()); + m_framebuffer = bgfx::createFrameBuffer(sdlNativeWindowHandle(window().sdl_window()), wdim.width(), wdim.height()); #endif bgfx::touch(window().m_index); } ScreenVertex::init(); + m_textures = new texture_manager(); + m_shaders = new shader_manager(); + m_effects = new effect_manager(*m_shaders); + // Create program from shaders. - m_progQuad = loadProgram("vs_quad", "fs_quad"); - m_progQuadTexture = loadProgram("vs_quad_texture", "fs_quad_texture"); - m_s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1); + m_gui_effect[0] = m_effects->effect("gui_opaque"); + m_gui_effect[1] = m_effects->effect("gui_blend"); + m_gui_effect[2] = m_effects->effect("gui_multiply"); + m_gui_effect[3] = m_effects->effect("gui_add"); - uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; - m_texture_cache = bgfx::createTexture2D(CACHE_SIZE, CACHE_SIZE, 1, bgfx::TextureFormat::RGBA8, flags); + m_screen_effect[0] = m_effects->effect("screen_opaque"); + m_screen_effect[1] = m_effects->effect("screen_blend"); + m_screen_effect[2] = m_effects->effect("screen_multiply"); + m_screen_effect[3] = m_effects->effect("screen_add"); - const bgfx::Memory* memory = bgfx::alloc(sizeof(uint32_t) * CACHE_SIZE * CACHE_SIZE); - memset(memory->data, 0, sizeof(uint32_t) * CACHE_SIZE * CACHE_SIZE); - bgfx::updateTexture2D(m_texture_cache, 0, 0, 0, CACHE_SIZE, CACHE_SIZE, memory, CACHE_SIZE * sizeof(uint32_t)); + uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; + m_texture_cache = m_textures->create_texture("#cache", bgfx::TextureFormat::RGBA8, CACHE_SIZE, CACHE_SIZE, nullptr, flags); memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16); m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white)); @@ -175,19 +144,22 @@ int renderer_bgfx::create() } //============================================================ -// drawbgfx_window_destroy +// destructor //============================================================ -void renderer_bgfx::destroy() +renderer_bgfx::~renderer_bgfx() { if (window().m_index > 0) { - bgfx::destroyFrameBuffer(fbh); + bgfx::destroyFrameBuffer(m_framebuffer); } - bgfx::destroyUniform(m_s_texColor); + // Cleanup. - bgfx::destroyProgram(m_progQuad); - bgfx::destroyProgram(m_progQuadTexture); + delete m_effects; + delete m_shaders; + delete m_textures; + + bgfx::shutdown(); } @@ -208,74 +180,6 @@ int renderer_bgfx::xy_to_render_target(int x, int y, int *xt, int *yt) } #endif -static const bgfx::Memory* loadMem(bx::FileReaderI* _reader, const char* _filePath) -{ - if (bx::open(_reader, _filePath)) - { - uint32_t size = (uint32_t)bx::getSize(_reader); - const bgfx::Memory* mem = bgfx::alloc(size + 1); - bx::read(_reader, mem->data, size); - bx::close(_reader); - mem->data[mem->size - 1] = '\0'; - return mem; - } - - return nullptr; -} -static bgfx::ShaderHandle loadShader(bx::FileReaderI* _reader, const char* _name) -{ - char filePath[512]; - - const char* shaderPath = "shaders/dx9/"; - - switch (bgfx::getRendererType()) - { - case bgfx::RendererType::Direct3D11: - case bgfx::RendererType::Direct3D12: - shaderPath = "shaders/dx11/"; - break; - - case bgfx::RendererType::OpenGL: - shaderPath = "shaders/glsl/"; - break; - - case bgfx::RendererType::Metal: - shaderPath = "shaders/metal/"; - break; - - case bgfx::RendererType::OpenGLES: - shaderPath = "shaders/gles/"; - break; - - default: - break; - } - - strcpy(filePath, shaderPath); - strcat(filePath, _name); - strcat(filePath, ".bin"); - - return bgfx::createShader(loadMem(_reader, filePath)); -} - -bgfx::ProgramHandle renderer_bgfx::loadProgram(bx::FileReaderI* _reader, const char* _vsName, const char* _fsName) -{ - bgfx::ShaderHandle vsh = loadShader(_reader, _vsName); - bgfx::ShaderHandle fsh = BGFX_INVALID_HANDLE; - if (nullptr != _fsName) - { - fsh = loadShader(_reader, _fsName); - } - - return bgfx::createProgram(vsh, fsh, true /* destroy shaders when program is destroyed */); -} -static auto s_fileReader = new bx::CrtFileReader; - -bgfx::ProgramHandle renderer_bgfx::loadProgram(const char* _vsName, const char* _fsName) -{ - return loadProgram(s_fileReader, _vsName, _fsName); -} - //============================================================ // drawbgfx_window_draw //============================================================ @@ -425,10 +329,10 @@ void renderer_bgfx::render_textured_quad(int view, render_primitive* prim, bgfx: bgfx::TextureHandle texture = bgfx::createTexture2D((uint16_t)prim->texture.width, (uint16_t)prim->texture.height, 1, bgfx::TextureFormat::RGBA8, texture_flags, mem); - bgfx::setTexture(0, m_s_texColor, texture); - - set_bgfx_state(PRIMFLAG_GET_BLENDMODE(prim->flags)); - bgfx::submit(view, m_progQuadTexture); + bgfx_effect** effects = PRIMFLAG_GET_SCREENTEX(prim->flags) ? m_screen_effect : m_gui_effect; + UINT32 blend = PRIMFLAG_GET_BLENDMODE(prim->flags); + bgfx::setTexture(0, effects[blend]->uniform("s_tex")->handle(), texture); + effects[blend]->submit(view); bgfx::destroyTexture(texture); } @@ -830,24 +734,27 @@ int renderer_bgfx::draw(int update) int height = wdim.height(); if (index == 0) { - if ((m_dimensions != osd_dim(width, height))) { + if ((m_dimensions != osd_dim(width, height))) + { bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); m_dimensions = osd_dim(width, height); } } - else { - if ((m_dimensions != osd_dim(width, height))) { + else + { + if ((m_dimensions != osd_dim(width, height))) + { bgfx::reset(window().m_main->get_size().width(), window().m_main->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE); - if (bgfx::isValid(fbh)) + if (bgfx::isValid(m_framebuffer)) { - bgfx::destroyFrameBuffer(fbh); + bgfx::destroyFrameBuffer(m_framebuffer); } #ifdef OSD_WINDOWS - fbh = bgfx::createFrameBuffer(window().m_hwnd, width, height); + m_framebuffer = bgfx::createFrameBuffer(window().m_hwnd, width, height); #else - fbh = bgfx::createFrameBuffer(sdlNativeWindowHandle(window().sdl_window()), width, height); + m_framebuffer = bgfx::createFrameBuffer(sdlNativeWindowHandle(window().sdl_window()), width, height); #endif - bgfx::setViewFrameBuffer(index, fbh); + bgfx::setViewFrameBuffer(index, m_framebuffer); m_dimensions = osd_dim(width, height); bgfx::setViewClear(index , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH @@ -860,7 +767,11 @@ int renderer_bgfx::draw(int update) return 0; } } - if (index != 0) bgfx::setViewFrameBuffer(index, fbh); + + if (index != 0) + { + bgfx::setViewFrameBuffer(index, m_framebuffer); + } bgfx::setViewSeq(index, true); bgfx::setViewRect(index, 0, 0, width, height); @@ -905,10 +816,9 @@ int renderer_bgfx::draw(int update) if (status != BUFFER_EMPTY) { - set_bgfx_state(blend); bgfx::setVertexBuffer(&buffer); - bgfx::setTexture(0, m_s_texColor, m_texture_cache); - bgfx::submit(index, m_progQuadTexture); + bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->handle()); + m_gui_effect[blend]->submit(index); } if (status != BUFFER_DONE && status != BUFFER_PRE_FLUSH) @@ -1051,7 +961,7 @@ void renderer_bgfx::process_atlas_packs(std::vector<std::vector<rectangle_packer } m_hash_to_entry[rect.hash()] = rect; const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(rect.format(), rect.width(), rect.height(), rect.rowpixels(), rect.palette(), rect.base()); - bgfx::updateTexture2D(m_texture_cache, 0, rect.x(), rect.y(), rect.width(), rect.height(), mem); + bgfx::updateTexture2D(m_texture_cache->handle(), 0, rect.x(), rect.y(), rect.width(), rect.height(), mem); } } } diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h index 86619eab718..67064b686f8 100644 --- a/src/osd/modules/render/drawbgfx.h +++ b/src/osd/modules/render/drawbgfx.h @@ -3,11 +3,19 @@ #ifndef __RENDER_BGFX__ #define __RENDER_BGFX__ +#include <bgfx/bgfx.h> + #include <map> #include <vector> #include "binpacker.h" +class texture_manager; +class shader_manager; +class effect_manager; +class bgfx_texture; +class bgfx_effect; + /* sdl_info is the information about SDL for the current screen */ class renderer_bgfx : public osd_renderer { @@ -17,8 +25,10 @@ public: , m_dimensions(0, 0) { } + virtual ~renderer_bgfx(); virtual int create() override; + virtual int init(running_machine &machine) override { return 0; } virtual int draw(const int update) override; #ifdef OSD_SDL virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override; @@ -27,7 +37,6 @@ public: virtual void record() override { } virtual void toggle_fsfx() override { } #endif - virtual void destroy() override; virtual render_primitive_list *get_primitives() override { osd_dim wdim = window().get_size(); @@ -83,18 +92,18 @@ private: const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base); UINT32 get_texture_hash(render_primitive *prim); - bgfx::ProgramHandle loadProgram(bx::FileReaderI* _reader, const char* _vsName, const char* _fsName); - bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName); - - bgfx::ProgramHandle m_progQuad; - bgfx::ProgramHandle m_progQuadTexture; - bgfx::UniformHandle m_s_texColor; - bgfx::FrameBufferHandle fbh; - bgfx::TextureHandle m_texture_cache; + bgfx::FrameBufferHandle m_framebuffer; + bgfx_texture* m_texture_cache; // Original display_mode osd_dim m_dimensions; + texture_manager* m_textures; + shader_manager* m_shaders; + effect_manager* m_effects; + bgfx_effect* m_gui_effect[4]; + bgfx_effect* m_screen_effect[4]; + std::map<UINT32, rectangle_packer::packed_rectangle> m_hash_to_entry; std::vector<rectangle_packer::packable_rectangle> m_texinfo; rectangle_packer m_packer; diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp index b8730696a54..83f94864495 100644 --- a/src/osd/modules/render/drawd3d.cpp +++ b/src/osd/modules/render/drawd3d.cpp @@ -14,16 +14,6 @@ // Windows NT shipped with DirectX 3.0a // Windows 95 shipped with DirectX 2 -// standard windows headers -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <tchar.h> -#include <mmsystem.h> -#include <d3d9.h> -#include <d3dx9.h> -#include <math.h> -#undef interface - // MAME headers #include "emu.h" #include "render.h" @@ -33,11 +23,11 @@ #include "aviio.h" // MAMEOS headers -#include "modules/render/d3d/d3dintf.h" #include "winmain.h" #include "window.h" -#include "modules/render/d3d/d3dcomm.h" #include "drawd3d.h" +#include "modules/render/d3d/d3dhlsl.h" +#include "d3dtarget.h" //============================================================ @@ -109,7 +99,7 @@ static inline BOOL GetClientRectExceptMenu(HWND hWnd, PRECT pRect, BOOL fullscre last_menu = menu; last_rect = *pRect; - SetMenu(hWnd, NULL); + SetMenu(hWnd, nullptr); result = GetClientRect(hWnd, &cached_rect); SetMenu(hWnd, menu); } @@ -165,26 +155,21 @@ static inline UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr) // drawd3d_init //============================================================ -static d3d::base * d3dintf; // FIX ME +static d3d_base * d3dintf; // FIX ME //============================================================ // PROTOTYPES //============================================================ -// core functions -static void drawd3d_exit(void); - - //============================================================ // drawd3d_window_init //============================================================ -int d3d::renderer::create() +int renderer_d3d9::create() { if (!initialize()) { - destroy(); osd_printf_error("Unable to initialize Direct3D.\n"); return 1; } @@ -192,50 +177,27 @@ int d3d::renderer::create() return 0; } - -//============================================================ -// drawd3d_exit -//============================================================ - -static void drawd3d_exit(void) -{ - if (d3dintf != NULL) - (*d3dintf->d3d.release)(d3dintf); -} - -void d3d::renderer::toggle_fsfx() +void renderer_d3d9::toggle_fsfx() { set_restarting(true); } -void d3d::renderer::record() +void renderer_d3d9::record() { get_shaders()->window_record(); } -void d3d::renderer::save() +void renderer_d3d9::save() { get_shaders()->window_save(); } //============================================================ -// drawd3d_window_destroy -//============================================================ - -void d3d::renderer::destroy() -{ - if (get_shaders() != NULL && get_shaders()->recording()) - get_shaders()->window_record(); - -} - - -//============================================================ // drawd3d_window_get_primitives //============================================================ -render_primitive_list *d3d::renderer::get_primitives() +render_primitive_list *renderer_d3d9::get_primitives() { RECT client; @@ -245,7 +207,7 @@ render_primitive_list *d3d::renderer::get_primitives() window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect()); window().target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh()); } - if (m_shaders != NULL) + if (m_shaders != nullptr) { window().target()->set_transform_primitives(!m_shaders->enabled()); } @@ -257,29 +219,18 @@ render_primitive_list *d3d::renderer::get_primitives() // drawnone_create //============================================================ -static osd_renderer *drawd3d_create(osd_window *window) -{ - return global_alloc(d3d::renderer(window)); -} - -int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks) +int renderer_d3d9::init(running_machine &machine) { - d3dintf = NULL; - // Use Direct3D9 - d3dintf = d3d::drawd3d9_init(); + d3dintf = drawd3d9_init(); // if we failed, note the error - if (d3dintf == NULL) + if (d3dintf == nullptr) { osd_printf_error("Unable to initialize Direct3D.\n"); return 1; } - // fill in the callbacks - memset(callbacks, 0, sizeof(*callbacks)); - callbacks->exit = drawd3d_exit; - callbacks->create = drawd3d_create; return 0; } @@ -288,7 +239,7 @@ int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks) // drawd3d_window_draw //============================================================ -int d3d::renderer::draw(const int update) +int renderer_d3d9::draw(const int update) { int check = pre_window_draw_check(); if (check >= 0) @@ -301,21 +252,19 @@ int d3d::renderer::draw(const int update) return 0; } -namespace d3d -{ -void renderer::set_texture(texture_info *texture) +void renderer_d3d9::set_texture(texture_info *texture) { if (texture != m_last_texture) { m_last_texture = texture; - m_last_texture_flags = (texture == NULL ? 0 : texture->get_flags()); - HRESULT result = (*d3dintf->device.set_texture)(m_device, 0, (texture == NULL) ? get_default_texture()->get_finaltex() : texture->get_finaltex()); + m_last_texture_flags = (texture == nullptr ? 0 : texture->get_flags()); + HRESULT result = (*d3dintf->device.set_texture)(m_device, 0, (texture == nullptr) ? get_default_texture()->get_finaltex() : texture->get_finaltex()); m_shaders->set_texture(texture); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result); } } -void renderer::set_filter(int filter) +void renderer_d3d9::set_filter(int filter) { if (filter != m_last_filter) { @@ -331,7 +280,7 @@ void renderer::set_filter(int filter) } } -void renderer::set_wrap(D3DTEXTUREADDRESS wrap) +void renderer_d3d9::set_wrap(unsigned int wrap) { if (wrap != m_last_wrap) { @@ -347,7 +296,7 @@ void renderer::set_wrap(D3DTEXTUREADDRESS wrap) } } -void renderer::set_modmode(DWORD modmode) +void renderer_d3d9::set_modmode(int modmode) { if (modmode != m_last_modmode) { @@ -359,7 +308,7 @@ void renderer::set_modmode(DWORD modmode) } } -void renderer::set_blendmode(int blendmode) +void renderer_d3d9::set_blendmode(int blendmode) { int blendenable; int blendop; @@ -406,7 +355,7 @@ void renderer::set_blendmode(int blendmode) } } -void renderer::reset_render_states() +void renderer_d3d9::reset_render_states() { // this ensures subsequent calls to the above setters will force-update the data m_last_texture = (texture_info *)~0; @@ -418,13 +367,13 @@ void renderer::reset_render_states() m_last_wrap = (D3DTEXTUREADDRESS)-1; } -texture_manager::texture_manager(renderer *d3d) +d3d_texture_manager::d3d_texture_manager(renderer_d3d9 *d3d) { m_renderer = d3d; - m_texlist = NULL; - m_vector_texture = NULL; - m_default_texture = NULL; + m_texlist = nullptr; + m_vector_texture = nullptr; + m_default_texture = nullptr; // check for dynamic texture support DWORD tempcaps; @@ -466,20 +415,20 @@ texture_manager::texture_manager(renderer *d3d) osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height); } -texture_manager::~texture_manager() +d3d_texture_manager::~d3d_texture_manager() { } -void texture_manager::create_resources() +void d3d_texture_manager::create_resources() { // experimental: load a PNG to use for vector rendering; it is treated // as a brightness map emu_file file(m_renderer->window().machine().options().art_path(), OPEN_FLAG_READ); - render_load_png(m_vector_bitmap, file, NULL, "vector.png"); + render_load_png(m_vector_bitmap, file, nullptr, "vector.png"); if (m_vector_bitmap.valid()) { m_vector_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff)); - render_load_png(m_vector_bitmap, file, NULL, "vector.png", true); + render_load_png(m_vector_bitmap, file, nullptr, "vector.png", true); } m_default_bitmap.allocate(8, 8); @@ -494,7 +443,7 @@ void texture_manager::create_resources() texture.rowpixels = m_default_bitmap.rowpixels(); texture.width = m_default_bitmap.width(); texture.height = m_default_bitmap.height(); - texture.palette = NULL; + texture.palette = nullptr; texture.seqid = 0; // now create it @@ -511,7 +460,7 @@ void texture_manager::create_resources() texture.rowpixels = m_vector_bitmap.rowpixels(); texture.width = m_vector_bitmap.width(); texture.height = m_vector_bitmap.height(); - texture.palette = NULL; + texture.palette = nullptr; texture.seqid = 0; // now create it @@ -519,17 +468,17 @@ void texture_manager::create_resources() } } -void texture_manager::delete_resources() +void d3d_texture_manager::delete_resources() { // is part of m_texlist and will be free'd there //global_free(m_default_texture); - m_default_texture = NULL; + m_default_texture = nullptr; //global_free(m_vector_texture); - m_vector_texture = NULL; + m_vector_texture = nullptr; // free all textures - while (m_texlist != NULL) + while (m_texlist != nullptr) { texture_info *tex = m_texlist; m_texlist = tex->get_next(); @@ -537,18 +486,18 @@ void texture_manager::delete_resources() } } -UINT32 texture_manager::texture_compute_hash(const render_texinfo *texture, UINT32 flags) +UINT32 d3d_texture_manager::texture_compute_hash(const render_texinfo *texture, UINT32 flags) { return (FPTR)texture->base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)); } -texture_info *texture_manager::find_texinfo(const render_texinfo *texinfo, UINT32 flags) +texture_info *d3d_texture_manager::find_texinfo(const render_texinfo *texinfo, UINT32 flags) { UINT32 hash = texture_compute_hash(texinfo, flags); texture_info *texture; // find a match - for (texture = m_renderer->get_texture_manager()->get_texlist(); texture != NULL; texture = texture->get_next()) + for (texture = m_renderer->get_texture_manager()->get_texlist(); texture != nullptr; texture = texture->get_next()) { UINT32 test_screen = (UINT32)texture->get_texinfo().osddata >> 1; UINT32 test_page = (UINT32)texture->get_texinfo().osddata & 1; @@ -568,7 +517,7 @@ texture_info *texture_manager::find_texinfo(const render_texinfo *texinfo, UINT3 // Reject a texture if it belongs to an out-of-date render target, so as to cause the HLSL system to re-cache if (m_renderer->get_shaders()->enabled() && texinfo->width != 0 && texinfo->height != 0 && (flags & PRIMFLAG_SCREENTEX_MASK) != 0) { - if (m_renderer->get_shaders()->find_render_target(texture) != NULL) + if (m_renderer->get_shaders()->find_render_target(texture) != nullptr) { return texture; } @@ -585,13 +534,13 @@ texture_info *texture_manager::find_texinfo(const render_texinfo *texinfo, UINT3 { if (texinfo->width == 0 || texinfo->height == 0) { - return NULL; + return nullptr; } UINT32 prim_screen = texinfo->osddata >> 1; UINT32 prim_page = texinfo->osddata & 1; - for (texture = m_renderer->get_texture_manager()->get_texlist(); texture != NULL; texture = texture->get_next()) + for (texture = m_renderer->get_texture_manager()->get_texlist(); texture != nullptr; texture = texture->get_next()) { UINT32 test_screen = texture->get_texinfo().osddata >> 1; UINT32 test_page = texture->get_texinfo().osddata & 1; @@ -612,18 +561,18 @@ texture_info *texture_manager::find_texinfo(const render_texinfo *texinfo, UINT3 } } - return NULL; + return nullptr; } -renderer::renderer(osd_window *window) - : osd_renderer(window, FLAG_NONE), m_adapter(0), m_width(0), m_height(0), m_refresh(0), m_create_error_count(0), m_device(NULL), m_gamma_supported(0), m_pixformat(), - m_vertexbuf(NULL), m_lockedbuf(NULL), m_numverts(0), m_vectorbatch(NULL), m_batchindex(0), m_numpolys(0), m_restarting(false), m_mod2x_supported(0), m_mod4x_supported(0), - m_screen_format(), m_last_texture(NULL), m_last_texture_flags(0), m_last_blendenable(0), m_last_blendop(0), m_last_blendsrc(0), m_last_blenddst(0), m_last_filter(0), - m_last_wrap(), m_last_modmode(0), m_hlsl_buf(NULL), m_shaders(NULL), m_shaders_options(NULL), m_texture_manager(NULL), m_line_count(0) +renderer_d3d9::renderer_d3d9(osd_window *window) + : osd_renderer(window, FLAG_NONE), m_adapter(0), m_width(0), m_height(0), m_refresh(0), m_create_error_count(0), m_device(nullptr), m_gamma_supported(0), m_pixformat(), + m_vertexbuf(nullptr), m_lockedbuf(nullptr), m_numverts(0), m_vectorbatch(nullptr), m_batchindex(0), m_numpolys(0), m_restarting(false), m_mod2x_supported(0), m_mod4x_supported(0), + m_screen_format(), m_last_texture(nullptr), m_last_texture_flags(0), m_last_blendenable(0), m_last_blendop(0), m_last_blendsrc(0), m_last_blenddst(0), m_last_filter(0), + m_last_wrap(), m_last_modmode(0), m_hlsl_buf(nullptr), m_shaders(nullptr), m_shaders_options(nullptr), m_texture_manager(nullptr), m_line_count(0) { } -int renderer::initialize() +int renderer_d3d9::initialize() { // configure the adapter for the mode we want if (config_adapter_mode()) @@ -636,7 +585,7 @@ int renderer::initialize() return true; } -int renderer::pre_window_draw_check() +int renderer_d3d9::pre_window_draw_check() { // if we're in the middle of resizing, leave things alone if (window().m_resize_state == RESIZE_STATE_RESIZING) @@ -651,7 +600,7 @@ int renderer::pre_window_draw_check() } // if we have a device, check the cooperative level - if (m_device != NULL) + if (m_device != nullptr) { if (device_test_cooperative()) { @@ -660,28 +609,28 @@ int renderer::pre_window_draw_check() } // in window mode, we need to track the window size - if (!window().fullscreen() || m_device == NULL) + if (!window().fullscreen() || m_device == nullptr) { // if the size changes, skip this update since the render target will be out of date if (update_window_size()) return 0; // if we have no device, after updating the size, return an error so GDI can try - if (m_device == NULL) + if (m_device == nullptr) return 1; } return -1; } -void texture_manager::update_textures() +void d3d_texture_manager::update_textures() { - for (render_primitive *prim = m_renderer->window().m_primlist->first(); prim != NULL; prim = prim->next()) + for (render_primitive *prim = m_renderer->window().m_primlist->first(); prim != nullptr; prim = prim->next()) { - if (prim->texture.base != NULL) + if (prim->texture.base != nullptr) { texture_info *texture = find_texinfo(&prim->texture, prim->flags); - if (texture == NULL) + if (texture == nullptr) { // if there isn't one, create a new texture global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags)); @@ -706,9 +655,9 @@ void texture_manager::update_textures() } } -void renderer::begin_frame() +void renderer_d3d9::begin_frame() { - HRESULT result = (*d3dintf->device.clear)(m_device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); + HRESULT result = (*d3dintf->device.clear)(m_device, 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); m_shaders->begin_frame(); @@ -723,7 +672,7 @@ void renderer::begin_frame() result = (*d3dintf->device.begin_scene)(m_device); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result); - m_lockedbuf = NULL; + m_lockedbuf = nullptr; if(m_shaders->enabled()) { @@ -734,15 +683,15 @@ void renderer::begin_frame() m_line_count = 0; // loop over primitives - for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next()) + for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags)) m_line_count++; } -void renderer::process_primitives() +void renderer_d3d9::process_primitives() { // Rotating index for vector time offsets - for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next()) + for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) { switch (prim->type) { @@ -770,7 +719,7 @@ void renderer::process_primitives() } } -void renderer::end_frame() +void renderer_d3d9::end_frame() { window().m_primlist->release_lock(); @@ -784,7 +733,7 @@ void renderer::end_frame() if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result); // present the current buffers - result = (*d3dintf->device.present)(m_device, NULL, NULL, NULL, NULL, 0); + result = (*d3dintf->device.present)(m_device, nullptr, nullptr, nullptr, nullptr, 0); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device present call\n", (int)result); } @@ -792,10 +741,10 @@ void renderer::end_frame() // device_create //============================================================ -int renderer::device_create(HWND device_hwnd) +int renderer_d3d9::device_create(HWND device_hwnd) { // if a device exists, free it - if (m_device != NULL) + if (m_device != nullptr) { device_delete(); } @@ -820,7 +769,7 @@ int renderer::device_create(HWND device_hwnd) return 1; } - m_texture_manager = global_alloc(texture_manager(this)); + m_texture_manager = global_alloc(d3d_texture_manager(this)); try_again: // try for XRGB first @@ -913,7 +862,7 @@ try_again: } // create shader options only once - if (m_shaders_options == NULL) + if (m_shaders_options == nullptr) { m_shaders_options = (hlsl_options*)global_alloc_clear<hlsl_options>(); m_shaders_options->params_init = false; @@ -936,7 +885,7 @@ try_again: // device_create_resources //============================================================ -int renderer::device_create_resources() +int renderer_d3d9::device_create_resources() { // allocate a vertex buffer to use HRESULT result = (*d3dintf->device.create_vertex_buffer)(m_device, @@ -988,8 +937,8 @@ int renderer::device_create_resources() reset_render_states(); // clear the buffer - result = (*d3dintf->device.clear)(m_device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - result = (*d3dintf->device.present)(m_device, NULL, NULL, NULL, NULL, 0); + result = (*d3dintf->device.clear)(m_device, 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); + result = (*d3dintf->device.present)(m_device, nullptr, nullptr, nullptr, nullptr, 0); m_texture_manager->create_resources(); @@ -1001,20 +950,26 @@ int renderer::device_create_resources() // device_delete //============================================================ -renderer::~renderer() +renderer_d3d9::~renderer_d3d9() { + if (get_shaders() != nullptr && get_shaders()->recording()) + get_shaders()->window_record(); + + if (d3dintf != nullptr) + (*d3dintf->d3d.release)(d3dintf); + device_delete(); - if (m_shaders_options != NULL) + if (m_shaders_options != nullptr) { global_free(m_shaders_options); - m_shaders_options = NULL; + m_shaders_options = nullptr; } } -void renderer::device_delete() +void renderer_d3d9::device_delete() { - if (m_shaders != NULL) + if (m_shaders != nullptr) { // free our effects m_shaders->delete_resources(false); @@ -1026,18 +981,18 @@ void renderer::device_delete() // free our base resources device_delete_resources(); - if (m_texture_manager != NULL) + if (m_texture_manager != nullptr) { global_free(m_texture_manager); - m_texture_manager = NULL; + m_texture_manager = nullptr; } // free the device itself - if (m_device != NULL) + if (m_device != nullptr) { (*d3dintf->device.reset)(m_device, &m_presentation); (*d3dintf->device.release)(m_device); - m_device = NULL; + m_device = nullptr; } } @@ -1046,18 +1001,18 @@ void renderer::device_delete() // device_delete_resources //============================================================ -void renderer::device_delete_resources() +void renderer_d3d9::device_delete_resources() { - if (m_texture_manager != NULL) + if (m_texture_manager != nullptr) { m_texture_manager->delete_resources(); } // free the vertex buffer - if (m_vertexbuf != NULL) + if (m_vertexbuf != nullptr) { (*d3dintf->vertexbuf.release)(m_vertexbuf); - m_vertexbuf = NULL; + m_vertexbuf = nullptr; } } @@ -1066,7 +1021,7 @@ void renderer::device_delete_resources() // device_verify_caps //============================================================ -int renderer::device_verify_caps() +int renderer_d3d9::device_verify_caps() { int retval = 0; @@ -1132,7 +1087,7 @@ int renderer::device_verify_caps() // device_test_cooperative //============================================================ -int renderer::device_test_cooperative() +int renderer_d3d9::device_test_cooperative() { // check our current status; if we lost the device, punt to GDI HRESULT result = (*d3dintf->device.test_cooperative_level)(m_device); @@ -1179,7 +1134,7 @@ int renderer::device_test_cooperative() // config_adapter_mode //============================================================ -int renderer::config_adapter_mode() +int renderer_d3d9::config_adapter_mode() { adapter_identifier identifier; @@ -1254,7 +1209,7 @@ int renderer::config_adapter_mode() // get_adapter_for_monitor //============================================================ -int renderer::get_adapter_for_monitor() +int renderer_d3d9::get_adapter_for_monitor() { int maxadapter = (*d3dintf->d3d.get_adapter_count)(d3dintf); @@ -1280,7 +1235,7 @@ int renderer::get_adapter_for_monitor() // pick_best_mode //============================================================ -void renderer::pick_best_mode() +void renderer_d3d9::pick_best_mode() { double target_refresh = 60.0; INT32 minwidth, minheight; @@ -1288,7 +1243,7 @@ void renderer::pick_best_mode() // determine the refresh rate of the primary screen const screen_device *primary_screen = window().machine().config().first_screen(); - if (primary_screen != NULL) + if (primary_screen != nullptr) { target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds()); } @@ -1368,14 +1323,14 @@ void renderer::pick_best_mode() // update_window_size //============================================================ -int renderer::update_window_size() +int renderer_d3d9::update_window_size() { // get the current window bounds RECT client; GetClientRectExceptMenu(window().m_hwnd, &client, window().fullscreen()); // if we have a device and matching width/height, nothing to do - if (m_device != NULL && rect_width(&client) == m_width && rect_height(&client) == m_height) + if (m_device != nullptr && rect_width(&client) == m_width && rect_height(&client) == m_height) { // clear out any pending resizing if the area didn't change if (window().m_resize_state == RESIZE_STATE_PENDING) @@ -1403,7 +1358,7 @@ int renderer::update_window_size() // batch_vectors //============================================================ -void renderer::batch_vectors() +void renderer_d3d9::batch_vectors() { windows_options &options = downcast<windows_options &>(window().machine().options()); @@ -1415,7 +1370,7 @@ void renderer::batch_vectors() int line_index = 0; float period = options.screen_vector_time_period(); UINT32 cached_flags = 0; - for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next()) + for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) { switch (prim->type) { @@ -1455,7 +1410,7 @@ void renderer::batch_vectors() m_line_count = 0; } -void renderer::batch_vector(const render_primitive *prim, float line_time) +void renderer_d3d9::batch_vector(const render_primitive *prim, float line_time) { // compute the effective width based on the direction of the line float effwidth = prim->width; @@ -1473,7 +1428,7 @@ void renderer::batch_vector(const render_primitive *prim, float line_time) step->weight != 0; step++) { // get a pointer to the vertex buffer - if (m_vectorbatch == NULL) + if (m_vectorbatch == nullptr) return; m_vectorbatch[m_batchindex + 0].x = b0.x0 + step->xoffs; @@ -1557,7 +1512,7 @@ void renderer::batch_vector(const render_primitive *prim, float line_time) // draw_line //============================================================ -void renderer::draw_line(const render_primitive *prim) +void renderer_d3d9::draw_line(const render_primitive *prim) { // compute the effective width based on the direction of the line float effwidth = prim->width; @@ -1576,7 +1531,7 @@ void renderer::draw_line(const render_primitive *prim) { // get a pointer to the vertex buffer vertex *vertex = mesh_alloc(4); - if (vertex == NULL) + if (vertex == nullptr) return; // rotate the unit vector by 135 degrees and add to point 0 @@ -1641,18 +1596,18 @@ void renderer::draw_line(const render_primitive *prim) // draw_quad //============================================================ -void renderer::draw_quad(const render_primitive *prim) +void renderer_d3d9::draw_quad(const render_primitive *prim) { texture_info *texture = m_texture_manager->find_texinfo(&prim->texture, prim->flags); - if (texture == NULL) + if (texture == nullptr) { texture = get_default_texture(); } // get a pointer to the vertex buffer vertex *vertex = mesh_alloc(4); - if (vertex == NULL) + if (vertex == nullptr) return; // fill in the vertexes clockwise @@ -1668,7 +1623,7 @@ void renderer::draw_quad(const render_primitive *prim) float height = prim->bounds.y1 - prim->bounds.y0; // set the texture coordinates - if(texture != NULL) + if(texture != nullptr) { vec2f& start = texture->get_uvstart(); vec2f& stop = texture->get_uvstop(); @@ -1689,7 +1644,7 @@ void renderer::draw_quad(const render_primitive *prim) INT32 b = (INT32)(prim->color.b * 255.0f); INT32 a = (INT32)(prim->color.a * 255.0f); DWORD modmode = D3DTOP_MODULATE; - if (texture != NULL) + if (texture != nullptr) { if (m_mod2x_supported && (r > 255 || g > 255 || b > 255)) { @@ -1755,12 +1710,12 @@ void poly_info::init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts, // primitive_alloc //============================================================ -vertex *renderer::mesh_alloc(int numverts) +vertex *renderer_d3d9::mesh_alloc(int numverts) { HRESULT result; // if we're going to overflow, flush - if (m_lockedbuf != NULL && m_numverts + numverts >= VERTEX_BUFFER_SIZE) + if (m_lockedbuf != nullptr && m_numverts + numverts >= VERTEX_BUFFER_SIZE) { primitive_flush_pending(); @@ -1772,21 +1727,21 @@ vertex *renderer::mesh_alloc(int numverts) } // if we don't have a lock, grab it now - if (m_lockedbuf == NULL) + if (m_lockedbuf == nullptr) { result = (*d3dintf->vertexbuf.lock)(m_vertexbuf, 0, 0, (VOID **)&m_lockedbuf, D3DLOCK_DISCARD); if (result != D3D_OK) - return NULL; + return nullptr; } // if we already have the lock and enough room, just return a pointer - if (m_lockedbuf != NULL && m_numverts + numverts < VERTEX_BUFFER_SIZE) + if (m_lockedbuf != nullptr && m_numverts + numverts < VERTEX_BUFFER_SIZE) { int oldverts = m_numverts; m_numverts += numverts; return &m_lockedbuf[oldverts]; } - return NULL; + return nullptr; } @@ -1794,10 +1749,10 @@ vertex *renderer::mesh_alloc(int numverts) // primitive_flush_pending //============================================================ -void renderer::primitive_flush_pending() +void renderer_d3d9::primitive_flush_pending() { // ignore if we're not locked - if (m_lockedbuf == NULL) + if (m_lockedbuf == nullptr) { return; } @@ -1805,7 +1760,7 @@ void renderer::primitive_flush_pending() // unlock the buffer HRESULT result = (*d3dintf->vertexbuf.unlock)(m_vertexbuf); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result); - m_lockedbuf = NULL; + m_lockedbuf = nullptr; // set the stream result = (*d3dintf->device.set_stream_source)(m_device, 0, m_vertexbuf, sizeof(vertex)); @@ -1830,7 +1785,7 @@ void renderer::primitive_flush_pending() set_texture(texture); // set filtering if different - if (texture != NULL) + if (texture != nullptr) { newfilter = FALSE; if (PRIMFLAG_GET_SCREENTEX(flags)) @@ -1882,24 +1837,24 @@ void renderer::primitive_flush_pending() texture_info::~texture_info() { - if (m_d3dfinaltex != NULL) + if (m_d3dfinaltex != nullptr) { if (m_d3dtex == m_d3dfinaltex) { - m_d3dtex = NULL; + m_d3dtex = nullptr; } (*d3dintf->texture.release)(m_d3dfinaltex); - m_d3dfinaltex = NULL; + m_d3dfinaltex = nullptr; } - if (m_d3dtex != NULL) + if (m_d3dtex != nullptr) { (*d3dintf->texture.release)(m_d3dtex); - m_d3dtex = NULL; + m_d3dtex = nullptr; } - if (m_d3dsurface != NULL) + if (m_d3dsurface != nullptr) { (*d3dintf->surface.release)(m_d3dsurface); - m_d3dsurface = NULL; + m_d3dsurface = nullptr; } } @@ -1908,7 +1863,7 @@ texture_info::~texture_info() // texture_info constructor //============================================================ -texture_info::texture_info(texture_manager *manager, const render_texinfo* texsource, int prescale, UINT32 flags) +texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* texsource, int prescale, UINT32 flags) { HRESULT result; @@ -1921,9 +1876,9 @@ texture_info::texture_info(texture_manager *manager, const render_texinfo* texso m_xprescale = prescale; m_yprescale = prescale; - m_d3dtex = NULL; - m_d3dsurface = NULL; - m_d3dfinaltex = NULL; + m_d3dtex = nullptr; + m_d3dsurface = nullptr; + m_d3dfinaltex = nullptr; // compute the size compute_size(texsource->width, texsource->height); @@ -2053,7 +2008,7 @@ texture_info::texture_info(texture_manager *manager, const render_texinfo* texso break; } (*d3dintf->texture.release)(m_d3dtex); - m_d3dtex = NULL; + m_d3dtex = nullptr; } } } @@ -2063,9 +2018,9 @@ texture_info::texture_info(texture_manager *manager, const render_texinfo* texso //texsource->osdhandle = (void*)this; // add us to the texture list - if(m_texture_manager->get_texlist() != NULL) + if(m_texture_manager->get_texlist() != nullptr) m_texture_manager->get_texlist()->m_prev = this; - m_prev = NULL; + m_prev = nullptr; m_next = m_texture_manager->get_texlist(); m_texture_manager->set_texlist(this); return; @@ -2073,9 +2028,9 @@ texture_info::texture_info(texture_manager *manager, const render_texinfo* texso error: d3dintf->post_fx_available = false; osd_printf_error("Direct3D: Critical warning: A texture failed to allocate. Expect things to get bad quickly.\n"); - if (m_d3dsurface != NULL) + if (m_d3dsurface != nullptr) (*d3dintf->surface.release)(m_d3dsurface); - if (m_d3dtex != NULL) + if (m_d3dtex != nullptr) (*d3dintf->texture.release)(m_d3dtex); } @@ -2242,7 +2197,7 @@ static inline void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, con assert(xborderpix == 0 || xborderpix == 1); // palette (really RGB map) case - if (palette != NULL) + if (palette != nullptr) { if (xborderpix) { @@ -2285,7 +2240,7 @@ static inline void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, co assert(xborderpix == 0 || xborderpix == 1); // palette (really RGB map) case - if (palette != NULL) + if (palette != nullptr) { if (xborderpix) { @@ -2329,7 +2284,7 @@ static inline void copyline_yuy16_to_yuy2(UINT16 *dst, const UINT16 *src, int wi assert(width % 2 == 0); // palette (really RGB map) case - if (palette != NULL) + if (palette != nullptr) { if (xborderpix) { @@ -2394,7 +2349,7 @@ static inline void copyline_yuy16_to_uyvy(UINT16 *dst, const UINT16 *src, int wi assert(width % 2 == 0); // palette (really RGB map) case - if (palette != NULL) + if (palette != nullptr) { if (xborderpix) { @@ -2457,7 +2412,7 @@ static inline void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int wi assert(width % 2 == 0); // palette (really RGB map) case - if (palette != NULL) + if (palette != nullptr) { if (xborderpix) { @@ -2535,9 +2490,9 @@ void texture_info::set_data(const render_texinfo *texsource, UINT32 flags) switch (m_type) { default: - case TEXTURE_TYPE_PLAIN: result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, NULL, 0); break; - case TEXTURE_TYPE_DYNAMIC: result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, NULL, D3DLOCK_DISCARD); break; - case TEXTURE_TYPE_SURFACE: result = (*d3dintf->surface.lock_rect)(m_d3dsurface, &rect, NULL, D3DLOCK_DISCARD); break; + case TEXTURE_TYPE_PLAIN: result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, nullptr, 0); break; + case TEXTURE_TYPE_DYNAMIC: result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, nullptr, D3DLOCK_DISCARD); break; + case TEXTURE_TYPE_SURFACE: result = (*d3dintf->surface.lock_rect)(m_d3dsurface, &rect, nullptr, D3DLOCK_DISCARD); break; } if (result != D3D_OK) { @@ -2625,7 +2580,7 @@ void texture_info::prescale() // if we have an offscreen plain surface, we can just StretchRect to it if (m_type == TEXTURE_TYPE_SURFACE) { - assert(m_d3dsurface != NULL); + assert(m_d3dsurface != nullptr); // set the source bounds RECT source; @@ -2649,7 +2604,7 @@ void texture_info::prescale() { surface *backbuffer; - assert(m_d3dtex != NULL); + assert(m_d3dtex != nullptr); // first remember the original render target and set the new one result = (*d3dintf->device.get_render_target)(m_renderer->get_device(), 0, &backbuffer); @@ -2704,7 +2659,7 @@ void texture_info::prescale() // unlock the vertex buffer result = (*d3dintf->vertexbuf.unlock)(m_renderer->get_vertex_buffer()); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result); - m_renderer->set_locked_buffer(NULL); + m_renderer->set_locked_buffer(nullptr); // set the stream and draw the triangle strip result = (*d3dintf->device.set_stream_source)(m_renderer->get_device(), 0, m_renderer->get_vertex_buffer(), sizeof(vertex)); @@ -2734,15 +2689,15 @@ void texture_info::prescale() cache_target::~cache_target() { - if (last_texture != NULL) + if (last_texture != nullptr) { (*d3dintf->texture.release)(last_texture); - last_texture = NULL; + last_texture = nullptr; } - if (last_target != NULL) + if (last_target != nullptr) { (*d3dintf->surface.release)(last_target); - last_target = NULL; + last_target = nullptr; } } @@ -2751,7 +2706,7 @@ cache_target::~cache_target() // cache_target::init - initializes a target cache //============================================================ -bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y) +bool cache_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y) { HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture); if (result != D3D_OK) @@ -2768,56 +2723,56 @@ bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int //============================================================ -// render_target::~render_target +// d3d_render_target::~d3d_render_target //============================================================ -render_target::~render_target() +d3d_render_target::~d3d_render_target() { for (int index = 0; index < 11; index++) { - if (bloom_texture[index] != NULL) + if (bloom_texture[index] != nullptr) { (*d3dintf->texture.release)(bloom_texture[index]); - bloom_texture[index] = NULL; + bloom_texture[index] = nullptr; } - if (bloom_target[index] != NULL) + if (bloom_target[index] != nullptr) { (*d3dintf->surface.release)(bloom_target[index]); - bloom_target[index] = NULL; + bloom_target[index] = nullptr; } } for (int index = 0; index < 2; index++) { - if (native_texture[index] != NULL) + if (native_texture[index] != nullptr) { (*d3dintf->texture.release)(native_texture[index]); - native_texture[index] = NULL; + native_texture[index] = nullptr; } - if (native_target[index] != NULL) + if (native_target[index] != nullptr) { (*d3dintf->surface.release)(native_target[index]); - native_target[index] = NULL; + native_target[index] = nullptr; } - if (prescale_texture[index] != NULL) + if (prescale_texture[index] != nullptr) { (*d3dintf->texture.release)(prescale_texture[index]); - prescale_texture[index] = NULL; + prescale_texture[index] = nullptr; } - if (prescale_target[index] != NULL) + if (prescale_target[index] != nullptr) { (*d3dintf->surface.release)(prescale_target[index]); - prescale_target[index] = NULL; + prescale_target[index] = nullptr; } } } //============================================================ -// render_target::init - initializes a render target +// d3d_render_target::init - initializes a render target //============================================================ -bool render_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y) +bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y) { HRESULT result; @@ -2866,4 +2821,12 @@ bool render_target::init(renderer *d3d, base *d3dintf, int width, int height, in return true; } +texture_info *renderer_d3d9::get_default_texture() +{ + return m_texture_manager->get_default_texture(); +} + +texture_info *renderer_d3d9::get_vector_texture() +{ + return m_texture_manager->get_vector_texture(); } diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h index 906bd7711b8..ac7195db8d7 100644 --- a/src/osd/modules/render/drawd3d.h +++ b/src/osd/modules/render/drawd3d.h @@ -9,9 +9,10 @@ #ifndef __WIN_DRAWD3D__ #define __WIN_DRAWD3D__ +#ifdef OSD_WINDOWS -#include "modules/render/d3d/d3dhlsl.h" - +#include "d3d/d3dintf.h" +#include "d3d/d3dcomm.h" //============================================================ // CONSTANTS @@ -24,87 +25,29 @@ // TYPE DEFINITIONS //============================================================ -namespace d3d -{ -class cache_target; -class render_target; -class renderer; - -/* cache_target is a simple linked list containing only a rednerable target and texture, used for phosphor effects */ -class cache_target -{ -public: - // construction/destruction - cache_target() { } - ~cache_target(); - - bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y); - - surface *last_target; - texture *last_texture; - - int target_width; - int target_height; - - int width; - int height; - - int screen_index; - - cache_target *next; - cache_target *prev; -}; - -/* render_target is the information about a Direct3D render target chain */ -class render_target -{ -public: - // construction/destruction - render_target() { } - ~render_target(); - - bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y); - int next_index(int index) { return ++index > 1 ? 0 : index; } - - int target_width; - int target_height; - - int prescale_x; - int prescale_y; - - int width; - int height; - - int screen_index; - int page_index; - - surface *prescale_target[2]; - texture *prescale_texture[2]; - surface *native_target[2]; - texture *native_texture[2]; - - render_target *next; - render_target *prev; - - surface *bloom_target[11]; - texture *bloom_texture[11]; -}; +class vertex; +class texture_info; +class texture_manager; +class device; +class vertex_buffer; +class shaders; +class hlsl_options; +class poly_info; /* renderer is the information about Direct3D for the current screen */ -class renderer : public osd_renderer +class renderer_d3d9 : public osd_renderer { public: - //renderer() { } - renderer(osd_window *window); - virtual ~renderer(); + renderer_d3d9(osd_window *window); + virtual ~renderer_d3d9(); virtual int create() override; + virtual int init(running_machine &machine) 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; - virtual void destroy() override; int initialize(); @@ -140,8 +83,8 @@ public: void set_texture(texture_info *texture); void set_filter(int filter); - void set_wrap(D3DTEXTUREADDRESS wrap); - void set_modmode(DWORD modmode); + void set_wrap(unsigned int wrap); + void set_modmode(int modmode); void set_blendmode(int blendmode); void reset_render_states(); @@ -164,15 +107,15 @@ public: bool is_mod2x_supported() { return (bool)m_mod2x_supported; } bool is_mod4x_supported() { return (bool)m_mod4x_supported; } - D3DFORMAT get_screen_format() { return m_screen_format; } - D3DFORMAT get_pixel_format() { return m_pixformat; } - D3DDISPLAYMODE get_origmode() { return m_origmode; } + D3DFORMAT get_screen_format() { return m_screen_format; } + D3DFORMAT get_pixel_format() { return m_pixformat; } + D3DDISPLAYMODE get_origmode() { return m_origmode; } UINT32 get_last_texture_flags() { return m_last_texture_flags; } - texture_manager * get_texture_manager() { return m_texture_manager; } - texture_info * get_default_texture() { return m_texture_manager->get_default_texture(); } - texture_info * get_vector_texture() { return m_texture_manager->get_vector_texture(); } + d3d_texture_manager * get_texture_manager() { return m_texture_manager; } + texture_info * get_default_texture(); + texture_info * get_vector_texture(); shaders * get_shaders() { return m_shaders; } hlsl_options * get_shaders_options() { return m_shaders_options; } @@ -186,9 +129,9 @@ private: device * m_device; // pointer to the Direct3DDevice object int m_gamma_supported; // is full screen gamma supported? - present_parameters m_presentation; // set of presentation parameters - D3DDISPLAYMODE m_origmode; // original display mode for the adapter - D3DFORMAT m_pixformat; // pixel format we are using + present_parameters m_presentation; // set of presentation parameters + D3DDISPLAYMODE m_origmode; // original display mode for the adapter + D3DFORMAT m_pixformat; // pixel format we are using vertex_buffer * m_vertexbuf; // pointer to the vertex buffer object vertex * m_lockedbuf; // pointer to the locked vertex buffer @@ -197,14 +140,14 @@ private: vertex * m_vectorbatch; // pointer to the vector batch buffer int m_batchindex; // current index into the vector batch - poly_info m_poly[VERTEX_BUFFER_SIZE/3];// array to hold polygons as they are created + poly_info m_poly[VERTEX_BUFFER_SIZE/3];// array to hold polygons as they are created int m_numpolys; // number of accumulated polygons bool m_restarting; // if we're restarting int m_mod2x_supported; // is D3DTOP_MODULATE2X supported? int m_mod4x_supported; // is D3DTOP_MODULATE4X supported? - D3DFORMAT m_screen_format; // format to use for screen textures + D3DFORMAT m_screen_format; // format to use for screen textures texture_info * m_last_texture; // previous texture UINT32 m_last_texture_flags; // previous texture flags @@ -213,18 +156,18 @@ private: int m_last_blendsrc; // previous blendmode int m_last_blenddst; // previous blendmode int m_last_filter; // previous texture filter - D3DTEXTUREADDRESS m_last_wrap; // previous wrap state - DWORD m_last_modmode; // previous texture modulation + UINT32 m_last_wrap; // previous wrap state + int m_last_modmode; // previous texture modulation void * m_hlsl_buf; // HLSL vertex data shaders * m_shaders; // HLSL interface hlsl_options * m_shaders_options; // HLSL options - texture_manager * m_texture_manager; // texture manager + d3d_texture_manager * m_texture_manager; // texture manager int m_line_count; }; -} +#endif // OSD_WINDOWS -#endif +#endif // __WIN_DRAWD3D__
\ No newline at end of file diff --git a/src/osd/modules/render/drawgdi.cpp b/src/osd/modules/render/drawgdi.cpp index 11e61a28407..bd305a6e7e7 100644 --- a/src/osd/modules/render/drawgdi.cpp +++ b/src/osd/modules/render/drawgdi.cpp @@ -6,125 +6,41 @@ // //============================================================ -// standard windows headers -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -// MAME headers -#include "emu.h" +#include "drawgdi.h" #include "rendersw.inc" -// MAMEOS headers -#include "window.h" - - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -class renderer_gdi : public osd_renderer -{ -public: - renderer_gdi(osd_window *window) - : osd_renderer(window, FLAG_NONE), bmdata(NULL), bmsize(0) { } - - virtual ~renderer_gdi() { } - - 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 {}; - virtual void destroy() override; - -private: - /* gdi_info is the information for the current screen */ - BITMAPINFO bminfo; - UINT8 * bmdata; - size_t bmsize; -}; - - -//============================================================ -// PROTOTYPES -//============================================================ - -// core functions -static void drawgdi_exit(void); - -//============================================================ -// drawnone_create -//============================================================ - -static osd_renderer *drawgdi_create(osd_window *window) -{ - return global_alloc(renderer_gdi(window)); -} - - -//============================================================ -// drawgdi_init -//============================================================ - -int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks) -{ - // fill in the callbacks - memset(callbacks, 0, sizeof(*callbacks)); - callbacks->exit = drawgdi_exit; - callbacks->create = drawgdi_create; - return 0; -} - - - //============================================================ -// drawgdi_exit +// destructor //============================================================ -static void drawgdi_exit(void) +renderer_gdi::~renderer_gdi() { + // free the bitmap memory + if (m_bmdata != NULL) + global_free_array(m_bmdata); } - - //============================================================ -// drawgdi_window_init +// renderer_gdi::create //============================================================ int renderer_gdi::create() { // fill in the bitmap info header - bminfo.bmiHeader.biSize = sizeof(bminfo.bmiHeader); - bminfo.bmiHeader.biPlanes = 1; - bminfo.bmiHeader.biBitCount = 32; - bminfo.bmiHeader.biCompression = BI_RGB; - bminfo.bmiHeader.biSizeImage = 0; - bminfo.bmiHeader.biXPelsPerMeter = 0; - bminfo.bmiHeader.biYPelsPerMeter = 0; - bminfo.bmiHeader.biClrUsed = 0; - bminfo.bmiHeader.biClrImportant = 0; - + m_bminfo.bmiHeader.biSize = sizeof(m_bminfo.bmiHeader); + m_bminfo.bmiHeader.biPlanes = 1; + m_bminfo.bmiHeader.biBitCount = 32; + m_bminfo.bmiHeader.biCompression = BI_RGB; + m_bminfo.bmiHeader.biSizeImage = 0; + m_bminfo.bmiHeader.biXPelsPerMeter = 0; + m_bminfo.bmiHeader.biYPelsPerMeter = 0; + m_bminfo.bmiHeader.biClrUsed = 0; + m_bminfo.bmiHeader.biClrImportant = 0; return 0; } - - -//============================================================ -// drawgdi_window_destroy -//============================================================ - -void renderer_gdi::destroy() -{ - // free the bitmap memory - if (bmdata != NULL) - global_free_array(bmdata); -} - - - //============================================================ -// drawgdi_window_get_primitives +// renderer_gdi::get_primitives //============================================================ render_primitive_list *renderer_gdi::get_primitives() @@ -135,49 +51,45 @@ render_primitive_list *renderer_gdi::get_primitives() return &window().target()->get_primitives(); } - - //============================================================ -// drawgdi_window_draw +// renderer_gdi::draw //============================================================ int renderer_gdi::draw(const int update) { - int width, height, pitch; - RECT bounds; - // we don't have any special resize behaviors if (window().m_resize_state == RESIZE_STATE_PENDING) window().m_resize_state = RESIZE_STATE_NORMAL; // get the target bounds + RECT bounds; GetClientRect(window().m_hwnd, &bounds); // compute width/height/pitch of target - width = rect_width(&bounds); - height = rect_height(&bounds); - pitch = (width + 3) & ~3; + int width = rect_width(&bounds); + int height = rect_height(&bounds); + int pitch = (width + 3) & ~3; // make sure our temporary bitmap is big enough - if (pitch * height * 4 > bmsize) + if (pitch * height * 4 > m_bmsize) { - bmsize = pitch * height * 4 * 2; - global_free_array(bmdata); - bmdata = global_alloc_array(UINT8, bmsize); + m_bmsize = pitch * height * 4 * 2; + global_free_array(m_bmdata); + m_bmdata = global_alloc_array(UINT8, m_bmsize); } // draw the primitives to the bitmap window().m_primlist->acquire_lock(); - software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, bmdata, width, height, pitch); + software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, m_bmdata, width, height, pitch); window().m_primlist->release_lock(); // fill in bitmap-specific info - bminfo.bmiHeader.biWidth = pitch; - bminfo.bmiHeader.biHeight = -height; + m_bminfo.bmiHeader.biWidth = pitch; + m_bminfo.bmiHeader.biHeight = -height; // blit to the screen StretchDIBits(window().m_dc, 0, 0, width, height, 0, 0, width, height, - bmdata, &bminfo, DIB_RGB_COLORS, SRCCOPY); + m_bmdata, &m_bminfo, DIB_RGB_COLORS, SRCCOPY); return 0; } diff --git a/src/osd/modules/render/drawgdi.h b/src/osd/modules/render/drawgdi.h new file mode 100644 index 00000000000..4782e83413d --- /dev/null +++ b/src/osd/modules/render/drawgdi.h @@ -0,0 +1,55 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +//============================================================ +// +// drawgdi.h - Win32 GDI drawing +// +//============================================================ + +#pragma once + +#ifndef __DRAWGDI__ +#define __DRAWGDI__ + +// standard windows headers +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +// MAME headers +#include "emu.h" + +// MAMEOS headers +#include "window.h" + + +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +class renderer_gdi : public osd_renderer +{ +public: + renderer_gdi(osd_window *window) + : osd_renderer(window, FLAG_NONE) + , m_bmdata(NULL) + , m_bmsize(0) + { + } + virtual ~renderer_gdi(); + + virtual int create() override; + virtual int init(running_machine &machine) override { return 0; } + 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: + /* gdi_info is the information for the current screen */ + BITMAPINFO m_bminfo; + UINT8 * m_bmdata; + size_t m_bmsize; +}; + +#endif // __DRAWGDI__
\ No newline at end of file diff --git a/src/osd/modules/render/drawnone.cpp b/src/osd/modules/render/drawnone.cpp index 9f45683e6da..5e1b4aa05dd 100644 --- a/src/osd/modules/render/drawnone.cpp +++ b/src/osd/modules/render/drawnone.cpp @@ -2,7 +2,7 @@ // copyright-holders:Aaron Giles //============================================================ // -// drawnone.c - stub "nothing" drawer +// drawnone.cpp - stub "nothing" drawer // //============================================================ @@ -13,88 +13,7 @@ // MAME headers #include "emu.h" -// MAMEOS headers -#include "window.h" - - -class renderer_none : public osd_renderer -{ -public: - renderer_none(osd_window *window) - : osd_renderer(window, FLAG_NONE) { } - - virtual ~renderer_none() { } - - 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 { }; - virtual void destroy() override; -}; - -//============================================================ -// PROTOTYPES -//============================================================ - -// core functions -static void drawnone_exit(void); - -//============================================================ -// drawnone_create -//============================================================ - -osd_renderer *drawnone_create(osd_window *window) -{ - return global_alloc(renderer_none(window)); -} - -//============================================================ -// drawnone_init -//============================================================ - -int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks) -{ - // fill in the callbacks - memset(callbacks, 0, sizeof(*callbacks)); - callbacks->exit = drawnone_exit; - callbacks->create = drawnone_create; - return 0; -} - - - -//============================================================ -// drawnone_exit -//============================================================ - -static void drawnone_exit(void) -{ -} - - - -//============================================================ -// drawnone_window_init -//============================================================ - -int renderer_none::create() -{ - return 0; -} - - - -//============================================================ -// drawnone_window_destroy -//============================================================ - -void renderer_none::destroy() -{ -} - - +#include "drawnone.h" //============================================================ // drawnone_window_get_primitives @@ -107,14 +26,3 @@ render_primitive_list *renderer_none::get_primitives() window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect()); return &window().target()->get_primitives(); } - - - -//============================================================ -// drawnone_window_draw -//============================================================ - -int renderer_none::draw(const int update) -{ - return 0; -} diff --git a/src/osd/modules/render/drawnone.h b/src/osd/modules/render/drawnone.h new file mode 100644 index 00000000000..621be08527c --- /dev/null +++ b/src/osd/modules/render/drawnone.h @@ -0,0 +1,34 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +//============================================================ +// +// drawnone.h - stub "nothing" drawer +// +//============================================================ + +// MAMEOS headers +#include "window.h" + +#pragma once + +#ifndef __DRAWNONE__ +#define __DRAWNONE__ + +class renderer_none : public osd_renderer +{ +public: + renderer_none(osd_window *window) + : osd_renderer(window, FLAG_NONE) { } + + virtual ~renderer_none() { } + + virtual int create() override { return 0; } + virtual int init(running_machine &machine) 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__
\ No newline at end of file diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp index 728b0810290..e85649534b9 100644 --- a/src/osd/modules/render/drawogl.cpp +++ b/src/osd/modules/render/drawogl.cpp @@ -119,17 +119,7 @@ typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuin #define GL_DEPTH_COMPONENT32 0x81A7 #endif -#define HASH_SIZE ((1<<10)+1) -#define OVERFLOW_SIZE (1<<10) - -// OSD headers -#ifndef OSD_WINDOWS -#include "osdsdl.h" -#include "window.h" -#else -#include "../windows/window.h" -typedef UINT64 HashT; -#endif +#include "drawogl.h" //============================================================ // DEBUGGING @@ -179,405 +169,6 @@ enum #define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0) #define GL_NO_PRIMITIVE -1 -//============================================================ -// TYPES -//============================================================ - -#if defined(OSD_WINDOWS) - -class win_gl_context : public osd_gl_context -{ -public: - win_gl_context(HWND window) : osd_gl_context(), m_context(0), m_window(NULL), m_hdc(0) - { - m_error[0] = 0; - - this->pfn_wglGetProcAddress = (PROC (WINAPI *)(LPCSTR lpszProc)) GetProcAddress(m_module, "wglGetProcAddress"); - this->pfn_wglCreateContext = (HGLRC (WINAPI *)(HDC hdc)) GetProcAddress(m_module, "wglCreateContext"); - this->pfn_wglDeleteContext = (BOOL (WINAPI *)(HGLRC hglrc)) GetProcAddress(m_module, "wglDeleteContext"); - this->pfn_wglMakeCurrent = (BOOL (WINAPI *)(HDC hdc, HGLRC hglrc)) GetProcAddress(m_module, "wglMakeCurrent"); - - this->pfn_wglGetExtensionsStringEXT = (const char *(WINAPI *) (void)) pfn_wglGetProcAddress("wglGetExtensionsStringEXT"); - - if (WGLExtensionSupported("WGL_EXT_swap_control")) - { - this->pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT"); - this->pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("wglGetSwapIntervalEXT"); - } - else - { - pfn_wglSwapIntervalEXT = NULL; - pfn_wglGetSwapIntervalEXT = NULL; - } - - m_hdc = GetDC(window); - if (!setupPixelFormat(m_hdc)) - { - m_context = this->pfn_wglCreateContext(m_hdc); - if (!m_context) - { - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, m_error, 255, NULL); - return; - } - this->pfn_wglMakeCurrent(m_hdc, m_context); - } - } - - virtual ~win_gl_context() - { - this->pfn_wglDeleteContext(m_context); - ReleaseDC(m_window, m_hdc); - } - - virtual void MakeCurrent() override - { - this->pfn_wglMakeCurrent(m_hdc, m_context); - } - - virtual const char *LastErrorMsg() override - { - if (m_error[0] == 0) - return NULL; - else - return m_error; - } - - virtual void *getProcAddress(const char *proc) override - { - void *ret = (void *) GetProcAddress(m_module, proc); - if (ret == NULL) - ret = (void *) this->pfn_wglGetProcAddress(proc); - return ret; - } - - virtual int SetSwapInterval(const int swap) override - { - if (this->pfn_wglSwapIntervalEXT != NULL) - { - this->pfn_wglSwapIntervalEXT(swap ? 1 : 0); - } - return 0; - } - - virtual void SwapBuffer() override - { - SwapBuffers(m_hdc); - //wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE); - } - - static void load_library() - { - m_module = LoadLibraryA("opengl32.dll"); - } - -private: - - int setupPixelFormat(HDC hDC) - { - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - PFD_SUPPORT_OPENGL | - PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER, /* support double-buffering */ - PFD_TYPE_RGBA, /* color type */ - 32, /* prefered color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - 0, /* no alpha buffer */ - 0, /* alpha bits (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 16, /* depth buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0, /* no layer, visible, damage masks */ - }; - int pixelFormat; - - pixelFormat = ChoosePixelFormat(hDC, &pfd); - if (pixelFormat == 0) { - strcpy(m_error, "ChoosePixelFormat failed"); - return 1; - } - - if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) { - strcpy(m_error, "SetPixelFormat failed."); - return 1; - } - return 0; - } - - bool WGLExtensionSupported(const char *extension_name) - { - //if (pfn_wglGetExtensionsStringEXT != NULL) - // printf("%s\n", this->pfn_wglGetExtensionsStringEXT()); - - if (pfn_wglGetExtensionsStringEXT != NULL && strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != NULL) - return true; - else - return false; - } - - HGLRC m_context; - HWND m_window; - HDC m_hdc; - char m_error[256]; - - PROC (WINAPI *pfn_wglGetProcAddress)(LPCSTR lpszProc); - HGLRC (WINAPI *pfn_wglCreateContext)(HDC hdc); - BOOL (WINAPI *pfn_wglDeleteContext)(HGLRC hglrc); - BOOL (WINAPI *pfn_wglMakeCurrent)(HDC hdc, HGLRC hglrc); - - const char *(WINAPI *pfn_wglGetExtensionsStringEXT) (void); - BOOL (WINAPI *pfn_wglSwapIntervalEXT) (int interval); - int (WINAPI * pfn_wglGetSwapIntervalEXT) (void); - - static HMODULE m_module; -}; - -HMODULE win_gl_context::m_module; - - -#else - -class sdl_gl_context : public osd_gl_context -{ -public: - sdl_gl_context(SDL_Window *window) : osd_gl_context(), m_context(0), m_window(window) - { - m_error[0] = 0; - m_context = SDL_GL_CreateContext(window); - if (!m_context) - { - snprintf(m_error,255, "OpenGL not supported on this driver: %s", SDL_GetError()); - } - } - virtual ~sdl_gl_context() - { - SDL_GL_DeleteContext(m_context); - } - virtual void MakeCurrent() override - { - SDL_GL_MakeCurrent(m_window, m_context); - } - - virtual int SetSwapInterval(const int swap) override - { - return SDL_GL_SetSwapInterval(swap); - } - - virtual const char *LastErrorMsg() override - { - if (m_error[0] == 0) - return NULL; - else - return m_error; - } - virtual void *getProcAddress(const char *proc) override - { - return SDL_GL_GetProcAddress(proc); - } - - virtual void SwapBuffer() override - { - SDL_GL_SwapWindow(m_window); - } - -private: - SDL_GLContext m_context; - SDL_Window *m_window; - char m_error[256]; -}; - -#endif - -//============================================================ -// 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(NULL), - 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 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 texture; // OpenGL texture "name"/ID - - GLenum texTarget; // OpenGL texture target - int texpow2; // Is this texture pow2 - - UINT32 mpass_dest_idx; // Multipass dest idx [0..1] - UINT32 mpass_textureunit[2]; // texture unit names for GLSL - - UINT32 mpass_texture_mamebm[2];// Multipass OpenGL texture "name"/ID for the shader - UINT32 mpass_fbo_mamebm[2]; // framebuffer object for this texture, multipass - UINT32 mpass_texture_scrn[2]; // Multipass OpenGL texture "name"/ID for the shader - UINT32 mpass_fbo_scrn[2]; // framebuffer object for this texture, multipass - - UINT32 pbo; // pixel buffer object for this texture (DYNAMIC only!) - UINT32 *data; // pixels for the texture - int data_own; // do we own / allocated it ? - GLfloat texCoord[8]; - GLuint texCoordBufferName; - -}; - -/* sdl_info is the information about SDL for the current screen */ -class sdl_info_ogl : public osd_renderer -{ -public: - sdl_info_ogl(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(NULL), - 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(NULL), - 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] = NULL; - 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 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 void destroy() override; - virtual render_primitive_list *get_primitives() override - { -#ifdef OSD_WINDOWS - osd_dim nd = window().get_size(); -#else - osd_dim nd = window().blit_surface_size(); -#endif - if (nd != m_blit_dim) - { - m_blit_dim = nd; - notify_changed(); - } - window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect()); - return &window().target()->get_primitives(); - } - -#ifdef OSD_WINDOWS - virtual void save() override { } - virtual void record() override { } - virtual void toggle_fsfx() override { } -#endif - -private: - void destroy_all_textures(); - - void loadGLExtensions(); - void initialize_gl(); - void set_blendmode(int blendmode); - void texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 flags); - void texture_compute_size_subroutine(ogl_texture_info *texture, UINT32 flags, - UINT32 width, UINT32 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 flags); - ogl_texture_info *texture_create(const render_texinfo *texsource, UINT32 flags); - int texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 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 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 m_texture_max_width; // texture maximum width - INT32 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 m_surf_w; - INT32 m_surf_h; - GLfloat m_texVerticex[8]; -}; - /* line_aa_step is used for drawing antialiased lines */ struct line_aa_step { @@ -606,14 +197,14 @@ static const line_aa_step line_aa_4step[] = // INLINES //============================================================ -static inline HashT texture_compute_hash(const render_texinfo *texture, UINT32 flags) +HashT renderer_ogl::texture_compute_hash(const render_texinfo *texture, UINT32 flags) { HashT h = (HashT)texture->base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)); //printf("hash %d\n", (int) h % HASH_SIZE); return (h >> 8) % HASH_SIZE; } -void sdl_info_ogl::set_blendmode(int blendmode) +void renderer_ogl::set_blendmode(int blendmode) { // try to minimize texture state changes if (blendmode != m_last_blendmode) @@ -642,45 +233,34 @@ void sdl_info_ogl::set_blendmode(int blendmode) } //============================================================ -// PROTOTYPES -//============================================================ - -// core functions - -//============================================================ // STATIC VARIABLES //============================================================ -static void drawogl_exit(void); -static void load_gl_lib(running_machine &machine); - - - // OGL 1.3 #ifdef GL_ARB_multitexture -static PFNGLACTIVETEXTUREARBPROC pfn_glActiveTexture = NULL; +static PFNGLACTIVETEXTUREARBPROC pfn_glActiveTexture = nullptr; #else -static PFNGLACTIVETEXTUREPROC pfn_glActiveTexture = NULL; +static PFNGLACTIVETEXTUREPROC pfn_glActiveTexture = nullptr; #endif // VBO -static PFNGLGENBUFFERSPROC pfn_glGenBuffers = NULL; -static PFNGLDELETEBUFFERSPROC pfn_glDeleteBuffers = NULL; -static PFNGLBINDBUFFERPROC pfn_glBindBuffer = NULL; -static PFNGLBUFFERDATAPROC pfn_glBufferData = NULL; -static PFNGLBUFFERSUBDATAPROC pfn_glBufferSubData = NULL; +static PFNGLGENBUFFERSPROC pfn_glGenBuffers = nullptr; +static PFNGLDELETEBUFFERSPROC pfn_glDeleteBuffers = nullptr; +static PFNGLBINDBUFFERPROC pfn_glBindBuffer = nullptr; +static PFNGLBUFFERDATAPROC pfn_glBufferData = nullptr; +static PFNGLBUFFERSUBDATAPROC pfn_glBufferSubData = nullptr; // PBO -static PFNGLMAPBUFFERPROC pfn_glMapBuffer = NULL; -static PFNGLUNMAPBUFFERPROC pfn_glUnmapBuffer = NULL; +static PFNGLMAPBUFFERPROC pfn_glMapBuffer = nullptr; +static PFNGLUNMAPBUFFERPROC pfn_glUnmapBuffer = nullptr; // FBO -static PFNGLISFRAMEBUFFEREXTPROC pfn_glIsFramebuffer = NULL; -static PFNGLBINDFRAMEBUFFEREXTPROC pfn_glBindFramebuffer = NULL; -static PFNGLDELETEFRAMEBUFFERSEXTPROC pfn_glDeleteFramebuffers = NULL; -static PFNGLGENFRAMEBUFFERSEXTPROC pfn_glGenFramebuffers = NULL; -static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pfn_glCheckFramebufferStatus = NULL; -static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pfn_glFramebufferTexture2D = NULL; +static PFNGLISFRAMEBUFFEREXTPROC pfn_glIsFramebuffer = nullptr; +static PFNGLBINDFRAMEBUFFEREXTPROC pfn_glBindFramebuffer = nullptr; +static PFNGLDELETEFRAMEBUFFERSEXTPROC pfn_glDeleteFramebuffers = nullptr; +static PFNGLGENFRAMEBUFFERSEXTPROC pfn_glGenFramebuffers = nullptr; +static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pfn_glCheckFramebufferStatus = nullptr; +static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pfn_glFramebufferTexture2D = nullptr; static int glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN; @@ -694,25 +274,12 @@ static void texture_set_data(ogl_texture_info *texture, const render_texinfo *te // Static Variables //============================================================ -static int shown_video_info = 0; -static int dll_loaded = 0; +bool renderer_ogl::s_shown_video_info = false; +bool renderer_ogl::s_dll_loaded = false; -//============================================================ -// drawsdl_init -//============================================================ - -static osd_renderer *drawogl_create(osd_window *window) +int renderer_ogl::init(running_machine &machine) { - return global_alloc(sdl_info_ogl(window)); -} - -int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks) -{ - // fill in the callbacks - callbacks->exit = drawogl_exit; - callbacks->create = drawogl_create; - - dll_loaded = 0; + s_dll_loaded = false; load_gl_lib(machine); #if defined(OSD_WINDOWS) @@ -725,6 +292,36 @@ int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks) } //============================================================ +// CONSTRUCTOR & DESTRUCTOR +//============================================================ + +renderer_ogl::~renderer_ogl() +{ + // free the memory in the window + destroy_all_textures(); + + global_free(m_gl_context); + m_gl_context = nullptr; + + for (int i = 0; i < video_config.glsl_shader_mamebm_num; i++) + { + if (nullptr != video_config.glsl_shader_mamebm[i]) + { + free(video_config.glsl_shader_mamebm[i]); + video_config.glsl_shader_mamebm[i] = nullptr; + } + } + for (int i =0; i < video_config.glsl_shader_scrn_num; i++) + { + if (nullptr != video_config.glsl_shader_scrn[i]) + { + free(video_config.glsl_shader_scrn[i]); + video_config.glsl_shader_scrn[i] = nullptr; + } + } +} + +//============================================================ // Load the OGL function addresses //============================================================ @@ -762,9 +359,13 @@ static void loadgl_functions(osd_gl_context *context) osd_gl_dispatch *gl_dispatch; #endif -static void load_gl_lib(running_machine &machine) +#ifdef OSD_WINDOWS +HMODULE win_gl_context::m_module; +#endif + +void renderer_ogl::load_gl_lib(running_machine &machine) { - if (!dll_loaded) + if (!s_dll_loaded) { #ifdef OSD_WINDOWS win_gl_context::load_library(); @@ -777,10 +378,10 @@ static void load_gl_lib(running_machine &machine) const char *stemp; stemp = downcast<sdl_options &>(machine.options()).gl_lib(); - if (stemp != NULL && strcmp(stemp, OSDOPTVAL_AUTO) == 0) - stemp = NULL; + if (stemp != nullptr && strcmp(stemp, OSDOPTVAL_AUTO) == 0) + stemp = nullptrnullptr; - if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==NULL + if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==nullptr { fatalerror("Unable to load opengl library: %s\n", stemp ? stemp : "<default>"); } @@ -791,11 +392,11 @@ static void load_gl_lib(running_machine &machine) #ifdef USE_DISPATCH_GL gl_dispatch = (osd_gl_dispatch *) osd_malloc(sizeof(osd_gl_dispatch)); #endif - dll_loaded=1; + s_dll_loaded = true; } } -void sdl_info_ogl::initialize_gl() +void renderer_ogl::initialize_gl() { int has_and_allow_texturerect = 0; @@ -808,7 +409,7 @@ void sdl_info_ogl::initialize_gl() extstr = (char *)""; #endif // print out the driver info for debugging - if (!shown_video_info) + if (!s_shown_video_info) { osd_printf_verbose("OpenGL: %s\nOpenGL: %s\nOpenGL: %s\n", vendor, (char *)glGetString(GL_RENDERER), (char *)glGetString(GL_VERSION)); } @@ -820,21 +421,19 @@ void sdl_info_ogl::initialize_gl() m_usefbo = 0; m_useglsl = 0; - if ( video_config.allowtexturerect && - ( strstr(extstr, "GL_ARB_texture_rectangle") || strstr(extstr, "GL_EXT_texture_rectangle") ) - ) + if (video_config.allowtexturerect && (strstr(extstr, "GL_ARB_texture_rectangle") || strstr(extstr, "GL_EXT_texture_rectangle"))) { has_and_allow_texturerect = 1; - if (!shown_video_info) - { - osd_printf_verbose("OpenGL: texture rectangle supported\n"); - } + if (!s_shown_video_info) + { + osd_printf_verbose("OpenGL: texture rectangle supported\n"); + } } // does this card support non-power-of-two sized textures? (they're faster, so use them if possible) if ( !video_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two")) { - if (!shown_video_info) + if (!s_shown_video_info) { osd_printf_verbose("OpenGL: non-power-of-2 textures supported (new method)\n"); } @@ -845,7 +444,7 @@ void sdl_info_ogl::initialize_gl() // second chance: GL_ARB_texture_rectangle or GL_EXT_texture_rectangle (old version) if (has_and_allow_texturerect) { - if (!shown_video_info) + if (!s_shown_video_info) { osd_printf_verbose("OpenGL: non-power-of-2 textures supported (old method)\n"); } @@ -853,7 +452,7 @@ void sdl_info_ogl::initialize_gl() } else { - if (!shown_video_info) + if (!s_shown_video_info) { osd_printf_verbose("OpenGL: forcing power-of-2 textures (creation, not copy)\n"); } @@ -862,8 +461,8 @@ void sdl_info_ogl::initialize_gl() if (strstr(extstr, "GL_ARB_vertex_buffer_object")) { - m_usevbo = video_config.vbo; - if (!shown_video_info) + m_usevbo = video_config.vbo; + if (!s_shown_video_info) { if(m_usevbo) osd_printf_verbose("OpenGL: vertex buffer supported\n"); @@ -877,15 +476,17 @@ void sdl_info_ogl::initialize_gl() if( m_usevbo ) { m_usepbo = video_config.pbo; - if (!shown_video_info) + if (!s_shown_video_info) { if(m_usepbo) osd_printf_verbose("OpenGL: pixel buffers supported\n"); else osd_printf_verbose("OpenGL: pixel buffers supported, but disabled\n"); } - } else { - if (!shown_video_info) + } + else + { + if (!s_shown_video_info) { osd_printf_verbose("OpenGL: pixel buffers supported, but disabled due to disabled vbo\n"); } @@ -893,7 +494,7 @@ void sdl_info_ogl::initialize_gl() } else { - if (!shown_video_info) + if (!s_shown_video_info) { osd_printf_verbose("OpenGL: pixel buffers not supported\n"); } @@ -902,7 +503,7 @@ void sdl_info_ogl::initialize_gl() if (strstr(extstr, "GL_EXT_framebuffer_object")) { m_usefbo = 1; - if (!shown_video_info) + if (!s_shown_video_info) { if(m_usefbo) osd_printf_verbose("OpenGL: framebuffer object supported\n"); @@ -918,22 +519,24 @@ void sdl_info_ogl::initialize_gl() ) { m_useglsl = video_config.glsl; - if (!shown_video_info) + if (!s_shown_video_info) { if(m_useglsl) osd_printf_verbose("OpenGL: GLSL supported\n"); else osd_printf_verbose("OpenGL: GLSL supported, but disabled\n"); } - } else { - if (!shown_video_info) + } + else + { + if (!s_shown_video_info) { osd_printf_verbose("OpenGL: GLSL not supported\n"); } } #ifdef TOBEMIGRATED - if (osd_getenv(SDLENV_VMWARE) != NULL) + if (osd_getenv(SDLENV_VMWARE) != nullptr) { m_usetexturerect = 1; m_texpoweroftwo = 1; @@ -941,45 +544,19 @@ void sdl_info_ogl::initialize_gl() #endif glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&m_texture_max_width); glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&m_texture_max_height); - if (!shown_video_info) + if (!s_shown_video_info) { osd_printf_verbose("OpenGL: max texture size %d x %d\n", m_texture_max_width, m_texture_max_height); } - shown_video_info = 1; + s_shown_video_info = true; } //============================================================ // sdl_info::create -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a -// a //============================================================ -int sdl_info_ogl::create() +int renderer_ogl::create() { // create renderer #if defined(OSD_WINDOWS) @@ -987,7 +564,7 @@ int sdl_info_ogl::create() #else m_gl_context = global_alloc(sdl_gl_context(window().sdl_window())); #endif - if (m_gl_context->LastErrorMsg() != NULL) + if (m_gl_context->LastErrorMsg() != nullptr) { osd_printf_error("%s\n", m_gl_context->LastErrorMsg()); return 1; @@ -1015,31 +592,16 @@ int sdl_info_ogl::create() m_init_context = 0; - osd_printf_verbose("Leave sdl_info_ogl::create\n"); + osd_printf_verbose("Leave renderer_ogl::create\n"); return 0; } //============================================================ -// sdl_info::destroy -//============================================================ - -void sdl_info_ogl::destroy() -{ - // free the memory in the window - - destroy_all_textures(); - - global_free(m_gl_context); - m_gl_context = NULL; -} - - -//============================================================ // drawsdl_xy_to_render_target //============================================================ #ifndef OSD_WINDOWS -int sdl_info_ogl::xy_to_render_target(int x, int y, int *xt, int *yt) +int renderer_ogl::xy_to_render_target(int x, int y, int *xt, int *yt) { *xt = x - m_last_hofs; *yt = y - m_last_vofs; @@ -1050,13 +612,14 @@ int sdl_info_ogl::xy_to_render_target(int x, int y, int *xt, int *yt) return 1; } #endif + //============================================================ -// drawsdl_destroy_all_textures +// renderer_ogl::destroy_all_textures //============================================================ -void sdl_info_ogl::destroy_all_textures() +void renderer_ogl::destroy_all_textures() { - ogl_texture_info *texture = NULL; + ogl_texture_info *texture = nullptr; int lock=FALSE; int i; @@ -1081,8 +644,8 @@ void sdl_info_ogl::destroy_all_textures() while (i<HASH_SIZE+OVERFLOW_SIZE) { texture = m_texhash[i]; - m_texhash[i] = NULL; - if (texture != NULL) + m_texhash[i] = nullptr; + if (texture != nullptr) { if(m_usevbo) { @@ -1114,7 +677,7 @@ void sdl_info_ogl::destroy_all_textures() if ( texture->data_own ) { free(texture->data); - texture->data=NULL; + texture->data=nullptr; texture->data_own=FALSE; } global_free(texture); @@ -1124,7 +687,7 @@ void sdl_info_ogl::destroy_all_textures() if ( m_useglsl ) { glsl_shader_free(m_glsl); - m_glsl = NULL; + m_glsl = nullptr; } m_initialized = 0; @@ -1136,7 +699,7 @@ void sdl_info_ogl::destroy_all_textures() // loadGLExtensions //============================================================ -void sdl_info_ogl::loadGLExtensions() +void renderer_ogl::loadGLExtensions() { static int _once = 1; @@ -1337,7 +900,7 @@ void sdl_info_ogl::loadGLExtensions() if ( m_useglsl ) { m_glsl = glsl_shader_init(m_gl_context); - m_useglsl = (m_glsl != NULL ? 1 : 0); + m_useglsl = (m_glsl != nullptr ? 1 : 0); if ( ! m_useglsl ) { @@ -1446,10 +1009,10 @@ void sdl_info_ogl::loadGLExtensions() // sdl_info::draw //============================================================ -int sdl_info_ogl::draw(const int update) +int renderer_ogl::draw(const int update) { render_primitive *prim; - ogl_texture_info *texture=NULL; + ogl_texture_info *texture=nullptr; float vofs, hofs; int pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE; @@ -1594,7 +1157,7 @@ int sdl_info_ogl::draw(const int update) window().m_primlist->acquire_lock(); // now draw - for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next()) + for (prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) { int i; @@ -1710,7 +1273,7 @@ int sdl_info_ogl::draw(const int update) // if we have a texture to use for the vectors, use it here #if 0 - if (d3d->vector_texture != NULL) + if (d3d->vector_texture != nullptr) { printf("SDL: textured lines unsupported\n"); vertex[0].u0 = d3d->vector_texture->ustart; @@ -1795,7 +1358,7 @@ int sdl_info_ogl::draw(const int update) if ( texture ) { texture_disable(texture); - texture=NULL; + texture=nullptr; } break; @@ -1853,32 +1416,6 @@ static const GLint texture_copy_properties[9][2] = { }; //============================================================ -// drawogl_exit -//============================================================ - -static void drawogl_exit(void) -{ - int i; - - for(i=0; i<video_config.glsl_shader_mamebm_num; i++) - { - if ( NULL!=video_config.glsl_shader_mamebm[i]) - { - free(video_config.glsl_shader_mamebm[i]); - video_config.glsl_shader_mamebm[i] = NULL; - } - } - for(i=0; i<video_config.glsl_shader_scrn_num; i++) - { - if ( NULL!=video_config.glsl_shader_scrn[i]) - { - free(video_config.glsl_shader_scrn[i]); - video_config.glsl_shader_scrn[i] = NULL; - } - } -} - -//============================================================ // texture_compute_size and type //============================================================ @@ -1889,7 +1426,7 @@ static void drawogl_exit(void) // we also don't want to use PBO's in the case of nocopy==TRUE, // since we now might have GLSL shaders - this decision simplifies out life ;-) // -void sdl_info_ogl::texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 flags) +void renderer_ogl::texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 flags) { texture->type = TEXTURE_TYPE_NONE; texture->nocopy = FALSE; @@ -1943,7 +1480,7 @@ static inline int get_valid_pow2_value(int v, int needPow2) return (needPow2)?gl_round_to_pow2(v):v; } -void sdl_info_ogl::texture_compute_size_subroutine(ogl_texture_info *texture, UINT32 flags, +void renderer_ogl::texture_compute_size_subroutine(ogl_texture_info *texture, UINT32 flags, UINT32 width, UINT32 height, int* p_width, int* p_height, int* p_width_create, int* p_height_create) { @@ -1994,7 +1531,7 @@ void sdl_info_ogl::texture_compute_size_subroutine(ogl_texture_info *texture, UI *p_height_create=height_create; } -void sdl_info_ogl::texture_compute_size_type(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 flags) +void renderer_ogl::texture_compute_size_type(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 flags) { int finalheight, finalwidth; int finalheight_create, finalwidth_create; @@ -2126,7 +1663,7 @@ static int texture_fbo_create(UINT32 text_unit, UINT32 text_name, UINT32 fbo_nam } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, - 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL ); + 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr ); } // non-screen textures will never be filtered glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -2147,7 +1684,7 @@ static int texture_fbo_create(UINT32 text_unit, UINT32 text_name, UINT32 fbo_nam return 0; } -int sdl_info_ogl::texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 flags) +int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 flags) { int uniform_location; int i; @@ -2266,7 +1803,7 @@ int sdl_info_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth_create); - UINT32 * dummy = NULL; + UINT32 * dummy = nullptr; GLint _width, _height; if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8, texture->rawwidth_create, texture->rawheight_create, @@ -2320,7 +1857,7 @@ int sdl_info_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex return 0; } -ogl_texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, UINT32 flags) +ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource, UINT32 flags) { ogl_texture_info *texture; @@ -2363,7 +1900,7 @@ ogl_texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, texture->format = SDL_TEXFORMAT_ARGB32; break; case TEXFORMAT_RGB32: - if (texsource->palette != NULL) + if (texsource->palette != nullptr) texture->format = SDL_TEXFORMAT_RGB32_PALETTED; else texture->format = SDL_TEXFORMAT_RGB32; @@ -2375,7 +1912,7 @@ ogl_texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, texture->format = SDL_TEXFORMAT_PALETTE16A; break; case TEXFORMAT_YUY16: - if (texsource->palette != NULL) + if (texsource->palette != nullptr) texture->format = SDL_TEXFORMAT_YUY16_PALETTED; else texture->format = SDL_TEXFORMAT_YUY16; @@ -2400,7 +1937,7 @@ ogl_texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, if ( texture_shader_create(texsource, texture, flags) ) { global_free(texture); - return NULL; + return nullptr; } } else @@ -2417,7 +1954,7 @@ ogl_texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, glTexImage2D(texture->texTarget, 0, GL_RGBA8, texture->rawwidth_create, texture->rawheight_create, texture->borderpix ? 1 : 0, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr); if ((PRIMFLAG_GET_SCREENTEX(flags)) && video_config.filter) { @@ -2464,7 +2001,7 @@ ogl_texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, // set up the PBO dimension, .. pfn_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, texture->rawwidth * texture->rawheight * sizeof(UINT32), - NULL, GL_STREAM_DRAW); + nullptr, GL_STREAM_DRAW); } if ( !texture->nocopy && texture->type!=TEXTURE_TYPE_DYNAMIC ) @@ -2474,13 +2011,13 @@ ogl_texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, } // add us to the texture list - if (m_texhash[texture->hash] == NULL) + if (m_texhash[texture->hash] == nullptr) m_texhash[texture->hash] = texture; else { int i; for (i = HASH_SIZE; i < HASH_SIZE + OVERFLOW_SIZE; i++) - if (m_texhash[i] == NULL) + if (m_texhash[i] == nullptr) { m_texhash[i] = texture; break; @@ -2495,7 +2032,7 @@ ogl_texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName ); // Load The Data pfn_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW ); - glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // we are using ARB VBO buffers + glTexCoordPointer( 2, GL_FLOAT, 0, (char *) nullptr ); // we are using ARB VBO buffers } else { @@ -2562,7 +2099,7 @@ static inline void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, con assert(xborderpix == 0 || xborderpix == 1); // palette (really RGB map) case - if (palette != NULL) + if (palette != nullptr) { if (xborderpix) { @@ -2614,7 +2151,7 @@ static inline void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, co assert(xborderpix == 0 || xborderpix == 1); // palette (really RGB map) case - if (palette != NULL) + if (palette != nullptr) { if (xborderpix) { @@ -2703,7 +2240,7 @@ static inline void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int wi assert(width % 2 == 0); // palette (really RGB map) case - if (palette != NULL) + if (palette != nullptr) { if (xborderpix) { @@ -2876,7 +2413,7 @@ static void texture_set_data(ogl_texture_info *texture, const render_texinfo *te // kick off the DMA glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr); } else { @@ -2911,13 +2448,13 @@ static int compare_texture_primitive(const ogl_texture_info *texture, const rend return 0; } -ogl_texture_info *sdl_info_ogl::texture_find(const render_primitive *prim) +ogl_texture_info *renderer_ogl::texture_find(const render_primitive *prim) { HashT texhash = texture_compute_hash(&prim->texture, prim->flags); ogl_texture_info *texture; texture = m_texhash[texhash]; - if (texture != NULL) + if (texture != nullptr) { int i; if (compare_texture_primitive(texture, prim)) @@ -2925,18 +2462,18 @@ ogl_texture_info *sdl_info_ogl::texture_find(const render_primitive *prim) for (i=HASH_SIZE; i<HASH_SIZE + OVERFLOW_SIZE; i++) { texture = m_texhash[i]; - if (texture != NULL && compare_texture_primitive(texture, prim)) + if (texture != nullptr && compare_texture_primitive(texture, prim)) return texture; } } - return NULL; + return nullptr; } //============================================================ // texture_update //============================================================ -void sdl_info_ogl::texture_coord_update(ogl_texture_info *texture, const render_primitive *prim, int shaderIdx) +void renderer_ogl::texture_coord_update(ogl_texture_info *texture, const render_primitive *prim, int shaderIdx) { float ustart = 0.0f, ustop = 0.0f; // beginning/ending U coordinates float vstart = 0.0f, vstop = 0.0f; // beginning/ending V coordinates @@ -3013,7 +2550,7 @@ void sdl_info_ogl::texture_coord_update(ogl_texture_info *texture, const render_ } } -void sdl_info_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx) +void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx) { UINT32 mpass_src_idx = texture->mpass_dest_idx; @@ -3085,12 +2622,12 @@ void sdl_info_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx) } } -void sdl_info_ogl::texture_shader_update(ogl_texture_info *texture, render_container *container, int shaderIdx) +void renderer_ogl::texture_shader_update(ogl_texture_info *texture, render_container *container, int shaderIdx) { int uniform_location; GLfloat vid_attributes[4]; - if (container!=NULL) + if (container!=nullptr) { render_container::user_settings settings; container->get_user_settings(settings); @@ -3110,17 +2647,17 @@ void sdl_info_ogl::texture_shader_update(ogl_texture_info *texture, render_conta } } -ogl_texture_info * sdl_info_ogl::texture_update(const render_primitive *prim, int shaderIdx) +ogl_texture_info * renderer_ogl::texture_update(const render_primitive *prim, int shaderIdx) { ogl_texture_info *texture = texture_find(prim); int texBound = 0; // if we didn't find one, create a new texture - if (texture == NULL && prim->texture.base != NULL) + if (texture == nullptr && prim->texture.base != nullptr) { texture = texture_create(&prim->texture, prim->flags); } - else if (texture != NULL) + else if (texture != nullptr) { if ( texture->type == TEXTURE_TYPE_SHADER ) { @@ -3138,7 +2675,7 @@ ogl_texture_info * sdl_info_ogl::texture_update(const render_primitive *prim, in } } - if (texture != NULL) + if (texture != nullptr) { if ( texture->type == TEXTURE_TYPE_SHADER ) { @@ -3151,7 +2688,7 @@ ogl_texture_info * sdl_info_ogl::texture_update(const render_primitive *prim, in if ( shaderIdx==0 ) // redundant for subsequent multipass shader { - if (prim->texture.base != NULL && texture->texinfo.seqid != prim->texture.seqid) + if (prim->texture.base != nullptr && texture->texinfo.seqid != prim->texture.seqid) { texture->texinfo.seqid = prim->texture.seqid; @@ -3172,7 +2709,7 @@ ogl_texture_info * sdl_info_ogl::texture_update(const render_primitive *prim, in pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName ); // Load The Data pfn_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord ); - glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // we are using ARB VBO buffers + glTexCoordPointer( 2, GL_FLOAT, 0, (char *) nullptr ); // we are using ARB VBO buffers } else { @@ -3183,7 +2720,7 @@ ogl_texture_info * sdl_info_ogl::texture_update(const render_primitive *prim, in return texture; } -void sdl_info_ogl::texture_disable(ogl_texture_info * texture) +void renderer_ogl::texture_disable(ogl_texture_info * texture) { if ( texture->type == TEXTURE_TYPE_SHADER ) { @@ -3198,7 +2735,7 @@ void sdl_info_ogl::texture_disable(ogl_texture_info * texture) } } -void sdl_info_ogl::texture_all_disable() +void renderer_ogl::texture_all_disable() { if ( m_useglsl ) { diff --git a/src/osd/modules/render/drawogl.h b/src/osd/modules/render/drawogl.h new file mode 100644 index 00000000000..6407588e421 --- /dev/null +++ b/src/osd/modules/render/drawogl.h @@ -0,0 +1,233 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +//============================================================ +// +// drawogl.h - SDL software and OpenGL implementation +// +// SDLMAME by Olivier Galibert and R. Belmont +// +//============================================================ + +#pragma once + +#ifndef __DRAWOGL__ +#define __DRAWOGL__ + +// OSD headers +#ifndef OSD_WINDOWS +#include "osdsdl.h" +#include "window.h" +#else +#include "../windows/window.h" +typedef UINT64 HashT; +#endif + +#if defined(OSD_WINDOWS) +#include "winglcontext.h" +#else +#include "sdlglcontext.h" +#endif + +#include "modules/opengl/gl_shader_mgr.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(NULL), + 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 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 texture; // OpenGL texture "name"/ID + + GLenum texTarget; // OpenGL texture target + int texpow2; // Is this texture pow2 + + UINT32 mpass_dest_idx; // Multipass dest idx [0..1] + UINT32 mpass_textureunit[2]; // texture unit names for GLSL + + UINT32 mpass_texture_mamebm[2];// Multipass OpenGL texture "name"/ID for the shader + UINT32 mpass_fbo_mamebm[2]; // framebuffer object for this texture, multipass + UINT32 mpass_texture_scrn[2]; // Multipass OpenGL texture "name"/ID for the shader + UINT32 mpass_fbo_scrn[2]; // framebuffer object for this texture, multipass + + UINT32 pbo; // pixel buffer object for this texture (DYNAMIC only!) + UINT32 *data; // pixels for the texture + int data_own; // do we own / allocated it ? + GLfloat texCoord[8]; + GLuint texCoordBufferName; + +}; + +/* sdl_info is the information about SDL for the current screen */ +class renderer_ogl : public osd_renderer +{ +public: + renderer_ogl(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(NULL) + , 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] = NULL; + 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(); + + virtual int create() override; + virtual int init(running_machine &machine) 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 + { +#ifdef OSD_WINDOWS + osd_dim nd = window().get_size(); +#else + osd_dim nd = window().blit_surface_size(); +#endif + if (nd != m_blit_dim) + { + m_blit_dim = nd; + notify_changed(); + } + window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect()); + return &window().target()->get_primitives(); + } + +#ifdef OSD_WINDOWS + virtual void save() override { } + virtual void record() override { } + virtual void toggle_fsfx() override { } +#endif + +private: + static const UINT32 HASH_SIZE = ((1 << 10) + 1); + static const UINT32 OVERFLOW_SIZE = (1 << 10); + + void destroy_all_textures(); + + 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 flags); + void texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 flags); + void texture_compute_size_subroutine(ogl_texture_info *texture, UINT32 flags, + UINT32 width, UINT32 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 flags); + ogl_texture_info *texture_create(const render_texinfo *texsource, UINT32 flags); + int texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, UINT32 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 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 m_texture_max_width; // texture maximum width + INT32 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 m_surf_w; + INT32 m_surf_h; + GLfloat m_texVerticex[8]; + + static bool s_shown_video_info; + static bool s_dll_loaded; +}; + +#endif // __DRAWOGL__
\ No newline at end of file diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp index b9a40038082..c7b2cd5197e 100644 --- a/src/osd/modules/render/drawsdl.cpp +++ b/src/osd/modules/render/drawsdl.cpp @@ -26,6 +26,8 @@ #include "osdsdl.h" #include "window.h" +#include "drawsdl.h" + //============================================================ // DEBUGGING //============================================================ @@ -34,92 +36,10 @@ // CONSTANTS //============================================================ -//============================================================ -// TYPES -//============================================================ - -struct sdl_scale_mode; - #define DRAW2_SCALEMODE_NEAREST "0" #define DRAW2_SCALEMODE_LINEAR "1" #define DRAW2_SCALEMODE_BEST "2" -/* sdl_info is the information about SDL for the current screen */ -class sdl_info : public osd_renderer -{ -public: - - sdl_info(osd_window *w, int extra_flags) - : osd_renderer(w, extra_flags), - m_sdl_renderer(NULL), - m_texture_id(NULL), - m_yuv_lookup(NULL), - m_yuv_bitmap(NULL), - //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 */ 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 */ void destroy() override; - /* virtual */ render_primitive_list *get_primitives() override - { - osd_dim nd = window().blit_surface_size(); - if (nd != m_blit_dim) - { - m_blit_dim = nd; - notify_changed(); - } - window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect()); - return &window().target()->get_primitives(); - } - -private: - 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 m_blittimer; - - SDL_Renderer *m_sdl_renderer; - SDL_Texture *m_texture_id; - - // YUV overlay - UINT32 *m_yuv_lookup; - UINT16 *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 *bitmap, UINT8 *ptr, const int pitch, const UINT32 *lookup, const int width, const int height); -}; - -//============================================================ -// INLINES -//============================================================ - //============================================================ // PROTOTYPES //============================================================ @@ -150,25 +70,7 @@ static const sdl_scale_mode scale_modes[] = { "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 }, - { NULL } -}; - -//============================================================ -// drawsdl_scale_mode -//============================================================ - -const char *drawsdl_scale_mode_str(int index) -{ - const sdl_scale_mode *sm = scale_modes; - - while (index>0) - { - if (sm->name == NULL) - return NULL; - index--; - sm++; - } - return sm->name; + { nullptr } }; int drawsdl_scale_mode(const char *s) @@ -177,7 +79,7 @@ int drawsdl_scale_mode(const char *s) int index; index = 0; - while (sm->name != NULL) + while (sm->name != nullptr) { if (strcmp(sm->name, s) == 0) return index; @@ -187,40 +89,21 @@ int drawsdl_scale_mode(const char *s) return -1; } - -static osd_renderer *drawsdl_create(osd_window *window) -{ - // FIXME: QUALITY HINTS - return global_alloc(sdl_info(window, osd_renderer::FLAG_NONE)); -} - //============================================================ // drawsdl_init //============================================================ -int drawsdl_init(osd_draw_callbacks *callbacks) +int renderer_sdl2::init(running_machine &machine) { - // fill in the callbacks - callbacks->create = drawsdl_create; - callbacks->exit = drawsdl_exit; - osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n"); return 0; } //============================================================ -// drawsdl_exit -//============================================================ - -static void drawsdl_exit(void) -{ -} - -//============================================================ // setup_texture for window //============================================================ -void sdl_info::setup_texture(const osd_dim &size) +void renderer_sdl2::setup_texture(const osd_dim &size) { const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode]; SDL_DisplayMode mode; @@ -232,7 +115,7 @@ void sdl_info::setup_texture(const osd_dim &size) if (m_yuv_bitmap) { global_free_array(m_yuv_bitmap); - m_yuv_bitmap = NULL; + m_yuv_bitmap = nullptr; } fmt = (sdl_sm->pixel_format ? sdl_sm->pixel_format : mode.format); @@ -271,10 +154,11 @@ void sdl_info::setup_texture(const osd_dim &size) // drawsdl_show_info //============================================================ -static void drawsdl_show_info(struct SDL_RendererInfo *render_info) +void renderer_sdl::show_info(struct SDL_RendererInfo *render_info) { #define RF_ENTRY(x) {x, #x } - static struct { + static struct + { int flag; const char *name; } rflist[] = @@ -288,22 +172,20 @@ static void drawsdl_show_info(struct SDL_RendererInfo *render_info) #endif RF_ENTRY(SDL_RENDERER_PRESENTVSYNC), RF_ENTRY(SDL_RENDERER_ACCELERATED), - {-1, NULL} + {-1, nullptr} }; - int i; osd_printf_verbose("window: using renderer %s\n", render_info->name ? render_info->name : "<unknown>"); - for (i = 0; rflist[i].name != NULL; i++) + for (int i = 0; rflist[i].name != nullptr; i++) if (render_info->flags & rflist[i].flag) osd_printf_verbose("renderer: flag %s\n", rflist[i].name); } //============================================================ -// sdl_info::create +// renderer_sdl2::create //============================================================ - -int sdl_info::create() +int renderer_sdl2::create() { const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode]; @@ -331,27 +213,25 @@ int sdl_info::create() fatalerror("Error on creating renderer: %s\n", SDL_GetError()); } - { - struct SDL_RendererInfo render_info; + struct SDL_RendererInfo render_info; - SDL_GetRendererInfo(m_sdl_renderer, &render_info); - drawsdl_show_info(&render_info); + SDL_GetRendererInfo(m_sdl_renderer, &render_info); + show_info(&render_info); - // Check scale mode + // Check scale mode - if (sm->pixel_format) - { - int i; - int found = 0; + if (sm->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]) - found = 1; + for (i=0; i < render_info.num_texture_formats; i++) + if (sm->pixel_format == render_info.texture_formats[i]) + found = 1; - if (!found) - { - fatalerror("window: Scale mode %s not supported!", sm->name); - } + if (!found) + { + fatalerror("window: Scale mode %s not supported!", sm->name); } } @@ -361,33 +241,31 @@ int sdl_info::create() setup_texture(w, h); #endif - m_yuv_lookup = NULL; + m_yuv_lookup = nullptr; m_blittimer = 0; yuv_init(); - osd_printf_verbose("Leave sdl_info::create\n"); + osd_printf_verbose("Leave renderer_sdl2::create\n"); return 0; } //============================================================ -// sdl_info::destroy +// DESTRUCTOR //============================================================ -void sdl_info::destroy() +renderer_sdl2::~renderer_sdl2() { - // free the memory in the window - destroy_all_textures(); - if (m_yuv_lookup != NULL) + if (m_yuv_lookup != nullptr) { global_free_array(m_yuv_lookup); - m_yuv_lookup = NULL; + m_yuv_lookup = nullptr; } - if (m_yuv_bitmap != NULL) + if (m_yuv_bitmap != nullptr) { global_free_array(m_yuv_bitmap); - m_yuv_bitmap = NULL; + m_yuv_bitmap = nullptr; } SDL_DestroyRenderer(m_sdl_renderer); } @@ -396,7 +274,7 @@ void sdl_info::destroy() // drawsdl_xy_to_render_target //============================================================ -int sdl_info::xy_to_render_target(int x, int y, int *xt, int *yt) +int renderer_sdl2::xy_to_render_target(int x, int y, int *xt, int *yt) { *xt = x - m_last_hofs; *yt = y - m_last_vofs; @@ -411,18 +289,18 @@ int sdl_info::xy_to_render_target(int x, int y, int *xt, int *yt) // drawsdl_destroy_all_textures //============================================================ -void sdl_info::destroy_all_textures() +void renderer_sdl2::destroy_all_textures() { SDL_DestroyTexture(m_texture_id); - m_texture_id = NULL; + m_texture_id = nullptr; } //============================================================ -// sdl_info::draw +// renderer_sdl2::draw //============================================================ -int sdl_info::draw(int update) +int renderer_sdl2::draw(int update) { const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode]; UINT8 *surfptr; @@ -444,8 +322,8 @@ int sdl_info::draw(int update) clear_flags(FI_CHANGED); m_blittimer = 3; m_last_dim = wdim; - SDL_RenderSetViewport(m_sdl_renderer, NULL); - if (m_texture_id != NULL) + SDL_RenderSetViewport(m_sdl_renderer, nullptr); + if (m_texture_id != nullptr) SDL_DestroyTexture(m_texture_id); setup_texture(m_blit_dim); m_blittimer = 3; @@ -467,12 +345,12 @@ int sdl_info::draw(int update) { /* SDL Underlays need alpha = 0 ! */ SDL_SetRenderDrawColor(m_sdl_renderer,0,0,0,0); - SDL_RenderFillRect(m_sdl_renderer,NULL); - //SDL_RenderFill(0,0,0,0 /*255*/,NULL); + SDL_RenderFillRect(m_sdl_renderer,nullptr); + //SDL_RenderFill(0,0,0,0 /*255*/,nullptr); m_blittimer--; } - SDL_LockTexture(m_texture_id, NULL, (void **) &surfptr, &pitch); + SDL_LockTexture(m_texture_id, nullptr, (void **) &surfptr, &pitch); // get ready to center the image vofs = hofs = 0; @@ -522,7 +400,7 @@ int sdl_info::draw(int update) // FIXME: this could be a lot easier if we get the primlist here! // Bounds would be set fit for purpose and done! - for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next()) + for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) { prim->bounds.x0 = floor(fw * prim->bounds.x0 + 0.5f); prim->bounds.x1 = floor(fw * prim->bounds.x1 + 0.5f); @@ -562,8 +440,8 @@ int sdl_info::draw(int update) } else { - assert (m_yuv_bitmap != NULL); - assert (surfptr != NULL); + assert (m_yuv_bitmap != nullptr); + assert (surfptr != nullptr); software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, m_yuv_bitmap, mamewidth, mameheight, mamewidth); sm->yuv_blit((UINT16 *)m_yuv_bitmap, surfptr, pitch, m_yuv_lookup, mamewidth, mameheight); } @@ -580,8 +458,8 @@ int sdl_info::draw(int update) r.w=blitwidth; r.h=blitheight; //printf("blitwidth %d %d - %d %d\n", blitwidth, blitheight, window().width, window().height); - //SDL_UpdateTexture(sdltex, NULL, sdlsurf->pixels, pitch); - SDL_RenderCopy(m_sdl_renderer,m_texture_id, NULL, &r); + //SDL_UpdateTexture(sdltex, nullptr, sdlsurf->pixels, pitch); + SDL_RenderCopy(m_sdl_renderer,m_texture_id, nullptr, &r); SDL_RenderPresent(m_sdl_renderer); } return 0; @@ -627,7 +505,7 @@ int sdl_info::draw(int update) #define YMASK (Y1MASK|Y2MASK) #define UVMASK (UMASK|VMASK) -void sdl_info::yuv_lookup_set(unsigned int pen, unsigned char red, +void renderer_sdl2::yuv_lookup_set(unsigned int pen, unsigned char red, unsigned char green, unsigned char blue) { UINT32 y,u,v; @@ -639,10 +517,10 @@ void sdl_info::yuv_lookup_set(unsigned int pen, unsigned char red, m_yuv_lookup[pen]=(y<<Y1SHIFT)|(u<<USHIFT)|(y<<Y2SHIFT)|(v<<VSHIFT); } -void sdl_info::yuv_init() +void renderer_sdl2::yuv_init() { unsigned char r,g,b; - if (m_yuv_lookup == NULL) + if (m_yuv_lookup == nullptr) m_yuv_lookup = global_alloc_array(UINT32, 65536); for (r = 0; r < 32; r++) for (g = 0; g < 32; g++) @@ -794,3 +672,15 @@ static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, } } } + +render_primitive_list *renderer_sdl2::get_primitives() +{ + osd_dim nd = window().blit_surface_size(); + if (nd != m_blit_dim) + { + m_blit_dim = nd; + notify_changed(); + } + window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect()); + return &window().target()->get_primitives(); +} diff --git a/src/osd/modules/render/drawsdl.h b/src/osd/modules/render/drawsdl.h new file mode 100644 index 00000000000..d22c27f8c6f --- /dev/null +++ b/src/osd/modules/render/drawsdl.h @@ -0,0 +1,84 @@ +// 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 +// +//============================================================ + +#pragma once + +#ifndef __DRAWSDL2__ +#define __DRAWSDL2__ + +/* renderer_sdl2 is the information about SDL for the current screen */ +class renderer_sdl2 : public osd_renderer +{ +public: + + renderer_sdl2(osd_window *w, int extra_flags) + : osd_renderer(w, extra_flags) + , m_sdl_renderer(NULL) + , m_texture_id(NULL) + , m_yuv_lookup(NULL) + , m_yuv_bitmap(NULL) + //, 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_sdl2(); + + /* virtual */ int create() override; + /* virtual */ int init(running_machine &machine) 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 m_blittimer; + + SDL_Renderer *m_sdl_renderer; + SDL_Texture *m_texture_id; + + // YUV overlay + UINT32 *m_yuv_lookup; + UINT16 *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 *bitmap, UINT8 *ptr, const int pitch, const UINT32 *lookup, const int width, const int height); +}; + +#endif // __DRAWSDL2__
\ No newline at end of file diff --git a/src/osd/modules/render/sdlglcontext.h b/src/osd/modules/render/sdlglcontext.h new file mode 100644 index 00000000000..27c0bbe68a6 --- /dev/null +++ b/src/osd/modules/render/sdlglcontext.h @@ -0,0 +1,67 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +//============================================================ +// +// sdlglcontext.h - SDL-specific GL context +// +// SDLMAME by Olivier Galibert and R. Belmont +// +//============================================================ + +#pragma once + +#ifndef __SDL_GL_CONTEXT__ +#define __SDL_GL_CONTEXT__ + +#include "modules/opengl/osd_opengl.h" + +class sdl_gl_context : public osd_gl_context +{ +public: + sdl_gl_context(SDL_Window *window) : osd_gl_context(), m_context(0), m_window(window) + { + m_error[0] = 0; + m_context = SDL_GL_CreateContext(window); + if (!m_context) + { + snprintf(m_error,255, "OpenGL not supported on this driver: %s", SDL_GetError()); + } + } + virtual ~sdl_gl_context() + { + SDL_GL_DeleteContext(m_context); + } + virtual void MakeCurrent() override + { + SDL_GL_MakeCurrent(m_window, m_context); + } + + virtual int SetSwapInterval(const int swap) override + { + return SDL_GL_SetSwapInterval(swap); + } + + virtual const char *LastErrorMsg() override + { + if (m_error[0] == 0) + return NULL; + else + return m_error; + } + virtual void *getProcAddress(const char *proc) override + { + return SDL_GL_GetProcAddress(proc); + } + + virtual void SwapBuffer() override + { + SDL_GL_SwapWindow(m_window); + } + +private: + SDL_GLContext m_context; + SDL_Window *m_window; + char m_error[256]; +}; + +#endif // __SDL_GL_CONTEXT__
\ No newline at end of file diff --git a/src/osd/modules/render/winglcontext.h b/src/osd/modules/render/winglcontext.h new file mode 100644 index 00000000000..44a30888fa5 --- /dev/null +++ b/src/osd/modules/render/winglcontext.h @@ -0,0 +1,170 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +//============================================================ +// +// winglcontext.h - Windows-specific GL context +// +// SDLMAME by Olivier Galibert and R. Belmont +// +//============================================================ + +#pragma once + +#ifndef __WIN_GL_CONTEXT__ +#define __WIN_GL_CONTEXT__ + +#include "modules/opengl/osd_opengl.h" + +class win_gl_context : public osd_gl_context +{ +public: + win_gl_context(HWND window) : osd_gl_context(), m_context(0), m_window(NULL), m_hdc(0) + { + m_error[0] = 0; + + this->pfn_wglGetProcAddress = (PROC (WINAPI *)(LPCSTR lpszProc)) GetProcAddress(m_module, "wglGetProcAddress"); + this->pfn_wglCreateContext = (HGLRC (WINAPI *)(HDC hdc)) GetProcAddress(m_module, "wglCreateContext"); + this->pfn_wglDeleteContext = (BOOL (WINAPI *)(HGLRC hglrc)) GetProcAddress(m_module, "wglDeleteContext"); + this->pfn_wglMakeCurrent = (BOOL (WINAPI *)(HDC hdc, HGLRC hglrc)) GetProcAddress(m_module, "wglMakeCurrent"); + + this->pfn_wglGetExtensionsStringEXT = (const char *(WINAPI *) (void)) pfn_wglGetProcAddress("wglGetExtensionsStringEXT"); + + if (WGLExtensionSupported("WGL_EXT_swap_control")) + { + this->pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT"); + this->pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("wglGetSwapIntervalEXT"); + } + else + { + pfn_wglSwapIntervalEXT = NULL; + pfn_wglGetSwapIntervalEXT = NULL; + } + + m_hdc = GetDC(window); + if (!setupPixelFormat(m_hdc)) + { + m_context = this->pfn_wglCreateContext(m_hdc); + if (!m_context) + { + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, m_error, 255, NULL); + return; + } + this->pfn_wglMakeCurrent(m_hdc, m_context); + } + } + + virtual ~win_gl_context() + { + this->pfn_wglDeleteContext(m_context); + ReleaseDC(m_window, m_hdc); + } + + virtual void MakeCurrent() override + { + this->pfn_wglMakeCurrent(m_hdc, m_context); + } + + virtual const char *LastErrorMsg() override + { + if (m_error[0] == 0) + return NULL; + else + return m_error; + } + + virtual void *getProcAddress(const char *proc) override + { + void *ret = (void *) GetProcAddress(m_module, proc); + if (ret == NULL) + ret = (void *) this->pfn_wglGetProcAddress(proc); + return ret; + } + + virtual int SetSwapInterval(const int swap) override + { + if (this->pfn_wglSwapIntervalEXT != NULL) + { + this->pfn_wglSwapIntervalEXT(swap ? 1 : 0); + } + return 0; + } + + virtual void SwapBuffer() override + { + SwapBuffers(m_hdc); + //wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE); + } + + static void load_library() + { + m_module = LoadLibraryA("opengl32.dll"); + } + +private: + + int setupPixelFormat(HDC hDC) + { + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + PFD_SUPPORT_OPENGL | + PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER, /* support double-buffering */ + PFD_TYPE_RGBA, /* color type */ + 32, /* prefered color depth */ + 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ + 0, /* no alpha buffer */ + 0, /* alpha bits (ignored) */ + 0, /* no accumulation buffer */ + 0, 0, 0, 0, /* accum bits (ignored) */ + 16, /* depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0, /* no layer, visible, damage masks */ + }; + int pixelFormat; + + pixelFormat = ChoosePixelFormat(hDC, &pfd); + if (pixelFormat == 0) { + strcpy(m_error, "ChoosePixelFormat failed"); + return 1; + } + + if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) { + strcpy(m_error, "SetPixelFormat failed."); + return 1; + } + return 0; + } + + bool WGLExtensionSupported(const char *extension_name) + { + //if (pfn_wglGetExtensionsStringEXT != NULL) + // printf("%s\n", this->pfn_wglGetExtensionsStringEXT()); + + if (pfn_wglGetExtensionsStringEXT != NULL && strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != NULL) + return true; + else + return false; + } + + HGLRC m_context; + HWND m_window; + HDC m_hdc; + char m_error[256]; + + PROC (WINAPI *pfn_wglGetProcAddress)(LPCSTR lpszProc); + HGLRC (WINAPI *pfn_wglCreateContext)(HDC hdc); + BOOL (WINAPI *pfn_wglDeleteContext)(HGLRC hglrc); + BOOL (WINAPI *pfn_wglMakeCurrent)(HDC hdc, HGLRC hglrc); + + const char *(WINAPI *pfn_wglGetExtensionsStringEXT) (void); + BOOL (WINAPI *pfn_wglSwapIntervalEXT) (int interval); + int (WINAPI * pfn_wglGetSwapIntervalEXT) (void); + + static HMODULE m_module; +}; + +#endif // __WIN_GL_CONTEXT__
\ No newline at end of file diff --git a/src/osd/osdepend.h b/src/osd/osdepend.h index 5b57f55881c..9e19b1419b1 100644 --- a/src/osd/osdepend.h +++ b/src/osd/osdepend.h @@ -41,6 +41,8 @@ public: // ======================> osd_interface +class slider_state; + // description of the currently-running machine class osd_interface { @@ -63,7 +65,7 @@ public: virtual void customize_input_type_list(simple_list<input_type_entry> &typelist) = 0; // video overridables - virtual void *get_slider_list() = 0; // FIXME: returns slider_state * + virtual slider_state *get_slider_list() = 0; // font interface virtual osd_font *font_alloc() = 0; diff --git a/src/osd/sdl/video.h b/src/osd/sdl/video.h index a811a417ef4..3b2c5ea81cd 100644 --- a/src/osd/sdl/video.h +++ b/src/osd/sdl/video.h @@ -19,13 +19,6 @@ #define MAX_VIDEO_WINDOWS (4) -enum { - VIDEO_MODE_SOFT = 0, - VIDEO_MODE_OPENGL, - VIDEO_MODE_SDL2ACCEL, - VIDEO_MODE_BGFX -}; - #define VIDEO_SCALE_MODE_NONE (0) #define GLSL_SHADER_MAX 10 @@ -34,114 +27,11 @@ enum { // TYPE DEFINITIONS //============================================================ -class osd_dim -{ -public: - osd_dim(const int &w, const int &h) - : m_w(w), m_h(h) - { - } - int width() const { return m_w; } - int height() const { return m_h; } - - bool operator!=(const osd_dim &other) { return (m_w != other.width()) || (m_h != other.height()); } - bool operator==(const osd_dim &other) { return (m_w == other.width()) && (m_h == other.height()); } -private: - int m_w; - int m_h; -}; - -class osd_rect -{ -public: - osd_rect() - : m_x(0), m_y(0), m_d(0,0) - { - } - osd_rect(const int x, const int y, const int &w, const int &h) - : m_x(x), m_y(y), m_d(w,h) - { - } - osd_rect(const int x, const int y, const osd_dim &d) - : m_x(x), m_y(y), m_d(d) - { - } - int top() const { return m_y; } - int left() const { return m_x; } - int width() const { return m_d.width(); } - int height() const { return m_d.height(); } - - osd_dim dim() const { return m_d; } - - int bottom() const { return m_y + m_d.height(); } - int right() const { return m_x + m_d.width(); } - - osd_rect move_by(int dx, int dy) const { return osd_rect(m_x + dx, m_y + dy, m_d); } - osd_rect resize(int w, int h) const { return osd_rect(m_x, m_y, w, h); } - -private: - int m_x; - int m_y; - osd_dim m_d; -}; - inline osd_rect SDL_Rect_to_osd_rect(const SDL_Rect &r) { return osd_rect(r.x, r.y, r.w, r.h); } -class osd_monitor_info -{ -public: - -#if 0 - osd_monitor_info() - : m_next(NULL), m_handle(NULL), m_aspect(0.0f) - { - strcpy(m_name, ""); - } -#endif - osd_monitor_info(void *handle, const char *monitor_device, float aspect) - : m_next(NULL), m_handle(handle), m_aspect(aspect) - { - strncpy(m_name, monitor_device, ARRAY_LENGTH(m_name) - 1); - } - - virtual ~osd_monitor_info() { } - - virtual void refresh() = 0; - - const void *oshandle() { return m_handle; } - - const osd_rect &position_size() { return m_pos_size; } - const osd_rect &usuable_position_size() { return m_usuable_pos_size; } - - const char *devicename() { return m_name[0] ? m_name : "UNKNOWN"; } - - float aspect(); - - void set_aspect(const float a) { m_aspect = a; } - bool is_primary() { return m_is_primary; } - - osd_monitor_info * next() { return m_next; } // pointer to next monitor in list - - static osd_monitor_info *pick_monitor(sdl_options &options, int index); - static osd_monitor_info *list; - - // FIXME: should be private! - osd_monitor_info *m_next; // pointer to next monitor in list -protected: - osd_rect m_pos_size; - osd_rect m_usuable_pos_size; - bool m_is_primary; - char m_name[64]; -private: - - void * m_handle; // handle to the monitor - float m_aspect; // computed/configured aspect ratio of the physical device -}; - - class sdl_monitor_info : public osd_monitor_info { public: diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp index 113a00b47bf..0f7b86e6611 100644 --- a/src/osd/sdl/window.cpp +++ b/src/osd/sdl/window.cpp @@ -94,11 +94,9 @@ static SDL_threadID window_threadid; // debugger //static int in_background; -static osd_draw_callbacks draw; - struct worker_param { worker_param() - : m_window(NULL), m_list(NULL), m_resize_new_width(0), m_resize_new_height(0) + : m_window(nullptr), m_list(nullptr), m_resize_new_width(0), m_resize_new_height(0) { } worker_param(sdl_window_info *awindow, render_primitive_list &alist) @@ -106,14 +104,14 @@ struct worker_param { { } worker_param(sdl_window_info *awindow, int anew_width, int anew_height) - : m_window(awindow), m_list(NULL), m_resize_new_width(anew_width), m_resize_new_height(anew_height) + : m_window(awindow), m_list(nullptr), m_resize_new_width(anew_width), m_resize_new_height(anew_height) { } worker_param(sdl_window_info *awindow) - : m_window(awindow), m_list(NULL), m_resize_new_width(0), m_resize_new_height(0) + : m_window(awindow), m_list(nullptr), m_resize_new_width(0), m_resize_new_height(0) { } - sdl_window_info *window() const { assert(m_window != NULL); return m_window; } + sdl_window_info *window() const { assert(m_window != nullptr); return m_window; } render_primitive_list *list() const { return m_list; } int new_width() const { return m_resize_new_width; } int new_height() const { return m_resize_new_height; } @@ -187,7 +185,7 @@ static OSDWORK_CALLBACK(sdlwindow_thread_id) exit(-1); } } - return NULL; + return nullptr; } @@ -210,39 +208,25 @@ bool sdl_osd_interface::window_init() { // create a thread to run the windows from work_queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_IO); - if (work_queue == NULL) + if (work_queue == nullptr) return false; - osd_work_item_queue(work_queue, &sdlwindow_thread_id, NULL, WORK_ITEM_FLAG_AUTO_RELEASE); + osd_work_item_queue(work_queue, &sdlwindow_thread_id, nullptr, WORK_ITEM_FLAG_AUTO_RELEASE); sdlwindow_sync(); } else { // otherwise, treat the window thread as the main thread //window_threadid = main_threadid; - sdlwindow_thread_id(NULL, 0); + sdlwindow_thread_id(nullptr, 0); } // initialize the drawers -#if USE_OPENGL - if (video_config.mode == VIDEO_MODE_OPENGL) - { - if (drawogl_init(machine(), &draw)) - video_config.mode = VIDEO_MODE_SOFT; - } -#endif - if (video_config.mode == VIDEO_MODE_SDL2ACCEL) - { - if (drawsdl2_init(machine(), &draw)) - video_config.mode = VIDEO_MODE_SOFT; - } - if (video_config.mode == VIDEO_MODE_BGFX) - { - if (drawbgfx_init(machine(), &draw)) - video_config.mode = VIDEO_MODE_SOFT; - } + if (m_renderer->init(machine())) + video_config.mode = VIDEO_MODE_SOFT; + if (video_config.mode == VIDEO_MODE_SOFT) { - if (drawsdl_init(&draw)) + if (m_renderer->init(machine())) return false; } @@ -271,11 +255,11 @@ 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 - NULL + nullptr }; osd_printf_verbose("\nHints:\n"); - for (int i = 0; hints[i] != NULL; i++) + for (int i = 0; hints[i] != nullptr; i++) osd_printf_verbose("\t%-40s %s\n", hints[i], SDL_GetHint(hints[i])); // set up the window list @@ -315,7 +299,7 @@ static OSDWORK_CALLBACK( sdlwindow_exit_wt ) if (param) osd_free(param); - return NULL; + return nullptr; } @@ -328,7 +312,7 @@ void sdl_osd_interface::window_exit() osd_printf_verbose("Enter sdlwindow_exit\n"); // free all the windows - while (sdl_window_list != NULL) + while (sdl_window_list != nullptr) { sdl_window_info *temp = sdl_window_list; sdl_window_list = temp->m_next; @@ -344,7 +328,7 @@ void sdl_osd_interface::window_exit() } // kill the drawers - (*draw.exit)(); + delete render_module; execute_async_wait(&sdlwindow_exit_wt, wp_dummy); @@ -464,7 +448,7 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_resize_wt ) window->renderer().notify_changed(); osd_free(wp); - return NULL; + return nullptr; } void sdl_window_info::resize(INT32 width, INT32 height) @@ -492,7 +476,7 @@ OSDWORK_CALLBACK( sdl_window_info::notify_changed_wt ) window->renderer().notify_changed(); osd_free(wp); - return NULL; + return nullptr; } void sdl_window_info::notify_changed() @@ -522,7 +506,7 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) // if we are in debug mode, never go full screen if (window->machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) - return NULL; + return nullptr; // If we are going fullscreen (leaving windowed) remember our windowed size if (!window->fullscreen()) @@ -530,9 +514,8 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) window->m_windowed_dim = window->get_size(); } - window->renderer().destroy(); global_free(window->m_renderer); - window->m_renderer = NULL; + window->m_renderer = nullptr; bool is_osx = false; #ifdef SDLMAME_MACOSX @@ -548,14 +531,16 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) SDL_DestroyWindow(window->sdl_window()); sdlinput_release_keys(); - window->set_renderer(draw.create(window)); + osd_renderer *renderer = osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(this)); + renderer->init(window->machine()); + window->set_renderer(renderer); // toggle the window mode window->set_fullscreen(!window->fullscreen()); complete_create_wt(param, 0); - return NULL; + return nullptr; } void sdl_window_info::toggle_full_screen() @@ -632,7 +617,7 @@ void sdl_window_info::update_cursor_state() SDL_SetWindowGrab(sdl_window(), SDL_TRUE); SDL_SetRelativeMouseMode(SDL_TRUE); } - SDL_SetCursor(NULL); // Force an update in case the underlying driver has changed visibility + SDL_SetCursor(nullptr); // Force an update in case the underlying driver has changed visibility } #endif } @@ -645,7 +630,7 @@ OSDWORK_CALLBACK( sdl_window_info::update_cursor_state_wt ) window->update_cursor_state(); osd_free(wp); - return NULL; + return nullptr; } int sdl_window_info::xy_to_render_target(int x, int y, int *xt, int *yt) @@ -674,6 +659,7 @@ int sdl_window_info::window_init() *last_window_ptr = this; last_window_ptr = &this->m_next; + osd_renderer* renderer = set_renderer(draw.create(this)); // create an event that we can use to skip blitting @@ -731,7 +717,8 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_video_window_destroy_wt ) ASSERT_WINDOW_THREAD(); // free the textures etc - window->renderer().destroy(); + global_free(window->m_renderer); + window->m_renderer = nullptr; if (window->fullscreen() && video_config.switchres) { @@ -745,7 +732,7 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_video_window_destroy_wt ) osd_free(wp); - return NULL; + return nullptr; } void sdl_window_info::destroy() @@ -761,7 +748,7 @@ void sdl_window_info::destroy() //osd_event_wait(window->rendered_event, osd_ticks_per_second()*10); // remove us from the list - for (prevptr = &sdl_window_list; *prevptr != NULL; prevptr = &(*prevptr)->m_next) + for (prevptr = &sdl_window_list; *prevptr != nullptr; prevptr = &(*prevptr)->m_next) if (*prevptr == this) { *prevptr = this->m_next; @@ -869,7 +856,7 @@ void sdl_window_info::update() execute_async(&update_cursor_state_wt, worker_param(this)); // if we're visible and running and not in the middle of a resize, draw - if (m_target != NULL) + if (m_target != nullptr) { int tempwidth, tempheight; @@ -1033,7 +1020,7 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) //window().sdl_window() = SDL_CreateWindow(window().m_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, // width, height, m_extra_flags); - if ( window->m_sdl_window == NULL ) + if ( window->m_sdl_window == nullptr ) { if (window->renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL)) osd_printf_error("OpenGL not supported on this driver: %s\n", SDL_GetError()); @@ -1064,7 +1051,7 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) } else { - //SDL_SetWindowDisplayMode(window().sdl_window(), NULL); // Use desktop + //SDL_SetWindowDisplayMode(window().sdl_window(), nullptr); // Use desktop } // show window @@ -1082,7 +1069,7 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) // set main window if (window->m_index > 0) { - for (auto w = sdl_window_list; w != NULL; w = w->m_next) + for (auto w = sdl_window_list; w != nullptr; w = w->m_next) { if (w->m_index == 0) { @@ -1169,7 +1156,7 @@ OSDWORK_CALLBACK( sdl_window_info::draw_video_contents_wt ) int scrnum = 0; int is_vector = 0; screen_device_iterator iter(window->machine().root_device()); - for (const screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) + for (const screen_device *screen = iter.first(); screen != nullptr; screen = iter.next()) { if (scrnum == window->m_index) { @@ -1192,7 +1179,7 @@ OSDWORK_CALLBACK( sdl_window_info::draw_video_contents_wt ) window->m_primlist = wp->list(); // if no bitmap, just fill - if (window->m_primlist == NULL) + if (window->m_primlist == nullptr) { } // otherwise, render with our drawing system @@ -1208,7 +1195,7 @@ OSDWORK_CALLBACK( sdl_window_info::draw_video_contents_wt ) osd_event_set(window->m_rendered_event); osd_free(wp); - return NULL; + return nullptr; } int sdl_window_info::wnd_extra_width() diff --git a/src/osd/sdl/window.h b/src/osd/sdl/window.h index bdaaa311330..f10bf6fbd92 100644 --- a/src/osd/sdl/window.h +++ b/src/osd/sdl/window.h @@ -161,7 +161,6 @@ private: struct osd_draw_callbacks { osd_renderer *(*create)(osd_window *window); - void (*exit)(void); }; //============================================================ @@ -179,8 +178,6 @@ extern sdl_window_info *sdl_window_list; // PROTOTYPES - drawsdl.c //============================================================ -int drawsdl_init(osd_draw_callbacks *callbacks); -const char *drawsdl_scale_mode_str(int index); int drawsdl_scale_mode(const char *s); //============================================================ diff --git a/src/osd/windows/video.cpp b/src/osd/windows/video.cpp index b441121f1ca..c814310fb29 100644 --- a/src/osd/windows/video.cpp +++ b/src/osd/windows/video.cpp @@ -23,6 +23,8 @@ #include "input.h" #include "strconv.h" +#include "modules/osdwindow.h" + //============================================================ // CONSTANTS //============================================================ @@ -266,8 +268,9 @@ static void init_monitors(void) // pick_monitor //============================================================ -osd_monitor_info *osd_monitor_info::pick_monitor(windows_options &options, int index) +osd_monitor_info *osd_monitor_info::pick_monitor(osd_options &osdopts, int index) { + windows_options &options = reinterpret_cast<windows_options &>(osdopts); osd_monitor_info *monitor; const char *scrname, *scrname2; int moncount = 0; diff --git a/src/osd/windows/video.h b/src/osd/windows/video.h index 87612fb51fe..e3c895c1726 100644 --- a/src/osd/windows/video.h +++ b/src/osd/windows/video.h @@ -11,6 +11,7 @@ #include "render.h" #include "winmain.h" +#include "modules/osdwindow.h" //============================================================ // CONSTANTS @@ -18,129 +19,17 @@ #define MAX_WINDOWS 4 -enum { - VIDEO_MODE_NONE, - VIDEO_MODE_GDI, - VIDEO_MODE_BGFX, -#if (USE_OPENGL) - VIDEO_MODE_OPENGL, -#endif - VIDEO_MODE_D3D -}; - #define GLSL_SHADER_MAX 10 //============================================================ // TYPE DEFINITIONS //============================================================ -class osd_dim -{ -public: - osd_dim(const int &w, const int &h) - : m_w(w), m_h(h) - { - } - int width() const { return m_w; } - int height() const { return m_h; } - - bool operator!=(const osd_dim &other) { return (m_w != other.width()) || (m_h != other.height()); } - bool operator==(const osd_dim &other) { return (m_w == other.width()) && (m_h == other.height()); } -private: - int m_w; - int m_h; -}; - -class osd_rect -{ -public: - osd_rect() - : m_x(0), m_y(0), m_d(0,0) - { - } - osd_rect(const int x, const int y, const int &w, const int &h) - : m_x(x), m_y(y), m_d(w,h) - { - } - osd_rect(const int x, const int y, const osd_dim &d) - : m_x(x), m_y(y), m_d(d) - { - } - int top() const { return m_y; } - int left() const { return m_x; } - int width() const { return m_d.width(); } - int height() const { return m_d.height(); } - - osd_dim dim() const { return m_d; } - - int bottom() const { return m_y + m_d.height(); } - int right() const { return m_x + m_d.width(); } - - osd_rect move_by(int dx, int dy) const { return osd_rect(m_x + dx, m_y + dy, m_d); } - osd_rect resize(int w, int h) const { return osd_rect(m_x, m_y, w, h); } - -private: - int m_x; - int m_y; - osd_dim m_d; -}; - inline osd_rect RECT_to_osd_rect(const RECT &r) { return osd_rect(r.left, r.top, r.right - r.left, r.bottom - r.top); } -class osd_monitor_info -{ -public: - -#if 0 - osd_monitor_info() - : m_next(NULL), m_handle(NULL), m_aspect(0.0f) - { - strcpy(m_name, ""); - } -#endif - osd_monitor_info(void *handle, const char *monitor_device, float aspect) - : m_next(NULL), m_handle(handle), m_aspect(aspect) - { - strncpy(m_name, monitor_device, ARRAY_LENGTH(m_name) - 1); - } - - virtual ~osd_monitor_info() { } - - virtual void refresh() = 0; - - const void *oshandle() { return m_handle; } - - const osd_rect &position_size() { return m_pos_size; } - const osd_rect &usuable_position_size() { return m_usuable_pos_size; } - - const char *devicename() { return m_name[0] ? m_name : "UNKNOWN"; } - - float aspect(); - - void set_aspect(const float a) { m_aspect = a; } - bool is_primary() { return m_is_primary; } - - osd_monitor_info * next() { return m_next; } // pointer to next monitor in list - - static osd_monitor_info *pick_monitor(windows_options &options, int index); - static osd_monitor_info *list; - - // FIXME: should be private! - osd_monitor_info *m_next; // pointer to next monitor in list -protected: - osd_rect m_pos_size; - osd_rect m_usuable_pos_size; - bool m_is_primary; - char m_name[64]; -private: - - void * m_handle; // handle to the monitor - float m_aspect; // computed/configured aspect ratio of the physical device -}; - class win_monitor_info : public osd_monitor_info { public: diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp index 0fbfae9c481..5a5520fc328 100644 --- a/src/osd/windows/window.cpp +++ b/src/osd/windows/window.cpp @@ -12,12 +12,6 @@ // Needed for RAW Input #define WM_INPUT 0x00FF -// standard windows headers -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <windowsx.h> -#include <mmsystem.h> - // standard C headers #include <process.h> @@ -34,14 +28,6 @@ #include "winutil.h" -extern int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks); -extern int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks); -extern int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks); -extern int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks); -#if (USE_OPENGL) -extern int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks); -#endif - //============================================================ // PARAMETERS //============================================================ @@ -107,8 +93,6 @@ static DWORD window_threadid; static DWORD last_update_time; -static osd_draw_callbacks draw; - static HANDLE ui_pause_event; static HANDLE window_thread_ready_event; @@ -183,7 +167,7 @@ bool windows_osd_interface::window_init() create_window_class(); // create an event to signal UI pausing - ui_pause_event = CreateEvent(NULL, TRUE, FALSE, NULL); + ui_pause_event = CreateEvent(nullptr, TRUE, FALSE, nullptr); if (!ui_pause_event) fatalerror("Failed to create pause event\n"); @@ -191,14 +175,14 @@ bool windows_osd_interface::window_init() if (multithreading_enabled) { // create an event to signal when the window thread is ready - window_thread_ready_event = CreateEvent(NULL, TRUE, FALSE, NULL); + window_thread_ready_event = CreateEvent(nullptr, TRUE, FALSE, nullptr); if (!window_thread_ready_event) fatalerror("Failed to create window thread ready event\n"); // create a thread to run the windows from - temp = _beginthreadex(NULL, 0, win_window_info::thread_entry, NULL, 0, (unsigned *)&window_threadid); + temp = _beginthreadex(nullptr, 0, win_window_info::thread_entry, nullptr, 0, (unsigned *)&window_threadid); window_thread = (HANDLE)temp; - if (window_thread == NULL) + if (window_thread == nullptr) fatalerror("Failed to create window thread\n"); // set the thread priority equal to the main MAME thread @@ -212,22 +196,6 @@ bool windows_osd_interface::window_init() window_threadid = main_threadid; } - // initialize the drawers - if (video_config.mode == VIDEO_MODE_D3D) - { - if (drawd3d_init(machine(), &draw)) - video_config.mode = VIDEO_MODE_GDI; - } - if (video_config.mode == VIDEO_MODE_GDI) - drawgdi_init(machine(), &draw); - if (video_config.mode == VIDEO_MODE_BGFX) - drawbgfx_init(machine(), &draw); - if (video_config.mode == VIDEO_MODE_NONE) - drawnone_init(machine(), &draw); -#if (USE_OPENGL) - if (video_config.mode == VIDEO_MODE_OPENGL) - drawogl_init(machine(), &draw); -#endif // set up the window list last_window_ptr = &win_window_list; @@ -246,7 +214,7 @@ void windows_osd_interface::window_exit() assert(GetCurrentThreadId() == main_threadid); // free all the windows - while (win_window_list != NULL) + while (win_window_list != nullptr) { win_window_info *temp = win_window_list; win_window_list = temp->m_next; @@ -254,9 +222,6 @@ void windows_osd_interface::window_exit() global_free(temp); } - // kill the drawers - (*draw.exit)(); - // if we're multithreaded, clean up the window thread if (multithreading_enabled) { @@ -278,24 +243,23 @@ void windows_osd_interface::window_exit() while (ShowCursor(TRUE) < 0) ; } - win_window_info::win_window_info(running_machine &machine) - : osd_window(), m_next(NULL), + : osd_window(), m_next(nullptr), m_init_state(0), m_startmaximized(0), m_isminimized(0), m_ismaximized(0), - m_monitor(NULL), + m_monitor(nullptr), m_fullscreen(0), m_fullscreen_safe(0), m_aspect(0), - m_target(NULL), + m_target(nullptr), m_targetview(0), m_targetorient(0), m_lastclicktime(0), m_lastclickx(0), m_lastclicky(0), - m_renderer(NULL), + m_renderer(nullptr), m_machine(machine) { memset(m_title,0,sizeof(m_title)); @@ -338,7 +302,7 @@ static BOOL is_mame_window(HWND hwnd) { win_window_info *window; - for (window = win_window_list; window != NULL; window = window->m_next) + for (window = win_window_list; window != nullptr; window = window->m_next) if (window->m_hwnd == hwnd) return TRUE; @@ -368,12 +332,12 @@ void winwindow_process_events(running_machine &machine, int ingame, bool nodispa WaitMessage(); // loop over all messages in the queue - while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) + while (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { // prevent debugger windows from getting messages during reset int dispatch = TRUE && !nodispatch; - if (message.hwnd == NULL || is_mame_window(message.hwnd)) + if (message.hwnd == nullptr || is_mame_window(message.hwnd)) { dispatch = TRUE; switch (message.message) @@ -485,7 +449,7 @@ void winwindow_take_snap(void) assert(GetCurrentThreadId() == main_threadid); // iterate over windows and request a snap - for (window = win_window_list; window != NULL; window = window->m_next) + for (window = win_window_list; window != nullptr; window = window->m_next) { window->m_renderer->save(); } @@ -505,7 +469,7 @@ void winwindow_toggle_fsfx(void) assert(GetCurrentThreadId() == main_threadid); // iterate over windows and request a snap - for (window = win_window_list; window != NULL; window = window->m_next) + for (window = win_window_list; window != nullptr; window = window->m_next) { window->m_renderer->toggle_fsfx(); } @@ -525,7 +489,7 @@ void winwindow_take_video(void) assert(GetCurrentThreadId() == main_threadid); // iterate over windows and request a snap - for (window = win_window_list; window != NULL; window = window->m_next) + for (window = win_window_list; window != nullptr; window = window->m_next) { window->m_renderer->record(); } @@ -545,7 +509,7 @@ void winwindow_toggle_full_screen(void) assert(GetCurrentThreadId() == main_threadid); // if we are in debug mode, never go full screen - for (window = win_window_list; window != NULL; window = window->m_next) + for (window = win_window_list; window != nullptr; window = window->m_next) if (window->machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) return; @@ -553,7 +517,7 @@ void winwindow_toggle_full_screen(void) video_config.windowed = !video_config.windowed; // iterate over windows and toggle their fullscreen state - for (window = win_window_list; window != NULL; window = window->m_next) + for (window = win_window_list; window != nullptr; window = window->m_next) SendMessage(window->m_hwnd, WM_USER_SET_FULLSCREEN, !video_config.windowed, 0); SetForegroundWindow(win_window_list->m_hwnd); } @@ -571,7 +535,7 @@ BOOL winwindow_has_focus(void) win_window_info *window; // see if one of the video windows has focus - for (window = win_window_list; window != NULL; window = window->m_next) + for (window = win_window_list; window != nullptr; window = window->m_next) if (focuswnd == window->m_hwnd) return TRUE; @@ -621,7 +585,7 @@ void winwindow_update_cursor_state(running_machine &machine) ShowCursor(FALSE); // allow cursor to move freely - ClipCursor(NULL); + ClipCursor(nullptr); if (saved_cursor_pos.x != -1 || saved_cursor_pos.y != -1) { SetCursorPos(saved_cursor_pos.x, saved_cursor_pos.y); @@ -639,22 +603,24 @@ void winwindow_update_cursor_state(running_machine &machine) void win_window_info::create(running_machine &machine, int index, osd_monitor_info *monitor, const osd_window_config *config) { - win_window_info *window, *win; + win_window_info *win; assert(GetCurrentThreadId() == main_threadid); // allocate a new window object - window = global_alloc(win_window_info(machine)); + win_window_info *window = global_alloc(win_window_info(machine)); //printf("%d, %d\n", config->width, config->height); window->m_win_config = *config; window->m_monitor = monitor; window->m_fullscreen = !video_config.windowed; window->m_index = index; + window->m_renderer = reinterpret_cast<osd_renderer *>(osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(window))); + window->m_renderer->init(machine); // set main window if (index > 0) { - for (auto w = win_window_list; w != NULL; w = w->m_next) + for (auto w = win_window_list; w != nullptr; w = w->m_next) { if (w->m_index == 0) { @@ -665,7 +631,7 @@ void win_window_info::create(running_machine &machine, int index, osd_monitor_in } // see if we are safe for fullscreen window->m_fullscreen_safe = TRUE; - for (win = win_window_list; win != NULL; win = win->m_next) + for (win = win_window_list; win != nullptr; win = win->m_next) if (win->m_monitor == monitor) window->m_fullscreen_safe = FALSE; @@ -731,7 +697,7 @@ void win_window_info::destroy() assert(GetCurrentThreadId() == main_threadid); // remove us from the list - for (prevptr = &win_window_list; *prevptr != NULL; prevptr = &(*prevptr)->m_next) + for (prevptr = &win_window_list; *prevptr != nullptr; prevptr = &(*prevptr)->m_next) if (*prevptr == this) { *prevptr = this->m_next; @@ -739,7 +705,7 @@ void win_window_info::destroy() } // destroy the window - if (m_hwnd != NULL) + if (m_hwnd != nullptr) SendMessage(m_hwnd, WM_USER_SELF_TERMINATE, 0, 0); // free the render target @@ -783,7 +749,7 @@ void win_window_info::update() } // if we're visible and running and not in the middle of a resize, draw - if (m_hwnd != NULL && m_target != NULL && m_renderer != NULL) + if (m_hwnd != nullptr && m_target != nullptr && m_renderer != nullptr) { bool got_lock = true; @@ -836,7 +802,7 @@ osd_monitor_info *win_window_info::winwindow_video_window_monitor(const osd_rect // in window mode, find the nearest if (!m_fullscreen) { - if (proposed != NULL) + if (proposed != nullptr) { RECT p; p.top = proposed->top(); @@ -879,7 +845,7 @@ static void create_window_class(void) wc.lpszClassName = TEXT("MAME"); wc.hInstance = GetModuleHandleUni(); wc.lpfnWndProc = winwindow_video_window_proc_ui; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hCursor = LoadCursor(nullptr, IDC_ARROW); wc.hIcon = LoadIcon(wc.hInstance, MAKEINTRESOURCE(2)); UnregisterClass(wc.lpszClassName, wc.hInstance); @@ -1065,7 +1031,7 @@ unsigned __stdcall win_window_info::thread_entry(void *param) MSG message; // make a bogus user call to make us a message thread - PeekMessage(&message, NULL, 0, 0, PM_NOREMOVE); + PeekMessage(&message, nullptr, 0, 0, PM_NOREMOVE); // attach our input to the main thread AttachThreadInput(main_threadid, window_threadid, TRUE); @@ -1074,11 +1040,11 @@ unsigned __stdcall win_window_info::thread_entry(void *param) SetEvent(window_thread_ready_event); // run the message pump - while (GetMessage(&message, NULL, 0, 0)) + while (GetMessage(&message, nullptr, 0, 0)) { int dispatch = TRUE; - if ((message.hwnd == NULL) || is_mame_window(message.hwnd)) + if ((message.hwnd == nullptr) || is_mame_window(message.hwnd)) { switch (message.message) { @@ -1160,7 +1126,7 @@ int win_window_info::complete_create() { RECT client; int tempwidth, tempheight; - HMENU menu = NULL; + HMENU menu = nullptr; HDC dc; assert(GetCurrentThreadId() == window_threadid); @@ -1183,11 +1149,11 @@ int win_window_info::complete_create() m_fullscreen ? FULLSCREEN_STYLE : WINDOW_STYLE, monitorbounds.left() + 20, monitorbounds.top() + 20, monitorbounds.left() + 100, monitorbounds.top() + 100, - NULL,//(win_window_list != NULL) ? win_window_list->m_hwnd : NULL, + nullptr,//(win_window_list != nullptr) ? win_window_list->m_hwnd : nullptr, menu, GetModuleHandleUni(), - NULL); - if (m_hwnd == NULL) + nullptr); + if (m_hwnd == nullptr) return 1; // set window #0 as the focus window for all windows, required for D3D & multimonitor @@ -1203,7 +1169,7 @@ int win_window_info::complete_create() // adjust the window position to the initial width/height tempwidth = (m_win_config.width != 0) ? m_win_config.width : 640; tempheight = (m_win_config.height != 0) ? m_win_config.height : 480; - SetWindowPos(m_hwnd, NULL, monitorbounds.left() + 20, monitorbounds.top() + 20, + SetWindowPos(m_hwnd, nullptr, monitorbounds.left() + 20, monitorbounds.top() + 20, monitorbounds.left() + tempwidth + wnd_extra_width(), monitorbounds.top() + tempheight + wnd_extra_height(), SWP_NOZORDER); @@ -1219,7 +1185,6 @@ int win_window_info::complete_create() if (!m_fullscreen || m_fullscreen_safe) { // finish off by trying to initialize DirectX; if we fail, ignore it - m_renderer = draw.create(this); if (m_renderer->create()) return 1; ShowWindow(m_hwnd, SW_SHOW); @@ -1246,7 +1211,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR win_window_info *window = (win_window_info *)ptr; // we may get called before SetWindowLongPtr is called - if (window != NULL) + if (window != nullptr) { assert(GetCurrentThreadId() == window_threadid); window->update_minmax_state(); @@ -1342,7 +1307,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR window->m_resize_state = RESIZE_STATE_PENDING; case WM_EXITMENULOOP: winwindow_ui_pause_from_window_thread(window->machine(), FALSE); - InvalidateRect(wnd, NULL, FALSE); + InvalidateRect(wnd, nullptr, FALSE); break; // get min/max info: set the minimum window size @@ -1366,7 +1331,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR rect->bottom = r.bottom(); rect->right = r.right(); } - InvalidateRect(wnd, NULL, FALSE); + InvalidateRect(wnd, nullptr, FALSE); break; } @@ -1380,7 +1345,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR return 1; // most SYSCOMMANDs require us to invalidate the window - InvalidateRect(wnd, NULL, FALSE); + InvalidateRect(wnd, nullptr, FALSE); // handle maximize if (cmd == SC_MAXIMIZE) @@ -1408,15 +1373,10 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR window->machine().schedule_exit(); break; - // destroy: clean up all attached rendering bits and NULL out our hwnd + // destroy: clean up all attached rendering bits and nullptr out our hwnd case WM_DESTROY: - if (!(window->m_renderer == NULL)) - { - window->m_renderer->destroy(); - global_free(window->m_renderer); - window->m_renderer = NULL; - } - window->m_hwnd = NULL; + window->m_renderer = nullptr; + window->m_hwnd = nullptr; return DefWindowProc(wnd, message, wparam, lparam); // self redraw: draw ourself in a non-painty way @@ -1467,7 +1427,7 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR // set focus: if we're not the primary window, switch back // commented out ATM because this prevents us from resizing secondary windows // case WM_SETFOCUS: -// if (window != win_window_list && win_window_list != NULL) +// if (window != win_window_list && win_window_list != nullptr) // SetFocus(win_window_list->m_hwnd); // break; @@ -1497,10 +1457,10 @@ void win_window_info::draw_video_contents(HDC dc, int update) mtlog_add("draw_video_contents: render lock acquired"); // if we're iconic, don't bother - if (m_hwnd != NULL && !IsIconic(m_hwnd)) + if (m_hwnd != nullptr && !IsIconic(m_hwnd)) { // if no bitmap, just fill - if (m_primlist == NULL) + if (m_primlist == nullptr) { RECT fill; GetClientRect(m_hwnd, &fill); @@ -1786,7 +1746,7 @@ void win_window_info::minimize_window() osd_rect newrect(bounds.left, bounds.top, newsize ); - SetWindowPos(m_hwnd, NULL, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER); + SetWindowPos(m_hwnd, nullptr, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER); } @@ -1808,7 +1768,7 @@ void win_window_info::maximize_window() work.top() + (work.height() - newsize.height()) / 2, newsize); - SetWindowPos(m_hwnd, NULL, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER); + SetWindowPos(m_hwnd, nullptr, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER); } @@ -1839,7 +1799,7 @@ void win_window_info::adjust_window_position_after_major_change() // in full screen, make sure it covers the primary display else { - osd_monitor_info *monitor = winwindow_video_window_monitor(NULL); + osd_monitor_info *monitor = winwindow_video_window_monitor(nullptr); newrect = monitor->position_size(); } @@ -1875,9 +1835,8 @@ void win_window_info::set_fullscreen(int fullscreen) m_fullscreen = fullscreen; // kill off the drawers - m_renderer->destroy(); global_free(m_renderer); - m_renderer = NULL; + m_renderer = nullptr; // hide ourself ShowWindow(m_hwnd, SW_HIDE); @@ -1933,7 +1892,9 @@ void win_window_info::set_fullscreen(int fullscreen) { if (video_config.mode != VIDEO_MODE_NONE) ShowWindow(m_hwnd, SW_SHOW); - m_renderer = draw.create(this); + osd_renderer *renderer = reinterpret_cast<osd_renderer *>(osd_renderer::make_for_type(video_config.mode, reinterpret_cast<osd_window *>(this))); + renderer->init(machine()); + m_renderer = renderer; if (m_renderer->create()) exit(1); } diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h index 6a925494f93..bc3544ba637 100644 --- a/src/osd/windows/window.h +++ b/src/osd/windows/window.h @@ -9,6 +9,12 @@ #ifndef __WIN_WINDOW__ #define __WIN_WINDOW__ +// standard windows headers +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <windowsx.h> +#include <mmsystem.h> + #include <mutex> #include "video.h" #include "render.h" diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index 260919961f5..59088235d65 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -250,7 +250,7 @@ public: virtual void update(bool skip_redraw) override; // video overridables - virtual void *get_slider_list() override; + virtual slider_state *get_slider_list() override; // input overridables virtual void customize_input_type_list(simple_list<input_type_entry> &typelist) override; |