1 // license:BSD-3-Clause 2 // copyright-holders:Nicola Salmoria, Aaron Giles, Alex W. Jackson 3 /*************************************************************************** 4 5 digfx.h 6 7 Device graphics interfaces. 8 9 ***************************************************************************/ 10 11 #pragma once 12 13 #ifndef __EMU_H__ 14 #error Dont include this file directly; include emu.h instead. 15 #endif 16 17 #ifndef MAME_EMU_DIGFX_H 18 #define MAME_EMU_DIGFX_H 19 20 21 22 //************************************************************************** 23 // CONSTANTS 24 //************************************************************************** 25 26 constexpr u8 MAX_GFX_ELEMENTS = 32; 27 constexpr u16 MAX_GFX_PLANES = 8; 28 constexpr u16 MAX_GFX_SIZE = 32; 29 30 31 32 //************************************************************************** 33 // GRAPHICS LAYOUT MACROS 34 //************************************************************************** 35 36 #define EXTENDED_XOFFS { 0 } 37 #define EXTENDED_YOFFS { 0 } 38 39 #define GFX_RAW 0x12345678 40 #define GFXLAYOUT_RAW( name, width, height, linemod, charmod ) \ 41 const gfx_layout name = { width, height, RGN_FRAC(1,1), 8, { GFX_RAW }, { 0 }, { linemod }, charmod }; 42 // When planeoffset[0] is set to GFX_RAW, the gfx data is left as-is, with no conversion. 43 // No buffer is allocated for the decoded data, and gfxdata is set to point to the source 44 // data. 45 // yoffset[0] is the line modulo (*8) and charincrement the char modulo (*8). They are *8 46 // for consistency with the usual behaviour, but the bottom 3 bits are not used. 47 // 48 // This special mode can be used for graphics that are already in 8bpp linear format, 49 // or for unusual formats that don't fit our generic model and need to be decoded using 50 // custom code. See blend_gfx() in atarigen.c for an example of the latter usage. 51 52 53 // these macros describe gfx_layouts in terms of fractions of a region 54 // they can be used for total, planeoffset, xoffset, yoffset 55 #define RGN_FRAC(num,den) (0x80000000 | (((num) & 0x0f) << 27) | (((den) & 0x0f) << 23)) 56 #define IS_FRAC(offset) ((offset) & 0x80000000) 57 #define FRAC_NUM(offset) (((offset) >> 27) & 0x0f) 58 #define FRAC_DEN(offset) (((offset) >> 23) & 0x0f) 59 #define FRAC_OFFSET(offset) ((offset) & 0x007fffff) 60 61 // these macros are useful in gfx_layouts 62 #define STEP2(START,STEP) (START),(START)+(STEP) 63 #define STEP4(START,STEP) STEP2(START,STEP),STEP2((START)+2*(STEP),STEP) 64 #define STEP8(START,STEP) STEP4(START,STEP),STEP4((START)+4*(STEP),STEP) 65 #define STEP16(START,STEP) STEP8(START,STEP),STEP8((START)+8*(STEP),STEP) 66 #define STEP32(START,STEP) STEP16(START,STEP),STEP16((START)+16*(STEP),STEP) 67 #define STEP64(START,STEP) STEP32(START,STEP),STEP32((START)+32*(STEP),STEP) 68 #define STEP128(START,STEP) STEP64(START,STEP),STEP64((START)+64*(STEP),STEP) 69 #define STEP256(START,STEP) STEP128(START,STEP),STEP128((START)+128*(STEP),STEP) 70 #define STEP512(START,STEP) STEP256(START,STEP),STEP256((START)+256*(STEP),STEP) 71 #define STEP1024(START,STEP) STEP512(START,STEP),STEP512((START)+512*(STEP),STEP) 72 #define STEP2048(START,STEP) STEP1024(START,STEP),STEP1024((START)+1024*(STEP),STEP) 73 74 #define STEP2_INV(START,STEP) (START)+(STEP),(START) 75 #define STEP4_INV(START,STEP) STEP2_INV(START+2*STEP,STEP),STEP2_INV(START,STEP) 76 77 //************************************************************************** 78 // GRAPHICS INFO MACROS 79 //************************************************************************** 80 81 // optional horizontal and vertical scaling factors 82 #define GFXENTRY_XSCALEMASK 0x000000ff 83 #define GFXENTRY_YSCALEMASK 0x0000ff00 84 #define GFXENTRY_XSCALE(x) ((((x)-1) << 0) & GFXENTRY_XSCALEMASK) 85 #define GFXENTRY_YSCALE(x) ((((x)-1) << 8) & GFXENTRY_YSCALEMASK) 86 #define GFXENTRY_GETXSCALE(x) ((((x) & GFXENTRY_XSCALEMASK) >> 0) + 1) 87 #define GFXENTRY_GETYSCALE(x) ((((x) & GFXENTRY_YSCALEMASK) >> 8) + 1) 88 89 // GFXENTRY_RAM means region tag refers to a RAM share instead of a ROM region 90 #define GFXENTRY_ROM 0x00000000 91 #define GFXENTRY_RAM 0x00010000 92 #define GFXENTRY_ISROM(x) (((x) & GFXENTRY_RAM) == 0) 93 #define GFXENTRY_ISRAM(x) (((x) & GFXENTRY_RAM) != 0) 94 95 // GFXENTRY_DEVICE means region tag is relative to this device instead of its owner 96 #define GFXENTRY_DEVICE 0x00020000 97 #define GFXENTRY_ISDEVICE(x) (((x) & GFXENTRY_DEVICE) != 0) 98 99 // GFXENTRY_REVERSE reverses the bit order in the layout (0-7 = LSB-MSB instead of MSB-LSB) 100 #define GFXENTRY_REVERSE 0x00040000 101 #define GFXENTRY_ISREVERSE(x) (((x) & GFXENTRY_REVERSE) != 0) 102 103 104 // these macros are used for declaring gfx_decode_entry info arrays 105 #define GFXDECODE_START( name ) const gfx_decode_entry name[] = { 106 #define GFXDECODE_END { 0 } }; 107 108 // use these to declare a gfx_decode_entry array as a member of a device class 109 #define DECLARE_GFXDECODE_MEMBER( name ) static const gfx_decode_entry name[] 110 #define GFXDECODE_MEMBER( name ) const gfx_decode_entry name[] = { 111 // common gfx_decode_entry macros 112 #define GFXDECODE_ENTRYX(region,offset,layout,start,colors,flags) { region, offset, &layout, start, colors, flags }, 113 #define GFXDECODE_ENTRY(region,offset,layout,start,colors) { region, offset, &layout, start, colors, 0 }, 114 115 // specialized gfx_decode_entry macros 116 #define GFXDECODE_RAM(region,offset,layout,start,colors) { region, offset, &layout, start, colors, GFXENTRY_RAM }, 117 #define GFXDECODE_DEVICE(region,offset,layout,start,colors) { region, offset, &layout, start, colors, GFXENTRY_DEVICE }, 118 #define GFXDECODE_DEVICE_RAM(region,offset,layout,start,colors) { region, offset, &layout, start, colors, GFXENTRY_DEVICE | GFXENTRY_RAM }, 119 #define GFXDECODE_SCALE(region,offset,layout,start,colors,x,y) { region, offset, &layout, start, colors, GFXENTRY_XSCALE(x) | GFXENTRY_YSCALE(y) }, 120 #define GFXDECODE_REVERSEBITS(region,offset,layout,start,colors) { region, offset, &layout, start, colors, GFXENTRY_REVERSE }, 121 122 123 124 //************************************************************************** 125 // TYPE DEFINITIONS 126 //************************************************************************** 127 128 struct gfx_layout 129 { xoffsgfx_layout130 u32 xoffs(int x) const { return (extxoffs != nullptr) ? extxoffs[x] : xoffset[x]; } yoffsgfx_layout131 u32 yoffs(int y) const { return (extyoffs != nullptr) ? extyoffs[y] : yoffset[y]; } 132 133 u16 width; // pixel width of each element 134 u16 height; // pixel height of each element 135 u32 total; // total number of elements, or RGN_FRAC() 136 u16 planes; // number of bitplanes 137 u32 planeoffset[MAX_GFX_PLANES]; // bit offset of each bitplane 138 u32 xoffset[MAX_GFX_SIZE]; // bit offset of each horizontal pixel 139 u32 yoffset[MAX_GFX_SIZE]; // bit offset of each vertical pixel 140 u32 charincrement; // distance between two consecutive elements (in bits) 141 const u32 * extxoffs; // extended X offset array for really big layouts 142 const u32 * extyoffs; // extended Y offset array for really big layouts 143 }; 144 145 struct gfx_decode_entry 146 { 147 const char * memory_region; // memory region where the data resides 148 u32 start; // offset of beginning of data to decode 149 const gfx_layout *gfxlayout; // pointer to gfx_layout describing the layout; nullptr marks the end of the array 150 u16 color_codes_start; // offset in the color lookup table where color codes start 151 u16 total_color_codes; // total number of color codes 152 u32 flags; // flags and optional scaling factors 153 }; 154 155 // ======================> device_gfx_interface 156 157 class device_gfx_interface : public device_interface 158 { 159 public: 160 static const gfx_decode_entry empty[]; 161 162 // construction/destruction 163 device_gfx_interface(const machine_config &mconfig, device_t &device, 164 const gfx_decode_entry *gfxinfo = nullptr, const char *palette_tag = finder_base::DUMMY_TAG); 165 virtual ~device_gfx_interface(); 166 167 // configuration set_info(const gfx_decode_entry * gfxinfo)168 void set_info(const gfx_decode_entry *gfxinfo) { m_gfxdecodeinfo = gfxinfo; } set_palette(T && tag)169 template <typename T> void set_palette(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); } 170 171 void set_palette_disable(bool disable); 172 173 // getters palette()174 device_palette_interface &palette() const { assert(m_palette); return *m_palette; } gfx(u8 index)175 gfx_element *gfx(u8 index) const { assert(index < MAX_GFX_ELEMENTS); return m_gfx[index].get(); } 176 177 // decoding 178 void decode_gfx(const gfx_decode_entry *gfxdecodeinfo); decode_gfx()179 void decode_gfx() { decode_gfx(m_gfxdecodeinfo); } 180 set_gfx(u8 index,std::unique_ptr<gfx_element> && element)181 void set_gfx(u8 index, std::unique_ptr<gfx_element> &&element) { assert(index < MAX_GFX_ELEMENTS); m_gfx[index] = std::move(element); } 182 183 protected: 184 // interface-level overrides 185 virtual void interface_validity_check(validity_checker &valid) const override; 186 virtual void interface_pre_start() override; 187 virtual void interface_post_start() override; 188 189 private: 190 optional_device<device_palette_interface> m_palette; // configured tag for palette device 191 std::unique_ptr<gfx_element> m_gfx[MAX_GFX_ELEMENTS]; // array of pointers to graphic sets 192 193 // configuration 194 const gfx_decode_entry * m_gfxdecodeinfo; // pointer to array of gfx decode information 195 bool m_palette_is_disabled; // no palette associated with this gfx decode 196 197 // internal state 198 bool m_decoded; // have we processed our decode info yet? 199 }; 200 201 // iterator 202 typedef device_interface_iterator<device_gfx_interface> gfx_interface_iterator; 203 204 205 #endif /* MAME_EMU_DIGFX_H */ 206