CG32bitImage *CSystemMap::CreateBackgroundImage (void) // CreateBackgroundImage // // Creates an image containing the map. // Caller is responsible for freeing the returned image. { int i; CG32bitImage *pImage = g_pUniverse->GetLibraryBitmapCopy(m_dwBackgroundImage); if (pImage == NULL) return NULL; int xCenter = pImage->GetWidth() / 2; int yCenter = pImage->GetHeight() / 2; // Paint all annotations if (m_Annotations.GetCount() > 0) { SViewportPaintCtx Ctx; for (i = 0; i < m_Annotations.GetCount(); i++) { SMapAnnotation *pAnnotation = &m_Annotations[i]; Ctx.iTick = pAnnotation->iTick; Ctx.iRotation = pAnnotation->iRotation; pAnnotation->pPainter->Paint(*pImage, xCenter + pAnnotation->xOffset, yCenter - pAnnotation->yOffset, Ctx); } } #ifdef DEBUG #if 0 // Test noise function CG32bitImage Alpha; Alpha.CreateBlankAlpha(pImage->GetWidth(), pImage->GetHeight()); DrawNebulosity8bit(Alpha, 0, 0, pImage->GetWidth(), pImage->GetHeight(), 256, 0, 255); pImage->Fill(0, 0, pImage->GetWidth(), pImage->GetHeight(), 0); pImage->FillMask(0, 0, pImage->GetWidth(), pImage->GetHeight(), Alpha, CG32bitPixel(255, 255, 255), 0, 0); #endif #endif return pImage; }
void CTransmuterSession::OnPaint(CG32bitImage &Screen, const RECT &rcInvalid) { // paint the background Screen.Fill(0, 0, Screen.GetWidth(), Screen.GetHeight(), CG32bitPixel(32, 32, 32)); // make sure m_SubSessions is up-to-date with any error sessions UpdateSubSessionsList(); // call paint functions of all subsessions for (int i = 0; i < m_SubSessions.GetCount(); i++) { m_SubSessions[i]->OnPaint(Screen, rcInvalid); } }
void CSystemMap::GetBackgroundImageSize (int *retcx, int *retcy) // GetBackgroundImageSize // // Returns the size of the background image { CG32bitImage *pImage = g_pUniverse->GetLibraryBitmap(m_dwBackgroundImage); if (pImage) { *retcx = pImage->GetWidth(); *retcy = pImage->GetHeight(); } else { *retcx = 0; *retcy = 0; } }
void CGalacticMapSession::OnPaint (CG32bitImage &Screen, const RECT &rcInvalid) // OnPaint // // Paint { int cxScreen = Screen.GetWidth(); int cyScreen = Screen.GetHeight(); const CVisualPalette &VI = m_HI.GetVisuals(); CG32bitPixel rgbBackgroundColor = VI.GetColor(colorAreaDeep); CG32bitPixel rgbLineColor = VI.GetColor(colorLineFrame); const CG16bitFont &HeaderFont = VI.GetFont(fontHeader); const CG16bitFont &MediumFont = VI.GetFont(fontMedium); // Paint the actual map if (m_pPainter) { m_pPainter->Paint(Screen); // Paint the ship CSpaceObject *pPlayer = g_pUniverse->GetPlayerShip(); if (pPlayer) { int xPos, yPos; g_pUniverse->GetCurrentSystem()->GetTopology()->GetDisplayPos(&xPos, &yPos); int xShip, yShip; m_pPainter->GalacticToView(xPos, yPos, m_xCenter, m_yCenter, m_Scale.GetScale(), &xShip, &yShip); pPlayer->PaintMap(CMapViewportCtx(), Screen, xShip, yShip); } } // Paint some help text m_HelpPainter.Paint(Screen, m_rcView.left + SCREEN_BORDER_X, m_rcView.bottom - (SCREEN_BORDER_Y + m_HelpPainter.GetHeight())); }
void GenerateTopologyMap (CUniverse &Universe, CXMLElement *pCmdLine) { int i, j; STopologyMapCtx Ctx; // Initialize the output COutputChart Output; Output.SetStyleFont(STYLE_NAME, pCmdLine->GetAttribute(CONSTLIT("font"))); Output.SetStyleColor(STYLE_NAME, CG32bitPixel(0xFF, 0xFF, 0xFF)); Output.SetOutputFilespec(pCmdLine->GetAttribute(CONSTLIT("output"))); // Get the topology node CTopologyNode *pFirstNode = Universe.GetFirstTopologyNode(); if (pFirstNode == NULL) { printf("ERROR: Unable to find topology node.\n"); return; } // Get the system map for the node Ctx.pMap = pFirstNode->GetDisplayPos(); if (Ctx.pMap == NULL) { printf("ERROR: No system map for node %s.\n", pFirstNode->GetID().GetASCIIZPointer()); return; } // Create a background image CG32bitImage *pImage = Ctx.pMap->CreateBackgroundImage(); // Create the output Output.SetContentSize((pImage ? pImage->GetWidth() : 1024), (pImage ? pImage->GetHeight() : 1024)); CG32bitImage &Dest = Output.GetOutputImage(); // Blt if (pImage) Dest.Blt(0, 0, pImage->GetWidth(), pImage->GetHeight(), *pImage, 0, 0); // Done with background image delete pImage; pImage = NULL; // Compute the size of the map (in pixels) Ctx.cxMap = Dest.GetWidth(); Ctx.cyMap = Dest.GetHeight(); Ctx.xCenter = Ctx.cxMap / 2; Ctx.yCenter = Ctx.cyMap / 2; // Loop over all nodes and clear marks on the ones that we need to draw for (i = 0; i < Universe.GetTopologyNodeCount(); i++) { CTopologyNode *pNode = Universe.GetTopologyNode(i); int xPos, yPos; pNode->SetMarked(pNode->GetDisplayPos(&xPos, &yPos) != Ctx.pMap || pNode->IsEndGame()); } // Paint the nodes for (i = 0; i < Universe.GetTopologyNodeCount(); i++) { CTopologyNode *pNode = Universe.GetTopologyNode(i); if (!pNode->IsMarked()) { int xPos, yPos; pNode->GetDisplayPos(&xPos, &yPos); // Convert to view coordinates int x = Ctx.xCenter + xPos; int y = Ctx.yCenter - yPos; // Draw gate connections for (j = 0; j < pNode->GetStargateCount(); j++) { CTopologyNode *pDestNode = pNode->GetStargateDest(j); if (pDestNode && !pDestNode->IsMarked()) { int xPos, yPos; pDestNode->GetDisplayPos(&xPos, &yPos); int xDest = Ctx.xCenter + xPos; int yDest = Ctx.yCenter - yPos; Dest.DrawLine(x, y, xDest, yDest, STARGATE_LINE_WIDTH, STARGATE_LINE_COLOR); } } // Draw star system DrawNode(Ctx, Output, pNode, x, y); pNode->SetMarked(); } } // Done Output.Output(); }
void CTranscendenceWnd::CreateNewsAnimation (CMultiverseNewsEntry *pEntry, IAnimatron **retpAnimatron) // CreateNewsAnimation // // Creates animation of a Multiverse news entry. { int iDuration = 600; int iInitialFade = 30; int iEndFade = 30; // Compute some metrics for the pane based on the entry information int cxInnerPane = NEWS_PANE_WIDTH - (2 * NEWS_PANE_PADDING_X); CG32bitImage *pImage = pEntry->LoadImageHandoff(); int cyImage = (pImage ? pImage->GetHeight() : 0); TArray<CString> TitleLines; m_Fonts.SubTitle.BreakText(pEntry->GetTitle(), cxInnerPane, &TitleLines); int cyTitle = m_Fonts.SubTitle.GetHeight() * TitleLines.GetCount(); TArray<CString> BodyLines; m_Fonts.Medium.BreakText(pEntry->GetBody(), cxInnerPane, &BodyLines); int cyBody = m_Fonts.Medium.GetHeight() * BodyLines.GetCount(); TArray<CString> FooterLines; m_Fonts.MediumHeavyBold.BreakText(pEntry->GetCallToActionText(), cxInnerPane, &FooterLines); int cyFooter = m_Fonts.MediumHeavyBold.GetHeight() * FooterLines.GetCount(); int cyPane = cyImage + cyTitle + NEWS_PANE_INNER_SPACING_Y + cyBody + NEWS_PANE_INNER_SPACING_Y + cyFooter + NEWS_PANE_PADDING_Y; int xPane = m_rcIntroMain.left + (RectWidth(m_rcIntroMain) / 2) + (RectWidth(m_rcIntroMain) / 6); int yPane = m_rcIntroMain.top + ((RectHeight(m_rcIntroMain) - cyPane) / 2); // Create sequencer to hold everything The origin of the sequencer is // at the top-center of the pane. CAniSequencer *pSeq = new CAniSequencer; pSeq->SetPropertyVector(PROP_POSITION, CVector(xPane, yPane)); int xLeft = -NEWS_PANE_WIDTH / 2; // Create a button that will respond to clicks on the news pane CAniButton *pButton = new CAniButton; pButton->SetPropertyVector(PROP_POSITION, CVector(xLeft, 0)); pButton->SetPropertyVector(PROP_SCALE, CVector(NEWS_PANE_WIDTH, cyPane)); pButton->SetStyle(STYLE_DOWN, NULL); pButton->SetStyle(STYLE_HOVER, NULL); pButton->SetStyle(STYLE_NORMAL, NULL); pButton->SetStyle(STYLE_DISABLED, NULL); pButton->SetStyle(STYLE_TEXT, NULL); pButton->AddListener(EVENT_ON_CLICK, m_pIntroSession, CMD_OPEN_NEWS); pSeq->AddTrack(pButton, 0); // Create the background CAniRoundedRect *pPane = new CAniRoundedRect; pPane->SetPropertyVector(PROP_POSITION, CVector(xLeft, 0)); pPane->SetPropertyVector(PROP_SCALE, CVector(NEWS_PANE_WIDTH, cyPane)); pPane->SetPropertyColor(PROP_COLOR, RGB_NEWS_PANE_BACKGROUND); pPane->SetPropertyOpacity(PROP_OPACITY, 64); pPane->SetPropertyInteger(PROP_UL_RADIUS, NEWS_PANE_CORNER_RADIUS); pPane->SetPropertyInteger(PROP_UR_RADIUS, NEWS_PANE_CORNER_RADIUS); pPane->SetPropertyInteger(PROP_LL_RADIUS, NEWS_PANE_CORNER_RADIUS); pPane->SetPropertyInteger(PROP_LR_RADIUS, NEWS_PANE_CORNER_RADIUS); pPane->AnimateLinearFade(iDuration, iInitialFade, iEndFade, 64); pSeq->AddTrack(pPane, 0); // Add the content int yPos = 0; int xInnerLeft = -(cxInnerPane / 2); // Create the image if (pImage) { // If the image is wide enough to hit the rounded corners, then we // need to mask it out. if (pImage->GetWidth() > (NEWS_PANE_WIDTH - 2 * NEWS_PANE_CORNER_RADIUS)) { // Create a mask the size of the pane and apply it to the image // (We own the image so we can modify it). CG8bitImage PaneMask; PaneMask.CreateRoundedRect(NEWS_PANE_WIDTH, cyPane, NEWS_PANE_CORNER_RADIUS); pImage->IntersectMask(0, 0, PaneMask.GetWidth(), PaneMask.GetHeight(), PaneMask, (pImage->GetWidth() - PaneMask.GetWidth()) / 2, 0); } // Create an animatron CAniRect *pRect = new CAniRect; pRect->SetPropertyVector(PROP_POSITION, CVector(-pImage->GetWidth() / 2, yPos)); pRect->SetPropertyVector(PROP_SCALE, CVector(pImage->GetWidth(), pImage->GetHeight())); pRect->SetFillMethod(new CAniImageFill(pImage, true)); pRect->AnimateLinearFade(iDuration, iInitialFade, iEndFade); pSeq->AddTrack(pRect, 0); yPos += cyImage; } // Create the title IAnimatron *pText; CAniText::Create(pEntry->GetTitle(), CVector(xInnerLeft, yPos), &m_Fonts.SubTitle, CG16bitFont::AlignCenter, m_Fonts.rgbTitleColor, &pText); pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane)); pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade); pSeq->AddTrack(pText, 0); yPos += cyTitle + NEWS_PANE_INNER_SPACING_Y; // Create the text CAniText::Create(pEntry->GetBody(), CVector(xInnerLeft, yPos), &m_Fonts.Medium, CG16bitFont::AlignCenter, m_Fonts.rgbTitleColor, &pText); pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane)); pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade); pSeq->AddTrack(pText, 0); yPos += cyBody + NEWS_PANE_INNER_SPACING_Y; // Create the call to action CAniText::Create(pEntry->GetCallToActionText(), CVector(xInnerLeft, yPos), &m_Fonts.MediumHeavyBold, CG16bitFont::AlignCenter, m_Fonts.rgbTitleColor, &pText); pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane)); pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade); pSeq->AddTrack(pText, 0); // Remember the URL to open when the user clicks m_sNewsURL = pEntry->GetCallToActionURL(); // Done *retpAnimatron = pSeq; }
void CExtension::CreateIcon (int cxWidth, int cyHeight, CG32bitImage **retpIcon) const // CreateIcon // // Creates a cover icon for the adventure. The caller is responsible for // freeing the result. { // Load the image CG32bitImage *pBackground = GetCoverImage(); if (pBackground == NULL || pBackground->GetWidth() == 0 || pBackground->GetHeight() == 0) { int cxSize = Min(cxWidth, cyHeight); *retpIcon = new CG32bitImage; (*retpIcon)->Create(cxSize, cxSize); return; } // Figure out the dimensions of the icon based on the image size and the // desired output. // // If the background is larger than the icon size then we need to scale it. CG32bitImage *pIcon; if (pBackground->GetWidth() > cxWidth || pBackground->GetHeight() > cyHeight) { int xSrc, ySrc, cxSrc, cySrc; Metric rScale; // If we have a widescreen cover image and we want a portrait or // square icon, then we zoom in on the key part of the cover. if (pBackground->GetWidth() > 2 * pBackground->GetHeight()) { rScale = (Metric)cyHeight / pBackground->GetHeight(); cxSrc = (int)(cxWidth / rScale); xSrc = Min(pBackground->GetWidth() - cxSrc, pBackground->GetWidth() - (RIGHT_COVER_OFFSET + (cxSrc / 2))); ySrc = 0; cySrc = pBackground->GetHeight(); } else { rScale = (Metric)cxWidth / pBackground->GetWidth(); if (rScale * pBackground->GetHeight() > (Metric)cyHeight) rScale = (Metric)cyHeight / pBackground->GetHeight(); xSrc = 0; ySrc = 0; cxSrc = pBackground->GetWidth(); cySrc = pBackground->GetHeight(); } // Create the icon pIcon = new CG32bitImage; pIcon->CreateFromImageTransformed(*pBackground, xSrc, ySrc, cxSrc, cySrc, rScale, rScale, 0.0); } // Otherwise we center the image on the icon else { // Create the icon pIcon = new CG32bitImage; pIcon->Create(cxWidth, cyHeight); // Blt pIcon->Blt(0, 0, pBackground->GetWidth(), pBackground->GetHeight(), *pBackground, (cxWidth - pBackground->GetWidth()) / 2, (cyHeight - pBackground->GetHeight()) / 2); } // Done *retpIcon = pIcon; }