Hi, After noticing a lot of demos (especially OpenGL demos) work quite well in WINE, I decided to fix a few problems. This patch corrects three, in fact (should I have split it into three different e-mails?): - Added a very, very crude wglSwapLayerBuffers() implementation -- some demos use it instead of SwapBuffers(). - The waveOut() timer has been vastly improved. The current version of WINE does not update the timer before after the last sample, which makes some demos (notably some 64kB intros, and the minifmod sound system) loop forever in the first second because the timer is never updated. This patch adds support for polling /dev/dsp to check the actual timer. It still isn't perfect (skips sometimes), but it works a _lot_ better on the programs I've tested it on, at least. - Some programs have complained about the lack of "DISPLAY.DLL", which appearently is a pseudo-name for an internal WINE system. Commenting out a simple import in x11drv.spec prevents the loop which makes x11drv need display.dll itself -- user32 is later imported anyhow, so it shouldn't matter :-) /* Steinar */ -- Homepage: http://www.sesse.net/
diff -r -u wine-20011108/dlls/opengl32/wgl.c wine-20011108-patched/dlls/opengl32/wgl.c --- wine-20011108/dlls/opengl32/wgl.c Sun Oct 14 18:18:52 2001 +++ wine-20011108-patched/dlls/opengl32/wgl.c Sat Nov 17 02:35:53 2001 @@ -404,9 +404,19 @@ */ BOOL WINAPI wglSwapLayerBuffers(HDC hdc, UINT fuPlanes) { - FIXME("(): stub !\n"); + DC * dc = DC_GetDCPtr( hdc ); + + FIXME("(): not complete yet!\n"); + if (dc == NULL) { + ERR("Null DC !!!\n"); + return FALSE; + } else { + X11DRV_PDEVICE *physDev =(X11DRV_PDEVICE *)dc->physDev; + + glXSwapBuffers(gdi_display, physDev->drawable); + } - return FALSE; + return TRUE; } /*********************************************************************** diff -r -u wine-20011108/dlls/winmm/wineoss/audio.c wine-20011108-patched/dlls/winmm/wineoss/audio.c --- wine-20011108/dlls/winmm/wineoss/audio.c Sat Aug 18 18:09:41 2001 +++ wine-20011108-patched/dlls/winmm/wineoss/audio.c Sat Nov 17 14:18:30 2001 @@ -103,6 +103,7 @@ DWORD dwLastFragDone; /* time in ms, when last played fragment will be actually played */ DWORD dwPlayedTotal; /* number of bytes played since opening */ + DWORD dwLastFill; /* number of fragments filled at last dwPlayedTotal sync */ /* info on current lpQueueHdr->lpWaveHdr */ DWORD dwOffCurrHdr; /* offset in lpPlayPtr->lpData for fragments */ @@ -425,6 +426,11 @@ TRACE("info={frag=%d fsize=%d ftotal=%d bytes=%d}\n", info.fragments, info.fragsize, info.fragstotal, info.bytes); + if (wwo->dwLastFill != info.bytes) { + wwo->dwPlayedTotal += info.bytes - wwo->dwLastFill; + wwo->dwLastFill = info.bytes; + } + if (!info.fragments) /* output queue is full, wait a bit */ return FALSE; @@ -464,9 +470,11 @@ /* write end of current wave hdr */ count = write(wwo->unixdev, lpData + wwo->dwOffCurrHdr, toWrite); TRACE("write(%p[%5lu], %5lu) => %d\n", lpData, wwo->dwOffCurrHdr, toWrite, count); if (count > 0 || toWrite == 0) { DWORD tc = GetTickCount(); + + wwo->dwLastFill -= count; if (wwo->dwLastFragDone /* + guard time ?? */ < tc) wwo->dwLastFragDone = tc; @@ -514,6 +522,7 @@ TRACE("Tagging frag with %08lx\n", wwo->dwLastFragDone); + wwo->dwLastFill -= count; wwo->dwOffCurrHdr += count; wwo->dwRemain = wwo->dwFragmentSize; } @@ -582,7 +591,7 @@ if (lpWaveHdr->reserved > tc && !force) break; - wwo->dwPlayedTotal += lpWaveHdr->dwBufferLength; +// wwo->dwPlayedTotal += lpWaveHdr->dwBufferLength; wwo->lpQueuePtr = lpWaveHdr->lpNext; lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; @@ -602,6 +611,8 @@ */ static void wodPlayer_Reset(WINE_WAVEOUT* wwo, WORD uDevID, BOOL reset) { + struct audio_buf_info info; + /* updates current notify list */ wodPlayer_Notify(wwo, uDevID, FALSE); @@ -612,9 +623,18 @@ wwo->state = WINE_WS_STOPPED; ExitThread(-1); } + + /* find the fill */ + if (ioctl(wwo->unixdev, SNDCTL_DSP_GETOSPACE, &info) == -1) { + perror("ioctl SNDCTL_DSP_GETOSPACE"); + wwo->hThread = 0; + wwo->state = WINE_WS_STOPPED; + ExitThread(-1); + } wwo->dwOffCurrHdr = 0; wwo->dwRemain = wwo->dwFragmentSize; + wwo->dwLastFill = info.bytes; if (reset) { /* empty notify list */ wodPlayer_Notify(wwo, uDevID, TRUE); @@ -677,7 +697,6 @@ else dwSleepTime = 0; } - TRACE("imhere[1] tc = %08lx\n", GetTickCount()); if (dwSleepTime) WaitForSingleObject(wwo->msg_event, dwSleepTime); @@ -728,7 +747,7 @@ if (wwo->state == WINE_WS_PLAYING) { wodPlayer_WriteFragments(wwo); } - wodPlayer_Notify(wwo, uDevID, FALSE); + wodPlayer_Notify(wwo, uDevID, (dwSleepTime == 0)); } if (!had_msg) { /* if we've received a msg we've just done this so we @@ -736,7 +755,7 @@ if (wwo->state == WINE_WS_PLAYING) { wodPlayer_WriteFragments(wwo); } - wodPlayer_Notify(wwo, uDevID, FALSE); + wodPlayer_Notify(wwo, uDevID, (dwSleepTime == 0)); } } ExitThread(0); @@ -1110,6 +1129,7 @@ int time; DWORD val; WINE_WAVEOUT* wwo; + struct audio_buf_info info; TRACE("(%u, %p, %lu);\n", wDevID, lpTime, uSize); @@ -1121,6 +1141,15 @@ if (lpTime == NULL) return MMSYSERR_INVALPARAM; wwo = &WOutDev[wDevID]; val = wwo->dwPlayedTotal; TRACE("wType=%04X wBitsPerSample=%u nSamplesPerSec=%lu nChannels=%u nAvgBytesPerSec=%lu\n", @@ -1135,7 +1164,8 @@ TRACE("TIME_BYTES=%lu\n", lpTime->u.cb); break; case TIME_SAMPLES: - lpTime->u.sample = val * 8 / wwo->format.wBitsPerSample; + lpTime->u.sample = val * 8 / wwo->format.wBitsPerSample / + wwo->format.wf.nChannels; TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample); break; case TIME_SMPTE: diff -r -u wine-20011108/dlls/x11drv/x11drv.spec wine-20011108-patched/dlls/x11drv/x11drv.spec --- wine-20011108/dlls/x11drv/x11drv.spec Mon Oct 22 21:08:34 2001 +++ wine-20011108-patched/dlls/x11drv/x11drv.spec Sat Nov 17 01:50:30 2001 @@ -2,7 +2,7 @@ type win32 init X11DRV_Init -import user32.dll +# import user32.dll import gdi32.dll import advapi32.dll import kernel32.dll