Mercurial > hg > xmms-sid
comparison src/xs_length.c @ 909:84394ee26545
Cleanups.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 10 Nov 2012 12:29:16 +0200 |
parents | 37ab2fba30c8 |
children | 560cdf7f1fec |
comparison
equal
deleted
inserted
replaced
908:8b4c016802ea | 909:84394ee26545 |
---|---|
29 | 29 |
30 /* Free memory allocated for given SLDB node | 30 /* Free memory allocated for given SLDB node |
31 */ | 31 */ |
32 static void xs_sldb_node_free(XSSLDBNode *node) | 32 static void xs_sldb_node_free(XSSLDBNode *node) |
33 { | 33 { |
34 if (node) { | 34 if (node) |
35 /* Nothing much to do here ... */ | 35 { |
36 g_free(node->lengths); | 36 g_free(node->lengths); |
37 g_free(node); | 37 g_free(node); |
38 } | 38 } |
39 } | 39 } |
40 | 40 |
43 */ | 43 */ |
44 static void xs_sldb_node_insert(XSSLDB *db, XSSLDBNode *node) | 44 static void xs_sldb_node_insert(XSSLDB *db, XSSLDBNode *node) |
45 { | 45 { |
46 assert(db != NULL); | 46 assert(db != NULL); |
47 | 47 |
48 if (db->nodes) { | 48 if (db->nodes) |
49 { | |
49 node->prev = db->nodes->prev; | 50 node->prev = db->nodes->prev; |
50 db->nodes->prev->next = node; | 51 db->nodes->prev->next = node; |
51 db->nodes->prev = node; | 52 db->nodes->prev = node; |
52 } else { | 53 } |
54 else | |
55 { | |
53 db->nodes = node; | 56 db->nodes = node; |
54 node->prev = node; | 57 node->prev = node; |
55 } | 58 } |
56 node->next = NULL; | 59 node->next = NULL; |
57 } | 60 } |
62 static gint xs_sldb_gettime(gchar *str, size_t *pos) | 65 static gint xs_sldb_gettime(gchar *str, size_t *pos) |
63 { | 66 { |
64 gint result, tmp; | 67 gint result, tmp; |
65 | 68 |
66 /* Check if it starts with a digit */ | 69 /* Check if it starts with a digit */ |
67 if (isdigit(str[*pos])) { | 70 if (isdigit(str[*pos])) |
71 { | |
68 /* Get minutes-field */ | 72 /* Get minutes-field */ |
69 result = 0; | 73 result = 0; |
70 while (isdigit(str[*pos])) | 74 while (isdigit(str[*pos])) |
71 result = (result * 10) + (str[(*pos)++] - '0'); | 75 result = (result * 10) + (str[(*pos)++] - '0'); |
72 | 76 |
73 result *= 60; | 77 result *= 60; |
74 | 78 |
75 /* Check the field separator char */ | 79 /* Check the field separator char */ |
76 if (str[*pos] == ':') { | 80 if (str[*pos] == ':') |
81 { | |
77 /* Get seconds-field */ | 82 /* Get seconds-field */ |
78 (*pos)++; | 83 (*pos)++; |
79 tmp = 0; | 84 tmp = 0; |
80 while (isdigit(str[*pos])) { | 85 while (isdigit(str[*pos])) |
81 tmp = (tmp * 10) + (str[(*pos)++] - '0'); | 86 tmp = (tmp * 10) + (str[(*pos)++] - '0'); |
82 } | |
83 | 87 |
84 result += tmp; | 88 result += tmp; |
85 } else | 89 } |
90 else | |
86 result = -2; | 91 result = -2; |
87 } else | 92 } |
93 else | |
88 result = -1; | 94 result = -1; |
89 | 95 |
90 /* Ignore and skip the possible attributes */ | 96 /* Ignore and skip the possible attributes */ |
91 while (str[*pos] && !isspace(str[*pos])) | 97 while (str[*pos] && !isspace(str[*pos])) |
92 (*pos)++; | 98 (*pos)++; |
104 gboolean isOK; | 110 gboolean isOK; |
105 XSSLDBNode *tmnode; | 111 XSSLDBNode *tmnode; |
106 | 112 |
107 /* Allocate new node */ | 113 /* Allocate new node */ |
108 tmnode = (XSSLDBNode *) g_malloc0(sizeof(XSSLDBNode)); | 114 tmnode = (XSSLDBNode *) g_malloc0(sizeof(XSSLDBNode)); |
109 if (!tmnode) { | 115 if (!tmnode) |
116 { | |
110 xs_error("Error allocating new node. Fatal error.\n"); | 117 xs_error("Error allocating new node. Fatal error.\n"); |
111 return NULL; | 118 return NULL; |
112 } | 119 } |
113 | 120 |
114 /* Get hash value */ | 121 /* Get hash value */ |
115 linePos = 0; | 122 linePos = 0; |
116 for (i = 0; i < XS_MD5HASH_LENGTH; i++, linePos += 2) { | 123 for (i = 0; i < XS_MD5HASH_LENGTH; i++, linePos += 2) |
124 { | |
117 gint tmpu; | 125 gint tmpu; |
118 sscanf(&inLine[linePos], "%2x", &tmpu); | 126 sscanf(&inLine[linePos], "%2x", &tmpu); |
119 tmnode->md5Hash[i] = tmpu; | 127 tmnode->md5Hash[i] = tmpu; |
120 } | 128 } |
121 | 129 |
122 /* Get playtimes */ | 130 /* Get playtimes */ |
123 if (inLine[linePos] != 0) { | 131 if (inLine[linePos] != 0) |
124 if (inLine[linePos] != '=') { | 132 { |
133 if (inLine[linePos] != '=') | |
134 { | |
125 xs_error("'=' expected on column #%d.\n", linePos); | 135 xs_error("'=' expected on column #%d.\n", linePos); |
126 xs_sldb_node_free(tmnode); | 136 xs_sldb_node_free(tmnode); |
127 return NULL; | 137 return NULL; |
128 } else { | 138 } |
139 else | |
140 { | |
129 size_t tmpLen, savePos; | 141 size_t tmpLen, savePos; |
130 | 142 |
131 /* First playtime is after '=' */ | 143 /* First playtime is after '=' */ |
132 savePos = ++linePos; | 144 savePos = ++linePos; |
133 tmpLen = strlen(inLine); | 145 tmpLen = strlen(inLine); |
134 | 146 |
135 /* Get number of sub-tune lengths */ | 147 /* Get number of sub-tune lengths */ |
136 isOK = TRUE; | 148 isOK = TRUE; |
137 while ((linePos < tmpLen) && isOK) { | 149 while (linePos < tmpLen && isOK) |
150 { | |
138 xs_findnext(inLine, &linePos); | 151 xs_findnext(inLine, &linePos); |
139 | 152 |
140 if (xs_sldb_gettime(inLine, &linePos) >= 0) | 153 if (xs_sldb_gettime(inLine, &linePos) >= 0) |
141 tmnode->nlengths++; | 154 tmnode->nlengths++; |
142 else | 155 else |
143 isOK = FALSE; | 156 isOK = FALSE; |
144 } | 157 } |
145 | 158 |
146 /* Allocate memory for lengths */ | 159 /* Allocate memory for lengths */ |
147 if (tmnode->nlengths > 0) { | 160 if (tmnode->nlengths > 0) |
161 { | |
148 tmnode->lengths = (gint *) g_malloc0(tmnode->nlengths * sizeof(gint)); | 162 tmnode->lengths = (gint *) g_malloc0(tmnode->nlengths * sizeof(gint)); |
149 if (!tmnode->lengths) { | 163 if (!tmnode->lengths) |
164 { | |
150 xs_error("Could not allocate memory for node.\n"); | 165 xs_error("Could not allocate memory for node.\n"); |
151 xs_sldb_node_free(tmnode); | 166 xs_sldb_node_free(tmnode); |
152 return NULL; | 167 return NULL; |
153 } | 168 } |
154 } else { | 169 } |
170 else | |
171 { | |
155 xs_sldb_node_free(tmnode); | 172 xs_sldb_node_free(tmnode); |
156 return NULL; | 173 return NULL; |
157 } | 174 } |
158 | 175 |
159 /* Read lengths in */ | 176 /* Read lengths in */ |
160 i = 0; | 177 for (i = 0, linePos = savePos, isOK = TRUE; |
161 linePos = savePos; | 178 linePos < tmpLen && i < tmnode->nlengths && isOK; i++) |
162 isOK = TRUE; | 179 { |
163 while ((linePos < tmpLen) && (i < tmnode->nlengths) && isOK) { | |
164 gint l; | 180 gint l; |
165 | 181 |
166 xs_findnext(inLine, &linePos); | 182 xs_findnext(inLine, &linePos); |
167 | 183 |
168 l = xs_sldb_gettime(inLine, &linePos); | 184 l = xs_sldb_gettime(inLine, &linePos); |
172 isOK = FALSE; | 188 isOK = FALSE; |
173 | 189 |
174 i++; | 190 i++; |
175 } | 191 } |
176 | 192 |
177 if (!isOK) { | 193 if (!isOK) |
194 { | |
178 xs_sldb_node_free(tmnode); | 195 xs_sldb_node_free(tmnode); |
179 return NULL; | 196 return NULL; |
180 } else | 197 } |
198 else | |
181 return tmnode; | 199 return tmnode; |
182 } | 200 } |
183 } | 201 } |
184 | 202 |
185 return NULL; | 203 return NULL; |
195 size_t lineNum; | 213 size_t lineNum; |
196 XSSLDBNode *tmnode; | 214 XSSLDBNode *tmnode; |
197 assert(db); | 215 assert(db); |
198 | 216 |
199 /* Try to open the file */ | 217 /* Try to open the file */ |
200 if ((inFile = fopen(dbFilename, "ra")) == NULL) { | 218 if ((inFile = fopen(dbFilename, "ra")) == NULL) |
219 { | |
201 xs_error("Could not open SongLengthDB '%s'\n", dbFilename); | 220 xs_error("Could not open SongLengthDB '%s'\n", dbFilename); |
202 return -1; | 221 return -1; |
203 } | 222 } |
204 | 223 |
205 /* Read and parse the data */ | 224 /* Read and parse the data */ |
206 lineNum = 0; | 225 lineNum = 0; |
207 | 226 |
208 while (fgets(inLine, XS_BUF2_SIZE, inFile) != NULL) { | 227 while (fgets(inLine, XS_BUF2_SIZE, inFile) != NULL) |
228 { | |
209 size_t linePos = 0; | 229 size_t linePos = 0; |
210 lineNum++; | 230 lineNum++; |
211 | 231 |
212 xs_findnext(inLine, &linePos); | 232 xs_findnext(inLine, &linePos); |
213 | 233 |
214 /* Check if it is datafield */ | 234 /* Check if it is datafield */ |
215 if (isxdigit(inLine[linePos])) { | 235 if (isxdigit(inLine[linePos])) |
236 { | |
216 /* Check the length of the hash */ | 237 /* Check the length of the hash */ |
217 gint hashLen; | 238 gint hashLen; |
218 for (hashLen = 0; inLine[linePos] && isxdigit(inLine[linePos]); hashLen++, linePos++); | 239 for (hashLen = 0; inLine[linePos] && isxdigit(inLine[linePos]); hashLen++, linePos++); |
219 | 240 |
220 if (hashLen != XS_MD5HASH_LENGTH_CH) { | 241 if (hashLen != XS_MD5HASH_LENGTH_CH) |
242 { | |
221 xs_error("Invalid MD5-hash in SongLengthDB file '%s' line #%d:\n%s\n", | 243 xs_error("Invalid MD5-hash in SongLengthDB file '%s' line #%d:\n%s\n", |
222 dbFilename, lineNum, inLine); | 244 dbFilename, lineNum, inLine); |
223 } else { | 245 } |
246 else | |
247 { | |
224 /* Parse and add node to db */ | 248 /* Parse and add node to db */ |
225 if ((tmnode = xs_sldb_read_entry(inLine)) != NULL) { | 249 if ((tmnode = xs_sldb_read_entry(inLine)) != NULL) |
250 { | |
226 xs_sldb_node_insert(db, tmnode); | 251 xs_sldb_node_insert(db, tmnode); |
227 } else { | 252 } |
253 else | |
254 { | |
228 xs_error("Invalid entry in SongLengthDB file '%s' line #%d:\n%s\n", | 255 xs_error("Invalid entry in SongLengthDB file '%s' line #%d:\n%s\n", |
229 dbFilename, lineNum, inLine); | 256 dbFilename, lineNum, inLine); |
230 } | 257 } |
231 } | 258 } |
232 } else if (inLine[linePos] != ';' && inLine[linePos] != '[' && inLine[linePos] != 0) { | 259 } |
260 else | |
261 if (inLine[linePos] != ';' && inLine[linePos] != '[' && inLine[linePos] != 0) | |
262 { | |
233 xs_error("Invalid line in SongLengthDB file '%s' line #%d:\n%s\n", | 263 xs_error("Invalid line in SongLengthDB file '%s' line #%d:\n%s\n", |
234 dbFilename, lineNum, inLine); | 264 dbFilename, lineNum, inLine); |
235 } | 265 } |
236 | 266 |
237 } | 267 } |
238 | 268 |
239 /* Close the file */ | |
240 fclose(inFile); | 269 fclose(inFile); |
241 | |
242 return 0; | 270 return 0; |
243 } | 271 } |
244 | 272 |
245 | 273 |
246 /* Compare two given MD5-hashes. | 274 /* Compare two given MD5-hashes. |
273 | 301 |
274 /* (Re)create index | 302 /* (Re)create index |
275 */ | 303 */ |
276 gint xs_sldb_index(XSSLDB * db) | 304 gint xs_sldb_index(XSSLDB * db) |
277 { | 305 { |
278 XSSLDBNode *pCurr; | 306 XSSLDBNode *node; |
279 size_t i; | 307 size_t i; |
280 assert(db); | 308 assert(db); |
281 | 309 |
282 /* Free old index */ | 310 /* Free old index */ |
283 if (db->pindex) { | 311 g_free(db->pindex); |
284 g_free(db->pindex); | 312 db->pindex = NULL; |
285 db->pindex = NULL; | |
286 } | |
287 | 313 |
288 /* Get size of db */ | 314 /* Get size of db */ |
289 pCurr = db->nodes; | 315 for (node = db->nodes, db->n = 0; node != NULL; node = node->next) |
290 db->n = 0; | |
291 while (pCurr) { | |
292 db->n++; | 316 db->n++; |
293 pCurr = pCurr->next; | |
294 } | |
295 | 317 |
296 /* Check number of nodes */ | 318 /* Check number of nodes */ |
297 if (db->n > 0) { | 319 if (db->n > 0) |
320 { | |
298 /* Allocate memory for index-table */ | 321 /* Allocate memory for index-table */ |
299 db->pindex = (XSSLDBNode **) g_malloc(sizeof(XSSLDBNode *) * db->n); | 322 db->pindex = (XSSLDBNode **) g_malloc(sizeof(XSSLDBNode *) * db->n); |
300 if (!db->pindex) | 323 if (!db->pindex) |
301 return -1; | 324 return -1; |
302 | 325 |
303 /* Get node-pointers to table */ | 326 /* Get node-pointers to table */ |
304 i = 0; | 327 for (i = 0, node = db->nodes; node && i < db->n; node = node->next) |
305 pCurr = db->nodes; | 328 db->pindex[i++] = node; |
306 while (pCurr && (i < db->n)) { | |
307 db->pindex[i++] = pCurr; | |
308 pCurr = pCurr->next; | |
309 } | |
310 | 329 |
311 /* Sort the indexes */ | 330 /* Sort the indexes */ |
312 qsort(db->pindex, db->n, sizeof(XSSLDBNode *), xs_sldb_cmp); | 331 qsort(db->pindex, db->n, sizeof(XSSLDBNode *), xs_sldb_cmp); |
313 } | 332 } |
314 | 333 |
318 | 337 |
319 /* Free a given song-length database | 338 /* Free a given song-length database |
320 */ | 339 */ |
321 void xs_sldb_free(XSSLDB * db) | 340 void xs_sldb_free(XSSLDB * db) |
322 { | 341 { |
323 XSSLDBNode *pCurr, *next; | 342 XSSLDBNode *node, *next; |
324 | 343 |
325 if (!db) | 344 if (!db) |
326 return; | 345 return; |
327 | 346 |
328 /* Free the memory allocated for nodes */ | 347 /* Free the memory allocated for nodes */ |
329 pCurr = db->nodes; | 348 node = db->nodes; |
330 while (pCurr) { | 349 while (node != NULL) |
331 next = pCurr->next; | 350 { |
332 xs_sldb_node_free(pCurr); | 351 next = node->next; |
333 pCurr = next; | 352 xs_sldb_node_free(node); |
353 node = next; | |
334 } | 354 } |
335 | 355 |
336 db->nodes = NULL; | 356 db->nodes = NULL; |
337 | 357 |
338 /* Free memory allocated for index */ | 358 /* Free memory allocated for index */ |
339 if (db->pindex) { | 359 g_free(db->pindex); |
340 g_free(db->pindex); | 360 db->pindex = NULL; |
341 db->pindex = NULL; | |
342 } | |
343 | 361 |
344 /* Free structure */ | 362 /* Free structure */ |
345 db->n = 0; | 363 db->n = 0; |
346 g_free(db); | 364 g_free(db); |
347 } | 365 } |
348 | 366 |
349 | 367 |
350 /* Compute md5hash of given SID-file | 368 /* Compute md5hash of given SID-file |
351 */ | 369 */ |
352 typedef struct { | 370 typedef struct |
371 { | |
353 gchar magicID[4]; /* "PSID" / "RSID" magic identifier */ | 372 gchar magicID[4]; /* "PSID" / "RSID" magic identifier */ |
354 guint16 version, /* Version number */ | 373 guint16 version, /* Version number */ |
355 dataOffset, /* Start of actual c64 data in file */ | 374 dataOffset, /* Start of actual c64 data in file */ |
356 loadAddress, /* Loading address */ | 375 loadAddress, /* Loading address */ |
357 initAddress, /* Initialization address */ | 376 initAddress, /* Initialization address */ |
363 gchar sidAuthor[32]; | 382 gchar sidAuthor[32]; |
364 gchar sidCopyright[32]; | 383 gchar sidCopyright[32]; |
365 } psidv1_header_t; | 384 } psidv1_header_t; |
366 | 385 |
367 | 386 |
368 typedef struct { | 387 typedef struct |
388 { | |
369 guint16 flags; /* Flags */ | 389 guint16 flags; /* Flags */ |
370 guint8 startPage, pageLength; | 390 guint8 startPage, pageLength; |
371 guint16 reserved; | 391 guint16 reserved; |
372 } psidv2_header_t; | 392 } psidv2_header_t; |
373 | 393 |
386 if ((inFile = xs_fopen(filename, "rb")) == NULL) | 406 if ((inFile = xs_fopen(filename, "rb")) == NULL) |
387 return -1; | 407 return -1; |
388 | 408 |
389 /* Read PSID header in */ | 409 /* Read PSID header in */ |
390 xs_fread(psidH.magicID, sizeof(psidH.magicID), 1, inFile); | 410 xs_fread(psidH.magicID, sizeof(psidH.magicID), 1, inFile); |
391 if (strncmp(psidH.magicID, "PSID", 4) && strncmp(psidH.magicID, "RSID", 4)) { | 411 if (strncmp(psidH.magicID, "PSID", 4) && |
412 strncmp(psidH.magicID, "RSID", 4)) | |
413 { | |
392 xs_fclose(inFile); | 414 xs_fclose(inFile); |
393 xs_error("Not a PSID or RSID file '%s'\n", filename); | 415 xs_error("Not a PSID or RSID file '%s'\n", filename); |
394 return -2; | 416 return -2; |
395 } | 417 } |
396 | 418 |
405 | 427 |
406 xs_fread(psidH.sidName, sizeof(gchar), sizeof(psidH.sidName), inFile); | 428 xs_fread(psidH.sidName, sizeof(gchar), sizeof(psidH.sidName), inFile); |
407 xs_fread(psidH.sidAuthor, sizeof(gchar), sizeof(psidH.sidAuthor), inFile); | 429 xs_fread(psidH.sidAuthor, sizeof(gchar), sizeof(psidH.sidAuthor), inFile); |
408 xs_fread(psidH.sidCopyright, sizeof(gchar), sizeof(psidH.sidCopyright), inFile); | 430 xs_fread(psidH.sidCopyright, sizeof(gchar), sizeof(psidH.sidCopyright), inFile); |
409 | 431 |
410 if (xs_feof(inFile) || xs_ferror(inFile)) { | 432 if (xs_feof(inFile) || xs_ferror(inFile)) |
433 { | |
411 xs_fclose(inFile); | 434 xs_fclose(inFile); |
412 xs_error("Error reading SID file header from '%s'\n", filename); | 435 xs_error("Error reading SID file header from '%s'\n", filename); |
413 return -4; | 436 return -4; |
414 } | 437 } |
415 | 438 |
416 /* Check if we need to load PSIDv2NG header ... */ | 439 /* Check if we need to load PSIDv2NG header ... */ |
417 psidH2.flags = 0; /* Just silence a stupid gcc warning */ | 440 psidH2.flags = 0; /* Just silence a stupid gcc warning */ |
418 | 441 |
419 if (psidH.version == 2) { | 442 if (psidH.version == 2) |
443 { | |
420 /* Yes, we need to */ | 444 /* Yes, we need to */ |
421 psidH2.flags = xs_fread_be16(inFile); | 445 psidH2.flags = xs_fread_be16(inFile); |
422 psidH2.startPage = xs_fgetc(inFile); | 446 psidH2.startPage = xs_fgetc(inFile); |
423 psidH2.pageLength = xs_fgetc(inFile); | 447 psidH2.pageLength = xs_fgetc(inFile); |
424 psidH2.reserved = xs_fread_be16(inFile); | 448 psidH2.reserved = xs_fread_be16(inFile); |
425 } | 449 } |
426 | 450 |
427 /* Allocate buffer */ | 451 /* Allocate buffer */ |
428 songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE * sizeof(guint8)); | 452 songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE * sizeof(guint8)); |
429 if (!songData) { | 453 if (!songData) |
454 { | |
430 xs_fclose(inFile); | 455 xs_fclose(inFile); |
431 xs_error("Error allocating temp data buffer for file '%s'\n", filename); | 456 xs_error("Error allocating temp data buffer for file '%s'\n", filename); |
432 return -3; | 457 return -3; |
433 } | 458 } |
434 | 459 |
437 xs_fclose(inFile); | 462 xs_fclose(inFile); |
438 | 463 |
439 /* Initialize and start MD5-hash calculation */ | 464 /* Initialize and start MD5-hash calculation */ |
440 xs_md5_init(&inState); | 465 xs_md5_init(&inState); |
441 | 466 |
442 if (psidH.loadAddress == 0) { | 467 if (psidH.loadAddress == 0) |
468 { | |
443 /* Strip load address (2 first bytes) */ | 469 /* Strip load address (2 first bytes) */ |
444 xs_md5_append(&inState, &songData[2], result - 2); | 470 xs_md5_append(&inState, &songData[2], result - 2); |
445 } else { | 471 } |
472 else | |
473 { | |
446 /* Append "as is" */ | 474 /* Append "as is" */ |
447 xs_md5_append(&inState, songData, result); | 475 xs_md5_append(&inState, songData, result); |
448 } | 476 } |
449 | 477 |
450 /* Free buffer */ | 478 /* Free buffer */ |
451 g_free(songData); | 479 g_free(songData); |
452 | 480 |
453 /* Append header data to hash */ | 481 /* Append header data to hash */ |
454 #define XSADDHASH(QDATAB) do { \ | 482 #define XSADDHASH(QDATAB) do { \ |
455 ib8[0] = (QDATAB & 0xff); \ | 483 ib8[0] = (QDATAB & 0xff); \ |
456 ib8[1] = (QDATAB >> 8); \ | 484 ib8[1] = (QDATAB >> 8); \ |
457 xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); \ | 485 xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); \ |
458 } while (0) | 486 } while (0) |
459 | 487 |
460 XSADDHASH(psidH.initAddress); | 488 XSADDHASH(psidH.initAddress); |
461 XSADDHASH(psidH.playAddress); | 489 XSADDHASH(psidH.playAddress); |
462 XSADDHASH(psidH.nSongs); | 490 XSADDHASH(psidH.nSongs); |
463 #undef XSADDHASH | 491 #undef XSADDHASH |
464 | 492 |
465 /* Append song speed data to hash */ | 493 /* Append song speed data to hash */ |
466 i8 = 0; | 494 i8 = 0; |
467 for (index = 0; (index < psidH.nSongs) && (index < 32); index++) { | 495 for (index = 0; index < psidH.nSongs && index < 32; index++) |
496 { | |
468 i8 = (psidH.speed & (1 << index)) ? 60 : 0; | 497 i8 = (psidH.speed & (1 << index)) ? 60 : 0; |
469 xs_md5_append(&inState, &i8, sizeof(i8)); | 498 xs_md5_append(&inState, &i8, sizeof(i8)); |
470 } | 499 } |
471 | 500 |
472 /* Rest of songs (more than 32) */ | 501 /* Rest of songs (more than 32) */ |
473 for (index = 32; index < psidH.nSongs; index++) { | 502 for (index = 32; index < psidH.nSongs; index++) |
474 xs_md5_append(&inState, &i8, sizeof(i8)); | 503 xs_md5_append(&inState, &i8, sizeof(i8)); |
475 } | |
476 | 504 |
477 /* PSIDv2NG specific */ | 505 /* PSIDv2NG specific */ |
478 if (psidH.version == 2) { | 506 if (psidH.version == 2) |
507 { | |
479 /* SEE SIDPLAY HEADERS FOR INFO */ | 508 /* SEE SIDPLAY HEADERS FOR INFO */ |
480 i8 = (psidH2.flags >> 2) & 3; | 509 i8 = (psidH2.flags >> 2) & 3; |
481 if (i8 == 2) | 510 if (i8 == 2) |
482 xs_md5_append(&inState, &i8, sizeof(i8)); | 511 xs_md5_append(&inState, &i8, sizeof(i8)); |
483 } | 512 } |
498 /* Check the database pointers */ | 527 /* Check the database pointers */ |
499 if (!db || !db->nodes || !db->pindex) | 528 if (!db || !db->nodes || !db->pindex) |
500 return NULL; | 529 return NULL; |
501 | 530 |
502 /* Get the hash and then look up from db */ | 531 /* Get the hash and then look up from db */ |
503 if (xs_get_sid_hash(filename, keyItem.md5Hash) == 0) { | 532 if (xs_get_sid_hash(filename, keyItem.md5Hash) == 0) |
533 { | |
504 key = &keyItem; | 534 key = &keyItem; |
505 item = bsearch(&key, db->pindex, db->n, | 535 item = bsearch(&key, db->pindex, db->n, |
506 sizeof(db->pindex[0]), xs_sldb_cmp); | 536 sizeof(db->pindex[0]), xs_sldb_cmp); |
507 | 537 |
508 if (item) | 538 return (item != NULL) ? *item : NULL; |
509 return *item; | 539 } |
510 else | 540 else |
511 return NULL; | |
512 } else | |
513 return NULL; | 541 return NULL; |
514 } | 542 } |
515 | |
516 |