]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2300b5
authorToni Wilen <twilen@winuae.net>
Fri, 23 Jul 2010 11:05:27 +0000 (14:05 +0300)
committerToni Wilen <twilen@winuae.net>
Fri, 23 Jul 2010 11:05:27 +0000 (14:05 +0300)
13 files changed:
audio.cpp
blkdev.cpp
blkdev_cdimage.cpp
drawing.cpp
include/options.h
od-win32/blkdev_win32_ioctl.cpp
od-win32/mp3decoder.cpp
od-win32/resources/winuae.rc
od-win32/win32.h
od-win32/winuae_msvc10/winuae_msvc.vcxproj
od-win32/winuaechangelog.txt
zfile.cpp
zfile_archive.cpp

index 3179ba0302e6699ee75d45a1328071ac7d3897ee..abb32ca8c67fc82a3fa94be4ee50a0ff3da8ad57 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -1269,6 +1269,7 @@ static void audio_state_channel2 (int nr, bool perfin)
                                // 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;
@@ -1307,7 +1308,8 @@ static void audio_state_channel2 (int nr, bool perfin)
                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;
index ac47acbd8958425aae596743161a5865cbd74d0b..545359db736b22fba2016d1217cf688e5747f83d 100644 (file)
@@ -286,8 +286,8 @@ int get_standard_cd_unit (enum cd_standard_unit csu)
                                        }
                                }
                                write_log (L"\n");
+                               sys_command_close (unitnum);
                        }
-                       sys_command_close (unitnum);
                }
        }
        if (isaudio) {
index 7fd7127216fe3964516e8a3628f0c8f7e4dd6fbc..4ef7d456184ec4c319f89b2652745dea2c0fba89 100644 (file)
@@ -13,6 +13,8 @@
 #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
@@ -53,7 +60,8 @@ struct cdtoc
        int track;
        int size;
        int skipsize; // bytes to skip after each block
-       int mp3;
+       audenc enctype;
+       int writeoffset;
        int subcode;
 };
 
@@ -115,6 +123,96 @@ static struct cdtoc *findtoc (struct cdunit *cdu, int *sectorp)
        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;
@@ -140,7 +238,7 @@ static int cdda_openwav (void)
        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;
        }
@@ -297,7 +395,9 @@ static void *cdda_play_func (void *v)
                        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;
@@ -308,19 +408,35 @@ static void *cdda_play_func (void *v)
                                } 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)) {
@@ -366,9 +482,10 @@ static void *cdda_play_func (void *v)
                                                        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);
@@ -567,29 +684,42 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int
        if (!cdu)
                return 0;
        struct cdtoc *t = findtoc (cdu, &sector);
-       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;
@@ -639,6 +769,7 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int
        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);
@@ -651,11 +782,20 @@ static int command_read (int unitnum, uae_u8 *data, int sector, int size)
        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;
 }
@@ -859,10 +999,10 @@ static int parsemds (struct cdunit *cdu, struct zfile *zmds, const TCHAR *img)
                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;
        }
 
@@ -1062,6 +1202,7 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
        int tracknum, index0, pregap;
        int offset, secoffset, newfile;
        TCHAR *fname, *fnametype;
+       audenc fnametypeid;
        int ctrl;
        mp3decoder *mp3dec = NULL;
 
@@ -1074,6 +1215,7 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
        ctrl = 0;
        index0 = -1;
        pregap = 0;
+       fnametypeid = AUDENC_NONE;
 
        write_log (L"CUE TOC: '%s'\n", img);
        for (;;) {
@@ -1089,11 +1231,18 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                        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;
@@ -1224,7 +1373,7 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                                        }
                                        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);
@@ -1243,8 +1392,9 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                                                        }
                                                        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();
@@ -1254,8 +1404,12 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img)
                                                        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;
                                        }
                                }
                        }
@@ -1347,12 +1501,12 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img)
                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);
        }
 
index 7a17e27400448e0bdb699993f36dede64871c987..628f9002dcff30818da916a60adb24fc5a766346 100644 (file)
@@ -2148,11 +2148,11 @@ static void pfield_draw_line (int lineno, int gfx_ypos, int follow_ypos)
 
        } 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;
 
        }
 }
index c01197521dfab4a4bda1a074db0f8ab7403eec34..763795202137efd0e6695ede96a0785a71617991 100644 (file)
@@ -8,8 +8,8 @@
 */
 
 #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;
 
index 11ccf0caa6ca3132286034fd9d9617c40e94fd51..1ab36e97a8a6c02e9912adcd448b153898787bc8 100644 (file)
@@ -207,6 +207,168 @@ static int open_createfile (struct dev_info_ioctl *ciw, int fullaccess)
        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)
@@ -239,7 +401,6 @@ static int cdda_openwav (struct dev_info_ioctl *ciw)
 
 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;
@@ -263,9 +424,9 @@ static void *cdda_play (void *v)
                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;
@@ -301,12 +462,13 @@ static void *cdda_play (void *v)
                                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))
@@ -316,23 +478,18 @@ static void *cdda_play (void *v)
                                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 {
@@ -398,7 +555,6 @@ static void *cdda_play (void *v)
 
                        }
 
-
                        if (bufon[0] == 0 && bufon[1] == 0) {
                                while (!(whdr[0].dwFlags & WHDR_DONE) || !(whdr[1].dwFlags & WHDR_DONE))
                                        Sleep (10);
@@ -419,7 +575,7 @@ end:
                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;
@@ -488,7 +644,7 @@ static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan,
        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;
@@ -512,6 +668,20 @@ static void sub_deinterleave (const uae_u8 *s, uae_u8 *d)
        }
 }
 
+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)
 {
@@ -608,131 +778,30 @@ 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;
@@ -757,22 +826,12 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz
                                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;
index 95730ee28cd9ea5d89ac3bb818a620a506cb7879..882f98b757eff20725fc140e7e242b5486e298ed 100644 (file)
@@ -94,7 +94,7 @@ mp3decoder::mp3decoder()
        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();
        }
 }
@@ -110,10 +110,10 @@ uae_u8 *mp3decoder::get (struct zfile *zf, int maxsize)
        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
@@ -129,11 +129,11 @@ uae_u8 *mp3decoder::get (struct zfile *zf, int maxsize)
        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)
@@ -141,7 +141,7 @@ uae_u8 *mp3decoder::get (struct zfile *zf, int maxsize)
                // 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)
@@ -152,17 +152,71 @@ uae_u8 *mp3decoder::get (struct zfile *zf, int 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;
@@ -175,6 +229,9 @@ uae_u32 mp3decoder::getsize (struct zfile *zf)
                        zfile_fseek (zf, -3, SEEK_CUR);
                        continue;
                }
+               if (firstframe < 0)
+                       firstframe = zfile_ftell (zf);
+
                ver = (header[1] >> 3) & 3;
                if (ver == 1)
                        return 0;
@@ -212,7 +269,20 @@ uae_u32 mp3decoder::getsize (struct zfile *zf)
                        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;
 }
index 2f2b7896ea40e0c766285d30d062e38f9b6c1fca..56e2d2a93bc20cddef6289733098b9894a36fb85 100644 (file)
@@ -1052,8 +1052,8 @@ END
 //\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
@@ -1069,12 +1069,12 @@ BEGIN
         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
index d5f7c0ff03bd3852a07ab5823bb8560d25a26156..bc460e4c57b9ad0d75bac7835d6b9a988bd6108b 100644 (file)
@@ -18,8 +18,8 @@
 #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""
 
index 7674f44e816f68971011a825d48633e068673f90..12e74aa5c3e92f7be14f53fa20a119d67fcb2fd2 100644 (file)
     </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>
index 25b9d13915cef7ef59e052bcd90534452c394d73..4b0c7433e077502d87afebe52c5af6b0f268df45 100644 (file)
@@ -1,4 +1,10 @@
 
+- 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
index 53d754f25edaf6b73c4982bdbded99852ea94bc3..e840e24b3d66332dea97d0c65844406325cd00b9 100644 (file)
--- a/zfile.cpp
+++ b/zfile.cpp
@@ -268,7 +268,7 @@ int zfile_gettype (struct zfile *z)
                        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));
index 40cbac0db535bf6c0e40f18bcb858c65468fdcb9..0fb55de8036d2fcf48de584a9e4af7c25b37cba9 100644 (file)
@@ -188,28 +188,37 @@ struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, uns
                        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++;