Index: trunk/src/dsound/new/.DEPEND
===================================================================
--- trunk/src/dsound/new/.DEPEND	(revision 3027)
+++ trunk/src/dsound/new/.DEPEND	(revision 3027)
@@ -0,0 +1,325 @@
+dart.obj: \
+     dart.cpp \
+     ..\..\include\os2wrap.h \
+     ..\..\include\os2mewrap.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     .\dart.h \
+     .\dsmixer.h \
+     ..\..\include\misc.h
+
+dsmixer.obj: \
+     dsmixer.cpp \
+     ..\..\include\os2win.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     ..\..\include\win\dsound.h \
+     .\os2dsound.h \
+     .\os2sndbuffer.h \
+     .\os2notify.h \
+     ..\..\include\misc.h
+
+DSOUND.obj: \
+     DSOUND.CPP \
+     ..\..\include\os2win.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\stdio.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     ..\..\include\win\dsound.h \
+     .\os2dsound.h \
+     ..\..\include\misc.h
+
+initterm.obj: \
+     initterm.cpp \
+     ..\..\include\os2wrap.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\stdio.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     ..\..\include\odin.h \
+     ..\..\include\win32type.h \
+     ..\..\include\winconst.h \
+     ..\..\include\odinlx.h \
+     ..\..\include\misc.h
+
+misc.obj: \
+     misc.cpp \
+     ..\..\include\os2wrap.h \
+     D:\IBMCPP\INCLUDE\stdio.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     D:\IBMCPP\INCLUDE\stdarg.h \
+     ..\..\include\misc.h \
+     .\initterm.h \
+     D:\IBMCPP\INCLUDE\stddef.h \
+     D:\IBMCPP\INCLUDE\time.h
+
+OS2DSOUND.obj: \
+     OS2DSOUND.CPP \
+     ..\..\include\os2win.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     ..\..\include\win\dsound.h \
+     .\os2dsound.h \
+     .\os2sndbuffer.h \
+     .\os2primbuff.h \
+     .\os2notify.h \
+     ..\..\include\misc.h
+
+os2helper.obj: \
+     os2helper.cpp \
+     ..\..\include\os2wrap.h \
+     ..\..\include\misc.h \
+     .\asmutil.h
+
+OS2NOTIFY.obj: \
+     OS2NOTIFY.CPP \
+     ..\..\include\os2win.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     ..\..\include\win\dsound.h \
+     .\os2dsound.h \
+     .\os2sndbuffer.h \
+     .\os2notify.h \
+     ..\..\include\misc.h
+
+OS2PrimBuff.obj: \
+     OS2PrimBuff.cpp \
+     ..\..\include\os2win.h \
+     D:\IBMCPP\INCLUDE\stdio.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     ..\..\include\win\dsound.h \
+     ..\..\include\win\DSound.h \
+     .\OS2DSound.h \
+     .\OS2SndBuffer.h \
+     .\OS2PrimBuff.h \
+     .\dart.h
+
+OS2SNDBUFFER.obj: \
+     OS2SNDBUFFER.CPP \
+     ..\..\include\os2win.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\string.h \
+     D:\IBMCPP\INCLUDE\math.h \
+     ..\..\include\win\dsound.h \
+     .\os2dsound.h \
+     .\os2sndbuffer.h \
+     .\os2primbuff.h \
+     .\os2notify.h \
+     ..\..\include\misc.h
+
+asmutil.h:
+
+Dart.h:
+
+dsmixer.h:
+
+initterm.h:
+
+OS2DSOUND.H:
+
+OS2NOTIFY.H: \
+     ..\..\include\win\mmsystem.h
+
+OS2PrimBuff.h: \
+     ..\..\include\win\mmsystem.h
+
+OS2SNDBUFFER.H: \
+     ..\..\include\win\mmsystem.h
+
+asmutil.obj: \
+     asmutil.asm
+
+resource.obj: \
+     resource.asm
+
+..\..\include\codepage.h: \
+     E:\OS2TK45\H\uconv.h
+
+..\..\include\comtype.h:
+
+..\..\include\cpuhlp.h:
+
+..\..\include\dcdata.h:
+
+..\..\include\exceptions.h: \
+     ..\..\include\win32type.h \
+     ..\..\include\misc.h
+
+..\..\include\excpt.h:
+
+..\..\include\exitlist.h:
+
+..\..\include\HandleManager.h: \
+     ..\..\include\winos2def.h
+
+..\..\include\heap.h: \
+     ..\..\include\win\winbase.h
+
+..\..\include\heapcode.h: \
+     ..\..\include\heapshared.h
+
+..\..\include\heapshared.h: \
+     D:\IBMCPP\INCLUDE\stddef.h \
+     D:\IBMCPP\INCLUDE\stdlib.h \
+     D:\IBMCPP\INCLUDE\umalloc.h
+
+..\..\include\heapstring.h: \
+     ..\..\include\odin.h
+
+..\..\include\midimapr.h:
+
+..\..\include\misc.h: \
+     ..\..\include\win32type.h \
+     ..\..\include\versionos2.h \
+     ..\..\include\unicode.h
+
+..\..\include\nameid.h:
+
+..\..\include\odin.h: \
+     D:\IBMCPP\INCLUDE\builtin.h
+
+..\..\include\odinlx.h:
+
+..\..\include\odinrsrc.h:
+
+..\..\include\odinwrap.h: \
+     ..\..\include\os2sel.h \
+     D:\IBMCPP\INCLUDE\malloc.h
+
+..\..\include\os2mewrap.h: \
+     E:\OS2TK45\H\os2me.h
+
+..\..\include\os2newapi.h:
+
+..\..\include\os2sel.h:
+
+..\..\include\OS2WIN.H: \
+     ..\..\include\win32type.h \
+     ..\..\include\odin.h \
+     ..\..\include\win\windef.h \
+     ..\..\include\win\winbase.h \
+     ..\..\include\win\wingdi.h \
+     ..\..\include\win\winuser.h \
+     ..\..\include\win\winerror.h \
+     ..\..\include\win\commdlg.h \
+     ..\..\include\win\ddeml.h \
+     ..\..\include\win\mmsystem.h \
+     ..\..\include\os2sel.h \
+     ..\..\include\misc.h
+
+..\..\include\os2wrap.h: \
+     E:\OS2TK45\H\os2.h \
+     ..\..\include\os2sel.h \
+     ..\..\include\os2newapi.h
+
+..\..\include\pefile.h: \
+     E:\OS2TK45\H\os2.h \
+     ..\..\include\win32type.h \
+     ..\..\include\win\peexe.h \
+     D:\IBMCPP\INCLUDE\stdlib.h
+
+..\..\include\pmmenu.h:
+
+..\..\include\spy.h:
+
+..\..\include\unicode.h: \
+     ..\..\include\uniconv.h
+
+..\..\include\uniconv.h: \
+     D:\IBMCPP\INCLUDE\stddef.h \
+     D:\IBMCPP\INCLUDE\time.h
+
+..\..\include\versionos2.h:
+
+..\..\include\vmutex.h:
+
+..\..\include\win32type.h: \
+     ..\..\include\odin.h
+
+..\..\include\win32util.h:
+
+..\..\include\win32wnd.h:
+
+..\..\include\winaccel.h:
+
+..\..\include\winconst.h:
+
+..\..\include\wincursor.h:
+
+..\..\include\windll.h: \
+     ..\..\include\winimage.h
+
+..\..\include\windllbase.h: \
+     ..\..\include\winimagebase.h \
+     ..\..\include\odinlx.h
+
+..\..\include\windlllx.h: \
+     ..\..\include\windllbase.h \
+     ..\..\include\winimagelx.h
+
+..\..\include\windllpe2lx.h: \
+     ..\..\include\windllbase.h \
+     ..\..\include\winimagepe2lx.h
+
+..\..\include\windllpeldr.h: \
+     ..\..\include\windllbase.h \
+     ..\..\include\winimagepeldr.h
+
+..\..\include\wineuni.h:
+
+..\..\include\winexe.h: \
+     ..\..\include\winimage.h \
+     ..\..\include\windll.h
+
+..\..\include\winexebase.h: \
+     ..\..\include\winimagebase.h
+
+..\..\include\winexelx.h: \
+     ..\..\include\winexebase.h \
+     ..\..\include\winimagelx.h \
+     ..\..\include\odinlx.h
+
+..\..\include\winexepe2lx.h: \
+     ..\..\include\winexebase.h \
+     ..\..\include\winimagepe2lx.h
+
+..\..\include\winexepeldr.h: \
+     ..\..\include\winexebase.h \
+     ..\..\include\winimagepeldr.h
+
+..\..\include\winfakepeldr.h: \
+     ..\..\include\winimagepeldr.h
+
+..\..\include\winicon.h:
+
+..\..\include\winimage.h: \
+     ..\..\include\win\peexe.h \
+     D:\IBMCPP\INCLUDE\iostream.h \
+     D:\IBMCPP\INCLUDE\fstream.h
+
+..\..\include\winimagebase.h: \
+     ..\..\include\win\peexe.h
+
+..\..\include\winimagelx.h: \
+     ..\..\include\winimagebase.h
+
+..\..\include\winimagepe2lx.h: \
+     ..\..\include\winimagebase.h
+
+..\..\include\winimagepeldr.h: \
+     ..\..\include\winimagebase.h
+
+..\..\include\winkeyboard.h:
+
+..\..\include\winmenu.h:
+
+..\..\include\winos2def.h:
+
+..\..\include\winres.h:
+
+..\..\include\wprocess.h: \
+     ..\..\include\win\winprocess.h \
+     ..\..\include\winconst.h \
+     ..\..\include\win\thread.h
+
Index: trunk/src/dsound/new/DSOUND.CPP
===================================================================
--- trunk/src/dsound/new/DSOUND.CPP	(revision 3027)
+++ trunk/src/dsound/new/DSOUND.CPP	(revision 3027)
@@ -0,0 +1,243 @@
+/* $Id: DSOUND.CPP,v 1.1 2000-03-06 13:11:37 mike Exp $ */
+
+/*
+ * DirectSound exported APIs
+ *
+ * Copyright 1998 Sander van Leeuwen
+ * Copyright 2000 Michal Necasek
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+/*@Header***********************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <os2win.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define INITGUID
+#define ICOM_CINTERFACE 1
+#define CINTERFACE
+#include <dsound.h>
+
+#include "os2dsound.h"
+
+#include <misc.h>
+
+OS2IDirectSound *DS = NULL;
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API OS2DirectSoundCreate(const GUID *lpGUID,
+                                      LPDIRECTSOUND * ppDS,
+                                      IUnknown *pUnkOuter)
+{
+   OS2IDirectSound *newsound;
+   HRESULT         rc;
+
+   dprintf(("DSOUND:DirectSoundCreate %X %X %X\n", lpGUID, ppDS, pUnkOuter));
+
+   if (OS2IDirectSound::fDSExists) {
+      *ppDS = (LPDIRECTSOUND)DS;
+      DS->Vtbl.AddRef(DS);
+      return DS_OK;
+   }
+
+   newsound = new OS2IDirectSound(lpGUID);
+
+   if (newsound == NULL)
+      return DSERR_OUTOFMEMORY;
+
+   rc = newsound->GetLastError();
+   if(rc != DS_OK) {
+     *ppDS = NULL;
+     delete newsound;
+   }
+   else {
+     *ppDS = (LPDIRECTSOUND)newsound;
+     newsound->Vtbl.AddRef(newsound);
+     DS = newsound;
+   }
+   return rc;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API OS2DirectSoundCaptureCreate(const GUID *lpGUID,
+                                             LPDIRECTSOUNDCAPTURE * ppDS,
+                                             IUnknown *pUnkOuter)
+{
+   return DSERR_OUTOFMEMORY;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API OS2DirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA lpCallback,
+                                                 LPVOID lpContext)
+{
+   dprintf(("DSOUND:DirectSoundCaptureEnumerateA\n"));
+
+   lpCallback(NULL, "DART DirectSoundCapture for OS/2",
+              "DirectSoundCapture/2 v0.1", lpContext);
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API OS2DirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW lpCallback,
+                                                 LPVOID lpContext)
+{
+   dprintf(("DSOUND:DirectSoundCaptureEnumerateW\n"));
+
+   lpCallback(NULL, (LPWSTR)L"DART DirectSoundCapture for OS/2",
+              (LPWSTR)L"DirectSoundCapture/2 v0.1", lpContext);
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API OS2DirectSoundEnumerateA(LPDSENUMCALLBACKA lpCallback,
+                                          LPVOID lpContext)
+{
+   dprintf(("DSOUND:DirectSoundEnumerateA\n"));
+
+   lpCallback(NULL, "DART DirectSound for OS/2", "DirectSound/2 v0.5",
+              lpContext);
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API OS2DirectSoundEnumerateW(LPDSENUMCALLBACKW lpCallback,
+                                          LPVOID lpContext)
+{
+   dprintf(("DSOUND:DirectSoundEnumerateW\n"));
+
+   lpCallback(NULL, (LPWSTR)L"DART DirectSound for OS/2", (LPWSTR)L"DirectSound/2 v0.5",
+              lpContext);
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+
+
+/*******************************************************************************
+ * DirectSound ClassFactory
+ *
+ */
+
+typedef struct
+{
+    /* IUnknown fields */
+    ICOM_VTABLE(IClassFactory) *lpvtbl;
+    DWORD                       ref;
+} IClassFactoryImpl;
+
+static HRESULT WINAPI
+DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
+{
+  ICOM_THIS(IClassFactoryImpl,iface);
+  char buf[80];
+
+  if (HIWORD(riid))
+    WINE_StringFromCLSID(riid,buf);
+  else
+    sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
+  dprintf(("DSOUND:DSCF_QueryInterface(%p)->(%s,%p),stub!\n",This,buf,ppobj));
+  return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+DSCF_AddRef(LPCLASSFACTORY iface)
+{
+  ICOM_THIS(IClassFactoryImpl,iface);
+  return ++(This->ref);
+}
+
+static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
+{
+  ICOM_THIS(IClassFactoryImpl,iface);
+  /* static class, won't be  freed */
+  return --(This->ref);
+}
+
+static HRESULT WINAPI DSCF_CreateInstance( LPCLASSFACTORY iface,
+                                           LPUNKNOWN pOuter,
+                                           REFIID riid,
+                                           LPVOID *ppobj)
+{
+  ICOM_THIS(IClassFactoryImpl,iface);
+  LPGUID lpGUID;
+  lpGUID = (LPGUID) riid;
+
+  dprintf(("DSOUND:DSCF_CreateInstance\n"));
+  if( lpGUID && (*lpGUID == IID_IDirectSound )) {
+    return OS2DirectSoundCreate(lpGUID,(LPDIRECTSOUND*)ppobj,pOuter);
+  }
+  return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
+{
+  ICOM_THIS(IClassFactoryImpl,iface);
+  dprintf(("DSOUND:DSCF_LockServer(%p)->(%d),stub!\n",This,dolock));
+  return S_OK;
+}
+
+static ICOM_VTABLE(IClassFactory) DSCF_Vtbl =
+{
+  DSCF_QueryInterface,
+  DSCF_AddRef,
+  DSCF_Release,
+  DSCF_CreateInstance,
+  DSCF_LockServer
+};
+
+static IClassFactoryImpl DSOUND_CF = {&DSCF_Vtbl, 1 };
+
+
+HRESULT WINAPI DllGetClassObject( REFCLSID rclsid,
+                                  REFIID riid,
+                                  LPVOID *ppv)
+{
+  char buf[80],xbuf[80];
+
+  if (HIWORD(rclsid))
+    WINE_StringFromCLSID(rclsid,xbuf);
+  else
+    sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
+  if (HIWORD(riid))
+    WINE_StringFromCLSID(riid,buf);
+  else
+    sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
+  WINE_StringFromCLSID(riid,xbuf);
+
+  dprintf(("DSOUND:(%p,%p,%p)\n", xbuf, buf, ppv));
+  if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory)))
+  {
+    *ppv = (LPVOID)&DSOUND_CF;
+    DSOUND_CF.lpvtbl->AddRef((IClassFactory*)&DSOUND_CF);
+    return S_OK;
+  }
+  dprintf(("DSOUND: (%p,%p,%p): no interface found.\n", xbuf, buf, ppv));
+  return E_NOINTERFACE;
+}
+
+
+/*******************************************************************************
+ * DllCanUnloadNow   Determines whether the DLL is in use.
+ *
+ * RETURNS
+ *    Success: S_OK
+ *    Failure: S_FALSE
+ */
+HRESULT WINAPI DllCanUnloadNow(void)
+{
+  dprintf(("DSOUND:DllCanUnloadNow(void) stub\n"));
+  return S_FALSE;
+}//******************************************************************************
+
Index: trunk/src/dsound/new/DSOUND.DEF
===================================================================
--- trunk/src/dsound/new/DSOUND.DEF	(revision 3027)
+++ trunk/src/dsound/new/DSOUND.DEF	(revision 3027)
@@ -0,0 +1,18 @@
+; $Id: DSOUND.DEF,v 1.1 2000-03-06 13:11:37 mike Exp $
+
+LIBRARY DSOUND INITINSTANCE TERMINSTANCE
+PROTMODE
+DATA MULTIPLE NONSHARED READWRITE LOADONCALL
+CODE LOADONCALL
+EXPORTS
+
+   DirectSoundCreate     = _OS2DirectSoundCreate@12                @1
+   DirectSoundEnumerateA = _OS2DirectSoundEnumerateA@8             @2
+   DirectSoundEnumerateW = _OS2DirectSoundEnumerateW@8             @3
+   DirectSoundCaptureCreate     = _OS2DirectSoundCreate@12         @6
+   DirectSoundCaptureEnumerateA = _OS2DirectSoundEnumerateA@8      @7
+   DirectSoundCaptureEnumerateW = _OS2DirectSoundEnumerateW@8      @8
+
+   DllCanUnloadNow   = _DllCanUnloadNow@0                          @4
+   DllGetClassObject = _DllGetClassObject@12                       @5
+
Index: trunk/src/dsound/new/Dart.h
===================================================================
--- trunk/src/dsound/new/Dart.h	(revision 3027)
+++ trunk/src/dsound/new/Dart.h	(revision 3027)
@@ -0,0 +1,47 @@
+
+#define INVALID_PARMS 1
+#define OUT_OF_MEMORY 2
+
+#ifdef DART_DSOUND
+
+  #define E_NOTIMPL                   0x80004001
+  #define CLASS_E_NOAGGREGATION       0x80040110
+  #define E_OUTOFMEMORY               0x8007000E
+  #define E_INVALIDARG                0x80070057
+  #define E_FAIL                      0x80000008
+
+  #define DS_OK                       0
+  #define DSERR_ALLOCATED             10
+  #define DSERR_CONTROLUNAVAIL        30
+  #define DSERR_INVALIDPARAM          E_INVALIDARG
+  #define DSERR_INVALIDCALL           50
+  #define DSERR_GENERIC               E_FAIL
+  #define DSERR_PRIOLEVELNEEDED       70
+  #define DSERR_OUTOFMEMORY           E_OUTOFMEMORY
+  #define DSERR_BADFORMAT             100
+  #define DSERR_UNSUPPORTED           E_NOTIMPL
+  #define DSERR_NODRIVER              120
+  #define DSERR_ALREADYINITIALIZED    130
+  #define DSERR_NOAGGREGATION         CLASS_E_NOAGGREGATION
+  #define DSERR_BUFFERLOST            150
+  #define DSERR_OTHERAPPHASPRIO       160
+  #define DSERR_UNINITIALIZED         170
+
+#endif
+
+#define BUFFER_SIZE 16384
+#define NUM_DART_BUFFS 16
+
+long Dart_Open_Device(USHORT *pusDeviceID, void **vpMixBuffer, void **vpMixSetup,
+                      void  **vpBuffParms, void **ppvBuffer);
+
+
+long Dart_Close_Device(USHORT usDeviceID, void *vpMixBuffer, void *vpMixSetup,
+                       void *vpBuffParms );
+
+long Dart_GetPosition(USHORT usDeviceID, LONG *pulPosition);
+long Dart_Stop(USHORT usDeviceID);
+long Dart_Play(USHORT usDeviceID, void *vpMixSetup, void *vpMixBuffer, long playing);
+long Dart_SetFormat(USHORT *pusDeviceID, void *vpMixSetup, void *vpBufferParms,
+                    void *vpMixBuffer, LONG lBPS, LONG lSPS, LONG lChannels );
+
Index: trunk/src/dsound/new/OS2DSOUND.CPP
===================================================================
--- trunk/src/dsound/new/OS2DSOUND.CPP	(revision 3027)
+++ trunk/src/dsound/new/OS2DSOUND.CPP	(revision 3027)
@@ -0,0 +1,286 @@
+/* $Id: OS2DSOUND.CPP,v 1.1 2000-03-06 13:11:38 mike Exp $ */
+
+/*
+ * DirectSound main class
+ *
+ * Copyright 1998 Sander van Leeuwen
+ * Copyright 2000 Michal Necasek
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+/*@Header***********************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <os2win.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define INITGUID
+#include <dsound.h>
+
+#include "os2dsound.h"
+#include "os2sndbuffer.h"
+#include "os2primbuff.h"
+#include "os2notify.h"
+#include <misc.h>
+
+// TODO: primary buffer should probably created right away when creating the DSound
+// object
+// TODO: handle cooperative levels properly!!
+
+// this flag is set if the OS2IDirectObject exists
+BOOL OS2IDirectSound::fDSExists = FALSE;
+
+//******************************************************************************
+//******************************************************************************
+OS2IDirectSound::OS2IDirectSound(const GUID *lpGUID) : Referenced(0),
+        lastError(DS_OK), hwndClient(0)
+{
+   lpVtbl = &Vtbl;
+   Vtbl.AddRef               = SoundAddRef;
+   Vtbl.Release              = SoundRelease;
+   Vtbl.QueryInterface       = SoundQueryInterface;
+   Vtbl.Compact              = SoundCompact;
+   Vtbl.CreateSoundBuffer    = SoundCreateSoundBuffer;
+   Vtbl.GetCaps              = SoundGetCaps;
+   Vtbl.DuplicateSoundBuffer = SoundDuplicateSoundBuffer;
+   Vtbl.SetCooperativeLevel  = SoundSetCooperativeLevel;
+   Vtbl.Compact              = SoundCompact;
+   Vtbl.GetSpeakerConfig     = SoundGetSpeakerConfig;
+   Vtbl.SetSpeakerConfig     = SoundSetSpeakerConfig;
+   Vtbl.Initialize           = SoundInitialize;
+
+   dprintf(("DSOUND-OS2IDirectSound::OS2IDirectSound\n"));
+
+   speakerConfig = DSSPEAKER_STEREO;
+   CoopLevel     = DSSCL_EXCLUSIVE;  //default
+
+   OS2IDirectSound::fDSExists = TRUE;
+
+   dprintf(("Sound init OK\n"));
+}
+//******************************************************************************
+//******************************************************************************
+OS2IDirectSound::~OS2IDirectSound()
+{
+   // TODO: Close all SoundBuffers here
+   OS2IDirectSoundBuffer::DestroyAllBuffers();
+   OS2IDirectSound::fDSExists = FALSE;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
+{
+   dprintf(("DSOUND-OS2IDirectSound::QueryInterface\n"));
+   if (This == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   *ppvObj = NULL;
+
+   if (!IsEqualGUID(riid, CLSID_DirectSound) &&
+       !IsEqualGUID(riid, IID_IDirectSound))
+      return E_NOINTERFACE;
+
+   *ppvObj = This;
+
+   SoundAddRef(This);
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+ULONG WIN32API SoundAddRef(THIS)
+{
+   OS2IDirectSound *me = (OS2IDirectSound *)This;
+
+   dprintf(("DSOUND-OS2IDirectSound::AddRef %d\n", me->Referenced+1));
+   return ++me->Referenced;
+}
+
+//******************************************************************************
+//******************************************************************************
+ULONG WIN32API SoundRelease(THIS)
+{
+   OS2IDirectSound *me = (OS2IDirectSound *)This;
+
+   dprintf(("DSOUND-OS2IDirectSound::Release %d\n", me->Referenced-1));
+   if (me->Referenced) {
+      me->Referenced--;
+      if (me->Referenced == 0) {
+         delete me;
+         return 0;
+      }
+      else
+         return me->Referenced;
+   }
+   else
+      return 0;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundCompact(THIS)
+{
+  dprintf(("DSOUND-OS2IDirectSound::Compact\n"));
+  return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundCreateSoundBuffer(THIS_
+                    LPDSBUFFERDESC lpDSBufferDesc, //new, const
+                    LPDIRECTSOUNDBUFFER *lplpDirectSoundBuffer,
+                    LPUNKNOWN pUnkOuter)
+{
+   OS2IDirectSound *me = (OS2IDirectSound *)This;
+   OS2IDirectSoundBuffer *sndbuf;
+
+   dprintf(("DSOUND-OS2IDirectSound::CreateSoundBuffer\n"));
+   if (me == NULL || lpDSBufferDesc == NULL || lplpDirectSoundBuffer == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+
+   if ((lpDSBufferDesc->dwFlags & DSBCAPS_PRIMARYBUFFER) && (lpDSBufferDesc->lpwfxFormat != NULL)) {
+      // Primary buffers must be created without format info!
+      return DSERR_INVALIDPARAM;
+   }
+
+   if (lpDSBufferDesc->dwFlags & DSBCAPS_PRIMARYBUFFER) {
+      OS2PrimBuff *primbuff;
+      primbuff = new OS2PrimBuff(me, lpDSBufferDesc);
+
+      if (primbuff == NULL)
+         return DSERR_OUTOFMEMORY;
+
+      if ( primbuff->GetLastError() != DS_OK ){
+         ULONG lastErr = primbuff->GetLastError();
+
+         dprintf(("LastErr = %d\n", lastErr));
+         delete primbuff;
+         return lastErr;
+      }
+      *lplpDirectSoundBuffer = (LPDIRECTSOUNDBUFFER)primbuff;
+      primbuff->Vtbl.AddRef(primbuff);
+      dprintf(("Created PrimBuff... Exiting Create Buffer function\n"));
+
+      return DS_OK;
+   }
+
+   sndbuf = new OS2IDirectSoundBuffer(me, lpDSBufferDesc);
+   if (sndbuf == NULL) {
+      return DSERR_OUTOFMEMORY;
+   }
+   if(sndbuf->GetLastError() != DS_OK) {
+      ULONG lastErr = sndbuf->GetLastError();
+      delete sndbuf;
+      return lastErr;
+   }
+   sndbuf->Vtbl.AddRef(sndbuf);
+
+   *lplpDirectSoundBuffer = (LPDIRECTSOUNDBUFFER)sndbuf;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundGetCaps(THIS_ LPDSCAPS lpCaps)
+{
+   dprintf(("DSOUND-OS2IDirectSound::GetCaps\n"));
+
+   if (lpCaps == NULL)
+      return DSERR_INVALIDPARAM;
+
+   lpCaps->dwSize                           = sizeof(DSCAPS);
+   lpCaps->dwFlags                          = DSCAPS_SECONDARY8BIT | DSCAPS_SECONDARY16BIT  |
+                                              DSCAPS_SECONDARYMONO | DSCAPS_SECONDARYSTEREO |
+                                              DSCAPS_PRIMARY8BIT   | DSCAPS_PRIMARY16BIT    |
+                                             /* DSCAPS_PRIMARYMONO   |*/ DSCAPS_PRIMARYSTEREO;
+   lpCaps->dwMinSecondarySampleRate         = 100;
+   lpCaps->dwMaxSecondarySampleRate         = 100000;
+   lpCaps->dwPrimaryBuffers                 = 1;
+   lpCaps->dwMaxHwMixingAllBuffers          = 0;  // no HW support, no HW buffers...
+   lpCaps->dwMaxHwMixingStaticBuffers       = 0;
+   lpCaps->dwMaxHwMixingStreamingBuffers    = 0;
+   lpCaps->dwFreeHwMixingAllBuffers         = 0;
+   lpCaps->dwFreeHwMixingStaticBuffers      = 0;
+   lpCaps->dwFreeHwMixingStreamingBuffers   = 0;
+   lpCaps->dwMaxHw3DAllBuffers              = 0;
+   lpCaps->dwMaxHw3DStaticBuffers           = 0;
+   lpCaps->dwMaxHw3DStreamingBuffers        = 0;
+   lpCaps->dwFreeHw3DAllBuffers             = 0;
+   lpCaps->dwFreeHw3DStaticBuffers          = 0;
+   lpCaps->dwFreeHw3DStreamingBuffers       = 0;
+   lpCaps->dwTotalHwMemBytes                = 0;
+   lpCaps->dwFreeHwMemBytes                 = 0;
+   lpCaps->dwMaxContigFreeHwMemBytes        = 0;
+   lpCaps->dwUnlockTransferRateHwBuffers    = 0;  // no transfer needed
+   lpCaps->dwPlayCpuOverheadSwBuffers       = 0;  // we lie here...
+   lpCaps->dwReserved1                      = 0;
+   lpCaps->dwReserved2                      = 0;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundDuplicateSoundBuffer(THIS_ LPDIRECTSOUNDBUFFER, LPLPDIRECTSOUNDBUFFER )
+{
+   dprintf(("DSOUND-OS2IDirectSound::DuplicateSoundBuffer\n"));
+   return DSERR_OUTOFMEMORY;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundSetCooperativeLevel(THIS_ HWND hwndClient, DWORD level)
+{
+   OS2IDirectSound *me = (OS2IDirectSound *)This;
+
+   dprintf(("DSOUND-OS2IDirectSound::SetCooperativeLevel (to %d)\n", level));
+   if (me == NULL) {
+     return DSERR_INVALIDPARAM;
+   }
+   me->hwndClient = (HWND)hwndClient;
+   me->CoopLevel  = level;
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundGetSpeakerConfig(THIS_ LPDWORD lpSpeakerCfg)
+{
+   OS2IDirectSound *me = (OS2IDirectSound *)This;
+
+   dprintf(("DSOUND-OS2IDirectSound::GetSpeakerConfig\n"));
+   if (me == NULL) {
+      return(DSERR_INVALIDPARAM);
+   }
+   *lpSpeakerCfg = me->speakerConfig;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundSetSpeakerConfig(THIS_ DWORD speakerCfg)
+{
+   OS2IDirectSound *me = (OS2IDirectSound *)This;
+
+   dprintf(("DSOUND-OS2IDirectSound::SetSpeakerConfig %X\n", speakerCfg));
+   if (me == NULL) {
+     return DSERR_INVALIDPARAM;
+   }
+   me->speakerConfig = speakerCfg;
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundInitialize(THIS_ LPGUID)
+{
+   dprintf(("DSOUND-OS2IDirectSound::Initialize NOP\n"));
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/dsound/new/OS2DSOUND.H
===================================================================
--- trunk/src/dsound/new/OS2DSOUND.H	(revision 3027)
+++ trunk/src/dsound/new/OS2DSOUND.H	(revision 3027)
@@ -0,0 +1,76 @@
+/* $Id: OS2DSOUND.H,v 1.1 2000-03-06 13:11:38 mike Exp $ */
+
+/*
+ * DirectSound main class
+ *
+ * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#ifndef __OS2DSOUND_H__
+#define __OS2DSOUND_H__
+
+#undef THIS
+#define THIS VOID*This
+
+#undef THIS_
+#define THIS_ VOID*This,
+
+class OS2IDirectSound
+{
+ public:
+    //this one has to go first!
+    IDirectSoundVtbl *lpVtbl;
+    IDirectSoundVtbl  Vtbl;
+
+    OS2IDirectSound(const GUID *lpGUID);
+    ~OS2IDirectSound();
+
+    int           Referenced;
+
+    static  BOOL          fDSExists;
+    inline  HRESULT       GetLastError()    { return lastError;    };
+    inline  DWORD         GetCoopLevel()    { return CoopLevel;    };
+
+ private:
+
+ protected:
+          HRESULT lastError;
+
+          DWORD   speakerConfig;
+          DWORD   CoopLevel;
+          HWND    hwndClient;
+
+
+              // Linked list management
+              OS2IDirectSound* next;                   // Next OS2IDirectSound
+    static    OS2IDirectSound* dsound;                 // List of OS2IDirectSound
+
+    friend    HRESULT __stdcall SoundQueryInterface(THIS, REFIID riid, LPVOID * ppvObj);
+    friend    ULONG   __stdcall SoundAddRef(THIS);
+    friend    ULONG   __stdcall SoundRelease(THIS);
+    friend    HRESULT __stdcall SoundCreateSoundBuffer(THIS_ LPDSBUFFERDESC, LPDIRECTSOUNDBUFFER*,LPUNKNOWN);
+    friend    HRESULT __stdcall SoundGetCaps(THIS_ LPDSCAPS );
+    friend    HRESULT __stdcall SoundDuplicateSoundBuffer(THIS_ LPDIRECTSOUNDBUFFER, LPLPDIRECTSOUNDBUFFER );
+    friend    HRESULT __stdcall SoundSetCooperativeLevel(THIS_ HWND, DWORD );
+    friend    HRESULT __stdcall SoundCompact(THIS );
+    friend    HRESULT __stdcall SoundGetSpeakerConfig(THIS_ LPDWORD );
+    friend    HRESULT __stdcall SoundSetSpeakerConfig(THIS_ DWORD );
+    friend    HRESULT __stdcall SoundInitialize(THIS_ LPGUID);
+};
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundQueryInterface(THIS, REFIID riid, LPVOID * ppvObj);
+ULONG   __stdcall SoundAddRef(THIS);
+ULONG   __stdcall SoundRelease(THIS);
+HRESULT __stdcall SoundCreateSoundBuffer(THIS_ LPDSBUFFERDESC, LPDIRECTSOUNDBUFFER*,LPUNKNOWN);
+HRESULT __stdcall SoundGetCaps(THIS_ LPDSCAPS );
+HRESULT __stdcall SoundDuplicateSoundBuffer(THIS_ LPDIRECTSOUNDBUFFER, LPLPDIRECTSOUNDBUFFER );
+HRESULT __stdcall SoundSetCooperativeLevel(THIS_ HWND, DWORD );
+HRESULT __stdcall SoundCompact(THIS );
+HRESULT __stdcall SoundGetSpeakerConfig(THIS_ LPDWORD );
+HRESULT __stdcall SoundSetSpeakerConfig(THIS_ DWORD );
+HRESULT __stdcall SoundInitialize(THIS_ LPGUID);
+
+#endif
Index: trunk/src/dsound/new/OS2NOTIFY.CPP
===================================================================
--- trunk/src/dsound/new/OS2NOTIFY.CPP	(revision 3027)
+++ trunk/src/dsound/new/OS2NOTIFY.CPP	(revision 3027)
@@ -0,0 +1,178 @@
+/*
+ * DirectSound DirectSoundNotify class
+ *
+ * Copyright 2000 Michal Necasek
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+
+/*@Header***********************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define INCL_DOSMISC
+#include <os2win.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#define INITGUID
+#include <dsound.h>
+
+#include "os2dsound.h"
+#include "os2sndbuffer.h"
+#include "os2notify.h"
+#include <misc.h>
+
+//******************************************************************************
+//******************************************************************************
+OS2IDirectSoundNotify::OS2IDirectSoundNotify(OS2IDirectSoundBuffer *parentBuffer)
+{
+   lpVtbl = &Vtbl;
+   Vtbl.AddRef                   = SoundNotifyAddRef;
+   Vtbl.Release                  = SoundNotifyRelease;
+   Vtbl.QueryInterface           = SoundNotifyQueryInterface;
+   Vtbl.SetNotificationPositions = SoundNotifySetNotificationPositions;
+
+   dprintf(("DSOUND-OS2IDirectSoundNotify::OS2IDirectSoundNotify (this=%X)", this));
+
+   lpSoundBuffer = parentBuffer;
+   lpPositions   = NULL;
+   cPositions    = 0;
+   Referenced    = 0;
+
+   // add a reference to the parent SoundBuffer to make sure it won't suddenly disappear
+   lpSoundBuffer->Vtbl.AddRef(lpSoundBuffer);
+   // set pointer to ourselves in parent SoundBuffer
+   lpSoundBuffer->SetNotify(this);
+}
+
+//******************************************************************************
+//******************************************************************************
+OS2IDirectSoundNotify::~OS2IDirectSoundNotify()
+{
+   dprintf(("DSOUND-OS2IDirectSoundNotify::~OS2IDirectSoundNotify (this=%X)", this));
+   lpSoundBuffer->SetNotify(NULL);
+   lpSoundBuffer->Vtbl.Release(lpSoundBuffer);
+   if (lpPositions != NULL)
+      free(lpPositions);
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundNotifyQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
+{
+   dprintf(("DSOUND-OS2IDirectSoundNotify::QueryInterface"));
+   if (This == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   *ppvObj = NULL;
+
+   if (!IsEqualGUID(riid, IID_IDirectSoundNotify))
+      return E_NOINTERFACE;
+
+   *ppvObj = This;
+
+   SoundNotifyAddRef(This);
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+ULONG __stdcall SoundNotifyAddRef(THIS)
+{
+   OS2IDirectSoundNotify *me = (OS2IDirectSoundNotify *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundNotify::AddRef (this=%X) %d", me, me->Referenced+1));
+   if (me == NULL) {
+      return 0;
+   }
+   return ++me->Referenced;
+}
+
+//******************************************************************************
+//******************************************************************************
+ULONG __stdcall SoundNotifyRelease(THIS)
+{
+   OS2IDirectSoundNotify *me = (OS2IDirectSoundNotify *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundNotify::Release (this=%X) %d", me, me->Referenced-1));
+   if (me == NULL) {
+      return 0;
+   }
+   if (me->Referenced) {
+      me->Referenced--;
+      if (me->Referenced == 0) {
+         delete me;
+         return DS_OK;
+      }
+      else
+         return me->Referenced;
+   }
+   else
+      return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundNotifySetNotificationPositions(THIS, DWORD cPositionNotifies,
+                                            LPCDSBPOSITIONNOTIFY lpcPositionNotifies)
+{
+   OS2IDirectSoundNotify *me = (OS2IDirectSoundNotify *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundNotify::SoundNotifySetPositions (%d, this=%X)", cPositionNotifies, me));
+   if (me == NULL || lpcPositionNotifies == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+
+   // we have to copy the notifications array to our own memory here; if any notifications
+   // were registered previously, discard them
+   me->cPositions  = cPositionNotifies;
+   if (me->lpPositions != NULL)
+      free(me->lpPositions);
+   me->lpPositions = (LPDSBPOSITIONNOTIFY)malloc(cPositionNotifies * sizeof(DSBPOSITIONNOTIFY));
+   for (int i = 0; i < cPositionNotifies; i++) {
+      me->lpPositions[i].dwOffset     = lpcPositionNotifies[i].dwOffset;
+      me->lpPositions[i].hEventNotify = lpcPositionNotifies[i].hEventNotify;
+   }
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+void  OS2IDirectSoundNotify::CheckPos(DWORD dwOldpos, DWORD dwNewpos)
+{
+   //dprintf(("DSOUND-OS2IDirectSoundNotify::CheckPos (%d, %d) (this=%X)", dwOldpos, dwNewpos, this));
+   // loop thru all registered notifications and check if any offset was reached
+   DWORD   i;
+
+   for (i = 0; i < cPositions; i++) {
+      // we do NOT handle the stop notification here
+      if (lpPositions[i].dwOffset == DSBPN_OFFSETSTOP)
+         continue;
+
+      if (dwOldpos < dwNewpos) { // did we just wrap?
+         if ((lpPositions[i].dwOffset >= dwOldpos) && (lpPositions[i].dwOffset < dwNewpos))
+            SetEvent(lpPositions[i].hEventNotify);
+      } else {                   // yes we wrapped
+         if ((lpPositions[i].dwOffset >= dwOldpos) || (lpPositions[i].dwOffset < dwNewpos))
+            SetEvent(lpPositions[i].hEventNotify);
+      }
+   }
+}
+
+//******************************************************************************
+//******************************************************************************
+void  OS2IDirectSoundNotify::CheckStop()
+{
+   //dprintf(("DSOUND-OS2IDirectSoundNotify::CheckStop (this=%X)", this));
+   // just loop thru all notifications and check if DSBPN_OFFSETSTOP is there
+   DWORD   i;
+
+   for (i = 0; i < cPositions; i++) {
+      if (lpPositions[i].dwOffset == DSBPN_OFFSETSTOP)
+         SetEvent(lpPositions[i].hEventNotify);
+   }
+}
Index: trunk/src/dsound/new/OS2NOTIFY.H
===================================================================
--- trunk/src/dsound/new/OS2NOTIFY.H	(revision 3027)
+++ trunk/src/dsound/new/OS2NOTIFY.H	(revision 3027)
@@ -0,0 +1,57 @@
+/*
+ * DirectSound DirectSoundNotify class
+ *
+ * Copyright 2000 Michal Necasek
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#ifndef __OS2NOTIFY_H__
+#define __OS2NOTIFY_H__
+
+#include <mmsystem.h>
+
+#undef THIS
+#define THIS VOID*This
+
+#undef THIS_
+#define THIS_ VOID*This,
+
+class OS2IDirectSoundNotify
+{
+ public:
+    //this one has to go first!
+    IDirectSoundNotifyVtbl *lpVtbl;
+    IDirectSoundNotifyVtbl  Vtbl;
+
+    OS2IDirectSoundNotify(OS2IDirectSoundBuffer *parentBuffer);
+    ~OS2IDirectSoundNotify();
+
+    int     Referenced;
+
+    // helper functions to handle notify event signaling
+    void    CheckPos(DWORD dwOldpos, DWORD dwNewpos);
+    void    CheckStop();
+
+ private:
+
+ protected:
+    OS2IDirectSoundBuffer      *lpSoundBuffer;   // parent sound buffer
+    DWORD                      cPositions;       // # of notification positions
+    LPDSBPOSITIONNOTIFY        lpPositions;      // notify positions and associated
+                                                 // event object handles
+
+    friend    HRESULT __stdcall SoundNotifyQueryInterface(THIS, REFIID riid, LPVOID * ppvObj);
+    friend    ULONG   __stdcall SoundNotifyAddRef(THIS);
+    friend    ULONG   __stdcall SoundNotifyRelease(THIS);
+    friend    HRESULT __stdcall SoundNotifySetNotificationPositions(THIS, DWORD cPositionNotifies, LPCDSBPOSITIONNOTIFY lpcPositionNotifies);
+};
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundNotifyQueryInterface(THIS, REFIID riid, LPVOID * ppvObj);
+ULONG   __stdcall SoundNotifyAddRef(THIS);
+ULONG   __stdcall SoundNotifyRelease(THIS);
+HRESULT __stdcall SoundNotifySetNotificationPositions(THIS, DWORD cPositionNotifies, LPCDSBPOSITIONNOTIFY lpcPositionNotifies);
+
+#endif
Index: trunk/src/dsound/new/OS2PrimBuff.cpp
===================================================================
--- trunk/src/dsound/new/OS2PrimBuff.cpp	(revision 3027)
+++ trunk/src/dsound/new/OS2PrimBuff.cpp	(revision 3027)
@@ -0,0 +1,518 @@
+/*
+ *  DirectSound Primary Buffer
+ *
+ *  Copyright 1999-2000  Kevin Langman
+ *
+ *  Project Odin Software License can be found in LICENSE.TXT
+ *
+ *
+ */
+
+
+/*  NOTES:
+
+   1.  I have cheaped out and simply send a DSERR_INVALIDCALL return code
+       for many calls. I don't know if DSound does the same or not!!
+       TODO: See if windows returns this in some of the set* functions!!!
+
+   2. The Dart.cpp file is used rather then imbeding code here to avoid
+      problems with using some of the os2 multimedis headders
+      I guess I should use the ODIN version of the API's to avoid
+      the FS reset problem.. This is a TODO!
+
+   3. Here is how the buffers, GetPosition and Lock work:
+      Dart is allocated 16 buffer of 1kb each. These buffers are filled
+      when dart has finished playing one of the buffer, from a 16kb buffer
+      that the Win32 program can write to. The GetPosition function will
+      determine what buffer is being played, and return the offset to the
+      end of this buffer. The Lock function will call the GetCurrentPosition
+      function to determine where the end of the currently playing buffer is
+      and allow the Win32 program to lock between that location and 15ms from
+      there (15ms should be past the next buffer).
+
+*/
+
+#define INCL_DOSMISC
+#include <os2win.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define INITGUID
+#include <dsound.h>
+
+#include "DSound.h"
+#include "OS2DSound.h"
+#include "OS2SndBuffer.h"
+#include "OS2PrimBuff.h"
+
+#include "dart.h"
+
+//******************************************************************************
+//******************************************************************************
+OS2PrimBuff::OS2PrimBuff(OS2IDirectSound *DSound, const DSBUFFERDESC *lpDSBufferDesc )
+{
+   LONG rc;
+
+   lpVtbl = &Vtbl;
+   Vtbl.AddRef               = PrimBufAddRef;
+   Vtbl.Release              = PrimBufRelease;
+   Vtbl.QueryInterface       = PrimBufQueryInterface;
+   Vtbl.GetCaps              = PrimBufGetCaps;
+   Vtbl.GetFormat            = PrimBufGetFormat;
+   Vtbl.GetVolume            = PrimBufGetVolume;
+   Vtbl.GetStatus            = PrimBufGetStatus;
+   Vtbl.GetCurrentPosition   = PrimBufGetCurrentPosition;
+   Vtbl.GetPan               = PrimBufGetPan;
+   Vtbl.GetFrequency         = PrimBufGetFrequency;
+   Vtbl.Initialize           = PrimBufInitialize;
+   Vtbl.Restore              = PrimBufRestore;
+   Vtbl.SetFormat            = PrimBufSetFormat;
+   Vtbl.SetVolume            = PrimBufSetVolume;
+   Vtbl.SetCurrentPosition   = PrimBufSetCurrentPosition;
+   Vtbl.SetPan               = PrimBufSetPan;
+   Vtbl.SetFrequency         = PrimBufSetFrequency;
+   Vtbl.Lock                 = PrimBufLock;
+   Vtbl.Unlock               = PrimBufUnlock;
+   Vtbl.Stop                 = PrimBufStop;
+   Vtbl.Play                 = PrimBufPlay;
+
+   dprintf(("DSOUND-PrimBuff: Constructor"));
+
+   parentDS   = DSound;
+   fPlaying   = FALSE;
+   playpos    = 0;
+   fPrimary   = TRUE;
+   Referenced = 0;
+
+   lpfxFormat = (WAVEFORMATEX *)malloc(/*bufferdesc.lpwfxFormat->cbSize +*/ sizeof(WAVEFORMATEX));
+   lpfxFormat->wBitsPerSample = bps      = 16;
+   lpfxFormat->nChannels      = channels = 2;
+   lpfxFormat->nSamplesPerSec = rate     = 22500;
+
+   bufferdesc.dwBufferBytes   = BUFFER_SIZE;
+
+   lastError = Dart_Open_Device(&usDeviceID,  &vpMixBuffer, &vpMixSetup,
+                                &vpBuffParms, (PVOID*)&lpBuffer );
+
+   if (lastError == DS_OK)
+      primary = this;
+}
+
+//******************************************************************************
+//******************************************************************************
+OS2PrimBuff::~OS2PrimBuff()
+{
+   dprintf(("DSOUND-PrimBuff: Destructor"));
+
+   if (fPlaying)
+      Dart_Stop(usDeviceID);
+
+   lastError = Dart_Close_Device(usDeviceID, vpMixBuffer, vpMixSetup,
+                                 vpBuffParms );
+
+   dprintf(("DSOUND-PrimBuff: Freeing Memory"));
+   free(lpfxFormat);
+   //free( *vpMixBuffer );
+   //free( *vpMixSetup  );
+   //free( *vpBuffParms );
+   //free( vpGenericParms );
+
+   dprintf(("DSOUND-PrimBuff: Destructor Complete"));
+
+   primary = NULL;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API PrimBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
+{
+   if (This == NULL) {
+     return DSERR_INVALIDPARAM;
+   }
+   *ppvObj = NULL;
+
+   if (!IsEqualGUID(riid, IID_IDirectSoundBuffer))
+     return E_NOINTERFACE;
+
+   *ppvObj = This;
+
+   PrimBufAddRef(This);
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+ULONG WIN32API PrimBufAddRef(THIS)
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+
+   dprintf(("DSOUND-PrimBuff: AddRef %d",  me->Referenced+1));
+
+   if (me == NULL) {
+      return DS_OK;
+   }
+   return ++me->Referenced;
+}
+
+//******************************************************************************
+//******************************************************************************
+ULONG WIN32API PrimBufRelease(THIS)
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+
+   dprintf(("DSOUND-PrimBuff: Release %d", me->Referenced-1));
+
+   if (me == NULL) {
+      return DS_OK;
+   }
+   if (me->Referenced) {
+      me->Referenced--;
+      if (me->Referenced == 0) {
+         delete me;
+         return DS_OK;
+      }
+      else
+         return me->Referenced;
+   }
+   else
+      return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufGetCaps(THIS_ LPDSBCAPS lpDSCaps )
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+
+   dprintf(("DSOUND-PrimBuff: GetCaps"));
+   if(me == NULL || lpDSCaps == NULL)
+   {
+      return DSERR_INVALIDPARAM;
+   }
+
+   lpDSCaps->dwFlags              = DSBCAPS_PRIMARYBUFFER;
+   lpDSCaps->dwBufferBytes        = BUFFER_SIZE;
+   lpDSCaps->dwUnlockTransferRate = 0;
+   lpDSCaps->dwPlayCpuOverhead    = 0;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufGetCurrentPosition(THIS_ LPDWORD lpdwCurrentPlayCursor,LPDWORD lpdwCurrentWriteCursor )
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+   LONG lDartPos;
+   LONG lBytesPerSec;
+
+   dprintf(("DSOUND-PrimBuff: GetCurrentPosition"));
+
+   if (me == NULL || lpdwCurrentPlayCursor == NULL || lpdwCurrentWriteCursor == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+
+   if (me->fPlaying == FALSE) {
+      *lpdwCurrentPlayCursor  = 0;
+      *lpdwCurrentWriteCursor = 0;
+      return DS_OK;
+   }
+
+
+   Dart_GetPosition( me->usDeviceID, &lDartPos ); // Returns the Playing Buffer * 'Bytes Per Dart Bufer'
+
+   *lpdwCurrentPlayCursor  = lDartPos;
+
+   // Calculate the Write Cursor as 15ms from the current play cursor.
+   // NOTE: This may need to be changed to insure that the write cursor is always beyond the
+   //       point where the next buffer will read from.
+   *lpdwCurrentWriteCursor = (lDartPos + (me->rate * me->channels * (me->bps/8) * 15 / 1000) ) % BUFFER_SIZE;
+
+   return DS_OK;
+}
+
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufGetFormat(THIS_ LPWAVEFORMATEX lpfxFormat, DWORD dwSizeAllocated , LPDWORD lpdwSizeWritten )
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+   long copysize;
+
+   dprintf(("DSOUND-PrimBuff: GetFormat"));
+
+   if( me == NULL || lpfxFormat == NULL || dwSizeAllocated == 0)
+   {
+      return DSERR_INVALIDPARAM;
+   }
+
+   copysize = min(dwSizeAllocated, (me->lpfxFormat->cbSize + sizeof(WAVEFORMATEX)));
+   memcpy(lpfxFormat, me->lpfxFormat, copysize);
+
+   if(lpdwSizeWritten)
+   {
+      *lpdwSizeWritten = copysize;
+   }
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufGetVolume(THIS_ LPLONG )
+{
+   dprintf(("DSOUND-PrimBuff: GetVolume"));
+
+   return DSERR_INVALIDCALL;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufGetPan(THIS_ LPLONG )
+{
+   dprintf(("DSOUND-PrimBuff: GetPan"));
+
+   return DSERR_INVALIDCALL;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufGetFrequency(THIS_ LPDWORD )
+{
+   dprintf(("DSOUND-PrimBuff: GetGrequency"));
+
+   return DSERR_INVALIDCALL;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufGetStatus(THIS_ LPDWORD lpdwStatus )
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+   dprintf(("DSOUND-PrimBuff: GetStatus"));
+
+   if (me == NULL || lpdwStatus == NULL) {
+      return(DSERR_INVALIDPARAM);
+   }
+
+   *lpdwStatus = DSBSTATUS_LOOPING /*| DSBSTATUS_LOCSOFTWARE*/;
+   if (me->fPlaying == TRUE)
+      *lpdwStatus |= DSBSTATUS_PLAYING;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC )
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+   dprintf(("DSOUND-PrimBuff: Initialize"));
+
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   return DSERR_ALREADYINITIALIZED;  //todo: for future extensions (dx5/6 ??) ??
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufLock(THIS_ DWORD dwWriteCursor, DWORD dwWriteBytes,
+                              LPVOID lplpAudioPtr1, LPDWORD lpdwAudioBytes1,
+                              LPVOID lplpAudioPtr2, LPDWORD lpdwAudioBytes2,
+                              DWORD  dwFlags)
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+   DWORD dwCurPlayPos, dwCurWritePos;
+   LONG rc;
+
+   dprintf(("DSOUND-PrimBuff: Lock"));
+
+   if (me == NULL || !lplpAudioPtr1 || !lpdwAudioBytes1) {
+      return DSERR_INVALIDPARAM;
+   }
+   //not sure if this is an error, but it's certainly a smart thing to do (cond. == true)
+   if (dwWriteBytes > BUFFER_SIZE) {
+      dprintf(("SoundBufLock: dwWriteBytes > me->bufferdesc.dwBufferBytes"));
+      return DSERR_INVALIDPARAM;
+   }
+
+   if (me->fPlaying == FALSE) {
+      *(DWORD*)lplpAudioPtr1 = (DWORD)(me->lpBuffer);
+      *lpdwAudioBytes1       = dwWriteBytes;
+      if (lplpAudioPtr2 != NULL) {
+         *(DWORD*)lplpAudioPtr2 = NULL;
+         *lpdwAudioBytes2       = 0;
+      }
+      return DS_OK;
+   }
+
+   rc = PrimBufGetCurrentPosition( me, &dwCurPlayPos, &dwCurWritePos );
+   if (rc != DS_OK) {
+      return DSERR_GENERIC;
+   }
+
+   /* Debugging */
+   dprintf(("DSOUND-PrimBuff: CurPlay = %d, CurWrite = %d", dwCurPlayPos, dwCurWritePos));
+
+   if (dwFlags & DSBLOCK_FROMWRITECURSOR) {
+      dprintf(("DSOUND-PrimBuff: Locking FromCursor"));
+      dwWriteCursor = dwCurWritePos;
+   }
+
+   *(DWORD*)lplpAudioPtr1 = (DWORD)(me->lpBuffer + dwWriteCursor);
+
+   if (dwWriteCursor > dwCurPlayPos) {
+      if (dwWriteCursor + dwWriteBytes > BUFFER_SIZE) {
+         *lpdwAudioBytes1 = BUFFER_SIZE - dwWriteCursor;
+         if (lplpAudioPtr2!=NULL) {
+            *(DWORD*)lplpAudioPtr2 = (DWORD)me->lpBuffer;
+            if (dwWriteBytes - *lpdwAudioBytes1 > dwCurPlayPos) {
+               *lpdwAudioBytes2 = dwCurPlayPos;
+            } else {
+               *lpdwAudioBytes2 = dwWriteBytes - *lpdwAudioBytes1;
+            }
+         }
+      } else {
+         *lpdwAudioBytes1 = dwWriteBytes;
+         if (lplpAudioPtr2!=NULL) {
+            *(DWORD*)lplpAudioPtr2   = NULL;
+            *lpdwAudioBytes2 = 0;
+         }
+      }
+   } else { // The WriteCursor is behind of the PlayCursor
+      if (lplpAudioPtr2!=NULL) {
+         *(DWORD*)lplpAudioPtr2   = NULL;
+         *lpdwAudioBytes2 = 0;
+      }
+      if (dwWriteCursor + dwWriteBytes > dwCurPlayPos) {
+         *lpdwAudioBytes1 = dwWriteCursor - dwCurPlayPos;
+      } else {
+         *lpdwAudioBytes1 = dwWriteBytes;
+      }
+   }
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufPlay(THIS_ DWORD dwRes1,DWORD dwRes2,DWORD dwFlags )
+{
+   long rc;
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+
+   if (me == NULL || !(dwFlags & DSBPLAY_LOOPING) ) {
+     return DSERR_INVALIDPARAM;
+   }
+
+   if (me->fPlaying)
+      return DS_OK;
+
+   dprintf(("DSOUND-PrimBuff: Play"));
+
+   rc = Dart_Play(me->usDeviceID, me->vpMixSetup, me->vpMixBuffer, me->fPlaying);
+   me->fPlaying = TRUE;
+   return rc;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufSetCurrentPosition(THIS_ DWORD )
+{
+   dprintf(("DSOUND-PrimBuff: SetCurrentPosition"));
+
+   return DSERR_INVALIDCALL;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufSetFormat(THIS_ LPWAVEFORMATEX lpfxFormat )
+{
+   dprintf(("DSOUND-PrimBuff: SetFormat"));
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+
+   memcpy( me->lpfxFormat, lpfxFormat, sizeof(WAVEFORMATEX) );
+
+   me->bps      = lpfxFormat->wBitsPerSample;
+   me->rate     = lpfxFormat->nSamplesPerSec;
+   me->channels = lpfxFormat->nChannels;
+
+   dprintf(("DSOUND-PrimBuff: BPS = %d, Rate = %d, Ch = %d", me->bps, me->rate, me->channels));
+
+   Dart_SetFormat(&me->usDeviceID, me->vpMixSetup, me->vpBuffParms, me->vpMixBuffer, me->bps, me->rate, me->channels);
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufSetVolume(THIS_ LONG )
+{
+   dprintf(("DSOUND-PrimBuff: SetVolume"));
+
+   return DSERR_CONTROLUNAVAIL;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufSetPan(THIS_ LONG )
+{
+   dprintf(("DSOUND-PrimBuff: SetPan"));
+
+   return DSERR_CONTROLUNAVAIL;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufSetFrequency(THIS_ DWORD )
+{
+   dprintf(("DSOUND-PrimBuff: SetFrequency"));
+
+   return DSERR_CONTROLUNAVAIL;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufStop(THIS  )
+{
+   OS2PrimBuff *me = (OS2PrimBuff *)This;
+   dprintf(("DSOUND-PrimBuff: Stop"));
+
+   if (me == NULL) {
+     return DSERR_INVALIDPARAM;
+   }
+
+   if (!me->fPlaying)
+      return DS_OK;
+
+   me->fPlaying = FALSE;
+
+   return Dart_Stop(me->usDeviceID);
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufUnlock(THIS_ LPVOID,DWORD,LPVOID,DWORD )
+{
+   // I don't think we really need any code here.. This may be a handly place to
+
+   dprintf(("DSOUND-PrimBuff: Unlock"));
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall PrimBufRestore(THIS )
+{
+   dprintf(("DSOUND-PrimBuff: Restore"));
+
+   return DS_OK;
+}
+
+
Index: trunk/src/dsound/new/OS2PrimBuff.h
===================================================================
--- trunk/src/dsound/new/OS2PrimBuff.h	(revision 3027)
+++ trunk/src/dsound/new/OS2PrimBuff.h	(revision 3027)
@@ -0,0 +1,89 @@
+/*
+ * Direct Sound Primary Buffer Implemetation ofr ODIN
+ *
+ * Kevin Langman
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ */
+
+#ifndef __OS2PRIMBUFF_H__
+#define __OS2PRIMBUFF_H__
+
+#include <mmsystem.h>
+
+#undef THIS
+#define THIS VOID*This
+
+#undef THIS_
+#define THIS_ VOID*This,
+
+
+
+class OS2PrimBuff: public OS2IDirectSoundBuffer
+{
+ public:
+
+    OS2PrimBuff(OS2IDirectSound *DSound, const DSBUFFERDESC *lpDSBufferDesc);
+    ~OS2PrimBuff();
+
+    int     Referenced;
+    inline  HRESULT       GetLastError()    { return lastError;    };
+
+ private:
+    void *vpMixBuffer;
+    void *vpMixSetup;
+    void *vpBuffParms;
+    //void *vpGenericParms;
+
+    USHORT usDeviceID;
+
+    long  rate;    // Samples per second
+    long  bps;     // Bits per sample 8 or 16 !!
+    long  channels;// Number of Channels 1 or 2 MONO/Stereo
+
+ protected:
+    HRESULT lastError;
+
+    friend    HRESULT __stdcall PrimBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj);
+    friend    ULONG   __stdcall PrimBufAddRef(THIS);
+    friend    ULONG   __stdcall PrimBufRelease(THIS);
+    friend    HRESULT __stdcall PrimBufGetCaps(THIS_ LPDSBCAPS );
+    friend    HRESULT __stdcall PrimBufGetCurrentPosition(THIS_ LPDWORD,LPDWORD ) ;
+    friend    HRESULT __stdcall PrimBufGetFormat(THIS_ LPWAVEFORMATEX, DWORD, LPDWORD ) ;
+    friend    HRESULT __stdcall PrimBufGetVolume(THIS_ LPLONG ) ;
+    friend    HRESULT __stdcall PrimBufGetPan(THIS_ LPLONG ) ;
+    friend    HRESULT __stdcall PrimBufGetFrequency(THIS_ LPDWORD ) ;
+    friend    HRESULT __stdcall PrimBufGetStatus(THIS_ LPDWORD ) ;
+    friend    HRESULT __stdcall PrimBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC ) ;
+    friend    HRESULT __stdcall PrimBufLock(THIS_ DWORD,DWORD,LPVOID,LPDWORD,LPVOID,LPDWORD,DWORD ) ;
+    friend    HRESULT __stdcall PrimBufPlay(THIS_ DWORD,DWORD,DWORD ) ;
+    friend    HRESULT __stdcall PrimBufSetCurrentPosition(THIS_ DWORD ) ;
+    friend    HRESULT __stdcall PrimBufSetFormat(THIS_ LPWAVEFORMATEX ) ;
+    friend    HRESULT __stdcall PrimBufSetVolume(THIS_ LONG ) ;
+    friend    HRESULT __stdcall PrimBufSetPan(THIS_ LONG ) ;
+    friend    HRESULT __stdcall PrimBufSetFrequency(THIS_ DWORD ) ;
+    friend    HRESULT __stdcall PrimBufStop(THIS  ) ;
+    friend    HRESULT __stdcall PrimBufUnlock(THIS_ LPVOID,DWORD,LPVOID,DWORD ) ;
+    friend    HRESULT __stdcall PrimBufRestore(THIS  ) ;
+};
+
+HRESULT __stdcall PrimBufGetCaps(THIS_ LPDSBCAPS );
+HRESULT __stdcall PrimBufGetCurrentPosition(THIS_ LPDWORD,LPDWORD ) ;
+HRESULT __stdcall PrimBufGetFormat(THIS_ LPWAVEFORMATEX, DWORD, LPDWORD ) ;
+HRESULT __stdcall PrimBufGetVolume(THIS_ LPLONG ) ;
+HRESULT __stdcall PrimBufGetPan(THIS_ LPLONG ) ;
+HRESULT __stdcall PrimBufGetFrequency(THIS_ LPDWORD ) ;
+HRESULT __stdcall PrimBufGetStatus(THIS_ LPDWORD ) ;
+HRESULT __stdcall PrimBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC ) ;
+HRESULT __stdcall PrimBufLock(THIS_ DWORD,DWORD,LPVOID,LPDWORD,LPVOID,LPDWORD,DWORD ) ;
+HRESULT __stdcall PrimBufPlay(THIS_ DWORD,DWORD,DWORD ) ;
+HRESULT __stdcall PrimBufSetCurrentPosition(THIS_ DWORD ) ;
+HRESULT __stdcall PrimBufSetFormat(THIS_ LPWAVEFORMATEX ) ;
+HRESULT __stdcall PrimBufSetVolume(THIS_ LONG ) ;
+HRESULT __stdcall PrimBufSetPan(THIS_ LONG ) ;
+HRESULT __stdcall PrimBufSetFrequency(THIS_ DWORD ) ;
+HRESULT __stdcall PrimBufStop(THIS  ) ;
+HRESULT __stdcall PrimBufUnlock(THIS_ LPVOID,DWORD,LPVOID,DWORD ) ;
+HRESULT __stdcall PrimBufRestore(THIS  ) ;
+
+#endif
Index: trunk/src/dsound/new/OS2SNDBUFFER.CPP
===================================================================
--- trunk/src/dsound/new/OS2SNDBUFFER.CPP	(revision 3027)
+++ trunk/src/dsound/new/OS2SNDBUFFER.CPP	(revision 3027)
@@ -0,0 +1,605 @@
+/* $Id: OS2SNDBUFFER.CPP,v 1.1 2000-03-06 13:11:39 mike Exp $ */
+
+/*
+ * DirectSound SoundBuffer class
+ *
+ * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
+ * Copyright 2000 Michal Necasek
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+
+/*@Header***********************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define INCL_DOSMISC
+#include <os2win.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#define INITGUID
+#include <dsound.h>
+
+#include "os2dsound.h"
+#include "os2sndbuffer.h"
+#include "os2primbuff.h"
+#include "os2notify.h"
+#include <misc.h>
+
+
+WAVEFORMATEX wfxDefaultPrimaryBuf = { WAVE_FORMAT_PCM,
+                                      2,
+                                      22050,
+                                      44100,
+                                      2,
+                                      8,
+                                      0};
+
+OS2IDirectSoundBuffer *OS2IDirectSoundBuffer::dsbroot = NULL;
+OS2IDirectSoundBuffer *OS2IDirectSoundBuffer::primary = NULL;
+
+//******************************************************************************
+//******************************************************************************
+OS2IDirectSoundBuffer::OS2IDirectSoundBuffer(OS2IDirectSound *DSound, const DSBUFFERDESC *lpDSBufferDesc)
+        : Referenced(0), lastError(DS_OK)
+{
+   lpVtbl = &Vtbl;
+   Vtbl.AddRef               = SoundBufAddRef;
+   Vtbl.Release              = SoundBufRelease;
+   Vtbl.QueryInterface       = SoundBufQueryInterface;
+   Vtbl.GetCaps              = SoundBufGetCaps;
+   Vtbl.GetFormat            = SoundBufGetFormat;
+   Vtbl.GetVolume            = SoundBufGetVolume;
+   Vtbl.GetStatus            = SoundBufGetStatus;
+   Vtbl.GetCurrentPosition   = SoundBufGetCurrentPosition;
+   Vtbl.GetPan               = SoundBufGetPan;
+   Vtbl.GetFrequency         = SoundBufGetFrequency;
+   Vtbl.Initialize           = SoundBufInitialize;
+   Vtbl.Restore              = SoundBufRestore;
+   Vtbl.SetFormat            = SoundBufSetFormat;
+   Vtbl.SetVolume            = SoundBufSetVolume;
+   Vtbl.SetCurrentPosition   = SoundBufSetCurrentPosition;
+   Vtbl.SetPan               = SoundBufSetPan;
+   Vtbl.SetFrequency         = SoundBufSetFrequency;
+   Vtbl.Lock                 = SoundBufLock;
+   Vtbl.Unlock               = SoundBufUnlock;
+   Vtbl.Stop                 = SoundBufStop;
+   Vtbl.Play                 = SoundBufPlay;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::OS2IDirectSoundBuffer (buf=%X)", this));
+
+   // If the primary SoundBuffer doesn't exist by now, we have to create it!
+   if (primary == NULL) {
+      OS2PrimBuff *primbuff;
+      primbuff = new OS2PrimBuff(DSound, lpDSBufferDesc);
+
+      if (primary == NULL) {
+         lastError = DSERR_OUTOFMEMORY;
+         return;
+      }
+   }
+   // Add a reference to the primary buffer for _every_ secondary buffer; this makes
+   // sure that as long as a secondary buffer exists the primary buffer won't get
+   // destroyed; moreover if the user didn't create  a primary buffer himself/herself,
+   // it will automatically get created and destroyed with the last secondary buffer
+   primary->Vtbl.AddRef(primary);
+
+   // Start playing the primary buffer
+   // TODO: only start playing the primary buffer when necessary!
+   OS2IDirectSoundBuffer::primary->Vtbl.Play(OS2IDirectSoundBuffer::primary, 0, 0, DSBPLAY_LOOPING);
+
+   parentDS  = DSound;
+   writepos  = 0;
+   playpos   = 0;
+   status    = 0;
+   fLocked   = FALSE;
+   fPrimary  = FALSE;
+   volume    = 255;
+   DSvolume  = 0;
+   pan       = 0;
+   DSpan     = 0;
+   lpfxFormat= NULL;
+   lpBuffer  = NULL;
+   fPlaying  = FALSE;
+   fLoop     = FALSE;
+   notify    = NULL;
+   memcpy(&bufferdesc, lpDSBufferDesc, sizeof(DSBUFFERDESC));
+
+   // Note: this cannot be a primary buffer - those take a different route
+
+   // frequency has to be set according to the bufer format
+   frequency = bufferdesc.lpwfxFormat->nSamplesPerSec;
+
+   if (bufferdesc.lpwfxFormat == NULL || bufferdesc.dwBufferBytes == 0) {
+      dprintf(("bufferdesc not valid!"));
+      lastError = DSERR_INVALIDPARAM;
+      return;
+   }
+
+   // Some apps pass trash in cbSize, can't rely on that!
+   lpfxFormat = (WAVEFORMATEX *)malloc(/*bufferdesc.lpwfxFormat->cbSize +*/ sizeof(WAVEFORMATEX));
+   memcpy(lpfxFormat,
+          bufferdesc.lpwfxFormat,
+          /*bufferdesc.lpwfxFormat->cbSize + */sizeof(WAVEFORMATEX));
+
+   dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
+
+   lpBuffer = (LPSTR)VirtualAlloc(0, bufferdesc.dwBufferBytes, MEM_COMMIT, PAGE_READWRITE);
+   if (lpBuffer == NULL) {
+      dprintf(("VirtualAlloc failed"));
+      lpBuffer  = NULL;
+      lastError = DSERR_OUTOFMEMORY;
+      return;
+   }
+
+   next = dsbroot;
+   dsbroot = this;
+}
+
+//******************************************************************************
+//******************************************************************************
+OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer()
+{
+   /* We must not run this destructor on the primary buffer! */
+   if (fPrimary)
+      return;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer (buf=%X)", this));
+
+   // free allocted memory
+   if (lpBuffer)
+      VirtualFree(lpBuffer, 0, MEM_RELEASE);
+
+   if (lpfxFormat)
+      free(lpfxFormat);
+
+   // remove ourselves from the linked list
+   OS2IDirectSoundBuffer *cur  = dsbroot;
+   OS2IDirectSoundBuffer *prev = NULL;
+
+   // release the primary buffer too
+   primary->Vtbl.Release(primary);
+
+   if (this == dsbroot)  // is this the first SoundBuffer?
+      dsbroot = next;
+   else {                // walk the chain
+      while (cur->next != this)
+         cur  = cur->next;
+
+      cur->next = next;
+   }
+
+}
+
+//******************************************************************************
+//******************************************************************************
+void OS2IDirectSoundBuffer::DestroyAllBuffers()
+{
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::DestroyAllBuffers"));
+
+   // if any SoundBuffers still exist when the OS2IDirectSound object is
+   // being closed, just kill them all
+   OS2IDirectSoundBuffer *cur  = dsbroot;
+   OS2IDirectSoundBuffer *tmp;
+
+   if (primary != NULL)
+      primary->Vtbl.Stop(primary);
+
+   while (cur != NULL) {
+      tmp = cur->next;
+      delete cur;
+      cur = tmp;
+   }
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::DestroyAllBuffers - %X", primary));
+   if (primary != NULL)
+      primary->Vtbl.Release(primary);
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT WIN32API SoundBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
+{
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::QueryInterface"));
+   if (This == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   *ppvObj = NULL;
+
+   if (IsEqualGUID(riid, IID_IDirectSoundBuffer)) {
+      *ppvObj = This;
+
+      SoundBufAddRef(This);
+      return DS_OK;
+   }
+
+   if (IsEqualGUID(riid, IID_IDirectSoundNotify)) {
+      OS2IDirectSoundBuffer  *me     = (OS2IDirectSoundBuffer *)This;
+      OS2IDirectSoundNotify  *notify;
+
+      notify     = new OS2IDirectSoundNotify(me);
+      *ppvObj    = notify;
+      notify->Vtbl.AddRef(notify);
+      return DS_OK;
+   }
+   return E_NOINTERFACE;
+}
+//******************************************************************************
+//******************************************************************************
+ULONG WIN32API SoundBufAddRef(THIS)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::AddRef (buf=%X) %d", me, me->Referenced+1));
+   if (me == NULL) {
+      return 0;
+   }
+   return ++me->Referenced;
+}
+//******************************************************************************
+//******************************************************************************
+ULONG WIN32API SoundBufRelease(THIS)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::Release (buf=%X) %d", me, me->Referenced-1));
+   if (me == NULL) {
+      return 0;
+   }
+   if (me->Referenced) {
+      me->Referenced--;
+      if (me->Referenced == 0) {
+         delete me;
+         return 0;
+      }
+      else
+         return me->Referenced;
+   }
+   else
+      return 0;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufGetCaps(THIS_ LPDSBCAPS lpDSCaps)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetCaps (buf=%X)", me));
+   if (me == NULL || lpDSCaps == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   /* FIXME: fill with more realistic values */
+   lpDSCaps->dwSize               = sizeof(DSBCAPS);
+   lpDSCaps->dwFlags              = me->bufferdesc.dwFlags | DSBCAPS_LOCSOFTWARE;
+   lpDSCaps->dwBufferBytes        = me->bufferdesc.dwBufferBytes;
+   lpDSCaps->dwUnlockTransferRate = 0;     /* in KB/sec - 0 == no transfer needed */
+   lpDSCaps->dwPlayCpuOverhead    = 0;     /* % CPU time - let's lie */
+
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufGetCurrentPosition(THIS_ LPDWORD lpdwCurrentPlayCursor,
+                         LPDWORD lpdwCurrentWriteCursor)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetCurrentPosition (buf=%X)", me));
+   if ( me == NULL || lpdwCurrentPlayCursor == NULL || lpdwCurrentWriteCursor == NULL) {
+     dprintf(("  Invalid parameters %d %d %d",me,lpdwCurrentPlayCursor,lpdwCurrentWriteCursor));
+     return DSERR_INVALIDPARAM;
+   }
+
+   dprintf(("  PlayPos %d, WritePos %d", me->playpos, me->writepos));
+   *lpdwCurrentPlayCursor  = me->playpos;
+   *lpdwCurrentWriteCursor = me->writepos;
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufGetFormat(THIS_ LPWAVEFORMATEX lpwfxFormat,
+                    DWORD ddwSizeAllocated, LPDWORD lpdwSizeWritten)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+   int copysize;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetFormat (buf=%X)", me));
+   if (me == NULL || lpwfxFormat == NULL || ddwSizeAllocated == 0) {
+      return DSERR_INVALIDPARAM;
+   }
+   copysize = min(ddwSizeAllocated, (me->lpfxFormat->cbSize + sizeof(WAVEFORMATEX)));
+   memcpy(lpwfxFormat, me->lpfxFormat, copysize);
+
+   if (lpdwSizeWritten) {
+      *lpdwSizeWritten = copysize;
+   }
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufGetVolume(THIS_ LPLONG lplVolume)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetVolume (buf=%X)", me));
+   if (me == NULL || lplVolume == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   *lplVolume = me->DSvolume;
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufGetPan(THIS_ LPLONG lplPan)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetPan (buf=%X)", me));
+   if (me == NULL || lplPan == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   *lplPan = me->DSpan;
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufGetFrequency(THIS_ LPDWORD lpdwFrequency)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetFrequency (buf=%X)", me));
+   if (me == NULL || lpdwFrequency == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   *lpdwFrequency = me->frequency;
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufGetStatus(THIS_ LPDWORD lpdwStatus)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetStatus (buf=%X)", me));
+   if (me == NULL || lpdwStatus == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+
+   if (me->fPlaying)
+      if (me->fLoop)
+         me->status |= DSBSTATUS_PLAYING | DSBSTATUS_LOOPING;
+      else
+         me->status |= DSBSTATUS_PLAYING;
+   else
+      me->status  &= ~(DSBSTATUS_PLAYING | DSBSTATUS_LOOPING);
+
+   *lpdwStatus = me->status;
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC )
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-SoundBufInitialize (buf=%X)", me));
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   return DSERR_ALREADYINITIALIZED;  //todo: for future extensions (dx5/6 ??)
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufLock(THIS_ DWORD dwWriteCursor, DWORD dwWriteBytes,
+                   LPVOID lplpvAudioPtr1, LPDWORD lpdwAudioBytes1,
+                   LPVOID lplpvAudioPtr2, LPDWORD lpdwAudioBytes2,
+                   DWORD dwFlags)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufLock (buf=%X, %d bytes)", me, dwWriteBytes));
+   if (me == NULL || !lplpvAudioPtr1 || !lpdwAudioBytes1)
+      return DSERR_INVALIDPARAM;
+
+   //not sure if this is an error, but it's certainly a smart thing to do (cond. == true)
+   if(dwWriteBytes > me->bufferdesc.dwBufferBytes) {
+      dprintf(("SoundBufLock: dwWriteBytes > me->bufferdesc.dwBufferBytes"));
+      return DSERR_INVALIDPARAM;
+   }
+   if (dwFlags & DSBLOCK_FROMWRITECURSOR) {
+      dwWriteCursor = me->writepos;
+   }
+   if (dwWriteCursor + dwWriteBytes > me->bufferdesc.dwBufferBytes) {
+      *(DWORD *)lplpvAudioPtr1  = (DWORD)(me->lpBuffer + dwWriteCursor);
+      *lpdwAudioBytes1          = me->bufferdesc.dwBufferBytes - dwWriteCursor;
+      if (lplpvAudioPtr2 && lpdwAudioBytes2) {
+         *(DWORD *)lplpvAudioPtr2   = (DWORD)me->lpBuffer;
+         *lpdwAudioBytes2           = dwWriteBytes - *lpdwAudioBytes1;
+      }
+   }
+   else {
+      *(DWORD *)lplpvAudioPtr1  = (DWORD)(me->lpBuffer + dwWriteCursor);
+      *lpdwAudioBytes1          = dwWriteBytes;
+      if (lplpvAudioPtr2 && lpdwAudioBytes2) {
+         *(DWORD *)lplpvAudioPtr2   = 0;
+         *lpdwAudioBytes2           = 0;
+      }
+   }
+
+   me->fLocked = TRUE;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufPlay(THIS_ DWORD dwRes1, DWORD dwRes2, DWORD dwFlags)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   ULONG ulBytesToPlay;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufPlay (buf=%X)", me));
+   if (me == NULL) {
+      dprintf(("  Invalid parms - me is NULL"));
+      return DSERR_INVALIDPARAM;
+   }
+
+   me->frac     = 0;
+   me->fPlaying = TRUE;
+   me->status   = DSBSTATUS_PLAYING;
+   me->fLoop = dwFlags == DSBPLAY_LOOPING;
+   if (me->fLoop)
+      me->status |= DSBSTATUS_LOOPING;
+
+   dprintf(("  Buffer %X: start at pos %d, loop %s",me, me->playpos, me->fLoop?"YES":"NO"));
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufSetCurrentPosition(THIS_ DWORD dwNewPosition)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetCurrentPosition (buf=%X) to %d", me, dwNewPosition));
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   me->playpos   = dwNewPosition;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX lpWaveFormatEx)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   // Note: this sets the format of the _primary_ buffer;
+   // since this class only handles secondary buffers, we just return error
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetFormat (buf=%X)", me));
+
+   return DSERR_UNSUPPORTED;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufSetVolume(THIS_ LONG lVolume)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetVolume (buf=%X)", me));
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   me->DSvolume = lVolume;
+
+   /* = (10 ^ (1/10)) = 1dB - but the formula below gives results _very_ similar */
+   /* to 'real' DirectSound, indistinguishable for all practical purposes        */
+   me->volume = 255.0 * pow(4, lVolume / 1000.0);
+
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufSetPan(THIS_ LONG lPan)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetPan (buf=%X)", me));
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   me->DSpan = lPan;
+   if (lPan == 0) {
+      me->pan = 0;
+      return DS_OK;
+   }
+
+   /* Note: the formula below is not necessarily mathematically correct but is */
+   /* experimentally proven to give very good results                          */
+   me->pan = 255.0 * pow(4, -abs(lPan) / 1000.0);
+   me->pan = 255 - me->pan;
+   if (lPan < 0)
+      me->pan = -me->pan;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufSetFrequency(THIS_ DWORD dwFrequency)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetFrequency (buf=%X)", me));
+   if (me == NULL) {
+     return DSERR_INVALIDPARAM;
+   }
+
+   // zero means default (buffer format) frequency
+   if (dwFrequency)
+      me->frequency = dwFrequency;
+   else
+     me->frequency = me->lpfxFormat->nSamplesPerSec;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufStop(THIS  )
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufStop (buf=%X)", me));
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+
+   me->fPlaying = FALSE;
+   me->status  &= ~(DSBSTATUS_PLAYING | DSBSTATUS_LOOPING);
+
+   if (me->notify != NULL)
+      me->notify->CheckStop();
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufUnlock(THIS_
+                                 LPVOID lpvAudioPtr1, DWORD dwAudioBytes1,
+                                 LPVOID lpvAudioPtr2, DWORD dwAudioBytes2)
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufUnlock (buf=%X)", me));
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+
+   me->fLocked = TRUE;
+
+   return DS_OK;
+}
+
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufRestore(THIS  )
+{
+   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
+
+   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufRestore (buf=%X)", me));
+   if (me == NULL) {
+      return DSERR_INVALIDPARAM;
+   }
+   return DS_OK;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/dsound/new/OS2SNDBUFFER.H
===================================================================
--- trunk/src/dsound/new/OS2SNDBUFFER.H	(revision 3027)
+++ trunk/src/dsound/new/OS2SNDBUFFER.H	(revision 3027)
@@ -0,0 +1,121 @@
+/* $Id: OS2SNDBUFFER.H,v 1.1 2000-03-06 13:11:39 mike Exp $ */
+
+/*
+ * DirectSound SoundBuffer class
+ *
+ * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#ifndef __OS2SNDBUFFER_H__
+#define __OS2SNDBUFFER_H__
+
+#include <mmsystem.h>
+
+#undef THIS
+#define THIS VOID*This
+
+#undef THIS_
+#define THIS_ VOID*This,
+
+// a forward declaration of the Notify class is needed here!
+class OS2IDirectSoundNotify;
+
+class OS2IDirectSoundBuffer
+{
+ public:
+    //this one has to go first!
+    IDirectSoundBufferVtbl *lpVtbl;
+    IDirectSoundBufferVtbl  Vtbl;
+
+    OS2IDirectSoundBuffer(OS2IDirectSound *DSound, const DSBUFFERDESC *lpDSBufferDesc);
+    OS2IDirectSoundBuffer() {};
+    ~OS2IDirectSoundBuffer();
+
+    static void OS2IDirectSoundBuffer::DestroyAllBuffers(); // called when DSound is closed
+
+    int     Referenced;
+    inline  HRESULT       GetLastError()    { return lastError;    };
+    inline  void          SetNotify(OS2IDirectSoundNotify *_notify) {
+                                    notify = _notify; };
+ private:
+
+ protected:
+    HRESULT lastError;
+
+    ULONG writepos, playpos;   // DSound write and play cursors
+    ULONG frequency;           // DSB frequency - may differ from source sample
+    WAVEFORMATEX *lpfxFormat;  // source sample format
+    ULONG status;              // DSB status - playing, looping etc.
+    BOOL  fLocked;             // is buffer currently locked?
+    BOOL  fPrimary;            // is this a primary buffer?
+    DWORD DSvolume;            // DSB volume (in dB)
+    LONG  volume;              // volume (linear)
+    LONG  DSpan;               // DSB pan (in dB)
+    LONG  pan;                 // pan (linear)
+    BOOL  fPlaying,fLoop;      // is buffer playing/looping?
+    DSBUFFERDESC bufferdesc;   // DSB description
+    LONG  frac;                // saved mixer position overflow
+
+    char *lpBuffer;            // sound data
+
+    OS2IDirectSoundNotify* notify;  // pointer to the associated Notify object (if exists)
+    OS2IDirectSound*       parentDS;
+
+              // Linked list management
+              OS2IDirectSoundBuffer* next;                   // Next OS2IDirectSoundBuffer
+    static    OS2IDirectSoundBuffer* dsbroot;                // List of OS2IDirectSoundBuffers
+    static    OS2IDirectSoundBuffer* primary;                // The primary SoundBuffer
+
+    friend    HRESULT __stdcall SoundBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj);
+    friend    ULONG   __stdcall SoundBufAddRef(THIS);
+    friend    ULONG   __stdcall SoundBufRelease(THIS);
+    friend    HRESULT __stdcall SoundBufGetCaps(THIS_ LPDSBCAPS );
+    friend    HRESULT __stdcall SoundBufGetCurrentPosition(THIS_ LPDWORD,LPDWORD ) ;
+    friend    HRESULT __stdcall SoundBufGetFormat(THIS_ LPWAVEFORMATEX, DWORD, LPDWORD ) ;
+    friend    HRESULT __stdcall SoundBufGetVolume(THIS_ LPLONG ) ;
+    friend    HRESULT __stdcall SoundBufGetPan(THIS_ LPLONG ) ;
+    friend    HRESULT __stdcall SoundBufGetFrequency(THIS_ LPDWORD ) ;
+    friend    HRESULT __stdcall SoundBufGetStatus(THIS_ LPDWORD ) ;
+    friend    HRESULT __stdcall SoundBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC ) ;
+    friend    HRESULT __stdcall SoundBufLock(THIS_ DWORD,DWORD,LPVOID,LPDWORD,LPVOID,LPDWORD,DWORD ) ;
+    friend    HRESULT __stdcall SoundBufPlay(THIS_ DWORD,DWORD,DWORD ) ;
+    friend    HRESULT __stdcall SoundBufSetCurrentPosition(THIS_ DWORD ) ;
+    friend    HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX ) ;
+    friend    HRESULT __stdcall SoundBufSetVolume(THIS_ LONG ) ;
+    friend    HRESULT __stdcall SoundBufSetPan(THIS_ LONG ) ;
+    friend    HRESULT __stdcall SoundBufSetFrequency(THIS_ DWORD ) ;
+    friend    HRESULT __stdcall SoundBufStop(THIS  ) ;
+    friend    HRESULT __stdcall SoundBufUnlock(THIS_ LPVOID,DWORD,LPVOID,DWORD ) ;
+    friend    HRESULT __stdcall SoundBufRestore(THIS  ) ;
+
+    friend    void MixCallback(ULONG cbMix);
+    friend    void MixFunc (OS2IDirectSoundBuffer *firstBuf, OS2IDirectSoundBuffer *outBuf, ULONG cbMix);
+    friend    void MixOneBuffer(OS2IDirectSoundBuffer *inBuf, int tomix, int outrate);
+};
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SoundBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj);
+ULONG   __stdcall SoundBufAddRef(THIS);
+ULONG   __stdcall SoundBufRelease(THIS);
+HRESULT __stdcall SoundBufGetCaps(THIS_ LPDSBCAPS );
+HRESULT __stdcall SoundBufGetCurrentPosition(THIS_ LPDWORD,LPDWORD ) ;
+HRESULT __stdcall SoundBufGetFormat(THIS_ LPWAVEFORMATEX, DWORD, LPDWORD ) ;
+HRESULT __stdcall SoundBufGetVolume(THIS_ LPLONG ) ;
+HRESULT __stdcall SoundBufGetPan(THIS_ LPLONG ) ;
+HRESULT __stdcall SoundBufGetFrequency(THIS_ LPDWORD ) ;
+HRESULT __stdcall SoundBufGetStatus(THIS_ LPDWORD ) ;
+HRESULT __stdcall SoundBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC ) ;
+HRESULT __stdcall SoundBufLock(THIS_ DWORD,DWORD,LPVOID,LPDWORD,LPVOID,LPDWORD,DWORD ) ;
+HRESULT __stdcall SoundBufPlay(THIS_ DWORD,DWORD,DWORD ) ;
+HRESULT __stdcall SoundBufSetCurrentPosition(THIS_ DWORD ) ;
+HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX ) ;
+HRESULT __stdcall SoundBufSetVolume(THIS_ LONG ) ;
+HRESULT __stdcall SoundBufSetPan(THIS_ LONG ) ;
+HRESULT __stdcall SoundBufSetFrequency(THIS_ DWORD ) ;
+HRESULT __stdcall SoundBufStop(THIS  ) ;
+HRESULT __stdcall SoundBufUnlock(THIS_ LPVOID,DWORD,LPVOID,DWORD ) ;
+HRESULT __stdcall SoundBufRestore(THIS  ) ;
+
+#endif
Index: trunk/src/dsound/new/dart.cpp
===================================================================
--- trunk/src/dsound/new/dart.cpp	(revision 3027)
+++ trunk/src/dsound/new/dart.cpp	(revision 3027)
@@ -0,0 +1,354 @@
+/*
+ *  Kevin Langman
+ *
+ *  The Dart functions are here to avoid the conficts with the
+ *  the OS/2 mcios2.h, meerror.h, os2medef.h and mmsystem.h
+ *
+ */
+
+#define INCL_DOS
+#define INCL_OS2MM
+#include <os2wrap.h>
+#include <os2mewrap.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#define DART_DSOUND
+#include "dart.h"
+#include "dsmixer.h"
+
+#include <misc.h>
+
+static MCI_MIXSETUP_PARMS *MixSetup_Global;
+static MCI_MIX_BUFFER     *pMixBuffs;
+static long               lLastBuff;
+static char               *pDSoundBuff;
+
+USHORT               usDeviceID;                 /* Amp Mixer device id          */
+MCI_MIX_BUFFER       MixBuffers[NUM_DART_BUFFS]; /* Device buffers               */
+MCI_MIXSETUP_PARMS   MixSetupParms;              /* Mixer parameters             */
+MCI_BUFFER_PARMS     BufferParms;                /* Device buffer parms          */
+
+
+#define ULONG_LOWD(ul)  (*(USHORT *)((ULONG *)(&ul)))     /* Low  Word */
+
+//******************************************************************************
+//******************************************************************************
+LONG APIENTRY OS2_Dart_Update(ULONG ulStatus,PMCI_MIX_BUFFER pBuffer,ULONG ulFlags)
+{
+   //MCI_STATUS_PARMS Status;
+   ULONG           rc;
+
+   if ((ulFlags == MIX_WRITE_COMPLETE) ||
+       ((ulFlags == (MIX_WRITE_COMPLETE | MIX_STREAM_ERROR))&&
+       (ulStatus == ERROR_DEVICE_UNDERRUN)))
+   {
+      lLastBuff++;
+      if (lLastBuff == NUM_DART_BUFFS)
+         lLastBuff = 0;
+
+      /* Now mix sound from all playing secondary SoundBuffers into the primary buffer */
+      MixCallback(BUFFER_SIZE/NUM_DART_BUFFS);
+
+      /* Fill The next buff from the DSound Buffer */
+      memcpy( pMixBuffs[lLastBuff].pBuffer, &pDSoundBuff[lLastBuff*(BUFFER_SIZE/NUM_DART_BUFFS)], BUFFER_SIZE/NUM_DART_BUFFS );
+
+      /* Send the NEXT Buffer to Dart for playing! */
+      rc = MixSetup_Global->pmixWrite(MixSetup_Global->ulMixHandle, &pMixBuffs[lLastBuff], 1 );
+      //dprintf(("DSOUND-DART: Playing Next Buffer %d", rc));
+   }
+
+   return TRUE;
+}
+
+
+long Dart_Open_Device(USHORT *pusDeviceID, void **vpMixBuffer, void **vpMixSetup,
+                      void **vpBuffParms,  void **ppvBuffer)
+{
+
+   MCI_AMP_OPEN_PARMS  AmpOpenParms;
+   //MCI_WAVE_SET_PARMS WaveSetParms;
+   ULONG   rc;
+   short   device = 0;
+
+   dprintf(("DSOUND-DART: Dart_Open_Device"));
+
+   *vpMixBuffer    = &MixBuffers;
+   *vpMixSetup     = &MixSetupParms;
+   *vpBuffParms    = &BufferParms;
+
+   pMixBuffs = &MixBuffers[0];
+   lLastBuff = 0;
+
+   /* Is there a way to avoid the use of the MixSetup_Global ????? */
+   MixSetup_Global = &MixSetupParms;
+   /****************************************************************/
+
+   // If the DSOUND_DEVICE is set then use that number as the device for DART.
+   // this will allow people with many sound cards to use the card of their choice
+   // for an instance of a DSOUND enabled app!
+   if (getenv("DSOUND_DEVICE") != NULL) {
+      device = atoi(getenv("DSOUND_DEVICE"));
+   }
+
+   /* Open the AmpMix Device and start processing the buffer! */
+   memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
+   AmpOpenParms.usDeviceID    = 0;
+   AmpOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
+
+   rc = mciSendCommand(0, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE_ID, (PVOID)&AmpOpenParms, 0);
+   if (rc != MCIERR_SUCCESS) {
+      dprintf(("DSOUND-DART: MCI_OPEN %d", rc));
+      return DSERR_GENERIC;
+   }
+   *pusDeviceID = AmpOpenParms.usDeviceID;
+   usDeviceID   = AmpOpenParms.usDeviceID;
+
+   /* setup playback parameters */
+   memset(&MixSetupParms, 0, sizeof(MCI_MIXSETUP_PARMS));
+   MixSetupParms.ulBitsPerSample  = 16;
+   MixSetupParms.ulFormatTag      = MCI_WAVE_FORMAT_PCM;
+   MixSetupParms.ulSamplesPerSec  = 22500;
+   MixSetupParms.ulChannels       = 2;
+   MixSetupParms.ulFormatMode     = MCI_PLAY;
+   MixSetupParms.ulDeviceType     = MCI_DEVTYPE_WAVEFORM_AUDIO;
+   MixSetupParms.pmixEvent        = OS2_Dart_Update;
+
+   rc = mciSendCommand(usDeviceID, MCI_MIXSETUP, MCI_WAIT | MCI_MIXSETUP_INIT,
+                      (PVOID)&MixSetupParms, 0);
+   if (rc != MCIERR_SUCCESS) {
+      dprintf(("DSOUND-DART: MCI_MIXSETUP (Constructor) %d", rc));
+      return DSERR_GENERIC;
+   }
+
+   /* Create the Audio Buffer */
+   // OK... Since DSound only uses 1 buffer and uses the GetPosition API to
+   // figure out where it can and can't write, I have emulating this by
+   // using 16 1kb buffers and do locking by tracking what buffer is currently
+   // playing. This maybe less CPU friendly then other methods but it's the best
+   // my little brain could come up with!!
+
+   MixSetupParms.ulBufferSize = BUFFER_SIZE/NUM_DART_BUFFS;
+
+//   BufferParms->ulStructLength = sizeof(MCI_BUFFER_PARMS);
+   BufferParms.ulNumBuffers   = NUM_DART_BUFFS;
+   BufferParms.ulBufferSize   = MixSetupParms.ulBufferSize;
+   BufferParms.pBufList       = MixBuffers;
+
+   rc = mciSendCommand(usDeviceID, MCI_BUFFER, MCI_WAIT | MCI_ALLOCATE_MEMORY,
+                                (PVOID)&BufferParms, 0);
+   if ( ULONG_LOWD(rc) != MCIERR_SUCCESS ) {
+      dprintf(("DSOUND-DART: MCI_BUFFER (Alloc) %d", rc));
+      mciSendCommand(*pusDeviceID, MCI_CLOSE, MCI_WAIT, NULL, 0);
+      return DSERR_OUTOFMEMORY;
+   }
+
+   /* Clear the Buffer */
+   // Todo:  I don't know if Dart expects Signed or Unsigned data... This will
+   // ok until I look in to this... Also it may be that Dart uses signed for
+   // 8bit data and unsigned for 16it.. Anyhow the worst that can happen by setting
+   // the buffer to 0 is a click on Dart_Play and a Clink when real sound is written
+   // to the buffer!
+   for (device = 0; device < NUM_DART_BUFFS; device++) {
+      memset(MixBuffers[device].pBuffer, 0, BUFFER_SIZE/NUM_DART_BUFFS);
+   }
+
+   // Allocate memory for the DSound "Holder" buffer.
+   // TODO: Move this to the Constructor for OS2PrimBuff
+   //       so that the Deconstructor can be used to free the memory!
+   *(char**)ppvBuffer = (char*)malloc(BUFFER_SIZE);
+   if (*ppvBuffer == NULL) {
+      return DSERR_OUTOFMEMORY;
+   }
+   pDSoundBuff = (char*)(*ppvBuffer);
+
+   dprintf(("DSOUND-DART: Dart_Open_Device Exiting"));
+
+   return DS_OK;
+}
+
+long Dart_Close_Device(USHORT usDeviceID, void *vpMixBuffer, void *vpMixSetup,
+                       void *vpBuffParms )
+{
+   MCI_MIX_BUFFER      *MixBuffer;
+   MCI_MIXSETUP_PARMS  *MixSetup;
+   MCI_BUFFER_PARMS    *BufferParms;
+
+   dprintf(("DSOUND-DART: Dart_Close_Device"));
+
+   MixBuffer   = (MCI_MIX_BUFFER*)vpMixBuffer;
+   MixSetup    = (MCI_MIXSETUP_PARMS*)vpMixSetup;
+   BufferParms = (MCI_BUFFER_PARMS*)vpBuffParms;
+
+    if (MixBuffer->pBuffer) {
+       mciSendCommand(usDeviceID,MCI_BUFFER,MCI_WAIT|MCI_DEALLOCATE_MEMORY, BufferParms,0);
+       MixBuffer->pBuffer=NULL;
+    }
+    if (usDeviceID) {
+        mciSendCommand(usDeviceID,MCI_CLOSE,MCI_WAIT, NULL, 0);
+        usDeviceID=0;
+    }
+
+   dprintf(("DSOUND-DART: Dart_Close_Device returning DS_OK"));
+   return DS_OK;
+}
+
+
+long Dart_GetPosition(USHORT usDeviceID, LONG *pulPosition)
+{
+   dprintf(("DSOUND-DART: Dart_GetPosition"));
+
+   *pulPosition = (lLastBuff * (BUFFER_SIZE/NUM_DART_BUFFS)) + (BUFFER_SIZE/NUM_DART_BUFFS);
+   if (*pulPosition > BUFFER_SIZE)
+      *pulPosition = 0;
+
+   dprintf(("DSOUND-DART: Returning %d", *pulPosition));
+
+   return DS_OK;
+}
+
+long Dart_SetFormat(USHORT *pusDeviceID, void *vpMixSetup, void *vpBufferParms, void *vpMixBuffer, LONG lBPS, LONG lSPS, LONG lChannels )
+{
+   ULONG   rc;
+   MCI_MIXSETUP_PARMS  *MixSetup;
+   MCI_BUFFER_PARMS    *BufferParms;
+   MCI_MIX_BUFFER      *MixBuffer;
+   MCI_AMP_OPEN_PARMS  AmpOpenParms;
+   short               device = 0;
+
+   MixSetup    = (MCI_MIXSETUP_PARMS*)vpMixSetup;
+   BufferParms = (MCI_BUFFER_PARMS*)vpBufferParms;
+   MixBuffer   = (MCI_MIX_BUFFER*)vpMixBuffer;
+
+   dprintf(("DSOUND-DART: Dart_SetFormat"));
+
+   // If the DSOUND_DEVICE is set then use that number as the device for DART.
+   // this will allow people with many sound cards to use the card of there choice
+   // for an instance of a DSOUND enabled app!
+   if (getenv("DSOUND_DEVICE") != NULL) {
+      device = atoi(getenv( "DSOUND_DEVICE" ));
+   }
+
+   /* Dealloc to avoid the 5511 error */
+   rc = mciSendCommand(*pusDeviceID, MCI_BUFFER, MCI_WAIT | MCI_DEALLOCATE_MEMORY,
+                       BufferParms, 0);
+   if (rc != MCIERR_SUCCESS) {
+      dprintf(("DSOUND-DART: MCI_DEALLOCATE_MEMORY (SetFormat) %d", rc));
+      return DSERR_GENERIC;
+   }
+
+   rc = mciSendCommand(*pusDeviceID, MCI_CLOSE, MCI_WAIT, NULL, 0);
+   if (rc != MCIERR_SUCCESS) {
+      dprintf(("DSOUND-DART: MCI_CLOSE (SetFormat) %d", rc));
+      return(DSERR_GENERIC);
+   }
+
+   /* Reopen the MixAmp Device and start processing the buffer! */
+   memset(&AmpOpenParms,0,sizeof(MCI_AMP_OPEN_PARMS));
+   AmpOpenParms.usDeviceID    = 0;
+   AmpOpenParms.pszDeviceType = (PSZ)MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX, (USHORT)device);
+
+   rc = mciSendCommand(0, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE_ID, (PVOID)&AmpOpenParms, 0);
+   if (rc != MCIERR_SUCCESS) {
+      dprintf(("DSOUND-DART: MCI_OPEN %d", rc));
+      return DSERR_GENERIC;
+   }
+   *pusDeviceID = AmpOpenParms.usDeviceID;
+
+   /* setup playback parameters */
+   memset(MixSetup, 0, sizeof(MCI_MIXSETUP_PARMS));
+   MixSetup->ulBitsPerSample  = lBPS;
+   MixSetup->ulFormatTag      = MCI_WAVE_FORMAT_PCM;
+   MixSetup->ulSamplesPerSec  = lSPS;
+   MixSetup->ulChannels       = lChannels;
+   MixSetup->ulFormatMode     = MCI_PLAY;
+   MixSetup->ulDeviceType     = MCI_DEVTYPE_WAVEFORM_AUDIO;
+   MixSetup->pmixEvent        = OS2_Dart_Update;
+
+   rc = mciSendCommand(*pusDeviceID, MCI_MIXSETUP, MCI_WAIT | MCI_MIXSETUP_INIT,
+                       (PVOID)MixSetup, 0);
+   if (rc != MCIERR_SUCCESS) {
+      dprintf(("DSOUND-DART: MCI_MIXSETUP (SetFormat) %d", rc));
+      return DSERR_GENERIC;
+   }
+
+   memset(BufferParms, 0, sizeof(MCI_BUFFER_PARMS));
+   memset(MixBuffer,   0, sizeof(MCI_MIX_BUFFER) * NUM_DART_BUFFS);
+   BufferParms->ulStructLength = sizeof(MCI_BUFFER_PARMS);
+   BufferParms->ulNumBuffers   = NUM_DART_BUFFS;
+   BufferParms->ulBufferSize   = BUFFER_SIZE/NUM_DART_BUFFS;
+   BufferParms->pBufList       = MixBuffer;
+   MixBuffer->pBuffer          = NULL;
+
+   rc = mciSendCommand(*pusDeviceID, MCI_BUFFER, MCI_WAIT | MCI_ALLOCATE_MEMORY,
+                       (PVOID)BufferParms, 0);
+   if (rc != MCIERR_SUCCESS) {
+      dprintf(("DSOUND-DART: MCI_BUFFER_ALLOCATE_MEMORY (SetFormat) %d", rc));
+      mciSendCommand(*pusDeviceID, MCI_CLOSE, MCI_WAIT, NULL, 0);
+      memset(MixBuffer, 0, sizeof(MCI_MIX_BUFFER) * NUM_DART_BUFFS);
+      return DSERR_OUTOFMEMORY;
+   }
+
+   /* Clear the Buffer */
+   // Todo:  I don't know if Dart expects Signed or Unsigned data... This will
+   // ok until I look in to this... Also it may be that Dart uses signed for
+   // 8bit data and unsigned for 16it.. Anyhow the worst that can happen by setting
+   // the buffer to 0 is a click on Dart_Play and a Clink when real sound is written
+   // to the buffer!
+   for (int i=0; i<NUM_DART_BUFFS; i++) {
+      memset(MixBuffer[i].pBuffer, 0, BUFFER_SIZE/NUM_DART_BUFFS);
+   }
+
+   return DS_OK;
+}
+
+
+long Dart_Stop(USHORT usDeviceID)
+{
+   ULONG   rc;
+
+   dprintf(("DSOUND-DART: Dart_Stop"));
+
+//   rc = mciSendCommand(usDeviceID, MCI_PAUSE, MCI_WAIT, NULL, 0);
+   rc = mciSendCommand(usDeviceID, MCI_STOP, MCI_WAIT, NULL, 0);
+   if (rc != MCIERR_SUCCESS) {
+      dprintf(("DSOUND-DART: MCI_PAUSE %d", rc));
+      return DSERR_GENERIC;
+   }
+   return DS_OK;
+}
+
+long Dart_Play(USHORT usDeviceID, void *vpMixSetup, void *vpMixBuffer, long playing)
+{
+   ULONG   rc;
+   MCI_MIXSETUP_PARMS  *MixSetup;
+   MCI_MIX_BUFFER      *MixBuffer;
+
+   MixSetup  = (MCI_MIXSETUP_PARMS*)vpMixSetup;
+   MixBuffer = (MCI_MIX_BUFFER*)vpMixBuffer;
+
+   dprintf(("DSOUND-DART: Dart_Play"));
+
+   if (playing == TRUE) {
+      rc = mciSendCommand(usDeviceID, MCI_RESUME, MCI_WAIT, NULL, 0);
+      if (rc != MCIERR_SUCCESS) {
+         dprintf(("DSOUND-DART: MCI_RESUME %d", rc));
+         return DSERR_GENERIC;
+      }
+   } else { //if (playing==FALSE)
+      dprintf(("DSOUND-DART: Playback started!!!!"));
+
+      /* Mix the first buffer before playing */
+      MixCallback(BUFFER_SIZE/NUM_DART_BUFFS);
+      memcpy(pMixBuffs[lLastBuff].pBuffer, &pDSoundBuff[lLastBuff*(BUFFER_SIZE/NUM_DART_BUFFS)], BUFFER_SIZE/NUM_DART_BUFFS);
+
+      USHORT  sel = RestoreOS2FS();
+      /* Note: the call to pmixWrite trashes the FS selector, we have to save */
+      /* and then restore FS!!! Otherwise exception handling will be broken.  */
+      MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle, MixBuffers, NUM_DART_BUFFS);
+      SetFS(sel);
+   }
+
+   return DS_OK;
+}
Index: trunk/src/dsound/new/dsmixer.cpp
===================================================================
--- trunk/src/dsound/new/dsmixer.cpp	(revision 3027)
+++ trunk/src/dsound/new/dsmixer.cpp	(revision 3027)
@@ -0,0 +1,193 @@
+/*
+ * DirectSound Software Mixer
+ *
+ * Copyright 2000 Michal Necasek
+ * Copyright 2000 Ondrej Necasek
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+
+/*@Header***********************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define INCL_DOSMISC
+#include <os2win.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#define INITGUID
+#include <dsound.h>
+
+#include "os2dsound.h"
+#include "os2sndbuffer.h"
+#include "os2notify.h"
+#include <misc.h>
+
+signed long mixbuf[2300*2]; /* enough for 50 ms at 44100Hz stereo */
+
+void MixCallback(ULONG cbMix) {
+   // Check for priority level here; for DSSCL_WRITEPRIMARY just play directly
+   // from the primary buffer; for all others mix the secondary buffers
+   if (OS2IDirectSoundBuffer::primary->parentDS->GetCoopLevel() != DSSCL_WRITEPRIMARY)
+      MixFunc(OS2IDirectSoundBuffer::dsbroot, OS2IDirectSoundBuffer::primary, cbMix);
+   else {
+   }
+}
+
+void MixOneBuffer(OS2IDirectSoundBuffer *inBuf, int tomix, int outrate)
+{
+   unsigned char *data8b;
+   signed short *data16b;
+   int inpos, spd, i, j, sample, len, bytespersample, vol1, vol2;
+   int oldpos;
+
+   bytespersample = inBuf->lpfxFormat->wBitsPerSample *
+      inBuf->lpfxFormat->nChannels / 8;
+   inpos = inBuf->playpos / bytespersample * 1024 + inBuf->frac;
+   spd = 1024 * inBuf->frequency / outrate;
+   if (inBuf->pan <= 0)
+      vol1 = inBuf->volume;
+   else
+      vol1 = inBuf->volume * (256 - inBuf->pan) / 256;
+   if (inBuf->pan >= 0)
+      vol2 = inBuf->volume;
+   else
+      vol2 = inBuf->volume * (256 + inBuf->pan) / 256;
+   len = inBuf->bufferdesc.dwBufferBytes / bytespersample * 1024;
+   if ((inBuf->lpfxFormat->nChannels == 2) && (inBuf->lpfxFormat->wBitsPerSample == 16)) {
+      data16b = (signed short *) inBuf->lpBuffer;
+      for (i = 0; i < tomix; i++) {
+         j = inpos / 1024 * 2;
+         mixbuf[i*2] += data16b[j] * vol1 / 256;
+         mixbuf[i*2+1] += data16b[j+1] * vol2 / 256;
+         inpos += spd;
+         if (inpos >= len) {
+            if (inBuf->fLoop) inpos -= len;
+            else {
+               inBuf->fPlaying = FALSE;
+               if (inBuf->notify != NULL)
+                  inBuf->notify->CheckStop();
+               break;
+            }
+         }
+      }
+   }
+   if ((inBuf->lpfxFormat->nChannels == 1) && (inBuf->lpfxFormat->wBitsPerSample == 16)) {
+      data16b = (signed short *) inBuf->lpBuffer;
+      for (i = 0; i < tomix; i++) {
+         j = inpos / 1024;
+         sample = data16b[j];
+         mixbuf[i*2] += sample * vol1 / 256;
+         mixbuf[i*2+1] += sample * vol2 / 256;
+         inpos += spd;
+         if (inpos >= len) {
+            if (inBuf->fLoop) inpos -= len;
+            else {
+               inBuf->fPlaying = FALSE;
+               if (inBuf->notify != NULL)
+                  inBuf->notify->CheckStop();
+               break;
+            }
+         }
+      }
+   }
+   if ((inBuf->lpfxFormat->nChannels == 2) && (inBuf->lpfxFormat->wBitsPerSample == 8)) {
+      data8b = (unsigned char *) inBuf->lpBuffer;
+      for (i = 0; i < tomix; i++) {
+         j = inpos / 1024 * 2;
+         sample = ((int) data8b[j] - 128) * vol1;
+         mixbuf[i*2] += sample;
+         sample = ((int) data8b[j+1] - 128) * vol2;
+         mixbuf[i*2+1] += sample;
+         inpos += spd;
+         if (inpos >= len) {
+            if (inBuf->fLoop) inpos -= len;
+            else {
+               inBuf->fPlaying = FALSE;
+               if (inBuf->notify != NULL)
+                  inBuf->notify->CheckStop();
+               break;
+            }
+         }
+      }
+   }
+   if ((inBuf->lpfxFormat->nChannels == 1) && (inBuf->lpfxFormat->wBitsPerSample == 8)) {
+      data8b = (unsigned char *) inBuf->lpBuffer;
+      for (i = 0; i < tomix; i++) {
+         j = inpos / 1024;
+         sample = (int) data8b[j] - 128;
+         mixbuf[i*2] += sample * vol1;
+         mixbuf[i*2+1] += sample * vol2;
+         inpos += spd;
+         if (inpos >= len) {
+            if (inBuf->fLoop) inpos -= len;
+            else {
+               inBuf->fPlaying = FALSE;
+               if (inBuf->notify != NULL)
+                  inBuf->notify->CheckStop();
+               break;
+            }
+         }
+      }
+   }
+   oldpos         = inBuf->playpos;
+   inBuf->playpos = inpos / 1024 * bytespersample;
+   inBuf->frac    = inpos % 1024;
+
+   // Check if any notifications are to be signaled
+   if (inBuf->notify != NULL)
+      inBuf->notify->CheckPos(oldpos, inBuf->playpos);
+
+   // keep the write cursor about 15ms ahead of the play cursor
+   inBuf->writepos  = inBuf->playpos + inBuf->frequency * bytespersample / 67;
+   inBuf->writepos %= inBuf->bufferdesc.dwBufferBytes;
+}
+
+void MixFunc (OS2IDirectSoundBuffer *firstBuf, OS2IDirectSoundBuffer *outBuf,
+   ULONG cbMix) {
+   OS2IDirectSoundBuffer *inBuf = firstBuf;
+   int i, outbits, outrate, outnch, tomix, outpos, outlen;
+   unsigned char *data8b;
+   signed short *data16b;
+
+   outbits = outBuf->lpfxFormat->wBitsPerSample;
+   outrate = outBuf->lpfxFormat->nSamplesPerSec;
+   outnch = outBuf->lpfxFormat->nChannels;
+   tomix = cbMix * 8 / outbits / outnch;
+
+   memset(&mixbuf, 0, tomix * 2 * sizeof(mixbuf[0]));
+
+   while (inBuf != NULL) {
+      if (inBuf->fPlaying) {
+         MixOneBuffer(inBuf, tomix, outrate);
+      }
+      inBuf = inBuf->next;
+   }
+
+   outpos = outBuf->playpos * 8 / outbits;
+   outlen = outBuf->bufferdesc.dwBufferBytes * 8 / outbits;
+   if (outbits == 16) {
+      data16b = (signed short *) outBuf->lpBuffer;
+      for (i = 0; i < tomix * outnch; i++) {
+         if (mixbuf[i] <= -32768) data16b[outpos] = -32768;
+         else if (mixbuf[i] >= 32767) data16b[outpos] = 32767;
+         else data16b[outpos] = mixbuf[i];
+         outpos++;
+         if (outpos >= outlen) outpos = 0;
+      }
+   } else {
+      data8b = (unsigned char *) outBuf->lpBuffer;
+      for (i = 0; i < tomix * outnch; i++) {
+         if (mixbuf[i] <= -32768) data16b[outpos] = 0;
+         else if (mixbuf[i] >= 32767) data16b[outpos] = 255;
+         else data16b[outpos] = mixbuf[i] / 256 + 128;
+         outpos++;
+         if (outpos >= outlen) outpos = 0;
+      }
+   }
+   outBuf->playpos = outpos * outbits / 8;
+}
+
Index: trunk/src/dsound/new/dsmixer.h
===================================================================
--- trunk/src/dsound/new/dsmixer.h	(revision 3027)
+++ trunk/src/dsound/new/dsmixer.h	(revision 3027)
@@ -0,0 +1,14 @@
+/*
+ * DirectSound software mixer
+ *
+ * Copyright 2000 Michal Necasek
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#ifndef __MIXER_H__
+#define __MIXER_H__
+
+void MixCallback(ULONG cbMix);
+
+#endif
Index: trunk/src/dsound/new/dsound.rc
===================================================================
--- trunk/src/dsound/new/dsound.rc	(revision 3027)
+++ trunk/src/dsound/new/dsound.rc	(revision 3027)
@@ -0,0 +1,41 @@
+/* $Id: dsound.rc,v 1.1 2000-03-06 13:11:40 mike Exp $ */
+
+#include "winuser.h"
+#include "odinrsrc.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version (based on NT 4 SP3)
+//
+
+1 VERSIONINFO
+ FILEVERSION ODIN_FILEVERSION
+ PRODUCTVERSION ODIN_PRODUCTVERSION
+ FILEFLAGSMASK 0x3fL
+ FILEFLAGS 0xaL
+ FILEOS 0x10001L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904E4"
+        BEGIN
+            VALUE "Comments", "Odin32 System Dll\0"
+            VALUE "CompanyName", "Odin Team\0"
+            VALUE "FileDescription", "DSOUND System dll\0"
+            VALUE "FileVersion", "4.04\0"
+            VALUE "InternalName", "DSOUND\0"
+            VALUE "LegalCopyright", "Copyright (C) 1999-2000\0"
+            VALUE "LegalTrademarks", "\0"
+            VALUE "OriginalFilename", "DSOUND.DLL\0"
+            VALUE "ProductName", "Odin32 - DSOUND\0"
+            VALUE "ProductVersion", "4.04\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+	VALUE "Translation", 0x409, 0x04E4
+    END
+END
Index: trunk/src/dsound/new/initterm.cpp
===================================================================
--- trunk/src/dsound/new/initterm.cpp	(revision 3027)
+++ trunk/src/dsound/new/initterm.cpp	(revision 3027)
@@ -0,0 +1,116 @@
+/* $Id: initterm.cpp,v 1.1 2000-03-06 13:11:40 mike Exp $ */
+
+/*
+ * DLL entry point
+ *
+ * Copyright 1998 Sander van Leeuwen
+ * Copyright 1998 Peter Fitzsimmons
+ *
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+/*-------------------------------------------------------------*/
+/* INITERM.C -- Source for a custom dynamic link library       */
+/*              initialization and termination (_DLL_InitTerm) */
+/*              function.                                      */
+/*                                                             */
+/* When called to perform initialization, this sample function */
+/* gets storage for an array of integers, and initializes its  */
+/* elements with random integers.  At termination time, it     */
+/* frees the array.  Substitute your own special processing.   */
+/*-------------------------------------------------------------*/
+
+
+/* Include files */
+#define  INCL_DOSMODULEMGR
+#define  INCL_DOSPROCESS
+#include <os2wrap.h>    //Odin32 OS/2 api wrappers
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <odin.h>
+#include <win32type.h>
+#include <winconst.h>
+#include <odinlx.h>
+#include <misc.h>       /*PLF Wed  98-03-18 23:18:15*/
+
+extern "C" {
+void CDECL _ctordtorInit( void );
+void CDECL _ctordtorTerm( void );
+
+ //Win32 resource table (produced by wrc)
+ extern DWORD _Resource_PEResTab;
+}
+
+char dsoundPath[CCHMAXPATH] = "";
+
+//******************************************************************************
+//******************************************************************************
+BOOL WINAPI LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
+{
+   switch (fdwReason)
+   {
+   case DLL_PROCESS_ATTACH:
+	return TRUE;
+
+   case DLL_THREAD_ATTACH:
+   case DLL_THREAD_DETACH:
+	return TRUE;
+
+   case DLL_PROCESS_DETACH:
+	_ctordtorTerm();
+	return TRUE;
+   }
+   return FALSE;
+}
+/****************************************************************************/
+/* _DLL_InitTerm is the function that gets called by the operating system   */
+/* loader when it loads and frees this DLL for each process that accesses   */
+/* this DLL.  However, it only gets called the first time the DLL is loaded */
+/* and the last time it is freed for a particular process.  The system      */
+/* linkage convention MUST be used because the operating system loader is   */
+/* calling this function.                                                   */
+/****************************************************************************/
+unsigned long SYSTEM _DLL_InitTerm(unsigned long hModule, unsigned long
+                                   ulFlag)
+{
+   size_t i;
+   APIRET rc;
+
+   /*-------------------------------------------------------------------------*/
+   /* If ulFlag is zero then the DLL is being loaded so initialization should */
+   /* be performed.  If ulFlag is 1 then the DLL is being freed so            */
+   /* termination should be performed.                                        */
+   /*-------------------------------------------------------------------------*/
+
+   switch (ulFlag) {
+      case 0 :
+      {
+   	 DosQueryModuleName(hModule, CCHMAXPATH, dsoundPath);
+         char *endofpath = strrchr(dsoundPath, '\\');
+         if(endofpath) *(endofpath+1) = 0;
+         _ctordtorInit();
+
+         CheckVersionFromHMOD(PE2LX_VERSION, hModule); /*PLF Wed  98-03-18 05:28:48*/
+
+	 if(RegisterLxDll(hModule, LibMain, (PVOID)&_Resource_PEResTab) == FALSE) 
+		return 0UL;
+
+         break;
+      }
+      case 1 :
+	 UnregisterLxDll(hModule);
+         break;
+      default  :
+         return 0UL;
+   }
+
+   /***********************************************************/
+   /* A non-zero value must be returned to indicate success.  */
+   /***********************************************************/
+   return 1UL;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/dsound/new/initterm.h
===================================================================
--- trunk/src/dsound/new/initterm.h	(revision 3027)
+++ trunk/src/dsound/new/initterm.h	(revision 3027)
@@ -0,0 +1,20 @@
+/* $Id: initterm.h,v 1.1 2000-03-06 13:11:40 mike Exp $ */
+/*
+ * KERNEL32 DLL entry point header
+ *
+ * Copyright 1998 Sander van Leeuwen
+ * Copyright 1998 Peter Fitzsimmons
+ *
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+#ifndef __INITTERM_H__
+#define __INITTERM_H__
+
+void CloseLogFile(); //misc.cpp
+
+extern char dsoundPath[];
+
+#endif
Index: trunk/src/dsound/new/makefile
===================================================================
--- trunk/src/dsound/new/makefile	(revision 3027)
+++ trunk/src/dsound/new/makefile	(revision 3027)
@@ -0,0 +1,64 @@
+# $Id: makefile,v 1.1 2000-03-06 13:11:41 mike Exp $
+
+#
+# PD-Win32 API
+#
+#       dsound.dll makefile
+#
+
+PDWIN32_INCLUDE = ..\..\..\include
+PDWIN32_LIB = ..\..\..\lib
+PDWIN32_BIN = ..\..\..\bin
+PDWIN32_TOOLS = ..\..\..\tools\bin
+
+
+!include $(PDWIN32_INCLUDE)/pdwin32.mk
+
+
+CFLAGS = $(CFLAGS) -I$(PDWIN32_INCLUDE)
+CXXFLAGS = $(CXXFLAGS) -I$(PDWIN32_INCLUDE)
+
+
+TARGET = dsound
+
+OBJS =  dsound.obj os2dsound.obj initterm.obj os2sndbuffer.obj \
+        os2primbuff.obj dart.obj os2notify.obj dsmixer.obj resource.obj
+
+all: $(TARGET).dll $(TARGET).lib
+
+
+$(TARGET).dll: $(OBJS) $(TARGET).def
+    $(LD) $(LDFLAGS) -Fm -Fe$@ $(OBJS) $(TARGET).def \
+          pmwinx.lib $(PDWIN32_LIB)/kernel32.lib \
+          mmpm2.lib  $(PDWIN32_LIB)/ole32.lib \
+          $(PDWIN32_LIB)/odincrt.lib OS2386.LIB $(RTLLIB_O)
+    $(CP) $@ $(PDWIN32_BIN)
+
+
+lib: $(TARGET).lib $(PDWIN32_LIB)\$(TARGET).lib
+
+$(PDWIN32_LIB)\$(TARGET).lib: $(TARGET).lib
+    $(CP) $** $@
+
+$(TARGET).lib: $(TARGET).def
+    $(IMPLIB) $(IMPLIBFLAGS) $@ $**
+    $(CP) $@ $(PDWIN32_LIB)
+
+resource.asm: $(TARGET).rc
+    $(RC) $(RCFLAGS) -o resource.asm $(TARGET).rc
+
+
+dep:
+    $(DEPEND) -I$(PDWIN32_INCLUDE);$(PDWIN32_INCLUDE)\win \
+        *.c *.cpp *.h *.asm *.inc $(PDWIN32_INCLUDE)\*.h
+
+!ifndef NODEP
+!include .depend
+!endif
+
+
+clean:
+    $(RM) *.obj *.lib *.dll *.map *.pch \
+        $(PDWIN32_BIN)\$(TARGET).dll $(PDWIN32_LIB)\$(TARGET).lib \
+        resource.asm $(TARGET)exp.def
+
Index: trunk/src/dsound/new/resource.asm
===================================================================
--- trunk/src/dsound/new/resource.asm	(revision 3027)
+++ trunk/src/dsound/new/resource.asm	(revision 3027)
@@ -0,0 +1,160 @@
+;/* This file is generated with wrc version 1.0.14 (08-Aug-1999). Do not edit! */
+;/* Source : dsound.rc */
+;/* Cmdline: wrc -s -I. -ID:\IBMCPP\include -I..\..\include -I..\..\include\win -o resource.asm dsound.rc */
+;/* Date   : Thu Feb 24 23:50:09 2000 */
+
+	.386p
+	.model flat
+	.data
+
+	align	4
+_Resource_PEResTab:
+	public	_Resource_PEResTab
+	dd	0
+	dd	038b5b5a1h
+	dd	0
+	dw	0, 1
+	dd	16
+	dd	(L16 - _Resource_PEResTab) or 80000000h
+L16:
+	dd	0
+	dd	038b5b5a1h
+	dd	0
+	dw	0, 1
+	dd	1
+	dd	(L16_1 - _Resource_PEResTab) or 80000000h
+L16_1:
+	dd	0
+	dd	038b5b5a1h
+	dd	0
+	dw	0, 1
+	dd	000000000h
+	dd	L16_1_0 - _Resource_PEResTab
+_Resource_ResourceDirectory:
+	public	_Resource_ResourceDirectory
+L16_1_0:
+	dd	_Resource_VerInf_1_0_data - _Resource_PEResTab
+	dd	804
+	dd	0
+	dd	0
+
+LResTabEnd:
+
+;/* Resource binary data */
+
+	align	4
+_Resource_VerInf_1_0_data:
+	db	024h, 003h, 034h, 000h, 000h, 000h, 056h, 000h
+	db	053h, 000h, 05fh, 000h, 056h, 000h, 045h, 000h
+	db	052h, 000h, 053h, 000h, 049h, 000h, 04fh, 000h
+	db	04eh, 000h, 05fh, 000h, 049h, 000h, 04eh, 000h
+	db	046h, 000h, 04fh, 000h, 000h, 000h, 000h, 000h
+	db	0bdh, 004h, 0efh, 0feh, 000h, 000h, 001h, 000h
+	db	000h, 000h, 001h, 000h, 000h, 000h, 000h, 000h
+	db	000h, 000h, 001h, 000h, 000h, 000h, 000h, 000h
+	db	03fh, 000h, 000h, 000h, 00ah, 000h, 000h, 000h
+	db	001h, 000h, 001h, 000h, 001h, 000h, 000h, 000h
+	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+	db	000h, 000h, 000h, 000h, 084h, 002h, 000h, 000h
+	db	000h, 000h, 053h, 000h, 074h, 000h, 072h, 000h
+	db	069h, 000h, 06eh, 000h, 067h, 000h, 046h, 000h
+	db	069h, 000h, 06ch, 000h, 065h, 000h, 049h, 000h
+	db	06eh, 000h, 066h, 000h, 06fh, 000h, 000h, 000h
+	db	060h, 002h, 000h, 000h, 000h, 000h, 030h, 000h
+	db	034h, 000h, 030h, 000h, 039h, 000h, 030h, 000h
+	db	034h, 000h, 045h, 000h, 034h, 000h, 000h, 000h
+	db	03ch, 000h, 012h, 000h, 001h, 000h, 043h, 000h
+	db	06fh, 000h, 06dh, 000h, 06dh, 000h, 065h, 000h
+	db	06eh, 000h, 074h, 000h, 073h, 000h, 000h, 000h
+	db	04fh, 000h, 064h, 000h, 069h, 000h, 06eh, 000h
+	db	033h, 000h, 032h, 000h, 020h, 000h, 053h, 000h
+	db	079h, 000h, 073h, 000h, 074h, 000h, 065h, 000h
+	db	06dh, 000h, 020h, 000h, 044h, 000h, 06ch, 000h
+	db	06ch, 000h, 000h, 000h, 034h, 000h, 00ah, 000h
+	db	001h, 000h, 043h, 000h, 06fh, 000h, 06dh, 000h
+	db	070h, 000h, 061h, 000h, 06eh, 000h, 079h, 000h
+	db	04eh, 000h, 061h, 000h, 06dh, 000h, 065h, 000h
+	db	000h, 000h, 000h, 000h, 04fh, 000h, 064h, 000h
+	db	069h, 000h, 06eh, 000h, 020h, 000h, 054h, 000h
+	db	065h, 000h, 061h, 000h, 06dh, 000h, 000h, 000h
+	db	04ch, 000h, 012h, 000h, 001h, 000h, 046h, 000h
+	db	069h, 000h, 06ch, 000h, 065h, 000h, 044h, 000h
+	db	065h, 000h, 073h, 000h, 063h, 000h, 072h, 000h
+	db	069h, 000h, 070h, 000h, 074h, 000h, 069h, 000h
+	db	06fh, 000h, 06eh, 000h, 000h, 000h, 000h, 000h
+	db	044h, 000h, 053h, 000h, 04fh, 000h, 055h, 000h
+	db	04eh, 000h, 044h, 000h, 020h, 000h, 053h, 000h
+	db	079h, 000h, 073h, 000h, 074h, 000h, 065h, 000h
+	db	06dh, 000h, 020h, 000h, 064h, 000h, 06ch, 000h
+	db	06ch, 000h, 000h, 000h, 02ah, 000h, 005h, 000h
+	db	001h, 000h, 046h, 000h, 069h, 000h, 06ch, 000h
+	db	065h, 000h, 056h, 000h, 065h, 000h, 072h, 000h
+	db	073h, 000h, 069h, 000h, 06fh, 000h, 06eh, 000h
+	db	000h, 000h, 000h, 000h, 034h, 000h, 02eh, 000h
+	db	030h, 000h, 034h, 000h, 000h, 000h, 000h, 000h
+	db	02eh, 000h, 007h, 000h, 001h, 000h, 049h, 000h
+	db	06eh, 000h, 074h, 000h, 065h, 000h, 072h, 000h
+	db	06eh, 000h, 061h, 000h, 06ch, 000h, 04eh, 000h
+	db	061h, 000h, 06dh, 000h, 065h, 000h, 000h, 000h
+	db	044h, 000h, 053h, 000h, 04fh, 000h, 055h, 000h
+	db	04eh, 000h, 044h, 000h, 000h, 000h, 000h, 000h
+	db	054h, 000h, 018h, 000h, 001h, 000h, 04ch, 000h
+	db	065h, 000h, 067h, 000h, 061h, 000h, 06ch, 000h
+	db	043h, 000h, 06fh, 000h, 070h, 000h, 079h, 000h
+	db	072h, 000h, 069h, 000h, 067h, 000h, 068h, 000h
+	db	074h, 000h, 000h, 000h, 043h, 000h, 06fh, 000h
+	db	070h, 000h, 079h, 000h, 072h, 000h, 069h, 000h
+	db	067h, 000h, 068h, 000h, 074h, 000h, 020h, 000h
+	db	028h, 000h, 043h, 000h, 029h, 000h, 020h, 000h
+	db	031h, 000h, 039h, 000h, 039h, 000h, 039h, 000h
+	db	02dh, 000h, 032h, 000h, 030h, 000h, 030h, 000h
+	db	030h, 000h, 000h, 000h, 02ah, 000h, 001h, 000h
+	db	001h, 000h, 04ch, 000h, 065h, 000h, 067h, 000h
+	db	061h, 000h, 06ch, 000h, 054h, 000h, 072h, 000h
+	db	061h, 000h, 064h, 000h, 065h, 000h, 06dh, 000h
+	db	061h, 000h, 072h, 000h, 06bh, 000h, 073h, 000h
+	db	000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
+	db	03eh, 000h, 00bh, 000h, 001h, 000h, 04fh, 000h
+	db	072h, 000h, 069h, 000h, 067h, 000h, 069h, 000h
+	db	06eh, 000h, 061h, 000h, 06ch, 000h, 046h, 000h
+	db	069h, 000h, 06ch, 000h, 065h, 000h, 06eh, 000h
+	db	061h, 000h, 06dh, 000h, 065h, 000h, 000h, 000h
+	db	044h, 000h, 053h, 000h, 04fh, 000h, 055h, 000h
+	db	04eh, 000h, 044h, 000h, 02eh, 000h, 044h, 000h
+	db	04ch, 000h, 04ch, 000h, 000h, 000h, 000h, 000h
+	db	040h, 000h, 010h, 000h, 001h, 000h, 050h, 000h
+	db	072h, 000h, 06fh, 000h, 064h, 000h, 075h, 000h
+	db	063h, 000h, 074h, 000h, 04eh, 000h, 061h, 000h
+	db	06dh, 000h, 065h, 000h, 000h, 000h, 000h, 000h
+	db	04fh, 000h, 064h, 000h, 069h, 000h, 06eh, 000h
+	db	033h, 000h, 032h, 000h, 020h, 000h, 02dh, 000h
+	db	020h, 000h, 044h, 000h, 053h, 000h, 04fh, 000h
+	db	055h, 000h, 04eh, 000h, 044h, 000h, 000h, 000h
+	db	02eh, 000h, 005h, 000h, 001h, 000h, 050h, 000h
+	db	072h, 000h, 06fh, 000h, 064h, 000h, 075h, 000h
+	db	063h, 000h, 074h, 000h, 056h, 000h, 065h, 000h
+	db	072h, 000h, 073h, 000h, 069h, 000h, 06fh, 000h
+	db	06eh, 000h, 000h, 000h, 034h, 000h, 02eh, 000h
+	db	030h, 000h, 034h, 000h, 000h, 000h, 000h, 000h
+	db	044h, 000h, 000h, 000h, 000h, 000h, 056h, 000h
+	db	061h, 000h, 072h, 000h, 046h, 000h, 069h, 000h
+	db	06ch, 000h, 065h, 000h, 049h, 000h, 06eh, 000h
+	db	066h, 000h, 06fh, 000h, 000h, 000h, 000h, 000h
+	db	024h, 000h, 004h, 000h, 000h, 000h, 054h, 000h
+	db	072h, 000h, 061h, 000h, 06eh, 000h, 073h, 000h
+	db	06ch, 000h, 061h, 000h, 074h, 000h, 069h, 000h
+	db	06fh, 000h, 06eh, 000h, 000h, 000h, 000h, 000h
+	db	009h, 004h, 0e4h, 004h
+
+	align	4
+_Resource_ResourceDescriptor:
+	public	_Resource_ResourceDescriptor
+_Resource_ResourceTable:
+	dd	_Resource_PEResTab
+_Resource_NumberOfResources:
+	dd	1
+_Resource_ResourceSectionSize:
+	dd	LResTabEnd - _Resource_PEResTab
+_Resource_ResourcesEntries:
+	dd	_Resource_ResourceDirectory
+	end
