// copy AUDxPT - 2 to internal latch instantly
cdp->pt = cdp->lc - 2;
cdp->dsr = false;
+ setirq (nr, 1);
} else {
// normal hardware behavior: latch it after first DMA fetch comes
cdp->dsr = true;
cdp->have_dat = false;
cdp->losample = cdp->hisample = false;
#endif
- setirq (nr, 1);
+ if (!usehacks ())
+ setirq (nr, 10);
setdr (nr);
if (cdp->wlen != 1)
cdp->wlen = (cdp->wlen - 1) & 0xffff;
}
}
write_log (L"\n");
+ sys_command_close (unitnum);
}
- sys_command_close (unitnum);
}
}
if (isaudio) {
#include "sysconfig.h"
#include "sysdeps.h"
+#include <sys/timeb.h>
+
#include "options.h"
#include "blkdev.h"
#include "zfile.h"
#include "rp.h"
#endif
+#define FLAC__NO_DLL
+#include "FLAC/stream_decoder.h"
+
#define scsi_log write_log
#define CDDA_BUFFERS 6
+enum audenc { AUDENC_NONE, AUDENC_PCM, AUDENC_MP3, AUDENC_FLAC };
+
#define AUDIO_STATUS_NOT_SUPPORTED 0x00
#define AUDIO_STATUS_IN_PROGRESS 0x11
#define AUDIO_STATUS_PAUSED 0x12
int track;
int size;
int skipsize; // bytes to skip after each block
- int mp3;
+ audenc enctype;
+ int writeoffset;
int subcode;
};
return NULL;
}
+// WOHOO, library that supports virtual file access functions. Perfect!
+static void flac_metadata_callback (const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
+{
+ struct cdtoc *t = (struct cdtoc*)client_data;
+ if (t->data)
+ return;
+ if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
+ t->filesize = metadata->data.stream_info.total_samples * (metadata->data.stream_info.bits_per_sample / 8) * metadata->data.stream_info.channels;
+ }
+}
+static void flac_error_callback (const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
+{
+ return;
+}
+static FLAC__StreamDecoderWriteStatus flac_write_callback (const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
+{
+ struct cdtoc *t = (struct cdtoc*)client_data;
+ uae_u16 *p = (uae_u16*)(t->data + t->writeoffset);
+ int size = 4;
+ for (int i = 0; i < frame->header.blocksize && t->writeoffset < t->filesize - size; i++, t->writeoffset += size) {
+ *p++ = (FLAC__int16)buffer[0][i];
+ *p++ = (FLAC__int16)buffer[1][i];
+ }
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+}
+static FLAC__StreamDecoderReadStatus file_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
+{
+ struct cdtoc *t = (struct cdtoc*)client_data;
+ if (zfile_ftell (t->handle) >= zfile_size (t->handle))
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ return zfile_fread (buffer, *bytes, 1, t->handle) ? FLAC__STREAM_DECODER_READ_STATUS_CONTINUE : FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+}
+static FLAC__StreamDecoderSeekStatus file_seek_callback (const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
+{
+ struct cdtoc *t = (struct cdtoc*)client_data;
+ zfile_fseek (t->handle, absolute_byte_offset, SEEK_SET);
+ return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
+}
+static FLAC__StreamDecoderTellStatus file_tell_callback (const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
+{
+ struct cdtoc *t = (struct cdtoc*)client_data;
+ *absolute_byte_offset = zfile_ftell (t->handle);
+ return FLAC__STREAM_DECODER_TELL_STATUS_OK;
+}
+static FLAC__StreamDecoderLengthStatus file_len_callback (const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
+{
+ struct cdtoc *t = (struct cdtoc*)client_data;
+ *stream_length = zfile_size (t->handle);
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
+}
+static FLAC__bool file_eof_callback (const FLAC__StreamDecoder *decoder, void *client_data)
+{
+ struct cdtoc *t = (struct cdtoc*)client_data;
+ return zfile_ftell (t->handle) >= zfile_size (t->handle);
+}
+
+static void flac_get_size (struct cdtoc *t)
+{
+ FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new ();
+ if (decoder) {
+ FLAC__stream_decoder_set_md5_checking (decoder, false);
+ int init_status = FLAC__stream_decoder_init_stream (decoder,
+ &file_read_callback, &file_seek_callback, &file_tell_callback,
+ &file_len_callback, &file_eof_callback,
+ &flac_write_callback, &flac_metadata_callback, &flac_error_callback, t);
+ FLAC__stream_decoder_process_until_end_of_metadata (decoder);
+ FLAC__stream_decoder_delete (decoder);
+ }
+}
+static uae_u8 *flac_get_data (struct cdtoc *t)
+{
+ if (t->data)
+ return t->data;
+ write_log (L"FLAC: unpacking '%s'..\n", zfile_getname (t->handle));
+ t->data = xcalloc (uae_u8,t->filesize + 2352);
+ t->writeoffset = 0;
+ FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new ();
+ if (decoder) {
+ FLAC__stream_decoder_set_md5_checking (decoder, false);
+ int init_status = FLAC__stream_decoder_init_stream (decoder,
+ &file_read_callback, &file_seek_callback, &file_tell_callback,
+ &file_len_callback, &file_eof_callback,
+ &flac_write_callback, &flac_metadata_callback, &flac_error_callback, t);
+ FLAC__stream_decoder_process_until_end_of_stream (decoder);
+ FLAC__stream_decoder_delete (decoder);
+ write_log (L"FLAC: %s unpacked\n", zfile_getname (t->handle));
+ }
+ return t->data;
+}
+
#ifdef _WIN32
static HWAVEOUT cdda_wavehandle;
wav.wFormatTag = WAVE_FORMAT_PCM;
mmr = waveOutOpen (&cdda_wavehandle, WAVE_MAPPER, &wav, 0, 0, WAVE_ALLOWSYNC | WAVE_FORMAT_DIRECT);
if (mmr != MMSYSERR_NOERROR) {
- write_log (L"CDDA: wave open %d\n", mmr);
+ write_log (L"IMAGE CDDA: wave open %d\n", mmr);
cdda_closewav ();
return 0;
}
if (oldplay != cdu->cdda_play) {
struct cdtoc *t;
int sector;
+ struct _timeb tb;
+ _ftime (&tb);
cdda_pos = cdu->cdda_start;
oldplay = cdu->cdda_play;
cdu->cd_last_pos = cdda_pos;
} else {
write_log (L"IMAGE CDDA: playing from %d to %d, track %d ('%s', offset %d, secoffset %d)\n",
cdu->cdda_start, cdu->cdda_end, t->track, t->fname, t->offset, sector);
- if (t->mp3 && !t->data) {
- if (!mp3dec) {
- try {
- mp3dec = new mp3decoder();
- } catch (exception) { };
+ if (!t->data) {
+ if (t->enctype == AUDENC_MP3) {
+ if (!mp3dec) {
+ try {
+ mp3dec = new mp3decoder();
+ } catch (exception) { };
+ }
+ if (mp3dec)
+ t->data = mp3dec->get (t->handle, t->filesize);
+ } else if (t->enctype == AUDENC_FLAC) {
+ flac_get_data (t);
}
- if (mp3dec)
- t->data = mp3dec->get (t->handle, t->filesize);
}
}
- firstloops = 25;
- while (cdu->cdda_paused && cdu->cdda_play > 0)
+ int millis;
+ struct _timeb tb2;
+ _ftime (&tb2);
+ millis = (tb2.time - tb.time) * 1000;
+ if (tb2.millitm >= tb.millitm)
+ millis += tb2.millitm - tb.millitm;
+ else
+ millis += 1000 - tb.millitm + tb2.millitm;
+ firstloops = 150 - millis * 75 / 1000;
+ while (cdu->cdda_paused && cdu->cdda_play > 0) {
Sleep (10);
+ firstloops = -1;
+ }
+ if (firstloops > 0)
+ firstloops /= num_sectors;
}
while (!(whdr[bufnum].dwFlags & WHDR_DONE)) {
if (t->handle && !(t->ctrl & 4)) {
uae_u8 *dst = px[bufnum] + cnt * t->size;
int totalsize = t->size + t->skipsize;
- if (t->mp3 && t->data) {
- memcpy (dst, t->data + sector * totalsize + t->offset, t->size);
- } else if (!t->mp3) {
+ if ((t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC) && t->data) {
+ if (t->filesize >= sector * totalsize + t->offset + t->size)
+ memcpy (dst, t->data + sector * totalsize + t->offset, t->size);
+ } else if (t->enctype == AUDENC_PCM) {
if (sector * totalsize + t->offset + totalsize < t->filesize) {
zfile_fseek (t->handle, sector * totalsize + t->offset, SEEK_SET);
zfile_fread (dst, t->size, 1, t->handle);
if (!cdu)
return 0;
struct cdtoc *t = findtoc (cdu, §or);
- int offset;
if (!t || t->handle == NULL)
return 0;
cdda_stop (cdu);
if (sectorsize > 0) {
- offset = 0;
if (sectorsize == 2352 && t->size == 2048) {
// 2048 -> 2352
- memset (data, 0, 16);
- zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
- zfile_fread (data + 16, t->size, size, t->handle);
- encode_l2 (data, sector + 150);
+ while (size-- > 0) {
+ memset (data, 0, 16);
+ zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
+ zfile_fread (data + 16, t->size, 1, t->handle);
+ encode_l2 (data, sector + 150);
+ sector++;
+ data += sectorsize;
+ }
+ } else if (sectorsize == 2048 && t->size == 2352) {
+ // 2352 -> 2048
+ while (size-- > 0) {
+ zfile_fseek (t->handle, t->offset + sector * t->size + 16, SEEK_SET);
+ zfile_fread (data, sectorsize, 1, t->handle);
+ sector++;
+ data += sectorsize;
+ }
} else if (sectorsize == 2336 && t->size == 2352) {
// 2352 -> 2336
- offset = 16;
- memset (data, 0, offset);
- zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
- zfile_fread (data, sectorsize, size, t->handle);
+ while (size-- > 0) {
+ zfile_fseek (t->handle, t->offset + sector * t->size + 16, SEEK_SET);
+ zfile_fread (data, sectorsize, 1, t->handle);
+ sector++;
+ data += sectorsize;
+ }
} else if (sectorsize == t->size) {
// no change
zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
zfile_fread (data, sectorsize, size, t->handle);
+ sector += size;
}
cdu->cd_last_pos = sector;
ret = sectorsize * size;
return ret;
}
+// this only supports 2048 byte sectors
static int command_read (int unitnum, uae_u8 *data, int sector, int size)
{
struct cdunit *cdu = unitisopen (unitnum);
if (!t || t->handle == NULL)
return NULL;
cdda_stop (cdu);
- offset = 0;
- if (t->size > 2048)
+ if (t->size == 2848) {
+ int offset = 0;
+ zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
+ zfile_fread (data, size, 2048, t->handle);
+ sector += size;
+ } else {
offset = 16;
- zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
- zfile_fread (data, size, 2048, t->handle);
+ while (size-- > 0) {
+ zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
+ zfile_fread (data, size, 2048, t->handle);
+ data += 2048;
+ sector++;
+ }
+ }
cdu->cd_last_pos = sector;
return 1;
}
goto end;
head = (MDS_Header*)mds;
- if (!memcmp (&head, MEDIA_DESCRIPTOR, strlen (MEDIA_DESCRIPTOR) - 1))
+ if (!memcmp (&head, MEDIA_DESCRIPTOR, strlen (MEDIA_DESCRIPTOR)))
goto end;
if (head->version[0] != 1) {
- write_log (L"unsupported version %d, only v.1 supported\n", head->version[0]);
+ write_log (L"unsupported MDS version %d, only v.1 supported\n", head->version[0]);
goto end;
}
int tracknum, index0, pregap;
int offset, secoffset, newfile;
TCHAR *fname, *fnametype;
+ audenc fnametypeid;
int ctrl;
mp3decoder *mp3dec = NULL;
ctrl = 0;
index0 = -1;
pregap = 0;
+ fnametypeid = AUDENC_NONE;
write_log (L"CUE TOC: '%s'\n", img);
for (;;) {
xfree (fname);
fname = my_strdup (nextstring (&p));
fnametype = nextstring (&p);
+ fnametypeid = AUDENC_NONE;
if (!fnametype)
break;
- if (_tcsicmp (fnametype, L"BINARY") && _tcsicmp (fnametype, L"WAVE") && _tcsicmp (fnametype, L"MP3")) {
+ if (_tcsicmp (fnametype, L"BINARY") && _tcsicmp (fnametype, L"WAVE") && _tcsicmp (fnametype, L"MP3") && _tcsicmp (fnametype, L"FLAC")) {
write_log (L"CUE: unknown file type '%s' ('%s')\n", fnametype, fname);
}
+ if (!_tcsicmp (fnametype, L"WAVE"))
+ fnametypeid = AUDENC_PCM;
+ else if (!_tcsicmp (fnametype, L"MP3"))
+ fnametypeid = AUDENC_MP3;
+ else if (!_tcsicmp (fnametype, L"FLAC"))
+ fnametypeid = AUDENC_FLAC;
offset = 0;
newfile = 1;
ctrl = 0;
}
if (!secoffset)
t->offset = offset * t->size;
- if (!_tcsicmp (fnametype, L"WAVE") && t->handle) {
+ if (fnametypeid == AUDENC_PCM && t->handle) {
struct zfile *zf = t->handle;
uae_u8 buf[16] = { 0 };
zfile_fread (buf, 12, 1, zf);
}
t->offset += zfile_ftell (zf);
t->filesize = size;
+ t->enctype = fnametypeid;
}
- } else if (!_tcsicmp (fnametype, L"MP3") && t->handle) {
+ } else if (fnametypeid == AUDENC_MP3 && t->handle) {
if (!mp3dec) {
try {
mp3dec = new mp3decoder();
t->offset = 0;
t->filesize = mp3dec->getsize (t->handle);
if (t->filesize)
- t->mp3 = 1;
+ t->enctype = fnametypeid;
}
+ } else if (fnametypeid == AUDENC_FLAC && t->handle) {
+ flac_get_size (t);
+ if (t->filesize)
+ t->enctype = fnametypeid;
}
}
}
write_log (L"%7d %02d:%02d:%02d",
t->address, (msf >> 16) & 0xff, (msf >> 8) & 0xff, (msf >> 0) & 0xff);
if (i < cdu->tracks)
- write_log (L" %s %x %10d %s", (t->ctrl & 4) ? L"DATA " : (t->subcode ? L"CDA+SUB" : L"CDA "),
- t->ctrl, t->offset, t->handle == NULL ? L"[FILE ERROR]" : L"");
+ write_log (L" %s %x %10d %10d %s", (t->ctrl & 4) ? L"DATA " : (t->subcode ? L"CDA+SUB" : L"CDA "),
+ t->ctrl, t->offset, t->filesize, t->handle == NULL ? L"[FILE ERROR]" : L"");
write_log (L"\n");
if (i < cdu->tracks)
write_log (L" - %s\n", t->fname);
- if (t->handle)
+ if (t->handle && !t->filesize)
t->filesize = zfile_size (t->handle);
}
} else {
- xcolnr tmp = colors_for_drawing.acolors[0];
- colors_for_drawing.acolors[0] = getxcolor (0);
+ int tmp = hposendblank;
+ hposendblank = 1;
fill_line ();
do_flush_line (gfx_ypos);
- colors_for_drawing.acolors[0] = tmp;
+ hposendblank = tmp;
}
}
*/
#define UAEMAJOR 2
-#define UAEMINOR 2
-#define UAESUBREV 1
+#define UAEMINOR 3
+#define UAESUBREV 0
typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang;
return 1;
}
+
+typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER {
+ SCSI_PASS_THROUGH_DIRECT spt;
+ ULONG Filler;
+ UCHAR SenseBuf[32];
+} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
+
+static int do_raw_scsi (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *cmd, int cmdlen, uae_u8 *data, int datalen)
+{
+ DWORD status, returned;
+ SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
+ uae_u8 *p = ciw->tempbuffer;
+ if (!open_createfile (ciw, 1))
+ return 0;
+ memset (&swb, 0, sizeof (swb));
+ memcpy (swb.spt.Cdb, cmd, cmdlen);
+ swb.spt.Length = sizeof (SCSI_PASS_THROUGH);
+ swb.spt.CdbLength = cmdlen;
+ swb.spt.DataIn = SCSI_IOCTL_DATA_IN;
+ swb.spt.DataTransferLength = IOCTL_DATA_BUFFER;
+ swb.spt.DataBuffer = p;
+ memset (p, 0, IOCTL_DATA_BUFFER);
+ swb.spt.TimeOutValue = 80 * 60;
+ swb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, SenseBuf);
+ swb.spt.SenseInfoLength = 32;
+ seterrormode (ciw);
+ status = DeviceIoControl (ciw->h, IOCTL_SCSI_PASS_THROUGH_DIRECT,
+ &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
+ &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
+ &returned, NULL);
+ reseterrormode (ciw);
+ if (!status) {
+ DWORD err = GetLastError ();
+ write_log (L"IOCTL_RAW_SCSI unit %d, CMD=%d, ERR=%d ", unitnum, cmd[0], err);
+ return 0;
+ }
+ int tlen = swb.spt.DataTransferLength > datalen ? datalen : swb.spt.DataTransferLength;
+ memcpy (data, p, tlen);
+ return tlen;
+}
+
+static int spti_inquiry (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data)
+{
+ uae_u8 cmd[6] = { 0x12,0,0,0,36,0 }; /* INQUIRY */
+ int len = sizeof cmd;
+
+ do_raw_scsi (ciw, unitnum, cmd, len, data, 256);
+ return 1;
+}
+
+static int spti_read (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data, int sector, int sectorsize)
+{
+ uae_u8 cmd[12] = { 0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
+ int tlen = sectorsize;
+
+ if (sectorsize == 2048 || sectorsize == 2336 || sectorsize == 2328) {
+ cmd[9] |= 1 << 4; // userdata
+ } else if (sectorsize >= 2352) {
+ cmd[9] |= 1 << 4; // userdata
+ cmd[9] |= 1 << 3; // EDC&ECC
+ cmd[9] |= 1 << 7; // sync
+ cmd[9] |= 3 << 5; // header code
+ if (sectorsize > 2352) {
+ cmd[10] |= 1; // RAW P-W
+ }
+ if (sectorsize > 2352 + SUB_CHANNEL_SIZE) {
+ cmd[9] |= 0x2 << 1; // C2
+ }
+ }
+ ciw->cd_last_pos = sector;
+ cmd[3] = (uae_u8)(sector >> 16);
+ cmd[4] = (uae_u8)(sector >> 8);
+ cmd[5] = (uae_u8)(sector >> 0);
+ if (unitnum >= 0)
+ gui_flicker_led (LED_CD, unitnum, 1);
+ int len = sizeof cmd;
+ return do_raw_scsi (ciw, unitnum, cmd, len, data, tlen);
+}
+
+extern void encode_l2 (uae_u8 *p, int address);
+
+static int read_block (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data, int sector, int size, int sectorsize)
+{
+ int forcexp = 0;
+ RAW_READ_INFO rri;
+ DWORD len;
+ uae_u8 *p = ciw->tempbuffer;
+ int ret;
+ int xp = forcexp || (os_winxp && !os_vista) ? 1 : 0;
+
+ if (!open_createfile (ciw, xp))
+ return 0;
+ ret = 0;
+ while (size-- > 0) {
+ seterrormode (ciw);
+ rri.DiskOffset.QuadPart = sector * 2048;
+ rri.SectorCount = 1;
+ rri.TrackMode = (sectorsize > 2352 + 96) ? RawWithC2AndSubCode : RawWithSubCode;
+ len = sectorsize;
+ memset (p, 0, sectorsize);
+ if (!forcexp && DeviceIoControl (ciw->h, IOCTL_CDROM_RAW_READ, &rri, sizeof rri, p, IOCTL_DATA_BUFFER, &len, NULL)) {
+ reseterrormode (ciw);
+ if (data) {
+ if (sectorsize >= 2352) {
+ memcpy (data, p, sectorsize);
+ data += sectorsize;
+ ret += sectorsize;
+ } else {
+ memcpy (data, p + 16, sectorsize);
+ data += sectorsize;
+ ret += sectorsize;
+ }
+ }
+ ciw->cd_last_pos = sector;
+ } else if (xp) {
+ int len = spti_read (ciw, unitnum, data, sector, sectorsize);
+ if (len) {
+ if (data) {
+ if (sectorsize >= 2352) {
+ memcpy (data, p, sectorsize);
+ data += sectorsize;
+ ret += sectorsize;
+ } else {
+ memcpy (data, p + 16, sectorsize);
+ data += sectorsize;
+ ret += sectorsize;
+ }
+ }
+ ciw->cd_last_pos = sector;
+ }
+ }
+ if (!ret) {
+ if (SetFilePointer (ciw->h, sector * 2048, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ reseterrormode (ciw);
+ return ret;
+ }
+ DWORD dtotal = 0;
+ ReadFile (ciw->h, p, 2048, &dtotal, 0);
+ reseterrormode (ciw);
+ if (dtotal != 2048)
+ return ret;
+ if (sectorsize >= 2352) {
+ memset (data, 0, 16);
+ memcpy (data + 16, p, 2048);
+ encode_l2 (data, sector + 150);
+ if (sectorsize > 2352)
+ memset (data + 2352, 0, sectorsize - 2352);
+ sector++;
+ data += sectorsize;
+ ret += sectorsize;
+ } else if (sectorsize == 2048) {
+ memcpy (data, p, 2048);
+ sector++;
+ data += sectorsize;
+ ret += sectorsize;
+ }
+ }
+ sector++;
+ }
+ return ret;
+}
+
static void cdda_closewav (struct dev_info_ioctl *ciw)
{
if (ciw->cdda_wavehandle != NULL)
static void *cdda_play (void *v)
{
- DWORD len;
struct dev_info_ioctl *ciw = (struct dev_info_ioctl*)v;
int cdda_pos;
int num_sectors = CDDA_BUFFERS;
Sleep (10);
oldplay = -1;
- p = (uae_u8*)VirtualAlloc (NULL, 2 * num_sectors * 4096, MEM_COMMIT, PAGE_READWRITE);
+ p = xmalloc (uae_u8, 2 * num_sectors * CD_RAW_SECTOR_WITH_SUBCODE_SIZE);
px[0] = p;
- px[1] = p + num_sectors * 4096;
+ px[1] = p + num_sectors * CD_RAW_SECTOR_WITH_SUBCODE_SIZE;
bufon[0] = bufon[1] = 0;
bufnum = 0;
buffered = 0;
firstloops = 25;
write_log (L"IOCTL CDDA: playing from %d to %d\n", ciw->cdda_start, ciw->cdda_end);
ciw->subcodevalid = false;
- while (ciw->cdda_paused && ciw->cdda_play > 0)
+ while (ciw->cdda_paused && ciw->cdda_play > 0) {
+ firstloops = -1;
Sleep (10);
+ }
}
if ((cdda_pos < ciw->cdda_end || ciw->cdda_end == 0xffffffff) && !ciw->cdda_paused && ciw->cdda_play) {
- RAW_READ_INFO rri;
int sectors = num_sectors;
if (!isaudiotrack (&ciw->di.toc, cdda_pos))
ciw->subcodevalid = false;
memset (ciw->subcode, 0, sizeof ciw->subcode);
+ memset (px[bufnum], 0, sectors * CD_RAW_SECTOR_WITH_SUBCODE_SIZE);
+
if (firstloops > 0) {
firstloops--;
if (ciw->cdda_subfunc)
ciw->cdda_subfunc (ciw->subcode, sectors);
- memset (px[bufnum], 0, sectors * 2352);
} else {
firstloops = -1;
- seterrormode (ciw);
- rri.DiskOffset.QuadPart = 2048 * (cdda_pos + 0);
- rri.SectorCount = sectors;
- rri.TrackMode = RawWithSubCode;
- if (!DeviceIoControl (ciw->h, IOCTL_CDROM_RAW_READ, &rri, sizeof rri, px[bufnum], sectors * CD_RAW_SECTOR_WITH_SUBCODE_SIZE, &len, NULL)) {
- DWORD err = GetLastError ();
- write_log (L"IOCTL_CDROM_RAW_READ CDDA sector %d returned %d\n", cdda_pos, err);
+ if (!read_block (ciw, -1, px[bufnum], cdda_pos, sectors, 2352 + 96)) {
if (ciw->cdda_subfunc)
ciw->cdda_subfunc (ciw->subcode, sectors);
} else {
}
-
if (bufon[0] == 0 && bufon[1] == 0) {
while (!(whdr[0].dwFlags & WHDR_DONE) || !(whdr[1].dwFlags & WHDR_DONE))
Sleep (10);
waveOutUnprepareHeader (ciw->cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
cdda_closewav (ciw);
- VirtualFree (p, 0, MEM_RELEASE);
+ xfree (p);
ciw->cdda_play = 0;
write_log (L"IOCTL CDDA: thread killed\n");
return NULL;
ciw->cdda_subfunc = subfunc;
ciw->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0);
if (!ciw->cdda_play) {
- uae_start_thread (L"cdimage_cdda_play", cdda_play, ciw, NULL);
+ uae_start_thread (L"ioctl_cdda_play", cdda_play, ciw, NULL);
}
ciw->cdda_start = startlsn;
ciw->cdda_end = endlsn;
}
}
+static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d)
+{
+ for (int i = 0; i < 8 * 12; i ++) {
+ int dmask = 0x80;
+ int smask = 1 << (7 - (i / 12));
+ (*d) = 0;
+ for (int j = 0; j < 8; j++) {
+ (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0;
+ dmask >>= 1;
+ }
+ d++;
+ }
+}
+
/* read qcode */
static int ioctl_command_qcode (int unitnum, uae_u8 *buf, int sector)
{
}
-typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER {
- SCSI_PASS_THROUGH_DIRECT spt;
- ULONG Filler;
- UCHAR SenseBuf[32];
-} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
-
-static int do_raw_scsi (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *cmd, int cmdlen, uae_u8 *data, int datalen)
-{
- DWORD status, returned;
- SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
- uae_u8 *p = ciw->tempbuffer;
- if (!open_createfile (ciw, 1))
- return 0;
- memset (&swb, 0, sizeof (swb));
- memcpy (swb.spt.Cdb, cmd, cmdlen);
- swb.spt.Length = sizeof (SCSI_PASS_THROUGH);
- swb.spt.CdbLength = cmdlen;
- swb.spt.DataIn = SCSI_IOCTL_DATA_IN;
- swb.spt.DataTransferLength = IOCTL_DATA_BUFFER;
- swb.spt.DataBuffer = p;
- memset (p, 0, IOCTL_DATA_BUFFER);
- swb.spt.TimeOutValue = 80 * 60;
- swb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, SenseBuf);
- swb.spt.SenseInfoLength = 32;
- seterrormode (ciw);
- status = DeviceIoControl (ciw->h, IOCTL_SCSI_PASS_THROUGH_DIRECT,
- &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
- &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
- &returned, NULL);
- reseterrormode (ciw);
- if (!status) {
- DWORD err = GetLastError ();
- write_log (L"IOCTL_RAW_SCSI unit %d, CMD=%d, ERR=%d ", unitnum, cmd[0], err);
- return 0;
- }
- memcpy (data, p, swb.spt.DataTransferLength > datalen ? datalen : swb.spt.DataTransferLength);
- return 1;
-}
-
-static int spti_inquiry (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data)
-{
- uae_u8 cmd[6] = { 0x12,0,0,0,36,0 }; /* INQUIRY */
- int len = sizeof cmd;
-
- do_raw_scsi (ciw, unitnum, cmd, len, data, 256);
- return 1;
-}
-
-static int spti_read (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data, int sector, int sectorsize)
-{
- /* number of bytes returned depends on type of track:
- * CDDA = 2352
- * Mode1 = 2048
- * Mode2 = 2336
- * Mode2 Form 1 = 2048
- * Mode2 Form 2 = 2328
- */
- uae_u8 cmd[12] = { 0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0x10, 0, 0 };
- ciw->cd_last_pos = sector;
- cmd[3] = (uae_u8)(sector >> 16);
- cmd[4] = (uae_u8)(sector >> 8);
- cmd[5] = (uae_u8)(sector >> 0);
- gui_flicker_led (LED_CD, unitnum, 1);
- int len = sizeof cmd;
- return do_raw_scsi (ciw, unitnum, cmd, len, data, sectorsize);
-}
-
-static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d)
-{
- for (int i = 0; i < 8 * 12; i ++) {
- int dmask = 0x80;
- int smask = 1 << (7 - (i / 12));
- (*d) = 0;
- for (int j = 0; j < 8; j++) {
- (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0;
- dmask >>= 1;
- }
- d++;
- }
-}
-
static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize, uae_u32 extra)
{
struct dev_info_ioctl *ciw = unitisopen (unitnum);
if (!ciw)
return 0;
- RAW_READ_INFO rri;
- DWORD len;
uae_u8 *p = ciw->tempbuffer;
int ret = 0;
if (log_scsi)
write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d\n", unitnum, sector, sectorsize);
- if (!os_vista)
- return spti_read (ciw, unitnum, data, sector, sectorsize);
- if (!open_createfile (ciw, 1))
- return 0;
cdda_stop (ciw);
gui_flicker_led (LED_CD, unitnum, 1);
if (sectorsize > 0) {
- if (sectorsize != 2336 && sectorsize != 2352 && sectorsize != 2048)
+ if (sectorsize != 2336 && sectorsize != 2352 && sectorsize != 2048 &&
+ sectorsize != 2336 + 96 && sectorsize != 2352 + 96 && sectorsize != 2048 + 96)
return 0;
- seterrormode (ciw);
- rri.DiskOffset.QuadPart = sector * 2048;
- rri.SectorCount = 1;
- rri.TrackMode = RawWithSubCode;
- len = sectorsize;
- memset (p, 0, sectorsize);
- if (!DeviceIoControl (ciw->h, IOCTL_CDROM_RAW_READ, &rri, sizeof rri,
- p, IOCTL_DATA_BUFFER, &len, NULL)) {
- DWORD err = GetLastError ();
- write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d mode=%d, ERR=%d\n",
- unitnum, sector, sectorsize, rri.TrackMode, err);
- }
- reseterrormode (ciw);
- if (data) {
- if (sectorsize == 2352)
- memcpy (data, p, sectorsize);
- else
- memcpy (data, p + 16, sectorsize);
+ while (size-- > 0) {
+ if (!read_block (ciw, unitnum, data, sector, 1, sectorsize))
+ break;
data += sectorsize;
ret += sectorsize;
+ sector++;
}
- ciw->cd_last_pos = sector;
} else {
uae_u8 sectortype = extra >> 16;
uae_u8 cmd9 = extra >> 8;
uae_u8 *odata = data;
int blocksize = errorfield == 0 ? 2352 : (errorfield == 1 ? 2352 + 294 : 2352 + 296);
int readblocksize = errorfield == 0 ? 2352 : 2352 + 296;
- seterrormode (ciw);
- rri.DiskOffset.QuadPart = sector * 2048;
- rri.SectorCount = 1;
- rri.TrackMode = errorfield > 0 ? RawWithC2AndSubCode : RawWithSubCode;
- len = sectorsize;
- memset (p, 0, blocksize);
- if (!DeviceIoControl (ciw->h, IOCTL_CDROM_RAW_READ, &rri, sizeof rri, p, IOCTL_DATA_BUFFER, &len, NULL)) {
- DWORD err = GetLastError ();
- write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d mode=%d, ERR=%d\n",
- unitnum, sector, sectorsize, rri.TrackMode, err);
- if (err) {
- reseterrormode (ciw);
- return ret;
- }
+
+ if (!read_block (ciw, unitnum, NULL, sector, 1, readblocksize)) {
+ reseterrormode (ciw);
+ return ret;
}
- reseterrormode (ciw);
+
if (subs == 0) {
memcpy (data, p, blocksize);
data += blocksize;
LocalFree(mp3format);
LocalFree(waveFormat);
if (mmr != MMSYSERR_NOERROR) {
- write_log(L"CUEMP3: couldn't open ACM mp3 decoder, %d\n", mmr);
+ write_log(L"MP3: couldn't open ACM mp3 decoder, %d\n", mmr);
throw exception();
}
}
ACMSTREAMHEADER mp3streamHead;
HACMSTREAM h = (HACMSTREAM)g_mp3stream;
- write_log(L"CUEMP3: decoding '%s'..\n", zfile_getname(zf));
+ write_log(L"MP3: decoding '%s'..\n", zfile_getname(zf));
mmr = acmStreamSize(h, MP3_BLOCK_SIZE, &rawbufsize, ACM_STREAMSIZEF_SOURCE);
if (mmr != MMSYSERR_NOERROR) {
- write_log (L"CUEMP3: acmStreamSize, %d\n", mmr);
+ write_log (L"MP3: acmStreamSize, %d\n", mmr);
return NULL;
}
// allocate our I/O buffers
mp3streamHead.cbDstLength = rawbufsize;
mmr = acmStreamPrepareHeader(h, &mp3streamHead, 0);
if (mmr != MMSYSERR_NOERROR) {
- write_log(L"CUEMP3: acmStreamPrepareHeader, %d\n", mmr);
+ write_log(L"MP3: acmStreamPrepareHeader, %d\n", mmr);
return NULL;
}
zfile_fseek(zf, 0, SEEK_SET);
- outbuf = xcalloc(uae_u8, maxsize);
+ outbuf = xcalloc(uae_u8, maxsize + 2352);
for (;;) {
int count = zfile_fread(mp3buf, 1, MP3_BLOCK_SIZE, zf);
if (count != MP3_BLOCK_SIZE)
// convert the data
mmr = acmStreamConvert(h, &mp3streamHead, ACM_STREAMCONVERTF_BLOCKALIGN);
if (mmr != MMSYSERR_NOERROR) {
- write_log(L"CUEMP3: acmStreamConvert, %d\n", mmr);
+ write_log(L"MP3: acmStreamConvert, %d\n", mmr);
return NULL;
}
if (outoffset + mp3streamHead.cbDstLengthUsed > maxsize)
acmStreamUnprepareHeader(h, &mp3streamHead, 0);
LocalFree(rawbuf);
LocalFree(mp3buf);
- write_log(L"CUEMP3: unpacked size %d bytes\n", outoffset);
+ write_log(L"MP3: unpacked size %d bytes\n", outoffset);
return outbuf;
}
uae_u32 mp3decoder::getsize (struct zfile *zf)
{
uae_u32 size;
- int frames;
+ int frames, sameframes;
+ int firstframe;
+ int oldbitrate;
+ int timelen = -1;
+ firstframe = -1;
+ oldbitrate = -1;
+ sameframes = -1;
frames = 0;
size = 0;
+ uae_u8 id3[10];
+
+ if (zfile_fread(id3, sizeof id3, 1, zf) != 1)
+ return 0;
+ if (id3[0] == 'I' && id3[1] == 'D' && id3[2] == '3' && id3[3] == 3 && id3[4] != 0xff && id3[6] < 0x80 && id3[7] < 0x80 && id3[8] < 0x80 && id3[9] < 0x80) {
+ int unsync = id3[5] & 0x80;
+ int exthead = id3[5] & 0x40;
+ int len = (id3[9] << 0) | (id3[8] << 7) | (id3[7] << 14) | (id3[6] << 21);
+ len &= 0x0fffffff;
+ uae_u8 *tag = xmalloc (uae_u8, len + 1);
+ if (zfile_fread (tag, len, 1, zf) != 1) {
+ xfree (tag);
+ return 0;
+ }
+ uae_u8 *p = tag;
+ if (exthead) {
+ int size = (p[4] << 21) | (p[5] << 14) | (p[6] << 7);
+ size &= 0x0fffffff;
+ p += size;
+ len -= size;
+ }
+ while (len > 0) {
+ int size = unsync ? (p[4] << 21) | (p[5] << 14) | (p[6] << 7) | (p[7] << 0) : (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | (p[7] << 0);
+ size &= 0x0fffffff;
+ if (size > len)
+ break;
+ int compr = p[9] & 0x80;
+ int enc = p[9] & 0x40;
+ if (compr == 0 && enc == 0) {
+ if (!memcmp (p, "TLEN", 4)) {
+ uae_u8 *data = p + 10;
+ data[size] = 0;
+ if (data[0] == 0)
+ timelen = atol ((char*)(data + 1));
+ else
+ timelen = _tstol ((wchar_t*)(data + 1));
+ }
+ }
+ size += 10;
+ p += size;
+ len -= size;
+ }
+ xfree (tag);
+ } else {
+ zfile_fseek(zf, -(int)sizeof id3, SEEK_CUR);
+ }
+
+
for (;;) {
int ver, layer, bitrate, freq, padding, bitindex, iscrc;
int samplerate, framelen, bitrateidx, channelmode;
zfile_fseek (zf, -3, SEEK_CUR);
continue;
}
+ if (firstframe < 0)
+ firstframe = zfile_ftell (zf);
+
ver = (header[1] >> 3) & 3;
if (ver == 1)
return 0;
return 0;
zfile_fseek(zf, framelen + iscrc - 4, SEEK_CUR);
frames++;
+ if (timelen > 0) {
+ size = ((uae_u64)timelen * freq * 2 * (isstereo ? 2 : 1)) / 1000;
+ break;
+ }
size += samplerate * 2 * (isstereo ? 2 : 1);
+ if (bitrate != oldbitrate) {
+ oldbitrate = bitrate;
+ sameframes++;
+ }
+ if (sameframes == 0 && frames > 100) {
+ // assume this is CBR MP3
+ size = samplerate * 2 * (isstereo ? 2 : 1) * ((zfile_size (zf) - firstframe) / ((samplerate / 8 * bitrate) / freq));
+ break;
+ }
}
return size;
}
//\r
\r
VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 2,2,0,0\r
- PRODUCTVERSION 2,2,0,0\r
+ FILEVERSION 2,3,0,0\r
+ PRODUCTVERSION 2,3,0,0\r
FILEFLAGSMASK 0x3fL\r
#ifdef _DEBUG\r
FILEFLAGS 0x1L\r
BLOCK "040904b0"\r
BEGIN\r
VALUE "FileDescription", "WinUAE"\r
- VALUE "FileVersion", "2.2.0.0"\r
+ VALUE "FileVersion", "2.3.0.0"\r
VALUE "InternalName", "WinUAE"\r
VALUE "LegalCopyright", "© 1996-2010 under the GNU Public License (GPL)"\r
VALUE "OriginalFilename", "WinUAE.exe"\r
VALUE "ProductName", "WinUAE"\r
- VALUE "ProductVersion", "2.2.0.0"\r
+ VALUE "ProductVersion", "2.3.0.0"\r
END\r
END\r
BLOCK "VarFileInfo"\r
#define WINUAEPUBLICBETA 1
#define LANG_DLL 1
-#define WINUAEBETA L"4"
-#define WINUAEDATE MAKEBD(2010, 7, 20)
+#define WINUAEBETA L"5"
+#define WINUAEDATE MAKEBD(2010, 7, 23)
#define WINUAEEXTRA L""
#define WINUAEREV L""
</ResourceCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
- <AdditionalDependencies>ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9d.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;prowizard.lib;lzmalib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9d.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;prowizard.lib;lzmalib.lib;libFLAC_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
- <AdditionalDependencies>ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
- <AdditionalDependencies>ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
- <AdditionalDependencies>ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;avrt.lib;enet.lib;prowizard.lib;lzmalib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;libpng.lib;lglcd.lib;wpcap.lib;packet.lib;openal32.lib;wintab32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;avrt.lib;enet.lib;prowizard.lib;lzmalib.lib;libFLAC_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
+- few lines of non-filter scanlines was missing in bottom part of display
+- mp3 cd audio: detect audio length using ID3v2 TLEN tag if it exists, assume it is CBR MP3 if
+ first 100 frames have same bit rate, fallback to original slow full file scan if no tags and VBR
+- remove mp3 decoding time from audio playback delay time, better av sync if decoding takes less
+ than 2 seconds
+
Beta 4:
- rawinput was disabled if only one keyboard device was detected, input didn't work at all
return ZFILE_NVR;
if (strcasecmp (ext, L"uae") == 0)
return ZFILE_CONFIGURATION;
- if (strcasecmp (ext, L"cue") == 0 || strcasecmp (ext, L"iso") == 0)
+ if (strcasecmp (ext, L"cue") == 0 || strcasecmp (ext, L"iso") == 0 || strcasecmp (ext, L"ccd") == 0 || strcasecmp (ext, L"mds") == 0)
return ZFILE_CDIMAGE;
}
memset (buf, 0, sizeof (buf));
if (zf->zipname && zf->zipname[0] == '#' && _tstol (zf->zipname + 1) == zipcnt)
select = -1;
if (select && we_have_file < 10) {
- struct zfile *zt = archive_getzfile (zn, id, FILE_PEEK);
- if (zt) {
- int ft = zfile_gettype (zt);
- TCHAR *ext = _tcsrchr (zn->fullname, '.');
- int whf = 1;
- if ((mask & ZFD_CD) && ft) {
- if (ext && !_tcsicmp (ext, L".iso"))
- whf = 2;
- if (ext && !_tcsicmp (ext, L".ccd"))
- whf = 9;
- if (ext && !_tcsicmp (ext, L".cue"))
- whf = 10;
+ struct zfile *zt = NULL;
+ TCHAR *ext = _tcsrchr (zn->fullname, '.');
+ int whf = 1;
+ int ft = 0;
+ if (mask & ZFD_CD) {
+ if (ext && !_tcsicmp (ext, L".iso")) {
+ whf = 2;
+ ft = ZFILE_CDIMAGE;
}
- if ((select < 0 || ft) && whf > we_have_file) {
- we_have_file = whf;
- if (z)
- zfile_fclose (z);
- z = zt;
- zt = NULL;
+ if (ext && !_tcsicmp (ext, L".ccd")) {
+ whf = 9;
+ ft = ZFILE_CDIMAGE;
}
- zfile_fclose (zt);
+ if (ext && !_tcsicmp (ext, L".cue")) {
+ whf = 10;
+ ft = ZFILE_CDIMAGE;
+ }
+ } else {
+ zt = archive_getzfile (zn, id, FILE_PEEK);
+ ft = zfile_gettype (zt);
+ }
+ if ((select < 0 || ft) && whf > we_have_file) {
+ if (!zt)
+ zt = archive_getzfile (zn, id, FILE_PEEK);
+ we_have_file = whf;
+ if (z)
+ zfile_fclose (z);
+ z = zt;
+ zt = NULL;
}
+ zfile_fclose (zt);
}
}
zipcnt++;