1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 /* helper functions for BFM SC4/5 set identification and layout file creation
4 - these are not strictly required by the emulation
5
6 */
7
8 #include "emu.h"
9
10 //#define sc45helperlog printf
11 #define sc45helperlog machine.logerror
12
13 // addrxor used for endianness stuff, mode used for when we have a missing pair half
find_project_string(running_machine & machine,int addrxor,int mode)14 int find_project_string(running_machine &machine, int addrxor, int mode)
15 {
16 // search for the title
17 const int strlength = 14;
18 char title_string[] = "PROJECT NUMBER";
19 uint8_t *src = machine.root_device().memregion( "maincpu" )->base();
20 int size = machine.root_device().memregion( "maincpu" )->bytes();
21
22 int search_start = 0;
23 int search_step = 1;
24
25 if (mode==1)
26 {
27 search_start = 0;
28 search_step = 2;
29 }
30
31 if (mode==2)
32 {
33 search_start = 1;
34 search_step = 2;
35 }
36
37 for (int i=0;i<size-strlength;i++)
38 {
39 // sc45helperlog("%02x", src[i]);
40
41 int j;
42 int found = 1;
43 for (j=search_start;j<strlength;j+=search_step)
44 {
45 uint8_t rom = src[(i+j)^addrxor];
46 uint8_t chr = title_string[j];
47
48 if (rom != chr)
49 {
50 found = 0;
51 break;
52 }
53 }
54
55 if (found!=0)
56 {
57 int end=0;
58 int count = 0;
59 int blankcount = 0;
60 sc45helperlog("ID String @ %08x\n", i);
61
62 if (mode==2)
63 {
64 count = -1;
65 }
66
67 while (!end)
68 {
69 uint8_t rom;
70 int addr;
71 if (mode==0)
72 {
73 addr = (i+count)^addrxor;
74 rom = src[addr];
75 }
76 else if (mode == 1)
77 {
78 addr = (i+count)^addrxor;
79
80 if (addr&1)
81 rom = src[addr];
82 else
83 rom = '_';
84 }
85 else
86 {
87 addr = (i+count)^addrxor;
88
89 if (addr&1)
90 rom = '_';
91 else
92 rom = src[addr];
93 }
94
95
96 //if (rom==0xff)
97 // end = 1;
98 //else
99 {
100 if ((rom>=0x20) && (rom<0x7f))
101 {
102 sc45helperlog("%c", rom);
103 blankcount = 0;
104 }
105 else
106 {
107 blankcount++;
108 if (blankcount<10) sc45helperlog(" ");
109 }
110 }
111
112 count++;
113
114 if (count>=0x100)
115 end = 1;
116 }
117 sc45helperlog("\n");
118
119 return 1;
120 }
121 }
122
123 return 0;
124 }
125
126 // find where the button definitions are in the ROM to make creating input ports easier for games using common test mode code
127 // not ALL games have a comprehensive list, but enough do to make this a worthwile debugging aid.
128
129 struct sc4inputinfo
130 {
131 std::string name;
132 bool used;
133 };
134
135 sc4inputinfo sc4inputs[32][16];
136
compare_input_code(running_machine & machine,int addr)137 bool compare_input_code(running_machine &machine, int addr)
138 {
139 uint16_t *src = (uint16_t*)machine.root_device().memregion( "maincpu" )->base();
140 uint16_t* rom = &src[addr];
141
142
143 if ((rom[0] != 0x48e7) || (rom[1] != 0x3020) || (rom[2] != 0x322f) || (rom[3] != 0x0010) || (rom[4] != 0x227c))
144 return false;
145
146 if ((rom[7] != 0x4242) || (rom[8] != 0x2449) || (rom[9] != 0x3639))
147 return false;
148
149 return true;
150 }
151
find_input_strings(running_machine & machine)152 int find_input_strings(running_machine &machine)
153 {
154 for (int i = 0; i < 32; i++)
155 {
156 for (int j = 0; j < 16; j++)
157 {
158 sc4inputs[i][j].name = string_format("IN%d-%d", i, j);
159 sc4inputs[i][j].used = false;
160 }
161 }
162
163
164 int foundat = -1;
165 uint32_t startblock = 0;
166 uint32_t endblock = 0;
167
168 uint16_t *rom = (uint16_t*)machine.root_device().memregion( "maincpu" )->base();
169 uint8_t *rom8 = machine.root_device().memregion( "maincpu" )->base();
170
171 for (int i=0;i<(0x100000-0x40)/2;i++)
172 {
173 bool found = compare_input_code(machine, i);
174
175 if (found==true)
176 {
177 startblock = (rom[i + 5] << 16) | rom[i + 6];
178 endblock = (rom[i + 10] << 16) | rom[i + 11];
179 sc45helperlog("------------ INPUTS -----------------\n");
180 sc45helperlog("input strings found at %08x (start of ponter block %08x end of pointer block %08x\n", i*2, startblock, endblock);
181 foundat = i;
182
183 if (endblock > startblock)
184 {
185 for (int j = startblock / 2; j < endblock / 2; j+=4)
186 {
187 uint16_t portpos = rom[j + 0];
188 int port = (portpos & 0x1f);
189 int pos = (portpos >> 5);
190
191 uint16_t unk2 = rom[j + 1];
192 uint32_t stringaddr = (rom[j + 2] << 16) | rom[j + 3];
193
194 sc45helperlog("(port %02x position %02x) unk %04x addr %08x ", port,pos, unk2, stringaddr);
195 std::string tempstring;
196
197 for (int k = stringaddr; k < stringaddr + 6; k++)
198 {
199 uint8_t chr = rom8[k^1];
200
201 if ((chr == 0xff) || (chr == 0x00))
202 {
203 k = stringaddr + 6;
204 }
205 else
206 {
207 tempstring.push_back(chr);
208 }
209
210 }
211
212 strtrimspace(tempstring);
213 strmakelower(tempstring);
214
215
216 //if (pos <= 5)
217 {
218 assert(pos >= 0 && pos < ARRAY_LENGTH(sc4inputs[port]));
219 if (sc4inputs[port][pos].used == false)
220 {
221 sc4inputs[port][pos].used = true;
222 sc4inputs[port][pos].name = tempstring;
223 }
224 else
225 {
226 printf("position already used?\n");
227
228 sc4inputs[port][pos].name.append(" OR ");
229 sc4inputs[port][pos].name.append(tempstring);
230 }
231 }
232 //else
233 //{
234 // printf("invalid port position?\n");
235 //}
236
237
238
239 sc45helperlog("%s", tempstring.c_str());
240
241 sc45helperlog("\n");
242
243 }
244 }
245
246 }
247 }
248
249 sc45helperlog("------------ INPUT STRUCTURE -----------------\n");
250
251 // i'm not sure exactly how many ports are valid for inputs, or if different
252 // hardware can also be connected to them, buttons typically map in
253 // ports 1,2, then jump to 8,9, and sometimes 10 (sc4dndys)
254 // some games appear to have mistakes in their tables (sc4dndclc claims the
255 // %age key maps over the dips?)
256 // dips are on the motherboard and the 16 switches appear mapped at 16,17,18,19 split 5-5-5-1 (I'm assuming this can't move)
257 // the green service mode button in port 20 is also on the motherboard (I'm assuming this can't move)
258 //
259 // sometimes an upper bit (0x100) is set for hopper related ports?
260
261 int ignoreports[32][16] =
262 {
263 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
264 { 1, 2, 3, 4, 5, 6, -1, -1, -7, -1, -1, -1, -1, -1, -1, -1, }, // port 1
265 { 7, 8, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 2
266 { -1, -1, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // many of the dutch games map inputs here instead of the stake key(!!)
267 { -1, -9, -1, -10,-8, -1, -1, -1, -6, -1, -1, -1, -1, -1, -1, -1, }, // port 4
268 { -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
269 { -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
270 { 31, 32, 33, 34, 35, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 7 (sc4cfqpse?)
271 { 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 8
272 { 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 9
273 { 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 10
274 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
275 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
276 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
277 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
278 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
279 { -3, -3, -3, -3, -3, -1, -1, -1, -5, -1, -1, -1, -1, -1, -1, -1, }, // port 16
280 { -3, -3, -3, -3, -3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 17
281 { -3, -3, -3, -3, -3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 18
282 { -3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 19
283 { -3, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, // port 20
284 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
285 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
286 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
287 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
288 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
289 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
290 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
291 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
292 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
293 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
294 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }
295 };
296
297 int buttons_used = 1;
298
299 printf("INPUT_PORTS_START( %s ) // this structure is generated\n", machine.system().name);
300 printf(" PORT_INCLUDE( sc4_base )\n");
301
302 for (int i = 0; i < 32; i++)
303 {
304 int thisportused = 0;
305
306 for (int j = 0; j < 16; j++)
307 {
308 if (sc4inputs[i][j].used == true)
309 {
310 if (thisportused == 0)
311 {
312 printf(" PORT_MODIFY(\"IN-%d\")\n", i);
313 thisportused = 1;
314 }
315
316 if (ignoreports[i][j] > 0)
317 {
318 printf(" PORT_BIT( 0x%04x, IP_ACTIVE_HIGH, SC45_BUTTON_MATRIX_%d_%d ) PORT_NAME(\"%s\")\n", 1 << j, i,j/*ignoreports[i][j]*/, sc4inputs[i][j].name.c_str());
319 buttons_used++;
320 }
321 else if (ignoreports[i][j] == -3)
322 {
323 printf(" // 0x%04x - \"%s\" // standard input (motherboard)\n", 1 << j, sc4inputs[i][j].name.c_str());
324 }
325 else if (ignoreports[i][j] == -2)
326 {
327 printf(" // 0x%04x - \"%s\" // standard input (expected here)\n", 1 << j, sc4inputs[i][j].name.c_str());
328 }
329 else if (ignoreports[i][j] == -1)
330 {
331 printf(" // 0x%04x - \"%s\" // unexpected here\n", 1 << j, sc4inputs[i][j].name.c_str());
332 }
333 else if (ignoreports[i][j] == -4)
334 {
335 printf(" // 0x%04x - \"%s\" // known extended input, mapping not understood\n", 1 << j, sc4inputs[i][j].name.c_str());
336 }
337 else if (ignoreports[i][j] == -5)
338 {
339 printf(" // 0x%04x - \"%s\" // known extended input, usually 'top up'\n", 1 << j, sc4inputs[i][j].name.c_str());
340 }
341 else if (ignoreports[i][j] == -6)
342 {
343 printf(" // 0x%04x - \"%s\" // known extended input, usually 'hopper low'\n", 1 << j, sc4inputs[i][j].name.c_str());
344 }
345 else if (ignoreports[i][j] == -7)
346 {
347 printf(" // 0x%04x - \"%s\" // known extended input, usually 'hopper fit'\n", 1 << j, sc4inputs[i][j].name.c_str());
348 }
349 else if (ignoreports[i][j] == -8)
350 {
351 printf(" // 0x%04x - \"%s\" // known extended(?) input, sometimes 'top up'\n", 1 << j, sc4inputs[i][j].name.c_str());
352 }
353 else if (ignoreports[i][j] == -9)
354 {
355 printf(" // 0x%04x - \"%s\" // known extended(?) input, sometimes 'hop hi'\n", 1 << j, sc4inputs[i][j].name.c_str());
356 }
357 else if (ignoreports[i][j] == -10)
358 {
359 printf(" // 0x%04x - \"%s\" // known extended(?) input, sometimes 'hop top'\n", 1 << j, sc4inputs[i][j].name.c_str());
360 }
361 buttons_used++;
362 }
363 }
364 }
365
366 printf("INPUT_PORTS_END\n");
367
368 return foundat;
369 }
370
371 struct lampinfo
372 {
373 std::string lampname;
374 std::string lampname_alt;
375 bool used;
376 int x, y;
377 int width, height;
378 bool draw_label;
379 std::string lamptypename;
380 int clickport;
381 int clickmask;
382 };
383
384 lampinfo lamps[16][16];
385
set_clickable_temp(running_machine & machine,const std::string & teststring,int clickport,int clickmask)386 void set_clickable_temp(running_machine &machine, const std::string &teststring, int clickport, int clickmask)
387 {
388 for (auto & lamp : lamps)
389 {
390 for (int x = 0; x < 16; x++)
391 {
392 if (!strcmp(teststring.c_str(), lamp[x].lampname_alt.c_str()))
393 {
394 lamp[x].clickport = clickport;
395 lamp[x].clickmask = clickmask;
396
397 lamp[x].lamptypename = "buttonlamp";
398 }
399
400 }
401 }
402 }
403
find_lamp_strings(running_machine & machine)404 int find_lamp_strings(running_machine &machine)
405 {
406 int startblock = -1;
407 int endblock = -1;
408
409
410 if (!strcmp(machine.system().name, "sc4dnd"))
411 {
412 // these are for sc4dnd ONLY, need to work out how the code calculates them
413 startblock = 0x1cac0;
414 endblock = 0x1cf9a;
415 }
416 else if (!strcmp(machine.system().name, "sc4dndtp"))
417 {
418 startblock = 0x2175c;
419 endblock = 0x21cb4;
420 }
421 else if (!strcmp(machine.system().name, "sc4dnddw"))
422 {
423 startblock = 0x18a8e;
424 endblock = 0x18fc2;
425 }
426
427 if (startblock == -1)
428 return 0;
429
430
431
432 for (int y = 0; y < 16; y++)
433 {
434 for (int x = 0; x < 16; x++)
435 {
436 char tmp[32];
437
438 sprintf(tmp, "(%02d:%02d)", y, x);
439
440 lamps[y][x].lampname = std::string(tmp);
441 lamps[y][x].used = false;
442 lamps[y][x].y = (y * 28);
443 lamps[y][x].x = 380 + (x * 24);
444 lamps[y][x].draw_label = true;
445 lamps[y][x].width = 23;
446 lamps[y][x].height = 16;
447 lamps[y][x].lamptypename = "unusedlamp";
448 lamps[y][x].clickport = -1;
449 lamps[y][x].clickmask = 0;
450
451 }
452 }
453
454
455
456
457
458
459
460
461 uint16_t *rom = (uint16_t*)machine.root_device().memregion( "maincpu" )->base();
462 uint8_t *rom8 = machine.root_device().memregion( "maincpu" )->base();
463
464 // sc45helperlog("------------ LAMPS -----------------\n");
465
466 if (endblock > startblock)
467 {
468 for (int j = startblock / 2; j < endblock / 2; j+=3)
469 {
470 uint16_t portpos = rom[j + 0];
471 int row = portpos & 0xf;
472 int col = (portpos >> 4 ) & 0xf;
473
474 uint32_t stringaddr = (rom[j + 1] << 16) | rom[j + 2];
475
476 //sc45helperlog("(row %02d, col %02d, unused %02x) addr %08x ", row,col, (portpos&0xff00)>>8, stringaddr);
477
478 std::string tempstring;
479
480 for (int k = stringaddr; k < stringaddr + 10; k++)
481 {
482 uint8_t chr = rom8[k^1];
483
484 if ((chr == 0xff) || (chr == 0x00))
485 {
486 k = stringaddr + 10;
487 }
488 else
489 {
490 tempstring.push_back(chr);
491 }
492
493 }
494
495 if (lamps[row][col].used == false)
496 {
497 lamps[row][col].used = true;
498 lamps[row][col].lampname = tempstring;
499 lamps[row][col].lamptypename = "matrixlamp";
500
501 strtrimspace(lamps[row][col].lampname);
502 strmakelower(lamps[row][col].lampname);
503 }
504 else
505 {
506 fatalerror("duplicate lamp?\n");
507 }
508
509 //sc45helperlog("%s", tempstring.c_str());
510
511 //sc45helperlog("\n");
512
513 }
514 }
515
516 // layout elements for each of the text labels
517 int d = 0;
518 for (auto & lamp : lamps)
519 {
520 //sc45helperlog("---ROW %02d---\n", y);
521 for (int x = 0; x < 16; x++)
522 {
523 sc45helperlog("<element name=\"lamplabelel%d\"><text string=\"%s\"><color red=\"1.0\" green=\"1.0\" blue=\"1.0\" /></text></element>\n", d, lamp[x].lampname.c_str());
524 d++;
525 }
526 }
527
528 sc45helperlog("\n\n");
529 // print out some input text labels for specific rows
530 d = 0;
531 for (int y = 0; y < 7; y++)
532 {
533 int actualrows[] = { 1, 2, 7, 8, 9, 10, 20 };
534 int realy = actualrows[y];
535
536 for (int x = 0; x < 6; x++)
537 {
538 sc45helperlog("<element name=\"inputlabel%d-%d\"><text string=\"%s\"><color red=\"1.0\" green=\"1.0\" blue=\"1.0\" /></text></element>\n", realy,x,sc4inputs[realy][x].name.c_str());
539
540 }
541 }
542 sc45helperlog("\n");
543
544
545
546
547 // some stuff needed by the matrix layout
548 sc45helperlog("<element name=\"matrixlamp\">\n");
549 sc45helperlog("<rect state =\"0\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.7\" green=\"0.7\" blue=\"0.7\" /></rect>\n");
550 sc45helperlog("<rect state =\"1\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.0\" green=\"0.0\" blue=\"1.0\" /></rect>\n");
551 sc45helperlog("<rect state =\"2\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.0\" green=\"1.0\" blue=\"0.0\" /></rect>\n");
552 sc45helperlog("</element>\n");
553 sc45helperlog("<element name=\"unusedlamp\">\n");
554 sc45helperlog("<rect state =\"0\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.2\" green=\"0.2\" blue=\"0.2\" /></rect>\n");
555 sc45helperlog("<rect state =\"1\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.0\" green=\"0.0\" blue=\"0.5\" /></rect>\n");
556 sc45helperlog("<rect state =\"2\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.0\" green=\"0.5\" blue=\"0.0\" /></rect>\n");
557 sc45helperlog("</element>\n");
558 sc45helperlog("<element name=\"reellamp\">\n");
559 sc45helperlog("<rect state =\"0\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.1\" green=\"0.1\" blue=\"0.1\" /></rect>\n");
560 sc45helperlog("<rect state =\"1\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.6\" green=\"0.6\" blue=\"0.6\" /></rect>\n");
561 sc45helperlog("<rect state =\"2\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.6\" green=\"0.6\" blue=\"0.6\" /></rect>\n");
562 sc45helperlog("</element>\n");
563 sc45helperlog("<element name=\"buttonlamp\">\n");
564 sc45helperlog("<rect state =\"0\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.6\" green=\"0.7\" blue=\"0.6\" /></rect>\n");
565 sc45helperlog("<rect state =\"1\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.0\" green=\"1.0\" blue=\"0.0\" /></rect>\n");
566 sc45helperlog("<rect state =\"2\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.0\" green=\"0.0\" blue=\"1.0\" /></rect>\n");
567 sc45helperlog("</element>\n");
568 sc45helperlog("<element name=\"button\">\n");
569 sc45helperlog("<rect state =\"0\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.2\" green=\"0.8\" blue=\"0.2\" /></rect>\n");
570 sc45helperlog("<rect state =\"1\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.2\" green=\"0.9\" blue=\"0.2\" /></rect>\n");
571 sc45helperlog("<rect state =\"2\"><bounds x=\"0\" y=\"0\" width=\"7\" height=\"7\" /><color red=\"0.2\" green=\"1.0\" blue=\"0.2\" /></rect>\n");
572 sc45helperlog("</element>\n");
573 sc45helperlog("<element name=\"vfd0\">\n");
574 sc45helperlog("<led14segsc><color red=\"0\" green=\"0.6\" blue=\"1.0\" /></led14segsc>\n");
575 sc45helperlog("</element>\n");
576 sc45helperlog("<element name=\"digit\" defstate=\"10\">\n");
577 sc45helperlog("<led7seg><color red=\"1.0\" green=\"0.3\" blue=\"0.0\" /></led7seg>\n");
578 sc45helperlog("</element>\n");
579 sc45helperlog("<element name=\"Steppers\" defstate=\"0\">\n");
580 sc45helperlog("<simplecounter maxstate=\"999\" digits=\"3\"><color red=\"1.0\" green=\"1.0\" blue=\"1.0\" /><bounds x=\"0\" y=\"0\" width=\"1\" height=\"1\" /></simplecounter>\n");
581 sc45helperlog("</element>\n");
582 sc45helperlog("\n\n");
583
584
585 sc45helperlog("<view name=\"AWP Simulated Video (No Artwork)\">\n");
586
587 // copy the button strings so we can modify some for easier comparisons
588 d = 0;
589 for (auto & lamp : lamps)
590 {
591 for (int x = 0; x < 16; x++)
592 {
593 lamp[x].lampname_alt = lamp[x].lampname;
594
595 if (!strcmp(lamp[x].lampname_alt.c_str(), "hold2/hi")) lamp[x].lampname_alt = "hold2";
596 if (!strcmp(lamp[x].lampname_alt.c_str(), "hold3/lo")) lamp[x].lampname_alt = "hold3";
597 if (!strcmp(lamp[x].lampname_alt.c_str(), "chg stake")) lamp[x].lampname_alt = "chnge stk";
598 if (!strcmp(lamp[x].lampname_alt.c_str(), "canc/coll")) lamp[x].lampname_alt = "cancel";
599 if (!strcmp(lamp[x].lampname_alt.c_str(), "start")) lamp[x].lampname_alt = "strt exch";
600
601 }
602 }
603
604
605 // try to find some specific named elements and move them around
606 d = 0;
607
608 for (int reel = 0; reel < 8; reel++)
609 {
610 char tempname[32];
611 sprintf(tempname, "reel%d ", reel+1);
612
613
614 for (int pos = 0; pos < 3; pos++)
615 {
616 char tempname2[64];
617
618 if (pos == 0) snprintf(tempname2, ARRAY_LENGTH(tempname2), "%stop", tempname);
619 if (pos == 1) snprintf(tempname2, ARRAY_LENGTH(tempname2), "%smid", tempname);
620 if (pos == 2) snprintf(tempname2, ARRAY_LENGTH(tempname2), "%sbot", tempname);
621
622
623 for (auto & lamp : lamps)
624 {
625 for (int x = 0; x < 16; x++)
626 {
627 if (!strcmp(tempname2, lamp[x].lampname_alt.c_str()))
628 {
629 //sc45helperlog("%s found\n", tempname2);
630 lamp[x].draw_label = false;
631
632 lamp[x].x = 0 + (50 * reel);
633 lamp[x].y = 300 + (17 * pos);
634 lamp[x].width = 50;
635 lamp[x].height = 17;
636 lamp[x].lamptypename = "reellamp";
637
638
639 }
640 else
641 {
642 //printf("%s:%s:\n", tempname2, lamps[y][x].lampname_alt.c_str());
643 }
644
645 }
646 }
647 }
648 }
649
650 // todo, find these by cross-referencing button names and lamp names instead
651 {
652 set_clickable_temp(machine, "cancel", 1, 0x01);
653 set_clickable_temp(machine, "hold1", 1, 0x02);
654 set_clickable_temp(machine, "hold2", 1, 0x04);
655 set_clickable_temp(machine, "hold3", 1, 0x08);
656 set_clickable_temp(machine, "hold4", 1, 0x10);
657
658 set_clickable_temp(machine, "chnge stk", 2, 0x01);
659 set_clickable_temp(machine, "collect", 2, 0x02);
660 set_clickable_temp(machine, "transfer", 2, 0x04);
661
662 set_clickable_temp(machine, "strt exch", 2, 0x10);
663
664 set_clickable_temp(machine, "nodeal", 8, 0x01);
665 set_clickable_temp(machine, "deal", 8, 0x02);
666 set_clickable_temp(machine, "cash bust", 8, 0x04);
667
668 // no 'refill' lamp?
669
670
671 }
672
673
674 // dump out basic matrix stuff in layout format
675 d = 0;
676 for (auto & lamp : lamps)
677 {
678 //sc45helperlog("---ROW %02d---\n", y);
679 for (int x = 0; x < 16; x++)
680 {
681 if (lamp[x].clickport== -1) sc45helperlog("<bezel name=\"lamp%d\" element=\"%s\" state=\"0\"><bounds x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"/></bezel>\n", d, lamp[x].lamptypename.c_str(), lamp[x].x, lamp[x].y, lamp[x].width, lamp[x].height);
682 else sc45helperlog("<bezel name=\"lamp%d\" element=\"%s\" state=\"0\" inputtag=\"IN-%d\" inputmask=\"0x%02x\"><bounds x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" /></bezel>\n", d, lamp[x].lamptypename.c_str(), lamp[x].clickport, lamp[x].clickmask, lamp[x].x, lamp[x].y, lamp[x].width, lamp[x].height);
683
684 if (lamp[x].draw_label == false) sc45helperlog("<!-- Label not drawn\n");
685 sc45helperlog("<bezel name=\"lamplabel%d\" element=\"lamplabelel%d\"><bounds x=\"%d\" y=\"%d\" width=\"%d\" height=\"10\" /></bezel>\n", d,d, lamp[x].x, lamp[x].y-10, lamp[x].width);
686 if (lamp[x].draw_label == false) sc45helperlog("-->\n");
687
688 d++;
689 }
690 }
691
692 // print out a simple matrix of some of the most common inputs,
693 d = 0;
694 for (int y = 0; y < 7; y++)
695 {
696 int actualrows[] = { 1, 2, 7, 8, 9, 10, 20 };
697 int realy = actualrows[y];
698
699 for (int x = 0; x < 6; x++)
700 {
701 sc45helperlog("<bezel name=\"input%d-%d\" element=\"button\" state=\"0\" inputtag=\"IN-%d\" inputmask=\"0x%02x\"><bounds x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" /></bezel>\n", realy,x, realy, 1<<x, 180+x*20, 0+y*20, 19, 10);
702
703 sc45helperlog("<bezel name=\"inputlab%d-%d\" element=\"inputlabel%d-%d\"><bounds x=\"%d\" y=\"%d\" width=\"%d\" height=\"10\" /></bezel>\n", realy,x,realy,x, 180+x*20, 0+(y*20)-10, 19);
704
705 d++;
706 }
707 }
708
709 sc45helperlog("\n");
710
711 // other layout debug stuff
712 d = 0;
713 int extrax = 0;
714 for (int x = 0; x < 32; x++)
715 {
716 if (x % 5 == 0) extrax += 4;
717
718 for (int y = 0; y < 8; y++)
719 {
720 sc45helperlog("<bezel name=\"matrix%d\" element=\"matrixlamp\" state=\"0\"><bounds x=\"%d\" y=\"%d\" width=\"3\" height=\"3\" /></bezel>\n", d, (x*4)+extrax, 40+y*4);
721 d++;
722 }
723 }
724
725 sc45helperlog("\n");
726
727 d = 0;
728 for (int x = 0; x < 16; x++)
729 {
730 for (int y = 0; y < 2; y++)
731 {
732 sc45helperlog("<bezel name=\"digit%d\" element=\"digit\" state=\"0\"><bounds x=\"%d\" y=\"%d\" width=\"9\" height=\"19\"/></bezel>\n", d, (15*10)- (x * 10), 80+(y * 20));
733 d++;
734 }
735 }
736
737 sc45helperlog("\n");
738
739 d = 0;
740 for (int x = 0; x < 16; x++)
741 {
742 int y = 10;
743
744 sc45helperlog("<bezel name=\"vfd%d\" element=\"vfd0\" state=\"0\"><bounds x=\"%d\" y=\"%d\" width=\"9\" height=\"17\"/></bezel>\n", d, 0 + (x * 10), y);
745 d++;
746 }
747
748 {
749 // write reel stuff to layouts
750 // sc4dnd specific..
751 int num_normal_reels = 4;
752 int num_special_reels = 2;
753 int current_reel = 0;
754
755 for (int i = 0; i < num_normal_reels + num_special_reels; i++)
756 {
757 int x = i * 50;
758 int y = 300;
759 sc45helperlog("<bezel name=\"reel%d\" element=\"Steppers\" state=\"0\"><bounds x=\"%d\" y=\"%d\" width=\"10\" height=\"5\" /></bezel>\n", current_reel+1, x+40, y+50);
760 sc45helperlog("<bezel name=\"sreel%d\" element=\"SteppersReel%d\" state=\"0\"><bounds x=\"%d\" y=\"%d\" width=\"50\" height=\"50\" /></bezel>\n", current_reel+1, current_reel+1, x, y);
761
762 current_reel++;
763
764 }
765
766
767 }
768
769
770
771 sc45helperlog("</view>\n");
772 sc45helperlog("</mamelayout>\n");
773
774
775 return 0;
776 }
777
778
find_reel_strings(running_machine & machine)779 int find_reel_strings(running_machine &machine)
780 {
781 int startblock = -1;
782 int endblock = -1;
783
784 std::vector<int> reelsizes;
785
786 // these are for sc4dnd ONLY, need to work out how the code calculates them
787
788 // this list is 4 * 16 symbols for the regular reels, 12 symbols for the number spin, and 2 groups of 16 depending on jackpot/stake keys used for the prize reel
789 // code that points at these is likely to be complex because it's conditional on the game code / mode..
790 if (!strcmp(machine.system().name, "sc4dnd"))
791 {
792 reelsizes.push_back(16);
793 reelsizes.push_back(16);
794 reelsizes.push_back(16);
795 reelsizes.push_back(16);
796 reelsizes.push_back(12);
797 reelsizes.push_back(16);
798 reelsizes.push_back(16);
799
800 startblock = 0x8d74c;
801 }
802 else if (!strcmp(machine.system().name, "sc4dndtp"))
803 {
804 reelsizes.push_back(16);
805 reelsizes.push_back(16);
806 reelsizes.push_back(16);
807 reelsizes.push_back(12);
808 reelsizes.push_back(16);
809 reelsizes.push_back(16);
810 reelsizes.push_back(16);
811
812 startblock = 0x9d252;
813 }
814 else if (!strcmp(machine.system().name, "sc4dnddw"))
815 {
816 reelsizes.push_back(16);
817 reelsizes.push_back(16);
818 reelsizes.push_back(16);
819 reelsizes.push_back(12);
820 reelsizes.push_back(20);
821 reelsizes.push_back(20);
822 reelsizes.push_back(20);
823
824 startblock = 0x9b8c8;
825 }
826
827
828 int total_reel_symbols = 0;
829
830 for (auto & reelsize : reelsizes)
831 {
832 total_reel_symbols += reelsize;
833 }
834
835 endblock = startblock + 4 * (total_reel_symbols);
836
837
838
839 if (startblock == -1)
840 return 0;
841
842
843
844
845
846 uint16_t *rom = (uint16_t*)machine.root_device().memregion( "maincpu" )->base();
847 uint8_t *rom8 = machine.root_device().memregion( "maincpu" )->base();
848
849
850
851 sc45helperlog("------------ LAYOUT -----------------\n");
852
853 sc45helperlog("<?xml version=\"1.0\"?>\n");
854 sc45helperlog("<mamelayout version=\"2\">\n");
855
856 if (endblock > startblock)
857 {
858 int which_reel = 0;
859 int current_symbols = 0;
860
861
862
863 for (int j = startblock / 2; j < endblock / 2; j+=2)
864 {
865 if (current_symbols == 0)
866 {
867 int shifted = ((0x10000 / 16) * 11 ) + 692;
868 // sc45helperlog("REEL %d\n", which_reel+1);
869 sc45helperlog("<element name=\"SteppersReel%d\" defstate=\"0\">\n", which_reel+1);
870 sc45helperlog("<reel stateoffset=\"%d\" symbollist=\"", shifted);
871 }
872
873 uint32_t stringaddr = (rom[j + 0] << 16) | rom[j + 1];
874 stringaddr &= 0xfffff;
875
876 if (stringaddr >= (0x10000 - 16))
877 continue;
878
879 //sc45helperlog("addr %08x ", stringaddr);
880
881 std::string tempstring;
882
883 for (int k = stringaddr; k < stringaddr + 10; k++)
884 {
885 uint8_t chr = rom8[k^1];
886
887 if ((chr == 0xff) || (chr == 0x00))
888 {
889 k = stringaddr + 10;
890 }
891 else
892 {
893 tempstring.push_back(chr);
894 }
895
896 }
897
898 strtrimspace(tempstring);
899 strmakelower(tempstring);
900
901 if (tempstring[0] == '!')
902 {
903 strdelchr(tempstring,'!');
904 tempstring.append("PND");
905 }
906
907 sc45helperlog("%s", tempstring.c_str());
908
909
910
911 //sc45helperlog("\n");
912
913 current_symbols++;
914 if (current_symbols == reelsizes[which_reel])
915 {
916 sc45helperlog("\"><color red=\"1.0\" green=\"1.0\" blue=\"1.0\" /><bounds x=\"0\" y=\"0\" width=\"1\" height=\"1\" /></reel>\n");
917 sc45helperlog("</element>\n");
918
919 current_symbols = 0;
920 which_reel++;
921 }
922 else
923 {
924 sc45helperlog(",");
925 }
926
927
928 }
929 }
930
931 return 0;
932 }
933
934
bfm_sc45_layout_helper(running_machine & machine)935 void bfm_sc45_layout_helper(running_machine &machine)
936 {
937 find_input_strings(machine);
938 find_reel_strings(machine);
939 find_lamp_strings(machine);
940 }
941