comparison sidinfo.c @ 55:54b48086a1d0

Begin slight refactoring of how output is done.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 26 Dec 2015 19:37:04 +0200
parents d989cf142f8c
children d2148880c71e
comparison
equal deleted inserted replaced
54:c4b4acee5efa 55:54b48086a1d0
52 } PSFOption; 52 } PSFOption;
53 53
54 54
55 static const PSFOption optPSFlags[] = 55 static const PSFOption optPSFlags[] =
56 { 56 {
57 { SIF_FILENAME , "Filename" , NULL },
57 { SIF_TYPE , "Type" , NULL }, 58 { SIF_TYPE , "Type" , NULL },
58 { SIF_VERSION , "Version" , NULL }, 59 { SIF_VERSION , "Version" , NULL },
60 { SIF_PLAYER_TYPE , "PlayerType" , "Player type" },
61 { SIF_PLAYSID_TUNE , "PlayerCompat", "Player compatibility" },
62 { SIF_VIDEO_CLOCK , "VideoClock" , "Video clock speed" },
63 { SIF_SID_MODEL , "SIDModel" , "SID model" },
64
59 { SIF_DATA_OFFS , "DataOffs" , "Data offset" }, 65 { SIF_DATA_OFFS , "DataOffs" , "Data offset" },
60 { SIF_DATA_SIZE , "DataSize" , "Data size" }, 66 { SIF_DATA_SIZE , "DataSize" , "Data size" },
61 { SIF_LOAD_ADDR , "LoadAddr" , "Load address" }, 67 { SIF_LOAD_ADDR , "LoadAddr" , "Load address" },
62 { SIF_INIT_ADDR , "InitAddr" , "Init address" }, 68 { SIF_INIT_ADDR , "InitAddr" , "Init address" },
63 { SIF_PLAY_ADDR , "PlayAddr" , "Play address" }, 69 { SIF_PLAY_ADDR , "PlayAddr" , "Play address" },
65 { SIF_START_SONG , "StartSong" , "Start song" }, 71 { SIF_START_SONG , "StartSong" , "Start song" },
66 { SIF_SID_NAME , "Name" , NULL }, 72 { SIF_SID_NAME , "Name" , NULL },
67 { SIF_SID_AUTHOR , "Author" , NULL }, 73 { SIF_SID_AUTHOR , "Author" , NULL },
68 { SIF_SID_COPYRIGHT , "Copyright" , NULL }, 74 { SIF_SID_COPYRIGHT , "Copyright" , NULL },
69 { SIF_HASH , "Hash" , NULL }, 75 { SIF_HASH , "Hash" , NULL },
70 { SIF_FILENAME , "Filename" , NULL },
71
72 { SIF_PLAYER_TYPE , "PlayerType" , "Player type" },
73 { SIF_PLAYSID_TUNE , "PlayerCompat", "Player compatibility" },
74 { SIF_VIDEO_CLOCK , "VideoClock" , "Video clock speed" },
75 { SIF_SID_MODEL , "SIDModel" , "SID model" },
76 76
77 { SIF_ALL , "All" , NULL }, 77 { SIF_ALL , "All" , NULL },
78 }; 78 };
79 79
80 static const int noptPSFlags = sizeof(optPSFlags) / sizeof(optPSFlags[0]); 80 static const int noptPSFlags = sizeof(optPSFlags) / sizeof(optPSFlags[0]);
83 // Option variables 83 // Option variables
84 BOOL optParsable = FALSE, 84 BOOL optParsable = FALSE,
85 optNoNamePrefix = FALSE, 85 optNoNamePrefix = FALSE,
86 optHexadecimal = FALSE, 86 optHexadecimal = FALSE,
87 optOneLine = FALSE; 87 optOneLine = FALSE;
88 char * optFieldSep = NULL; 88 char *optFieldSep = NULL;
89 uint32_t optFields = SIF_ALL; 89 uint32_t optFields = SIF_ALL;
90 int optNFiles = 0; 90 int optNFiles = 0;
91 91
92 92
93 // Define option arguments 93 // Define option arguments
163 // Match field name 163 // Match field name
164 int found = argMatchPSField(opt); 164 int found = argMatchPSField(opt);
165 switch (found) 165 switch (found)
166 { 166 {
167 case -1: 167 case -1:
168 THERR("No such flag '%s'.\n", opt); 168 THERR("No such field '%s'.\n", opt);
169 return FALSE; 169 return FALSE;
170 170
171 case -2: 171 case -2:
172 THERR("Flag '%s' is ambiguous.\n", opt); 172 THERR("Field '%s' is ambiguous.\n", opt);
173 return FALSE; 173 return FALSE;
174 174
175 default: 175 default:
176 *fields |= optPSFlags[found].flag; 176 *fields |= optPSFlags[found].flag;
177 return TRUE; 177 return TRUE;
437 th_free(fileData); 437 th_free(fileData);
438 return ret; 438 return ret;
439 } 439 }
440 440
441 441
442 const char *siGetSIDClockStr(int flags)
443 {
444 switch (flags & PSF_CLOCK_MASK)
445 {
446 case PSF_CLOCK_UNKNOWN : return "Unknown";
447 case PSF_CLOCK_PAL : return "PAL 50Hz";
448 case PSF_CLOCK_NTSC : return "NTSC 60Hz";
449 case PSF_CLOCK_ANY : return "PAL / NTSC";
450 default : return "?";
451 }
452 }
453
454
455 const char *siGetSIDModelStr(int flags)
456 {
457 switch (flags & PSF_MODEL_MASK)
458 {
459 case PSF_MODEL_UNKNOWN : return "Unknown";
460 case PSF_MODEL_MOS6581 : return "MOS6581";
461 case PSF_MODEL_MOS8580 : return "MOS8580";
462 case PSF_MODEL_ANY : return "MOS6581 / MOS8580";
463 default : return "?";
464 }
465 }
466
467
442 static void siPrintFieldPrefix(FILE *outFile, const char *name) 468 static void siPrintFieldPrefix(FILE *outFile, const char *name)
443 { 469 {
444 if (!optNoNamePrefix) 470 if (!optNoNamePrefix)
445 fprintf(outFile, optParsable ? "%s=" : "%-20s : ", name); 471 fprintf(outFile, optParsable ? "%s=" : "%-20s : ", name);
446 } 472 }
474 siPrintFieldSeparator(outFile); 500 siPrintFieldSeparator(outFile);
475 *shown = TRUE; 501 *shown = TRUE;
476 } 502 }
477 } 503 }
478 504
479 #define PR(xindex, xfmt, xaltfmt, ...) siPrintPSIDInfoLine(outFile, &shown, xindex, xfmt, xaltfmt, __VA_ARGS__ ) 505 #define PR(xfmt, xaltfmt, ...) siPrintPSIDInfoLine(outFile, shown, xindex, xfmt, xaltfmt, __VA_ARGS__ )
480 506
481 507 void siPrintPSIDInformationField(FILE *outFile, const char *filename, const PSIDHeader *psid, BOOL *shown, const int xindex)
482 void siPrintPSIDInformation(FILE *outFile, const char *filename, const PSIDHeader *psid) 508 {
483 { 509 switch (xindex)
510 {
511 case 0: PR("%s", NULL, filename); break;
512 case 1: PR("%s", NULL, psid->magic); break;
513 case 2: PR("%d.%d", NULL, (psid->version & 0xff), (psid->version >> 8)); break;
514 case 3: PR("%s", NULL, (psid->flags & PSF_PLAYER_TYPE) ? "Compute! SIDPlayer MUS" : "Normal built-in"); break;
515 case 4:
516 if (psid->version >= 2)
517 PR("%s", NULL, (psid->flags & PSF_PLAYSID_TUNE) ? "PlaySID" : "C64 compatible");
518 break;
519 case 5:
520 if (psid->version >= 2)
521 PR("%s", NULL, siGetSIDClockStr(psid->flags));
522 break;
523 case 6:
524 if (psid->version >= 2)
525 PR("%s", NULL, siGetSIDModelStr(psid->flags));
526 break;
527
528 case 7: PR("%d", "$%08x", psid->dataOffset); break;
529 case 8: PR("%d", "$%08x", psid->dataSize); break;
530 case 9: PR("%d", "$%04x", psid->loadAddress); break;
531 case 10: PR("%d", "$%04x", psid->initAddress); break;
532 case 11: PR("%d", "$%04x", psid->playAddress); break;
533 case 12: PR("%d", "$%04x", psid->nSongs); break;
534 case 13: PR("%d", "$%04x", psid->startSong); break;
535 case 14: PR("%s", NULL, psid->sidName); break;
536 case 15: PR("%s", NULL, psid->sidAuthor); break;
537 case 16: PR("%s", NULL, psid->sidCopyright); break;
538
539 case 17:
540 {
541 const PSFOption *opt = &optPSFlags[xindex];
542 if (optFormatStack || (optFields & opt->flag))
543 {
544 siPrintFieldPrefix(outFile, "Hash");
545 th_md5_print(outFile, psid->hash);
546 siPrintFieldSeparator(outFile);
547 }
548 }
549 break;
550 }
551 }
552
553
554 BOOL argHandleFile(char *filename)
555 {
556 static PSIDHeader psid;
557 FILE *inFile = NULL, *outFile;
558 int index;
484 BOOL shown = FALSE; 559 BOOL shown = FALSE;
485 560
486 PR(13, "%s", NULL, filename);
487
488 PR( 0, "%s", NULL, psid->magic);
489 PR( 1, "%d.%d", NULL, (psid->version & 0xff), (psid->version >> 8));
490 PR(14, "%s", NULL, (psid->flags & PSF_PLAYER_TYPE) ? "Compute! SIDPlayer MUS" : "Normal built-in");
491 if (psid->version >= 2)
492 {
493 char *str;
494 PR(15, "%s", NULL, (psid->flags & PSF_PLAYSID_TUNE) ? "PlaySID" : "C64 compatible");
495
496 switch (psid->flags & PSF_CLOCK_MASK)
497 {
498 case PSF_CLOCK_UNKNOWN : str = "Unknown"; break;
499 case PSF_CLOCK_PAL : str = "PAL 50Hz"; break;
500 case PSF_CLOCK_NTSC : str = "NTSC 60Hz"; break;
501 case PSF_CLOCK_ANY : str = "PAL / NTSC"; break;
502 default : str = "?"; break;
503 }
504 PR(16, "%s", NULL, str);
505
506 switch (psid->flags & PSF_MODEL_MASK)
507 {
508 case PSF_MODEL_UNKNOWN : str = "Unknown"; break;
509 case PSF_MODEL_MOS6581 : str = "MOS6581"; break;
510 case PSF_MODEL_MOS8580 : str = "MOS8580"; break;
511 case PSF_MODEL_ANY : str = "MOS6581 / MOS8580"; break;
512 default : str = "?"; break;
513 }
514 PR(17, "%s", NULL, str);
515 }
516
517 PR( 2, "%d", "$%08x", psid->dataOffset);
518 PR( 3, "%d", "$%08x", psid->dataSize);
519 PR( 4, "%d", "$%04x", psid->loadAddress);
520 PR( 5, "%d", "$%04x", psid->initAddress);
521 PR( 6, "%d", "$%04x", psid->playAddress);
522 PR( 7, "%d", "$%04x", psid->nSongs);
523 PR( 8, "%d", "$%04x", psid->startSong);
524
525 PR( 9, "%s", NULL, psid->sidName);
526 PR(10, "%s", NULL, psid->sidAuthor);
527 PR(11, "%s", NULL, psid->sidCopyright);
528
529 if (optFields & SIF_HASH)
530 {
531 siPrintFieldPrefix(outFile, "Hash");
532 th_md5_print(outFile, psid->hash);
533 siPrintFieldSeparator(outFile);
534 }
535
536 if (shown && optOneLine)
537 fprintf(outFile, "\n");
538 }
539
540
541 BOOL argHandleFile(char *filename)
542 {
543 static PSIDHeader psid;
544 static FILE *inFile = NULL;
545 optNFiles++; 561 optNFiles++;
562 outFile = stdout;
546 563
547 if ((inFile = fopen(filename, "rb")) == NULL) 564 if ((inFile = fopen(filename, "rb")) == NULL)
548 { 565 {
549 THERR("Could not open file '%s'.\n", filename); 566 THERR("Could not open file '%s'.\n", filename);
550 return TRUE; 567 return TRUE;
556 THERR("Error reading %s\n", filename); 573 THERR("Error reading %s\n", filename);
557 goto error; 574 goto error;
558 } 575 }
559 576
560 // Output 577 // Output
561 siPrintPSIDInformation(stdout, filename, &psid); 578 {
579 for (index = 0; index < noptPSFlags - 1; index++)
580 siPrintPSIDInformationField(outFile, filename, &psid, &shown, index);
581 if (shown && optOneLine)
582 fprintf(outFile, "\n");
583 }
562 584
563 // Shutdown 585 // Shutdown
564 error: 586 error:
565 if (inFile != NULL) 587 if (inFile != NULL)
566 fclose(inFile); 588 fclose(inFile);