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