summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/osdwindow.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/osdwindow.h')
-rw-r--r--src/osd/modules/osdwindow.h399
1 files changed, 266 insertions, 133 deletions
diff --git a/src/osd/modules/osdwindow.h b/src/osd/modules/osdwindow.h
index 3fe020c56fe..9167a775682 100644
--- a/src/osd/modules/osdwindow.h
+++ b/src/osd/modules/osdwindow.h
@@ -6,13 +6,21 @@
//
//============================================================
-#ifndef __OSDWINDOW__
-#define __OSDWINDOW__
+#ifndef MAME_OSD_MODULES_OSDWINDOW_H
+#define MAME_OSD_MODULES_OSDWINDOW_H
-#include "render.h"
+#pragma once
+
+#include "emucore.h"
#include "osdhelper.h"
#include "../frontend/mame/ui/menuitem.h"
+#include <cassert>
+#include <chrono>
+#include <memory>
+#include <string>
+#include <vector>
+
// standard windows headers
#ifdef OSD_WINDOWS
#include <windows.h>
@@ -20,32 +28,16 @@
#include <mmsystem.h>
#endif
-#ifdef OSD_SDL
-// forward declaration
-struct SDL_Window;
-#endif
-
//============================================================
// TYPE DEFINITIONS
//============================================================
-class osd_options;
+class osd_monitor_info;
+class render_module;
class render_primitive_list;
-enum
-{
- VIDEO_MODE_NONE = 0,
- VIDEO_MODE_GDI,
- VIDEO_MODE_BGFX,
-#if defined(USE_OPENGL) && USE_OPENGL
- VIDEO_MODE_OPENGL,
-#endif
- VIDEO_MODE_SDL2ACCEL,
- VIDEO_MODE_D3D,
- VIDEO_MODE_SOFT,
+class osd_renderer;
- VIDEO_MODE_COUNT
-};
class osd_window_config
{
@@ -59,58 +51,37 @@ public:
int refresh; // decoded refresh
};
-class osd_renderer;
-class osd_monitor_info;
-class osd_window : public std::enable_shared_from_this<osd_window>
+class osd_window
{
public:
- osd_window(const osd_window_config &config)
- :
-#ifdef OSD_WINDOWS
- m_dc(nullptr), m_resize_state(0),
-#endif
- m_primlist(nullptr),
- m_win_config(config),
- m_index(0),
- m_prescale(1),
- m_renderer(nullptr),
- m_main(nullptr)
- {}
-
- virtual ~osd_window() { }
+ virtual ~osd_window();
- virtual render_target *target() = 0;
- virtual int fullscreen() const = 0;
- virtual running_machine &machine() const = 0;
+ render_target *target() const { return m_target; }
+ int fullscreen() const { return m_fullscreen; }
+ running_machine &machine() const { return m_machine; }
+ const std::string &title() const { return m_title; }
bool has_renderer() const { return m_renderer != nullptr; }
osd_renderer &renderer() const { return *m_renderer; }
- void set_renderer(std::unique_ptr<osd_renderer> renderer)
- {
- m_renderer = std::move(renderer);
- }
- void renderer_reset() { m_renderer.reset(); }
+ void renderer_reset() { m_renderer.reset(); } // public because OSD object calls it directly during teardown
- int prescale() const { return m_prescale; };
+ int index() const { return m_index; }
+ int prescale() const { return m_prescale; }
float pixel_aspect() const;
- bool swap_xy()
- {
- bool orientation_swap_xy =
- (machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
- bool rotation_swap_xy =
- (target()->orientation() & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
- return orientation_swap_xy ^ rotation_swap_xy;
- };
+ bool swap_xy() const;
+
+ bool keepaspect() const;
virtual osd_dim get_size() = 0;
- virtual osd_monitor_info *monitor() const = 0;
+ osd_monitor_info *monitor() const { return m_monitor.get(); }
+ std::shared_ptr<osd_monitor_info> monitor_from_rect(const osd_rect *proposed) const;
- std::shared_ptr<osd_window> main_window() const { return m_main; }
- void set_main_window(std::shared_ptr<osd_window> main) { m_main = main; }
+ void create_target();
+ void destroy();
// Clips the pointer to the bounds of this window
virtual void capture_pointer() = 0;
@@ -122,45 +93,252 @@ public:
virtual void hide_pointer() = 0;
virtual void update() = 0;
- virtual void destroy() = 0;
+ virtual void complete_destroy() = 0;
-#if defined(OSD_WINDOWS) || defined(OSD_UWP)
- virtual bool win_has_menu() = 0;
-#endif
+protected:
+ static inline constexpr int CLICK_DISTANCE = 16; // in pointer units squared
+ static inline constexpr int TAP_DISTANCE = 49; // taps are less repeatable than clicks
-#ifdef OSD_WINDOWS
- HDC m_dc; // only used by GDI renderer!
- int m_resize_state;
-#endif
+ struct prev_touch
+ {
+ prev_touch() = default;
+ prev_touch(prev_touch const &) = default;
+ prev_touch(prev_touch &&) = default;
+ prev_touch &operator=(prev_touch const &) = default;
+ prev_touch &operator=(prev_touch &&) = default;
+
+ std::chrono::steady_clock::time_point when = std::chrono::steady_clock::time_point::min();
+ int x = 0, y = 0, cnt = 0;
+ };
+
+ struct pointer_dev_info
+ {
+ pointer_dev_info() = default;
+ pointer_dev_info(pointer_dev_info const &) = default;
+ pointer_dev_info(pointer_dev_info &&) = default;
+ pointer_dev_info &operator=(pointer_dev_info const &) = default;
+ pointer_dev_info &operator=(pointer_dev_info &&) = default;
+
+ unsigned clear_expired_touches(std::chrono::steady_clock::time_point const &now, std::chrono::steady_clock::duration const &time);
+ unsigned consume_touch(unsigned i);
+
+ prev_touch touches[8];
+ };
+
+ struct pointer_info
+ {
+ pointer_info(pointer_info const &) = default;
+ pointer_info(pointer_info &&) = default;
+ pointer_info &operator=(pointer_info const &) = default;
+ pointer_info &operator=(pointer_info &&) = default;
+
+ pointer_info(unsigned i, unsigned d);
+
+ void primary_down(
+ int cx,
+ int cy,
+ std::chrono::steady_clock::duration const &time,
+ int tolerance,
+ bool checkprev,
+ std::vector<pointer_dev_info> &devices);
+ void check_primary_hold_drag(
+ int cx,
+ int cy,
+ std::chrono::steady_clock::duration const &time,
+ int tolerance);
+
+ std::chrono::steady_clock::time_point pressed;
+ unsigned index, device;
+ int x, y;
+ unsigned buttons;
+ int pressedx, pressedy;
+ int clickcnt;
+ };
+
+ osd_window(
+ running_machine &machine,
+ render_module &renderprovider,
+ int index,
+ const std::shared_ptr<osd_monitor_info> &monitor,
+ const osd_window_config &config);
+
+ bool renderer_interactive() const;
+ bool renderer_sdl_needs_opengl() const;
+ void renderer_create();
+
+private:
+ void set_starting_view(int index, const char *defview, const char *view);
+
+private:
+ render_target *m_target;
+public:
render_primitive_list *m_primlist;
osd_window_config m_win_config;
+private:
int m_index;
protected:
+ bool m_fullscreen;
int m_prescale;
+
private:
- std::unique_ptr<osd_renderer> m_renderer;
- std::shared_ptr<osd_window> m_main;
+ running_machine &m_machine;
+ render_module &m_renderprovider;
+ std::shared_ptr<osd_monitor_info> m_monitor;
+ std::unique_ptr<osd_renderer> m_renderer;
+ const std::string m_title;
};
-template <class TWindowHandle>
-class osd_window_t : public osd_window
+
+inline unsigned osd_window::pointer_dev_info::clear_expired_touches(
+ std::chrono::steady_clock::time_point const &now,
+ std::chrono::steady_clock::duration const &time)
{
-private:
- TWindowHandle m_platform_window;
-public:
- osd_window_t(const osd_window_config &config)
- : osd_window(config),
- m_platform_window(nullptr)
+ // find first non-expired touch (if any)
+ unsigned end(0);
+ while ((std::size(touches) > end) && touches[end].cnt && ((touches[end].when + time) < now))
+ touches[end++].cnt = 0;
+
+ // shift non-expired touches back if necessary
+ if (end)
+ {
+ unsigned pos(0);
+ while ((std::size(touches) > end) && touches[end].cnt)
+ {
+ touches[pos++] = std::move(touches[end]);
+ touches[end++].cnt = 0;
+ }
+ return pos;
+ }
+ else
+ {
+ while ((std::size(touches) > end) && touches[end].cnt)
+ ++end;
+ return end;
+ }
+}
+
+inline unsigned osd_window::pointer_dev_info::consume_touch(unsigned i)
+{
+ assert(std::size(touches) > i);
+ touches[i].cnt = 0;
+ unsigned pos(i + 1);
+ while ((std::size(touches) > pos) && touches[pos].cnt)
+ {
+ touches[i++] = std::move(touches[pos]);
+ touches[pos++].cnt = 0;
+ }
+ return i;
+}
+
+inline osd_window::pointer_info::pointer_info(unsigned i, unsigned d) :
+ pressed(std::chrono::steady_clock::time_point::min()),
+ index(i),
+ device(d),
+ x(-1),
+ y(-1),
+ buttons(0),
+ pressedx(0),
+ pressedy(0),
+ clickcnt(0)
+{
+}
+
+inline void osd_window::pointer_info::primary_down(
+ int cx,
+ int cy,
+ std::chrono::steady_clock::duration const &time,
+ int tolerance,
+ bool checkprev,
+ std::vector<pointer_dev_info> &devices)
+{
+ auto const now(std::chrono::steady_clock::now());
+ auto const exp(time + pressed);
+ if (0 > clickcnt)
+ {
+ // previous click turned into a hold/drag
+ clickcnt = 1;
+ }
+ else if (clickcnt)
+ {
+ // potential multi-click action
+ int const dx(cx - pressedx);
+ int const dy(cy - pressedy);
+ int const distance((dx * dx) + (dy * dy));
+ if ((exp < now) || (tolerance < distance))
+ clickcnt = 1;
+ else
+ ++clickcnt;
+ }
+ else
+ {
+ // first click for this pointer, but may need to check previous touches
+ clickcnt = 1;
+ if (checkprev)
+ {
+ if (devices.size() > device)
+ {
+ auto &devinfo(devices[device]);
+ unsigned const end(devinfo.clear_expired_touches(now, time));
+ for (int i = 0; end > i; ++i)
+ {
+ int const dx(cx - devinfo.touches[i].x);
+ int const dy(cy - devinfo.touches[i].y);
+ int const distance((dx * dx) + (dy * dy));
+ if (tolerance >= distance)
+ {
+ // close match - consume it
+ clickcnt = devinfo.touches[i].cnt + 1;
+ devinfo.consume_touch(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // record the time/location where the pointer was pressed
+ pressed = now;
+ pressedx = cx;
+ pressedy = cy;
+}
+
+inline void osd_window::pointer_info::check_primary_hold_drag(
+ int cx,
+ int cy,
+ std::chrono::steady_clock::duration const &time,
+ int tolerance)
+{
+ // check for conversion to a (multi-)click-and-hold/drag
+ if (0 < clickcnt)
{
+ auto const now(std::chrono::steady_clock::now());
+ auto const exp(time + pressed);
+ int const dx(cx - pressedx);
+ int const dy(cy - pressedy);
+ int const distance((dx * dx) + (dy * dy));
+ if ((exp < now) || (tolerance < distance))
+ clickcnt = -clickcnt;
}
+}
+
+template <class TWindowHandle>
+class osd_window_t : public osd_window
+{
+public:
TWindowHandle platform_window() const { return m_platform_window; }
+protected:
+ using osd_window::osd_window;
+
void set_platform_window(TWindowHandle window)
{
assert(window == nullptr || m_platform_window == nullptr);
m_platform_window = window;
}
+
+private:
+ TWindowHandle m_platform_window = nullptr;
};
@@ -170,31 +348,13 @@ public:
/* Generic flags */
static const int FLAG_NONE = 0x0000;
- static const int FLAG_NEEDS_OPENGL = 0x0001;
- static const int FLAG_HAS_VECTOR_SCREEN = 0x0002;
+ static const int FLAG_HAS_VECTOR_SCREEN = 0x0001;
- /* SDL 1.2 flags */
- static const int FLAG_NEEDS_DOUBLEBUF = 0x0100;
- static const int FLAG_NEEDS_ASYNCBLIT = 0x0200;
-
- osd_renderer(std::shared_ptr<osd_window> window, const int flags)
- : m_sliders_dirty(false), m_window(window), m_flags(flags)
- { }
+ osd_renderer(osd_window &window) : m_sliders_dirty(false), m_window(window), m_flags(0) { }
virtual ~osd_renderer() { }
- std::shared_ptr<osd_window> assert_window() const
- {
- auto win = m_window.lock();
- if (!win)
- throw emu_fatalerror("osd_renderer::assert_window: Window weak_ptr is not available!");
- return win;
- }
-
- std::shared_ptr<osd_window> try_getwindow() const
- {
- return m_window.lock();
- }
+ osd_window &window() const { return m_window; }
bool has_flags(const int flag) const { return ((m_flags & flag)) == flag; }
void set_flags(int aflag) { m_flags |= aflag; }
@@ -210,14 +370,12 @@ public:
virtual void add_audio_to_recording(const int16_t *buffer, int samples_this_frame) { }
virtual std::vector<ui::menu_item> get_slider_list() { return m_sliders; }
virtual int draw(const int update) = 0;
- 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 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 bool sliders_dirty() { return m_sliders_dirty; }
- static std::unique_ptr<osd_renderer> make_for_type(int mode, std::shared_ptr<osd_window> window, int extra_flags = FLAG_NONE);
-
protected:
virtual void build_slider_list() { }
@@ -227,7 +385,7 @@ protected:
std::vector<ui::menu_item> m_sliders;
private:
- std::weak_ptr<osd_window> m_window;
+ osd_window &m_window;
int m_flags;
};
@@ -239,10 +397,6 @@ private:
#define MAX_VIDEO_WINDOWS (4)
-#define VIDEO_SCALE_MODE_NONE (0)
-
-#define GLSL_SHADER_MAX 10
-
//============================================================
// TYPE DEFINITIONS
@@ -253,40 +407,22 @@ struct osd_video_config
// global configuration
int windowed; // start windowed?
int prescale; // prescale factor
- int keepaspect; // keep aspect ratio
int numscreens; // number of screens
- int fullstretch; // fractional stretch
// hardware options
- int mode; // output mode
int waitvsync; // spin until vsync
int syncrefresh; // sync only to refresh rate
int switchres; // switch resolutions
// d3d, accel, opengl
int filter; // enable filtering
- //int filter; // enable filtering, disabled if glsl_filter>0
-
- // OpenGL options
- int glsl;
- int glsl_filter; // glsl filtering, >0 disables filter
- char * glsl_shader_mamebm[GLSL_SHADER_MAX]; // custom glsl shader set, mame bitmap
- int glsl_shader_mamebm_num; // custom glsl shader set number, mame bitmap
- char * glsl_shader_scrn[GLSL_SHADER_MAX]; // custom glsl shader set, screen bitmap
- int glsl_shader_scrn_num; // custom glsl shader number, screen bitmap
- int pbo;
- int vbo;
- int allowtexturerect; // allow GL_ARB_texture_rectangle, default: no
- int forcepow2texture; // force power of two textures, default: no
-
- // dd, d3d
+
+ // d3d
int triplebuf; // triple buffer
//============================================================
// SDL - options
//============================================================
- int novideo; // don't draw, for pure CPU benchmarking
-
int centerh;
int centerv;
@@ -298,9 +434,6 @@ struct osd_video_config
// X11 options
int restrictonemonitor; // in fullscreen, confine to Xinerama monitor 0
-
- // YUV options
- int scale_mode;
};
//============================================================
@@ -309,4 +442,4 @@ struct osd_video_config
extern osd_video_config video_config;
-#endif /* __OSDWINDOW__ */
+#endif // MAME_OSD_MODULES_OSDWINDOW_H