diff options
author | Matthew Stewart | 2018-08-02 05:20:23 -0400 |
---|---|---|
committer | Eugene Sandulenko | 2018-08-09 08:37:30 +0200 |
commit | e5e54b8a1f937e2df1dfd141de9d4444257f9540 (patch) | |
tree | 36400c273a77bc516daa1caddba7b713bb41d1cd /engines/startrek/startrek.cpp | |
parent | a84746bf660f0413a205636edd39b484018e73b7 (diff) | |
download | scummvm-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.cpp | 1607 |
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? |