SLUDGE: Refactor PersonaAnimation related code in PeopleManager

This commit is contained in:
Simei Yin 2018-04-15 21:35:19 +02:00
parent 7c74e81e0a
commit 53c79fdde9
8 changed files with 161 additions and 169 deletions

View File

@ -855,7 +855,7 @@ builtIn(anim) {
}
// First store the frame numbers and take 'em off the stack
PersonaAnimation *ba = g_sludge->_peopleMan->createPersonaAnim(numParams - 1, fun->stack);
PersonaAnimation *ba = new PersonaAnimation(numParams - 1, fun->stack);
// Only remaining paramter is the file number
int fileNumber;
@ -867,7 +867,7 @@ builtIn(anim) {
LoadedSpriteBank *sprBanky = g_sludge->_gfxMan->loadBankForAnim(fileNumber);
if (!sprBanky)
return BR_ERROR; // File not found, fatal done already
g_sludge->_peopleMan->setBankFile(ba, sprBanky);
ba->theSprites = sprBanky;
// Return value
newAnimationVariable(fun->reg, ba);
@ -1589,7 +1589,7 @@ builtIn(animate) {
return BR_ERROR;
trimStack(fun->stack);
g_sludge->_peopleMan->animatePerson(obj, pp);
setVariable(fun->reg, SVT_INT, g_sludge->_peopleMan->timeForAnim(pp));
setVariable(fun->reg, SVT_INT, pp->getTotalTime());
return BR_CONTINUE;
}

View File

@ -44,18 +44,24 @@ CursorManager::~CursorManager() {
}
void CursorManager::init() {
_mouseCursorAnim = _vm->_peopleMan->makeNullAnim();
_mouseCursorAnim = new PersonaAnimation();
_mouseCursorFrameNum = 0;
_mouseCursorCountUp = 0;
}
void CursorManager::kill() {
_vm->_peopleMan->deleteAnim(_mouseCursorAnim);
if (_mouseCursorAnim) {
delete _mouseCursorAnim;
_mouseCursorAnim = nullptr;
}
_mouseCursorAnim = nullptr;
}
void CursorManager::pickAnimCursor(PersonaAnimation *pp) {
_vm->_peopleMan->deleteAnim(_mouseCursorAnim);
if (_mouseCursorAnim) {
delete _mouseCursorAnim;
_mouseCursorAnim = nullptr;
}
_mouseCursorAnim = pp;
_mouseCursorFrameNum = 0;
_mouseCursorCountUp = 0;
@ -107,18 +113,21 @@ void CursorManager::pasteCursor(int x, int y, PersonaAnimation *c) {
void CursorManager::freeze(FrozenStuffStruct *frozenStuff) {
frozenStuff->mouseCursorAnim = _mouseCursorAnim;
frozenStuff->mouseCursorFrameNum = _mouseCursorFrameNum;
_mouseCursorAnim = _vm->_peopleMan->makeNullAnim();
_mouseCursorAnim = new PersonaAnimation();
_mouseCursorFrameNum = 0;
}
void CursorManager::resotre(FrozenStuffStruct *frozenStuff) {
_vm->_peopleMan->deleteAnim(_mouseCursorAnim);
if (_mouseCursorAnim) {
delete _mouseCursorAnim;
_mouseCursorAnim = nullptr;
}
_mouseCursorAnim = frozenStuff->mouseCursorAnim;
_mouseCursorFrameNum = frozenStuff->mouseCursorFrameNum;
}
void CursorManager::saveCursor(Common::WriteStream *stream) {
_vm->_peopleMan->saveAnim(_mouseCursorAnim, stream);
_mouseCursorAnim->save(stream);
stream->writeUint16BE(_mouseCursorFrameNum);
}
@ -126,7 +135,7 @@ bool CursorManager::loadCursor(Common::SeekableReadStream *stream) {
_mouseCursorAnim = new PersonaAnimation;
if (!checkNew(_mouseCursorAnim))
return false;
if (!_vm->_peopleMan->loadAnim(_mouseCursorAnim, stream))
if (!_mouseCursorAnim->load(stream))
return false;
_mouseCursorFrameNum = stream->readUint16BE();
return true;

View File

@ -53,7 +53,7 @@ public:
private:
SludgeEngine *_vm;
PersonaAnimation *_mouseCursorAnim;
PersonaAnimation *_mouseCursorAnim;
int _mouseCursorFrameNum;
int _mouseCursorCountUp;
};

View File

@ -218,7 +218,7 @@ bool saveVariable(Variable *from, Common::WriteStream *stream) {
return false;
case SVT_ANIM:
g_sludge->_peopleMan->saveAnim(from->varData.animHandler, stream);
from->varData.animHandler->save(stream);
return false;
case SVT_NULL:
@ -260,7 +260,7 @@ bool loadVariable(Variable *to, Common::SeekableReadStream *stream) {
to->varData.animHandler = new PersonaAnimation ;
if (!checkNew(to->varData.animHandler))
return false;
g_sludge->_peopleMan->loadAnim(to->varData.animHandler, stream);
to->varData.animHandler->load(stream);
return true;
default:

View File

@ -50,6 +50,114 @@ extern VariableStack *noStack;
extern int ssgVersion;
extern Floor *currentFloor;
PersonaAnimation::PersonaAnimation() {
theSprites = nullptr;
numFrames = 0;
frames = nullptr;
}
PersonaAnimation::~PersonaAnimation() {
if (numFrames) {
delete[] frames;
frames = nullptr;
}
}
PersonaAnimation::PersonaAnimation(int num, VariableStack *&stacky) {
theSprites = nullptr;
numFrames = num;
frames = new AnimFrame[num];
int a = num, frameNum, howMany;
while (a) {
a--;
frames[a].noise = 0;
if (stacky->thisVar.varType == SVT_FILE) {
frames[a].noise = stacky->thisVar.varData.intValue;
} else if (stacky->thisVar.varType == SVT_FUNC) {
frames[a].noise = -stacky->thisVar.varData.intValue;
} else if (stacky->thisVar.varType == SVT_STACK) {
getValueType(frameNum, SVT_INT, stacky->thisVar.varData.theStack->first->thisVar);
getValueType(howMany, SVT_INT, stacky->thisVar.varData.theStack->first->next->thisVar);
} else {
getValueType(frameNum, SVT_INT, stacky->thisVar);
howMany = 1;
}
trimStack(stacky);
frames[a].frameNum = frameNum;
frames[a].howMany = howMany;
}
}
PersonaAnimation::PersonaAnimation(PersonaAnimation *orig) {
int num = orig->numFrames;
// Copy the easy bits...
theSprites = orig->theSprites;
numFrames = num;
if (num) {
// Argh! Frames! We need a whole NEW array of AnimFrame structures...
frames = new AnimFrame[num];
for (int a = 0; a < num; a++) {
frames[a].frameNum = orig->frames[a].frameNum;
frames[a].howMany = orig->frames[a].howMany;
frames[a].noise = orig->frames[a].noise;
}
} else {
frames = nullptr;
}
}
int PersonaAnimation::getTotalTime() {
int total = 0;
for (int a = 0; a < numFrames; a++) {
total += frames[a].howMany;
}
return total;
}
bool PersonaAnimation::save(Common::WriteStream *stream) {
stream->writeUint16BE(numFrames);
if (numFrames) {
stream->writeUint32LE(theSprites->ID);
for (int a = 0; a < numFrames; a++) {
stream->writeUint32LE(frames[a].frameNum);
stream->writeUint32LE(frames[a].howMany);
stream->writeUint32LE(frames[a].noise);
}
}
return true;
}
bool PersonaAnimation::load(Common::SeekableReadStream *stream) {
numFrames = stream->readUint16BE();
if (numFrames) {
int a = stream->readUint32LE();
frames = new AnimFrame [numFrames];
if (!checkNew(frames))
return false;
theSprites = g_sludge->_gfxMan->loadBankForAnim(a);
for (a = 0; a < numFrames; a++) {
frames[a].frameNum = stream->readUint32LE();
frames[a].howMany = stream->readUint32LE();
if (ssgVersion >= VERSION(2, 0)) {
frames[a].noise = stream->readUint32LE();
} else {
frames[a].noise = 0;
}
}
} else {
theSprites = NULL;
frames = NULL;
}
return true;
}
PeopleManager::PeopleManager(SludgeEngine *vm) {
_vm = vm;
_allPeople = nullptr;
@ -69,91 +177,6 @@ void PeopleManager::setFrames(OnScreenPerson &m, int a) {
m.myAnim = m.myPersona->animation[(a * m.myPersona->numDirections) + m.direction];
}
PersonaAnimation *PeopleManager::createPersonaAnim(int num, VariableStack *&stacky) {
PersonaAnimation *newP = new PersonaAnimation ;
checkNew(newP);
newP->numFrames = num;
newP->frames = new AnimFrame [num];
checkNew(newP->frames);
int a = num, frameNum, howMany;
while (a) {
a--;
newP->frames[a].noise = 0;
if (stacky->thisVar.varType == SVT_FILE) {
newP->frames[a].noise = stacky->thisVar.varData.intValue;
} else if (stacky->thisVar.varType == SVT_FUNC) {
newP->frames[a].noise = -stacky->thisVar.varData.intValue;
} else if (stacky->thisVar.varType == SVT_STACK) {
getValueType(frameNum, SVT_INT, stacky->thisVar.varData.theStack->first->thisVar);
getValueType(howMany, SVT_INT, stacky->thisVar.varData.theStack->first->next->thisVar);
} else {
getValueType(frameNum, SVT_INT, stacky->thisVar);
howMany = 1;
}
trimStack(stacky);
newP->frames[a].frameNum = frameNum;
newP->frames[a].howMany = howMany;
}
return newP;
}
PersonaAnimation *PeopleManager::makeNullAnim() {
PersonaAnimation *newAnim = new PersonaAnimation ;
if (!checkNew(newAnim))
return NULL;
newAnim->theSprites = NULL;
newAnim->numFrames = 0;
newAnim->frames = NULL;
return newAnim;
}
PersonaAnimation *PeopleManager::copyAnim(PersonaAnimation *orig) {
int num = orig->numFrames;
PersonaAnimation *newAnim = new PersonaAnimation ;
if (!checkNew(newAnim))
return NULL;
// Copy the easy bits...
newAnim->theSprites = orig->theSprites;
newAnim->numFrames = num;
if (num) {
// Argh!Frames!We need a whole NEW array of AnimFrame structures...
newAnim->frames = new AnimFrame [num];
if (!checkNew(newAnim->frames))
return NULL;
for (int a = 0; a < num; a++) {
newAnim->frames[a].frameNum = orig->frames[a].frameNum;
newAnim->frames[a].howMany = orig->frames[a].howMany;
newAnim->frames[a].noise = orig->frames[a].noise;
}
} else {
newAnim->frames = NULL;
}
return newAnim;
}
void PeopleManager::deleteAnim(PersonaAnimation *orig) {
if (orig) {
if (orig->numFrames) {
delete[] orig->frames;
}
delete orig;
orig = NULL;
}
}
void PeopleManager::turnMeAngle(OnScreenPerson *thisPerson, int direc) {
int d = thisPerson->myPersona->numDirections;
thisPerson->angle = direc;
@ -859,14 +882,6 @@ bool PeopleManager::addPerson(int x, int y, int objNum, Persona *p) {
return (bool)(newPerson->thisType != NULL);
}
int PeopleManager::timeForAnim(PersonaAnimation *fram) {
int total = 0;
for (int a = 0; a < fram->numFrames; a++) {
total += fram->frames[a].howMany;
}
return total;
}
void PeopleManager::animatePerson(int obj, PersonaAnimation *fram) { // Set a new SINGLE animation
OnScreenPerson *moveMe = findPerson(obj);
if (moveMe) {
@ -956,51 +971,11 @@ void PeopleManager::removeOneCharacter(int i) {
}
}
bool PeopleManager::saveAnim(PersonaAnimation *p, Common::WriteStream *stream) {
stream->writeUint16BE(p->numFrames);
if (p->numFrames) {
stream->writeUint32LE(p->theSprites->ID);
for (int a = 0; a < p->numFrames; a++) {
stream->writeUint32LE(p->frames[a].frameNum);
stream->writeUint32LE(p->frames[a].howMany);
stream->writeUint32LE(p->frames[a].noise);
}
}
return true;
}
bool PeopleManager::loadAnim(PersonaAnimation *p, Common::SeekableReadStream *stream) {
p->numFrames = stream->readUint16BE();
if (p->numFrames) {
int a = stream->readUint32LE();
p->frames = new AnimFrame [p->numFrames];
if (!checkNew(p->frames))
return false;
p->theSprites = g_sludge->_gfxMan->loadBankForAnim(a);
for (a = 0; a < p->numFrames; a++) {
p->frames[a].frameNum = stream->readUint32LE();
p->frames[a].howMany = stream->readUint32LE();
if (ssgVersion >= VERSION(2, 0)) {
p->frames[a].noise = stream->readUint32LE();
} else {
p->frames[a].noise = 0;
}
}
} else {
p->theSprites = NULL;
p->frames = NULL;
}
return true;
}
bool PeopleManager::saveCostume(Persona *cossy, Common::WriteStream *stream) {
int a;
stream->writeUint16BE(cossy->numDirections);
for (a = 0; a < cossy->numDirections * 3; a++) {
if (!saveAnim(cossy->animation[a], stream))
if (!cossy->animation[a]->save(stream))
return false;
}
return true;
@ -1017,7 +992,7 @@ bool PeopleManager::loadCostume(Persona *cossy, Common::SeekableReadStream *stre
if (!checkNew(cossy->animation[a]))
return false;
if (!loadAnim(cossy->animation[a], stream))
if (!cossy->animation[a]->load(stream))
return false;
}
return true;
@ -1044,7 +1019,7 @@ bool PeopleManager::savePeople(Common::WriteStream *stream) {
stream->writeFloatLE(me->y);
saveCostume(me->myPersona, stream);
saveAnim(me->myAnim, stream);
me->myAnim->save(stream);
stream->writeByte(me->myAnim == me->lastUsedAnim);
stream->writeFloatLE(me->scale);
@ -1120,7 +1095,7 @@ bool PeopleManager::loadPeople(Common::SeekableReadStream *stream) {
me->y = stream->readFloatLE();
loadCostume(me->myPersona, stream);
loadAnim(me->myAnim, stream);
me->myAnim->load(stream);
me->lastUsedAnim = stream->readByte() ? me->myAnim : NULL;

View File

@ -27,6 +27,7 @@
namespace Sludge {
struct FrozenStuffStruct;
struct LoadedSpriteBank;
struct ScreenRegion;
struct AnimFrame {
@ -44,9 +45,21 @@ struct AnimFrame {
#define EXTRA_RECTANGULAR 64
struct PersonaAnimation {
struct LoadedSpriteBank *theSprites;
LoadedSpriteBank *theSprites;
AnimFrame *frames;
int numFrames;
PersonaAnimation();
PersonaAnimation(int num, struct VariableStack *&stacky);
PersonaAnimation(PersonaAnimation *orig);
~PersonaAnimation();
// Setter & getter
int getTotalTime();
// Save & load
bool save(Common::WriteStream *stream);
bool load(Common::SeekableReadStream *stream);
};
struct Persona {
@ -117,19 +130,9 @@ public:
// Animating 'em
void animatePerson(int obj, PersonaAnimation *);
void animatePerson(int obj, Persona *per);
PersonaAnimation *createPersonaAnim(int num, struct VariableStack *&stacky);
inline void setBankFile(PersonaAnimation *newP, LoadedSpriteBank *sB) {
newP->theSprites = sB;
}
bool setPersonExtra(int f, int newSetting);
int timeForAnim(PersonaAnimation *fram);
PersonaAnimation *copyAnim(PersonaAnimation *orig);
PersonaAnimation *makeNullAnim();
void deleteAnim(PersonaAnimation *orig);
// Loading and saving
bool saveAnim(PersonaAnimation *p, Common::WriteStream *stream);
bool loadAnim(PersonaAnimation *p, Common::SeekableReadStream *stream);
bool savePeople(Common::WriteStream *stream);
bool loadPeople(Common::SeekableReadStream *stream);
bool saveCostume(Persona *cossy, Common::WriteStream *stream);

View File

@ -65,7 +65,10 @@ void unlinkVar(Variable &thisVar) {
break;
case SVT_ANIM:
g_sludge->_peopleMan->deleteAnim(thisVar.varData.animHandler);
if (thisVar.varData.animHandler) {
delete thisVar.varData.animHandler;
thisVar.varData.animHandler = nullptr;
}
break;
default:
@ -85,12 +88,12 @@ void newAnimationVariable(Variable &thisVar, PersonaAnimation *i) {
thisVar.varData.animHandler = i;
}
PersonaAnimation *getAnimationFromVar(Variable &thisVar) {
PersonaAnimation *getAnimationFromVar(Variable &thisVar) {
if (thisVar.varType == SVT_ANIM)
return g_sludge->_peopleMan->copyAnim(thisVar.varData.animHandler);
return new PersonaAnimation(thisVar.varData.animHandler);
if (thisVar.varType == SVT_INT && thisVar.varData.intValue == 0)
return g_sludge->_peopleMan->makeNullAnim();
return new PersonaAnimation();
fatal("Expecting an animation variable; found Variable of type", typeName[thisVar.varType]);
return NULL;
@ -116,7 +119,7 @@ Persona *getCostumeFromVar(Variable &thisVar) {
return NULL;
for (int iii = 0; iii < 3; iii++)
p->animation[iii] = g_sludge->_peopleMan->copyAnim(thisVar.varData.animHandler);
p->animation[iii] = new PersonaAnimation(thisVar.varData.animHandler);
break;
@ -370,7 +373,7 @@ bool copyMain(const Variable &from, Variable &to) {
return true;
case SVT_ANIM:
to.varData.animHandler = g_sludge->_peopleMan->copyAnim(from.varData.animHandler);
to.varData.animHandler = new PersonaAnimation(from.varData.animHandler);
return true;
case SVT_NULL:

View File

@ -24,6 +24,8 @@
namespace Sludge {
struct Persona;
struct PersonaAnimation;
struct Variable;
struct VariableStack;
@ -58,8 +60,8 @@ union VariableData {
signed int intValue;
const char *theString;
StackHandler *theStack;
struct PersonaAnimation *animHandler;
struct Persona *costumeHandler;
PersonaAnimation *animHandler;
Persona *costumeHandler;
FastArrayHandler *fastArray;
};