]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc0992b1.zip
authorToni Wilen <twilen@winuae.net>
Wed, 1 Sep 2004 16:17:46 +0000 (19:17 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:24:18 +0000 (21:24 +0200)
49 files changed:
audio.c
blitter.c
cfgfile.c
custom.c
disk.c
drawing.c
filesys.c
fsdb.c
hardfile.c
include/custom.h
include/drawing.h
include/fsdb.h
include/keyboard.h
include/options.h
inputdevice.c
inputevents.def
main.c
memory.c
od-win32/7z/DLL.h [new file with mode: 0755]
od-win32/7z/Defs.h [new file with mode: 0755]
od-win32/7z/FileIO.h [new file with mode: 0755]
od-win32/7z/FileStreams.h [new file with mode: 0755]
od-win32/7z/IArchive.h [new file with mode: 0755]
od-win32/7z/IMyUnknown.h [new file with mode: 0755]
od-win32/7z/IProgress.h [new file with mode: 0755]
od-win32/7z/IStream.h [new file with mode: 0755]
od-win32/7z/MyCom.h [new file with mode: 0755]
od-win32/7z/PropID.h [new file with mode: 0755]
od-win32/7z/PropVariant.h [new file with mode: 0755]
od-win32/7z/PropVariantConversions.h [new file with mode: 0755]
od-win32/7z/String.h [new file with mode: 0755]
od-win32/7z/StringConvert.h [new file with mode: 0755]
od-win32/7z/Types.h [new file with mode: 0755]
od-win32/7z/Vector.h [new file with mode: 0755]
od-win32/7z/win32_decompress.cpp [new file with mode: 0755]
od-win32/dxwrap.h
od-win32/fsdb_win32.c
od-win32/keyboard_win32.c
od-win32/parser.c
od-win32/parser.h
od-win32/posixemu.c
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/sounddep/sound.c
od-win32/win32.c
od-win32/win32.h
od-win32/win32_decompress.c [new file with mode: 0755]
od-win32/win32gfx.c
od-win32/win32gui.c

diff --git a/audio.c b/audio.c
index 7dee685dab48d5f42e3aaa15e09904346c80a630..e836e1e1d68999140ce11dd41c83f29fc3a9f687 100755 (executable)
--- a/audio.c
+++ b/audio.c
@@ -911,7 +911,7 @@ void audio_hsync (int dmaaction)
                handle2 = 1;
            if (chan_ena) {
 #ifdef CPUEMU_6
-               cycle_line[13 + nr * 2] |= CYCLE_AUDIO;
+               cycle_line[13 + nr * 2] |= CYCLE_MISC;
 #endif
                if (cdp->request_word == 1 || cdp->request_word == 2)
                    cdp->pt += 2;
index 397cf42e0d8e5c613be3baee374b3f320575ada2..a95d4e42b191371a63a47af69128618567584103 100755 (executable)
--- a/blitter.c
+++ b/blitter.c
@@ -116,7 +116,7 @@ static uae_u8 blit_cycle_diagram_fill[][10] =
 
 static uae_u8 blit_cycle_diagram_line[] =
 {
-    0, 4, 0,0,3,4 /* total guess.. */
+    0, 4, 0,0,0,4 /* total guess.. */
 };
 
 void build_blitfilltable(void)
@@ -529,6 +529,14 @@ STATIC_INLINE int channel_state (int cycles)
     return blit_diag[((cycles - blit_diag[0]) % blit_diag[1]) + 2];
 }
 
+int is_bitplane_dma (int hpos);
+STATIC_INLINE int canblit (int hpos)
+{
+    if ((cycle_line[hpos] == 0 || cycle_line[hpos] == CYCLE_NOCPU) && !is_bitplane_dma (hpos))
+       return 1;
+    return 0;
+}
+
 #ifdef CPUEMU_6
 
 static int blit_last_hpos;
@@ -575,8 +583,6 @@ STATIC_INLINE uae_u16 blitter_doblit (void)
 }
 
 
-int is_bitplane_dma (int hpos);
-
 STATIC_INLINE int blitter_doddma (void)
 {
     int wd;
@@ -667,7 +673,7 @@ static void decide_blitter_line (int hpos)
        while (blit_last_hpos < hpos) {
            int c = channel_state (blit_cyclecounter);
            for (;;) {
-               if (c && (cycle_line[blit_last_hpos] || is_bitplane_dma (blit_last_hpos)))
+               if (c && !canblit (blit_last_hpos))
                    break;
                if (c)
                    cycle_line[blit_last_hpos] |= CYCLE_BLITTER;
@@ -719,7 +725,7 @@ void decide_blitter (int hpos)
            }
 #endif
            for (;;) {
-               if (c && (cycle_line[blit_last_hpos] || is_bitplane_dma (blit_last_hpos))) {
+               if (c && !canblit (blit_last_hpos)) {
                    blit_misscyclecounter++;
                    break;
                }
@@ -779,10 +785,14 @@ static void blitter_force_finish (void)
        dmacon |= DMA_MASTER | DMA_BLITTER;
        write_log ("forcing blitter finish\n");
        if (currprefs.blitter_cycle_exact) {
-           while (bltstate != BLT_done) {
+           int rounds = 10000;
+           while (bltstate != BLT_done && rounds > 0) {
                memset (cycle_line, 0, maxhpos);
                decide_blitter (maxhpos);
+               rounds--;
            }
+           if (rounds == 0)
+               write_log ("blitter froze!?\n");
        } else {
            actually_do_blit ();
        }
@@ -833,6 +843,7 @@ static void blit_bltset (int con)
     if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS))
        write_log("warning: BLTCON1 DOFF-bit set\n");
 
+    ddat1use = ddat2use = 0;
     blit_dmacount = blit_dmacount2 = 0;
     for (i = 0; i < blit_diag[1]; i++) {
        int v = blit_diag[2 + i];
@@ -958,7 +969,8 @@ void maybe_blit (int hpos, int hack)
 #ifndef BLITTER_DEBUG
        warned = 1;
 #endif
-       write_log ("warning: Program does not wait for blitter %p\n", m68k_getpc());
+       write_log ("warning: Program does not wait for blitter %p vpos=%d tc=%d\n",
+           m68k_getpc(), vpos, blit_cyclecounter);
     }
 
     if (currprefs.blitter_cycle_exact) {
index ea169a2f122716ea086d75c61c3c0ec6568ff442..c565268661f62308e796de60377fd4428daa6386 100755 (executable)
--- a/cfgfile.c
+++ b/cfgfile.c
@@ -310,6 +310,9 @@ static void save_options (struct zfile *f, struct uae_prefs *p, int type)
 
     cfgfile_write (f, "synchronize_clock=%s\n", p->tod_hack ? "yes" : "no");
     cfgfile_write (f, "maprom=0x%x\n", p->maprom);
+    cfgfile_write (f, "parallel_postscript_emulation=%s\n", p->parallel_postscript_emulation ? "yes" : "no");
+    cfgfile_write (f, "parallel_postscript_detection=%s\n", p->parallel_postscript_detection ? "yes" : "no");
+    cfgfile_write (f, "ghostscript_parameters=%s\n", p->ghostscript_parameters);
 
     cfgfile_write (f, "gfx_display=%d\n", p->gfx_display);
     cfgfile_write (f, "gfx_framerate=%d\n", p->gfx_framerate);
@@ -382,6 +385,7 @@ static void save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_write (f, "chipset=ecs_denise\n");
     else
        cfgfile_write (f, "chipset=ocs\n");
+    cfgfile_write (f, "chipset_refreshrate=%d\n", p->chipset_refreshrate);
     cfgfile_write (f, "collision_level=%s\n", collmode[p->collision_level]);
 
     cfgfile_write (f, "fastmem_size=%d\n", p->fastmem_size / 0x100000);
@@ -845,6 +849,8 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu
        || cfgfile_yesno (option, value, "blitter_cycle_exact", &p->blitter_cycle_exact)
        || cfgfile_yesno (option, value, "cpu_24bit_addressing", &p->address_space_24)
        || cfgfile_yesno (option, value, "parallel_on_demand", &p->parallel_demand)
+       || cfgfile_yesno (option, value, "parallel_postscript_emulation", &p->parallel_postscript_emulation)
+       || cfgfile_yesno (option, value, "parallel_postscript_detection", &p->parallel_postscript_detection)
        || cfgfile_yesno (option, value, "serial_on_demand", &p->serial_demand)
        || cfgfile_yesno (option, value, "serial_hardware_ctsrts", &p->serial_hwctsrts)
        || cfgfile_yesno (option, value, "serial_direct", &p->serial_direct)
@@ -858,6 +864,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu
        || cfgfile_yesno (option, value, "scsi", &p->scsi))
        return 1;
     if (cfgfile_intval (option, value, "cachesize", &p->cachesize, 1)
+       || cfgfile_intval (option, value, "chipset_refreshrate", &p->chipset_refreshrate, 1)
        || cfgfile_intval (option, value, "fastmem_size", &p->fastmem_size, 0x100000)
        || cfgfile_intval (option, value, "a3000mem_size", &p->a3000mem_size, 0x100000)
        || cfgfile_intval (option, value, "z3mem_size", &p->z3fastmem_size, 0x100000)
@@ -883,7 +890,8 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu
        || cfgfile_string (option, value, "kickstart_ext_rom_file", p->romextfile, 256)
        || cfgfile_string (option, value, "flash_file", p->flashfile, 256)
        || cfgfile_string (option, value, "cart_file", p->cartfile, 256)
-       || cfgfile_string (option, value, "pci_devices", p->pci_devices, 256))
+       || cfgfile_string (option, value, "pci_devices", p->pci_devices, 256)
+       || cfgfile_string (option, value, "ghostscript_parameters", p->ghostscript_parameters, 256))
        return 1;
 
     for (i = 0; i < 4; i++) {
@@ -1342,6 +1350,7 @@ int cfgfile_load (struct uae_prefs *p, const char *filename, int *type, int igno
     }
 end:
     recursive--;
+    fixup_prefs (p);
     return v;
 }
 
@@ -1762,7 +1771,7 @@ void cfgfile_addcfgparam (char *line)
     temp_lines = u;
 }
 
-static int cmdlineparser (char *s, char *outp[], int max)
+int cmdlineparser (char *s, char *outp[], int max)
 {
     int j, cnt = 0;
     int slash = 0;
@@ -2161,6 +2170,8 @@ void default_prefs (struct uae_prefs *p, int type)
     p->catweasel_io = 0;
     p->tod_hack = 0;
     p->maprom = 0;
+    p->filesys_no_uaefsdb = 0;
+    p->filesys_custom_uaefsdb = 1;
 
     p->gfx_filter = 0;
     p->gfx_filter_filtermode = 1;
@@ -2231,8 +2242,21 @@ static void buildin_default_prefs_68020 (struct uae_prefs *p)
     p->m68k_speed = -1;
 }
 
+static void buildin_default_host_prefs (struct uae_prefs *p)
+{
+    p->sound_filter = 1;
+    p->sound_stereo = 1;
+    p->sound_stereo_separation = 7;
+    p->sound_mixed_stereo = 0;
+}
+
 static void buildin_default_prefs (struct uae_prefs *p)
 {
+    free_mountinfo (currprefs.mountinfo);
+    currprefs.mountinfo = p->mountinfo = alloc_mountinfo ();
+
+    buildin_default_host_prefs (p);
+
     p->nr_floppies = 2;
     p->dfxtype[0] = 0;
     p->dfxtype[1] = 0;
@@ -2256,10 +2280,6 @@ static void buildin_default_prefs (struct uae_prefs *p)
     p->catweasel_io = 0;
     p->tod_hack = 0;
     p->maprom = 0;
-    p->sound_filter = 1;
-    p->sound_stereo = 1;
-    p->sound_stereo_separation = 7;
-    p->sound_mixed_stereo = 0;
     p->cachesize = 0;
 
     p->chipmem_size = 0x00080000;
index bc5d84db4cc91f90d6626793f925427b5b34b53d..1b482913e9437982fd7553c9512b79da2778c40a 100755 (executable)
--- a/custom.c
+++ b/custom.c
@@ -11,8 +11,8 @@
 //#define CUSTOM_DEBUG
 #define DEBUG_COPPER 0
 #define SPRITE_DEBUG 0
-#define SPRITE_DEBUG_MINY 0
-#define SPRITE_DEBUG_MAXY 400
+#define SPRITE_DEBUG_MINY 50
+#define SPRITE_DEBUG_MAXY 200
 //#define DISABLE_SPRITES
 #define SPR0_HPOS 0x15
 #define MAX_SPRITES 8
@@ -358,6 +358,11 @@ enum fetchstate {
  * helper functions
  */
 
+STATIC_INLINE int nodraw (void)
+{
+    return !currprefs.cpu_cycle_exact && framecnt != 0;
+}
+
 uae_u32 get_copper_address (int copno)
 {
     switch (copno) {
@@ -1386,7 +1391,7 @@ STATIC_INLINE void update_fetch (int until, int fm)
 
     int ddfstop_to_test;
 
-    if (framecnt != 0 || passed_plfstop == 3)
+    if (nodraw() || passed_plfstop == 3)
        return;
 
     /* We need an explicit test against HARD_DDF_STOP here to guard against
@@ -1519,7 +1524,7 @@ static void start_bpl_dma (int hpos, int hstart)
 
     /* If someone already wrote BPL1DAT, clear the area between that point and
        the real fetch start.  */
-    if (framecnt == 0) {
+    if (!nodraw ()) {
        if (thisline_decision.plfleft != -1) {
            out_nbits = (plfstrt - thisline_decision.plfleft) << (1 + toscr_res);
            out_offs = out_nbits >> 5;
@@ -1604,7 +1609,7 @@ static void record_color_change (int hpos, int regno, unsigned long value)
     }
 
     /* Early positions don't appear on-screen. */
-    if (framecnt != 0 || vpos < minfirstline || hpos < HARD_DDF_START
+    if (nodraw () || vpos < minfirstline || hpos < HARD_DDF_START
        /*|| currprefs.emul_accuracy == 0*/)
        return;
 
@@ -1937,7 +1942,7 @@ static void decide_sprites (int hpos)
     int width = sprite_width;
     int window_width = (width << lores_shift) >> sprres;
 
-    if (framecnt != 0 || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point)
+    if (nodraw () || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point)
        return;
 #ifdef DISABLE_SPRITES
     return;
@@ -2040,7 +2045,7 @@ static void finish_decisions (void)
     int changed;
     int hpos = current_hpos ();
 
-    if (framecnt != 0)
+    if (nodraw ())
        return;
 
     decide_diw (hpos);
@@ -2074,7 +2079,7 @@ static void finish_decisions (void)
     changed = thisline_changed;
 
     if (thisline_decision.plfleft != -1) {
-       record_diw_line (diwfirstword, diwlastword);
+       record_diw_line (thisline_decision.plfleft, diwfirstword, diwlastword);
 
        decide_sprites (hpos);
     }
@@ -2110,7 +2115,7 @@ static void finish_decisions (void)
 /* Set the state of all decisions to "undecided" for a new scanline. */
 static void reset_decisions (void)
 {
-    if (framecnt != 0)
+    if (nodraw ())
        return;
     toscr_res_first = 0;
 
@@ -2164,22 +2169,14 @@ int turbo_emulation;
 void compute_vsynctime (void)
 {
     fake_vblank_hz = 0;
-    if (currprefs.gfx_vsync && currprefs.gfx_afullscreen && currprefs.gfx_refreshrate) {
-       vblank_hz = abs (currprefs.gfx_refreshrate);
-       vblank_skip = 1;
-#if 0
-       if (vblank_hz == 75) {
-           fake_vblank_hz = 50;
-           vblank_skip = 2;
-       }
-       if (vblank_hz == 90) {
-           fake_vblank_hz = 60;
-           vblank_skip = 2;
-       }
-#endif
-       if (!fake_vblank_hz && vblank_hz > 85) {
-           vblank_hz /= 2;
-           vblank_skip = -1;
+    if (currprefs.chipset_refreshrate) {
+       vblank_hz = currprefs.chipset_refreshrate;
+       if (currprefs.gfx_vsync && currprefs.gfx_afullscreen) {
+           vblank_skip = 1;
+           if (!fake_vblank_hz && vblank_hz > 85) {
+               vblank_hz /= 2;
+               vblank_skip = -1;
+           }
        }
     }
     if (!fake_vblank_hz)
@@ -2204,6 +2201,16 @@ void init_hz (void)
 {
     int isntsc;
 
+    if ((currprefs.chipset_refreshrate == 50 && !currprefs.ntscmode) ||
+        (currprefs.chipset_refreshrate == 60 && currprefs.ntscmode)) {
+       currprefs.chipset_refreshrate = 0;
+       changed_prefs.chipset_refreshrate = 0;
+    }
+    if (currprefs.gfx_vsync && currprefs.gfx_afullscreen) {
+        currprefs.chipset_refreshrate = abs (currprefs.gfx_refreshrate);
+        changed_prefs.chipset_refreshrate = abs (currprefs.gfx_refreshrate);
+    }
+
     beamcon0 = new_beamcon0;
     isntsc = beamcon0 & 0x20 ? 0 : 1;
     if (hack_vpos > 0) {
@@ -2301,10 +2308,12 @@ static void calcdiw (void)
     plfstrt = ddfstrt;
     plfstop = ddfstop;
     /* probably not the correct place.. */
-    if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && ddfstop > maxhpos)
-       plfstrt = 0;
-    if (plfstrt < HARD_DDF_START)
-       plfstrt = HARD_DDF_START;
+    if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
+       if (ddfstop > maxhpos)
+           plfstrt = 0;
+       if (plfstrt < HARD_DDF_START)
+           plfstrt = HARD_DDF_START;
+    }
 }
 
 /* display mode changed (lores, doubling etc..), recalculate everything */
@@ -2493,7 +2502,7 @@ static int intlev_2 (void)
 {
     uae_u16 imask = intreq & intena;
     unsigned long cycles = get_cycles ();
-    int c = currprefs.cpu_level >= 2 ? 20 : 4;
+    int c = 4;
     int i;
 
     if (!(imask && (intena & 0x4000))) {
@@ -3006,7 +3015,7 @@ STATIC_INLINE void SPRxCTLPOS (int num)
     if (vpos == s->vstop)
         s->dmastate = 0;
 }
-    
+
 STATIC_INLINE void SPRxCTL_1 (uae_u16 v, int num, int hpos)
 {
     struct sprite *s = &spr[num];
@@ -4320,12 +4329,22 @@ static void hsync_handler (void)
 
 #ifdef CPUEMU_6
     if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) {
+       int i;
         decide_blitter (hpos);
        memset (cycle_line, 0, MAXHPOS);
+#if 1
        cycle_line[maxhpos - 1] = CYCLE_REFRESH;
-       cycle_line[0] = CYCLE_REFRESH;
        cycle_line[2] = CYCLE_REFRESH;
        cycle_line[4] = CYCLE_REFRESH;
+       cycle_line[6] = CYCLE_REFRESH;
+#else
+       cycle_line[4] = CYCLE_REFRESH;
+       cycle_line[6] = CYCLE_REFRESH;
+       cycle_line[8] = CYCLE_REFRESH;
+       cycle_line[10] = CYCLE_REFRESH;
+       for (i = 12; i < 0x16; i += 2)
+           cycle_line[i] = CYCLE_NOCPU;
+#endif
     }
 #endif
     if ((currprefs.chipset_mask & CSMASK_AGA) || (!currprefs.chipset_mask & CSMASK_ECS_AGNUS))
@@ -4378,7 +4397,7 @@ static void hsync_handler (void)
     if ((bplcon0 & 4) && currprefs.gfx_linedbl)
        notice_interlace_seen ();
 
-    if (framecnt == 0) {
+    if (!nodraw ()) {
        int lineno = vpos;
        nextline_how = nln_normal;
        if (currprefs.gfx_linedbl) {
diff --git a/disk.c b/disk.c
index 96e638c1270c3b1725f9af8a129117d358c4ec1f..3cd96c8a0438dd33278a8cb308dd3fe26a12df08 100755 (executable)
--- a/disk.c
+++ b/disk.c
@@ -1370,7 +1370,7 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
 
        trackoffs = (id & 0xff00) >> 8;
        if (trackoffs + 1 > drvsec) {
-           write_log ("Disk write: weird sector number %d\n", trackoffs);
+           write_log ("Disk decode: weird sector number %d\n", trackoffs);
            if (filetype == ADF_EXT2)
                return 2;
            continue;
@@ -1394,7 +1394,7 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
        even = getmfmlong (mbuf + 2, shift);
        mbuf += 4;
        if (((odd << 1) | even) != chksum || ((id & 0x00ff0000) >> 16) != cyl * 2 + side) {
-           write_log ("Disk write: checksum error on sector %d header\n", trackoffs);
+           write_log ("Disk decode: checksum error on sector %d header\n", trackoffs);
            if (filetype == ADF_EXT2)
                return 3;
            continue;
@@ -1417,7 +1417,7 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
        }
        mbuf += 256;
        if (chksum) {
-           write_log ("Disk write: sector %d, data checksum error\n", trackoffs);
+           write_log ("Disk decode: sector %d, data checksum error\n", trackoffs);
            if (filetype == ADF_EXT2)
                return 4;
            continue;
@@ -1429,9 +1429,9 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
     if (filetype == ADF_EXT2 && (secwritten == 0 || secwritten < 0))
        return 5;
     if (secwritten == 0)
-       write_log ("Disk write in unsupported format\n");
+       write_log ("Disk decode: unsupported format\n");
     if (secwritten < 0)
-       write_log ("Disk write: sector labels ignored\n");
+       write_log ("Disk decode: sector labels ignored\n");
     *drvsecp = drvsec;
     return 0;
 }
@@ -1745,6 +1745,7 @@ char *DISK_history_get (int idx)
 void disk_insert (int num, const char *name)
 {
     drive *drv = floppy + num;
+
     if (!strcmp (currprefs.df[num], name))
        return;
     strcpy (drv->newname, name);
@@ -2240,8 +2241,8 @@ static void disk_doupdate_read (drive * drv, int floppybits)
                put_word (dskpt, word);
                dskpt += 2;
 #ifdef CPUEMU_6
-               cycle_line[7] |= CYCLE_DISK;
-               cycle_line[9] |= CYCLE_DISK;
+               cycle_line[7] |= CYCLE_MISC;
+               cycle_line[9] |= CYCLE_MISC;
 #endif
            }
 #if 0
index f1044fc35a1553dd670b2ff0ca08f53f3d3370fc..6164d2ce5e7bd5121dd9af9eb1ca2da07b7f273c 100755 (executable)
--- a/drawing.c
+++ b/drawing.c
@@ -220,12 +220,17 @@ static struct decision *dp_for_drawing;
 static struct draw_info *dip_for_drawing;
 
 /* Record DIW of the current line for use by centering code.  */
-void record_diw_line (int first, int last)
+void record_diw_line (int plfstrt, int first, int last)
 {
     if (last > max_diwstop)
        max_diwstop = last;
-    if (first < min_diwstart)
+    if (first < min_diwstart) {
        min_diwstart = first;
+/*
+       if (plfstrt * 2 > min_diwstart)
+           min_diwstart = plfstrt * 2;
+*/
+    }
 }
 
 /*
index 43f4f0dd23ea5c9ec7b6eea025ddc6461d1da349..da73ebf2608a26781eb0cfc009a03c6bdfd6e8ca 100755 (executable)
--- a/filesys.c
+++ b/filesys.c
@@ -97,6 +97,7 @@ typedef struct {
     uaecptr devname_amiga;
     uaecptr startup;
     char *volname; /* volume name, e.g. CDROM, WORK, etc. */
+    int volflags; /* volume flags, readonly, stream uaefsdb support */
     char *rootdir; /* root unix directory */
     int readonly; /* disallow write access? */
     int bootpri; /* boot priority */
@@ -208,7 +209,6 @@ static char *set_filesys_unit_1 (struct uaedev_mount_info *mountinfo, int nr,
                                 int blocksize, int bootpri, char *filesysdir)
 {
     UnitInfo *ui = mountinfo->ui + nr;
-    int v;
     static char errmsg[1024];
 
     if (nr >= mountinfo->num_units)
@@ -224,24 +224,18 @@ static char *set_filesys_unit_1 (struct uaedev_mount_info *mountinfo, int nr,
     ui->filesysdir = 0;
 
     if (volname != 0) {
-        struct stat statbuf;
-       memset (&statbuf, 0, sizeof (statbuf));
+       int flags;
        ui->volname = my_strdup (volname);
-       v = isspecialdrive (rootdir);
-       if (v < 0) {
-           sprintf (errmsg, "invalid drive '%s'", rootdir);
+       flags = my_getvolumeinfo (rootdir);
+       if (flags < 0) {
+           sprintf (errmsg, "directory '%s' not found", rootdir);
            return errmsg;
        }
-       if (v == 0) {
-            if (stat (rootdir, &statbuf) < 0) {
-               sprintf (errmsg, "directory '%s' not found", rootdir);
-               return errmsg;
-           }
-           if (!(statbuf.st_mode & FILEFLAG_WRITE)) {
-               write_log ("'%s' set to read-only\n", rootdir);
-               readonly = 1;
-           }
+       if (flags & MYVOLUMEINFO_READONLY) {
+           write_log ("'%s' set to read-only\n", rootdir);
+           readonly = 1;
        }
+       ui->volflags = flags;
     } else {
        ui->hf.secspertrack = secspertrack;
        ui->hf.surfaces = surfaces;
@@ -588,6 +582,8 @@ typedef struct _unit {
     unsigned long nr_cache_lookups;
 
     struct notify *notifyhash[NOTIFY_HASH_SIZE];
+    
+    int volflags;
 
 } Unit;
 
@@ -984,7 +980,7 @@ static char *create_nname (Unit *unit, a_inode *base, char *rel)
 #if 0
        oh_dear:
 #endif
-       if (currprefs.filesys_no_uaefsdb) {
+       if (currprefs.filesys_no_uaefsdb && !(base->volflags & MYVOLUMEINFO_STREAMS)) {
            write_log ("illegal filename '%s' and uaefsdb disabled\n", rel);
            return 0;
        }
@@ -1045,6 +1041,7 @@ static void init_child_aino (Unit *unit, a_inode *base, a_inode *aino)
     aino->sibling = base->child;
     base->child = aino;
     aino->next = aino->prev = 0;
+    aino->volflags = unit->volflags;
 
     aino_test_init (aino);
     aino_test (aino);
@@ -1073,7 +1070,7 @@ static a_inode *new_child_aino (Unit *unit, a_inode *base, char *rel)
        aino->comment = 0;
        aino->has_dbentry = 0;
 
-       if (!fsdb_fill_file_attrs (aino)) {
+       if (!fsdb_fill_file_attrs (base, aino)) {
            xfree (aino);
            return 0;
        }
@@ -1173,7 +1170,7 @@ static a_inode *lookup_child_aino_for_exnext (Unit *unit, a_inode *base, char *r
        c->aname = get_aname (unit, base, rel);
        c->comment = 0;
        c->has_dbentry = 0;
-       if (!fsdb_fill_file_attrs (c)) {
+       if (!fsdb_fill_file_attrs (base, c)) {
            xfree (c);
            *err = ERROR_NO_FREE_STORE;
            return 0;
@@ -1299,6 +1296,7 @@ static Unit *startup_create_unit (UnitInfo *uinfo)
     unit->rootnode.elock = 0;
     unit->rootnode.comment = 0;
     unit->rootnode.has_dbentry = 0;
+    unit->rootnode.volflags = uinfo->volflags;
     aino_test_init (&unit->rootnode);
     unit->aino_cache_size = 0;
     for (i = 0; i < MAX_AINO_HASH; i++)
@@ -1336,7 +1334,7 @@ static uae_u32 startup_handler (void)
     }
 
     if (i == current_mountinfo->num_units
-       || access (current_mountinfo->ui[i].rootdir, R_OK) != 0)
+       || !my_existsdir (current_mountinfo->ui[i].rootdir))
     {
        write_log ("Failed attempt to mount device\n", devname);
        put_long (pkt + dp_Res1, DOS_FALSE);
@@ -1345,10 +1343,11 @@ static uae_u32 startup_handler (void)
     }
     uinfo = current_mountinfo->ui + i;
     unit = startup_create_unit (uinfo);
+    unit->volflags = uinfo->volflags;
 
 /*    write_comm_pipe_int (unit->ui.unit_pipe, -1, 1);*/
 
-    TRACE(("**** STARTUP volume %s\n", unit->ui.volname));
+    write_log ("FS: %s (flags=%08.8X) starting..\n", unit->ui.volname, unit->volflags);
 
     /* fill in our process in the device node */
     put_long ((get_long (pkt + dp_Arg3) << 2) + 8, unit->port);
@@ -1445,7 +1444,7 @@ static void free_key (Unit *unit, Key *k)
        prev = k1;
     }
 
-    if (k->fd >= 0)
+    if (k->fd != NULL)
        my_close (k->fd);
 
     xfree(k);
@@ -2452,6 +2451,7 @@ action_read (Unit *unit, dpacket packet)
        }
        xfree (buf);
     }
+    TRACE(("=%d\n", actual));
 }
 
 static void
@@ -2460,6 +2460,7 @@ action_write (Unit *unit, dpacket packet)
     Key *k = lookup_key (unit, GET_PCK_ARG1 (packet));
     uaecptr addr = GET_PCK_ARG2 (packet);
     long size = GET_PCK_ARG3 (packet);
+    long actual;
     char *buf;
     int i;
 
@@ -2489,11 +2490,13 @@ action_write (Unit *unit, dpacket packet)
     for (i = 0; i < size; i++)
        buf[i] = get_byte(addr + i);
 
-    PUT_PCK_RES1 (packet, my_write (k->fd, buf, size));
-    if (GET_PCK_RES1 (packet) != size)
+    actual = my_write (k->fd, buf, size);
+    TRACE(("=%d\n", actual));
+    PUT_PCK_RES1 (packet, actual);
+    if (actual != size)
        PUT_PCK_RES2 (packet, dos_errno ());
-    if (GET_PCK_RES1 (packet) >= 0)
-       k->file_pos += GET_PCK_RES1 (packet);
+    if (actual >= 0)
+       k->file_pos += actual;
 
     k->notifyactive = 1;
     xfree (buf);
@@ -2571,7 +2574,8 @@ action_set_protect (Unit *unit, dpacket packet)
        return;
     }
 
-    err = fsdb_set_file_attrs (a, mask);
+    a->amigaos_mode = mask;
+    err = fsdb_set_file_attrs (a);
     if (err != 0) {
        PUT_PCK_RES1 (packet, DOS_FALSE);
        PUT_PCK_RES2 (packet, err);
@@ -2620,7 +2624,7 @@ static void action_set_comment (Unit * unit, dpacket packet)
     if (a->comment)
        xfree (a->comment);
     a->comment = commented;
-    a->dirty = 1;
+    fsdb_set_file_attrs (a);
     notify_check (unit, a);
     gui_hd_led (1);
 }
@@ -4024,9 +4028,12 @@ static void get_new_device (int type, uaecptr parmpacket, char **devname, uaecpt
     }
     *devname_amiga = ds (device_dupfix (get_long (parmpacket + PP_EXPLIB), buffer));
     if (type == FILESYS_VIRTUAL)
-       write_log ("FS: mounted virtual unit %s\n", buffer);
+       write_log ("FS: mounted virtual unit %s (%s)\n", buffer, current_mountinfo->ui[unit_no].rootdir);
     else
-       write_log ("FS: mounted HDF unit %s\n", buffer);
+       write_log ("FS: mounted HDF unit %s (%04.4x-%08.8x, %s)\n", buffer,
+           (uae_u32)(current_mountinfo->ui[unit_no].hf.size >> 32),
+           (uae_u32)(current_mountinfo->ui[unit_no].hf.size),
+           current_mountinfo->ui[unit_no].rootdir);
 }
 
 /* Fill in per-unit fields of a parampacket */
diff --git a/fsdb.c b/fsdb.c
index 57c04849a9d363e9e5434340165d9ad35df30aed..da01bed056a82588876ba7e5d226e7790cac5d17 100755 (executable)
--- a/fsdb.c
+++ b/fsdb.c
@@ -28,7 +28,7 @@
  * Offset 1, 4 bytes, mode
  * Offset 5, 257 bytes, aname
  * Offset 263, 257 bytes, nname
- * Offset 518, 81 bytes, comment
+ * Offset 519, 81 bytes, comment
  */
 
 #define TRACING_ENABLED 0
@@ -46,6 +46,7 @@ char *nname_begin (char *nname)
     return nname;
 }
 
+#ifndef _WIN32
 /* Find the name REL in directory DIRNAME.  If we find a file that
  * has exactly the same name, return REL.  If we find a file that
  * has the same name when compared case-insensitively, return a
@@ -55,9 +56,10 @@ char *fsdb_search_dir (const char *dirname, char *rel)
 {
     char *p = 0;
     int de;
-    void *dir = my_opendir (dirname);
+    void *dir;
     char fn[MAX_DPATH];
 
+    dir = my_opendir (dirname);
     /* This really shouldn't happen...  */
     if (! dir)
        return 0;
@@ -71,6 +73,7 @@ char *fsdb_search_dir (const char *dirname, char *rel)
     my_closedir (dir);
     return p;
 }
+#endif
 
 static FILE *get_fsdb (a_inode *dir, const char *mode)
 {
@@ -113,10 +116,12 @@ static void fsdb_fixup (FILE *f, char *buf, int size, a_inode *base)
 void fsdb_clean_dir (a_inode *dir)
 {
     char buf[1 + 4 + 257 + 257 + 81];
-    char *n = build_nname (dir->nname, FSDB_FILE);
-    FILE *f = fopen (n, "r+b");
+    char *n;
+    FILE *f;
     off_t pos1 = 0, pos2;
 
+    n = build_nname (dir->nname, FSDB_FILE);
+    f = fopen (n, "r+b");
     if (f == 0) {
        free (n);
        return;
@@ -152,23 +157,24 @@ static a_inode *aino_from_buf (a_inode *base, char *buf, long off)
     aino->nname = build_nname (base->nname, buf);
     buf += 257;
     aino->comment = *buf != '\0' ? my_strdup (buf) : 0;
-    fsdb_fill_file_attrs (aino);
+    fsdb_fill_file_attrs (base, aino);
     aino->amigaos_mode = mode;
     aino->has_dbentry = 1;
     aino->dirty = 0;
     aino->db_offset = off;
-    TRACE (("aino=%d a='%s' n='%s' c='%s' mode=%d dir=%d\n",
-       off, aino->aname, aino->nname, aino->comment, aino->amigaos_mode, aino->dir));
     return aino;
 }
 
 a_inode *fsdb_lookup_aino_aname (a_inode *base, const char *aname)
 {
-    FILE *f = get_fsdb (base, "r+b");
+    FILE *f;
 
-    if (f == 0)
+    f = get_fsdb (base, "r+b");
+    if (f == 0) {
+       if (currprefs.filesys_custom_uaefsdb && (base->volflags & MYVOLUMEINFO_STREAMS))
+           return custom_fsdb_lookup_aino_aname (base, aname);
        return 0;
-
+    }
     for (;;) {
        char buf[1 + 4 + 257 + 257 + 81];
        if (fread (buf, 1, sizeof buf, f) < sizeof buf)
@@ -185,11 +191,14 @@ a_inode *fsdb_lookup_aino_aname (a_inode *base, const char *aname)
 
 a_inode *fsdb_lookup_aino_nname (a_inode *base, const char *nname)
 {
-    FILE *f = get_fsdb (base, "r+b");
+    FILE *f;
 
-    if (f == 0)
+    f = get_fsdb (base, "r+b");
+    if (f == 0) {
+       if (currprefs.filesys_custom_uaefsdb && (base->volflags & MYVOLUMEINFO_STREAMS))
+           return custom_fsdb_lookup_aino_nname (base, nname);
        return 0;
-
+    }
     for (;;) {
        char buf[1 + 4 + 257 + 257 + 81];
        if (fread (buf, 1, sizeof buf, f) < sizeof buf)
@@ -206,11 +215,15 @@ a_inode *fsdb_lookup_aino_nname (a_inode *base, const char *nname)
 
 int fsdb_used_as_nname (a_inode *base, const char *nname)
 {
-    FILE *f = get_fsdb (base, "r+b");
+    FILE *f;
     char buf[1 + 4 + 257 + 257 + 81];
     
-    if (f == 0)
-       return 0;
+    f = get_fsdb (base, "r+b");
+    if (f == 0) {
+       if (currprefs.filesys_custom_uaefsdb && (base->volflags & MYVOLUMEINFO_STREAMS))
+           return custom_fsdb_used_as_nname (base, nname);
+       return 0;
+    }
     for (;;) {
        if (fread (buf, 1, sizeof buf, f) < sizeof buf)
            break;
@@ -248,7 +261,7 @@ static void write_aino (FILE *f, a_inode *aino)
     buf[5 + 256] = '\0';
     strncpy (buf + 5 + 257, nname_begin (aino->nname), 256);
     buf[5 + 257 + 256] = '\0';
-    strncpy (buf + 5 + 2*257, aino->comment ? aino->comment : "", 80);
+    strncpy (buf + 5 + 2 * 257, aino->comment ? aino->comment : "", 80);
     buf[5 + 2 * 257 + 80] = '\0';
     aino->db_offset = ftell (f);
     fwrite (buf, 1, sizeof buf, f);
@@ -300,8 +313,12 @@ void fsdb_dir_writeback (a_inode *dir)
 
     f = get_fsdb (dir, "r+b");
     if (f == 0) {
-       if (currprefs.filesys_no_uaefsdb) {
-           TRACE (("disabled\n"));
+       if ((currprefs.filesys_custom_uaefsdb  && (dir->volflags & MYVOLUMEINFO_STREAMS)) ||currprefs.filesys_no_uaefsdb) {
+           for (aino = dir->child; aino; aino = aino->sibling) {
+               aino->dirty = 0;
+               aino->has_dbentry = 0;
+               aino->needs_dbentry = 0;
+           }
            return;
        }
        f = get_fsdb (dir, "w+b");
index 4b23f0e800da8b80f9cea1976de265bb8dbf5fd9..ba5728aa20f87cb12472fbfcbcb4032ec2e5c84c 100755 (executable)
@@ -463,6 +463,14 @@ static void getchs (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head,
         *cylsec = hfd->sectors * hfd->heads;
         return;
     }
+    /* what about HDF settings? */
+    if (hfd->surfaces && hfd->secspertrack) {
+       *head = hfd->surfaces;
+       *tracksec = hfd->secspertrack;
+       *cylsec = (*head) * (*tracksec);
+       *cyl = (unsigned int)(hfd->size / hfd->blocksize) / ((*tracksec) * (*head));
+       return;
+    }
     /* no, lets guess something.. */
     if (total <= 504 * 1024)
        heads = 16;
index 37132773c8e378b7c71fcf48ff7d3c806293bb28..20816f1cb427e488cfe60e1120006df48e3786c8 100755 (executable)
@@ -115,13 +115,13 @@ extern unsigned long syncbase;
 #define DMA_BLITPRI   0x0400
 
 #define CYCLE_REFRESH  0x01
-#define CYCLE_DISK     0x02
-#define CYCLE_AUDIO    0x04
-#define CYCLE_SPRITE   0x08
-#define CYCLE_BITPLANE 0x10
-#define CYCLE_COPPER   0x20
-#define CYCLE_BLITTER  0x40
-#define CYCLE_CPU      0x80
+#define CYCLE_MISC     0x02
+#define CYCLE_SPRITE   0x04
+#define CYCLE_BITPLANE 0x08
+#define CYCLE_COPPER   0x10
+#define CYCLE_BLITTER  0x20
+#define CYCLE_CPU      0x40
+#define CYCLE_NOCPU    0x80
 
 extern unsigned long frametime, timeframes;
 extern int plfstrt, plfstop, plffirstline, plflastline;
index 77f9fe9de66fcd4bb8626d0737c06f0cd8cb5352..9b7d3f6b192e3571c6d147cf43f92376beba3c2c 100755 (executable)
@@ -232,7 +232,7 @@ extern uae_u8 *real_bplpt[8];
 extern int coord_native_to_amiga_y (int);
 extern int coord_native_to_amiga_x (int);
 
-extern void record_diw_line (int first, int last);
+extern void record_diw_line (int plfstrt, int first, int last);
 extern void hardware_line_completed (int lineno);
 
 /* Determine how to draw a scan line.  */
index 72310f41dd50351840a235ede5a4bad482375ddc..f147d966a41a8fb73a824c43455aa0daad608a88 100755 (executable)
@@ -84,6 +84,8 @@ typedef struct a_inode_struct {
     /* If nonzero, this represents a deleted file; the corresponding
      * entry in the database must be cleared.  */
     unsigned int deleted:1;
+    /* target volume flag */
+    unsigned int volflags;
 #ifdef AINO_DEBUG
     uae_u32 checksum2;
 #endif
@@ -110,8 +112,8 @@ STATIC_INLINE int same_aname (const char *an1, const char *an2)
 
 /* Filesystem-dependent functions.  */
 extern int fsdb_name_invalid (const char *n);
-extern int fsdb_fill_file_attrs (a_inode *);
-extern int fsdb_set_file_attrs (a_inode *, int);
+extern int fsdb_fill_file_attrs (a_inode *, a_inode *);
+extern int fsdb_set_file_attrs (a_inode *);
 extern int fsdb_mode_representable_p (const a_inode *);
 extern char *fsdb_create_unique_nname (a_inode *base, const char *);
 
@@ -131,4 +133,15 @@ extern unsigned int my_read (void*, void*, unsigned int);
 extern unsigned int my_write (void*, void*, unsigned int);
 extern int my_truncate (const char *name, long int len);
 extern int dos_errno (void);
+extern int my_existsfile (const char *name);
+extern int my_existsdir (const char *name);
 
+extern char *custom_fsdb_search_dir (const char *dirname, char *rel);
+extern a_inode *custom_fsdb_lookup_aino_aname (a_inode *base, const char *aname);
+extern a_inode *custom_fsdb_lookup_aino_nname (a_inode *base, const char *nname);
+extern int custom_fsdb_used_as_nname (a_inode *base, const char *nname);
+
+#define MYVOLUMEINFO_READONLY 1
+#define MYVOLUMEINFO_STREAMS 2
+
+extern int my_getvolumeinfo (char *root);
index 074c787bef824112aa6b5f35bc6c131aedbb55ba..5f06208f304f0d07a96d15600991fe956cca0968 100755 (executable)
@@ -145,5 +145,7 @@ enum aks { AKS_ENTERGUI = 0x200, AKS_SCREENSHOT, AKS_FREEZEBUTTON,
     AKS_STATESAVEQUICK7, AKS_STATERESTOREQUICK7,
     AKS_STATESAVEQUICK8, AKS_STATERESTOREQUICK8,
     AKS_STATESAVEQUICK9, AKS_STATERESTOREQUICK9,
-    AKS_STATESAVEDIALOG, AKS_STATERESTOREDIALOG
+    AKS_STATESAVEDIALOG, AKS_STATERESTOREDIALOG,
+    AKS_DECREASEREFRESHRATE,
+    AKS_INCREASEREFRESHRATE
 }; 
index 498f851422b8e11aece033cdc96f9cee19372cd9..b6a865cb9f165f28b031179c583b12fa14764506 100755 (executable)
@@ -9,7 +9,7 @@
 
 #define UAEMAJOR 0
 #define UAEMINOR 9
-#define UAESUBREV 91
+#define UAESUBREV 92
 
 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang;
 
@@ -62,6 +62,9 @@ struct uae_prefs {
     int serial_hwctsrts;
     int serial_direct;
     int parallel_demand;
+    int parallel_postscript_emulation;
+    int parallel_postscript_detection;
+    char ghostscript_parameters[256];
     int use_gfxlib;
     int socket_emu;
 
@@ -133,6 +136,7 @@ struct uae_prefs {
     int immediate_blits;
     unsigned int chipset_mask;
     int ntscmode;
+    int chipset_refreshrate;
     int collision_level;
     int leds_on_screen;
     int keyboard_leds[3];
@@ -176,6 +180,7 @@ struct uae_prefs {
 
     int kickshifter;
     int filesys_no_uaefsdb;
+    int filesys_custom_uaefsdb;
 
     struct uaedev_mount_info *mountinfo;
 
@@ -264,8 +269,10 @@ extern uae_u32 cfgfile_uaelib (int mode, uae_u32 name, uae_u32 dst, uae_u32 maxl
 extern uae_u32 cfgfile_uaelib_modify (uae_u32 mode, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize);
 extern void cfgfile_addcfgparam (char *);
 extern int build_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck);
+extern int cmdlineparser (char *s, char *outp[], int max);
 
 extern void fixup_prefs_dimensions (struct uae_prefs *prefs);
+extern void fixup_prefs (struct uae_prefs *prefs);
 
 extern void check_prefs_changed_custom (void);
 extern void check_prefs_changed_cpu (void);
index 97167296f737ea9bb851bb23586c52de6e5b56d8..0155f93e9478e7b252fb575e88fea7e57996fe62 100755 (executable)
@@ -1247,7 +1247,19 @@ void inputdevice_handle_inputcode (void)
        case AKS_STATERESTOREDIALOG:
        gui_display (4);
        break;
-
+       case AKS_DECREASEREFRESHRATE:
+       case AKS_INCREASEREFRESHRATE:
+       {
+           int dir = code == AKS_INCREASEREFRESHRATE ? 5 : -5;
+           if (currprefs.chipset_refreshrate == 0)
+               currprefs.chipset_refreshrate = currprefs.ntscmode ? 60 : 50;
+           changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate + dir;
+           if (changed_prefs.chipset_refreshrate < 10)
+               changed_prefs.chipset_refreshrate = 10;
+           if (changed_prefs.chipset_refreshrate > 900)
+               changed_prefs.chipset_refreshrate = 900;
+       }
+       break;
     }
 }
 
index 1ed64855b37af6a5921c66b9dbbdce9ac1d7da1e..f7fa0adabbd4ebd313401b8a349f4c80f66a0ffb 100755 (executable)
@@ -256,9 +256,9 @@ DEFEVENT(SPC_FLOPPY1,"Change disk in DF1:",AM_K,0,0,AKS_FLOPPY1)
 DEFEVENT(SPC_FLOPPY2,"Change disk in DF2:",AM_K,0,0,AKS_FLOPPY2)
 DEFEVENT(SPC_FLOPPY3,"Change disk in DF3:",AM_K,0,0,AKS_FLOPPY3)
 DEFEVENT(SPC_EFLOPPY0,"Eject disk in DF0:",AM_K,0,0,AKS_EFLOPPY0)
-DEFEVENT(SPC_EFLOPPY1,"Eject disk in DF0:",AM_K,0,0,AKS_EFLOPPY1)
-DEFEVENT(SPC_EFLOPPY2,"Eject disk in DF0:",AM_K,0,0,AKS_EFLOPPY2)
-DEFEVENT(SPC_EFLOPPY3,"Eject disk in DF0:",AM_K,0,0,AKS_EFLOPPY3)
+DEFEVENT(SPC_EFLOPPY1,"Eject disk in DF1:",AM_K,0,0,AKS_EFLOPPY1)
+DEFEVENT(SPC_EFLOPPY2,"Eject disk in DF2:",AM_K,0,0,AKS_EFLOPPY2)
+DEFEVENT(SPC_EFLOPPY3,"Eject disk in DF3:",AM_K,0,0,AKS_EFLOPPY3)
 DEFEVENT(SPC_PAUSE,"Pause emulation",AM_K,0,0,AKS_PAUSE)
 DEFEVENT(SPC_WARP,"Warp mode",AM_K,0,0,AKS_WARP)
 DEFEVENT(SPC_INHIBITSCREEN,"Toggle screen updates",AM_K,0,0,AKS_INHIBITSCREEN)
@@ -273,4 +273,6 @@ DEFEVENT(SPC_STATERESTORE,"Quick restore state",AM_K,0,0,AKS_STATERESTOREQUICK)
 DEFEVENT(SPC_STATESAVEDIALOG,"Save state",AM_K,0,0,AKS_STATESAVEDIALOG)
 DEFEVENT(SPC_STATERESTOREDIALOG,"Restore state",AM_K,0,0,AKS_STATERESTOREDIALOG)
 DEFEVENT(SPC_TOGGLEFULLSCREEN,"Toggle windowed/fullscreen",AM_K,0,0,AKS_TOGGLEFULLSCREEN)
+DEFEVENT(SPC_DECREASE_REFRESHRATE,"Decrease emulation speed",AM_K,0,0,AKS_DECREASEREFRESHRATE)
+DEFEVENT(SPC_INCREASE_REFRESHRARE,"Increase emulation speed",AM_K,0,0,AKS_INCREASEREFRESHRATE)
 
diff --git a/main.c b/main.c
index cfa711c1fa69b83a9c65d40c20536111d9c2cdb3..36d24c9f0eb475c4f1b975a9ed38371db6476c2c 100755 (executable)
--- a/main.c
+++ b/main.c
@@ -115,194 +115,199 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs)
     prefs->gfx_width_win &= ~7;
 }
 
-static void fix_options (void)
+void fixup_prefs (struct uae_prefs *p)
 {
     int err = 0;
 
-    if ((currprefs.chipmem_size & (currprefs.chipmem_size - 1)) != 0
-       || currprefs.chipmem_size < 0x40000
-       || currprefs.chipmem_size > 0x800000)
+    if ((p->chipmem_size & (p->chipmem_size - 1)) != 0
+       || p->chipmem_size < 0x40000
+       || p->chipmem_size > 0x800000)
     {
-       currprefs.chipmem_size = 0x200000;
+       p->chipmem_size = 0x200000;
        write_log ("Unsupported chipmem size!\n");
        err = 1;
     }
-    if (currprefs.chipmem_size > 0x80000)
-       currprefs.chipset_mask |= CSMASK_ECS_AGNUS;
+    if (p->chipmem_size > 0x80000)
+       p->chipset_mask |= CSMASK_ECS_AGNUS;
 
-    if ((currprefs.fastmem_size & (currprefs.fastmem_size - 1)) != 0
-       || (currprefs.fastmem_size != 0 && (currprefs.fastmem_size < 0x100000 || currprefs.fastmem_size > 0x800000)))
+    if ((p->fastmem_size & (p->fastmem_size - 1)) != 0
+       || (p->fastmem_size != 0 && (p->fastmem_size < 0x100000 || p->fastmem_size > 0x800000)))
     {
-       currprefs.fastmem_size = 0;
+       p->fastmem_size = 0;
        write_log ("Unsupported fastmem size!\n");
        err = 1;
     }
-    if ((currprefs.gfxmem_size & (currprefs.gfxmem_size - 1)) != 0
-       || (currprefs.gfxmem_size != 0 && (currprefs.gfxmem_size < 0x100000 || currprefs.gfxmem_size > 0x2000000)))
+    if ((p->gfxmem_size & (p->gfxmem_size - 1)) != 0
+       || (p->gfxmem_size != 0 && (p->gfxmem_size < 0x100000 || p->gfxmem_size > 0x2000000)))
     {
-       write_log ("Unsupported graphics card memory size %lx!\n", currprefs.gfxmem_size);
-       currprefs.gfxmem_size = 0;
+       write_log ("Unsupported graphics card memory size %lx!\n", p->gfxmem_size);
+       p->gfxmem_size = 0;
        err = 1;
     }
-    if ((currprefs.z3fastmem_size & (currprefs.z3fastmem_size - 1)) != 0
-       || (currprefs.z3fastmem_size != 0 && (currprefs.z3fastmem_size < 0x100000 || currprefs.z3fastmem_size > 0x20000000)))
+    if ((p->z3fastmem_size & (p->z3fastmem_size - 1)) != 0
+       || (p->z3fastmem_size != 0 && (p->z3fastmem_size < 0x100000 || p->z3fastmem_size > 0x20000000)))
     {
-       currprefs.z3fastmem_size = 0;
+       p->z3fastmem_size = 0;
        write_log ("Unsupported Zorro III fastmem size!\n");
        err = 1;
     }
-    if (currprefs.address_space_24 && (currprefs.gfxmem_size != 0 || currprefs.z3fastmem_size != 0)) {
-       currprefs.z3fastmem_size = currprefs.gfxmem_size = 0;
+    if (p->address_space_24 && (p->gfxmem_size != 0 || p->z3fastmem_size != 0)) {
+       p->z3fastmem_size = p->gfxmem_size = 0;
        write_log ("Can't use a graphics card or Zorro III fastmem when using a 24 bit\n"
                 "address space - sorry.\n");
     }
-    if (currprefs.bogomem_size != 0 && currprefs.bogomem_size != 0x80000 && currprefs.bogomem_size != 0x100000 && currprefs.bogomem_size != 0x180000 && currprefs.bogomem_size != 0x1c0000)
+    if (p->bogomem_size != 0 && p->bogomem_size != 0x80000 && p->bogomem_size != 0x100000 && p->bogomem_size != 0x180000 && p->bogomem_size != 0x1c0000)
     {
-       currprefs.bogomem_size = 0;
+       p->bogomem_size = 0;
        write_log ("Unsupported bogomem size!\n");
        err = 1;
     }
 
-    if (currprefs.chipmem_size > 0x200000 && currprefs.fastmem_size != 0) {
+    if (p->chipmem_size > 0x200000 && p->fastmem_size != 0) {
        write_log ("You can't use fastmem and more than 2MB chip at the same time!\n");
-       currprefs.fastmem_size = 0;
+       p->fastmem_size = 0;
        err = 1;
     }
 #if 0
-    if (currprefs.m68k_speed < -1 || currprefs.m68k_speed > 20) {
+    if (p->m68k_speed < -1 || p->m68k_speed > 20) {
        write_log ("Bad value for -w parameter: must be -1, 0, or within 1..20.\n");
-       currprefs.m68k_speed = 4;
+       p->m68k_speed = 4;
        err = 1;
     }
 #endif
   
-    if (currprefs.produce_sound < 0 || currprefs.produce_sound > 3) {
+    if (p->produce_sound < 0 || p->produce_sound > 3) {
        write_log ("Bad value for -S parameter: enable value must be within 0..3\n");
-       currprefs.produce_sound = 0;
+       p->produce_sound = 0;
        err = 1;
     }
-    if (currprefs.comptrustbyte < 0 || currprefs.comptrustbyte > 3) {
+    if (p->comptrustbyte < 0 || p->comptrustbyte > 3) {
        write_log ("Bad value for comptrustbyte parameter: value must be within 0..2\n");
-       currprefs.comptrustbyte = 1;
+       p->comptrustbyte = 1;
        err = 1;
     }
-    if (currprefs.comptrustword < 0 || currprefs.comptrustword > 3) {
+    if (p->comptrustword < 0 || p->comptrustword > 3) {
        write_log ("Bad value for comptrustword parameter: value must be within 0..2\n");
-       currprefs.comptrustword = 1;
+       p->comptrustword = 1;
        err = 1;
     }
-    if (currprefs.comptrustlong < 0 || currprefs.comptrustlong > 3) {
+    if (p->comptrustlong < 0 || p->comptrustlong > 3) {
        write_log ("Bad value for comptrustlong parameter: value must be within 0..2\n");
-       currprefs.comptrustlong = 1;
+       p->comptrustlong = 1;
        err = 1;
     }
-    if (currprefs.comptrustnaddr < 0 || currprefs.comptrustnaddr > 3) {
+    if (p->comptrustnaddr < 0 || p->comptrustnaddr > 3) {
        write_log ("Bad value for comptrustnaddr parameter: value must be within 0..2\n");
-       currprefs.comptrustnaddr = 1;
+       p->comptrustnaddr = 1;
        err = 1;
     }
-    if (currprefs.compnf < 0 || currprefs.compnf > 1) {
+    if (p->compnf < 0 || p->compnf > 1) {
        write_log ("Bad value for compnf parameter: value must be within 0..1\n");
-       currprefs.compnf = 1;
+       p->compnf = 1;
        err = 1;
     }
-    if (currprefs.comp_hardflush < 0 || currprefs.comp_hardflush > 1) {
+    if (p->comp_hardflush < 0 || p->comp_hardflush > 1) {
        write_log ("Bad value for comp_hardflush parameter: value must be within 0..1\n");
-       currprefs.comp_hardflush = 1;
+       p->comp_hardflush = 1;
        err = 1;
     }
-    if (currprefs.comp_constjump < 0 || currprefs.comp_constjump > 1) {
+    if (p->comp_constjump < 0 || p->comp_constjump > 1) {
        write_log ("Bad value for comp_constjump parameter: value must be within 0..1\n");
-       currprefs.comp_constjump = 1;
+       p->comp_constjump = 1;
        err = 1;
     }
-    if (currprefs.comp_oldsegv < 0 || currprefs.comp_oldsegv > 1) {
+    if (p->comp_oldsegv < 0 || p->comp_oldsegv > 1) {
        write_log ("Bad value for comp_oldsegv parameter: value must be within 0..1\n");
-       currprefs.comp_oldsegv = 1;
+       p->comp_oldsegv = 1;
        err = 1;
     }
-    if (currprefs.cachesize < 0 || currprefs.cachesize > 16384) {
+    if (p->cachesize < 0 || p->cachesize > 16384) {
        write_log ("Bad value for cachesize parameter: value must be within 0..16384\n");
-       currprefs.cachesize = 0;
+       p->cachesize = 0;
        err = 1;
     }
 
-    if (currprefs.cpu_level < 2 && currprefs.z3fastmem_size > 0) {
+    if (p->cpu_level < 2 && p->z3fastmem_size > 0) {
        write_log ("Z3 fast memory can't be used with a 68000/68010 emulation. It\n"
                 "requires a 68020 emulation. Turning off Z3 fast memory.\n");
-       currprefs.z3fastmem_size = 0;
+       p->z3fastmem_size = 0;
        err = 1;
     }
-    if (currprefs.gfxmem_size > 0 && (currprefs.cpu_level < 2 || currprefs.address_space_24)) {
+    if (p->gfxmem_size > 0 && (p->cpu_level < 2 || p->address_space_24)) {
        write_log ("Picasso96 can't be used with a 68000/68010 or 68EC020 emulation. It\n"
                 "requires a 68020 emulation. Turning off Picasso96.\n");
-       currprefs.gfxmem_size = 0;
+       p->gfxmem_size = 0;
        err = 1;
     }
 #ifndef BSDSOCKET
-    if (currprefs.socket_emu) {
+    if (p->socket_emu) {
        write_log ("Compile-time option of BSDSOCKET_SUPPORTED was not enabled.  You can't use bsd-socket emulation.\n");
-       currprefs.socket_emu = 0;
+       p->socket_emu = 0;
        err = 1;
     }
 #endif
 
-    if (currprefs.nr_floppies < 0 || currprefs.nr_floppies > 4) {
+    if (p->nr_floppies < 0 || p->nr_floppies > 4) {
        write_log ("Invalid number of floppies.  Using 4.\n");
-       currprefs.nr_floppies = 4;
-       currprefs.dfxtype[0] = 0;
-       currprefs.dfxtype[1] = 0;
-       currprefs.dfxtype[2] = 0;
-       currprefs.dfxtype[3] = 0;
+       p->nr_floppies = 4;
+       p->dfxtype[0] = 0;
+       p->dfxtype[1] = 0;
+       p->dfxtype[2] = 0;
+       p->dfxtype[3] = 0;
        err = 1;
     }
 
-    if (currprefs.floppy_speed > 0 && currprefs.floppy_speed < 10) {
-       currprefs.floppy_speed = 100;
+    if (p->floppy_speed > 0 && p->floppy_speed < 10) {
+       p->floppy_speed = 100;
     }
-    if (currprefs.input_mouse_speed < 1 || currprefs.input_mouse_speed > 1000) {
-       currprefs.input_mouse_speed = 100;
+    if (p->input_mouse_speed < 1 || p->input_mouse_speed > 1000) {
+       p->input_mouse_speed = 100;
     }
-    if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact)
-       currprefs.fast_copper = 0;
+    if (p->cpu_cycle_exact || p->blitter_cycle_exact)
+       p->fast_copper = 0;
 
-    if (currprefs.collision_level < 0 || currprefs.collision_level > 3) {
+    if (p->collision_level < 0 || p->collision_level > 3) {
        write_log ("Invalid collision support level.  Using 1.\n");
-       currprefs.collision_level = 1;
+       p->collision_level = 1;
        err = 1;
     }
-    fixup_prefs_dimensions (&currprefs);
+
+    if (p->parallel_postscript_emulation)
+       p->parallel_postscript_detection = 1;
+
+    fixup_prefs_dimensions (p);
 
 #ifdef CPU_68000_ONLY
-    currprefs.cpu_level = 0;
+    p->cpu_level = 0;
 #endif
 #ifndef CPUEMU_0
-    currprefs.cpu_compatible = 1;
-    currprefs.address_space_24 = 1;
+    p->cpu_compatible = 1;
+    p->address_space_24 = 1;
 #endif
 #if !defined(CPUEMU_5) && !defined (CPUEMU_6)
-    currprefs.cpu_compatible = 0;
-    currprefs.address_space_24 = 0;
+    p->cpu_compatible = 0;
+    p->address_space_24 = 0;
 #endif
 #if !defined (CPUEMU_6)
-    currprefs.cpu_cycle_exact = currprefs.blitter_cycle_exact = 0;
+    p->cpu_cycle_exact = p->blitter_cycle_exact = 0;
 #endif
 #ifndef AGA
-    currprefs.chipset_mask &= ~CSMASK_AGA;
+    p->chipset_mask &= ~CSMASK_AGA;
 #endif
 #ifndef AUTOCONFIG
-    currprefs.z3fastmem_size = 0;
-    currprefs.fastmem_size = 0;
-    currprefs.gfxmem_size = 0;
+    p->z3fastmem_size = 0;
+    p->fastmem_size = 0;
+    p->gfxmem_size = 0;
 #endif
 #if !defined (BSDSOCKET)
-    currprefs.socket_emu = 0;
+    p->socket_emu = 0;
 #endif
 #if !defined (SCSIEMU)
-    currprefs.scsi = 0;
-    currprefs.win32_aspi = 0;
+    p->scsi = 0;
+    p->win32_aspi = 0;
 #endif
 
+
     if (err)
        write_log ("Please use \"uae -h\" to get usage information.\n");
 }
@@ -452,7 +457,7 @@ static void parse_cmdline_and_init_file (int argc, char **argv)
        target_cfgfile_load (&currprefs, optionsfile, 0);
 #endif
     }
-    fix_options ();
+    fixup_prefs (&currprefs);
 
     parse_cmdline (argc, argv);
 }
@@ -554,7 +559,7 @@ static void real_main2 (int argc, char **argv)
         currprefs.mountinfo = alloc_mountinfo ();
 #endif
        default_prefs (&currprefs, 0);
-       fix_options ();
+       fixup_prefs (&currprefs);
     }
 
     if (! graphics_setup ()) {
@@ -609,7 +614,7 @@ static void real_main2 (int argc, char **argv)
 
     logging_init(); /* Yes, we call this twice - the first case handles when the user has loaded
                       a config using the cmd-line.  This case handles loads through the GUI. */
-    fix_options ();
+    fixup_prefs (&currprefs);
     changed_prefs = currprefs;
 
     savestate_init ();
index 5c14fb9854bfb668f754ffd18c22fa29b5cc18d8..e3ce3720bfceb38abd940713b7eb224ffd22636d 100755 (executable)
--- a/memory.c
+++ b/memory.c
@@ -1801,6 +1801,12 @@ void memory_reset (void)
     map_banks (&kickmem_bank, 0xF8, 8, 0);
     if (currprefs.maprom)
        map_banks (&kickram_bank, currprefs.maprom >> 16, 8, 0);
+    /* map beta Kickstarts to 0x200000 */
+    if (kickmemory[2] == 0x4e && kickmemory[3] == 0xf9 && kickmemory[4] == 0x00) {
+       uae_u32 addr = kickmemory[5];
+        if (addr == 0x20 && currprefs.chipmem_size <= 0x200000 && currprefs.fastmem_size == 0)
+           map_banks (&kickmem_bank, addr, 8, 0);
+    }
 
     if (a1000_bootrom)
         a1000_handle_kickstart (1);
diff --git a/od-win32/7z/DLL.h b/od-win32/7z/DLL.h
new file mode 100755 (executable)
index 0000000..2e75a89
--- /dev/null
@@ -0,0 +1,56 @@
+// Windows/DLL.h
+
+#ifndef __WINDOWS_DLL_H
+#define __WINDOWS_DLL_H
+
+#pragma once
+
+#include "String.h"
+
+namespace NWindows {
+namespace NDLL {
+
+class CLibrary
+{
+  bool LoadOperations(HMODULE newModule);
+protected:
+  HMODULE _module;
+public:
+  operator HMODULE() const { return _module; }
+  HMODULE* operator&() { return &_module; }
+
+  CLibrary():_module(NULL) {};
+  ~CLibrary();
+  void Attach(HMODULE m)
+  {
+    Free();
+    _module = m;
+  }
+  HMODULE Detach()
+  {
+    HMODULE m = _module;
+    _module = NULL;
+    return m;
+  }
+
+  // operator HMODULE() const { return _module; };
+  // bool IsLoaded() const { return (_module != NULL); };
+  bool Free();
+  bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+  bool Load(LPCTSTR fileName);
+  #ifndef _UNICODE
+  bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+  bool Load(LPCWSTR fileName);
+  #endif
+  FARPROC GetProcAddress(LPCSTR procName) const
+    { return ::GetProcAddress(_module, procName); }
+};
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result);
+#endif
+
+}}
+
+#endif
diff --git a/od-win32/7z/Defs.h b/od-win32/7z/Defs.h
new file mode 100755 (executable)
index 0000000..bfaaa6c
--- /dev/null
@@ -0,0 +1,22 @@
+// Common/Defs.h
+
+// #pragma once
+
+#ifndef __COMMON_DEFS_H
+#define __COMMON_DEFS_H
+
+template <class T> inline T MyMin(T a, T b)
+  {  return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b)
+  {  return a > b ? a : b; }
+
+template <class T> inline int MyCompare(T a, T b)
+  {  return a < b ? -1 : (a == b ? 0 : 1); }
+
+inline int BoolToInt(bool value)
+  { return (value ? 1: 0); }
+
+inline bool IntToBool(int value)
+  { return (value != 0); }
+
+#endif
diff --git a/od-win32/7z/FileIO.h b/od-win32/7z/FileIO.h
new file mode 100755 (executable)
index 0000000..a8360c0
--- /dev/null
@@ -0,0 +1,98 @@
+// Windows/FileIO.h
+
+#pragma once
+
+#ifndef __WINDOWS_FILEIO_H
+#define __WINDOWS_FILEIO_H
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+struct CByHandleFileInfo
+{ 
+  DWORD    Attributes; 
+  FILETIME CreationTime; 
+  FILETIME LastAccessTime; 
+  FILETIME LastWriteTime; 
+  DWORD    VolumeSerialNumber; 
+  UINT64   Size;
+  DWORD    NumberOfLinks; 
+  UINT64   FileIndex; 
+};
+
+class CFileBase
+{
+protected:
+  bool _fileIsOpen;
+  HANDLE _handle;
+  bool Create(LPCTSTR fileName, DWORD desiredAccess,
+      DWORD shareMode, DWORD creationDisposition,  DWORD flagsAndAttributes);
+  #ifndef _UNICODE
+  bool Create(LPCWSTR fileName, DWORD desiredAccess,
+      DWORD shareMode, DWORD creationDisposition,  DWORD flagsAndAttributes);
+  #endif
+
+public:
+  CFileBase():
+    _fileIsOpen(false){};
+  virtual ~CFileBase();
+
+  virtual bool Close();
+
+  bool GetPosition(UINT64 &position) const;
+  bool GetLength(UINT64 &length) const;
+
+  bool Seek(INT64 distanceToMove, DWORD moveMethod, UINT64 &newPosition) const;
+  bool Seek(UINT64 position, UINT64 &newPosition); 
+  bool SeekToBegin(); 
+  bool SeekToEnd(UINT64 &newPosition); 
+  
+  bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+  bool Open(LPCTSTR fileName, DWORD shareMode, 
+      DWORD creationDisposition,  DWORD flagsAndAttributes);
+  bool Open(LPCTSTR fileName);
+  #ifndef _UNICODE
+  bool Open(LPCWSTR fileName, DWORD shareMode, 
+      DWORD creationDisposition,  DWORD flagsAndAttributes);
+  bool Open(LPCWSTR fileName);
+  #endif
+  bool Read(void *data, UINT32 size, UINT32 &processedSize);
+};
+
+class COutFile: public CFileBase
+{
+  DWORD m_CreationDisposition;
+public:
+  COutFile(): m_CreationDisposition(CREATE_NEW){};
+  bool Open(LPCTSTR fileName, DWORD shareMode, 
+      DWORD creationDisposition, DWORD flagsAndAttributes);
+  bool Open(LPCTSTR fileName);
+
+  #ifndef _UNICODE
+  bool Open(LPCWSTR fileName, DWORD shareMode, 
+      DWORD creationDisposition, DWORD flagsAndAttributes);
+  bool Open(LPCWSTR fileName);
+  #endif
+
+  void SetOpenCreationDisposition(DWORD creationDisposition)
+    { m_CreationDisposition = creationDisposition; }
+  void SetOpenCreationDispositionCreateAlways()
+    { m_CreationDisposition = CREATE_ALWAYS; }
+
+  bool SetTime(const FILETIME *creationTime,
+      const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+  bool SetLastWriteTime(const FILETIME *lastWriteTime);
+  bool Write(const void *data, UINT32 size, UINT32 &processedSize);
+  bool SetEndOfFile();
+  bool SetLength(UINT64 length);
+};
+
+}}}
+
+#endif
diff --git a/od-win32/7z/FileStreams.h b/od-win32/7z/FileStreams.h
new file mode 100755 (executable)
index 0000000..b288ce4
--- /dev/null
@@ -0,0 +1,55 @@
+// FileStreams.h
+
+#pragma once
+
+#ifndef __FILESTREAMS_H
+#define __FILESTREAMS_H
+
+#include "FileIO.h"
+
+#include "IStream.h"
+#include "MyCom.h"
+
+class CInFileStream: 
+  public IInStream,
+  public IStreamGetSize,
+  public CMyUnknownImp
+{
+public:
+  NWindows::NFile::NIO::CInFile File;
+  CInFileStream() {}
+  bool Open(LPCTSTR fileName);
+  #ifndef _UNICODE
+  bool Open(LPCWSTR fileName);
+  #endif
+
+  MY_UNKNOWN_IMP1(IStreamGetSize)
+
+  STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
+  STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+  STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition);
+
+  STDMETHOD(GetSize)(UINT64 *size);
+};
+
+class COutFileStream: 
+  public IOutStream,
+  public CMyUnknownImp
+{
+public:
+  NWindows::NFile::NIO::COutFile File;
+  COutFileStream() {}
+  bool Open(LPCTSTR fileName);
+  #ifndef _UNICODE
+  bool Open(LPCWSTR fileName);
+  #endif
+  
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+  STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+  STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition);
+  STDMETHOD(SetSize)(INT64 newSize);
+};
+
+#endif
diff --git a/od-win32/7z/IArchive.h b/od-win32/7z/IArchive.h
new file mode 100755 (executable)
index 0000000..6372868
--- /dev/null
@@ -0,0 +1,172 @@
+// IArchive.h
+
+#ifndef __IARCHIVE_H
+#define __IARCHIVE_H
+
+#include "IStream.h"
+#include "IProgress.h"
+#include "PropID.h"
+
+namespace NFileTimeType
+{
+  enum EEnum
+  {
+    kWindows,
+    kUnix,
+    kDOS
+  };
+}
+
+namespace NArchive
+{
+  enum 
+  {
+    kName = 0,
+    kClassID,
+    kExtension,
+    kAddExtension,
+    kUpdate,
+    kKeepName,
+  };
+
+  namespace NExtract
+  {
+    namespace NAskMode
+    {
+      enum 
+      {
+        kExtract = 0,
+        kTest,
+        kSkip,
+      };
+    }
+    namespace NOperationResult
+    {
+      enum 
+      {
+        kOK = 0,
+        kUnSupportedMethod,
+        kDataError,
+        kCRCError,
+      };
+    }
+  }
+  namespace NUpdate
+  {
+    namespace NOperationResult
+    {
+      enum 
+      {
+        kOK = 0,
+        kError,
+      };
+    }
+  }
+}
+
+// {23170F69-40C1-278A-0000-000100010000}
+DEFINE_GUID(IID_IArchiveOpenCallback, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100010000")
+IArchiveOpenCallback: public IUnknown
+{
+public:
+  STDMETHOD(SetTotal)(const UINT64 *files, const UINT64 *bytes) PURE;
+  STDMETHOD(SetCompleted)(const UINT64 *files, const UINT64 *bytes) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000100090000}
+DEFINE_GUID(IID_IArchiveExtractCallback, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100090000")
+IArchiveExtractCallback: public IProgress
+{
+public:
+  STDMETHOD(GetStream)(UINT32 index, ISequentialOutStream **outStream, 
+      INT32 askExtractMode) PURE;
+  STDMETHOD(PrepareOperation)(INT32 askExtractMode) PURE;
+  STDMETHOD(SetOperationResult)(INT32 resultEOperationResult) PURE;
+};
+
+
+// {23170F69-40C1-278A-0000-0001000D0000}
+DEFINE_GUID(IID_IArchiveOpenVolumeCallback, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000D0000")
+IArchiveOpenVolumeCallback: public IUnknown
+{
+public:
+  STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE;
+  STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE;
+};
+
+
+// {23170F69-40C1-278A-0000-000100080000}
+DEFINE_GUID(IID_IInArchive, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100080000")
+IInArchive: public IUnknown
+{
+public:
+  STDMETHOD(Open)(IInStream *stream, const UINT64 *maxCheckStartPosition,
+      IArchiveOpenCallback *openArchiveCallback) PURE;  
+  STDMETHOD(Close)() PURE;  
+  STDMETHOD(GetNumberOfItems)(UINT32 *numItems) PURE;  
+  STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value) PURE;
+  STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, 
+      INT32 testMode, IArchiveExtractCallback *extractCallback) PURE;
+
+  STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE;
+
+  STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE;  
+  STDMETHOD(GetPropertyInfo)(UINT32 index,     
+      BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+
+  STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties) PURE;  
+  STDMETHOD(GetArchivePropertyInfo)(UINT32 index,     
+      BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+};
+
+
+// {23170F69-40C1-278A-0000-000100040000}
+DEFINE_GUID(IID_IArchiveUpdateCallback, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100040000")
+IArchiveUpdateCallback: public IProgress
+{
+public:
+  // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) PURE;  
+  STDMETHOD(GetUpdateItemInfo)(UINT32 index, 
+      INT32 *newData, // 1 - new data, 0 - old data
+      INT32 *newProperties, // 1 - new properties, 0 - old properties
+      UINT32 *indexInArchive // -1 if there is no in archive, or if doesn't matter
+      ) PURE;
+  STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value) PURE;
+  STDMETHOD(GetStream)(UINT32 index, IInStream **inStream) PURE;
+  STDMETHOD(SetOperationResult)(INT32 operationResult) PURE;
+  // STDMETHOD(GetVolumeSize)(UINT32 index, UINT64 *size) PURE;
+  // STDMETHOD(GetVolumeStream)(UINT32 index, IOutStream **volumeStream) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000100020000}
+DEFINE_GUID(IID_IOutArchive, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100020000")
+IOutArchive: public IUnknown
+{
+  STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
+      IArchiveUpdateCallback *updateCallback) PURE;
+  STDMETHOD(GetFileTimeType)(UINT32 *type) PURE;  
+};
+
+// {23170F69-40C1-278A-0000-000100030000}
+DEFINE_GUID(IID_ISetProperties, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100030000")
+ISetProperties: public IUnknown
+{
+  STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties) PURE;
+};
+
+
+#endif
diff --git a/od-win32/7z/IMyUnknown.h b/od-win32/7z/IMyUnknown.h
new file mode 100755 (executable)
index 0000000..d614d99
--- /dev/null
@@ -0,0 +1,71 @@
+// IMyUnknown.h
+
+// #pragma once
+
+#ifndef __MYUNKNOWN_H
+#define __MYUNKNOWN_H
+
+#ifdef WIN32
+
+// #include <guiddef.h>
+#include <basetyps.h>
+
+#else 
+
+#define HRESULT LONG
+#define STDMETHODCALLTYPE __stdcall 
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)
+
+#define PURE = 0;
+
+typedef struct {
+  unsigned long  Data1;
+  unsigned short Data2;
+  unsigned short Data3;
+  unsigned char Data4[8];
+} GUID;
+
+#ifdef __cplusplus
+    #define MY_EXTERN_C    extern "C"
+#else
+    #define MY_EXTERN_C    extern
+#endif
+
+#ifdef INITGUID
+  #define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+      MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
+#else
+  #define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+      MY_EXTERN_C const GUID name
+#endif
+
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID * __MIDL_CONST
+#endif
+
+#define MIDL_INTERFACE(x) struct 
+inline int operator==(REFGUID g1, REFGUID g2)
+{ 
+  for (int i = 0; i < sizeof(g1); i++)
+    if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
+      return false;
+  return true;
+}
+inline int operator!=(REFGUID &g1, REFGUID &g2)
+  { return !(g1 == g2); }
+
+struct IUnknown
+{
+  STDMETHOD(QueryInterface) (const GUID *iid, void **outObject) PURE;
+  STDMETHOD_(ULONG, AddRef)() PURE;
+  STDMETHOD_(ULONG, Release)() PURE;
+};
+
+#endif
+  
+#endif
diff --git a/od-win32/7z/IProgress.h b/od-win32/7z/IProgress.h
new file mode 100755 (executable)
index 0000000..db14b05
--- /dev/null
@@ -0,0 +1,32 @@
+// Interface/IProgress.h
+
+// #pragma once
+
+#ifndef __IPROGRESS_H
+#define __IPROGRESS_H
+
+// {23170F69-40C1-278A-0000-000000050000}
+DEFINE_GUID(IID_IProgress, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050000")
+IProgress: public IUnknown
+{
+public:
+  STDMETHOD(SetTotal)(UINT64 total) PURE;
+  STDMETHOD(SetCompleted)(const UINT64 *completeValue) PURE;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000000050002}
+DEFINE_GUID(IID_IProgress2, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002")
+IProgress2: public IUnknown
+{
+public:
+  STDMETHOD(SetTotal)(const UINT64 *total) PURE;
+  STDMETHOD(SetCompleted)(const UINT64 *completeValue) PURE;
+};
+*/
+
+#endif
diff --git a/od-win32/7z/IStream.h b/od-win32/7z/IStream.h
new file mode 100755 (executable)
index 0000000..147be41
--- /dev/null
@@ -0,0 +1,64 @@
+// IStream.h
+
+// #pragma once
+
+#ifndef __ISTREAMS_H
+#define __ISTREAMS_H
+
+#include "IMyUnknown.h"
+
+// {23170F69-40C1-278A-0000-000000010000}
+DEFINE_GUID(IID_ISequentialInStream, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000")
+ISequentialInStream : public IUnknown
+{
+public:
+  // out: if (processedSize == 0) then there are no more bytes
+  STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize) = 0;
+  STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000000020000}
+DEFINE_GUID(IID_ISequentialOutStream, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000")
+ISequentialOutStream : public IUnknown
+{
+public:
+  STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize) = 0;
+  STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000000030000}
+DEFINE_GUID(IID_IInStream, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000")
+IInStream : public ISequentialInStream
+{
+public:
+  STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000000040000}
+DEFINE_GUID(IID_IOutStream, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000")
+IOutStream : public ISequentialOutStream
+{
+public:
+  STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0;
+  STDMETHOD(SetSize)(INT64 aNewSize) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000000060000}
+DEFINE_GUID(IID_IStreamGetSize, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000")
+IStreamGetSize : public IUnknown
+{
+public:
+  STDMETHOD(GetSize)(UINT64 *size) = 0;
+};
+
+#endif
diff --git a/od-win32/7z/MyCom.h b/od-win32/7z/MyCom.h
new file mode 100755 (executable)
index 0000000..40e4ce2
--- /dev/null
@@ -0,0 +1,187 @@
+// MyCom.h
+
+// #pragma once
+
+#ifndef __MYCOM_H
+#define __MYCOM_H
+
+#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+
+template <class T>
+class CMyComPtr
+{
+  T* _p;
+public:
+  // typedef T _PtrClass;
+  CMyComPtr() { _p = NULL;}
+  CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
+  CMyComPtr(const CMyComPtr<T>& lp)
+  {
+    if ((_p = lp._p) != NULL)
+      _p->AddRef();
+  }
+  ~CMyComPtr() { if (_p) _p->Release(); }
+  void Release() { if (_p) { _p->Release(); _p = NULL; } }
+  operator T*() const {  return (T*)_p;  }
+  // T& operator*() const {  return *_p; }
+  T** operator&() { return &_p; }
+  T* operator->() const { return _p; }
+  T* operator=(T* p) 
+  { 
+    if (p != 0)
+      p->AddRef();
+    if (_p) 
+      _p->Release();
+    _p = p;
+    return p;
+  }
+  T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
+  bool operator!() const { return (_p == NULL); }
+  // bool operator==(T* pT) const {  return _p == pT; }
+  // Compare two objects for equivalence
+  void Attach(T* p2)
+  {
+    Release();
+    _p = p2;
+  }
+  T* Detach()
+  {
+    T* pt = _p;
+    _p = NULL;
+    return pt;
+  }
+  HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+  {
+    return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
+  }
+  /*
+  HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+  {
+    CLSID clsid;
+    HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
+    ATLASSERT(_p == NULL);
+    if (SUCCEEDED(hr))
+      hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
+    return hr;
+  }
+  */
+  template <class Q>
+  HRESULT QueryInterface(REFGUID iid, Q** pp) const
+  {
+    return _p->QueryInterface(iid, (void**)pp);
+  }
+};
+
+//////////////////////////////////////////////////////////
+
+class CMyComBSTR
+{
+public:
+  BSTR m_str;
+  CMyComBSTR() { m_str = NULL; }
+  CMyComBSTR(LPCOLESTR pSrc) {  m_str = ::SysAllocString(pSrc);  }
+  // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
+  // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize);  }
+  CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+  /*
+  CMyComBSTR(REFGUID src)
+  {
+    LPOLESTR szGuid;
+    StringFromCLSID(src, &szGuid);
+    m_str = ::SysAllocString(szGuid);
+    CoTaskMemFree(szGuid);
+  }
+  */
+  ~CMyComBSTR() { ::SysFreeString(m_str); }
+  CMyComBSTR& operator=(const CMyComBSTR& src)
+  {
+    if (m_str != src.m_str)
+    {
+      if (m_str)
+        ::SysFreeString(m_str);
+      m_str = src.MyCopy();
+    }
+    return *this;
+  }
+  CMyComBSTR& operator=(LPCOLESTR pSrc)
+  {
+    ::SysFreeString(m_str);
+    m_str = ::SysAllocString(pSrc);
+    return *this;
+  }
+  unsigned int Length() const { return ::SysStringLen(m_str); }
+  operator BSTR() const { return m_str; }
+  BSTR* operator&() { return &m_str; }
+  BSTR MyCopy() const 
+  { 
+    int byteLen = ::SysStringByteLen(m_str);
+    BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
+    memmove(res, m_str, byteLen);
+    return res;
+  }
+  void Attach(BSTR src) {  m_str = src; }
+  BSTR Detach()
+  {
+    BSTR s = m_str;
+    m_str = NULL;
+    return s;
+  }
+  void Empty()
+  {
+    ::SysFreeString(m_str);
+    m_str = NULL;
+  }
+  bool operator!() const {  return (m_str == NULL); }
+};
+
+
+//////////////////////////////////////////////////////////
+
+class CMyUnknownImp
+{
+public:
+  ULONG __m_RefCount;
+  CMyUnknownImp(): __m_RefCount(0) {}
+};
+
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
+    (REFGUID iid, void **outObject) { 
+#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
+    { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+
+#define MY_ADDREF_RELEASE \
+STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0)  \
+  return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC(i) \
+  MY_QUERYINTERFACE_BEGIN \
+  i \
+  MY_QUERYINTERFACE_END \
+  MY_ADDREF_RELEASE
+
+
+#define MY_UNKNOWN_IMP MY_UNKNOWN_IMP_SPEC(;)
+
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY(i) \
+  )
+
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY(i1) \
+  MY_QUERYINTERFACE_ENTRY(i2) \
+  )
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY(i1) \
+  MY_QUERYINTERFACE_ENTRY(i2) \
+  MY_QUERYINTERFACE_ENTRY(i3) \
+  )
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY(i1) \
+  MY_QUERYINTERFACE_ENTRY(i2) \
+  MY_QUERYINTERFACE_ENTRY(i3) \
+  MY_QUERYINTERFACE_ENTRY(i4) \
+  )
+
+#endif
diff --git a/od-win32/7z/PropID.h b/od-win32/7z/PropID.h
new file mode 100755 (executable)
index 0000000..d0e8e86
--- /dev/null
@@ -0,0 +1,51 @@
+// Interface/PropID.h
+
+// #pragma once
+
+#ifndef __INTERFACE_PROPID_H
+#define __INTERFACE_PROPID_H
+
+enum
+{
+  kpidNoProperty = 0,
+  
+  kpidHandlerItemIndex = 2,
+  kpidPath,
+  kpidName,
+  kpidExtension,
+  kpidIsFolder,
+  kpidSize,
+  kpidPackedSize,
+  kpidAttributes,
+  kpidCreationTime,
+  kpidLastAccessTime,
+  kpidLastWriteTime,
+  kpidSolid, 
+  kpidCommented, 
+  kpidEncrypted, 
+  kpidSplitBefore, 
+  kpidSplitAfter, 
+  kpidDictionarySize, 
+  kpidCRC, 
+  kpidType,
+  kpidIsAnti,
+  kpidMethod,
+  kpidHostOS,
+  kpidFileSystem,
+  kpidUser,
+  kpidGroup,
+  kpidBlock,
+  kpidComment,
+
+  kpidTotalSize = 0x1100,
+  kpidFreeSpace, 
+  kpidClusterSize,
+  kpidVolumeName,
+
+  kpidLocalName = 0x1200,
+  kpidProvider,
+
+  kpidUserDefined = 0x10000
+};
+
+#endif
diff --git a/od-win32/7z/PropVariant.h b/od-win32/7z/PropVariant.h
new file mode 100755 (executable)
index 0000000..44fd74f
--- /dev/null
@@ -0,0 +1,60 @@
+// Windows/PropVariant.h
+
+// #pragma once
+
+#ifndef __WINDOWS_PROPVARIANT_H
+#define __WINDOWS_PROPVARIANT_H
+
+namespace NWindows {
+namespace NCOM {
+
+class CPropVariant : public tagPROPVARIANT
+{
+public:
+  CPropVariant() { vt = VT_EMPTY; }
+  ~CPropVariant() { Clear(); }
+  CPropVariant(const PROPVARIANT& varSrc);
+  CPropVariant(const CPropVariant& varSrc);
+  CPropVariant(BSTR bstrSrc);
+  CPropVariant(LPCOLESTR lpszSrc);
+  CPropVariant(bool bSrc) { vt = VT_BOOL; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
+  CPropVariant(UINT32 value) {  vt = VT_UI4; ulVal = value; }
+  CPropVariant(UINT64 value) {  vt = VT_UI8; uhVal = *(ULARGE_INTEGER*)&value; }
+  CPropVariant(const FILETIME &value) {  vt = VT_FILETIME; filetime = value; }
+  CPropVariant(int value) { vt = VT_I4; lVal = value; }
+  CPropVariant(BYTE value) { vt = VT_UI1; bVal = value; }
+  CPropVariant(short value) { vt = VT_I2; iVal = value; }
+  CPropVariant(long value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
+
+  CPropVariant& operator=(const CPropVariant& varSrc);
+  CPropVariant& operator=(const PROPVARIANT& varSrc);
+  CPropVariant& operator=(BSTR bstrSrc);
+  CPropVariant& operator=(LPCOLESTR lpszSrc);
+  CPropVariant& operator=(bool bSrc);
+  CPropVariant& operator=(UINT32 value);
+  CPropVariant& operator=(UINT64 value);
+  CPropVariant& operator=(const FILETIME &value);
+
+  CPropVariant& operator=(int value);
+  CPropVariant& operator=(BYTE value);
+  CPropVariant& operator=(short value);
+  CPropVariant& operator=(long value);
+
+  HRESULT Clear();
+  HRESULT Copy(const PROPVARIANT* pSrc);
+  HRESULT Attach(PROPVARIANT* pSrc);
+  HRESULT Detach(PROPVARIANT* pDest);
+  HRESULT ChangeType(VARTYPE vtNew, const PROPVARIANT* pSrc = NULL);
+
+  HRESULT InternalClear();
+  void InternalCopy(const PROPVARIANT* pSrc);
+
+  HRESULT WriteToStream(ISequentialStream *stream) const;
+  HRESULT ReadFromStream(ISequentialStream *stream);
+  
+  int Compare(const CPropVariant &a1);
+};
+
+}}
+
+#endif
diff --git a/od-win32/7z/PropVariantConversions.h b/od-win32/7z/PropVariantConversions.h
new file mode 100755 (executable)
index 0000000..a32bacc
--- /dev/null
@@ -0,0 +1,17 @@
+// Windows/PropVariantConversions.h
+
+#pragma once
+
+#ifndef __PROPVARIANTCONVERSIONS_H
+#define __PROPVARIANTCONVERSIONS_H
+
+#include "String.h"
+
+// CSysString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime = true);
+UString ConvertFileTimeToString2(const FILETIME &fileTime, bool includeTime = true, 
+    bool includeSeconds = true);
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant);
+
+UINT64 ConvertPropVariantToUINT64(const PROPVARIANT &propVariant);
+
+#endif
diff --git a/od-win32/7z/String.h b/od-win32/7z/String.h
new file mode 100755 (executable)
index 0000000..be27327
--- /dev/null
@@ -0,0 +1,672 @@
+// Common/String.h
+
+#pragma once
+
+#ifndef __COMMON_STRING_H
+#define __COMMON_STRING_H
+
+#include "Vector.h"
+
+extern bool g_IsNT;
+
+static const char *kTrimDefaultCharSet  = " \n\t";
+
+template <class T>
+inline size_t MyStringLen(const T *s)
+{ 
+  int i;
+  for (i = 0; s[i] != '\0'; i++);
+  return i;
+}
+
+template <class T>
+inline T * MyStringCopy(T *dest, const T *src)
+{ 
+  T *destStart = dest;
+  while((*dest++ = *src++) != 0);
+  return destStart;
+}
+
+inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
+  { return (p + 1); }
+inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
+  { return (p + 1); }
+inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, wchar_t *p)
+  { return (p - 1); }
+inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, const wchar_t *p)
+  { return (p - 1); }
+
+#ifdef WIN32
+
+inline char* MyStringGetNextCharPointer(char *p)
+  { return CharNextA(p); }
+inline const char* MyStringGetNextCharPointer(const char *p)
+  { return CharNextA(p); }
+
+inline char* MyStringGetPrevCharPointer(char *base, char *p)
+  { return CharPrevA(base, p); }
+inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
+  { return CharPrevA(base, p); }
+
+inline char MyCharUpper(char c)
+  { return (char)CharUpperA((LPSTR)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharUpper(wchar_t c)
+  { return (wchar_t)CharUpperW((LPWSTR)c); }
+#else
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+inline char MyCharLower(char c)
+  { return (char)CharLowerA((LPSTR)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharLower(wchar_t c)
+  { return (wchar_t)CharLowerW((LPWSTR)c); }
+#else
+wchar_t MyCharLower(wchar_t c);
+#endif
+
+
+inline char * MyStringUpper(char *s)
+  { return CharUpperA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringUpper(wchar_t *s)
+  { return CharUpperW(s); }
+#else
+wchar_t * MyStringUpper(wchar_t *s);
+#endif
+
+inline char * MyStringLower(char *s)
+  { return CharLowerA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringLower(wchar_t *s)
+  { return CharLowerW(s); }
+#else
+wchar_t * MyStringLower(wchar_t *s);
+#endif
+
+
+//////////////////////////////////////
+// Compare
+
+inline int ConvertCompareResult(int r)
+  { return r - 2; }
+
+inline int MyStringCollate(const char *s1, const char *s2)
+  { return ConvertCompareResult(CompareStringA(
+    LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); }
+#ifdef _UNICODE
+inline int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
+  { return ConvertCompareResult(CompareStringW(
+    LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); }
+#else
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
+#endif
+
+inline int MyStringCollateNoCase(const char *s1, const char *s2)
+  { return ConvertCompareResult(CompareStringA(
+    LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); }
+#ifdef _UNICODE
+inline int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+  { return ConvertCompareResult(CompareStringW(
+    LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); }
+#else
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
+#endif
+
+#else // Standard-C
+
+inline NormalizeCompareResult(int res)
+{
+  if (res < 0)
+    return -1;
+  if (res > 0)
+    return 1;
+  return 0;
+}
+
+inline wchar_t MyCharUpper(wchar_t c)
+  { return towupper(c); }
+
+inline int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+  { return NormalizeCompareResult(wcscoll(s1, s2)); }
+
+#endif
+
+
+template <class T>
+inline int MyStringCompare(const T *s1, const T *s2)
+{ 
+  while (true)
+  {
+    unsigned int c1 = (unsigned int)*s1++;
+    unsigned int c2 = (unsigned int)*s2++;
+    if (c1 < c2)
+      return -1;
+    if (c1 > c2)
+      return 1;
+    if (c1 == 0)
+      return 0;
+  }
+}
+
+template <class T>
+inline int MyStringCompareNoCase(const T *s1, const T *s2)
+  { return MyStringCollateNoCase(s1, s2); }
+
+template <class T>
+class CStringBase
+{
+  void TrimLeftWithCharSet(const CStringBase &charSet)
+  {
+    const T *p = _chars;
+    while (charSet.Find(*p) >= 0 && (*p != 0))
+      p = GetNextCharPointer(p);
+    Delete(0, p - _chars);
+  }
+  void TrimRightWithCharSet(const CStringBase &charSet)
+  {
+    const T *p = _chars;
+    const T *pLast = NULL;
+    while (*p != 0)
+    {
+      if (charSet.Find(*p) >= 0)
+      {
+        if (pLast == NULL)
+          pLast = p;
+      }
+      else
+        pLast = NULL;
+      p = GetNextCharPointer(p);
+    }
+    if(pLast != NULL)
+    {
+      int i = pLast - _chars;
+      Delete(i, _length - i);
+    }
+
+  }
+  void MoveItems(int destIndex, int srcIndex)
+  {
+    memmove(_chars + destIndex, _chars + srcIndex, 
+        sizeof(T) * (_length - srcIndex + 1));
+  }
+  
+  void InsertSpace(int &index, int size)
+  {
+    CorrectIndex(index);
+    GrowLength(size);
+    MoveItems(index + size, index);
+  }
+
+  static T *GetNextCharPointer(T *p)
+    { return MyStringGetNextCharPointer(p); }
+  static const T *GetNextCharPointer(const T *p)
+    { return MyStringGetNextCharPointer(p); }
+  static T *GetPrevCharPointer(T *base, T *p)
+    { return MyStringGetPrevCharPointer(base, p); }
+  static const T *GetPrevCharPointer(const T *base, const T *p)
+    { return MyStringGetPrevCharPointer(base, p); }
+protected:
+  T *_chars;
+  int _length;
+       int _capacity;
+  
+  void SetCapacity(int newCapacity)
+  {
+    int realCapacity = newCapacity + 1;
+    if(realCapacity == _capacity)
+      return;
+    /*
+    const int kMaxStringSize = 0x20000000;
+    #ifndef _WIN32_WCE
+    if(newCapacity > kMaxStringSize || newCapacity < _length)
+      throw 1052337;
+    #endif
+    */
+    T *newBuffer = new T[realCapacity];
+    if(_capacity > 0)
+    {
+      for (int i = 0; i < (_length + 1); i++)
+        newBuffer[i] = _chars[i];
+      delete []_chars;
+      _chars = newBuffer;
+    }
+    else
+    {
+      _chars = newBuffer;
+      _chars[0] = 0;
+    }
+    _capacity = realCapacity;
+  }
+
+  void GrowLength(int n)
+  {
+    int freeSize = _capacity - _length - 1;
+    if (n <= freeSize) 
+      return;
+    int delta;
+    if (_capacity > 64)
+      delta = _capacity / 2;
+    else if (_capacity > 8)
+      delta = 16;
+    else
+      delta = 4;
+    if (freeSize + delta < n)
+      delta = n - freeSize;
+    SetCapacity(_capacity + delta);
+  }
+
+  void CorrectIndex(int &index) const
+  {
+    if (index > _length)
+      index = _length;
+  }
+
+public:
+  CStringBase(): _chars(0), _length(0), _capacity(0)
+    { SetCapacity(16 - 1); }
+  CStringBase(T c):  _chars(0), _length(0), _capacity(0)
+  {
+    SetCapacity(1);
+    _chars[0] = c;
+    _chars[1] = 0;
+    _length = 1;
+  }
+  CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
+  {
+    int length = MyStringLen(chars);
+    SetCapacity(length);
+    MyStringCopy(_chars, chars); // can be optimized by memove()
+    _length = length;
+  }
+  CStringBase(const CStringBase &s):  _chars(0), _length(0), _capacity(0)
+  {
+    SetCapacity(s._length);
+    MyStringCopy(_chars, s._chars);
+    _length = s._length;
+  }
+  ~CStringBase() {  delete []_chars; }
+
+  operator const T*() const { return _chars;} 
+
+  // The minimum size of the character buffer in characters. 
+  // This value does not include space for a null terminator.
+  T* GetBuffer(int minBufLength)
+  {
+    if(minBufLength >= _capacity)
+      SetCapacity(minBufLength + 1);
+    return _chars;
+  }
+  void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
+  void ReleaseBuffer(int newLength)
+  {
+    /*
+    #ifndef _WIN32_WCE
+    if(newLength >= _capacity)
+      throw 282217;
+    #endif
+    */
+    _chars[newLength] = 0;
+    _length = newLength;
+  }
+
+  CStringBase& operator=(T c)
+  {
+    Empty();
+    SetCapacity(1);
+    _chars[0] = c;
+    _chars[1] = 0;
+    _length = 1;
+    return *this;
+  }
+  CStringBase& operator=(const T *chars)
+  {
+    Empty();
+    int length = MyStringLen(chars);
+    SetCapacity(length);
+    MyStringCopy(_chars, chars);
+    _length = length; 
+    return *this;
+  }  
+  CStringBase& operator=(const CStringBase& s)
+  {
+    if(&s == this)
+      return *this;
+    Empty();
+    SetCapacity(s._length);
+    MyStringCopy(_chars, s._chars);
+    _length = s._length;
+    return *this;
+  }
+  
+  CStringBase& operator+=(T c)
+  {
+    GrowLength(1);
+    _chars[_length] = c;
+    _chars[++_length] = 0;
+    return *this;
+  }
+  CStringBase& operator+=(const T *s)
+  {
+    int len = MyStringLen(s);
+    GrowLength(len);
+    MyStringCopy(_chars + _length, s);
+    _length += len;
+    return *this;
+  }
+  CStringBase& operator+=(const CStringBase &s)
+  {
+    GrowLength(s._length);
+    MyStringCopy(_chars + _length, s._chars);
+    _length += s._length;
+    return *this;
+  }
+  void Empty()
+  {
+    _length = 0;
+    _chars[0] = 0;
+  }
+  int Length() const { return _length; }
+  bool IsEmpty() const { return (_length == 0); }
+
+  CStringBase Mid(int startIndex) const
+    { return Mid(startIndex, _length - startIndex); }
+  CStringBase Mid(int startIndex, int count ) const
+  {
+    if (startIndex + count > _length)
+      count = _length - startIndex;
+    
+    if (startIndex == 0 && startIndex + count == _length)
+      return *this;
+    
+    CStringBase<T> result;
+    result.SetCapacity(count);
+    // MyStringNCopy(result._chars, _chars + startIndex, count);
+    for (int i = 0; i < count; i++)
+      result._chars[i] = _chars[startIndex + i];
+    result._chars[count] = 0;
+    result._length = count;
+    return result;
+  }
+  CStringBase Left(int count) const
+    { return Mid(0, count); }
+  CStringBase Right(int count) const
+  {
+    if (count > _length)
+      count = _length;
+    return Mid(_length - count, count);
+  }
+
+  void MakeUpper()
+    { MyStringUpper(_chars); }
+  void MakeLower()
+    { MyStringLower(_chars); }
+
+  int Compare(const CStringBase& s) const
+    { return MyStringCompare(_chars, s._chars); }
+
+  int CompareNoCase(const CStringBase& s) const
+    { return MyStringCompareNoCase(_chars, s._chars); }
+  int Collate(const CStringBase& s) const
+    { return MyStringCollate(_chars, s._chars); }
+  int CollateNoCase(const CStringBase& s) const
+    { return MyStringCollateNoCase(_chars, s._chars); }
+
+  int Find(T c) const { return Find(c, 0); }
+  int Find(T c, int startIndex) const
+  {
+    T *p = _chars + startIndex;
+    while (true)
+    {
+      if (*p == c)
+        return p - _chars;
+      if (*p == 0)
+        return -1;
+      p = GetNextCharPointer(p);
+    }
+  }
+  int Find(const CStringBase &s) const { return Find(s, 0); }
+  int Find(const CStringBase &s, int startIndex) const
+  {
+    if (s.IsEmpty())
+      return startIndex;
+    for (; startIndex < _length; startIndex++)
+    {
+      int j;
+      for (j = 0; j < s._length && startIndex + j < _length; j++)
+        if (_chars[startIndex+j] != s._chars[j])
+          break;
+      if (j == s._length)
+        return startIndex;
+    }
+    return -1;
+  }
+  int ReverseFind(T c) const
+  {
+    if (_length == 0)
+      return -1;
+    T *p = _chars + _length - 1;
+    while (true)
+    {
+      if (*p == c)
+        return p - _chars;
+      if (p == _chars)
+        return -1;
+      p = GetPrevCharPointer(_chars, p);
+    }
+  }
+  int FindOneOf(const CStringBase &s) const
+  {
+    for(int i = 0; i < _length; i++)
+      if (s.Find(_chars[i]) >= 0)
+        return i;
+      return -1;
+  }
+
+  void TrimLeft(T c)
+  {
+    const T *p = _chars;
+    while (c == *p)
+      p = GetNextCharPointer(p);
+    Delete(0, p - _chars);
+  }
+  void TrimLeft()
+  {
+    CStringBase<T> charSet;
+    for(int i = 0; i < sizeof(kTrimDefaultCharSet) /
+      sizeof(kTrimDefaultCharSet[0]); i++)
+      charSet += kTrimDefaultCharSet[i];
+    TrimLeftWithCharSet(charSet);
+  }
+  void TrimRight()
+  {
+    CStringBase<T> charSet;
+    for(int i = 0; i < sizeof(kTrimDefaultCharSet) / 
+      sizeof(kTrimDefaultCharSet[0]); i++)
+      charSet += kTrimDefaultCharSet[i];
+    TrimRightWithCharSet(charSet);
+  }
+  void TrimRight(T c)
+  {
+    const T *p = _chars;
+    const T *pLast = NULL;
+    while (*p != 0)
+    {
+      if (*p == c)
+      {
+        if (pLast == NULL)
+          pLast = p;
+      }
+      else
+        pLast = NULL;
+      p = GetNextCharPointer(p);
+    }
+    if(pLast != NULL)
+    {
+      int i = pLast - _chars;
+      Delete(i, _length - i);
+    }
+  }
+  void Trim()
+  {
+    TrimRight();
+    TrimLeft();
+  }
+
+  int Insert(int index, T c)
+  {
+    InsertSpace(index, 1);
+    _chars[index] = c;
+    _length++;
+    return _length;
+  }
+  int Insert(int index, const CStringBase &s)
+  {
+    CorrectIndex(index);
+    if (s.IsEmpty())
+      return _length;
+    int numInsertChars = s.Length();
+    InsertSpace(index, numInsertChars);
+    for(int i = 0; i < numInsertChars; i++)
+      _chars[index + i] = s[i];
+    _length += numInsertChars;
+    return _length;
+  }
+
+  // !!!!!!!!!!!!!!! test it if newChar = '\0'
+  int Replace(T oldChar, T newChar)
+  {
+    if (oldChar == newChar)
+      return 0;
+    int number  = 0;
+    int pos  = 0;
+    while (pos < Length())
+    {
+      pos = Find(oldChar, pos);
+      if (pos < 0) 
+        break;
+      _chars[pos] = newChar;
+      pos++;
+      number++;
+    }
+    return number;
+  }
+  int Replace(const CStringBase &oldString, const CStringBase &newString)
+  {
+    if (oldString.IsEmpty())
+      return 0;
+    if (oldString == newString)
+      return 0;
+    int oldStringLength = oldString.Length();
+    int newStringLength = newString.Length();
+    int number  = 0;
+    int pos  = 0;
+    while (pos < _length)
+    {
+      pos = Find(oldString, pos);
+      if (pos < 0) 
+        break;
+      Delete(pos, oldStringLength);
+      Insert(pos, newString);
+      pos += newStringLength;
+      number++;
+    }
+    return number;
+  }
+  int Delete(int index, int count = 1 )
+  {
+    if (index + count > _length)
+      count = _length - index;
+    if (count > 0)
+    {
+      MoveItems(index, index + count);
+      _length -= count;
+    }
+    return _length;
+  }
+};
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
+{
+  CStringBase<T> result(s1);
+  result += s2;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, T c)
+{
+  CStringBase<T> result(s);
+  result += c;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(T c, const CStringBase<T>& s)
+{
+  CStringBase<T> result(c);
+  result += s;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
+{
+  CStringBase<T> result(s);
+  result += chars;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
+{
+  CStringBase<T> result(chars);
+  result += s;
+  return result; 
+}
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) < 0); }
+
+template <class T>
+bool operator==(const T *s1, const CStringBase<T>& s2)
+  { return (s2.Compare(s1) == 0); }
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const T *s2)
+  { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) != 0); }
+
+template <class T>
+bool operator!=(const T *s1, const CStringBase<T>& s2)
+  { return (s2.Compare(s1) != 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const T *s2)
+  { return (s1.Compare(s2) != 0); }
+
+typedef CStringBase<char> AString;
+typedef CStringBase<wchar_t> UString;
+
+typedef CObjectVector<AString> AStringVector;
+typedef CObjectVector<UString> UStringVector;
+
+#ifdef _UNICODE
+  typedef UString CSysString;
+#else
+  typedef AString CSysString;
+#endif
+
+typedef CObjectVector<CSysString> CSysStringVector;
+
+#endif
diff --git a/od-win32/7z/StringConvert.h b/od-win32/7z/StringConvert.h
new file mode 100755 (executable)
index 0000000..982fb89
--- /dev/null
@@ -0,0 +1,72 @@
+// Common/StringConvert.h
+
+#pragma once
+
+#ifndef __COMMON_STRINGCONVERT_H
+#define __COMMON_STRINGCONVERT_H
+
+#include "String.h"
+#include "Types.h"
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
+
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
+  { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString)
+  { return unicodeString; }
+inline UString GetUnicodeString(const AString &ansiString)
+  { return MultiByteToUnicodeString(ansiString); }
+inline UString GetUnicodeString(const AString &multiByteString, UINT codePage)
+  { return MultiByteToUnicodeString(multiByteString, codePage); }
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT codePage)
+  { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString, UINT codePage)
+  { return unicodeString; }
+
+inline const char* GetAnsiString(const char* ansiString)
+  { return ansiString; }
+inline const AString& GetAnsiString(const AString &ansiString)
+  { return ansiString; }
+inline AString GetAnsiString(const UString &unicodeString)
+  { return UnicodeStringToMultiByte(unicodeString); }
+
+inline const char* GetOemString(const char* oemString)
+  { return oemString; }
+inline const AString& GetOemString(const AString &oemString)
+  { return oemString; }
+inline AString GetOemString(const UString &unicodeString)
+  { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); }
+
+
+#ifdef _UNICODE
+  inline const wchar_t* GetSystemString(const wchar_t* unicodeString)
+    { return unicodeString;}
+  inline const UString& GetSystemString(const UString &unicodeString)
+    { return unicodeString;}
+  inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT codePage)
+    { return unicodeString;}
+  inline const UString& GetSystemString(const UString &unicodeString, UINT codePage)
+    { return unicodeString;}
+  inline UString GetSystemString(const AString &multiByteString, UINT codePage)
+    { return MultiByteToUnicodeString(multiByteString, codePage);}
+  inline UString GetSystemString(const AString &multiByteString)
+    { return MultiByteToUnicodeString(multiByteString);}
+#else
+  inline const char* GetSystemString(const char *ansiString)
+    { return ansiString; }
+  inline const AString& GetSystemString(const AString &multiByteString, UINT codePage)
+    { return multiByteString; }
+  inline const char * GetSystemString(const char *multiByteString, UINT codePage)
+    { return multiByteString; }
+  inline AString GetSystemString(const UString &unicodeString)
+    { return UnicodeStringToMultiByte(unicodeString); }
+  inline AString GetSystemString(const UString &unicodeString, UINT codePage)
+    { return UnicodeStringToMultiByte(unicodeString, codePage); }
+#endif
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString);
+#endif
+
+#endif
diff --git a/od-win32/7z/Types.h b/od-win32/7z/Types.h
new file mode 100755 (executable)
index 0000000..02853e0
--- /dev/null
@@ -0,0 +1,19 @@
+// Common/Types.h
+
+// #pragma once
+
+#ifndef __COMMON_TYPES_H
+#define __COMMON_TYPES_H
+
+#include <basetsd.h>
+
+typedef unsigned char   UINT8;
+typedef unsigned short  UINT16;
+typedef short INT16;
+#ifndef _WINDOWS_ 
+  // typedef unsigned long UINT32;
+  typedef UINT8 BYTE;
+#endif
+
+#endif
+
diff --git a/od-win32/7z/Vector.h b/od-win32/7z/Vector.h
new file mode 100755 (executable)
index 0000000..051d4e4
--- /dev/null
@@ -0,0 +1,177 @@
+// Common/Vector.h
+
+#pragma once
+
+#ifndef __COMMON_VECTOR_H
+#define __COMMON_VECTOR_H
+
+#include "Defs.h"
+
+class CBaseRecordVector
+{
+  void MoveItems(int destIndex, int srcIndex);
+protected:
+       int _capacity;
+  int _size;
+       void *_items;
+  size_t _itemSize;
+
+       void ReserveOnePosition();
+  void InsertOneItem(int index);
+  void TestIndexAndCorrectNum(int index, int &num) const
+    { if (index + num > _size) num = _size - index; } 
+public:
+  CBaseRecordVector(size_t itemSize):
+      _size(0), _capacity(0), _items(0), _itemSize(itemSize) {}
+       virtual ~CBaseRecordVector();
+  int Size() const { return _size; }
+       bool IsEmpty() const { return (_size == 0); }
+       void Reserve(int newCapacity);
+       virtual void Delete(int index, int num = 1);
+       void Clear();
+  void DeleteFrom(int index);
+  void DeleteBack();
+};
+
+template <class T>
+class CRecordVector: public CBaseRecordVector
+{
+public:
+  CRecordVector():CBaseRecordVector(sizeof(T)){};
+  CRecordVector(const CRecordVector &v):
+    CBaseRecordVector(sizeof(T)) { *this = v;}
+       CRecordVector& operator=(const CRecordVector &v)
+  {
+    Clear();
+    return (*this += v);
+  }
+  CRecordVector& operator+=(const CRecordVector &v)
+  {
+    int size = v.Size();
+    Reserve(Size() + size);
+    for(int i = 0; i < size; i++)
+      Add(v[i]);
+    return *this;
+  }
+       int Add(T item)
+  {
+    ReserveOnePosition();
+    ((T *)_items)[_size] = item;
+    return _size++;
+  }
+       void Insert(int index, T item)
+  {
+    InsertOneItem(index);
+    ((T *)_items)[index] = item;
+  }
+  // T* GetPointer() const { return (T*)_items; }
+  // operator const T *() const { return _items; };
+  const T& operator[](int index) const { return ((T *)_items)[index]; }
+       T& operator[](int index) { return ((T *)_items)[index]; }
+       const T& Front() const { return operator[](0); }
+  T& Front()   { return operator[](0); }
+       const T& Back() const { return operator[](_size - 1); }
+  T& Back()   { return operator[](_size - 1); }
+  static int __cdecl CompareRecordItems(const void *a1, const void *a2)
+    { return MyCompare(*((const T *)a1), *((const T *)a2)); }
+  void Sort()
+    { qsort(&Front(), Size(), _itemSize, CompareRecordItems); }
+};
+
+typedef CRecordVector<int> CIntVector;
+typedef CRecordVector<unsigned int> CUIntVector;
+typedef CRecordVector<bool> CBoolVector;
+typedef CRecordVector<unsigned char> CByteVector;
+typedef CRecordVector<void *> CPointerVector;
+
+template <class T>
+class CObjectVector: public CPointerVector
+{
+public:
+  CObjectVector(){};
+  ~CObjectVector() { Clear(); }
+  CObjectVector(const CObjectVector &objectVector)
+    { *this = objectVector; }
+       CObjectVector& operator=(const CObjectVector &objectVector)
+  {
+    Clear();
+    return (*this += objectVector);
+  }
+       CObjectVector& operator+=(const CObjectVector &objectVector)
+  {
+    int size = objectVector.Size();
+    Reserve(Size() + size);
+    for(int i = 0; i < size; i++)
+      Add(objectVector[i]);
+    return *this;
+  }
+       const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
+       T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
+       T& Front() { return operator[](0); }
+       const T& Front() const { return operator[](0); }
+       T& Back() { return operator[](_size - 1); }
+       const T& Back() const { return operator[](_size - 1); }
+       int Add(const T& item)
+    { return CPointerVector::Add(new T(item)); }
+       void Insert(int index, const T& item)
+    { CPointerVector::Insert(index, new T(item)); }
+       virtual void Delete(int index, int num = 1)
+  {
+    TestIndexAndCorrectNum(index, num);
+    for(int i = 0; i < num; i++)
+      delete (T *)(((void **)_items)[index + i]);
+    CPointerVector::Delete(index, num);
+  }
+  int Find(const T& item) const
+  {
+    for(int i = 0; i < Size(); i++)
+      if (item == (*this)[mid])
+        return i;
+      return -1;
+  }
+  int FindInSorted(const T& item) const
+  {
+    int left = 0, right = Size(); 
+    while (left != right)
+    {
+      int mid = (left + right) / 2;
+      const T& midValue = (*this)[mid];
+      if (item == midValue)
+        return mid;
+      if (item < midValue)
+        right = mid;
+      else
+        left = mid + 1;
+    }
+    return -1;
+  }
+  int AddToSorted(const T& item)
+  {
+    int left = 0, right = Size(); 
+    while (left != right)
+    {
+      int mid = (left + right) / 2;
+      const T& midValue = (*this)[mid];
+      if (item == midValue)
+      {
+        right = mid + 1;
+        break;
+      }
+      if (item < midValue)
+        right = mid;
+      else
+        left = mid + 1;
+    }
+    Insert(right, item);
+    return right;
+  }
+  static int __cdecl CompareObjectItems(const void *a1, const void *a2)
+    { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
+  void Sort()
+  {
+    CPointerVector &pointerVector = *this;
+    qsort(&pointerVector[0], Size(), sizeof(void *), CompareObjectItems);
+  }
+};
+
+#endif 
diff --git a/od-win32/7z/win32_decompress.cpp b/od-win32/7z/win32_decompress.cpp
new file mode 100755 (executable)
index 0000000..708e2ac
--- /dev/null
@@ -0,0 +1,76 @@
+ /*
+  * UAE - The Un*x Amiga Emulator
+  *
+  * 7z decompression library support
+  *
+  */
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include <windows.h>
+#include <initguid.h>
+#include <basetyps.h>
+
+#include "config.h"
+#include "options.h"
+#include "zfile.h"
+
+#include "IArchive.h"
+#include "DLL.h"
+#include "MyCom.h"
+#include "FileStreams.h"
+#include "PropVariant.h"
+#include "PropVariantConversions.h"
+#include "StringConvert.h"
+
+typedef UINT32 (WINAPI * CreateObjectFunc)(
+    const GUID *clsID, 
+    const GUID *interfaceID, 
+    void **outObject);
+
+DEFINE_GUID (CLSID_CFormat7z, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
+
+void test7z (void)
+{
+  NWindows::NDLL::CLibrary library;
+  if (!library.Load("7z.dll"))
+  {
+    return;
+  }
+  CreateObjectFunc createObjectFunc = (CreateObjectFunc)library.GetProcAddress("CreateObject");
+  CMyComPtr<IInArchive> archive;
+  if (createObjectFunc(&CLSID_CFormat7z, 
+        &IID_IInArchive, (void **)&archive) != S_OK)
+  {
+    return;
+  }
+
+  CInFileStream *fileSpec = new CInFileStream;
+  CMyComPtr<IInStream> file = fileSpec;
+
+  if (!fileSpec->Open("test.7z"))
+  {
+    return;
+  }
+  if (archive->Open(file, 0, 0) != S_OK)
+    return;
+  UINT32 numItems = 0;
+  archive->GetNumberOfItems(&numItems);  
+  for (UINT32 i = 0; i < numItems; i++)
+  {
+    NWindows::NCOM::CPropVariant propVariant;
+    archive->GetProperty(i, kpidPath, &propVariant);
+    UString s = ConvertPropVariantToString(propVariant);
+    printf("%s\n", (LPCSTR)GetOemString(s));
+  }
+}
+
\ No newline at end of file
index 9425ef85c447a64508ccb52aeccc5633c7c5097f..3203b1c3aed5809aa1060760f508b34f60578705 100755 (executable)
@@ -13,7 +13,6 @@ struct ScreenResolution
 #define MAX_REFRESH_RATES 100
 struct PicassoResolution
 {
-    struct Resolutions *next;
     struct ScreenResolution res;
     int depth;   /* depth in bytes-per-pixel */
     int refresh[MAX_REFRESH_RATES]; /* refresh-rates in Hz */
index 6feafc008612402a2f322350d83b1c46261a68f7..6abb14337ce1b493e90d765f946140ac43764fef 100755 (executable)
 
 #include "sysconfig.h"
 #include "sysdeps.h"
+#include "config.h"
+#include "options.h"
+#include "memory.h"
 
 #include "fsdb.h"
+#include "win32.h"
 #include <windows.h>
 
+#define TRACING_ENABLED 0
+#if TRACING_ENABLED
+#define TRACE(x)       do { write_log x; } while(0)
+#else
+#define TRACE(x)
+#endif
+
 /* these are deadly (but I think allowed on the Amiga): */
 #define NUM_EVILCHARS 7
 static char evilchars[NUM_EVILCHARS] = { '\\', '*', '?', '\"', '<', '>', '|' };
 
+#define UAEFSDB_BEGINS "__uae___"
+#define UAEFSDB_BEGINSX "__uae___*"
+#define UAEFSDB_LEN 604
+
+/* The on-disk format is as follows:
+ * Offset 0, 1 byte, valid
+ * Offset 1, 4 bytes, mode
+ * Offset 5, 257 bytes, aname
+ * Offset 263, 257 bytes, nname
+ * Offset 519, 81 bytes, comment
+ * Offset 600, 4 bytes, Windows-side mode
+ */
+
+static char *make_uaefsdbpath (const char *dir, const char *name)
+{
+    int len;
+    char *p;
+    
+    len = strlen (dir) + 1 + 1;
+    if (name)
+       len += 1 + strlen (name);
+    len += 1 + strlen (FSDB_FILE);
+    p = xmalloc (len);
+    if (!p)
+       return NULL;
+    if (name)
+       sprintf (p, "%s\\%s:%s", dir, name, FSDB_FILE);
+    else
+       sprintf (p, "%s:%s", dir, FSDB_FILE);
+    return p;
+}
+
+static int read_uaefsdb (const char *dir, const char *name, uae_u8 *fsdb)
+{
+    char *p;
+    HANDLE h;
+    DWORD read;
+    
+    p = make_uaefsdbpath (dir, name);
+    h = CreateFile (p, GENERIC_READ, 0,
+       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    xfree (p);
+    if (h != INVALID_HANDLE_VALUE) {
+       ReadFile (h, fsdb, UAEFSDB_LEN, &read, NULL);
+       CloseHandle (h);
+       if (read == UAEFSDB_LEN)
+           return 1;
+    }
+    memset (fsdb, 0, UAEFSDB_LEN);
+    return 0;
+}
+
+static int write_uaefsdb (const char *dir, const char *name, uae_u8 *fsdb)
+{
+    char *p;
+    HANDLE h;
+    DWORD written, attr = INVALID_FILE_ATTRIBUTES;
+    int ret = 0;
+    
+    p = make_uaefsdbpath (dir, name);
+    h = CreateFile (p, GENERIC_WRITE, 0,
+        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (h == INVALID_HANDLE_VALUE && GetLastError () == ERROR_ACCESS_DENIED) {
+       attr = GetFileAttributes (p);
+       if (attr != INVALID_FILE_ATTRIBUTES) {
+           if (attr & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)) {
+               SetFileAttributes (p, attr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN));
+               h = CreateFile (p, GENERIC_WRITE, 0,
+                   NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+           }
+       }
+    }
+    if (h != INVALID_HANDLE_VALUE) {
+       WriteFile (h, fsdb, UAEFSDB_LEN, &written, NULL);
+       CloseHandle (h);
+       if (written == UAEFSDB_LEN) {
+           ret = 1;
+           goto end;
+       }
+    }
+    DeleteFile (p);
+end:
+    if (attr != INVALID_FILE_ATTRIBUTES)
+       SetFileAttributes (p, attr);
+    xfree (p);
+    return ret;
+}
+
+static void create_uaefsdb (a_inode *aino, uae_u8 *buf, int winmode)
+{
+    buf[0] = 1;
+    do_put_mem_long ((uae_u32 *)(buf + 1), aino->amigaos_mode);
+    strncpy (buf + 5, aino->aname, 256);
+    buf[5 + 256] = '\0';
+    strncpy (buf + 5 + 257, nname_begin (aino->nname), 256);
+    buf[5 + 257 + 256] = '\0';
+    strncpy (buf + 5 + 2 * 257, aino->comment ? aino->comment : "", 80);
+    buf[5 + 2 * 257 + 80] = '\0';
+    do_put_mem_long ((uae_u32 *)(buf + 5 + 2 * 257 + 81), winmode); 
+    aino->has_dbentry = 0;
+    aino->dirty = 0;
+}
+
+static a_inode *aino_from_buf (a_inode *base, uae_u8 *buf, int *winmode)
+{
+    uae_u32 mode;
+    a_inode *aino = (a_inode *) xcalloc (sizeof (a_inode), 1);
+
+    mode = do_get_mem_long ((uae_u32 *)(buf + 1));
+    buf += 5;
+    aino->aname = my_strdup (buf);
+    buf += 257;
+    aino->nname = build_nname (base->nname, buf);
+    buf += 257;
+    aino->comment = *buf != '\0' ? my_strdup (buf) : 0;
+    buf += 81;
+    aino->amigaos_mode = mode;
+    *winmode = do_get_mem_long ((uae_u32 *)buf);
+    *winmode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
+    aino->has_dbentry = 0;
+    aino->dirty = 0;
+    aino->db_offset = 0;
+    return aino;
+}
+
 /* Return nonzero for any name we can't create on the native filesystem.  */
 int fsdb_name_invalid (const char *n)
 {
@@ -72,23 +208,41 @@ uae_u32 filesys_parse_mask(uae_u32 mask)
 
 int fsdb_exists (char *nname)
 {
-    if (GetFileAttributes(nname) == 0xFFFFFFFF)
+    if (GetFileAttributes(nname) == INVALID_FILE_ATTRIBUTES)
        return 0;
     return 1;
 }
 
 /* For an a_inode we have newly created based on a filename we found on the
  * native fs, fill in information about this file/directory.  */
-int fsdb_fill_file_attrs (a_inode *aino)
+int fsdb_fill_file_attrs (a_inode *base, a_inode *aino)
 {
-    int mode;
+    int mode, winmode, oldamode;
+    uae_u8 fsdb[UAEFSDB_LEN];
+    int reset = 0;
 
-    if((mode = GetFileAttributes(aino->nname)) == 0xFFFFFFFF) {
-       write_log("GetFileAttributes('%s') failed! error=%d, aino=%p dir=%d\n", aino->nname,GetLastError(),aino,aino->dir);
+    if((mode = GetFileAttributes(aino->nname)) == INVALID_FILE_ATTRIBUTES) {
+       write_log("GetFileAttributes('%s') failed! error=%d, aino=%p dir=%d\n",
+           aino->nname, GetLastError(), aino,aino->dir);
        return 0;
     }
-
     aino->dir = (mode & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
+    mode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
+
+    if ((base->volflags & MYVOLUMEINFO_STREAMS) && read_uaefsdb (aino->nname, NULL, fsdb)) {
+       aino->amigaos_mode = do_get_mem_long ((uae_u32 *)(fsdb + 1));
+       xfree (aino->comment);
+       if (fsdb[5 + 2 * 257])
+           aino->comment = my_strdup (fsdb + 5 + 2 * 257);
+       xfree (aino_from_buf (base, fsdb, &winmode));
+       if (winmode == mode) /* no Windows-side editing? */
+           return 1;
+       write_log ("FS: '%s' protection flags edited from Windows-side\n", aino->nname);
+       reset = 1;
+       /* edited from Windows-side -> use Windows side flags instead */
+    }
+
+    oldamode = aino->amigaos_mode;
     aino->amigaos_mode = A_FIBF_EXECUTE | A_FIBF_READ;
     if (!(FILE_ATTRIBUTE_ARCHIVE & mode))
        aino->amigaos_mode |= A_FIBF_ARCHIVE;
@@ -99,41 +253,49 @@ int fsdb_fill_file_attrs (a_inode *aino)
     if (FILE_ATTRIBUTE_HIDDEN & mode)
        aino->amigaos_mode |= A_FIBF_HIDDEN;
     aino->amigaos_mode = filesys_parse_mask(aino->amigaos_mode);
+    aino->amigaos_mode |= oldamode & A_FIBF_SCRIPT;
+    if (reset) {
+       if (base->volflags & MYVOLUMEINFO_STREAMS) {
+           create_uaefsdb (aino, fsdb, mode);
+           write_uaefsdb (aino->nname, NULL, fsdb);
+       }
+    }
     return 1;
 }
 
-int fsdb_set_file_attrs (a_inode *aino, int mask)
+int fsdb_set_file_attrs (a_inode *aino)
 {
-    struct stat statbuf;
-    uae_u32 mode=0, tmpmask;
+    uae_u32 tmpmask;
+    uae_u8 fsdb[UAEFSDB_LEN];
+    uae_u32 mode;
 
-    tmpmask = filesys_parse_mask(mask);
+    tmpmask = filesys_parse_mask (aino->amigaos_mode);
 
-    if (stat (aino->nname, &statbuf) == -1)
+    mode = GetFileAttributes (aino->nname);
+    if (mode == INVALID_FILE_ATTRIBUTES)
        return ERROR_OBJECT_NOT_AROUND;
+    mode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
 
     /* Unix dirs behave differently than AmigaOS ones.  */
     /* windows dirs go where no dir has gone before...  */
     if (! aino->dir) {
+       mode = 0;
        if ((tmpmask & (A_FIBF_READ | A_FIBF_DELETE)) == 0)
            mode |= FILE_ATTRIBUTE_READONLY;
        if (!(tmpmask & A_FIBF_ARCHIVE))
            mode |= FILE_ATTRIBUTE_ARCHIVE;
-       else
-           mode &= ~FILE_ATTRIBUTE_ARCHIVE;
        if (tmpmask & A_FIBF_PURE)
            mode |= FILE_ATTRIBUTE_SYSTEM;
-       else
-           mode &= ~FILE_ATTRIBUTE_SYSTEM;
        if (tmpmask & A_FIBF_HIDDEN)
            mode |= FILE_ATTRIBUTE_HIDDEN;
-       else
-           mode &= ~FILE_ATTRIBUTE_HIDDEN;
-       SetFileAttributes(aino->nname, mode);
+       SetFileAttributes (aino->nname, mode);
     }
 
-    aino->amigaos_mode = mask;
     aino->dirty = 1;
+    if (aino->volflags & MYVOLUMEINFO_STREAMS) {
+       create_uaefsdb (aino, fsdb, mode);
+       write_uaefsdb (aino->nname, NULL, fsdb);
+    }
     return 0;
 }
 
@@ -163,7 +325,7 @@ int fsdb_mode_representable_p (const a_inode *aino)
 char *fsdb_create_unique_nname (a_inode *base, const char *suggestion)
 {
     char *c;
-    char tmp[256] = "__uae___";
+    char tmp[256] = UAEFSDB_BEGINS;
     int i;
 
     strncat (tmp, suggestion, 240);
@@ -193,6 +355,72 @@ char *fsdb_create_unique_nname (a_inode *base, const char *suggestion)
     }
 }
 
+char *fsdb_search_dir (const char *dirname, char *rel)
+{
+    WIN32_FIND_DATA fd;
+    HANDLE h;
+    char *tmp, *p = 0;
+
+    tmp = build_nname (dirname, rel);
+    h = FindFirstFile (tmp, &fd);
+    if (h != INVALID_HANDLE_VALUE) {
+       if (strcmp (fd.cFileName, rel) == 0)
+           p = rel;
+       else
+           p = my_strdup (fd.cFileName);
+       FindClose (h);
+    }
+    xfree (tmp);
+    return p;
+}
+
+static a_inode *custom_fsdb_lookup_aino (a_inode *base, const char *aname, int offset, int dontcreate)
+{
+    uae_u8 fsdb[UAEFSDB_LEN];
+    char *tmp1;
+    HANDLE h;
+    WIN32_FIND_DATA fd;
+    static a_inode dummy;
+    
+    tmp1 = build_nname (base->nname, UAEFSDB_BEGINSX);
+    if (!tmp1)
+       return NULL;
+    h = FindFirstFile (tmp1, &fd);
+    if (h != INVALID_HANDLE_VALUE) {
+       do {
+           if (read_uaefsdb (base->nname, fd.cFileName, fsdb)) {
+               if (same_aname (fsdb + offset, aname)) {
+                   int winmode;
+                   FindClose (h);
+                   xfree (tmp1);
+                   if (dontcreate)
+                       return &dummy;
+                   return aino_from_buf (base, fsdb, &winmode);
+               }
+           }
+       } while (FindNextFile (h, &fd));
+       FindClose (h);
+    }
+    xfree (tmp1);
+    return NULL;
+}
+
+a_inode *custom_fsdb_lookup_aino_aname (a_inode *base, const char *aname)
+{
+    return custom_fsdb_lookup_aino (base, aname, 5, 0);
+}
+a_inode *custom_fsdb_lookup_aino_nname (a_inode *base, const char *nname)
+{
+    return custom_fsdb_lookup_aino (base, nname, 5 + 257, 0);
+}
+
+int custom_fsdb_used_as_nname (a_inode *base, const char *nname)
+{
+    if (custom_fsdb_lookup_aino (base, nname, 5 + 257, 1))
+       return 1;
+    return 0;
+}
+
 int my_mkdir (const char *name)
 {
     return CreateDirectory (name, NULL) == 0 ? -1 : 0;
@@ -310,6 +538,7 @@ void my_close (void *d)
 {
     struct my_opens *mos = d;
     CloseHandle (mos->h);
+    //write_log ("closehandle %x\n", mos->h);
     xfree (mos);
 }
 
@@ -336,6 +565,26 @@ unsigned int my_write (void *d, void *b, unsigned int size)
     return written;
 }
 
+int my_existsfile (const char *name)
+{
+    HANDLE h = CreateFile (name, GENERIC_READ, FILE_SHARE_READ,
+       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (h == INVALID_HANDLE_VALUE)
+       return 0;
+    CloseHandle (h);
+    return 1;
+}
+
+int my_existsdir (const char *name)
+{
+    DWORD attr = GetFileAttributes (name);
+    if (attr == INVALID_FILE_ATTRIBUTES)
+       return 0;
+    if (attr & FILE_ATTRIBUTE_DIRECTORY)
+       return 1;
+    return 0;
+}
+
 void *my_open (const char *name, int flags)
 {
     struct my_opens *mos;
@@ -344,10 +593,12 @@ void *my_open (const char *name, int flags)
     DWORD ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
     DWORD CreationDisposition = OPEN_EXISTING;
     DWORD FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+    DWORD attr;
     
     mos = xmalloc (sizeof (struct my_opens));
     if (!mos)
        return NULL;
+    attr = GetFileAttributes (name);
     if (flags & O_TRUNC)
        CreationDisposition = CREATE_ALWAYS;
     else if (flags & O_CREAT)
@@ -360,20 +611,25 @@ void *my_open (const char *name, int flags)
     }
     if (flags & O_RDWR)
        DesiredAccess = GENERIC_READ | GENERIC_WRITE;
+    if (CreationDisposition == CREATE_ALWAYS && attr != INVALID_FILE_ATTRIBUTES &&
+       (attr & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
+       SetFileAttributes (name, FILE_ATTRIBUTE_NORMAL);
     h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL);
     if (h == INVALID_HANDLE_VALUE) {
-       if (DesiredAccess & GENERIC_WRITE) {
+       if (GetLastError () == ERROR_ACCESS_DENIED && (DesiredAccess & GENERIC_WRITE)) {
            DesiredAccess &= ~GENERIC_WRITE;
-           CreationDisposition = OPEN_EXISTING;
            h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL);
        }
        if (h == INVALID_HANDLE_VALUE) {
            write_log ("failed to open '%s' %x %x\n", name, DesiredAccess, CreationDisposition);
            xfree (mos);
-           return 0;
+           mos = 0;
+           goto err;
        }
     }
     mos->h = h;
+err:
+    //write_log ("open '%s' = %x\n", name, mos ? mos->h : 0);
     return mos;
 }
 
@@ -403,6 +659,7 @@ int dos_errno (void)
 {
     DWORD e = GetLastError ();
 
+    //write_log ("ec=%d\n", e);
     switch (e) {
      case ERROR_NOT_ENOUGH_MEMORY:
      case ERROR_OUTOFMEMORY:
@@ -439,3 +696,46 @@ int dos_errno (void)
         return ERROR_NOT_IMPLEMENTED;
     }
 }
+
+typedef BOOL (CALLBACK* GETVOLUMEPATHNAME)
+  (LPCTSTR lpszFileName, LPTSTR lpszVolumePathName, DWORD cchBufferLength);
+
+int my_getvolumeinfo (char *root)
+{
+    DWORD last, v, err;
+    int ret = 0;
+    GETVOLUMEPATHNAME pGetVolumePathName;
+    char volume[MAX_DPATH];
+
+    last = SetErrorMode (SEM_FAILCRITICALERRORS);
+    v = GetFileAttributes (root);
+    err = GetLastError ();
+    SetErrorMode (last);
+    if (v == INVALID_FILE_ATTRIBUTES)
+       return -1;
+    if (!(v & FILE_ATTRIBUTE_DIRECTORY))
+       return -1;
+    if (v & FILE_ATTRIBUTE_READONLY)
+       ret |= MYVOLUMEINFO_READONLY;
+    if (!os_winnt)
+       return ret;
+    pGetVolumePathName = (GETVOLUMEPATHNAME)GetProcAddress(
+       GetModuleHandle("kernel32.dll"), "GetVolumePathNameA");
+    if (pGetVolumePathName && pGetVolumePathName (root, volume, sizeof (volume))) {
+       char fsname[MAX_DPATH];
+       DWORD comlen;
+       DWORD flags;
+       if (GetVolumeInformation (volume, NULL, 0, NULL, &comlen, &flags, fsname, sizeof (fsname))) {
+           write_log ("Volume %s FS=%s maxlen=%d flags=%08.8X\n", volume, fsname, comlen, flags);
+           if (flags & FILE_NAMED_STREAMS)
+               ret |= MYVOLUMEINFO_STREAMS;
+       }
+    }
+    return ret;
+}
+
+
+
+
+
+
index 3cb88bfc3cde4c6c2c7979029a3c028e09ec9279..2b62ff74f0b11a102438e2bf5657d52457dd4f9e 100755 (executable)
@@ -261,6 +261,7 @@ static int np[] = { DIK_NUMPAD0, 0, DIK_NUMPADPERIOD, 0, DIK_NUMPAD1, 1, DIK_NUM
 void my_kbd_handler (int keyboard, int scancode, int newstate)
 {
     int code = 0;
+    static int swapperdrive = 0;
 
 //    write_log( "keyboard = %d scancode = 0x%02.2x state = %d\n", keyboard, scancode, newstate ); 
     if (newstate) {
@@ -301,6 +302,34 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                    code = AKS_STATERESTOREDIALOG;
            }
            break;
+           case DIK_1:
+           case DIK_2:
+           case DIK_3:
+           case DIK_4:
+           case DIK_5:
+           case DIK_6:
+           case DIK_7:
+           case DIK_8:
+           case DIK_9:
+           case DIK_0:
+           if (endpressed ()) {
+               int num = scancode - DIK_1;
+               if (shiftpressed ())
+                   num += 10;
+               if (ctrlpressed ()) {
+                   swapperdrive = num;
+                   if (num > 3)
+                       swapperdrive = 0;
+               } else {
+                   int i;
+                   for (i = 0; i < 4; i++) {
+                       if (!strcmp (currprefs.df[i], currprefs.dfxlist[num]))
+                           changed_prefs.df[i][0] = 0;
+                   }
+                   strcpy (changed_prefs.df[swapperdrive], currprefs.dfxlist[num]);
+               }
+           }
+           break;
            case DIK_NUMPAD0:
            case DIK_NUMPAD1:
            case DIK_NUMPAD2:
@@ -345,12 +374,20 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
            case DIK_NEXT:
            break;
            case DIK_NUMPADMINUS:
-           if (endpressed ())
-               code = AKS_VOLDOWN;
+           if (endpressed ()) {
+               if (shiftpressed ())
+                   code = AKS_DECREASEREFRESHRATE;
+               else
+                   code = AKS_VOLDOWN;
+           }
            break;
            case DIK_NUMPADPLUS:
-           if (endpressed ())
-               code = AKS_VOLUP;
+           if (endpressed ()) {
+               if (shiftpressed ())
+                   code = AKS_INCREASEREFRESHRATE;
+               else
+                   code = AKS_VOLUP;
+           }
            break;
            case DIK_NUMPADSTAR:
            if (endpressed ())
index adaf341def2684262513a3c1a182597927326fe6..afb67296a9baae34df2b2f884c2921d8de604aab 100755 (executable)
 #include "win32.h"
 #include "ioport.h"
 #include "parallel.h"
+#include "zfile.h"
+#include "threaddep/thread.h"
+
+#include <Ghostscript/errors.h>
+#include <Ghostscript/iapi.h>
 
-static UINT prttimer;
 static char prtbuf[PRTBUFSIZE];
 static int prtbufbytes,wantwrite;
 static HANDLE hPrt = INVALID_HANDLE_VALUE;
@@ -53,24 +57,172 @@ extern void flushpixels(void);
 void DoSomeWeirdPrintingStuff( char val );
 static int uartbreak;
 
+static uae_thread_id prt_tid;
+static volatile int prt_running;
+static volatile int prt_started;
+static smp_comm_pipe prt_requests;
+
+#ifdef PRINT_DUMP
+static struct zfile *prtdump;
+#endif
+
+static int psmode = 0;
+static HMODULE gsdll;
+static gs_main_instance *gsinstance;
+static int gs_exitcode;
+
+typedef int (CALLBACK* GSAPI_REVISION)(gsapi_revision_t *pr, int len);
+static GSAPI_REVISION ptr_gsapi_revision;
+typedef int (CALLBACK* GSAPI_NEW_INSTANCE)(gs_main_instance **pinstance, void *caller_handle);
+static GSAPI_NEW_INSTANCE ptr_gsapi_new_instance;
+typedef void (CALLBACK* GSAPI_DELETE_INSTANCE)(gs_main_instance *instance);
+static GSAPI_DELETE_INSTANCE ptr_gsapi_delete_instance;
+typedef int (CALLBACK* GSAPI_SET_STDIO)(gs_main_instance *instance,
+    int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len),
+    int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len),
+    int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len));
+static GSAPI_SET_STDIO ptr_gsapi_set_stdio;
+typedef int (CALLBACK* GSAPI_INIT_WITH_ARGS)(gs_main_instance *instance, int argc, char **argv);
+static GSAPI_INIT_WITH_ARGS ptr_gsapi_init_with_args;
+
+typedef int (CALLBACK* GSAPI_EXIT)(gs_main_instance *instance);
+static GSAPI_EXIT ptr_gsapi_exit;
+
+typedef (CALLBACK* GSAPI_RUN_STRING_BEGIN)(gs_main_instance *instance, int user_errors, int *pexit_code);
+static GSAPI_RUN_STRING_BEGIN ptr_gsapi_run_string_begin;
+typedef (CALLBACK* GSAPI_RUN_STRING_CONTINUE)(gs_main_instance *instance, const char *str, unsigned int length, int user_errors, int *pexit_code);
+static GSAPI_RUN_STRING_CONTINUE ptr_gsapi_run_string_continue;
+typedef (CALLBACK* GSAPI_RUN_STRING_END)(gs_main_instance *instance, int user_errors, int *pexit_code);
+static GSAPI_RUN_STRING_END ptr_gsapi_run_string_end;
+
+static uae_u8 **psbuffer;
+static int psbuffers;
+
+static LONG WINAPI ExceptionFilter (struct _EXCEPTION_POINTERS * pExceptionPointers, DWORD ec)
+{
+    return EXCEPTION_EXECUTE_HANDLER;
+}
+
+static void freepsbuffers (void)
+{
+    int i;
+    for (i = 0; i < psbuffers; i++)
+       free (psbuffer[i]);
+    free (psbuffer);
+    psbuffer = NULL;
+    psbuffers = 0;
+}
+
+static int openprinter_ps (void)
+{
+    char *gsargv[] = {
+        "-dNOPAUSE", "-dBATCH", "-dNOPAGEPROMPT", "-dNOPROMPT", "-dQUIET", "-dNoCancel", 
+        "-sDEVICE=mswinpr2", NULL
+    };
+    int gsargc, gsargc2, i;
+    char *tmpparms[100];
+    char tmp[MAX_DPATH];
+
+    if (ptr_gsapi_new_instance (&gsinstance, NULL) < 0)
+        return 0;
+    tmpparms[0] = "WinUAE";
+    gsargc2 = cmdlineparser (currprefs.ghostscript_parameters, tmpparms + 1, 100 - 10) + 1;
+    for (gsargc = 0; gsargv[gsargc]; gsargc++);
+    for (i = 0; i < gsargc; i++)
+       tmpparms[gsargc2++] = gsargv[i];
+    sprintf (tmp, "-sOutputFile=%%printer%%%s", currprefs.prtname);
+    tmpparms[gsargc2++] = tmp;
+    __try {
+       ptr_gsapi_init_with_args (gsinstance, gsargc2, tmpparms);
+       ptr_gsapi_run_string_begin (gsinstance, 0, &gs_exitcode);
+    } __except(ExceptionFilter(GetExceptionInformation(), GetExceptionCode())) {
+       write_log("GS crashed\n");
+       return 0;
+    }
+    psmode = 1;    
+    return 1;
+}
+
+static void *prt_thread (void *p)
+{
+    uae_u8 **buffers = p;
+    int err, cnt, ok;
+
+    ok = 1;
+    prt_running++;
+    prt_started = 1;
+    SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
+    if (load_ghostscript ()) {
+        if (openprinter_ps ()) {
+            write_log ("PostScript printing emulation started..\n");
+           cnt = 0;
+           while (buffers[cnt]) {
+               uae_u8 *p = buffers[cnt];
+               err = ptr_gsapi_run_string_continue (gsinstance, p + 2, (p[0] << 8) | p[1], 0, &gs_exitcode);
+               if (err != e_NeedInput && err <= e_Fatal) {
+                   ptr_gsapi_exit (gsinstance);
+                   write_log ("PostScript parsing failed.\n");
+                   ok = 0;
+                   break;
+               }
+               cnt++;
+           }
+           cnt = 0;
+           while (buffers[cnt]) {
+               free (buffers[cnt]);
+               cnt++;
+           }
+           free (buffers);
+           if (ok) {
+               write_log ("PostScript printing emulation finished..\n");
+               ptr_gsapi_run_string_end (gsinstance, 0, &gs_exitcode);
+           }
+       } else {
+           write_log ("gsdll32.dll failed to initialize\n");
+       }
+    } else {
+       write_log ("gsdll32.dll failed to load\n");
+    }
+    unload_ghostscript ();
+    prt_running--;
+    return 0;
+}
+
+
+
 static void flushprtbuf (void)
 {
     DWORD written = 0;
 
-    if (hPrt != INVALID_HANDLE_VALUE)
-    {
-       if( WritePrinter( hPrt, prtbuf, prtbufbytes, &written ) )
-       {
+    if (!prtbufbytes)
+       return;
+
+#ifdef PRINT_DUMP
+    if (prtdump)
+       zfile_fwrite (prtbuf, prtbufbytes, 1, prtdump);
+#endif
+
+    if (currprefs.parallel_postscript_emulation) {
+       if (psmode) {
+           uae_u8 *p;
+           psbuffer = realloc (psbuffer, (psbuffers + 2) * sizeof (uae_u8*));
+           p = malloc (prtbufbytes + 2);
+           p[0] = prtbufbytes >> 8;
+           p[1] = prtbufbytes;
+           memcpy (p + 2, prtbuf, prtbufbytes);
+           psbuffer[psbuffers++] = p;
+           psbuffer[psbuffers] = NULL;
+       }
+       prtbufbytes = 0;
+       return;
+    } else if (hPrt != INVALID_HANDLE_VALUE) {
+       if( WritePrinter( hPrt, prtbuf, prtbufbytes, &written ) ) {
            if( written != prtbufbytes )
                write_log( "PRINTER: Only wrote %d of %d bytes!\n", written, prtbufbytes );
-       }
-       else
-       {
+       } else {
            write_log( "PRINTER: Couldn't write data!\n" );
        }
-    }
-    else
-    {
+    } else {
        write_log( "PRINTER: Not open!\n" );
     }
     prtbufbytes = 0;
@@ -80,19 +232,53 @@ void finishjob (void)
 {
     flushprtbuf ();
 }
-static void DoSomeWeirdPrintingStuff( char val )
+
+static void DoSomeWeirdPrintingStuff (char val)
 {
-       //if (prttimer)
-       //KillTimer (hAmigaWnd, prttimer);
+    static char prev[4];
+    static uae_u8 one = 1;
+    static uae_u8 three = 3;
+
+    memmove (prev, prev + 1, 3);
+    prev[3] = val;
+    if (currprefs.parallel_postscript_detection) {
+       if (psmode && val == 4) {
+           flushprtbuf ();
+           *prtbuf = val;
+           prtbufbytes = 1;
+           flushprtbuf ();
+           write_log ("PostScript end detected..\n");
+           if (currprefs.parallel_postscript_emulation) {
+               prt_started = 0;
+               if (uae_start_thread (prt_thread, psbuffer, &prt_tid)) {
+                   while (!prt_started)
+                       Sleep (5);
+                   psbuffers = 0;
+                   psbuffer = NULL;
+               }
+           } else {
+               closeprinter ();
+           }
+           freepsbuffers ();
+           return;
+       } else if (!psmode && !stricmp (prev, "%!PS")) {
+           psmode = 1;
+           psbuffer = malloc (sizeof (uae_u8*));
+           psbuffer[0] = 0;
+           psbuffers = 0;
+           strcpy (prtbuf, "%!PS\n");
+           prtbufbytes = strlen (prtbuf);
+           flushprtbuf ();
+           write_log ("PostScript start detected..\n");
+           return;
+       }
+    }
     if (prtbufbytes < PRTBUFSIZE) {
        prtbuf[prtbufbytes++] = val;
-       //prttimer = SetTimer (hAmigaWnd, 1, 2000, NULL);
     } else {
        flushprtbuf ();
        *prtbuf = val;
        prtbufbytes = 1;
-       prttimer = 0;
     }
 }
 
@@ -114,74 +300,152 @@ int isprinteropen (void)
     return 0;
 }
 
+int load_ghostscript (void)
+{
+    struct gsapi_revision_s r;
+    char path[MAX_DPATH];
+
+    if (gsdll)
+       return 1;
+    gsdll = LoadLibrary ("gsdll32.dll");
+    if (!gsdll) {
+       if (GetEnvironmentVariable ("GS_DLL", path, sizeof (path)))
+           gsdll = LoadLibrary (path);
+    }
+    if (!gsdll) {
+       HKEY key;
+       if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\AFPL Ghostscript", 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS) {
+           int idx = 0;
+           char tmp1[MAX_DPATH];
+           for (;;) {
+               DWORD size1 = sizeof (tmp1);
+               FILETIME ft;
+               if (RegEnumKeyEx (key, idx, tmp1, &size1, NULL, NULL, NULL, &ft) == ERROR_SUCCESS) {
+                   HKEY key2;
+                   if (RegOpenKeyEx (key, tmp1, 0, KEY_ALL_ACCESS, &key2) == ERROR_SUCCESS) {
+                       DWORD type = REG_SZ;
+                       DWORD size = sizeof (path);
+                       if (RegQueryValueEx (key2, "GS_DLL", 0, &type, (LPBYTE)path, &size) == ERROR_SUCCESS)
+                           gsdll = LoadLibrary (path);
+                       RegCloseKey (key2);
+                       if (gsdll)
+                           break;
+                   }
+               }
+               idx++;
+           }
+           RegCloseKey (key);
+       }
+    }
+    if (!gsdll)
+       return 0;
+    ptr_gsapi_revision = (GSAPI_REVISION)GetProcAddress (gsdll, "gsapi_revision");
+    if (!ptr_gsapi_revision) {
+       unload_ghostscript ();
+        return -1;
+    }
+    if (ptr_gsapi_revision(&r, sizeof(r))) {
+       unload_ghostscript ();
+       return -2;
+    }
+    ptr_gsapi_new_instance = (GSAPI_NEW_INSTANCE)GetProcAddress (gsdll, "gsapi_new_instance");
+    ptr_gsapi_delete_instance = (GSAPI_DELETE_INSTANCE)GetProcAddress (gsdll, "gsapi_delete_instance");
+    ptr_gsapi_set_stdio = (GSAPI_SET_STDIO)GetProcAddress (gsdll, "gsapi_set_stdio");
+    ptr_gsapi_exit = (GSAPI_EXIT)GetProcAddress (gsdll, "gsapi_exit");
+    ptr_gsapi_run_string_begin = (GSAPI_RUN_STRING_BEGIN)GetProcAddress (gsdll, "gsapi_run_string_begin");
+    ptr_gsapi_run_string_continue = (GSAPI_RUN_STRING_CONTINUE)GetProcAddress (gsdll, "gsapi_run_string_continue");
+    ptr_gsapi_run_string_end = (GSAPI_RUN_STRING_END)GetProcAddress (gsdll, "gsapi_run_string_end");
+    ptr_gsapi_init_with_args = (GSAPI_INIT_WITH_ARGS)GetProcAddress (gsdll, "gsapi_init_with_args");
+    if (!ptr_gsapi_new_instance || !ptr_gsapi_delete_instance || !ptr_gsapi_exit ||
+       !ptr_gsapi_run_string_begin || !ptr_gsapi_run_string_continue || !ptr_gsapi_run_string_end ||
+       !ptr_gsapi_init_with_args) {
+       unload_ghostscript ();
+       return -3;
+    }
+    write_log ("gsdll32.dll: %s rev %d initialized\n", r.product, r.revision);
+    return 1;
+}
+
+void unload_ghostscript (void)
+{
+    if (gsinstance) {
+        ptr_gsapi_exit (gsinstance);
+        ptr_gsapi_delete_instance (gsinstance);
+    }
+    gsinstance = NULL;
+    if (gsdll)
+        FreeLibrary (gsdll);
+    gsdll = NULL;
+    psmode = 0;
+}
+
 void openprinter( void )
 {
     DOC_INFO_1 DocInfo;
-
+    static int first;
+    
     closeprinter ();
     if (!strcasecmp(currprefs.prtname,"none"))
        return;
-    if( ( hPrt == INVALID_HANDLE_VALUE ) && *currprefs.prtname)
-    {
-       if( OpenPrinter(currprefs.prtname, &hPrt, NULL ) )
-       {
+#ifdef PRINT_DUMP
+    prtdump = zfile_fopen ("c:\\prtdump.dat", "wb");
+#endif
+
+    if (currprefs.parallel_postscript_emulation) {
+       prtopen = 1;
+       return;
+    } else if (hPrt == INVALID_HANDLE_VALUE) {
+       if( OpenPrinter(currprefs.prtname, &hPrt, NULL ) ) {
            // Fill in the structure with info about this "document."
            DocInfo.pDocName = "My Document";
            DocInfo.pOutputFile = NULL;
            DocInfo.pDatatype = "RAW";
            // Inform the spooler the document is beginning.
-           if( (dwJob = StartDocPrinter( hPrt, 1, (LPSTR)&DocInfo )) == 0 )
-           {
+           if( (dwJob = StartDocPrinter( hPrt, 1, (LPSTR)&DocInfo )) == 0 ) {
                ClosePrinter( hPrt );
                hPrt = INVALID_HANDLE_VALUE;
-           }
-           else if( StartPagePrinter( hPrt ) )
-           {
+           } else if( StartPagePrinter( hPrt ) ) {
                prtopen = 1;
            }
-       }
-       else
-       {
+       } else {
            hPrt = INVALID_HANDLE_VALUE; // Stupid bug in Win32, where OpenPrinter fails, but hPrt ends up being zero
        }
     }
-    if( hPrt != INVALID_HANDLE_VALUE )
-    {
+    if( hPrt != INVALID_HANDLE_VALUE ) {
        write_log( "PRINTER: Opening printer \"%s\" with handle 0x%x.\n", currprefs.prtname, hPrt );
-    }
-    else if( *currprefs.prtname )
-    {
+    } else if( *currprefs.prtname ) {
        write_log( "PRINTER: ERROR - Couldn't open printer \"%s\" for output.\n", currprefs.prtname );
     }
 }
 
 void flushprinter (void)
 {
-    if (hPrt != INVALID_HANDLE_VALUE) {
-        SetJob(
-           hPrt,  // handle to printer object
-           dwJob,      // print job identifier
-           0,      // information level
-           0,     // job information buffer
-           5     // job command value
-       );
-       closeprinter();
-    }
+    closeprinter();
 }
 
 void closeprinter( void )
 {
-    if( hPrt != INVALID_HANDLE_VALUE )
-    {
-       EndPagePrinter( hPrt );
-       EndDocPrinter( hPrt );
-       ClosePrinter( hPrt );
+#ifdef PRINT_DUMP
+    zfile_fclose (prtdump);
+#endif
+    psmode = 0;
+    if (hPrt != INVALID_HANDLE_VALUE) {
+       EndPagePrinter (hPrt);
+       EndDocPrinter (hPrt);
+       ClosePrinter (hPrt);
        hPrt = INVALID_HANDLE_VALUE;
-       write_log( "PRINTER: Closing printer.\n" );
+       write_log ("PRINTER: Closing printer.\n");
+    }
+    if (currprefs.parallel_postscript_emulation)
+       prtopen = 1;
+    else
+       prtopen = 0;
+    if (prt_running) {
+       write_log ("waiting for printing to finish...\n");
+       while (prt_running)
+           Sleep (10);
     }
-    //KillTimer( hAmigaWnd, prttimer );
-    prttimer = 0;
-    prtopen = 0;
+    freepsbuffers ();
 }
 
 static void putprinter (char val)
@@ -528,10 +792,7 @@ void hsyncstuff(void)
     keycheck++;
     if(keycheck==1000)
     {
-       if (prtbufbytes)
-       {
-           flushprtbuf ();
-       } 
+        flushprtbuf ();
        {
            extern flashscreen;
            int DX_Fill( int , int , int, int, uae_u32 , enum RGBFTYPE  );
index 86a743c69be84fd0026ae1f31b02fef8cf919a27..cee1bf6be1216bcb39c18a22f4ce8eb9721eda08 100755 (executable)
@@ -29,3 +29,6 @@ void serialuartbreak (int);
 #define TIOCM_DTR 8
 #define TIOCM_RTS 16
 #define TIOCM_CTS 32
+
+extern void unload_ghostscript (void);
+extern int load_ghostscript (void);
index 9335aebf3af286f365a36d4a2a8f5798fa62e955..90b633394a84f8d53050d398f9734457736c9054 100755 (executable)
@@ -89,22 +89,6 @@ static DWORD getattr(const char *name, LPFILETIME lpft, size_t *size)
     return fd.dwFileAttributes;
 }
 
-int isspecialdrive(const char *name)
-{
-    int v, err;
-    DWORD last = SetErrorMode (SEM_FAILCRITICALERRORS);
-    v = GetFileAttributes(name);
-    err = GetLastError ();
-    SetErrorMode (last);
-    if (v != INVALID_FILE_ATTRIBUTES)
-       return 0;
-    if (err == ERROR_NOT_READY)
-       return 1;
-    if (err)
-       return -1;
-    return 0;
-}
-
 int posixemu_stat(const char *name, struct stat *statbuf)
 {
     DWORD attr;
index 0ac34d079dd5e216c04759e53d3c411318c9dccf..2ac4300347b5d55059effa5ed2be4bb9905a3166 100755 (executable)
 #define IDC_FASTMEM                     1027
 #define IDC_SHOWLEDS                    1027
 #define IDC_PORT1_JOYS                  1027
+#define IDC_PRINTERLIST2                1028
 #define IDC_SLOWMEM                     1030
 #define IDC_PARALLEL                    1033
 #define IDC_JULIAN                      1040
 #define IDC_PORT1                       1313
 #define IDC_MIDIFRAME                   1314
 #define IDC_SERPARFRAME                 1315
+#define IDC_SERIALFRAME                 1316
 #define IDC_EDIT                        1334
 #define IDC_REMOVE                      1335
 #define IDC_VOLUMELIST                  1336
 #define IDC_T5                          1555
 #define IDC_SERIAL_DIRECT               1555
 #define IDC_T6                          1556
+#define IDC_PSPRINTER                   1556
 #define IDC_T7                          1557
+#define IDC_PSPRINTERDETECT             1557
 #define IDC_T8                          1558
 #define IDC_T9                          1559
 #define IDC_T10                         1560
 #define IDC_FILTERHOV                   1694
 #define IDC_CONFIGLINK                  1694
 #define IDC_FILTERVZV                   1695
+#define IDC_PS_PARAMS                   1695
 #define IDC_FILTERHZV                   1696
 #define ID__FLOPPYDRIVES                40004
 #define ID_FLOPPYDRIVES_DF0             40005
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        245
 #define _APS_NEXT_COMMAND_VALUE         40021
-#define _APS_NEXT_CONTROL_VALUE         1695
+#define _APS_NEXT_CONTROL_VALUE         1696
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
index d19ebacc4b688edf800022683b905c7a37df8f0c..2e54d4780ab858115e934cb327fc9b258dafe181 100755 (executable)
@@ -57,7 +57,7 @@ BEGIN
                     CBS_SORT | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_CARTCHOOSER,280,90,10,15
     RTEXT           "Flash RAM File:",IDC_FLASHTEXT,8,112,75,10
-    EDITTEXT        IDC_FLASHFILE,89,110,185,15,ES_AUTOHSCROLL
+    EDITTEXT        IDC_FLASHFILE,89,110,185,13,ES_AUTOHSCROLL
     PUSHBUTTON      "...",IDC_FLASHCHOOSER,280,110,10,15
 END
 
@@ -285,14 +285,12 @@ FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
     CONTROL         "List1",IDC_VOLUMELIST,"SysListView32",LVS_REPORT | 
                     LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | 
-                    LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,5,260,185
-    PUSHBUTTON      "",IDC_UP,270,52,25,15,BS_ICON
-    PUSHBUTTON      "",IDC_DOWN,270,132,25,15,BS_ICON
+                    LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,5,290,185
     PUSHBUTTON      "Add &Directory...",IDC_NEW_FS,5,196,60,15
     PUSHBUTTON      "Add &Hardfile...",IDC_NEW_HF,70,196,60,15
     PUSHBUTTON      "Add Ha&rddrive...",IDC_NEW_HD,135,196,60,15
-    PUSHBUTTON      "Remove",IDC_REMOVE,135,218,60,15
-    PUSHBUTTON      "&Properties",IDC_EDIT,200,218,60,15
+    PUSHBUTTON      "Remove",IDC_REMOVE,235,196,60,15
+    PUSHBUTTON      "&Properties",IDC_EDIT,235,217,60,15
     CONTROL         "Add PC Drives at Startup",IDC_MAPDRIVES,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,5,216,105,10,0,
                     HIDC_MAPDRIVES
@@ -396,60 +394,67 @@ BEGIN
     PUSHBUTTON      "Delete",IDC_DELETE,255,225,40,15
 END
 
-IDD_PORTS DIALOGEX 0, 0, 300, 194
+IDD_PORTS DIALOGEX 0, 0, 300, 242
 STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
-    GROUPBOX        "Serial and Parallel",IDC_SERPARFRAME,4,2,291,46
-    RTEXT           "Serial:",IDC_STATIC,20,15,25,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_SERIAL,50,15,95,65,CBS_DROPDOWNLIST | WS_VSCROLL | 
+    GROUPBOX        "Parallel Port",IDC_SERPARFRAME,5,2,291,68
+    COMBOBOX        IDC_SERIAL,19,83,95,65,CBS_DROPDOWNLIST | WS_VSCROLL | 
                     WS_TABSTOP
     CONTROL         "Shared",IDC_SHARED,"Button",BS_AUTOCHECKBOX | 
-                    BS_VCENTER | WS_TABSTOP,33,32,37,12
+                    BS_VCENTER | WS_TABSTOP,132,83,48,13
     CONTROL         "RTS/CTS",IDC_SER_CTSRTS,"Button",BS_AUTOCHECKBOX | 
-                    BS_VCENTER | WS_TABSTOP,77,32,44,12
+                    BS_VCENTER | WS_TABSTOP,185,83,53,12
     CONTROL         "Direct",IDC_SERIAL_DIRECT,"Button",BS_AUTOCHECKBOX | 
-                    BS_VCENTER | WS_TABSTOP,128,32,40,12
-    RTEXT           "Printer:",IDC_STATIC,155,15,25,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_PRINTERLIST,185,15,95,134,CBS_DROPDOWNLIST | 
+                    BS_VCENTER | WS_TABSTOP,243,83,46,12
+    RTEXT           "Printer:",IDC_STATIC,15,15,25,15,SS_CENTERIMAGE
+    COMBOBOX        IDC_PRINTERLIST,49,15,153,134,CBS_DROPDOWNLIST | 
                     WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Flush print job",IDC_FLUSHPRINTER,199,31,58,12
-    GROUPBOX        "MIDI",IDC_MIDIFRAME,4,50,292,36
-    RTEXT           "Out:",IDC_MIDI,10,64,34,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_MIDIOUTLIST,50,64,95,130,CBS_DROPDOWNLIST | 
+    PUSHBUTTON      "Flush print job",IDC_FLUSHPRINTER,220,14,58,12
+    GROUPBOX        "MIDI",IDC_MIDIFRAME,4,104,292,33
+    RTEXT           "Out:",IDC_MIDI,10,115,34,15,SS_CENTERIMAGE
+    COMBOBOX        IDC_MIDIOUTLIST,50,115,95,130,CBS_DROPDOWNLIST | 
                     WS_VSCROLL | WS_TABSTOP
-    RTEXT           "In:",IDC_MIDI2,150,64,29,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_MIDIINLIST,185,64,95,134,CBS_DROPDOWNLIST | 
+    RTEXT           "In:",IDC_MIDI2,150,115,29,15,SS_CENTERIMAGE
+    COMBOBOX        IDC_MIDIINLIST,185,115,95,134,CBS_DROPDOWNLIST | 
                     WS_VSCROLL | WS_TABSTOP
-    GROUPBOX        "Amiga Mouse/Joystick Port 0",IDC_PORT0,4,92,141,78
+    GROUPBOX        "Amiga Mouse/Joystick Port 0",IDC_PORT0,4,141,141,78
     CONTROL         "",IDC_PORT0_JOYSC,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP | WS_TABSTOP,10,107,9,11
+                    WS_GROUP | WS_TABSTOP,10,156,9,11
     CONTROL         "Keyboard Layout ""A"" []Numeric keypad, 0 and 5 = fire",
                     IDC_PORT0_KBDA,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
-                    10,127,90,10
+                    10,176,90,10
     CONTROL         "Keyboard Layout ""B"" []Cursor keys, right CTRL and ALT = fire",
                     IDC_PORT0_KBDB,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
-                    10,142,90,10
+                    10,191,90,10
     CONTROL         "Keyboard Layout ""C"" []T = up, B = down, F = left, H = right, left ALT = fire",
                     IDC_PORT0_KBDC,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
-                    10,156,90,10
-    COMBOBOX        IDC_PORT0_JOYS,23,106,117,130,CBS_DROPDOWNLIST | 
+                    10,205,90,10
+    COMBOBOX        IDC_PORT0_JOYS,23,155,117,130,CBS_DROPDOWNLIST | 
                     WS_VSCROLL | WS_TABSTOP
-    GROUPBOX        "Amiga Joystick/Mouse Port 1",IDC_PORT1,150,92,146,78
+    GROUPBOX        "Amiga Joystick/Mouse Port 1",IDC_PORT1,150,141,146,78
     CONTROL         "",IDC_PORT1_JOYSC,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP | WS_TABSTOP,155,107,9,11
+                    WS_GROUP | WS_TABSTOP,155,156,9,11
     CONTROL         "Keyboard Layout ""A"" []Numeric keypad, 0 and 5 = fire",
                     IDC_PORT1_KBDA,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
-                    155,127,90,10
+                    155,176,90,10
     CONTROL         "Keyboard Layout ""B"" []Cursor keys, right CTRL and ALT = fire",
                     IDC_PORT1_KBDB,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
-                    155,142,90,10
+                    155,191,90,10
     CONTROL         "Keyboard Layout ""C"" []T = up, B = down, F = left, H = right, left ALT = fire",
                     IDC_PORT1_KBDC,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
-                    155,156,90,10
-    COMBOBOX        IDC_PORT1_JOYS,168,106,123,130,CBS_DROPDOWNLIST | 
+                    155,205,90,10
+    COMBOBOX        IDC_PORT1_JOYS,168,155,123,130,CBS_DROPDOWNLIST | 
                     WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Swap ports",IDC_SWAP,119,176,54,14
+    PUSHBUTTON      "Swap ports",IDC_SWAP,119,225,54,14
+    CONTROL         "PostScript printer emulation",IDC_PSPRINTER,"Button",
+                    BS_AUTOCHECKBOX | BS_VCENTER | WS_TABSTOP,18,32,103,12
+    CONTROL         "PostScript detection",IDC_PSPRINTERDETECT,"Button",
+                    BS_AUTOCHECKBOX | BS_VCENTER | WS_TABSTOP,122,32,103,12
+    EDITTEXT        IDC_PS_PARAMS,121,50,165,12,ES_AUTOHSCROLL
+    GROUPBOX        "Serial Port",IDC_SERIALFRAME,4,72,292,29
+    RTEXT           "Ghostscript extra parameters:",IDC_STATIC,15,49,91,15,
+                    SS_CENTERIMAGE
 END
 
 IDD_CONTRIBUTORS DIALOGEX 0, 0, 411, 242
@@ -846,10 +851,8 @@ FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
     CONTROL         "",IDC_DISKLIST,"SysListView32",LVS_REPORT | 
                     LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | 
-                    LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,4,6,262,211
-    PUSHBUTTON      "",IDC_UP,270,66,25,15,BS_ICON
-    PUSHBUTTON      "",IDC_DOWN,270,146,25,15,BS_ICON
-    PUSHBUTTON      "Remove disk image",IDC_DISKLISTREMOVE,94,223,93,15
+                    LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,4,6,292,211
+    PUSHBUTTON      "Remove disk image",IDC_DISKLISTREMOVE,98,223,93,15
 END
 
 IDD_PANEL DIALOGEX 0, 0, 420, 278
@@ -1016,8 +1019,8 @@ IDI_PATHS               ICON                    "paths.ico"
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,9,91,0
- PRODUCTVERSION 0,9,91,0
+ FILEVERSION 0,9,92,0
+ PRODUCTVERSION 0,9,92,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -1033,12 +1036,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "WinUAE"
-            VALUE "FileVersion", "0.9.91"
+            VALUE "FileVersion", "0.9.92"
             VALUE "InternalName", "WinUAE"
             VALUE "LegalCopyright", "© 1996-2004 under the GNU Public License (GPL)"
             VALUE "OriginalFilename", "WinUAE.exe"
             VALUE "ProductName", "WinUAE"
-            VALUE "ProductVersion", "0.9.91"
+            VALUE "ProductVersion", "0.9.92"
         END
     END
     BLOCK "VarFileInfo"
index eb8ee58a98b542d87a3e3e0affdbd2e00d2749c6..fdb770e630614ea4b7eae66d0d71c98cf5a55910 100755 (executable)
@@ -84,7 +84,7 @@ void update_sound (int freq)
        freq = lastfreq;
     lastfreq = freq;
     if (have_sound) {
-       if (currprefs.gfx_vsync && currprefs.gfx_afullscreen) {
+       if ((currprefs.gfx_vsync && currprefs.gfx_afullscreen) || currprefs.chipset_refreshrate) {
            if (currprefs.ntscmode)
                scaled_sample_evtime_orig = (unsigned long)(MAXHPOS_NTSC * MAXVPOS_NTSC * freq * CYCLE_UNIT + obtainedfreq - 1) / obtainedfreq;
            else
@@ -249,7 +249,6 @@ static int open_audio_ds (int size)
     DSCAPS DSCaps;
     DSBCAPS DSBCaps;
     WAVEFORMATEX wavfmt;
-    int minfreq, maxfreq;
     int freq = currprefs.sound_freq;
     
     enumerate_sound_devices (0);
@@ -280,10 +279,10 @@ static int open_audio_ds (int size)
     if (DSCaps.dwFlags & DSCAPS_EMULDRIVER) {
        write_log ("SOUND: Emulated DirectSound driver detected, don't complain if sound quality is crap :)\n");
     }
-    minfreq = DSCaps.dwMinSecondarySampleRate;
-    maxfreq = DSCaps.dwMaxSecondarySampleRate;
-    if (maxfreq > 11000) {
-       if (minfreq > freq && minfreq < 22050) {
+    if (DSCaps.dwFlags & DSCAPS_CONTINUOUSRATE) {
+       int minfreq = DSCaps.dwMinSecondarySampleRate;
+       int maxfreq = DSCaps.dwMaxSecondarySampleRate;
+       if (minfreq > freq) {
            freq = minfreq;
            changed_prefs.sound_freq = currprefs.sound_freq = freq;
            write_log("SOUND: minimum supported frequency: %d\n", minfreq);
@@ -293,8 +292,6 @@ static int open_audio_ds (int size)
            changed_prefs.sound_freq = currprefs.sound_freq = freq;
            write_log("SOUND: maximum supported frequency: %d\n", maxfreq);
        }
-    } else {
-       write_log("SOUND: ignored weird min (%d) or max (%d) sample rate\n", minfreq, maxfreq);
     }
     filter_mul1 = exp (-FILTER_FREQUENCY / freq);
     filter_mul2 = 1 - filter_mul1;
@@ -480,11 +477,12 @@ void sound_setadjust (double v)
     if ((currprefs.gfx_vsync && currprefs.gfx_afullscreen) || (avioutput_audio && !compiled_code)) {
        vsynctime = vsynctime_orig;
        scaled_sample_evtime = (long)(((double)scaled_sample_evtime_orig) * mult / 1000.0);
-    } else if (compiled_code) {
+    } else if (compiled_code || currprefs.m68k_speed != 0) {
        vsynctime = (long)(((double)vsynctime_orig) * mult / 1000.0);
        scaled_sample_evtime = scaled_sample_evtime_orig;
-    } else
+    } else {
        vsynctime = vsynctime_orig * 9 / 10;
+    }
 }
 
 static void finish_sound_buffer_ds (void)
index 0095f14f010cc623a76d86afa6f608d470be73f5..9d0a159d1d53e675ff3f0bd6193f3bcd474a1a10 100755 (executable)
@@ -96,7 +96,7 @@ COLORREF g_dwBackgroundColor  = RGB(10, 0, 10);
 
 static int emulation_paused;
 static int activatemouse = 1;
-static int ignore_messages_all;
+int ignore_messages_all;
 int pause_emulation;
 
 static int didmousepos;
@@ -588,7 +588,9 @@ static long FAR PASCAL AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam,
     {
     case WM_SIZE:
     {
+#if 0
        write_log ("WM_SIZE %d %d\n", wParam, minimized);
+#endif
        if (isfullscreen ()) {
            v = minimized;
            switch (wParam)
@@ -616,7 +618,9 @@ static long FAR PASCAL AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam,
     }
            
     case WM_ACTIVATE:
+#if 0
        write_log ("WM_ACTIVE %d %d %d\n", HIWORD (wParam), LOWORD (wParam), minimized);
+#endif
        if (!isfullscreen ()) {
            minimized = HIWORD (wParam);
            if (LOWORD (wParam) != WA_INACTIVE) {
@@ -638,7 +642,9 @@ static long FAR PASCAL AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam,
        break;
 
     case WM_ACTIVATEAPP:
+#if 0
        write_log ("WM_ACTIVATEAPP %d %d\n", wParam, minimized);
+#endif
        if (!wParam) {
            setmouseactive (0);
            if (normal_display_change_starting == 0)
@@ -1139,7 +1145,7 @@ int WIN32_RegisterClasses( void )
     wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_OWNDC;
     wc.lpfnWndProc = AmigaWindowProc;
     wc.cbClsExtra = 0;
-    wc.cbWndExtra = 0;
+    wc.cbWndExtra = DLGWINDOWEXTRA;
     wc.hInstance = 0;
     wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON));
     wc.hCursor = LoadCursor (NULL, IDC_ARROW);
@@ -1152,7 +1158,7 @@ int WIN32_RegisterClasses( void )
     wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
     wc.lpfnWndProc = MainWindowProc;
     wc.cbClsExtra = 0;
-    wc.cbWndExtra = 0;
+    wc.cbWndExtra = DLGWINDOWEXTRA;
     wc.hInstance = 0;
     wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON));
     wc.hCursor = LoadCursor (NULL, IDC_ARROW);
@@ -1165,7 +1171,7 @@ int WIN32_RegisterClasses( void )
     wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW;
     wc.lpfnWndProc = HiddenWindowProc;
     wc.cbClsExtra = 0;
-    wc.cbWndExtra = 0;
+    wc.cbWndExtra = DLGWINDOWEXTRA;
     wc.hInstance = 0;
     wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON));
     wc.hCursor = LoadCursor (NULL, IDC_ARROW);
@@ -1975,9 +1981,7 @@ static void WIN32_HandleRegistryStuff( void )
                    
            if( MessageBox( NULL, szMessage, szTitle, MB_YESNO | MB_ICONWARNING | MB_TASKMODAL | MB_SETFOREGROUND ) == IDYES )
            {
-               ignore_messages_all++;
                colortype = WIN32GFX_FigurePixelFormats(0);
-               ignore_messages_all--;
                RegSetValueEx( hWinUAEKey, "DisplayInfo", 0, REG_DWORD, (CONST BYTE *)&colortype, sizeof( colortype ) );
            }
        }
@@ -2120,7 +2124,6 @@ static int osdetect (void)
     os_winnt_admin = isadminpriv ();
     return 1;
 }
-
 static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
                    int nCmdShow)
 {
@@ -2249,7 +2252,6 @@ __asm{
 #endif
 #ifdef PARALLEL_PORT
     paraport_free ();
-    flushprinter ();
     closeprinter ();
 #endif
     WIN32_CleanupLibraries();
index b43fbfb68d4f2aa8758f63f516c3fd0568eea323..b2b2d95ab5d693bf13606734f154cb240c49abbe 100755 (executable)
@@ -20,8 +20,9 @@ extern int in_sizemove;
 extern int manual_painting_needed;
 extern int manual_palette_refresh_needed;
 extern int mouseactive, focus;
-#define WINUAEBETA 0
-#define WINUAEBETASTR ""
+extern int ignore_messages_all;
+#define WINUAEBETA 1
+#define WINUAEBETASTR " Beta 1"
 
 extern void my_kbd_handler (int, int, int);
 extern void clearallkeys(void);
diff --git a/od-win32/win32_decompress.c b/od-win32/win32_decompress.c
new file mode 100755 (executable)
index 0000000..5ea42bc
--- /dev/null
@@ -0,0 +1,72 @@
+ /*
+  * UAE - The Un*x Amiga Emulator
+  *
+  * 7z decompression library support
+  *
+  */
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include <windows.h>
+#include <initguid.h>
+#include <basetyps.h>
+
+#include "config.h"
+#include "options.h"
+#include "zfile.h"
+
+typedef UINT32 (WINAPI * CreateObjectFunc)(
+    const GUID *clsID, 
+    const GUID *interfaceID, 
+    void **outObject);
+
+DEFINE_GUID (IID_IInArchive, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00);
+DEFINE_GUID (CLSID_CFormat7z, 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
+
+STDMETHOD(Open)(IInStream *stream, const UINT64 *maxCheckStartPosition,
+    IArchiveOpenCallback *openArchiveCallback) PURE;  
+STDMETHOD(Close)(void) PURE;  
+STDMETHOD(GetNumberOfItems)(UINT32 *numItems) PURE;  
+STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value) PURE;
+STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems, 
+    INT32 testMode, IArchiveExtractCallback *extractCallback) PURE;
+STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE;
+STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE;  
+STDMETHOD(GetPropertyInfo)(UINT32 index,     
+    BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties) PURE;  
+STDMETHOD(GetArchivePropertyInfo)(UINT32 index,     
+    BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+
+void test7z (void)
+{
+    HMODULE lib;
+    CreateObjectFunc createObjectFunc;
+    void *archive;
+     
+    lib = LoadLibrary ("7z.dll");
+    if (!lib)
+       return;
+    createObjectFunc =  (CreateObjectFunc)GetProcAddress (lib, "CreateObject");
+    if (createObjectFunc (&CLSID_CFormat7z,  &IID_IInArchive, (void **)&archive) != S_OK)
+       return;
+
+ }
\ No newline at end of file
index 6758d8b43562a4c51b9c8d3423c865a45a655a50..f581e65fbb2fee920395209cf5ccd9b8eb619a66 100755 (executable)
@@ -589,6 +589,7 @@ RGBFTYPE WIN32GFX_FigurePixelFormats( RGBFTYPE colortype )
     struct PicassoResolution *dm;
     int i;
 
+    ignore_messages_all++;
     DirectDraw_Start (NULL);
     if( colortype == 0 ) /* Need to query a 16-bit display mode for its pixel-format.  Do this by opening such a screen */
     {
@@ -625,7 +626,7 @@ RGBFTYPE WIN32GFX_FigurePixelFormats( RGBFTYPE colortype )
         if (!got_16bit_mode) {
            write_log ("figure_pixel_formats: Attempting %dx%d..\n", dm->res.width, dm->res.height);
 
-            ddrval = DirectDraw_SetDisplayMode( dm->res.width, dm->res.height, 16, 0 ); /* 0 for default freq */
+           ddrval = DirectDraw_SetDisplayMode (dm->res.width, dm->res.height, 16, 0); /* 0 for default freq */
            if (ddrval != DD_OK)
                continue;
 
@@ -656,6 +657,7 @@ RGBFTYPE WIN32GFX_FigurePixelFormats( RGBFTYPE colortype )
        hAmigaWnd = NULL;
     }
     DirectDraw_Release ();
+    ignore_messages_all--;
     return colortype;
 }
 
@@ -1018,6 +1020,13 @@ int check_prefs_changed_gfx (void)
        inputdevice_acquire ();
        return 1;
     }
+
+    if (currprefs.chipset_refreshrate != changed_prefs.chipset_refreshrate) {
+        currprefs.chipset_refreshrate = changed_prefs.chipset_refreshrate;
+        init_hz ();
+        return 1;
+    }
+
     if (currprefs.gfx_correct_aspect != changed_prefs.gfx_correct_aspect ||
        currprefs.gfx_xcenter != changed_prefs.gfx_xcenter ||
        currprefs.gfx_ycenter != changed_prefs.gfx_ycenter)
index 37ab396dcb1346f0587d67b5f5d9d5066f080221..88101e6db1430ff366fdfa4a9518679b8b3e0137 100755 (executable)
@@ -115,6 +115,7 @@ static int LOADSAVE_ID = -1, MEMORY_ID = -1, KICKSTART_ID = -1, CPU_ID = -1,
     PATHS_ID = -1, QUICKSTART_ID = -1, ABOUT_ID = -1;
 static HWND pages[MAX_C_PAGES];
 static HWND guiDlg, panelDlg, ToolTipHWND;
+static HACCEL hAccelTable;
 
 void exit_gui (int ok)
 {
@@ -139,7 +140,132 @@ static int getcbn (HWND hDlg, int v, char *out, int len)
     }
 }
 
-static HICON hMoveUp = NULL, hMoveDown = NULL;
+/* base Drag'n'Drop code borrowed from http://www.codeproject.com/listctrl/jianghong.asp */
+
+static int bDragging = 0;
+static HIMAGELIST hDragImageList;
+static int drag_start (HWND hWnd, HWND hListView, LPARAM lParam)
+{
+    POINT p, pt;
+    int bFirst, iPos, iHeight;
+    HIMAGELIST hOneImageList, hTempImageList;
+    IMAGEINFO imf;
+
+    // You can set your customized cursor here
+    p.x = 8;
+    p.y = 8;
+    // Ok, now we create a drag-image for all selected items
+    bFirst = TRUE;
+    iPos = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
+    while (iPos != -1) {
+        if (bFirst) {
+            // For the first selected item,
+            // we simply create a single-line drag image
+            hDragImageList = ListView_CreateDragImage(hListView, iPos, &p);
+            ImageList_GetImageInfo(hDragImageList, 0, &imf);
+            iHeight = imf.rcImage.bottom;
+            bFirst = FALSE;
+        } else {
+            // For the rest selected items,
+            // we create a single-line drag image, then
+            // append it to the bottom of the complete drag image
+            hOneImageList = ListView_CreateDragImage(hListView, iPos, &p);
+            hTempImageList = ImageList_Merge(hDragImageList, 
+                             0, hOneImageList, 0, 0, iHeight);
+            ImageList_Destroy(hDragImageList);
+            ImageList_Destroy(hOneImageList);
+            hDragImageList = hTempImageList;
+            ImageList_GetImageInfo(hDragImageList, 0, &imf);
+            iHeight = imf.rcImage.bottom;
+        }
+        iPos = ListView_GetNextItem(hListView, iPos, LVNI_SELECTED);
+    }
+
+    // Now we can initialize then start the drag action
+    ImageList_BeginDrag(hDragImageList, 0, 0, 0);
+
+    pt = ((NM_LISTVIEW*) ((LPNMHDR)lParam))->ptAction;
+    ClientToScreen(hListView, &pt);
+
+    ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y);
+
+    bDragging = TRUE;
+
+    // Don't forget to capture the mouse
+    SetCapture (hWnd);
+
+    return 1;
+}
+
+static int drag_end (HWND hWnd, HWND hListView, LPARAM lParam, int **draggeditems)
+{
+    int iPos, cnt;
+    LVHITTESTINFO lvhti;
+    LVITEM  lvi;
+
+    *draggeditems = NULL;
+    if (!bDragging)
+       return -1;
+    // End the drag-and-drop process
+    bDragging = FALSE;
+    ImageList_DragLeave(hListView);
+    ImageList_EndDrag();
+    ImageList_Destroy(hDragImageList);
+    ReleaseCapture();
+
+    // Determine the dropped item
+    lvhti.pt.x = LOWORD(lParam);
+    lvhti.pt.y = HIWORD(lParam);
+    ClientToScreen(hWnd, &lvhti.pt);
+    ScreenToClient(hListView, &lvhti.pt);
+    ListView_HitTest(hListView, &lvhti);
+
+    // Out of the ListView?
+    if (lvhti.iItem == -1)
+       return -1;
+    // Not in an item?
+    if ((lvhti.flags & LVHT_ONITEMLABEL) == 0 &&  (lvhti.flags & LVHT_ONITEMSTATEICON) == 0)
+       return -1;
+    // Dropped item is selected?
+    lvi.iItem = lvhti.iItem;
+    lvi.iSubItem = 0;
+    lvi.mask = LVIF_STATE;
+    lvi.stateMask = LVIS_SELECTED;
+    ListView_GetItem(hListView, &lvi);
+    if (lvi.state & LVIS_SELECTED)
+       return -1;
+    // Rearrange the items
+    iPos = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
+    cnt = 0;
+    while (iPos != -1) {
+       iPos = ListView_GetNextItem(hListView, iPos, LVNI_SELECTED);
+       cnt++;
+    }
+    if (cnt == 0)
+       return -1;
+    *draggeditems = xmalloc (sizeof (int) * (cnt + 1));
+    iPos = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
+    cnt = 0;
+    while (iPos != -1) {
+       (*draggeditems)[cnt++] = iPos;
+       iPos = ListView_GetNextItem(hListView, iPos, LVNI_SELECTED);
+    }
+    (*draggeditems)[cnt] = -1;    
+    return lvhti.iItem;
+}
+static int drag_move (HWND hWnd, LPARAM lParam)
+{
+    POINT p;
+
+    if (!bDragging)
+       return 0;
+    p.x = LOWORD(lParam);
+    p.y = HIWORD(lParam);
+    ClientToScreen(hWnd, &p);
+    ImageList_DragMove(p.x, p.y);
+    return 1;
+}
+
 static HWND cachedlist = NULL;
 
 #define MIN_CHIP_MEM 0
@@ -1278,7 +1404,7 @@ static int disk_in_drive (int entry)
     return -1;
 }
 
-static int disk_swap (int entry, int col)
+static int disk_swap (int entry, int mode)
 {
     int drv, i, drvs[4] = { -1, -1, -1, -1 };
 
@@ -1369,7 +1495,7 @@ static int clicked_entry = -1;
 static int listview_num_columns;
 static int listview_column_width[HARDDISK_COLUMNS];
 
-void InitializeListView( HWND hDlg )
+void InitializeListView (HWND hDlg)
 {
     int lv_type;
     HWND list;
@@ -1414,6 +1540,7 @@ void InitializeListView( HWND hDlg )
        WIN32GUI_LoadUIString( IDS_DISK_DRIVENAME, column_heading[2], MAX_COLUMN_HEADING_WIDTH );
        list = GetDlgItem (hDlg, IDC_DISK);
     }
+    cachedlist = list;
 
     ListView_DeleteAllItems( list );
 
@@ -1487,7 +1614,7 @@ void InitializeListView( HWND hDlg )
            entry++;
        }
        listview_column_width[0] = 30;
-       listview_column_width[1] = 308;
+       listview_column_width[1] = 354;
        listview_column_width[2] = 50;
 
     }
@@ -2498,12 +2625,12 @@ static void init_quickstartdlg (HWND hDlg)
            RegQueryValueEx (hWinUAEKey, "QuickStartCompatibility", 0, &dwType, (LPBYTE)&quickstart_compa, &qssize);
        }
        if (quickstart) {
-           quickstarthost (hDlg, hostconf);
            workprefs.df[0][0] = 0;
            workprefs.df[1][0] = 0;
            workprefs.df[2][0] = 0;
            workprefs.df[3][0] = 0;
            load_quickstart (hDlg, 1);
+           quickstarthost (hDlg, hostconf);
        }
        firsttime = 1;
     }
@@ -2739,6 +2866,8 @@ static BOOL CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR
                    if (hWinUAEKey)
                        RegSetValueEx (hWinUAEKey, "QuickStartHostConfig", 0, REG_SZ, (CONST BYTE *)&tmp, strlen (tmp) + 1);
                    quickstarthost (hDlg, tmp);
+                   if (val == 0 && quickstart)
+                       load_quickstart (hDlg, 0);
                }
                break;
            }
@@ -2778,12 +2907,14 @@ static BOOL CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR
        if (recursive > 0)
            break;
        recursive++;
-       val = SendMessage (GetDlgItem (hDlg, IDC_QUICKSTART_COMPATIBILITY), TBM_GETPOS, 0, 0);
-       if (val >= 0 && val != quickstart_compa) {
-           quickstart_compa = val;
-           init_quickstartdlg (hDlg);
-           if (quickstart)
-               load_quickstart (hDlg, 0);
+       if ((HWND)lParam == GetDlgItem (hDlg, IDC_QUICKSTART_COMPATIBILITY)) {
+           val = SendMessage ((HWND)lParam, TBM_GETPOS, 0, 0);
+           if (val >= 0 && val != quickstart_compa) {
+               quickstart_compa = val;
+               init_quickstartdlg (hDlg);
+               if (quickstart)
+                   load_quickstart (hDlg, 0);
+           }
        }
        recursive--;
        break;
@@ -5191,6 +5322,13 @@ static void harddisk_edit (HWND hDlg)
     }
 }
 
+static ACCEL HarddiskAccel[] = {
+    { FVIRTKEY, VK_UP, 10001 }, { FVIRTKEY, VK_DOWN, 10002 },
+    { FVIRTKEY|FSHIFT, VK_UP, IDC_UP }, { FVIRTKEY|FSHIFT, VK_DOWN, IDC_DOWN },
+    { FVIRTKEY, VK_RETURN, IDC_EDIT }, { FVIRTKEY, VK_DELETE, IDC_REMOVE },
+    { 0, 0, 0 }
+};
+
 static void harddiskdlg_button (HWND hDlg, int button)
 {
     switch (button) {
@@ -5253,6 +5391,9 @@ static void harddiskdlg_volume_notify (HWND hDlg, NM_LISTVIEW *nmlistview)
     int entry = 0;
 
     switch (nmlistview->hdr.code) {
+     case LVN_BEGINDRAG:
+       drag_start (hDlg, cachedlist, (LPARAM)nmlistview);
+       break;
      case NM_DBLCLK:
        dblclick = 1;
        /* fall through */
@@ -5262,16 +5403,27 @@ static void harddiskdlg_volume_notify (HWND hDlg, NM_LISTVIEW *nmlistview)
        {
            if(dblclick)
                harddisk_edit (hDlg);
-           InitializeListView( hDlg );
+           InitializeListView (hDlg);
            clicked_entry = entry;
-           cachedlist = list;
            // Hilite the current selected item
-           ListView_SetItemState( cachedlist, clicked_entry, LVIS_SELECTED, LVIS_SELECTED );
+           ListView_SetItemState (cachedlist, clicked_entry, LVIS_SELECTED, LVIS_SELECTED);
        }
        break;
     }
 }
 
+static void hilitehd (void)
+{
+    int total = ListView_GetItemCount (cachedlist);
+    if (total <= 0)
+       return;
+    if (clicked_entry < 0)
+       clicked_entry = 0;
+    if (clicked_entry >= total)
+       clicked_entry = total;
+    ListView_SetItemState( cachedlist, clicked_entry, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
+}
+
 static BOOL CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 
@@ -5280,34 +5432,50 @@ static BOOL CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        clicked_entry = 0;
        pages[HARDDISK_ID] = hDlg;
        currentpage = HARDDISK_ID;
-       SendMessage( GetDlgItem( hDlg, IDC_UP ), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hMoveUp );
-       SendMessage( GetDlgItem( hDlg, IDC_DOWN ), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hMoveDown );
        EnableWindow (GetDlgItem(hDlg, IDC_NEW_HD), os_winnt && os_winnt_admin ? TRUE : FALSE);
        
     case WM_USER:
-        CheckDlgButton( hDlg, IDC_MAPDRIVES, workprefs.win32_automount_drives );
-        CheckDlgButton( hDlg, IDC_NOUAEFSDB, workprefs.filesys_no_uaefsdb );
-        InitializeListView( hDlg );
+        CheckDlgButton (hDlg, IDC_MAPDRIVES, workprefs.win32_automount_drives);
+        CheckDlgButton (hDlg, IDC_NOUAEFSDB, workprefs.filesys_no_uaefsdb);
+        InitializeListView (hDlg);
+        hilitehd ();
        break;
-       
+
+    case WM_MOUSEMOVE:
+       if (drag_move (hDlg, lParam))
+           return TRUE;
+       break;
+    case WM_LBUTTONUP:
+    {
+       int *draggeditems, item;
+       if ((item = drag_end (hDlg, cachedlist, lParam, &draggeditems)) >= 0) {
+           move_filesys_unit (currprefs.mountinfo, draggeditems[0], item);
+            InitializeListView (hDlg);
+            clicked_entry = item;
+            hilitehd ();
+       }
+       xfree (draggeditems);
+       break;
+    }
+
     case WM_COMMAND:
-       if (HIWORD (wParam) == BN_CLICKED)
+       switch (LOWORD(wParam))
        {
+           case 10001:
+           clicked_entry--;
+           hilitehd ();
+           break;
+           case 10002:
+           clicked_entry++;
+           hilitehd ();
+           break;
+           default:
            harddiskdlg_button (hDlg, LOWORD (wParam));
-           InitializeListView( hDlg );
-
-           if( clicked_entry < 0 )
-               clicked_entry = 0;
-           if( clicked_entry >= ListView_GetItemCount( cachedlist ) )
-               clicked_entry = ListView_GetItemCount( cachedlist ) - 1;
-
-           if( cachedlist && clicked_entry >= 0 )
-           {
-               // Hilite the current selected item
-               ListView_SetItemState( cachedlist, clicked_entry, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
-           }
+           InitializeListView (hDlg);
+           hilitehd ();
+           break;
        }
-       break;
+    break;
        
     case WM_NOTIFY:
        if (((LPNMHDR) lParam)->idFrom == IDC_VOLUMELIST)
@@ -5742,7 +5910,26 @@ static BOOL CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
     return FALSE;
 }
 
-static BOOL CALLBACK DiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+static ACCEL SwapperAccel[] = {
+    { FALT|FVIRTKEY, '1', 10001 }, { FALT|FVIRTKEY, '2', 10002 }, { FALT|FVIRTKEY, '3', 10003 }, { FALT|FVIRTKEY, '4', 10004 }, { FALT|FVIRTKEY, '5', 10005 },
+    { FALT|FVIRTKEY, '6', 10006 }, { FALT|FVIRTKEY, '7', 10007 }, { FALT|FVIRTKEY, '8', 10008 }, { FALT|FVIRTKEY, '9', 10009 }, { FALT|FVIRTKEY, '0', 10010 },
+    { FALT|FSHIFT|FVIRTKEY, '1', 10011 }, { FALT|FSHIFT|FVIRTKEY, '2', 10012 }, { FALT|FSHIFT|FVIRTKEY, '3', 10013 }, { FALT|FSHIFT|FVIRTKEY, '4', 10014 }, { FALT|FSHIFT|FVIRTKEY, '5', 10015 },
+    { FALT|FSHIFT|FVIRTKEY, '6', 10016 }, { FALT|FSHIFT|FVIRTKEY, '7', 10017 }, { FALT|FSHIFT|FVIRTKEY, '8', 10018 }, { FALT|FSHIFT|FVIRTKEY, '9', 10019 }, { FALT|FSHIFT|FVIRTKEY, '0', 10020 },
+    { FVIRTKEY, VK_UP, 10101 }, { FVIRTKEY, VK_DOWN, 10102 }, { FVIRTKEY, VK_RIGHT, 10104 }, 
+    { FVIRTKEY|FSHIFT, VK_UP, IDC_UP }, { FVIRTKEY|FSHIFT, VK_DOWN, IDC_DOWN },
+    { FVIRTKEY|FCONTROL, '1', 10201 }, { FVIRTKEY|FCONTROL, '2', 10202 }, { FVIRTKEY|FCONTROL, '3', 10203 }, { FVIRTKEY|FCONTROL, '4', 10204 },
+    { FVIRTKEY|FCONTROL|FSHIFT, '1', 10205 }, { FVIRTKEY|FCONTROL|FSHIFT, '2', 10206 }, { FVIRTKEY|FCONTROL|FSHIFT, '3', 10207 }, { FVIRTKEY|FCONTROL|FSHIFT, '4', 10208 },
+    { FVIRTKEY, VK_RETURN, 10209 }, { FVIRTKEY, VK_DELETE, IDC_DISKLISTREMOVE },
+    { 0, 0, 0 }
+};
+
+static void swapperhili (int entry)
+{
+    ListView_SetItemState (cachedlist, entry,
+        LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+}
+
+static BOOL CALLBACK SwapperDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     static int recursive = 0;
     static int entry;
@@ -5754,18 +5941,128 @@ static BOOL CALLBACK DiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPa
        pages[DISK_ID] = hDlg;
        currentpage = DISK_ID;
        InitializeListView(hDlg);
-       SendMessage( GetDlgItem( hDlg, IDC_UP ), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hMoveUp );
-       SendMessage( GetDlgItem( hDlg, IDC_DOWN ), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hMoveDown );
-       entry = -1;
+       entry = 0;
+       swapperhili (entry);
+    break;
+    case WM_LBUTTONUP:
+    {
+       int *draggeditems;
+       int item = drag_end (hDlg, cachedlist, lParam, &draggeditems);
+       if (item >= 0) {
+           int i, item2;
+           entry = item;
+           for (i = 0; (item2 = draggeditems[i]) >= 0 && item2 < MAX_SPARE_DRIVES; i++, item++) {
+               if (item != item2) {
+                   char tmp[1000];
+                   strcpy (tmp, workprefs.dfxlist[item]);
+                   strcpy (workprefs.dfxlist[item], workprefs.dfxlist[item2]);
+                   strcpy (workprefs.dfxlist[item2], tmp);
+               }
+           }
+           InitializeListView(hDlg);
+           swapperhili (entry);
+           return TRUE;
+       }
+       xfree (draggeditems);
+    }
+    break;
+    case WM_MOUSEMOVE:
+    if (drag_move (hDlg, lParam))
+       return TRUE;
     break;
     case WM_COMMAND:
     {
-       switch (wParam)
+       switch (LOWORD(wParam))
        {
+           case 10001:
+           case 10002:
+           case 10003:
+           case 10004:
+           case 10005:
+           case 10006:
+           case 10007:
+           case 10008:
+           case 10009:
+           case 10010:
+           case 10011:
+           case 10012:
+           case 10013:
+           case 10014:
+           case 10015:
+           case 10016:
+           case 10017:
+           case 10018:
+           case 10019:
+           case 10020:
+           entry = LOWORD (wParam) - 10001;
+           swapperhili (entry);
+           break;
+           case 10101:
+           if (entry > 0) {
+               entry--;
+               swapperhili (entry);
+           }
+           break;
+           case 10102:
+           if (entry >= 0 && entry < MAX_SPARE_DRIVES - 1) {
+               entry++;
+               swapperhili (entry);
+           }
+           break;
+           case 10103:
+           case 10104:
+           disk_swap (entry, 1);
+           InitializeListView (hDlg);
+           swapperhili (entry);
+           break;
+           case 10201:
+           case 10202:
+           case 10203:
+           case 10204:
+           {
+               int drv = LOWORD (wParam) - 10201;
+               int i;
+               if (workprefs.dfxtype[drv] >= 0 && entry >= 0) {
+                   for (i = 0; i < 4; i++) {
+                       if (!strcmp (workprefs.df[i], workprefs.dfxlist[entry])) {
+                           workprefs.df[i][0] = 0;
+                           disk_eject (i);
+                       }
+                   }
+                   strcpy (workprefs.df[drv], workprefs.dfxlist[entry]);
+                   disk_insert (drv, workprefs.df[drv]);
+                   InitializeListView (hDlg);
+                   swapperhili (entry);
+               }
+           }
+           break;
+           case 10205:
+           case 10206:
+           case 10207:
+           case 10208:
+           {
+               int drv = LOWORD (wParam) - 10201;
+               disk_eject (drv);
+               InitializeListView (hDlg);
+               swapperhili (entry);
+           }
+           break;
+           case 10209:
+           {
+               char path[MAX_DPATH];
+               if (DiskSelection (hDlg, -1, 0, &changed_prefs, path)) {
+                   strcpy (workprefs.dfxlist[entry], path);
+                   InitializeListView (hDlg);
+                   swapperhili (entry);
+               }
+           }
+           break;
+       
            case IDC_DISKLISTREMOVE:
                if (entry >= 0) {
                    workprefs.dfxlist[entry][0] = 0;
                    InitializeListView (hDlg);
+                   swapperhili (entry);
                }
                break;
            case IDC_UP:
@@ -5775,8 +6072,7 @@ static BOOL CALLBACK DiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPa
                    strcpy (workprefs.dfxlist[entry], tmp);
                    InitializeListView (hDlg);
                    entry--;
-                   ListView_SetItemState (cachedlist, entry,
-                       LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+                   swapperhili (entry);
                }
                break;
            case IDC_DOWN:
@@ -5786,8 +6082,7 @@ static BOOL CALLBACK DiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPa
                    strcpy (workprefs.dfxlist[entry], tmp);
                    InitializeListView (hDlg);
                    entry++;
-                   ListView_SetItemState (cachedlist, entry,
-                       LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+                   swapperhili (entry);
                }
                break;
        }
@@ -5803,6 +6098,9 @@ static BOOL CALLBACK DiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPa
            cachedlist = list = nmlistview->hdr.hwndFrom;
            switch (nmlistview->hdr.code) 
            {
+               case LVN_BEGINDRAG:
+               drag_start (hDlg, cachedlist, lParam);
+               break;
                case NM_DBLCLK:
                dblclick = 1;
                /* fall-through */
@@ -5810,13 +6108,15 @@ static BOOL CALLBACK DiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPa
                entry = listview_entry_from_click (list, &col);
                if (entry >= 0) {
                    if (col == 2) {
-                       if (disk_swap (entry, col))
+                       if (disk_swap (entry, 0))
                            InitializeListView (hDlg);
+                       swapperhili (entry);
                    } else if (col == 1) {
                        char path[MAX_DPATH];
                        if (dblclick && DiskSelection (hDlg, -1, 0, &changed_prefs, path)) {
                            strcpy (workprefs.dfxlist[entry], path);
                            InitializeListView (hDlg);
+                           swapperhili (entry);
                        }
                    }
                }
@@ -5832,6 +6132,7 @@ static DWORD dwEnumeratedPrinters = 0;
 #define MAX_PRINTERS 10
 #define MAX_SERIALS 8
 static char comports[MAX_SERIALS][8];
+static int ghostscript_available;
 
 static int joy0idc[] = {
     IDC_PORT0_JOYSC, IDC_PORT0_KBDA, IDC_PORT0_KBDB, IDC_PORT0_KBDC,
@@ -5872,8 +6173,13 @@ static void enable_for_portsdlg( HWND hDlg )
 #if !defined (PARALLEL_PORT)
     EnableWindow( GetDlgItem( hDlg, IDC_PRINTERLIST), FALSE );
     EnableWindow( GetDlgItem( hDlg, IDC_FLUSHPRINTER), FALSE );
+    EnableWindow( GetDlgItem( hDlg, IDC_PSPRINTER), FALSE );
+    EnableWindow( GetDlgItem( hDlg, IDC_PS_PARAMS), FALSE );
 #else
     EnableWindow( GetDlgItem( hDlg, IDC_FLUSHPRINTER), isprinteropen () ? TRUE : FALSE );
+    EnableWindow( GetDlgItem( hDlg, IDC_PSPRINTER), full_property_sheet && ghostscript_available ? TRUE : FALSE );
+    EnableWindow( GetDlgItem( hDlg, IDC_PSPRINTERDETECT), full_property_sheet ? TRUE : FALSE );
+    EnableWindow( GetDlgItem( hDlg, IDC_PS_PARAMS), full_property_sheet && ghostscript_available );
 #endif
 }
 
@@ -6064,6 +6370,8 @@ static void values_from_portsdlg (HWND hDlg)
     workprefs.serial_direct = 0;
     if( IsDlgButtonChecked( hDlg, IDC_SERIAL_DIRECT ) )
         workprefs.serial_direct = 1;
+    GetDlgItemText (hDlg, IDC_PS_PARAMS, workprefs.ghostscript_parameters, 256);
+
 }
 
 static void values_to_portsdlg (HWND hDlg)
@@ -6097,6 +6405,10 @@ static void values_to_portsdlg (HWND hDlg)
            result = 0;
        }
     }
+    CheckDlgButton( hDlg, IDC_PSPRINTER, workprefs.parallel_postscript_emulation );
+    CheckDlgButton( hDlg, IDC_PSPRINTERDETECT, workprefs.parallel_postscript_detection );
+    SetDlgItemText (hDlg, IDC_PS_PARAMS, workprefs.ghostscript_parameters);
+    
     SendDlgItemMessage( hDlg, IDC_PRINTERLIST, CB_SETCURSEL, result, 0 );
     SendDlgItemMessage( hDlg, IDC_MIDIOUTLIST, CB_SETCURSEL, workprefs.win32_midioutdev + 2, 0 );
     if (!bNoMidiIn && workprefs.win32_midiindev >= 0)
@@ -6148,12 +6460,24 @@ static void values_to_portsdlg (HWND hDlg)
 
 static void init_portsdlg( HWND hDlg )
 {
+    static int first;
     int port, portcnt, numdevs;
     COMMCONFIG cc;
     DWORD size = sizeof(COMMCONFIG);
     MIDIOUTCAPS midiOutCaps;
     MIDIINCAPS midiInCaps;
 
+    if (!first) {
+       first = 1;
+       if (load_ghostscript () > 0) {
+           unload_ghostscript ();
+           ghostscript_available = 1;
+       }
+    }
+    if (!ghostscript_available) {
+       workprefs.parallel_postscript_emulation = 0;
+    }
+
     joy0previous = joy1previous = -1;
     SendDlgItemMessage (hDlg, IDC_SERIAL, CB_RESETCONTENT, 0, 0L);
     SendDlgItemMessage (hDlg, IDC_SERIAL, CB_ADDSTRING, 0, (LPARAM)szNone );
@@ -6281,9 +6605,16 @@ static BOOL CALLBACK PortsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP
            updatejoyport (hDlg);
        } else if (wParam == IDC_FLUSHPRINTER) {
            if (isprinter ()) {
-               flushprinter ();
-               openprinter ();
+               closeprinter ();
            }
+       } else if (wParam == IDC_PSPRINTER) {
+           workprefs.parallel_postscript_emulation = IsDlgButtonChecked (hDlg, IDC_PSPRINTER) ? 1 : 0;
+           if (workprefs.parallel_postscript_emulation)
+               CheckDlgButton (hDlg, IDC_PSPRINTERDETECT, 1);
+       } else if (wParam == IDC_PSPRINTERDETECT) {
+           workprefs.parallel_postscript_detection = IsDlgButtonChecked (hDlg, IDC_PSPRINTERDETECT) ? 1 : 0;
+           if (!workprefs.parallel_postscript_detection)
+               CheckDlgButton (hDlg, IDC_PSPRINTER, 0);
        } else {
            values_from_portsdlg (hDlg);
            updatejoyport (hDlg);
@@ -7274,6 +7605,7 @@ struct GUIPAGE {
     int himg;
     int idx;
     const char *help;
+    HACCEL accel;
 };
 
 static int GetPanelRect (HWND hDlg, RECT *r)
@@ -7364,6 +7696,7 @@ static HWND updatePanel (HWND hDlg, int id)
        DestroyWindow (ToolTipHWND);
        ToolTipHWND = NULL;
     }
+    hAccelTable = NULL;
     if (id < 0) {
        if (!isfullscreen ()) {
            RECT r;
@@ -7422,6 +7755,8 @@ static HWND updatePanel (HWND hDlg, int id)
     EnumChildWindows (panelDlg, &childenumproc, (LPARAM)NULL);
     SendMessage (panelDlg, WM_NULL, 0, 0);
 
+    hAccelTable = ppage[currentpage].accel;
+
     return panelDlg;
 }
 
@@ -7653,12 +7988,21 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage)
     return ret;
 }
 
+static int dialogreturn;
 static BOOL CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     static int recursive = 0;
 
     switch(msg)
     {
+       case WM_DESTROY:
+       PostQuitMessage (0);
+        return TRUE;
+       case WM_CLOSE:
+        DestroyWindow(hDlg);
+        if (dialogreturn < 0)
+           dialogreturn = 0;
+        return TRUE;
        case WM_INITDIALOG:
            guiDlg = hDlg;
            SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE(IDI_APPICON)));
@@ -7693,7 +8037,7 @@ static BOOL CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPara
            }
            break;
        case WM_COMMAND:
-           switch (wParam) 
+           switch (LOWORD(wParam))
            {
                case IDC_RESETAMIGA:
                    uae_reset (0);
@@ -7709,13 +8053,15 @@ static BOOL CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPara
                    return TRUE;
                case IDOK:
                    updatePanel (hDlg, -1);
-                   EndDialog (hDlg, 1);
+                   dialogreturn = 1;
+                   DestroyWindow (hDlg);
                    gui_to_prefs ();
                    guiDlg = NULL;
                    return TRUE;
                case IDCANCEL:
                    updatePanel (hDlg, -1);
-                   EndDialog (hDlg, 0);
+                   dialogreturn = 0;
+                   DestroyWindow (hDlg);
                    if (allow_quit) {
                        quit_program = 1;
                        regs.spcflags |= SPCFLAG_BRK;
@@ -7728,11 +8074,17 @@ static BOOL CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPara
     return FALSE;
 }
 
+static ACCEL EmptyAccel[] = {
+    { FVIRTKEY, VK_UP, 20001 }, { FVIRTKEY, VK_DOWN, 20002 },
+    { 0, 0, 0 }
+};
 
 static int init_page (int tmpl, int icon, int title,
-               BOOL (CALLBACK FAR *func) (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam), char *help)
+               BOOL (CALLBACK FAR *func) (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam), ACCEL *accels, char *help)
 {
     static id = 0;
+    int i = -1;
+
     LPTSTR lpstrTitle;
     ppage[id].pp.pszTemplate = MAKEINTRESOURCE (tmpl);
     ppage[id].pp.pszIcon = MAKEINTRESOURCE (icon);
@@ -7742,6 +8094,11 @@ static int init_page (int tmpl, int icon, int title,
     ppage[id].pp.pfnDlgProc = func;
     ppage[id].help = help;
     ppage[id].idx = id;
+    ppage[id].accel = NULL;
+    if (!accels)
+       accels = EmptyAccel;
+    while (accels[++i].key);
+    ppage[id].accel = CreateAcceleratorTable (accels, i);
     id++;
     return id - 1;
 }
@@ -7750,6 +8107,7 @@ static int GetSettings (int all_options, HWND hwnd)
 {
     static int init_called = 0;
     int psresult;
+    HWND dhwnd;
 
     gui_active = 1;
 
@@ -7758,50 +8116,73 @@ static int GetSettings (int all_options, HWND hwnd)
     pguiprefs = &currprefs;
     default_prefs (&workprefs, 0);
 
-    WIN32GUI_LoadUIString( IDS_NONE, szNone, MAX_DPATH );
+    WIN32GUI_LoadUIString (IDS_NONE, szNone, MAX_DPATH);
 
     prefs_to_gui (&changed_prefs);
 
-    if (!init_called)
-    {
-       LOADSAVE_ID = init_page (IDD_LOADSAVE, IDI_CONFIGFILE, IDS_LOADSAVE, LoadSaveDlgProc, "gui/configurations.htm");
-       MEMORY_ID = init_page (IDD_MEMORY, IDI_MEMORY, IDS_MEMORY, MemoryDlgProc, "gui/ram.htm");
-       KICKSTART_ID = init_page (IDD_KICKSTART, IDI_MEMORY, IDS_KICKSTART, KickstartDlgProc, "gui/rom.htm");
-       CPU_ID = init_page (IDD_CPU, IDI_CPU, IDS_CPU, CPUDlgProc, "gui/cpu.htm");
-       DISPLAY_ID = init_page (IDD_DISPLAY, IDI_DISPLAY, IDS_DISPLAY, DisplayDlgProc, "gui/display.htm");
+    if (!init_called) {
+       LOADSAVE_ID = init_page (IDD_LOADSAVE, IDI_CONFIGFILE, IDS_LOADSAVE, LoadSaveDlgProc, NULL, "gui/configurations.htm");
+       MEMORY_ID = init_page (IDD_MEMORY, IDI_MEMORY, IDS_MEMORY, MemoryDlgProc, NULL, "gui/ram.htm");
+       KICKSTART_ID = init_page (IDD_KICKSTART, IDI_MEMORY, IDS_KICKSTART, KickstartDlgProc, NULL, "gui/rom.htm");
+       CPU_ID = init_page (IDD_CPU, IDI_CPU, IDS_CPU, CPUDlgProc, NULL, "gui/cpu.htm");
+       DISPLAY_ID = init_page (IDD_DISPLAY, IDI_DISPLAY, IDS_DISPLAY, DisplayDlgProc, NULL, "gui/display.htm");
 #if defined (GFXFILTER)
-       HW3D_ID = init_page (IDD_FILTER, IDI_DISPLAY, IDS_FILTER, hw3dDlgProc, "gui/filter.htm");
+       HW3D_ID = init_page (IDD_FILTER, IDI_DISPLAY, IDS_FILTER, hw3dDlgProc, NULL, "gui/filter.htm");
 #endif
-       CHIPSET_ID = init_page (IDD_CHIPSET, IDI_CPU, IDS_CHIPSET, ChipsetDlgProc, "gui/chipset.htm");
-       SOUND_ID = init_page (IDD_SOUND, IDI_SOUND, IDS_SOUND, SoundDlgProc, "gui/sound.htm");
-       FLOPPY_ID = init_page (IDD_FLOPPY, IDI_FLOPPY, IDS_FLOPPY, FloppyDlgProc, "gui/floppies.htm");
-       DISK_ID = init_page (IDD_DISK, IDI_FLOPPY, IDS_DISK, DiskDlgProc, "gui/disk.htm");
+       CHIPSET_ID = init_page (IDD_CHIPSET, IDI_CPU, IDS_CHIPSET, ChipsetDlgProc, NULL, "gui/chipset.htm");
+       SOUND_ID = init_page (IDD_SOUND, IDI_SOUND, IDS_SOUND, SoundDlgProc, NULL, "gui/sound.htm");
+       FLOPPY_ID = init_page (IDD_FLOPPY, IDI_FLOPPY, IDS_FLOPPY, FloppyDlgProc, NULL, "gui/floppies.htm");
+       DISK_ID = init_page (IDD_DISK, IDI_FLOPPY, IDS_DISK, SwapperDlgProc, SwapperAccel, "gui/disk.htm");
 #ifdef FILESYS
-       HARDDISK_ID = init_page (IDD_HARDDISK, IDI_HARDDISK, IDS_HARDDISK, HarddiskDlgProc, "gui/hard-drives.htm");
+       HARDDISK_ID = init_page (IDD_HARDDISK, IDI_HARDDISK, IDS_HARDDISK, HarddiskDlgProc, HarddiskAccel, "gui/hard-drives.htm");
 #endif
-       PORTS_ID = init_page (IDD_PORTS, IDI_PORTS, IDS_PORTS, PortsDlgProc, "gui/ports.htm");
-       INPUT_ID = init_page (IDD_INPUT, IDI_INPUT, IDS_INPUT, InputDlgProc, "gui/input.htm");
-       MISC1_ID = init_page (IDD_MISC1, IDI_MISC1, IDS_MISC1, MiscDlgProc1, "gui/misc.htm");
-       MISC2_ID = init_page (IDD_MISC2, IDI_MISC2, IDS_MISC2, MiscDlgProc2, "gui/misc.htm");
+       PORTS_ID = init_page (IDD_PORTS, IDI_PORTS, IDS_PORTS, PortsDlgProc, NULL, "gui/ports.htm");
+       INPUT_ID = init_page (IDD_INPUT, IDI_INPUT, IDS_INPUT, InputDlgProc, NULL, "gui/input.htm");
+       MISC1_ID = init_page (IDD_MISC1, IDI_MISC1, IDS_MISC1, MiscDlgProc1, NULL, "gui/misc.htm");
+       MISC2_ID = init_page (IDD_MISC2, IDI_MISC2, IDS_MISC2, MiscDlgProc2, NULL, "gui/misc.htm");
 #ifdef AVIOUTPUT
-       AVIOUTPUT_ID = init_page (IDD_AVIOUTPUT, IDI_AVIOUTPUT, IDS_AVIOUTPUT, AVIOutputDlgProc, "gui/output.htm");
+       AVIOUTPUT_ID = init_page (IDD_AVIOUTPUT, IDI_AVIOUTPUT, IDS_AVIOUTPUT, AVIOutputDlgProc, NULL, "gui/output.htm");
 #endif
-       PATHS_ID = init_page (IDD_PATHS, IDI_PATHS, IDS_PATHS, PathsDlgProc, "gui/paths.htm");
-       QUICKSTART_ID = init_page (IDD_QUICKSTART, IDI_QUICKSTART, IDS_QUICKSTART, QuickstartDlgProc, "gui/quickstart.htm");
-       ABOUT_ID = init_page (IDD_ABOUT, IDI_ABOUT, IDS_ABOUT, AboutDlgProc, NULL);
+       PATHS_ID = init_page (IDD_PATHS, IDI_PATHS, IDS_PATHS, PathsDlgProc, NULL, "gui/paths.htm");
+       QUICKSTART_ID = init_page (IDD_QUICKSTART, IDI_QUICKSTART, IDS_QUICKSTART, QuickstartDlgProc, NULL, "gui/quickstart.htm");
+       ABOUT_ID = init_page (IDD_ABOUT, IDI_ABOUT, IDS_ABOUT, AboutDlgProc, NULL, NULL);
        C_PAGES = ABOUT_ID + 1;
        init_called = 1;
        if (quickstart && !qs_override)
            currentpage = QUICKSTART_ID;
        else
            currentpage = LOADSAVE_ID;
-       hMoveUp = (HICON)LoadImage (hInst, MAKEINTRESOURCE( IDI_MOVE_UP ), IMAGE_ICON, 16, 16, LR_LOADMAP3DCOLORS);
-       hMoveDown = (HICON)LoadImage (hInst, MAKEINTRESOURCE( IDI_MOVE_DOWN ), IMAGE_ICON, 16, 16, LR_LOADMAP3DCOLORS);
     }
 
     if (all_options || !configstore)
        CreateConfigStore (NULL);
-    psresult = DialogBox (hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE (IDD_PANEL), hwnd, DialogProc);
+
+    dialogreturn = -1;
+    hAccelTable = NULL;
+    dhwnd = CreateDialog (hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE (IDD_PANEL), hwnd, DialogProc);
+    psresult = 0;
+    if (dhwnd != NULL) {
+       MSG msg;
+       DWORD v;
+       ShowWindow (dhwnd, SW_SHOW);
+       while ((v = GetMessage (&msg, NULL, 0, 0))) {
+           if (dialogreturn >= 0)
+               break;
+           if (v == -1)
+               continue;
+           if (!IsWindow (dhwnd))
+               continue;
+           if (hAccelTable && panelDlg) {
+               if (TranslateAccelerator (panelDlg, hAccelTable, &msg))
+                   continue;
+           }
+           if (IsDialogMessage (dhwnd, &msg))
+               continue;
+           TranslateMessage (&msg);
+           DispatchMessage (&msg);
+       }
+       psresult = dialogreturn;
+    }
 
     if (quit_program)
         psresult = -2;
@@ -7834,6 +8215,13 @@ int gui_update (void)
 
 void gui_exit (void)
 {
+    int i;
+    
+    for (i = 0; i < C_PAGES; i++) {
+       if (ppage[i].accel)
+           DestroyAcceleratorTable (ppage[i].accel);
+       ppage[i].accel = NULL;
+    }
     FreeConfigStore ();
 #ifdef PARALLEL_PORT
     closeprinter(); // Bernd Roesch