Develop and Download Open Source Software

Browse CVS Repository

Contents of /mame32jp/mame32jp/src/mame.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.7 - (show annotations) (download) (as text)
Thu May 9 19:20:51 2002 UTC (21 years, 11 months ago) by zero
Branch: MAIN
CVS Tags: ver0_60_3, ver0_60_4, ver0_60_5, HEAD
Changes since 1.6: +11 -6 lines
File MIME type: text/x-csrc
*** empty log message ***

1 #include "driver.h"
2 #include <ctype.h>
3 #include <stdarg.h>
4 #include "ui_text.h" /* LBO 042400 */
5 #include "mamedbg.h"
6 #include "artwork.h"
7 #include "state.h"
8 #include "vidhrdw/generic.h"
9 #include "palette.h"
10 #include "harddisk.h"
11 #ifdef MAME32JP
12 #include "tilemap.h"
13 #if !defined(CPSMAME) && !defined(NEOMAME) && !defined(TINY_COMPILE)
14 #include "patch/neopatch.h"
15 #define WIN32_LEAN_AND_MEAN
16 #include <windows.h>
17 BOOL Use60HzVsync(void);
18 #endif
19 #endif
20
21 #define TEST_CLIPPING 0
22
23
24 static struct RunningMachine active_machine;
25 struct RunningMachine *Machine = &active_machine;
26 static const struct GameDriver *gamedrv;
27 static struct InternalMachineDriver internal_drv;
28 static struct mame_bitmap *real_scrbitmap;
29
30 /* Variables to hold the status of various game options */
31 struct GameOptions options;
32
33 void *record; /* for -record */
34 void *playback; /* for -playback */
35 int mame_debug; /* !0 when -debug option is specified */
36
37 int bailing; /* set to 1 if the startup is aborted to prevent multiple error messages */
38
39 static int settingsloaded;
40
41 #ifndef MAME32JP
42 static int leds_status;
43 #else
44 int inp_use = 0;
45 #endif
46 static int bitmap_dirty;
47
48 static int last_partial_scanline;
49 int partial_update_count;
50
51
52
53 static void *mame_hard_disk_open(const char *filename, const char *mode);
54 static void mame_hard_disk_close(void *file);
55 static UINT32 mame_hard_disk_read(void *file, UINT64 offset, UINT32 count, void *buffer);
56 static UINT32 mame_hard_disk_write(void *file, UINT64 offset, UINT32 count, const void *buffer);
57
58 static struct hard_disk_interface mame_hard_disk_interface =
59 {
60 mame_hard_disk_open,
61 mame_hard_disk_close,
62 mame_hard_disk_read,
63 mame_hard_disk_write
64 };
65
66
67
68 int init_machine(void);
69 void shutdown_machine(void);
70 int run_machine(void);
71
72
73 #ifdef MAME_DEBUG
74
75 INLINE int my_stricmp( const char *dst, const char *src)
76 {
77 while (*src && *dst)
78 {
79 if( tolower(*src) != tolower(*dst) ) return *dst - *src;
80 src++;
81 dst++;
82 }
83 return *dst - *src;
84 }
85
86 static int validitychecks(void)
87 {
88 int i,j,cpu;
89 UINT8 a,b;
90 int error = 0;
91
92
93 a = 0xff;
94 b = a + 1;
95 if (b > a) { printf("UINT8 must be 8 bits\n"); error = 1; }
96
97 if (sizeof(INT8) != 1) { printf("INT8 must be 8 bits\n"); error = 1; }
98 if (sizeof(UINT8) != 1) { printf("UINT8 must be 8 bits\n"); error = 1; }
99 if (sizeof(INT16) != 2) { printf("INT16 must be 16 bits\n"); error = 1; }
100 if (sizeof(UINT16) != 2) { printf("UINT16 must be 16 bits\n"); error = 1; }
101 if (sizeof(INT32) != 4) { printf("INT32 must be 32 bits\n"); error = 1; }
102 if (sizeof(UINT32) != 4) { printf("UINT32 must be 32 bits\n"); error = 1; }
103 if (sizeof(INT64) != 8) { printf("INT64 must be 64 bits\n"); error = 1; }
104 if (sizeof(UINT64) != 8) { printf("UINT64 must be 64 bits\n"); error = 1; }
105
106 for (i = 0;drivers[i];i++)
107 {
108 struct InternalMachineDriver drv;
109 const struct RomModule *romp;
110 const struct InputPortTiny *inp;
111
112 expand_machine_driver(drivers[i]->drv, &drv);
113
114 if (drivers[i]->clone_of == drivers[i])
115 {
116 printf("%s: %s is set as a clone of itself\n",drivers[i]->source_file,drivers[i]->name);
117 error = 1;
118 }
119
120 if (drivers[i]->clone_of && drivers[i]->clone_of->clone_of)
121 {
122 if ((drivers[i]->clone_of->clone_of->flags & NOT_A_DRIVER) == 0)
123 {
124 printf("%s: %s is a clone of a clone\n",drivers[i]->source_file,drivers[i]->name);
125 error = 1;
126 }
127 }
128
129 #if 0
130 // if (drivers[i]->drv->color_table_len == drivers[i]->drv->total_colors &&
131 if (drivers[i]->drv->color_table_len && drivers[i]->drv->total_colors &&
132 drivers[i]->drv->vh_init_palette == 0)
133 {
134 printf("%s: %s could use color_table_len = 0\n",drivers[i]->source_file,drivers[i]->name);
135 error = 1;
136 }
137 #endif
138
139 for (j = i+1;drivers[j];j++)
140 {
141 if (!strcmp(drivers[i]->name,drivers[j]->name))
142 {
143 printf("%s: %s is a duplicate name (%s, %s)\n",drivers[i]->source_file,drivers[i]->name,drivers[i]->source_file,drivers[j]->source_file);
144 error = 1;
145 }
146 if (!strcmp(drivers[i]->description,drivers[j]->description))
147 {
148 printf("%s: %s is a duplicate description (%s, %s)\n",drivers[i]->description,drivers[i]->source_file,drivers[i]->name,drivers[j]->name);
149 error = 1;
150 }
151 if (drivers[i]->rom && drivers[i]->rom == drivers[j]->rom
152 && (drivers[i]->flags & NOT_A_DRIVER) == 0
153 && (drivers[j]->flags & NOT_A_DRIVER) == 0)
154 {
155 printf("%s: %s and %s use the same ROM set\n",drivers[i]->source_file,drivers[i]->name,drivers[j]->name);
156 error = 1;
157 }
158 }
159
160 romp = drivers[i]->rom;
161
162 if (romp)
163 {
164 int region_type_used[REGION_MAX];
165 int region_length[REGION_MAX];
166 const char *last_name = 0;
167 int count = -1;
168
169 for (j = 0;j < REGION_MAX;j++)
170 {
171 region_type_used[j] = 0;
172 region_length[j] = 0;
173 }
174
175 while (!ROMENTRY_ISEND(romp))
176 {
177 const char *c;
178
179 if (ROMENTRY_ISREGION(romp))
180 {
181 int type = ROMREGION_GETTYPE(romp);
182
183 count++;
184 if (type && (type >= REGION_MAX || type <= REGION_INVALID))
185 {
186 printf("%s: %s has invalid ROM_REGION type %x\n",drivers[i]->source_file,drivers[i]->name,type);
187 error = 1;
188 }
189
190 region_type_used[type]++;
191 region_length[type] = region_length[count] = ROMREGION_GETLENGTH(romp);
192 }
193 if (ROMENTRY_ISFILE(romp))
194 {
195 int pre,post;
196
197 last_name = c = ROM_GETNAME(romp);
198 while (*c)
199 {
200 if (tolower(*c) != *c)
201 {
202 printf("%s: %s has upper case ROM name %s\n",drivers[i]->source_file,drivers[i]->name,ROM_GETNAME(romp));
203 error = 1;
204 }
205 c++;
206 }
207
208 c = ROM_GETNAME(romp);
209 pre = 0;
210 post = 0;
211 while (*c && *c != '.')
212 {
213 pre++;
214 c++;
215 }
216 while (*c)
217 {
218 post++;
219 c++;
220 }
221 if (pre > 8 || post > 4)
222 {
223 printf("%s: %s has >8.3 ROM name %s\n",drivers[i]->source_file,drivers[i]->name,ROM_GETNAME(romp));
224 error = 1;
225 }
226 }
227 if (!ROMENTRY_ISREGIONEND(romp)) /* ROM_LOAD_XXX() */
228 {
229 if (ROM_GETOFFSET(romp) + ROM_GETLENGTH(romp) > region_length[count])
230 {
231 printf("%s: %s has ROM %s extending past the defined memory region\n",drivers[i]->source_file,drivers[i]->name,last_name);
232 error = 1;
233 }
234 }
235 romp++;
236 }
237
238 for (j = 1;j < REGION_MAX;j++)
239 {
240 if (region_type_used[j] > 1)
241 {
242 printf("%s: %s has duplicated ROM_REGION type %x\n",drivers[i]->source_file,drivers[i]->name,j);
243 error = 1;
244 }
245 }
246
247
248 for (cpu = 0;cpu < MAX_CPU;cpu++)
249 {
250 if (drv.cpu[cpu].cpu_type)
251 {
252 int alignunit,databus_width;
253
254
255 alignunit = cputype_align_unit(drv.cpu[cpu].cpu_type & ~CPU_FLAGS_MASK);
256 databus_width = cputype_databus_width(drv.cpu[cpu].cpu_type & ~CPU_FLAGS_MASK);
257
258 if (drv.cpu[cpu].memory_read)
259 {
260 const struct Memory_ReadAddress *mra = drv.cpu[cpu].memory_read;
261
262 if (!IS_MEMPORT_MARKER(mra) || (mra->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_READ)
263 {
264 printf("%s: %s wrong MEMPORT_READ_START\n",drivers[i]->source_file,drivers[i]->name);
265 error = 1;
266 }
267
268 switch (databus_width)
269 {
270 case 8:
271 if ((mra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_8)
272 {
273 printf("%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mra->end);
274 error = 1;
275 }
276 break;
277 case 16:
278 if ((mra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_16)
279 {
280 printf("%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mra->end);
281 error = 1;
282 }
283 break;
284 case 32:
285 if ((mra->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_32)
286 {
287 printf("%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mra->end);
288 error = 1;
289 }
290 break;
291 }
292
293 while (!IS_MEMPORT_END(mra))
294 {
295 if (!IS_MEMPORT_MARKER(mra))
296 {
297 if (mra->end < mra->start)
298 {
299 printf("%s: %s wrong memory read handler start = %08x > end = %08x\n",drivers[i]->source_file,drivers[i]->name,mra->start,mra->end);
300 error = 1;
301 }
302 if ((mra->start & (alignunit-1)) != 0 || (mra->end & (alignunit-1)) != (alignunit-1))
303 {
304 printf("%s: %s wrong memory read handler start = %08x, end = %08x ALIGN = %d\n",drivers[i]->source_file,drivers[i]->name,mra->start,mra->end,alignunit);
305 error = 1;
306 }
307 }
308 mra++;
309 }
310 }
311 if (drv.cpu[cpu].memory_write)
312 {
313 const struct Memory_WriteAddress *mwa = drv.cpu[cpu].memory_write;
314
315 if (mwa->start != MEMPORT_MARKER ||
316 (mwa->end & MEMPORT_DIRECTION_MASK) != MEMPORT_DIRECTION_WRITE)
317 {
318 printf("%s: %s wrong MEMPORT_WRITE_START\n",drivers[i]->source_file,drivers[i]->name);
319 error = 1;
320 }
321
322 switch (databus_width)
323 {
324 case 8:
325 if ((mwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_8)
326 {
327 printf("%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mwa->end);
328 error = 1;
329 }
330 break;
331 case 16:
332 if ((mwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_16)
333 {
334 printf("%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mwa->end);
335 error = 1;
336 }
337 break;
338 case 32:
339 if ((mwa->end & MEMPORT_WIDTH_MASK) != MEMPORT_WIDTH_32)
340 {
341 printf("%s: %s cpu #%d uses wrong data width memory handlers! (width = %d, memory = %08x)\n",drivers[i]->source_file,drivers[i]->name,cpu,databus_width,mwa->end);
342 error = 1;
343 }
344 break;
345 }
346
347 while (!IS_MEMPORT_END(mwa))
348 {
349 if (!IS_MEMPORT_MARKER(mwa))
350 {
351 if (mwa->end < mwa->start)
352 {
353 printf("%s: %s wrong memory write handler start = %08x > end = %08x\n",drivers[i]->source_file,drivers[i]->name,mwa->start,mwa->end);
354 error = 1;
355 }
356 if ((mwa->start & (alignunit-1)) != 0 || (mwa->end & (alignunit-1)) != (alignunit-1))
357 {
358 printf("%s: %s wrong memory write handler start = %08x, end = %08x ALIGN = %d\n",drivers[i]->source_file,drivers[i]->name,mwa->start,mwa->end,alignunit);
359 error = 1;
360 }
361 }
362 mwa++;
363 }
364 }
365 }
366 }
367
368
369 if (drv.gfxdecodeinfo)
370 {
371 for (j = 0;j < MAX_GFX_ELEMENTS && drv.gfxdecodeinfo[j].memory_region != -1;j++)
372 {
373 int len,avail,k,start;
374 int type = drv.gfxdecodeinfo[j].memory_region;
375
376
377 /*
378 if (type && (type >= REGION_MAX || type <= REGION_INVALID))
379 {
380 printf("%s: %s has invalid memory region for gfx[%d]\n",drivers[i]->source_file,drivers[i]->name,j);
381 error = 1;
382 }
383 */
384
385 if (!IS_FRAC(drv.gfxdecodeinfo[j].gfxlayout->total))
386 {
387 start = 0;
388 for (k = 0;k < MAX_GFX_PLANES;k++)
389 {
390 if (drv.gfxdecodeinfo[j].gfxlayout->planeoffset[k] > start)
391 start = drv.gfxdecodeinfo[j].gfxlayout->planeoffset[k];
392 }
393 start &= ~(drv.gfxdecodeinfo[j].gfxlayout->charincrement-1);
394 len = drv.gfxdecodeinfo[j].gfxlayout->total *
395 drv.gfxdecodeinfo[j].gfxlayout->charincrement;
396 avail = region_length[type]
397 - (drv.gfxdecodeinfo[j].start & ~(drv.gfxdecodeinfo[j].gfxlayout->charincrement/8-1));
398 if ((start + len) / 8 > avail)
399 {
400 printf("%s: %s has gfx[%d] extending past allocated memory\n",drivers[i]->source_file,drivers[i]->name,j);
401 error = 1;
402 }
403 }
404 }
405 }
406 }
407
408
409 inp = drivers[i]->input_ports;
410
411 if (inp)
412 {
413 while (inp->type != IPT_END)
414 {
415 if (inp->name && inp->name != IP_NAME_DEFAULT)
416 {
417 j = 0;
418
419 for (j = 0;j < STR_TOTAL;j++)
420 {
421 if (inp->name == ipdn_defaultstrings[j]) break;
422 else if (!my_stricmp(inp->name,ipdn_defaultstrings[j]))
423 {
424 printf("%s: %s must use DEF_STR( %s )\n",drivers[i]->source_file,drivers[i]->name,inp->name);
425 error = 1;
426 }
427 }
428
429 if (inp->name == DEF_STR( On ) && (inp+1)->name == DEF_STR( Off ))
430 {
431 printf("%s: %s has inverted Off/On dipswitch order\n",drivers[i]->source_file,drivers[i]->name);
432 error = 1;
433 }
434
435 if (inp->name == DEF_STR( Yes ) && (inp+1)->name == DEF_STR( No ))
436 {
437 printf("%s: %s has inverted No/Yes dipswitch order\n",drivers[i]->source_file,drivers[i]->name);
438 error = 1;
439 }
440
441 if (!my_stricmp(inp->name,"table"))
442 {
443 printf("%s: %s must use DEF_STR( Cocktail ), not %s\n",drivers[i]->source_file,drivers[i]->name,inp->name);
444 error = 1;
445 }
446
447 if (inp->name == DEF_STR( Cabinet ) && (inp+1)->name == DEF_STR( Upright )
448 && inp->default_value != (inp+1)->default_value)
449 {
450 printf("%s: %s Cabinet must default to Upright\n",drivers[i]->source_file,drivers[i]->name);
451 error = 1;
452 }
453
454 if (inp->name == DEF_STR( Cocktail ) && (inp+1)->name == DEF_STR( Upright ))
455 {
456 printf("%s: %s has inverted Upright/Cocktail dipswitch order\n",drivers[i]->source_file,drivers[i]->name);
457 error = 1;
458 }
459
460 if (inp->name >= DEF_STR( 9C_1C ) && inp->name <= DEF_STR( Free_Play )
461 && (inp+1)->name >= DEF_STR( 9C_1C ) && (inp+1)->name <= DEF_STR( Free_Play )
462 && inp->name >= (inp+1)->name)
463 {
464 printf("%s: %s has unsorted coinage %s > %s\n",drivers[i]->source_file,drivers[i]->name,inp->name,(inp+1)->name);
465 error = 1;
466 }
467
468 if (inp->name == DEF_STR( Flip_Screen ) && (inp+1)->name != DEF_STR( Off ))
469 {
470 printf("%s: %s has wrong Flip Screen option %s\n",drivers[i]->source_file,drivers[i]->name,(inp+1)->name);
471 error = 1;
472 }
473
474 if (inp->name == DEF_STR( Demo_Sounds ) && (inp+2)->name == DEF_STR( On )
475 && inp->default_value != (inp+2)->default_value)
476 {
477 printf("%s: %s Demo Sounds must default to On\n",drivers[i]->source_file,drivers[i]->name);
478 error = 1;
479 }
480
481 }
482
483 inp++;
484 }
485 }
486 }
487
488 return error;
489 }
490 #endif
491
492
493
494
495 int run_game(int game)
496 {
497 int err;
498
499 begin_resource_tracking();
500
501 #ifdef MAME_DEBUG
502 /* validity checks */
503 if (validitychecks()) return 1;
504 #endif
505
506 #ifdef MAME32JP
507 set_tilefunc();
508 {
509 extern int resampling;
510 resampling = 0;
511 }
512 #endif
513
514 /* copy some settings into easier-to-handle variables */
515 record = options.record;
516 playback = options.playback;
517 mame_debug = options.mame_debug;
518
519 Machine->gamedrv = gamedrv = drivers[game];
520 expand_machine_driver(gamedrv->drv, &internal_drv);
521 Machine->drv = &internal_drv;
522
523 /* copy configuration */
524 if (Machine->drv->video_attributes & VIDEO_RGB_DIRECT)
525 {
526 if (Machine->drv->video_attributes & VIDEO_NEEDS_6BITS_PER_GUN)
527 Machine->color_depth = 32;
528 else
529 Machine->color_depth = 15;
530 }
531 else
532 Machine->color_depth = 16;
533
534 switch (options.color_depth)
535 {
536 case 16:
537 /* comply to -depth 16 only if we don't need a direct RGB mode */
538 if (!(Machine->drv->video_attributes & VIDEO_RGB_DIRECT))
539 Machine->color_depth = options.color_depth;
540 break;
541
542 case 15:
543 case 32:
544 /* comply to -depth 15/32 only if we need a direct RGB mode */
545 if (Machine->drv->video_attributes & VIDEO_RGB_DIRECT)
546 Machine->color_depth = options.color_depth;
547 break;
548 }
549
550
551 if (Machine->color_depth == 15 || Machine->color_depth == 32)
552 {
553 if (!(Machine->drv->video_attributes & VIDEO_RGB_DIRECT))
554 Machine->color_depth = 16;
555 else
556 {
557 alpha_active = 1;
558 alpha_init();
559 }
560 }
561 else
562 alpha_active = 0;
563
564 if (options.vector_width == 0) options.vector_width = 640;
565 if (options.vector_height == 0) options.vector_height = 480;
566
567 Machine->sample_rate = options.samplerate;
568
569 /* get orientation right */
570 Machine->orientation = gamedrv->flags & ORIENTATION_MASK;
571 Machine->ui_orientation = ROT0;
572 if (options.norotate)
573 Machine->orientation = ROT0;
574 if (options.ror)
575 {
576 /* if only one of the components is inverted, switch them */
577 if ((Machine->orientation & ROT180) == ORIENTATION_FLIP_X ||
578 (Machine->orientation & ROT180) == ORIENTATION_FLIP_Y)
579 Machine->orientation ^= ROT180;
580
581 Machine->orientation ^= ROT90;
582
583 /* if only one of the components is inverted, switch them */
584 if ((Machine->ui_orientation & ROT180) == ORIENTATION_FLIP_X ||
585 (Machine->ui_orientation & ROT180) == ORIENTATION_FLIP_Y)
586 Machine->ui_orientation ^= ROT180;
587
588 Machine->ui_orientation ^= ROT90;
589 }
590 if (options.rol)
591 {
592 /* if only one of the components is inverted, switch them */
593 if ((Machine->orientation & ROT180) == ORIENTATION_FLIP_X ||
594 (Machine->orientation & ROT180) == ORIENTATION_FLIP_Y)
595 Machine->orientation ^= ROT180;
596
597 Machine->orientation ^= ROT270;
598
599 /* if only one of the components is inverted, switch them */
600 if ((Machine->ui_orientation & ROT180) == ORIENTATION_FLIP_X ||
601 (Machine->ui_orientation & ROT180) == ORIENTATION_FLIP_Y)
602 Machine->ui_orientation ^= ROT180;
603
604 Machine->ui_orientation ^= ROT270;
605 }
606 if (options.flipx)
607 {
608 Machine->orientation ^= ORIENTATION_FLIP_X;
609 Machine->ui_orientation ^= ORIENTATION_FLIP_X;
610 }
611 if (options.flipy)
612 {
613 Machine->orientation ^= ORIENTATION_FLIP_Y;
614 Machine->ui_orientation ^= ORIENTATION_FLIP_Y;
615 }
616
617 /* Do the work*/
618 err = 1;
619 bailing = 0;
620
621 #ifdef MESS
622 if (get_filenames())
623 return err;
624 #endif
625
626 if (options.savegame)
627 cpu_loadsave_schedule(LOADSAVE_LOAD, options.savegame);
628 else
629 cpu_loadsave_reset();
630
631 if (osd_init() == 0)
632 {
633 begin_resource_tracking();
634 if (init_machine() == 0)
635 {
636 if (run_machine() == 0)
637 err = 0;
638 else if (!bailing)
639 {
640 bailing = 1;
641 printf("Unable to start machine emulation\n");
642 }
643
644 shutdown_machine();
645 }
646 else if (!bailing)
647 {
648 bailing = 1;
649 printf("Unable to initialize machine emulation\n");
650 }
651
652 end_resource_tracking();
653 osd_exit();
654 }
655 else if (!bailing)
656 {
657 bailing = 1;
658 printf ("Unable to initialize system\n");
659 }
660
661 end_resource_tracking();
662 return err;
663 }
664
665
666
667 /***************************************************************************
668
669 Initialize the emulated machine (load the roms, initialize the various
670 subsystems...). Returns 0 if successful.
671
672 ***************************************************************************/
673 int init_machine(void)
674 {
675 #ifndef JAPANESE
676 /* LBO 042400 start */
677 if (uistring_init (options.language_file) != 0)
678 {
679 logerror("uisting_init failed\n");
680 goto out;
681 }
682 /* LBO 042400 end */
683 #endif
684
685 if (code_init() != 0)
686 {
687 logerror("code_init failed\n");
688 goto out;
689 }
690
691 memset(&Machine->memory_region, 0, sizeof(Machine->memory_region));
692
693 if (gamedrv->input_ports)
694 {
695 Machine->input_ports = input_port_allocate(gamedrv->input_ports);
696 if (!Machine->input_ports)
697 {
698 logerror("could not allocate Machine->input_ports\n");
699 goto out_code;
700 }
701 Machine->input_ports_default = input_port_allocate(gamedrv->input_ports);
702 if (!Machine->input_ports_default)
703 {
704 logerror("could not allocate Machine->input_ports_default\n");
705 input_port_free(Machine->input_ports);
706 Machine->input_ports = 0;
707 goto out_code;
708 }
709 }
710
711 #ifdef MESS
712 if (!gamedrv->rom)
713 {
714 logerror("Going to load_next tag\n");
715 goto load_next;
716 }
717 #endif
718
719 if (readroms() != 0)
720 {
721 logerror("readroms failed\n");
722 goto out_free;
723 }
724
725 #ifdef MAME32JP
726 #if !defined(CPSMAME) && !defined(NEOMAME) && !defined(TINY_COMPILE)
727 if(!Use60HzVsync()) {
728 if (strcmp(Machine->gamedrv->name, "kof99p") == 0)
729 neogeo_kof99p_patch();
730 else if (strcmp(Machine->gamedrv->name, "garoup") == 0)
731 neogeo_garoup_patch();
732 else if (strcmp(Machine->gamedrv->name, "fightfev") == 0)
733 neogeo_fightfev_patch();
734 }
735 #endif
736 #endif
737
738 #ifdef MESS
739 load_next:
740 if (init_devices(gamedrv))
741 {
742 logerror("init_devices failed\n");
743 goto out_free;
744 }
745 #endif
746
747 /* Mish: Multi-session safety - set spriteram size to zero before memory map is set up */
748 spriteram_size=spriteram_2_size=0;
749
750 /* first init the timers; some CPUs have built-in timers and will need */
751 /* to allocate them up front */
752 timer_init();
753 cpu_init_refresh_timer();
754
755 /* first of all initialize the memory handlers, which could be used by the */
756 /* other initialization routines */
757 cpu_init();
758
759 /* init the hard drives */
760 hard_disk_set_interface(&mame_hard_disk_interface);
761
762 /* load input ports settings (keys, dip switches, and so on) */
763 settingsloaded = load_input_port_settings();
764
765 if( !memory_init() )
766 {
767 logerror("memory_init failed\n");
768 goto out_free;
769 }
770
771 if (gamedrv->driver_init) (*gamedrv->driver_init)();
772
773 return 0;
774
775 out_free:
776 input_port_free(Machine->input_ports);
777 Machine->input_ports = 0;
778 input_port_free(Machine->input_ports_default);
779 Machine->input_ports_default = 0;
780 out_code:
781 code_close();
782 out:
783 return 1;
784 }
785
786
787 void shutdown_machine(void)
788 {
789 int i;
790
791 #ifdef MESS
792 exit_devices();
793 #endif
794
795 /* ASG 971007 free memory element map */
796 memory_shutdown();
797
798 /* free the memory allocated for ROM and RAM */
799 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
800 free_memory_region(i);
801
802 /* close all hard drives */
803 hard_disk_close_all();
804
805 /* reset the CPU system */
806 cpu_exit();
807
808 /* free the memory allocated for input ports definition */
809 input_port_free(Machine->input_ports);
810 Machine->input_ports = 0;
811 input_port_free(Machine->input_ports_default);
812 Machine->input_ports_default = 0;
813
814 code_close();
815
816 #ifndef JAPANESE
817 uistring_shutdown (); /* LBO 042400 */
818 #endif
819 state_save_reset();
820 }
821
822
823
824 static void vh_close(void)
825 {
826 int i;
827
828
829 for (i = 0;i < MAX_GFX_ELEMENTS;i++)
830 {
831 freegfx(Machine->gfx[i]);
832 Machine->gfx[i] = 0;
833 }
834 #ifdef JAPANESE
835 uifont_freefont();
836 #else
837 freegfx(Machine->uifont);
838 Machine->uifont = NULL;
839 #endif
840 if (Machine->debugger_font)
841 {
842 freegfx(Machine->debugger_font);
843 Machine->debugger_font = NULL;
844 }
845 osd_close_display();
846 if (Machine->scrbitmap)
847 {
848 bitmap_free(Machine->scrbitmap);
849 Machine->scrbitmap = NULL;
850 }
851 if (Machine->debug_bitmap)
852 {
853 bitmap_free(Machine->debug_bitmap);
854 Machine->debug_bitmap = NULL;
855 }
856
857 palette_stop();
858 }
859
860
861
862 /* Scale the vector games to a given resolution */
863 static void scale_vectorgames(int gfx_width,int gfx_height,int *width,int *height)
864 {
865 double x_scale, y_scale, scale;
866
867 if (Machine->orientation & ORIENTATION_SWAP_XY)
868 {
869 x_scale=(double)gfx_width/(double)(*height);
870 y_scale=(double)gfx_height/(double)(*width);
871 }
872 else
873 {
874 x_scale=(double)gfx_width/(double)(*width);
875 y_scale=(double)gfx_height/(double)(*height);
876 }
877 if (x_scale<y_scale)
878 scale=x_scale;
879 else
880 scale=y_scale;
881 *width=(int)((double)*width*scale);
882 *height=(int)((double)*height*scale);
883
884 /* Padding to an dword value */
885 *width-=*width % 4;
886 *height-=*height % 4;
887 }
888
889
890 static int vh_open(void)
891 {
892 int i;
893 int bmwidth,bmheight,viswidth,visheight,attr;
894
895
896 for (i = 0;i < MAX_GFX_ELEMENTS;i++) Machine->gfx[i] = 0;
897 Machine->uifont = NULL;
898 Machine->debugger_font = NULL;
899
900 if (palette_start() != 0)
901 {
902 vh_close();
903 return 1;
904 }
905
906
907 /* convert the gfx ROMs into character sets. This is done BEFORE calling the driver's */
908 /* convert_color_prom() routine (in palette_init()) because it might need to check the */
909 /* Machine->gfx[] data */
910 if (Machine->drv->gfxdecodeinfo)
911 {
912 for (i = 0;i < MAX_GFX_ELEMENTS && Machine->drv->gfxdecodeinfo[i].memory_region != -1;i++)
913 {
914 int reglen = 8*memory_region_length(Machine->drv->gfxdecodeinfo[i].memory_region);
915 struct GfxLayout glcopy;
916 int j;
917
918
919 memcpy(&glcopy,Machine->drv->gfxdecodeinfo[i].gfxlayout,sizeof(glcopy));
920
921 if (IS_FRAC(glcopy.total))
922 glcopy.total = reglen / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total);
923 for (j = 0;j < MAX_GFX_PLANES;j++)
924 {
925 if (IS_FRAC(glcopy.planeoffset[j]))
926 {
927 glcopy.planeoffset[j] = FRAC_OFFSET(glcopy.planeoffset[j]) +
928 reglen * FRAC_NUM(glcopy.planeoffset[j]) / FRAC_DEN(glcopy.planeoffset[j]);
929 }
930 }
931 for (j = 0;j < MAX_GFX_SIZE;j++)
932 {
933 if (IS_FRAC(glcopy.xoffset[j]))
934 {
935 glcopy.xoffset[j] = FRAC_OFFSET(glcopy.xoffset[j]) +
936 reglen * FRAC_NUM(glcopy.xoffset[j]) / FRAC_DEN(glcopy.xoffset[j]);
937 }
938 if (IS_FRAC(glcopy.yoffset[j]))
939 {
940 glcopy.yoffset[j] = FRAC_OFFSET(glcopy.yoffset[j]) +
941 reglen * FRAC_NUM(glcopy.yoffset[j]) / FRAC_DEN(glcopy.yoffset[j]);
942 }
943 }
944
945 /* some games increment on partial tile boundaries; to handle this without reading */
946 /* past the end of the region, we may need to truncate the count */
947 /* an example is the games in metro.c */
948 if (glcopy.planeoffset[0] == GFX_RAW)
949 {
950 int region = Machine->drv->gfxdecodeinfo[i].memory_region;
951 UINT8 *base = memory_region(region) + Machine->drv->gfxdecodeinfo[i].start;
952 UINT8 *end = memory_region(region) + memory_region_length(region);
953 while (glcopy.total > 0)
954 {
955 UINT8 *elementbase = base + (glcopy.total - 1) * glcopy.charincrement / 8;
956 UINT8 *lastpixelbase = elementbase + glcopy.height * glcopy.yoffset[0] / 8 - 1;
957 if (lastpixelbase < end)
958 break;
959 glcopy.total--;
960 }
961 }
962
963
964 if ((Machine->gfx[i] = decodegfx(memory_region(Machine->drv->gfxdecodeinfo[i].memory_region)
965 + Machine->drv->gfxdecodeinfo[i].start,
966 &glcopy)) == 0)
967 {
968 vh_close();
969
970 bailing = 1;
971 printf("Out of memory decoding gfx\n");
972
973 return 1;
974 }
975 if (Machine->remapped_colortable)
976 Machine->gfx[i]->colortable = &Machine->remapped_colortable[Machine->drv->gfxdecodeinfo[i].color_codes_start];
977 Machine->gfx[i]->total_colors = Machine->drv->gfxdecodeinfo[i].total_color_codes;
978 }
979 }
980
981
982 bmwidth = Machine->drv->screen_width;
983 bmheight = Machine->drv->screen_height;
984
985 if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
986 scale_vectorgames(options.vector_width,options.vector_height,&bmwidth,&bmheight);
987
988 if (!(Machine->drv->video_attributes & VIDEO_TYPE_VECTOR))
989 {
990 viswidth = Machine->drv->default_visible_area.max_x - Machine->drv->default_visible_area.min_x + 1;
991 visheight = Machine->drv->default_visible_area.max_y - Machine->drv->default_visible_area.min_y + 1;
992 }
993 else
994 {
995 viswidth = bmwidth;
996 visheight = bmheight;
997 }
998
999 if (Machine->orientation & ORIENTATION_SWAP_XY)
1000 {
1001 int temp;
1002 temp = viswidth; viswidth = visheight; visheight = temp;
1003 }
1004
1005 /* take out the hicolor flag if it's not being used */
1006 attr = Machine->drv->video_attributes;
1007 if (Machine->color_depth != 15 && Machine->color_depth != 32)
1008 attr &= ~VIDEO_RGB_DIRECT;
1009
1010 /* create the display bitmap, and allocate the palette */
1011 if (osd_create_display(viswidth,visheight,Machine->color_depth,
1012 Machine->drv->frames_per_second,attr,Machine->orientation))
1013 {
1014 vh_close();
1015 return 1;
1016 }
1017
1018 Machine->scrbitmap = bitmap_alloc_depth(bmwidth,bmheight,Machine->color_depth);
1019 if (!Machine->scrbitmap)
1020 {
1021 vh_close();
1022 return 1;
1023 }
1024
1025 switch_ui_orientation(NULL);
1026 if (mame_debug)
1027 {
1028 Machine->debug_bitmap = bitmap_alloc_depth(options.debug_width,options.debug_height,Machine->color_depth);
1029 if (!Machine->debug_bitmap)
1030 {
1031 vh_close();
1032 return 1;
1033 }
1034 }
1035 switch_true_orientation(NULL);
1036
1037 set_visible_area(
1038 Machine->drv->default_visible_area.min_x,
1039 Machine->drv->default_visible_area.max_x,
1040 Machine->drv->default_visible_area.min_y,
1041 Machine->drv->default_visible_area.max_y);
1042
1043 /* create spriteram buffers if necessary */
1044 if (Machine->drv->video_attributes & VIDEO_BUFFERS_SPRITERAM)
1045 {
1046 if (spriteram_size)
1047 {
1048 buffered_spriteram = auto_malloc(spriteram_size);
1049 if (!buffered_spriteram)
1050 {
1051 vh_close();
1052 return 1;
1053 }
1054
1055 state_save_register_UINT8("generic_video", 0, "buffered_spriteram", buffered_spriteram, spriteram_size);
1056
1057 if (spriteram_2_size)
1058 {
1059 buffered_spriteram_2 = auto_malloc(spriteram_2_size);
1060 if (!buffered_spriteram_2)
1061 {
1062 vh_close();
1063 return 1;
1064 }
1065
1066 state_save_register_UINT8("generic_video", 0, "buffered_spriteram_2", buffered_spriteram_2, spriteram_2_size);
1067 }
1068
1069 buffered_spriteram16 = (data16_t *)buffered_spriteram;
1070 buffered_spriteram32 = (data32_t *)buffered_spriteram;
1071 buffered_spriteram16_2 = (data16_t *)buffered_spriteram_2;
1072 buffered_spriteram32_2 = (data32_t *)buffered_spriteram_2;
1073 }
1074 else
1075 {
1076 logerror("vh_open(): Video buffers spriteram but spriteram_size is 0\n");
1077 }
1078 }
1079
1080 /* build our private user interface font */
1081 /* This must be done AFTER osd_create_display() so the function knows the */
1082 /* resolution we are running at and can pick a different font depending on it. */
1083 /* It must be done BEFORE palette_init() because that will also initialize */
1084 /* (through osd_allocate_colors()) the uifont colortable. */
1085 #ifdef JAPANESE
1086 if (uifont_buildfont() == 0)
1087 #else
1088 if (NULL == (Machine->uifont = builduifont()))
1089 #endif
1090 {
1091 vh_close();
1092 return 1;
1093 }
1094 #ifdef MAME_DEBUG
1095 if (mame_debug)
1096 {
1097 if (NULL == (Machine->debugger_font = build_debugger_font()))
1098 {
1099 vh_close();
1100 return 1;
1101 }
1102 }
1103 #endif
1104
1105 /* initialize the palette - must be done after osd_create_display() */
1106 if (palette_init())
1107 {
1108 vh_close();
1109 return 1;
1110 }
1111
1112 pdrawgfx_shadow_lowpri = 0;
1113
1114 #ifndef MAME32JP
1115 leds_status = 0;
1116 #endif
1117
1118 return 0;
1119 }
1120
1121
1122
1123 /***************************************************************************
1124
1125 This function takes care of refreshing the screen, processing user input,
1126 and throttling the emulation speed to obtain the required frames per second.
1127
1128 ***************************************************************************/
1129
1130 void force_partial_update(int scanline)
1131 {
1132 struct rectangle clip = Machine->visible_area;
1133
1134 /* if skipping this frame, bail */
1135 if (osd_skip_this_frame())
1136 return;
1137
1138 /* skip if less than the lowest so far */
1139 if (scanline < last_partial_scanline)
1140 return;
1141
1142 /* if there's a dirty bitmap and we didn't do any partial updates yet, handle it now */
1143 if (bitmap_dirty && last_partial_scanline == 0)
1144 {
1145 fillbitmap(Machine->scrbitmap, get_black_pen(), NULL);
1146 osd_mark_dirty(Machine->uixmin, Machine->uiymin, Machine->uixmin+Machine->uiwidth-1, Machine->uiymin+Machine->uiheight-1);
1147 bitmap_dirty = 0;
1148 }
1149
1150 /* set the start/end scanlines */
1151 if (last_partial_scanline > clip.min_y)
1152 clip.min_y = last_partial_scanline;
1153 if (scanline < clip.max_y)
1154 clip.max_y = scanline;
1155
1156 /* render if necessary */
1157 if (clip.min_y <= clip.max_y)
1158 {
1159 profiler_mark(PROFILER_VIDEO);
1160 (*Machine->drv->video_update)(Machine->scrbitmap, &clip);
1161 partial_update_count++;
1162 profiler_mark(PROFILER_END);
1163 }
1164
1165 /* remember where we left off */
1166 last_partial_scanline = scanline + 1;
1167 }
1168
1169
1170 void reset_partial_updates(void)
1171 {
1172 last_partial_scanline = 0;
1173 partial_update_count = 0;
1174 }
1175
1176
1177
1178 /*************************************
1179 *
1180 * Called by cpuexec either at the
1181 * start or end of VBLANK
1182 *
1183 *************************************/
1184
1185 int updatescreen(void)
1186 {
1187 /* update sound */
1188 sound_update();
1189 #ifdef MAME32JP
1190 osd_log_wave();
1191 #endif
1192
1193 /* if we're not skipping this frame, draw the screen */
1194 if (osd_skip_this_frame() == 0)
1195 {
1196 profiler_mark(PROFILER_VIDEO);
1197 draw_screen();
1198 profiler_mark(PROFILER_END);
1199 }
1200
1201 /* the user interface must be called between vh_update() and osd_update_video_and_audio(), */
1202 /* to allow it to overlay things on the game display. We must call it even */
1203 /* if the frame is skipped, to keep a consistent timing. */
1204 if (handle_user_interface(real_scrbitmap))
1205 /* quit if the user asked to */
1206 return 1;
1207
1208 /* blit to the screen */
1209 update_video_and_audio();
1210
1211 /* call the end-of-frame callback */
1212 if (Machine->drv->video_eof)
1213 (*Machine->drv->video_eof)();
1214
1215 return 0;
1216 }
1217
1218
1219 /***************************************************************************
1220
1221 Draw screen with overlays and backdrops
1222
1223 ***************************************************************************/
1224
1225 void draw_screen(void)
1226 {
1227 /* finish updating the screen */
1228 force_partial_update(Machine->visible_area.max_y);
1229
1230 /* blend with artwork */
1231 if (artwork_backdrop || artwork_overlay)
1232 artwork_draw(artwork_real_scrbitmap, Machine->scrbitmap, bitmap_dirty);
1233 }
1234
1235 void schedule_full_refresh(void)
1236 {
1237 bitmap_dirty = 1;
1238 }
1239
1240
1241 /***************************************************************************
1242
1243 Calls OSD layer handling overlays and backdrops
1244
1245 ***************************************************************************/
1246 void update_video_and_audio(void)
1247 {
1248 #ifdef MAME_DEBUG
1249 debug_trace_delay = 0;
1250 #endif
1251 #ifdef MAME32JP
1252 osd_update_video_and_audio(real_scrbitmap,Machine->debug_bitmap);
1253 #else
1254 osd_update_video_and_audio(real_scrbitmap,Machine->debug_bitmap,leds_status);
1255 #endif
1256 }
1257
1258
1259 /***************************************************************************
1260
1261 Run the emulation. Start the various subsystems and the CPU emulation.
1262 Returns non zero in case of error.
1263
1264 ***************************************************************************/
1265 int run_machine(void)
1266 {
1267 int res = 1;
1268
1269 /* start the video hardware */
1270 if (vh_open() == 0)
1271 {
1272 tilemap_init();
1273 if (Machine->drv->video_start == 0 || (*Machine->drv->video_start)() == 0) /* start the video hardware */
1274 {
1275 if (sound_start() == 0) /* start the audio hardware */
1276 {
1277 int region;
1278
1279 if (artwork_overlay || artwork_backdrop)
1280 real_scrbitmap = artwork_real_scrbitmap;
1281 else
1282 real_scrbitmap = Machine->scrbitmap;
1283
1284 /* free memory regions allocated with REGIONFLAG_DISPOSE (typically gfx roms) */
1285 for (region = 0; region < MAX_MEMORY_REGIONS; region++)
1286 {
1287 if (Machine->memory_region[region].flags & ROMREGION_DISPOSE)
1288 {
1289 int i;
1290
1291 /* invalidate contents to avoid subtle bugs */
1292 for (i = 0;i < memory_region_length(region);i++)
1293 memory_region(region)[i] = rand();
1294 free(Machine->memory_region[region].base);
1295 Machine->memory_region[region].base = 0;
1296 }
1297 }
1298
1299 if (settingsloaded == 0)
1300 {
1301 /* if there is no saved config, it must be first time we run this game, */
1302 /* so show the disclaimer. */
1303 if (showcopyright(real_scrbitmap)) goto userquit;
1304 }
1305
1306 if (showgamewarnings(real_scrbitmap) == 0) /* show info about incorrect behaviour (wrong colors etc.) */
1307 {
1308 init_user_interface();
1309
1310 /* disable cheat if no roms */
1311 if (!gamedrv->rom) options.cheat = 0;
1312
1313 if (options.cheat) InitCheat();
1314
1315 if (Machine->drv->nvram_handler)
1316 {
1317 void *f;
1318
1319 f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_NVRAM,0);
1320 (*Machine->drv->nvram_handler)(f,0);
1321 if (f) osd_fclose(f);
1322 }
1323 #ifdef MAME32JP
1324 if((inp_use & 0x80000000)) {
1325 if(options.record) {
1326 (*Machine->drv->nvram_handler)(options.record,1);
1327 } else if(options.playback) {
1328 (*Machine->drv->nvram_handler)(options.playback,0);
1329 }
1330 }
1331 #endif
1332 cpu_run(); /* run the emulation! */
1333
1334 if (Machine->drv->nvram_handler)
1335 {
1336 void *f;
1337
1338 if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_NVRAM,1)) != 0)
1339 {
1340 (*Machine->drv->nvram_handler)(f,1);
1341 osd_fclose(f);
1342 }
1343 }
1344
1345 #ifdef MAME32JP
1346 if(inp_use) {
1347 extern void SetUse60HzVsync(int);
1348 SetUse60HzVsync(inp_use >> 3);
1349 inp_use = 0;
1350 }
1351 #endif
1352 if (options.cheat) StopCheat();
1353
1354 /* save input ports settings */
1355 save_input_port_settings();
1356 }
1357
1358 userquit:
1359 /* the following MUST be done after hiscore_save() otherwise */
1360 /* some 68000 games will not work */
1361 sound_stop();
1362 if (Machine->drv->video_stop) (*Machine->drv->video_stop)();
1363 artwork_kill();
1364
1365 res = 0;
1366 }
1367 else if (!bailing)
1368 {
1369 bailing = 1;
1370 printf("Unable to start audio emulation\n");
1371 }
1372 }
1373 else if (!bailing)
1374 {
1375 bailing = 1;
1376 printf("Unable to start video emulation\n");
1377 }
1378
1379 tilemap_close();
1380 vh_close();
1381 }
1382 else if (!bailing)
1383 {
1384 bailing = 1;
1385 printf("Unable to start video emulation\n");
1386 }
1387
1388 return res;
1389 }
1390
1391
1392
1393 int mame_highscore_enabled(void)
1394 {
1395 /* disable high score when record/playback is on */
1396 if (record != 0 || playback != 0) return 0;
1397
1398 /* disable high score when cheats are used */
1399 if (he_did_cheat != 0) return 0;
1400
1401 #ifdef MAME_NET
1402 /* disable high score when playing network game */
1403 /* (this forces all networked machines to start from the same state!) */
1404 if (net_active()) return 0;
1405 #endif /* MAME_NET */
1406
1407 return 1;
1408 }
1409
1410
1411 #ifndef MAME32JP
1412 void set_led_status(int num,int on)
1413 {
1414 if (on) leds_status |= (1 << num);
1415 else leds_status &= ~(1 << num);
1416 }
1417 #endif
1418
1419
1420
1421 /*************************************
1422 *
1423 * Expand a machine driver
1424 *
1425 *************************************/
1426
1427 void expand_machine_driver(void (*constructor)(struct InternalMachineDriver *), struct InternalMachineDriver *output)
1428 {
1429 memset(output, 0, sizeof(*output));
1430
1431 /* if this is tagged in the new format, parse it */
1432 (*constructor)(output);
1433 }
1434
1435
1436
1437 /*************************************
1438 *
1439 * Helper functions for building up
1440 * InternalMachineDrivers
1441 *
1442 *************************************/
1443
1444 struct MachineCPU *machine_add_cpu(struct InternalMachineDriver *machine, const char *tag, int type, int cpuclock)
1445 {
1446 int cpunum;
1447
1448 for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
1449 if (machine->cpu[cpunum].cpu_type == 0)
1450 {
1451 machine->cpu[cpunum].tag = tag;
1452 machine->cpu[cpunum].cpu_type = type;
1453 machine->cpu[cpunum].cpu_clock = cpuclock;
1454 return &machine->cpu[cpunum];
1455 }
1456
1457 logerror("Out of CPU's!\n");
1458 return NULL;
1459 }
1460
1461
1462 struct MachineCPU *machine_find_cpu(struct InternalMachineDriver *machine, const char *tag)
1463 {
1464 int cpunum;
1465
1466 for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
1467 if (machine->cpu[cpunum].tag && strcmp(machine->cpu[cpunum].tag, tag) == 0)
1468 return &machine->cpu[cpunum];
1469
1470 logerror("Can't find CPU '%s'!\n", tag);
1471 return NULL;
1472 }
1473
1474
1475 void machine_remove_cpu(struct InternalMachineDriver *machine, const char *tag)
1476 {
1477 int cpunum;
1478
1479 for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
1480 if (machine->cpu[cpunum].tag == tag)
1481 {
1482 memmove(&machine->cpu[cpunum], &machine->cpu[cpunum + 1], sizeof(machine->cpu[0]) * (MAX_CPU - cpunum - 1));
1483 memset(&machine->cpu[MAX_CPU - 1], 0, sizeof(machine->cpu[0]));
1484 return;
1485 }
1486
1487 logerror("Can't find CPU '%s'!\n", tag);
1488 }
1489
1490
1491 struct MachineSound *machine_add_sound(struct InternalMachineDriver *machine, const char *tag, int type, void *sndintf)
1492 {
1493 int soundnum;
1494
1495 for (soundnum = 0; soundnum < MAX_SOUND; soundnum++)
1496 if (machine->sound[soundnum].sound_type == 0)
1497 {
1498 machine->sound[soundnum].tag = tag;
1499 machine->sound[soundnum].sound_type = type;
1500 machine->sound[soundnum].sound_interface = sndintf;
1501 return &machine->sound[soundnum];
1502 }
1503
1504 logerror("Out of sounds!\n");
1505 return NULL;
1506
1507 }
1508
1509
1510 struct MachineSound *machine_find_sound(struct InternalMachineDriver *machine, const char *tag)
1511 {
1512 int soundnum;
1513
1514 for (soundnum = 0; soundnum < MAX_SOUND; soundnum++)
1515 if (machine->sound[soundnum].tag && strcmp(machine->sound[soundnum].tag, tag) == 0)
1516 return &machine->sound[soundnum];
1517
1518 logerror("Can't find sound '%s'!\n", tag);
1519 return NULL;
1520 }
1521
1522
1523 void machine_remove_sound(struct InternalMachineDriver *machine, const char *tag)
1524 {
1525 int soundnum;
1526
1527 for (soundnum = 0; soundnum < MAX_SOUND; soundnum++)
1528 if (machine->sound[soundnum].tag == tag)
1529 {
1530 memmove(&machine->sound[soundnum], &machine->sound[soundnum + 1], sizeof(machine->sound[0]) * (MAX_SOUND - soundnum - 1));
1531 memset(&machine->sound[MAX_SOUND - 1], 0, sizeof(machine->sound[0]));
1532 return;
1533 }
1534
1535 logerror("Can't find sound '%s'!\n", tag);
1536 }
1537
1538
1539 void *mame_hard_disk_open(const char *filename, const char *mode)
1540 {
1541 /* look for read-only drives first in the ROM path */
1542 if (mode[0] == 'r' && !strchr(mode, '+'))
1543 {
1544 void *file = osd_fopen(Machine->gamedrv->name, filename, OSD_FILETYPE_IMAGE_R, 0);
1545 if (file)
1546 return file;
1547 }
1548
1549 /* look for read/write drives in the diff area */
1550 return osd_fopen(NULL, filename, OSD_FILETYPE_IMAGE_DIFF, 1);
1551 }
1552
1553
1554 void mame_hard_disk_close(void *file)
1555 {
1556 osd_fclose(file);
1557 }
1558
1559
1560 UINT32 mame_hard_disk_read(void *file, UINT64 offset, UINT32 count, void *buffer)
1561 {
1562 osd_fseek(file, offset, SEEK_SET);
1563 return osd_fread(file, buffer, count);
1564 }
1565
1566
1567 UINT32 mame_hard_disk_write(void *file, UINT64 offset, UINT32 count, const void *buffer)
1568 {
1569 osd_fseek(file, offset, SEEK_SET);
1570 return osd_fwrite(file, buffer, count);
1571 }
1572

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26