//=========================================================================== // Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. // // Component: Win32Platform // // Description: Abstracts the differences for setting up and shutting down // the different platforms. // // History: + Stolen and cleaned up from Svxy -- Darwin Chau // //=========================================================================== //======================================== // System Includes //======================================== // Standard Lib #include #include // Pure 3D #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Pure 3D: Loader-specific #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Foundation Tech #include #include #include #include #include #include #include #include #include //This is so we can get the name of the file that's failing. #include <../src/radfile/common/requests.hpp> // sim - for InstallSimLoaders #include //======================================== // Project Includes //======================================== #include #include
#include
#include
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include
#define WIN32_SECTION "WIN32_SECTION" #define TIMER_LEAVE 1 //#define PRINT_WINMESSAGES //****************************************************************************** // // Global Data, Local Data, Local Classes // //****************************************************************************** // Static pointer to instance of singleton. Win32Platform* Win32Platform::spInstance = NULL; // Other static members. HINSTANCE Win32Platform::mhInstance = NULL; HWND Win32Platform::mhWnd = NULL; HANDLE Win32Platform::mhMutex = NULL; bool Win32Platform::mShowCursor = true; //The Adlib font. unsigned char gFont[] = #include // // Define the starting resolution. // static const Win32Platform::Resolution StartingResolution = Win32Platform::Res_800x600; static const int StartingBPP = 32; // This specifies the PDDI DLL to use. We are using directx8. #ifdef RAD_DEBUG static const char d3dLibraryName[] = "pddidx8d.dll"; #endif #ifdef RAD_TUNE static const char d3dLibraryName[] = "pddidx8t.dll"; #endif #ifdef RAD_RELEASE static const char d3dLibraryName[] = "pddidx8r.dll"; #endif // Name of the application. This is the string that appears in the Window's // title bar. static const char ApplicationName[] = "The Simpsons: Hit & Run"; // The window style static const DWORD WndStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; // The gamma of the desktop.. needed to reset it on alt-tabs. static WORD DesktopGammaRamp[ 3 ][ 256 ] = { 0 }; void LoadMemP3DFile( unsigned char* buffer, unsigned int size, tEntityStore* store ) { tFileMem* file = new tFileMem(buffer,size); file->AddRef(); file->SetFilename("memfile.p3d"); p3d::loadManager->GetP3DHandler()->Load( file, p3d::inventory ); file->Release(); } //****************************************************************************** // // Public Member Functions // //****************************************************************************** //============================================================================== // Win32Platform::CreateInstance //============================================================================== // // Description: Creates the Win32Platform. // // Parameters: win32 parameters. // // Return: Pointer to the Win32Platform. // // Constraints: This is a singleton so only one instance is allowed. // //============================================================================== Win32Platform* Win32Platform::CreateInstance( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { MEMTRACK_PUSH_GROUP( "Win32Platform" ); rAssert( spInstance == NULL ); spInstance = new(GMA_PERSISTENT) Win32Platform( hInstance, hPrevInstance, lpCmdLine, nCmdShow ); rAssert( spInstance ); MEMTRACK_POP_GROUP( "Win32Platform" ); return spInstance; } //============================================================================== // Win32Platform::GetInstance //============================================================================== // // Description: - Access point for the Win32Platform singleton. // // Parameters: None. // // Return: Pointer to the Win32Platform. // // Constraints: This is a singleton so only one instance is allowed. // //============================================================================== Win32Platform* Win32Platform::GetInstance() { rAssert( spInstance != NULL ); return spInstance; } //============================================================================== // Win32Platform::DestroyInstance //============================================================================== // // Description: Destroy the Win32Platform. // // Parameters: None. // // Return: None. // //============================================================================== void Win32Platform::DestroyInstance() { rAssert( spInstance != NULL ); delete( GMA_PERSISTENT, spInstance ); spInstance = NULL; } //============================================================================== // Win32Platform::InitializeWindow //============================================================================== // Description: Creates the window class and window instance for the application. // We must do this before initializing the platform. // // Parameters: hInstance - the handle to the instance. // // Return: true if successful and the program can run. // false if another simpsons window already exists and this // instance should terminate. // // Constraints: Must be initialized before the platform. // //============================================================================== bool Win32Platform::InitializeWindow( HINSTANCE hInstance ) { // check to see if another instance is running... mhMutex = CreateMutex(NULL, 0, ApplicationName); if (GetLastError() == ERROR_ALREADY_EXISTS) { // simpsons is already running, so lets find the window and give it focus HWND hwnd = FindWindow(ApplicationName, NULL); if (hwnd != NULL) { // if window is minimized, restore it WINDOWPLACEMENT wndpl; if (GetWindowPlacement(hwnd, &wndpl) != 0) { if ((wndpl.showCmd == SW_MINIMIZE) || (wndpl.showCmd == SW_SHOWMINIMIZED)) { ShowWindow(hwnd, SW_RESTORE); } } // activate the window SetForegroundWindow(hwnd); return false; } } mhInstance = hInstance; // Create and resigter an object that defines the window that we will // run our game in. WNDCLASS Wndclass; Wndclass.style = CS_HREDRAW | CS_VREDRAW; Wndclass.lpfnWndProc = WndProc; Wndclass.cbClsExtra = 0; Wndclass.cbWndExtra = 0; Wndclass.hInstance = mhInstance; Wndclass.hIcon = LoadIcon( mhInstance, "IDI_SIMPSONSICON" ); Wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); Wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); Wndclass.lpszMenuName= NULL; Wndclass.lpszClassName = ApplicationName; ::RegisterClass(&Wndclass); // Set up the window. int x, y; TranslateResolution( StartingResolution, x, y ); RECT clientRect; clientRect.left = 0; clientRect.top = 0; clientRect.right = x; clientRect.bottom = y; // for windowed mode, center the screen int nScreenWidth = GetSystemMetrics(SM_CXSCREEN); int nScreenHeight = GetSystemMetrics(SM_CYSCREEN); while (nScreenWidth > 1600 ) // probably multimonitor { nScreenWidth /= 2; } // centre the window clientRect.left = (nScreenWidth-x)/2; clientRect.top = (nScreenHeight-y)/2; clientRect.right += clientRect.left; clientRect.bottom += clientRect.top; AdjustWindowRect(&clientRect,WndStyle,FALSE); // Create the game's main window. mhWnd = ::CreateWindow(ApplicationName, ApplicationName, WndStyle, clientRect.left, clientRect.top, clientRect.right-clientRect.left, clientRect.bottom-clientRect.top, NULL, NULL, mhInstance, NULL); rAssert(mhWnd != NULL); ShowTheCursor( false ); return true; } //============================================================================== // Win32Platform::InitializeFoundation //============================================================================== // Description: FTech must be setup first so that all the memory services // are ready to go before we begin allocating anything. // // Parameters: None. // // Return: None. // // Constraints: The FTech systems must be initialized in a particular order. // Consult their documentation before changing. // //============================================================================== void Win32Platform::InitializeFoundation() { // // Initialize the memory heaps // obsolete now.. the heaps initialize memory. // //InitializeMemory(); // // Register an out-of-memory display handler in case something goes bad // while allocating the heaps // ::radMemorySetOutOfMemoryCallback( PrintOutOfMemoryMessage, NULL ); // // Initialize memory monitor by JamesCo. TM. // if( CommandLineOptions::Get( CLO_MEMORY_MONITOR ) ) { const int KB = 1024; ::radMemoryMonitorInitialize( 64 * KB, GMA_DEBUG ); } // Setup the memory heaps // HeapMgr()->PrepareHeapsStartup (); // Seed the heap stack // HeapMgr()->PushHeap (GMA_PERSISTENT); // // Initilalize the platform system // ::radPlatformInitialize( mhWnd, mhInstance, 0 ); // // Initialize the timer system // ::radTimeInitialize(); // // Initialize the debug communication system. // ::radDbgComTargetInitialize( WinSocket, radDbgComDefaultPort, // Default NULL, // Default GMA_DEBUG ); // // Initialize the Watcher. // ::radDbgWatchInitialize( "SRR2", 32 * 16384, // 2 * Default GMA_DEBUG ); // // Initialize the file system. // ::radFileInitialize( 50, // Default 32, // Default GMA_PERSISTENT ); ::radLoadInitialize(); //radLoad->SetSyncLoading( true ); ::radDriveMount( NULL, GMA_PERSISTENT); // // Initialize the new movie player // ::radMovieInitialize2( GMA_PERSISTENT ); HeapMgr()->PopHeap (GMA_PERSISTENT); } //============================================================================== // Win32Platform::InitializeMemory //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void Win32Platform::InitializeMemory() { // // Only do this once! // if( gMemorySystemInitialized == true ) { return; } gMemorySystemInitialized = true; // // Initialize the thread system. // ::radThreadInitialize(); // // Initialize the memory system. // ::radMemoryInitialize(); } //============================================================================== // Win32Platform::ShutdownMemory //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void Win32Platform::ShutdownMemory() { if( gMemorySystemInitialized ) { gMemorySystemInitialized = false; // No shutdown the memory. This leads to bad errors when destroying // static variables sprinkled here and there. //::radMemoryTerminate(); ::radThreadTerminate(); } } //============================================================================== // Win32Platform::InitializePlatform //============================================================================== // Description: Get the Win32 ready to go. // // Parameters: None. // // Return: None. // //============================================================================== void Win32Platform::InitializePlatform() { HeapMgr()->PushHeap (GMA_PERSISTENT); // // Rendering is good. // InitializePure3D(); // // Add anything here that needs to be before the drive is opened. // DisplaySplashScreen( Error ); // blank screen // // Show the window on the screen. Must be done before initializing the input manager. // ShowWindow( mhWnd, mFullscreen ? SW_SHOWMAXIMIZED : SW_SHOW ); // // Opening the drive is SLOW... // InitializeFoundationDrive(); // // Initialize the controller. // GetInputManager()->Init(); // // Register with the game config manager // GetGameConfigManager()->RegisterConfig( this ); HeapMgr()->PopHeap (GMA_PERSISTENT); } //============================================================================== // Win32Platform::ShutdownPlatform //============================================================================== // Description: Shut down the PS2. // // Parameters: None. // // Return: None. // //============================================================================== void Win32Platform::ShutdownPlatform() { ShutdownPure3D(); ShutdownFoundation(); } //============================================================================= // Win32Platform::LaunchDashboard //============================================================================= // Description: We use this a the emergency exit from the game if we arent in a context that suppose the transition // to the CONTEXT_EXIT // Parameters: () // // Return: void // //============================================================================= void Win32Platform::LaunchDashboard() { { //chuck I copied and pasted from the other platform's implementations GetLoadingManager()->CancelPendingRequests(); //TODO: Make sure sounds shut down too. GetSoundManager()->SetMasterVolume( 0.0f ); // DisplaySplashScreen( FadeToBlack ); GetPresentationManager()->StopAll(); //Shouldn't need to do this since, this singleton and the others should get destroyed once we //retrun the main loop //GameDataManager::DestroyInstance(); //Get rid of memcards p3d::loadManager->CancelAll(); GetSoundManager()->StopForMovie(); //Shouldnt need the early destruction of this singleton either //SoundManager::DestroyInstance(); //Dont want to shutdown platform early either. //ShutdownPlatform(); //rAssertMsg( false, "Doesn't make sense for win32." ); } } //============================================================================= // Win32Platform::ResetMachine //============================================================================= // Description: Comment // // Parameters: () // // Return: void // //============================================================================= void Win32Platform::ResetMachine() { rAssertMsg( false, "Doesn't make sense for win32." ); } //============================================================================= // Win32Platform::DisplaySplashScreen //============================================================================= // Description: Comment // // Parameters: ( SplashScreen screenID, // const char* overlayText = NULL, // float fontScale = 1.0f, // float textPosX = 0.0f, // float textPosY = 0.0f, // tColour textColour, // int fadeFrames = 3 ) // // Return: void // //============================================================================= void Win32Platform::DisplaySplashScreen( SplashScreen screenID, const char* overlayText, float fontScale, float textPosX, float textPosY, tColour textColour, int fadeFrames ) { HeapMgr()->PushHeap( GMA_TEMP ); p3d::inventory->PushSection(); p3d::inventory->AddSection( WIN32_SECTION ); p3d::inventory->SelectSection( WIN32_SECTION ); P3D_UNICODE unicodeText[256]; // Save the current Projection mode so I can restore it later pddiProjectionMode pm = p3d::pddi->GetProjectionMode(); p3d::pddi->SetProjectionMode(PDDI_PROJECTION_DEVICE); pddiCullMode cm = p3d::pddi->GetCullMode(); p3d::pddi->SetCullMode(PDDI_CULL_NONE); //CREATE THE FONT tTextureFont* thisFont = NULL; // Convert memory buffer into a texturefont. // //p3d::load(gFont, DEFAULTFONT_SIZE, GMA_TEMP); LoadMemP3DFile( gFont, DEFAULTFONT_SIZE, p3d::inventory ); thisFont = p3d::find("adlibn_20"); rAssert( thisFont ); thisFont->AddRef(); tShader* fontShader = thisFont->GetShader(); //fontShader->SetInt( ) p3d::AsciiToUnicode( overlayText, unicodeText, 256 ); // Make the missing letter into somthing I can see // thisFont->SetMissingLetter(p3d::ConvertCharToUnicode('j')); int a = 0; do { p3d::pddi->SetColourWrite(true, true, true, true); p3d::pddi->SetClearColour( pddiColour(0,0,0) ); p3d::pddi->BeginFrame(); p3d::pddi->Clear(PDDI_BUFFER_COLOUR); //This is for fading in the font and shaders. int bright = 255; if (a < fadeFrames) bright = (a * 255) / fadeFrames; if ( bright > 255 ) bright = 255; tColour c(bright, bright, bright, 255); //Display font if (overlayText != NULL) { tColour colour = textColour; colour.SetAlpha( bright ); thisFont->SetColour( colour ); p3d::pddi->SetProjectionMode(PDDI_PROJECTION_ORTHOGRAPHIC); p3d::stack->Push(); p3d::stack->LoadIdentity(); p3d::stack->Translate( textPosX, textPosY, 1.5f); float scaleSize = 1.0f / 480.0f; //This is likely good for 528 also. p3d::stack->Scale(scaleSize * fontScale, scaleSize* fontScale , 1.0f); if ( textPosX != 0.0f || textPosY != 0.0f ) { thisFont->DisplayText( unicodeText ); } else { thisFont->DisplayText( unicodeText, 3 ); } p3d::stack->Pop(); } p3d::pddi->EndFrame(); p3d::context->SwapBuffers(); ++a; } while (a <= fadeFrames); p3d::pddi->SetCullMode(cm); p3d::pddi->SetProjectionMode(pm); //Should do this after a vsync. thisFont->Release(); p3d::inventory->RemoveSectionElements(WIN32_SECTION); p3d::inventory->DeleteSection(WIN32_SECTION); p3d::inventory->PopSection(); HeapMgr()->PopHeap( GMA_TEMP ); } //============================================================================= // Win32Platform::DisplaySplashScreen //============================================================================= // Description: Comment // // Parameters: ( const char* textureName, // const char* overlayText = NULL, // float fontScale = 1.0f, // float textPosX = 0.0f, // float textPosY = 0.0f, // tColour textColour, // int fadeFrames = 3 ) // // Return: void // //============================================================================= void Win32Platform::DisplaySplashScreen( const char* textureName, const char* overlayText, float fontScale, float textPosX, float textPosY, tColour textColour, int fadeFrames ) { } void Win32Platform::OnControllerError(const char *msg) { DisplaySplashScreen( Error, msg, 0.7f, 0.0f, 0.0f, tColour(255, 255, 255), 0 ); mErrorState = CTL_ERROR; mPauseForError = true; } //============================================================================= // Win32Platform::OnDriveError //============================================================================= // Description: Comment // // Parameters: ( radFileError error, const char* pDriveName, void* pUserData ) // // Return: bool // //============================================================================= bool Win32Platform::OnDriveError( radFileError error, const char* pDriveName, void* pUserData ) { // First check if the error is related to loading/saving games. // We do this here because windows has one drive for all operations. // If the game data manager is using the drive, it handles the error. GameDataManager* gm = GetGameDataManager(); if( gm->IsUsingDrive() ) { return gm->OnDriveError( error, pDriveName, pUserData ); } switch ( error ) { case Success: { if ( mErrorState != NONE ) { DisplaySplashScreen( FadeToBlack ); mErrorState = NONE; mPauseForError = false; } return true; break; } case FileNotFound: { rAssert( pUserData != NULL ); radFileRequest* request = static_cast( pUserData ); const char* fileName = request->GetFilename(); //Get rid of the slashes. unsigned int i; unsigned int lastIndex = 0; for ( i = 0; i < strlen( fileName ); ++i ) { if ( fileName[ i ] == '\\' ) { lastIndex = i; } } unsigned int adjustedIndex = lastIndex == 0 ? lastIndex : lastIndex + 1; char adjustedName[32]; strncpy( adjustedName, &fileName[adjustedIndex], ( strlen( fileName ) - lastIndex ) ); adjustedName[ strlen( fileName ) - lastIndex ] = '\0'; if( strcmp( fileName, GameConfigManager::ConfigFilename ) == 0 ) { return false; } char errorString[256]; sprintf( errorString, "%s:\n%s", ERROR_STRINGS[error], adjustedName ); DisplaySplashScreen( Error, errorString, 1.0f, 0.0f, 0.0f, tColour(255, 255, 255), 0 ); mErrorState = P_ERROR; mPauseForError = true; return true; } case NoMedia: case MediaNotFormatted: case MediaCorrupt: case NoFreeSpace: case HardwareFailure: { //This could be the wrong disc. DisplaySplashScreen( Error, ERROR_STRINGS[error], 1.0f, 0.0f, 0.0f, tColour(255, 255, 255), 0 ); mErrorState = P_ERROR; mPauseForError = true; return true; } default: { //Others are not supported. rAssert( false ); } } return false; } //============================================================================= // Win32Platform::SetResolution //============================================================================= // Description: Sets the screen resolution // // Parameters: res - desired resolution // // Returns: true if successful // false if not supported // // Notes: //============================================================================= bool Win32Platform::SetResolution( Resolution res, int bpp, bool fullscreen ) { // Check if resolution is supported. if( !IsResolutionSupported( res, bpp ) ) { return false; } // Set up the new properties mResolution = res; mbpp = bpp; mFullscreen = fullscreen; // Reinitialize the d3d context. InitializeContext(); // Resize the window for the new resolution ResizeWindow(); return true; } //============================================================================= // Win32Platform::GetResolution //============================================================================= // Description: Returns the current resolution // // Parameters: n/a // // Returns: resolution // // Notes: //============================================================================= Win32Platform::Resolution Win32Platform::GetResolution() const { return mResolution; } //============================================================================= // Win32Platform::GetBPP //============================================================================= // Description: Returns the current bit depth. // // Parameters: n/a // // Returns: bit depth // // Notes: //============================================================================= int Win32Platform::GetBPP() const { return mbpp; } //============================================================================= // Win32Platform::IsFullscreen //============================================================================= // Description: Returns true if currently in full screen mode // // Parameters: n/a // // Returns: true if in full screen, false if in window // // Notes: //============================================================================= bool Win32Platform::IsFullscreen() const { return mFullscreen; } //============================================================================= // Win32Platform::GetConfigName //============================================================================= // Description: Returns the name of the win32 platform's config // // Parameters: n/a // // Returns: // // Notes: //============================================================================= const char* Win32Platform::GetConfigName() const { return "System"; } //============================================================================= // Win32Platform::GetNumProperties //============================================================================= // Description: Returns the number of config properties // // Parameters: n/a // // Returns: // // Notes: //============================================================================= int Win32Platform::GetNumProperties() const { return 4; } //============================================================================= // Win32Platform::LoadDefaults //============================================================================= // Description: Loads the default configuration for the system. // // Parameters: n/a // // Returns: // // Notes: //============================================================================= void Win32Platform::LoadDefaults() { #ifdef RAD_DEBUG SetResolution( StartingResolution, StartingBPP, !CommandLineOptions::Get( CLO_WINDOW_MODE ) ); #else SetResolution( StartingResolution, StartingBPP, true ); #endif GetRenderFlow()->SetGamma( 1.0f ); } //============================================================================= // Win32Platform::LoadConfig //============================================================================= // Description: Loads the platforms configuration // // Parameters: n/a // // Returns: // // Notes: //============================================================================= void Win32Platform::LoadConfig( ConfigString& config ) { char property[ ConfigString::MaxLength ]; char value[ ConfigString::MaxLength ]; while ( config.ReadProperty( property, value ) ) { if( _stricmp( property, "display" ) == 0 ) { if( _stricmp( value, "window" ) == 0 ) { mFullscreen = false; } else if( _stricmp( value, "fullscreen" ) == 0 ) { mFullscreen = true; } } else if( _stricmp( property, "resolution" ) == 0 ) { if( strcmp( value, "640x480" ) == 0 ) { mResolution = Res_640x480; } else if( strcmp( value, "800x600" ) == 0 ) { mResolution = Res_800x600; } else if( strcmp( value, "1024x768" ) == 0 ) { mResolution = Res_1024x768; } else if( strcmp( value, "1152x864" ) == 0 ) { mResolution = Res_1152x864; } else if( strcmp( value, "1280x1024" ) == 0 ) { mResolution = Res_1280x1024; } else if( strcmp( value, "1600x1200" ) == 0 ) { mResolution = Res_1600x1200; } } else if( _stricmp( property, "bpp" ) == 0 ) { if( strcmp( value, "16" ) == 0 ) { mbpp = 16; } else if( strcmp( value, "32" ) == 0 ) { mbpp = 32; } } else if( _stricmp( property, "gamma" ) == 0 ) { float val = (float) atof( value ); if( val > 0 ) { GetRenderFlow()->SetGamma( val ); } } } // apply the new settings. SetResolution( mResolution, mbpp, mFullscreen ); } //============================================================================= // Win32Platform::SaveConfig //============================================================================= // Description: Saves the system configuration to the config string. // // Parameters: config string to save to // // Returns: // // Notes: //============================================================================= void Win32Platform::SaveConfig( ConfigString& config ) { config.WriteProperty( "display", mFullscreen ? "fullscreen" : "window" ); const char* res = "800x600"; switch( mResolution ) { case Res_640x480: { res = "640x480"; break; } case Res_800x600: { res = "800x600"; break; } case Res_1024x768: { res = "1024x768"; break; } case Res_1152x864: { res = "1152x864"; break; } case Res_1280x1024: { res = "1280x1024"; break; } case Res_1600x1200: { res = "1600x1200"; break; } default: { rAssert( false ); } } config.WriteProperty( "resolution", res ); config.WriteProperty( "bpp", mbpp == 16 ? "16" : "32" ); char gamma[20]; sprintf( gamma, "%f", GetRenderFlow()->GetGamma() ); config.WriteProperty( "gamma", gamma ); } //****************************************************************************** // // Private Member Functions // //****************************************************************************** //============================================================================== // Win32Platform::Win32Platform //============================================================================== // Description: Constructor. // // Parameters: None. // // Return: N/A. // //============================================================================== Win32Platform::Win32Platform( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) : mpPlatform( NULL ), mpContext( NULL ), mResolution( StartingResolution ), mbpp( StartingBPP ) { mhInstance = hInstance; mFullscreen = false; mScreenWidth = GetSystemMetrics(SM_CXSCREEN); mScreenHeight = GetSystemMetrics(SM_CYSCREEN); while (mScreenWidth > 1600 ) // probably multimonitor { mScreenWidth /= 2; } } //============================================================================== // Win32Platform::~Win32Platform //============================================================================== // Description: Destructor. // // Parameters: None. // // Return: N/A. // //============================================================================== Win32Platform::~Win32Platform() { HeapManager::DestroyInstance(); CloseHandle( mhMutex ); } //============================================================================== // Win32Platform::InitializeFoundationDrive //============================================================================== // Description: Get FTech ready to go. // // Parameters: None. // // Return: None. // // Constraints: The FTech systems must be initialized in a particular order. // Consult their documentation before changing. // //============================================================================== void Win32Platform::InitializeFoundationDrive() { // // Get the default drive and hold it open for the life of the game. // This is a costly operation so we only want to do it once. // char defaultDrive[ radFileDrivenameMax + 1 ]; ::radGetDefaultDrive( defaultDrive ); ::radDriveOpenSync( &mpIRadDrive, defaultDrive, NormalPriority, // Default GMA_PERSISTENT ); rAssert( mpIRadDrive != NULL ); mpIRadDrive->RegisterErrorHandler( this, NULL ); } //============================================================================== // Win32Platform::ShutdownFoundation //============================================================================== // Description: Shut down Foundation Tech. // // Parameters: None. // // Return: None. // // Constraints: The FTech systems must be terminated in the reverse order that // they were initialized in. // //============================================================================== void Win32Platform::ShutdownFoundation() { // // Release the drive we've held open since the begining. // mpIRadDrive->Release(); mpIRadDrive = NULL; // // Shutdown the systems in the reverse order. // ::radMovieTerminate2(); ::radDriveUnmount( NULL ); ::radLoadTerminate(); ::radFileTerminate(); ::radDbgWatchTerminate(); if( CommandLineOptions::Get( CLO_MEMORY_MONITOR ) ) { ::radMemoryMonitorTerminate(); } ::radDbgComTargetTerminate(); ::radTimeTerminate(); ::radPlatformTerminate(); } //============================================================================== // Win32Platform::InitializePure3D //============================================================================== // Description: Get Pure3D ready to go. // // Parameters: None. // // Return: None. // //============================================================================== void Win32Platform::InitializePure3D() { MEMTRACK_PUSH_GROUP( "Win32Platform" ); // p3d::SetMemAllocator( p3d::ALLOC_DEFAULT, GMA_PERSISTENT ); // p3d::SetMemAllocator( p3d::ALLOC_LOADED, GMA_LEVEL ); // // Initialise Pure3D platform object. // This call differs between different platforms. The Win32 version, // for example requires the application instance to be passed in. // mpPlatform = tPlatform::Create( mhInstance ); rAssert( mpPlatform != NULL ); // // Initialize the d3d context. // InitializeContext(); // // This call installs chunk handlers for all the primary chunk types that // Pure3D supports. This includes textures, materials, geometries, and the // like. // // p3d::InstallDefaultLoaders(); P3DASSERT(p3d::context); tP3DFileHandler* p3d = new(GMA_PERSISTENT) tP3DFileHandler; // p3d::loadManager->AddHandler(p3d, "p3d"); p3d::context->GetLoadManager()->AddHandler(p3d, "p3d"); p3d::context->GetLoadManager()->AddHandler(new(GMA_PERSISTENT) tPNGHandler, "png"); if( CommandLineOptions::Get( CLO_FE_UNJOINED ) ) { p3d::context->GetLoadManager()->AddHandler(new(GMA_PERSISTENT) tBMPHandler, "bmp"); p3d::context->GetLoadManager()->AddHandler(new(GMA_PERSISTENT) tTargaHandler, "tga"); } else { p3d::context->GetLoadManager()->AddHandler(new(GMA_PERSISTENT) tBMPHandler, "p3d"); p3d::context->GetLoadManager()->AddHandler(new(GMA_PERSISTENT) tPNGHandler, "p3d"); p3d::context->GetLoadManager()->AddHandler(new(GMA_PERSISTENT) tTargaHandler, "p3d"); } // p3d->AddHandler(new tGeometryLoader); // GeometryWrappedLoader* pGWL = new GeometryWrappedLoader; GeometryWrappedLoader* pGWL = (GeometryWrappedLoader*)GetAllWrappers()->mpLoader( AllWrappers::msGeometry ); pGWL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pGWL ); StaticEntityLoader* pSEL = (StaticEntityLoader*)GetAllWrappers()->mpLoader( AllWrappers::msStaticEntity ); pSEL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pSEL ); StaticPhysLoader* pSPL = (StaticPhysLoader*)GetAllWrappers()->mpLoader( AllWrappers::msStaticPhys ); pSPL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pSPL ); TreeDSGLoader* pTDL = (TreeDSGLoader*)GetAllWrappers()->mpLoader( AllWrappers::msTreeDSG ); pTDL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pTDL ); FenceLoader* pFL = (FenceLoader*)GetAllWrappers()->mpLoader( AllWrappers::msFenceEntity ); pFL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pFL ); IntersectLoader* pIL = (IntersectLoader*)GetAllWrappers()->mpLoader( AllWrappers::msIntersectDSG ); pIL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pIL ); AnimCollLoader* pACL = (AnimCollLoader*)GetAllWrappers()->mpLoader( AllWrappers::msAnimCollEntity ); pACL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pACL ); AnimDSGLoader* pAnimDSGLoader = (AnimDSGLoader*)GetAllWrappers()->mpLoader( AllWrappers::msAnimEntity ); pAnimDSGLoader->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pAnimDSGLoader ); DynaPhysLoader* pDPL = (DynaPhysLoader*)GetAllWrappers()->mpLoader( AllWrappers::msDynaPhys ); pDPL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pDPL ); InstStatPhysLoader* pISPL = (InstStatPhysLoader*)GetAllWrappers()->mpLoader( AllWrappers::msInstStatPhys ); pISPL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pISPL ); InstStatEntityLoader* pISEL = (InstStatEntityLoader*)GetAllWrappers()->mpLoader( AllWrappers::msInstStatEntity ); pISEL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pISEL ); LocatorLoader* pLL = (LocatorLoader*)GetAllWrappers()->mpLoader( AllWrappers::msLocator); pLL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pLL ); RoadLoader* pRL = (RoadLoader*)GetAllWrappers()->mpLoader( AllWrappers::msRoadSegment); pRL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pRL ); PathLoader* pPL = (PathLoader*)GetAllWrappers()->mpLoader( AllWrappers::msPathSegment); pPL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pPL ); WorldSphereLoader* pWSL = (WorldSphereLoader*)GetAllWrappers()->mpLoader( AllWrappers::msWorldSphere); pWSL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pWSL ); LensFlareLoader* pLSL = (LensFlareLoader*)GetAllWrappers()->mpLoader( AllWrappers::msLensFlare); pLSL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pLSL ); BillboardWrappedLoader* pBWL = (BillboardWrappedLoader*)GetAllWrappers()->mpLoader( AllWrappers::msBillboard); pBWL->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pBWL ); InstParticleSystemLoader* pInstParticleSystemLoader = (InstParticleSystemLoader*) GetAllWrappers()->mpLoader( AllWrappers::msInstParticleSystem); pInstParticleSystemLoader->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pInstParticleSystemLoader ); BreakableObjectLoader* pBreakableObjectLoader = (BreakableObjectLoader*) GetAllWrappers()->mpLoader( AllWrappers::msBreakableObject); pBreakableObjectLoader->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pBreakableObjectLoader ); AnimDynaPhysLoader* pAnimDynaPhysLoader = (AnimDynaPhysLoader*) GetAllWrappers()->mpLoader( AllWrappers::msAnimDynaPhys); pAnimDynaPhysLoader->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pAnimDynaPhysLoader ); AnimDynaPhysWrapperLoader* pAnimWrapperLoader = (AnimDynaPhysWrapperLoader*) GetAllWrappers()->mpLoader( AllWrappers::msAnimDynaPhysWrapper); pAnimWrapperLoader->SetRegdListener( GetRenderManager(), 0 ); p3d->AddHandler( pAnimWrapperLoader ); p3d->AddHandler(new(GMA_PERSISTENT) tTextureLoader); p3d->AddHandler( new(GMA_PERSISTENT) tSetLoader ); p3d->AddHandler(new(GMA_PERSISTENT) tShaderLoader); p3d->AddHandler(new(GMA_PERSISTENT) tCameraLoader); p3d->AddHandler(new(GMA_PERSISTENT) tGameAttrLoader); p3d->AddHandler(new(GMA_PERSISTENT) tLightLoader); p3d->AddHandler(new(GMA_PERSISTENT) tLocatorLoader); p3d->AddHandler(new(GMA_PERSISTENT) tLightGroupLoader); p3d->AddHandler(new(GMA_PERSISTENT) tImageLoader); p3d->AddHandler(new(GMA_PERSISTENT) tTextureFontLoader); p3d->AddHandler(new(GMA_PERSISTENT) tImageFontLoader); p3d->AddHandler(new(GMA_PERSISTENT) tSpriteLoader); //p3d->AddHandler(new(GMA_PERSISTENT) tBillboardQuadGroupLoader); p3d->AddHandler(new(GMA_PERSISTENT) tSkeletonLoader); p3d->AddHandler(new(GMA_PERSISTENT) tPolySkinLoader); p3d->AddHandler(new(GMA_PERSISTENT) tCompositeDrawableLoader); p3d->AddHandler(new(GMA_PERSISTENT) tVertexAnimKeyLoader); p3d->AddHandler(new(GMA_PERSISTENT) tAnimationLoader); p3d->AddHandler(new(GMA_PERSISTENT) tFrameControllerLoader); p3d->AddHandler(new(GMA_PERSISTENT) tMultiControllerLoader); p3d->AddHandler(new(GMA_PERSISTENT) tAnimatedObjectFactoryLoader); p3d->AddHandler(new(GMA_PERSISTENT) tAnimatedObjectLoader); p3d->AddHandler(new(GMA_PERSISTENT) tParticleSystemFactoryLoader); p3d->AddHandler(new(GMA_PERSISTENT) tParticleSystemLoader); p3d->AddHandler(new(GMA_PERSISTENT) tLensFlareGroupLoader); p3d->AddHandler(new(GMA_PERSISTENT) sg::Loader); p3d->AddHandler(new(GMA_PERSISTENT) tExpressionGroupLoader); p3d->AddHandler(new(GMA_PERSISTENT) tExpressionMixerLoader); p3d->AddHandler(new(GMA_PERSISTENT) tExpressionLoader); //ATCloader, hope this doesnt blow up p3d->AddHandler(new(GMA_PERSISTENT) ATCLoader); //p3d->AddHandler(new p3d::tIgnoreLoader); tSEQFileHandler* sequencerFileHandler = new(GMA_PERSISTENT) tSEQFileHandler; p3d::loadManager->AddHandler(sequencerFileHandler, "seq"); // sim lib sim::InstallSimLoaders(); p3d->AddHandler(new(GMA_PERSISTENT) CameraDataLoader, SRR2::ChunkID::FOLLOWCAM); p3d->AddHandler(new(GMA_PERSISTENT) CameraDataLoader, SRR2::ChunkID::WALKERCAM); p3d->AddHandler(new(GMA_PERSISTENT) IntersectionLoader); //p3d->AddHandler(new(GMA_PERSISTENT) RoadLoader); p3d->AddHandler(new(GMA_PERSISTENT) RoadDataSegmentLoader); p3d->AddHandler(new(GMA_PERSISTENT) CStatePropDataLoader); MEMTRACK_POP_GROUP( "Win32Platform" ); } //============================================================================== // Win32Platform::ShutdownPure3D //============================================================================== // Description: Clean up and shut down Pure3D. // // Parameters: None. // // Return: None. // //============================================================================== void Win32Platform::ShutdownPure3D() { // // Clean-up the Pure3D Inventory // p3d::inventory->RemoveAllElements(); p3d::inventory->DeleteAllSections(); // // Clean-up the space taken by the Pure 3D context. // if( mpContext != NULL ) { mpPlatform->DestroyContext( mpContext ); mpContext = NULL; } // // Clean-up the space taken by the Pure 3D platform. // if( mpPlatform != NULL ) { tPlatform::Destroy( mpPlatform ); mpPlatform = NULL; } } //============================================================================== // Win32Platform::InitializeContext //============================================================================== // Description: Initializes the d3d context for this application according to // the class' display settings - resolution, bpp, fullscreen. // // Parameters: n/a // // Return: n/a // //============================================================================== void Win32Platform::InitializeContext() { tContextInitData init; // // This is the window we want to render into. // init.hwnd = mhWnd; // // Set the fullscreen/window mode. // init.displayMode = mFullscreen ? PDDI_DISPLAY_FULLSCREEN : PDDI_DISPLAY_WINDOW; // // This the name of the PDDI we will be using for rendering // strncpy(init.PDDIlib, d3dLibraryName, 128); // // All applications should supply PDDI_BUFFER_COLOUR. PDDI_BUFFER_DEPTH // specifies that we also want to allocate a Z-buffer. // init.bufferMask = PDDI_BUFFER_COLOUR | PDDI_BUFFER_DEPTH; init.enableSnapshot = false; // // These values only take effect in fullscreen mode. In windowed mode, the // dimensions of the window define the rendering area. We'll define them // anyway for completeness sake. // TranslateResolution( mResolution, init.xsize, init.ysize ); // // Depth of the rendering buffer. Again, this value only works in // fullscreen mode. In window mode, the depth of the desktop is used. // This value should be either 16 or 32. // init.bpp = mbpp; init.lockToVsync = false; if( mpContext == NULL ) { // Create the context mpContext = mpPlatform->CreateContext( &init ); rAssert( mpContext != NULL ); // // Assign this context to the platform. // mpPlatform->SetActiveContext( mpContext ); p3d::pddi->EnableZBuffer( true ); } else { // Update the display settings. mpContext->GetDisplay()->InitDisplay( &init ); } } //============================================================================== // Win32Platform::TranslateResolution //============================================================================== // Description: translates resolution enums to x and y // // Parameters: resolution - the res enum // x - corresponding width // y - corresponding height // // Return: N/A. // //============================================================================== void Win32Platform::TranslateResolution( Resolution res, int&x, int&y ) { switch( res ) { case Res_640x480: { x = 640; y = 480; break; } case Res_800x600: { x = 800; y = 600; break; } case Res_1024x768: { x = 1024; y = 768; break; } case Res_1152x864: { x = 1152; y = 864; break; } case Res_1280x1024: { x = 1280; y = 1024; break; } case Res_1600x1200: { x = 1600; y = 1200; break; } default: { rAssert( false ); } } } //============================================================================== // Win32Platform::IsResolutionSupported //============================================================================== // Description: Determines if a resolution is supported on this pc // // Parameters: resolution - the res enum // // Return: true if supported. // //============================================================================== bool Win32Platform::IsResolutionSupported( Resolution res, int bpp ) const { int x,y; TranslateResolution( res, x, y ); // Get the display info for the device pddiDisplayInfo* displays = NULL; int num_adapters = mpContext->GetDevice()->GetDisplayInfo( &displays ); rAssert( num_adapters > 0 ); // Go through the supported modes and see if we can do it. // Ignore the refresh rate - directx uses default. for( int i = 0; i < displays[0].nDisplayModes; i++ ) { if( displays[0].modeInfo[i].width == x && displays[0].modeInfo[i].height == y && displays[0].modeInfo[i].bpp == bpp ) { return true; } } return false; } //============================================================================== // Win32Platform::TrackMouseEvent //============================================================================== // Description: Determines if a resolution is supported on this pc // // Parameters: pMouseEventTracker - the tracker // // Return: true if succeeded in creating a timer. // //============================================================================== BOOL Win32Platform::TrackMouseEvent( MOUSETRACKER* pMouseEventTracker ) { if ( !pMouseEventTracker || pMouseEventTracker->cbSize < sizeof(MOUSETRACKER) ) return false; if( !IsWindow( pMouseEventTracker->hwndTrack ) ) return false; if( !(pMouseEventTracker->dwFlags & TIMER_LEAVE) ) return false; return SetTimer( pMouseEventTracker->hwndTrack, pMouseEventTracker->dwFlags, 100, (TIMERPROC)TrackMouseTimerProc ); } //============================================================================= // Win32Platform::ResizeWindow //============================================================================= // Description: Resizes the app's window based on the current resolution. // // Parameters: n/a // // Returns: n/a // // Notes: //============================================================================= void Win32Platform::ResizeWindow() { // If fullscreen, no need to change the window size. if( mFullscreen ) { return; } int x,y,cx,cy; RECT clientRect; TranslateResolution( mResolution, cx, cy ); if( cx < mScreenWidth ) // if the window fits on the desktop { x = ( mScreenWidth - cx ) / 2; y = ( mScreenHeight - cy ) / 2; // Adjust the rectangle for the title bar and borders clientRect.left = x; clientRect.top = y; clientRect.right = x+cx; clientRect.bottom = y+cy; AdjustWindowRect(&clientRect,WndStyle,FALSE); } else // if the window is bigger than the client area { clientRect.left = 0; clientRect.top = 0; clientRect.right = cx; clientRect.bottom = cy; } SetWindowPos( mhWnd, HWND_TOP, clientRect.left, clientRect.top, clientRect.right-clientRect.left, clientRect.bottom-clientRect.top, 0 ); ShowWindow( mhWnd, SW_SHOW ); } //============================================================================= // Win32Platform::ShowTheCursor //============================================================================= // Description: Shows or hides the cursor. Wrapper for the windows ShowCursor // function, except it doesn't keep a counter for the number of // shows/hides. // // Parameters: show - show cursor // // Returns: n/a // // Notes: //============================================================================= void Win32Platform::ShowTheCursor( bool show ) { if( mShowCursor != show ) { mShowCursor = show; ShowCursor( mShowCursor ); } } //============================================================================= // GetMessageName //============================================================================= // Description: Prints the name of windows messages. // // Parameters: message - message id // // Returns: string name // // Notes: //============================================================================= #if defined( PRINT_WINMESSAGES ) && defined( RAD_DEBUG ) static const char* GetMessageName( UINT message ) { switch ( message ) { case 0x0000: return "WM_NULL"; case 0x0001: return "WM_CREATE"; case 0x0002: return "WM_DESTROY"; case 0x0003: return "WM_MOVE"; case 0x0005: return "WM_SIZE"; case 0x0006: return "WM_ACTIVATE"; case 0x0007: return "WM_SETFOCUS"; case 0x0008: return "WM_KILLFOCUS"; case 0x000A: return "WM_ENABLE"; case 0x000B: return "WM_SETREDRAW"; case 0x000C: return "WM_SETTEXT"; case 0x000D: return "WM_GETTEXT"; case 0x000E: return "WM_GETTEXTLENGTH"; case 0x000F: return "WM_PAINT"; case 0x0010: return "WM_CLOSE"; case 0x0011: return "WM_QUERYENDSESSION"; case 0x0013: return "WM_QUERYOPEN"; case 0x0016: return "WM_ENDSESSION"; case 0x0012: return "WM_QUIT"; case 0x0014: return "WM_ERASEBKGND"; case 0x0015: return "WM_SYSCOLORCHANGE"; case 0x0018: return "WM_SHOWWINDOW"; case 0x001A: return "WM_WININICHANGE"; case 0x001B: return "WM_DEVMODECHANGE"; case 0x001C: return "WM_ACTIVATEAPP"; case 0x001D: return "WM_FONTCHANGE"; case 0x001E: return "WM_TIMECHANGE"; case 0x001F: return "WM_CANCELMODE"; case 0x0020: return "WM_SETCURSOR"; case 0x0021: return "WM_MOUSEACTIVATE"; case 0x0022: return "WM_CHILDACTIVATE"; case 0x0023: return "WM_QUEUESYNC"; case 0x0024: return "WM_GETMINMAXINFO"; case 0x0026: return "WM_PAINTICON"; case 0x0027: return "WM_ICONERASEBKGND"; case 0x0028: return "WM_NEXTDLGCTL"; case 0x002A: return "WM_SPOOLERSTATUS"; case 0x002B: return "WM_DRAWITEM"; case 0x002C: return "WM_MEASUREITEM"; case 0x002D: return "WM_DELETEITEM"; case 0x002E: return "WM_VKEYTOITEM"; case 0x002F: return "WM_CHARTOITEM"; case 0x0030: return "WM_SETFONT"; case 0x0031: return "WM_GETFONT"; case 0x0032: return "WM_SETHOTKEY"; case 0x0033: return "WM_GETHOTKEY"; case 0x0037: return "WM_QUERYDRAGICON"; case 0x0039: return "WM_COMPAREITEM"; case 0x0041: return "WM_COMPACTING"; case 0x0044: return "WM_COMMNOTIFY"; case 0x0046: return "WM_WINDOWPOSCHANGING"; case 0x0047: return "WM_WINDOWPOSCHANGED"; case 0x0048: return "WM_POWER"; case 0x004A: return "WM_COPYDATA"; case 0x004B: return "WM_CANCELJOURNAL"; case 0x004E: return "WM_NOTIFY"; case 0x0050: return "WM_INPUTLANGCHANGEREQUEST"; case 0x0051: return "WM_INPUTLANGCHANGE"; case 0x0052: return "WM_TCARD"; case 0x0053: return "WM_HELP"; case 0x0054: return "WM_USERCHANGED"; case 0x0055: return "WM_NOTIFYFORMAT"; case 0x007B: return "WM_CONTEXTMENU"; case 0x007C: return "WM_STYLECHANGING"; case 0x007D: return "WM_STYLECHANGED"; case 0x007E: return "WM_DISPLAYCHANGE"; case 0x007F: return "WM_GETICON"; case 0x0080: return "WM_SETICON"; case 0x0081: return "WM_NCCREATE"; case 0x0082: return "WM_NCDESTROY"; case 0x0083: return "WM_NCCALCSIZE"; case 0x0084: return "WM_NCHITTEST"; case 0x0085: return "WM_NCPAINT"; case 0x0086: return "WM_NCACTIVATE"; case 0x0087: return "WM_GETDLGCODE"; case 0x0088: return "WM_SYNCPAINT"; case 0x00A0: return "WM_NCMOUSEMOVE"; case 0x00A1: return "WM_NCLBUTTONDOWN"; case 0x00A2: return "WM_NCLBUTTONUP"; case 0x00A3: return "WM_NCLBUTTONDBLCLK"; case 0x00A4: return "WM_NCRBUTTONDOWN"; case 0x00A5: return "WM_NCRBUTTONUP"; case 0x00A6: return "WM_NCRBUTTONDBLCLK"; case 0x00A7: return "WM_NCMBUTTONDOWN"; case 0x00A8: return "WM_NCMBUTTONUP"; case 0x00A9: return "WM_NCMBUTTONDBLCLK"; case 0x00AB: return "WM_NCXBUTTONDOWN"; case 0x00AC: return "WM_NCXBUTTONUP"; case 0x00AD: return "WM_NCXBUTTONDBLCLK"; case 0x00FF: return "WM_INPUT"; case 0x0100: return "WM_KEYDOWN"; case 0x0101: return "WM_KEYUP"; case 0x0102: return "WM_CHAR"; case 0x0103: return "WM_DEADCHAR"; case 0x0104: return "WM_SYSKEYDOWN"; case 0x0105: return "WM_SYSKEYUP"; case 0x0106: return "WM_SYSCHAR"; case 0x0107: return "WM_SYSDEADCHAR"; case 0x0109: return "WM_KEYLAST"; case 0xFFFF: return "UNICODE_NOCHAR"; case 0x0108: return "WM_KEYLAST"; case 0x010D: return "WM_IME_STARTCOMPOSITION"; case 0x010E: return "WM_IME_ENDCOMPOSITION"; case 0x010F: return "WM_IME_KEYLAST"; case 0x0110: return "WM_INITDIALOG"; case 0x0111: return "WM_COMMAND"; case 0x0112: return "WM_SYSCOMMAND"; case 0x0113: return "WM_TIMER"; case 0x0114: return "WM_HSCROLL"; case 0x0115: return "WM_VSCROLL"; case 0x0116: return "WM_INITMENU"; case 0x0117: return "WM_INITMENUPOPUP"; case 0x011F: return "WM_MENUSELECT"; case 0x0120: return "WM_MENUCHAR"; case 0x0121: return "WM_ENTERIDLE"; case 0x0122: return "WM_MENURBUTTONUP"; case 0x0123: return "WM_MENUDRAG"; case 0x0124: return "WM_MENUGETOBJECT"; case 0x0125: return "WM_UNINITMENUPOPUP"; case 0x0126: return "WM_MENUCOMMAND"; case 0x0127: return "WM_CHANGEUISTATE"; case 0x0128: return "WM_UPDATEUISTATE"; case 0x0129: return "WM_QUERYUISTATE"; case 0x0132: return "WM_CTLCOLORMSGBOX"; case 0x0133: return "WM_CTLCOLOREDIT"; case 0x0134: return "WM_CTLCOLORLISTBOX"; case 0x0135: return "WM_CTLCOLORBTN"; case 0x0136: return "WM_CTLCOLORDLG"; case 0x0137: return "WM_CTLCOLORSCROLLBAR"; case 0x0138: return "WM_CTLCOLORSTATIC"; case 0x0200: return "WM_MOUSEMOVE"; case 0x0201: return "WM_LBUTTONDOWN"; case 0x0202: return "WM_LBUTTONUP"; case 0x0203: return "WM_LBUTTONDBLCLK"; case 0x0204: return "WM_RBUTTONDOWN"; case 0x0205: return "WM_RBUTTONUP"; case 0x0206: return "WM_RBUTTONDBLCLK"; case 0x0207: return "WM_MBUTTONDOWN"; case 0x0208: return "WM_MBUTTONUP"; case 0x0209: return "WM_MBUTTONDBLCLK"; case 0x020A: return "WM_MOUSEWHEEL"; case 0x020B: return "WM_XBUTTONDOWN"; case 0x020C: return "WM_XBUTTONUP"; case 0x020D: return "WM_MOUSELAST"; case 0x0210: return "WM_PARENTNOTIFY"; case 0x0211: return "WM_ENTERMENULOOP"; case 0x0212: return "WM_EXITMENULOOP"; case 0x0213: return "WM_NEXTMENU"; case 0x0214: return "WM_SIZING"; case 0x0215: return "WM_CAPTURECHANGED"; case 0x0216: return "WM_MOVING"; case 0x0218: return "WM_POWERBROADCAST"; case 0x0219: return "WM_DEVICECHANGE"; case 0x0220: return "WM_MDICREATE"; case 0x0221: return "WM_MDIDESTROY"; case 0x0222: return "WM_MDIACTIVATE"; case 0x0223: return "WM_MDIRESTORE"; case 0x0224: return "WM_MDINEXT"; case 0x0225: return "WM_MDIMAXIMIZE"; case 0x0226: return "WM_MDITILE"; case 0x0227: return "WM_MDICASCADE"; case 0x0228: return "WM_MDIICONARRANGE"; case 0x0229: return "WM_MDIGETACTIVE"; case 0x0230: return "WM_MDISETMENU"; case 0x0231: return "WM_ENTERSIZEMOVE"; case 0x0232: return "WM_EXITSIZEMOVE"; case 0x0233: return "WM_DROPFILES"; case 0x0234: return "WM_MDIREFRESHMENU"; case 0x0281: return "WM_IME_SETCONTEXT"; case 0x0282: return "WM_IME_NOTIFY"; case 0x0283: return "WM_IME_CONTROL"; case 0x0284: return "WM_IME_COMPOSITIONFULL"; case 0x0285: return "WM_IME_SELECT"; case 0x0286: return "WM_IME_CHAR"; case 0x0288: return "WM_IME_REQUEST"; case 0x0290: return "WM_IME_KEYDOWN"; case 0x0291: return "WM_IME_KEYUP"; case 0x02A1: return "WM_MOUSEHOVER"; case 0x02A3: return "WM_MOUSELEAVE"; case 0x02A0: return "WM_NCMOUSEHOVER"; case 0x02A2: return "WM_NCMOUSELEAVE"; case 0x02B1: return "WM_WTSSESSION_CHANGE"; case 0x02c0: return "WM_TABLET_FIRST"; case 0x02df: return "WM_TABLET_LAST"; case 0x0300: return "WM_CUT"; case 0x0301: return "WM_COPY"; case 0x0302: return "WM_PASTE"; case 0x0303: return "WM_CLEAR"; case 0x0304: return "WM_UNDO"; case 0x0305: return "WM_RENDERFORMAT"; case 0x0306: return "WM_RENDERALLFORMATS"; case 0x0307: return "WM_DESTROYCLIPBOARD"; case 0x0308: return "WM_DRAWCLIPBOARD"; case 0x0309: return "WM_PAINTCLIPBOARD"; case 0x030A: return "WM_VSCROLLCLIPBOARD"; case 0x030B: return "WM_SIZECLIPBOARD"; case 0x030C: return "WM_ASKCBFORMATNAME"; case 0x030D: return "WM_CHANGECBCHAIN"; case 0x030E: return "WM_HSCROLLCLIPBOARD"; case 0x030F: return "WM_QUERYNEWPALETTE"; case 0x0310: return "WM_PALETTEISCHANGING"; case 0x0311: return "WM_PALETTECHANGED"; case 0x0312: return "WM_HOTKEY"; case 0x0317: return "WM_PRINT"; case 0x0318: return "WM_PRINTCLIENT"; case 0x0319: return "WM_APPCOMMAND"; case 0x031A: return "WM_THEMECHANGED"; case 0x0358: return "WM_HANDHELDFIRST"; case 0x035F: return "WM_HANDHELDLAST"; case 0x0360: return "WM_AFXFIRST"; case 0x0380: return "WM_PENWINFIRST"; case 0x038F: return "WM_PENWINLAST"; case 0x8000: return "WM_APP"; default: return "UNKNOWN MESSAGE"; } } #endif void Win32Platform::TrackMouseTimerProc( HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime ) { RECT clientRect; POINT point; GetClientRect( hWnd, &clientRect ); MapWindowPoints( hWnd, NULL, (LPPOINT)&clientRect, 2 ); GetCursorPos( &point ); if( !PtInRect( &clientRect, point ) || (WindowFromPoint(point) != hWnd ) ) { if( !KillTimer( hWnd, idEvent ) ) { rDebugPrintf( "Couldn't kill the timer" ); } PostMessage( hWnd, WM_MOUSELEAVE, 0, 0 ); } else { GetInputManager()->GetFEMouse()->getCursor()->SetVisible( true ); } } //============================================================================= // Win32Platform::WndProc //============================================================================= // Description: The windows os messaging callback for the game. // Routes messages to pure3d. // // Parameters: hwnd - handle for window // message - message ID // wParam - word parameter // lParam - long parameter // // Returns: windows result // // Notes: //============================================================================= LRESULT Win32Platform::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { #if defined( PRINT_WINMESSAGES ) && defined( RAD_DEBUG ) rDebugPrintf( "Windows Message: 0x%08x (%s) [0x%08x, 0x%08x]\n", message, GetMessageName(message), wParam, lParam ); #endif MOUSETRACKER mouseEventTracker; static bool bMouseInWindow; // A flag to poll if you want to check if the mouse is in the clientwindow. // // Under Win32, Pure3D needs to get a crack at the Windows messages so // it can detect window moving, resizing, and activation. // p3d::platform->ProcessWindowsMessage(hwnd, message, wParam, lParam); switch(message) { case WM_ACTIVATEAPP: { InputManager* pInputManager = GetInputManager(); if( spInstance != NULL && spInstance->mpContext != NULL ) { if( wParam ) // Window is being shown (in focus) { RenderFlow* rf = GetRenderFlow(); rf->SetGamma( rf->GetGamma() ); if( pInputManager ) { //GetInputManager()->SetRumbleForDevice(0, true); //rDebugPrintf("Force Effects Started!!! \n"); } } else // Window is being hidden (not in focus) { SetDeviceGammaRamp( GetDC( GetDesktopWindow( ) ), DesktopGammaRamp ); if( pInputManager ) { //GetInputManager()->SetRumbleForDevice(0, false); //rDebugPrintf("Force Effects Stopped!!! \n"); } } if( GetInputManager() != NULL ) { GetInputManager()->GetFEMouse()->SetInGameOverride( !wParam ); } } break; } case WM_SYSKEYDOWN: case WM_SYSKEYUP: { //Ignore Alt and F10 keys. switch(wParam) { case VK_MENU: return 0; case VK_F10: return 0; default: break; } } case WM_SHOWWINDOW: { break; } case WM_CREATE: { GetDeviceGammaRamp( GetDC( GetDesktopWindow( ) ), DesktopGammaRamp ); bMouseInWindow = false; break; } case WM_DESTROY: PostQuitMessage(0); break; case WM_MOUSELEAVE: bMouseInWindow = false; GetInputManager()->GetFEMouse()->getCursor()->SetVisible( false ); break; case WM_NCMOUSEMOVE: { POINT pPoint; GetCursorPos( &pPoint ); // Convert the absolute screen coordinates from windows to client window absolute coordinates. ScreenToClient( hwnd, &pPoint ); RECT clientRect; GetClientRect( hwnd, &clientRect ); GetInputManager()->GetFEMouse()->Move( pPoint.x, pPoint.y, clientRect.right, clientRect.bottom ); ShowTheCursor( true ); break; } case WM_MOUSEMOVE: { POINT pPoint; pPoint.x = LOWORD(lParam); pPoint.y = HIWORD(lParam); // For some reason beyond my comprehension WM_MOUSEMOVE seems to be getting called regardless if the // mouse moved or not. So let the FEMouse determine if we moved. FEMouse* pFEMouse = GetInputManager()->GetFEMouse(); if( pFEMouse->DidWeMove( pPoint.x, pPoint.y ) ) { RECT clientRect; GetClientRect( hwnd, &clientRect ); pFEMouse->Move( pPoint.x, pPoint.y, clientRect.right, clientRect.bottom ); } ShowTheCursor( false ); if( !bMouseInWindow ) { bMouseInWindow = true; mouseEventTracker.cbSize = sizeof(MOUSETRACKER); mouseEventTracker.dwFlags = TIMER_LEAVE; mouseEventTracker.hwndTrack = hwnd; if( !TrackMouseEvent( &mouseEventTracker ) ) { rDebugPrintf( "TrackMouseEvent Failed" ); } } break; } case WM_LBUTTONDOWN: { GetInputManager()->GetFEMouse()->ButtonDown( BUTTON_LEFT ); // rDebugPrintf("LEFT MOUSE BUTTON PRESSED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n"); break; } case WM_LBUTTONUP: { GetInputManager()->GetFEMouse()->ButtonUp( BUTTON_LEFT ); break; } case WM_SYSCOMMAND: { switch (wParam) { case SC_SCREENSAVE: // Screensaver Trying To Start? case SC_MONITORPOWER: // Monitor Trying To Enter Powersave? return 0; } break; } // PDDI will sent this message to enable or disable rendering in response to an // application level window event. For example, if the user clicks away from // the rendering window, or uses ALT-TAB to select another application, PDDI // will tell sent a WM_PDDI_DRAW_ENABLE(0) message. When the application // regains focus, WM_PDDI_DRAW_ENABLE(1) will be sent. case WM_PDDI_DRAW_ENABLE: //GetApplication()->EnableRendering(wParam == 1); break; case WM_CHAR: { break; } default: break; } return DefWindowProc(hwnd, message, wParam, lParam); }