Commit ae7267e2 authored by Peter Achten's avatar Peter Achten
Browse files

Initial import

parent a2835260
ole32.dll
CoInitialize@4
CoUninitialize@0
CoTaskMemFree@4
This diff is collapsed.
/*==========================================================================
*
* Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
*
* File: ddutil.cpp
* Content: Routines for loading bitmap and palettes from resources
*
***************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
extern IDirectDrawPalette * DDLoadPalette(IDirectDraw *pdd, LPCSTR szBitmap);
extern IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap, int dx, int dy);
extern HRESULT DDReLoadBitmap(IDirectDrawSurface *pdds, LPCSTR szBitmap);
extern HRESULT DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int x, int y, int dx, int dy);
extern DWORD DDColorMatch(IDirectDrawSurface *pdds, COLORREF rgb);
extern HRESULT DDSetColorKey(IDirectDrawSurface *pdds, COLORREF rgb);
#ifdef __cplusplus
}
#endif /* __cplusplus */
/*==========================================================================
*
* Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
*
* File: dsutil.cpp
* Content: Routines for dealing with sounds from resources
*
*
***************************************************************************/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <dsound.h>
typedef struct
{
BYTE *pbWaveData; // pointer into wave resource (for restore)
DWORD cbWaveSize; // size of wave data (for restore)
int iAlloc; // number of buffers.
int iCurrent; // current buffer
IDirectSoundBuffer* Buffers[1]; // list of buffers
} SNDOBJ, *HSNDOBJ;
#define _HSNDOBJ_DEFINED
#include "dsutil.h"
static const char c_szWAV[] = "WAV";
static HGLOBAL ptr = NULL;
///////////////////////////////////////////////////////////////////////////////
//
// DSLoadSoundBuffer
//
///////////////////////////////////////////////////////////////////////////////
IDirectSoundBuffer *DSLoadSoundBuffer(IDirectSound *pDS, LPCTSTR lpName)
{
IDirectSoundBuffer *pDSB = NULL;
DSBUFFERDESC dsBD = {0};
BYTE *pbWaveData;
if (DSGetWaveResource(NULL, lpName, &dsBD.lpwfxFormat, &pbWaveData, &dsBD.dwBufferBytes))
{
dsBD.dwSize = sizeof(dsBD);
dsBD.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLDEFAULT | DSBCAPS_GETCURRENTPOSITION2;
if (SUCCEEDED(IDirectSound_CreateSoundBuffer(pDS, &dsBD, &pDSB, NULL)))
{
if (!DSFillSoundBuffer(pDSB, pbWaveData, dsBD.dwBufferBytes))
{
IDirectSoundBuffer_Release(pDSB);
pDSB = NULL;
}
}
else
{
pDSB = NULL;
}
}
if (ptr)
{
GlobalFree (ptr);
ptr = NULL;
}
return pDSB;
}
///////////////////////////////////////////////////////////////////////////////
//
// DSReloadSoundBuffer
//
///////////////////////////////////////////////////////////////////////////////
BOOL DSReloadSoundBuffer(IDirectSoundBuffer *pDSB, LPCTSTR lpName)
{
BOOL result=FALSE;
BYTE *pbWaveData;
DWORD cbWaveSize;
if (DSGetWaveResource(NULL, lpName, NULL, &pbWaveData, &cbWaveSize))
{
if (SUCCEEDED(IDirectSoundBuffer_Restore(pDSB)) &&
DSFillSoundBuffer(pDSB, pbWaveData, cbWaveSize))
{
result = TRUE;
}
}
if (ptr)
{
GlobalFree (ptr);
ptr = NULL;
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
//
// DSGetWaveResource
//
///////////////////////////////////////////////////////////////////////////////
BOOL DSGetWaveResource(HMODULE hModule, LPCTSTR lpName,
WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData, DWORD *pcbWaveSize)
{
HRSRC hResInfo;
HGLOBAL hResData;
void *pvRes;
HANDLE fh;
DWORD dwsize;
DWORD dwread;
if (((hResInfo = FindResource(hModule, lpName, c_szWAV)) != NULL) &&
((hResData = LoadResource(hModule, hResInfo)) != NULL) &&
((pvRes = LockResource(hResData)) != NULL) &&
DSParseWaveResource(pvRes, ppWaveHeader, ppbWaveData, pcbWaveSize))
{
return TRUE;
}
fh = CreateFile (lpName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh != INVALID_HANDLE_VALUE)
{
dwsize = GetFileSize (fh, NULL);
if (dwsize != 0xFFFFFFFF)
{
if (ptr)
{
GlobalFree (ptr);
ptr = NULL;
}
ptr = GlobalAlloc (GPTR, dwsize);
if (ptr)
{
if (ReadFile (fh, ptr, dwsize, &dwread, NULL))
{
if (DSParseWaveResource (ptr, ppWaveHeader, ppbWaveData,
pcbWaveSize))
{
return TRUE;
}
}
}
}
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// SndObj fns
///////////////////////////////////////////////////////////////////////////////
SNDOBJ *SndObjCreate(IDirectSound *pDS, LPCTSTR lpName, int iConcurrent)
{
SNDOBJ *pSO = NULL;
LPWAVEFORMATEX pWaveHeader;
BYTE *pbData;
UINT cbData;
if (DSGetWaveResource(NULL, lpName, &pWaveHeader, &pbData, &cbData))
{
if (iConcurrent < 1)
iConcurrent = 1;
if ((pSO = (SNDOBJ *)LocalAlloc(LPTR, sizeof(SNDOBJ) +
(iConcurrent-1) * sizeof(IDirectSoundBuffer *))) != NULL)
{
int i;
pSO->iAlloc = iConcurrent;
pSO->pbWaveData = pbData;
pSO->cbWaveSize = cbData;
pSO->Buffers[0] = DSLoadSoundBuffer(pDS, lpName);
for (i=1; i<pSO->iAlloc; i++)
{
if (FAILED(IDirectSound_DuplicateSoundBuffer(pDS,
pSO->Buffers[0], &pSO->Buffers[i])))
{
pSO->Buffers[i] = DSLoadSoundBuffer(pDS, lpName);
if (!pSO->Buffers[i])
{
SndObjDestroy(pSO);
pSO = NULL;
break;
}
}
}
}
}
if (ptr)
{
GlobalFree (ptr);
ptr = NULL;
}
return pSO;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void SndObjDestroy(SNDOBJ *pSO)
{
if (pSO)
{
int i;
for (i=0; i<pSO->iAlloc; i++)
{
if (pSO->Buffers[i])
{
IDirectSoundBuffer_Release(pSO->Buffers[i]);
pSO->Buffers[i] = NULL;
}
}
LocalFree((HANDLE)pSO);
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
IDirectSoundBuffer *SndObjGetFreeBuffer(SNDOBJ *pSO)
{
IDirectSoundBuffer *pDSB;
if (pSO == NULL)
return NULL;
if (pDSB = pSO->Buffers[pSO->iCurrent])
{
HRESULT hres;
DWORD dwStatus;
hres = IDirectSoundBuffer_GetStatus(pDSB, &dwStatus);
if (FAILED(hres))
dwStatus = 0;
if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
{
if (pSO->iAlloc > 1)
{
if (++pSO->iCurrent >= pSO->iAlloc)
pSO->iCurrent = 0;
pDSB = pSO->Buffers[pSO->iCurrent];
hres = IDirectSoundBuffer_GetStatus(pDSB, &dwStatus);
if (SUCCEEDED(hres) && (dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
{
IDirectSoundBuffer_Stop(pDSB);
IDirectSoundBuffer_SetCurrentPosition(pDSB, 0);
}
}
else
{
pDSB = NULL;
}
}
if (pDSB && (dwStatus & DSBSTATUS_BUFFERLOST))
{
if (FAILED(IDirectSoundBuffer_Restore(pDSB)) ||
!DSFillSoundBuffer(pDSB, pSO->pbWaveData, pSO->cbWaveSize))
{
pDSB = NULL;
}
}
}
return pDSB;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
BOOL SndObjPlay(SNDOBJ *pSO, DWORD dwPlayFlags)
{
BOOL result = FALSE;
if (pSO == NULL)
return FALSE;
if ((!(dwPlayFlags & DSBPLAY_LOOPING) || (pSO->iAlloc == 1)))
{
IDirectSoundBuffer *pDSB = SndObjGetFreeBuffer(pSO);
if (pDSB != NULL) {
result = SUCCEEDED(IDirectSoundBuffer_Play(pDSB, 0, 0, dwPlayFlags));
}
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
BOOL SndObjStop(SNDOBJ *pSO)
{
int i;
if (pSO == NULL)
return FALSE;
for (i=0; i<pSO->iAlloc; i++)
{
IDirectSoundBuffer_Stop(pSO->Buffers[i]);
IDirectSoundBuffer_SetCurrentPosition(pSO->Buffers[i], 0);
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
BOOL DSFillSoundBuffer(IDirectSoundBuffer *pDSB, BYTE *pbWaveData, DWORD cbWaveSize)
{
if (pDSB && pbWaveData && cbWaveSize)
{
LPVOID pMem1, pMem2;
DWORD dwSize1, dwSize2;
if (SUCCEEDED(IDirectSoundBuffer_Lock(pDSB, 0, cbWaveSize,
&pMem1, &dwSize1, &pMem2, &dwSize2, 0)))
{
CopyMemory(pMem1, pbWaveData, dwSize1);
if ( 0 != dwSize2 )
CopyMemory(pMem2, pbWaveData+dwSize1, dwSize2);
IDirectSoundBuffer_Unlock(pDSB, pMem1, dwSize1, pMem2, dwSize2);
return TRUE;
}
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
BOOL DSParseWaveResource(void *pvRes, WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData,DWORD *pcbWaveSize)
{
DWORD *pdw;
DWORD *pdwEnd;
DWORD dwRiff;
DWORD dwType;
DWORD dwLength;
if (ppWaveHeader)
*ppWaveHeader = NULL;
if (ppbWaveData)
*ppbWaveData = NULL;
if (pcbWaveSize)
*pcbWaveSize = 0;
pdw = (DWORD *)pvRes;
dwRiff = *pdw++;
dwLength = *pdw++;
dwType = *pdw++;
if (dwRiff != mmioFOURCC('R', 'I', 'F', 'F'))
goto exit; // not even RIFF
if (dwType != mmioFOURCC('W', 'A', 'V', 'E'))
goto exit; // not a WAV
pdwEnd = (DWORD *)((BYTE *)pdw + dwLength-4);
while (pdw < pdwEnd)
{
dwType = *pdw++;
dwLength = *pdw++;
switch (dwType)
{
case mmioFOURCC('f', 'm', 't', ' '):
if (ppWaveHeader && !*ppWaveHeader)
{
if (dwLength < sizeof(WAVEFORMAT))
goto exit; // not a WAV
*ppWaveHeader = (WAVEFORMATEX *)pdw;
if ((!ppbWaveData || *ppbWaveData) &&
(!pcbWaveSize || *pcbWaveSize))
{
return TRUE;
}
}
break;
case mmioFOURCC('d', 'a', 't', 'a'):
if ((ppbWaveData && !*ppbWaveData) ||
(pcbWaveSize && !*pcbWaveSize))
{
if (ppbWaveData)
*ppbWaveData = (LPBYTE)pdw;
if (pcbWaveSize)
*pcbWaveSize = dwLength;
if (!ppWaveHeader || *ppWaveHeader)
return TRUE;
}
break;
}
pdw = (DWORD *)((BYTE *)pdw + ((dwLength+1)&~1));
}
exit:
return FALSE;
}
/*==========================================================================
*
* Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
*
* File: dsutil.cpp
* Content: Routines for dealing with sounds from resources
*
*
***************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////
//
// DSLoadSoundBuffer Loads an IDirectSoundBuffer from a Win32 resource in
// the current application.
//
// Params:
// pDS -- Pointer to an IDirectSound that will be used to create
// the buffer.
//
// lpName -- Name of WAV resource to load the data from. Can be a
// resource id specified using the MAKEINTRESOURCE macro.
//
// Returns an IDirectSoundBuffer containing the wave data or NULL on error.
//
// example:
// in the application's resource script (.RC file)
// Turtle WAV turtle.wav
//
// some code in the application:
// IDirectSoundBuffer *pDSB = DSLoadSoundBuffer(pDS, "Turtle");
//
// if (pDSB)
// {
// IDirectSoundBuffer_Play(pDSB, 0, 0, DSBPLAY_TOEND);
// /* ... */
//
///////////////////////////////////////////////////////////////////////////////
IDirectSoundBuffer *DSLoadSoundBuffer(IDirectSound *pDS, LPCTSTR lpName);
///////////////////////////////////////////////////////////////////////////////
//
// DSReloadSoundBuffer Reloads an IDirectSoundBuffer from a Win32 resource in
// the current application. normally used to handle
// a DSERR_BUFFERLOST error.
// Params:
// pDSB -- Pointer to an IDirectSoundBuffer to be reloaded.
//
// lpName -- Name of WAV resource to load the data from. Can be a
// resource id specified using the MAKEINTRESOURCE macro.
//
// Returns a BOOL indicating whether the buffer was successfully reloaded.
//
// example:
// in the application's resource script (.RC file)
// Turtle WAV turtle.wav
//
// some code in the application:
// TryAgain:
// HRESULT hres = IDirectSoundBuffer_Play(pDSB, 0, 0, DSBPLAY_TOEND);
//
// if (FAILED(hres))
// {
// if ((hres == DSERR_BUFFERLOST) &&
// DSReloadSoundBuffer(pDSB, "Turtle"))
// {
// goto TryAgain;
// }
// /* deal with other errors... */
// }
//
///////////////////////////////////////////////////////////////////////////////
BOOL DSReloadSoundBuffer(IDirectSoundBuffer *pDSB, LPCTSTR lpName);
///////////////////////////////////////////////////////////////////////////////
//
// DSGetWaveResource Finds a WAV resource in a Win32 module.
//
// Params:
// hModule -- Win32 module handle of module containing WAV resource.
// Pass NULL to indicate current application.
//
// lpName -- Name of WAV resource to load the data from. Can be a
// resource id specified using the MAKEINTRESOURCE macro.
//
// ppWaveHeader-- Optional pointer to WAVEFORMATEX * to receive a pointer to
// the WAVEFORMATEX header in the specified WAV resource.
// Pass NULL if not required.
//
// ppbWaveData -- Optional pointer to BYTE * to receive a pointer to the
// waveform data in the specified WAV resource. Pass NULL if
// not required.
//
// pdwWaveSize -- Optional pointer to DWORD to receive the size of the
// waveform data in the specified WAV resource. Pass NULL if
// not required.
//
// Returns a BOOL indicating whether a valid WAV resource was found.
//
///////////////////////////////////////////////////////////////////////////////
BOOL DSGetWaveResource(HMODULE hModule, LPCTSTR lpName,
WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData, DWORD *pdwWaveSize);
///////////////////////////////////////////////////////////////////////////////
//
// HSNDOBJ Handle to a SNDOBJ object.
//
// SNDOBJs are implemented in dsutil as an example layer built on top
// of DirectSound.
//
// A SNDOBJ is generally used to manage individual
// sounds which need to be played multiple times concurrently. A
// SNDOBJ represents a queue of IDirectSoundBuffer objects which
// all refer to the same buffer memory.