forked from Mirrors/openclonk
Object Draw: Really fix message display
parent
e40fbcad03
commit
e6ad5d3bd4
|
@ -5084,6 +5084,11 @@ void C4Object::GetParallaxity(int32_t *parX, int32_t *parY)
|
|||
{
|
||||
assert(parX); assert(parY);
|
||||
*parX = 100; *parY = 100;
|
||||
if (Category & C4D_Foreground)
|
||||
{
|
||||
*parX = 0; *parY = 0;
|
||||
return;
|
||||
}
|
||||
if (!(Category & C4D_Parallax)) return;
|
||||
C4Value parV; GetPropertyVal(P_Parallaxity, &parV);
|
||||
C4ValueArray *par = parV.getArray();
|
||||
|
@ -5135,7 +5140,7 @@ bool C4Object::GetDrawPosition(const C4TargetFacet & cgo, float objx, float objy
|
|||
GetParallaxity(&iParX, &iParY);
|
||||
float targetx = cgo.TargetX; float targety = cgo.TargetY;
|
||||
int width = cgo.Wdt; int height = cgo.Hgt;
|
||||
float parx = iParX/100.0f; float pary = iParY / 100.0f;
|
||||
float parx = iParX / 100.0f; float pary = iParY / 100.0f;
|
||||
float par = parx; //todo: pary?
|
||||
// Old
|
||||
/*resultzoom = zoom;
|
||||
|
@ -5156,7 +5161,7 @@ bool C4Object::GetDrawPosition(const C4TargetFacet & cgo, float objx, float objy
|
|||
|
||||
// Step 1: project to landscape coordinates
|
||||
resultzoom = 1.0 / (1.0 - (par - par/zoom));
|
||||
if (resultzoom < 0 || resultzoom > 100) // FIXME: optimize treshhold
|
||||
if (resultzoom <= 0 || resultzoom > 100) // FIXME: optimize treshhold
|
||||
return false;
|
||||
|
||||
float rx = ((1 - parx) * targetx) * resultzoom + objx;
|
||||
|
|
|
@ -106,7 +106,7 @@ int32_t DrawMessageOffset = -35; // For finding the optimum place to draw startu
|
|||
int32_t PortraitWidth = 64;
|
||||
int32_t PortraitIndent = 10;
|
||||
|
||||
void C4GameMessage::Draw(C4TargetFacet &cgo, int32_t iPlayer, float Zoom)
|
||||
void C4GameMessage::Draw(C4TargetFacet &cgo, int32_t iPlayer)
|
||||
{
|
||||
// Globals or player
|
||||
if (Type == C4GM_Global || ((Type == C4GM_GlobalPlayer) && (iPlayer == Player)))
|
||||
|
@ -188,17 +188,12 @@ void C4GameMessage::Draw(C4TargetFacet &cgo, int32_t iPlayer, float Zoom)
|
|||
{
|
||||
// adjust position by object; care about parallaxity
|
||||
float iMsgX, iMsgY, newzoom;
|
||||
if (Type == C4GM_Target || Type == C4GM_TargetPlayer)
|
||||
{
|
||||
Target->GetDrawPosition(cgo, iMsgX, iMsgY, newzoom);
|
||||
iMsgY -= Target->Def->Shape.Hgt/2+5;
|
||||
iMsgX+=X; iMsgY+=Y;
|
||||
}
|
||||
else
|
||||
{ iMsgX=X; iMsgY=Y; }
|
||||
Target->GetDrawPosition(cgo, iMsgX, iMsgY, newzoom);
|
||||
iMsgY -= Target->Def->Shape.Hgt/2+5;
|
||||
iMsgX+=X; iMsgY+=Y;
|
||||
// check output bounds
|
||||
if (Inside<float>((iMsgX - cgo.X) * newzoom, 0, cgo.Wdt - 1))
|
||||
if (Inside<float>((iMsgY - cgo.Y) * newzoom, 0, cgo.Hgt - 1))
|
||||
if (Inside<float>((iMsgX - cgo.X) * newzoom, 0, cgo.Wdt * cgo.Zoom - 1))
|
||||
if (Inside<float>((iMsgY - cgo.Y) * newzoom, 0, cgo.Hgt * cgo.Zoom - 1))
|
||||
{
|
||||
// if the message is attached to an object and the object
|
||||
// is invisible for that player, the message won't be drawn
|
||||
|
@ -208,7 +203,7 @@ void C4GameMessage::Draw(C4TargetFacet &cgo, int32_t iPlayer, float Zoom)
|
|||
// check fog of war
|
||||
C4Player *pPlr = ::Players.Get(iPlayer);
|
||||
if (pPlr && pPlr->fFogOfWar)
|
||||
if (!pPlr->FoWIsVisible(iMsgX, iMsgY))
|
||||
if (!pPlr->FoWIsVisible(iMsgX + cgo.TargetX - cgo.X, iMsgY + cgo.TargetY - cgo.Y))
|
||||
{
|
||||
// special: Target objects that ignore FoW should display the message even if within FoW
|
||||
if (Type != C4GM_Target && Type != C4GM_TargetPlayer) return;
|
||||
|
@ -217,22 +212,25 @@ void C4GameMessage::Draw(C4TargetFacet &cgo, int32_t iPlayer, float Zoom)
|
|||
// Word wrap to cgo width
|
||||
StdStrBuf sText;
|
||||
if (~dwFlags & C4GM_NoBreak)
|
||||
::GraphicsResource.FontRegular.BreakMessage(Text.getData(), BoundBy<int32_t>(cgo.Wdt, 50, 200), &sText, true);
|
||||
::GraphicsResource.FontRegular.BreakMessage(Text.getData(), BoundBy<int32_t>(cgo.Wdt * cgo.Zoom, 50, 200), &sText, true);
|
||||
else
|
||||
sText.Ref(Text);
|
||||
// Adjust position by output boundaries
|
||||
int32_t iTX,iTY,iTWdt,iTHgt;
|
||||
float iTX,iTY;
|
||||
int iTWdt,iTHgt;
|
||||
::GraphicsResource.FontRegular.GetTextExtent(sText.getData(),iTWdt,iTHgt,true);
|
||||
// +0.5f for proper rounding; avoids oscillations near pixel border:
|
||||
iTX = BoundBy<float>((iMsgX - cgo.X) * newzoom, iTWdt/2, cgo.Wdt - iTWdt / 2) + 0.5f;
|
||||
iTY = BoundBy<float>((iMsgY - cgo.Y) * newzoom - iTHgt, 0, cgo.Hgt - iTHgt) + 0.5f;
|
||||
iTX = BoundBy<float>((iMsgX - cgo.X) * newzoom, iTWdt/2, cgo.Wdt * cgo.Zoom - iTWdt / 2) + 0.5f;
|
||||
iTY = BoundBy<float>((iMsgY - cgo.Y) * newzoom - iTHgt, 0, cgo.Hgt * cgo.Zoom - iTHgt) + 0.5f;
|
||||
// Draw
|
||||
Application.DDraw->TextOut(sText.getData(), ::GraphicsResource.FontRegular, 1.0,
|
||||
cgo.Surface,
|
||||
cgo.X + iTX,
|
||||
cgo.Y + iTY,
|
||||
ColorDw,ACenter);
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "%f %f '%s'\n", iMsgX, iMsgY, Text.getData());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,17 +375,15 @@ void C4GameMessageList::UpdateDef(C4ID idUpdDef)
|
|||
for (cmsg=First; cmsg; cmsg=cmsg->Next) cmsg->UpdateDef(idUpdDef);
|
||||
}
|
||||
|
||||
void C4GameMessageList::Draw(C4TargetFacet &cgo, int32_t iPlayer, float Zoom)
|
||||
void C4GameMessageList::Draw(C4TargetFacet &gui_cgo, C4TargetFacet &cgo, int32_t iPlayer)
|
||||
{
|
||||
C4GameMessage *cmsg;
|
||||
for (cmsg=First; cmsg; cmsg=cmsg->Next)
|
||||
{
|
||||
// determine zoom: GUI object messages need to be drawn in GUI zoom
|
||||
float msg_zoom = Zoom;
|
||||
if ((cmsg->Target && (cmsg->Target->Category & C4D_Foreground)) || cmsg->Type == C4GM_Global || cmsg->Type == C4GM_GlobalPlayer)
|
||||
msg_zoom = C4GUI::GetZoom();
|
||||
// draw msg
|
||||
cmsg->Draw(cgo,iPlayer,msg_zoom);
|
||||
cmsg->Draw(gui_cgo,iPlayer);
|
||||
else
|
||||
cmsg->Draw(cgo,iPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ class C4GameMessage
|
|||
{
|
||||
friend class C4GameMessageList;
|
||||
public:
|
||||
void Draw(C4TargetFacet &cgo, int32_t iPlayer, float Zoom);
|
||||
void Draw(C4TargetFacet &cgo, int32_t iPlayer);
|
||||
C4GameMessage();
|
||||
~C4GameMessage();
|
||||
protected:
|
||||
|
@ -91,7 +91,7 @@ public:
|
|||
void Default();
|
||||
void Clear();
|
||||
void Execute();
|
||||
void Draw(C4TargetFacet &cgo, int32_t iPlayer, float Zoom);
|
||||
void Draw(C4TargetFacet &gui_cgo, C4TargetFacet &cgo, int32_t iPlayer);
|
||||
void ClearPlayers(int32_t iPlayer, int32_t dwPositioningFlags);
|
||||
void ClearPointers(C4Object *pObj);
|
||||
void UpdateDef(C4ID idUpdDef); // called after reloaddef
|
||||
|
|
|
@ -891,10 +891,6 @@ void C4Viewport::DrawOverlay(C4TargetFacet &cgo, const ZoomData &GameZoom)
|
|||
DrawMenu(cgo);
|
||||
C4ST_STOP(MenuStat)
|
||||
}
|
||||
// Game messages
|
||||
C4ST_STARTNEW(MsgStat, "C4Viewport::DrawOverlay: Messages")
|
||||
::Messages.Draw(cgo, Player, Zoom);
|
||||
C4ST_STOP(MsgStat)
|
||||
|
||||
// Control overlays (if not film/replay)
|
||||
if (!Game.C4S.Head.Film || !Game.C4S.Head.Replay)
|
||||
|
@ -980,7 +976,7 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay)
|
|||
C4TargetFacet cgo; cgo.Set(cgo0);
|
||||
ZoomData GameZoom;
|
||||
GameZoom.X = cgo.X; GameZoom.Y = cgo.Y;
|
||||
GameZoom.Zoom = Zoom;
|
||||
GameZoom.Zoom = cgo.Zoom;
|
||||
|
||||
if (fDrawOverlay)
|
||||
{
|
||||
|
@ -991,12 +987,11 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay)
|
|||
if (BorderBottom)Application.DDraw->BlitSurfaceTile(::GraphicsResource.fctBackground.Surface,cgo.Surface,DrawX+BorderLeft,DrawY+ViewHgt-BorderBottom,ViewWdt-BorderLeft-BorderRight,BorderBottom,-DrawX-BorderLeft,-DrawY-ViewHgt+BorderBottom);
|
||||
|
||||
// Set clippers
|
||||
cgo.X += BorderLeft; cgo.Y += BorderTop; cgo.Wdt -= int(float(BorderLeft+BorderRight)/Zoom); cgo.Hgt -= int(float(BorderTop+BorderBottom)/Zoom);
|
||||
cgo.X += BorderLeft; cgo.Y += BorderTop; cgo.Wdt -= int(float(BorderLeft+BorderRight)/cgo.Zoom); cgo.Hgt -= int(float(BorderTop+BorderBottom)/cgo.Zoom);
|
||||
GameZoom.X = cgo.X; GameZoom.Y = cgo.Y;
|
||||
cgo.TargetX += BorderLeft/Zoom; cgo.TargetY += BorderTop/Zoom;
|
||||
// Apply Zoom
|
||||
lpDDraw->SetZoom(GameZoom);
|
||||
cgo.Zoom = GameZoom.Zoom;
|
||||
Application.DDraw->SetPrimaryClipper(cgo.X,cgo.Y,DrawX+ViewWdt-1-BorderRight,DrawY+ViewHgt-1-BorderBottom);
|
||||
}
|
||||
last_game_draw_cgo = cgo;
|
||||
|
@ -1054,27 +1049,33 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay)
|
|||
// now restore complete cgo range for overlay drawing
|
||||
lpDDraw->SetZoom(DrawX,DrawY, fGUIZoom);
|
||||
Application.DDraw->SetPrimaryClipper(DrawX,DrawY,DrawX+(ViewWdt-1),DrawY+(ViewHgt-1));
|
||||
cgo.Set(cgo0);
|
||||
C4TargetFacet gui_cgo;
|
||||
gui_cgo.Set(cgo0);
|
||||
|
||||
cgo.X = DrawX; cgo.Y = DrawY; cgo.Zoom = fGUIZoom;
|
||||
cgo.Wdt = int(float(ViewWdt)/fGUIZoom); cgo.Hgt = int(float(ViewHgt)/fGUIZoom);
|
||||
cgo.TargetX = ViewX; cgo.TargetY = ViewY;
|
||||
gui_cgo.X = DrawX; gui_cgo.Y = DrawY; gui_cgo.Zoom = fGUIZoom;
|
||||
gui_cgo.Wdt = int(float(ViewWdt)/fGUIZoom); gui_cgo.Hgt = int(float(ViewHgt)/fGUIZoom);
|
||||
gui_cgo.TargetX = ViewX; gui_cgo.TargetY = ViewY;
|
||||
|
||||
last_gui_draw_cgo = cgo;
|
||||
last_gui_draw_cgo = gui_cgo;
|
||||
|
||||
// draw custom GUI objects
|
||||
::Objects.ForeObjects.DrawIfCategory(cgo, Player, C4D_Foreground, false);
|
||||
::Objects.ForeObjects.DrawIfCategory(gui_cgo, Player, C4D_Foreground, false);
|
||||
|
||||
// Draw overlay
|
||||
C4ST_STARTNEW(OvrStat, "C4Viewport::Draw: Overlay")
|
||||
|
||||
if (!Application.isFullScreen) Console.EditCursor.Draw(cgo);
|
||||
|
||||
DrawOverlay(cgo, GameZoom);
|
||||
DrawOverlay(gui_cgo, GameZoom);
|
||||
|
||||
// Game messages
|
||||
C4ST_STARTNEW(MsgStat, "C4Viewport::DrawOverlay: Messages")
|
||||
::Messages.Draw(gui_cgo, cgo, Player);
|
||||
C4ST_STOP(MsgStat)
|
||||
|
||||
// Netstats
|
||||
if (::GraphicsSystem.ShowNetstatus)
|
||||
::Network.DrawStatus(cgo);
|
||||
::Network.DrawStatus(gui_cgo);
|
||||
|
||||
C4ST_STOP(OvrStat)
|
||||
|
||||
|
@ -1115,7 +1116,7 @@ void C4Viewport::Execute()
|
|||
C4TargetFacet cgo;
|
||||
CStdWindow * w = pWindow;
|
||||
if (!w) w = &FullScreen;
|
||||
cgo.Set(w->pSurface,DrawX,DrawY,int32_t(ceilf(float(ViewWdt)/Zoom)),int32_t(ceilf(float(ViewHgt)/Zoom)),ViewX,ViewY);
|
||||
cgo.Set(w->pSurface,DrawX,DrawY,int32_t(ceilf(float(ViewWdt)/Zoom)),int32_t(ceilf(float(ViewHgt)/Zoom)),ViewX,ViewY,Zoom);
|
||||
lpDDraw->PrepareRendering(w->pSurface);
|
||||
// Draw
|
||||
Draw(cgo, true);
|
||||
|
|
|
@ -346,6 +346,7 @@ protected:
|
|||
struct ZoomDataStackItem: public ZoomData
|
||||
{
|
||||
ZoomDataStackItem(float newzoom) { lpDDraw->GetZoom(this); lpDDraw->SetZoom(X, Y, newzoom); }
|
||||
ZoomDataStackItem(int X, int Y, float newzoom) { lpDDraw->GetZoom(this); lpDDraw->SetZoom(X, Y, newzoom); }
|
||||
~ZoomDataStackItem() { lpDDraw->SetZoom(*this); }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue