Mercurial > hg > sidinfo
diff sidinfo.c @ 70:4779bbec2f28
Split some functionality into sidlib.[ch].
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 01 Jan 2016 03:32:42 +0200 |
parents | 6bbe11ae6bf5 |
children | 2b2376f1b0cc |
line wrap: on
line diff
--- a/sidinfo.c Fri Jan 01 03:17:11 2016 +0200 +++ b/sidinfo.c Fri Jan 01 03:32:42 2016 +0200 @@ -1,12 +1,12 @@ /* * SIDInfo - PSID/RSID information displayer - * Written by Matti 'ccr' Hämäläinen + * Written by Matti 'ccr' Hämäläinen <ccr@tnsp.org> * (C) Copyright 2014-2015 Tecnic Software productions (TNSP) */ #include "th_args.h" -#include "th_endian.h" #include "th_string.h" -#include "th_crypto.h" +#include "sidlib.h" + // Some constants #define PSID_MAGIC_LEN 4 @@ -378,233 +378,6 @@ } -typedef struct -{ - char magic[PSID_MAGIC_LEN + 1]; // "PSID" / "RSID" magic identifier - uint16_t - version, // Version number - dataOffset, // Start of actual c64 data in file - loadAddress, // Loading address - initAddress, // Initialization address - playAddress, // Play one frame - nSongs, // Number of subsongs - startSong; // Default starting song - uint32_t speed; // Speed - char sidName[PSID_STR_LEN + 1]; // Descriptive text-fields, ASCIIZ - char sidAuthor[PSID_STR_LEN + 1]; - char sidCopyright[PSID_STR_LEN + 1]; - - // PSIDv2 data - uint16_t flags; // Flags - uint8_t startPage, pageLength; - uint16_t reserved; - - // Extra data - BOOL isRSID; - size_t dataSize; // Total size of data - header - th_md5hash_t hash; // Songlength database hash - -} PSIDHeader; - - -enum -{ - PSF_PLAYER_TYPE = 0x0001, // 0 = built-in, 1 = Compute! SIDPlayer MUS - PSF_PLAYSID_TUNE = 0x0002, // 0 = Real C64-compatible, 1 = PlaySID specific (v2NG) - - PSF_CLOCK_UNKNOWN = 0x0000, // Video standard used (v2NG) - PSF_CLOCK_PAL = 0x0004, - PSF_CLOCK_NTSC = 0x0008, - PSF_CLOCK_ANY = 0x000c, - PSF_CLOCK_MASK = 0x000c, - - PSF_MODEL_UNKNOWN = 0x0000, // SID model (v2NG) - PSF_MODEL_MOS6581 = 0x0010, - PSF_MODEL_MOS8580 = 0x0020, - PSF_MODEL_ANY = 0x0030, - PSF_MODEL_MASK = 0x0030, -}; - - -static void siAppendHash16(th_md5state_t *state, uint16_t data) -{ - uint8_t ib8[2]; - ib8[0] = data & 0xff; - ib8[1] = data >> 8; - th_md5_append(state, (uint8_t *) &ib8, sizeof(ib8)); -} - - -int siReadPSIDFile(FILE *inFile, PSIDHeader *psid) -{ - th_md5state_t state; - uint8_t tmp8, *fileData = NULL; - int index, ret = -1; - size_t read; - BOOL first; - - memset(psid, 0, sizeof(*psid)); - - if ((fileData = (uint8_t *) th_malloc(PSID_BUFFER_SIZE)) == NULL) - { - THERR("Error allocating temporary data buffer of %d bytes.\n", PSID_BUFFER_SIZE); - goto error; - } - - // Read PSID header in - if (!th_fread_str(inFile, (uint8_t *) psid->magic, PSID_MAGIC_LEN) || - !th_fread_be16(inFile, &psid->version) || - !th_fread_be16(inFile, &psid->dataOffset) || - !th_fread_be16(inFile, &psid->loadAddress) || - !th_fread_be16(inFile, &psid->initAddress) || - !th_fread_be16(inFile, &psid->playAddress) || - !th_fread_be16(inFile, &psid->nSongs) || - !th_fread_be16(inFile, &psid->startSong) || - !th_fread_be32(inFile, &psid->speed)) - { - THERR("Could not read PSID/RSID header.\n"); - goto error; - } - - psid->magic[PSID_MAGIC_LEN] = 0; - - if ((psid->magic[0] != 'R' && psid->magic[0] != 'P') || - psid->magic[1] != 'S' || psid->magic[2] != 'I' || psid->magic[3] != 'D' || - psid->version < 1 || psid->version > 3) - { - THERR("Not a supported PSID or RSID file.\n"); - goto error; - } - - psid->isRSID = psid->magic[0] == 'R'; - - if (!th_fread_str(inFile, (uint8_t *)psid->sidName, PSID_STR_LEN) || - !th_fread_str(inFile, (uint8_t *)psid->sidAuthor, PSID_STR_LEN) || - !th_fread_str(inFile, (uint8_t *)psid->sidCopyright, PSID_STR_LEN)) - { - THERR("Error reading SID file header.\n"); - goto error; - } - - psid->sidName[PSID_STR_LEN] = 0; - psid->sidAuthor[PSID_STR_LEN] = 0; - psid->sidCopyright[PSID_STR_LEN] = 0; - - // Check if we need to load PSIDv2NG header ... - if (psid->version >= 2) - { - // Yes, we need to - if (!th_fread_be16(inFile, &psid->flags) || - !th_fread_byte(inFile, &psid->startPage) || - !th_fread_byte(inFile, &psid->pageLength) || - !th_fread_be16(inFile, &psid->reserved)) - { - THERR("Error reading PSID/RSID v2+ extra header data.\n"); - goto error; - } - } - - // Initialize MD5-hash calculation - th_md5_init(&state); - - // Process actual data - psid->dataSize = 0; - first = TRUE; - do - { - read = fread(fileData, sizeof(uint8_t), PSID_BUFFER_SIZE, inFile); - psid->dataSize += read; - - if (first && psid->loadAddress == 0) - { - if (read < 4) - { - THERR("Error reading song data, unexpectedly small file.\n"); - goto error; - } - - // Grab the actual load address - psid->loadAddress = TH_LE16_TO_NATIVE(*(uint16_t *) fileData); - - // Strip load address (2 first bytes) - th_md5_append(&state, &fileData[2], read - 2); - first = FALSE; - } - else - if (read > 0) - { - // Append "as is" - th_md5_append(&state, fileData, read); - } - } while (read > 0 && !feof(inFile)); - - // Append header data to hash - siAppendHash16(&state, psid->initAddress); - siAppendHash16(&state, psid->playAddress); - siAppendHash16(&state, psid->nSongs); - - // Append song speed data to hash - tmp8 = psid->isRSID ? 60 : 0; - for (index = 0; index < psid->nSongs && index < 32; index++) - { - if (psid->isRSID) - tmp8 = 60; - else - tmp8 = (psid->speed & (1 << index)) ? 60 : 0; - - th_md5_append(&state, &tmp8, sizeof(tmp8)); - } - - // Rest of songs (more than 32) - for (index = 32; index < psid->nSongs; index++) - th_md5_append(&state, &tmp8, sizeof(tmp8)); - - // PSIDv2NG specific - if (psid->version >= 2) - { - // REFER TO SIDPLAY HEADERS FOR MORE INFORMATION - tmp8 = (psid->flags >> 2) & 3; - if (tmp8 == 2) - th_md5_append(&state, &tmp8, sizeof(tmp8)); - } - - // Calculate the hash - th_md5_finish(&state, psid->hash); - ret = 0; - -error: - // Free buffer - th_free(fileData); - return ret; -} - - -const char *siGetSIDClockStr(int flags) -{ - switch (flags & PSF_CLOCK_MASK) - { - case PSF_CLOCK_UNKNOWN : return "Unknown"; - case PSF_CLOCK_PAL : return "PAL 50Hz"; - case PSF_CLOCK_NTSC : return "NTSC 60Hz"; - case PSF_CLOCK_ANY : return "PAL / NTSC"; - default : return "?"; - } -} - - -const char *siGetSIDModelStr(int flags) -{ - switch (flags & PSF_MODEL_MASK) - { - case PSF_MODEL_UNKNOWN : return "Unknown"; - case PSF_MODEL_MOS6581 : return "MOS6581"; - case PSF_MODEL_MOS8580 : return "MOS8580"; - case PSF_MODEL_ANY : return "MOS6581 / MOS8580"; - default : return "?"; - } -} - - static void siPrintStrEscapes(FILE *outFile, const char *str) { while (*str) @@ -777,7 +550,7 @@ int main(int argc, char *argv[]) { // Initialize - th_init("SIDInfo", "PSID/RSID information displayer", "0.6.0", NULL, NULL); + th_init("SIDInfo", "PSID/RSID information displayer", "0.6.1", NULL, NULL); th_verbosityLevel = 0; memset(&optFormat, 0, sizeof(optFormat));