bool C4FacetExSurface::CopyFromSfcMaxSize(C4Surface &srcSfc, int32_t iMaxSize, uint32_t dwColor) { // safety if (!srcSfc.Wdt || !srcSfc.Hgt) return false; Clear(); // no scale? bool fNeedsScale = !(srcSfc.Wdt <= iMaxSize && srcSfc.Hgt <= iMaxSize); if (!fNeedsScale && !dwColor) { // no change necessary; just copy then Face.Copy(srcSfc); } else { // must scale down or colorize. Just blit. C4Facet fctSource; fctSource.Set(&srcSfc, 0, 0, srcSfc.Wdt, srcSfc.Hgt); int32_t iTargetWdt, iTargetHgt; if (fNeedsScale) { if (fctSource.Wdt > fctSource.Hgt) { iTargetWdt = iMaxSize; iTargetHgt = fctSource.Hgt * iTargetWdt / fctSource.Wdt; } else { iTargetHgt = iMaxSize; iTargetWdt = fctSource.Wdt * iTargetHgt / fctSource.Hgt; } } else { iTargetWdt = fctSource.Wdt; iTargetHgt = fctSource.Hgt; } if (dwColor) srcSfc.SetClr(dwColor); Create(iTargetWdt, iTargetHgt); lpDDraw->Blit(&srcSfc, 0.0f, 0.0f, float(fctSource.Wdt), float(fctSource.Hgt), &Face, 0, 0, iTargetWdt, iTargetHgt); } Set(&Face, 0, 0, Face.Wdt, Face.Hgt); return true; }
void C4DefGraphics::Draw(C4Facet &cgo, DWORD iColor, C4Object *pObj, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform* trans) { // default: def picture rect C4Rect fctPicRect = pDef->PictureRect; C4Facet fctPicture; // if assigned: use object specific rect and graphics if (pObj) if (pObj->PictureRect.Wdt) fctPicRect = pObj->PictureRect; // specific object color? if (pObj) pObj->PrepareDrawing(); switch(Type) { case C4DefGraphics::TYPE_None: // Def has no graphics break; case C4DefGraphics::TYPE_Bitmap: fctPicture.Set(GetBitmap(iColor),fctPicRect.x,fctPicRect.y,fctPicRect.Wdt,fctPicRect.Hgt); fctPicture.DrawTUnscaled(cgo,true,iPhaseX,iPhaseY,trans); break; case C4DefGraphics::TYPE_Mesh: // TODO: Allow rendering of a mesh directly, without instance (to render pose; no animation) std::unique_ptr<StdMeshInstance> dummy; StdMeshInstance* instance; C4Value value; if (pObj) { instance = pObj->pMeshInstance; pObj->GetProperty(P_PictureTransformation, &value); } else { dummy.reset(new StdMeshInstance(*Mesh, 1.0f)); instance = dummy.get(); pDef->GetProperty(P_PictureTransformation, &value); } StdMeshMatrix matrix; if (C4ValueToMatrix(value, &matrix)) pDraw->SetMeshTransform(&matrix); pDraw->SetPerspective(true); pDraw->RenderMesh(*instance, cgo.Surface, cgo.X,cgo.Y, cgo.Wdt, cgo.Hgt, pObj ? pObj->Color : iColor, trans); pDraw->SetPerspective(false); pDraw->SetMeshTransform(NULL); break; } if (pObj) pObj->FinishedDrawing(); // draw overlays if (pObj && pObj->pGfxOverlay) for (C4GraphicsOverlay *pGfxOvrl = pObj->pGfxOverlay; pGfxOvrl; pGfxOvrl = pGfxOvrl->GetNext()) if (pGfxOvrl->IsPicture()) pGfxOvrl->DrawPicture(cgo, pObj, trans); }
bool C4FacetExSurface::EnsureOwnSurface() { // is it a link? if (Surface != &Face) { // then recreate in same size C4Facet fctOld = *this; if (!Create(fctOld.Wdt, fctOld.Hgt)) return false; fctOld.Draw(*this); } return true; }
bool Picture::EnsureOwnSurface() { // no surface? if (!Facet.Surface) return false; // equals face already? if (Facet.Surface == &Facet.GetFace()) return true; // then create as a copy C4Facet cgo = Facet; if (!Facet.Create(cgo.Wdt, cgo.Hgt)) return false; cgo.Draw(Facet); return true; }
void C4GoalDisplay::GoalPicture::DrawElement(C4FacetEx &cgo) { // draw area C4Facet cgoDraw; cgoDraw.Set(cgo.Surface, cgo.X+rcBounds.x+cgo.TargetX, cgo.Y+rcBounds.y+cgo.TargetY, rcBounds.Wdt, rcBounds.Hgt); // draw buffered picture Picture.Draw(cgoDraw); // draw star symbol if fulfilled if (fFulfilled) { cgoDraw.Set(cgoDraw.Surface, cgoDraw.X+cgoDraw.Wdt*1/2, cgoDraw.Y+cgoDraw.Hgt*1/2, cgoDraw.Wdt/2, cgoDraw.Hgt/2); C4GUI::Icon::GetIconFacet(C4GUI::Ico_Star).Draw(cgoDraw); } }
C4Facet Icon::GetIconFacet(Icons icoIconIndex) { if (icoIconIndex == Ico_None) return C4Facet(); C4Facet *rFacet; switch (icoIconIndex & ~0xff) { case Ico_Extended: rFacet = &::GraphicsResource.fctIconsEx; break; case Ico_Controller: rFacet = &::GraphicsResource.fctControllerIcons; break; default: rFacet = &::GraphicsResource.fctIcons; } icoIconIndex = Icons(icoIconIndex & 0xff); int32_t iXMax, iYMax; rFacet->GetPhaseNum(iXMax, iYMax); if (!iXMax) iXMax = 6; return rFacet->GetPhase(icoIconIndex % iXMax, icoIconIndex / iXMax); }
bool C4MainMenu::ActivateGoals(int32_t iPlayer, bool fDoActivate) { C4FacetSurface fctSymbol; C4Facet fctGF; // goal fulfilled facet if (fDoActivate) { // Menu symbol/init InitRefSym(GfxR->fctMenu.GetPhase(4),LoadResStr("IDS_MENU_CPGOALS"),iPlayer); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetPermanent(false); fctGF.Set(NULL, C4SymbolSize-::GraphicsResource.fctCaptain.Wdt-2, 2, ::GraphicsResource.fctCaptain.Wdt, ::GraphicsResource.fctCaptain.Hgt); } // determine if the goals are fulfilled - do the calls even if the menu is not to be opened to ensure synchronization C4IDList GoalList, FulfilledGoalList; C4RoundResults::EvaluateGoals(GoalList, FulfilledGoalList, iPlayer); // Add Items if (fDoActivate) { int32_t iNumGoals = GoalList.GetNumberOfIDs(), cnt; C4ID idGoal; C4Def *pDef; for (int32_t i=0; i<iNumGoals; ++i) if ((idGoal = GoalList.GetID(i, &cnt))) if ((pDef = C4Id2Def(idGoal))) { fctSymbol.Create(C4SymbolSize,C4SymbolSize); // 2do: If an object instance is known, draw the object instead? // this would allow us to do dynamic pictures and overlays; e.g. draw the actual, required settlement score // for settlement score goals // Same for pDef->GetName(), pDef->GetDesc() pDef->Draw(fctSymbol); if (FulfilledGoalList.GetIDCount(idGoal)) { fctGF.Surface=fctSymbol.Surface; ::GraphicsResource.fctCaptain.Draw(fctGF); } StdStrBuf Command; Command.Format("Player:Goal:%s", idGoal.ToString()); Add(pDef->GetName(),fctSymbol,Command.getData(),C4MN_Item_NoCount,NULL,""); } // Go back to options menu on close SetCloseCommand("ActivateMenu:Main"); } // Done return true; }
void C4IDList::Draw(C4Facet &cgo, int32_t iSelection, C4DefList &rDefs, DWORD dwCategory, bool fCounts, int32_t iAlign) const { int32_t sections = cgo.GetSectionCount(); int32_t idnum = GetNumberOfIDs(rDefs,dwCategory); int32_t firstid = Clamp<int32_t>(iSelection-sections/2,0,std::max<int32_t>(idnum-sections,0)); int32_t idcount; C4ID c_id; C4Facet cgo2; char buf[10]; for (int32_t cnt=0; (cnt<sections) && (c_id=GetID(rDefs,dwCategory,firstid+cnt,&idcount)); cnt++) { cgo2 = cgo.TruncateSection(iAlign); rDefs.Draw(c_id,cgo2,(firstid+cnt==iSelection),0); sprintf(buf,"%dx",idcount); if (fCounts) pDraw->TextOut(buf, ::GraphicsResource.FontRegular, 1.0, cgo2.Surface,cgo2.X+cgo2.Wdt-1, cgo2.Y + cgo2.Hgt - 1 - ::GraphicsResource.FontRegular.GetLineHeight(),C4Draw::DEFAULT_MESSAGE_COLOR,ARight); } }
void C4SolidMask::Draw(C4FacetEx &cgo) { // only if put if (!MaskPut) return; // set topface facet C4Facet fct; fct.Set(pForObject->GetGraphics()->GetBitmap(), pForObject->SolidMask.x, pForObject->SolidMask.y, pForObject->SolidMask.Wdt, pForObject->SolidMask.Hgt); // draw it if (MaskPutRotation) fct.DrawXR(cgo.Surface, pForObject->x + pForObject->Shape.x + cgo.X - cgo.TargetX + pForObject->SolidMask.tx, pForObject->y + pForObject->Shape.y + cgo.Y - cgo.TargetY + pForObject->SolidMask.ty, fct.Wdt, fct.Hgt, 0, 0, MaskPutRotation); else fct.DrawX(cgo.Surface, pForObject->x + pForObject->Shape.x + cgo.X - cgo.TargetX + pForObject->SolidMask.tx, pForObject->y + pForObject->Shape.y + cgo.Y - cgo.TargetY + pForObject->SolidMask.ty, fct.Wdt, fct.Hgt, 0, 0); }
void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByPlayer) { assert(!IsPicture()); assert(pForObj); // get target pos float offX, offY; float newzoom; pForObj->GetDrawPosition(cgo, offX, offY, newzoom); ZoomDataStackItem zdsi(newzoom); // special blit mode if (dwBlitMode == C4GFXBLIT_PARENT) (OverlayObj ? static_cast<C4Object*>(OverlayObj) : pForObj)->PrepareDrawing(); else { pDraw->SetBlitMode(dwBlitMode); if (dwClrModulation != 0xffffff) pDraw->ActivateBlitModulation(dwClrModulation); if (pMeshInstance) pMeshInstance->SetFaceOrderingForClrModulation(dwClrModulation); } if (eMode == MODE_Rank) { C4TargetFacet ccgo; ccgo.Set(cgo.Surface, offX+pForObj->Shape.x,offY+pForObj->Shape.y,pForObj->Shape.Wdt,pForObj->Shape.Hgt, cgo.TargetX, cgo.TargetY); DrawRankSymbol(ccgo, OverlayObj); } // drawing specific object? else if (OverlayObj) { // TODO: Shouldn't have called PrepareDrawing/set ClrModulation here, since // OverlayObj drawing will do it on its own. if (eMode == MODE_ObjectPicture) { C4Facet fctTarget; fctTarget.Set(cgo.Surface, offX+pForObj->Shape.x, offY+pForObj->Shape.y, pForObj->Shape.Wdt, pForObj->Shape.Hgt); OverlayObj->DrawPicture(fctTarget, false, &C4DrawTransform(Transform, fctTarget.X+float(fctTarget.Wdt)/2, fctTarget.Y+float(fctTarget.Hgt)/2)); } else { // Draw specified object at target pos of this object; offset by transform. OverlayObj->Draw(cgo, iByPlayer, C4Object::ODM_Overlay, offX + Transform.GetXOffset(), offY + Transform.GetYOffset()); OverlayObj->DrawTopFace(cgo, iByPlayer, C4Object::ODM_Overlay, offX + Transform.GetXOffset(), offY + Transform.GetYOffset()); } } else if (eMode == MODE_ExtraGraphics) { // draw self with specified gfx if (pSourceGfx) { C4DefGraphics *pPrevGfx = pForObj->GetGraphics(); C4DrawTransform *pPrevTrf = pForObj->pDrawTransform; C4DrawTransform trf; if (pPrevTrf) { trf = *pPrevTrf; trf *= Transform; } else { trf = Transform; } pForObj->SetGraphics(pSourceGfx, true); pForObj->pDrawTransform = &trf; pForObj->Draw(cgo, iByPlayer, C4Object::ODM_BaseOnly); pForObj->DrawTopFace(cgo, iByPlayer, C4Object::ODM_BaseOnly); pForObj->SetGraphics(pPrevGfx, true); pForObj->pDrawTransform = pPrevTrf; } } else if(eMode == MODE_Picture || eMode == MODE_IngamePicture) { float twdt, thgt; if (fZoomToShape) { twdt = pForObj->Shape.Wdt; thgt = pForObj->Shape.Hgt; } else { twdt = pSourceGfx->pDef->Shape.Wdt; thgt = pSourceGfx->pDef->Shape.Hgt; } C4TargetFacet ccgo; ccgo.Set(cgo.Surface, offX-twdt/2, offY-thgt/2, twdt, thgt, cgo.TargetX, cgo.TargetY); C4DrawTransform trf(Transform, offX, offY); // Don't set pForObj because we don't draw the picture of pForObj, but the picture of another definition on top of pForObj: pSourceGfx->Draw(ccgo, pForObj->Color, NULL, iPhase, 0, &trf); } else { // no object specified: Draw from fctBlit // update by object color if (fctBlit.Surface) fctBlit.Surface->SetClr(pForObj->Color); if (!pMeshInstance) { // draw there C4DrawTransform trf(Transform, offX, offY); if (fZoomToShape) { float fZoom = std::min(pForObj->Shape.Wdt / std::max(fctBlit.Wdt, 1.0f), pForObj->Shape.Hgt / std::max(fctBlit.Hgt, 1.0f)); trf.ScaleAt(fZoom, fZoom, offX, offY); } fctBlit.DrawT(cgo.Surface, offX - fctBlit.Wdt/2 + fctBlit.TargetX, offY - fctBlit.Hgt/2 + fctBlit.TargetY, iPhase, 0, &trf); } else { C4Def *pDef = pSourceGfx->pDef; // draw there C4DrawTransform trf(Transform, offX, offY); if (fZoomToShape) { float fZoom = std::min((float)pForObj->Shape.Wdt / std::max(pDef->Shape.Wdt, 1), (float)pForObj->Shape.Hgt / std::max(pDef->Shape.Hgt, 1)); trf.ScaleAt(fZoom, fZoom, offX, offY); } C4Value value; pDef->GetProperty(P_MeshTransformation, &value); StdMeshMatrix matrix; if (C4ValueToMatrix(value, &matrix)) pDraw->SetMeshTransform(&matrix); pDraw->RenderMesh(*pMeshInstance, cgo.Surface, offX - pDef->Shape.Wdt/2.0, offY - pDef->Shape.Hgt/2.0, pDef->Shape.Wdt, pDef->Shape.Hgt, pForObj->Color, &trf); pDraw->SetMeshTransform(NULL); } } // cleanup if (dwBlitMode == C4GFXBLIT_PARENT) (OverlayObj ? static_cast<C4Object*>(OverlayObj) : pForObj)->FinishedDrawing(); else { pDraw->ResetBlitMode(); pDraw->DeactivateBlitModulation(); } }
bool C4Application::PreInit() { // startup dialog: Only use if no next mission has been provided bool fUseStartupDialog = !Game.HasScenario(); // Load graphics early, before we draw anything, since we need shaders // loaded to draw. Game.SetInitProgress(0.0f); Log(LoadResStr("IDS_PRC_GFXRES")); if (!GraphicsResource.Init()) return false; Game.SetInitProgress(fUseStartupDialog ? 10.0f : 1.0f); // Startup message board if (!isEditor) if (Config.Graphics.ShowStartupMessages || Game.NetworkActive) { C4Facet cgo; cgo.Set(FullScreen.pSurface,0,0,C4GUI::GetScreenWdt(), C4GUI::GetScreenHgt()); GraphicsSystem.MessageBoard->Init(cgo,true); } // init loader: Black screen for first start if a video is to be shown; otherwise default spec if (fUseStartupDialog && !isEditor) { if (!::GraphicsSystem.InitLoaderScreen(C4CFN_StartupBackgroundMain)) { LogFatal(LoadResStr("IDS_PRC_ERRLOADER")); return false; } } Game.SetInitProgress(fUseStartupDialog ? 20.0f : 2.0f); if (!Game.PreInit()) return false; // Music if (!MusicSystem.Init("frontend")) Log(LoadResStr("IDS_PRC_NOMUSIC")); Game.SetInitProgress(fUseStartupDialog ? 34.0f : 2.0f); // Sound if (!SoundSystem.Init()) Log(LoadResStr("IDS_PRC_NOSND")); // Play some music! - after sound init because sound system might be needed by music system if (fUseStartupDialog && !isEditor && Config.Sound.FEMusic) MusicSystem.Play(); Game.SetInitProgress(fUseStartupDialog ? 35.0f : 3.0f); if (fUseStartupDialog) { AppState = C4AS_Startup; // default record? Game.Record = Game.Record || Config.General.DefRec; // if no scenario or direct join has been specified, get game startup parameters by startup dialog if (!isEditor) C4Startup::InitStartup(); } // directly launch scenario / network game else { AppState = C4AS_StartGame; } return true; }
bool C4RankSystem::DrawRankSymbol(C4FacetExSurface *fctSymbol, int32_t iRank, C4FacetEx *pfctRankSymbols, int32_t iRankSymbolCount, bool fOwnSurface, int32_t iXOff, C4Facet *cgoDrawDirect) { // safety if (iRank<0) iRank = 0; // symbol by rank int32_t iMaxRankSym,Q; if (pfctRankSymbols->GetPhaseNum(iMaxRankSym, Q)) { if (!iMaxRankSym) iMaxRankSym=1; int32_t iBaseRank=iRank%iRankSymbolCount; if (iRank/iRankSymbolCount) { // extended rank: draw // extension star defaults to captain star; but use extended symbols if they are in the gfx C4Facet fctExtended = (const C4Facet &) Game.GraphicsResource.fctCaptain; if (iMaxRankSym > iRankSymbolCount) { int32_t iExtended = iRank / iRankSymbolCount - 1 + iRankSymbolCount; if (iExtended >= iMaxRankSym) { // max rank exceeded iExtended = iMaxRankSym - 1; iBaseRank = iRankSymbolCount - 1; } fctExtended = (const C4Facet &) pfctRankSymbols->GetPhase(iExtended); } int32_t iSize = pfctRankSymbols->Wdt; if (!cgoDrawDirect) { fctSymbol->Create(iSize,iSize); pfctRankSymbols->DrawX(fctSymbol->Surface, 0,0,iSize,iSize,iBaseRank); fctExtended.DrawX(fctSymbol->Surface, 0,0,iSize*2/3,iSize*2/3); } else { pfctRankSymbols->Draw(cgoDrawDirect->Surface,cgoDrawDirect->X+iXOff,cgoDrawDirect->Y,iBaseRank); fctExtended.Draw(cgoDrawDirect->Surface, cgoDrawDirect->X+iXOff-4,cgoDrawDirect->Y-3); } } else { // regular rank: copy facet if (cgoDrawDirect) { pfctRankSymbols->Draw(cgoDrawDirect->Surface, cgoDrawDirect->X+iXOff,cgoDrawDirect->Y,iBaseRank); } else if (fOwnSurface) { int32_t iSize = pfctRankSymbols->Wdt; fctSymbol->Create(iSize,iSize); pfctRankSymbols->DrawX(fctSymbol->Surface, 0,0,iSize,iSize,iBaseRank); } else { fctSymbol->Set(pfctRankSymbols->GetPhase(iBaseRank)); } } return true; } return false; }
bool C4LoaderScreen::Init(const char *szLoaderSpec) { // Determine loader specification if (!szLoaderSpec || !szLoaderSpec[0]) szLoaderSpec = "Loader*"; char szLoaderSpecPng[128 + 1 + 4], szLoaderSpecBmp[128 + 1 + 4]; char szLoaderSpecJpg[128 + 1 + 4], szLoaderSpecJpeg[128 + 1 + 5]; SCopy(szLoaderSpec, szLoaderSpecPng); DefaultExtension(szLoaderSpecPng, "png"); SCopy(szLoaderSpec, szLoaderSpecBmp); DefaultExtension(szLoaderSpecBmp, "bmp"); SCopy(szLoaderSpec, szLoaderSpecJpg); DefaultExtension(szLoaderSpecJpg, "jpg"); SCopy(szLoaderSpec, szLoaderSpecJpeg); DefaultExtension(szLoaderSpecJpeg, "jpeg"); int iLoaders=0; C4Group *pGroup=NULL,*pChosenGrp=NULL; char ChosenFilename[_MAX_PATH+1]; // query groups of equal priority in set while (pGroup=Game.GroupSet.FindGroup(C4GSCnt_Loaders, pGroup, true)) { iLoaders+=SeekLoaderScreens(*pGroup, szLoaderSpecPng, iLoaders, ChosenFilename, &pChosenGrp); iLoaders+=SeekLoaderScreens(*pGroup, szLoaderSpecJpeg, iLoaders, ChosenFilename, &pChosenGrp); iLoaders+=SeekLoaderScreens(*pGroup, szLoaderSpecJpg, iLoaders, ChosenFilename, &pChosenGrp); // lower the chance for any loader other than png iLoaders*=2; iLoaders+=SeekLoaderScreens(*pGroup, szLoaderSpecBmp, iLoaders, ChosenFilename, &pChosenGrp); } // nothing found? seek in main gfx grp C4Group GfxGrp; if (!iLoaders) { // open it GfxGrp.Close(); if (!GfxGrp.Open(Config.AtExePath(C4CFN_Graphics))) { LogFatal(FormatString(LoadResStr("IDS_PRC_NOGFXFILE"),C4CFN_Graphics,GfxGrp.GetError()).getData()); return FALSE; } // seek for png-loaders iLoaders=SeekLoaderScreens(GfxGrp, szLoaderSpecPng, iLoaders, ChosenFilename, &pChosenGrp); iLoaders+=SeekLoaderScreens(GfxGrp, szLoaderSpecJpg, iLoaders, ChosenFilename, &pChosenGrp); iLoaders+=SeekLoaderScreens(GfxGrp, szLoaderSpecJpeg, iLoaders, ChosenFilename, &pChosenGrp); iLoaders*=2; // seek for bmp-loaders iLoaders+=SeekLoaderScreens(GfxGrp, szLoaderSpecBmp, iLoaders, ChosenFilename, &pChosenGrp); // Still nothing found: fall back to general loader spec in main graphics group if (!iLoaders) { iLoaders = SeekLoaderScreens(GfxGrp, "Loader*.png", 0, ChosenFilename, &pChosenGrp); iLoaders += SeekLoaderScreens(GfxGrp, "Loader*.jpg", iLoaders, ChosenFilename, &pChosenGrp); iLoaders += SeekLoaderScreens(GfxGrp, "Loader*.jpeg", iLoaders, ChosenFilename, &pChosenGrp); } // Not even default loaders available? Fail. if (!iLoaders) { LogFatal(FormatString("No loaders found for loader specification: %s/%s/%s/%s", szLoaderSpecPng, szLoaderSpecBmp, szLoaderSpecJpg, szLoaderSpecJpeg).getData()); return FALSE; } } // load loader fctBackground.GetFace().SetBackground(); if (!fctBackground.Load(*pChosenGrp,ChosenFilename, C4FCT_Full,C4FCT_Full,true)) return FALSE; // load info if (szInfo) { delete [] szInfo; szInfo=NULL; } /*size_t iInfoSize; if (Game.ScenarioFile.AccessEntry(C4CFN_Info, &iInfoSize)) { szInfo = new char[iInfoSize+1]; // load info file Game.ScenarioFile.Read(szInfo, iInfoSize); // terminate buffer szInfo[iInfoSize]=0; // insert linebreaks SReplaceChar(szInfo, 0x0a, '|'); }*/ // init fonts if (!Game.GraphicsResource.InitFonts()) return false; // initial draw C4Facet cgo; cgo.Set(Application.DDraw->lpPrimary,0,0,Config.Graphics.ResX,Config.Graphics.ResY); Draw(cgo); // done, success! return TRUE; }