mirror of
https://github.com/microsoft/Microsoft-3D-Movie-Maker.git
synced 2024-12-02 16:07:28 +00:00
2062 lines
47 KiB
C++
2062 lines
47 KiB
C++
/* Copyright (c) Microsoft Corporation.
|
|
Licensed under the MIT License. */
|
|
|
|
/***************************************************************************
|
|
|
|
esl.cpp: Easel classes
|
|
|
|
Primary Author: ******
|
|
Listener Easel: *****
|
|
Review Status: REVIEWED - any changes to this file must be reviewed!
|
|
|
|
ESL is the base class for all easels. It handles cidEaselOk and
|
|
cidEaselCancel commands, and calls the virtual _FAcceptChanges()
|
|
function for cidEaselOk.
|
|
|
|
Custom easels have their own command maps to handle specific messages,
|
|
and implement _FAcceptChanges() to do the right thing.
|
|
|
|
***************************************************************************/
|
|
#include "studio.h"
|
|
ASSERTNAME
|
|
|
|
const long kcchMaxTdt = 50; // max length of a spletter
|
|
const long kdtsMaxRecord = 10 * kdtsSecond; // max time to record a sound
|
|
const long kdtimMeterUpdate = kdtimSecond / 10; // interval to update meter
|
|
const long kcsampSec = 11025; // sampling rate for recorder easel
|
|
long csampSec; // sampling rate for recorder easel
|
|
|
|
RTCLASS(ESL)
|
|
RTCLASS(ESLT)
|
|
RTCLASS(ESLA)
|
|
RTCLASS(SNE)
|
|
RTCLASS(ESLL)
|
|
RTCLASS(LSND)
|
|
RTCLASS(ESLR)
|
|
|
|
/***************************************************************************
|
|
Function to build a GCB for creating a child GOB
|
|
***************************************************************************/
|
|
bool FBuildGcb(PGCB pgcb, long kidParent, long kidChild)
|
|
{
|
|
AssertVarMem(pgcb);
|
|
|
|
PGOK pgokPar;
|
|
RC rcRel;
|
|
|
|
pgokPar = (PGOK)vpapp->Pkwa()->PgobFromHid(kidParent);
|
|
if (pvNil == pgokPar)
|
|
{
|
|
TrashVar(pgcb);
|
|
return fFalse;
|
|
}
|
|
|
|
rcRel.Set(krelZero, krelZero, krelOne, krelOne);
|
|
pgcb->Set(kidChild, pgokPar, fgobNil, kginDefault, pvNil, &rcRel);
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Sets the given gok to the given state
|
|
***************************************************************************/
|
|
void SetGokState(long kid, long st)
|
|
{
|
|
PGOK pgok;
|
|
|
|
pgok = (PGOK)vpapp->Pkwa()->PgobFromHid(kid);
|
|
if (pvNil != pgok && pgok->FIs(kclsGOK) && pgok->Sno() != st)
|
|
pgok->FChangeState(st); // ignore failure
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
// ESL (generic easel) stuff begins here
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
BEGIN_CMD_MAP(ESL, GOK)
|
|
ON_CID_GEN(cidEaselOk, FCmdDismiss, pvNil)
|
|
ON_CID_GEN(cidEaselCancel, FCmdDismiss, pvNil)
|
|
END_CMD_MAP_NIL()
|
|
|
|
|
|
/***************************************************************************
|
|
Create a new easel
|
|
***************************************************************************/
|
|
PESL ESL::PeslNew(PRCA prca, long kidParent, long kidEasel)
|
|
{
|
|
AssertPo(prca, 0);
|
|
|
|
GCB gcb;
|
|
PESL pesl;
|
|
|
|
if (!FBuildGcb(&gcb, kidParent, kidEasel))
|
|
return pvNil;
|
|
pesl = NewObj ESL(&gcb);
|
|
if (pvNil == pesl)
|
|
return pvNil;
|
|
if (!pesl->_FInit(prca, kidEasel))
|
|
{
|
|
ReleasePpo(&pesl);
|
|
return pvNil;
|
|
}
|
|
AssertPo(pesl, 0);
|
|
vpcex->EnqueueCid(cidEaselVisible);
|
|
return pesl;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Initialize the easel and make it visible
|
|
***************************************************************************/
|
|
bool ESL::_FInit(PRCA prca, long kidEasel)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertPo(prca, 0);
|
|
|
|
if (!ESL_PAR::_FInit(vpapp->Pkwa(), kidEasel, prca))
|
|
return fFalse;
|
|
if (!_FEnterState(ksnoInit))
|
|
return fFalse;
|
|
|
|
vpapp->DisableAccel();
|
|
|
|
STDIO::PauseActionButton();
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Clean up and delete this easel
|
|
***************************************************************************/
|
|
ESL::~ESL(void)
|
|
{
|
|
AssertBaseThis(0);
|
|
|
|
vpapp->EnableAccel();
|
|
STDIO::ResumeActionButton();
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Dismiss and delete this easel
|
|
***************************************************************************/
|
|
bool ESL::FCmdDismiss(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
if (pcmd->cid == cidEaselOk)
|
|
{
|
|
bool fDismissEasel = fTrue;
|
|
|
|
// Could return fTrue here if _FAcceptChanges fails to abort
|
|
// dismissal of easel, but instead we release anyway to be
|
|
// consistent with browsers.
|
|
_FAcceptChanges(&fDismissEasel);
|
|
|
|
// If we did not accept the changes, (but nothing failed),
|
|
// then we will not dismiss the easel.
|
|
if(!fDismissEasel)
|
|
return fTrue;
|
|
|
|
}
|
|
Release(); // destroys entire gob tree
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the ESL.
|
|
***************************************************************************/
|
|
void ESL::AssertValid(ulong grf)
|
|
{
|
|
ESL_PAR::AssertValid(fobjAllocated);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the ESL
|
|
***************************************************************************/
|
|
void ESL::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
ESL_PAR::MarkMem();
|
|
}
|
|
#endif //DEBUG
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
// ESLT (text easel) stuff begins here
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
BEGIN_CMD_MAP(ESLT, ESL)
|
|
ON_CID_GEN(cidEaselRotate, FCmdRotate, pvNil)
|
|
ON_CID_GEN(cidEaselTransmogrify, FCmdTransmogrify, pvNil)
|
|
ON_CID_GEN(cidEaselFont, FCmdStartPopup, pvNil)
|
|
ON_CID_GEN(cidEaselShape, FCmdStartPopup, pvNil)
|
|
ON_CID_GEN(cidEaselTexture, FCmdStartPopup, pvNil)
|
|
ON_CID_GEN(cidEaselSetFont, FCmdSetFont, pvNil)
|
|
ON_CID_GEN(cidEaselSetShape, FCmdSetShape, pvNil)
|
|
ON_CID_GEN(cidEaselSetColor, FCmdSetColor, pvNil)
|
|
END_CMD_MAP_NIL()
|
|
|
|
|
|
/***************************************************************************
|
|
Create a new text easel. If pactr is pvNil, this is for a new TDT
|
|
and pstnNew, tdtsNew, and ptagTdfNew will be used as initial values.
|
|
***************************************************************************/
|
|
PESLT ESLT::PesltNew(PRCA prca, PMVIE pmvie, PACTR pactr, PSTN pstnNew,
|
|
long tdtsNew, PTAG ptagTdfNew)
|
|
{
|
|
AssertPo(prca, 0);
|
|
AssertPo(pmvie, 0);
|
|
AssertNilOrPo(pactr, 0);
|
|
AssertNilOrPo(pstnNew, 0);
|
|
if (tdtsNew != tdtsNil)
|
|
AssertIn(tdtsNew, 0, tdtsLim);
|
|
AssertNilOrVarMem(ptagTdfNew);
|
|
|
|
PESLT peslt;
|
|
GCB gcb;
|
|
|
|
if (!FBuildGcb(&gcb, kidBackground, kidSpltGlass))
|
|
return pvNil;
|
|
|
|
peslt = NewObj ESLT(&gcb);
|
|
if (pvNil == peslt)
|
|
return pvNil;
|
|
if (!peslt->_FInit(prca, kidSpltGlass, pmvie, pactr, pstnNew,
|
|
tdtsNew, ptagTdfNew))
|
|
{
|
|
ReleasePpo(&peslt);
|
|
return pvNil;
|
|
}
|
|
AssertPo(peslt, 0);
|
|
vpcex->EnqueueCid(cidEaselVisible);
|
|
|
|
return peslt;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Set up this easel
|
|
***************************************************************************/
|
|
bool ESLT::_FInit(PRCA prca, long kidEasel, PMVIE pmvie, PACTR pactr,
|
|
PSTN pstnNew, long tdtsNew, PTAG ptagTdfNew)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertPo(prca, 0);
|
|
AssertPo(pmvie, 0);
|
|
AssertNilOrPo(pactr, 0);
|
|
Assert(pvNil == pactr || pactr->Ptmpl()->FIsTdt(),
|
|
"only use ESLT for TDTs");
|
|
AssertNilOrPo(pstnNew, 0);
|
|
if (tdtsNew != tdtsNil)
|
|
AssertIn(tdtsNew, 0, tdtsLim);
|
|
AssertNilOrVarMem(ptagTdfNew);
|
|
|
|
GCB gcb;
|
|
COST cost;
|
|
STN stn;
|
|
bool fNewTdt = (pactr == pvNil);
|
|
PTDT ptdt;
|
|
|
|
_prca = prca;
|
|
_pactr = pactr;
|
|
_pmvie = pmvie;
|
|
|
|
if (!ESLT_PAR::_FInit(prca, kidEasel))
|
|
return fFalse;
|
|
if (!FBuildGcb(&gcb, kidSpltPreviewFrame, CMH::HidUnique()))
|
|
return fFalse;
|
|
|
|
_psflTdts = NewObj SFL;
|
|
if (pvNil == _psflTdts)
|
|
return fFalse;
|
|
|
|
_psflTdf = NewObj SFL;
|
|
if (pvNil == _psflTdf)
|
|
return fFalse;
|
|
|
|
_psflMtrl = NewObj SFL;
|
|
if (pvNil == _psflMtrl)
|
|
return fFalse;
|
|
|
|
if (fNewTdt)
|
|
{
|
|
AssertPo(pstnNew, 0);
|
|
AssertIn(tdtsNew, 0, tdtsLim);
|
|
AssertVarMem(ptagTdfNew);
|
|
|
|
ptdt = TDT::PtdtNew(pstnNew, tdtsNew, ptagTdfNew);
|
|
if (pvNil == ptdt)
|
|
return fFalse;
|
|
_pape = APE::PapeNew(&gcb, ptdt, pvNil, 0, fFalse, _prca);
|
|
ReleasePpo(&ptdt);
|
|
if (pvNil == _pape)
|
|
return fFalse;
|
|
stn = *pstnNew;
|
|
}
|
|
else
|
|
{
|
|
// We have to make a duplicate TDT rather than use the existing one
|
|
// because the user may experimentally change the TDT, then hit Cancel.
|
|
if (!cost.FGet(pactr->Pbody()))
|
|
return fFalse;
|
|
ptdt = ((PTDT)pactr->Ptmpl())->PtdtDup();
|
|
if (pvNil == ptdt)
|
|
return fFalse;
|
|
_pape = APE::PapeNew(&gcb, ptdt, &cost, 0, fFalse, _prca);
|
|
ReleasePpo(&ptdt);
|
|
if (pvNil == _pape)
|
|
return fFalse;
|
|
pactr->Ptmpl()->GetName(&stn);
|
|
}
|
|
|
|
// Set up the edit box
|
|
if (!FBuildGcb(&gcb, kidSpltEditBox, CMH::HidUnique()))
|
|
return fFalse;
|
|
EDPAR edpar(gcb._hid, gcb._pgob, gcb._grfgob, gcb._gin, &gcb._rcAbs,
|
|
&gcb._rcRel, vpappb->OnnDefVariable(), 0, vpappb->DypTextDef(),
|
|
tahLeft, tavCenter);
|
|
_psne = SNE::PsneNew(&edpar, this, &stn);
|
|
if (pvNil == _psne)
|
|
return fFalse;
|
|
_psne->Activate(fTrue);
|
|
_psne->SetSel(0, _psne->IchMac(), fFalse); // select all of the text
|
|
_psne->SetCursCno(_prca, kcrsIBeam);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Clean up and delete this easel. Note that I don't need to delete
|
|
_psne or _pape because they're GOBs and are automatically destroyed
|
|
with the gob tree.
|
|
***************************************************************************/
|
|
ESLT::~ESLT(void)
|
|
{
|
|
AssertBaseThis(0);
|
|
ReleasePpo(&_psflTdts);
|
|
ReleasePpo(&_psflTdf);
|
|
ReleasePpo(&_psflMtrl);
|
|
ReleasePpo(&_pbclTdf);
|
|
ReleasePpo(&_pbclMtrl);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Handle a rotate command
|
|
***************************************************************************/
|
|
bool ESLT::FCmdRotate(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
_pape->ChangeView();
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Handle a transmogrify command (pick a random shape, font, and material)
|
|
***************************************************************************/
|
|
bool ESLT::FCmdTransmogrify(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
long tdts;
|
|
CKI cki;
|
|
long ithd;
|
|
THD thd;
|
|
TAG tagTdf;
|
|
TAG tagMtrl;
|
|
|
|
vpappb->BeginLongOp();
|
|
|
|
// Pick a random shape
|
|
tdts = _psflTdts->LwNext(tdtsLim);
|
|
|
|
// Pick a random font
|
|
if (pvNil == _pbclTdf)
|
|
{
|
|
cki.ctg = kctgTfth;
|
|
cki.cno = cnoNil;
|
|
_pbclTdf = BCL::PbclNew(pvNil, &cki, ctgNil, pvNil, fTrue);
|
|
}
|
|
if (_pbclTdf != pvNil && _pbclTdf->IthdMac() != 0)
|
|
{
|
|
ithd = _psflTdf->LwNext(_pbclTdf->IthdMac());
|
|
_pbclTdf->GetThd(ithd, &thd);
|
|
tagTdf = thd.tag;
|
|
if (vptagm->FCacheTagToHD(&tagTdf))
|
|
{
|
|
// Failure here is harmless
|
|
_pape->FChangeTdt(pvNil, tdts, &tagTdf);
|
|
}
|
|
}
|
|
|
|
// Pick a random material
|
|
if (pvNil == _pbclMtrl)
|
|
{
|
|
cki.ctg = kctgMtth;
|
|
cki.cno = cnoNil;
|
|
_pbclMtrl = BCL::PbclNew(pvNil, &cki, ctgNil, pvNil, fTrue);
|
|
}
|
|
if (_pbclMtrl != pvNil && _pbclMtrl->IthdMac() != 0)
|
|
{
|
|
ithd = _psflMtrl->LwNext(_pbclMtrl->IthdMac());
|
|
_pbclMtrl->GetThd(ithd, &thd);
|
|
tagMtrl = thd.tag;
|
|
if (vptagm->FCacheTagToHD(&tagMtrl))
|
|
{
|
|
// Failure here is harmless
|
|
_pape->FSetTdtMtrl(&tagMtrl);
|
|
}
|
|
}
|
|
|
|
vpappb->EndLongOp();
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Start a popup
|
|
***************************************************************************/
|
|
bool ESLT::FCmdStartPopup(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
CKI ckiGPar;
|
|
long kid;
|
|
long ithumSelect = ivNil;
|
|
long sidSelect = vpapp->SidProduct();
|
|
long cidSelect;
|
|
TAG tagTdf;
|
|
long tdts;
|
|
CNO cnoSelect;
|
|
|
|
ckiGPar.cno = cnoNil;
|
|
|
|
switch (pcmd->cid)
|
|
{
|
|
case cidEaselFont:
|
|
ckiGPar.ctg = kctgTfth;
|
|
kid = kidSpltsFont;
|
|
_pape->GetTdtInfo(pvNil, pvNil, &tagTdf);
|
|
ithumSelect = tagTdf.cno;
|
|
sidSelect = tagTdf.sid;
|
|
cidSelect = cidEaselSetFont;
|
|
break;
|
|
|
|
case cidEaselShape:
|
|
ckiGPar.ctg = kctgTsth;
|
|
kid = kidSpltsShape;
|
|
_pape->GetTdtInfo(pvNil, &tdts, pvNil);
|
|
ithumSelect = tdts;
|
|
cidSelect = cidEaselSetShape;
|
|
break;
|
|
|
|
case cidEaselTexture:
|
|
ckiGPar.ctg = kctgMtth;
|
|
if (_pape->FGetTdtMtrlCno(&cnoSelect))
|
|
ithumSelect = cnoSelect;
|
|
else
|
|
ithumSelect = ivNil;
|
|
kid = kidSpltsColor;
|
|
cidSelect = cidEaselSetColor;
|
|
break;
|
|
|
|
default:
|
|
Bug("Invalid cid for ESLT::FCmdStartPopup");
|
|
break;
|
|
}
|
|
|
|
MP::PmpNew(kidSpltBackground, kid, _prca, pcmd, kbwsCnoRoot, ithumSelect,
|
|
sidSelect, ckiGPar, ctgNil, this, cidSelect, fTrue);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Handle a command to change the font
|
|
***************************************************************************/
|
|
bool ESLT::FCmdSetFont(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
TAG tagTdfOld;
|
|
TAG tagTdfNew;
|
|
|
|
tagTdfNew.sid = pcmd->rglw[1];
|
|
tagTdfNew.pcrf = pvNil;
|
|
tagTdfNew.ctg = kctgTdf;
|
|
tagTdfNew.cno = pcmd->rglw[0];
|
|
|
|
_pape->GetTdtInfo(pvNil, pvNil, &tagTdfOld);
|
|
if (fcmpEq == vptagm->FcmpCompareTags(&tagTdfOld, &tagTdfNew))
|
|
return fTrue; // nothing to do
|
|
|
|
// If FChangeTdt fails, someone will report the error
|
|
if (vptagm->FCacheTagToHD(&tagTdfNew))
|
|
_pape->FChangeTdt(pvNil, tdtsNil, &tagTdfNew);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Handle a command to change the shape
|
|
***************************************************************************/
|
|
bool ESLT::FCmdSetShape(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
long tdtsOld;
|
|
long tdtsNew = pcmd->rglw[0];
|
|
|
|
_pape->GetTdtInfo(pvNil, &tdtsOld, pvNil);
|
|
// If FChangeTdt fails, someone will report the error
|
|
if (tdtsOld != tdtsNew)
|
|
_pape->FChangeTdt(pvNil, tdtsNew, pvNil);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Handle a command to change the color
|
|
***************************************************************************/
|
|
bool ESLT::FCmdSetColor(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
TAG tagTdfNew;
|
|
|
|
tagTdfNew.sid = pcmd->rglw[1];
|
|
tagTdfNew.pcrf = pvNil;
|
|
tagTdfNew.ctg = kctgMtrl;
|
|
tagTdfNew.cno = pcmd->rglw[0];
|
|
|
|
// If FSetTdtMtrl fails, someone will report the error
|
|
if (vptagm->FCacheTagToHD(&tagTdfNew))
|
|
_pape->FSetTdtMtrl(&tagTdfNew);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Update the APE when the text of the SNE changed
|
|
***************************************************************************/
|
|
bool ESLT::FTextChanged(PSTN pstnNew)
|
|
{
|
|
AssertBaseThis(0); // we may still be setting up the ESLT
|
|
AssertPo(pstnNew, 0);
|
|
|
|
return _pape->FChangeTdt(pstnNew, tdtsNil, pvNil);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Make the changes to pactr
|
|
***************************************************************************/
|
|
bool ESLT::_FAcceptChanges(bool *pfDismissEasel)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pfDismissEasel);
|
|
|
|
long ich;
|
|
bool fNonSpaceFound = fFalse;
|
|
PACTR pactrDup = pvNil;
|
|
bool fChangesMade = fFalse;
|
|
PTDT ptdtOld;
|
|
STN stnOld;
|
|
long tdtsOld;
|
|
TAG tagTdfOld;
|
|
STN stnNew;
|
|
long tdtsNew;
|
|
TAG tagTdfNew;
|
|
long cbset;
|
|
long ibset;
|
|
bool fMtrl;
|
|
long cmid;
|
|
TAG tagMtrl;
|
|
|
|
if (pvNil == _pactr) // new TDT
|
|
{
|
|
_pape->GetTdtInfo(&stnNew, &tdtsNew, &tagTdfNew);
|
|
for (ich = 0; ich < stnNew.Cch(); ich++)
|
|
{
|
|
if (stnNew.Psz()[ich] != ChLit(' '))
|
|
{
|
|
fNonSpaceFound = fTrue;
|
|
break;
|
|
}
|
|
}
|
|
if (!fNonSpaceFound)
|
|
{
|
|
// user deleted all text, so treat like a cancel
|
|
vpcex->EnqueueCid(cidEaselClosing, pvNil, pvNil, fFalse);
|
|
return fTrue;
|
|
}
|
|
if (!_pmvie->FInsTdt(&stnNew, tdtsNew, &tagTdfNew))
|
|
goto LFail;
|
|
_pactr = _pmvie->Pscen()->PactrSelected();
|
|
|
|
cbset = _pape->Cbset();
|
|
// Now apply costume changes
|
|
for (ibset = 0; ibset < cbset; ibset++)
|
|
{
|
|
if (_pape->FGetMaterial(ibset, &fMtrl, &cmid, &tagMtrl))
|
|
{
|
|
if (!_pactr->FSetCostumeCore(ibset, &tagMtrl, cmid, !fMtrl))
|
|
goto LFail;
|
|
fChangesMade = fTrue;
|
|
}
|
|
}
|
|
_pmvie->PmvuCur()->StartPlaceActor();
|
|
}
|
|
else
|
|
{
|
|
ptdtOld = (PTDT)_pactr->Ptmpl();
|
|
|
|
if (!_pactr->FDup(&pactrDup))
|
|
goto LFail;
|
|
|
|
// first apply TDT changes
|
|
ptdtOld->GetInfo(&stnOld, &tdtsOld, &tagTdfOld);
|
|
_pape->GetTdtInfo(&stnNew, &tdtsNew, &tagTdfNew);
|
|
if (!stnOld.FEqual(&stnNew) || tdtsOld != tdtsNew ||
|
|
fcmpEq != TAGM::FcmpCompareTags(&tagTdfOld, &tagTdfNew))
|
|
{
|
|
if (!_pmvie->FChangeActrTdt(_pactr, &stnNew, tdtsNew, &tagTdfNew))
|
|
goto LFail;
|
|
fChangesMade = fTrue;
|
|
}
|
|
|
|
// Now apply costume changes
|
|
cbset = _pape->Cbset();
|
|
for (ibset = 0; ibset < cbset; ibset++)
|
|
{
|
|
if (_pape->FGetMaterial(ibset, &fMtrl, &cmid, &tagMtrl))
|
|
{
|
|
if (!_pactr->FSetCostumeCore(ibset, &tagMtrl, cmid, !fMtrl))
|
|
goto LFail;
|
|
fChangesMade = fTrue;
|
|
}
|
|
}
|
|
|
|
if (fChangesMade)
|
|
{
|
|
if (!_pactr->FCreateUndo(pactrDup))
|
|
goto LFail;
|
|
}
|
|
ReleasePpo(&pactrDup);
|
|
}
|
|
vpcex->EnqueueCid(cidEaselClosing, pvNil, pvNil, fTrue);
|
|
_pmvie->Pscen()->SelectActr(_pactr);
|
|
return fTrue;
|
|
LFail:
|
|
if (_pactr != pvNil)
|
|
{
|
|
if (pvNil != pactrDup)
|
|
{
|
|
_pactr->Restore(pactrDup);
|
|
ReleasePpo(&pactrDup);
|
|
}
|
|
PushErc(ercSoc3DWordChange);
|
|
}
|
|
else
|
|
PushErc(ercSoc3DWordCreate);
|
|
return fFalse;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the ESLT.
|
|
***************************************************************************/
|
|
void ESLT::AssertValid(ulong grf)
|
|
{
|
|
ESLT_PAR::AssertValid(fobjAllocated);
|
|
AssertPo(_pmvie, 0);
|
|
AssertNilOrPo(_pactr, 0);
|
|
AssertPo(_pape, 0);
|
|
AssertPo(_psne, 0);
|
|
AssertPo(_prca, 0);
|
|
AssertPo(_psflTdts, 0);
|
|
AssertPo(_psflTdf, 0);
|
|
AssertPo(_psflMtrl, 0);
|
|
AssertNilOrPo(_pbclTdf, 0);
|
|
AssertNilOrPo(_pbclMtrl, 0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the ESLT. The _pape and _psne are marked
|
|
automatically with the GOB tree.
|
|
***************************************************************************/
|
|
void ESLT::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
ESLT_PAR::MarkMem();
|
|
MarkMemObj(_psflTdts);
|
|
MarkMemObj(_psflTdf);
|
|
MarkMemObj(_psflMtrl);
|
|
MarkMemObj(_pbclTdf);
|
|
MarkMemObj(_pbclMtrl);
|
|
}
|
|
#endif //DEBUG
|
|
|
|
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
// SNE (spletter name editor) stuff begins here
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
/***************************************************************************
|
|
Create a new spletter name editor with initial string pstnInit. Text
|
|
change notifications will be sent to peslt.
|
|
***************************************************************************/
|
|
PSNE SNE::PsneNew(PEDPAR pedpar, PESLT peslt, PSTN pstnInit)
|
|
{
|
|
AssertVarMem(pedpar);
|
|
AssertBasePo(peslt, 0);
|
|
AssertPo(pstnInit, 0);
|
|
|
|
PSNE psne;
|
|
|
|
psne = NewObj SNE(pedpar);
|
|
if (pvNil == psne)
|
|
return pvNil;
|
|
|
|
if (!psne->_FInit())
|
|
{
|
|
ReleasePpo(&psne);
|
|
return pvNil;
|
|
}
|
|
|
|
psne->_peslt = peslt;
|
|
psne->SetStn(pstnInit, fFalse);
|
|
return psne;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Trap the default FReplace to prevent illegal strings and to notify the
|
|
ESLT that the text has changed.
|
|
***************************************************************************/
|
|
bool SNE::FReplace(achar *prgch, long cchIns, long ich1, long ich2,
|
|
long gin)
|
|
{
|
|
AssertThis(0);
|
|
|
|
STN stnOld;
|
|
STN stnNew;
|
|
|
|
GetStn(&stnOld);
|
|
|
|
// Note that gin is forced to ginNil here so there's no flicker if
|
|
// the resulting text is illegal
|
|
if (!SNE_PAR::FReplace(prgch, cchIns, ich1, ich2, ginNil))
|
|
return fFalse;
|
|
|
|
// Look for illegal strings:
|
|
GetStn(&stnNew);
|
|
if (stnNew.Cch() > kcchMaxTdt)
|
|
{
|
|
SetStn(&stnOld, fFalse);
|
|
GetStn(&stnNew);
|
|
}
|
|
#ifdef DEBUG
|
|
else if (stnNew.Cch() == 5 && stnNew.Psz()[0] == ChLit(')') &&
|
|
stnNew.Psz()[4] == ChLit('('))
|
|
{
|
|
// Hack for testing: ")xxx(" changes the TDT to
|
|
// all ASCII values from xxx to xxx + kcchMaxTdt (or up to chNil).
|
|
STN stnT;
|
|
achar rgch[kcchMaxTdt];
|
|
long ichStart;
|
|
long ich;
|
|
long cch = 0;
|
|
|
|
stnT.SetRgch(&stnNew.Psz()[1], 3);
|
|
if (stnT.FGetLw(&ichStart, 10))
|
|
{
|
|
for (ich = 0; ich < kcchMaxTdt; ich++)
|
|
{
|
|
rgch[ich] = (achar)ichStart + (achar)ich;
|
|
if (rgch[ich] == chNil)
|
|
break;
|
|
cch++;
|
|
}
|
|
SNE_PAR::FReplace(rgch, cch, 0, IchMac(), fFalse);
|
|
GetStn(&stnNew);
|
|
}
|
|
}
|
|
#endif //DEBUG
|
|
|
|
// Notify the easel so the TDT can be updated
|
|
if (!_peslt->FTextChanged(&stnNew))
|
|
SetStn(&stnOld, fFalse);
|
|
|
|
// Now do the actual update
|
|
_UpdateLn(0, 1, 1, _dypLine, gin);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the SNE.
|
|
***************************************************************************/
|
|
void SNE::AssertValid(ulong grf)
|
|
{
|
|
SNE_PAR::AssertValid(fobjAllocated);
|
|
AssertBasePo(_peslt, 0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the SNE
|
|
***************************************************************************/
|
|
void SNE::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
SNE_PAR::MarkMem();
|
|
}
|
|
#endif //DEBUG
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
// ESLA (actor easel) stuff begins here
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
BEGIN_CMD_MAP(ESLA, ESL)
|
|
ON_CID_GEN(cidEaselRotate, FCmdRotate, pvNil)
|
|
ON_CID_GEN(cidEaselCostumes, FCmdTool, pvNil)
|
|
ON_CID_GEN(cidEaselAccessories, FCmdTool, pvNil)
|
|
END_CMD_MAP_NIL()
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
Create a new actor easel
|
|
***************************************************************************/
|
|
PESLA ESLA::PeslaNew(PRCA prca, PMVIE pmvie, PACTR pactr)
|
|
{
|
|
AssertPo(prca, 0);
|
|
AssertPo(pmvie, 0);
|
|
AssertPo(pactr, 0);
|
|
|
|
PESLA pesla;
|
|
GCB gcb;
|
|
|
|
if (!FBuildGcb(&gcb, kidBackground, kidCostGlass))
|
|
return pvNil;
|
|
|
|
pesla = NewObj ESLA(&gcb);
|
|
if (pvNil == pesla)
|
|
return pvNil;
|
|
if (!pesla->_FInit(prca, kidCostGlass, pmvie, pactr))
|
|
{
|
|
ReleasePpo(&pesla);
|
|
return pvNil;
|
|
}
|
|
AssertPo(pesla, 0);
|
|
vpcex->EnqueueCid(cidEaselVisible);
|
|
|
|
return pesla;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Set up this easel
|
|
***************************************************************************/
|
|
bool ESLA::_FInit(PRCA prca, long kidEasel, PMVIE pmvie, PACTR pactr)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertPo(prca, 0);
|
|
AssertPo(pmvie, 0);
|
|
AssertPo(pactr, 0);
|
|
|
|
GCB gcb;
|
|
COST cost;
|
|
STN stn;
|
|
EDPAR edpar;
|
|
|
|
if (!ESLA_PAR::_FInit(prca, kidEasel))
|
|
return fFalse;
|
|
if (!cost.FGet(pactr->Pbody()))
|
|
return fFalse;
|
|
if (!FBuildGcb(&gcb, kidCostPreviewFrame, CMH::HidUnique()))
|
|
return fFalse;
|
|
_pape = APE::PapeNew(&gcb, pactr->Ptmpl(), &cost, pactr->AnidCur(),
|
|
fFalse, prca);
|
|
if (pvNil == _pape)
|
|
return fFalse;
|
|
_pape->SetToolIncCmtl();
|
|
|
|
if (!FBuildGcb(&gcb, kidCostEditBox, CMH::HidUnique()))
|
|
return fFalse;
|
|
edpar.Set(gcb._hid, gcb._pgob, gcb._grfgob, gcb._gin, &gcb._rcAbs,
|
|
&gcb._rcRel, vpappb->OnnDefVariable(), 0, vpappb->DypTextDef(),
|
|
tahLeft, tavCenter);
|
|
_pmvie = pmvie;
|
|
_pactr = pactr;
|
|
_pactr->GetName(&stn);
|
|
_pedsl = EDSL::PedslNew(&edpar);
|
|
if (pvNil == _pedsl)
|
|
return fFalse;
|
|
_pedsl->SetStn(&stn);
|
|
_pedsl->SetSel(0, _pedsl->IchMac()); // select all of the text
|
|
_pedsl->Activate(fTrue);
|
|
_pedsl->SetCursCno(prca, kcrsIBeam);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Clean up and delete this easel. Note that I don't need to delete
|
|
_pedsl or _pape because they're GOBs and are automatically destroyed
|
|
with the gob tree.
|
|
***************************************************************************/
|
|
ESLA::~ESLA(void)
|
|
{
|
|
AssertBaseThis(0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Handle a rotate command
|
|
***************************************************************************/
|
|
bool ESLA::FCmdRotate(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
_pape->ChangeView();
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Handle a tool change command
|
|
***************************************************************************/
|
|
bool ESLA::FCmdTool(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
switch(pcmd->cid)
|
|
{
|
|
case cidEaselAccessories:
|
|
_pape->SetToolIncAccessory();
|
|
break;
|
|
|
|
case cidEaselCostumes:
|
|
_pape->SetToolIncCmtl();
|
|
break;
|
|
|
|
default:
|
|
Bug("unexpected cid");
|
|
break;
|
|
}
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Make the changes to _pactr
|
|
***************************************************************************/
|
|
bool ESLA::_FAcceptChanges(bool *pfDismissEasel)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pfDismissEasel);
|
|
|
|
PACTR pactrDup;
|
|
bool fNonSpaceFound;
|
|
long ich;
|
|
bool fChangesMade = fFalse;
|
|
STN stnOld;
|
|
STN stnNew;
|
|
long cbset;
|
|
long ibset;
|
|
bool fMtrl;
|
|
long cmid;
|
|
TAG tagMtrl;
|
|
|
|
if (!_pactr->FDup(&pactrDup))
|
|
return fFalse;
|
|
|
|
_pactr->GetName(&stnOld);
|
|
_pedsl->GetStn(&stnNew);
|
|
if (!stnOld.FEqual(&stnNew))
|
|
{
|
|
// Check for empty or "spaces only" string
|
|
fNonSpaceFound = fFalse;
|
|
for (ich = 0; ich < stnNew.Cch(); ich++)
|
|
{
|
|
if (stnNew.Psz()[ich] != ChLit(' '))
|
|
{
|
|
fNonSpaceFound = fTrue;
|
|
break;
|
|
}
|
|
}
|
|
if (fNonSpaceFound)
|
|
{
|
|
if (!_pmvie->FNameActr(_pactr->Arid(), &stnNew))
|
|
goto LFail;
|
|
fChangesMade = fTrue;
|
|
}
|
|
}
|
|
|
|
// Now apply costume changes
|
|
cbset = _pape->Cbset();
|
|
for (ibset = 0; ibset < cbset; ibset++)
|
|
{
|
|
if (_pape->FGetMaterial(ibset, &fMtrl, &cmid, &tagMtrl))
|
|
{
|
|
if (!_pactr->FSetCostumeCore(ibset, &tagMtrl, cmid, !fMtrl))
|
|
goto LFail;
|
|
fChangesMade = fTrue;
|
|
}
|
|
}
|
|
|
|
if (fChangesMade)
|
|
{
|
|
if (!_pactr->FCreateUndo(pactrDup, fFalse, &stnOld))
|
|
goto LFail;
|
|
}
|
|
ReleasePpo(&pactrDup);
|
|
return fTrue;
|
|
LFail:
|
|
_pactr->Restore(pactrDup);
|
|
ReleasePpo(&pactrDup);
|
|
return fFalse;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the ESLA.
|
|
***************************************************************************/
|
|
void ESLA::AssertValid(ulong grf)
|
|
{
|
|
ESLA_PAR::AssertValid(fobjAllocated);
|
|
AssertPo(_pmvie, 0);
|
|
AssertPo(_pactr, 0);
|
|
AssertPo(_pape, 0);
|
|
AssertPo(_pedsl, 0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the ESLA. The _pape and _pedsl are marked
|
|
automatically with the GOB tree.
|
|
***************************************************************************/
|
|
void ESLA::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
ESLA_PAR::MarkMem();
|
|
}
|
|
#endif //DEBUG
|
|
|
|
|
|
//
|
|
//
|
|
// ESLL (EaSeL Listener)
|
|
// The Listener displays either all background sounds or the
|
|
// actor Sound Effects and the actor Speech sounds of highest precedence.
|
|
// Note: A sounder speech sound takes precedence over a motion match
|
|
// speech sound
|
|
//
|
|
|
|
BEGIN_CMD_MAP(ESLL, ESL)
|
|
ON_CID_GEN(cidEaselVol, FCmdVlm, pvNil)
|
|
ON_CID_GEN(cidEaselPlay, FCmdPlay, pvNil)
|
|
END_CMD_MAP_NIL()
|
|
|
|
|
|
/***************************************************************************
|
|
Create a new listener easel
|
|
***************************************************************************/
|
|
PESLL ESLL::PesllNew(PRCA prca, PMVIE pmvie, PACTR pactr)
|
|
{
|
|
AssertPo(prca, 0);
|
|
AssertPo(pmvie, 0);
|
|
AssertNilOrPo(pactr, 0);
|
|
|
|
PESLL pesll;
|
|
GCB gcb;
|
|
long kidGlass;
|
|
|
|
if (pvNil == pactr)
|
|
kidGlass = kidListenGlassBkgd;
|
|
else
|
|
kidGlass = kidListenGlassActor;
|
|
|
|
if (!FBuildGcb(&gcb, kidBackground, kidGlass))
|
|
return pvNil;
|
|
|
|
pesll = NewObj ESLL(&gcb);
|
|
if (pvNil == pesll)
|
|
return pvNil;
|
|
if (!pesll->_FInit(prca, kidGlass, pmvie, pactr))
|
|
{
|
|
ReleasePpo(&pesll);
|
|
return pvNil;
|
|
}
|
|
AssertPo(pesll, 0);
|
|
vpcex->EnqueueCid(cidEaselVisible);
|
|
|
|
return pesll;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Set up this easel
|
|
***************************************************************************/
|
|
bool ESLL::_FInit(PRCA prca, long kidEasel, PMVIE pmvie, PACTR pactr)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertPo(prca, 0);
|
|
AssertPo(pmvie, 0);
|
|
AssertNilOrPo(pactr, 0);
|
|
|
|
PGL pgltag;
|
|
long vlm;
|
|
bool fLoop;
|
|
|
|
if (!ESLL_PAR::_FInit(prca, kidEasel))
|
|
return fFalse;
|
|
_pmvie = pmvie;
|
|
_pscen = pmvie->Pscen();
|
|
_pactr = pactr;
|
|
|
|
if (pvNil == pactr)
|
|
{
|
|
// Scene sounds
|
|
|
|
// Speech
|
|
if (!_pscen->FQuerySnd(stySpeech, &pgltag, &vlm, &fLoop))
|
|
return fFalse;
|
|
if (!_lsndSpeech.FInit(stySpeech, kidListenVolSpeech,
|
|
kidListenSpeechIcon, kidListenEditBoxSpeech, &pgltag,
|
|
vlm, fLoop, 0, fFalse))
|
|
{
|
|
return fFalse;
|
|
}
|
|
|
|
// SFX
|
|
if (!_pscen->FQuerySnd(stySfx, &pgltag, &vlm, &fLoop))
|
|
return fFalse;
|
|
if (!_lsndSfx.FInit(stySfx, kidListenVolFX, kidListenFXIcon,
|
|
kidListenEditBoxFX, &pgltag, vlm, fLoop, 0, fFalse))
|
|
{
|
|
return fFalse;
|
|
}
|
|
|
|
// Midi
|
|
if (!_pscen->FQuerySnd(styMidi, &pgltag, &vlm, &fLoop))
|
|
return fFalse;
|
|
if (!_lsndMidi.FInit(styMidi, kidListenVolMidi, kidListenMidiIcon,
|
|
kidListenEditBoxMidi, &pgltag, vlm, fLoop, 0, fFalse))
|
|
{
|
|
return fFalse;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Actor sounds
|
|
|
|
// Speech
|
|
if (!_pactr->FQuerySnd(stySpeech, fFalse, &pgltag, &vlm, &fLoop))
|
|
return fFalse;
|
|
if (!_lsndSpeech.FInit(stySpeech, kidListenVolSpeech,
|
|
kidListenSpeechIcon, kidListenEditBoxSpeech, &pgltag,
|
|
vlm, fLoop, _pactr->Arid(), fFalse))
|
|
{
|
|
return fFalse;
|
|
}
|
|
|
|
// SFX
|
|
if (!_pactr->FQuerySnd(stySfx, fFalse, &pgltag, &vlm, &fLoop))
|
|
return fFalse;
|
|
if (!_lsndSfx.FInit(stySfx, kidListenVolFX, kidListenFXIcon,
|
|
kidListenEditBoxFX, &pgltag, vlm, fLoop, _pactr->Arid(), fFalse))
|
|
{
|
|
return fFalse;
|
|
}
|
|
|
|
// Motion-match speech
|
|
// If no non-motion match speech sounds take precedence, display
|
|
// motion match speech sounds
|
|
if (!_lsndSpeech.FValidSnd())
|
|
{
|
|
if (!_pactr->FQuerySnd(stySpeech, fTrue, &pgltag, &vlm, &fLoop))
|
|
return fFalse;
|
|
if (!_lsndSpeechMM.FInit(stySpeech, kidListenVolSpeechMM,
|
|
kidListenSpeechMMIcon, kidListenEditBoxSpeechMM, &pgltag, vlm,
|
|
fLoop, _pactr->Arid(), fTrue))
|
|
{
|
|
return fFalse;
|
|
}
|
|
}
|
|
|
|
// Motion-match SFX
|
|
// If no non-motion match sound effects sounds take precedence, display
|
|
// motion match sound effects sounds
|
|
if (!_lsndSfx.FValidSnd())
|
|
{
|
|
if (!_pactr->FQuerySnd(stySfx, fTrue, &pgltag, &vlm, &fLoop))
|
|
return fFalse;
|
|
if (!_lsndSfxMM.FInit(stySfx, kidListenVolFXMM, kidListenFXMMIcon,
|
|
kidListenEditBoxFXMM, &pgltag, vlm, fLoop, _pactr->Arid(), fTrue))
|
|
{
|
|
return fFalse;
|
|
}
|
|
}
|
|
|
|
}
|
|
return fTrue;
|
|
}
|
|
|
|
/***************************************************************************
|
|
Are there valid sounds in this Lsnd?
|
|
***************************************************************************/
|
|
bool LSND::FValidSnd(void)
|
|
{
|
|
AssertThis(0);
|
|
PMSND pmsnd;
|
|
long itag;
|
|
TAG tag;
|
|
|
|
if (pvNil == _pgltag)
|
|
return fFalse;
|
|
|
|
for(itag = 0; itag < _pgltag->IvMac(); itag++)
|
|
{
|
|
_pgltag->Get(itag, &tag);
|
|
pmsnd = (PMSND)vptagm->PbacoFetch(&tag, MSND::FReadMsnd);
|
|
if (pvNil == pmsnd)
|
|
continue;
|
|
if (!pmsnd->FValid())
|
|
{
|
|
ReleasePpo(&pmsnd);
|
|
continue;
|
|
}
|
|
ReleasePpo(&pmsnd);
|
|
return fTrue;
|
|
}
|
|
return fFalse;
|
|
}
|
|
|
|
/***************************************************************************
|
|
Clean up and delete this easel
|
|
***************************************************************************/
|
|
ESLL::~ESLL(void)
|
|
{
|
|
AssertBaseThis(0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Handle a Listener volume change command
|
|
***************************************************************************/
|
|
bool ESLL::FCmdVlm(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
long kid = pcmd->rglw[0];
|
|
long vlm = pcmd->rglw[1];
|
|
|
|
switch (kid)
|
|
{
|
|
case kidListenVolSpeech:
|
|
_lsndSpeech.SetVlmNew(vlm);
|
|
break;
|
|
case kidListenVolFX:
|
|
_lsndSfx.SetVlmNew(vlm);
|
|
break;
|
|
case kidListenVolSpeechMM:
|
|
_lsndSpeechMM.SetVlmNew(vlm);
|
|
break;
|
|
case kidListenVolFXMM:
|
|
_lsndSfxMM.SetVlmNew(vlm);
|
|
break;
|
|
case kidListenVolMidi:
|
|
_lsndMidi.SetVlmNew(vlm);
|
|
break;
|
|
default:
|
|
Bug("Invalid kid");
|
|
break;
|
|
}
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
/***************************************************************************
|
|
Handle a Listener play command
|
|
***************************************************************************/
|
|
bool ESLL::FCmdPlay(PCMD pcmd)
|
|
{
|
|
AssertVarMem(pcmd);
|
|
AssertNilOrPo(_pactr, 0);
|
|
|
|
long kid = pcmd->rglw[0];
|
|
bool fPlay = FPure(pcmd->rglw[1]);
|
|
|
|
if (!fPlay)
|
|
{
|
|
StopAllMovieSounds();
|
|
return fTrue;
|
|
}
|
|
|
|
// Actor Sounds
|
|
switch (kid)
|
|
{
|
|
case kidListenEditBoxSpeech:
|
|
_lsndSpeech.Play();
|
|
break;
|
|
case kidListenEditBoxFX:
|
|
_lsndSfx.Play();
|
|
break;
|
|
case kidListenEditBoxSpeechMM:
|
|
_lsndSpeechMM.Play();
|
|
break;
|
|
case kidListenEditBoxFXMM:
|
|
_lsndSfxMM.Play();
|
|
break;
|
|
case kidListenEditBoxMidi:
|
|
_lsndMidi.Play();
|
|
break;
|
|
default:
|
|
Bug("Invalid Vlm type");
|
|
break;
|
|
}
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Make the changes to _pscen or _pactr. For actor sounds, we could
|
|
create an undo object here, but we currently don't. Scene sounds would
|
|
require a new type of undo object so that's definitely not supported.
|
|
***************************************************************************/
|
|
bool ESLL::_FAcceptChanges(bool *pfDismissEasel)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pfDismissEasel);
|
|
|
|
long vlmNew;
|
|
bool fNuked;
|
|
|
|
if (pvNil == _pactr)
|
|
{
|
|
// Scene sounds
|
|
if (_lsndSpeech.FChanged(&vlmNew, &fNuked))
|
|
{
|
|
if (fNuked)
|
|
_pscen->RemSndCore(stySpeech);
|
|
else
|
|
_pscen->SetSndVlmCore(stySpeech, vlmNew);
|
|
}
|
|
|
|
if (_lsndSfx.FChanged(&vlmNew, &fNuked))
|
|
{
|
|
if (fNuked)
|
|
_pscen->RemSndCore(stySfx);
|
|
else
|
|
_pscen->SetSndVlmCore(stySfx, vlmNew);
|
|
}
|
|
|
|
if (_lsndMidi.FChanged(&vlmNew, &fNuked))
|
|
{
|
|
if (fNuked)
|
|
_pscen->RemSndCore(styMidi);
|
|
else
|
|
_pscen->SetSndVlmCore(styMidi, vlmNew);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// Actor sounds
|
|
if (_lsndSpeech.FChanged(&vlmNew, &fNuked))
|
|
{
|
|
if (fNuked)
|
|
{
|
|
if (!_pactr->FDeleteSndCore(stySpeech, fFalse))
|
|
return fFalse;
|
|
}
|
|
else
|
|
{
|
|
if (!_pactr->FSetVlmSnd(stySpeech, fFalse, vlmNew))
|
|
return fFalse;
|
|
}
|
|
}
|
|
|
|
if (_lsndSfx.FChanged(&vlmNew, &fNuked))
|
|
{
|
|
if (fNuked)
|
|
{
|
|
if (!_pactr->FDeleteSndCore(stySfx, fFalse))
|
|
return fFalse;
|
|
}
|
|
else
|
|
{
|
|
if (!_pactr->FSetVlmSnd(stySfx, fFalse, vlmNew))
|
|
return fFalse;
|
|
}
|
|
}
|
|
|
|
if (_lsndSpeechMM.FChanged(&vlmNew, &fNuked))
|
|
{
|
|
if (fNuked)
|
|
{
|
|
if (!_pactr->FDeleteSndCore(stySpeech, fTrue))
|
|
return fFalse;
|
|
}
|
|
else
|
|
{
|
|
if (!_pactr->FSetVlmSnd(stySpeech, fTrue, vlmNew))
|
|
return fFalse;
|
|
}
|
|
}
|
|
|
|
if (_lsndSfxMM.FChanged(&vlmNew, &fNuked))
|
|
{
|
|
if (fNuked)
|
|
{
|
|
if (!_pactr->FDeleteSndCore(stySfx, fTrue))
|
|
return fFalse;
|
|
}
|
|
else
|
|
{
|
|
if (!_pactr->FSetVlmSnd(stySfx, fTrue, vlmNew))
|
|
return fFalse;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
_pmvie->ClearUndo();
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the ESLL.
|
|
***************************************************************************/
|
|
void ESLL::AssertValid(ulong grf)
|
|
{
|
|
ESLL_PAR::AssertValid(fobjAllocated);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the ESLL
|
|
***************************************************************************/
|
|
void ESLL::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
ESLL_PAR::MarkMem();
|
|
MarkMemObj(&_lsndSpeech);
|
|
MarkMemObj(&_lsndSfx);
|
|
MarkMemObj(&_lsndSpeechMM);
|
|
MarkMemObj(&_lsndSfxMM);
|
|
MarkMemObj(&_lsndMidi);
|
|
}
|
|
#endif //DEBUG
|
|
|
|
|
|
//
|
|
//
|
|
// LSND (Listener Sound) stuff begins here
|
|
//
|
|
//
|
|
|
|
|
|
/***************************************************************************
|
|
Initialize a LSND. Note that the LSND takes over the reference to
|
|
*ppgltag.
|
|
***************************************************************************/
|
|
bool LSND::FInit(long sty, long kidVol, long kidIcon, long kidEditBox,
|
|
PGL *ppgltag, long vlm, bool fLoop, long objID, bool fMatcher)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertIn(sty, 0, styLim);
|
|
AssertNilOrPo(*ppgltag, 0);
|
|
|
|
long st;
|
|
PGOK pgok;
|
|
PTGOB ptgob;
|
|
PMSND pmsnd;
|
|
long itag;
|
|
TAG tag;
|
|
|
|
_sty = sty;
|
|
_kidVol = kidVol;
|
|
_kidIcon = kidIcon;
|
|
_kidEditBox = kidEditBox;
|
|
_pgltag = *ppgltag;
|
|
*ppgltag = pvNil;
|
|
_vlm = vlm;
|
|
_vlmNew = vlm;
|
|
_fLoop = fLoop;
|
|
_objID = objID;
|
|
_fMatcher = fMatcher;
|
|
|
|
if (pvNil == _pgltag || 0 == _pgltag->IvMac())
|
|
return fTrue;
|
|
|
|
// Set button state based on the tool
|
|
if (_pgltag == pvNil || _pgltag->IvMac() == 0)
|
|
st = kstListenDisabled;
|
|
else if (_fMatcher)
|
|
st = kstListenMatcher;
|
|
else if (_pgltag->IvMac() > 1)
|
|
st = kstListenSounderChain;
|
|
else if (_fLoop)
|
|
st = kstListenLooper;
|
|
else
|
|
st = kstListenSounder;
|
|
|
|
// Create the TGOB to display the sound name
|
|
// Search until a valid (not deleted) msnd is found
|
|
for(itag = 0; itag < _pgltag->IvMac(); itag++)
|
|
{
|
|
_pgltag->Get(itag, &tag);
|
|
pmsnd = (PMSND)vptagm->PbacoFetch(&tag, MSND::FReadMsnd);
|
|
if (pvNil == pmsnd)
|
|
return fFalse;
|
|
if (!pmsnd->FValid())
|
|
{
|
|
ReleasePpo(&pmsnd);
|
|
continue;
|
|
}
|
|
ptgob = TGOB::PtgobCreate(kidEditBox, idsListenFont, tavCenter);
|
|
if (pvNil == ptgob)
|
|
{
|
|
Warn("missing edit box");
|
|
ReleasePpo(&pmsnd);
|
|
return fFalse;
|
|
}
|
|
ptgob->SetText(pmsnd->Pstn());
|
|
ReleasePpo(&pmsnd);
|
|
goto LFound;
|
|
}
|
|
// No valid msnd -> no UI change required
|
|
return fTrue;
|
|
|
|
LFound:
|
|
// Update the slider volume
|
|
vpcex->EnqueueCid(cidListenVolSet,
|
|
vpapp->Pkwa()->PgobFromHid(kidVol), pvNil, _vlm);
|
|
|
|
pgok = (PGOK)vpapp->Pkwa()->PgobFromHid(kidIcon);
|
|
if ((pgok != pvNil) && pgok->FIs(kclsGOK))
|
|
pgok->FChangeState(st);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Play the LSND's sound
|
|
***************************************************************************/
|
|
void LSND::Play(void)
|
|
{
|
|
AssertThis(0);
|
|
|
|
long itag;
|
|
TAG tag;
|
|
PMSND pmsnd;
|
|
|
|
if (pvNil == _pgltag || _pgltag->IvMac() == 0)
|
|
return; // nothing to play
|
|
if (_vlmNew < 0)
|
|
return; // don't play nuked sounds
|
|
|
|
// Stop sounds that are already playing. This handles, among other
|
|
// things, a problem that would otherwise occur when changing the
|
|
// volume of a MIDI sound. Normally, MSND doesn't restart a MIDI
|
|
// sound that's currently playing, but we want to force it to
|
|
// restart here.
|
|
StopAllMovieSounds();
|
|
|
|
for (itag = 0; itag < _pgltag->IvMac(); itag++)
|
|
{
|
|
_pgltag->Get(itag, &tag);
|
|
// Verify sound before including in the event list
|
|
pmsnd = (PMSND)vptagm->PbacoFetch(&tag, MSND::FReadMsnd);
|
|
if (pvNil == pmsnd)
|
|
continue; // ignore failure
|
|
Assert(pmsnd->Sty() == _sty, 0);
|
|
pmsnd->Play(_objID, _fLoop, (itag > 0), _vlmNew, 1, fTrue);
|
|
ReleasePpo(&pmsnd);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Return whether the LSND has changed. Specifies new volume and whether
|
|
the sound was nuked.
|
|
***************************************************************************/
|
|
bool LSND::FChanged(long *pvlmNew, bool *pfNuked)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pvlmNew);
|
|
AssertVarMem(pfNuked);
|
|
|
|
*pfNuked = (_vlmNew < 0);
|
|
*pvlmNew = _vlmNew;
|
|
return (_pgltag != pvNil && _pgltag->IvMac() > 0 && _vlm != _vlmNew);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Destroy a LSND
|
|
***************************************************************************/
|
|
LSND::~LSND(void)
|
|
{
|
|
AssertBaseThis(0);
|
|
ReleasePpo(&_pgltag);
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the LSND.
|
|
***************************************************************************/
|
|
void LSND::AssertValid(ulong grf)
|
|
{
|
|
LSND_PAR::AssertValid(0);
|
|
AssertNilOrPo(_pgltag, 0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the LSND
|
|
***************************************************************************/
|
|
void LSND::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
LSND_PAR::MarkMem();
|
|
MarkMemObj(_pgltag);
|
|
}
|
|
#endif //DEBUG
|
|
|
|
|
|
//
|
|
//
|
|
// ESLR (Sound recording easel) stuff begins here
|
|
//
|
|
//
|
|
|
|
BEGIN_CMD_MAP(ESLR, ESL)
|
|
ON_CID_GEN(cidEaselRecord, FCmdRecord, pvNil)
|
|
ON_CID_GEN(cidEaselPlay, FCmdPlay, pvNil)
|
|
ON_CID_GEN(cidAlarm, FCmdUpdateMeter, pvNil)
|
|
END_CMD_MAP_NIL()
|
|
|
|
|
|
/***************************************************************************
|
|
Create a new sound recording easel
|
|
***************************************************************************/
|
|
PESLR ESLR::PeslrNew(PRCA prca, PMVIE pmvie, bool fSpeech, PSTN pstnNew)
|
|
{
|
|
AssertPo(prca, 0);
|
|
AssertPo(pmvie, 0);
|
|
AssertPo(pstnNew, 0);
|
|
|
|
PESLR peslr;
|
|
GCB gcb;
|
|
|
|
if (!FBuildGcb(&gcb, kidBackground, kidRecordGlass))
|
|
return pvNil;
|
|
|
|
peslr = NewObj ESLR(&gcb);
|
|
if (pvNil == peslr)
|
|
return pvNil;
|
|
if (!peslr->_FInit(prca, kidRecordGlass, pmvie, fSpeech, pstnNew))
|
|
{
|
|
ReleasePpo(&peslr);
|
|
return pvNil;
|
|
}
|
|
AssertPo(peslr, 0);
|
|
vpcex->EnqueueCid(cidEaselVisible);
|
|
|
|
return peslr;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Set up this easel
|
|
***************************************************************************/
|
|
bool ESLR::_FInit(PRCA prca, long kidEasel, PMVIE pmvie, bool fSpeech,
|
|
PSTN pstnNew)
|
|
{
|
|
AssertBaseThis(0);
|
|
AssertPo(prca, 0);
|
|
AssertPo(pmvie, 0);
|
|
AssertPo(pstnNew, 0);
|
|
|
|
GCB gcb;
|
|
EDPAR edpar;
|
|
|
|
_pmvie = pmvie;
|
|
_fSpeech = fSpeech;
|
|
|
|
if (!ESLR_PAR::_FInit(prca, kidEasel))
|
|
return fFalse;
|
|
|
|
if (!FBuildGcb(&gcb, kidRecordSoundName, CMH::HidUnique()))
|
|
return fFalse;
|
|
edpar.Set(gcb._hid, gcb._pgob, gcb._grfgob, gcb._gin, &gcb._rcAbs,
|
|
&gcb._rcRel, vpappb->OnnDefVariable(), 0, vpappb->DypTextDef(),
|
|
tahLeft, tavCenter);
|
|
_pedsl = EDSL::PedslNew(&edpar);
|
|
if (pvNil == _pedsl)
|
|
return fFalse;
|
|
_pedsl->SetStn(pstnNew, fFalse);
|
|
_pedsl->SetSel(0, _pedsl->IchMac(), fFalse); // select all of the text
|
|
_pedsl->Activate(fTrue);
|
|
_pedsl->SetCursCno(prca, kcrsIBeam);
|
|
|
|
// added loop around psrecNew to drop sample rate until it worked
|
|
// to work around Win95 SB16 bug. (Tom Laird-McConnell)
|
|
csampSec = kcsampSec;
|
|
do
|
|
{
|
|
_psrec = SREC::PsrecNew(csampSec, 1, 1, kdtsMaxRecord);
|
|
|
|
// if we failed, then the pointer is nil
|
|
if (pvNil == _psrec)
|
|
{
|
|
// then downgrade the samples per second to next level
|
|
csampSec >>= 1;
|
|
}
|
|
// until it succeeds, or the sample rate drops below 11025.
|
|
} while ((pvNil == _psrec) && (csampSec >= 11025));
|
|
|
|
// if we still failed
|
|
if (pvNil == _psrec)
|
|
{
|
|
PushErc(ercSndamWaveDeviceBusy);
|
|
return fFalse;
|
|
}
|
|
|
|
_clok.Start(0);
|
|
|
|
// Set sound meter to 0
|
|
PGOK pgok = (PGOK)vpapp->Pkwa()->PgobFromHid(kidRecordSoundLength);
|
|
if (pvNil != pgok)
|
|
vpcex->EnqueueCid(cidRecordSetLength, pgok, 0, 0, 0, 0, 0);
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Clean up and delete this easel
|
|
***************************************************************************/
|
|
ESLR::~ESLR(void)
|
|
{
|
|
AssertBaseThis(0);
|
|
|
|
ReleasePpo(&_psrec);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Update the meter that shows how long we've been recording.
|
|
***************************************************************************/
|
|
void ESLR::_UpdateMeter(void)
|
|
{
|
|
AssertThis(0);
|
|
|
|
PGOK pgok;
|
|
long dtsRec;
|
|
long percentDone; // no good hungarian for a percent
|
|
|
|
if (_fRecording)
|
|
{
|
|
dtsRec = TsCurrent() - _tsStartRec;
|
|
|
|
percentDone = LwMulDiv(dtsRec, 100, kdtsMaxRecord);
|
|
percentDone = LwBound(percentDone, 0, 100);
|
|
|
|
pgok = (PGOK)vpapp->Pkwa()->PgobFromHid(kidRecordSoundLength);
|
|
if (pvNil != pgok)
|
|
vpcex->EnqueueCid(cidRecordSetLength, pgok, 0, percentDone, 0, 0, 0);
|
|
else
|
|
Bug("where's the sound length gok?");
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Start or stop recording
|
|
***************************************************************************/
|
|
bool ESLR::FCmdRecord(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
if (!_fRecording)
|
|
{
|
|
if (_psrec->FStart())
|
|
{
|
|
_tsStartRec = TsCurrent();
|
|
_fRecording = fTrue;
|
|
if (!_clok.FSetAlarm(0, this))
|
|
return fFalse;
|
|
}
|
|
else
|
|
{
|
|
SetGokState(kidRecordRecord, kstDefault); // pop out rec button
|
|
_fRecording = fFalse;
|
|
_UpdateMeter();
|
|
PushErc(ercSndamWaveDeviceBusy);
|
|
return fFalse;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_psrec->FStop())
|
|
{
|
|
SetGokState(kidRecordRecord, kstDefault); // pop out rec button
|
|
_fRecording = fFalse;
|
|
_UpdateMeter();
|
|
}
|
|
}
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Time to update the meter that shows how long we've been recording.
|
|
***************************************************************************/
|
|
bool ESLR::FCmdUpdateMeter(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
bool fRecordingOld = _fRecording;
|
|
bool fPlayingOld = _fPlaying;
|
|
|
|
_UpdateMeter();
|
|
_fRecording = _psrec->FRecording();
|
|
_fPlaying = _psrec->FPlaying();
|
|
if (fRecordingOld && !_fRecording)
|
|
{
|
|
SetGokState(kidRecordRecord, kstDefault); // pop out rec button
|
|
_UpdateMeter();
|
|
}
|
|
if (fPlayingOld && !_fPlaying)
|
|
SetGokState(kidRecordPlay, kstDefault); // pop out play button
|
|
if (_fRecording || _fPlaying)
|
|
_clok.FSetAlarm(kdtimMeterUpdate, this);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Play the sound that was recorded
|
|
***************************************************************************/
|
|
bool ESLR::FCmdPlay(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
if (_fRecording)
|
|
{
|
|
// try to stop recording
|
|
if (_psrec->FStop())
|
|
{
|
|
SetGokState(kidRecordRecord, kstDefault); // pop out rec button
|
|
_fRecording = fFalse;
|
|
_UpdateMeter();
|
|
}
|
|
else
|
|
{
|
|
// We can't stop the recording, so set the record btn to its
|
|
// selected state. (Script had popped the record btn out as
|
|
// soon as the play button was selected).
|
|
|
|
SetGokState(kidRecordRecord, kstSelected); // pop in rec button
|
|
}
|
|
}
|
|
|
|
if (!_fRecording && _psrec->FHaveSound())
|
|
{
|
|
if (!_fPlaying)
|
|
{
|
|
if (_psrec->FPlay())
|
|
{
|
|
_fPlaying = fTrue;
|
|
if (!_clok.FSetAlarm(0, this))
|
|
return fFalse;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_psrec->FStop())
|
|
{
|
|
_fPlaying = fFalse;
|
|
SetGokState(kidRecordPlay, kstDefault); // pop out play button
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetGokState(kidRecordPlay, kstDefault); // pop out play button
|
|
}
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Save the new sound
|
|
***************************************************************************/
|
|
bool ESLR::_FAcceptChanges(bool *pfDismissEasel)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pfDismissEasel);
|
|
|
|
FNI fni;
|
|
STN stn;
|
|
PFIL pfil = pvNil;
|
|
CNO cno;
|
|
long sty = _fSpeech ? stySpeech : stySfx;
|
|
long kid = _fSpeech ? kidSpeechGlass : kidFXGlass;
|
|
|
|
if (_psrec->FRecording())
|
|
{
|
|
if (_psrec->FStop())
|
|
{
|
|
SetGokState(kidRecordRecord, kstDefault); // pop out rec button
|
|
_fRecording = fFalse;
|
|
_UpdateMeter();
|
|
}
|
|
}
|
|
|
|
if (_psrec->FPlaying())
|
|
{
|
|
if (_psrec->FStop())
|
|
{
|
|
_fPlaying = fFalse;
|
|
SetGokState(kidRecordPlay, kstDefault); // pop out play button
|
|
}
|
|
}
|
|
|
|
if (!_psrec->FHaveSound())
|
|
return fTrue; // user didn't record anything, so don't do anything
|
|
|
|
_pedsl->GetStn(&stn);
|
|
|
|
// If the user did not specify a name for the recorded sound, then
|
|
// display an error and keep the recording easel displayed.
|
|
|
|
if (stn.Cch() == 0)
|
|
{
|
|
PushErc(ercSocNoSoundName);
|
|
|
|
*pfDismissEasel = fFalse;
|
|
return fTrue;
|
|
}
|
|
|
|
if (!fni.FGetTemp())
|
|
return fFalse;
|
|
|
|
if (!_psrec->FSave(&fni))
|
|
return fFalse;
|
|
|
|
pfil = FIL::PfilOpen(&fni, ffilNil);
|
|
if (pvNil == pfil)
|
|
goto LFail;
|
|
|
|
if (!_pmvie->FCopySndFileToMvie(pfil, sty, &cno, &stn))
|
|
goto LFail;
|
|
|
|
// Select the item, extend lists and hilite it
|
|
vpcex->EnqueueCid(cidBrowserSelectThum, vpappb->PcmhFromHid(kid),
|
|
pvNil, cno, ksidUseCrf, 1, 1);
|
|
|
|
ReleasePpo(&pfil);
|
|
if (!fni.FDelete())
|
|
Warn("Couldn't delete temp sound file");
|
|
return fTrue;
|
|
LFail:
|
|
ReleasePpo(&pfil);
|
|
if (!fni.FDelete())
|
|
Warn("Couldn't delete temp sound file");
|
|
return fFalse;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the ESLR.
|
|
***************************************************************************/
|
|
void ESLR::AssertValid(ulong grf)
|
|
{
|
|
ESLL_PAR::AssertValid(fobjAllocated);
|
|
AssertPo(_psrec, 0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the ESLR
|
|
***************************************************************************/
|
|
void ESLR::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
ESLL_PAR::MarkMem();
|
|
MarkMemObj(_psrec);
|
|
}
|
|
#endif //DEBUG
|
|
|