summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/osdwindow.h
blob: 3fe020c56fe438fa5cd9b39100c6f8be6c1093d7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont, Couriersud
//============================================================
//
//  osdwindow.h - SDL window handling
//
//============================================================

#ifndef __OSDWINDOW__
#define __OSDWINDOW__

#include "render.h"
#include "osdhelper.h"
#include "../frontend/mame/ui/menuitem.h"

// standard windows headers
#ifdef OSD_WINDOWS
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#endif

#ifdef OSD_SDL
// forward declaration
struct SDL_Window;
#endif

//============================================================
//  TYPE DEFINITIONS
//============================================================

class osd_options;
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,

	VIDEO_MODE_COUNT
};

class osd_window_config
{
public:
	osd_window_config() : aspect(0.0f), width(0), height(0), depth(0), refresh(0) {}

	float               aspect;                     // decoded aspect ratio FIXME: not used on windows
	int                 width;                      // decoded width
	int                 height;                     // decoded height
	int                 depth;                      // decoded depth - only SDL
	int                 refresh;                    // decoded refresh
};

class osd_renderer;
class osd_monitor_info;

class osd_window : public std::enable_shared_from_this<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 render_target *target() = 0;
	virtual int fullscreen() const = 0;
	virtual running_machine &machine() const = 0;

	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(); }

	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;
	};

	virtual osd_dim get_size() = 0;

	virtual osd_monitor_info *monitor() const = 0;

	std::shared_ptr<osd_window> main_window() const { return m_main;    }
	void set_main_window(std::shared_ptr<osd_window> main) { m_main = main; }

	// Clips the pointer to the bounds of this window
	virtual void capture_pointer() = 0;

	// Releases the pointer from a previously captured state
	virtual void release_pointer() = 0;

	virtual void show_pointer() = 0;
	virtual void hide_pointer() = 0;

	virtual void update() = 0;
	virtual void destroy() = 0;

#if defined(OSD_WINDOWS) || defined(OSD_UWP)
	virtual bool win_has_menu() = 0;
#endif

#ifdef OSD_WINDOWS
	HDC                     m_dc;       // only used by GDI renderer!
	int                     m_resize_state;
#endif
	render_primitive_list   *m_primlist;
	osd_window_config       m_win_config;
	int                     m_index;
protected:
	int                     m_prescale;
private:
	std::unique_ptr<osd_renderer>  m_renderer;
	std::shared_ptr<osd_window>    m_main;
};

template <class TWindowHandle>
class osd_window_t : public osd_window
{
private:
	TWindowHandle m_platform_window;
public:
	osd_window_t(const osd_window_config &config)
		: osd_window(config),
		m_platform_window(nullptr)
	{
	}

	TWindowHandle platform_window() const { return m_platform_window; }

	void set_platform_window(TWindowHandle window)
	{
		assert(window == nullptr || m_platform_window == nullptr);
		m_platform_window = window;
	}
};


class osd_renderer
{
public:

	/* Generic flags */
	static const int FLAG_NONE                  = 0x0000;
	static const int FLAG_NEEDS_OPENGL          = 0x0001;
	static const int FLAG_HAS_VECTOR_SCREEN     = 0x0002;

	/* 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)
	{ }

	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();
	}

	bool has_flags(const int flag) const { return ((m_flags & flag)) == flag; }
	void set_flags(int aflag) { m_flags |= aflag; }
	void clear_flags(int aflag) { m_flags &= ~aflag; }

	void notify_changed() { set_flags(FI_CHANGED); }

	/* Interface to be implemented by render code */

	virtual int create() = 0;
	virtual render_primitive_list *get_primitives() = 0;

	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 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() { }

	/* Internal flags */
	static const int FI_CHANGED                 = 0x010000;
	bool                        m_sliders_dirty;
	std::vector<ui::menu_item>   m_sliders;

private:
	std::weak_ptr<osd_window>  m_window;
	int         m_flags;
};



//============================================================
//  CONSTANTS
//============================================================

#define MAX_VIDEO_WINDOWS           (4)

#define VIDEO_SCALE_MODE_NONE       (0)

#define GLSL_SHADER_MAX 10


//============================================================
//  TYPE DEFINITIONS
//============================================================

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
	int                 triplebuf;                  // triple buffer

	//============================================================
	// SDL - options
	//============================================================
	int                 novideo;                // don't draw, for pure CPU benchmarking

	int                 centerh;
	int                 centerv;

	// vector options
	float               beamwidth;      // beam width

	// perftest
	int                 perftest;       // print out real video fps

	// X11 options
	int                 restrictonemonitor; // in fullscreen, confine to Xinerama monitor 0

	// YUV options
	int                 scale_mode;
};

//============================================================
//  GLOBAL VARIABLES
//============================================================

extern osd_video_config video_config;

#endif /* __OSDWINDOW__ */