src/mess/device.c
| r2113 | r2114 | |
| 17 | 17 | |
| 18 | 18 | |
| 19 | 19 | /*************************************************************************** |
| 20 | CONSTANTS |
| 21 | ***************************************************************************/ |
| 22 | |
| 23 | #define MESS_DEVICE DEVICE_GET_INFO_NAME(mess_device) |
| 24 | |
| 25 | |
| 26 | |
| 27 | /*************************************************************************** |
| 20 | 28 | TYPE DEFINITIONS |
| 21 | 29 | ***************************************************************************/ |
| 22 | 30 | |
| 23 | | struct Devices |
| 31 | /* this is placed in the inline_config of the MAME device structure */ |
| 32 | typedef struct _mess_device_config mess_device_config; |
| 33 | struct _mess_device_config |
| 24 | 34 | { |
| 25 | | iodevice_t type; |
| 26 | | const char *name; |
| 27 | | const char *shortname; |
| 35 | struct IODevice io_device; |
| 36 | char string_buffer[1024]; |
| 37 | struct CreateImageOptions createimage_options[MESS_DEVINFO_CREATE_OPTMAX + 1]; |
| 28 | 38 | }; |
| 29 | 39 | |
| 30 | 40 | |
| 31 | 41 | |
| 32 | | typedef struct _device_list device_list; |
| 33 | | struct _device_list |
| 42 | struct Devices |
| 34 | 43 | { |
| 35 | | object_pool *pool; |
| 36 | | struct IODevice devices[1]; |
| 44 | iodevice_t type; |
| 45 | const char *name; |
| 46 | const char *shortname; |
| 37 | 47 | }; |
| 38 | 48 | |
| 39 | 49 | |
| r2113 | r2114 | |
| 192 | 202 | |
| 193 | 203 | |
| 194 | 204 | /*------------------------------------------------- |
| 195 | | devices_allocate - allocate devices |
| 205 | DEVICE_START(mess_device) - device start |
| 206 | callback |
| 196 | 207 | -------------------------------------------------*/ |
| 197 | 208 | |
| 198 | | const struct IODevice *devices_allocate(const game_driver *gamedrv) |
| 209 | static DEVICE_START(mess_device) |
| 199 | 210 | { |
| 200 | | struct SystemConfigurationParamBlock params; |
| 201 | | device_getinfo_handler handlers[64]; |
| 202 | | int count_overrides[sizeof(handlers) / sizeof(handlers[0])]; |
| 203 | | int createimage_optcount, count, i, j, position; |
| 204 | | const char *file_extensions, *info_string; |
| 205 | | char *converted_file_extensions; |
| 206 | | object_pool *pool; |
| 207 | | device_list *devlist; |
| 208 | | struct IODevice *devices; |
| 211 | } |
| 209 | 212 | |
| 210 | | memset(handlers, 0, sizeof(handlers)); |
| 211 | | memset(count_overrides, 0, sizeof(count_overrides)); |
| 212 | 213 | |
| 213 | | if (gamedrv->sysconfig_ctor) |
| 214 | |
| 215 | /*------------------------------------------------- |
| 216 | DEVICE_GET_INFO(mess_device) - device get info |
| 217 | callback |
| 218 | -------------------------------------------------*/ |
| 219 | |
| 220 | DEVICE_GET_INFO(mess_device) |
| 221 | { |
| 222 | switch (state) |
| 214 | 223 | { |
| 215 | | memset(¶ms, 0, sizeof(params)); |
| 216 | | params.device_slotcount = sizeof(handlers) / sizeof(handlers[0]); |
| 217 | | params.device_handlers = handlers; |
| 218 | | params.device_countoverrides = count_overrides; |
| 219 | | gamedrv->sysconfig_ctor(¶ms); |
| 224 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 225 | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(mess_device_config); break; |
| 226 | case DEVINFO_INT_TOKEN_BYTES: info->i = 1; break; |
| 227 | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_OTHER; break; |
| 228 | |
| 229 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 230 | case DEVINFO_FCT_SET_INFO: /* Nothing */ break; |
| 231 | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(mess_device); break; |
| 232 | case DEVINFO_FCT_STOP: /* Nothing */ break; |
| 233 | case DEVINFO_FCT_RESET: /* Nothing */ break; |
| 234 | |
| 235 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 236 | case DEVINFO_STR_NAME: info->s = "Legacy MESS Device"; break; |
| 237 | case DEVINFO_STR_FAMILY: info->s = "Legacy MESS Device"; break; |
| 238 | case DEVINFO_STR_VERSION: info->s = "1.0"; break; |
| 239 | case DEVINFO_STR_SOURCE_FILE: info->s = __FILE__; break; |
| 240 | case DEVINFO_STR_CREDITS: info->s = "Copyright the MESS Team"; break; |
| 220 | 241 | } |
| 242 | } |
| 221 | 243 | |
| 222 | | /* count the amount of handlers that we have available */ |
| 223 | | for (count = 0; handlers[count]; count++) |
| 224 | | ; |
| 225 | | count++; /* for our purposes, include the tailing empty device */ |
| 226 | 244 | |
| 227 | | /* allocate a memory pool to use for these devices */ |
| 228 | | pool = pool_alloc(NULL); |
| 229 | | if (!pool) |
| 230 | | goto error; |
| 231 | 245 | |
| 232 | | /* allocate the device list */ |
| 233 | | devlist = (device_list *) pool_malloc(pool, sizeof(device_list) + (count - 1) * sizeof(struct IODevice)); |
| 234 | | if (!devlist) |
| 235 | | goto error; |
| 236 | | memset(devlist, 0, sizeof(device_list) + (count - 1) * sizeof(struct IODevice)); |
| 237 | | devlist->pool = pool; |
| 238 | | devices = devlist->devices; |
| 246 | /*------------------------------------------------- |
| 247 | string_buffer_putc |
| 248 | -------------------------------------------------*/ |
| 239 | 249 | |
| 240 | | position = 0; |
| 250 | static void string_buffer_putc(char *buffer, size_t buffer_length, size_t *buffer_pos, char c) |
| 251 | { |
| 252 | size_t pos; |
| 253 | |
| 254 | /* sanity check */ |
| 255 | assert_always(*buffer_pos < buffer_length, "Buffer too small"); |
| 256 | |
| 257 | pos = (*buffer_pos)++; |
| 258 | buffer[pos] = c; |
| 259 | } |
| 241 | 260 | |
| 242 | | for (i = 0; i < count; i++) |
| 261 | |
| 262 | |
| 263 | /*------------------------------------------------- |
| 264 | string_buffer_putstr |
| 265 | -------------------------------------------------*/ |
| 266 | |
| 267 | static char *string_buffer_putstr(char *buffer, size_t buffer_length, size_t *buffer_pos, const char *s) |
| 268 | { |
| 269 | char *result = NULL; |
| 270 | size_t i = 0; |
| 271 | |
| 272 | if (s != NULL) |
| 243 | 273 | { |
| 244 | | devices[i].type = IO_COUNT; |
| 245 | | |
| 246 | | if (handlers[i]) |
| 274 | result = &buffer[*buffer_pos]; |
| 275 | do |
| 247 | 276 | { |
| 248 | | devices[i].devclass.get_info = handlers[i]; |
| 249 | | devices[i].devclass.gamedrv = gamedrv; |
| 277 | string_buffer_putc(buffer, buffer_length, buffer_pos, s[i]); |
| 278 | } |
| 279 | while(s[i++] != '\0'); |
| 280 | } |
| 250 | 281 | |
| 251 | | /* convert file extensions from comma delimited to null delimited */ |
| 252 | | converted_file_extensions = NULL; |
| 253 | | file_extensions = mess_device_get_info_string(&devices[i].devclass, MESS_DEVINFO_STR_FILE_EXTENSIONS); |
| 254 | | if (file_extensions) |
| 255 | | { |
| 256 | | converted_file_extensions = pool_malloc(pool, strlen(file_extensions) + 2); |
| 257 | | if (!converted_file_extensions) |
| 258 | | goto error; |
| 282 | return result; |
| 283 | } |
| 259 | 284 | |
| 260 | | for (j = 0; file_extensions[j]; j++) |
| 261 | | converted_file_extensions[j] = (file_extensions[j] != ',') ? file_extensions[j] : '\0'; |
| 262 | | converted_file_extensions[j + 0] = '\0'; |
| 263 | | converted_file_extensions[j + 1] = '\0'; |
| 264 | | } |
| 265 | 285 | |
| 266 | | info_string = mess_device_get_info_string(&devices[i].devclass, MESS_DEVINFO_STR_DEV_TAG); |
| 267 | | devices[i].tag = info_string ? pool_strdup(pool, info_string) : NULL; |
| 268 | | devices[i].type = mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_TYPE); |
| 269 | | devices[i].count = mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_COUNT); |
| 270 | | devices[i].position = position; |
| 271 | | devices[i].file_extensions = converted_file_extensions; |
| 272 | 286 | |
| 273 | | devices[i].readable = mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_READABLE) ? 1 : 0; |
| 274 | | devices[i].writeable = mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_WRITEABLE) ? 1 : 0; |
| 275 | | devices[i].creatable = mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_CREATABLE) ? 1 : 0; |
| 276 | | devices[i].reset_on_load = mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_RESET_ON_LOAD) ? 1 : 0; |
| 277 | | devices[i].must_be_loaded = mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_MUST_BE_LOADED) ? 1 : 0; |
| 278 | | devices[i].load_at_init = mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_LOAD_AT_INIT) ? 1 : 0; |
| 287 | /*------------------------------------------------- |
| 288 | create_mess_device - allocates a single legacy |
| 289 | MESS device |
| 290 | -------------------------------------------------*/ |
| 279 | 291 | |
| 280 | | devices[i].init = (device_init_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_INIT); |
| 281 | | devices[i].exit = (device_exit_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_EXIT); |
| 282 | | devices[i].load = (device_load_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_LOAD); |
| 283 | | devices[i].create = (device_create_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_CREATE); |
| 284 | | devices[i].unload = (device_unload_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_UNLOAD); |
| 285 | | devices[i].imgverify = (device_verify_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_VERIFY); |
| 286 | | devices[i].partialhash = (device_partialhash_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_PARTIAL_HASH); |
| 287 | | devices[i].getdispositions = (device_getdispositions_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_GET_DISPOSITIONS); |
| 292 | static void create_mess_device(device_config **listheadptr, device_getinfo_handler handler, const game_driver *gamedrv, |
| 293 | int count_override, int *position) |
| 294 | { |
| 295 | mess_device_class mess_devclass; |
| 296 | const char *tag; |
| 297 | const char *info_string; |
| 298 | char dynamic_tag[32]; |
| 299 | device_config *device; |
| 300 | mess_device_config *mess_device; |
| 301 | const char *file_extensions; |
| 302 | int j; |
| 303 | size_t string_buffer_pos = 0; |
| 304 | int createimage_optcount; |
| 288 | 305 | |
| 289 | | devices[i].display = (device_display_handler) mess_device_get_info_fct(&devices[i].devclass, MESS_DEVINFO_PTR_DISPLAY); |
| 290 | | devices[i].name = default_device_name; |
| 306 | /* set up MESS's device class */ |
| 307 | mess_devclass.get_info = handler; |
| 308 | mess_devclass.gamedrv = gamedrv; |
| 291 | 309 | |
| 292 | | devices[i].createimage_optguide = (const struct OptionGuide *) mess_device_get_info_ptr(&devices[i].devclass, MESS_DEVINFO_PTR_CREATE_OPTGUIDE); |
| 310 | /* determine the tag */ |
| 311 | tag = mess_device_get_info_string(&mess_devclass, MESS_DEVINFO_STR_DEV_TAG); |
| 312 | if (tag == NULL) |
| 313 | { |
| 314 | /* create a default tag */ |
| 315 | snprintf(dynamic_tag, ARRAY_LENGTH(dynamic_tag), "mess_device_%d", *position); |
| 316 | tag = dynamic_tag; |
| 317 | } |
| 318 | |
| 319 | /* create a bonafide MAME device */ |
| 320 | device = device_list_add(listheadptr, MESS_DEVICE, tag); |
| 321 | mess_device = (mess_device_config *) device->inline_config; |
| 293 | 322 | |
| 294 | | createimage_optcount = (int) mess_device_get_info_int(&devices[i].devclass, MESS_DEVINFO_INT_CREATE_OPTCOUNT); |
| 295 | | if (createimage_optcount > 0) |
| 296 | | { |
| 297 | | struct CreateImageOptions *createimage_options; |
| 323 | /* convert file extensions from comma delimited to null delimited */ |
| 324 | file_extensions = mess_device_get_info_string(&mess_devclass, MESS_DEVINFO_STR_FILE_EXTENSIONS); |
| 325 | if (file_extensions != NULL) |
| 326 | { |
| 327 | const char *file_extensions_copy = &mess_device->string_buffer[string_buffer_pos]; |
| 298 | 328 | |
| 299 | | if (createimage_optcount > MESS_DEVINFO_CREATE_OPTMAX) |
| 300 | | fatalerror("MESS_DEVINFO_INT_CREATE_OPTCOUNT: Too many options"); |
| 329 | /* copy the file extensions over to the buffer */ |
| 330 | for (j = 0; file_extensions[j] != '\0'; j++) |
| 331 | { |
| 332 | string_buffer_putc(mess_device->string_buffer, ARRAY_LENGTH(mess_device->string_buffer), &string_buffer_pos, |
| 333 | (file_extensions[j] != ',') ? file_extensions[j] : '\0'); |
| 334 | } |
| 335 | string_buffer_putc(mess_device->string_buffer, ARRAY_LENGTH(mess_device->string_buffer), &string_buffer_pos, '\0'); |
| 336 | string_buffer_putc(mess_device->string_buffer, ARRAY_LENGTH(mess_device->string_buffer), &string_buffer_pos, '\0'); |
| 301 | 337 | |
| 302 | | /* allocate the options */ |
| 303 | | createimage_options = pool_malloc(pool, (createimage_optcount + 1) * sizeof(*createimage_options)); |
| 304 | | if (!createimage_options) |
| 305 | | goto error; |
| 338 | file_extensions = file_extensions_copy; |
| 339 | } |
| 306 | 340 | |
| 307 | | /* set up each option in the list */ |
| 308 | | for (j = 0; j < createimage_optcount; j++) |
| 309 | | { |
| 310 | | info_string = mess_device_get_info_string(&devices[i].devclass, MESS_DEVINFO_STR_CREATE_OPTNAME + j); |
| 311 | | createimage_options[j].name = info_string ? pool_strdup(pool, info_string) : NULL; |
| 312 | | info_string = mess_device_get_info_string(&devices[i].devclass, MESS_DEVINFO_STR_CREATE_OPTDESC + j); |
| 313 | | createimage_options[j].description = info_string ? pool_strdup(pool, info_string) : NULL; |
| 314 | | info_string = mess_device_get_info_string(&devices[i].devclass, MESS_DEVINFO_STR_CREATE_OPTEXTS + j); |
| 315 | | createimage_options[j].extensions = info_string ? pool_strdup(pool, info_string) : NULL; |
| 316 | | createimage_options[j].optspec = mess_device_get_info_ptr(&devices[i].devclass, MESS_DEVINFO_PTR_CREATE_OPTSPEC + j); |
| 317 | | } |
| 341 | /* populate the legacy MESS device */ |
| 342 | mess_device->io_device.tag = device->tag; |
| 343 | mess_device->io_device.devconfig = device; |
| 344 | mess_device->io_device.devclass = mess_devclass; |
| 345 | mess_device->io_device.type = mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_TYPE); |
| 346 | mess_device->io_device.count = mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_COUNT); |
| 347 | mess_device->io_device.position = *position; |
| 348 | mess_device->io_device.file_extensions = file_extensions; |
| 318 | 349 | |
| 319 | | /* terminate the list */ |
| 320 | | memset(&createimage_options[createimage_optcount], 0, sizeof(createimage_options[createimage_optcount])); |
| 350 | mess_device->io_device.readable = mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_READABLE) ? 1 : 0; |
| 351 | mess_device->io_device.writeable = mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_WRITEABLE) ? 1 : 0; |
| 352 | mess_device->io_device.creatable = mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_CREATABLE) ? 1 : 0; |
| 353 | mess_device->io_device.reset_on_load = mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_RESET_ON_LOAD) ? 1 : 0; |
| 354 | mess_device->io_device.must_be_loaded = mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_MUST_BE_LOADED) ? 1 : 0; |
| 355 | mess_device->io_device.load_at_init = mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_LOAD_AT_INIT) ? 1 : 0; |
| 321 | 356 | |
| 322 | | /* place this list in the structure */ |
| 323 | | devices[i].createimage_options = createimage_options; |
| 324 | | } |
| 357 | mess_device->io_device.init = (device_init_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_INIT); |
| 358 | mess_device->io_device.exit = (device_exit_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_EXIT); |
| 359 | mess_device->io_device.load = (device_load_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_LOAD); |
| 360 | mess_device->io_device.create = (device_create_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_CREATE); |
| 361 | mess_device->io_device.unload = (device_unload_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_UNLOAD); |
| 362 | mess_device->io_device.imgverify = (device_verify_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_VERIFY); |
| 363 | mess_device->io_device.partialhash = (device_partialhash_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_PARTIAL_HASH); |
| 364 | mess_device->io_device.getdispositions = (device_getdispositions_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_GET_DISPOSITIONS); |
| 325 | 365 | |
| 326 | | position += devices[i].count; |
| 366 | mess_device->io_device.display = (device_display_handler) mess_device_get_info_fct(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_DISPLAY); |
| 367 | mess_device->io_device.name = default_device_name; |
| 327 | 368 | |
| 328 | | /* overriding the count? */ |
| 329 | | if (count_overrides[i]) |
| 330 | | devices[i].count = count_overrides[i]; |
| 369 | mess_device->io_device.createimage_optguide = (const struct OptionGuide *) mess_device_get_info_ptr(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_CREATE_OPTGUIDE); |
| 331 | 370 | |
| 332 | | /* any problems? */ |
| 333 | | if ((devices[i].type < 0) || (devices[i].type >= IO_COUNT)) |
| 334 | | goto error; |
| 335 | | if ((devices[i].count < 0) || (devices[i].count > MAX_DEV_INSTANCES)) |
| 336 | | goto error; |
| 371 | createimage_optcount = (int) mess_device_get_info_int(&mess_device->io_device.devclass, MESS_DEVINFO_INT_CREATE_OPTCOUNT); |
| 372 | if (createimage_optcount > 0) |
| 373 | { |
| 374 | if (createimage_optcount > MESS_DEVINFO_CREATE_OPTMAX) |
| 375 | fatalerror("MESS_DEVINFO_INT_CREATE_OPTCOUNT: Too many options"); |
| 337 | 376 | |
| 338 | | /* fill in defaults */ |
| 339 | | if (!devices[i].getdispositions) |
| 340 | | devices[i].getdispositions = default_device_getdispositions; |
| 377 | /* set up each option in the list */ |
| 378 | for (j = 0; j < createimage_optcount; j++) |
| 379 | { |
| 380 | info_string = mess_device_get_info_string(&mess_device->io_device.devclass, MESS_DEVINFO_STR_CREATE_OPTNAME + j); |
| 381 | mess_device->createimage_options[j].name = string_buffer_putstr(mess_device->string_buffer, ARRAY_LENGTH(mess_device->string_buffer), &string_buffer_pos, info_string); |
| 382 | |
| 383 | info_string = mess_device_get_info_string(&mess_device->io_device.devclass, MESS_DEVINFO_STR_CREATE_OPTDESC + j); |
| 384 | mess_device->createimage_options[j].description = string_buffer_putstr(mess_device->string_buffer, ARRAY_LENGTH(mess_device->string_buffer), &string_buffer_pos, info_string); |
| 385 | |
| 386 | info_string = mess_device_get_info_string(&mess_device->io_device.devclass, MESS_DEVINFO_STR_CREATE_OPTEXTS + j); |
| 387 | mess_device->createimage_options[j].extensions = string_buffer_putstr(mess_device->string_buffer, ARRAY_LENGTH(mess_device->string_buffer), &string_buffer_pos, info_string); |
| 388 | |
| 389 | mess_device->createimage_options[j].optspec = mess_device_get_info_ptr(&mess_device->io_device.devclass, MESS_DEVINFO_PTR_CREATE_OPTSPEC + j); |
| 341 | 390 | } |
| 391 | |
| 392 | /* terminate the list */ |
| 393 | memset(&mess_device->createimage_options[createimage_optcount], 0, sizeof(mess_device->createimage_options[createimage_optcount])); |
| 342 | 394 | } |
| 343 | 395 | |
| 344 | | return devices; |
| 396 | *position += mess_device->io_device.count; |
| 345 | 397 | |
| 346 | | error: |
| 347 | | if (pool != NULL) |
| 348 | | pool_free(pool); |
| 349 | | return NULL; |
| 398 | /* overriding the count? */ |
| 399 | if (count_override != 0) |
| 400 | mess_device->io_device.count = count_override; |
| 401 | |
| 402 | /* any problems? */ |
| 403 | assert((mess_device->io_device.type >= 0) && (mess_device->io_device.type < IO_COUNT)); |
| 404 | assert ((mess_device->io_device.count >= 0) && (mess_device->io_device.count <= MAX_DEV_INSTANCES)); |
| 405 | |
| 406 | /* fill in defaults */ |
| 407 | if (!mess_device->io_device.getdispositions) |
| 408 | mess_device->io_device.getdispositions = default_device_getdispositions; |
| 350 | 409 | } |
| 351 | 410 | |
| 352 | 411 | |
| 353 | 412 | |
| 354 | 413 | /*------------------------------------------------- |
| 355 | | devices_free - free a device list |
| 414 | mess_devices_setup - allocate devices |
| 356 | 415 | -------------------------------------------------*/ |
| 357 | 416 | |
| 358 | | void devices_free(const struct IODevice *devices) |
| 417 | void mess_devices_setup(machine_config *config, const game_driver *gamedrv) |
| 359 | 418 | { |
| 360 | | const UINT8 *devices_b = (const UINT8 *) devices; |
| 361 | | const UINT8 *devlist_b = devices_b - offsetof(device_list, devices); |
| 362 | | device_list *devlist = (device_list *) devlist_b; |
| 363 | | pool_free(devlist->pool); |
| 419 | device_getinfo_handler handlers[64]; |
| 420 | int count_overrides[sizeof(handlers) / sizeof(handlers[0])]; |
| 421 | int i, position = 0; |
| 422 | |
| 423 | memset(handlers, 0, sizeof(handlers)); |
| 424 | memset(count_overrides, 0, sizeof(count_overrides)); |
| 425 | |
| 426 | /* call the "sysconfig" constructor, if present */ |
| 427 | if (gamedrv->sysconfig_ctor != NULL) |
| 428 | { |
| 429 | struct SystemConfigurationParamBlock params; |
| 430 | |
| 431 | memset(¶ms, 0, sizeof(params)); |
| 432 | params.device_slotcount = sizeof(handlers) / sizeof(handlers[0]); |
| 433 | params.device_handlers = handlers; |
| 434 | params.device_countoverrides = count_overrides; |
| 435 | gamedrv->sysconfig_ctor(¶ms); |
| 436 | } |
| 437 | |
| 438 | /* loop through all handlers */ |
| 439 | for (i = 0; handlers[i] != NULL; i++) |
| 440 | { |
| 441 | create_mess_device(&config->devicelist, handlers[i], gamedrv, count_overrides[i], &position); |
| 442 | } |
| 364 | 443 | } |
| 365 | 444 | |
| 366 | 445 | |
| 367 | 446 | |
| 447 | /*------------------------------------------------- |
| 448 | machine_config_alloc_with_mess_devices - |
| 449 | allocate a machine_config with MESS devices |
| 450 | -------------------------------------------------*/ |
| 451 | |
| 452 | machine_config *machine_config_alloc_with_mess_devices(const game_driver *gamedrv) |
| 453 | { |
| 454 | machine_config *config = machine_config_alloc(gamedrv->machine_config); |
| 455 | mess_devices_setup(config, gamedrv); |
| 456 | return config; |
| 457 | } |
| 458 | |
| 459 | |
| 460 | |
| 368 | 461 | /************************************* |
| 369 | 462 | * |
| 370 | 463 | * Device enumeration |
| 371 | 464 | * |
| 372 | 465 | *************************************/ |
| 373 | 466 | |
| 374 | | static const struct IODevice *filter_device_array_termination(const struct IODevice *dev) |
| 375 | | { |
| 376 | | return ((dev != NULL) && (dev->type < IO_COUNT)) ? dev : NULL; |
| 377 | | } |
| 378 | | |
| 379 | | |
| 380 | | |
| 381 | 467 | const struct IODevice *mess_device_first_from_machine(const running_machine *machine) |
| 382 | 468 | { |
| 383 | | return filter_device_array_termination(machine->devices); |
| 469 | const device_config *devconfig; |
| 470 | devconfig = device_list_first(machine->config->devicelist, MESS_DEVICE); |
| 471 | return (devconfig != NULL) ? devconfig->inline_config : NULL; |
| 384 | 472 | } |
| 385 | 473 | |
| 386 | 474 | |
| 387 | 475 | |
| 388 | 476 | const struct IODevice *mess_device_next(const struct IODevice *dev) |
| 389 | 477 | { |
| 390 | | return filter_device_array_termination(dev + 1); |
| 478 | const device_config *devconfig; |
| 479 | devconfig = device_list_next(dev->devconfig, MESS_DEVICE); |
| 480 | return (devconfig != NULL) ? devconfig->inline_config : NULL; |
| 391 | 481 | } |
| 392 | 482 | |
| 393 | 483 | |
| r2113 | r2114 | |
| 398 | 488 | * |
| 399 | 489 | *************************************/ |
| 400 | 490 | |
| 401 | | const struct IODevice *device_find_tag(const struct IODevice *devices, const char *tag) |
| 491 | const struct IODevice *mess_device_from_core_device(const device_config *device) |
| 402 | 492 | { |
| 403 | | int i; |
| 404 | | for (i = 0; devices[i].type != IO_COUNT; i++) |
| 405 | | { |
| 406 | | if (devices[i].tag && !strcmp(devices[i].tag, tag)) |
| 407 | | return &devices[i]; |
| 408 | | } |
| 409 | | return NULL; |
| 493 | const mess_device_config *mess_device = (device != NULL) ? (const mess_device_config *) device->inline_config : NULL; |
| 494 | return (mess_device != NULL) ? &mess_device->io_device : NULL; |
| 410 | 495 | } |
| 411 | 496 | |
| 412 | 497 | |
| 413 | 498 | |
| 414 | | int device_count_tag(const struct IODevice *devices, const char *tag) |
| 415 | | { |
| 416 | | const struct IODevice *dev; |
| 417 | | dev = device_find_tag(devices, tag); |
| 418 | | return dev ? dev->count : 0; |
| 419 | | } |
| 420 | | |
| 421 | | |
| 422 | | |
| 423 | 499 | int device_count_tag_from_machine(const running_machine *machine, const char *tag) |
| 424 | 500 | { |
| 425 | | return device_count_tag(machine->devices, tag); |
| 501 | const device_config *device = device_list_find_by_tag(machine->config->devicelist, MESS_DEVICE, tag); |
| 502 | const struct IODevice *iodev = mess_device_from_core_device(device); |
| 503 | return (iodev != NULL) ? iodev->count : 0; |
| 426 | 504 | } |
| 427 | 505 | |
| 428 | 506 | |
| 429 | 507 | |
| 430 | 508 | /* this function is deprecated */ |
| 431 | | const struct IODevice *device_find(const struct IODevice *devices, iodevice_t type) |
| 509 | const struct IODevice *device_find_from_machine(const running_machine *machine, iodevice_t type) |
| 432 | 510 | { |
| 433 | | int i; |
| 434 | | for (i = 0; devices[i].type != IO_COUNT; i++) |
| 511 | const device_config *device; |
| 512 | |
| 513 | for (device = device_list_first(machine->config->devicelist, MESS_DEVICE); device != NULL; device = device_list_next(device, MESS_DEVICE)) |
| 435 | 514 | { |
| 436 | | if (devices[i].type == type) |
| 437 | | return &devices[i]; |
| 515 | const struct IODevice *iodev = mess_device_from_core_device(device); |
| 516 | if (iodev->type == type) |
| 517 | { |
| 518 | return iodev; |
| 519 | } |
| 438 | 520 | } |
| 439 | 521 | return NULL; |
| 440 | 522 | } |
| r2113 | r2114 | |
| 442 | 524 | |
| 443 | 525 | |
| 444 | 526 | /* this function is deprecated */ |
| 445 | | const struct IODevice *device_find_from_machine(const running_machine *machine, iodevice_t type) |
| 446 | | { |
| 447 | | return device_find(machine->devices, type); |
| 448 | | } |
| 449 | | |
| 450 | | |
| 451 | | |
| 452 | | /* this function is deprecated */ |
| 453 | 527 | int device_count(iodevice_t type) |
| 454 | 528 | { |
| 455 | 529 | const struct IODevice *iodev = device_find_from_machine(Machine, type); |
src/mess/osd/winui/messui.c
| r2113 | r2114 | |
| 375 | 375 | |
| 376 | 376 | BOOL MessApproveImageList(HWND hParent, int drvindex) |
| 377 | 377 | { |
| 378 | | int i, nPos, devindex; |
| 379 | | const struct IODevice *devices; |
| 380 | | const game_driver *pDriver; |
| 378 | machine_config *config; |
| 379 | const device_config *dev; |
| 380 | const struct IODevice *iodev; |
| 381 | int i, nPos; |
| 381 | 382 | char szMessage[256]; |
| 382 | 383 | LPCSTR pszSoftware; |
| 383 | 384 | BOOL bResult = FALSE; |
| 384 | 385 | |
| 385 | 386 | begin_resource_tracking(); |
| 386 | 387 | |
| 387 | | pDriver = drivers[drvindex]; |
| 388 | | devices = devices_allocate(pDriver); |
| 388 | // allocate the machine config |
| 389 | config = machine_config_alloc_with_mess_devices(drivers[drvindex]); |
| 389 | 390 | |
| 390 | 391 | nPos = 0; |
| 391 | | for (devindex = 0; devices[devindex].type < IO_COUNT; devindex++) |
| 392 | for (dev = device_list_first(config->devicelist, MESS_DEVICE); dev != NULL; dev = device_list_next(dev, MESS_DEVICE)) |
| 392 | 393 | { |
| 394 | iodev = mess_device_from_core_device(dev); |
| 395 | |
| 393 | 396 | // confirm any mandatory devices are loaded |
| 394 | | if (devices[devindex].must_be_loaded) |
| 397 | if (iodev->must_be_loaded) |
| 395 | 398 | { |
| 396 | | for (i = 0; i < devices[devindex].count; i++) |
| 399 | for (i = 0; i < iodev->count; i++) |
| 397 | 400 | { |
| 398 | | pszSoftware = GetSelectedSoftware(drvindex, &devices[devindex].devclass, i); |
| 401 | pszSoftware = GetSelectedSoftware(drvindex, &iodev->devclass, i); |
| 399 | 402 | if (!pszSoftware || !*pszSoftware) |
| 400 | 403 | { |
| 401 | 404 | snprintf(szMessage, sizeof(szMessage) / sizeof(szMessage[0]), |
| 402 | 405 | "System '%s' requires that device %s must have an image to load\n", |
| 403 | | pDriver->description, |
| 404 | | device_typename(devices[devindex].type)); |
| 406 | drivers[drvindex]->description, |
| 407 | device_typename(iodev->type)); |
| 405 | 408 | goto done; |
| 406 | 409 | } |
| 407 | 410 | } |
| 408 | 411 | } |
| 409 | 412 | |
| 410 | | nPos += devices[devindex].count; |
| 413 | nPos += iodev->count; |
| 411 | 414 | } |
| 412 | 415 | bResult = TRUE; |
| 413 | 416 | |
| r2113 | r2114 | |
| 417 | 420 | win_message_box_utf8(hParent, szMessage, MAMEUINAME, MB_OK); |
| 418 | 421 | } |
| 419 | 422 | |
| 420 | | devices_free(devices); |
| 423 | machine_config_free(config); |
| 421 | 424 | return bResult; |
| 422 | 425 | } |
| 423 | 426 | |
| r2113 | r2114 | |
| 441 | 444 | // Places the specified image in the specified slot; nID = -1 means don't matter |
| 442 | 445 | static void MessSpecifyImage(int drvindex, const mess_device_class *devclass, int nID, LPCSTR pszFilename) |
| 443 | 446 | { |
| 444 | | const struct IODevice *devices; |
| 445 | | const struct IODevice *dev; |
| 447 | machine_config *config; |
| 448 | const device_config *dev; |
| 449 | const struct IODevice *iodev = NULL; |
| 446 | 450 | const char *s; |
| 447 | 451 | int i; |
| 448 | 452 | |
| 449 | | devices = devices_allocate(devclass->gamedrv); |
| 453 | // allocate the machine config |
| 454 | config = machine_config_alloc_with_mess_devices(drivers[drvindex]); |
| 450 | 455 | |
| 451 | | for (dev = devices; dev->type < IO_COUNT; dev++) |
| 456 | for (dev = device_list_first(config->devicelist, MESS_DEVICE); dev != NULL; dev = device_list_next(dev, MESS_DEVICE)) |
| 452 | 457 | { |
| 453 | | if (dev->devclass.get_info == devclass->get_info) |
| 458 | iodev = mess_device_from_core_device(dev); |
| 459 | |
| 460 | if (iodev->devclass.get_info == devclass->get_info) |
| 454 | 461 | break; |
| 455 | 462 | } |
| 456 | 463 | |
| r2113 | r2114 | |
| 462 | 469 | if (nID < 0) |
| 463 | 470 | { |
| 464 | 471 | // special case; first try to find existing image |
| 465 | | for (i = 0; i < dev->count; i++) |
| 472 | for (i = 0; i < iodev->count; i++) |
| 466 | 473 | { |
| 467 | | s = GetSelectedSoftware(drvindex, &dev->devclass, i); |
| 474 | s = GetSelectedSoftware(drvindex, &iodev->devclass, i); |
| 468 | 475 | if (s && !mame_stricmp(s, pszFilename)) |
| 469 | 476 | { |
| 470 | 477 | nID = i; |
| r2113 | r2114 | |
| 476 | 483 | if (nID < 0) |
| 477 | 484 | { |
| 478 | 485 | // still not found? locate an empty slot |
| 479 | | for (i = 0; i < dev->count; i++) |
| 486 | for (i = 0; i < iodev->count; i++) |
| 480 | 487 | { |
| 481 | | s = GetSelectedSoftware(drvindex, &dev->devclass, i); |
| 488 | s = GetSelectedSoftware(drvindex, &iodev->devclass, i); |
| 482 | 489 | if (!s || !*s || !mame_stricmp(s, pszFilename)) |
| 483 | 490 | { |
| 484 | 491 | nID = i; |
| r2113 | r2114 | |
| 488 | 495 | } |
| 489 | 496 | |
| 490 | 497 | if (nID >= 0) |
| 491 | | InternalSetSelectedSoftware(drvindex, &dev->devclass, nID, pszFilename); |
| 498 | InternalSetSelectedSoftware(drvindex, &iodev->devclass, nID, pszFilename); |
| 492 | 499 | else if (LOG_SOFTWARE) |
| 493 | 500 | dprintf("MessSpecifyImage(): Failed to place image '%s'\n", pszFilename); |
| 494 | 501 | |
| 495 | | devices_free(devices); |
| 502 | machine_config_free(config); |
| 496 | 503 | } |
| 497 | 504 | |
| 498 | 505 | |
| r2113 | r2114 | |
| 500 | 507 | static void MessRemoveImage(int drvindex, mess_device_class devclass, LPCSTR pszFilename) |
| 501 | 508 | { |
| 502 | 509 | int i, nPos; |
| 503 | | const struct IODevice *devices; |
| 504 | | const struct IODevice *dev; |
| 510 | machine_config *config; |
| 511 | const device_config *dev; |
| 512 | const struct IODevice *iodev = NULL; |
| 505 | 513 | |
| 506 | | if (devclass.gamedrv) |
| 514 | if (devclass.gamedrv != NULL) |
| 507 | 515 | { |
| 508 | | devices = devices_allocate(devclass.gamedrv); |
| 516 | // allocate the machine config |
| 517 | config = machine_config_alloc_with_mess_devices(drivers[drvindex]); |
| 509 | 518 | |
| 510 | 519 | nPos = 0; |
| 511 | | for (dev = devices; dev->type < IO_COUNT; dev++) |
| 520 | for (dev = device_list_first(config->devicelist, MESS_DEVICE); dev != NULL; dev = device_list_next(dev, MESS_DEVICE)) |
| 512 | 521 | { |
| 513 | | if (dev->devclass.get_info == devclass.get_info) |
| 522 | iodev = mess_device_from_core_device(dev); |
| 523 | |
| 524 | if (iodev->devclass.get_info == devclass.get_info) |
| 514 | 525 | break; |
| 515 | | nPos += dev->count; |
| 526 | nPos += iodev->count; |
| 516 | 527 | } |
| 517 | 528 | |
| 518 | | if (dev->type < IO_COUNT) |
| 529 | if (iodev != NULL) |
| 519 | 530 | { |
| 520 | | for (i = 0; i < dev->count; i++) |
| 531 | for (i = 0; i < iodev->count; i++) |
| 521 | 532 | { |
| 522 | | if (!mame_stricmp(pszFilename, GetSelectedSoftware(drvindex, &dev->devclass, i))) |
| 533 | if (!mame_stricmp(pszFilename, GetSelectedSoftware(drvindex, &iodev->devclass, i))) |
| 523 | 534 | { |
| 524 | 535 | MessSpecifyImage(drvindex, &devclass, i, NULL); |
| 525 | 536 | break; |
| r2113 | r2114 | |
| 527 | 538 | } |
| 528 | 539 | } |
| 529 | 540 | |
| 530 | | devices_free(devices); |
| 541 | machine_config_free(config); |
| 531 | 542 | } |
| 532 | 543 | } |
| 533 | 544 | |
| r2113 | r2114 | |
| 549 | 560 | HWND hwndSoftware; |
| 550 | 561 | int i, id; |
| 551 | 562 | LVFINDINFO lvfi; |
| 552 | | const game_driver *pDriver; |
| 553 | | const struct IODevice *pDeviceList; |
| 554 | | const struct IODevice *pDevice; |
| 563 | machine_config *config; |
| 564 | const device_config *dev; |
| 565 | const struct IODevice *iodev; |
| 555 | 566 | LPCSTR pszSoftware; |
| 556 | 567 | |
| 557 | 568 | hwndSoftware = GetDlgItem(GetMainWindow(), IDC_SWLIST); |
| 558 | | pDriver = drivers[drvindex]; |
| 559 | | pDeviceList = devices_allocate(pDriver); |
| 560 | | if (!pDeviceList) |
| 561 | | goto done; |
| 562 | 569 | |
| 570 | // allocate the machine config |
| 571 | config = machine_config_alloc_with_mess_devices(drivers[drvindex]); |
| 572 | |
| 563 | 573 | s_bIgnoreSoftwarePickerNotifies = TRUE; |
| 564 | 574 | |
| 565 | 575 | // Now clear everything out; this may call back into us but it should not |
| 566 | 576 | // be problematic |
| 567 | 577 | ListView_SetItemState(hwndSoftware, -1, 0, LVIS_SELECTED); |
| 568 | 578 | |
| 569 | | for (pDevice = pDeviceList; pDevice->type < IO_COUNT; pDevice++) |
| 579 | for (dev = device_list_first(config->devicelist, MESS_DEVICE); dev != NULL; dev = device_list_next(dev, MESS_DEVICE)) |
| 570 | 580 | { |
| 571 | | for (id = 0; id < pDevice->count; id++) |
| 581 | iodev = mess_device_from_core_device(dev); |
| 582 | |
| 583 | for (id = 0; id < iodev->count; id++) |
| 572 | 584 | { |
| 573 | | pszSoftware = GetSelectedSoftware(drvindex, &pDevice->devclass, id); |
| 585 | pszSoftware = GetSelectedSoftware(drvindex, &iodev->devclass, id); |
| 574 | 586 | if (pszSoftware && *pszSoftware) |
| 575 | 587 | { |
| 576 | 588 | i = SoftwarePicker_LookupIndex(hwndSoftware, pszSoftware); |
| r2113 | r2114 | |
| 591 | 603 | } |
| 592 | 604 | } |
| 593 | 605 | |
| 594 | | |
| 595 | | done: |
| 596 | | devices_free(pDeviceList); |
| 606 | machine_config_free(config); |
| 597 | 607 | s_bIgnoreSoftwarePickerNotifies = FALSE; |
| 598 | 608 | } |
| 599 | 609 | |
| r2113 | r2114 | |
| 747 | 757 | |
| 748 | 758 | |
| 749 | 759 | /* Specify IO_COUNT for type if you want all types */ |
| 750 | | static void SetupImageTypes(const struct IODevice *devices, mess_image_type *types, int count, BOOL bZip, int type) |
| 760 | static void SetupImageTypes(const machine_config *config, mess_image_type *types, int count, BOOL bZip, int type) |
| 751 | 761 | { |
| 752 | 762 | int num_extensions = 0; |
| 753 | | int devindex; |
| 763 | const device_config *dev; |
| 764 | const struct IODevice *iodev; |
| 754 | 765 | |
| 755 | 766 | memset(types, 0, sizeof(*types) * count); |
| 756 | 767 | count--; |
| r2113 | r2114 | |
| 762 | 773 | num_extensions++; |
| 763 | 774 | } |
| 764 | 775 | |
| 765 | | if (devices != NULL) |
| 776 | for (dev = device_list_first(config->devicelist, MESS_DEVICE); dev != NULL; dev = device_list_next(dev, MESS_DEVICE)) |
| 766 | 777 | { |
| 767 | | for (devindex = 0; devices[devindex].type < IO_COUNT; devindex++) |
| 778 | iodev = mess_device_from_core_device(dev); |
| 779 | |
| 780 | if (iodev->type != IO_PRINTER) |
| 768 | 781 | { |
| 769 | | if (devices[devindex].type != IO_PRINTER) |
| 782 | const char *ext = iodev->file_extensions; |
| 783 | if (ext != NULL) |
| 770 | 784 | { |
| 771 | | const char *ext = devices[devindex].file_extensions; |
| 772 | | if (ext) |
| 785 | while(*ext != '\0') |
| 773 | 786 | { |
| 774 | | while(*ext) |
| 787 | if ((type == IO_COUNT) || (type == iodev->type)) |
| 775 | 788 | { |
| 776 | | if ((type == IO_COUNT) || (type == devices[devindex].type)) |
| 789 | if (num_extensions < count) |
| 777 | 790 | { |
| 778 | | if (num_extensions < count) |
| 779 | | { |
| 780 | | types[num_extensions].dev = &devices[devindex]; |
| 781 | | types[num_extensions].ext = ext; |
| 782 | | num_extensions++; |
| 783 | | } |
| 791 | types[num_extensions].dev = iodev; |
| 792 | types[num_extensions].ext = ext; |
| 793 | num_extensions++; |
| 784 | 794 | } |
| 785 | | ext += strlen(ext) + 1; |
| 786 | 795 | } |
| 796 | ext += strlen(ext) + 1; |
| 787 | 797 | } |
| 788 | 798 | } |
| 789 | 799 | } |
| r2113 | r2114 | |
| 799 | 809 | int drvindex; |
| 800 | 810 | HWND hwndList; |
| 801 | 811 | char* utf8_filename; |
| 802 | | const struct IODevice *devices; |
| 812 | machine_config *config; |
| 803 | 813 | |
| 804 | 814 | begin_resource_tracking(); |
| 805 | 815 | |
| 806 | 816 | hwndList = GetDlgItem(GetMainWindow(), IDC_LIST); |
| 807 | 817 | drvindex = Picker_GetSelectedItem(hwndList); |
| 808 | | devices = devices_allocate(drivers[drvindex]); |
| 809 | | SetupImageTypes(devices, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, iDevice); |
| 810 | 818 | |
| 819 | // allocate the machine config |
| 820 | config = machine_config_alloc_with_mess_devices(drivers[drvindex]); |
| 821 | |
| 822 | SetupImageTypes(config, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, iDevice); |
| 823 | |
| 811 | 824 | if (CommonFileImageDialog(last_directory, cfd, filename, imagetypes)) |
| 812 | 825 | { |
| 813 | 826 | utf8_filename = utf8_from_tstring(filename); |
| r2113 | r2114 | |
| 818 | 831 | free(utf8_filename); |
| 819 | 832 | } |
| 820 | 833 | |
| 821 | | if (devices != NULL) |
| 822 | | devices_free(devices); |
| 834 | machine_config_free(config); |
| 823 | 835 | } |
| 824 | 836 | |
| 825 | 837 | |
| r2113 | r2114 | |
| 844 | 856 | mess_image_type imagetypes[64]; |
| 845 | 857 | HWND hwndList; |
| 846 | 858 | int gamenum; |
| 847 | | const struct IODevice *devices; |
| 859 | machine_config *config; |
| 848 | 860 | |
| 849 | 861 | hwndList = GetDlgItem(GetMainWindow(), IDC_LIST); |
| 850 | 862 | gamenum = Picker_GetSelectedItem(hwndList); |
| 851 | | devices = devices_allocate(drivers[gamenum]); |
| 852 | | SetupImageTypes(devices, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev->type); |
| 863 | |
| 864 | // allocate the machine config |
| 865 | config = machine_config_alloc_with_mess_devices(drivers[gamenum]); |
| 866 | |
| 867 | SetupImageTypes(config, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev->type); |
| 853 | 868 | bResult = CommonFileImageDialog(last_directory, GetOpenFileName, pszFilename, imagetypes); |
| 854 | 869 | |
| 855 | | if (devices != NULL) |
| 856 | | devices_free(devices); |
| 870 | machine_config_free(config); |
| 857 | 871 | return bResult; |
| 858 | 872 | } |
| 859 | 873 | |
| r2113 | r2114 | |
| 865 | 879 | mess_image_type imagetypes[64]; |
| 866 | 880 | HWND hwndList; |
| 867 | 881 | int gamenum; |
| 868 | | const struct IODevice *devices; |
| 882 | machine_config *config; |
| 869 | 883 | |
| 870 | 884 | hwndList = GetDlgItem(GetMainWindow(), IDC_LIST); |
| 871 | 885 | gamenum = Picker_GetSelectedItem(hwndList); |
| 872 | | devices = devices_allocate(drivers[gamenum]); |
| 873 | | SetupImageTypes(devices, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev->type); |
| 886 | |
| 887 | // allocate the machine config |
| 888 | config = machine_config_alloc_with_mess_devices(drivers[gamenum]); |
| 889 | |
| 890 | SetupImageTypes(config, imagetypes, sizeof(imagetypes) / sizeof(imagetypes[0]), TRUE, dev->type); |
| 874 | 891 | bResult = CommonFileImageDialog(last_directory, GetSaveFileName, pszFilename, imagetypes); |
| 875 | 892 | |
| 876 | | if (devices != NULL) |
| 877 | | devices_free(devices); |
| 893 | machine_config_free(config); |
| 878 | 894 | return bResult; |
| 879 | 895 | } |
| 880 | 896 | |