summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/screen.h
blob: 3842a65b2e6d54a5f9933bc0c528d27dafb2c637 (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
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    screen.h

    Core MAME screen device.

***************************************************************************/
#ifndef MAME_EMU_SCREEN_H
#define MAME_EMU_SCREEN_H

#pragma once

#include <type_traits>
#include <utility>


//**************************************************************************
//  CONSTANTS
//**************************************************************************

// screen types
enum screen_type_enum
{
	SCREEN_TYPE_INVALID = 0,
	SCREEN_TYPE_RASTER,
	SCREEN_TYPE_VECTOR,
	SCREEN_TYPE_LCD,
	SCREEN_TYPE_SVG
};

// texture formats
enum texture_format
{
	TEXFORMAT_UNDEFINED = 0,                            // require a format to be specified
	TEXFORMAT_PALETTE16,                                // 16bpp palettized, no alpha
	TEXFORMAT_RGB32,                                    // 32bpp 8-8-8 RGB
	TEXFORMAT_ARGB32,                                   // 32bpp 8-8-8-8 ARGB
	TEXFORMAT_YUY16                                     // 16bpp 8-8 Y/Cb, Y/Cr in sequence
};

// screen_update callback flags
constexpr u32 UPDATE_HAS_NOT_CHANGED = 0x0001;   // the video has not changed

/*!
 @defgroup flags for video_attributes
 @{
 @def VIDEO_UPDATE_BEFORE_VBLANK
 update_video called at the start of the VBLANK period
 @todo hack, remove me

 @def VIDEO_UPDATE_AFTER_VBLANK
 update_video called at the end of the VBLANK period
 @todo hack, remove me

 @def VIDEO_SELF_RENDER
 indicates VIDEO_UPDATE will add container bits itself

 @def VIDEO_ALWAYS_UPDATE
 force VIDEO_UPDATE to be called even for skipped frames.
 @todo in case you need this one for model updating, then you're doing it wrong (read: hack)

 @def VIDEO_UPDATE_SCANLINE
 calls VIDEO_UPDATE for every visible scanline, even for skipped frames

 @def VIDEO_VARIABLE_WIDTH
 causes the screen to construct its final bitmap from a composite upscale of individual scanline bitmaps

 @}
 */

constexpr u32 VIDEO_UPDATE_BEFORE_VBLANK    = 0x0000;
constexpr u32 VIDEO_UPDATE_AFTER_VBLANK     = 0x0004;

constexpr u32 VIDEO_SELF_RENDER             = 0x0008;
constexpr u32 VIDEO_ALWAYS_UPDATE           = 0x0080;
constexpr u32 VIDEO_UPDATE_SCANLINE         = 0x0100;
constexpr u32 VIDEO_VARIABLE_WIDTH          = 0x0200;


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> screen_bitmap

class screen_bitmap
{
private:
	// internal helpers
	bitmap_t &live() { assert(m_live != nullptr); return *m_live; }
	const bitmap_t &live() const { assert(m_live != nullptr); return *m_live; }

public:
	// construction/destruction
	screen_bitmap()
		: m_format(BITMAP_FORMAT_RGB32)
		, m_texformat(TEXFORMAT_RGB32)
		, m_live(&m_rgb32)
	{ }
	screen_bitmap(bitmap_ind16 &orig)
		: m_format(BITMAP_FORMAT_IND16)
		, m_texformat(TEXFORMAT_PALETTE16)
		, m_live(&m_ind16)
		, m_ind16(orig, orig.cliprect())
	{ }
	screen_bitmap(bitmap_rgb32 &orig)
		: m_format(BITMAP_FORMAT_RGB32)
		, m_texformat(TEXFORMAT_RGB32)
		, m_live(&m_rgb32)
		, m_rgb32(orig, orig.cliprect())
	{ }

	// resizing
	void resize(int width, int height) { live().resize(width, height); }

	// conversion
	operator bitmap_t &() { return live(); }
	bitmap_ind16 &as_ind16() { assert(m_format == BITMAP_FORMAT_IND16); return m_ind16; }
	bitmap_rgb32 &as_rgb32() { assert(m_format == BITMAP_FORMAT_RGB32); return m_rgb32; }

	// getters
	s32 width() const { return live().width(); }
	s32 height() const { return live().height(); }
	s32 rowpixels() const { return live().rowpixels(); }
	s32 rowbytes() const { return live().rowbytes(); }
	u8 bpp() const { return live().bpp(); }
	bitmap_format format() const { return m_format; }
	texture_format texformat() const { return m_texformat; }
	bool valid() const { return live().valid(); }
	palette_t *palette() const { return live().palette(); }
	const rectangle &cliprect() const { return live().cliprect(); }

	// operations
	void set_palette(palette_t *palette) { live().set_palette(palette); }
	void set_format(bitmap_format format, texture_format texformat)
	{
		m_format = format;
		m_texformat = texformat;
		switch (format)
		{
			case BITMAP_FORMAT_IND16:   m_live = &m_ind16;  break;
			case BITMAP_FORMAT_RGB32:   m_live = &m_rgb32;  break;
			default:                    m_live = nullptr;      break;
		}
		m_ind16.reset();
		m_rgb32.reset();
	}

private:
	// internal state
	bitmap_format       m_format;
	texture_format      m_texformat;
	bitmap_t *          m_live;
	bitmap_ind16        m_ind16;
	bitmap_rgb32        m_rgb32;
};


// ======================> other delegate types

typedef delegate<void (screen_device &, bool)> vblank_state_delegate;

typedef device_delegate<u32 (screen_device &, bitmap_ind16 &, const rectangle &)> screen_update_ind16_delegate;
typedef device_delegate<u32 (screen_device &, bitmap_rgb32 &, const rectangle &)> screen_update_rgb32_delegate;


// ======================> screen_device

class screen_device : public device_t
{
	friend class render_manager;

public:
	// construction/destruction
	screen_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);

	screen_device(const machine_config &mconfig, const char *tag, device_t *owner, screen_type_enum type)
		: screen_device(mconfig, tag, owner, u32(0))
	{
		set_type(type);
	}
	screen_device(const machine_config &mconfig, const char *tag, device_t *owner, screen_type_enum type, rgb_t color)
		: screen_device(mconfig, tag, owner, u32(0))
	{
		set_type(type);
		set_color(color);
	}
	~screen_device();

	// configuration readers
	screen_type_enum screen_type() const { return m_type; }
	int orientation() const { assert(configured()); return m_orientation; }
	std::pair<unsigned, unsigned> physical_aspect() const;
	int width() const { return m_width; }
	int height() const { return m_height; }
	const rectangle &visible_area() const { return m_visarea; }
	const rectangle &cliprect() const { return m_bitmap[0].cliprect(); }
	bool oldstyle_vblank_supplied() const { return m_oldstyle_vblank_supplied; }
	attoseconds_t refresh_attoseconds() const { return m_refresh; }
	attoseconds_t vblank_attoseconds() const { return m_vblank; }
	bitmap_format format() const { return !m_screen_update_ind16.isnull() ? BITMAP_FORMAT_IND16 : BITMAP_FORMAT_RGB32; }
	float xoffset() const { return m_xoffset; }
	float yoffset() const { return m_yoffset; }
	float xscale() const { return m_xscale; }
	float yscale() const { return m_yscale; }
	bool has_screen_update() const { return !m_screen_update_ind16.isnull() || !m_screen_update_rgb32.isnull(); }

	// inline configuration helpers
	void set_type(screen_type_enum type) { assert(!configured()); m_type = type; }
	void set_orientation(int orientation) { assert(!configured()); m_orientation = orientation; }
	void set_physical_aspect(unsigned x, unsigned y) { assert(!configured()); m_phys_aspect = std::make_pair(x, y); }
	void set_native_aspect() { assert(!configured()); m_phys_aspect = std::make_pair(~0U, ~0U); }

	/// \brief Configure screen parameters
	///
	/// \param [in] pixclock Pixel clock frequency in Hertz.
	/// \param [in] htotal Total pixel clocks per line, including
	///   horizontal blanking period.
	/// \param [in] hbend Index of first visible pixel after horizontal
	///   blanking period ends.
	/// \param [in] hbstart Index of first pixel in horzontal blanking
	///   period after visible pixels.
	/// \param [in] vtotal Total lines per frame, including vertical
	///   blanking period.
	/// \param [in] vbend Index of first visible line after vertical
	///   blanking period ends.
	/// \param [in] vbstart Index of first line in vertical blanking
	///   period after visible lines.
	/// \return Reference to device for method chaining.
	screen_device &set_raw(u32 pixclock, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart)
	{
		assert(pixclock != 0);
		m_clock = pixclock;
		m_refresh = HZ_TO_ATTOSECONDS(pixclock) * htotal * vtotal;
		m_vblank = m_refresh / vtotal * (vtotal - (vbstart - vbend));
		m_width = htotal;
		m_height = vtotal;
		m_visarea.set(hbend, hbstart - 1, vbend, vbstart - 1);
		return *this;
	}
	screen_device &set_raw(const XTAL &xtal, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart)
	{
		xtal.validate(std::string("Configuring screen ") + tag());
		return set_raw(xtal.value(), htotal, hbend, hbstart, vtotal, vbend, vbstart);
	}
	void set_refresh(attoseconds_t rate) { m_refresh = rate; }

	/// \brief Set refresh rate in Hertz
	///
	/// Sets refresh rate in Hertz (frames per second). Used in
	/// conjunction with #set_vblank_time, #set_size and #set_visarea.
	/// For raster displays, please use #set_raw to configure screen
	/// parameters in terms of pixel clock.
	/// \param [in] hz Desired refresh rate.
	/// \return Reference to device for method chaining.
	template <typename T> screen_device &set_refresh_hz(T &&hz)
	{
		set_refresh(HZ_TO_ATTOSECONDS(std::forward<T>(hz)));
		return *this;
	}

	/// \brief Set vertical blanking interval time
	///
	/// Sets vertical blanking interval period.  Used in conjunction
	/// with #set_refresh_hz, #set_size and #set_visarea.  For raster
	/// displays, please use #set_raw to configure screen parameters in
	/// terms of pixel clock.
	/// \param [in] time Length of vertical blanking interval.
	/// \return Reference to device for method chaining.
	screen_device &set_vblank_time(attoseconds_t time)
	{
		m_vblank = time;
		m_oldstyle_vblank_supplied = true;
		return *this;
	}

	/// \brief Set total screen size
	///
	/// Set the total screen size in pixels, including blanking areas if
	/// applicable.  This sets the size of the screen bitmap.  Used in
	/// conjunction with #set_refresh_hz, #set_vblank_time and
	/// #set_visarea.  For raster displays, please use #set_raw to
	/// configure screen parameters in terms of pixel clock.
	/// \param [in] width Total width in pixels, including horizontal
	///   blanking period if applicable.
	/// \param [in] height Total height in lines, including vertical
	///   blanking period if applicable.
	/// \return Reference to device for method chaining.
	screen_device &set_size(u16 width, u16 height)
	{
		m_width = width;
		m_height = height;
		return *this;
	}

	/// \brief Set visible screen area
	///
	/// Set visible screen area.  This should fit within the total
	/// screen area.  Used in conjunction with #set_refresh_hz,
	/// #set_vblank_time and #set_size.  For raster displays, please
	/// use #set_raw to configure screen parameters in terms of pixel
	/// clock.
	/// \param [in] minx First visible pixel index after horizontal
	///   blanking period ends.
	/// \param [in] maxx Last visible pixel index before horizontal
	///   blanking period starts.
	/// \param [in] miny First visible line index after vertical
	///   blanking period ends.
	/// \param [in] maxy Last visible line index before vertical
	///   blanking period starts.
	/// \return Reference to device for method chaining.
	screen_device &set_visarea(s16 minx, s16 maxx, s16 miny, s16 maxy)
	{
		m_visarea.set(minx, maxx, miny, maxy);
		return *this;
	}

	/// \brief Set visible area to full area
	///
	/// Set visible screen area to the full screen area (i.e. noi
	/// horizontal or vertical blanking period).  This is generally not
	/// possible for raster displays, but is useful for other display
	/// simulations.  Must be called after calling #set_size.
	/// \return Reference to device for method chaining.
	/// \sa set_visarea
	screen_device &set_visarea_full()
	{
		m_visarea.set(0, m_width - 1, 0, m_height - 1);
		return *this;
	}

	void set_default_position(double xscale, double xoffs, double yscale, double yoffs)
	{
		m_xscale = xscale;
		m_xoffset = xoffs;
		m_yscale = yscale;
		m_yoffset = yoffs;
	}

	template <typename F>
	std::enable_if_t<screen_update_ind16_delegate::supports_callback<F>::value> set_screen_update(F &&callback, const char *name)
	{
		m_screen_update_ind16.set(std::forward<F>(callback), name);
		m_screen_update_rgb32 = screen_update_rgb32_delegate(*this);
	}
	template <typename F>
	std::enable_if_t<screen_update_rgb32_delegate::supports_callback<F>::value> set_screen_update(F &&callback, const char *name)
	{
		m_screen_update_ind16 = screen_update_ind16_delegate(*this);
		m_screen_update_rgb32.set(std::forward<F>(callback), name);
	}
	template <typename T, typename F>
	std::enable_if_t<screen_update_ind16_delegate::supports_callback<F>::value> set_screen_update(T &&target, F &&callback, const char *name)
	{
		m_screen_update_ind16.set(std::forward<T>(target), std::forward<F>(callback), name);
		m_screen_update_rgb32 = screen_update_rgb32_delegate(*this);
	}
	template <typename T, typename F>
	std::enable_if_t<screen_update_rgb32_delegate::supports_callback<F>::value> set_screen_update(T &&target, F &&callback, const char *name)
	{
		m_screen_update_ind16 = screen_update_ind16_delegate(*this);
		m_screen_update_rgb32.set(std::forward<T>(target), std::forward<F>(callback), name);
	}

	auto screen_vblank() { return m_screen_vblank.bind(); }
	auto scanline() { m_video_attributes |= VIDEO_UPDATE_SCANLINE; return m_scanline_cb.bind(); }
	template <typename T> screen_device &set_palette(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); return *this; }
	screen_device &set_no_palette() { m_palette.set_tag(finder_base::DUMMY_TAG); return *this; }
	screen_device &set_video_attributes(u32 flags) { m_video_attributes = flags; return *this; }
	screen_device &set_color(rgb_t color) { m_color = color; return *this; }
	template <typename T> screen_device &set_svg_region(T &&tag) { m_svg_region.set_tag(std::forward<T>(tag)); return *this; } // default region is device tag

	// information getters
	render_container &container() const { assert(m_container != nullptr); return *m_container; }
	bitmap_ind8 &priority() { return m_priority; }
	device_palette_interface &palette() const { assert(m_palette != nullptr); return *m_palette; }
	bool has_palette() const { return m_palette != nullptr; }
	screen_bitmap &curbitmap() { return m_bitmap[m_curtexture]; }

	// dynamic configuration
	void configure(int width, int height, const rectangle &visarea, attoseconds_t frame_period);
	void reset_origin(int beamy = 0, int beamx = 0);
	void set_visible_area(int min_x, int max_x, int min_y, int max_y);
	void set_brightness(u8 brightness) { m_brightness = brightness; }

	// beam positioning and state
	int vpos() const;
	int hpos() const;
	DECLARE_READ_LINE_MEMBER(vblank) const { return (machine().time() < m_vblank_end_time) ? 1 : 0; }
	DECLARE_READ_LINE_MEMBER(hblank) const { int const curpos = hpos(); return (curpos < m_visarea.left() || curpos > m_visarea.right()) ? 1 : 0; }

	// timing
	attotime time_until_pos(int vpos, int hpos = 0) const;
	attotime time_until_vblank_start() const { return time_until_pos(m_visarea.bottom() + 1); }
	attotime time_until_vblank_end() const;
	attotime time_until_update() const { return (m_video_attributes & VIDEO_UPDATE_AFTER_VBLANK) ? time_until_vblank_end() : time_until_vblank_start(); }
	attotime scan_period() const { return attotime(0, m_scantime); }
	attotime frame_period() const { return attotime(0, m_frame_period); }
	u64 frame_number() const { return m_frame_number; }

	// pixel-level access
	u32 pixel(s32 x, s32 y);
	void pixels(u32* buffer);

	// updating
	int partial_updates() const { return m_partial_updates_this_frame; }
	bool update_partial(int scanline);
	void update_now();
	void reset_partial_updates();

	// additional helpers
	void register_vblank_callback(vblank_state_delegate vblank_callback);
	void register_screen_bitmap(bitmap_t &bitmap);

	// internal to the video system
	bool update_quads();
	void update_burnin();

	// globally accessible constants
	static constexpr int DEFAULT_FRAME_RATE = 60;
	static const attotime DEFAULT_FRAME_PERIOD;

private:
	class svg_renderer;

	// timer IDs
	enum
	{
		TID_VBLANK_START,
		TID_VBLANK_END,
		TID_SCANLINE0,
		TID_SCANLINE
	};

	// device-level overrides
	virtual void device_validity_check(validity_checker &valid) const override;
	virtual void device_config_complete() override;
	virtual void device_resolve_objects() override;
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_stop() override;
	virtual void device_post_load() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

	// internal helpers
	void set_container(render_container &container) { m_container = &container; }
	void realloc_screen_bitmaps();
	void vblank_begin();
	void vblank_end();
	void finalize_burnin();
	void load_effect_overlay(const char *filename);
	void update_scan_bitmap_size(int y);
	void pre_update_scanline(int y);
	void create_composited_bitmap();

	// inline configuration data
	screen_type_enum    m_type;                     // type of screen
	int                 m_orientation;              // orientation flags combined with system flags
	std::pair<unsigned, unsigned> m_phys_aspect;    // physical aspect ratio
	bool                m_oldstyle_vblank_supplied; // set_vblank_time call used
	attoseconds_t       m_refresh;                  // default refresh period
	attoseconds_t       m_vblank;                   // duration of a VBLANK
	float               m_xoffset, m_yoffset;       // default X/Y offsets
	float               m_xscale, m_yscale;         // default X/Y scale factor
	screen_update_ind16_delegate m_screen_update_ind16; // screen update callback (16-bit palette)
	screen_update_rgb32_delegate m_screen_update_rgb32; // screen update callback (32-bit RGB)
	devcb_write_line    m_screen_vblank;            // screen vblank line callback
	devcb_write32       m_scanline_cb;              // screen scanline callback
	optional_device<device_palette_interface> m_palette;      // our palette
	u32                 m_video_attributes;         // flags describing the video system
	optional_memory_region m_svg_region;            // the region in which the svg data is in

	// internal state
	render_container *  m_container;                // pointer to our container
	std::unique_ptr<svg_renderer> m_svg; // the svg renderer
	// dimensions
	int                 m_max_width;                // maximum width encountered
	int                 m_width;                    // current width (HTOTAL)
	int                 m_height;                   // current height (VTOTAL)
	rectangle           m_visarea;                  // current visible area (HBLANK end/start, VBLANK end/start)
	std::vector<int>    m_scan_widths;              // current width, in samples, of each individual scanline

	// textures and bitmaps
	texture_format      m_texformat;                // texture format
	render_texture *    m_texture[2];               // 2x textures for the screen bitmap
	screen_bitmap       m_bitmap[2];                // 2x bitmaps for rendering
	std::vector<bitmap_t *> m_scan_bitmaps[2];      // 2x bitmaps for each individual scanline
	bitmap_ind8         m_priority;                 // priority bitmap
	bitmap_ind64        m_burnin;                   // burn-in bitmap
	u8                  m_curbitmap;                // current bitmap index
	u8                  m_curtexture;               // current texture index
	bool                m_changed;                  // has this bitmap changed?
	s32                 m_last_partial_scan;        // scanline of last partial update
	s32                 m_partial_scan_hpos;        // horizontal pixel last rendered on this partial scanline
	bitmap_argb32       m_screen_overlay_bitmap;    // screen overlay bitmap
	u32                 m_unique_id;                // unique id for this screen_device
	rgb_t               m_color;                    // render color
	u8                  m_brightness;               // global brightness

	// screen timing
	attoseconds_t       m_frame_period;             // attoseconds per frame
	attoseconds_t       m_scantime;                 // attoseconds per scanline
	attoseconds_t       m_pixeltime;                // attoseconds per pixel
	attoseconds_t       m_vblank_period;            // attoseconds per VBLANK period
	attotime            m_vblank_start_time;        // time of last VBLANK start
	attotime            m_vblank_end_time;          // time of last VBLANK end
	emu_timer *         m_vblank_begin_timer;       // timer to signal VBLANK start
	emu_timer *         m_vblank_end_timer;         // timer to signal VBLANK end
	emu_timer *         m_scanline0_timer;          // scanline 0 timer
	emu_timer *         m_scanline_timer;           // scanline timer
	u64                 m_frame_number;             // the current frame number
	u32                 m_partial_updates_this_frame;// partial update counter this frame

	bool                m_is_primary_screen;

	// VBLANK callbacks
	class callback_item
	{
	public:
		callback_item(vblank_state_delegate callback)
			: m_callback(std::move(callback)) { }

		vblank_state_delegate       m_callback;
	};
	std::vector<std::unique_ptr<callback_item>> m_callback_list;     // list of VBLANK callbacks

	// auto-sizing bitmaps
	class auto_bitmap_item
	{
	public:
		auto_bitmap_item(bitmap_t &bitmap)
			: m_bitmap(bitmap) { }
		bitmap_t &                  m_bitmap;
	};
	std::vector<std::unique_ptr<auto_bitmap_item>> m_auto_bitmap_list; // list of registered bitmaps

	// static data
	static u32          m_id_counter;   // incremented for each constructed screen_device,
										// used as a unique identifier during runtime
};

// device type definition
DECLARE_DEVICE_TYPE(SCREEN, screen_device)

// iterator helper
typedef device_type_iterator<screen_device> screen_device_iterator;

/*!
 @defgroup Screen device configuration functions
 @{
 @def set_type
  Modify the screen device type
  @see screen_type_enum
 @}
 */

#endif // MAME_EMU_SCREEN_H