#include "pch.hpp"
//===========================================================================//
// File:	 Globals.cpp													 //
// Project:  GameOS					                                         //
// Contents: global variables												 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 11/04/97  SCP    Created													 //
// 01/07/98  JTR    Major expansion. Moved all globals here.				 //
//---------------------------------------------------------------------------//
// Copyright (C) 1999 Microsoft Corp.						                 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//
#include "Globals.HPP"
#include "ControlManager.hpp"
#include "LocalizationManager.hpp"
#include "LinkedList.hpp"
#include "DXRasterizer.hpp"
#include "3DRasterizer.hpp"
#include "Sound Renderer.hpp"
#include "ErrorHandler.hpp"
#include "Texture Manager.hpp"
#include "Debugger.hpp"
#include "Windows.hpp"

//
// Processor information
//
int HasCPUID;			// 1 when at least a Pentium is being used.
int HasMMX;				// 1 when MMX instructions are present
int HasRDTSC;			// 1 when RDTSC instruction is present
int HasKatmai;			// 1 when Katmai instructions available
int Has3DNow;			// 1 when 3DNox instructions available
extern int HasTLHAL;	// 1 when Hardware T&L being used
extern DWORD gCaptureScreen;
extern int HasBumpEnvMap;

BYTE CPUID0[17];		// CPUID 0 information (+ terminating 0)
BYTE CPUID1[16];		// CPUID 1 information
BYTE CPUID2[16];		// CPUID 2 information

long StartSeed;

int LoseFocusBehavior=0;	// What to do when focus lost.

DWORD gHardwareMouse;	// 0=Disable hardware mouse
DWORD SkipRendering=0;	// 1=Skip rendering
DWORD MouseInWindow;	// 1=Mouse over window in a window mode
DWORD DisableUVAssert=0;
DWORD GameNoVsync=0;	// Ignore VSYNC

void UpdateCursor();

//
// These variable are used to control the behavior of SCROLL, CAPS, and NUMLOCK
//
extern void SetExtended( BYTE vk, BOOL bState );
extern DWORD gNumLockMode;
extern DWORD gCapLockMode;
extern DWORD gScrollLockMode;

extern DWORD WaitUntilTime;
extern DWORD GetIMEInfo();
extern DWORD GetIMECaretStatus();
//
// Seed the random number generator
//
void __stdcall gos_srand( unsigned int seed )
{
	StartSeed=seed;
}

//
// Return a random number between 0 and 32767
//
int __stdcall gos_rand()
{
	return(((StartSeed = StartSeed * 214013L + 2531011L) >> 16) & 0x7fff);
}






//
// Enable a GameOS setting
//
DWORD __stdcall gos_EnableSetting( gosSetting Setting, DWORD Value )
{
	switch( Setting )
	{
//
// 0=Disable cursor (default), 1=Enable cursor (Hardware if possible)
//
		case gos_Set_MouseCursor:
		{
			DWORD OldgHardwareMouse=gHardwareMouse;
			if( Value!=gHardwareMouse )
			{
				gHardwareMouse=Value;
				UpdateCursor();
			}
			return OldgHardwareMouse;
		}
//
// When this is set to 1 there will be no rendering for the current frame. Can be used to skip frames when behind.
//
		case gos_Set_SkipRender:
		{
			DWORD OldValue=SkipRendering;
			SkipRendering=Value;
			return OldValue;
		}
//
// Value is the number of Milliseconds between the last GameLogic and the next. GameOS will 'spin' until this time is met.
//
// Can be used to 'cap' frame rate ie: 33 would cap frame rate at 30Hz
//
		case gos_Set_NextGameLogicTime:
		{
			gosASSERT( 0==WaitUntilTime || Value>1000 );			// Max 1 second to stop app becoming unresponsive
			WaitUntilTime=Value;
			return 0;
		}
//
// Value is a (char*) pointing to an address ie: "http:\\microsoft.com"
//
		case gos_Set_TriggerBrowser:
		{
			if( Environment.fullScreen )
				EnterWindowMode();
			char* Name=(char*)Value;
			char Buffer[MAX_PATH];
			while( *Name )
			{
				if( *Name=='"' )
				{
					do
					{
						Name++;
					} while( *Name!='"' && *(Name+1)!=0 );
				}

				if( *Name==' ' )
					break;

				Name++;
			}
			memcpy( Buffer, (char*)Value, (DWORD)Name-Value );
			Buffer[(DWORD)Name-Value]=0;
			while( *Name==' ' )
				Name++;
			ShellExecute( hWindow, TEXT("open"), Buffer, Name, NULL, SW_SHOWNORMAL );
       		return 1;
		}
//
// 0=Slow to 10Hz (default), 1=Pause game, 2=Run at full speed
//
		case gos_Set_LoseFocusBehavior:
		{
			gosASSERT( Value<4 );
			DWORD oldvalue=LoseFocusBehavior;
			LoseFocusBehavior=Value;
			return oldvalue;
		}
//
// Disable the maximum U,V message assert. This is for apps in development that have u,v's larger than the card can handle
//
		case gos_Set_IgnoreMaxUV:
		{
			DisableUVAssert=Value;
			return 1;
		}
//
// Use BLT not FLIP in full screen modes
//
		case gos_Set_IgnoreVSYNC:
		{
			GameNoVsync=Value;
			return 1;
		}
//
// Trigger a screen capture to occur
//
		case gos_Set_CaptureScreen:
		{
			gCaptureScreen=1;
			gScreenBMP=Value;
			return 1;
		}
//
// Set how NUMLOCK behaves
//
		case gos_Set_NumLockMode:
		{
			gosASSERT(Value >=0 && Value <= 2);
			gNumLockMode = Value;
			if (gNumLockMode !=2)
				SetExtended(VK_NUMLOCK, gNumLockMode);

			return 1;
		}
//
// Set how CAPS LOCK behaves
//
		case gos_Set_CapsLockMode:
		{
			gosASSERT(Value >=0 && Value <= 2);
			gCapLockMode = Value;
			if (gCapLockMode !=2)
				SetExtended(VK_CAPITAL, gCapLockMode);

			return 1;
		}
//
// Set how SCROLL LOCK behaves
//
		case gos_Set_ScrollLockMode:
		{
			gosASSERT(Value >=0 && Value <= 2);
			gScrollLockMode = Value;
			if (gScrollLockMode !=2)
				SetExtended(VK_SCROLL, gScrollLockMode);

			return 1;
		}
//
// Force application to minimize or maximize
//
		case gos_Set_MinMaxApp:
		{
			if( Value==0 )
				ShowWindow( hWindow, SW_MINIMIZE );
			else
				if( IsIconic(hWindow) )
					ShowWindow( hWindow, SW_RESTORE );
			return 1;
		}
//
//
//
		default:
			STOP(( "Unknown Value" ));
	}
	return 0;
}




//
//
// Returns machine information, valid for THE CURRENT FRAME ONLY
//
//
DWORD __stdcall gos_GetMachineInformation( MachineInfo mi, int Param1, int Param2, int Param3 )
{
	switch( mi )
	{
		case gos_Info_HasAGPAvailable:
			return HasAGP;
		case gos_Info_HasGuardBandClipping:
			return HasGuardBandClipping;
		case gos_Info_TextureOffset:
			return (Compatibility3D&TextureOffset) ? 1 : 0;
		case gos_Info_TextureSize:
			if( RenderStates[gos_State_Texture] )
				return TEXHANDLE_TO_PTR(RenderStates[gos_State_Texture])->Width();
			else
				return 1;
		case gos_Info_GetOSInfo:
		{
			static char Buffer[128];
			OSVERSIONINFO osinfo;
			osinfo.dwOSVersionInfoSize=sizeof(osinfo);
			GetVersionEx( &osinfo );

			if( osinfo.dwPlatformId==VER_PLATFORM_WIN32_NT )
			{
				char *OSString="Windows";
				if( osinfo.dwMajorVersion<5 )
					OSString="Windows NT";
				else if( osinfo.dwMajorVersion==5 )
				{
					if( osinfo.dwBuildNumber==2600 )
						OSString="Windows XP";
					else
					OSString="Windows 2000";
				}
				
				char *Build="";
				if( osinfo.dwBuildNumber==2031 )
					Build="RC0";
				else if( osinfo.dwBuildNumber==2072 )
					Build="RC1";
				else if( osinfo.dwBuildNumber==2128 )
					Build="RC2";
				else if( osinfo.dwBuildNumber==2183 )
					Build="RC3";
				else if( osinfo.dwBuildNumber==2195 )
					Build="RTM";
				
				sprintf( Buffer,"%s (%d.%d.%d) %s %s",OSString,osinfo.dwMajorVersion,osinfo.dwMinorVersion,osinfo.dwBuildNumber,Build,osinfo.szCSDVersion );
				return (DWORD)&Buffer;
			}
			else
			{
				char* OSString=(osinfo.dwMinorVersion ? "98" : "95");
				char *Build="";
				if( (osinfo.dwBuildNumber&0xffff)==3000 )
				{
					OSString="Me";
					Build="";
				}
				else
				{
					if( (osinfo.dwBuildNumber&0xffff)==950 || (osinfo.dwBuildNumber&0xffff)==1998 )
						Build=" GOLD";
					else if( (osinfo.dwBuildNumber&0xffff)==2222 )
						Build=" SE";
					else if( (osinfo.dwBuildNumber&0xffff)==1111 )
						Build=" OSR 2";
					else if( (osinfo.dwBuildNumber&0xffff)==1212 )
						Build=" OSR 2.1";
					else if( (osinfo.dwBuildNumber&0xffff)==1214 )
						Build=" OSR 2.5";
				}
				sprintf( Buffer,"Windows %s%s (%d.%d.%d)", OSString, Build, osinfo.dwMajorVersion,osinfo.dwMinorVersion,osinfo.dwBuildNumber&0xffff );
				return (DWORD)&Buffer;
			}
		}
		case gos_Info_GetMemorySize:
		{
			MEMORYSTATUS ms;
			GlobalMemoryStatus( &ms );
			return ms.dwTotalPhys;
		}
		case gos_Info_GetVirtualMemorySize:
		{
			MEMORYSTATUS ms;
			GlobalMemoryStatus( &ms );
			return ms.dwTotalVirtual;
 		}
//
// Returns a user readable string that shows the processor (ie: Intel Pentium III)
//
		case gos_Info_GetProcessorInfo:
			return (DWORD)GetProcessor();
//
// Returns the number of processors in the system
//
		case gos_Info_GetNumberProcessors:
		{
			SYSTEM_INFO Si;
			GetSystemInfo(&Si);
			return Si.dwNumberOfProcessors;
		}
//
// Return the speed in MHz - ie: 400
//
		case gos_Info_GetProcessorSpeed:
			return (DWORD)ProcessorSpeed;
//
// Number of devices GameOS can render to (always at least 1)
//
		case gos_Info_NumberDevices:
			return NumDevices;
//
// Returns the name of the device specified in Param1 (Riva TNT, Voodoo 1 etc...)
//
		case gos_Info_GetDeviceName:
			if( Param1>=NumDevices )
				return (DWORD)&"Blade";
			return (DWORD)DeviceArray[Param1].DDid.szDescription;
//
// Returns the vendor of the device specified in Param1 (0x121a=3Dfx for example - See Videocard.cpp for complete list)
//
		case gos_Info_GetDeviceVendorID:
			if( Param1>=NumDevices )
				return (DWORD)0;
			return (DWORD)DeviceArray[Param1].DDid.dwVendorId;
//
// Returns the DeviceID of the device specified in Param1 (2=Voodoo2 for example - See Videocard.cpp for complete list)
//
		case gos_Info_GetDeviceDeviceID:
			if( Param1>=NumDevices )
				return (DWORD)0;
			return (DWORD)DeviceArray[Param1].DDid.dwDeviceId;
//
// Returns the amount of video memory available (for front/back/z buffers etc..) for device specified in Param1
//
		case gos_Info_GetDeviceVideoMemory:
			if( Param1>=NumDevices )
				return 0;
			return (DWORD)DeviceArray[Param1].TotalVid;
//
// Returns the amount of local video memory available (may be the same as above) for device specified in Param1
//
		case gos_Info_GetDeviceLocalMemory:
			if( Param1>=NumDevices )
				return 0;
			return (DWORD)DeviceArray[Param1].TotalLocalTex;
//
// Returns the amount of AGP video memory available (may be 0 on non-agp cards) for device specified in Param1
//
		case gos_Info_GetDeviceAGPMemory:
			if( Param1>=NumDevices )
				return 0;
			return (DWORD)DeviceArray[Param1].TotalTex;
//
// Number of milliseconds between mouse clicks
//
		case gos_Info_GetDoubleClickTime:
			return (DWORD)GetDoubleClickTime();
//
// Returns true if device Param1 can support mode Param2, Param3
//
		case gos_Info_ValidMode:
		{
			if( NumDevices==0 )
			{
				if( Param2==800 && Param3==600 )
					return 1;
			}
			if( Param1>=NumDevices )
				return 0;
			for( int t0=0; t0<16; t0++ )
			{
				if( DeviceArray[Param1].Modes16[t0*2]==Param2 && DeviceArray[Param1].Modes16[t0*2+1]==Param3 )
					return 1;
			}
			return 0;
		}
//
// Returns true if the device specified in Param1 can render antialiased
//
		case gos_Info_CanDeviceAntiAlias:
			if( Param1>=NumDevices )
				return 0;
			return (DeviceArray[Param1].D3DCaps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT) ? 1 : 0;
//
// Returns true if the device specified in Param1 can render in 32 bit mode
//
		case gos_Info_CanDeviceRender32Bit:
			if( Param1>=NumDevices )
				return 0;
			return DeviceArray[Param1].Modes32[0]!=0 && (DeviceArray[Param1].D3DCaps.dwDeviceRenderBitDepth&DDBD_32);
//
// Returns true if the gamma of the display will be adjusted using HARDWARE or SOFTWARE (software is much slower)
//
		case gos_Info_CanDeviceHardwareGamma:
			return Environment.fullScreen && GammaControlInterface;
//
// Returns true if the device specified in Param1 can render with a stencil buffer
//
		case gos_Info_CanDeviceRenderStencil:
		{
			if( Param1>=NumDevices )
				return 0;
			for( int t0=0; t0<16; t0++ )
			{
				if( DeviceArray[Param1].ZFormats[t0].dwSize )								// Valid Z format?
				{
					if( DeviceArray[Param1].ZFormats[t0].dwFlags&DDPF_STENCILBUFFER )		// Can do stencil?
					{
						if( DeviceArray[Param1].ZFormats[t0].dwZBufferBitDepth==32 &&
							DeviceArray[Param1].ZFormats[t0].dwStencilBitDepth==8 &&
							DeviceArray[Param1].ZFormats[t0].dwZBitMask==0xffffff00 &&		// Correct format
							DeviceArray[Param1].ZFormats[t0].dwStencilBitMask==0xff )							
						{
							if( -1!=DeviceArray[Param1].CurrentCard && (KnownCards[ DeviceArray[Param1].CurrentCard ].CompatibilityFlags & RenderEqualZ) )
								return 2;
							else
								return 1;
						}
					}
				}
			}
			return false;
		}
//
// (DWORD)	 TRUE when the card can support Alpha testing (GameOS will enable AlphaInvAlpha blending)
//
		case gos_Info_CanAlphaTest:
			return HasAlphaTest;
//
// (DWORD)	TRUE when the card can support Alpha ONE:ONE blending
//
		case gos_Info_CanAlphaOneOne:
			return HasAlphaModes;
//
// (DWORD)	 TRUE when texture address mode CLAMP is available (GameOS will default to wrap)
//
		case gos_Info_CanClampTextures:
			return HasClamp;
//
// (DWORD)	 TRUE when ModulateAlpha is a supported mode (GameOS will default to Modulate)
//
		case gos_Info_CanModulateAlpha:
			return HasModulateAlpha;
//
// (DWORD)	 TRUE when specular is supported (GameOS will ignore all specular otherwise)
//
		case gos_Info_CanSpecular:
			return HasSpecular;
//
// Multitexture modes
//
		case gos_Info_CanMultitextureLightMap:
		{
			return (gEnableMulti && HasMultitextureLightmap) ? 1 : 0;
		}
		case gos_Info_CanMultitextureSpecularMap:
		{
			return (gEnableMulti && HasMultitextureSpecularmap) ? 1 : 0;
		}
		case gos_Info_CanMultitextureDetail:
		{
			return (gEnableMulti && HasMultitextureDetailTexture) ? 1 : 0;
		}
		case gos_Info_GetMaximumUVSize:
		{
			DWORD MaxUV=CapsDirect3D.dwMaxTextureRepeat;
			if( MaxUV && Param1 )
			{
				if( 0==(CapsDirect3D.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE) )
				{
					MaxUV/=Param1;
				}
				return MaxUV;
			}
			return MaxUV;
		}
//
// How far outside window is mouse (0=inside window)
//
		case gos_Info_IsMouseInSideWindow:
		{
			if( Environment.fullScreen )
				return 0;
			else
				return MouseInWindow;
		}
//
// Return pixel color at given screen location
//
		case gos_Info_GetPixelColor:
		{
			gosASSERT( !InsideBeginScene );				// Only valid in game logic or before SetupViewPort

			if( Param1 >= Environment.screenWidth )
				Param1=Environment.screenWidth-1;
			if( Param2 >= Environment.screenHeight )	// Clamp coords (display may have changed modes / resolution since last frame)
				Param2=Environment.screenHeight-1;

			IDirectDrawSurface7* Surface=BackBufferSurface;
			if( Param3 && CopyTarget )
				Surface=CopyTarget;
						
			static DWORD Pixel;
	
			DDSURFACEDESC2 ddsd;
			ddsd.dwSize = sizeof(ddsd);
			AllowFail=1;
			HRESULT hr=wLock( Surface, NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT | DDLOCK_READONLY, NULL );
			AllowFail=1;
				
			if( SUCCEEDED(hr) )
			{
				if( 32==ddsd.ddpfPixelFormat.dwRGBBitCount )
				{
					Pixel=(*((DWORD*)ddsd.lpSurface+Param1+(Param2*ddsd.lPitch>>2))) &0xffffff;
				}
				else
				{
					Pixel=GetBackBufferColor(*((WORD*)ddsd.lpSurface+Param1+(Param2*ddsd.lPitch>>1)));				
				}
				wUnlock( Surface, NULL );
			}

			return Pixel;
		}
//
// Return true if running with hardware T&L
//
		case gos_Info_CanHardwareTandL:
		{
			return HasTLHAL ? 1 : 0;
		}
//
// Return maximum number of active lights in current mode
//
		case gos_Info_GetMaximumActiveLights:
		{
			return CapsDirect3D.dwMaxActiveLights ;
		}
//
// Return maximum number of vertex blend matrices possible in current mode
//
		case gos_Info_GetVertexBlendMatrices:
		{
			return HasVertexBlending;
		}
//
// Returns the number of valid modes for device Param1, bitdepth Param2 (16 or 32 only)
//
		case gos_Info_NumberValidModes:
		{
			if( Param1>=NumDevices )
				return 0;
			gosASSERT( Param2==16 || Param2==32 );
			DWORD Modes=0;
			for( int t0=0; t0<16; t0++ )
			{
				if( Param2==16 )
				{
					if( DeviceArray[Param1].Modes16[t0*2]!=0 )
						Modes++;
				}
				else
				{
					if( DeviceArray[Param1].Modes32[t0*2]!=0 )
						Modes++;
				}
			}
			return Modes;
		}
//
// Returns a DWORD containing HIWORD=Width, LOWORD=Height of device 'Param1' for bitdepth 'Param2', mode number Param3
//
		case gos_Info_GetValidMode:
		{
			if( Param1>=NumDevices )
				return 0;
			gosASSERT( Param2==16 || Param2==32 );
			if( Param2==16 )
			{
				return (DeviceArray[Param1].Modes16[Param3*2]<<16) + (DeviceArray[Param1].Modes16[Param3*2+1]);
			}
			else
			{
				return (DeviceArray[Param1].Modes32[Param3*2]<<16) + (DeviceArray[Param1].Modes32[Param3*2+1]);
			}
		}
//
// Returns a DWORD, Bit 0 is true when the app is active, Bit 1 is true when the app has keyboard focus
//
		case gos_Info_GetApplicationStatus:
		{
			DWORD result=(gActive ? 1 : 0) + (gGotFocus ? 2 : 0);
			
			if( WindowsNT && CurrentDDobject && Environment.fullScreen && !gActive )
			{
				result|=4;			
			}

			if( 1==LogMode )	// Log file playing back?
			{
				if( !InDebugger )
					result=ReadBitStream(2,Log_NetInfo);
			}
			else				// Log file recording
			{
				if( !InDebugger )
					WriteBitStream((DWORD)result,2,Log_NetInfo);
			}
			return result;
		}
//
// Get the resolution of the desktop (high word is vertical, low word is horizontal)
//
		case gos_Info_GetDesktopResolution:
		{
			return DesktopRes;
		}
//
// Get the bitdepth of the desktop
//
		case gos_Info_GetDesktopBitDepth:
		{
			return DesktopBpp;
		}
//
// Get the status of the IME
//
		case gos_Info_GetIMEStatus:
		{
			DWORD result=GetIMEInfo();
			if( 1==LogMode )	// Log file playing back?
			{
				if( !InDebugger )
					result=ReadBitStream(1,Log_NetInfo);
			}
			else				// Log file recording
			{
				if( !InDebugger )
					WriteBitStream((DWORD)result,1,Log_NetInfo);
			}
			return result;
		}
//
// Get the current keyboard layout from windows
//
		case gos_Info_GetKeyboardLayout:
		{
			return (DWORD)GetKeyboardLayout(0);
		}
//
// Get the maximum texture width
//
		case gos_Info_GetMaximumTextureWidth:
		{
			return CapsDirect3D.dwMaxTextureWidth;
		}
//
// Get the maximum texture height
//
		case gos_Info_GetMaximumTextureHeight:
		{
			return CapsDirect3D.dwMaxTextureHeight;
		}
//
// Check whether bump environment mapping is supported
//
		case gos_Info_CanBumpEnvMap:
		{
			return HasBumpEnvMap;
		}
//
// Check whether bump dot-3 mapping is supported
//
		case gos_Info_CanBumpDotMap:
		{
			return CapsDirect3D.dwTextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3;
		}
//
// (DWORD)	TRUE if full screen and hardware gamma control possible. Otherwise slower software gamma emulation is used
//
		case gos_Info_HardwareGammaControl:
		{
			return (Environment.fullScreen && GammaControlInterface);
		}
//
// (DWORD)	TRUE if full screen and hardware brightness control possible. Otherwise invalid
//
		case gos_Info_HardwareBrightnessControl:
		{
			return (Environment.fullScreen && AllowBrightness);
		}
//
// (DWORD)	TRUE if full screen and hardware brightness control possible. Otherwise invalid
//
		case gos_Info_HardwareContrastControl:
		{
			return (Environment.fullScreen && AllowContrast);
		}
//
// (DWORD)	TRUE when using a hardware renderer, 0=Blade. (Environment.renderer may have not been able to support hardware)
//
		case gos_Info_UsingHardwareRenderer:
		{
			return HardwareRenderer;
		}
//
// (DWORD)  TRUE if an edit box should show its caret. When it's FALSE, an edit box shouldn't display caret.
//
		case gos_Info_GetIMECaretStatus:
			return GetIMECaretStatus();

		default:
			STOP(( "Unknown Value" ));
	}
	return 0;
}




//
// Current settings of all variables passed between game and GameOS
//
gosEnvironment Environment;


// Font-related
typedef struct 
{
	DWORD x;
	DWORD y;
	DWORD z;
} POSITION;

// Surface-related
	DWORD g_DDstate = 0;
	bool g_DDneedsRestore = false, g_DDperformFlip = false;
	HWND g_DDhWnd = 0;

// MemoryManager-related
	bool g_MMInitialized = false;


DWORD TerminateGame = FALSE;
bool WindowClosed = FALSE;

ControlManagerDataStruct g_CMData;

// Video-Related
LinkedList<HGOSVIDEO> g_activeVideos;
// Music-Related
HGOSMUSIC g_activeMusicList;

// SOUND RENDERER RELATED
SoundRendererData SoundRenderer;
LinkedList<SoundResource *> * g_soundResources;
CRITICAL_SECTION g_soundCritSec = {0};
//
// Windows variables
//
bool gActive=0;
bool gGotFocus=0;





