1 // license:BSD-3-Clause 2 // copyright-holders:Aaron Giles 3 /*************************************************************************** 4 5 gamedrv.h 6 7 Definitions for game drivers. 8 9 ***************************************************************************/ 10 11 #ifndef MAME_EMU_GAMEDRV_H 12 #define MAME_EMU_GAMEDRV_H 13 14 #pragma once 15 16 #include <type_traits> 17 18 19 //************************************************************************** 20 // CONSTANTS 21 //************************************************************************** 22 23 // maxima 24 constexpr int MAX_DRIVER_NAME_CHARS = 16; 25 26 struct machine_flags 27 { 28 enum type : u32 29 { 30 MASK_ORIENTATION = 0x00000007, 31 MASK_TYPE = 0x00000038, 32 33 FLIP_X = 0x00000001, 34 FLIP_Y = 0x00000002, 35 SWAP_XY = 0x00000004, 36 ROT0 = 0x00000000, 37 ROT90 = FLIP_X | SWAP_XY, 38 ROT180 = FLIP_X | FLIP_Y, 39 ROT270 = FLIP_Y | SWAP_XY, 40 41 TYPE_ARCADE = 0x00000008, // coin-operated machine for public use 42 TYPE_CONSOLE = 0x00000010, // console system 43 TYPE_COMPUTER = 0x00000018, // any kind of computer including home computers, minis, calculators, ... 44 TYPE_OTHER = 0x00000038, // any other emulated system (e.g. clock, satellite receiver, ...) 45 46 NOT_WORKING = 0x00000040, 47 SUPPORTS_SAVE = 0x00000080, // system supports save states 48 NO_COCKTAIL = 0x00000100, // screen flip support is missing 49 IS_BIOS_ROOT = 0x00000200, // this driver entry is a BIOS root 50 REQUIRES_ARTWORK = 0x00000400, // requires external artwork for key game elements 51 CLICKABLE_ARTWORK = 0x00000800, // artwork is clickable and requires mouse cursor 52 UNOFFICIAL = 0x00001000, // unofficial hardware modification 53 NO_SOUND_HW = 0x00002000, // system has no sound output 54 MECHANICAL = 0x00004000, // contains mechanical parts (pinball, redemption games, ...) 55 IS_INCOMPLETE = 0x00008000 // official system with blatantly incomplete hardware/software 56 }; 57 }; 58 59 DECLARE_ENUM_BITWISE_OPERATORS(machine_flags::type); 60 61 62 // flags for machine drivers 63 constexpr u64 MACHINE_TYPE_ARCADE = machine_flags::TYPE_ARCADE; 64 constexpr u64 MACHINE_TYPE_CONSOLE = machine_flags::TYPE_CONSOLE; 65 constexpr u64 MACHINE_TYPE_COMPUTER = machine_flags::TYPE_COMPUTER; 66 constexpr u64 MACHINE_TYPE_OTHER = machine_flags::TYPE_OTHER; 67 constexpr u64 MACHINE_NOT_WORKING = machine_flags::NOT_WORKING; 68 constexpr u64 MACHINE_SUPPORTS_SAVE = machine_flags::SUPPORTS_SAVE; 69 constexpr u64 MACHINE_NO_COCKTAIL = machine_flags::NO_COCKTAIL; 70 constexpr u64 MACHINE_IS_BIOS_ROOT = machine_flags::IS_BIOS_ROOT; 71 constexpr u64 MACHINE_REQUIRES_ARTWORK = machine_flags::REQUIRES_ARTWORK; 72 constexpr u64 MACHINE_CLICKABLE_ARTWORK = machine_flags::CLICKABLE_ARTWORK; 73 constexpr u64 MACHINE_UNOFFICIAL = machine_flags::UNOFFICIAL; 74 constexpr u64 MACHINE_NO_SOUND_HW = machine_flags::NO_SOUND_HW; 75 constexpr u64 MACHINE_MECHANICAL = machine_flags::MECHANICAL; 76 constexpr u64 MACHINE_IS_INCOMPLETE = machine_flags::IS_INCOMPLETE; 77 78 // flags that map to device feature flags 79 constexpr u64 MACHINE_UNEMULATED_PROTECTION = 0x00000001'00000000; // game's protection not fully emulated 80 constexpr u64 MACHINE_WRONG_COLORS = 0x00000002'00000000; // colors are totally wrong 81 constexpr u64 MACHINE_IMPERFECT_COLORS = 0x00000004'00000000; // colors are not 100% accurate, but close 82 constexpr u64 MACHINE_IMPERFECT_GRAPHICS = 0x00000008'00000000; // graphics are wrong/incomplete 83 constexpr u64 MACHINE_NO_SOUND = 0x00000010'00000000; // sound is missing 84 constexpr u64 MACHINE_IMPERFECT_SOUND = 0x00000020'00000000; // sound is known to be wrong 85 constexpr u64 MACHINE_IMPERFECT_CONTROLS = 0x00000040'00000000; // controls are known to be imperfectly emulated 86 constexpr u64 MACHINE_NODEVICE_MICROPHONE = 0x00000080'00000000; // any game/system that has unemulated audio capture device 87 constexpr u64 MACHINE_NODEVICE_PRINTER = 0x00000100'00000000; // any game/system that has unemulated hardcopy output device 88 constexpr u64 MACHINE_NODEVICE_LAN = 0x00000200'00000000; // any game/system that has unemulated local networking 89 constexpr u64 MACHINE_IMPERFECT_TIMING = 0x00000400'00000000; // timing is known to be imperfectly emulated 90 91 // useful combinations of flags 92 constexpr u64 MACHINE_IS_SKELETON = MACHINE_NO_SOUND | MACHINE_NOT_WORKING; // flag combination for skeleton drivers 93 constexpr u64 MACHINE_IS_SKELETON_MECHANICAL = MACHINE_IS_SKELETON | MACHINE_MECHANICAL | MACHINE_REQUIRES_ARTWORK; // flag combination for skeleton mechanical machines 94 95 96 //************************************************************************** 97 // TYPE DEFINITIONS 98 //************************************************************************** 99 100 // static POD structure describing each game driver entry 101 class game_driver 102 { 103 public: 104 typedef void (*machine_creator_wrapper)(machine_config &, device_t &); 105 typedef void (*driver_init_wrapper)(device_t &); 106 unemulated_features(u64 flags)107 static constexpr device_t::feature_type unemulated_features(u64 flags) 108 { 109 return 110 ((flags & MACHINE_WRONG_COLORS) ? device_t::feature::PALETTE : device_t::feature::NONE) | 111 ((flags & MACHINE_NO_SOUND) ? device_t::feature::SOUND : device_t::feature::NONE) | 112 ((flags & MACHINE_NODEVICE_MICROPHONE) ? device_t::feature::MICROPHONE : device_t::feature::NONE) | 113 ((flags & MACHINE_NODEVICE_PRINTER) ? device_t::feature::PRINTER : device_t::feature::NONE) | 114 ((flags & MACHINE_NODEVICE_LAN) ? device_t::feature::LAN : device_t::feature::NONE); 115 } 116 imperfect_features(u64 flags)117 static constexpr device_t::feature_type imperfect_features(u64 flags) 118 { 119 return 120 ((flags & MACHINE_UNEMULATED_PROTECTION) ? device_t::feature::PROTECTION : device_t::feature::NONE) | 121 ((flags & MACHINE_IMPERFECT_COLORS) ? device_t::feature::PALETTE : device_t::feature::NONE) | 122 ((flags & MACHINE_IMPERFECT_GRAPHICS) ? device_t::feature::GRAPHICS : device_t::feature::NONE) | 123 ((flags & MACHINE_IMPERFECT_SOUND) ? device_t::feature::SOUND : device_t::feature::NONE) | 124 ((flags & MACHINE_IMPERFECT_CONTROLS) ? device_t::feature::CONTROLS : device_t::feature::NONE) | 125 ((flags & MACHINE_IMPERFECT_TIMING) ? device_t::feature::TIMING : device_t::feature::NONE); 126 } 127 128 device_type type; // static type info for driver class 129 const char * parent; // if this is a clone, the name of the parent 130 const char * year; // year the game was released 131 const char * manufacturer; // manufacturer of the game 132 machine_creator_wrapper machine_creator; // machine driver tokens 133 ioport_constructor ipt; // pointer to constructor for input ports 134 driver_init_wrapper driver_init; // DRIVER_INIT callback 135 const tiny_rom_entry * rom; // pointer to list of ROMs for the game 136 const char * compatible_with; 137 const internal_layout * default_layout; // default internally defined layout 138 machine_flags::type flags; // orientation and other flags; see defines above 139 char name[MAX_DRIVER_NAME_CHARS + 1]; // short name of the game 140 }; 141 142 143 //************************************************************************** 144 // MACROS 145 //************************************************************************** 146 147 // wrappers for declaring and defining game drivers 148 #define GAME_NAME(name) driver_##name 149 #define GAME_TRAITS_NAME(name) driver_##name##traits 150 #define GAME_EXTERN(name) extern game_driver const GAME_NAME(name) 151 152 // static game traits 153 #define GAME_DRIVER_TRAITS(NAME, FULLNAME) \ 154 namespace { \ 155 struct GAME_TRAITS_NAME(NAME) { static constexpr char const shortname[] = #NAME, fullname[] = FULLNAME, source[] = __FILE__; }; \ 156 constexpr char const GAME_TRAITS_NAME(NAME)::shortname[], GAME_TRAITS_NAME(NAME)::fullname[], GAME_TRAITS_NAME(NAME)::source[]; \ 157 } 158 #define GAME_DRIVER_TYPE(NAME, CLASS, FLAGS) \ 159 driver_device_creator< \ 160 CLASS, \ 161 (GAME_TRAITS_NAME(NAME)::shortname), \ 162 (GAME_TRAITS_NAME(NAME)::fullname), \ 163 (GAME_TRAITS_NAME(NAME)::source), \ 164 game_driver::unemulated_features(FLAGS), \ 165 game_driver::imperfect_features(FLAGS)> 166 167 // standard GAME() macro 168 #define GAME(YEAR,NAME,PARENT,MACHINE,INPUT,CLASS,INIT,MONITOR,COMPANY,FULLNAME,FLAGS) \ 169 GAME_DRIVER_TRAITS(NAME,FULLNAME) \ 170 extern game_driver const GAME_NAME(NAME) \ 171 { \ 172 GAME_DRIVER_TYPE(NAME, CLASS, FLAGS), \ 173 #PARENT, \ 174 #YEAR, \ 175 COMPANY, \ 176 [] (machine_config &config, device_t &owner) { downcast<CLASS &>(owner).MACHINE(config); }, \ 177 INPUT_PORTS_NAME(INPUT), \ 178 [] (device_t &owner) { downcast<CLASS &>(owner).INIT(); }, \ 179 ROM_NAME(NAME), \ 180 nullptr, \ 181 nullptr, \ 182 machine_flags::type(u32((MONITOR) | (FLAGS) | MACHINE_TYPE_ARCADE)),\ 183 #NAME \ 184 }; 185 186 // standard macro with additional layout 187 #define GAMEL(YEAR,NAME,PARENT,MACHINE,INPUT,CLASS,INIT,MONITOR,COMPANY,FULLNAME,FLAGS,LAYOUT) \ 188 GAME_DRIVER_TRAITS(NAME,FULLNAME) \ 189 extern game_driver const GAME_NAME(NAME) \ 190 { \ 191 GAME_DRIVER_TYPE(NAME, CLASS, FLAGS), \ 192 #PARENT, \ 193 #YEAR, \ 194 COMPANY, \ 195 [] (machine_config &config, device_t &owner) { downcast<CLASS &>(owner).MACHINE(config); }, \ 196 INPUT_PORTS_NAME(INPUT), \ 197 [] (device_t &owner) { downcast<CLASS &>(owner).INIT(); }, \ 198 ROM_NAME(NAME), \ 199 nullptr, \ 200 &LAYOUT, \ 201 machine_flags::type(u32((MONITOR) | (FLAGS) | MACHINE_TYPE_ARCADE)),\ 202 #NAME \ 203 }; 204 205 206 // standard console definition macro 207 #define CONS(YEAR,NAME,PARENT,COMPAT,MACHINE,INPUT,CLASS,INIT,COMPANY,FULLNAME,FLAGS) \ 208 GAME_DRIVER_TRAITS(NAME,FULLNAME) \ 209 extern game_driver const GAME_NAME(NAME) \ 210 { \ 211 GAME_DRIVER_TYPE(NAME, CLASS, FLAGS), \ 212 #PARENT, \ 213 #YEAR, \ 214 COMPANY, \ 215 [] (machine_config &config, device_t &owner) { downcast<CLASS &>(owner).MACHINE(config); }, \ 216 INPUT_PORTS_NAME(INPUT), \ 217 [] (device_t &owner) { downcast<CLASS &>(owner).INIT(); }, \ 218 ROM_NAME(NAME), \ 219 #COMPAT, \ 220 nullptr, \ 221 machine_flags::type(u32(ROT0 | (FLAGS) | MACHINE_TYPE_CONSOLE)), \ 222 #NAME \ 223 }; 224 225 // standard computer definition macro 226 #define COMP(YEAR,NAME,PARENT,COMPAT,MACHINE,INPUT,CLASS,INIT,COMPANY,FULLNAME,FLAGS) \ 227 GAME_DRIVER_TRAITS(NAME,FULLNAME) \ 228 extern game_driver const GAME_NAME(NAME) \ 229 { \ 230 GAME_DRIVER_TYPE(NAME, CLASS, FLAGS), \ 231 #PARENT, \ 232 #YEAR, \ 233 COMPANY, \ 234 [] (machine_config &config, device_t &owner) { downcast<CLASS &>(owner).MACHINE(config); }, \ 235 INPUT_PORTS_NAME(INPUT), \ 236 [] (device_t &owner) { downcast<CLASS &>(owner).INIT(); }, \ 237 ROM_NAME(NAME), \ 238 #COMPAT, \ 239 nullptr, \ 240 machine_flags::type(u32(ROT0 | (FLAGS) | MACHINE_TYPE_COMPUTER)), \ 241 #NAME \ 242 }; 243 244 // standard system definition macro 245 #define SYST(YEAR,NAME,PARENT,COMPAT,MACHINE,INPUT,CLASS,INIT,COMPANY,FULLNAME,FLAGS) \ 246 GAME_DRIVER_TRAITS(NAME,FULLNAME) \ 247 extern game_driver const GAME_NAME(NAME) \ 248 { \ 249 GAME_DRIVER_TYPE(NAME, CLASS, FLAGS), \ 250 #PARENT, \ 251 #YEAR, \ 252 COMPANY, \ 253 [] (machine_config &config, device_t &owner) { downcast<CLASS &>(owner).MACHINE(config); }, \ 254 INPUT_PORTS_NAME(INPUT), \ 255 [] (device_t &owner) { downcast<CLASS &>(owner).INIT(); }, \ 256 ROM_NAME(NAME), \ 257 #COMPAT, \ 258 nullptr, \ 259 machine_flags::type(u32(ROT0 | (FLAGS) | MACHINE_TYPE_OTHER)), \ 260 #NAME \ 261 }; 262 263 264 #endif // MAME_EMU_GAMEDRV_H 265