コード例 #1
0
void CTranscendenceWnd::Animate (bool bTopMost)

//	Animate
//
//	Called on each frame

	{
	bool bFailed = false;
	CG16bitImage &TheScreen = g_pHI->GetScreen();

	try
		{
		SetProgramState(psAnimating);

		//	Do the appropriate thing

		switch (m_State)
			{
			case gsIntro:
				AnimateIntro(bTopMost);
				break;

			case gsProlog:
				AnimateProlog(bTopMost);
				break;

			case gsInGame:
			case gsDestroyed:
				{
				DWORD dwStartTimer;
				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					dwStartTimer = ::GetTickCount();

				//	Figure out some stats

				bool bBlind = false;
				bool bSRSEnhanced = false;
				bool bShowMapHUD = false;
				CShip *pShip = NULL;
				if (GetPlayer())
					{
					pShip = GetPlayer()->GetShip();
					bBlind = pShip->IsBlind();
					bSRSEnhanced = pShip->IsSRSEnhanced();
					bShowMapHUD = GetPlayer()->IsMapHUDActive();
					}

				//	Update some displays

				if ((m_iTick % 7) == 0)
					{
					SetProgramState(psUpdatingReactorDisplay);
					m_ReactorDisplay.Update();
					SetProgramState(psAnimating);
					}

				//	If we're showing damage flash, fill the screen

				if (m_iDamageFlash > 0 && (m_iDamageFlash % 2) == 0)
					{
					TheScreen.Fill(0, 0, g_cxScreen, g_cyScreen, CG16bitImage::RGBValue(128,0,0));
					if (pShip && pShip->GetSystem())
						{
						if (m_bShowingMap)
							g_pUniverse->PaintObjectMap(TheScreen, m_rcMainScreen, pShip);
						else
							g_pUniverse->PaintObject(TheScreen, m_rcMainScreen, pShip);
						}
					}

				//	Otherwise, if we're in map mode, paint the map

				else if (m_bShowingMap)
					{
					SetProgramState(psPaintingMap);
					PaintMap();
					SetProgramState(psAnimating);
					}

				//	Otherwise, if we're blind, paint scramble

				else if (bBlind 
						&& (m_iTick % (20 + (((m_iTick / 100) * pShip->GetDestiny()) % 100))) > 15)
					PaintSRSSnow();

				//	Otherwise, paint the normal SRS screen

				else
					{
					SetProgramState(psPaintingSRS);
					g_pUniverse->PaintPOV(TheScreen, m_rcMainScreen, bSRSEnhanced);
					SetProgramState(psAnimating);

					PaintMainScreenBorder();
					}

				if (m_iDamageFlash > 0)
					m_iDamageFlash--;

				//	Paint various displays

				SetProgramState(psPaintingLRS);
				PaintLRS();

				if (!m_bShowingMap || bShowMapHUD)
					{
					SetProgramState(psPaintingArmorDisplay);
					m_ArmorDisplay.Paint(TheScreen);

					SetProgramState(psPaintingReactorDisplay);
					m_ReactorDisplay.Paint(TheScreen);

					SetProgramState(psPaintingTargetDisplay);
					m_TargetDisplay.Paint(TheScreen);

					SetProgramState(psPaintingDeviceDisplay);
					m_DeviceDisplay.Paint(TheScreen);
					}

				if (m_CurrentPicker == pickNone)
					{
					SetProgramState(psPaintingMessageDisplay);
					m_MessageDisplay.Paint(TheScreen);
					}

				SetProgramState(psAnimating);

				if (m_CurrentMenu != menuNone)
					m_MenuDisplay.Paint(TheScreen);
				if (m_CurrentPicker != pickNone)
					m_PickerDisplay.Paint(TheScreen);
				if (m_bDebugConsole)
					m_DebugConsole.Paint(TheScreen);

#ifdef DEBUG_LINE_OF_FIRE
				if (GetPlayer())
					{
					if (!GetPlayer()->GetShip()->IsLineOfFireClear(GetPlayer()->GetShip()->GetPos(),
							NULL,
							GetPlayer()->GetShip()->GetRotation()))
						g_pUniverse->DebugOutput("line of fire blocked");
					}
#endif
#ifdef DEBUG
				PaintDebugLines();
#endif

				//	Figure out how long it took to paint

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					{
					DWORD dwNow = ::GetTickCount();
					m_iPaintTime[m_iFrameCount % FRAME_RATE_COUNT] = dwNow - dwStartTimer;
					dwStartTimer = dwNow;
					}

				//	Some debug information

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					PaintFrameRate();

				//	Update the screen

				if (bTopMost)
					g_pHI->GetScreenMgr().Blt();

				//	Figure out how long it took to blt

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					{
					DWORD dwNow = ::GetTickCount();
					m_iBltTime[m_iFrameCount % FRAME_RATE_COUNT] = dwNow - dwStartTimer;
					dwStartTimer = dwNow;
					}

				//	Update the universe

				if (!m_bPaused || m_bPausedStep)
					{
					SetProgramState(psUpdating);
					g_pUniverse->Update(g_SecondsPerUpdate);
					if (m_bAutopilot)
						{
						g_pUniverse->Update(g_SecondsPerUpdate);
						g_pUniverse->Update(g_SecondsPerUpdate);
						g_pUniverse->Update(g_SecondsPerUpdate);
						g_pUniverse->Update(g_SecondsPerUpdate);
						}
					SetProgramState(psAnimating);

					if (GetPlayer())
						GetPlayer()->Update(m_iTick);
					if (GetPlayer() && GetPlayer()->GetSelectedTarget())
						m_TargetDisplay.Invalidate();
					m_iTick++;

					m_bPausedStep = false;
					}

				m_MessageDisplay.Update();

				//	Figure out how long it took to update

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					{
					DWORD dwNow = ::GetTickCount();
					m_iUpdateTime[m_iFrameCount % FRAME_RATE_COUNT] = dwNow - dwStartTimer;
					dwStartTimer = dwNow;
					}

				//	Destroyed?

				if (m_State == gsDestroyed)
					{
					if (!m_bPaused || m_bPausedStep)
						{
						if (--m_iCountdown == 0)
							g_pHI->HICommand(CONSTLIT("gameEndDestroyed"));
						m_bPausedStep = false;
						}
					}

				break;
				}

			case gsDocked:
				{
				//	Paint the screen

				m_pCurrentScreen->Paint(TheScreen);
				m_pCurrentScreen->Update();
				PaintMainScreenBorder();
				m_ArmorDisplay.Paint(TheScreen);
				m_TargetDisplay.Paint(TheScreen);

				//	Debug console

				if (m_bDebugConsole)
					m_DebugConsole.Paint(TheScreen);

				//	We don't paint the LRS because the player doesn't need it and
				//	because it overwrites the credits/cargo space display
				//PaintLRS();

				//	Update the screen

				if (bTopMost)
					g_pHI->GetScreenMgr().Blt();

				//	Update the universe (at 1/4 rate)

				if ((m_iTick % 4) == 0)
					g_pUniverse->Update(g_SecondsPerUpdate);
				m_MessageDisplay.Update();
				m_CurrentDock.Update(m_iTick);
				m_iTick++;

				//	Invalidate areas of the screen that are overlapped by
				//	the displays. Note that we need to convert to main screen
				//	coordinates.

				if (m_pCurrentScreen)
					{
					RECT rcRect = m_ArmorDisplay.GetRect();
					::OffsetRect(&rcRect, -m_rcMainScreen.left, -m_rcMainScreen.top);
					m_pCurrentScreen->Invalidate(rcRect);

					rcRect = m_TargetDisplay.GetRect();
					::OffsetRect(&rcRect, -m_rcMainScreen.left, -m_rcMainScreen.top);
					m_pCurrentScreen->Invalidate(rcRect);

					rcRect = m_rcLRS;
					::OffsetRect(&rcRect, -m_rcMainScreen.left, -m_rcMainScreen.top);
					m_pCurrentScreen->Invalidate(rcRect);

					if (m_bDebugConsole)
						{
						rcRect = m_DebugConsole.GetRect();
						::OffsetRect(&rcRect, -m_rcMainScreen.left, -m_rcMainScreen.top);
						m_pCurrentScreen->Invalidate(rcRect);
						}
					}

				break;
				}

			case gsEnteringStargate:
				{
				//	Update some displays

				if ((m_iTick % 10) == 0)
					m_ReactorDisplay.Update();

				//	Tell the universe to paint

				g_pUniverse->PaintPOV(TheScreen, m_rcMainScreen, false);
				PaintMainScreenBorder();
				PaintLRS();
				m_ArmorDisplay.Paint(TheScreen);
				m_MessageDisplay.Paint(TheScreen);
				m_ReactorDisplay.Paint(TheScreen);
				m_TargetDisplay.Paint(TheScreen);
				m_DeviceDisplay.Paint(TheScreen);

				//	Debug information

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					PaintFrameRate();

#ifdef DEBUG
				PaintDebugLines();
#endif

				//	Update the screen

				if (bTopMost)
					g_pHI->GetScreenMgr().Blt();

				//	Update the universe

				g_pUniverse->Update(g_SecondsPerUpdate);
				m_MessageDisplay.Update();
				m_iTick++;

				if (--m_iCountdown == 0)
					EnterStargate();
				break;
				}

			case gsLeavingStargate:
				{
				//	Update some displays

				if ((m_iTick % 10) == 0)
					m_ReactorDisplay.Update();

				//	Tell the universe to paint

				g_pUniverse->PaintPOV(TheScreen, m_rcMainScreen, false);
				PaintMainScreenBorder();
				PaintLRS();
				m_ArmorDisplay.Paint(TheScreen);
				m_MessageDisplay.Paint(TheScreen);
				m_ReactorDisplay.Paint(TheScreen);
				m_TargetDisplay.Paint(TheScreen);
				m_DeviceDisplay.Paint(TheScreen);

				//	Debug information

				if (m_pTC->GetOptionBoolean(CGameSettings::debugVideo))
					PaintFrameRate();

#ifdef DEBUG
				PaintDebugLines();
#endif

				//	Update the screen

				if (bTopMost)
					g_pHI->GetScreenMgr().Blt();

				//	Update the universe

				g_pUniverse->Update(g_SecondsPerUpdate);
				m_MessageDisplay.Update();
				m_iTick++;

				if (--m_iCountdown == 0)
					LeaveStargate();
				break;
				}
			}

		//	Flip

		if (bTopMost)
			g_pHI->GetScreenMgr().Flip();

		SetProgramState(psUnknown);
		}
	catch (...)
		{
		bFailed = true;
		}

	//	Deal with errors/crashes

	if (bFailed)
		{
		g_pHI->GetScreenMgr().StopDX();
		ReportCrash();
		}
	}
コード例 #2
0
void CArmorDisplay::Update (void)

//	Update
//
//	Updates buffer from data

	{
	int i;

	if (m_pPlayer == NULL)
		return;

	CShip *pShip = m_pPlayer->GetShip();
	const CPlayerSettings *pSettings = pShip->GetClass()->GetPlayerSettings();
	CItemListManipulator ItemList(pShip->GetItemList());
	const CG16bitFont &SmallFont = m_pPlayer->GetTrans()->GetFonts().Small;
	m_Text.DeleteAll();

	//	If we've changed ships then we need to delete the painters

	if (m_dwCachedShipID != pShip->GetID())
		{
		if (m_pShieldPainter)
			{
			m_pShieldPainter->Delete();
			m_pShieldPainter = NULL;
			}

		m_dwCachedShipID = pShip->GetID();
		}

	//	Erase everything

	m_Buffer.Fill(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, DEFAULT_TRANSPARENT_COLOR);

	//	Figure out the status of the shields

	int iHP = 0;
	int iMaxHP = 10;
	CInstalledDevice *pShield = pShip->GetNamedDevice(devShields);
	if (pShield)
		pShield->GetStatus(pShip, &iHP, &iMaxHP);

	//	Draw the base ship image, if we have it

	const SArmorImageDesc &ArmorDesc = pSettings->GetArmorDesc();
	if (!ArmorDesc.ShipImage.IsEmpty())
		{
		const RECT &rcShip = ArmorDesc.ShipImage.GetImageRect();

		m_Buffer.ColorTransBlt(rcShip.left, 
				rcShip.top, 
				RectWidth(rcShip), 
				RectHeight(rcShip), 
				255,
				ArmorDesc.ShipImage.GetImage(NULL_STR), 
				DESCRIPTION_WIDTH + ((SHIELD_IMAGE_WIDTH - RectWidth(rcShip)) / 2),
				(SHIELD_IMAGE_HEIGHT - RectHeight(rcShip)) / 2);
		}

	//	Draw the old-style shields

	const SShieldImageDesc &ShieldDesc = pSettings->GetShieldDesc();
	if (!ShieldDesc.pShieldEffect)
		{
		int iWhole = (iMaxHP > 0 ? (iHP * 100) / iMaxHP : 100);
		int iIndex = (100 - iWhole) / 20;

		const RECT &rcShield = ShieldDesc.Image.GetImageRect();
		m_Buffer.ColorTransBlt(rcShield.left, 
				rcShield.top + (RectHeight(rcShield) * iIndex), 
				RectWidth(rcShield), 
				RectHeight(rcShield), 
				255,
				ShieldDesc.Image.GetImage(NULL_STR), 
				DESCRIPTION_WIDTH + ((SHIELD_IMAGE_WIDTH - RectWidth(rcShield)) / 2),
				(SHIELD_IMAGE_HEIGHT - RectHeight(rcShield)) / 2);
		}

	if (pShield)
		{
		m_Buffer.Fill(SHIELD_HP_DISPLAY_X,
				SHIELD_HP_DISPLAY_Y, 
				SHIELD_HP_DISPLAY_WIDTH, 
				SHIELD_HP_DISPLAY_HEIGHT,
				SHIELD_HP_DISPLAY_BACK_COLOR);
		
		CString sHP = strFromInt(iHP);
		int cxWidth = m_pFonts->Medium.MeasureText(sHP, NULL);
		m_pFonts->Medium.DrawText(m_Buffer,
				SHIELD_HP_DISPLAY_X + (SHIELD_HP_DISPLAY_WIDTH - cxWidth) / 2,
				SHIELD_HP_DISPLAY_Y - 1,
				CG16bitImage::LightenPixel(m_pFonts->wAltGreenColor, 60),
				sHP);

		DrawBrokenLine(m_Buffer,
				0,
				SHIELD_HP_DISPLAY_Y,
				SHIELD_HP_DISPLAY_X,
				SHIELD_HP_DISPLAY_Y,
				0,
				SHIELD_HP_DISPLAY_LINE_COLOR);

		WORD wColor;
		if (pShield->IsEnabled() && !pShield->IsDamaged() && !pShield->IsDisrupted())
			wColor = m_pFonts->wAltGreenColor;
		else
			wColor = DISABLED_TEXT_COLOR;

		CString sShieldName = pShield->GetClass()->GetName();
		int cyHeight;
		cxWidth = m_pFonts->Medium.MeasureText(sShieldName, &cyHeight);

		//	Add the shield name to list of text to paint

		STextPaint *pPaint = m_Text.Insert();
		pPaint->sText = sShieldName;
		pPaint->x = 0;
		pPaint->y = SHIELD_HP_DISPLAY_Y;
		pPaint->pFont = &m_pFonts->Medium;
		pPaint->wColor = wColor;

		//	Paint the modifiers

		if (pShield->GetMods().IsNotEmpty() || pShield->GetBonus() != 0)
			{
			pShip->SetCursorAtNamedDevice(ItemList, devShields);
			CString sMods = pShield->GetEnhancedDesc(pShip, &ItemList.GetItemAtCursor());
			if (!sMods.IsBlank())
				{
				bool bDisadvantage = (*(sMods.GetASCIIZPointer()) == '-');

				int cx = SmallFont.MeasureText(sMods);
				m_Buffer.Fill(SHIELD_HP_DISPLAY_X - cx - 8,
						SHIELD_HP_DISPLAY_Y,
						cx + 8,
						SHIELD_HP_DISPLAY_HEIGHT,
						(bDisadvantage ? ARMOR_DAMAGED_BACK_COLOR : ARMOR_ENHANCE_BACK_COLOR));

				SmallFont.DrawText(m_Buffer,
						SHIELD_HP_DISPLAY_X - cx - 4,
						SHIELD_HP_DISPLAY_Y + (SHIELD_HP_DISPLAY_HEIGHT - SmallFont.GetHeight()) / 2,
						(bDisadvantage ? ARMOR_DAMAGED_TEXT_COLOR : ARMOR_ENHANCE_TEXT_COLOR),
						sMods);
				}
			}
		}

	//	Draw armor

	int iArmorCount = Min(pShip->GetArmorSectionCount(), pSettings->GetArmorDescCount());
	for (i = 0; i < iArmorCount; i++)
		{
		const SArmorSegmentImageDesc *pImage = &pSettings->GetArmorDesc(i);

		CInstalledArmor *pArmor = pShip->GetArmorSection(i);
		int iMaxHP = pArmor->GetMaxHP(pShip);
		int iWhole = (iMaxHP == 0 ? 100 : (pArmor->GetHitPoints() * 100) / iMaxHP);
		int iIndex = (100 - iWhole) / 20;
		
		if (iIndex < 5)
			{
			const RECT &rcImage = pImage->Image.GetImageRect();
			m_Buffer.ColorTransBlt(rcImage.left,
					rcImage.top + iIndex * RectHeight(rcImage),
					RectWidth(rcImage),
					RectHeight(rcImage),
					255,
					pImage->Image.GetImage(NULL_STR),
					DESCRIPTION_WIDTH + pImage->xDest,
					pImage->yDest);
			}
		}

	//	Draw the new style shields on top

	if (ShieldDesc.pShieldEffect)
		{
		int x = DESCRIPTION_WIDTH + SHIELD_IMAGE_WIDTH / 2;
		int y = SHIELD_IMAGE_HEIGHT / 2;

		SViewportPaintCtx Ctx;
		Ctx.iTick = g_pUniverse->GetTicks();
		Ctx.iVariant = (iMaxHP > 0 ? (iHP * 100) / iMaxHP : 0);
		Ctx.iDestiny = pShip->GetDestiny();
		Ctx.iRotation = 90;

		if (m_pShieldPainter == NULL)
			m_pShieldPainter = ShieldDesc.pShieldEffect->CreatePainter();

		m_pShieldPainter->Paint(m_Buffer, x, y, Ctx);
		}

	//	Draw armor names

	for (i = 0; i < iArmorCount; i++)
		{
		const SArmorSegmentImageDesc *pImage = &pSettings->GetArmorDesc(i);
		CInstalledArmor *pArmor = pShip->GetArmorSection(i);

		//	Paint the HPs

		if (i == m_iSelection)
			{
			m_Buffer.Fill(DESCRIPTION_WIDTH + pImage->xHP - 1, 
					pImage->yHP - 1, 
					HP_DISPLAY_WIDTH + 2, 
					HP_DISPLAY_HEIGHT + 2,
					CG16bitImage::DarkenPixel(m_pFonts->wSelectBackground, 128));
			}
		else
			{
			m_Buffer.Fill(DESCRIPTION_WIDTH + pImage->xHP, 
					pImage->yHP, 
					HP_DISPLAY_WIDTH, 
					HP_DISPLAY_HEIGHT,
					HP_DISPLAY_BACK_COLOR);
			}

		CString sHP = strFromInt(pArmor->GetHitPoints());
		int cxWidth = m_pFonts->Medium.MeasureText(sHP, NULL);
		m_pFonts->Medium.DrawText(m_Buffer,
				DESCRIPTION_WIDTH + pImage->xHP + (HP_DISPLAY_WIDTH - cxWidth) / 2,
				pImage->yHP - 1,
				m_pFonts->wTitleColor,
				sHP);

		//	Paint the armor name line

		DrawBrokenLine(m_Buffer,
				0,
				pImage->yName + m_pFonts->Medium.GetHeight(),
				DESCRIPTION_WIDTH + pImage->xHP + pImage->xNameDestOffset,
				pImage->yHP + pImage->yNameDestOffset,
				pImage->cxNameBreak,
				(i == m_iSelection ? CG16bitImage::DarkenPixel(m_pFonts->wSelectBackground, 128) : ARMOR_LINE_COLOR));

		//	Paint the armor names

		CString sName = pArmor->GetClass()->GetShortName();
		int cy;
		int cx = m_pFonts->Medium.MeasureText(sName, &cy) + 4;
		if (i == m_iSelection)
			{
			m_Buffer.Fill(0, 
					pImage->yName, 
					cx, 
					cy,
					CG16bitImage::DarkenPixel(m_pFonts->wSelectBackground, 128));
			}

		STextPaint *pPaint = m_Text.Insert();
		pPaint->sText = sName;
		pPaint->x = 2;
		pPaint->y = pImage->yName;
		pPaint->pFont = &m_pFonts->Medium;
		pPaint->wColor = m_pFonts->wTitleColor;

		//	Paint the modifiers

		if (pArmor->GetMods().IsNotEmpty())
			{
			pShip->SetCursorAtArmor(ItemList, i);
			CString sMods = ItemList.GetItemAtCursor().GetEnhancedDesc(pShip);
			if (!sMods.IsBlank())
				{
				int cx = SmallFont.MeasureText(sMods);
				m_Buffer.Fill(ARMOR_ENHANCE_X - cx - 4,
						pImage->yName + m_pFonts->Medium.GetHeight() - HP_DISPLAY_HEIGHT,
						cx + 8,
						HP_DISPLAY_HEIGHT,
						ARMOR_ENHANCE_BACK_COLOR);

				SmallFont.DrawText(m_Buffer,
						ARMOR_ENHANCE_X - cx,
						pImage->yName + 3,
						ARMOR_ENHANCE_TEXT_COLOR,
						sMods);
				}
			}
		}
	}