Skip to content

Commit

Permalink
STARTREK: Basic walking
Browse files Browse the repository at this point in the history
  • Loading branch information
Stewmath authored and sev- committed Aug 9, 2018
1 parent 0187c79 commit 65d24b0
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 28 deletions.
21 changes: 15 additions & 6 deletions engines/startrek/awaymission.cpp
Expand Up @@ -158,10 +158,10 @@ void StarTrekEngine::handleAwayMissionEvents() {
_gfx->incPaletteFadeLevel(); _gfx->incPaletteFadeLevel();
break; break;
case TREKEVENT_LBUTTONDOWN: case TREKEVENT_LBUTTONDOWN:
if (_awayMission.field1d != 0) //if (_awayMission.field1d != 0) // FIXME: uncomment
break; // break;
switch (_awayMission.mapFileLoaded) { switch (_awayMission.mapFileLoaded) {
case 0: case 1:
if (_awayMission.field1c == 0) { if (_awayMission.field1c == 0) {
_kirkObject->sprite.drawMode = 1; // Hide these objects for function call below? _kirkObject->sprite.drawMode = 1; // Hide these objects for function call below?
_spockObject->sprite.drawMode = 1; _spockObject->sprite.drawMode = 1;
Expand All @@ -178,11 +178,9 @@ void StarTrekEngine::handleAwayMissionEvents() {


Common::String animFilename = getCrewmanAnimFilename(0, "walk"); Common::String animFilename = getCrewmanAnimFilename(0, "walk");
Common::Point mousePos = _gfx->getMousePos(); 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; break;
case 1:
break;
case 2: case 2:
break; break;
case 3: case 3:
Expand Down Expand Up @@ -232,6 +230,17 @@ Room *StarTrekEngine::getRoom() {
} }


void StarTrekEngine::runAwayMissionCycle() { 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));
} }


} }
2 changes: 1 addition & 1 deletion engines/startrek/awaymission.h
Expand Up @@ -28,7 +28,7 @@ struct AwayMission {
int16 mouseX; int16 mouseX;
int16 mouseY; int16 mouseY;
byte field1c; byte field1c;
byte field1d; byte field1d; // Set while beaming in?
bool redshirtDead; bool redshirtDead;
byte mapFileLoaded; byte mapFileLoaded;
int8 field25[4]; int8 field25[4];
Expand Down
30 changes: 17 additions & 13 deletions engines/startrek/object.h
Expand Up @@ -54,21 +54,25 @@ struct Object {
uint16 field72; uint16 field72;
uint16 field74; uint16 field74;
uint16 field76; uint16 field76;
uint16 iwSrcPosition; int16 iwSrcPosition;
uint16 iwDestPosition; int16 iwDestPosition;
uint16 field7c;
uint16 field7e; // Fixed-point position values (16.16) used while walking.
uint16 field80; uint32 granularPosX;
uint16 field82; uint32 granularPosY;
uint16 field84;
uint16 field86; // Fixed-point speed values (16.16).
uint16 field88; uint32 speedX;
uint16 field8a; uint32 speedY;
uint16 field8c;
uint16 field8e; Common::Point dest; // Position object is walking toward
uint16 field90; uint16 field90;
byte field92; 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 field94;
uint16 field96; uint16 field96;
char animationString[9]; char animationString[9];
Expand Down
179 changes: 174 additions & 5 deletions engines/startrek/startrek.cpp
Expand Up @@ -100,7 +100,7 @@ Common::Error StarTrekEngine::run() {
_gameMode = -1; _gameMode = -1;
_lastGameMode = -1; _lastGameMode = -1;


runGameMode(GAMEMODE_BEAMDOWN); runGameMode(GAMEMODE_AWAYMISSION);
return Common::kNoError; return Common::kNoError;




Expand Down Expand Up @@ -381,14 +381,51 @@ int StarTrekEngine::loadObjectAnim(int objectIndex, const Common::String &animNa
return objectIndex; 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() { void StarTrekEngine::updateObjectAnimations() {
for (int i = 0; i < MAX_OBJECTS; i++) { for (int i = 0; i < MAX_OBJECTS; i++) {
Object *object = &_objectList[i]; Object *object = &_objectList[i];
if (!object->spriteDrawn) if (!object->spriteDrawn)
continue; continue;


switch (object->animType) { switch (object->animType) {
case 0: case 0: // Not walking?
case 2: case 2:
if (_frameIndex >= object->frameToStartNextAnim) { if (_frameIndex >= object->frameToStartNextAnim) {
int nextAnimIndex = 0; // TODO: "chooseNextAnimFrame" function int nextAnimIndex = 0; // TODO: "chooseNextAnimFrame" function
Expand Down Expand Up @@ -439,8 +476,60 @@ void StarTrekEngine::updateObjectAnimations() {
} }
} }
break; break;
case 1: // TODO case 1: // Walking
warning("Unimplemented anim type %d", object->animType); 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; break;
default: default:
error("Invalid anim type."); error("Invalid anim type.");
Expand Down Expand Up @@ -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; Common::String animFilename = _animName;
if (_animName.hasPrefixIgnoreCase("stnd") /* && word_45d20 == -1 */) // TODO if (_animName.hasPrefixIgnoreCase("stnd") /* && word_45d20 == -1 */) // TODO
animFilename += 'j'; animFilename += 'j';
Expand Down Expand Up @@ -571,6 +660,86 @@ void StarTrekEngine::initStandAnim(int objectIndex) {
object->animType = 0; 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> StarTrekEngine::loadAnimationFrame(const Common::String &filename, uint16 scale) {
SharedPtr<Bitmap> bitmapToReturn; SharedPtr<Bitmap> bitmapToReturn;


Expand Down
11 changes: 8 additions & 3 deletions engines/startrek/startrek.h
Expand Up @@ -99,7 +99,8 @@ struct TrekEvent {


enum Commands { enum Commands {
COMMAND_TICK = 0, COMMAND_TICK = 0,
COMMAND_CLICKED_ON_OBJECT COMMAND_CLICKED_ON_OBJECT = 1,
COMMAND_12 = 12
}; };


struct Command { struct Command {
Expand Down Expand Up @@ -134,6 +135,8 @@ class StarTrekEngine : public ::Engine {
uint16 getObjectScaleAtPosition(int16 y); uint16 getObjectScaleAtPosition(int16 y);
void runAwayMissionCycle(); void runAwayMissionCycle();


bool isPositionSolid(int16 x, int16 y);

public: public:
Room *getRoom(); Room *getRoom();


Expand All @@ -153,13 +156,15 @@ class StarTrekEngine : public ::Engine {
// Objects // Objects
void initObjects(); void initObjects();
int loadObjectAnim(int objectIndex, const Common::String &animName, int16 x, int16 y, uint16 arg8); 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 updateObjectAnimations();
void removeObjectFromScreen(int objectIndex); void removeObjectFromScreen(int objectIndex);
void objectFunc1(); 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 releaseAnim(Object *object);
void initStandAnim(int objectIndex); 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); SharedPtr<Bitmap> loadAnimationFrame(const Common::String &filename, uint16 arg2);
Common::String getCrewmanAnimFilename(int objectIndex, const Common::String &basename); Common::String getCrewmanAnimFilename(int objectIndex, const Common::String &basename);
Expand Down

0 comments on commit 65d24b0

Please sign in to comment.