Object Draw: Factorize calculation of position on screen into one function

floating-point
Günther Brammer 2010-09-23 03:51:08 +02:00
parent 43583b4ac9
commit 68d868f3ba
4 changed files with 145 additions and 105 deletions

View File

@ -405,13 +405,14 @@ void C4EditCursor::Draw(C4TargetFacet &cgo, float Zoom)
for (clnk=Selection.First; clnk && (cobj=clnk->Obj); clnk=clnk->Next)
{
// target pos (parallax)
float cotx = cgo.TargetX, coty = cgo.TargetY; cobj->TargetPos(cotx, coty, cgo);
float offX, offY, newzoom;
cobj->GetDrawPosition(cgo, Zoom, offX, offY, newzoom);
FLOAT_RECT frame =
{
(cobj->GetX()+cobj->Shape.x-cotx)*Zoom + cgo.X,
(cobj->GetX()+cobj->Shape.x-cotx)*Zoom + cgo.X + cobj->Shape.Wdt*Zoom,
(cobj->GetY()+cobj->Shape.y-coty)*Zoom + cgo.Y,
(cobj->GetY()+cobj->Shape.y-coty)*Zoom + cgo.Y + cobj->Shape.Hgt*Zoom
(offX+cobj->Shape.x-cgo.X)*newzoom + cgo.X,
(offX+cobj->Shape.x-cgo.X)*newzoom + cgo.X + cobj->Shape.Wdt*newzoom,
(offY+cobj->Shape.y-cgo.Y)*newzoom + cgo.Y,
(offY+cobj->Shape.y-cgo.Y)*newzoom + cgo.Y + cobj->Shape.Hgt*newzoom
};
DrawSelectMark(cgo, frame);
// highlight selection if shift is pressed

View File

@ -751,6 +751,7 @@ void C4GraphicsOverlay::UpdateFacet()
fctBlit.Set(pSourceGfx->GetBitmap(),
action->GetPropertyInt(P_X), action->GetPropertyInt(P_Y),
action->GetPropertyInt(P_Wdt), action->GetPropertyInt(P_Hgt));
// FIXME: fctBlit.TargetX has to be set here
}
else
{
@ -987,9 +988,10 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
assert(!IsPicture());
assert(pForObj);
// get target pos
float cotx=cgo.TargetX,coty=cgo.TargetY; pForObj->TargetPos(cotx, coty, cgo);
float iTx = fixtof(pForObj->fix_x) - cotx + cgo.X,
iTy = fixtof(pForObj->fix_y) - coty + cgo.Y;
float offX, offY;
float newzoom;
pForObj->GetDrawPosition(cgo, 1.0, offX, offY, newzoom);
// special blit mode
if (dwBlitMode == C4GFXBLIT_PARENT)
(OverlayObj ? static_cast<C4Object*>(OverlayObj) : pForObj)->PrepareDrawing();
@ -1004,7 +1006,7 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
if (eMode == MODE_Rank)
{
C4TargetFacet ccgo;
ccgo.Set(cgo.Surface, iTx+pForObj->Shape.x,iTy+pForObj->Shape.y,pForObj->Shape.Wdt,pForObj->Shape.Hgt, cgo.TargetX, cgo.TargetY);
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?
@ -1013,22 +1015,15 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
if (eMode == MODE_ObjectPicture)
{
C4Facet fctTarget;
fctTarget.Set(cgo.Surface, iTx+pForObj->Shape.x, iTy+pForObj->Shape.y, pForObj->Shape.Wdt, pForObj->Shape.Hgt);
fctTarget.Set(cgo.Surface, offX+pForObj->Shape.x, offY+pForObj->Shape.y, pForObj->Shape.Wdt, pForObj->Shape.Hgt);
OverlayObj->DrawPicture(fctTarget, false, NULL, &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.
// This ignores any other transform than offset, and it doesn't work with parallax overlay objects yet
// (But any parallaxity of pForObj is regarded in calculation of cotx/y!)
int32_t oldTx = cgo.TargetX, oldTy = cgo.TargetY;
cgo.TargetX = cotx - pForObj->GetX() + OverlayObj->GetX() - Transform.GetXOffset();
cgo.TargetY = coty - pForObj->GetY() + OverlayObj->GetY() - Transform.GetYOffset();
OverlayObj->Draw(cgo, iByPlayer, C4Object::ODM_Overlay);
OverlayObj->DrawTopFace(cgo, iByPlayer, C4Object::ODM_Overlay);
cgo.TargetX = oldTx;
cgo.TargetY = oldTy;
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)
@ -1065,25 +1060,25 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
if (!pMeshInstance)
{
// draw there
C4DrawTransform trf(Transform, float(iTx), float(iTy));
C4DrawTransform trf(Transform, offX, offY);
if (fZoomToShape)
{
float fZoom = Min<float>((float) pForObj->Shape.Wdt / Max<int>(fctBlit.Wdt,1), (float) pForObj->Shape.Hgt / Max<int>(fctBlit.Hgt,1));
trf.ScaleAt(fZoom, fZoom, float(iTx), float(iTy));
trf.ScaleAt(fZoom, fZoom, offX, offY);
}
fctBlit.DrawT(cgo.Surface, iTx - fctBlit.Wdt/2 + fctBlit.TargetX, iTy - fctBlit.Hgt/2 + fctBlit.TargetY, iPhase, 0, &trf);
fctBlit.DrawT(cgo.Surface, offX - fctBlit.Wdt/2 + fctBlit.TargetX, offY - fctBlit.Hgt/2 + fctBlit.TargetY, iPhase, 0, &trf);
}
else if(eMode == MODE_Base || eMode == MODE_Action)
{
C4Def *pDef = pSourceGfx->pDef;
// draw there
C4DrawTransform trf(Transform, float(iTx), float(iTy));
C4DrawTransform trf(Transform, offX, offY);
if (fZoomToShape)
{
float fZoom = Min<float>((float) pForObj->Shape.Wdt / Max<int>(pDef->Shape.Wdt,1), (float) pForObj->Shape.Hgt / Max<int>(pDef->Shape.Hgt,1));
trf.ScaleAt(fZoom, fZoom, float(iTx), float(iTy));
trf.ScaleAt(fZoom, fZoom, offX, offY);
}
C4Value value;
@ -1092,7 +1087,7 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
if (C4ValueToMatrix(value, &matrix))
lpDDraw->SetMeshTransform(&matrix);
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, iTx - pDef->Shape.Wdt/2.0, iTy - pDef->Shape.Hgt/2.0, pDef->Shape.Wdt, pDef->Shape.Hgt, pForObj->Color, &trf);
lpDDraw->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);
lpDDraw->SetMeshTransform(NULL);
}
else
@ -1117,9 +1112,9 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
if (C4ValueToMatrix(value, &matrix))
lpDDraw->SetMeshTransform(&matrix);
C4DrawTransform trf(Transform, float(iTx), float(iTy));
C4DrawTransform trf(Transform, offX, offY);
lpDDraw->SetPerspective(true);
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, iTx - twdt/2, iTy - thgt/2, twdt, thgt, pForObj->Color, &trf);
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, offX - twdt/2, offY - thgt/2, twdt, thgt, pForObj->Color, &trf);
lpDDraw->SetPerspective(false);
lpDDraw->SetMeshTransform(NULL);
}

View File

@ -2286,7 +2286,7 @@ bool C4Object::SetPhase(int32_t iPhase)
return true;
}
void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode, float offX, float offY)
{
C4Facet ccgo;
@ -2303,8 +2303,11 @@ void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
if (BackParticles && !Contained && eDrawMode!=ODM_BaseOnly) BackParticles.Draw(cgo,this);
// Object output position
float cotx = cgo.TargetX,coty=cgo.TargetY; if (eDrawMode!=ODM_Overlay) TargetPos(cotx, coty, cgo);
float offX = cgo.X + fixtof(fix_x) - cotx, offY = cgo.Y + fixtof(fix_y) - coty;
float newzoom;
if (eDrawMode!=ODM_Overlay)
{
if (!GetDrawPosition(cgo, 1.0, offX, offY, newzoom)) return;
}
bool fYStretchObject=false;
C4PropList* pActionDef = GetAction();
@ -2341,7 +2344,7 @@ void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
{
C4Command *pCom;
int32_t ccx=GetX(),ccy=GetY();
int32_t x1,y1,x2,y2;
float offX1, offY1, offX2, offY2, newzoom;
char szCommand[200];
StdStrBuf Cmds;
int32_t iMoveTos=0;
@ -2353,11 +2356,13 @@ void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
// Angle
int32_t iAngle; iAngle=Angle(ccx,ccy,pCom->Tx._getInt(),pCom->Ty); while (iAngle>180) iAngle-=360;
// Path
x1=ccx-cotx; y1=ccy-coty;
x2=pCom->Tx._getInt()-cotx; y2=pCom->Ty-coty;
Application.DDraw->DrawLineDw(cgo.Surface,cgo.X+x1,cgo.Y+y1,cgo.X+x2,cgo.Y+y2,C4RGB(0xca,0,0));
Application.DDraw->DrawFrameDw(cgo.Surface,cgo.X+x2-1,cgo.Y+y2-1,cgo.X+x2+1,cgo.Y+y2+1,C4RGB(0xca,0,0));
if (x1>x2) Swap(x1,x2); if (y1>y2) Swap(y1,y2);
if(GetDrawPosition(cgo, ccx, ccy, 1.0, offX1, offY1, newzoom) &&
GetDrawPosition(cgo, pCom->Tx._getInt(), pCom->Ty, 1.0, offX2, offY2, newzoom))
{
Application.DDraw->DrawLineDw(cgo.Surface,offX1,offY1,offX2,offY2,C4RGB(0xca,0,0));
Application.DDraw->DrawFrameDw(cgo.Surface,offX2-1,offY2-1,offX2+1,offY2+1,C4RGB(0xca,0,0));
}
ccx=pCom->Tx._getInt(); ccy=pCom->Ty;
// Message
iMoveTos++; szCommand[0]=0;
@ -2384,11 +2389,13 @@ void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
break;
case C4CMD_Transfer:
// Path
x1=ccx-cotx; y1=ccy-coty;
x2=pCom->Tx._getInt()-cotx; y2=pCom->Ty-coty;
Application.DDraw->DrawLineDw(cgo.Surface,cgo.X+x1,cgo.Y+y1,cgo.X+x2,cgo.Y+y2,C4RGB(0,0xca,0));
Application.DDraw->DrawFrameDw(cgo.Surface,cgo.X+x2-1,cgo.Y+y2-1,cgo.X+x2+1,cgo.Y+y2+1,C4RGB(0,0xca,0));
if (x1>x2) Swap(x1,x2); if (y1>y2) Swap(y1,y2);
if(GetDrawPosition(cgo, ccx, ccy, 1.0, offX1, offY1, newzoom) &&
GetDrawPosition(cgo, pCom->Tx._getInt(), pCom->Ty, 1.0, offX2, offY2, newzoom))
{
Application.DDraw->DrawLineDw(cgo.Surface,offX1,offY1,offX2,offY2,C4RGB(0,0xca,0));
Application.DDraw->DrawFrameDw(cgo.Surface,offX2-1,offY2-1,offX2+1,offY2+1,C4RGB(0,0xca,0));
}
ccx=pCom->Tx._getInt(); ccy=pCom->Ty;
// Message
sprintf(szCommand,"%s %s",CommandName(pCom->Command),pCom->Target ? pCom->Target->GetName() : "");
@ -2561,28 +2568,31 @@ void C4Object::Draw(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
}
void C4Object::DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode)
void C4Object::DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDrawMode, float offX, float offY)
{
// Status
if (!Status || !Def) return;
// visible?
if (!IsVisible(iByPlayer, eDrawMode==ODM_Overlay)) return;
// target pos (parallax)
float cotx = cgo.TargetX, coty = cgo.TargetY; if (eDrawMode!=ODM_Overlay) TargetPos(cotx, coty, cgo);
float newzoom;
if (eDrawMode!=ODM_Overlay) GetDrawPosition(cgo, 1.0, offX, offY, 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 (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<int>(GetX() + Shape.GetX() - cotx, 1 - Shape.Wdt, cgo.Wdt)
|| !Inside<int>(GetY() + Shape.GetY() - coty, 1 - Shape.Hgt, cgo.Hgt)) return;
if (!Inside<int>(offX + Shape.GetX(), cgo.X - Shape.Wdt, cgo.X + cgo.Wdt)
|| !Inside<int>(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())
if (pOwner)
if (!Hostile(Owner, iByPlayer))
if (!pOwner->IsInvisible())
{
int32_t X = GetX();
int32_t Y = GetY() - Def->Shape.Hgt / 2 - 20;
// compose string
char szText[C4GM_MaxText+1];
if (Config.Graphics.ShowCrewNames)
@ -2597,41 +2607,38 @@ void C4Object::DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDraw
int32_t iMaxLine = Max<int32_t>( cgo.Wdt / iCharWdt, 20 );
SWordWrap(szText,' ','|',iMaxLine);
// Adjust position by output boundaries
int32_t iTX,iTY,iTWdt,iTHgt;
float iTX,iTY;
int iTWdt,iTHgt;
::GraphicsResource.FontRegular.GetTextExtent(szText,iTWdt,iTHgt, true);
iTX = BoundBy<int>( X-cotx, iTWdt/2, cgo.Wdt-iTWdt/2 );
iTY = BoundBy<int>( Y-coty-iTHgt, 0, cgo.Hgt-iTHgt );
iTX = BoundBy<int>(offX, cgo.X + iTWdt / 2, cgo.X + cgo.Wdt - iTWdt / 2);
iTY = BoundBy<int>(offY - Def->Shape.Hgt / 2 - 20 - iTHgt, cgo.Y, cgo.Y + cgo.Hgt - iTHgt);
// Draw
Application.DDraw->TextOut(szText, ::GraphicsResource.FontRegular, 1.0, cgo.Surface, cgo.X + iTX, cgo.Y + iTY,
Application.DDraw->TextOut(szText, ::GraphicsResource.FontRegular, 1.0, cgo.Surface, iTX, iTY,
pOwner->ColorDw|0x7f000000,ACenter);
}
}
// TopFace
if (!(TopFace.Surface || (OCF & OCF_Construct))) return;
// Output position
float offX = cgo.X + fixtof(fix_x) - cotx, offY = cgo.Y + fixtof(fix_y) - coty;
float cox = fixtof(fix_x) + Shape.GetX() - cotx, coy = fixtof(fix_y) + Shape.GetY() - coty;
// Output bounds check
if (!Inside<float>(cox,1-Shape.Wdt,cgo.Wdt)
|| !Inside<float>(coy,1-Shape.Hgt,cgo.Hgt))
if (!Inside<float>(offX, cgo.X - Shape.Wdt, cgo.X + cgo.Wdt)
|| !Inside<float>(offY, cgo.Y - Shape.Hgt, cgo.Y + cgo.Hgt))
return;
// Don't draw (show solidmask)
if (::GraphicsSystem.ShowSolidMask)
if (SolidMask.Wdt)
return;
if (::GraphicsSystem.ShowSolidMask && SolidMask.Wdt) return;
// Contained
if (Contained) if (eDrawMode!=ODM_Overlay) return;
// Construction sign
if (OCF & OCF_Construct) if (r==0) if (eDrawMode!=ODM_BaseOnly)
{
C4Facet &fctConSign = ::GraphicsResource.fctConstruction;
lpDDraw->Blit(fctConSign.Surface,
fctConSign.X, fctConSign.Y,
fctConSign.Wdt, fctConSign.Hgt,
cgo.Surface,
cgo.X + cox, cgo.Y + coy + Shape.Hgt - fctConSign.Hgt,
fctConSign.Wdt, fctConSign.Hgt, true);
}
if (OCF & OCF_Construct && r == 0)
if (eDrawMode!=ODM_BaseOnly)
{
C4Facet &fctConSign = ::GraphicsResource.fctConstruction;
lpDDraw->Blit(fctConSign.Surface,
fctConSign.X, fctConSign.Y,
fctConSign.Wdt, fctConSign.Hgt,
cgo.Surface,
offX + Shape.GetX(), offY + Shape.GetY() + Shape.Hgt - fctConSign.Hgt,
fctConSign.Wdt, fctConSign.Hgt, true);
}
// FacetTopFace: Override TopFace.GetX()/GetY()
C4PropList* pActionDef = GetAction();
if (pActionDef && pActionDef->GetPropertyInt(P_FacetTopFace))
@ -2651,7 +2658,7 @@ void C4Object::DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDraw
lpDDraw->Blit(TopFace.Surface,
TopFace.X, TopFace.Y, TopFace.Wdt, TopFace.Hgt,
cgo.Surface,
cgo.X + cox + float(Def->TopFace.tx * Con) / FullCon, cgo.Y + coy + float(Def->TopFace.ty * Con) / FullCon,
offX + Shape.GetX() + float(Def->TopFace.tx * Con) / FullCon, offY + Shape.GetY() + float(Def->TopFace.ty * Con) / FullCon,
float(TopFace.Wdt * Con) / FullCon, float(TopFace.Hgt * Con) / FullCon,
true, pDrawTransform ? &C4DrawTransform(*pDrawTransform, offX, offY) : NULL);
else
@ -2660,7 +2667,7 @@ void C4Object::DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer, DrawMode eDraw
TopFace.X,TopFace.Y,
TopFace.Wdt,TopFace.Hgt,
cgo.Surface,
cgo.X + cox + Def->TopFace.tx, cgo.Y + coy + Def->TopFace.ty,
offX + Shape.GetX() + Def->TopFace.tx, offY + Shape.GetY() + Def->TopFace.ty,
TopFace.Wdt, TopFace.Hgt,
true, pDrawTransform ? &C4DrawTransform(*pDrawTransform, offX, offY) : NULL);
// end of color modulation
@ -3159,17 +3166,18 @@ void C4Object::DrawSelectMark(C4TargetFacet &cgo, float Zoom)
// No select marks in film playback
if (Game.C4S.Head.Film && Game.C4S.Head.Replay) return;
// target pos (parallax)
float cotx=cgo.TargetX,coty=cgo.TargetY; TargetPos(cotx, coty, cgo);
float offX, offY, newzoom;
GetDrawPosition(cgo, Zoom, offX, offY, newzoom);
// Output boundary
if (!Inside<float>(fixtof(fix_x) - cotx, 0, cgo.Wdt - 1)
|| !Inside<float>(fixtof(fix_y) - coty, 0, cgo.Hgt - 1)) return;
if (!Inside<float>(offX, cgo.X, cgo.X + cgo.Wdt)
|| !Inside<float>(offY, cgo.Y, cgo.Y + cgo.Hgt)) return;
// Draw select marks
float cox = (fixtof(fix_x) + Shape.GetX() - cotx) * Zoom + cgo.X - 2;
float coy = (fixtof(fix_y) + Shape.GetY() - coty) * Zoom + cgo.Y - 2;
float cox = (offX + Shape.GetX() - cgo.X) * Zoom + cgo.X - 2;
float coy = (offY + Shape.GetY() - cgo.Y) * Zoom + cgo.Y - 2;
GfxR->fctSelectMark.Draw(cgo.Surface,cox,coy,0);
GfxR->fctSelectMark.Draw(cgo.Surface,cox+Shape.Wdt*Zoom,coy,1);
GfxR->fctSelectMark.Draw(cgo.Surface,cox,coy+Shape.Hgt*Zoom,2);
GfxR->fctSelectMark.Draw(cgo.Surface,cox+Shape.Wdt*Zoom,coy+Shape.Hgt*Zoom,3);
GfxR->fctSelectMark.Draw(cgo.Surface,cox+Shape.Wdt*newzoom,coy,1);
GfxR->fctSelectMark.Draw(cgo.Surface,cox,coy+Shape.Hgt*newzoom,2);
GfxR->fctSelectMark.Draw(cgo.Surface,cox+Shape.Wdt*newzoom,coy+Shape.Hgt*newzoom,3);
}
void C4Object::ClearCommands()
@ -4843,9 +4851,10 @@ void C4Object::PlrFoWActualize()
void C4Object::SetAudibilityAt(C4TargetFacet &cgo, int32_t iX, int32_t iY)
{
// target pos (parallax)
float cotx=cgo.TargetX,coty=cgo.TargetY; TargetPos(cotx, coty, cgo);
Audible = Max<int>(Audible, BoundBy(100 - 100 * Distance(cotx + cgo.Wdt / 2, coty + cgo.Hgt / 2, iX,iY) / 700, 0, 100));
AudiblePan = BoundBy<int>(AudiblePan + (iX - (cotx + cgo.Wdt / 2)) / 5, -100, 100);
float offX, offY, newzoom;
GetDrawPosition(cgo, iX, iY, 1.0, offX, offY, newzoom);
Audible = Max<int>(Audible, BoundBy(100 - 100 * Distance(cgo.X + cgo.Wdt / 2, cgo.Y + cgo.Hgt / 2, offX, offY) / 700, 0, 100));
AudiblePan = BoundBy<int>(200 * (offX - cgo.X - (cgo.Wdt / 2)) / cgo.Wdt, -100, 100);
}
bool C4Object::IsVisible(int32_t iForPlr, bool fAsOverlay)
@ -5094,22 +5103,6 @@ bool C4Object::GetDragImage(C4Object **drag_object, C4ID *drag_id)
return true;
}
void C4Object::ApplyParallaxity(float &riTx, float &riTy, const C4Facet &fctViewport)
{
// parallaxity by locals
// special: Negative positions with parallaxity 0 mean HUD elements positioned to the right/bottom
int iParX, iParY;
GetParallaxity(&iParX, &iParY);
if (!iParX && GetX()<0)
riTx = -fctViewport.Wdt;
else
riTx = riTx * iParX / 100;
if (!iParY && GetY()<0)
riTy = -fctViewport.Hgt;
else
riTy = riTy * iParY / 100;
}
bool C4Object::DoSelect()
{
// selection allowed?
@ -5126,6 +5119,58 @@ void C4Object::UnSelect()
Call(PSF_CrewSelection, &C4AulParSet(C4VBool(true)));
}
bool C4Object::GetDrawPosition(const C4TargetFacet & cgo, float zoom,
float & resultx, float & resulty, float & resultzoom)
{
return GetDrawPosition(cgo, fixtof(fix_x), fixtof(fix_y), zoom, resultx, resulty, resultzoom);
}
bool C4Object::GetDrawPosition(const C4TargetFacet & cgo, float objx, float objy, float zoom, float & resultx, float & resulty, float & resultzoom)
{
int iParX, iParY;
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 par = parx; //todo: pary?
// Old
resultzoom = zoom;
if(parx == 0 && fix_x < 0)
resultx = cgo.X + objx + cgo.Wdt;
else
resultx = cgo.X + objx - targetx*parx;
if(pary == 0 && fix_y < 0)
resulty = cgo.Y + objy + cgo.Hgt;
else
resulty = cgo.Y + objy - targety*pary;
return true;
// New
// Step 1: project to landscape coordinates
resultzoom = 1.0 / (1.0 - (par - par/zoom));
if (resultzoom < 0 || resultzoom > 100) // FIXME: optimize treshhold
return false;
float rx = ((1 - parx) * targetx) * resultzoom + objx;
float ry = ((1 - pary) * targety) * resultzoom + objy;
// Step 2: convert to screen coordinates
if(parx == 0 && fix_x < 0)
resultx = cgo.X + (objx + cgo.Wdt) * zoom / resultzoom;
else
resultx = cgo.X + (rx - targetx) * zoom / resultzoom;
if(pary == 0 && fix_y < 0)
resulty = cgo.Y + (objy + cgo.Hgt) * zoom / resultzoom;
else
resulty = cgo.Y + (ry - targety) * zoom / resultzoom;
return true;
}
void C4Object::GetViewPosPar(float &riX, float &riY, float tx, float ty, const C4Facet &fctViewport)
{
int iParX, iParY;

View File

@ -257,8 +257,8 @@ public:
bool SetPhase(int32_t iPhase);
void AssignRemoval(bool fExitContents=false);
enum DrawMode { ODM_Normal=0, ODM_Overlay=1, ODM_BaseOnly=2 };
void Draw(C4TargetFacet &cgo, int32_t iByPlayer = -1, DrawMode eDrawMode=ODM_Normal);
void DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer = -1, DrawMode eDrawMode=ODM_Normal);
void Draw(C4TargetFacet &cgo, int32_t iByPlayer = -1, DrawMode eDrawMode=ODM_Normal, float offX=0, float offY=0);
void DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer = -1, DrawMode eDrawMode=ODM_Normal, float offX=0, float offY=0);
void DrawActionFace(C4TargetFacet &cgo, float offX, float offY);
void DrawFace(C4TargetFacet &cgo, float offX, float offY, int32_t iPhaseX=0, int32_t iPhaseY=0);
void DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy, float fwdt, float fhgt, float tx, float ty, float twdt, float thgt, C4DrawTransform* transform);
@ -364,10 +364,9 @@ public:
bool GrabInfo(C4Object *pFrom); // grab info object from other object
bool ShiftContents(bool fShiftBack, bool fDoCalls); // rotate through contents
void DirectComContents(C4Object *pTarget, bool fDoCalls); // direct com: scroll contents to given ID
inline void TargetPos(float &riTx, float &riTy, const C4Facet &fctViewport) // update scroll pos applying parallaxity
{ if (Category & C4D_Parallax) ApplyParallaxity(riTx, riTy, fctViewport); }
void GetParallaxity(int32_t *parX, int32_t *parY);
void ApplyParallaxity(float &riTx, float &riTy, const C4Facet &fctViewport); // apply parallaxity by locals of object
bool GetDrawPosition(const C4TargetFacet & cgo, float zoom, float & resultx, float & resulty, float & resultzoom); // converts the object's position into screen coordinates
bool GetDrawPosition(const C4TargetFacet & cgo, float x, float y, float zoom, float & resultx, float & resulty, float & resultzoom); // converts object coordinates into screen coordinates
bool IsInLiquidCheck(); // returns whether the Clonk is within liquid material
void UpdateInLiquid(); // makes splash when a liquid is entered
void GrabContents(C4Object *pFrom); // grab all contents that don't reject it