bool IDockScreenDisplay::GetDisplayOptions (SInitCtx &Ctx, SDisplayOptions *retOptions, CString *retsError) // GetDisplayOptions // // Initializes the display options structure, which is used by list and // selector displays. { // Initialize background image options CString sBackgroundID; if (Ctx.pDesc->FindAttribute(BACKGROUND_ID_ATTRIB, &sBackgroundID)) { // If the attribute exists, but is empty (or equals "none") then // we don't have a background if (sBackgroundID.IsBlank() || strEquals(sBackgroundID, CONSTLIT("none"))) retOptions->BackgroundDesc.iType = backgroundNone; else if (strEquals(sBackgroundID, TYPE_HERO)) { retOptions->BackgroundDesc.iType = backgroundObjHeroImage; retOptions->BackgroundDesc.pObj = Ctx.pLocation; } // If the ID is "object" then we should ask the object else if (strEquals(sBackgroundID, TYPE_OBJECT)) { retOptions->BackgroundDesc.pObj = Ctx.pLocation; if (Ctx.pLocation->IsPlayer()) retOptions->BackgroundDesc.iType = backgroundObjSchematicImage; else retOptions->BackgroundDesc.iType = backgroundObjHeroImage; } else if (strEquals(sBackgroundID, TYPE_SCHEMATIC)) { retOptions->BackgroundDesc.iType = backgroundObjSchematicImage; retOptions->BackgroundDesc.pObj = Ctx.pLocation; } // If the ID is "player" then we should ask the player ship else if (strEquals(sBackgroundID, DATA_FROM_PLAYER)) { CSpaceObject *pPlayer = g_pUniverse->GetPlayerShip(); if (pPlayer) { retOptions->BackgroundDesc.iType = backgroundObjSchematicImage; retOptions->BackgroundDesc.pObj = pPlayer; } } // Otherwise, we expect an integer else { retOptions->BackgroundDesc.iType = backgroundImage; retOptions->BackgroundDesc.dwImageID = strToInt(sBackgroundID, 0); } } // Initialize control rect. If we have a background, then initialize to // backwards compatible position. Otherwise, we take up the full range. if (retOptions->BackgroundDesc.iType != backgroundDefault) { retOptions->rcControl.left = 4; retOptions->rcControl.top = 12; retOptions->rcControl.right = 548; retOptions->rcControl.bottom = 396; } else { retOptions->rcControl.left = 0; retOptions->rcControl.top = 23; retOptions->rcControl.right = 600; retOptions->rcControl.bottom = 482; } // There are a couple of different ways to get options (for backwards // compatibility). CXMLElement *pOptions; if ((pOptions = Ctx.pDesc->GetContentElementByTag(LIST_OPTIONS_TAG)) == NULL && (pOptions = Ctx.pDesc->GetContentElementByTag(LIST_TAG)) == NULL) return true; // Read from the element retOptions->sDataFrom = pOptions->GetAttribute(DATA_FROM_ATTRIB); retOptions->sItemCriteria = pOptions->GetAttribute(LIST_ATTRIB); retOptions->sCode = pOptions->GetContentText(0); retOptions->sInitialItemCode = pOptions->GetAttribute(INITIAL_ITEM_ATTRIB); retOptions->sRowHeightCode = pOptions->GetAttribute(ROW_HEIGHT_ATTRIB); // See if we have control position if (pOptions->FindAttributeInteger(POS_X_ATTRIB, (int *)&retOptions->rcControl.left)) { retOptions->rcControl.top = pOptions->GetAttributeIntegerBounded(POS_Y_ATTRIB, 0, -1); retOptions->rcControl.right = retOptions->rcControl.left + pOptions->GetAttributeIntegerBounded(WIDTH_ATTRIB, 0, -1); retOptions->rcControl.bottom = retOptions->rcControl.top + pOptions->GetAttributeIntegerBounded(HEIGHT_ATTRIB, 0, -1); } return true; }
void CDockingPorts::InitPortsFromXML (CSpaceObject *pOwner, CXMLElement *pElement) // InitPortsFromXML // // InitPortsFromXML { int i; // See if we've got a special element with docking port geometry CXMLElement *pDockingPorts = pElement->GetContentElementByTag(DOCKING_PORTS_TAG); if (pDockingPorts) { // Initialize max dist // NOTE: pOwner can be NULL because sometimes we init ports from a ship class // (without an object). int iDefaultDist = Max(DEFAULT_DOCK_DISTANCE_LS, (pOwner ? 8 + (int)((pOwner->GetBoundsRadius() / LIGHT_SECOND) + 0.5) : 0)); m_iMaxDist = pDockingPorts->GetAttributeIntegerBounded(MAX_DIST_ATTRIB, 1, -1, iDefaultDist); // If we have sub-elements then these are port definitions. m_iPortCount = pDockingPorts->GetContentElementCount(); if (m_iPortCount > 0) { m_pPort = new SDockingPort[m_iPortCount]; for (i = 0; i < m_iPortCount; i++) { CXMLElement *pPort = pDockingPorts->GetContentElement(i); CVector vDockPos((pPort->GetAttributeInteger(X_ATTRIB) * g_KlicksPerPixel), (pPort->GetAttributeInteger(Y_ATTRIB) * g_KlicksPerPixel)); m_pPort[i].vPos = vDockPos; if (pPort->FindAttributeInteger(ROTATION_ATTRIB, &m_pPort[i].iRotation)) m_pPort[i].iRotation = (m_pPort[i].iRotation % 360); else m_pPort[i].iRotation = (VectorToPolar(vDockPos) + 180) % 360; if (pPort->GetAttributeBool(BRING_TO_FRONT_ATTRIB)) m_pPort[i].iLayer = plBringToFront; else if (pPort->GetAttributeBool(SEND_TO_BACK_ATTRIB)) m_pPort[i].iLayer = plSendToBack; } } // Otherwise, we expect a port count and radius else if ((m_iPortCount = pDockingPorts->GetAttributeIntegerBounded(PORT_COUNT_ATTRIB, 0, -1, 0)) > 0) { int iRadius = pDockingPorts->GetAttributeIntegerBounded(PORT_RADIUS_ATTRIB, 0, -1, DEFAULT_PORT_POS_RADIUS); int iAngle = 360 / m_iPortCount; // We need the image scale to adjust coordinates int iScale = (pOwner ? pOwner->GetImage().GetImageViewportSize() : 512); // Initialize ports m_pPort = new SDockingPort[m_iPortCount]; for (i = 0; i < m_iPortCount; i++) { C3DConversion::CalcCoord(iScale, i * iAngle, iRadius, 0, &m_pPort[i].vPos); m_pPort[i].iRotation = ((i * iAngle) + 180) % 360; } } // Otherwise, no ports else { m_iPortCount = 0; m_pPort = NULL; } } // Otherwise, initialize ports based on a count else InitPorts(pOwner, pElement->GetAttributeInteger(DOCKING_PORTS_ATTRIB), 64 * g_KlicksPerPixel); }
void InitStationTypeImage (SEntryDesc &Entry, CStationType *pStationType) { struct SSatImageDesc { const CObjectImageArray *pImage; CCompositeImageSelector Selector; int xOffset; int yOffset; }; int i; SSelectorInitCtx InitCtx; pStationType->SetImageSelector(InitCtx, &Entry.Selector); const CObjectImageArray *pMainImage = &pStationType->GetImage(Entry.Selector, CCompositeImageModifiers()); // If we have no satellites, then we can just return the single station // image. CXMLElement *pSatellites = pStationType->GetSatellitesDesc(); if (pSatellites == NULL) { Entry.pImage = pMainImage; return; } // Figure out the extents of the image RECT rcMainImage = pMainImage->GetImageRect(); RECT rcBounds; rcBounds.left = -(RectWidth(rcMainImage) / 2); rcBounds.top = -(RectHeight(rcMainImage) / 2); rcBounds.right = rcBounds.left + RectWidth(rcMainImage); rcBounds.bottom = rcBounds.top + RectHeight(rcMainImage); // Loop over all satellites and get metrics TArray<SSatImageDesc> SatImages; for (i = 0; i < pSatellites->GetContentElementCount(); i++) { CXMLElement *pSatDesc = pSatellites->GetContentElement(i); if (!pSatDesc->FindAttribute(SEGMENT_ATTRIB) || !strEquals(STATION_TAG, pSatDesc->GetTag())) continue; // Get the type of the satellite CStationType *pSatType = g_pUniverse->FindStationType(pSatDesc->GetAttributeInteger(TYPE_ATTRIB)); if (pSatType == NULL) continue; // Prepare the image for the satellite SSatImageDesc *pSatImage = SatImages.Insert(); pSatType->SetImageSelector(InitCtx, &pSatImage->Selector); // If we have an image variant, then set it int iVariant; if (pSatDesc->FindAttributeInteger(IMAGE_VARIANT_ATTRIB, &iVariant)) { IImageEntry *pRoot = pSatType->GetImage().GetRoot(); DWORD dwID = (pRoot ? pRoot->GetID() : DEFAULT_SELECTOR_ID); pSatImage->Selector.DeleteAll(); pSatImage->Selector.AddVariant(dwID, iVariant); } pSatImage->pImage = &pSatType->GetImage(pSatImage->Selector, CCompositeImageModifiers()); // Now get the offset pSatImage->xOffset = pSatDesc->GetAttributeInteger(X_OFFSET_ATTRIB); pSatImage->yOffset = pSatDesc->GetAttributeInteger(Y_OFFSET_ATTRIB); // Compute the satellite rect RECT rcSatImage = pSatImage->pImage->GetImageRect(); RECT rcSatBounds; rcSatBounds.left = pSatImage->xOffset - (RectWidth(rcSatImage) / 2); rcSatBounds.top = -pSatImage->yOffset - (RectHeight(rcSatImage) / 2); rcSatBounds.right = rcSatBounds.left + RectWidth(rcSatImage); rcSatBounds.bottom = rcSatBounds.top + RectHeight(rcSatImage); // Increase the size of the bounds rcBounds.left = Min(rcBounds.left, rcSatBounds.left); rcBounds.right = Max(rcBounds.right, rcSatBounds.right); rcBounds.top = Min(rcBounds.top, rcSatBounds.top); rcBounds.bottom = Max(rcBounds.bottom, rcSatBounds.bottom); } // If no segments, then we just return the basic image if (SatImages.GetCount() == 0) { Entry.pImage = pMainImage; return; } // Create an image that will hold the composite CG32bitImage *pCompositeImage = new CG32bitImage; pCompositeImage->Create(RectWidth(rcBounds), RectHeight(rcBounds), CG32bitImage::alpha8, CG32bitPixel::Null()); int xCenter = -rcBounds.left; int yCenter = -rcBounds.top; // Paint the main image pMainImage->PaintImage(*pCompositeImage, xCenter, yCenter, 0, Entry.iRotation, true); // Paint all the satellites for (i = 0; i < SatImages.GetCount(); i++) SatImages[i].pImage->PaintImage(*pCompositeImage, xCenter + SatImages[i].xOffset, yCenter - SatImages[i].yOffset, 0, 0, true); // Now create the proper image array RECT rcResult; rcResult.left = 0; rcResult.top = 0; rcResult.right = RectWidth(rcBounds); rcResult.bottom = RectHeight(rcBounds); int xOffset = (RectWidth(rcBounds) / 2) - xCenter; int yOffset = (RectHeight(rcBounds) / 2) - yCenter; Entry.pCompositeImageArray = new CObjectImageArray; Entry.pCompositeImageArray->Init(pCompositeImage, rcResult, 0, 0, true, xOffset, yOffset); // Done Entry.pImage = Entry.pCompositeImageArray; }
void CDockingPorts::InitPortsFromXML (CSpaceObject *pOwner, CXMLElement *pElement) // InitPortsFromXML // // InitPortsFromXML { int i; // See if we've got a special element with docking port geometry CXMLElement *pDockingPorts = pElement->GetContentElementByTag(DOCKING_PORTS_TAG); if (pDockingPorts) { // Initialize max dist m_iMaxDist = pDockingPorts->GetAttributeIntegerBounded(MAX_DIST_ATTRIB, 1, -1, DEFAULT_DOCK_DISTANCE_LS); // If we have sub-elements then these are port definitions. m_iPortCount = pDockingPorts->GetContentElementCount(); if (m_iPortCount > 0) { m_pPort = new DockingPort[m_iPortCount]; for (i = 0; i < m_iPortCount; i++) { CXMLElement *pPort = pDockingPorts->GetContentElement(i); CVector vDockPos((pPort->GetAttributeInteger(X_ATTRIB) * g_KlicksPerPixel), (pPort->GetAttributeInteger(Y_ATTRIB) * g_KlicksPerPixel)); m_pPort[i].iStatus = psEmpty; m_pPort[i].pObj = NULL; m_pPort[i].vPos = vDockPos; if (pPort->FindAttributeInteger(ROTATION_ATTRIB, &m_pPort[i].iRotation)) m_pPort[i].iRotation = (m_pPort[i].iRotation % 360); else m_pPort[i].iRotation = (VectorToPolar(vDockPos) + 180) % 360; } } // Otherwise, we expect a port count and radius else if ((m_iPortCount = pDockingPorts->GetAttributeIntegerBounded(PORT_COUNT_ATTRIB, 0, -1, 0)) > 0) { m_pPort = new DockingPort[m_iPortCount]; int iRadius = pDockingPorts->GetAttributeIntegerBounded(PORT_RADIUS_ATTRIB, 0, -1, DEFAULT_PORT_POS_RADIUS); Metric rRadius = g_KlicksPerPixel * iRadius; int iAngle = 360 / m_iPortCount; for (i = 0; i < m_iPortCount; i++) { m_pPort[i].iStatus = psEmpty; m_pPort[i].pObj = NULL; m_pPort[i].vPos = PolarToVector(i * iAngle, rRadius); m_pPort[i].iRotation = ((i * iAngle) + 180) % 360; } } // Otherwise, no ports else { m_iPortCount = 0; m_pPort = NULL; } } // Otherwise, initialize ports based on a count else InitPorts(pOwner, pElement->GetAttributeInteger(DOCKING_PORTS_ATTRIB), 64 * g_KlicksPerPixel); }