/* read 32-bit integer from file. * Returns 1 if error occurs */ static int read_word32(VFSFile *fp, int32_t *p) { int c; if ((c = vfs_getc(fp)) == EOF) { perror("libayemu: read_word32()"); return 1; } *p = c; if ((c = vfs_getc(fp)) == EOF) { perror("libayemu: read_word32()"); return 1; } *p += c << 8; if ((c = vfs_getc(fp)) == EOF) { perror("libayemu: read_word32()"); return 1; } *p += c << 16; if ((c = vfs_getc(fp)) == EOF) { perror("libayemu: read_word32()"); return 1; } *p += c << 24; return 0; }
/* Read 8-bit integer from file. * Return 1 if error occurs */ static int read_byte(VFSFile *fp, int *p) { int c; if ((c = vfs_getc(fp)) == EOF) { perror("libayemu: read_byte()"); return 1; } *p = c; return 0; }
/* read_NTstring: reads null-terminated string from file. * Return 1 if error occures. */ static int read_NTstring(VFSFile *fp, char s[]) { int i, c; for (i = 0 ; i < AYEMU_VTX_NTSTRING_MAX && (c = vfs_getc(fp)) != EOF && c ; i++) s[i] = c; s[i] = '\0'; if (c == EOF) { fprintf(stderr, "libayemu: read_NTstring(): uninspected end of file!\n"); return 1; } return 0; }
/** Read and encode lha data from .vtx file * * Return value: pointer to unpacked data or NULL * Note: you must call ayemu_vtx_open() first. */ char *ayemu_vtx_load_data (ayemu_vtx_t *vtx) { char *packed_data; size_t packed_size; size_t buf_alloc; int c; if (vtx->fp == NULL) { fprintf(stderr, "ayemu_vtx_load_data: tune file not open yet (do you call ayemu_vtx_open first?)\n"); return NULL; } packed_size = 0; buf_alloc = 4096; packed_data = (char *) malloc (buf_alloc); /* read packed AY register data to end of file. */ while ((c = vfs_getc (vtx->fp)) != EOF) { if (buf_alloc < packed_size) { buf_alloc *= 2; packed_data = (char *) realloc (packed_data, buf_alloc); if (packed_data == NULL) { fprintf (stderr, "ayemu_vtx_load_data: Packed data out of memory!\n"); vfs_fclose (vtx->fp); return NULL; } } packed_data[packed_size++] = c; } vfs_fclose (vtx->fp); vtx->fp = NULL; if ((vtx->regdata = (char *) malloc (vtx->hdr.regdata_size)) == NULL) { fprintf (stderr, "ayemu_vtx_load_data: Can allocate %d bytes for unpack register data\n", (int)(vtx->hdr.regdata_size)); free (packed_data); return NULL; } lh5_decode ((unsigned char *)packed_data, (unsigned char *)(vtx->regdata), vtx->hdr.regdata_size, packed_size); free (packed_data); vtx->pos = 0; return vtx->regdata; }
/** * Reads a string of characters from a stream, ending in newline or EOF. * * @param s A buffer to put the string in. * @param n The amount of characters to read. * @param stream A #VFSFile object representing the stream. * @return The string on success, or NULL. */ EXPORT char *vfs_fgets(char *s, int n, VFSFile *stream) { int c; register char *p; if (n <= 0) return NULL; p = s; while (--n) { if ((c = vfs_getc(stream))== EOF) { break; } if ((*p++ = c) == '\n') { break; } } if (p > s) { *p = 0; return s; } return NULL; }
/* reads a single byte */ int i_midi_file_read_byte (midifile_t * mf) { ++mf->file_offset; return vfs_getc (mf->file_pointer); }
static int xs_get_sid_hash(const char *filename, xs_md5hash_t hash) { VFSFile *inFile; xs_md5state_t inState; psidv1_header_t psidH; psidv2_header_t psidH2; uint8_t *songData; uint8_t ib8[2], i8; int index, result; /* Try to open the file */ if ((inFile = vfs_fopen(filename, "rb")) == NULL) return -1; /* Read PSID header in */ if (vfs_fread(psidH.magicID, 1, sizeof psidH.magicID, inFile) < sizeof psidH.magicID) { vfs_fclose(inFile); return -1; } if (strncmp(psidH.magicID, "PSID", 4) && strncmp(psidH.magicID, "RSID", 4)) { vfs_fclose(inFile); xs_error("Not a PSID or RSID file '%s'\n", filename); return -2; } psidH.version = xs_fread_be16(inFile); psidH.dataOffset = xs_fread_be16(inFile); psidH.loadAddress = xs_fread_be16(inFile); psidH.initAddress = xs_fread_be16(inFile); psidH.playAddress = xs_fread_be16(inFile); psidH.nSongs = xs_fread_be16(inFile); psidH.startSong = xs_fread_be16(inFile); psidH.speed = xs_fread_be32(inFile); if (vfs_fread(psidH.sidName, 1, sizeof psidH.sidName, inFile) < sizeof psidH.sidName || vfs_fread(psidH.sidAuthor, 1, sizeof psidH.sidAuthor, inFile) < sizeof psidH.sidAuthor || vfs_fread(psidH.sidCopyright, 1, sizeof psidH.sidCopyright, inFile) < sizeof psidH.sidCopyright) { vfs_fclose(inFile); xs_error("Error reading SID file header from '%s'\n", filename); return -4; } /* Check if we need to load PSIDv2NG header ... */ psidH2.flags = 0; /* Just silence a stupid gcc warning */ if (psidH.version == 2) { /* Yes, we need to */ psidH2.flags = xs_fread_be16(inFile); psidH2.startPage = vfs_getc(inFile); psidH2.pageLength = vfs_getc(inFile); psidH2.reserved = xs_fread_be16(inFile); } /* Allocate buffer */ songData = (uint8_t *) malloc(XS_SIDBUF_SIZE * sizeof(uint8_t)); if (!songData) { vfs_fclose(inFile); xs_error("Error allocating temp data buffer for file '%s'\n", filename); return -3; } /* Read data to buffer */ result = vfs_fread(songData, sizeof(uint8_t), XS_SIDBUF_SIZE, inFile); vfs_fclose(inFile); /* Initialize and start MD5-hash calculation */ xs_md5_init(&inState); if (psidH.loadAddress == 0) { /* Strip load address (2 first bytes) */ xs_md5_append(&inState, &songData[2], result - 2); } else { /* Append "as is" */ xs_md5_append(&inState, songData, result); } /* Free buffer */ free(songData); /* Append header data to hash */ #define XSADDHASH(QDATAB) do { \ ib8[0] = (QDATAB & 0xff); \ ib8[1] = (QDATAB >> 8); \ xs_md5_append(&inState, (uint8_t *) &ib8, sizeof(ib8)); \ } while (0) XSADDHASH(psidH.initAddress); XSADDHASH(psidH.playAddress); XSADDHASH(psidH.nSongs); #undef XSADDHASH /* Append song speed data to hash */ i8 = 0; for (index = 0; (index < psidH.nSongs) && (index < 32); index++) { i8 = (psidH.speed & (1 << index)) ? 60 : 0; xs_md5_append(&inState, &i8, sizeof(i8)); } /* Rest of songs (more than 32) */ for (index = 32; index < psidH.nSongs; index++) { xs_md5_append(&inState, &i8, sizeof(i8)); } /* PSIDv2NG specific */ if (psidH.version == 2) { /* SEE SIDPLAY HEADERS FOR INFO */ i8 = (psidH2.flags >> 2) & 3; if (i8 == 2) xs_md5_append(&inState, &i8, sizeof(i8)); }