aboutsummaryrefslogtreecommitdiff
path: root/engines/startrek/startrek.cpp
diff options
context:
space:
mode:
authorMatthew Stewart2018-08-02 05:20:23 -0400
committerEugene Sandulenko2018-08-09 08:37:30 +0200
commite5e54b8a1f937e2df1dfd141de9d4444257f9540 (patch)
tree36400c273a77bc516daa1caddba7b713bb41d1cd /engines/startrek/startrek.cpp
parenta84746bf660f0413a205636edd39b484018e73b7 (diff)
downloadscummvm-rg350-e5e54b8a1f937e2df1dfd141de9d4444257f9540.tar.gz
scummvm-rg350-e5e54b8a1f937e2df1dfd141de9d4444257f9540.tar.bz2
scummvm-rg350-e5e54b8a1f937e2df1dfd141de9d4444257f9540.zip
STARTREK: Split up startrek.cpp into more files
Diffstat (limited to 'engines/startrek/startrek.cpp')
-rw-r--r--engines/startrek/startrek.cpp1607
1 files changed, 1 insertions, 1606 deletions
diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp
index b6960740d2..cea59a48fd 100644
--- a/engines/startrek/startrek.cpp
+++ b/engines/startrek/startrek.cpp
@@ -240,219 +240,6 @@ Common::Error StarTrekEngine::runGameMode(int mode, bool resume) {
return Common::kNoError;
}
-void StarTrekEngine::playIntro() {
- // TODO: .MT audio file
-
- initStarfieldPosition();
- initStarfield(10, 20, 309, 169, 128);
-
- SharedPtr<Bitmap> fakeStarfieldBitmap(new StubBitmap(0, 0));
- _starfieldSprite.bitmap = fakeStarfieldBitmap;
- initStarfieldSprite(&_starfieldSprite, fakeStarfieldBitmap, _starfieldRect);
-
- //delR3(&_enterpriseR3); // TODO: uncomment
-
- R3 planetR3 = R3();
- planetR3.matrix = initMatrix();
- planetR3.field1e = 3;
- planetR3.funcPtr1 = nullptr;
- planetR3.funcPtr2 = nullptr;
- planetR3.bitmapOffset = 0;
-
- _gfx->clearScreenAndPriBuffer();
- _gfx->fadeoutScreen();
- _gfx->loadPalette("gold");
- _gfx->setBackgroundImage(_gfx->loadBitmap("goldlogo"));
- _sound->playVoc("logo");
- _gfx->copyBackgroundScreen();
- _system->updateScreen();
- _gfx->fadeinScreen();
-
- uint32 clockTicks = _clockTicks;
-
- Sprite subtitleSprite;
- _gfx->addSprite(&subtitleSprite);
- subtitleSprite.setXYAndPriority(0, 0, 12);
- subtitleSprite.bitmap = _gfx->loadBitmap("blank");
- subtitleSprite.drawPriority2 = 16;
-
- int index = 12;
- while (index >= 0) {
- Common::String file = Common::String::format("credit%02d.shp", index);
- // TODO: This loads the file, but does not do anything with the resulting data, so
- // this is just for caching it?
- // Remember to deal with similar commented function calls below, too.
- //loadFileWithParams(file, false, true, false);
- index -= 1;
- }
-
- //loadFileWithParams("legal.bmp", false, true, false);
-
- index = 6;
- while (index >= 0) {
- Common::String file = Common::String::format("tittxt%02d.bmp", index);
- //loadFileWithParams(file, false, true, false);
- index -= 1;
- }
-
- //loadFileWithParams("planet.shp", false, true, false);
-
- index = 6;
- while (index >= 0) {
- Common::String file = Common::String::format("ent%d3.r3s", index);
- //loadFileWithParams(file, false, true, false);
- index -= 1;
- }
-
- // TODO: kirkintr
-
- clockTicks += 540;
-
- while (_clockTicks < clockTicks && _sound->isMidiPlaying()) {
- waitForNextTick(true);
- }
-
- // TODO: MT audio file
-
- _gfx->fadeoutScreen();
- _gfx->loadPalette("bridge");
- _gfx->clearScreenAndPriBuffer();
- _sound->loadMusicFile("title");
- clockTicks = _clockTicks;
-
- int32 starfieldZoomSpeed;
- int16 frame = 0;
- bool buttonPressed = false;
-
- while (frame != 0x180 || (_sound->isMidiPlaying() && !buttonPressed)) {
- if (!buttonPressed) {
- TrekEvent event;
- while (popNextEvent(&event, false)) {
- if (event.type == TREKEVENT_KEYDOWN) {
- _gfx->fadeoutScreen();
- buttonPressed = true;
- } else if (event.type == TREKEVENT_TICK)
- break;
- }
- }
-
- switch (frame) {
- case 0:
- starfieldZoomSpeed = 10;
- playMidiMusicTracks(MIDITRACK_0, -1);
- _byte_45b3c = 0;
- break;
-
- case 30:
- _sound->playVoc("kirkintr");
- loadSubtitleSprite(0, &subtitleSprite);
- break;
-
- case 36:
- loadSubtitleSprite(1, &subtitleSprite);
- break;
-
- case 42: // Enterprise moves toward camera
- loadSubtitleSprite(-1, &subtitleSprite);
- addR3(&_enterpriseR3);
- _enterpriseR3.field1e = 2;
- initIntroR3ObjectToMove(&_enterpriseR3, 330, 5000, 0, 0, 18);
- break;
-
- case 60: // Enterprise moves away from camera
- initIntroR3ObjectToMove(&_enterpriseR3, 0, 0, 30, 5000, 6);
- break;
-
- case 66: // Cut to scene with planet
- loadSubtitleSprite(2, &subtitleSprite);
- planetR3.field22 = 2000;
- planetR3.field24 = 10000 / _starfieldPointDivisor;
- planetR3.shpFile = loadFile("planet.shp");
- initIntroR3ObjectToMove(&planetR3, 6, 10000, 6, 10000, 0);
- addR3(&planetR3);
- initIntroR3ObjectToMove(&_enterpriseR3, -15, 250, 15, 500, 18);
- starfieldZoomSpeed = 0;
- break;
-
- case 186:
- delR3(&_enterpriseR3);
- // TODO: the rest
- break;
-
- case 366:
- planetR3.shpFile.reset();
- delR3(&planetR3);
- break;
-
- case 378:
- _gfx->delSprite(&subtitleSprite);
- _byte_45b3c = 1;
- break;
- }
-
- if (!buttonPressed) {
- updateStarfieldAndShips(false);
- _gfx->drawAllSprites();
- _gfx->incPaletteFadeLevel();
- clockTicks += 3;
-
- while (_clockTicks < clockTicks)
- waitForNextTick();
- }
-
- _starfieldPosition.z += starfieldZoomSpeed;
-
- frame++;
- if (frame >= 0x186)
- frame = 0x186;
- }
-
- _gfx->fadeoutScreen();
- _gfx->delSprite(&_starfieldSprite);
- // TODO: the rest
-}
-
-void StarTrekEngine::initIntroR3ObjectToMove(R3 *r3, int16 srcAngle, int16 srcDepth, int16 destAngle, int16 destDepth, int16 ticks) {
- Fixed8 a1 = Fixed8::fromRaw((srcAngle << 8) / 90);
- Fixed8 a2 = Fixed8::fromRaw((destAngle << 8) / 90);
-
- r3->pos.x = sin(a1).multToInt(srcDepth) + _starfieldPosition.x;
- r3->pos.z = cos(a1).multToInt(srcDepth) + _starfieldPosition.z;
- r3->pos.y = 0;
-
- int32 deltaX = sin(a2).multToInt(destDepth) + _starfieldPosition.x - r3->pos.x;
- int32 deltaZ = cos(a2).multToInt(destDepth) + _starfieldPosition.z - r3->pos.z;
- debug("Z: %d, %d", r3->pos.z - _starfieldPosition.z, cos(a2).multToInt(destDepth));
-
- Angle angle = atan2(deltaX, deltaZ);
- r3->matrix = initSpeedMatrixForXZMovement(angle, initMatrix());
-
- debugCN(5, kDebugSpace, "initIntroR3ObjectToMove: pos %x,%x,%x; ", r3->pos.x, r3->pos.y, r3->pos.z);
-
- if (ticks != 0) {
- debugC(5, kDebugSpace, "speed %x,%x,%x\n", r3->speed.x, r3->speed.y, r3->speed.z);
- r3->speed.x = deltaX / ticks;
- r3->speed.z = deltaZ / ticks;
- r3->speed.y = 0;
- } else {
- debugC(5, kDebugSpace, "speed 0\n");
- r3->speed.x = 0;
- r3->speed.z = 0;
- r3->speed.y = 0;
- }
-}
-
-void StarTrekEngine::loadSubtitleSprite(int index, Sprite *sprite) {
- if (_showSubtitles) {
- if (index == -1)
- sprite->setBitmap(_gfx->loadBitmap("blank"));
- else {
- Common::String file = Common::String::format("tittxt%02d", index);
- sprite->setBitmap(_gfx->loadBitmap(file));
- }
- }
-}
-
void StarTrekEngine::runTransportSequence(const Common::String &name) {
const uint16 crewmanTransportPositions[][2] = {
{ 0x8e, 0x7c },
@@ -579,6 +366,7 @@ void StarTrekEngine::playSoundEffectIndex(int index) {
_sound->playVoc("WARP");
break;
default:
+ debugC(kDebugSound, 6, "Unmapped sound 0x%x", index);
break;
}
}
@@ -596,1399 +384,6 @@ void StarTrekEngine::stopPlayingSpeech() {
_sound->stopPlayingSpeech();
}
-void StarTrekEngine::initActors() {
- for (int i = 0; i < NUM_ACTORS; i++)
- _actorList[i] = Actor();
- for (int i = 0; i < MAX_BAN_FILES; i++)
- _banFiles[i].reset();
-
- strcpy(_kirkActor->animationString, "kstnd");
- strcpy(_spockActor->animationString, "sstnd");
- strcpy(_mccoyActor->animationString, "mstnd");
- strcpy(_redshirtActor->animationString, "rstnd");
-}
-
-int StarTrekEngine::loadActorAnim(int actorIndex, const Common::String &animName, int16 x, int16 y, Fixed8 scale) {
- debugC(6, kDebugGraphics, "Load animation '%s' on actor %d", animName.c_str(), actorIndex);
-
- Actor *actor;
-
- if (actorIndex == -1) {
- // TODO
- warning("loadActorAnim: actor == -1");
- } else
- actor = &_actorList[actorIndex];
-
- if (actor->spriteDrawn) {
- releaseAnim(actor);
- drawActorToScreen(actor, animName, x, y, scale, false);
- } else {
- drawActorToScreen(actor, animName, x, y, scale, true);
- }
-
- actor->triggerActionWhenAnimFinished = false;
- actor->finishedAnimActionParam = 0;
-
- return actorIndex;
-}
-
-void StarTrekEngine::loadBanFile(const Common::String &name) {
- debugC(kDebugGeneral, 7, "Load BAN file: %s.ban", name.c_str());
- for (int i = 0; i < MAX_BAN_FILES; i++) {
- if (!_banFiles[i]) {
- _banFiles[i] = loadFile(name + ".ban");
- _banFileOffsets[i] = 0;
- return;
- }
- }
-
- warning("Couldn't load .BAN file \"%s.ban\"", name.c_str());
-}
-
-bool StarTrekEngine::actorWalkToPosition(int actorIndex, const Common::String &animFile, int16 srcX, int16 srcY, int16 destX, int16 destY) {
- debugC(6, "Obj %d: walk from (%d,%d) to (%d,%d)", actorIndex, srcX, srcY, destX, destY);
-
- Actor *actor = &_actorList[actorIndex];
-
- actor->triggerActionWhenAnimFinished = false;
- if (isPositionSolid(destX, destY))
- return false;
-
- if (actor->spriteDrawn)
- releaseAnim(actor);
- else
- _gfx->addSprite(&actor->sprite);
-
- actor->spriteDrawn = true;
- actor->animType = 1;
- actor->frameToStartNextAnim = _frameIndex + 1;
- strcpy(actor->animationString2, animFile.c_str());
-
- actor->dest.x = destX;
- actor->dest.y = destY;
- actor->field92 = 0;
- actor->triggerActionWhenAnimFinished = false;
-
- actor->iwDestPosition = -1;
- actor->iwSrcPosition = -1;
-
- if (directPathExists(srcX, srcY, destX, destY)) {
- chooseActorDirectionForWalking(actor, srcX, srcY, destX, destY);
- updateActorPositionWhileWalking(actor, (actor->granularPosX + 0.5).toInt(), (actor->granularPosY + 0.5).toInt());
- return true;
- } else {
- actor->iwSrcPosition = _iwFile->getClosestKeyPosition(srcX, srcY);
- actor->iwDestPosition = _iwFile->getClosestKeyPosition(destX, destY);
-
- if (actor->iwSrcPosition == -1 || actor->iwDestPosition == -1) {
- // No path exists; face south by default.
- strcat(actor->animationString2, "S");
- actor->direction = 'S';
-
- updateActorPositionWhileWalking(actor, srcX, srcY);
- initStandAnim(actorIndex);
-
- return false;
- } else {
- Common::Point iwSrc = _iwFile->_keyPositions[actor->iwSrcPosition];
- chooseActorDirectionForWalking(actor, srcX, srcY, iwSrc.x, iwSrc.y);
- updateActorPositionWhileWalking(actor, (actor->granularPosX + 0.5).toInt(), (actor->granularPosY + 0.5).toInt());
- return true;
- }
- }
-}
-
-void StarTrekEngine::updateActorAnimations() {
- for (int i = 0; i < NUM_ACTORS; i++) {
- Actor *actor = &_actorList[i];
- if (!actor->spriteDrawn)
- continue;
-
- switch (actor->animType) {
- case 0: // Not walking?
- case 2:
- if (_frameIndex >= actor->frameToStartNextAnim) {
- int nextAnimIndex = getRandomWord() & 3;
- actor->animFile->seek(18 + nextAnimIndex + actor->animFrame * 22, SEEK_SET);
- byte nextAnimFrame = actor->animFile->readByte();
-
- if (actor->animFrame != nextAnimFrame) {
- if (nextAnimFrame == actor->numAnimFrames - 1) {
- actor->field62++;
- if (actor->triggerActionWhenAnimFinished) {
- addAction(ACTION_FINISHED_ANIMATION, actor->finishedAnimActionParam, 0, 0);
- }
- }
- }
-
- actor->animFrame = nextAnimFrame;
- if (actor->animFrame >= actor->numAnimFrames) {
- if (actor->animationString[0] == '\0')
- removeActorFromScreen(i);
- else
- initStandAnim(i);
- } else {
- Sprite *sprite = &actor->sprite;
-
- actor->animFile->seek(actor->animFrame * 22, SEEK_SET);
- char animFrameFilename[16];
- actor->animFile->read(animFrameFilename, 16);
- sprite->setBitmap(loadAnimationFrame(animFrameFilename, actor->scale));
-
- memset(actor->bitmapFilename, 0, 10);
- strncpy(actor->bitmapFilename, animFrameFilename, 9);
-
- actor->animFile->seek(10 + actor->animFrame * 22, SEEK_SET);
- uint16 xOffset = actor->animFile->readUint16();
- uint16 yOffset = actor->animFile->readUint16();
- uint16 basePriority = actor->animFile->readUint16();
- uint16 frames = actor->animFile->readUint16();
-
- sprite->pos.x = xOffset + actor->pos.x;
- sprite->pos.y = yOffset + actor->pos.y;
- sprite->drawPriority = _gfx->getPriValue(0, yOffset + actor->pos.y) + basePriority;
- sprite->bitmapChanged = true;
-
- actor->frameToStartNextAnim = frames + _frameIndex;
- }
- }
- break;
- case 1: // Walking
- if (_frameIndex < actor->frameToStartNextAnim)
- break;
- if (i == 0) // Kirk only
- checkTouchedLoadingZone(actor->pos.x, actor->pos.y);
- if (actor->field90 != 0) {
- Sprite *sprite = &actor->sprite;
- int loops;
- if (getActorScaleAtPosition((actor->granularPosY + 0.5).toInt()) < 0.625)
- loops = 1;
- else
- loops = 2;
- for (int k = 0; k < loops; k++) {
- if (actor->field90 == 0)
- break;
- actor->field90--;
- Fixed16 newX = actor->granularPosX + actor->speedX;
- Fixed16 newY = actor->granularPosY + actor->speedY;
- if ((actor->field90 & 3) == 0) {
- sprite->bitmap.reset();
- updateActorPositionWhileWalking(actor, (newX + 0.5).toInt(), (newY + 0.5).toInt());
- actor->field92++;
- }
-
- actor->granularPosX = newX;
- actor->granularPosY = newY;
- actor->frameToStartNextAnim = _frameIndex;
- }
- } else { // actor->field90 == 0
- if (actor->iwSrcPosition == -1) {
- if (actor->triggerActionWhenAnimFinished) {
- actor->triggerActionWhenAnimFinished = false;
- addAction(ACTION_FINISHED_WALKING, actor->finishedAnimActionParam & 0xff, 0, 0);
- }
-
- actor->sprite.bitmap.reset();
- updateActorPositionWhileWalking(actor, (actor->granularPosX + 0.5).toInt(), (actor->granularPosY + 0.5).toInt());
- initStandAnim(i);
- } else { // actor->iwSrcPosition != -1
- if (actor->iwSrcPosition == actor->iwDestPosition) {
- actor->animationString2[strlen(actor->animationString2) - 1] = '\0';
- actor->iwDestPosition = -1;
- actor->iwSrcPosition = -1;
- chooseActorDirectionForWalking(actor, actor->pos.x, actor->pos.y, actor->dest.x, actor->dest.y);
- } else {
- int index = _iwFile->_iwEntries[actor->iwSrcPosition][actor->iwDestPosition];
- actor->iwSrcPosition = index;
- Common::Point dest = _iwFile->_keyPositions[actor->iwSrcPosition];
- actor->animationString2[strlen(actor->animationString2) - 1] = '\0';
- chooseActorDirectionForWalking(actor, actor->pos.x, actor->pos.y, dest.x, dest.y);
- }
- }
- }
- break;
- default:
- error("Invalid anim type.");
- break;
- }
- }
-}
-
-void StarTrekEngine::renderBanBelowSprites() {
- if ((_frameIndex & 3) != 0)
- return;
-
- byte *screenPixels = _gfx->lockScreenPixels();
- byte *bgPixels = _gfx->getBackgroundPixels();
-
- for (int i = 0; i < MAX_BAN_FILES; i++) {
- if (!_banFiles[i])
- continue;
-
- // TODO: video modes other than VGA
-
- _banFiles[i]->seek(_banFileOffsets[i], SEEK_SET);
- uint16 offset = _banFiles[i]->readUint16();
-
- if (offset == 0xffff) {
- _banFileOffsets[i] = 0;
- _banFiles[i]->seek(0, SEEK_SET);
- offset = _banFiles[i]->readSint16();
- }
-
- int16 size = _banFiles[i]->readSint16();
- if (size != 0) {
- _banFiles[i]->seek(_banFileOffsets[i], SEEK_SET);
- renderBan(screenPixels, _banFiles[i]);
-
- _banFiles[i]->seek(_banFileOffsets[i], SEEK_SET);
- renderBan(bgPixels, _banFiles[i]);
- //sub_10e51(_gfx->getBackgroundPixels(), _banFiles[i]);
- }
-
- }
-
- _gfx->unlockScreenPixels();
-}
-
-void StarTrekEngine::renderBan(byte *destPixels, SharedPtr<FileStream> banFile) {
- uint16 offset = banFile->readUint16();
- int32 size = banFile->readUint16();
-
- byte *dest = destPixels + offset;
-
- // Skip 8 bytes (rectangle encompassing the area being drawn to)
- banFile->readSint32();
- banFile->readSint32();
-
- while (--size >= 0) {
- assert(dest >= destPixels && dest < destPixels + SCREEN_WIDTH * SCREEN_HEIGHT);
- int8 b = banFile->readByte();
-
- if (b == -128) // Add value to destination (usually jumping to next row)
- dest += banFile->readUint16();
- else if (b < 0) { // Repeated byte
- byte c = banFile->readByte();
- if (c == 0)
- dest += (-b) + 1;
- else {
- for (int j = 0; j < (-b) + 1; j++)
- (*dest++) = c;
- }
- } else { // List of bytes
- b++;
- while (b-- != 0) {
- byte c = banFile->readByte();
- if (c == 0)
- dest++;
- else
- *(dest++) = c;
- }
- }
- }
-}
-
-void StarTrekEngine::renderBanAboveSprites() {
- if ((_frameIndex & 3) != 0)
- return;
-
- for (int i = 0; i < MAX_BAN_FILES; i++) {
- if (!_banFiles[i])
- continue;
-
- _banFiles[i]->seek(_banFileOffsets[i], SEEK_SET);
- uint16 offset = _banFiles[i]->readUint16();
-
- if (offset == 0xffff) {
- _banFileOffsets[i] = 0;
- _banFiles[i]->seek(0, SEEK_SET);
- offset = _banFiles[i]->readSint16();
- }
-
- int16 size = _banFiles[i]->readSint16();
- if (size != 0) {
- Common::Rect rect;
- rect.left = _banFiles[i]->readSint16();
- rect.top = _banFiles[i]->readSint16();
- rect.right = _banFiles[i]->readSint16() + 1;
- rect.bottom = _banFiles[i]->readSint16() + 1;
-
- // Draw all sprites in this rectangle to a custom surface, and only update the
- // specific pixels that were updated by the BAN file this frame.
- // Rationale behind this is that, since the background may not have been
- // redrawn, the transparent sprites (ie. textboxes) would further darken any
- // pixels behind them that haven't been updated this frame. So, we can't just
- // update everything in this rectangle.
- // FIXME: This copies the entire screen surface for temporary drawing, which
- // is somewhat wasteful. Original game had one more graphics layer it drew to
- // before the screen was updated...
- ::Graphics::Surface surface;
- _gfx->drawAllSpritesInRectToSurface(rect, &surface);
-
- byte *destPixels = _gfx->lockScreenPixels();
- byte *src = (byte *)surface.getPixels() + offset;
- byte *dest = destPixels + offset;
-
- // This is similar to renderBan(), except it copies pixels from the surface
- // above instead of drawing directly to it. (Important since sprites may be
- // drawn on top.)
- while (--size >= 0) {
- assert(dest >= destPixels && dest < destPixels + SCREEN_WIDTH * SCREEN_HEIGHT);
- int8 b = _banFiles[i]->readByte();
- if (b == -128) {
- uint16 skip = _banFiles[i]->readUint16();
- dest += skip;
- src += skip;
- } else if (b < 0) {
- byte c = _banFiles[i]->readByte();
- if (c == 0) {
- dest += (-b) + 1;
- src += (-b) + 1;
- }
- else {
- for (int j = 0; j < (-b) + 1; j++)
- *(dest++) = *(src++);
- }
- } else {
- b++;
- while (b-- != 0) {
- byte c = _banFiles[i]->readByte();
- if (c == 0) {
- dest++;
- src++;
- } else
- *(dest++) = *(src++);
- }
- }
- }
-
- _gfx->unlockScreenPixels();
- surface.free();
-
- _banFileOffsets[i] = _banFiles[i]->pos();
- }
- }
-}
-
-void StarTrekEngine::removeActorFromScreen(int actorIndex) {
- Actor *actor = &_actorList[actorIndex];
-
- if (actor->spriteDrawn != 1)
- return;
-
- debugC(6, kDebugGraphics, "Stop drawing actor %d", actorIndex);
-
- Sprite *sprite = &actor->sprite;
- sprite->field16 = true;
- sprite->bitmapChanged = true;
- _gfx->drawAllSprites();
- _gfx->delSprite(sprite);
- releaseAnim(actor);
-}
-
-void StarTrekEngine::actorFunc1() {
- for (int i = 0; i < NUM_ACTORS; i++) {
- if (_actorList[i].spriteDrawn == 1) {
- removeActorFromScreen(i);
- }
- }
-
- for (int i = 0; i < MAX_BAN_FILES; i++) {
- _banFiles[i].reset();
- }
-}
-
-void StarTrekEngine::drawActorToScreen(Actor *actor, const Common::String &_animName, int16 x, int16 y, Fixed8 scale, bool addSprite) {
- Common::String animFilename = _animName;
- if (_animName.hasPrefixIgnoreCase("stnd") /* && word_45d20 == -1 */) // TODO
- animFilename += 'j';
- memcpy(actor->animFilename, _animName.c_str(), sizeof(actor->animFilename));
-
- actor->animType = 2;
- actor->animFile = loadFile(animFilename + ".anm");
- actor->numAnimFrames = actor->animFile->size() / 22;
- actor->animFrame = 0;
- actor->pos.x = x;
- actor->pos.y = y;
- actor->field62 = 0;
- actor->scale = scale;
-
- actor->animFile->seek(16, SEEK_SET);
- actor->frameToStartNextAnim = actor->animFile->readUint16() + _frameIndex;
-
- char firstFrameFilename[11];
- actor->animFile->seek(0, SEEK_SET);
- actor->animFile->read(firstFrameFilename, 10);
- firstFrameFilename[10] = '\0';
-
- Sprite *sprite = &actor->sprite;
- if (addSprite)
- _gfx->addSprite(sprite);
-
- sprite->setBitmap(loadAnimationFrame(firstFrameFilename, scale));
- memset(actor->bitmapFilename, 0, sizeof(char) * 10);
- strncpy(actor->bitmapFilename, firstFrameFilename, sizeof(char) * 9);
-
- actor->scale = scale;
-
- actor->animFile->seek(10, SEEK_SET);
- uint16 xOffset = actor->animFile->readUint16();
- uint16 yOffset = actor->animFile->readUint16();
- uint16 basePriority = actor->animFile->readUint16();
-
- sprite->pos.x = xOffset + actor->pos.x;
- sprite->pos.y = yOffset + actor->pos.y;
- sprite->drawPriority = _gfx->getPriValue(0, yOffset + actor->pos.y) + basePriority;
- sprite->bitmapChanged = true;
-
- actor->spriteDrawn = 1;
-}
-
-void StarTrekEngine::releaseAnim(Actor *actor) {
- switch (actor->animType) {
- case 0:
- case 2:
- actor->sprite.bitmap.reset();
- actor->animFile.reset();
- break;
- case 1:
- actor->sprite.bitmap.reset();
- break;
- default:
- error("Invalid anim type");
- break;
- }
-
- actor->spriteDrawn = 0;
-}
-
-void StarTrekEngine::initStandAnim(int actorIndex) {
- Actor *actor = &_actorList[actorIndex];
-
- if (!actor->spriteDrawn)
- error("initStandAnim: dead anim");
-
- ////////////////////
- // sub_239d2
- const char *directions = "nsew";
-
- if (actorIndex >= 0 && actorIndex <= 3) {
- int8 dir = _awayMission.crewDirectionsAfterWalk[actorIndex];
- if (dir != -1) {
- actor->direction = directions[dir];
- _awayMission.crewDirectionsAfterWalk[actorIndex] = -1;
- }
- }
- // end of sub_239d2
- ////////////////////
-
- Common::String animName;
- if (actor->direction != 0)
- animName = Common::String(actor->animationString) + (char)actor->direction;
- else // Default to facing south
- animName = Common::String(actor->animationString) + 's';
-
- Fixed8 scale = getActorScaleAtPosition(actor->pos.y);
- loadActorAnim(actorIndex, animName, actor->pos.x, actor->pos.y, scale);
- actor->animType = 0;
-}
-
-void StarTrekEngine::updateActorPositionWhileWalking(Actor *actor, int16 x, int16 y) {
- actor->scale = getActorScaleAtPosition(y);
- Common::String animName = Common::String::format("%s%02d", actor->animationString2, actor->field92 & 7);
- actor->sprite.setBitmap(loadAnimationFrame(animName, actor->scale));
-
- memset(actor->bitmapFilename, 0, 10);
- strncpy(actor->bitmapFilename, animName.c_str(), 9);
-
- Sprite *sprite = &actor->sprite;
- sprite->drawPriority = _gfx->getPriValue(0, y);
- sprite->pos.x = x;
- sprite->pos.y = y;
- sprite->bitmapChanged = true;
-
- actor->frameToStartNextAnim = _frameIndex;
- actor->pos.x = x;
- actor->pos.y = y;
-}
-
-void StarTrekEngine::chooseActorDirectionForWalking(Actor *actor, int16 srcX, int16 srcY, int16 destX, int16 destY) {
- actor->granularPosX = srcX;
- actor->granularPosY = srcY;
-
- 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
- actor->animationString2[strlen(actor->animationString2) + 1] = '\0';
- actor->animationString2[strlen(actor->animationString2)] = d;
-
- actor->direction = d;
- actor->field90 = absDistX;
-
- if (distX != 0) {
- if (distX > 0)
- actor->speedX = 1.0;
- else
- actor->speedX = -1.0;
-
- actor->speedY = Fixed16(distY) / absDistX;
- }
- } else {
- char d;
- if (distY > 0)
- d = 'S';
- else
- d = 'N';
-
- // Append direction to animation string
- actor->animationString2[strlen(actor->animationString2) + 1] = '\0';
- actor->animationString2[strlen(actor->animationString2)] = d;
-
- actor->direction = d;
- actor->field90 = absDistY;
-
- if (distY != 0) {
- if (distY > 0)
- actor->speedY = 1.0;
- else
- actor->speedY = -1.0;
-
- actor->speedX = Fixed16(distX) / absDistY;
- }
- }
-}
-
-bool StarTrekEngine::directPathExists(int16 srcX, int16 srcY, int16 destX, int16 destY) {
- int32 distX = destX - srcX;
- int32 distY = destY - srcY;
-
- int32 absDistX = abs(distX);
- int32 absDistY = abs(distY);
-
- int32 distCounter;
- Fixed16 speedX, speedY;
-
- if (absDistX > absDistY) {
- distCounter = absDistX;
-
- if (distCounter == 0)
- return true;
-
- speedY = Fixed16(distY) / absDistX;
-
- if (distX > 0)
- speedX = 1.0;
- else
- speedX = -1.0;
- } else { // absDistX <= absDistY
- distCounter = absDistY;
-
- if (distCounter == 0)
- return true;
-
- speedX = Fixed16(distX) / absDistY;
-
- if (distY > 0)
- speedY = 1.0;
- else
- speedY = -1.0;
- }
-
- Fixed16 fixedX = srcX;
- Fixed16 fixedY = srcY;
-
- if (isPositionSolid((fixedX + 0.5).toInt(), (fixedY + 0.5).toInt()))
- return false;
-
- while (distCounter-- > 0) {
- fixedX += speedX;
- fixedY += speedY;
-
- if (isPositionSolid((fixedX + 0.5).toInt(), (fixedY + 0.5).toInt()))
- return false;
- }
-
- return true;
-}
-
-int StarTrekEngine::findObjectAt(int x, int y) {
- Sprite *sprite = _gfx->getSpriteAt(x, y);
-
- if (sprite != nullptr) {
- if (sprite == &_inventoryIconSprite)
- return OBJECT_INVENTORY_ICON;
- else if (sprite == &_itemIconSprite)
- return _awayMission.activeObject;
-
- for (int i = 0; i < NUM_ACTORS; i++) {
- Actor *actor = &_actorList[i];
- if (sprite == &actor->sprite)
- return i;
- }
-
- error("findObject: Clicked on an unknown sprite");
- }
-
- _objectHasWalkPosition = false;
- int actionBit = 1 << (_awayMission.activeAction - 1);
- int offset = _room->getFirstHotspot();
-
- while (offset != _room->getHotspotEnd()) {
- uint16 word = _room->readRdfWord(offset);
- if (word & 0x8000) {
- if ((word & actionBit) && isPointInPolygon((int16 *)(_room->_rdfData + offset + 6), x, y)) {
- int actorIndex = _room->readRdfWord(offset + 6);
- _objectHasWalkPosition = true;
- _objectWalkPosition.x = _room->readRdfWord(offset + 2);
- _objectWalkPosition.y = _room->readRdfWord(offset + 4);
- return actorIndex;
- }
-
- int numVertices = _room->readRdfWord(offset + 8);
- offset = offset + 10 + numVertices * 4;
- } else {
- if (isPointInPolygon((int16 *)(_room->_rdfData + offset), x, y)) {
- int actorIndex = _room->readRdfWord(offset);
- return actorIndex;
- }
-
- int numVertices = _room->readRdfWord(offset + 2);
- offset = offset + 4 + numVertices * 4;
- }
- }
-
- return -1;
-}
-
-SharedPtr<Bitmap> StarTrekEngine::loadAnimationFrame(const Common::String &filename, Fixed8 scale) {
- SharedPtr<Bitmap> bitmapToReturn;
-
- char basename[5];
- strncpy(basename, filename.c_str() + 1, 4);
- basename[4] = '\0';
-
- char c = filename[0];
- if ((strcmp(basename, "stnd") == 0 || strcmp(basename, "tele") == 0)
- && (c == 'm' || c == 's' || c == 'k' || c == 'r')) {
- if (c == 'm') {
- // Mccoy has the "base" animations for all crewmen
- bitmapToReturn = _gfx->loadBitmap(filename);
- } else {
- // All crewman other than mccoy copy the animation frames from mccoy, change
- // the colors of the uniforms, and load an "xor" file to redraw the face.
-
- // TODO: The ".$bm" extension is a "virtual file"? Caches the changes to the
- // file made here?
- // bitmapToReturn = _gfx->loadBitmap(filename + ".$bm");
-
- if (bitmapToReturn == nullptr) {
- Common::String mccoyFilename = filename;
- mccoyFilename.setChar('m', 0);
- SharedPtr<Bitmap> bitmap = _gfx->loadBitmap(mccoyFilename);
-
- uint16 width = bitmap->width;
- uint16 height = bitmap->height;
-
- bitmapToReturn = SharedPtr<Bitmap>(new Bitmap(width, height));
- bitmapToReturn->xoffset = bitmap->xoffset;
- bitmapToReturn->yoffset = bitmap->yoffset;
-
- // Change uniform color
- int16 colorShift;
- switch (c) {
- case 'k': // Kirk
- colorShift = 8;
- break;
- case 'r': // Redshirt
- colorShift = -8;
- break;
- case 's': // Spock
- colorShift = 0;
- break;
- }
-
- if (colorShift == 0) {
- memcpy(bitmapToReturn->pixels, bitmap->pixels, width * height);
- } else {
- byte *src = bitmap->pixels;
- byte *dest = bitmapToReturn->pixels;
- byte baseUniformColor = 0xa8;
-
- for (int i = 0; i < width * height; i++) {
- byte b = *src++;
- if (b >= baseUniformColor && b < baseUniformColor + 8)
- *dest++ = b + colorShift;
- else
- *dest++ = b;
- }
- }
-
- // Redraw face with xor file
- SharedPtr<FileStream> xorFile = loadFile(filename + ".xor");
- xorFile->seek(0, SEEK_SET);
- uint16 xoffset = bitmap->xoffset - xorFile->readUint16();
- uint16 yoffset = bitmap->yoffset - xorFile->readUint16();
- uint16 xorWidth = xorFile->readUint16();
- uint16 xorHeight = xorFile->readUint16();
-
- byte *dest = bitmapToReturn->pixels + yoffset * bitmap->width + xoffset;
-
- for (int i = 0; i < xorHeight; i++) {
- for (int j = 0; j < xorWidth; j++)
- *dest++ ^= xorFile->readByte();
- dest += (bitmap->width - xorWidth);
- }
- }
- }
- } else {
- // TODO: when loading a bitmap, it passes a different argument than is standard to
- // the "file loading with cache" function...
- bitmapToReturn = _gfx->loadBitmap(filename);
- }
-
- if (scale != 1.0) {
- bitmapToReturn = scaleBitmap(bitmapToReturn, scale);
- }
-
- return bitmapToReturn;
-}
-
-
-int StarTrekEngine::selectObjectForUseAction() {
- while (true) {
- if (!(_awayMission.crewDownBitset & (1 << OBJECT_KIRK)))
- showInventoryIcons(false);
-
- TrekEvent event;
-
- while (true) {
- if (!getNextEvent(&event))
- continue;
-
- if (event.type == TREKEVENT_TICK) {
- updateMouseBitmap();
- _gfx->drawAllSprites();
- _sound->checkLoopMusic();
- } else if (event.type == TREKEVENT_LBUTTONDOWN) {
- removeNextEvent();
- break;
- } else if (event.type == TREKEVENT_MOUSEMOVE) {
- } else if (event.type == TREKEVENT_RBUTTONDOWN) {
- // Allow this to be processed by main away mission loop
- break;
- } else if (event.type == TREKEVENT_KEYDOWN) {
- if (event.kbd.keycode == Common::KEYCODE_ESCAPE
- || event.kbd.keycode == Common::KEYCODE_w
- || event.kbd.keycode == Common::KEYCODE_t
- || event.kbd.keycode == Common::KEYCODE_u
- || event.kbd.keycode == Common::KEYCODE_g
- || event.kbd.keycode == Common::KEYCODE_l
- || event.kbd.keycode == Common::KEYCODE_SPACE
- || event.kbd.keycode == Common::KEYCODE_F2) {
- // Allow these buttons to be processed by main away mission loop
- break;
- } else if (event.kbd.keycode == Common::KEYCODE_i) {
- removeNextEvent();
- break;
- } else if (event.kbd.keycode == Common::KEYCODE_RETURN || event.kbd.keycode == Common::KEYCODE_KP_ENTER || event.kbd.keycode == Common::KEYCODE_F1) {
- // Simulate left-click
- removeNextEvent();
- event.type = TREKEVENT_LBUTTONDOWN;
- break;
- }
- }
-
- removeNextEvent();
- }
-
- if (event.type == TREKEVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_i) {
- hideInventoryIcons();
- int clickedObject = showInventoryMenu(50, 50, true);
- if (clickedObject == -1)
- continue;
- return clickedObject;
- } else if (event.type == TREKEVENT_LBUTTONDOWN) {
- int clickedObject = findObjectAt(_gfx->getMousePos());
- hideInventoryIcons();
-
- if (clickedObject == -1)
- continue;
- else if (isObjectUnusable(clickedObject, ACTION_USE))
- continue;
- else if (clickedObject == OBJECT_INVENTORY_ICON) {
- clickedObject = showInventoryMenu(50, 50, false);
- if (clickedObject == -1)
- continue;
- else
- return clickedObject;
- } else if (clickedObject <= OBJECT_REDSHIRT)
- return clickedObject;
- else if (isObjectUnusable(OBJECT_KIRK, ACTION_USE))
- continue;
- else if (_room->actionHasCode(ACTION_USE, OBJECT_KIRK, clickedObject, 0)
- || _room->actionHasCode(ACTION_GET, clickedObject, 0, 0)
- || _room->actionHasCode(ACTION_WALK, clickedObject, 0, 0)) {
- _awayMission.activeObject = OBJECT_KIRK;
- _awayMission.passiveObject = clickedObject;
- _awayMission.activeAction = ACTION_USE;
- clickedObject = OBJECT_KIRK;
- if (!walkActiveObjectToHotspot())
- addAction(_awayMission.activeAction, _awayMission.activeObject, _awayMission.passiveObject, 0);
- return clickedObject;
- } else
- continue;
- } else {
- hideInventoryIcons();
- return -1;
- }
- }
-}
-
-Common::String StarTrekEngine::getCrewmanAnimFilename(int actorIndex, const Common::String &basename) {
- const char *crewmanChars = "ksmr";
- assert(actorIndex >= 0 && actorIndex < 4);
- return crewmanChars[actorIndex] + basename;
-}
-
-void StarTrekEngine::updateMouseBitmap() {
- const bool worksOnCrewmen[] = { // True if the action reacts with crewmen
- false, // ACTION_WALK
- true, // ACTION_USE
- false, // ACTION_GET
- true, // ACTION_LOOK
- true // ACTION_TALK
- };
- const bool worksOnActors[] = { // True if the action reacts with other objects
- false, // ACTION_WALK
- true, // ACTION_USE
- true, // ACTION_GET
- true, // ACTION_LOOK
- true // ACTION_TALK
- };
- const bool worksOnHotspots[] = { // True if the action reacts with hotspots
- false, // ACTION_WALK
- true, // ACTION_USE
- true, // ACTION_GET
- true, // ACTION_LOOK
- false // ACTION_TALK
- };
-
- Common::Point mousePos = _gfx->getMousePos();
- int selected = findObjectAt(mousePos.x, mousePos.y);
- int action = _awayMission.activeAction;
- assert(action >= 1 && action <= 5);
-
- bool withRedOutline;
-
- if (selected >= 0 && selected <= 3 && worksOnCrewmen[action - 1])
- withRedOutline = true;
- else if (selected > 3 && selected < NUM_ACTORS && worksOnActors[action - 1])
- withRedOutline = true;
- else if (selected >= NUM_ACTORS && selected < HOTSPOTS_END && worksOnHotspots[action - 1])
- withRedOutline = true;
- else
- withRedOutline = false;
-
- chooseMouseBitmapForAction(action, withRedOutline);
-}
-
-bool StarTrekEngine::walkActiveObjectToHotspot() {
- if (!_objectHasWalkPosition)
- return false;
-
- int objectIndex;
- if (_awayMission.activeAction != ACTION_USE)
- objectIndex = OBJECT_KIRK;
- else if (_awayMission.activeObject <= OBJECT_REDSHIRT)
- objectIndex = _awayMission.activeObject;
- else if (_awayMission.activeObject >= ITEMS_START && _awayMission.activeObject <= ITEMS_END) { // FIXME: "<= ITEMS_END" doesn't make sense?
- if (_awayMission.activeObject == OBJECT_ISTRICOR)
- objectIndex = OBJECT_SPOCK;
- else if (_awayMission.activeObject == OBJECT_IMTRICOR)
- objectIndex = OBJECT_MCCOY;
- else
- objectIndex = OBJECT_KIRK;
- } else // This is the original error message...
- error("Jay didn't think about pmcheck");
-
- byte finishedAnimActionParam = false;
- bool walk = false;
-
- if (_awayMission.activeAction == ACTION_WALK)
- walk = true;
- else {
- // If this action has code defined for it in this room, buffer the action to be
- // done after the object finished walking there.
- Action action = {_awayMission.activeAction, _awayMission.activeObject, 0, 0};
- if (_awayMission.activeAction == ACTION_USE)
- action.b2 = _awayMission.passiveObject;
-
- if (_room->actionHasCode(action)) {
- for (int i = 0; i < MAX_BUFFERED_WALK_ACTIONS; i++) {
- if (!_actionOnWalkCompletionInUse[i]) {
- finishedAnimActionParam = i + 0xe0;
- _actionOnWalkCompletionInUse[i] = true;
- _actionOnWalkCompletion[i] = action;
- walk = true;
- break;
- }
- }
- }
- }
-
- if (walk) {
- Actor *actor = &_actorList[objectIndex];
- Common::String anim = getCrewmanAnimFilename(objectIndex, "walk");
- actorWalkToPosition(objectIndex, anim, actor->pos.x, actor->pos.y, _objectWalkPosition.x, _objectWalkPosition.y);
- if (finishedAnimActionParam != 0) {
- actor->triggerActionWhenAnimFinished = true;
- actor->finishedAnimActionParam = finishedAnimActionParam;
- }
- _objectHasWalkPosition = false;
- return true;
- } else {
- _objectHasWalkPosition = false;
- return false;
- }
-}
-
-void StarTrekEngine::showInventoryIcons(bool showItem) {
- const char *crewmanFilenames[] = {
- "ikirk",
- "ispock",
- "imccoy",
- "iredshir"
- };
-
- Common::String itemFilename;
-
- if (showItem) {
- int i = _awayMission.activeObject;
- if (i >= OBJECT_KIRK && i <= OBJECT_REDSHIRT)
- itemFilename = crewmanFilenames[i];
- else {
- assert(i >= ITEMS_START && i < ITEMS_END);
- Item *item = &_itemList[i - ITEMS_START];
- itemFilename = item->name;
- }
- }
-
- if (itemFilename.empty())
- _inventoryIconSprite.pos.x = 10;
- else {
- _gfx->addSprite(&_itemIconSprite);
- _itemIconSprite.drawMode = 2;
- _itemIconSprite.pos.x = 10;
- _itemIconSprite.pos.y = 10;
- _itemIconSprite.drawPriority = 15;
- _itemIconSprite.drawPriority2 = 8;
- _itemIconSprite.setBitmap(_gfx->loadBitmap(itemFilename));
-
- _inventoryIconSprite.pos.x = 46;
- }
-
- _gfx->addSprite(&_inventoryIconSprite);
-
- _inventoryIconSprite.pos.y = 10;
- _inventoryIconSprite.drawMode = 2;
- _inventoryIconSprite.drawPriority = 15;
- _inventoryIconSprite.drawPriority2 = 8;
- _inventoryIconSprite.setBitmap(_gfx->loadBitmap("inv00"));
-}
-
-bool StarTrekEngine::isObjectUnusable(int object, int action) {
- if (action == ACTION_LOOK)
- return false;
- if (object == OBJECT_REDSHIRT && _awayMission.redshirtDead)
- return true;
- if (object >= OBJECT_KIRK && object <= OBJECT_REDSHIRT && (_awayMission.crewDownBitset & (1 << object)))
- return true;
- if (object == OBJECT_IMTRICOR && (_awayMission.crewDownBitset & (1 << OBJECT_MCCOY)))
- return true;
- if (object == OBJECT_ISTRICOR && (_awayMission.crewDownBitset & (1 << OBJECT_SPOCK)))
- return true;
- return false;
-}
-
-void StarTrekEngine::hideInventoryIcons() {
- // Clear these sprites from the screen
- if (_itemIconSprite.drawMode == 2)
- _itemIconSprite.dontDrawNextFrame();
- if (_inventoryIconSprite.drawMode == 2)
- _inventoryIconSprite.dontDrawNextFrame();
-
- _gfx->drawAllSprites();
-
- if (_itemIconSprite.drawMode == 2) {
- _gfx->delSprite(&_itemIconSprite);
- _itemIconSprite.drawMode = 0;
- _itemIconSprite.bitmap.reset();
- }
-
- if (_inventoryIconSprite.drawMode == 2) {
- _gfx->delSprite(&_inventoryIconSprite);
- _inventoryIconSprite.drawMode = 0;
- _inventoryIconSprite.bitmap.reset();
- }
-}
-
-void StarTrekEngine::updateCrewmanGetupTimers() {
- if (_awayMission.crewDownBitset == 0)
- return;
- for (int i = OBJECT_KIRK; i <= OBJECT_REDSHIRT; i++) {
- Actor *actor = &_actorList[i];
-
- if (!(_awayMission.crewDownBitset & (1 << i)))
- continue;
-
- _awayMission.crewGetupTimers[i]--;
- if (_awayMission.crewGetupTimers[i] <= 0) {
- Common::String anim = getCrewmanAnimFilename(i, "getu");
- int8 dir = _awayMission.crewDirectionsAfterWalk[i];
- char d;
- if (dir == -1) {
- d = actor->direction;
- } else {
- const char *dirs = "nsew";
- Fixed8 scale = getActorScaleAtPosition(actor->sprite.pos.y);
- d = dirs[dir];
-
- int16 xOffset = 0, yOffset = 0;
- if (d == 'n') {
- xOffset = -24;
- yOffset = -8;
- } else if (d == 'w') {
- xOffset = -35;
- yOffset = -12;
- }
- actor->sprite.pos.x += scale.multToInt(xOffset);
- actor->sprite.pos.y += scale.multToInt(yOffset);
- }
-
- anim += (char)d;
- loadActorAnimWithRoomScaling(i, anim, actor->sprite.pos.x, actor->sprite.pos.y);
- _awayMission.crewDownBitset &= ~(1 << i);
- }
- }
-}
-
-int StarTrekEngine::showInventoryMenu(int x, int y, bool restoreMouse) {
- const int ITEMS_PER_ROW = 5;
-
- Common::Point oldMousePos = _gfx->getMousePos();
- bool keyboardControlledMouse = _keyboardControlsMouse;
- _keyboardControlsMouse = false;
-
- int itemIndex = 0;
- int numItems = 0;
-
- char itemNames[NUM_OBJECTS][10];
- Common::Point itemPositions[NUM_OBJECTS];
- int16 itemIndices[NUM_OBJECTS];
-
- while (itemIndex < NUM_OBJECTS) {
- if (_itemList[itemIndex].have) {
- strcpy(itemNames[numItems], _itemList[itemIndex].name);
-
- int16 itemX = (numItems % ITEMS_PER_ROW) * 32 + x;
- int16 itemY = (numItems / ITEMS_PER_ROW) * 32 + y;
- itemPositions[numItems] = Common::Point(itemX, itemY);
- itemIndices[numItems] = _itemList[itemIndex].field2;
-
- numItems++;
- }
- itemIndex++;
- }
-
- Sprite itemSprites[NUM_OBJECTS];
-
- for (int i = 0; i < numItems; i++) {
- _gfx->addSprite(&itemSprites[i]);
-
- itemSprites[i].drawMode = 2;
- itemSprites[i].pos.x = itemPositions[i].x;
- itemSprites[i].pos.y = itemPositions[i].y;
- itemSprites[i].drawPriority = 15;
- itemSprites[i].drawPriority2 = 8;
- itemSprites[i].setBitmap(_gfx->loadBitmap(itemNames[i]));
- }
-
- chooseMousePositionFromSprites(itemSprites, numItems, -1, 4);
- bool displayMenu = true;
- int lastItemIndex = -1;
-
- while (displayMenu) {
- _sound->checkLoopMusic();
-
- TrekEvent event;
- if (!getNextEvent(&event))
- continue;
-
- switch (event.type) {
- case TREKEVENT_TICK: {
- Common::Point mousePos = _gfx->getMousePos();
- itemIndex = getMenuButtonAt(itemSprites, numItems, mousePos.x, mousePos.y);
- if (itemIndex != lastItemIndex) {
- if (lastItemIndex != -1) {
- drawMenuButtonOutline(itemSprites[lastItemIndex].bitmap, 0);
- itemSprites[lastItemIndex].bitmapChanged = true;
- }
- if (itemIndex != -1) {
- drawMenuButtonOutline(itemSprites[itemIndex].bitmap, 15);
- itemSprites[itemIndex].bitmapChanged = true;
- }
- lastItemIndex = itemIndex;
- }
- _gfx->drawAllSprites();
- break;
- }
-
- case TREKEVENT_LBUTTONDOWN:
-exitWithSelection:
- displayMenu = false;
- break;
-
- case TREKEVENT_RBUTTONDOWN:
-exitWithoutSelection:
- displayMenu = false;
- lastItemIndex = -1;
- break;
-
- case TREKEVENT_KEYDOWN:
- switch (event.kbd.keycode) {
- case Common::KEYCODE_ESCAPE:
- case Common::KEYCODE_F2:
- goto exitWithoutSelection;
-
- case Common::KEYCODE_RETURN:
- case Common::KEYCODE_KP_ENTER:
- case Common::KEYCODE_F1:
- goto exitWithSelection;
-
- case Common::KEYCODE_HOME:
- case Common::KEYCODE_KP7:
- chooseMousePositionFromSprites(itemSprites, numItems, lastItemIndex, 4);
- break;
-
- case Common::KEYCODE_UP:
- case Common::KEYCODE_KP8:
- case Common::KEYCODE_PAGEUP:
- case Common::KEYCODE_KP9:
- chooseMousePositionFromSprites(itemSprites, numItems, lastItemIndex, 2);
- break;
-
- case Common::KEYCODE_LEFT:
- case Common::KEYCODE_KP4:
- chooseMousePositionFromSprites(itemSprites, numItems, lastItemIndex, 1);
- break;
-
- case Common::KEYCODE_RIGHT:
- case Common::KEYCODE_KP6:
- chooseMousePositionFromSprites(itemSprites, numItems, lastItemIndex, 0);
- break;
-
- case Common::KEYCODE_END:
- case Common::KEYCODE_KP1:
- chooseMousePositionFromSprites(itemSprites, numItems, lastItemIndex, 5);
- break;
-
- case Common::KEYCODE_DOWN:
- case Common::KEYCODE_KP2:
- case Common::KEYCODE_PAGEDOWN:
- case Common::KEYCODE_KP3:
- chooseMousePositionFromSprites(itemSprites, numItems, lastItemIndex, 3);
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-
- removeNextEvent();
- }
-
- playSoundEffectIndex(0x10);
- if (lastItemIndex >= 0)
- drawMenuButtonOutline(itemSprites[lastItemIndex].bitmap, 0);
-
- for (int i = 0; i < numItems; i++)
- itemSprites[i].dontDrawNextFrame();
-
- _gfx->drawAllSprites();
-
- for (int i = 0; i < numItems; i++) {
- itemSprites[i].bitmap.reset();
- _gfx->delSprite(&itemSprites[i]);
- }
-
- if (lastItemIndex >= 0) {
- lastItemIndex = itemIndices[lastItemIndex];
- }
-
- if (restoreMouse)
- _gfx->warpMouse(oldMousePos.x, oldMousePos.y);
-
- _keyboardControlsMouse = keyboardControlledMouse;
- return lastItemIndex;
-}
-
-void StarTrekEngine::initStarfieldSprite(Sprite *sprite, SharedPtr<Bitmap> bitmap, const Common::Rect &rect) {
- sprite->setXYAndPriority(rect.left, rect.top, 0);
- sprite->setBitmap(bitmap);
- bitmap->xoffset = 0;
- bitmap->yoffset = 0;
- bitmap->width = rect.width();
- bitmap->height = rect.height();
- _gfx->addSprite(sprite);
- sprite->drawMode = 1;
-}
-
-SharedPtr<Bitmap> StarTrekEngine::scaleBitmap(SharedPtr<Bitmap> bitmap, Fixed8 scale) {
- int scaledWidth = scale.multToInt(bitmap->width);
- int scaledHeight = scale.multToInt(bitmap->height);
- int origWidth = bitmap->width;
- int origHeight = bitmap->height;
-
- if (scaledWidth < 1)
- scaledWidth = 1;
- if (scaledHeight < 1)
- scaledHeight = 1;
-
- SharedPtr<Bitmap> scaledBitmap(new Bitmap(scaledWidth, scaledHeight));
- scaledBitmap->xoffset = scale.multToInt(bitmap->xoffset);
- scaledBitmap->yoffset = scale.multToInt(bitmap->yoffset);
-
- // sub_344a5(scaledWidth, origWidth);
-
- origHeight--;
- scaledHeight--;
-
- byte *src = bitmap->pixels;
- byte *dest = scaledBitmap->pixels;
-
- if (scale <= 1.0) {
- int16 var2e = 0;
- uint16 var30 = scaledHeight << 1;
- uint16 var32 = (scaledHeight - origHeight) << 1;
- uint16 origRow = 0;
-
- while (origRow <= origHeight) {
- if (var2e < 0) {
- var2e += var30;
- } else {
- var2e += var32;
- scaleBitmapRow(src, dest, origWidth, scaledWidth);
- dest += scaledWidth;
- }
-
- src += bitmap->width;
- origRow++;
- }
- } else {
- int16 var2e = (origHeight << 1) - scaledHeight;
- uint16 var30 = origHeight << 1;
- uint16 var32 = (origHeight - scaledHeight) << 1;
- uint16 srcRowChanged = true;
- origWidth = bitmap->width;
- uint16 scaledRow = 0;
- byte *rowData = new byte[scaledWidth];
-
- while (scaledRow++ <= scaledHeight) {
- if (srcRowChanged) {
- scaleBitmapRow(src, rowData, origWidth, scaledWidth);
- srcRowChanged = false;
- }
-
- memcpy(dest, rowData, scaledWidth);
- dest += scaledWidth;
-
- if (var2e < 0) {
- var2e += var30;
- } else {
- var2e += var32;
- src += origWidth;
- srcRowChanged = true;
- }
- }
-
- delete[] rowData;
- }
-
- return scaledBitmap;
-}
-
-void StarTrekEngine::scaleBitmapRow(byte *src, byte *dest, uint16 origWidth, uint16 scaledWidth) {
- if (origWidth >= scaledWidth) {
- int16 var2 = (scaledWidth << 1) - origWidth;
- uint16 var4 = scaledWidth << 1;
- uint16 var6 = (scaledWidth - origWidth) << 1;
- uint16 varE = 0;
- uint16 varA = 0;
- uint16 var8 = origWidth;
- uint16 di = 0;
-
- while (var8-- != 0) {
- if (var2 < 0) {
- var2 += var4;
- } else {
- var2 += var6;
- if (di != 0) {
- if (varE != 0) {
- *(dest - 1) = *src++;
- varE = 0;
- di--;
- }
- src += di;
- di = 0;
- }
- *dest++ = *src;
- varE = 1;
- }
-
- di++;
- varA++;
- }
- } else {
- int16 var2 = ((origWidth - 1) << 1) - (scaledWidth - 1);
- uint16 var4 = (origWidth - 1) << 1;
- uint16 var6 = ((origWidth - 1) - (scaledWidth - 1)) << 1;
- uint16 varA = 0;
- uint16 var8 = scaledWidth;
- uint16 di = 0;
-
- while (var8-- != 0) {
- if (di != 0) {
- src += di;
- di = 0;
- }
- *dest++ = *src;
-
- if (var2 < 0)
- var2 += var4;
- else {
- var2 += var6;
- di++;
- }
-
- varA++;
- }
- }
-}
-
/**
* TODO:
* - Should return nullptr on failure to open a file?