Support subpixel object movement in the editor

This also converts internal usage of ForcePosition to C4Real. For the
attach procedure, this should only result in smoother movements, but the
consequences for flight are less clear.
Günther Brammer 2010-10-10 18:46:23 +02:00
parent ecf6fa550e
commit 25d74134c7
8 changed files with 29 additions and 38 deletions

View File

@ -901,7 +901,7 @@ void C4ControlJoinPlayer::CompileFunc(StdCompiler *pComp)
// *** C4ControlEMMoveObject
C4ControlEMMoveObject::C4ControlEMMoveObject(C4ControlEMObjectAction eAction, int32_t tx, int32_t ty, C4Object *pTargetObj,
C4ControlEMMoveObject::C4ControlEMMoveObject(C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj,
int32_t iObjectNum, int32_t *pObjects, const char *szScript)
: eAction(eAction), tx(tx), ty(ty), iTargetObj(::Objects.ObjectNumber(pTargetObj)),
iObjectNum(iObjectNum), pObjects(pObjects), Script(szScript, true)
@ -927,7 +927,7 @@ void C4ControlEMMoveObject::Execute() const
for (int i=0; i<iObjectNum; ++i)
if ((pObj = ::Objects.SafeObjectPointer(pObjects[i]))) if (pObj->Status)
{
pObj->ForcePosition(pObj->GetX()+tx,pObj->GetY()+ty);
pObj->ForcePosition(pObj->fix_x+tx,pObj->fix_y+ty);
pObj->xdir=pObj->ydir=0;
pObj->Mobile = false;
}
@ -977,8 +977,8 @@ void C4ControlEMMoveObject::Execute() const
ScriptCtrl.SetTargetObj(pObjects[i]);
ScriptCtrl.Execute();
}
break;
}
break;
case EMMO_Remove:
{
if (!pObjects) return;
@ -988,7 +988,7 @@ void C4ControlEMMoveObject::Execute() const
if ((pObj = ::Objects.SafeObjectPointer(pObjects[i])))
pObj->AssignRemoval();
}
break; // Here was fallthrough. Seemed wrong. ck.
break;
case EMMO_Exit:
{
if (!pObjects) return;
@ -998,7 +998,7 @@ void C4ControlEMMoveObject::Execute() const
if ((pObj = ::Objects.SafeObjectPointer(pObjects[i])))
pObj->Exit(pObj->GetX(), pObj->GetY(), pObj->r);
}
break; // Same. ck.
break;
}
// update property dlg & status bar
if (fLocalCall)

View File

@ -353,12 +353,12 @@ class C4ControlEMMoveObject : public C4ControlPacket // sync
{
public:
C4ControlEMMoveObject() : pObjects(NULL) { }
C4ControlEMMoveObject(C4ControlEMObjectAction eAction, int32_t tx, int32_t ty, C4Object *pTargetObj,
C4ControlEMMoveObject(C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj,
int32_t iObjectNum = 0, int32_t *pObjects = NULL, const char *szScript = NULL);
~C4ControlEMMoveObject();
protected:
C4ControlEMObjectAction eAction; // action to be performed
int32_t tx,ty; // target position
C4Real tx,ty; // target position
int32_t iTargetObj; // enumerated ptr to target object
int32_t iObjectNum; // number of objects moved
int32_t *pObjects; // pointer on array of objects moved

View File

@ -76,7 +76,7 @@ void C4EditCursor::Execute()
case C4CNS_ModeEdit:
// Hold selection
if (Hold)
EMMoveObject(EMMO_Move, 0, 0, NULL, &Selection);
EMMoveObject(EMMO_Move, Fix0, Fix0, NULL, &Selection);
break;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4CNS_ModeDraw:
@ -153,7 +153,7 @@ bool C4EditCursor::Move(float iX, float iY, WORD wKeyFlags)
// Hold
if (!DragFrame && Hold)
{
MoveSelection(int32_t(xoff),int32_t(yoff));
MoveSelection(ftofix(xoff),ftofix(yoff));
UpdateDropTarget(wKeyFlags);
}
// Update target
@ -370,7 +370,7 @@ bool C4EditCursor::RightButtonUp()
bool C4EditCursor::Delete()
{
if (!EditingOK()) return false;
EMMoveObject(EMMO_Remove, 0, 0, NULL, &Selection);
EMMoveObject(EMMO_Remove, Fix0, Fix0, NULL, &Selection);
if (::Control.isCtrlHost())
{
OnSelectionChanged();
@ -395,7 +395,7 @@ bool C4EditCursor::OpenPropTools()
bool C4EditCursor::Duplicate()
{
EMMoveObject(EMMO_Duplicate, 0, 0, NULL, &Selection);
EMMoveObject(EMMO_Duplicate, Fix0, Fix0, NULL, &Selection);
return true;
}
@ -485,9 +485,9 @@ void C4EditCursor::DrawSelectMark(C4Facet &cgo, FLOAT_RECT frame)
}
void C4EditCursor::MoveSelection(int32_t iXOff, int32_t iYOff)
void C4EditCursor::MoveSelection(C4Real XOff, C4Real YOff)
{
EMMoveObject(EMMO_Move, iXOff, iYOff, NULL, &Selection);
EMMoveObject(EMMO_Move, XOff, YOff, NULL, &Selection);
}
void C4EditCursor::FrameSelection()
@ -505,7 +505,7 @@ void C4EditCursor::FrameSelection()
bool C4EditCursor::In(const char *szText)
{
EMMoveObject(EMMO_Script, 0, 0, NULL, &Selection, szText);
EMMoveObject(EMMO_Script, Fix0, Fix0, NULL, &Selection, szText);
return true;
}
@ -679,7 +679,7 @@ void C4EditCursor::GrabContents()
Hold=true;
// Exit all objects
EMMoveObject(EMMO_Exit, 0, 0, NULL, &Selection);
EMMoveObject(EMMO_Exit, Fix0, Fix0, NULL, &Selection);
}
void C4EditCursor::UpdateDropTarget(WORD wKeyFlags)
@ -703,7 +703,7 @@ void C4EditCursor::UpdateDropTarget(WORD wKeyFlags)
void C4EditCursor::PutContents()
{
if (!DropTarget) return;
EMMoveObject(EMMO_Enter, 0, 0, DropTarget, &Selection);
EMMoveObject(EMMO_Enter, Fix0, Fix0, DropTarget, &Selection);
}
C4Object *C4EditCursor::GetTarget()
@ -769,7 +769,7 @@ void C4EditCursor::ApplyToolPicker()
Hold=false;
}
void C4EditCursor::EMMoveObject(C4ControlEMObjectAction eAction, int32_t tx, int32_t ty, C4Object *pTargetObj, const C4ObjectList *pObjs, const char *szScript)
void C4EditCursor::EMMoveObject(C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj, const C4ObjectList *pObjs, const char *szScript)
{
// construct object list
int32_t iObjCnt = 0; int32_t *pObjIDs = NULL;

View File

@ -95,8 +95,8 @@ protected:
void ApplyToolBrush();
void DrawSelectMark(C4Facet &cgo, FLOAT_RECT r);
void FrameSelection();
void MoveSelection(int32_t iXOff, int32_t iYOff);
void EMMoveObject(enum C4ControlEMObjectAction eAction, int32_t tx, int32_t ty, C4Object *pTargetObj, const C4ObjectList *pObjs = NULL, const char *szScript = NULL);
void MoveSelection(C4Real iXOff, C4Real iYOff);
void EMMoveObject(enum C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj, const C4ObjectList *pObjs = NULL, const char *szScript = NULL);
void EMControl(enum C4PacketType eCtrlType, class C4ControlPacket *pCtrl);
#ifdef WITH_DEVELOPER_MODE

View File

@ -504,16 +504,9 @@ void C4Object::CopyMotion(C4Object *from)
xdir=from->xdir; ydir=from->ydir;
}
void C4Object::ForcePosition(int32_t tx, int32_t ty)
void C4Object::ForcePosition(C4Real tx, C4Real ty)
{
fix_x=itofix(tx); fix_y=itofix(ty);
UpdatePos();
UpdateSolidMask(false);
}
void C4Object::ForcePosition(int32_t tx, int32_t ty, long iPrec)
{
fix_x=itofix(tx, iPrec); fix_y=itofix(ty, iPrec);
fix_x=tx; fix_y=ty;
UpdatePos();
UpdateSolidMask(false);
}

View File

@ -3805,12 +3805,12 @@ void C4Object::ContactAction()
bool fAllowDown = !(t_contact & CNAT_Bottom);
if (t_contact & CNAT_Right)
{
ForcePosition(GetX() - 1, GetY() + fAllowDown);
ForcePosition(fix_x - 1, fix_y + fAllowDown);
xdir=ydir=0;
}
if (t_contact & CNAT_Left)
{
ForcePosition(GetX() + 1, GetY() + fAllowDown);
ForcePosition(fix_x + 1, fix_y + fAllowDown);
xdir=ydir=0;
}
}
@ -3818,7 +3818,7 @@ void C4Object::ContactAction()
{
if (t_contact & CNAT_Top)
{
ForcePosition(GetX(), GetY() + 1);
ForcePosition(fix_x, fix_y + 1);
xdir=ydir=0;
}
}
@ -4603,9 +4603,9 @@ void C4Object::ExecAction()
}
// Force position
ForcePosition(Action.Target->GetX()+Action.Target->Shape.VtxX[Action.Data&255]
ForcePosition(Action.Target->fix_x + Action.Target->Shape.VtxX[Action.Data&255]
-Shape.VtxX[Action.Data>>8],
Action.Target->GetY()+Action.Target->Shape.VtxY[Action.Data&255]
Action.Target->fix_y + Action.Target->Shape.VtxY[Action.Data&255]
-Shape.VtxY[Action.Data>>8]);
// must zero motion...
xdir=ydir=0;

View File

@ -307,8 +307,7 @@ public:
bool Enter(C4Object *pTarget, bool fCalls=true, bool fCopyMotion=true, bool *pfRejectCollect=NULL);
bool Exit(int32_t iX=0, int32_t iY=0, int32_t iR=0, C4Real iXDir=Fix0, C4Real iYDir=Fix0, C4Real iRDir=Fix0, bool fCalls=true);
void CopyMotion(C4Object *from);
void ForcePosition(int32_t tx, int32_t ty);
void ForcePosition(int32_t tx, int32_t ty, long iPrec);
void ForcePosition(C4Real tx, C4Real ty);
void MovePosition(int32_t dx, int32_t dy);
void DoMotion(int32_t mx, int32_t my);
bool ActivateEntrance(int32_t by_plr, C4Object *by_obj);

View File

@ -457,14 +457,13 @@ static C4Void FnRemoveObject(C4AulObjectContext *cthr, bool fEjectContents)
static C4Void FnSetPosition(C4AulObjectContext *cthr, long iX, long iY, bool fCheckBounds, long iPrec)
{
if (!iPrec) iPrec = 1;
C4Real i_x = itofix(iX, iPrec), i_y = itofix(iY, iPrec);
if (fCheckBounds)
{
// BoundsCheck takes ref to C4Real and not to long
C4Real i_x = itofix(iX, iPrec), i_y = itofix(iY, iPrec);
cthr->Obj->BoundsCheck(i_x, i_y);
iX = fixtoi(i_x, iPrec); iY = fixtoi(i_y, iPrec);
}
cthr->Obj->ForcePosition(iX,iY, iPrec);
cthr->Obj->ForcePosition(i_x, i_y);
// update liquid
cthr->Obj->UpdateInLiquid();
return C4VNull;