Common Source Code Project for Qt (a.k.a for FM-7).
修订版 | 4968506ddcc7995efb04fda764c3c8694ad0073f (tree) |
---|---|
时间 | 2018-11-20 05:16:35 |
作者 | K.Ohta <whatisthis.sowhat@gmai...> |
Commiter | K.Ohta |
[VM][SCSI_CDROM] Use std::string instead of C string functions.
[VM][SCSI_CDROM] CUE image:Fix correct toc description.
[VM][SCSI_CDROM][WIP] Fixing around CDDA.
@@ -82,9 +82,20 @@ void SCSI_CDROM::event_callback(int event_id, int err) | ||
82 | 82 | // one frame finished |
83 | 83 | if(++cdda_playing_frame == cdda_end_frame) { |
84 | 84 | // reached to end frame |
85 | + #ifdef _CDROM_DEBUG_LOG | |
86 | + this->out_debug_log(_T("Reaches to the end of track. REPEAT=%s\n"), (cdda_repeat) ? _T("YES") : _T("NO")); | |
87 | + #endif | |
85 | 88 | if(cdda_repeat) { |
86 | 89 | // reload buffer |
87 | - fio_img->Fseek(cdda_start_frame * 2352, FILEIO_SEEK_SET); | |
90 | + if(is_cue) { | |
91 | + fio_img->Fclose(); | |
92 | + current_track = 0; | |
93 | + int trk = get_track(cdda_start_frame); | |
94 | + //int trk = current_track; | |
95 | + fio_img->Fseek((cdda_start_frame - toc_table[trk].lba_offset) * 2352, FILEIO_SEEK_SET); | |
96 | + } else { | |
97 | + fio_img->Fseek(cdda_start_frame * 2352, FILEIO_SEEK_SET); | |
98 | + } | |
88 | 99 | fio_img->Fread(cdda_buffer, sizeof(cdda_buffer), 1); |
89 | 100 | cdda_buffer_ptr = 0; |
90 | 101 | cdda_playing_frame = cdda_start_frame; |
@@ -121,6 +132,9 @@ void SCSI_CDROM::set_cdda_status(uint8_t status) | ||
121 | 132 | if(cdda_status != CDDA_PLAYING) { |
122 | 133 | touch_sound(); |
123 | 134 | set_realtime_render(this, true); |
135 | + #ifdef _CDROM_DEBUG_LOG | |
136 | + this->out_debug_log(_T("START Playing CDDA.\n")); | |
137 | + #endif | |
124 | 138 | } |
125 | 139 | } else { |
126 | 140 | //if(status == CDDA_OFF) { |
@@ -135,6 +149,9 @@ void SCSI_CDROM::set_cdda_status(uint8_t status) | ||
135 | 149 | if(cdda_status == CDDA_PLAYING) { |
136 | 150 | touch_sound(); |
137 | 151 | set_realtime_render(this, false); |
152 | + #ifdef _CDROM_DEBUG_LOG | |
153 | + this->out_debug_log(_T("STOP Playing CDDA.\n")); | |
154 | + #endif | |
138 | 155 | } |
139 | 156 | } |
140 | 157 | cdda_status = status; |
@@ -177,18 +194,15 @@ void SCSI_CDROM::get_track_by_track_num(int track) | ||
177 | 194 | } |
178 | 195 | if(is_cue) { |
179 | 196 | // ToDo: Apply audio with some codecs. |
180 | - if(current_track != track) { | |
181 | - if(fio_img != NULL) { | |
182 | - if(fio_img->IsOpened()) { | |
183 | - fio_img->Fclose(); | |
184 | - } | |
185 | - current_track = track; | |
197 | + if((current_track != track) || !(fio_img->IsOpened())){ | |
198 | + if(fio_img->IsOpened()) { | |
199 | + fio_img->Fclose(); | |
186 | 200 | } |
187 | 201 | #ifdef _CDROM_DEBUG_LOG |
188 | 202 | this->out_debug_log(_T("LOAD TRK #%02d from %s\n"), track, track_data_path[track - 1]); |
189 | 203 | #endif |
190 | 204 | |
191 | - if((track > 0) && (track < 100) && (track <= track_num)) { | |
205 | + if((track > 0) && (track < 100) && (track < track_num)) { | |
192 | 206 | if((strlen(track_data_path[track - 1]) <= 0) || |
193 | 207 | !(fio_img->Fopen(track_data_path[track - 1], FILEIO_READ_BINARY))) { |
194 | 208 | track = 0; |
@@ -198,21 +212,22 @@ void SCSI_CDROM::get_track_by_track_num(int track) | ||
198 | 212 | } |
199 | 213 | } |
200 | 214 | } |
215 | + current_track = track; | |
201 | 216 | } |
202 | 217 | |
203 | 218 | int SCSI_CDROM::get_track(uint32_t lba) |
204 | 219 | { |
205 | 220 | int track = 0; |
206 | 221 | |
207 | - if(is_cue) { | |
208 | - for(int i = 1; i <= track_num; i++) { | |
209 | - if(lba >= toc_table[i].lba_offset) { | |
210 | - track = i; | |
211 | - } else { | |
212 | - break; | |
213 | - } | |
214 | - } | |
215 | - } else { | |
222 | +// if(is_cue) { | |
223 | +// for(int i = 1; i <= track_num; i++) { | |
224 | +// if(lba >= toc_table[i].lba_offset) { | |
225 | +// track = i; | |
226 | +// } else { | |
227 | +// break; | |
228 | +// } | |
229 | +// } | |
230 | +// } else { | |
216 | 231 | for(int i = 0; i < track_num; i++) { |
217 | 232 | if(lba >= toc_table[i].index0) { |
218 | 233 | track = i; |
@@ -220,7 +235,7 @@ int SCSI_CDROM::get_track(uint32_t lba) | ||
220 | 235 | break; |
221 | 236 | } |
222 | 237 | } |
223 | - } | |
238 | +// } | |
224 | 239 | if(is_cue) { |
225 | 240 | get_track_by_track_num(track); |
226 | 241 | } else { |
@@ -241,13 +256,8 @@ double SCSI_CDROM::get_seek_time(uint32_t lba) | ||
241 | 256 | } |
242 | 257 | } |
243 | 258 | |
244 | -uint32_t SCSI_CDROM::lba_to_msf(int trk, uint32_t lba) | |
259 | +uint32_t SCSI_CDROM::lba_to_msf(uint32_t lba) | |
245 | 260 | { |
246 | - if(is_cue) { | |
247 | - if(trk > 0) { | |
248 | - lba = lba + toc_table[trk - 1].lba_offset; | |
249 | - } | |
250 | - } | |
251 | 261 | uint8_t m = lba / (60 * 75); |
252 | 262 | lba -= m * (60 * 75); |
253 | 263 | uint8_t s = lba / 75; |
@@ -256,13 +266,8 @@ uint32_t SCSI_CDROM::lba_to_msf(int trk, uint32_t lba) | ||
256 | 266 | return ((m / 10) << 20) | ((m % 10) << 16) | ((s / 10) << 12) | ((s % 10) << 8) | ((f / 10) << 4) | ((f % 10) << 0); |
257 | 267 | } |
258 | 268 | |
259 | -uint32_t SCSI_CDROM::lba_to_msf_alt(int trk, uint32_t lba) | |
269 | +uint32_t SCSI_CDROM::lba_to_msf_alt(uint32_t lba) | |
260 | 270 | { |
261 | - if(is_cue) { | |
262 | - if(trk > 0) { | |
263 | - lba = lba + toc_table[trk - 1].lba_offset; | |
264 | - } | |
265 | - } | |
266 | 271 | uint32_t ret = 0; |
267 | 272 | ret |= ((lba / (60 * 75)) & 0xff) << 16; |
268 | 273 | ret |= (((lba / 75) % 60) & 0xff) << 8; |
@@ -290,7 +295,7 @@ void SCSI_CDROM::start_command() | ||
290 | 295 | |
291 | 296 | case 0xd8: |
292 | 297 | #ifdef _SCSI_DEBUG_LOG |
293 | - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Set Audio Playback Start Position\n"), scsi_id); | |
298 | + this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Set Audio Playback Start Position CMD=%02x\n"), scsi_id, ((command[2] == 0) && (command[3] == 0) && (command[4] == 0)) ? 0x00 : command[9]); | |
294 | 299 | #endif |
295 | 300 | if(is_device_ready()) { |
296 | 301 | if(command[2] == 0 && command[3] == 0 && command[4] == 0) { |
@@ -317,13 +322,13 @@ void SCSI_CDROM::start_command() | ||
317 | 322 | // PCE tries to be clever here and set (start of track + track pregap size) to skip the pregap |
318 | 323 | // (I guess it wants the TOC to have the real start sector for data tracks and the start of the pregap for audio?) |
319 | 324 | int track = get_track(cdda_start_frame); |
320 | - if((is_cue) && (track > 1)) { | |
321 | - if(cdda_start_frame >= toc_table[track].lba_offset) { | |
322 | - cdda_start_frame = cdda_start_frame - toc_table[track].lba_offset; | |
323 | - } else { | |
324 | - cdda_start_frame = 0; | |
325 | - } | |
326 | - } | |
325 | +// if((is_cue) && (track > 1)) { | |
326 | +// if(cdda_start_frame >= toc_table[track - 1].lba_offset) { | |
327 | +// cdda_start_frame = cdda_start_frame - toc_table[track - 1].lba_offset; | |
328 | +// } else { | |
329 | +// cdda_start_frame = 0; | |
330 | +// } | |
331 | +// } | |
327 | 332 | cdda_start_frame -= toc_table[track].pregap; |
328 | 333 | |
329 | 334 | if(cdda_start_frame < toc_table[track].index1) { |
@@ -350,7 +355,6 @@ void SCSI_CDROM::start_command() | ||
350 | 355 | // } else |
351 | 356 | if((command[1] & 3) != 0) { |
352 | 357 | if((is_cue) && (current_track != track_num)){ |
353 | - seek_offset = toc_table[current_track].lba_offset; | |
354 | 358 | get_track_by_track_num(track_num); |
355 | 359 | } |
356 | 360 | cdda_end_frame = toc_table[track_num].index0; // end of disc |
@@ -358,12 +362,12 @@ void SCSI_CDROM::start_command() | ||
358 | 362 | } else { |
359 | 363 | uint32_t _sframe = cdda_start_frame; |
360 | 364 | int _trk; |
361 | - if((is_cue) && (current_track > 0)) { | |
362 | - _sframe = _sframe + toc_table[current_track].lba_offset; | |
365 | +// if((is_cue) && (current_track > 0)) { | |
366 | +// _sframe = _sframe + toc_table[current_track].lba_offset; | |
367 | +// cdda_end_frame = toc_table[get_track(_sframe) + 1].index1; // end of this track | |
368 | +// } else { | |
363 | 369 | cdda_end_frame = toc_table[get_track(_sframe) + 1].index1; // end of this track |
364 | - } else { | |
365 | - cdda_end_frame = toc_table[get_track(_sframe) + 1].index1; // end of this track | |
366 | - } | |
370 | +// } | |
367 | 371 | set_cdda_status(CDDA_PAUSED); |
368 | 372 | } |
369 | 373 | cdda_repeat = false; |
@@ -371,7 +375,12 @@ void SCSI_CDROM::start_command() | ||
371 | 375 | |
372 | 376 | // read buffer |
373 | 377 | double seek_time = get_seek_time(cdda_start_frame); |
374 | - fio_img->Fseek(cdda_start_frame * 2352, FILEIO_SEEK_SET); | |
378 | + if(is_cue) { | |
379 | + int trk = get_track(cdda_start_frame); | |
380 | + fio_img->Fseek((cdda_start_frame - toc_table[trk].lba_offset) * 2352, FILEIO_SEEK_SET); | |
381 | + } else { | |
382 | + fio_img->Fseek(cdda_start_frame * 2352, FILEIO_SEEK_SET); | |
383 | + } | |
375 | 384 | fio_img->Fread(cdda_buffer, sizeof(cdda_buffer), 1); |
376 | 385 | cdda_buffer_ptr = 0; |
377 | 386 | cdda_playing_frame = cdda_start_frame; |
@@ -390,12 +399,22 @@ void SCSI_CDROM::start_command() | ||
390 | 399 | |
391 | 400 | case 0xd9: |
392 | 401 | #ifdef _SCSI_DEBUG_LOG |
393 | - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Set Audio Playback End Position\n"), scsi_id); | |
402 | + this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Set Audio Playback End Position CMD=%02x ARG=%02x %02x %02x %02x\n"), scsi_id, command[9], command[2], command[3], command[4], command[5]); | |
394 | 403 | #endif |
395 | 404 | if(is_device_ready()) { |
396 | 405 | switch(command[9] & 0xc0) { |
397 | 406 | case 0x00: |
398 | 407 | cdda_end_frame = (command[3] << 16) | (command[4] << 8) | command[5]; |
408 | +// if(is_cue) { | |
409 | +// int track = get_track(cdda_end_frame); | |
410 | +// if(track > 1) { | |
411 | +// if(cdda_end_frame >= toc_table[track].lba_offset) { | |
412 | +// cdda_end_frame = cdda_end_frame - toc_table[track].lba_offset; | |
413 | +// } else { | |
414 | +// cdda_end_frame = 0; | |
415 | +// } | |
416 | +// } | |
417 | +// } | |
399 | 418 | break; |
400 | 419 | case 0x40: |
401 | 420 | { |
@@ -403,30 +422,45 @@ void SCSI_CDROM::start_command() | ||
403 | 422 | uint8_t s = FROM_BCD(command[3]); |
404 | 423 | uint8_t f = FROM_BCD(command[4]); |
405 | 424 | cdda_end_frame = f + 75 * (s + m * 60); |
425 | + //printf("END FRAME=%d\n", cdda_end_frame); | |
406 | 426 | |
407 | 427 | // PCE tries to be clever here and set (start of track + track pregap size) to skip the pregap |
408 | 428 | // (I guess it wants the TOC to have the real start sector for data tracks and the start of the pregap for audio?) |
409 | 429 | int track =get_track(cdda_end_frame); |
410 | - if((is_cue) && (track > 1)) { | |
411 | - if(cdda_end_frame >= toc_table[track].lba_offset) { | |
412 | - cdda_end_frame = cdda_end_frame - toc_table[track].lba_offset; | |
413 | - } else { | |
414 | - cdda_end_frame = 0; | |
415 | - } | |
416 | - } | |
417 | - | |
430 | +// if((is_cue) && (track > 1)) { | |
431 | +// if(cdda_end_frame >= toc_table[track - 1].lba_offset) { | |
432 | +// cdda_end_frame = cdda_end_frame - toc_table[track - 1].lba_offset; | |
433 | +// } else { | |
434 | +// cdda_end_frame = 0; | |
435 | +// } | |
436 | +// //if(cdda_end_frame >= toc_table[track - 1].lba_size) { | |
437 | +// // cdda_end_frame = toc_table[track - 1].lba_size - 1; | |
438 | +// //} | |
439 | +// //if(toc_table[track - 1].lba_size == 0) cdda_end_frame = 0; | |
440 | +// } | |
418 | 441 | if(cdda_end_frame > toc_table[track].index1 && (cdda_end_frame - toc_table[track].pregap) <= toc_table[track].index1) { |
419 | 442 | cdda_end_frame = toc_table[track].index1; |
420 | 443 | } |
421 | 444 | } |
422 | 445 | break; |
423 | 446 | case 0x80: |
424 | - cdda_end_frame = toc_table[FROM_BCD(command[2]) - 1].index1; | |
447 | + { | |
448 | + int _track = FROM_BCD(command[2]) - 1; | |
449 | + if(_track >= 0) { | |
450 | + cdda_end_frame = toc_table[_track].index1; | |
451 | + if(is_cue) { | |
452 | + if(_track != current_track) { | |
453 | + get_track_by_track_num(_track); | |
454 | + } | |
455 | + } | |
456 | + } | |
457 | + } | |
425 | 458 | break; |
426 | 459 | } |
427 | 460 | if((command[1] & 3) != 0) { |
428 | 461 | set_cdda_status(CDDA_PLAYING); |
429 | 462 | cdda_repeat = ((command[1] & 3) == 1); |
463 | + //cdda_repeat = ((command[1] & 1) == 1); | |
430 | 464 | cdda_interrupt = ((command[1] & 3) == 2); |
431 | 465 | } else { |
432 | 466 | set_cdda_status(CDDA_OFF); |
@@ -461,7 +495,7 @@ void SCSI_CDROM::start_command() | ||
461 | 495 | if(is_device_ready()) { |
462 | 496 | // create track info |
463 | 497 | uint32_t frame = (cdda_status == CDDA_OFF) ? cdda_start_frame : cdda_playing_frame; |
464 | - uint32_t msf_abs = lba_to_msf_alt(current_track - 1, frame); | |
498 | + uint32_t msf_abs = lba_to_msf_alt(frame); | |
465 | 499 | int track; |
466 | 500 | if(is_cue) { |
467 | 501 | //track = get_track(frame + ((current_track > 0) ? toc_table[current_track - 1].lba_offset : 0)); |
@@ -469,7 +503,7 @@ void SCSI_CDROM::start_command() | ||
469 | 503 | } else { |
470 | 504 | track = get_track(frame); |
471 | 505 | } |
472 | - uint32_t msf_rel = lba_to_msf_alt(track - 1, frame - toc_table[track].index0); | |
506 | + uint32_t msf_rel = lba_to_msf_alt(frame - toc_table[track].index0); | |
473 | 507 | buffer->clear(); |
474 | 508 | buffer->write((cdda_status == CDDA_PLAYING) ? 0x00 : (cdda_status == CDDA_PAUSED) ? 0x02 : 0x03); |
475 | 509 | buffer->write(0x01 | (toc_table[track].is_audio ? 0x00 : 0x40)); |
@@ -510,7 +544,7 @@ void SCSI_CDROM::start_command() | ||
510 | 544 | break; |
511 | 545 | case 0x01: /* Get total disk size in MSF format */ |
512 | 546 | { |
513 | - uint32_t msf = lba_to_msf(track_num - 1, toc_table[track_num].index0 + 150); | |
547 | + uint32_t msf = lba_to_msf(toc_table[track_num].index0 + 150); | |
514 | 548 | buffer->write((msf >> 16) & 0xff); |
515 | 549 | buffer->write((msf >> 8) & 0xff); |
516 | 550 | buffer->write((msf >> 0) & 0xff); |
@@ -518,25 +552,25 @@ void SCSI_CDROM::start_command() | ||
518 | 552 | break; |
519 | 553 | case 0x02: /* Get track information */ |
520 | 554 | if(command[2] == 0xaa) { |
521 | - uint32_t msf = lba_to_msf(track_num - 1, toc_table[track_num].index0 + 150); | |
555 | + uint32_t msf = lba_to_msf(toc_table[track_num].index0 + 150); | |
522 | 556 | buffer->write((msf >> 16) & 0xff); |
523 | 557 | buffer->write((msf >> 8) & 0xff); |
524 | 558 | buffer->write((msf >> 0) & 0xff); |
525 | 559 | buffer->write(0x04); // correct ? |
526 | 560 | } else { |
527 | 561 | int track = max(FROM_BCD(command[2]), 1); |
528 | - uint32_t frame = toc_table[track - 1].index0; | |
562 | + uint32_t frame = toc_table[track].index0; | |
529 | 563 | // PCE wants the start sector for data tracks to *not* include the pregap |
530 | - if(!toc_table[track - 1].is_audio) { | |
531 | - frame += toc_table[track - 1].pregap; | |
564 | + if(!toc_table[track].is_audio) { | |
565 | + frame += toc_table[track].pregap; | |
532 | 566 | } |
533 | 567 | get_track_by_track_num(track); |
534 | 568 | |
535 | - uint32_t msf = lba_to_msf(track - 1, toc_table[track - 1].index1 + 150); | |
569 | + uint32_t msf = lba_to_msf(toc_table[track].index1 + 150); | |
536 | 570 | buffer->write((msf >> 16) & 0xff); // M |
537 | 571 | buffer->write((msf >> 8) & 0xff); // S |
538 | 572 | buffer->write((msf >> 0) & 0xff); // F |
539 | - buffer->write(toc_table[track - 1].is_audio ? 0x00 : 0x04); | |
573 | + buffer->write(toc_table[track].is_audio ? 0x00 : 0x04); | |
540 | 574 | } |
541 | 575 | break; |
542 | 576 | } |
@@ -565,10 +599,17 @@ bool SCSI_CDROM::read_buffer(int length) | ||
565 | 599 | return false; |
566 | 600 | } |
567 | 601 | uint32_t offset = (uint32_t)(position % 2352); |
568 | - | |
569 | - if(fio_img->Fseek((long)position, FILEIO_SEEK_SET) != 0) { | |
570 | - set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_SEEKERR | |
571 | - return false; | |
602 | + | |
603 | + if(is_cue) { | |
604 | + if(fio_img->Fseek(((long)position - (long)(toc_table[current_track].lba_offset * 2352)), FILEIO_SEEK_SET) != 0) { | |
605 | + set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_SEEKERR | |
606 | + return false; | |
607 | + } | |
608 | + } else { | |
609 | + if(fio_img->Fseek((long)position, FILEIO_SEEK_SET) != 0) { | |
610 | + set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_SEEKERR | |
611 | + return false; | |
612 | + } | |
572 | 613 | } |
573 | 614 | while(length > 0) { |
574 | 615 | uint8_t tmp_buffer[SCSI_BUFFER_SIZE]; |
@@ -636,14 +677,16 @@ int hexatoi(const char *string) | ||
636 | 677 | return value; |
637 | 678 | } |
638 | 679 | |
680 | +#include <string> | |
681 | + | |
639 | 682 | bool SCSI_CDROM::open_cue_file(const _TCHAR* file_path) |
640 | 683 | { |
684 | + std::string line_buf; | |
685 | + std::string line_buf_shadow; | |
686 | + std::string image_tmp_data_path; | |
641 | 687 | |
642 | - _TCHAR line_buf[2048]; | |
643 | - _TCHAR line_buf_shadow[2048]; | |
644 | 688 | _TCHAR full_path_cue[_MAX_PATH]; |
645 | - _TCHAR image_tmp_data_path[_MAX_PATH]; | |
646 | - int ptr; | |
689 | + size_t ptr; | |
647 | 690 | int line_count = 0; |
648 | 691 | int slen; |
649 | 692 | int nr_current_track = 0; |
@@ -651,14 +694,24 @@ bool SCSI_CDROM::open_cue_file(const _TCHAR* file_path) | ||
651 | 694 | if(fio == NULL) return false; |
652 | 695 | |
653 | 696 | memset(full_path_cue, 0x00, sizeof(full_path_cue)); |
654 | - memset(image_tmp_data_path, 0x00, sizeof(image_tmp_data_path)); | |
697 | + image_tmp_data_path.clear(); | |
655 | 698 | |
656 | 699 | get_long_full_path_name(file_path, full_path_cue, sizeof(full_path_cue)); |
657 | 700 | |
658 | - _TCHAR *parent_dir = get_parent_dir(full_path_cue); | |
659 | - if(fio->Fopen(file_path, FILEIO_READ_ASCII)) { // ToDo: Support not ASCII cue file (i.e. SJIS/UTF8).20181118 K.O | |
660 | - memset(line_buf, 0x00, sizeof(line_buf)); | |
701 | + _TCHAR *parent_dir = get_parent_dir(full_path_cue); | |
702 | + | |
703 | + size_t _arg1_ptr; | |
704 | + size_t _arg2_ptr; | |
705 | + size_t _arg2_ptr_s; | |
706 | + size_t _arg3_ptr; | |
707 | + size_t _arg3_ptr_s; | |
661 | 708 | |
709 | + std::string _arg1; | |
710 | + std::string _arg2; | |
711 | + std::string _arg3; | |
712 | + | |
713 | + if(fio->Fopen(file_path, FILEIO_READ_ASCII)) { // ToDo: Support not ASCII cue file (i.e. SJIS/UTF8).20181118 K.O | |
714 | + line_buf.clear(); | |
662 | 715 | for(int i = 0; i < 100; i++) { |
663 | 716 | memset(&(track_data_path[i][0]), 0x00, _MAX_PATH * sizeof(_TCHAR)); |
664 | 717 | } |
@@ -666,162 +719,126 @@ bool SCSI_CDROM::open_cue_file(const _TCHAR* file_path) | ||
666 | 719 | bool is_eof = false; |
667 | 720 | int sptr = 0; |
668 | 721 | while(1) { |
669 | - memset(line_buf, 0x00, sizeof(line_buf)); | |
722 | + line_buf.clear(); | |
670 | 723 | int _np = 0; |
671 | 724 | _c = EOF; |
672 | 725 | do { |
673 | 726 | _c = fio->Fgetc(); |
674 | - if((_c == '\n') || (_c == EOF) || (_np >= 2048)) break; | |
675 | - if(_c != '\r') line_buf[_np++] = (_TCHAR)_c; | |
727 | + if((_c == '\0') || (_c == '\n') || (_c == EOF)) break;; | |
728 | + if(_c != '\r') line_buf.push_back((char)_c); | |
676 | 729 | } while(1); |
677 | 730 | if(_c == EOF) is_eof = true; |
678 | - slen = strlen(line_buf); | |
731 | + slen = (int)line_buf.length(); | |
679 | 732 | if(slen <= 0) goto _n_continue; |
680 | 733 | // Trim head of Space or TAB |
681 | 734 | ptr = 0; |
682 | 735 | sptr = 0; |
683 | - while((line_buf[ptr] == '\t') || (line_buf[ptr] == ' ')) { | |
684 | - ptr++; | |
685 | - if(ptr >= slen) break; | |
686 | - } | |
687 | - if(ptr > slen) { | |
736 | + // Tokenize | |
737 | + _arg1.clear(); | |
738 | + _arg2.clear(); | |
739 | + _arg3.clear(); | |
740 | + | |
741 | + ptr = line_buf.find_first_not_of((const char*)" \t"); | |
742 | + if(ptr == std::string::npos) { | |
688 | 743 | goto _n_continue; |
689 | 744 | } |
690 | - memset(line_buf_shadow, 0x00, sizeof(line_buf_shadow)); | |
691 | - while((line_buf[ptr] != ' ') && (line_buf[ptr] != '\0') && (line_buf[ptr] != '\t')) { | |
692 | - line_buf_shadow[sptr++] = (_TCHAR)(toupper(line_buf[ptr++])); | |
693 | - if(ptr >= slen) break; | |
694 | - } | |
695 | - if((ptr > slen) || (sptr == 0)) { | |
696 | - goto _n_continue; | |
745 | + // Token1 | |
746 | + line_buf_shadow = line_buf.substr(ptr); | |
747 | + | |
748 | + _arg1_ptr = line_buf_shadow.find_first_of((const char *)" \t"); | |
749 | + _arg1 = line_buf_shadow.substr(0, _arg1_ptr); | |
750 | + _arg2 = line_buf_shadow.substr(_arg1_ptr); | |
751 | + std::transform(_arg1.begin(), _arg1.end(), _arg1.begin(), | |
752 | + [](unsigned char c) -> unsigned char{ return std::toupper(c); }); | |
753 | + | |
754 | + _arg2_ptr = _arg2.find_first_not_of((const char *)" \t"); | |
755 | + | |
756 | + if(_arg2_ptr != std::string::npos) { | |
757 | + _arg2 = _arg2.substr(_arg2_ptr); | |
697 | 758 | } |
698 | - // Command | |
699 | - if(strcmp(line_buf_shadow, "REM") == 0) { | |
759 | + | |
760 | + if(_arg1 == "REM") { | |
700 | 761 | // REM |
701 | 762 | goto _n_continue; |
702 | - } else if(strcmp(line_buf_shadow, "FILE") == 0) { | |
703 | - while((line_buf[ptr] != '"') && (line_buf[ptr] != '\0')) { | |
704 | - ptr++; | |
705 | - if(ptr > slen) break; | |
706 | - } | |
707 | - if(ptr >= slen) { | |
708 | - goto _n_continue; | |
709 | - } | |
710 | - // ARG1 | |
711 | - ptr++; | |
712 | - if(ptr >= slen) goto _n_continue; | |
713 | - sptr = 0; | |
714 | - _TCHAR _tmps[_MAX_PATH]; | |
715 | - memset(_tmps, 0x00, sizeof(_tmps)); | |
716 | - while((line_buf[ptr] != '"') && (line_buf[ptr] != '\0')) { | |
717 | - _tmps[sptr++] = line_buf[ptr++]; | |
718 | - if(ptr >= slen) break; | |
719 | - } | |
720 | - if(ptr >= slen) { | |
721 | - goto _n_continue; | |
722 | - } | |
723 | - if((sptr != 0) && (line_buf[ptr] == '"')) { | |
724 | - strncpy(image_tmp_data_path, parent_dir, _MAX_PATH); | |
725 | - strncat(image_tmp_data_path, _tmps, _MAX_PATH - 1); | |
726 | - #ifdef _CDROM_DEBUG_LOG | |
727 | - this->out_debug_log(_T("**FILE %s\n"), image_tmp_data_path); | |
728 | - #endif | |
729 | -// goto _n_continue; | |
730 | - } | |
763 | + } else if(_arg1 == "FILE") { | |
764 | + _arg2_ptr = _arg2.find_first_of((const char *)"\"") + 1; | |
765 | + if(_arg2_ptr == std::string::npos) goto _n_continue; | |
766 | + | |
767 | + _arg2 = _arg2.substr(_arg2_ptr); | |
768 | + _arg3_ptr = _arg2.find_first_of((const char *)"\""); | |
769 | + if(_arg3_ptr == std::string::npos) goto _n_continue; | |
770 | + _arg2 = _arg2.substr(0, _arg3_ptr); | |
771 | + | |
772 | + image_tmp_data_path.clear(); | |
773 | + image_tmp_data_path = std::string(parent_dir); | |
774 | + image_tmp_data_path.append(_arg2); | |
775 | + | |
776 | + #ifdef _CDROM_DEBUG_LOG | |
777 | + this->out_debug_log(_T("**FILE %s\n"), image_tmp_data_path.c_str()); | |
778 | + #endif | |
731 | 779 | goto _n_continue; // ToDo: Check ARG2 (BINARY etc..) 20181118 K.O |
732 | - } else if(strcmp(line_buf_shadow, "TRACK") == 0) { | |
733 | - while((line_buf[ptr] == ' ') || (line_buf[ptr] == '\t')) { | |
734 | - ptr++; | |
735 | - if(ptr >= slen) break; | |
736 | - } | |
737 | - if(ptr > slen) goto _n_continue; | |
738 | - int _nr_num = 0; | |
739 | - _TCHAR _tmps[128]; | |
740 | - int _n = 0; | |
741 | - memset(_tmps, 0x00, sizeof(_tmps)); | |
742 | - while((line_buf[ptr] != ' ') && (line_buf[ptr] != '\t') && (line_buf[ptr] != '\0')) { | |
743 | - if(ptr >= slen) break; | |
744 | - _tmps[_n++] = line_buf[ptr++]; | |
745 | - } | |
746 | - _nr_num = atoi(_tmps); | |
747 | - //ptr++; | |
780 | + } else if(_arg1 == "TRACK") { | |
781 | + _arg2_ptr_s = _arg2.find_first_of((const char *)" \t"); | |
782 | + | |
783 | + _arg3 = _arg2.substr(_arg2_ptr_s); | |
784 | + _arg2 = _arg2.substr(0, _arg2_ptr_s); | |
785 | + _arg3_ptr = _arg3.find_first_not_of((const char *)" \t"); | |
786 | + int _nr_num = atoi(_arg2.c_str()); | |
787 | + | |
748 | 788 | // Set image file |
749 | - if((_nr_num > 0) && (_nr_num < 100)) { | |
789 | + if((_nr_num > 0) && (_nr_num < 100) && (_arg3_ptr != std::string::npos)) { | |
750 | 790 | nr_current_track = _nr_num; |
751 | - if(strlen(image_tmp_data_path) > 0) { | |
752 | - strncpy(track_data_path[_nr_num - 1], image_tmp_data_path, _MAX_PATH); | |
753 | - // ARG2 | |
754 | - while((line_buf[ptr] == ' ') || (line_buf[ptr] == '\t')) { | |
755 | - ptr++; | |
756 | - if(ptr >= slen) break; | |
757 | - } | |
758 | - memset(_tmps, 0x00, sizeof(_tmps)); | |
759 | - for(int i = 0; i < 127; i++) { | |
760 | - if((line_buf[ptr] == '\0') || (line_buf[ptr] == ' ') || | |
761 | - (line_buf[ptr] == '\n') || (line_buf[ptr] == '\t')) break; | |
762 | - _tmps[i] = (_TCHAR)(toupper(line_buf[ptr++])); | |
763 | - if(ptr > slen) break; | |
764 | - } | |
765 | - | |
766 | - toc_table[nr_current_track - 1].is_audio = false; | |
767 | - toc_table[nr_current_track - 1].index0 = 0; | |
768 | - toc_table[nr_current_track - 1].index1 = 0; | |
769 | - toc_table[nr_current_track - 1].pregap = 0; | |
791 | + _arg3 = _arg3.substr(_arg3_ptr); | |
792 | + | |
793 | + memset(track_data_path[_nr_num - 1], 0x00, sizeof(_TCHAR) * _MAX_PATH); | |
794 | + strncpy((char *)(track_data_path[_nr_num - 1]), image_tmp_data_path.c_str(), _MAX_PATH); | |
795 | + | |
796 | + _arg3_ptr_s = _arg3.find_first_of((const char *)" \t\n"); | |
797 | + _arg3.substr(0, _arg3_ptr_s); | |
798 | + | |
799 | + std::transform(_arg3.begin(), _arg3.end(), _arg3.begin(), | |
800 | + [](unsigned char c) -> unsigned char{ return std::toupper(c); }); | |
801 | + | |
802 | + toc_table[nr_current_track].is_audio = false; | |
803 | + toc_table[nr_current_track].index0 = 0; | |
804 | + toc_table[nr_current_track].index1 = 0; | |
805 | + toc_table[nr_current_track].pregap = 0; | |
770 | 806 | |
771 | - if(strcmp(_tmps, "AUDIO") == 0) { | |
772 | - toc_table[nr_current_track - 1].is_audio = true; | |
773 | - } else if(strcmp(_tmps, "MODE1/2352") == 0) { | |
774 | - toc_table[nr_current_track - 1].is_audio = false; | |
775 | - } else { | |
776 | - // ToDo: Another data mode 20181118 K.Ohta | |
777 | - memset(track_data_path[_nr_num - 1], 0x00, _MAX_PATH * sizeof(_TCHAR)); | |
778 | - } | |
779 | - if(track_num < _nr_num) track_num = _nr_num; | |
807 | + if(_arg3.compare("AUDIO") == 0) { | |
808 | + toc_table[nr_current_track].is_audio = true; | |
809 | + } else if(_arg3.compare("MODE1/2352") == 0) { | |
810 | + toc_table[nr_current_track].is_audio = false; | |
811 | + } else { | |
812 | + // ToDo: another type | |
780 | 813 | } |
814 | + if(track_num < (_nr_num + 1)) track_num = _nr_num + 1; | |
781 | 815 | } else { |
782 | 816 | // ToDo: 20181118 K.Ohta |
783 | 817 | nr_current_track = 0; |
784 | 818 | } |
785 | 819 | goto _n_continue; |
786 | - } else if(strcmp(line_buf_shadow, "INDEX") == 0) { | |
787 | - | |
820 | + } else if(_arg1 == "INDEX") { | |
821 | + | |
788 | 822 | if((nr_current_track > 0) && (nr_current_track < 100)) { |
789 | - while((line_buf[ptr] == '\t') || (line_buf[ptr] == ' ')) { | |
790 | - ptr++; | |
791 | - if(ptr >= slen) break; | |
792 | - } | |
793 | - // ARG1 | |
794 | - int index_type = 0; | |
795 | - _TCHAR _tmps[32]; | |
796 | - memset(_tmps, 0x00, sizeof(_tmps)); | |
797 | - for(int i = 0; i < 31; i++) { | |
798 | - if((line_buf[ptr] < '0') || (line_buf[ptr] > '9')) break; | |
799 | - _tmps[i] = line_buf[ptr++]; | |
800 | - if(ptr > slen) break; | |
801 | - } | |
802 | - index_type = atoi(_tmps); | |
803 | - if(ptr >= slen) goto _n_continue; | |
823 | + _arg2_ptr_s = _arg2.find_first_of((const char *)" \t"); | |
824 | + if(_arg2_ptr_s == std::string::npos) goto _n_continue; | |
804 | 825 | |
805 | - // ARG2 | |
806 | - while((line_buf[ptr] == '\t') || (line_buf[ptr] == ' ')) { | |
807 | - ptr++; | |
808 | - if(ptr > slen) break; | |
809 | - } | |
810 | - memset(_tmps, 0x00, sizeof(_tmps)); | |
811 | - for(int i = 0; i < 31; i++) { | |
812 | - if((line_buf[ptr] < '0') || (line_buf[ptr] > '9')) { | |
813 | - if(line_buf[ptr] != ':') break; | |
814 | - } | |
815 | - _tmps[i] = line_buf[ptr++]; | |
816 | - if(ptr > slen) break; | |
817 | - } | |
826 | + _arg3 = _arg2.substr(_arg2_ptr_s); | |
827 | + _arg2 = _arg2.substr(0, _arg2_ptr_s); | |
828 | + _arg3_ptr = _arg3.find_first_not_of((const char *)" \t"); | |
829 | + if(_arg3_ptr == std::string::npos) goto _n_continue; | |
830 | + | |
831 | + _arg3 = _arg3.substr(_arg3_ptr); | |
832 | + _arg3_ptr_s = _arg3.find_first_of((const char *)" \t"); | |
833 | + _arg3.substr(0, _arg3_ptr_s); | |
834 | + int index_type = atoi(_arg2.c_str()); | |
818 | 835 | |
819 | 836 | switch(index_type) { |
820 | 837 | case 0: |
821 | - toc_table[nr_current_track - 1].index0 = get_frames_from_msf(_tmps); | |
838 | + toc_table[nr_current_track].index0 = get_frames_from_msf(_arg3.c_str()); | |
822 | 839 | break; |
823 | 840 | case 1: |
824 | - toc_table[nr_current_track - 1].index1 = get_frames_from_msf(_tmps); | |
841 | + toc_table[nr_current_track].index1 = get_frames_from_msf(_arg3.c_str()); | |
825 | 842 | break; |
826 | 843 | default: |
827 | 844 | break; |
@@ -830,23 +847,12 @@ bool SCSI_CDROM::open_cue_file(const _TCHAR* file_path) | ||
830 | 847 | } else { |
831 | 848 | goto _n_continue; |
832 | 849 | } |
833 | - } else if(strcmp(line_buf_shadow, "PREGAP") == 0) { | |
850 | + } else if(_arg1 == "PREGAP") { | |
834 | 851 | if((nr_current_track > 0) && (nr_current_track < 100)) { |
835 | - while((line_buf[ptr] == '\t') || (line_buf[ptr] == ' ')) { | |
836 | - ptr++; | |
837 | - if(ptr >= slen) break; | |
838 | - } | |
839 | - // ARG1 | |
840 | - _TCHAR _tmps[32]; | |
841 | - memset(_tmps, 0x00, sizeof(_tmps)); | |
842 | - for(int i = 0; i < 31; i++) { | |
843 | - if((line_buf[ptr] < '0') || (line_buf[ptr] > '9')) { | |
844 | - if(line_buf[ptr] != ':') break; | |
845 | - } | |
846 | - _tmps[i] = line_buf[ptr++]; | |
847 | - if(ptr >= slen) goto _n_continue; | |
848 | - } | |
849 | - toc_table[nr_current_track - 1].pregap = get_frames_from_msf(_tmps); | |
852 | + _arg2_ptr_s = _arg2.find_first_of((const char *)" \t"); | |
853 | + _arg2 = _arg2.substr(0, _arg2_ptr_s - 1); | |
854 | + | |
855 | + toc_table[nr_current_track].pregap = get_frames_from_msf(_arg2.c_str()); | |
850 | 856 | goto _n_continue; |
851 | 857 | } else { |
852 | 858 | goto _n_continue; |
@@ -854,44 +860,54 @@ bool SCSI_CDROM::open_cue_file(const _TCHAR* file_path) | ||
854 | 860 | } |
855 | 861 | _n_continue: |
856 | 862 | if(is_eof) break; |
857 | - memset(line_buf, 0x00, sizeof(line_buf)); | |
863 | + line_buf.clear(); | |
858 | 864 | continue; |
859 | 865 | } |
860 | 866 | // Finish |
861 | 867 | max_logical_block = 0; |
862 | 868 | if(track_num > 0) { |
863 | 869 | toc_table[0].lba_offset = 0; |
864 | - for(int i = 0; i < track_num; i++) { | |
865 | - | |
866 | - if(toc_table[i].index0 == 0) { | |
867 | - toc_table[i].index0 = toc_table[i].index1 - toc_table[i].pregap; | |
868 | - } else if(toc_table[i].pregap == 0) { | |
869 | - toc_table[i].pregap = toc_table[i].index1 - toc_table[i].index0; | |
870 | - } | |
870 | + toc_table[0].lba_size = 0; | |
871 | + toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; | |
872 | + // P1: Calc | |
873 | + int _n = 0; | |
874 | + for(int i = 1; i < track_num; i++) { | |
875 | + | |
871 | 876 | if(fio_img->IsOpened()) { |
872 | 877 | fio_img->Fclose(); |
873 | 878 | } |
874 | - // ToDo: Support unreguler (!CDDA, i.e. MP3/WAV...) codec.20181118 K.O | |
875 | - int _n = 0; | |
876 | - toc_table[i].lba_offset = max_logical_block; | |
877 | - if(strlen(track_data_path[i]) > 0) { | |
878 | - if(fio_img->Fopen(track_data_path[i], FILEIO_READ_BINARY)) { | |
879 | + toc_table[i].index1 = toc_table[i].index1 + max_logical_block; | |
880 | + if(toc_table[i].index0 == 0) { | |
881 | + toc_table[i].index0 = toc_table[i].index1 - toc_table[i].pregap; | |
882 | + } else { | |
883 | + toc_table[i].index0 = toc_table[i].index0 + max_logical_block; | |
884 | + if(toc_table[i].pregap == 0) { | |
885 | + toc_table[i].pregap = toc_table[i].index1 - toc_table[i].index0; | |
886 | + } | |
887 | + } | |
888 | + if(strlen(track_data_path[i - 1]) > 0) { | |
889 | + if(fio_img->Fopen(track_data_path[i - 1], FILEIO_READ_BINARY)) { | |
879 | 890 | if((_n = fio_img->FileLength() / 2352) > 0) { |
880 | 891 | max_logical_block += _n; |
881 | 892 | } |
882 | 893 | } |
883 | 894 | } |
895 | + toc_table[i].lba_size = _n; | |
896 | + toc_table[i].lba_offset = max_logical_block - _n; | |
884 | 897 | |
898 | + | |
885 | 899 | #ifdef _CDROM_DEBUG_LOG |
886 | 900 | this->out_debug_log(_T("TRACK#%02d TYPE=%s PREGAP=%d INDEX0=%d INDEX1=%d LBA_SIZE=%d LBA_OFFSET=%d PATH=%s\n"), |
887 | - i + 1, (toc_table[i].is_audio) ? _T("AUDIO") : _T("MODE1/2352"), | |
901 | + i, (toc_table[i].is_audio) ? _T("AUDIO") : _T("MODE1/2352"), | |
888 | 902 | toc_table[i].pregap, toc_table[i].index0, toc_table[i].index1, |
889 | - _n, toc_table[i].lba_offset, track_data_path[i]); | |
903 | + toc_table[i].lba_size, toc_table[i].lba_offset, track_data_path[i - 1]); | |
890 | 904 | #endif |
891 | 905 | } |
892 | - //toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; | |
893 | - toc_table[track_num].index0 = toc_table[track_num].index1 = max_logical_block; | |
894 | - toc_table[track_num].lba_offset = max_logical_block; | |
906 | + toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; | |
907 | +// toc_table[track_num].index0 = toc_table[track_num].index1 = max_logical_block; | |
908 | +// toc_table[track_num].lba_offset = max_logical_block; | |
909 | +// toc_table[track_num].lba_size = 0; | |
910 | + | |
895 | 911 | } |
896 | 912 | fio->Fclose(); |
897 | 913 | } |
@@ -913,7 +929,7 @@ void SCSI_CDROM::open(const _TCHAR* file_path) | ||
913 | 929 | // 20181014 K.O |
914 | 930 | if(check_file_extension(file_path, _T(".cue"))) { |
915 | 931 | #if 1 |
916 | - is_cue = true; | |
932 | + is_cue = false; | |
917 | 933 | current_track = 0; |
918 | 934 | open_cue_file(file_path); |
919 | 935 | #else |
@@ -1042,12 +1058,19 @@ void SCSI_CDROM::open(const _TCHAR* file_path) | ||
1042 | 1058 | } |
1043 | 1059 | if(track_num != 0) { |
1044 | 1060 | toc_table[0].lba_offset = 0; |
1061 | + toc_table[0].pregap = 0; | |
1045 | 1062 | for(int i = 1; i < track_num; i++) { |
1046 | 1063 | toc_table[i].index0 = toc_table[i].index1 - toc_table[i].pregap; |
1047 | - toc_table[i].lba_offset = toc_table[i].index0; | |
1064 | + toc_table[i].lba_offset = toc_table[i].pregap; | |
1065 | + toc_table[i - 1].lba_size = toc_table[i].pregap - toc_table[i - 1].pregap; | |
1048 | 1066 | } |
1049 | 1067 | toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; |
1050 | 1068 | toc_table[track_num].index0 = toc_table[track_num].index1 = max_logical_block; |
1069 | + if(track_num > 0) { | |
1070 | + toc_table[track_num].lba_size = max_logical_block - toc_table[track_num - 1].lba_offset; | |
1071 | + } else { | |
1072 | + toc_table[track_num].lba_size = 0; | |
1073 | + } | |
1051 | 1074 | } else { |
1052 | 1075 | fio_img->Fclose(); |
1053 | 1076 | } |
@@ -1060,9 +1083,9 @@ void SCSI_CDROM::open(const _TCHAR* file_path) | ||
1060 | 1083 | #ifdef _SCSI_DEBUG_LOG |
1061 | 1084 | if(mounted()) { |
1062 | 1085 | for(int i = 0; i < track_num + 1; i++) { |
1063 | - uint32_t idx0_msf = lba_to_msf(i, toc_table[i].index0); | |
1064 | - uint32_t idx1_msf = lba_to_msf(i, toc_table[i].index1); | |
1065 | - uint32_t pgap_msf = lba_to_msf(i, toc_table[i].pregap); | |
1086 | + uint32_t idx0_msf = lba_to_msf(toc_table[i].index0); | |
1087 | + uint32_t idx1_msf = lba_to_msf(toc_table[i].index1); | |
1088 | + uint32_t pgap_msf = lba_to_msf(toc_table[i].pregap); | |
1066 | 1089 | this->out_debug_log(_T("Track%02d: Index0=%02x:%02x:%02x Index1=%02x:%02x:%02x PreGpap=%02x:%02x:%02x\n"), i + 1, |
1067 | 1090 | (idx0_msf >> 16) & 0xff, (idx0_msf >> 8) & 0xff, idx0_msf & 0xff, |
1068 | 1091 | (idx1_msf >> 16) & 0xff, (idx1_msf >> 8) & 0xff, idx1_msf & 0xff, |
@@ -27,6 +27,7 @@ protected: | ||
27 | 27 | struct { |
28 | 28 | uint32_t index0, index1, pregap; |
29 | 29 | uint32_t lba_offset; |
30 | + uint32_t lba_size; | |
30 | 31 | bool is_audio; |
31 | 32 | } toc_table[1024]; |
32 | 33 | bool is_cue; |
@@ -54,8 +55,8 @@ protected: | ||
54 | 55 | |
55 | 56 | bool open_cue_file(const _TCHAR *file_path); |
56 | 57 | void get_track_by_track_num(int track); |
57 | - uint32_t lba_to_msf(int trk, uint32_t lba); | |
58 | - uint32_t lba_to_msf_alt(int trk, uint32_t lba); | |
58 | + uint32_t lba_to_msf(uint32_t lba); | |
59 | + uint32_t lba_to_msf_alt(uint32_t lba); | |
59 | 60 | public: |
60 | 61 | SCSI_CDROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : SCSI_DEV(parent_vm, parent_emu) |
61 | 62 | { |