// This is a WINDOWS dedicated function // LATER: This function doesn't work as expected, it won't "blink" on and off, and I cann't find a solution yet void EngineApp::FlashWhileMinimized( void ) { #if !defined( _WINDOWS ) && !defined( WINDOWS ) return; #endif if( !m_pWindow ) { return; } HWND hwnd = GetHwnd(); ENG_ASSERT( hwnd ); // If the window is minized if( GetWindowState() & SDL_WINDOW_MINIMIZED ) { GetGlobalTimer()->GetElapsedTime(); float totalTime = 0.f; SDL_Event event; FlashWindow( hwnd, true ); while( true ) { SDL_PumpEvents(); if( SDL_PeepEvents( &event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT ) > 0 ) { // wait for processing if close or other window event is called if( event.type != SDL_WINDOWEVENT || event.type != SDL_QUIT ) { MsgProc(); } // Not minimized anymore, flash for once and break if( !( GetWindowState() & SDL_WINDOW_MINIMIZED ) ) { FlashWindow( GetHwnd(), false ); break; } } else // The window has no upcoming message, keep flashing { totalTime += GetGlobalTimer()->GetElapsedTime(); if( totalTime > 1.0f ) { totalTime -= 1.0f; FlashWindow( GetHwnd(), true ); } } } } }
double PrecisionTimer::GetTimer() const { double delta = GetGlobalTimer() - startCount; // could be < 0 after call to Reset, so clamp return delta < 0.0? 0.0 : delta; }
int Checkpoint::Send( const Topic &node ) { /* Optionally update our own timestamp before we send on our information */ if (( m_TopicFlags & TOPIC_TIMESTAMP_FLAG ) != 0 ) m_tTime = GetGlobalTimer().Get(); return TopicSource::Send( node ); }
void EngineApp::SingleLoop( void ) { static double fAppTime = 0.0; static double fAbsoluteTime = 0.0; static float fElapasedTime = 0.0f; MsgProc(); GetGlobalTimer()->GetTimeValues( &fAppTime, &fAbsoluteTime, &fElapasedTime ); OnUpdateGame( fAppTime, fElapasedTime ); OnFrameRender( fAppTime, fElapasedTime ); }
// // class GameCodeApp::PumpUntilMessage - Chapter 10, page 295 // int EngineApp::PumpUntilMessage( Uint32& eventEnd, Sint32& code ) { SDL_Event event; int currentTime = timeGetTime(); for ( ;; ) { SDL_PumpEvents(); if ( SDL_PeepEvents( &event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT ) > 0 ) { // it should be the event we want if ( event.type == eventEnd ) { SDL_PeepEvents( &event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT ); eventEnd = event.user.type; code = event.user.code; break; } else { // Default processing MsgProc(); } } else { // Update the game views, but nothing else! ( actor & game logic state skipped ) // Remember this is a modal screen. if ( m_pEngineLogic ) { double fAppTime = 0.0; double fAbsoluteTime = 0.0; float fElapasedTime = 0.0f; GetGlobalTimer()->GetTimeValues( &fAppTime, &fAbsoluteTime, &fElapasedTime ); m_pEngineLogic->VOnUpdate( fAppTime, fElapasedTime ); OnFrameRender( fAppTime, fElapasedTime ); } } } return 0; }
void EngineApp::MainLoop( void ) { double fAppTime = 0.0; double fAbsoluteTime = 0.0; float fElapasedTime = 0.0f; while( true ) { MsgProc(); if( !m_bIsRunning ) { break; } GetGlobalTimer()->GetTimeValues( &fAppTime, &fAbsoluteTime, &fElapasedTime ); OnUpdateGame( fAppTime, fElapasedTime ); OnFrameRender( fAppTime, fElapasedTime ); } OnClose(); }
bool EventManager::VUpdate( unsigned long maxMs ) { unsigned long currMs = (unsigned long) ( GetGlobalTimer()->GetTime() * 1000.0 ); unsigned long targetMs = ( maxMs == kINFINITE )? kINFINITE: currMs + maxMs; // swap active queues and clear the new queue after the swap int queueToProcess = m_ActiveQueue; m_ActiveQueue = (m_ActiveQueue + 1) % EVENTMANAGER_NUM_QUEUES; m_EventQueues[m_ActiveQueue].clear(); std::string s( ( "EventLoop", "Processing Event Queue " + ToStr( queueToProcess ) + "; " + ToStr( ( unsigned long ) m_EventQueues[ queueToProcess ].size() ) + " events to process" ) ); \ Logger::Log( "EventLoop", s, NULL, NULL, 0 ); \ /*ENG_LOG("EventLoop", "Processing Event Queue " + ToStr(queueToProcess) + "; " + ToStr((unsigned long)m_EventQueues[queueToProcess].size()) + " events to process");*/ // Process the queue while ( !m_EventQueues[queueToProcess].empty() ) { // pop the front of the queue IEventPtr pEvent = m_EventQueues[queueToProcess].front(); m_EventQueues[queueToProcess].pop_front(); ENG_LOG( "EventLoop", "\t\tProcessing Event " + std::string( pEvent->GetName() ) ); const EventType& eventType = pEvent->VGetEventType(); // find all the delegate functions registered for this event auto findIt = m_EventListeners.find(eventType); if (findIt != m_EventListeners.end()) { const EventListenerList& eventListeners = findIt->second; ENG_LOG("EventLoop", "\t\tFound " + ToStr((unsigned long)eventListeners.size()) + " delegates"); // call each listener for (auto it = eventListeners.begin(); it != eventListeners.end(); ++it) { EventListenerDelegate listener = (*it); ENG_LOG("EventLoop", "\t\tSending event " + std::string(pEvent->GetName()) + " to delegate"); listener(pEvent); } } // check to see if time ran out currMs = (unsigned long) ( GetGlobalTimer()->GetTime() * 1000.0 ); if ( targetMs != IEventManager::kINFINITE && currMs >= targetMs ) { ENG_LOG("EventLoop", "Aborting event processing; time ran out"); break; } } // If we couldn't process all of the events, push the remaining events to the new active queue. // Note: To preserve sequencing, go back-to-front, inserting them at the head of the active queue bool queueFlushed = ( m_EventQueues[queueToProcess].empty() ); if ( !queueFlushed ) { while (!m_EventQueues[queueToProcess].empty()) { IEventPtr pEvent = m_EventQueues[queueToProcess].back(); m_EventQueues[queueToProcess].pop_back(); m_EventQueues[m_ActiveQueue].push_front(pEvent); } } return queueFlushed; }
bool EngineApp::InitInstance( SDL_Window* window, int screenWidth, int screenHeight ) { /*auto test = std::vector< Vec2 >( { Vec2( 1.0f, 1.0f ), Vec2( 5.0f, 5.0f ), Vec2( 4.0f, 4.0f ), Vec2( 1.0f, -3.0f ) } );*/ //auto test = std::vector< Vec2 >( { Vec2( 0.0f, 2.0f ), Vec2( 1.0f, 4.0f ), Vec2( 2.0f, 0.0f ), Vec2( 3.0f, 1.0f ), Vec2( 4.0f, 3.0f ) } ); //Triangulation( test ); // Check for existing instance of the same window // Not sure if this feature is working normally.... #ifndef _DEBUG // Note - it can be really useful to debug network code to have // more than one instance of the game up at one time - so // feel free to comment these lines in or out as you wish! if (!IsOnlyInstance( VGetGameTitle() ) ) { return false; } #endif //--------------------------------- // Check system requirements //--------------------------------- bool resourceCheck = false; while (!resourceCheck) { const DWORDLONG physicalRAM = 512 * MEGABYTE; const DWORDLONG virtualRAM = 1024 * MEGABYTE; const DWORDLONG diskSpace = 10 * MEGABYTE; if ( !CheckStorage(diskSpace) ) { return false; } const DWORD minCpuSpeed = 1300; // 1.3Ghz DWORD thisCPU = ReadCPUSpeed(); if ( thisCPU < minCpuSpeed ) { ENG_ERROR("GetCPUSpeed reports CPU is too slow for this game."); return false; } resourceCheck = true; } //--------------------------------- // Check system requirements //--------------------------------- //--------------------------------- // Initialize ResCache, all assets are within a zip file //--------------------------------- IResourceFile *pFile = NULL; if( m_EngineOptions.GetIsUsingDevDirectory() ) { pFile = ENG_NEW DevResourceFile( DevResourceFile::Editor ); } else { pFile = ENG_NEW ResourceZipFile( L"Assets.zip" ); } m_pResCache = ENG_NEW ResourceCache( 50, pFile ); if ( !m_pResCache->Init() ) { ENG_ERROR("Failed to initialize resource cache! Are your paths set up correctly?"); return false; } // extern shared_ptr<IResourceLoader> CreateWAVResourceLoader(); m_pResCache->RegisterLoader< XmlResourceLoader >(); m_pResCache->RegisterLoader< MeshResourceLoader >(); m_pResCache->RegisterLoader< TextureResourceLoader >(); m_pResCache->RegisterLoader< ScriptResourceLoader >(); if( !LoadStrings("English") ) { ENG_ERROR("Failed to load strings"); return false; } //--------------------------------- // Initialize ResCache //--------------------------------- //--------------------------------- // Initialize Lua scripting //--------------------------------- // Rez up the Lua State manager now, and run the initial script - discussed in Chapter 5, page 144. if( !LuaStateManager::GetSingleton().VInit() ) { ENG_ERROR( "Failed to initialize Lua" ); return false; } ScriptExports::Register(); Resource resource( m_EngineOptions.GetPreInitScriptFile() ); shared_ptr<ResHandle> pResourceHandle = m_pResCache->GetHandle( resource ); ENG_ASSERT( pResourceHandle ); RegisterScriptClass< AnimationClipNode, IAnimationNode >(); RegisterScriptClass< AnimationLerpNode, IAnimationNode >(); RegisterScriptClass< AnimationState >(); //--------------------------------- // Initialize Lua scripting //--------------------------------- //--------------------------------- // Initialize EventManager //--------------------------------- // Set as global EventManager m_pEventManager = ENG_NEW EventManager( "Engine Event Manager", true ); if ( !m_pEventManager ) { ENG_ERROR( "Failed to create EventManager." ); return false; } //--------------------------------- // Initialize EventManager //--------------------------------- //--------------------------------- // Initiate window & SDL, glew //--------------------------------- if ( SDL_Init(SDL_INIT_EVERYTHING) != 0 ) { ENG_ERROR( SDL_GetError() ); return false; } CHAR charTitle[100]; if( GenericToAnsiCch( charTitle, VGetGameTitle(), strlen( charTitle ) ) != S_OK ) { ENG_ERROR( "Game title translation failed" ); } if( !window ) { m_pWindow = SDL_CreateWindow( charTitle, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screenWidth,screenHeight, SDL_WINDOW_OPENGL ); if ( !m_pWindow ) { ENG_ERROR( SDL_GetError() ); return false; } } else { m_pWindow = window; } // Only if execute under editor can engine allow file drop if( m_EngineOptions.GetEngineEnvironment() == Environment_Editor ) { SDL_EventState( SDL_DROPFILE, SDL_ENABLE ); } if( m_EngineOptions.GetShowMouseCursor() ) { SDL_ShowCursor( SDL_ENABLE ); } else { SDL_ShowCursor( SDL_DISABLE ); } SDL_WarpMouseInWindow( g_pApp->GetWindow(), g_pApp->GetScreenSize().GetX() / 2, g_pApp->GetScreenSize().GetY() / 2 ); // setup opengl rendering context SDL_GLContext glContext = SDL_GL_CreateContext( m_pWindow ); if( !glContext ) { ENG_ERROR( SDL_GetError() ); } // Needed for core profile glewExperimental = true; GLenum error = glewInit(); if( error != GLEW_OK ) { ENG_ERROR( reinterpret_cast<const char *>( gluErrorString( error ) ) ); } // set two buffer for rendering SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); m_ShutDownEventType = RegisterEvent( 1 ); //--------------------------------- // Initiate window & SDL, glew //--------------------------------- //--------------------------------- // SDL_Image //--------------------------------- int initFlags= IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF; int initted = IMG_Init( initFlags ); if( ( initted & initFlags ) != initFlags ) { ENG_ERROR( IMG_GetError() ); } //--------------------------------- // SDL_Image //--------------------------------- //--------------------------------- // Set Renderer //--------------------------------- if( GetRendererImpl() == Renderer_OpenGL ) { m_pRenderer = shared_ptr<IRenderer>( ENG_NEW OpenGLRenderer() ); } else { ENG_ERROR( "Not supported renderer type" ); } m_pRenderer->VSetBackgroundColor( g_Black ); // Enable depth test glEnable( GL_DEPTH_TEST ); // Accept fragment if it closer to the camera than the former one glDepthFunc( GL_LESS ); // Cull triangles which normal is not towards the camera glEnable( GL_CULL_FACE ); m_pRenderer->VOnRestore(); //--------------------------------- // Set Renderer //--------------------------------- // Start global timer GetGlobalTimer()->Reset(); // initialize the directory location you can store save game files _tcscpy_s( m_saveGameDirectory, GetSaveGameDirectory( GetHwnd(), VGetGameAppDirectory() ) ); //--------------------------------- // Create game & view //--------------------------------- m_pEngineLogic = VCreateLogic(); if (!m_pEngineLogic) { return false; } //--------------------------------- // Create game & view //--------------------------------- m_bIsRunning = true; return true; }
void PrecisionTimer::Reset() { startCount = GetGlobalTimer(); }