Mercurial > hg > sidinfo
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); |