From 53646e3b5d3a4be368cde8a9d0293f364af3629b Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 24 Jul 2010 15:20:08 +0300 Subject: [PATCH] 2300b6 --- a2065.cpp | 4 +- audio.cpp | 2 +- blkdev.cpp | 34 +++++- blkdev_cdimage.cpp | 131 ++++++++++++++------- disk.cpp | 20 ++-- include/blkdev.h | 4 + include/zarchive.h | 3 + include/zfile.h | 1 + od-win32/blkdev_win32_ioctl.cpp | 16 +-- od-win32/mp3decoder.cpp | 4 +- od-win32/mp3decoder.h | 2 +- od-win32/win32.cpp | 3 + od-win32/win32.h | 4 +- od-win32/win32_uaenet.cpp | 4 +- od-win32/win32_uaenet.h | 8 +- od-win32/win32gui.cpp | 32 +++--- od-win32/winuaechangelog.txt | 58 ++++++++-- sana2.cpp | 108 +++++++++--------- zfile.cpp | 60 ++++++---- zfile_archive.cpp | 196 +++++++++++++++++++++----------- 20 files changed, 462 insertions(+), 232 deletions(-) diff --git a/a2065.cpp b/a2065.cpp index 1d4c4fbe..c445f8e8 100644 --- a/a2065.cpp +++ b/a2065.cpp @@ -225,7 +225,7 @@ static int mungepacket (uae_u8 *packet, int len) return ret; } -static int getfunc (struct devstruct *dev, uae_u8 *d, int *len) +static int getfunc (struct s2devstruct *dev, uae_u8 *d, int *len) { int tlen; @@ -249,7 +249,7 @@ static int mcfilter (const uae_u8 *data) return 1; // just allow everything } -static void gotfunc (struct devstruct *dev, const uae_u8 *data2, int len) +static void gotfunc (struct s2devstruct *dev, const uae_u8 *data2, int len) { int i; int size, insize, first; diff --git a/audio.cpp b/audio.cpp index abb32ca8..ecf24069 100644 --- a/audio.cpp +++ b/audio.cpp @@ -64,7 +64,7 @@ static bool debugchannel (int ch) STATIC_INLINE bool usehacks (void) { - return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != -1; + return currprefs.cpu_model >= 68020 || currprefs.m68k_speed != 0; } #define SINC_QUEUE_MAX_AGE 2048 diff --git a/blkdev.cpp b/blkdev.cpp index 545359db..de163497 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -24,6 +24,7 @@ static int scsiemu[MAX_TOTAL_SCSI_DEVICES]; static struct device_functions *device_func[MAX_TOTAL_SCSI_DEVICES]; static int openlist[MAX_TOTAL_SCSI_DEVICES]; +static int waspaused[MAX_TOTAL_SCSI_DEVICES]; /* convert minutes, seconds and frames -> logical sector number */ int msf2lsn (int msf) @@ -316,12 +317,14 @@ int sys_command_isopen (int unitnum) int sys_command_open (int unitnum) { + waspaused[unitnum] = 0; return sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : NULL); } void sys_command_close (int unitnum) { + waspaused[unitnum] = 0; if (openlist[unitnum] <= 0) write_log (L"BUG unit %d close: opencnt=%d!\n", unitnum, openlist[unitnum]); if (device_func[unitnum]) { @@ -353,6 +356,32 @@ int device_func_init (int flags) return 1; } +void blkdev_entergui (void) +{ + for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { + waspaused[i] = 0; + struct device_info di; + if (sys_command_info (i, &di, 1)) { + if (sys_command_cd_pause (i, 1) == 0) + waspaused[i] = 1; + } + } +} +void blkdev_exitgui (void) +{ + for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { + if (waspaused[i]) { + struct device_info di; + if (sys_command_info (i, &di, 1)) { + sys_command_cd_pause (i, 0); + } + } + waspaused[i] = 0; + } +} + + + static TCHAR newimagefiles[MAX_TOTAL_SCSI_DEVICES][256]; static int imagechangetime[MAX_TOTAL_SCSI_DEVICES]; static bool cdimagefileinuse[MAX_TOTAL_SCSI_DEVICES], wasopen[MAX_TOTAL_SCSI_DEVICES]; @@ -656,6 +685,8 @@ int sys_command_ismedia (int unitnum, int quick) struct device_info *sys_command_info (int unitnum, struct device_info *di, int quick) { + if (failunit (unitnum)) + return NULL; return device_func[unitnum]->info (unitnum, di, quick); } @@ -1466,7 +1497,7 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as) as->status = scsi_emulate (unitnum, cmd, as->cmd_len, scsi_datap, &datalen, replydata, &replylen, as->sensedata, &senselen); - as->cmdactual = as->status == 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */ + as->cmdactual = as->status != 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */ if (as->status) { io_error = 45; /* HFERR_BadStatus */ as->sense_len = senselen; @@ -1584,3 +1615,4 @@ uae_u8 *restore_cd (int num, uae_u8 *src) } #endif + diff --git a/blkdev_cdimage.cpp b/blkdev_cdimage.cpp index 4ef7d456..30f80f90 100644 --- a/blkdev_cdimage.cpp +++ b/blkdev_cdimage.cpp @@ -84,7 +84,6 @@ struct cdunit { play_subchannel_callback cdda_subfunc; int imagechange; - int donotmountme; TCHAR newfile[MAX_DPATH]; uae_sem_t sub_sem; struct device_info di; @@ -93,6 +92,9 @@ struct cdunit { static struct cdunit cdunits[MAX_TOTAL_SCSI_DEVICES]; static int bus_open; +static volatile int cdimage_unpack_thread, cdimage_unpack_active; +static smp_comm_pipe unpack_pipe; + static struct cdunit *unitisopen (int unitnum) { struct cdunit *cdu = &cdunits[unitnum]; @@ -194,10 +196,7 @@ static void flac_get_size (struct cdtoc *t) } 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) { @@ -340,6 +339,51 @@ static void dosub (struct cdunit *cdu, struct cdtoc *t, int sector) cdu->cdda_subfunc (d, 1); } + +static void *cdda_unpack_func (void *v) +{ + cdimage_unpack_thread = 1; + mp3decoder *mp3dec = NULL; + + for (;;) { + uae_u32 cduidx = read_comm_pipe_u32_blocking (&unpack_pipe); + if (cdimage_unpack_thread == 0) + break; + uae_u32 tocidx = read_comm_pipe_u32_blocking (&unpack_pipe); + struct cdunit *cdu = &cdunits[cduidx]; + struct cdtoc *t = &cdu->toc[tocidx]; + if (t->handle) { + // force unpack if handle points to delayed zipped file + uae_s64 pos = zfile_ftell (t->handle); + zfile_fseek (t->handle, -1, SEEK_END); + uae_u8 b; + zfile_fread (&b, 1, 1, t->handle); + zfile_fseek (t->handle, pos, SEEK_SET); + if (!t->data && (t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC)) { + t->data = xcalloc (uae_u8, t->filesize + 2352); + cdimage_unpack_active = 1; + 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->data, t->filesize); + } else if (t->enctype == AUDENC_FLAC) { + flac_get_data (t); + } + } + } + } + cdimage_unpack_active = 2; + } + delete mp3dec; + cdimage_unpack_thread = -1; + return 0; +} + static void *cdda_play_func (void *v) { int cdda_pos; @@ -354,7 +398,6 @@ static void *cdda_play_func (void *v) MMRESULT mmr; int volume[2], volume_main; int oldplay; - mp3decoder *mp3dec = NULL; struct cdunit *cdu = (struct cdunit*)v; int firstloops; @@ -408,29 +451,17 @@ 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->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); - } - } + // do this even if audio is not compressed, t->handle also could be + // compressed and we want to unpack it in background too + while (cdimage_unpack_active == 1) + Sleep (10); + cdimage_unpack_active = 0; + write_comm_pipe_u32 (&unpack_pipe, cdu - &cdunits[0], 0); + write_comm_pipe_u32 (&unpack_pipe, t - &cdu->toc[0], 1); + while (cdimage_unpack_active == 0) + Sleep (10); } - 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; + firstloops = 150; while (cdu->cdda_paused && cdu->cdda_play > 0) { Sleep (10); firstloops = -1; @@ -454,6 +485,8 @@ static void *cdda_play_func (void *v) int sector, cnt; int dofinish = 0; + gui_flicker_led (LED_CD, cdu->di.unitnum - 1, LED_CD_AUDIO); + memset (px[bufnum], 0, num_sectors * 2352); if (firstloops > 0) { @@ -550,9 +583,11 @@ end: for (i = 0; i < 2; i++) waveOutUnprepareHeader (cdda_wavehandle, &whdr[i], sizeof (WAVEHDR)); + while (cdimage_unpack_active == 1) + Sleep (10); + cdda_closewav (); xfree (p); - delete mp3dec; cdu->cdda_play = 0; write_log (L"IMAGE CDDA: thread killed\n"); return NULL; @@ -782,7 +817,7 @@ static int command_read (int unitnum, uae_u8 *data, int sector, int size) if (!t || t->handle == NULL) return NULL; cdda_stop (cdu); - if (t->size == 2848) { + if (t->size == 2048) { int offset = 0; zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET); zfile_fread (data, size, 2048, t->handle); @@ -847,7 +882,6 @@ static int command_toc (int unitnum, struct cd_toc_head *th) toc++; memcpy (&cdu->di.toc, th, sizeof (struct cd_toc_head)); - gui_flicker_led (LED_CD, unitnum, 1); return 1; } @@ -1237,9 +1271,8 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img) 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_PCM; + if (!_tcsicmp (fnametype, L"MP3")) fnametypeid = AUDENC_MP3; else if (!_tcsicmp (fnametype, L"FLAC")) fnametypeid = AUDENC_FLAC; @@ -1298,14 +1331,14 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img) } newfile = 0; - ztrack = zfile_fopen (fname, L"rb", ZFD_ARCHIVE); + ztrack = zfile_fopen (fname, L"rb", ZFD_ARCHIVE | ZFD_DELAYEDOPEN); if (!ztrack) { TCHAR tmp[MAX_DPATH]; _tcscpy (tmp, fname); p = tmp + _tcslen (tmp); while (p > tmp) { if (*p == '/' || *p == '\\') { - ztrack = zfile_fopen (p + 1, L"rb", ZFD_ARCHIVE); + ztrack = zfile_fopen (p + 1, L"rb", ZFD_ARCHIVE | ZFD_DELAYEDOPEN); if (ztrack) { xfree (fname); fname = my_strdup (p + 1); @@ -1326,7 +1359,7 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img) s2[0] = 0; _tcscat (tmp, L"\\"); _tcscat (tmp, fname); - ztrack = zfile_fopen (tmp, L"rb", ZFD_ARCHIVE); + ztrack = zfile_fopen (tmp, L"rb", ZFD_ARCHIVE | ZFD_DELAYEDOPEN); } } t->track = tracknum; @@ -1392,8 +1425,8 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img) } t->offset += zfile_ftell (zf); t->filesize = size; - t->enctype = fnametypeid; } + t->enctype = fnametypeid; } else if (fnametypeid == AUDENC_MP3 && t->handle) { if (!mp3dec) { try { @@ -1532,7 +1565,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int struct cdunit *cdu = &cdunits[unitnum]; memset (di, 0, sizeof (struct device_info)); if (!cdu->enabled) - return 0; + return NULL; di->open = cdu->open; di->removable = 1; di->bus = unitnum; @@ -1595,6 +1628,12 @@ static int open_device (int unitnum, const TCHAR *ident) cdu->cdda_volume[0] = 0x7fff; cdu->cdda_volume[1] = 0x7fff; blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name); + if (cdimage_unpack_thread == 0) { + init_comm_pipe (&unpack_pipe, 10, 1); + uae_start_thread (L"cdimage_unpack", cdda_unpack_func, NULL, NULL); + while (cdimage_unpack_thread == 0) + Sleep (10); + } return 1; } @@ -1607,8 +1646,16 @@ static void close_device (int unitnum) unload_image (cdu); uae_sem_destroy (&cdu->sub_sem); cdu->open = false; - cdu->enabled = false; blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name); + if (cdimage_unpack_thread) { + cdimage_unpack_thread = 0; + write_comm_pipe_u32 (&unpack_pipe, -1, 0); + write_comm_pipe_u32 (&unpack_pipe, -1, 1); + while (cdimage_unpack_thread == 0) + Sleep (10); + cdimage_unpack_thread = 0; + destroy_comm_pipe (&unpack_pipe); + } } static void close_bus (void) @@ -1617,6 +1664,12 @@ static void close_bus (void) write_log (L"IMAGE close_bus() when already closed!\n"); return; } + for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { + struct cdunit *cdu = &cdunits[i]; + if (cdu->open) + close_device (i); + cdu->enabled = false; + } bus_open = 0; write_log (L"IMAGE driver closed.\n"); } diff --git a/disk.cpp b/disk.cpp index f7adccba..daa8b7b9 100644 --- a/disk.cpp +++ b/disk.cpp @@ -2781,6 +2781,15 @@ static void disk_doupdate_predict (int startcycle) } } +int disk_fifostatus (void) +{ + if (fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2]) + return 1; + if (!fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2]) + return -1; + return 0; +} + static bool doreaddma (void) { if (dmaen (DMA_DISK) && bitoffset == 15 && dma_enable && dskdmaen == 2 && dsklength >= 0) { @@ -2795,6 +2804,9 @@ static bool doreaddma (void) } DSKDAT (word); dsklength--; + } else if (dsklength == 0 && disk_fifostatus () < 0) { + // zero length transfer wouldn't finish without this + disk_dmafinished (); } return true; } @@ -3280,14 +3292,6 @@ uae_u16 DSKDATR (void) } return v; } -int disk_fifostatus (void) -{ - if (fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2]) - return 1; - if (!fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2]) - return -1; - return 0; -} uae_u16 disk_dmal (void) { diff --git a/include/blkdev.h b/include/blkdev.h index 7f55bf67..eee0b771 100644 --- a/include/blkdev.h +++ b/include/blkdev.h @@ -197,3 +197,7 @@ enum cd_standard_unit { CD_STANDARD_UNIT_AUDIO, CD_STANDARD_UNIT_CDTV, CD_STANDA extern int get_standard_cd_unit (enum cd_standard_unit csu); extern void close_standard_cd_unit (int); extern void blkdev_cd_change (int unitnum, const TCHAR *name); + +extern void blkdev_entergui (void); +extern void blkdev_exitgui (void); + diff --git a/include/zarchive.h b/include/zarchive.h index d8353a93..45ec42d7 100644 --- a/include/zarchive.h +++ b/include/zarchive.h @@ -11,6 +11,7 @@ struct zfile { uae_u8 *data; // unpacked data int dataseek; // use seek position even if real file struct zfile *archiveparent; // set if parent is archive and this has not yet been unpacked (datasize < size) + int archiveid; uae_s64 size; // real size uae_s64 datasize; // available size (not yet unpacked completely?) uae_s64 seek; // seek position @@ -98,6 +99,7 @@ struct zarchive_info #define PEEK_BYTES 1024 #define FILE_PEEK 1 +#define FILE_DELAYEDOPEN 2 extern int zfile_is_ignore_ext (const TCHAR *name); @@ -141,5 +143,6 @@ extern void archive_access_scan (struct zfile *zf, zfile_callback zc, void *user extern void archive_access_close (void *handle, unsigned int id); extern struct zfile *archive_getzfile (struct znode *zn, unsigned int id, int flags); +extern struct zfile *archive_unpackzfile (struct zfile *zf); extern struct zfile *decompress_zfd (struct zfile*); \ No newline at end of file diff --git a/include/zfile.h b/include/zfile.h index 9d7f86b0..4fef64eb 100644 --- a/include/zfile.h +++ b/include/zfile.h @@ -78,6 +78,7 @@ extern TCHAR *zfile_geterror (void); #define ZFD_CD 32 //cue/iso, cue has priority over iso #define ZFD_DISKHISTORY 0x100 //allow diskhistory (if disk image) #define ZFD_CHECKONLY 0x200 //file exists checkc +#define ZFD_DELAYEDOPEN 0x400 //do not unpack, just get metadata #define ZFD_NORMAL (ZFD_ARCHIVE|ZFD_UNPACK) #define ZFD_ALL 0x0000ffff diff --git a/od-win32/blkdev_win32_ioctl.cpp b/od-win32/blkdev_win32_ioctl.cpp index 1ab36e97..f56be63d 100644 --- a/od-win32/blkdev_win32_ioctl.cpp +++ b/od-win32/blkdev_win32_ioctl.cpp @@ -281,7 +281,7 @@ static int spti_read (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data, int cmd[4] = (uae_u8)(sector >> 8); cmd[5] = (uae_u8)(sector >> 0); if (unitnum >= 0) - gui_flicker_led (LED_CD, unitnum, 1); + gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); int len = sizeof cmd; return do_raw_scsi (ciw, unitnum, cmd, len, data, tlen); } @@ -474,6 +474,8 @@ static void *cdda_play (void *v) if (!isaudiotrack (&ciw->di.toc, cdda_pos)) goto end; // data track? + gui_flicker_led (LED_CD, ciw->di.unitnum - 1, LED_CD_AUDIO); + uae_sem_wait (&ciw->sub_sem); ciw->subcodevalid = false; memset (ciw->subcode, 0, sizeof ciw->subcode); @@ -790,7 +792,7 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz if (log_scsi) write_log (L"IOCTL rawread unit=%d sector=%d blocksize=%d\n", unitnum, sector, sectorsize); cdda_stop (ciw); - gui_flicker_led (LED_CD, unitnum, 1); + gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); if (sectorsize > 0) { if (sectorsize != 2336 && sectorsize != 2352 && sectorsize != 2048 && sectorsize != 2336 + 96 && sectorsize != 2352 + 96 && sectorsize != 2048 + 96) @@ -878,7 +880,7 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write cdda_stop (ciw); ciw->cd_last_pos = sector; while (cnt-- > 0) { - gui_flicker_led (LED_CD, unitnum, 1); + gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); seterrormode (ciw); if (SetFilePointer (ciw->h, sector * ciw->di.bytespersector, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { reseterrormode (ciw); @@ -890,7 +892,7 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write break; } while (size-- > 0) { - gui_flicker_led (LED_CD, unitnum, 1); + gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); seterrormode (ciw); if (write) { if (data) { @@ -928,7 +930,7 @@ static int ioctl_command_readwrite (int unitnum, int sector, int size, int write } } reseterrormode (ciw); - gui_flicker_led (LED_CD, unitnum, 1); + gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); } return 1; } @@ -998,7 +1000,7 @@ static int ioctl_command_toc (int unitnum, struct cd_toc_head *tocout) if (!open_createfile (ciw, 0)) return 0; - gui_flicker_led (LED_CD, unitnum, 1); + gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); while (cnt-- > 0) { seterrormode (ciw); if (!DeviceIoControl (ciw->h, IOCTL_CDROM_READ_TOC, NULL, 0, toc, sizeof (CDROM_TOC), &len, NULL)) { @@ -1045,7 +1047,7 @@ static int ioctl_command_toc (int unitnum, struct cd_toc_head *tocout) t->paddress = th->lastaddress; t++; - gui_flicker_led (LED_CD, unitnum, 1); + gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); memcpy (tocout, th, sizeof (struct cd_toc_head)); return 1; } diff --git a/od-win32/mp3decoder.cpp b/od-win32/mp3decoder.cpp index 882f98b7..2887b77a 100644 --- a/od-win32/mp3decoder.cpp +++ b/od-win32/mp3decoder.cpp @@ -99,13 +99,12 @@ mp3decoder::mp3decoder() } } -uae_u8 *mp3decoder::get (struct zfile *zf, int maxsize) +uae_u8 *mp3decoder::get (struct zfile *zf, uae_u8 *outbuf, int maxsize) { MMRESULT mmr; unsigned long rawbufsize = 0; LPBYTE mp3buf; LPBYTE rawbuf; - uae_u8 *outbuf = NULL; int outoffset = 0; ACMSTREAMHEADER mp3streamHead; HACMSTREAM h = (HACMSTREAM)g_mp3stream; @@ -133,7 +132,6 @@ uae_u8 *mp3decoder::get (struct zfile *zf, int maxsize) return NULL; } zfile_fseek(zf, 0, SEEK_SET); - outbuf = xcalloc(uae_u8, maxsize + 2352); for (;;) { int count = zfile_fread(mp3buf, 1, MP3_BLOCK_SIZE, zf); if (count != MP3_BLOCK_SIZE) diff --git a/od-win32/mp3decoder.h b/od-win32/mp3decoder.h index 7655c801..0fa1d926 100644 --- a/od-win32/mp3decoder.h +++ b/od-win32/mp3decoder.h @@ -5,6 +5,6 @@ class mp3decoder public: mp3decoder(); ~mp3decoder(); - uae_u8 *get(struct zfile *zf, int maxsize); + uae_u8 *get(struct zfile *zf, uae_u8 *, int maxsize); uae_u32 mp3decoder::getsize(struct zfile *zf); }; diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index bb590b1a..aefd3661 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -84,6 +84,7 @@ #include "cdtv.h" #include "direct3d.h" #include "clipboard_win32.h" +#include "blkdev.h" #ifdef RETROPLATFORM #include "rp.h" #endif @@ -416,6 +417,7 @@ void resumepaused (int priority) #ifdef CDTV cdtv_exitgui (); #endif + blkdev_exitgui (); if (pausemouseactive) setmouseactive (-1); pausemouseactive = 0; @@ -437,6 +439,7 @@ void setpaused (int priority) #ifdef CDTV cdtv_entergui (); #endif + blkdev_entergui (); pausemouseactive = 1; if (isfullscreen () <= 0) { pausemouseactive = mouseactive; diff --git a/od-win32/win32.h b/od-win32/win32.h index bc460e4c..4114b427 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -18,8 +18,8 @@ #define WINUAEPUBLICBETA 1 #define LANG_DLL 1 -#define WINUAEBETA L"5" -#define WINUAEDATE MAKEBD(2010, 7, 23) +#define WINUAEBETA L"6" +#define WINUAEDATE MAKEBD(2010, 7, 24) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/win32_uaenet.cpp b/od-win32/win32_uaenet.cpp index d021abbc..b599aa5b 100644 --- a/od-win32/win32_uaenet.cpp +++ b/od-win32/win32_uaenet.cpp @@ -156,7 +156,7 @@ static void *uaenet_trap_threadr (void *arg) r = pcap_next_ex (sd->fp, &header, &pkt_data); if (r == 1) { uae_sem_wait (&sd->change_sem); - sd->gotfunc ((struct devstruct*)sd->user, pkt_data, header->len); + sd->gotfunc ((struct s2devstruct*)sd->user, pkt_data, header->len); uae_sem_post (&sd->change_sem); } if (r < 0) { @@ -180,7 +180,7 @@ static void *uaenet_trap_threadw (void *arg) int donotwait = 0; int towrite = sd->mtu; uae_sem_wait (&sd->change_sem); - if (sd->getfunc ((struct devstruct*)sd->user, sd->writebuffer, &towrite)) { + if (sd->getfunc ((struct s2devstruct*)sd->user, sd->writebuffer, &towrite)) { pcap_sendpacket (sd->fp, sd->writebuffer, towrite); donotwait = 1; } diff --git a/od-win32/win32_uaenet.h b/od-win32/win32_uaenet.h index 55071bba..daefde5b 100644 --- a/od-win32/win32_uaenet.h +++ b/od-win32/win32_uaenet.h @@ -7,8 +7,8 @@ struct netdriverdata int active; }; -typedef void (uaenet_gotfunc)(struct devstruct *dev, const uae_u8 *data, int len); -typedef int (uaenet_getfunc)(struct devstruct *dev, uae_u8 *d, int *len); +typedef void (uaenet_gotfunc)(struct s2devstruct *dev, const uae_u8 *data, int len); +typedef int (uaenet_getfunc)(struct s2devstruct *dev, uae_u8 *d, int *len); #define MAX_TOTAL_NET_DEVICES 10 @@ -20,7 +20,7 @@ extern int uaenet_getdatalenght (void); extern int uaenet_getbytespending (void*); extern int uaenet_open (void*, struct netdriverdata*, void*, uaenet_gotfunc*, uaenet_getfunc*, int); extern void uaenet_close (void*); -extern void uaenet_gotdata (struct devstruct *dev, const uae_u8 *data, int len); -extern int uaenet_getdata (struct devstruct *dev, uae_u8 *d, int *len); +extern void uaenet_gotdata (struct s2devstruct *dev, const uae_u8 *data, int len); +extern int uaenet_getdata (struct s2devstruct *dev, uae_u8 *d, int *len); extern void uaenet_trigger (void*); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 946c79d2..74087578 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -914,7 +914,9 @@ static TCHAR *favoritepopup (HWND hwnd, int drive) idx2--; if (p2) { fname = my_strdup (p2 + 1); - p2[0] = 0; + do { + *p2-- = 0; + } while (p2 > tmp2 && *p2 == ' '); p2 = _tcschr (fname, '"'); if (p2) *p2 = 0; @@ -2440,6 +2442,8 @@ static BOOL CreateHardFile (HWND hDlg, UINT hfsizem, TCHAR *dostype, TCHAR *newp if (dynamic) { if (!_stscanf (dostype, L"%x", &dt)) dt = 0; + if (_tcslen (init_path) > 4 && !_tcsicmp (init_path + _tcslen (init_path) - 4, L".hdf")) + _tcscpy (init_path + _tcslen (init_path) - 4, L".vhd"); result = vhd_create (init_path, hfsize, dt); } else { SetCursor (LoadCursor (NULL, IDC_WAIT)); @@ -9095,7 +9099,7 @@ static ACCEL HarddiskAccel[] = { { 0, 0, 0 } }; -static void harddiskdlg_button (HWND hDlg, WPARAM wParam) +static int harddiskdlg_button (HWND hDlg, WPARAM wParam) { int button = LOWORD (wParam); switch (button) { @@ -9115,19 +9119,19 @@ static void harddiskdlg_button (HWND hDlg, WPARAM wParam) archivehd = 0; if (CustomDialogBox (IDD_FILESYS, hDlg, VolumeSettingsProc)) new_filesys (hDlg, -1); - break; + return 1; case IDC_NEW_FSARCH: archivehd = 1; current_fsvdlg = empty_fsvdlg; if (CustomDialogBox (IDD_FILESYS, hDlg, VolumeSettingsProc)) new_filesys (hDlg, -1); - break; + return 1; case IDC_NEW_HF: current_hfdlg = empty_hfdlg; if (CustomDialogBox (IDD_HARDFILE, hDlg, HardfileSettingsProc)) new_hardfile (hDlg, -1); - break; + return 1; case IDC_NEW_HD: memset (¤t_hfdlg, 0, sizeof (current_hfdlg)); @@ -9139,25 +9143,25 @@ static void harddiskdlg_button (HWND hDlg, WPARAM wParam) if (CustomDialogBox (IDD_HARDDRIVE, hDlg, HarddriveSettingsProc)) new_harddrive (hDlg, -1); } - break; + return 1; case IDC_EDIT: harddisk_edit (hDlg); - break; + return 1; case IDC_REMOVE: harddisk_remove (hDlg); - break; + return 1; case IDC_UP: harddisk_move (hDlg, 1); clicked_entry--; - break; + return 1; case IDC_DOWN: harddisk_move (hDlg, 0); clicked_entry++; - break; + return 1; case IDC_MAPDRIVES_AUTO: workprefs.win32_automount_removable = ischecked (hDlg, IDC_MAPDRIVES_AUTO); @@ -9188,6 +9192,7 @@ static void harddiskdlg_button (HWND hDlg, WPARAM wParam) break; } + return 0; } static void harddiskdlg_volume_notify (HWND hDlg, NM_LISTVIEW *nmlistview) @@ -9316,9 +9321,10 @@ static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA hilitehd (); break; default: - harddiskdlg_button (hDlg, wParam); - InitializeListView (hDlg); - hilitehd (); + if (harddiskdlg_button (hDlg, wParam)) { + InitializeListView (hDlg); + hilitehd (); + } break; } } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 4b0c7433..68d2ea10 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,9 +1,58 @@ +- MP3/FLAC background decompression, no more delayed CDA startup if audio file + decompression takes more than 2 seconds +- implemented "delayed decompression" zfile open flag, currently only zip backend supports it + and it is only enabled when using CD images. Most zipped CD images with big audio files + start almost instantly now +- potential memory corruption crash in zfile_fclose() if file had parent file(s) +- zero length disk DMA (used by some copy protections) never finished, broke in b1 +- fixed extra space characters in favorite menu items +- pause uaescsi.device CDA when emulation is paused or GUI is open +- uaescsi.device CDA lights green on screen CD led +- cue/bin audio tracks were completely silent (cue/wav worked) +- on the fly image switching didn't send uaescsi.device change interrupts correctly + if CDFS polling flag was disabled (empty drive without diskchange command) +- new dynamic hardfiles have .vhd extension instead of .hdf + +Beta 5 + +- version number bumped to 2.3 - few lines of non-filter scanlines was missing in bottom part of display +- audio DMA start interrupt is now immediate after starting DMA in too fast CPU modes + (normally when audio state changes to 5), fixes EasyACDDA hang. Seems to be + yet another audio.device bug when CPU and memory is "too fast".. + +More CD related changes and updates: + +- unified CD32/CDTV CD unit allocation, also internal unit number is always zero = + GUI CD media change now work as expected +- CDTV frontpanel Stop now quits frontpanel/CD+G mode correctly +- added more obsolete SCSI commands: PLAY AUDIO TRACK RELATIVE (10) and (12) and + PLAY AUDIO (12) (10-byte version was added in b4) +- CDTV subchannel hardware interrupt timing improved, CD+G works in cycle-exact mode now +- cd configuration code cleanups +- added mds/mdf image format (only v1 and first session, v2 appears to be scrambled..) +- cdimage0 in configuration file now disables all following units (backwards compatiblity) + add 2 or more cdimage[0-7]= lines in increasing order if you want multiple units configured +- cue/ccd/iso/mds detection in zipped cd images stopped working +- moved 2048 to 2352 byte sector conversion code to generic image mounter code from CD32 + emulation, CD32 FMV ROM now detects VideoCDs (and then it hangs) - 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 + first 100 frames have equal bit rate, fallback to original slow full file scan if no tags and VBR +- remove mp3 decoding time from audio playback delay time, keeps av sync if decoding takes less than 2 seconds +- FLAC CD audio tracks supported (cue/iso/flac), perhaps this will be useful in future.. + (remember to redownload winuaeinclibs.zip if you want to recompile this or future versions) +- note that currently both mp3 and flac decoding needs to finish before playback starts which + can take few seconds on slow machines +- some XP-only CD access issues fixed, tested on VMware workstation (donated by Cloanto). + VirtualPC sucks too much. +- when looking for cue/iso/ccd/mds inside archives: do not attempt to autodetect (unpack) + other files. CD image archives containing audio tracks should start faster now (all audio + tracks are still unpacked at startup but previously they were unpacked twice) + +Future todo: hardware IDE (ATAPI) and SCSI emulation to CD SCSI emulation connection, no big CD +GUI updates until it has been designed. (won't be done in this beta series) Beta 4: @@ -47,11 +96,6 @@ If CD32 or CDTV is started in "autodetect" mode and it chose unit 1 or later (CD Audio CD inserted), unit 0 changes are ignored until original drive becomes empty. This needs to be more intelligent. -Configuration file accepts cdimage0 to cdimage7. Full syntax: -cdimagex=image path or device name,cd backend(:reserved for future) -Cd backend not mandatory. Supported CD backend names are: -image, ioctl, spti and aspi. (this is autoselected when using GUI) - Beta 3: - most debugger options now accept .b, .w and .l size extension (+special .3 if 3-byte word), diff --git a/sana2.cpp b/sana2.cpp index be8f1d54..088b07d9 100644 --- a/sana2.cpp +++ b/sana2.cpp @@ -168,7 +168,7 @@ struct mcast { int cnt; }; -struct devstruct { +struct s2devstruct { int unit, opencnt, exclusive, promiscuous; struct asyncreq *ar; struct asyncreq *s2p; @@ -197,7 +197,7 @@ struct devstruct { #define FLUSH_TIMEOUT 20 -struct priv_devstruct { +struct priv_s2devstruct { int inuse; int unit; int flags; /* OpenDevice() */ @@ -224,19 +224,19 @@ struct priv_devstruct { }; static struct netdriverdata *td; -static struct devstruct devst[MAX_TOTAL_NET_DEVICES]; -static struct priv_devstruct pdevst[MAX_OPEN_DEVICES]; +static struct s2devstruct devst[MAX_TOTAL_NET_DEVICES]; +static struct priv_s2devstruct pdevst[MAX_OPEN_DEVICES]; static uae_u32 nscmd_cmd; static uae_sem_t change_sem, async_sem; -static struct devstruct *getdevstruct (int unit) +static struct s2devstruct *gets2devstruct (int unit) { if (unit >= MAX_TOTAL_NET_DEVICES || unit < 0) return 0; return &devst[unit]; } -static struct priv_devstruct *getpdevstruct (uaecptr request) +static struct priv_s2devstruct *getps2devstruct (uaecptr request) { int i = get_long (request + 24); if (i < 0 || i >= MAX_OPEN_DEVICES || pdevst[i].inuse == 0) { @@ -247,7 +247,7 @@ static struct priv_devstruct *getpdevstruct (uaecptr request) } static void *dev_thread (void *devs); -static int start_thread (struct devstruct *dev) +static int start_thread (struct s2devstruct *dev) { if (dev->thread_running) return 1; @@ -261,14 +261,14 @@ static int start_thread (struct devstruct *dev) static uae_u32 REGPARAM2 dev_close_2 (TrapContext *context) { uae_u32 request = m68k_areg (regs, 1); - struct priv_devstruct *pdev = getpdevstruct (request); - struct devstruct *dev; + struct priv_s2devstruct *pdev = getps2devstruct (request); + struct s2devstruct *dev; if (!pdev) { write_log (L"%s close with unknown request %08X!?\n", SANA2NAME, request); return 0; } - dev = getdevstruct (pdev->unit); + dev = gets2devstruct (pdev->unit); if (!dev) { write_log (L"%s:%d close with unknown request %08X!?\n", SANA2NAME, pdev->unit, request); return 0; @@ -349,8 +349,8 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context) uae_u32 unit = m68k_dreg (regs, 0); uae_u32 flags = m68k_dreg (regs, 1); uaecptr buffermgmt; - struct devstruct *dev = getdevstruct (unit); - struct priv_devstruct *pdev = 0; + struct s2devstruct *dev = gets2devstruct (unit); + struct priv_s2devstruct *pdev = 0; int i; uaecptr tagp, tagpnext; @@ -486,7 +486,7 @@ static void freepacket (struct s2packet *s2p) xfree (s2p); } -static void add_async_packet (struct devstruct *dev, struct s2packet *s2p, uaecptr request) +static void add_async_packet (struct s2devstruct *dev, struct s2packet *s2p, uaecptr request) { struct asyncreq *ar, *ar2; @@ -503,7 +503,7 @@ static void add_async_packet (struct devstruct *dev, struct s2packet *s2p, uaecp ar->request = request; } -static void rem_async_packet (struct devstruct *dev, uaecptr request) +static void rem_async_packet (struct s2devstruct *dev, uaecptr request) { struct asyncreq *ar, *prevar; @@ -527,7 +527,7 @@ static void rem_async_packet (struct devstruct *dev, uaecptr request) uae_sem_post (&async_sem); } -static struct asyncreq *get_async_request (struct devstruct *dev, uaecptr request, int ready) +static struct asyncreq *get_async_request (struct s2devstruct *dev, uaecptr request, int ready) { struct asyncreq *ar; int ret = 0; @@ -546,7 +546,7 @@ static struct asyncreq *get_async_request (struct devstruct *dev, uaecptr reques return ar; } -static int add_async_request (struct devstruct *dev, uaecptr request) +static int add_async_request (struct s2devstruct *dev, uaecptr request) { struct asyncreq *ar, *ar2; @@ -568,7 +568,7 @@ static int add_async_request (struct devstruct *dev, uaecptr request) return 1; } -static int release_async_request (struct devstruct *dev, uaecptr request) +static int release_async_request (struct s2devstruct *dev, uaecptr request) { struct asyncreq *ar, *prevar; @@ -595,7 +595,7 @@ static int release_async_request (struct devstruct *dev, uaecptr request) return 0; } -static void do_abort_async (struct devstruct *dev, uaecptr request) +static void do_abort_async (struct s2devstruct *dev, uaecptr request) { put_byte (request + 30, get_byte (request + 30) | 0x20); put_byte (request + 31, IOERR_ABORTED); @@ -603,7 +603,7 @@ static void do_abort_async (struct devstruct *dev, uaecptr request) write_comm_pipe_u32 (&dev->requests, request, 1); } -static void abort_async (struct devstruct *dev, uaecptr request) +static void abort_async (struct s2devstruct *dev, uaecptr request) { struct asyncreq *ar = get_async_request (dev, request, 1); if (!ar) { @@ -615,7 +615,7 @@ static void abort_async (struct devstruct *dev, uaecptr request) do_abort_async (dev, request); } -static void signalasync (struct devstruct *dev, struct asyncreq *ar, int actual, int err) +static void signalasync (struct s2devstruct *dev, struct asyncreq *ar, int actual, int err) { uaecptr request = ar->request; int command = get_word (request + 28); @@ -691,7 +691,7 @@ static uae_u64 amigaaddrto64 (uaecptr d) return addr; } -static void addmulticastaddresses (struct devstruct *dev, uae_u64 start, uae_u64 end) +static void addmulticastaddresses (struct s2devstruct *dev, uae_u64 start, uae_u64 end) { struct mcast *mc, *mc2; @@ -718,7 +718,7 @@ static void addmulticastaddresses (struct devstruct *dev, uae_u64 start, uae_u64 mc2->next = mc; } } -static int delmulticastaddresses (struct devstruct *dev, uae_u64 start, uae_u64 end) +static int delmulticastaddresses (struct s2devstruct *dev, uae_u64 start, uae_u64 end) { struct mcast *mc, *prevmc; @@ -744,7 +744,7 @@ static int delmulticastaddresses (struct devstruct *dev, uae_u64 start, uae_u64 return 0; } -static struct s2packet *createreadpacket (struct devstruct *dev, const uae_u8 *d, int len) +static struct s2packet *createreadpacket (struct s2devstruct *dev, const uae_u8 *d, int len) { struct s2packet *s2p = xcalloc (struct s2packet, 1); s2p->data = xmalloc (uae_u8, dev->td->mtu + ETH_HEADER_SIZE + 2); @@ -753,7 +753,7 @@ static struct s2packet *createreadpacket (struct devstruct *dev, const uae_u8 *d return s2p; } -static int handleread (TrapContext *ctx, struct priv_devstruct *pdev, uaecptr request, uae_u8 *d, int len, int cmd) +static int handleread (TrapContext *ctx, struct priv_s2devstruct *pdev, uaecptr request, uae_u8 *d, int len, int cmd) { uae_u8 flags = get_byte (request + 30); uaecptr data = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4); @@ -794,7 +794,7 @@ static int handleread (TrapContext *ctx, struct priv_devstruct *pdev, uaecptr re return 1; } -void uaenet_gotdata (struct devstruct *dev, const uae_u8 *d, int len) +void uaenet_gotdata (struct s2devstruct *dev, const uae_u8 *d, int len) { uae_u16 type; struct mcast *mc; @@ -853,7 +853,7 @@ static struct s2packet *createwritepacket (TrapContext *ctx, uaecptr request) uaecptr srcaddr = request + 32 + 4 + 4; uaecptr dstaddr = request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES; uae_u16 packettype = get_long (request + 32 + 4); - struct priv_devstruct *pdev = getpdevstruct (request); + struct priv_s2devstruct *pdev = getps2devstruct (request); struct s2packet *s2p; if (!pdev) @@ -881,7 +881,7 @@ static struct s2packet *createwritepacket (TrapContext *ctx, uaecptr request) return s2p; } -static int uaenet_getdata (struct devstruct *dev, uae_u8 *d, int *len) +static int uaenet_getdata (struct s2devstruct *dev, uae_u8 *d, int *len) { int gotit; struct asyncreq *ar; @@ -895,7 +895,7 @@ static int uaenet_getdata (struct devstruct *dev, uae_u8 *d, int *len) int command = get_word (request + 28); uae_u32 packettype = get_long (request + 32 + 4); if (command == CMD_WRITE || command == S2_BROADCAST || command == S2_MULTICAST) { - struct priv_devstruct *pdev = getpdevstruct (request); + struct priv_s2devstruct *pdev = getps2devstruct (request); struct asyncreq *ars2p = dev->s2p; while (ars2p) { if (ars2p->request == request) { @@ -921,7 +921,7 @@ static int uaenet_getdata (struct devstruct *dev, uae_u8 *d, int *len) return gotit; } -void checkevents (struct devstruct *dev, int mask, int sem) +void checkevents (struct s2devstruct *dev, int mask, int sem) { struct asyncreq *ar; @@ -942,7 +942,7 @@ void checkevents (struct devstruct *dev, int mask, int sem) uae_sem_post (&async_sem); } -static int checksize (uaecptr request, struct devstruct *dev) +static int checksize (uaecptr request, struct s2devstruct *dev) { uae_u32 datalength = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2); @@ -951,15 +951,15 @@ static int checksize (uaecptr request, struct devstruct *dev) return 1; } -static void flush (struct priv_devstruct *pdev) +static void flush (struct priv_s2devstruct *pdev) { struct asyncreq *ar; - struct devstruct *dev; + struct s2devstruct *dev; - dev = getdevstruct (pdev->unit); + dev = gets2devstruct (pdev->unit); ar = dev->ar; while (ar) { - if (!ar->ready && getpdevstruct (ar->request) == pdev) { + if (!ar->ready && getps2devstruct (ar->request) == pdev) { ar->ready = 1; do_abort_async (dev, ar->request); } @@ -967,7 +967,7 @@ static void flush (struct priv_devstruct *pdev) } } -static int dev_do_io_2 (struct devstruct *dev, uaecptr request, int quick) +static int dev_do_io_2 (struct s2devstruct *dev, uaecptr request, int quick) { uae_u8 flags = get_byte (request + 30); uae_u32 command = get_word (request + 28); @@ -982,7 +982,7 @@ static int dev_do_io_2 (struct devstruct *dev, uaecptr request, int quick) uae_u32 wire_error = 0; int i; int async = 0; - struct priv_devstruct *pdev = getpdevstruct (request); + struct priv_s2devstruct *pdev = getps2devstruct (request); if (log_net) write_log (L"S2: C=%02d T=%04X S=%02X%02X%02X%02X%02X%02X D=%02X%02X%02X%02X%02X%02X L=%d D=%08X SD=%08X BM=%08X\n", @@ -1225,10 +1225,10 @@ end: return async; } -static int dev_do_io (struct devstruct *dev, uaecptr request, int quick) +static int dev_do_io (struct s2devstruct *dev, uaecptr request, int quick) { uae_u32 command = get_word (request + 28); - struct priv_devstruct *pdev = getpdevstruct (request); + struct priv_s2devstruct *pdev = getps2devstruct (request); uaecptr data = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4); put_byte (request + 31, 0); @@ -1267,7 +1267,7 @@ static int dev_can_quick (uae_u32 command) return 0; } -static int dev_canquick (struct devstruct *dev, uaecptr request) +static int dev_canquick (struct s2devstruct *dev, uaecptr request) { uae_u32 command = get_word (request + 28); return dev_can_quick (command); @@ -1278,8 +1278,8 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context) uae_u32 request = m68k_areg (regs, 1); uae_u8 flags = get_byte (request + 30); int command = get_word (request + 28); - struct priv_devstruct *pdev = getpdevstruct (request); - struct devstruct *dev; + struct priv_s2devstruct *pdev = getps2devstruct (request); + struct s2devstruct *dev; put_byte (request + 8, NT_MESSAGE); if (!pdev) { @@ -1287,7 +1287,7 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context) put_byte (request + 31, 32); return get_byte (request + 31); } - dev = getdevstruct (pdev->unit); + dev = gets2devstruct (pdev->unit); if (!dev) { write_log (L"%s unknown iorequest (2) %08x\n", getdevname (), request); put_byte (request + 31, 32); @@ -1334,7 +1334,7 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context) static void *dev_thread (void *devs) { - struct devstruct *dev = (struct devstruct*)devs; + struct s2devstruct *dev = (struct s2devstruct*)devs; uae_set_thread_priority (NULL, 1); dev->thread_running = 1; @@ -1380,15 +1380,15 @@ static uae_u32 REGPARAM2 dev_init (TrapContext *context) static uae_u32 REGPARAM2 dev_abortio (TrapContext *context) { uae_u32 request = m68k_areg (regs, 1); - struct priv_devstruct *pdev = getpdevstruct (request); - struct devstruct *dev; + struct priv_s2devstruct *pdev = getps2devstruct (request); + struct s2devstruct *dev; if (!pdev) { write_log (L"%s abortio but no request %08x found!\n", getdevname(), request); put_byte (request + 31, 32); return get_byte (request + 31); } - dev = getdevstruct (pdev->unit); + dev = gets2devstruct (pdev->unit); if (!dev) { write_log (L"%s (%d) abortio but no request %08x found!\n", getdevname(), pdev->unit, request); put_byte (request + 31, 32); @@ -1415,7 +1415,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx) pdevst[i].tmp = 0; for (i = 0; i < MAX_TOTAL_NET_DEVICES; i++) { - struct devstruct *dev = &devst[i]; + struct s2devstruct *dev = &devst[i]; struct s2packet *p; if (dev->online) { while (dev->readqueue) { @@ -1430,7 +1430,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx) int command = get_word (request + 28); uae_u32 packettype = get_long (request + 32 + 4); if (command == CMD_READ && (packettype == type || (packettype <= 1500 && type <= 1500))) { - struct priv_devstruct *pdev = getpdevstruct (request); + struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev && pdev->tmp == 0) { if (handleread (ctx, pdev, request, p->data, p->len, command)) { if (log_net) @@ -1455,7 +1455,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx) uaecptr request = ar->request; int command = get_word (request + 28); if (command == S2_READORPHAN) { - struct priv_devstruct *pdev = getpdevstruct (request); + struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev && pdev->tmp <= 0) { if (log_net) write_log (L"-> %p Accepted, S2_READORPHAN, REQ=%08X LEN=%d\n", p, request, p->len); @@ -1497,7 +1497,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx) uaecptr request = ar->request; int command = get_word (request + 28); if (command == S2_ONLINE) { - struct priv_devstruct *pdev = getpdevstruct (request); + struct priv_s2devstruct *pdev = getps2devstruct (request); dev->packetsreceived = 0; dev->packetssent = 0; dev->baddata = 0; @@ -1525,7 +1525,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx) write_comm_pipe_u32 (&dev->requests, request, 1); uaenet_vsync_requested--; } else { - struct priv_devstruct *pdev = getpdevstruct (request); + struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev) { dev->flush_timeout--; if (dev->flush_timeout <= 0) { @@ -1554,7 +1554,7 @@ static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx) static void dev_reset (void) { int i; - struct devstruct *dev; + struct s2devstruct *dev; int unitnum = 0; write_log (L"%s reset\n", getdevname()); @@ -1574,10 +1574,10 @@ static void dev_reset (void) } while (dev->mc) delmulticastaddresses (dev, dev->mc->start, dev->mc->end); - memset (dev, 0, sizeof (struct devstruct)); + memset (dev, 0, sizeof (struct s2devstruct)); } for (i = 0; i < MAX_OPEN_DEVICES; i++) - memset (&pdevst[i], 0, sizeof (struct priv_devstruct)); + memset (&pdevst[i], 0, sizeof (struct priv_s2devstruct)); uaenet_vsync_requested = 0; uaenet_int_requested = 0; irq_init = 0; diff --git a/zfile.cpp b/zfile.cpp index e840e24b..ad540aea 100644 --- a/zfile.cpp +++ b/zfile.cpp @@ -147,7 +147,14 @@ static struct zcache *zcache_put (const TCHAR *name, struct zdiskimage *data) zc->tm = time (NULL); return zc; } - + +static void checkarchiveparent (struct zfile *z) +{ + // unpack completely if opened in PEEK mode + if (z->archiveparent) + archive_unpackzfile (z); +} + static struct zfile *zfile_create (struct zfile *prev) { struct zfile *z; @@ -191,10 +198,6 @@ void zfile_exit (void) void zfile_fclose (struct zfile *f) { - struct zfile *pl = NULL; - struct zfile *l = zlist; - struct zfile *nxt; - //write_log (L"%p\n", f); if (!f) return; @@ -211,6 +214,13 @@ void zfile_fclose (struct zfile *f) if (f->parent->opencnt <= 0) zfile_fclose (f->parent); } + if (f->archiveparent) { + zfile_fclose (f->archiveparent); + f->archiveparent = NULL; + } + struct zfile *pl = NULL; + struct zfile *nxt; + struct zfile *l = zlist; while (l != f) { if (l == 0) { write_log (L"zfile: tried to free already freed or nonexisting filehandle!\n"); @@ -1836,6 +1846,8 @@ struct zfile *zfile_dup (struct zfile *zf) struct zfile *nzf; if (!zf) return NULL; + if (zf->archiveparent) + checkarchiveparent (zf); if (zf->userdata) return NULL; if (!zf->data && zf->dataseek) { @@ -1846,12 +1858,17 @@ struct zfile *zfile_dup (struct zfile *zf) memcpy (nzf->data, zf->data, zf->size); nzf->size = zf->size; nzf->datasize = zf->datasize; - } else if (zf->zipname) { - nzf = openzip (zf->name); - return nzf; - } else { + } else { + if (zf->zipname) { + nzf = openzip (zf->name); + if (nzf) + return nzf; + } + FILE *ff = _tfopen (zf->name, zf->mode); + if (!ff) + return NULL; nzf = zfile_create (zf); - nzf->f = _tfopen (zf->name, zf->mode); + nzf->f = ff; } zfile_fseek (nzf, zf->seek, SEEK_SET); if (zf->name) @@ -1997,8 +2014,10 @@ size_t zfile_fread (void *b, size_t l1, size_t l2, struct zfile *z) return z->zfileread (b, l1, l2, z); if (z->data) { if (z->datasize < z->size && z->seek + l1 * l2 > z->datasize) { - write_log (L"zfile_fread(%s) attempted to read past PEEK_BYTES\n", z->name); - + if (z->archiveparent) { + archive_unpackzfile (z); + return zfile_fread (b, l1, l2, z); + } return 0; } if (z->seek + l1 * l2 > z->size) { @@ -2037,6 +2056,8 @@ size_t zfile_fread (void *b, size_t l1, size_t l2, struct zfile *z) size_t zfile_fwrite (void *b, size_t l1, size_t l2, struct zfile *z) { + if (z->archiveparent) + return 0; if (z->zfilewrite) return z->zfilewrite (b, l1, l2, z); if (z->parent && z->useparent) @@ -2065,6 +2086,7 @@ size_t zfile_fputs (struct zfile *z, TCHAR *s) char *zfile_fgetsa (char *s, int size, struct zfile *z) { + checkarchiveparent (z); if (z->data) { char *os = s; int i; @@ -2090,6 +2112,7 @@ char *zfile_fgetsa (char *s, int size, struct zfile *z) TCHAR *zfile_fgets (TCHAR *s, int size, struct zfile *z) { + checkarchiveparent (z); if (z->data) { char s2[MAX_DPATH]; char *p = s2; @@ -2133,6 +2156,7 @@ int zfile_putc (int c, struct zfile *z) int zfile_getc (struct zfile *z) { + checkarchiveparent (z); int out = -1; if (z->data) { if (z->seek < z->size) { @@ -2159,14 +2183,10 @@ uae_u8 *zfile_getdata (struct zfile *z, uae_s64 offset, int len) zfile_fseek (z, 0, SEEK_SET); } b = xmalloc (uae_u8, len); - if (z->data) { - memcpy (b, z->data + offset, len); - } else { - pos = zfile_ftell (z); - zfile_fseek (z, offset, SEEK_SET); - zfile_fread (b, len, 1, z); - zfile_fseek (z, pos, SEEK_SET); - } + pos = zfile_ftell (z); + zfile_fseek (z, offset, SEEK_SET); + zfile_fread (b, len, 1, z); + zfile_fseek (z, pos, SEEK_SET); return b; } diff --git a/zfile_archive.cpp b/zfile_archive.cpp index 0fb55de8..6d35afe0 100644 --- a/zfile_archive.cpp +++ b/zfile_archive.cpp @@ -24,6 +24,8 @@ #include +#define unpack_log write_log + static time_t fromdostime (uae_u32 dd) { struct tm tm; @@ -84,49 +86,6 @@ static struct zvolume *getzvolume (struct znode *parent, struct zfile *zf, unsig return zv; } -struct zfile *archive_getzfile (struct znode *zn, unsigned int id, int flags) -{ - struct zfile *zf = NULL; - - switch (id) - { - case ArchiveFormatZIP: - zf = archive_access_zip (zn, flags); - break; - case ArchiveFormat7Zip: - zf = archive_access_7z (zn); - break; - case ArchiveFormatRAR: - zf = archive_access_rar (zn); - break; - case ArchiveFormatLHA: - zf = archive_access_lha (zn); - break; - case ArchiveFormatLZX: - zf = archive_access_lzx (zn); - break; - case ArchiveFormatPLAIN: - zf = archive_access_plain (zn); - break; - case ArchiveFormatADF: - zf = archive_access_adf (zn); - break; - case ArchiveFormatRDB: - zf = archive_access_rdb (zn); - break; - case ArchiveFormatFAT: - zf = archive_access_fat (zn); - break; - case ArchiveFormatDIR: - zf = archive_access_dir (zn); - break; - case ArchiveFormatTAR: - zf = archive_access_tar (zn); - break; - } - return zf; -} - struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, unsigned int id, int dodefault, int *retcode, int index) { struct zvolume *zv; @@ -138,6 +97,7 @@ struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, uns int diskimg; int mask = zf->zfdmask; int canhistory = (mask & ZFD_DISKHISTORY) && !(mask & ZFD_CHECKONLY); + int getflag = (mask & ZFD_DELAYEDOPEN) ? FILE_DELAYEDOPEN : 0; if (retcode) *retcode = 0; @@ -206,12 +166,12 @@ struct zfile *archive_access_select (struct znode *parent, struct zfile *zf, uns ft = ZFILE_CDIMAGE; } } else { - zt = archive_getzfile (zn, id, FILE_PEEK); + zt = archive_getzfile (zn, id, getflag); ft = zfile_gettype (zt); } if ((select < 0 || ft) && whf > we_have_file) { if (!zt) - zt = archive_getzfile (zn, id, FILE_PEEK); + zt = archive_getzfile (zn, id, getflag); we_have_file = whf; if (z) zfile_fclose (z); @@ -358,7 +318,6 @@ struct zfile *archive_access_tar (struct znode *zn) static void archive_close_zip (void *handle) { - unzClose (handle); } struct zvolume *archive_directory_zip (struct zfile *z) @@ -373,7 +332,7 @@ struct zvolume *archive_directory_zip (struct zfile *z) return 0; if (unzGoToFirstFile (uz) != UNZ_OK) return 0; - zv = zvolume_alloc (z, ArchiveFormatZIP, uz, NULL); + zv = zvolume_alloc (z, ArchiveFormatZIP, NULL, NULL); for (;;) { char filename_inzip2[MAX_DPATH]; TCHAR c; @@ -409,22 +368,29 @@ struct zvolume *archive_directory_zip (struct zfile *z) if (err != UNZ_OK) break; } + unzClose (uz); zv->method = ArchiveFormatZIP; return zv; } -struct zfile *archive_access_zip (struct znode *zn, int flags) +static struct zfile *archive_do_zip (struct znode *zn, struct zfile *z, int flags) { - struct zfile *z = NULL; - unzFile uz = zn->volume->handle; - int i, err; + unzFile uz; + int i; TCHAR tmp[MAX_DPATH]; + TCHAR *name = z ? z->archiveparent->name : zn->volume->root.fullname; char *s; - _tcscpy (tmp, zn->fullname + _tcslen (zn->volume->root.fullname) + 1); - if (unzGoToFirstFile (uz) != UNZ_OK) + uz = unzOpen (z ? z->archiveparent : zn->volume->archive); + if (!uz) return 0; + if (z) + _tcscpy (tmp, z->archiveparent->name); + else + _tcscpy (tmp, zn->fullname + _tcslen (zn->volume->root.fullname) + 1); + if (unzGoToFirstFile (uz) != UNZ_OK) + goto error; for (i = 0; tmp[i]; i++) { if (tmp[i] == '\\') tmp[i] = '/'; @@ -439,22 +405,52 @@ struct zfile *archive_access_zip (struct znode *zn, int flags) s = ua (tmp); if (unzLocateFile (uz, s, 1) != UNZ_OK) { xfree (s); - return 0; + goto error; } } xfree (s); s = NULL; if (unzOpenCurrentFile (uz) != UNZ_OK) - return 0; -// write_log (L"unpacking %s\n", zn->fullname); - z = zfile_fopen_empty (NULL, zn->fullname, zn->size); + goto error; + if (!z) + z = zfile_fopen_empty (NULL, zn->fullname, zn->size); if (z) { -// if (flags & FILE_PEEK) -// z->datasize = PEEK_BYTES; - err = unzReadCurrentFile (uz, z->data, z->datasize); + int err = -1; + if (!(flags & FILE_DELAYEDOPEN) || z->size <= PEEK_BYTES) { + unpack_log (L"ZIP: unpacking %s, flags=%d\n", name, flags); + err = unzReadCurrentFile (uz, z->data, z->datasize); + unpack_log (L"ZIP: unpacked, code=%d\n", err); + } else { + z->archiveparent = zfile_dup (zn->volume->archive); + if (z->archiveparent) { + unpack_log (L"ZIP: delayed open '%s'\n", name); + xfree (z->archiveparent->name); + z->archiveparent->name = my_strdup (tmp); + z->datasize = PEEK_BYTES; + err = unzReadCurrentFile (uz, z->data, z->datasize); + unpack_log (L"ZIP: unpacked, code=%d\n", err); + } else { + unpack_log (L"ZIP: unpacking %s (failed DELAYEDOPEN)\n", name); + err = unzReadCurrentFile (uz, z->data, z->datasize); + unpack_log (L"ZIP: unpacked, code=%d\n", err); + } + } } unzCloseCurrentFile (uz); + unzClose (uz); return z; +error: + unzClose (uz); + return NULL; +} + +static struct zfile *archive_access_zip (struct znode *zn, int flags) +{ + return archive_do_zip (zn, NULL, flags); +} +static struct zfile *archive_unpack_zip (struct zfile *zf) +{ + return archive_do_zip (NULL, zf, 0); } /* 7Z */ @@ -590,7 +586,7 @@ struct zvolume *archive_directory_7z (struct zfile *z) return zv; } -struct zfile *archive_access_7z (struct znode *zn) +static struct zfile *archive_access_7z (struct znode *zn) { SRes res; struct zvolume *zv = zn->volume; @@ -738,7 +734,7 @@ struct zvolume *archive_directory_rar (struct zfile *z) return zv; } -struct zfile *archive_access_rar (struct znode *zn) +static struct zfile *archive_access_rar (struct znode *zn) { struct RARContext *rc = (struct RARContext*)zn->volume->handle; int i; @@ -935,7 +931,7 @@ struct zvolume *archive_directory_arcacc (struct zfile *z, unsigned int id) } -struct zfile *archive_access_arcacc (struct znode *zn) +static struct zfile *archive_access_arcacc (struct znode *zn) { struct zfile *zf; struct zfile *z = zn->volume->archive; @@ -1049,7 +1045,7 @@ struct zvolume *archive_directory_plain (struct zfile *z) } return zv; } -struct zfile *archive_access_plain (struct znode *zn) +static struct zfile *archive_access_plain (struct znode *zn) { struct zfile *z; @@ -1500,7 +1496,7 @@ static int sfsfindblock (struct adfhandle *adf, int btree, int theblock, struct } -struct zfile *archive_access_adf (struct znode *zn) +static struct zfile *archive_access_adf (struct znode *zn) { struct zfile *z = NULL; int root, ffs; @@ -1713,7 +1709,7 @@ struct zvolume *archive_directory_rdb (struct zfile *z) return zv; } -struct zfile *archive_access_rdb (struct znode *zn) +static struct zfile *archive_access_rdb (struct znode *zn) { struct zfile *z = zn->volume->archive; struct zfile *zf; @@ -1978,7 +1974,7 @@ struct zvolume *archive_directory_fat (struct zfile *z) return zv; } -struct zfile *archive_access_fat (struct znode *zn) +static struct zfile *archive_access_fat (struct znode *zn) { uae_u8 buf[512] = { 0 }; int fatbits = 12; @@ -2047,8 +2043,72 @@ void archive_access_close (void *handle, unsigned int id) } } -struct zfile *archive_access_dir (struct znode *zn) +static struct zfile *archive_access_dir (struct znode *zn) { return zfile_fopen (zn->fullname, L"rb", 0); } + +struct zfile *archive_unpackzfile (struct zfile *zf) +{ + struct zfile *zout = NULL; + if (!zf->archiveparent) + return NULL; + unpack_log (L"delayed unpack '%s'\n", zf->name); + zf->datasize = zf->size; + switch (zf->archiveid) + { + case ArchiveFormatZIP: + zout = archive_unpack_zip (zf); + break; + } + zfile_fclose (zf->archiveparent); + zf->archiveparent = NULL; + zf->archiveid = 0; + return NULL; +} + +struct zfile *archive_getzfile (struct znode *zn, unsigned int id, int flags) +{ + struct zfile *zf = NULL; + + switch (id) + { + case ArchiveFormatZIP: + zf = archive_access_zip (zn, flags); + break; + case ArchiveFormat7Zip: + zf = archive_access_7z (zn); + break; + case ArchiveFormatRAR: + zf = archive_access_rar (zn); + break; + case ArchiveFormatLHA: + zf = archive_access_lha (zn); + break; + case ArchiveFormatLZX: + zf = archive_access_lzx (zn); + break; + case ArchiveFormatPLAIN: + zf = archive_access_plain (zn); + break; + case ArchiveFormatADF: + zf = archive_access_adf (zn); + break; + case ArchiveFormatRDB: + zf = archive_access_rdb (zn); + break; + case ArchiveFormatFAT: + zf = archive_access_fat (zn); + break; + case ArchiveFormatDIR: + zf = archive_access_dir (zn); + break; + case ArchiveFormatTAR: + zf = archive_access_tar (zn); + break; + } + if (zf) + zf->archiveid = id; + return zf; +} -- 2.47.3