void CLocalGUI::Draw ( void ) { // Get the game interface CGame* pGame = CCore::GetSingleton ().GetGame (); eSystemState SystemState = pGame->GetSystemState (); CGUI* pGUI = CCore::GetSingleton ().GetGUI (); // Update mainmenu stuff m_pMainMenu->Update (); // Make sure our version labels are always visible static short WaitForMenu = 0; // Cope with early finish if ( pGame->HasCreditScreenFadedOut () ) WaitForMenu = 250; if ( SystemState == 7 || SystemState == 9 ) { if ( WaitForMenu < 250 ) { WaitForMenu++; } else { m_pLabelVersionTag->SetVisible ( true ); if ( MTASA_VERSION_TYPE < VERSION_TYPE_RELEASE ) m_pLabelVersionTag->SetAlwaysOnTop ( true ); } } // If we're ingame, make sure the chatbox is drawn bool bChatVisible = ( SystemState == 9 /* GS_INGAME */ && m_pMainMenu->GetIsIngame () && m_bChatboxVisible && !CCore::GetSingleton ().IsOfflineMod() ); if ( m_pChat->IsVisible () != bChatVisible ) m_pChat->SetVisible ( bChatVisible ); bool bDebugVisible = ( SystemState == 9 /* GS_INGAME */ && m_pMainMenu->GetIsIngame () && m_pDebugViewVisible && !CCore::GetSingleton ().IsOfflineMod() ); if ( m_pDebugView->IsVisible () != bDebugVisible ) m_pDebugView->SetVisible ( bDebugVisible ); // Make sure the cursor is displayed only when needed UpdateCursor (); // Draw the chat m_pChat->Draw ( true ); // Draw the debugger m_pDebugView->Draw ( false ); // If we're not at the loadingscreen static bool bDelayedFrame = false; if ( SystemState != 8 || !bDelayedFrame /* GS_INIT_PLAYING_GAME */ ) { // If we have a GUI manager, draw the GUI if ( pGUI ) { pGUI->Draw ( ); } else { WriteDebugEvent ( "WARNING: CLocalGUI::Draw() called, but CLocalGUI::CreateObjects() isn't!" ); } // If the system state was 8, make sure we don't do another delayed frame if ( SystemState == 8 ) { bDelayedFrame = true; } } }
void CMainMenu::Update(void) { if (g_pCore->GetDiagnosticDebug() == EDiagnosticDebug::JOYSTICK_0000) { m_pFiller->SetVisible(false); m_pFiller2->SetVisible(false); m_pBackground->SetVisible(false); m_bHideGame = false; } if (m_bFrameDelay) { m_bFrameDelay = false; return; } // Get the game interface and the system state CGame* pGame = CCore::GetSingleton().GetGame(); eSystemState SystemState = pGame->GetSystemState(); m_Credits.Update(); m_Settings.Update(); unsigned long ulCurrentTick = GetTickCount32(); unsigned long ulTimePassed = ulCurrentTick - ulPreviousTick; if (m_bHideGame) m_pGraphics->DrawRectangle(0, 0, m_ScreenSize.fX, m_ScreenSize.fY, 0xFF000000); if (m_bIsIngame) // CEGUI hack { float fAlpha = m_pDisconnect->image->GetAlpha(); m_pDisconnect->image->SetAlpha(0.35f); m_pDisconnect->image->SetAlpha(fAlpha); } if (m_bIsFullyVisible) { // Grab our cursor position tagPOINT cursor; GetCursorPos(&cursor); HWND hookedWindow = CCore::GetSingleton().GetHookedWindow(); tagPOINT windowPos = {0}; ClientToScreen(hookedWindow, &windowPos); CVector2D vecResolution = CCore::GetSingleton().GetGUI()->GetResolution(); cursor.x -= windowPos.x; cursor.y -= windowPos.y; if (cursor.x < 0) cursor.x = 0; else if (cursor.x > (long)vecResolution.fX) cursor.x = (long)vecResolution.fX; if (cursor.y < 0) cursor.y = 0; else if (cursor.y > (long)vecResolution.fY) cursor.y = (long)vecResolution.fY; // If we're within our highlight bounding box if (m_bMouseOverMenu && (cursor.x > m_menuAX) && (cursor.y > m_menuAY + BODGE_FACTOR_3) && (cursor.x < m_menuBX) && (cursor.y < m_menuBY + BODGE_FACTOR_4)) { float fHoveredIndex = ((cursor.y - m_menuAY) / (float)(m_menuBY - m_menuAY) * m_menuItems.size()); fHoveredIndex = Clamp<float>(0, fHoveredIndex, m_menuItems.size() - 1); sMenuItem* pItem = m_menuItems[(int)floor(fHoveredIndex)]; int iSizeX = (pItem->nativeSizeX / NATIVE_RES_X) * m_iMenuSizeX; if (cursor.x < (iSizeX + m_menuAX)) { if ((m_pHoveredItem) && (m_pHoveredItem != pItem)) { m_unhoveredItems.insert(m_pHoveredItem); m_pHoveredItem = pItem; } else { m_pHoveredItem = NULL; } m_pHoveredItem = pItem; } else if (m_pHoveredItem) { m_unhoveredItems.insert(m_pHoveredItem); m_pHoveredItem = NULL; } if (m_pHoveredItem) { float fProgress = (m_pHoveredItem->image->GetAlpha() - CORE_MTA_NORMAL_ALPHA) / (CORE_MTA_HOVER_ALPHA - CORE_MTA_NORMAL_ALPHA); // Let's work out what the target progress should be by working out the time passed fProgress = ((float)ulTimePassed / CORE_MTA_ANIMATION_TIME) * (CORE_MTA_HOVER_ALPHA - CORE_MTA_NORMAL_ALPHA) + fProgress; MapRemove(m_unhoveredItems, m_pHoveredItem); SetItemHoverProgress(m_pHoveredItem, fProgress, true); } } else if (m_pHoveredItem) { m_unhoveredItems.insert(m_pHoveredItem); m_pHoveredItem = NULL; } // Let's unhover our recently un-moused over items std::set<sMenuItem*>::iterator it = m_unhoveredItems.begin(); while (it != m_unhoveredItems.end()) { float fProgress = ((*it)->image->GetAlpha() - CORE_MTA_NORMAL_ALPHA) / (CORE_MTA_HOVER_ALPHA - CORE_MTA_NORMAL_ALPHA); // Let's work out what the target progress should be by working out the time passed // Min of 0.5 progress fixes occasional graphical glitchekal fProgress = fProgress - std::min(0.5f, ((float)ulTimePassed / CORE_MTA_ANIMATION_TIME) * (CORE_MTA_HOVER_ALPHA - CORE_MTA_NORMAL_ALPHA)); if (SetItemHoverProgress((*it), fProgress, false)) { std::set<sMenuItem*>::iterator itToErase = it++; m_unhoveredItems.erase(itToErase); } else it++; } } if (m_iMoveStartPos) { float fTickDifference = ulCurrentTick - m_ulMoveStartTick; float fMoveTime = (fTickDifference / CORE_MTA_MOVE_ANIM_TIME); fMoveTime = Clamp<float>(0, fMoveTime, 1); // Use OutQuad easing to smoothen the movement fMoveTime = -fMoveTime * (fMoveTime - 2); SetMenuVerticalPosition(fMoveTime * (m_iMoveTargetPos - m_iMoveStartPos) + m_iMoveStartPos); m_pDisconnect->image->SetAlpha(m_bIsIngame ? fMoveTime * CORE_MTA_NORMAL_ALPHA : (1 - fMoveTime) * CORE_MTA_NORMAL_ALPHA); if (fMoveTime == 1) { m_iMoveStartPos = 0; if (!m_bIsIngame) m_pDisconnect->image->SetVisible(false); else { m_menuItems.push_front(m_pDisconnect); m_pDisconnect->image->SetVisible(true); float fTopItemSize = m_pDisconnect->image->GetSize(false).fY; float fTopItemCentre = m_pDisconnect->image->GetPosition(false).fY + fTopItemSize * 0.5f; m_menuAY = fTopItemCentre - fTopItemSize * (CORE_MTA_HOVER_SCALE / CORE_MTA_NORMAL_SCALE) * 0.5f; // Top side of the items m_menuAY += BODGE_FACTOR_1; m_pMenuArea->SetPosition(CVector2D(m_menuAX - m_iXOff, m_menuAY - m_iYOff) + BODGE_FACTOR_5, false); m_pMenuArea->SetSize(CVector2D(m_menuBX - m_menuAX, m_menuBY - m_menuAY) + BODGE_FACTOR_6, false); } } } // Fade in if (m_ucFade == FADE_IN) { // Increment the fader (use the other define if we're fading to the credits) m_fFader += CORE_MTA_FADER; float fFadeTarget = m_bIsIngame ? CORE_MTA_BG_INGAME_ALPHA : CORE_MTA_BG_MAX_ALPHA; m_pFiller->SetAlpha(Clamp<float>(0.f, m_fFader, CORE_MTA_BG_MAX_ALPHA)); m_pFiller2->SetAlpha(Clamp<float>(0.f, m_fFader, CORE_MTA_BG_MAX_ALPHA)); m_pCanvas->SetAlpha(Clamp<float>(0.f, m_fFader, CORE_MTA_BG_MAX_ALPHA)); m_pBackground->SetAlpha(Clamp<float>(0.f, m_fFader, CORE_MTA_BG_MAX_ALPHA)); if (m_fFader > 0.0f) { m_bIsVisible = true; // Make cursor appear faster } // If the fade is complete if (m_fFader >= fFadeTarget) { m_ucFade = FADE_VISIBLE; m_bIsVisible = true; m_bIsFullyVisible = true; } } // Fade out else if (m_ucFade == FADE_OUT) { m_fFader -= CORE_MTA_FADER; m_pFiller->SetAlpha(Clamp(0.f, m_fFader, CORE_MTA_BG_MAX_ALPHA)); m_pFiller2->SetAlpha(Clamp(0.f, m_fFader, CORE_MTA_BG_MAX_ALPHA)); m_pCanvas->SetAlpha(Clamp(0.f, m_fFader, CORE_MTA_BG_MAX_ALPHA)); m_pBackground->SetAlpha(Clamp(0.f, m_fFader, CORE_MTA_BG_MAX_ALPHA)); if (m_fFader < 1.0f) m_bIsVisible = false; // Make cursor disappear faster // If the fade is complete if (m_fFader <= 0) { m_bIsFullyVisible = false; m_ucFade = FADE_INVISIBLE; m_bIsVisible = false; // Turn the widgets invisible m_pFiller->SetVisible(false); m_pFiller2->SetVisible(false); m_pCanvas->SetVisible(false); m_pBackground->SetVisible(false); } } // Force the mainmenu on if we're at GTA's mainmenu or not ingame if ((SystemState == 7 || SystemState == 9) && !m_bIsIngame) { // Cope with early finish if (pGame->HasCreditScreenFadedOut()) WaitForMenu = std::max(WaitForMenu, 250); // Fade up if (WaitForMenu >= 250) { m_bIsVisible = true; m_bStarted = true; } // Create headlines while the screen is still black if (WaitForMenu == 250) m_pNewsBrowser->CreateHeadlines(); // Start updater after fade up is complete if (WaitForMenu == 275) GetVersionUpdater()->EnableChecking(true); if (WaitForMenu < 300) WaitForMenu++; } // If we're visible if (m_bIsVisible && SystemState != 8) { // If we're at the game's mainmenu, or ingame when m_bIsIngame is true show the background if (SystemState == 7 || // GS_FRONTEND SystemState == 9 && !m_bIsIngame) // GS_PLAYING_GAME { if (m_ucFade == FADE_INVISIBLE) Show(false); } else { if (m_ucFade == FADE_INVISIBLE) Show(true); } } else { if (m_ucFade == FADE_VISIBLE) Hide(); } ulPreviousTick = GetTickCount32(); // Call subdialog pulses m_ServerBrowser.Update(); m_ServerInfo.DoPulse(); }