mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 06:39:17 +00:00
STARTREK: Basic walking
This commit is contained in:
parent
0187c795d5
commit
65d24b0451
@ -158,10 +158,10 @@ void StarTrekEngine::handleAwayMissionEvents() {
|
||||
_gfx->incPaletteFadeLevel();
|
||||
break;
|
||||
case TREKEVENT_LBUTTONDOWN:
|
||||
if (_awayMission.field1d != 0)
|
||||
break;
|
||||
//if (_awayMission.field1d != 0) // FIXME: uncomment
|
||||
// break;
|
||||
switch (_awayMission.mapFileLoaded) {
|
||||
case 0:
|
||||
case 1:
|
||||
if (_awayMission.field1c == 0) {
|
||||
_kirkObject->sprite.drawMode = 1; // Hide these objects for function call below?
|
||||
_spockObject->sprite.drawMode = 1;
|
||||
@ -178,11 +178,9 @@ void StarTrekEngine::handleAwayMissionEvents() {
|
||||
|
||||
Common::String animFilename = getCrewmanAnimFilename(0, "walk");
|
||||
Common::Point mousePos = _gfx->getMousePos();
|
||||
// objectWalkToPosition(0, animFilename, _kirkObject->pos.x, _kirkObject->pos.y, mousePos.x, mousePos.y);
|
||||
objectWalkToPosition(0, animFilename, _kirkObject->pos.x, _kirkObject->pos.y, mousePos.x, mousePos.y);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
@ -232,6 +230,17 @@ Room *StarTrekEngine::getRoom() {
|
||||
}
|
||||
|
||||
void StarTrekEngine::runAwayMissionCycle() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given position in the room is solid (not walkable).
|
||||
* Reads from a ".map" file which has a bit for each position in the room, which is true
|
||||
* when that position is solid.
|
||||
*/
|
||||
bool StarTrekEngine::isPositionSolid(int16 x, int16 y) {
|
||||
_mapFile->seek((y * SCREEN_WIDTH + x) / 8, SEEK_SET);
|
||||
return _mapFile->readByte() & (0x80 >> (x % 8));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ struct AwayMission {
|
||||
int16 mouseX;
|
||||
int16 mouseY;
|
||||
byte field1c;
|
||||
byte field1d;
|
||||
byte field1d; // Set while beaming in?
|
||||
bool redshirtDead;
|
||||
byte mapFileLoaded;
|
||||
int8 field25[4];
|
||||
|
@ -54,21 +54,25 @@ struct Object {
|
||||
uint16 field72;
|
||||
uint16 field74;
|
||||
uint16 field76;
|
||||
uint16 iwSrcPosition;
|
||||
uint16 iwDestPosition;
|
||||
uint16 field7c;
|
||||
uint16 field7e;
|
||||
uint16 field80;
|
||||
uint16 field82;
|
||||
uint16 field84;
|
||||
uint16 field86;
|
||||
uint16 field88;
|
||||
uint16 field8a;
|
||||
uint16 field8c;
|
||||
uint16 field8e;
|
||||
int16 iwSrcPosition;
|
||||
int16 iwDestPosition;
|
||||
|
||||
// Fixed-point position values (16.16) used while walking.
|
||||
uint32 granularPosX;
|
||||
uint32 granularPosY;
|
||||
|
||||
// Fixed-point speed values (16.16).
|
||||
uint32 speedX;
|
||||
uint32 speedY;
|
||||
|
||||
Common::Point dest; // Position object is walking toward
|
||||
uint16 field90;
|
||||
byte field92;
|
||||
char direction; // Can 'n', 's', 'e', 'w', or 0 for uninitialized?
|
||||
|
||||
// Can 'n', 's', 'e', 'w', or 0 for uninitialized?
|
||||
// Can also be capitalized?
|
||||
char direction;
|
||||
|
||||
uint16 field94;
|
||||
uint16 field96;
|
||||
char animationString[9];
|
||||
|
@ -100,7 +100,7 @@ Common::Error StarTrekEngine::run() {
|
||||
_gameMode = -1;
|
||||
_lastGameMode = -1;
|
||||
|
||||
runGameMode(GAMEMODE_BEAMDOWN);
|
||||
runGameMode(GAMEMODE_AWAYMISSION);
|
||||
return Common::kNoError;
|
||||
|
||||
|
||||
@ -381,6 +381,43 @@ int StarTrekEngine::loadObjectAnim(int objectIndex, const Common::String &animNa
|
||||
return objectIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to make an object walk to a position.
|
||||
* Returns true if successful in initiating the walk.
|
||||
*/
|
||||
bool StarTrekEngine::objectWalkToPosition(int objectIndex, const Common::String &animFile, int16 srcX, int16 srcY, int16 destX, int16 destY) {
|
||||
debugC(6, "Obj %d: walk from (%d,%d) to (%d,%d)", objectIndex, srcX, srcY, destX, destY);
|
||||
|
||||
Object *object = &_objectList[objectIndex];
|
||||
|
||||
object->field64 = 0;
|
||||
if (isPositionSolid(destX, destY))
|
||||
return false;
|
||||
|
||||
if (object->spriteDrawn)
|
||||
releaseAnim(object);
|
||||
else
|
||||
_gfx->addSprite(&object->sprite);
|
||||
|
||||
object->spriteDrawn = true;
|
||||
object->animType = 1;
|
||||
object->frameToStartNextAnim = _frameIndex + 1;
|
||||
strcpy(object->animationString2, animFile.c_str());
|
||||
|
||||
object->dest.x = destX;
|
||||
object->dest.y = destY;
|
||||
object->field92 = 0;
|
||||
object->field64 = 0;
|
||||
|
||||
object->iwDestPosition = -1;
|
||||
object->iwSrcPosition = -1;
|
||||
|
||||
// TODO: if (directPathExists(srcX, srcY, destX, destY)) {
|
||||
|
||||
chooseObjectDirectionForWalking(object, srcX, srcY, destX, destY);
|
||||
updateObjectPositionWhileWalking(object, (object->granularPosX + 0x8000) >> 16, (object->granularPosY + 0x8000) >> 16);
|
||||
}
|
||||
|
||||
void StarTrekEngine::updateObjectAnimations() {
|
||||
for (int i = 0; i < MAX_OBJECTS; i++) {
|
||||
Object *object = &_objectList[i];
|
||||
@ -388,7 +425,7 @@ void StarTrekEngine::updateObjectAnimations() {
|
||||
continue;
|
||||
|
||||
switch (object->animType) {
|
||||
case 0:
|
||||
case 0: // Not walking?
|
||||
case 2:
|
||||
if (_frameIndex >= object->frameToStartNextAnim) {
|
||||
int nextAnimIndex = 0; // TODO: "chooseNextAnimFrame" function
|
||||
@ -439,8 +476,60 @@ void StarTrekEngine::updateObjectAnimations() {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: // TODO
|
||||
warning("Unimplemented anim type %d", object->animType);
|
||||
case 1: // Walking
|
||||
if (_frameIndex < object->frameToStartNextAnim)
|
||||
break;
|
||||
/*
|
||||
if (i == 0) // TODO: Kirk only
|
||||
sub_22c2d(object->pos.x, object->pos.y);
|
||||
*/
|
||||
if (object->field90 != 0) {
|
||||
Sprite *sprite = &object->sprite;
|
||||
int loops;
|
||||
if (getObjectScaleAtPosition((object->granularPosY + 0x8000) >> 16) < 0xa0)
|
||||
loops = 1;
|
||||
else
|
||||
loops = 2;
|
||||
for (int k = 0; k < loops; k++) {
|
||||
if (object->field90 == 0)
|
||||
break;
|
||||
object->field90--;
|
||||
uint32 newX = object->granularPosX + object->speedX;
|
||||
uint32 newY = object->granularPosY + object->speedY;
|
||||
if ((object->field90 & 3) == 0) {
|
||||
sprite->bitmap.reset();
|
||||
updateObjectPositionWhileWalking(object, (newX + 0x8000) >> 16, (newY + 0x8000) >> 16);
|
||||
object->field92++;
|
||||
}
|
||||
|
||||
object->granularPosX = newX;
|
||||
object->granularPosY = newY;
|
||||
object->frameToStartNextAnim = _frameIndex;
|
||||
}
|
||||
}
|
||||
else { // object->field90 == 0
|
||||
if (object->iwSrcPosition == -1) {
|
||||
if (object->field64 != 0) {
|
||||
object->field64 = 0;
|
||||
//addCommand(COMMAND_12, object->field66 & 0xff, 0, 0);
|
||||
}
|
||||
|
||||
object->sprite.bitmap.reset();
|
||||
updateObjectPositionWhileWalking(object, (object->granularPosX + 0x8000) >> 16, (object->granularPosY + 0x8000) >> 16);
|
||||
initStandAnim(i);
|
||||
}
|
||||
else { // object->iwSrcPosition != -1
|
||||
if (object->iwSrcPosition == object->iwDestPosition) {
|
||||
object->animationString2[strlen(object->animationString2) - 1] = '\0';
|
||||
object->iwDestPosition = -1;
|
||||
object->iwSrcPosition = -1;
|
||||
// sub_11677(object->pos.x, object->pos.y, object->dest.x, object->dest.y);
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("Invalid anim type.");
|
||||
@ -477,7 +566,7 @@ void StarTrekEngine::objectFunc1() {
|
||||
}
|
||||
}
|
||||
|
||||
void StarTrekEngine::drawObjectToScreen(Object *object, const Common::String &_animName, uint16 x, uint16 y, uint16 scale, bool addSprite) {
|
||||
void StarTrekEngine::drawObjectToScreen(Object *object, const Common::String &_animName, int16 x, int16 y, uint16 scale, bool addSprite) {
|
||||
Common::String animFilename = _animName;
|
||||
if (_animName.hasPrefixIgnoreCase("stnd") /* && word_45d20 == -1 */) // TODO
|
||||
animFilename += 'j';
|
||||
@ -571,6 +660,86 @@ void StarTrekEngine::initStandAnim(int objectIndex) {
|
||||
object->animType = 0;
|
||||
}
|
||||
|
||||
void StarTrekEngine::updateObjectPositionWhileWalking(Object *object, int16 x, int16 y) {
|
||||
object->scale = getObjectScaleAtPosition(y);
|
||||
Common::String animName = Common::String::format("%s%02d", object->animationString2, object->field92 & 7);
|
||||
object->sprite.setBitmap(loadAnimationFrame(animName, object->scale));
|
||||
|
||||
memset(object->animationString4, 0, 10);
|
||||
strncpy(object->animationString4, animName.c_str(), 9);
|
||||
|
||||
Sprite *sprite = &object->sprite;
|
||||
sprite->drawPriority = _gfx->getPriValue(0, y);
|
||||
sprite->pos.x = x;
|
||||
sprite->pos.y = y;
|
||||
sprite->bitmapChanged = true;
|
||||
|
||||
object->frameToStartNextAnim = _frameIndex;
|
||||
object->pos.x = x;
|
||||
object->pos.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses a value for the object's speed and direction, based on a source position and
|
||||
* a destination position it's walking to.
|
||||
*/
|
||||
void StarTrekEngine::chooseObjectDirectionForWalking(Object *object, int16 srcX, int16 srcY, int16 destX, int16 destY) {
|
||||
object->granularPosX = srcX << 16;
|
||||
object->granularPosY = srcY << 16;
|
||||
|
||||
int16 distX = destX - srcX;
|
||||
int16 distY = destY - srcY;
|
||||
int16 absDistX = abs(distX);
|
||||
int16 absDistY = abs(distY);
|
||||
|
||||
if (absDistX > absDistY) {
|
||||
char d;
|
||||
if (distX > 0)
|
||||
d = 'E';
|
||||
else
|
||||
d = 'W';
|
||||
|
||||
// Append direction to animation string
|
||||
object->animationString2[strlen(object->animationString2) + 1] = '\0';
|
||||
object->animationString2[strlen(object->animationString2)] = d;
|
||||
|
||||
object->direction = d;
|
||||
object->field90 = absDistX;
|
||||
|
||||
if (distX != 0) {
|
||||
if (distX > 0)
|
||||
object->speedX = 1 << 16;
|
||||
else
|
||||
object->speedX = -1 << 16; // 0xffff0000
|
||||
|
||||
object->speedY = (distY << 16) / absDistX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char d;
|
||||
if (distY > 0)
|
||||
d = 'S';
|
||||
else
|
||||
d = 'N';
|
||||
|
||||
// Append direction to animation string
|
||||
object->animationString2[strlen(object->animationString2) + 1] = '\0';
|
||||
object->animationString2[strlen(object->animationString2)] = d;
|
||||
|
||||
object->direction = d;
|
||||
object->field90 = absDistY;
|
||||
|
||||
if (distY != 0) {
|
||||
if (distY > 0)
|
||||
object->speedY = 1 << 16;
|
||||
else
|
||||
object->speedY = -1 << 16; // 0xffff0000
|
||||
|
||||
object->speedX = (distX << 16) / absDistY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SharedPtr<Bitmap> StarTrekEngine::loadAnimationFrame(const Common::String &filename, uint16 scale) {
|
||||
SharedPtr<Bitmap> bitmapToReturn;
|
||||
|
||||
|
@ -99,7 +99,8 @@ struct TrekEvent {
|
||||
|
||||
enum Commands {
|
||||
COMMAND_TICK = 0,
|
||||
COMMAND_CLICKED_ON_OBJECT
|
||||
COMMAND_CLICKED_ON_OBJECT = 1,
|
||||
COMMAND_12 = 12
|
||||
};
|
||||
|
||||
struct Command {
|
||||
@ -134,6 +135,8 @@ private:
|
||||
uint16 getObjectScaleAtPosition(int16 y);
|
||||
void runAwayMissionCycle();
|
||||
|
||||
bool isPositionSolid(int16 x, int16 y);
|
||||
|
||||
public:
|
||||
Room *getRoom();
|
||||
|
||||
@ -153,13 +156,15 @@ public:
|
||||
// Objects
|
||||
void initObjects();
|
||||
int loadObjectAnim(int objectIndex, const Common::String &animName, int16 x, int16 y, uint16 arg8);
|
||||
bool objectWalkToPosition(int objectIndex, Common::Point src, Common::Point dest);
|
||||
bool objectWalkToPosition(int objectIndex, const Common::String &animFile, int16 srcX, int16 srcY, int16 destX, int16 destY);
|
||||
void updateObjectAnimations();
|
||||
void removeObjectFromScreen(int objectIndex);
|
||||
void objectFunc1();
|
||||
void drawObjectToScreen(Object *object, const Common::String &animName, uint16 field5e, uint16 field60, uint16 arg8, bool addSprite);
|
||||
void drawObjectToScreen(Object *object, const Common::String &animName, int16 x, int16 y, uint16 scale, bool addSprite);
|
||||
void releaseAnim(Object *object);
|
||||
void initStandAnim(int objectIndex);
|
||||
void updateObjectPositionWhileWalking(Object *object, int16 x, int16 y);
|
||||
void chooseObjectDirectionForWalking(Object *object, int16 srcX, int16 srcY, int16 destX, int16 destY);
|
||||
|
||||
SharedPtr<Bitmap> loadAnimationFrame(const Common::String &filename, uint16 arg2);
|
||||
Common::String getCrewmanAnimFilename(int objectIndex, const Common::String &basename);
|
||||
|
Loading…
Reference in New Issue
Block a user