diff --git a/Include/dxwnd.h b/Include/dxwnd.h
index 0b1519f..ecca996 100644
--- a/Include/dxwnd.h
+++ b/Include/dxwnd.h
@@ -20,7 +20,7 @@
#define HANDLEEXCEPTIONS 0x00000040 // Handles exceptions: Div by 0 ....
#define SAVELOAD 0x00000080
#define EMULATEBUFFER 0x00000100
-// #define AUTOMATIC 0x00000200
+#define HOOKDI8 0x00000200
#define BLITFROMBACKBUFFER 0x00000400
#define SUPPRESSCLIPPING 0x00000800
#define AUTOREFRESH 0x00001000
@@ -92,7 +92,7 @@
#define EMULATEREGISTRY 0x00000400 // Emulate registry api to read extra keys
#define CDROMDRIVETYPE 0x00000800 // Pretends that GetDriveType() always returns DRIVE_CDROM
#define NOWINDOWMOVE 0x00001000 // Do not try to update window position & size on D3D rendering
-//#define DISABLEHAL 0x00002000 // Disable HAL support (IID_IDirect3DHALDevice) - no longer used
+#define FORCECLIPPER 0x00002000 // Set ddraw clipping for real primary surface and primary window - but FastBlt cannot be used!
#define LOCKSYSCOLORS 0x00004000 // Lock Sys Colors changes by SetSysColors() call
#define GDIEMULATEDC 0x00008000 // Map GDI/user32 calls to primary to a memory surface to be stretch-blitted to the primary
#define FULLSCREENONLY 0x00010000 // assume that the program is always in fullscreen mode
@@ -210,8 +210,8 @@
#define SYNCPALETTE 0x04000000 // Syncronize GDI to DDRAW palette
#define VIRTUALJOYSTICK 0x08000000 // Enables the DxWnd virtual joystick
#define UNACQUIRE 0x10000000 // Unacquire DirectInput devices when losing focus and acquire back when gaining focus
-#define HOOKGOGLIBS 0x20000000
-#define BYPASSGOGLIBS 0x40000000
+#define HOOKGOGLIBS 0x20000000 // Hook additional libraries provided by GOG with different names but same functionalities as system ones
+#define BYPASSGOGLIBS 0x40000000 // Bypass GOG proxy system libraries loading directly the system libraries from the system folder
// logging Tflags DWORD:
#define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general
diff --git a/Include/qmixer.h b/Include/qmixer.h
new file mode 100644
index 0000000..7158651
--- /dev/null
+++ b/Include/qmixer.h
@@ -0,0 +1,1429 @@
+//
+// QMixer for Windows and Macintosh.
+// Copyright (c) 1995-1998 QSound Labs, Inc. All Rights Reserved.
+// Version 4.13, July 26, 1998.
+//
+// Based on Microsoft's WaveMix API.
+// Copyright (c) 1993, 1994 Microsoft Corporation. All Rights Reserved.
+//
+
+
+#ifndef QMIXER_H
+#define QMIXER_H
+
+#if !defined(_QMIXIMP)
+ #define _QMIXIMP __declspec(dllimport)
+#endif
+
+DECLARE_HANDLE(HQMIXER);
+
+//
+// Constants for qprocessing
+//
+#define Q_PAN_MIN 0
+#define Q_PAN_MAX 60
+#define Q_PAN_DEFAULT 15
+#define Q_VOLUME_DEFAULT 10000
+
+//
+// Flags for channel functions.
+//
+#define QMIX_ALL 0x0001 // apply to all channels
+#define QMIX_NOREMIX 0x0002 // don't remix
+#define QMIX_CONTROL_NOREMIX 0x0004 // don't remix
+
+
+typedef
+struct QSVECTOR {
+ float x; // meters
+ float y; // meters
+ float z; // meters
+} QSVECTOR, *LPQSVECTOR;
+
+
+typedef
+struct QSPOLAR {
+ float azimuth; // degrees
+ float range; // meters
+ float elevation; // degrees
+} QSPOLAR, *LPQSPOLAR;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef
+struct QMIXINFO {
+ DWORD dwSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+}
+QMIXINFO, FAR* LPQMIXINFO;
+
+_QMIXIMP
+DWORD
+WINAPI
+QSWaveMixGetInfoEx(
+ LPQMIXINFO lpInfo
+ );
+
+
+//
+// Error handling functions.
+//
+
+typedef UINT QMIX_RESULT;
+
+_QMIXIMP
+QMIX_RESULT
+WINAPI
+QSWaveMixGetLastError(
+ void
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetErrorText(
+ QMIX_RESULT qmrError,
+ LPSTR pszText,
+ UINT cchText
+ );
+
+
+//
+// Initialization functions.
+//
+
+_QMIXIMP
+HQMIXER
+WINAPI
+QSWaveMixInit(
+ void
+ );
+
+#define QMIX_CONFIG_USEPRIMARY 0x0001
+#define QMIX_CONFIG_NOTHREAD 0x0002
+#define QMIX_CONFIG_PLAYSILENCE 0x0004
+#define QMIX_CONFIG_LEFTCOORDS 0x0008
+#define QMIX_CONFIG_RIGHTCOORDS 0x0000
+#define QMIX_CONFIG_GLOBALROLLOFF 0x0010
+
+#define QMIX_CONFIG_OUTPUT_DETECT 0
+#define QMIX_CONFIG_OUTPUT_WAVEOUT 1
+#define QMIX_CONFIG_OUTPUT_DIRECTSOUND 2
+
+#define QMIX_CONFIG_MATH_DETECT 0
+#define QMIX_CONFIG_MATH_INTEGER 1
+#define QMIX_CONFIG_MATH_FLOAT 2
+#define QMIX_CONFIG_MATH_MMX 3
+
+typedef
+struct QMIXCONFIG {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwSamplingRate; // 11025, 22050, or 44100 Hz; if 0 uses 22050
+ LPVOID lpIDirectSound;
+ const GUID FAR* lpGuid;
+ int iChannels; // if 0, uses default of 8
+ int iOutput; // if 0, uses best output device
+ int iLatency; // (in ms) if 0, uses default for output device
+ int iMath; // style of math
+ HWND hwnd; // handle used when initializing DirectSound
+ // (if 0, QMixer will find main window)
+ int iChannels3dHw; // number of 3d hardware channels
+ int iChannels3dQS; // number of 3d QSound software channels
+ int iChannels3dSw; // number of 3d software channels
+ int iChannels2dHw; // number of 2d hardware channels
+ int iChannels2dQS; // number of 2d QSound software channels
+ int iChannels2dSw; // number of 2d software channels
+}
+QMIXCONFIG, FAR* LPQMIXCONFIG;
+
+
+_QMIXIMP
+HQMIXER
+WINAPI
+QSWaveMixInitEx(
+ LPQMIXCONFIG lpConfig
+ );
+
+
+//
+// Choose between speakers or headphones.
+//
+#define QMIX_SPEAKERS_STEREO 0
+#define QMIX_SPEAKERS_HEADPHONES 1
+#define QMIX_SPEAKERS_MONO 2
+#define QMIX_SPEAKERS_QUAD 3
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetSpeakerPlacement(
+ HQMIXER hQMixer,
+ int placement
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetSpeakerPlacement(
+ HQMIXER hQMixer,
+ LPDWORD lpdwPlacement
+ );
+
+
+//
+// The following function turns on and off various options
+// in the mixer. Turning off features can save CPU cycles.
+//
+#define QMIX_OPTIONS_REAR 1 // improved rear effect
+#define QMIX_OPTIONS_CROSSOVER 2 // improved frequency response
+#define QMIX_OPTIONS_FLIPOUTPUT 4 // flip output channels
+#define QMIX_OPTIONS_DOPPLER 8 // calculate listener velocity using position updates
+#define QMIX_OPTIONS_ALL 0xffffffff
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetOptions(
+ HQMIXER hQMixer,
+ DWORD dwFlags,
+ DWORD dwMask
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetOptions(
+ HQMIXER hQMixer,
+ LPDWORD lpdwFlags
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetMixerOption(
+ HQMIXER hQMixer,
+ DWORD dwFlags,
+ LPVOID lpvOptions
+ );
+
+
+//
+// QSWaveMixOpenChannel flags
+//
+#define QMIX_OPENSINGLE 0 // open the single channel specified by iChannel
+#define QMIX_OPENALL 1 // opens all the channels, iChannel ignored
+#define QMIX_OPENCOUNT 2 // open iChannel Channels (eg. if iChannel = 4 will create channels 0-3)
+#define QMIX_OPENAVAILABLE 3 // open the first unopened channel, and return channel number
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixOpenChannel(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags
+ );
+
+
+//
+// Comprehensive channel parameters. Used in the functions
+// - QSWaveMixGetChannelParams
+// - QSWaveMixSetChannelParams
+// - QSWaveMixCalculateChannelParams
+// - QSWaveMixFindChannel
+// - QSWaveMixPlayEx
+//
+// The first set of parameters shouldn't be modified, the second set
+// can be altered for QSWaveMixSetChannelParams, and the third set
+// are calculated by QMixer.
+//
+typedef
+struct QMIX_CHANNEL_PARAMS {
+ DWORD dwSize; // size of this structure
+ DWORD dwChannelType; // combination of QMIX_CHANNELTYPE_ flags
+ LPWAVEFORMATEX lpwfxFormat; // channel format (overrides default mixer output)
+ DWORD dwMixerFlags; // reserved
+
+ QSVECTOR vPosition; // 3d position (Cartesian coordinates)
+ QSVECTOR vVelocity; // 3d velocity (Cartesian coordinates)
+ QSVECTOR vOrientation; // 3d orientation (Cartesian coordinates)
+ float flInnerConeAngle; // inner cone angle (degrees)
+ float flOuterConeAngle; // outer cone angle (degrees)
+ float flOuterConeAtten; // attenuation outside cone (db)
+ float flMinDistance; // minimum distance (m)
+ float flMaxDistance; // maximum distance (m)
+ float flRolloff; // rolloff factor (0..10, default=1.0)
+ float flVolume; // scale
+ LONG lFrequency; // playback frequency
+ LONG lPanRate; // time in which a change is completed (ms)
+ LONG lPriority; // user-defined priority
+ DWORD dwModes; // combination of QSWaveMixEnableChannel flags
+ long unused[16]; // reserved for future expansion (set to zero)
+
+ LONG lTimePlaying; // current time playing current sound (ms)
+ LONG lTimeRemaining; // current time left to play (ms)
+ float flDistance; // current distance to listener (m)
+ float flAzimuth; // current azimuth (degrees)
+ float flElevation; // current elevation (degrees)
+ float flConeScale; // amount that volume is scaled for cone effect
+ float flRolloffScale; // amount that volume is scaled for rolloff effect
+ float flAppliedVolume; // volume applied to sound, including rolloff & cone effects (scale)
+ float flDopplerSpeedup; // speedup due to Doppler shift
+ QSVECTOR vHeadPosition; // position relative to listener (left-handed coordinates)
+ QSVECTOR vHeadVelocity; // velocity relative to listener (left-handed coordinates)
+} QMIX_CHANNEL_PARAMS;
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetChannelParams(
+ HQMIXER hQMixer,
+ int iChannel,
+ QMIX_CHANNEL_PARAMS* params
+ );
+
+
+_QMIXIMP MMRESULT WINAPI
+QSWaveMixSetChannelParams(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ const QMIX_CHANNEL_PARAMS* params
+ );
+
+
+_QMIXIMP MMRESULT WINAPI
+QSWaveMixCalculateChannelParams(
+ HQMIXER hQMixer,
+ QMIX_CHANNEL_PARAMS* params,
+ DWORD dwFlags
+ );
+
+
+//
+// Channel types. These flags are used in:
+// QSWaveMixConfigureChannel,
+// QSWaveMixFindChannel.
+// They also appear in the dwChannelType field in QMIX_CHANNEL_PARAMS.
+//
+#define QMIX_CHANNELTYPE_QSOUND 0x00010000 // uses QSound software mixer
+#define QMIX_CHANNELTYPE_STREAMING 0x00020000 // uses hardware streaming DirectSoundBuffer
+#define QMIX_CHANNELTYPE_STATIC 0x00040000 // uses hardware static DirectSoundBuffer
+#define QMIX_CHANNELTYPE_SOFTWARE 0x00080000 // uses software DirectSoundBuffer
+#define QMIX_CHANNELTYPE_DSOUND \
+ (QMIX_CHANNELTYPE_STREAMING|QMIX_CHANNELTYPE_STATIC|QMIX_CHANNELTYPE_SOFTWARE)
+#define QMIX_CHANNELTYPE_ANYMIXER 0x00ff0000
+
+#define QMIX_CHANNELTYPE_2D 0x01000000 // stereo only
+#define QMIX_CHANNELTYPE_3D 0x02000000 // supports full 3d features
+#define QMIX_CHANNELTYPE_ANYFEATURE 0x7f000000
+
+#define QMIX_CHANNELTYPE_ALL (QMIX_CHANNELTYPE_ANYMIXER|QMIX_CHANNELTYPE_ANYFEATURE)
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixConfigureChannel(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags, // type of channel
+ LPCWAVEFORMATEX format, // format of channel (optional)
+ LPVOID lpvOptions // options (reserved, set to zero)
+ );
+
+
+//
+// Find a channel using one of the QMIX_FINDCHANNEL_ priority schemes.
+//
+// The type of channel can be restricted to one of the types given by
+// a combination of the QMIX_CHANNELTYPE_ flags.
+//
+// Normally the channel will be excluded from subsequent calls to
+// QSWaveMixFindChannel until a sound is played on the channel. This is
+// to allow the setting up of several sounds to be played at the same
+// instant. This reservation can be disabled by setting the
+// QMIX_FINDCHANNEL_NORESERVE flag.
+//
+
+#define QMIX_FINDCHANNEL_SORTMETHOD 0x0000000f // mask for sort method
+#define QMIX_FINDCHANNEL_BEGINTIME 0x00000000 // sort by time from beginning (least-recently used)
+#define QMIX_FINDCHANNEL_ENDTIME 0x00000001 // sort by time to end (most-recently available)
+#define QMIX_FINDCHANNEL_VOLUME 0x00000002 // sort by applied volume
+#define QMIX_FINDCHANNEL_DISTANCE 0x00000003 // sort by distance from listener
+#define QMIX_FINDCHANNEL_PRIORITY 0x00000004 // sort by user priority
+
+#define QMIX_FINDCHANNEL_TOPLAY 0x00000000 // pick a playing or ready (idle) channel for playing another
+#define QMIX_FINDCHANNEL_TOPAUSE 0x00000010 // pick a playing channel for pausing
+#define QMIX_FINDCHANNEL_TORESTART 0x00000020 // pick a paused channel for restarting
+#define QMIX_FINDCHANNEL_FORMAT 0x00000080 // channel must match lpParams->lpwfxFormat
+#define QMIX_FINDCHANNEL_NORESERVE 0x80000000 // don't exclude from subsequent searches
+
+#define QMIX_FINDCHANNEL_LRU QMIX_FINDCHANNEL_BEGINTIME
+#define QMIX_FINDCHANNEL_MRA QMIX_FINDCHANNEL_ENDTIME
+
+_QMIXIMP
+int
+WINAPI
+QSWaveMixFindChannel(
+ HQMIXER hQMixer,
+ DWORD dwFlags,
+ const QMIX_CHANNEL_PARAMS* lpParams // compare with these parameters
+ );
+
+
+//
+// Turn on QMixer's dynamic scheduling. The lpChannelTypes array gives the
+// channel type (one of QMIX_CHANNELTYPE_ANYMIXER and one of
+// QMIX_CHANNELTYPE_ANYFEATURE) and the maximum number of desired channels of
+// that type that should play at any time. A count of -1 channels specifies
+// that as many channels as possible should be played. An entry with
+// dwChannelType ends the list. If lpChannelTypes is null, the current type
+// settings are used. If QMIX_PRIORITIZE_NONE is used, scheduling is turned
+// off.
+//
+typedef
+struct QMIX_CHANNELTYPES {
+ DWORD dwChannelType; // type of channel
+ int iMaxChannels; // maximum number of channels of that type to play
+} QMIX_CHANNELTYPES, *LPQMIX_CHANNELTYPES;
+
+
+#define QMIX_PRIORITIZE_NONE 0x0000000f
+
+_QMIXIMP MMRESULT WINAPI
+QSWaveMixPrioritizeChannels(
+ HQMIXER hQMixer,
+ LPQMIX_CHANNELTYPES lpChannelTypes,
+ DWORD dwFlags,
+ LPVOID lpvParams
+ );
+
+
+//
+// Structure describing wave data; returned by QSWaveMixOpenWave and
+// QSWaveMixOpenWaveEx.
+//
+#define MAXFILENAME 15
+
+typedef struct MIXWAVE {
+ PCMWAVEFORMAT pcm; // data format
+ WAVEHDR wh; // location and length of data
+ char szWaveFilename[MAXFILENAME+1]; // truncated version of name
+ LPWAVEFORMATEX pwf; // data format; needed for MSACM wave files
+#if defined(MACINTOSH)
+ CmpSoundHeader format; // Mac version of sound info
+#endif
+}
+MIXWAVE, FAR* LPMIXWAVE;
+typedef const MIXWAVE FAR* LPCMIXWAVE;
+
+// Input streaming callback function. Return TRUE to continue to play, return
+// FALSE to stop playing.
+typedef BOOL (CALLBACK *LPQMIXINPUTCALLBACK)(void* buffer, DWORD bytes, void* user);
+
+//
+// QSWaveMixOpenWave and QSWaveMixOpenWaveEx flags.
+//
+#define QMIX_FILE 0x0001 // load from file
+#define QMIX_RESOURCE 0x0002 // load from resource
+#define QMIX_MEMORY 0x0004 // load using MMIOINFO supplied by user
+#define QMIX_RESIDENT 0x0008 // use memory-resident data
+#define QMIX_FILESTREAM 0x0010 // stream from file
+#define QMIX_INPUTSTREAM 0x0011 // stream from input buffer
+#define QMIX_FILESPEC 0x0012 // Macintosh file specification
+
+typedef union {
+ const char* FileName; // Name of RIFF file (e.g. "*.wav") with wave.
+ struct { // Wave stored in resource.
+ const char* Name; // Name of resource.
+ HINSTANCE hInstance; // Handle of module where resource is located.
+ } Resource;
+ LPMMIOINFO lpMmioInfo; // Read from file already opened by mmioOpen.
+ struct { // Memory resident wave.
+ LPCWAVEFORMATEX Format; // Format of wave; can be compressed.
+ HPSTR Data; // Pointer to memory resident audio samples.
+ DWORD Bytes; // Length of Data, in bytes.
+ DWORD Samples; // Number of wave samples; needed if compressed.
+ DWORD Tag; // User-defined id.
+ } Resident;
+ struct { // Input streaming using user callback.
+ LPCWAVEFORMATEX Format; // Format of data (must be uncompressed).
+ DWORD BlockBytes; // Preferred length of block.
+ LPQMIXINPUTCALLBACK Callback; // User-defined callback function.
+ LPVOID User; // Data to be provided to callback.
+ DWORD Tag; // User-defined id.
+ } Stream;
+#if defined(MACINTOSH)
+ FSSpec* FileSpec; // Macintosh file specifier.
+#endif
+} QMIXWAVEPARAMS, *LPQMIXWAVEPARAMS;
+
+
+_QMIXIMP
+LPMIXWAVE
+WINAPI
+QSWaveMixOpenWaveEx(
+ HQMIXER hQMixer,
+ LPQMIXWAVEPARAMS lpWaveParams,
+ DWORD dwFlags
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixActivate(
+ HQMIXER hQMixer,
+ BOOL fActivate
+ );
+
+
+//
+// Options for dwFlags parameter in QSWaveMixPlayEx.
+//
+// Note: the QMIX_USELRUCHANNEL flag has two functions. When QMIX_CLEARQUEUE
+// is also set, the channel that has been playing the longest (least-recently-
+// used) is cleared and the buffer played. When QMIX_QUEUEWAVE is set, the
+// channel that will first finish playing will be selected and the buffer
+// queued to play. Of course, if an unused channel is found, it will be
+// selected instead. If QMIX_WAIT has not been specified, then the channel
+// number will be returned in the iChannel field.
+//
+#define QMIX_QUEUEWAVE 0x0000 // queue on channel
+#define QMIX_CLEARQUEUE 0x0001 // clear queue on channel
+#define QMIX_USELRUCHANNEL 0x0002 // see note above
+#define QMIX_HIPRIORITY 0x0004
+#define QMIX_HIGHPRIORITY QMIX_HIPRIORITY
+#define QMIX_WAIT 0x0008 // queue to be played with other sounds
+#define QMIX_IMMEDIATE 0x0020 // apply volume/pan changes without interpolation
+
+#define QMIX_PLAY_SETEVENT 0x0100 // call SetEvent((HANDLE)callback) on completion
+#define QMIX_PLAY_PULSEEVENT 0x0200 // call PulseEvent((HANDLE)callback) on completion
+#define QMIX_PLAY_NOTIFYSTOP 0x0400 // do callback even when stopping or flushing sound
+
+typedef void (CALLBACK *LPQMIXDONECALLBACK)(int iChannel, LPMIXWAVE lpWave, DWORD dwUser);
+
+typedef struct QMIXPLAYPARAMS {
+ DWORD dwSize; // this must be set
+ LPMIXWAVE lpImage; // additional preprocessed audio for high performance
+ HWND hwndNotify; // if set, WOM_OPEN and WOM_DONE notification messages sent here
+ LPQMIXDONECALLBACK callback;
+ DWORD dwUser; // user data accompanying callback
+ LONG lStart;
+ LONG lStartLoop;
+ LONG lEndLoop;
+ LONG lEnd;
+ const QMIX_CHANNEL_PARAMS* lpChannelParams; // initialize with these parameters
+}
+QMIXPLAYPARAMS, *LPQMIXPLAYPARAMS;
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixPlayEx(
+ HQMIXER hQMixer, // the mixer handle
+ int iChannel, // channel number to be played on
+ DWORD dwFlags,
+ LPMIXWAVE lpMixWave, // sound to be played
+ int iLoops, // number of loops to be played (-1 = forever)
+ LPQMIXPLAYPARAMS lpParams // if NULL, defaults will be used
+ );
+
+
+//
+// Functions for controlling channels.
+//
+// The flag QMIX_WAIT can be used in the dwFlags argument of the
+// channel parameter functions to defer the use of the new parameter
+// until the next sound is played with QSWaveMixPlayEx. This allows
+// us synchronize the changing of channel parameters with the beginning
+// of a sound.
+//
+// The flag QMIX_USEONCE can be used to use the parameter only for the
+// remainder of the current sound; afterwards the parameter reverts
+// back to the channel's defaults. If no sound is playing, the
+// parameter is used for the entire duration of the next sound.
+// If both QMIX_USEONCE and QMIX_WAIT are used, then the property takes
+// effect for the entire duration of the following sound.
+//
+// These flags can be used with the following functions:
+// - QSWaveMixEnableChannel
+// - QSWaveMixSetChannelParams
+// - QSWaveMixSetChannelPriority
+// - QSWaveMixSetDistanceMapping
+// - QSWaveMixSetFrequency
+// - QSWaveMixSetPan
+// - QSWaveMixSetPanRate
+// - QSWaveMixSetPolarPosition
+// - QSWaveMixSetPosition
+// - QSWaveMixSetSourceCone
+// - QSWaveMixSetSourceCone2
+// - QSWaveMixSetSourcePosition
+// - QSWaveMixSetSourceVelocity
+// - QSWaveMixSetVolume
+//
+#define QMIX_USEONCE 0x10 // settings are temporary
+
+
+//
+// Set the amount of time, in milliseconds, to effect a change in
+// a channel property (e.g. volume, position). Non-zero values smooth
+// out changes.
+//
+// Use QSWaveMixSetPanRate(hQMixer, iChannel, QMIX_WAIT|QMIX_USEONCE, 0)
+// to implement sudden changes for the next sound without losing the
+// smoothing function. Using QMIX_IMMEDIATE with QSWaveMixPlayEx also
+// causes immediate changes while preserving subsequent pan interpolations.
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetPanRate(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ DWORD dwRate
+ );
+
+//
+// The pan value can be set to values from 0 to 60:
+// 0 = full left,
+// 15 = straight ahead (mono),
+// 30 = full right,
+// 45 = behind.
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetPan(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ int pan
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetVolume(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ int volume
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetPolarPosition(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ const QSPOLAR* lpQPosition
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetFrequency(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ DWORD dwFrequency
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixPauseChannel(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixRestartChannel(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags
+ );
+
+
+#define QMIX_STOP_FINISHLASTLOOP 0x1000
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixStopChannel(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags
+ );
+
+
+//
+// QSWaveMixEnableChannel: if mode==0, use conventional, high-performance
+// stereo mixer. Non-zero modes imply some form of additional processing.
+//
+#define QMIX_CHANNEL_STEREO 0x0000 // perform stereo mixing
+#define QMIX_CHANNEL_QSOUND 0x0001 // perform QSound localization (default)
+#define QMIX_CHANNEL_DOPPLER 0x0002 // calculate velocity using position updates
+#define QMIX_CHANNEL_RANGE 0x0004 // do range effects
+#define QMIX_CHANNEL_ELEVATION 0x0008 // do elevation effects
+#define QMIX_CHANNEL_NODOPPLERPITCH 0x0010 // disable Doppler pitch shift for this channel
+#define QMIX_CHANNEL_PITCH_COPY 0x0000 // pitch shifting using copying (fastest)
+#define QMIX_CHANNEL_PITCH_LINEAR 0x0100 // pitch shifting using linear interpolation (better but slower)
+#define QMIX_CHANNEL_PITCH_SPLINE 0x0200 // pitch shifting using spline interpolation (better yet, but much slower)
+#define QMIX_CHANNEL_PITCH_FILTER 0x0300 // pitch shifting using FIR filter (best, but slowest)
+#define QMIX_CHANNEL_PITCH_MASK 0x0700 // bits reserved for pitch types
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixEnableChannel(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ int mode
+ );
+
+
+//
+// QSWaveMixEnable is equivalent to
+// QSWaveMixEnableChannel(hQMixer, 0, QMIX_ALL, mode).
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixEnable(
+ HQMIXER hQMixer,
+ int mode
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetChannelPriority(
+ HQMIXER hQMixer,
+ int iChannel,
+ LONG lPriority,
+ DWORD dwFlags
+ );
+
+
+//
+// Status functions.
+//
+
+//
+// Return a pointer to the internal DirectSound object. Handy for creating
+// additional secondary buffers (but only if QMIX_CONFIG_USEPRIMARY was not
+// set in QSWaveMixConfigureInit).
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetDirectSound(
+ HQMIXER hQMixer,
+ LPVOID FAR* lplpIDirectSound
+ );
+
+
+//
+// Return a pointer to the internal DirectSoundBuffer object.
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetDirectSoundBuffer(
+ HQMIXER hQMixer,
+ int iChannel,
+ LPVOID FAR* lplpIDirectSoundBuffer
+);
+
+
+//
+// Return TRUE if there are no more buffers playing or queued on the channel.
+// This is an alternative to waiting for a WOM_DONE message to be sent to a
+// window.
+//
+_QMIXIMP
+BOOL
+WINAPI
+QSWaveMixIsChannelDone(
+ HQMIXER hQMixer,
+ int iChannel
+ );
+
+
+#define QMIX_CHANNELSTATUS_OPEN 0x01 // channel is open
+#define QMIX_CHANNELSTATUS_QUEUED 0x02 // channel has a play request queued on it
+#define QMIX_CHANNELSTATUS_PAUSED 0x04 // channel is paused
+#define QMIX_CHANNELSTATUS_PLAYING 0x08 // channel is playing a sound
+#define QMIX_CHANNELSTATUS_RESERVED 0x10 // channel is reserved from FindChannel for playing
+
+_QMIXIMP DWORD WINAPI
+QSWaveMixGetChannelStatus(
+ HQMIXER hQMixer,
+ int iChannel
+ );
+
+
+#define QMIX_POSITION_BYTES 0
+#define QMIX_POSITION_SAMPLES 1
+#define QMIX_POSITION_MS 2
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetPlayPosition(
+ HQMIXER hQMixer,
+ int iChannel,
+ LPMIXWAVE* lplpWave,
+ LPDWORD lpdwPosition,
+ DWORD dwFlags
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetPan(
+ HQMIXER hQMixer,
+ int iChannel,
+ LPDWORD lpdwPan
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetVolume(
+ HQMIXER hQMixer,
+ int iChannel,
+ LPDWORD lpdwVolume
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetPanRate(
+ HQMIXER hQMixer,
+ int iChannel,
+ LPDWORD lpdwRate
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetFrequency(
+ HQMIXER hQMixer,
+ int iChannel,
+ LPDWORD lpdwFrequency
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetPolarPosition(
+ HQMIXER hQMixer,
+ int iChannel,
+ QSPOLAR* lpQPosition
+ );
+
+
+//**********************************************************************
+// Interface for 3d Cartesian Coordinate system.
+//
+// All measurements are in S.I. units, e.g. coordinates and room size are
+// meters, velocity and speed of sound in m/s.
+//
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetRoomSize(
+ HQMIXER hQMixer,
+ float roomSize,
+ DWORD dwFlags
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetSpeedOfSound(
+ HQMIXER hQMixer,
+ float speed,
+ DWORD dwFlags
+ );
+
+
+typedef struct QMIX_DISTANCES {
+ UINT cbSize; // size of structure (needed for future versions)
+ float minDistance; // sounds are at full volume if closer than this
+ float maxDistance; // sounds are muted if further away than this
+ float scale; // relative amount to adjust rolloff by
+} QMIX_DISTANCES, *LPQMIX_DISTANCES;
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetDistanceMapping(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ const LPQMIX_DISTANCES lpDistances
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetRoomSize(
+ HQMIXER hQMixer,
+ float* pfRoomSize
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetSpeedOfSound(
+ HQMIXER hQMixer,
+ float* pfSpeed
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetDistanceMapping(
+ HQMIXER hQMixer,
+ int iChannel,
+ LPQMIX_DISTANCES lpDistances
+ );
+
+//
+// Listener parameters.
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetListenerPosition(
+ HQMIXER hQMixer,
+ const QSVECTOR* position,
+ DWORD dwFlags
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetListenerOrientation(
+ HQMIXER hQMixer,
+ const QSVECTOR* direction,
+ const QSVECTOR* up,
+ DWORD dwFlags
+ );
+
+//
+// Velocity is used solely to set Doppler shift.
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetListenerVelocity(
+ HQMIXER hQMixer,
+ const QSVECTOR* velocity,
+ DWORD dwFlags
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetListenerRolloff(
+ HQMIXER hQMixer,
+ float rolloff,
+ DWORD dwFlags
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetListenerPosition(
+ HQMIXER hQMixer,
+ QSVECTOR* position
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetListenerOrientation(
+ HQMIXER hQMixer,
+ QSVECTOR* direction,
+ QSVECTOR* up
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetListenerVelocity(
+ HQMIXER hQMixer,
+ QSVECTOR* velocity
+ );
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetSourcePosition(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ const QSVECTOR* position
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetSourceVelocity(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ const QSVECTOR* velocity
+ );
+
+//
+// Listener will hear full volume if inside source's cone, given by
+// orientation and angle. If outside, source will be attenuated by
+// additional attenuation.
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetSourceCone(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ const QSVECTOR* orientation,
+ float coneAngle,
+ float ambient_db
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetSourceCone2(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ const QSVECTOR* orientation,
+ float innerConeAngle,
+ float outerConeAngle,
+ float ambient_db
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetSourcePosition(
+ HQMIXER hQMixer,
+ int iChannel,
+ QSVECTOR* position
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetSourceVelocity(
+ HQMIXER hQMixer,
+ int iChannel,
+ QSVECTOR* velocity
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetSourceCone(
+ HQMIXER hQMixer,
+ int iChannel,
+ QSVECTOR* orientation,
+ float* pfAngle,
+ float* ambient_db
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetSourceCone2(
+ HQMIXER hQMixer,
+ int iChannel,
+ QSVECTOR* orientation,
+ float* pfInnerAngle,
+ float* pfOuterAngle,
+ float* ambient_db
+ );
+
+
+//**********************************************************************
+// Profiling functions.
+//
+typedef struct QMIX_PROFILE {
+ DWORD dwCalls; // number of times mixer thread was called
+ DWORD dwMixing; // time spent mixing
+ DWORD dwAudioDriver; // time spent calling audio driver (e.g. DirectSound)
+ DWORD dwTotal; // total time in mixer thread
+ DWORD dwDuration; // time during test
+} QMIX_PROFILE, *LPQMIX_PROFILE;
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixStartProfile(
+ HQMIXER hQMixer
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixStopProfile(
+ HQMIXER hQMixer,
+ LPQMIX_PROFILE lpProfile,
+ UINT cbProfile
+ );
+
+
+//**********************************************************************
+// Call QSWaveMixPump to force more mixing. Essential if mixer was
+// configured with QMIX_CONFIG_NOTHREAD.
+//
+_QMIXIMP
+void
+WINAPI
+QSWaveMixPump(
+ void);
+
+
+//**********************************************************************
+// Functions to shut down mixer.
+//
+// Note that, in versions 2.10 and later, that QSWaveMixFreeWave can be
+// called with a null hQMixer if QSWaveMixCloseSession has been called.
+//
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixFlushChannel(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixCloseChannel(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixFreeWave(
+ HQMIXER hQMixer,
+ LPMIXWAVE lpMixWave
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixCloseSession(
+ HQMIXER hQMixer
+ );
+
+
+//
+// Diagnostic codes available from QSWaveMixGetLastError. Equivalent strings
+// can be recalled using QSWaveMixGetErrorText.
+//
+#define ERROR_QMIX_OK 0 // OK, no error.
+#define ERROR_QMIX_CONFIGMISSING 1 // Can't find configuration (.ini) file.
+#define ERROR_QMIX_MIXERHANDLE 2 // Mixer handle is null or invalid.
+#define ERROR_QMIX_RESULTUNKNOWN 3 // Unknown error code.
+#define ERROR_QMIX_MEMORY 4 // Out of memory.
+#define ERROR_QMIX_EXCEPTIONUNKNOWN 5 // Unknown error.
+#define ERROR_QMIX_WAVEOUTNONE 6 // No wave output devices.
+#define ERROR_QMIX_DLLNAME 7 // Name of QMixer library is unavailable or invalid.
+#define ERROR_QMIX_WAVEOUTINCOMPATIBLE 8 // The wave output device is incompatible with QMixer.
+#define ERROR_QMIX_ACTIVATED 9 // Can't activate two QMixer sessions.
+#define ERROR_QMIX_CHANNELINVALID 10 // Channel number is invalid.
+#define ERROR_QMIX_OPENCHANNELFLAG 11 // Invalid flag for opening channel.
+#define ERROR_QMIX_PANINVALID 12 // Invalid pan value.
+#define ERROR_QMIX_NOTACTIVATED 13 // Mixer has not been activated.
+#define ERROR_QMIX_CHANNELUNAVAILABLE 14 // No channels are available for playing this sound.
+#define ERROR_QMIX_WAVERESOURCE 15 // Couldn't find or load resource containing wave data.
+#define ERROR_QMIX_WAVEOPEN 16 // Couldn't open wave file.
+#define ERROR_QMIX_WAVEFORMAT 17 // Format of wave data is corrupted.
+#define ERROR_QMIX_ACMINVALID 18 // The ACM wave format couldn't be translated.
+#define ERROR_QMIX_DSOUNDMISSING 19 // The DirectSound library dsound.dll could not be found.
+#define ERROR_QMIX_DSOUNDCREATEADDR 20 // Could not find DirectSoundCreate function in dsound.dll.
+#define ERROR_QMIX_DSOUNDCREATE 21 // Couldn't create DirectSound object.
+#define ERROR_QMIX_DSOUNDCOOPERATIVE 22 // The cooperative level for DirectSound could not be set.
+#define ERROR_QMIX_DSOUNDCAPS 23 // Couldn't determine DirectSound capabilities.
+#define ERROR_QMIX_DSOUNDPRIMARY 24 // Couldn't create DirectSound primary buffer.
+#define ERROR_QMIX_DSOUNDPRIMARYCAPS 25 // Couldn't determine DirectSound primary buffer capabilities.
+#define ERROR_QMIX_DSOUNDFORMAT 26 // Couldn't set format of DirectSound output.
+#define ERROR_QMIX_DSOUNDSECONDARY 27 // Couldn't create DirectSound secondary buffer.
+#define ERROR_QMIX_DSOUNDPLAY 28 // Couldn't play DirectSound buffer.
+#define ERROR_QMIX_WAVEOUTOPEN 29 // Wave output error while opening device.
+#define ERROR_QMIX_WAVEOUTWRITE 30 // Wave output error while writing to device.
+#define ERROR_QMIX_WAVEOUTCLOSE 31 // Wave output error while closing device.
+#define ERROR_QMIX_PARAMPTR 32 // Parameter points to invalid location.
+#define ERROR_QMIX_NOTIMPLEMENTED 33 // Feature is not implemented.
+#define ERROR_QMIX_DSOUNDNODRIVER 34 // No DirectSound driver is available for use.
+#define ERROR_QMIX_SMALLPRIMARY 35 // DirectSound primary buffer is too small.
+#define ERROR_QMIX_UNKNOWNFORMAT 36 // Unknown sound file format.
+#define ERROR_QMIX_DRIVENOTREADY 37 // Drive is not ready.
+#define ERROR_QMIX_READERROR 38 // Error reading sound file.
+#define ERROR_QMIX_UNKNOWNAIFC 39 // Unknown format of AIFF-C file.
+#define ERROR_QMIX_MACRESOURCE 40 // Unable to obtain sampled sound data from resource.
+#define ERROR_QMIX_SCINVALID 41 // The sound data format couldn't be translated.
+#define ERROR_QMIX_MACSOUNDCAPS 42 // Couldn't retrieve Macintosh sound output capabilities.
+#define ERROR_QMIX_MACCHANNEL 43 // Couldn't create sound channel.
+#define ERROR_QMIX_MACCLEAR 44 // Couldn't clear sound channel.
+#define ERROR_QMIX_MACPAUSE 45 // Couldn't pause sound channel.
+#define ERROR_QMIX_MACQUEUE 46 // Couldn't queue data on sound channel.
+#define ERROR_QMIX_MACRESUME 47 // Couldn't resume paused sound channel.
+#define ERROR_QMIX_CATCH 48 // Caught unknown error.
+#define ERROR_QMIX_HOLD 49 // Unable to prevent virtual memory from being paged.
+#define ERROR_QMIX_INVALIDPARAM 50 // Invalid parameter.
+#define ERROR_QMIX_DSB_STATUS 51 // Couldn't get DirectSound buffer status.
+#define ERROR_QMIX_DSB_POSITION 52 // Couldn't get DirectSound buffer position.
+#define ERROR_QMIX_DSOUNDMIXPRIMARY 53 // Can't mix into primary buffer (DirectSound driver is probably emulated).
+
+
+/* set to byte packing so Win16 and Win32 structures will be the same */
+#pragma pack(1)
+
+typedef struct WAVEMIXINFO {
+ WORD wSize;
+ BYTE bVersionMajor;
+ BYTE bVersionMinor;
+ char szDate[12]; /* Mmm dd yyyy */
+ DWORD dwFormats; /* see waveOutGetDevCaps (wavemix requires synchronous device) */
+}
+WAVEMIXINFO, *PWAVEMIXINFO, FAR * LPWAVEMIXINFO;
+
+_QMIXIMP
+WORD
+WINAPI
+QSWaveMixGetInfo(
+ LPWAVEMIXINFO lpWaveMixInfo
+ );
+
+
+//
+// Constants, structure, and declaration for obsolete configuration function.
+//
+
+#define WMIX_CONFIG_CHANNELS 0x0001
+#define WMIX_CONFIG_SAMPLINGRATE 0x0002
+#define WMIX_CONFIG_DIRECTSOUND 0x0004
+#define WMIX_CONFIG_USEPRIMARY 0x0008
+#define WMIX_CONFIG_INPUTCHANNELS 0x0010
+#define WMIX_CONFIG_OUTPUT 0x0020
+#define WMIX_CONFIG_LATENCY 0x0040
+#define WMIX_CONFIG_NOTHREAD 0x0080
+
+#define WMIX_OUTPUT_WAVEOUT 0
+#define WMIX_OUTPUT_DIRECTSOUND 1
+#define WMIX_OUTPUT_NATIVEAUDIO 2 // not implemented
+
+typedef struct MIXCONFIG {
+ WORD wSize;
+ DWORD dwFlags;
+ WORD wChannels; // 1=MONO, 2=STEREO
+ WORD wSamplingRate; // 11=11025, 22=22050, 44=44100 Hz
+ LPVOID lpIDirectSound;
+ WORD wInputChannels;
+ WORD wOutput;
+ WORD wLatency;
+}
+MIXCONFIG, *PMIXCONFIG, FAR * LPMIXCONFIG;
+
+_QMIXIMP
+HQMIXER
+WINAPI
+QSWaveMixConfigureInit(
+ LPMIXCONFIG lpConfig
+ );
+
+
+//
+// Obsolete wave opening function.
+//
+
+//
+// Structure for opening waves that are already residing in memory.
+// Note that the dwSamples parameter is a new field needed for using
+// compressed data. To keep backwards compatibility, it is only used
+// when QSWaveMixOpenWave is used with the QMIX_RESIDENT_COMPRESSED
+// parameter.
+//
+#define QMIX_RESIDENT_COMPRESSED 0x0009 // QMIX_RESIDENT with valid dwSample parameter
+
+typedef struct QMEMRESIDENT {
+ PCMWAVEFORMAT* pcm; // format; LPWAVEFORMATEX works here too
+ HPSTR lpData; // pointer to memory resident audio samples
+ DWORD dwDataSize; // length of data, in bytes
+ WORD tag; // user-defined id (used in MIXWAVE.szWaveFilename)
+ DWORD dwSamples; // number of samples in compressed wave
+}
+QMEMRESIDENT, * PQMEMRESIDENT, FAR * LPQMEMRESIDENT;
+
+//
+// Structure for a wave that will get audio from user callback function.
+//
+#if defined(_WIN32)
+ typedef void (__cdecl* LPQMIXSTREAMCALLBACK)(void* buffer, DWORD bytes, void* user);
+#endif
+#if defined(MACINTOSH)
+ typedef void (* LPQMIXSTREAMCALLBACK)(void* buffer, DWORD bytes, void* user);
+#endif
+typedef struct QINPUTSTREAM {
+ PCMWAVEFORMAT* pcm; // format of input data: must be in PCM
+ DWORD dwBlockLength; // preferred block length (bytes)
+ LPQMIXSTREAMCALLBACK callback;
+ // callback called when more data needed
+ void *user; // user data sent to callback
+ WORD tag;
+}
+QINPUTSTREAM, *PQINPUTSTREAM, FAR* LPQINPUTSTREAM;
+
+//
+// Open wave file. The szWaveFilename parameter is one of the
+// following:
+// - name of file (QMIX_FILE and QMIX_FILESTREAM flags),
+// - name of resource (also need to set hInst) (QMIX_RESOURCE flag),
+// - LPQMEMRESIDENT pointer cast to LPSTR (QMIX_RESIDENT flag),
+// - LPQINPUTSTREAM pointer cast to LPSTR (QMIX_INPUTSTREAM flag),
+// - LPMMIOINFO pointer cast to LPSTR (QMIX_MEMORY flag),
+// - FSSpec* pointer cast to LPSTR (on Macintosh) (QMIX_FILESPEC flag),
+//
+_QMIXIMP
+LPMIXWAVE
+WINAPI
+QSWaveMixOpenWave(
+ HQMIXER hQMixer,
+ LPSTR szWaveFilename, // see notes above
+ HINSTANCE hInst, // only required when QMIX_RESOURCE flag set
+ DWORD dwFlags
+ );
+
+
+typedef struct QPOSITION {
+ int azimuth; // degrees; 0 is straight ahead, 90 is to the right
+ int range; // 0 to 32767; 0 is closest
+ int elevation; // -90 to 90 degrees
+} QPOSITION, FAR* LPQPOSITION;
+
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixSetPosition(
+ HQMIXER hQMixer,
+ int iChannel,
+ DWORD dwFlags,
+ const QPOSITION* lpQPosition
+ );
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixGetPosition(
+ HQMIXER hQMixer,
+ int iChannel,
+ LPQPOSITION lpQPosition
+ );
+
+//
+// Obsolete play function.
+//
+
+#define QMIX_USEPOSITION 0x10 // use the MIXPLAYPARAMS.position field
+
+typedef struct MIXPLAYPARAMS {
+ WORD wSize; // this must be set
+ HQMIXER hMixSession; // value returned by QSWaveMixInit or QSWaveMixConfigureInit
+ int iChannel; // channel number
+ LPMIXWAVE lpMixWave; // pointer returned by QSWaveMixOpenWave
+ HWND hWndNotify; // if set, WOM_OPEN and WOM_DONE notification messages sent here
+ DWORD dwFlags;
+ WORD wLoops; // 0xFFFF means loop forever
+ int qVolume; // initial volume; set to -1 to use default
+ int qPanPos; // initial pan position; set to -1 to use default
+ LPMIXWAVE lpImage; // set to preprocessed data for high performance
+ QPOSITION position; // initial position (used only if QMIX_USEPOSITION set)
+}
+MIXPLAYPARAMS, * PMIXPLAYPARAM, FAR* LPMIXPLAYPARAMS;
+
+_QMIXIMP
+MMRESULT
+WINAPI
+QSWaveMixPlay(
+ LPMIXPLAYPARAMS lpMixPlayParams
+ );
+
+
+/* return to default packing */
+#pragma pack()
+
+//
+// Obsolete constants.
+//
+#define WMIX_ALL QMIX_ALL
+#define WMIX_NOREMIX QMIX_NOREMIX
+#define WMIX_CONTROL_NOREMIX QMIX_CONTROL_NOREMIX
+
+#define WMIX_OPENSINGLE QMIX_OPENSINGLE
+#define WMIX_OPENALL QMIX_OPENALL
+#define WMIX_OPENCOUNT QMIX_OPENCOUNT
+#define WMIX_OPENAVAILABLE QMIX_OPENAVAILABLE
+
+#define WMIX_FILE QMIX_FILE
+#define WMIX_RESOURCE QMIX_RESOURCE
+#define WMIX_MEMORY QMIX_MEMORY
+#define WMIX_RESIDENT QMIX_RESIDENT
+#define WMIX_FILESTREAM QMIX_FILESTREAM
+#define WMIX_INPUTSTREAM QMIX_INPUTSTREAM
+
+#define WMIX_QUEUEWAVE QMIX_QUEUEWAVE
+#define WMIX_CLEARQUEUE QMIX_CLEARQUEUE
+#define WMIX_USELRUCHANNEL QMIX_USELRUCHANNEL
+#define WMIX_HIPRIORITY QMIX_HIPRIORITY
+#define WMIX_HIGHPRIORITY QMIX_HIGHPRIORITY
+#define WMIX_WAIT QMIX_WAIT
+#define WMIX_USEPOSITION QMIX_USEPOSITION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/build/dxwnd.dll b/build/dxwnd.dll
index 9a87d37..80d28ca 100644
--- a/build/dxwnd.dll
+++ b/build/dxwnd.dll
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:4ba9b297fe64848f5b2fc2ec464edf523c15537cec300708587e072b69b6d175
-size 622080
+oid sha256:b4a56c750b4f879d9a6bf014e56fa028e80775f98c19db9213fcbf8567169193
+size 622592
diff --git a/build/dxwnd.exe b/build/dxwnd.exe
index 89e6f9f..f250f67 100644
--- a/build/dxwnd.exe
+++ b/build/dxwnd.exe
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:bd5ee4d4d589d7580de254177665f34b2c8ead891982d3700123f29cecc90cc3
-size 546304
+oid sha256:b1fae4424d81cb9fc6c32e8a30525dc678480e1bc9c40784d2b528a6d736f9bb
+size 546816
diff --git a/build/dxwnd.ini b/build/dxwnd.ini
deleted file mode 100644
index 5d59aee..0000000
--- a/build/dxwnd.ini
+++ /dev/null
@@ -1,64 +0,0 @@
-[window]
-posx=1313
-posy=581
-sizx=320
-sizy=200
-lang=default
-exepath=D:\Games\Kasbrik\
-;lang=automatic
-;updatepaths=1
-;debug=1
-;multiprocesshook=0
-;checkadmin=0
-[texture]
-MinTexX=16
-MaxTexX=0
-MinTexY=16
-MaxTexY=0
-[keymapping]
-timetoggle=0x72
-altf4=0x73
-timeslow=0x74
-timefast=0x75
-cliptoggle=
-refresh=
-logtoggle=
-plocktoggle=
-fpstoggle=
-printscreen=0x7B
-corner=0x7A
-freezetime=0x79
-
-
-[target]
-title0=Kasbrik 3D
-path0=D:\Games\Kasbrik\Kasbrik.exe
-launchpath0=
-module0=
-opengllib0=
-notes0=
-registry0=
-ver0=8
-coord0=0
-flag0=136314914
-flagg0=1207959552
-flagh0=20
-flagi0=138412036
-flagj0=4224
-flagk0=327680
-tflag0=0
-initx0=0
-inity0=0
-minx0=0
-miny0=0
-maxx0=0
-maxy0=0
-posx0=50
-posy0=50
-sizx0=800
-sizy0=600
-maxfps0=0
-initts0=0
-winver0=0
-maxres0=-1
-swapeffect0=0
diff --git a/build/exports/Age of Empires.dxw b/build/exports/Age of Empires.dxw
index b8e909f..7b47328 100644
--- a/build/exports/Age of Empires.dxw
+++ b/build/exports/Age of Empires.dxw
@@ -6,7 +6,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=134218272
+flag0=134218274
flagg0=1207959552
flagh0=20
flagi0=4194308
@@ -26,3 +26,7 @@ initts0=0
winver0=0
maxres0=-1
flagj0=128
+notes0=
+registry0=
+flagk0=0
+swapeffect0=0
diff --git a/build/exports/Croc 2.dxw b/build/exports/Croc 2.dxw
index d24154e..ec5b60c 100644
--- a/build/exports/Croc 2.dxw
+++ b/build/exports/Croc 2.dxw
@@ -6,7 +6,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=134218272
+flag0=134218274
flagg0=1207959552
flagh0=20
flagi0=138412036
@@ -27,3 +27,6 @@ winver0=0
maxres0=-1
notes0=
flagj0=128
+registry0=
+flagk0=65536
+swapeffect0=0
diff --git a/build/exports/Dark Colony.dxw b/build/exports/Dark Colony.dxw
index 31fed2d..f23cefd 100644
--- a/build/exports/Dark Colony.dxw
+++ b/build/exports/Dark Colony.dxw
@@ -5,7 +5,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=134218272
+flag0=134218274
flagg0=1207959552
flagh0=20
flagi0=4194308
@@ -26,3 +26,7 @@ winver0=0
maxres0=-1
launchpath0=
flagj0=128
+notes0=
+registry0=
+flagk0=0
+swapeffect0=0
diff --git a/build/exports/Dark Planet Battle for Natrolis.dxw b/build/exports/Dark Planet Battle for Natrolis.dxw
index 8094d4a..3cc87aa 100644
--- a/build/exports/Dark Planet Battle for Natrolis.dxw
+++ b/build/exports/Dark Planet Battle for Natrolis.dxw
@@ -6,9 +6,9 @@ opengllib0=
ver0=0
coord0=0
flag0=671088675
-flagg0=1208025088
+flagg0=1207959552
flagh0=20
-flagi0=4194316
+flagi0=4194308
tflag0=0
initx0=0
inity0=0
@@ -27,5 +27,6 @@ maxres0=-1
launchpath0=
notes0=
flagj0=128
-flagk0=0
+flagk0=65536
swapeffect0=0
+registry0=
diff --git a/build/exports/Dark Vengeance.dxw b/build/exports/Dark Vengeance.dxw
index 5e8c151..307d6ea 100644
--- a/build/exports/Dark Vengeance.dxw
+++ b/build/exports/Dark Vengeance.dxw
@@ -26,3 +26,7 @@ winver0=0
maxres0=-1
launchpath0=
flagj0=128
+notes0=
+registry0=
+flagk0=65536
+swapeffect0=0
diff --git a/build/exports/Darkened Skye.dxw b/build/exports/Darkened Skye.dxw
index a7c1926..1fa83fe 100644
--- a/build/exports/Darkened Skye.dxw
+++ b/build/exports/Darkened Skye.dxw
@@ -5,7 +5,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=679493666
+flag0=679493682
flagg0=1207959552
flagh0=65556
flagi0=69206020
@@ -14,8 +14,8 @@ initx0=0
inity0=0
minx0=0
miny0=0
-maxx0=0
-maxy0=0
+maxx0=800
+maxy0=600
posx0=50
posy0=50
sizx0=800
@@ -27,5 +27,6 @@ maxres0=-1
launchpath0=
notes0=
flagj0=128
-flagk0=0
+flagk0=65536
swapeffect0=0
+registry0=
diff --git a/build/exports/DeathSpank The Baconing.dxw b/build/exports/DeathSpank The Baconing.dxw
index 854119a..c94cdeb 100644
--- a/build/exports/DeathSpank The Baconing.dxw
+++ b/build/exports/DeathSpank The Baconing.dxw
@@ -5,10 +5,10 @@ module0=
opengllib0=
ver0=9
coord0=0
-flag0=134218272
+flag0=-2013265376
flagg0=1207959552
flagh0=20
-flagi0=4
+flagi0=4194308
tflag0=0
initx0=0
inity0=0
@@ -24,3 +24,9 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+launchpath0=
+notes0=
+registry0=
+flagj0=0
+flagk0=0
+swapeffect0=0
diff --git a/build/exports/Dracula Twins.dxw b/build/exports/Dracula Twins.dxw
index f3774e5..66785bb 100644
--- a/build/exports/Dracula Twins.dxw
+++ b/build/exports/Dracula Twins.dxw
@@ -8,7 +8,7 @@ coord0=0
flag0=134217762
flagg0=1207959552
flagh0=20
-flagi0=4
+flagi0=4194308
tflag0=0
initx0=0
inity0=0
@@ -22,3 +22,11 @@ sizx0=800
sizy0=600
maxfps0=0
initts0=0
+launchpath0=
+notes0=
+registry0=
+flagj0=128
+flagk0=0
+winver0=0
+maxres0=0
+swapeffect0=0
diff --git a/build/exports/Dune 2000.dxw b/build/exports/Dune 2000.dxw
index 328d89a..84115c1 100644
--- a/build/exports/Dune 2000.dxw
+++ b/build/exports/Dune 2000.dxw
@@ -12,7 +12,7 @@ flagg0=1207959568
flagh0=20
flagi0=4194308
flagj0=128
-flagk0=0
+flagk0=32768
tflag0=0
initx0=0
inity0=0
@@ -29,3 +29,4 @@ initts0=0
winver0=0
maxres0=-1
swapeffect0=0
+registry0=
diff --git a/build/exports/Earthworm Jim 3D.dxw b/build/exports/Earthworm Jim 3D.dxw
index cdc01c8..430093f 100644
--- a/build/exports/Earthworm Jim 3D.dxw
+++ b/build/exports/Earthworm Jim 3D.dxw
@@ -6,10 +6,10 @@ opengllib0=
ver0=0
coord0=0
flag0=134217762
-flagg0=1212153856
+flagg0=1213202432
flagh0=65556
flagi0=4194308
-tflag0=6147
+tflag0=0
initx0=0
inity0=0
minx0=0
@@ -27,5 +27,6 @@ maxres0=-1
launchpath0=
notes0=
flagj0=128
-flagk0=0
+flagk0=65536
swapeffect0=0
+registry0=
diff --git a/build/exports/Echelon.dxw b/build/exports/Echelon.dxw
index f978d4a..8537efb 100644
--- a/build/exports/Echelon.dxw
+++ b/build/exports/Echelon.dxw
@@ -27,5 +27,6 @@ maxres0=-1
launchpath0=
notes0=
flagj0=128
-flagk0=0
+flagk0=65536
swapeffect0=0
+registry0=
diff --git a/build/exports/Ed Hunter.dxw b/build/exports/Ed Hunter.dxw
index 743b133..a3a58a1 100644
--- a/build/exports/Ed Hunter.dxw
+++ b/build/exports/Ed Hunter.dxw
@@ -27,5 +27,6 @@ maxres0=-1
launchpath0=
notes0=
flagj0=128
-flagk0=0
+flagk0=98304
swapeffect0=0
+registry0=
diff --git a/build/exports/Hexplore.dxw b/build/exports/Hexplore.dxw
index eb0303f..c973580 100644
--- a/build/exports/Hexplore.dxw
+++ b/build/exports/Hexplore.dxw
@@ -6,7 +6,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=134234146
+flag0=134236194
flagg0=1207959552
flagh0=20
flagi0=138412036
@@ -26,3 +26,7 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+notes0=
+registry0=
+flagk0=65536
+swapeffect0=0
diff --git a/build/exports/House of the Dead 2.dxw b/build/exports/House of the Dead 2.dxw
index c022a51..d416ca6 100644
--- a/build/exports/House of the Dead 2.dxw
+++ b/build/exports/House of the Dead 2.dxw
@@ -6,7 +6,7 @@ opengllib0=
ver0=0
coord0=0
flag0=738197538
-flagg0=1207959552
+flagg0=1744830464
flagh0=20
flagi0=4194308
tflag0=0
@@ -29,3 +29,4 @@ notes0=
flagj0=128
flagk0=65536
swapeffect0=0
+registry0=
diff --git a/build/exports/Hydro Thunder.dxw b/build/exports/Hydro Thunder.dxw
index d952464..26cb925 100644
--- a/build/exports/Hydro Thunder.dxw
+++ b/build/exports/Hydro Thunder.dxw
@@ -5,7 +5,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=704643106
+flag0=706740258
flagg0=1207959552
flagh0=20
flagi0=4194308
@@ -29,3 +29,4 @@ notes0=
flagj0=128
flagk0=65536
swapeffect0=0
+registry0=
diff --git a/build/exports/Jazz Jackrabbit 2.dxw b/build/exports/Jazz Jackrabbit 2.dxw
index a01a21a..fda43f3 100644
--- a/build/exports/Jazz Jackrabbit 2.dxw
+++ b/build/exports/Jazz Jackrabbit 2.dxw
@@ -5,10 +5,10 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=671097376
+flag0=671097378
flagg0=1207959552
flagh0=20
-flagi0=4
+flagi0=4194308
tflag0=0
initx0=0
inity0=0
@@ -24,3 +24,9 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+launchpath0=
+notes0=
+registry0=
+flagj0=0
+flagk0=0
+swapeffect0=0
diff --git a/build/exports/Jeff Gordon XS Racing demo.dxw b/build/exports/Jeff Gordon XS Racing demo.dxw
index 1c4b335..aea3e5e 100644
--- a/build/exports/Jeff Gordon XS Racing demo.dxw
+++ b/build/exports/Jeff Gordon XS Racing demo.dxw
@@ -7,7 +7,7 @@ opengllib0=
notes0=
ver0=0
coord0=0
-flag0=671088928
+flag0=740294690
flagg0=1476395008
flagh0=20
flagi0=138412036
@@ -27,3 +27,6 @@ maxfps0=0
initts0=0
winver0=0
maxres0=-1
+registry0=
+flagk0=65536
+swapeffect0=0
diff --git a/build/exports/KKND Xtreme.dxw b/build/exports/KKND Xtreme.dxw
index 385b289..919a720 100644
--- a/build/exports/KKND Xtreme.dxw
+++ b/build/exports/KKND Xtreme.dxw
@@ -5,7 +5,7 @@ module0=
opengllib0=
ver0=0
coord0=0
-flag0=402669600
+flag0=402669602
flagg0=1207959552
flagh0=20
flagi0=4194308
@@ -26,4 +26,7 @@ winver0=0
maxres0=-1
launchpath0=
notes0=
-flagj0=8388736
+flagj0=128
+registry0=
+flagk0=65536
+swapeffect0=0
diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt
index 539309d..ab8f15a 100644
--- a/build/readme-relnotes.txt
+++ b/build/readme-relnotes.txt
@@ -981,3 +981,10 @@ fix: completely revised directinput hooking to manage multiple devices acquire/u
fix: added some dinput error codes to log messages
fix: increased time freeze toggle key hysteresis time to 1 sec to avoid multiple activations
+v2.03.48
+fix: set proper surface capabilities for 3DDEVICE surfaces, according to VIDEOMEMORY capability.
+add: "force clipper" flag to redirect clipper definition to main window and primary surface
+fix: better handling of surfaces on minimize / restore events, mainly on WinXP
+fix: proper default values for"Share ddraw and GDI DC" and "Lock/Unlock Pitch Fix" flags
+
+
diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp
index fb390c1..423214d 100644
--- a/dll/ddblit.cpp
+++ b/dll/ddblit.cpp
@@ -8,7 +8,8 @@
#include "hddraw.h"
#include "dxhelper.h"
-//extern LPDIRECTDRAWSURFACE lpDDSBack;
+#define FIXBIGGERRECT 1
+
extern LPDIRECTDRAWSURFACE lpDDSEmu_Prim;
extern LPDIRECTDRAW lpPrimaryDD;
extern Blt_Type pBlt;
@@ -37,8 +38,7 @@ static HRESULT sBltNoPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdest
//extern PrimaryBlt_Type pPrimaryBlt;
//CkArg arg;
- //FromScreen=dxwss.IsAPrimarySurface(lpddssrc) && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77
- FromScreen=dxwss.IsAPrimarySurface(lpddssrc); // ghogho
+ FromScreen=dxwss.IsAPrimarySurface(lpddssrc);
// make a working copy of srcrect if not NULL
if (lpsrcrect){
@@ -136,7 +136,6 @@ static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdest
}
#endif
-#define FIXBIGGERRECT 1
#if FIXBIGGERRECT
if(lpdestrect){
if((DWORD)lpdestrect->top < 0) lpdestrect->top = 0;
@@ -163,6 +162,12 @@ static HRESULT sBltToPrimary(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdest
destrect.left, destrect.top, destrect.right, destrect.bottom,
dxw.GetScreenWidth(), dxw.GetScreenHeight());
+ // v2.03.48: on WinXP it may happen (reported by Cloudstr) that alt tabbing produces
+ // bad blit attempts where the client coordinates get the (-32000,-32000) - (-32000,-32000)
+ // value. In such cases, it's adviseable to simulate an OK return code without attempting
+ // any blit operation!
+ if(destrect.left == -32000) return DD_OK; // no blit on invisible window
+
if(!lpddssrc) {
if (isFlipping){
// handle the flipping chain ...
diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp
index 5754549..62ce43b 100644
--- a/dll/ddraw.cpp
+++ b/dll/ddraw.cpp
@@ -1093,6 +1093,8 @@ static void HookDDClipper(LPDIRECTDRAWCLIPPER FAR* lplpDDClipper)
SetHook((void *)(**(DWORD **)lplpDDClipper + 8), extReleaseC, (void **)&pReleaseC, "Release(C)");
// IDirectDrawClipper::GetClipList
SetHook((void *)(**(DWORD **)lplpDDClipper + 12), extGetClipList, (void **)&pGetClipList, "GetClipList(C)");
+ // IDirectDrawClipper::SetHWnd
+ SetHook((void *)(**(DWORD **)lplpDDClipper + 32), extSetHWndProxy, (void **)&pSetHWnd, "SetHWnd(C)");
if (!(dxw.dwTFlags & OUTPROXYTRACE)) return;
// Just proxed ...
@@ -1109,8 +1111,6 @@ static void HookDDClipper(LPDIRECTDRAWCLIPPER FAR* lplpDDClipper)
SetHook((void *)(**(DWORD **)lplpDDClipper + 24), extIsClipListChangedProxy, (void **)&pIsClipListChanged, "IsClipListChanged(C)");
// IDirectDrawClipper::SetClipList
SetHook((void *)(**(DWORD **)lplpDDClipper + 28), extSetClipListProxy, (void **)&pSetClipList, "SetClipList(C)");
- // IDirectDrawClipper::SetHWnd
- SetHook((void *)(**(DWORD **)lplpDDClipper + 32), extSetHWndProxy, (void **)&pSetHWnd, "SetHWnd(C)");
return;
}
@@ -2203,12 +2203,19 @@ static void FixSurfaceCaps(LPDDSURFACEDESC2 lpddsd, int dxversion)
lpddsd->ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
return;
}
-
- if((lpddsd->dwFlags & DDSD_CAPS) &&
- (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) // v2.02.90: added for "Zoo Tycoon" textures
- { // 3DDEVICE no TEXTURE: enforce PIXELFORMAT on MEMORY
+
+ // 3DDEVICE no TEXTURE: enforce PIXELFORMAT
+ // v2.02.90: added for "Zoo Tycoon" textures
+ // v2.03.48 - there are two situations
+ // "Arx fatalis" asks for DDSCAPS_3DDEVICE+DDSCAPS_OFFSCREENPLAIN capability and needs no DDSCAPS_SYSTEMMEMORY capability
+ // "Bunnies must die" asks for DDSCAPS_3DDEVICE+DDSCAPS_OFFSCREENPLAIN+DDSCAPS_VIDEOMEMORY capability and requires DDSCAPS_SYSTEMMEMORY capability
+ // we try to manage them by checking for the DDSCAPS_VIDEOMEMORY capability ...
+ if((lpddsd->dwFlags & DDSD_CAPS) && (lpddsd->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)){
lpddsd->dwFlags |= DDSD_PIXELFORMAT;
- lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE);
+ if(lpddsd->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
+ lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE|DDSCAPS_SYSTEMMEMORY); // good for "Bunnies must die", NO "Arx Fatalis"
+ else
+ lpddsd->ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE); // good for "Arx Fatalis", NO "Bunnies must die"
GetPixFmt(lpddsd);
return;
}
@@ -3207,12 +3214,24 @@ HRESULT WINAPI PrimaryBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECT
HRESULT WINAPI PrimaryFastBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect)
{
+ HRESULT res;
RECT client;
int iXOffset, iYOffset; // offsets to center surface area to window
(*pGetClientRect)(dxw.GethWnd(), &client);
iXOffset = (client.right - dxw.GetScreenWidth()) >> 1;
iYOffset = (client.bottom - dxw.GetScreenHeight()) >> 1;
- return (*pBltFast)(lpdds, iXOffset + lpdestrect->left, iYOffset + lpdestrect->top, lpddssrc, lpsrcrect, DDBLTFAST_WAIT);
+ if(dxw.dwFlags3 & FORCECLIPPER){
+ RECT destrect;
+ destrect.left = iXOffset + lpdestrect->left;
+ destrect.right = iXOffset + lpdestrect->right;
+ destrect.top = iYOffset + lpdestrect->top;
+ destrect.bottom = iYOffset + lpdestrect->bottom;
+ res = (*pBlt)(lpdds, &destrect, lpddssrc, lpsrcrect, DDBLT_WAIT, 0);
+ }
+ else {
+ res= (*pBltFast)(lpdds, iXOffset + lpdestrect->left, iYOffset + lpdestrect->top, lpddssrc, lpsrcrect, DDBLTFAST_WAIT);
+ }
+ return res;
}
HRESULT WINAPI PrimaryStretchBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect)
@@ -3270,8 +3289,14 @@ HRESULT WINAPI PrimaryStretchBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, L
}
else {
// fast-blit to primary
- res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT);
- if(res) OutTraceE("PrimaryStretchBlt: Blt ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
+ if(dxw.dwFlags3 & FORCECLIPPER){
+ res= (*pBlt)(lpdds, lpdestrect, lpddsTmp, &TmpRect, DDBLT_WAIT, 0);
+ if(res) OutTraceE("PrimaryStretchBlt: Blt ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
+ }
+ else{
+ res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT);
+ if(res) OutTraceE("PrimaryStretchBlt: BltFast ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
+ }
}
(*pReleaseS)(lpddsTmp);
return res;
@@ -3423,8 +3448,14 @@ HRESULT WINAPI PrimaryBilinearBlt(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
// fast-blit to primary
(*pUnlockMethod(lpddssrc))(lpddssrc, NULL);
(*pUnlockMethod(lpddsTmp))(lpddsTmp, NULL);
- res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT);
- if(res) OutTraceE("PrimaryBilinearBlt: BltFast ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
+ if(dxw.dwFlags3 & FORCECLIPPER) {
+ res= (*pBlt)(lpdds, lpdestrect, lpddsTmp, &TmpRect, DDBLT_WAIT, 0);
+ if(res) OutTraceE("PrimaryBilinearBlt: Blt ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
+ }
+ else {
+ res= (*pBltFast)(lpdds, lpdestrect->left, lpdestrect->top, lpddsTmp, &TmpRect, DDBLTFAST_WAIT);
+ if(res) OutTraceE("PrimaryBilinearBlt: BltFast ERROR %x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
+ }
(*pReleaseS)(lpddsTmp);
if(lpddsCopy) (*pReleaseS)(lpddsCopy);
return res;
@@ -3850,16 +3881,30 @@ HRESULT WINAPI extSetClipper(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWCLIPPER lpdd
if(dxw.dwFlags1 & SUPPRESSCLIPPING) return 0;
if(dxw.dwFlags1 & (EMULATESURFACE|EMULATEBUFFER)){
- if ((isPrim && lpDDSEmu_Prim) ||
- (dxwss.IsABackBufferSurface(lpdds) && lpDDSEmu_Back)){
- OutTraceDW("SetClipper: skip primary/backbuffer lpdds=%x\n", lpdds);
- res=0;
+ if (dxw.dwFlags3 & FORCECLIPPER){
+ // v2.03.48: FORCECLIPPER ensures that a valid clipper is issued on the real primary surface
+ // and on the main game window. Then, you won't be able to BltFast any longer....
+ if ((isPrim || dxwss.IsABackBufferSurface(lpdds)) && lpDDSEmu_Prim){
+ OutTraceDW("SetClipper: redirect surface to primary hwnd=%x lpdds=%x%s->%x\n",
+ dxw.GethWnd(), lpdds, isPrim?"(PRIM)":"", lpDDSEmu_Prim);
+ res=(*pSetHWnd)(lpddc, 0, dxw.GethWnd());
+ //res=lpddc->SetHWnd(0, dxw.GethWnd());
+ if (res) OutTraceE("SetClipper: SetHWnd ERROR res=%x(%s)\n", res, ExplainDDError(res));
+ res=(*pSetClipper)(lpDDSEmu_Prim, lpddc);
+ if (res) OutTraceE("SetClipper: ERROR res=%x(%s)\n", res, ExplainDDError(res));
+ return res;
+ }
+ }
+ else {
+ if ((isPrim && lpDDSEmu_Prim) ||
+ (dxwss.IsABackBufferSurface(lpdds) && lpDDSEmu_Back)){
+ OutTraceDW("SetClipper: skip primary/backbuffer lpdds=%x\n", lpdds);
+ return 0;
+ }
}
- else
- res=(*pSetClipper)(lpdds, lpddc);
}
- else
- res=(*pSetClipper)(lpdds, lpddc);
+
+ res=(*pSetClipper)(lpdds, lpddc);
if (res)
OutTraceE("SetClipper: ERROR res=%x(%s)\n", res, ExplainDDError(res));
diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp
index 4a90362..dd565e2 100644
--- a/dll/dxhook.cpp
+++ b/dll/dxhook.cpp
@@ -55,7 +55,7 @@ CRITICAL_SECTION TraceCS;
static char *FlagNames[32]={
"UNNOTIFY", "EMULATESURFACE", "CLIPCURSOR", "RESETPRIMARY",
"HOOKDI", "MODIFYMOUSE", "HANDLEEXCEPTIONS", "SAVELOAD",
- "EMULATEBUFFER", "--AUTOMATIC--", "BLITFROMBACKBUFFER", "SUPPRESSCLIPPING",
+ "EMULATEBUFFER", "HOOKDI8", "BLITFROMBACKBUFFER", "SUPPRESSCLIPPING",
"AUTOREFRESH", "FIXWINFRAME", "HIDEHWCURSOR", "SLOWDOWN",
"ENABLECLIPPING", "LOCKWINSTYLE", "MAPGDITOPRIMARY", "FIXTEXTOUT",
"KEEPCURSORWITHIN", "USERGB565", "SUPPRESSDXERRORS", "PREVENTMAXIMIZE",
@@ -866,7 +866,7 @@ void HookModule(HMODULE base, int dxversion)
HookMSV4WLibs(base); // -- used by Aliens & Amazons demo: what for?
HookAVIFil32(base);
//HookSmackW32(base);
- //if (HOOKDIRECTSOUND) HookDirectSound(base);
+ //if (HOOKDIRECTSOUND) HookDirectSound(base);
//HookComDlg32(base);
}
diff --git a/dll/dxwcore.cpp b/dll/dxwcore.cpp
index a98ff3d..483f90f 100644
--- a/dll/dxwcore.cpp
+++ b/dll/dxwcore.cpp
@@ -674,6 +674,17 @@ void dxwCore::MapClient(LPPOINT lppoint)
lppoint->y= ((lppoint->y * h)+(dwScreenHeight >> 1)) / (int)dwScreenHeight;
}
+//void dxwCore::MapClient(float *SX, float *SY)
+//{
+// RECT client;
+// int w, h;
+// if(!(*pGetClientRect)(hWnd, &client)) return;
+// w = client.right ? client.right : iSizX;
+// h = client.bottom ? client.bottom : iSizY;
+// *SX= (*SX * (float)w) / (float)dwScreenWidth;
+// *SY= (*SY * (float)h) / (float)dwScreenHeight;
+//}
+
void dxwCore::MapClient(int *nXDest, int *nYDest)
{
RECT client;
diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp
index 8fe2003..f576e69 100644
--- a/dll/dxwcore.hpp
+++ b/dll/dxwcore.hpp
@@ -69,6 +69,7 @@ public: // methods
void MapClient(LPRECT);
void MapClient(int *, int *, int *, int *);
void MapClient(int *, int *);
+ //void MapClient(float *, float *);
void UnmapClient(LPPOINT);
void UnmapClient(int *, int *);
void UnmapClient(LPRECT);
diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp
index ed97561..e2fb9d6 100644
--- a/dll/dxwnd.cpp
+++ b/dll/dxwnd.cpp
@@ -27,7 +27,7 @@ along with this program. If not, see .
#include "TlHelp32.h"
-#define VERSION "2.03.47"
+#define VERSION "2.03.48"
#define DDTHREADLOCK 1
//#define LOCKTHREADS
diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo
index 10a43ca..98895f4 100644
Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ
diff --git a/dll/dxwnd.vs2008.vcproj b/dll/dxwnd.vs2008.vcproj
index 1549714..48d5ea3 100644
--- a/dll/dxwnd.vs2008.vcproj
+++ b/dll/dxwnd.vs2008.vcproj
@@ -503,7 +503,7 @@
>
-
-
diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp
index d5cea72..476052a 100644
--- a/dll/hd3d7.cpp
+++ b/dll/hd3d7.cpp
@@ -860,6 +860,12 @@ HRESULT WINAPI extSetViewport(void *lpvp, LPD3DVIEWPORT vpd)
OutTraceD3D("SetViewport: viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d) scale=(%fx%f) maxXYZ=(%f,%f,%f) minZ=%f\n",
lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight, vpd->dvScaleX, vpd->dvScaleY,
vpd->dvMaxX, vpd->dvMaxY, vpd->dvMaxZ, vpd->dvMinZ);
+
+ // v2.03.48: scaled dvScaleX/Y fields. Fixes "Dark Vengeance" viewport size when using D3D interface.
+ // no.... see Forsaken
+ //dxw.MapClient(&vpd->dvScaleX, &vpd->dvScaleY);
+ //OutTraceDW("SetViewport: FIXED scale=(%fx%f)\n", vpd->dvScaleX, vpd->dvScaleY);
+
res=(*pSetViewport)(lpvp, vpd);
if(res) OutTraceE("SetViewport ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
else OutTraceD3D("SetViewport: OK\n");
@@ -872,6 +878,7 @@ HRESULT WINAPI extGetViewport(void *lpvp, LPD3DVIEWPORT vpd)
OutTraceD3D("GetViewport: viewport=%x viewportd=%x\n", lpvp, vpd);
res=(*pGetViewport)(lpvp, vpd);
+ // v2.03.48: should the dvScaleX/Y fields be unscaled?
if(res) OutTraceE("GetViewport ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
else OutTraceD3D("GetViewport: OK size=%d pos=(%d,%d) dim=(%dx%d) scale=(%fx%f) maxXYZ=(%f,%f,%f) minZ=%f\n",
vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight, vpd->dvScaleX, vpd->dvScaleY,
diff --git a/host/TabDirectX.cpp b/host/TabDirectX.cpp
index b859a5c..63781ac 100644
--- a/host/TabDirectX.cpp
+++ b/host/TabDirectX.cpp
@@ -30,6 +30,7 @@ void CTabDirectX::DoDataExchange(CDataExchange* pDX)
DDX_Radio(pDX, IDC_NOEMULATESURFACE, cTarget->m_DxEmulationMode);
DDX_Radio(pDX, IDC_DDRAWFILTER, cTarget->m_DxFilterMode);
DDX_Check(pDX, IDC_SUPPRESSCLIPPING, cTarget->m_SuppressClipping);
+ DDX_Check(pDX, IDC_FORCECLIPPER, cTarget->m_ForceClipper);
DDX_Check(pDX, IDC_BLITFROMBACKBUFFER, cTarget->m_BlitFromBackBuffer);
DDX_Check(pDX, IDC_AUTOREFRESH, cTarget->m_AutoRefresh);
DDX_Check(pDX, IDC_TEXTUREFORMAT, cTarget->m_TextureFormat);
diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp
index e0f2a19..c0d6bd4 100644
--- a/host/TargetDlg.cpp
+++ b/host/TargetDlg.cpp
@@ -93,6 +93,8 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_FreezeInjectedSon = FALSE;
m_StressResources = FALSE;
m_DisableFogging = FALSE;
+ m_Power2Width = FALSE;
+ m_FixPitch = FALSE,
m_NoPower2Fix = FALSE;
m_NoPerfCounter = FALSE;
m_UnNotify = FALSE;
@@ -120,6 +122,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_BlitFromBackBuffer = FALSE;
m_NoFlipEmulation = FALSE;
m_SuppressClipping = FALSE;
+ m_ForceClipper = FALSE;
m_DisableGammaRamp = FALSE;
m_AutoRefresh = FALSE;
m_TextureFormat = FALSE;
@@ -128,7 +131,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/)
m_CursorClipping = FALSE;
m_VideoToSystemMem = FALSE;
m_FixTextOut = FALSE;
- m_SharedDC = TRUE; // seems better .....
+ m_SharedDC = FALSE;
m_HookGlide = FALSE;
m_RemapMCI = TRUE;
m_NoMovies = FALSE;
diff --git a/host/TargetDlg.h b/host/TargetDlg.h
index fffb53f..b6f6983 100644
--- a/host/TargetDlg.h
+++ b/host/TargetDlg.h
@@ -84,6 +84,7 @@ public:
BOOL m_BlitFromBackBuffer;
BOOL m_NoFlipEmulation;
BOOL m_SuppressClipping;
+ BOOL m_ForceClipper;
BOOL m_DisableGammaRamp;
BOOL m_AutoRefresh;
BOOL m_TextureFormat;
diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps
index 629abd5..4fbf6db 100644
Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ
diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc
index 9979cdb..b960bf7 100644
Binary files a/host/dxwndhost.rc and b/host/dxwndhost.rc differ
diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo
index bb42508..c077dc7 100644
Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ
diff --git a/host/dxwndhost.vs2008.vcproj.User-PC.User.user b/host/dxwndhost.vs2008.vcproj.User-PC.User.user
new file mode 100644
index 0000000..b907e0c
--- /dev/null
+++ b/host/dxwndhost.vs2008.vcproj.User-PC.User.user
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp
index 2983e35..906054b 100644
--- a/host/dxwndhostView.cpp
+++ b/host/dxwndhostView.cpp
@@ -321,6 +321,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg)
if(dlg->m_BlitFromBackBuffer) t->flags |= BLITFROMBACKBUFFER;
if(dlg->m_NoFlipEmulation) t->flags4 |= NOFLIPEMULATION;
if(dlg->m_SuppressClipping) t->flags |= SUPPRESSCLIPPING;
+ if(dlg->m_ForceClipper) t->flags3 |= FORCECLIPPER;
if(dlg->m_DisableGammaRamp) t->flags2 |= DISABLEGAMMARAMP;
if(dlg->m_AutoRefresh) t->flags |= AUTOREFRESH;
if(dlg->m_TextureFormat) t->flags5 |= TEXTUREFORMAT;
@@ -567,6 +568,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg)
dlg->m_BlitFromBackBuffer = t->flags & BLITFROMBACKBUFFER ? 1 : 0;
dlg->m_NoFlipEmulation = t->flags4 & NOFLIPEMULATION ? 1 : 0;
dlg->m_SuppressClipping = t->flags & SUPPRESSCLIPPING ? 1 : 0;
+ dlg->m_ForceClipper = t->flags3 & FORCECLIPPER ? 1 : 0;
dlg->m_DisableGammaRamp = t->flags2 & DISABLEGAMMARAMP ? 1 : 0;
dlg->m_AutoRefresh = t->flags & AUTOREFRESH ? 1 : 0;
dlg->m_TextureFormat = t->flags5 & TEXTUREFORMAT ? 1 : 0;
diff --git a/host/resource b/host/resource
index e023a09..1e6ee56 100644
Binary files a/host/resource and b/host/resource differ