From 2a112b1d00a9db74d75077b7fd7c63e0710c13d2 Mon Sep 17 00:00:00 2001 From: David Dormagen Date: Sun, 22 Mar 2015 09:58:43 +0100 Subject: [PATCH] fixed player names, clonk names and selector info being zoomed (#687) --- src/config/C4Config.cpp | 2 +- src/game/C4Game.cpp | 132 +++++++++++++++++++++------- src/game/C4Game.h | 2 +- src/game/C4Viewport.cpp | 2 +- src/graphics/C4GraphicsResource.cpp | 4 +- src/object/C4Object.cpp | 40 --------- 6 files changed, 103 insertions(+), 79 deletions(-) diff --git a/src/config/C4Config.cpp b/src/config/C4Config.cpp index ccd77038f..ca6549865 100644 --- a/src/config/C4Config.cpp +++ b/src/config/C4Config.cpp @@ -103,7 +103,7 @@ void C4ConfigGraphics::CompileFunc(StdCompiler *pComp) pComp->Value(mkNamingAdapt(UpperBoard, "UpperBoard", 1 ,false, true)); pComp->Value(mkNamingAdapt(ShowClock, "ShowClock", 0 ,false, true)); pComp->Value(mkNamingAdapt(ShowCrewNames, "ShowCrewNames", 1 ,false, true)); - pComp->Value(mkNamingAdapt(ShowCrewCNames, "ShowCrewCNames", 1 ,false, true)); + pComp->Value(mkNamingAdapt(ShowCrewCNames, "ShowCrewCNames", 0 ,false, true)); pComp->Value(mkNamingAdapt(BitDepth, "BitDepth", 32 ,false, true)); pComp->Value(mkNamingAdapt(Windowed, "Windowed", 0 ,false, true)); pComp->Value(mkNamingAdapt(PXSGfx, "PXSGfx" , 1 )); diff --git a/src/game/C4Game.cpp b/src/game/C4Game.cpp index 8a188fc0c..19c14b250 100644 --- a/src/game/C4Game.cpp +++ b/src/game/C4Game.cpp @@ -1519,44 +1519,108 @@ void C4Game::Evaluate() } -void C4Game::DrawCursors(C4TargetFacet &cgo, int32_t iPlayer) +void C4Game::DrawCrewOverheadText(C4TargetFacet &cgo, int32_t iPlayer) { + + // All drawing in this function must not be affected by zoom; but remember zoom and reset later. + ZoomData r; + pDraw->GetZoom(&r); + const float zoom = r.Zoom; + r.Zoom = 1.0; + pDraw->SetZoom(r); + // Offset for all text/objects + const float fixedOffsetX = -cgo.X * cgo.Zoom + cgo.X; + const float fixedOffsetY = (-cgo.Y - 10.0f) * cgo.Zoom + cgo.Y; // Draw cursor mark arrow & cursor object name - float cox,coy; - int32_t cphase; - C4Object *cursor; - C4Facet &fctCursor = GraphicsResource.fctCursor; - for (C4Player *pPlr=Players.First; pPlr; pPlr=pPlr->Next) - if (pPlr->Number == iPlayer || iPlayer==NO_OWNER) - if (pPlr->CursorFlash) - if (pPlr->Cursor) + C4Facet &fctCursor = GraphicsResource.fctMouseCursor; + for (C4Player *pPlr = Players.First; pPlr; pPlr = pPlr->Next) + { + // Draw a small selector & name above the cursor? F.e. after switching crew. + const bool drawCursorInfo = (pPlr->Number == iPlayer || iPlayer == NO_OWNER) // only for the viewport's player.. + && (pPlr->CursorFlash && pPlr->Cursor); // ..and if the player wants to show their cursor. + // Otherwise, for allied players we might want to draw player & crew names. + // Note that these two conditions are generally mutually-exclusive. + const bool drawPlayerAndCursorNames = (pPlr->Number != iPlayer) // Never for own player.. + && (Config.Graphics.ShowCrewNames || Config.Graphics.ShowCrewCNames) // ..and if the settings allow it.. + && !Hostile(iPlayer, pPlr->Number) && !pPlr->IsInvisible(); // ..and of course only if applicable. + + if (!drawPlayerAndCursorNames && !drawCursorInfo) continue; + + // Lambda to calculate correct drawing position of object, (re-)adjusted by zoom. + float drawX, drawY, drawZoom; + auto calculateObjectTextPosition = [&](C4Object *obj) + { + obj->GetDrawPosition(cgo, fixtof(obj->fix_x), fixtof(obj->fix_y), 1.0, drawX, drawY, drawZoom); + drawX = drawX * cgo.Zoom + fixedOffsetX; + drawY = drawY * cgo.Zoom - static_cast(obj->Def->Shape.Hgt) / 2.0 + fixedOffsetY; + }; + + // Actual text output! + if (drawPlayerAndCursorNames) + { + // We need to show crew names for that player, we do so for every crew-member. + for (C4Object * const & crew : pPlr->Crew) + { + if (!crew->Status || !crew->Def) continue; + if (crew->Contained) continue; + if ((crew->OCF & OCF_CrewMember) == 0) continue; + if (!crew->IsVisible(iPlayer, false)) continue; + + calculateObjectTextPosition(crew); + drawY -= 5.0f; // aesthetical offset + + // compose string + char szText[C4GM_MaxText + 1]; + if (Config.Graphics.ShowCrewNames) + if (Config.Graphics.ShowCrewCNames) + sprintf(szText, "%s (%s)", crew->GetName(), pPlr->GetName()); + else + SCopy(pPlr->GetName(), szText); + else + SCopy(crew->GetName(), szText); + // Word wrap to cgo width + int32_t iCharWdt, dummy; + ::GraphicsResource.FontRegular.GetTextExtent("m", iCharWdt, dummy, false); + int32_t iMaxLine = Max(cgo.Wdt / iCharWdt, 20); + SWordWrap(szText, ' ', '|', iMaxLine); + // Center text vertically, too + int textWidth, textHeight; + ::GraphicsResource.FontRegular.GetTextExtent(szText, textWidth, textHeight, true); + // Draw + pDraw->TextOut(szText, ::GraphicsResource.FontRegular, 1.0, cgo.Surface, drawX, drawY - static_cast(textHeight) / 2.0, + pPlr->ColorDw | 0x7f000000, ACenter); + } + } + else if (drawCursorInfo) + { + C4Object * const cursor = pPlr->Cursor; + calculateObjectTextPosition(cursor); + // Draw a down-arrow above the Clonk's head + drawY += -fctCursor.Hgt; + fctCursor.Draw(cgo.Surface, drawX - static_cast(fctCursor.Wdt) / 2.0, drawY, 4); + // And possibly draw some info text, too + if (cursor->Info) + { + int32_t texthgt = ::GraphicsResource.FontRegular.GetLineHeight(); + StdStrBuf str; + if (cursor->Info->Rank > 0) { - cursor=pPlr->Cursor; - cox=cursor->GetX()-fctCursor.Wdt/2-cgo.TargetX; - coy=cursor->GetY()-cursor->Def->Shape.Hgt/2-fctCursor.Hgt-cgo.TargetY; - if (Inside(int32_t(cox),1-fctCursor.Wdt,cgo.Wdt) && Inside(int32_t(coy),1-fctCursor.Hgt,cgo.Hgt)) - { - cphase=0; if (cursor->Contained) cphase=1; - fctCursor.Draw(cgo.Surface,cgo.X+cox,cgo.Y+coy,cphase); - if (cursor->Info) - { - int32_t texthgt = ::GraphicsResource.FontRegular.GetLineHeight(); - StdStrBuf str; - if (cursor->Info->Rank>0) - { - str.Format("%s|%s",cursor->Info->sRankName.getData(),cursor->GetName ()); - texthgt += texthgt; - } - else str = cursor->GetName(); - - pDraw->TextOut(str.getData(), ::GraphicsResource.FontRegular, 1.0, cgo.Surface, - cgo.X + cox + fctCursor.Wdt / 2, - cgo.Y + coy - 2 - texthgt, - 0xffff0000, ACenter); - - } - } + str.Format("%s|%s", cursor->Info->sRankName.getData(), cursor->GetName()); + texthgt += texthgt; } + else str = cursor->GetName(); + + pDraw->TextOut(str.getData(), ::GraphicsResource.FontRegular, 1.0, cgo.Surface, + drawX, + drawY - static_cast(texthgt) / 2.0, + 0xffff0000, ACenter); + + } + } + } + // Reset zoom + r.Zoom = zoom; + pDraw->SetZoom(r); } void C4Game::Ticks() diff --git a/src/game/C4Game.h b/src/game/C4Game.h index f577ebb3f..dfb80a732 100644 --- a/src/game/C4Game.h +++ b/src/game/C4Game.h @@ -142,7 +142,7 @@ public: void Evaluate(); void ShowGameOverDlg(); bool DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType eEventType, bool fAlt, bool fCtrl, bool fShift, bool fRepeated, class C4GUI::Dialog *pForDialog=NULL, bool fPlrCtrlOnly=false, int32_t iStrength=-1); - void DrawCursors(C4TargetFacet &cgo, int32_t iPlayer); + void DrawCrewOverheadText(C4TargetFacet &cgo, int32_t iPlayer); void FixRandom(int32_t iSeed); bool Init(); bool PreInit(); diff --git a/src/game/C4Viewport.cpp b/src/game/C4Viewport.cpp index 54fb535a6..c76803eab 100644 --- a/src/game/C4Viewport.cpp +++ b/src/game/C4Viewport.cpp @@ -274,7 +274,7 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay) if (::GraphicsSystem.ShowPathfinder) Game.PathFinder.Draw(cgo); // Draw overlay - if (!Game.C4S.Head.Film || !Game.C4S.Head.Replay) Game.DrawCursors(cgo, Player); + if (!Game.C4S.Head.Film || !Game.C4S.Head.Replay) Game.DrawCrewOverheadText(cgo, Player); // Lights overlay if (::GraphicsSystem.ShowLights && pFoW) pFoW->Render(&cgo); diff --git a/src/graphics/C4GraphicsResource.cpp b/src/graphics/C4GraphicsResource.cpp index b68f21733..774fd3988 100644 --- a/src/graphics/C4GraphicsResource.cpp +++ b/src/graphics/C4GraphicsResource.cpp @@ -312,8 +312,8 @@ bool C4GraphicsResource::LoadCursorGfx() return false; // adjust dependant faces int32_t iCursorSize = fctMouseCursor.Hgt; - fctCursor.Set(fctMouseCursor.Surface, 35*iCursorSize, 0, iCursorSize, iCursorSize); - fctDropTarget.Set(fctMouseCursor.Surface, 38*iCursorSize, 0, iCursorSize, iCursorSize); + fctCursor.Set(fctMouseCursor.Surface, 11*iCursorSize, 0, iCursorSize, iCursorSize); + fctDropTarget.Set(fctMouseCursor.Surface, 11*iCursorSize, 0, iCursorSize, iCursorSize); return true; } diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp index 712275a6f..dd080a3a3 100644 --- a/src/object/C4Object.cpp +++ b/src/object/C4Object.cpp @@ -2170,46 +2170,6 @@ void C4Object::DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDraw float newzoom = cgo.Zoom; if (eDrawMode!=ODM_Overlay) GetDrawPosition(cgo, offX, offY, newzoom); ZoomDataStackItem zdsi(newzoom); - // Clonk name - // Name of Owner/Clonk (only when Crew Member; never in films) - if (OCF & OCF_CrewMember) - if ((Config.Graphics.ShowCrewNames || Config.Graphics.ShowCrewCNames) && (!Game.C4S.Head.Film || !Game.C4S.Head.Replay)) - if (!eDrawMode) - if (Owner != iByPlayer && !Contained) - { - // inside screen range? - if (!Inside(offX + Shape.GetX(), cgo.X - Shape.Wdt, cgo.X + cgo.Wdt) - || !Inside(offY + Shape.GetY(), cgo.Y - Shape.Hgt, cgo.Y + cgo.Hgt)) return; - // get player - C4Player* pOwner = ::Players.Get(Owner); - if (pOwner) - if (!Hostile(Owner, iByPlayer)) - if (!pOwner->IsInvisible()) - { - // compose string - char szText[C4GM_MaxText+1]; - if (Config.Graphics.ShowCrewNames) - if (Config.Graphics.ShowCrewCNames) - sprintf(szText, "%s (%s)", GetName(), pOwner->GetName()); - else - SCopy(pOwner->GetName(),szText); - else - SCopy(GetName(),szText); - // Word wrap to cgo width - int32_t iCharWdt, dummy; ::GraphicsResource.FontRegular.GetTextExtent("m", iCharWdt, dummy, false); - int32_t iMaxLine = Max( cgo.Wdt / iCharWdt, 20 ); - SWordWrap(szText,' ','|',iMaxLine); - // Adjust position by output boundaries - float iTX,iTY; - int iTWdt,iTHgt; - ::GraphicsResource.FontRegular.GetTextExtent(szText,iTWdt,iTHgt, true); - iTX = Clamp(offX, cgo.X + iTWdt / 2, cgo.X + cgo.Wdt - iTWdt / 2); - iTY = Clamp(offY - Def->Shape.Hgt / 2 - 20 - iTHgt, cgo.Y, cgo.Y + cgo.Hgt - iTHgt); - // Draw - pDraw->TextOut(szText, ::GraphicsResource.FontRegular, 1.0, cgo.Surface, iTX, iTY, - pOwner->ColorDw|0x7f000000,ACenter); - } - } // TopFace if (!(TopFace.Surface || (OCF & OCF_Construct))) return; // Output bounds check