]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1600b25.zip
authorToni Wilen <twilen@winuae.net>
Mon, 20 Apr 2009 14:54:04 +0000 (17:54 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:46:03 +0000 (21:46 +0200)
18 files changed:
audio.c
blitter.c
include/gui.h
inputdevice.c
main.c
moduleripper.c
od-win32/ahidsound.c
od-win32/clipboard_win32.c
od-win32/dinput.c
od-win32/direct3d.c
od-win32/picasso96_win.c
od-win32/sounddep/sound.c
od-win32/win32.c
od-win32/win32.h
od-win32/win32gui.c
od-win32/winuae_msvc/winuae_msvc.vcproj
od-win32/winuaechangelog.txt
uaeunp.c

diff --git a/audio.c b/audio.c
index d43bd5b343ef1a14206d1a1e906c644077a5d565..19398300c0fe3910962455bb312258e671725b3c 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -1049,7 +1049,7 @@ int audio_activate (void)
     if (!audio_work_to_do) {
        restart_sound_buffer ();
        ret = 1;
-       audio_event_reset();
+       audio_event_reset ();
     }
     audio_work_to_do = 4 * maxvpos * 50;
     return ret;
index 721285e206a6b7dabc68d99274b6249cc2e43fca..7bd9e139eaef50f0cdc72e4c6ea35b04355ba1ec 100644 (file)
--- a/blitter.c
+++ b/blitter.c
@@ -71,6 +71,8 @@ static const int *blit_diag;
 static uae_u16 ddat1, ddat2;
 static int ddat1use, ddat2use;
 
+static int blit_last_hpos;
+
 /*
 
 Confirmed blitter information by Toni Wilen
@@ -259,6 +261,7 @@ static void blitter_done (void)
     INTREQ (0x8040);
     event2_remevent (ev2_blitter);
     unset_special (&regs, SPCFLAG_BLTNASTY);
+    blit_last_hpos = 0;
 #ifdef BLITTER_DEBUG
     write_log (L"vpos=%d, cycles %d, missed %d, total %d\n",
        vpos, blit_cyclecounter, blit_misscyclecounter, blit_cyclecounter + blit_misscyclecounter);
@@ -579,8 +582,6 @@ STATIC_INLINE void blitter_nxline (void)
 
 #ifdef CPUEMU_12
 
-static int blit_last_hpos;
-
 static int blitter_cyclecounter;
 static int blitter_hcounter1, blitter_hcounter2;
 static int blitter_vcounter1, blitter_vcounter2;
@@ -1244,7 +1245,7 @@ uae_u8 *save_blitter (int *len, uae_u8 *dstptr)
        dstbak = dst = dstptr;
     else
        dstbak = dst = xmalloc (16);
-    save_u32(((bltstate != BLT_done) ? 0 : 1) | forced);
+    save_u32 (((bltstate != BLT_done) ? 0 : 1) | forced);
     *len = dst - dstbak;
     return dstbak;
 
index bf9c454d42ff2cde3b125f2bf140a99c0035cc56..6102e785295b22b832bc3f6696a8e10459f9e6f4 100644 (file)
@@ -22,7 +22,7 @@ extern void gui_disk_image_change (int, const TCHAR *);
 extern unsigned int gui_ledstate;
 extern void gui_display (int shortcut);
 
-extern int no_gui;
+extern int no_gui, quit_to_gui;
 
 struct gui_info
 {
index c3ef007760eca5e41ff3762fe740807d11849eac..d9d6455a84bfba16c34aaf243d67cbb5e8f22997 100644 (file)
@@ -1480,17 +1480,17 @@ int getbuttonstate (int joy, int button)
        oldbuttons[joy] &= ~(1 << button);
        if (v)
            oldbuttons[joy] |= 1 << button;
-       inprec_rstart(INPREC_JOYBUTTON);
-       inprec_ru8(joy);
-       inprec_ru8(button);
-       inprec_ru8(v);
-       inprec_rend();
+       inprec_rstart (INPREC_JOYBUTTON);
+       inprec_ru8 (joy);
+       inprec_ru8 (button);
+       inprec_ru8 (v);
+       inprec_rend ();
     } else if (input_recording < 0) {
        while(inprec_pstart (INPREC_JOYBUTTON)) {
-           uae_u8 j = inprec_pu8();
-           uae_u8 but = inprec_pu8();
-           uae_u8 vv = inprec_pu8();
-           inprec_pend();
+           uae_u8 j = inprec_pu8 ();
+           uae_u8 but = inprec_pu8 ();
+           uae_u8 vv = inprec_pu8 ();
+           inprec_pend ();
            oldbuttons[j] &= ~(1 << but);
            if (vv)
                oldbuttons[j] |= 1 << but;
diff --git a/main.c b/main.c
index f6a1d8eb6039da322865b17890794129984be984..b2add800ae8d2301787243827e4ddedb7c9d919a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -58,8 +58,7 @@ long int version = 256 * 65536L * UAEMAJOR + 65536L * UAEMINOR + UAESUBREV;
 
 struct uae_prefs currprefs, changed_prefs;
 
-int no_gui = 0;
-int joystickpresent = 0;
+int no_gui = 0, quit_to_gui = 0;
 int cloanto_rom = 0;
 int kickstart_rom = 1;
 
@@ -685,7 +684,7 @@ void leave_program (void)
     do_leave_program ();
 }
 
-static void real_main2 (int argc, TCHAR **argv)
+static int real_main2 (int argc, TCHAR **argv)
 {
 #if defined (JIT) && (defined (_WIN32) || defined (_WIN64)) && !defined (NO_WIN32_EXCEPTION_HANDLER)
     extern int EvalException (LPEXCEPTION_POINTERS blah, int n_except);
@@ -717,7 +716,7 @@ static void real_main2 (int argc, TCHAR **argv)
 
     if (!machdep_init ()) {
        restart_program = 0;
-       return;
+       return -1;
     }
 
     if (! setup_sound ()) {
@@ -738,8 +737,9 @@ static void real_main2 (int argc, TCHAR **argv)
        currprefs = changed_prefs;
        if (err == -1) {
            write_log (L"Failed to initialize the GUI\n");
+           return -1;
        } else if (err == -2) {
-           return;
+           return 1;
        }
     }
 
@@ -833,6 +833,7 @@ static void real_main2 (int argc, TCHAR **argv)
        // EvalException does the good stuff...
     }
 #endif
+    return 0;
 }
 
 void real_main (int argc, TCHAR **argv)
@@ -841,8 +842,11 @@ void real_main (int argc, TCHAR **argv)
     fetch_configurationpath (restart_config, sizeof (restart_config) / sizeof (TCHAR));
     _tcscat (restart_config, OPTIONSFILENAME);
     while (restart_program) {
+       int ret;
        changed_prefs = currprefs;
-       real_main2 (argc, argv);
+       ret = real_main2 (argc, argv);
+       if (ret == 0 && quit_to_gui)
+           restart_program = 1;
        leave_program ();
        quit_program = 0;
     }
index e487440f783583a9a2a490e5ebadccf72112cd21..8bcace9988b6494aef8a3c2a5b7aafa5ff392aed 100644 (file)
@@ -46,7 +46,7 @@ void moduleripper (void)
     size += currprefs.mbresmem_high_size;
     size += currprefs.z3fastmem_size;
     size += currprefs.z3fastmem2_size;
-    buf = p = (uae_u8*)xmalloc (size);
+    buf = p = xmalloc (size);
     if (!buf)
        return;
     memcpy (p, chipmemory, currprefs.chipmem_size);
index 67206fdb79d1ad9d84d190abd219a42933a85a52..45881e13629075394bf37d5d7b71a6ced907f8a3 100644 (file)
 static long samples, playchannel, intcount;
 static int record_enabled;
 int ahi_on;
-static TCHAR *sndptrmax, soundneutral, sndptr;
+static uae_u8 *sndptrmax;
+static uae_u8 soundneutral;
 
 static LPSTR lpData,sndptrout;
 extern uae_u32 chipmem_mask;
 unsigned int *sndbufrecpt;
-static TCHAR *ahisndbuffer, *sndrecbuffer;
+static uae_u8 *ahisndbuffer, *sndrecbuffer;
 static int ahisndbufsize, *ahisndbufpt, ahitweak;;
 int ahi_pollrate = 40;
 
index 7addb05d3d69a3d7d6dc347965c66d4ddb6b56d9..21130b81308b37428c94962a987f970bffa8aea8 100644 (file)
@@ -63,7 +63,7 @@ static void to_amiga_start (void)
     if (clipboard_debug) {
        debugwrite (L"clipboard_p2a", to_amiga, to_amiga_size);
     }
-    write_log (L"clipboard: to_amiga %08x\n", clipboard_data);
+    //write_log (L"clipboard: to_amiga %08x\n", clipboard_data);
     put_long (clipboard_data, to_amiga_size);
     uae_Signal (get_long (clipboard_data + 8), 1 << 13);
 }
index 5bb24c9ed6e242bfebcbc5b163897e8cf31e403e..39220b694726a2fda40b60f9fdbb316c30005037 100644 (file)
@@ -998,7 +998,7 @@ static void handle_rawinput_2 (RAWINPUT *raw)
        if (num == num_mouse)
            return;
 
-       if (isfocus () > 0) {
+       if (isfocus ()) {
            for (i = 0; i < (5 > did->buttons ? did->buttons : 5); i++) {
                if (rm->usButtonFlags & (3 << (i * 2)))
                    setmousebuttonstate (num, i, (rm->usButtonFlags & (1 << (i * 2))) ? 1 : 0);
@@ -1072,7 +1072,7 @@ static void handle_rawinput_2 (RAWINPUT *raw)
            inputdevice_do_keyboard (scancode, pressed);
        } else {
            scancode = keyhack (scancode, pressed, num);
-           if (scancode < 0 || isfocus () <= 0)
+           if (scancode < 0 || isfocus () == 0)
                return;
            di_keycodes[num][scancode] = pressed;
            if (stopoutput == 0)
@@ -1702,7 +1702,7 @@ static void read_mouse (void)
 #ifdef DI_DEBUG2
                write_log (L"MOUSE: %d OFF=%d DATA=%d STATE=%d\n", i, dimofs, data, state);
 #endif
-               if (istest || isfocus () > 0) {
+               if (istest || isfocus ()) {
                    for (k = 0; k < did->axles; k++) {
                        if (did->axismappings[k] == dimofs)
                            setmousestate (i, k, data, 0);
@@ -2133,7 +2133,7 @@ static void read_kb (void)
        }
        elements = DI_KBBUFFER;
        hr = IDirectInputDevice8_GetDeviceData (lpdi, sizeof(DIDEVICEOBJECTDATA), didod, &elements, 0);
-       if ((SUCCEEDED (hr) || hr == DI_BUFFEROVERFLOW) && isfocus () > 0) {
+       if ((SUCCEEDED (hr) || hr == DI_BUFFEROVERFLOW) && isfocus ()) {
            if (did->superdevice && (normalkb || rawkb))
                continue;
            for (j = 0; j < elements; j++) {
@@ -2298,7 +2298,7 @@ static void read_joystick (void)
        if (!did->acquired)
            continue;
        if (did->connection == DIDC_CAT) {
-           if (getjoystickstate (i) && isfocus () > 0) {
+           if (getjoystickstate (i) && isfocus ()) {
                /* only read CW state if it is really needed */
                uae_u8 cdir, cbuttons;
                if (catweasel_read_joystick (&cdir, &cbuttons)) {
@@ -2318,7 +2318,7 @@ static void read_joystick (void)
            continue;
        elements = DI_BUFFER;
        hr = IDirectInputDevice8_GetDeviceData (lpdi, sizeof (DIDEVICEOBJECTDATA), didod, &elements, 0);
-       if ((SUCCEEDED (hr) || hr == DI_BUFFEROVERFLOW) && isfocus () > 0) {
+       if ((SUCCEEDED (hr) || hr == DI_BUFFEROVERFLOW) && isfocus ()) {
            for (j = 0; j < elements; j++) {
                int dimofs = didod[j].dwOfs;
                int data = didod[j].dwData;
index d78773dd1ebf1053349f053421cae5cbe4a60df8..ec1da0861867bdb7de56834aa0c0a5ea0232cf74 100644 (file)
@@ -319,7 +319,7 @@ int D3D_canshaders (void)
     if (yesno > 0)
        return 1;
     yesno = -1;
-    h = LoadLibrary (L"d3dx9_40.dll");
+    h = LoadLibrary (L"d3dx9_41.dll");
     if (h != NULL) {
        FreeLibrary (h);
        d3dx = Direct3DCreate9 (D3D_SDK_VERSION);
@@ -1194,16 +1194,15 @@ int D3D_needreset (void)
 
 void D3D_clear (void)
 {
+    int i;
     HRESULT hr;
     hr = IDirect3DDevice9_TestCooperativeLevel (d3ddev);
     if (FAILED (hr))
        return;
-    IDirect3DDevice9_Clear (d3ddev, 0L, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0L);
-    hr = IDirect3DDevice9_BeginScene (d3ddev);
-    if (FAILED (hr))
-       return;
-    IDirect3DDevice9_EndScene (d3ddev);
-    IDirect3DDevice9_Present (d3ddev, 0, 0, 0 ,0);
+    for (i = 0; i < 2; i++) {
+       IDirect3DDevice9_Clear (d3ddev, 0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0L);
+       IDirect3DDevice9_Present (d3ddev, NULL, NULL, NULL, NULL);
+    }
 }
 
 static void D3D_render2 (int clear)
@@ -1219,13 +1218,17 @@ static void D3D_render2 (int clear)
     }
     setupscenecoords ();
     settransform ();
-    hr = IDirect3DDevice9_BeginScene (d3ddev);
     if (clear || needclear) {
-       hr = IDirect3DDevice9_Clear (d3ddev, 0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L );
-       if (FAILED (hr))
-           write_log (L"IDirect3DDevice9_Clear() failed: %s\n", D3D_ErrorString (hr));
+       int i;
+       for (i = 0; i < 2; i++) {
+           hr = IDirect3DDevice9_Clear (d3ddev, 0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0L );
+           if (FAILED (hr))
+               write_log (L"IDirect3DDevice9_Clear() failed: %s\n", D3D_ErrorString (hr));
+           IDirect3DDevice9_Present (d3ddev, NULL, NULL, NULL, NULL);
+       }
        needclear = 0;
     }
+    hr = IDirect3DDevice9_BeginScene (d3ddev);
     if (psActive) {
         UINT uPasses, uPass;
        LPDIRECT3DSURFACE9 lpRenderTarget;
@@ -1292,7 +1295,7 @@ static void D3D_render2 (int clear)
     }
 
     hr = IDirect3DDevice9_EndScene (d3ddev);
-    hr = IDirect3DDevice9_Present (d3ddev, 0, 0, 0 ,0);
+    hr = IDirect3DDevice9_Present (d3ddev, NULL, NULL, NULL, NULL);
 }
 
 void D3D_render (void)
index cecd26264258c4d1cfa5055b38aa7b8ab1ad2682..8593ed2eb4fc6de9ee79c7846bd4752018394f6f 100644 (file)
@@ -1167,7 +1167,7 @@ static int do_blitrect_frame_buffer (struct RenderInfo *ri, struct
        write_log (L"WARNING - BlitRect() has mask 0x%x with Bpp %d.\n", mask, Bpp);
     }
 
-    P96TRACE (("(%dx%d)=(%dx%d)=(%dx%d)=%d\n", srcx, srcy, dstx, dsty, width, height, opcode));
+    P96TRACE ((L"(%dx%d)=(%dx%d)=(%dx%d)=%d\n", srcx, srcy, dstx, dsty, width, height, opcode));
     if (mask == 0xFF || Bpp > 1) {
 
        if(opcode == BLIT_SRC) {
@@ -1329,7 +1329,7 @@ static uae_u32 REGPARAM2 picasso_SetSpriteColor (TrapContext *ctx)
     if (idx >= 4)
        return 0;
     cursorrgb[idx] = (red << 16) | (green << 8) | (blue << 0);
-    P96TRACE_SPR (("SetSpriteColor(%08x,%d:%02X%02X%02X). %x\n", bi, idx, red, green, blue, bi + PSSO_BoardInfo_MousePens));
+    P96TRACE_SPR ((L"SetSpriteColor(%08x,%d:%02X%02X%02X). %x\n", bi, idx, red, green, blue, bi + PSSO_BoardInfo_MousePens));
     return 1;
 }
 
@@ -1705,7 +1705,7 @@ static uae_u32 setspriteimage (uaecptr bi)
        doubledsprite = 1;
     updatesprcolors ();
 
-    P96TRACE_SPR (("SetSpriteImage(%08x,%08x,w=%d,h=%d,%d/%d,%08x)\n",
+    P96TRACE_SPR ((L"SetSpriteImage(%08x,%08x,w=%d,h=%d,%d/%d,%08x)\n",
        bi, get_long (bi + PSSO_BoardInfo_MouseImage), w, h,
        hiressprite - 1, doubledsprite, bi + PSSO_BoardInfo_MouseImage));
 
@@ -1780,7 +1780,7 @@ static uae_u32 setspriteimage (uaecptr bi)
                }
                IDirectDrawSurface_Unlock (dxdata.cursorsurface1, NULL);
                if (!different) {
-                   P96TRACE_SPR (("sprite was same as previously\n"));
+                   P96TRACE_SPR ((L"sprite was same as previously\n"));
                    ret = 1;
                    goto end;
                }
@@ -1814,7 +1814,7 @@ static uae_u32 setspriteimage (uaecptr bi)
     ret = 1;
     reloadcursor = 0;
     cursorok = TRUE;
-    P96TRACE_SPR (("hardware sprite created\n"));
+    P96TRACE_SPR ((L"hardware sprite created\n"));
 end:
     xfree (tmpbuf);
     return ret;
@@ -1876,7 +1876,7 @@ static uae_u32 REGPARAM2 picasso_SetSprite (TrapContext *ctx)
        cursordeactivate = 2;
     }
     result = 1;
-    P96TRACE_SPR (("SetSprite: %d\n", activate));
+    P96TRACE_SPR ((L"SetSprite: %d\n", activate));
     return result;
 }
 
@@ -2575,7 +2575,7 @@ static uae_u32 REGPARAM2 picasso_SetColorArray (TrapContext *ctx)
     uaecptr clut = boardinfo + PSSO_BoardInfo_CLUT;
     if (updateclut (clut, start, count))
        full_refresh = 1;
-    P96TRACE(("SetColorArray(%d,%d)\n", start, count));
+    P96TRACE((L"SetColorArray(%d,%d)\n", start, count));
     return 1;
 }
 
@@ -2593,7 +2593,7 @@ static uae_u32 REGPARAM2 picasso_SetDAC (TrapContext *ctx)
 /* Fill in some static UAE related structure about this new DAC setting
     * Lets us keep track of what pixel format the Amiga is thinking about in our frame-buffer */
 
-    P96TRACE(("SetDAC()\n"));
+    P96TRACE((L"SetDAC()\n"));
     return 1;
 }
 
@@ -2651,7 +2651,7 @@ static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx)
     picasso96_state.GC_Depth = get_byte (modeinfo + PSSO_ModeInfo_Depth);
     picasso96_state.GC_Flags = get_byte (modeinfo + PSSO_ModeInfo_Flags);
 
-    P96TRACE(("SetGC(%d,%d,%d,%d)\n", picasso96_state.Width, picasso96_state.Height, picasso96_state.GC_Depth, border));
+    P96TRACE((L"SetGC(%d,%d,%d,%d)\n", picasso96_state.Width, picasso96_state.Height, picasso96_state.GC_Depth, border));
     set_gc_called = 1;
     picasso96_state.HostAddress = NULL;
     init_picasso_screen ();
@@ -2744,7 +2744,7 @@ static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx)
 
     full_refresh = 1;
     set_panning_called = 1;
-    P96TRACE(("SetPanning(%d, %d, %d) Start 0x%x, BPR %d Bpp %d RGBF %d\n",
+    P96TRACE((L"SetPanning(%d, %d, %d) Start 0x%x, BPR %d Bpp %d RGBF %d\n",
        Width, picasso96_state.XOffset, picasso96_state.YOffset,
        start_of_screen, picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, picasso96_state.RGBFormat));
     init_picasso_screen ();
@@ -2810,7 +2810,7 @@ static uae_u32 REGPARAM2 picasso_InvertRect (TrapContext *ctx)
     if (NOBLITTER)
        return 0;
     if (CopyRenderInfoStructureA2U (renderinfo, &ri)) {
-       P96TRACE(("InvertRect %dbpp 0x%lx\n", Bpp, (long)mask));
+       P96TRACE((L"InvertRect %dbpp 0x%lx\n", Bpp, (long)mask));
 
        if (mask != 0xFF && Bpp > 1)
            mask = 0xFF;
@@ -2861,7 +2861,7 @@ static uae_u32 REGPARAM2 picasso_FillRect (TrapContext *ctx)
     if (CopyRenderInfoStructureA2U (renderinfo, &ri) && Y != 0xFFFF) {
        Bpp = GetBytesPerPixel (RGBFormat);
 
-       P96TRACE(("FillRect(%d, %d, %d, %d) Pen 0x%x BPP %d BPR %d Mask 0x%x\n",
+       P96TRACE((L"FillRect(%d, %d, %d, %d) Pen 0x%x BPP %d BPR %d Mask 0x%x\n",
            X, Y, Width, Height, Pen, Bpp, ri.BytesPerRow, Mask));
 
        if(Bpp > 1)
@@ -3030,7 +3030,7 @@ static uae_u32 REGPARAM2 picasso_BlitRect (TrapContext *ctx)
 
     if (NOBLITTER_BLIT)
        return 0;
-    P96TRACE(("BlitRect(%d, %d, %d, %d, %d, %d, 0x%x)\n", srcx, srcy, dstx, dsty, width, height, Mask));
+    P96TRACE((L"BlitRect(%d, %d, %d, %d, %d, %d, 0x%x)\n", srcx, srcy, dstx, dsty, width, height, Mask));
     result = BlitRect (renderinfo, (uaecptr)NULL, srcx, srcy, dstx, dsty, width, height, Mask, BLIT_SRC);
     return result;
 }
@@ -3071,7 +3071,7 @@ static uae_u32 REGPARAM2 picasso_BlitRectNoMaskComplete (TrapContext *ctx)
     if (NOBLITTER_BLIT)
        return 0;
 
-    P96TRACE(("BlitRectNoMaskComplete() op 0x%02x, %08x:(%4d,%4d) --> %08x:(%4d,%4d), wh(%4d,%4d)\n",
+    P96TRACE((L"BlitRectNoMaskComplete() op 0x%02x, %08x:(%4d,%4d) --> %08x:(%4d,%4d), wh(%4d,%4d)\n",
        OpCode, get_long (srcri + PSSO_RenderInfo_Memory), srcx, srcy, get_long (dstri + PSSO_RenderInfo_Memory), dstx, dsty, width, height));
     result = BlitRect (srcri, dstri, srcx, srcy, dstx, dsty, width, height, 0xFF, OpCode);
     return result;
@@ -3165,7 +3165,7 @@ static uae_u32 REGPARAM2 picasso_BlitPattern (TrapContext *ctx)
 
        if(result) {
            uae_u32 fgpen, bgpen;
-           P96TRACE(("BlitPattern() xy(%d,%d), wh(%d,%d) draw 0x%x, off(%d,%d), ph %d\n",
+           P96TRACE((L"BlitPattern() xy(%d,%d), wh(%d,%d) draw 0x%x, off(%d,%d), ph %d\n",
            X, Y, W, H, pattern.DrawMode, pattern.XOffset, pattern.YOffset, 1 << pattern.Size));
 
 #if P96TRACING_ENABLED
@@ -3333,7 +3333,7 @@ static uae_u32 REGPARAM2 picasso_BlitTemplate (TrapContext *ctx)
        if(result) {
            uae_u32 fgpen, bgpen;
 
-           P96TRACE(("BlitTemplate() xy(%d,%d), wh(%d,%d) draw 0x%x fg 0x%x bg 0x%x \n",
+           P96TRACE((L"BlitTemplate() xy(%d,%d), wh(%d,%d) draw 0x%x fg 0x%x bg 0x%x \n",
                X, Y, W, H, tmp.DrawMode, tmp.FgPen, tmp.BgPen));
 
            bitoffset = tmp.XOffset % 8;
@@ -3469,7 +3469,7 @@ static uae_u32 REGPARAM2 picasso_SetDisplay (TrapContext *ctx)
 {
     struct regstruct *regs = &ctx->regs;
     uae_u32 state = m68k_dreg (regs, 0);
-    P96TRACE (("SetDisplay(%d)\n", state));
+    P96TRACE ((L"SetDisplay(%d)\n", state));
     return !state;
 }
 
@@ -3625,9 +3625,9 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Chunky (TrapContext *ctx)
        write_log (L"ERROR - BlitPlanar2Chunky() has minterm 0x%x, which I don't handle. Using fall-back routine.\n",
            minterm);
     } else if (CopyRenderInfoStructureA2U (ri, &local_ri) && CopyBitMapStructureA2U (bm, &local_bm)) {
-       P96TRACE(("BlitPlanar2Chunky(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n",
+       P96TRACE((L"BlitPlanar2Chunky(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n",
            srcx, srcy, dstx, dsty, width, height, minterm, mask, local_bm.Depth));
-       P96TRACE(("P2C - BitMap has %d BPR, %d rows\n", local_bm.BytesPerRow, local_bm.Rows));
+       P96TRACE((L"P2C - BitMap has %d BPR, %d rows\n", local_bm.BytesPerRow, local_bm.Rows));
        PlanarToChunky (&local_ri, &local_bm, srcx, srcy, dstx, dsty, width, height, mask);
        result = 1;
     }
@@ -3770,7 +3770,7 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Direct (TrapContext *ctx)
     if (CopyRenderInfoStructureA2U (ri, &local_ri) && CopyBitMapStructureA2U (bm, &local_bm)) {
        Mask = 0xFF;
        CopyColorIndexMappingA2U (cim, &local_cim, GetBytesPerPixel (local_ri.RGBFormat));
-       P96TRACE(("BlitPlanar2Direct(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n",
+       P96TRACE((L"BlitPlanar2Direct(%d, %d, %d, %d, %d, %d) Minterm 0x%x, Mask 0x%x, Depth %d\n",
            srcx, srcy, dstx, dsty, width, height, minterm, Mask, local_bm.Depth));
        PlanarToDirect (&local_ri, &local_bm, srcx, srcy, dstx, dsty, width, height, Mask, &local_cim);
        result = 1;
@@ -3782,7 +3782,7 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
 {
     uae_u8 *src2 = src + y * picasso96_state.BytesPerRow;
     uae_u8 *dst2 = dst + y * picasso_vidinfo.rowbytes;
-    int endx = x + width;
+    int endx = x + width, endx4;
     int dstpix = picasso_vidinfo.pixbytes;
     int srcpix = picasso96_state.BytesPerPixel;
 
@@ -3791,6 +3791,8 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
         return;
     }
 
+    endx4 = endx & ~3;
+
     switch (picasso_convert)
     {
        /* Picasso96mode == Nativemode */
@@ -3841,7 +3843,12 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
        case RGBFB_R5G5B5_32:
        case RGBFB_B5G6R5PC_32:
        case RGBFB_B5G5R5PC_32:
-           while (x < endx) {
+       {
+           while ((x & 3) && x < endx) {
+               ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]];
+               x++;
+           }
+           while (x < endx4) {
                ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]];
                x++;
                ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]];
@@ -3851,6 +3858,11 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
                ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]];
                x++;
            }
+           while (x < endx) {
+               ((uae_u32*)dst2)[x] = p96_rgbx16[((uae_u16*)src2)[x]];
+               x++;
+           }
+       }
        break;
 
        /* 16/15bit->16bit */
@@ -3859,7 +3871,12 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
        case RGBFB_R5G5B5_16:
        case RGBFB_B5G5R5PC_16:
        case RGBFB_B5G6R5PC_16:
-           while (x < endx) {
+       {
+           while ((x & 3) && x < endx) {
+               ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]];
+               x++;
+           }
+           while (x < endx4) {
                ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]];
                x++;
                ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]];
@@ -3869,6 +3886,11 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
                ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]];
                x++;
            }
+           while (x < endx) {
+               ((uae_u16*)dst2)[x] = (uae_u16)p96_rgbx16[((uae_u16*)src2)[x]];
+               x++;
+           }
+       }
        break;
 
        /* 24bit->16bit */
@@ -3927,7 +3949,12 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
 
        /* 8bit->32bit */
        case RGBFB_CLUT_RGBFB_32:
-           while (x < endx) {
+       {
+           while ((x & 3) && x < endx) {
+               ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
+               x++;
+           }
+           while (x < endx4) {
                ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
                x++;
                ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
@@ -3937,11 +3964,21 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
                ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
                x++;
            }
+           while (x < endx) {
+               ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
+               x++;
+           }
+       }
        break;
 
        /* 8bit->16bit */
        case RGBFB_CLUT_RGBFB_16:
-           while (x < endx) {
+       {
+           while ((x & 3) && x < endx) {
+               ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
+               x++;
+           }
+           while (x < endx4) {
                ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
                x++;
                ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
@@ -3951,6 +3988,11 @@ STATIC_INLINE void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width)
                ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
                x++;
            }
+           while (x < endx) {
+               ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]];
+               x++;
+           }
+       }
        break;
     }
 }
index 63d342f8f00a305e11fe7aa3c29a0e238d2cd640..cfb26c12b871b9d8de92e70fcfc454e4af029d54 100644 (file)
 int sound_debug = 0;
 int sound_mode_skip = 0;
 
-static int devicetype;
-static int obtainedfreq;
 static int have_sound;
-static int paused;
-static int mute;
 
 #define SND_MAX_BUFFER2 524288
 #define SND_MAX_BUFFER 8192
@@ -63,46 +59,64 @@ uae_u16 sndbuffer[SND_MAX_BUFFER];
 uae_u16 *sndbufpt;
 int sndbufsize;
 
-static int max_sndbufsize, snd_configsize, dsoundbuf, samplesize;
-static int snd_writeoffset, snd_maxoffset, snd_totalmaxoffset_uf, snd_totalmaxoffset_of;
-static int waiting_for_buffer;
-
 static uae_sem_t sound_sem, sound_init_sem;
 
 struct sound_device sound_devices[MAX_SOUND_DEVICES];
 struct sound_device record_devices[MAX_SOUND_DEVICES];
 static int num_sound_devices, num_record_devices;
 
-// directsound
-
-static LPDIRECTSOUND8 lpDS;
-static LPDIRECTSOUNDBUFFER8 lpDSBsecondary;
-static DWORD writepos;
-
+struct sound_data
+{
+    int waiting_for_buffer;
+    int devicetype;
+    int obtainedfreq;
+    int paused;
+    int mute;
+
+    // directsound
+
+    LPDIRECTSOUND8 lpDS;
+    LPDIRECTSOUNDBUFFER8 lpDSBsecondary;
+    DWORD writepos;
+    int dsoundbuf;
+    int safedist;
+    int snd_writeoffset;
+    int snd_maxoffset;
+    int snd_totalmaxoffset_uf;
+    int snd_totalmaxoffset_of;
+    int max_sndbufsize;
+    int snd_configsize;
+    int samplesize;
 
 // openal
 
-#define AL_BUFFERS 2
-static ALCdevice *al_dev;
-static ALCcontext *al_ctx;
-static ALuint al_Buffers[AL_BUFFERS];
-static ALuint al_Source;
-static int al_toggle;
-static DWORD al_format;
-static uae_u8 *al_bigbuffer;
-static int al_bufsize, al_offset;
+    #define AL_BUFFERS 2
+    ALCdevice *al_dev;
+    ALCcontext *al_ctx;
+    ALuint al_Buffers[AL_BUFFERS];
+    ALuint al_Source;
+    int al_toggle;
+    DWORD al_format;
+    uae_u8 *al_bigbuffer;
+    int al_bufsize, al_offset;
 
 
 // portaudio
 
-static volatile int patoggle;
-static volatile int pacounter;
-static uae_u8 *pasoundbuffer[2];
-static int pasndbufsize;
-static int paframesperbuffer;
-static PaStream *pastream;
-static HANDLE paevent;
+    volatile int patoggle;
+    volatile int pacounter;
+    uae_u8 *pasoundbuffer[2];
+    int pasndbufsize;
+    int paframesperbuffer;
+    PaStream *pastream;
+    HANDLE paevent;
+    int opacounter;
+
+
+};
 
+static struct sound_data sdpaula;
+static struct sound_data *sdp = &sdpaula;
 
 int setup_sound (void)
 {
@@ -110,111 +124,112 @@ int setup_sound (void)
     return 1;
 }
 
-static int isvsync(void)
+static int isvsync (void)
 {
     return currprefs.gfx_avsync && currprefs.gfx_afullscreen;
 }
 
 int scaled_sample_evtime_orig;
-static int lastfreq;
 void update_sound (int freq)
+
 {
+    static int lastfreq;
     if (freq < 0)
        freq = lastfreq;
     lastfreq = freq;
     if (have_sound) {
        if (isvsync () || currprefs.chipset_refreshrate) {
            if (currprefs.ntscmode)
-               scaled_sample_evtime_orig = (unsigned long)(MAXHPOS_NTSC * MAXVPOS_NTSC * freq * CYCLE_UNIT + obtainedfreq - 1) / obtainedfreq;
+               scaled_sample_evtime_orig = (unsigned long)(MAXHPOS_NTSC * MAXVPOS_NTSC * freq * CYCLE_UNIT + sdp->obtainedfreq - 1) / sdp->obtainedfreq;
            else
-               scaled_sample_evtime_orig = (unsigned long)(MAXHPOS_PAL * MAXVPOS_PAL * freq * CYCLE_UNIT + obtainedfreq - 1) / obtainedfreq;
+               scaled_sample_evtime_orig = (unsigned long)(MAXHPOS_PAL * MAXVPOS_PAL * freq * CYCLE_UNIT + sdp->obtainedfreq - 1) / sdp->obtainedfreq;
        } else {
-           scaled_sample_evtime_orig = (unsigned long)(312.0 * 50 * CYCLE_UNIT / (obtainedfreq  / 227.0));
+           scaled_sample_evtime_orig = (unsigned long)(312.0 * 50 * CYCLE_UNIT / (sdp->obtainedfreq  / 227.0));
        }
        scaled_sample_evtime = scaled_sample_evtime_orig;
     }
 }
 
-static void clearbuffer_ds (void)
+static void clearbuffer_ds (struct sound_data *sd)
 {
     void *buffer;
     DWORD size;
 
-    HRESULT hr = IDirectSoundBuffer_Lock (lpDSBsecondary, 0, dsoundbuf, &buffer, &size, NULL, NULL, 0);
+    HRESULT hr = IDirectSoundBuffer_Lock (sd->lpDSBsecondary, 0, sd->dsoundbuf, &buffer, &size, NULL, NULL, 0);
     if (hr == DSERR_BUFFERLOST) {
-       IDirectSoundBuffer_Restore (lpDSBsecondary);
-       hr = IDirectSoundBuffer_Lock (lpDSBsecondary, 0, dsoundbuf, &buffer, &size, NULL, NULL, 0);
+       IDirectSoundBuffer_Restore (sd->lpDSBsecondary);
+       hr = IDirectSoundBuffer_Lock (sd->lpDSBsecondary, 0, sd->dsoundbuf, &buffer, &size, NULL, NULL, 0);
     }
     if (FAILED (hr)) {
        write_log (L"SOUND: failed to Lock sound buffer (clear): %s\n", DXError (hr));
        return;
     }
     memset (buffer, 0, size);
-    IDirectSoundBuffer_Unlock (lpDSBsecondary, buffer, size, NULL, 0);
+    IDirectSoundBuffer_Unlock (sd->lpDSBsecondary, buffer, size, NULL, 0);
 }
 
-static void clearbuffer (void)
+static void clearbuffer (struct sound_data *sd)
 {
-    if (devicetype == SOUND_DEVICE_DS)
-       clearbuffer_ds ();
+    if (sdp->devicetype == SOUND_DEVICE_DS)
+       clearbuffer_ds (sdp);
 }
 
-static void pause_audio_ds (void)
+static void pause_audio_ds (struct sound_data *sd)
 {
     HRESULT hr;
 
-    waiting_for_buffer = 0;
-    hr = IDirectSoundBuffer_Stop (lpDSBsecondary);
+    sd->waiting_for_buffer = 0;
+    hr = IDirectSoundBuffer_Stop (sd->lpDSBsecondary);
     if (FAILED (hr))
-       write_log (L"SOUND: DirectSoundBuffer_Stop failed, %s\n", DXError(hr));
-    hr = IDirectSoundBuffer_SetCurrentPosition (lpDSBsecondary, 0);
+       write_log (L"SOUND: DirectSoundBuffer_Stop failed, %s\n", DXError (hr));
+    hr = IDirectSoundBuffer_SetCurrentPosition (sd->lpDSBsecondary, 0);
     if (FAILED (hr))
        write_log (L"SOUND: DirectSoundBuffer_SetCurretPosition failed, %s\n", DXError (hr));
-    clearbuffer ();
+    clearbuffer (sd);
 }
-static void resume_audio_ds (void)
+static void resume_audio_ds (struct sound_data *sd)
 {
-    paused = 0;
-    clearbuffer ();
-    waiting_for_buffer = 1;
+    sd->paused = 0;
+    clearbuffer (sd);
+    sd->waiting_for_buffer = 1;
 }
-static void pause_audio_pa (void)
+static void pause_audio_pa (struct sound_data *sd)
 {
-    PaError err = Pa_StopStream (pastream);
+    PaError err = Pa_StopStream (sd->pastream);
     if (err != paNoError)
        write_log (L"SOUND: Pa_StopStream() error %d (%s)\n", err, Pa_GetErrorText (err));
 }
-static void resume_audio_pa (void)
+static void resume_audio_pa (struct sound_data *sd)
 {
-    PaError err = Pa_StartStream (pastream);
+    PaError err = Pa_StartStream (sd->pastream);
     if (err != paNoError)
        write_log (L"SOUND: Pa_StartStream() error %d (%s)\n", err, Pa_GetErrorText (err));
-    paused = 0;
+    sd->paused = 0;
 }
-static void pause_audio_al (void)
+static void pause_audio_al (struct sound_data *sd)
 {
-    waiting_for_buffer = 0;
-    alSourcePause (al_Source);
+    sd->waiting_for_buffer = 0;
+    alSourcePause (sd->al_Source);
 }
-static void resume_audio_al (void)
+static void resume_audio_al (struct sound_data *sd)
 {
-    waiting_for_buffer = 1;
-    al_offset = 0;
+    sd->waiting_for_buffer = 1;
+    sd->al_offset = 0;
 }
 
-static int restore_ds (DWORD hr)
+static int restore_ds (struct sound_data *sd, DWORD hr)
 {
     if (hr != DSERR_BUFFERLOST)
        return 0;
     if (sound_debug)
        write_log (L"SOUND: sound buffer lost\n");
-    hr = IDirectSoundBuffer_Restore (lpDSBsecondary);
-    if (FAILED(hr)) {
+    hr = IDirectSoundBuffer_Restore (sd->lpDSBsecondary);
+    if (FAILED (hr)) {
        write_log (L"SOUND: restore failed %s\n", DXError (hr));
        return 1;
     }
-    pause_audio_ds ();
-    resume_audio_ds ();
+    pause_audio_ds (sd);
+    resume_audio_ds (sd);
     return 1;
 }
 
@@ -230,50 +245,51 @@ static double getqpf (void)
     return (qpfc2.QuadPart - qpfc.QuadPart) / (qpf.QuadPart / 1000.0);
 }
 
-static void close_audio_ds (void)
+static void close_audio_ds (struct sound_data *sd)
 {
-    if (lpDSBsecondary)
-       IDirectSound_Release (lpDSBsecondary);
-    lpDSBsecondary = 0;
+    if (sd->lpDSBsecondary)
+       IDirectSound_Release (sd->lpDSBsecondary);
+    sd->lpDSBsecondary = 0;
 #ifdef USE_PRIMARY_BUFFER
-    if (lpDSBprimary)
-       IDirectSound_Release (lpDSBprimary);
-    lpDSBprimary = 0;
+    if (sd->lpDSBprimary)
+       IDirectSound_Release (sd->lpDSBprimary);
+    sd->lpDSBprimary = 0;
 #endif
-    if (lpDS) {
-       IDirectSound_Release (lpDS);
+    if (sd->lpDS) {
+       IDirectSound_Release (sd->lpDS);
        write_log (L"SOUND: DirectSound driver freed\n");
     }
-    lpDS = 0;
+    sd->lpDS = 0;
 }
 
 extern HWND hMainWnd;
-extern void setvolume_ahi(LONG);
+extern void setvolume_ahi (LONG);
 void set_volume (int volume, int mute)
 {
-    if (devicetype == SOUND_DEVICE_AL) {
+    struct sound_data *sd = sdp;
+    if (sd->devicetype == SOUND_DEVICE_AL) {
        float vol = 0.0;
        if (volume < 100 && !mute)
            vol = (100 - volume) / 100.0;
-       alSourcef (al_Source, AL_GAIN, vol);
-    } else if (devicetype == SOUND_DEVICE_DS) {
+       alSourcef (sd->al_Source, AL_GAIN, vol);
+    } else if (sd->devicetype == SOUND_DEVICE_DS) {
        HRESULT hr;
        LONG vol = DSBVOLUME_MIN;
        if (volume < 100 && !mute)
            vol = (LONG)((DSBVOLUME_MIN / 2) + (-DSBVOLUME_MIN / 2) * log (1 + (2.718281828 - 1) * (1 - volume / 100.0)));
-       hr = IDirectSoundBuffer_SetVolume (lpDSBsecondary, vol);
+       hr = IDirectSoundBuffer_SetVolume (sd->lpDSBsecondary, vol);
        if (FAILED (hr))
            write_log (L"SOUND: SetVolume(%d) failed: %s\n", vol, DXError (hr));
        setvolume_ahi (vol);
     }
 }
 
-static void recalc_offsets (void)
+static void recalc_offsets (struct sound_data *sd)
 {
-    snd_writeoffset = max_sndbufsize * 5 / 8;
-    snd_maxoffset = max_sndbufsize;
-    snd_totalmaxoffset_of = max_sndbufsize + (dsoundbuf - max_sndbufsize) * 3 / 9;
-    snd_totalmaxoffset_uf = max_sndbufsize + (dsoundbuf - max_sndbufsize) * 7 / 9;
+    sd->snd_writeoffset = sd->max_sndbufsize * 5 / 8;
+    sd->snd_maxoffset = sd->max_sndbufsize;
+    sd->snd_totalmaxoffset_of = sd->max_sndbufsize + (sd->dsoundbuf - sd->max_sndbufsize) * 3 / 9;
+    sd->snd_totalmaxoffset_uf = sd->max_sndbufsize + (sd->dsoundbuf - sd->max_sndbufsize) * 7 / 9;
 }
 
 const static GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010,
@@ -331,7 +347,7 @@ DWORD fillsupportedmodes (LPDIRECTSOUND8 lpDS, int freq, struct dsaudiomodes *ds
            wavfmt.dwChannelMask = rn[round];
            memset (&sound_buffer, 0, sizeof (sound_buffer));
            sound_buffer.dwSize = sizeof (sound_buffer);
-           sound_buffer.dwBufferBytes = dsoundbuf;
+           sound_buffer.dwBufferBytes = sdp->dsoundbuf;
            sound_buffer.lpwfxFormat = &wavfmt.Format;
            sound_buffer.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
            sound_buffer.dwFlags |= DSBCAPS_CTRLVOLUME;
@@ -349,15 +365,13 @@ DWORD fillsupportedmodes (LPDIRECTSOUND8 lpDS, int freq, struct dsaudiomodes *ds
 }
 
 
-static void finish_sound_buffer_pa (void)
+static void finish_sound_buffer_pa (struct sound_data *sd)
 {
-    static int opacounter;
-
-    while (opacounter == pacounter && pastream && !paused)
-       WaitForSingleObject (paevent, 10);
-    ResetEvent (paevent);
-    opacounter = pacounter;
-    memcpy (pasoundbuffer[patoggle], sndbuffer, sndbufsize);
+    while (sd->opacounter == sd->pacounter && sd->pastream && !sd->paused)
+       WaitForSingleObject (sd->paevent, 10);
+    ResetEvent (sd->paevent);
+    sd->opacounter = sd->pacounter;
+    memcpy (sd->pasoundbuffer[sd->patoggle], sndbuffer, sndbufsize);
 }
 
 static int portAudioCallback (const void *inputBuffer, void *outputBuffer,
@@ -366,32 +380,38 @@ static int portAudioCallback (const void *inputBuffer, void *outputBuffer,
                            PaStreamCallbackFlags statusFlags,
                            void *userData)
 {
-    memcpy (outputBuffer, pasoundbuffer[patoggle], sndbufsize);
-    patoggle ^= 1;
-    pacounter++;
-    SetEvent (paevent);
+    struct sound_data *sd = userData;
+
+    if (framesPerBuffer != sndbufsize / (get_audio_nativechannels () * 2)) {
+       write_log (L"%d <> %d\n", framesPerBuffer, sndbufsize / (get_audio_nativechannels () * 2));
+    } else {
+       memcpy (outputBuffer, sd->pasoundbuffer[sd->patoggle], sndbufsize);
+    }
+    sd->patoggle ^= 1;
+    sd->pacounter++;
+    SetEvent (sd->paevent);
     return paContinue;
 }
 
-static void close_audio_pa (void)
+static void close_audio_pa (struct sound_data *sd)
 {
     int i;
 
-    if (pastream)
-       Pa_CloseStream (pastream);
-    pastream = NULL;
+    if (sd->pastream)
+       Pa_CloseStream (sd->pastream);
+    sd->pastream = NULL;
     for (i = 0; i < 2; i++) {
-       xfree (pasoundbuffer[i]);
-       pasoundbuffer[i] = NULL;
+       xfree (sd->pasoundbuffer[i]);
+       sd->pasoundbuffer[i] = NULL;
     }
-    if (paevent) {
-       SetEvent (paevent);
-       CloseHandle (paevent);
+    if (sd->paevent) {
+       SetEvent (sd->paevent);
+       CloseHandle (sd->paevent);
     }
-    paevent = NULL;
+    sd->paevent = NULL;
 }
 
-static int open_audio_pa (int size)
+static int open_audio_pa (struct sound_data *sd, int size)
 {
     int i;
     int freq = currprefs.sound_freq;
@@ -401,9 +421,9 @@ static int open_audio_pa (int size)
     PaStreamParameters p;
     PaError err;
 
-    paframesperbuffer = size;
+    sd->paframesperbuffer = size;
     sndbufsize = size * ch * 2;
-    devicetype = SOUND_DEVICE_PA;
+    sdp->devicetype = SOUND_DEVICE_PA;
     memset (&p, 0, sizeof p);
     p.channelCount = ch;
     p.device = dev;
@@ -435,97 +455,97 @@ static int open_audio_pa (int size)
        write_log (L"SOUND: sound format not supported\n");
        goto end;
     }
-    err = Pa_OpenStream (&pastream, NULL, &p, freq, paframesperbuffer, paNoFlag, portAudioCallback, NULL);
+    err = Pa_OpenStream (&sd->pastream, NULL, &p, freq, sd->paframesperbuffer, paNoFlag, portAudioCallback, sd);
     if (err != paNoError) {
        write_log (L"SOUND: Pa_OpenStream() error %d (%s)\n", err, Pa_GetErrorText (err));
        goto end;
     }
-    paevent = CreateEvent (NULL, FALSE, FALSE, NULL);
+    sd->paevent = CreateEvent (NULL, FALSE, FALSE, NULL);
     for (i = 0; i < 2; i++)
-       pasoundbuffer[i] = xcalloc (sndbufsize, 1);
+       sd->pasoundbuffer[i] = xcalloc (sndbufsize, 1);
     return 1;
 end:
-    pastream = NULL;
-    close_audio_pa ();
+    sd->pastream = NULL;
+    close_audio_pa (sd);
     return 0;
 }
 
-static void close_audio_al (void)
+static void close_audio_al (struct sound_data *sd)
 {
     int i;
 
-    alDeleteSources (1, &al_Source);
-    al_Source = 0;
-    alDeleteBuffers (AL_BUFFERS, al_Buffers);
+    alDeleteSources (1, &sd->al_Source);
+    sd->al_Source = 0;
+    alDeleteBuffers (AL_BUFFERS, sd->al_Buffers);
     alcMakeContextCurrent (NULL);
-    if (al_ctx)
-       alcDestroyContext (al_ctx);
-    al_ctx = NULL;
-    if (al_dev)
-        alcCloseDevice (al_dev);
-    al_dev = NULL;
+    if (sd->al_ctx)
+       alcDestroyContext (sd->al_ctx);
+    sd->al_ctx = NULL;
+    if (sd->al_dev)
+        alcCloseDevice (sd->al_dev);
+    sd->al_dev = NULL;
     for (i = 0; i < AL_BUFFERS; i++) {
-       al_Buffers[i] = 0;
+       sd->al_Buffers[i] = 0;
     }
-    xfree (al_bigbuffer);
-    al_bigbuffer = NULL;
+    xfree (sd->al_bigbuffer);
+    sd->al_bigbuffer = NULL;
 }
 
-static int open_audio_al (int size)
+static int open_audio_al (struct sound_data *sd, int size)
 {
     int freq = currprefs.sound_freq;
     int ch = get_audio_nativechannels ();
     char *name;
 
-    devicetype = SOUND_DEVICE_AL;
+    sd->devicetype = SOUND_DEVICE_AL;
     size *= ch * 2;
     sndbufsize = size / 8;
     if (sndbufsize > SND_MAX_BUFFER)
        sndbufsize = SND_MAX_BUFFER;
-    al_bufsize = size;
-    al_bigbuffer = xcalloc (al_bufsize, 1);
+    sd->al_bufsize = size;
+    sd->al_bigbuffer = xcalloc (sd->al_bufsize, 1);
     name = ua (sound_devices[currprefs.win32_soundcard].alname);
-    al_dev = alcOpenDevice (name);
+    sd->al_dev = alcOpenDevice (name);
     xfree (name);
-    if (!al_dev)
+    if (!sd->al_dev)
        goto error;
-    al_ctx = alcCreateContext (al_dev, NULL);
-    if (!al_ctx)
+    sd->al_ctx = alcCreateContext (sd->al_dev, NULL);
+    if (!sd->al_ctx)
        goto error;
-    alcMakeContextCurrent (al_ctx);
-    alGenBuffers (AL_BUFFERS, al_Buffers);
-    alGenSources (1, &al_Source);
-    al_toggle = 0;
-    al_format = 0;
+    alcMakeContextCurrent (sd->al_ctx);
+    alGenBuffers (AL_BUFFERS, sd->al_Buffers);
+    alGenSources (1, &sd->al_Source);
+    sd->al_toggle = 0;
+    sd->al_format = 0;
     switch (ch)
     {
        case 1:
-       al_format = AL_FORMAT_MONO16;
+       sd->al_format = AL_FORMAT_MONO16;
        break;
        case 2:
-       al_format = AL_FORMAT_STEREO16;
+       sd->al_format = AL_FORMAT_STEREO16;
        break;
        case 4:
-       al_format = alGetEnumValue ("AL_FORMAT_QUAD16");
+       sd->al_format = alGetEnumValue ("AL_FORMAT_QUAD16");
        break;
        case 6:
-       al_format = alGetEnumValue ("AL_FORMAT_51CHN16");
+       sd->al_format = alGetEnumValue ("AL_FORMAT_51CHN16");
        break;
     }
-    if (al_format == 0)
+    if (sd->al_format == 0)
        goto error;
 
     write_log (L"SOUND: %08X,CH=%d,FREQ=%d '%s' buffer %d (%d)\n",
-           al_format, ch, freq, sound_devices[currprefs.win32_soundcard].alname,
-           sndbufsize, al_bufsize);
+           sd->al_format, ch, freq, sound_devices[currprefs.win32_soundcard].alname,
+           sndbufsize, sd->al_bufsize);
     return 1;
 
 error:
-    close_audio_al ();
+    close_audio_al (sd);
     return 0;
 }
 
-static int open_audio_ds (int size)
+static int open_audio_ds (struct sound_data *sd, int size)
 {
     HRESULT hr;
     DSBUFFERDESC sound_buffer;
@@ -537,35 +557,35 @@ static int open_audio_ds (int size)
     int round, i;
     DWORD speakerconfig;
 
-    devicetype = SOUND_DEVICE_DS;
+    sd->devicetype = SOUND_DEVICE_DS;
     size *= ch * 2;
-    snd_configsize = size;
+    sd->snd_configsize = size;
     sndbufsize = size / 32;
     if (sndbufsize > SND_MAX_BUFFER)
        sndbufsize = SND_MAX_BUFFER;
 
-    max_sndbufsize = size * 4;
-    if (max_sndbufsize > SND_MAX_BUFFER2)
-       max_sndbufsize = SND_MAX_BUFFER2;
-    dsoundbuf = max_sndbufsize * 2;
+    sd->max_sndbufsize = size * 4;
+    if (sd->max_sndbufsize > SND_MAX_BUFFER2)
+       sd->max_sndbufsize = SND_MAX_BUFFER2;
+    sd->dsoundbuf = sd->max_sndbufsize * 2;
 
-    if (dsoundbuf < DSBSIZE_MIN)
-       dsoundbuf = DSBSIZE_MIN;
-    if (dsoundbuf > DSBSIZE_MAX)
-       dsoundbuf = DSBSIZE_MAX;
+    if (sd->dsoundbuf < DSBSIZE_MIN)
+       sd->dsoundbuf = DSBSIZE_MIN;
+    if (sd->dsoundbuf > DSBSIZE_MAX)
+       sd->dsoundbuf = DSBSIZE_MAX;
 
-    if (max_sndbufsize * 2 > dsoundbuf)
-       max_sndbufsize = dsoundbuf / 2;
+    if (sd->max_sndbufsize * 2 > sd->dsoundbuf)
+       sd->max_sndbufsize = sd->dsoundbuf / 2;
 
-    recalc_offsets ();
+    recalc_offsets (sd);
 
-    hr = DirectSoundCreate8 (&sound_devices[currprefs.win32_soundcard].guid, &lpDS, NULL);
+    hr = DirectSoundCreate8 (&sound_devices[currprefs.win32_soundcard].guid, &sd->lpDS, NULL);
     if (FAILED (hr))  {
        write_log (L"SOUND: DirectSoundCreate8() failure: %s\n", DXError (hr));
        return 0;
     }
 
-    hr = IDirectSound_SetCooperativeLevel (lpDS, hMainWnd, DSSCL_PRIORITY);
+    hr = IDirectSound_SetCooperativeLevel (sd->lpDS, hMainWnd, DSSCL_PRIORITY);
     if (FAILED (hr)) {
        write_log (L"SOUND: Can't set cooperativelevel: %s\n", DXError (hr));
        goto error;
@@ -573,7 +593,7 @@ static int open_audio_ds (int size)
 
     memset (&DSCaps, 0, sizeof (DSCaps));
     DSCaps.dwSize = sizeof (DSCaps);
-    hr = IDirectSound_GetCaps (lpDS, &DSCaps);
+    hr = IDirectSound_GetCaps (sd->lpDS, &DSCaps);
     if (FAILED(hr)) {
        write_log (L"SOUND: Error getting DirectSound capabilities: %s\n", DXError (hr));
        goto error;
@@ -596,7 +616,7 @@ static int open_audio_ds (int size)
        }
     }
 
-    speakerconfig = fillsupportedmodes (lpDS, freq, supportedmodes);
+    speakerconfig = fillsupportedmodes (sd->lpDS, freq, supportedmodes);
     write_log (L"SOUND: %08X ", speakerconfig);
     for (i = 0; supportedmodes[i].ch; i++)
        write_log (L"%d:%08X ", supportedmodes[i].ch, supportedmodes[i].ksmode);
@@ -626,27 +646,27 @@ static int open_audio_ds (int size)
        wavfmt.Format.nBlockAlign = wavfmt.Format.wBitsPerSample / 8 * wavfmt.Format.nChannels;
        wavfmt.Format.nAvgBytesPerSec = wavfmt.Format.nBlockAlign * wavfmt.Format.nSamplesPerSec;
 
-       samplesize = ch * 2;
+       sd->samplesize = ch * 2;
        write_log (L"SOUND: %08X,CH=%d,FREQ=%d '%s' buffer %d (%d), dist %d\n",
            ksmode, ch, freq, sound_devices[currprefs.win32_soundcard].name,
-           max_sndbufsize / samplesize, max_sndbufsize, snd_configsize / samplesize);
+           sd->max_sndbufsize / sd->samplesize, sd->max_sndbufsize, sd->snd_configsize / sd->samplesize);
 
        memset (&sound_buffer, 0, sizeof (sound_buffer));
        sound_buffer.dwSize = sizeof (sound_buffer);
-       sound_buffer.dwBufferBytes = dsoundbuf;
+       sound_buffer.dwBufferBytes = sd->dsoundbuf;
        sound_buffer.lpwfxFormat = &wavfmt.Format;
        sound_buffer.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
        sound_buffer.dwFlags |= DSBCAPS_CTRLVOLUME | (ch >= 4 ? DSBCAPS_LOCHARDWARE : DSBCAPS_LOCSOFTWARE);
        sound_buffer.guid3DAlgorithm = GUID_NULL;
 
-       hr = IDirectSound_CreateSoundBuffer (lpDS, &sound_buffer, &pdsb, NULL);
+       hr = IDirectSound_CreateSoundBuffer (sd->lpDS, &sound_buffer, &pdsb, NULL);
        if (SUCCEEDED (hr))
            break;
        if (sound_buffer.dwFlags & DSBCAPS_LOCHARDWARE) {
            HRESULT hr2 = hr;
            sound_buffer.dwFlags &= ~DSBCAPS_LOCHARDWARE;
            sound_buffer.dwFlags |=  DSBCAPS_LOCSOFTWARE;
-           hr = IDirectSound_CreateSoundBuffer (lpDS, &sound_buffer, &pdsb, NULL);
+           hr = IDirectSound_CreateSoundBuffer (sd->lpDS, &sound_buffer, &pdsb, NULL);
            if (SUCCEEDED(hr)) {
                //write_log (L"SOUND: Couldn't use hardware buffer (switched to software): %s\n", DXError (hr2));
                break;
@@ -657,18 +677,18 @@ static int open_audio_ds (int size)
 
     if (pdsb == NULL)
        goto error;
-    hr = IDirectSound_QueryInterface (pdsb, &IID_IDirectSoundBuffer8, (LPVOID*)&lpDSBsecondary);
+    hr = IDirectSound_QueryInterface (pdsb, &IID_IDirectSoundBuffer8, (LPVOID*)&sd->lpDSBsecondary);
     if (FAILED (hr))  {
        write_log (L"SOUND: Secondary QueryInterface() failure: %s\n", DXError (hr));
        goto error;
     }
     IDirectSound_Release (pdsb);
-    clearbuffer ();
+    clearbuffer (sd);
 
     return 1;
 
 error:
-    close_audio_ds ();
+    close_audio_ds (sd);
     return 0;
 }
 
@@ -692,22 +712,22 @@ static int open_sound (void)
 
     enumerate_sound_devices ();
     if (sound_devices[currprefs.win32_soundcard].type == SOUND_DEVICE_AL)
-       ret = open_audio_al (size);
+       ret = open_audio_al (sdp, size);
     else if (sound_devices[currprefs.win32_soundcard].type == SOUND_DEVICE_DS)
-       ret = open_audio_ds (size);
+       ret = open_audio_ds (sdp, size);
     else if (sound_devices[currprefs.win32_soundcard].type == SOUND_DEVICE_PA)
-       ret = open_audio_pa (size);
+       ret = open_audio_pa (sdp, size);
     if (!ret)
        return 0;
 
-    set_volume (currprefs.sound_volume, mute);
+    set_volume (currprefs.sound_volume, sdp->mute);
     init_sound_table16 ();
     if (get_audio_amigachannels() == 4)
        sample_handler = sample16ss_handler;
     else
        sample_handler = get_audio_ismono () ? sample16_handler : sample16s_handler;
 
-    obtainedfreq = currprefs.sound_freq;
+    sdp->obtainedfreq = currprefs.sound_freq;
 
     have_sound = 1;
     sound_available = 1;
@@ -725,12 +745,12 @@ void close_sound (void)
     if (! have_sound)
        return;
     pause_sound ();
-    if (devicetype == SOUND_DEVICE_AL)
-       close_audio_al ();
-    else if (devicetype == SOUND_DEVICE_DS)
-       close_audio_ds ();
-    else if (devicetype == SOUND_DEVICE_PA)
-       close_audio_pa ();
+    if (sdp->devicetype == SOUND_DEVICE_AL)
+       close_audio_al (sdp);
+    else if (sdp->devicetype == SOUND_DEVICE_DS)
+       close_audio_ds (sdp);
+    else if (sdp->devicetype == SOUND_DEVICE_PA)
+       close_audio_pa (sdp);
     have_sound = 0;
 }
 
@@ -746,7 +766,7 @@ int init_sound (void)
        return 1;
     if (!open_sound ())
        return 0;
-    paused = 1;
+    sdp->paused = 1;
     driveclick_reset ();
     resume_sound ();
     return 1;
@@ -754,38 +774,38 @@ int init_sound (void)
 
 void pause_sound (void)
 {
-    if (paused)
+    if (sdp->paused)
        return;
-    paused = 1;
+    sdp->paused = 1;
     if (!have_sound)
        return;
-    if (devicetype == SOUND_DEVICE_AL)
-       pause_audio_al ();
-    else if (devicetype == SOUND_DEVICE_DS)
-       pause_audio_ds ();
-    else if (devicetype == SOUND_DEVICE_PA)
-       pause_audio_pa ();
+    if (sdp->devicetype == SOUND_DEVICE_AL)
+       pause_audio_al (sdp);
+    else if (sdp->devicetype == SOUND_DEVICE_DS)
+       pause_audio_ds (sdp);
+    else if (sdp->devicetype == SOUND_DEVICE_PA)
+       pause_audio_pa (sdp);
 }
 
 void resume_sound (void)
 {
-    if (!paused)
+    if (!sdp->paused)
        return;
     if (!have_sound)
        return;
-    if (devicetype == SOUND_DEVICE_AL)
-       resume_audio_al ();
-    else if (devicetype == SOUND_DEVICE_DS)
-       resume_audio_ds ();
-    else if (devicetype == SOUND_DEVICE_PA)
-       resume_audio_pa ();
+    if (sdp->devicetype == SOUND_DEVICE_AL)
+       resume_audio_al (sdp);
+    else if (sdp->devicetype == SOUND_DEVICE_DS)
+       resume_audio_ds (sdp);
+    else if (sdp->devicetype == SOUND_DEVICE_PA)
+       resume_audio_pa (sdp);
 }
 
 void reset_sound (void)
 {
     if (!have_sound)
        return;
-    clearbuffer ();
+    clearbuffer (sdp);
 }
 
 #ifdef JIT
@@ -818,54 +838,57 @@ void sound_setadjust (double v)
 
 #define SND_STATUSCNT 10
 
-static int safedist;
+#define cf(x) if ((x) >= sd->dsoundbuf) (x) -= sd->dsoundbuf;
 
-#define cf(x) if ((x) >= dsoundbuf) (x) -= dsoundbuf;
-
-void restart_sound_buffer (void)
+static void restart_sound_buffer2 (struct sound_data *sd)
 {
     DWORD playpos, safed;
     HRESULT hr;
 
-    if (devicetype != SOUND_DEVICE_DS)
+    if (sd->devicetype != SOUND_DEVICE_DS)
        return;
-    if (waiting_for_buffer != -1)
+    if (sdp->waiting_for_buffer != -1)
        return;
-    hr = IDirectSoundBuffer_GetCurrentPosition (lpDSBsecondary, &playpos, &safed);
+    hr = IDirectSoundBuffer_GetCurrentPosition (sd->lpDSBsecondary, &playpos, &safed);
     if (FAILED (hr)) {
        write_log (L"SOUND: DirectSoundBuffer_GetCurrentPosition failed, %s\n", DXError (hr));
        return;
     }
-    writepos = safed + snd_writeoffset;
-    if (writepos < 0)
-       writepos += dsoundbuf;
-    cf (writepos);
+    sd->writepos = safed + sd->snd_writeoffset;
+    if (sd->writepos < 0)
+       sd->writepos += sd->dsoundbuf;
+    cf (sd->writepos);
 }
 
-static int alcheck (int v)
+void restart_sound_buffer (void)
+{
+    restart_sound_buffer2 (sdp);
+}
+
+static int alcheck (struct sound_data *sd, int v)
 {
     int err = alGetError ();
     if (err != AL_NO_ERROR) {
        int v1, v2, v3;
-        alGetSourcei (al_Source, AL_BUFFERS_PROCESSED, &v1);
-       alGetSourcei (al_Source, AL_BUFFERS_QUEUED, &v2);
-       alGetSourcei (al_Source, AL_SOURCE_STATE, &v3);
+        alGetSourcei (sd->al_Source, AL_BUFFERS_PROCESSED, &v1);
+       alGetSourcei (sd->al_Source, AL_BUFFERS_QUEUED, &v2);
+       alGetSourcei (sd->al_Source, AL_SOURCE_STATE, &v3);
        write_log (L"OpenAL %d: error %d. PROC=%d QUEUE=%d STATE=%d\n", v, err, v1, v2, v3);
        write_log (L"           %d %08x %08x %08x %d %d\n",
-           al_toggle, al_Buffers[al_toggle], al_format, al_bigbuffer, al_bufsize, currprefs.sound_freq);
+           sd->al_toggle, sd->al_Buffers[sd->al_toggle], sd->al_format, sd->al_bigbuffer, sd->al_bufsize, currprefs.sound_freq);
        return 1;
     }
     return 0;
 }
 
-static void finish_sound_buffer_al (void)
+static void finish_sound_buffer_al (struct sound_data *sd)
 {
     static int tfprev;
     static int statuscnt;
     int v, v2;
     double m, skipmode;
 
-    if (!waiting_for_buffer)
+    if (!sd->waiting_for_buffer)
        return;
     if (savestate_state)
        return;
@@ -879,62 +902,62 @@ static void finish_sound_buffer_al (void)
        gui_data.sndbuf_status = 0;
     alGetError ();
 
-    memcpy (al_bigbuffer + al_offset, sndbuffer, sndbufsize);
-    al_offset += sndbufsize;
-    if (al_offset >= al_bufsize) {
+    memcpy (sd->al_bigbuffer + sd->al_offset, sndbuffer, sndbufsize);
+    sd->al_offset += sndbufsize;
+    if (sd->al_offset >= sd->al_bufsize) {
        ALuint tmp;
-       alGetSourcei (al_Source, AL_BUFFERS_PROCESSED, &v);
-       while (v == 0 && waiting_for_buffer < 0) {
+       alGetSourcei (sd->al_Source, AL_BUFFERS_PROCESSED, &v);
+       while (v == 0 && sd->waiting_for_buffer < 0) {
            sleep_millis (1);
-           alGetSourcei (al_Source, AL_SOURCE_STATE, &v);
+           alGetSourcei (sd->al_Source, AL_SOURCE_STATE, &v);
            if (v != AL_PLAYING)
                break;
-           alGetSourcei (al_Source, AL_BUFFERS_PROCESSED, &v);
+           alGetSourcei (sd->al_Source, AL_BUFFERS_PROCESSED, &v);
        }
 
-        alSourceUnqueueBuffers (al_Source, 1, &tmp);
+        alSourceUnqueueBuffers (sd->al_Source, 1, &tmp);
        alGetError ();
 
 //     write_log (L"           %d %08x %08x %08x %d %d\n",
 //         al_toggle, al_Buffers[al_toggle], al_format, al_bigbuffer, al_bufsize, currprefs.sound_freq);
 
-       alBufferData (al_Buffers[al_toggle], al_format, al_bigbuffer, al_bufsize, currprefs.sound_freq);
-       alcheck(4);
-       alSourceQueueBuffers (al_Source, 1, &al_Buffers[al_toggle]);
-       alcheck(2);
-       al_toggle++;
-       if (al_toggle >= AL_BUFFERS)
-           al_toggle = 0;
-
-       alGetSourcei (al_Source, AL_BUFFERS_QUEUED, &v2);
-       alcheck(5);
-       alGetSourcei (al_Source, AL_SOURCE_STATE, &v);
-       alcheck(3);
+       alBufferData (sd->al_Buffers[sd->al_toggle], sd->al_format, sd->al_bigbuffer, sd->al_bufsize, currprefs.sound_freq);
+       alcheck (sd, 4);
+       alSourceQueueBuffers (sd->al_Source, 1, &sd->al_Buffers[sd->al_toggle]);
+       alcheck (sd, 2);
+       sd->al_toggle++;
+       if (sd->al_toggle >= AL_BUFFERS)
+           sd->al_toggle = 0;
+
+       alGetSourcei (sd->al_Source, AL_BUFFERS_QUEUED, &v2);
+       alcheck (sd, 5);
+       alGetSourcei (sd->al_Source, AL_SOURCE_STATE, &v);
+       alcheck (sd, 3);
        if (v != AL_PLAYING && v2 >= AL_BUFFERS) {
-           if (waiting_for_buffer > 0) {
+           if (sd->waiting_for_buffer > 0) {
                write_log (L"AL SOUND PLAY!\n");
-               alSourcePlay (al_Source);
-               waiting_for_buffer = -1;
+               alSourcePlay (sd->al_Source);
+               sd->waiting_for_buffer = -1;
                tfprev = timeframes + 10;
                tfprev = (tfprev / 10) * 10;
            } else {
                gui_data.sndbuf_status = 2;
                statuscnt = SND_STATUSCNT;
                write_log (L"AL underflow\n");
-               clearbuffer ();
-               waiting_for_buffer = 1;
+               clearbuffer (sd);
+               sd->waiting_for_buffer = 1;
            }
        }
-       al_offset = 0;
+       sd->al_offset = 0;
     }
-    alcheck(1);
+    alcheck (sd, 1);
 
-    alGetSourcei (al_Source, AL_SOURCE_STATE, &v);
-    alcheck(6);
+    alGetSourcei (sd->al_Source, AL_SOURCE_STATE, &v);
+    alcheck (sd, 6);
     if (v == AL_PLAYING) {
-       alGetSourcei (al_Source, AL_BYTE_OFFSET, &v);
-       alcheck(7);
-       v -= al_offset;
+       alGetSourcei (sd->al_Source, AL_BYTE_OFFSET, &v);
+       alcheck (sd, 7);
+       v -= sd->al_offset;
        gui_data.sndbuf = 100 * v / sndbufsize;
        m = gui_data.sndbuf / 100.0;
 
@@ -968,10 +991,10 @@ static void finish_sound_buffer_al (void)
        }
     }
 
-    alcheck (0);
+    alcheck (sd, 0);
 }
 
-static void finish_sound_buffer_ds (void)
+static void finish_sound_buffer_ds (struct sound_data *sd)
 {
     static int tfprev;
     DWORD playpos, safepos, status;
@@ -991,30 +1014,30 @@ static void finish_sound_buffer_ds (void)
     if (gui_data.sndbuf_status == 3)
        gui_data.sndbuf_status = 0;
 
-    if (!waiting_for_buffer)
+    if (!sd->waiting_for_buffer)
        return;
     if (savestate_state)
        return;
 
-    if (waiting_for_buffer == 1) {
-       hr = IDirectSoundBuffer_Play (lpDSBsecondary, 0, 0, DSBPLAY_LOOPING);
+    if (sd->waiting_for_buffer == 1) {
+       hr = IDirectSoundBuffer_Play (sd->lpDSBsecondary, 0, 0, DSBPLAY_LOOPING);
        if (FAILED (hr)) {
            write_log (L"SOUND: Play failed: %s\n", DXError (hr));
-           restore_ds (DSERR_BUFFERLOST);
-           waiting_for_buffer = 0;
+           restore_ds (sd, DSERR_BUFFERLOST);
+           sd->waiting_for_buffer = 0;
            return;
        }
-       hr = IDirectSoundBuffer_SetCurrentPosition (lpDSBsecondary, 0);
+       hr = IDirectSoundBuffer_SetCurrentPosition (sd->lpDSBsecondary, 0);
        if (FAILED (hr)) {
            write_log (L"SOUND: 1st SetCurrentPosition failed: %s\n", DXError (hr));
-           restore_ds (DSERR_BUFFERLOST);
-           waiting_for_buffer = 0;
+           restore_ds (sd, DSERR_BUFFERLOST);
+           sd->waiting_for_buffer = 0;
            return;
        }
        /* there are crappy drivers that return PLAYCURSOR = WRITECURSOR = 0 without this.. */
        counter = 5000;
        for (;;) {
-           hr = IDirectSoundBuffer_GetCurrentPosition (lpDSBsecondary, &playpos, &safedist);
+           hr = IDirectSoundBuffer_GetCurrentPosition (sd->lpDSBsecondary, &playpos, &sd->safedist);
            if (playpos > 0)
                break;
            sleep_millis (1);
@@ -1024,64 +1047,64 @@ static void finish_sound_buffer_ds (void)
                break;
            }
        }
-       write_log (L"SOUND: %d = (%d - %d)\n", (safedist - playpos) / samplesize, safedist / samplesize, playpos / samplesize);
-       recalc_offsets ();
-       safedist -= playpos;
-       if (safedist < 64)
-           safedist = 64;
-       cf (safedist);
+       write_log (L"SOUND: %d = (%d - %d)\n", (sd->safedist - playpos) / sd->samplesize, sd->safedist / sd->samplesize, playpos / sd->samplesize);
+       recalc_offsets (sd);
+       sd->safedist -= playpos;
+       if (sd->safedist < 64)
+           sd->safedist = 64;
+       cf (sd->safedist);
 #if 0
-       snd_totalmaxoffset_uf += safedist;
+       snd_totalmaxoffset_uf += sd->safedist;
        cf (snd_totalmaxoffset_uf);
-       snd_totalmaxoffset_of += safedist;
+       snd_totalmaxoffset_of += sd->safedist;
        cf (snd_totalmaxoffset_of);
-       snd_maxoffset += safedist;
+       snd_maxoffset += sd->safedist;
        cf (snd_maxoffset);
-       snd_writeoffset += safedist;
+       snd_writeoffset += sd->safedist;
        cf (snd_writeoffset);
 #endif
-       waiting_for_buffer = -1;
-       restart_sound_buffer ();
+       sd->waiting_for_buffer = -1;
+       restart_sound_buffer2 (sd);
        write_log (L"SOUND: bs=%d w=%d max=%d tof=%d tuf=%d\n",
-           sndbufsize / samplesize, snd_writeoffset / samplesize,
-           snd_maxoffset / samplesize, snd_totalmaxoffset_of / samplesize,
-           snd_totalmaxoffset_uf / samplesize);
+           sndbufsize / sd->samplesize, sd->snd_writeoffset / sd->samplesize,
+           sd->snd_maxoffset / sd->samplesize, sd->snd_totalmaxoffset_of / sd->samplesize,
+           sd->snd_totalmaxoffset_uf / sd->samplesize);
        tfprev = timeframes + 10;
        tfprev = (tfprev / 10) * 10;
     }
 
     counter = 5000;
-    hr = IDirectSoundBuffer_GetStatus (lpDSBsecondary, &status);
+    hr = IDirectSoundBuffer_GetStatus (sd->lpDSBsecondary, &status);
     if (FAILED (hr)) {
        write_log (L"SOUND: GetStatus() failed: %s\n", DXError (hr));
-       restore_ds (DSERR_BUFFERLOST);
+       restore_ds (sd, DSERR_BUFFERLOST);
        return;
     }
     if (status & DSBSTATUS_BUFFERLOST) {
        write_log (L"SOUND: buffer lost\n");
-       restore_ds (DSERR_BUFFERLOST);
+       restore_ds (sd, DSERR_BUFFERLOST);
        return;
     }
     if ((status & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) != (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) {
        write_log (L"SOUND: status = %08X\n", status);
-       restore_ds (DSERR_BUFFERLOST);
+       restore_ds (sd, DSERR_BUFFERLOST);
        return;
     }
     for (;;) {
-       hr = IDirectSoundBuffer_GetCurrentPosition (lpDSBsecondary, &playpos, &safepos);
+       hr = IDirectSoundBuffer_GetCurrentPosition (sd->lpDSBsecondary, &playpos, &safepos);
        if (FAILED (hr)) {
-           restore_ds (hr);
+           restore_ds (sd, hr);
            write_log (L"SOUND: GetCurrentPosition failed: %s\n", DXError (hr));
            return;
        }
-       if (writepos >= safepos)
-           diff = writepos - safepos;
+       if (sd->writepos >= safepos)
+           diff = sd->writepos - safepos;
        else
-           diff = dsoundbuf - safepos + writepos;
+           diff = sd->dsoundbuf - safepos + sd->writepos;
 
-       if (diff < sndbufsize || diff > snd_totalmaxoffset_uf) {
+       if (diff < sndbufsize || diff > sd->snd_totalmaxoffset_uf) {
 #if 0
-           hr = IDirectSoundBuffer_Lock (lpDSBsecondary, writepos, sndbufsize, &b1, &s1, &b2, &s2, 0);
+           hr = IDirectSoundBuffer_Lock (lpDSBsecondary, sd->writepos, sndbufsize, &b1, &s1, &b2, &s2, 0);
            if (SUCCEEDED(hr)) {
                memset (b1, 0, s1);
                if (b2)
@@ -1091,31 +1114,31 @@ static void finish_sound_buffer_ds (void)
 #endif
            gui_data.sndbuf_status = -1;
            statuscnt = SND_STATUSCNT;
-           if (diff > snd_totalmaxoffset_uf)
-               writepos += dsoundbuf - diff;
-           writepos += sndbufsize;
-           cf (writepos);
-           diff = safedist;
+           if (diff > sd->snd_totalmaxoffset_uf)
+               sd->writepos += sd->dsoundbuf - diff;
+           sd->writepos += sndbufsize;
+           cf (sd->writepos);
+           diff = sd->safedist;
            break;
        }
 
-       if (diff > snd_totalmaxoffset_of) {
+       if (diff > sd->snd_totalmaxoffset_of) {
            gui_data.sndbuf_status = 2;
            statuscnt = SND_STATUSCNT;
-           restart_sound_buffer ();
-           diff = snd_writeoffset;
-           write_log (L"SOUND: underflow (%d %d)\n", diff / samplesize, snd_totalmaxoffset_of / samplesize);
+           restart_sound_buffer2 (sd);
+           diff = sd->snd_writeoffset;
+           write_log (L"SOUND: underflow (%d %d)\n", diff / sd->samplesize, sd->snd_totalmaxoffset_of / sd->samplesize);
            break;
        }
 
-       if (diff > snd_maxoffset) {
+       if (diff > sd->snd_maxoffset) {
            gui_data.sndbuf_status = 1;
            statuscnt = SND_STATUSCNT;
            sleep_millis (1);
            counter--;
            if (counter < 0) {
                write_log (L"SOUND: sound system got stuck!?\n");
-               restore_ds (DSERR_BUFFERLOST);
+               restore_ds (sd, DSERR_BUFFERLOST);
                return;
            }
            continue;
@@ -1123,20 +1146,20 @@ static void finish_sound_buffer_ds (void)
        break;
     }
 
-    hr = IDirectSoundBuffer_Lock (lpDSBsecondary, writepos, sndbufsize, &b1, &s1, &b2, &s2, 0);
-    if (restore_ds (hr))
+    hr = IDirectSoundBuffer_Lock (sd->lpDSBsecondary, sd->writepos, sndbufsize, &b1, &s1, &b2, &s2, 0);
+    if (restore_ds (sd, hr))
        return;
     if (FAILED (hr)) {
-       write_log (L"SOUND: lock failed: %s (%d %d)\n", DXError (hr), writepos / samplesize, sndbufsize / samplesize);
+       write_log (L"SOUND: lock failed: %s (%d %d)\n", DXError (hr), sd->writepos / sd->samplesize, sndbufsize / sd->samplesize);
        return;
     }
     memcpy (b1, sndbuffer, s1);
     if (b2)
        memcpy (b2, (uae_u8*)sndbuffer + s1, s2);
-    IDirectSoundBuffer_Unlock (lpDSBsecondary, b1, s1, b2, s2);
+    IDirectSoundBuffer_Unlock (sd->lpDSBsecondary, b1, s1, b2, s2);
 
-    vdiff = diff - snd_writeoffset;
-    m = 100.0 * vdiff / max_sndbufsize;
+    vdiff = diff - sd->snd_writeoffset;
+    m = 100.0 * vdiff / sd->max_sndbufsize;
 
     if (isvsync ()) {
 
@@ -1163,16 +1186,16 @@ static void finish_sound_buffer_ds (void)
     if (tfprev != timeframes) {
        if (sound_debug && !(tfprev % 10))
            write_log (L"b=%4d,%5d,%5d,%5d d=%5d vd=%5.0f s=%+02.1f\n",
-               sndbufsize / samplesize, snd_configsize / samplesize, max_sndbufsize / samplesize,
-               dsoundbuf / samplesize, diff / samplesize, vdiff, skipmode);
+               sndbufsize / sd->samplesize, sd->snd_configsize / sd->samplesize, sd->max_sndbufsize / sd->samplesize,
+               sd->dsoundbuf / sd->samplesize, diff / sd->samplesize, vdiff, skipmode);
        tfprev = timeframes;
        if (!avioutput_audio)
            sound_setadjust (skipmode);
-       gui_data.sndbuf = vdiff * 1000 / (snd_maxoffset - snd_writeoffset);
+       gui_data.sndbuf = vdiff * 1000 / (sd->snd_maxoffset - sd->snd_writeoffset);
     }
 
-    writepos += sndbufsize;
-    cf (writepos);
+    sd->writepos += sndbufsize;
+    cf (sd->writepos);
 }
 
 static void channelswap (uae_s16 *sndbuffer, int len)
@@ -1221,12 +1244,12 @@ void finish_sound_buffer (void)
     if (!have_sound)
        return;
 
-    if (devicetype == SOUND_DEVICE_AL)
-       finish_sound_buffer_al ();
-    else if (devicetype == SOUND_DEVICE_DS)
-       finish_sound_buffer_ds ();
-    else if (devicetype == SOUND_DEVICE_PA)
-       finish_sound_buffer_pa ();
+    if (sdp->devicetype == SOUND_DEVICE_AL)
+       finish_sound_buffer_al (sdp);
+    else if (sdp->devicetype == SOUND_DEVICE_DS)
+       finish_sound_buffer_ds (sdp);
+    else if (sdp->devicetype == SOUND_DEVICE_PA)
+       finish_sound_buffer_pa (sdp);
 }
 
 static BOOL CALLBACK DSEnumProc (LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext)
@@ -1600,10 +1623,10 @@ static int get_master_volume (int *volume, int *mute)
 void sound_mute (int newmute)
 {
     if (newmute < 0)
-       mute = mute ? 0 : 1;
+       sdp->mute = sdp->mute ? 0 : 1;
     else
-       mute = newmute;
-    set_volume (currprefs.sound_volume, mute);
+       sdp->mute = newmute;
+    set_volume (currprefs.sound_volume, sdp->mute);
 }
 
 void sound_volume (int dir)
@@ -1614,7 +1637,7 @@ void sound_volume (int dir)
     if (currprefs.sound_volume > 100)
        currprefs.sound_volume = 100;
     changed_prefs.sound_volume = currprefs.sound_volume;
-    set_volume (currprefs.sound_volume, mute);
+    set_volume (currprefs.sound_volume, sdp->mute);
 }
 void master_sound_volume (int dir)
 {
index fa4990ddd31863700157a237d138efa10f0d1008..6a2a7b20d5c9c8b03097338df03e54275ac1876d 100644 (file)
@@ -3505,6 +3505,10 @@ static int parseargs (const TCHAR *arg, const TCHAR *np, const TCHAR *np2)
         ahi_debug = 3;
        return 1;
     }
+    if (!_tcscmp (arg, L"-quittogui")) {
+       quit_to_gui = 1;
+       return 1;
+    }
 
     if (!np)
        return 0;
@@ -3872,7 +3876,7 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR
 #ifdef RETROPLATFORM
     rp_free ();
 #endif
-    if(hWinUAEKey)
+    if (hWinUAEKey)
        RegCloseKey (hWinUAEKey);
     CloseHandle (hMutex);
     WIN32_CleanupLibraries ();
index f96612be74673d9eda89fb8019bc2b8a5cdf126b..dc6335c6d739be182ddd3cc021e69863108bd8e7 100644 (file)
@@ -17,8 +17,8 @@
 
 #define WINUAEPUBLICBETA 1
 
-#define WINUAEBETA L"24"
-#define WINUAEDATE MAKEBD(2009, 4, 12)
+#define WINUAEBETA L"25"
+#define WINUAEDATE MAKEBD(2009, 4, 20)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index 0781ca7a9475391035f37cee8ec22d1d67717c82..dedf717b41eeafe3f1eac5304bb2016b7f810aa9 100644 (file)
@@ -12329,10 +12329,12 @@ int gui_message_multibutton (int flags, const TCHAR *format,...)
     else if (flags == 2)
        mbflags |= MB_YESNOCANCEL;
 
-    pause_sound ();
     flipflop = fsdialog (&hwnd, &mbflags);
-    if (flipflop)
-       ShowWindow (hAmigaWnd, SW_MINIMIZE);
+    if (!gui_active) {
+       pause_sound ();
+       if (flipflop)
+           ShowWindow (hAmigaWnd, SW_MINIMIZE);
+    }
 
     va_start (parms, format);
     _vstprintf (msg, format, parms);
@@ -12345,11 +12347,12 @@ int gui_message_multibutton (int flags, const TCHAR *format,...)
 
     ret = MessageBox (hwnd, msg, szTitle, mbflags);
 
-    if (flipflop)
-       ShowWindow (hAmigaWnd, SW_RESTORE);
-
-    resume_sound ();
-    setmouseactive (focuso > 0 ? 1 : 0);
+    if (!gui_active) {
+       if (flipflop)
+           ShowWindow (hAmigaWnd, SW_RESTORE);
+        resume_sound ();
+       setmouseactive (focuso > 0 ? 1 : 0);
+    }
     if (ret == IDOK)
        return 0;
     if (ret == IDYES)
@@ -12375,14 +12378,18 @@ void gui_message (const TCHAR *format,...)
     va_start (parms, format);
     _vstprintf (msg, format, parms);
     va_end (parms);
+
     if (full_property_sheet) {
        pre_gui_message (msg);
        return;
     }
-    pause_sound ();
+
     flipflop = fsdialog (&hwnd, &flags);
-    if (flipflop)
-       ShowWindow (hAmigaWnd, SW_MINIMIZE);
+    if (!gui_active) {
+        pause_sound ();
+       if (flipflop)
+           ShowWindow (hAmigaWnd, SW_MINIMIZE);
+    }
 
     write_log (msg);
     if (msg[_tcslen (msg) - 1] != '\n')
@@ -12391,12 +12398,14 @@ void gui_message (const TCHAR *format,...)
     WIN32GUI_LoadUIString (IDS_ERRORTITLE, szTitle, MAX_DPATH);
 
     if (!MessageBox (hwnd, msg, szTitle, flags))
-       write_log (L"MessageBox(%s) failed, err=%d\n", msg, GetLastError());
+       write_log (L"MessageBox(%s) failed, err=%d\n", msg, GetLastError ());
 
-    if (flipflop)
-       ShowWindow (hAmigaWnd, SW_RESTORE);
-    resume_sound ();
-    setmouseactive (focuso > 0 ? 1 : 0);
+    if (!gui_active) {
+       if (flipflop)
+           ShowWindow (hAmigaWnd, SW_RESTORE);
+       resume_sound ();
+       setmouseactive (focuso > 0 ? 1 : 0);
+    }
 }
 
 void gui_message_id (int id)
index 0756fcc4849bad889ca9f57e05d5fbf0844604b6..28fb5b511c0031eeadbc725b4463cf494fe0528d 100644 (file)
@@ -92,7 +92,7 @@
                                LinkIncremental="2"
                                SuppressStartupBanner="true"
                                GenerateManifest="false"
-                               DelayLoadDLLs="wpcap.dll;packet.dll;d3dx9_40.dll;openal32.dll;wintab32.dll;portaudio_x86.dll"
+                               DelayLoadDLLs="wpcap.dll;packet.dll;d3dx9_41.dll;openal32.dll;wintab32.dll;portaudio_x86.dll"
                                GenerateDebugInformation="true"
                                ProgramDatabaseFile=".\Debug/winuae.pdb"
                                SubSystem="2"
                                AdditionalLibraryDirectories=""
                                GenerateManifest="true"
                                AdditionalManifestDependencies=""
-                               DelayLoadDLLs="wpcap.dll;packet.dll;d3dx9_40.dll;openal32.dll;wintab32.dll;portaudio_x86.dll"
+                               DelayLoadDLLs="wpcap.dll;packet.dll;d3dx9_41.dll;openal32.dll;wintab32.dll;portaudio_x86.dll"
                                GenerateDebugInformation="true"
                                ProgramDatabaseFile=".\Release/winuae.pdb"
                                SubSystem="2"
                                AdditionalLibraryDirectories=""
                                GenerateManifest="true"
                                AdditionalManifestDependencies=""
-                               DelayLoadDLLs="wpcap.dll;packet.dll;d3dx9_40.dll;openal32.dll;wintab32.dll;portaudio_x86.dll"
+                               DelayLoadDLLs="wpcap.dll;packet.dll;d3dx9_41.dll;openal32.dll;wintab32.dll;portaudio_x86.dll"
                                GenerateDebugInformation="true"
                                ProgramDatabaseFile=".\FullRelease/winuae.pdb"
                                SubSystem="2"
index 9fc9d6d01f880983ef5d49da7511f2ed603ecf8a..f488589269a2c306ba0053f087aa6d3d0b3b7fb7 100644 (file)
@@ -1,4 +1,18 @@
 
+Beta 25:
+
+- Picasso96 crash in some specific cases when 8bit->16/32 or 16->32
+  conversion is used (bug since new Picasso96 emulation was introduced)
+- "yes/no"-style dialogs in fullscreen with active GUI: mouse was
+  (incorrectly) captured when exiting the dialog
+- switching between ce and non-ce mode in some blitter heavy programs
+  could have frozen the blitter (workaround was to switch back to
+  original mode)
+- input was disabled when in "mouse driver" mode and focus was lost
+  and regained
+- DXSDK update, D3D support requires March 2009 DX runtime or newer
+- D3D fullscreen flickering fixed
+
 Beta 24:
 
 - debugger T command fixed (b15)
@@ -8,7 +22,7 @@ Beta 24:
   after reset -> random errors and crashes)
 - do not include mice in parallel port joystick select menus
 - add new empty adf files to disk history list
-- added simple list devices, libraries and resources commands to
+- added simple list devices, libraries and resources command to
   debugger (Td Tl Tr)
 - log file long datestamps fixed
 
index 9775d7b6e77ea00698df7d32c93c9f7ca6f24ff7..5f37fcbe3dcc599fe30d1f084f6a1083ed6b39d6 100644 (file)
--- a/uaeunp.c
+++ b/uaeunp.c
@@ -115,6 +115,7 @@ struct arcdir {
     uae_u64 size;
     TCHAR *comment;
     uae_u32 crc32;
+    int iscrc;
     __time64_t dt;
     int parent, nextlevel;
 };
@@ -131,6 +132,7 @@ static void dolist (struct arcdir **filelist, struct arcdir *adp, int entries, i
            int j;
            TCHAR protflags[9];
            TCHAR dates[32];
+           TCHAR crcs[16];
            int flags;
            struct tm *dt;
 
@@ -161,12 +163,16 @@ static void dolist (struct arcdir **filelist, struct arcdir *adp, int entries, i
 
                for (j = 0; j < level; j++)
                    _tprintf (L" ");
+               if (ad->iscrc)
+                   _stprintf (crcs, L"%08X", ad->crc32);
+               else
+                   _tcscpy (crcs, L"--------");
                if (ad->isdir > 0)
                    _tprintf (L"     [DIR] %s %s          %s\n", protflags, dates, ad->name);
                else if (ad->isdir < 0)
                    _tprintf (L"    [VDIR] %s %s          %s\n", protflags, dates, ad->name);
                else
-                   _tprintf (L"%10I64d %s %s %08X %s\n", ad->size, protflags, dates, ad->crc32, ad->name);
+                   _tprintf (L"%10I64d %s %s %s %s\n", ad->size, protflags, dates, crcs, ad->name);
                if (ad->comment)
                    _tprintf (L" \"%s\"\n", ad->comment);
                if (ad->nextlevel >= 0) {
@@ -183,6 +189,14 @@ static void dolist (struct arcdir **filelist, struct arcdir *adp, int entries, i
 static int parentid = -1, subdirid;
 static int maxentries = 10000, entries;
 
+static void resetlist (void)
+{
+    parentid = -1;
+    subdirid = 0;
+    maxentries = 10000;
+    entries = 0;
+}
+
 static int unlist2 (struct arcdir *adp, const TCHAR *src, int all)
 {
     struct zvolume *zv;
@@ -217,6 +231,7 @@ static int unlist2 (struct arcdir *adp, const TCHAR *src, int all)
         TCHAR *comment;
        struct zfile *zf;
        uae_u32 crc32 = 0;
+       int iscrc = 0;
        int nextdir = -1;
 
         _tcscpy (p, src);
@@ -231,10 +246,11 @@ static int unlist2 (struct arcdir *adp, const TCHAR *src, int all)
        comment = 0;
        zfile_fill_file_attrs_archive (p, &isdir, &flags, &comment);
        flags ^= 15;
-       if (!isdir) {
+       if (!isdir && st.st_size < 1024 * 1024 * 2 && st.st_size > 0) {
            zf = zfile_open_archive (p, 0);
            if (zf) {
                crc32 = zfile_crc32 (zf);
+               iscrc = 1;
            }
        }
 
@@ -247,6 +263,7 @@ static int unlist2 (struct arcdir *adp, const TCHAR *src, int all)
        ad->dt = st.st_mtime;
        ad->parent = parentid;
        ad->crc32 = crc32;
+       ad->iscrc = iscrc;
 
        if (isdir && all) {
            int oldparent = parentid;
@@ -285,6 +302,7 @@ static int unlist2 (struct arcdir *adp, const TCHAR *src, int all)
 
     dolist (filelist, adp, entries, -1, 0);
     zfile_closedir_archive (h);
+    zfile_fclose_archive (zv);
     return 1;
 }
 
@@ -296,6 +314,41 @@ static int unlist (const TCHAR *src, int all)
     return 1;
 }
 
+static int docrclist (const TCHAR *src)
+{
+    WIN32_FIND_DATA ffd;
+    HANDLE h;
+    TCHAR path[MAX_DPATH];
+    
+    _tcscpy (path, src);
+    _tcscat (path, L"\\*.*");
+    h = FindFirstFile (path, &ffd);
+    while (h) {
+       if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+           if (!_tcscmp (ffd.cFileName, L".") || !_tcscmp (ffd.cFileName, L".."))
+               goto next;
+           _tcscpy (path, src);
+           _tcscat (path, L"\\");
+           _tcscat (path, ffd.cFileName);
+           docrclist (path);
+       } else {
+           TCHAR path2[MAX_DPATH];
+           _tcscpy (path, src);
+           _tcscat (path, L"\\");
+           _tcscat (path, ffd.cFileName);
+           GetFullPathName (path, MAX_DPATH, path2, NULL);
+           resetlist ();
+           unlist (path2, 1);
+       }
+next:
+       if (!FindNextFile (h, &ffd)) {
+           FindClose (h);
+           break;
+       }
+    }
+    return 1;
+}
+
 static void setdate (const TCHAR *src, __time64_t tm)
 {
     struct utimbuf ut;
@@ -526,14 +579,23 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
 {
     int ok = 0, i;
     int list = 0, xtract = 0, extract = 0;
-    int out = 0, all = 0;
-    TCHAR path[MAX_DPATH], tmppath[MAX_DPATH];
+    int out = 0, all = 0, crclist = 0;
+    TCHAR path[MAX_DPATH] = { 0 }, pathx[MAX_DPATH] = { 0 };
+#if 0
+    TCHAR tmppath[MAX_DPATH];
+#endif
     int used[32] = { 0 };
     TCHAR *parm2 = NULL;
     TCHAR *parm3 = NULL;
     TCHAR *match = NULL;
     
+    resetlist ();
+
     for (i = 0; i < argc && i < 32; i++) {
+       if (!_tcsicmp (argv[i], L"-crclist")) {
+           crclist = 1;
+           used[i] = 1;
+       }
        if (!_tcsicmp (argv[i], L"o")) {
            out = 1;
            used[i] = 1;
@@ -582,6 +644,7 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
     }
     for (i = 1; i < argc && i < 32; i++) {
        if (!used[i]) {
+           _tcscpy (pathx, argv[i]);
            GetFullPathName (argv[i], MAX_DPATH, path, NULL);
            used[i] = 1;
            break;
@@ -605,7 +668,10 @@ int wmain (int argc, wchar_t *argv[], wchar_t *envp[])
 //    _tcscpy (tmppath, path);
 //    scanpath (tmppath, path);
 
-    if (match) {
+    if (crclist) {
+       docrclist (L".");
+       ok = 1;
+    } else if (match) {
        unpack2 (path, match, 0);
        ok = 1;
     } else if (!parm2 && all > 0) {