DISP_ROOM additions + 'Person' functions

svn-id: r10779
This commit is contained in:
Gregory Montoir 2003-10-13 14:21:17 +00:00
parent 5acafb15c2
commit b750398d20
7 changed files with 314 additions and 60 deletions

View File

@ -385,15 +385,15 @@ void Graphics::bobSetupControl() {
}
void Graphics::bobAnimString(uint32 bobnum, uint8* animBuf) {
void Graphics::bobAnimString(uint32 bobnum, uint16* animBuf) {
BobSlot *pbs = &_bobs[bobnum];
pbs->active = true;
pbs->animating = true;
pbs->anim.string.buffer = animBuf;
pbs->anim.string.curPos = animBuf;
pbs->frameNum = READ_LE_UINT16(animBuf);
pbs->anim.speed = READ_LE_UINT16(animBuf + 2) / 4;
pbs->frameNum = animBuf[0];
pbs->anim.speed = animBuf[1] / 4;
}
@ -499,16 +499,16 @@ void BobSlot::animOneStep() {
if (anim.string.buffer != NULL) {
--anim.speed;
if(anim.speed == 0) {
anim.string.curPos += 4;
uint16 nextFrame = READ_LE_UINT16(anim.string.curPos);
anim.string.curPos += 2;
uint16 nextFrame = anim.string.curPos[0];
if (nextFrame == 0) {
anim.string.curPos = anim.string.buffer;
frameNum = READ_LE_UINT16(anim.string.curPos);
frameNum = anim.string.curPos[0];
}
else {
frameNum = nextFrame;
}
anim.speed = READ_LE_UINT16(anim.string.curPos + 2) / 4;
anim.speed = anim.string.curPos[1] / 4;
// FIXME: handle that when QueenSound class is ready
// play memory sfx and move on to next frame

View File

@ -64,8 +64,8 @@ struct BobSlot {
//! string based animation
struct {
uint8* buffer;
uint8* curPos;
uint16* buffer;
uint16* curPos;
} string;
//! normal moving animation
@ -115,7 +115,7 @@ public:
void bankErase(uint32 bankslot); // erase()
void bobSetupControl();
void bobAnimString(uint32 bobnum, uint8* animBuf); // stringanim()
void bobAnimString(uint32 bobnum, uint16* animBuf); // stringanim()
void bobAnimNormal(uint32 bobnum, uint16 firstFrame, uint16 lastFrame, uint16 speed, bool rebound, bool xflip); // makeanim()
void bobMove(uint32 bobnum, uint16 endx, uint16 endy, int16 speed); // movebob()
void bobDraw(uint32 bobnum, uint16 x, uint16 y, uint16 scale, bool xflip, const Box& box); // bob()

View File

@ -32,6 +32,7 @@ Logic::Logic(Resource *resource, Graphics *graphics)
_jas = _resource->loadFile("QUEEN.JAS", 20);
_joe.x = _joe.y = 0;
_walk = new Walk(this, _graphics);
memset(_gameState, 0, sizeof(_gameState));
initialise();
}
@ -360,7 +361,7 @@ void Logic::initialise() {
_graphicAnim[i].frame3 = (int16)READ_BE_UINT16(ptr);
ptr += 2;
}
_currentRoom = _objectData[_entryObj].room;
_entryObj = 0;
@ -438,6 +439,7 @@ void Logic::initialise() {
_graphics->panelLoad();
_graphics->bobSetupControl();
_walk->joeSetup();
zoneSetupPanel();
memset(_zones, 0, sizeof(_zones));
_oldRoom = 0;
@ -855,7 +857,15 @@ void Logic::roomErase() {
// TODO: TALKHEAD=0;
// TODO: _display->fadeOut();
// TODO: credits system
// TODO: person animations
// invalidates all persons animations
uint16 i;
for (i = 0; i <= 3; ++i) {
_personFrames[i] = 0;
}
for (i = 1; i <= 16; ++i) {
_newAnim[i][0] = 0;
}
uint16 cur = _roomData[_oldRoom] + 1;
uint16 last = _roomData[_oldRoom + 1];
@ -889,13 +899,12 @@ void Logic::roomSetupFurniture() {
// count the furniture and update gameState
uint16 furnitureTotal = 0;
uint16 i;
// FIXME: uncomment when Array< FurnitureData > available in Logic
// for (i = 1; i <= _numFurnitureData; ++i) {
// if (_furnitureData[i].room == _currentRoom) {
// ++furnitureTotal;
// _gameState[furnitureTotal] = _furnitureData[i].gameStateValue;
// }
// }
for (i = 1; i <= _numFurniture; ++i) {
if (_furnitureData[i].room == _currentRoom) {
++furnitureTotal;
_gameState[furnitureTotal] = _furnitureData[i].gameStateValue;
}
}
if (furnitureTotal == 0) {
return;
}
@ -1018,20 +1027,17 @@ void Logic::roomSetupObjects() {
}
// persons Bobs
uint16 bobNum = 0;
for (i = firstRoomObj; i <= lastRoomObj; ++i) {
ObjectData *pod = &_objectData[i];
if (pod->image == -3 || pod->image == -4) {
++bobNum;
uint16 noun = i - firstRoomObj;
// FIXME: need Person stuff
// if (pod->name > 0) {
// curImage = personSetup(noun, curImage);
// }
// else {
// curImage = personAllocate(noun, curImage);
// }
warning("Logic::roomSetupObjects() - Person object number %d not handled", noun);
debug(9, "Logic::roomSetupObjects() - Setting up person %d", i);
uint16 noun = i - _roomData[_currentRoom];
if (pod->name > 0) {
curImage = personSetup(noun, curImage);
}
else {
curImage = personAllocate(noun, curImage);
}
}
}
@ -1108,5 +1114,228 @@ uint16 Logic::findScale(uint16 x, uint16 y) {
}
void Logic::personSetData(int16 noun, const char *actorName, bool loadBank, Person *pp) {
if (noun <= 0) {
warning("Logic::personSetData() - Negative object number");
}
uint16 i;
uint16 obj = _roomData[_currentRoom] + noun;
int16 img = _objectData[obj].image;
if (img != -3 && img != -4) {
warning("Logic::personSetData() - Object %d is not a person", obj);
return;
}
// search Bob number for the person
uint16 bobNum = 0;
for (i = _roomData[_currentRoom] + 1; i <= obj; ++i) {
img = _objectData[i].image;
if (img == -3 || img == -4) {
++bobNum;
}
}
// search for a matching actor
uint16 actor = 1;
for (i = 1; i <= _numActors; ++i) {
ActorData *pad = &_actorData[i];
if (pad->room == _currentRoom) {
if (_gameState[pad->gameStateSlot] == pad->gameStateValue) {
if ((bobNum > 0 && bobNum == pad->bobNum) || strcmp(pp->name, actorName) == 0) {
actor = i;
break;
}
}
}
}
pp->actor = &_actorData[actor];
pp->name = _aName[pp->actor->name];
if (pp->actor->anim != 0) {
pp->anim = _aAnim[pp->actor->anim];
}
else {
pp->anim = NULL;
}
if (loadBank) {
const char *actorFile = _aFile[pp->actor->actorFile];
if (actorFile) {
_graphics->bankLoad(actorFile, pp->bankNum);
}
else {
pp->bankNum = 15;
}
}
if (pp->actor->bobNum >= 1 && pp->actor->bobNum <= 3) {
pp->bobFrame = 29 + FRAMES_JOE_XTRA + pp->actor->bobNum;
}
else {
warning("Logic::personSetData() - The bob number for actor is not in the [1:3] range");
}
}
uint16 Logic::personSetup(uint16 noun, uint16 curImage) {
Person p;
personSetData(noun, "", true, &p);
const ActorData *pad = p.actor;
uint16 scale = 100;
uint16 a = zoneInArea(ZONE_ROOM, pad->x, pad->y);
if (a > 0) {
// person is not standing in the area box, scale it accordingly
scale = currentRoomArea(a)->calcScale(pad->y);
}
_graphics->bankUnpack(pad->bobFrameStanding, p.bobFrame, p.bankNum);
bool xflip = false;
uint16 person = _roomData[_currentRoom] + noun;
if (_objectData[person].image == -3) {
// person is facing left
xflip = true;
}
BobSlot *pbs = _graphics->bob(pad->bobNum);
pbs->active = true;
pbs->scale = scale;
pbs->x = pad->x;
pbs->y = pad->y;
pbs->frameNum = p.bobFrame;
pbs->xflip = xflip;
if (p.anim != NULL) {
_personFrames[pad->bobNum] = curImage + 1;
curImage = animCreate(curImage, &p);
}
else {
animErase(pad->bobNum);
}
return curImage;
}
uint16 Logic::personAllocate(uint16 noun, uint16 curImage) {
uint16 i;
uint16 person = _roomData[_currentRoom] + noun;
// search Bob number for the person
uint16 bobNum = 0;
for (i = _roomData[_currentRoom] + 1; i <= person; ++i) {
int16 img = _objectData[i].image;
if (img == -3 || img == -4) {
++bobNum;
}
}
// search for a matching actor
uint16 actor = 0;
for (i = 1; i <= _numActors; ++i) {
ActorData *pad = &_actorData[i];
if (pad->room == _currentRoom) {
if (_gameState[pad->gameStateSlot] == pad->gameStateValue) {
if (bobNum > 0 && bobNum == pad->bobNum) {
actor = i;
break;
}
}
}
}
if (actor > 0) {
const char *animStr = _aAnim[_actorData[actor].actorFile];
if (animStr[0] != '\0') {
bool allocatedFrames[256];
memset(allocatedFrames, 0, sizeof(allocatedFrames));
uint16 f1, f2;
do {
sscanf(animStr, "%3hu,%3hu", &f1, &f2);
animStr += 8;
allocatedFrames[f1] = true;
} while(f1 != 0);
for (i = 1; i <= 255; ++i) {
if (allocatedFrames[i]) {
++curImage;
}
}
_personFrames[bobNum] = curImage + 1;
}
}
return curImage;
}
uint16 Logic::animCreate(uint16 curImage, const Person *person) {
uint16 *animFrames = _newAnim[person->actor->bobNum];
uint16 allocatedFrames[256];
memset(allocatedFrames, 0, sizeof(allocatedFrames));
const char *p = person->anim;
int frame = 0;
uint16 f1, f2;
do {
sscanf(p, "%3hu,%3hu", &f1, &f2);
animFrames[frame + 0] = f1;
animFrames[frame + 1] = f2;
if (f1 > 500) {
// SFX
allocatedFrames[f1 - 500] = 1;
}
else {
allocatedFrames[f1] = 1;
}
p += 8;
frame += 2;
} while(f1 != 0);
// ajust frame numbers
uint16 n = 1;
uint16 i;
for (i = 1; i <= 255; ++i) {
if (allocatedFrames[i] != 0) {
allocatedFrames[i] = n;
++n;
}
}
for (i = 0; animFrames[i] != 0; i += 2) {
uint16 frameNum = animFrames[i];
if (frameNum > 500) {
animFrames[i] = curImage + allocatedFrames[frameNum - 500] + 500;
}
else {
animFrames[i] = curImage + allocatedFrames[frameNum];
}
}
// unpack necessary frames
for (i = 1; i <= 255; ++i) {
if (allocatedFrames[i] != 0) {
++curImage;
_graphics->bankUnpack(i, curImage, person->bankNum);
}
}
// start animation
_graphics->bobAnimString(person->actor->bobNum, animFrames);
return curImage;
}
void Logic::animErase(uint16 bobNum) {
_newAnim[bobNum][0] = 0;
BobSlot *pbs = _graphics->bob(bobNum);
pbs->animating = false;
pbs->anim.string.buffer = NULL;
}
} // End of namespace Queen

View File

@ -63,7 +63,7 @@ public:
uint16 findBob(uint16 obj);
uint16 findFrame(uint16 obj);
uint16 objectForPerson(uint16 bobnum);
uint16 objectForPerson(uint16 bobnum); // OBJ_PERSON
WalkOffData *walkOffPointForObject(uint16 obj);
Area *area(int room, int num);
@ -112,6 +112,13 @@ public:
int16 entryObj() const { return _entryObj; }
void entryObj(int16 obj) { _entryObj = obj; }
void personSetData(int16 noun, const char *actorName, bool loadBank, Person *pp); // SET_PERSON_DATA
uint16 personSetup(uint16 noun, uint16 curImage); // SETUP_PERSON
uint16 personAllocate(uint16 noun, uint16 curImage); // ALLOCATE_PERSON
uint16 animCreate(uint16 curImage, const Person *person); // CREATE_ANIM
void animErase(uint16 bobNum);
protected:
bool _textToggle;
@ -191,6 +198,10 @@ protected:
uint16 _numFurnitureStatic; // FMAX
uint16 _numFurnitureAnimatedLen; // FMAXLEN
uint16 _numFrames; // FRAMES
uint16 _personFrames[4];
//! contains the animation frames (max 60) to use for a bob (whose number must be < 17)
uint16 _newAnim[17][60];
Resource *_resource;
Graphics *_graphics;

View File

@ -184,6 +184,17 @@ struct GraphicAnim {
};
struct Person {
const ActorData *actor; // P_ROOM, P_BNUM, P_GAMES, P_VALUE, P_COLOR, P_STAND, P_X, P_Y
const char *name; // P_NAMEstr
const char *anim; // P_ANIMstr
uint16 bobFrame; // SFRAME
//! As the bank number may change, we can't re-use actor->bankNum
uint16 bankNum; // P_BANK
};
} // End of namespace Queen
#endif

View File

@ -210,7 +210,7 @@ void Walk::animateJoe() {
}
void Walk::animatePersonPrepare(const MovePersonData *mpd, const Person *pp) {
void Walk::animatePersonPrepare(const MovePersonData *mpd, int direction) {
// queen.c l.2469-2572
int i;
for (i = 1; i <= _walkDataCount; ++i) {
@ -229,7 +229,7 @@ void Walk::animatePersonPrepare(const MovePersonData *mpd, const Person *pp) {
}
else {
// we have specific moves for this actor, see what direction they were last facing
if (pp->direction == -3) {
if (direction == -3) {
// previously facing right
pwd->anim.set(mpd->walkLeft1, mpd->walkLeft2, DIR_LEFT);
}
@ -272,7 +272,7 @@ void Walk::animatePersonPrepare(const MovePersonData *mpd, const Person *pp) {
}
else {
// we have a special move for left/right, so select that instead!
if (pp->direction == -3) {
if (direction == -3) {
// previously facing right
pwd->anim.set(mpd->walkLeft1, mpd->walkLeft2, DIR_FRONT);
}
@ -287,14 +287,14 @@ void Walk::animatePersonPrepare(const MovePersonData *mpd, const Person *pp) {
}
void Walk::animatePerson(const MovePersonData *mpd, const Person *pp) {
void Walk::animatePerson(const MovePersonData *mpd, uint16 image, uint16 bobNum, uint16 bankNum, int direction) {
// queen.c l.2572-2651
BobSlot *pbs = _graphics->bob(pp->bobNum);
BobSlot *pbs = _graphics->bob(bobNum);
// check to see which way person should be facing
if (mpd->walkLeft1 == mpd->walkRight1) {
pbs->xflip = (pp->direction == -3);
pbs->xflip = (direction == -3);
}
else {
// they have special walk for left and right, so don't flip
@ -305,24 +305,24 @@ void Walk::animatePerson(const MovePersonData *mpd, const Person *pp) {
for (i = 1; i <= _walkDataCount; ++i) {
WalkData *pwd = &_walkData[i];
// unpack necessary frames for bob animation
uint16 dstFrame = pp->image;
uint16 dstFrame = image;
uint16 srcFrame = ABS(pwd->anim.firstFrame);
while (srcFrame <= ABS(pwd->anim.lastFrame)) {
_graphics->bankUnpack(srcFrame, dstFrame, pp->bankNum);
_graphics->bankUnpack(srcFrame, dstFrame, bankNum);
++dstFrame;
++srcFrame;
}
// pass across bobs direction ONLY if walk is a mirror flip!
if (ABS(mpd->walkLeft1) == ABS(mpd->walkRight1)) {
_graphics->bobAnimNormal(pp->bobNum, pp->image, dstFrame - 1, mpd->animSpeed, false, pbs->xflip);
_graphics->bobAnimNormal(bobNum, image, dstFrame - 1, mpd->animSpeed, false, pbs->xflip);
}
else {
_graphics->bobAnimNormal(pp->bobNum, pp->image, dstFrame - 1, mpd->animSpeed, false, false);
_graphics->bobAnimNormal(bobNum, image, dstFrame - 1, mpd->animSpeed, false, false);
}
// move other actors at correct speed relative to scale
uint16 moveSpeed = _logic->findScale(pbs->x, pbs->y) * mpd->moveSpeed / 100;
_graphics->bobMove(pp->bobNum, pbs->x + pwd->dx, pbs->y + pwd->dy, moveSpeed);
_graphics->bobMove(bobNum, pbs->x + pwd->dx, pbs->y + pwd->dy, moveSpeed);
// flip if one set of frames for actor
if (mpd->walkLeft1 < 0 || ABS(mpd->walkLeft1) == ABS(mpd->walkRight1)) {
@ -477,18 +477,21 @@ void Walk::joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway) {
void Walk::personMove(Person* pp, uint16 endx, uint16 endy) {
void Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction) {
// CAN = 0;
initWalkData();
uint16 oldx = _graphics->bob(pp->bobNum)->x;
uint16 oldy = _graphics->bob(pp->bobNum)->y;
uint16 bobNum = pp->actor->bobNum;
uint16 bankNum = pp->bankNum;
uint16 oldx = _graphics->bob(bobNum)->x;
uint16 oldy = _graphics->bob(bobNum)->y;
uint16 oldPos = _logic->zoneInArea(ZONE_ROOM, oldx, oldy);
uint16 newPos = _logic->zoneInArea(ZONE_ROOM, endx, endy);
debug(9, "Walk::personMove(%d, %d, %d, %d, %d), old = %d, new = %d", pp->direction, oldx, oldy, endx, endy, oldPos, newPos);
debug(9, "Walk::personMove(%d, %d, %d, %d, %d), old = %d, new = %d", direction, oldx, oldy, endx, endy, oldPos, newPos);
calc(oldPos, newPos, oldx, oldy, endx, endy);
@ -505,30 +508,30 @@ void Walk::personMove(Person* pp, uint16 endx, uint16 endy) {
}
if (_walkDataCount > 0) {
animatePersonPrepare(mpd, pp);
animatePerson(mpd, pp);
animatePersonPrepare(mpd, direction);
animatePerson(mpd, curImage, bobNum, bankNum, direction);
}
uint16 standingFrame = 0;
if (pp->bobNum <= 3) {
standingFrame = 29 + FRAMES_JOE_XTRA + pp->bobNum;
if (bobNum <= 3) {
standingFrame = 29 + FRAMES_JOE_XTRA + bobNum;
}
else {
warning("Walk::personMove() - Wrong bob number : %d", pp->bobNum);
warning("Walk::personMove() - Wrong bob number : %d", bobNum);
}
// make other person face the right direction
BobSlot *pbs = _graphics->bob(pp->bobNum);
BobSlot *pbs = _graphics->bob(bobNum);
pbs->endx = endx;
pbs->endy = endy;
pbs->animating = false;
pbs->scale = _walkData[_walkDataCount].area->calcScale(endy);
if (_walkData[_walkDataCount].anim.facing == DIR_BACK) {
_graphics->bankUnpack(mpd->backStandingFrame, standingFrame, pp->bankNum);
_graphics->bankUnpack(mpd->backStandingFrame, standingFrame, bankNum);
}
else {
_graphics->bankUnpack(mpd->frontStandingFrame, standingFrame, pp->bankNum);
_graphics->bankUnpack(mpd->frontStandingFrame, standingFrame, bankNum);
}
uint16 obj = _logic->objectForPerson(pp->bobNum);
uint16 obj = _logic->objectForPerson(bobNum);
if (_walkData[_walkDataCount].dx < 0) {
_logic->objectData(obj)->image = -3;
pbs->xflip = true;

View File

@ -64,7 +64,7 @@ struct MovePersonData {
uint16 moveSpeed;
};
/*
struct Person {
const char* name;
uint16 bobNum; // P_BOB
@ -72,7 +72,7 @@ struct Person {
uint16 image; // MOVE_OTHER, CI arg
int direction; // MOVE_OTHER, dir arg
};
*/
class Logic;
class Graphics;
@ -95,7 +95,7 @@ public:
uint16 joeFace();
//! MOVE_OTHER
void personMove(Person* name, uint16 endx, uint16 endy);
void personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction);
private:
@ -105,8 +105,8 @@ private:
void animateJoePrepare();
void animateJoe();
void animatePersonPrepare(const MovePersonData *mpd, const Person* pp);
void animatePerson(const MovePersonData *mpd, const Person* pp);
void animatePersonPrepare(const MovePersonData *mpd, int direction);
void animatePerson(const MovePersonData *mpd, uint16 image, uint16 bobNum, uint16 bankNum, int direction);
//! CALC_X, CALC_Y
static uint16 calcC(uint16 c1, uint16 c2, uint16 c3, uint16 c4, uint16 lastc);