mirror of
https://github.com/microsoft/Microsoft-3D-Movie-Maker.git
synced 2024-11-22 10:22:40 +01:00
697 lines
18 KiB
C++
697 lines
18 KiB
C++
/* Copyright (c) Microsoft Corporation.
|
|
Licensed under the MIT License. */
|
|
|
|
/***************************************************************************
|
|
|
|
bkgd.cpp: Background class
|
|
|
|
Primary Author: ******
|
|
Review Status: REVIEWED - any changes to this file must be reviewed!
|
|
|
|
A BKGD (background) consists of a set of light sources (GLLT), a
|
|
background sound (SND), and one or more camera views. Each camera view
|
|
consists of a camera specification, a pre-rendered RGB bitmap, and a
|
|
pre-rendered Z-buffer. Here's how the chunks look:
|
|
|
|
BKGD // Contains stage bounding cuboid
|
|
|
|
|
+---GLLT (chid 0) // GL of light position specs (LITEs)
|
|
|
|
|
+---SND (chid 0) // Background sound/music
|
|
|
|
|
+---CAM (chid 0) // Contains camera pos/orient matrix, hither, yon
|
|
| |
|
|
| +---MBMP (chid 0) // Background RGB bitmap
|
|
| |
|
|
| +---ZBMP (chid 0) // Background Z-buffer
|
|
|
|
|
+---CAM (chid 1)
|
|
| |
|
|
| +---MBMP (chid 0)
|
|
| |
|
|
| +---ZBMP (chid 0)
|
|
|
|
|
+---CAM (chid 2)
|
|
. |
|
|
. +---MBMP (chid 0)
|
|
. |
|
|
+---ZBMP (chid 0)
|
|
|
|
***************************************************************************/
|
|
#include "soc.h"
|
|
ASSERTNAME
|
|
|
|
RTCLASS(BKGD)
|
|
|
|
const CHID kchidBds = 0; // Background default sound
|
|
const CHID kchidGllt = 0; // GL of LITEs
|
|
const CHID kchidGlcr = 0; // Palette
|
|
const br_colour kbrcLight = BR_COLOUR_RGB(0xff, 0xff, 0xff);
|
|
|
|
/***************************************************************************
|
|
Add the background's chunks (excluding camera views) to the tag list
|
|
***************************************************************************/
|
|
bool BKGD::FAddTagsToTagl(PTAG ptagBkgd, PTAGL ptagl)
|
|
{
|
|
AssertVarMem(ptagBkgd);
|
|
AssertPo(ptagl, 0);
|
|
|
|
if (!ptagl->FInsertTag(ptagBkgd, fFalse))
|
|
return fFalse;
|
|
if (!ptagl->FInsertChild(ptagBkgd, kchidBds, kctgBds))
|
|
return fFalse;
|
|
if (!ptagl->FInsertChild(ptagBkgd, kchidGllt, kctgGllt))
|
|
return fFalse;
|
|
if (!ptagl->FInsertChild(ptagBkgd, kchidGlcr, kctgColorTable))
|
|
return fFalse;
|
|
|
|
// Have to cache first camera view since scene switches to it
|
|
// automatically
|
|
if (!ptagl->FInsertChild(ptagBkgd, 0, kctgCam))
|
|
return fFalse;
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Cache the background's chunks (excluding camera views) to HD
|
|
***************************************************************************/
|
|
bool BKGD::FCacheToHD(PTAG ptagBkgd)
|
|
{
|
|
AssertVarMem(ptagBkgd);
|
|
|
|
TAG tagBds;
|
|
TAG tagGllt;
|
|
TAG tagGlcr;
|
|
TAG tagCam;
|
|
|
|
// Build the child tags
|
|
if (!vptagm->FBuildChildTag(ptagBkgd, kchidBds, kctgBds, &tagBds))
|
|
return fFalse;
|
|
if (!vptagm->FBuildChildTag(ptagBkgd, kchidGllt, kctgGllt, &tagGllt))
|
|
return fFalse;
|
|
if (!vptagm->FBuildChildTag(ptagBkgd, kchidGlcr, kctgColorTable, &tagGlcr))
|
|
return fFalse;
|
|
if (!vptagm->FBuildChildTag(ptagBkgd, 0, kctgCam, &tagCam))
|
|
return fFalse;
|
|
|
|
// Cache the BKGD chunk
|
|
if (!vptagm->FCacheTagToHD(ptagBkgd, fFalse))
|
|
return fFalse;
|
|
|
|
// Cache the child chunks
|
|
if (!vptagm->FCacheTagToHD(&tagBds))
|
|
return fFalse;
|
|
if (!vptagm->FCacheTagToHD(&tagGllt))
|
|
return fFalse;
|
|
if (!vptagm->FCacheTagToHD(&tagGlcr))
|
|
return fFalse;
|
|
|
|
// Have to cache first camera view since scene switches to it
|
|
// automatically
|
|
if (!vptagm->FCacheTagToHD(&tagCam))
|
|
return fFalse;
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
A PFNRPO to read a BKGD from a file
|
|
***************************************************************************/
|
|
bool BKGD::FReadBkgd(PCRF pcrf, CTG ctg, CNO cno, PBLCK pblck,
|
|
PBACO *ppbaco, long *pcb)
|
|
{
|
|
AssertPo(pcrf, 0);
|
|
AssertPo(pblck, 0);
|
|
AssertNilOrVarMem(ppbaco);
|
|
AssertVarMem(pcb);
|
|
|
|
BKGD *pbkgd;
|
|
|
|
*pcb = size(BKGD) + size(BACT) + size(BLIT); // estimate BKGD size
|
|
if (pvNil == ppbaco)
|
|
return fTrue;
|
|
pbkgd = NewObj BKGD;
|
|
if (pvNil == pbkgd || !pbkgd->_FInit(pcrf->Pcfl(), ctg, cno))
|
|
{
|
|
TrashVar(ppbaco);
|
|
TrashVar(pcb);
|
|
ReleasePpo(&pbkgd);
|
|
return fFalse;
|
|
}
|
|
AssertPo(pbkgd, 0);
|
|
*ppbaco = pbkgd;
|
|
*pcb = size(BKGD) + LwMul(pbkgd->_cbactLight, size(BACT)) +
|
|
LwMul(pbkgd->_cbactLight, size(BLIT)); // actual BKGD size
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Read a BKGD from the given chunk of the given CFL.
|
|
Note: Although we read the data for the lights here, we don't turn
|
|
them on yet because we don't have a BWLD to add them to. The lights
|
|
are turned on with the first FSetCamera() call.
|
|
***************************************************************************/
|
|
bool BKGD::_FInit(PCFL pcfl, CTG ctg, CNO cno)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertPo(pcfl, 0);
|
|
|
|
BLCK blck;
|
|
BKGDF bkgdf;
|
|
KID kid;
|
|
PGL pgllite = pvNil;
|
|
short bo;
|
|
|
|
_ccam = _Ccam(pcfl, ctg, cno); // compute # of views in this background
|
|
_icam = ivNil;
|
|
|
|
if (!pcfl->FFind(ctg, cno, &blck) || !blck.FUnpackData())
|
|
goto LFail;
|
|
if (blck.Cb() != size(BKGDF))
|
|
goto LFail;
|
|
if (!blck.FReadRgb(&bkgdf, size(BKGDF), 0))
|
|
goto LFail;
|
|
if (kboCur != bkgdf.bo)
|
|
SwapBytesBom(&bkgdf, kbomBkgdf);
|
|
Assert(kboCur == bkgdf.bo, "bad BKGDF");
|
|
|
|
if (!pcfl->FGetName(ctg, cno, &_stn))
|
|
goto LFail;
|
|
|
|
// Get the default sound
|
|
if (pcfl->FGetKidChidCtg(ctg, cno, kchidBds, kctgBds, &kid))
|
|
{
|
|
if (!pcfl->FFind(kid.cki.ctg, kid.cki.cno, &blck) || !blck.FUnpackData())
|
|
goto LFail;
|
|
if (blck.Cb() != size(BDS))
|
|
goto LFail;
|
|
if (!blck.FReadRgb(&_bds, size(BDS), 0))
|
|
goto LFail;
|
|
if (kboCur != _bds.bo)
|
|
SwapBytesBom(&_bds, kbomBds);
|
|
Assert(kboCur == _bds.bo, "bad BDS");
|
|
}
|
|
else
|
|
{
|
|
_bds.tagSnd.sid = ksidInvalid;
|
|
}
|
|
|
|
|
|
// If there is a GLCR child, get it
|
|
if (pcfl->FGetKidChidCtg(ctg, cno, kchidGlcr, kctgColorTable, &kid))
|
|
{
|
|
if (!pcfl->FFind(kid.cki.ctg, kid.cki.cno, &blck))
|
|
goto LFail;
|
|
_pglclr = GL::PglRead(&blck, &bo);
|
|
if (_pglclr != pvNil)
|
|
{
|
|
if (kboOther == bo)
|
|
SwapBytesRglw(_pglclr->QvGet(0), _pglclr->IvMac());
|
|
}
|
|
_bIndexBase = bkgdf.bIndexBase;
|
|
}
|
|
else
|
|
_pglclr = pvNil;
|
|
|
|
// Read the GL of LITEs (GLLT)
|
|
if (!pcfl->FGetKidChidCtg(ctg, cno, kchidGllt, kctgGllt, &kid))
|
|
goto LFail;
|
|
if (!pcfl->FFind(kid.cki.ctg, kid.cki.cno, &blck))
|
|
goto LFail;
|
|
pgllite = GL::PglRead(&blck, &bo);
|
|
if (pvNil == pgllite)
|
|
goto LFail;
|
|
Assert(pgllite->CbEntry() == size(LITE),
|
|
"bad pgllite...you may need to update bkgds.chk");
|
|
AssertBomRglw(kbomLite, size(LITE));
|
|
if (kboOther == bo)
|
|
{
|
|
SwapBytesRglw(pgllite->QvGet(0), LwMul(pgllite->IvMac(),
|
|
size(LITE) / size(long)));
|
|
}
|
|
_cbactLight = pgllite->IvMac();
|
|
if (!FAllocPv((void **)&_prgbactLight, LwMul(_cbactLight, size(BACT)),
|
|
fmemClear, mprNormal))
|
|
{
|
|
goto LFail;
|
|
}
|
|
if (!FAllocPv((void **)&_prgblitLight, LwMul(_cbactLight, size(BLIT)),
|
|
fmemClear, mprNormal))
|
|
{
|
|
goto LFail;
|
|
}
|
|
_SetupLights(pgllite);
|
|
ReleasePpo(&pgllite);
|
|
return fTrue;
|
|
LFail:
|
|
Warn("Error reading background");
|
|
ReleasePpo(&pgllite);
|
|
return fFalse;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Return the number of camera views in this scene. CAM chunks need to be
|
|
contiguous CHIDs starting at CHID 0.
|
|
***************************************************************************/
|
|
long BKGD::_Ccam(PCFL pcfl, CTG ctg, CNO cno)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertPo(pcfl, 0);
|
|
|
|
KID kid;
|
|
long ccam;
|
|
|
|
for (ccam = 0; pcfl->FGetKidChidCtg(ctg, cno, ccam, kctgCam, &kid);
|
|
ccam++)
|
|
{
|
|
}
|
|
#ifdef DEBUG
|
|
// Make sure chids are consecutive
|
|
long ckid;
|
|
long ccamT = 0;
|
|
for (ckid = 0; pcfl->FGetKid(ctg, cno, ckid, &kid); ckid++)
|
|
{
|
|
if (kid.cki.ctg == kctgCam)
|
|
ccamT++;
|
|
}
|
|
Assert(ccamT == ccam, "cam chids are not consecutive!");
|
|
#endif
|
|
return ccam;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Fill _prgbactLight and _prgblitLight using a GL of LITEs
|
|
***************************************************************************/
|
|
void BKGD::_SetupLights(PGL pgllite)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertPo(pgllite, 0);
|
|
|
|
long ilite;
|
|
LITE *qlite;
|
|
BACT *pbact;
|
|
BLIT *pblit;
|
|
|
|
for (ilite = 0; ilite < _cbactLight; ilite++)
|
|
{
|
|
qlite = (LITE *)pgllite->QvGet(ilite);
|
|
pbact = &_prgbactLight[ilite];
|
|
pblit = &_prgblitLight[ilite];
|
|
pblit->type = (byte)qlite->lt;
|
|
pblit->colour = kbrcLight;
|
|
pblit->attenuation_c = qlite->rIntensity;
|
|
pbact->type = BR_ACTOR_LIGHT;
|
|
pbact->type_data = pblit;
|
|
pbact->t.type = BR_TRANSFORM_MATRIX34;
|
|
pbact->t.t.mat = qlite->bmat34;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Clean up and delete this background
|
|
***************************************************************************/
|
|
BKGD::~BKGD(void)
|
|
{
|
|
AssertBaseThis(0);
|
|
Assert(!_fLeaveLitesOn, "Shouldn't be freeing background now");
|
|
if (pvNil != _prgbactLight && pvNil != _prgblitLight)
|
|
TurnOffLights();
|
|
FreePpv((void **)&_prgbactLight);
|
|
FreePpv((void **)&_prgblitLight);
|
|
ReleasePpo(&_pglclr);
|
|
ReleasePpo(&_pglapos);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Get the background's name
|
|
***************************************************************************/
|
|
void BKGD::GetName(PSTN pstn)
|
|
{
|
|
AssertThis(0);
|
|
AssertPo(pstn, 0);
|
|
|
|
*pstn = _stn;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Get the custom palette for this background, if any. Returns fFalse if
|
|
an error occurs. Sets *ppglclr to an empty GL and *piclrMin to 0 if
|
|
this background has no custom palette.
|
|
***************************************************************************/
|
|
bool BKGD::FGetPalette(PGL *ppglclr, long *piclrMin)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(ppglclr);
|
|
AssertVarMem(piclrMin);
|
|
|
|
*piclrMin = _bIndexBase;
|
|
if (pvNil == _pglclr) // no custom palette
|
|
{
|
|
*ppglclr = GL::PglNew(size(CLR)); // "palette" with 0 entries
|
|
}
|
|
else
|
|
{
|
|
*ppglclr = _pglclr->PglDup();
|
|
}
|
|
return (pvNil != *ppglclr);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Get the camera position in worldspace
|
|
***************************************************************************/
|
|
void BKGD::GetCameraPos(BRS *pxr, BRS *pyr, BRS *pzr)
|
|
{
|
|
AssertThis(0);
|
|
AssertNilOrVarMem(pxr);
|
|
AssertNilOrVarMem(pyr);
|
|
AssertNilOrVarMem(pzr);
|
|
|
|
if (pvNil != pxr)
|
|
*pxr = _xrCam;
|
|
if (pvNil != pyr)
|
|
*pyr = _yrCam;
|
|
if (pvNil != pzr)
|
|
*pzr = _zrCam;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Turn on lights in pbwld
|
|
***************************************************************************/
|
|
void BKGD::TurnOnLights(PBWLD pbwld)
|
|
{
|
|
AssertThis(0);
|
|
AssertPo(pbwld, 0);
|
|
|
|
long ilite;
|
|
BACT *pbact;
|
|
|
|
if (!_fLites)
|
|
{
|
|
for (ilite = 0; ilite < _cbactLight; ilite++)
|
|
{
|
|
pbact = &_prgbactLight[ilite];
|
|
pbwld->AddActor(pbact);
|
|
BrLightEnable(pbact);
|
|
}
|
|
|
|
_fLites = fTrue;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Turn off lights in pbwld
|
|
***************************************************************************/
|
|
void BKGD::TurnOffLights(void)
|
|
{
|
|
AssertThis(0);
|
|
|
|
long ilite;
|
|
BACT *pbact;
|
|
|
|
if (!_fLites || _fLeaveLitesOn)
|
|
return;
|
|
for (ilite = 0; ilite < _cbactLight; ilite++)
|
|
{
|
|
pbact = &_prgbactLight[ilite];
|
|
BrLightDisable(pbact);
|
|
BrActorRemove(pbact);
|
|
}
|
|
_fLites = fFalse;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Set the camera and associated bitmaps to icam
|
|
***************************************************************************/
|
|
bool BKGD::FSetCamera(PBWLD pbwld, long icam)
|
|
{
|
|
AssertThis(0);
|
|
AssertPo(pbwld, 0);
|
|
AssertIn(icam, 0, Ccam());
|
|
|
|
long capos;
|
|
KID kidCam;
|
|
KID kidRGB;
|
|
KID kidZ;
|
|
BLCK blck;
|
|
CAM cam;
|
|
PCFL pcfl = Pcrf()->Pcfl();
|
|
BREUL breul;
|
|
|
|
TurnOnLights(pbwld);
|
|
|
|
// read new camera data
|
|
if (!pcfl->FGetKidChidCtg(Ctg(), Cno(), icam, kctgCam, &kidCam))
|
|
return fFalse;
|
|
if (!pcfl->FFind(kidCam.cki.ctg, kidCam.cki.cno, &blck) || !blck.FUnpackData())
|
|
return fFalse;
|
|
|
|
// Need at least one actor position
|
|
if (blck.Cb() < size(CAM))
|
|
{
|
|
Bug("CAM chunk not large enough");
|
|
return fFalse;
|
|
}
|
|
capos = (blck.Cb() - size(CAM)) / size(APOS);
|
|
if ((capos * size(APOS) + size(CAM)) != blck.Cb())
|
|
{
|
|
Bug("CAM chunk's extra data not an even multiple of size(APOS)");
|
|
return fFalse;
|
|
}
|
|
|
|
if (!blck.FReadRgb(&cam, size(CAM), 0))
|
|
return fFalse;
|
|
|
|
#ifdef DEBUG
|
|
{
|
|
BOM bomCam = kbomCam, bomCamOld = kbomCamOld;
|
|
Assert(bomCam == bomCamOld, "BOM macros aren't right");
|
|
}
|
|
#endif // DEBUG
|
|
|
|
Assert((size(APOS) / size(long)) * size(long) == size(APOS),
|
|
"APOS not an even number of longs");
|
|
if (kboOther == cam.bo)
|
|
{
|
|
SwapBytesBom(&cam, kbomCam);
|
|
SwapBytesRglw(PvAddBv(&cam, offset(CAM, bmat34Cam)),
|
|
size(cam.bmat34Cam) / size(long));
|
|
SwapBytesRglw(PvAddBv(&cam, size(CAM)),
|
|
capos * (size(APOS) / size(long)));
|
|
}
|
|
Assert(kboCur == cam.bo, "bad cam");
|
|
|
|
// find RGB pict
|
|
if (!pcfl->FGetKidChidCtg(kidCam.cki.ctg, kidCam.cki.cno, 0, kctgMbmp,
|
|
&kidRGB))
|
|
{
|
|
return fFalse;
|
|
}
|
|
// find Z pict
|
|
if (!pcfl->FGetKidChidCtg(kidCam.cki.ctg, kidCam.cki.cno, 0, kctgZbmp,
|
|
&kidZ))
|
|
{
|
|
return fFalse;
|
|
}
|
|
if (!pbwld->FSetBackground(Pcrf(), kidRGB.cki.ctg, kidRGB.cki.cno,
|
|
kidZ.cki.ctg, kidZ.cki.cno))
|
|
{
|
|
return fFalse;
|
|
}
|
|
|
|
// Get actor placements
|
|
ReleasePpo(&_pglapos);
|
|
_iaposNext = _iaposLast = 0;
|
|
if (capos > 0 && (_pglapos = GL::PglNew(size(APOS), capos)) != pvNil)
|
|
{
|
|
AssertDo(_pglapos->FSetIvMac(capos), "Should never fail");
|
|
_pglapos->Lock();
|
|
if (!blck.FReadRgb(_pglapos->QvGet(0), size(APOS) * capos, size(CAM)))
|
|
{
|
|
ReleasePpo(&_pglapos);
|
|
return fFalse;
|
|
}
|
|
_pglapos->Unlock();
|
|
}
|
|
|
|
_icam = icam;
|
|
_xrPlace = cam.apos.xrPlace;
|
|
_yrPlace = cam.apos.yrPlace;
|
|
_zrPlace = cam.apos.zrPlace;
|
|
|
|
_xrCam = cam.bmat34Cam.m[3][0];
|
|
_yrCam = cam.bmat34Cam.m[3][1];
|
|
_zrCam = cam.bmat34Cam.m[3][2];
|
|
|
|
// Find bmat34 without X & Z rotation
|
|
breul.order = BR_EULER_YXY_R;
|
|
BrMatrix34ToEuler(&breul, &cam.bmat34Cam);
|
|
_braRotY = breul.a + breul.c;
|
|
BrMatrix34RotateY(&_bmat34Mouse, _braRotY);
|
|
BrMatrix34PostTranslate(&_bmat34Mouse, cam.bmat34Cam.m[3][0],
|
|
cam.bmat34Cam.m[3][1], cam.bmat34Cam.m[3][2]);
|
|
|
|
pbwld->SetCamera(&cam.bmat34Cam, cam.zrHither, cam.zrYon, cam.aFov);
|
|
pbwld->MarkDirty();
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Gets the matrix for mouse-dragging relative to the camera
|
|
***************************************************************************/
|
|
void BKGD::GetMouseMatrix(BMAT34 *pbmat34)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pbmat34);
|
|
|
|
*pbmat34 = _bmat34Mouse;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Gets the point at which to place new actors for this bkgd/view.
|
|
***************************************************************************/
|
|
void BKGD::GetActorPlacePoint(BRS *pxr, BRS *pyr, BRS *pzr)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pxr);
|
|
AssertVarMem(pyr);
|
|
AssertVarMem(pzr);
|
|
|
|
APOS apos;
|
|
|
|
if (_iaposNext == 0)
|
|
{
|
|
*pxr = _xrPlace;
|
|
*pyr = _yrPlace;
|
|
*pzr = _zrPlace;
|
|
}
|
|
else
|
|
{
|
|
_pglapos->Get(_iaposNext - 1, &apos);
|
|
*pxr = apos.xrPlace;
|
|
*pyr = apos.yrPlace;
|
|
*pzr = apos.zrPlace;
|
|
}
|
|
|
|
_iaposLast = _iaposNext;
|
|
if (_pglapos != pvNil)
|
|
{
|
|
_iaposNext++;
|
|
if (_iaposNext > _pglapos->IvMac())
|
|
_iaposNext = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
ReuseActorPlacePoint
|
|
Resets the current actor place point to the last one used. Call this
|
|
from the actor placement code if the actor was placed at a point other
|
|
than the one you just asked for.
|
|
************************************************************ PETED ***********/
|
|
void BKGD::ReuseActorPlacePoint(void)
|
|
{
|
|
_iaposNext = _iaposLast;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Authoring only. Writes a special file with the given place info.
|
|
***************************************************************************/
|
|
bool BKGD::FWritePlaceFile(BRS xrPlace, BRS yrPlace, BRS zrPlace)
|
|
{
|
|
AssertThis(0);
|
|
Assert(yrPlace == rZero, "are you sure you want non-zero Y?");
|
|
|
|
STN stnFile;
|
|
FNI fni;
|
|
PFIL pfil = pvNil;
|
|
STN stnData;
|
|
FP fp;
|
|
long xr1 = BrScalarToInt(xrPlace);
|
|
long xr2 = LwAbs((long)(1000000.0 * BrScalarToFloat(xrPlace -
|
|
BrIntToScalar(xr1))));
|
|
long yr1 = BrScalarToInt(yrPlace);
|
|
long yr2 = LwAbs((long)(1000000.0 * BrScalarToFloat(yrPlace -
|
|
BrIntToScalar(yr1))));
|
|
long zr1 = BrScalarToInt(zrPlace);
|
|
long zr2 = LwAbs((long)(1000000.0 * BrScalarToFloat(zrPlace -
|
|
BrIntToScalar(zr1))));
|
|
|
|
if (!stnFile.FFormatSz("%s-cam.1-%d.pos", &_stn, _icam + 1))
|
|
goto LFail;
|
|
if (!fni.FBuildFromPath(&stnFile))
|
|
goto LFail;
|
|
if (fni.TExists() == tYes)
|
|
pfil = FIL::PfilOpen(&fni, ffilWriteEnable);
|
|
else
|
|
pfil = FIL::PfilCreate(&fni);
|
|
if (pvNil == pfil)
|
|
goto LFail;
|
|
if (!stnData.FFormatSz("NEW_ACTOR_POS %d.%06d %d.%06d %d.%06d\n\r",
|
|
xr1, xr2, yr1, yr2, zr1, zr2))
|
|
{
|
|
goto LFail;
|
|
}
|
|
if ((fp = pfil->FpMac()) > 0)
|
|
{
|
|
// Go to the end of the file (and write over null byte at end
|
|
// of previous string)
|
|
fp--;
|
|
}
|
|
if (!pfil->FWriteRgb(stnData.Psz(), stnData.Cch() + 1, fp))
|
|
goto LFail;
|
|
ReleasePpo(&pfil);
|
|
return fTrue;
|
|
LFail:
|
|
ReleasePpo(&pfil);
|
|
return fFalse;
|
|
}
|
|
#endif // DEBUG
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the BKGD.
|
|
***************************************************************************/
|
|
void BKGD::AssertValid(ulong grf)
|
|
{
|
|
BKGD_PAR::AssertValid(fobjAllocated);
|
|
AssertIn(_cbactLight, 1, 100); // 100 is sanity check
|
|
AssertIn(_ccam, 1, 100); // 100 is sanity check
|
|
Assert(_icam == ivNil || (_icam >= 0 && _icam < _ccam), "bad _icam");
|
|
AssertPvCb(_prgbactLight, LwMul(_cbactLight, size(BACT)));
|
|
AssertPvCb(_prgblitLight, LwMul(_cbactLight, size(BLIT)));
|
|
AssertPo(&_stn, 0);
|
|
AssertNilOrPo(_pglapos, 0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the BKGD
|
|
***************************************************************************/
|
|
void BKGD::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
BKGD_PAR::MarkMem();
|
|
MarkPv(_prgbactLight);
|
|
MarkPv(_prgblitLight);
|
|
MarkMemObj(_pglclr);
|
|
MarkMemObj(_pglapos);
|
|
}
|
|
#endif //DEBUG
|