[Scummvm-git-logs] scummvm master -> 4e4681f27202bcb8610d5e2e2555e0c1c19e33b1
sev-
sev at scummvm.org
Sat Oct 24 14:13:54 UTC 2020
This automated email contains information about 85 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
bc35611293 TWINE: initial import
37bbfc168b TWINE: converted to classes and use the scummvm systems
77f29ada5f TWINE: renamed variables and initialize members
784e62d012 TWINE: updated detection entries for other languages
9428284b17 TWINE: reduced scope
a93aafbdc4 TWINE: removed Quit member from ConfigFile
1b4a8b8510 TWINE: replaced magic number
3bc2c1921b TWINE: fixed parts of the input handling
ecbc291e25 TWINE: use Graphics::Surface instead of raw 8 bit buffer
3afcbb8f35 TWINE: removed raw buffer crossFade method
859957cbee TWINE: reduced scope and cleanup
7e04efc533 TWINE: converted c artifacts to c++
4026b23d7c TWINE: merged version 0.2.2 of twine develop branch
c3f0c2b1c1 TWINE: removed unused enum
150266bd4b TWINE: refactored the input code to use the KeyMapper
5d18dd0d17 TWINE: handle magic ball action and code cleanup
7978dffee6 TWINE: fixed valgrind error reports
e652a0e93b TWINE: update the palette in crossFade
33d27512f1 TWINE: switch to managed surfaces
385a7b5422 TWINE: switched to rgba palette and ported crossFade
030b23b4db TWINE: refactored the input handling a little bit
903e0cc18a TWINE: further refactored the input handling
d8ad31f056 TWINE: moved actionstates into keyboard struct
2ac8330823 TWINE: renamed member of Keyboard struct
36884ce640 TWINE: converted remaining key down events to keymapper
5a80f0f0ac TWINE: convert to boolean
cc716125f5 TWINE: converted to char array
431ac7f465 TWINE: use constants for music config and improved midi hqr detection
e3e6f7eebe TWINE: try to open the fla files from a flat installation dir
cb96e1f388 TWINE: fixed escape mapping
b833a88e43 TWINE: fixed language detection for the scummvm language descriptions
53858b559e TWINE: fixed sound implementation
4900ee4fcf TWINE: only reset pressedKey member if the custom action is done
02910b092d TWINE: missed to add escape action to the KeyProperties
e1ec83207f TWINE: implemented midi music
18e7620613 TWINE: convert to boolean
707856a3a0 TWINE: fixed LanuageId text bank handling
9847b34a35 TWINE: refactored the way the voice playback is handled
5d37d79ebb TWINE: safeguards
13acf495a8 TWINE: error checks
401ab87715 TWINE: error checks
3fbb55b76e TWINE: sanity checks for resource loading
60e7cbfe11 TWINE: started to refactor the main loop
0766f49c23 TWINE: converted to boolean
c8e1dfbee0 TWINE: minor cleanup
a0a47a54d5 TWINE: renamed method params
c6b673c051 TWINE: converted to bool and use constants
e7f911fcbc TWINE: convert to boolean
dff5595cae TWINE: replaced magic numbers
d1a7b95d9a TWINE: replaced magic number
38cd5622b3 TWINE: forgot to reset the midi buffer pointer after freeing it
dffaa2956d TWINE: disabled partial screen blitting for now
232cfc691e TWINE: cleanup in holomap code
7988b5a750 TWINE: reduced scopes
d976da7962 TWINE: format
3789ff815b TWINE: error checks
cbbeaf3203 TWINE: reduced scope
b387c3903e TWINE: new todo comment
3868b03b4c TWINE: added small helper function to Keyboard struct
219d1f3562 TWINE: provide default parameter values for playSample
6affc464e7 TWINE: minor cleanup
37fdcb84e4 TWINE: reduced scope
851cf6a8c5 TWINE: fixed restarting the engine with broken menu state
f7defb55e0 TWINE: cleanup gamestate - use constants for dynamic menu
1003a57f40 TWINE: fixed warning
0ef816f5e2 TWINE: comments
b7d5232708 TWINE: refactored input
c59fd6a32e TWINE: refactored input
d417478b8c TWINE: started to split keymaps for ui, game and cutscenes
4c593bdbdd TWINE: further refactored the input code
1027ddda97 TWINE: fixed memory leaks
c5b5e98db1 TWINE: fixed showing delayed text
84f2ba7e41 TWINE: implemented more keymap actions
5b21b55a85 TWINE: use toggleAbortAction for GameState::processFoundItem
82cda6e217 TWINE: reduced scope + cleanup
a8762fca13 TWINE: sanity checks
c8a12ef178 TWINE: reduced scope + cleanup
600f796e57 TWINE: don't show the ui if you abort the intro movie
a6117c2897 TWINE: connect more keymapper events to their in-game actions
235ba116fc TWINE: doxygen
a1e43850d1 TWINE: cleanup and more keymapper actions connected
764640ac74 TWINE: connect more keymapper actions
2ccbff91d8 TWINE: connect some of the advanced options menu settings
fdca862294 TWINE: transfer auto agressive settings to actor state
4e4681f272 TWINE: activate intros again and fixed warning
Commit: bc3561129348e11bb7fa2a5c232884a62beb7aa6
https://github.com/scummvm/scummvm/commit/bc3561129348e11bb7fa2a5c232884a62beb7aa6
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: initial import
Changed paths:
A engines/twine/actor.cpp
A engines/twine/actor.h
A engines/twine/animations.cpp
A engines/twine/animations.h
A engines/twine/collision.cpp
A engines/twine/collision.h
A engines/twine/configure.engine
A engines/twine/debug.cpp
A engines/twine/debug.grid.cpp
A engines/twine/debug.grid.h
A engines/twine/debug.h
A engines/twine/debug.scene.cpp
A engines/twine/debug.scene.h
A engines/twine/detection.cpp
A engines/twine/detection.h
A engines/twine/extra.cpp
A engines/twine/extra.h
A engines/twine/fcaseopen.cpp
A engines/twine/fcaseopen.h
A engines/twine/filereader.cpp
A engines/twine/filereader.h
A engines/twine/flamovies.cpp
A engines/twine/flamovies.h
A engines/twine/gamestate.cpp
A engines/twine/gamestate.h
A engines/twine/grid.cpp
A engines/twine/grid.h
A engines/twine/holomap.cpp
A engines/twine/holomap.h
A engines/twine/hqrdepack.cpp
A engines/twine/hqrdepack.h
A engines/twine/interface.cpp
A engines/twine/interface.h
A engines/twine/keyboard.cpp
A engines/twine/keyboard.h
A engines/twine/lbaengine.cpp
A engines/twine/lbaengine.h
A engines/twine/main.cpp
A engines/twine/main.h
A engines/twine/menu.cpp
A engines/twine/menu.h
A engines/twine/menuoptions.cpp
A engines/twine/menuoptions.h
A engines/twine/metaengine.cpp
A engines/twine/module.mk
A engines/twine/movements.cpp
A engines/twine/movements.h
A engines/twine/music.cpp
A engines/twine/music.h
A engines/twine/redraw.cpp
A engines/twine/redraw.h
A engines/twine/renderer.cpp
A engines/twine/renderer.h
A engines/twine/resources.cpp
A engines/twine/resources.h
A engines/twine/scene.cpp
A engines/twine/scene.h
A engines/twine/screens.cpp
A engines/twine/screens.h
A engines/twine/script.life.cpp
A engines/twine/script.life.h
A engines/twine/script.move.cpp
A engines/twine/script.move.h
A engines/twine/sdlengine.cpp
A engines/twine/sdlengine.h
A engines/twine/shadeangletab.h
A engines/twine/sound.cpp
A engines/twine/sound.h
A engines/twine/sys.cpp
A engines/twine/sys.h
A engines/twine/text.cpp
A engines/twine/text.h
A engines/twine/xmidi.cpp
A engines/twine/xmidi.h
diff --git a/engines/twine/actor.cpp b/engines/twine/actor.cpp
new file mode 100644
index 0000000000..db31b5f9a6
--- /dev/null
+++ b/engines/twine/actor.cpp
@@ -0,0 +1,540 @@
+/** @file actor.cpp
+ @brief
+ This file contains scene actor routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "actor.h"
+#include "lbaengine.h"
+#include "scene.h"
+#include "hqrdepack.h"
+#include "resources.h"
+#include "renderer.h"
+#include "grid.h"
+#include "animations.h"
+#include "renderer.h"
+#include "movements.h"
+#include "gamestate.h"
+#include "sound.h"
+#include "extra.h"
+
+/** Actors 3D body table - size of NUM_BODIES */
+uint8 *bodyTable[NUM_BODIES];
+
+/** Restart hero variables while opening new scenes */
+void restartHeroScene() {
+ sceneHero->controlMode = 1;
+ memset(&sceneHero->dynamicFlags, 0, 2);
+ memset(&sceneHero->staticFlags, 0, 2);
+
+ sceneHero->staticFlags.bComputeCollisionWithObj = 1;
+ sceneHero->staticFlags.bComputeCollisionWithBricks = 1;
+ sceneHero->staticFlags.bIsZonable = 1;
+ sceneHero->staticFlags.bCanDrown = 1;
+ sceneHero->staticFlags.bCanFall = 1;
+
+ sceneHero->armor = 1;
+ sceneHero->positionInMoveScript = -1;
+ sceneHero->labelIdx = -1;
+ sceneHero->positionInLifeScript = 0;
+ sceneHero->zone = -1;
+ sceneHero->angle = previousHeroAngle;
+
+ setActorAngleSafe(sceneHero->angle, sceneHero->angle, 0, &sceneHero->move);
+ setBehaviour(previousHeroBehaviour);
+
+ cropBottomScreen = 0;
+}
+
+/** Load hero 3D body and animations */
+void loadHeroEntities() {
+ hqrGetallocEntry(&heroEntityATHLETIC, HQR_FILE3D_FILE, FILE3DHQR_HEROATHLETIC);
+ sceneHero->entityDataPtr = heroEntityATHLETIC;
+ heroAnimIdxATHLETIC = getBodyAnimIndex(0, 0);
+
+ hqrGetallocEntry(&heroEntityAGGRESSIVE, HQR_FILE3D_FILE, FILE3DHQR_HEROAGGRESSIVE);
+ sceneHero->entityDataPtr = heroEntityAGGRESSIVE;
+ heroAnimIdxAGGRESSIVE = getBodyAnimIndex(0, 0);
+
+ hqrGetallocEntry(&heroEntityDISCRETE, HQR_FILE3D_FILE, FILE3DHQR_HERODISCRETE);
+ sceneHero->entityDataPtr = heroEntityDISCRETE;
+ heroAnimIdxDISCRETE = getBodyAnimIndex(0, 0);
+
+ hqrGetallocEntry(&heroEntityPROTOPACK, HQR_FILE3D_FILE, FILE3DHQR_HEROPROTOPACK);
+ sceneHero->entityDataPtr = heroEntityPROTOPACK;
+ heroAnimIdxPROTOPACK = getBodyAnimIndex(0, 0);
+
+ hqrGetallocEntry(&heroEntityNORMAL, HQR_FILE3D_FILE, FILE3DHQR_HERONORMAL);
+ sceneHero->entityDataPtr = heroEntityNORMAL;
+ heroAnimIdxNORMAL = getBodyAnimIndex(0, 0);
+
+ sceneHero->animExtraPtr = currentActorAnimExtraPtr;
+}
+
+/** Set hero behaviour
+ @param behaviour behaviour value to set */
+void setBehaviour(int32 behaviour) {
+ int32 bodyIdx;
+
+ switch (behaviour) {
+ case kNormal:
+ heroBehaviour = kNormal;
+ sceneHero->entityDataPtr = heroEntityNORMAL;
+ break;
+ case kAthletic:
+ heroBehaviour = kAthletic;
+ sceneHero->entityDataPtr = heroEntityATHLETIC;
+ break;
+ case kAggressive:
+ heroBehaviour = kAggressive;
+ sceneHero->entityDataPtr = heroEntityAGGRESSIVE;
+ break;
+ case kDiscrete:
+ heroBehaviour = kDiscrete;
+ sceneHero->entityDataPtr = heroEntityDISCRETE;
+ break;
+ case kProtoPack:
+ heroBehaviour = kProtoPack;
+ sceneHero->entityDataPtr = heroEntityPROTOPACK;
+ break;
+ };
+
+ bodyIdx = sceneHero->body;
+
+ sceneHero->entity = -1;
+ sceneHero->body = -1;
+
+ initModelActor(bodyIdx, 0);
+
+ sceneHero->anim = -1;
+ sceneHero->animType = 0;
+
+ initAnim(kStanding, 0, 255, 0);
+}
+
+/** Initialize sprite actor
+ @param actorIdx sprite actor index */
+void initSpriteActor(int32 actorIdx) {
+ ActorStruct *localActor = &sceneActors[actorIdx];
+
+ if (localActor->staticFlags.bIsSpriteActor && localActor->sprite != -1 && localActor->entity != localActor->sprite) {
+ int16 *ptr = (int16 *)(spriteBoundingBoxPtr + localActor->sprite * 16 + 4);
+
+ localActor->entity = localActor->sprite;
+ localActor->boudingBox.X.bottomLeft = *(ptr++);
+ localActor->boudingBox.X.topRight = *(ptr++);
+ localActor->boudingBox.Y.bottomLeft = *(ptr++);
+ localActor->boudingBox.Y.topRight = *(ptr++);
+ localActor->boudingBox.Z.bottomLeft = *(ptr++);
+ localActor->boudingBox.Z.topRight = *(ptr++);
+ }
+}
+
+/** Initialize 3D actor body
+ @param bodyIdx 3D actor body index
+ @param actorIdx 3D actor index */
+int32 initBody(int32 bodyIdx, int32 actorIdx) {
+ ActorStruct *localActor;
+ uint8 *bodyPtr;
+ uint8 var1;
+ uint8 var2;
+ uint8 *bodyPtr2;
+ uint8 *bodyPtr3;
+ uint8 *bodyPtr4;
+// int16 *bodyPtr5;
+ int16 flag;
+ int32 index;
+
+ localActor = &sceneActors[actorIdx];
+ bodyPtr = localActor->entityDataPtr;
+
+ do {
+ var1 = *(bodyPtr++);
+
+ if (var1 == 0xFF)
+ return (-1);
+
+ bodyPtr2 = bodyPtr + 1;
+
+ if (var1 == 1) {
+ var2 = *(bodyPtr);
+
+ if (var2 == bodyIdx) {
+ bodyPtr3 = bodyPtr2 + 1;
+ flag = *((uint16*)bodyPtr3);
+
+ if (!(flag & 0x8000)) {
+ hqrGetallocEntry(&bodyTable[currentPositionInBodyPtrTab], HQR_BODY_FILE, flag & 0xFFFF);
+
+ if (!bodyTable[currentPositionInBodyPtrTab]) {
+ printf("HQR ERROR: Loading body entities\n");
+ exit(1);
+ }
+ prepareIsoModel(bodyTable[currentPositionInBodyPtrTab]);
+ *((uint16*)bodyPtr3) = currentPositionInBodyPtrTab + 0x8000;
+ index = currentPositionInBodyPtrTab;
+ currentPositionInBodyPtrTab++;
+ } else {
+ flag &= 0x7FFF;
+ index = flag;
+ }
+
+ bodyPtr3 += 2;
+ bottomLeftX = -32000;
+
+ bodyPtr4 = bodyPtr3;
+ bodyPtr3++;
+
+ if (!*bodyPtr4)
+ return (index);
+
+ bodyPtr4 = bodyPtr3;
+ bodyPtr3++;
+
+ if (*bodyPtr4 != 14)
+ return (index);
+
+// bodyPtr5 = (int16 *) bodyPtr3;
+
+ bottomLeftX = *((uint16*)bodyPtr3);
+ bodyPtr3 += 2;
+ bottomLeftY = *((uint16*)bodyPtr3);
+ bodyPtr3 += 2;
+ bottomLeftZ = *((uint16*)bodyPtr3);
+ bodyPtr3 += 2;
+
+ topRightX = *((uint16*)bodyPtr3);
+ bodyPtr3 += 2;
+ topRightY = *((uint16*)bodyPtr3);
+ bodyPtr3 += 2;
+ topRightZ = *((uint16*)bodyPtr3);
+ bodyPtr3 += 2;
+
+ return (index);
+ }
+ }
+
+ bodyPtr = *bodyPtr2 + bodyPtr2;
+ } while (1);
+}
+
+/** Initialize 3D actor
+ @param bodyIdx 3D actor body index
+ @param actorIdx 3D actor index */
+void initModelActor(int32 bodyIdx, int16 actorIdx) {
+ ActorStruct *localActor;
+ int32 entityIdx;
+ int currentIndex;
+ uint16 *ptr;
+ int16 var1, var2, var3, var4;
+
+ int32 result, result1, result2;
+
+ result = 0;
+
+ localActor = &sceneActors[actorIdx];
+
+ if (localActor->staticFlags.bIsSpriteActor)
+ return;
+
+ if (actorIdx == 0 && heroBehaviour == kProtoPack && localActor->armor != 0 && localActor->armor != 1) { // if hero
+ setBehaviour(kNormal);
+ }
+
+ if (bodyIdx != -1) {
+ entityIdx = initBody(bodyIdx, actorIdx);
+ } else {
+ entityIdx = -1;
+ }
+
+ if (entityIdx != -1) {
+ if (localActor->entity == entityIdx)
+ return;
+
+ localActor->entity = entityIdx;
+ localActor->body = bodyIdx;
+ currentIndex = localActor->entity;
+
+ if (bottomLeftX == -32000) {
+ ptr = (uint16 *) bodyTable[localActor->entity];
+ ptr++;
+
+ var1 = *((int16 *)ptr++);
+ var2 = *((int16 *)ptr++);
+ localActor->boudingBox.Y.bottomLeft = *((int16 *)ptr++);
+ localActor->boudingBox.Y.topRight = *((int16 *)ptr++);
+ var3 = *((int16 *)ptr++);
+ var4 = *((int16 *)ptr++);
+
+ if (localActor->staticFlags.bUseMiniZv) {
+ result1 = var2 - var1; // take smaller for bound
+ result2 = var4 - var3;
+
+ if (result1 < result2)
+ result = result1;
+ else
+ result = result2;
+
+ result = abs(result);
+ result >>= 1;
+ } else {
+ result1 = var2 - var1; // take average for bound
+ result2 = var4 - var3;
+
+ result = result2 + result1;
+ result = abs(result);
+ result >>= 2;
+ }
+
+ localActor->boudingBox.X.bottomLeft = -result;
+ localActor->boudingBox.X.topRight = result;
+ localActor->boudingBox.Z.bottomLeft = -result;
+ localActor->boudingBox.Z.topRight = result;
+ } else {
+ localActor->boudingBox.X.bottomLeft = bottomLeftX;
+ localActor->boudingBox.X.topRight = topRightX;
+ localActor->boudingBox.Y.bottomLeft = bottomLeftY;
+ localActor->boudingBox.Y.topRight = topRightY;
+ localActor->boudingBox.Z.bottomLeft = bottomLeftZ;
+ localActor->boudingBox.Z.topRight = topRightZ;
+ }
+
+ if (currentIndex == -1)
+ return;
+
+ if (localActor->previousAnimIdx == -1)
+ return;
+
+ copyActorInternAnim(bodyTable[currentIndex], bodyTable[localActor->entity]);
+
+ return;
+ }
+
+ localActor->body = -1;
+ localActor->entity = -1;
+
+ localActor->boudingBox.X.bottomLeft = 0;
+ localActor->boudingBox.X.topRight = 0;
+ localActor->boudingBox.Y.bottomLeft = 0;
+ localActor->boudingBox.Y.topRight = 0;
+ localActor->boudingBox.Z.bottomLeft = 0;
+ localActor->boudingBox.Z.topRight = 0;
+}
+
+/** Initialize actors
+ @param actorIdx actor index to init */
+void initActor(int16 actorIdx) {
+ ActorStruct *actor = &sceneActors[actorIdx];
+
+ if (actor->staticFlags.bIsSpriteActor) { // if sprite actor
+ if (actor->strengthOfHit != 0) {
+ actor->dynamicFlags.bIsHitting = 1;
+ }
+
+ actor->entity = -1;
+
+ initSpriteActor(actorIdx);
+
+ setActorAngleSafe(0, 0, 0, &actor->move);
+
+ if (actor->staticFlags.bUsesClipping) {
+ actor->lastX = actor->X;
+ actor->lastY = actor->Y;
+ actor->lastZ = actor->Z;
+ }
+
+ } else {
+ actor->entity = -1;
+
+ initModelActor(actor->body, actorIdx);
+
+ actor->previousAnimIdx = -1;
+ actor->animType = 0;
+
+ if (actor->entity != -1) {
+ initAnim(actor->anim, 0, 255, actorIdx);
+ }
+
+ setActorAngleSafe(actor->angle, actor->angle, 0, &actor->move);
+ }
+
+ actor->positionInMoveScript = -1;
+ actor->labelIdx = -1;
+ actor->positionInLifeScript = 0;
+}
+
+/** Reset actor
+ @param actorIdx actor index to init */
+void resetActor(int16 actorIdx) {
+ ActorStruct *actor = &sceneActors[actorIdx];
+
+ actor->body = 0;
+ actor->anim = 0;
+ actor->X = 0;
+ actor->Y = -1;
+ actor->Z = 0;
+
+ actor->boudingBox.X.bottomLeft = 0;
+ actor->boudingBox.X.topRight = 0;
+ actor->boudingBox.Y.bottomLeft = 0;
+ actor->boudingBox.Y.topRight = 0;
+ actor->boudingBox.Z.bottomLeft = 0;
+ actor->boudingBox.Z.topRight = 0;
+
+ actor->angle = 0;
+ actor->speed = 40;
+ actor->controlMode = 0;
+
+ actor->info0 = 0;
+ actor->info1 = 0;
+ actor->info2 = 0;
+ actor->info3 = 0;
+
+ actor->brickShape = 0;
+ actor->collision = -1;
+ actor->standOn = -1;
+ actor->zone = -1;
+
+ memset(&actor->staticFlags,0,2);
+ memset(&actor->dynamicFlags,0,2);
+
+ actor->life = 50;
+ actor->armor = 1;
+ actor->hitBy = -1;
+ actor->lastRotationAngle = 0;
+ actor->lastX = 0;
+ actor->lastY = 0;
+ actor->lastZ = 0;
+ actor->entity = -1;
+ actor->previousAnimIdx = -1;
+ actor->animType = 0;
+ actor->animPosition = 0;
+
+ setActorAngleSafe(0, 0, 0, &actor->move);
+
+ actor->positionInMoveScript = -1;
+ actor->positionInLifeScript = 0;
+}
+
+/** Process hit actor
+ @param actorIdx actor hitting index
+ @param actorIdxAttacked actor attacked index
+ @param strengthOfHit actor hitting strength of hit
+ @param angle angle of actor hitting */
+void hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32 angle) {
+ ActorStruct *actor = &sceneActors[actorIdxAttacked];
+
+ if (actor->life <= 0) {
+ return;
+ }
+
+ actor->hitBy = actorIdx;
+
+ if (actor->armor <= strengthOfHit) {
+ if (actor->anim == kBigHit || actor->anim == kHit2) {
+ int32 tmpAnimPos;
+ tmpAnimPos = actor->animPosition;
+ if (actor->animExtra) {
+ processAnimActions(actorIdxAttacked);
+ }
+
+ actor->animPosition = tmpAnimPos;
+ } else {
+ if (angle != -1) {
+ setActorAngleSafe(angle, angle, 0, &actor->move);
+ }
+
+ if (rand() & 1) {
+ initAnim(kHit2, 3, 255, actorIdxAttacked);
+ } else {
+ initAnim(kBigHit, 3, 255, actorIdxAttacked);
+ }
+ }
+
+ addExtraSpecial(actor->X, actor->Y + 1000, actor->Z, kHitStars);
+
+ if (!actorIdxAttacked) {
+ heroMoved = 1;
+ }
+
+ actor->life -= strengthOfHit;
+
+ if (actor->life < 0) {
+ actor->life = 0;
+ }
+ } else {
+ initAnim(kHit, 3, 255, actorIdxAttacked);
+ }
+}
+
+/** Process actor carrier */
+void processActorCarrier(int32 actorIdx) { // CheckCarrier
+ int32 a;
+ ActorStruct *actor = &sceneActors[actorIdx];
+
+ if (actor->staticFlags.bIsCarrierActor) {
+ for (a = 0; a < sceneNumActors; a++) {
+ if (actor->standOn == actorIdx) {
+ actor->standOn = -1;
+ }
+ }
+ }
+}
+
+/** Process actor extra bonus */
+void processActorExtraBonus(int32 actorIdx) { // GiveExtraBonus
+ int32 a, numBonus;
+ int8 bonusTable[8], currentBonus;
+ ActorStruct *actor = &sceneActors[actorIdx];
+
+ numBonus = 0;
+
+ for (a = 0; a < 5; a++) {
+ if (actor->bonusParameter & (1 << (a + 4))) {
+ bonusTable[numBonus++] = a;
+ }
+ }
+
+ if (numBonus) {
+ currentBonus = bonusTable[Rnd(numBonus)];
+ // if bonus is magic an no magic level yet, then give life points
+ if (!magicLevelIdx && currentBonus == 2) {
+ currentBonus = 1;
+ }
+ currentBonus += 3;
+
+ if (actor->dynamicFlags.bIsDead) {
+ addExtraBonus(actor->X, actor->Y, actor->Z, 0x100, 0, currentBonus, actor->bonusAmount);
+ // FIXME add constant for sample index
+ playSample(11, 0x1000, 1, actor->X, actor->Y, actor->Z, actorIdx);
+ } else {
+ int32 angle = getAngleAndSetTargetActorDistance(actor->X, actor->Z, sceneHero->X, sceneHero->Z);
+ addExtraBonus(actor->X, actor->Y + actor->boudingBox.Y.topRight, actor->Z, 200, angle, currentBonus, actor->bonusAmount);
+ // FIXME add constant for sample index
+ playSample(11, 0x1000, 1, actor->X, actor->Y + actor->boudingBox.Y.topRight, actor->Z, actorIdx);
+ }
+ }
+}
diff --git a/engines/twine/actor.h b/engines/twine/actor.h
new file mode 100644
index 0000000000..d3cd776009
--- /dev/null
+++ b/engines/twine/actor.h
@@ -0,0 +1,294 @@
+/** @file actor.h
+ @brief
+ This file contains scene actor routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef ACTOR_H
+#define ACTOR_H
+
+#include "sys.h"
+
+/** Total number of sprites allowed in the game */
+#define NUM_SPRITES 200
+
+/** Total number of bodies allowed in the game */
+#define NUM_BODIES 200
+
+enum HeroBehaviourType {
+ kNormal = 0,
+ kAthletic = 1,
+ kAggressive = 2,
+ kDiscrete = 3,
+ kProtoPack = 4
+};
+
+
+/** Table with all loaded sprites */
+uint8* spriteTable[NUM_SPRITES];
+/** Table with all loaded sprite sizes */
+uint32 spriteSizeTable[NUM_SPRITES];
+
+/** Actors move structure */
+typedef struct ActorMoveStruct {
+ int16 from;
+ int16 to;
+ int16 numOfStep;
+ int32 timeOfChange;
+} ActorMoveStruct;
+
+/** Actors zone volumique points structure */
+typedef struct ZVPoint {
+ int16 bottomLeft;
+ int16 topRight;
+} ZVPoint;
+
+/** Actors zone volumique box structure */
+typedef struct ZVBox {
+ ZVPoint X;
+ ZVPoint Y;
+ ZVPoint Z;
+} ZVBox;
+
+/** Actors animation timer structure */
+typedef struct AnimTimerDataStruct {
+ uint8* ptr;
+ int32 time;
+} AnimTimerDataStruct;
+
+/** Actors static flags structure */
+typedef struct StaticFlagsStruct {
+ uint16 bComputeCollisionWithObj : 1; // 0x0001
+ uint16 bComputeCollisionWithBricks : 1; // 0x0002
+ uint16 bIsZonable : 1; // 0x0004
+ uint16 bUsesClipping : 1; // 0x0008
+ uint16 bCanBePushed : 1; // 0x0010
+ uint16 bComputeLowCollision : 1; // 0x0020
+ uint16 bCanDrown : 1; // 0x0040
+ uint16 bUnk80 : 1; // 0x0080
+ uint16 bUnk0100 : 1; // 0x0100
+ uint16 bIsHidden : 1; // 0x0200
+ uint16 bIsSpriteActor : 1; // 0x0400
+ uint16 bCanFall : 1; // 0x0800
+ uint16 bDoesntCastShadow : 1; // 0x1000
+ uint16 bIsBackgrounded : 1; // 0x2000
+ uint16 bIsCarrierActor : 1; // 0x4000
+ uint16 bUseMiniZv : 1; // 0x8000
+} StaticFlagsStruct;
+
+/** Actors dynamic flags structure */
+typedef struct DynamicFlagsStruct {
+ uint16 bWaitHitFrame : 1; // 0x0001 wait for hit frame
+ uint16 bIsHitting : 1; // 0x0002 hit frame anim
+ uint16 bAnimEnded : 1; // 0x0004 anim ended in the current loop (will be looped in the next engine loop)
+ uint16 bAnimFrameReached : 1; // 0x0008 new frame anim reached
+ uint16 bIsVisible : 1; // 0x0010 actor has been drawn in this loop
+ uint16 bIsDead : 1; // 0x0020 is dead
+ uint16 bIsSpriteMoving : 1; // 0x0040 door is opening or closing (wait to reach the destination position)
+ uint16 bIsRotationByAnim : 1; // 0x0080 actor rotation is managed by its animaation not by the engine
+ uint16 bIsFalling : 1; // 0x0100 is falling on scene
+ uint16 bUnk0200 : 1; // 0x0200 unused
+ uint16 bUnk0400 : 1; // 0x0400 unused
+ uint16 bUnk0800 : 1; // 0x0800 unused
+ uint16 bUnk1000 : 1; // 0x1000 unused
+ uint16 bUnk2000 : 1; // 0x2000 unused
+ uint16 bUnk4000 : 1; // 0x4000 unused
+ uint16 bUnk8000 : 1; // 0x8000 unused
+} DynamicFlagsStruct;
+
+/** Actors structure */
+typedef struct ActorStruct {
+ StaticFlagsStruct staticFlags;
+ DynamicFlagsStruct dynamicFlags;
+
+ int32 entity; // costumeIndex
+ int32 body;
+ int32 anim;
+ int32 animExtra; //field_2
+ int32 brickShape; // field_3
+ uint8 *animExtraPtr;
+ int32 sprite; // field_8
+ uint8 *entityDataPtr;
+
+ int32 X;
+ int32 Y;
+ int32 Z;
+ int32 strengthOfHit; // field_66
+ int32 hitBy;
+ int32 bonusParameter; // field_10
+ int32 angle;
+ int32 speed;
+ int32 controlMode;
+ int32 info0; // cropLeft
+ int32 info1; // cropTop
+ int32 info2; // cropRight
+ int32 info3; // cropBottom
+ int32 followedActor; // same as info3
+ int32 bonusAmount; // field_12
+ int32 talkColor;
+ int32 armor; // field_14
+ int32 life;
+
+ int32 collisionX; // field_20
+ int32 collisionY; // field_22
+ int32 collisionZ; // field_24
+
+ int32 positionInMoveScript;
+ uint8 *moveScript;
+
+ int32 positionInLifeScript;
+ uint8 *lifeScript;
+
+ int32 labelIdx; // script label index
+ int32 currentLabelPtr; // pointer to LABEL offset
+ int32 pausedTrackPtr;
+
+ //int costumeIndex;
+ int32 collision;
+ int32 standPosition;
+ int32 standOn;
+ int32 zone;
+
+ int32 lastRotationAngle;
+ int32 lastX;
+ int32 lastZ;
+ int32 lastY;
+ int32 previousAnimIdx;
+ int32 doorStatus;
+ int32 animPosition;
+ int32 animType; // field_78
+ int32 brickSound; // field_7A
+
+ ZVBox boudingBox;
+ ActorMoveStruct move;
+ AnimTimerDataStruct animTimerData;
+} ActorStruct;
+
+/** Actor shadow X coordinate */
+int32 shadowX;
+/** Actor shadow Y coordinate */
+int32 shadowY;
+/** Actor shadow Z coordinate */
+int32 shadowZ;
+/** Actor shadow collition type */
+int8 shadowCollisionType; // shadowVar
+
+/** Hero behaviour */
+int16 heroBehaviour;
+/** Hero auto agressive mode */
+int16 autoAgressive;
+/** Previous Hero behaviour */
+int16 previousHeroBehaviour;
+/** Previous Hero angle */
+int16 previousHeroAngle;
+
+int16 cropBottomScreen;
+
+/** Hero 3D entity for normal behaviour */
+uint8 *heroEntityNORMAL; // file3D0
+/** Hero 3D entity for athletic behaviour */
+uint8 *heroEntityATHLETIC; // file3D1
+/** Hero 3D entity for aggressive behaviour */
+uint8 *heroEntityAGGRESSIVE; // file3D2
+/** Hero 3D entity for discrete behaviour */
+uint8 *heroEntityDISCRETE; // file3D3
+/** Hero 3D entity for protopack behaviour */
+uint8 *heroEntityPROTOPACK; // file3D4
+
+/** Hero current anim for normal behaviour */
+int16 heroAnimIdxNORMAL; // TCos0Init
+/** Hero current anim for athletic behaviour */
+int16 heroAnimIdxATHLETIC; // TCos1Init
+/** Hero current anim for aggressive behaviour */
+int16 heroAnimIdxAGGRESSIVE; // TCos2Init
+/** Hero current anim for discrete behaviour */
+int16 heroAnimIdxDISCRETE; // TCos3Init
+/** Hero current anim for protopack behaviour */
+int16 heroAnimIdxPROTOPACK; // TCos4Init
+
+/** Hero anim for behaviour menu */
+int16 heroAnimIdx[4]; // TCOS
+
+/** Actors 3D body table - size of NUM_BODIES */
+extern uint8 *bodyTable[NUM_BODIES];
+
+/** Current position in body table */
+int32 currentPositionInBodyPtrTab;
+
+/** Actor bounding box bottom left X coordinate */
+int16 bottomLeftX; // loadCostumeVar
+/** Actor bounding box bottom left Y coordinate */
+int16 bottomLeftY; // loadCostumeVar2
+/** Actor bounding box bottom left Z coordinate */
+int16 bottomLeftZ; // loadCostumeVar3
+/** Actor bounding box top left X coordinate */
+int16 topRightX; // loadCostumeVar4
+/** Actor bounding box top left Y coordinate */
+int16 topRightY; // loadCostumeVar5
+/** Actor bounding box top left Z coordinate */
+int16 topRightZ; // loadCostumeVar6
+
+/** Restart hero variables while opening new scenes */
+void restartHeroScene();
+
+/** Load hero 3D body and animations */
+void loadHeroEntities();
+
+/** Set hero behaviour
+ @param behaviour behaviour value to set */
+void setBehaviour(int32 behaviour);
+
+/** Initialize 3D actor body
+ @param bodyIdx 3D actor body index
+ @param actorIdx 3D actor index */
+int32 initBody(int32 bodyIdx, int32 actorIdx);
+
+/** Preload all sprites */
+void preloadSprites();
+
+/** Initialize 3D actor
+ @param bodyIdx 3D actor body index
+ @param actorIdx 3D actor index */
+void initModelActor(int32 bodyIdx, int16 actorIdx);
+
+/** Initialize actors
+ @param actorIdx actor index to init */
+void initActor(int16 actorIdx);
+
+/** Reset actor
+ @param actorIdx actor index to init */
+void resetActor(int16 actorIdx);
+
+/** Process hit actor
+ @param actorIdx actor hitting index
+ @param actorIdxAttacked actor attacked index
+ @param strengthOfHit actor hitting strength of hit
+ @param angle angle of actor hitting */
+void hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32 angle);
+
+/** Process actor carrier */
+void processActorCarrier(int32 actorIdx);
+
+/** Process actor extra bonus */
+void processActorExtraBonus(int32 actorIdx);
+
+#endif
diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
new file mode 100644
index 0000000000..8f34e458f1
--- /dev/null
+++ b/engines/twine/animations.cpp
@@ -0,0 +1,1282 @@
+/** @file animations.cpp
+ @brief
+ This file contains 3D actors animations routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "animations.h"
+#include "lbaengine.h"
+#include "resources.h"
+#include "scene.h"
+#include "actor.h"
+#include "renderer.h"
+#include "movements.h"
+#include "sound.h"
+#include "gamestate.h"
+#include "collision.h"
+#include "grid.h"
+#include "main.h"
+
+enum ActionType {
+ ACTION_HITTING = 0,
+ ACTION_SAMPLE = 1,
+ ACTION_SAMPLE_FREQ = 2,
+ ACTION_THROW_EXTRA_BONUS = 3,
+ ACTION_THROW_MAGIC_BALL = 4,
+ ACTION_SAMPLE_REPEAT = 5,
+ ACTION_UNKNOWN_6 = 6,
+ ACTION_UNKNOWN_7 = 7,
+ ACTION_SAMPLE_STOP = 8,
+ ACTION_UNKNOWN_9 = 9, // unused
+ ACTION_SAMPLE_BRICK_1 = 10,
+ ACTION_SAMPLE_BRICK_2 = 11,
+ ACTION_HERO_HITTING = 12,
+ ACTION_UNKNOWN_13 = 13,
+ ACTION_UNKNOWN_14 = 14,
+ ACTION_UNKNOWN_15 = 15,
+ ACTION_LAST
+};
+
+/** Set animation keyframe
+ @param keyframIdx Animation keyframe index
+ @param animPtr Pointer to animation
+ @param bodyPtr Body model poitner
+ @param animTimerDataPtr Animation time data */
+int setAnimAtKeyframe(int32 keyframeIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr) {
+ int16 numOfKeyframeInAnim;
+ int16 numOfBonesInAnim;
+ uint8 *ptrToData;
+ uint8 *ptrToDataBackup;
+ uint8 *ptrToBodyData;
+ int16 bodyHeader;
+ int16 numOfElementInBody;
+ int16 numOfPointInBody;
+ int32 i;
+
+ numOfKeyframeInAnim = *(int16 *)(animPtr);
+
+ if (keyframeIdx >= numOfKeyframeInAnim)
+ return numOfKeyframeInAnim;
+
+ numOfBonesInAnim = *(int16 *)(animPtr + 2);
+
+ ptrToData = (uint8 *)((numOfBonesInAnim * 8 + 8) * keyframeIdx + animPtr + 8);
+
+ bodyHeader = *(int16 *)(bodyPtr);
+
+ if (!(bodyHeader & 2))
+ return 0;
+
+ ptrToBodyData = bodyPtr + 14;
+
+ animTimerDataPtr->ptr = ptrToData;
+ animTimerDataPtr->time = lbaTime;
+
+ ptrToBodyData = ptrToBodyData + *(int16 *)(ptrToBodyData) + 2;
+
+ numOfElementInBody = *(int16 *)(ptrToBodyData);
+
+ ptrToBodyData = ptrToBodyData + numOfElementInBody * 6 + 12;
+
+ numOfPointInBody = *(int16 *)(ptrToBodyData - 10); // num elements
+
+ if (numOfBonesInAnim > numOfPointInBody) {
+ numOfBonesInAnim = numOfPointInBody;
+ }
+
+ ptrToDataBackup = ptrToData;
+
+ ptrToData += 8;
+
+ do {
+ for (i = 0; i < 8; i++) {
+ *(ptrToBodyData++) = *(ptrToData++);
+ }
+
+ ptrToBodyData += 30;
+
+ } while (--numOfBonesInAnim);
+
+ ptrToData = ptrToDataBackup + 2;
+
+ currentStepX = *(int16 *)(ptrToData);
+ currentStepY = *(int16 *)(ptrToData + 2);
+ currentStepZ = *(int16 *)(ptrToData + 4);
+
+ processRotationByAnim = *(int16 *)(ptrToData + 6);
+ processLastRotationAngle = *(int16 *)(ptrToData + 10);
+
+ return 1;
+}
+
+/** Get total number of keyframes in animation
+ @param animPtr Pointer to animation */
+int32 getNumKeyframes(uint8 *animPtr) {
+ return (*(int16 *)(animPtr));
+}
+
+/** Get first keyframes in animation
+ @param animPtr Pointer to animation */
+int32 getStartKeyframe(uint8 *animPtr) {
+ return (*(int16 *)(animPtr + 4));
+}
+
+/** Apply animation step rotation */
+void applyAnimStepRotation(uint8 **ptr, int32 bp, int32 bx) {
+ int16 *dest;
+ int16 lastAngle;
+ int16 newAngle;
+ int16 angleDif;
+ int16 computedAngle;
+
+ lastAngle = *(int16 *)(lastKeyFramePtr);
+ lastKeyFramePtr += 2;
+
+ newAngle = *(int16 *)(keyFramePtr);
+ keyFramePtr += 2;
+
+ lastAngle &= 0x3FF;
+ newAngle &= 0x3FF;
+
+ angleDif = newAngle - lastAngle;
+
+ if (angleDif) {
+ if (angleDif < -0x200) {
+ angleDif += 0x400;
+ } else if (angleDif > 0x200) {
+ angleDif -= 0x400;
+ }
+
+ computedAngle = lastAngle + (angleDif * bp) / bx;
+ } else {
+ computedAngle = lastAngle;
+ }
+
+ dest = (int16 *) * (ptr);
+ *dest = computedAngle & 0x3FF;
+ *(ptr) = *(ptr) + 2;
+}
+
+/** Apply animation step */
+void applyAnimStep(uint8 **ptr, int32 bp, int32 bx) {
+ int16 *dest;
+ int16 lastAngle;
+ int16 newAngle;
+ int16 angleDif;
+ int16 computedAngle;
+
+ lastAngle = *(int16 *) lastKeyFramePtr;
+ lastKeyFramePtr += 2;
+
+ newAngle = *(int16 *) keyFramePtr;
+ keyFramePtr += 2;
+
+ angleDif = newAngle - lastAngle;
+
+ if (angleDif) {
+ computedAngle = lastAngle + (angleDif * bp) / bx;
+ } else {
+ computedAngle = lastAngle;
+ }
+
+ dest = (int16 *) * (ptr);
+ *dest = computedAngle;
+ *(ptr) = *(ptr) + 2;
+}
+
+/** Get animation mode */
+int32 getAnimMode(uint8 **ptr) {
+ int16 *lptr;
+ int16 opcode;
+
+ lptr = (int16 *) * ptr;
+
+ opcode = *(int16 *)(keyFramePtr);
+ *(int16 *)(lptr) = opcode;
+
+ keyFramePtr += 2;
+ *(ptr) = *(ptr) + 2;
+ lastKeyFramePtr += 2;
+
+ return opcode;
+}
+
+/** Set new body animation
+ @param animIdx Animation index
+ @param animPtr Animation pointer
+ @param bodyPtr Body model poitner
+ @param animTimerDataPtr Animation time data */
+int32 setModelAnimation(int32 animState, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr) {
+ int16 animOpcode;
+
+ int16 bodyHeader;
+
+ uint8 *edi;
+ uint8 *ebx;
+ int32 ebp;
+ int32 eax;
+ int32 keyFrameLength;
+ int32 numOfPointInBody;
+ int32 numOfPointInAnim;
+ uint8 *keyFramePtrOld;
+
+ numOfPointInAnim = *(int16 *)(animPtr + 2);
+
+ keyFramePtr = ((numOfPointInAnim * 8 + 8) * animState) + animPtr + 8;
+
+ keyFrameLength = *(int16 *)(keyFramePtr);
+
+ bodyHeader = *(int16 *)(bodyPtr);
+
+ if (!(bodyHeader & 2)) {
+ return 0;
+ }
+
+ edi = bodyPtr + 16;
+
+ ebx = animTimerDataPtr->ptr;
+ ebp = animTimerDataPtr->time;
+
+ if (!ebx) {
+ ebx = keyFramePtr;
+ ebp = keyFrameLength;
+ }
+
+ lastKeyFramePtr = ebx;
+
+ eax = *(int16 *)(edi - 2);
+ edi += eax;
+
+ eax = *(int16 *)(edi);
+ eax = eax + eax * 2;
+ edi = edi + eax * 2 + 12;
+
+ numOfPointInBody = *(int16 *)(edi - 10);
+
+ if (numOfPointInAnim > numOfPointInBody) {
+ numOfPointInAnim = numOfPointInBody;
+ }
+
+ eax = lbaTime - ebp;
+
+ if (eax >= keyFrameLength) {
+ int32 *destPtr; // keyFrame
+ int32 *sourcePtr;
+
+ sourcePtr = (int32 *)(keyFramePtr + 8);
+ destPtr = (int32 *) edi;
+
+ do {
+ *(destPtr++) = *(sourcePtr++);
+ *(destPtr++) = *(sourcePtr++);
+ destPtr = (int32 *)(((int8 *)destPtr) + 30);
+ } while (--numOfPointInAnim);
+
+ animTimerDataPtr->ptr = keyFramePtr;
+ animTimerDataPtr->time = lbaTime;
+
+ currentStepX = *(int16 *)(keyFramePtr + 2);
+ currentStepY = *(int16 *)(keyFramePtr + 4);
+ currentStepZ = *(int16 *)(keyFramePtr + 6);
+
+ processRotationByAnim = *(int16 *)(keyFramePtr + 8);
+ processLastRotationAngle = *(int16 *)(keyFramePtr + 12);
+
+ return 1;
+ } else {
+ keyFramePtrOld = keyFramePtr;
+
+ lastKeyFramePtr += 8;
+ keyFramePtr += 8;
+
+ processRotationByAnim = *(int16 *)(keyFramePtr);
+ processLastRotationAngle = (*(int16 *)(keyFramePtr + 4) * eax) / keyFrameLength;
+
+ lastKeyFramePtr += 8;
+ keyFramePtr += 8;
+
+ edi += 38;
+
+ if (--numOfPointInAnim) {
+ int16 tmpNumOfPoints = numOfPointInAnim;
+
+ do {
+ animOpcode = getAnimMode(&edi);
+
+ switch (animOpcode) {
+ case 0: { // allow global rotate
+ applyAnimStepRotation(&edi, eax, keyFrameLength);
+ applyAnimStepRotation(&edi, eax, keyFrameLength);
+ applyAnimStepRotation(&edi, eax, keyFrameLength);
+ break;
+ }
+ case 1: { // dissallow global rotate
+ applyAnimStep(&edi, eax, keyFrameLength);
+ applyAnimStep(&edi, eax, keyFrameLength);
+ applyAnimStep(&edi, eax, keyFrameLength);
+ break;
+ }
+ case 2: { // dissallow global rotate + hide
+ applyAnimStep(&edi, eax, keyFrameLength);
+ applyAnimStep(&edi, eax, keyFrameLength);
+ applyAnimStep(&edi, eax, keyFrameLength);
+ break;
+ }
+ default: {
+ printf("Unsupported animation rotation mode %d!\n", animOpcode);
+ exit(1);
+ }
+ }
+
+ edi += 30;
+ } while (--tmpNumOfPoints);
+ }
+
+ currentStepX = (*(int16 *)(keyFramePtrOld + 2) * eax) / keyFrameLength;
+ currentStepY = (*(int16 *)(keyFramePtrOld + 4) * eax) / keyFrameLength;
+ currentStepZ = (*(int16 *)(keyFramePtrOld + 6) * eax) / keyFrameLength;
+ }
+
+ return 0;
+}
+
+/** Get entity anim index (This is taken from File3D entities)
+ @param anim Entity animation index
+ @param actorIdx Actor index */
+int32 getBodyAnimIndex(int32 animIdx, int32 actorIdx) {
+ int8 type;
+ uint16 realAnimIdx;
+ uint8 *bodyPtr;
+ uint8 *ptr, *ptr2;
+ uint8 *costumePtr = NULL;
+ ActorStruct *actor;
+
+ actor = &sceneActors[actorIdx];
+ bodyPtr = actor->entityDataPtr;
+
+ do {
+ type = *(bodyPtr++);
+
+ if (type == -1) {
+ currentActorAnimExtraPtr = NULL;
+ return -1;
+ }
+
+ ptr = (bodyPtr + 1);
+
+ if (type == 3) {
+ if (animIdx == *bodyPtr) {
+ ptr++;
+ realAnimIdx = *(int16 *)(ptr);
+ ptr += 2;
+ ptr2 = ptr;
+ ptr++;
+ if (*ptr2 != 0) {
+ costumePtr = ptr - 1;
+ }
+ currentActorAnimExtraPtr = costumePtr;
+ return realAnimIdx;
+ }
+ }
+
+ bodyPtr = *ptr + ptr;
+
+ } while (1);
+
+ return 0;
+}
+
+/** Stock animation - copy the next keyFrame from a different buffer
+ @param animPtr Animation pointer
+ @param bodyPtr Body model poitner
+ @param animTimerDataPtr Animation time data */
+int32 stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr) {
+ int32 playAnim;
+ uint8 *ptr;
+ int32 *edi;
+ int32 *esi;
+ int32 var0;
+ int32 var1;
+ int32 var2;
+ int32 counter;
+
+ playAnim = *(int16 *)(bodyPtr);
+
+ if (playAnim & 2) {
+ ptr = (bodyPtr + 0x10);
+
+ animTimerDataPtr->time = lbaTime;
+ animTimerDataPtr->ptr = animPtr;
+
+ var0 = *(int16 *)(ptr - 2);
+ ptr = ptr + var0;
+
+ var1 = *(int16 *)(ptr);
+ var1 = var1 + var1 * 2;
+
+ ptr = ptr + var1 * 2 + 2;
+
+ var2 = *(int16 *)(ptr);
+ counter = var2;
+ var2 = (var2 * 8) + 8;
+
+ edi = (int32 *)(animPtr + 8);
+ esi = (int32 *)(ptr + 10);
+
+ do {
+ *(edi++) = *(esi++);
+ *(edi++) = *(esi++);
+
+ esi = (int32 *)(((int8 *) esi) + 30);
+ } while (counter--);
+
+ return var2;
+ }
+ return 0;
+}
+
+/** Verify animation at keyframe
+ @param animIdx Animation index
+ @param animPtr Animation pointer
+ @param bodyPtr Body model poitner
+ @param animTimerDataPtr Animation time data */
+int32 verifyAnimAtKeyframe(int32 animIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr) {
+ int16 bodyHeader;
+
+ uint8 *ebx;
+ int32 ebp;
+ int32 eax;
+ int32 keyFrameLength;
+ int32 numOfPointInAnim = -1;
+ uint8 *keyFramePtrOld;
+
+ numOfPointInAnim = *(int16 *)(animPtr + 2);
+
+ keyFramePtr = ((numOfPointInAnim * 8 + 8) * animIdx) + animPtr + 8;
+
+ keyFrameLength = *(int16 *)(keyFramePtr);
+
+ bodyHeader = *(int16 *)(bodyPtr);
+
+ if (!(bodyHeader & 2)) {
+ return 0;
+ }
+
+ ebx = animTimerDataPtr->ptr;
+ ebp = animTimerDataPtr->time;
+
+ if (!ebx) {
+ ebx = keyFramePtr;
+ ebp = keyFrameLength;
+ }
+
+ lastKeyFramePtr = ebx;
+
+ eax = lbaTime - ebp;
+
+ if (eax >= keyFrameLength) {
+ animTimerDataPtr->ptr = keyFramePtr;
+ animTimerDataPtr->time = lbaTime;
+
+ currentStepX = *(int16 *)(keyFramePtr + 2);
+ currentStepY = *(int16 *)(keyFramePtr + 4);
+ currentStepZ = *(int16 *)(keyFramePtr + 6);
+
+ processRotationByAnim = *(int16 *)(keyFramePtr + 8);
+ processLastRotationAngle = *(int16 *)(keyFramePtr + 12);
+
+ return 1;
+ } else {
+ keyFramePtrOld = keyFramePtr;
+
+ lastKeyFramePtr += 8;
+ keyFramePtr += 8;
+
+ processRotationByAnim = *(int16 *)(keyFramePtr);
+ processLastRotationAngle = (*(int16 *)(keyFramePtr + 4) * eax) / keyFrameLength;
+
+ lastKeyFramePtr += 8;
+ keyFramePtr += 8;
+
+ currentStepX = (*(int16 *)(keyFramePtrOld + 2) * eax) / keyFrameLength;
+ currentStepY = (*(int16 *)(keyFramePtrOld + 4) * eax) / keyFrameLength;
+ currentStepZ = (*(int16 *)(keyFramePtrOld + 6) * eax) / keyFrameLength;
+ }
+
+ return 0;
+}
+
+//--------------------------------
+//helper class
+struct _DataReader {
+ uint8* ptr;
+};
+typedef struct _DataReader DataReader;
+
+int8 readByte(DataReader* data){
+ return *(data->ptr++);
+}
+
+int16 readWord(DataReader* data){
+ int16 result;
+ result = *(int16 *)(data->ptr);
+ data->ptr += 2;
+ return result;
+}
+//--------------------------------
+
+void skipBytes(DataReader* data, int n){
+ data->ptr += n;
+}
+
+/** Process acotr animation actions
+ @param actorIdx Actor index */
+void processAnimActions(int32 actorIdx) {
+ int32 index=0, endAnimEntityIdx, actionType, animPos;
+ ActorStruct *actor;
+ DataReader* data;
+
+ actor = &sceneActors[actorIdx];
+ if (!actor->animExtraPtr) return; // avoid null pointers
+
+ data = (DataReader*) malloc(sizeof(DataReader));
+ data->ptr = actor->animExtraPtr;
+
+ endAnimEntityIdx = readByte(data);
+ while (index++ < endAnimEntityIdx) {
+ actionType = readByte(data) - 5;
+ if (actionType >= ACTION_LAST) return;
+
+ switch (actionType) {
+ case ACTION_HITTING:
+ {
+ int8 strength;
+
+ animPos = readByte(data) - 1;
+ strength = readByte(data);
+
+ if (animPos == actor->animPosition) {
+ actor->strengthOfHit = strength;
+ actor->dynamicFlags.bIsHitting = 1;
+ }
+ }
+ break;
+ case ACTION_SAMPLE:
+ {
+ int16 sampleIdx;
+
+ animPos = readByte(data);
+ sampleIdx = readWord(data);
+
+ if (animPos == actor->animPosition)
+ playSample(sampleIdx, 0x1000, 1, actor->X, actor->Y, actor->Z, actorIdx);
+ }
+ break;
+ case ACTION_SAMPLE_FREQ:
+ {
+ int16 sampleIdx, frequency;
+
+ animPos = readByte(data);
+ sampleIdx = readWord(data);
+ frequency = readWord(data);
+
+ if (animPos == actor->animPosition) {
+ frequency = Rnd(frequency) + 0x1000 - (Abs(frequency) >> 1);
+ playSample(sampleIdx, frequency, 1, actor->X, actor->Y, actor->Z, actorIdx);
+ }
+ }
+ break;
+ case ACTION_THROW_EXTRA_BONUS:
+ {
+ int32 yHeight, var_C, var_24, var_14, cx, dx, var;
+
+ animPos = readByte(data);
+ yHeight = readWord(data);
+ var_C = readByte(data);
+ cx = readWord(data);
+ dx = actor->angle + readWord(data);
+ var_24 = readWord(data);
+ var_14 = readByte(data);
+ var = readByte(data);
+
+ if (animPos == actor->animPosition)
+ addExtraThrow(actorIdx, actor->X, actor->Y + yHeight, actor->Z, var_C, cx, dx, var_24, var_14, var);
+ }
+ break;
+ case ACTION_THROW_MAGIC_BALL:
+ {
+ int32 var_8, dx, var_24, var_14;
+
+ animPos = readByte(data);
+ var_8 = readWord(data);
+ dx = readWord(data);
+ var_24 = readWord(data);
+ var_14 = readByte(data);
+
+ if (magicBallIdx == -1 && animPos == actor->animPosition)
+ addExtraThrowMagicball(actor->X, actor->Y + var_8, actor->Z, dx, actor->angle, var_24, var_14);
+ }
+ break;
+ case ACTION_SAMPLE_REPEAT:
+ {
+ int16 sampleIdx, repeat;
+
+ animPos = readByte(data);
+ sampleIdx = readWord(data);
+ repeat = readWord(data);
+
+ if (animPos == actor->animPosition)
+ playSample(sampleIdx, 0x1000, repeat, actor->X, actor->Y, actor->Z, actorIdx);
+ }
+ break;
+ case ACTION_UNKNOWN_6:
+ animPos = readByte(data);
+ if (animPos == actor->animPosition) {
+ int32 var_8, var_C, dx, var_24, temp;
+
+ //The folowing fetches 7 bytes, but the else block skips only 6 bytes.
+ // Please check if that's correct.
+ var_8 = readWord(data);
+ var_C = readByte(data);
+ dx = readByte(data);
+ var_24 = readWord(data);
+ temp = readByte(data);
+
+ addExtraAiming(actorIdx, actor->X, actor->Y + var_8, actor->Z, var_C, dx, var_24, temp);
+ } else {
+ skipBytes(data, 6);
+ }
+ break;
+ case ACTION_UNKNOWN_7:
+ {
+ int32 yHeight, var_C, var_24, var_14, cx, dx, var;
+
+ animPos = readByte(data);
+ yHeight = readWord(data);
+ var_C = readByte(data);
+ dx = readWord(data);
+ cx = actor->angle + readWord(data);
+ var_24 = readWord(data);
+ var_14 = readByte(data);
+ var = readByte(data);
+
+ if (animPos == actor->animPosition)
+ addExtraThrow(actorIdx, actor->X, actor->Y + yHeight, actor->Z, var_C, dx, cx, var_24, var_14, var);
+ }
+ break;
+ case ACTION_SAMPLE_STOP:
+ {
+ int32 sampleIdx;
+
+ animPos = readByte(data);
+ sampleIdx = readByte(data); //why is it reading a byte but saving it in a 32bit variable?
+ skipBytes(data, 1); //what is the meaning of this extra byte?
+
+ if (animPos == actor->animPosition) {
+ stopSample(sampleIdx);
+ }
+ }
+ break;
+ case ACTION_SAMPLE_BRICK_1:
+ animPos = readByte(data);
+ if (animPos == actor->animPosition && (actor->brickSound & 0x0F0) != 0x0F0) {
+ int16 sampleIdx = (actor->brickSound & 0x0F) + 126;
+ playSample(sampleIdx, Rnd(1000) + 3596, 1, actor->X, actor->Y, actor->Z, actorIdx);
+ }
+ break;
+ case ACTION_SAMPLE_BRICK_2:
+ animPos = readByte(data);
+ if (animPos == actor->animPosition && (actor->brickSound & 0x0F0) != 0x0F0) {
+ int16 sampleIdx = (actor->brickSound & 0x0F) + 126;
+ playSample(sampleIdx, Rnd(1000) + 3596, 1, actor->X, actor->Y, actor->Z, actorIdx);
+ }
+ break;
+ case ACTION_HERO_HITTING:
+ animPos = readByte(data) - 1;
+ if (animPos == actor->animPosition) {
+ actor->strengthOfHit = magicLevelStrengthOfHit[magicLevelIdx];
+ actor->dynamicFlags.bIsHitting = 1;
+ }
+ break;
+ case ACTION_UNKNOWN_13:
+ {
+ int32 throwX, throwY, throwZ;
+ int32 distanceX, distanceY, distanceZ;
+ int32 spriteIdx, strength;
+ int32 param1, param2, param3, param4;
+
+ animPos = readByte(data);
+ distanceX = readWord(data);
+ distanceY = readWord(data);
+ distanceZ = readWord(data);
+
+ spriteIdx = readByte(data);
+
+ param1 = readWord(data);
+ param2 = readWord(data);
+ param3 = readWord(data);
+ param4 = readByte(data);
+
+ strength = readByte(data);
+
+ if (animPos == actor->animPosition) {
+ rotateActor(distanceX, distanceZ, actor->angle);
+
+ throwX = destX + actor->X;
+ throwY = distanceY + actor->Y;
+ throwZ = destZ + actor->Z;
+
+ addExtraThrow(actorIdx, throwX, throwY, throwZ, spriteIdx,
+ param1, param2 + actor->angle, param3, param4, strength);
+ }
+ }
+ break;
+ case ACTION_UNKNOWN_14:
+ {
+ int32 newAngle, throwX, throwY, throwZ;
+ int32 distanceX, distanceY, distanceZ;
+ int32 spriteIdx, strength;
+ int32 param1, param2, param3, param4;
+
+ animPos = readByte(data);
+ distanceX = readWord(data);
+ distanceY = readWord(data);
+ distanceZ = readWord(data);
+
+ spriteIdx = readByte(data);
+
+ param1 = readWord(data);
+ param2 = readWord(data);
+ param3 = readWord(data);
+ param4 = readByte(data);
+
+ strength = readByte(data);
+
+ if (animPos == actor->animPosition) {
+ newAngle = getAngleAndSetTargetActorDistance(actor->Y, 0, sceneHero->Y, getDistance2D(actor->X, actor->Z, sceneHero->X, sceneHero->Z));
+
+ rotateActor(distanceX, distanceZ, actor->angle);
+
+ throwX = destX + actor->X;
+ throwY = distanceY + actor->Y;
+ throwZ = destZ + actor->Z;
+
+ addExtraThrow(actorIdx, throwX, throwY, throwZ, spriteIdx,
+ param1 + newAngle, param2 + actor->angle, param3, param4, strength);
+ }
+ }
+ break;
+ case ACTION_UNKNOWN_15:
+ {
+ int32 distanceX, distanceY, distanceZ;
+ int32 spriteIdx, targetActor, param3, param4;
+
+ animPos = readByte(data);
+ distanceX = readWord(data);
+ distanceY = readWord(data);
+ distanceZ = readWord(data);
+ spriteIdx = readByte(data);
+ targetActor = readByte(data);
+ param3 = readWord(data);
+ param4 = readByte(data);
+
+ if (animPos == actor->animPosition) {
+ rotateActor( distanceX, distanceZ, actor->angle);
+ addExtraAiming(actorIdx, actor->X + destX, actor->Y + distanceY, actor->Z + distanceZ, spriteIdx,
+ targetActor, param3, param4);
+ }
+ }
+ break;
+ case ACTION_UNKNOWN_9:
+ break;
+ default:
+ break;
+ }
+ }
+ free(data);
+}
+
+/** Initialize animation
+ @param newAnim animation to init
+ @param animType animation type
+ @param animExtra animation actions extra data
+ @param actorIdx actor index */
+int32 initAnim(int32 newAnim, int16 animType, uint8 animExtra, int32 actorIdx) {
+ ActorStruct *actor;
+ int32 animIndex;
+
+ actor = &sceneActors[actorIdx];
+
+ if (actor->entity == -1)
+ return 0;
+
+ if (actor->staticFlags.bIsSpriteActor)
+ return 0;
+
+ if (newAnim == actor->anim && actor->previousAnimIdx != -1)
+ return 1;
+
+ if (animExtra == 255 && actor->animType != 2)
+ animExtra = actor->anim;
+
+ animIndex = getBodyAnimIndex(newAnim, actorIdx);
+
+ if (animIndex == -1)
+ animIndex = getBodyAnimIndex(0, actorIdx);
+
+ if (animType != 4 && actor->animType == 2) {
+ actor->animExtra = newAnim;
+ return 0;
+ }
+
+ if (animType == 3) {
+ animType = 2;
+
+ animExtra = actor->anim;
+
+ if (animExtra == 15 || animExtra == 7 || animExtra == 8 || animExtra == 9) {
+ animExtra = 0;
+ }
+ }
+
+ if (animType == 4)
+ animType = 2;
+
+ if (actor->previousAnimIdx == -1) { // if no previous animation
+ setAnimAtKeyframe(0, animTable[animIndex], bodyTable[actor->entity], &actor->animTimerData);
+ } else { // interpolation between animations
+ animBuffer2 += stockAnimation(animBuffer2, bodyTable[actor->entity], &actor->animTimerData);
+ if (animBuffer1 + 4488 < animBuffer2)
+ animBuffer2 = animBuffer1;
+ }
+
+ actor->previousAnimIdx = animIndex;
+ actor->anim = newAnim;
+ actor->animExtra = animExtra;
+ actor->animExtraPtr = currentActorAnimExtraPtr;
+ actor->animType = animType;
+ actor->animPosition = 0;
+ actor->dynamicFlags.bIsHitting = 0;
+ actor->dynamicFlags.bAnimEnded = 0;
+ actor->dynamicFlags.bAnimFrameReached = 1;
+
+ if (actor->animExtraPtr) {
+ processAnimActions(actorIdx);
+ }
+
+ actor->lastRotationAngle = 0;
+ actor->lastX = 0;
+ actor->lastY = 0;
+ actor->lastZ = 0;
+
+ return 1;
+}
+
+/** Process main loop actor animations
+ @param actorIdx Actor index */
+void processActorAnimations(int32 actorIdx) { // DoAnim
+ int16 numKeyframe;
+ uint8 *animPtr;
+ ActorStruct *actor;
+
+ actor = &sceneActors[actorIdx];
+
+ currentlyProcessedActorIdx = actorIdx;
+ processActorPtr = actor;
+
+ if (actor->entity == -1)
+ return;
+
+ previousActorX = actor->collisionX;
+ previousActorY = actor->collisionY;
+ previousActorZ = actor->collisionZ;
+
+ if (actor->staticFlags.bIsSpriteActor) { // is sprite actor
+ if (actor->strengthOfHit) {
+ actor->dynamicFlags.bIsHitting = 1;
+ }
+
+ processActorX = actor->X;
+ processActorY = actor->Y;
+ processActorZ = actor->Z;
+
+ if (!actor->dynamicFlags.bIsFalling) {
+ if (actor->speed) {
+ int32 angle = getRealValue(&actor->move);
+ if (!angle) {
+ if (actor->move.to > 0) {
+ angle = 1;
+ } else {
+ angle = -1;
+ }
+ }
+
+ rotateActor(angle, 0, actor->animType);
+
+ processActorY = actor->Y - destZ;
+
+ rotateActor(0, destX, actor->angle);
+
+ processActorX = actor->X + destX;
+ processActorZ = actor->Z + destZ;
+
+ setActorAngle(0, actor->speed, 50, &actor->move);
+
+ if (actor->dynamicFlags.bIsSpriteMoving) {
+ if (actor->doorStatus) { // open door
+ if (getDistance2D(processActorX, processActorZ, actor->lastX, actor->lastZ) >= actor->doorStatus) {
+ if (actor->angle == 0) {
+ processActorZ = actor->lastZ + actor->doorStatus;
+ } else if (actor->angle == 0x100) {
+ processActorX = actor->lastX + actor->doorStatus;
+ } else if (actor->angle == 0x200) {
+ processActorZ = actor->lastZ - actor->doorStatus;
+ } else if (actor->angle == 0x300) {
+ processActorX = actor->lastX - actor->doorStatus;
+ }
+
+ actor->dynamicFlags.bIsSpriteMoving = 0;
+ actor->speed = 0;
+ }
+ } else { // close door
+ int16 updatePos = 0;
+
+ if (actor->angle == 0) {
+ if (processActorZ <= actor->lastZ) {
+ updatePos = 1;
+ }
+ } else if (actor->angle == 0x100) {
+ if (processActorX <= actor->lastX) {
+ updatePos = 1;
+ }
+ } else if (actor->angle == 0x200) {
+ if (processActorZ >= actor->lastZ) {
+ updatePos = 1;
+ }
+ } else if (actor->angle == 0x300) {
+ if (processActorX >= actor->lastX) {
+ updatePos = 1;
+ }
+ }
+
+ if (updatePos) {
+ processActorX = actor->lastX;
+ processActorY = actor->lastY;
+ processActorZ = actor->lastZ;
+
+ actor->dynamicFlags.bIsSpriteMoving = 0;
+ actor->speed = 0;
+ }
+ }
+ }
+ }
+
+ if (actor->staticFlags.bCanBePushed) {
+ processActorX += actor->lastX;
+ processActorY += actor->lastY;
+ processActorZ += actor->lastZ;
+
+ if (actor->staticFlags.bUseMiniZv) {
+ processActorX = ((processActorX / 128) * 128);
+ processActorZ = ((processActorZ / 128) * 128);
+ }
+
+ actor->lastX = 0;
+ actor->lastY = 0;
+ actor->lastZ = 0;
+ }
+ }
+ } else { // 3D actor
+ if (actor->previousAnimIdx != -1) {
+ int32 keyFramePassed;
+ animPtr = animTable[actor->previousAnimIdx];
+
+ keyFramePassed = verifyAnimAtKeyframe(actor->animPosition, animPtr, bodyTable[actor->entity], &actor->animTimerData);
+
+ if (processRotationByAnim) {
+ actor->dynamicFlags.bIsRotationByAnim = 1;
+ } else {
+ actor->dynamicFlags.bIsRotationByAnim = 0;
+ }
+
+ actor->angle = (actor->angle + processLastRotationAngle - actor->lastRotationAngle) & 0x3FF;
+ actor->lastRotationAngle = processLastRotationAngle;
+
+ rotateActor(currentStepX, currentStepZ, actor->angle);
+
+ currentStepX = destX;
+ currentStepZ = destZ;
+
+ processActorX = actor->X + currentStepX - actor->lastX;
+ processActorY = actor->Y + currentStepY - actor->lastY;
+ processActorZ = actor->Z + currentStepZ - actor->lastZ;
+
+ actor->lastX = currentStepX;
+ actor->lastY = currentStepY;
+ actor->lastZ = currentStepZ;
+
+ actor->dynamicFlags.bAnimEnded = 0;
+ actor->dynamicFlags.bAnimFrameReached = 0;
+
+ if (keyFramePassed) {
+ actor->animPosition++;
+
+ // if actor have animation actions to process
+ if (actor->animExtraPtr) {
+ processAnimActions(actorIdx);
+ }
+
+ numKeyframe = actor->animPosition;
+ if (numKeyframe == getNumKeyframes(animPtr)) {
+ actor->dynamicFlags.bIsHitting = 0;
+
+ if (actor->animType == 0) {
+ actor->animPosition = getStartKeyframe(animPtr);
+ } else {
+ actor->anim = actor->animExtra;
+ actor->previousAnimIdx = getBodyAnimIndex(actor->anim, actorIdx);
+
+ if (actor->previousAnimIdx == -1) {
+ actor->previousAnimIdx = getBodyAnimIndex(0, actorIdx);
+ actor->anim = 0;
+ }
+
+ actor->animExtraPtr = currentActorAnimExtraPtr;
+
+ actor->animType = 0;
+ actor->animPosition = 0;
+ actor->strengthOfHit = 0;
+ }
+
+ if (actor->animExtraPtr) {
+ processAnimActions(actorIdx);
+ }
+
+ actor->dynamicFlags.bAnimEnded = 1;
+ }
+
+ actor->lastRotationAngle = 0;
+
+ actor->lastX = 0;
+ actor->lastY = 0;
+ actor->lastZ = 0;
+ }
+ }
+ }
+
+ // actor standing on another actor
+ if (actor->standOn != -1) {
+ processActorX -= sceneActors[actor->standOn].collisionX;
+ processActorY -= sceneActors[actor->standOn].collisionY;
+ processActorZ -= sceneActors[actor->standOn].collisionZ;
+
+ processActorX += sceneActors[actor->standOn].X;
+ processActorY += sceneActors[actor->standOn].Y;
+ processActorZ += sceneActors[actor->standOn].Z;
+
+ if (!standingOnActor(actorIdx, actor->standOn)) {
+ actor->standOn = -1; // no longer standing on other actor
+ }
+ }
+
+ // actor falling Y speed
+ if (actor->dynamicFlags.bIsFalling) {
+ processActorX = previousActorX;
+ processActorY = previousActorY + loopActorStep; // add step to fall
+ processActorZ = previousActorZ;
+ }
+
+ // actor collisions with bricks
+ if (actor->staticFlags.bComputeCollisionWithBricks) {
+ int32 brickShape;
+ collisionY = 0;
+
+ brickShape = getBrickShape(previousActorX, previousActorY, previousActorZ);
+
+ if (brickShape) {
+ if (brickShape != kSolid) {
+ reajustActorPosition(brickShape);
+ } /*else { // this shouldn't happen (collision should avoid it)
+ actor->Y = processActorY = (processActorY / 256) * 256 + 256; // go upper
+ }*/
+ }
+
+ if (actor->staticFlags.bComputeCollisionWithObj) {
+ checkCollisionWithActors(actorIdx);
+ }
+
+ if (actor->standOn != -1 && actor->dynamicFlags.bIsFalling) {
+ stopFalling();
+ }
+
+ causeActorDamage = 0;
+
+ processCollisionX = processActorX;
+ processCollisionY = processActorY;
+ processCollisionZ = processActorZ;
+
+ if (!actorIdx && !actor->staticFlags.bComputeLowCollision) {
+ // check hero collisions with bricks
+ checkHeroCollisionWithBricks(actor->boudingBox.X.bottomLeft, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.bottomLeft, 1);
+ checkHeroCollisionWithBricks(actor->boudingBox.X.topRight, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.bottomLeft, 2);
+ checkHeroCollisionWithBricks(actor->boudingBox.X.topRight, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.topRight, 4);
+ checkHeroCollisionWithBricks(actor->boudingBox.X.bottomLeft, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.topRight, 8);
+ } else {
+ // check other actors collisions with bricks
+ checkActorCollisionWithBricks(actor->boudingBox.X.bottomLeft, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.bottomLeft, 1);
+ checkActorCollisionWithBricks(actor->boudingBox.X.topRight, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.bottomLeft, 2);
+ checkActorCollisionWithBricks(actor->boudingBox.X.topRight, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.topRight, 4);
+ checkActorCollisionWithBricks(actor->boudingBox.X.bottomLeft, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.topRight, 8);
+ }
+
+ // process wall hit while running
+ if (causeActorDamage && !actor->dynamicFlags.bIsFalling && !currentlyProcessedActorIdx && heroBehaviour == kAthletic && actor->anim == kForward) {
+ rotateActor(actor->boudingBox.X.bottomLeft, actor->boudingBox.Z.bottomLeft, actor->angle + 0x580);
+
+ destX += processActorX;
+ destZ += processActorZ;
+
+ if (destX >= 0 && destZ >= 0 && destX <= 0x7E00 && destZ <= 0x7E00) {
+ if (getBrickShape(destX, processActorY + 0x100, destZ) && cfgfile.WallCollision == 1) { // avoid wall hit damage
+ addExtraSpecial(actor->X, actor->Y + 1000, actor->Z, kHitStars);
+ initAnim(kBigHit, 2, 0, currentlyProcessedActorIdx);
+
+ if (currentlyProcessedActorIdx == 0) {
+ heroMoved = 1;
+ }
+
+ actor->life--;
+ }
+ }
+ }
+
+ brickShape = getBrickShape(processActorX, processActorY, processActorZ);
+ actor->brickShape = brickShape;
+
+ if (brickShape) {
+ if (brickShape == kSolid) {
+ if (actor->dynamicFlags.bIsFalling) {
+ stopFalling();
+ processActorY = (collisionY << 8) + 0x100;
+ } else {
+ if (!actorIdx && heroBehaviour == kAthletic && actor->anim == brickShape && cfgfile.WallCollision == 1) { // avoid wall hit damage
+ addExtraSpecial(actor->X, actor->Y + 1000, actor->Z, kHitStars);
+ initAnim(kBigHit, 2, 0, currentlyProcessedActorIdx);
+
+ if (!actorIdx) {
+ heroMoved = 1;
+ }
+
+ actor->life--;
+ }
+
+ // no Z coordinate issue
+ if (!getBrickShape(processActorX, processActorY, previousActorZ)) {
+ processActorZ = previousActorZ;
+ }
+
+ // no X coordinate issue
+ if (!getBrickShape(previousActorX, processActorY, processActorZ)) {
+ processActorX = previousActorX;
+ }
+
+ // X and Z with issue, no move
+ if (getBrickShape(processActorX, processActorY, previousActorZ) && getBrickShape(previousActorX, processActorY, processActorZ)) {
+ return;
+ }
+ }
+ } else {
+ if (actor->dynamicFlags.bIsFalling) {
+ stopFalling();
+ }
+
+ reajustActorPosition(brickShape);
+ }
+
+ actor->dynamicFlags.bIsFalling = 0;
+ } else {
+ if (actor->staticFlags.bCanFall && actor->standOn == -1) {
+ brickShape = getBrickShape(processActorX, processActorY - 1, processActorZ);
+
+ if (brickShape) {
+ if (actor->dynamicFlags.bIsFalling) {
+ stopFalling();
+ }
+
+ reajustActorPosition(brickShape);
+ } else {
+ if (!actor->dynamicFlags.bIsRotationByAnim) {
+ actor->dynamicFlags.bIsFalling = 1;
+
+ if (!actorIdx && heroYBeforeFall == 0) {
+ heroYBeforeFall = processActorY;
+ }
+
+ initAnim(kFall, 0, 255, actorIdx);
+ }
+ }
+ }
+ }
+
+ // if under the map, than die
+ if (collisionY == -1) {
+ actor->life = 0;
+ }
+ } else {
+ if (actor->staticFlags.bComputeCollisionWithObj) {
+ checkCollisionWithActors(actorIdx);
+ }
+ }
+
+ if (causeActorDamage) {
+ actor->brickShape |= 0x80;
+ }
+
+ // check and fix actor bounding position
+ if (processActorX < 0) {
+ processActorX = 0;
+ }
+
+ if (processActorY < 0) {
+ processActorY = 0;
+ }
+
+ if (processActorZ < 0) {
+ processActorZ = 0;
+ }
+
+ if (processActorX > 0x7E00) {
+ processActorX = 0x7E00;
+ }
+
+ if (processActorZ > 0x7E00) {
+ processActorZ = 0x7E00;
+ }
+
+ actor->X = processActorX;
+ actor->Y = processActorY;
+ actor->Z = processActorZ;
+}
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
new file mode 100644
index 0000000000..ff07bac41b
--- /dev/null
+++ b/engines/twine/animations.h
@@ -0,0 +1,147 @@
+/** @file animations.h
+ @brief
+ This file contains 3D actors animations routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef ANIMATIONS_H
+#define ANIMATIONS_H
+
+#include "sys.h"
+#include "actor.h"
+
+/** Total number of animations allowed in the game */
+#define NUM_ANIMS 600
+
+enum AnimationTypes {
+ kStanding = 0,
+ kForward = 1,
+ kBackward = 2,
+ kTurnLeft = 3,
+ kTurnRight = 4,
+ kHit = 5,
+ kBigHit = 6,
+ kFall = 7,
+ kLanding = 8,
+ kLandingHit = 9,
+ kLandDeath = 10,
+ kAction = 11,
+ kClimbLadder = 12,
+ kTopLadder = 13,
+ kJump = 14,
+ kThrowBall = 15,
+ kHide = 16,
+ kKick = 17,
+ kRightPunch = 18,
+ kLeftPunch = 19,
+ kFoundItem = 20,
+ kDrawn = 21,
+ kHit2 = 22,
+ kSabreAttack = 23
+};
+
+
+/** Table with all loaded animations */
+uint8* animTable[NUM_ANIMS];
+/** Table with all loaded animations sizes */
+uint32 animSizeTable[NUM_ANIMS];
+
+/** Rotation by anim and not by engine */
+int16 processRotationByAnim; // processActorVar5
+/** Last rotation angle */
+int16 processLastRotationAngle; // processActorVar6
+/** Current process actor index */
+int16 currentlyProcessedActorIdx;
+
+/** Current step X coornidate */
+int16 currentStepX;
+/** Current step Y coornidate */
+int16 currentStepY;
+/** Current step Z coornidate */
+int16 currentStepZ;
+/** Current actor anim extra pointer */
+uint8 *currentActorAnimExtraPtr;
+
+/** Pointer to current animation keyframe */
+uint8 *keyFramePtr;
+/** Pointer to last animation keyframe */
+uint8 *lastKeyFramePtr;
+
+uint8 *animBuffer1;
+uint8 *animBuffer2;
+
+/** Set animation keyframe
+ @param keyframIdx Animation keyframe index
+ @param animPtr Pointer to animation
+ @param bodyPtr Body model poitner
+ @param animTimerDataPtr Animation time data */
+int32 setAnimAtKeyframe(int32 keyframeIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr);
+
+/** Get total number of keyframes in animation
+ @param animPtr Pointer to animation */
+int32 getNumKeyframes(uint8 *animPtr);
+
+/** Get first keyframes in animation
+ @param animPtr Pointer to animation */
+int32 getStartKeyframe(uint8 *animPtr);
+
+/** Set new body animation
+ @param animIdx Animation index
+ @param animPtr Animation pointer
+ @param bodyPtr Body model poitner
+ @param animTimerDataPtr Animation time data */
+int32 setModelAnimation(int32 animIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr);
+
+/** Get entity anim index (This is taken from File3D entities)
+ @param animIdx Entity animation index
+ @param actorIdx Actor index */
+int32 getBodyAnimIndex(int32 animIdx, int32 actorIdx);
+
+/** Stock animation - copy the next keyFrame from a different buffer
+ @param animPtr Animation pointer
+ @param bodyPtr Body model poitner
+ @param animTimerDataPtr Animation time data */
+int32 stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr);
+
+/** Verify animation at keyframe
+ @param animIdx Animation index
+ @param animPtr Animation pointer
+ @param bodyPtr Body model poitner
+ @param animTimerDataPtr Animation time data */
+int32 verifyAnimAtKeyframe(int32 animPos, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr);
+
+/** Initialize animation
+ @param newAnim animation to init
+ @param animType animation type
+ @param animExtra animation actions extra data
+ @param actorIdx actor index */
+int32 initAnim(int32 newAnim, int16 animType, uint8 animExtra, int32 actorIdx);
+
+/** Process acotr animation actions
+ @param actorIdx Actor index */
+void processAnimActions(int32 actorIdx);
+
+/** Process main loop actor animations
+ @param actorIdx Actor index */
+void processActorAnimations(int32 actorIdx);
+
+#endif
diff --git a/engines/twine/collision.cpp b/engines/twine/collision.cpp
new file mode 100644
index 0000000000..cf2663add0
--- /dev/null
+++ b/engines/twine/collision.cpp
@@ -0,0 +1,624 @@
+/** @file collision.cpp
+ @brief
+ This file contains movies routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+
+#include "collision.h"
+#include "scene.h"
+#include "actor.h"
+#include "movements.h"
+#include "grid.h"
+#include "main.h"
+#include "animations.h"
+#include "renderer.h"
+#include "extra.h"
+
+/** Check if actor 1 is standing in actor2
+ @param actorIdx1 Actor 1 index
+ @param actorIdx2 Actor 2 index */
+int32 standingOnActor(int32 actorIdx1, int32 actorIdx2) { // CheckZvOnZv
+ int32 x1Left, y1Left, z1Left, x1Right, y1Right, z1Right;
+ int32 x2Left, y2Left, z2Left, x2Right, y2Right, z2Right;
+ ActorStruct *actor1;
+ ActorStruct *actor2;
+
+ actor1 = &sceneActors[actorIdx1];
+ actor2 = &sceneActors[actorIdx2];
+
+ // Current actor (actor 1)
+ x1Left = processActorX + actor1->boudingBox.X.bottomLeft;
+ x1Right = processActorX + actor1->boudingBox.X.topRight;
+
+ y1Left = processActorY + actor1->boudingBox.Y.bottomLeft;
+ y1Right = processActorY + actor1->boudingBox.Y.topRight;
+
+ z1Left = processActorZ + actor1->boudingBox.Z.bottomLeft;
+ z1Right = processActorZ + actor1->boudingBox.Z.topRight;
+
+ // Actor 2
+ x2Left = actor2->X + actor2->boudingBox.X.bottomLeft;
+ x2Right = actor2->X + actor2->boudingBox.X.topRight;
+
+ y2Left = actor2->Y + actor2->boudingBox.Y.bottomLeft;
+ y2Right = actor2->Y + actor2->boudingBox.Y.topRight;
+
+ z2Left = actor2->Z + actor2->boudingBox.Z.bottomLeft;
+ z2Right = actor2->Z + actor2->boudingBox.Z.topRight;
+
+ if (x1Left >= x2Right)
+ return 0; // not standing
+
+ if (x1Right <= x2Left)
+ return 0;
+
+ if (y1Left > (y2Right + 1))
+ return 0;
+
+ if (y1Left <= (y2Right - 0x100))
+ return 0;
+
+ if (y1Right <= y2Left)
+ return 0;
+
+ if (z1Left >= z2Right)
+ return 0;
+
+ if (z1Right <= z2Left)
+ return 0;
+
+ return 1; // standing
+}
+
+int32 getAverageValue(int32 var0, int32 var1, int32 var2, int32 var3) {
+ if (var3 <= 0) {
+ return var0;
+ }
+
+ if (var3 >= var2) {
+ return var1;
+ }
+
+ return ((((var1 - var0) * var3) / var2) + var0);
+}
+
+/** Reajust actor position in scene according with brick shape bellow actor
+ @param brickShape Shape of brick bellow the actor */
+void reajustActorPosition(int32 brickShape) {
+ int32 brkX, brkY, brkZ;
+
+ if (!brickShape) {
+ return;
+ }
+
+ brkX = (collisionX << 9) - 0x100;
+ brkY = collisionY << 8;
+ brkZ = (collisionZ << 9) - 0x100;
+
+ // double-side stairs
+ if (brickShape >= kDoubleSideStairsTop1 && brickShape <= kDoubleSideStairsRight2) {
+ switch (brickShape) {
+ case kDoubleSideStairsTop1:
+ if (processActorZ - collisionZ <= processActorX - collisionX) {
+ brickShape = kStairsTopLeft;
+ } else {
+ brickShape = kStairsTopRight;
+ }
+ break;
+ case kDoubleSideStairsBottom1:
+ if (processActorZ - collisionZ <= processActorX - collisionX) {
+ brickShape = kStairsBottomLeft;
+ } else {
+ brickShape = kStairsBottomRight;
+ }
+ break;
+ case kDoubleSideStairsLeft1:
+ if (512 - processActorX - collisionX <= processActorZ - collisionZ) {
+ brickShape = kStairsTopLeft;
+ } else {
+ brickShape = kStairsBottomLeft;
+ }
+ break;
+ case kDoubleSideStairsRight1:
+ if (512 - processActorX - collisionX <= processActorZ - collisionZ) {
+ brickShape = kStairsTopRight;
+ } else {
+ brickShape = kStairsBottomRight;
+ }
+ break;
+ case kDoubleSideStairsTop2:
+ if (processActorX - collisionX >= processActorZ - collisionZ) {
+ brickShape = kStairsTopRight;
+ } else {
+ brickShape = kStairsTopLeft;
+ }
+ break;
+ case kDoubleSideStairsBottom2:
+ if (processActorZ - collisionZ <= processActorX - collisionX) {
+ brickShape = kStairsBottomRight;
+ } else {
+ brickShape = kStairsBottomLeft;
+ }
+ break;
+ case kDoubleSideStairsLeft2:
+ if (512 - processActorX - collisionX <= processActorZ - collisionZ) {
+ brickShape = kStairsBottomLeft;
+ } else {
+ brickShape = kStairsTopLeft;
+ }
+ break;
+ case kDoubleSideStairsRight2:
+ if (512 - processActorX - collisionX <= processActorZ - collisionZ) {
+ brickShape = kStairsBottomRight;
+ } else {
+ brickShape = kStairsTopRight;
+ }
+ break;
+ default:
+ if (cfgfile.Debug == 1) {
+ printf("Brick Shape %d unsupported\n", brickShape);
+ }
+ break;
+ }
+ }
+
+ if (brickShape >= kStairsTopLeft && brickShape <= kStairsBottomRight) {
+ switch (brickShape) {
+ case kStairsTopLeft:
+ processActorY = brkY + getAverageValue(0, 0x100, 0x200, processActorX - brkX);
+ break;
+ case kStairsTopRight:
+ processActorY = brkY + getAverageValue(0, 0x100, 0x200, processActorZ - brkZ);
+ break;
+ case kStairsBottomLeft:
+ processActorY = brkY + getAverageValue(0x100, 0, 0x200, processActorZ - brkZ);
+ break;
+ case kStairsBottomRight:
+ processActorY = brkY + getAverageValue(0x100, 0, 0x200, processActorX - brkX);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/** Check collision with actors
+ @param actorIx Current process actor index */
+int32 checkCollisionWithActors(int32 actorIdx) {
+ int32 a, xLeft, xRight, yLeft, yRight, zLeft, zRight;
+ ActorStruct *actor, *actorTest;
+
+ actor = &sceneActors[actorIdx];
+
+ xLeft = processActorX + actor->boudingBox.X.bottomLeft;
+ xRight = processActorX + actor->boudingBox.X.topRight;
+
+ yLeft = processActorY + actor->boudingBox.Y.bottomLeft;
+ yRight = processActorY + actor->boudingBox.Y.topRight;
+
+ zLeft = processActorZ + actor->boudingBox.Z.bottomLeft;
+ zRight = processActorZ + actor->boudingBox.Z.topRight;
+
+ actor->collision = -1;
+
+ for (a = 0; a < sceneNumActors; a++) {
+ actorTest = &sceneActors[a];
+
+ // aviod current processed actor
+ if (a != actorIdx && actorTest->entity != -1 && !actor->staticFlags.bComputeLowCollision && actorTest->standOn != actorIdx) {
+ int32 xLeftTest, xRightTest, yLeftTest, yRightTest, zLeftTest, zRightTest;
+
+ xLeftTest = actorTest->X + actorTest->boudingBox.X.bottomLeft;
+ xRightTest = actorTest->X + actorTest->boudingBox.X.topRight;
+
+ yLeftTest = actorTest->Y + actorTest->boudingBox.Y.bottomLeft;
+ yRightTest = actorTest->Y + actorTest->boudingBox.Y.topRight;
+
+ zLeftTest = actorTest->Z + actorTest->boudingBox.Z.bottomLeft;
+ zRightTest = actorTest->Z + actorTest->boudingBox.Z.topRight;
+
+ if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
+ actor->collision = a; // mark as collision with actor a
+
+ if (actorTest->staticFlags.bIsCarrierActor) {
+ if (actor->dynamicFlags.bIsFalling) {
+ processActorY = yRightTest - actor->boudingBox.Y.bottomLeft + 1;
+ actor->standOn = a;
+ } else {
+ if (standingOnActor(actorIdx, a)) {
+ processActorY = yRightTest - actor->boudingBox.Y.bottomLeft + 1;
+ actor->standOn = a;
+ } else {
+ int32 newAngle;
+
+ newAngle = getAngleAndSetTargetActorDistance(processActorX, processActorZ, actorTest->X, actorTest->Z);
+
+ if (actorTest->staticFlags.bCanBePushed && !actor->staticFlags.bCanBePushed) {
+ actorTest->lastY = 0;
+
+ if (actorTest->staticFlags.bUseMiniZv) {
+ if (newAngle >= 0x80 && newAngle < 0x180 && actor->angle > 0x80 && actor->angle < 0x180) {
+ actorTest->lastX = 192;
+ }
+ if (newAngle >= 0x180 && newAngle < 0x280 && actor->angle > 0x180 && actor->angle < 0x280) {
+ actorTest->lastZ = -64;
+ }
+ if (newAngle >= 0x280 && newAngle < 0x380 && actor->angle > 0x280 && actor->angle < 0x380) {
+ actorTest->lastX = -64;
+ }
+ if ((newAngle >= 0x380 || newAngle < 0x80) && (actor->angle > 0x380 || actor->angle < 0x80)) {
+ actorTest->lastX = 192;
+ }
+ } else {
+ actorTest->lastX = processActorX - actor->collisionX;
+ actorTest->lastZ = processActorZ - actor->collisionZ;
+ }
+ }
+
+ if ((actorTest->boudingBox.X.topRight - actorTest->boudingBox.X.bottomLeft == actorTest->boudingBox.Z.topRight - actorTest->boudingBox.Z.bottomLeft) &&
+ (actor->boudingBox.X.topRight - actor->boudingBox.X.bottomLeft == actor->boudingBox.Z.topRight - actor->boudingBox.Z.bottomLeft)) {
+ if (newAngle < 0x180) {
+ processActorX = xLeftTest - actor->boudingBox.X.topRight;
+ }
+ if (newAngle >= 0x180 && newAngle < 0x280) {
+ processActorZ = zRightTest - actor->boudingBox.Z.bottomLeft;
+ }
+ if (newAngle >= 0x280 && newAngle < 0x380) {
+ processActorX = xRightTest - actor->boudingBox.X.bottomLeft;
+ }
+ if (newAngle >= 0x380 || (newAngle < 0x380 && newAngle < 0x80)) {
+ processActorZ = zLeftTest - actor->boudingBox.Z.topRight;
+ }
+ } else {
+ if (!actor->dynamicFlags.bIsFalling) {
+ processActorX = previousActorX;
+ processActorY = previousActorY;
+ processActorZ = previousActorZ;
+ }
+ }
+ }
+ }
+ } else {
+ int32 newAngle;
+
+ if (standingOnActor(actorIdx, a)) {
+ hitActor(actorIdx, a, 1, -1);
+ }
+
+ newAngle = getAngleAndSetTargetActorDistance(processActorX, processActorZ, actorTest->X, actorTest->Z);
+
+ if (actorTest->staticFlags.bCanBePushed && !actor->staticFlags.bCanBePushed) {
+ actorTest->lastY = 0;
+
+ if (actorTest->staticFlags.bUseMiniZv) {
+ if (newAngle >= 0x80 && newAngle < 0x180 && actor->angle > 0x80 && actor->angle < 0x180) {
+ actorTest->lastX = 192;
+ }
+ if (newAngle >= 0x180 && newAngle < 0x280 && actor->angle > 0x180 && actor->angle < 0x280) {
+ actorTest->lastZ = -64;
+ }
+ if (newAngle >= 0x280 && newAngle < 0x380 && actor->angle > 0x280 && actor->angle < 0x380) {
+ actorTest->lastX = -64;
+ }
+ if ((newAngle >= 0x380 || newAngle < 0x80) && (actor->angle > 0x380 || actor->angle < 0x80)) {
+ actorTest->lastX = 192;
+ }
+ } else {
+ actorTest->lastX = processActorX - actor->collisionX;
+ actorTest->lastZ = processActorZ - actor->collisionZ;
+ }
+ }
+
+ if ((actorTest->boudingBox.X.topRight - actorTest->boudingBox.X.bottomLeft == actorTest->boudingBox.Z.topRight - actorTest->boudingBox.Z.bottomLeft) &&
+ (actor->boudingBox.X.topRight - actor->boudingBox.X.bottomLeft == actor->boudingBox.Z.topRight - actor->boudingBox.Z.bottomLeft)) {
+ if (newAngle < 0x180) {
+ processActorX = xLeftTest - actor->boudingBox.X.topRight;
+ }
+ if (newAngle >= 0x180 && newAngle < 0x280) {
+ processActorZ = zRightTest - actor->boudingBox.Z.bottomLeft;
+ }
+ if (newAngle >= 0x280 && newAngle < 0x380) {
+ processActorX = xRightTest - actor->boudingBox.X.bottomLeft;
+ }
+ if (newAngle >= 0x380 || (newAngle < 0x380 && newAngle < 0x80)) {
+ processActorZ = zLeftTest - actor->boudingBox.Z.topRight;
+ }
+ } else {
+ if (!actor->dynamicFlags.bIsFalling) {
+ processActorX = previousActorX;
+ processActorY = previousActorY;
+ processActorZ = previousActorZ;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (actor->dynamicFlags.bIsHitting) {
+ rotateActor(0, 200, actor->angle);
+
+ xLeft = destX + processActorX + actor->boudingBox.X.bottomLeft;
+ xRight = destX + processActorX + actor->boudingBox.X.topRight;
+
+ yLeft = processActorY + actor->boudingBox.Y.bottomLeft;
+ yRight = processActorY + actor->boudingBox.Y.topRight;
+
+ zLeft = destZ + processActorZ + actor->boudingBox.Z.bottomLeft;
+ zRight = destZ + processActorZ + actor->boudingBox.Z.topRight;
+
+ for (a = 0; a < sceneNumActors; a++) {
+ actorTest = &sceneActors[a];
+
+ // aviod current processed actor
+ if (a != actorIdx && actorTest->entity != -1 && !actorTest->staticFlags.bIsHidden && actorTest->standOn != actorIdx) {
+ int32 xLeftTest, xRightTest, yLeftTest, yRightTest, zLeftTest, zRightTest;
+
+ xLeftTest = actorTest->X + actorTest->boudingBox.X.bottomLeft;
+ xRightTest = actorTest->X + actorTest->boudingBox.X.topRight;
+
+ yLeftTest = actorTest->Y + actorTest->boudingBox.Y.bottomLeft;
+ yRightTest = actorTest->Y + actorTest->boudingBox.Y.topRight;
+
+ zLeftTest = actorTest->Z + actorTest->boudingBox.Z.bottomLeft;
+ zRightTest = actorTest->Z + actorTest->boudingBox.Z.topRight;
+
+ if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
+ hitActor(actorIdx, a, actor->strengthOfHit, actor->angle + 0x200);
+ actor->dynamicFlags.bIsHitting = 0;
+ }
+ }
+ }
+ }
+
+ return actor->collision;
+}
+
+/** Check Hero collision with bricks
+ @param X Hero X coordinate
+ @param Y Hero Y coordinate
+ @param Z Hero Z coordinate
+ @param damageMask Cause damage mask */
+void checkHeroCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask) {
+ int32 brickShape;
+
+ brickShape = getBrickShape(processActorX, processActorY, processActorZ);
+
+ processActorX += X;
+ processActorY += Y;
+ processActorZ += Z;
+
+ if (processActorX >= 0 && processActorZ >= 0 && processActorX <= 0x7E00 && processActorZ <= 0x7E00) {
+ reajustActorPosition(brickShape);
+ brickShape = getBrickShapeFull(processActorX, processActorY, processActorZ, processActorPtr->boudingBox.Y.topRight);
+
+ if (brickShape == kSolid) {
+ causeActorDamage |= damageMask;
+ brickShape = getBrickShapeFull(processActorX, processActorY, previousActorZ + Z, processActorPtr->boudingBox.Y.topRight);
+
+ if (brickShape == kSolid) {
+ brickShape = getBrickShapeFull(X + previousActorX, processActorY, processActorZ, processActorPtr->boudingBox.Y.topRight);
+
+ if (brickShape != kSolid) {
+ processCollisionX = previousActorX;
+ }
+ } else {
+ processCollisionZ = previousActorZ;
+ }
+ }
+ }
+
+ processActorX = processCollisionX;
+ processActorY = processCollisionY;
+ processActorZ = processCollisionZ;
+}
+
+/** Check other actor collision with bricks
+ @param X Actor X coordinate
+ @param Y Actor Y coordinate
+ @param Z Actor Z coordinate
+ @param damageMask Cause damage mask */
+void checkActorCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask) {
+ int32 brickShape;
+
+ brickShape = getBrickShape(processActorX, processActorY, processActorZ);
+
+ processActorX += X;
+ processActorY += Y;
+ processActorZ += Z;
+
+ if (processActorX >= 0 && processActorZ >= 0 && processActorX <= 0x7E00 && processActorZ <= 0x7E00) {
+ reajustActorPosition(brickShape);
+ brickShape = getBrickShape(processActorX, processActorY, processActorZ);
+
+ if (brickShape == kSolid) {
+ causeActorDamage |= damageMask;
+ brickShape = getBrickShape(processActorX, processActorY, previousActorZ + Z);
+
+ if (brickShape == kSolid) {
+ brickShape = getBrickShape(X + previousActorX, processActorY, processActorZ);
+
+ if (brickShape != kSolid) {
+ processCollisionX = previousActorX;
+ }
+ } else {
+ processCollisionZ = previousActorZ;
+ }
+ }
+ }
+
+ processActorX = processCollisionX;
+ processActorY = processCollisionY;
+ processActorZ = processCollisionZ;
+}
+
+/** Make actor to stop falling */
+void stopFalling() { // ReceptionObj()
+ int32 fall;
+
+ if (currentlyProcessedActorIdx == 0) {
+ fall = heroYBeforeFall - processActorY;
+
+ if (fall >= 0x1000) {
+ addExtraSpecial(processActorPtr->X, processActorPtr->Y + 1000, processActorPtr->Z, kHitStars);
+ processActorPtr->life--;
+ initAnim(kLandingHit, 2, 0, currentlyProcessedActorIdx);
+ } else if (fall >= 0x800) {
+ addExtraSpecial(processActorPtr->X, processActorPtr->Y + 1000, processActorPtr->Z, kHitStars);
+ processActorPtr->life--;
+ initAnim(kLandingHit, 2, 0, currentlyProcessedActorIdx);
+ } else if (fall > 10) {
+ initAnim(kLanding, 2, 0, currentlyProcessedActorIdx);
+ } else {
+ initAnim(kStanding, 0, 0, currentlyProcessedActorIdx);
+ }
+
+ heroYBeforeFall = 0;
+ } else {
+ initAnim(kLanding, 2, processActorPtr->animExtra, currentlyProcessedActorIdx);
+ }
+
+ processActorPtr->dynamicFlags.bIsFalling = 0;
+}
+
+/** Check extra collision with actors
+ @param extra to process
+ @param actorIdx actor to check collision */
+int32 checkExtraCollisionWithActors(ExtraListStruct* extra, int32 actorIdx) {
+ int32 a;
+ int32 xLeft, xRight, yLeft, yRight, zLeft, zRight;
+ int16 * spriteBounding;
+ ActorStruct *actorTest;
+
+ spriteBounding = (int16*)(spriteBoundingBoxPtr + extra->info0 * 16 + 4);
+
+ xLeft = *(spriteBounding++) + extra->X;
+ xRight = *(spriteBounding++) + extra->X;
+
+ yLeft = *(spriteBounding++) + extra->Y;
+ yRight = *(spriteBounding++) + extra->Y;
+
+ zLeft = *(spriteBounding++) + extra->Z;
+ zRight = *(spriteBounding++) + extra->Z;
+
+ for (a = 0; a < sceneNumActors; a++) {
+ actorTest = &sceneActors[a];
+
+ if (a != actorIdx && actorTest->entity != -1) {
+ int32 xLeftTest, xRightTest, yLeftTest, yRightTest, zLeftTest, zRightTest;
+
+ xLeftTest = actorTest->X + actorTest->boudingBox.X.bottomLeft;
+ xRightTest = actorTest->X + actorTest->boudingBox.X.topRight;
+
+ yLeftTest = actorTest->Y + actorTest->boudingBox.Y.bottomLeft;
+ yRightTest = actorTest->Y + actorTest->boudingBox.Y.topRight;
+
+ zLeftTest = actorTest->Z + actorTest->boudingBox.Z.bottomLeft;
+ zRightTest = actorTest->Z + actorTest->boudingBox.Z.topRight;
+
+ if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
+ if (extra->strengthOfHit != 0) {
+ hitActor(actorIdx, a, extra->strengthOfHit, -1);
+ }
+
+ return a;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/** Check extra collision with bricks */
+int32 checkExtraCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 oldX, int32 oldY, int32 oldZ) {
+ int32 averageX, averageY, averageZ;
+
+ if (getBrickShape(oldX, oldY, oldZ)) {
+ return 1;
+ }
+
+ averageX = Abs(X + oldX)/2;
+ averageY = Abs(Y + oldY)/2;
+ averageZ = Abs(Z + oldZ)/2;
+
+ if (getBrickShape(averageX, averageY, averageZ)) {
+ return 1;
+ }
+
+ if (getBrickShape(Abs(oldX + averageX)/2, Abs(oldY + averageY)/2, Abs(oldZ + averageZ)/2)) {
+ return 1;
+ }
+
+ if (getBrickShape(Abs(X + averageX)/2, Abs(Y + averageY)/2, Abs(Z + averageZ)/2)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/** Check extra collision with another extra
+ @param extra to process
+ @param extraIdx extra index to check collision */
+int32 checkExtraCollisionWithExtra(ExtraListStruct* extra, int32 extraIdx) {
+ int32 i;
+ int32 xLeft, xRight, yLeft, yRight, zLeft, zRight;
+ int16 * spriteBounding;
+
+ spriteBounding = (int16*)(spriteBoundingBoxPtr + extra->info0 * 16 + 4);
+
+ xLeft = *(spriteBounding++) + extra->X;
+ xRight = *(spriteBounding++) + extra->X;
+
+ yLeft = *(spriteBounding++) + extra->Y;
+ yRight = *(spriteBounding++) + extra->Y;
+
+ zLeft = *(spriteBounding++) + extra->Z;
+ zRight = *(spriteBounding++) + extra->Z;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extraTest = &extraList[i];
+ if ( i != extraIdx && extraTest->info0 != -1) {
+ int32 xLeftTest, xRightTest, yLeftTest, yRightTest, zLeftTest, zRightTest;
+// int16 * spriteBoundingTest;
+// spriteBoundingTest = (int16*)(spriteBoundingBoxPtr + extraTest->info0 * 16 + 4);
+
+ xLeftTest = *(spriteBounding++) + extraTest->X;
+ xRightTest = *(spriteBounding++) + extraTest->X;
+
+ yLeftTest = *(spriteBounding++) + extraTest->Y;
+ yRightTest = *(spriteBounding++) + extraTest->Y;
+
+ zLeftTest = *(spriteBounding++) + extraTest->Z;
+ zRightTest = *(spriteBounding++) + extraTest->Z;
+
+ if (xLeft < xLeftTest) {
+ if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
+ return i;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
diff --git a/engines/twine/collision.h b/engines/twine/collision.h
new file mode 100644
index 0000000000..3b802dd205
--- /dev/null
+++ b/engines/twine/collision.h
@@ -0,0 +1,94 @@
+/** @file collision.h
+ @brief
+ This file contains movies routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef COLLISION_H
+#define COLLISION_H
+
+#include "sys.h"
+#include "extra.h"
+
+/** Actor collition X coordinate */
+int32 collisionX; // getPosVar1
+/** Actor collition Y coordinate */
+int32 collisionY; // getPosVar2
+/** Actor collition Z coordinate */
+int32 collisionZ; // getPosVar3
+
+/** Actor collition X coordinate */
+int32 processCollisionX; // processActorVar11
+/** Actor collition Y coordinate */
+int32 processCollisionY; // processActorVar12
+/** Actor collition Z coordinate */
+int32 processCollisionZ; // processActorVar13
+
+/** Cause damage in current processed actor */
+int32 causeActorDamage; //fieldCauseDamage
+
+/** Check if actor 1 is standing in actor2
+ @param actorIdx1 Actor 1 index
+ @param actorIdx2 Actor 2 index */
+int32 standingOnActor(int32 actorIdx1, int32 actorIdx2);
+
+int32 getAverageValue(int32 var0, int32 var1, int32 var2, int32 var3);
+
+/** Reajust actor position in scene according with brick shape bellow actor
+ @param brickShape Shape of brick bellow the actor */
+void reajustActorPosition(int32 brickShape);
+
+/** Check collision with actors
+ @param actorIx Current process actor index */
+int32 checkCollisionWithActors(int32 actorIdx);
+
+/** Check Hero collision with bricks
+ @param X Hero X coordinate
+ @param Y Hero Y coordinate
+ @param Z Hero Z coordinate
+ @param damageMask Cause damage mask */
+void checkHeroCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask);
+
+/** Check other actor collision with bricks
+ @param X Actor X coordinate
+ @param Y Actor Y coordinate
+ @param Z Actor Z coordinate
+ @param damageMask Cause damage mask */
+void checkActorCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask);
+
+/** Make actor to stop falling */
+void stopFalling();
+
+/** Check extra collision with actors
+ @param extra to process
+ @param actorIdx actor to check collision */
+int32 checkExtraCollisionWithActors(ExtraListStruct* extra, int32 actorIdx);
+
+/** Check extra collision with bricks */
+int32 checkExtraCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 oldX, int32 oldY, int32 oldZ);
+
+/** Check extra collision with another extra
+ @param extra to process
+ @param extraIdx extra index to check collision */
+int32 checkExtraCollisionWithExtra(ExtraListStruct* extra, int32 extraIdx);
+
+#endif
diff --git a/engines/twine/configure.engine b/engines/twine/configure.engine
new file mode 100644
index 0000000000..510f98d061
--- /dev/null
+++ b/engines/twine/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine twine "Little Big Adventure" no
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
new file mode 100644
index 0000000000..4b4a085704
--- /dev/null
+++ b/engines/twine/debug.cpp
@@ -0,0 +1,556 @@
+/** @file debug.cpp
+ @brief
+ This file contains the main game debug window routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "debug.h"
+
+#ifdef GAMEMOD
+#include "debug.scene.h"
+#include "debug.grid.h"
+#include "scene.h"
+#include "sdlengine.h"
+#include "menu.h"
+#include "interface.h"
+#include "text.h"
+#include "lbaengine.h"
+#include "screens.h"
+#include "redraw.h"
+
+enum ButtonType {
+ NO_ACTION,
+ FREE_CAMERA,
+ CHANGE_SCENE,
+ SHOW_CELLING_GRID,
+ SHOW_ZONES,
+ SHOW_ZONE_CUBE,
+ SHOW_ZONE_CAMERA,
+ SHOW_ZONE_SCENARIC,
+ SHOW_ZONE_CELLINGGRID,
+ SHOW_ZONE_OBJECT,
+ SHOW_ZONE_TEXT,
+ SHOW_ZONE_LADDER
+};
+
+enum WindowType {
+ NO_MENU,
+ FREE_CAMERA_INFO_MENU,
+ CHANGE_SCENE_INFO_MENU,
+ ZONES_MENU
+};
+
+typedef struct DebugButtonStruct {
+ int32 left;
+ int32 top;
+ int32 right;
+ int32 bottom;
+ int8 *text;
+ int32 textLeft;
+ int32 textTop;
+ int32 isActive;
+ int32 color;
+ int32 activeColor;
+ int32 submenu;
+ int32 type;
+} DebugButtonStruct;
+
+typedef struct DebugWindowStruct {
+ int32 left;
+ int32 top;
+ int32 right;
+ int32 bottom;
+ int32 alpha;
+ int32 isActive;
+ int32 numLines;
+ int8 *text[20];
+ int32 numButtons;
+ DebugButtonStruct debugButtons[50];
+} DebugWindowStruct;
+
+DebugWindowStruct debugWindows[10];
+int32 numDebugWindows = 0;
+
+
+void debugFillButton(int32 X, int32 Y, int32 width, int32 height, int8 color) {
+ int32 i, j;
+ uint8 *ptr;
+ int32 offset;
+
+ ptr = frontVideoBuffer + screenLookupTable[Y] + X;
+ offset = 640 - (width);
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ *(ptr++) = color;
+ }
+ ptr += offset;
+ }
+}
+
+void debugDrawButton(int32 left, int32 top, int32 right, int32 bottom, int8 *text, int32 textLeft, int32 textRight, int32 isActive, int8 color) {
+ debugFillButton(left + 1, top + 1, right - left - 1, bottom - top - 1, color);
+ drawBox(left, top, right, bottom);
+ ttfDrawText(textLeft, textRight, text, 0);
+ copyBlockPhys(left, top, right, bottom);
+}
+
+void debugDrawWindowBox(int32 left, int32 top, int32 right, int32 bottom, int32 alpha) {
+ drawTransparentBox(left, top, right, bottom, alpha);
+ drawBox(left, top, right, bottom);
+ //copyBlockPhys(left,top,right,bottom);
+}
+
+void debugDrawWindowButtons(int32 w) {
+ int32 b;
+
+ for (b = 0; b < debugWindows[w].numButtons; b++) {
+ int32 left = debugWindows[w].debugButtons[b].left;
+ int32 top = debugWindows[w].debugButtons[b].top;
+ int32 right = debugWindows[w].debugButtons[b].right;
+ int32 bottom = debugWindows[w].debugButtons[b].bottom;
+ int8 *text = debugWindows[w].debugButtons[b].text;
+ int32 textLeft = debugWindows[w].debugButtons[b].textLeft;
+ int32 textTop = debugWindows[w].debugButtons[b].textTop;
+ int32 isActive = debugWindows[w].debugButtons[b].isActive;
+ int8 color = debugWindows[w].debugButtons[b].color;
+ if (isActive > 0)
+ color = debugWindows[w].debugButtons[b].activeColor;
+
+ debugDrawButton(left, top, right, bottom, text, textLeft, textTop, isActive, color);
+ }
+}
+
+void debugDrawWindow(int32 w) {
+ int32 left = debugWindows[w].left;
+ int32 top = debugWindows[w].top;
+ int32 right = debugWindows[w].right;
+ int32 bottom = debugWindows[w].bottom;
+ int32 alpha = debugWindows[w].alpha;
+
+ debugDrawWindowBox(left, top, right, bottom, alpha);
+
+ if (debugWindows[w].numLines > 0) {
+ int32 l;
+
+ for (l = 0; l < debugWindows[w].numLines; l++) {
+ ttfDrawText(left + 10, top + l*20 + 5, debugWindows[w].text[l], 0);
+ }
+ }
+
+ copyBlockPhys(left, top, right, bottom);
+
+ debugDrawWindowButtons(w);
+}
+
+int32 debugTypeUseMenu(int32 type) {
+ int32 w, b;
+
+ for (w = 0; w < numDebugWindows; w++) {
+ if (debugWindows[w].isActive > 0) {
+ for (b = 0; b < debugWindows[w].numButtons; b++) {
+ if (debugWindows[w].debugButtons[b].type == type) {
+ int submenu = debugWindows[w].debugButtons[b].submenu;
+ if (submenu > 0)
+ debugWindows[submenu].isActive = !debugWindows[submenu].isActive;
+ return submenu;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void debugResetButtonsState() {
+ int w, b;
+ for (w = 0; w < numDebugWindows; w++) {
+ if (debugWindows[w].isActive > 0) {
+ for (b = 0; b < debugWindows[w].numButtons; b++) {
+ if (debugWindows[w].debugButtons[b].type <= -1)
+ debugWindows[w].debugButtons[b].isActive = 0;
+ }
+ }
+ }
+}
+
+void debugRefreshButtons(int32 type) {
+ int32 w, b;
+
+ for (w = 0; w < numDebugWindows; w++) {
+ if (debugWindows[w].isActive > 0) {
+ for (b = 0; b < debugWindows[w].numButtons; b++) {
+ if (debugWindows[w].debugButtons[b].type == type) {
+ int32 left = debugWindows[w].debugButtons[b].left;
+ int32 top = debugWindows[w].debugButtons[b].top;
+ int32 right = debugWindows[w].debugButtons[b].right;
+ int32 bottom = debugWindows[w].debugButtons[b].bottom;
+ int8 *text = debugWindows[w].debugButtons[b].text;
+ int32 textLeft = debugWindows[w].debugButtons[b].textLeft;
+ int32 textTop = debugWindows[w].debugButtons[b].textTop;
+ int8 color = debugWindows[w].debugButtons[b].color;
+ int32 isActive = debugWindows[w].debugButtons[b].isActive = !debugWindows[w].debugButtons[b].isActive;
+
+ if (isActive > 0)
+ color = debugWindows[w].debugButtons[b].activeColor;
+
+ debugDrawButton(left, top, right, bottom, text, textLeft, textTop, isActive, color);
+
+ if (debugWindows[w].debugButtons[b].submenu && isActive > 0)
+ debugDrawWindow(debugWindows[w].debugButtons[b].submenu);
+ }
+ }
+ }
+ }
+}
+
+void debugDrawWindows() {
+ int32 w;
+
+ for (w = 0; w < numDebugWindows; w++) {
+ if (debugWindows[w].isActive > 0) {
+ debugDrawWindow(w);
+ }
+ }
+}
+
+void debugResetButton(int32 type) {
+ int32 w, b;
+
+ for (w = 0; w < numDebugWindows; w++) {
+ if (debugWindows[w].isActive > 0) {
+ for (b = 0; b < debugWindows[w].numButtons; b++) {
+ if (debugWindows[w].debugButtons[b].type == type) {
+ int submenu = debugWindows[w].debugButtons[b].submenu;
+ debugWindows[w].debugButtons[b].isActive = 0;
+ if (submenu > 0) {
+ debugWindows[submenu].debugButtons[b].isActive = !debugWindows[submenu].debugButtons[b].isActive;
+ }
+
+ return;
+ }
+ }
+ }
+ }
+}
+
+void debugRedrawScreen() {
+ redrawEngineActions(1);
+ copyScreen(frontVideoBuffer, workVideoBuffer);
+ debugDrawWindows();
+}
+
+int32 debugGetActionsState(int32 type) {
+ int32 state = 0;
+
+ switch (type) {
+ case FREE_CAMERA:
+ state = useFreeCamera;
+ break;
+ case CHANGE_SCENE:
+ state = canChangeScenes;
+ break;
+ case SHOW_ZONES:
+ state = showingZones;
+ break;
+ case SHOW_ZONE_CUBE:
+ case SHOW_ZONE_CAMERA:
+ case SHOW_ZONE_SCENARIC:
+ case SHOW_ZONE_CELLINGGRID:
+ case SHOW_ZONE_OBJECT:
+ case SHOW_ZONE_TEXT:
+ case SHOW_ZONE_LADDER:
+ state = typeZones;
+ break;
+ default:
+ break;
+ }
+ return state;
+}
+
+void debugSetActions(int32 type) {
+ switch (type) {
+ case FREE_CAMERA:
+ useFreeCamera = !useFreeCamera;
+ break;
+
+ case CHANGE_SCENE:
+ canChangeScenes = !canChangeScenes;
+ break;
+
+ case SHOW_ZONES:
+ showingZones = !showingZones;
+ debugResetButton(-1);
+ debugResetButton(-2);
+ debugRedrawScreen();
+ break;
+ case SHOW_ZONE_CUBE:
+ if (showingZones) {
+ if (typeZones & 0x01)
+ typeZones &= ~0x01;
+ else
+ typeZones |= 0x01;
+ debugRedrawScreen();
+ }
+ break;
+ case SHOW_ZONE_CAMERA:
+ if (showingZones) {
+ if (typeZones & 0x02)
+ typeZones &= ~0x02;
+ else
+ typeZones |= 0x02;
+ debugRedrawScreen();
+ }
+ break;
+ case SHOW_ZONE_SCENARIC:
+ if (showingZones) {
+ if (typeZones & 0x04)
+ typeZones &= ~0x04;
+ else
+ typeZones |= 0x04;
+ debugRedrawScreen();
+ }
+ break;
+ case SHOW_ZONE_CELLINGGRID:
+ if (showingZones) {
+ if (typeZones & 0x08)
+ typeZones &= ~0x08;
+ else
+ typeZones |= 0x08;
+ debugRedrawScreen();
+ debugRedrawScreen();
+ }
+ break;
+ case SHOW_ZONE_OBJECT:
+ if (showingZones) {
+ if (typeZones & 0x10)
+ typeZones &= ~0x10;
+ else
+ typeZones |= 0x10;
+ debugRedrawScreen();
+ debugRedrawScreen();
+ }
+ break;
+ case SHOW_ZONE_TEXT:
+ if (showingZones) {
+ if (typeZones & 0x20)
+ typeZones &= ~0x20;
+ else
+ typeZones |= 0x20;
+ debugRedrawScreen();
+ }
+ break;
+ case SHOW_ZONE_LADDER:
+ if (showingZones) {
+ if (typeZones & 0x40)
+ typeZones &= ~0x40;
+ else
+ typeZones |= 0x40;
+ debugRedrawScreen();
+ }
+ break;
+
+
+ case -1:
+ debugResetButton(-2);
+ debugRedrawScreen();
+ break;
+ case -2:
+ debugResetButton(-1);
+ debugRedrawScreen();
+ break;
+ default:
+ break;
+ }
+}
+
+void debugAddButton(int32 window, int32 left, int32 top, int32 right, int32 bottom, int8 *text, int32 textLeft, int32 textTop, int32 isActive, int32 color, int32 activeColor, int32 submenu, int32 type) {
+ int32 button = debugWindows[window].numButtons;
+ debugWindows[window].debugButtons[button].left = left;
+ debugWindows[window].debugButtons[button].top = top;
+ debugWindows[window].debugButtons[button].right = right;
+ debugWindows[window].debugButtons[button].bottom = bottom;
+ debugWindows[window].debugButtons[button].text = text;
+ debugWindows[window].debugButtons[button].textLeft = textLeft;
+ debugWindows[window].debugButtons[button].textTop = textTop;
+ debugWindows[window].debugButtons[button].isActive = debugGetActionsState(type);
+ debugWindows[window].debugButtons[button].color = color;
+ debugWindows[window].debugButtons[button].activeColor = activeColor;
+ debugWindows[window].debugButtons[button].submenu = submenu;
+ debugWindows[window].debugButtons[button].type = type;
+ debugWindows[window].numButtons++;
+}
+
+void debugAddWindowText(int32 window, int8 *text) {
+ int32 line = debugWindows[window].numLines;
+ debugWindows[window].text[line] = text;
+ debugWindows[window].numLines++;
+}
+
+void debugAddWindow(int32 left, int32 top, int32 right, int32 bottom, int32 alpha, int32 isActive) {
+ debugWindows[numDebugWindows].left = left;
+ debugWindows[numDebugWindows].top = top;
+ debugWindows[numDebugWindows].right = right;
+ debugWindows[numDebugWindows].bottom = bottom;
+ debugWindows[numDebugWindows].alpha = alpha;
+ debugWindows[numDebugWindows].numButtons = 0;
+ debugWindows[numDebugWindows].isActive = isActive;
+ numDebugWindows++;
+}
+
+void debugLeftMenu() {
+ // left menu window
+ debugAddWindow(5, 60, 200, 474, 4, 1);
+ debugAddButton(0, 5, 55, 160, 75, (int8*) "Use free camera", 30, 60, 0, 87, 119, NO_MENU, FREE_CAMERA);
+ debugAddButton(0, 161, 55, 200, 75, (int8*) "info", 171, 60, 0, 87, 119, FREE_CAMERA_INFO_MENU, -1);
+ debugAddButton(0, 5, 76, 160, 96, (int8*) "Change scenes", 30, 81, 0, 87, 119, NO_MENU, CHANGE_SCENE);
+ debugAddButton(0, 161, 76, 200, 96, (int8*) "info", 171, 81, 0, 87, 119, CHANGE_SCENE_INFO_MENU, -2);
+ debugAddButton(0, 5, 97, 200, 117, (int8*) "Show celling grids", 30, 102, 0, 87, 119, NO_MENU, 3);
+ debugAddButton(0, 5, 118, 200, 138, (int8*) "Show zones", 30, 123, 0, 87, 119, ZONES_MENU, SHOW_ZONES);
+
+ // add submenu windows
+ // - free camera window
+ debugAddWindow(205, 55, 634, 160, 4, 0);
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) "When enable, use the following keys to browse through the scenes:");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) " - S to go North");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) " - X to go South");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) " - Z to go West");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) " - C to go East");
+
+ // - change scene window
+ debugAddWindow(205, 55, 634, 137, 4, 0);
+ debugAddWindowText(CHANGE_SCENE_INFO_MENU, (int8*) "When enable, use the following keys to change to another scene:");
+ debugAddWindowText(CHANGE_SCENE_INFO_MENU, (int8*) " - R to go Next Scene");
+ debugAddWindowText(CHANGE_SCENE_INFO_MENU, (int8*) " - F to go Previous Scene");
+
+ // - zones window
+ debugAddWindow(205, 55, 634, 97, 4, 0);
+ debugAddWindowText(ZONES_MENU, (int8*) "You can enable or disable each zone type:");
+ debugAddButton(ZONES_MENU, 205, 118, 350, 138, (int8*) "Cube Zones", 215, 123, 1, 87, 119, 0, SHOW_ZONE_CUBE);
+ debugAddButton(ZONES_MENU, 205, 139, 350, 159, (int8*) "Camera Zones", 215, 144, 2, 87, 119, 0, SHOW_ZONE_CAMERA);
+ debugAddButton(ZONES_MENU, 205, 160, 350, 180, (int8*) "Scenaric Zones", 215, 165, 3, 87, 119, 0, SHOW_ZONE_SCENARIC);
+ debugAddButton(ZONES_MENU, 205, 181, 350, 201, (int8*) "Celling Grid Zones", 215, 186, 4, 87, 119, 0, SHOW_ZONE_CELLINGGRID);
+ debugAddButton(ZONES_MENU, 205, 202, 350, 222, (int8*) "Object Zones", 215, 207, 5, 87, 119, 0, SHOW_ZONE_OBJECT);
+ debugAddButton(ZONES_MENU, 205, 223, 350, 243, (int8*) "Text Zones", 215, 228, 6, 87, 119, 0, SHOW_ZONE_TEXT);
+ debugAddButton(ZONES_MENU, 205, 244, 350, 264, (int8*) "Ladder Zones", 215, 249, 7, 87, 119, 0, SHOW_ZONE_LADDER);
+}
+
+int32 debugProcessButton(int32 X, int32 Y) {
+ int32 i;
+ int32 j;
+
+ for (i = 0; i < numDebugWindows; i++) {
+ for (j = 0; j < debugWindows[i].numButtons; j++) {
+ if (X > (debugWindows[i].debugButtons[j].left)
+ && X < (debugWindows[i].debugButtons[j].right)
+ && Y > (debugWindows[i].debugButtons[j].top)
+ && Y < (debugWindows[i].debugButtons[j].bottom)) {
+ return (debugWindows[i].debugButtons[j].type);
+ }
+ }
+ }
+
+ return 0;
+}
+
+void debugPlasmaWindow(int8 *text, int32 color) {
+ int32 textSize;
+ processPlasmaEffect(5, color);
+ if (!(rand() % 5)) {
+ plasmaEffectPtr[rand() % 320 * 10 + 6400] = 255;
+ }
+ textSize = getTextSize(text);
+ drawText((SCREEN_WIDTH / 2) - (textSize / 2), 10, text);
+ drawBox(5, 5, 634, 50);
+ copyBlockPhys(5, 5, 634, 50);
+}
+
+void debugProcessWindow() {
+ if (rightMouse) {
+ int32 quit = 0;
+ int8* text = (int8*) "Game Debug Window";
+ int32 color = 64;
+ int32 colorIdx = 4;
+ int32 count = 0;
+ MouseStatusStruct mouseData;
+ rightMouse = 0;
+ leftMouse = 0;
+
+ copyScreen(frontVideoBuffer, workVideoBuffer);
+
+ debugResetButtonsState();
+ if (numDebugWindows == 0)
+ debugLeftMenu();
+ debugDrawWindows();
+
+ do {
+ readKeys();
+ getMousePositions(&mouseData);
+
+ if (mouseData.left) {
+ int type = 0;
+ if ((type = debugProcessButton(mouseData.X, mouseData.Y)) != NO_ACTION) { // process menu item
+ if (debugTypeUseMenu(type)) {
+ copyScreen(workVideoBuffer, frontVideoBuffer);
+ copyBlockPhys(205, 55, 634, 474);
+ }
+
+ debugRefreshButtons(type);
+ debugSetActions(type);
+ }
+ mouseData.left = 0;
+ }
+
+ // draw window plasma effect
+ if (count == 256) {
+ colorIdx++;
+ count = 0;
+ }
+ color = colorIdx * 16;
+ if (color >= 240) {
+ color = 64;
+ colorIdx = 4;
+ }
+ debugPlasmaWindow(text, color);
+
+ // quit
+ if (mouseData.right)
+ quit = 1;
+
+ fpsCycles(25); // rest
+
+ count++;
+ } while (!quit);
+ reqBgRedraw = 1;
+ }
+}
+
+void processDebug(int16 pKey) {
+ debugProcessWindow();
+
+ changeGrid(pKey);
+ changeGridCamera(pKey);
+ if (needChangeScene == 0);
+ applyCellingGrid(pKey);
+}
+
+#endif
+
diff --git a/engines/twine/debug.grid.cpp b/engines/twine/debug.grid.cpp
new file mode 100644
index 0000000000..1dd1f1ee8d
--- /dev/null
+++ b/engines/twine/debug.grid.cpp
@@ -0,0 +1,131 @@
+/** @file debug.grid.cpp
+ @brief
+ This file contains grid debug routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debug.grid.h"
+#include "grid.h"
+#include "lbaengine.h"
+#include "scene.h"
+#include "main.h"
+#include "redraw.h"
+
+int32 useFreeCamera = 0;
+#ifdef _DEBUG
+int32 canChangeScenes = 1;
+#else
+int32 canChangeScenes = 0;
+#endif
+
+/** Change scenario camera positions */
+void changeGridCamera(int16 pKey) {
+ if (useFreeCamera) {
+ // Press up - more X positions
+ if (pKey == 0x2E) {
+ newCameraZ--;
+ reqBgRedraw = 1;
+ }
+
+ // Press down - less X positions
+ if (pKey == 0x2C) {
+ newCameraZ++;
+ reqBgRedraw = 1;
+ }
+
+ // Press left - less Z positions
+ if (pKey == 0x1F) {
+ newCameraX--;
+ reqBgRedraw = 1;
+ }
+
+ // Press right - more Z positions
+ if (pKey == 0x2D) {
+ newCameraX++;
+ reqBgRedraw = 1;
+ }
+ }
+}
+
+/** Change grid index */
+void changeGrid(int16 pKey) {
+ if (canChangeScenes) {
+ // Press up - more X positions
+ if (pKey == 0x13) {
+ currentSceneIdx++;
+ if (currentSceneIdx > NUM_SCENES)
+ currentSceneIdx = 0;
+ needChangeScene = currentSceneIdx;
+ reqBgRedraw = 1;
+ }
+
+ // Press down - less X positions
+ if (pKey == 0x21) {
+ currentSceneIdx--;
+ if (currentSceneIdx < 0)
+ currentSceneIdx = NUM_SCENES;
+ needChangeScene = currentSceneIdx;
+ reqBgRedraw = 1;
+ }
+
+ if (cfgfile.Debug && (pKey == 'f' || pKey == 'r'))
+ printf("\nGrid index changed: %d\n", needChangeScene);
+ }
+}
+
+/** Apply and change disappear celling grid */
+void applyCellingGrid(int16 pKey) {
+ // Increase celling grid index
+ if (pKey == 0x22) {
+ cellingGridIdx++;
+ if (cellingGridIdx > 133)
+ cellingGridIdx = 133;
+ }
+ // Decrease celling grid index
+ if (pKey == 0x30) {
+ cellingGridIdx--;
+ if (cellingGridIdx < 0)
+ cellingGridIdx = 0;
+ }
+
+ // Enable/disable celling grid
+ if (pKey == 0x14 && useCellingGrid == -1) {
+ useCellingGrid = 1;
+ //createGridMap();
+ initCellingGrid(cellingGridIdx);
+ if (cfgfile.Debug && pKey == 0x14)
+ printf("\nEnable Celling Grid index: %d\n", cellingGridIdx);
+ needChangeScene = -2; // tricky to make the fade
+ } else if (pKey == 0x14 && useCellingGrid == 1) {
+ useCellingGrid = -1;
+ createGridMap();
+ reqBgRedraw = 1;
+ if (cfgfile.Debug && pKey == 0x14)
+ printf("\nDisable Celling Grid index: %d\n", cellingGridIdx);
+ needChangeScene = -2; // tricky to make the fade
+ }
+}
+
diff --git a/engines/twine/debug.grid.h b/engines/twine/debug.grid.h
new file mode 100644
index 0000000000..27633fa95b
--- /dev/null
+++ b/engines/twine/debug.grid.h
@@ -0,0 +1,41 @@
+/** @file debug.grid.h
+ @brief
+ This file contains grid debug routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef GRIDDEBUG_H
+#define GRIDDEBUG_H
+
+#include "sys.h"
+
+extern int32 useFreeCamera;
+extern int32 canChangeScenes;
+
+/** Change scenario camera positions */
+void changeGridCamera(int16 pKey);
+/** Change grid index */
+void changeGrid(int16 pKey);
+/** Apply and change disappear celling grid */
+void applyCellingGrid(int16 pKey);
+
+#endif
diff --git a/engines/twine/debug.h b/engines/twine/debug.h
new file mode 100644
index 0000000000..f0d5409a3d
--- /dev/null
+++ b/engines/twine/debug.h
@@ -0,0 +1,41 @@
+/** @file debug.h
+ @brief
+ This file contains the main game debug window routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include "sys.h"
+
+typedef struct MouseStatusStruct {
+ int32 left;
+ int32 right;
+ int32 X;
+ int32 Y;
+} MouseStatusStruct;
+
+
+void processDebug(int16 pKey);
+
+#endif
diff --git a/engines/twine/debug.scene.cpp b/engines/twine/debug.scene.cpp
new file mode 100644
index 0000000000..64cc5c9266
--- /dev/null
+++ b/engines/twine/debug.scene.cpp
@@ -0,0 +1,203 @@
+/** @file debug.scene.cpp
+ @brief
+ This file contains scenario debug routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "debug.scene.h"
+#include "scene.h"
+#include "grid.h"
+#include "lbaengine.h"
+#include "redraw.h"
+#include "interface.h"
+#include "renderer.h"
+
+int32 showingZones = 0;
+int32 typeZones = 127; // all zones on as default
+
+void drawBoundingBoxProjectPoints(ScenePoint* pPoint3d, ScenePoint* pPoint3dProjected) {
+ projectPositionOnScreen(pPoint3d->X, pPoint3d->Y, pPoint3d->Z);
+
+ pPoint3dProjected->X = projPosX;
+ pPoint3dProjected->Y = projPosY;
+ pPoint3dProjected->Z = projPosZ;
+
+ if (renderLeft > projPosX)
+ renderLeft = projPosX;
+
+ if (renderRight < projPosX)
+ renderRight = projPosX;
+
+ if (renderTop > projPosY)
+ renderTop = projPosY;
+
+ if (renderBottom < projPosY)
+ renderBottom = projPosY;
+}
+
+int32 checkZoneType(int32 type) {
+ switch (type) {
+ case 0:
+ if (typeZones & 0x01)
+ return 1;
+ break;
+ case 1:
+ if (typeZones & 0x02)
+ return 1;
+ break;
+ case 2:
+ if (typeZones & 0x04)
+ return 1;
+ break;
+ case 3:
+ if (typeZones & 0x08)
+ return 1;
+ break;
+ case 4:
+ if (typeZones & 0x10)
+ return 1;
+ break;
+ case 5:
+ if (typeZones & 0x20)
+ return 1;
+ break;
+ case 6:
+ if (typeZones & 0x40)
+ return 1;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void displayZones(int16 pKey) {
+ if (showingZones == 1) {
+ int z;
+ ZoneStruct *zonePtr = sceneZones;
+ for (z = 0; z < sceneNumZones; z++) {
+ zonePtr = &sceneZones[z];
+
+ if (checkZoneType(zonePtr->type)) {
+ ScenePoint frontBottomLeftPoint;
+ ScenePoint frontBottomRightPoint;
+
+ ScenePoint frontTopLeftPoint;
+ ScenePoint frontTopRightPoint;
+
+ ScenePoint backBottomLeftPoint;
+ ScenePoint backBottomRightPoint;
+
+ ScenePoint backTopLeftPoint;
+ ScenePoint backTopRightPoint;
+
+ ScenePoint frontBottomLeftPoint2D;
+ ScenePoint frontBottomRightPoint2D;
+
+ ScenePoint frontTopLeftPoint2D;
+ ScenePoint frontTopRightPoint2D;
+
+ ScenePoint backBottomLeftPoint2D;
+ ScenePoint backBottomRightPoint2D;
+
+ ScenePoint backTopLeftPoint2D;
+ ScenePoint backTopRightPoint2D;
+
+ uint8 color;
+
+ // compute the points in 3D
+
+ frontBottomLeftPoint.X = zonePtr->bottomLeft.X - cameraX;
+ frontBottomLeftPoint.Y = zonePtr->bottomLeft.Y - cameraY;
+ frontBottomLeftPoint.Z = zonePtr->topRight.Z - cameraZ;
+
+ frontBottomRightPoint.X = zonePtr->topRight.X - cameraX;
+ frontBottomRightPoint.Y = zonePtr->bottomLeft.Y - cameraY;
+ frontBottomRightPoint.Z = zonePtr->topRight.Z - cameraZ;
+
+ frontTopLeftPoint.X = zonePtr->bottomLeft.X - cameraX;
+ frontTopLeftPoint.Y = zonePtr->topRight.Y - cameraY;
+ frontTopLeftPoint.Z = zonePtr->topRight.Z - cameraZ;
+
+ frontTopRightPoint.X = zonePtr->topRight.X - cameraX;
+ frontTopRightPoint.Y = zonePtr->topRight.Y - cameraY;
+ frontTopRightPoint.Z = zonePtr->topRight.Z - cameraZ;
+
+ backBottomLeftPoint.X = zonePtr->bottomLeft.X - cameraX;
+ backBottomLeftPoint.Y = zonePtr->bottomLeft.Y - cameraY;
+ backBottomLeftPoint.Z = zonePtr->bottomLeft.Z - cameraZ;
+
+ backBottomRightPoint.X = zonePtr->topRight.X - cameraX;
+ backBottomRightPoint.Y = zonePtr->bottomLeft.Y - cameraY;
+ backBottomRightPoint.Z = zonePtr->bottomLeft.Z - cameraZ;
+
+ backTopLeftPoint.X = zonePtr->bottomLeft.X - cameraX;
+ backTopLeftPoint.Y = zonePtr->topRight.Y - cameraY;
+ backTopLeftPoint.Z = zonePtr->bottomLeft.Z - cameraZ;
+
+ backTopRightPoint.X = zonePtr->topRight.X - cameraX;
+ backTopRightPoint.Y = zonePtr->topRight.Y - cameraY;
+ backTopRightPoint.Z = zonePtr->bottomLeft.Z - cameraZ;
+
+ // project all points
+
+ drawBoundingBoxProjectPoints(&frontBottomLeftPoint, &frontBottomLeftPoint2D);
+ drawBoundingBoxProjectPoints(&frontBottomRightPoint, &frontBottomRightPoint2D);
+ drawBoundingBoxProjectPoints(&frontTopLeftPoint, &frontTopLeftPoint2D);
+ drawBoundingBoxProjectPoints(&frontTopRightPoint, &frontTopRightPoint2D);
+ drawBoundingBoxProjectPoints(&backBottomLeftPoint, &backBottomLeftPoint2D);
+ drawBoundingBoxProjectPoints(&backBottomRightPoint, &backBottomRightPoint2D);
+ drawBoundingBoxProjectPoints(&backTopLeftPoint, &backTopLeftPoint2D);
+ drawBoundingBoxProjectPoints(&backTopRightPoint, &backTopRightPoint2D);
+
+ // draw all lines
+
+ color = 15 * 3 + zonePtr->type * 16;
+
+ // draw front part
+ drawLine(frontBottomLeftPoint2D.X, frontBottomLeftPoint2D.Y, frontTopLeftPoint2D.X, frontTopLeftPoint2D.Y, color);
+ drawLine(frontTopLeftPoint2D.X, frontTopLeftPoint2D.Y, frontTopRightPoint2D.X, frontTopRightPoint2D.Y, color);
+ drawLine(frontTopRightPoint2D.X, frontTopRightPoint2D.Y, frontBottomRightPoint2D.X, frontBottomRightPoint2D.Y, color);
+ drawLine(frontBottomRightPoint2D.X, frontBottomRightPoint2D.Y, frontBottomLeftPoint2D.X, frontBottomLeftPoint2D.Y, color);
+
+ // draw top part
+ drawLine(frontTopLeftPoint2D.X, frontTopLeftPoint2D.Y, backTopLeftPoint2D.X, backTopLeftPoint2D.Y, color);
+ drawLine(backTopLeftPoint2D.X, backTopLeftPoint2D.Y, backTopRightPoint2D.X, backTopRightPoint2D.Y, color);
+ drawLine(backTopRightPoint2D.X, backTopRightPoint2D.Y, frontTopRightPoint2D.X, frontTopRightPoint2D.Y, color);
+ drawLine(frontTopRightPoint2D.X, frontTopRightPoint2D.Y, frontTopLeftPoint2D.X, frontTopLeftPoint2D.Y, color);
+
+ // draw back part
+ drawLine(backBottomLeftPoint2D.X, backBottomLeftPoint2D.Y, backTopLeftPoint2D.X, backTopLeftPoint2D.Y, color);
+ drawLine(backTopLeftPoint2D.X, backTopLeftPoint2D.Y, backTopRightPoint2D.X, backTopRightPoint2D.Y, color);
+ drawLine(backTopRightPoint2D.X, backTopRightPoint2D.Y, backBottomRightPoint2D.X, backBottomRightPoint2D.Y, color);
+ drawLine(backBottomRightPoint2D.X, backBottomRightPoint2D.Y, backBottomLeftPoint2D.X, backBottomLeftPoint2D.Y, color);
+
+ // draw bottom part
+ drawLine(frontBottomLeftPoint2D.X, frontBottomLeftPoint2D.Y, backBottomLeftPoint2D.X, backBottomLeftPoint2D.Y, color);
+ drawLine(backBottomLeftPoint2D.X, backBottomLeftPoint2D.Y, backBottomRightPoint2D.X, backBottomRightPoint2D.Y, color);
+ drawLine(backBottomRightPoint2D.X, backBottomRightPoint2D.Y, frontBottomRightPoint2D.X, frontBottomRightPoint2D.Y, color);
+ drawLine(frontBottomRightPoint2D.X, frontBottomRightPoint2D.Y, frontBottomLeftPoint2D.X, frontBottomLeftPoint2D.Y, color);
+ }
+ }
+ }
+}
diff --git a/engines/twine/debug.scene.h b/engines/twine/debug.scene.h
new file mode 100644
index 0000000000..f454cc058f
--- /dev/null
+++ b/engines/twine/debug.scene.h
@@ -0,0 +1,36 @@
+/** @file debug.scene.h
+ @brief
+ This file contains scenario debug routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef SCENE_DEBUG_H
+#define SCENE_DEBUG_H
+
+#include "sys.h"
+
+extern int32 showingZones;
+extern int32 typeZones;
+
+void displayZones(int16 pKey);
+
+#endif
diff --git a/engines/twine/detection.cpp b/engines/twine/detection.cpp
new file mode 100644
index 0000000000..a84e977ec9
--- /dev/null
+++ b/engines/twine/detection.cpp
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "engines/advancedDetector.h"
+#include "base/plugins.h"
+#include "twine/detection.h"
+
+static const PlainGameDescriptor twineGames[] = {
+ { "twine", "Little Big Adventure" },
+ { nullptr, nullptr }
+};
+
+static const ADGameDescription twineGameDescriptions[] = {
+ {
+ "twine",
+ "",
+ AD_ENTRY1s("infobar.txt", "f1e42a95972643462b9c3c2ea79d6683", 543),
+ Common::FR_FRA,
+ Common::kPlatformDOS,
+ TwinE::kGameFlagNoSubtitles,
+ GUIO1(GUIO_NOMIDI)
+ },
+ AD_TABLE_END_MARKER
+};
+
+class TwinEMetaEngineDetection : public AdvancedMetaEngineDetection {
+public:
+ TwinEMetaEngineDetection() : AdvancedMetaEngineDetection(twineGameDescriptions, sizeof(ADGameDescription), twineGames) {
+ _md5Bytes = 512;
+ }
+
+ const char *getEngineId() const override {
+ return "twine";
+ }
+
+ const char *getName() const override {
+ return "Little Big Adventure";
+ }
+
+ const char *getOriginalCopyright() const override {
+ return "Little Big Adventure (C) Adeline Software International";
+ }
+};
+
+REGISTER_PLUGIN_STATIC(TWINE_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, TwinEMetaEngineDetection);
diff --git a/engines/twine/detection.h b/engines/twine/detection.h
new file mode 100644
index 0000000000..9841764c9f
--- /dev/null
+++ b/engines/twine/detection.h
@@ -0,0 +1,37 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_DETECTION_H
+#define TWINE_DETECTION_H
+
+namespace TwinE {
+
+enum GameFlag {
+ kGameFlagDemo = 1 << 0,
+ kGameFlagEncodedData = 1 << 1,
+ kGameFlagNoSubtitles = 1 << 2,
+ kGameFlagIntroOnly = 1 << 3
+};
+
+} // End of namespace TwinE
+
+#endif // TWINE_DETECTION_H
diff --git a/engines/twine/extra.cpp b/engines/twine/extra.cpp
new file mode 100644
index 0000000000..5a8c72f8ed
--- /dev/null
+++ b/engines/twine/extra.cpp
@@ -0,0 +1,925 @@
+/** @file extra.cpp
+ @brief
+ This file contains extra (bonus, projectils, keys, etc.) routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+
+#include "extra.h"
+#include "lbaengine.h"
+#include "collision.h"
+#include "resources.h"
+#include "gamestate.h"
+#include "scene.h"
+#include "movements.h"
+#include "renderer.h"
+#include "grid.h"
+#include "sound.h"
+#include "redraw.h"
+#include "interface.h"
+
+/** Hit Stars shape info */
+int16 hitStarsShapeTable[] = {
+ 10,
+ 0,
+ -20,
+ 4,
+ -6,
+ 19,
+ -6,
+ 7,
+ 2,
+ 12,
+ 16,
+ 0,
+ 7,
+ -12,
+ 16,
+ -7,
+ 2,
+ -19,
+ -6,
+ -4,
+ -6
+};
+
+/** Explode Cloud shape info */
+int16 explodeCloudShapeTable [] = {
+ 18,
+ 0,
+ -20,
+ 6,
+ -16,
+ 8,
+ -10,
+ 14,
+ -12,
+ 20,
+ -4,
+ 18,
+ 4,
+ 12,
+ 4,
+ 16,
+ 8,
+ 8,
+ 16,
+ 2,
+ 12,
+ -4,
+ 18,
+ -10,
+ 16,
+ -12,
+ 8,
+ -16,
+ 10,
+ -20,
+ 4,
+ -12,
+ -8,
+ -6,
+ -6,
+ -10,
+ -12
+};
+
+int32 addExtra(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 info0, int32 targetActor, int32 maxSpeed, int32 strengthOfHit) {
+ int32 i;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 == -1) {
+ extra->info0 = info0;
+ extra->type = 0x80;
+ extra->info1 = 0;
+ extra->X = X;
+ extra->Y = Y;
+ extra->Z = Z;
+ extra->actorIdx = actorIdx;
+ extra->lifeTime = targetActor;
+ extra->destZ = maxSpeed;
+ extra->strengthOfHit = strengthOfHit;
+
+ setActorAngle(0, maxSpeed, 50, &extra->trackActorMove);
+ extra->angle = getAngleAndSetTargetActorDistance(X, Z, sceneActors[targetActor].X, sceneActors[targetActor].Z);
+ return i;
+ }
+ }
+ return -1;
+}
+
+/** Add extra explosion
+ @param X Explostion X coordinate
+ @param Y Explostion Y coordinate
+ @param Z Explostion Z coordinate */
+int32 addExtraExplode(int32 X, int32 Y, int32 Z) {
+ int32 i;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 == -1) {
+ extra->info0 = 0x61;
+ extra->type = 0x1001;
+ extra->info1 = 0;
+ extra->X = X;
+ extra->Y = Y;
+ extra->Z = Z;
+ extra->actorIdx = 0x28;
+ extra->lifeTime = lbaTime;
+ extra->strengthOfHit = 0;
+ return i;
+ }
+ }
+ return -1;
+}
+
+/** Reset all used extras */
+void resetExtras() {
+ int32 i;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ extra->info0 = -1;
+ extra->info1 = 1;
+ }
+}
+
+void throwExtra(ExtraListStruct *extra, int32 var1, int32 var2, int32 var3, int32 var4) { // InitFly
+ extra->type |= 2;
+
+ extra->lastX = extra->X;
+ extra->lastY = extra->Y;
+ extra->lastZ = extra->Z;
+
+ rotateActor(var3, 0, var1);
+
+ extra->destY = -destZ;
+
+ rotateActor(0, destX, var2);
+
+ extra->destX = destX;
+ extra->destZ = destZ;
+
+ extra->angle = var4;
+ extra->lifeTime = lbaTime;
+}
+
+void addExtraSpecial(int32 X, int32 Y, int32 Z, int32 type) { // InitSpecial
+ int32 i;
+ int16 flag = 0x8000 + type;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 == -1) {
+ extra->info0 = flag;
+ extra->info1 = 0;
+
+ if (type == kHitStars) {
+ extra->type = 9;
+
+ extra->X = X;
+ extra->Y = Y;
+ extra->Z = Z;
+
+ // same as InitFly
+ throwExtra(extra, Rnd(0x100) + 0x80, Rnd(0x400), 50, 20);
+
+ extra->strengthOfHit = 0;
+ extra->lifeTime = lbaTime;
+ extra->actorIdx = 100;
+
+ return;
+ } else if (type == kExplodeCloud) {
+ extra->type = 1;
+
+ extra->X = X;
+ extra->Y = Y;
+ extra->Z = Z;
+
+ extra->strengthOfHit = 0;
+ extra->lifeTime = lbaTime;
+ extra->actorIdx = 5;
+
+ return;
+ }
+ }
+ }
+}
+
+int32 addExtraBonus(int32 X, int32 Y, int32 Z, int32 param, int32 angle, int32 type, int32 bonusAmount) { // ExtraBonus
+ int32 i;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 == -1) {
+ extra->info0 = type;
+ extra->type = 0x4071;
+
+ /*if(type == SPRITEHQR_KEY) {
+ extra->type = 0x4030;
+ }*/
+
+ extra->X = X;
+ extra->Y = Y;
+ extra->Z = Z;
+
+ // same as InitFly
+ throwExtra(extra, param, angle, 40, 15);
+
+ extra->strengthOfHit = 0;
+ extra->lifeTime = lbaTime;
+ extra->actorIdx = 1000;
+ extra->info1 = bonusAmount;
+
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int32 addExtraThrow(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprite, int32 var2, int32 var3, int32 var4, int32 var5, int32 strengthOfHit) { // ThrowExtra
+ int32 i;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 == -1) {
+ extra->info0 = sprite;
+ extra->type = 0x210C;
+ extra->X = X;
+ extra->Y = Y;
+ extra->Z = Z;
+
+ // same as InitFly
+ throwExtra(extra, var2, var3, var4, var5);
+
+ extra->strengthOfHit = strengthOfHit;
+ extra->lifeTime = lbaTime;
+ extra->actorIdx = actorIdx;
+ extra->info1 = 0;
+
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int32 addExtraAiming(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 targetActorIdx, int32 maxSpeed, int32 strengthOfHit) { // ExtraSearch
+ int32 i;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 == -1) {
+ extra->info0 = spriteIdx;
+ extra->type = 0x80;
+ extra->info1 = 0;
+ extra->X = X;
+ extra->Y = Y;
+ extra->Z = Z;
+ extra->actorIdx = actorIdx;
+ extra->lifeTime = targetActorIdx;
+ extra->destZ = maxSpeed;
+ extra->strengthOfHit = strengthOfHit;
+ setActorAngle(0, maxSpeed, 50, &extra->trackActorMove);
+ extra->angle = getAngleAndSetTargetActorDistance(X, Z, sceneActors[targetActorIdx].X, sceneActors[targetActorIdx].Z);
+
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+// cseg01:00018168
+int32 findExtraKey() {
+ int32 i;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 == SPRITEHQR_KEY) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+// cseg01:00018250
+int32 addExtraAimingAtKey(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 extraIdx) { // addMagicBallAimingAtKey
+ int32 i;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 == -1) {
+ extra->info0 = spriteIdx;
+ extra->type = 0x200;
+ extra->info1 = 0;
+ extra->X = X;
+ extra->Y = Y;
+ extra->Z = Z;
+ extra->actorIdx = extraIdx;
+ extra->destZ = 0x0FA0;
+ extra->strengthOfHit = 0;
+ setActorAngle(0, 0x0FA0, 50, &extra->trackActorMove);
+ extra->angle = getAngleAndSetTargetActorDistance(X, Z, extraList[extraIdx].X, extraList[extraIdx].Z);
+
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void addExtraThrowMagicball(int32 X, int32 Y, int32 Z, int32 param1, int32 angle, int32 param2, int32 param3) { // ThrowMagicBall
+ int32 ballSprite = -1;
+ int32 ballStrength = 0;
+ int32 extraIdx = -1;
+
+ switch (magicLevelIdx) {
+ case 0:
+ case 1:
+ ballSprite = 1;
+ ballStrength = 4;
+ break;
+ case 2:
+ ballSprite = 42;
+ ballStrength = 6;
+ break;
+ case 3:
+ ballSprite = 43;
+ ballStrength = 8;
+ break;
+ case 4:
+ ballSprite = 13;
+ ballStrength = 10;
+ break;
+ }
+
+ magicBallNumBounce = ((inventoryMagicPoints - 1) / 20) + 1;
+ if (inventoryMagicPoints == 0) {
+ magicBallNumBounce = 0;
+ }
+
+ extraIdx = findExtraKey();
+ if (extraIdx != -1) { // there is a key to aim
+ magicBallNumBounce = 5;
+ }
+
+ switch (magicBallNumBounce) {
+ case 0:
+ magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
+ break;
+ case 1:
+ magicBallAuxBounce = 4;
+ magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ magicBallNumBounce = 1;
+ magicBallAuxBounce = 4;
+ magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
+ break;
+ case 5:
+ magicBallIdx = addExtraAimingAtKey(0, X, Y, Z, ballSprite, extraIdx);
+ break;
+ }
+
+ if (inventoryMagicPoints > 0) {
+ inventoryMagicPoints--;
+ }
+}
+
+void drawSpecialShape(int16 *shapeTable, int32 X, int32 Y, int32 color, int32 angle, int32 size) {
+ int16 currentShapeTable;
+ int16 var_8;
+ int16 temp1;
+ int32 computedX;
+ int32 computedY;
+ int32 oldComputedX;
+ int32 oldComputedY;
+ int32 numEntries;
+ int32 currentX;
+ int32 currentY;
+
+ currentShapeTable = *(shapeTable++);
+
+ var_8 = ((*(shapeTable++)) * size) >> 4;
+ temp1 = ((*(shapeTable++)) * size) >> 4;
+
+ renderLeft = 0x7D00;
+ renderRight = -0x7D00;
+ renderTop = 0x7D00;
+ renderBottom = -0x7D00;
+
+ rotateActor(var_8, temp1, angle);
+
+ computedX = destX + X;
+ computedY = destZ + Y;
+
+ if (computedX < renderLeft)
+ renderLeft = computedX;
+
+ if (computedX > renderRight)
+ renderRight = computedX;
+
+ if (computedY < renderTop)
+ renderTop = computedY;
+
+ if (computedY > renderBottom)
+ renderBottom = computedY;
+
+ numEntries = 1;
+
+ currentX = computedX;
+ currentY = computedY;
+
+ while (numEntries < currentShapeTable) {
+ var_8 = ((*(shapeTable++)) * size) >> 4;
+ temp1 = ((*(shapeTable++)) * size) >> 4;
+
+ oldComputedX = currentX;
+ oldComputedY = currentY;
+
+ projPosX = currentX;
+ projPosY = currentY;
+
+ rotateActor(var_8, temp1, angle);
+
+ currentX = destX + X;
+ currentY = destZ + Y;
+
+ if (currentX < renderLeft)
+ renderLeft = currentX;
+
+ if (currentX > renderRight)
+ renderRight = currentX;
+
+ if (currentY < renderTop)
+ renderTop = currentY;
+
+ if (currentY > renderBottom)
+ renderBottom = currentY;
+
+ projPosX = currentX;
+ projPosY = currentY;
+
+ drawLine(oldComputedX, oldComputedY, currentX, currentY, color);
+
+ numEntries++;
+
+ currentX = projPosX;
+ currentY = projPosY;
+
+ }
+
+ projPosX = currentX;
+ projPosY = currentY;
+ drawLine(currentX, currentY, computedX, computedY, color);
+}
+
+void drawExtraSpecial(int32 extraIdx, int32 X, int32 Y) {
+ int32 specialType;
+ ExtraListStruct *extra = &extraList[extraIdx];
+
+ specialType = extra->info0 & 0x7FFF;
+
+ switch(specialType) {
+ case kHitStars:
+ drawSpecialShape(hitStarsShapeTable, X, Y, 15, (lbaTime << 5) & 0x300, 4);
+ break;
+ case kExplodeCloud: {
+ int32 cloudTime = 1 + lbaTime - extra->lifeTime;
+
+ if (cloudTime > 32) {
+ cloudTime = 32;
+ }
+
+ drawSpecialShape(explodeCloudShapeTable, X, Y, 15, 0, cloudTime);
+ }
+ break;
+ }
+}
+
+void processMagicballBounce(ExtraListStruct *extra, int32 X, int32 Y, int32 Z) {
+ if (getBrickShape(X, extra->Y, Z)) {
+ extra->destY = -extra->destY;
+ }
+ if (getBrickShape(extra->X, Y, Z)) {
+ extra->destX = -extra->destX;
+ }
+ if (getBrickShape(X, Y, extra->Z)) {
+ extra->destZ = -extra->destZ;
+ }
+
+ extra->X = X;
+ extra->lastX = X;
+ extra->Y = Y;
+ extra->lastY = Y;
+ extra->Z = Z;
+ extra->lastZ = Z;
+
+ extra->lifeTime = lbaTime;
+}
+
+/** Process extras */
+void processExtras() {
+ int32 i;
+
+ int32 currentExtraX = 0;
+ int32 currentExtraY = 0;
+ int32 currentExtraZ = 0;
+ int32 currentExtraSpeedX = 0;
+ int32 currentExtraSpeedY = 0;
+
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extra = &extraList[i];
+ if (extra->info0 != -1) {
+ // process extra life time
+ if (extra->type & 0x1) {
+ if (extra->actorIdx + extra->lifeTime <= lbaTime) {
+ extra->info0 = -1;
+ continue;
+ }
+ }
+ // reset extra
+ if (extra->type & 0x800) {
+ extra->info0 = -1;
+ continue;
+ }
+ //
+ if (extra->type & 0x1000) {
+ extra->info0 = getAverageValue(97, 100, 30, lbaTime - extra->lifeTime);
+ continue;
+ }
+ // process extra moving
+ if (extra->type & 0x2) {
+ currentExtraX = extra->X;
+ currentExtraY = extra->Y;
+ currentExtraZ = extra->Z;
+
+ currentExtraSpeedX = extra->destX * (lbaTime - extra->lifeTime);
+ extra->X = currentExtraSpeedX + extra->lastX;
+
+ currentExtraSpeedY = extra->destY * (lbaTime - extra->lifeTime);
+ currentExtraSpeedY += extra->lastY;
+ extra->Y = currentExtraSpeedY - Abs(((extra->angle * (lbaTime - extra->lifeTime))* (lbaTime - extra->lifeTime)) >> 4);
+
+ extra->Z = extra->destZ * (lbaTime - extra->lifeTime) + extra->lastZ;
+
+ // check if extra is out of scene
+ if (extra->Y < 0 || extra->X < 0 || extra->X > 0x7E00 || extra->Z < 0 || extra->Z > 0x7E00) {
+ // if extra is Magic Ball
+ if (i == magicBallIdx) {
+ int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
+
+ if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
+ spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
+ }
+ if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
+ spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
+ }
+
+ magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 10000, 0);
+ }
+
+ // if can take extra on ground
+ if (extra->type & 0x20) {
+ extra->type &= 0xFFED;
+ } else {
+ extra->info0 = -1;
+ }
+
+ continue;
+ }
+ }
+ //
+ if (extra->type & 0x4000) {
+ if (lbaTime - extra->lifeTime > 40) {
+ extra->type &= 0xBFFF;
+ }
+ continue;
+ }
+ // process actor target hit
+ if (extra->type & 0x80) {
+ int32 actorIdx, actorIdxAttacked, tmpAngle, angle;
+
+ actorIdxAttacked = extra->lifeTime;
+ actorIdx = extra->actorIdx;
+
+ currentExtraX = sceneActors[actorIdxAttacked].X;
+ currentExtraY = sceneActors[actorIdxAttacked].Y + 1000;
+ currentExtraZ = sceneActors[actorIdxAttacked].Z;
+
+ tmpAngle = getAngleAndSetTargetActorDistance(extra->X, extra->Z, currentExtraX, currentExtraZ);
+ angle = (tmpAngle - extra->angle) & 0x3FF;
+
+ if (angle > 400 && angle < 600) {
+ if (extra->strengthOfHit) {
+ hitActor(actorIdx, actorIdxAttacked, extra->strengthOfHit, -1);
+ }
+
+ if (i == magicBallIdx) {
+ magicBallIdx = -1;
+ }
+
+ extra->info0 = -1;
+ continue;
+ } else {
+ int32 angle, pos;
+
+ angle = getAngleAndSetTargetActorDistance(extra->Y, 0, currentExtraY, targetActorDistance);
+
+ pos = getRealAngle(&extra->trackActorMove);
+
+ if (!pos) {
+ pos = 1;
+ }
+
+ rotateActor(pos, 0, angle);
+ extra->Y -= destZ;
+
+ rotateActor(0, destX, tmpAngle);
+ extra->X += destX;
+ extra->Z += destZ;
+
+ setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
+
+ if (actorIdxAttacked == checkExtraCollisionWithActors(extra, actorIdx)) {
+ if (i == magicBallIdx) {
+ magicBallIdx = -1;
+ }
+
+ extra->info0 = -1;
+ continue;
+ }
+ }
+ }
+ // process magic ball extra aiming for key
+ if (extra->type & 0x200) {
+ int32 actorIdx, tmpAngle, angle;
+// int32 actorIdxAttacked = extra->lifeTime;
+ ExtraListStruct *extraKey = &extraList[extra->actorIdx];
+ actorIdx = extra->actorIdx;
+
+ tmpAngle = getAngleAndSetTargetActorDistance(extra->X, extra->Z, extraKey->X, extraKey->Z);
+ angle = (tmpAngle - extra->angle) & 0x3FF;
+
+ if (angle > 400 && angle < 600) {
+ playSample(97, 0x1000, 1, sceneHero->X, sceneHero->Y, sceneHero->Z, 0);
+
+ if (extraKey->info1 > 1) {
+ projectPositionOnScreen(extraKey->X - cameraX, extraKey->Y - cameraY, extraKey->Z - cameraZ);
+ addOverlay(koNumber, extraKey->info1, projPosX, projPosY, koNormal, 0, 2);
+ }
+
+ addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
+
+ inventoryNumKeys += extraKey->info1;
+ extraKey->info0 = -1;
+
+ extra->info0 = -1;
+ magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, SPRITEHQR_KEY, 0, 8000, 0);
+ continue;
+ } else {
+ int32 angle, pos;
+
+ angle = getAngleAndSetTargetActorDistance(extra->Y, 0, extraKey->Y, targetActorDistance);
+ pos = getRealAngle(&extra->trackActorMove);
+
+ if (!pos) {
+ pos = 1;
+ }
+
+ rotateActor(pos, 0, angle);
+ extra->Y -= destZ;
+
+ rotateActor(0, destX, tmpAngle);
+ extra->X += destX;
+ extra->Z += destZ;
+
+ setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
+
+ if (actorIdx == checkExtraCollisionWithExtra(extra, magicBallIdx)) {
+ playSample(97, 0x1000, 1, sceneHero->X, sceneHero->Y, sceneHero->Z, 0);
+
+ if (extraKey->info1 > 1) {
+ projectPositionOnScreen(extraKey->X - cameraX, extraKey->Y - cameraY, extraKey->Z - cameraZ);
+ addOverlay(koNumber, extraKey->info1, projPosX, projPosY, koNormal, 0, 2);
+ }
+
+ addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
+
+ inventoryNumKeys += extraKey->info1;
+ extraKey->info0 = -1;
+
+ extra->info0 = -1;
+ magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, SPRITEHQR_KEY, 0, 8000, 0);
+ continue;
+ }
+ }
+ if (extraKey->info0 == -1) {
+ int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
+
+ if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
+ spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
+ }
+ if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
+ spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
+ }
+
+ extra->info0 = -1;
+ magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 8000, 0);
+ continue;
+ }
+ }
+ // process extra collision with actors
+ if (extra->type & 0x4) {
+ if (checkExtraCollisionWithActors(extra, extra->actorIdx) != -1) {
+ // if extra is Magic Ball
+ if (i == magicBallIdx) {
+ int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
+
+ if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
+ spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
+ }
+ if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
+ spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
+ }
+
+ magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 10000, 0);
+ }
+
+ extra->info0 = -1;
+ continue;
+ }
+ }
+ // process extra collision with scene ground
+ if (extra->type & 0x8) {
+ int32 process = 0;
+
+ if (checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->X, extra->Y, extra->Z)) {
+ // if not touch the ground
+ if (!(extra->type & 0x2000)) {
+ process = 1;
+ }
+ } else {
+ // if touch the ground
+ if (extra->type & 0x2000) {
+ extra->type &= 0xDFFF; // set flag out of ground
+ }
+ }
+
+ if (process) {
+ // show explode cloud
+ if (extra->type & 0x100) {
+ addExtraSpecial(currentExtraX, currentExtraY, currentExtraZ, kExplodeCloud);
+ }
+ // if extra is magic ball
+ if (i == magicBallIdx) {
+ // FIXME: add constant for sample index
+ playSample(86, Rnd(300) + 3946, 1, extra->X, extra->Y, extra->Z, -1);
+
+ // cant bounce with not magic points
+ if (magicBallNumBounce <= 0) {
+ int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
+
+ if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
+ spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
+ }
+ if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
+ spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
+ }
+
+ magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 10000, 0);
+
+ extra->info0 = -1;
+ continue;
+ }
+
+ // if has magic points
+ if (magicBallNumBounce == 1) {
+ if (!magicBallAuxBounce--) {
+ int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
+
+ if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
+ spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
+ }
+ if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
+ spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
+ }
+
+ magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 10000, 0);
+
+ extra->info0 = -1;
+ continue;
+ } else {
+ processMagicballBounce(extra, currentExtraX, currentExtraY, currentExtraZ);
+ }
+ }
+ } else {
+ extra->info0 = -1;
+ continue;
+ }
+ }
+ }
+ // extra stop moving while collision with bricks
+ if (extra->type & 0x10) {
+ int32 process = 0;
+
+ if (checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->X, extra->Y, extra->Z)) {
+ // if not touch the ground
+ if (!(extra->type & 0x2000)) {
+ process = 1;
+ }
+ } else {
+ // if touch the ground
+ if (extra->type & 0x2000) {
+ extra->type &= 0xDFFF; // set flag out of ground
+ }
+ }
+
+ if (process) {
+ int16 *spriteBounds;
+
+ spriteBounds = (int16 *)(spriteBoundingBoxPtr + extra->info0 * 16 + 8);
+ extra->Y = (collisionY << 8) + 0x100 - *(spriteBounds);
+ extra->type &= 0xFFED;
+ continue;
+ }
+ }
+ // get extras on ground
+ if ((extra->type & 0x20) && !(extra->type & 0x2)) {
+ // if hero touch extra
+ if (checkExtraCollisionWithActors(extra, -1) == 0) {
+ // FIXME: add constant for sample index
+ playSample(97, 0x1000, 1, extra->X, extra->Y, extra->Z, -1);
+
+ if (extra->info1 > 1 && !(loopPressedKey & 2)) {
+ projectPositionOnScreen(extra->X - cameraX, extra->Y - cameraY, extra->Z - cameraZ);
+ addOverlay(koNumber, extra->info1, projPosX, projPosY, 158, koNormal, 2);
+ }
+
+ addOverlay(koSprite, extra->info0, 10, 30, 0, koNormal, 2);
+
+ if (extra->info0 == SPRITEHQR_KASHES) {
+ inventoryNumKashes += extra->info1;
+ if (inventoryNumKashes > 999) {
+ inventoryNumKashes = 999;
+ }
+ }
+
+ if (extra->info0 == SPRITEHQR_LIFEPOINTS) {
+ sceneHero->life += extra->info1;
+ if (sceneHero->life > 50) {
+ sceneHero->life = 50;
+ }
+ }
+
+ if (extra->info0 == SPRITEHQR_MAGICPOINTS && magicLevelIdx) {
+ inventoryMagicPoints += extra->info1 * 2;
+ if (inventoryMagicPoints > magicLevelIdx * 20) {
+ inventoryMagicPoints = magicLevelIdx * 20;
+ }
+ }
+
+ if (extra->info0 == SPRITEHQR_KEY) {
+ inventoryNumKeys += extra->info1;
+ }
+
+ if (extra->info0 == SPRITEHQR_CLOVERLEAF) {
+ inventoryNumLeafs += extra->info1;
+ if (inventoryNumLeafs > inventoryNumLeafsBox) {
+ inventoryNumLeafs = inventoryNumLeafsBox;
+ }
+ }
+
+ extra->info0 = -1;
+ }
+ }
+ }
+ }
+}
+
diff --git a/engines/twine/extra.h b/engines/twine/extra.h
new file mode 100644
index 0000000000..c0a6bac048
--- /dev/null
+++ b/engines/twine/extra.h
@@ -0,0 +1,89 @@
+/** @file extra.h
+ @brief
+ This file contains extra (bonus, projectils, keys, etc.) routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sys.h"
+#include "actor.h"
+
+#ifndef EXTRA_H
+#define EXTRA_H
+
+#define EXTRA_MAX_ENTRIES 50
+
+typedef struct ExtraListStruct
+{
+ int16 info0; // field_0
+ int16 X;
+ int16 Y;
+ int16 Z;
+
+ int16 lastX; // field_8
+ int16 lastY; // field_A
+ int16 lastZ; // field_C
+
+ ActorMoveStruct trackActorMove;
+
+ int16 destX; // field_E
+ int16 destY; // field_10
+ int16 destZ; // field_12
+ int16 type; // field_14
+ int16 angle; // field_16
+ int32 lifeTime;
+ int16 actorIdx; // field_ 1C
+ int16 strengthOfHit; // field_1E
+ int16 info1; // field_20
+} ExtraListStruct;
+
+ExtraListStruct extraList[EXTRA_MAX_ENTRIES];
+
+enum ExtraSpecialType {
+ kHitStars = 0,
+ kExplodeCloud = 1
+};
+
+int32 addExtra(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 info0, int32 targetActor, int32 maxSpeed, int32 strengthOfHit);
+
+/** Add extra explosion
+ @param X Explostion X coordinate
+ @param Y Explostion Y coordinate
+ @param Z Explostion Z coordinate */
+int32 addExtraExplode(int32 X, int32 Y, int32 Z);
+
+/** Reset all used extras */
+void resetExtras();
+
+void addExtraSpecial(int32 X, int32 Y, int32 Z, int32 type);
+int32 addExtraBonus(int32 X, int32 Y, int32 Z, int32 param, int32 angle, int32 type, int32 bonusAmount);
+int32 addExtraThrow(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprite, int32 var2, int32 var3, int32 var4, int32 var5, int32 strengthOfHit);
+int32 addExtraAiming(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 targetActorIdx, int32 maxSpeed, int32 strengthOfHit);
+void addExtraThrowMagicball(int32 X, int32 Y, int32 Z, int32 param1, int32 angle, int32 param2, int32 param3);
+
+void drawExtraSpecial(int32 extraIdx, int32 X, int32 Y);
+
+/** Process extras */
+void processExtras();
+
+
+#endif
+
diff --git a/engines/twine/fcaseopen.cpp b/engines/twine/fcaseopen.cpp
new file mode 100644
index 0000000000..fd5e7533fc
--- /dev/null
+++ b/engines/twine/fcaseopen.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2009 Keith Bauer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "fcaseopen.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <dirent.h>
+#endif
+
+#ifndef WIN32
+
+// r must have strlen(path) + 2 bytes
+static int casepath(char const *path, char *r)
+{
+ size_t l = strlen(path);
+ char *p = alloca(l + 1);
+ strcpy(p, path);
+ size_t rl = 0;
+
+ DIR *d;
+ if (p[0] == '/')
+ {
+ d = opendir("/");
+ p = p + 1;
+ }
+ else
+ {
+ d = opendir(".");
+ r[0] = '.';
+ r[1] = 0;
+ rl = 1;
+ }
+
+ int last = 0;
+ char *c = strsep(&p, "/");
+ while (c)
+ {
+ if (!d)
+ {
+ return 0;
+ }
+
+ if (last)
+ {
+ closedir(d);
+ return 0;
+ }
+
+ r[rl] = '/';
+ rl += 1;
+ r[rl] = 0;
+
+ struct dirent *e = readdir(d);
+ while (e)
+ {
+ if (strcasecmp(c, e->d_name) == 0)
+ {
+ strcpy(r + rl, e->d_name);
+ rl += strlen(e->d_name);
+
+ closedir(d);
+ d = opendir(r);
+
+ break;
+ }
+
+ e = readdir(d);
+ }
+
+ if (!e)
+ {
+ strcpy(r + rl, c);
+ rl += strlen(c);
+ last = 1;
+ }
+
+ c = strsep(&p, "/");
+ }
+
+ if (d) closedir(d);
+ return 1;
+}
+#endif
+
+FILE *fcaseopen(char const *path, char const *mode)
+{
+ FILE *f = fopen(path, mode);
+#ifndef WIN32
+ if (!f)
+ {
+ char *r = alloca(strlen(path) + 2);
+ if (casepath(path, r))
+ {
+ f = fopen(r, mode);
+ }
+ }
+#endif
+ return f;
+}
+
+void casechdir(char const *path)
+{
+#ifndef WIN32
+ char *r = alloca(strlen(path) + 2);
+ if (casepath(path, r))
+ {
+ chdir(r);
+ }
+ else
+ {
+ errno = ENOENT;
+ }
+#else
+ _chdir(path);
+#endif
+}
diff --git a/engines/twine/fcaseopen.h b/engines/twine/fcaseopen.h
new file mode 100644
index 0000000000..379a6d4174
--- /dev/null
+++ b/engines/twine/fcaseopen.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2009 Keith Bauer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef fcaseopen_h
+#define fcaseopen_h
+
+#include <stdio.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern FILE *fcaseopen(char const *path, char const *mode);
+
+extern void casechdir(char const *path);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/engines/twine/filereader.cpp b/engines/twine/filereader.cpp
new file mode 100644
index 0000000000..0b9a70ac78
--- /dev/null
+++ b/engines/twine/filereader.cpp
@@ -0,0 +1,112 @@
+/** @file filereader.cpp
+ @brief
+ This file contains file read routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "filereader.h"
+#include "fcaseopen.h"
+#include <ctype.h>
+
+/** Feed buffer from file
+ @param fr FileReader pointer */
+void frfeed(FileReader* fr) {
+ fread(fr->buffer, BUFFER_SIZE, 1, fr->fd);
+ fr->bufferPos = 0;
+}
+
+/** Read file
+ @param fr FileReader pointer
+ @param destPtr content destination pointer
+ @param size size of read characters */
+void frread(FileReader* fr, void* destPtr, uint32 size) {
+ if (BUFFER_SIZE - fr->bufferPos >= size) {
+ memcpy(destPtr, &fr->buffer[fr->bufferPos], size);
+ fr->bufferPos += size;
+ } else {
+ // feed what we can
+ int8* tempPtr = (int8*)destPtr;
+ memcpy(tempPtr, &fr->buffer[fr->bufferPos], BUFFER_SIZE - fr->bufferPos);
+ tempPtr += BUFFER_SIZE - fr->bufferPos;
+ size -= BUFFER_SIZE - fr->bufferPos;
+
+ // feed the rest
+ do {
+ fr->currSector++;
+ frfeed(fr);
+ if (size >= BUFFER_SIZE) {
+ memcpy(tempPtr, fr->buffer, BUFFER_SIZE);
+ tempPtr += BUFFER_SIZE;
+ size -= BUFFER_SIZE;
+ } else {
+ memcpy(tempPtr, fr->buffer, size);
+ fr->bufferPos += size;
+ size = 0;
+ }
+ } while (size > 0);
+ }
+}
+
+/** Seek file
+ @param fr FileReader pointer
+ @param seekPosition position to seek */
+void frseek(FileReader* fr, uint32 seekPosition) {
+ uint32 sectorToSeek;
+
+ sectorToSeek = seekPosition / 2048;
+
+ fseek(fr->fd, sectorToSeek * 2048, SEEK_SET);
+
+ fr->currSector = sectorToSeek;
+ frfeed(fr);
+ fr->bufferPos = (seekPosition - (sectorToSeek * 2048));
+}
+
+/** Open file
+ @param fr FileReader pointer
+ @param filename file path
+ @return true if file open and false if error occurred */
+int32 fropen2(FileReader* fr, char* filename, const char* mode) {
+ fr->fd = fcaseopen(filename, mode);
+
+ if (fr->fd) {
+ fr->currSector = 0;
+ frfeed(fr);
+ return 1;
+ }
+
+ return 0;
+}
+
+/** Write file
+ @param fr FileReader pointer
+ @param destPtr content destination pointer
+ @param size size of read characters */
+void frwrite(FileReader* fr, void* destPtr, uint32 size, uint32 count) {
+ fwrite(destPtr, size, count, fr->fd);
+}
+
+/** Close file
+ @param fr FileReader pointer */
+void frclose(FileReader* fr) {
+ fclose(fr->fd);
+}
diff --git a/engines/twine/filereader.h b/engines/twine/filereader.h
new file mode 100644
index 0000000000..8200565410
--- /dev/null
+++ b/engines/twine/filereader.h
@@ -0,0 +1,83 @@
+/** @file filereader.h
+ @brief
+ This file contains file read routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef FILEREADER_H
+#define FILEREADER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sys.h"
+
+/** Number of sector in the buffer */
+#define SECTORS_IN_BUFFER (3)
+/** Buffer size */
+#define BUFFER_SIZE (2048*SECTORS_IN_BUFFER)
+
+/** File reader structure */
+typedef struct FileReader {
+ /** File descriptor */
+ FILE* fd;
+ /** Content buffer */
+ uint8 buffer[BUFFER_SIZE];
+ /** Current position in the buffer */
+ uint32 bufferPos;
+ /** Current sector in the buffer */
+ uint32 currSector;
+} FileReader;
+
+/** Feed buffer from file
+ @param fr FileReader pointer */
+void frfeed(FileReader* fr);
+
+/** Read file
+ @param fr FileReader pointer
+ @param destPtr content destination pointer
+ @param size size of read characters */
+void frread(FileReader* fr, void* destPtr, uint32 size);
+
+/** Seek file
+ @param fr FileReader pointer
+ @param seekPosition position to seek */
+void frseek(FileReader* fr, uint32 seekPosition);
+
+/** Open file
+ @param fr FileReader pointer
+ @param filename file path
+ @return true if file open and false if error occurred */
+int32 fropen2(FileReader* fr, char* filename, const char* mode);
+
+/** Write file
+ @param fr FileReader pointer
+ @param destPtr content destination pointer
+ @param size size of read characters */
+void frwrite(FileReader* fr, void* destPtr, uint32 size, uint32 count);
+
+/** Close file
+ @param fr FileReader pointer */
+void frclose(FileReader* fr);
+
+#endif
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
new file mode 100644
index 0000000000..2eecd0f563
--- /dev/null
+++ b/engines/twine/flamovies.cpp
@@ -0,0 +1,492 @@
+/** @file movies.cpp
+ @brief
+ This file contains movies routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "flamovies.h"
+#include "screens.h"
+#include "sdlengine.h"
+#include "main.h"
+#include "sound.h"
+#include "music.h"
+#include "filereader.h"
+#include "lbaengine.h"
+#include "keyboard.h"
+
+/** Config movie types */
+#define CONF_MOVIE_NONE 0
+#define CONF_MOVIE_FLA 1
+#define CONF_MOVIE_FLAWIDE 2
+#define CONF_MOVIE_FLAPCX 3
+
+/** FLA movie extension */
+#define FLA_EXT ".fla"
+
+/** FLA Frame Opcode types */
+enum FlaFrameOpcode {
+ kLoadPalette = 0,
+ kFade = 1,
+ kPlaySample = 2,
+ kStopSample = 4,
+ kDeltaFrame = 5,
+ kKeyFrame = 7
+};
+
+/** Auxiliar FLA fade out variable */
+int32 _fadeOut;
+/** Auxiliar FLA fade out variable to count frames between the fade */
+int32 fadeOutFrames;
+
+/** FLA movie sample auxiliar table */
+int32 flaSampleTable[100];
+/** Number of samples in FLA movie */
+int32 samplesInFla;
+/** Auxiliar work video buffer */
+uint8* workVideoBufferCopy;
+/** FLA movie header data */
+FLAHeaderStruct flaHeaderData;
+/** FLA movie header data */
+FLAFrameDataStruct frameData;
+
+FileReader frFla;
+
+/** FLA movie draw key frame
+ @param ptr FLA frame buffer pointer
+ @param width FLA movie width
+ @param height FLA movie height */
+void drawKeyFrame(uint8 * ptr, int32 width, int32 height) {
+ int32 a, b;
+ uint8 * destPtr = (uint8 *)flaBuffer;
+ uint8 * startOfLine = destPtr;
+ int8 flag1;
+ int8 flag2;
+
+ do {
+ flag1 = *(ptr++);
+
+ for (a = 0; a < flag1; a++) {
+ flag2 = *(ptr++);
+
+ if (flag2 < 0) {
+ flag2 = - flag2;
+ for (b = 0; b < flag2; b++) {
+ *(destPtr++) = *(ptr++);
+ }
+ } else {
+ char colorFill;
+
+ colorFill = *(ptr++);
+
+ for (b = 0; b < flag2; b++) {
+ *(destPtr++) = colorFill;
+ }
+ }
+ }
+
+ startOfLine = destPtr = startOfLine + width;
+ } while (--height);
+}
+
+/** FLA movie draw delta frame
+ @param ptr FLA frame buffer pointer
+ @param width FLA movie width */
+void drawDeltaFrame(uint8 * ptr, int32 width) {
+ int32 a, b;
+ uint16 skip;
+ uint8 * destPtr;
+ uint8 * startOfLine;
+ int32 height;
+
+ int8 flag1;
+ int8 flag2;
+
+ skip = *((uint16*)ptr);
+ ptr += 2;
+ skip *= width;
+ startOfLine = destPtr = (uint8 *)flaBuffer + skip;
+ height = *((int16*)ptr);
+ ptr += 2;
+
+ do {
+ flag1 = *(ptr++);
+
+ for (a = 0; a < flag1; a++) {
+ destPtr += (unsigned char) * (ptr++);
+ flag2 = *(ptr++);
+
+ if (flag2 > 0) {
+ for (b = 0; b < flag2; b++) {
+ *(destPtr++) = *(ptr++);
+ }
+ } else {
+ char colorFill;
+ flag2 = - flag2;
+
+ colorFill = *(ptr++);
+
+ for (b = 0; b < flag2; b++) {
+ *(destPtr++) = colorFill;
+ }
+ }
+ }
+
+ startOfLine = destPtr = startOfLine + width;
+ } while (--height);
+}
+
+/** Scale FLA movie 2 times
+
+ According with the settins we can put the original aspect radio stretch
+ to fullscreen or preserve it and use top and button black bars */
+void scaleFla2x() {
+ int32 i, j;
+ uint8* source = (uint8*)flaBuffer;
+ uint8* dest = (uint8*)workVideoBuffer;
+
+ if (cfgfile.Movie == CONF_MOVIE_FLAWIDE) {
+ for (i = 0; i < SCREEN_WIDTH / SCALE*40; i++) {
+ *(dest++) = 0x00;
+ }
+ }
+
+ for (i = 0; i < FLASCREEN_HEIGHT; i++) {
+ for (j = 0; j < FLASCREEN_WIDTH; j++) {
+ *(dest++) = *(source);
+ *(dest++) = *(source++);
+ }
+ if (cfgfile.Movie == CONF_MOVIE_FLAWIDE) { // include wide bars
+ memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH*2);
+ dest += FLASCREEN_WIDTH * 2;
+ } else { // stretch the movie like original game.
+ if (i % (2)) {
+ memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH*2);
+ dest += FLASCREEN_WIDTH * 2;
+ }
+ if (i % 10) {
+ memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH*2);
+ dest += FLASCREEN_WIDTH * 2;
+ }
+ }
+ }
+
+ if (cfgfile.Movie == CONF_MOVIE_FLAWIDE) {
+ for (i = 0; i < SCREEN_WIDTH / SCALE*40; i++) {
+ *(dest++) = 0x00;
+ }
+ }
+}
+
+/** FLA movie process frame */
+void processFrame() {
+ FLASampleStruct sample;
+ uint32 opcodeBlockSize;
+ uint8 opcode;
+ int32 aux = 0;
+ uint8 * ptr;
+
+ frread(&frFla, &frameData.videoSize, 1);
+ frread(&frFla, &frameData.dummy, 1);
+ frread(&frFla, &frameData.frameVar0, 4);
+
+ frread(&frFla, workVideoBufferCopy, frameData.frameVar0);
+
+ if ((int32)frameData.videoSize <= 0)
+ return;
+
+ ptr = workVideoBufferCopy;
+
+ do {
+ opcode = *((uint8*)ptr);
+ ptr += 2;
+ opcodeBlockSize = *((uint16*)ptr);
+ ptr += 2;
+
+ switch (opcode - 1) {
+ case kLoadPalette: {
+ int16 numOfColor = *((int16*)ptr);
+ int16 startColor = *((int16*)(ptr + 2));
+ memcpy((palette + (startColor*3)), (ptr + 4), numOfColor*3);
+ break;
+ }
+ case kFade: {
+ // FLA movies don't use cross fade
+ // fade out tricky
+ if (_fadeOut != 1) {
+ convertPalToRGBA(palette, paletteRGBACustom);
+ fadeToBlack(paletteRGBACustom);
+ _fadeOut = 1;
+ }
+ break;
+ }
+ case kPlaySample: {
+ memcpy(&sample, ptr, sizeof(FLASampleStruct));
+ playFlaSample(sample.sampleNum, sample.freq, sample.repeat, sample.x, sample.y);
+ break;
+ }
+ case kStopSample: {
+ stopSample(sample.sampleNum);
+ break;
+ }
+ case kDeltaFrame: {
+ drawDeltaFrame(ptr, FLASCREEN_WIDTH);
+ if (_fadeOut == 1)
+ fadeOutFrames++;
+ break;
+ }
+ case kKeyFrame: {
+ drawKeyFrame(ptr, FLASCREEN_WIDTH, FLASCREEN_HEIGHT);
+ break;
+ }
+ default: {
+ return;
+ }
+ }
+
+ aux++;
+ ptr += opcodeBlockSize;
+
+ } while (aux < (int32)frameData.videoSize);
+ //free(workVideoBufferCopy);
+}
+
+/** Play FLA PCX Screens
+ @param flaName FLA movie name */
+void fla_pcxList(int8 *flaName) {
+ // TODO if is using FLA PCX than show the images instead
+}
+
+/** Play FLA movies
+ @param flaName FLA movie name */
+void playFlaMovie(int8 *flaName) {
+ int32 i;
+ int32 quit = 0;
+ int32 currentFrame;
+ int16 tmpValue;
+ int8 fileNamePath[256];
+
+ stopSamples();
+
+ // Play FLA PCX instead of movies
+ if (cfgfile.Movie == CONF_MOVIE_FLAPCX) {
+ fla_pcxList(flaName);
+ return;
+ }
+
+ stopMusic();
+
+ // take extension if movie name has it
+ for (i = 0; i < (int32)strlen(flaName); i++) {
+ if(flaName[i] == '.') {
+ flaName[i] = 0;
+ }
+ }
+
+ sprintf(fileNamePath, FLA_DIR);
+ strcat(fileNamePath, flaName);
+ strcat(fileNamePath, FLA_EXT);
+
+ _fadeOut = -1;
+ fadeOutFrames = 0;
+
+ if (!fropen2(&frFla, fileNamePath, "rb"))
+ return;
+
+ workVideoBufferCopy = workVideoBuffer;
+
+ frread(&frFla, &flaHeaderData.version, 6);
+ frread(&frFla, &flaHeaderData.numOfFrames, 4);
+ frread(&frFla, &flaHeaderData.speed, 1);
+ frread(&frFla, &flaHeaderData.var1, 1);
+ frread(&frFla, &flaHeaderData.xsize, 2);
+ frread(&frFla, &flaHeaderData.ysize, 2);
+
+ frread(&frFla, &samplesInFla, 2);
+ frread(&frFla, &tmpValue, 2);
+
+ for (i = 0; i < samplesInFla; i++) {
+ int16 var0;
+ int16 var1;
+ frread(&frFla, &var0, 2);
+ frread(&frFla, &var1, 2);
+ flaSampleTable[i] = var0;
+ }
+
+ if (!strcmp(flaHeaderData.version, "V1.3")) {
+ currentFrame = 0;
+
+ if (!quit) {
+ do {
+ if (currentFrame == flaHeaderData.numOfFrames)
+ quit = 1;
+ else {
+ processFrame();
+ scaleFla2x();
+ copyScreen(workVideoBuffer, frontVideoBuffer);
+
+ // Only blit to screen if isn't a fade
+ if (_fadeOut == -1) {
+ convertPalToRGBA(palette, paletteRGBACustom);
+ if (!currentFrame) // fade in the first frame
+ fadeIn(paletteRGBACustom);
+ else
+ setPalette(paletteRGBACustom);
+ }
+
+ // TRICKY: fade in tricky
+ if (fadeOutFrames >= 2) {
+ flip();
+ convertPalToRGBA(palette, paletteRGBACustom);
+ fadeToPal(paletteRGBACustom);
+ _fadeOut = -1;
+ fadeOutFrames = 0;
+ }
+
+ currentFrame++;
+
+ fpsCycles(flaHeaderData.speed + 1);
+
+ readKeys();
+
+ if (skipIntro)
+ break;
+ }
+ } while (!quit);
+ }
+ }
+
+ if (cfgfile.CrossFade) {
+ crossFade(frontVideoBuffer, paletteRGBACustom);
+ } else {
+ fadeToBlack(paletteRGBACustom);
+ }
+
+ stopSamples();
+}
+
+/*
+void fla_pcxList(char *flaName)
+{
+ // check if FLAPCX file exist
+// if(!checkIfFileExist("FLA_PCX.HQR") || !checkIfFileExist("FLA_GIF.HQR")){
+// printf("FLA_PCX file doesn't exist!");
+ //return;
+ //}
+
+ // TODO: done this with the HQR 23th entry (movies informations)
+ if(!strcmp(flaName,"INTROD"))
+ {
+ prepareFlaPCX(1);
+ WaitTime(5000);
+ prepareFlaPCX(2);
+ WaitTime(5000);
+ prepareFlaPCX(3);
+ WaitTime(5000);
+ prepareFlaPCX(4);
+ WaitTime(5000);
+ prepareFlaPCX(5);
+ WaitTime(5000);
+
+ }
+ else if(!strcmp(flaName,"BAFFE") || !strcmp(flaName,"BAFFE2") || !strcmp(flaName,"BAFFE3") || !strcmp(flaName,"BAFFE4"))
+ {
+ prepareFlaPCX(6);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"bateau") || !strcmp(flaName,"bateau2"))
+ {
+ prepareFlaPCX(7);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"flute2"))
+ {
+ prepareFlaPCX(8);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"navette"))
+ {
+ prepareFlaPCX(15);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"templebu"))
+ {
+ prepareFlaPCX(12);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"glass2"))
+ {
+ prepareFlaPCX(8);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"surf"))
+ {
+ prepareFlaPCX(9);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"verser") || !strcmp(flaName,"verser2"))
+ {
+ prepareFlaPCX(10);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"capture"))
+ {
+ prepareFlaPCX(14);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"neige2"))
+ {
+ prepareFlaPCX(11);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"sendel"))
+ {
+ prepareFlaPCX(14);
+ WaitTime(5000);
+ }
+ else if(!strcmp(flaName,"sendel2"))
+ {
+ prepareFlaPCX(17);
+ WaitTime(5000);
+ }
+}
+
+void prepareFlaPCX(int index)
+{
+ int i;
+ SDL_Surface *image;
+
+ // TODO: Done this without SDL_Image Library
+ if(checkIfFileExist("FLA_PCX.HQR"))
+ image = IMG_LoadPCX_RW(SDL_RWFromMem(HQR_Get(HQR_FlaPCX,index), Size_HQR("FLA_PCX.HQR", index))); // rwop
+ else if(checkIfFileExist("FLA_GIF.HQR"))
+ image = IMG_LoadGIF_RW(SDL_RWFromMem(HQR_Get(HQR_FlaGIF,index), Size_HQR("fla_gif.hqr", index))); // rwop
+
+ if(!image) {
+ printf("Can't load FLA PCX: %s\n", IMG_GetError());
+ }
+
+ osystem_FlaPCXCrossFade(image);
+}*/
diff --git a/engines/twine/flamovies.h b/engines/twine/flamovies.h
new file mode 100644
index 0000000000..bd81defeb8
--- /dev/null
+++ b/engines/twine/flamovies.h
@@ -0,0 +1,83 @@
+/** @file movies.h
+ @brief
+ This file contains movies routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef FLAMOVIES_H
+#define FLAMOVIES_H
+
+#include "main.h"
+
+/** FLA movie directory */
+#define FLA_DIR "fla/"
+
+/** FLA movie header structure */
+typedef struct FLAHeaderStruct {
+ /** FLA version */
+ int8 version[6];
+ /** Number of frames */
+ int32 numOfFrames;
+ /** Frames per second */
+ int8 speed;
+ /** Unknown var1 */
+ int8 var1;
+ /** Frame width */
+ int16 xsize;
+ /** Frame height */
+ int16 ysize;
+} FLAHeaderStruct;
+
+/** FLA movie frame structure */
+typedef struct FLAFrameDataStruct {
+ /** Current frame size */
+ int8 videoSize;
+ /** Dummy variable */
+ int8 dummy;
+ /** Unknown frameVar0 */
+ int32 frameVar0;
+} FLAFrameDataStruct;
+
+/** FLA movie sample structure */
+typedef struct FLASampleStruct {
+ /** Number os samples */
+ int16 sampleNum;
+ /** Sample frequency */
+ int16 freq;
+ /** Numbers of time to repeat */
+ int16 repeat;
+ /** Dummy variable */
+ int8 dummy;
+ /** Unknown x */
+ uint8 x;
+ /** Unknown y */
+ uint8 y;
+} FLASampleStruct;
+
+/** FLA movie file buffer */
+unsigned char flaBuffer[FLASCREEN_WIDTH*FLASCREEN_HEIGHT];
+
+/** Play FLA movies
+ @param flaName FLA movie name */
+void playFlaMovie(int8 *flaName);
+
+#endif
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
new file mode 100644
index 0000000000..6b6e1c373d
--- /dev/null
+++ b/engines/twine/gamestate.cpp
@@ -0,0 +1,531 @@
+/** @file gamestate.cpp
+ @brief
+ This file contains game state routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "gamestate.h"
+#include "scene.h"
+#include "redraw.h"
+#include "text.h"
+#include "menu.h"
+#include "renderer.h"
+#include "grid.h"
+#include "lbaengine.h"
+#include "interface.h"
+#include "animations.h"
+#include "keyboard.h"
+#include "resources.h"
+#include "extra.h"
+#include "sound.h"
+#include "screens.h"
+#include "music.h"
+#include "filereader.h"
+#include "menuoptions.h"
+#include "collision.h"
+
+#define SAVE_DIR "save/"
+
+int32 magicLevelStrengthOfHit[] = {
+ kNoBallStrenght,
+ kYellowBallStrenght,
+ kGreenBallStrenght,
+ kRedBallStrenght,
+ kFireBallStrength,
+ 0
+};
+
+/** Initialize engine 3D projections */
+void initEngineProjections() { // reinitAll1
+ setOrthoProjection(311, 240, 512);
+ setBaseTranslation(0, 0, 0);
+ setBaseRotation(0, 0, 0);
+ setLightVector(alphaLight, betaLight, 0);
+}
+
+/** Initialize variables */
+void initSceneVars() {
+ int32 i;
+
+ resetExtras();
+
+ for (i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
+ overlayList[i].info0 = -1;
+ }
+
+ for (i = 0; i < NUM_SCENES_FLAGS; i++) {
+ sceneFlags[i] = 0;
+ }
+
+ for (i = 0; i < NUM_GAME_FLAGS; i++) {
+ gameFlags[i] = 0;
+ }
+
+ for (i = 0; i < NUM_INVENTORY_ITEMS; i++) {
+ inventoryFlags[i] = 0;
+ }
+
+ sampleAmbiance[0] = -1;
+ sampleAmbiance[1] = -1;
+ sampleAmbiance[2] = -1;
+ sampleAmbiance[3] = -1;
+
+ sampleRepeat[0] = 0;
+ sampleRepeat[1] = 0;
+ sampleRepeat[2] = 0;
+ sampleRepeat[3] = 0;
+
+ sampleRound[0] = 0;
+ sampleRound[1] = 0;
+ sampleRound[2] = 0;
+ sampleRound[3] = 0;
+
+ for (i = 0; i < 150; i++) {
+ holomapFlags[i] = 0;
+ }
+
+ sceneNumActors = 0;
+ sceneNumZones = 0;
+ sceneNumTracks = 0;
+
+ currentPositionInBodyPtrTab = 0;
+}
+
+void initHeroVars() { // reinitAll3
+ resetActor(0); // reset Hero
+
+ magicBallIdx = -1;
+
+ inventoryNumLeafsBox = 2;
+ inventoryNumLeafs = 2;
+ inventoryNumKashes = 0;
+ inventoryNumKeys = 0;
+ inventoryMagicPoints = 0;
+
+ usingSabre = 0;
+
+ sceneHero->body = 0;
+ sceneHero->life = 50;
+ sceneHero->talkColor = 4;
+}
+
+/** Initialize all engine variables */
+void initEngineVars(int32 save) { // reinitAll
+ resetClip();
+
+ alphaLight = 896;
+ betaLight = 950;
+ initEngineProjections();
+ initSceneVars();
+ initHeroVars();
+
+ newHeroX = 0x2000;
+ newHeroY = 0x1800;
+ newHeroZ = 0x2000;
+
+ currentSceneIdx = -1;
+ needChangeScene = 0;
+ quitGame = -1;
+ mecaPinguinIdx = -1;
+ canShowCredits = 0;
+
+ inventoryNumLeafs = 0;
+ inventoryNumLeafsBox = 2;
+ inventoryMagicPoints = 0;
+ inventoryNumKashes = 0;
+ inventoryNumKeys = 0;
+ inventoryNumGas = 0;
+
+ cropBottomScreen = 0;
+
+ magicLevelIdx = 0;
+ usingSabre = 0;
+
+ gameChapter = 0;
+
+ currentTextBank = 0;
+ currentlyFollowedActor = 0;
+ heroBehaviour = 0;
+ previousHeroAngle = 0;
+ previousHeroBehaviour = 0;
+
+ if (save == -1) {
+ loadGame();
+ if (newHeroX == -1) {
+ heroPositionType = kNoPosition;
+ }
+ }
+}
+
+void loadGame() {
+ FileReader fr;
+ uint8 data;
+ int8* namePtr;
+
+ if (!fropen2(&fr, SAVE_DIR "S9999.LBA", "rb")) {
+ printf("Can't load S9999.LBA saved game!\n");
+ return;
+ }
+
+ namePtr = savePlayerName;
+
+ frread(&fr, &data, 1); // save game id
+
+ do {
+ frread(&fr, &data, 1); // get save player name characters
+ *(namePtr++) = data;
+ } while (data);
+
+ frread(&fr, &data, 1); // number of game flags, always 0xFF
+ frread(&fr, gameFlags, data);
+ frread(&fr, &needChangeScene, 1); // scene index
+ frread(&fr, &gameChapter, 1);
+
+ frread(&fr, &heroBehaviour, 1);
+ previousHeroBehaviour = heroBehaviour;
+ frread(&fr, &sceneHero->life, 1);
+ frread(&fr, &inventoryNumKashes, 2);
+ frread(&fr, &magicLevelIdx, 1);
+ frread(&fr, &inventoryMagicPoints, 1);
+ frread(&fr, &inventoryNumLeafsBox, 1);
+ frread(&fr, &newHeroX, 2);
+ frread(&fr, &newHeroY, 2);
+ frread(&fr, &newHeroZ, 2);
+ frread(&fr, &sceneHero->angle, 2);
+ previousHeroAngle = sceneHero->angle;
+ frread(&fr, &sceneHero->body, 1);
+
+ frread(&fr, &data, 1); // number of holomap locations, always 0x96
+ frread(&fr, holomapFlags, data);
+
+ frread(&fr, &inventoryNumGas, 1);
+
+ frread(&fr, &data, 1); // number of used inventory items, always 0x1C
+ frread(&fr, inventoryFlags, data);
+
+ frread(&fr, &inventoryNumLeafs, 1);
+ frread(&fr, &usingSabre, 1);
+
+ frclose(&fr);
+
+ currentSceneIdx = -1;
+ heroPositionType = kReborn;
+}
+
+void saveGame() {
+ FileReader fr;
+ int8 data;
+
+ if (!fropen2(&fr, SAVE_DIR "S9999.LBA", "wb+")) {
+ printf("Can't save S9999.LBA saved game!\n");
+ return;
+ }
+
+ data = 0x03;
+ frwrite(&fr, &data, 1, 1);
+
+ data = 0x00;
+ frwrite(&fr, "TwinEngineSave", 15, 1);
+
+ data = 0xFF; // number of game flags
+ frwrite(&fr, &data, 1, 1);
+ frwrite(&fr, gameFlags, 255, 1);
+
+ frwrite(&fr, ¤tSceneIdx, 1, 1);
+ frwrite(&fr, &gameChapter, 1, 1);
+ frwrite(&fr, &heroBehaviour, 1, 1);
+ frwrite(&fr, &sceneHero->life, 1, 1);
+ frwrite(&fr, &inventoryNumKashes, 2, 1);
+ frwrite(&fr, &magicLevelIdx, 1, 1);
+ frwrite(&fr, &inventoryMagicPoints, 1, 1);
+ frwrite(&fr, &inventoryNumLeafsBox, 1, 1);
+ frwrite(&fr, &newHeroX, 2, 1);
+ frwrite(&fr, &newHeroY, 2, 1);
+ frwrite(&fr, &newHeroZ, 2, 1);
+ frwrite(&fr, &sceneHero->angle, 2, 1);
+ frwrite(&fr, &sceneHero->body, 1, 1);
+
+ data = 0x96; // number of holomap locations
+ frwrite(&fr, &data, 1, 1);
+ frwrite(&fr, holomapFlags, 150, 1);
+
+ frwrite(&fr, &inventoryNumGas, 1, 1);
+
+ data = 0x1C; // number of inventory items
+ frwrite(&fr, &data, 1, 1);
+ frwrite(&fr, inventoryFlags, 28, 1);
+
+ frwrite(&fr, &inventoryNumLeafs, 1, 1);
+ frwrite(&fr, &usingSabre, 1, 1);
+
+ frclose(&fr);
+}
+
+void processFoundItem(int32 item) {
+ int32 itemCameraX, itemCameraY, itemCameraZ; // objectXYZ
+ int32 itemX, itemY, itemZ; // object2XYZ
+ int32 boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY;
+ int32 textState, quitItem, currentAnimState;
+ uint8 *currentAnim;
+ AnimTimerDataStruct tmpAnimTimer;
+
+ newCameraX = (sceneHero->X + 0x100) >> 9;
+ newCameraY = (sceneHero->Y + 0x100) >> 8;
+ newCameraZ = (sceneHero->Z + 0x100) >> 9;
+
+ // Hide hero in scene
+ sceneHero->staticFlags.bIsHidden = 1;
+ redrawEngineActions(1);
+ sceneHero->staticFlags.bIsHidden = 0;
+
+ copyScreen(frontVideoBuffer, workVideoBuffer);
+
+ itemCameraX = newCameraX << 9;
+ itemCameraY = newCameraY << 8;
+ itemCameraZ = newCameraZ << 9;
+
+ renderIsoModel(sceneHero->X - itemCameraX, sceneHero->Y - itemCameraY, sceneHero->Z - itemCameraZ, 0, 0x80, 0, bodyTable[sceneHero->entity]);
+ setClip(renderLeft, renderTop, renderRight, renderBottom);
+
+ itemX = (sceneHero->X + 0x100) >> 9;
+ itemY = sceneHero->Y >> 8;
+ if (sceneHero->brickShape & 0x7F) {
+ itemY++;
+ }
+ itemZ = (sceneHero->Z + 0x100) >> 9;
+
+ drawOverModelActor(itemX, itemY, itemZ);
+ flip();
+
+ projectPositionOnScreen(sceneHero->X - itemCameraX, sceneHero->Y - itemCameraY, sceneHero->Z - itemCameraZ);
+ projPosY -= 150;
+
+ boxTopLeftX = projPosX - 65;
+ boxTopLeftY = projPosY - 65;
+
+ boxBottomRightX = projPosX + 65;
+ boxBottomRightY = projPosY + 65;
+
+ playSample(41, 0x1000, 1, 0x80, 0x80, 0x80, -1);
+
+ // process vox play
+ {
+ int32 tmpLanguageCDId;
+ stopMusic();
+ tmpLanguageCDId = cfgfile.LanguageCDId;
+ //cfgfile.LanguageCDId = 0; // comented so we can init vox bank
+ initTextBank(2);
+ cfgfile.LanguageCDId = tmpLanguageCDId;
+ }
+
+ resetClip();
+ initText(item);
+ initDialogueBox();
+
+ textState = 1;
+ quitItem = 0;
+
+ if (cfgfile.LanguageCDId) {
+ initVoxToPlay(item);
+ }
+
+ currentAnim = animTable[getBodyAnimIndex(kFoundItem, 0)];
+
+ tmpAnimTimer = sceneHero->animTimerData;
+
+ animBuffer2 += stockAnimation(animBuffer2, bodyTable[sceneHero->entity], &sceneHero->animTimerData);
+ if (animBuffer1 + 4488 < animBuffer2) {
+ animBuffer2 = animBuffer1;
+ }
+
+ currentAnimState = 0;
+
+ prepareIsoModel(inventoryTable[item]);
+ numOfRedrawBox = 0;
+
+ while (!quitItem) {
+ resetClip();
+ currNumOfRedrawBox = 0;
+ blitBackgroundAreas();
+ drawTransparentBox(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY, 4);
+
+ setClip(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
+
+ itemAngle[item] += 8;
+
+ renderInventoryItem(projPosX, projPosY, inventoryTable[item], itemAngle[item], 10000);
+
+ drawBox(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
+ addRedrawArea(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
+ resetClip();
+ initEngineProjections();
+
+ if (setModelAnimation(currentAnimState, currentAnim, bodyTable[sceneHero->entity], &sceneHero->animTimerData)) {
+ currentAnimState++; // keyframe
+ if (currentAnimState >= getNumKeyframes(currentAnim)) {
+ currentAnimState = getStartKeyframe(currentAnim);
+ }
+ }
+
+ renderIsoModel(sceneHero->X - itemCameraX, sceneHero->Y - itemCameraY, sceneHero->Z - itemCameraZ, 0, 0x80, 0, bodyTable[sceneHero->entity]);
+ setClip(renderLeft, renderTop, renderRight, renderBottom);
+ drawOverModelActor(itemX, itemY, itemZ);
+ addRedrawArea(renderLeft, renderTop, renderRight, renderBottom);
+
+ if (textState) {
+ resetClip();
+ textState = printText10();
+ }
+
+ if (textState == 0 || textState == 2) {
+ sdldelay(15);
+ }
+
+ flipRedrawAreas();
+
+ readKeys();
+ if (skippedKey) {
+ if (!textState) {
+ quitItem = 1;
+ }
+
+ if (textState == 2) {
+ textState = 1;
+ }
+ }
+
+ lbaTime++;
+ }
+
+ while (playVoxSimple(currDialTextEntry)) {
+ readKeys();
+ if (skipIntro == 1) {
+ break;
+ }
+ delaySkip(1);
+ }
+
+ initEngineProjections();
+ initTextBank(currentTextBank + 3);
+
+ /*do {
+ readKeys();
+ delaySkip(1);
+ } while (!skipIntro);*/
+
+ if (cfgfile.LanguageCDId && isSamplePlaying(currDialTextEntry)) {
+ stopVox(currDialTextEntry);
+ }
+
+ sceneHero->animTimerData = tmpAnimTimer;
+}
+
+void processGameChoices(int32 choiceIdx) {
+ int32 i;
+ copyScreen(frontVideoBuffer, workVideoBuffer);
+
+ gameChoicesSettings[0] = 0; // Current loaded button (button number)
+ gameChoicesSettings[1] = numChoices; // Num of buttons
+ gameChoicesSettings[2] = 0; // Buttons box height
+ gameChoicesSettings[3] = currentTextBank + 3;
+
+ if (numChoices > 0) {
+ for(i = 0; i < numChoices; i++) {
+ gameChoicesSettings[i * 2 + 4] = 0;
+ gameChoicesSettings[i * 2 + 5] = gameChoices[i];
+ }
+ }
+
+ drawAskQuestion(choiceIdx);
+
+ processMenu(gameChoicesSettings);
+ choiceAnswer = gameChoices[gameChoicesSettings[0]];
+
+ // get right VOX entry index
+ if (cfgfile.LanguageCDId) {
+ initVoxToPlay(choiceAnswer);
+ while(playVoxSimple(currDialTextEntry));
+ stopVox(currDialTextEntry);
+
+ hasHiddenVox = 0;
+ voxHiddenIndex = 0;
+ }
+}
+
+void processGameoverAnimation() { // makeGameOver
+ int32 tmpLbaTime, startLbaTime;
+ uint8 *gameOverPtr;
+
+ tmpLbaTime = lbaTime;
+
+ // workaround to fix hero redraw after drowning
+ sceneHero->staticFlags.bIsHidden = 1;
+ redrawEngineActions(1);
+ sceneHero->staticFlags.bIsHidden = 0;
+
+ // TODO: drawInGameTransBox
+ setPalette(paletteRGBA);
+ copyScreen(frontVideoBuffer, workVideoBuffer);
+ gameOverPtr = malloc(hqrEntrySize(HQR_RESS_FILE, RESSHQR_GAMEOVERMDL));
+ hqrGetEntry(gameOverPtr, HQR_RESS_FILE, RESSHQR_GAMEOVERMDL);
+
+ if (gameOverPtr) {
+ int32 avg, cdot;
+
+ prepareIsoModel(gameOverPtr);
+ stopSamples();
+ stopMidiMusic(); // stop fade music
+ setCameraPosition(320, 240, 128, 200, 200);
+ startLbaTime = lbaTime;
+ setClip(120, 120, 519, 359);
+
+ while(skipIntro != 1 && (lbaTime - startLbaTime) <= 0x1F4) {
+ readKeys();
+
+ avg = getAverageValue(40000, 3200, 500, lbaTime - startLbaTime);
+ cdot = crossDot(1, 1024, 100, (lbaTime - startLbaTime) % 0x64);
+ blitBox(120, 120, 519, 359, (int8*) workVideoBuffer, 120, 120, (int8*) frontVideoBuffer);
+ setCameraAngle(0, 0, 0, 0, -cdot, 0, avg);
+ renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
+ copyBlockPhys(120, 120, 519, 359);
+
+ lbaTime++;
+ sdldelay(15);
+ }
+
+ playSample(37, Rnd(2000) + 3096, 1, 0x80, 0x80, 0x80, -1);
+ blitBox(120, 120, 519, 359, (int8*) workVideoBuffer, 120, 120, (int8*) frontVideoBuffer);
+ setCameraAngle(0, 0, 0, 0, 0, 0, 3200);
+ renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
+ copyBlockPhys(120, 120, 519, 359);
+
+ delaySkip(2000);
+
+ resetClip();
+ free(gameOverPtr);
+ copyScreen(workVideoBuffer, frontVideoBuffer);
+ flip();
+ initEngineProjections();
+
+ lbaTime = tmpLbaTime;
+ }
+}
diff --git a/engines/twine/gamestate.h b/engines/twine/gamestate.h
new file mode 100644
index 0000000000..28bd0d2dae
--- /dev/null
+++ b/engines/twine/gamestate.h
@@ -0,0 +1,114 @@
+/** @file gamestate.h
+ @brief
+ This file contains game state routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef GAMESTATE_H
+#define GAMESTATE_H
+
+#include "sys.h"
+
+#define NUM_GAME_FLAGS 255
+#define NUM_INVENTORY_ITEMS 28
+
+#define GAMEFLAG_HAS_HOLOMAP 0
+#define GAMEFLAG_HAS_MAGICBALL 1
+#define GAMEFLAG_HAS_SABRE 2
+#define GAMEFLAG_TUNIC 4
+#define GAMEFLAG_BOOKOFBU 6
+#define GAMEFLAG_PROTOPACK 12
+#define GAMEFLAG_MECA_PINGUIN 14
+#define GAMEFLAG_HAS_CLOVER_LEAF 27
+#define GAMEFLAG_INVENTORY_DISABLED 70
+
+/** Magicball strength*/
+enum MagicballStrengthType {
+ kNoBallStrenght = 2,
+ kYellowBallStrenght = 3,
+ kGreenBallStrenght = 4,
+ kRedBallStrenght = 6,
+ kFireBallStrength = 8
+};
+
+/** LBA engine game flags to save quest states */
+uint8 gameFlags[256];
+
+/** LBA engine chapter */
+int16 gameChapter;
+
+/** Magic ball type index */
+int16 magicBallIdx;
+/** Magic ball num bounce */
+int16 magicBallNumBounce;
+/** Magic ball auxiliar bounce number */
+int16 magicBallAuxBounce; // magicBallParam
+/** Magic level index */
+int16 magicLevelIdx;
+
+/** Store the number of inventory keys */
+int16 inventoryNumKeys;
+/** Store the number of inventory kashes */
+int16 inventoryNumKashes;
+/** Store the number of inventory clover leafs boxes */
+int16 inventoryNumLeafsBox;
+/** Store the number of inventory clover leafs */
+int16 inventoryNumLeafs;
+/** Store the number of inventory magic points */
+int16 inventoryMagicPoints;
+/** Store the number of gas */
+int16 inventoryNumGas;
+
+/** Its using FunFrock Sabre */
+int16 usingSabre;
+
+/** Inventory used flags */
+uint8 inventoryFlags[NUM_INVENTORY_ITEMS];
+
+/** Inventory used flags */
+uint8 holomapFlags[150]; // GV14
+
+int8 savePlayerName[30]; // playerName
+
+int32 gameChoices[10]; // inGameMenuData
+int32 numChoices; // numOfOptionsInChoice
+int16 gameChoicesSettings[18]; // choiceTab - same structure as menu settings
+int32 choiceAnswer; // inGameMenuAnswer
+
+extern int32 magicLevelStrengthOfHit[];
+
+/** Initialize all engine variables */
+void initEngineVars(int32 save);
+
+/** Initialize engine 3D projections */
+void initEngineProjections();
+
+void processFoundItem(int32 item);
+
+void loadGame();
+void saveGame();
+
+void processGameChoices(int32 choiceIdx);
+
+void processGameoverAnimation();
+
+#endif
diff --git a/engines/twine/grid.cpp b/engines/twine/grid.cpp
new file mode 100644
index 0000000000..d10c8576e6
--- /dev/null
+++ b/engines/twine/grid.cpp
@@ -0,0 +1,984 @@
+/** @file grid.cpp
+ @brief
+ This file contains grid manipulation routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "grid.h"
+#include "resources.h"
+#include "lbaengine.h"
+#include "scene.h"
+#include "sdlengine.h"
+#include "interface.h"
+#include "screens.h"
+#include "actor.h"
+#include "renderer.h"
+#include "redraw.h"
+#include "collision.h"
+
+/** Grip X size */
+#define GRID_SIZE_X 64
+/** Grip Y size */
+#define GRID_SIZE_Y 25
+/** Grip Z size */
+#define GRID_SIZE_Z GRID_SIZE_X
+
+/** Total number of bricks allowed in the game */
+#define NUM_BRICKS 9000
+
+/** Total number of bricks allowed in the game */
+#define CELLING_GRIDS_START_INDEX 120
+
+/** Table with all loaded bricks */
+uint8* brickTable[NUM_BRICKS];
+/** Table with all loaded bricks masks */
+uint8* brickMaskTable[NUM_BRICKS];
+/** Table with all loaded bricks sizes */
+uint32 brickSizeTable[NUM_BRICKS];
+/** Table with all loaded bricks usage */
+uint8 brickUsageTable[NUM_BRICKS];
+
+/** Current grid pointer */
+uint8 *currentGrid;
+/** Current block library pointer */
+uint8 *currentBll;
+/** Number of block libraries */
+int32 numberOfBll;
+
+/** Block fragment entry */
+struct BlockEntry {
+ /** Block library index */
+ uint8 blockIdx;
+ /** Brick index inside the block library */
+ uint8 brickBlockIdx;
+};
+/** Grid block entry types */
+typedef struct BlockEntry blockMap[64][64][25];
+
+/** Brick entry data */
+typedef struct BrickEntry {
+ /** Brick X position in screen */
+ int16 x; //z
+ /** Brick Y position in screen */
+ int16 y;
+ /** Brick Z position in screen */
+ int16 z; // x
+ /** Brick pixel X position */
+ int16 posX;
+ /** Brick pixel Y position */
+ int16 posY;
+ /** Brick index */
+ int16 index;
+ /** Brick shape type */
+ uint8 shape;
+ /** Brick sound type */
+ uint8 sound;
+} BrickEntry;
+
+/** Brick data buffer */
+BrickEntry bricksDataBuffer[28][150];
+/** Brick info buffer */
+int16 brickInfoBuffer[28];
+
+/** Current brick pixel X position */
+int32 brickPixelPosX;
+/** Current brick pixel Y position */
+int32 brickPixelPosY;
+
+/** Copy grid mask to allow actors to display over the bricks
+ @param index current brick index
+ @param x grid X coordinate
+ @param y grid Y coordinate
+ @param buffer work video buffer */
+void copyGridMask(int32 index, int32 x, int32 y, uint8 *buffer) {
+ uint8 *ptr;
+ int32 top;
+ int32 bottom;
+ int32 left;
+ int32 right;
+ uint8 *outPtr;
+ uint8 *inPtr;
+ int32 offset;
+ int32 vc3;
+
+ int32 temp;
+ int32 j;
+
+ int32 absX;
+ int32 absY;
+
+ int32 vSize;
+
+ ptr = brickMaskTable[index];
+
+ left = x + *(ptr + 2);
+ top = y + *(ptr + 3);
+ right = *ptr + left - 1;
+ bottom = *(ptr + 1) + top - 1;
+
+ if (left > textWindowRight || right < textWindowLeft || bottom < textWindowTop || top > textWindowBottom)
+ return;
+
+ ptr += 4;
+
+ absX = left;
+ absY = top;
+
+ vSize = (bottom - top) + 1;
+
+ if (vSize <= 0)
+ return;
+
+ offset = -((right - left) - SCREEN_WIDTH) - 1;
+
+ right++;
+ bottom++;
+
+ // if line on top aren't in the blitting area...
+ if (absY < textWindowTop) {
+ int numOfLineToRemove;
+
+ numOfLineToRemove = textWindowTop - absY;
+
+ vSize -= numOfLineToRemove;
+ if (vSize <= 0)
+ return;
+
+ absY += numOfLineToRemove;
+
+ do {
+ int lineDataSize;
+
+ lineDataSize = *(ptr++);
+ ptr += lineDataSize;
+ } while (--numOfLineToRemove);
+ }
+
+ // reduce the vSize to remove lines on bottom
+ if (absY + vSize - 1 > textWindowBottom) {
+ vSize = textWindowBottom - absY + 1;
+ if (vSize <= 0)
+ return;
+ }
+
+ outPtr = frontVideoBuffer + screenLookupTable[absY] + left;
+ inPtr = buffer + screenLookupTable[absY] + left;
+
+ do {
+ vc3 = *(ptr++);
+
+ do {
+ temp = *(ptr++); // skip size
+ outPtr += temp;
+ inPtr += temp;
+
+ absX += temp;
+
+ vc3--;
+ if (!vc3)
+ break;
+
+ temp = *(ptr++); // copy size
+
+ for (j = 0; j < temp; j++) {
+ if (absX >= textWindowLeft && absX <= textWindowRight)
+ *outPtr = *inPtr;
+
+ absX++;
+ outPtr++;
+ inPtr++;
+ }
+ } while (--vc3);
+
+ absX = left;
+
+ outPtr += offset;
+ inPtr += offset;
+ } while (--vSize);
+}
+
+/** Draw 3D actor over bricks
+ @param X actor X coordinate
+ @param Y actor Y coordinate
+ @param Z actor Z coordinate */
+void drawOverModelActor(int32 X, int32 Y, int32 Z) {
+ int32 CopyBlockPhysLeft;
+ int32 CopyBlockPhysRight;
+ int32 i;
+ int32 j;
+ BrickEntry *currBrickEntry;
+
+ CopyBlockPhysLeft = ((textWindowLeft + 24) / 24) - 1;
+ CopyBlockPhysRight = ((textWindowRight + 24) / 24);
+
+ for (j = CopyBlockPhysLeft; j <= CopyBlockPhysRight; j++) {
+ for (i = 0; i < brickInfoBuffer[j]; i++) {
+ currBrickEntry = &bricksDataBuffer[j][i];
+
+ if (currBrickEntry->posY + 38 > textWindowTop && currBrickEntry->posY <= textWindowBottom && currBrickEntry->y >= Y) {
+ if (currBrickEntry->x + currBrickEntry->z > Z + X) {
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, workVideoBuffer);
+ }
+ }
+ }
+ }
+}
+
+/** Draw sprite actor over bricks
+ @param X actor X coordinate
+ @param Y actor Y coordinate
+ @param Z actor Z coordinate */
+void drawOverSpriteActor(int32 X, int32 Y, int32 Z) {
+ int32 CopyBlockPhysLeft;
+ int32 CopyBlockPhysRight;
+ int32 i;
+ int32 j;
+ BrickEntry *currBrickEntry;
+
+ CopyBlockPhysLeft = ((textWindowLeft + 24) / 24) - 1;
+ CopyBlockPhysRight = (textWindowRight + 24) / 24;
+
+ for (j = CopyBlockPhysLeft; j <= CopyBlockPhysRight; j++) {
+ for (i = 0; i < brickInfoBuffer[j]; i++) {
+ currBrickEntry = &bricksDataBuffer[j][i];
+
+ if (currBrickEntry->posY + 38 > textWindowTop && currBrickEntry->posY <= textWindowBottom && currBrickEntry->y >= Y) {
+ if ((currBrickEntry->x == X) && (currBrickEntry->z == Z)) {
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, workVideoBuffer);
+ }
+
+ if ((currBrickEntry->x > X) || (currBrickEntry->z > Z)) {
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, workVideoBuffer);
+ }
+ }
+ }
+ }
+}
+
+/** Process brick masks to allow actors to display over the bricks
+ @param buffer brick pointer buffer
+ @param ptr brick mask pointer buffer */
+int processGridMask(uint8 *buffer, uint8 *ptr) {
+ uint32 *ptrSave = (uint32 *)ptr;
+ uint8 *ptr2;
+ uint8 *esi;
+ uint8 *edi;
+ uint8 iteration, numOfBlock, ah, bl, al, bh;
+ int32 ebx;
+
+ ebx = *((uint32 *)buffer); // brick flag
+ buffer += 4;
+ *((uint32 *)ptr) = ebx;
+ ptr += 4;
+
+ bh = (ebx & 0x0000FF00) >> 8;
+
+ esi = (uint8 *) buffer;
+ edi = (uint8 *) ptr;
+
+ iteration = 0;
+
+ do {
+ numOfBlock = 0;
+ ah = 0;
+ ptr2 = edi;
+
+ edi++;
+
+ bl = *(esi++);
+
+ if (*(esi) & 0xC0) { // the first time isn't skip. the skip size is 0 in that case
+ *edi++ = 0;
+ numOfBlock++;
+ }
+
+ do {
+ al = *esi++;
+ iteration = al;
+ iteration &= 0x3F;
+ iteration++;
+
+ if (al & 0x80) {
+ ah += iteration;
+ esi++;
+ } else if (al & 0x40) {
+ ah += iteration;
+ esi += iteration;
+ } else { // skip
+ if (ah) {
+ *edi++ = ah; // write down the number of pixel passed so far
+ numOfBlock++;
+ ah = 0;
+ }
+ *(edi++) = iteration; //write skip
+ numOfBlock++;
+ }
+ } while (--bl > 0);
+
+ if (ah) {
+ *edi++ = ah;
+ numOfBlock++;
+
+ ah = 0;
+ }
+
+ *ptr2 = numOfBlock;
+ } while (--bh > 0);
+
+ return ((int)((uint8 *) edi - (uint8 *) ptrSave));
+}
+
+/** Create grid masks to allow display actors over the bricks */
+void createGridMask() {
+ int32 b;
+
+ for (b = 0; b < NUM_BRICKS; b++) {
+ if (brickUsageTable[b]) {
+ if (brickMaskTable[b])
+ free(brickMaskTable[b]);
+ brickMaskTable[b] = (uint8*)malloc(brickSizeTable[b]);
+ processGridMask(brickTable[b], brickMaskTable[b]);
+ }
+ }
+}
+
+/** Get sprite width and height sizes
+ @param offset sprite pointer offset
+ @param width sprite width size
+ @param height sprite height size
+ @param spritePtr sprite buffer pointer */
+void getSpriteSize(int32 offset, int32 *width, int32 *height, uint8 *spritePtr) {
+ spritePtr += *((int32 *)(spritePtr + offset * 4));
+
+ *width = *spritePtr;
+ *height = *(spritePtr + 1);
+}
+
+/** Load grid bricks according with block librarie usage
+ @param gridSize size of the current grid
+ @return true if everything went ok*/
+int32 loadGridBricks(int32 gridSize) {
+ uint32 firstBrick = 60000;
+ uint32 lastBrick = 0;
+ uint8* ptrToBllBits;
+ uint32 i;
+ uint32 j;
+ uint32 currentBllEntryIdx = 0;
+
+ memset(brickTable, 0, sizeof(brickTable));
+ memset(brickSizeTable, 0, sizeof(brickSizeTable));
+ memset(brickUsageTable, 0, sizeof(brickUsageTable));
+
+ // get block librarie usage bits
+ ptrToBllBits = currentGrid + (gridSize - 32);
+
+ // for all bits under the 32bytes (256bits)
+ for (i = 1; i < 256; i++) {
+ uint8 currentBitByte = *(ptrToBllBits + (i / 8));
+ uint8 currentBitMask = 1 << (7 - (i & 7));
+
+ if (currentBitByte & currentBitMask) {
+ uint32 currentBllOffset = *((uint32 *)(currentBll + currentBllEntryIdx));
+ uint8* currentBllPtr = currentBll + currentBllOffset;
+
+ uint32 bllSizeX = currentBllPtr[0];
+ uint32 bllSizeY = currentBllPtr[1];
+ uint32 bllSizeZ = currentBllPtr[2];
+
+ uint32 bllSize = bllSizeX * bllSizeY * bllSizeZ;
+
+ uint8* bllDataPtr = currentBllPtr + 5;
+
+ for (j = 0; j < bllSize; j++) {
+ uint32 brickIdx = *((int16*)(bllDataPtr));
+
+ if (brickIdx) {
+ brickIdx--;
+
+ if (brickIdx <= firstBrick)
+ firstBrick = brickIdx;
+
+ if (brickIdx > lastBrick)
+ lastBrick = brickIdx;
+
+ brickUsageTable[brickIdx] = 1;
+ }
+ bllDataPtr += 4;
+ }
+ }
+ currentBllEntryIdx += 4;
+ }
+
+ for (i = firstBrick; i <= lastBrick; i++) {
+ if (brickUsageTable[i]) {
+ brickSizeTable[i] = hqrGetallocEntry(&brickTable[i], HQR_LBA_BRK_FILE, i);
+ }
+ }
+
+ return 1;
+}
+
+/** Create grid Y column in block buffer
+ @param gridEntry current grid index
+ @param dest destination block buffer */
+void createGridColumn(uint8 *gridEntry, uint8 *dest) {
+ int32 blockCount;
+ int32 brickCount;
+ int32 flag;
+ int32 gridIdx;
+ int32 i;
+ uint16 *gridBuffer;
+ uint16 *blockByffer;
+
+ brickCount = *(gridEntry++);
+
+ do {
+ flag = *(gridEntry++);
+
+ blockCount = (flag & 0x3F) + 1;
+
+ gridBuffer = (uint16 *) gridEntry;
+ blockByffer = (uint16 *) dest;
+
+ if (!(flag & 0xC0)) {
+ for (i = 0; i < blockCount; i++)
+ *(blockByffer++) = 0;
+ } else if (flag & 0x40) {
+ for (i = 0; i < blockCount; i++)
+ *(blockByffer++) = *(gridBuffer++);
+ } else {
+ gridIdx = *(gridBuffer++);
+ for (i = 0; i < blockCount; i++)
+ *(blockByffer++) = gridIdx;
+ }
+
+ gridEntry = (uint8 *) gridBuffer;
+ dest = (uint8 *) blockByffer;
+
+ } while (--brickCount);
+}
+
+/** Create grid Y column in block buffer
+ @param gridEntry current grid index
+ @param dest destination block buffer */
+void createCellingGridColumn(uint8 *gridEntry, uint8 *dest) {
+ int32 blockCount;
+ int32 brickCount;
+ int32 flag;
+ int32 gridIdx;
+ int32 i;
+ uint16 *gridBuffer;
+ uint16 *blockByffer;
+
+ brickCount = *(gridEntry++);
+
+ do {
+ flag = *(gridEntry++);
+
+ blockCount = (flag & 0x3F) + 1;
+
+ gridBuffer = (uint16*) gridEntry;
+ blockByffer = (uint16 *) dest;
+
+ if (!(flag & 0xC0)) {
+ for (i = 0; i < blockCount; i++)
+ blockByffer++;
+ } else if (flag & 0x40) {
+ for (i = 0; i < blockCount; i++)
+ *(blockByffer++) = *(gridBuffer++);
+ } else {
+ gridIdx = *(gridBuffer++);
+ for (i = 0; i < blockCount; i++)
+ *(blockByffer++) = gridIdx;
+ }
+
+ gridEntry = (uint8 *) gridBuffer;
+ dest = (uint8 *) blockByffer;
+
+ } while (--brickCount);
+}
+
+/** Create grid map from current grid to block library buffer */
+void createGridMap() {
+ int32 currOffset = 0;
+ int32 blockOffset;
+ int32 gridIdx;
+ int32 x, z;
+
+ for (z = 0; z < GRID_SIZE_Z; z++) {
+ blockOffset = currOffset;
+ gridIdx = z << 6;
+
+ for (x = 0; x < GRID_SIZE_X; x++) {
+ int32 gridOffset = *((uint16 *)(currentGrid + 2 * (x + gridIdx)));
+ createGridColumn(currentGrid + gridOffset, blockBuffer + blockOffset);
+ blockOffset += 50;
+ }
+ currOffset += 3200;
+ }
+}
+
+/** Create celling grid map from celling grid to block library buffer
+ @param gridPtr celling grid buffer pointer */
+void createCellingGridMap(uint8* gridPtr) {
+ int32 currGridOffset = 0;
+ int32 currOffset = 0;
+ int32 blockOffset;
+ int32 z, x;
+ uint8* tempGridPtr;
+
+ for (z = 0; z < GRID_SIZE_Z; z++) {
+ blockOffset = currOffset;
+ tempGridPtr = gridPtr + currGridOffset;
+
+ for (x = 0; x < GRID_SIZE_X; x++) {
+ int gridOffset = *((uint16 *)tempGridPtr);
+ tempGridPtr += 2;
+ createCellingGridColumn(gridPtr + gridOffset, blockBuffer + blockOffset);
+ blockOffset += 50;
+ }
+ currGridOffset += 128;
+ currOffset += 3200;
+ }
+}
+
+/** Initialize grid (background scenearios)
+ @param index grid index number */
+int32 initGrid(int32 index) {
+
+ // load grids from file
+ int32 gridSize = hqrGetallocEntry(¤tGrid, HQR_LBA_GRI_FILE, index);
+
+ // load layouts from file
+ hqrGetallocEntry(¤tBll, HQR_LBA_BLL_FILE, index);
+
+ loadGridBricks(gridSize);
+
+ createGridMask();
+
+ numberOfBll = (*((uint32 *)currentBll) >> 2);
+
+ createGridMap();
+
+ return 1;
+}
+
+/** Initialize celling grid (background scenearios)
+ @param index grid index number */
+int32 initCellingGrid(int32 index) {
+ uint8* gridPtr;
+
+ // load grids from file
+ hqrGetallocEntry(&gridPtr, HQR_LBA_GRI_FILE, index + CELLING_GRIDS_START_INDEX);
+
+ createCellingGridMap(gridPtr);
+
+ if (gridPtr)
+ free(gridPtr);
+
+ reqBgRedraw = 1;
+
+ return 0;
+}
+
+/** Draw brick sprite in the screen
+ @param index brick index to draw
+ @param posX brick X position to draw
+ @param posY brick Y position to draw */
+void drawBrick(int32 index, int32 posX, int32 posY) {
+ drawBrickSprite(index, posX, posY, brickTable[index], 0);
+}
+
+/** Draw sprite in the screen
+ @param index sprite index to draw
+ @param posX sprite X position to draw
+ @param posY sprite Y position to draw
+ @param ptr sprite buffer pointer to draw */
+void drawSprite(int32 index, int32 posX, int32 posY, uint8 *ptr) {
+ drawBrickSprite(index, posX, posY, ptr, 1);
+}
+
+// WARNING: Rewrite this function to have better performance
+/** Draw sprite or bricks in the screen according with the type
+ @param index sprite index to draw
+ @param posX sprite X position to draw
+ @param posY sprite Y position to draw
+ @param ptr sprite buffer pointer to draw
+ @param isSprite allows to identify if the sprite to display is brick or a single sprite */
+void drawBrickSprite(int32 index, int32 posX, int32 posY, uint8 *ptr, int32 isSprite) {
+ //unsigned char *ptr;
+ int32 top;
+ int32 bottom;
+ int32 left;
+ int32 right;
+ uint8 *outPtr;
+ int32 offset;
+ int32 c1;
+ int32 c2;
+ int32 vc3;
+
+ int32 temp;
+ int32 iteration;
+ int32 i;
+
+ int32 x;
+ int32 y;
+
+ if (isSprite == 1)
+ ptr = ptr + *((uint32 *)(ptr + index * 4));
+
+ left = posX + *(ptr + 2);
+ top = posY + *(ptr + 3);
+ right = *ptr + left - 1;
+ bottom = *(ptr + 1) + top - 1;
+
+ ptr += 4;
+
+ x = left;
+ y = top;
+
+ //if (left >= textWindowLeft-2 && top >= textWindowTop-2 && right <= textWindowRight-2 && bottom <= textWindowBottom-2) // crop
+ {
+ right++;
+ bottom++;
+
+ outPtr = frontVideoBuffer + screenLookupTable[top] + left;
+
+ offset = -((right - left) - SCREEN_WIDTH);
+
+ for (c1 = 0; c1 < bottom - top; c1++) {
+ vc3 = *(ptr++);
+ for (c2 = 0; c2 < vc3; c2++) {
+ temp = *(ptr++);
+ iteration = temp & 0x3F;
+ if (temp & 0xC0) {
+ iteration++;
+ if (!(temp & 0x40)) {
+ temp = *(ptr++);
+ for (i = 0; i < iteration; i++) {
+ if (x >= textWindowLeft && x<textWindowRight && y >= textWindowTop && y < textWindowBottom)
+ frontVideoBuffer[y*SCREEN_WIDTH+x] = temp;
+
+ x++;
+ outPtr++;
+ }
+ } else {
+ for (i = 0; i < iteration; i++) {
+ if (x >= textWindowLeft && x<textWindowRight && y >= textWindowTop && y < textWindowBottom)
+ frontVideoBuffer[y*SCREEN_WIDTH+x] = *ptr;
+
+ x++;
+ ptr++;
+ outPtr++;
+ }
+ }
+ } else {
+ outPtr += iteration + 1;
+ x += iteration + 1;
+ }
+ }
+ outPtr += offset;
+ x = left;
+ y++;
+ }
+ }
+}
+
+/** Get block library
+ @param index block library index
+ @return pointer to the current block index */
+uint8* getBlockLibrary(int32 index) {
+ int32 offset = *((uint32 *)(currentBll + 4 * index));
+ return (uint8 *)(currentBll + offset);
+}
+
+/** Get brick position in the screen
+ @param x column x position in the current camera
+ @param y column y position in the current camera
+ @param z column z position in the current camera */
+void getBrickPos(int32 x, int32 y, int32 z) {
+ brickPixelPosX = (x - z) * 24 + 288; // x pos
+ brickPixelPosY = ((x + z) * 12) - (y * 15) + 215; // y pos
+}
+
+/** Draw a specific brick in the grid column according with the block index
+ @param blockIdx block library index
+ @param brickBlockIdx brick index inside the block
+ @param x column x position
+ @param y column y position
+ @param z column z position */
+void drawColumnGrid(int32 blockIdx, int32 brickBlockIdx, int32 x, int32 y, int32 z) {
+ uint8 *blockPtr;
+ uint16 brickIdx;
+ uint8 brickShape;
+ uint8 brickSound;
+ int32 brickBuffIdx;
+ BrickEntry *currBrickEntry;
+
+ blockPtr = getBlockLibrary(blockIdx) + 3 + brickBlockIdx * 4;
+
+ brickShape = *((uint8 *)(blockPtr));
+ brickSound = *((uint8 *)(blockPtr + 1));
+ brickIdx = *((uint16 *)(blockPtr + 2));
+
+ if (!brickIdx)
+ return;
+
+ getBrickPos(x - newCameraX, y - newCameraY, z - newCameraZ);
+
+ if (brickPixelPosX < -24)
+ return;
+ if (brickPixelPosX >= SCREEN_WIDTH)
+ return;
+ if (brickPixelPosY < -38)
+ return;
+ if (brickPixelPosY >= SCREEN_HEIGHT)
+ return;
+
+ // draw the background brick
+ drawBrick(brickIdx - 1, brickPixelPosX, brickPixelPosY);
+
+ brickBuffIdx = (brickPixelPosX + 24) / 24;
+
+ if (brickInfoBuffer[brickBuffIdx] >= 150) {
+ printf("\nGRID WARNING: brick buffer exceeded! \n");
+ return;
+ }
+
+ currBrickEntry = &bricksDataBuffer[brickBuffIdx][brickInfoBuffer[brickBuffIdx]];
+
+ currBrickEntry->x = x;
+ currBrickEntry->y = y;
+ currBrickEntry->z = z;
+ currBrickEntry->posX = brickPixelPosX;
+ currBrickEntry->posY = brickPixelPosY;
+ currBrickEntry->index = brickIdx - 1;
+ currBrickEntry->shape = brickShape;
+ currBrickEntry->sound = brickSound;
+
+ brickInfoBuffer[brickBuffIdx]++;
+}
+
+/** Redraw grid background */
+void redrawGrid() {
+ int32 i, x, y, z;
+ uint8 blockIdx;
+ blockMap* map = (blockMap*)blockBuffer;
+
+ cameraX = newCameraX << 9;
+ cameraY = newCameraY << 8;
+ cameraZ = newCameraZ << 9;
+
+ projectPositionOnScreen(-cameraX, -cameraY, -cameraZ);
+
+ projPosXScreen = projPosX;
+ projPosYScreen = projPosY;
+
+ for (i = 0; i < 28; i++) {
+ brickInfoBuffer[i] = 0;
+ }
+
+ if (changeRoomVar10 == 0)
+ return;
+
+ for (z = 0; z < GRID_SIZE_Z; z++) {
+ for (x = 0; x < GRID_SIZE_X; x++) {
+ for (y = 0; y < GRID_SIZE_Y; y++) {
+ blockIdx = (*map)[z][x][y].blockIdx;
+ if (blockIdx) {
+ drawColumnGrid(blockIdx - 1, (*map)[z][x][y].brickBlockIdx, x, y, z);
+ }
+ }
+ }
+ }
+}
+
+int32 getBrickShape(int32 x, int32 y, int32 z) { // WorldColBrick
+ uint8 blockIdx;
+ uint8 *blockBufferPtr;
+
+ blockBufferPtr = blockBuffer;
+
+ collisionX = (x + 0x100) >> 9;
+ collisionY = y >> 8;
+ collisionZ = (z + 0x100) >> 9;
+
+ if (collisionX < 0 || collisionX >= 64)
+ return 0;
+
+ if (collisionY <= -1)
+ return 1;
+
+ if (collisionY < 0 || collisionY > 24 || collisionZ < 0 || collisionZ >= 64)
+ return 0;
+
+ blockBufferPtr += collisionX * 50;
+ blockBufferPtr += collisionY * 2;
+ blockBufferPtr += (collisionZ << 7) * 25;
+
+ blockIdx = *blockBufferPtr;
+
+ if (blockIdx) {
+ uint8 *blockPtr;
+ uint8 tmpBrickIdx;
+
+ blockPtr = currentBll;
+
+ blockPtr += *(uint32 *)(blockPtr + blockIdx * 4 - 4);
+ blockPtr += 3;
+
+ tmpBrickIdx = *(blockBufferPtr + 1);
+ blockPtr = blockPtr + tmpBrickIdx * 4;
+
+ return *blockPtr;
+ } else {
+ return *(blockBufferPtr + 1);
+ }
+}
+
+int32 getBrickShapeFull(int32 x, int32 y, int32 z, int32 y2) {
+ int32 newY, currY, i;
+ uint8 blockIdx, brickShape;
+ uint8 *blockBufferPtr;
+
+ blockBufferPtr = blockBuffer;
+
+ collisionX = (x + 0x100) >> 9;
+ collisionY = y >> 8;
+ collisionZ = (z + 0x100) >> 9;
+
+ if (collisionX < 0 || collisionX >= 64)
+ return 0;
+
+ if (collisionY <= -1)
+ return 1;
+
+ if (collisionY < 0 || collisionY > 24 || collisionZ < 0 || collisionZ >= 64)
+ return 0;
+
+ blockBufferPtr += collisionX * 50;
+ blockBufferPtr += collisionY * 2;
+ blockBufferPtr += (collisionZ << 7) * 25;
+
+ blockIdx = *blockBufferPtr;
+
+ if (blockIdx) {
+ uint8 *blockPtr;
+ uint8 tmpBrickIdx;
+
+ blockPtr = currentBll;
+
+ blockPtr += *(uint32 *)(blockPtr + blockIdx * 4 - 4);
+ blockPtr += 3;
+
+ tmpBrickIdx = *(blockBufferPtr + 1);
+ blockPtr = blockPtr + tmpBrickIdx * 4;
+
+ brickShape = *blockPtr;
+
+ newY = (y2 + 255) >> 8;
+ currY = collisionY;
+
+ for (i = 0; i < newY; i++) {
+ if (currY > 24) {
+ return brickShape;
+ }
+
+ blockBufferPtr += 2;
+ currY++;
+
+ if (*(int16 *)(blockBufferPtr) != 0) {
+ return 1;
+ }
+ }
+
+ return brickShape;
+ } else {
+ brickShape = *(blockBufferPtr + 1);
+
+ newY = (y2 + 255) >> 8;
+ currY = collisionY;
+
+ for (i = 0; i < newY; i++) {
+ if (currY > 24) {
+ return brickShape;
+ }
+
+ blockBufferPtr += 2;
+ currY++;
+
+ if (*(int16 *)(blockBufferPtr) != 0) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int32 getBrickSoundType(int32 x, int32 y, int32 z) { // getPos2
+ uint8 blockIdx;
+ uint8 *blockBufferPtr;
+
+ blockBufferPtr = blockBuffer;
+
+ collisionX = (x + 0x100) >> 9;
+ collisionY = y >> 8;
+ collisionZ = (z + 0x100) >> 9;
+
+ if (collisionX < 0 || collisionX >= 64)
+ return 0;
+
+ if (collisionY <= -1)
+ return 1;
+
+ if (collisionY < 0 || collisionY > 24 || collisionZ < 0 || collisionZ >= 64)
+ return 0;
+
+ blockBufferPtr += collisionX * 50;
+ blockBufferPtr += collisionY * 2;
+ blockBufferPtr += (collisionZ << 7) * 25;
+
+ blockIdx = *blockBufferPtr;
+
+ if (blockIdx) {
+ uint8 *blockPtr;
+ uint8 tmpBrickIdx;
+
+ blockPtr = currentBll;
+
+ blockPtr += *(uint32 *)(blockPtr + blockIdx * 4 - 4);
+ blockPtr += 3;
+
+ tmpBrickIdx = *(blockBufferPtr + 1);
+ blockPtr = blockPtr + tmpBrickIdx * 4;
+ blockPtr++;
+
+ return *((int16 *)blockPtr);
+ }
+
+ return 0xF0;
+}
diff --git a/engines/twine/grid.h b/engines/twine/grid.h
new file mode 100644
index 0000000000..3c87790606
--- /dev/null
+++ b/engines/twine/grid.h
@@ -0,0 +1,139 @@
+/** @file grid.h
+ @brief
+ This file contains grid manipulation routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef GRID_H
+#define GRID_H
+
+#include "sys.h"
+
+enum ShapeType {
+ kNone = 0,
+ kSolid = 1,
+ kStairsTopLeft = 2,
+ kStairsTopRight = 3,
+ kStairsBottomLeft = 4,
+ kStairsBottomRight = 5,
+ kDoubleSideStairsTop1 = 6,
+ kDoubleSideStairsBottom1 = 7,
+ kDoubleSideStairsLeft1 = 8,
+ kDoubleSideStairsRight1 = 9,
+ kDoubleSideStairsTop2 = 10,
+ kDoubleSideStairsBottom2 = 11,
+ kDoubleSideStairsLeft2 = 12,
+ kDoubleSideStairsRight2 = 13,
+ kFlatBottom1 = 14,
+ kFlatBottom2 = 15
+};
+
+/** New grid camera X coordinates */
+int32 newCameraX;
+/** New grid camera Y coordinates */
+int32 newCameraY;
+/** New grid camera Z coordinates */
+int32 newCameraZ;
+
+/** Current grid camera X coordinates */
+int32 cameraX;
+/** Current grid camera Y coordinates */
+int32 cameraY;
+/** Current grid camera Z coordinates */
+int32 cameraZ;
+
+/** Celling grid brick block buffer */
+uint8 *blockBuffer;
+
+
+/** Flag to know if the engine is using celling grids */
+int16 useCellingGrid; // useAnotherGrm
+/** Current celling grid index */
+int16 cellingGridIdx; // currentGrid2
+
+
+/** Draw 3D actor over bricks
+ @param X actor X coordinate
+ @param Y actor Y coordinate
+ @param Z actor Z coordinate */
+void drawOverModelActor(int32 X, int32 Y, int32 Z);
+
+/** Draw sprite actor over bricks
+ @param X actor X coordinate
+ @param Y actor Y coordinate
+ @param Z actor Z coordinate */
+void drawOverSpriteActor(int32 X, int32 Y, int32 Z);
+
+/** Get sprite width and height sizes
+ @param offset sprite pointer offset
+ @param width sprite width size
+ @param height sprite height size
+ @param spritePtr sprite buffer pointer */
+void getSpriteSize(int32 offset, int32 *width, int32 *height, uint8 *spritePtr);
+
+/** Draw brick sprite in the screen
+ @param index brick index to draw
+ @param posX brick X position to draw
+ @param posY brick Y position to draw */
+void drawBrick(int32 index, int32 posX, int32 posY);
+
+/** Draw sprite in the screen
+ @param index sprite index to draw
+ @param posX sprite X position to draw
+ @param posY sprite Y position to draw
+ @param ptr sprite buffer pointer to draw */
+void drawSprite(int32 index, int32 posX, int32 posY, uint8 *spritePtr);
+
+/** Draw sprite or bricks in the screen according with the type
+ @param index sprite index to draw
+ @param posX sprite X position to draw
+ @param posY sprite Y position to draw
+ @param ptr sprite buffer pointer to draw
+ @param isSprite allows to identify if the sprite to display is brick or a single sprite */
+void drawBrickSprite(int32 index, int32 posX, int32 posY, uint8 *spritePtr, int32 isSprite);
+
+/** Get block library
+ @param index block library index
+ @return pointer to the current block index */
+uint8* getBlockLibrary(int32 index);
+
+/** Create grid map from current grid to block library buffer */
+void createGridMap();
+
+/** Initialize grid (background scenearios)
+ @param index grid index number */
+int32 initGrid(int32 index);
+
+/** Initialize celling grid (background scenearios)
+ @param index grid index number */
+int32 initCellingGrid(int32 index);
+
+/** Redraw grid background */
+void redrawGrid();
+
+int32 getBrickShape(int32 x, int32 y, int32 z);
+
+int32 getBrickShapeFull(int32 x, int32 y, int32 z, int32 y2);
+
+int32 getBrickSoundType(int32 x, int32 y, int32 z);
+
+#endif
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
new file mode 100644
index 0000000000..8d54b7a124
--- /dev/null
+++ b/engines/twine/holomap.cpp
@@ -0,0 +1,40 @@
+/** @file holomap.cpp
+ @brief
+ This file contains holomap routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "holomap.h"
+#include "gamestate.h"
+
+/** Set Holomap location position
+ @location Scene where position must be set */
+void setHolomapPosition(int32 location) {
+ holomapFlags[location] = 0x81;
+}
+
+/** Clear Holomap location position
+ @location Scene where position must be cleared */
+void clearHolomapPosition(int32 location) {
+ holomapFlags[location] &= 0x7E;
+ holomapFlags[location] |= 0x40;
+}
diff --git a/engines/twine/holomap.h b/engines/twine/holomap.h
new file mode 100644
index 0000000000..08ab5bd7dd
--- /dev/null
+++ b/engines/twine/holomap.h
@@ -0,0 +1,40 @@
+/** @file holomap.h
+ @brief
+ This file contains holomap routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef HOLOMAP_H
+#define HOLOMAP_H
+
+#include "sys.h"
+
+/** Set Holomap location position
+ @location Scene where position must be set */
+void setHolomapPosition(int32 location);
+
+/** Clear Holomap location position
+ @location Scene where position must be cleared */
+void clearHolomapPosition(int32 location);
+
+
+#endif
diff --git a/engines/twine/hqrdepack.cpp b/engines/twine/hqrdepack.cpp
new file mode 100644
index 0000000000..2941d9d647
--- /dev/null
+++ b/engines/twine/hqrdepack.cpp
@@ -0,0 +1,386 @@
+/** @file hqrdepack.cpp
+ @brief
+ This file contains High Quality Resource (HQR) decompress routines.
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "hqrdepack.h"
+#include "filereader.h"
+
+FileReader fr;
+
+/** Decompress entry based in Yaz0r and Zink decompression code
+ @param dst destination pointer where will be the decompressed entry
+ @param src compressed data pointer
+ @decompsize real file size after decompression
+ @mode compression mode used */
+void hqrDecompressEntry(uint8 * dst, uint8 * src, int32 decompsize, int32 mode) {
+ uint8 b;
+ int32 lenght, d, i;
+ uint16 offset;
+ uint8 *ptr;
+
+ do {
+ b = *(src++);
+ for (d = 0; d < 8; d++) {
+ if (!(b & (1 << d))) {
+ offset = *(uint16*)(src);
+ src += 2;
+ lenght = (offset & 0x0F) + (mode + 1);
+ ptr = dst - (offset >> 4) - 1;
+ for (i = 0; i < lenght; i++)
+ *(dst++) = *(ptr++);
+ } else {
+ lenght = 1;
+ *(dst++) = *(src++);
+ }
+ decompsize -= lenght;
+ if (decompsize <= 0)
+ return;
+ }
+ } while (decompsize);
+}
+
+/** Decompress entry based in the original expand lzss lba code
+ @param dst destination pointer where will be the decompressed entry
+ @param src compressed data pointer
+ @decompsize real file size after decompression
+ @mode compression mode used */
+void hqrDecompressLZEntry(uint8 * dst, uint8 * src, int32 decompsize, int32 mode) {
+ uint16 offset;
+ int32 lenght;
+ uint8 *ptr;
+
+ while (decompsize > 0) {
+ uint8 bits;
+ uint8 type = *(src++);
+ for (bits = 1; bits != 0; bits <<= 1) {
+ if (!(type&bits)) {
+ offset = *(uint16*)(src);
+ src += 2;
+ lenght = (offset & 0x0F) + (mode + 1);
+ ptr = dst - (offset >> 4) - 1;
+ if (offset == 0) {
+ memset(dst, *ptr, lenght);
+ } else {
+ if ((ptr + lenght) >= dst) {
+ int32 n;
+ uint8 *tmp = dst;
+ for (n = 0; n < lenght; n++)
+ *tmp++ = *ptr++;
+ } else {
+ memcpy(dst, ptr, lenght);
+ }
+ }
+ dst += lenght;
+ } else {
+ lenght = 1;
+ *(dst++) = *(src++);
+ }
+ decompsize -= lenght;
+ if (decompsize <= 0)
+ return;
+ }
+ }
+}
+
+/** Get a HQR entry pointer
+ @param ptr pointer to save the entry
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size*/
+int32 hqrGetEntry(uint8 * ptr, int8 *filename, int32 index) {
+ uint32 headerSize;
+ uint32 offsetToData;
+ uint32 realSize;
+ uint32 compSize;
+ uint16 mode;
+
+ if (!filename)
+ return 0;
+
+ if (!fropen2(&fr, (char*)filename, "rb"))
+ printf("HQR: %s can't be found !\n", filename);
+
+ frread(&fr, &headerSize, 4);
+
+ if ((uint32)index >= headerSize / 4) {
+ printf("\nHQR WARNING: Invalid entry index!!\n");
+ frclose(&fr);
+ return 0;
+ }
+
+ frseek(&fr, index*4);
+ frread(&fr, &offsetToData, 4);
+
+ frseek(&fr, offsetToData);
+ frread(&fr, &realSize, 4);
+ frread(&fr, &compSize, 4);
+ frread(&fr, &mode, 2);
+
+ if (!ptr)
+ ptr = (uint8*)malloc(realSize);
+
+ if (!ptr) {
+ printf("\nHQR WARNING: Unable to allocate memory!!\n");
+ frclose(&fr);
+ return 0;
+ }
+
+ // uncompressed
+ if (mode == 0) {
+ frread(&fr, ptr, realSize);
+ }
+ // compressed: modes (1 & 2)
+ else if (mode == 1 || mode == 2) {
+ uint8* compDataPtr = 0;
+ compDataPtr = (uint8*)malloc(compSize);
+ frread(&fr, compDataPtr, compSize);
+ hqrDecompressEntry(ptr, compDataPtr, realSize, mode);
+ free(compDataPtr);
+ }
+
+ frclose(&fr);
+
+ return realSize;
+}
+
+/** Get a HQR entry pointer
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size */
+int hqrEntrySize(int8 *filename, int32 index) {
+ uint32 headerSize;
+ uint32 offsetToData;
+ uint32 realSize;
+
+ if (!filename)
+ return 0;
+
+ if (!fropen2(&fr, (char*)filename, "rb")) {
+ printf("HQR: %s can't be found !\n", filename);
+ exit(1);
+ }
+
+ frread(&fr, &headerSize, 4);
+
+ if ((uint32)index >= headerSize / 4) {
+ printf("\nHQR WARNING: Invalid entry index!!\n");
+ frclose(&fr);
+ return 0;
+ }
+
+ frseek(&fr, index*4);
+ frread(&fr, &offsetToData, 4);
+
+ frseek(&fr, offsetToData);
+ frread(&fr, &realSize, 4);
+
+ frclose(&fr);
+
+ return realSize;
+}
+
+/** Get a HQR total number of entries
+ @param filename HQR file name
+ @return total number of entries */
+int hqrNumEntries(int8 *filename) {
+ uint32 headerSize;
+
+ if (!filename)
+ return 0;
+
+ if (!fropen2(&fr, (char*)filename, "rb")) {
+ printf("HQR: %s can't be found !\n", filename);
+ exit(1);
+ }
+
+ frread(&fr, &headerSize, 4);
+
+ return headerSize / 4;
+}
+
+/** Get a HQR entry pointer with memory allocation
+ @param ptr pointer to save the entry
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size */
+int32 hqrGetallocEntry(uint8 ** ptr, int8 *filename, int32 index) {
+ int32 size;
+ size = hqrEntrySize(filename, index);
+
+ *ptr = (uint8*)malloc(size * sizeof(uint8));
+ if (!*ptr) {
+ printf("HQR WARNING: unable to allocate entry memory!!\n");
+ return 0;
+ }
+ hqrGetEntry(*ptr, filename, index);
+
+ return size;
+}
+
+/** Get a HQR entry pointer
+ @param ptr pointer to save the entry
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size*/
+int32 hqrGetVoxEntry(uint8 * ptr, int8 *filename, int32 index, int32 hiddenIndex) {
+ uint32 headerSize;
+ uint32 offsetToData;
+ uint32 realSize;
+ uint32 compSize;
+ uint16 mode;
+
+ if (!filename)
+ return 0;
+
+ if (!fropen2(&fr, (char*)filename, "rb"))
+ printf("HQR: %s can't be found !\n", filename);
+
+ frread(&fr, &headerSize, 4);
+
+ if ((uint32)index >= headerSize / 4) {
+ printf("\nHQR WARNING: Invalid entry index!!\n");
+ frclose(&fr);
+ return 0;
+ }
+
+ frseek(&fr, index*4);
+ frread(&fr, &offsetToData, 4);
+
+ frseek(&fr, offsetToData);
+ frread(&fr, &realSize, 4);
+ frread(&fr, &compSize, 4);
+ frread(&fr, &mode, 2);
+
+ // exist hidden entries
+ if (hiddenIndex > 0) {
+ int32 i = 0;
+ for (i = 0; i < hiddenIndex; i++) {
+ frseek(&fr, offsetToData + compSize + 10); // hidden entry
+ offsetToData = offsetToData + compSize + 10; // current hidden offset
+
+ frread(&fr, &realSize, 4);
+ frread(&fr, &compSize, 4);
+ frread(&fr, &mode, 2);
+ }
+ }
+
+ if (!ptr)
+ ptr = (uint8*)malloc(realSize);
+
+ if (!ptr) {
+ printf("\nHQR WARNING: Unable to allocate memory!!\n");
+ frclose(&fr);
+ return 0;
+ }
+
+ // uncompressed
+ if (mode == 0) {
+ frread(&fr, ptr, realSize);
+ }
+ // compressed: modes (1 & 2)
+ else if (mode == 1 || mode == 2) {
+ uint8* compDataPtr = 0;
+ compDataPtr = (uint8*)malloc(compSize);
+ frread(&fr, compDataPtr, compSize);
+ hqrDecompressEntry(ptr, compDataPtr, realSize, mode);
+ free(compDataPtr);
+ }
+
+ frclose(&fr);
+
+ return realSize;
+}
+
+/** Get a HQR entry pointer
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size */
+int hqrVoxEntrySize(int8 *filename, int32 index, int32 hiddenIndex) {
+ uint32 headerSize;
+ uint32 offsetToData;
+ uint32 realSize;
+ uint32 compSize;
+
+ if (!filename)
+ return 0;
+
+ if (!fropen2(&fr, (char*)filename, "rb")) {
+ printf("HQR: %s can't be found !\n", filename);
+ exit(1);
+ }
+
+ frread(&fr, &headerSize, 4);
+
+ if ((uint32)index >= headerSize / 4) {
+ printf("\nHQR WARNING: Invalid entry index!!\n");
+ frclose(&fr);
+ return 0;
+ }
+
+ frseek(&fr, index*4);
+ frread(&fr, &offsetToData, 4);
+
+ frseek(&fr, offsetToData);
+ frread(&fr, &realSize, 4);
+ frread(&fr, &compSize, 4);
+
+ // exist hidden entries
+ if (hiddenIndex > 0) {
+ int32 i = 0;
+ for (i = 0; i < hiddenIndex; i++) {
+ frseek(&fr, offsetToData + compSize + 10); // hidden entry
+ offsetToData = offsetToData + compSize + 10; // current hidden offset
+
+ frread(&fr, &realSize, 4);
+ frread(&fr, &compSize, 4);
+ }
+ }
+
+ frclose(&fr);
+
+ return realSize;
+}
+
+/** Get a HQR entry pointer with memory allocation
+ @param ptr pointer to save the entry
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size */
+int32 hqrGetallocVoxEntry(uint8 ** ptr, int8 *filename, int32 index, int32 hiddenIndex) {
+ int32 size;
+ size = hqrVoxEntrySize(filename, index, hiddenIndex);
+
+ *ptr = (uint8*)malloc(size * sizeof(uint8));
+ if (!*ptr) {
+ printf("HQR WARNING: unable to allocate entry memory!!\n");
+ return 0;
+ }
+ hqrGetVoxEntry(*ptr, filename, index, hiddenIndex);
+
+ return size;
+}
diff --git a/engines/twine/hqrdepack.h b/engines/twine/hqrdepack.h
new file mode 100644
index 0000000000..a77abdf2d8
--- /dev/null
+++ b/engines/twine/hqrdepack.h
@@ -0,0 +1,59 @@
+/** @file hqrdepack.h
+ @brief
+ This file contains High Quality Resource (HQR) decompress routines.
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef HQRDEPACK_H
+#define HQRDEPACK_H
+
+#include "sys.h"
+
+/** Get a HQR entry pointer
+ @param ptr pointer to save the entry
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size */
+int32 hqrGetEntry(uint8 * ptr, int8 *filename, int32 index);
+
+/** Get a HQR entry pointer
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size */
+int32 hqrEntrySize(int8 *filename, int32 index);
+
+/** Get a HQR total number of entries
+ @param filename HQR file name
+ @return total number of entries */
+int32 hqrNumEntries(int8 *filename);
+
+/** Get a HQR entry pointer with memory allocation
+ @param ptr pointer to save the entry
+ @param filename HQR file name
+ @param index entry index to extract
+ @return entry real size */
+int32 hqrGetallocEntry(uint8 ** ptr, int8 *filename, int32 index);
+
+int32 hqrGetVoxEntry(uint8 * ptr, int8 *filename, int32 index, int32 hiddenIndex);
+int32 hqrGetallocVoxEntry(uint8 ** ptr, int8 *filename, int32 index, int32 hiddenIndex);
+
+#endif
diff --git a/engines/twine/interface.cpp b/engines/twine/interface.cpp
new file mode 100644
index 0000000000..e6b851bc76
--- /dev/null
+++ b/engines/twine/interface.cpp
@@ -0,0 +1,328 @@
+/** @file interface.cpp
+ @brief
+ This file contains in-game interface routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "interface.h"
+#include "sdlengine.h"
+#include "main.h"
+#include "lbaengine.h"
+const int32 INSIDE = 0; // 0000
+const int32 LEFT = 1; // 0001
+const int32 RIGHT = 2; // 0010
+const int32 TOP = 4; // 0100
+const int32 BOTTOM = 8; // 1000
+
+int32 checkClipping(int32 x, int32 y)
+{
+ int32 code = INSIDE;
+ if (x < textWindowLeft) code |= LEFT;
+ else if (x > textWindowRight) code |= RIGHT;
+ if (y < textWindowTop) code |= TOP;
+ else if (y > textWindowBottom) code |= BOTTOM;
+ return code;
+}
+
+/** Draw button line
+ @param startWidth width value where the line starts
+ @param startHeight height value where the line starts
+ @param endWidth width value where the line ends
+ @param endHeight height value where the line ends
+ @param lineColor line color in the current palette */
+void drawLine(int32 startWidth, int32 startHeight, int32 endWidth, int32 endHeight, int32 lineColor) {
+ int32 temp;
+ int32 flag2;
+ uint8 *out;
+ int16 color;
+ int16 var2;
+ int16 xchg;
+ int32 outcode0, outcode1;
+ int32 x, y, outcodeOut;
+ int32 currentLineColor = lineColor;
+
+ // draw line from left to right
+ if (startWidth > endWidth) {
+ temp = endWidth;
+ endWidth = startWidth;
+ startWidth = temp;
+
+ temp = endHeight;
+ endHeight = startHeight;
+ startHeight = temp;
+ }
+
+ // Perform proper clipping (CohenâSutherland algorithm)
+ outcode0 = checkClipping(startWidth, startHeight);
+ outcode1 = checkClipping(endWidth, endHeight);
+
+ while ((outcode0 | outcode1) != 0) {
+ if (((outcode0 & outcode1) != 0) && (outcode0 != INSIDE)) return; // Reject lines which are behind one clipping plane
+
+ // At least one endpoint is outside the clip rectangle; pick it.
+ outcodeOut = outcode0 ? outcode0 : outcode1;
+
+ if (outcodeOut & TOP) { // point is above the clip rectangle
+ x = startWidth + (int)((endWidth - startWidth) * (float)(textWindowTop - startHeight) / (float)(endHeight - startHeight));
+ y = textWindowTop;
+ } else if (outcodeOut & BOTTOM) { // point is below the clip rectangle
+ x = startWidth + (int)((endWidth - startWidth) * (float)(textWindowBottom - startHeight) / (float)(endHeight - startHeight));
+ y = textWindowBottom;
+ } else if (outcodeOut & RIGHT) { // point is to the right of clip rectangle
+ y = startHeight + (int)((endHeight - startHeight) * (float)(textWindowRight - startWidth) / (float)(endWidth - startWidth));
+ x = textWindowRight;
+ } else if (outcodeOut & LEFT) { // point is to the left of clip rectangle
+ y = startHeight + (int)((endHeight - startHeight) * (float)(textWindowLeft - startWidth) / (float)(endWidth - startWidth));
+ x = textWindowLeft;
+ }
+
+ // Clip the point
+ if (outcodeOut == outcode0) {
+ startWidth = x;
+ startHeight = y;
+ outcode0 = checkClipping(startWidth, startHeight);
+ } else {
+ endWidth = x;
+ endHeight = y;
+ outcode1 = checkClipping(endWidth, endHeight);
+ }
+ }
+
+ flag2 = 640;//SCREEN_WIDTH;
+ endWidth -= startWidth;
+ endHeight -= startHeight;
+ if (endHeight < 0) {
+ flag2 = -flag2;
+ endHeight = -endHeight;
+ }
+
+ out = frontVideoBuffer + screenLookupTable[startHeight] + startWidth;
+
+ color = currentLineColor;
+ if (endWidth < endHeight) { // significant slope
+ xchg = endWidth;
+ endWidth = endHeight;
+ endHeight = xchg;
+ var2 = endWidth;
+ var2 <<= 1;
+ startHeight = endWidth;
+ endHeight <<= 1;
+ endWidth++;
+ do {
+ *out = (uint8) color;
+ startHeight -= endHeight;
+ if (startHeight > 0) {
+ out += flag2;
+ } else {
+ startHeight += var2;
+ out += flag2 + 1;
+ }
+ } while (--endWidth);
+ } else { // reduced slope
+ var2 = endWidth;
+ var2 <<= 1;
+ startHeight = endWidth;
+ endHeight <<= 1;
+ endWidth++;
+ do {
+ *out = (uint8) color;
+ out++;
+ startHeight -= endHeight;
+ if (startHeight < 0) {
+ startHeight += var2;
+ out += flag2;
+ }
+ } while (--endWidth);
+ }
+}
+
+/** Blit button box from working buffer to front buffer
+ @param left start width to draw the button
+ @param top start height to draw the button
+ @param right end width to draw the button
+ @param bottom end height to draw the button
+ @source source screen buffer, in this case working buffer
+ @param leftDest start width to draw the button in destination buffer
+ @param topDest start height to draw the button in destination buffer
+ @dest destination screen buffer, in this case front buffer */
+void blitBox(int32 left, int32 top, int32 right, int32 bottom, int8 *source, int32 leftDest, int32 topDest, int8 *dest) {
+ int32 width;
+ int32 height;
+ int8 *s;
+ int8 *d;
+ int32 insideLine;
+ int32 temp3;
+ int32 i;
+ int32 j;
+
+ s = screenLookupTable[top] + source + left;
+ d = screenLookupTable[topDest] + dest + leftDest;
+
+ width = right - left + 1;
+ height = bottom - top + 1;
+
+ insideLine = SCREEN_WIDTH - width;
+ temp3 = left;
+
+ left >>= 2;
+ temp3 &= 3;
+
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width; i++) {
+ *(d++) = *(s++);
+ }
+
+ d += insideLine;
+ s += insideLine;
+ }
+}
+
+/** Draws inside buttons transparent area
+ @param left start width to draw the button
+ @param top start height to draw the button
+ @param right end width to draw the button
+ @param bottom end height to draw the button
+ @param colorAdj index to adjust the transparent box color */
+void drawTransparentBox(int32 left, int32 top, int32 right, int32 bottom, int32 colorAdj) {
+ uint8 *pos;
+ int32 width;
+ int32 height;
+ int32 height2;
+ int32 temp;
+ int32 localMode;
+ int32 var1;
+ int8 color;
+ int8 color2;
+
+ if (left > SCREEN_TEXTLIMIT_RIGHT)
+ return;
+ if (right < SCREEN_TEXTLIMIT_LEFT)
+ return;
+ if (top > SCREEN_TEXTLIMIT_BOTTOM)
+ return;
+ if (bottom < SCREEN_TEXTLIMIT_TOP)
+ return;
+
+ if (left < SCREEN_TEXTLIMIT_LEFT)
+ left = SCREEN_TEXTLIMIT_LEFT;
+ if (right > SCREEN_TEXTLIMIT_RIGHT)
+ right = SCREEN_TEXTLIMIT_RIGHT;
+ if (top < SCREEN_TEXTLIMIT_TOP)
+ top = SCREEN_TEXTLIMIT_TOP;
+ if (bottom > SCREEN_TEXTLIMIT_BOTTOM)
+ bottom = SCREEN_TEXTLIMIT_BOTTOM;
+
+ pos = screenLookupTable[top] + frontVideoBuffer + left;
+ height2 = height = bottom - top;
+ height2++;
+
+ width = right - left + 1;
+
+ temp = 640 - width; // SCREEN_WIDTH
+ localMode = colorAdj;
+
+ do {
+ var1 = width;
+ do {
+ color2 = color = *pos;
+ color2 &= 0xF0;
+ color &= 0x0F;
+ color -= localMode;
+ if (color < 0)
+ color = color2;
+ else
+ color += color2;
+ *pos++ = color;
+ var1--;
+ } while (var1 > 0);
+ pos += temp;
+ height2--;
+ } while (height2 > 0);
+}
+
+void drawSplittedBox(int32 left, int32 top, int32 right, int32 bottom, uint8 e) { // Box
+ uint8 *ptr;
+
+ int32 offset;
+
+ int32 x;
+ int32 y;
+
+ if (left > SCREEN_TEXTLIMIT_RIGHT)
+ return;
+ if (right < SCREEN_TEXTLIMIT_LEFT)
+ return;
+ if (top > SCREEN_TEXTLIMIT_BOTTOM)
+ return;
+ if (bottom < SCREEN_TEXTLIMIT_TOP)
+ return;
+
+ // cropping
+ offset = -((right - left) - SCREEN_WIDTH);
+
+ ptr = frontVideoBuffer + screenLookupTable[top] + left;
+
+ for (x = top; x < bottom; x++) {
+ for (y = left; y < right; y++) {
+ *(ptr++) = e;
+ }
+ ptr += offset;
+ }
+}
+
+void setClip(int32 left, int32 top, int32 right, int32 bottom) {
+ if (left < 0)
+ left = 0;
+ textWindowLeft = left;
+
+ if (top < 0)
+ top = 0;
+ textWindowTop = top;
+
+ if (right >= SCREEN_WIDTH)
+ right = SCREEN_TEXTLIMIT_RIGHT;
+ textWindowRight = right;
+
+ if (bottom >= SCREEN_HEIGHT)
+ bottom = SCREEN_TEXTLIMIT_BOTTOM;
+ textWindowBottom = bottom;
+}
+
+void saveClip() { // saveTextWindow
+ textWindowLeftSave = textWindowLeft;
+ textWindowTopSave = textWindowTop;
+ textWindowRightSave = textWindowRight;
+ textWindowBottomSave = textWindowBottom;
+}
+
+void loadClip() { // loadSavedTextWindow
+ textWindowLeft = textWindowLeftSave;
+ textWindowTop = textWindowTopSave;
+ textWindowRight = textWindowRightSave;
+ textWindowBottom = textWindowBottomSave;
+}
+
+void resetClip() {
+ textWindowTop = textWindowLeft = SCREEN_TEXTLIMIT_TOP;
+ textWindowRight = SCREEN_TEXTLIMIT_RIGHT;
+ textWindowBottom = SCREEN_TEXTLIMIT_BOTTOM;
+}
diff --git a/engines/twine/interface.h b/engines/twine/interface.h
new file mode 100644
index 0000000000..c7fc7bf873
--- /dev/null
+++ b/engines/twine/interface.h
@@ -0,0 +1,84 @@
+/** @file interface.h
+ @brief
+ This file contains in-game interface routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include "sys.h"
+#include "main.h"
+
+/** Screen top limit to display the texts */
+#define SCREEN_TEXTLIMIT_TOP 0
+/** Screen left limit to display the texts */
+#define SCREEN_TEXTLIMIT_LEFT 0
+/** Screen right limit to display the texts */
+#define SCREEN_TEXTLIMIT_RIGHT SCREEN_WIDTH-1
+/** Screen bottom limit to display the texts */
+#define SCREEN_TEXTLIMIT_BOTTOM SCREEN_HEIGHT-1
+
+int32 textWindowTop;
+int32 textWindowTopSave;
+int32 textWindowLeft;
+int32 textWindowLeftSave;
+int32 textWindowRight;
+int32 textWindowRightSave;
+int32 textWindowBottom;
+int32 textWindowBottomSave;
+
+/** Draw button line
+ @param startWidth width value where the line starts
+ @param startHeight height value where the line starts
+ @param endWidth width value where the line ends
+ @param endHeight height value where the line ends
+ @param lineColor line color in the current palette */
+void drawLine(int32 startWidth, int32 startHeight, int32 endWidth, int32 endHeight, int32 lineColor);
+
+/** Blit button box from working buffer to front buffer
+ @param left start width to draw the button
+ @param top start height to draw the button
+ @param right end width to draw the button
+ @param bottom end height to draw the button
+ @source source screen buffer, in this case working buffer
+ @param leftDest start width to draw the button in destination buffer
+ @param topDest start height to draw the button in destination buffer
+ @dest destination screen buffer, in this case front buffer */
+void blitBox(int32 left, int32 top, int32 right, int32 bottom, int8 *source, int32 leftDest, int32 topDest, int8 *dest);
+
+/** Draws inside buttons transparent area
+ @param left start width to draw the button
+ @param top start height to draw the button
+ @param right end width to draw the button
+ @param bottom end height to draw the button
+ @param colorAdj index to adjust the transparent box color */
+void drawTransparentBox(int32 left, int32 top, int32 right, int32 bottom, int32 colorAdj);
+
+void drawSplittedBox(int32 left, int32 top, int32 right, int32 bottom, uint8 e);
+
+void setClip(int32 left, int32 top, int32 right, int32 bottom);
+void saveClip(); // saveTextWindow
+void loadClip(); // loadSavedTextWindow
+void resetClip();
+
+#endif
diff --git a/engines/twine/keyboard.cpp b/engines/twine/keyboard.cpp
new file mode 100644
index 0000000000..ba0681ad4b
--- /dev/null
+++ b/engines/twine/keyboard.cpp
@@ -0,0 +1,98 @@
+/** @file keyboard.cpp
+ @brief
+ This file contains movies routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "keyboard.h"
+
+/** Initialize engine auxiliar keymap */
+uint8 pressedKeyMap[29] = {
+ 0x48, // 0
+ 0x50,
+ 0x4B,
+ 0x4D,
+ 0x47,
+ 0x49,
+ 0x51,
+ 0x4F, // 7
+
+ 0x39, // 8
+ 0x1C,
+ 0x1D,
+ 0x38,
+ 0x53,
+ 0x2A,
+ 0x36, // 14
+
+ 0x3B, // 15
+ 0x3C,
+ 0x3D,
+ 0x3E,
+ 0x3F,
+ 0x40, // LBAKEY_F6
+ 0x41,
+ 0x42,
+ 0x43,
+ 0x44,
+ 0x57,
+ 0x58,
+ 0x2A,
+ 0x0, // 28
+};
+
+uint16 pressedKeyCharMap[31] = {
+ 0x0100, // up
+ 0x0200, // down
+ 0x0400, // left
+ 0x0800, // right
+ 0x0500, // home
+ 0x0900, // pageup
+ 0x0A00, // pagedown
+ 0x0600, // end
+
+ 0x0101, // space bar
+ 0x0201, // enter
+ 0x0401, // ctrl
+ 0x0801, // alt
+ 0x1001, // del
+ 0x2001, // left shift
+ 0x2001, // right shift
+
+ 0x0102, // F1
+ 0x0202, // F2
+ 0x0402, // F3
+ 0x0802, // F4
+ 0x1002, // F5
+ 0x2002, // F6
+ 0x4002, // F7
+ 0x8002, // F8
+
+ 0x0103, // F9
+ 0x0203, // F10
+ 0x0403, // ?
+ 0x0803, // ?
+ 0x00FF, // left shift
+ 0x00FF,
+ 0x0,
+ 0x0,
+};
diff --git a/engines/twine/keyboard.h b/engines/twine/keyboard.h
new file mode 100644
index 0000000000..325a6e2c68
--- /dev/null
+++ b/engines/twine/keyboard.h
@@ -0,0 +1,51 @@
+/** @file keyboard.h
+ @brief
+ This file contains movies routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef KEYBOARD_H
+#define KEYBOARD_H
+
+#include "sys.h"
+
+/** Pressed key map - scanCodeTab1 */
+extern uint8 pressedKeyMap[29];
+/** Pressed key char map - scanCodeTab2 */
+extern uint16 pressedKeyCharMap[31];
+
+/** Skipped key - key1 */
+int16 skippedKey;
+/** Pressed key - printTextVar12 */
+int16 pressedKey;
+//int printTextVar13;
+/** Skip intro variable */
+int16 skipIntro;
+/** Current key value */
+int16 currentKey;
+/** Auxiliar key value */
+int16 key;
+
+int32 heroPressedKey;
+int32 heroPressedKey2;
+
+#endif
diff --git a/engines/twine/lbaengine.cpp b/engines/twine/lbaengine.cpp
new file mode 100644
index 0000000000..9b164215fe
--- /dev/null
+++ b/engines/twine/lbaengine.cpp
@@ -0,0 +1,538 @@
+/** @file lbaengine.cpp
+ @brief
+ This file contains the main game engine routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "lbaengine.h"
+#include "main.h"
+#include "sdlengine.h"
+#include "screens.h"
+#include "grid.h"
+#include "debug.grid.h"
+#include "scene.h"
+#include "menu.h"
+#include "interface.h"
+#include "text.h"
+#include "redraw.h"
+#include "hqrdepack.h"
+#include "resources.h"
+#include "renderer.h"
+#include "animations.h"
+#include "movements.h"
+#include "keyboard.h"
+#include "gamestate.h"
+#include "sound.h"
+#include "script.life.h"
+#include "script.move.h"
+#include "extra.h"
+#include "menuoptions.h"
+#include "collision.h"
+
+#ifdef GAMEMOD
+#include "debug.h"
+#endif
+
+int32 isTimeFreezed = 0;
+int32 saveFreezedTime = 0;
+
+enum InventoryItems {
+ kiHolomap = 0,
+ kiMagicBall = 1,
+ kiUseSabre = 2,
+ kiBookOfBu = 5,
+ kiProtoPack = 12,
+ kiPinguin = 14,
+ kiBonusList = 26,
+ kiCloverLeaf = 27
+};
+
+void freezeTime() {
+ if (!isTimeFreezed)
+ saveFreezedTime = lbaTime;
+ isTimeFreezed++;
+}
+
+void unfreezeTime() {
+ --isTimeFreezed;
+ if (isTimeFreezed == 0)
+ lbaTime = saveFreezedTime;
+}
+
+void processActorSamplePosition(int32 actorIdx) {
+ int32 channelIdx;
+ ActorStruct *actor = &sceneActors[actorIdx];
+ channelIdx = getActorChannel(actorIdx);
+ setSamplePosition(channelIdx, actor->X, actor->Y, actor->Z);
+}
+
+/** Game engine main loop
+ @return true if we want to show credit sequence */
+int32 runGameEngine() { // mainLoopInteration
+ int32 a;
+ readKeys();
+
+ if (needChangeScene > -1) {
+ changeScene();
+ }
+
+ previousLoopPressedKey = loopPressedKey;
+ key = pressedKey;
+ loopPressedKey = skippedKey;
+ loopCurrentKey = skipIntro;
+
+#ifdef GAMEMOD
+ processDebug(loopCurrentKey);
+#endif
+
+ if(canShowCredits != 0) {
+ // TODO: if current music playing != 8, than play_track(8);
+ if (skipIntro != 0) {
+ return 0;
+ }
+ if (pressedKey != 0) {
+ return 0;
+ }
+ if (skippedKey != 0) {
+ return 0;
+ }
+ } else {
+ // Process give up menu - Press ESC
+ if (skipIntro == 1 && sceneHero->life > 0 && sceneHero->entity != -1 && !sceneHero->staticFlags.bIsHidden) {
+ freezeTime();
+ if (giveupMenu()) {
+ unfreezeTime();
+ redrawEngineActions(1);
+ freezeTime();
+ saveGame(); // auto save game
+ quitGame = 0;
+ cfgfile.Quit = 0;
+ unfreezeTime();
+ return 0;
+ } else {
+ unfreezeTime();
+ redrawEngineActions(1);
+ }
+ }
+
+ // Process options menu - Press F6
+ if (loopCurrentKey == 0x40) {
+ int tmpLangCD = cfgfile.LanguageCDId;
+ freezeTime();
+ pauseSamples();
+ OptionsMenuSettings[5] = 15;
+ cfgfile.LanguageCDId = 0;
+ initTextBank(0);
+ optionsMenu();
+ cfgfile.LanguageCDId = tmpLangCD;
+ initTextBank(currentTextBank + 3);
+ //TODO: play music
+ resumeSamples();
+ unfreezeTime();
+ redrawEngineActions(1);
+ }
+
+ // inventory menu
+ loopInventoryItem = -1;
+ if (loopCurrentKey == 0x36 && sceneHero->entity != -1 && sceneHero->controlMode == kManual) {
+ freezeTime();
+ processInventoryMenu();
+
+ switch (loopInventoryItem) {
+ case kiHolomap:
+ printf("Use Inventory [kiHolomap] not implemented!\n");
+ break;
+ case kiMagicBall:
+ if (usingSabre == 1) {
+ initModelActor(0, 0);
+ }
+ usingSabre = 0;
+ break;
+ case kiUseSabre:
+ if (sceneHero->body != GAMEFLAG_HAS_SABRE) {
+ if (heroBehaviour == kProtoPack) {
+ setBehaviour(kNormal);
+ }
+ initModelActor(GAMEFLAG_HAS_SABRE, 0);
+ initAnim(24, 1, 0, 0);
+
+ usingSabre = 1;
+ }
+ break;
+ case kiBookOfBu: {
+ int32 tmpFlagDisplayText;
+
+ fadeToBlack(paletteRGBA);
+ loadImage(RESSHQR_INTROSCREEN1IMG, 1);
+ initTextBank(2);
+ newGameVar4 = 0;
+ textClipFull();
+ setFontCrossColor(15);
+ tmpFlagDisplayText = cfgfile.FlagDisplayText;
+ cfgfile.FlagDisplayText = 1;
+ drawTextFullscreen(161);
+ cfgfile.FlagDisplayText = tmpFlagDisplayText;
+ textClipSmall();
+ newGameVar4 = 1;
+ initTextBank(currentTextBank + 3);
+ fadeToBlack(paletteRGBACustom);
+ clearScreen();
+ flip();
+ setPalette(paletteRGBA);
+ lockPalette = 1;
+ }
+ break;
+ case kiProtoPack:
+ if (gameFlags[GAMEFLAG_BOOKOFBU]) {
+ sceneHero->body = 0;
+ } else {
+ sceneHero->body = 1;
+ }
+
+ if (heroBehaviour == kProtoPack) {
+ setBehaviour(kNormal);
+ } else {
+ setBehaviour(kProtoPack);
+ }
+ break;
+ case kiPinguin: {
+ ActorStruct *pinguin = &sceneActors[mecaPinguinIdx];
+
+ pinguin->X = destX + sceneHero->X;
+ pinguin->Y = sceneHero->Y;
+ pinguin->Z = destZ + sceneHero->Z;
+ pinguin->angle = sceneHero->angle;
+
+ rotateActor(0, 800, pinguin->angle);
+
+ if (!checkCollisionWithActors(mecaPinguinIdx)) {
+ pinguin->life = 50;
+ pinguin->body = -1;
+ initModelActor(0, mecaPinguinIdx);
+ pinguin->dynamicFlags.bIsDead = 0; // &= 0xDF
+ pinguin->brickShape = 0;
+ moveActor(pinguin->angle, pinguin->angle, pinguin->speed, &pinguin->move);
+ gameFlags[GAMEFLAG_MECA_PINGUIN] = 0; // byte_50D89 = 0;
+ pinguin->info0 = lbaTime + 1500;
+ }
+ }
+ break;
+ case kiBonusList: {
+ int32 tmpLanguageCDIdx;
+ tmpLanguageCDIdx = cfgfile.LanguageCDId;
+ unfreezeTime();
+ redrawEngineActions(1);
+ freezeTime();
+ cfgfile.LanguageCDId = 0;
+ initTextBank(2);
+ textClipFull();
+ setFontCrossColor(15);
+ drawTextFullscreen(162);
+ textClipSmall();
+ cfgfile.LanguageCDId = tmpLanguageCDIdx;
+ initTextBank(currentTextBank + 3);
+ }
+ break;
+ case kiCloverLeaf:
+ if (sceneHero->life < 50) {
+ if (inventoryNumLeafs > 0) {
+ sceneHero->life = 50;
+ inventoryMagicPoints = magicLevelIdx * 20;
+ inventoryNumLeafs--;
+ addOverlay(koInventoryItem, 27, 0, 0, 0, koNormal, 3);
+ }
+ }
+ break;
+ }
+
+
+ unfreezeTime();
+ redrawEngineActions(1);
+ }
+
+ // Process behaviour menu - Press CTRL and F1..F4 Keys
+ if ((loopCurrentKey == 0x1D || loopCurrentKey == 0x3B || loopCurrentKey == 0x3C || loopCurrentKey == 0x3D || loopCurrentKey == 0x3E) && sceneHero->entity != -1 && sceneHero->controlMode == kManual) {
+ if (loopCurrentKey != 0x1D) {
+ heroBehaviour = loopCurrentKey - 0x3B;
+ }
+ freezeTime();
+ processBehaviourMenu();
+ unfreezeTime();
+ redrawEngineActions(1);
+ }
+
+ // use Proto-Pack
+ if (loopCurrentKey == 0x24 && gameFlags[GAMEFLAG_PROTOPACK] == 1) {
+ if (gameFlags[GAMEFLAG_BOOKOFBU]) {
+ sceneHero->body = 0;
+ } else {
+ sceneHero->body = 1;
+ }
+
+ if (heroBehaviour == kProtoPack) {
+ setBehaviour(kNormal);
+ } else {
+ setBehaviour(kProtoPack);
+ }
+ }
+
+ // Press Enter to Recenter Screen
+ if ((loopPressedKey & 2) && !disableScreenRecenter) {
+ newCameraX = sceneActors[currentlyFollowedActor].X >> 9;
+ newCameraY = sceneActors[currentlyFollowedActor].Y >> 8;
+ newCameraZ = sceneActors[currentlyFollowedActor].Z >> 9;
+ reqBgRedraw = 1;
+ }
+
+ // TODO: draw holomap
+
+ // Process Pause - Press P
+ if (loopCurrentKey == 0x19) {
+ freezeTime();
+ setFontColor(15);
+ drawText(5, 446, (int8*)"Pause"); // no key for pause in Text Bank
+ copyBlockPhys(5, 446, 100, 479);
+ do {
+ readKeys();
+ SDL_Delay(10);
+ } while (skipIntro != 0x19 && !pressedKey);
+ unfreezeTime();
+ redrawEngineActions(1);
+ }
+ }
+
+ loopActorStep = getRealValue(&loopMovePtr);
+ if (!loopActorStep) {
+ loopActorStep = 1;
+ }
+
+ setActorAngle(0, -256, 5, &loopMovePtr);
+ disableScreenRecenter = 0;
+
+ processEnvironmentSound();
+
+ // Reset HitBy state
+ for (a = 0; a < sceneNumActors; a++)
+ {
+ sceneActors[a].hitBy = -1;
+ }
+
+ processExtras();
+
+ for (a = 0; a < sceneNumActors; a++) {
+ ActorStruct *actor = &sceneActors[a];
+
+ if (!actor->dynamicFlags.bIsDead) {
+ if (actor->life == 0) {
+ if (a == 0) { // if its hero who died
+ initAnim(kLandDeath, 4, 0, 0);
+ actor->controlMode = 0;
+ } else {
+ playSample(37, Rnd(2000) + 3096, 1, actor->X, actor->Y, actor->Z, a);
+
+ if (a == mecaPinguinIdx) {
+ addExtraExplode(actor->X, actor->Y, actor->Z);
+ }
+ }
+
+ if (actor->bonusParameter & 0x1F0 && !(actor->bonusParameter & 1)) {
+ processActorExtraBonus(a);
+ }
+ }
+
+ processActorMovements(a);
+
+ actor->collisionX = actor->X;
+ actor->collisionY = actor->Y;
+ actor->collisionZ = actor->Z;
+
+ if (actor->positionInMoveScript != -1) {
+ processMoveScript(a);
+ }
+
+ processActorAnimations(a);
+
+ if (actor->staticFlags.bIsZonable) {
+ processActorZones(a);
+ }
+
+ if (actor->positionInLifeScript != -1) {
+ processLifeScript(a);
+ }
+
+ processActorSamplePosition(a);
+
+ if (quitGame != -1) {
+ return quitGame;
+ }
+
+ if (actor->staticFlags.bCanDrown) {
+ int32 brickSound;
+ brickSound = getBrickSoundType(actor->X, actor->Y - 1, actor->Z);
+ actor->brickSound = brickSound;
+
+ if ((brickSound & 0xF0) == 0xF0) {
+ if ((brickSound & 0xF) == 1) {
+ if (a) { // all other actors
+ int32 rnd = Rnd(2000) + 3096;
+ playSample(0x25, rnd, 1, actor->X, actor->Y, actor->Z, a);
+ if (actor->bonusParameter & 0x1F0) {
+ if (!(actor->bonusParameter & 1)) {
+ processActorExtraBonus(a);
+ }
+ actor->life = 0;
+ }
+ } else { // if Hero
+ if (heroBehaviour != 4 || (brickSound & 0x0F) != actor->anim) {
+ if (!cropBottomScreen)
+ {
+ initAnim(kDrawn, 4, 0, 0);
+ projectPositionOnScreen(actor->X - cameraX, actor->Y - cameraY, actor->Z - cameraZ);
+ cropBottomScreen = projPosY;
+ }
+ projectPositionOnScreen(actor->X - cameraX, actor->Y - cameraY, actor->Z - cameraZ);
+ actor->controlMode = 0;
+ actor->life = -1;
+ cropBottomScreen = projPosY;
+ actor->staticFlags.bCanDrown |= 0x10;
+ }
+ }
+ }
+ }
+ }
+
+ if (actor->life <= 0) {
+ if (!a) { // if its Hero
+ if (actor->dynamicFlags.bAnimEnded) {
+ if (inventoryNumLeafs > 0) { // use clover leaf automaticaly
+ sceneHero->X = newHeroX;
+ sceneHero->Y = newHeroY;
+ sceneHero->Z = newHeroZ;
+
+ needChangeScene = currentSceneIdx;
+ inventoryMagicPoints = magicLevelIdx * 20;
+
+ newCameraX = (sceneHero->X >> 9);
+ newCameraY = (sceneHero->Y >> 8);
+ newCameraZ = (sceneHero->Z >> 9);
+
+ heroPositionType = kReborn;
+
+ sceneHero->life = 50;
+ reqBgRedraw = 1;
+ lockPalette = 1;
+ inventoryNumLeafs--;
+ cropBottomScreen = 0;
+ } else { // game over
+ inventoryNumLeafsBox = 2;
+ inventoryNumLeafs = 1;
+ inventoryMagicPoints = magicLevelIdx * 20;
+ heroBehaviour = previousHeroBehaviour;
+ actor->angle = previousHeroAngle;
+ actor->life = 50;
+
+ if (previousSceneIdx != currentSceneIdx) {
+ newHeroX = -1;
+ newHeroY = -1;
+ newHeroZ = -1;
+ currentSceneIdx = previousSceneIdx;
+ }
+
+ saveGame();
+ processGameoverAnimation();
+ quitGame = 0;
+ return 0;
+ }
+ }
+ } else {
+ processActorCarrier(a);
+ actor->dynamicFlags.bIsDead = 1;
+ actor->entity = -1;
+ actor->zone = -1;
+ }
+ }
+
+ if (needChangeScene != -1) {
+ return 0;
+ }
+ }
+ }
+
+ // recenter screen automatically
+ if (!disableScreenRecenter && !useFreeCamera) {
+ ActorStruct *actor = &sceneActors[currentlyFollowedActor];
+ projectPositionOnScreen(actor->X - (newCameraX << 9),
+ actor->Y - (newCameraY << 8),
+ actor->Z - (newCameraZ << 9));
+ if (projPosX < 80 || projPosX > 539 || projPosY < 80 || projPosY > 429) {
+ newCameraX = ((actor->X + 0x100) >> 9) + (((actor->X + 0x100) >> 9) - newCameraX) / 2;
+ newCameraY = actor->Y >> 8;
+ newCameraZ = ((actor->Z + 0x100) >> 9) + (((actor->Z + 0x100) >> 9) - newCameraZ) / 2;
+
+ if(newCameraX >= 64) {
+ newCameraX = 63;
+ }
+
+ if(newCameraZ >= 64) {
+ newCameraZ = 63;
+ }
+
+ reqBgRedraw = 1;
+ }
+ }
+
+ redrawEngineActions(reqBgRedraw);
+
+ // workaround to fix hero redraw after drowning
+ if(cropBottomScreen && reqBgRedraw == 1) {
+ sceneHero->staticFlags.bIsHidden = 1;
+ redrawEngineActions(1);
+ sceneHero->staticFlags.bIsHidden = 0;
+ }
+
+ needChangeScene = -1;
+ reqBgRedraw = 0;
+
+ return 0;
+}
+
+/** Game engine main loop
+ @return true if we want to show credit sequence */
+int32 gameEngineLoop() { // mainLoop
+ uint32 start;
+
+ reqBgRedraw = 1;
+ lockPalette = 1;
+ setActorAngle(0, -256, 5, &loopMovePtr);
+
+ while (quitGame == -1) {
+ start = SDL_GetTicks();
+
+ while (SDL_GetTicks() < start + cfgfile.Fps) {
+ if (runGameEngine())
+ return 1;
+ SDL_Delay(1);
+ }
+ lbaTime++;
+ }
+ return 0;
+}
diff --git a/engines/twine/lbaengine.h b/engines/twine/lbaengine.h
new file mode 100644
index 0000000000..315dc284b8
--- /dev/null
+++ b/engines/twine/lbaengine.h
@@ -0,0 +1,67 @@
+/** @file lbaengine.h
+ @brief
+ This file contains the main game engine routines
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef GAMEENGINE_H
+#define GAMEENGINE_H
+
+#include "sys.h"
+#include "actor.h"
+
+int32 quitGame;
+volatile int32 lbaTime;
+
+int16 leftMouse;
+int16 rightMouse;
+
+/** Work video buffer */
+uint8 *workVideoBuffer;
+/** Main game video buffer */
+uint8 *frontVideoBuffer;
+/** Auxiliar game video buffer */
+uint8 *frontVideoBufferbis;
+
+/** temporary screen table */
+int32 screenLookupTable[2000];
+
+ActorMoveStruct loopMovePtr; // mainLoopVar1
+
+int32 loopPressedKey; // mainLoopVar5
+int32 previousLoopPressedKey; // mainLoopVar6
+int32 loopCurrentKey; // mainLoopVar7
+int32 loopInventoryItem; // mainLoopVar9
+
+int32 loopActorStep; // mainLoopVar17
+
+/** Disable screen recenter */
+int16 disableScreenRecenter;
+
+int32 zoomScreen;
+
+void freezeTime();
+void unfreezeTime();
+
+int32 gameEngineLoop();
+
+#endif
diff --git a/engines/twine/main.cpp b/engines/twine/main.cpp
new file mode 100644
index 0000000000..2f9a9cfd98
--- /dev/null
+++ b/engines/twine/main.cpp
@@ -0,0 +1,498 @@
+/** @file main.cpp
+ @brief
+ This file contains the main engine functions.
+ It also contains configurations file definitions.
+
+ TwinEngine: a Little Big Adventure engine
+
+ Copyright (C) 2013 The TwinEngine team
+ Copyright (C) 2008-2013 Prequengine team
+ Copyright (C) 2002-2007 The TwinEngine team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "main.h"
+#include "resources.h"
+#include "sdlengine.h"
+#include "screens.h"
+#include "music.h"
+#include "menu.h"
+#include "interface.h"
+#include "flamovies.h"
+#include "hqrdepack.h"
+#include "scene.h"
+#include "grid.h"
+#include "lbaengine.h"
+#include "redraw.h"
+#include "text.h"
+#include "renderer.h"
+#include "animations.h"
+#include "gamestate.h"
+#include "keyboard.h"
+#include "actor.h"
+#include "sound.h"
+#include "fcaseopen.h"
+
+/** Engine current version */
+const int8* ENGINE_VERSION = (int8*) "0.2.0";
+
+/** Engine configuration filename */
+const int8* CONFIG_FILENAME = (int8*) "lba.cfg";
+
+/** Engine install setup filename
+
+ This file contains informations about the game version.
+ This is only used for original games. For mod games project you can
+ used \a lba.cfg file \b Version tag. If this tag is set for original game
+ it will be used instead of \a setup.lst file. */
+const int8* SETUP_FILENAME = (int8*) "setup.lst";
+
+/** Configuration types at \a lba.cfg file
+
+ Fill this with all needed configurations at \a lba.cfg file.
+ This engine version allows new type of configurations.
+ Check new config lines at \a lba.cfg file after the first game execution */
+int8 CFGList[][22] = {
+ "Language:",
+ "LanguageCD:",
+ "FlagDisplayText:",
+ "FlagKeepVoice:",
+ "SvgaDriver:",
+ "MidiDriver:",
+ "MidiExec:",
+ "MidiBase:",
+ "MidiType:",
+ "MidiIRQ:",
+ "MidiDMA:", // 10
+ "WaveDriver:",
+ "WaveExec:",
+ "WaveBase:",
+ "WaveIRQ:",
+ "WaveDMA:",
+ "WaveRate:",
+ "MixerDriver:",
+ "MixerBase:",
+ "WaveVolume:",
+ "VoiceVolume:", // 20
+ "MusicVolume:",
+ "CDVolume:",
+ "LineVolume:",
+ "MasterVolume:",
+ "Version:",
+ "FullScreen:",
+ "UseCD:",
+ "Sound:",
+ "Movie:",
+ "CrossFade:", // 30
+ "Fps:",
+ "Debug:",
+ "UseAutoSaving:",
+ "CombatAuto:",
+ "Shadow:",
+ "SceZoom:",
+ "FillDetails:",
+ "InterfaceStyle",
+ "WallCollision" // 39
+};
+
+int8 LanguageTypes[][10] = {
+ "English",
+ "Français",
+ "Deutsch",
+ "Español",
+ "Italiano",
+ "Português"
+};
+ConfigFile cfgfile;
+
+/** Allocate video memory, both front and back buffers */
+void allocVideoMemory() {
+ int32 i, j, k;
+
+ workVideoBuffer = (uint8 *) malloc((SCREEN_WIDTH * SCREEN_HEIGHT) * sizeof(uint8));
+ frontVideoBuffer = frontVideoBufferbis = (uint8 *) malloc(sizeof(uint8) * SCREEN_WIDTH * SCREEN_HEIGHT);
+ initScreenBuffer(frontVideoBuffer, SCREEN_WIDTH, SCREEN_HEIGHT);
+
+ j = 0;
+ k = 0;
+ for (i = SCREEN_HEIGHT; i > 0; i--) {
+ screenLookupTable[j] = k;
+ j++;
+ k += SCREEN_WIDTH;
+ }
+
+ // initVideoVar1 = -1;
+}
+
+/** Gets configuration type index from lba.cfg config file
+ @param lineBuffer buffer with config line
+ @return config type index */
+int getConfigTypeIndex(int8* lineBuffer) {
+ int32 i;
+ char buffer[256];
+ char* ptr;
+
+ strcpy(buffer, lineBuffer);
+
+ ptr = strchr(buffer, ' ');
+
+ if (ptr) {
+ *ptr = 0;
+ }
+
+ for (i = 0; i < (sizeof(CFGList) / 22); i++) {
+ if (strlen(CFGList[i])) {
+ if (!strcmp(CFGList[i], buffer)) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/** Gets configuration type index from lba.cfg config file
+ @param lineBuffer buffer with config line
+ @return config type index */
+int getLanguageTypeIndex(int8* language) {
+ int32 i;
+ char buffer[256];
+ char* ptr;
+
+ strcpy(buffer, language);
+
+ ptr = strchr(buffer, ' ');
+
+ if (ptr) {
+ *ptr = 0;
+ }
+
+ for (i = 0; i < (sizeof(LanguageTypes) / 10); i++) {
+ if (strlen(LanguageTypes[i])) {
+ if (!strcmp(LanguageTypes[i], buffer)) {
+ return i;
+ }
+ }
+ }
+
+ return 0; // English
+}
+
+/** Init configuration file \a lba.cfg */
+void initConfigurations() {
+ FILE *fd, *fd_test;
+ int8 buffer[256], tmp[16];
+ int32 cfgtype = -1;
+
+ fd = fcaseopen(CONFIG_FILENAME, "rb");
+ if (!fd)
+ printf("Error: Can't find config file %s\n", CONFIG_FILENAME);
+
+ // make sure it quit when it reaches the end of file
+ while (fgets(buffer, 256, fd) != NULL) {
+ *strchr(buffer, 0x0D0A) = 0;
+ cfgtype = getConfigTypeIndex(buffer);
+ if (cfgtype != -1) {
+ switch (cfgtype) {
+ case 0:
+ sscanf(buffer, "Language: %s", cfgfile.Language);
+ cfgfile.LanguageId = getLanguageTypeIndex(cfgfile.Language);
+ break;
+ case 1:
+ sscanf(buffer, "LanguageCD: %s", cfgfile.LanguageCD);
+ cfgfile.LanguageCDId = getLanguageTypeIndex(cfgfile.Language) + 1;
+ break;
+ case 2:
+ sscanf(buffer, "FlagDisplayText: %s", cfgfile.FlagDisplayTextStr);
+ if (!strcmp(cfgfile.FlagDisplayTextStr,"ON")) {
+ cfgfile.FlagDisplayText = 1;
+ } else {
+ cfgfile.FlagDisplayText = 0;
+ }
+ break;
+ case 3:
+ sscanf(buffer, "FlagKeepVoice: %s", cfgfile.FlagKeepVoiceStr);
+ break;
+ case 8:
+ sscanf(buffer, "MidiType: %s", tmp);
+ if (strcmp(tmp, "auto") == 0) {
+ fd_test = fcaseopen(HQR_MIDI_MI_WIN_FILE, "rb");
+ if (fd_test) {
+ fclose(fd_test);
+ cfgfile.MidiType = 1;
+ }
+ else
+ cfgfile.MidiType = 0;
+ }
+ else if (strcmp(tmp, "midi") == 0)
+ cfgfile.MidiType = 1;
+ else
+ cfgfile.MidiType = 0;
+ break;
+ case 19:
+ sscanf(buffer, "WaveVolume: %d", &cfgfile.WaveVolume);
+ cfgfile.VoiceVolume = cfgfile.WaveVolume;
+ break;
Commit: 37bbfc168b1dde8cf2cd6a39f1ec72e4bcc92903
https://github.com/scummvm/scummvm/commit/37bbfc168b1dde8cf2cd6a39f1ec72e4bcc92903
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: converted to classes and use the scummvm systems
also converted the code to the coding guidelines of the scummvm team
Changed paths:
A engines/twine/debug_grid.cpp
A engines/twine/debug_grid.h
A engines/twine/debug_scene.cpp
A engines/twine/debug_scene.h
A engines/twine/script_life.cpp
A engines/twine/script_life.h
A engines/twine/script_move.cpp
A engines/twine/script_move.h
A engines/twine/twine.cpp
A engines/twine/twine.h
R engines/twine/debug.grid.cpp
R engines/twine/debug.grid.h
R engines/twine/debug.scene.cpp
R engines/twine/debug.scene.h
R engines/twine/fcaseopen.cpp
R engines/twine/fcaseopen.h
R engines/twine/filereader.cpp
R engines/twine/filereader.h
R engines/twine/keyboard.cpp
R engines/twine/lbaengine.cpp
R engines/twine/lbaengine.h
R engines/twine/main.cpp
R engines/twine/main.h
R engines/twine/script.life.cpp
R engines/twine/script.life.h
R engines/twine/script.move.cpp
R engines/twine/script.move.h
R engines/twine/sdlengine.cpp
R engines/twine/sdlengine.h
R engines/twine/sys.cpp
R engines/twine/sys.h
devtools/credits.pl
engines/twine/actor.cpp
engines/twine/actor.h
engines/twine/animations.cpp
engines/twine/animations.h
engines/twine/collision.cpp
engines/twine/collision.h
engines/twine/configure.engine
engines/twine/debug.cpp
engines/twine/debug.h
engines/twine/detection.cpp
engines/twine/detection.h
engines/twine/extra.cpp
engines/twine/extra.h
engines/twine/flamovies.cpp
engines/twine/flamovies.h
engines/twine/gamestate.cpp
engines/twine/gamestate.h
engines/twine/grid.cpp
engines/twine/grid.h
engines/twine/holomap.cpp
engines/twine/holomap.h
engines/twine/hqrdepack.cpp
engines/twine/hqrdepack.h
engines/twine/interface.cpp
engines/twine/interface.h
engines/twine/keyboard.h
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/menuoptions.cpp
engines/twine/menuoptions.h
engines/twine/metaengine.cpp
engines/twine/module.mk
engines/twine/movements.cpp
engines/twine/movements.h
engines/twine/music.cpp
engines/twine/music.h
engines/twine/redraw.cpp
engines/twine/redraw.h
engines/twine/renderer.cpp
engines/twine/renderer.h
engines/twine/resources.cpp
engines/twine/resources.h
engines/twine/scene.cpp
engines/twine/scene.h
engines/twine/screens.cpp
engines/twine/screens.h
engines/twine/shadeangletab.h
engines/twine/sound.cpp
engines/twine/sound.h
engines/twine/text.cpp
engines/twine/text.h
engines/twine/xmidi.cpp
engines/twine/xmidi.h
gui/credits.h
diff --git a/devtools/credits.pl b/devtools/credits.pl
index db1df98bf5..33eea17332 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -949,6 +949,19 @@ begin_credits("Credits");
add_person("Gregory Montoir", "cyx", "(retired)");
end_section();
+ begin_section("TwinE");
+ add_person("Alexandre Fontoura", "xesf", "(retired)");
+ add_person("Vincent Hamm", "yaz0r", "(retired)");
+ add_person("Felipe Sanches", "jucablues", "(retired)");
+ add_person("Nikita Tereshin", "rumkex", "(retired)");
+ add_person("Patrik Dahlström", "risca", "(retired)");
+ add_person("Arthur Blot", "arthur.blot78", "(retired)");
+ add_person("Kyuubu", "wett", "(retired)");
+ add_person("Toël Hartmann", "toel__", "(retired)");
+ add_person("Sebástien Viannay", "", "(retired)");
+ add_person("Martin Gerhardy", "mgerhardy", "");
+ end_section();
+
begin_section("Ultima");
add_person("Paul Gilbert", "dreammaster", "");
add_person("Matthew Duggan", "stauff", "");
diff --git a/engines/twine/actor.cpp b/engines/twine/actor.cpp
index db31b5f9a6..795f4faff0 100644
--- a/engines/twine/actor.cpp
+++ b/engines/twine/actor.cpp
@@ -1,200 +1,176 @@
-/** @file actor.cpp
- @brief
- This file contains scene actor routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "actor.h"
-#include "lbaengine.h"
-#include "scene.h"
-#include "hqrdepack.h"
-#include "resources.h"
-#include "renderer.h"
-#include "grid.h"
-#include "animations.h"
-#include "renderer.h"
-#include "movements.h"
-#include "gamestate.h"
-#include "sound.h"
-#include "extra.h"
-
-/** Actors 3D body table - size of NUM_BODIES */
-uint8 *bodyTable[NUM_BODIES];
-
-/** Restart hero variables while opening new scenes */
-void restartHeroScene() {
- sceneHero->controlMode = 1;
- memset(&sceneHero->dynamicFlags, 0, 2);
- memset(&sceneHero->staticFlags, 0, 2);
-
- sceneHero->staticFlags.bComputeCollisionWithObj = 1;
- sceneHero->staticFlags.bComputeCollisionWithBricks = 1;
- sceneHero->staticFlags.bIsZonable = 1;
- sceneHero->staticFlags.bCanDrown = 1;
- sceneHero->staticFlags.bCanFall = 1;
-
- sceneHero->armor = 1;
- sceneHero->positionInMoveScript = -1;
- sceneHero->labelIdx = -1;
- sceneHero->positionInLifeScript = 0;
- sceneHero->zone = -1;
- sceneHero->angle = previousHeroAngle;
-
- setActorAngleSafe(sceneHero->angle, sceneHero->angle, 0, &sceneHero->move);
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/actor.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+#include "twine/animations.h"
+#include "twine/extra.h"
+#include "twine/gamestate.h"
+#include "twine/grid.h"
+#include "twine/hqrdepack.h"
+#include "twine/movements.h"
+#include "twine/renderer.h"
+#include "twine/resources.h"
+#include "twine/scene.h"
+#include "twine/screens.h"
+#include "twine/sound.h"
+#include "twine/twine.h"
+
+namespace TwinE {
+
+Actor::Actor(TwinEEngine *engine) : _engine(engine) {
+}
+
+void Actor::restartHeroScene() {
+ _engine->_scene->sceneHero->controlMode = 1;
+ memset(&_engine->_scene->sceneHero->dynamicFlags, 0, sizeof(_engine->_scene->sceneHero->dynamicFlags));
+ memset(&_engine->_scene->sceneHero->staticFlags, 0, sizeof(_engine->_scene->sceneHero->staticFlags));
+
+ _engine->_scene->sceneHero->staticFlags.bComputeCollisionWithObj = 1;
+ _engine->_scene->sceneHero->staticFlags.bComputeCollisionWithBricks = 1;
+ _engine->_scene->sceneHero->staticFlags.bIsZonable = 1;
+ _engine->_scene->sceneHero->staticFlags.bCanDrown = 1;
+ _engine->_scene->sceneHero->staticFlags.bCanFall = 1;
+
+ _engine->_scene->sceneHero->armor = 1;
+ _engine->_scene->sceneHero->positionInMoveScript = -1;
+ _engine->_scene->sceneHero->labelIdx = -1;
+ _engine->_scene->sceneHero->positionInLifeScript = 0;
+ _engine->_scene->sceneHero->zone = -1;
+ _engine->_scene->sceneHero->angle = previousHeroAngle;
+
+ _engine->_movements->setActorAngleSafe(_engine->_scene->sceneHero->angle, _engine->_scene->sceneHero->angle, 0, &_engine->_scene->sceneHero->move);
setBehaviour(previousHeroBehaviour);
cropBottomScreen = 0;
}
-/** Load hero 3D body and animations */
-void loadHeroEntities() {
- hqrGetallocEntry(&heroEntityATHLETIC, HQR_FILE3D_FILE, FILE3DHQR_HEROATHLETIC);
- sceneHero->entityDataPtr = heroEntityATHLETIC;
- heroAnimIdxATHLETIC = getBodyAnimIndex(0, 0);
+void Actor::loadHeroEntities() {
+ _engine->_hqrdepack->hqrGetallocEntry(&heroEntityATHLETIC, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROATHLETIC);
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityATHLETIC;
+ heroAnimIdxATHLETIC = _engine->_animations->getBodyAnimIndex(0, 0);
- hqrGetallocEntry(&heroEntityAGGRESSIVE, HQR_FILE3D_FILE, FILE3DHQR_HEROAGGRESSIVE);
- sceneHero->entityDataPtr = heroEntityAGGRESSIVE;
- heroAnimIdxAGGRESSIVE = getBodyAnimIndex(0, 0);
+ _engine->_hqrdepack->hqrGetallocEntry(&heroEntityAGGRESSIVE, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROAGGRESSIVE);
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityAGGRESSIVE;
+ heroAnimIdxAGGRESSIVE = _engine->_animations->getBodyAnimIndex(0, 0);
- hqrGetallocEntry(&heroEntityDISCRETE, HQR_FILE3D_FILE, FILE3DHQR_HERODISCRETE);
- sceneHero->entityDataPtr = heroEntityDISCRETE;
- heroAnimIdxDISCRETE = getBodyAnimIndex(0, 0);
+ _engine->_hqrdepack->hqrGetallocEntry(&heroEntityDISCRETE, Resources::HQR_FILE3D_FILE, FILE3DHQR_HERODISCRETE);
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityDISCRETE;
+ heroAnimIdxDISCRETE = _engine->_animations->getBodyAnimIndex(0, 0);
- hqrGetallocEntry(&heroEntityPROTOPACK, HQR_FILE3D_FILE, FILE3DHQR_HEROPROTOPACK);
- sceneHero->entityDataPtr = heroEntityPROTOPACK;
- heroAnimIdxPROTOPACK = getBodyAnimIndex(0, 0);
+ _engine->_hqrdepack->hqrGetallocEntry(&heroEntityPROTOPACK, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROPROTOPACK);
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityPROTOPACK;
+ heroAnimIdxPROTOPACK = _engine->_animations->getBodyAnimIndex(0, 0);
- hqrGetallocEntry(&heroEntityNORMAL, HQR_FILE3D_FILE, FILE3DHQR_HERONORMAL);
- sceneHero->entityDataPtr = heroEntityNORMAL;
- heroAnimIdxNORMAL = getBodyAnimIndex(0, 0);
+ _engine->_hqrdepack->hqrGetallocEntry(&heroEntityNORMAL, Resources::HQR_FILE3D_FILE, FILE3DHQR_HERONORMAL);
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityNORMAL;
+ heroAnimIdxNORMAL = _engine->_animations->getBodyAnimIndex(0, 0);
- sceneHero->animExtraPtr = currentActorAnimExtraPtr;
+ _engine->_scene->sceneHero->animExtraPtr = _engine->_animations->currentActorAnimExtraPtr;
}
-/** Set hero behaviour
- @param behaviour behaviour value to set */
-void setBehaviour(int32 behaviour) {
- int32 bodyIdx;
-
+void Actor::setBehaviour(int32 behaviour) {
switch (behaviour) {
case kNormal:
heroBehaviour = kNormal;
- sceneHero->entityDataPtr = heroEntityNORMAL;
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityNORMAL;
break;
case kAthletic:
heroBehaviour = kAthletic;
- sceneHero->entityDataPtr = heroEntityATHLETIC;
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityATHLETIC;
break;
case kAggressive:
heroBehaviour = kAggressive;
- sceneHero->entityDataPtr = heroEntityAGGRESSIVE;
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityAGGRESSIVE;
break;
case kDiscrete:
heroBehaviour = kDiscrete;
- sceneHero->entityDataPtr = heroEntityDISCRETE;
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityDISCRETE;
break;
case kProtoPack:
heroBehaviour = kProtoPack;
- sceneHero->entityDataPtr = heroEntityPROTOPACK;
+ _engine->_scene->sceneHero->entityDataPtr = heroEntityPROTOPACK;
break;
};
- bodyIdx = sceneHero->body;
+ const int32 bodyIdx = _engine->_scene->sceneHero->body;
- sceneHero->entity = -1;
- sceneHero->body = -1;
+ _engine->_scene->sceneHero->entity = -1;
+ _engine->_scene->sceneHero->body = -1;
initModelActor(bodyIdx, 0);
- sceneHero->anim = -1;
- sceneHero->animType = 0;
+ _engine->_scene->sceneHero->anim = kAnimNone;
+ _engine->_scene->sceneHero->animType = 0;
- initAnim(kStanding, 0, 255, 0);
+ _engine->_animations->initAnim(kStanding, 0, 255, 0);
}
-/** Initialize sprite actor
- @param actorIdx sprite actor index */
-void initSpriteActor(int32 actorIdx) {
- ActorStruct *localActor = &sceneActors[actorIdx];
+void Actor::initSpriteActor(int32 actorIdx) {
+ ActorStruct *localActor = &_engine->_scene->sceneActors[actorIdx];
if (localActor->staticFlags.bIsSpriteActor && localActor->sprite != -1 && localActor->entity != localActor->sprite) {
- int16 *ptr = (int16 *)(spriteBoundingBoxPtr + localActor->sprite * 16 + 4);
+ const int16 *ptr = (const int16 *)(_engine->_scene->spriteBoundingBoxPtr + localActor->sprite * 16 + 4);
localActor->entity = localActor->sprite;
- localActor->boudingBox.X.bottomLeft = *(ptr++);
- localActor->boudingBox.X.topRight = *(ptr++);
- localActor->boudingBox.Y.bottomLeft = *(ptr++);
- localActor->boudingBox.Y.topRight = *(ptr++);
- localActor->boudingBox.Z.bottomLeft = *(ptr++);
- localActor->boudingBox.Z.topRight = *(ptr++);
+ localActor->boudingBox.x.bottomLeft = *(ptr++);
+ localActor->boudingBox.x.topRight = *(ptr++);
+ localActor->boudingBox.y.bottomLeft = *(ptr++);
+ localActor->boudingBox.y.topRight = *(ptr++);
+ localActor->boudingBox.z.bottomLeft = *(ptr++);
+ localActor->boudingBox.z.topRight = *(ptr++);
}
}
-/** Initialize 3D actor body
- @param bodyIdx 3D actor body index
- @param actorIdx 3D actor index */
-int32 initBody(int32 bodyIdx, int32 actorIdx) {
- ActorStruct *localActor;
- uint8 *bodyPtr;
- uint8 var1;
- uint8 var2;
- uint8 *bodyPtr2;
- uint8 *bodyPtr3;
- uint8 *bodyPtr4;
-// int16 *bodyPtr5;
- int16 flag;
- int32 index;
-
- localActor = &sceneActors[actorIdx];
- bodyPtr = localActor->entityDataPtr;
+int32 Actor::initBody(int32 bodyIdx, int32 actorIdx) {
+ ActorStruct *localActor = &_engine->_scene->sceneActors[actorIdx];
+ uint8 *bodyPtr = localActor->entityDataPtr;
do {
- var1 = *(bodyPtr++);
+ uint8 var1 = *(bodyPtr++);
- if (var1 == 0xFF)
- return (-1);
+ if (var1 == 0xFF) {
+ return -1;
+ }
- bodyPtr2 = bodyPtr + 1;
+ uint8 *bodyPtr2 = bodyPtr + 1;
if (var1 == 1) {
- var2 = *(bodyPtr);
+ uint8 var2 = *(bodyPtr);
if (var2 == bodyIdx) {
- bodyPtr3 = bodyPtr2 + 1;
- flag = *((uint16*)bodyPtr3);
+ int32 index;
+ uint8 *bodyPtr3 = bodyPtr2 + 1;
+ int16 flag = *((uint16 *)bodyPtr3);
if (!(flag & 0x8000)) {
- hqrGetallocEntry(&bodyTable[currentPositionInBodyPtrTab], HQR_BODY_FILE, flag & 0xFFFF);
+ _engine->_hqrdepack->hqrGetallocEntry(&bodyTable[currentPositionInBodyPtrTab], Resources::HQR_BODY_FILE, flag & 0xFFFF);
if (!bodyTable[currentPositionInBodyPtrTab]) {
- printf("HQR ERROR: Loading body entities\n");
- exit(1);
+ error("HQR ERROR: Loading body entities");
}
- prepareIsoModel(bodyTable[currentPositionInBodyPtrTab]);
- *((uint16*)bodyPtr3) = currentPositionInBodyPtrTab + 0x8000;
+ _engine->_renderer->prepareIsoModel(bodyTable[currentPositionInBodyPtrTab]);
+ *((uint16 *)bodyPtr3) = currentPositionInBodyPtrTab + 0x8000;
index = currentPositionInBodyPtrTab;
currentPositionInBodyPtrTab++;
} else {
@@ -205,35 +181,37 @@ int32 initBody(int32 bodyIdx, int32 actorIdx) {
bodyPtr3 += 2;
bottomLeftX = -32000;
- bodyPtr4 = bodyPtr3;
+ uint8 *bodyPtr4 = bodyPtr3;
bodyPtr3++;
- if (!*bodyPtr4)
- return (index);
+ if (!*bodyPtr4) {
+ return index;
+ }
bodyPtr4 = bodyPtr3;
bodyPtr3++;
- if (*bodyPtr4 != 14)
- return (index);
+ if (*bodyPtr4 != 14) {
+ return index;
+ }
-// bodyPtr5 = (int16 *) bodyPtr3;
+ // bodyPtr5 = (int16 *) bodyPtr3;
- bottomLeftX = *((uint16*)bodyPtr3);
+ bottomLeftX = *((uint16 *)bodyPtr3);
bodyPtr3 += 2;
- bottomLeftY = *((uint16*)bodyPtr3);
+ bottomLeftY = *((uint16 *)bodyPtr3);
bodyPtr3 += 2;
- bottomLeftZ = *((uint16*)bodyPtr3);
+ bottomLeftZ = *((uint16 *)bodyPtr3);
bodyPtr3 += 2;
- topRightX = *((uint16*)bodyPtr3);
+ topRightX = *((uint16 *)bodyPtr3);
bodyPtr3 += 2;
- topRightY = *((uint16*)bodyPtr3);
+ topRightY = *((uint16 *)bodyPtr3);
bodyPtr3 += 2;
- topRightZ = *((uint16*)bodyPtr3);
+ topRightZ = *((uint16 *)bodyPtr3);
bodyPtr3 += 2;
- return (index);
+ return index;
}
}
@@ -241,29 +219,17 @@ int32 initBody(int32 bodyIdx, int32 actorIdx) {
} while (1);
}
-/** Initialize 3D actor
- @param bodyIdx 3D actor body index
- @param actorIdx 3D actor index */
-void initModelActor(int32 bodyIdx, int16 actorIdx) {
- ActorStruct *localActor;
- int32 entityIdx;
- int currentIndex;
- uint16 *ptr;
- int16 var1, var2, var3, var4;
-
- int32 result, result1, result2;
-
- result = 0;
-
- localActor = &sceneActors[actorIdx];
-
- if (localActor->staticFlags.bIsSpriteActor)
+void Actor::initModelActor(int32 bodyIdx, int16 actorIdx) {
+ ActorStruct *localActor = &_engine->_scene->sceneActors[actorIdx];
+ if (localActor->staticFlags.bIsSpriteActor) {
return;
+ }
if (actorIdx == 0 && heroBehaviour == kProtoPack && localActor->armor != 0 && localActor->armor != 1) { // if hero
setBehaviour(kNormal);
}
+ int32 entityIdx;
if (bodyIdx != -1) {
entityIdx = initBody(bodyIdx, actorIdx);
} else {
@@ -271,55 +237,54 @@ void initModelActor(int32 bodyIdx, int16 actorIdx) {
}
if (entityIdx != -1) {
- if (localActor->entity == entityIdx)
+ if (localActor->entity == entityIdx) {
return;
+ }
localActor->entity = entityIdx;
localActor->body = bodyIdx;
- currentIndex = localActor->entity;
+ int currentIndex = localActor->entity;
if (bottomLeftX == -32000) {
- ptr = (uint16 *) bodyTable[localActor->entity];
+ uint16 *ptr = (uint16 *)bodyTable[localActor->entity];
ptr++;
- var1 = *((int16 *)ptr++);
- var2 = *((int16 *)ptr++);
- localActor->boudingBox.Y.bottomLeft = *((int16 *)ptr++);
- localActor->boudingBox.Y.topRight = *((int16 *)ptr++);
- var3 = *((int16 *)ptr++);
- var4 = *((int16 *)ptr++);
+ int16 var1 = *((int16 *)ptr++);
+ int16 var2 = *((int16 *)ptr++);
+ localActor->boudingBox.y.bottomLeft = *((int16 *)ptr++);
+ localActor->boudingBox.y.topRight = *((int16 *)ptr++);
+ int16 var3 = *((int16 *)ptr++);
+ int16 var4 = *((int16 *)ptr++);
+ int32 result = 0;
if (localActor->staticFlags.bUseMiniZv) {
- result1 = var2 - var1; // take smaller for bound
- result2 = var4 - var3;
+ int32 result1 = var2 - var1; // take smaller for bound
+ int32 result2 = var4 - var3;
- if (result1 < result2)
- result = result1;
- else
- result = result2;
+ result = MIN(result1, result2);
- result = abs(result);
+ result = ABS(result);
result >>= 1;
} else {
- result1 = var2 - var1; // take average for bound
- result2 = var4 - var3;
+ int32 result1 = var2 - var1; // take average for bound
+ int32 result2 = var4 - var3;
result = result2 + result1;
- result = abs(result);
+ result = ABS(result);
result >>= 2;
}
- localActor->boudingBox.X.bottomLeft = -result;
- localActor->boudingBox.X.topRight = result;
- localActor->boudingBox.Z.bottomLeft = -result;
- localActor->boudingBox.Z.topRight = result;
+ localActor->boudingBox.x.bottomLeft = -result;
+ localActor->boudingBox.x.topRight = result;
+ localActor->boudingBox.z.bottomLeft = -result;
+ localActor->boudingBox.z.topRight = result;
} else {
- localActor->boudingBox.X.bottomLeft = bottomLeftX;
- localActor->boudingBox.X.topRight = topRightX;
- localActor->boudingBox.Y.bottomLeft = bottomLeftY;
- localActor->boudingBox.Y.topRight = topRightY;
- localActor->boudingBox.Z.bottomLeft = bottomLeftZ;
- localActor->boudingBox.Z.topRight = topRightZ;
+ localActor->boudingBox.x.bottomLeft = bottomLeftX;
+ localActor->boudingBox.x.topRight = topRightX;
+ localActor->boudingBox.y.bottomLeft = bottomLeftY;
+ localActor->boudingBox.y.topRight = topRightY;
+ localActor->boudingBox.z.bottomLeft = bottomLeftZ;
+ localActor->boudingBox.z.topRight = topRightZ;
}
if (currentIndex == -1)
@@ -328,7 +293,7 @@ void initModelActor(int32 bodyIdx, int16 actorIdx) {
if (localActor->previousAnimIdx == -1)
return;
- copyActorInternAnim(bodyTable[currentIndex], bodyTable[localActor->entity]);
+ _engine->_renderer->copyActorInternAnim(bodyTable[currentIndex], bodyTable[localActor->entity]);
return;
}
@@ -336,18 +301,16 @@ void initModelActor(int32 bodyIdx, int16 actorIdx) {
localActor->body = -1;
localActor->entity = -1;
- localActor->boudingBox.X.bottomLeft = 0;
- localActor->boudingBox.X.topRight = 0;
- localActor->boudingBox.Y.bottomLeft = 0;
- localActor->boudingBox.Y.topRight = 0;
- localActor->boudingBox.Z.bottomLeft = 0;
- localActor->boudingBox.Z.topRight = 0;
+ localActor->boudingBox.x.bottomLeft = 0;
+ localActor->boudingBox.x.topRight = 0;
+ localActor->boudingBox.y.bottomLeft = 0;
+ localActor->boudingBox.y.topRight = 0;
+ localActor->boudingBox.z.bottomLeft = 0;
+ localActor->boudingBox.z.topRight = 0;
}
-/** Initialize actors
- @param actorIdx actor index to init */
-void initActor(int16 actorIdx) {
- ActorStruct *actor = &sceneActors[actorIdx];
+void Actor::initActor(int16 actorIdx) {
+ ActorStruct *actor = &_engine->_scene->sceneActors[actorIdx];
if (actor->staticFlags.bIsSpriteActor) { // if sprite actor
if (actor->strengthOfHit != 0) {
@@ -358,14 +321,13 @@ void initActor(int16 actorIdx) {
initSpriteActor(actorIdx);
- setActorAngleSafe(0, 0, 0, &actor->move);
+ _engine->_movements->setActorAngleSafe(0, 0, 0, &actor->move);
if (actor->staticFlags.bUsesClipping) {
- actor->lastX = actor->X;
- actor->lastY = actor->Y;
- actor->lastZ = actor->Z;
+ actor->lastX = actor->x;
+ actor->lastY = actor->y;
+ actor->lastZ = actor->z;
}
-
} else {
actor->entity = -1;
@@ -375,10 +337,10 @@ void initActor(int16 actorIdx) {
actor->animType = 0;
if (actor->entity != -1) {
- initAnim(actor->anim, 0, 255, actorIdx);
+ _engine->_animations->initAnim(actor->anim, 0, 255, actorIdx);
}
- setActorAngleSafe(actor->angle, actor->angle, 0, &actor->move);
+ _engine->_movements->setActorAngleSafe(actor->angle, actor->angle, 0, &actor->move);
}
actor->positionInMoveScript = -1;
@@ -386,23 +348,21 @@ void initActor(int16 actorIdx) {
actor->positionInLifeScript = 0;
}
-/** Reset actor
- @param actorIdx actor index to init */
-void resetActor(int16 actorIdx) {
- ActorStruct *actor = &sceneActors[actorIdx];
+void Actor::resetActor(int16 actorIdx) {
+ ActorStruct *actor = &_engine->_scene->sceneActors[actorIdx];
actor->body = 0;
- actor->anim = 0;
- actor->X = 0;
- actor->Y = -1;
- actor->Z = 0;
-
- actor->boudingBox.X.bottomLeft = 0;
- actor->boudingBox.X.topRight = 0;
- actor->boudingBox.Y.bottomLeft = 0;
- actor->boudingBox.Y.topRight = 0;
- actor->boudingBox.Z.bottomLeft = 0;
- actor->boudingBox.Z.topRight = 0;
+ actor->anim = kStanding;
+ actor->x = 0;
+ actor->y = -1;
+ actor->z = 0;
+
+ actor->boudingBox.x.bottomLeft = 0;
+ actor->boudingBox.x.topRight = 0;
+ actor->boudingBox.y.bottomLeft = 0;
+ actor->boudingBox.y.topRight = 0;
+ actor->boudingBox.z.bottomLeft = 0;
+ actor->boudingBox.z.topRight = 0;
actor->angle = 0;
actor->speed = 40;
@@ -418,8 +378,8 @@ void resetActor(int16 actorIdx) {
actor->standOn = -1;
actor->zone = -1;
- memset(&actor->staticFlags,0,2);
- memset(&actor->dynamicFlags,0,2);
+ memset(&actor->staticFlags, 0, sizeof(StaticFlagsStruct));
+ memset(&actor->dynamicFlags, 0, sizeof(DynamicFlagsStruct));
actor->life = 50;
actor->armor = 1;
@@ -433,19 +393,14 @@ void resetActor(int16 actorIdx) {
actor->animType = 0;
actor->animPosition = 0;
- setActorAngleSafe(0, 0, 0, &actor->move);
+ _engine->_movements->setActorAngleSafe(0, 0, 0, &actor->move);
actor->positionInMoveScript = -1;
actor->positionInLifeScript = 0;
}
-/** Process hit actor
- @param actorIdx actor hitting index
- @param actorIdxAttacked actor attacked index
- @param strengthOfHit actor hitting strength of hit
- @param angle angle of actor hitting */
-void hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32 angle) {
- ActorStruct *actor = &sceneActors[actorIdxAttacked];
+void Actor::hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32 angle) {
+ ActorStruct *actor = &_engine->_scene->sceneActors[actorIdxAttacked];
if (actor->life <= 0) {
return;
@@ -455,29 +410,28 @@ void hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32
if (actor->armor <= strengthOfHit) {
if (actor->anim == kBigHit || actor->anim == kHit2) {
- int32 tmpAnimPos;
- tmpAnimPos = actor->animPosition;
+ const int32 tmpAnimPos = actor->animPosition;
if (actor->animExtra) {
- processAnimActions(actorIdxAttacked);
+ _engine->_animations->processAnimActions(actorIdxAttacked);
}
actor->animPosition = tmpAnimPos;
} else {
if (angle != -1) {
- setActorAngleSafe(angle, angle, 0, &actor->move);
+ _engine->_movements->setActorAngleSafe(angle, angle, 0, &actor->move);
}
- if (rand() & 1) {
- initAnim(kHit2, 3, 255, actorIdxAttacked);
+ if (_engine->getRandomNumber() & 1) {
+ _engine->_animations->initAnim(kHit2, 3, 255, actorIdxAttacked);
} else {
- initAnim(kBigHit, 3, 255, actorIdxAttacked);
+ _engine->_animations->initAnim(kBigHit, 3, 255, actorIdxAttacked);
}
}
- addExtraSpecial(actor->X, actor->Y + 1000, actor->Z, kHitStars);
+ _engine->_extra->addExtraSpecial(actor->x, actor->y + 1000, actor->z, kHitStars);
if (!actorIdxAttacked) {
- heroMoved = 1;
+ _engine->_movements->heroMoved = 1;
}
actor->life -= strengthOfHit;
@@ -486,55 +440,55 @@ void hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32
actor->life = 0;
}
} else {
- initAnim(kHit, 3, 255, actorIdxAttacked);
+ _engine->_animations->initAnim(kHit, 3, 255, actorIdxAttacked);
}
}
-/** Process actor carrier */
-void processActorCarrier(int32 actorIdx) { // CheckCarrier
- int32 a;
- ActorStruct *actor = &sceneActors[actorIdx];
-
- if (actor->staticFlags.bIsCarrierActor) {
- for (a = 0; a < sceneNumActors; a++) {
- if (actor->standOn == actorIdx) {
- actor->standOn = -1;
- }
+void Actor::processActorCarrier(int32 actorIdx) { // CheckCarrier
+ ActorStruct *actor = &_engine->_scene->sceneActors[actorIdx];
+ if (!actor->staticFlags.bIsCarrierActor) {
+ return;
+ }
+ for (int32 a = 0; a < _engine->_scene->sceneNumActors; a++) {
+ if (actor->standOn == actorIdx) {
+ actor->standOn = -1;
}
}
}
-/** Process actor extra bonus */
-void processActorExtraBonus(int32 actorIdx) { // GiveExtraBonus
- int32 a, numBonus;
- int8 bonusTable[8], currentBonus;
- ActorStruct *actor = &sceneActors[actorIdx];
+void Actor::processActorExtraBonus(int32 actorIdx) { // GiveExtraBonus
+ ActorStruct *actor = &_engine->_scene->sceneActors[actorIdx];
- numBonus = 0;
+ int32 numBonus = 0;
- for (a = 0; a < 5; a++) {
+ int8 bonusTable[8];
+ for (int32 a = 0; a < 5; a++) {
if (actor->bonusParameter & (1 << (a + 4))) {
bonusTable[numBonus++] = a;
}
}
- if (numBonus) {
- currentBonus = bonusTable[Rnd(numBonus)];
- // if bonus is magic an no magic level yet, then give life points
- if (!magicLevelIdx && currentBonus == 2) {
- currentBonus = 1;
- }
- currentBonus += 3;
+ if (numBonus == 0) {
+ return;
+ }
- if (actor->dynamicFlags.bIsDead) {
- addExtraBonus(actor->X, actor->Y, actor->Z, 0x100, 0, currentBonus, actor->bonusAmount);
- // FIXME add constant for sample index
- playSample(11, 0x1000, 1, actor->X, actor->Y, actor->Z, actorIdx);
- } else {
- int32 angle = getAngleAndSetTargetActorDistance(actor->X, actor->Z, sceneHero->X, sceneHero->Z);
- addExtraBonus(actor->X, actor->Y + actor->boudingBox.Y.topRight, actor->Z, 200, angle, currentBonus, actor->bonusAmount);
- // FIXME add constant for sample index
- playSample(11, 0x1000, 1, actor->X, actor->Y + actor->boudingBox.Y.topRight, actor->Z, actorIdx);
- }
+ int8 currentBonus = bonusTable[_engine->getRandomNumber(numBonus)];
+ // if bonus is magic an no magic level yet, then give life points
+ if (!_engine->_gameState->magicLevelIdx && currentBonus == 2) {
+ currentBonus = 1;
+ }
+ currentBonus += 3;
+
+ if (actor->dynamicFlags.bIsDead) {
+ _engine->_extra->addExtraBonus(actor->x, actor->y, actor->z, 0x100, 0, currentBonus, actor->bonusAmount);
+ // FIXME add constant for sample index
+ _engine->_sound->playSample(11, 0x1000, 1, actor->x, actor->y, actor->z, actorIdx);
+ } else {
+ int32 angle = _engine->_movements->getAngleAndSetTargetActorDistance(actor->x, actor->z, _engine->_scene->sceneHero->x, _engine->_scene->sceneHero->z);
+ _engine->_extra->addExtraBonus(actor->x, actor->y + actor->boudingBox.y.topRight, actor->z, 200, angle, currentBonus, actor->bonusAmount);
+ // FIXME add constant for sample index
+ _engine->_sound->playSample(11, 0x1000, 1, actor->x, actor->y + actor->boudingBox.y.topRight, actor->z, actorIdx);
}
}
+
+} // namespace TwinE
diff --git a/engines/twine/actor.h b/engines/twine/actor.h
index d3cd776009..18dfa67992 100644
--- a/engines/twine/actor.h
+++ b/engines/twine/actor.h
@@ -1,32 +1,31 @@
-/** @file actor.h
- @brief
- This file contains scene actor routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef ACTOR_H
-#define ACTOR_H
-
-#include "sys.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_ACTOR_H
+#define TWINE_ACTOR_H
+
+#include "common/scummsys.h"
+
+namespace TwinE {
/** Total number of sprites allowed in the game */
#define NUM_SPRITES 200
@@ -34,85 +33,118 @@
/** Total number of bodies allowed in the game */
#define NUM_BODIES 200
+/** Hero behaviour
+ * <li> NORMAL: Talk / Read / Search / Use
+ * <li> ATHLETIC: Jump
+ * <li> AGGRESSIVE:
+ * Auto mode : Fight
+ * Manual mode : While holding the spacebar down
+ * UP / RIGHT / LEFT will manually select
+ * different punch/kick options
+ * <li> DISCREET: Kneel down to hide
+ */
enum HeroBehaviourType {
- kNormal = 0,
- kAthletic = 1,
+ kNormal = 0,
+ kAthletic = 1,
kAggressive = 2,
- kDiscrete = 3,
- kProtoPack = 4
+ kDiscrete = 3,
+ kProtoPack = 4
};
-
-/** Table with all loaded sprites */
-uint8* spriteTable[NUM_SPRITES];
-/** Table with all loaded sprite sizes */
-uint32 spriteSizeTable[NUM_SPRITES];
-
/** Actors move structure */
typedef struct ActorMoveStruct {
- int16 from;
- int16 to;
- int16 numOfStep;
- int32 timeOfChange;
+ int16 from = 0;
+ int16 to = 0;
+ int16 numOfStep = 0;
+ int32 timeOfChange = 0;
} ActorMoveStruct;
/** Actors zone volumique points structure */
typedef struct ZVPoint {
- int16 bottomLeft;
- int16 topRight;
+ int16 bottomLeft = 0;
+ int16 topRight = 0;
} ZVPoint;
/** Actors zone volumique box structure */
typedef struct ZVBox {
- ZVPoint X;
- ZVPoint Y;
- ZVPoint Z;
+ ZVPoint x;
+ ZVPoint y;
+ ZVPoint z;
} ZVBox;
/** Actors animation timer structure */
typedef struct AnimTimerDataStruct {
- uint8* ptr;
- int32 time;
+ uint8 *ptr = nullptr;
+ int32 time = 0;
} AnimTimerDataStruct;
+enum AnimationTypes {
+ kAnimNone = -1,
+ kStanding = 0,
+ kForward = 1,
+ kBackward = 2,
+ kTurnLeft = 3,
+ kTurnRight = 4,
+ kHit = 5,
+ kBigHit = 6,
+ kFall = 7,
+ kLanding = 8,
+ kLandingHit = 9,
+ kLandDeath = 10,
+ kAction = 11,
+ kClimbLadder = 12,
+ kTopLadder = 13,
+ kJump = 14,
+ kThrowBall = 15,
+ kHide = 16,
+ kKick = 17,
+ kRightPunch = 18,
+ kLeftPunch = 19,
+ kFoundItem = 20,
+ kDrawn = 21,
+ kHit2 = 22,
+ kSabreAttack = 23,
+ kSabreUnknown = 24,
+};
+
/** Actors static flags structure */
typedef struct StaticFlagsStruct {
- uint16 bComputeCollisionWithObj : 1; // 0x0001
- uint16 bComputeCollisionWithBricks : 1; // 0x0002
- uint16 bIsZonable : 1; // 0x0004
- uint16 bUsesClipping : 1; // 0x0008
- uint16 bCanBePushed : 1; // 0x0010
- uint16 bComputeLowCollision : 1; // 0x0020
- uint16 bCanDrown : 1; // 0x0040
- uint16 bUnk80 : 1; // 0x0080
- uint16 bUnk0100 : 1; // 0x0100
- uint16 bIsHidden : 1; // 0x0200
- uint16 bIsSpriteActor : 1; // 0x0400
- uint16 bCanFall : 1; // 0x0800
- uint16 bDoesntCastShadow : 1; // 0x1000
- uint16 bIsBackgrounded : 1; // 0x2000
- uint16 bIsCarrierActor : 1; // 0x4000
- uint16 bUseMiniZv : 1; // 0x8000
+ uint16 bComputeCollisionWithObj : 1; // 0x0001
+ uint16 bComputeCollisionWithBricks : 1; // 0x0002
+ uint16 bIsZonable : 1; // 0x0004
+ uint16 bUsesClipping : 1; // 0x0008
+ uint16 bCanBePushed : 1; // 0x0010
+ uint16 bComputeLowCollision : 1; // 0x0020
+ uint16 bCanDrown : 1; // 0x0040
+ uint16 bUnk80 : 1; // 0x0080
+ uint16 bUnk0100 : 1; // 0x0100
+ uint16 bIsHidden : 1; // 0x0200
+ uint16 bIsSpriteActor : 1; // 0x0400
+ uint16 bCanFall : 1; // 0x0800
+ uint16 bDoesntCastShadow : 1; // 0x1000
+ uint16 bIsBackgrounded : 1; // 0x2000
+ uint16 bIsCarrierActor : 1; // 0x4000
+ uint16 bUseMiniZv : 1; // 0x8000
} StaticFlagsStruct;
/** Actors dynamic flags structure */
typedef struct DynamicFlagsStruct {
- uint16 bWaitHitFrame : 1; // 0x0001 wait for hit frame
- uint16 bIsHitting : 1; // 0x0002 hit frame anim
- uint16 bAnimEnded : 1; // 0x0004 anim ended in the current loop (will be looped in the next engine loop)
- uint16 bAnimFrameReached : 1; // 0x0008 new frame anim reached
- uint16 bIsVisible : 1; // 0x0010 actor has been drawn in this loop
- uint16 bIsDead : 1; // 0x0020 is dead
- uint16 bIsSpriteMoving : 1; // 0x0040 door is opening or closing (wait to reach the destination position)
- uint16 bIsRotationByAnim : 1; // 0x0080 actor rotation is managed by its animaation not by the engine
- uint16 bIsFalling : 1; // 0x0100 is falling on scene
- uint16 bUnk0200 : 1; // 0x0200 unused
- uint16 bUnk0400 : 1; // 0x0400 unused
- uint16 bUnk0800 : 1; // 0x0800 unused
- uint16 bUnk1000 : 1; // 0x1000 unused
- uint16 bUnk2000 : 1; // 0x2000 unused
- uint16 bUnk4000 : 1; // 0x4000 unused
- uint16 bUnk8000 : 1; // 0x8000 unused
+ uint16 bWaitHitFrame : 1; // 0x0001 wait for hit frame
+ uint16 bIsHitting : 1; // 0x0002 hit frame anim
+ uint16 bAnimEnded : 1; // 0x0004 anim ended in the current loop (will be looped in the next engine loop)
+ uint16 bAnimFrameReached : 1; // 0x0008 new frame anim reached
+ uint16 bIsVisible : 1; // 0x0010 actor has been drawn in this loop
+ uint16 bIsDead : 1; // 0x0020 is dead
+ uint16 bIsSpriteMoving : 1; // 0x0040 door is opening or closing (wait to reach the destination position)
+ uint16 bIsRotationByAnim : 1; // 0x0080 actor rotation is managed by its animaation not by the engine
+ uint16 bIsFalling : 1; // 0x0100 is falling on scene
+ uint16 bUnk0200 : 1; // 0x0200 unused
+ uint16 bUnk0400 : 1; // 0x0400 unused
+ uint16 bUnk0800 : 1; // 0x0800 unused
+ uint16 bUnk1000 : 1; // 0x1000 unused
+ uint16 bUnk2000 : 1; // 0x2000 unused
+ uint16 bUnk4000 : 1; // 0x4000 unused
+ uint16 bUnk8000 : 1; // 0x8000 unused
} DynamicFlagsStruct;
/** Actors structure */
@@ -120,175 +152,191 @@ typedef struct ActorStruct {
StaticFlagsStruct staticFlags;
DynamicFlagsStruct dynamicFlags;
- int32 entity; // costumeIndex
- int32 body;
- int32 anim;
- int32 animExtra; //field_2
- int32 brickShape; // field_3
- uint8 *animExtraPtr;
- int32 sprite; // field_8
- uint8 *entityDataPtr;
-
- int32 X;
- int32 Y;
- int32 Z;
- int32 strengthOfHit; // field_66
- int32 hitBy;
- int32 bonusParameter; // field_10
- int32 angle;
- int32 speed;
- int32 controlMode;
- int32 info0; // cropLeft
- int32 info1; // cropTop
- int32 info2; // cropRight
- int32 info3; // cropBottom
- int32 followedActor; // same as info3
- int32 bonusAmount; // field_12
- int32 talkColor;
- int32 armor; // field_14
- int32 life;
-
- int32 collisionX; // field_20
- int32 collisionY; // field_22
- int32 collisionZ; // field_24
-
- int32 positionInMoveScript;
- uint8 *moveScript;
-
- int32 positionInLifeScript;
- uint8 *lifeScript;
-
- int32 labelIdx; // script label index
- int32 currentLabelPtr; // pointer to LABEL offset
- int32 pausedTrackPtr;
+ int32 entity = 0; // costumeIndex
+ int32 body = 0;
+ AnimationTypes anim = kAnimNone;
+ int32 animExtra = 0; //field_2
+ int32 brickShape = 0; // field_3
+ uint8 *animExtraPtr = nullptr;
+ int32 sprite = 0; // field_8
+ uint8 *entityDataPtr = nullptr;
+
+ int32 x = 0;
+ int32 y = 0;
+ int32 z = 0;
+ int32 strengthOfHit = 0; // field_66
+ int32 hitBy = 0;
+ int32 bonusParameter = 0; // field_10
+ int32 angle = 0;
+ int32 speed = 0;
+ int32 controlMode = 0;
+ int32 info0 = 0; // cropLeft
+ int32 info1 = 0; // cropTop
+ int32 info2 = 0; // cropRight
+ int32 info3 = 0; // cropBottom
+ int32 followedActor = 0; // same as info3
+ int32 bonusAmount = 0; // field_12
+ int32 talkColor = 0;
+ int32 armor = 0; // field_14
+ int32 life = 0;
+
+ int32 collisionX = 0; // field_20
+ int32 collisionY = 0; // field_22
+ int32 collisionZ = 0; // field_24
+
+ int32 positionInMoveScript = 0;
+ uint8 *moveScript = nullptr;
+
+ int32 positionInLifeScript = 0;
+ uint8 *lifeScript = nullptr;
+
+ int32 labelIdx = 0; // script label index
+ int32 currentLabelPtr = 0; // pointer to LABEL offset
+ int32 pausedTrackPtr = 0;
//int costumeIndex;
- int32 collision;
- int32 standPosition;
- int32 standOn;
- int32 zone;
-
- int32 lastRotationAngle;
- int32 lastX;
- int32 lastZ;
- int32 lastY;
- int32 previousAnimIdx;
- int32 doorStatus;
- int32 animPosition;
- int32 animType; // field_78
- int32 brickSound; // field_7A
+ int32 collision = 0;
+ int32 standPosition = 0;
+ int32 standOn = 0;
+ int32 zone = 0;
+
+ int32 lastRotationAngle = 0;
+ int32 lastX = 0;
+ int32 lastZ = 0;
+ int32 lastY = 0;
+ int32 previousAnimIdx = 0;
+ int32 doorStatus = 0;
+ int32 animPosition = 0;
+ int32 animType = 0; // field_78
+ int32 brickSound = 0; // field_7A
ZVBox boudingBox;
ActorMoveStruct move;
AnimTimerDataStruct animTimerData;
} ActorStruct;
-/** Actor shadow X coordinate */
-int32 shadowX;
-/** Actor shadow Y coordinate */
-int32 shadowY;
-/** Actor shadow Z coordinate */
-int32 shadowZ;
-/** Actor shadow collition type */
-int8 shadowCollisionType; // shadowVar
-
-/** Hero behaviour */
-int16 heroBehaviour;
-/** Hero auto agressive mode */
-int16 autoAgressive;
-/** Previous Hero behaviour */
-int16 previousHeroBehaviour;
-/** Previous Hero angle */
-int16 previousHeroAngle;
-
-int16 cropBottomScreen;
-
-/** Hero 3D entity for normal behaviour */
-uint8 *heroEntityNORMAL; // file3D0
-/** Hero 3D entity for athletic behaviour */
-uint8 *heroEntityATHLETIC; // file3D1
-/** Hero 3D entity for aggressive behaviour */
-uint8 *heroEntityAGGRESSIVE; // file3D2
-/** Hero 3D entity for discrete behaviour */
-uint8 *heroEntityDISCRETE; // file3D3
-/** Hero 3D entity for protopack behaviour */
-uint8 *heroEntityPROTOPACK; // file3D4
-
-/** Hero current anim for normal behaviour */
-int16 heroAnimIdxNORMAL; // TCos0Init
-/** Hero current anim for athletic behaviour */
-int16 heroAnimIdxATHLETIC; // TCos1Init
-/** Hero current anim for aggressive behaviour */
-int16 heroAnimIdxAGGRESSIVE; // TCos2Init
-/** Hero current anim for discrete behaviour */
-int16 heroAnimIdxDISCRETE; // TCos3Init
-/** Hero current anim for protopack behaviour */
-int16 heroAnimIdxPROTOPACK; // TCos4Init
-
-/** Hero anim for behaviour menu */
-int16 heroAnimIdx[4]; // TCOS
-
-/** Actors 3D body table - size of NUM_BODIES */
-extern uint8 *bodyTable[NUM_BODIES];
-
-/** Current position in body table */
-int32 currentPositionInBodyPtrTab;
-
-/** Actor bounding box bottom left X coordinate */
-int16 bottomLeftX; // loadCostumeVar
-/** Actor bounding box bottom left Y coordinate */
-int16 bottomLeftY; // loadCostumeVar2
-/** Actor bounding box bottom left Z coordinate */
-int16 bottomLeftZ; // loadCostumeVar3
-/** Actor bounding box top left X coordinate */
-int16 topRightX; // loadCostumeVar4
-/** Actor bounding box top left Y coordinate */
-int16 topRightY; // loadCostumeVar5
-/** Actor bounding box top left Z coordinate */
-int16 topRightZ; // loadCostumeVar6
-
-/** Restart hero variables while opening new scenes */
-void restartHeroScene();
-
-/** Load hero 3D body and animations */
-void loadHeroEntities();
-
-/** Set hero behaviour
+class TwinEEngine;
+
+class Actor {
+private:
+ TwinEEngine* _engine;
+
+ void initSpriteActor(int32 actorIdx);
+public:
+ Actor(TwinEEngine* engine);
+ /** Table with all loaded sprites */
+ uint8 *spriteTable[NUM_SPRITES] {nullptr};
+ /** Table with all loaded sprite sizes */
+ uint32 spriteSizeTable[NUM_SPRITES] {0};
+
+ /** Actor shadow X coordinate */
+ int32 shadowX = 0;
+ /** Actor shadow Y coordinate */
+ int32 shadowY = 0;
+ /** Actor shadow Z coordinate */
+ int32 shadowZ = 0;
+ /** Actor shadow collition type */
+ int8 shadowCollisionType = 0; // shadowVar
+
+ HeroBehaviourType heroBehaviour = kNormal;
+ /** Hero auto agressive mode */
+ int16 autoAgressive = 0;
+ /** Previous Hero behaviour */
+ HeroBehaviourType previousHeroBehaviour = kNormal;
+ /** Previous Hero angle */
+ int16 previousHeroAngle = 0;
+
+ int16 cropBottomScreen = 0;
+
+ /** Hero 3D entity for normal behaviour */
+ uint8 *heroEntityNORMAL = nullptr; // file3D0
+ /** Hero 3D entity for athletic behaviour */
+ uint8 *heroEntityATHLETIC = nullptr; // file3D1
+ /** Hero 3D entity for aggressive behaviour */
+ uint8 *heroEntityAGGRESSIVE = nullptr; // file3D2
+ /** Hero 3D entity for discrete behaviour */
+ uint8 *heroEntityDISCRETE = nullptr; // file3D3
+ /** Hero 3D entity for protopack behaviour */
+ uint8 *heroEntityPROTOPACK = nullptr; // file3D4
+
+ /** Hero current anim for normal behaviour */
+ int16 heroAnimIdxNORMAL = 0; // TCos0Init
+ /** Hero current anim for athletic behaviour */
+ int16 heroAnimIdxATHLETIC = 0; // TCos1Init
+ /** Hero current anim for aggressive behaviour */
+ int16 heroAnimIdxAGGRESSIVE = 0; // TCos2Init
+ /** Hero current anim for discrete behaviour */
+ int16 heroAnimIdxDISCRETE = 0; // TCos3Init
+ /** Hero current anim for protopack behaviour */
+ int16 heroAnimIdxPROTOPACK = 0; // TCos4Init
+
+ /** Hero anim for behaviour menu */
+ int16 heroAnimIdx[4]; // TCOS
+
+ /** Actors 3D body table - size of NUM_BODIES */
+ uint8 *bodyTable[NUM_BODIES];
+
+ /** Current position in body table */
+ int32 currentPositionInBodyPtrTab;
+
+ /** Actor bounding box bottom left X coordinate */
+ int16 bottomLeftX; // loadCostumeVar
+ /** Actor bounding box bottom left Y coordinate */
+ int16 bottomLeftY; // loadCostumeVar2
+ /** Actor bounding box bottom left Z coordinate */
+ int16 bottomLeftZ; // loadCostumeVar3
+ /** Actor bounding box top left X coordinate */
+ int16 topRightX; // loadCostumeVar4
+ /** Actor bounding box top left Y coordinate */
+ int16 topRightY; // loadCostumeVar5
+ /** Actor bounding box top left Z coordinate */
+ int16 topRightZ; // loadCostumeVar6
+
+ /** Restart hero variables while opening new scenes */
+ void restartHeroScene();
+
+ /** Load hero 3D body and animations */
+ void loadHeroEntities();
+
+ /** Set hero behaviour
@param behaviour behaviour value to set */
-void setBehaviour(int32 behaviour);
+ void setBehaviour(int32 behaviour);
-/** Initialize 3D actor body
+ /** Initialize 3D actor body
@param bodyIdx 3D actor body index
@param actorIdx 3D actor index */
-int32 initBody(int32 bodyIdx, int32 actorIdx);
+ int32 initBody(int32 bodyIdx, int32 actorIdx);
-/** Preload all sprites */
-void preloadSprites();
+ /** Preload all sprites */
+ void preloadSprites();
-/** Initialize 3D actor
+ /** Initialize 3D actor
@param bodyIdx 3D actor body index
@param actorIdx 3D actor index */
-void initModelActor(int32 bodyIdx, int16 actorIdx);
+ void initModelActor(int32 bodyIdx, int16 actorIdx);
-/** Initialize actors
+ /** Initialize actors
@param actorIdx actor index to init */
-void initActor(int16 actorIdx);
+ void initActor(int16 actorIdx);
-/** Reset actor
+ /** Reset actor
@param actorIdx actor index to init */
-void resetActor(int16 actorIdx);
+ void resetActor(int16 actorIdx);
-/** Process hit actor
+ /** Process hit actor
@param actorIdx actor hitting index
@param actorIdxAttacked actor attacked index
@param strengthOfHit actor hitting strength of hit
@param angle angle of actor hitting */
-void hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32 angle);
+ void hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32 angle);
+
+ /** Process actor carrier */
+ void processActorCarrier(int32 actorIdx);
-/** Process actor carrier */
-void processActorCarrier(int32 actorIdx);
+ /** Process actor extra bonus */
+ void processActorExtraBonus(int32 actorIdx);
+};
-/** Process actor extra bonus */
-void processActorExtraBonus(int32 actorIdx);
+} // namespace TwinE
#endif
diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 8f34e458f1..73d878bdfc 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -1,71 +1,74 @@
-/** @file animations.cpp
- @brief
- This file contains 3D actors animations routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "animations.h"
-#include "lbaengine.h"
-#include "resources.h"
-#include "scene.h"
-#include "actor.h"
-#include "renderer.h"
-#include "movements.h"
-#include "sound.h"
-#include "gamestate.h"
-#include "collision.h"
-#include "grid.h"
-#include "main.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/animations.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+#include "common/util.h"
+#include "twine/actor.h"
+#include "twine/collision.h"
+#include "twine/gamestate.h"
+#include "twine/grid.h"
+#include "twine/movements.h"
+#include "twine/renderer.h"
+#include "twine/resources.h"
+#include "twine/scene.h"
+#include "twine/sound.h"
+#include "twine/twine.h"
+
+namespace TwinE {
+
+static const int32 magicLevelStrengthOfHit[] = {
+ kNoBallStrenght,
+ kYellowBallStrenght,
+ kGreenBallStrenght,
+ kRedBallStrenght,
+ kFireBallStrength,
+ 0};
enum ActionType {
- ACTION_HITTING = 0,
- ACTION_SAMPLE = 1,
- ACTION_SAMPLE_FREQ = 2,
- ACTION_THROW_EXTRA_BONUS = 3,
- ACTION_THROW_MAGIC_BALL = 4,
- ACTION_SAMPLE_REPEAT = 5,
- ACTION_UNKNOWN_6 = 6,
- ACTION_UNKNOWN_7 = 7,
- ACTION_SAMPLE_STOP = 8,
- ACTION_UNKNOWN_9 = 9, // unused
- ACTION_SAMPLE_BRICK_1 = 10,
- ACTION_SAMPLE_BRICK_2 = 11,
- ACTION_HERO_HITTING = 12,
- ACTION_UNKNOWN_13 = 13,
- ACTION_UNKNOWN_14 = 14,
- ACTION_UNKNOWN_15 = 15,
- ACTION_LAST
+ ACTION_HITTING = 0,
+ ACTION_SAMPLE = 1,
+ ACTION_SAMPLE_FREQ = 2,
+ ACTION_THROW_EXTRA_BONUS = 3,
+ ACTION_THROW_MAGIC_BALL = 4,
+ ACTION_SAMPLE_REPEAT = 5,
+ ACTION_UNKNOWN_6 = 6,
+ ACTION_UNKNOWN_7 = 7,
+ ACTION_SAMPLE_STOP = 8,
+ ACTION_UNKNOWN_9 = 9, // unused
+ ACTION_SAMPLE_BRICK_1 = 10,
+ ACTION_SAMPLE_BRICK_2 = 11,
+ ACTION_HERO_HITTING = 12,
+ ACTION_UNKNOWN_13 = 13,
+ ACTION_UNKNOWN_14 = 14,
+ ACTION_UNKNOWN_15 = 15,
+ ACTION_LAST
};
-/** Set animation keyframe
- @param keyframIdx Animation keyframe index
- @param animPtr Pointer to animation
- @param bodyPtr Body model poitner
- @param animTimerDataPtr Animation time data */
-int setAnimAtKeyframe(int32 keyframeIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr) {
+Animations::Animations(TwinEEngine *engine) : _engine(engine) {
+}
+
+int Animations::setAnimAtKeyframe(int32 keyframeIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
int16 numOfKeyframeInAnim;
int16 numOfBonesInAnim;
uint8 *ptrToData;
@@ -93,7 +96,7 @@ int setAnimAtKeyframe(int32 keyframeIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTim
ptrToBodyData = bodyPtr + 14;
animTimerDataPtr->ptr = ptrToData;
- animTimerDataPtr->time = lbaTime;
+ animTimerDataPtr->time = _engine->lbaTime;
ptrToBodyData = ptrToBodyData + *(int16 *)(ptrToBodyData) + 2;
@@ -126,26 +129,21 @@ int setAnimAtKeyframe(int32 keyframeIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTim
currentStepY = *(int16 *)(ptrToData + 2);
currentStepZ = *(int16 *)(ptrToData + 4);
- processRotationByAnim = *(int16 *)(ptrToData + 6);
+ processRotationByAnim = *(int16 *)(ptrToData + 6);
processLastRotationAngle = *(int16 *)(ptrToData + 10);
return 1;
}
-/** Get total number of keyframes in animation
- @param animPtr Pointer to animation */
-int32 getNumKeyframes(uint8 *animPtr) {
+int32 Animations::getNumKeyframes(uint8 *animPtr) {
return (*(int16 *)(animPtr));
}
-/** Get first keyframes in animation
- @param animPtr Pointer to animation */
-int32 getStartKeyframe(uint8 *animPtr) {
+int32 Animations::getStartKeyframe(uint8 *animPtr) {
return (*(int16 *)(animPtr + 4));
}
-/** Apply animation step rotation */
-void applyAnimStepRotation(uint8 **ptr, int32 bp, int32 bx) {
+void Animations::applyAnimStepRotation(uint8 **ptr, int32 bp, int32 bx) {
int16 *dest;
int16 lastAngle;
int16 newAngle;
@@ -175,23 +173,22 @@ void applyAnimStepRotation(uint8 **ptr, int32 bp, int32 bx) {
computedAngle = lastAngle;
}
- dest = (int16 *) * (ptr);
+ dest = (int16 *)*(ptr);
*dest = computedAngle & 0x3FF;
*(ptr) = *(ptr) + 2;
}
-/** Apply animation step */
-void applyAnimStep(uint8 **ptr, int32 bp, int32 bx) {
+void Animations::applyAnimStep(uint8 **ptr, int32 bp, int32 bx) {
int16 *dest;
int16 lastAngle;
int16 newAngle;
int16 angleDif;
int16 computedAngle;
- lastAngle = *(int16 *) lastKeyFramePtr;
+ lastAngle = *(int16 *)lastKeyFramePtr;
lastKeyFramePtr += 2;
- newAngle = *(int16 *) keyFramePtr;
+ newAngle = *(int16 *)keyFramePtr;
keyFramePtr += 2;
angleDif = newAngle - lastAngle;
@@ -202,17 +199,16 @@ void applyAnimStep(uint8 **ptr, int32 bp, int32 bx) {
computedAngle = lastAngle;
}
- dest = (int16 *) * (ptr);
+ dest = (int16 *)*(ptr);
*dest = computedAngle;
*(ptr) = *(ptr) + 2;
}
-/** Get animation mode */
-int32 getAnimMode(uint8 **ptr) {
+int32 Animations::getAnimMode(uint8 **ptr) {
int16 *lptr;
int16 opcode;
- lptr = (int16 *) * ptr;
+ lptr = (int16 *)*ptr;
opcode = *(int16 *)(keyFramePtr);
*(int16 *)(lptr) = opcode;
@@ -224,12 +220,7 @@ int32 getAnimMode(uint8 **ptr) {
return opcode;
}
-/** Set new body animation
- @param animIdx Animation index
- @param animPtr Animation pointer
- @param bodyPtr Body model poitner
- @param animTimerDataPtr Animation time data */
-int32 setModelAnimation(int32 animState, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr) {
+int32 Animations::setModelAnimation(int32 animState, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
int16 animOpcode;
int16 bodyHeader;
@@ -280,14 +271,14 @@ int32 setModelAnimation(int32 animState, uint8 *animPtr, uint8 *bodyPtr, AnimTim
numOfPointInAnim = numOfPointInBody;
}
- eax = lbaTime - ebp;
+ eax = _engine->lbaTime - ebp;
if (eax >= keyFrameLength) {
int32 *destPtr; // keyFrame
int32 *sourcePtr;
sourcePtr = (int32 *)(keyFramePtr + 8);
- destPtr = (int32 *) edi;
+ destPtr = (int32 *)edi;
do {
*(destPtr++) = *(sourcePtr++);
@@ -296,77 +287,72 @@ int32 setModelAnimation(int32 animState, uint8 *animPtr, uint8 *bodyPtr, AnimTim
} while (--numOfPointInAnim);
animTimerDataPtr->ptr = keyFramePtr;
- animTimerDataPtr->time = lbaTime;
+ animTimerDataPtr->time = _engine->lbaTime;
currentStepX = *(int16 *)(keyFramePtr + 2);
currentStepY = *(int16 *)(keyFramePtr + 4);
currentStepZ = *(int16 *)(keyFramePtr + 6);
- processRotationByAnim = *(int16 *)(keyFramePtr + 8);
+ processRotationByAnim = *(int16 *)(keyFramePtr + 8);
processLastRotationAngle = *(int16 *)(keyFramePtr + 12);
return 1;
- } else {
- keyFramePtrOld = keyFramePtr;
-
- lastKeyFramePtr += 8;
- keyFramePtr += 8;
-
- processRotationByAnim = *(int16 *)(keyFramePtr);
- processLastRotationAngle = (*(int16 *)(keyFramePtr + 4) * eax) / keyFrameLength;
+ }
+ keyFramePtrOld = keyFramePtr;
- lastKeyFramePtr += 8;
- keyFramePtr += 8;
+ lastKeyFramePtr += 8;
+ keyFramePtr += 8;
- edi += 38;
+ processRotationByAnim = *(int16 *)(keyFramePtr);
+ processLastRotationAngle = (*(int16 *)(keyFramePtr + 4) * eax) / keyFrameLength;
- if (--numOfPointInAnim) {
- int16 tmpNumOfPoints = numOfPointInAnim;
+ lastKeyFramePtr += 8;
+ keyFramePtr += 8;
- do {
- animOpcode = getAnimMode(&edi);
+ edi += 38;
- switch (animOpcode) {
- case 0: { // allow global rotate
- applyAnimStepRotation(&edi, eax, keyFrameLength);
- applyAnimStepRotation(&edi, eax, keyFrameLength);
- applyAnimStepRotation(&edi, eax, keyFrameLength);
- break;
- }
- case 1: { // dissallow global rotate
- applyAnimStep(&edi, eax, keyFrameLength);
- applyAnimStep(&edi, eax, keyFrameLength);
- applyAnimStep(&edi, eax, keyFrameLength);
- break;
- }
- case 2: { // dissallow global rotate + hide
- applyAnimStep(&edi, eax, keyFrameLength);
- applyAnimStep(&edi, eax, keyFrameLength);
- applyAnimStep(&edi, eax, keyFrameLength);
- break;
- }
- default: {
- printf("Unsupported animation rotation mode %d!\n", animOpcode);
- exit(1);
- }
- }
+ if (--numOfPointInAnim) {
+ int16 tmpNumOfPoints = numOfPointInAnim;
- edi += 30;
- } while (--tmpNumOfPoints);
- }
+ do {
+ animOpcode = getAnimMode(&edi);
+
+ switch (animOpcode) {
+ case 0: { // allow global rotate
+ applyAnimStepRotation(&edi, eax, keyFrameLength);
+ applyAnimStepRotation(&edi, eax, keyFrameLength);
+ applyAnimStepRotation(&edi, eax, keyFrameLength);
+ break;
+ }
+ case 1: { // dissallow global rotate
+ applyAnimStep(&edi, eax, keyFrameLength);
+ applyAnimStep(&edi, eax, keyFrameLength);
+ applyAnimStep(&edi, eax, keyFrameLength);
+ break;
+ }
+ case 2: { // dissallow global rotate + hide
+ applyAnimStep(&edi, eax, keyFrameLength);
+ applyAnimStep(&edi, eax, keyFrameLength);
+ applyAnimStep(&edi, eax, keyFrameLength);
+ break;
+ }
+ default: {
+ error("Unsupported animation rotation mode %d!\n", animOpcode);
+ }
+ }
- currentStepX = (*(int16 *)(keyFramePtrOld + 2) * eax) / keyFrameLength;
- currentStepY = (*(int16 *)(keyFramePtrOld + 4) * eax) / keyFrameLength;
- currentStepZ = (*(int16 *)(keyFramePtrOld + 6) * eax) / keyFrameLength;
+ edi += 30;
+ } while (--tmpNumOfPoints);
}
+ currentStepX = (*(int16 *)(keyFramePtrOld + 2) * eax) / keyFrameLength;
+ currentStepY = (*(int16 *)(keyFramePtrOld + 4) * eax) / keyFrameLength;
+ currentStepZ = (*(int16 *)(keyFramePtrOld + 6) * eax) / keyFrameLength;
+
return 0;
}
-/** Get entity anim index (This is taken from File3D entities)
- @param anim Entity animation index
- @param actorIdx Actor index */
-int32 getBodyAnimIndex(int32 animIdx, int32 actorIdx) {
+int32 Animations::getBodyAnimIndex(int32 animIdx, int32 actorIdx) {
int8 type;
uint16 realAnimIdx;
uint8 *bodyPtr;
@@ -374,7 +360,7 @@ int32 getBodyAnimIndex(int32 animIdx, int32 actorIdx) {
uint8 *costumePtr = NULL;
ActorStruct *actor;
- actor = &sceneActors[actorIdx];
+ actor = &_engine->_scene->sceneActors[actorIdx];
bodyPtr = actor->entityDataPtr;
do {
@@ -409,11 +395,7 @@ int32 getBodyAnimIndex(int32 animIdx, int32 actorIdx) {
return 0;
}
-/** Stock animation - copy the next keyFrame from a different buffer
- @param animPtr Animation pointer
- @param bodyPtr Body model poitner
- @param animTimerDataPtr Animation time data */
-int32 stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr) {
+int32 Animations::stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
int32 playAnim;
uint8 *ptr;
int32 *edi;
@@ -428,7 +410,7 @@ int32 stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTi
if (playAnim & 2) {
ptr = (bodyPtr + 0x10);
- animTimerDataPtr->time = lbaTime;
+ animTimerDataPtr->time = _engine->lbaTime;
animTimerDataPtr->ptr = animPtr;
var0 = *(int16 *)(ptr - 2);
@@ -450,7 +432,7 @@ int32 stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTi
*(edi++) = *(esi++);
*(edi++) = *(esi++);
- esi = (int32 *)(((int8 *) esi) + 30);
+ esi = (int32 *)(((int8 *)esi) + 30);
} while (counter--);
return var2;
@@ -458,12 +440,7 @@ int32 stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTi
return 0;
}
-/** Verify animation at keyframe
- @param animIdx Animation index
- @param animPtr Animation pointer
- @param bodyPtr Body model poitner
- @param animTimerDataPtr Animation time data */
-int32 verifyAnimAtKeyframe(int32 animIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr) {
+int32 Animations::verifyAnimAtKeyframe(int32 animIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
int16 bodyHeader;
uint8 *ebx;
@@ -495,340 +472,313 @@ int32 verifyAnimAtKeyframe(int32 animIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTi
lastKeyFramePtr = ebx;
- eax = lbaTime - ebp;
+ eax = _engine->lbaTime - ebp;
if (eax >= keyFrameLength) {
animTimerDataPtr->ptr = keyFramePtr;
- animTimerDataPtr->time = lbaTime;
+ animTimerDataPtr->time = _engine->lbaTime;
currentStepX = *(int16 *)(keyFramePtr + 2);
currentStepY = *(int16 *)(keyFramePtr + 4);
currentStepZ = *(int16 *)(keyFramePtr + 6);
- processRotationByAnim = *(int16 *)(keyFramePtr + 8);
+ processRotationByAnim = *(int16 *)(keyFramePtr + 8);
processLastRotationAngle = *(int16 *)(keyFramePtr + 12);
return 1;
- } else {
- keyFramePtrOld = keyFramePtr;
+ }
+ keyFramePtrOld = keyFramePtr;
- lastKeyFramePtr += 8;
- keyFramePtr += 8;
+ lastKeyFramePtr += 8;
+ keyFramePtr += 8;
- processRotationByAnim = *(int16 *)(keyFramePtr);
- processLastRotationAngle = (*(int16 *)(keyFramePtr + 4) * eax) / keyFrameLength;
+ processRotationByAnim = *(int16 *)(keyFramePtr);
+ processLastRotationAngle = (*(int16 *)(keyFramePtr + 4) * eax) / keyFrameLength;
- lastKeyFramePtr += 8;
- keyFramePtr += 8;
+ lastKeyFramePtr += 8;
+ keyFramePtr += 8;
- currentStepX = (*(int16 *)(keyFramePtrOld + 2) * eax) / keyFrameLength;
- currentStepY = (*(int16 *)(keyFramePtrOld + 4) * eax) / keyFrameLength;
- currentStepZ = (*(int16 *)(keyFramePtrOld + 6) * eax) / keyFrameLength;
- }
+ currentStepX = (*(int16 *)(keyFramePtrOld + 2) * eax) / keyFrameLength;
+ currentStepY = (*(int16 *)(keyFramePtrOld + 4) * eax) / keyFrameLength;
+ currentStepZ = (*(int16 *)(keyFramePtrOld + 6) * eax) / keyFrameLength;
return 0;
}
-//--------------------------------
-//helper class
struct _DataReader {
- uint8* ptr;
+ uint8 *ptr;
};
typedef struct _DataReader DataReader;
-int8 readByte(DataReader* data){
- return *(data->ptr++);
+int8 readByte(DataReader *data) {
+ return *(data->ptr++);
}
-int16 readWord(DataReader* data){
- int16 result;
- result = *(int16 *)(data->ptr);
- data->ptr += 2;
- return result;
+int16 readWord(DataReader *data) {
+ int16 result;
+ result = *(int16 *)(data->ptr);
+ data->ptr += 2;
+ return result;
}
-//--------------------------------
-void skipBytes(DataReader* data, int n){
- data->ptr += n;
+void skipBytes(DataReader *data, int n) {
+ data->ptr += n;
}
-/** Process acotr animation actions
- @param actorIdx Actor index */
-void processAnimActions(int32 actorIdx) {
- int32 index=0, endAnimEntityIdx, actionType, animPos;
+void Animations::processAnimActions(int32 actorIdx) {
+ int32 index = 0, endAnimEntityIdx, actionType, animPos;
ActorStruct *actor;
- DataReader* data;
+ DataReader *data;
- actor = &sceneActors[actorIdx];
- if (!actor->animExtraPtr) return; // avoid null pointers
+ actor = &_engine->_scene->sceneActors[actorIdx];
+ if (!actor->animExtraPtr) {
+ return; // avoid null pointers
+ }
- data = (DataReader*) malloc(sizeof(DataReader));
- data->ptr = actor->animExtraPtr;
+ data = (DataReader *)malloc(sizeof(DataReader));
+ if (!data) {
+ error("Failed to allocate memory for the animation actions");
+ }
+ data->ptr = actor->animExtraPtr;
endAnimEntityIdx = readByte(data);
while (index++ < endAnimEntityIdx) {
actionType = readByte(data) - 5;
- if (actionType >= ACTION_LAST) return;
+ if (actionType >= ACTION_LAST)
+ return;
switch (actionType) {
- case ACTION_HITTING:
- {
- int8 strength;
-
- animPos = readByte(data) - 1;
- strength = readByte(data);
-
- if (animPos == actor->animPosition) {
- actor->strengthOfHit = strength;
- actor->dynamicFlags.bIsHitting = 1;
- }
- }
- break;
- case ACTION_SAMPLE:
- {
- int16 sampleIdx;
-
- animPos = readByte(data);
- sampleIdx = readWord(data);
-
- if (animPos == actor->animPosition)
- playSample(sampleIdx, 0x1000, 1, actor->X, actor->Y, actor->Z, actorIdx);
- }
- break;
- case ACTION_SAMPLE_FREQ:
- {
- int16 sampleIdx, frequency;
-
- animPos = readByte(data);
- sampleIdx = readWord(data);
- frequency = readWord(data);
-
- if (animPos == actor->animPosition) {
- frequency = Rnd(frequency) + 0x1000 - (Abs(frequency) >> 1);
- playSample(sampleIdx, frequency, 1, actor->X, actor->Y, actor->Z, actorIdx);
- }
- }
- break;
- case ACTION_THROW_EXTRA_BONUS:
- {
- int32 yHeight, var_C, var_24, var_14, cx, dx, var;
-
- animPos = readByte(data);
- yHeight = readWord(data);
- var_C = readByte(data);
- cx = readWord(data);
- dx = actor->angle + readWord(data);
- var_24 = readWord(data);
- var_14 = readByte(data);
- var = readByte(data);
-
- if (animPos == actor->animPosition)
- addExtraThrow(actorIdx, actor->X, actor->Y + yHeight, actor->Z, var_C, cx, dx, var_24, var_14, var);
- }
- break;
- case ACTION_THROW_MAGIC_BALL:
- {
- int32 var_8, dx, var_24, var_14;
-
- animPos = readByte(data);
- var_8 = readWord(data);
- dx = readWord(data);
- var_24 = readWord(data);
- var_14 = readByte(data);
-
- if (magicBallIdx == -1 && animPos == actor->animPosition)
- addExtraThrowMagicball(actor->X, actor->Y + var_8, actor->Z, dx, actor->angle, var_24, var_14);
- }
- break;
- case ACTION_SAMPLE_REPEAT:
- {
- int16 sampleIdx, repeat;
-
- animPos = readByte(data);
- sampleIdx = readWord(data);
- repeat = readWord(data);
-
- if (animPos == actor->animPosition)
- playSample(sampleIdx, 0x1000, repeat, actor->X, actor->Y, actor->Z, actorIdx);
- }
- break;
- case ACTION_UNKNOWN_6:
- animPos = readByte(data);
- if (animPos == actor->animPosition) {
- int32 var_8, var_C, dx, var_24, temp;
-
- //The folowing fetches 7 bytes, but the else block skips only 6 bytes.
- // Please check if that's correct.
- var_8 = readWord(data);
- var_C = readByte(data);
- dx = readByte(data);
- var_24 = readWord(data);
- temp = readByte(data);
-
- addExtraAiming(actorIdx, actor->X, actor->Y + var_8, actor->Z, var_C, dx, var_24, temp);
- } else {
- skipBytes(data, 6);
- }
- break;
- case ACTION_UNKNOWN_7:
- {
- int32 yHeight, var_C, var_24, var_14, cx, dx, var;
-
- animPos = readByte(data);
- yHeight = readWord(data);
- var_C = readByte(data);
- dx = readWord(data);
- cx = actor->angle + readWord(data);
- var_24 = readWord(data);
- var_14 = readByte(data);
- var = readByte(data);
-
- if (animPos == actor->animPosition)
- addExtraThrow(actorIdx, actor->X, actor->Y + yHeight, actor->Z, var_C, dx, cx, var_24, var_14, var);
- }
- break;
- case ACTION_SAMPLE_STOP:
- {
- int32 sampleIdx;
-
- animPos = readByte(data);
- sampleIdx = readByte(data); //why is it reading a byte but saving it in a 32bit variable?
- skipBytes(data, 1); //what is the meaning of this extra byte?
-
- if (animPos == actor->animPosition) {
- stopSample(sampleIdx);
- }
- }
- break;
- case ACTION_SAMPLE_BRICK_1:
- animPos = readByte(data);
- if (animPos == actor->animPosition && (actor->brickSound & 0x0F0) != 0x0F0) {
- int16 sampleIdx = (actor->brickSound & 0x0F) + 126;
- playSample(sampleIdx, Rnd(1000) + 3596, 1, actor->X, actor->Y, actor->Z, actorIdx);
- }
- break;
- case ACTION_SAMPLE_BRICK_2:
- animPos = readByte(data);
- if (animPos == actor->animPosition && (actor->brickSound & 0x0F0) != 0x0F0) {
- int16 sampleIdx = (actor->brickSound & 0x0F) + 126;
- playSample(sampleIdx, Rnd(1000) + 3596, 1, actor->X, actor->Y, actor->Z, actorIdx);
- }
- break;
- case ACTION_HERO_HITTING:
- animPos = readByte(data) - 1;
- if (animPos == actor->animPosition) {
- actor->strengthOfHit = magicLevelStrengthOfHit[magicLevelIdx];
- actor->dynamicFlags.bIsHitting = 1;
- }
- break;
- case ACTION_UNKNOWN_13:
- {
- int32 throwX, throwY, throwZ;
- int32 distanceX, distanceY, distanceZ;
- int32 spriteIdx, strength;
- int32 param1, param2, param3, param4;
-
- animPos = readByte(data);
- distanceX = readWord(data);
- distanceY = readWord(data);
- distanceZ = readWord(data);
-
- spriteIdx = readByte(data);
-
- param1 = readWord(data);
- param2 = readWord(data);
- param3 = readWord(data);
- param4 = readByte(data);
-
- strength = readByte(data);
-
- if (animPos == actor->animPosition) {
- rotateActor(distanceX, distanceZ, actor->angle);
-
- throwX = destX + actor->X;
- throwY = distanceY + actor->Y;
- throwZ = destZ + actor->Z;
-
- addExtraThrow(actorIdx, throwX, throwY, throwZ, spriteIdx,
- param1, param2 + actor->angle, param3, param4, strength);
- }
- }
- break;
- case ACTION_UNKNOWN_14:
- {
- int32 newAngle, throwX, throwY, throwZ;
- int32 distanceX, distanceY, distanceZ;
- int32 spriteIdx, strength;
- int32 param1, param2, param3, param4;
-
- animPos = readByte(data);
- distanceX = readWord(data);
- distanceY = readWord(data);
- distanceZ = readWord(data);
-
- spriteIdx = readByte(data);
-
- param1 = readWord(data);
- param2 = readWord(data);
- param3 = readWord(data);
- param4 = readByte(data);
-
- strength = readByte(data);
-
- if (animPos == actor->animPosition) {
- newAngle = getAngleAndSetTargetActorDistance(actor->Y, 0, sceneHero->Y, getDistance2D(actor->X, actor->Z, sceneHero->X, sceneHero->Z));
-
- rotateActor(distanceX, distanceZ, actor->angle);
-
- throwX = destX + actor->X;
- throwY = distanceY + actor->Y;
- throwZ = destZ + actor->Z;
-
- addExtraThrow(actorIdx, throwX, throwY, throwZ, spriteIdx,
- param1 + newAngle, param2 + actor->angle, param3, param4, strength);
- }
- }
- break;
- case ACTION_UNKNOWN_15:
- {
- int32 distanceX, distanceY, distanceZ;
- int32 spriteIdx, targetActor, param3, param4;
-
- animPos = readByte(data);
- distanceX = readWord(data);
- distanceY = readWord(data);
- distanceZ = readWord(data);
- spriteIdx = readByte(data);
- targetActor = readByte(data);
- param3 = readWord(data);
- param4 = readByte(data);
-
- if (animPos == actor->animPosition) {
- rotateActor( distanceX, distanceZ, actor->angle);
- addExtraAiming(actorIdx, actor->X + destX, actor->Y + distanceY, actor->Z + distanceZ, spriteIdx,
- targetActor, param3, param4);
- }
- }
- break;
- case ACTION_UNKNOWN_9:
- break;
- default:
- break;
+ case ACTION_HITTING: {
+ int8 strength;
+
+ animPos = readByte(data) - 1;
+ strength = readByte(data);
+
+ if (animPos == actor->animPosition) {
+ actor->strengthOfHit = strength;
+ actor->dynamicFlags.bIsHitting = 1;
+ }
+ } break;
+ case ACTION_SAMPLE: {
+ int16 sampleIdx;
+
+ animPos = readByte(data);
+ sampleIdx = readWord(data);
+
+ if (animPos == actor->animPosition)
+ _engine->_sound->playSample(sampleIdx, 0x1000, 1, actor->x, actor->y, actor->z, actorIdx);
+ } break;
+ case ACTION_SAMPLE_FREQ: {
+ int16 sampleIdx, frequency;
+
+ animPos = readByte(data);
+ sampleIdx = readWord(data);
+ frequency = readWord(data);
+
+ if (animPos == actor->animPosition) {
+ frequency = _engine->getRandomNumber(frequency) + 0x1000 - (ABS(frequency) >> 1);
+ _engine->_sound->playSample(sampleIdx, frequency, 1, actor->x, actor->y, actor->z, actorIdx);
+ }
+ } break;
+ case ACTION_THROW_EXTRA_BONUS: {
+ int32 yHeight, var_C, var_24, var_14, cx, dx, var;
+
+ animPos = readByte(data);
+ yHeight = readWord(data);
+ var_C = readByte(data);
+ cx = readWord(data);
+ dx = actor->angle + readWord(data);
+ var_24 = readWord(data);
+ var_14 = readByte(data);
+ var = readByte(data);
+
+ if (animPos == actor->animPosition)
+ _engine->_extra->addExtraThrow(actorIdx, actor->x, actor->y + yHeight, actor->z, var_C, cx, dx, var_24, var_14, var);
+ } break;
+ case ACTION_THROW_MAGIC_BALL: {
+ int32 var_8, dx, var_24, var_14;
+
+ animPos = readByte(data);
+ var_8 = readWord(data);
+ dx = readWord(data);
+ var_24 = readWord(data);
+ var_14 = readByte(data);
+
+ if (_engine->_gameState->magicBallIdx == -1 && animPos == actor->animPosition)
+ _engine->_extra->addExtraThrowMagicball(actor->x, actor->y + var_8, actor->z, dx, actor->angle, var_24, var_14);
+ } break;
+ case ACTION_SAMPLE_REPEAT: {
+ int16 sampleIdx, repeat;
+
+ animPos = readByte(data);
+ sampleIdx = readWord(data);
+ repeat = readWord(data);
+
+ if (animPos == actor->animPosition)
+ _engine->_sound->playSample(sampleIdx, 0x1000, repeat, actor->x, actor->y, actor->z, actorIdx);
+ } break;
+ case ACTION_UNKNOWN_6:
+ animPos = readByte(data);
+ if (animPos == actor->animPosition) {
+ int32 var_8, var_C, dx, var_24, temp;
+
+ //The folowing fetches 7 bytes, but the else block skips only 6 bytes.
+ // Please check if that's correct.
+ var_8 = readWord(data);
+ var_C = readByte(data);
+ dx = readByte(data);
+ var_24 = readWord(data);
+ temp = readByte(data);
+
+ _engine->_extra->addExtraAiming(actorIdx, actor->x, actor->y + var_8, actor->z, var_C, dx, var_24, temp);
+ } else {
+ skipBytes(data, 6);
+ }
+ break;
+ case ACTION_UNKNOWN_7: {
+ int32 yHeight, var_C, var_24, var_14, cx, dx, var;
+
+ animPos = readByte(data);
+ yHeight = readWord(data);
+ var_C = readByte(data);
+ dx = readWord(data);
+ cx = actor->angle + readWord(data);
+ var_24 = readWord(data);
+ var_14 = readByte(data);
+ var = readByte(data);
+
+ if (animPos == actor->animPosition)
+ _engine->_extra->addExtraThrow(actorIdx, actor->x, actor->y + yHeight, actor->z, var_C, dx, cx, var_24, var_14, var);
+ } break;
+ case ACTION_SAMPLE_STOP: {
+ int32 sampleIdx;
+
+ animPos = readByte(data);
+ sampleIdx = readByte(data); //why is it reading a byte but saving it in a 32bit variable?
+ skipBytes(data, 1); //what is the meaning of this extra byte?
+
+ if (animPos == actor->animPosition) {
+ _engine->_sound->stopSample(sampleIdx);
+ }
+ } break;
+ case ACTION_SAMPLE_BRICK_1:
+ animPos = readByte(data);
+ if (animPos == actor->animPosition && (actor->brickSound & 0x0F0) != 0x0F0) {
+ int16 sampleIdx = (actor->brickSound & 0x0F) + 126;
+ _engine->_sound->playSample(sampleIdx, _engine->getRandomNumber(1000) + 3596, 1, actor->x, actor->y, actor->z, actorIdx);
+ }
+ break;
+ case ACTION_SAMPLE_BRICK_2:
+ animPos = readByte(data);
+ if (animPos == actor->animPosition && (actor->brickSound & 0x0F0) != 0x0F0) {
+ int16 sampleIdx = (actor->brickSound & 0x0F) + 126;
+ _engine->_sound->playSample(sampleIdx, _engine->getRandomNumber(1000) + 3596, 1, actor->x, actor->y, actor->z, actorIdx);
+ }
+ break;
+ case ACTION_HERO_HITTING:
+ animPos = readByte(data) - 1;
+ if (animPos == actor->animPosition) {
+ actor->strengthOfHit = magicLevelStrengthOfHit[_engine->_gameState->magicLevelIdx];
+ actor->dynamicFlags.bIsHitting = 1;
+ }
+ break;
+ case ACTION_UNKNOWN_13: {
+ int32 throwX, throwY, throwZ;
+ int32 distanceX, distanceY, distanceZ;
+ int32 spriteIdx, strength;
+ int32 param1, param2, param3, param4;
+
+ animPos = readByte(data);
+ distanceX = readWord(data);
+ distanceY = readWord(data);
+ distanceZ = readWord(data);
+
+ spriteIdx = readByte(data);
+
+ param1 = readWord(data);
+ param2 = readWord(data);
+ param3 = readWord(data);
+ param4 = readByte(data);
+
+ strength = readByte(data);
+
+ if (animPos == actor->animPosition) {
+ _engine->_movements->rotateActor(distanceX, distanceZ, actor->angle);
+
+ throwX = _engine->_renderer->destX + actor->x;
+ throwY = distanceY + actor->y;
+ throwZ = _engine->_renderer->destZ + actor->z;
+
+ _engine->_extra->addExtraThrow(actorIdx, throwX, throwY, throwZ, spriteIdx,
+ param1, param2 + actor->angle, param3, param4, strength);
+ }
+ } break;
+ case ACTION_UNKNOWN_14: {
+ int32 newAngle, throwX, throwY, throwZ;
+ int32 distanceX, distanceY, distanceZ;
+ int32 spriteIdx, strength;
+ int32 param1, param2, param3, param4;
+
+ animPos = readByte(data);
+ distanceX = readWord(data);
+ distanceY = readWord(data);
+ distanceZ = readWord(data);
+
+ spriteIdx = readByte(data);
+
+ param1 = readWord(data);
+ param2 = readWord(data);
+ param3 = readWord(data);
+ param4 = readByte(data);
+
+ strength = readByte(data);
+
+ if (animPos == actor->animPosition) {
+ newAngle = _engine->_movements->getAngleAndSetTargetActorDistance(actor->y, 0, _engine->_scene->sceneHero->y, _engine->_movements->getDistance2D(actor->x, actor->z, _engine->_scene->sceneHero->x, _engine->_scene->sceneHero->z));
+
+ _engine->_movements->rotateActor(distanceX, distanceZ, actor->angle);
+
+ throwX = _engine->_renderer->destX + actor->x;
+ throwY = distanceY + actor->y;
+ throwZ = _engine->_renderer->destZ + actor->z;
+
+ _engine->_extra->addExtraThrow(actorIdx, throwX, throwY, throwZ, spriteIdx,
+ param1 + newAngle, param2 + actor->angle, param3, param4, strength);
+ }
+ } break;
+ case ACTION_UNKNOWN_15: {
+ int32 distanceX, distanceY, distanceZ;
+ int32 spriteIdx, targetActor, param3, param4;
+
+ animPos = readByte(data);
+ distanceX = readWord(data);
+ distanceY = readWord(data);
+ distanceZ = readWord(data);
+ spriteIdx = readByte(data);
+ targetActor = readByte(data);
+ param3 = readWord(data);
+ param4 = readByte(data);
+
+ if (animPos == actor->animPosition) {
+ _engine->_movements->rotateActor(distanceX, distanceZ, actor->angle);
+ _engine->_extra->addExtraAiming(actorIdx, actor->x + _engine->_renderer->destX, actor->y + distanceY, actor->z + distanceZ, spriteIdx,
+ targetActor, param3, param4);
+ }
+ } break;
+ case ACTION_UNKNOWN_9:
+ break;
+ default:
+ break;
}
}
- free(data);
+ free(data);
}
-/** Initialize animation
- @param newAnim animation to init
- @param animType animation type
- @param animExtra animation actions extra data
- @param actorIdx actor index */
-int32 initAnim(int32 newAnim, int16 animType, uint8 animExtra, int32 actorIdx) {
+int32 Animations::initAnim(AnimationTypes newAnim, int16 animType, uint8 animExtra, int32 actorIdx) {
ActorStruct *actor;
int32 animIndex;
- actor = &sceneActors[actorIdx];
+ actor = &_engine->_scene->sceneActors[actorIdx];
if (actor->entity == -1)
return 0;
@@ -840,7 +790,7 @@ int32 initAnim(int32 newAnim, int16 animType, uint8 animExtra, int32 actorIdx) {
return 1;
if (animExtra == 255 && actor->animType != 2)
- animExtra = actor->anim;
+ animExtra = (uint8)actor->anim;
animIndex = getBodyAnimIndex(newAnim, actorIdx);
@@ -865,10 +815,10 @@ int32 initAnim(int32 newAnim, int16 animType, uint8 animExtra, int32 actorIdx) {
if (animType == 4)
animType = 2;
- if (actor->previousAnimIdx == -1) { // if no previous animation
- setAnimAtKeyframe(0, animTable[animIndex], bodyTable[actor->entity], &actor->animTimerData);
+ if (actor->previousAnimIdx == -1) { // if no previous animation
+ setAnimAtKeyframe(0, animTable[animIndex], _engine->_actor->bodyTable[actor->entity], &actor->animTimerData);
} else { // interpolation between animations
- animBuffer2 += stockAnimation(animBuffer2, bodyTable[actor->entity], &actor->animTimerData);
+ animBuffer2 += stockAnimation(animBuffer2, _engine->_actor->bodyTable[actor->entity], &actor->animTimerData);
if (animBuffer1 + 4488 < animBuffer2)
animBuffer2 = animBuffer1;
}
@@ -895,37 +845,35 @@ int32 initAnim(int32 newAnim, int16 animType, uint8 animExtra, int32 actorIdx) {
return 1;
}
-/** Process main loop actor animations
- @param actorIdx Actor index */
-void processActorAnimations(int32 actorIdx) { // DoAnim
+void Animations::processActorAnimations(int32 actorIdx) { // DoAnim
int16 numKeyframe;
uint8 *animPtr;
ActorStruct *actor;
- actor = &sceneActors[actorIdx];
+ actor = &_engine->_scene->sceneActors[actorIdx];
currentlyProcessedActorIdx = actorIdx;
- processActorPtr = actor;
+ _engine->_movements->processActorPtr = actor;
if (actor->entity == -1)
return;
- previousActorX = actor->collisionX;
- previousActorY = actor->collisionY;
- previousActorZ = actor->collisionZ;
+ _engine->_movements->previousActorX = actor->collisionX;
+ _engine->_movements->previousActorY = actor->collisionY;
+ _engine->_movements->previousActorZ = actor->collisionZ;
if (actor->staticFlags.bIsSpriteActor) { // is sprite actor
if (actor->strengthOfHit) {
actor->dynamicFlags.bIsHitting = 1;
}
- processActorX = actor->X;
- processActorY = actor->Y;
- processActorZ = actor->Z;
+ _engine->_movements->processActorX = actor->x;
+ _engine->_movements->processActorY = actor->y;
+ _engine->_movements->processActorZ = actor->z;
if (!actor->dynamicFlags.bIsFalling) {
if (actor->speed) {
- int32 angle = getRealValue(&actor->move);
+ int32 angle = _engine->_movements->getRealValue(&actor->move);
if (!angle) {
if (actor->move.to > 0) {
angle = 1;
@@ -934,28 +882,28 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
}
}
- rotateActor(angle, 0, actor->animType);
+ _engine->_movements->rotateActor(angle, 0, actor->animType);
- processActorY = actor->Y - destZ;
+ _engine->_movements->processActorY = actor->y - _engine->_renderer->destZ;
- rotateActor(0, destX, actor->angle);
+ _engine->_movements->rotateActor(0, _engine->_renderer->destX, actor->angle);
- processActorX = actor->X + destX;
- processActorZ = actor->Z + destZ;
+ _engine->_movements->processActorX = actor->x + _engine->_renderer->destX;
+ _engine->_movements->processActorZ = actor->z + _engine->_renderer->destZ;
- setActorAngle(0, actor->speed, 50, &actor->move);
+ _engine->_movements->setActorAngle(0, actor->speed, 50, &actor->move);
if (actor->dynamicFlags.bIsSpriteMoving) {
if (actor->doorStatus) { // open door
- if (getDistance2D(processActorX, processActorZ, actor->lastX, actor->lastZ) >= actor->doorStatus) {
+ if (_engine->_movements->getDistance2D(_engine->_movements->processActorX, _engine->_movements->processActorZ, actor->lastX, actor->lastZ) >= actor->doorStatus) {
if (actor->angle == 0) {
- processActorZ = actor->lastZ + actor->doorStatus;
+ _engine->_movements->processActorZ = actor->lastZ + actor->doorStatus;
} else if (actor->angle == 0x100) {
- processActorX = actor->lastX + actor->doorStatus;
+ _engine->_movements->processActorX = actor->lastX + actor->doorStatus;
} else if (actor->angle == 0x200) {
- processActorZ = actor->lastZ - actor->doorStatus;
+ _engine->_movements->processActorZ = actor->lastZ - actor->doorStatus;
} else if (actor->angle == 0x300) {
- processActorX = actor->lastX - actor->doorStatus;
+ _engine->_movements->processActorX = actor->lastX - actor->doorStatus;
}
actor->dynamicFlags.bIsSpriteMoving = 0;
@@ -965,27 +913,27 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
int16 updatePos = 0;
if (actor->angle == 0) {
- if (processActorZ <= actor->lastZ) {
+ if (_engine->_movements->processActorZ <= actor->lastZ) {
updatePos = 1;
}
} else if (actor->angle == 0x100) {
- if (processActorX <= actor->lastX) {
+ if (_engine->_movements->processActorX <= actor->lastX) {
updatePos = 1;
}
} else if (actor->angle == 0x200) {
- if (processActorZ >= actor->lastZ) {
+ if (_engine->_movements->processActorZ >= actor->lastZ) {
updatePos = 1;
}
} else if (actor->angle == 0x300) {
- if (processActorX >= actor->lastX) {
+ if (_engine->_movements->processActorX >= actor->lastX) {
updatePos = 1;
}
}
if (updatePos) {
- processActorX = actor->lastX;
- processActorY = actor->lastY;
- processActorZ = actor->lastZ;
+ _engine->_movements->processActorX = actor->lastX;
+ _engine->_movements->processActorY = actor->lastY;
+ _engine->_movements->processActorZ = actor->lastZ;
actor->dynamicFlags.bIsSpriteMoving = 0;
actor->speed = 0;
@@ -995,13 +943,13 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
}
if (actor->staticFlags.bCanBePushed) {
- processActorX += actor->lastX;
- processActorY += actor->lastY;
- processActorZ += actor->lastZ;
+ _engine->_movements->processActorX += actor->lastX;
+ _engine->_movements->processActorY += actor->lastY;
+ _engine->_movements->processActorZ += actor->lastZ;
if (actor->staticFlags.bUseMiniZv) {
- processActorX = ((processActorX / 128) * 128);
- processActorZ = ((processActorZ / 128) * 128);
+ _engine->_movements->processActorX = ((_engine->_movements->processActorX / 128) * 128);
+ _engine->_movements->processActorZ = ((_engine->_movements->processActorZ / 128) * 128);
}
actor->lastX = 0;
@@ -1014,7 +962,7 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
int32 keyFramePassed;
animPtr = animTable[actor->previousAnimIdx];
- keyFramePassed = verifyAnimAtKeyframe(actor->animPosition, animPtr, bodyTable[actor->entity], &actor->animTimerData);
+ keyFramePassed = verifyAnimAtKeyframe(actor->animPosition, animPtr, _engine->_actor->bodyTable[actor->entity], &actor->animTimerData);
if (processRotationByAnim) {
actor->dynamicFlags.bIsRotationByAnim = 1;
@@ -1025,14 +973,14 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
actor->angle = (actor->angle + processLastRotationAngle - actor->lastRotationAngle) & 0x3FF;
actor->lastRotationAngle = processLastRotationAngle;
- rotateActor(currentStepX, currentStepZ, actor->angle);
+ _engine->_movements->rotateActor(currentStepX, currentStepZ, actor->angle);
- currentStepX = destX;
- currentStepZ = destZ;
+ currentStepX = _engine->_renderer->destX;
+ currentStepZ = _engine->_renderer->destZ;
- processActorX = actor->X + currentStepX - actor->lastX;
- processActorY = actor->Y + currentStepY - actor->lastY;
- processActorZ = actor->Z + currentStepZ - actor->lastZ;
+ _engine->_movements->processActorX = actor->x + currentStepX - actor->lastX;
+ _engine->_movements->processActorY = actor->y + currentStepY - actor->lastY;
+ _engine->_movements->processActorZ = actor->z + currentStepZ - actor->lastZ;
actor->lastX = currentStepX;
actor->lastY = currentStepY;
@@ -1056,12 +1004,12 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
if (actor->animType == 0) {
actor->animPosition = getStartKeyframe(animPtr);
} else {
- actor->anim = actor->animExtra;
+ actor->anim = (AnimationTypes)actor->animExtra;
actor->previousAnimIdx = getBodyAnimIndex(actor->anim, actorIdx);
if (actor->previousAnimIdx == -1) {
actor->previousAnimIdx = getBodyAnimIndex(0, actorIdx);
- actor->anim = 0;
+ actor->anim = kStanding;
}
actor->animExtraPtr = currentActorAnimExtraPtr;
@@ -1089,83 +1037,83 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
// actor standing on another actor
if (actor->standOn != -1) {
- processActorX -= sceneActors[actor->standOn].collisionX;
- processActorY -= sceneActors[actor->standOn].collisionY;
- processActorZ -= sceneActors[actor->standOn].collisionZ;
+ _engine->_movements->processActorX -= _engine->_scene->sceneActors[actor->standOn].collisionX;
+ _engine->_movements->processActorY -= _engine->_scene->sceneActors[actor->standOn].collisionY;
+ _engine->_movements->processActorZ -= _engine->_scene->sceneActors[actor->standOn].collisionZ;
- processActorX += sceneActors[actor->standOn].X;
- processActorY += sceneActors[actor->standOn].Y;
- processActorZ += sceneActors[actor->standOn].Z;
+ _engine->_movements->processActorX += _engine->_scene->sceneActors[actor->standOn].x;
+ _engine->_movements->processActorY += _engine->_scene->sceneActors[actor->standOn].y;
+ _engine->_movements->processActorZ += _engine->_scene->sceneActors[actor->standOn].z;
- if (!standingOnActor(actorIdx, actor->standOn)) {
+ if (!_engine->_collision->standingOnActor(actorIdx, actor->standOn)) {
actor->standOn = -1; // no longer standing on other actor
}
}
// actor falling Y speed
if (actor->dynamicFlags.bIsFalling) {
- processActorX = previousActorX;
- processActorY = previousActorY + loopActorStep; // add step to fall
- processActorZ = previousActorZ;
+ _engine->_movements->processActorX = _engine->_movements->previousActorX;
+ _engine->_movements->processActorY = _engine->_movements->previousActorY + _engine->loopActorStep; // add step to fall
+ _engine->_movements->processActorZ = _engine->_movements->previousActorZ;
}
// actor collisions with bricks
if (actor->staticFlags.bComputeCollisionWithBricks) {
int32 brickShape;
- collisionY = 0;
+ _engine->_collision->collisionY = 0;
- brickShape = getBrickShape(previousActorX, previousActorY, previousActorZ);
+ brickShape = _engine->_grid->getBrickShape(_engine->_movements->previousActorX, _engine->_movements->previousActorY, _engine->_movements->previousActorZ);
if (brickShape) {
if (brickShape != kSolid) {
- reajustActorPosition(brickShape);
+ _engine->_collision->reajustActorPosition(brickShape);
} /*else { // this shouldn't happen (collision should avoid it)
- actor->Y = processActorY = (processActorY / 256) * 256 + 256; // go upper
+ actor->y = processActorY = (processActorY / 256) * 256 + 256; // go upper
}*/
}
if (actor->staticFlags.bComputeCollisionWithObj) {
- checkCollisionWithActors(actorIdx);
+ _engine->_collision->checkCollisionWithActors(actorIdx);
}
if (actor->standOn != -1 && actor->dynamicFlags.bIsFalling) {
- stopFalling();
+ _engine->_collision->stopFalling();
}
- causeActorDamage = 0;
+ _engine->_collision->causeActorDamage = 0;
- processCollisionX = processActorX;
- processCollisionY = processActorY;
- processCollisionZ = processActorZ;
+ _engine->_collision->processCollisionX = _engine->_movements->processActorX;
+ _engine->_collision->processCollisionY = _engine->_movements->processActorY;
+ _engine->_collision->processCollisionZ = _engine->_movements->processActorZ;
if (!actorIdx && !actor->staticFlags.bComputeLowCollision) {
// check hero collisions with bricks
- checkHeroCollisionWithBricks(actor->boudingBox.X.bottomLeft, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.bottomLeft, 1);
- checkHeroCollisionWithBricks(actor->boudingBox.X.topRight, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.bottomLeft, 2);
- checkHeroCollisionWithBricks(actor->boudingBox.X.topRight, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.topRight, 4);
- checkHeroCollisionWithBricks(actor->boudingBox.X.bottomLeft, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.topRight, 8);
+ _engine->_collision->checkHeroCollisionWithBricks(actor->boudingBox.x.bottomLeft, actor->boudingBox.y.bottomLeft, actor->boudingBox.z.bottomLeft, 1);
+ _engine->_collision->checkHeroCollisionWithBricks(actor->boudingBox.x.topRight, actor->boudingBox.y.bottomLeft, actor->boudingBox.z.bottomLeft, 2);
+ _engine->_collision->checkHeroCollisionWithBricks(actor->boudingBox.x.topRight, actor->boudingBox.y.bottomLeft, actor->boudingBox.z.topRight, 4);
+ _engine->_collision->checkHeroCollisionWithBricks(actor->boudingBox.x.bottomLeft, actor->boudingBox.y.bottomLeft, actor->boudingBox.z.topRight, 8);
} else {
// check other actors collisions with bricks
- checkActorCollisionWithBricks(actor->boudingBox.X.bottomLeft, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.bottomLeft, 1);
- checkActorCollisionWithBricks(actor->boudingBox.X.topRight, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.bottomLeft, 2);
- checkActorCollisionWithBricks(actor->boudingBox.X.topRight, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.topRight, 4);
- checkActorCollisionWithBricks(actor->boudingBox.X.bottomLeft, actor->boudingBox.Y.bottomLeft, actor->boudingBox.Z.topRight, 8);
+ _engine->_collision->checkActorCollisionWithBricks(actor->boudingBox.x.bottomLeft, actor->boudingBox.y.bottomLeft, actor->boudingBox.z.bottomLeft, 1);
+ _engine->_collision->checkActorCollisionWithBricks(actor->boudingBox.x.topRight, actor->boudingBox.y.bottomLeft, actor->boudingBox.z.bottomLeft, 2);
+ _engine->_collision->checkActorCollisionWithBricks(actor->boudingBox.x.topRight, actor->boudingBox.y.bottomLeft, actor->boudingBox.z.topRight, 4);
+ _engine->_collision->checkActorCollisionWithBricks(actor->boudingBox.x.bottomLeft, actor->boudingBox.y.bottomLeft, actor->boudingBox.z.topRight, 8);
}
// process wall hit while running
- if (causeActorDamage && !actor->dynamicFlags.bIsFalling && !currentlyProcessedActorIdx && heroBehaviour == kAthletic && actor->anim == kForward) {
- rotateActor(actor->boudingBox.X.bottomLeft, actor->boudingBox.Z.bottomLeft, actor->angle + 0x580);
+ if (_engine->_collision->causeActorDamage && !actor->dynamicFlags.bIsFalling && !currentlyProcessedActorIdx && _engine->_actor->heroBehaviour == kAthletic && actor->anim == kForward) {
+ _engine->_movements->rotateActor(actor->boudingBox.x.bottomLeft, actor->boudingBox.z.bottomLeft, actor->angle + 0x580);
- destX += processActorX;
- destZ += processActorZ;
+ _engine->_renderer->destX += _engine->_movements->processActorX;
+ _engine->_renderer->destZ += _engine->_movements->processActorZ;
- if (destX >= 0 && destZ >= 0 && destX <= 0x7E00 && destZ <= 0x7E00) {
- if (getBrickShape(destX, processActorY + 0x100, destZ) && cfgfile.WallCollision == 1) { // avoid wall hit damage
- addExtraSpecial(actor->X, actor->Y + 1000, actor->Z, kHitStars);
+ if (_engine->_renderer->destX >= 0 && _engine->_renderer->destZ >= 0 && _engine->_renderer->destX <= 0x7E00 && _engine->_renderer->destZ <= 0x7E00) {
+ if (_engine->_grid->getBrickShape(_engine->_renderer->destX, _engine->_movements->processActorY + 0x100, _engine->_renderer->destZ) && _engine->cfgfile.WallCollision == 1) { // avoid wall hit damage
+ _engine->_extra->addExtraSpecial(actor->x, actor->y + 1000, actor->z, kHitStars);
initAnim(kBigHit, 2, 0, currentlyProcessedActorIdx);
if (currentlyProcessedActorIdx == 0) {
- heroMoved = 1;
+ _engine->_movements->heroMoved = 1;
}
actor->life--;
@@ -1173,66 +1121,66 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
}
}
- brickShape = getBrickShape(processActorX, processActorY, processActorZ);
+ brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ);
actor->brickShape = brickShape;
if (brickShape) {
if (brickShape == kSolid) {
if (actor->dynamicFlags.bIsFalling) {
- stopFalling();
- processActorY = (collisionY << 8) + 0x100;
+ _engine->_collision->stopFalling();
+ _engine->_movements->processActorY = (_engine->_collision->collisionY << 8) + 0x100;
} else {
- if (!actorIdx && heroBehaviour == kAthletic && actor->anim == brickShape && cfgfile.WallCollision == 1) { // avoid wall hit damage
- addExtraSpecial(actor->X, actor->Y + 1000, actor->Z, kHitStars);
+ if (!actorIdx && _engine->_actor->heroBehaviour == kAthletic && actor->anim == brickShape && _engine->cfgfile.WallCollision == 1) { // avoid wall hit damage
+ _engine->_extra->addExtraSpecial(actor->x, actor->y + 1000, actor->z, kHitStars);
initAnim(kBigHit, 2, 0, currentlyProcessedActorIdx);
if (!actorIdx) {
- heroMoved = 1;
+ _engine->_movements->heroMoved = 1;
}
actor->life--;
}
// no Z coordinate issue
- if (!getBrickShape(processActorX, processActorY, previousActorZ)) {
- processActorZ = previousActorZ;
+ if (!_engine->_grid->getBrickShape(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->previousActorZ)) {
+ _engine->_movements->processActorZ = _engine->_movements->previousActorZ;
}
// no X coordinate issue
- if (!getBrickShape(previousActorX, processActorY, processActorZ)) {
- processActorX = previousActorX;
+ if (!_engine->_grid->getBrickShape(_engine->_movements->previousActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ)) {
+ _engine->_movements->processActorX = _engine->_movements->previousActorX;
}
// X and Z with issue, no move
- if (getBrickShape(processActorX, processActorY, previousActorZ) && getBrickShape(previousActorX, processActorY, processActorZ)) {
+ if (_engine->_grid->getBrickShape(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->previousActorZ) && _engine->_grid->getBrickShape(_engine->_movements->previousActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ)) {
return;
}
}
} else {
if (actor->dynamicFlags.bIsFalling) {
- stopFalling();
+ _engine->_collision->stopFalling();
}
- reajustActorPosition(brickShape);
+ _engine->_collision->reajustActorPosition(brickShape);
}
actor->dynamicFlags.bIsFalling = 0;
} else {
if (actor->staticFlags.bCanFall && actor->standOn == -1) {
- brickShape = getBrickShape(processActorX, processActorY - 1, processActorZ);
+ brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActorX, _engine->_movements->processActorY - 1, _engine->_movements->processActorZ);
if (brickShape) {
if (actor->dynamicFlags.bIsFalling) {
- stopFalling();
+ _engine->_collision->stopFalling();
}
- reajustActorPosition(brickShape);
+ _engine->_collision->reajustActorPosition(brickShape);
} else {
if (!actor->dynamicFlags.bIsRotationByAnim) {
actor->dynamicFlags.bIsFalling = 1;
- if (!actorIdx && heroYBeforeFall == 0) {
- heroYBeforeFall = processActorY;
+ if (!actorIdx && _engine->_scene->heroYBeforeFall == 0) {
+ _engine->_scene->heroYBeforeFall = _engine->_movements->processActorY;
}
initAnim(kFall, 0, 255, actorIdx);
@@ -1242,41 +1190,43 @@ void processActorAnimations(int32 actorIdx) { // DoAnim
}
// if under the map, than die
- if (collisionY == -1) {
+ if (_engine->_collision->collisionY == -1) {
actor->life = 0;
}
} else {
if (actor->staticFlags.bComputeCollisionWithObj) {
- checkCollisionWithActors(actorIdx);
+ _engine->_collision->checkCollisionWithActors(actorIdx);
}
}
- if (causeActorDamage) {
+ if (_engine->_collision->causeActorDamage) {
actor->brickShape |= 0x80;
}
// check and fix actor bounding position
- if (processActorX < 0) {
- processActorX = 0;
+ if (_engine->_movements->processActorX < 0) {
+ _engine->_movements->processActorX = 0;
}
- if (processActorY < 0) {
- processActorY = 0;
+ if (_engine->_movements->processActorY < 0) {
+ _engine->_movements->processActorY = 0;
}
- if (processActorZ < 0) {
- processActorZ = 0;
+ if (_engine->_movements->processActorZ < 0) {
+ _engine->_movements->processActorZ = 0;
}
- if (processActorX > 0x7E00) {
- processActorX = 0x7E00;
+ if (_engine->_movements->processActorX > 0x7E00) {
+ _engine->_movements->processActorX = 0x7E00;
}
- if (processActorZ > 0x7E00) {
- processActorZ = 0x7E00;
+ if (_engine->_movements->processActorZ > 0x7E00) {
+ _engine->_movements->processActorZ = 0x7E00;
}
- actor->X = processActorX;
- actor->Y = processActorY;
- actor->Z = processActorZ;
+ actor->x = _engine->_movements->processActorX;
+ actor->y = _engine->_movements->processActorY;
+ actor->z = _engine->_movements->processActorZ;
}
+
+} // namespace TwinE
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index ff07bac41b..a820681c79 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -1,147 +1,151 @@
-/** @file animations.h
- @brief
- This file contains 3D actors animations routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef ANIMATIONS_H
-#define ANIMATIONS_H
-
-#include "sys.h"
-#include "actor.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_ANIMATIONS_H
+#define TWINE_ANIMATIONS_H
+
+#include "common/scummsys.h"
+#include "twine/actor.h"
+
+namespace TwinE {
/** Total number of animations allowed in the game */
#define NUM_ANIMS 600
-enum AnimationTypes {
- kStanding = 0,
- kForward = 1,
- kBackward = 2,
- kTurnLeft = 3,
- kTurnRight = 4,
- kHit = 5,
- kBigHit = 6,
- kFall = 7,
- kLanding = 8,
- kLandingHit = 9,
- kLandDeath = 10,
- kAction = 11,
- kClimbLadder = 12,
- kTopLadder = 13,
- kJump = 14,
- kThrowBall = 15,
- kHide = 16,
- kKick = 17,
- kRightPunch = 18,
- kLeftPunch = 19,
- kFoundItem = 20,
- kDrawn = 21,
- kHit2 = 22,
- kSabreAttack = 23
+class TwinEEngine;
+
+class Animations {
+private:
+ TwinEEngine *_engine;
+ void applyAnimStepRotation(uint8 **ptr, int32 bp, int32 bx);
+ int32 getAnimMode(uint8 **ptr);
+ void applyAnimStep(uint8 **ptr, int32 bp, int32 bx);
+
+public:
+ Animations(TwinEEngine *engine);
+ /** Table with all loaded animations */
+ uint8 *animTable[NUM_ANIMS]{nullptr};
+ /** Table with all loaded animations sizes */
+ uint32 animSizeTable[NUM_ANIMS]{0};
+
+ /** Rotation by anim and not by engine */
+ int16 processRotationByAnim = 0; // processActorVar5
+ /** Last rotation angle */
+ int16 processLastRotationAngle = 0; // processActorVar6
+ /** Current process actor index */
+ int16 currentlyProcessedActorIdx = 0;
+
+ /** Current step X coornidate */
+ int16 currentStepX = 0;
+ /** Current step Y coornidate */
+ int16 currentStepY = 0;
+ /** Current step Z coornidate */
+ int16 currentStepZ = 0;
+ /** Current actor anim extra pointer */
+ uint8 *currentActorAnimExtraPtr = nullptr;
+
+ /** Pointer to current animation keyframe */
+ uint8 *keyFramePtr = nullptr;
+ /** Pointer to last animation keyframe */
+ uint8 *lastKeyFramePtr = nullptr;
+
+ uint8 *animBuffer1 = nullptr;
+ uint8 *animBuffer2 = nullptr;
+
+ /**
+ * Set animation keyframe
+ * @param keyframIdx Animation keyframe index
+ * @param animPtr Pointer to animation
+ * @param bodyPtr Body model poitner
+ * @param animTimerDataPtr Animation time data
+ */
+ int32 setAnimAtKeyframe(int32 keyframeIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+
+ /**
+ * Get total number of keyframes in animation
+ * @param animPtr Pointer to animation
+ */
+ int32 getNumKeyframes(uint8 *animPtr);
+
+ /**
+ * Get first keyframes in animation
+ * @param animPtr Pointer to animation
+ */
+ int32 getStartKeyframe(uint8 *animPtr);
+
+ /**
+ * Set new body animation
+ * @param animIdx Animation index
+ * @param animPtr Animation pointer
+ * @param bodyPtr Body model poitner
+ * @param animTimerDataPtr Animation time data
+ */
+ int32 setModelAnimation(int32 animIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+
+ /**
+ * Get entity anim index (This is taken from File3D entities)
+ * @param animIdx Entity animation index
+ * @param actorIdx Actor index
+ */
+ int32 getBodyAnimIndex(int32 animIdx, int32 actorIdx);
+
+ /**
+ * Stock animation - copy the next keyFrame from a different buffer
+ * @param animPtr Animation pointer
+ * @param bodyPtr Body model poitner
+ * @param animTimerDataPtr Animation time data
+ */
+ int32 stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+
+ /**
+ * Verify animation at keyframe
+ * @param animIdx Animation index
+ * @param animPtr Animation pointer
+ * @param bodyPtr Body model poitner
+ * @param animTimerDataPtr Animation time data
+ */
+ int32 verifyAnimAtKeyframe(int32 animPos, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+
+ /**
+ * Initialize animation
+ * @param newAnim animation to init
+ * @param animType animation type
+ * @param animExtra animation actions extra data
+ * @param actorIdx actor index
+ */
+ int32 initAnim(AnimationTypes newAnim, int16 animType, uint8 animExtra, int32 actorIdx);
+
+ /**
+ * Process acotr animation actions
+ * @param actorIdx Actor index
+ */
+ void processAnimActions(int32 actorIdx);
+
+ /**
+ * Process main loop actor animations
+ * @param actorIdx Actor index
+ */
+ void processActorAnimations(int32 actorIdx);
};
-
-/** Table with all loaded animations */
-uint8* animTable[NUM_ANIMS];
-/** Table with all loaded animations sizes */
-uint32 animSizeTable[NUM_ANIMS];
-
-/** Rotation by anim and not by engine */
-int16 processRotationByAnim; // processActorVar5
-/** Last rotation angle */
-int16 processLastRotationAngle; // processActorVar6
-/** Current process actor index */
-int16 currentlyProcessedActorIdx;
-
-/** Current step X coornidate */
-int16 currentStepX;
-/** Current step Y coornidate */
-int16 currentStepY;
-/** Current step Z coornidate */
-int16 currentStepZ;
-/** Current actor anim extra pointer */
-uint8 *currentActorAnimExtraPtr;
-
-/** Pointer to current animation keyframe */
-uint8 *keyFramePtr;
-/** Pointer to last animation keyframe */
-uint8 *lastKeyFramePtr;
-
-uint8 *animBuffer1;
-uint8 *animBuffer2;
-
-/** Set animation keyframe
- @param keyframIdx Animation keyframe index
- @param animPtr Pointer to animation
- @param bodyPtr Body model poitner
- @param animTimerDataPtr Animation time data */
-int32 setAnimAtKeyframe(int32 keyframeIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr);
-
-/** Get total number of keyframes in animation
- @param animPtr Pointer to animation */
-int32 getNumKeyframes(uint8 *animPtr);
-
-/** Get first keyframes in animation
- @param animPtr Pointer to animation */
-int32 getStartKeyframe(uint8 *animPtr);
-
-/** Set new body animation
- @param animIdx Animation index
- @param animPtr Animation pointer
- @param bodyPtr Body model poitner
- @param animTimerDataPtr Animation time data */
-int32 setModelAnimation(int32 animIdx, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr);
-
-/** Get entity anim index (This is taken from File3D entities)
- @param animIdx Entity animation index
- @param actorIdx Actor index */
-int32 getBodyAnimIndex(int32 animIdx, int32 actorIdx);
-
-/** Stock animation - copy the next keyFrame from a different buffer
- @param animPtr Animation pointer
- @param bodyPtr Body model poitner
- @param animTimerDataPtr Animation time data */
-int32 stockAnimation(uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr);
-
-/** Verify animation at keyframe
- @param animIdx Animation index
- @param animPtr Animation pointer
- @param bodyPtr Body model poitner
- @param animTimerDataPtr Animation time data */
-int32 verifyAnimAtKeyframe(int32 animPos, uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct* animTimerDataPtr);
-
-/** Initialize animation
- @param newAnim animation to init
- @param animType animation type
- @param animExtra animation actions extra data
- @param actorIdx actor index */
-int32 initAnim(int32 newAnim, int16 animType, uint8 animExtra, int32 actorIdx);
-
-/** Process acotr animation actions
- @param actorIdx Actor index */
-void processAnimActions(int32 actorIdx);
-
-/** Process main loop actor animations
- @param actorIdx Actor index */
-void processActorAnimations(int32 actorIdx);
-
+} // namespace TwinE
#endif
diff --git a/engines/twine/collision.cpp b/engines/twine/collision.cpp
index cf2663add0..d08215f970 100644
--- a/engines/twine/collision.cpp
+++ b/engines/twine/collision.cpp
@@ -1,71 +1,70 @@
-/** @file collision.cpp
- @brief
- This file contains movies routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include <stdio.h>
-
-#include "collision.h"
-#include "scene.h"
-#include "actor.h"
-#include "movements.h"
-#include "grid.h"
-#include "main.h"
-#include "animations.h"
-#include "renderer.h"
-#include "extra.h"
-
-/** Check if actor 1 is standing in actor2
- @param actorIdx1 Actor 1 index
- @param actorIdx2 Actor 2 index */
-int32 standingOnActor(int32 actorIdx1, int32 actorIdx2) { // CheckZvOnZv
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/actor.h"
+#include "twine/animations.h"
+#include "twine/collision.h"
+#include "common/debug.h"
+#include "common/util.h"
+#include "twine/extra.h"
+#include "twine/grid.h"
+#include "twine/movements.h"
+#include "twine/renderer.h"
+#include "twine/scene.h"
+#include "twine/twine.h"
+
+namespace TwinE {
+
+Collision::Collision(TwinEEngine *engine) : _engine(engine) {
+}
+
+int32 Collision::standingOnActor(int32 actorIdx1, int32 actorIdx2) { // CheckZvOnZv
int32 x1Left, y1Left, z1Left, x1Right, y1Right, z1Right;
int32 x2Left, y2Left, z2Left, x2Right, y2Right, z2Right;
ActorStruct *actor1;
ActorStruct *actor2;
- actor1 = &sceneActors[actorIdx1];
- actor2 = &sceneActors[actorIdx2];
+ actor1 = &_engine->_scene->sceneActors[actorIdx1];
+ actor2 = &_engine->_scene->sceneActors[actorIdx2];
// Current actor (actor 1)
- x1Left = processActorX + actor1->boudingBox.X.bottomLeft;
- x1Right = processActorX + actor1->boudingBox.X.topRight;
+ x1Left = _engine->_movements->processActorX + actor1->boudingBox.x.bottomLeft;
+ x1Right = _engine->_movements->processActorX + actor1->boudingBox.x.topRight;
- y1Left = processActorY + actor1->boudingBox.Y.bottomLeft;
- y1Right = processActorY + actor1->boudingBox.Y.topRight;
+ y1Left = _engine->_movements->processActorY + actor1->boudingBox.y.bottomLeft;
+ y1Right = _engine->_movements->processActorY + actor1->boudingBox.y.topRight;
- z1Left = processActorZ + actor1->boudingBox.Z.bottomLeft;
- z1Right = processActorZ + actor1->boudingBox.Z.topRight;
+ z1Left = _engine->_movements->processActorZ + actor1->boudingBox.z.bottomLeft;
+ z1Right = _engine->_movements->processActorZ + actor1->boudingBox.z.topRight;
// Actor 2
- x2Left = actor2->X + actor2->boudingBox.X.bottomLeft;
- x2Right = actor2->X + actor2->boudingBox.X.topRight;
+ x2Left = actor2->x + actor2->boudingBox.x.bottomLeft;
+ x2Right = actor2->x + actor2->boudingBox.x.topRight;
- y2Left = actor2->Y + actor2->boudingBox.Y.bottomLeft;
- y2Right = actor2->Y + actor2->boudingBox.Y.topRight;
+ y2Left = actor2->y + actor2->boudingBox.y.bottomLeft;
+ y2Right = actor2->y + actor2->boudingBox.y.topRight;
- z2Left = actor2->Z + actor2->boudingBox.Z.bottomLeft;
- z2Right = actor2->Z + actor2->boudingBox.Z.topRight;
+ z2Left = actor2->z + actor2->boudingBox.z.bottomLeft;
+ z2Right = actor2->z + actor2->boudingBox.z.topRight;
if (x1Left >= x2Right)
return 0; // not standing
@@ -91,7 +90,7 @@ int32 standingOnActor(int32 actorIdx1, int32 actorIdx2) { // CheckZvOnZv
return 1; // standing
}
-int32 getAverageValue(int32 var0, int32 var1, int32 var2, int32 var3) {
+int32 Collision::getAverageValue(int32 var0, int32 var1, int32 var2, int32 var3) {
if (var3 <= 0) {
return var0;
}
@@ -100,12 +99,10 @@ int32 getAverageValue(int32 var0, int32 var1, int32 var2, int32 var3) {
return var1;
}
- return ((((var1 - var0) * var3) / var2) + var0);
+ return ((((var1 - var0) * var3) / var2) + var0);
}
-/** Reajust actor position in scene according with brick shape bellow actor
- @param brickShape Shape of brick bellow the actor */
-void reajustActorPosition(int32 brickShape) {
+void Collision::reajustActorPosition(int32 brickShape) {
int32 brkX, brkY, brkZ;
if (!brickShape) {
@@ -120,64 +117,64 @@ void reajustActorPosition(int32 brickShape) {
if (brickShape >= kDoubleSideStairsTop1 && brickShape <= kDoubleSideStairsRight2) {
switch (brickShape) {
case kDoubleSideStairsTop1:
- if (processActorZ - collisionZ <= processActorX - collisionX) {
+ if (_engine->_movements->processActorZ - collisionZ <= _engine->_movements->processActorX - collisionX) {
brickShape = kStairsTopLeft;
} else {
brickShape = kStairsTopRight;
}
break;
case kDoubleSideStairsBottom1:
- if (processActorZ - collisionZ <= processActorX - collisionX) {
+ if (_engine->_movements->processActorZ - collisionZ <= _engine->_movements->processActorX - collisionX) {
brickShape = kStairsBottomLeft;
} else {
brickShape = kStairsBottomRight;
}
break;
case kDoubleSideStairsLeft1:
- if (512 - processActorX - collisionX <= processActorZ - collisionZ) {
+ if (512 - _engine->_movements->processActorX - collisionX <= _engine->_movements->processActorZ - collisionZ) {
brickShape = kStairsTopLeft;
} else {
brickShape = kStairsBottomLeft;
}
break;
case kDoubleSideStairsRight1:
- if (512 - processActorX - collisionX <= processActorZ - collisionZ) {
+ if (512 - _engine->_movements->processActorX - collisionX <= _engine->_movements->processActorZ - collisionZ) {
brickShape = kStairsTopRight;
} else {
brickShape = kStairsBottomRight;
}
break;
case kDoubleSideStairsTop2:
- if (processActorX - collisionX >= processActorZ - collisionZ) {
+ if (_engine->_movements->processActorX - collisionX >= _engine->_movements->processActorZ - collisionZ) {
brickShape = kStairsTopRight;
} else {
brickShape = kStairsTopLeft;
}
break;
case kDoubleSideStairsBottom2:
- if (processActorZ - collisionZ <= processActorX - collisionX) {
+ if (_engine->_movements->processActorZ - collisionZ <= _engine->_movements->processActorX - collisionX) {
brickShape = kStairsBottomRight;
} else {
brickShape = kStairsBottomLeft;
}
break;
case kDoubleSideStairsLeft2:
- if (512 - processActorX - collisionX <= processActorZ - collisionZ) {
+ if (512 - _engine->_movements->processActorX - collisionX <= _engine->_movements->processActorZ - collisionZ) {
brickShape = kStairsBottomLeft;
} else {
brickShape = kStairsTopLeft;
}
break;
case kDoubleSideStairsRight2:
- if (512 - processActorX - collisionX <= processActorZ - collisionZ) {
+ if (512 - _engine->_movements->processActorX - collisionX <= _engine->_movements->processActorZ - collisionZ) {
brickShape = kStairsBottomRight;
} else {
brickShape = kStairsTopRight;
}
break;
default:
- if (cfgfile.Debug == 1) {
- printf("Brick Shape %d unsupported\n", brickShape);
+ if (_engine->cfgfile.Debug == 1) {
+ debug("Brick Shape %d unsupported\n", brickShape);
}
break;
}
@@ -186,16 +183,16 @@ void reajustActorPosition(int32 brickShape) {
if (brickShape >= kStairsTopLeft && brickShape <= kStairsBottomRight) {
switch (brickShape) {
case kStairsTopLeft:
- processActorY = brkY + getAverageValue(0, 0x100, 0x200, processActorX - brkX);
+ _engine->_movements->processActorY = brkY + getAverageValue(0, 0x100, 0x200, _engine->_movements->processActorX - brkX);
break;
case kStairsTopRight:
- processActorY = brkY + getAverageValue(0, 0x100, 0x200, processActorZ - brkZ);
+ _engine->_movements->processActorY = brkY + getAverageValue(0, 0x100, 0x200, _engine->_movements->processActorZ - brkZ);
break;
case kStairsBottomLeft:
- processActorY = brkY + getAverageValue(0x100, 0, 0x200, processActorZ - brkZ);
+ _engine->_movements->processActorY = brkY + getAverageValue(0x100, 0, 0x200, _engine->_movements->processActorZ - brkZ);
break;
case kStairsBottomRight:
- processActorY = brkY + getAverageValue(0x100, 0, 0x200, processActorX - brkX);
+ _engine->_movements->processActorY = brkY + getAverageValue(0x100, 0, 0x200, _engine->_movements->processActorX - brkX);
break;
default:
break;
@@ -203,56 +200,54 @@ void reajustActorPosition(int32 brickShape) {
}
}
-/** Check collision with actors
- @param actorIx Current process actor index */
-int32 checkCollisionWithActors(int32 actorIdx) {
+int32 Collision::checkCollisionWithActors(int32 actorIdx) {
int32 a, xLeft, xRight, yLeft, yRight, zLeft, zRight;
ActorStruct *actor, *actorTest;
- actor = &sceneActors[actorIdx];
+ actor = &_engine->_scene->sceneActors[actorIdx];
- xLeft = processActorX + actor->boudingBox.X.bottomLeft;
- xRight = processActorX + actor->boudingBox.X.topRight;
+ xLeft = _engine->_movements->processActorX + actor->boudingBox.x.bottomLeft;
+ xRight = _engine->_movements->processActorX + actor->boudingBox.x.topRight;
- yLeft = processActorY + actor->boudingBox.Y.bottomLeft;
- yRight = processActorY + actor->boudingBox.Y.topRight;
+ yLeft = _engine->_movements->processActorY + actor->boudingBox.y.bottomLeft;
+ yRight = _engine->_movements->processActorY + actor->boudingBox.y.topRight;
- zLeft = processActorZ + actor->boudingBox.Z.bottomLeft;
- zRight = processActorZ + actor->boudingBox.Z.topRight;
+ zLeft = _engine->_movements->processActorZ + actor->boudingBox.z.bottomLeft;
+ zRight = _engine->_movements->processActorZ + actor->boudingBox.z.topRight;
actor->collision = -1;
- for (a = 0; a < sceneNumActors; a++) {
- actorTest = &sceneActors[a];
+ for (a = 0; a < _engine->_scene->sceneNumActors; a++) {
+ actorTest = &_engine->_scene->sceneActors[a];
// aviod current processed actor
if (a != actorIdx && actorTest->entity != -1 && !actor->staticFlags.bComputeLowCollision && actorTest->standOn != actorIdx) {
int32 xLeftTest, xRightTest, yLeftTest, yRightTest, zLeftTest, zRightTest;
- xLeftTest = actorTest->X + actorTest->boudingBox.X.bottomLeft;
- xRightTest = actorTest->X + actorTest->boudingBox.X.topRight;
+ xLeftTest = actorTest->x + actorTest->boudingBox.x.bottomLeft;
+ xRightTest = actorTest->x + actorTest->boudingBox.x.topRight;
- yLeftTest = actorTest->Y + actorTest->boudingBox.Y.bottomLeft;
- yRightTest = actorTest->Y + actorTest->boudingBox.Y.topRight;
+ yLeftTest = actorTest->y + actorTest->boudingBox.y.bottomLeft;
+ yRightTest = actorTest->y + actorTest->boudingBox.y.topRight;
- zLeftTest = actorTest->Z + actorTest->boudingBox.Z.bottomLeft;
- zRightTest = actorTest->Z + actorTest->boudingBox.Z.topRight;
+ zLeftTest = actorTest->z + actorTest->boudingBox.z.bottomLeft;
+ zRightTest = actorTest->z + actorTest->boudingBox.z.topRight;
if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
actor->collision = a; // mark as collision with actor a
if (actorTest->staticFlags.bIsCarrierActor) {
if (actor->dynamicFlags.bIsFalling) {
- processActorY = yRightTest - actor->boudingBox.Y.bottomLeft + 1;
+ _engine->_movements->processActorY = yRightTest - actor->boudingBox.y.bottomLeft + 1;
actor->standOn = a;
} else {
if (standingOnActor(actorIdx, a)) {
- processActorY = yRightTest - actor->boudingBox.Y.bottomLeft + 1;
+ _engine->_movements->processActorY = yRightTest - actor->boudingBox.y.bottomLeft + 1;
actor->standOn = a;
} else {
int32 newAngle;
- newAngle = getAngleAndSetTargetActorDistance(processActorX, processActorZ, actorTest->X, actorTest->Z);
+ newAngle = _engine->_movements->getAngleAndSetTargetActorDistance(_engine->_movements->processActorX, _engine->_movements->processActorZ, actorTest->x, actorTest->z);
if (actorTest->staticFlags.bCanBePushed && !actor->staticFlags.bCanBePushed) {
actorTest->lastY = 0;
@@ -271,30 +266,30 @@ int32 checkCollisionWithActors(int32 actorIdx) {
actorTest->lastX = 192;
}
} else {
- actorTest->lastX = processActorX - actor->collisionX;
- actorTest->lastZ = processActorZ - actor->collisionZ;
+ actorTest->lastX = _engine->_movements->processActorX - actor->collisionX;
+ actorTest->lastZ = _engine->_movements->processActorZ - actor->collisionZ;
}
}
- if ((actorTest->boudingBox.X.topRight - actorTest->boudingBox.X.bottomLeft == actorTest->boudingBox.Z.topRight - actorTest->boudingBox.Z.bottomLeft) &&
- (actor->boudingBox.X.topRight - actor->boudingBox.X.bottomLeft == actor->boudingBox.Z.topRight - actor->boudingBox.Z.bottomLeft)) {
+ if ((actorTest->boudingBox.x.topRight - actorTest->boudingBox.x.bottomLeft == actorTest->boudingBox.z.topRight - actorTest->boudingBox.z.bottomLeft) &&
+ (actor->boudingBox.x.topRight - actor->boudingBox.x.bottomLeft == actor->boudingBox.z.topRight - actor->boudingBox.z.bottomLeft)) {
if (newAngle < 0x180) {
- processActorX = xLeftTest - actor->boudingBox.X.topRight;
+ _engine->_movements->processActorX = xLeftTest - actor->boudingBox.x.topRight;
}
if (newAngle >= 0x180 && newAngle < 0x280) {
- processActorZ = zRightTest - actor->boudingBox.Z.bottomLeft;
+ _engine->_movements->processActorZ = zRightTest - actor->boudingBox.z.bottomLeft;
}
if (newAngle >= 0x280 && newAngle < 0x380) {
- processActorX = xRightTest - actor->boudingBox.X.bottomLeft;
+ _engine->_movements->processActorX = xRightTest - actor->boudingBox.x.bottomLeft;
}
if (newAngle >= 0x380 || (newAngle < 0x380 && newAngle < 0x80)) {
- processActorZ = zLeftTest - actor->boudingBox.Z.topRight;
+ _engine->_movements->processActorZ = zLeftTest - actor->boudingBox.z.topRight;
}
} else {
if (!actor->dynamicFlags.bIsFalling) {
- processActorX = previousActorX;
- processActorY = previousActorY;
- processActorZ = previousActorZ;
+ _engine->_movements->processActorX = _engine->_movements->previousActorX;
+ _engine->_movements->processActorY = _engine->_movements->previousActorY;
+ _engine->_movements->processActorZ = _engine->_movements->previousActorZ;
}
}
}
@@ -303,10 +298,10 @@ int32 checkCollisionWithActors(int32 actorIdx) {
int32 newAngle;
if (standingOnActor(actorIdx, a)) {
- hitActor(actorIdx, a, 1, -1);
+ _engine->_actor->hitActor(actorIdx, a, 1, -1);
}
- newAngle = getAngleAndSetTargetActorDistance(processActorX, processActorZ, actorTest->X, actorTest->Z);
+ newAngle = _engine->_movements->getAngleAndSetTargetActorDistance(_engine->_movements->processActorX, _engine->_movements->processActorZ, actorTest->x, actorTest->z);
if (actorTest->staticFlags.bCanBePushed && !actor->staticFlags.bCanBePushed) {
actorTest->lastY = 0;
@@ -325,30 +320,30 @@ int32 checkCollisionWithActors(int32 actorIdx) {
actorTest->lastX = 192;
}
} else {
- actorTest->lastX = processActorX - actor->collisionX;
- actorTest->lastZ = processActorZ - actor->collisionZ;
+ actorTest->lastX = _engine->_movements->processActorX - actor->collisionX;
+ actorTest->lastZ = _engine->_movements->processActorZ - actor->collisionZ;
}
}
- if ((actorTest->boudingBox.X.topRight - actorTest->boudingBox.X.bottomLeft == actorTest->boudingBox.Z.topRight - actorTest->boudingBox.Z.bottomLeft) &&
- (actor->boudingBox.X.topRight - actor->boudingBox.X.bottomLeft == actor->boudingBox.Z.topRight - actor->boudingBox.Z.bottomLeft)) {
+ if ((actorTest->boudingBox.x.topRight - actorTest->boudingBox.x.bottomLeft == actorTest->boudingBox.z.topRight - actorTest->boudingBox.z.bottomLeft) &&
+ (actor->boudingBox.x.topRight - actor->boudingBox.x.bottomLeft == actor->boudingBox.z.topRight - actor->boudingBox.z.bottomLeft)) {
if (newAngle < 0x180) {
- processActorX = xLeftTest - actor->boudingBox.X.topRight;
+ _engine->_movements->processActorX = xLeftTest - actor->boudingBox.x.topRight;
}
if (newAngle >= 0x180 && newAngle < 0x280) {
- processActorZ = zRightTest - actor->boudingBox.Z.bottomLeft;
+ _engine->_movements->processActorZ = zRightTest - actor->boudingBox.z.bottomLeft;
}
if (newAngle >= 0x280 && newAngle < 0x380) {
- processActorX = xRightTest - actor->boudingBox.X.bottomLeft;
+ _engine->_movements->processActorX = xRightTest - actor->boudingBox.x.bottomLeft;
}
if (newAngle >= 0x380 || (newAngle < 0x380 && newAngle < 0x80)) {
- processActorZ = zLeftTest - actor->boudingBox.Z.topRight;
+ _engine->_movements->processActorZ = zLeftTest - actor->boudingBox.z.topRight;
}
} else {
if (!actor->dynamicFlags.bIsFalling) {
- processActorX = previousActorX;
- processActorY = previousActorY;
- processActorZ = previousActorZ;
+ _engine->_movements->processActorX = _engine->_movements->previousActorX;
+ _engine->_movements->processActorY = _engine->_movements->previousActorY;
+ _engine->_movements->processActorZ = _engine->_movements->previousActorZ;
}
}
}
@@ -357,35 +352,35 @@ int32 checkCollisionWithActors(int32 actorIdx) {
}
if (actor->dynamicFlags.bIsHitting) {
- rotateActor(0, 200, actor->angle);
+ _engine->_movements->rotateActor(0, 200, actor->angle);
- xLeft = destX + processActorX + actor->boudingBox.X.bottomLeft;
- xRight = destX + processActorX + actor->boudingBox.X.topRight;
+ xLeft = _engine->_renderer->destX + _engine->_movements->processActorX + actor->boudingBox.x.bottomLeft;
+ xRight = _engine->_renderer->destX + _engine->_movements->processActorX + actor->boudingBox.x.topRight;
- yLeft = processActorY + actor->boudingBox.Y.bottomLeft;
- yRight = processActorY + actor->boudingBox.Y.topRight;
+ yLeft = _engine->_movements->processActorY + actor->boudingBox.y.bottomLeft;
+ yRight = _engine->_movements->processActorY + actor->boudingBox.y.topRight;
- zLeft = destZ + processActorZ + actor->boudingBox.Z.bottomLeft;
- zRight = destZ + processActorZ + actor->boudingBox.Z.topRight;
+ zLeft = _engine->_renderer->destZ + _engine->_movements->processActorZ + actor->boudingBox.z.bottomLeft;
+ zRight = _engine->_renderer->destZ + _engine->_movements->processActorZ + actor->boudingBox.z.topRight;
- for (a = 0; a < sceneNumActors; a++) {
- actorTest = &sceneActors[a];
+ for (a = 0; a < _engine->_scene->sceneNumActors; a++) {
+ actorTest = &_engine->_scene->sceneActors[a];
// aviod current processed actor
if (a != actorIdx && actorTest->entity != -1 && !actorTest->staticFlags.bIsHidden && actorTest->standOn != actorIdx) {
int32 xLeftTest, xRightTest, yLeftTest, yRightTest, zLeftTest, zRightTest;
- xLeftTest = actorTest->X + actorTest->boudingBox.X.bottomLeft;
- xRightTest = actorTest->X + actorTest->boudingBox.X.topRight;
+ xLeftTest = actorTest->x + actorTest->boudingBox.x.bottomLeft;
+ xRightTest = actorTest->x + actorTest->boudingBox.x.topRight;
- yLeftTest = actorTest->Y + actorTest->boudingBox.Y.bottomLeft;
- yRightTest = actorTest->Y + actorTest->boudingBox.Y.topRight;
+ yLeftTest = actorTest->y + actorTest->boudingBox.y.bottomLeft;
+ yRightTest = actorTest->y + actorTest->boudingBox.y.topRight;
- zLeftTest = actorTest->Z + actorTest->boudingBox.Z.bottomLeft;
- zRightTest = actorTest->Z + actorTest->boudingBox.Z.topRight;
+ zLeftTest = actorTest->z + actorTest->boudingBox.z.bottomLeft;
+ zRightTest = actorTest->z + actorTest->boudingBox.z.topRight;
if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
- hitActor(actorIdx, a, actor->strengthOfHit, actor->angle + 0x200);
+ _engine->_actor->hitActor(actorIdx, a, actor->strengthOfHit, actor->angle + 0x200);
actor->dynamicFlags.bIsHitting = 0;
}
}
@@ -395,151 +390,137 @@ int32 checkCollisionWithActors(int32 actorIdx) {
return actor->collision;
}
-/** Check Hero collision with bricks
- @param X Hero X coordinate
- @param Y Hero Y coordinate
- @param Z Hero Z coordinate
- @param damageMask Cause damage mask */
-void checkHeroCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask) {
+void Collision::checkHeroCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask) {
int32 brickShape;
- brickShape = getBrickShape(processActorX, processActorY, processActorZ);
+ brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ);
- processActorX += X;
- processActorY += Y;
- processActorZ += Z;
+ _engine->_movements->processActorX += X;
+ _engine->_movements->processActorY += Y;
+ _engine->_movements->processActorZ += Z;
- if (processActorX >= 0 && processActorZ >= 0 && processActorX <= 0x7E00 && processActorZ <= 0x7E00) {
+ if (_engine->_movements->processActorX >= 0 && _engine->_movements->processActorZ >= 0 && _engine->_movements->processActorX <= 0x7E00 && _engine->_movements->processActorZ <= 0x7E00) {
reajustActorPosition(brickShape);
- brickShape = getBrickShapeFull(processActorX, processActorY, processActorZ, processActorPtr->boudingBox.Y.topRight);
+ brickShape = _engine->_grid->getBrickShapeFull(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ, _engine->_movements->processActorPtr->boudingBox.y.topRight);
if (brickShape == kSolid) {
causeActorDamage |= damageMask;
- brickShape = getBrickShapeFull(processActorX, processActorY, previousActorZ + Z, processActorPtr->boudingBox.Y.topRight);
+ brickShape = _engine->_grid->getBrickShapeFull(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->previousActorZ + Z, _engine->_movements->processActorPtr->boudingBox.y.topRight);
if (brickShape == kSolid) {
- brickShape = getBrickShapeFull(X + previousActorX, processActorY, processActorZ, processActorPtr->boudingBox.Y.topRight);
+ brickShape = _engine->_grid->getBrickShapeFull(X + _engine->_movements->previousActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ, _engine->_movements->processActorPtr->boudingBox.y.topRight);
if (brickShape != kSolid) {
- processCollisionX = previousActorX;
+ processCollisionX = _engine->_movements->previousActorX;
}
} else {
- processCollisionZ = previousActorZ;
+ processCollisionZ = _engine->_movements->previousActorZ;
}
}
}
- processActorX = processCollisionX;
- processActorY = processCollisionY;
- processActorZ = processCollisionZ;
+ _engine->_movements->processActorX = processCollisionX;
+ _engine->_movements->processActorY = processCollisionY;
+ _engine->_movements->processActorZ = processCollisionZ;
}
-/** Check other actor collision with bricks
- @param X Actor X coordinate
- @param Y Actor Y coordinate
- @param Z Actor Z coordinate
- @param damageMask Cause damage mask */
-void checkActorCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask) {
+void Collision::checkActorCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask) {
int32 brickShape;
- brickShape = getBrickShape(processActorX, processActorY, processActorZ);
+ brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ);
- processActorX += X;
- processActorY += Y;
- processActorZ += Z;
+ _engine->_movements->processActorX += X;
+ _engine->_movements->processActorY += Y;
+ _engine->_movements->processActorZ += Z;
- if (processActorX >= 0 && processActorZ >= 0 && processActorX <= 0x7E00 && processActorZ <= 0x7E00) {
+ if (_engine->_movements->processActorX >= 0 && _engine->_movements->processActorZ >= 0 && _engine->_movements->processActorX <= 0x7E00 && _engine->_movements->processActorZ <= 0x7E00) {
reajustActorPosition(brickShape);
- brickShape = getBrickShape(processActorX, processActorY, processActorZ);
+ brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ);
if (brickShape == kSolid) {
causeActorDamage |= damageMask;
- brickShape = getBrickShape(processActorX, processActorY, previousActorZ + Z);
+ brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActorX, _engine->_movements->processActorY, _engine->_movements->previousActorZ + Z);
if (brickShape == kSolid) {
- brickShape = getBrickShape(X + previousActorX, processActorY, processActorZ);
+ brickShape = _engine->_grid->getBrickShape(X + _engine->_movements->previousActorX, _engine->_movements->processActorY, _engine->_movements->processActorZ);
if (brickShape != kSolid) {
- processCollisionX = previousActorX;
+ processCollisionX = _engine->_movements->previousActorX;
}
} else {
- processCollisionZ = previousActorZ;
+ processCollisionZ = _engine->_movements->previousActorZ;
}
}
}
- processActorX = processCollisionX;
- processActorY = processCollisionY;
- processActorZ = processCollisionZ;
+ _engine->_movements->processActorX = processCollisionX;
+ _engine->_movements->processActorY = processCollisionY;
+ _engine->_movements->processActorZ = processCollisionZ;
}
-/** Make actor to stop falling */
-void stopFalling() { // ReceptionObj()
+void Collision::stopFalling() { // ReceptionObj()
int32 fall;
- if (currentlyProcessedActorIdx == 0) {
- fall = heroYBeforeFall - processActorY;
+ if (_engine->_animations->currentlyProcessedActorIdx == 0) {
+ fall = _engine->_scene->heroYBeforeFall - _engine->_movements->processActorY;
if (fall >= 0x1000) {
- addExtraSpecial(processActorPtr->X, processActorPtr->Y + 1000, processActorPtr->Z, kHitStars);
- processActorPtr->life--;
- initAnim(kLandingHit, 2, 0, currentlyProcessedActorIdx);
+ _engine->_extra->addExtraSpecial(_engine->_movements->processActorPtr->x, _engine->_movements->processActorPtr->y + 1000, _engine->_movements->processActorPtr->z, kHitStars);
+ _engine->_movements->processActorPtr->life--;
+ _engine->_animations->initAnim(kLandingHit, 2, 0, _engine->_animations->currentlyProcessedActorIdx);
} else if (fall >= 0x800) {
- addExtraSpecial(processActorPtr->X, processActorPtr->Y + 1000, processActorPtr->Z, kHitStars);
- processActorPtr->life--;
- initAnim(kLandingHit, 2, 0, currentlyProcessedActorIdx);
+ _engine->_extra->addExtraSpecial(_engine->_movements->processActorPtr->x, _engine->_movements->processActorPtr->y + 1000, _engine->_movements->processActorPtr->z, kHitStars);
+ _engine->_movements->processActorPtr->life--;
+ _engine->_animations->initAnim(kLandingHit, 2, 0, _engine->_animations->currentlyProcessedActorIdx);
} else if (fall > 10) {
- initAnim(kLanding, 2, 0, currentlyProcessedActorIdx);
+ _engine->_animations->initAnim(kLanding, 2, 0, _engine->_animations->currentlyProcessedActorIdx);
} else {
- initAnim(kStanding, 0, 0, currentlyProcessedActorIdx);
+ _engine->_animations->initAnim(kStanding, 0, 0, _engine->_animations->currentlyProcessedActorIdx);
}
- heroYBeforeFall = 0;
+ _engine->_scene->heroYBeforeFall = 0;
} else {
- initAnim(kLanding, 2, processActorPtr->animExtra, currentlyProcessedActorIdx);
+ _engine->_animations->initAnim(kLanding, 2, _engine->_movements->processActorPtr->animExtra, _engine->_animations->currentlyProcessedActorIdx);
}
- processActorPtr->dynamicFlags.bIsFalling = 0;
+ _engine->_movements->processActorPtr->dynamicFlags.bIsFalling = 0;
}
-/** Check extra collision with actors
- @param extra to process
- @param actorIdx actor to check collision */
-int32 checkExtraCollisionWithActors(ExtraListStruct* extra, int32 actorIdx) {
+int32 Collision::checkExtraCollisionWithActors(ExtraListStruct *extra, int32 actorIdx) {
int32 a;
int32 xLeft, xRight, yLeft, yRight, zLeft, zRight;
- int16 * spriteBounding;
+ int16 *spriteBounding;
ActorStruct *actorTest;
- spriteBounding = (int16*)(spriteBoundingBoxPtr + extra->info0 * 16 + 4);
+ spriteBounding = (int16 *)(_engine->_scene->spriteBoundingBoxPtr + extra->info0 * 16 + 4);
- xLeft = *(spriteBounding++) + extra->X;
- xRight = *(spriteBounding++) + extra->X;
+ xLeft = *(spriteBounding++) + extra->x;
+ xRight = *(spriteBounding++) + extra->x;
- yLeft = *(spriteBounding++) + extra->Y;
- yRight = *(spriteBounding++) + extra->Y;
+ yLeft = *(spriteBounding++) + extra->y;
+ yRight = *(spriteBounding++) + extra->y;
- zLeft = *(spriteBounding++) + extra->Z;
- zRight = *(spriteBounding++) + extra->Z;
+ zLeft = *(spriteBounding++) + extra->z;
+ zRight = *(spriteBounding++) + extra->z;
- for (a = 0; a < sceneNumActors; a++) {
- actorTest = &sceneActors[a];
+ for (a = 0; a < _engine->_scene->sceneNumActors; a++) {
+ actorTest = &_engine->_scene->sceneActors[a];
if (a != actorIdx && actorTest->entity != -1) {
int32 xLeftTest, xRightTest, yLeftTest, yRightTest, zLeftTest, zRightTest;
- xLeftTest = actorTest->X + actorTest->boudingBox.X.bottomLeft;
- xRightTest = actorTest->X + actorTest->boudingBox.X.topRight;
+ xLeftTest = actorTest->x + actorTest->boudingBox.x.bottomLeft;
+ xRightTest = actorTest->x + actorTest->boudingBox.x.topRight;
- yLeftTest = actorTest->Y + actorTest->boudingBox.Y.bottomLeft;
- yRightTest = actorTest->Y + actorTest->boudingBox.Y.topRight;
+ yLeftTest = actorTest->y + actorTest->boudingBox.y.bottomLeft;
+ yRightTest = actorTest->y + actorTest->boudingBox.y.topRight;
- zLeftTest = actorTest->Z + actorTest->boudingBox.Z.bottomLeft;
- zRightTest = actorTest->Z + actorTest->boudingBox.Z.topRight;
+ zLeftTest = actorTest->z + actorTest->boudingBox.z.bottomLeft;
+ zRightTest = actorTest->z + actorTest->boudingBox.z.topRight;
if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
if (extra->strengthOfHit != 0) {
- hitActor(actorIdx, a, extra->strengthOfHit, -1);
+ _engine->_actor->hitActor(actorIdx, a, extra->strengthOfHit, -1);
}
return a;
@@ -550,75 +531,73 @@ int32 checkExtraCollisionWithActors(ExtraListStruct* extra, int32 actorIdx) {
return -1;
}
-/** Check extra collision with bricks */
-int32 checkExtraCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 oldX, int32 oldY, int32 oldZ) {
+int32 Collision::checkExtraCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 oldX, int32 oldY, int32 oldZ) {
int32 averageX, averageY, averageZ;
- if (getBrickShape(oldX, oldY, oldZ)) {
+ if (_engine->_grid->getBrickShape(oldX, oldY, oldZ)) {
return 1;
}
- averageX = Abs(X + oldX)/2;
- averageY = Abs(Y + oldY)/2;
- averageZ = Abs(Z + oldZ)/2;
+ averageX = ABS(X + oldX) / 2;
+ averageY = ABS(Y + oldY) / 2;
+ averageZ = ABS(Z + oldZ) / 2;
- if (getBrickShape(averageX, averageY, averageZ)) {
+ if (_engine->_grid->getBrickShape(averageX, averageY, averageZ)) {
return 1;
}
- if (getBrickShape(Abs(oldX + averageX)/2, Abs(oldY + averageY)/2, Abs(oldZ + averageZ)/2)) {
+ if (_engine->_grid->getBrickShape(ABS(oldX + averageX) / 2, ABS(oldY + averageY) / 2, ABS(oldZ + averageZ) / 2)) {
return 1;
}
- if (getBrickShape(Abs(X + averageX)/2, Abs(Y + averageY)/2, Abs(Z + averageZ)/2)) {
+ if (_engine->_grid->getBrickShape(ABS(X + averageX) / 2, ABS(Y + averageY) / 2, ABS(Z + averageZ) / 2)) {
return 1;
}
return 0;
}
-/** Check extra collision with another extra
- @param extra to process
- @param extraIdx extra index to check collision */
-int32 checkExtraCollisionWithExtra(ExtraListStruct* extra, int32 extraIdx) {
+int32 Collision::checkExtraCollisionWithExtra(ExtraListStruct *extra, int32 extraIdx) {
int32 i;
int32 xLeft, xRight, yLeft, yRight, zLeft, zRight;
- int16 * spriteBounding;
+ int16 *spriteBounding;
- spriteBounding = (int16*)(spriteBoundingBoxPtr + extra->info0 * 16 + 4);
+ spriteBounding = (int16 *)(_engine->_scene->spriteBoundingBoxPtr + extra->info0 * 16 + 4);
- xLeft = *(spriteBounding++) + extra->X;
- xRight = *(spriteBounding++) + extra->X;
+ xLeft = *(spriteBounding++) + extra->x;
+ xRight = *(spriteBounding++) + extra->x;
- yLeft = *(spriteBounding++) + extra->Y;
- yRight = *(spriteBounding++) + extra->Y;
+ yLeft = *(spriteBounding++) + extra->y;
+ yRight = *(spriteBounding++) + extra->y;
- zLeft = *(spriteBounding++) + extra->Z;
- zRight = *(spriteBounding++) + extra->Z;
+ zLeft = *(spriteBounding++) + extra->z;
+ zRight = *(spriteBounding++) + extra->z;
- for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
- ExtraListStruct *extraTest = &extraList[i];
- if ( i != extraIdx && extraTest->info0 != -1) {
+ for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ ExtraListStruct *extraTest = &_engine->_extra->extraList[i];
+ if (i != extraIdx && extraTest->info0 != -1) {
int32 xLeftTest, xRightTest, yLeftTest, yRightTest, zLeftTest, zRightTest;
-// int16 * spriteBoundingTest;
-// spriteBoundingTest = (int16*)(spriteBoundingBoxPtr + extraTest->info0 * 16 + 4);
+ // int16 * spriteBoundingTest;
+ // spriteBoundingTest = (int16*)(_engine->_scene->spriteBoundingBoxPtr + extraTest->info0 * 16 + 4);
- xLeftTest = *(spriteBounding++) + extraTest->X;
- xRightTest = *(spriteBounding++) + extraTest->X;
+ xLeftTest = *(spriteBounding++) + extraTest->x;
+ xRightTest = *(spriteBounding++) + extraTest->x;
- yLeftTest = *(spriteBounding++) + extraTest->Y;
- yRightTest = *(spriteBounding++) + extraTest->Y;
+ yLeftTest = *(spriteBounding++) + extraTest->y;
+ yRightTest = *(spriteBounding++) + extraTest->y;
- zLeftTest = *(spriteBounding++) + extraTest->Z;
- zRightTest = *(spriteBounding++) + extraTest->Z;
+ zLeftTest = *(spriteBounding++) + extraTest->z;
+ zRightTest = *(spriteBounding++) + extraTest->z;
- if (xLeft < xLeftTest) {
- if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
- return i;
- }
- }
+ if (xLeft < xLeftTest) {
+ if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
+ return i;
+ }
+ }
}
}
return -1;
}
+
+} // namespace TwinE
diff --git a/engines/twine/collision.h b/engines/twine/collision.h
index 3b802dd205..d0c006fbdd 100644
--- a/engines/twine/collision.h
+++ b/engines/twine/collision.h
@@ -1,94 +1,116 @@
-/** @file collision.h
- @brief
- This file contains movies routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef COLLISION_H
-#define COLLISION_H
-
-#include "sys.h"
-#include "extra.h"
-
-/** Actor collition X coordinate */
-int32 collisionX; // getPosVar1
-/** Actor collition Y coordinate */
-int32 collisionY; // getPosVar2
-/** Actor collition Z coordinate */
-int32 collisionZ; // getPosVar3
-
-/** Actor collition X coordinate */
-int32 processCollisionX; // processActorVar11
-/** Actor collition Y coordinate */
-int32 processCollisionY; // processActorVar12
-/** Actor collition Z coordinate */
-int32 processCollisionZ; // processActorVar13
-
-/** Cause damage in current processed actor */
-int32 causeActorDamage; //fieldCauseDamage
-
-/** Check if actor 1 is standing in actor2
- @param actorIdx1 Actor 1 index
- @param actorIdx2 Actor 2 index */
-int32 standingOnActor(int32 actorIdx1, int32 actorIdx2);
-
-int32 getAverageValue(int32 var0, int32 var1, int32 var2, int32 var3);
-
-/** Reajust actor position in scene according with brick shape bellow actor
- @param brickShape Shape of brick bellow the actor */
-void reajustActorPosition(int32 brickShape);
-
-/** Check collision with actors
- @param actorIx Current process actor index */
-int32 checkCollisionWithActors(int32 actorIdx);
-
-/** Check Hero collision with bricks
- @param X Hero X coordinate
- @param Y Hero Y coordinate
- @param Z Hero Z coordinate
- @param damageMask Cause damage mask */
-void checkHeroCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask);
-
-/** Check other actor collision with bricks
- @param X Actor X coordinate
- @param Y Actor Y coordinate
- @param Z Actor Z coordinate
- @param damageMask Cause damage mask */
-void checkActorCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask);
-
-/** Make actor to stop falling */
-void stopFalling();
-
-/** Check extra collision with actors
- @param extra to process
- @param actorIdx actor to check collision */
-int32 checkExtraCollisionWithActors(ExtraListStruct* extra, int32 actorIdx);
-
-/** Check extra collision with bricks */
-int32 checkExtraCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 oldX, int32 oldY, int32 oldZ);
-
-/** Check extra collision with another extra
- @param extra to process
- @param extraIdx extra index to check collision */
-int32 checkExtraCollisionWithExtra(ExtraListStruct* extra, int32 extraIdx);
-
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_COLLISION_H
+#define TWINE_COLLISION_H
+
+#include "common/scummsys.h"
+#include "twine/extra.h"
+
+namespace TwinE {
+
+class TwinEEngine;
+
+class Collision {
+private:
+ TwinEEngine *_engine;
+public:
+ Collision(TwinEEngine *engine);
+ /** Actor collition X coordinate */
+ int32 collisionX = 0; // getPosVar1
+ /** Actor collition Y coordinate */
+ int32 collisionY = 0; // getPosVar2
+ /** Actor collition Z coordinate */
+ int32 collisionZ = 0; // getPosVar3
+
+ /** Actor collition X coordinate */
+ int32 processCollisionX = 0; // processActorVar11
+ /** Actor collition Y coordinate */
+ int32 processCollisionY = 0; // processActorVar12
+ /** Actor collition Z coordinate */
+ int32 processCollisionZ = 0; // processActorVar13
+
+ /** Cause damage in current processed actor */
+ int32 causeActorDamage = 0; //fieldCauseDamage
+
+ /**
+ * Check if actor 1 is standing in actor2
+ * @param actorIdx1 Actor 1 index
+ * @param actorIdx2 Actor 2 index
+ */
+ int32 standingOnActor(int32 actorIdx1, int32 actorIdx2);
+
+ int32 getAverageValue(int32 var0, int32 var1, int32 var2, int32 var3);
+
+ /**
+ * Reajust actor position in scene according with brick shape bellow actor
+ * @param brickShape Shape of brick bellow the actor
+ */
+ void reajustActorPosition(int32 brickShape);
+
+ /**
+ * Check collision with actors
+ * @param actorIx Current process actor index
+ */
+ int32 checkCollisionWithActors(int32 actorIdx);
+
+ /**
+ * Check Hero collision with bricks
+ * @param X Hero X coordinate
+ * @param Y Hero Y coordinate
+ * @param Z Hero Z coordinate
+ * @param damageMask Cause damage mask
+ */
+ void checkHeroCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask);
+
+ /**
+ * Check other actor collision with bricks
+ * @param X Actor X coordinate
+ * @param Y Actor Y coordinate
+ * @param Z Actor Z coordinate
+ * @param damageMask Cause damage mask
+ */
+ void checkActorCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 damageMask);
+
+ /** Make actor to stop falling */
+ void stopFalling();
+
+ /**
+ * Check extra collision with actors
+ * @param extra to process
+ * @param actorIdx actor to check collision
+ */
+ int32 checkExtraCollisionWithActors(ExtraListStruct *extra, int32 actorIdx);
+
+ /** Check extra collision with bricks */
+ int32 checkExtraCollisionWithBricks(int32 X, int32 Y, int32 Z, int32 oldX, int32 oldY, int32 oldZ);
+
+ /**
+ * Check extra collision with another extra
+ * @param extra to process
+ * @param extraIdx extra index to check collision
+ */
+ int32 checkExtraCollisionWithExtra(ExtraListStruct *extra, int32 extraIdx);
+};
+
+} // namespace TwinE
#endif
diff --git a/engines/twine/configure.engine b/engines/twine/configure.engine
index 510f98d061..1895015425 100644
--- a/engines/twine/configure.engine
+++ b/engines/twine/configure.engine
@@ -1,3 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine twine "Little Big Adventure" no
+add_engine twine "Little Big Adventure" no "" "" "cxx11"
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 4b4a085704..2f729c7844 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -1,102 +1,46 @@
-/** @file debug.cpp
- @brief
- This file contains the main game debug window routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "debug.h"
-
-#ifdef GAMEMOD
-#include "debug.scene.h"
-#include "debug.grid.h"
-#include "scene.h"
-#include "sdlengine.h"
-#include "menu.h"
-#include "interface.h"
-#include "text.h"
-#include "lbaengine.h"
-#include "screens.h"
-#include "redraw.h"
-
-enum ButtonType {
- NO_ACTION,
- FREE_CAMERA,
- CHANGE_SCENE,
- SHOW_CELLING_GRID,
- SHOW_ZONES,
- SHOW_ZONE_CUBE,
- SHOW_ZONE_CAMERA,
- SHOW_ZONE_SCENARIC,
- SHOW_ZONE_CELLINGGRID,
- SHOW_ZONE_OBJECT,
- SHOW_ZONE_TEXT,
- SHOW_ZONE_LADDER
-};
-
-enum WindowType {
- NO_MENU,
- FREE_CAMERA_INFO_MENU,
- CHANGE_SCENE_INFO_MENU,
- ZONES_MENU
-};
-
-typedef struct DebugButtonStruct {
- int32 left;
- int32 top;
- int32 right;
- int32 bottom;
- int8 *text;
- int32 textLeft;
- int32 textTop;
- int32 isActive;
- int32 color;
- int32 activeColor;
- int32 submenu;
- int32 type;
-} DebugButtonStruct;
-
-typedef struct DebugWindowStruct {
- int32 left;
- int32 top;
- int32 right;
- int32 bottom;
- int32 alpha;
- int32 isActive;
- int32 numLines;
- int8 *text[20];
- int32 numButtons;
- DebugButtonStruct debugButtons[50];
-} DebugWindowStruct;
-
-DebugWindowStruct debugWindows[10];
-int32 numDebugWindows = 0;
-
-
-void debugFillButton(int32 X, int32 Y, int32 width, int32 height, int8 color) {
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/debug.h"
+
+#include "common/system.h"
+#include "twine/debug_grid.h"
+#include "twine/debug_scene.h"
+#include "twine/interface.h"
+#include "twine/menu.h"
+#include "twine/redraw.h"
+#include "twine/scene.h"
+#include "twine/screens.h"
+#include "twine/text.h"
+#include "twine/twine.h"
+
+namespace TwinE {
+
+void Debug::debugFillButton(int32 X, int32 Y, int32 width, int32 height, int8 color) {
int32 i, j;
uint8 *ptr;
int32 offset;
- ptr = frontVideoBuffer + screenLookupTable[Y] + X;
+ ptr = _engine->frontVideoBuffer + _engine->screenLookupTable[Y] + X;
offset = 640 - (width);
for (i = 0; i < height; i++) {
@@ -107,20 +51,20 @@ void debugFillButton(int32 X, int32 Y, int32 width, int32 height, int8 color) {
}
}
-void debugDrawButton(int32 left, int32 top, int32 right, int32 bottom, int8 *text, int32 textLeft, int32 textRight, int32 isActive, int8 color) {
+void Debug::debugDrawButton(int32 left, int32 top, int32 right, int32 bottom, const char *text, int32 textLeft, int32 textRight, int32 isActive, int8 color) {
debugFillButton(left + 1, top + 1, right - left - 1, bottom - top - 1, color);
- drawBox(left, top, right, bottom);
- ttfDrawText(textLeft, textRight, text, 0);
- copyBlockPhys(left, top, right, bottom);
+ _engine->_menu->drawBox(left, top, right, bottom);
+ _engine->drawText(textLeft, textRight, text, 0);
+ _engine->copyBlockPhys(left, top, right, bottom);
}
-void debugDrawWindowBox(int32 left, int32 top, int32 right, int32 bottom, int32 alpha) {
- drawTransparentBox(left, top, right, bottom, alpha);
- drawBox(left, top, right, bottom);
- //copyBlockPhys(left,top,right,bottom);
+void Debug::debugDrawWindowBox(int32 left, int32 top, int32 right, int32 bottom, int32 alpha) {
+ _engine->_interface->drawTransparentBox(left, top, right, bottom, alpha);
+ _engine->_menu->drawBox(left, top, right, bottom);
+ //_engine->copyBlockPhys(left,top,right,bottom);
}
-void debugDrawWindowButtons(int32 w) {
+void Debug::debugDrawWindowButtons(int32 w) {
int32 b;
for (b = 0; b < debugWindows[w].numButtons; b++) {
@@ -128,11 +72,11 @@ void debugDrawWindowButtons(int32 w) {
int32 top = debugWindows[w].debugButtons[b].top;
int32 right = debugWindows[w].debugButtons[b].right;
int32 bottom = debugWindows[w].debugButtons[b].bottom;
- int8 *text = debugWindows[w].debugButtons[b].text;
+ const char *text = debugWindows[w].debugButtons[b].text;
int32 textLeft = debugWindows[w].debugButtons[b].textLeft;
int32 textTop = debugWindows[w].debugButtons[b].textTop;
int32 isActive = debugWindows[w].debugButtons[b].isActive;
- int8 color = debugWindows[w].debugButtons[b].color;
+ int8 color = debugWindows[w].debugButtons[b].color;
if (isActive > 0)
color = debugWindows[w].debugButtons[b].activeColor;
@@ -140,7 +84,7 @@ void debugDrawWindowButtons(int32 w) {
}
}
-void debugDrawWindow(int32 w) {
+void Debug::debugDrawWindow(int32 w) {
int32 left = debugWindows[w].left;
int32 top = debugWindows[w].top;
int32 right = debugWindows[w].right;
@@ -153,16 +97,16 @@ void debugDrawWindow(int32 w) {
int32 l;
for (l = 0; l < debugWindows[w].numLines; l++) {
- ttfDrawText(left + 10, top + l*20 + 5, debugWindows[w].text[l], 0);
+ _engine->drawText(left + 10, top + l * 20 + 5, debugWindows[w].text[l], 0);
}
}
- copyBlockPhys(left, top, right, bottom);
+ _engine->copyBlockPhys(left, top, right, bottom);
debugDrawWindowButtons(w);
}
-int32 debugTypeUseMenu(int32 type) {
+int32 Debug::debugTypeUseMenu(int32 type) {
int32 w, b;
for (w = 0; w < numDebugWindows; w++) {
@@ -180,7 +124,7 @@ int32 debugTypeUseMenu(int32 type) {
return 0;
}
-void debugResetButtonsState() {
+void Debug::debugResetButtonsState() {
int w, b;
for (w = 0; w < numDebugWindows; w++) {
if (debugWindows[w].isActive > 0) {
@@ -192,7 +136,7 @@ void debugResetButtonsState() {
}
}
-void debugRefreshButtons(int32 type) {
+void Debug::debugRefreshButtons(int32 type) {
int32 w, b;
for (w = 0; w < numDebugWindows; w++) {
@@ -203,10 +147,10 @@ void debugRefreshButtons(int32 type) {
int32 top = debugWindows[w].debugButtons[b].top;
int32 right = debugWindows[w].debugButtons[b].right;
int32 bottom = debugWindows[w].debugButtons[b].bottom;
- int8 *text = debugWindows[w].debugButtons[b].text;
+ const char *text = debugWindows[w].debugButtons[b].text;
int32 textLeft = debugWindows[w].debugButtons[b].textLeft;
int32 textTop = debugWindows[w].debugButtons[b].textTop;
- int8 color = debugWindows[w].debugButtons[b].color;
+ int8 color = debugWindows[w].debugButtons[b].color;
int32 isActive = debugWindows[w].debugButtons[b].isActive = !debugWindows[w].debugButtons[b].isActive;
if (isActive > 0)
@@ -222,7 +166,7 @@ void debugRefreshButtons(int32 type) {
}
}
-void debugDrawWindows() {
+void Debug::debugDrawWindows() {
int32 w;
for (w = 0; w < numDebugWindows; w++) {
@@ -232,7 +176,7 @@ void debugDrawWindows() {
}
}
-void debugResetButton(int32 type) {
+void Debug::debugResetButton(int32 type) {
int32 w, b;
for (w = 0; w < numDebugWindows; w++) {
@@ -252,24 +196,24 @@ void debugResetButton(int32 type) {
}
}
-void debugRedrawScreen() {
- redrawEngineActions(1);
- copyScreen(frontVideoBuffer, workVideoBuffer);
+void Debug::debugRedrawScreen() {
+ _engine->_redraw->redrawEngineActions(1);
+ _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
debugDrawWindows();
}
-int32 debugGetActionsState(int32 type) {
+int32 Debug::debugGetActionsState(int32 type) {
int32 state = 0;
switch (type) {
case FREE_CAMERA:
- state = useFreeCamera;
+ state = _engine->_debugGrid->useFreeCamera;
break;
case CHANGE_SCENE:
- state = canChangeScenes;
+ state = _engine->_debugGrid->canChangeScenes;
break;
case SHOW_ZONES:
- state = showingZones;
+ state = _engine->_debugScene->showingZones;
break;
case SHOW_ZONE_CUBE:
case SHOW_ZONE_CAMERA:
@@ -278,7 +222,7 @@ int32 debugGetActionsState(int32 type) {
case SHOW_ZONE_OBJECT:
case SHOW_ZONE_TEXT:
case SHOW_ZONE_LADDER:
- state = typeZones;
+ state = _engine->_debugScene->typeZones;
break;
default:
break;
@@ -286,89 +230,88 @@ int32 debugGetActionsState(int32 type) {
return state;
}
-void debugSetActions(int32 type) {
+void Debug::debugSetActions(int32 type) {
switch (type) {
case FREE_CAMERA:
- useFreeCamera = !useFreeCamera;
+ _engine->_debugGrid->useFreeCamera = !_engine->_debugGrid->useFreeCamera;
break;
case CHANGE_SCENE:
- canChangeScenes = !canChangeScenes;
+ _engine->_debugGrid->canChangeScenes = !_engine->_debugGrid->canChangeScenes;
break;
case SHOW_ZONES:
- showingZones = !showingZones;
+ _engine->_debugScene->showingZones = !_engine->_debugScene->showingZones;
debugResetButton(-1);
debugResetButton(-2);
debugRedrawScreen();
break;
case SHOW_ZONE_CUBE:
- if (showingZones) {
- if (typeZones & 0x01)
- typeZones &= ~0x01;
+ if (_engine->_debugScene->showingZones) {
+ if (_engine->_debugScene->typeZones & 0x01)
+ _engine->_debugScene->typeZones &= ~0x01;
else
- typeZones |= 0x01;
+ _engine->_debugScene->typeZones |= 0x01;
debugRedrawScreen();
}
break;
case SHOW_ZONE_CAMERA:
- if (showingZones) {
- if (typeZones & 0x02)
- typeZones &= ~0x02;
+ if (_engine->_debugScene->showingZones) {
+ if (_engine->_debugScene->typeZones & 0x02)
+ _engine->_debugScene->typeZones &= ~0x02;
else
- typeZones |= 0x02;
+ _engine->_debugScene->typeZones |= 0x02;
debugRedrawScreen();
}
break;
case SHOW_ZONE_SCENARIC:
- if (showingZones) {
- if (typeZones & 0x04)
- typeZones &= ~0x04;
+ if (_engine->_debugScene->showingZones) {
+ if (_engine->_debugScene->typeZones & 0x04)
+ _engine->_debugScene->typeZones &= ~0x04;
else
- typeZones |= 0x04;
+ _engine->_debugScene->typeZones |= 0x04;
debugRedrawScreen();
}
break;
case SHOW_ZONE_CELLINGGRID:
- if (showingZones) {
- if (typeZones & 0x08)
- typeZones &= ~0x08;
+ if (_engine->_debugScene->showingZones) {
+ if (_engine->_debugScene->typeZones & 0x08)
+ _engine->_debugScene->typeZones &= ~0x08;
else
- typeZones |= 0x08;
+ _engine->_debugScene->typeZones |= 0x08;
debugRedrawScreen();
debugRedrawScreen();
}
break;
case SHOW_ZONE_OBJECT:
- if (showingZones) {
- if (typeZones & 0x10)
- typeZones &= ~0x10;
+ if (_engine->_debugScene->showingZones) {
+ if (_engine->_debugScene->typeZones & 0x10)
+ _engine->_debugScene->typeZones &= ~0x10;
else
- typeZones |= 0x10;
+ _engine->_debugScene->typeZones |= 0x10;
debugRedrawScreen();
debugRedrawScreen();
}
break;
case SHOW_ZONE_TEXT:
- if (showingZones) {
- if (typeZones & 0x20)
- typeZones &= ~0x20;
+ if (_engine->_debugScene->showingZones) {
+ if (_engine->_debugScene->typeZones & 0x20)
+ _engine->_debugScene->typeZones &= ~0x20;
else
- typeZones |= 0x20;
+ _engine->_debugScene->typeZones |= 0x20;
debugRedrawScreen();
}
break;
case SHOW_ZONE_LADDER:
- if (showingZones) {
- if (typeZones & 0x40)
- typeZones &= ~0x40;
+ if (_engine->_debugScene->showingZones) {
+ if (_engine->_debugScene->typeZones & 0x40)
+ _engine->_debugScene->typeZones &= ~0x40;
else
- typeZones |= 0x40;
+ _engine->_debugScene->typeZones |= 0x40;
debugRedrawScreen();
}
break;
-
case -1:
debugResetButton(-2);
debugRedrawScreen();
@@ -382,7 +325,7 @@ void debugSetActions(int32 type) {
}
}
-void debugAddButton(int32 window, int32 left, int32 top, int32 right, int32 bottom, int8 *text, int32 textLeft, int32 textTop, int32 isActive, int32 color, int32 activeColor, int32 submenu, int32 type) {
+void Debug::debugAddButton(int32 window, int32 left, int32 top, int32 right, int32 bottom, const char *text, int32 textLeft, int32 textTop, int32 isActive, int32 color, int32 activeColor, int32 submenu, int32 type) {
int32 button = debugWindows[window].numButtons;
debugWindows[window].debugButtons[button].left = left;
debugWindows[window].debugButtons[button].top = top;
@@ -399,13 +342,13 @@ void debugAddButton(int32 window, int32 left, int32 top, int32 right, int32 bott
debugWindows[window].numButtons++;
}
-void debugAddWindowText(int32 window, int8 *text) {
+void Debug::debugAddWindowText(int32 window, const char *text) {
int32 line = debugWindows[window].numLines;
debugWindows[window].text[line] = text;
debugWindows[window].numLines++;
}
-void debugAddWindow(int32 left, int32 top, int32 right, int32 bottom, int32 alpha, int32 isActive) {
+void Debug::debugAddWindow(int32 left, int32 top, int32 right, int32 bottom, int32 alpha, int32 isActive) {
debugWindows[numDebugWindows].left = left;
debugWindows[numDebugWindows].top = top;
debugWindows[numDebugWindows].right = right;
@@ -416,53 +359,50 @@ void debugAddWindow(int32 left, int32 top, int32 right, int32 bottom, int32 alph
numDebugWindows++;
}
-void debugLeftMenu() {
+void Debug::debugLeftMenu() {
// left menu window
debugAddWindow(5, 60, 200, 474, 4, 1);
- debugAddButton(0, 5, 55, 160, 75, (int8*) "Use free camera", 30, 60, 0, 87, 119, NO_MENU, FREE_CAMERA);
- debugAddButton(0, 161, 55, 200, 75, (int8*) "info", 171, 60, 0, 87, 119, FREE_CAMERA_INFO_MENU, -1);
- debugAddButton(0, 5, 76, 160, 96, (int8*) "Change scenes", 30, 81, 0, 87, 119, NO_MENU, CHANGE_SCENE);
- debugAddButton(0, 161, 76, 200, 96, (int8*) "info", 171, 81, 0, 87, 119, CHANGE_SCENE_INFO_MENU, -2);
- debugAddButton(0, 5, 97, 200, 117, (int8*) "Show celling grids", 30, 102, 0, 87, 119, NO_MENU, 3);
- debugAddButton(0, 5, 118, 200, 138, (int8*) "Show zones", 30, 123, 0, 87, 119, ZONES_MENU, SHOW_ZONES);
+ debugAddButton(0, 5, 55, 160, 75, "Use free camera", 30, 60, 0, 87, 119, NO_MENU, FREE_CAMERA);
+ debugAddButton(0, 161, 55, 200, 75, "info", 171, 60, 0, 87, 119, FREE_CAMERA_INFO_MENU, -1);
+ debugAddButton(0, 5, 76, 160, 96, "Change scenes", 30, 81, 0, 87, 119, NO_MENU, CHANGE_SCENE);
+ debugAddButton(0, 161, 76, 200, 96, "info", 171, 81, 0, 87, 119, CHANGE_SCENE_INFO_MENU, -2);
+ debugAddButton(0, 5, 97, 200, 117, "Show celling grids", 30, 102, 0, 87, 119, NO_MENU, 3);
+ debugAddButton(0, 5, 118, 200, 138, "Show zones", 30, 123, 0, 87, 119, ZONES_MENU, SHOW_ZONES);
// add submenu windows
// - free camera window
debugAddWindow(205, 55, 634, 160, 4, 0);
- debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) "When enable, use the following keys to browse through the scenes:");
- debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) " - S to go North");
- debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) " - X to go South");
- debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) " - Z to go West");
- debugAddWindowText(FREE_CAMERA_INFO_MENU, (int8*) " - C to go East");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, "When enable, use the following keys to browse through the scenes:");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, " - S to go North");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, " - X to go South");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, " - Z to go West");
+ debugAddWindowText(FREE_CAMERA_INFO_MENU, " - C to go East");
// - change scene window
debugAddWindow(205, 55, 634, 137, 4, 0);
- debugAddWindowText(CHANGE_SCENE_INFO_MENU, (int8*) "When enable, use the following keys to change to another scene:");
- debugAddWindowText(CHANGE_SCENE_INFO_MENU, (int8*) " - R to go Next Scene");
- debugAddWindowText(CHANGE_SCENE_INFO_MENU, (int8*) " - F to go Previous Scene");
+ debugAddWindowText(CHANGE_SCENE_INFO_MENU, "When enable, use the following keys to change to another scene:");
+ debugAddWindowText(CHANGE_SCENE_INFO_MENU, " - R to go Next Scene");
+ debugAddWindowText(CHANGE_SCENE_INFO_MENU, " - F to go Previous Scene");
// - zones window
debugAddWindow(205, 55, 634, 97, 4, 0);
- debugAddWindowText(ZONES_MENU, (int8*) "You can enable or disable each zone type:");
- debugAddButton(ZONES_MENU, 205, 118, 350, 138, (int8*) "Cube Zones", 215, 123, 1, 87, 119, 0, SHOW_ZONE_CUBE);
- debugAddButton(ZONES_MENU, 205, 139, 350, 159, (int8*) "Camera Zones", 215, 144, 2, 87, 119, 0, SHOW_ZONE_CAMERA);
- debugAddButton(ZONES_MENU, 205, 160, 350, 180, (int8*) "Scenaric Zones", 215, 165, 3, 87, 119, 0, SHOW_ZONE_SCENARIC);
- debugAddButton(ZONES_MENU, 205, 181, 350, 201, (int8*) "Celling Grid Zones", 215, 186, 4, 87, 119, 0, SHOW_ZONE_CELLINGGRID);
- debugAddButton(ZONES_MENU, 205, 202, 350, 222, (int8*) "Object Zones", 215, 207, 5, 87, 119, 0, SHOW_ZONE_OBJECT);
- debugAddButton(ZONES_MENU, 205, 223, 350, 243, (int8*) "Text Zones", 215, 228, 6, 87, 119, 0, SHOW_ZONE_TEXT);
- debugAddButton(ZONES_MENU, 205, 244, 350, 264, (int8*) "Ladder Zones", 215, 249, 7, 87, 119, 0, SHOW_ZONE_LADDER);
+ debugAddWindowText(ZONES_MENU, "You can enable or disable each zone type:");
+ debugAddButton(ZONES_MENU, 205, 118, 350, 138, "Cube Zones", 215, 123, 1, 87, 119, 0, SHOW_ZONE_CUBE);
+ debugAddButton(ZONES_MENU, 205, 139, 350, 159, "Camera Zones", 215, 144, 2, 87, 119, 0, SHOW_ZONE_CAMERA);
+ debugAddButton(ZONES_MENU, 205, 160, 350, 180, "Scenaric Zones", 215, 165, 3, 87, 119, 0, SHOW_ZONE_SCENARIC);
+ debugAddButton(ZONES_MENU, 205, 181, 350, 201, "Celling Grid Zones", 215, 186, 4, 87, 119, 0, SHOW_ZONE_CELLINGGRID);
+ debugAddButton(ZONES_MENU, 205, 202, 350, 222, "Object Zones", 215, 207, 5, 87, 119, 0, SHOW_ZONE_OBJECT);
+ debugAddButton(ZONES_MENU, 205, 223, 350, 243, "Text Zones", 215, 228, 6, 87, 119, 0, SHOW_ZONE_TEXT);
+ debugAddButton(ZONES_MENU, 205, 244, 350, 264, "Ladder Zones", 215, 249, 7, 87, 119, 0, SHOW_ZONE_LADDER);
}
-int32 debugProcessButton(int32 X, int32 Y) {
+int32 Debug::debugProcessButton(int32 X, int32 Y) {
int32 i;
int32 j;
for (i = 0; i < numDebugWindows; i++) {
for (j = 0; j < debugWindows[i].numButtons; j++) {
- if (X > (debugWindows[i].debugButtons[j].left)
- && X < (debugWindows[i].debugButtons[j].right)
- && Y > (debugWindows[i].debugButtons[j].top)
- && Y < (debugWindows[i].debugButtons[j].bottom)) {
+ if (X > (debugWindows[i].debugButtons[j].left) && X < (debugWindows[i].debugButtons[j].right) && Y > (debugWindows[i].debugButtons[j].top) && Y < (debugWindows[i].debugButtons[j].bottom)) {
return (debugWindows[i].debugButtons[j].type);
}
}
@@ -471,30 +411,30 @@ int32 debugProcessButton(int32 X, int32 Y) {
return 0;
}
-void debugPlasmaWindow(int8 *text, int32 color) {
+void Debug::debugPlasmaWindow(const char *text, int32 color) {
int32 textSize;
- processPlasmaEffect(5, color);
- if (!(rand() % 5)) {
- plasmaEffectPtr[rand() % 320 * 10 + 6400] = 255;
+ _engine->_menu->processPlasmaEffect(5, color);
+ if (!(_engine->getRandomNumber() % 5)) {
+ _engine->_menu->plasmaEffectPtr[_engine->getRandomNumber() % 320 * 10 + 6400] = 255;
}
- textSize = getTextSize(text);
- drawText((SCREEN_WIDTH / 2) - (textSize / 2), 10, text);
- drawBox(5, 5, 634, 50);
- copyBlockPhys(5, 5, 634, 50);
+ textSize = _engine->_text->getTextSize(text);
+ _engine->_text->drawText((SCREEN_WIDTH / 2) - (textSize / 2), 10, text);
+ _engine->_menu->drawBox(5, 5, 634, 50);
+ _engine->copyBlockPhys(5, 5, 634, 50);
}
-void debugProcessWindow() {
- if (rightMouse) {
+void Debug::debugProcessWindow() {
+ if (_engine->rightMouse) {
int32 quit = 0;
- int8* text = (int8*) "Game Debug Window";
+ const char *text = "Game Debug Window";
int32 color = 64;
int32 colorIdx = 4;
int32 count = 0;
MouseStatusStruct mouseData;
- rightMouse = 0;
- leftMouse = 0;
+ _engine->rightMouse = 0;
+ _engine->leftMouse = 0;
- copyScreen(frontVideoBuffer, workVideoBuffer);
+ _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
debugResetButtonsState();
if (numDebugWindows == 0)
@@ -502,15 +442,18 @@ void debugProcessWindow() {
debugDrawWindows();
do {
- readKeys();
- getMousePositions(&mouseData);
+ _engine->readKeys();
+ if (_engine->shouldQuit()) {
+ quit = 1;
+ }
+ _engine->getMousePositions(&mouseData);
if (mouseData.left) {
int type = 0;
if ((type = debugProcessButton(mouseData.X, mouseData.Y)) != NO_ACTION) { // process menu item
if (debugTypeUseMenu(type)) {
- copyScreen(workVideoBuffer, frontVideoBuffer);
- copyBlockPhys(205, 55, 634, 474);
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->copyBlockPhys(205, 55, 634, 474);
}
debugRefreshButtons(type);
@@ -532,25 +475,27 @@ void debugProcessWindow() {
debugPlasmaWindow(text, color);
// quit
- if (mouseData.right)
+ if (mouseData.right) {
quit = 1;
+ }
- fpsCycles(25); // rest
+ _engine->_system->delayMillis(1000 / 25); // rest
count++;
} while (!quit);
- reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = 1;
}
}
-void processDebug(int16 pKey) {
+void Debug::processDebug(int16 pKey) {
+ if (!_engine->cfgfile.Debug) {
+ return;
+ }
debugProcessWindow();
- changeGrid(pKey);
- changeGridCamera(pKey);
- if (needChangeScene == 0);
- applyCellingGrid(pKey);
+ _engine->_debugGrid->changeGrid(pKey);
+ _engine->_debugGrid->changeGridCamera(pKey);
+ _engine->_debugGrid->applyCellingGrid(pKey);
}
-#endif
-
+} // namespace TwinE
diff --git a/engines/twine/debug.grid.cpp b/engines/twine/debug.grid.cpp
deleted file mode 100644
index 1dd1f1ee8d..0000000000
--- a/engines/twine/debug.grid.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/** @file debug.grid.cpp
- @brief
- This file contains grid debug routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "debug.grid.h"
-#include "grid.h"
-#include "lbaengine.h"
-#include "scene.h"
-#include "main.h"
-#include "redraw.h"
-
-int32 useFreeCamera = 0;
-#ifdef _DEBUG
-int32 canChangeScenes = 1;
-#else
-int32 canChangeScenes = 0;
-#endif
-
-/** Change scenario camera positions */
-void changeGridCamera(int16 pKey) {
- if (useFreeCamera) {
- // Press up - more X positions
- if (pKey == 0x2E) {
- newCameraZ--;
- reqBgRedraw = 1;
- }
-
- // Press down - less X positions
- if (pKey == 0x2C) {
- newCameraZ++;
- reqBgRedraw = 1;
- }
-
- // Press left - less Z positions
- if (pKey == 0x1F) {
- newCameraX--;
- reqBgRedraw = 1;
- }
-
- // Press right - more Z positions
- if (pKey == 0x2D) {
- newCameraX++;
- reqBgRedraw = 1;
- }
- }
-}
-
-/** Change grid index */
-void changeGrid(int16 pKey) {
- if (canChangeScenes) {
- // Press up - more X positions
- if (pKey == 0x13) {
- currentSceneIdx++;
- if (currentSceneIdx > NUM_SCENES)
- currentSceneIdx = 0;
- needChangeScene = currentSceneIdx;
- reqBgRedraw = 1;
- }
-
- // Press down - less X positions
- if (pKey == 0x21) {
- currentSceneIdx--;
- if (currentSceneIdx < 0)
- currentSceneIdx = NUM_SCENES;
- needChangeScene = currentSceneIdx;
- reqBgRedraw = 1;
- }
-
- if (cfgfile.Debug && (pKey == 'f' || pKey == 'r'))
- printf("\nGrid index changed: %d\n", needChangeScene);
- }
-}
-
-/** Apply and change disappear celling grid */
-void applyCellingGrid(int16 pKey) {
- // Increase celling grid index
- if (pKey == 0x22) {
- cellingGridIdx++;
- if (cellingGridIdx > 133)
- cellingGridIdx = 133;
- }
- // Decrease celling grid index
- if (pKey == 0x30) {
- cellingGridIdx--;
- if (cellingGridIdx < 0)
- cellingGridIdx = 0;
- }
-
- // Enable/disable celling grid
- if (pKey == 0x14 && useCellingGrid == -1) {
- useCellingGrid = 1;
- //createGridMap();
- initCellingGrid(cellingGridIdx);
- if (cfgfile.Debug && pKey == 0x14)
- printf("\nEnable Celling Grid index: %d\n", cellingGridIdx);
- needChangeScene = -2; // tricky to make the fade
- } else if (pKey == 0x14 && useCellingGrid == 1) {
- useCellingGrid = -1;
- createGridMap();
- reqBgRedraw = 1;
- if (cfgfile.Debug && pKey == 0x14)
- printf("\nDisable Celling Grid index: %d\n", cellingGridIdx);
- needChangeScene = -2; // tricky to make the fade
- }
-}
-
diff --git a/engines/twine/debug.grid.h b/engines/twine/debug.grid.h
deleted file mode 100644
index 27633fa95b..0000000000
--- a/engines/twine/debug.grid.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/** @file debug.grid.h
- @brief
- This file contains grid debug routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef GRIDDEBUG_H
-#define GRIDDEBUG_H
-
-#include "sys.h"
-
-extern int32 useFreeCamera;
-extern int32 canChangeScenes;
-
-/** Change scenario camera positions */
-void changeGridCamera(int16 pKey);
-/** Change grid index */
-void changeGrid(int16 pKey);
-/** Apply and change disappear celling grid */
-void applyCellingGrid(int16 pKey);
-
-#endif
diff --git a/engines/twine/debug.h b/engines/twine/debug.h
index f0d5409a3d..0e9f06c6de 100644
--- a/engines/twine/debug.h
+++ b/engines/twine/debug.h
@@ -1,41 +1,116 @@
-/** @file debug.h
- @brief
- This file contains the main game debug window routines
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
- TwinEngine: a Little Big Adventure engine
+#ifndef TWINE_DEBUG_H
+#define TWINE_DEBUG_H
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
+#include "common/scummsys.h"
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+namespace TwinE {
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+enum ButtonType {
+ NO_ACTION,
+ FREE_CAMERA,
+ CHANGE_SCENE,
+ SHOW_CELLING_GRID,
+ SHOW_ZONES,
+ SHOW_ZONE_CUBE,
+ SHOW_ZONE_CAMERA,
+ SHOW_ZONE_SCENARIC,
+ SHOW_ZONE_CELLINGGRID,
+ SHOW_ZONE_OBJECT,
+ SHOW_ZONE_TEXT,
+ SHOW_ZONE_LADDER
+};
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
+enum WindowType {
+ NO_MENU,
+ FREE_CAMERA_INFO_MENU,
+ CHANGE_SCENE_INFO_MENU,
+ ZONES_MENU
+};
-#ifndef DEBUG_H
-#define DEBUG_H
+typedef struct DebugButtonStruct {
+ int32 left = 0;
+ int32 top = 0;
+ int32 right = 0;
+ int32 bottom = 0;
+ const char *text = "";
+ int32 textLeft = 0;
+ int32 textTop = 0;
+ int32 isActive = 0;
+ int32 color = 0;
+ int32 activeColor = 0;
+ int32 submenu = 0;
+ int32 type = 0;
+} DebugButtonStruct;
-#include "sys.h"
+typedef struct DebugWindowStruct {
+ int32 left = 0;
+ int32 top = 0;
+ int32 right = 0;
+ int32 bottom = 0;
+ int32 alpha = 0;
+ int32 isActive = 0;
+ int32 numLines = 0;
+ const char *text[20] {0};
+ int32 numButtons = 0;
+ DebugButtonStruct debugButtons[50];
+} DebugWindowStruct;
-typedef struct MouseStatusStruct {
- int32 left;
- int32 right;
- int32 X;
- int32 Y;
-} MouseStatusStruct;
+class TwinEEngine;
+class Debug {
+private:
+ TwinEEngine *_engine;
-void processDebug(int16 pKey);
+ DebugWindowStruct debugWindows[10];
+ int32 numDebugWindows = 0;
+ void debugFillButton(int32 X, int32 Y, int32 width, int32 height, int8 color);
+ void debugDrawButton(int32 left, int32 top, int32 right, int32 bottom, const char *text, int32 textLeft, int32 textRight, int32 isActive, int8 color);
+ void debugDrawWindowBox(int32 left, int32 top, int32 right, int32 bottom, int32 alpha);
+ void debugDrawWindowButtons(int32 w);
+ void debugDrawWindow(int32 w);
+ int32 debugTypeUseMenu(int32 type);
+ void debugResetButtonsState();
+ void debugRefreshButtons(int32 type);
+ void debugDrawWindows();
+ void debugResetButton(int32 type);
+ void debugRedrawScreen();
+ int32 debugGetActionsState(int32 type);
+ void debugSetActions(int32 type);
+ void debugAddButton(int32 window, int32 left, int32 top, int32 right, int32 bottom, const char *text, int32 textLeft, int32 textTop, int32 isActive, int32 color, int32 activeColor, int32 submenu, int32 type);
+ void debugAddWindowText(int32 window, const char *text);
+ void debugAddWindow(int32 left, int32 top, int32 right, int32 bottom, int32 alpha, int32 isActive);
+ void debugLeftMenu();
+ int32 debugProcessButton(int32 X, int32 Y);
+ void debugPlasmaWindow(const char *text, int32 color);
+ void debugProcessWindow();
+
+public:
+ Debug(TwinEEngine *engine) : _engine(engine) {}
+ void processDebug(int16 pKey);
+};
+
+} // namespace TwinE
#endif
diff --git a/engines/twine/debug.scene.cpp b/engines/twine/debug.scene.cpp
deleted file mode 100644
index 64cc5c9266..0000000000
--- a/engines/twine/debug.scene.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/** @file debug.scene.cpp
- @brief
- This file contains scenario debug routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "debug.scene.h"
-#include "scene.h"
-#include "grid.h"
-#include "lbaengine.h"
-#include "redraw.h"
-#include "interface.h"
-#include "renderer.h"
-
-int32 showingZones = 0;
-int32 typeZones = 127; // all zones on as default
-
-void drawBoundingBoxProjectPoints(ScenePoint* pPoint3d, ScenePoint* pPoint3dProjected) {
- projectPositionOnScreen(pPoint3d->X, pPoint3d->Y, pPoint3d->Z);
-
- pPoint3dProjected->X = projPosX;
- pPoint3dProjected->Y = projPosY;
- pPoint3dProjected->Z = projPosZ;
-
- if (renderLeft > projPosX)
- renderLeft = projPosX;
-
- if (renderRight < projPosX)
- renderRight = projPosX;
-
- if (renderTop > projPosY)
- renderTop = projPosY;
-
- if (renderBottom < projPosY)
- renderBottom = projPosY;
-}
-
-int32 checkZoneType(int32 type) {
- switch (type) {
- case 0:
- if (typeZones & 0x01)
- return 1;
- break;
- case 1:
- if (typeZones & 0x02)
- return 1;
- break;
- case 2:
- if (typeZones & 0x04)
- return 1;
- break;
- case 3:
- if (typeZones & 0x08)
- return 1;
- break;
- case 4:
- if (typeZones & 0x10)
- return 1;
- break;
- case 5:
- if (typeZones & 0x20)
- return 1;
- break;
- case 6:
- if (typeZones & 0x40)
- return 1;
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-void displayZones(int16 pKey) {
- if (showingZones == 1) {
- int z;
- ZoneStruct *zonePtr = sceneZones;
- for (z = 0; z < sceneNumZones; z++) {
- zonePtr = &sceneZones[z];
-
- if (checkZoneType(zonePtr->type)) {
- ScenePoint frontBottomLeftPoint;
- ScenePoint frontBottomRightPoint;
-
- ScenePoint frontTopLeftPoint;
- ScenePoint frontTopRightPoint;
-
- ScenePoint backBottomLeftPoint;
- ScenePoint backBottomRightPoint;
-
- ScenePoint backTopLeftPoint;
- ScenePoint backTopRightPoint;
-
- ScenePoint frontBottomLeftPoint2D;
- ScenePoint frontBottomRightPoint2D;
-
- ScenePoint frontTopLeftPoint2D;
- ScenePoint frontTopRightPoint2D;
-
- ScenePoint backBottomLeftPoint2D;
- ScenePoint backBottomRightPoint2D;
-
- ScenePoint backTopLeftPoint2D;
- ScenePoint backTopRightPoint2D;
-
- uint8 color;
-
- // compute the points in 3D
-
- frontBottomLeftPoint.X = zonePtr->bottomLeft.X - cameraX;
- frontBottomLeftPoint.Y = zonePtr->bottomLeft.Y - cameraY;
- frontBottomLeftPoint.Z = zonePtr->topRight.Z - cameraZ;
-
- frontBottomRightPoint.X = zonePtr->topRight.X - cameraX;
- frontBottomRightPoint.Y = zonePtr->bottomLeft.Y - cameraY;
- frontBottomRightPoint.Z = zonePtr->topRight.Z - cameraZ;
-
- frontTopLeftPoint.X = zonePtr->bottomLeft.X - cameraX;
- frontTopLeftPoint.Y = zonePtr->topRight.Y - cameraY;
- frontTopLeftPoint.Z = zonePtr->topRight.Z - cameraZ;
-
- frontTopRightPoint.X = zonePtr->topRight.X - cameraX;
- frontTopRightPoint.Y = zonePtr->topRight.Y - cameraY;
- frontTopRightPoint.Z = zonePtr->topRight.Z - cameraZ;
-
- backBottomLeftPoint.X = zonePtr->bottomLeft.X - cameraX;
- backBottomLeftPoint.Y = zonePtr->bottomLeft.Y - cameraY;
- backBottomLeftPoint.Z = zonePtr->bottomLeft.Z - cameraZ;
-
- backBottomRightPoint.X = zonePtr->topRight.X - cameraX;
- backBottomRightPoint.Y = zonePtr->bottomLeft.Y - cameraY;
- backBottomRightPoint.Z = zonePtr->bottomLeft.Z - cameraZ;
-
- backTopLeftPoint.X = zonePtr->bottomLeft.X - cameraX;
- backTopLeftPoint.Y = zonePtr->topRight.Y - cameraY;
- backTopLeftPoint.Z = zonePtr->bottomLeft.Z - cameraZ;
-
- backTopRightPoint.X = zonePtr->topRight.X - cameraX;
- backTopRightPoint.Y = zonePtr->topRight.Y - cameraY;
- backTopRightPoint.Z = zonePtr->bottomLeft.Z - cameraZ;
-
- // project all points
-
- drawBoundingBoxProjectPoints(&frontBottomLeftPoint, &frontBottomLeftPoint2D);
- drawBoundingBoxProjectPoints(&frontBottomRightPoint, &frontBottomRightPoint2D);
- drawBoundingBoxProjectPoints(&frontTopLeftPoint, &frontTopLeftPoint2D);
- drawBoundingBoxProjectPoints(&frontTopRightPoint, &frontTopRightPoint2D);
- drawBoundingBoxProjectPoints(&backBottomLeftPoint, &backBottomLeftPoint2D);
- drawBoundingBoxProjectPoints(&backBottomRightPoint, &backBottomRightPoint2D);
- drawBoundingBoxProjectPoints(&backTopLeftPoint, &backTopLeftPoint2D);
- drawBoundingBoxProjectPoints(&backTopRightPoint, &backTopRightPoint2D);
-
- // draw all lines
-
- color = 15 * 3 + zonePtr->type * 16;
-
- // draw front part
- drawLine(frontBottomLeftPoint2D.X, frontBottomLeftPoint2D.Y, frontTopLeftPoint2D.X, frontTopLeftPoint2D.Y, color);
- drawLine(frontTopLeftPoint2D.X, frontTopLeftPoint2D.Y, frontTopRightPoint2D.X, frontTopRightPoint2D.Y, color);
- drawLine(frontTopRightPoint2D.X, frontTopRightPoint2D.Y, frontBottomRightPoint2D.X, frontBottomRightPoint2D.Y, color);
- drawLine(frontBottomRightPoint2D.X, frontBottomRightPoint2D.Y, frontBottomLeftPoint2D.X, frontBottomLeftPoint2D.Y, color);
-
- // draw top part
- drawLine(frontTopLeftPoint2D.X, frontTopLeftPoint2D.Y, backTopLeftPoint2D.X, backTopLeftPoint2D.Y, color);
- drawLine(backTopLeftPoint2D.X, backTopLeftPoint2D.Y, backTopRightPoint2D.X, backTopRightPoint2D.Y, color);
- drawLine(backTopRightPoint2D.X, backTopRightPoint2D.Y, frontTopRightPoint2D.X, frontTopRightPoint2D.Y, color);
- drawLine(frontTopRightPoint2D.X, frontTopRightPoint2D.Y, frontTopLeftPoint2D.X, frontTopLeftPoint2D.Y, color);
-
- // draw back part
- drawLine(backBottomLeftPoint2D.X, backBottomLeftPoint2D.Y, backTopLeftPoint2D.X, backTopLeftPoint2D.Y, color);
- drawLine(backTopLeftPoint2D.X, backTopLeftPoint2D.Y, backTopRightPoint2D.X, backTopRightPoint2D.Y, color);
- drawLine(backTopRightPoint2D.X, backTopRightPoint2D.Y, backBottomRightPoint2D.X, backBottomRightPoint2D.Y, color);
- drawLine(backBottomRightPoint2D.X, backBottomRightPoint2D.Y, backBottomLeftPoint2D.X, backBottomLeftPoint2D.Y, color);
-
- // draw bottom part
- drawLine(frontBottomLeftPoint2D.X, frontBottomLeftPoint2D.Y, backBottomLeftPoint2D.X, backBottomLeftPoint2D.Y, color);
- drawLine(backBottomLeftPoint2D.X, backBottomLeftPoint2D.Y, backBottomRightPoint2D.X, backBottomRightPoint2D.Y, color);
- drawLine(backBottomRightPoint2D.X, backBottomRightPoint2D.Y, frontBottomRightPoint2D.X, frontBottomRightPoint2D.Y, color);
- drawLine(frontBottomRightPoint2D.X, frontBottomRightPoint2D.Y, frontBottomLeftPoint2D.X, frontBottomLeftPoint2D.Y, color);
- }
- }
- }
-}
diff --git a/engines/twine/debug.scene.h b/engines/twine/debug.scene.h
deleted file mode 100644
index f454cc058f..0000000000
--- a/engines/twine/debug.scene.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/** @file debug.scene.h
- @brief
- This file contains scenario debug routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef SCENE_DEBUG_H
-#define SCENE_DEBUG_H
-
-#include "sys.h"
-
-extern int32 showingZones;
-extern int32 typeZones;
-
-void displayZones(int16 pKey);
-
-#endif
diff --git a/engines/twine/debug_grid.cpp b/engines/twine/debug_grid.cpp
new file mode 100644
index 0000000000..2f8a917d14
--- /dev/null
+++ b/engines/twine/debug_grid.cpp
@@ -0,0 +1,123 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/debug_grid.h"
+#include "common/debug.h"
+#include "twine/grid.h"
+#include "twine/keyboard.h"
+#include "twine/redraw.h"
+#include "twine/scene.h"
+#include "twine/twine.h"
+
+namespace TwinE {
+
+DebugGrid::DebugGrid(TwinEEngine *engine) : _engine(engine) {
+ canChangeScenes = _engine->cfgfile.Debug ? 1 : 0;
+}
+
+void DebugGrid::changeGridCamera(int16 pKey) {
+ if (useFreeCamera) {
+ // Press up - more X positions
+ if (pKey == Keys::DebugGridCameraPressUp) {
+ _engine->_grid->newCameraZ--;
+ _engine->_redraw->reqBgRedraw = 1;
+ }
+
+ // Press down - less X positions
+ else if (pKey == Keys::DebugGridCameraPressDown) {
+ _engine->_grid->newCameraZ++;
+ _engine->_redraw->reqBgRedraw = 1;
+ }
+
+ // Press left - less Z positions
+ else if (pKey == Keys::DebugGridCameraPressLeft) {
+ _engine->_grid->newCameraX--;
+ _engine->_redraw->reqBgRedraw = 1;
+ }
+
+ // Press right - more Z positions
+ else if (pKey == Keys::DebugGridCameraPressRight) {
+ _engine->_grid->newCameraX++;
+ _engine->_redraw->reqBgRedraw = 1;
+ }
+ }
+}
+
+void DebugGrid::changeGrid(int16 pKey) {
+ if (!canChangeScenes) {
+ return;
+ }
+ // Press up - more X positions
+ if (pKey == Keys::NextRoom) {
+ _engine->_scene->currentSceneIdx++;
+ if (_engine->_scene->currentSceneIdx > NUM_SCENES)
+ _engine->_scene->currentSceneIdx = 0;
+ _engine->_scene->needChangeScene = _engine->_scene->currentSceneIdx;
+ _engine->_redraw->reqBgRedraw = 1;
+ }
+
+ // Press down - less X positions
+ if (pKey == Keys::PreviousRoom) {
+ _engine->_scene->currentSceneIdx--;
+ if (_engine->_scene->currentSceneIdx < 0)
+ _engine->_scene->currentSceneIdx = NUM_SCENES;
+ _engine->_scene->needChangeScene = _engine->_scene->currentSceneIdx;
+ _engine->_redraw->reqBgRedraw = 1;
+ }
+
+ if (_engine->cfgfile.Debug && (pKey == 'f' || pKey == 'r')) {
+ debug("Grid index changed: %d", _engine->_scene->needChangeScene);
+ }
+}
+
+void DebugGrid::applyCellingGrid(int16 pKey) {
+ // Increase celling grid index
+ if (pKey == Keys::IncreaseCellingGridIndex) {
+ _engine->_grid->cellingGridIdx++;
+ if (_engine->_grid->cellingGridIdx > 133)
+ _engine->_grid->cellingGridIdx = 133;
+ }
+ // Decrease celling grid index
+ else if (pKey == Keys::DecreaseCellingGridIndex) {
+ _engine->_grid->cellingGridIdx--;
+ if (_engine->_grid->cellingGridIdx < 0)
+ _engine->_grid->cellingGridIdx = 0;
+ }
+ // Enable/disable celling grid
+ else if (pKey == Keys::ApplyCellingGrid) {
+ if (_engine->_grid->useCellingGrid == -1) {
+ _engine->_grid->useCellingGrid = 1;
+ //createGridMap();
+ _engine->_grid->initCellingGrid(_engine->_grid->cellingGridIdx);
+ debug("Enable Celling Grid index: %d", _engine->_grid->cellingGridIdx);
+ _engine->_scene->needChangeScene = -2; // tricky to make the fade
+ } else if (_engine->_grid->useCellingGrid == 1) {
+ _engine->_grid->useCellingGrid = -1;
+ _engine->_grid->createGridMap();
+ _engine->_redraw->reqBgRedraw = 1;
+ debug("Disable Celling Grid index: %d", _engine->_grid->cellingGridIdx);
+ _engine->_scene->needChangeScene = -2; // tricky to make the fade
+ }
+ }
+}
+
+} // namespace TwinE
diff --git a/engines/twine/debug_grid.h b/engines/twine/debug_grid.h
new file mode 100644
index 0000000000..718d3de083
--- /dev/null
+++ b/engines/twine/debug_grid.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_GRIDDEBUG_H
+#define TWINE_GRIDDEBUG_H
+
+#include "common/scummsys.h"
+
+namespace TwinE {
+
+class TwinEEngine;
+
+class DebugGrid {
+private:
+ TwinEEngine *_engine;
+
+public:
+ DebugGrid(TwinEEngine *engine);
+
+ int32 useFreeCamera = 0;
+ int32 canChangeScenes = 0;
+
+ /** Change scenario camera positions */
+ void changeGridCamera(int16 pKey);
+ /** Change grid index */
+ void changeGrid(int16 pKey);
+ /** Apply and change disappear celling grid */
+ void applyCellingGrid(int16 pKey);
+};
+
+} // namespace TwinE
+
+#endif
diff --git a/engines/twine/debug_scene.cpp b/engines/twine/debug_scene.cpp
new file mode 100644
index 0000000000..d7c8256c0f
--- /dev/null
+++ b/engines/twine/debug_scene.cpp
@@ -0,0 +1,203 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/debug_scene.h"
+#include "twine/grid.h"
+#include "twine/interface.h"
+#include "twine/redraw.h"
+#include "twine/renderer.h"
+#include "twine/scene.h"
+#include "twine/twine.h"
+
+namespace TwinE {
+
+DebugScene::DebugScene(TwinEEngine *engine) : _engine(engine) {}
+
+void DebugScene::drawBoundingBoxProjectPoints(ScenePoint *pPoint3d, ScenePoint *pPoint3dProjected) {
+ _engine->_renderer->projectPositionOnScreen(pPoint3d->x, pPoint3d->y, pPoint3d->z);
+
+ pPoint3dProjected->x = _engine->_renderer->projPosX;
+ pPoint3dProjected->y = _engine->_renderer->projPosY;
+ pPoint3dProjected->z = _engine->_renderer->projPosZ;
+
+ if (_engine->_redraw->renderLeft > _engine->_renderer->projPosX)
+ _engine->_redraw->renderLeft = _engine->_renderer->projPosX;
+
+ if (_engine->_redraw->renderRight < _engine->_renderer->projPosX)
+ _engine->_redraw->renderRight = _engine->_renderer->projPosX;
+
+ if (_engine->_redraw->renderTop >_engine->_renderer->projPosY)
+ _engine->_redraw->renderTop = _engine->_renderer->projPosY;
+
+ if (_engine->_redraw->renderBottom < _engine->_renderer->projPosY)
+ _engine->_redraw->renderBottom = _engine->_renderer->projPosY;
+}
+
+int32 DebugScene::checkZoneType(int32 type) {
+ switch (type) {
+ case 0:
+ if (typeZones & 0x01)
+ return 1;
+ break;
+ case 1:
+ if (typeZones & 0x02)
+ return 1;
+ break;
+ case 2:
+ if (typeZones & 0x04)
+ return 1;
+ break;
+ case 3:
+ if (typeZones & 0x08)
+ return 1;
+ break;
+ case 4:
+ if (typeZones & 0x10)
+ return 1;
+ break;
+ case 5:
+ if (typeZones & 0x20)
+ return 1;
+ break;
+ case 6:
+ if (typeZones & 0x40)
+ return 1;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void DebugScene::displayZones(int16 pKey) {
+ if (showingZones == 1) {
+ int z;
+ ZoneStruct *zonePtr = _engine->_scene->sceneZones;
+ for (z = 0; z < _engine->_scene->sceneNumZones; z++) {
+ zonePtr = &_engine->_scene->sceneZones[z];
+
+ if (checkZoneType(zonePtr->type)) {
+ ScenePoint frontBottomLeftPoint;
+ ScenePoint frontBottomRightPoint;
+
+ ScenePoint frontTopLeftPoint;
+ ScenePoint frontTopRightPoint;
+
+ ScenePoint backBottomLeftPoint;
+ ScenePoint backBottomRightPoint;
+
+ ScenePoint backTopLeftPoint;
+ ScenePoint backTopRightPoint;
+
+ ScenePoint frontBottomLeftPoint2D;
+ ScenePoint frontBottomRightPoint2D;
+
+ ScenePoint frontTopLeftPoint2D;
+ ScenePoint frontTopRightPoint2D;
+
+ ScenePoint backBottomLeftPoint2D;
+ ScenePoint backBottomRightPoint2D;
+
+ ScenePoint backTopLeftPoint2D;
+ ScenePoint backTopRightPoint2D;
+
+ uint8 color;
+
+ // compute the points in 3D
+
+ frontBottomLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
+ frontBottomLeftPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
+ frontBottomLeftPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
+
+ frontBottomRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
+ frontBottomRightPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
+ frontBottomRightPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
+
+ frontTopLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
+ frontTopLeftPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
+ frontTopLeftPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
+
+ frontTopRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
+ frontTopRightPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
+ frontTopRightPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
+
+ backBottomLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
+ backBottomLeftPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
+ backBottomLeftPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
+
+ backBottomRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
+ backBottomRightPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
+ backBottomRightPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
+
+ backTopLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
+ backTopLeftPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
+ backTopLeftPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
+
+ backTopRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
+ backTopRightPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
+ backTopRightPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
+
+ // project all points
+
+ drawBoundingBoxProjectPoints(&frontBottomLeftPoint, &frontBottomLeftPoint2D);
+ drawBoundingBoxProjectPoints(&frontBottomRightPoint, &frontBottomRightPoint2D);
+ drawBoundingBoxProjectPoints(&frontTopLeftPoint, &frontTopLeftPoint2D);
+ drawBoundingBoxProjectPoints(&frontTopRightPoint, &frontTopRightPoint2D);
+ drawBoundingBoxProjectPoints(&backBottomLeftPoint, &backBottomLeftPoint2D);
+ drawBoundingBoxProjectPoints(&backBottomRightPoint, &backBottomRightPoint2D);
+ drawBoundingBoxProjectPoints(&backTopLeftPoint, &backTopLeftPoint2D);
+ drawBoundingBoxProjectPoints(&backTopRightPoint, &backTopRightPoint2D);
+
+ // draw all lines
+
+ color = 15 * 3 + zonePtr->type * 16;
+
+ // draw front part
+ _engine->_interface->drawLine(frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, color);
+ _engine->_interface->drawLine(frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, frontTopRightPoint2D.x, frontTopRightPoint2D.y, color);
+ _engine->_interface->drawLine(frontTopRightPoint2D.x, frontTopRightPoint2D.y, frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, color);
+ _engine->_interface->drawLine(frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, color);
+
+ // draw top part
+ _engine->_interface->drawLine(frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, backTopLeftPoint2D.x, backTopLeftPoint2D.y, color);
+ _engine->_interface->drawLine(backTopLeftPoint2D.x, backTopLeftPoint2D.y, backTopRightPoint2D.x, backTopRightPoint2D.y, color);
+ _engine->_interface->drawLine(backTopRightPoint2D.x, backTopRightPoint2D.y, frontTopRightPoint2D.x, frontTopRightPoint2D.y, color);
+ _engine->_interface->drawLine(frontTopRightPoint2D.x, frontTopRightPoint2D.y, frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, color);
+
+ // draw back part
+ _engine->_interface->drawLine(backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, backTopLeftPoint2D.x, backTopLeftPoint2D.y, color);
+ _engine->_interface->drawLine(backTopLeftPoint2D.x, backTopLeftPoint2D.y, backTopRightPoint2D.x, backTopRightPoint2D.y, color);
+ _engine->_interface->drawLine(backTopRightPoint2D.x, backTopRightPoint2D.y, backBottomRightPoint2D.x, backBottomRightPoint2D.y, color);
+ _engine->_interface->drawLine(backBottomRightPoint2D.x, backBottomRightPoint2D.y, backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, color);
+
+ // draw bottom part
+ _engine->_interface->drawLine(frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, color);
+ _engine->_interface->drawLine(backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, backBottomRightPoint2D.x, backBottomRightPoint2D.y, color);
+ _engine->_interface->drawLine(backBottomRightPoint2D.x, backBottomRightPoint2D.y, frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, color);
+ _engine->_interface->drawLine(frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, color);
+ }
+ }
+ }
+}
+
+} // namespace TwinE
diff --git a/engines/twine/debug_scene.h b/engines/twine/debug_scene.h
new file mode 100644
index 0000000000..4d633dd682
--- /dev/null
+++ b/engines/twine/debug_scene.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_DEBUG_SCENE_H
+#define TWINE_DEBUG_SCENE_H
+
+#include "common/scummsys.h"
+
+namespace TwinE {
+
+class TwinEEngine;
+struct ScenePoint;
+
+class DebugScene {
+private:
+ TwinEEngine *_engine;
+
+ void drawBoundingBoxProjectPoints(ScenePoint *pPoint3d, ScenePoint *pPoint3dProjected);
+ int32 checkZoneType(int32 type);
+public:
+ DebugScene(TwinEEngine *engine);
+ int32 showingZones = 0;
+ int32 typeZones = 127; // all zones on as default
+
+ void displayZones(int16 pKey);
+};
+
+} // namespace TwinE
+
+#endif
diff --git a/engines/twine/detection.cpp b/engines/twine/detection.cpp
index a84e977ec9..26df3f60cd 100644
--- a/engines/twine/detection.cpp
+++ b/engines/twine/detection.cpp
@@ -21,6 +21,7 @@
*/
#include "common/config-manager.h"
+#include "common/language.h"
#include "engines/advancedDetector.h"
#include "base/plugins.h"
#include "twine/detection.h"
@@ -33,12 +34,12 @@ static const PlainGameDescriptor twineGames[] = {
static const ADGameDescription twineGameDescriptions[] = {
{
"twine",
- "",
- AD_ENTRY1s("infobar.txt", "f1e42a95972643462b9c3c2ea79d6683", 543),
- Common::FR_FRA,
+ "GOG 1.0",
+ AD_ENTRY1s("text.hqr", "ae7343552f8fbd17a1fc6cea2197a912", 248654),
+ Common::EN_ANY,
Common::kPlatformDOS,
- TwinE::kGameFlagNoSubtitles,
- GUIO1(GUIO_NOMIDI)
+ 0,
+ GUIO1(GUIO_NONE)
},
AD_TABLE_END_MARKER
};
@@ -46,7 +47,6 @@ static const ADGameDescription twineGameDescriptions[] = {
class TwinEMetaEngineDetection : public AdvancedMetaEngineDetection {
public:
TwinEMetaEngineDetection() : AdvancedMetaEngineDetection(twineGameDescriptions, sizeof(ADGameDescription), twineGames) {
- _md5Bytes = 512;
}
const char *getEngineId() const override {
diff --git a/engines/twine/detection.h b/engines/twine/detection.h
index 9841764c9f..03a3cb7609 100644
--- a/engines/twine/detection.h
+++ b/engines/twine/detection.h
@@ -26,10 +26,7 @@
namespace TwinE {
enum GameFlag {
- kGameFlagDemo = 1 << 0,
- kGameFlagEncodedData = 1 << 1,
- kGameFlagNoSubtitles = 1 << 2,
- kGameFlagIntroOnly = 1 << 3
+ kGameFlagDemo = 1 << 0
};
} // End of namespace TwinE
diff --git a/engines/twine/extra.cpp b/engines/twine/extra.cpp
index 5a8c72f8ed..22231b77ae 100644
--- a/engines/twine/extra.cpp
+++ b/engines/twine/extra.cpp
@@ -1,110 +1,108 @@
-/** @file extra.cpp
- @brief
- This file contains extra (bonus, projectils, keys, etc.) routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include <stdio.h>
-
-#include "extra.h"
-#include "lbaengine.h"
-#include "collision.h"
-#include "resources.h"
-#include "gamestate.h"
-#include "scene.h"
-#include "movements.h"
-#include "renderer.h"
-#include "grid.h"
-#include "sound.h"
-#include "redraw.h"
-#include "interface.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/extra.h"
+#include "common/util.h"
+#include "twine/collision.h"
+#include "twine/gamestate.h"
+#include "twine/grid.h"
+#include "twine/interface.h"
+#include "twine/movements.h"
+#include "twine/redraw.h"
+#include "twine/renderer.h"
+#include "twine/resources.h"
+#include "twine/scene.h"
+#include "twine/sound.h"
+#include "twine/twine.h"
+
+namespace TwinE {
/** Hit Stars shape info */
-int16 hitStarsShapeTable[] = {
- 10,
- 0,
- -20,
- 4,
- -6,
- 19,
- -6,
- 7,
- 2,
- 12,
- 16,
- 0,
- 7,
- -12,
- 16,
- -7,
- 2,
- -19,
- -6,
- -4,
- -6
-};
+static const int16 hitStarsShapeTable[] = {
+ 10,
+ 0,
+ -20,
+ 4,
+ -6,
+ 19,
+ -6,
+ 7,
+ 2,
+ 12,
+ 16,
+ 0,
+ 7,
+ -12,
+ 16,
+ -7,
+ 2,
+ -19,
+ -6,
+ -4,
+ -6};
/** Explode Cloud shape info */
-int16 explodeCloudShapeTable [] = {
- 18,
- 0,
- -20,
- 6,
- -16,
- 8,
- -10,
- 14,
- -12,
- 20,
- -4,
- 18,
- 4,
- 12,
- 4,
- 16,
- 8,
- 8,
- 16,
- 2,
- 12,
- -4,
- 18,
- -10,
- 16,
- -12,
- 8,
- -16,
- 10,
- -20,
- 4,
- -12,
- -8,
- -6,
- -6,
- -10,
- -12
-};
-
-int32 addExtra(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 info0, int32 targetActor, int32 maxSpeed, int32 strengthOfHit) {
+static const int16 explodeCloudShapeTable[] = {
+ 18,
+ 0,
+ -20,
+ 6,
+ -16,
+ 8,
+ -10,
+ 14,
+ -12,
+ 20,
+ -4,
+ 18,
+ 4,
+ 12,
+ 4,
+ 16,
+ 8,
+ 8,
+ 16,
+ 2,
+ 12,
+ -4,
+ 18,
+ -10,
+ 16,
+ -12,
+ 8,
+ -16,
+ 10,
+ -20,
+ 4,
+ -12,
+ -8,
+ -6,
+ -6,
+ -10,
+ -12};
+
+Extra::Extra(TwinEEngine *engine) : _engine(engine) {}
+
+int32 Extra::addExtra(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 info0, int32 targetActor, int32 maxSpeed, int32 strengthOfHit) {
int32 i;
for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
@@ -113,27 +111,23 @@ int32 addExtra(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 info0, int32 tar
extra->info0 = info0;
extra->type = 0x80;
extra->info1 = 0;
- extra->X = X;
- extra->Y = Y;
- extra->Z = Z;
+ extra->x = X;
+ extra->y = Y;
+ extra->z = Z;
extra->actorIdx = actorIdx;
extra->lifeTime = targetActor;
extra->destZ = maxSpeed;
extra->strengthOfHit = strengthOfHit;
- setActorAngle(0, maxSpeed, 50, &extra->trackActorMove);
- extra->angle = getAngleAndSetTargetActorDistance(X, Z, sceneActors[targetActor].X, sceneActors[targetActor].Z);
+ _engine->_movements->setActorAngle(0, maxSpeed, 50, &extra->trackActorMove);
+ extra->angle = _engine->_movements->getAngleAndSetTargetActorDistance(X, Z, _engine->_scene->sceneActors[targetActor].x, _engine->_scene->sceneActors[targetActor].z);
return i;
}
}
return -1;
}
-/** Add extra explosion
- @param X Explostion X coordinate
- @param Y Explostion Y coordinate
- @param Z Explostion Z coordinate */
-int32 addExtraExplode(int32 X, int32 Y, int32 Z) {
+int32 Extra::addExtraExplode(int32 X, int32 Y, int32 Z) {
int32 i;
for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
@@ -142,11 +136,11 @@ int32 addExtraExplode(int32 X, int32 Y, int32 Z) {
extra->info0 = 0x61;
extra->type = 0x1001;
extra->info1 = 0;
- extra->X = X;
- extra->Y = Y;
- extra->Z = Z;
+ extra->x = X;
+ extra->y = Y;
+ extra->z = Z;
extra->actorIdx = 0x28;
- extra->lifeTime = lbaTime;
+ extra->lifeTime = _engine->lbaTime;
extra->strengthOfHit = 0;
return i;
}
@@ -154,8 +148,7 @@ int32 addExtraExplode(int32 X, int32 Y, int32 Z) {
return -1;
}
-/** Reset all used extras */
-void resetExtras() {
+void Extra::resetExtras() {
int32 i;
for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
@@ -165,27 +158,27 @@ void resetExtras() {
}
}
-void throwExtra(ExtraListStruct *extra, int32 var1, int32 var2, int32 var3, int32 var4) { // InitFly
+void Extra::throwExtra(ExtraListStruct *extra, int32 var1, int32 var2, int32 var3, int32 var4) { // InitFly
extra->type |= 2;
- extra->lastX = extra->X;
- extra->lastY = extra->Y;
- extra->lastZ = extra->Z;
+ extra->lastX = extra->x;
+ extra->lastY = extra->y;
+ extra->lastZ = extra->z;
- rotateActor(var3, 0, var1);
+ _engine->_movements->rotateActor(var3, 0, var1);
- extra->destY = -destZ;
+ extra->destY = -_engine->_renderer->destZ;
- rotateActor(0, destX, var2);
+ _engine->_movements->rotateActor(0, _engine->_renderer->destX, var2);
- extra->destX = destX;
- extra->destZ = destZ;
+ extra->destX = _engine->_renderer->destX;
+ extra->destZ = _engine->_renderer->destZ;
extra->angle = var4;
- extra->lifeTime = lbaTime;
+ extra->lifeTime = _engine->lbaTime;
}
-void addExtraSpecial(int32 X, int32 Y, int32 Z, int32 type) { // InitSpecial
+void Extra::addExtraSpecial(int32 X, int32 Y, int32 Z, int32 type) { // InitSpecial
int32 i;
int16 flag = 0x8000 + type;
@@ -198,27 +191,28 @@ void addExtraSpecial(int32 X, int32 Y, int32 Z, int32 type) { // InitSpecial
if (type == kHitStars) {
extra->type = 9;
- extra->X = X;
- extra->Y = Y;
- extra->Z = Z;
+ extra->x = X;
+ extra->y = Y;
+ extra->z = Z;
// same as InitFly
- throwExtra(extra, Rnd(0x100) + 0x80, Rnd(0x400), 50, 20);
+ throwExtra(extra, _engine->getRandomNumber(0x100) + 0x80, _engine->getRandomNumber(0x400), 50, 20);
extra->strengthOfHit = 0;
- extra->lifeTime = lbaTime;
+ extra->lifeTime = _engine->lbaTime;
extra->actorIdx = 100;
return;
- } else if (type == kExplodeCloud) {
+ }
+ if (type == kExplodeCloud) {
extra->type = 1;
- extra->X = X;
- extra->Y = Y;
- extra->Z = Z;
+ extra->x = X;
+ extra->y = Y;
+ extra->z = Z;
extra->strengthOfHit = 0;
- extra->lifeTime = lbaTime;
+ extra->lifeTime = _engine->lbaTime;
extra->actorIdx = 5;
return;
@@ -227,7 +221,7 @@ void addExtraSpecial(int32 X, int32 Y, int32 Z, int32 type) { // InitSpecial
}
}
-int32 addExtraBonus(int32 X, int32 Y, int32 Z, int32 param, int32 angle, int32 type, int32 bonusAmount) { // ExtraBonus
+int32 Extra::addExtraBonus(int32 X, int32 Y, int32 Z, int32 param, int32 angle, int32 type, int32 bonusAmount) { // ExtraBonus
int32 i;
for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
@@ -240,15 +234,15 @@ int32 addExtraBonus(int32 X, int32 Y, int32 Z, int32 param, int32 angle, int32 t
extra->type = 0x4030;
}*/
- extra->X = X;
- extra->Y = Y;
- extra->Z = Z;
+ extra->x = X;
+ extra->y = Y;
+ extra->z = Z;
// same as InitFly
throwExtra(extra, param, angle, 40, 15);
extra->strengthOfHit = 0;
- extra->lifeTime = lbaTime;
+ extra->lifeTime = _engine->lbaTime;
extra->actorIdx = 1000;
extra->info1 = bonusAmount;
@@ -259,7 +253,7 @@ int32 addExtraBonus(int32 X, int32 Y, int32 Z, int32 param, int32 angle, int32 t
return -1;
}
-int32 addExtraThrow(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprite, int32 var2, int32 var3, int32 var4, int32 var5, int32 strengthOfHit) { // ThrowExtra
+int32 Extra::addExtraThrow(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprite, int32 var2, int32 var3, int32 var4, int32 var5, int32 strengthOfHit) { // ThrowExtra
int32 i;
for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
@@ -267,15 +261,15 @@ int32 addExtraThrow(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprite, int
if (extra->info0 == -1) {
extra->info0 = sprite;
extra->type = 0x210C;
- extra->X = X;
- extra->Y = Y;
- extra->Z = Z;
+ extra->x = X;
+ extra->y = Y;
+ extra->z = Z;
// same as InitFly
throwExtra(extra, var2, var3, var4, var5);
extra->strengthOfHit = strengthOfHit;
- extra->lifeTime = lbaTime;
+ extra->lifeTime = _engine->lbaTime;
extra->actorIdx = actorIdx;
extra->info1 = 0;
@@ -286,7 +280,7 @@ int32 addExtraThrow(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprite, int
return -1;
}
-int32 addExtraAiming(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 targetActorIdx, int32 maxSpeed, int32 strengthOfHit) { // ExtraSearch
+int32 Extra::addExtraAiming(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 targetActorIdx, int32 maxSpeed, int32 strengthOfHit) { // ExtraSearch
int32 i;
for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
@@ -295,15 +289,15 @@ int32 addExtraAiming(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx,
extra->info0 = spriteIdx;
extra->type = 0x80;
extra->info1 = 0;
- extra->X = X;
- extra->Y = Y;
- extra->Z = Z;
+ extra->x = X;
+ extra->y = Y;
+ extra->z = Z;
extra->actorIdx = actorIdx;
extra->lifeTime = targetActorIdx;
extra->destZ = maxSpeed;
extra->strengthOfHit = strengthOfHit;
- setActorAngle(0, maxSpeed, 50, &extra->trackActorMove);
- extra->angle = getAngleAndSetTargetActorDistance(X, Z, sceneActors[targetActorIdx].X, sceneActors[targetActorIdx].Z);
+ _engine->_movements->setActorAngle(0, maxSpeed, 50, &extra->trackActorMove);
+ extra->angle = _engine->_movements->getAngleAndSetTargetActorDistance(X, Z, _engine->_scene->sceneActors[targetActorIdx].x, _engine->_scene->sceneActors[targetActorIdx].z);
return i;
}
@@ -313,7 +307,7 @@ int32 addExtraAiming(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx,
}
// cseg01:00018168
-int32 findExtraKey() {
+int32 Extra::findExtraKey() {
int32 i;
for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
@@ -327,7 +321,7 @@ int32 findExtraKey() {
}
// cseg01:00018250
-int32 addExtraAimingAtKey(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 extraIdx) { // addMagicBallAimingAtKey
+int32 Extra::addExtraAimingAtKey(int32 actorIdx, int32 x, int32 y, int32 z, int32 spriteIdx, int32 extraIdx) { // addMagicBallAimingAtKey
int32 i;
for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
@@ -336,14 +330,14 @@ int32 addExtraAimingAtKey(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprit
extra->info0 = spriteIdx;
extra->type = 0x200;
extra->info1 = 0;
- extra->X = X;
- extra->Y = Y;
- extra->Z = Z;
+ extra->x = x;
+ extra->y = y;
+ extra->z = z;
extra->actorIdx = extraIdx;
extra->destZ = 0x0FA0;
extra->strengthOfHit = 0;
- setActorAngle(0, 0x0FA0, 50, &extra->trackActorMove);
- extra->angle = getAngleAndSetTargetActorDistance(X, Z, extraList[extraIdx].X, extraList[extraIdx].Z);
+ _engine->_movements->setActorAngle(0, 0x0FA0, 50, &extra->trackActorMove);
+ extra->angle = _engine->_movements->getAngleAndSetTargetActorDistance(x, z, extraList[extraIdx].x, extraList[extraIdx].z);
return i;
}
@@ -352,12 +346,12 @@ int32 addExtraAimingAtKey(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprit
return -1;
}
-void addExtraThrowMagicball(int32 X, int32 Y, int32 Z, int32 param1, int32 angle, int32 param2, int32 param3) { // ThrowMagicBall
+void Extra::addExtraThrowMagicball(int32 X, int32 Y, int32 Z, int32 param1, int32 angle, int32 param2, int32 param3) { // ThrowMagicBall
int32 ballSprite = -1;
int32 ballStrength = 0;
int32 extraIdx = -1;
- switch (magicLevelIdx) {
+ switch (_engine->_gameState->magicLevelIdx) {
case 0:
case 1:
ballSprite = 1;
@@ -377,42 +371,42 @@ void addExtraThrowMagicball(int32 X, int32 Y, int32 Z, int32 param1, int32 angle
break;
}
- magicBallNumBounce = ((inventoryMagicPoints - 1) / 20) + 1;
- if (inventoryMagicPoints == 0) {
- magicBallNumBounce = 0;
+ _engine->_gameState->magicBallNumBounce = ((_engine->_gameState->inventoryMagicPoints - 1) / 20) + 1;
+ if (_engine->_gameState->inventoryMagicPoints == 0) {
+ _engine->_gameState->magicBallNumBounce = 0;
}
extraIdx = findExtraKey();
if (extraIdx != -1) { // there is a key to aim
- magicBallNumBounce = 5;
+ _engine->_gameState->magicBallNumBounce = 5;
}
- switch (magicBallNumBounce) {
+ switch (_engine->_gameState->magicBallNumBounce) {
case 0:
- magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
+ _engine->_gameState->magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
break;
case 1:
- magicBallAuxBounce = 4;
- magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
+ _engine->_gameState->magicBallAuxBounce = 4;
+ _engine->_gameState->magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
break;
case 2:
case 3:
case 4:
- magicBallNumBounce = 1;
- magicBallAuxBounce = 4;
- magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
+ _engine->_gameState->magicBallNumBounce = 1;
+ _engine->_gameState->magicBallAuxBounce = 4;
+ _engine->_gameState->magicBallIdx = addExtraThrow(0, X, Y, Z, ballSprite, param1, angle, param2, param3, ballStrength);
break;
case 5:
- magicBallIdx = addExtraAimingAtKey(0, X, Y, Z, ballSprite, extraIdx);
- break;
+ _engine->_gameState->magicBallIdx = addExtraAimingAtKey(0, X, Y, Z, ballSprite, extraIdx);
+ break;
}
- if (inventoryMagicPoints > 0) {
- inventoryMagicPoints--;
+ if (_engine->_gameState->inventoryMagicPoints > 0) {
+ _engine->_gameState->inventoryMagicPoints--;
}
}
-void drawSpecialShape(int16 *shapeTable, int32 X, int32 Y, int32 color, int32 angle, int32 size) {
+void Extra::drawSpecialShape(const int16 *shapeTable, int32 X, int32 Y, int32 color, int32 angle, int32 size) {
int16 currentShapeTable;
int16 var_8;
int16 temp1;
@@ -429,27 +423,27 @@ void drawSpecialShape(int16 *shapeTable, int32 X, int32 Y, int32 color, int32 an
var_8 = ((*(shapeTable++)) * size) >> 4;
temp1 = ((*(shapeTable++)) * size) >> 4;
- renderLeft = 0x7D00;
- renderRight = -0x7D00;
- renderTop = 0x7D00;
- renderBottom = -0x7D00;
+ _engine->_redraw->renderLeft = 0x7D00;
+ _engine->_redraw->renderRight = -0x7D00;
+ _engine->_redraw->renderTop = 0x7D00;
+ _engine->_redraw->renderBottom = -0x7D00;
- rotateActor(var_8, temp1, angle);
+ _engine->_movements->rotateActor(var_8, temp1, angle);
- computedX = destX + X;
- computedY = destZ + Y;
+ computedX = _engine->_renderer->destX + X;
+ computedY = _engine->_renderer->destZ + Y;
- if (computedX < renderLeft)
- renderLeft = computedX;
+ if (computedX < _engine->_redraw->renderLeft)
+ _engine->_redraw->renderLeft = computedX;
- if (computedX > renderRight)
- renderRight = computedX;
+ if (computedX > _engine->_redraw->renderRight)
+ _engine->_redraw->renderRight = computedX;
- if (computedY < renderTop)
- renderTop = computedY;
+ if (computedY < _engine->_redraw->renderTop)
+ _engine->_redraw->renderTop = computedY;
- if (computedY > renderBottom)
- renderBottom = computedY;
+ if (computedY > _engine->_redraw->renderBottom)
+ _engine->_redraw->renderBottom = computedY;
numEntries = 1;
@@ -463,89 +457,87 @@ void drawSpecialShape(int16 *shapeTable, int32 X, int32 Y, int32 color, int32 an
oldComputedX = currentX;
oldComputedY = currentY;
- projPosX = currentX;
- projPosY = currentY;
+ _engine->_renderer->projPosX = currentX;
+ _engine->_renderer->projPosY = currentY;
- rotateActor(var_8, temp1, angle);
+ _engine->_movements->rotateActor(var_8, temp1, angle);
- currentX = destX + X;
- currentY = destZ + Y;
+ currentX = _engine->_renderer->destX + X;
+ currentY = _engine->_renderer->destZ + Y;
- if (currentX < renderLeft)
- renderLeft = currentX;
+ if (currentX < _engine->_redraw->renderLeft)
+ _engine->_redraw->renderLeft = currentX;
- if (currentX > renderRight)
- renderRight = currentX;
+ if (currentX > _engine->_redraw->renderRight)
+ _engine->_redraw->renderRight = currentX;
- if (currentY < renderTop)
- renderTop = currentY;
+ if (currentY < _engine->_redraw->renderTop)
+ _engine->_redraw->renderTop = currentY;
- if (currentY > renderBottom)
- renderBottom = currentY;
+ if (currentY > _engine->_redraw->renderBottom)
+ _engine->_redraw->renderBottom = currentY;
- projPosX = currentX;
- projPosY = currentY;
+ _engine->_renderer->projPosX = currentX;
+ _engine->_renderer->projPosY = currentY;
- drawLine(oldComputedX, oldComputedY, currentX, currentY, color);
+ _engine->_interface->drawLine(oldComputedX, oldComputedY, currentX, currentY, color);
numEntries++;
- currentX = projPosX;
- currentY = projPosY;
-
+ currentX = _engine->_renderer->projPosX;
+ currentY = _engine->_renderer->projPosY;
}
- projPosX = currentX;
- projPosY = currentY;
- drawLine(currentX, currentY, computedX, computedY, color);
+ _engine->_renderer->projPosX = currentX;
+ _engine->_renderer->projPosY = currentY;
+ _engine->_interface->drawLine(currentX, currentY, computedX, computedY, color);
}
-void drawExtraSpecial(int32 extraIdx, int32 X, int32 Y) {
+void Extra::drawExtraSpecial(int32 extraIdx, int32 X, int32 Y) {
int32 specialType;
ExtraListStruct *extra = &extraList[extraIdx];
specialType = extra->info0 & 0x7FFF;
- switch(specialType) {
+ switch (specialType) {
case kHitStars:
- drawSpecialShape(hitStarsShapeTable, X, Y, 15, (lbaTime << 5) & 0x300, 4);
+ drawSpecialShape(hitStarsShapeTable, X, Y, 15, (_engine->lbaTime << 5) & 0x300, 4);
break;
case kExplodeCloud: {
- int32 cloudTime = 1 + lbaTime - extra->lifeTime;
+ int32 cloudTime = 1 + _engine->lbaTime - extra->lifeTime;
if (cloudTime > 32) {
cloudTime = 32;
}
drawSpecialShape(explodeCloudShapeTable, X, Y, 15, 0, cloudTime);
- }
- break;
+ } break;
}
}
-void processMagicballBounce(ExtraListStruct *extra, int32 X, int32 Y, int32 Z) {
- if (getBrickShape(X, extra->Y, Z)) {
+void Extra::processMagicballBounce(ExtraListStruct *extra, int32 X, int32 Y, int32 Z) {
+ if (_engine->_grid->getBrickShape(X, extra->y, Z)) {
extra->destY = -extra->destY;
}
- if (getBrickShape(extra->X, Y, Z)) {
+ if (_engine->_grid->getBrickShape(extra->x, Y, Z)) {
extra->destX = -extra->destX;
}
- if (getBrickShape(X, Y, extra->Z)) {
+ if (_engine->_grid->getBrickShape(X, Y, extra->z)) {
extra->destZ = -extra->destZ;
}
- extra->X = X;
+ extra->x = X;
extra->lastX = X;
- extra->Y = Y;
+ extra->y = Y;
extra->lastY = Y;
- extra->Z = Z;
+ extra->z = Z;
extra->lastZ = Z;
- extra->lifeTime = lbaTime;
+ extra->lifeTime = _engine->lbaTime;
}
/** Process extras */
-void processExtras() {
+void Extra::processExtras() {
int32 i;
int32 currentExtraX = 0;
@@ -559,7 +551,7 @@ void processExtras() {
if (extra->info0 != -1) {
// process extra life time
if (extra->type & 0x1) {
- if (extra->actorIdx + extra->lifeTime <= lbaTime) {
+ if (extra->actorIdx + extra->lifeTime <= _engine->lbaTime) {
extra->info0 = -1;
continue;
}
@@ -571,28 +563,28 @@ void processExtras() {
}
//
if (extra->type & 0x1000) {
- extra->info0 = getAverageValue(97, 100, 30, lbaTime - extra->lifeTime);
+ extra->info0 = _engine->_collision->getAverageValue(97, 100, 30, _engine->lbaTime - extra->lifeTime);
continue;
}
// process extra moving
if (extra->type & 0x2) {
- currentExtraX = extra->X;
- currentExtraY = extra->Y;
- currentExtraZ = extra->Z;
+ currentExtraX = extra->x;
+ currentExtraY = extra->y;
+ currentExtraZ = extra->z;
- currentExtraSpeedX = extra->destX * (lbaTime - extra->lifeTime);
- extra->X = currentExtraSpeedX + extra->lastX;
+ currentExtraSpeedX = extra->destX * (_engine->lbaTime - extra->lifeTime);
+ extra->x = currentExtraSpeedX + extra->lastX;
- currentExtraSpeedY = extra->destY * (lbaTime - extra->lifeTime);
+ currentExtraSpeedY = extra->destY * (_engine->lbaTime - extra->lifeTime);
currentExtraSpeedY += extra->lastY;
- extra->Y = currentExtraSpeedY - Abs(((extra->angle * (lbaTime - extra->lifeTime))* (lbaTime - extra->lifeTime)) >> 4);
+ extra->y = currentExtraSpeedY - ABS(((extra->angle * (_engine->lbaTime - extra->lifeTime)) * (_engine->lbaTime - extra->lifeTime)) >> 4);
- extra->Z = extra->destZ * (lbaTime - extra->lifeTime) + extra->lastZ;
+ extra->z = extra->destZ * (_engine->lbaTime - extra->lifeTime) + extra->lastZ;
// check if extra is out of scene
- if (extra->Y < 0 || extra->X < 0 || extra->X > 0x7E00 || extra->Z < 0 || extra->Z > 0x7E00) {
+ if (extra->y < 0 || extra->x < 0 || extra->x > 0x7E00 || extra->z < 0 || extra->z > 0x7E00) {
// if extra is Magic Ball
- if (i == magicBallIdx) {
+ if (i == _engine->_gameState->magicBallIdx) {
int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
@@ -602,7 +594,7 @@ void processExtras() {
spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
}
- magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 10000, 0);
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
}
// if can take extra on ground
@@ -617,7 +609,7 @@ void processExtras() {
}
//
if (extra->type & 0x4000) {
- if (lbaTime - extra->lifeTime > 40) {
+ if (_engine->lbaTime - extra->lifeTime > 40) {
extra->type &= 0xBFFF;
}
continue;
@@ -629,47 +621,45 @@ void processExtras() {
actorIdxAttacked = extra->lifeTime;
actorIdx = extra->actorIdx;
- currentExtraX = sceneActors[actorIdxAttacked].X;
- currentExtraY = sceneActors[actorIdxAttacked].Y + 1000;
- currentExtraZ = sceneActors[actorIdxAttacked].Z;
+ currentExtraX = _engine->_scene->sceneActors[actorIdxAttacked].x;
+ currentExtraY = _engine->_scene->sceneActors[actorIdxAttacked].y + 1000;
+ currentExtraZ = _engine->_scene->sceneActors[actorIdxAttacked].z;
- tmpAngle = getAngleAndSetTargetActorDistance(extra->X, extra->Z, currentExtraX, currentExtraZ);
+ tmpAngle = _engine->_movements->getAngleAndSetTargetActorDistance(extra->x, extra->z, currentExtraX, currentExtraZ);
angle = (tmpAngle - extra->angle) & 0x3FF;
if (angle > 400 && angle < 600) {
if (extra->strengthOfHit) {
- hitActor(actorIdx, actorIdxAttacked, extra->strengthOfHit, -1);
+ _engine->_actor->hitActor(actorIdx, actorIdxAttacked, extra->strengthOfHit, -1);
}
- if (i == magicBallIdx) {
- magicBallIdx = -1;
+ if (i == _engine->_gameState->magicBallIdx) {
+ _engine->_gameState->magicBallIdx = -1;
}
extra->info0 = -1;
continue;
} else {
- int32 angle, pos;
-
- angle = getAngleAndSetTargetActorDistance(extra->Y, 0, currentExtraY, targetActorDistance);
+ const int32 angle2 = _engine->_movements->getAngleAndSetTargetActorDistance(extra->y, 0, currentExtraY, _engine->_movements->targetActorDistance);
- pos = getRealAngle(&extra->trackActorMove);
+ int32 pos = _engine->_movements->getRealAngle(&extra->trackActorMove);
if (!pos) {
pos = 1;
}
- rotateActor(pos, 0, angle);
- extra->Y -= destZ;
+ _engine->_movements->rotateActor(pos, 0, angle2);
+ extra->y -= _engine->_renderer->destZ;
- rotateActor(0, destX, tmpAngle);
- extra->X += destX;
- extra->Z += destZ;
+ _engine->_movements->rotateActor(0, _engine->_renderer->destX, tmpAngle);
+ extra->x += _engine->_renderer->destX;
+ extra->z += _engine->_renderer->destZ;
- setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
+ _engine->_movements->setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
- if (actorIdxAttacked == checkExtraCollisionWithActors(extra, actorIdx)) {
- if (i == magicBallIdx) {
- magicBallIdx = -1;
+ if (actorIdxAttacked == _engine->_collision->checkExtraCollisionWithActors(extra, actorIdx)) {
+ if (i == _engine->_gameState->magicBallIdx) {
+ _engine->_gameState->magicBallIdx = -1;
}
extra->info0 = -1;
@@ -679,66 +669,62 @@ void processExtras() {
}
// process magic ball extra aiming for key
if (extra->type & 0x200) {
- int32 actorIdx, tmpAngle, angle;
-// int32 actorIdxAttacked = extra->lifeTime;
- ExtraListStruct *extraKey = &extraList[extra->actorIdx];
- actorIdx = extra->actorIdx;
+ // int32 actorIdxAttacked = extra->lifeTime;
+ ExtraListStruct *extraKey = &extraList[extra->actorIdx];
+ int32 actorIdx = extra->actorIdx;
- tmpAngle = getAngleAndSetTargetActorDistance(extra->X, extra->Z, extraKey->X, extraKey->Z);
- angle = (tmpAngle - extra->angle) & 0x3FF;
+ int32 tmpAngle = _engine->_movements->getAngleAndSetTargetActorDistance(extra->x, extra->z, extraKey->x, extraKey->z);
+ int32 angle = (tmpAngle - extra->angle) & 0x3FF;
if (angle > 400 && angle < 600) {
- playSample(97, 0x1000, 1, sceneHero->X, sceneHero->Y, sceneHero->Z, 0);
+ _engine->_sound->playSample(97, 0x1000, 1, _engine->_scene->sceneHero->x, _engine->_scene->sceneHero->y, _engine->_scene->sceneHero->z, 0);
- if (extraKey->info1 > 1) {
- projectPositionOnScreen(extraKey->X - cameraX, extraKey->Y - cameraY, extraKey->Z - cameraZ);
- addOverlay(koNumber, extraKey->info1, projPosX, projPosY, koNormal, 0, 2);
- }
+ if (extraKey->info1 > 1) {
+ _engine->_renderer->projectPositionOnScreen(extraKey->x - _engine->_grid->cameraX, extraKey->y - _engine->_grid->cameraY, extraKey->z - _engine->_grid->cameraZ);
+ _engine->_redraw->addOverlay(koNumber, extraKey->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, koNormal, 0, 2);
+ }
- addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
+ _engine->_redraw->addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
- inventoryNumKeys += extraKey->info1;
- extraKey->info0 = -1;
+ _engine->_gameState->inventoryNumKeys += extraKey->info1;
+ extraKey->info0 = -1;
extra->info0 = -1;
- magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, SPRITEHQR_KEY, 0, 8000, 0);
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, SPRITEHQR_KEY, 0, 8000, 0);
continue;
- } else {
- int32 angle, pos;
-
- angle = getAngleAndSetTargetActorDistance(extra->Y, 0, extraKey->Y, targetActorDistance);
- pos = getRealAngle(&extra->trackActorMove);
+ }
+ int32 angle2 = _engine->_movements->getAngleAndSetTargetActorDistance(extra->y, 0, extraKey->y, _engine->_movements->targetActorDistance);
+ int32 pos = _engine->_movements->getRealAngle(&extra->trackActorMove);
- if (!pos) {
- pos = 1;
- }
+ if (!pos) {
+ pos = 1;
+ }
- rotateActor(pos, 0, angle);
- extra->Y -= destZ;
+ _engine->_movements->rotateActor(pos, 0, angle2);
+ extra->y -= _engine->_renderer->destZ;
- rotateActor(0, destX, tmpAngle);
- extra->X += destX;
- extra->Z += destZ;
+ _engine->_movements->rotateActor(0, _engine->_renderer->destX, tmpAngle);
+ extra->x += _engine->_renderer->destX;
+ extra->z += _engine->_renderer->destZ;
- setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
+ _engine->_movements->setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
- if (actorIdx == checkExtraCollisionWithExtra(extra, magicBallIdx)) {
- playSample(97, 0x1000, 1, sceneHero->X, sceneHero->Y, sceneHero->Z, 0);
+ if (actorIdx == _engine->_collision->checkExtraCollisionWithExtra(extra, _engine->_gameState->magicBallIdx)) {
+ _engine->_sound->playSample(97, 0x1000, 1, _engine->_scene->sceneHero->x, _engine->_scene->sceneHero->y, _engine->_scene->sceneHero->z, 0);
- if (extraKey->info1 > 1) {
- projectPositionOnScreen(extraKey->X - cameraX, extraKey->Y - cameraY, extraKey->Z - cameraZ);
- addOverlay(koNumber, extraKey->info1, projPosX, projPosY, koNormal, 0, 2);
- }
+ if (extraKey->info1 > 1) {
+ _engine->_renderer->projectPositionOnScreen(extraKey->x - _engine->_grid->cameraX, extraKey->y - _engine->_grid->cameraY, extraKey->z - _engine->_grid->cameraZ);
+ _engine->_redraw->addOverlay(koNumber, extraKey->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, koNormal, 0, 2);
+ }
- addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
+ _engine->_redraw->addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
- inventoryNumKeys += extraKey->info1;
- extraKey->info0 = -1;
+ _engine->_gameState->inventoryNumKeys += extraKey->info1;
+ extraKey->info0 = -1;
- extra->info0 = -1;
- magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, SPRITEHQR_KEY, 0, 8000, 0);
- continue;
- }
+ extra->info0 = -1;
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, SPRITEHQR_KEY, 0, 8000, 0);
+ continue;
}
if (extraKey->info0 == -1) {
int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
@@ -751,15 +737,15 @@ void processExtras() {
}
extra->info0 = -1;
- magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 8000, 0);
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 8000, 0);
continue;
}
}
// process extra collision with actors
if (extra->type & 0x4) {
- if (checkExtraCollisionWithActors(extra, extra->actorIdx) != -1) {
+ if (_engine->_collision->checkExtraCollisionWithActors(extra, extra->actorIdx) != -1) {
// if extra is Magic Ball
- if (i == magicBallIdx) {
+ if (i == _engine->_gameState->magicBallIdx) {
int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
@@ -769,7 +755,7 @@ void processExtras() {
spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
}
- magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 10000, 0);
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
}
extra->info0 = -1;
@@ -780,7 +766,7 @@ void processExtras() {
if (extra->type & 0x8) {
int32 process = 0;
- if (checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->X, extra->Y, extra->Z)) {
+ if (_engine->_collision->checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->x, extra->y, extra->z)) {
// if not touch the ground
if (!(extra->type & 0x2000)) {
process = 1;
@@ -798,12 +784,12 @@ void processExtras() {
addExtraSpecial(currentExtraX, currentExtraY, currentExtraZ, kExplodeCloud);
}
// if extra is magic ball
- if (i == magicBallIdx) {
+ if (i == _engine->_gameState->magicBallIdx) {
// FIXME: add constant for sample index
- playSample(86, Rnd(300) + 3946, 1, extra->X, extra->Y, extra->Z, -1);
+ _engine->_sound->playSample(86, _engine->getRandomNumber(300) + 3946, 1, extra->x, extra->y, extra->z, -1);
// cant bounce with not magic points
- if (magicBallNumBounce <= 0) {
+ if (_engine->_gameState->magicBallNumBounce <= 0) {
int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
@@ -813,15 +799,15 @@ void processExtras() {
spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
}
- magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 10000, 0);
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
extra->info0 = -1;
continue;
}
// if has magic points
- if (magicBallNumBounce == 1) {
- if (!magicBallAuxBounce--) {
+ if (_engine->_gameState->magicBallNumBounce == 1) {
+ if (!_engine->_gameState->magicBallAuxBounce--) {
int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
@@ -831,7 +817,7 @@ void processExtras() {
spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
}
- magicBallIdx = addExtra(-1, extra->X, extra->Y, extra->Z, spriteIdx, 0, 10000, 0);
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
extra->info0 = -1;
continue;
@@ -849,7 +835,7 @@ void processExtras() {
if (extra->type & 0x10) {
int32 process = 0;
- if (checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->X, extra->Y, extra->Z)) {
+ if (_engine->_collision->checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->x, extra->y, extra->z)) {
// if not touch the ground
if (!(extra->type & 0x2000)) {
process = 1;
@@ -864,8 +850,8 @@ void processExtras() {
if (process) {
int16 *spriteBounds;
- spriteBounds = (int16 *)(spriteBoundingBoxPtr + extra->info0 * 16 + 8);
- extra->Y = (collisionY << 8) + 0x100 - *(spriteBounds);
+ spriteBounds = (int16 *)(_engine->_scene->spriteBoundingBoxPtr + extra->info0 * 16 + 8);
+ extra->y = (_engine->_collision->collisionY << 8) + 0x100 - *(spriteBounds);
extra->type &= 0xFFED;
continue;
}
@@ -873,46 +859,46 @@ void processExtras() {
// get extras on ground
if ((extra->type & 0x20) && !(extra->type & 0x2)) {
// if hero touch extra
- if (checkExtraCollisionWithActors(extra, -1) == 0) {
+ if (_engine->_collision->checkExtraCollisionWithActors(extra, -1) == 0) {
// FIXME: add constant for sample index
- playSample(97, 0x1000, 1, extra->X, extra->Y, extra->Z, -1);
+ _engine->_sound->playSample(97, 0x1000, 1, extra->x, extra->y, extra->z, -1);
- if (extra->info1 > 1 && !(loopPressedKey & 2)) {
- projectPositionOnScreen(extra->X - cameraX, extra->Y - cameraY, extra->Z - cameraZ);
- addOverlay(koNumber, extra->info1, projPosX, projPosY, 158, koNormal, 2);
+ if (extra->info1 > 1 && !(_engine->loopPressedKey & 2)) {
+ _engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
+ _engine->_redraw->addOverlay(koNumber, extra->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, 158, koNormal, 2);
}
- addOverlay(koSprite, extra->info0, 10, 30, 0, koNormal, 2);
+ _engine->_redraw->addOverlay(koSprite, extra->info0, 10, 30, 0, koNormal, 2);
if (extra->info0 == SPRITEHQR_KASHES) {
- inventoryNumKashes += extra->info1;
- if (inventoryNumKashes > 999) {
- inventoryNumKashes = 999;
+ _engine->_gameState->inventoryNumKashes += extra->info1;
+ if (_engine->_gameState->inventoryNumKashes > 999) {
+ _engine->_gameState->inventoryNumKashes = 999;
}
}
if (extra->info0 == SPRITEHQR_LIFEPOINTS) {
- sceneHero->life += extra->info1;
- if (sceneHero->life > 50) {
- sceneHero->life = 50;
+ _engine->_scene->sceneHero->life += extra->info1;
+ if (_engine->_scene->sceneHero->life > 50) {
+ _engine->_scene->sceneHero->life = 50;
}
}
- if (extra->info0 == SPRITEHQR_MAGICPOINTS && magicLevelIdx) {
- inventoryMagicPoints += extra->info1 * 2;
- if (inventoryMagicPoints > magicLevelIdx * 20) {
- inventoryMagicPoints = magicLevelIdx * 20;
+ if (extra->info0 == SPRITEHQR_MAGICPOINTS && _engine->_gameState->magicLevelIdx) {
+ _engine->_gameState->inventoryMagicPoints += extra->info1 * 2;
+ if (_engine->_gameState->inventoryMagicPoints > _engine->_gameState->magicLevelIdx * 20) {
+ _engine->_gameState->inventoryMagicPoints = _engine->_gameState->magicLevelIdx * 20;
}
}
if (extra->info0 == SPRITEHQR_KEY) {
- inventoryNumKeys += extra->info1;
+ _engine->_gameState->inventoryNumKeys += extra->info1;
}
if (extra->info0 == SPRITEHQR_CLOVERLEAF) {
- inventoryNumLeafs += extra->info1;
- if (inventoryNumLeafs > inventoryNumLeafsBox) {
- inventoryNumLeafs = inventoryNumLeafsBox;
+ _engine->_gameState->inventoryNumLeafs += extra->info1;
+ if (_engine->_gameState->inventoryNumLeafs > _engine->_gameState->inventoryNumLeafsBox) {
+ _engine->_gameState->inventoryNumLeafs = _engine->_gameState->inventoryNumLeafsBox;
}
}
@@ -923,3 +909,4 @@ void processExtras() {
}
}
+} // namespace TwinE
diff --git a/engines/twine/extra.h b/engines/twine/extra.h
index c0a6bac048..8e122cf2e1 100644
--- a/engines/twine/extra.h
+++ b/engines/twine/extra.h
@@ -1,89 +1,102 @@
-/** @file extra.h
- @brief
- This file contains extra (bonus, projectils, keys, etc.) routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "sys.h"
-#include "actor.h"
-
-#ifndef EXTRA_H
-#define EXTRA_H
-
-#define EXTRA_MAX_ENTRIES 50
-
-typedef struct ExtraListStruct
-{
- int16 info0; // field_0
- int16 X;
- int16 Y;
- int16 Z;
-
- int16 lastX; // field_8
- int16 lastY; // field_A
- int16 lastZ; // field_C
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/actor.h"
+#include "common/scummsys.h"
+
+#ifndef TWINE_EXTRA_H
+#define TWINE_EXTRA_H
+
+namespace TwinE {
+
+#define EXTRA_MAX_ENTRIES 50
+
+typedef struct ExtraListStruct {
+ int16 info0 = 0; // field_0
+ int16 x = 0;
+ int16 y = 0;
+ int16 z = 0;
+
+ int16 lastX = 0; // field_8
+ int16 lastY = 0; // field_A
+ int16 lastZ = 0; // field_C
ActorMoveStruct trackActorMove;
- int16 destX; // field_E
- int16 destY; // field_10
- int16 destZ; // field_12
- int16 type; // field_14
- int16 angle; // field_16
- int32 lifeTime;
- int16 actorIdx; // field_ 1C
- int16 strengthOfHit; // field_1E
- int16 info1; // field_20
+ int16 destX = 0; // field_E
+ int16 destY = 0; // field_10
+ int16 destZ = 0; // field_12
+ int16 type = 0; // field_14
+ int16 angle = 0; // field_16
+ int32 lifeTime = 0;
+ int16 actorIdx = 0; // field_ 1C
+ int16 strengthOfHit = 0; // field_1E
+ int16 info1 = 0; // field_20
} ExtraListStruct;
-ExtraListStruct extraList[EXTRA_MAX_ENTRIES];
-
enum ExtraSpecialType {
kHitStars = 0,
kExplodeCloud = 1
};
-int32 addExtra(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 info0, int32 targetActor, int32 maxSpeed, int32 strengthOfHit);
+class TwinEEngine;
+
+class Extra {
+private:
+ TwinEEngine *_engine;
+
+ void throwExtra(ExtraListStruct *extra, int32 var1, int32 var2, int32 var3, int32 var4);
+ void processMagicballBounce(ExtraListStruct *extra, int32 X, int32 Y, int32 Z);
+ int32 findExtraKey();
+ int32 addExtraAimingAtKey(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 extraIdx);
+ void drawSpecialShape(const int16 *shapeTable, int32 X, int32 Y, int32 color, int32 angle, int32 size);
-/** Add extra explosion
+public:
+ Extra(TwinEEngine *engine);
+ ExtraListStruct extraList[EXTRA_MAX_ENTRIES];
+
+ int32 addExtra(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 info0, int32 targetActor, int32 maxSpeed, int32 strengthOfHit);
+
+ /** Add extra explosion
@param X Explostion X coordinate
@param Y Explostion Y coordinate
@param Z Explostion Z coordinate */
-int32 addExtraExplode(int32 X, int32 Y, int32 Z);
+ int32 addExtraExplode(int32 X, int32 Y, int32 Z);
-/** Reset all used extras */
-void resetExtras();
+ /** Reset all used extras */
+ void resetExtras();
-void addExtraSpecial(int32 X, int32 Y, int32 Z, int32 type);
-int32 addExtraBonus(int32 X, int32 Y, int32 Z, int32 param, int32 angle, int32 type, int32 bonusAmount);
-int32 addExtraThrow(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprite, int32 var2, int32 var3, int32 var4, int32 var5, int32 strengthOfHit);
-int32 addExtraAiming(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 targetActorIdx, int32 maxSpeed, int32 strengthOfHit);
-void addExtraThrowMagicball(int32 X, int32 Y, int32 Z, int32 param1, int32 angle, int32 param2, int32 param3);
+ void addExtraSpecial(int32 X, int32 Y, int32 Z, int32 type);
+ int32 addExtraBonus(int32 X, int32 Y, int32 Z, int32 param, int32 angle, int32 type, int32 bonusAmount);
+ int32 addExtraThrow(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 sprite, int32 var2, int32 var3, int32 var4, int32 var5, int32 strengthOfHit);
+ int32 addExtraAiming(int32 actorIdx, int32 X, int32 Y, int32 Z, int32 spriteIdx, int32 targetActorIdx, int32 maxSpeed, int32 strengthOfHit);
+ void addExtraThrowMagicball(int32 X, int32 Y, int32 Z, int32 param1, int32 angle, int32 param2, int32 param3);
-void drawExtraSpecial(int32 extraIdx, int32 X, int32 Y);
+ void drawExtraSpecial(int32 extraIdx, int32 X, int32 Y);
-/** Process extras */
-void processExtras();
+ /** Process extras */
+ void processExtras();
+};
+} // namespace TwinE
#endif
-
diff --git a/engines/twine/fcaseopen.cpp b/engines/twine/fcaseopen.cpp
deleted file mode 100644
index fd5e7533fc..0000000000
--- a/engines/twine/fcaseopen.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2009 Keith Bauer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "fcaseopen.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#ifdef WIN32
-#include <direct.h>
-#else
-#include <unistd.h>
-#include <dirent.h>
-#endif
-
-#ifndef WIN32
-
-// r must have strlen(path) + 2 bytes
-static int casepath(char const *path, char *r)
-{
- size_t l = strlen(path);
- char *p = alloca(l + 1);
- strcpy(p, path);
- size_t rl = 0;
-
- DIR *d;
- if (p[0] == '/')
- {
- d = opendir("/");
- p = p + 1;
- }
- else
- {
- d = opendir(".");
- r[0] = '.';
- r[1] = 0;
- rl = 1;
- }
-
- int last = 0;
- char *c = strsep(&p, "/");
- while (c)
- {
- if (!d)
- {
- return 0;
- }
-
- if (last)
- {
- closedir(d);
- return 0;
- }
-
- r[rl] = '/';
- rl += 1;
- r[rl] = 0;
-
- struct dirent *e = readdir(d);
- while (e)
- {
- if (strcasecmp(c, e->d_name) == 0)
- {
- strcpy(r + rl, e->d_name);
- rl += strlen(e->d_name);
-
- closedir(d);
- d = opendir(r);
-
- break;
- }
-
- e = readdir(d);
- }
-
- if (!e)
- {
- strcpy(r + rl, c);
- rl += strlen(c);
- last = 1;
- }
-
- c = strsep(&p, "/");
- }
-
- if (d) closedir(d);
- return 1;
-}
-#endif
-
-FILE *fcaseopen(char const *path, char const *mode)
-{
- FILE *f = fopen(path, mode);
-#ifndef WIN32
- if (!f)
- {
- char *r = alloca(strlen(path) + 2);
- if (casepath(path, r))
- {
- f = fopen(r, mode);
- }
- }
-#endif
- return f;
-}
-
-void casechdir(char const *path)
-{
-#ifndef WIN32
- char *r = alloca(strlen(path) + 2);
- if (casepath(path, r))
- {
- chdir(r);
- }
- else
- {
- errno = ENOENT;
- }
-#else
- _chdir(path);
-#endif
-}
diff --git a/engines/twine/fcaseopen.h b/engines/twine/fcaseopen.h
deleted file mode 100644
index 379a6d4174..0000000000
--- a/engines/twine/fcaseopen.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2009 Keith Bauer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef fcaseopen_h
-#define fcaseopen_h
-
-#include <stdio.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern FILE *fcaseopen(char const *path, char const *mode);
-
-extern void casechdir(char const *path);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/engines/twine/filereader.cpp b/engines/twine/filereader.cpp
deleted file mode 100644
index 0b9a70ac78..0000000000
--- a/engines/twine/filereader.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/** @file filereader.cpp
- @brief
- This file contains file read routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "filereader.h"
-#include "fcaseopen.h"
-#include <ctype.h>
-
-/** Feed buffer from file
- @param fr FileReader pointer */
-void frfeed(FileReader* fr) {
- fread(fr->buffer, BUFFER_SIZE, 1, fr->fd);
- fr->bufferPos = 0;
-}
-
-/** Read file
- @param fr FileReader pointer
- @param destPtr content destination pointer
- @param size size of read characters */
-void frread(FileReader* fr, void* destPtr, uint32 size) {
- if (BUFFER_SIZE - fr->bufferPos >= size) {
- memcpy(destPtr, &fr->buffer[fr->bufferPos], size);
- fr->bufferPos += size;
- } else {
- // feed what we can
- int8* tempPtr = (int8*)destPtr;
- memcpy(tempPtr, &fr->buffer[fr->bufferPos], BUFFER_SIZE - fr->bufferPos);
- tempPtr += BUFFER_SIZE - fr->bufferPos;
- size -= BUFFER_SIZE - fr->bufferPos;
-
- // feed the rest
- do {
- fr->currSector++;
- frfeed(fr);
- if (size >= BUFFER_SIZE) {
- memcpy(tempPtr, fr->buffer, BUFFER_SIZE);
- tempPtr += BUFFER_SIZE;
- size -= BUFFER_SIZE;
- } else {
- memcpy(tempPtr, fr->buffer, size);
- fr->bufferPos += size;
- size = 0;
- }
- } while (size > 0);
- }
-}
-
-/** Seek file
- @param fr FileReader pointer
- @param seekPosition position to seek */
-void frseek(FileReader* fr, uint32 seekPosition) {
- uint32 sectorToSeek;
-
- sectorToSeek = seekPosition / 2048;
-
- fseek(fr->fd, sectorToSeek * 2048, SEEK_SET);
-
- fr->currSector = sectorToSeek;
- frfeed(fr);
- fr->bufferPos = (seekPosition - (sectorToSeek * 2048));
-}
-
-/** Open file
- @param fr FileReader pointer
- @param filename file path
- @return true if file open and false if error occurred */
-int32 fropen2(FileReader* fr, char* filename, const char* mode) {
- fr->fd = fcaseopen(filename, mode);
-
- if (fr->fd) {
- fr->currSector = 0;
- frfeed(fr);
- return 1;
- }
-
- return 0;
-}
-
-/** Write file
- @param fr FileReader pointer
- @param destPtr content destination pointer
- @param size size of read characters */
-void frwrite(FileReader* fr, void* destPtr, uint32 size, uint32 count) {
- fwrite(destPtr, size, count, fr->fd);
-}
-
-/** Close file
- @param fr FileReader pointer */
-void frclose(FileReader* fr) {
- fclose(fr->fd);
-}
diff --git a/engines/twine/filereader.h b/engines/twine/filereader.h
deleted file mode 100644
index 8200565410..0000000000
--- a/engines/twine/filereader.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/** @file filereader.h
- @brief
- This file contains file read routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef FILEREADER_H
-#define FILEREADER_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "sys.h"
-
-/** Number of sector in the buffer */
-#define SECTORS_IN_BUFFER (3)
-/** Buffer size */
-#define BUFFER_SIZE (2048*SECTORS_IN_BUFFER)
-
-/** File reader structure */
-typedef struct FileReader {
- /** File descriptor */
- FILE* fd;
- /** Content buffer */
- uint8 buffer[BUFFER_SIZE];
- /** Current position in the buffer */
- uint32 bufferPos;
- /** Current sector in the buffer */
- uint32 currSector;
-} FileReader;
-
-/** Feed buffer from file
- @param fr FileReader pointer */
-void frfeed(FileReader* fr);
-
-/** Read file
- @param fr FileReader pointer
- @param destPtr content destination pointer
- @param size size of read characters */
-void frread(FileReader* fr, void* destPtr, uint32 size);
-
-/** Seek file
- @param fr FileReader pointer
- @param seekPosition position to seek */
-void frseek(FileReader* fr, uint32 seekPosition);
-
-/** Open file
- @param fr FileReader pointer
- @param filename file path
- @return true if file open and false if error occurred */
-int32 fropen2(FileReader* fr, char* filename, const char* mode);
-
-/** Write file
- @param fr FileReader pointer
- @param destPtr content destination pointer
- @param size size of read characters */
-void frwrite(FileReader* fr, void* destPtr, uint32 size, uint32 count);
-
-/** Close file
- @param fr FileReader pointer */
-void frclose(FileReader* fr);
-
-#endif
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 2eecd0f563..03fdc8fdbc 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -1,107 +1,65 @@
-/** @file movies.cpp
- @brief
- This file contains movies routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "flamovies.h"
-#include "screens.h"
-#include "sdlengine.h"
-#include "main.h"
-#include "sound.h"
-#include "music.h"
-#include "filereader.h"
-#include "lbaengine.h"
-#include "keyboard.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/flamovies.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "twine/grid.h"
+#include "twine/keyboard.h"
+#include "twine/music.h"
+#include "twine/screens.h"
+#include "twine/sound.h"
+#include "twine/twine.h"
+
+namespace TwinE {
/** Config movie types */
-#define CONF_MOVIE_NONE 0
-#define CONF_MOVIE_FLA 1
+#define CONF_MOVIE_NONE 0
+#define CONF_MOVIE_FLA 1
#define CONF_MOVIE_FLAWIDE 2
-#define CONF_MOVIE_FLAPCX 3
+#define CONF_MOVIE_FLAPCX 3
/** FLA movie extension */
#define FLA_EXT ".fla"
-/** FLA Frame Opcode types */
-enum FlaFrameOpcode {
- kLoadPalette = 0,
- kFade = 1,
- kPlaySample = 2,
- kStopSample = 4,
- kDeltaFrame = 5,
- kKeyFrame = 7
-};
-
-/** Auxiliar FLA fade out variable */
-int32 _fadeOut;
-/** Auxiliar FLA fade out variable to count frames between the fade */
-int32 fadeOutFrames;
-
-/** FLA movie sample auxiliar table */
-int32 flaSampleTable[100];
-/** Number of samples in FLA movie */
-int32 samplesInFla;
-/** Auxiliar work video buffer */
-uint8* workVideoBufferCopy;
-/** FLA movie header data */
-FLAHeaderStruct flaHeaderData;
-/** FLA movie header data */
-FLAFrameDataStruct frameData;
-
-FileReader frFla;
-
-/** FLA movie draw key frame
- @param ptr FLA frame buffer pointer
- @param width FLA movie width
- @param height FLA movie height */
-void drawKeyFrame(uint8 * ptr, int32 width, int32 height) {
- int32 a, b;
- uint8 * destPtr = (uint8 *)flaBuffer;
- uint8 * startOfLine = destPtr;
- int8 flag1;
- int8 flag2;
+void FlaMovies::drawKeyFrame(uint8 *ptr, int32 width, int32 height) {
+ uint8 *destPtr = (uint8 *)flaBuffer;
+ uint8 *startOfLine = destPtr;
do {
- flag1 = *(ptr++);
+ int8 flag1 = *(ptr++);
- for (a = 0; a < flag1; a++) {
- flag2 = *(ptr++);
+ for (int8 a = 0; a < flag1; a++) {
+ int8 flag2 = *(ptr++);
if (flag2 < 0) {
- flag2 = - flag2;
- for (b = 0; b < flag2; b++) {
+ flag2 = -flag2;
+ for (int8 b = 0; b < flag2; b++) {
*(destPtr++) = *(ptr++);
}
} else {
- char colorFill;
+ char colorFill = *(ptr++);
- colorFill = *(ptr++);
-
- for (b = 0; b < flag2; b++) {
+ for (int8 b = 0; b < flag2; b++) {
*(destPtr++) = colorFill;
}
}
@@ -111,31 +69,28 @@ void drawKeyFrame(uint8 * ptr, int32 width, int32 height) {
} while (--height);
}
-/** FLA movie draw delta frame
- @param ptr FLA frame buffer pointer
- @param width FLA movie width */
-void drawDeltaFrame(uint8 * ptr, int32 width) {
+void FlaMovies::drawDeltaFrame(uint8 *ptr, int32 width) {
int32 a, b;
uint16 skip;
- uint8 * destPtr;
- uint8 * startOfLine;
+ uint8 *destPtr;
+ uint8 *startOfLine;
int32 height;
int8 flag1;
int8 flag2;
- skip = *((uint16*)ptr);
+ skip = *((uint16 *)ptr);
ptr += 2;
skip *= width;
startOfLine = destPtr = (uint8 *)flaBuffer + skip;
- height = *((int16*)ptr);
+ height = *((int16 *)ptr);
ptr += 2;
do {
flag1 = *(ptr++);
for (a = 0; a < flag1; a++) {
- destPtr += (unsigned char) * (ptr++);
+ destPtr += (unsigned char)*(ptr++);
flag2 = *(ptr++);
if (flag2 > 0) {
@@ -144,7 +99,7 @@ void drawDeltaFrame(uint8 * ptr, int32 width) {
}
} else {
char colorFill;
- flag2 = - flag2;
+ flag2 = -flag2;
colorFill = *(ptr++);
@@ -158,17 +113,13 @@ void drawDeltaFrame(uint8 * ptr, int32 width) {
} while (--height);
}
-/** Scale FLA movie 2 times
-
- According with the settins we can put the original aspect radio stretch
- to fullscreen or preserve it and use top and button black bars */
-void scaleFla2x() {
+void FlaMovies::scaleFla2x() {
int32 i, j;
- uint8* source = (uint8*)flaBuffer;
- uint8* dest = (uint8*)workVideoBuffer;
+ uint8 *source = (uint8 *)flaBuffer;
+ uint8 *dest = (uint8 *)_engine->workVideoBuffer;
- if (cfgfile.Movie == CONF_MOVIE_FLAWIDE) {
- for (i = 0; i < SCREEN_WIDTH / SCALE*40; i++) {
+ if (_engine->cfgfile.Movie == CONF_MOVIE_FLAWIDE) {
+ for (i = 0; i < SCREEN_WIDTH / SCALE * 40; i++) {
*(dest++) = 0x00;
}
}
@@ -178,41 +129,40 @@ void scaleFla2x() {
*(dest++) = *(source);
*(dest++) = *(source++);
}
- if (cfgfile.Movie == CONF_MOVIE_FLAWIDE) { // include wide bars
- memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH*2);
+ if (_engine->cfgfile.Movie == CONF_MOVIE_FLAWIDE) { // include wide bars
+ memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH * 2);
dest += FLASCREEN_WIDTH * 2;
} else { // stretch the movie like original game.
if (i % (2)) {
- memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH*2);
+ memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH * 2);
dest += FLASCREEN_WIDTH * 2;
}
if (i % 10) {
- memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH*2);
+ memcpy(dest, dest - SCREEN_WIDTH / SCALE, FLASCREEN_WIDTH * 2);
dest += FLASCREEN_WIDTH * 2;
}
}
}
- if (cfgfile.Movie == CONF_MOVIE_FLAWIDE) {
- for (i = 0; i < SCREEN_WIDTH / SCALE*40; i++) {
+ if (_engine->cfgfile.Movie == CONF_MOVIE_FLAWIDE) {
+ for (i = 0; i < SCREEN_WIDTH / SCALE * 40; i++) {
*(dest++) = 0x00;
}
}
}
-/** FLA movie process frame */
-void processFrame() {
+void FlaMovies::processFrame() {
FLASampleStruct sample;
uint32 opcodeBlockSize;
uint8 opcode;
int32 aux = 0;
- uint8 * ptr;
+ uint8 *ptr;
- frread(&frFla, &frameData.videoSize, 1);
- frread(&frFla, &frameData.dummy, 1);
- frread(&frFla, &frameData.frameVar0, 4);
+ file.read(&frameData.videoSize, 1);
+ file.read(&frameData.dummy, 1);
+ file.read(&frameData.frameVar0, 4);
- frread(&frFla, workVideoBufferCopy, frameData.frameVar0);
+ file.read(workVideoBufferCopy, frameData.frameVar0);
if ((int32)frameData.videoSize <= 0)
return;
@@ -220,35 +170,35 @@ void processFrame() {
ptr = workVideoBufferCopy;
do {
- opcode = *((uint8*)ptr);
+ opcode = *((uint8 *)ptr);
ptr += 2;
- opcodeBlockSize = *((uint16*)ptr);
+ opcodeBlockSize = *((uint16 *)ptr);
ptr += 2;
switch (opcode - 1) {
case kLoadPalette: {
- int16 numOfColor = *((int16*)ptr);
- int16 startColor = *((int16*)(ptr + 2));
- memcpy((palette + (startColor*3)), (ptr + 4), numOfColor*3);
+ int16 numOfColor = *((int16 *)ptr);
+ int16 startColor = *((int16 *)(ptr + 2));
+ memcpy((_engine->_screens->palette + (startColor * 3)), (ptr + 4), numOfColor * 3);
break;
}
case kFade: {
// FLA movies don't use cross fade
// fade out tricky
if (_fadeOut != 1) {
- convertPalToRGBA(palette, paletteRGBACustom);
- fadeToBlack(paletteRGBACustom);
+ _engine->_screens->copyPal(_engine->_screens->palette, _engine->_screens->paletteRGBCustom);
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBCustom);
_fadeOut = 1;
}
break;
}
case kPlaySample: {
memcpy(&sample, ptr, sizeof(FLASampleStruct));
- playFlaSample(sample.sampleNum, sample.freq, sample.repeat, sample.x, sample.y);
+ _engine->_sound->playFlaSample(sample.sampleNum, sample.freq, sample.repeat, sample.x, sample.y);
break;
}
case kStopSample: {
- stopSample(sample.sampleNum);
+ _engine->_sound->stopSample(sample.sampleNum);
break;
}
case kDeltaFrame: {
@@ -275,116 +225,107 @@ void processFrame() {
/** Play FLA PCX Screens
@param flaName FLA movie name */
-void fla_pcxList(int8 *flaName) {
+static void fla_pcxList(const char *flaName) {
// TODO if is using FLA PCX than show the images instead
}
-/** Play FLA movies
- @param flaName FLA movie name */
-void playFlaMovie(int8 *flaName) {
- int32 i;
- int32 quit = 0;
- int32 currentFrame;
- int16 tmpValue;
- int8 fileNamePath[256];
+FlaMovies::FlaMovies(TwinEEngine *engine) : _engine(engine) {}
- stopSamples();
+void FlaMovies::playFlaMovie(const char *flaName) {
+ _engine->_sound->stopSamples();
// Play FLA PCX instead of movies
- if (cfgfile.Movie == CONF_MOVIE_FLAPCX) {
+ if (_engine->cfgfile.Movie == CONF_MOVIE_FLAPCX) {
fla_pcxList(flaName);
return;
}
- stopMusic();
+ _engine->_music->stopMusic();
- // take extension if movie name has it
- for (i = 0; i < (int32)strlen(flaName); i++) {
- if(flaName[i] == '.') {
- flaName[i] = 0;
- }
+ Common::String fileNamePath = Common::String::format(FLA_DIR "%s", flaName);
+ const size_t n = fileNamePath.findLastOf(".");
+ if (n != Common::String::npos) {
+ fileNamePath.erase(n);
}
-
- sprintf(fileNamePath, FLA_DIR);
- strcat(fileNamePath, flaName);
- strcat(fileNamePath, FLA_EXT);
+ fileNamePath += FLA_EXT;
_fadeOut = -1;
fadeOutFrames = 0;
- if (!fropen2(&frFla, fileNamePath, "rb"))
+ if (!file.open(fileNamePath)) {
+ warning("Failed to open fla movie '%s'", fileNamePath.c_str());
return;
+ }
- workVideoBufferCopy = workVideoBuffer;
+ workVideoBufferCopy = _engine->workVideoBuffer;
- frread(&frFla, &flaHeaderData.version, 6);
- frread(&frFla, &flaHeaderData.numOfFrames, 4);
- frread(&frFla, &flaHeaderData.speed, 1);
- frread(&frFla, &flaHeaderData.var1, 1);
- frread(&frFla, &flaHeaderData.xsize, 2);
- frread(&frFla, &flaHeaderData.ysize, 2);
+ file.read(&flaHeaderData.version, 6);
+ flaHeaderData.numOfFrames = file.readUint32LE();
+ flaHeaderData.speed = file.readByte();
+ flaHeaderData.var1 = file.readByte();
+ flaHeaderData.xsize = file.readUint16LE();
+ flaHeaderData.ysize = file.readUint16LE();
- frread(&frFla, &samplesInFla, 2);
- frread(&frFla, &tmpValue, 2);
+ samplesInFla = file.readUint16LE();
+ file.skip(2);
- for (i = 0; i < samplesInFla; i++) {
- int16 var0;
- int16 var1;
- frread(&frFla, &var0, 2);
- frread(&frFla, &var1, 2);
- flaSampleTable[i] = var0;
+ for (int32 i = 0; i < samplesInFla; i++) {
+ flaSampleTable[i] = file.readSint16LE();
+ file.skip(2);
}
- if (!strcmp(flaHeaderData.version, "V1.3")) {
- currentFrame = 0;
-
- if (!quit) {
- do {
- if (currentFrame == flaHeaderData.numOfFrames)
- quit = 1;
- else {
- processFrame();
- scaleFla2x();
- copyScreen(workVideoBuffer, frontVideoBuffer);
-
- // Only blit to screen if isn't a fade
- if (_fadeOut == -1) {
- convertPalToRGBA(palette, paletteRGBACustom);
- if (!currentFrame) // fade in the first frame
- fadeIn(paletteRGBACustom);
- else
- setPalette(paletteRGBACustom);
- }
-
- // TRICKY: fade in tricky
- if (fadeOutFrames >= 2) {
- flip();
- convertPalToRGBA(palette, paletteRGBACustom);
- fadeToPal(paletteRGBACustom);
- _fadeOut = -1;
- fadeOutFrames = 0;
- }
-
- currentFrame++;
-
- fpsCycles(flaHeaderData.speed + 1);
-
- readKeys();
-
- if (skipIntro)
- break;
- }
- } while (!quit);
- }
+ if (!strcmp((const char *)flaHeaderData.version, "V1.3")) {
+ int32 currentFrame = 0;
+
+ do {
+ if (currentFrame == flaHeaderData.numOfFrames) {
+ break;
+ }
+ processFrame();
+ scaleFla2x();
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+
+ // Only blit to screen if isn't a fade
+ if (_fadeOut == -1) {
+ _engine->_screens->copyPal(_engine->_screens->palette, _engine->_screens->paletteRGBCustom);
+ if (!currentFrame) // fade in the first frame
+ _engine->_screens->fadeIn(_engine->_screens->paletteRGBCustom);
+ else
+ _engine->setPalette(_engine->_screens->paletteRGBCustom);
+ }
+
+ // TRICKY: fade in tricky
+ if (fadeOutFrames >= 2) {
+ _engine->flip();
+ _engine->_screens->copyPal(_engine->_screens->palette, _engine->_screens->paletteRGBCustom);
+ _engine->_screens->fadeToPal(_engine->_screens->paletteRGBCustom);
+ _fadeOut = -1;
+ fadeOutFrames = 0;
+ }
+
+ currentFrame++;
+
+ _engine->_system->delayMillis(1000 / flaHeaderData.speed + 1);
+
+ _engine->readKeys();
+
+ if (_engine->shouldQuit()) {
+ break;
+ }
+
+ if (_engine->_keyboard.skipIntro) {
+ break;
+ }
+ } while (true);
}
- if (cfgfile.CrossFade) {
- crossFade(frontVideoBuffer, paletteRGBACustom);
+ if (_engine->cfgfile.CrossFade) {
+ _engine->crossFade(_engine->frontVideoBuffer, _engine->_screens->paletteRGBCustom);
} else {
- fadeToBlack(paletteRGBACustom);
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBCustom);
}
- stopSamples();
+ _engine->_sound->stopSamples();
}
/*
@@ -490,3 +431,5 @@ void prepareFlaPCX(int index)
osystem_FlaPCXCrossFade(image);
}*/
+
+} // namespace TwinE
diff --git a/engines/twine/flamovies.h b/engines/twine/flamovies.h
index bd81defeb8..60846563e8 100644
--- a/engines/twine/flamovies.h
+++ b/engines/twine/flamovies.h
@@ -1,83 +1,139 @@
-/** @file movies.h
- @brief
- This file contains movies routines
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
- TwinEngine: a Little Big Adventure engine
+#ifndef TWINE_FLAMOVIES_H
+#define TWINE_FLAMOVIES_H
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
+#include "common/scummsys.h"
+#include "common/file.h"
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef FLAMOVIES_H
-#define FLAMOVIES_H
-
-#include "main.h"
+namespace TwinE {
/** FLA movie directory */
#define FLA_DIR "fla/"
+/** Original FLA screen width */
+#define FLASCREEN_WIDTH 320
+/** Original FLA screen height */
+#define FLASCREEN_HEIGHT 200
/** FLA movie header structure */
typedef struct FLAHeaderStruct {
/** FLA version */
- int8 version[6];
+ int8 version[6] {0};
/** Number of frames */
- int32 numOfFrames;
+ int32 numOfFrames = 0;
/** Frames per second */
- int8 speed;
+ int8 speed = 0;
/** Unknown var1 */
- int8 var1;
+ int8 var1 = 0;
/** Frame width */
- int16 xsize;
+ int16 xsize = 0;
/** Frame height */
- int16 ysize;
+ int16 ysize = 0;
} FLAHeaderStruct;
/** FLA movie frame structure */
typedef struct FLAFrameDataStruct {
/** Current frame size */
- int8 videoSize;
+ int8 videoSize = 0;
/** Dummy variable */
- int8 dummy;
+ int8 dummy = 0;
/** Unknown frameVar0 */
- int32 frameVar0;
+ int32 frameVar0 = 0;
} FLAFrameDataStruct;
/** FLA movie sample structure */
typedef struct FLASampleStruct {
/** Number os samples */
- int16 sampleNum;
+ int16 sampleNum = 0;
/** Sample frequency */
- int16 freq;
+ int16 freq = 0;
/** Numbers of time to repeat */
- int16 repeat;
+ int16 repeat = 0;
/** Dummy variable */
- int8 dummy;
+ int8 dummy = 0;
/** Unknown x */
- uint8 x;
+ uint8 x = 0;
/** Unknown y */
- uint8 y;
+ uint8 y = 0;
} FLASampleStruct;
-/** FLA movie file buffer */
-unsigned char flaBuffer[FLASCREEN_WIDTH*FLASCREEN_HEIGHT];
+/** FLA Frame Opcode types */
+enum FlaFrameOpcode {
+ kLoadPalette = 0,
+ kFade = 1,
+ kPlaySample = 2,
+ kStopSample = 4,
+ kDeltaFrame = 5,
+ kKeyFrame = 7
+};
+
+class TwinEEngine;
+
+class FlaMovies {
+private:
+ TwinEEngine *_engine;
+
+ Common::File file;
+
+ /** Auxiliar FLA fade out variable */
+ int32 _fadeOut = 0;
+ /** Auxiliar FLA fade out variable to count frames between the fade */
+ int32 fadeOutFrames = 0;
+
+ /** FLA movie sample auxiliar table */
+ int32 flaSampleTable[100] {0};
+ /** Number of samples in FLA movie */
+ int32 samplesInFla = 0;
+ /** Auxiliar work video buffer */
+ uint8 *workVideoBufferCopy = nullptr;
+ /** FLA movie header data */
+ FLAHeaderStruct flaHeaderData;
+ /** FLA movie header data */
+ FLAFrameDataStruct frameData;
+
+ void drawKeyFrame(uint8 *ptr, int32 width, int32 height);
+ void drawDeltaFrame(uint8 *ptr, int32 width);
+ /**
+ * Scale FLA movie 2 times
+ * According with the settins we can put the original aspect radio stretch
+ * to fullscreen or preserve it and use top and button black bars
+ */
+ void scaleFla2x();
+ void processFrame();
+
+public:
+ FlaMovies(TwinEEngine *engine);
+
+ /** FLA movie file buffer */
+ uint8 flaBuffer[FLASCREEN_WIDTH * FLASCREEN_HEIGHT] {0};
+
+ /**
+ * Play FLA movies
+ * @param flaName FLA movie name
+ */
+ void playFlaMovie(const char *flaName);
+};
-/** Play FLA movies
- @param flaName FLA movie name */
-void playFlaMovie(int8 *flaName);
+} // namespace TwinE
#endif
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 6b6e1c373d..e2537eeac5 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -1,79 +1,74 @@
-/** @file gamestate.cpp
- @brief
- This file contains game state routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "gamestate.h"
-#include "scene.h"
-#include "redraw.h"
-#include "text.h"
-#include "menu.h"
-#include "renderer.h"
-#include "grid.h"
-#include "lbaengine.h"
-#include "interface.h"
-#include "animations.h"
-#include "keyboard.h"
-#include "resources.h"
-#include "extra.h"
-#include "sound.h"
-#include "screens.h"
-#include "music.h"
-#include "filereader.h"
-#include "menuoptions.h"
-#include "collision.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/gamestate.h"
+#include "common/file.h"
+#include "common/str.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+#include "common/util.h"
+#include "twine/actor.h"
+#include "twine/animations.h"
+#include "twine/collision.h"
+#include "twine/extra.h"
+#include "twine/grid.h"
+#include "twine/interface.h"
+#include "twine/keyboard.h"
+#include "twine/menu.h"
+#include "twine/menuoptions.h"
+#include "twine/music.h"
+#include "twine/redraw.h"
+#include "twine/renderer.h"
+#include "twine/resources.h"
+#include "twine/scene.h"
+#include "twine/screens.h"
+#include "twine/sound.h"
+#include "twine/text.h"
+#include "twine/twine.h"
+
+namespace TwinE {
#define SAVE_DIR "save/"
-int32 magicLevelStrengthOfHit[] = {
- kNoBallStrenght,
- kYellowBallStrenght,
- kGreenBallStrenght,
- kRedBallStrenght,
- kFireBallStrength,
- 0
-};
-
-/** Initialize engine 3D projections */
-void initEngineProjections() { // reinitAll1
- setOrthoProjection(311, 240, 512);
- setBaseTranslation(0, 0, 0);
- setBaseRotation(0, 0, 0);
- setLightVector(alphaLight, betaLight, 0);
+GameState::GameState(TwinEEngine *engine) : _engine(engine) {}
+
+void GameState::initEngineProjections() { // reinitAll1
+ _engine->_renderer->setOrthoProjection(311, 240, 512);
+ _engine->_renderer->setBaseTranslation(0, 0, 0);
+ _engine->_renderer->setBaseRotation(0, 0, 0);
+ _engine->_renderer->setLightVector(_engine->_scene->alphaLight, _engine->_scene->betaLight, 0);
}
-/** Initialize variables */
-void initSceneVars() {
+void GameState::initSceneVars() {
int32 i;
- resetExtras();
+ _engine->_extra->resetExtras();
for (i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
- overlayList[i].info0 = -1;
+ _engine->_redraw->overlayList[i].info0 = -1;
}
for (i = 0; i < NUM_SCENES_FLAGS; i++) {
- sceneFlags[i] = 0;
+ _engine->_scene->sceneFlags[i] = 0;
}
for (i = 0; i < NUM_GAME_FLAGS; i++) {
@@ -84,69 +79,68 @@ void initSceneVars() {
inventoryFlags[i] = 0;
}
- sampleAmbiance[0] = -1;
- sampleAmbiance[1] = -1;
- sampleAmbiance[2] = -1;
- sampleAmbiance[3] = -1;
+ _engine->_scene->sampleAmbiance[0] = -1;
+ _engine->_scene->sampleAmbiance[1] = -1;
+ _engine->_scene->sampleAmbiance[2] = -1;
+ _engine->_scene->sampleAmbiance[3] = -1;
- sampleRepeat[0] = 0;
- sampleRepeat[1] = 0;
- sampleRepeat[2] = 0;
- sampleRepeat[3] = 0;
+ _engine->_scene->sampleRepeat[0] = 0;
+ _engine->_scene->sampleRepeat[1] = 0;
+ _engine->_scene->sampleRepeat[2] = 0;
+ _engine->_scene->sampleRepeat[3] = 0;
- sampleRound[0] = 0;
- sampleRound[1] = 0;
- sampleRound[2] = 0;
- sampleRound[3] = 0;
+ _engine->_scene->sampleRound[0] = 0;
+ _engine->_scene->sampleRound[1] = 0;
+ _engine->_scene->sampleRound[2] = 0;
+ _engine->_scene->sampleRound[3] = 0;
- for (i = 0; i < 150; i++) {
+ for (i = 0; i < ARRAYSIZE(holomapFlags); i++) {
holomapFlags[i] = 0;
}
- sceneNumActors = 0;
- sceneNumZones = 0;
- sceneNumTracks = 0;
+ _engine->_scene->sceneNumActors = 0;
+ _engine->_scene->sceneNumZones = 0;
+ _engine->_scene->sceneNumTracks = 0;
- currentPositionInBodyPtrTab = 0;
+ _engine->_actor->currentPositionInBodyPtrTab = 0;
}
-void initHeroVars() { // reinitAll3
- resetActor(0); // reset Hero
+void GameState::initHeroVars() { // reinitAll3
+ _engine->_actor->resetActor(0); // reset Hero
magicBallIdx = -1;
inventoryNumLeafsBox = 2;
- inventoryNumLeafs = 2;
- inventoryNumKashes = 0;
- inventoryNumKeys = 0;
+ inventoryNumLeafs = 2;
+ inventoryNumKashes = 0;
+ inventoryNumKeys = 0;
inventoryMagicPoints = 0;
usingSabre = 0;
- sceneHero->body = 0;
- sceneHero->life = 50;
- sceneHero->talkColor = 4;
+ _engine->_scene->sceneHero->body = 0;
+ _engine->_scene->sceneHero->life = 50;
+ _engine->_scene->sceneHero->talkColor = 4;
}
-/** Initialize all engine variables */
-void initEngineVars(int32 save) { // reinitAll
- resetClip();
+void GameState::initEngineVars() { // reinitAll
+ _engine->_interface->resetClip();
- alphaLight = 896;
- betaLight = 950;
+ _engine->_scene->alphaLight = 896;
+ _engine->_scene->betaLight = 950;
initEngineProjections();
initSceneVars();
initHeroVars();
- newHeroX = 0x2000;
- newHeroY = 0x1800;
- newHeroZ = 0x2000;
+ _engine->_scene->newHeroX = 0x2000;
+ _engine->_scene->newHeroY = 0x1800;
+ _engine->_scene->newHeroZ = 0x2000;
- currentSceneIdx = -1;
- needChangeScene = 0;
- quitGame = -1;
- mecaPinguinIdx = -1;
- canShowCredits = 0;
+ _engine->_scene->currentSceneIdx = -1;
+ _engine->_scene->needChangeScene = 0;
+ _engine->quitGame = -1;
+ _engine->_scene->mecaPinguinIdx = -1;
+ _engine->_menuOptions->canShowCredits = 0;
inventoryNumLeafs = 0;
inventoryNumLeafsBox = 2;
@@ -155,255 +149,259 @@ void initEngineVars(int32 save) { // reinitAll
inventoryNumKeys = 0;
inventoryNumGas = 0;
- cropBottomScreen = 0;
+ _engine->_actor->cropBottomScreen = 0;
magicLevelIdx = 0;
usingSabre = 0;
gameChapter = 0;
- currentTextBank = 0;
- currentlyFollowedActor = 0;
- heroBehaviour = 0;
- previousHeroAngle = 0;
- previousHeroBehaviour = 0;
-
- if (save == -1) {
- loadGame();
- if (newHeroX == -1) {
- heroPositionType = kNoPosition;
- }
- }
+ _engine->_text->currentTextBank = 0;
+ _engine->_scene->currentlyFollowedActor = 0;
+ _engine->_actor->heroBehaviour = kNormal;
+ _engine->_actor->previousHeroAngle = 0;
+ _engine->_actor->previousHeroBehaviour = kNormal;
}
-void loadGame() {
- FileReader fr;
- uint8 data;
- int8* namePtr;
-
- if (!fropen2(&fr, SAVE_DIR "S9999.LBA", "rb")) {
- printf("Can't load S9999.LBA saved game!\n");
- return;
+bool GameState::loadGame() {
+ Common::File file;
+ // TODO: the filename must be handled properly
+ if (!file.open(SAVE_DIR "S9999.LBA")) {
+ warning("Could not load the gamestate");
+ return false;
}
- namePtr = savePlayerName;
-
- frread(&fr, &data, 1); // save game id
+ file.skip(1); // skip save game id
+ int playerNameIdx = 0;
do {
- frread(&fr, &data, 1); // get save player name characters
- *(namePtr++) = data;
- } while (data);
-
- frread(&fr, &data, 1); // number of game flags, always 0xFF
- frread(&fr, gameFlags, data);
- frread(&fr, &needChangeScene, 1); // scene index
- frread(&fr, &gameChapter, 1);
-
- frread(&fr, &heroBehaviour, 1);
- previousHeroBehaviour = heroBehaviour;
- frread(&fr, &sceneHero->life, 1);
- frread(&fr, &inventoryNumKashes, 2);
- frread(&fr, &magicLevelIdx, 1);
- frread(&fr, &inventoryMagicPoints, 1);
- frread(&fr, &inventoryNumLeafsBox, 1);
- frread(&fr, &newHeroX, 2);
- frread(&fr, &newHeroY, 2);
- frread(&fr, &newHeroZ, 2);
- frread(&fr, &sceneHero->angle, 2);
- previousHeroAngle = sceneHero->angle;
- frread(&fr, &sceneHero->body, 1);
-
- frread(&fr, &data, 1); // number of holomap locations, always 0x96
- frread(&fr, holomapFlags, data);
-
- frread(&fr, &inventoryNumGas, 1);
-
- frread(&fr, &data, 1); // number of used inventory items, always 0x1C
- frread(&fr, inventoryFlags, data);
-
- frread(&fr, &inventoryNumLeafs, 1);
- frread(&fr, &usingSabre, 1);
-
- frclose(&fr);
-
- currentSceneIdx = -1;
- heroPositionType = kReborn;
-}
-
-void saveGame() {
- FileReader fr;
- int8 data;
+ const byte c = file.readByte();
+ if (c == '\0') {
+ break;
+ }
+ playerName[playerNameIdx++] = c;
+ if (playerNameIdx >= ARRAYSIZE(playerName)) {
+ warning("Failed to load savegame");
+ return false;
+ }
+ } while (true);
+ playerName[playerNameIdx] = '\0';
- if (!fropen2(&fr, SAVE_DIR "S9999.LBA", "wb+")) {
- printf("Can't save S9999.LBA saved game!\n");
- return;
+ byte numGameFlags = file.readByte();
+ if (numGameFlags != NUM_GAME_FLAGS) {
+ warning("Failed to load gameflags");
+ return false;
}
+ file.read(gameFlags, numGameFlags);
+ _engine->_scene->needChangeScene = file.readByte(); // scene index
+ gameChapter = file.readByte();
+
+ _engine->_actor->heroBehaviour = (HeroBehaviourType)file.readByte();
+ _engine->_actor->previousHeroBehaviour = _engine->_actor->heroBehaviour;
+ _engine->_scene->sceneHero->life = file.readByte();
+ inventoryNumKashes = file.readSint16LE();
+ magicLevelIdx = file.readByte();
+ inventoryMagicPoints = file.readByte();
+ inventoryNumLeafsBox = file.readByte();
+ _engine->_scene->newHeroX = file.readSint16LE();
+ _engine->_scene->newHeroY = file.readSint16LE();
+ _engine->_scene->newHeroZ = file.readSint16LE();
+ _engine->_scene->sceneHero->angle = file.readSint16LE();
+ _engine->_actor->previousHeroAngle = _engine->_scene->sceneHero->angle;
+ _engine->_scene->sceneHero->body = file.readByte();
+
+ const byte numHolemapFlags = file.readByte(); // number of holomap locations, always 150
+ if (numHolemapFlags != ARRAYSIZE(holomapFlags)) {
+ warning("Failed to load holomapflags");
+ return false;
+ }
+ file.read(holomapFlags, numHolemapFlags);
- data = 0x03;
- frwrite(&fr, &data, 1, 1);
-
- data = 0x00;
- frwrite(&fr, "TwinEngineSave", 15, 1);
-
- data = 0xFF; // number of game flags
- frwrite(&fr, &data, 1, 1);
- frwrite(&fr, gameFlags, 255, 1);
-
- frwrite(&fr, ¤tSceneIdx, 1, 1);
- frwrite(&fr, &gameChapter, 1, 1);
- frwrite(&fr, &heroBehaviour, 1, 1);
- frwrite(&fr, &sceneHero->life, 1, 1);
- frwrite(&fr, &inventoryNumKashes, 2, 1);
- frwrite(&fr, &magicLevelIdx, 1, 1);
- frwrite(&fr, &inventoryMagicPoints, 1, 1);
- frwrite(&fr, &inventoryNumLeafsBox, 1, 1);
- frwrite(&fr, &newHeroX, 2, 1);
- frwrite(&fr, &newHeroY, 2, 1);
- frwrite(&fr, &newHeroZ, 2, 1);
- frwrite(&fr, &sceneHero->angle, 2, 1);
- frwrite(&fr, &sceneHero->body, 1, 1);
+ inventoryNumGas = file.readByte();
- data = 0x96; // number of holomap locations
- frwrite(&fr, &data, 1, 1);
- frwrite(&fr, holomapFlags, 150, 1);
+ const byte numInventoryFlags = file.readByte(); // number of used inventory items, always 28
+ if (numInventoryFlags != NUM_INVENTORY_ITEMS) {
+ warning("Failed to load inventoryFlags");
+ return false;
+ }
+ file.read(inventoryFlags, numInventoryFlags);
- frwrite(&fr, &inventoryNumGas, 1, 1);
+ inventoryNumLeafs = file.readByte();
+ usingSabre = file.readByte();
- data = 0x1C; // number of inventory items
- frwrite(&fr, &data, 1, 1);
- frwrite(&fr, inventoryFlags, 28, 1);
+ _engine->_scene->currentSceneIdx = -1;
+ _engine->_scene->heroPositionType = kReborn;
+ return true;
+}
- frwrite(&fr, &inventoryNumLeafs, 1, 1);
- frwrite(&fr, &usingSabre, 1, 1);
+bool GameState::saveGame() {
+ Common::DumpFile file;
+ // TODO: the filename must be handled properly
+ if (!file.open(SAVE_DIR "S9999.LBA")) {
+ warning("Could not save the game");
+ return false;
+ }
- frclose(&fr);
+ // TODO: the player name must be handled properly
+ Common::strlcpy(playerName, "TwinEngineSave", sizeof(playerName));
+
+ file.writeByte(0x03);
+ file.writeString(playerName);
+ file.writeByte(NUM_GAME_FLAGS);
+ file.write(gameFlags, sizeof(gameFlags));
+ file.writeByte(_engine->_scene->currentSceneIdx);
+ file.writeByte(gameChapter);
+ file.writeByte(_engine->_actor->heroBehaviour);
+ file.writeByte(_engine->_scene->sceneHero->life);
+ file.writeSint16LE(inventoryNumKashes);
+ file.writeByte(magicLevelIdx);
+ file.writeByte(inventoryMagicPoints);
+ file.writeByte(inventoryNumLeafsBox);
+ file.writeSint16LE(_engine->_scene->newHeroX);
+ file.writeSint16LE(_engine->_scene->newHeroY);
+ file.writeSint16LE(_engine->_scene->newHeroZ);
+ file.writeSint16LE(_engine->_scene->sceneHero->angle);
+ file.writeByte(_engine->_scene->sceneHero->body);
+
+ // number of holomap locations
+ file.writeByte(ARRAYSIZE(holomapFlags));
+ file.write(holomapFlags, sizeof(holomapFlags));
+
+ file.writeByte(inventoryNumGas);
+
+ // number of inventory items
+ file.writeByte(ARRAYSIZE(inventoryFlags));
+ file.write(inventoryFlags, sizeof(inventoryFlags));
+
+ file.writeByte(inventoryNumLeafs);
+ file.writeByte(usingSabre);
+
+ return true;
}
-void processFoundItem(int32 item) {
- int32 itemCameraX, itemCameraY, itemCameraZ; // objectXYZ
+void GameState::processFoundItem(int32 item) {
int32 itemX, itemY, itemZ; // object2XYZ
int32 boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY;
int32 textState, quitItem, currentAnimState;
uint8 *currentAnim;
AnimTimerDataStruct tmpAnimTimer;
- newCameraX = (sceneHero->X + 0x100) >> 9;
- newCameraY = (sceneHero->Y + 0x100) >> 8;
- newCameraZ = (sceneHero->Z + 0x100) >> 9;
+ _engine->_grid->newCameraX = (_engine->_scene->sceneHero->x + 0x100) >> 9;
+ _engine->_grid->newCameraY = (_engine->_scene->sceneHero->y + 0x100) >> 8;
+ _engine->_grid->newCameraZ = (_engine->_scene->sceneHero->z + 0x100) >> 9;
// Hide hero in scene
- sceneHero->staticFlags.bIsHidden = 1;
- redrawEngineActions(1);
- sceneHero->staticFlags.bIsHidden = 0;
+ _engine->_scene->sceneHero->staticFlags.bIsHidden = 1;
+ _engine->_redraw->redrawEngineActions(1);
+ _engine->_scene->sceneHero->staticFlags.bIsHidden = 0;
- copyScreen(frontVideoBuffer, workVideoBuffer);
+ _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- itemCameraX = newCameraX << 9;
- itemCameraY = newCameraY << 8;
- itemCameraZ = newCameraZ << 9;
+ int32 itemCameraX = _engine->_grid->newCameraX << 9;
+ int32 itemCameraY = _engine->_grid->newCameraY << 8;
+ int32 itemCameraZ = _engine->_grid->newCameraZ << 9;
- renderIsoModel(sceneHero->X - itemCameraX, sceneHero->Y - itemCameraY, sceneHero->Z - itemCameraZ, 0, 0x80, 0, bodyTable[sceneHero->entity]);
- setClip(renderLeft, renderTop, renderRight, renderBottom);
+ _engine->_renderer->renderIsoModel(_engine->_scene->sceneHero->x - itemCameraX, _engine->_scene->sceneHero->y - itemCameraY, _engine->_scene->sceneHero->z - itemCameraZ, 0, 0x80, 0, _engine->_actor->bodyTable[_engine->_scene->sceneHero->entity]);
+ _engine->_interface->setClip(_engine->_redraw->renderLeft, _engine->_redraw->renderTop, _engine->_redraw->renderRight, _engine->_redraw->renderBottom);
- itemX = (sceneHero->X + 0x100) >> 9;
- itemY = sceneHero->Y >> 8;
- if (sceneHero->brickShape & 0x7F) {
+ itemX = (_engine->_scene->sceneHero->x + 0x100) >> 9;
+ itemY = _engine->_scene->sceneHero->y >> 8;
+ if (_engine->_scene->sceneHero->brickShape & 0x7F) {
itemY++;
}
- itemZ = (sceneHero->Z + 0x100) >> 9;
+ itemZ = (_engine->_scene->sceneHero->z + 0x100) >> 9;
- drawOverModelActor(itemX, itemY, itemZ);
- flip();
+ _engine->_grid->drawOverModelActor(itemX, itemY, itemZ);
+ _engine->flip();
- projectPositionOnScreen(sceneHero->X - itemCameraX, sceneHero->Y - itemCameraY, sceneHero->Z - itemCameraZ);
- projPosY -= 150;
+ _engine->_renderer->projectPositionOnScreen(_engine->_scene->sceneHero->x - itemCameraX, _engine->_scene->sceneHero->y - itemCameraY, _engine->_scene->sceneHero->z - itemCameraZ);
+ _engine->_renderer->projPosY -= 150;
- boxTopLeftX = projPosX - 65;
- boxTopLeftY = projPosY - 65;
+ boxTopLeftX = _engine->_renderer->projPosX - 65;
+ boxTopLeftY = _engine->_renderer->projPosY - 65;
- boxBottomRightX = projPosX + 65;
- boxBottomRightY = projPosY + 65;
+ boxBottomRightX = _engine->_renderer->projPosX + 65;
+ boxBottomRightY = _engine->_renderer->projPosY + 65;
- playSample(41, 0x1000, 1, 0x80, 0x80, 0x80, -1);
+ _engine->_sound->playSample(41, 0x1000, 1, 0x80, 0x80, 0x80, -1);
// process vox play
{
int32 tmpLanguageCDId;
- stopMusic();
- tmpLanguageCDId = cfgfile.LanguageCDId;
- //cfgfile.LanguageCDId = 0; // comented so we can init vox bank
- initTextBank(2);
- cfgfile.LanguageCDId = tmpLanguageCDId;
+ _engine->_music->stopMusic();
+ tmpLanguageCDId = _engine->cfgfile.LanguageCDId;
+ //_engine->cfgfile.LanguageCDId = 0; // comented so we can init vox bank
+ _engine->_text->initTextBank(2);
+ _engine->cfgfile.LanguageCDId = tmpLanguageCDId;
}
- resetClip();
- initText(item);
- initDialogueBox();
+ _engine->_interface->resetClip();
+ _engine->_text->initText(item);
+ _engine->_text->initDialogueBox();
textState = 1;
quitItem = 0;
- if (cfgfile.LanguageCDId) {
- initVoxToPlay(item);
+ if (_engine->cfgfile.LanguageCDId) {
+ _engine->_text->initVoxToPlay(item);
}
- currentAnim = animTable[getBodyAnimIndex(kFoundItem, 0)];
+ currentAnim = _engine->_animations->animTable[_engine->_animations->getBodyAnimIndex(kFoundItem, 0)];
- tmpAnimTimer = sceneHero->animTimerData;
+ tmpAnimTimer = _engine->_scene->sceneHero->animTimerData;
- animBuffer2 += stockAnimation(animBuffer2, bodyTable[sceneHero->entity], &sceneHero->animTimerData);
- if (animBuffer1 + 4488 < animBuffer2) {
- animBuffer2 = animBuffer1;
+ _engine->_animations->animBuffer2 += _engine->_animations->stockAnimation(_engine->_animations->animBuffer2, _engine->_actor->bodyTable[_engine->_scene->sceneHero->entity], &_engine->_scene->sceneHero->animTimerData);
+ if (_engine->_animations->animBuffer1 + 4488 < _engine->_animations->animBuffer2) {
+ _engine->_animations->animBuffer2 = _engine->_animations->animBuffer1;
}
currentAnimState = 0;
- prepareIsoModel(inventoryTable[item]);
- numOfRedrawBox = 0;
+ _engine->_renderer->prepareIsoModel(_engine->_resources->inventoryTable[item]);
+ _engine->_redraw->numOfRedrawBox = 0;
while (!quitItem) {
- resetClip();
- currNumOfRedrawBox = 0;
- blitBackgroundAreas();
- drawTransparentBox(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY, 4);
+ _engine->_interface->resetClip();
+ _engine->_redraw->currNumOfRedrawBox = 0;
+ _engine->_redraw->blitBackgroundAreas();
+ _engine->_interface->drawTransparentBox(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY, 4);
- setClip(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
+ _engine->_interface->setClip(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
- itemAngle[item] += 8;
+ _engine->_menu->itemAngle[item] += 8;
- renderInventoryItem(projPosX, projPosY, inventoryTable[item], itemAngle[item], 10000);
+ _engine->_renderer->renderInventoryItem(_engine->_renderer->projPosX, _engine->_renderer->projPosY, _engine->_resources->inventoryTable[item], _engine->_menu->itemAngle[item], 10000);
- drawBox(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
- addRedrawArea(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
- resetClip();
+ _engine->_menu->drawBox(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
+ _engine->_redraw->addRedrawArea(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
+ _engine->_interface->resetClip();
initEngineProjections();
- if (setModelAnimation(currentAnimState, currentAnim, bodyTable[sceneHero->entity], &sceneHero->animTimerData)) {
+ if (_engine->_animations->setModelAnimation(currentAnimState, currentAnim, _engine->_actor->bodyTable[_engine->_scene->sceneHero->entity], &_engine->_scene->sceneHero->animTimerData)) {
currentAnimState++; // keyframe
- if (currentAnimState >= getNumKeyframes(currentAnim)) {
- currentAnimState = getStartKeyframe(currentAnim);
+ if (currentAnimState >= _engine->_animations->getNumKeyframes(currentAnim)) {
+ currentAnimState = _engine->_animations->getStartKeyframe(currentAnim);
}
}
- renderIsoModel(sceneHero->X - itemCameraX, sceneHero->Y - itemCameraY, sceneHero->Z - itemCameraZ, 0, 0x80, 0, bodyTable[sceneHero->entity]);
- setClip(renderLeft, renderTop, renderRight, renderBottom);
- drawOverModelActor(itemX, itemY, itemZ);
- addRedrawArea(renderLeft, renderTop, renderRight, renderBottom);
+ _engine->_renderer->renderIsoModel(_engine->_scene->sceneHero->x - itemCameraX, _engine->_scene->sceneHero->y - itemCameraY, _engine->_scene->sceneHero->z - itemCameraZ, 0, 0x80, 0, _engine->_actor->bodyTable[_engine->_scene->sceneHero->entity]);
+ _engine->_interface->setClip(_engine->_redraw->renderLeft, _engine->_redraw->renderTop, _engine->_redraw->renderRight, _engine->_redraw->renderBottom);
+ _engine->_grid->drawOverModelActor(itemX, itemY, itemZ);
+ _engine->_redraw->addRedrawArea(_engine->_redraw->renderLeft, _engine->_redraw->renderTop, _engine->_redraw->renderRight, _engine->_redraw->renderBottom);
if (textState) {
- resetClip();
- textState = printText10();
+ _engine->_interface->resetClip();
+ textState = _engine->_text->printText10();
}
if (textState == 0 || textState == 2) {
- sdldelay(15);
+ _engine->_system->delayMillis(15);
}
- flipRedrawAreas();
+ _engine->_redraw->flipRedrawAreas();
- readKeys();
- if (skippedKey) {
+ _engine->readKeys();
+ if (_engine->_keyboard.skippedKey) {
if (!textState) {
quitItem = 1;
}
@@ -413,119 +411,124 @@ void processFoundItem(int32 item) {
}
}
- lbaTime++;
+ _engine->lbaTime++;
}
- while (playVoxSimple(currDialTextEntry)) {
- readKeys();
- if (skipIntro == 1) {
+ while (_engine->_text->playVoxSimple(_engine->_text->currDialTextEntry)) {
+ _engine->readKeys();
+ if (_engine->_keyboard.skipIntro == 1) {
break;
}
- delaySkip(1);
+ _engine->delaySkip(1);
}
initEngineProjections();
- initTextBank(currentTextBank + 3);
+ _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
/*do {
readKeys();
+ if (_engine->shouldQuit()) {
+ break;
+ }
delaySkip(1);
} while (!skipIntro);*/
- if (cfgfile.LanguageCDId && isSamplePlaying(currDialTextEntry)) {
- stopVox(currDialTextEntry);
+ if (_engine->cfgfile.LanguageCDId && _engine->_sound->isSamplePlaying(_engine->_text->currDialTextEntry)) {
+ _engine->_text->stopVox(_engine->_text->currDialTextEntry);
}
- sceneHero->animTimerData = tmpAnimTimer;
+ _engine->_scene->sceneHero->animTimerData = tmpAnimTimer;
}
-void processGameChoices(int32 choiceIdx) {
- int32 i;
- copyScreen(frontVideoBuffer, workVideoBuffer);
+void GameState::processGameChoices(int32 choiceIdx) {
+ _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- gameChoicesSettings[0] = 0; // Current loaded button (button number)
+ gameChoicesSettings[0] = 0; // Current loaded button (button number)
gameChoicesSettings[1] = numChoices; // Num of buttons
- gameChoicesSettings[2] = 0; // Buttons box height
- gameChoicesSettings[3] = currentTextBank + 3;
+ gameChoicesSettings[2] = 0; // Buttons box height
+ gameChoicesSettings[3] = _engine->_text->currentTextBank + 3;
if (numChoices > 0) {
- for(i = 0; i < numChoices; i++) {
+ for (int32 i = 0; i < numChoices; i++) {
gameChoicesSettings[i * 2 + 4] = 0;
gameChoicesSettings[i * 2 + 5] = gameChoices[i];
}
}
- drawAskQuestion(choiceIdx);
+ _engine->_text->drawAskQuestion(choiceIdx);
- processMenu(gameChoicesSettings);
+ _engine->_menu->processMenu(gameChoicesSettings);
choiceAnswer = gameChoices[gameChoicesSettings[0]];
// get right VOX entry index
- if (cfgfile.LanguageCDId) {
- initVoxToPlay(choiceAnswer);
- while(playVoxSimple(currDialTextEntry));
- stopVox(currDialTextEntry);
+ if (_engine->cfgfile.LanguageCDId) {
+ _engine->_text->initVoxToPlay(choiceAnswer);
+ while (_engine->_text->playVoxSimple(_engine->_text->currDialTextEntry)) {
+ if (_engine->shouldQuit()) {
+ break;
+ }
+ }
+ _engine->_text->stopVox(_engine->_text->currDialTextEntry);
- hasHiddenVox = 0;
- voxHiddenIndex = 0;
+ _engine->_text->hasHiddenVox = 0;
+ _engine->_text->voxHiddenIndex = 0;
}
}
-void processGameoverAnimation() { // makeGameOver
- int32 tmpLbaTime, startLbaTime;
- uint8 *gameOverPtr;
-
- tmpLbaTime = lbaTime;
+void GameState::processGameoverAnimation() { // makeGameOver
+ int32 tmpLbaTime = _engine->lbaTime;
// workaround to fix hero redraw after drowning
- sceneHero->staticFlags.bIsHidden = 1;
- redrawEngineActions(1);
- sceneHero->staticFlags.bIsHidden = 0;
+ _engine->_scene->sceneHero->staticFlags.bIsHidden = 1;
+ _engine->_redraw->redrawEngineActions(1);
+ _engine->_scene->sceneHero->staticFlags.bIsHidden = 0;
// TODO: drawInGameTransBox
- setPalette(paletteRGBA);
- copyScreen(frontVideoBuffer, workVideoBuffer);
- gameOverPtr = malloc(hqrEntrySize(HQR_RESS_FILE, RESSHQR_GAMEOVERMDL));
- hqrGetEntry(gameOverPtr, HQR_RESS_FILE, RESSHQR_GAMEOVERMDL);
+ _engine->setPalette(_engine->_screens->paletteRGB);
+ _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
+ uint8 *gameOverPtr = (uint8 *)malloc(_engine->_hqrdepack->hqrEntrySize(Resources::HQR_RESS_FILE, RESSHQR_GAMEOVERMDL));
+ _engine->_hqrdepack->hqrGetEntry(gameOverPtr, Resources::HQR_RESS_FILE, RESSHQR_GAMEOVERMDL);
if (gameOverPtr) {
int32 avg, cdot;
- prepareIsoModel(gameOverPtr);
- stopSamples();
- stopMidiMusic(); // stop fade music
- setCameraPosition(320, 240, 128, 200, 200);
- startLbaTime = lbaTime;
- setClip(120, 120, 519, 359);
-
- while(skipIntro != 1 && (lbaTime - startLbaTime) <= 0x1F4) {
- readKeys();
-
- avg = getAverageValue(40000, 3200, 500, lbaTime - startLbaTime);
- cdot = crossDot(1, 1024, 100, (lbaTime - startLbaTime) % 0x64);
- blitBox(120, 120, 519, 359, (int8*) workVideoBuffer, 120, 120, (int8*) frontVideoBuffer);
- setCameraAngle(0, 0, 0, 0, -cdot, 0, avg);
- renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
- copyBlockPhys(120, 120, 519, 359);
-
- lbaTime++;
- sdldelay(15);
+ _engine->_renderer->prepareIsoModel(gameOverPtr);
+ _engine->_sound->stopSamples();
+ _engine->_music->stopMidiMusic(); // stop fade music
+ _engine->_renderer->setCameraPosition(320, 240, 128, 200, 200);
+ int32 startLbaTime = _engine->lbaTime;
+ _engine->_interface->setClip(120, 120, 519, 359);
+
+ while (_engine->_keyboard.skipIntro != 1 && (_engine->lbaTime - startLbaTime) <= 0x1F4) {
+ _engine->readKeys();
+
+ avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
+ cdot = _engine->_screens->crossDot(1, 1024, 100, (_engine->lbaTime - startLbaTime) % 0x64);
+ _engine->_interface->blitBox(120, 120, 519, 359, (int8 *)_engine->workVideoBuffer, 120, 120, (int8 *)_engine->frontVideoBuffer);
+ _engine->_renderer->setCameraAngle(0, 0, 0, 0, -cdot, 0, avg);
+ _engine->_renderer->renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
+ _engine->copyBlockPhys(120, 120, 519, 359);
+
+ _engine->lbaTime++;
+ _engine->_system->delayMillis(15);
}
- playSample(37, Rnd(2000) + 3096, 1, 0x80, 0x80, 0x80, -1);
- blitBox(120, 120, 519, 359, (int8*) workVideoBuffer, 120, 120, (int8*) frontVideoBuffer);
- setCameraAngle(0, 0, 0, 0, 0, 0, 3200);
- renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
- copyBlockPhys(120, 120, 519, 359);
+ _engine->_sound->playSample(37, _engine->getRandomNumber(2000) + 3096, 1, 0x80, 0x80, 0x80, -1);
+ _engine->_interface->blitBox(120, 120, 519, 359, (int8 *)_engine->workVideoBuffer, 120, 120, (int8 *)_engine->frontVideoBuffer);
+ _engine->_renderer->setCameraAngle(0, 0, 0, 0, 0, 0, 3200);
+ _engine->_renderer->renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
+ _engine->copyBlockPhys(120, 120, 519, 359);
- delaySkip(2000);
+ _engine->delaySkip(2000);
- resetClip();
+ _engine->_interface->resetClip();
free(gameOverPtr);
- copyScreen(workVideoBuffer, frontVideoBuffer);
- flip();
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
initEngineProjections();
- lbaTime = tmpLbaTime;
+ _engine->lbaTime = tmpLbaTime;
}
}
+
+} // namespace TwinE
diff --git a/engines/twine/gamestate.h b/engines/twine/gamestate.h
index 28bd0d2dae..c06de48638 100644
--- a/engines/twine/gamestate.h
+++ b/engines/twine/gamestate.h
@@ -1,114 +1,131 @@
-/** @file gamestate.h
- @brief
- This file contains game state routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_GAMESTATE_H
+#define TWINE_GAMESTATE_H
+
+#include "common/scummsys.h"
+#include "twine/actor.h"
+
+namespace TwinE {
+
+#define NUM_GAME_FLAGS 255
+#define NUM_INVENTORY_ITEMS 28
+
+#define GAMEFLAG_INVENTORY_DISABLED 70
+
+enum InventoryItems {
+ kiHolomap = 0,
+ kiMagicBall = 1,
+ kiUseSabre = 2,
+ kiTunic = 4,
+ kiBookOfBu = 5,
+ kiProtoPack = 12,
+ kiPinguin = 14,
+ kiBonusList = 26,
+ kiCloverLeaf = 27
+};
-#ifndef GAMESTATE_H
-#define GAMESTATE_H
+/** Magicball strength*/
+enum MagicballStrengthType {
+ kNoBallStrenght = 2,
+ kYellowBallStrenght = 3,
+ kGreenBallStrenght = 4,
+ kRedBallStrenght = 6,
+ kFireBallStrength = 8
+};
-#include "sys.h"
+class TwinEEngine;
-#define NUM_GAME_FLAGS 255
-#define NUM_INVENTORY_ITEMS 28
+class GameState {
+private:
+ TwinEEngine *_engine;
-#define GAMEFLAG_HAS_HOLOMAP 0
-#define GAMEFLAG_HAS_MAGICBALL 1
-#define GAMEFLAG_HAS_SABRE 2
-#define GAMEFLAG_TUNIC 4
-#define GAMEFLAG_BOOKOFBU 6
-#define GAMEFLAG_PROTOPACK 12
-#define GAMEFLAG_MECA_PINGUIN 14
-#define GAMEFLAG_HAS_CLOVER_LEAF 27
-#define GAMEFLAG_INVENTORY_DISABLED 70
+ void initSceneVars();
+ void initHeroVars();
-/** Magicball strength*/
-enum MagicballStrengthType {
- kNoBallStrenght = 2,
- kYellowBallStrenght = 3,
- kGreenBallStrenght = 4,
- kRedBallStrenght = 6,
- kFireBallStrength = 8
-};
+public:
+ GameState(TwinEEngine *engine);
-/** LBA engine game flags to save quest states */
-uint8 gameFlags[256];
+ /** LBA engine game flags to save quest states */
+ // TODO: why not NUM_GAME_FLAGS?
+ uint8 gameFlags[256]{0};
-/** LBA engine chapter */
-int16 gameChapter;
+ /** LBA engine chapter */
+ int16 gameChapter = 0;
-/** Magic ball type index */
-int16 magicBallIdx;
-/** Magic ball num bounce */
-int16 magicBallNumBounce;
-/** Magic ball auxiliar bounce number */
-int16 magicBallAuxBounce; // magicBallParam
-/** Magic level index */
-int16 magicLevelIdx;
+ /** Magic ball type index */
+ int16 magicBallIdx = 0;
+ /** Magic ball num bounce */
+ int16 magicBallNumBounce = 0;
+ /** Magic ball auxiliar bounce number */
+ int16 magicBallAuxBounce = 0; // magicBallParam
+ /** Magic level index */
+ int16 magicLevelIdx = 0;
-/** Store the number of inventory keys */
-int16 inventoryNumKeys;
-/** Store the number of inventory kashes */
-int16 inventoryNumKashes;
-/** Store the number of inventory clover leafs boxes */
-int16 inventoryNumLeafsBox;
-/** Store the number of inventory clover leafs */
-int16 inventoryNumLeafs;
-/** Store the number of inventory magic points */
-int16 inventoryMagicPoints;
-/** Store the number of gas */
-int16 inventoryNumGas;
+ /** Store the number of inventory keys */
+ int16 inventoryNumKeys = 0;
+ /** Store the number of inventory kashes */
+ int16 inventoryNumKashes = 0;
+ /** Store the number of inventory clover leafs boxes */
+ int16 inventoryNumLeafsBox = 0;
+ /** Store the number of inventory clover leafs */
+ int16 inventoryNumLeafs = 0;
+ /** Store the number of inventory magic points */
+ int16 inventoryMagicPoints = 0;
+ /** Store the number of gas */
+ int16 inventoryNumGas = 0;
-/** Its using FunFrock Sabre */
-int16 usingSabre;
+ /** Its using FunFrock Sabre */
+ int16 usingSabre = 0;
-/** Inventory used flags */
-uint8 inventoryFlags[NUM_INVENTORY_ITEMS];
+ /** Inventory used flags */
+ uint8 inventoryFlags[NUM_INVENTORY_ITEMS]{0};
-/** Inventory used flags */
-uint8 holomapFlags[150]; // GV14
+ uint8 holomapFlags[150]{0}; // GV14
-int8 savePlayerName[30]; // playerName
+ char playerName[30] = "";
-int32 gameChoices[10]; // inGameMenuData
-int32 numChoices; // numOfOptionsInChoice
-int16 gameChoicesSettings[18]; // choiceTab - same structure as menu settings
-int32 choiceAnswer; // inGameMenuAnswer
+ int32 gameChoices[10]{0}; // inGameMenuData
+ int32 numChoices = 0; // numOfOptionsInChoice
+ int16 gameChoicesSettings[18]{0}; // choiceTab - same structure as menu settings
+ int32 choiceAnswer = 0; // inGameMenuAnswer
-extern int32 magicLevelStrengthOfHit[];
+ /** Initialize all engine variables */
+ void initEngineVars();
-/** Initialize all engine variables */
-void initEngineVars(int32 save);
+ /** Initialize engine 3D projections */
+ void initEngineProjections();
-/** Initialize engine 3D projections */
-void initEngineProjections();
+ void processFoundItem(int32 item);
-void processFoundItem(int32 item);
+ bool loadGame();
+ bool saveGame();
-void loadGame();
-void saveGame();
+ void processGameChoices(int32 choiceIdx);
-void processGameChoices(int32 choiceIdx);
+ void processGameoverAnimation();
+};
-void processGameoverAnimation();
+} // namespace TwinE
#endif
diff --git a/engines/twine/grid.cpp b/engines/twine/grid.cpp
index d10c8576e6..b007d65c32 100644
--- a/engines/twine/grid.cpp
+++ b/engines/twine/grid.cpp
@@ -1,43 +1,38 @@
-/** @file grid.cpp
- @brief
- This file contains grid manipulation routines
-
- TwinEngine: a Little Big Adventure engine
-
- Copyright (C) 2013 The TwinEngine team
- Copyright (C) 2008-2013 Prequengine team
- Copyright (C) 2002-2007 The TwinEngine team
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "grid.h"
-#include "resources.h"
-#include "lbaengine.h"
-#include "scene.h"
-#include "sdlengine.h"
-#include "interface.h"
-#include "screens.h"
-#include "actor.h"
-#include "renderer.h"
-#include "redraw.h"
-#include "collision.h"
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/grid.h"
+#include "common/textconsole.h"
+#include "twine/actor.h"
+#include "twine/collision.h"
+#include "twine/interface.h"
+#include "twine/redraw.h"
+#include "twine/renderer.h"
+#include "twine/resources.h"
+#include "twine/scene.h"
+#include "twine/screens.h"
+#include "twine/twine.h"
+
+namespace TwinE {
/** Grip X size */
#define GRID_SIZE_X 64
@@ -46,122 +41,37 @@
/** Grip Z size */
#define GRID_SIZE_Z GRID_SIZE_X
-/** Total number of bricks allowed in the game */
-#define NUM_BRICKS 9000
-
-/** Total number of bricks allowed in the game */
-#define CELLING_GRIDS_START_INDEX 120
-
-/** Table with all loaded bricks */
-uint8* brickTable[NUM_BRICKS];
-/** Table with all loaded bricks masks */
-uint8* brickMaskTable[NUM_BRICKS];
-/** Table with all loaded bricks sizes */
-uint32 brickSizeTable[NUM_BRICKS];
-/** Table with all loaded bricks usage */
-uint8 brickUsageTable[NUM_BRICKS];
-
-/** Current grid pointer */
-uint8 *currentGrid;
-/** Current block library pointer */
-uint8 *currentBll;
-/** Number of block libraries */
-int32 numberOfBll;
-
-/** Block fragment entry */
-struct BlockEntry {
- /** Block library index */
- uint8 blockIdx;
- /** Brick index inside the block library */
- uint8 brickBlockIdx;
-};
-/** Grid block entry types */
-typedef struct BlockEntry blockMap[64][64][25];
-
-/** Brick entry data */
-typedef struct BrickEntry {
- /** Brick X position in screen */
- int16 x; //z
- /** Brick Y position in screen */
- int16 y;
- /** Brick Z position in screen */
- int16 z; // x
- /** Brick pixel X position */
- int16 posX;
- /** Brick pixel Y position */
- int16 posY;
- /** Brick index */
- int16 index;
- /** Brick shape type */
- uint8 shape;
- /** Brick sound type */
- uint8 sound;
-} BrickEntry;
-
-/** Brick data buffer */
-BrickEntry bricksDataBuffer[28][150];
-/** Brick info buffer */
-int16 brickInfoBuffer[28];
-
-/** Current brick pixel X position */
-int32 brickPixelPosX;
-/** Current brick pixel Y position */
-int32 brickPixelPosY;
-
-/** Copy grid mask to allow actors to display over the bricks
- @param index current brick index
- @param x grid X coordinate
- @param y grid Y coordinate
- @param buffer work video buffer */
-void copyGridMask(int32 index, int32 x, int32 y, uint8 *buffer) {
- uint8 *ptr;
- int32 top;
- int32 bottom;
- int32 left;
- int32 right;
- uint8 *outPtr;
- uint8 *inPtr;
- int32 offset;
- int32 vc3;
-
- int32 temp;
- int32 j;
+Grid::Grid(TwinEEngine *engine) : _engine(engine) {}
- int32 absX;
- int32 absY;
+void Grid::copyGridMask(int32 index, int32 x, int32 y, uint8 *buffer) {
+ uint8 *ptr = brickMaskTable[index];
- int32 vSize;
+ int32 left = x + *(ptr + 2);
+ int32 top = y + *(ptr + 3);
+ int32 right = *ptr + left - 1;
+ int32 bottom = *(ptr + 1) + top - 1;
- ptr = brickMaskTable[index];
-
- left = x + *(ptr + 2);
- top = y + *(ptr + 3);
- right = *ptr + left - 1;
- bottom = *(ptr + 1) + top - 1;
-
- if (left > textWindowRight || right < textWindowLeft || bottom < textWindowTop || top > textWindowBottom)
+ if (left > _engine->_interface->textWindowRight || right < _engine->_interface->textWindowLeft || bottom < _engine->_interface->textWindowTop || top > _engine->_interface->textWindowBottom)
return;
ptr += 4;
- absX = left;
- absY = top;
+ int32 absX = left;
+ int32 absY = top;
- vSize = (bottom - top) + 1;
+ int32 vSize = (bottom - top) + 1;
if (vSize <= 0)
return;
- offset = -((right - left) - SCREEN_WIDTH) - 1;
+ int32 offset = -((right - left) - SCREEN_WIDTH) - 1;
right++;
bottom++;
// if line on top aren't in the blitting area...
- if (absY < textWindowTop) {
- int numOfLineToRemove;
-
- numOfLineToRemove = textWindowTop - absY;
+ if (absY < _engine->_interface->textWindowTop) {
+ int numOfLineToRemove = _engine->_interface->textWindowTop - absY;
vSize -= numOfLineToRemove;
if (vSize <= 0)
@@ -178,20 +88,20 @@ void copyGridMask(int32 index, int32 x, int32 y, uint8 *buffer) {
}
// reduce the vSize to remove lines on bottom
- if (absY + vSize - 1 > textWindowBottom) {
- vSize = textWindowBottom - absY + 1;
+ if (absY + vSize - 1 > _engine->_interface->textWindowBottom) {
+ vSize = _engine->_interface->textWindowBottom - absY + 1;
if (vSize <= 0)
return;
}
- outPtr = frontVideoBuffer + screenLookupTable[absY] + left;
- inPtr = buffer + screenLookupTable[absY] + left;
+ uint8 *outPtr = _engine->frontVideoBuffer + _engine->screenLookupTable[absY] + left;
+ uint8 *inPtr = buffer + _engine->screenLookupTable[absY] + left;
do {
- vc3 = *(ptr++);
+ int32 vc3 = *(ptr++);
do {
- temp = *(ptr++); // skip size
+ int32 temp = *(ptr++); // skip size
outPtr += temp;
inPtr += temp;
@@ -203,8 +113,8 @@ void copyGridMask(int32 index, int32 x, int32 y, uint8 *buffer) {
temp = *(ptr++); // copy size
- for (j = 0; j < temp; j++) {
- if (absX >= textWindowLeft && absX <= textWindowRight)
+ for (int32 j = 0; j < temp; j++) {
+ if (absX >= _engine->_interface->textWindowLeft && absX <= _engine->_interface->textWindowRight)
*outPtr = *inPtr;
absX++;
@@ -220,103 +130,80 @@ void copyGridMask(int32 index, int32 x, int32 y, uint8 *buffer) {
} while (--vSize);
}
-/** Draw 3D actor over bricks
- @param X actor X coordinate
- @param Y actor Y coordinate
- @param Z actor Z coordinate */
-void drawOverModelActor(int32 X, int32 Y, int32 Z) {
- int32 CopyBlockPhysLeft;
- int32 CopyBlockPhysRight;
- int32 i;
- int32 j;
- BrickEntry *currBrickEntry;
+void Grid::drawOverModelActor(int32 X, int32 Y, int32 Z) {
+ const int32 copyBlockPhysLeft = ((_engine->_interface->textWindowLeft + 24) / 24) - 1;
+ const int32 copyBlockPhysRight = ((_engine->_interface->textWindowRight + 24) / 24);
- CopyBlockPhysLeft = ((textWindowLeft + 24) / 24) - 1;
- CopyBlockPhysRight = ((textWindowRight + 24) / 24);
-
- for (j = CopyBlockPhysLeft; j <= CopyBlockPhysRight; j++) {
- for (i = 0; i < brickInfoBuffer[j]; i++) {
- currBrickEntry = &bricksDataBuffer[j][i];
+ for (int32 j = copyBlockPhysLeft; j <= copyBlockPhysRight; j++) {
+ for (int32 i = 0; i < brickInfoBuffer[j]; i++) {
+ BrickEntry *currBrickEntry = &bricksDataBuffer[j][i];
- if (currBrickEntry->posY + 38 > textWindowTop && currBrickEntry->posY <= textWindowBottom && currBrickEntry->y >= Y) {
+ if (currBrickEntry->posY + 38 > _engine->_interface->textWindowTop && currBrickEntry->posY <= _engine->_interface->textWindowBottom && currBrickEntry->y >= Y) {
if (currBrickEntry->x + currBrickEntry->z > Z + X) {
- copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, workVideoBuffer);
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, _engine->workVideoBuffer);
}
}
}
}
}
-/** Draw sprite actor over bricks
- @param X actor X coordinate
- @param Y actor Y coordinate
- @param Z actor Z coordinate */
-void drawOverSpriteActor(int32 X, int32 Y, int32 Z) {
- int32 CopyBlockPhysLeft;
- int32 CopyBlockPhysRight;
+void Grid::drawOverSpriteActor(int32 X, int32 Y, int32 Z) {
+ int32 copyBlockPhysLeft;
+ int32 copyBlockPhysRight;
int32 i;
int32 j;
BrickEntry *currBrickEntry;
- CopyBlockPhysLeft = ((textWindowLeft + 24) / 24) - 1;
- CopyBlockPhysRight = (textWindowRight + 24) / 24;
+ copyBlockPhysLeft = ((_engine->_interface->textWindowLeft + 24) / 24) - 1;
+ copyBlockPhysRight = (_engine->_interface->textWindowRight + 24) / 24;
- for (j = CopyBlockPhysLeft; j <= CopyBlockPhysRight; j++) {
+ for (j = copyBlockPhysLeft; j <= copyBlockPhysRight; j++) {
for (i = 0; i < brickInfoBuffer[j]; i++) {
currBrickEntry = &bricksDataBuffer[j][i];
- if (currBrickEntry->posY + 38 > textWindowTop && currBrickEntry->posY <= textWindowBottom && currBrickEntry->y >= Y) {
+ if (currBrickEntry->posY + 38 > _engine->_interface->textWindowTop && currBrickEntry->posY <= _engine->_interface->textWindowBottom && currBrickEntry->y >= Y) {
if ((currBrickEntry->x == X) && (currBrickEntry->z == Z)) {
- copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, workVideoBuffer);
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, _engine->workVideoBuffer);
}
if ((currBrickEntry->x > X) || (currBrickEntry->z > Z)) {
- copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, workVideoBuffer);
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, _engine->workVideoBuffer);
}
}
}
}
}
-/** Process brick masks to allow actors to display over the bricks
- @param buffer brick pointer buffer
- @param ptr brick mask pointer buffer */
-int processGridMask(uint8 *buffer, uint8 *ptr) {
+int Grid::processGridMask(uint8 *buffer, uint8 *ptr) {
uint32 *ptrSave = (uint32 *)ptr;
- uint8 *ptr2;
- uint8 *esi;
- uint8 *edi;
- uint8 iteration, numOfBlock, ah, bl, al, bh;
- int32 ebx;
-
- ebx = *((uint32 *)buffer); // brick flag
+ int32 ebx = *((uint32 *)buffer); // brick flag
buffer += 4;
*((uint32 *)ptr) = ebx;
ptr += 4;
- bh = (ebx & 0x0000FF00) >> 8;
+ uint8 bh = (ebx & 0x0000FF00) >> 8;
- esi = (uint8 *) buffer;
- edi = (uint8 *) ptr;
+ uint8 *esi = (uint8 *)buffer;
+ uint8 *edi = (uint8 *)ptr;
- iteration = 0;
+ uint8 iteration = 0;
do {
- numOfBlock = 0;
- ah = 0;
- ptr2 = edi;
+ uint8 numOfBlock = 0;
+ uint8 ah = 0;
+ uint8 *ptr2 = edi;
edi++;
- bl = *(esi++);
+ uint8 bl = *(esi++);
- if (*(esi) & 0xC0) { // the first time isn't skip. the skip size is 0 in that case
+ if (*(esi)&0xC0) { // the first time isn't skip. the skip size is 0 in that case
*edi++ = 0;
numOfBlock++;
}
do {
- al = *esi++;
+ uint8 al = *esi++;
iteration = al;
iteration &= 0x3F;
iteration++;
@@ -348,44 +235,31 @@ int processGridMask(uint8 *buffer, uint8 *ptr) {
*ptr2 = numOfBlock;
} while (--bh > 0);
- return ((int)((uint8 *) edi - (uint8 *) ptrSave));
+ return ((int)((uint8 *)edi - (uint8 *)ptrSave));
}
-/** Create grid masks to allow display actors over the bricks */
-void createGridMask() {
- int32 b;
-
- for (b = 0; b < NUM_BRICKS; b++) {
- if (brickUsageTable[b]) {
- if (brickMaskTable[b])
- free(brickMaskTable[b]);
- brickMaskTable[b] = (uint8*)malloc(brickSizeTable[b]);
- processGridMask(brickTable[b], brickMaskTable[b]);
+void Grid::createGridMask() {
+ for (int32 b = 0; b < NUM_BRICKS; b++) {
+ if (!brickUsageTable[b]) {
+ continue;
}
+ if (brickMaskTable[b])
+ free(brickMaskTable[b]);
+ brickMaskTable[b] = (uint8 *)malloc(brickSizeTable[b]);
+ processGridMask(brickTable[b], brickMaskTable[b]);
}
}
-/** Get sprite width and height sizes
- @param offset sprite pointer offset
- @param width sprite width size
- @param height sprite height size
- @param spritePtr sprite buffer pointer */
-void getSpriteSize(int32 offset, int32 *width, int32 *height, uint8 *spritePtr) {
+void Grid::getSpriteSize(int32 offset, int32 *width, int32 *height, uint8 *spritePtr) {
spritePtr += *((int32 *)(spritePtr + offset * 4));
*width = *spritePtr;
*height = *(spritePtr + 1);
}
-/** Load grid bricks according with block librarie usage
- @param gridSize size of the current grid
- @return true if everything went ok*/
-int32 loadGridBricks(int32 gridSize) {
+int32 Grid::loadGridBricks(int32 gridSize) {
uint32 firstBrick = 60000;
uint32 lastBrick = 0;
- uint8* ptrToBllBits;
- uint32 i;
- uint32 j;
uint32 currentBllEntryIdx = 0;
memset(brickTable, 0, sizeof(brickTable));
@@ -393,16 +267,16 @@ int32 loadGridBricks(int32 gridSize) {
memset(brickUsageTable, 0, sizeof(brickUsageTable));
// get block librarie usage bits
- ptrToBllBits = currentGrid + (gridSize - 32);
+ uint8 *ptrToBllBits = currentGrid + (gridSize - 32);
// for all bits under the 32bytes (256bits)
- for (i = 1; i < 256; i++) {
+ for (uint32 i = 1; i < 256; i++) {
uint8 currentBitByte = *(ptrToBllBits + (i / 8));
uint8 currentBitMask = 1 << (7 - (i & 7));
if (currentBitByte & currentBitMask) {
uint32 currentBllOffset = *((uint32 *)(currentBll + currentBllEntryIdx));
- uint8* currentBllPtr = currentBll + currentBllOffset;
+ uint8 *currentBllPtr = currentBll + currentBllOffset;
uint32 bllSizeX = currentBllPtr[0];
uint32 bllSizeY = currentBllPtr[1];
@@ -410,10 +284,10 @@ int32 loadGridBricks(int32 gridSize) {
uint32 bllSize = bllSizeX * bllSizeY * bllSizeZ;
- uint8* bllDataPtr = currentBllPtr + 5;
+ uint8 *bllDataPtr = currentBllPtr + 5;
- for (j = 0; j < bllSize; j++) {
- uint32 brickIdx = *((int16*)(bllDataPtr));
+ for (uint32 j = 0; j < bllSize; j++) {
+ uint32 brickIdx = *((int16 *)(bllDataPtr));
if (brickIdx) {
brickIdx--;
@@ -432,107 +306,80 @@ int32 loadGridBricks(int32 gridSize) {
currentBllEntryIdx += 4;
}
- for (i = firstBrick; i <= lastBrick; i++) {
+ for (uint32 i = firstBrick; i <= lastBrick; i++) {
if (brickUsageTable[i]) {
- brickSizeTable[i] = hqrGetallocEntry(&brickTable[i], HQR_LBA_BRK_FILE, i);
+ brickSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&brickTable[i], Resources::HQR_LBA_BRK_FILE, i);
}
}
return 1;
}
-/** Create grid Y column in block buffer
- @param gridEntry current grid index
- @param dest destination block buffer */
-void createGridColumn(uint8 *gridEntry, uint8 *dest) {
- int32 blockCount;
- int32 brickCount;
- int32 flag;
- int32 gridIdx;
- int32 i;
- uint16 *gridBuffer;
- uint16 *blockByffer;
-
- brickCount = *(gridEntry++);
+void Grid::createGridColumn(uint8 *gridEntry, uint8 *dest) {
+ int32 brickCount = *(gridEntry++);
do {
- flag = *(gridEntry++);
-
- blockCount = (flag & 0x3F) + 1;
+ int32 flag = *(gridEntry++);
+ int32 blockCount = (flag & 0x3F) + 1;
- gridBuffer = (uint16 *) gridEntry;
- blockByffer = (uint16 *) dest;
+ uint16 *gridBuffer = (uint16 *)gridEntry;
+ uint16 *blockByffer = (uint16 *)dest;
if (!(flag & 0xC0)) {
- for (i = 0; i < blockCount; i++)
+ for (int32 i = 0; i < blockCount; i++)
*(blockByffer++) = 0;
} else if (flag & 0x40) {
- for (i = 0; i < blockCount; i++)
+ for (int32 i = 0; i < blockCount; i++)
*(blockByffer++) = *(gridBuffer++);
} else {
- gridIdx = *(gridBuffer++);
- for (i = 0; i < blockCount; i++)
+ int32 gridIdx = *(gridBuffer++);
+ for (int32 i = 0; i < blockCount; i++)
*(blockByffer++) = gridIdx;
}
- gridEntry = (uint8 *) gridBuffer;
- dest = (uint8 *) blockByffer;
+ gridEntry = (uint8 *)gridBuffer;
+ dest = (uint8 *)blockByffer;
} while (--brickCount);
}
-/** Create grid Y column in block buffer
- @param gridEntry current grid index
- @param dest destination block buffer */
-void createCellingGridColumn(uint8 *gridEntry, uint8 *dest) {
- int32 blockCount;
- int32 brickCount;
- int32 flag;
- int32 gridIdx;
- int32 i;
- uint16 *gridBuffer;
- uint16 *blockByffer;
Commit: 77f29ada5f2a1f0f7a3f2052cb317088318e354d
https://github.com/scummvm/scummvm/commit/77f29ada5f2a1f0f7a3f2052cb317088318e354d
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: renamed variables and initialize members
Changed paths:
engines/twine/actor.h
engines/twine/menu.h
engines/twine/redraw.cpp
engines/twine/redraw.h
engines/twine/renderer.cpp
engines/twine/renderer.h
engines/twine/text.h
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/actor.h b/engines/twine/actor.h
index 18dfa67992..6b4a1aae31 100644
--- a/engines/twine/actor.h
+++ b/engines/twine/actor.h
@@ -240,7 +240,7 @@ public:
HeroBehaviourType heroBehaviour = kNormal;
/** Hero auto agressive mode */
- int16 autoAgressive = 0;
+ int16 autoAgressive = 1;
/** Previous Hero behaviour */
HeroBehaviourType previousHeroBehaviour = kNormal;
/** Previous Hero angle */
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index f2a09afbc2..8c34f3d71a 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -80,8 +80,8 @@ private:
public:
Menu(TwinEEngine *engine);
- int32 currMenuTextIndex = 0;
- int32 currMenuTextBank = 0;
+ int32 currMenuTextIndex = -1;
+ int32 currMenuTextBank = -1;
char currMenuTextBuffer[256] = "";
int16 itemAngle[255]{0}; // objectRotation
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index acdd752043..4bccea2100 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -155,13 +155,10 @@ void Redraw::blitBackgroundAreas() {
}
void Redraw::sortDrawingList(DrawListStruct *list, int32 listSize) {
- int32 i;
- int32 j;
-
DrawListStruct tempStruct;
- for (i = 0; i < listSize - 1; i++) {
- for (j = 0; j < listSize - 1 - i; j++) {
+ for (int32 i = 0; i < listSize - 1; i++) {
+ for (int32 j = 0; j < listSize - 1 - i; j++) {
if (list[j + 1].posValue < list[j].posValue) {
memcpy(&tempStruct, &list[j + 1], sizeof(DrawListStruct));
memcpy(&list[j + 1], &list[j], sizeof(DrawListStruct));
@@ -171,14 +168,14 @@ void Redraw::sortDrawingList(DrawListStruct *list, int32 listSize) {
}
}
-void Redraw::addOverlay(int16 type, int16 info0, int16 X, int16 Y, int16 info1, int16 posType, int16 lifeTime) {
+void Redraw::addOverlay(int16 type, int16 info0, int16 x, int16 y, int16 info1, int16 posType, int16 lifeTime) {
for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
OverlayListStruct *overlay = &overlayList[i];
if (overlay->info0 == -1) {
overlay->type = type;
overlay->info0 = info0;
- overlay->X = X;
- overlay->Y = Y;
+ overlay->x = x;
+ overlay->y = y;
overlay->info1 = info1;
overlay->posType = posType;
overlay->lifeTime = _engine->lbaTime + lifeTime * 50;
@@ -194,8 +191,8 @@ void Redraw::updateOverlayTypePosition(int16 X1, int16 Y1, int16 X2, int16 Y2) {
for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
OverlayListStruct *overlay = &overlayList[i];
if (overlay->type == koFollowActor) {
- overlay->X = newX;
- overlay->Y = newY;
+ overlay->x = newX;
+ overlay->y = newY;
}
}
}
@@ -203,12 +200,6 @@ void Redraw::updateOverlayTypePosition(int16 X1, int16 Y1, int16 X2, int16 Y2) {
void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
int16 tmp_projPosX;
int16 tmp_projPosY;
- int32 i;
- int32 tmpVal;
- int32 modelActorPos; // arg_1A
- int32 spriteActorPos; // top6
- int32 shadowActorPos; // top2
- int32 drawListPos; // a12
ActorStruct *actor;
tmp_projPosX = _engine->_renderer->projPosXScreen;
@@ -235,10 +226,10 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
// first loop
- modelActorPos = 0;
- drawListPos = 0;
- spriteActorPos = 0x1000;
- shadowActorPos = 0x0C00;
+ int32 modelActorPos = 0;
+ int32 drawListPos = 0;
+ int32 spriteActorPos = 0x1000;
+ int32 shadowActorPos = 0x0C00;
// Process actors drawing list
for (modelActorPos = 0; modelActorPos < _engine->_scene->sceneNumActors; modelActorPos++, spriteActorPos++, shadowActorPos++) {
@@ -264,7 +255,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
if ((actor->staticFlags.bUsesClipping && _engine->_renderer->projPosX > -112 && _engine->_renderer->projPosX < 752 && _engine->_renderer->projPosY > -50 && _engine->_renderer->projPosY < 651) ||
((!actor->staticFlags.bUsesClipping) && _engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580)) {
- tmpVal = actor->z + actor->x - _engine->_grid->cameraX - _engine->_grid->cameraZ;
+ int32 tmpVal = actor->z + actor->x - _engine->_grid->cameraX - _engine->_grid->cameraZ;
// if actor is above another actor
if (actor->standOn != -1) {
@@ -297,9 +288,9 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
tmpVal--;
drawList[drawListPos].posValue = tmpVal; // save the shadow entry in the drawList
drawList[drawListPos].index = 0xC00; // shadowActorPos
- drawList[drawListPos].X = _engine->_actor->shadowX;
- drawList[drawListPos].Y = _engine->_actor->shadowY;
- drawList[drawListPos].Z = _engine->_actor->shadowZ;
+ drawList[drawListPos].x = _engine->_actor->shadowX;
+ drawList[drawListPos].y = _engine->_actor->shadowY;
+ drawList[drawListPos].z = _engine->_actor->shadowZ;
drawList[drawListPos].field_A = 2;
drawListPos++;
}
@@ -310,7 +301,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
}
// second loop
- for (i = 0; i < EXTRA_MAX_ENTRIES; i++) {
+ for (int32 i = 0; i < EXTRA_MAX_ENTRIES; i++) {
ExtraListStruct *extra = &_engine->_extra->extraList[i];
if (extra->info0 != -1) {
if (extra->type & 0x400) {
@@ -334,9 +325,9 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ - 1;
drawList[drawListPos].index = 0xC00;
- drawList[drawListPos].X = _engine->_actor->shadowX;
- drawList[drawListPos].Y = _engine->_actor->shadowY;
- drawList[drawListPos].Z = _engine->_actor->shadowZ;
+ drawList[drawListPos].x = _engine->_actor->shadowX;
+ drawList[drawListPos].y = _engine->_actor->shadowY;
+ drawList[drawListPos].z = _engine->_actor->shadowZ;
drawList[drawListPos].field_A = 0;
drawListPos++;
}
@@ -414,7 +405,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
DrawListStruct shadow = drawList[pos];
// get actor position on screen
- _engine->_renderer->projectPositionOnScreen(shadow.X - _engine->_grid->cameraX, shadow.Y - _engine->_grid->cameraY, shadow.Z - _engine->_grid->cameraZ);
+ _engine->_renderer->projectPositionOnScreen(shadow.x - _engine->_grid->cameraX, shadow.y - _engine->_grid->cameraY, shadow.z - _engine->_grid->cameraZ);
_engine->_grid->getSpriteSize(shadow.field_A, &spriteWidth, &spriteHeight, _engine->_scene->spriteShadowPtr);
@@ -430,9 +421,9 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
_engine->_grid->drawSprite(shadow.field_A, renderLeft, renderTop, _engine->_scene->spriteShadowPtr);
}
- tmpX = (shadow.X + 0x100) >> 9;
- tmpY = shadow.Y >> 8;
- tmpZ = (shadow.Z + 0x100) >> 9;
+ tmpX = (shadow.x + 0x100) >> 9;
+ tmpY = shadow.y >> 8;
+ tmpZ = (shadow.z + 0x100) >> 9;
_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
@@ -524,9 +515,9 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
if (_engine->_interface->textWindowLeft <= _engine->_interface->textWindowRight && _engine->_interface->textWindowTop <= _engine->_interface->textWindowBottom) {
int32 tmpX, tmpY, tmpZ;
- tmpX = (drawList[pos].X + 0x100) >> 9;
- tmpY = drawList[pos].Y >> 8;
- tmpZ = (drawList[pos].Z + 0x100) >> 9;
+ tmpX = (drawList[pos].x + 0x100) >> 9;
+ tmpY = drawList[pos].y >> 8;
+ tmpZ = (drawList[pos].z + 0x100) >> 9;
_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
addRedrawArea(_engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, renderRight, renderBottom);
@@ -545,7 +536,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
_engine->_debugScene->displayZones(_engine->_keyboard.skipIntro);
}
- for (i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
+ for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
OverlayListStruct *overlay = &overlayList[i];
if (overlay->info0 != -1) {
// process position overlay
@@ -561,8 +552,8 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
_engine->_renderer->projectPositionOnScreen(actor2->x - _engine->_grid->cameraX, actor2->y + actor2->boudingBox.y.topRight - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ);
- overlay->X = _engine->_renderer->projPosX;
- overlay->Y = _engine->_renderer->projPosY;
+ overlay->x = _engine->_renderer->projPosX;
+ overlay->y = _engine->_renderer->projPosY;
if (_engine->lbaTime >= overlay->lifeTime) {
overlay->info0 = -1;
@@ -583,8 +574,8 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
offsetX = *((int16 *)(_engine->_scene->spriteBoundingBoxPtr + (overlay->info0 * 16)));
offsetY = *((int16 *)(_engine->_scene->spriteBoundingBoxPtr + (overlay->info0 * 16) + 2));
- renderLeft = offsetX + overlay->X;
- renderTop = offsetY + overlay->Y;
+ renderLeft = offsetX + overlay->x;
+ renderTop = offsetY + overlay->y;
renderRight = renderLeft + spriteWidth;
renderBottom = renderTop + spriteHeight;
@@ -598,15 +589,15 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
case koNumber: {
int32 textLength, textHeight;
char text[10];
- sprintf(text, "%d", overlay->info0);
+ snprintf(text, sizeof(text), "%d", overlay->info0);
textLength = _engine->_text->getTextSize(text);
textHeight = 48;
- renderLeft = overlay->X - (textLength / 2);
- renderTop = overlay->Y - 24;
- renderRight = overlay->X + (textLength / 2);
- renderBottom = overlay->Y + textHeight;
+ renderLeft = overlay->x - (textLength / 2);
+ renderTop = overlay->y - 24;
+ renderRight = overlay->x + (textLength / 2);
+ renderBottom = overlay->y + textHeight;
_engine->_interface->setClip(renderLeft, renderTop, renderRight, renderBottom);
@@ -629,10 +620,10 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
textLength = _engine->_text->getTextSize(text);
textHeight = 48;
- renderLeft = overlay->X - (textLength / 2);
- renderTop = overlay->Y - 24;
- renderRight = overlay->X + (textLength / 2);
- renderBottom = overlay->Y + textHeight;
+ renderLeft = overlay->x - (textLength / 2);
+ renderTop = overlay->y - 24;
+ renderRight = overlay->x + (textLength / 2);
+ renderBottom = overlay->y + textHeight;
_engine->_interface->setClip(renderLeft, renderTop, renderRight, renderBottom);
@@ -669,10 +660,10 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
int32 textLength = _engine->_text->getTextSize(text);
int32 textHeight = 48;
- renderLeft = overlay->X - (textLength / 2);
- renderTop = overlay->Y - 24;
- renderRight = overlay->X + (textLength / 2);
- renderBottom = overlay->Y + textHeight;
+ renderLeft = overlay->x - (textLength / 2);
+ renderTop = overlay->y - 24;
+ renderRight = overlay->x + (textLength / 2);
+ renderBottom = overlay->y + textHeight;
if (renderLeft < 0) {
renderLeft = 0;
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index e737b837cf..78202505d5 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -46,8 +46,8 @@ enum OverlayPosType {
typedef struct OverlayListStruct {
int16 type = 0;
int16 info0 = 0; // sprite/3d model entry | number | number range
- int16 X = 0;
- int16 Y = 0;
+ int16 x = 0;
+ int16 y = 0;
int16 info1 = 0; // followed actor | total coins
int16 posType = 0;
int16 lifeTime = 0;
@@ -60,9 +60,9 @@ private:
typedef struct DrawListStruct {
int16 posValue = 0;
uint16 index = 0; // field_2
- uint16 X = 0;
- uint16 Y = 0;
- uint16 Z = 0;
+ uint16 x = 0;
+ uint16 y = 0;
+ uint16 z = 0;
uint16 field_A = 0;
uint16 field_C = 0;
uint16 field_E = 0;
@@ -124,7 +124,7 @@ public:
int32 numOfRedrawBox = 0;
/** Save last actor that bubble dialog icon */
- int32 bubbleActor = 0;
+ int32 bubbleActor = -1;
int32 bubbleSpriteIndex = 0;
OverlayListStruct overlayList[OVERLAY_MAX_ENTRIES];
diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index cb12b314ef..58bcbf2648 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -20,13 +20,13 @@
*
*/
+#include "twine/renderer.h"
#include "common/textconsole.h"
#include "common/util.h"
#include "twine/interface.h"
#include "twine/menu.h"
#include "twine/movements.h"
#include "twine/redraw.h"
-#include "twine/renderer.h"
#include "twine/shadeangletab.h"
#include "twine/twine.h"
@@ -64,24 +64,23 @@ int32 Renderer::projectPositionOnScreen(int32 cX, int32 cY, int32 cZ) {
projPosY = (-cY * cameraPosZ) / posZ + orthoProjY;
projPosZ = posZ;
return -1;
- } else {
- projPosX = 0;
- projPosY = 0;
- projPosZ = 0;
- return 0;
}
- } else {
- projPosX = ((cX - cZ) * 24) / 512 + orthoProjX;
- projPosY = (((cX + cZ) * 12) - cY * 30) / 512 + orthoProjY;
- projPosZ = cZ - cY - cX;
+
+ projPosX = 0;
+ projPosY = 0;
+ projPosZ = 0;
+ return 0;
}
+ projPosX = ((cX - cZ) * 24) / 512 + orthoProjX;
+ projPosY = (((cX + cZ) * 12) - cY * 30) / 512 + orthoProjY;
+ projPosZ = cZ - cY - cX;
return 1;
}
-void Renderer::setCameraPosition(int32 X, int32 Y, int32 cX, int32 cY, int32 cZ) {
- orthoProjX = X;
- orthoProjY = Y;
+void Renderer::setCameraPosition(int32 x, int32 y, int32 cX, int32 cY, int32 cZ) {
+ orthoProjX = x;
+ orthoProjY = y;
cameraPosX = cX;
cameraPosY = cY;
@@ -90,10 +89,10 @@ void Renderer::setCameraPosition(int32 X, int32 Y, int32 cX, int32 cY, int32 cZ)
isUsingOrhoProjection = 0;
}
-void Renderer::setBaseTranslation(int32 X, int32 Y, int32 Z) {
- baseTransPosX = X;
- baseTransPosY = Y;
- baseTransPosZ = Z;
+void Renderer::setBaseTranslation(int32 x, int32 y, int32 z) {
+ baseTransPosX = x;
+ baseTransPosY = y;
+ baseTransPosZ = z;
}
void Renderer::setOrthoProjection(int32 X, int32 Y, int32 Z) {
@@ -104,25 +103,22 @@ void Renderer::setOrthoProjection(int32 X, int32 Y, int32 Z) {
isUsingOrhoProjection = 1;
}
-void Renderer::getBaseRotationPosition(int32 X, int32 Y, int32 Z) {
- destX = (baseMatrix[0] * X + baseMatrix[1] * Y + baseMatrix[2] * Z) >> 14;
- destY = (baseMatrix[3] * X + baseMatrix[4] * Y + baseMatrix[5] * Z) >> 14;
- destZ = (baseMatrix[6] * X + baseMatrix[7] * Y + baseMatrix[8] * Z) >> 14;
+void Renderer::getBaseRotationPosition(int32 x, int32 y, int32 z) {
+ destX = (baseMatrix[0] * x + baseMatrix[1] * y + baseMatrix[2] * z) >> 14;
+ destY = (baseMatrix[3] * x + baseMatrix[4] * y + baseMatrix[5] * z) >> 14;
+ destZ = (baseMatrix[6] * x + baseMatrix[7] * y + baseMatrix[8] * z) >> 14;
}
-void Renderer::setBaseRotation(int32 X, int32 Y, int32 Z) {
- int32 matrixElem;
- double Xradians, Yradians, Zradians;
-
+void Renderer::setBaseRotation(int32 x, int32 y, int32 z) {
shadeAngleTab3 = &shadeAngleTable[384];
- baseMatrixRotationX = X & 0x3FF;
- baseMatrixRotationY = Y & 0x3FF;
- baseMatrixRotationZ = Z & 0x3FF;
+ baseMatrixRotationX = x & 0x3FF;
+ baseMatrixRotationY = y & 0x3FF;
+ baseMatrixRotationZ = z & 0x3FF;
- Xradians = (double)((256 - X) % 1024) * 2 * M_PI / 1024;
- Yradians = (double)((256 - Y) % 1024) * 2 * M_PI / 1024;
- Zradians = (double)((256 - Z) % 1024) * 2 * M_PI / 1024;
+ double Xradians = (double)((256 - x) % 1024) * 2 * M_PI / 1024;
+ double Yradians = (double)((256 - y) % 1024) * 2 * M_PI / 1024;
+ double Zradians = (double)((256 - z) % 1024) * 2 * M_PI / 1024;
baseMatrix[0] = (int32)(sin(Zradians) * sin(Yradians) * 16384);
baseMatrix[1] = (int32)(-cos(Zradians) * 16384);
@@ -132,7 +128,7 @@ void Renderer::setBaseRotation(int32 X, int32 Y, int32 Z) {
baseMatrix[6] = (int32)(cos(Zradians) * cos(Xradians) * 16384);
baseMatrix[7] = (int32)(sin(Zradians) * cos(Xradians) * 16384);
- matrixElem = baseMatrix[3];
+ int32 matrixElem = baseMatrix[3];
baseMatrix[3] = (int32)(sin(Yradians) * matrixElem + 16384 * cos(Yradians) * cos(Xradians));
baseMatrix[5] = (int32)(cos(Yradians) * matrixElem - 16384 * sin(Yradians) * cos(Xradians));
@@ -149,10 +145,10 @@ void Renderer::setBaseRotation(int32 X, int32 Y, int32 Z) {
baseRotPosZ = destZ;
}
-void Renderer::getCameraAnglePositions(int32 X, int32 Y, int32 Z) {
- destX = (baseMatrix[0] * X + baseMatrix[3] * Y + baseMatrix[6] * Z) >> 14;
- destY = (baseMatrix[1] * X + baseMatrix[4] * Y + baseMatrix[7] * Z) >> 14;
- destZ = (baseMatrix[2] * X + baseMatrix[5] * Y + baseMatrix[8] * Z) >> 14;
+void Renderer::getCameraAnglePositions(int32 x, int32 y, int32 z) {
+ destX = (baseMatrix[0] * x + baseMatrix[3] * y + baseMatrix[6] * z) >> 14;
+ destY = (baseMatrix[1] * x + baseMatrix[4] * y + baseMatrix[7] * z) >> 14;
+ destZ = (baseMatrix[2] * x + baseMatrix[5] * y + baseMatrix[8] * z) >> 14;
}
void Renderer::setCameraAngle(int32 transPosX, int32 transPosY, int32 transPosZ, int32 rotPosX, int32 rotPosY, int32 rotPosZ, int32 param6) {
@@ -172,19 +168,14 @@ void Renderer::setCameraAngle(int32 transPosX, int32 transPosY, int32 transPosZ,
}
void Renderer::applyRotation(int32 *tempMatrix, int32 *currentMatrix) {
- int32 i;
- int32 angle;
- int32 angleVar1; // esi
- int32 angleVar2; // ecx
-
int32 matrix1[9];
int32 matrix2[9];
if (renderAngleX) {
- angle = renderAngleX;
- angleVar2 = shadeAngleTable[angle & 0x3FF];
+ int32 angle = renderAngleX;
+ int32 angleVar2 = shadeAngleTable[angle & 0x3FF];
angle += 0x100;
- angleVar1 = shadeAngleTable[angle & 0x3FF];
+ int32 angleVar1 = shadeAngleTable[angle & 0x3FF];
matrix1[0] = currentMatrix[0];
matrix1[3] = currentMatrix[3];
@@ -197,15 +188,15 @@ void Renderer::applyRotation(int32 *tempMatrix, int32 *currentMatrix) {
matrix1[7] = (currentMatrix[8] * angleVar2 + currentMatrix[7] * angleVar1) >> 14;
matrix1[8] = (currentMatrix[8] * angleVar1 - currentMatrix[7] * angleVar2) >> 14;
} else {
- for (i = 0; i < 9; i++)
+ for (int32 i = 0; i < 9; i++)
matrix1[i] = currentMatrix[i];
}
if (renderAngleZ) {
- angle = renderAngleZ;
- angleVar2 = shadeAngleTable[angle & 0x3FF];
+ int32 angle = renderAngleZ;
+ int32 angleVar2 = shadeAngleTable[angle & 0x3FF];
angle += 0x100;
- angleVar1 = shadeAngleTable[angle & 0x3FF];
+ int32 angleVar1 = shadeAngleTable[angle & 0x3FF];
matrix2[2] = matrix1[2];
matrix2[5] = matrix1[5];
@@ -218,15 +209,15 @@ void Renderer::applyRotation(int32 *tempMatrix, int32 *currentMatrix) {
matrix2[6] = (matrix1[7] * angleVar2 + matrix1[6] * angleVar1) >> 14;
matrix2[7] = (matrix1[7] * angleVar1 - matrix1[6] * angleVar2) >> 14;
} else {
- for (i = 0; i < 9; i++)
+ for (int32 i = 0; i < 9; i++)
matrix2[i] = matrix1[i];
}
if (renderAngleY) {
- angle = renderAngleY;
- angleVar2 = shadeAngleTable[angle & 0x3FF]; // esi
+ int32 angle = renderAngleY;
+ int32 angleVar2 = shadeAngleTable[angle & 0x3FF]; // esi
angle += 0x100;
- angleVar1 = shadeAngleTable[angle & 0x3FF]; // ecx
+ int32 angleVar1 = shadeAngleTable[angle & 0x3FF]; // ecx
tempMatrix[1] = matrix2[1];
tempMatrix[4] = matrix2[4];
@@ -240,28 +231,21 @@ void Renderer::applyRotation(int32 *tempMatrix, int32 *currentMatrix) {
tempMatrix[6] = (matrix2[6] * angleVar1 - matrix2[8] * angleVar2) >> 14;
tempMatrix[8] = (matrix2[6] * angleVar2 + matrix2[8] * angleVar1) >> 14;
} else {
- for (i = 0; i < 9; i++)
+ for (int32 i = 0; i < 9; i++)
tempMatrix[i] = matrix2[i];
}
}
void Renderer::applyPointsRotation(uint8 *firstPointsPtr, int32 numPoints, pointTab *destPoints, int32 *rotationMatrix) {
- int16 tmpX;
- int16 tmpY;
- int16 tmpZ;
-
- int16 *tempPtr;
-
int32 numOfPoints2 = numPoints;
- uint8 *pointsPtr2;
do {
- pointsPtr2 = firstPointsPtr;
- tempPtr = (int16 *)(firstPointsPtr);
+ uint8 *pointsPtr2 = firstPointsPtr;
+ const int16 *tempPtr = (int16 *)(firstPointsPtr);
- tmpX = tempPtr[0];
- tmpY = tempPtr[1];
- tmpZ = tempPtr[2];
+ const int16 tmpX = tempPtr[0];
+ const int16 tmpY = tempPtr[1];
+ const int16 tmpZ = tempPtr[2];
destPoints->X = ((rotationMatrix[0] * tmpX + rotationMatrix[1] * tmpY + rotationMatrix[2] * tmpZ) >> 14) + destX;
destPoints->Y = ((rotationMatrix[3] * tmpX + rotationMatrix[4] * tmpY + rotationMatrix[5] * tmpZ) >> 14) + destY;
@@ -273,9 +257,6 @@ void Renderer::applyPointsRotation(uint8 *firstPointsPtr, int32 numPoints, point
}
void Renderer::processRotatedElement(int32 rotZ, int32 rotY, int32 rotX, elementEntry *elemPtr) { // unsigned char * elemPtr) // loadPart
- int32 *currentMatrix;
- int16 baseElement;
-
int32 firstPoint = elemPtr->firstPoint;
int32 numOfPoints2 = elemPtr->numOfPoints;
@@ -288,8 +269,9 @@ void Renderer::processRotatedElement(int32 rotZ, int32 rotY, int32 rotX, element
}
//baseElement = *((unsigned short int*)elemPtr+6);
- baseElement = elemPtr->baseElement;
+ const int16 baseElement = elemPtr->baseElement;
+ int32 *currentMatrix;
// if its the first point
if (baseElement == -1) {
currentMatrix = baseMatrix;
@@ -316,22 +298,15 @@ void Renderer::processRotatedElement(int32 rotZ, int32 rotY, int32 rotX, element
}
void Renderer::applyPointsTranslation(uint8 *firstPointsPtr, int32 numPoints, pointTab *destPoints, int32 *translationMatrix) {
- int16 tmpX;
- int16 tmpY;
- int16 tmpZ;
-
- int16 *tempPtr;
-
int32 numOfPoints2 = numPoints;
- uint8 *pointsPtr2;
do {
- pointsPtr2 = firstPointsPtr;
- tempPtr = (int16 *)(firstPointsPtr);
+ uint8 *pointsPtr2 = firstPointsPtr;
+ int16 *tempPtr = (int16 *)(firstPointsPtr);
- tmpX = tempPtr[0] + renderAngleZ;
- tmpY = tempPtr[1] + renderAngleY;
- tmpZ = tempPtr[2] + renderAngleX;
+ const int16 tmpX = tempPtr[0] + renderAngleZ;
+ const int16 tmpY = tempPtr[1] + renderAngleY;
+ const int16 tmpZ = tempPtr[2] + renderAngleX;
destPoints->X = ((translationMatrix[0] * tmpX + translationMatrix[1] * tmpY + translationMatrix[2] * tmpZ) >> 14) + destX;
destPoints->Y = ((translationMatrix[3] * tmpX + translationMatrix[4] * tmpY + translationMatrix[5] * tmpZ) >> 14) + destY;
@@ -343,35 +318,28 @@ void Renderer::applyPointsTranslation(uint8 *firstPointsPtr, int32 numPoints, po
}
void Renderer::processTranslatedElement(int32 rotX, int32 rotY, int32 rotZ, elementEntry *elemPtr) {
- int32 *dest;
- int32 *source;
-
renderAngleX = rotX;
renderAngleY = rotY;
renderAngleZ = rotZ;
if (elemPtr->baseElement == -1) { // base point
- int32 i;
-
destX = 0;
destY = 0;
destZ = 0;
- dest = (int32 *)currentMatrixTableEntry;
+ int32 *dest = (int32 *)currentMatrixTableEntry;
- for (i = 0; i < 9; i++)
+ for (int32 i = 0; i < 9; i++)
dest[i] = baseMatrix[i];
} else { // dependent
- int32 i;
-
destX = computedPoints[(elemPtr->basePoint) / 6].X;
destY = computedPoints[(elemPtr->basePoint) / 6].Y;
destZ = computedPoints[(elemPtr->basePoint) / 6].Z;
- source = (int32 *)((uint8 *)matricesTable + elemPtr->baseElement);
- dest = (int32 *)currentMatrixTableEntry;
+ const int32 *source = (const int32 *)((const uint8 *)matricesTable + elemPtr->baseElement);
+ int32 *dest = (int32 *)currentMatrixTableEntry;
- for (i = 0; i < 9; i++)
+ for (int32 i = 0; i < 9; i++)
dest[i] = source[i];
}
@@ -379,18 +347,12 @@ void Renderer::processTranslatedElement(int32 rotX, int32 rotY, int32 rotZ, elem
}
void Renderer::translateGroup(int16 ax, int16 bx, int16 cx) {
- int32 ebp;
- int32 ebx;
- int32 ecx;
- int32 eax;
- int32 edi;
-
- ebp = ax;
- ebx = bx;
- ecx = cx;
+ int32 ebp = ax;
+ int32 ebx = bx;
+ int32 ecx = cx;
- edi = shadeMatrix[0];
- eax = shadeMatrix[1];
+ int32 edi = shadeMatrix[0];
+ int32 eax = shadeMatrix[1];
edi *= ebp;
eax *= ebx;
edi += eax;
@@ -439,21 +401,15 @@ void Renderer::setLightVector(int32 angleX, int32 angleY, int32 angleZ) {
lightZ = destZ;
}
-// TODO: remove me - use scummvm function
FORCEINLINE int16 clamp(int16 x, int16 a, int16 b) {
return x < a ? a : (x > b ? b : x);
}
int Renderer::computePolygons() {
- int16 vertexX, vertexY;
int16 *outPtr;
int32 i, nVertex;
int8 direction, up;
- int16 oldVertexX, oldVertexY;
- int16 currentVertexX, currentVertexY;
- int16 vsize, hsize, ypos;
- int16 cvalue, cdelta;
- int64 slope, xpos;
+ int64 slope;
vertexData *vertices;
pRenderV1 = vertexCoordinates;
@@ -466,7 +422,7 @@ int Renderer::computePolygons() {
for (i = 0; i < numOfVertex; i++) {
vertices[i].x = clamp(vertices[i].x, 0, SCREEN_WIDTH - 1);
- vertexX = vertices[i].x;
+ int16 vertexX = vertices[i].x;
if (vertexX < vleft)
vleft = vertexX;
@@ -474,7 +430,7 @@ int Renderer::computePolygons() {
vright = vertexX;
vertices[i].y = clamp(vertices[i].y, 0, SCREEN_HEIGHT - 1);
- vertexY = vertices[i].y;
+ int16 vertexY = vertices[i].y;
if (vertexY < vtop)
vtop = vertexY;
if (vertexY > vbottom)
@@ -482,12 +438,12 @@ int Renderer::computePolygons() {
}
vertexParam1 = vertexParam2 = vertices[numOfVertex - 1].param;
- currentVertexX = vertices[numOfVertex - 1].x;
- currentVertexY = vertices[numOfVertex - 1].y;
+ int16 currentVertexX = vertices[numOfVertex - 1].x;
+ int16 currentVertexY = vertices[numOfVertex - 1].y;
for (nVertex = 0; nVertex < numOfVertex; nVertex++) {
- oldVertexY = currentVertexY;
- oldVertexX = currentVertexX;
+ int16 oldVertexY = currentVertexY;
+ int16 oldVertexX = currentVertexX;
oldVertexParam = vertexParam1;
vertexParam1 = vertexParam2 = vertices[nVertex].param;
@@ -502,9 +458,13 @@ int Renderer::computePolygons() {
up = currentVertexY < oldVertexY;
direction = up ? -1 : 1;
- vsize = ABS(currentVertexY - oldVertexY);
- hsize = ABS(currentVertexX - oldVertexX);
+ int16 vsize = ABS(currentVertexY - oldVertexY);
+ int16 hsize = ABS(currentVertexX - oldVertexX);
+ int16 cvalue;
+ int16 cdelta;
+ int16 ypos;
+ int16 xpos;
if (direction * oldVertexX > direction * currentVertexX) { // if we are going up right
xpos = currentVertexX;
ypos = currentVertexY;
@@ -525,7 +485,7 @@ int Renderer::computePolygons() {
for (i = 0; i < vsize + 2; i++) {
if ((outPtr - polyTab) < 960)
if ((outPtr - polyTab) > 0)
- *(outPtr) = (int16)xpos;
+ *(outPtr) = xpos;
outPtr += direction;
xpos += slope;
}
@@ -1659,11 +1619,10 @@ void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
// This function should only be called ONCE, otherwise it corrupts the model data.
// The following code implements an unused flag to indicate that a model was already processed.
- if (!(bodyHeader->bodyFlag & 0x80)) {
- bodyHeader->bodyFlag |= 0x80;
- } else {
+ if ((bodyHeader->bodyFlag & 0x80)) {
return;
}
+ bodyHeader->bodyFlag |= 0x80;
if (!(bodyHeader->bodyFlag & 2)) { // no animation applicable
return;
@@ -1732,10 +1691,6 @@ int Renderer::renderIsoModel(int32 X, int32 Y, int32 Z, int32 angleX, int32 angl
}
void Renderer::copyActorInternAnim(uint8 *bodyPtrSrc, uint8 *bodyPtrDest) {
- int16 cx;
- int16 ax;
- int32 i;
-
// check if both characters allow animation
if (!(*((int16 *)bodyPtrSrc) & 2))
return;
@@ -1752,11 +1707,11 @@ void Renderer::copyActorInternAnim(uint8 *bodyPtrSrc, uint8 *bodyPtrDest) {
bodyPtrSrc = bodyPtrSrc + *((int16 *)(bodyPtrSrc - 2));
bodyPtrSrc = bodyPtrSrc + (*((int16 *)bodyPtrSrc)) * 6 + 2;
- cx = *((int16 *)bodyPtrSrc);
+ int16 cx = *((int16 *)bodyPtrSrc);
bodyPtrDest = bodyPtrDest + *((int16 *)(bodyPtrDest - 2));
bodyPtrDest = bodyPtrDest + (*((int16 *)bodyPtrDest)) * 6 + 2;
- ax = *((int16 *)bodyPtrDest);
+ int16 ax = *((int16 *)bodyPtrDest);
if (cx > ax)
cx = ax;
@@ -1764,7 +1719,7 @@ void Renderer::copyActorInternAnim(uint8 *bodyPtrSrc, uint8 *bodyPtrDest) {
bodyPtrSrc += 10;
bodyPtrDest += 10;
- for (i = 0; i < cx; i++) {
+ for (int32 i = 0; i < cx; i++) {
*((uint32 *)bodyPtrDest) = *((uint32 *)bodyPtrSrc);
*((uint32 *)(bodyPtrDest + 4)) = *((uint32 *)(bodyPtrSrc + 4));
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index a10006371b..adacc2695e 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -55,7 +55,7 @@ private:
int32 numOfShades = 0; // field_10
int32 field_14 = 0;
int32 field_18 = 0;
- int32 Y = 0;
+ int32 y = 0;
int32 field_20 = 0;
int16 field_24 = 0;
} elementEntry;
diff --git a/engines/twine/text.h b/engines/twine/text.h
index a30f46cea2..2eee225ea5 100644
--- a/engines/twine/text.h
+++ b/engines/twine/text.h
@@ -104,7 +104,7 @@ public:
Text(TwinEEngine *engine) : _engine(engine) {}
/** Current text bank */
- int32 currentTextBank = 0;
+ int32 currentTextBank = -1;
/** Current dialogue text size */
int32 currDialTextSize = 0;
/** Current dialogue text pointer */
@@ -151,7 +151,7 @@ public:
int32 nextDialTextEntry = 0; // ordered entry
Common::String currentVoxBankFile;
- int32 showDialogueBubble = 0;
+ int32 showDialogueBubble = 1;
/**
* Initialize dialogue
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 392997488a..f0d704871a 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -278,26 +278,14 @@ void TwinEEngine::initAll() {
memset(_menu->itemAngle, 256, sizeof(_menu->itemAngle)); // reset inventory items angles
_redraw->bubbleSpriteIndex = SPRITEHQR_DIAG_BUBBLE_LEFT;
- _redraw->bubbleActor = -1;
- _text->showDialogueBubble = 1;
-
- _text->currentTextBank = -1;
- _menu->currMenuTextIndex = -1;
- _menu->currMenuTextBank = -1;
- _actor->autoAgressive = 1;
_scene->sceneHero = &_scene->sceneActors[0];
- _redraw->renderLeft = 0;
- _redraw->renderTop = 0;
_redraw->renderRight = SCREEN_TEXTLIMIT_RIGHT;
_redraw->renderBottom = SCREEN_TEXTLIMIT_BOTTOM;
// Set clip to fullscreen by default, allows main menu to render properly after load
_interface->resetClip();
- rightMouse = 0;
- leftMouse = 0;
-
_resources->initResources();
initSVGA();
@@ -308,21 +296,22 @@ int TwinEEngine::getRandomNumber(uint max) {
}
void TwinEEngine::freezeTime() {
- if (!isTimeFreezed)
+ if (!isTimeFreezed) {
saveFreezedTime = lbaTime;
+ }
isTimeFreezed++;
}
void TwinEEngine::unfreezeTime() {
--isTimeFreezed;
- if (isTimeFreezed == 0)
+ if (isTimeFreezed == 0) {
lbaTime = saveFreezedTime;
+ }
}
void TwinEEngine::processActorSamplePosition(int32 actorIdx) {
- int32 channelIdx;
- ActorStruct *actor = &_scene->sceneActors[actorIdx];
- channelIdx = _sound->getActorChannel(actorIdx);
+ const ActorStruct *actor = &_scene->sceneActors[actorIdx];
+ const int32 channelIdx = _sound->getActorChannel(actorIdx);
_sound->setSamplePosition(channelIdx, actor->x, actor->y, actor->z);
}
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 845e96a992..8063e7f3da 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -60,13 +60,12 @@ static const struct TwinELanguage {
const char *name;
const char *id;
} LanguageTypes[] = {
- {"English", "EN_"},
- {"Francais", "FR_"},
- {"Deutsch", "DE_"},
- {"Espanol", "SP_"},
- {"Italiano", "IT_"},
- {"Portugues", ""}
-};
+ {"English", "EN_"},
+ {"Francais", "FR_"},
+ {"Deutsch", "DE_"},
+ {"Espanol", "SP_"},
+ {"Italiano", "IT_"},
+ {"Portugues", ""}};
/** Configuration file structure
@@ -153,6 +152,7 @@ class TwinEEngine : public Engine {
private:
int32 isTimeFreezed = 0;
int32 saveFreezedTime = 0;
+ ActorMoveStruct loopMovePtr; // mainLoopVar1
public:
TwinEEngine(OSystem *system, Common::Language language, uint32 flags);
@@ -194,7 +194,7 @@ public:
ConfigFile cfgfile;
/** CD Game directory */
- const char *cdDir;
+ const char *cdDir = "";
/** Initialize LBA engine */
void initEngine();
@@ -211,11 +211,11 @@ public:
/** Allocate video memory, both front and back buffers */
void allocVideoMemory();
int getRandomNumber(uint max = 0x7FFF);
- int32 quitGame;
- int32 lbaTime;
+ int32 quitGame = 0;
+ int32 lbaTime = 0;
- int16 leftMouse;
- int16 rightMouse;
+ int16 leftMouse = 0;
+ int16 rightMouse = 0;
/** Work video buffer */
uint8 *workVideoBuffer = nullptr;
@@ -223,21 +223,18 @@ public:
uint8 *frontVideoBuffer = nullptr;
/** temporary screen table */
- int32 screenLookupTable[2000];
-
- ActorMoveStruct loopMovePtr; // mainLoopVar1
-
- int32 loopPressedKey; // mainLoopVar5
- int32 previousLoopPressedKey; // mainLoopVar6
- int32 loopCurrentKey; // mainLoopVar7
- int32 loopInventoryItem; // mainLoopVar9
+ int32 screenLookupTable[2000]{0};
- int32 loopActorStep; // mainLoopVar17
+ int32 loopPressedKey = 0; // mainLoopVar5
+ int32 previousLoopPressedKey = 0; // mainLoopVar6
+ int32 loopCurrentKey = 0; // mainLoopVar7
+ int32 loopInventoryItem = 0; // mainLoopVar9
+ int32 loopActorStep = 0; // mainLoopVar17
/** Disable screen recenter */
- int16 disableScreenRecenter;
+ int16 disableScreenRecenter = 0;
- int32 zoomScreen;
+ int32 zoomScreen = 0;
void freezeTime();
void unfreezeTime();
Commit: 784e62d0126165c8e0d99cba958d53a526766756
https://github.com/scummvm/scummvm/commit/784e62d0126165c8e0d99cba958d53a526766756
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: updated detection entries for other languages
Changed paths:
engines/twine/detection.cpp
diff --git a/engines/twine/detection.cpp b/engines/twine/detection.cpp
index 26df3f60cd..9270ba5ab5 100644
--- a/engines/twine/detection.cpp
+++ b/engines/twine/detection.cpp
@@ -34,13 +34,31 @@ static const PlainGameDescriptor twineGames[] = {
static const ADGameDescription twineGameDescriptions[] = {
{
"twine",
- "GOG 1.0",
+ "GOG 1.0 English",
AD_ENTRY1s("text.hqr", "ae7343552f8fbd17a1fc6cea2197a912", 248654),
Common::EN_ANY,
Common::kPlatformDOS,
0,
GUIO1(GUIO_NONE)
},
+ {
+ "twine",
+ "GOG 1.0 French",
+ AD_ENTRY1s("text.hqr", "ae7343552f8fbd17a1fc6cea2197a912", 248654),
+ Common::FR_FRA,
+ Common::kPlatformDOS,
+ 0,
+ GUIO1(GUIO_NONE)
+ },
+ {
+ "twine",
+ "GOG 1.0 German",
+ AD_ENTRY1s("text.hqr", "ae7343552f8fbd17a1fc6cea2197a912", 248654),
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ 0,
+ GUIO1(GUIO_NONE)
+ },
AD_TABLE_END_MARKER
};
Commit: 9428284b17df4c5c9583ccae732836175f5b716e
https://github.com/scummvm/scummvm/commit/9428284b17df4c5c9583ccae732836175f5b716e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: reduced scope
Changed paths:
engines/twine/twine.cpp
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index f0d704871a..8478d3e30b 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -62,9 +62,6 @@
namespace TwinE {
-/** Engine current version */
-static const char *ENGINE_VERSION = "0.2.0";
-
TwinEEngine::TwinEEngine(OSystem *system, Common::Language language, uint32 flags)
: Engine(system), _gameLang(language), _gameFlags(flags), _rnd("twine") {
setDebugger(new GUI::Debugger());
@@ -221,6 +218,9 @@ void TwinEEngine::initEngine() {
// getting configuration file
initConfigurations();
+ /** Engine current version */
+ const char *ENGINE_VERSION = "0.2.0";
+
// Show engine information
debug("TwinEngine v%s", ENGINE_VERSION);
debug("(c)2002 The TwinEngine team.");
Commit: a93aafbdc43dde76a886077724f8ead65ebe0b46
https://github.com/scummvm/scummvm/commit/a93aafbdc43dde76a886077724f8ead65ebe0b46
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: removed Quit member from ConfigFile
Changed paths:
engines/twine/menu.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 104f4ffd74..098a5f2839 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -24,6 +24,7 @@
#include "audio/mixer.h"
#include "backends/audiocd/audiocd.h"
#include "common/config-manager.h"
+#include "common/events.h"
#include "common/scummsys.h"
#include "common/system.h"
#include "twine/actor.h"
@@ -688,7 +689,7 @@ void Menu::mainMenu() {
memset(plasmaEffectPtr, 0, kPlasmaEffectFilesize);
_engine->_hqrdepack->hqrGetEntry(plasmaEffectPtr, Resources::HQR_RESS_FILE, RESSHQR_PLASMAEFFECT);
- while (!_engine->cfgfile.Quit) {
+ while (!_engine->shouldQuit()) {
_engine->_text->initTextBank(0);
_engine->_music->playTrackMusic(9); // LBA's Theme
@@ -711,7 +712,9 @@ void Menu::mainMenu() {
break;
}
case kQuit: {
- _engine->cfgfile.Quit = 1;
+ Common::Event event;
+ event.type = Common::EVENT_QUIT;
+ _engine->_system->getEventManager()->pushEvent(event);
break;
}
case kBackground: {
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 8478d3e30b..e0dd192b06 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -350,7 +350,6 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
freezeTime();
_gameState->saveGame(); // auto save game
quitGame = 0;
- cfgfile.Quit = 0;
unfreezeTime();
return 0;
}
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 8063e7f3da..478af023a8 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -107,8 +107,6 @@ typedef struct ConfigFile {
int32 AutoAgressive = 0;
/** SceZoom mode type */
int32 SceZoom = 0;
- /** Flag to quit the game */
- int32 Quit = 0;
/** Flag to toggle Wall Collision */
int32 WallCollision = 0;
} ConfigFile;
@@ -205,8 +203,10 @@ public:
/** Initialize all needed stuffs at first time running engine */
void initAll();
void processActorSamplePosition(int32 actorIdx);
- /** Game engine main loop
- @return true if we want to show credit sequence */
+ /**
+ * Game engine main loop
+ * @return true if we want to show credit sequence
+ */
int32 runGameEngine();
/** Allocate video memory, both front and back buffers */
void allocVideoMemory();
Commit: 1b4a8b85100b379278830cfe0fcce7bf28672094
https://github.com/scummvm/scummvm/commit/1b4a8b85100b379278830cfe0fcce7bf28672094
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: replaced magic number
Changed paths:
engines/twine/twine.cpp
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index e0dd192b06..a20d08040d 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -1086,7 +1086,7 @@ void TwinEEngine::readKeys() {
int find = 0;
bool found = false;
- for (int i = 0; i < 28; i++) {
+ for (int i = 0; i < ARRAYSIZE(pressedKeyMap); i++) {
if (pressedKeyMap[i] == localKey) {
find = i;
found = true;
Commit: 3bc2c1921bf75d85cf0f46481b2de9e183f8a1dc
https://github.com/scummvm/scummvm/commit/3bc2c1921bf75d85cf0f46481b2de9e183f8a1dc
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed parts of the input handling
fixed error when playing a second fla
Changed paths:
engines/twine/flamovies.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 03fdc8fdbc..7a5cdea0d5 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -252,6 +252,7 @@ void FlaMovies::playFlaMovie(const char *flaName) {
_fadeOut = -1;
fadeOutFrames = 0;
+ file.close();
if (!file.open(fileNamePath)) {
warning("Failed to open fla movie '%s'", fileNamePath.c_str());
return;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index a20d08040d..138ff3682f 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -1009,7 +1009,9 @@ void TwinEEngine::readKeys() {
break;
}
}
-
+#if 1
+ {
+#else
int32 size = 0;
uint8 *keyboard = nullptr; // TODO: SDL_GetKeyState(&size);
for (int32 j = 0; j < size; j++) {
@@ -1083,7 +1085,7 @@ void TwinEEngine::readKeys() {
}
}
}
-
+#endif
int find = 0;
bool found = false;
for (int i = 0; i < ARRAYSIZE(pressedKeyMap); i++) {
Commit: ecbc291e25fb2b5cb5c24a5a697fe8eb094a1031
https://github.com/scummvm/scummvm/commit/ecbc291e25fb2b5cb5c24a5a697fe8eb094a1031
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: use Graphics::Surface instead of raw 8 bit buffer
Changed paths:
engines/twine/debug.cpp
engines/twine/flamovies.cpp
engines/twine/flamovies.h
engines/twine/gamestate.cpp
engines/twine/grid.cpp
engines/twine/interface.cpp
engines/twine/interface.h
engines/twine/menu.cpp
engines/twine/menuoptions.cpp
engines/twine/redraw.cpp
engines/twine/renderer.cpp
engines/twine/screens.cpp
engines/twine/screens.h
engines/twine/text.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 2f729c7844..188a34236e 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -40,7 +40,7 @@ void Debug::debugFillButton(int32 X, int32 Y, int32 width, int32 height, int8 co
uint8 *ptr;
int32 offset;
- ptr = _engine->frontVideoBuffer + _engine->screenLookupTable[Y] + X;
+ ptr = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[Y] + X;
offset = 640 - (width);
for (i = 0; i < height; i++) {
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 7a5cdea0d5..b03c456ad6 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -116,7 +116,7 @@ void FlaMovies::drawDeltaFrame(uint8 *ptr, int32 width) {
void FlaMovies::scaleFla2x() {
int32 i, j;
uint8 *source = (uint8 *)flaBuffer;
- uint8 *dest = (uint8 *)_engine->workVideoBuffer;
+ uint8 *dest = (uint8 *)_engine->workVideoBuffer.getPixels();
if (_engine->cfgfile.Movie == CONF_MOVIE_FLAWIDE) {
for (i = 0; i < SCREEN_WIDTH / SCALE * 40; i++) {
@@ -156,19 +156,20 @@ void FlaMovies::processFrame() {
uint32 opcodeBlockSize;
uint8 opcode;
int32 aux = 0;
- uint8 *ptr;
file.read(&frameData.videoSize, 1);
file.read(&frameData.dummy, 1);
file.read(&frameData.frameVar0, 4);
+ if (frameData.frameVar0 > _engine->workVideoBuffer.w * _engine->workVideoBuffer.h * _engine->workVideoBuffer.format.bpp()) {
+ return;
+ }
- file.read(workVideoBufferCopy, frameData.frameVar0);
+ uint8 *ptr = (uint8*)_engine->workVideoBuffer.getPixels();
+ file.read(ptr, frameData.frameVar0);
if ((int32)frameData.videoSize <= 0)
return;
- ptr = workVideoBufferCopy;
-
do {
opcode = *((uint8 *)ptr);
ptr += 2;
@@ -258,8 +259,6 @@ void FlaMovies::playFlaMovie(const char *flaName) {
return;
}
- workVideoBufferCopy = _engine->workVideoBuffer;
-
file.read(&flaHeaderData.version, 6);
flaHeaderData.numOfFrames = file.readUint32LE();
flaHeaderData.speed = file.readByte();
diff --git a/engines/twine/flamovies.h b/engines/twine/flamovies.h
index 60846563e8..c87b1bb804 100644
--- a/engines/twine/flamovies.h
+++ b/engines/twine/flamovies.h
@@ -104,8 +104,6 @@ private:
int32 flaSampleTable[100] {0};
/** Number of samples in FLA movie */
int32 samplesInFla = 0;
- /** Auxiliar work video buffer */
- uint8 *workVideoBufferCopy = nullptr;
/** FLA movie header data */
FLAHeaderStruct flaHeaderData;
/** FLA movie header data */
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index e2537eeac5..169a08e132 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -504,7 +504,7 @@ void GameState::processGameoverAnimation() { // makeGameOver
avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
cdot = _engine->_screens->crossDot(1, 1024, 100, (_engine->lbaTime - startLbaTime) % 0x64);
- _engine->_interface->blitBox(120, 120, 519, 359, (int8 *)_engine->workVideoBuffer, 120, 120, (int8 *)_engine->frontVideoBuffer);
+ _engine->_interface->blitBox(120, 120, 519, 359, (int8 *)_engine->workVideoBuffer.getPixels(), 120, 120, (int8 *)_engine->frontVideoBuffer.getPixels());
_engine->_renderer->setCameraAngle(0, 0, 0, 0, -cdot, 0, avg);
_engine->_renderer->renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
_engine->copyBlockPhys(120, 120, 519, 359);
@@ -514,7 +514,7 @@ void GameState::processGameoverAnimation() { // makeGameOver
}
_engine->_sound->playSample(37, _engine->getRandomNumber(2000) + 3096, 1, 0x80, 0x80, 0x80, -1);
- _engine->_interface->blitBox(120, 120, 519, 359, (int8 *)_engine->workVideoBuffer, 120, 120, (int8 *)_engine->frontVideoBuffer);
+ _engine->_interface->blitBox(120, 120, 519, 359, (int8 *)_engine->workVideoBuffer.getPixels(), 120, 120, (int8 *)_engine->frontVideoBuffer.getPixels());
_engine->_renderer->setCameraAngle(0, 0, 0, 0, 0, 0, 3200);
_engine->_renderer->renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
_engine->copyBlockPhys(120, 120, 519, 359);
diff --git a/engines/twine/grid.cpp b/engines/twine/grid.cpp
index b007d65c32..b658262db7 100644
--- a/engines/twine/grid.cpp
+++ b/engines/twine/grid.cpp
@@ -94,7 +94,7 @@ void Grid::copyGridMask(int32 index, int32 x, int32 y, uint8 *buffer) {
return;
}
- uint8 *outPtr = _engine->frontVideoBuffer + _engine->screenLookupTable[absY] + left;
+ uint8 *outPtr = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[absY] + left;
uint8 *inPtr = buffer + _engine->screenLookupTable[absY] + left;
do {
@@ -140,7 +140,7 @@ void Grid::drawOverModelActor(int32 X, int32 Y, int32 Z) {
if (currBrickEntry->posY + 38 > _engine->_interface->textWindowTop && currBrickEntry->posY <= _engine->_interface->textWindowBottom && currBrickEntry->y >= Y) {
if (currBrickEntry->x + currBrickEntry->z > Z + X) {
- copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, _engine->workVideoBuffer);
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, (uint8 *)_engine->workVideoBuffer.getPixels());
}
}
}
@@ -163,11 +163,11 @@ void Grid::drawOverSpriteActor(int32 X, int32 Y, int32 Z) {
if (currBrickEntry->posY + 38 > _engine->_interface->textWindowTop && currBrickEntry->posY <= _engine->_interface->textWindowBottom && currBrickEntry->y >= Y) {
if ((currBrickEntry->x == X) && (currBrickEntry->z == Z)) {
- copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, _engine->workVideoBuffer);
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, (uint8 *)_engine->workVideoBuffer.getPixels());
}
if ((currBrickEntry->x > X) || (currBrickEntry->z > Z)) {
- copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, _engine->workVideoBuffer);
+ copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, (uint8 *)_engine->workVideoBuffer.getPixels());
}
}
}
@@ -475,7 +475,7 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, uint8 *ptr, bool
right++;
bottom++;
- outPtr = _engine->frontVideoBuffer + _engine->screenLookupTable[top] + left;
+ outPtr = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
int32 offset = -((right - left) - SCREEN_WIDTH);
@@ -489,16 +489,18 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, uint8 *ptr, bool
if (!(temp & 0x40)) {
temp = *(ptr++);
for (int32 i = 0; i < iteration; i++) {
- if (x >= _engine->_interface->textWindowLeft && x < _engine->_interface->textWindowRight && y >= _engine->_interface->textWindowTop && y < _engine->_interface->textWindowBottom)
- _engine->frontVideoBuffer[y * SCREEN_WIDTH + x] = temp;
+ if (x >= _engine->_interface->textWindowLeft && x < _engine->_interface->textWindowRight && y >= _engine->_interface->textWindowTop && y < _engine->_interface->textWindowBottom) {
+ *(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = temp;
+ }
x++;
outPtr++;
}
} else {
for (int32 i = 0; i < iteration; i++) {
- if (x >= _engine->_interface->textWindowLeft && x < _engine->_interface->textWindowRight && y >= _engine->_interface->textWindowTop && y < _engine->_interface->textWindowBottom)
- _engine->frontVideoBuffer[y * SCREEN_WIDTH + x] = *ptr;
+ if (x >= _engine->_interface->textWindowLeft && x < _engine->_interface->textWindowRight && y >= _engine->_interface->textWindowTop && y < _engine->_interface->textWindowBottom) {
+ *(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = *ptr;
+ }
x++;
ptr++;
diff --git a/engines/twine/interface.cpp b/engines/twine/interface.cpp
index 163fb526b0..74177c96c2 100644
--- a/engines/twine/interface.cpp
+++ b/engines/twine/interface.cpp
@@ -114,7 +114,7 @@ void Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, in
endHeight = -endHeight;
}
- out = _engine->frontVideoBuffer + _engine->screenLookupTable[startHeight] + startWidth;
+ out = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[startHeight] + startWidth;
color = currentLineColor;
if (endWidth < endHeight) { // significant slope
@@ -154,10 +154,10 @@ void Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, in
}
}
-void Interface::blitBox(int32 left, int32 top, int32 right, int32 bottom, int8 *source, int32 leftDest, int32 topDest, int8 *dest) {
+void Interface::blitBox(int32 left, int32 top, int32 right, int32 bottom, const int8 *source, int32 leftDest, int32 topDest, int8 *dest) {
int32 width;
int32 height;
- int8 *s;
+ const int8 *s;
int8 *d;
int32 insideLine;
int32 temp3;
@@ -215,7 +215,7 @@ void Interface::drawTransparentBox(int32 left, int32 top, int32 right, int32 bot
if (bottom > SCREEN_TEXTLIMIT_BOTTOM)
bottom = SCREEN_TEXTLIMIT_BOTTOM;
- pos = _engine->screenLookupTable[top] + _engine->frontVideoBuffer + left;
+ pos = _engine->screenLookupTable[top] + (uint8*)_engine->frontVideoBuffer.getPixels() + left;
height2 = height = bottom - top;
height2++;
@@ -263,7 +263,7 @@ void Interface::drawSplittedBox(int32 left, int32 top, int32 right, int32 bottom
// cropping
offset = -((right - left) - SCREEN_WIDTH);
- ptr = _engine->frontVideoBuffer + _engine->screenLookupTable[top] + left;
+ ptr = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
for (x = top; x < bottom; x++) {
for (y = left; y < right; y++) {
diff --git a/engines/twine/interface.h b/engines/twine/interface.h
index 049b22a436..f04fd51ab0 100644
--- a/engines/twine/interface.h
+++ b/engines/twine/interface.h
@@ -75,7 +75,7 @@ public:
* @param topDest start height to draw the button in destination buffer
* @param dest destination screen buffer, in this case front buffer
*/
- void blitBox(int32 left, int32 top, int32 right, int32 bottom, int8 *source, int32 leftDest, int32 topDest, int8 *dest);
+ void blitBox(int32 left, int32 top, int32 right, int32 bottom, const int8 *source, int32 leftDest, int32 topDest, int8 *dest);
/**
* Draws inside buttons transparent area
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 098a5f2839..2efb86d8d8 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -273,7 +273,7 @@ void Menu::processPlasmaEffect(int32 top, int32 color) {
plasmaEffectRenderFrame();
in = plasmaEffectPtr + 5 * PLASMA_WIDTH;
- out = _engine->frontVideoBuffer + _engine->screenLookupTable[top];
+ out = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top];
for (i = 0; i < 25; i++) {
for (j = 0; j < kMainMenuButtonWidth; j++) {
@@ -355,7 +355,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 id, int32 value, in
}
}
} else {
- _engine->_interface->blitBox(left, top, right, bottom, (int8 *)_engine->workVideoBuffer, left, top, (int8 *)_engine->frontVideoBuffer);
+ _engine->_interface->blitBox(left, top, right, bottom, (const int8*)_engine->workVideoBuffer.getPixels(), left, top, (int8*)_engine->frontVideoBuffer.getPixels());
_engine->_interface->drawTransparentBox(left, top, right, bottom2, 4);
}
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 8cb48e6c02..80b2854645 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -140,7 +140,7 @@ void MenuOptions::drawSelectableCharacter(int32 x, int32 y, int32 arg) {
if (arg != 0) {
_engine->_interface->drawSplittedBox(left, top, right, bottom, 91);
} else {
- _engine->_interface->blitBox(left, top, right, bottom, (int8 *)_engine->workVideoBuffer, left, top, (int8 *)_engine->frontVideoBuffer);
+ _engine->_interface->blitBox(left, top, right, bottom, (const int8*)_engine->workVideoBuffer.getPixels(), left, top, (int8*)_engine->frontVideoBuffer.getPixels());
right2 = right;
_engine->_interface->drawTransparentBox(left, top, right2, bottom, 4);
}
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 4bccea2100..4b95c94d2e 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -22,6 +22,7 @@
#include "twine/redraw.h"
#include "common/textconsole.h"
+#include "graphics/surface.h"
#include "twine/actor.h"
#include "twine/animations.h"
#include "twine/collision.h"
@@ -149,7 +150,7 @@ void Redraw::blitBackgroundAreas() {
const RedrawStruct *currentArea = currentRedrawList;
for (i = 0; i < numOfRedrawBox; i++) {
- _engine->_interface->blitBox(currentArea->left, currentArea->top, currentArea->right, currentArea->bottom, (int8 *)_engine->workVideoBuffer, currentArea->left, currentArea->top, (int8 *)_engine->frontVideoBuffer);
+ _engine->_interface->blitBox(currentArea->left, currentArea->top, currentArea->right, currentArea->bottom, (const int8*)_engine->workVideoBuffer.getPixels(), currentArea->left, currentArea->top, (int8*)_engine->frontVideoBuffer.getPixels());
currentArea++;
}
}
@@ -393,7 +394,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
addRedrawArea(_engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, renderRight, renderBottom);
if (actor2->staticFlags.bIsBackgrounded && bgRedraw == 1) {
- _engine->_interface->blitBox(_engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, renderRight, renderBottom, (int8 *)_engine->frontVideoBuffer, _engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, (int8 *)_engine->workVideoBuffer);
+ _engine->_interface->blitBox(_engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, renderRight, renderBottom, (const int8*)_engine->frontVideoBuffer.getPixels(), _engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, (int8*)_engine->workVideoBuffer.getPixels());
}
}
}
@@ -481,7 +482,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
addRedrawArea(_engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, _engine->_interface->textWindowRight, _engine->_interface->textWindowBottom);
if (actor2->staticFlags.bIsBackgrounded && bgRedraw == 1) {
- _engine->_interface->blitBox(_engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, _engine->_interface->textWindowRight, _engine->_interface->textWindowBottom, (int8 *)_engine->frontVideoBuffer, _engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, (int8 *)_engine->workVideoBuffer);
+ _engine->_interface->blitBox(_engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, _engine->_interface->textWindowRight, _engine->_interface->textWindowBottom, (const int8*)_engine->frontVideoBuffer.getPixels(), _engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, (int8*)_engine->workVideoBuffer.getPixels());
}
// show clipping area
@@ -763,25 +764,22 @@ void Redraw::drawBubble(int32 actorIdx) {
}
void Redraw::zoomScreenScale() {
- uint8 *dest;
- uint8 *zoomWorkVideoBuffer = (uint8 *)malloc((SCREEN_WIDTH * SCREEN_HEIGHT) * sizeof(uint8));
- if (!zoomWorkVideoBuffer) {
- error("Failed to allocate memory for the scale buffer");
- }
- memcpy(zoomWorkVideoBuffer, _engine->workVideoBuffer, SCREEN_WIDTH * SCREEN_HEIGHT);
-
- dest = _engine->workVideoBuffer;
-
- for (int h = 0; h < SCREEN_HEIGHT; h++) {
- for (int w = 0; w < SCREEN_WIDTH; w++) {
- *dest++ = *zoomWorkVideoBuffer;
- *dest++ = *zoomWorkVideoBuffer++;
+ Graphics::Surface zoomWorkVideoBuffer;
+ zoomWorkVideoBuffer.copyFrom(_engine->workVideoBuffer);
+
+ // TODO: this is broken
+ const uint8 *src = (const uint8*)zoomWorkVideoBuffer.getPixels();
+ uint8 *dest = (uint8*)_engine->workVideoBuffer.getPixels();
+ for (int h = 0; h < zoomWorkVideoBuffer.h; h++) {
+ for (int w = 0; w < zoomWorkVideoBuffer.w; w++) {
+ *dest++ = *src;
+ *dest++ = *src++;
}
//memcpy(dest, dest - SCREEN_WIDTH, SCREEN_WIDTH);
//dest += SCREEN_WIDTH;
}
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- free(zoomWorkVideoBuffer);
+ zoomWorkVideoBuffer.free();
}
} // namespace TwinE
diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 58bcbf2648..890aa6c32a 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -516,7 +516,7 @@ void Renderer::renderPolygons(int32 renderType, int32 color) {
int16 start, stop;
- out = _engine->frontVideoBuffer + 640 * vtop;
+ out = (uint8*)_engine->frontVideoBuffer.getPixels() + 640 * vtop;
ptr1 = &polyTab[vtop];
ptr2 = &polyTab2[vtop];
diff --git a/engines/twine/screens.cpp b/engines/twine/screens.cpp
index b6d2de4571..34820fd2ed 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/screens.cpp
@@ -21,6 +21,7 @@
*/
#include "common/system.h"
+#include "graphics/surface.h"
#include "twine/screens.h"
#include "twine/hqrdepack.h"
#include "twine/music.h"
@@ -39,7 +40,7 @@ void Screens::adelineLogo() {
}
void Screens::loadMenuImage(bool fade_in) {
- _engine->_hqrdepack->hqrGetEntry(_engine->workVideoBuffer, Resources::HQR_RESS_FILE, RESSHQR_MENUIMG);
+ _engine->_hqrdepack->hqrGetEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, RESSHQR_MENUIMG);
copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
if (fade_in) {
fadeToPal(paletteRGB);
@@ -60,7 +61,7 @@ void Screens::copyPal(const uint8* in, uint8* out) {
}
void Screens::loadImage(int32 index, bool fade_in) {
- _engine->_hqrdepack->hqrGetEntry(_engine->workVideoBuffer, Resources::HQR_RESS_FILE, index);
+ _engine->_hqrdepack->hqrGetEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, index);
copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
loadCustomPalette(index + 1);
if (fade_in) {
@@ -247,8 +248,12 @@ void Screens::copyScreen(const uint8 *source, uint8 *destination) {
}
}
+void Screens::copyScreen(const Graphics::Surface& source, Graphics::Surface &destination) {
+ copyScreen((const uint8 *)source.getPixels(), (uint8 *)destination.getPixels());
+}
+
void Screens::clearScreen() {
- memset(_engine->frontVideoBuffer, 0, SCREEN_WIDTH * SCREEN_HEIGHT);
+ memset(_engine->frontVideoBuffer.getPixels(), 0, SCREEN_WIDTH * SCREEN_HEIGHT);
}
} // namespace TwinE
diff --git a/engines/twine/screens.h b/engines/twine/screens.h
index 0d6f91c24b..c860a00c22 100644
--- a/engines/twine/screens.h
+++ b/engines/twine/screens.h
@@ -24,6 +24,7 @@
#define TWINE_SCREENS_H
#include "common/scummsys.h"
+#include "graphics/surface.h"
#include "twine/twine.h"
namespace TwinE {
@@ -37,13 +38,13 @@ public:
Screens(TwinEEngine *engine) : _engine(engine) {}
/** In-game palette (should not be used, except in special case. otherwise use other images functions instead) */
- uint8 palette[NUMOFCOLORS * 3] {0};
+ uint8 palette[NUMOFCOLORS * 3]{0};
/** converted in-game palette */
- uint8 paletteRGB[NUMOFCOLORS * 3] {0};
+ uint8 paletteRGB[NUMOFCOLORS * 3]{0};
/** converted custom palette */
- uint8 paletteRGBCustom[NUMOFCOLORS * 3] {0};
+ uint8 paletteRGBCustom[NUMOFCOLORS * 3]{0};
/** flag to check if a custom palette is in use */
int16 palCustom = 0;
@@ -61,12 +62,12 @@ public:
uint8 *mainPalette = nullptr;
/** converted in-game palette */
- uint8 mainPaletteRGB[NUMOFCOLORS * 3] {0};
+ uint8 mainPaletteRGB[NUMOFCOLORS * 3]{0};
/** Load and display Adeline Logo */
void adelineLogo();
- void copyPal(const uint8* in, uint8* out);
+ void copyPal(const uint8 *in, uint8 *out);
/**
* Load a custom palette
@@ -136,8 +137,10 @@ public:
*/
void fadeToBlack(uint8 *palette);
- /** Fade image with another palette source
- @param palette current palette to fade */
+ /**
+ * Fade image with another palette source
+ * @param palette current palette to fade
+ */
void fadeToPal(uint8 *palette);
/** Fade black palette to white palette */
@@ -146,18 +149,25 @@ public:
/** Resets both in-game and sdl palettes */
void setBackPal();
- /** Fade palette to red palette
- @param palette current palette to fade */
+ /**
+ * Fade palette to red palette
+ * @param palette current palette to fade
+ */
void fadePalRed(uint8 *palette);
- /** Fade red to palette
- @param palette current palette to fade */
+ /**
+ * Fade red to palette
+ * @param palette current palette to fade
+ */
void fadeRedPal(uint8 *palette);
- /** Copy a determinate screen buffer to another
- @param source screen buffer
- @param destination screen buffer */
+ /**
+ * Copy a determinate screen buffer to another
+ * @param source screen buffer
+ * @param destination screen buffer
+ */
void copyScreen(const uint8 *source, uint8 *destination);
+ void copyScreen(const Graphics::Surface &source, Graphics::Surface &destination);
/** Clear front buffer screen */
void clearScreen();
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 4dea8faa97..08eb568b16 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -181,7 +181,7 @@ void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
usedColor = dialTextColor;
- screen2 = _engine->frontVideoBuffer + _engine->screenLookupTable[y] + x;
+ screen2 = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[y] + x;
tempX = x;
tempY = y;
@@ -206,8 +206,9 @@ void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
} else {
number = *(data++);
for (i = 0; i < number; i++) {
- if (tempX >= SCREEN_TEXTLIMIT_LEFT && tempX < SCREEN_TEXTLIMIT_RIGHT && tempY >= SCREEN_TEXTLIMIT_TOP && tempY < SCREEN_TEXTLIMIT_BOTTOM)
- _engine->frontVideoBuffer[SCREEN_WIDTH * tempY + tempX] = usedColor;
+ if (tempX >= SCREEN_TEXTLIMIT_LEFT && tempX < SCREEN_TEXTLIMIT_RIGHT && tempY >= SCREEN_TEXTLIMIT_TOP && tempY < SCREEN_TEXTLIMIT_BOTTOM) {
+ *((uint8*)_engine->frontVideoBuffer.getBasePtr(tempX, tempY)) = usedColor;
+ }
screen2++;
tempX++;
@@ -298,7 +299,7 @@ int32 Text::getTextSize(const char *dialogue) { // SizeFont
}
void Text::initDialogueBox() { // InitDialWindow
- _engine->_interface->blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (int8 *)_engine->workVideoBuffer, dialTextBoxLeft, dialTextBoxTop, (int8 *)_engine->frontVideoBuffer);
+ _engine->_interface->blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (const int8 *)_engine->workVideoBuffer.getPixels(), dialTextBoxLeft, dialTextBoxTop, (int8 *)_engine->frontVideoBuffer.getPixels());
if (newGameVar4 != 0) {
_engine->_menu->drawBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom);
@@ -307,11 +308,11 @@ void Text::initDialogueBox() { // InitDialWindow
_engine->copyBlockPhys(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom);
printText8Var3 = 0;
- _engine->_interface->blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (int8 *)_engine->frontVideoBuffer, dialTextBoxLeft, dialTextBoxTop, (int8 *)_engine->workVideoBuffer);
+ _engine->_interface->blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (const int8 *)_engine->frontVideoBuffer.getPixels(), dialTextBoxLeft, dialTextBoxTop, (int8 *)_engine->workVideoBuffer.getPixels());
}
void Text::initInventoryDialogueBox() { // SecondInitDialWindow
- _engine->_interface->blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (int8 *)_engine->workVideoBuffer, dialTextBoxLeft, dialTextBoxTop, (int8 *)_engine->frontVideoBuffer);
+ _engine->_interface->blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (const int8 *)_engine->workVideoBuffer.getPixels(), dialTextBoxLeft, dialTextBoxTop, (int8 *)_engine->frontVideoBuffer.getPixels());
_engine->copyBlockPhys(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom);
printText8Var3 = 0;
}
@@ -546,7 +547,7 @@ int Text::printText10() {
return 0;
}
if (printText8Var6 != 0) {
- _engine->_interface->blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (int8 *)_engine->workVideoBuffer, dialTextBoxLeft, dialTextBoxTop, (int8 *)_engine->frontVideoBuffer);
+ _engine->_interface->blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (const int8 *)_engine->workVideoBuffer.getPixels(), dialTextBoxLeft, dialTextBoxTop, (int8 *)_engine->frontVideoBuffer.getPixels());
_engine->copyBlockPhys(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom);
printText8Var3 = 0;
printText8Var6 = 0;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 138ff3682f..81c09079c2 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -31,6 +31,7 @@
#include "common/textconsole.h"
#include "engines/util.h"
#include "graphics/palette.h"
+#include "graphics/surface.h"
#include "gui/debugger.h"
#include "twine/actor.h"
#include "twine/animations.h"
@@ -138,9 +139,9 @@ bool TwinEEngine::hasFeature(EngineFeature f) const {
}
void TwinEEngine::allocVideoMemory() {
- const size_t videoBufferSize = (SCREEN_WIDTH * SCREEN_HEIGHT) * sizeof(uint8);
- workVideoBuffer = (uint8 *)malloc(videoBufferSize);
- frontVideoBuffer = (uint8 *)malloc(videoBufferSize);
+ const Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
+ workVideoBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, format);
+ frontVideoBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, format);
int32 j = 0;
int32 k = 0;
@@ -803,21 +804,26 @@ void TwinEEngine::fadeBlackToWhite() {
}
void TwinEEngine::flip() {
- g_system->copyRectToScreen(frontVideoBuffer, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ g_system->copyRectToScreen(frontVideoBuffer.getPixels(), frontVideoBuffer.pitch, 0, 0, frontVideoBuffer.w, frontVideoBuffer.h);
g_system->updateScreen();
}
void TwinEEngine::copyBlockPhys(int32 left, int32 top, int32 right, int32 bottom) {
- g_system->copyRectToScreen(frontVideoBuffer, SCREEN_WIDTH, left, top, right - left + 1, bottom - top + 1);
+ // TODO: fix this
+ //g_system->copyRectToScreen(frontVideoBuffer, SCREEN_WIDTH, left, top, right - left + 1, bottom - top + 1);
g_system->updateScreen();
}
-void TwinEEngine::crossFade(uint8 *buffer, uint8 *palette) {
+void TwinEEngine::crossFade(const uint8 *buffer, uint8 *palette) {
// TODO: implement cross fading
g_system->copyRectToScreen(buffer, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
g_system->updateScreen();
}
+void TwinEEngine::crossFade(const Graphics::Surface &buffer, uint8 *palette) {
+ crossFade((const uint8*)buffer.getPixels(), palette);
+}
+
void TwinEEngine::toggleFullscreen() {
_redraw->reqBgRedraw = 1;
_system->setFeatureState(OSystem::kFeatureFullscreenMode, cfgfile.FullScreen);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 478af023a8..d5606445b5 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -218,9 +218,9 @@ public:
int16 rightMouse = 0;
/** Work video buffer */
- uint8 *workVideoBuffer = nullptr;
+ Graphics::Surface workVideoBuffer;
/** Main game video buffer */
- uint8 *frontVideoBuffer = nullptr;
+ Graphics::Surface frontVideoBuffer;
/** temporary screen table */
int32 screenLookupTable[2000]{0};
@@ -280,7 +280,8 @@ public:
* @param buffer screen buffer
* @param palette new palette to cross fade
*/
- void crossFade(uint8 *buffer, uint8 *palette);
+ void crossFade(const uint8 *buffer, uint8 *palette);
+ void crossFade(const Graphics::Surface &buffer, uint8 *palette);
/** Switch between window and fullscreen modes */
void toggleFullscreen();
Commit: 3afcbb8f3564d847c389e21608e7fbfa808e5891
https://github.com/scummvm/scummvm/commit/3afcbb8f3564d847c389e21608e7fbfa808e5891
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: removed raw buffer crossFade method
Changed paths:
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 81c09079c2..5345778204 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -810,20 +810,16 @@ void TwinEEngine::flip() {
void TwinEEngine::copyBlockPhys(int32 left, int32 top, int32 right, int32 bottom) {
// TODO: fix this
- //g_system->copyRectToScreen(frontVideoBuffer, SCREEN_WIDTH, left, top, right - left + 1, bottom - top + 1);
+ g_system->copyRectToScreen(frontVideoBuffer.getPixels(), frontVideoBuffer.pitch, left, top, right - left + 1, bottom - top + 1);
g_system->updateScreen();
}
-void TwinEEngine::crossFade(const uint8 *buffer, uint8 *palette) {
+void TwinEEngine::crossFade(const Graphics::Surface &buffer, uint8 *palette) {
// TODO: implement cross fading
- g_system->copyRectToScreen(buffer, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ g_system->copyRectToScreen(buffer.getPixels(), buffer.pitch, 0, 0, buffer.w, buffer.h);
g_system->updateScreen();
}
-void TwinEEngine::crossFade(const Graphics::Surface &buffer, uint8 *palette) {
- crossFade((const uint8*)buffer.getPixels(), palette);
-}
-
void TwinEEngine::toggleFullscreen() {
_redraw->reqBgRedraw = 1;
_system->setFeatureState(OSystem::kFeatureFullscreenMode, cfgfile.FullScreen);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index d5606445b5..e72c276b6b 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -280,7 +280,6 @@ public:
* @param buffer screen buffer
* @param palette new palette to cross fade
*/
- void crossFade(const uint8 *buffer, uint8 *palette);
void crossFade(const Graphics::Surface &buffer, uint8 *palette);
/** Switch between window and fullscreen modes */
Commit: 859957cbee9c3bc3466ded921319b783cd4819e2
https://github.com/scummvm/scummvm/commit/859957cbee9c3bc3466ded921319b783cd4819e2
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: reduced scope and cleanup
Changed paths:
engines/twine/text.cpp
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 08eb568b16..9a8fdcc48d 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -402,20 +402,16 @@ Text::WordSize Text::getWordSize(const char *arg1, char *arg2) {
}
void Text::processTextLine() {
- int16 var4;
- char *buffer;
- char *temp;
-
- buffer = printText8Var8;
+ char *buffer = printText8Var8;
dialCharSpace = 7;
- var4 = 1;
+ int16 var4 = 1;
addLineBreakX = 0;
printText8PrepareBufferVar2 = 0;
buf2[0] = 0;
for (;;) {
- if (*buffer == 0x20) {
+ if (*buffer == ' ') {
buffer++;
continue;
}
@@ -424,7 +420,7 @@ void Text::processTextLine() {
printText8Var8 = buffer;
WordSize wordSize = getWordSize(buffer, buf1);
if (addLineBreakX + dialCharSpace + wordSize.inPixel < dialTextBoxParam2) {
- temp = buffer + 1;
+ char *temp = buffer + 1;
if (*buffer == 1) {
var4 = 0;
buffer = temp;
@@ -462,7 +458,7 @@ void Text::processTextLine() {
if (printText8PrepareBufferVar2 != 0)
printText8PrepareBufferVar2--;
- if (*printText8Var8 != 0 && var4 == 1) {
+ if (*printText8Var8 != '\0' && var4 == 1) {
dialCharSpace += (dialTextBoxParam2 - addLineBreakX) / printText8PrepareBufferVar2;
printText10Var1 = dialTextBoxParam2 - addLineBreakX - dialTextBoxParam2 - addLineBreakX; // stupid... recheck
}
@@ -494,51 +490,38 @@ void Text::printText10Sub() {
}
void Text::printText10Sub2() {
- int32 currentLetter;
- int32 currentIndex;
- int32 counter;
- int32 counter2;
- int16 *ptr;
-
- currentLetter = printText8Var3;
- currentLetter--;
-
- currentIndex = currentLetter * 3;
-
- ptr = pt8s4 + currentIndex;
+ const int32 currentLetter = printText8Var3 - 1;
+ const int32 currentIndex = currentLetter * 3;
+ int16 *ptr = pt8s4 + currentIndex;
+ int32 counter = printText8Var3;
+ int32 fontColor = dialTextStartColor;
_engine->_system->delayMillis(15);
- counter = printText8Var3;
- counter2 = dialTextStartColor;
-
while (--counter >= 0) {
- setFontColor(counter2);
- drawCharacterShadow(*(ptr + 1), *(ptr + 2), (uint8)*ptr, counter2);
- counter2 -= dialTextStepSize;
- if (counter2 > dialTextStopColor)
- counter2 = dialTextStopColor;
+ setFontColor(fontColor);
+ drawCharacterShadow(*(ptr + 1), *(ptr + 2), (uint8)*ptr, fontColor);
+ fontColor -= dialTextStepSize;
+ if (fontColor > dialTextStopColor) {
+ fontColor = dialTextStopColor;
+ }
ptr -= 3;
};
}
void Text::TEXT_GetLetterSize(uint8 character, int32 *pLetterWidth, int32 *pLetterHeight, uint8 *pFont) { // TEXT_GetLetterSize
- uint8 *temp;
-
- temp = (uint8 *)(pFont + *((int16 *)(pFont + character * 4)));
+ uint8 *temp = (uint8 *)(pFont + *((int16 *)(pFont + character * 4)));
*pLetterWidth = *(temp);
*pLetterHeight = *(temp + 1);
}
// TODO: refactor this code
int Text::printText10() {
- int32 charWidth, charHeight; // a, b
-
if (printTextVar13 == 0) {
return 0;
}
- if (*(printText8Ptr2) == 0) {
+ if (*printText8Ptr2 == '\0') {
if (printText8Var5 != 0) {
if (newGameVar5 != 0) {
printText10Sub();
@@ -554,7 +537,7 @@ int Text::printText10() {
TEXT_CurrentLetterX = dialTextBoxLeft + 8;
TEXT_CurrentLetterY = dialTextBoxTop + 8;
}
- if (*(printText8Var8) == 0) {
+ if (*printText8Var8 == '\0') {
initProgressiveTextBuffer();
printText8Var5 = 1;
return 1;
@@ -563,15 +546,17 @@ int Text::printText10() {
}
// RECHECK this later
- if (*(printText8Ptr2) == 0) {
+ if (*printText8Ptr2 == '\0') {
return 1;
}
printText8Sub4(TEXT_CurrentLetterX, TEXT_CurrentLetterY, *printText8Ptr2);
printText10Sub2();
+ int32 charWidth;
+ int32 charHeight;
TEXT_GetLetterSize(*printText8Ptr2, &charWidth, &charHeight, (uint8 *)fontPtr);
- if (*(printText8Ptr2) != 0x20) {
+ if (*printText8Ptr2 != ' ') {
TEXT_CurrentLetterX += charWidth + 2;
} else {
if (printText10Var1 != 0) {
@@ -584,7 +569,7 @@ int Text::printText10() {
// next character
printText8Ptr2++;
- if (*(printText8Ptr2) != 0)
+ if (*printText8Ptr2 != '\0')
return 1;
TEXT_CurrentLetterY += 38;
@@ -603,7 +588,7 @@ int Text::printText10() {
initProgressiveTextBuffer();
printText8Var6 = 1;
- if (*(printText8Var8) == 0) {
+ if (*printText8Var8 == '\0') {
printText8Var5 = 1;
}
@@ -777,8 +762,9 @@ bool Text::getText(int32 index) { // findString
// choose right text from order index
do {
orderIdx = *(localOrderBuf++);
- if (orderIdx == index)
+ if (orderIdx == index) {
break;
+ }
currIdx++;
} while (currIdx < numDialTextEntries);
@@ -801,8 +787,9 @@ bool Text::getText(int32 index) { // findString
void Text::copyText(const char *src, char *dst, int32 size) { // copyStringToString
int32 i;
- for (i = 0; i < size; i++)
+ for (i = 0; i < size; i++) {
*(dst++) = *(src++);
+ }
}
void Text::getMenuText(int32 index, char *text, uint32 textSize) { // GetMultiText
Commit: 7e04efc533aa6f8e6718ea2d98f1b93e5689e3bb
https://github.com/scummvm/scummvm/commit/7e04efc533aa6f8e6718ea2d98f1b93e5689e3bb
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: converted c artifacts to c++
Changed paths:
engines/twine/actor.h
engines/twine/animations.cpp
engines/twine/debug.cpp
engines/twine/debug.h
engines/twine/extra.h
engines/twine/flamovies.h
engines/twine/grid.h
engines/twine/movements.cpp
engines/twine/redraw.h
engines/twine/renderer.h
engines/twine/scene.h
engines/twine/script_life.cpp
engines/twine/script_move.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/actor.h b/engines/twine/actor.h
index 6b4a1aae31..f849f25995 100644
--- a/engines/twine/actor.h
+++ b/engines/twine/actor.h
@@ -52,31 +52,31 @@ enum HeroBehaviourType {
};
/** Actors move structure */
-typedef struct ActorMoveStruct {
+struct ActorMoveStruct {
int16 from = 0;
int16 to = 0;
int16 numOfStep = 0;
int32 timeOfChange = 0;
-} ActorMoveStruct;
+};
/** Actors zone volumique points structure */
-typedef struct ZVPoint {
+struct ZVPoint {
int16 bottomLeft = 0;
int16 topRight = 0;
-} ZVPoint;
+};
/** Actors zone volumique box structure */
-typedef struct ZVBox {
+struct ZVBox {
ZVPoint x;
ZVPoint y;
ZVPoint z;
-} ZVBox;
+};
/** Actors animation timer structure */
-typedef struct AnimTimerDataStruct {
+struct AnimTimerDataStruct {
uint8 *ptr = nullptr;
int32 time = 0;
-} AnimTimerDataStruct;
+};
enum AnimationTypes {
kAnimNone = -1,
@@ -108,7 +108,7 @@ enum AnimationTypes {
};
/** Actors static flags structure */
-typedef struct StaticFlagsStruct {
+struct StaticFlagsStruct {
uint16 bComputeCollisionWithObj : 1; // 0x0001
uint16 bComputeCollisionWithBricks : 1; // 0x0002
uint16 bIsZonable : 1; // 0x0004
@@ -125,10 +125,10 @@ typedef struct StaticFlagsStruct {
uint16 bIsBackgrounded : 1; // 0x2000
uint16 bIsCarrierActor : 1; // 0x4000
uint16 bUseMiniZv : 1; // 0x8000
-} StaticFlagsStruct;
+};
/** Actors dynamic flags structure */
-typedef struct DynamicFlagsStruct {
+struct DynamicFlagsStruct {
uint16 bWaitHitFrame : 1; // 0x0001 wait for hit frame
uint16 bIsHitting : 1; // 0x0002 hit frame anim
uint16 bAnimEnded : 1; // 0x0004 anim ended in the current loop (will be looped in the next engine loop)
@@ -145,10 +145,10 @@ typedef struct DynamicFlagsStruct {
uint16 bUnk2000 : 1; // 0x2000 unused
uint16 bUnk4000 : 1; // 0x4000 unused
uint16 bUnk8000 : 1; // 0x8000 unused
-} DynamicFlagsStruct;
+};
/** Actors structure */
-typedef struct ActorStruct {
+struct ActorStruct {
StaticFlagsStruct staticFlags;
DynamicFlagsStruct dynamicFlags;
@@ -213,7 +213,7 @@ typedef struct ActorStruct {
ZVBox boudingBox;
ActorMoveStruct move;
AnimTimerDataStruct animTimerData;
-} ActorStruct;
+};
class TwinEEngine;
diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 73d878bdfc..f7221223a0 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -505,10 +505,9 @@ int32 Animations::verifyAnimAtKeyframe(int32 animIdx, uint8 *animPtr, uint8 *bod
return 0;
}
-struct _DataReader {
+struct DataReader {
uint8 *ptr;
};
-typedef struct _DataReader DataReader;
int8 readByte(DataReader *data) {
return *(data->ptr++);
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 188a34236e..26e8b31c76 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -450,7 +450,7 @@ void Debug::debugProcessWindow() {
if (mouseData.left) {
int type = 0;
- if ((type = debugProcessButton(mouseData.X, mouseData.Y)) != NO_ACTION) { // process menu item
+ if ((type = debugProcessButton(mouseData.x, mouseData.y)) != NO_ACTION) { // process menu item
if (debugTypeUseMenu(type)) {
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
_engine->copyBlockPhys(205, 55, 634, 474);
diff --git a/engines/twine/debug.h b/engines/twine/debug.h
index 0e9f06c6de..1ae44a7f36 100644
--- a/engines/twine/debug.h
+++ b/engines/twine/debug.h
@@ -49,7 +49,7 @@ enum WindowType {
ZONES_MENU
};
-typedef struct DebugButtonStruct {
+struct DebugButtonStruct {
int32 left = 0;
int32 top = 0;
int32 right = 0;
@@ -62,9 +62,9 @@ typedef struct DebugButtonStruct {
int32 activeColor = 0;
int32 submenu = 0;
int32 type = 0;
-} DebugButtonStruct;
+};
-typedef struct DebugWindowStruct {
+struct DebugWindowStruct {
int32 left = 0;
int32 top = 0;
int32 right = 0;
@@ -75,7 +75,7 @@ typedef struct DebugWindowStruct {
const char *text[20] {0};
int32 numButtons = 0;
DebugButtonStruct debugButtons[50];
-} DebugWindowStruct;
+};
class TwinEEngine;
diff --git a/engines/twine/extra.h b/engines/twine/extra.h
index 8e122cf2e1..259e615e4c 100644
--- a/engines/twine/extra.h
+++ b/engines/twine/extra.h
@@ -30,7 +30,7 @@ namespace TwinE {
#define EXTRA_MAX_ENTRIES 50
-typedef struct ExtraListStruct {
+struct ExtraListStruct {
int16 info0 = 0; // field_0
int16 x = 0;
int16 y = 0;
@@ -51,7 +51,7 @@ typedef struct ExtraListStruct {
int16 actorIdx = 0; // field_ 1C
int16 strengthOfHit = 0; // field_1E
int16 info1 = 0; // field_20
-} ExtraListStruct;
+};
enum ExtraSpecialType {
kHitStars = 0,
diff --git a/engines/twine/flamovies.h b/engines/twine/flamovies.h
index c87b1bb804..e877430e4c 100644
--- a/engines/twine/flamovies.h
+++ b/engines/twine/flamovies.h
@@ -36,7 +36,7 @@ namespace TwinE {
#define FLASCREEN_HEIGHT 200
/** FLA movie header structure */
-typedef struct FLAHeaderStruct {
+struct FLAHeaderStruct {
/** FLA version */
int8 version[6] {0};
/** Number of frames */
@@ -49,20 +49,20 @@ typedef struct FLAHeaderStruct {
int16 xsize = 0;
/** Frame height */
int16 ysize = 0;
-} FLAHeaderStruct;
+};
/** FLA movie frame structure */
-typedef struct FLAFrameDataStruct {
+struct FLAFrameDataStruct {
/** Current frame size */
int8 videoSize = 0;
/** Dummy variable */
int8 dummy = 0;
/** Unknown frameVar0 */
int32 frameVar0 = 0;
-} FLAFrameDataStruct;
+};
/** FLA movie sample structure */
-typedef struct FLASampleStruct {
+struct FLASampleStruct {
/** Number os samples */
int16 sampleNum = 0;
/** Sample frequency */
@@ -75,7 +75,7 @@ typedef struct FLASampleStruct {
uint8 x = 0;
/** Unknown y */
uint8 y = 0;
-} FLASampleStruct;
+};
/** FLA Frame Opcode types */
enum FlaFrameOpcode {
diff --git a/engines/twine/grid.h b/engines/twine/grid.h
index b3153d642d..14944e6f8b 100644
--- a/engines/twine/grid.h
+++ b/engines/twine/grid.h
@@ -55,7 +55,7 @@ struct BlockEntry {
uint8 brickBlockIdx = 0;
};
/** Brick entry data */
-typedef struct BrickEntry {
+struct BrickEntry {
/** Brick X position in screen */
int16 x = 0; //z
/** Brick Y position in screen */
@@ -72,7 +72,7 @@ typedef struct BrickEntry {
uint8 shape = 0;
/** Brick sound type */
uint8 sound = 0;
-} BrickEntry;
+};
/** Total number of bricks allowed in the game */
#define NUM_BRICKS 9000
diff --git a/engines/twine/movements.cpp b/engines/twine/movements.cpp
index e61b03063b..169f6c13fe 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/movements.cpp
@@ -352,6 +352,8 @@ void Movements::processActorMovements(int32 actorIdx) {
_engine->_animations->initAnim(kHide, 0, 255, actorIdx);
}
break;
+ case kProtoPack:
+ break;
}
}
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index 78202505d5..3df6b146ac 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -43,7 +43,7 @@ enum OverlayPosType {
};
/** Overlay list structure */
-typedef struct OverlayListStruct {
+struct OverlayListStruct {
int16 type = 0;
int16 info0 = 0; // sprite/3d model entry | number | number range
int16 x = 0;
@@ -51,13 +51,13 @@ typedef struct OverlayListStruct {
int16 info1 = 0; // followed actor | total coins
int16 posType = 0;
int16 lifeTime = 0;
-} OverlayListStruct;
+};
class TwinEEngine;
class Redraw {
private:
TwinEEngine *_engine;
- typedef struct DrawListStruct {
+ struct DrawListStruct {
int16 posValue = 0;
uint16 index = 0; // field_2
uint16 x = 0;
@@ -67,17 +67,17 @@ private:
uint16 field_C = 0;
uint16 field_E = 0;
uint16 field_10 = 0;
- } DrawListStruct;
+ };
/** Draw list array to grab the necessary */
DrawListStruct drawList[150];
- typedef struct RedrawStruct {
+ struct RedrawStruct {
uint16 left = 0;
uint16 top = 0;
uint16 right = 0;
uint16 bottom = 0;
- } RedrawStruct;
+ };
RedrawStruct currentRedrawList[300];
RedrawStruct nextRedrawList[300];
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index adacc2695e..f72c47781b 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -31,19 +31,19 @@ class Renderer {
private:
TwinEEngine *_engine;
- typedef struct renderTabEntry {
+ struct renderTabEntry {
int16 depth = 0;
int16 renderType = 0;
uint8 *dataPtr = nullptr;
- } renderTabEntry;
+ };
- typedef struct pointTab {
+ struct pointTab {
int16 X = 0;
int16 Y = 0;
int16 Z = 0;
- } pointTab;
+ };
- typedef struct elementEntry {
+ struct elementEntry {
int16 firstPoint = 0; // data1
int16 numOfPoints = 0; // data2
int16 basePoint = 0; // data3
@@ -58,40 +58,40 @@ private:
int32 y = 0;
int32 field_20 = 0;
int16 field_24 = 0;
- } elementEntry;
+ };
- typedef struct lineCoordinates {
+ struct lineCoordinates {
int32 data = 0;
int16 x1 = 0;
int16 y1 = 0;
int16 x2 = 0;
int16 y2 = 0;
- } lineCoordinates;
+ };
- typedef struct lineData {
+ struct lineData {
int32 data = 0;
int16 p1 = 0;
int16 p2 = 0;
- } lineData;
+ };
- typedef struct polyHeader {
+ struct polyHeader {
uint8 renderType = 0; //FillVertic_AType
uint8 numOfVertex = 0;
int16 colorIndex = 0;
- } polyHeader;
+ };
- typedef struct polyVertexHeader {
+ struct polyVertexHeader {
int16 shadeEntry = 0;
int16 dataOffset = 0;
- } polyVertexHeader;
+ };
- typedef struct computedVertex {
+ struct computedVertex {
int16 shadeValue = 0;
int16 x = 0;
int16 y = 0;
- } computedVertex;
+ };
- typedef struct bodyHeaderStruct {
+ struct bodyHeaderStruct {
int16 bodyFlag = 0;
int16 unk0 = 0;
int16 unk1 = 0;
@@ -102,21 +102,21 @@ private:
int16 offsetToData = 0;
int8 *ptrToKeyFrame = nullptr;
int32 keyFrameTime = 0;
- } bodyHeaderStruct;
+ };
- typedef struct vertexData {
+ struct vertexData {
uint8 param = 0;
int16 x = 0;
int16 y = 0;
- } vertexData;
+ };
- typedef union packed16 {
+ union packed16 {
struct {
uint8 al = 0;
uint8 ah = 0;
} bit;
uint16 temp = 0;
- } packed16;
+ };
int32 renderAnimatedModel(uint8 *bodyPtr);
void circleFill(int32 x, int32 y, int32 radius, int8 color);
diff --git a/engines/twine/scene.h b/engines/twine/scene.h
index a29d3ba293..f285b96f2f 100644
--- a/engines/twine/scene.h
+++ b/engines/twine/scene.h
@@ -46,13 +46,13 @@ enum ScenePositionType {
// ZONES
-typedef struct ScenePoint {
+struct ScenePoint {
int16 x = 0;
int16 y = 0;
int16 z = 0;
-} ScenePoint;
+};
-typedef struct ZoneStruct {
+struct ZoneStruct {
ScenePoint bottomLeft;
ScenePoint topRight;
int16 type = 0;
@@ -87,7 +87,7 @@ typedef struct ZoneStruct {
} generic;
} infoData;
int16 snap = 0;
-} ZoneStruct;
+};
enum ZoneType {
kCube = 0, // Change to another scene
diff --git a/engines/twine/script_life.cpp b/engines/twine/script_life.cpp
index 073f1e55ac..c05592d939 100644
--- a/engines/twine/script_life.cpp
+++ b/engines/twine/script_life.cpp
@@ -54,10 +54,10 @@ static char textStr[256]; // string
1 - Break script */
typedef int32 ScriptLifeFunc(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor);
-typedef struct ScriptLifeFunction {
+struct ScriptLifeFunction {
const char *name;
ScriptLifeFunc *function;
-} ScriptLifeFunction;
+};
#define MAPFUNC(name, func) \
{ name, func }
diff --git a/engines/twine/script_move.cpp b/engines/twine/script_move.cpp
index 5f9266714e..61e7421327 100644
--- a/engines/twine/script_move.cpp
+++ b/engines/twine/script_move.cpp
@@ -42,10 +42,10 @@ static int32 numRepeatSample = 1;
typedef int32 ScriptMoveFunc(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor);
-typedef struct ScriptMoveFunction {
+struct ScriptMoveFunction {
const char *name;
ScriptMoveFunc *function;
-} ScriptMoveFunction;
+};
#define MAPFUNC(name, func) \
{ name, func }
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 5345778204..87cf893287 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -1145,8 +1145,8 @@ void TwinEEngine::drawText(int32 x, int32 y, const char *string, int32 center) {
void TwinEEngine::getMousePositions(MouseStatusStruct *mouseData) {
Common::Point point = g_system->getEventManager()->getMousePos();
- mouseData->X = point.x;
- mouseData->Y = point.y;
+ mouseData->x = point.x;
+ mouseData->y = point.y;
mouseData->left = leftMouse;
mouseData->right = rightMouse;
leftMouse = 0;
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index e72c276b6b..e39ac6083e 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -72,7 +72,7 @@ static const struct TwinELanguage {
Used in the engine to load/use certain parts of code according with
this settings. Check \a lba.cfg file for valid values for each settings.\n
All the settings with (*) means they are new and only exist in this engine. */
-typedef struct ConfigFile {
+struct ConfigFile {
/** Index into the LanguageTypes array. */
int32 LanguageId = 0;
/** Index into the LanguageTypes array. */
@@ -109,14 +109,14 @@ typedef struct ConfigFile {
int32 SceZoom = 0;
/** Flag to toggle Wall Collision */
int32 WallCollision = 0;
-} ConfigFile;
+};
-typedef struct MouseStatusStruct {
+struct MouseStatusStruct {
int32 left = 0;
int32 right = 0;
- int32 X = 0;
- int32 Y = 0;
-} MouseStatusStruct;
+ int32 x = 0;
+ int32 y = 0;
+};
class Actor;
class Animations;
Commit: 4026b23d7cdf7ddb64e8c169a65c7818b248b042
https://github.com/scummvm/scummvm/commit/4026b23d7cdf7ddb64e8c169a65c7818b248b042
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: merged version 0.2.2 of twine develop branch
Changed paths:
engines/twine/flamovies.cpp
engines/twine/gamestate.cpp
engines/twine/holomap.cpp
engines/twine/holomap.h
engines/twine/resources.h
engines/twine/twine.cpp
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index b03c456ad6..ca013b1f97 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -213,7 +213,7 @@ void FlaMovies::processFrame() {
break;
}
default: {
- return;
+ break;
}
}
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 169a08e132..b89aa8572a 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -51,7 +51,7 @@ namespace TwinE {
GameState::GameState(TwinEEngine *engine) : _engine(engine) {}
-void GameState::initEngineProjections() { // reinitAll1
+void GameState::initEngineProjections() {
_engine->_renderer->setOrthoProjection(311, 240, 512);
_engine->_renderer->setBaseTranslation(0, 0, 0);
_engine->_renderer->setBaseRotation(0, 0, 0);
@@ -105,7 +105,7 @@ void GameState::initSceneVars() {
_engine->_actor->currentPositionInBodyPtrTab = 0;
}
-void GameState::initHeroVars() { // reinitAll3
+void GameState::initHeroVars() {
_engine->_actor->resetActor(0); // reset Hero
magicBallIdx = -1;
@@ -123,7 +123,7 @@ void GameState::initHeroVars() { // reinitAll3
_engine->_scene->sceneHero->talkColor = 4;
}
-void GameState::initEngineVars() { // reinitAll
+void GameState::initEngineVars() {
_engine->_interface->resetClip();
_engine->_scene->alphaLight = 896;
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index f701e4248b..c2c3961af4 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -22,21 +22,139 @@
#include "twine/holomap.h"
#include "twine/gamestate.h"
+#include "twine/interface.h"
+#include "twine/renderer.h"
+#include "twine/resources.h"
+#include "twine/scene.h"
+#include "twine/screens.h"
+#include "twine/sound.h"
+#include "twine/text.h"
#include "twine/twine.h"
namespace TwinE {
Holomap::Holomap(TwinEEngine *engine) : _engine(engine) {}
-void Holomap::setHolomapPosition(int32 location) {
- assert(location >= 0 && location <= ARRAYSIZE(_engine->_gameState->holomapFlags));
- _engine->_gameState->holomapFlags[location] = 0x81;
+void Holomap::setHolomapPosition(int32 locationIdx) {
+ assert(locationIdx >= 0 && locationIdx <= ARRAYSIZE(_engine->_gameState->holomapFlags));
+ _engine->_gameState->holomapFlags[locationIdx] = 0x81;
}
-void Holomap::clearHolomapPosition(int32 location) {
- assert(location >= 0 && location <= ARRAYSIZE(_engine->_gameState->holomapFlags));
- _engine->_gameState->holomapFlags[location] &= 0x7E;
- _engine->_gameState->holomapFlags[location] |= 0x40;
+void Holomap::clearHolomapPosition(int32 locationIdx) {
+ assert(locationIdx >= 0 && locationIdx <= ARRAYSIZE(_engine->_gameState->holomapFlags));
+ _engine->_gameState->holomapFlags[locationIdx] &= 0x7E;
+ _engine->_gameState->holomapFlags[locationIdx] |= 0x40;
+}
+
+void Holomap::loadGfxSub(uint8 *modelPtr) {
+ // TODO
+}
+
+void Holomap::loadGfxSub1() {
+ // TODO
+}
+
+void Holomap::loadGfxSub2() {
+ // TODO
+}
+
+void Holomap::loadHolomapGFX() {
+ videoPtr1 = (uint8 *)_engine->workVideoBuffer.getPixels();
+ videoPtr2 = videoPtr1 + 4488;
+ videoPtr3 = videoPtr1 + 7854;
+ videoPtr4 = videoPtr1 + 8398;
+
+ videoPtr5 = videoPtr1 + 73934;
+
+ _engine->_hqrdepack->hqrGetEntry(videoPtr3, Resources::HQR_RESS_FILE, RESSHQR_HOLOSURFACE);
+ _engine->_hqrdepack->hqrGetEntry(videoPtr4, Resources::HQR_RESS_FILE, RESSHQR_HOLOIMG);
+
+ videoPtr6 = videoPtr5 + _engine->_hqrdepack->hqrGetEntry(videoPtr5, Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINMDL);
+ videoPtr7 = videoPtr6 + _engine->_hqrdepack->hqrGetEntry(videoPtr6, Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWMDL);
+ videoPtr8 = videoPtr7 + _engine->_hqrdepack->hqrGetEntry(videoPtr7, Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINARROWMDL);
+ videoPtr11 = videoPtr8 + _engine->_hqrdepack->hqrGetEntry(videoPtr8, Resources::HQR_RESS_FILE, RESSHQR_HOLOPOINTMDL);
+
+ loadGfxSub(videoPtr5);
+ loadGfxSub(videoPtr6);
+ loadGfxSub(videoPtr7);
+
+ loadGfxSub(videoPtr8);
+
+ videoPtr10 = videoPtr11 + 4488;
+ videoPtr12 = videoPtr10 + _engine->_hqrdepack->hqrGetEntry(videoPtr10, Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWINFO);
+ videoPtr13 = videoPtr12 + _engine->_hqrdepack->hqrGetEntry(videoPtr12, Resources::HQR_RESS_FILE, RESSHQR_HOLOPOINTANIM);
+
+ _engine->_screens->loadCustomPalette(RESSHQR_HOLOPAL);
+
+ int32 j = 576;
+ for (int32 i = 0; i < 96; i += 3, j += 3) {
+ paletteHolomap[i] = _engine->_screens->palette[j];
+ paletteHolomap[i + 1] = _engine->_screens->palette[j + 1];
+ paletteHolomap[i + 2] = _engine->_screens->palette[j + 2];
+ }
+
+ j = 576;
+ for (int32 i = 96; i < 189; i += 3, j += 3) {
+ paletteHolomap[i] = _engine->_screens->palette[j];
+ paletteHolomap[i + 1] = _engine->_screens->palette[j + 1];
+ paletteHolomap[i + 2] = _engine->_screens->palette[j + 2];
+ }
+
+ loadGfxSub1();
+ loadGfxSub2();
+
+ needToLoadHolomapGFX = 0;
+}
+
+void Holomap::drawHolomapTitle(int32 width, int32 height) {
+ // TODO
+}
+
+void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
+ // TODO
+}
+
+void Holomap::processHolomap() {
+ int32 alphaLightTmp;
+ int32 betaLightTmp;
+
+ _engine->freezeTime();
+
+ // TODO memcopy palette
+
+ alphaLightTmp = _engine->_scene->alphaLight;
+ betaLightTmp = _engine->_scene->betaLight;
+
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGB);
+ _engine->_sound->stopSamples();
+ _engine->_interface->resetClip();
+ _engine->_screens->clearScreen();
+ _engine->flip();
+ _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
+
+ loadHolomapGFX();
+ drawHolomapTitle(320, 25);
+ _engine->_renderer->setCameraPosition(320, 190, 128, 1024, 1024);
+
+ const int32 tmpLanguageCDId = _engine->cfgfile.LanguageCDId;
+ _engine->cfgfile.LanguageCDId = 0;
+ _engine->_text->initTextBank(2);
+ _engine->_text->setFontCrossColor(9);
+
+ // TODO
+
+ _engine->_text->newGameVar4 = 1;
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGB);
+ _engine->_scene->alphaLight = alphaLightTmp;
+ _engine->_scene->betaLight = betaLightTmp;
+ _engine->_gameState->initEngineVars();
+
+ _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+
+ // TODO memcopy reset palette
+
+ _engine->cfgfile.LanguageCDId = tmpLanguageCDId;
+ _engine->unfreezeTime();
}
} // namespace TwinE
diff --git a/engines/twine/holomap.h b/engines/twine/holomap.h
index c36f96738f..1c06f3e189 100644
--- a/engines/twine/holomap.h
+++ b/engines/twine/holomap.h
@@ -24,6 +24,7 @@
#define TWINE_HOLOMAP_H
#include "common/scummsys.h"
+#include "twine/twine.h"
namespace TwinE {
@@ -32,16 +33,54 @@ class TwinEEngine;
class Holomap {
private:
TwinEEngine *_engine;
+
+ int32 needToLoadHolomapGFX = 0;
+ uint8 paletteHolomap[NUMOFCOLORS * 3]{0};
+
+ uint8 *videoPtr1 = nullptr;
+ uint8 *videoPtr2 = nullptr;
+ uint8 *videoPtr3 = nullptr;
+ uint8 *videoPtr4 = nullptr;
+ uint8 *videoPtr5 = nullptr;
+ uint8 *videoPtr6 = nullptr;
+ uint8 *videoPtr7 = nullptr;
+ uint8 *videoPtr8 = nullptr;
+ uint8 *videoPtr9 = nullptr;
+ uint8 *videoPtr10 = nullptr;
+ uint8 *videoPtr11 = nullptr;
+ uint8 *videoPtr12 = nullptr;
+ uint8 *videoPtr13 = nullptr;
+
public:
Holomap(TwinEEngine *engine);
- /** Set Holomap location position
- @location Scene where position must be set */
- void setHolomapPosition(int32 location);
+ /**
+ * Set Holomap location position
+ * @param locationIdx Scene where position must be set
+ */
+ void setHolomapPosition(int32 locationIdx);
+
+ /**
+ * Clear Holomap location position
+ * @param locationIdx Scene where position must be cleared
+ */
+ void clearHolomapPosition(int32 locationIdx);
+
+ /** Draw Holomap Title */
+ void drawHolomapTitle(int32 width, int32 height);
+
+ /** Draw Holomap Trajectory */
+ void drawHolomapTrajectory(int32 trajectoryIndex);
+
+ void loadGfxSub(uint8 *modelPtr);
+ void loadGfxSub1();
+ void loadGfxSub2();
+
+ /** Load Holomap content */
+ void loadHolomapGFX();
- /** Clear Holomap location position
- @location Scene where position must be cleared */
- void clearHolomapPosition(int32 location);
+ /** Main holomap process loop */
+ void processHolomap();
};
} // namespace TwinE
diff --git a/engines/twine/resources.h b/engines/twine/resources.h
index 0189aad2a9..3c5f6ae14b 100644
--- a/engines/twine/resources.h
+++ b/engines/twine/resources.h
@@ -59,6 +59,9 @@ namespace TwinE {
#define RESSHQR_ADELINEIMG 27
#define RESSHQR_ADELINEPAL 28
+#define RESSHQR_HOLOPOINTMDL 29
+#define RESSHQR_HOLOPOINTANIM 30
+
#define RESSHQR_LBAIMG 49
#define RESSHQR_LBAPAL 50
#define RESSHQR_PLASMAEFFECT 51
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 87cf893287..455cbc8bbe 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -220,7 +220,7 @@ void TwinEEngine::initEngine() {
initConfigurations();
/** Engine current version */
- const char *ENGINE_VERSION = "0.2.0";
+ const char *ENGINE_VERSION = "0.2.2";
// Show engine information
debug("TwinEngine v%s", ENGINE_VERSION);
@@ -383,7 +383,9 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
switch (loopInventoryItem) {
case kiHolomap:
- warning("Use Inventory [kiHolomap] not implemented!\n");
+ _holomap->processHolomap();
+ _screens->lockPalette = 1;
+ warning("Use inventory [kiHolomap] not implemented!\n");
break;
case kiMagicBall:
if (_gameState->usingSabre == 1) {
@@ -532,7 +534,15 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_redraw->reqBgRedraw = 1;
}
- // TODO: draw holomap
+ // Draw holomap
+ if (loopCurrentKey == 35 && _gameState->gameFlags[InventoryItems::kiHolomap] == 1 && !_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED]) {
+ freezeTime();
+ //TestRestoreModeSVGA(1);
+ _holomap->processHolomap();
+ _screens->lockPalette = 1;
+ unfreezeTime();
+ _redraw->redrawEngineActions(1);
+ }
// Process Pause - Press P
if (loopCurrentKey == Keys::Pause) {
Commit: c3f0c2b1c1601d16e6421b52b9f2bdbc0a5e729c
https://github.com/scummvm/scummvm/commit/c3f0c2b1c1601d16e6421b52b9f2bdbc0a5e729c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: removed unused enum
Changed paths:
engines/twine/detection.h
diff --git a/engines/twine/detection.h b/engines/twine/detection.h
index 03a3cb7609..f76f115396 100644
--- a/engines/twine/detection.h
+++ b/engines/twine/detection.h
@@ -25,10 +25,6 @@
namespace TwinE {
-enum GameFlag {
- kGameFlagDemo = 1 << 0
-};
-
} // End of namespace TwinE
#endif // TWINE_DETECTION_H
Commit: 150266bd4bf82ef712f36e964186d28f42561a8c
https://github.com/scummvm/scummvm/commit/150266bd4bf82ef712f36e964186d28f42561a8c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: refactored the input code to use the KeyMapper
Changed paths:
engines/twine/debug_grid.cpp
engines/twine/keyboard.h
engines/twine/metaengine.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/debug_grid.cpp b/engines/twine/debug_grid.cpp
index 2f8a917d14..8f9f813efe 100644
--- a/engines/twine/debug_grid.cpp
+++ b/engines/twine/debug_grid.cpp
@@ -37,25 +37,25 @@ DebugGrid::DebugGrid(TwinEEngine *engine) : _engine(engine) {
void DebugGrid::changeGridCamera(int16 pKey) {
if (useFreeCamera) {
// Press up - more X positions
- if (pKey == Keys::DebugGridCameraPressUp) {
+ if (pKey == twineactions[TwinEActionType::DebugGridCameraPressUp].localKey) {
_engine->_grid->newCameraZ--;
_engine->_redraw->reqBgRedraw = 1;
}
// Press down - less X positions
- else if (pKey == Keys::DebugGridCameraPressDown) {
+ else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressDown].localKey) {
_engine->_grid->newCameraZ++;
_engine->_redraw->reqBgRedraw = 1;
}
// Press left - less Z positions
- else if (pKey == Keys::DebugGridCameraPressLeft) {
+ else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressLeft].localKey) {
_engine->_grid->newCameraX--;
_engine->_redraw->reqBgRedraw = 1;
}
// Press right - more Z positions
- else if (pKey == Keys::DebugGridCameraPressRight) {
+ else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressRight].localKey) {
_engine->_grid->newCameraX++;
_engine->_redraw->reqBgRedraw = 1;
}
@@ -67,7 +67,7 @@ void DebugGrid::changeGrid(int16 pKey) {
return;
}
// Press up - more X positions
- if (pKey == Keys::NextRoom) {
+ if (pKey == twineactions[TwinEActionType::NextRoom].localKey) {
_engine->_scene->currentSceneIdx++;
if (_engine->_scene->currentSceneIdx > NUM_SCENES)
_engine->_scene->currentSceneIdx = 0;
@@ -76,34 +76,30 @@ void DebugGrid::changeGrid(int16 pKey) {
}
// Press down - less X positions
- if (pKey == Keys::PreviousRoom) {
+ if (pKey == twineactions[TwinEActionType::PreviousRoom].localKey) {
_engine->_scene->currentSceneIdx--;
if (_engine->_scene->currentSceneIdx < 0)
_engine->_scene->currentSceneIdx = NUM_SCENES;
_engine->_scene->needChangeScene = _engine->_scene->currentSceneIdx;
_engine->_redraw->reqBgRedraw = 1;
}
-
- if (_engine->cfgfile.Debug && (pKey == 'f' || pKey == 'r')) {
- debug("Grid index changed: %d", _engine->_scene->needChangeScene);
- }
}
void DebugGrid::applyCellingGrid(int16 pKey) {
// Increase celling grid index
- if (pKey == Keys::IncreaseCellingGridIndex) {
+ if (pKey == twineactions[TwinEActionType::IncreaseCellingGridIndex].localKey) {
_engine->_grid->cellingGridIdx++;
if (_engine->_grid->cellingGridIdx > 133)
_engine->_grid->cellingGridIdx = 133;
}
// Decrease celling grid index
- else if (pKey == Keys::DecreaseCellingGridIndex) {
+ else if (pKey == twineactions[TwinEActionType::DecreaseCellingGridIndex].localKey) {
_engine->_grid->cellingGridIdx--;
if (_engine->_grid->cellingGridIdx < 0)
_engine->_grid->cellingGridIdx = 0;
}
// Enable/disable celling grid
- else if (pKey == Keys::ApplyCellingGrid) {
+ else if (pKey == twineactions[TwinEActionType::ApplyCellingGrid].localKey) {
if (_engine->_grid->useCellingGrid == -1) {
_engine->_grid->useCellingGrid = 1;
//createGridMap();
diff --git a/engines/twine/keyboard.h b/engines/twine/keyboard.h
index b948c58bfe..ed64d6f9f3 100644
--- a/engines/twine/keyboard.h
+++ b/engines/twine/keyboard.h
@@ -28,38 +28,72 @@
namespace TwinE {
-namespace Keys {
+enum TwinEActionType {
+ Pause,
+ NextRoom,
+ PreviousRoom,
+ ApplyCellingGrid,
+ IncreaseCellingGridIndex,
+ DecreaseCellingGridIndex,
+ DebugGridCameraPressUp,
+ DebugGridCameraPressDown,
+ DebugGridCameraPressLeft,
+ DebugGridCameraPressRight,
+ QuickBehaviourNormal,
+ QuickBehaviourAthletic,
+ QuickBehaviourAggressive,
+ QuickBehaviourDiscreet,
+ ExecuteBehaviourAction,
+ BehaviourMenu,
+ OptionsMenu,
+ RecenterScreenOnTwinsen,
+ UseSelectedObject,
+ ThrowMagicBall,
+ MoveForward,
+ MoveBackward,
+ TurnRight,
+ TurnLeft,
+ UseProtoPack,
+ OpenHolomap,
+ InventoryMenu,
-enum _Keys {
- Pause = 0x19,
- NextRoom = 0x13,
- PreviousRoom = 0x21,
- ApplyCellingGrid = 0x14,
- IncreaseCellingGridIndex = 0x22,
- DecreaseCellingGridIndex = 0x30,
- DebugGridCameraPressUp = 0x2E,
- DebugGridCameraPressDown = 0x2C,
- DebugGridCameraPressLeft = 0x1F,
- DebugGridCameraPressRight = 0x2D,
- QuickBehaviourNormal = 0x3B,
- QuickBehaviourAthletic = 0x3C,
- QuickBehaviourAggressive = 0x3D,
- QuickBehaviourDiscreet = 0x3E,
- ExecuteBehaviourAction = 0x39,
- BehaviourMenu = 0x1D,
- OptionsMenu = 0x40,
- RecenterScreenOnTwinsen = 0x1C,
- UseSelectedObject = 0x1C,
- MoveForward = 0x48,
- MoveBackward = 0x50,
- TurnRight = 0x4D,
- TurnLeft = 0x4B,
- UseProtoPack = 0x24,
- OpenHolomap = 0x23,
- InventoryMenu = 0x36
+ Max
};
-}
+static constexpr const struct ActionMapping {
+ TwinEActionType action;
+ uint16 localKey;
+} twineactions[] = {
+ {Pause, 0x19},
+ {NextRoom, 0x13},
+ {PreviousRoom, 0x21},
+ {ApplyCellingGrid, 0x14},
+ {IncreaseCellingGridIndex, 0x22},
+ {DecreaseCellingGridIndex, 0x30},
+ {DebugGridCameraPressUp, 0x2E},
+ {DebugGridCameraPressDown, 0x2C},
+ {DebugGridCameraPressLeft, 0x1F},
+ {DebugGridCameraPressRight, 0x2D},
+ {QuickBehaviourNormal, 0x3B},
+ {QuickBehaviourAthletic, 0x3C},
+ {QuickBehaviourAggressive, 0x3D},
+ {QuickBehaviourDiscreet, 0x3E},
+ {ExecuteBehaviourAction, 0x39},
+ {BehaviourMenu, 0x1D},
+ {OptionsMenu, 0x40},
+ {RecenterScreenOnTwinsen, 0x1C},
+ {UseSelectedObject, 0x1C},
+ {ThrowMagicBall, 0xDEAD}, // TODO:
+ {MoveForward, 0x48},
+ {MoveBackward, 0x50},
+ {TurnRight, 0x4D},
+ {TurnLeft, 0x4B},
+ {UseProtoPack, 0x24},
+ {OpenHolomap, 0x23},
+ {InventoryMenu, 0x36}
+};
+
+static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected action mapping array size");
struct Keyboard {
/** Skipped key - key1 */
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index ac29cfbd8d..7cc5465cf6 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -20,12 +20,16 @@
*
*/
+#include "backends/keymapper/action.h"
+#include "backends/keymapper/standard-actions.h"
#include "base/plugins.h"
#include "common/fs.h"
#include "common/savefile.h"
#include "common/system.h"
+#include "common/translation.h"
#include "engines/advancedDetector.h"
+#include "twine/keyboard.h"
#include "twine/twine.h"
namespace TwinE {
@@ -46,8 +50,169 @@ public:
}
return desc != nullptr;
}
+
+ Common::Array<Common::Keymap *> initKeymaps(const char *target) const override;
};
+Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
+ using namespace Common;
+
+ Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "twine", "Little Big Adventure");
+
+ Action *act;
+
+ act = new Action("PAUSE", _("Pause"));
+ act->setCustomEngineActionEvent(TwinEActionType::Pause);
+ act->addDefaultInputMapping("p");
+ engineKeyMap->addAction(act);
+
+ act = new Action("NEXTROOM", _("Debug Next Room"));
+ act->setCustomEngineActionEvent(TwinEActionType::NextRoom);
+ act->addDefaultInputMapping("r");
+ engineKeyMap->addAction(act);
+
+ act = new Action("PREVIOUSROOM", _("Debug Previous Room"));
+ act->setCustomEngineActionEvent(TwinEActionType::PreviousRoom);
+ act->addDefaultInputMapping("f");
+ engineKeyMap->addAction(act);
+
+ act = new Action("APPLYCELLINGGRID", _("Debug Apply Celling Grid"));
+ act->setCustomEngineActionEvent(TwinEActionType::ApplyCellingGrid);
+ act->addDefaultInputMapping("t");
+ engineKeyMap->addAction(act);
+
+ act = new Action("INCREASECELLINGGRIDINDEX", _("Debug Increase Celling Grid Index"));
+ act->setCustomEngineActionEvent(TwinEActionType::IncreaseCellingGridIndex);
+ act->addDefaultInputMapping("g");
+ engineKeyMap->addAction(act);
+
+ act = new Action("DECREASECELLINGGRIDINDEX", _("Debug Decrease Celling Grid Index"));
+ act->setCustomEngineActionEvent(TwinEActionType::DecreaseCellingGridIndex);
+ act->addDefaultInputMapping("b");
+ engineKeyMap->addAction(act);
+
+ act = new Action("DEBUGGRIDCAMERAPRESSUP", _("Debug Grid Camera Up"));
+ act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressUp);
+ act->addDefaultInputMapping("w");
+ engineKeyMap->addAction(act);
+
+ act = new Action("DEBUGGRIDCAMERAPRESSDOWN", _("Debug Grid Camera Down"));
+ act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressDown);
+ act->addDefaultInputMapping("s");
+ engineKeyMap->addAction(act);
+
+ act = new Action("DEBUGGRIDCAMERAPRESSLEFT", _("Debug Grid Camera Left"));
+ act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressLeft);
+ act->addDefaultInputMapping("a");
+ engineKeyMap->addAction(act);
+
+ act = new Action("DEBUGGRIDCAMERAPRESSRIGHT", _("Debug Grid Camera Right"));
+ act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressRight);
+ act->addDefaultInputMapping("d");
+ engineKeyMap->addAction(act);
+
+ act = new Action("NORMALBEHAVIOUR", _("Normal Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourNormal);
+ act->addDefaultInputMapping("F1");
+ engineKeyMap->addAction(act);
+
+ act = new Action("ATHLETICBEHAVIOUR", _("Athletic Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAthletic);
+ act->addDefaultInputMapping("F2");
+ engineKeyMap->addAction(act);
+
+ act = new Action("AGGRESSIVEBEHAVIOUR", _("Aggressive Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAggressive);
+ act->addDefaultInputMapping("F3");
+ engineKeyMap->addAction(act);
+
+ act = new Action("DISCREETBEHAVIOUR", _("Discreet Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourDiscreet);
+ act->addDefaultInputMapping("F4");
+ engineKeyMap->addAction(act);
+
+ act = new Action("BEHAVIOURACTION", _("Behaviour Action"));
+ act->setCustomEngineActionEvent(TwinEActionType::ExecuteBehaviourAction);
+ act->addDefaultInputMapping("SPACE");
+ act->addDefaultInputMapping("JOY_A");
+ engineKeyMap->addAction(act);
+
+ act = new Action("CHANGEBEHAVIOUR", _("Change Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::BehaviourMenu);
+ act->addDefaultInputMapping("CTRL");
+ engineKeyMap->addAction(act);
+
+ act = new Action("OPTIONSMENU", _("Options Menu"));
+ act->setCustomEngineActionEvent(TwinEActionType::OptionsMenu);
+ act->addDefaultInputMapping("F6");
+ engineKeyMap->addAction(act);
+
+ act = new Action("CENTER", _("Center"));
+ act->setCustomEngineActionEvent(TwinEActionType::RecenterScreenOnTwinsen);
+ act->addDefaultInputMapping("RETURN");
+ act->addDefaultInputMapping("KP_ENTER");
+ engineKeyMap->addAction(act);
+
+ act = new Action("USESELECTEDOBJECT", _("Use Selected Object"));
+ act->setCustomEngineActionEvent(TwinEActionType::UseSelectedObject);
+ act->addDefaultInputMapping("SHIFT+RETURN");
+ act->addDefaultInputMapping("SHIFT+KP_ENTER");
+ engineKeyMap->addAction(act);
+
+ act = new Action("THROWMAGICBALL", _("Throw Magic Ball"));
+ act->setCustomEngineActionEvent(TwinEActionType::ThrowMagicBall);
+ act->addDefaultInputMapping("ALT");
+ engineKeyMap->addAction(act);
+
+ act = new Action("MOVEFORWARD", _("Move Forward"));
+ act->setCustomEngineActionEvent(TwinEActionType::MoveForward);
+ act->addDefaultInputMapping("UP");
+ act->addDefaultInputMapping("KP8");
+ engineKeyMap->addAction(act);
+
+ act = new Action("MOVEBACKWARD", _("Move Backward"));
+ act->setCustomEngineActionEvent(TwinEActionType::MoveBackward);
+ act->addDefaultInputMapping("DOWN");
+ act->addDefaultInputMapping("KP2");
+ engineKeyMap->addAction(act);
+
+ act = new Action("TurnRight", _("Turn Right"));
+ act->setCustomEngineActionEvent(TwinEActionType::TurnRight);
+ act->addDefaultInputMapping("RIGHT");
+ act->addDefaultInputMapping("KP6");
+ engineKeyMap->addAction(act);
+
+ act = new Action("TurnLeft", _("Turn Left"));
+ act->setCustomEngineActionEvent(TwinEActionType::TurnLeft);
+ act->addDefaultInputMapping("LEFT");
+ act->addDefaultInputMapping("KP4");
+ engineKeyMap->addAction(act);
+
+ act = new Action("USEPROTOPACK", _("Use Protopack"));
+ act->setCustomEngineActionEvent(TwinEActionType::UseProtoPack);
+ act->addDefaultInputMapping("j");
+ engineKeyMap->addAction(act);
+
+ act = new Action("OPENHOLOMAP", _("Open Holomap"));
+ act->setCustomEngineActionEvent(TwinEActionType::OpenHolomap);
+ act->addDefaultInputMapping("h");
+ engineKeyMap->addAction(act);
+
+ act = new Action("INVENTORY", _("Inventory"));
+ act->setCustomEngineActionEvent(TwinEActionType::InventoryMenu);
+ act->addDefaultInputMapping("LSHIFT");
+ act->addDefaultInputMapping("RSHIFT");
+ act->addDefaultInputMapping("i");
+ engineKeyMap->addAction(act);
+
+ const int delta = (int)TwinEActionType::Max - (int)engineKeyMap->getActions().size();
+ if (delta != 0) {
+ error("Registered key map actions differs from TwinEActionType by %i", delta);
+ }
+
+ return Keymap::arrayOf(engineKeyMap);
+}
+
} // namespace TwinE
#if PLUGIN_ENABLED_DYNAMIC(TWINE)
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 455cbc8bbe..8318a32486 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -233,9 +233,6 @@ void TwinEEngine::initEngine() {
_screens->clearScreen();
- // Toggle fullscreen if Fullscreen flag is set
- toggleFullscreen();
-
// Check if LBA CD-Rom is on drive
_music->initCdrom();
@@ -377,7 +374,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
// inventory menu
loopInventoryItem = -1;
- if (loopCurrentKey == Keys::InventoryMenu && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
+ if (loopCurrentKey == twineactions[TwinEActionType::InventoryMenu].localKey && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
freezeTime();
_menu->processInventoryMenu();
@@ -490,19 +487,19 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
// Process behaviour menu - Press CTRL and F1..F4 Keys
- if ((loopCurrentKey == Keys::BehaviourMenu
- || loopCurrentKey == Keys::QuickBehaviourNormal
- || loopCurrentKey == Keys::QuickBehaviourAthletic
- || loopCurrentKey == Keys::QuickBehaviourAggressive
- || loopCurrentKey == Keys::QuickBehaviourDiscreet)
- && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
- if (loopCurrentKey == Keys::QuickBehaviourNormal) {
+ if ((loopCurrentKey == twineactions[TwinEActionType::BehaviourMenu].localKey ||
+ loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourNormal].localKey ||
+ loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAthletic].localKey ||
+ loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAggressive].localKey ||
+ loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey) &&
+ _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
+ if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourNormal].localKey) {
_actor->heroBehaviour = HeroBehaviourType::kNormal;
- } else if (loopCurrentKey == Keys::QuickBehaviourAthletic) {
+ } else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAthletic].localKey) {
_actor->heroBehaviour = HeroBehaviourType::kAthletic;
- } else if (loopCurrentKey == Keys::QuickBehaviourAggressive) {
+ } else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAggressive].localKey) {
_actor->heroBehaviour = HeroBehaviourType::kAggressive;
- } else if (loopCurrentKey == Keys::QuickBehaviourDiscreet) {
+ } else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey) {
_actor->heroBehaviour = HeroBehaviourType::kDiscrete;
}
freezeTime();
@@ -512,7 +509,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
// use Proto-Pack
- if (loopCurrentKey == Keys::UseProtoPack && _gameState->gameFlags[InventoryItems::kiProtoPack] == 1) {
+ if (loopCurrentKey == twineactions[TwinEActionType::UseProtoPack].localKey && _gameState->gameFlags[InventoryItems::kiProtoPack] == 1) {
if (_gameState->gameFlags[InventoryItems::kiBookOfBu]) {
_scene->sceneHero->body = 0;
} else {
@@ -545,7 +542,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
// Process Pause - Press P
- if (loopCurrentKey == Keys::Pause) {
+ if (loopCurrentKey == twineactions[TwinEActionType::Pause].localKey) {
freezeTime();
_text->setFontColor(15);
_text->drawText(5, 446, "Pause"); // no key for pause in Text Bank
@@ -830,12 +827,6 @@ void TwinEEngine::crossFade(const Graphics::Surface &buffer, uint8 *palette) {
g_system->updateScreen();
}
-void TwinEEngine::toggleFullscreen() {
- _redraw->reqBgRedraw = 1;
- _system->setFeatureState(OSystem::kFeatureFullscreenMode, cfgfile.FullScreen);
- cfgfile.FullScreen = !cfgfile.FullScreen;
-}
-
/** Pressed key map - scanCodeTab1 */
static const uint8 pressedKeyMap[] = {
0x48, // 0
@@ -911,7 +902,6 @@ static const uint16 pressedKeyCharMap[] = {
};
static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
-/** Handle keyboard pressed keys */
void TwinEEngine::readKeys() {
if (shouldQuit()) {
_keyboard.skipIntro = 1;
@@ -920,11 +910,34 @@ void TwinEEngine::readKeys() {
}
_keyboard.skippedKey = 0;
_keyboard.skipIntro = 0;
- int32 localKey = 0;
Common::Event event;
while (g_system->getEventManager()->pollEvent(event)) {
+ int32 localKey = 0;
switch (event.type) {
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
+ actionStates[event.customType] = false;
+ localKey = twineactions[event.customType].localKey | 0x80;
+ break;
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
+ if (!cfgfile.Debug) {
+ switch (event.customType) {
+ case TwinEActionType::NextRoom:
+ case TwinEActionType::PreviousRoom:
+ case TwinEActionType::ApplyCellingGrid:
+ case TwinEActionType::IncreaseCellingGridIndex:
+ case TwinEActionType::DecreaseCellingGridIndex:
+ break;
+ default:
+ localKey = twineactions[event.customType].localKey;
+ actionStates[event.customType] = true;
+ break;
+ }
+ } else {
+ localKey = twineactions[event.customType].localKey;
+ actionStates[event.customType] = true;
+ }
+ break;
case Common::EVENT_KEYUP:
_keyboard.pressedKey = 0;
break;
@@ -933,82 +946,19 @@ void TwinEEngine::readKeys() {
case Common::KEYCODE_ESCAPE:
localKey = 0x1;
break;
- case Common::KEYCODE_SPACE:
- localKey = Keys::ExecuteBehaviourAction;
- break;
- case Common::KEYCODE_RETURN:
- case Common::KEYCODE_KP_ENTER:
- localKey = Keys::RecenterScreenOnTwinsen; // TODO: depends on the context
- break;
- case Common::KEYCODE_LSHIFT:
- case Common::KEYCODE_RSHIFT:
- localKey = Keys::InventoryMenu;
- break;
case Common::KEYCODE_LALT:
case Common::KEYCODE_RALT:
localKey = 0x38;
break;
- case Common::KEYCODE_LCTRL:
- case Common::KEYCODE_RCTRL:
- localKey = Keys::BehaviourMenu;
- break;
case Common::KEYCODE_PAGEUP:
localKey = 0x49;
break;
- case Common::KEYCODE_p: // pause
- localKey = Keys::Pause;
- break;
- case Common::KEYCODE_h: // holomap
- localKey = Keys::OpenHolomap;
- break;
- case Common::KEYCODE_j:
- localKey = Keys::UseProtoPack;
- break;
case Common::KEYCODE_w: // Especial key to do the action
localKey = 0x11;
break;
- case Common::KEYCODE_F1:
- localKey = Keys::QuickBehaviourNormal;
- break;
- case Common::KEYCODE_F2:
- localKey = Keys::QuickBehaviourAthletic;
- break;
- case Common::KEYCODE_F3:
- localKey = Keys::QuickBehaviourAggressive;
- break;
- case Common::KEYCODE_F4:
- localKey = Keys::QuickBehaviourDiscreet;
- break;
- case Common::KEYCODE_F6:
- localKey = Keys::OptionsMenu;
- break;
- case Common::KEYCODE_F12:
- toggleFullscreen();
- break;
default:
break;
}
- if (cfgfile.Debug) {
- switch (event.kbd.keycode) {
- case Common::KEYCODE_r: // next room
- localKey = Keys::NextRoom;
- break;
- case Common::KEYCODE_f: // previous room
- localKey = Keys::PreviousRoom;
- break;
- case Common::KEYCODE_t: // apply celling grid
- localKey = Keys::ApplyCellingGrid;
- break;
- case Common::KEYCODE_g: // increase celling grid index
- localKey = Keys::IncreaseCellingGridIndex;
- break;
- case Common::KEYCODE_b: // decrease celling grid index
- localKey = Keys::DecreaseCellingGridIndex;
- break;
- default:
- break;
- }
- }
break;
}
case Common::EVENT_LBUTTONDOWN:
@@ -1020,109 +970,29 @@ void TwinEEngine::readKeys() {
default:
break;
}
- }
-#if 1
- {
-#else
- int32 size = 0;
- uint8 *keyboard = nullptr; // TODO: SDL_GetKeyState(&size);
- for (int32 j = 0; j < size; j++) {
- if (keyboard[j]) {
- switch (j) {
- case Common::KEYCODE_RETURN:
- case Common::KEYCODE_KP_ENTER:
- localKey = Keys::RecenterScreenOnTwinsen; // TODO: depends on the context
- break;
- case Common::KEYCODE_SPACE:
- localKey = Keys::ExecuteBehaviourAction;
- break;
- case Common::KEYCODE_UP:
- case Common::KEYCODE_KP8:
- localKey = Keys::MoveForward;
- break;
- case Common::KEYCODE_DOWN:
- case Common::KEYCODE_KP2:
- localKey = Keys::MoveBackward;
- break;
- case Common::KEYCODE_LEFT:
- case Common::KEYCODE_KP4:
- localKey = Keys::TurnLeft;
- break;
- case Common::KEYCODE_RIGHT:
- case Common::KEYCODE_KP6:
- localKey = Keys::TurnRight;
- break;
- case Common::KEYCODE_LCTRL:
- case Common::KEYCODE_RCTRL:
- localKey = Keys::BehaviourMenu;
- break;
- /*case Common::KEYCODE_LSHIFT:
- case Common::KEYCODE_RSHIFT:
- localKey = 0x36;
- break;*/
- case Common::KEYCODE_LALT:
- case Common::KEYCODE_RALT:
- localKey = 0x38;
- break;
- case Common::KEYCODE_F1:
- localKey = Keys::QuickBehaviourNormal;
- break;
- case Common::KEYCODE_F2:
- localKey = Keys::QuickBehaviourAthletic;
- break;
- case Common::KEYCODE_F3:
- localKey = Keys::QuickBehaviourAggressive;
- break;
- case Common::KEYCODE_F4:
- localKey = Keys::QuickBehaviourDiscreet;
- break;
- default:
- break;
- }
- if (cfgfile.Debug) {
- switch (keyboard[j]) {
- // change grid camera
- case Common::KEYCODE_s:
- localKey = 0x1F;
- break;
- case Common::KEYCODE_x:
- localKey = 0x2D;
- break;
- case Common::KEYCODE_z:
- localKey = 0x2C;
- break;
- case Common::KEYCODE_c:
- localKey = 0x2E;
- break;
- }
- }
+
+ if (localKey == 0) {
+ continue;
}
-#endif
- int find = 0;
- bool found = false;
+
for (int i = 0; i < ARRAYSIZE(pressedKeyMap); i++) {
if (pressedKeyMap[i] == localKey) {
- find = i;
- found = true;
- break;
- }
- }
-
- if (found) {
- int16 temp = pressedKeyCharMap[find];
- uint8 temp2 = temp & 0x00FF;
-
- if (temp2 == 0) {
- // pressed valid keys
- if (!(localKey & 0x80)) {
- _keyboard.pressedKey |= (temp & 0xFF00) >> 8;
- } else {
- _keyboard.pressedKey &= -((temp & 0xFF00) >> 8);
+ int16 temp = pressedKeyCharMap[i];
+ uint8 temp2 = temp & 0x00FF;
+
+ if (temp2 == 0) {
+ // pressed valid keys
+ if (!(localKey & 0x80)) {
+ _keyboard.pressedKey |= (temp & 0xFF00) >> 8;
+ } else {
+ _keyboard.pressedKey &= -((temp & 0xFF00) >> 8);
+ }
}
- }
- // pressed inactive keys
- else {
- _keyboard.skippedKey |= (temp & 0xFF00) >> 8;
+ // pressed inactive keys
+ else {
+ _keyboard.skippedKey |= (temp & 0xFF00) >> 8;
+ }
+ break;
}
}
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index e39ac6083e..f0161ae7ec 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -23,6 +23,7 @@
#ifndef TWINE_TWINE_H
#define TWINE_TWINE_H
+#include "backends/keymapper/keymap.h"
#include "common/random.h"
#include "engines/engine.h"
@@ -151,6 +152,7 @@ private:
int32 isTimeFreezed = 0;
int32 saveFreezedTime = 0;
ActorMoveStruct loopMovePtr; // mainLoopVar1
+ bool actionStates[TwinEActionType::Max] {false};
public:
TwinEEngine(OSystem *system, Common::Language language, uint32 flags);
@@ -282,9 +284,6 @@ public:
*/
void crossFade(const Graphics::Surface &buffer, uint8 *palette);
- /** Switch between window and fullscreen modes */
- void toggleFullscreen();
-
/** Handle keyboard pressed keys */
void readKeys();
Commit: 5d18dd0d17bbbe1c8eff08cec3c01da70c0450e0
https://github.com/scummvm/scummvm/commit/5d18dd0d17bbbe1c8eff08cec3c01da70c0450e0
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: handle magic ball action and code cleanup
Changed paths:
engines/twine/keyboard.h
engines/twine/menu.cpp
engines/twine/text.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/keyboard.h b/engines/twine/keyboard.h
index ed64d6f9f3..c2442e25af 100644
--- a/engines/twine/keyboard.h
+++ b/engines/twine/keyboard.h
@@ -62,7 +62,7 @@ enum TwinEActionType {
static constexpr const struct ActionMapping {
TwinEActionType action;
- uint16 localKey;
+ uint8 localKey;
} twineactions[] = {
{Pause, 0x19},
{NextRoom, 0x13},
@@ -83,7 +83,7 @@ static constexpr const struct ActionMapping {
{OptionsMenu, 0x40},
{RecenterScreenOnTwinsen, 0x1C},
{UseSelectedObject, 0x1C},
- {ThrowMagicBall, 0xDEAD}, // TODO:
+ {ThrowMagicBall, 0x38},
{MoveForward, 0x48},
{MoveBackward, 0x50},
{TurnRight, 0x4D},
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 2efb86d8d8..ae12a4afe1 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -273,7 +273,7 @@ void Menu::processPlasmaEffect(int32 top, int32 color) {
plasmaEffectRenderFrame();
in = plasmaEffectPtr + 5 * PLASMA_WIDTH;
- out = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top];
+ out = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top];
for (i = 0; i < 25; i++) {
for (j = 0; j < kMainMenuButtonWidth; j++) {
@@ -355,7 +355,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 id, int32 value, in
}
}
} else {
- _engine->_interface->blitBox(left, top, right, bottom, (const int8*)_engine->workVideoBuffer.getPixels(), left, top, (int8*)_engine->frontVideoBuffer.getPixels());
+ _engine->_interface->blitBox(left, top, right, bottom, (const int8 *)_engine->workVideoBuffer.getPixels(), left, top, (int8 *)_engine->frontVideoBuffer.getPixels());
_engine->_interface->drawTransparentBox(left, top, right, bottom2, 4);
}
@@ -440,8 +440,8 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (_engine->lbaTime - localTime > 11650) {
return kBackground;
}
- if (_engine->_keyboard.skipIntro == 46) {
- if (_engine->_keyboard.skippedKey != 32) {
+ if (_engine->_keyboard.skipIntro == '.') {
+ if (_engine->_keyboard.skippedKey != ' ') {
return kBackground;
}
}
@@ -472,12 +472,13 @@ int32 Menu::processMenu(int16 *menuSettings) {
buttonReleased = 0;
}
- if (*(localData + 8) <= 5) { // if its a volume button
- int16 id = *(localData + currentButton * 2 + 4); // get button parameters from settings array
+ if (*(localData + 8) <= 5) { // if its a volume button
+ const int16 id = *(localData + currentButton * 2 + 4); // get button parameters from settings array
+ Audio::Mixer *mixer = _engine->_system->getMixer();
switch (id) {
case kMusicVolume: {
- int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
+ int volume = mixer->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
volume -= 4;
}
@@ -488,14 +489,14 @@ int32 Menu::processMenu(int16 *menuSettings) {
break;
}
case kSoundVolume: {
- int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
+ int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
volume -= 4;
}
if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
volume += 4;
}
- _engine->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
+ mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
break;
}
case kCDVolume: {
@@ -510,25 +511,25 @@ int32 Menu::processMenu(int16 *menuSettings) {
break;
}
case kLineVolume: {
- int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
+ int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
volume -= 4;
}
if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
volume += 4;
}
- _engine->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
+ mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
break;
}
case kMasterVolume: {
- int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
+ int volume = mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
volume -= 4;
}
if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
volume += 4;
}
- _engine->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
+ mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
break;
}
default:
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 9a8fdcc48d..3125d38221 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -253,20 +253,18 @@ void Text::drawCharacterShadow(int32 x, int32 y, uint8 character, int32 color) {
}
void Text::drawText(int32 x, int32 y, const char *dialogue) { // Font
- uint8 currChar;
-
if (fontPtr == 0) // if the font is not defined
return;
do {
- currChar = (uint8) * (dialogue++); // read the next char from the string
+ uint8 currChar = (uint8) *(dialogue++); // read the next char from the string
if (currChar == 0) // if the char is 0x0, -> end of string
break;
- if (currChar == 0x20) // if it's a space char
+ if (currChar == ' ') {
x += dialCharSpace;
- else {
+ } else {
dialTextSize = *(fontPtr + (*((int16 *)(fontPtr + currChar * 4)))); // get the length of the character
drawCharacter(x, y, currChar); // draw the character on screen
// add the length of the space between 2 characters
@@ -278,16 +276,14 @@ void Text::drawText(int32 x, int32 y, const char *dialogue) { // Font
}
int32 Text::getTextSize(const char *dialogue) { // SizeFont
- uint8 currChar;
dialTextSize = 0;
do {
- currChar = (uint8) * (dialogue++);
-
+ uint8 currChar = (uint8) * (dialogue++);
if (currChar == 0)
break;
- if (currChar == 0x20) {
+ if (currChar == ' ') {
dialTextSize += dialCharSpace;
} else {
dialTextSize += dialSpaceBetween;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 8318a32486..9d27278500 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -355,8 +355,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_redraw->redrawEngineActions(1);
}
- // Process options menu - Press F6
- if (loopCurrentKey == 0x40) {
+ if (loopCurrentKey == twineactions[TwinEActionType::OptionsMenu].localKey) {
int tmpLangCD = cfgfile.LanguageCDId;
freezeTime();
_sound->pauseSamples();
@@ -917,7 +916,7 @@ void TwinEEngine::readKeys() {
switch (event.type) {
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
actionStates[event.customType] = false;
- localKey = twineactions[event.customType].localKey | 0x80;
+ localKey = twineactions[event.customType].localKey;
break;
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
if (!cfgfile.Debug) {
@@ -944,11 +943,7 @@ void TwinEEngine::readKeys() {
case Common::EVENT_KEYDOWN: {
switch (event.kbd.keycode) {
case Common::KEYCODE_ESCAPE:
- localKey = 0x1;
- break;
- case Common::KEYCODE_LALT:
- case Common::KEYCODE_RALT:
- localKey = 0x38;
+ _keyboard.skipIntro = 1;
break;
case Common::KEYCODE_PAGEUP:
localKey = 0x49;
Commit: 7978dffee6ff5668adf100dbaa586d654131d34c
https://github.com/scummvm/scummvm/commit/7978dffee6ff5668adf100dbaa586d654131d34c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed valgrind error reports
Changed paths:
engines/twine/flamovies.cpp
engines/twine/sound.h
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index ca013b1f97..324a8ec72f 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -160,7 +160,8 @@ void FlaMovies::processFrame() {
file.read(&frameData.videoSize, 1);
file.read(&frameData.dummy, 1);
file.read(&frameData.frameVar0, 4);
- if (frameData.frameVar0 > _engine->workVideoBuffer.w * _engine->workVideoBuffer.h * _engine->workVideoBuffer.format.bpp()) {
+ if (frameData.frameVar0 > _engine->workVideoBuffer.w * _engine->workVideoBuffer.h) {
+ warning("Skipping video frame - it would exceed the screen buffer: %i", frameData.frameVar0);
return;
}
diff --git a/engines/twine/sound.h b/engines/twine/sound.h
index dbbd35b1c1..f67e7fbecf 100644
--- a/engines/twine/sound.h
+++ b/engines/twine/sound.h
@@ -44,16 +44,16 @@ private:
Audio::SoundHandle samplesPlaying[NUM_CHANNELS];
/** Samples playing at a actors position */
- int32 samplesPlayingActors[NUM_CHANNELS];
+ int32 samplesPlayingActors[NUM_CHANNELS]{0};
public:
Sound(TwinEEngine *engine);
bool isChannelPlaying(int32 channel);
/** Table with all loaded samples */
- uint8 *samplesTable[NUM_SAMPLES] {nullptr};
+ uint8 *samplesTable[NUM_SAMPLES]{nullptr};
/** Table with all loaded samples sizes */
- uint32 samplesSizeTable[NUM_SAMPLES] {0};
+ uint32 samplesSizeTable[NUM_SAMPLES]{0};
/**
* Sample volume
Commit: e652a0e93b7c37da23ae669e97c7a680ab92f164
https://github.com/scummvm/scummvm/commit/e652a0e93b7c37da23ae669e97c7a680ab92f164
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: update the palette in crossFade
Changed paths:
engines/twine/script_life.h
engines/twine/script_move.h
engines/twine/twine.cpp
diff --git a/engines/twine/script_life.h b/engines/twine/script_life.h
index 3d93d3d9f5..58b86a6d52 100644
--- a/engines/twine/script_life.h
+++ b/engines/twine/script_life.h
@@ -38,8 +38,10 @@ private:
public:
ScriptLife(TwinEEngine *engine);
- /** Process actor life script
- @param actorIdx Current processed actor index */
+ /**
+ * Process actor life script
+ * @param actorIdx Current processed actor index
+ */
void processLifeScript(int32 actorIdx);
};
diff --git a/engines/twine/script_move.h b/engines/twine/script_move.h
index ae932818f8..2e1fc8abd8 100644
--- a/engines/twine/script_move.h
+++ b/engines/twine/script_move.h
@@ -35,8 +35,10 @@ private:
public:
ScriptMove(TwinEEngine *engine);
- /** Process actor move script
- @param actorIdx Current processed actor index */
+ /**
+ * Process actor move script
+ * @param actorIdx Current processed actor index
+ */
void processMoveScript(int32 actorIdx);
};
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 9d27278500..b520748655 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -821,6 +821,7 @@ void TwinEEngine::copyBlockPhys(int32 left, int32 top, int32 right, int32 bottom
}
void TwinEEngine::crossFade(const Graphics::Surface &buffer, uint8 *palette) {
+ g_system->getPaletteManager()->setPalette(palette, 0, 256);
// TODO: implement cross fading
g_system->copyRectToScreen(buffer.getPixels(), buffer.pitch, 0, 0, buffer.w, buffer.h);
g_system->updateScreen();
Commit: 33d27512f1c3f2a4f7f600cc38e6377ccb41b7a6
https://github.com/scummvm/scummvm/commit/33d27512f1c3f2a4f7f600cc38e6377ccb41b7a6
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: switch to managed surfaces
Changed paths:
engines/twine/redraw.cpp
engines/twine/screens.cpp
engines/twine/screens.h
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 4b95c94d2e..83f66df3b3 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -764,7 +764,7 @@ void Redraw::drawBubble(int32 actorIdx) {
}
void Redraw::zoomScreenScale() {
- Graphics::Surface zoomWorkVideoBuffer;
+ Graphics::ManagedSurface zoomWorkVideoBuffer;
zoomWorkVideoBuffer.copyFrom(_engine->workVideoBuffer);
// TODO: this is broken
diff --git a/engines/twine/screens.cpp b/engines/twine/screens.cpp
index 34820fd2ed..133919619d 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/screens.cpp
@@ -248,7 +248,7 @@ void Screens::copyScreen(const uint8 *source, uint8 *destination) {
}
}
-void Screens::copyScreen(const Graphics::Surface& source, Graphics::Surface &destination) {
+void Screens::copyScreen(const Graphics::ManagedSurface& source, Graphics::ManagedSurface &destination) {
copyScreen((const uint8 *)source.getPixels(), (uint8 *)destination.getPixels());
}
diff --git a/engines/twine/screens.h b/engines/twine/screens.h
index c860a00c22..a55ceecc17 100644
--- a/engines/twine/screens.h
+++ b/engines/twine/screens.h
@@ -24,6 +24,7 @@
#define TWINE_SCREENS_H
#include "common/scummsys.h"
+#include "graphics/managed_surface.h"
#include "graphics/surface.h"
#include "twine/twine.h"
@@ -167,7 +168,7 @@ public:
* @param destination screen buffer
*/
void copyScreen(const uint8 *source, uint8 *destination);
- void copyScreen(const Graphics::Surface &source, Graphics::Surface &destination);
+ void copyScreen(const Graphics::ManagedSurface &source, Graphics::ManagedSurface &destination);
/** Clear front buffer screen */
void clearScreen();
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index b520748655..fe71e20e23 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -30,6 +30,7 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "engines/util.h"
+#include "graphics/managed_surface.h"
#include "graphics/palette.h"
#include "graphics/surface.h"
#include "gui/debugger.h"
@@ -815,12 +816,14 @@ void TwinEEngine::flip() {
}
void TwinEEngine::copyBlockPhys(int32 left, int32 top, int32 right, int32 bottom) {
- // TODO: fix this
+ assert(left < right);
+ assert(top < bottom);
+ // TODO: fix this - looks like the palette includes a color key at pos 0
g_system->copyRectToScreen(frontVideoBuffer.getPixels(), frontVideoBuffer.pitch, left, top, right - left + 1, bottom - top + 1);
g_system->updateScreen();
}
-void TwinEEngine::crossFade(const Graphics::Surface &buffer, uint8 *palette) {
+void TwinEEngine::crossFade(const Graphics::ManagedSurface &buffer, uint8 *palette) {
g_system->getPaletteManager()->setPalette(palette, 0, 256);
// TODO: implement cross fading
g_system->copyRectToScreen(buffer.getPixels(), buffer.pitch, 0, 0, buffer.w, buffer.h);
@@ -1003,7 +1006,7 @@ void TwinEEngine::drawText(int32 x, int32 y, const char *string, int32 center) {
SDL_Color white = {0xFF, 0xFF, 0xFF, 0};
SDL_Color *forecol = &white;
SDL_Rect rectangle;
- Graphics::Surface *text = TTF_RenderText_Solid(font, string, *forecol);
+ Graphics::ManagedSurface *text = TTF_RenderText_Solid(font, string, *forecol);
if (center) {
rectangle.x = x - (text->w / 2);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index f0161ae7ec..8bdcd37206 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -27,6 +27,7 @@
#include "common/random.h"
#include "engines/engine.h"
+#include "graphics/managed_surface.h"
#include "graphics/pixelformat.h"
#include "graphics/surface.h"
#include "twine/actor.h"
@@ -220,9 +221,9 @@ public:
int16 rightMouse = 0;
/** Work video buffer */
- Graphics::Surface workVideoBuffer;
+ Graphics::ManagedSurface workVideoBuffer;
/** Main game video buffer */
- Graphics::Surface frontVideoBuffer;
+ Graphics::ManagedSurface frontVideoBuffer;
/** temporary screen table */
int32 screenLookupTable[2000]{0};
@@ -282,7 +283,7 @@ public:
* @param buffer screen buffer
* @param palette new palette to cross fade
*/
- void crossFade(const Graphics::Surface &buffer, uint8 *palette);
+ void crossFade(const Graphics::ManagedSurface &buffer, uint8 *palette);
/** Handle keyboard pressed keys */
void readKeys();
Commit: 385a7b542269e9f9c0927d4318b494a8e9a4b214
https://github.com/scummvm/scummvm/commit/385a7b542269e9f9c0927d4318b494a8e9a4b214
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: switched to rgba palette and ported crossFade
Changed paths:
engines/twine/debug.cpp
engines/twine/flamovies.cpp
engines/twine/gamestate.cpp
engines/twine/holomap.cpp
engines/twine/menuoptions.cpp
engines/twine/redraw.cpp
engines/twine/resources.cpp
engines/twine/screens.cpp
engines/twine/screens.h
engines/twine/script_life.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 26e8b31c76..6c958472ae 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -36,16 +36,12 @@
namespace TwinE {
void Debug::debugFillButton(int32 X, int32 Y, int32 width, int32 height, int8 color) {
- int32 i, j;
- uint8 *ptr;
- int32 offset;
+ uint8 *ptr = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[Y] + X;
+ int32 offset = 640 - width;
- ptr = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[Y] + X;
- offset = 640 - (width);
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- *(ptr++) = color;
+ for (int32 i = 0; i < height; i++) {
+ for (int32 j = 0; j < width; j++) {
+ *ptr++ = color;
}
ptr += offset;
}
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 324a8ec72f..2f799feab3 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -188,8 +188,8 @@ void FlaMovies::processFrame() {
// FLA movies don't use cross fade
// fade out tricky
if (_fadeOut != 1) {
- _engine->_screens->copyPal(_engine->_screens->palette, _engine->_screens->paletteRGBCustom);
- _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBCustom);
+ _engine->_screens->convertPalToRGBA(_engine->_screens->palette, _engine->_screens->paletteRGBACustom);
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBACustom);
_fadeOut = 1;
}
break;
@@ -288,18 +288,18 @@ void FlaMovies::playFlaMovie(const char *flaName) {
// Only blit to screen if isn't a fade
if (_fadeOut == -1) {
- _engine->_screens->copyPal(_engine->_screens->palette, _engine->_screens->paletteRGBCustom);
+ _engine->_screens->convertPalToRGBA(_engine->_screens->palette, _engine->_screens->paletteRGBACustom);
if (!currentFrame) // fade in the first frame
- _engine->_screens->fadeIn(_engine->_screens->paletteRGBCustom);
+ _engine->_screens->fadeIn(_engine->_screens->paletteRGBACustom);
else
- _engine->setPalette(_engine->_screens->paletteRGBCustom);
+ _engine->setPalette(_engine->_screens->paletteRGBACustom);
}
// TRICKY: fade in tricky
if (fadeOutFrames >= 2) {
_engine->flip();
- _engine->_screens->copyPal(_engine->_screens->palette, _engine->_screens->paletteRGBCustom);
- _engine->_screens->fadeToPal(_engine->_screens->paletteRGBCustom);
+ _engine->_screens->convertPalToRGBA(_engine->_screens->palette, _engine->_screens->paletteRGBACustom);
+ _engine->_screens->fadeToPal(_engine->_screens->paletteRGBACustom);
_fadeOut = -1;
fadeOutFrames = 0;
}
@@ -321,9 +321,9 @@ void FlaMovies::playFlaMovie(const char *flaName) {
}
if (_engine->cfgfile.CrossFade) {
- _engine->crossFade(_engine->frontVideoBuffer, _engine->_screens->paletteRGBCustom);
+ _engine->crossFade(_engine->frontVideoBuffer, _engine->_screens->paletteRGBACustom);
} else {
- _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBCustom);
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBACustom);
}
_engine->_sound->stopSamples();
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index b89aa8572a..5141e75732 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -484,7 +484,7 @@ void GameState::processGameoverAnimation() { // makeGameOver
_engine->_scene->sceneHero->staticFlags.bIsHidden = 0;
// TODO: drawInGameTransBox
- _engine->setPalette(_engine->_screens->paletteRGB);
+ _engine->setPalette(_engine->_screens->paletteRGBA);
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
uint8 *gameOverPtr = (uint8 *)malloc(_engine->_hqrdepack->hqrEntrySize(Resources::HQR_RESS_FILE, RESSHQR_GAMEOVERMDL));
_engine->_hqrdepack->hqrGetEntry(gameOverPtr, Resources::HQR_RESS_FILE, RESSHQR_GAMEOVERMDL);
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index c2c3961af4..fdeb82de14 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -125,7 +125,7 @@ void Holomap::processHolomap() {
alphaLightTmp = _engine->_scene->alphaLight;
betaLightTmp = _engine->_scene->betaLight;
- _engine->_screens->fadeToBlack(_engine->_screens->paletteRGB);
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBA);
_engine->_sound->stopSamples();
_engine->_interface->resetClip();
_engine->_screens->clearScreen();
@@ -144,7 +144,7 @@ void Holomap::processHolomap() {
// TODO
_engine->_text->newGameVar4 = 1;
- _engine->_screens->fadeToBlack(_engine->_screens->paletteRGB);
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBA);
_engine->_scene->alphaLight = alphaLightTmp;
_engine->_scene->betaLight = betaLightTmp;
_engine->_gameState->initEngineVars();
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 80b2854645..767b3fcd64 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -79,7 +79,7 @@ void MenuOptions::newGame() {
_engine->_text->textClipSmall();
_engine->_text->newGameVar4 = 1;
- _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBCustom);
+ _engine->_screens->fadeToBlack(_engine->_screens->paletteRGBACustom);
_engine->_screens->clearScreen();
_engine->flip();
@@ -90,7 +90,7 @@ void MenuOptions::newGame() {
_engine->flip();
// set main palette back
- _engine->setPalette(_engine->_screens->paletteRGB);
+ _engine->setPalette(_engine->_screens->paletteRGBA);
_engine->cfgfile.FlagDisplayText = tmpFlagDisplayText;
}
@@ -120,7 +120,7 @@ void MenuOptions::showCredits() {
_engine->_screens->clearScreen();
_engine->flip();
- _engine->setPalette(_engine->_screens->paletteRGB);
+ _engine->setPalette(_engine->_screens->paletteRGBA);
}
void MenuOptions::drawSelectableCharacter(int32 x, int32 y, int32 arg) {
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 83f66df3b3..a99fbebdc7 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -211,15 +211,15 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
if (bgRedraw) {
_engine->freezeTime();
if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2)
- _engine->_screens->fadeOut(_engine->_screens->paletteRGB);
+ _engine->_screens->fadeOut(_engine->_screens->paletteRGBA);
_engine->_screens->clearScreen();
_engine->_grid->redrawGrid();
updateOverlayTypePosition(tmp_projPosX, tmp_projPosY, _engine->_renderer->projPosXScreen, _engine->_renderer->projPosYScreen);
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
- _engine->_screens->fadeIn(_engine->_screens->paletteRGB);
- _engine->setPalette(_engine->_screens->paletteRGB);
+ _engine->_screens->fadeIn(_engine->_screens->paletteRGBA);
+ _engine->setPalette(_engine->_screens->paletteRGBA);
}
} else {
blitBackgroundAreas();
@@ -701,7 +701,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
// make celling grid fade
// need to be here to fade after drawing all actors in scene
if (_engine->_scene->needChangeScene == -2) {
- _engine->crossFade(_engine->frontVideoBuffer, _engine->_screens->paletteRGB);
+ _engine->crossFade(_engine->frontVideoBuffer, _engine->_screens->paletteRGBA);
_engine->_scene->needChangeScene = -1;
}
@@ -715,9 +715,9 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
if (_engine->_screens->lockPalette) {
if (_engine->_screens->useAlternatePalette) {
- _engine->_screens->fadeToPal(_engine->_screens->paletteRGB);
+ _engine->_screens->fadeToPal(_engine->_screens->paletteRGBA);
} else {
- _engine->_screens->fadeToPal(_engine->_screens->mainPaletteRGB);
+ _engine->_screens->fadeToPal(_engine->_screens->mainPaletteRGBA);
}
_engine->_screens->lockPalette = 0;
}
diff --git a/engines/twine/resources.cpp b/engines/twine/resources.cpp
index 77fe9c293a..71099469f7 100644
--- a/engines/twine/resources.cpp
+++ b/engines/twine/resources.cpp
@@ -32,12 +32,12 @@ namespace TwinE {
void Resources::initPalettes() {
// Init standard palette
_engine->_hqrdepack->hqrGetallocEntry(&_engine->_screens->mainPalette, Resources::HQR_RESS_FILE, RESSHQR_MAINPAL);
- _engine->_screens->copyPal(_engine->_screens->mainPalette, _engine->_screens->mainPaletteRGB);
+ _engine->_screens->convertPalToRGBA(_engine->_screens->mainPalette, _engine->_screens->mainPaletteRGBA);
memcpy(_engine->_screens->palette, _engine->_screens->mainPalette, NUMOFCOLORS * 3);
- _engine->_screens->copyPal(_engine->_screens->palette, _engine->_screens->paletteRGB);
- _engine->setPalette(_engine->_screens->paletteRGB);
+ _engine->_screens->convertPalToRGBA(_engine->_screens->palette, _engine->_screens->paletteRGBA);
+ _engine->setPalette(_engine->_screens->paletteRGBA);
// We use it now
_engine->_screens->palCustom = 0;
diff --git a/engines/twine/screens.cpp b/engines/twine/screens.cpp
index 133919619d..c69701b5ef 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/screens.cpp
@@ -35,7 +35,7 @@ void Screens::adelineLogo() {
loadImage(RESSHQR_ADELINEIMG);
_engine->delaySkip(7000);
- fadeOut(paletteRGBCustom);
+ fadeOut(paletteRGBACustom);
palCustom = 1;
}
@@ -43,9 +43,9 @@ void Screens::loadMenuImage(bool fade_in) {
_engine->_hqrdepack->hqrGetEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, RESSHQR_MENUIMG);
copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
if (fade_in) {
- fadeToPal(paletteRGB);
+ fadeToPal(paletteRGBA);
} else {
- _engine->setPalette(paletteRGB);
+ _engine->setPalette(paletteRGBA);
}
palCustom = 0;
@@ -53,11 +53,18 @@ void Screens::loadMenuImage(bool fade_in) {
void Screens::loadCustomPalette(int32 index) {
_engine->_hqrdepack->hqrGetEntry(palette, Resources::HQR_RESS_FILE, index);
- copyPal(palette, paletteRGBCustom);
+ convertPalToRGBA(palette, paletteRGBACustom);
}
-void Screens::copyPal(const uint8* in, uint8* out) {
- memcpy(out, in, NUMOFCOLORS * 3);
+void Screens::convertPalToRGBA(const uint8* in, uint32* out) {
+ uint8* palDest = (uint8*)out;
+ for (int i = 0; i < NUMOFCOLORS; i++) {
+ palDest[0] = in[0];
+ palDest[1] = in[1];
+ palDest[2] = in[2];
+ palDest += 4;
+ in += 3;
+ }
}
void Screens::loadImage(int32 index, bool fade_in) {
@@ -65,9 +72,9 @@ void Screens::loadImage(int32 index, bool fade_in) {
copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
loadCustomPalette(index + 1);
if (fade_in) {
- fadeToPal(paletteRGBCustom);
+ fadeToPal(paletteRGBACustom);
} else {
- _engine->setPalette(paletteRGBCustom);
+ _engine->setPalette(paletteRGBACustom);
}
palCustom = 1;
@@ -76,10 +83,10 @@ void Screens::loadImage(int32 index, bool fade_in) {
void Screens::loadImageDelay(int32 index, int32 time) {
loadImage(index);
_engine->delaySkip(1000 * time);
- fadeOut(paletteRGBCustom);
+ fadeOut(paletteRGBACustom);
}
-void Screens::fadeIn(uint8 *pal) {
+void Screens::fadeIn(uint32 *pal) {
if (_engine->cfgfile.CrossFade)
_engine->crossFade(_engine->frontVideoBuffer, pal);
else
@@ -88,7 +95,7 @@ void Screens::fadeIn(uint8 *pal) {
_engine->setPalette(pal);
}
-void Screens::fadeOut(uint8 *pal) {
+void Screens::fadeOut(uint32 *pal) {
/*if(cfgfile.CrossFade)
crossFade(frontVideoBuffer, palette);
else
@@ -99,58 +106,61 @@ void Screens::fadeOut(uint8 *pal) {
int32 Screens::crossDot(int32 modifier, int32 color, int32 param, int32 intensity) {
if (!param)
- return (color);
+ return color;
return (((color - modifier) * intensity) / param) + modifier;
}
-void Screens::adjustPalette(uint8 R, uint8 G, uint8 B, uint8 *pal, int32 intensity) {
- uint8 localPalette[NUMOFCOLORS * 3];
+void Screens::adjustPalette(uint8 R, uint8 G, uint8 B, const uint32 *rgbaPal, int32 intensity) {
+ uint32 pal2[NUMOFCOLORS];
int32 counter = 0;
+ const uint8 *pal = (const uint8*)rgbaPal;
+ uint8 *localPalette = (uint8*)pal2;
uint8 *newR = &localPalette[0];
uint8 *newG = &localPalette[1];
uint8 *newB = &localPalette[2];
+ uint8 *newA = &localPalette[3];
for (int32 i = 0; i < NUMOFCOLORS; i++) {
*newR = crossDot(R, pal[counter], 100, intensity);
*newG = crossDot(G, pal[counter + 1], 100, intensity);
*newB = crossDot(B, pal[counter + 2], 100, intensity);
+ *newA = 0;
- newR += 3;
- newG += 3;
- newB += 3;
+ newR += 4;
+ newG += 4;
+ newB += 4;
+ newA += 4;
- counter += 3;
+ counter += 4;
}
- _engine->setPalette(localPalette);
+ _engine->setPalette(pal2);
}
-void Screens::adjustCrossPalette(uint8 *pal1, uint8 *pal2) {
- uint8 localPalette[NUMOFCOLORS * 4];
-
- uint8 *newR;
- uint8 *newG;
- uint8 *newB;
- uint8 *newA;
+void Screens::adjustCrossPalette(const uint32 *pal1, const uint32 *pal2) {
+ uint32 pal[NUMOFCOLORS];
int32 i;
int32 counter = 0;
int32 intensity = 0;
+ const uint8 *pal1p = (const uint8*)pal1;
+ const uint8 *pal2p = (const uint8*)pal2;
+ uint8 *localPalette = (uint8*)pal;
do {
counter = 0;
- newR = &localPalette[counter];
- newG = &localPalette[counter + 1];
- newB = &localPalette[counter + 2];
- newA = &localPalette[counter + 3];
+ uint8 *newR = &localPalette[counter];
+ uint8 *newG = &localPalette[counter + 1];
+ uint8 *newB = &localPalette[counter + 2];
+ uint8 *newA = &localPalette[counter + 3];
for (i = 0; i < NUMOFCOLORS; i++) {
- *newR = crossDot(pal1[counter], pal2[counter], 100, intensity);
- *newG = crossDot(pal1[counter + 1], pal2[counter + 1], 100, intensity);
- *newB = crossDot(pal1[counter + 2], pal2[counter + 2], 100, intensity);
+ *newR = crossDot(pal1p[counter], pal2p[counter], 100, intensity);
+ *newG = crossDot(pal1p[counter + 1], pal2p[counter + 1], 100, intensity);
+ *newB = crossDot(pal1p[counter + 2], pal2p[counter + 2], 100, intensity);
*newA = 0;
newR += 4;
@@ -161,19 +171,19 @@ void Screens::adjustCrossPalette(uint8 *pal1, uint8 *pal2) {
counter += 4;
}
- _engine->setPalette(localPalette);
+ _engine->setPalette(pal);
_engine->_system->delayMillis(1000 / 50);
intensity++;
} while (intensity <= 100);
}
-void Screens::fadeToBlack(uint8 *pal) {
+void Screens::fadeToBlack(uint32 *pal) {
int32 i = 0;
if (palReseted == 0) {
for (i = 100; i >= 0; i -= 3) {
- adjustPalette(0, 0, 0, (uint8 *)pal, i);
+ adjustPalette(0, 0, 0, pal, i);
_engine->_system->delayMillis(1000 / 50);
}
}
@@ -181,21 +191,21 @@ void Screens::fadeToBlack(uint8 *pal) {
palReseted = 1;
}
-void Screens::fadeToPal(uint8 *pal) {
+void Screens::fadeToPal(uint32 *pal) {
int32 i = 100;
for (i = 0; i <= 100; i += 3) {
- adjustPalette(0, 0, 0, (uint8 *)pal, i);
+ adjustPalette(0, 0, 0, pal, i);
_engine->_system->delayMillis(1000 / 50);
}
- _engine->setPalette((uint8 *)pal);
+ _engine->setPalette(pal);
palReseted = 0;
}
void Screens::blackToWhite() {
- uint8 pal[NUMOFCOLORS * 4];
+ uint32 pal[NUMOFCOLORS];
for (int32 i = 0; i < NUMOFCOLORS; i += 3) {
memset(pal, i, sizeof(pal));
@@ -206,27 +216,27 @@ void Screens::blackToWhite() {
void Screens::setBackPal() {
memset(palette, 0, sizeof(palette));
- memset(paletteRGB, 0, sizeof(paletteRGB));
+ memset(paletteRGBA, 0, sizeof(paletteRGBA));
- _engine->setPalette(paletteRGB);
+ _engine->setPalette(paletteRGBA);
palReseted = 1;
}
-void Screens::fadePalRed(uint8 *pal) {
+void Screens::fadePalRed(uint32 *pal) {
int32 i = 100;
for (i = 100; i >= 0; i -= 2) {
- adjustPalette(0xFF, 0, 0, (uint8 *)pal, i);
+ adjustPalette(0xFF, 0, 0, pal, i);
_engine->_system->delayMillis(1000 / 50);
}
}
-void Screens::fadeRedPal(uint8 *pal) {
+void Screens::fadeRedPal(uint32 *pal) {
int32 i = 0;
for (i = 0; i <= 100; i += 2) {
- adjustPalette(0xFF, 0, 0, (uint8 *)pal, i);
+ adjustPalette(0xFF, 0, 0, pal, i);
_engine->_system->delayMillis(1000 / 50);
}
}
diff --git a/engines/twine/screens.h b/engines/twine/screens.h
index a55ceecc17..6a3e6ba27d 100644
--- a/engines/twine/screens.h
+++ b/engines/twine/screens.h
@@ -42,10 +42,10 @@ public:
uint8 palette[NUMOFCOLORS * 3]{0};
/** converted in-game palette */
- uint8 paletteRGB[NUMOFCOLORS * 3]{0};
+ uint32 paletteRGBA[NUMOFCOLORS]{0};
/** converted custom palette */
- uint8 paletteRGBCustom[NUMOFCOLORS * 3]{0};
+ uint32 paletteRGBACustom[NUMOFCOLORS]{0};
/** flag to check if a custom palette is in use */
int16 palCustom = 0;
@@ -63,12 +63,12 @@ public:
uint8 *mainPalette = nullptr;
/** converted in-game palette */
- uint8 mainPaletteRGB[NUMOFCOLORS * 3]{0};
+ uint32 mainPaletteRGBA[NUMOFCOLORS]{0};
/** Load and display Adeline Logo */
void adelineLogo();
- void copyPal(const uint8 *in, uint8 *out);
+ void convertPalToRGBA(const uint8 *in, uint32 *out);
/**
* Load a custom palette
@@ -97,13 +97,13 @@ public:
* Fade image in
* @param palette current palette to fade in
*/
- void fadeIn(uint8 *palette);
+ void fadeIn(uint32 *palette);
/**
* Fade image out
* @param palette current palette to fade out
*/
- void fadeOut(uint8 *palette);
+ void fadeOut(uint32 *palette);
/**
* Calculate a new color component according with an intensity
@@ -123,26 +123,26 @@ public:
* @param palette palette to adjust
* @param intensity intensity value to adjust
*/
- void adjustPalette(uint8 R, uint8 G, uint8 B, uint8 *palette, int32 intensity);
+ void adjustPalette(uint8 R, uint8 G, uint8 B, const uint32 *palette, int32 intensity);
/**
* Adjust between two palettes
* @param pal1 palette from adjust
* @param pal2 palette to adjust
*/
- void adjustCrossPalette(uint8 *pal1, uint8 *pal2);
+ void adjustCrossPalette(const uint32 *pal1, const uint32 *pal2);
/**
* Fade image to black
* @param palette current palette to fade
*/
- void fadeToBlack(uint8 *palette);
+ void fadeToBlack(uint32 *palette);
/**
* Fade image with another palette source
* @param palette current palette to fade
*/
- void fadeToPal(uint8 *palette);
+ void fadeToPal(uint32 *palette);
/** Fade black palette to white palette */
void blackToWhite();
@@ -154,13 +154,13 @@ public:
* Fade palette to red palette
* @param palette current palette to fade
*/
- void fadePalRed(uint8 *palette);
+ void fadePalRed(uint32 *palette);
/**
* Fade red to palette
* @param palette current palette to fade
*/
- void fadeRedPal(uint8 *palette);
+ void fadeRedPal(uint32 *palette);
/**
* Copy a determinate screen buffer to another
diff --git a/engines/twine/script_life.cpp b/engines/twine/script_life.cpp
index c05592d939..016da2ba91 100644
--- a/engines/twine/script_life.cpp
+++ b/engines/twine/script_life.cpp
@@ -942,12 +942,12 @@ static int32 lZOOM(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->zoomScreen = *(scriptPtr++);
if (engine->zoomScreen && !engine->_redraw->drawInGameTransBox && engine->cfgfile.SceZoom) {
- engine->_screens->fadeToBlack(engine->_screens->mainPaletteRGB);
+ engine->_screens->fadeToBlack(engine->_screens->mainPaletteRGBA);
engine->initMCGA();
engine->_screens->setBackPal();
engine->_screens->lockPalette = 1;
} else if (!engine->zoomScreen && engine->_redraw->drawInGameTransBox) {
- engine->_screens->fadeToBlack(engine->_screens->mainPaletteRGB);
+ engine->_screens->fadeToBlack(engine->_screens->mainPaletteRGBA);
engine->initSVGA();
engine->_screens->setBackPal();
engine->_screens->lockPalette = 1;
@@ -1027,7 +1027,7 @@ static int32 lPLAY_FLA(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor)
scriptPtr += nameSize + 1;
engine->_flaMovies->playFlaMovie(movie);
- engine->setPalette(engine->_screens->paletteRGB);
+ engine->setPalette(engine->_screens->paletteRGBA);
engine->_screens->clearScreen();
engine->flip();
@@ -1218,7 +1218,7 @@ static int32 lGRM_OFF(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
/*0x52*/
static int32 lFADE_PAL_RED(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->freezeTime();
- engine->_screens->fadePalRed(engine->_screens->mainPaletteRGB);
+ engine->_screens->fadePalRed(engine->_screens->mainPaletteRGBA);
engine->_screens->useAlternatePalette = 0;
engine->unfreezeTime();
return 0;
@@ -1228,8 +1228,8 @@ static int32 lFADE_PAL_RED(TwinEEngine *engine, int32 actorIdx, ActorStruct *act
static int32 lFADE_ALARM_RED(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->freezeTime();
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
- engine->_screens->copyPal(engine->_screens->palette, engine->_screens->paletteRGB);
- engine->_screens->fadePalRed(engine->_screens->paletteRGB);
+ engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
+ engine->_screens->fadePalRed(engine->_screens->paletteRGBA);
engine->_screens->useAlternatePalette = 1;
engine->unfreezeTime();
return 0;
@@ -1239,8 +1239,8 @@ static int32 lFADE_ALARM_RED(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
static int32 lFADE_ALARM_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->freezeTime();
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
- engine->_screens->copyPal(engine->_screens->palette, engine->_screens->paletteRGB);
- engine->_screens->adjustCrossPalette(engine->_screens->paletteRGB, engine->_screens->mainPaletteRGB);
+ engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
+ engine->_screens->adjustCrossPalette(engine->_screens->paletteRGBA, engine->_screens->mainPaletteRGBA);
engine->_screens->useAlternatePalette = 0;
engine->unfreezeTime();
return 0;
@@ -1249,7 +1249,7 @@ static int32 lFADE_ALARM_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
/*0x55*/
static int32 lFADE_RED_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->freezeTime();
- engine->_screens->fadeRedPal(engine->_screens->mainPaletteRGB);
+ engine->_screens->fadeRedPal(engine->_screens->mainPaletteRGBA);
engine->_screens->useAlternatePalette = 0;
engine->unfreezeTime();
return 0;
@@ -1259,8 +1259,8 @@ static int32 lFADE_RED_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *act
static int32 lFADE_RED_ALARM(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->freezeTime();
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
- engine->_screens->copyPal(engine->_screens->palette, engine->_screens->paletteRGB);
- engine->_screens->fadeRedPal(engine->_screens->paletteRGB);
+ engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
+ engine->_screens->fadeRedPal(engine->_screens->paletteRGBA);
engine->_screens->useAlternatePalette = 1;
engine->unfreezeTime();
return 0;
@@ -1270,8 +1270,8 @@ static int32 lFADE_RED_ALARM(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
static int32 lFADE_PAL_ALARM(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->freezeTime();
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
- engine->_screens->copyPal(engine->_screens->palette, engine->_screens->paletteRGB);
- engine->_screens->adjustCrossPalette(engine->_screens->mainPaletteRGB, engine->_screens->paletteRGB);
+ engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
+ engine->_screens->adjustCrossPalette(engine->_screens->mainPaletteRGBA, engine->_screens->paletteRGBA);
engine->_screens->useAlternatePalette = 1;
engine->unfreezeTime();
return 0;
@@ -1323,8 +1323,8 @@ static int32 lSET_DARK_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *act
engine->freezeTime();
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_DARKPAL);
if (!engine->_screens->lockPalette) {
- engine->_screens->copyPal(engine->_screens->palette, engine->_screens->paletteRGB);
- engine->setPalette(engine->_screens->paletteRGB);
+ engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
+ engine->setPalette(engine->_screens->paletteRGBA);
}
engine->_screens->useAlternatePalette = 1;
engine->unfreezeTime();
@@ -1335,7 +1335,7 @@ static int32 lSET_DARK_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *act
static int32 lSET_NORMAL_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->_screens->useAlternatePalette = 0;
if (!engine->_screens->lockPalette) {
- engine->setPalette(engine->_screens->mainPaletteRGB);
+ engine->setPalette(engine->_screens->mainPaletteRGBA);
}
return 0;
}
@@ -1345,7 +1345,7 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, int32 actorIdx, ActorStruct *
int32 tmpFlagDisplayText;
engine->freezeTime();
- engine->_screens->fadeToBlack(engine->_screens->paletteRGB);
+ engine->_screens->fadeToBlack(engine->_screens->paletteRGBA);
engine->_screens->loadImage(25);
engine->_text->textClipFull();
engine->_text->setFontCrossColor(15);
@@ -1355,9 +1355,9 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, int32 actorIdx, ActorStruct *
engine->_text->drawTextFullscreen(6);
engine->_text->newGameVar4 = 1;
engine->_text->textClipSmall();
- engine->_screens->fadeToBlack(engine->_screens->paletteRGBCustom);
+ engine->_screens->fadeToBlack(engine->_screens->paletteRGBACustom);
engine->_screens->clearScreen();
- engine->setPalette(engine->_screens->paletteRGB);
+ engine->setPalette(engine->_screens->paletteRGBA);
engine->cfgfile.FlagDisplayText = tmpFlagDisplayText;
do {
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index fe71e20e23..9e689e0dff 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -32,6 +32,7 @@
#include "engines/util.h"
#include "graphics/managed_surface.h"
#include "graphics/palette.h"
+#include "graphics/pixelformat.h"
#include "graphics/surface.h"
#include "gui/debugger.h"
#include "twine/actor.h"
@@ -402,7 +403,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
break;
case kiBookOfBu: {
- _screens->fadeToBlack(_screens->paletteRGB);
+ _screens->fadeToBlack(_screens->paletteRGBA);
_screens->loadImage(RESSHQR_INTROSCREEN1IMG);
_text->initTextBank(2);
_text->newGameVar4 = 0;
@@ -415,10 +416,10 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_text->textClipSmall();
_text->newGameVar4 = 1;
_text->initTextBank(_text->currentTextBank + 3);
- _screens->fadeToBlack(_screens->paletteRGBCustom);
+ _screens->fadeToBlack(_screens->paletteRGBACustom);
_screens->clearScreen();
flip();
- setPalette(_screens->paletteRGB);
+ setPalette(_screens->paletteRGBA);
_screens->lockPalette = 1;
} break;
case kiProtoPack:
@@ -794,20 +795,24 @@ void TwinEEngine::delaySkip(uint32 time) {
} while (stopTicks <= time);
}
-void TwinEEngine::setPalette(uint8 *palette) {
- g_system->getPaletteManager()->setPalette(palette, 0, 256);
- flip();
-}
-
-void TwinEEngine::fadeBlackToWhite() {
-#if 0
- SDL_Color colorPtr[256];
- SDL_UpdateRect(screen, 0, 0, 0, 0);
- for (int32 i = 0; i < 256; i += 3) {
- memset(colorPtr, i, sizeof(colorPtr));
- SDL_SetPalette(screen, SDL_PHYSPAL, colorPtr, 0, 256);
+void TwinEEngine::setPalette(const uint32 *palette) {
+#if 1
+ uint8 pal[NUMOFCOLORS * 3];
+ uint8* out = pal;
+ const uint8* in = (const uint8*)palette;
+ for (int i = 0; i < NUMOFCOLORS; i++) {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out += 3;
+ in += 4;
}
+ g_system->getPaletteManager()->setPalette(pal, 0, 256);
+#else
+ frontVideoBuffer.setPalette(palette, 0, 256);
+ workVideoBuffer.setPalette(palette, 0, 256);
#endif
+ flip();
}
void TwinEEngine::flip() {
@@ -823,11 +828,38 @@ void TwinEEngine::copyBlockPhys(int32 left, int32 top, int32 right, int32 bottom
g_system->updateScreen();
}
-void TwinEEngine::crossFade(const Graphics::ManagedSurface &buffer, uint8 *palette) {
- g_system->getPaletteManager()->setPalette(palette, 0, 256);
- // TODO: implement cross fading
- g_system->copyRectToScreen(buffer.getPixels(), buffer.pitch, 0, 0, buffer.w, buffer.h);
- g_system->updateScreen();
+void TwinEEngine::crossFade(const Graphics::ManagedSurface &buffer, const uint32 *palette) {
+ Graphics::ManagedSurface backupSurface;
+ Graphics::ManagedSurface newSurface;
+ Graphics::ManagedSurface tempSurface;
+ Graphics::ManagedSurface surfaceTable;
+
+ Graphics::PixelFormat fmt(4, 8, 8, 8, 8, 24, 16, 8, 0);
+ backupSurface.create(frontVideoBuffer.w, frontVideoBuffer.h, fmt);
+ newSurface.create(frontVideoBuffer.w, frontVideoBuffer.h, fmt);
+ tempSurface.create(frontVideoBuffer.w, frontVideoBuffer.h, Graphics::PixelFormat::createFormatCLUT8());
+ tempSurface.setPalette(palette, 0, 256);
+
+ surfaceTable.create(frontVideoBuffer.w, frontVideoBuffer.h, fmt);
+
+ backupSurface.transBlitFrom(frontVideoBuffer);
+ newSurface.transBlitFrom(tempSurface);
+
+ for (int32 i = 0; i < 8; i++) {
+ surfaceTable.blitFrom(backupSurface);
+ surfaceTable.transBlitFrom(newSurface, 0, false, 0, i * 32);
+ frontVideoBuffer.blitFrom(surfaceTable);
+ flip();
+ delaySkip(50);
+ }
+
+ frontVideoBuffer.blitFrom(newSurface);
+ flip();
+
+ backupSurface.free();
+ newSurface.free();
+ tempSurface.free();
+ surfaceTable.free();
}
/** Pressed key map - scanCodeTab1 */
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 8bdcd37206..db95720209 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -262,10 +262,7 @@ public:
* Set a new palette in the SDL screen buffer
* @param palette palette to set
*/
- void setPalette(uint8 *palette);
-
- /** Fade screen from black to white */
- void fadeBlackToWhite();
+ void setPalette(const uint32 *palette);
/** Blit surface in the screen */
void flip();
@@ -283,7 +280,7 @@ public:
* @param buffer screen buffer
* @param palette new palette to cross fade
*/
- void crossFade(const Graphics::ManagedSurface &buffer, uint8 *palette);
+ void crossFade(const Graphics::ManagedSurface &buffer, const uint32 *palette);
/** Handle keyboard pressed keys */
void readKeys();
Commit: 030b23b4db4a1d46eddface22a14a7dba6639f07
https://github.com/scummvm/scummvm/commit/030b23b4db4a1d46eddface22a14a7dba6639f07
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: refactored the input handling a little bit
Changed paths:
engines/twine/gamestate.cpp
engines/twine/menu.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 5141e75732..a4a8c5359c 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -426,12 +426,12 @@ void GameState::processFoundItem(int32 item) {
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
/*do {
- readKeys();
+ _engine->readKeys();
if (_engine->shouldQuit()) {
break;
}
delaySkip(1);
- } while (!skipIntro);*/
+ } while (!_engine->_keyboard.skipIntro);*/
if (_engine->cfgfile.LanguageCDId && _engine->_sound->isSamplePlaying(_engine->_text->currDialTextEntry)) {
_engine->_text->stopVox(_engine->_text->currDialTextEntry);
@@ -499,7 +499,7 @@ void GameState::processGameoverAnimation() { // makeGameOver
int32 startLbaTime = _engine->lbaTime;
_engine->_interface->setClip(120, 120, 519, 359);
- while (_engine->_keyboard.skipIntro != 1 && (_engine->lbaTime - startLbaTime) <= 0x1F4) {
+ while (_engine->_keyboard.skipIntro != 1 && (_engine->lbaTime - startLbaTime) <= 500) {
_engine->readKeys();
avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index ae12a4afe1..984263a00f 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -936,7 +936,7 @@ void Menu::processBehaviourMenu() {
tmpTime = _engine->lbaTime;
- while (_engine->_keyboard.skippedKey & 4 || (_engine->_keyboard.skipIntro >= 59 && _engine->_keyboard.skipIntro <= 62)) {
+ while (_engine->_keyboard.skippedKey & 4 || (_engine->_keyboard.skipIntro >= twineactions[TwinEActionType::QuickBehaviourNormal].localKey && _engine->_keyboard.skipIntro <= twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey)) {
_engine->readKeys();
_engine->_keyboard.key = _engine->_keyboard.pressedKey;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 9e689e0dff..c68af86840 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -798,8 +798,8 @@ void TwinEEngine::delaySkip(uint32 time) {
void TwinEEngine::setPalette(const uint32 *palette) {
#if 1
uint8 pal[NUMOFCOLORS * 3];
- uint8* out = pal;
- const uint8* in = (const uint8*)palette;
+ uint8 *out = pal;
+ const uint8 *in = (const uint8 *)palette;
for (int i = 0; i < NUMOFCOLORS; i++) {
out[0] = in[0];
out[1] = in[1];
@@ -899,41 +899,44 @@ static const uint8 pressedKeyMap[] = {
static_assert(ARRAYSIZE(pressedKeyMap) == 29, "Expected size of key map");
/** Pressed key char map - scanCodeTab2 */
-static const uint16 pressedKeyCharMap[] = {
- 0x0100, // up
- 0x0200, // down
- 0x0400, // left
- 0x0800, // right
- 0x0500, // home
- 0x0900, // pageup
- 0x0A00, // pagedown
- 0x0600, // end
-
- 0x0101, // space bar
- 0x0201, // enter
- 0x0401, // ctrl
- 0x0801, // alt
- 0x1001, // del
- 0x2001, // left shift
- 0x2001, // right shift
-
- 0x0102, // F1
- 0x0202, // F2
- 0x0402, // F3
- 0x0802, // F4
- 0x1002, // F5
- 0x2002, // F6
- 0x4002, // F7
- 0x8002, // F8
-
- 0x0103, // F9
- 0x0203, // F10
- 0x0403, // ?
- 0x0803, // ?
- 0x00FF, // left shift
- 0x00FF,
- 0x0,
- 0x0,
+static const union KeyProperties {
+ struct {
+ uint8 high;
+ uint8 low; // defines whether this is pressed or skipped key
+ } details;
+ uint16 mask;
+} pressedKeyCharMap[] = {
+ {{0x01,0x00}}, // up
+ {{0x02,0x00}}, // down
+ {{0x04,0x00}}, // left
+ {{0x08,0x00}}, // right
+ {{0x05,0x00}}, // home
+ {{0x09,0x00}}, // pageup
+ {{0x0A,0x00}}, // pagedown
+ {{0x06,0x00}}, // end
+ {{0x01,0x01}}, // space bar
+ {{0x02,0x01}}, // enter
+ {{0x04,0x01}}, // ctrl
+ {{0x08,0x01}}, // alt
+ {{0x10,0x01}}, // del
+ {{0x20,0x01}}, // left shift
+ {{0x20,0x01}}, // right shift
+ {{0x01,0x02}}, // F1
+ {{0x02,0x02}}, // F2
+ {{0x04,0x02}}, // F3
+ {{0x08,0x02}}, // F4
+ {{0x10,0x02}}, // F5
+ {{0x20,0x02}}, // F6
+ {{0x40,0x02}}, // F7
+ {{0x80,0x02}}, // F8
+ {{0x01,0x03}}, // F9
+ {{0x02,0x03}}, // F10
+ {{0x04,0x03}}, // ?
+ {{0x08,0x03}}, // ?
+ {{0x00,0xFF}}, // left shift
+ {{0x00,0xFF}},
+ {{0x00,0x00}},
+ {{0x00,0x00}}
};
static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
@@ -948,7 +951,7 @@ void TwinEEngine::readKeys() {
Common::Event event;
while (g_system->getEventManager()->pollEvent(event)) {
- int32 localKey = 0;
+ uint8 localKey = 0;
switch (event.type) {
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
actionStates[event.customType] = false;
@@ -1008,28 +1011,17 @@ void TwinEEngine::readKeys() {
for (int i = 0; i < ARRAYSIZE(pressedKeyMap); i++) {
if (pressedKeyMap[i] == localKey) {
- int16 temp = pressedKeyCharMap[i];
- uint8 temp2 = temp & 0x00FF;
-
- if (temp2 == 0) {
+ if (pressedKeyCharMap[i].details.low == 0) {
// pressed valid keys
- if (!(localKey & 0x80)) {
- _keyboard.pressedKey |= (temp & 0xFF00) >> 8;
- } else {
- _keyboard.pressedKey &= -((temp & 0xFF00) >> 8);
- }
- }
- // pressed inactive keys
- else {
- _keyboard.skippedKey |= (temp & 0xFF00) >> 8;
+ _keyboard.pressedKey |= pressedKeyCharMap[i].details.high;
+ } else {
+ // pressed inactive keys
+ _keyboard.skippedKey |= pressedKeyCharMap[i].details.high;
}
break;
}
}
-
- //if (!found) {
_keyboard.skipIntro = localKey;
- //}
}
}
Commit: 903e0cc18a4519f32e27cb0e73264886013a3152
https://github.com/scummvm/scummvm/commit/903e0cc18a4519f32e27cb0e73264886013a3152
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: further refactored the input handling
Changed paths:
engines/twine/twine.cpp
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index c68af86840..357eb99957 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -862,82 +862,43 @@ void TwinEEngine::crossFade(const Graphics::ManagedSurface &buffer, const uint32
surfaceTable.free();
}
-/** Pressed key map - scanCodeTab1 */
-static const uint8 pressedKeyMap[] = {
- 0x48, // 0
- 0x50,
- 0x4B,
- 0x4D,
- 0x47,
- 0x49,
- 0x51,
- 0x4F, // 7
-
- 0x39, // 8
- 0x1C,
- 0x1D,
- 0x38,
- 0x53,
- 0x2A,
- 0x36, // 14
-
- 0x3B, // 15
- 0x3C,
- 0x3D,
- 0x3E,
- 0x3F,
- 0x40, // LBAKEY_F6
- 0x41,
- 0x42,
- 0x43,
- 0x44,
- 0x57,
- 0x58,
- 0x2A,
- 0x0, // 28
-};
-static_assert(ARRAYSIZE(pressedKeyMap) == 29, "Expected size of key map");
-
/** Pressed key char map - scanCodeTab2 */
-static const union KeyProperties {
- struct {
- uint8 high;
- uint8 low; // defines whether this is pressed or skipped key
- } details;
- uint16 mask;
+static const struct KeyProperties {
+ uint8 high;
+ bool pressed;
+ uint8 key;
} pressedKeyCharMap[] = {
- {{0x01,0x00}}, // up
- {{0x02,0x00}}, // down
- {{0x04,0x00}}, // left
- {{0x08,0x00}}, // right
- {{0x05,0x00}}, // home
- {{0x09,0x00}}, // pageup
- {{0x0A,0x00}}, // pagedown
- {{0x06,0x00}}, // end
- {{0x01,0x01}}, // space bar
- {{0x02,0x01}}, // enter
- {{0x04,0x01}}, // ctrl
- {{0x08,0x01}}, // alt
- {{0x10,0x01}}, // del
- {{0x20,0x01}}, // left shift
- {{0x20,0x01}}, // right shift
- {{0x01,0x02}}, // F1
- {{0x02,0x02}}, // F2
- {{0x04,0x02}}, // F3
- {{0x08,0x02}}, // F4
- {{0x10,0x02}}, // F5
- {{0x20,0x02}}, // F6
- {{0x40,0x02}}, // F7
- {{0x80,0x02}}, // F8
- {{0x01,0x03}}, // F9
- {{0x02,0x03}}, // F10
- {{0x04,0x03}}, // ?
- {{0x08,0x03}}, // ?
- {{0x00,0xFF}}, // left shift
- {{0x00,0xFF}},
- {{0x00,0x00}},
- {{0x00,0x00}}
-};
+ {0x01, false, 0x48}, // up
+ {0x02, false, 0x50}, // down
+ {0x04, false, 0x4B}, // left
+ {0x08, false, 0x4D}, // right
+ {0x05, false, 0x47}, // home
+ {0x09, false, 0x49}, // pageup
+ {0x0A, false, 0x51}, // pagedown
+ {0x06, false, 0x4F}, // end
+ {0x01, true, 0x39}, // space bar
+ {0x02, true, 0x1C}, // enter
+ {0x04, true, 0x1D}, // ctrl
+ {0x08, true, 0x38}, // alt
+ {0x10, true, 0x53}, // del
+ {0x20, true, 0x2A}, // left shift
+ {0x20, true, 0x36}, // right shift
+ {0x01, true, 0x3B}, // F1
+ {0x02, true, 0x3C}, // F2
+ {0x04, true, 0x3D}, // F3
+ {0x08, true, 0x3E}, // F4
+ {0x10, true, 0x3F}, // F5
+ {0x20, true, 0x40}, // F6
+ {0x40, true, 0x41}, // F7
+ {0x80, true, 0x42}, // F8
+ {0x01, true, 0x43}, // F9
+ {0x02, true, 0x44}, // F10
+ {0x04, true, 0x57}, // ?
+ {0x08, true, 0x58}, // ?
+ {0x00, true, 0x2A}, // left shift
+ {0x00, true, 0x00},
+ {0x00, false, 0x00},
+ {0x00, false, 0x00}};
static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
void TwinEEngine::readKeys() {
@@ -1009,14 +970,12 @@ void TwinEEngine::readKeys() {
continue;
}
- for (int i = 0; i < ARRAYSIZE(pressedKeyMap); i++) {
- if (pressedKeyMap[i] == localKey) {
- if (pressedKeyCharMap[i].details.low == 0) {
- // pressed valid keys
- _keyboard.pressedKey |= pressedKeyCharMap[i].details.high;
+ for (int i = 0; i < ARRAYSIZE(pressedKeyCharMap); i++) {
+ if (pressedKeyCharMap[i].key == localKey) {
+ if (pressedKeyCharMap[i].pressed) {
+ _keyboard.pressedKey |= pressedKeyCharMap[i].high;
} else {
- // pressed inactive keys
- _keyboard.skippedKey |= pressedKeyCharMap[i].details.high;
+ _keyboard.skippedKey |= pressedKeyCharMap[i].high;
}
break;
}
Commit: d8ad31f056f36aab73e4b8366ca29b505fd02dcb
https://github.com/scummvm/scummvm/commit/d8ad31f056f36aab73e4b8366ca29b505fd02dcb
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: moved actionstates into keyboard struct
Changed paths:
engines/twine/keyboard.h
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/keyboard.h b/engines/twine/keyboard.h
index c2442e25af..457e3d304b 100644
--- a/engines/twine/keyboard.h
+++ b/engines/twine/keyboard.h
@@ -96,6 +96,7 @@ static constexpr const struct ActionMapping {
static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected action mapping array size");
struct Keyboard {
+ bool actionStates[TwinEActionType::Max] {false};
/** Skipped key - key1 */
int16 skippedKey = 0;
/** Pressed key - printTextVar12 */
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 357eb99957..114dd44515 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -915,7 +915,7 @@ void TwinEEngine::readKeys() {
uint8 localKey = 0;
switch (event.type) {
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
- actionStates[event.customType] = false;
+ _keyboard.actionStates[event.customType] = false;
localKey = twineactions[event.customType].localKey;
break;
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
@@ -929,12 +929,12 @@ void TwinEEngine::readKeys() {
break;
default:
localKey = twineactions[event.customType].localKey;
- actionStates[event.customType] = true;
+ _keyboard.actionStates[event.customType] = true;
break;
}
} else {
localKey = twineactions[event.customType].localKey;
- actionStates[event.customType] = true;
+ _keyboard.actionStates[event.customType] = true;
}
break;
case Common::EVENT_KEYUP:
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index db95720209..df89c6d3b7 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -153,7 +153,6 @@ private:
int32 isTimeFreezed = 0;
int32 saveFreezedTime = 0;
ActorMoveStruct loopMovePtr; // mainLoopVar1
- bool actionStates[TwinEActionType::Max] {false};
public:
TwinEEngine(OSystem *system, Common::Language language, uint32 flags);
Commit: 2ac8330823e1b7bd72809af7920d71e012020405
https://github.com/scummvm/scummvm/commit/2ac8330823e1b7bd72809af7920d71e012020405
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: renamed member of Keyboard struct
Changed paths:
engines/twine/flamovies.cpp
engines/twine/gamestate.cpp
engines/twine/keyboard.h
engines/twine/menu.cpp
engines/twine/menuoptions.cpp
engines/twine/movements.cpp
engines/twine/redraw.cpp
engines/twine/script_life.cpp
engines/twine/text.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 2f799feab3..9061585f11 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -314,7 +314,7 @@ void FlaMovies::playFlaMovie(const char *flaName) {
break;
}
- if (_engine->_keyboard.skipIntro) {
+ if (_engine->_keyboard.internalKeyCode) {
break;
}
} while (true);
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index a4a8c5359c..273e80f7b0 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -416,7 +416,7 @@ void GameState::processFoundItem(int32 item) {
while (_engine->_text->playVoxSimple(_engine->_text->currDialTextEntry)) {
_engine->readKeys();
- if (_engine->_keyboard.skipIntro == 1) {
+ if (_engine->_keyboard.internalKeyCode == 1) {
break;
}
_engine->delaySkip(1);
@@ -431,7 +431,7 @@ void GameState::processFoundItem(int32 item) {
break;
}
delaySkip(1);
- } while (!_engine->_keyboard.skipIntro);*/
+ } while (!_engine->_keyboard.internalKeyCode);*/
if (_engine->cfgfile.LanguageCDId && _engine->_sound->isSamplePlaying(_engine->_text->currDialTextEntry)) {
_engine->_text->stopVox(_engine->_text->currDialTextEntry);
@@ -499,7 +499,7 @@ void GameState::processGameoverAnimation() { // makeGameOver
int32 startLbaTime = _engine->lbaTime;
_engine->_interface->setClip(120, 120, 519, 359);
- while (_engine->_keyboard.skipIntro != 1 && (_engine->lbaTime - startLbaTime) <= 500) {
+ while (_engine->_keyboard.internalKeyCode != 1 && (_engine->lbaTime - startLbaTime) <= 500) {
_engine->readKeys();
avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
diff --git a/engines/twine/keyboard.h b/engines/twine/keyboard.h
index 457e3d304b..7ee95cc181 100644
--- a/engines/twine/keyboard.h
+++ b/engines/twine/keyboard.h
@@ -97,18 +97,11 @@ static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected actio
struct Keyboard {
bool actionStates[TwinEActionType::Max] {false};
- /** Skipped key - key1 */
int16 skippedKey = 0;
- /** Pressed key - printTextVar12 */
int16 pressedKey = 0;
- //int printTextVar13;
- /** Skip intro variable */
- int16 skipIntro = 0;
- /** Current key value */
+ int16 internalKeyCode = 0;
int16 currentKey = 0;
- /** Auxiliar key value */
int16 key = 0;
-
int32 heroPressedKey = 0;
int32 heroPressedKey2 = 0;
};
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 984263a00f..a988741f0c 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -440,7 +440,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (_engine->lbaTime - localTime > 11650) {
return kBackground;
}
- if (_engine->_keyboard.skipIntro == '.') {
+ if (_engine->_keyboard.internalKeyCode == '.') {
if (_engine->_keyboard.skippedKey != ' ') {
return kBackground;
}
@@ -545,7 +545,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
do {
_engine->readKeys();
drawButton(localData, 1);
- } while (_engine->_keyboard.pressedKey == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.skipIntro == 0);
+ } while (_engine->_keyboard.pressedKey == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.internalKeyCode == 0);
buttonNeedRedraw = 0;
} else {
if (musicChanged) {
@@ -936,7 +936,7 @@ void Menu::processBehaviourMenu() {
tmpTime = _engine->lbaTime;
- while (_engine->_keyboard.skippedKey & 4 || (_engine->_keyboard.skipIntro >= twineactions[TwinEActionType::QuickBehaviourNormal].localKey && _engine->_keyboard.skipIntro <= twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey)) {
+ while (_engine->_keyboard.skippedKey & 4 || (_engine->_keyboard.internalKeyCode >= twineactions[TwinEActionType::QuickBehaviourNormal].localKey && _engine->_keyboard.internalKeyCode <= twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey)) {
_engine->readKeys();
_engine->_keyboard.key = _engine->_keyboard.pressedKey;
@@ -1068,14 +1068,14 @@ void Menu::processInventoryMenu() {
_engine->_text->setFontCrossColor(4);
_engine->_text->initDialogueBox();
- while (_engine->_keyboard.skipIntro != 1) {
+ while (_engine->_keyboard.internalKeyCode != 1) {
_engine->readKeys();
prevSelectedItem = inventorySelectedItem;
if (!di) {
_engine->_keyboard.key = _engine->_keyboard.pressedKey;
_engine->loopPressedKey = _engine->_keyboard.skippedKey;
- _engine->loopCurrentKey = _engine->_keyboard.skipIntro;
+ _engine->loopCurrentKey = _engine->_keyboard.internalKeyCode;
if (_engine->_keyboard.key != 0 || _engine->_keyboard.skippedKey != 0) {
di = 1;
@@ -1181,7 +1181,7 @@ void Menu::processInventoryMenu() {
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
- while (_engine->_keyboard.skipIntro != 0 && _engine->_keyboard.skippedKey != 0) {
+ while (_engine->_keyboard.internalKeyCode != 0 && _engine->_keyboard.skippedKey != 0) {
_engine->readKeys();
_engine->_system->delayMillis(1);
_engine->flip(); // TODO: needed?
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 767b3fcd64..775af1fcba 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -63,13 +63,13 @@ void MenuOptions::newGame() {
_engine->_text->drawTextFullscreen(150);
_engine->readKeys();
- if (_engine->_keyboard.skipIntro != 1) {
+ if (_engine->_keyboard.internalKeyCode != 1) {
// intro screen 1 - twinsun
_engine->_screens->loadImage(RESSHQR_INTROSCREEN2IMG);
_engine->_text->drawTextFullscreen(151);
_engine->readKeys();
- if (_engine->_keyboard.skipIntro != 1) {
+ if (_engine->_keyboard.internalKeyCode != 1) {
_engine->_screens->loadImage(RESSHQR_INTROSCREEN3IMG);
_engine->_text->drawTextFullscreen(152);
}
@@ -231,7 +231,7 @@ int32 MenuOptions::enterPlayerName(int32 textIdx) {
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.skipIntro);
+ } while (_engine->_keyboard.internalKeyCode);
if (_engine->shouldQuit()) {
break;
}
@@ -246,7 +246,7 @@ int32 MenuOptions::enterPlayerName(int32 textIdx) {
}
} while (_engine->_keyboard.pressedKey);
- while (!_engine->_keyboard.skipIntro) {
+ while (!_engine->_keyboard.internalKeyCode) {
_engine->readKeys();
if (_engine->shouldQuit()) {
break;
@@ -256,7 +256,7 @@ int32 MenuOptions::enterPlayerName(int32 textIdx) {
}
// FIXME: remove this lines after implementing everything
- if (_engine->_keyboard.skipIntro)
+ if (_engine->_keyboard.internalKeyCode)
break;
}
@@ -290,7 +290,7 @@ void MenuOptions::newGameMenu() {
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.skipIntro != 0);
+ } while (_engine->_keyboard.internalKeyCode != 0);
}
}
@@ -328,7 +328,7 @@ void MenuOptions::continueGameMenu() {
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.skipIntro != 0);
+ } while (_engine->_keyboard.internalKeyCode != 0);
}
}
diff --git a/engines/twine/movements.cpp b/engines/twine/movements.cpp
index 169f6c13fe..b7eef19740 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/movements.cpp
@@ -296,7 +296,7 @@ void Movements::processActorMovements(int32 actorIdx) {
heroAction = 0;
// If press W for action
- if (_engine->_keyboard.skipIntro == 0x11) {
+ if (_engine->_keyboard.internalKeyCode == 0x11) {
heroAction = 1;
}
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index a99fbebdc7..c9b6b444bf 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -534,7 +534,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
}
if (_engine->cfgfile.Debug) {
- _engine->_debugScene->displayZones(_engine->_keyboard.skipIntro);
+ _engine->_debugScene->displayZones(_engine->_keyboard.internalKeyCode);
}
for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
diff --git a/engines/twine/script_life.cpp b/engines/twine/script_life.cpp
index 016da2ba91..267c2b5d2b 100644
--- a/engines/twine/script_life.cpp
+++ b/engines/twine/script_life.cpp
@@ -1362,7 +1362,7 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, int32 actorIdx, ActorStruct *
do {
engine->readKeys();
- } while (engine->_keyboard.skipIntro || engine->_keyboard.skippedKey);
+ } while (engine->_keyboard.internalKeyCode || engine->_keyboard.skippedKey);
engine->unfreezeTime();
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 3125d38221..6acc32fd5d 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -621,7 +621,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
if (_engine->shouldQuit()) {
break;
}
- if (_engine->_keyboard.skipIntro == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.pressedKey == 0) {
+ if (_engine->_keyboard.internalKeyCode == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.pressedKey == 0) {
break;
}
playVox(currDialTextEntry);
@@ -633,7 +633,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
if (_engine->shouldQuit()) {
break;
}
- if (_engine->_keyboard.skipIntro != 0 || _engine->_keyboard.skippedKey != 0 || _engine->_keyboard.pressedKey != 0) {
+ if (_engine->_keyboard.internalKeyCode != 0 || _engine->_keyboard.skippedKey != 0 || _engine->_keyboard.pressedKey != 0) {
break;
}
playVox(currDialTextEntry);
@@ -641,7 +641,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
} while (1);
}
- if (_engine->_keyboard.skipIntro == 1) {
+ if (_engine->_keyboard.internalKeyCode == 1) {
skipText = 1;
}
@@ -681,13 +681,13 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (_engine->_keyboard.skipIntro || _engine->_keyboard.skippedKey || _engine->_keyboard.pressedKey);
+ } while (_engine->_keyboard.internalKeyCode || _engine->_keyboard.skippedKey || _engine->_keyboard.pressedKey);
// RECHECK this later
// wait key to display next text
do {
_engine->readKeys();
- if (_engine->_keyboard.skipIntro != 0) {
+ if (_engine->_keyboard.internalKeyCode != 0) {
_engine->_interface->loadClip();
return;
}
@@ -701,7 +701,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
_engine->_system->delayMillis(1);
} while (!_engine->_keyboard.pressedKey);
} else { // RECHECK THIS
- while (playVox(currDialTextEntry) && _engine->_keyboard.skipIntro != 1) {
+ while (playVox(currDialTextEntry) && _engine->_keyboard.internalKeyCode != 1) {
if (_engine->shouldQuit()) {
break;
}
@@ -855,7 +855,7 @@ void Text::drawAskQuestion(int32 index) { // MyDial
}
playVox(currDialTextEntry);
_engine->_system->delayMillis(1);
- } while (_engine->_keyboard.skipIntro || _engine->_keyboard.skippedKey || _engine->_keyboard.pressedKey);
+ } while (_engine->_keyboard.internalKeyCode || _engine->_keyboard.skippedKey || _engine->_keyboard.pressedKey);
do {
_engine->readKeys();
@@ -864,7 +864,7 @@ void Text::drawAskQuestion(int32 index) { // MyDial
}
playVox(currDialTextEntry);
_engine->_system->delayMillis(1);
- } while (!_engine->_keyboard.skipIntro && !_engine->_keyboard.skippedKey && !_engine->_keyboard.pressedKey);
+ } while (!_engine->_keyboard.internalKeyCode && !_engine->_keyboard.skippedKey && !_engine->_keyboard.pressedKey);
}
_engine->_system->delayMillis(1);
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 114dd44515..83c4409bf2 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -325,13 +325,13 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
previousLoopPressedKey = loopPressedKey;
_keyboard.key = _keyboard.pressedKey;
loopPressedKey = _keyboard.skippedKey;
- loopCurrentKey = _keyboard.skipIntro;
+ loopCurrentKey = _keyboard.internalKeyCode;
_debug->processDebug(loopCurrentKey);
if (_menuOptions->canShowCredits != 0) {
// TODO: if current music playing != 8, than play_track(8);
- if (_keyboard.skipIntro != 0) {
+ if (_keyboard.internalKeyCode != 0) {
return 0;
}
if (_keyboard.pressedKey != 0) {
@@ -342,7 +342,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
} else {
// Process give up menu - Press ESC
- if (_keyboard.skipIntro == 1 && _scene->sceneHero->life > 0 && _scene->sceneHero->entity != -1 && !_scene->sceneHero->staticFlags.bIsHidden) {
+ if (_keyboard.internalKeyCode == 1 && _scene->sceneHero->life > 0 && _scene->sceneHero->entity != -1 && !_scene->sceneHero->staticFlags.bIsHidden) {
freezeTime();
if (_menu->giveupMenu()) {
unfreezeTime();
@@ -554,7 +554,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
break;
}
g_system->delayMillis(10);
- } while (_keyboard.skipIntro != 0x19 && !_keyboard.pressedKey);
+ } while (_keyboard.internalKeyCode != 0x19 && !_keyboard.pressedKey);
unfreezeTime();
_redraw->redrawEngineActions(1);
}
@@ -780,10 +780,10 @@ bool TwinEEngine::gameEngineLoop() { // mainLoop
void TwinEEngine::delaySkip(uint32 time) {
uint32 startTicks = _system->getMillis();
uint32 stopTicks = 0;
- _keyboard.skipIntro = 0;
+ _keyboard.internalKeyCode = 0;
do {
readKeys();
- if (_keyboard.skipIntro == 1) {
+ if (_keyboard.internalKeyCode == 1) {
break;
}
if (shouldQuit()) {
@@ -903,12 +903,12 @@ static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map
void TwinEEngine::readKeys() {
if (shouldQuit()) {
- _keyboard.skipIntro = 1;
+ _keyboard.internalKeyCode = 1;
_keyboard.skippedKey = 1;
return;
}
_keyboard.skippedKey = 0;
- _keyboard.skipIntro = 0;
+ _keyboard.internalKeyCode = 0;
Common::Event event;
while (g_system->getEventManager()->pollEvent(event)) {
@@ -943,7 +943,7 @@ void TwinEEngine::readKeys() {
case Common::EVENT_KEYDOWN: {
switch (event.kbd.keycode) {
case Common::KEYCODE_ESCAPE:
- _keyboard.skipIntro = 1;
+ _keyboard.internalKeyCode = 1;
break;
case Common::KEYCODE_PAGEUP:
localKey = 0x49;
@@ -980,7 +980,7 @@ void TwinEEngine::readKeys() {
break;
}
}
- _keyboard.skipIntro = localKey;
+ _keyboard.internalKeyCode = localKey;
}
}
Commit: 36884ce640a565ce1e3d9d0c1810d868654108bb
https://github.com/scummvm/scummvm/commit/36884ce640a565ce1e3d9d0c1810d868654108bb
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: converted remaining key down events to keymapper
Changed paths:
engines/twine/keyboard.h
engines/twine/metaengine.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/keyboard.h b/engines/twine/keyboard.h
index 7ee95cc181..9094c5c4a9 100644
--- a/engines/twine/keyboard.h
+++ b/engines/twine/keyboard.h
@@ -56,6 +56,9 @@ enum TwinEActionType {
UseProtoPack,
OpenHolomap,
InventoryMenu,
+ SpecialAction,
+ Escape,
+ PageUp,
Max
};
@@ -90,7 +93,10 @@ static constexpr const struct ActionMapping {
{TurnLeft, 0x4B},
{UseProtoPack, 0x24},
{OpenHolomap, 0x23},
- {InventoryMenu, 0x36}
+ {InventoryMenu, 0x36},
+ {SpecialAction, 0x11},
+ {Escape, 0x01},
+ {PageUp, 0x49} // TODO: used for what?
};
static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected action mapping array size");
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index 7cc5465cf6..db9da39ee8 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -93,22 +93,23 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
act = new Action("DEBUGGRIDCAMERAPRESSUP", _("Debug Grid Camera Up"));
act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressUp);
- act->addDefaultInputMapping("w");
+ act->addDefaultInputMapping("s");
engineKeyMap->addAction(act);
act = new Action("DEBUGGRIDCAMERAPRESSDOWN", _("Debug Grid Camera Down"));
act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressDown);
- act->addDefaultInputMapping("s");
+ act->addDefaultInputMapping("x");
engineKeyMap->addAction(act);
act = new Action("DEBUGGRIDCAMERAPRESSLEFT", _("Debug Grid Camera Left"));
act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressLeft);
- act->addDefaultInputMapping("a");
+ act->addDefaultInputMapping("y");
+ act->addDefaultInputMapping("z");
engineKeyMap->addAction(act);
act = new Action("DEBUGGRIDCAMERAPRESSRIGHT", _("Debug Grid Camera Right"));
act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressRight);
- act->addDefaultInputMapping("d");
+ act->addDefaultInputMapping("c");
engineKeyMap->addAction(act);
act = new Action("NORMALBEHAVIOUR", _("Normal Behaviour"));
@@ -205,6 +206,21 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
act->addDefaultInputMapping("i");
engineKeyMap->addAction(act);
+ act = new Action("SPECIALACTION", _("Special Action"));
+ act->setCustomEngineActionEvent(TwinEActionType::SpecialAction);
+ act->addDefaultInputMapping("w");
+ engineKeyMap->addAction(act);
+
+ act = new Action("ESCAPE", _("Escape"));
+ act->setCustomEngineActionEvent(TwinEActionType::Escape);
+ act->addDefaultInputMapping("ESC");
+ engineKeyMap->addAction(act);
+
+ act = new Action("PAGEUP", _("Page Up"));
+ act->setCustomEngineActionEvent(TwinEActionType::PageUp);
+ act->addDefaultInputMapping("PAGEUP");
+ engineKeyMap->addAction(act);
+
const int delta = (int)TwinEActionType::Max - (int)engineKeyMap->getActions().size();
if (delta != 0) {
error("Registered key map actions differs from TwinEActionType by %i", delta);
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 83c4409bf2..7920939873 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -940,22 +940,6 @@ void TwinEEngine::readKeys() {
case Common::EVENT_KEYUP:
_keyboard.pressedKey = 0;
break;
- case Common::EVENT_KEYDOWN: {
- switch (event.kbd.keycode) {
- case Common::KEYCODE_ESCAPE:
- _keyboard.internalKeyCode = 1;
- break;
- case Common::KEYCODE_PAGEUP:
- localKey = 0x49;
- break;
- case Common::KEYCODE_w: // Especial key to do the action
- localKey = 0x11;
- break;
- default:
- break;
- }
- break;
- }
case Common::EVENT_LBUTTONDOWN:
leftMouse = 1;
break;
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index df89c6d3b7..848d87aa4e 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -227,11 +227,11 @@ public:
/** temporary screen table */
int32 screenLookupTable[2000]{0};
- int32 loopPressedKey = 0; // mainLoopVar5
- int32 previousLoopPressedKey = 0; // mainLoopVar6
- int32 loopCurrentKey = 0; // mainLoopVar7
- int32 loopInventoryItem = 0; // mainLoopVar9
- int32 loopActorStep = 0; // mainLoopVar17
+ int32 loopPressedKey = 0;
+ int32 previousLoopPressedKey = 0;
+ int32 loopCurrentKey = 0;
+ int32 loopInventoryItem = 0;
+ int32 loopActorStep = 0;
/** Disable screen recenter */
int16 disableScreenRecenter = 0;
Commit: 5a80f0f0acc1e1e7ccc6dfba2431a6168937898a
https://github.com/scummvm/scummvm/commit/5a80f0f0acc1e1e7ccc6dfba2431a6168937898a
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: convert to boolean
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index a988741f0c..d1189fdc66 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -425,9 +425,9 @@ void Menu::drawButton(const int16 *menuSettings, int32 mode) {
int32 Menu::processMenu(int16 *menuSettings) {
int16 *localData = menuSettings;
int16 currentButton = 0; // localData[0];
- int32 buttonReleased = 1;
- int32 musicChanged = 0;
- int32 buttonNeedRedraw = 1;
+ bool buttonReleased = true;
+ bool buttonNeedRedraw = true;
+ bool musicChanged = false;
int32 numEntry = localData[1];
int32 localTime = _engine->lbaTime;
int32 maxButton = numEntry - 1;
@@ -448,7 +448,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
if (_engine->_keyboard.pressedKey == 0) {
- buttonReleased = 1;
+ buttonReleased = true;
}
if (buttonReleased) {
@@ -459,8 +459,8 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (currentButton == numEntry) { // if current button is the last, than next button is the first
currentButton = 0;
}
- buttonNeedRedraw = 1;
- buttonReleased = 0;
+ buttonNeedRedraw = true;
+ buttonReleased = false;
}
if (((uint8)_engine->_keyboard.key & 1)) { // on arrow key up
@@ -468,8 +468,8 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (currentButton < 0) { // if current button is the first, than previous button is the last
currentButton = maxButton;
}
- buttonNeedRedraw = 1;
- buttonReleased = 0;
+ buttonNeedRedraw = true;
+ buttonReleased = false;
}
if (*(localData + 8) <= 5) { // if its a volume button
@@ -538,7 +538,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
}
- if (buttonNeedRedraw == 1) {
+ if (buttonNeedRedraw) {
*localData = currentButton;
drawButton(localData, 0); // current button
@@ -546,13 +546,12 @@ int32 Menu::processMenu(int16 *menuSettings) {
_engine->readKeys();
drawButton(localData, 1);
} while (_engine->_keyboard.pressedKey == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.internalKeyCode == 0);
- buttonNeedRedraw = 0;
+ buttonNeedRedraw = false;
} else {
if (musicChanged) {
// TODO: update volume settings
}
- buttonNeedRedraw = 0;
drawButton(localData, 1);
_engine->readKeys();
// WARNING: this is here to prevent a fade bug while quit the menu
Commit: cc716125f5b45b4f2779bc2a5451d4d951871091
https://github.com/scummvm/scummvm/commit/cc716125f5b45b4f2779bc2a5451d4d951871091
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: converted to char array
Changed paths:
engines/twine/menuoptions.cpp
engines/twine/menuoptions.h
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 775af1fcba..1ec8ed8ff4 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -165,7 +165,7 @@ void MenuOptions::drawSelectableCharacters() {
}
// 0001F18C
-void MenuOptions::drawPlayerName(int32 centerx, int32 top, int8 * /*playerName*/, int32 type) {
+void MenuOptions::drawPlayerName(int32 centerx, int32 top, const char * /*playerName*/, int32 type) {
/*
int v4; // ebp at 0
int v6; // [sp+0h] [bp-14h]@0
diff --git a/engines/twine/menuoptions.h b/engines/twine/menuoptions.h
index 2eaac36a3c..cb48efb194 100644
--- a/engines/twine/menuoptions.h
+++ b/engines/twine/menuoptions.h
@@ -34,7 +34,7 @@ private:
int32 enterPlayerName(int32 textIdx);
void drawSelectableCharacters();
- void drawPlayerName(int32 centerx, int32 top, int8 *playerName, int32 type);
+ void drawPlayerName(int32 centerx, int32 top, const char *playerName, int32 type);
void drawSelectableCharacter(int32 x, int32 y, int32 arg);
void showCredits();
void newGame();
@@ -44,7 +44,7 @@ public:
int32 canShowCredits = 0;
- int8 playerName[256] = "";
+ char playerName[256] = "";
int8 enterPlayerNameVar1 = 0;
int32 enterPlayerNameVar2 = 0;
Commit: 431ac7f465923c58cdeee146c8e4e8a15dff87bf
https://github.com/scummvm/scummvm/commit/431ac7f465923c58cdeee146c8e4e8a15dff87bf
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: use constants for music config and improved midi hqr detection
Changed paths:
engines/twine/flamovies.cpp
engines/twine/music.cpp
engines/twine/music.h
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 9061585f11..f06d37baf0 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -32,12 +32,6 @@
namespace TwinE {
-/** Config movie types */
-#define CONF_MOVIE_NONE 0
-#define CONF_MOVIE_FLA 1
-#define CONF_MOVIE_FLAWIDE 2
-#define CONF_MOVIE_FLAPCX 3
-
/** FLA movie extension */
#define FLA_EXT ".fla"
diff --git a/engines/twine/music.cpp b/engines/twine/music.cpp
index e787b3cbd8..cf747d9bd5 100644
--- a/engines/twine/music.cpp
+++ b/engines/twine/music.cpp
@@ -35,32 +35,51 @@ namespace TwinE {
/** MP3 music folder */
#define MUSIC_FOLDER "music"
-/** LBA1 default number of tracks */
+/**
+ * LBA1 default number of tracks
+ * <pre>
+ * TRACK 01 MODE1/2352
+ * INDEX 01 00:00:00
+ * TRACK 02 AUDIO
+ * INDEX 01 10:47:52
+ * TRACK 03 AUDIO
+ * INDEX 01 14:02:01
+ * TRACK 04 AUDIO
+ * INDEX 01 17:02:19
+ * TRACK 05 AUDIO
+ * INDEX 01 19:34:45
+ * TRACK 06 AUDIO
+ * INDEX 01 22:22:34
+ * TRACK 07 AUDIO
+ * INDEX 01 25:09:32
+ * TRACK 08 AUDIO
+ * INDEX 01 26:47:72
+ * TRACK 09 AUDIO
+ * INDEX 01 30:29:07
+ * TRACK 10 AUDIO
+ * INDEX 01 32:04:62
+ * </pre>
+ */
#define NUM_CD_TRACKS 10
/** Number of miliseconds to fade music */
#define FADE_MS 500
-#if 0 // TODO
-/** SDL_Mixer track variable interface */
-Mix_Music *current_track;
-#endif
-
void Music::musicVolume(int32 volume) {
_engine->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType, volume);
}
-void Music::musicFadeIn(int32 loops, int32 ms) {
+void Music::musicFadeIn() {
int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
#if 0 // TODO
- Mix_FadeInMusic(current_track, loops, ms);
+ Mix_FadeInMusic(current_track, 1, FADE_MS);
#endif
musicVolume(volume);
}
-void Music::musicFadeOut(int32 ms) {
+void Music::musicFadeOut() {
int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
#if 0 // TODO
- while (!Mix_FadeOutMusic(ms) && Mix_PlayingMusic()) {
+ while (!Mix_FadeOutMusic(FADE_MS) && Mix_PlayingMusic()) {
SDL_Delay(100);
}
Mix_HaltMusic();
@@ -104,13 +123,11 @@ void Music::stopTrackMusic() {
return;
}
- musicFadeOut(FADE_MS);
+ musicFadeOut();
stopTrackMusicCd();
}
void Music::playMidiMusic(int32 midiIdx, int32 loop) {
- uint8 *dos_midi_ptr;
- int32 midiSize;
if (!_engine->cfgfile.Sound) {
return;
@@ -124,19 +141,20 @@ void Music::playMidiMusic(int32 midiIdx, int32 loop) {
currentMusic = midiIdx;
char filename[256];
- if (_engine->cfgfile.MidiType == 0)
+ if (_engine->cfgfile.MidiType == MIDIFILE_DOS)
snprintf(filename, sizeof(filename), "%s", Resources::HQR_MIDI_MI_DOS_FILE);
else
snprintf(filename, sizeof(filename), "%s", Resources::HQR_MIDI_MI_WIN_FILE);
if (midiPtr) {
- musicFadeOut(FADE_MS / 2);
+ musicFadeOut();
stopMidiMusic();
}
- midiSize = _engine->_hqrdepack->hqrGetallocEntry(&midiPtr, filename, midiIdx);
+ int32 midiSize = _engine->_hqrdepack->hqrGetallocEntry(&midiPtr, filename, midiIdx);
if (_engine->cfgfile.Sound == 1 && _engine->cfgfile.MidiType == 0) {
+ uint8 *dos_midi_ptr;
midiSize = convert_to_midi(midiPtr, midiSize, &dos_midi_ptr);
free(midiPtr);
midiPtr = dos_midi_ptr;
@@ -146,7 +164,7 @@ void Music::playMidiMusic(int32 midiIdx, int32 loop) {
SDL_RWops *rw = SDL_RWFromMem(midiPtr, midiSize);
current_track = Mix_LoadMUS_RW(rw, 0);
- musicFadeIn(1, FADE_MS);
+ musicFadeIn();
if (Mix_PlayMusic(current_track, loop) == -1)
warning("Error while playing music: %d \n", midiIdx);
diff --git a/engines/twine/music.h b/engines/twine/music.h
index 936603932a..71f55d07c0 100644
--- a/engines/twine/music.h
+++ b/engines/twine/music.h
@@ -33,8 +33,8 @@ class Music {
private:
TwinEEngine *_engine;
- void musicFadeIn(int32 loops, int32 ms);
- void musicFadeOut(int32 ms);
+ void musicFadeIn();
+ void musicFadeOut();
/** Auxiliar midi pointer to */
uint8 *midiPtr = nullptr;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 7920939873..d70ae43abc 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -190,23 +190,26 @@ void TwinEEngine::initConfigurations() {
cfgfile.FlagDisplayText = ConfGetOrDefault("FlagDisplayText", "ON") == "ON";
cfgfile.FlagKeepVoice = ConfGetOrDefault("FlagKeepVoice", "OFF") == "ON";
const Common::String midiType = ConfGetOrDefault("MidiType", "auto");
- if (midiType == "auto") {
+ if (midiType == "None") {
+ cfgfile.MidiType = MIDIFILE_NONE;
+ } else {
Common::File midiHqr;
if (midiHqr.exists(Resources::HQR_MIDI_MI_WIN_FILE)) {
- cfgfile.MidiType = 1;
+ cfgfile.MidiType = MIDIFILE_WIN;
+ debug("Use %s for midi", Resources::HQR_MIDI_MI_WIN_FILE);
+ } else if (midiHqr.exists(Resources::HQR_MIDI_MI_DOS_FILE)) {
+ cfgfile.MidiType = MIDIFILE_DOS;
+ debug("Use %s for midi", Resources::HQR_MIDI_MI_DOS_FILE);
} else {
- cfgfile.MidiType = 0;
+ cfgfile.MidiType = MIDIFILE_NONE;
+ debug("Could not find midi hqr file");
}
- } else if (midiType == "midi") {
- cfgfile.MidiType = 1;
- } else {
- cfgfile.MidiType = 0;
}
cfgfile.Version = ConfGetIntOrDefault("Version", EUROPE_VERSION);
cfgfile.FullScreen = ConfGetIntOrDefault("FullScreen", 1) == 1;
cfgfile.UseCD = ConfGetIntOrDefault("UseCD", 0);
- cfgfile.Sound = ConfGetIntOrDefault("Sound", 0);
- cfgfile.Movie = ConfGetIntOrDefault("Movie", 0);
+ cfgfile.Sound = ConfGetIntOrDefault("Sound", 1);
+ cfgfile.Movie = ConfGetIntOrDefault("Movie", CONF_MOVIE_FLA);
cfgfile.CrossFade = ConfGetIntOrDefault("CrossFade", 0);
cfgfile.Fps = ConfGetIntOrDefault("Fps", DEFAULT_FRAMES_PER_SECOND);
cfgfile.Debug = ConfGetIntOrDefault("Debug", 0);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 848d87aa4e..ae092ee1bd 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -69,6 +69,20 @@ static const struct TwinELanguage {
{"Italiano", "IT_"},
{"Portugues", ""}};
+enum MidiFileType {
+ MIDIFILE_NONE,
+ MIDIFILE_DOS,
+ MIDIFILE_WIN
+};
+
+/** Config movie types */
+enum MovieType {
+ CONF_MOVIE_NONE = 0,
+ CONF_MOVIE_FLA = 1,
+ CONF_MOVIE_FLAWIDE = 2,
+ CONF_MOVIE_FLAPCX = 3
+};
+
/** Configuration file structure
Used in the engine to load/use certain parts of code according with
@@ -84,7 +98,7 @@ struct ConfigFile {
/** Save voice files on hard disk */
bool FlagKeepVoice = false;
/** Type of music file to be used */
- int8 MidiType = 0;
+ MidiFileType MidiType = MIDIFILE_NONE;
/** *Game version */
int32 Version = 0;
/** To allow fullscreen or window mode. */
@@ -94,7 +108,7 @@ struct ConfigFile {
/** Allow various sound types */
int32 Sound = 0;
/** Allow various movie types */
- int32 Movie = 0;
+ int32 Movie = CONF_MOVIE_FLA;
/** Use cross fade effect while changing images, or be as the original */
int32 CrossFade = 0;
/** Flag used to keep the game frames per second */
Commit: e3e6f7eebe093fd099f6a8e1f92bb781fbfab3c9
https://github.com/scummvm/scummvm/commit/e3e6f7eebe093fd099f6a8e1f92bb781fbfab3c9
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: try to open the fla files from a flat installation dir
Changed paths:
engines/twine/flamovies.cpp
engines/twine/hqrdepack.cpp
engines/twine/sound.cpp
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index f06d37baf0..fe7612dbaf 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -238,7 +238,7 @@ void FlaMovies::playFlaMovie(const char *flaName) {
_engine->_music->stopMusic();
- Common::String fileNamePath = Common::String::format(FLA_DIR "%s", flaName);
+ Common::String fileNamePath = Common::String::format("%s", flaName);
const size_t n = fileNamePath.findLastOf(".");
if (n != Common::String::npos) {
fileNamePath.erase(n);
@@ -249,9 +249,11 @@ void FlaMovies::playFlaMovie(const char *flaName) {
fadeOutFrames = 0;
file.close();
- if (!file.open(fileNamePath)) {
- warning("Failed to open fla movie '%s'", fileNamePath.c_str());
- return;
+ if (!file.open(FLA_DIR + fileNamePath)) {
+ if (!file.open(fileNamePath)) {
+ warning("Failed to open fla movie '%s'", fileNamePath.c_str());
+ return;
+ }
}
file.read(&flaHeaderData.version, 6);
diff --git a/engines/twine/hqrdepack.cpp b/engines/twine/hqrdepack.cpp
index 55e284dd16..5b54b0dcc8 100644
--- a/engines/twine/hqrdepack.cpp
+++ b/engines/twine/hqrdepack.cpp
@@ -21,6 +21,7 @@
*/
#include "twine/hqrdepack.h"
+#include "common/debug.h"
#include "common/file.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -96,7 +97,8 @@ int32 HQRDepack::hqrGetEntry(uint8 *ptr, const char *filename, int32 index) {
Common::File file;
if (!file.open(filename)) {
- error("HQR: %s can't be found!", filename);
+ debug("Could not open %s", filename);
+ return 0;
}
uint32 headerSize = file.readUint32LE();
diff --git a/engines/twine/sound.cpp b/engines/twine/sound.cpp
index 67406c871a..9eb2b0f63a 100644
--- a/engines/twine/sound.cpp
+++ b/engines/twine/sound.cpp
@@ -62,10 +62,17 @@ void Sound::playFlaSample(int32 index, int32 frequency, int32 repeat, int32 x, i
return;
}
- const Common::String& sampfile = Common::String::format(FLA_DIR "%s", Resources::HQR_FLASAMP_FILE);
-
uint8 *sampPtr;
- int32 sampSize = _engine->_hqrdepack->hqrGetallocEntry(&sampPtr, sampfile.c_str(), index);
+ int32 sampSize;
+ Common::String sampfile = Common::String::format("%s", Resources::HQR_FLASAMP_FILE);
+ sampSize = _engine->_hqrdepack->hqrGetallocEntry(&sampPtr, sampfile.c_str(), index);
+ if (sampSize == 0) {
+ sampfile = Common::String::format(FLA_DIR "%s", Resources::HQR_FLASAMP_FILE);
+ sampSize = _engine->_hqrdepack->hqrGetallocEntry(&sampPtr, sampfile.c_str(), index);
+ if (sampSize == 0) {
+ return;
+ }
+ }
// Fix incorrect sample files first byte
if (*sampPtr != 'C') {
*sampPtr = 'C';
Commit: cb96e1f38899a806c659eefa0561e7d0e9d73e34
https://github.com/scummvm/scummvm/commit/cb96e1f38899a806c659eefa0561e7d0e9d73e34
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed escape mapping
Changed paths:
engines/twine/metaengine.cpp
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index db9da39ee8..7772e08785 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -213,7 +213,7 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
act = new Action("ESCAPE", _("Escape"));
act->setCustomEngineActionEvent(TwinEActionType::Escape);
- act->addDefaultInputMapping("ESC");
+ act->addDefaultInputMapping("ESCAPE");
engineKeyMap->addAction(act);
act = new Action("PAGEUP", _("Page Up"));
Commit: b833a88e431d5c9c34f577e6912370aaa18e3a72
https://github.com/scummvm/scummvm/commit/b833a88e431d5c9c34f577e6912370aaa18e3a72
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed language detection for the scummvm language descriptions
Changed paths:
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index d70ae43abc..f10653a319 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -172,6 +172,7 @@ static int getLanguageTypeIndex(const char *languageName) {
}
}
+ debug("Failed to detect language %s - falling back to english", languageName);
return 0; // English
}
@@ -181,12 +182,9 @@ static int getLanguageTypeIndex(const char *languageName) {
void TwinEEngine::initConfigurations() {
// TODO: use existing entries for some of the settings - like volume and so on.
- Common::String language = ConfGetOrDefault("Language", Common::getLanguageDescription(_gameLang));
- cfgfile.LanguageId = getLanguageTypeIndex(language.c_str()) + 1;
-
- Common::String languageCD = ConfGetOrDefault("LanguageCD", "None");
- cfgfile.LanguageCDId = getLanguageTypeIndex(languageCD.c_str()) + 1;
-
+ const char *lng = Common::getLanguageDescription(_gameLang);
+ cfgfile.LanguageId = getLanguageTypeIndex(lng) + 1;
+ cfgfile.LanguageCDId = getLanguageTypeIndex(lng) + 1;
cfgfile.FlagDisplayText = ConfGetOrDefault("FlagDisplayText", "ON") == "ON";
cfgfile.FlagKeepVoice = ConfGetOrDefault("FlagKeepVoice", "OFF") == "ON";
const Common::String midiType = ConfGetOrDefault("MidiType", "auto");
@@ -206,7 +204,6 @@ void TwinEEngine::initConfigurations() {
}
}
cfgfile.Version = ConfGetIntOrDefault("Version", EUROPE_VERSION);
- cfgfile.FullScreen = ConfGetIntOrDefault("FullScreen", 1) == 1;
cfgfile.UseCD = ConfGetIntOrDefault("UseCD", 0);
cfgfile.Sound = ConfGetIntOrDefault("Sound", 1);
cfgfile.Movie = ConfGetIntOrDefault("Movie", CONF_MOVIE_FLA);
@@ -221,9 +218,6 @@ void TwinEEngine::initConfigurations() {
}
void TwinEEngine::initEngine() {
- // getting configuration file
- initConfigurations();
-
/** Engine current version */
const char *ENGINE_VERSION = "0.2.2";
@@ -236,6 +230,9 @@ void TwinEEngine::initEngine() {
debug("The original Little Big Adventure game is:");
debug("(c)1994 by Adeline Software International, All Rights Reserved.");
+ // getting configuration file
+ initConfigurations();
+
_screens->clearScreen();
// Check if LBA CD-Rom is on drive
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index ae092ee1bd..f8df0bdd0a 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -63,11 +63,11 @@ static const struct TwinELanguage {
const char *id;
} LanguageTypes[] = {
{"English", "EN_"},
- {"Francais", "FR_"},
- {"Deutsch", "DE_"},
- {"Espanol", "SP_"},
- {"Italiano", "IT_"},
- {"Portugues", ""}};
+ {"French", "FR_"},
+ {"German", "DE_"},
+ {"Spanish", "SP_"},
+ {"Italian", "IT_"},
+ {"Portuguese", ""}};
enum MidiFileType {
MIDIFILE_NONE,
@@ -101,8 +101,6 @@ struct ConfigFile {
MidiFileType MidiType = MIDIFILE_NONE;
/** *Game version */
int32 Version = 0;
- /** To allow fullscreen or window mode. */
- bool FullScreen = false;
/** If you want to use the LBA CD or not */
int32 UseCD = 0;
/** Allow various sound types */
Commit: 53858b559ef7c93708bddb155420d6a429feeafa
https://github.com/scummvm/scummvm/commit/53858b559ef7c93708bddb155420d6a429feeafa
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed sound implementation
Changed paths:
engines/twine/sound.cpp
engines/twine/sound.h
diff --git a/engines/twine/sound.cpp b/engines/twine/sound.cpp
index 9eb2b0f63a..17aee79b45 100644
--- a/engines/twine/sound.cpp
+++ b/engines/twine/sound.cpp
@@ -22,7 +22,7 @@
#include "twine/sound.h"
#include "audio/audiostream.h"
-#include "audio/decoders/wave.h"
+#include "audio/decoders/voc.h"
#include "common/memstream.h"
#include "common/system.h"
#include "common/types.h"
@@ -52,6 +52,19 @@ void Sound::sampleVolume(int32 chan, int32 volume) {
_engine->_system->getMixer()->setChannelVolume(samplesPlaying[chan], volume / 2);
}
+void Sound::setSamplePosition(int32 chan, int32 x, int32 y, int32 z) {
+ int32 distance;
+ distance = ABS(_engine->_movements->getDistance3D(_engine->_grid->newCameraX << 9, _engine->_grid->newCameraY << 8, _engine->_grid->newCameraZ << 9, x, y, z));
+ distance = _engine->_collision->getAverageValue(0, distance, 10000, 255);
+ if (distance > 255) { // don't play it if its to far away
+ distance = 255;
+ }
+
+#if 0 // TODO
+ Mix_SetDistance(chan, distance);
+#endif
+}
+
void Sound::playFlaSample(int32 index, int32 frequency, int32 repeat, int32 x, int32 y) {
if (!_engine->cfgfile.Sound) {
return;
@@ -73,28 +86,8 @@ void Sound::playFlaSample(int32 index, int32 frequency, int32 repeat, int32 x, i
return;
}
}
- // Fix incorrect sample files first byte
- if (*sampPtr != 'C') {
- *sampPtr = 'C';
- }
-
- Common::MemoryReadStream stream(sampPtr, sampSize, DisposeAfterUse::YES);
- Audio::SeekableAudioStream *audioStream = Audio::makeWAVStream(&stream, DisposeAfterUse::NO);
- // TODO: mgerhardy repeat flag
- _engine->_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &samplesPlaying[channelIdx], audioStream, index);
-}
-
-void Sound::setSamplePosition(int32 chan, int32 x, int32 y, int32 z) {
- int32 distance;
- distance = ABS(_engine->_movements->getDistance3D(_engine->_grid->newCameraX << 9, _engine->_grid->newCameraY << 8, _engine->_grid->newCameraZ << 9, x, y, z));
- distance = _engine->_collision->getAverageValue(0, distance, 10000, 255);
- if (distance > 255) { // don't play it if its to far away
- distance = 255;
- }
-#if 0 // TODO
- Mix_SetDistance(chan, distance);
-#endif
+ playSample(channelIdx, index, sampPtr, sampSize, repeat, sampfile.c_str());
}
void Sound::playSample(int32 index, int32 frequency, int32 repeat, int32 x, int32 y, int32 z, int32 actorIdx) {
@@ -108,22 +101,50 @@ void Sound::playSample(int32 index, int32 frequency, int32 repeat, int32 x, int3
}
uint8 *sampPtr;
int32 sampSize = _engine->_hqrdepack->hqrGetallocEntry(&sampPtr, Resources::HQR_SAMPLES_FILE, index);
- // Fix incorrect sample files first byte
- if (*sampPtr != 'C') {
- *sampPtr = 'C';
- }
-
if (actorIdx != -1) {
setSamplePosition(channelIdx, x, y, z);
-
// save the actor index for the channel so we can check the position
samplesPlayingActors[channelIdx] = actorIdx;
}
- Common::MemoryReadStream stream(sampPtr, sampSize, DisposeAfterUse::YES);
- Audio::SeekableAudioStream *audioStream = Audio::makeWAVStream(&stream, DisposeAfterUse::NO);
- // TODO: mgerhardy repeat flag
+ playSample(channelIdx, index, sampPtr, sampSize, repeat, Resources::HQR_SAMPLES_FILE);
+}
+
+void Sound::playVoxSample(int32 index) {
+ if (!_engine->cfgfile.Sound) {
+ return;
+ }
+
+ int channelIdx = getFreeSampleChannelIndex();
+ if (channelIdx != -1) {
+ return;
+ }
+
+ uint8 *sampPtr = nullptr;
+ int32 sampSize = _engine->_hqrdepack->hqrGetallocVoxEntry(&sampPtr, _engine->_text->currentVoxBankFile.c_str(), index, _engine->_text->voxHiddenIndex);
+
+ // Fix incorrect sample files first byte
+ if (*sampPtr != 'C') {
+ _engine->_text->hasHiddenVox = *sampPtr;
+ _engine->_text->voxHiddenIndex++;
+ }
+
+ playSample(channelIdx, index, sampPtr, sampSize, 1, _engine->_text->currentVoxBankFile.c_str());
+}
+
+bool Sound::playSample(int channelIdx, int index, uint8 *sampPtr, int32 sampSize, int32 loop, const char *name) {
+ // Fix incorrect sample files first byte
+ if (*sampPtr != 'C') {
+ *sampPtr = 'C';
+ }
+ Common::MemoryReadStream *stream = new Common::MemoryReadStream(sampPtr, sampSize, DisposeAfterUse::YES);
+ Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(stream, DisposeAfterUse::YES);
+ if (audioStream == nullptr) {
+ warning("Failed to create voc audio stream for %s", name);
+ return false;
+ }
_engine->_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &samplesPlaying[channelIdx], audioStream, index);
+ return true;
}
void Sound::resumeSamples() {
@@ -175,7 +196,7 @@ void Sound::stopSample(int32 index) {
if (!_engine->cfgfile.Sound) {
return;
}
- int32 stopChannel = getSampleChannel(index);
+ const int32 stopChannel = getSampleChannel(index);
if (stopChannel != -1) {
_engine->_system->getMixer()->stopID(index);
removeSampleChannel(stopChannel);
@@ -206,29 +227,4 @@ int32 Sound::getFreeSampleChannelIndex() {
return -1;
}
-void Sound::playVoxSample(int32 index) {
- if (!_engine->cfgfile.Sound) {
- return;
- }
-
- int channelIdx = getFreeSampleChannelIndex();
- if (channelIdx != -1) {
- return;
- }
-
- uint8 *sampPtr = nullptr;
- int32 sampSize = _engine->_hqrdepack->hqrGetallocVoxEntry(&sampPtr, _engine->_text->currentVoxBankFile.c_str(), index, _engine->_text->voxHiddenIndex);
-
- // Fix incorrect sample files first byte
- if (*sampPtr != 'C') {
- _engine->_text->hasHiddenVox = *sampPtr;
- _engine->_text->voxHiddenIndex++;
- *sampPtr = 'C';
- }
-
- Common::MemoryReadStream stream(sampPtr, sampSize, DisposeAfterUse::YES);
- Audio::SeekableAudioStream *audioStream = Audio::makeWAVStream(&stream, DisposeAfterUse::NO);
- _engine->_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &samplesPlaying[channelIdx], audioStream, index);
-}
-
} // namespace TwinE
diff --git a/engines/twine/sound.h b/engines/twine/sound.h
index f67e7fbecf..186f1bbb98 100644
--- a/engines/twine/sound.h
+++ b/engines/twine/sound.h
@@ -46,6 +46,8 @@ private:
/** Samples playing at a actors position */
int32 samplesPlayingActors[NUM_CHANNELS]{0};
+ bool playSample(int channelIdx, int index, uint8 *sampPtr, int32 sampSize, int32 loop, const char *name);
+
public:
Sound(TwinEEngine *engine);
Commit: 4900ee4fcfb0ce235a7aca041a073aebf536952a
https://github.com/scummvm/scummvm/commit/4900ee4fcfb0ce235a7aca041a073aebf536952a
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: only reset pressedKey member if the custom action is done
Changed paths:
engines/twine/twine.cpp
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index f10653a319..534725dd06 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -937,9 +937,6 @@ void TwinEEngine::readKeys() {
_keyboard.actionStates[event.customType] = true;
}
break;
- case Common::EVENT_KEYUP:
- _keyboard.pressedKey = 0;
- break;
case Common::EVENT_LBUTTONDOWN:
leftMouse = 1;
break;
@@ -957,7 +954,11 @@ void TwinEEngine::readKeys() {
for (int i = 0; i < ARRAYSIZE(pressedKeyCharMap); i++) {
if (pressedKeyCharMap[i].key == localKey) {
if (pressedKeyCharMap[i].pressed) {
- _keyboard.pressedKey |= pressedKeyCharMap[i].high;
+ if (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
+ _keyboard.pressedKey &= ~pressedKeyCharMap[i].high;
+ } else {
+ _keyboard.pressedKey |= pressedKeyCharMap[i].high;
+ }
} else {
_keyboard.skippedKey |= pressedKeyCharMap[i].high;
}
Commit: 02910b092d3d9a41e1e23603a52a1f98ccfb9928
https://github.com/scummvm/scummvm/commit/02910b092d3d9a41e1e23603a52a1f98ccfb9928
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: missed to add escape action to the KeyProperties
the skippedKey was not set due to this and skipping intros wasn't working anmore
I suppose there will be a lot of work left to refactor the input system...
Changed paths:
engines/twine/twine.cpp
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 534725dd06..87bfb2d0ba 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -897,7 +897,7 @@ static const struct KeyProperties {
{0x08, true, 0x58}, // ?
{0x00, true, 0x2A}, // left shift
{0x00, true, 0x00},
- {0x00, false, 0x00},
+ {0x01, false, 0x01}, // esc
{0x00, false, 0x00}};
static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
Commit: e1ec83207f335c5cd69e3a4c25aa5d40cb3bc486
https://github.com/scummvm/scummvm/commit/e1ec83207f335c5cd69e3a4c25aa5d40cb3bc486
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: implemented midi music
Changed paths:
engines/twine/menuoptions.cpp
engines/twine/music.cpp
engines/twine/music.h
engines/twine/scene.cpp
engines/twine/screens.cpp
engines/twine/script_life.cpp
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 1ec8ed8ff4..d176d4df61 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -83,7 +83,7 @@ void MenuOptions::newGame() {
_engine->_screens->clearScreen();
_engine->flip();
- _engine->_music->playMidiMusic(1, 0);
+ _engine->_music->playMidiMusic(1);
_engine->_flaMovies->playFlaMovie(FLA_INTROD);
_engine->_screens->clearScreen();
diff --git a/engines/twine/music.cpp b/engines/twine/music.cpp
index cf747d9bd5..8fc3493244 100644
--- a/engines/twine/music.cpp
+++ b/engines/twine/music.cpp
@@ -20,13 +20,14 @@
*
*/
+#include "twine/music.h"
#include "audio/midiparser.h"
+#include "audio/midiplayer.h"
#include "backends/audiocd/audiocd.h"
#include "common/debug.h"
#include "common/system.h"
#include "common/textconsole.h"
#include "twine/hqrdepack.h"
-#include "twine/music.h"
#include "twine/resources.h"
#include "twine/twine.h"
#include "twine/xmidi.h"
@@ -61,30 +62,52 @@ namespace TwinE {
* </pre>
*/
#define NUM_CD_TRACKS 10
-/** Number of miliseconds to fade music */
-#define FADE_MS 500
+
+TwinEMidiPlayer::TwinEMidiPlayer() {
+ MidiPlayer::createDriver();
+
+ int ret = _driver->open();
+ if (ret == 0) {
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+ _driver->setTimerCallback(this, &timerCallback);
+ }
+}
+
+void TwinEMidiPlayer::play(byte *buf, int size) {
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(buf, size)) {
+ parser->setTrack(0);
+ parser->setMidiDriver(this);
+ parser->setTimerRate(_driver->getBaseTempo());
+ parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+
+ _parser = parser;
+
+ syncVolume();
+
+ // All the tracks are supposed to loop
+ _isLooping = true;
+ _isPlaying = true;
+ }
+}
void Music::musicVolume(int32 volume) {
_engine->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType, volume);
+ _midiPlayer.setVolume(volume);
}
void Music::musicFadeIn() {
int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
-#if 0 // TODO
- Mix_FadeInMusic(current_track, 1, FADE_MS);
-#endif
+ // TODO implement fade in
musicVolume(volume);
}
void Music::musicFadeOut() {
int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
-#if 0 // TODO
- while (!Mix_FadeOutMusic(FADE_MS) && Mix_PlayingMusic()) {
- SDL_Delay(100);
- }
- Mix_HaltMusic();
- Mix_RewindMusic();
-#endif
+ // TODO implement fade out
musicVolume(volume);
}
@@ -110,8 +133,9 @@ void Music::playTrackMusic(int32 track) {
return;
}
- if (track == currentMusic)
+ if (track == currentMusic) {
return;
+ }
currentMusic = track;
stopMusic();
@@ -128,8 +152,7 @@ void Music::stopTrackMusic() {
}
void Music::playMidiMusic(int32 midiIdx, int32 loop) {
-
- if (!_engine->cfgfile.Sound) {
+ if (!_engine->cfgfile.Sound || _engine->cfgfile.MidiType == MIDIFILE_NONE) {
return;
}
@@ -140,11 +163,12 @@ void Music::playMidiMusic(int32 midiIdx, int32 loop) {
stopMusic();
currentMusic = midiIdx;
- char filename[256];
- if (_engine->cfgfile.MidiType == MIDIFILE_DOS)
- snprintf(filename, sizeof(filename), "%s", Resources::HQR_MIDI_MI_DOS_FILE);
- else
- snprintf(filename, sizeof(filename), "%s", Resources::HQR_MIDI_MI_WIN_FILE);
+ const char *filename;
+ if (_engine->cfgfile.MidiType == MIDIFILE_DOS) {
+ filename = Resources::HQR_MIDI_MI_DOS_FILE;
+ } else {
+ filename = Resources::HQR_MIDI_MI_WIN_FILE;
+ }
if (midiPtr) {
musicFadeOut();
@@ -153,22 +177,14 @@ void Music::playMidiMusic(int32 midiIdx, int32 loop) {
int32 midiSize = _engine->_hqrdepack->hqrGetallocEntry(&midiPtr, filename, midiIdx);
- if (_engine->cfgfile.Sound == 1 && _engine->cfgfile.MidiType == 0) {
+ if (_engine->cfgfile.MidiType == MIDIFILE_DOS) {
uint8 *dos_midi_ptr;
midiSize = convert_to_midi(midiPtr, midiSize, &dos_midi_ptr);
free(midiPtr);
midiPtr = dos_midi_ptr;
}
-#if 0
- SDL_RWops *rw = SDL_RWFromMem(midiPtr, midiSize);
- current_track = Mix_LoadMUS_RW(rw, 0);
-
- musicFadeIn();
-
- if (Mix_PlayMusic(current_track, loop) == -1)
- warning("Error while playing music: %d \n", midiIdx);
-#endif
+ _midiPlayer.play(midiPtr, midiSize);
}
void Music::stopMidiMusic() {
@@ -176,31 +192,25 @@ void Music::stopMidiMusic() {
return;
}
-#if 0 // TODO
- if (current_track != NULL) {
- Mix_FreeMusic(current_track);
- current_track = NULL;
- if (midiPtr != NULL)
- free(midiPtr);
- }
-#endif
+ _midiPlayer.stop();
+ free(midiPtr);
}
-int Music::initCdrom() {
+bool Music::initCdrom() {
if (!_engine->cfgfile.Sound) {
- return 0;
+ return false;
}
#if 0 // TODO: mgerhardy
AudioCDManager* cdrom = g_system->getAudioCDManager();
if (cdrom->numtracks == NUM_CD_TRACKS) {
_engine->cdDir = "LBA";
_engine->cfgfile.UseCD = 1;
- return 1;
+ return true;
}
#endif
// not found the right CD
_engine->cfgfile.UseCD = 0;
- return 0;
+ return false;
}
void Music::stopMusic() {
diff --git a/engines/twine/music.h b/engines/twine/music.h
index 71f55d07c0..95e193ccc2 100644
--- a/engines/twine/music.h
+++ b/engines/twine/music.h
@@ -23,15 +23,23 @@
#ifndef TWINE_MUSIC_H
#define TWINE_MUSIC_H
+#include "audio/midiplayer.h"
#include "common/scummsys.h"
namespace TwinE {
class TwinEEngine;
+class TwinEMidiPlayer : public Audio::MidiPlayer {
+public:
+ TwinEMidiPlayer();
+ void play(byte *buf, int size);
+};
+
class Music {
private:
TwinEEngine *_engine;
+ TwinEMidiPlayer _midiPlayer;
void musicFadeIn();
void musicFadeOut();
@@ -67,12 +75,12 @@ public:
* Play MIDI music
* @param midiIdx music index under mini_mi_win.hqr
*/
- void playMidiMusic(int32 midiIdx, int32 loop);
+ void playMidiMusic(int32 midiIdx, int32 loop = 0);
/** Stop MIDI music */
void stopMidiMusic();
/** Initialize CD-Rom */
- int32 initCdrom();
+ bool initCdrom();
/** Stop MIDI and Track music */
void stopMusic();
diff --git a/engines/twine/scene.cpp b/engines/twine/scene.cpp
index eebfde4101..4b799be83e 100644
--- a/engines/twine/scene.cpp
+++ b/engines/twine/scene.cpp
@@ -387,7 +387,7 @@ void Scene::changeScene() {
_engine->_renderer->setLightVector(alphaLight, betaLight, 0);
if (sceneMusic != -1) {
- _engine->_music->playMidiMusic(sceneMusic, 0); // TODO this should play midi or cd tracks
+ _engine->_music->playMidiMusic(sceneMusic); // TODO this should play midi or cd tracks
}
}
diff --git a/engines/twine/screens.cpp b/engines/twine/screens.cpp
index c69701b5ef..2c2ad516e2 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/screens.cpp
@@ -31,7 +31,7 @@
namespace TwinE {
void Screens::adelineLogo() {
- _engine->_music->playMidiMusic(31, 0);
+ _engine->_music->playMidiMusic(31);
loadImage(RESSHQR_ADELINEIMG);
_engine->delaySkip(7000);
diff --git a/engines/twine/script_life.cpp b/engines/twine/script_life.cpp
index 267c2b5d2b..7b54337dc5 100644
--- a/engines/twine/script_life.cpp
+++ b/engines/twine/script_life.cpp
@@ -1037,7 +1037,7 @@ static int32 lPLAY_FLA(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor)
/*0x41*/
static int32 lPLAY_MIDI(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
int32 midiIdx = *(scriptPtr++);
- engine->_music->playMidiMusic(midiIdx, 0); // TODO: improve this
+ engine->_music->playMidiMusic(midiIdx); // TODO: improve this
return 0;
}
Commit: 18e7620613019f5e4fdfc68a53607b83a0243d8d
https://github.com/scummvm/scummvm/commit/18e7620613019f5e4fdfc68a53607b83a0243d8d
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: convert to boolean
Changed paths:
engines/twine/debug.cpp
engines/twine/debug_grid.cpp
engines/twine/grid.cpp
engines/twine/redraw.cpp
engines/twine/redraw.h
engines/twine/resources.cpp
engines/twine/scene.cpp
engines/twine/screens.cpp
engines/twine/screens.h
engines/twine/script_life.cpp
engines/twine/script_move.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 6c958472ae..7a4002e391 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -479,7 +479,7 @@ void Debug::debugProcessWindow() {
count++;
} while (!quit);
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
}
diff --git a/engines/twine/debug_grid.cpp b/engines/twine/debug_grid.cpp
index 8f9f813efe..f9e6d68482 100644
--- a/engines/twine/debug_grid.cpp
+++ b/engines/twine/debug_grid.cpp
@@ -39,25 +39,25 @@ void DebugGrid::changeGridCamera(int16 pKey) {
// Press up - more X positions
if (pKey == twineactions[TwinEActionType::DebugGridCameraPressUp].localKey) {
_engine->_grid->newCameraZ--;
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
// Press down - less X positions
else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressDown].localKey) {
_engine->_grid->newCameraZ++;
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
// Press left - less Z positions
else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressLeft].localKey) {
_engine->_grid->newCameraX--;
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
// Press right - more Z positions
else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressRight].localKey) {
_engine->_grid->newCameraX++;
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
}
}
@@ -72,7 +72,7 @@ void DebugGrid::changeGrid(int16 pKey) {
if (_engine->_scene->currentSceneIdx > NUM_SCENES)
_engine->_scene->currentSceneIdx = 0;
_engine->_scene->needChangeScene = _engine->_scene->currentSceneIdx;
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
// Press down - less X positions
@@ -81,7 +81,7 @@ void DebugGrid::changeGrid(int16 pKey) {
if (_engine->_scene->currentSceneIdx < 0)
_engine->_scene->currentSceneIdx = NUM_SCENES;
_engine->_scene->needChangeScene = _engine->_scene->currentSceneIdx;
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
}
@@ -109,7 +109,7 @@ void DebugGrid::applyCellingGrid(int16 pKey) {
} else if (_engine->_grid->useCellingGrid == 1) {
_engine->_grid->useCellingGrid = -1;
_engine->_grid->createGridMap();
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
debug("Disable Celling Grid index: %d", _engine->_grid->cellingGridIdx);
_engine->_scene->needChangeScene = -2; // tricky to make the fade
}
diff --git a/engines/twine/grid.cpp b/engines/twine/grid.cpp
index b658262db7..7d37d911b5 100644
--- a/engines/twine/grid.cpp
+++ b/engines/twine/grid.cpp
@@ -439,7 +439,7 @@ int32 Grid::initCellingGrid(int32 index) {
if (gridPtr)
free(gridPtr);
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
return 0;
}
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index c9b6b444bf..e81bbca1e9 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -719,7 +719,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
} else {
_engine->_screens->fadeToPal(_engine->_screens->mainPaletteRGBA);
}
- _engine->_screens->lockPalette = 0;
+ _engine->_screens->lockPalette = false;
}
if (_engine->zoomScreen) {
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index 3df6b146ac..9f5a1ae906 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -113,10 +113,10 @@ public:
/** Auxiliar object render bottom position on screen */
int32 renderBottom = 0;
- int16 drawInGameTransBox = 0;
+ bool drawInGameTransBox = false;
/** Request background redraw */
- int16 reqBgRedraw = 0;
+ bool reqBgRedraw = false;
/** Current number of redraw regions in the screen */
int32 currNumOfRedrawBox = 0; // fullRedrawVar8
diff --git a/engines/twine/resources.cpp b/engines/twine/resources.cpp
index 71099469f7..a3d78eb6f4 100644
--- a/engines/twine/resources.cpp
+++ b/engines/twine/resources.cpp
@@ -40,7 +40,7 @@ void Resources::initPalettes() {
_engine->setPalette(_engine->_screens->paletteRGBA);
// We use it now
- _engine->_screens->palCustom = 0;
+ _engine->_screens->palCustom = false;
}
void Resources::preloadSprites() {
diff --git a/engines/twine/scene.cpp b/engines/twine/scene.cpp
index 4b799be83e..b15df478d9 100644
--- a/engines/twine/scene.cpp
+++ b/engines/twine/scene.cpp
@@ -299,7 +299,7 @@ void Scene::resetScene() {
}
_engine->_actor->currentPositionInBodyPtrTab = 0;
- _engine->_screens->useAlternatePalette = 0;
+ _engine->_screens->useAlternatePalette = false;
}
void Scene::changeScene() {
@@ -377,8 +377,8 @@ void Scene::changeScene() {
_engine->_movements->heroMoved = 1;
_engine->_grid->useCellingGrid = -1;
_engine->_grid->cellingGridIdx = -1;
- _engine->_redraw->reqBgRedraw = 1;
- _engine->_screens->lockPalette = 0;
+ _engine->_redraw->reqBgRedraw = true;
+ _engine->_screens->lockPalette = false;
needChangeScene = -1;
changeRoomVar10 = 1;
@@ -500,7 +500,7 @@ void Scene::processActorZones(int32 actorIdx) {
_engine->_grid->newCameraX = zone->infoData.CameraView.x;
_engine->_grid->newCameraY = zone->infoData.CameraView.y;
_engine->_grid->newCameraZ = zone->infoData.CameraView.z;
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
}
break;
@@ -565,7 +565,7 @@ void Scene::processActorZones(int32 actorIdx) {
_engine->_grid->useCellingGrid = -1;
_engine->_grid->cellingGridIdx = -1;
_engine->_grid->createGridMap();
- _engine->_redraw->reqBgRedraw = 1;
+ _engine->_redraw->reqBgRedraw = true;
}
}
diff --git a/engines/twine/screens.cpp b/engines/twine/screens.cpp
index 2c2ad516e2..019d6c1009 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/screens.cpp
@@ -36,7 +36,7 @@ void Screens::adelineLogo() {
loadImage(RESSHQR_ADELINEIMG);
_engine->delaySkip(7000);
fadeOut(paletteRGBACustom);
- palCustom = 1;
+ palCustom = true;
}
void Screens::loadMenuImage(bool fade_in) {
@@ -48,7 +48,7 @@ void Screens::loadMenuImage(bool fade_in) {
_engine->setPalette(paletteRGBA);
}
- palCustom = 0;
+ palCustom = false;
}
void Screens::loadCustomPalette(int32 index) {
@@ -77,7 +77,7 @@ void Screens::loadImage(int32 index, bool fade_in) {
_engine->setPalette(paletteRGBACustom);
}
- palCustom = 1;
+ palCustom = true;
}
void Screens::loadImageDelay(int32 index, int32 time) {
@@ -181,14 +181,14 @@ void Screens::adjustCrossPalette(const uint32 *pal1, const uint32 *pal2) {
void Screens::fadeToBlack(uint32 *pal) {
int32 i = 0;
- if (palReseted == 0) {
+ if (!palResetted) {
for (i = 100; i >= 0; i -= 3) {
adjustPalette(0, 0, 0, pal, i);
_engine->_system->delayMillis(1000 / 50);
}
}
- palReseted = 1;
+ palResetted = true;
}
void Screens::fadeToPal(uint32 *pal) {
@@ -201,7 +201,7 @@ void Screens::fadeToPal(uint32 *pal) {
_engine->setPalette(pal);
- palReseted = 0;
+ palResetted = false;
}
void Screens::blackToWhite() {
@@ -220,7 +220,7 @@ void Screens::setBackPal() {
_engine->setPalette(paletteRGBA);
- palReseted = 1;
+ palResetted = true;
}
void Screens::fadePalRed(uint32 *pal) {
diff --git a/engines/twine/screens.h b/engines/twine/screens.h
index 6a3e6ba27d..7707a0de31 100644
--- a/engines/twine/screens.h
+++ b/engines/twine/screens.h
@@ -48,16 +48,16 @@ public:
uint32 paletteRGBACustom[NUMOFCOLORS]{0};
/** flag to check if a custom palette is in use */
- int16 palCustom = 0;
+ bool palCustom = false;
/** flag to check in the game palette was changed */
- int16 palReseted = 0;
+ bool palResetted = false;
/** flag to check if the main flag is locked */
- int16 lockPalette = 0;
+ bool lockPalette = false;
/** flag to check if we are using a different palette than the main one */
- int16 useAlternatePalette = 0;
+ bool useAlternatePalette = false;
/** main game palette */
uint8 *mainPalette = nullptr;
diff --git a/engines/twine/script_life.cpp b/engines/twine/script_life.cpp
index 7b54337dc5..a7c00ca898 100644
--- a/engines/twine/script_life.cpp
+++ b/engines/twine/script_life.cpp
@@ -625,7 +625,7 @@ static int32 lCAM_FOLLOW(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor
engine->_grid->newCameraZ = engine->_scene->sceneActors[followedActorIdx].z >> 9;
engine->_scene->currentlyFollowedActor = followedActorIdx;
- engine->_redraw->reqBgRedraw = 1;
+ engine->_redraw->reqBgRedraw = true;
}
return 0;
@@ -945,13 +945,13 @@ static int32 lZOOM(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->_screens->fadeToBlack(engine->_screens->mainPaletteRGBA);
engine->initMCGA();
engine->_screens->setBackPal();
- engine->_screens->lockPalette = 1;
+ engine->_screens->lockPalette = true;
} else if (!engine->zoomScreen && engine->_redraw->drawInGameTransBox) {
engine->_screens->fadeToBlack(engine->_screens->mainPaletteRGBA);
engine->initSVGA();
engine->_screens->setBackPal();
- engine->_screens->lockPalette = 1;
- engine->_redraw->reqBgRedraw = 1;
+ engine->_screens->lockPalette = true;
+ engine->_redraw->reqBgRedraw = true;
}
return 0;
@@ -1219,7 +1219,7 @@ static int32 lGRM_OFF(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
static int32 lFADE_PAL_RED(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->freezeTime();
engine->_screens->fadePalRed(engine->_screens->mainPaletteRGBA);
- engine->_screens->useAlternatePalette = 0;
+ engine->_screens->useAlternatePalette = false;
engine->unfreezeTime();
return 0;
}
@@ -1230,7 +1230,7 @@ static int32 lFADE_ALARM_RED(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->_screens->fadePalRed(engine->_screens->paletteRGBA);
- engine->_screens->useAlternatePalette = 1;
+ engine->_screens->useAlternatePalette = true;
engine->unfreezeTime();
return 0;
}
@@ -1241,7 +1241,7 @@ static int32 lFADE_ALARM_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->_screens->adjustCrossPalette(engine->_screens->paletteRGBA, engine->_screens->mainPaletteRGBA);
- engine->_screens->useAlternatePalette = 0;
+ engine->_screens->useAlternatePalette = false;
engine->unfreezeTime();
return 0;
}
@@ -1250,7 +1250,7 @@ static int32 lFADE_ALARM_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
static int32 lFADE_RED_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
engine->freezeTime();
engine->_screens->fadeRedPal(engine->_screens->mainPaletteRGBA);
- engine->_screens->useAlternatePalette = 0;
+ engine->_screens->useAlternatePalette = false;
engine->unfreezeTime();
return 0;
}
@@ -1261,7 +1261,7 @@ static int32 lFADE_RED_ALARM(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->_screens->fadeRedPal(engine->_screens->paletteRGBA);
- engine->_screens->useAlternatePalette = 1;
+ engine->_screens->useAlternatePalette = true;
engine->unfreezeTime();
return 0;
}
@@ -1272,7 +1272,7 @@ static int32 lFADE_PAL_ALARM(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
engine->_hqrdepack->hqrGetEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->_screens->adjustCrossPalette(engine->_screens->mainPaletteRGBA, engine->_screens->paletteRGBA);
- engine->_screens->useAlternatePalette = 1;
+ engine->_screens->useAlternatePalette = true;
engine->unfreezeTime();
return 0;
}
@@ -1326,14 +1326,14 @@ static int32 lSET_DARK_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *act
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->setPalette(engine->_screens->paletteRGBA);
}
- engine->_screens->useAlternatePalette = 1;
+ engine->_screens->useAlternatePalette = true;
engine->unfreezeTime();
return 0;
}
/*0x5D*/
static int32 lSET_NORMAL_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
- engine->_screens->useAlternatePalette = 0;
+ engine->_screens->useAlternatePalette = false;
if (!engine->_screens->lockPalette) {
engine->setPalette(engine->_screens->mainPaletteRGBA);
}
diff --git a/engines/twine/script_move.cpp b/engines/twine/script_move.cpp
index 61e7421327..38e5a10b08 100644
--- a/engines/twine/script_move.cpp
+++ b/engines/twine/script_move.cpp
@@ -298,14 +298,14 @@ static int32 mBACKGROUND(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor
if (!actor->staticFlags.bIsBackgrounded) {
actor->staticFlags.bIsBackgrounded = 1;
if (actor->dynamicFlags.bIsVisible) {
- engine->_redraw->reqBgRedraw = 1;
+ engine->_redraw->reqBgRedraw = true;
}
}
} else {
if (actor->staticFlags.bIsBackgrounded) {
actor->staticFlags.bIsBackgrounded = 0;
if (actor->dynamicFlags.bIsVisible) {
- engine->_redraw->reqBgRedraw = 1;
+ engine->_redraw->reqBgRedraw = true;
}
}
}
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 87bfb2d0ba..0d83d35ae9 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -265,11 +265,11 @@ void TwinEEngine::initEngine() {
}
void TwinEEngine::initMCGA() {
- _redraw->drawInGameTransBox = 1;
+ _redraw->drawInGameTransBox = true;
}
void TwinEEngine::initSVGA() {
- _redraw->drawInGameTransBox = 0;
+ _redraw->drawInGameTransBox = false;
}
void TwinEEngine::initAll() {
@@ -382,7 +382,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
switch (loopInventoryItem) {
case kiHolomap:
_holomap->processHolomap();
- _screens->lockPalette = 1;
+ _screens->lockPalette = true;
warning("Use inventory [kiHolomap] not implemented!\n");
break;
case kiMagicBall:
@@ -420,7 +420,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_screens->clearScreen();
flip();
setPalette(_screens->paletteRGBA);
- _screens->lockPalette = 1;
+ _screens->lockPalette = true;
} break;
case kiProtoPack:
if (_gameState->gameFlags[InventoryItems::kiBookOfBu]) {
@@ -529,7 +529,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_grid->newCameraX = _scene->sceneActors[_scene->currentlyFollowedActor].x >> 9;
_grid->newCameraY = _scene->sceneActors[_scene->currentlyFollowedActor].y >> 8;
_grid->newCameraZ = _scene->sceneActors[_scene->currentlyFollowedActor].z >> 9;
- _redraw->reqBgRedraw = 1;
+ _redraw->reqBgRedraw = true;
}
// Draw holomap
@@ -537,7 +537,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
freezeTime();
//TestRestoreModeSVGA(1);
_holomap->processHolomap();
- _screens->lockPalette = 1;
+ _screens->lockPalette = true;
unfreezeTime();
_redraw->redrawEngineActions(1);
}
@@ -676,8 +676,8 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_scene->heroPositionType = kReborn;
_scene->sceneHero->life = 50;
- _redraw->reqBgRedraw = 1;
- _screens->lockPalette = 1;
+ _redraw->reqBgRedraw = true;
+ _screens->lockPalette = true;
_gameState->inventoryNumLeafs--;
_actor->cropBottomScreen = 0;
} else { // game over
@@ -734,7 +734,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_grid->newCameraZ = 63;
}
- _redraw->reqBgRedraw = 1;
+ _redraw->reqBgRedraw = true;
}
}
@@ -756,8 +756,8 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
bool TwinEEngine::gameEngineLoop() { // mainLoop
uint32 start;
- _redraw->reqBgRedraw = 1;
- _screens->lockPalette = 1;
+ _redraw->reqBgRedraw = true;
+ _screens->lockPalette = true;
_movements->setActorAngle(0, -256, 5, &loopMovePtr);
while (quitGame == -1) {
Commit: 707856a3a085a6bdde337080ed58a2b79c0db55e
https://github.com/scummvm/scummvm/commit/707856a3a085a6bdde337080ed58a2b79c0db55e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed LanuageId text bank handling
Changed paths:
engines/twine/resources.h
engines/twine/text.cpp
engines/twine/text.h
engines/twine/twine.cpp
diff --git a/engines/twine/resources.h b/engines/twine/resources.h
index 3c5f6ae14b..949bf980af 100644
--- a/engines/twine/resources.h
+++ b/engines/twine/resources.h
@@ -119,23 +119,36 @@ public:
/** Initialize resource pointers */
void initResources();
+ // main palette
static constexpr const char *HQR_RESS_FILE = "ress.hqr";
+ // dialoges
static constexpr const char *HQR_TEXT_FILE = "text.hqr";
- static constexpr const char *HQR_FLASAMP_FILE = "flasamp.hqr";
- static constexpr const char *HQR_MIDI_MI_DOS_FILE = "midi_mi.hqr";
- static constexpr const char *HQR_MIDI_MI_WIN_FILE = "midi_mi_win.hqr";
- static constexpr const char *HQR_MIDI_MI_WIN_MP3_FILE = "midi_mi_win_mp3.hqr";
- static constexpr const char *HQR_MIDI_MI_WIN_OGG_FILE = "midi_mi_win_ogg.hqr";
+ // samples
static constexpr const char *HQR_SAMPLES_FILE = "samples.hqr";
+ // isometric grids
static constexpr const char *HQR_LBA_GRI_FILE = "lba_gri.hqr";
+ // isometric libraries
static constexpr const char *HQR_LBA_BLL_FILE = "lba_bll.hqr";
+ // isometric bricks
static constexpr const char *HQR_LBA_BRK_FILE = "lba_brk.hqr";
+ // scenes
static constexpr const char *HQR_SCENE_FILE = "scene.hqr";
+ // sprites
static constexpr const char *HQR_SPRITES_FILE = "sprites.hqr";
+ // model/animation entities
static constexpr const char *HQR_FILE3D_FILE = "file3d.hqr";
+ // 3d model data
static constexpr const char *HQR_BODY_FILE = "body.hqr";
+ // animations
static constexpr const char *HQR_ANIM_FILE = "anim.hqr";
+ // inventory objects
static constexpr const char *HQR_INVOBJ_FILE = "invobj.hqr";
+
+ static constexpr const char *HQR_FLASAMP_FILE = "flasamp.hqr";
+ static constexpr const char *HQR_MIDI_MI_DOS_FILE = "midi_mi.hqr";
+ static constexpr const char *HQR_MIDI_MI_WIN_FILE = "midi_mi_win.hqr";
+ static constexpr const char *HQR_MIDI_MI_WIN_MP3_FILE = "midi_mi_win_mp3.hqr";
+ static constexpr const char *HQR_MIDI_MI_WIN_OGG_FILE = "midi_mi_win_ogg.hqr";
};
} // namespace TwinE
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 6acc32fd5d..ca33859159 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -121,25 +121,22 @@ void Text::stopVox(int32 index) {
}
void Text::initTextBank(int32 bankIdx) { // InitDial
- int32 langIdx;
- int32 hqrSize;
-
// don't load if we already have the dialogue text bank loaded
- if (bankIdx == currentBankIdx)
+ if (bankIdx == currentBankIdx) {
return;
+ }
currentBankIdx = bankIdx;
- // RECHECK THIS LATER
- textVar2[0] = textVar3;
+ textVar2[0] = '\0';
// get index according with language
- langIdx = (_engine->cfgfile.LanguageId * 14) * 2 + bankIdx * 2;
-
- hqrSize = _engine->_hqrdepack->hqrGetallocEntry((uint8 **)&dialOrderPtr, Resources::HQR_TEXT_FILE, langIdx);
+ const int32 size = 28; // lba2 is 30
+ const int32 languageIndex = _engine->cfgfile.LanguageId * size + bankIdx * 2;
+ const int32 hqrSize = _engine->_hqrdepack->hqrGetallocEntry((uint8 **)&dialOrderPtr, Resources::HQR_TEXT_FILE, languageIndex);
numDialTextEntries = hqrSize / 2;
- hqrSize = _engine->_hqrdepack->hqrGetallocEntry((uint8 **)&dialTextPtr, Resources::HQR_TEXT_FILE, ++langIdx);
+ _engine->_hqrdepack->hqrGetallocEntry((uint8 **)&dialTextPtr, Resources::HQR_TEXT_FILE, languageIndex + 1);
if (_engine->cfgfile.LanguageCDId) {
initVoxBank(bankIdx);
diff --git a/engines/twine/text.h b/engines/twine/text.h
index 2eee225ea5..fdb7b5ac55 100644
--- a/engines/twine/text.h
+++ b/engines/twine/text.h
@@ -71,7 +71,6 @@ private:
// RECHECK THIS LATER
int32 currentBankIdx = -1; // textVar1
char textVar2[256] = "";
- uint8 textVar3 = 0u;
/** Dialogue text pointer */
char *dialTextPtr = nullptr; // bufText
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 0d83d35ae9..eab7e1258b 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -183,8 +183,8 @@ void TwinEEngine::initConfigurations() {
// TODO: use existing entries for some of the settings - like volume and so on.
const char *lng = Common::getLanguageDescription(_gameLang);
- cfgfile.LanguageId = getLanguageTypeIndex(lng) + 1;
- cfgfile.LanguageCDId = getLanguageTypeIndex(lng) + 1;
+ cfgfile.LanguageId = getLanguageTypeIndex(lng);
+ cfgfile.LanguageCDId = getLanguageTypeIndex(lng);
cfgfile.FlagDisplayText = ConfGetOrDefault("FlagDisplayText", "ON") == "ON";
cfgfile.FlagKeepVoice = ConfGetOrDefault("FlagKeepVoice", "OFF") == "ON";
const Common::String midiType = ConfGetOrDefault("MidiType", "auto");
Commit: 9847b34a355f9f0c03c87b76967db52cb84401ef
https://github.com/scummvm/scummvm/commit/9847b34a355f9f0c03c87b76967db52cb84401ef
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: refactored the way the voice playback is handled
Changed paths:
engines/twine/gamestate.cpp
engines/twine/holomap.cpp
engines/twine/menu.cpp
engines/twine/menuoptions.cpp
engines/twine/text.cpp
engines/twine/text.h
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 273e80f7b0..cdd09ed4b8 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -326,14 +326,8 @@ void GameState::processFoundItem(int32 item) {
_engine->_sound->playSample(41, 0x1000, 1, 0x80, 0x80, 0x80, -1);
// process vox play
- {
- int32 tmpLanguageCDId;
- _engine->_music->stopMusic();
- tmpLanguageCDId = _engine->cfgfile.LanguageCDId;
- //_engine->cfgfile.LanguageCDId = 0; // comented so we can init vox bank
- _engine->_text->initTextBank(2);
- _engine->cfgfile.LanguageCDId = tmpLanguageCDId;
- }
+ _engine->_music->stopMusic();
+ _engine->_text->initTextBank(2);
_engine->_interface->resetClip();
_engine->_text->initText(item);
@@ -342,9 +336,7 @@ void GameState::processFoundItem(int32 item) {
textState = 1;
quitItem = 0;
- if (_engine->cfgfile.LanguageCDId) {
- _engine->_text->initVoxToPlay(item);
- }
+ _engine->_text->initVoxToPlay(item);
currentAnim = _engine->_animations->animTable[_engine->_animations->getBodyAnimIndex(kFoundItem, 0)];
@@ -433,9 +425,7 @@ void GameState::processFoundItem(int32 item) {
delaySkip(1);
} while (!_engine->_keyboard.internalKeyCode);*/
- if (_engine->cfgfile.LanguageCDId && _engine->_sound->isSamplePlaying(_engine->_text->currDialTextEntry)) {
- _engine->_text->stopVox(_engine->_text->currDialTextEntry);
- }
+ _engine->_text->stopVox(_engine->_text->currDialTextEntry);
_engine->_scene->sceneHero->animTimerData = tmpAnimTimer;
}
@@ -461,8 +451,7 @@ void GameState::processGameChoices(int32 choiceIdx) {
choiceAnswer = gameChoices[gameChoicesSettings[0]];
// get right VOX entry index
- if (_engine->cfgfile.LanguageCDId) {
- _engine->_text->initVoxToPlay(choiceAnswer);
+ if (_engine->_text->initVoxToPlay(choiceAnswer)) {
while (_engine->_text->playVoxSimple(_engine->_text->currDialTextEntry)) {
if (_engine->shouldQuit()) {
break;
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index fdeb82de14..e58a1015a9 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -136,8 +136,6 @@ void Holomap::processHolomap() {
drawHolomapTitle(320, 25);
_engine->_renderer->setCameraPosition(320, 190, 128, 1024, 1024);
- const int32 tmpLanguageCDId = _engine->cfgfile.LanguageCDId;
- _engine->cfgfile.LanguageCDId = 0;
_engine->_text->initTextBank(2);
_engine->_text->setFontCrossColor(9);
@@ -153,7 +151,6 @@ void Holomap::processHolomap() {
// TODO memcopy reset palette
- _engine->cfgfile.LanguageCDId = tmpLanguageCDId;
_engine->unfreezeTime();
}
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index d1189fdc66..ffb9b568c5 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -897,10 +897,6 @@ void Menu::drawBehaviourMenu(int32 angle) {
}
void Menu::processBehaviourMenu() {
- int32 tmpLanguageCD;
- int32 tmpTextBank;
- int32 tmpTime;
-
if (_engine->_actor->heroBehaviour == kProtoPack) {
_engine->_sound->stopSamples();
_engine->_actor->setBehaviour(kNormal);
@@ -917,10 +913,7 @@ void Menu::processBehaviourMenu() {
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- tmpLanguageCD = _engine->cfgfile.LanguageCDId;
- _engine->cfgfile.LanguageCDId = 0;
-
- tmpTextBank = _engine->_text->currentTextBank;
+ int32 tmpTextBank = _engine->_text->currentTextBank;
_engine->_text->currentTextBank = -1;
_engine->_text->initTextBank(0);
@@ -933,7 +926,7 @@ void Menu::processBehaviourMenu() {
_engine->readKeys();
- tmpTime = _engine->lbaTime;
+ int32 tmpTime = _engine->lbaTime;
while (_engine->_keyboard.skippedKey & 4 || (_engine->_keyboard.internalKeyCode >= twineactions[TwinEActionType::QuickBehaviourNormal].localKey && _engine->_keyboard.internalKeyCode <= twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey)) {
_engine->readKeys();
@@ -986,8 +979,6 @@ void Menu::processBehaviourMenu() {
_engine->_text->currentTextBank = tmpTextBank;
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
-
- _engine->cfgfile.LanguageCDId = tmpLanguageCD;
}
void Menu::drawMagicItemsBox(int32 left, int32 top, int32 right, int32 bottom, int32 color) { // Rect
@@ -1040,10 +1031,9 @@ void Menu::drawInventoryItems() {
void Menu::processInventoryMenu() {
int32 di = 1;
- int32 prevSelectedItem, tmpLanguageCD, bx, tmpAlphaLight, tmpBetaLight;
- tmpAlphaLight = _engine->_scene->alphaLight;
- tmpBetaLight = _engine->_scene->betaLight;
+ int32 tmpAlphaLight = _engine->_scene->alphaLight;
+ int32 tmpBetaLight = _engine->_scene->betaLight;
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
@@ -1057,19 +1047,16 @@ void Menu::processInventoryMenu() {
drawInventoryItems();
- tmpLanguageCD = _engine->cfgfile.LanguageCDId;
- _engine->cfgfile.LanguageCDId = 0;
-
_engine->_text->initTextBank(2);
- bx = 3;
+ int32 bx = 3;
_engine->_text->setFontCrossColor(4);
_engine->_text->initDialogueBox();
while (_engine->_keyboard.internalKeyCode != 1) {
_engine->readKeys();
- prevSelectedItem = inventorySelectedItem;
+ int32 prevSelectedItem = inventorySelectedItem;
if (!di) {
_engine->_keyboard.key = _engine->_keyboard.pressedKey;
@@ -1176,8 +1163,6 @@ void Menu::processInventoryMenu() {
_engine->_gameState->initEngineProjections();
- _engine->cfgfile.LanguageCDId = tmpLanguageCD;
-
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
while (_engine->_keyboard.internalKeyCode != 0 && _engine->_keyboard.skippedKey != 0) {
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index d176d4df61..0ba8e859bf 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -96,13 +96,11 @@ void MenuOptions::newGame() {
}
void MenuOptions::showCredits() {
- int32 tmpShadowMode, tmpLanguageCDIdx;
+ int32 tmpShadowMode;
canShowCredits = 1;
tmpShadowMode = _engine->cfgfile.ShadowMode;
- tmpLanguageCDIdx = _engine->cfgfile.LanguageCDId;
_engine->cfgfile.ShadowMode = 0;
- _engine->cfgfile.LanguageCDId = 0;
_engine->_gameState->initEngineVars();
_engine->_scene->currentSceneIdx = 119;
_engine->_scene->needChangeScene = 119;
@@ -111,7 +109,6 @@ void MenuOptions::showCredits() {
canShowCredits = 0;
_engine->cfgfile.ShadowMode = tmpShadowMode;
- _engine->cfgfile.LanguageCDId = tmpLanguageCDIdx;
_engine->_screens->clearScreen();
_engine->flip();
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index ca33859159..ca9d94c534 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -66,10 +66,9 @@ void Text::initVoxBank(int32 bankIdx) {
// TODO check the rest to reverse
}
-int32 Text::initVoxToPlay(int32 index) { // setVoxFileAtDigit
- int32 i = 0;
+
+bool Text::initVoxToPlay(int32 index) { // setVoxFileAtDigit
int32 currIdx = 0;
- int32 orderIdx = 0;
int16 *localOrderBuf = (int16 *)dialOrderPtr;
@@ -77,8 +76,8 @@ int32 Text::initVoxToPlay(int32 index) { // setVoxFileAtDigit
hasHiddenVox = 0;
// choose right text from order index
- for (i = 0; i < numDialTextEntries; i++) {
- orderIdx = *(localOrderBuf++);
+ for (int32 i = 0; i < numDialTextEntries; i++) {
+ int32 orderIdx = *(localOrderBuf++);
if (orderIdx == index) {
currIdx = i;
break;
@@ -89,35 +88,35 @@ int32 Text::initVoxToPlay(int32 index) { // setVoxFileAtDigit
_engine->_sound->playVoxSample(currDialTextEntry);
- return 1;
+ return true;
}
-int32 Text::playVox(int32 index) {
- if (_engine->cfgfile.LanguageCDId && index) {
- if (hasHiddenVox && !_engine->_sound->isSamplePlaying(index)) {
- _engine->_sound->playVoxSample(index);
- return 1;
- }
+bool Text::playVox(int32 index) {
+ if (!_engine->cfgfile.Voice) {
+ return false;
+ }
+ if (hasHiddenVox && !_engine->_sound->isSamplePlaying(index)) {
+ _engine->_sound->playVoxSample(index);
+ return true;
}
- return 0;
+ return false;
}
-int32 Text::playVoxSimple(int32 index) {
- if (_engine->cfgfile.LanguageCDId && index) {
- playVox(index);
-
- if (_engine->_sound->isSamplePlaying(index)) {
- return 1;
- }
+bool Text::playVoxSimple(int32 index) {
+ if (_engine->_sound->isSamplePlaying(index)) {
+ return true;
}
-
- return 0;
+ return playVox(index);
}
-void Text::stopVox(int32 index) {
+bool Text::stopVox(int32 index) {
+ if (!_engine->_sound->isSamplePlaying(index)) {
+ return false;
+ }
hasHiddenVox = 0;
_engine->_sound->stopSample(index);
+ return true;
}
void Text::initTextBank(int32 bankIdx) { // InitDial
@@ -138,9 +137,7 @@ void Text::initTextBank(int32 bankIdx) { // InitDial
_engine->_hqrdepack->hqrGetallocEntry((uint8 **)&dialTextPtr, Resources::HQR_TEXT_FILE, languageIndex + 1);
- if (_engine->cfgfile.LanguageCDId) {
- initVoxBank(bankIdx);
- }
+ initVoxBank(bankIdx);
}
void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
@@ -598,9 +595,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
// get right VOX entry index
- if (_engine->cfgfile.LanguageCDId) {
- initVoxToPlay(index);
- }
+ initVoxToPlay(index);
// if we don't display text, than still plays vox file
if (_engine->cfgfile.FlagDisplayText) {
@@ -654,9 +649,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
hasHiddenVox = 0;
- if (_engine->cfgfile.LanguageCDId && _engine->_sound->isSamplePlaying(currDialTextEntry)) {
- stopVox(currDialTextEntry);
- }
+ stopVox(currDialTextEntry);
printTextVar13 = 0;
@@ -707,9 +700,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
voxHiddenIndex = 0;
}
- if (_engine->cfgfile.LanguageCDId && _engine->_sound->isSamplePlaying(currDialTextEntry)) {
- stopVox(currDialTextEntry);
- }
+ stopVox(currDialTextEntry);
_engine->_interface->loadClip();
}
@@ -833,9 +824,7 @@ void Text::drawAskQuestion(int32 index) { // MyDial
int32 textStatus = 1;
// get right VOX entry index
- if (_engine->cfgfile.LanguageCDId) {
- initVoxToPlay(index);
- }
+ initVoxToPlay(index);
initText(index);
initDialogueBox();
@@ -867,19 +856,17 @@ void Text::drawAskQuestion(int32 index) { // MyDial
_engine->_system->delayMillis(1);
} while (textStatus);
- if (_engine->cfgfile.LanguageCDId) {
- while (playVoxSimple(currDialTextEntry)) {
- if (_engine->shouldQuit()) {
- break;
- }
+ while (playVoxSimple(currDialTextEntry)) {
+ if (_engine->shouldQuit()) {
+ break;
}
+ }
- hasHiddenVox = 0;
- voxHiddenIndex = 0;
+ hasHiddenVox = 0;
+ voxHiddenIndex = 0;
- if (_engine->_sound->isSamplePlaying(currDialTextEntry)) {
- stopVox(currDialTextEntry);
- }
+ if (_engine->_sound->isSamplePlaying(currDialTextEntry)) {
+ stopVox(currDialTextEntry);
}
printTextVar13 = 0;
diff --git a/engines/twine/text.h b/engines/twine/text.h
index fdb7b5ac55..6e7f917a7d 100644
--- a/engines/twine/text.h
+++ b/engines/twine/text.h
@@ -228,10 +228,10 @@ public:
void drawAskQuestion(int32 index);
- int32 playVox(int32 index);
- int32 playVoxSimple(int32 index);
- void stopVox(int32 index);
- int32 initVoxToPlay(int32 index);
+ bool playVox(int32 index);
+ bool playVoxSimple(int32 index);
+ bool stopVox(int32 index);
+ bool initVoxToPlay(int32 index);
};
} // namespace TwinE
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index eab7e1258b..3df07c78b0 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -184,9 +184,8 @@ void TwinEEngine::initConfigurations() {
const char *lng = Common::getLanguageDescription(_gameLang);
cfgfile.LanguageId = getLanguageTypeIndex(lng);
- cfgfile.LanguageCDId = getLanguageTypeIndex(lng);
+ cfgfile.Voice = ConfGetOrDefault("Voice", "ON") == "ON";
cfgfile.FlagDisplayText = ConfGetOrDefault("FlagDisplayText", "ON") == "ON";
- cfgfile.FlagKeepVoice = ConfGetOrDefault("FlagKeepVoice", "OFF") == "ON";
const Common::String midiType = ConfGetOrDefault("MidiType", "auto");
if (midiType == "None") {
cfgfile.MidiType = MIDIFILE_NONE;
@@ -358,14 +357,11 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
if (loopCurrentKey == twineactions[TwinEActionType::OptionsMenu].localKey) {
- int tmpLangCD = cfgfile.LanguageCDId;
freezeTime();
_sound->pauseSamples();
_menu->OptionsMenuSettings[5] = 15;
- cfgfile.LanguageCDId = 0;
_text->initTextBank(0);
_menu->optionsMenu();
- cfgfile.LanguageCDId = tmpLangCD;
_text->initTextBank(_text->currentTextBank + 3);
//TODO: play music
_sound->resumeSamples();
@@ -457,18 +453,14 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
} break;
case kiBonusList: {
- int32 tmpLanguageCDIdx;
- tmpLanguageCDIdx = cfgfile.LanguageCDId;
unfreezeTime();
_redraw->redrawEngineActions(1);
freezeTime();
- cfgfile.LanguageCDId = 0;
_text->initTextBank(2);
_text->textClipFull();
_text->setFontCrossColor(15);
_text->drawTextFullscreen(162);
_text->textClipSmall();
- cfgfile.LanguageCDId = tmpLanguageCDIdx;
_text->initTextBank(_text->currentTextBank + 3);
} break;
case kiCloverLeaf:
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index f8df0bdd0a..308cdce509 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -91,12 +91,9 @@ enum MovieType {
struct ConfigFile {
/** Index into the LanguageTypes array. */
int32 LanguageId = 0;
- /** Index into the LanguageTypes array. */
- int32 LanguageCDId = 0;
+ bool Voice = true;
/** Enable/Disable game dialogues */
bool FlagDisplayText = false;
- /** Save voice files on hard disk */
- bool FlagKeepVoice = false;
/** Type of music file to be used */
MidiFileType MidiType = MIDIFILE_NONE;
/** *Game version */
Commit: 5d37d79ebbb91b36ac5858a5bf20b7c4fe63ca13
https://github.com/scummvm/scummvm/commit/5d37d79ebbb91b36ac5858a5bf20b7c4fe63ca13
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: safeguards
Changed paths:
engines/twine/hqrdepack.cpp
diff --git a/engines/twine/hqrdepack.cpp b/engines/twine/hqrdepack.cpp
index 5b54b0dcc8..0ea8a951b9 100644
--- a/engines/twine/hqrdepack.cpp
+++ b/engines/twine/hqrdepack.cpp
@@ -30,6 +30,8 @@ namespace TwinE {
HQRDepack::HQRDepack(TwinEEngine *engine) : _engine(engine) {}
+#define wrap(cmd) if ((cmd) == 0) { warning("Failed to execute " #cmd ); return 0; }
+
void HQRDepack::hqrDecompressEntry(uint8 *dst, uint8 *src, int32 decompsize, int32 mode) {
do {
uint8 b = *(src++);
@@ -108,23 +110,23 @@ int32 HQRDepack::hqrGetEntry(uint8 *ptr, const char *filename, int32 index) {
return 0;
}
- file.seek(index * 4);
+ wrap(file.seek(index * 4))
uint32 offsetToData = file.readUint32LE();
- file.seek(offsetToData);
+ wrap(file.seek(offsetToData))
uint32 realSize = file.readUint32LE();
uint32 compSize = file.readUint32LE();
uint16 mode = file.readUint16LE();
// uncompressed
if (mode == 0) {
- file.read(ptr, realSize);
+ wrap(file.read(ptr, realSize))
}
// compressed: modes (1 & 2)
else if (mode == 1 || mode == 2) {
uint8 *compDataPtr = 0;
compDataPtr = (uint8 *)malloc(compSize);
- file.read(compDataPtr, compSize);
+ wrap(file.read(compDataPtr, compSize))
hqrDecompressEntry(ptr, compDataPtr, realSize, mode);
free(compDataPtr);
}
@@ -143,20 +145,20 @@ int HQRDepack::hqrEntrySize(const char *filename, int32 index) {
}
uint32 headerSize;
- file.read(&headerSize, 4);
+ wrap(file.read(&headerSize, 4))
if ((uint32)index >= headerSize / 4) {
warning("HQR WARNING: Invalid entry index!!");
return 0;
}
- file.seek(index * 4);
+ wrap(file.seek(index * 4))
uint32 offsetToData;
- file.read(&offsetToData, 4);
+ wrap(file.read(&offsetToData, 4))
- file.seek(offsetToData);
+ wrap(file.seek(offsetToData))
uint32 realSize;
- file.read(&realSize, 4);
+ wrap(file.read(&realSize, 4))
return realSize;
}
@@ -172,7 +174,7 @@ int HQRDepack::hqrNumEntries(const char *filename) {
}
uint32 headerSize;
- file.read(&headerSize, 4);
+ wrap(file.read(&headerSize, 4))
return (int)headerSize / 4;
}
@@ -202,44 +204,44 @@ int32 HQRDepack::hqrGetVoxEntry(uint8 *ptr, const char *filename, int32 index, i
}
uint32 headerSize;
- file.read(&headerSize, 4);
+ wrap(file.read(&headerSize, 4))
if ((uint32)index >= headerSize / 4) {
warning("HQR WARNING: Invalid entry index!!");
return 0;
}
- file.seek(index * 4);
+ wrap(file.seek(index * 4))
uint32 offsetToData;
- file.read(&offsetToData, 4);
+ wrap(file.read(&offsetToData, 4))
- file.seek(offsetToData);
+ wrap(file.seek(offsetToData))
uint32 realSize;
- file.read(&realSize, 4);
+ wrap(file.read(&realSize, 4))
uint32 compSize;
- file.read(&compSize, 4);
+ wrap(file.read(&compSize, 4))
uint16 mode;
- file.read(&mode, 2);
+ wrap(file.read(&mode, 2))
// exist hidden entries
for (int32 i = 0; i < hiddenIndex; i++) {
- file.seek(offsetToData + compSize + 10); // hidden entry
+ wrap(file.seek(offsetToData + compSize + 10)) // hidden entry
offsetToData = offsetToData + compSize + 10; // current hidden offset
- file.read(&realSize, 4);
- file.read(&compSize, 4);
- file.read(&mode, 2);
+ wrap(file.read(&realSize, 4))
+ wrap(file.read(&compSize, 4))
+ wrap(file.read(&mode, 2))
}
// uncompressed
if (mode == 0) {
- file.read(ptr, realSize);
+ wrap(file.read(ptr, realSize))
}
// compressed: modes (1 & 2)
else if (mode == 1 || mode == 2) {
uint8 *compDataPtr = 0;
compDataPtr = (uint8 *)malloc(compSize);
- file.read(compDataPtr, compSize);
+ wrap(file.read(compDataPtr, compSize))
hqrDecompressEntry(ptr, compDataPtr, realSize, mode);
free(compDataPtr);
}
@@ -258,30 +260,30 @@ int HQRDepack::hqrVoxEntrySize(const char *filename, int32 index, int32 hiddenIn
}
uint32 headerSize;
- file.read(&headerSize, 4);
+ wrap(file.read(&headerSize, 4))
if ((uint32)index >= headerSize / 4) {
warning("HQR WARNING: Invalid entry index!!");
return 0;
}
- file.seek(index * 4);
+ wrap(file.seek(index * 4))
uint32 offsetToData;
- file.read(&offsetToData, 4);
+ wrap(file.read(&offsetToData, 4))
- file.seek(offsetToData);
+ wrap(file.seek(offsetToData))
uint32 realSize;
- file.read(&realSize, 4);
+ wrap(file.read(&realSize, 4))
uint32 compSize;
- file.read(&compSize, 4);
+ wrap(file.read(&compSize, 4))
// exist hidden entries
for (int32 i = 0; i < hiddenIndex; i++) {
- file.seek(offsetToData + compSize + 10); // hidden entry
+ wrap(file.seek(offsetToData + compSize + 10)) // hidden entry
offsetToData = offsetToData + compSize + 10; // current hidden offset
- file.read(&realSize, 4);
- file.read(&compSize, 4);
+ wrap(file.read(&realSize, 4))
+ wrap(file.read(&compSize, 4))
}
return realSize;
@@ -300,4 +302,6 @@ int32 HQRDepack::hqrGetallocVoxEntry(uint8 **ptr, const char *filename, int32 in
return size;
}
+#undef wrap
+
} // namespace TwinE
Commit: 13acf495a867046eacec5472e6b3ed251a63186c
https://github.com/scummvm/scummvm/commit/13acf495a867046eacec5472e6b3ed251a63186c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: error checks
Changed paths:
engines/twine/text.cpp
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index ca9d94c534..c9c9cccc7b 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -132,11 +132,17 @@ void Text::initTextBank(int32 bankIdx) { // InitDial
const int32 size = 28; // lba2 is 30
const int32 languageIndex = _engine->cfgfile.LanguageId * size + bankIdx * 2;
const int32 hqrSize = _engine->_hqrdepack->hqrGetallocEntry((uint8 **)&dialOrderPtr, Resources::HQR_TEXT_FILE, languageIndex);
+ if (hqrSize == 0) {
+ warning("Failed to initialize text bank %i from file %s", languageIndex, Resources::HQR_TEXT_FILE);
+ return;
+ }
numDialTextEntries = hqrSize / 2;
- _engine->_hqrdepack->hqrGetallocEntry((uint8 **)&dialTextPtr, Resources::HQR_TEXT_FILE, languageIndex + 1);
-
+ if (_engine->_hqrdepack->hqrGetallocEntry((uint8 **)&dialTextPtr, Resources::HQR_TEXT_FILE, languageIndex + 1) == 0) {
+ warning("Failed to initialize additional text bank %i from file %s", languageIndex + 1, Resources::HQR_TEXT_FILE);
+ return;
+ }
initVoxBank(bankIdx);
}
@@ -227,7 +233,7 @@ void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
void Text::drawCharacterShadow(int32 x, int32 y, uint8 character, int32 color) { // drawDoubleLetter
int32 left, top, right, bottom;
- if (character != 0x20) {
+ if (character != ' ') {
// shadow color
setFontColor(0);
drawCharacter(x + 2, y + 4, character);
Commit: 401ab87715fc47a1f2d35b602e04fb4536b091d8
https://github.com/scummvm/scummvm/commit/401ab87715fc47a1f2d35b602e04fb4536b091d8
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: error checks
Changed paths:
engines/twine/actor.cpp
engines/twine/hqrdepack.cpp
engines/twine/resources.cpp
diff --git a/engines/twine/actor.cpp b/engines/twine/actor.cpp
index 795f4faff0..79be9d94cf 100644
--- a/engines/twine/actor.cpp
+++ b/engines/twine/actor.cpp
@@ -66,23 +66,33 @@ void Actor::restartHeroScene() {
}
void Actor::loadHeroEntities() {
- _engine->_hqrdepack->hqrGetallocEntry(&heroEntityATHLETIC, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROATHLETIC);
+ if (_engine->_hqrdepack->hqrGetallocEntry(&heroEntityATHLETIC, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROATHLETIC) == 0) {
+ error("Failed to load actor athletic 3d data");
+ }
_engine->_scene->sceneHero->entityDataPtr = heroEntityATHLETIC;
heroAnimIdxATHLETIC = _engine->_animations->getBodyAnimIndex(0, 0);
- _engine->_hqrdepack->hqrGetallocEntry(&heroEntityAGGRESSIVE, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROAGGRESSIVE);
+ if (_engine->_hqrdepack->hqrGetallocEntry(&heroEntityAGGRESSIVE, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROAGGRESSIVE) == 0) {
+ error("Failed to load actor aggressive 3d data");
+ }
_engine->_scene->sceneHero->entityDataPtr = heroEntityAGGRESSIVE;
heroAnimIdxAGGRESSIVE = _engine->_animations->getBodyAnimIndex(0, 0);
- _engine->_hqrdepack->hqrGetallocEntry(&heroEntityDISCRETE, Resources::HQR_FILE3D_FILE, FILE3DHQR_HERODISCRETE);
+ if (_engine->_hqrdepack->hqrGetallocEntry(&heroEntityDISCRETE, Resources::HQR_FILE3D_FILE, FILE3DHQR_HERODISCRETE) == 0) {
+ error("Failed to load actor discrete 3d data");
+ }
_engine->_scene->sceneHero->entityDataPtr = heroEntityDISCRETE;
heroAnimIdxDISCRETE = _engine->_animations->getBodyAnimIndex(0, 0);
- _engine->_hqrdepack->hqrGetallocEntry(&heroEntityPROTOPACK, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROPROTOPACK);
+ if (_engine->_hqrdepack->hqrGetallocEntry(&heroEntityPROTOPACK, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROPROTOPACK) == 0) {
+ error("Failed to load actor protopack 3d data");
+ }
_engine->_scene->sceneHero->entityDataPtr = heroEntityPROTOPACK;
heroAnimIdxPROTOPACK = _engine->_animations->getBodyAnimIndex(0, 0);
- _engine->_hqrdepack->hqrGetallocEntry(&heroEntityNORMAL, Resources::HQR_FILE3D_FILE, FILE3DHQR_HERONORMAL);
+ if (_engine->_hqrdepack->hqrGetallocEntry(&heroEntityNORMAL, Resources::HQR_FILE3D_FILE, FILE3DHQR_HERONORMAL) == 0) {
+ error("Failed to load actor normal 3d data");
+ }
_engine->_scene->sceneHero->entityDataPtr = heroEntityNORMAL;
heroAnimIdxNORMAL = _engine->_animations->getBodyAnimIndex(0, 0);
diff --git a/engines/twine/hqrdepack.cpp b/engines/twine/hqrdepack.cpp
index 0ea8a951b9..bd2e2a9284 100644
--- a/engines/twine/hqrdepack.cpp
+++ b/engines/twine/hqrdepack.cpp
@@ -175,7 +175,7 @@ int HQRDepack::hqrNumEntries(const char *filename) {
uint32 headerSize;
wrap(file.read(&headerSize, 4))
- return (int)headerSize / 4;
+ return ((int)headerSize / 4) - 1;
}
int32 HQRDepack::hqrGetallocEntry(uint8 **ptr, const char *filename, int32 index) {
diff --git a/engines/twine/resources.cpp b/engines/twine/resources.cpp
index a3d78eb6f4..da7cbab00c 100644
--- a/engines/twine/resources.cpp
+++ b/engines/twine/resources.cpp
@@ -44,37 +44,29 @@ void Resources::initPalettes() {
}
void Resources::preloadSprites() {
- int32 i;
- int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_SPRITES_FILE) - 1;
-
- for (i = 0; i < numEntries; i++) {
+ const int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_SPRITES_FILE);
+ for (int32 i = 0; i < numEntries; i++) {
_engine->_actor->spriteSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&_engine->_actor->spriteTable[i], Resources::HQR_SPRITES_FILE, i);
}
}
void Resources::preloadAnimations() {
- int32 i;
- int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_ANIM_FILE) - 1;
-
- for (i = 0; i < numEntries; i++) {
+ const int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_ANIM_FILE);
+ for (int32 i = 0; i < numEntries; i++) {
_engine->_animations->animSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&_engine->_animations->animTable[i], Resources::HQR_ANIM_FILE, i);
}
}
void Resources::preloadSamples() {
- int32 i;
- int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_SAMPLES_FILE) - 1;
-
- for (i = 0; i < numEntries; i++) {
+ const int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_SAMPLES_FILE);
+ for (int32 i = 0; i < numEntries; i++) {
_engine->_sound->samplesSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&_engine->_sound->samplesTable[i], Resources::HQR_SAMPLES_FILE, i);
}
}
void Resources::preloadInventoryItems() {
- int32 i;
- int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_INVOBJ_FILE) - 1;
-
- for (i = 0; i < numEntries; i++) {
+ const int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_INVOBJ_FILE);
+ for (int32 i = 0; i < numEntries; i++) {
inventorySizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&inventoryTable[i], Resources::HQR_INVOBJ_FILE, i);
}
}
@@ -83,17 +75,21 @@ void Resources::initResources() {
// Menu and in-game palette
initPalettes();
- // load LBA font
- _engine->_hqrdepack->hqrGetallocEntry(&_engine->_text->fontPtr, Resources::HQR_RESS_FILE, RESSHQR_LBAFONT);
+ if (_engine->_hqrdepack->hqrGetallocEntry(&_engine->_text->fontPtr, Resources::HQR_RESS_FILE, RESSHQR_LBAFONT) == 0) {
+ error("Failed to load font");
+ }
_engine->_text->setFontParameters(2, 8);
_engine->_text->setFontColor(14);
_engine->_text->setTextCrossColor(136, 143, 2);
- _engine->_hqrdepack->hqrGetallocEntry(&_engine->_scene->spriteShadowPtr, Resources::HQR_RESS_FILE, RESSHQR_SPRITESHADOW);
+ if (_engine->_hqrdepack->hqrGetallocEntry(&_engine->_scene->spriteShadowPtr, Resources::HQR_RESS_FILE, RESSHQR_SPRITESHADOW) == 0) {
+ error("Failed to load sprite shadow");
+ }
- // load sprite actors bounding box data
- _engine->_hqrdepack->hqrGetallocEntry(&_engine->_scene->spriteBoundingBoxPtr, Resources::HQR_RESS_FILE, RESSHQR_SPRITEBOXDATA);
+ if (_engine->_hqrdepack->hqrGetallocEntry(&_engine->_scene->spriteBoundingBoxPtr, Resources::HQR_RESS_FILE, RESSHQR_SPRITEBOXDATA) == 0) {
+ error("Failed to load actors bounding box data");
+ }
preloadSprites();
preloadAnimations();
Commit: 3fbb55b76e10156683231a060bb68fbf5111fb6d
https://github.com/scummvm/scummvm/commit/3fbb55b76e10156683231a060bb68fbf5111fb6d
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: sanity checks for resource loading
Changed paths:
engines/twine/resources.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/resources.cpp b/engines/twine/resources.cpp
index da7cbab00c..1a0d90235c 100644
--- a/engines/twine/resources.cpp
+++ b/engines/twine/resources.cpp
@@ -45,6 +45,10 @@ void Resources::initPalettes() {
void Resources::preloadSprites() {
const int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_SPRITES_FILE);
+ if (numEntries > NUM_SPRITES) {
+ error("Max allowed sprites exceeded: %i/%i", numEntries, NUM_SPRITES);
+ }
+ debug("preload %i sprites", numEntries);
for (int32 i = 0; i < numEntries; i++) {
_engine->_actor->spriteSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&_engine->_actor->spriteTable[i], Resources::HQR_SPRITES_FILE, i);
}
@@ -52,6 +56,10 @@ void Resources::preloadSprites() {
void Resources::preloadAnimations() {
const int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_ANIM_FILE);
+ if (numEntries > NUM_ANIMS) {
+ error("Max allowed animations exceeded: %i/%i", numEntries, NUM_ANIMS);
+ }
+ debug("preload %i animations", numEntries);
for (int32 i = 0; i < numEntries; i++) {
_engine->_animations->animSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&_engine->_animations->animTable[i], Resources::HQR_ANIM_FILE, i);
}
@@ -59,6 +67,10 @@ void Resources::preloadAnimations() {
void Resources::preloadSamples() {
const int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_SAMPLES_FILE);
+ if (numEntries > NUM_SAMPLES) {
+ error("Max allowed samples exceeded: %i/%i", numEntries, NUM_SAMPLES);
+ }
+ debug("preload %i samples", numEntries);
for (int32 i = 0; i < numEntries; i++) {
_engine->_sound->samplesSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&_engine->_sound->samplesTable[i], Resources::HQR_SAMPLES_FILE, i);
}
@@ -66,6 +78,10 @@ void Resources::preloadSamples() {
void Resources::preloadInventoryItems() {
const int32 numEntries = _engine->_hqrdepack->hqrNumEntries(Resources::HQR_INVOBJ_FILE);
+ if (numEntries > NUM_INVENTORY_ITEMS) {
+ error("Max allowed inventory items exceeded: %i/%i", numEntries, NUM_INVENTORY_ITEMS);
+ }
+ debug("preload %i inventory items", numEntries);
for (int32 i = 0; i < numEntries; i++) {
inventorySizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&inventoryTable[i], Resources::HQR_INVOBJ_FILE, i);
}
@@ -93,7 +109,7 @@ void Resources::initResources() {
preloadSprites();
preloadAnimations();
- //preloadSamples();
+ preloadSamples();
preloadInventoryItems();
}
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 3df07c78b0..baf7b41fea 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -125,7 +125,18 @@ TwinEEngine::~TwinEEngine() {
}
Common::Error TwinEEngine::run() {
- debug("Starting twine");
+ /** Engine current version */
+ const char *ENGINE_VERSION = "0.2.2";
+
+ // Show engine information
+ debug("TwinEngine v%s", ENGINE_VERSION);
+ debug("(c)2002 The TwinEngine team.");
+ debug("(c)2020 The ScummVM team.");
+ debug("Refer to the credits for further details.");
+ debug("Released under the terms of the GNU GPL license version 2 (or, at your opinion, any later). See COPYING file.");
+ debug("The original Little Big Adventure game is:");
+ debug("(c)1994 by Adeline Software International, All Rights Reserved.");
+
syncSoundSettings();
initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT);
allocVideoMemory();
@@ -217,18 +228,6 @@ void TwinEEngine::initConfigurations() {
}
void TwinEEngine::initEngine() {
- /** Engine current version */
- const char *ENGINE_VERSION = "0.2.2";
-
- // Show engine information
- debug("TwinEngine v%s", ENGINE_VERSION);
- debug("(c)2002 The TwinEngine team.");
- debug("(c)2020 The ScummVM team.");
- debug("Refer to the credits for further details.");
- debug("Released under the terms of the GNU GPL license version 2 (or, at your opinion, any later). See COPYING file.");
- debug("The original Little Big Adventure game is:");
- debug("(c)1994 by Adeline Software International, All Rights Reserved.");
-
// getting configuration file
initConfigurations();
Commit: 60e7cbfe11a01fb6b2d47e4846ac4cacb5e20a37
https://github.com/scummvm/scummvm/commit/60e7cbfe11a01fb6b2d47e4846ac4cacb5e20a37
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: started to refactor the main loop
Changed paths:
engines/twine/interface.cpp
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/text.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/interface.cpp b/engines/twine/interface.cpp
index 74177c96c2..902b6b750d 100644
--- a/engines/twine/interface.cpp
+++ b/engines/twine/interface.cpp
@@ -48,19 +48,12 @@ int32 Interface::checkClipping(int32 x, int32 y) {
// TODO: check if Graphics::drawLine() works here
void Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, int32 endHeight, int32 lineColor) {
- int32 temp;
- int32 flag2;
- uint8 *out;
- int16 color;
- int16 var2;
- int16 xchg;
- int32 outcode0, outcode1;
- int32 x, y, outcodeOut;
int32 currentLineColor = lineColor;
+ uint8 *out;
// draw line from left to right
if (startWidth > endWidth) {
- temp = endWidth;
+ int32 temp = endWidth;
endWidth = startWidth;
startWidth = temp;
@@ -70,16 +63,18 @@ void Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, in
}
// Perform proper clipping (CohenSutherland algorithm)
- outcode0 = checkClipping(startWidth, startHeight);
- outcode1 = checkClipping(endWidth, endHeight);
+ int32 outcode0 = checkClipping(startWidth, startHeight);
+ int32 outcode1 = checkClipping(endWidth, endHeight);
while ((outcode0 | outcode1) != 0) {
if (((outcode0 & outcode1) != 0) && (outcode0 != INSIDE))
return; // Reject lines which are behind one clipping plane
// At least one endpoint is outside the clip rectangle; pick it.
- outcodeOut = outcode0 ? outcode0 : outcode1;
+ int32 outcodeOut = outcode0 ? outcode0 : outcode1;
+ int32 x = 0;
+ int32 y = 0;
if (outcodeOut & TOP) { // point is above the clip rectangle
x = startWidth + (int)((endWidth - startWidth) * (float)(textWindowTop - startHeight) / (float)(endHeight - startHeight));
y = textWindowTop;
@@ -106,7 +101,7 @@ void Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, in
}
}
- flag2 = 640; //SCREEN_WIDTH;
+ int32 flag2 = DEFAULT_SCREEN_WIDTH;
endWidth -= startWidth;
endHeight -= startHeight;
if (endHeight < 0) {
@@ -116,12 +111,12 @@ void Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, in
out = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[startHeight] + startWidth;
- color = currentLineColor;
+ int16 color = currentLineColor;
if (endWidth < endHeight) { // significant slope
- xchg = endWidth;
+ int16 xchg = endWidth;
endWidth = endHeight;
endHeight = xchg;
- var2 = endWidth;
+ int16 var2 = endWidth;
var2 <<= 1;
startHeight = endWidth;
endHeight <<= 1;
@@ -137,7 +132,7 @@ void Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, in
}
} while (--endWidth);
} else { // reduced slope
- var2 = endWidth;
+ int16 var2 = endWidth;
var2 <<= 1;
startHeight = endWidth;
endHeight <<= 1;
@@ -155,29 +150,20 @@ void Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, in
}
void Interface::blitBox(int32 left, int32 top, int32 right, int32 bottom, const int8 *source, int32 leftDest, int32 topDest, int8 *dest) {
- int32 width;
- int32 height;
- const int8 *s;
- int8 *d;
- int32 insideLine;
- int32 temp3;
- int32 i;
- int32 j;
-
- s = _engine->screenLookupTable[top] + source + left;
- d = _engine->screenLookupTable[topDest] + dest + leftDest;
+ const int8 *s = _engine->screenLookupTable[top] + source + left;
+ int8 *d = _engine->screenLookupTable[topDest] + dest + leftDest;
- width = right - left + 1;
- height = bottom - top + 1;
+ int32 width = right - left + 1;
+ int32 height = bottom - top + 1;
- insideLine = SCREEN_WIDTH - width;
- temp3 = left;
+ int32 insideLine = SCREEN_WIDTH - width;
+ int32 temp3 = left;
left >>= 2;
temp3 &= 3;
- for (j = 0; j < height; j++) {
- for (i = 0; i < width; i++) {
+ for (int32 j = 0; j < height; j++) {
+ for (int32 i = 0; i < width; i++) {
*(d++) = *(s++);
}
@@ -187,16 +173,6 @@ void Interface::blitBox(int32 left, int32 top, int32 right, int32 bottom, const
}
void Interface::drawTransparentBox(int32 left, int32 top, int32 right, int32 bottom, int32 colorAdj) {
- uint8 *pos;
- int32 width;
- int32 height;
- int32 height2;
- int32 temp;
- int32 localMode;
- int32 var1;
- int8 color;
- int8 color2;
-
if (left > SCREEN_TEXTLIMIT_RIGHT)
return;
if (right < SCREEN_TEXTLIMIT_LEFT)
@@ -215,42 +191,33 @@ void Interface::drawTransparentBox(int32 left, int32 top, int32 right, int32 bot
if (bottom > SCREEN_TEXTLIMIT_BOTTOM)
bottom = SCREEN_TEXTLIMIT_BOTTOM;
- pos = _engine->screenLookupTable[top] + (uint8*)_engine->frontVideoBuffer.getPixels() + left;
- height2 = height = bottom - top;
- height2++;
-
- width = right - left + 1;
-
- temp = 640 - width; // SCREEN_WIDTH
- localMode = colorAdj;
+ uint8 *pos = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
+ int32 height = bottom - top;
+ int32 height2 = height + 1;
+ int32 width = right - left + 1;
+ int32 pitch = DEFAULT_SCREEN_WIDTH - width;
+ int32 localMode = colorAdj;
do {
- var1 = width;
+ int32 var1 = width;
do {
- color2 = color = *pos;
- color2 &= 0xF0;
- color &= 0x0F;
+ int8 color = *pos & 0x0F;
+ const int8 color2 = *pos & 0xF0;
color -= localMode;
- if (color < 0)
+ if (color < 0) {
color = color2;
- else
+ } else {
color += color2;
+ }
*pos++ = color;
var1--;
} while (var1 > 0);
- pos += temp;
+ pos += pitch;
height2--;
} while (height2 > 0);
}
void Interface::drawSplittedBox(int32 left, int32 top, int32 right, int32 bottom, uint8 e) { // Box
- uint8 *ptr;
-
- int32 offset;
-
- int32 x;
- int32 y;
-
if (left > SCREEN_TEXTLIMIT_RIGHT)
return;
if (right < SCREEN_TEXTLIMIT_LEFT)
@@ -261,12 +228,12 @@ void Interface::drawSplittedBox(int32 left, int32 top, int32 right, int32 bottom
return;
// cropping
- offset = -((right - left) - SCREEN_WIDTH);
+ int32 offset = -((right - left) - SCREEN_WIDTH);
- ptr = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
+ uint8 *ptr = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
- for (x = top; x < bottom; x++) {
- for (y = left; y < right; y++) {
+ for (int32 x = top; x < bottom; x++) {
+ for (int32 y = left; y < right; y++) {
*(ptr++) = e;
}
ptr += offset;
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index ffb9b568c5..3412edadf9 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -230,7 +230,7 @@ void Menu::plasmaEffectRenderFrame() {
for (j = 1; j < PLASMA_HEIGHT - 1; j++) {
for (i = 1; i < PLASMA_WIDTH - 1; i++) {
- /*Here we calculate the average of all 8 neighbour pixel values*/
+ /* Here we calculate the average of all 8 neighbour pixel values */
c = plasmaEffectPtr[(i - 1) + (j - 1) * PLASMA_WIDTH]; //top-left
c += plasmaEffectPtr[(i + 0) + (j - 1) * PLASMA_WIDTH]; //top
@@ -243,8 +243,9 @@ void Menu::plasmaEffectRenderFrame() {
c += plasmaEffectPtr[(i + 0) + (j + 1) * PLASMA_WIDTH]; // bottom
c += plasmaEffectPtr[(i + 1) + (j + 1) * PLASMA_WIDTH]; // bottom-right
- c = (c >> 3) | ((c & 0x0003) << 13); /* And the 2 least significant bits are used as a
- randomizing parameter for statistically fading the flames */
+ /* And the 2 least significant bits are used as a
+ * randomizing parameter for statistically fading the flames */
+ c = (c >> 3) | ((c & 0x0003) << 13);
if (!(c & 0x6500) &&
(j >= (PLASMA_HEIGHT - 4) || c > 0)) {
@@ -264,25 +265,21 @@ void Menu::plasmaEffectRenderFrame() {
}
void Menu::processPlasmaEffect(int32 top, int32 color) {
- uint8 *in;
- uint8 *out;
- int32 i, j, target;
- uint8 c;
- uint8 max_value = color + 15;
+ const uint8 max_value = color + 15;
plasmaEffectRenderFrame();
- in = plasmaEffectPtr + 5 * PLASMA_WIDTH;
- out = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top];
+ uint8 *in = plasmaEffectPtr + 5 * PLASMA_WIDTH;
+ uint8 *out = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top];
- for (i = 0; i < 25; i++) {
- for (j = 0; j < kMainMenuButtonWidth; j++) {
- c = in[i * kMainMenuButtonWidth + j] / 2 + color;
+ for (int32 i = 0; i < 25; i++) {
+ for (int32 j = 0; j < kMainMenuButtonWidth; j++) {
+ uint8 c = in[i * kMainMenuButtonWidth + j] / 2 + color;
if (c > max_value)
c = max_value;
/* 2x2 squares sharing the same pixel color: */
- target = 2 * (i * SCREEN_W + j);
+ int32 target = 2 * (i * SCREEN_W + j);
out[target] = c;
out[target + 1] = c;
out[target + SCREEN_W] = c;
@@ -300,16 +297,19 @@ void Menu::drawBox(int32 left, int32 top, int32 right, int32 bottom) {
void Menu::drawButtonGfx(int32 width, int32 topheight, int32 id, int32 value, int32 mode) {
/*
- * int CDvolumeRemaped; int musicVolumeRemaped; int masterVolumeRemaped; int lineVolumeRemaped;
+ * int CDvolumeRemaped;
+ * int musicVolumeRemaped;
+ * int masterVolumeRemaped;
+ * int lineVolumeRemaped;
* int waveVolumeRemaped;
*/
int32 left = width - kMainMenuButtonSpan / 2;
int32 right = width + kMainMenuButtonSpan / 2;
- // topheigh is the center Y pos of the button
+ // topheight is the center Y pos of the button
int32 top = topheight - 25; // this makes the button be 50 height
- int32 bottom = topheight + 25; // ||
+ int32 bottom = topheight + 25;
int32 bottom2 = bottom;
if (mode != 0) {
@@ -423,12 +423,11 @@ void Menu::drawButton(const int16 *menuSettings, int32 mode) {
}
int32 Menu::processMenu(int16 *menuSettings) {
- int16 *localData = menuSettings;
- int16 currentButton = 0; // localData[0];
+ int16 currentButton = menuSettings[MenuSettings_CurrentLoadedButton];
bool buttonReleased = true;
bool buttonNeedRedraw = true;
bool musicChanged = false;
- int32 numEntry = localData[1];
+ const int32 numEntry = menuSettings[MenuSettings_NumberOfButtons];
int32 localTime = _engine->lbaTime;
int32 maxButton = numEntry - 1;
@@ -436,7 +435,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
do {
// if its on main menu
- if (localData == MainMenuSettings) {
+ if (menuSettings == MainMenuSettings) {
if (_engine->lbaTime - localTime > 11650) {
return kBackground;
}
@@ -455,6 +454,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
_engine->_keyboard.key = _engine->_keyboard.pressedKey;
if (((uint8)_engine->_keyboard.key & 2)) { // on arrow key down
+ debug("pressed down");
currentButton++;
if (currentButton == numEntry) { // if current button is the last, than next button is the first
currentButton = 0;
@@ -464,6 +464,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
if (((uint8)_engine->_keyboard.key & 1)) { // on arrow key up
+ debug("pressed up");
currentButton--;
if (currentButton < 0) { // if current button is the first, than previous button is the last
currentButton = maxButton;
@@ -472,8 +473,9 @@ int32 Menu::processMenu(int16 *menuSettings) {
buttonReleased = false;
}
- if (*(localData + 8) <= 5) { // if its a volume button
- const int16 id = *(localData + currentButton * 2 + 4); // get button parameters from settings array
+ // if its a volume button
+ if ((menuSettings == OptionsMenuSettings || menuSettings == VolumeMenuSettings) && *(menuSettings + 8) <= 5) {
+ const int16 id = *(menuSettings + currentButton * 2 + MenuSettings_FirstButtonState); // get button parameters from settings array
Audio::Mixer *mixer = _engine->_system->getMixer();
switch (id) {
@@ -539,12 +541,12 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
if (buttonNeedRedraw) {
- *localData = currentButton;
+ menuSettings[MenuSettings_CurrentLoadedButton] = currentButton;
- drawButton(localData, 0); // current button
+ drawButton(menuSettings, 0); // current button
do {
_engine->readKeys();
- drawButton(localData, 1);
+ drawButton(menuSettings, 1);
} while (_engine->_keyboard.pressedKey == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.internalKeyCode == 0);
buttonNeedRedraw = false;
} else {
@@ -552,14 +554,14 @@ int32 Menu::processMenu(int16 *menuSettings) {
// TODO: update volume settings
}
- drawButton(localData, 1);
+ drawButton(menuSettings, 1);
_engine->readKeys();
// WARNING: this is here to prevent a fade bug while quit the menu
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
}
} while (!(_engine->_keyboard.skippedKey & 2) && !(_engine->_keyboard.skippedKey & 1));
- currentButton = *(localData + 5 + currentButton * 2); // get current browsed button
+ currentButton = *(menuSettings + MenuSettings_FirstButton + currentButton * 2); // get current browsed button
_engine->readKeys();
@@ -679,50 +681,46 @@ int32 Menu::optionsMenu() {
return 0;
}
-void Menu::mainMenu() {
- _engine->_sound->stopSamples();
-
- _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
-
+bool Menu::init() {
// load menu effect file only once
plasmaEffectPtr = (uint8 *)malloc(kPlasmaEffectFilesize);
memset(plasmaEffectPtr, 0, kPlasmaEffectFilesize);
- _engine->_hqrdepack->hqrGetEntry(plasmaEffectPtr, Resources::HQR_RESS_FILE, RESSHQR_PLASMAEFFECT);
+ return _engine->_hqrdepack->hqrGetEntry(plasmaEffectPtr, Resources::HQR_RESS_FILE, RESSHQR_PLASMAEFFECT) > 0;
+}
- while (!_engine->shouldQuit()) {
- _engine->_text->initTextBank(0);
+void Menu::run() {
+ _engine->_text->initTextBank(0);
- _engine->_music->playTrackMusic(9); // LBA's Theme
- _engine->_sound->stopSamples();
+ _engine->_music->playTrackMusic(9); // LBA's Theme
+ _engine->_sound->stopSamples();
- switch (processMenu(MainMenuSettings)) {
- case kNewGame: {
- _engine->_menuOptions->newGameMenu();
- break;
- }
- case kContinueGame: {
- _engine->_menuOptions->continueGameMenu();
- break;
- }
- case kOptions: {
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
- OptionsMenuSettings[5] = kReturnMenu;
- optionsMenu();
- break;
- }
- case kQuit: {
- Common::Event event;
- event.type = Common::EVENT_QUIT;
- _engine->_system->getEventManager()->pushEvent(event);
- break;
- }
- case kBackground: {
- _engine->_screens->loadMenuImage();
- }
- }
- _engine->_system->delayMillis(1000 / _engine->cfgfile.Fps);
+ switch (processMenu(MainMenuSettings)) {
+ case kNewGame: {
+ _engine->_menuOptions->newGameMenu();
+ break;
+ }
+ case kContinueGame: {
+ _engine->_menuOptions->continueGameMenu();
+ break;
+ }
+ case kOptions: {
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
+ OptionsMenuSettings[5] = kReturnMenu;
+ optionsMenu();
+ break;
+ }
+ case kQuit: {
+ Common::Event event;
+ event.type = Common::EVENT_QUIT;
+ _engine->_system->getEventManager()->pushEvent(event);
+ break;
+ }
+ case kBackground: {
+ _engine->_screens->loadMenuImage();
+ }
}
+ _engine->_system->delayMillis(1000 / _engine->cfgfile.Fps);
}
int32 Menu::giveupMenu() {
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index 8c34f3d71a..a764b93ec0 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -27,6 +27,17 @@
namespace TwinE {
+enum MenuSettingsType {
+ // button number
+ MenuSettings_CurrentLoadedButton = 0,
+ // is used to calc the height where the first button will appear
+ MenuSettings_NumberOfButtons = 1,
+ MenuSettings_ButtonsBoxHeight = 2,
+ MenuSettings_HeaderEnd = 3, // TODO: unknown
+ MenuSettings_FirstButtonState = 4,
+ MenuSettings_FirstButton = 5
+};
+
class Menu {
private:
TwinEEngine *_engine;
@@ -124,8 +135,10 @@ public:
*/
int32 processMenu(int16 *menuSettings);
+ bool init();
+
/** Used to run the main menu */
- void mainMenu();
+ void run();
/** Used to run the in-game give-up menu */
int32 giveupMenu();
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index c9c9cccc7b..ae96deaa40 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -257,10 +257,11 @@ void Text::drawText(int32 x, int32 y, const char *dialogue) { // Font
return;
do {
- uint8 currChar = (uint8) *(dialogue++); // read the next char from the string
+ const uint8 currChar = (uint8) *(dialogue++); // read the next char from the string
- if (currChar == 0) // if the char is 0x0, -> end of string
+ if (currChar == '\0') {
break;
+ }
if (currChar == ' ') {
x += dialCharSpace;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index baf7b41fea..26d94cb248 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -142,6 +142,13 @@ Common::Error TwinEEngine::run() {
allocVideoMemory();
initAll();
initEngine();
+ _sound->stopSamples();
+ _screens->copyScreen(frontVideoBuffer, workVideoBuffer);
+
+ _menu->init();
+ while (!shouldQuit()) {
+ _menu->run();
+ }
_music->stopTrackMusic();
_music->stopMidiMusic();
return Common::kNoError;
@@ -258,8 +265,6 @@ void TwinEEngine::initEngine() {
_flaMovies->playFlaMovie(FLA_DRAGON3);
_screens->loadMenuImage();
-
- _menu->mainMenu();
}
void TwinEEngine::initMCGA() {
@@ -358,7 +363,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
if (loopCurrentKey == twineactions[TwinEActionType::OptionsMenu].localKey) {
freezeTime();
_sound->pauseSamples();
- _menu->OptionsMenuSettings[5] = 15;
+ _menu->OptionsMenuSettings[MenuSettings_FirstButton] = 15;
_text->initTextBank(0);
_menu->optionsMenu();
_text->initTextBank(_text->currentTextBank + 3);
@@ -478,7 +483,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_redraw->redrawEngineActions(1);
}
- // Process behaviour menu - Press CTRL and F1..F4 Keys
+ // Process behaviour menu
if ((loopCurrentKey == twineactions[TwinEActionType::BehaviourMenu].localKey ||
loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourNormal].localKey ||
loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAthletic].localKey ||
@@ -515,7 +520,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
}
- // Press Enter to Recenter Screen
+ // Recenter Screen
if ((loopPressedKey & 2) && !disableScreenRecenter) {
_grid->newCameraX = _scene->sceneActors[_scene->currentlyFollowedActor].x >> 9;
_grid->newCameraY = _scene->sceneActors[_scene->currentlyFollowedActor].y >> 8;
@@ -533,7 +538,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_redraw->redrawEngineActions(1);
}
- // Process Pause - Press P
+ // Process Pause
if (loopCurrentKey == twineactions[TwinEActionType::Pause].localKey) {
freezeTime();
_text->setFontColor(15);
Commit: 0766f49c23843e677be79be4c481979eb1bd020b
https://github.com/scummvm/scummvm/commit/0766f49c23843e677be79be4c481979eb1bd020b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: converted to boolean
Changed paths:
engines/twine/collision.cpp
engines/twine/debug.cpp
engines/twine/debug_grid.cpp
engines/twine/debug_grid.h
engines/twine/debug_scene.cpp
engines/twine/debug_scene.h
engines/twine/menuoptions.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/collision.cpp b/engines/twine/collision.cpp
index d08215f970..9d4782541a 100644
--- a/engines/twine/collision.cpp
+++ b/engines/twine/collision.cpp
@@ -173,8 +173,8 @@ void Collision::reajustActorPosition(int32 brickShape) {
}
break;
default:
- if (_engine->cfgfile.Debug == 1) {
- debug("Brick Shape %d unsupported\n", brickShape);
+ if (_engine->cfgfile.Debug) {
+ debug("Brick Shape %d unsupported", brickShape);
}
break;
}
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 7a4002e391..de9ffbe519 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -203,13 +203,13 @@ int32 Debug::debugGetActionsState(int32 type) {
switch (type) {
case FREE_CAMERA:
- state = _engine->_debugGrid->useFreeCamera;
+ state = _engine->_debugGrid->useFreeCamera ? 1 : 0;
break;
case CHANGE_SCENE:
- state = _engine->_debugGrid->canChangeScenes;
+ state = _engine->_debugGrid->canChangeScenes ? 1 : 0;
break;
case SHOW_ZONES:
- state = _engine->_debugScene->showingZones;
+ state = _engine->_debugScene->showingZones ? 1 : 0;
break;
case SHOW_ZONE_CUBE:
case SHOW_ZONE_CAMERA:
diff --git a/engines/twine/debug_grid.cpp b/engines/twine/debug_grid.cpp
index f9e6d68482..aad2c95763 100644
--- a/engines/twine/debug_grid.cpp
+++ b/engines/twine/debug_grid.cpp
@@ -31,7 +31,7 @@
namespace TwinE {
DebugGrid::DebugGrid(TwinEEngine *engine) : _engine(engine) {
- canChangeScenes = _engine->cfgfile.Debug ? 1 : 0;
+ canChangeScenes = _engine->cfgfile.Debug;
}
void DebugGrid::changeGridCamera(int16 pKey) {
diff --git a/engines/twine/debug_grid.h b/engines/twine/debug_grid.h
index 718d3de083..588a0006f1 100644
--- a/engines/twine/debug_grid.h
+++ b/engines/twine/debug_grid.h
@@ -36,8 +36,8 @@ private:
public:
DebugGrid(TwinEEngine *engine);
- int32 useFreeCamera = 0;
- int32 canChangeScenes = 0;
+ bool useFreeCamera = false;
+ bool canChangeScenes = false;
/** Change scenario camera positions */
void changeGridCamera(int16 pKey);
diff --git a/engines/twine/debug_scene.cpp b/engines/twine/debug_scene.cpp
index d7c8256c0f..53a82814e4 100644
--- a/engines/twine/debug_scene.cpp
+++ b/engines/twine/debug_scene.cpp
@@ -45,7 +45,7 @@ void DebugScene::drawBoundingBoxProjectPoints(ScenePoint *pPoint3d, ScenePoint *
if (_engine->_redraw->renderRight < _engine->_renderer->projPosX)
_engine->_redraw->renderRight = _engine->_renderer->projPosX;
- if (_engine->_redraw->renderTop >_engine->_renderer->projPosY)
+ if (_engine->_redraw->renderTop > _engine->_renderer->projPosY)
_engine->_redraw->renderTop = _engine->_renderer->projPosY;
if (_engine->_redraw->renderBottom < _engine->_renderer->projPosY)
@@ -90,113 +90,113 @@ int32 DebugScene::checkZoneType(int32 type) {
}
void DebugScene::displayZones(int16 pKey) {
- if (showingZones == 1) {
- int z;
- ZoneStruct *zonePtr = _engine->_scene->sceneZones;
- for (z = 0; z < _engine->_scene->sceneNumZones; z++) {
- zonePtr = &_engine->_scene->sceneZones[z];
+ if (!showingZones) {
+ return;
+ }
+ for (int z = 0; z < _engine->_scene->sceneNumZones; z++) {
+ const ZoneStruct *zonePtr = &_engine->_scene->sceneZones[z];
- if (checkZoneType(zonePtr->type)) {
- ScenePoint frontBottomLeftPoint;
- ScenePoint frontBottomRightPoint;
+ if (!checkZoneType(zonePtr->type)) {
+ continue;
+ }
+ ScenePoint frontBottomLeftPoint;
+ ScenePoint frontBottomRightPoint;
- ScenePoint frontTopLeftPoint;
- ScenePoint frontTopRightPoint;
+ ScenePoint frontTopLeftPoint;
+ ScenePoint frontTopRightPoint;
- ScenePoint backBottomLeftPoint;
- ScenePoint backBottomRightPoint;
+ ScenePoint backBottomLeftPoint;
+ ScenePoint backBottomRightPoint;
- ScenePoint backTopLeftPoint;
- ScenePoint backTopRightPoint;
+ ScenePoint backTopLeftPoint;
+ ScenePoint backTopRightPoint;
- ScenePoint frontBottomLeftPoint2D;
- ScenePoint frontBottomRightPoint2D;
+ ScenePoint frontBottomLeftPoint2D;
+ ScenePoint frontBottomRightPoint2D;
- ScenePoint frontTopLeftPoint2D;
- ScenePoint frontTopRightPoint2D;
+ ScenePoint frontTopLeftPoint2D;
+ ScenePoint frontTopRightPoint2D;
- ScenePoint backBottomLeftPoint2D;
- ScenePoint backBottomRightPoint2D;
+ ScenePoint backBottomLeftPoint2D;
+ ScenePoint backBottomRightPoint2D;
- ScenePoint backTopLeftPoint2D;
- ScenePoint backTopRightPoint2D;
+ ScenePoint backTopLeftPoint2D;
+ ScenePoint backTopRightPoint2D;
- uint8 color;
+ uint8 color;
- // compute the points in 3D
+ // compute the points in 3D
- frontBottomLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
- frontBottomLeftPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
- frontBottomLeftPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
+ frontBottomLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
+ frontBottomLeftPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
+ frontBottomLeftPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
- frontBottomRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
- frontBottomRightPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
- frontBottomRightPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
+ frontBottomRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
+ frontBottomRightPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
+ frontBottomRightPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
- frontTopLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
- frontTopLeftPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
- frontTopLeftPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
+ frontTopLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
+ frontTopLeftPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
+ frontTopLeftPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
- frontTopRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
- frontTopRightPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
- frontTopRightPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
+ frontTopRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
+ frontTopRightPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
+ frontTopRightPoint.z = zonePtr->topRight.z - _engine->_grid->cameraZ;
- backBottomLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
- backBottomLeftPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
- backBottomLeftPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
+ backBottomLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
+ backBottomLeftPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
+ backBottomLeftPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
- backBottomRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
- backBottomRightPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
- backBottomRightPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
+ backBottomRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
+ backBottomRightPoint.y = zonePtr->bottomLeft.y - _engine->_grid->cameraY;
+ backBottomRightPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
- backTopLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
- backTopLeftPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
- backTopLeftPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
+ backTopLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
+ backTopLeftPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
+ backTopLeftPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
- backTopRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
- backTopRightPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
- backTopRightPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
+ backTopRightPoint.x = zonePtr->topRight.x - _engine->_grid->cameraX;
+ backTopRightPoint.y = zonePtr->topRight.y - _engine->_grid->cameraY;
+ backTopRightPoint.z = zonePtr->bottomLeft.z - _engine->_grid->cameraZ;
- // project all points
+ // project all points
- drawBoundingBoxProjectPoints(&frontBottomLeftPoint, &frontBottomLeftPoint2D);
- drawBoundingBoxProjectPoints(&frontBottomRightPoint, &frontBottomRightPoint2D);
- drawBoundingBoxProjectPoints(&frontTopLeftPoint, &frontTopLeftPoint2D);
- drawBoundingBoxProjectPoints(&frontTopRightPoint, &frontTopRightPoint2D);
- drawBoundingBoxProjectPoints(&backBottomLeftPoint, &backBottomLeftPoint2D);
- drawBoundingBoxProjectPoints(&backBottomRightPoint, &backBottomRightPoint2D);
- drawBoundingBoxProjectPoints(&backTopLeftPoint, &backTopLeftPoint2D);
- drawBoundingBoxProjectPoints(&backTopRightPoint, &backTopRightPoint2D);
+ drawBoundingBoxProjectPoints(&frontBottomLeftPoint, &frontBottomLeftPoint2D);
+ drawBoundingBoxProjectPoints(&frontBottomRightPoint, &frontBottomRightPoint2D);
+ drawBoundingBoxProjectPoints(&frontTopLeftPoint, &frontTopLeftPoint2D);
+ drawBoundingBoxProjectPoints(&frontTopRightPoint, &frontTopRightPoint2D);
+ drawBoundingBoxProjectPoints(&backBottomLeftPoint, &backBottomLeftPoint2D);
+ drawBoundingBoxProjectPoints(&backBottomRightPoint, &backBottomRightPoint2D);
+ drawBoundingBoxProjectPoints(&backTopLeftPoint, &backTopLeftPoint2D);
+ drawBoundingBoxProjectPoints(&backTopRightPoint, &backTopRightPoint2D);
- // draw all lines
+ // draw all lines
- color = 15 * 3 + zonePtr->type * 16;
+ color = 15 * 3 + zonePtr->type * 16;
- // draw front part
- _engine->_interface->drawLine(frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, color);
- _engine->_interface->drawLine(frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, frontTopRightPoint2D.x, frontTopRightPoint2D.y, color);
- _engine->_interface->drawLine(frontTopRightPoint2D.x, frontTopRightPoint2D.y, frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, color);
- _engine->_interface->drawLine(frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, color);
+ // draw front part
+ _engine->_interface->drawLine(frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, color);
+ _engine->_interface->drawLine(frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, frontTopRightPoint2D.x, frontTopRightPoint2D.y, color);
+ _engine->_interface->drawLine(frontTopRightPoint2D.x, frontTopRightPoint2D.y, frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, color);
+ _engine->_interface->drawLine(frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, color);
- // draw top part
- _engine->_interface->drawLine(frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, backTopLeftPoint2D.x, backTopLeftPoint2D.y, color);
- _engine->_interface->drawLine(backTopLeftPoint2D.x, backTopLeftPoint2D.y, backTopRightPoint2D.x, backTopRightPoint2D.y, color);
- _engine->_interface->drawLine(backTopRightPoint2D.x, backTopRightPoint2D.y, frontTopRightPoint2D.x, frontTopRightPoint2D.y, color);
- _engine->_interface->drawLine(frontTopRightPoint2D.x, frontTopRightPoint2D.y, frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, color);
+ // draw top part
+ _engine->_interface->drawLine(frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, backTopLeftPoint2D.x, backTopLeftPoint2D.y, color);
+ _engine->_interface->drawLine(backTopLeftPoint2D.x, backTopLeftPoint2D.y, backTopRightPoint2D.x, backTopRightPoint2D.y, color);
+ _engine->_interface->drawLine(backTopRightPoint2D.x, backTopRightPoint2D.y, frontTopRightPoint2D.x, frontTopRightPoint2D.y, color);
+ _engine->_interface->drawLine(frontTopRightPoint2D.x, frontTopRightPoint2D.y, frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, color);
- // draw back part
- _engine->_interface->drawLine(backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, backTopLeftPoint2D.x, backTopLeftPoint2D.y, color);
- _engine->_interface->drawLine(backTopLeftPoint2D.x, backTopLeftPoint2D.y, backTopRightPoint2D.x, backTopRightPoint2D.y, color);
- _engine->_interface->drawLine(backTopRightPoint2D.x, backTopRightPoint2D.y, backBottomRightPoint2D.x, backBottomRightPoint2D.y, color);
- _engine->_interface->drawLine(backBottomRightPoint2D.x, backBottomRightPoint2D.y, backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, color);
+ // draw back part
+ _engine->_interface->drawLine(backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, backTopLeftPoint2D.x, backTopLeftPoint2D.y, color);
+ _engine->_interface->drawLine(backTopLeftPoint2D.x, backTopLeftPoint2D.y, backTopRightPoint2D.x, backTopRightPoint2D.y, color);
+ _engine->_interface->drawLine(backTopRightPoint2D.x, backTopRightPoint2D.y, backBottomRightPoint2D.x, backBottomRightPoint2D.y, color);
+ _engine->_interface->drawLine(backBottomRightPoint2D.x, backBottomRightPoint2D.y, backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, color);
- // draw bottom part
- _engine->_interface->drawLine(frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, color);
- _engine->_interface->drawLine(backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, backBottomRightPoint2D.x, backBottomRightPoint2D.y, color);
- _engine->_interface->drawLine(backBottomRightPoint2D.x, backBottomRightPoint2D.y, frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, color);
- _engine->_interface->drawLine(frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, color);
- }
- }
+ // draw bottom part
+ _engine->_interface->drawLine(frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, color);
+ _engine->_interface->drawLine(backBottomLeftPoint2D.x, backBottomLeftPoint2D.y, backBottomRightPoint2D.x, backBottomRightPoint2D.y, color);
+ _engine->_interface->drawLine(backBottomRightPoint2D.x, backBottomRightPoint2D.y, frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, color);
+ _engine->_interface->drawLine(frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, color);
}
}
diff --git a/engines/twine/debug_scene.h b/engines/twine/debug_scene.h
index 4d633dd682..b40bc979fd 100644
--- a/engines/twine/debug_scene.h
+++ b/engines/twine/debug_scene.h
@@ -38,7 +38,7 @@ private:
int32 checkZoneType(int32 type);
public:
DebugScene(TwinEEngine *engine);
- int32 showingZones = 0;
+ bool showingZones = false;
int32 typeZones = 127; // all zones on as default
void displayZones(int16 pKey);
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 0ba8e859bf..592c51d895 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -259,13 +259,13 @@ int32 MenuOptions::enterPlayerName(int32 textIdx) {
enterPlayerNameVar2 = 0;
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip(); // frontVideoBuffer
+ _engine->flip();
return 1;
}
void MenuOptions::newGameMenu() {
- //TODO: process players name
+ // TODO: process players name
if (enterPlayerName(MAINMENU_ENTERPLAYERNAME)) {
_engine->_gameState->initEngineVars();
newGame();
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 26d94cb248..5630e206c6 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -226,7 +226,7 @@ void TwinEEngine::initConfigurations() {
cfgfile.Movie = ConfGetIntOrDefault("Movie", CONF_MOVIE_FLA);
cfgfile.CrossFade = ConfGetIntOrDefault("CrossFade", 0);
cfgfile.Fps = ConfGetIntOrDefault("Fps", DEFAULT_FRAMES_PER_SECOND);
- cfgfile.Debug = ConfGetIntOrDefault("Debug", 0);
+ cfgfile.Debug = ConfGetIntOrDefault("Debug", 0) == 1;
cfgfile.UseAutoSaving = ConfGetIntOrDefault("UseAutoSaving", 0);
cfgfile.AutoAgressive = ConfGetIntOrDefault("CombatAuto", 0);
cfgfile.ShadowMode = ConfGetIntOrDefault("Shadow", 0);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 308cdce509..d268bf7fd0 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -109,7 +109,7 @@ struct ConfigFile {
/** Flag used to keep the game frames per second */
int32 Fps = 0;
/** Flag to display game debug */
- int32 Debug = 0;
+ bool Debug = false;
/** Use original autosaving system or save when you want */
int32 UseAutoSaving = 0;
/** Shadow mode type */
Commit: c8e1dfbee011e2e7b9b3282473e2420e0e075ea8
https://github.com/scummvm/scummvm/commit/c8e1dfbee011e2e7b9b3282473e2420e0e075ea8
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: minor cleanup
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 3412edadf9..aeb7669ac9 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -308,7 +308,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 id, int32 value, in
int32 right = width + kMainMenuButtonSpan / 2;
// topheight is the center Y pos of the button
- int32 top = topheight - 25; // this makes the button be 50 height
+ int32 top = topheight - 25; // this makes the button be 50 height
int32 bottom = topheight + 25;
int32 bottom2 = bottom;
@@ -474,7 +474,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
// if its a volume button
- if ((menuSettings == OptionsMenuSettings || menuSettings == VolumeMenuSettings) && *(menuSettings + 8) <= 5) {
+ if (menuSettings == VolumeMenuSettings && *(menuSettings + 8) <= 5) {
const int16 id = *(menuSettings + currentButton * 2 + MenuSettings_FirstButtonState); // get button parameters from settings array
Audio::Mixer *mixer = _engine->_system->getMixer();
@@ -718,6 +718,7 @@ void Menu::run() {
}
case kBackground: {
_engine->_screens->loadMenuImage();
+ break;
}
}
_engine->_system->delayMillis(1000 / _engine->cfgfile.Fps);
Commit: a0a47a54d55a37d0a49cc42a91df9523d8c2900b
https://github.com/scummvm/scummvm/commit/a0a47a54d55a37d0a49cc42a91df9523d8c2900b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: renamed method params
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index aeb7669ac9..8e3f5a6b4e 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -295,7 +295,7 @@ void Menu::drawBox(int32 left, int32 top, int32 right, int32 bottom) {
_engine->_interface->drawLine(++left, bottom, right, bottom, 73); // bottom line
}
-void Menu::drawButtonGfx(int32 width, int32 topheight, int32 id, int32 value, int32 mode) {
+void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 textId, int32 mode) {
/*
* int CDvolumeRemaped;
* int musicVolumeRemaped;
@@ -313,9 +313,9 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 id, int32 value, in
int32 bottom2 = bottom;
if (mode != 0) {
- if (id <= kMasterVolume && id >= kMusicVolume) {
+ if (buttonId <= kMasterVolume && buttonId >= kMusicVolume) {
int32 newWidth = 0;
- switch (id) {
+ switch (buttonId) {
case kMusicVolume: {
const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
newWidth = _engine->_screens->crossDot(left, right, Audio::Mixer::kMaxMixerVolume, volume);
@@ -364,7 +364,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 id, int32 value, in
_engine->_text->setFontColor(15);
_engine->_text->setFontParameters(2, 8);
char dialText[256];
- _engine->_text->getMenuText(value, dialText, sizeof(dialText));
+ _engine->_text->getMenuText(textId, dialText, sizeof(dialText));
const int32 textSize = _engine->_text->getTextSize(dialText);
_engine->_text->drawText(width - (textSize / 2), topheight - 18, dialText);
Commit: c6b673c0519ceca22bf09c42d9c72478b074fa05
https://github.com/scummvm/scummvm/commit/c6b673c0519ceca22bf09c42d9c72478b074fa05
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: converted to bool and use constants
Changed paths:
engines/twine/menu.cpp
engines/twine/menu.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 8e3f5a6b4e..065be61dd3 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -295,7 +295,7 @@ void Menu::drawBox(int32 left, int32 top, int32 right, int32 bottom) {
_engine->_interface->drawLine(++left, bottom, right, bottom, 73); // bottom line
}
-void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 textId, int32 mode) {
+void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 textId, bool hover) {
/*
* int CDvolumeRemaped;
* int musicVolumeRemaped;
@@ -312,7 +312,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
int32 bottom = topheight + 25;
int32 bottom2 = bottom;
- if (mode != 0) {
+ if (hover != 0) {
if (buttonId <= kMasterVolume && buttonId >= kMusicVolume) {
int32 newWidth = 0;
switch (buttonId) {
@@ -374,14 +374,10 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
}
void Menu::drawButton(const int16 *menuSettings, int32 mode) {
- const int16 *localData = menuSettings;
- int32 buttonNumber = *localData;
- localData += 1;
- int32 maxButton = *localData;
- localData += 1;
- int32 topHeight = *localData;
- localData += 2;
+ int16 buttonNumber = menuSettings[MenuSettings_CurrentLoadedButton];
+ const int32 maxButton = menuSettings[MenuSettings_NumberOfButtons];
+ int32 topHeight = menuSettings[MenuSettings_ButtonsBoxHeight];
if (topHeight == 0) {
topHeight = 35;
@@ -395,6 +391,8 @@ void Menu::drawButton(const int16 *menuSettings, int32 mode) {
uint8 currentButton = 0;
+ const int16 *localData = menuSettings;
+ localData += 4;
do {
// get menu item settings
uint8 menuItemId = (uint8)*localData;
@@ -404,13 +402,13 @@ void Menu::drawButton(const int16 *menuSettings, int32 mode) {
localData += 1;
if (mode != 0) {
if (currentButton == buttonNumber) {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, 1);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, true);
}
} else {
if (currentButton == buttonNumber) {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, 1);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, true);
} else {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, 0);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, false);
}
}
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index a764b93ec0..a032fbefa2 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -56,11 +56,11 @@ private:
* Draws main menu button
* @param width menu button width
* @param topheight is the height between the top of the screen and the first button
- * @param id current button identification from menu settings
- * @param value current button key pressed value
- * @param mode flag to know if should draw as a hover button or not
+ * @param buttonId current button identification from menu settings
+ * @param textId
+ * @param hover flag to know if should draw as a hover button or not
*/
- void drawButtonGfx(int32 width, int32 topheight, int32 id, int32 value, int32 mode);
+ void drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 textId, bool hover);
void plasmaEffectRenderFrame();
/**
* Process the menu button draw
Commit: e7f911fcbca6102e58591452023d470215d83aa4
https://github.com/scummvm/scummvm/commit/e7f911fcbca6102e58591452023d470215d83aa4
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: convert to boolean
Changed paths:
engines/twine/menu.cpp
engines/twine/menu.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 065be61dd3..99d2be4d1f 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -373,8 +373,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
_engine->copyBlockPhys(left, top, right, bottom);
}
-void Menu::drawButton(const int16 *menuSettings, int32 mode) {
-
+void Menu::drawButton(const int16 *menuSettings, bool hover) {
int16 buttonNumber = menuSettings[MenuSettings_CurrentLoadedButton];
const int32 maxButton = menuSettings[MenuSettings_NumberOfButtons];
int32 topHeight = menuSettings[MenuSettings_ButtonsBoxHeight];
@@ -400,9 +399,9 @@ void Menu::drawButton(const int16 *menuSettings, int32 mode) {
// applicable for sound menus, to save the volume/sound bar
uint16 menuItemValue = *localData;
localData += 1;
- if (mode != 0) {
+ if (hover) {
if (currentButton == buttonNumber) {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, true);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, hover);
}
} else {
if (currentButton == buttonNumber) {
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index a032fbefa2..7fede85416 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -67,7 +67,7 @@ private:
* @param data menu settings array
* @param mode flag to know if should draw as a hover button or not
*/
- void drawButton(const int16 *menuSettings, int32 mode);
+ void drawButton(const int16 *menuSettings, bool hover);
/** Used to run the advanced options menu */
int32 advoptionsMenu();
/** Used to run the volume menu */
Commit: dff5595cae8a29dbc6d1a4377a30808b59ee7a36
https://github.com/scummvm/scummvm/commit/dff5595cae8a29dbc6d1a4377a30808b59ee7a36
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: replaced magic numbers
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 99d2be4d1f..59d14d1bda 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -149,11 +149,11 @@ int16 Menu::OptionsMenuSettings[] = {
0,
24, // return to previous menu
0,
- 30, // volume settings
+ kVolume, // volume settings
0,
- 46, // save game management
+ kSaveManage, // save game management
0,
- 47, // advanced options
+ kAdvanced, // advanced options
};
/** Advanced Options Menu Settings
@@ -202,15 +202,15 @@ int16 Menu::VolumeMenuSettings[] = {
0, // unused
0,
26, // return to main menu
- 1,
+ kMusicVolume,
10, // music volume
- 2,
+ kSoundVolume,
11, // sfx volume
- 3,
+ kCDVolume,
12, // cd volume
- 4,
+ kLineVolume,
13, // line-in volume
- 5,
+ kMasterVolume,
14, // master volume
0,
16, // save parameters
@@ -381,7 +381,7 @@ void Menu::drawButton(const int16 *menuSettings, bool hover) {
if (topHeight == 0) {
topHeight = 35;
} else {
- topHeight = topHeight - (((maxButton - 1) * 6) + ((maxButton)*50)) / 2;
+ topHeight = topHeight - (((maxButton - 1) * 6) + (maxButton * 50)) / 2;
}
if (maxButton <= 0) {
@@ -391,23 +391,23 @@ void Menu::drawButton(const int16 *menuSettings, bool hover) {
uint8 currentButton = 0;
const int16 *localData = menuSettings;
- localData += 4;
+ localData += MenuSettings_FirstButtonState;
do {
// get menu item settings
uint8 menuItemId = (uint8)*localData;
localData += 1;
// applicable for sound menus, to save the volume/sound bar
- uint16 menuItemValue = *localData;
+ uint16 textId = *localData;
localData += 1;
if (hover) {
if (currentButton == buttonNumber) {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, hover);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, hover);
}
} else {
if (currentButton == buttonNumber) {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, true);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, true);
} else {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, menuItemValue, false);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, false);
}
}
@@ -540,10 +540,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (buttonNeedRedraw) {
menuSettings[MenuSettings_CurrentLoadedButton] = currentButton;
- drawButton(menuSettings, 0); // current button
+ drawButton(menuSettings, false); // current button
do {
_engine->readKeys();
- drawButton(menuSettings, 1);
+ drawButton(menuSettings, true);
} while (_engine->_keyboard.pressedKey == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.internalKeyCode == 0);
buttonNeedRedraw = false;
} else {
@@ -551,7 +551,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
// TODO: update volume settings
}
- drawButton(menuSettings, 1);
+ drawButton(menuSettings, true);
_engine->readKeys();
// WARNING: this is here to prevent a fade bug while quit the menu
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
Commit: d1a7b95d9a59c09ed977938889583027cbd84664
https://github.com/scummvm/scummvm/commit/d1a7b95d9a59c09ed977938889583027cbd84664
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: replaced magic number
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 59d14d1bda..f26d11781d 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -471,8 +471,8 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
// if its a volume button
- if (menuSettings == VolumeMenuSettings && *(menuSettings + 8) <= 5) {
- const int16 id = *(menuSettings + currentButton * 2 + MenuSettings_FirstButtonState); // get button parameters from settings array
+ if (menuSettings == VolumeMenuSettings) {
+ const int16 id = *(&menuSettings[MenuSettings_FirstButtonState] + currentButton * 2); // get button parameters from settings array
Audio::Mixer *mixer = _engine->_system->getMixer();
switch (id) {
Commit: 38cd5622b3567fb74530bdb9e573d6ecd9cb1d8c
https://github.com/scummvm/scummvm/commit/38cd5622b3567fb74530bdb9e573d6ecd9cb1d8c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: forgot to reset the midi buffer pointer after freeing it
Changed paths:
engines/twine/music.cpp
diff --git a/engines/twine/music.cpp b/engines/twine/music.cpp
index 8fc3493244..0495ad3f93 100644
--- a/engines/twine/music.cpp
+++ b/engines/twine/music.cpp
@@ -194,6 +194,7 @@ void Music::stopMidiMusic() {
_midiPlayer.stop();
free(midiPtr);
+ midiPtr = nullptr;
}
bool Music::initCdrom() {
Commit: dffaa2956d883150e6044be63dda06442fd91fac
https://github.com/scummvm/scummvm/commit/dffaa2956d883150e6044be63dda06442fd91fac
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: disabled partial screen blitting for now
Changed paths:
engines/twine/twine.cpp
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 5630e206c6..061fd73ac9 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -819,9 +819,13 @@ void TwinEEngine::flip() {
void TwinEEngine::copyBlockPhys(int32 left, int32 top, int32 right, int32 bottom) {
assert(left < right);
assert(top < bottom);
+#if 0
// TODO: fix this - looks like the palette includes a color key at pos 0
g_system->copyRectToScreen(frontVideoBuffer.getPixels(), frontVideoBuffer.pitch, left, top, right - left + 1, bottom - top + 1);
g_system->updateScreen();
+#else
+ flip();
+#endif
}
void TwinEEngine::crossFade(const Graphics::ManagedSurface &buffer, const uint32 *palette) {
Commit: 232cfc691e1152711a4308abbd69356b979d622d
https://github.com/scummvm/scummvm/commit/232cfc691e1152711a4308abbd69356b979d622d
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: cleanup in holomap code
Changed paths:
engines/twine/holomap.cpp
engines/twine/holomap.h
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index e58a1015a9..62d7bc55c9 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -59,20 +59,18 @@ void Holomap::loadGfxSub2() {
}
void Holomap::loadHolomapGFX() {
- videoPtr1 = (uint8 *)_engine->workVideoBuffer.getPixels();
- videoPtr2 = videoPtr1 + 4488;
- videoPtr3 = videoPtr1 + 7854;
- videoPtr4 = videoPtr1 + 8398;
+ uint8 *videoPtr1 = (uint8 *)_engine->workVideoBuffer.getPixels();
+ uint8 *videoPtr3 = videoPtr1 + 7854;
+ uint8 *videoPtr4 = videoPtr1 + 8398;
- videoPtr5 = videoPtr1 + 73934;
+ uint8 *videoPtr5 = videoPtr1 + 73934;
_engine->_hqrdepack->hqrGetEntry(videoPtr3, Resources::HQR_RESS_FILE, RESSHQR_HOLOSURFACE);
_engine->_hqrdepack->hqrGetEntry(videoPtr4, Resources::HQR_RESS_FILE, RESSHQR_HOLOIMG);
- videoPtr6 = videoPtr5 + _engine->_hqrdepack->hqrGetEntry(videoPtr5, Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINMDL);
- videoPtr7 = videoPtr6 + _engine->_hqrdepack->hqrGetEntry(videoPtr6, Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWMDL);
- videoPtr8 = videoPtr7 + _engine->_hqrdepack->hqrGetEntry(videoPtr7, Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINARROWMDL);
- videoPtr11 = videoPtr8 + _engine->_hqrdepack->hqrGetEntry(videoPtr8, Resources::HQR_RESS_FILE, RESSHQR_HOLOPOINTMDL);
+ uint8 *videoPtr6 = videoPtr5 + _engine->_hqrdepack->hqrGetEntry(videoPtr5, Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINMDL);
+ uint8 *videoPtr7 = videoPtr6 + _engine->_hqrdepack->hqrGetEntry(videoPtr6, Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWMDL);
+ uint8 *videoPtr8 = videoPtr7 + _engine->_hqrdepack->hqrGetEntry(videoPtr7, Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINARROWMDL);
loadGfxSub(videoPtr5);
loadGfxSub(videoPtr6);
@@ -80,22 +78,25 @@ void Holomap::loadHolomapGFX() {
loadGfxSub(videoPtr8);
- videoPtr10 = videoPtr11 + 4488;
- videoPtr12 = videoPtr10 + _engine->_hqrdepack->hqrGetEntry(videoPtr10, Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWINFO);
- videoPtr13 = videoPtr12 + _engine->_hqrdepack->hqrGetEntry(videoPtr12, Resources::HQR_RESS_FILE, RESSHQR_HOLOPOINTANIM);
+ // TODO:
+ // uint8 *videoPtr2 = videoPtr1 + 4488;
+ // uint8 *videoPtr11 = videoPtr8 + _engine->_hqrdepack->hqrGetEntry(videoPtr8, Resources::HQR_RESS_FILE, RESSHQR_HOLOPOINTMDL);
+ // uint8 *videoPtr10 = videoPtr11 + 4488;
+ // uint8 *videoPtr12 = videoPtr10 + _engine->_hqrdepack->hqrGetEntry(videoPtr10, Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWINFO);
+ // uint8 *videoPtr13 = videoPtr12 + _engine->_hqrdepack->hqrGetEntry(videoPtr12, Resources::HQR_RESS_FILE, RESSHQR_HOLOPOINTANIM);
_engine->_screens->loadCustomPalette(RESSHQR_HOLOPAL);
int32 j = 576;
for (int32 i = 0; i < 96; i += 3, j += 3) {
- paletteHolomap[i] = _engine->_screens->palette[j];
+ paletteHolomap[i + 0] = _engine->_screens->palette[j + 0];
paletteHolomap[i + 1] = _engine->_screens->palette[j + 1];
paletteHolomap[i + 2] = _engine->_screens->palette[j + 2];
}
j = 576;
for (int32 i = 96; i < 189; i += 3, j += 3) {
- paletteHolomap[i] = _engine->_screens->palette[j];
+ paletteHolomap[i + 0] = _engine->_screens->palette[j + 0];
paletteHolomap[i + 1] = _engine->_screens->palette[j + 1];
paletteHolomap[i + 2] = _engine->_screens->palette[j + 2];
}
@@ -115,15 +116,12 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
}
void Holomap::processHolomap() {
- int32 alphaLightTmp;
- int32 betaLightTmp;
-
_engine->freezeTime();
// TODO memcopy palette
- alphaLightTmp = _engine->_scene->alphaLight;
- betaLightTmp = _engine->_scene->betaLight;
+ const int32 alphaLightTmp = _engine->_scene->alphaLight;
+ const int32 betaLightTmp = _engine->_scene->betaLight;
_engine->_screens->fadeToBlack(_engine->_screens->paletteRGBA);
_engine->_sound->stopSamples();
diff --git a/engines/twine/holomap.h b/engines/twine/holomap.h
index 1c06f3e189..09c3fd46f5 100644
--- a/engines/twine/holomap.h
+++ b/engines/twine/holomap.h
@@ -37,20 +37,6 @@ private:
int32 needToLoadHolomapGFX = 0;
uint8 paletteHolomap[NUMOFCOLORS * 3]{0};
- uint8 *videoPtr1 = nullptr;
- uint8 *videoPtr2 = nullptr;
- uint8 *videoPtr3 = nullptr;
- uint8 *videoPtr4 = nullptr;
- uint8 *videoPtr5 = nullptr;
- uint8 *videoPtr6 = nullptr;
- uint8 *videoPtr7 = nullptr;
- uint8 *videoPtr8 = nullptr;
- uint8 *videoPtr9 = nullptr;
- uint8 *videoPtr10 = nullptr;
- uint8 *videoPtr11 = nullptr;
- uint8 *videoPtr12 = nullptr;
- uint8 *videoPtr13 = nullptr;
-
public:
Holomap(TwinEEngine *engine);
Commit: 7988b5a750d30e9e9de0b434561ded8880509241
https://github.com/scummvm/scummvm/commit/7988b5a750d30e9e9de0b434561ded8880509241
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: reduced scopes
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index f26d11781d..f6251024c9 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -223,15 +223,11 @@ int16 Menu::VolumeMenuSettings[] = {
Menu::Menu(TwinEEngine *engine) : _engine(engine) {}
void Menu::plasmaEffectRenderFrame() {
- int16 c;
- int32 i, j;
- uint8 *dest;
- uint8 *src;
-
- for (j = 1; j < PLASMA_HEIGHT - 1; j++) {
- for (i = 1; i < PLASMA_WIDTH - 1; i++) {
+ for (int32 j = 1; j < PLASMA_HEIGHT - 1; j++) {
+ for (int32 i = 1; i < PLASMA_WIDTH - 1; i++) {
/* Here we calculate the average of all 8 neighbour pixel values */
+ int16 c;
c = plasmaEffectPtr[(i - 1) + (j - 1) * PLASMA_WIDTH]; //top-left
c += plasmaEffectPtr[(i + 0) + (j - 1) * PLASMA_WIDTH]; //top
c += plasmaEffectPtr[(i + 1) + (j - 1) * PLASMA_WIDTH]; //top-right
@@ -258,14 +254,14 @@ void Menu::plasmaEffectRenderFrame() {
}
// flip the double-buffer while scrolling the effect vertically:
- dest = plasmaEffectPtr;
- src = plasmaEffectPtr + (PLASMA_HEIGHT + 1) * PLASMA_WIDTH;
- for (i = 0; i < PLASMA_HEIGHT * PLASMA_WIDTH; i++)
+ uint8 *dest = plasmaEffectPtr;
+ uint8 *src = plasmaEffectPtr + (PLASMA_HEIGHT + 1) * PLASMA_WIDTH;
+ for (int32 i = 0; i < PLASMA_HEIGHT * PLASMA_WIDTH; i++)
*(dest++) = *(src++);
}
void Menu::processPlasmaEffect(int32 top, int32 color) {
- const uint8 max_value = color + 15;
+ const int32 max_value = color + 15;
plasmaEffectRenderFrame();
@@ -274,15 +270,12 @@ void Menu::processPlasmaEffect(int32 top, int32 color) {
for (int32 i = 0; i < 25; i++) {
for (int32 j = 0; j < kMainMenuButtonWidth; j++) {
- uint8 c = in[i * kMainMenuButtonWidth + j] / 2 + color;
- if (c > max_value)
- c = max_value;
-
+ const uint8 c = MIN(in[i * kMainMenuButtonWidth + j] / 2 + color, max_value);
/* 2x2 squares sharing the same pixel color: */
- int32 target = 2 * (i * SCREEN_W + j);
- out[target] = c;
+ const int32 target = 2 * (i * SCREEN_W + j);
+ out[target + 0] = c;
out[target + 1] = c;
- out[target + SCREEN_W] = c;
+ out[target + SCREEN_W + 0] = c;
out[target + SCREEN_W + 1] = c;
}
}
@@ -291,8 +284,8 @@ void Menu::processPlasmaEffect(int32 top, int32 color) {
void Menu::drawBox(int32 left, int32 top, int32 right, int32 bottom) {
_engine->_interface->drawLine(left, top, right, top, 79); // top line
_engine->_interface->drawLine(left, top, left, bottom, 79); // left line
- _engine->_interface->drawLine(right, ++top, right, bottom, 73); // right line
- _engine->_interface->drawLine(++left, bottom, right, bottom, 73); // bottom line
+ _engine->_interface->drawLine(right, top + 1, right, bottom, 73); // right line
+ _engine->_interface->drawLine(left + 1, bottom, right, bottom, 73); // bottom line
}
void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 textId, bool hover) {
@@ -304,25 +297,24 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
* int waveVolumeRemaped;
*/
- int32 left = width - kMainMenuButtonSpan / 2;
- int32 right = width + kMainMenuButtonSpan / 2;
+ const int32 left = width - kMainMenuButtonSpan / 2;
+ const int32 right = width + kMainMenuButtonSpan / 2;
// topheight is the center Y pos of the button
- int32 top = topheight - 25; // this makes the button be 50 height
- int32 bottom = topheight + 25;
- int32 bottom2 = bottom;
+ const int32 top = topheight - 25; // this makes the button be 50 height
+ const int32 bottom = topheight + 25;
if (hover != 0) {
if (buttonId <= kMasterVolume && buttonId >= kMusicVolume) {
int32 newWidth = 0;
switch (buttonId) {
case kMusicVolume: {
- const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
+ const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
newWidth = _engine->_screens->crossDot(left, right, Audio::Mixer::kMaxMixerVolume, volume);
break;
}
case kSoundVolume: {
- const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kSFXSoundType);
+ const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
newWidth = _engine->_screens->crossDot(left, right, Audio::Mixer::kMaxMixerVolume, volume);
break;
}
@@ -332,12 +324,12 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
break;
}
case kLineVolume: {
- const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kSpeechSoundType);
+ const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
newWidth = _engine->_screens->crossDot(left, right, Audio::Mixer::kMaxMixerVolume, volume);
break;
}
case kMasterVolume: {
- const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kPlainSoundType);
+ const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
newWidth = _engine->_screens->crossDot(left, right, Audio::Mixer::kMaxMixerVolume, volume);
break;
}
@@ -356,7 +348,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
}
} else {
_engine->_interface->blitBox(left, top, right, bottom, (const int8 *)_engine->workVideoBuffer.getPixels(), left, top, (int8 *)_engine->frontVideoBuffer.getPixels());
- _engine->_interface->drawTransparentBox(left, top, right, bottom2, 4);
+ _engine->_interface->drawTransparentBox(left, top, right, bottom, 4);
}
drawBox(left, top, right, bottom);
Commit: d976da79624a232a403e3e7c955f05efe942cf94
https://github.com/scummvm/scummvm/commit/d976da79624a232a403e3e7c955f05efe942cf94
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: format
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index f6251024c9..ae1246f2de 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -282,8 +282,8 @@ void Menu::processPlasmaEffect(int32 top, int32 color) {
}
void Menu::drawBox(int32 left, int32 top, int32 right, int32 bottom) {
- _engine->_interface->drawLine(left, top, right, top, 79); // top line
- _engine->_interface->drawLine(left, top, left, bottom, 79); // left line
+ _engine->_interface->drawLine(left, top, right, top, 79); // top line
+ _engine->_interface->drawLine(left, top, left, bottom, 79); // left line
_engine->_interface->drawLine(right, top + 1, right, bottom, 73); // right line
_engine->_interface->drawLine(left + 1, bottom, right, bottom, 73); // bottom line
}
Commit: 3789ff815bee5cd6421766542b8d991640817e4f
https://github.com/scummvm/scummvm/commit/3789ff815bee5cd6421766542b8d991640817e4f
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: error checks
Changed paths:
engines/twine/screens.cpp
diff --git a/engines/twine/screens.cpp b/engines/twine/screens.cpp
index 019d6c1009..e75a46b1f4 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/screens.cpp
@@ -40,7 +40,10 @@ void Screens::adelineLogo() {
}
void Screens::loadMenuImage(bool fade_in) {
- _engine->_hqrdepack->hqrGetEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, RESSHQR_MENUIMG);
+ if (_engine->_hqrdepack->hqrGetEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, RESSHQR_MENUIMG) == 0) {
+ warning("Failed to load menu image");
+ return;
+ }
copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
if (fade_in) {
fadeToPal(paletteRGBA);
@@ -52,7 +55,10 @@ void Screens::loadMenuImage(bool fade_in) {
}
void Screens::loadCustomPalette(int32 index) {
- _engine->_hqrdepack->hqrGetEntry(palette, Resources::HQR_RESS_FILE, index);
+ if (_engine->_hqrdepack->hqrGetEntry(palette, Resources::HQR_RESS_FILE, index) == 0) {
+ warning("Failed to load custom palette %i", index);
+ return;
+ }
convertPalToRGBA(palette, paletteRGBACustom);
}
@@ -68,7 +74,10 @@ void Screens::convertPalToRGBA(const uint8* in, uint32* out) {
}
void Screens::loadImage(int32 index, bool fade_in) {
- _engine->_hqrdepack->hqrGetEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, index);
+ if (_engine->_hqrdepack->hqrGetEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, index) == 0) {
+ warning("Failed to load image with index %i", index);
+ return;
+ }
copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
loadCustomPalette(index + 1);
if (fade_in) {
Commit: cbbeaf3203539ab5d0ae895ecbdf308ceb2786f6
https://github.com/scummvm/scummvm/commit/cbbeaf3203539ab5d0ae895ecbdf308ceb2786f6
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: reduced scope
Changed paths:
engines/twine/screens.cpp
diff --git a/engines/twine/screens.cpp b/engines/twine/screens.cpp
index e75a46b1f4..6ba1c498d3 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/screens.cpp
@@ -96,10 +96,11 @@ void Screens::loadImageDelay(int32 index, int32 time) {
}
void Screens::fadeIn(uint32 *pal) {
- if (_engine->cfgfile.CrossFade)
+ if (_engine->cfgfile.CrossFade) {
_engine->crossFade(_engine->frontVideoBuffer, pal);
- else
+ } else {
fadeToPal(pal);
+ }
_engine->setPalette(pal);
}
@@ -109,13 +110,15 @@ void Screens::fadeOut(uint32 *pal) {
crossFade(frontVideoBuffer, palette);
else
fadeToBlack(palette);*/
- if (!_engine->cfgfile.CrossFade)
+ if (!_engine->cfgfile.CrossFade) {
fadeToBlack(pal);
+ }
}
int32 Screens::crossDot(int32 modifier, int32 color, int32 param, int32 intensity) {
- if (!param)
+ if (!param) {
return color;
+ }
return (((color - modifier) * intensity) / param) + modifier;
}
@@ -188,22 +191,20 @@ void Screens::adjustCrossPalette(const uint32 *pal1, const uint32 *pal2) {
}
void Screens::fadeToBlack(uint32 *pal) {
- int32 i = 0;
+ if (palResetted) {
+ return;
+ }
- if (!palResetted) {
- for (i = 100; i >= 0; i -= 3) {
- adjustPalette(0, 0, 0, pal, i);
- _engine->_system->delayMillis(1000 / 50);
- }
+ for (int32 i = 100; i >= 0; i -= 3) {
+ adjustPalette(0, 0, 0, pal, i);
+ _engine->_system->delayMillis(1000 / 50);
}
palResetted = true;
}
void Screens::fadeToPal(uint32 *pal) {
- int32 i = 100;
-
- for (i = 0; i <= 100; i += 3) {
+ for (int32 i = 0; i <= 100; i += 3) {
adjustPalette(0, 0, 0, pal, i);
_engine->_system->delayMillis(1000 / 50);
}
@@ -233,31 +234,25 @@ void Screens::setBackPal() {
}
void Screens::fadePalRed(uint32 *pal) {
- int32 i = 100;
-
- for (i = 100; i >= 0; i -= 2) {
+ for (int32 i = 100; i >= 0; i -= 2) {
adjustPalette(0xFF, 0, 0, pal, i);
_engine->_system->delayMillis(1000 / 50);
}
}
void Screens::fadeRedPal(uint32 *pal) {
- int32 i = 0;
-
- for (i = 0; i <= 100; i += 2) {
+ for (int32 i = 0; i <= 100; i += 2) {
adjustPalette(0xFF, 0, 0, pal, i);
_engine->_system->delayMillis(1000 / 50);
}
}
void Screens::copyScreen(const uint8 *source, uint8 *destination) {
- int32 w, h;
-
if (SCALE == 1) {
memcpy(destination, source, SCREEN_WIDTH * SCREEN_HEIGHT);
} else if (SCALE == 2) {
- for (h = 0; h < SCREEN_HEIGHT / SCALE; h++) {
- for (w = 0; w < SCREEN_WIDTH / SCALE; w++) {
+ for (int32 h = 0; h < SCREEN_HEIGHT / SCALE; h++) {
+ for (int32 w = 0; w < SCREEN_WIDTH / SCALE; w++) {
*destination++ = *source;
*destination++ = *source++;
}
Commit: b387c3903ef181c437f67bc6890000ccb10b0f25
https://github.com/scummvm/scummvm/commit/b387c3903ef181c437f67bc6890000ccb10b0f25
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: new todo comment
Changed paths:
engines/twine/twine.cpp
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 061fd73ac9..12b375d746 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -363,11 +363,11 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
if (loopCurrentKey == twineactions[TwinEActionType::OptionsMenu].localKey) {
freezeTime();
_sound->pauseSamples();
- _menu->OptionsMenuSettings[MenuSettings_FirstButton] = 15;
+ _menu->OptionsMenuSettings[MenuSettings_FirstButton] = 15; // TODO: why? - where is the reset? kReturnGame
_text->initTextBank(0);
_menu->optionsMenu();
_text->initTextBank(_text->currentTextBank + 3);
- //TODO: play music
+ // TODO: play music
_sound->resumeSamples();
unfreezeTime();
_redraw->redrawEngineActions(1);
Commit: 3868b03b4c617d92d72bda0f07cda47bb3f580cd
https://github.com/scummvm/scummvm/commit/3868b03b4c617d92d72bda0f07cda47bb3f580cd
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: added small helper function to Keyboard struct
Changed paths:
engines/twine/flamovies.cpp
engines/twine/keyboard.h
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index fe7612dbaf..ba68701590 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -310,7 +310,7 @@ void FlaMovies::playFlaMovie(const char *flaName) {
break;
}
- if (_engine->_keyboard.internalKeyCode) {
+ if (_engine->_keyboard.isAnyKeyPressed()) {
break;
}
} while (true);
diff --git a/engines/twine/keyboard.h b/engines/twine/keyboard.h
index 9094c5c4a9..abe9e2cced 100644
--- a/engines/twine/keyboard.h
+++ b/engines/twine/keyboard.h
@@ -110,6 +110,10 @@ struct Keyboard {
int16 key = 0;
int32 heroPressedKey = 0;
int32 heroPressedKey2 = 0;
+
+ bool isAnyKeyPressed() const {
+ return internalKeyCode != 0;
+ }
};
} // namespace TwinE
Commit: 219d1f35626e42270f5675d59cb50d3974b1b01c
https://github.com/scummvm/scummvm/commit/219d1f35626e42270f5675d59cb50d3974b1b01c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: provide default parameter values for playSample
Changed paths:
engines/twine/gamestate.cpp
engines/twine/redraw.cpp
engines/twine/scene.cpp
engines/twine/sound.h
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index cdd09ed4b8..dfba180069 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -323,7 +323,7 @@ void GameState::processFoundItem(int32 item) {
boxBottomRightX = _engine->_renderer->projPosX + 65;
boxBottomRightY = _engine->_renderer->projPosY + 65;
- _engine->_sound->playSample(41, 0x1000, 1, 0x80, 0x80, 0x80, -1);
+ _engine->_sound->playSample(41);
// process vox play
_engine->_music->stopMusic();
@@ -502,7 +502,7 @@ void GameState::processGameoverAnimation() { // makeGameOver
_engine->_system->delayMillis(15);
}
- _engine->_sound->playSample(37, _engine->getRandomNumber(2000) + 3096, 1, 0x80, 0x80, 0x80, -1);
+ _engine->_sound->playSample(37, _engine->getRandomNumber(2000) + 3096);
_engine->_interface->blitBox(120, 120, 519, 359, (int8 *)_engine->workVideoBuffer.getPixels(), 120, 120, (int8 *)_engine->frontVideoBuffer.getPixels());
_engine->_renderer->setCameraAngle(0, 0, 0, 0, 0, 0, 3200);
_engine->_renderer->renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index e81bbca1e9..45bea9db7f 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -310,7 +310,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
extra->lifeTime = _engine->lbaTime;
extra->type &= 0xFBFF;
// FIXME make constant for sample index
- _engine->_sound->playSample(11, 0x1000, 1, extra->x, extra->y, extra->z, -1);
+ _engine->_sound->playSample(11, 4096, 1, extra->x, extra->y, extra->z);
}
} else {
if ((extra->type & 1) || (extra->type & 0x40) || (extra->actorIdx + extra->lifeTime - 150 < _engine->lbaTime) || (!((_engine->lbaTime + extra->lifeTime) & 8))) {
diff --git a/engines/twine/scene.cpp b/engines/twine/scene.cpp
index b15df478d9..df4d719a48 100644
--- a/engines/twine/scene.cpp
+++ b/engines/twine/scene.cpp
@@ -411,7 +411,7 @@ void Scene::processEnvironmentSound() {
decal = sampleRound[currentAmb];
repeat = sampleRepeat[currentAmb];
- _engine->_sound->playSample(sampleIdx, (0x1000 + _engine->getRandomNumber(decal) - (decal / 2)), repeat, 110, -1, 110, -1);
+ _engine->_sound->playSample(sampleIdx, (0x1000 + _engine->getRandomNumber(decal) - (decal / 2)), repeat, 110, -1, 110);
break;
}
}
diff --git a/engines/twine/sound.h b/engines/twine/sound.h
index 186f1bbb98..687d5f4e70 100644
--- a/engines/twine/sound.h
+++ b/engines/twine/sound.h
@@ -82,11 +82,11 @@ public:
* @param index sample index under flasamp.hqr file
* @param frequency frequency used to play the sample
* @param repeat number of times to repeat the sample
- * @param x unknown x variable
- * @param y unknown y variable
- * @param z unknown z variable
+ * @param x sound generating entity x position
+ * @param y sound generating entity y position
+ * @param z sound generating entity z position
*/
- void playSample(int32 index, int32 frequency, int32 repeat, int32 x, int32 y, int32 z, int32 actorIdx);
+ void playSample(int32 index, int32 frequency = 4096, int32 repeat = 1, int32 x = 128, int32 y = 128, int32 z = 128, int32 actorIdx = -1);
/** Pause samples */
void pauseSamples();
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 12b375d746..59317ef93c 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -629,7 +629,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
if ((brickSound & 0xF) == 1) {
if (a) { // all other actors
int32 rnd = getRandomNumber(2000) + 3096;
- _sound->playSample(0x25, rnd, 1, actor->x, actor->y, actor->z, a);
+ _sound->playSample(37, rnd, 1, actor->x, actor->y, actor->z, a);
if (actor->bonusParameter & 0x1F0) {
if (!(actor->bonusParameter & 1)) {
_actor->processActorExtraBonus(a);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index d268bf7fd0..0c0051a79c 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -112,7 +112,7 @@ struct ConfigFile {
bool Debug = false;
/** Use original autosaving system or save when you want */
int32 UseAutoSaving = 0;
- /** Shadow mode type */
+ /** Shadow mode type, value: all, character only, none */
int32 ShadowMode = 0;
/** AutoAgressive mode type */
int32 AutoAgressive = 0;
Commit: 6affc464e7b2aba3728917836a18b349b3e0a86c
https://github.com/scummvm/scummvm/commit/6affc464e7b2aba3728917836a18b349b3e0a86c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: minor cleanup
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index ae1246f2de..9351c2da6a 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -255,7 +255,7 @@ void Menu::plasmaEffectRenderFrame() {
// flip the double-buffer while scrolling the effect vertically:
uint8 *dest = plasmaEffectPtr;
- uint8 *src = plasmaEffectPtr + (PLASMA_HEIGHT + 1) * PLASMA_WIDTH;
+ const uint8 *src = plasmaEffectPtr + (PLASMA_HEIGHT + 1) * PLASMA_WIDTH;
for (int32 i = 0; i < PLASMA_HEIGHT * PLASMA_WIDTH; i++)
*(dest++) = *(src++);
}
@@ -265,7 +265,7 @@ void Menu::processPlasmaEffect(int32 top, int32 color) {
plasmaEffectRenderFrame();
- uint8 *in = plasmaEffectPtr + 5 * PLASMA_WIDTH;
+ const uint8 *in = plasmaEffectPtr + 5 * PLASMA_WIDTH;
uint8 *out = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top];
for (int32 i = 0; i < 25; i++) {
@@ -289,14 +289,6 @@ void Menu::drawBox(int32 left, int32 top, int32 right, int32 bottom) {
}
void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 textId, bool hover) {
- /*
- * int CDvolumeRemaped;
- * int musicVolumeRemaped;
- * int masterVolumeRemaped;
- * int lineVolumeRemaped;
- * int waveVolumeRemaped;
- */
-
const int32 left = width - kMainMenuButtonSpan / 2;
const int32 right = width + kMainMenuButtonSpan / 2;
Commit: 37fdcb84e4603ac549f2a98add15b08c8fbad954
https://github.com/scummvm/scummvm/commit/37fdcb84e4603ac549f2a98add15b08c8fbad954
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: reduced scope
Changed paths:
engines/twine/menu.cpp
engines/twine/menu.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 9351c2da6a..f684d282b1 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -706,29 +706,22 @@ void Menu::run() {
}
int32 Menu::giveupMenu() {
- //int32 saveLangue=0;
- int32 menuId;
- int16 *localMenu;
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
_engine->_sound->pauseSamples();
- if (_engine->cfgfile.UseAutoSaving == 1)
+ int16 *localMenu;
+ if (_engine->cfgfile.UseAutoSaving == 1) {
localMenu = GiveUpMenuSettings;
- else
+ } else {
localMenu = GiveUpMenuSettingsWithSave;
+ }
+ int32 menuId;
do {
- //saveLangue = languageCD1;
- //languageCD1 = 0;
_engine->_text->initTextBank(0);
-
menuId = processMenu(localMenu);
-
- //languageCD1 = saveLangue;
-
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
-
_engine->_system->delayMillis(1000 / _engine->cfgfile.Fps);
} while (menuId != kGiveUp && menuId != kContinue);
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index 7fede85416..0486bcea39 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -41,7 +41,6 @@ enum MenuSettingsType {
class Menu {
private:
TwinEEngine *_engine;
-
/** Hero behaviour menu entity */
uint8 *behaviourEntity = 0;
/** Behaviour menu anim state */
Commit: 851cf6a8c53c79f35226aece8306100b53fc0fc1
https://github.com/scummvm/scummvm/commit/851cf6a8c53c79f35226aece8306100b53fc0fc1
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed restarting the engine with broken menu state
Changed paths:
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/twine.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index f684d282b1..478153dc9b 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -27,6 +27,7 @@
#include "common/events.h"
#include "common/scummsys.h"
#include "common/system.h"
+#include "common/util.h"
#include "twine/actor.h"
#include "twine/animations.h"
#include "twine/gamestate.h"
@@ -90,10 +91,11 @@ enum VolumeMenuType {
kMasterVolume = 5
};
+namespace _priv {
/** Main Menu Settings
Used to create the game main menu. */
-int16 Menu::MainMenuSettings[] = {
+static const int16 MainMenuSettings[] = {
0, // Current loaded button (button number)
4, // Num of buttons
200, // Buttons box height ( is used to calc the height where the first button will appear )
@@ -111,7 +113,7 @@ int16 Menu::MainMenuSettings[] = {
/** Give Up Menu Settings
Used to create the in-game menu. */
-int16 Menu::GiveUpMenuSettings[] = {
+static const int16 GiveUpMenuSettings[] = {
0, // Current loaded button (button number)
2, // Num of buttons
240, // Buttons box height ( is used to calc the height where the first button will appear )
@@ -125,7 +127,7 @@ int16 Menu::GiveUpMenuSettings[] = {
/** Give Up Menu Settings
Used to create the in-game menu. This menu have one extra item to save the game */
-int16 Menu::GiveUpMenuSettingsWithSave[] = {
+static const int16 GiveUpMenuWithSaveSettings[] = {
0, // Current loaded button (button number)
3, // Num of buttons
240, // Buttons box height ( is used to calc the height where the first button will appear )
@@ -141,7 +143,7 @@ int16 Menu::GiveUpMenuSettingsWithSave[] = {
/** Options Menu Settings
Used to create the options menu. */
-int16 Menu::OptionsMenuSettings[] = {
+static const int16 OptionsMenuSettings[] = {
0, // Current loaded button (button number)
4, // Num of buttons
0, // Buttons box height ( is used to calc the height where the first button will appear )
@@ -159,7 +161,7 @@ int16 Menu::OptionsMenuSettings[] = {
/** Advanced Options Menu Settings
Used to create the advanced options menu. */
-int16 Menu::AdvOptionsMenuSettings[] = {
+static const int16 AdvOptionsMenuSettings[] = {
0, // Current loaded button (button number)
5, // Num of buttons
0, // Buttons box height ( is used to calc the height where the first button will appear )
@@ -179,7 +181,7 @@ int16 Menu::AdvOptionsMenuSettings[] = {
/** Save Game Management Menu Settings
Used to create the save game management menu. */
-int16 Menu::SaveManageMenuSettings[] = {
+static const int16 SaveManageMenuSettings[] = {
0, // Current loaded button (button number)
3, // Num of buttons
0, // Buttons box height ( is used to calc the height where the first button will appear )
@@ -195,7 +197,7 @@ int16 Menu::SaveManageMenuSettings[] = {
/** Volume Menu Settings
Used to create the volume menu. */
-int16 Menu::VolumeMenuSettings[] = {
+static const int16 VolumeMenuSettings[] = {
0, // Current loaded button (button number)
7, // Num of buttons
0, // Buttons box height ( is used to calc the height where the first button will appear )
@@ -215,12 +217,30 @@ int16 Menu::VolumeMenuSettings[] = {
0,
16, // save parameters
};
+} // namespace _priv
#define PLASMA_WIDTH 320
#define PLASMA_HEIGHT 50
#define SCREEN_W 640
-Menu::Menu(TwinEEngine *engine) : _engine(engine) {}
+static int16* copySettings(const int16* settings, size_t size) {
+ int16 *buf = (int16 *)malloc(size);
+ if (buf == nullptr) {
+ error("Failed to allocate menu state memory");
+ }
+ memcpy(buf, settings, size);
+ return buf;
+}
+
+Menu::Menu(TwinEEngine *engine) : _engine(engine) {
+ OptionsMenuState = copySettings(_priv::OptionsMenuSettings, sizeof(_priv::OptionsMenuSettings));
+ GiveUpMenuWithSaveState = copySettings(_priv::GiveUpMenuWithSaveSettings, sizeof(_priv::GiveUpMenuWithSaveSettings));
+ VolumeMenuState = copySettings(_priv::VolumeMenuSettings, sizeof(_priv::VolumeMenuSettings));
+ SaveManageMenuState = copySettings(_priv::SaveManageMenuSettings, sizeof(_priv::SaveManageMenuSettings));
+ GiveUpMenuState = copySettings(_priv::GiveUpMenuSettings, sizeof(_priv::GiveUpMenuSettings));
+ MainMenuState = copySettings(_priv::MainMenuSettings, sizeof(_priv::MainMenuSettings));
+ AdvOptionsMenuState = copySettings(_priv::AdvOptionsMenuSettings, sizeof(_priv::AdvOptionsMenuSettings));
+}
void Menu::plasmaEffectRenderFrame() {
for (int32 j = 1; j < PLASMA_HEIGHT - 1; j++) {
@@ -416,7 +436,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
do {
// if its on main menu
- if (menuSettings == MainMenuSettings) {
+ if (menuSettings == MainMenuState) {
if (_engine->lbaTime - localTime > 11650) {
return kBackground;
}
@@ -455,7 +475,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
// if its a volume button
- if (menuSettings == VolumeMenuSettings) {
+ if (menuSettings == VolumeMenuState) {
const int16 id = *(&menuSettings[MenuSettings_FirstButtonState] + currentButton * 2); // get button parameters from settings array
Audio::Mixer *mixer = _engine->_system->getMixer();
@@ -555,7 +575,7 @@ int32 Menu::advoptionsMenu() {
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
do {
- switch (processMenu(AdvOptionsMenuSettings)) {
+ switch (processMenu(AdvOptionsMenuState)) {
case kReturnMenu: {
ret = 1; // quit option menu
break;
@@ -578,7 +598,7 @@ int32 Menu::savemanageMenu() {
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
do {
- switch (processMenu(SaveManageMenuSettings)) {
+ switch (processMenu(SaveManageMenuState)) {
case kReturnMenu: {
ret = 1; // quit option menu
break;
@@ -601,7 +621,7 @@ int32 Menu::volumeMenu() {
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
do {
- switch (processMenu(VolumeMenuSettings)) {
+ switch (processMenu(VolumeMenuState)) {
case kReturnMenu: {
ret = 1; // quit option menu
break;
@@ -627,7 +647,7 @@ int32 Menu::optionsMenu() {
//_engine->_music->playCDtrack(9);
do {
- switch (processMenu(OptionsMenuSettings)) {
+ switch (processMenu(OptionsMenuState)) {
case kReturnGame:
case kReturnMenu: {
ret = 1; // quit option menu
@@ -675,7 +695,7 @@ void Menu::run() {
_engine->_music->playTrackMusic(9); // LBA's Theme
_engine->_sound->stopSamples();
- switch (processMenu(MainMenuSettings)) {
+ switch (processMenu(MainMenuState)) {
case kNewGame: {
_engine->_menuOptions->newGameMenu();
break;
@@ -687,7 +707,7 @@ void Menu::run() {
case kOptions: {
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
_engine->flip();
- OptionsMenuSettings[5] = kReturnMenu;
+ OptionsMenuState[MenuSettings_FirstButton] = kReturnMenu;
optionsMenu();
break;
}
@@ -712,9 +732,9 @@ int32 Menu::giveupMenu() {
int16 *localMenu;
if (_engine->cfgfile.UseAutoSaving == 1) {
- localMenu = GiveUpMenuSettings;
+ localMenu = GiveUpMenuState;
} else {
- localMenu = GiveUpMenuSettingsWithSave;
+ localMenu = GiveUpMenuWithSaveState;
}
int32 menuId;
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index 0486bcea39..a9c76874ee 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -87,8 +87,16 @@ private:
*/
void drawMagicItemsBox(int32 left, int32 top, int32 right, int32 bottom, int32 color);
+ int16 *GiveUpMenuWithSaveState;
+ int16 *VolumeMenuState;
+ int16 *SaveManageMenuState;
+ int16 *GiveUpMenuState;
+ int16 *MainMenuState;
+ int16 *AdvOptionsMenuState;
+
public:
Menu(TwinEEngine *engine);
+ int16 *OptionsMenuState;
int32 currMenuTextIndex = -1;
int32 currMenuTextBank = -1;
@@ -96,15 +104,6 @@ public:
int16 itemAngle[255]{0}; // objectRotation
- // TODO: these should be const - or the state might not get reset on an engine restart
- static int16 OptionsMenuSettings[];
- static int16 GiveUpMenuSettingsWithSave[];
- static int16 VolumeMenuSettings[];
- static int16 SaveManageMenuSettings[];
- static int16 GiveUpMenuSettings[];
- static int16 MainMenuSettings[];
- static int16 AdvOptionsMenuSettings[];
-
/** Behaviour menu move pointer */
ActorMoveStruct moveMenu;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 59317ef93c..131fc97aa5 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -363,7 +363,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
if (loopCurrentKey == twineactions[TwinEActionType::OptionsMenu].localKey) {
freezeTime();
_sound->pauseSamples();
- _menu->OptionsMenuSettings[MenuSettings_FirstButton] = 15; // TODO: why? - where is the reset? kReturnGame
+ _menu->OptionsMenuState[MenuSettings_FirstButton] = 15; // TODO: why? - where is the reset? kReturnGame
_text->initTextBank(0);
_menu->optionsMenu();
_text->initTextBank(_text->currentTextBank + 3);
Commit: f7defb55e0c441d9cc4886ca42a0adbb862966ef
https://github.com/scummvm/scummvm/commit/f7defb55e0c441d9cc4886ca42a0adbb862966ef
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: cleanup gamestate - use constants for dynamic menu
Changed paths:
engines/twine/gamestate.cpp
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index dfba180069..805ae997f8 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -433,22 +433,21 @@ void GameState::processFoundItem(int32 item) {
void GameState::processGameChoices(int32 choiceIdx) {
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- gameChoicesSettings[0] = 0; // Current loaded button (button number)
- gameChoicesSettings[1] = numChoices; // Num of buttons
- gameChoicesSettings[2] = 0; // Buttons box height
- gameChoicesSettings[3] = _engine->_text->currentTextBank + 3;
-
- if (numChoices > 0) {
- for (int32 i = 0; i < numChoices; i++) {
- gameChoicesSettings[i * 2 + 4] = 0;
- gameChoicesSettings[i * 2 + 5] = gameChoices[i];
- }
+ gameChoicesSettings[MenuSettings_CurrentLoadedButton] = 0; // Current loaded button (button number)
+ gameChoicesSettings[MenuSettings_NumberOfButtons] = numChoices; // Num of buttons
+ gameChoicesSettings[MenuSettings_ButtonsBoxHeight] = 0; // Buttons box height
+ gameChoicesSettings[MenuSettings_HeaderEnd] = _engine->_text->currentTextBank + 3;
+
+ // filled via script
+ for (int32 i = 0; i < numChoices; i++) {
+ gameChoicesSettings[i * 2 + MenuSettings_FirstButtonState] = 0;
+ gameChoicesSettings[i * 2 + MenuSettings_FirstButton] = gameChoices[i];
}
_engine->_text->drawAskQuestion(choiceIdx);
_engine->_menu->processMenu(gameChoicesSettings);
- choiceAnswer = gameChoices[gameChoicesSettings[0]];
+ choiceAnswer = gameChoices[gameChoicesSettings[MenuSettings_CurrentLoadedButton]];
// get right VOX entry index
if (_engine->_text->initVoxToPlay(choiceAnswer)) {
@@ -479,8 +478,6 @@ void GameState::processGameoverAnimation() { // makeGameOver
_engine->_hqrdepack->hqrGetEntry(gameOverPtr, Resources::HQR_RESS_FILE, RESSHQR_GAMEOVERMDL);
if (gameOverPtr) {
- int32 avg, cdot;
-
_engine->_renderer->prepareIsoModel(gameOverPtr);
_engine->_sound->stopSamples();
_engine->_music->stopMidiMusic(); // stop fade music
@@ -491,8 +488,8 @@ void GameState::processGameoverAnimation() { // makeGameOver
while (_engine->_keyboard.internalKeyCode != 1 && (_engine->lbaTime - startLbaTime) <= 500) {
_engine->readKeys();
- avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
- cdot = _engine->_screens->crossDot(1, 1024, 100, (_engine->lbaTime - startLbaTime) % 0x64);
+ int32 avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
+ int32 cdot = _engine->_screens->crossDot(1, 1024, 100, (_engine->lbaTime - startLbaTime) % 0x64);
_engine->_interface->blitBox(120, 120, 519, 359, (int8 *)_engine->workVideoBuffer.getPixels(), 120, 120, (int8 *)_engine->frontVideoBuffer.getPixels());
_engine->_renderer->setCameraAngle(0, 0, 0, 0, -cdot, 0, avg);
_engine->_renderer->renderIsoModel(0, 0, 0, 0, 0, 0, gameOverPtr);
Commit: 1003a57f40383511b6f8f5b898afec02caec19de
https://github.com/scummvm/scummvm/commit/1003a57f40383511b6f8f5b898afec02caec19de
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed warning
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 478153dc9b..809a02af5a 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -316,7 +316,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
const int32 top = topheight - 25; // this makes the button be 50 height
const int32 bottom = topheight + 25;
- if (hover != 0) {
+ if (hover) {
if (buttonId <= kMasterVolume && buttonId >= kMusicVolume) {
int32 newWidth = 0;
switch (buttonId) {
Commit: 0ef816f5e294757c1e19f1af46302bf671f9e662
https://github.com/scummvm/scummvm/commit/0ef816f5e294757c1e19f1af46302bf671f9e662
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: comments
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 809a02af5a..789b9711b5 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -544,9 +544,12 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (buttonNeedRedraw) {
menuSettings[MenuSettings_CurrentLoadedButton] = currentButton;
- drawButton(menuSettings, false); // current button
+ // draw all buttons
+ drawButton(menuSettings, false);
do {
_engine->readKeys();
+ // draw plasma effect for the current selected button
+ // .. until a key was pressed
drawButton(menuSettings, true);
} while (_engine->_keyboard.pressedKey == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.internalKeyCode == 0);
buttonNeedRedraw = false;
Commit: b7d52327085ca5f2a8246ff8ea436341a1edd5a9
https://github.com/scummvm/scummvm/commit/b7d52327085ca5f2a8246ff8ea436341a1edd5a9
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: refactored input
Changed paths:
A engines/twine/input.cpp
A engines/twine/input.h
R engines/twine/keyboard.h
engines/twine/menu.cpp
engines/twine/menuoptions.cpp
engines/twine/menuoptions.h
engines/twine/module.mk
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/input.cpp b/engines/twine/input.cpp
new file mode 100644
index 0000000000..2f5dd0c524
--- /dev/null
+++ b/engines/twine/input.cpp
@@ -0,0 +1,123 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_KEYBOARD_H
+#define TWINE_KEYBOARD_H
+
+#include "twine/input.h"
+#include "common/system.h"
+
+namespace TwinE {
+
+Input::Input(TwinEEngine *engine) : _engine(engine) {}
+
+bool Input::isAnyKeyPressed() const {
+ return internalKeyCode != 0;
+}
+
+bool Input::isPressed(Common::KeyCode keycode) {
+}
+
+void Input::readKeys() {
+ if (_engine->shouldQuit()) {
+ internalKeyCode = 1;
+ skippedKey = 1;
+ return;
+ }
+ skippedKey = 0;
+ internalKeyCode = 0;
+
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ uint8 localKey = 0;
+ switch (event.type) {
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
+ actionStates[event.customType] = false;
+ localKey = twineactions[event.customType].localKey;
+ break;
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
+ if (!cfgfile.Debug) {
+ switch (event.customType) {
+ case TwinEActionType::NextRoom:
+ case TwinEActionType::PreviousRoom:
+ case TwinEActionType::ApplyCellingGrid:
+ case TwinEActionType::IncreaseCellingGridIndex:
+ case TwinEActionType::DecreaseCellingGridIndex:
+ break;
+ default:
+ localKey = twineactions[event.customType].localKey;
+ actionStates[event.customType] = true;
+ break;
+ }
+ } else {
+ localKey = twineactions[event.customType].localKey;
+ actionStates[event.customType] = true;
+ }
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ leftMouse = 1;
+ break;
+ case Common::EVENT_KEYDOWN: {
+ if (event.kbd.keycode == Common::KeyCode::KEYCODE_RETURN || event.kbd.keycode == Common::KeyCode::KEYCODE_KP_ENTER) {
+ _hitEnter = true;
+ }
+ break;
+ }
+ case Common::EVENT_KEYUP: {
+ if (event.kbd.keycode == Common::KeyCode::KEYCODE_RETURN || event.kbd.keycode == Common::KeyCode::KEYCODE_KP_ENTER) {
+ _hitEnter = false;
+ }
+ break;
+ }
+ case Common::EVENT_RBUTTONDOWN:
+ rightMouse = 1;
+ break;
+ default:
+ break;
+ }
+
+ if (localKey == 0) {
+ continue;
+ }
+
+ for (int i = 0; i < ARRAYSIZE(pressedKeyCharMap); i++) {
+ if (pressedKeyCharMap[i].key == localKey) {
+ if (pressedKeyCharMap[i].pressed) {
+ if (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
+ pressedKey &= ~pressedKeyCharMap[i].high;
+ } else {
+ pressedKey |= pressedKeyCharMap[i].high;
+ }
+ } else {
+ skippedKey |= pressedKeyCharMap[i].high;
+ }
+ break;
+ }
+ }
+ internalKeyCode = localKey;
+ }
+}
+}; // namespace TwinE
+
+} // namespace TwinE
+
+#endif
diff --git a/engines/twine/keyboard.h b/engines/twine/input.h
similarity index 61%
rename from engines/twine/keyboard.h
rename to engines/twine/input.h
index abe9e2cced..8b995f2f31 100644
--- a/engines/twine/keyboard.h
+++ b/engines/twine/input.h
@@ -23,6 +23,7 @@
#ifndef TWINE_KEYBOARD_H
#define TWINE_KEYBOARD_H
+#include "common/keyboard.h"
#include "common/scummsys.h"
#include "common/util.h"
@@ -67,42 +68,52 @@ static constexpr const struct ActionMapping {
TwinEActionType action;
uint8 localKey;
} twineactions[] = {
- {Pause, 0x19},
- {NextRoom, 0x13},
- {PreviousRoom, 0x21},
- {ApplyCellingGrid, 0x14},
- {IncreaseCellingGridIndex, 0x22},
- {DecreaseCellingGridIndex, 0x30},
- {DebugGridCameraPressUp, 0x2E},
- {DebugGridCameraPressDown, 0x2C},
- {DebugGridCameraPressLeft, 0x1F},
- {DebugGridCameraPressRight, 0x2D},
- {QuickBehaviourNormal, 0x3B},
- {QuickBehaviourAthletic, 0x3C},
- {QuickBehaviourAggressive, 0x3D},
- {QuickBehaviourDiscreet, 0x3E},
- {ExecuteBehaviourAction, 0x39},
- {BehaviourMenu, 0x1D},
- {OptionsMenu, 0x40},
- {RecenterScreenOnTwinsen, 0x1C},
- {UseSelectedObject, 0x1C},
- {ThrowMagicBall, 0x38},
- {MoveForward, 0x48},
- {MoveBackward, 0x50},
- {TurnRight, 0x4D},
- {TurnLeft, 0x4B},
- {UseProtoPack, 0x24},
- {OpenHolomap, 0x23},
- {InventoryMenu, 0x36},
- {SpecialAction, 0x11},
- {Escape, 0x01},
- {PageUp, 0x49} // TODO: used for what?
+ {Pause, 0x19},
+ {NextRoom, 0x13},
+ {PreviousRoom, 0x21},
+ {ApplyCellingGrid, 0x14},
+ {IncreaseCellingGridIndex, 0x22},
+ {DecreaseCellingGridIndex, 0x30},
+ {DebugGridCameraPressUp, 0x2E},
+ {DebugGridCameraPressDown, 0x2C},
+ {DebugGridCameraPressLeft, 0x1F},
+ {DebugGridCameraPressRight, 0x2D},
+ {QuickBehaviourNormal, 0x3B},
+ {QuickBehaviourAthletic, 0x3C},
+ {QuickBehaviourAggressive, 0x3D},
+ {QuickBehaviourDiscreet, 0x3E},
+ {ExecuteBehaviourAction, 0x39},
+ {BehaviourMenu, 0x1D},
+ {OptionsMenu, 0x40},
+ {RecenterScreenOnTwinsen, 0x1C},
+ {UseSelectedObject, 0x1C},
+ {ThrowMagicBall, 0x38},
+ {MoveForward, 0x48},
+ {MoveBackward, 0x50},
+ {TurnRight, 0x4D},
+ {TurnLeft, 0x4B},
+ {UseProtoPack, 0x24},
+ {OpenHolomap, 0x23},
+ {InventoryMenu, 0x36},
+ {SpecialAction, 0x11},
+ {Escape, 0x01},
+ {PageUp, 0x49} // TODO: used for what?
};
static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected action mapping array size");
-struct Keyboard {
- bool actionStates[TwinEActionType::Max] {false};
+class TwinEEngine;
+
+class Input {
+private:
+ friend class TwinEEngine;
+ TwinEEngine *_engine;
+ bool _hitEnter = false;
+
+public:
+ Input(TwinEEngine *engine);
+
+ bool actionStates[TwinEActionType::Max]{false};
int16 skippedKey = 0;
int16 pressedKey = 0;
int16 internalKeyCode = 0;
@@ -110,10 +121,14 @@ struct Keyboard {
int16 key = 0;
int32 heroPressedKey = 0;
int32 heroPressedKey2 = 0;
+ int16 leftMouse = 0;
+ int16 rightMouse = 0;
+
+ bool isAnyKeyPressed() const;
+
+ bool isPressed(Common::KeyCode keycode);
- bool isAnyKeyPressed() const {
- return internalKeyCode != 0;
- }
+ void readKeys();
};
} // namespace TwinE
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 789b9711b5..965897f2db 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -25,6 +25,7 @@
#include "backends/audiocd/audiocd.h"
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/keyboard.h"
#include "common/scummsys.h"
#include "common/system.h"
#include "common/util.h"
@@ -101,13 +102,13 @@ static const int16 MainMenuSettings[] = {
200, // Buttons box height ( is used to calc the height where the first button will appear )
0, // unused
0,
- 20, // new game
+ kNewGame, // new game
0,
- 21, // continue game
+ kContinueGame, // continue game
0,
- 23, // options
+ kOptions, // options
0,
- 22, // quit
+ kQuit, // quit
};
/** Give Up Menu Settings
@@ -223,7 +224,7 @@ static const int16 VolumeMenuSettings[] = {
#define PLASMA_HEIGHT 50
#define SCREEN_W 640
-static int16* copySettings(const int16* settings, size_t size) {
+static int16 *copySettings(const int16 *settings, size_t size) {
int16 *buf = (int16 *)malloc(size);
if (buf == nullptr) {
error("Failed to allocate menu state memory");
@@ -425,143 +426,111 @@ void Menu::drawButton(const int16 *menuSettings, bool hover) {
int32 Menu::processMenu(int16 *menuSettings) {
int16 currentButton = menuSettings[MenuSettings_CurrentLoadedButton];
- bool buttonReleased = true;
- bool buttonNeedRedraw = true;
+ bool buttonsNeedRedraw = true;
bool musicChanged = false;
const int32 numEntry = menuSettings[MenuSettings_NumberOfButtons];
- int32 localTime = _engine->lbaTime;
int32 maxButton = numEntry - 1;
- _engine->readKeys();
-
do {
- // if its on main menu
- if (menuSettings == MainMenuState) {
- if (_engine->lbaTime - localTime > 11650) {
- return kBackground;
- }
- if (_engine->_keyboard.internalKeyCode == '.') {
- if (_engine->_keyboard.skippedKey != ' ') {
- return kBackground;
- }
+ _engine->readKeys();
+ _engine->_keyboard.key = _engine->_keyboard.pressedKey;
+
+ if (_engine->_keyboard.isPressed(Common::KeyCode::KEYCODE_DOWN)) { // on arrow key down
+ debug("pressed down");
+ currentButton++;
+ if (currentButton == numEntry) { // if current button is the last, than next button is the first
+ currentButton = 0;
}
+ buttonsNeedRedraw = true;
}
- if (_engine->_keyboard.pressedKey == 0) {
- buttonReleased = true;
+ if (((uint8)_engine->_keyboard.key & 1)) { // on arrow key up
+ debug("pressed up");
+ currentButton--;
+ if (currentButton < 0) { // if current button is the first, than previous button is the last
+ currentButton = maxButton;
+ }
+ buttonsNeedRedraw = true;
}
- if (buttonReleased) {
- _engine->_keyboard.key = _engine->_keyboard.pressedKey;
+ // if its a volume button
+ if (menuSettings == VolumeMenuState) {
+ const int16 id = *(&menuSettings[MenuSettings_FirstButtonState] + currentButton * 2); // get button parameters from settings array
- if (((uint8)_engine->_keyboard.key & 2)) { // on arrow key down
- debug("pressed down");
- currentButton++;
- if (currentButton == numEntry) { // if current button is the last, than next button is the first
- currentButton = 0;
+ Audio::Mixer *mixer = _engine->_system->getMixer();
+ switch (id) {
+ case kMusicVolume: {
+ int volume = mixer->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
+ if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ volume -= 4;
+ }
+ if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ volume += 4;
}
- buttonNeedRedraw = true;
- buttonReleased = false;
+ _engine->_music->musicVolume(volume);
+ break;
}
-
- if (((uint8)_engine->_keyboard.key & 1)) { // on arrow key up
- debug("pressed up");
- currentButton--;
- if (currentButton < 0) { // if current button is the first, than previous button is the last
- currentButton = maxButton;
+ case kSoundVolume: {
+ int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
+ if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ volume -= 4;
}
- buttonNeedRedraw = true;
- buttonReleased = false;
+ if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ volume += 4;
+ }
+ mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
+ break;
}
-
- // if its a volume button
- if (menuSettings == VolumeMenuState) {
- const int16 id = *(&menuSettings[MenuSettings_FirstButtonState] + currentButton * 2); // get button parameters from settings array
-
- Audio::Mixer *mixer = _engine->_system->getMixer();
- switch (id) {
- case kMusicVolume: {
- int volume = mixer->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
- volume -= 4;
- }
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
- volume += 4;
- }
- _engine->_music->musicVolume(volume);
- break;
+ case kCDVolume: {
+ AudioCDManager::Status status = _engine->_system->getAudioCDManager()->getStatus();
+ if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ status.volume -= 4;
}
- case kSoundVolume: {
- int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
- volume -= 4;
- }
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
- volume += 4;
- }
- mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
- break;
+ if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ status.volume += 4;
}
- case kCDVolume: {
- AudioCDManager::Status status = _engine->_system->getAudioCDManager()->getStatus();
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
- status.volume -= 4;
- }
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
- status.volume += 4;
- }
- _engine->_system->getAudioCDManager()->setVolume(status.volume);
- break;
+ _engine->_system->getAudioCDManager()->setVolume(status.volume);
+ break;
+ }
+ case kLineVolume: {
+ int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
+ if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ volume -= 4;
}
- case kLineVolume: {
- int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
- volume -= 4;
- }
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
- volume += 4;
- }
- mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
- break;
+ if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ volume += 4;
}
- case kMasterVolume: {
- int volume = mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
- volume -= 4;
- }
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
- volume += 4;
- }
- mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
- break;
+ mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
+ break;
+ }
+ case kMasterVolume: {
+ int volume = mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
+ if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ volume -= 4;
}
- default:
- break;
+ if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ volume += 4;
}
+ mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
+ break;
+ }
+ default:
+ break;
}
}
- if (buttonNeedRedraw) {
+ if (buttonsNeedRedraw) {
menuSettings[MenuSettings_CurrentLoadedButton] = currentButton;
// draw all buttons
drawButton(menuSettings, false);
- do {
- _engine->readKeys();
- // draw plasma effect for the current selected button
- // .. until a key was pressed
- drawButton(menuSettings, true);
- } while (_engine->_keyboard.pressedKey == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.internalKeyCode == 0);
- buttonNeedRedraw = false;
- } else {
- if (musicChanged) {
- // TODO: update volume settings
- }
+ buttonsNeedRedraw = false;
+ }
- drawButton(menuSettings, true);
- _engine->readKeys();
- // WARNING: this is here to prevent a fade bug while quit the menu
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ // draw plasma effect for the current selected button
+ drawButton(menuSettings, true);
+ if (musicChanged) {
+ // TODO: update volume settings
}
} while (!(_engine->_keyboard.skippedKey & 2) && !(_engine->_keyboard.skippedKey & 1));
@@ -576,6 +545,7 @@ int32 Menu::advoptionsMenu() {
int32 ret = 0;
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
do {
switch (processMenu(AdvOptionsMenuState)) {
@@ -589,9 +559,6 @@ int32 Menu::advoptionsMenu() {
}
} while (ret != 1);
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
-
return 0;
}
@@ -599,6 +566,7 @@ int32 Menu::savemanageMenu() {
int32 ret = 0;
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
do {
switch (processMenu(SaveManageMenuState)) {
@@ -612,9 +580,6 @@ int32 Menu::savemanageMenu() {
}
} while (ret != 1);
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
-
return 0;
}
@@ -622,6 +587,7 @@ int32 Menu::volumeMenu() {
int32 ret = 0;
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
do {
switch (processMenu(VolumeMenuState)) {
@@ -635,9 +601,6 @@ int32 Menu::volumeMenu() {
}
} while (ret != 1);
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
-
return 0;
}
@@ -645,6 +608,7 @@ int32 Menu::optionsMenu() {
int32 ret = 0;
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
_engine->_sound->stopSamples();
//_engine->_music->playCDtrack(9);
@@ -657,20 +621,14 @@ int32 Menu::optionsMenu() {
break;
}
case kVolume: {
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
volumeMenu();
break;
}
case kSaveManage: {
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
savemanageMenu();
break;
}
case kAdvanced: {
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
advoptionsMenu();
break;
}
@@ -679,9 +637,6 @@ int32 Menu::optionsMenu() {
}
} while (ret != 1);
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
-
return 0;
}
@@ -708,8 +663,6 @@ void Menu::run() {
break;
}
case kOptions: {
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
OptionsMenuState[MenuSettings_FirstButton] = kReturnMenu;
optionsMenu();
break;
@@ -729,7 +682,6 @@ void Menu::run() {
}
int32 Menu::giveupMenu() {
-
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
_engine->_sound->pauseSamples();
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 592c51d895..15f42fcd39 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -152,112 +152,53 @@ void MenuOptions::drawSelectableCharacter(int32 x, int32 y, int32 arg) {
}
void MenuOptions::drawSelectableCharacters() {
- int8 x, y;
-
- for (x = 0; x < 5; x++) {
- for (y = 0; y < 14; y++) {
+ for (int8 x = 0; x < 5; x++) {
+ for (int8 y = 0; y < 14; y++) {
drawSelectableCharacter(x, y, 0);
}
}
}
// 0001F18C
-void MenuOptions::drawPlayerName(int32 centerx, int32 top, const char * /*playerName*/, int32 type) {
- /*
- int v4; // ebp at 0
- int v6; // [sp+0h] [bp-14h]@0
- int v7; // [sp+0h] [bp-14h]@4
- int v8; // [sp+4h] [bp-10h]@0
- int v9; // [sp+4h] [bp-10h]@4
-
- LOWORD(v8) = a1 - buttonDrawVar1 / 2;
- if ( !a4 )
- {
- v6 = (signed __int16)(a2 + 25);
- blitRectangle(v4);
- drawBoxInsideTrans(v4);
- }
- if ( a4 == 1 )
- {
- makeFireEffect(v4);
- if ( !(rand(v6, v8) % 5) )
- *(_BYTE *)(10 * rand(v7, v9) % 320 + bufSpeak + 6400) = -1;
- }
- if ( a4 == 2 )
- Box(v4);
- DrawCadre();
- CoulFont(0xFu);
- SizeFont(a3);
- Font(v4);
- return CopyBlockPhys(v4);
- */
-
- // TODO: implement the other types (don't seam to be used)
- /*if (type == 1) {
- processPlasmaEffect(top, 1);
+void MenuOptions::drawPlayerName(int32 centerx, int32 top, int32 type) {
+ if (type == 1) {
+ _engine->_menu->processPlasmaEffect(top, 1);
}
- drawBox(x, top, dialTextBoxRight, dialTextBoxBottom);
- drawTransparentBox(dialTextBoxLeft + 1, dialTextBoxTop + 1, dialTextBoxRight - 1, dialTextBoxBottom - 1, 3);
+ const int left = _engine->_text->dialTextBoxLeft;
+ const int right = _engine->_text->dialTextBoxRight;
+ const int bottom = _engine->_text->dialTextBoxBottom;
+ _engine->_menu->drawBox(left, top, right, bottom);
+ _engine->_interface->drawTransparentBox(left + 1, top + 1, right - 1, bottom - 1, 3);
- setFontColor(15);
- drawText(centerX - getTextSize(playerName) / 2, top, playerName);
+ _engine->_text->drawText(centerx - _engine->_text->getTextSize(playerName) / 2, top, playerName);
- copyBlockPhys(x, y, x + 320, y + 25);*/
+ _engine->copyBlockPhys(left, top, right, bottom);
}
int32 MenuOptions::enterPlayerName(int32 textIdx) {
- char buffer[256];
-
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
+ playerName[0] = '\0'; // TODO: read from settings?
while (1) {
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip(); //frontVideoBuffer
_engine->_text->initTextBank(0);
+ char buffer[256];
_engine->_text->getMenuText(textIdx, buffer, sizeof(buffer));
_engine->_text->setFontColor(15);
- _engine->_text->drawText(320 - (_engine->_text->getTextSize(buffer) / 2), 20, buffer);
- _engine->copyBlockPhys(0, 0, 639, 99);
- playerName[0] = enterPlayerNameVar1;
- drawPlayerName(320, 100, playerName, 1);
+ const int halfScreenWidth = (SCREEN_WIDTH / 2);
+ _engine->_text->drawText(halfScreenWidth - (_engine->_text->getTextSize(buffer) / 2), 20, buffer);
+ _engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99);
+ drawPlayerName(halfScreenWidth, 100, 1);
drawSelectableCharacters();
do {
_engine->readKeys();
- do {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
- break;
- }
- } while (_engine->_keyboard.internalKeyCode);
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.skippedKey);
-
- enterPlayerNameVar2 = 1;
-
- do {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
- break;
- }
- } while (_engine->_keyboard.pressedKey);
-
- while (!_engine->_keyboard.internalKeyCode) {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
- break;
- }
- // TODO
- drawPlayerName(320, 100, playerName, 1);
- }
-
- // FIXME: remove this lines after implementing everything
- if (_engine->_keyboard.internalKeyCode)
- break;
+ } while (_engine->_keyboard.hitEnter());
}
- enterPlayerNameVar2 = 0;
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
_engine->flip();
diff --git a/engines/twine/menuoptions.h b/engines/twine/menuoptions.h
index cb48efb194..a0dcb0bb5e 100644
--- a/engines/twine/menuoptions.h
+++ b/engines/twine/menuoptions.h
@@ -34,7 +34,7 @@ private:
int32 enterPlayerName(int32 textIdx);
void drawSelectableCharacters();
- void drawPlayerName(int32 centerx, int32 top, const char *playerName, int32 type);
+ void drawPlayerName(int32 centerx, int32 top, int32 type);
void drawSelectableCharacter(int32 x, int32 y, int32 arg);
void showCredits();
void newGame();
@@ -45,8 +45,6 @@ public:
int32 canShowCredits = 0;
char playerName[256] = "";
- int8 enterPlayerNameVar1 = 0;
- int32 enterPlayerNameVar2 = 0;
/** Main menu new game options */
void newGameMenu();
diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index 7e444e61d5..5589531b12 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -15,6 +15,7 @@ MODULE_OBJS := \
holomap.o \
hqrdepack.o \
interface.o \
+ input.o \
menu.o \
menuoptions.o \
metaengine.o \
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 131fc97aa5..3c0459f454 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -243,6 +243,7 @@ void TwinEEngine::initEngine() {
// Check if LBA CD-Rom is on drive
_music->initCdrom();
+#if 0
// Display company logo
_screens->adelineLogo();
@@ -263,6 +264,7 @@ void TwinEEngine::initEngine() {
}
_flaMovies->playFlaMovie(FLA_DRAGON3);
+#endif
_screens->loadMenuImage();
}
@@ -902,71 +904,7 @@ static const struct KeyProperties {
static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
void TwinEEngine::readKeys() {
- if (shouldQuit()) {
- _keyboard.internalKeyCode = 1;
- _keyboard.skippedKey = 1;
- return;
- }
- _keyboard.skippedKey = 0;
- _keyboard.internalKeyCode = 0;
-
- Common::Event event;
- while (g_system->getEventManager()->pollEvent(event)) {
- uint8 localKey = 0;
- switch (event.type) {
- case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
- _keyboard.actionStates[event.customType] = false;
- localKey = twineactions[event.customType].localKey;
- break;
- case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
- if (!cfgfile.Debug) {
- switch (event.customType) {
- case TwinEActionType::NextRoom:
- case TwinEActionType::PreviousRoom:
- case TwinEActionType::ApplyCellingGrid:
- case TwinEActionType::IncreaseCellingGridIndex:
- case TwinEActionType::DecreaseCellingGridIndex:
- break;
- default:
- localKey = twineactions[event.customType].localKey;
- _keyboard.actionStates[event.customType] = true;
- break;
- }
- } else {
- localKey = twineactions[event.customType].localKey;
- _keyboard.actionStates[event.customType] = true;
- }
- break;
- case Common::EVENT_LBUTTONDOWN:
- leftMouse = 1;
- break;
- case Common::EVENT_RBUTTONDOWN:
- rightMouse = 1;
- break;
- default:
- break;
- }
-
- if (localKey == 0) {
- continue;
- }
-
- for (int i = 0; i < ARRAYSIZE(pressedKeyCharMap); i++) {
- if (pressedKeyCharMap[i].key == localKey) {
- if (pressedKeyCharMap[i].pressed) {
- if (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
- _keyboard.pressedKey &= ~pressedKeyCharMap[i].high;
- } else {
- _keyboard.pressedKey |= pressedKeyCharMap[i].high;
- }
- } else {
- _keyboard.skippedKey |= pressedKeyCharMap[i].high;
- }
- break;
- }
- }
- _keyboard.internalKeyCode = localKey;
- }
+ _keyboard.readKeys();
}
void TwinEEngine::drawText(int32 x, int32 y, const char *string, int32 center) {
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 0c0051a79c..88b059e284 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -225,9 +225,6 @@ public:
int32 quitGame = 0;
int32 lbaTime = 0;
- int16 leftMouse = 0;
- int16 rightMouse = 0;
-
/** Work video buffer */
Graphics::ManagedSurface workVideoBuffer;
/** Main game video buffer */
Commit: c59fd6a32e3edbbe716da1f89ab5a06819348dfe
https://github.com/scummvm/scummvm/commit/c59fd6a32e3edbbe716da1f89ab5a06819348dfe
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: refactored input
Changed paths:
engines/twine/debug.cpp
engines/twine/debug_grid.cpp
engines/twine/flamovies.cpp
engines/twine/gamestate.cpp
engines/twine/input.cpp
engines/twine/input.h
engines/twine/menu.cpp
engines/twine/menuoptions.cpp
engines/twine/metaengine.cpp
engines/twine/movements.cpp
engines/twine/redraw.cpp
engines/twine/script_life.cpp
engines/twine/text.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index de9ffbe519..4481ed34d2 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -420,15 +420,15 @@ void Debug::debugPlasmaWindow(const char *text, int32 color) {
}
void Debug::debugProcessWindow() {
- if (_engine->rightMouse) {
+ if (_engine->_input->rightMouse) {
int32 quit = 0;
const char *text = "Game Debug Window";
int32 color = 64;
int32 colorIdx = 4;
int32 count = 0;
MouseStatusStruct mouseData;
- _engine->rightMouse = 0;
- _engine->leftMouse = 0;
+ _engine->_input->rightMouse = 0;
+ _engine->_input->leftMouse = 0;
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
@@ -442,7 +442,7 @@ void Debug::debugProcessWindow() {
if (_engine->shouldQuit()) {
quit = 1;
}
- _engine->getMousePositions(&mouseData);
+ _engine->_input->getMousePositions(&mouseData);
if (mouseData.left) {
int type = 0;
diff --git a/engines/twine/debug_grid.cpp b/engines/twine/debug_grid.cpp
index aad2c95763..a860775951 100644
--- a/engines/twine/debug_grid.cpp
+++ b/engines/twine/debug_grid.cpp
@@ -23,7 +23,7 @@
#include "twine/debug_grid.h"
#include "common/debug.h"
#include "twine/grid.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/redraw.h"
#include "twine/scene.h"
#include "twine/twine.h"
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index ba68701590..b9908f9141 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -24,7 +24,7 @@
#include "common/file.h"
#include "common/system.h"
#include "twine/grid.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/music.h"
#include "twine/screens.h"
#include "twine/sound.h"
@@ -310,7 +310,7 @@ void FlaMovies::playFlaMovie(const char *flaName) {
break;
}
- if (_engine->_keyboard.isAnyKeyPressed()) {
+ if (_engine->_input->isAnyKeyPressed()) {
break;
}
} while (true);
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 805ae997f8..f7d87ff868 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -32,7 +32,7 @@
#include "twine/extra.h"
#include "twine/grid.h"
#include "twine/interface.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/menu.h"
#include "twine/menuoptions.h"
#include "twine/music.h"
@@ -393,7 +393,7 @@ void GameState::processFoundItem(int32 item) {
_engine->_redraw->flipRedrawAreas();
_engine->readKeys();
- if (_engine->_keyboard.skippedKey) {
+ if (_engine->_input->skippedKey) {
if (!textState) {
quitItem = 1;
}
@@ -408,7 +408,7 @@ void GameState::processFoundItem(int32 item) {
while (_engine->_text->playVoxSimple(_engine->_text->currDialTextEntry)) {
_engine->readKeys();
- if (_engine->_keyboard.internalKeyCode == 1) {
+ if (_engine->_input->internalKeyCode == 1) {
break;
}
_engine->delaySkip(1);
@@ -423,7 +423,7 @@ void GameState::processFoundItem(int32 item) {
break;
}
delaySkip(1);
- } while (!_engine->_keyboard.internalKeyCode);*/
+ } while (!_engine->_input->internalKeyCode);*/
_engine->_text->stopVox(_engine->_text->currDialTextEntry);
@@ -485,7 +485,7 @@ void GameState::processGameoverAnimation() { // makeGameOver
int32 startLbaTime = _engine->lbaTime;
_engine->_interface->setClip(120, 120, 519, 359);
- while (_engine->_keyboard.internalKeyCode != 1 && (_engine->lbaTime - startLbaTime) <= 500) {
+ while (_engine->_input->internalKeyCode != 1 && (_engine->lbaTime - startLbaTime) <= 500) {
_engine->readKeys();
int32 avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
diff --git a/engines/twine/input.cpp b/engines/twine/input.cpp
index 2f5dd0c524..c8ecc79df7 100644
--- a/engines/twine/input.cpp
+++ b/engines/twine/input.cpp
@@ -20,21 +20,59 @@
*
*/
-#ifndef TWINE_KEYBOARD_H
-#define TWINE_KEYBOARD_H
-
#include "twine/input.h"
#include "common/system.h"
+#include "twine/twine.h"
namespace TwinE {
+/** Pressed key char map - scanCodeTab2 */
+static const struct KeyProperties {
+ uint8 high;
+ bool pressed;
+ uint8 key;
+} pressedKeyCharMap[] = {
+ {0x01, false, 0x48}, // up
+ {0x02, false, 0x50}, // down
+ {0x04, false, 0x4B}, // left
+ {0x08, false, 0x4D}, // right
+ {0x05, false, 0x47}, // home
+ {0x09, false, 0x49}, // pageup
+ {0x0A, false, 0x51}, // pagedown
+ {0x06, false, 0x4F}, // end
+ {0x01, true, 0x39}, // space bar
+ {0x02, true, 0x1C}, // enter
+ {0x04, true, 0x1D}, // ctrl
+ {0x08, true, 0x38}, // alt
+ {0x10, true, 0x53}, // del
+ {0x20, true, 0x2A}, // left shift
+ {0x20, true, 0x36}, // right shift
+ {0x01, true, 0x3B}, // F1
+ {0x02, true, 0x3C}, // F2
+ {0x04, true, 0x3D}, // F3
+ {0x08, true, 0x3E}, // F4
+ {0x10, true, 0x3F}, // F5
+ {0x20, true, 0x40}, // F6
+ {0x40, true, 0x41}, // F7
+ {0x80, true, 0x42}, // F8
+ {0x01, true, 0x43}, // F9
+ {0x02, true, 0x44}, // F10
+ {0x04, true, 0x57}, // ?
+ {0x08, true, 0x58}, // ?
+ {0x00, true, 0x2A}, // left shift
+ {0x00, true, 0x00},
+ {0x01, false, 0x01}, // esc
+ {0x00, false, 0x00}};
+static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
+
Input::Input(TwinEEngine *engine) : _engine(engine) {}
bool Input::isAnyKeyPressed() const {
return internalKeyCode != 0;
}
-bool Input::isPressed(Common::KeyCode keycode) {
+bool Input::isPressed(Common::KeyCode keycode) const {
+ return false; // TODO:
}
void Input::readKeys() {
@@ -55,7 +93,7 @@ void Input::readKeys() {
localKey = twineactions[event.customType].localKey;
break;
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
- if (!cfgfile.Debug) {
+ if (!_engine->cfgfile.Debug) {
switch (event.customType) {
case TwinEActionType::NextRoom:
case TwinEActionType::PreviousRoom:
@@ -116,8 +154,15 @@ void Input::readKeys() {
internalKeyCode = localKey;
}
}
-}; // namespace TwinE
-} // namespace TwinE
+void Input::getMousePositions(MouseStatusStruct *mouseData) {
+ Common::Point point = g_system->getEventManager()->getMousePos();
+ mouseData->x = point.x;
+ mouseData->y = point.y;
+ mouseData->left = leftMouse;
+ mouseData->right = rightMouse;
+ leftMouse = 0;
+ rightMouse = 0;
+}
-#endif
+} // namespace TwinE
diff --git a/engines/twine/input.h b/engines/twine/input.h
index 8b995f2f31..28784ddaef 100644
--- a/engines/twine/input.h
+++ b/engines/twine/input.h
@@ -102,11 +102,17 @@ static constexpr const struct ActionMapping {
static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected action mapping array size");
+struct MouseStatusStruct {
+ int32 left = 0;
+ int32 right = 0;
+ int32 x = 0;
+ int32 y = 0;
+};
+
class TwinEEngine;
class Input {
private:
- friend class TwinEEngine;
TwinEEngine *_engine;
bool _hitEnter = false;
@@ -126,7 +132,17 @@ public:
bool isAnyKeyPressed() const;
- bool isPressed(Common::KeyCode keycode);
+ bool isPressed(Common::KeyCode keycode) const;
+
+ inline bool isPressedEnter() const {
+ return isPressed(Common::KEYCODE_RETURN) || isPressed(Common::KEYCODE_KP_ENTER);
+ }
+
+ /**
+ * Gets mouse positions
+ * @param mouseData structure that contains mouse position info
+ */
+ void getMousePositions(MouseStatusStruct *mouseData);
void readKeys();
};
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 965897f2db..8acf1158e1 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -35,7 +35,7 @@
#include "twine/grid.h"
#include "twine/hqrdepack.h"
#include "twine/interface.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/menuoptions.h"
#include "twine/movements.h"
#include "twine/music.h"
@@ -433,9 +433,9 @@ int32 Menu::processMenu(int16 *menuSettings) {
do {
_engine->readKeys();
- _engine->_keyboard.key = _engine->_keyboard.pressedKey;
+ _engine->_input->key = _engine->_input->pressedKey;
- if (_engine->_keyboard.isPressed(Common::KeyCode::KEYCODE_DOWN)) { // on arrow key down
+ if (_engine->_input->isPressed(Common::KeyCode::KEYCODE_DOWN)) { // on arrow key down
debug("pressed down");
currentButton++;
if (currentButton == numEntry) { // if current button is the last, than next button is the first
@@ -444,7 +444,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
buttonsNeedRedraw = true;
}
- if (((uint8)_engine->_keyboard.key & 1)) { // on arrow key up
+ if (((uint8)_engine->_input->key & 1)) { // on arrow key up
debug("pressed up");
currentButton--;
if (currentButton < 0) { // if current button is the first, than previous button is the last
@@ -461,10 +461,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
switch (id) {
case kMusicVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->key & 4)) { // on arrow key left
volume -= 4;
}
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->key & 8)) { // on arrow key right
volume += 4;
}
_engine->_music->musicVolume(volume);
@@ -472,10 +472,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kSoundVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->key & 4)) { // on arrow key left
volume -= 4;
}
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->key & 8)) { // on arrow key right
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
@@ -483,10 +483,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kCDVolume: {
AudioCDManager::Status status = _engine->_system->getAudioCDManager()->getStatus();
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->key & 4)) { // on arrow key left
status.volume -= 4;
}
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->key & 8)) { // on arrow key right
status.volume += 4;
}
_engine->_system->getAudioCDManager()->setVolume(status.volume);
@@ -494,10 +494,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kLineVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->key & 4)) { // on arrow key left
volume -= 4;
}
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->key & 8)) { // on arrow key right
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
@@ -505,10 +505,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kMasterVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
- if (((uint8)_engine->_keyboard.key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->key & 4)) { // on arrow key left
volume -= 4;
}
- if (((uint8)_engine->_keyboard.key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->key & 8)) { // on arrow key right
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
@@ -532,7 +532,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (musicChanged) {
// TODO: update volume settings
}
- } while (!(_engine->_keyboard.skippedKey & 2) && !(_engine->_keyboard.skippedKey & 1));
+ } while (!(_engine->_input->skippedKey & 2) && !(_engine->_input->skippedKey & 1));
currentButton = *(menuSettings + MenuSettings_FirstButton + currentButton * 2); // get current browsed button
@@ -876,16 +876,16 @@ void Menu::processBehaviourMenu() {
int32 tmpTime = _engine->lbaTime;
- while (_engine->_keyboard.skippedKey & 4 || (_engine->_keyboard.internalKeyCode >= twineactions[TwinEActionType::QuickBehaviourNormal].localKey && _engine->_keyboard.internalKeyCode <= twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey)) {
+ while (_engine->_input->skippedKey & 4 || (_engine->_input->internalKeyCode >= twineactions[TwinEActionType::QuickBehaviourNormal].localKey && _engine->_input->internalKeyCode <= twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey)) {
_engine->readKeys();
- _engine->_keyboard.key = _engine->_keyboard.pressedKey;
+ _engine->_input->key = _engine->_input->pressedKey;
int heroBehaviour = (int)_engine->_actor->heroBehaviour;
- if (_engine->_keyboard.key & 8) {
+ if (_engine->_input->key & 8) {
heroBehaviour++;
}
- if (_engine->_keyboard.key & 4) {
+ if (_engine->_input->key & 4) {
heroBehaviour--;
}
@@ -905,7 +905,7 @@ void Menu::processBehaviourMenu() {
_engine->_movements->setActorAngleSafe(_engine->_scene->sceneHero->angle, _engine->_scene->sceneHero->angle - 256, 50, &moveMenu);
_engine->_animations->setAnimAtKeyframe(behaviourAnimState[_engine->_actor->heroBehaviour], _engine->_animations->animTable[_engine->_actor->heroAnimIdx[_engine->_actor->heroBehaviour]], behaviourEntity, &behaviourAnimData[_engine->_actor->heroBehaviour]);
- while (_engine->_keyboard.pressedKey) {
+ while (_engine->_input->pressedKey) {
_engine->readKeys();
if (_engine->shouldQuit()) {
break;
@@ -1002,23 +1002,23 @@ void Menu::processInventoryMenu() {
_engine->_text->setFontCrossColor(4);
_engine->_text->initDialogueBox();
- while (_engine->_keyboard.internalKeyCode != 1) {
+ while (_engine->_input->internalKeyCode != 1) {
_engine->readKeys();
int32 prevSelectedItem = inventorySelectedItem;
if (!di) {
- _engine->_keyboard.key = _engine->_keyboard.pressedKey;
- _engine->loopPressedKey = _engine->_keyboard.skippedKey;
- _engine->loopCurrentKey = _engine->_keyboard.internalKeyCode;
+ _engine->_input->key = _engine->_input->pressedKey;
+ _engine->loopPressedKey = _engine->_input->skippedKey;
+ _engine->loopCurrentKey = _engine->_input->internalKeyCode;
- if (_engine->_keyboard.key != 0 || _engine->_keyboard.skippedKey != 0) {
+ if (_engine->_input->key != 0 || _engine->_input->skippedKey != 0) {
di = 1;
}
} else {
_engine->loopCurrentKey = 0;
- _engine->_keyboard.key = 0;
+ _engine->_input->key = 0;
_engine->loopPressedKey = 0;
- if (!_engine->_keyboard.pressedKey && !_engine->_keyboard.skippedKey) {
+ if (!_engine->_input->pressedKey && !_engine->_input->skippedKey) {
di = 0;
}
}
@@ -1026,7 +1026,7 @@ void Menu::processInventoryMenu() {
if (_engine->loopCurrentKey == 1 || _engine->loopPressedKey & 0x20)
break;
- if (_engine->_keyboard.key & 2) { // down
+ if (_engine->_input->key & 2) { // down
inventorySelectedItem++;
if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
inventorySelectedItem = 0;
@@ -1035,7 +1035,7 @@ void Menu::processInventoryMenu() {
bx = 3;
}
- if (_engine->_keyboard.key & 1) { // up
+ if (_engine->_input->key & 1) { // up
inventorySelectedItem--;
if (inventorySelectedItem < 0) {
inventorySelectedItem = NUM_INVENTORY_ITEMS - 1;
@@ -1044,7 +1044,7 @@ void Menu::processInventoryMenu() {
bx = 3;
}
- if (_engine->_keyboard.key & 4) { // left
+ if (_engine->_input->key & 4) { // left
inventorySelectedItem -= 4;
if (inventorySelectedItem < 0) {
inventorySelectedItem += NUM_INVENTORY_ITEMS;
@@ -1053,7 +1053,7 @@ void Menu::processInventoryMenu() {
bx = 3;
}
- if (_engine->_keyboard.key & 8) { // right
+ if (_engine->_input->key & 8) { // right
inventorySelectedItem += 4;
if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
inventorySelectedItem -= NUM_INVENTORY_ITEMS;
@@ -1113,7 +1113,7 @@ void Menu::processInventoryMenu() {
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
- while (_engine->_keyboard.internalKeyCode != 0 && _engine->_keyboard.skippedKey != 0) {
+ while (_engine->_input->internalKeyCode != 0 && _engine->_input->skippedKey != 0) {
_engine->readKeys();
_engine->_system->delayMillis(1);
_engine->flip(); // TODO: needed?
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 15f42fcd39..f17315a496 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -21,10 +21,11 @@
*/
#include "twine/menuoptions.h"
+#include "common/keyboard.h"
#include "twine/flamovies.h"
#include "twine/gamestate.h"
#include "twine/interface.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/menu.h"
#include "twine/music.h"
#include "twine/resources.h"
@@ -63,13 +64,13 @@ void MenuOptions::newGame() {
_engine->_text->drawTextFullscreen(150);
_engine->readKeys();
- if (_engine->_keyboard.internalKeyCode != 1) {
+ if (_engine->_input->internalKeyCode != 1) {
// intro screen 1 - twinsun
_engine->_screens->loadImage(RESSHQR_INTROSCREEN2IMG);
_engine->_text->drawTextFullscreen(151);
_engine->readKeys();
- if (_engine->_keyboard.internalKeyCode != 1) {
+ if (_engine->_input->internalKeyCode != 1) {
_engine->_screens->loadImage(RESSHQR_INTROSCREEN3IMG);
_engine->_text->drawTextFullscreen(152);
}
@@ -196,7 +197,7 @@ int32 MenuOptions::enterPlayerName(int32 textIdx) {
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.hitEnter());
+ } while (_engine->_input->isPressedEnter());
}
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
@@ -224,11 +225,11 @@ void MenuOptions::newGameMenu() {
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.skippedKey != 0);
+ } while (_engine->_input->skippedKey != 0);
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.internalKeyCode != 0);
+ } while (_engine->_input->internalKeyCode != 0);
}
}
@@ -262,11 +263,11 @@ void MenuOptions::continueGameMenu() {
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.skippedKey != 0);
+ } while (_engine->_input->skippedKey != 0);
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_keyboard.internalKeyCode != 0);
+ } while (_engine->_input->internalKeyCode != 0);
}
}
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index 7772e08785..d504ad8f85 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -29,7 +29,7 @@
#include "common/translation.h"
#include "engines/advancedDetector.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/twine.h"
namespace TwinE {
diff --git a/engines/twine/movements.cpp b/engines/twine/movements.cpp
index b7eef19740..7097b37e04 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/movements.cpp
@@ -27,7 +27,7 @@
#include "twine/collision.h"
#include "twine/gamestate.h"
#include "twine/grid.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/renderer.h"
#include "twine/scene.h"
#include "twine/twine.h"
@@ -270,15 +270,15 @@ void Movements::processActorMovements(int32 actorIdx) {
if (actor->controlMode != 1)
return;
- if (_engine->_keyboard.key & 4)
+ if (_engine->_input->key & 4)
tempAngle = 0x100;
- if (_engine->_keyboard.key & 8)
+ if (_engine->_input->key & 8)
tempAngle = -0x100;
moveActor(actor->angle, actor->angle + tempAngle, actor->speed, &actor->move);
- _engine->_keyboard.heroPressedKey = _engine->_keyboard.key;
+ _engine->_input->heroPressedKey = _engine->_input->key;
} else {
int16 tempAngle;
@@ -296,7 +296,7 @@ void Movements::processActorMovements(int32 actorIdx) {
heroAction = 0;
// If press W for action
- if (_engine->_keyboard.internalKeyCode == 0x11) {
+ if (_engine->_input->internalKeyCode == 0x11) {
heroAction = 1;
}
@@ -333,15 +333,15 @@ void Movements::processActorMovements(int32 actorIdx) {
}
}
} else {
- if (_engine->_keyboard.key & 8) {
+ if (_engine->_input->key & 8) {
_engine->_animations->initAnim(kRightPunch, 1, 0, actorIdx);
}
- if (_engine->_keyboard.key & 4) {
+ if (_engine->_input->key & 4) {
_engine->_animations->initAnim(kLeftPunch, 1, 0, actorIdx);
}
- if (_engine->_keyboard.key & 1) {
+ if (_engine->_input->key & 1) {
_engine->_animations->initAnim(kKick, 1, 0, actorIdx);
}
}
@@ -383,11 +383,11 @@ void Movements::processActorMovements(int32 actorIdx) {
if (!_engine->loopPressedKey || heroAction) {
- if (_engine->_keyboard.key & 3) { // if continue walking
+ if (_engine->_input->key & 3) { // if continue walking
heroMoved = 0; // don't break animation
}
- if (_engine->_keyboard.key != _engine->_keyboard.heroPressedKey || _engine->loopPressedKey != _engine->_keyboard.heroPressedKey2) {
+ if (_engine->_input->key != _engine->_input->heroPressedKey || _engine->loopPressedKey != _engine->_input->heroPressedKey2) {
if (heroMoved) {
_engine->_animations->initAnim(kStanding, 0, 255, actorIdx);
}
@@ -395,19 +395,19 @@ void Movements::processActorMovements(int32 actorIdx) {
heroMoved = 0;
- if (_engine->_keyboard.key & 1) { // walk forward
+ if (_engine->_input->key & 1) { // walk forward
if (!_engine->_scene->currentActorInZone) {
_engine->_animations->initAnim(kForward, 0, 255, actorIdx);
}
heroMoved = 1;
}
- if (_engine->_keyboard.key & 2 && !(_engine->_keyboard.key & 1)) { // walk backward
+ if (_engine->_input->key & 2 && !(_engine->_input->key & 1)) { // walk backward
_engine->_animations->initAnim(kBackward, 0, 255, actorIdx);
heroMoved = 1;
}
- if (_engine->_keyboard.key & 4) { // turn left
+ if (_engine->_input->key & 4) { // turn left
heroMoved = 1;
if (actor->anim == 0) {
_engine->_animations->initAnim(kTurnLeft, 0, 255, actorIdx);
@@ -418,7 +418,7 @@ void Movements::processActorMovements(int32 actorIdx) {
}
}
- if (_engine->_keyboard.key & 8) { // turn right
+ if (_engine->_input->key & 8) { // turn right
heroMoved = 1;
if (actor->anim == 0) {
_engine->_animations->initAnim(kTurnRight, 0, 255, actorIdx);
@@ -432,18 +432,18 @@ void Movements::processActorMovements(int32 actorIdx) {
tempAngle = 0;
- if (_engine->_keyboard.key & 4) {
+ if (_engine->_input->key & 4) {
tempAngle = 0x100;
}
- if (_engine->_keyboard.key & 8) {
+ if (_engine->_input->key & 8) {
tempAngle = -0x100;
}
moveActor(actor->angle, actor->angle + tempAngle, actor->speed, &actor->move);
- _engine->_keyboard.heroPressedKey = _engine->_keyboard.key;
- _engine->_keyboard.heroPressedKey2 = _engine->loopPressedKey;
+ _engine->_input->heroPressedKey = _engine->_input->key;
+ _engine->_input->heroPressedKey2 = _engine->loopPressedKey;
break;
case kFollow: {
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 45bea9db7f..3f6a18dc5b 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -29,7 +29,7 @@
#include "twine/grid.h"
#include "twine/hqrdepack.h"
#include "twine/interface.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/menu.h"
#include "twine/movements.h"
#include "twine/renderer.h"
@@ -534,7 +534,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
}
if (_engine->cfgfile.Debug) {
- _engine->_debugScene->displayZones(_engine->_keyboard.internalKeyCode);
+ _engine->_debugScene->displayZones(_engine->_input->internalKeyCode);
}
for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
diff --git a/engines/twine/script_life.cpp b/engines/twine/script_life.cpp
index a7c00ca898..4a159a3605 100644
--- a/engines/twine/script_life.cpp
+++ b/engines/twine/script_life.cpp
@@ -28,7 +28,7 @@
#include "twine/grid.h"
#include "twine/holomap.h"
#include "twine/interface.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/movements.h"
#include "twine/music.h"
#include "twine/redraw.h"
@@ -1362,7 +1362,7 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, int32 actorIdx, ActorStruct *
do {
engine->readKeys();
- } while (engine->_keyboard.internalKeyCode || engine->_keyboard.skippedKey);
+ } while (engine->_input->internalKeyCode || engine->_input->skippedKey);
engine->unfreezeTime();
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index ae96deaa40..11d7fc8637 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -26,7 +26,7 @@
#include "common/system.h"
#include "twine/hqrdepack.h"
#include "twine/interface.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/menu.h"
#include "twine/renderer.h"
#include "twine/resources.h"
@@ -620,7 +620,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
if (_engine->shouldQuit()) {
break;
}
- if (_engine->_keyboard.internalKeyCode == 0 && _engine->_keyboard.skippedKey == 0 && _engine->_keyboard.pressedKey == 0) {
+ if (_engine->_input->internalKeyCode == 0 && _engine->_input->skippedKey == 0 && _engine->_input->pressedKey == 0) {
break;
}
playVox(currDialTextEntry);
@@ -632,7 +632,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
if (_engine->shouldQuit()) {
break;
}
- if (_engine->_keyboard.internalKeyCode != 0 || _engine->_keyboard.skippedKey != 0 || _engine->_keyboard.pressedKey != 0) {
+ if (_engine->_input->internalKeyCode != 0 || _engine->_input->skippedKey != 0 || _engine->_input->pressedKey != 0) {
break;
}
playVox(currDialTextEntry);
@@ -640,7 +640,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
} while (1);
}
- if (_engine->_keyboard.internalKeyCode == 1) {
+ if (_engine->_input->internalKeyCode == 1) {
skipText = 1;
}
@@ -678,17 +678,17 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (_engine->_keyboard.internalKeyCode || _engine->_keyboard.skippedKey || _engine->_keyboard.pressedKey);
+ } while (_engine->_input->internalKeyCode || _engine->_input->skippedKey || _engine->_input->pressedKey);
// RECHECK this later
// wait key to display next text
do {
_engine->readKeys();
- if (_engine->_keyboard.internalKeyCode != 0) {
+ if (_engine->_input->internalKeyCode != 0) {
_engine->_interface->loadClip();
return;
}
- if (_engine->_keyboard.skippedKey != 0) {
+ if (_engine->_input->skippedKey != 0) {
_engine->_interface->loadClip();
return;
}
@@ -696,9 +696,9 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (!_engine->_keyboard.pressedKey);
+ } while (!_engine->_input->pressedKey);
} else { // RECHECK THIS
- while (playVox(currDialTextEntry) && _engine->_keyboard.internalKeyCode != 1) {
+ while (playVox(currDialTextEntry) && _engine->_input->internalKeyCode != 1) {
if (_engine->shouldQuit()) {
break;
}
@@ -848,7 +848,7 @@ void Text::drawAskQuestion(int32 index) { // MyDial
}
playVox(currDialTextEntry);
_engine->_system->delayMillis(1);
- } while (_engine->_keyboard.internalKeyCode || _engine->_keyboard.skippedKey || _engine->_keyboard.pressedKey);
+ } while (_engine->_input->internalKeyCode || _engine->_input->skippedKey || _engine->_input->pressedKey);
do {
_engine->readKeys();
@@ -857,7 +857,7 @@ void Text::drawAskQuestion(int32 index) { // MyDial
}
playVox(currDialTextEntry);
_engine->_system->delayMillis(1);
- } while (!_engine->_keyboard.internalKeyCode && !_engine->_keyboard.skippedKey && !_engine->_keyboard.pressedKey);
+ } while (!_engine->_input->internalKeyCode && !_engine->_input->skippedKey && !_engine->_input->pressedKey);
}
_engine->_system->delayMillis(1);
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 3c0459f454..f33c55698b 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -48,7 +48,7 @@
#include "twine/holomap.h"
#include "twine/hqrdepack.h"
#include "twine/interface.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
#include "twine/menu.h"
#include "twine/menuoptions.h"
#include "twine/movements.h"
@@ -92,6 +92,7 @@ TwinEEngine::TwinEEngine(OSystem *system, Common::Language language, uint32 flag
_sound = new Sound(this);
_text = new Text(this);
_debugGrid = new DebugGrid(this);
+ _input = new Input(this);
_debug = new Debug(this);
_debugScene = new DebugScene(this);
}
@@ -120,6 +121,7 @@ TwinEEngine::~TwinEEngine() {
delete _sound;
delete _text;
delete _debugGrid;
+ delete _input;
delete _debug;
delete _debugScene;
}
@@ -328,26 +330,26 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
previousLoopPressedKey = loopPressedKey;
- _keyboard.key = _keyboard.pressedKey;
- loopPressedKey = _keyboard.skippedKey;
- loopCurrentKey = _keyboard.internalKeyCode;
+ _input->key = _input->pressedKey;
+ loopPressedKey = _input->skippedKey;
+ loopCurrentKey = _input->internalKeyCode;
_debug->processDebug(loopCurrentKey);
if (_menuOptions->canShowCredits != 0) {
// TODO: if current music playing != 8, than play_track(8);
- if (_keyboard.internalKeyCode != 0) {
+ if (_input->internalKeyCode != 0) {
return 0;
}
- if (_keyboard.pressedKey != 0) {
+ if (_input->pressedKey != 0) {
return 0;
}
- if (_keyboard.skippedKey != 0) {
+ if (_input->skippedKey != 0) {
return 0;
}
} else {
// Process give up menu - Press ESC
- if (_keyboard.internalKeyCode == 1 && _scene->sceneHero->life > 0 && _scene->sceneHero->entity != -1 && !_scene->sceneHero->staticFlags.bIsHidden) {
+ if (_input->internalKeyCode == 1 && _scene->sceneHero->life > 0 && _scene->sceneHero->entity != -1 && !_scene->sceneHero->staticFlags.bIsHidden) {
freezeTime();
if (_menu->giveupMenu()) {
unfreezeTime();
@@ -552,7 +554,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
break;
}
g_system->delayMillis(10);
- } while (_keyboard.internalKeyCode != 0x19 && !_keyboard.pressedKey);
+ } while (_input->internalKeyCode != 0x19 && !_input->pressedKey);
unfreezeTime();
_redraw->redrawEngineActions(1);
}
@@ -778,10 +780,10 @@ bool TwinEEngine::gameEngineLoop() { // mainLoop
void TwinEEngine::delaySkip(uint32 time) {
uint32 startTicks = _system->getMillis();
uint32 stopTicks = 0;
- _keyboard.internalKeyCode = 0;
+ _input->internalKeyCode = 0;
do {
readKeys();
- if (_keyboard.internalKeyCode == 1) {
+ if (_input->internalKeyCode == 1) {
break;
}
if (shouldQuit()) {
@@ -864,47 +866,8 @@ void TwinEEngine::crossFade(const Graphics::ManagedSurface &buffer, const uint32
surfaceTable.free();
}
-/** Pressed key char map - scanCodeTab2 */
-static const struct KeyProperties {
- uint8 high;
- bool pressed;
- uint8 key;
-} pressedKeyCharMap[] = {
- {0x01, false, 0x48}, // up
- {0x02, false, 0x50}, // down
- {0x04, false, 0x4B}, // left
- {0x08, false, 0x4D}, // right
- {0x05, false, 0x47}, // home
- {0x09, false, 0x49}, // pageup
- {0x0A, false, 0x51}, // pagedown
- {0x06, false, 0x4F}, // end
- {0x01, true, 0x39}, // space bar
- {0x02, true, 0x1C}, // enter
- {0x04, true, 0x1D}, // ctrl
- {0x08, true, 0x38}, // alt
- {0x10, true, 0x53}, // del
- {0x20, true, 0x2A}, // left shift
- {0x20, true, 0x36}, // right shift
- {0x01, true, 0x3B}, // F1
- {0x02, true, 0x3C}, // F2
- {0x04, true, 0x3D}, // F3
- {0x08, true, 0x3E}, // F4
- {0x10, true, 0x3F}, // F5
- {0x20, true, 0x40}, // F6
- {0x40, true, 0x41}, // F7
- {0x80, true, 0x42}, // F8
- {0x01, true, 0x43}, // F9
- {0x02, true, 0x44}, // F10
- {0x04, true, 0x57}, // ?
- {0x08, true, 0x58}, // ?
- {0x00, true, 0x2A}, // left shift
- {0x00, true, 0x00},
- {0x01, false, 0x01}, // esc
- {0x00, false, 0x00}};
-static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
-
void TwinEEngine::readKeys() {
- _keyboard.readKeys();
+ _input->readKeys();
}
void TwinEEngine::drawText(int32 x, int32 y, const char *string, int32 center) {
@@ -928,14 +891,4 @@ void TwinEEngine::drawText(int32 x, int32 y, const char *string, int32 center) {
#endif
}
-void TwinEEngine::getMousePositions(MouseStatusStruct *mouseData) {
- Common::Point point = g_system->getEventManager()->getMousePos();
- mouseData->x = point.x;
- mouseData->y = point.y;
- mouseData->left = leftMouse;
- mouseData->right = rightMouse;
- leftMouse = 0;
- rightMouse = 0;
-}
-
} // namespace TwinE
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 88b059e284..3505e0444b 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -31,7 +31,7 @@
#include "graphics/pixelformat.h"
#include "graphics/surface.h"
#include "twine/actor.h"
-#include "twine/keyboard.h"
+#include "twine/input.h"
namespace TwinE {
@@ -122,13 +122,6 @@ struct ConfigFile {
int32 WallCollision = 0;
};
-struct MouseStatusStruct {
- int32 left = 0;
- int32 right = 0;
- int32 x = 0;
- int32 y = 0;
-};
-
class Actor;
class Animations;
class Collision;
@@ -194,7 +187,7 @@ public:
Sound *_sound;
Text *_text;
DebugGrid *_debugGrid;
- Keyboard _keyboard;
+ Input *_input;
Debug *_debug;
DebugScene *_debugScene;
@@ -298,12 +291,6 @@ public:
* @param center if the text should be centered accoding with the giving positions
*/
void drawText(int32 x, int32 y, const char *string, int32 center);
-
- /**
- * Gets mouse positions
- * @param mouseData structure that contains mouse position info
- */
- void getMousePositions(MouseStatusStruct *mouseData);
};
} // namespace TwinE
Commit: d417478b8ca59f9152494c82ff1da455f487cbbe
https://github.com/scummvm/scummvm/commit/d417478b8ca59f9152494c82ff1da455f487cbbe
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: started to split keymaps for ui, game and cutscenes
Changed paths:
engines/twine/debug.cpp
engines/twine/flamovies.cpp
engines/twine/input.cpp
engines/twine/input.h
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/menuoptions.cpp
engines/twine/menuoptions.h
engines/twine/metaengine.cpp
engines/twine/redraw.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 4481ed34d2..9964f3f2c6 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -409,7 +409,7 @@ int32 Debug::debugProcessButton(int32 X, int32 Y) {
void Debug::debugPlasmaWindow(const char *text, int32 color) {
int32 textSize;
- _engine->_menu->processPlasmaEffect(5, color);
+ _engine->_menu->processPlasmaEffect(0, 5, SCREEN_WIDTH, color);
if (!(_engine->getRandomNumber() % 5)) {
_engine->_menu->plasmaEffectPtr[_engine->getRandomNumber() % 320 * 10 + 6400] = 255;
}
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index b9908f9141..7b0160bb70 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -274,7 +274,13 @@ void FlaMovies::playFlaMovie(const char *flaName) {
if (!strcmp((const char *)flaHeaderData.version, "V1.3")) {
int32 currentFrame = 0;
+ ScopedKeyMap scopedKeyMap(_engine, cutsceneKeyMapId);
+
do {
+ _engine->readKeys();
+ if (_engine->shouldQuit()) {
+ break;
+ }
if (currentFrame == flaHeaderData.numOfFrames) {
break;
}
@@ -303,17 +309,7 @@ void FlaMovies::playFlaMovie(const char *flaName) {
currentFrame++;
_engine->_system->delayMillis(1000 / flaHeaderData.speed + 1);
-
- _engine->readKeys();
-
- if (_engine->shouldQuit()) {
- break;
- }
-
- if (_engine->_input->isAnyKeyPressed()) {
- break;
- }
- } while (true);
+ } while (!_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
}
if (_engine->cfgfile.CrossFade) {
diff --git a/engines/twine/input.cpp b/engines/twine/input.cpp
index c8ecc79df7..cdeb91c3aa 100644
--- a/engines/twine/input.cpp
+++ b/engines/twine/input.cpp
@@ -21,11 +21,19 @@
*/
#include "twine/input.h"
+#include "backends/keymapper/keymapper.h"
+#include "common/events.h"
+#include "common/keyboard.h"
#include "common/system.h"
+#include "twine/actor.h"
#include "twine/twine.h"
namespace TwinE {
+const char *mainKeyMapId = "mainKeyMap";
+const char *uiKeyMapId = "uiKeyMap";
+const char *cutsceneKeyMapId = "cutsceneKeyMap";
+
/** Pressed key char map - scanCodeTab2 */
static const struct KeyProperties {
uint8 high;
@@ -65,22 +73,62 @@ static const struct KeyProperties {
{0x00, false, 0x00}};
static_assert(ARRAYSIZE(pressedKeyCharMap) == 31, "Expected size of key char map");
+ScopedKeyMapperDisable::ScopedKeyMapperDisable() {
+ g_system->getEventManager()->getKeymapper()->setEnabled(false);
+}
+
+ScopedKeyMapperDisable::~ScopedKeyMapperDisable() {
+ g_system->getEventManager()->getKeymapper()->setEnabled(true);
+}
+
+ScopedKeyMap::ScopedKeyMap(TwinEEngine* engine, const char *id) : _engine(engine) {
+ _prevKeyMap = _engine->_input->currentKeyMap();
+ _engine->_input->enabledKeyMap(cutsceneKeyMapId);
+}
+
+ScopedKeyMap::~ScopedKeyMap() {
+ _engine->_input->enabledKeyMap(_prevKeyMap.c_str());
+}
+
Input::Input(TwinEEngine *engine) : _engine(engine) {}
-bool Input::isAnyKeyPressed() const {
- return internalKeyCode != 0;
+bool Input::isPressed(Common::KeyCode keycode, bool onlyFirstTime) const {
+ if (onlyFirstTime) {
+ return _pressed[keycode] == 1;
+ }
+ return _pressed[keycode] > 0;
}
-bool Input::isPressed(Common::KeyCode keycode) const {
- return false; // TODO:
+bool Input::isActionActive(TwinEActionType actionType, bool onlyFirstTime) const {
+ if (onlyFirstTime) {
+ return actionStates[actionType] == 1;
+ }
+ return actionStates[actionType] > 0;
}
-void Input::readKeys() {
- if (_engine->shouldQuit()) {
- internalKeyCode = 1;
- skippedKey = 1;
- return;
+bool Input::toggleActionIfActive(TwinEActionType actionType) {
+ if (actionStates[actionType] > 0) {
+ actionStates[actionType] = 0;
+ return true;
}
+ return false;
+}
+
+bool Input::isQuickBehaviourActionActive() const {
+ return isActionActive(TwinEActionType::QuickBehaviourNormal) || isActionActive(TwinEActionType::QuickBehaviourAthletic) || isActionActive(TwinEActionType::QuickBehaviourAggressive) || isActionActive(TwinEActionType::QuickBehaviourDiscreet);
+}
+
+void Input::enabledKeyMap(const char *id) {
+ Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
+ const Common::KeymapArray &keymaps = keymapper->getKeymaps();
+ for (Common::Keymap *keymap : keymaps) {
+ keymap->setEnabled(keymap->getId() == id);
+ }
+ _currentKeyMap = id;
+}
+
+void Input::readKeys() {
+ ++_tickCounter;
skippedKey = 0;
internalKeyCode = 0;
@@ -89,7 +137,7 @@ void Input::readKeys() {
uint8 localKey = 0;
switch (event.type) {
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
- actionStates[event.customType] = false;
+ actionStates[event.customType] = 0;
localKey = twineactions[event.customType].localKey;
break;
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
@@ -103,29 +151,25 @@ void Input::readKeys() {
break;
default:
localKey = twineactions[event.customType].localKey;
- actionStates[event.customType] = true;
+ debug("repeat: %i", event.kbdRepeat);
+ actionStates[event.customType] = 1 + event.kbdRepeat;
break;
}
} else {
localKey = twineactions[event.customType].localKey;
- actionStates[event.customType] = true;
+ debug("repeat: %i", event.kbdRepeat);
+ actionStates[event.customType] = 1 + event.kbdRepeat;
}
break;
case Common::EVENT_LBUTTONDOWN:
leftMouse = 1;
break;
- case Common::EVENT_KEYDOWN: {
- if (event.kbd.keycode == Common::KeyCode::KEYCODE_RETURN || event.kbd.keycode == Common::KeyCode::KEYCODE_KP_ENTER) {
- _hitEnter = true;
- }
+ case Common::EVENT_KEYDOWN:
+ _pressed[event.kbd.keycode] = 1 + event.kbdRepeat;
break;
- }
- case Common::EVENT_KEYUP: {
- if (event.kbd.keycode == Common::KeyCode::KEYCODE_RETURN || event.kbd.keycode == Common::KeyCode::KEYCODE_KP_ENTER) {
- _hitEnter = false;
- }
+ case Common::EVENT_KEYUP:
+ _pressed[event.kbd.keycode] = 0;
break;
- }
case Common::EVENT_RBUTTONDOWN:
rightMouse = 1;
break;
diff --git a/engines/twine/input.h b/engines/twine/input.h
index 28784ddaef..9afcd7ade8 100644
--- a/engines/twine/input.h
+++ b/engines/twine/input.h
@@ -29,6 +29,12 @@
namespace TwinE {
+class TwinEEngine;
+
+extern const char *mainKeyMapId;
+extern const char *uiKeyMapId;
+extern const char *cutsceneKeyMapId;
+
enum TwinEActionType {
Pause,
NextRoom,
@@ -61,9 +67,19 @@ enum TwinEActionType {
Escape,
PageUp,
+ UIEnter,
+ UIAbort,
+ UILeft,
+ UIRight,
+ UIUp,
+ UIDown,
+
+ CutsceneAbort,
+
Max
};
+// TODO: get rid of this table
static constexpr const struct ActionMapping {
TwinEActionType action;
uint8 localKey;
@@ -97,8 +113,14 @@ static constexpr const struct ActionMapping {
{InventoryMenu, 0x36},
{SpecialAction, 0x11},
{Escape, 0x01},
- {PageUp, 0x49} // TODO: used for what?
-};
+ {PageUp, 0x49}, // TODO: used for what?
+ {UIEnter, 0x00},
+ {UIAbort, 0x00},
+ {UILeft, 0x00},
+ {UIRight, 0x00},
+ {UIUp, 0x00},
+ {UIDown, 0x00},
+ {CutsceneAbort, 0x00}};
static_assert(ARRAYSIZE(twineactions) == TwinEActionType::Max, "Unexpected action mapping array size");
@@ -109,17 +131,31 @@ struct MouseStatusStruct {
int32 y = 0;
};
-class TwinEEngine;
+struct ScopedKeyMapperDisable {
+ ScopedKeyMapperDisable();
+ ~ScopedKeyMapperDisable();
+};
+
+class ScopedKeyMap {
+private:
+ TwinEEngine* _engine;
+ Common::String _prevKeyMap;
+public:
+ ScopedKeyMap(TwinEEngine* engine, const char *id);
+ ~ScopedKeyMap();
+};
class Input {
private:
TwinEEngine *_engine;
- bool _hitEnter = false;
+ int _tickCounter = 0;
+ uint8 _pressed[Common::KEYCODE_LAST]{0};
+ Common::String _currentKeyMap;
public:
Input(TwinEEngine *engine);
- bool actionStates[TwinEActionType::Max]{false};
+ uint8 actionStates[TwinEActionType::Max]{false};
int16 skippedKey = 0;
int16 pressedKey = 0;
int16 internalKeyCode = 0;
@@ -130,14 +166,45 @@ public:
int16 leftMouse = 0;
int16 rightMouse = 0;
- bool isAnyKeyPressed() const;
+ /**
+ * @brief Dependent on the context we are currently in the game, we might want to disable certain keymaps.
+ * Like disabling ui keymaps when we are in-game - or vice versa.
+ */
+ void enabledKeyMap(const char *id);
+
+ const Common::String currentKeyMap() const;
+
+ /**
+ * @param onlyFirstTime If this is set to @c true, repeating key press events are not taken into account here
+ * This means, that even if the key is held down, this will return @c false. @c false as value for this parameter
+ * will return @c true also for repeating key presses.
+ *
+ * @sa isPressed()
+ */
+ bool isActionActive(TwinEActionType actionType, bool onlyFirstTime = true) const;
+
+ /**
+ * @brief If the action is active, the internal state is reset and a following call of this method won't return
+ * @c true anymore
+ */
+ bool toggleActionIfActive(TwinEActionType actionType);
- bool isPressed(Common::KeyCode keycode) const;
+ /**
+ * @param onlyFirstTime If this is set to @c true, repeating key press events are not taken into account here
+ * This means, that even if the key is held down, this will return @c false. @c false as value for this parameter
+ * will return @c true also for repeating key presses.
+ *
+ * @note You won't receive any pressed events if you have that key bound to a @c TwinEActionType value.
+ * @sa isActionActive()
+ */
+ bool isPressed(Common::KeyCode keycode, bool onlyFirstTime = true) const;
- inline bool isPressedEnter() const {
- return isPressed(Common::KEYCODE_RETURN) || isPressed(Common::KEYCODE_KP_ENTER);
+ inline bool isPressedEnter(bool onlyFirstTime = true) const {
+ return isPressed(Common::KEYCODE_RETURN, onlyFirstTime) || isPressed(Common::KEYCODE_KP_ENTER, onlyFirstTime);
}
+ bool isQuickBehaviourActionActive() const;
+
/**
* Gets mouse positions
* @param mouseData structure that contains mouse position info
@@ -147,6 +214,10 @@ public:
void readKeys();
};
+inline const Common::String Input::currentKeyMap() const {
+ return _currentKeyMap;
+}
+
} // namespace TwinE
#endif
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 8acf1158e1..a2f6327642 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -34,8 +34,8 @@
#include "twine/gamestate.h"
#include "twine/grid.h"
#include "twine/hqrdepack.h"
-#include "twine/interface.h"
#include "twine/input.h"
+#include "twine/interface.h"
#include "twine/menuoptions.h"
#include "twine/movements.h"
#include "twine/music.h"
@@ -281,13 +281,13 @@ void Menu::plasmaEffectRenderFrame() {
*(dest++) = *(src++);
}
-void Menu::processPlasmaEffect(int32 top, int32 color) {
+void Menu::processPlasmaEffect(int32 left, int32 top, int32 right, int32 color) {
const int32 max_value = color + 15;
plasmaEffectRenderFrame();
const uint8 *in = plasmaEffectPtr + 5 * PLASMA_WIDTH;
- uint8 *out = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top];
+ uint8 *out = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
for (int32 i = 0; i < 25; i++) {
for (int32 j = 0; j < kMainMenuButtonWidth; j++) {
@@ -348,13 +348,13 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
}
};
- processPlasmaEffect(top, 80);
+ processPlasmaEffect(left, top, right, 80);
if (!(_engine->getRandomNumber() % 5)) {
plasmaEffectPtr[_engine->getRandomNumber() % 140 * 10 + 1900] = 255;
}
_engine->_interface->drawSplittedBox(newWidth, top, right, bottom, 68);
} else {
- processPlasmaEffect(top, 64);
+ processPlasmaEffect(left, top, right, 64);
if (!(_engine->getRandomNumber() % 5)) {
plasmaEffectPtr[_engine->getRandomNumber() % 320 * 10 + 6400] = 255;
}
@@ -431,21 +431,20 @@ int32 Menu::processMenu(int16 *menuSettings) {
const int32 numEntry = menuSettings[MenuSettings_NumberOfButtons];
int32 maxButton = numEntry - 1;
+ _engine->_input->enabledKeyMap(uiKeyMapId);
+
+ _engine->_screens->loadMenuImage(false);
do {
_engine->readKeys();
_engine->_input->key = _engine->_input->pressedKey;
- if (_engine->_input->isPressed(Common::KeyCode::KEYCODE_DOWN)) { // on arrow key down
- debug("pressed down");
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown)) {
currentButton++;
if (currentButton == numEntry) { // if current button is the last, than next button is the first
currentButton = 0;
}
buttonsNeedRedraw = true;
- }
-
- if (((uint8)_engine->_input->key & 1)) { // on arrow key up
- debug("pressed up");
+ } else if (_engine->_input->toggleActionIfActive(TwinEActionType::UIUp)) {
currentButton--;
if (currentButton < 0) { // if current button is the first, than previous button is the last
currentButton = maxButton;
@@ -461,10 +460,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
switch (id) {
case kMusicVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
- if (((uint8)_engine->_input->key & 4)) { // on arrow key left
+ if (_engine->_input->isActionActive(TwinEActionType::UILeft)) {
volume -= 4;
}
- if (((uint8)_engine->_input->key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
volume += 4;
}
_engine->_music->musicVolume(volume);
@@ -472,10 +471,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kSoundVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
- if (((uint8)_engine->_input->key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
volume -= 4;
}
- if (((uint8)_engine->_input->key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
@@ -483,10 +482,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kCDVolume: {
AudioCDManager::Status status = _engine->_system->getAudioCDManager()->getStatus();
- if (((uint8)_engine->_input->key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
status.volume -= 4;
}
- if (((uint8)_engine->_input->key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
status.volume += 4;
}
_engine->_system->getAudioCDManager()->setVolume(status.volume);
@@ -494,10 +493,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kLineVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
- if (((uint8)_engine->_input->key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
volume -= 4;
}
- if (((uint8)_engine->_input->key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
@@ -505,10 +504,10 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kMasterVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
- if (((uint8)_engine->_input->key & 4)) { // on arrow key left
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
volume -= 4;
}
- if (((uint8)_engine->_input->key & 8)) { // on arrow key right
+ if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
@@ -532,7 +531,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
if (musicChanged) {
// TODO: update volume settings
}
- } while (!(_engine->_input->skippedKey & 2) && !(_engine->_input->skippedKey & 1));
+ } while (!_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter));
currentButton = *(menuSettings + MenuSettings_FirstButton + currentButton * 2); // get current browsed button
@@ -872,20 +871,18 @@ void Menu::processBehaviourMenu() {
_engine->_animations->setAnimAtKeyframe(behaviourAnimState[_engine->_actor->heroBehaviour], _engine->_animations->animTable[_engine->_actor->heroAnimIdx[_engine->_actor->heroBehaviour]], behaviourEntity, &behaviourAnimData[_engine->_actor->heroBehaviour]);
- _engine->readKeys();
-
int32 tmpTime = _engine->lbaTime;
- while (_engine->_input->skippedKey & 4 || (_engine->_input->internalKeyCode >= twineactions[TwinEActionType::QuickBehaviourNormal].localKey && _engine->_input->internalKeyCode <= twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey)) {
+ while (_engine->_input->isActionActive(TwinEActionType::BehaviourMenu) || _engine->_input->isQuickBehaviourActionActive()) {
_engine->readKeys();
_engine->_input->key = _engine->_input->pressedKey;
int heroBehaviour = (int)_engine->_actor->heroBehaviour;
- if (_engine->_input->key & 8) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
heroBehaviour++;
}
- if (_engine->_input->key & 4) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft)) {
heroBehaviour--;
}
@@ -965,14 +962,12 @@ void Menu::drawItem(int32 item) {
}
void Menu::drawInventoryItems() {
- int32 item;
-
_engine->_interface->drawTransparentBox(17, 10, 622, 320, 4);
drawBox(17, 10, 622, 320);
drawMagicItemsBox(110, 18, 188, 311, 75);
_engine->copyBlockPhys(17, 10, 622, 320);
- for (item = 0; item < NUM_INVENTORY_ITEMS; item++) {
+ for (int32 item = 0; item < NUM_INVENTORY_ITEMS; item++) {
drawItem(item);
}
}
@@ -1002,7 +997,7 @@ void Menu::processInventoryMenu() {
_engine->_text->setFontCrossColor(4);
_engine->_text->initDialogueBox();
- while (_engine->_input->internalKeyCode != 1) {
+ while (_engine->_input->isActionActive(TwinEActionType::InventoryMenu)) {
_engine->readKeys();
int32 prevSelectedItem = inventorySelectedItem;
@@ -1026,7 +1021,7 @@ void Menu::processInventoryMenu() {
if (_engine->loopCurrentKey == 1 || _engine->loopPressedKey & 0x20)
break;
- if (_engine->_input->key & 2) { // down
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown)) {
inventorySelectedItem++;
if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
inventorySelectedItem = 0;
@@ -1035,7 +1030,7 @@ void Menu::processInventoryMenu() {
bx = 3;
}
- if (_engine->_input->key & 1) { // up
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UIUp)) {
inventorySelectedItem--;
if (inventorySelectedItem < 0) {
inventorySelectedItem = NUM_INVENTORY_ITEMS - 1;
@@ -1044,7 +1039,7 @@ void Menu::processInventoryMenu() {
bx = 3;
}
- if (_engine->_input->key & 4) { // left
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft)) {
inventorySelectedItem -= 4;
if (inventorySelectedItem < 0) {
inventorySelectedItem += NUM_INVENTORY_ITEMS;
@@ -1053,7 +1048,7 @@ void Menu::processInventoryMenu() {
bx = 3;
}
- if (_engine->_input->key & 8) { // right
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
inventorySelectedItem += 4;
if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
inventorySelectedItem -= NUM_INVENTORY_ITEMS;
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index a9c76874ee..be472a8d51 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -115,7 +115,7 @@ public:
* @param top top height where the effect will be draw in the front buffer
* @param color plasma effect start color
*/
- void processPlasmaEffect(int32 top, int32 color);
+ void processPlasmaEffect(int32 left, int32 top, int32 right, int32 color);
/**
* Draw the entire button box
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index f17315a496..6af8a4d4a6 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -21,11 +21,11 @@
*/
#include "twine/menuoptions.h"
-#include "common/keyboard.h"
+#include "common/system.h"
#include "twine/flamovies.h"
#include "twine/gamestate.h"
-#include "twine/interface.h"
#include "twine/input.h"
+#include "twine/interface.h"
#include "twine/menu.h"
#include "twine/music.h"
#include "twine/resources.h"
@@ -138,7 +138,7 @@ void MenuOptions::drawSelectableCharacter(int32 x, int32 y, int32 arg) {
if (arg != 0) {
_engine->_interface->drawSplittedBox(left, top, right, bottom, 91);
} else {
- _engine->_interface->blitBox(left, top, right, bottom, (const int8*)_engine->workVideoBuffer.getPixels(), left, top, (int8*)_engine->frontVideoBuffer.getPixels());
+ _engine->_interface->blitBox(left, top, right, bottom, (const int8 *)_engine->workVideoBuffer.getPixels(), left, top, (int8 *)_engine->frontVideoBuffer.getPixels());
right2 = right;
_engine->_interface->drawTransparentBox(left, top, right2, bottom, 4);
}
@@ -162,19 +162,20 @@ void MenuOptions::drawSelectableCharacters() {
// 0001F18C
void MenuOptions::drawPlayerName(int32 centerx, int32 top, int32 type) {
+ const int left = _engine->_text->dialTextBoxLeft;
+ const int right = _engine->_text->dialTextBoxRight;
if (type == 1) {
- _engine->_menu->processPlasmaEffect(top, 1);
+ _engine->_menu->processPlasmaEffect(left, top, right, 1);
}
- const int left = _engine->_text->dialTextBoxLeft;
- const int right = _engine->_text->dialTextBoxRight;
const int bottom = _engine->_text->dialTextBoxBottom;
_engine->_menu->drawBox(left, top, right, bottom);
_engine->_interface->drawTransparentBox(left + 1, top + 1, right - 1, bottom - 1, 3);
_engine->_text->drawText(centerx - _engine->_text->getTextSize(playerName) / 2, top, playerName);
- _engine->copyBlockPhys(left, top, right, bottom);
+ _engine->flip();
+ // TODO: _engine->copyBlockPhys(left, top, right, bottom);
}
int32 MenuOptions::enterPlayerName(int32 textIdx) {
@@ -191,18 +192,35 @@ int32 MenuOptions::enterPlayerName(int32 textIdx) {
_engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99);
drawPlayerName(halfScreenWidth, 100, 1);
drawSelectableCharacters();
-
- do {
- _engine->readKeys();
+ _engine->flip();
+
+ // we don't want custom events here - as we are entering the player name
+ ScopedKeyMapperDisable scopedKeyMapperDisable;
+ for (;;) {
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ if (event.type == Common::EVENT_KEYDOWN) {
+ if (event.kbd.keycode == Common::KEYCODE_KP_ENTER || event.kbd.keycode == Common::KEYCODE_RETURN) {
+ return 1;
+ }
+ const size_t size = strlen(playerName);
+ if (size >= sizeof(playerName) - 1) {
+ return 1;
+ }
+ playerName[size] = event.kbd.ascii;
+ playerName[size + 1] = '\0';
+ debug("name: %s", playerName);
+
+ drawPlayerName(halfScreenWidth, 100, 1);
+ _engine->flip();
+ }
+ }
if (_engine->shouldQuit()) {
break;
}
- } while (_engine->_input->isPressedEnter());
+ _engine->_system->delayMillis(1);
+ };
}
-
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
-
return 1;
}
diff --git a/engines/twine/menuoptions.h b/engines/twine/menuoptions.h
index a0dcb0bb5e..0b7bce18cc 100644
--- a/engines/twine/menuoptions.h
+++ b/engines/twine/menuoptions.h
@@ -44,7 +44,7 @@ public:
int32 canShowCredits = 0;
- char playerName[256] = "";
+ char playerName[32] = "";
/** Main menu new game options */
void newGameMenu();
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index d504ad8f85..0b6179acc4 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -56,177 +56,231 @@ public:
Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
using namespace Common;
+ Action *act;
- Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "twine", "Little Big Adventure");
+ KeymapArray array(3);
+
+ {
+ Keymap *gameKeyMap = new Keymap(Keymap::kKeymapTypeGame, mainKeyMapId, "Little Big Adventure");
+ act = new Action("PAUSE", _("Pause"));
+ act->setCustomEngineActionEvent(TwinEActionType::Pause);
+ act->addDefaultInputMapping("p");
+ gameKeyMap->addAction(act);
+
+ act = new Action("NEXTROOM", _("Debug Next Room"));
+ act->setCustomEngineActionEvent(TwinEActionType::NextRoom);
+ act->addDefaultInputMapping("r");
+ gameKeyMap->addAction(act);
+
+ act = new Action("PREVIOUSROOM", _("Debug Previous Room"));
+ act->setCustomEngineActionEvent(TwinEActionType::PreviousRoom);
+ act->addDefaultInputMapping("f");
+ gameKeyMap->addAction(act);
+
+ act = new Action("APPLYCELLINGGRID", _("Debug Apply Celling Grid"));
+ act->setCustomEngineActionEvent(TwinEActionType::ApplyCellingGrid);
+ act->addDefaultInputMapping("t");
+ gameKeyMap->addAction(act);
+
+ act = new Action("INCREASECELLINGGRIDINDEX", _("Debug Increase Celling Grid Index"));
+ act->setCustomEngineActionEvent(TwinEActionType::IncreaseCellingGridIndex);
+ act->addDefaultInputMapping("g");
+ gameKeyMap->addAction(act);
+
+ act = new Action("DECREASECELLINGGRIDINDEX", _("Debug Decrease Celling Grid Index"));
+ act->setCustomEngineActionEvent(TwinEActionType::DecreaseCellingGridIndex);
+ act->addDefaultInputMapping("b");
+ gameKeyMap->addAction(act);
+
+ act = new Action("DEBUGGRIDCAMERAPRESSUP", _("Debug Grid Camera Up"));
+ act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressUp);
+ act->addDefaultInputMapping("s");
+ gameKeyMap->addAction(act);
+
+ act = new Action("DEBUGGRIDCAMERAPRESSDOWN", _("Debug Grid Camera Down"));
+ act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressDown);
+ act->addDefaultInputMapping("x");
+ gameKeyMap->addAction(act);
+
+ act = new Action("DEBUGGRIDCAMERAPRESSLEFT", _("Debug Grid Camera Left"));
+ act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressLeft);
+ act->addDefaultInputMapping("y");
+ act->addDefaultInputMapping("z");
+ gameKeyMap->addAction(act);
+
+ act = new Action("DEBUGGRIDCAMERAPRESSRIGHT", _("Debug Grid Camera Right"));
+ act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressRight);
+ act->addDefaultInputMapping("c");
+ gameKeyMap->addAction(act);
+
+ act = new Action("NORMALBEHAVIOUR", _("Normal Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourNormal);
+ act->addDefaultInputMapping("F1");
+ gameKeyMap->addAction(act);
+
+ act = new Action("ATHLETICBEHAVIOUR", _("Athletic Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAthletic);
+ act->addDefaultInputMapping("F2");
+ gameKeyMap->addAction(act);
+
+ act = new Action("AGGRESSIVEBEHAVIOUR", _("Aggressive Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAggressive);
+ act->addDefaultInputMapping("F3");
+ gameKeyMap->addAction(act);
+
+ act = new Action("DISCREETBEHAVIOUR", _("Discreet Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourDiscreet);
+ act->addDefaultInputMapping("F4");
+ gameKeyMap->addAction(act);
+
+ act = new Action("BEHAVIOURACTION", _("Behaviour Action"));
+ act->setCustomEngineActionEvent(TwinEActionType::ExecuteBehaviourAction);
+ act->addDefaultInputMapping("SPACE");
+ act->addDefaultInputMapping("JOY_A");
+ gameKeyMap->addAction(act);
+
+ act = new Action("CHANGEBEHAVIOUR", _("Change Behaviour"));
+ act->setCustomEngineActionEvent(TwinEActionType::BehaviourMenu);
+ act->addDefaultInputMapping("CTRL");
+ gameKeyMap->addAction(act);
+
+ act = new Action("OPTIONSMENU", _("Options Menu"));
+ act->setCustomEngineActionEvent(TwinEActionType::OptionsMenu);
+ act->addDefaultInputMapping("F6");
+ gameKeyMap->addAction(act);
+
+ act = new Action("CENTER", _("Center"));
+ act->setCustomEngineActionEvent(TwinEActionType::RecenterScreenOnTwinsen);
+ act->addDefaultInputMapping("RETURN");
+ act->addDefaultInputMapping("KP_ENTER");
+ gameKeyMap->addAction(act);
+
+ act = new Action("USESELECTEDOBJECT", _("Use Selected Object"));
+ act->setCustomEngineActionEvent(TwinEActionType::UseSelectedObject);
+ act->addDefaultInputMapping("SHIFT+RETURN");
+ act->addDefaultInputMapping("SHIFT+KP_ENTER");
+ gameKeyMap->addAction(act);
+
+ act = new Action("THROWMAGICBALL", _("Throw Magic Ball"));
+ act->setCustomEngineActionEvent(TwinEActionType::ThrowMagicBall);
+ act->addDefaultInputMapping("ALT");
+ gameKeyMap->addAction(act);
+
+ act = new Action("MOVEFORWARD", _("Move Forward"));
+ act->setCustomEngineActionEvent(TwinEActionType::MoveForward);
+ act->addDefaultInputMapping("UP");
+ act->addDefaultInputMapping("KP8");
+ gameKeyMap->addAction(act);
+
+ act = new Action("MOVEBACKWARD", _("Move Backward"));
+ act->setCustomEngineActionEvent(TwinEActionType::MoveBackward);
+ act->addDefaultInputMapping("DOWN");
+ act->addDefaultInputMapping("KP2");
+ gameKeyMap->addAction(act);
+
+ act = new Action("TURNRIGHT", _("Turn Right"));
+ act->setCustomEngineActionEvent(TwinEActionType::TurnRight);
+ act->addDefaultInputMapping("RIGHT");
+ act->addDefaultInputMapping("KP6");
+ gameKeyMap->addAction(act);
+
+ act = new Action("TURNLEFT", _("Turn Left"));
+ act->setCustomEngineActionEvent(TwinEActionType::TurnLeft);
+ act->addDefaultInputMapping("LEFT");
+ act->addDefaultInputMapping("KP4");
+ gameKeyMap->addAction(act);
+
+ act = new Action("USEPROTOPACK", _("Use Protopack"));
+ act->setCustomEngineActionEvent(TwinEActionType::UseProtoPack);
+ act->addDefaultInputMapping("j");
+ gameKeyMap->addAction(act);
+
+ act = new Action("OPENHOLOMAP", _("Open Holomap"));
+ act->setCustomEngineActionEvent(TwinEActionType::OpenHolomap);
+ act->addDefaultInputMapping("h");
+ gameKeyMap->addAction(act);
+
+ act = new Action("INVENTORY", _("Inventory"));
+ act->setCustomEngineActionEvent(TwinEActionType::InventoryMenu);
+ act->addDefaultInputMapping("LSHIFT");
+ act->addDefaultInputMapping("RSHIFT");
+ act->addDefaultInputMapping("i");
+ gameKeyMap->addAction(act);
+
+ act = new Action("SPECIALACTION", _("Special Action"));
+ act->setCustomEngineActionEvent(TwinEActionType::SpecialAction);
+ act->addDefaultInputMapping("w");
+ gameKeyMap->addAction(act);
+
+ act = new Action("ESCAPE", _("Escape"));
+ act->setCustomEngineActionEvent(TwinEActionType::Escape);
+ act->addDefaultInputMapping("ESCAPE");
+ gameKeyMap->addAction(act);
+
+ act = new Action("PAGEUP", _("Page Up"));
+ act->setCustomEngineActionEvent(TwinEActionType::PageUp);
+ act->addDefaultInputMapping("PAGEUP");
+ gameKeyMap->addAction(act);
+
+ array[0] = gameKeyMap;
+ }
- Action *act;
+ {
+ Keymap *uiKeyMap = new Keymap(Keymap::kKeymapTypeGame, uiKeyMapId, "Little Big Adventure UI");
+
+ act = new Action("ACCEPT", _("Accept"));
+ act->setCustomEngineActionEvent(TwinEActionType::UIEnter);
+ act->addDefaultInputMapping("RETURN");
+ act->addDefaultInputMapping("KP_ENTER");
+ uiKeyMap->addAction(act);
+
+ act = new Action("ABORT", _("Abort"));
+ act->setCustomEngineActionEvent(TwinEActionType::UIAbort);
+ act->addDefaultInputMapping("ESCAPE");
+ uiKeyMap->addAction(act);
+
+ act = new Action("UP", _("Up"));
+ act->setCustomEngineActionEvent(TwinEActionType::UIUp);
+ act->addDefaultInputMapping("UP");
+ act->addDefaultInputMapping("KP8");
+ uiKeyMap->addAction(act);
+
+ act = new Action("DOWN", _("Down"));
+ act->setCustomEngineActionEvent(TwinEActionType::UIDown);
+ act->addDefaultInputMapping("DOWN");
+ act->addDefaultInputMapping("KP2");
+ uiKeyMap->addAction(act);
+
+ act = new Action("RIGHT", _("Right"));
+ act->setCustomEngineActionEvent(TwinEActionType::UIRight);
+ act->addDefaultInputMapping("RIGHT");
+ act->addDefaultInputMapping("KP6");
+ uiKeyMap->addAction(act);
+
+ act = new Action("LEFT", _("Left"));
+ act->setCustomEngineActionEvent(TwinEActionType::UILeft);
+ act->addDefaultInputMapping("LEFT");
+ act->addDefaultInputMapping("KP4");
+ uiKeyMap->addAction(act);
+
+ array[1] = uiKeyMap;
+ }
+
+ {
+ Keymap *cutsceneKeyMap = new Keymap(Keymap::kKeymapTypeGame, cutsceneKeyMapId, "Little Big Adventure Cutscenes");
+
+ act = new Action("ABORT", _("Abort"));
+ act->setCustomEngineActionEvent(TwinEActionType::CutsceneAbort);
+ act->addDefaultInputMapping("RETURN");
+ act->addDefaultInputMapping("KP_ENTER");
+ act->addDefaultInputMapping("ESCAPE");
+ act->addDefaultInputMapping("SPACE");
+ cutsceneKeyMap->addAction(act);
- act = new Action("PAUSE", _("Pause"));
- act->setCustomEngineActionEvent(TwinEActionType::Pause);
- act->addDefaultInputMapping("p");
- engineKeyMap->addAction(act);
-
- act = new Action("NEXTROOM", _("Debug Next Room"));
- act->setCustomEngineActionEvent(TwinEActionType::NextRoom);
- act->addDefaultInputMapping("r");
- engineKeyMap->addAction(act);
-
- act = new Action("PREVIOUSROOM", _("Debug Previous Room"));
- act->setCustomEngineActionEvent(TwinEActionType::PreviousRoom);
- act->addDefaultInputMapping("f");
- engineKeyMap->addAction(act);
-
- act = new Action("APPLYCELLINGGRID", _("Debug Apply Celling Grid"));
- act->setCustomEngineActionEvent(TwinEActionType::ApplyCellingGrid);
- act->addDefaultInputMapping("t");
- engineKeyMap->addAction(act);
-
- act = new Action("INCREASECELLINGGRIDINDEX", _("Debug Increase Celling Grid Index"));
- act->setCustomEngineActionEvent(TwinEActionType::IncreaseCellingGridIndex);
- act->addDefaultInputMapping("g");
- engineKeyMap->addAction(act);
-
- act = new Action("DECREASECELLINGGRIDINDEX", _("Debug Decrease Celling Grid Index"));
- act->setCustomEngineActionEvent(TwinEActionType::DecreaseCellingGridIndex);
- act->addDefaultInputMapping("b");
- engineKeyMap->addAction(act);
-
- act = new Action("DEBUGGRIDCAMERAPRESSUP", _("Debug Grid Camera Up"));
- act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressUp);
- act->addDefaultInputMapping("s");
- engineKeyMap->addAction(act);
-
- act = new Action("DEBUGGRIDCAMERAPRESSDOWN", _("Debug Grid Camera Down"));
- act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressDown);
- act->addDefaultInputMapping("x");
- engineKeyMap->addAction(act);
-
- act = new Action("DEBUGGRIDCAMERAPRESSLEFT", _("Debug Grid Camera Left"));
- act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressLeft);
- act->addDefaultInputMapping("y");
- act->addDefaultInputMapping("z");
- engineKeyMap->addAction(act);
-
- act = new Action("DEBUGGRIDCAMERAPRESSRIGHT", _("Debug Grid Camera Right"));
- act->setCustomEngineActionEvent(TwinEActionType::DebugGridCameraPressRight);
- act->addDefaultInputMapping("c");
- engineKeyMap->addAction(act);
-
- act = new Action("NORMALBEHAVIOUR", _("Normal Behaviour"));
- act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourNormal);
- act->addDefaultInputMapping("F1");
- engineKeyMap->addAction(act);
-
- act = new Action("ATHLETICBEHAVIOUR", _("Athletic Behaviour"));
- act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAthletic);
- act->addDefaultInputMapping("F2");
- engineKeyMap->addAction(act);
-
- act = new Action("AGGRESSIVEBEHAVIOUR", _("Aggressive Behaviour"));
- act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourAggressive);
- act->addDefaultInputMapping("F3");
- engineKeyMap->addAction(act);
-
- act = new Action("DISCREETBEHAVIOUR", _("Discreet Behaviour"));
- act->setCustomEngineActionEvent(TwinEActionType::QuickBehaviourDiscreet);
- act->addDefaultInputMapping("F4");
- engineKeyMap->addAction(act);
-
- act = new Action("BEHAVIOURACTION", _("Behaviour Action"));
- act->setCustomEngineActionEvent(TwinEActionType::ExecuteBehaviourAction);
- act->addDefaultInputMapping("SPACE");
- act->addDefaultInputMapping("JOY_A");
- engineKeyMap->addAction(act);
-
- act = new Action("CHANGEBEHAVIOUR", _("Change Behaviour"));
- act->setCustomEngineActionEvent(TwinEActionType::BehaviourMenu);
- act->addDefaultInputMapping("CTRL");
- engineKeyMap->addAction(act);
-
- act = new Action("OPTIONSMENU", _("Options Menu"));
- act->setCustomEngineActionEvent(TwinEActionType::OptionsMenu);
- act->addDefaultInputMapping("F6");
- engineKeyMap->addAction(act);
-
- act = new Action("CENTER", _("Center"));
- act->setCustomEngineActionEvent(TwinEActionType::RecenterScreenOnTwinsen);
- act->addDefaultInputMapping("RETURN");
- act->addDefaultInputMapping("KP_ENTER");
- engineKeyMap->addAction(act);
-
- act = new Action("USESELECTEDOBJECT", _("Use Selected Object"));
- act->setCustomEngineActionEvent(TwinEActionType::UseSelectedObject);
- act->addDefaultInputMapping("SHIFT+RETURN");
- act->addDefaultInputMapping("SHIFT+KP_ENTER");
- engineKeyMap->addAction(act);
-
- act = new Action("THROWMAGICBALL", _("Throw Magic Ball"));
- act->setCustomEngineActionEvent(TwinEActionType::ThrowMagicBall);
- act->addDefaultInputMapping("ALT");
- engineKeyMap->addAction(act);
-
- act = new Action("MOVEFORWARD", _("Move Forward"));
- act->setCustomEngineActionEvent(TwinEActionType::MoveForward);
- act->addDefaultInputMapping("UP");
- act->addDefaultInputMapping("KP8");
- engineKeyMap->addAction(act);
-
- act = new Action("MOVEBACKWARD", _("Move Backward"));
- act->setCustomEngineActionEvent(TwinEActionType::MoveBackward);
- act->addDefaultInputMapping("DOWN");
- act->addDefaultInputMapping("KP2");
- engineKeyMap->addAction(act);
-
- act = new Action("TurnRight", _("Turn Right"));
- act->setCustomEngineActionEvent(TwinEActionType::TurnRight);
- act->addDefaultInputMapping("RIGHT");
- act->addDefaultInputMapping("KP6");
- engineKeyMap->addAction(act);
-
- act = new Action("TurnLeft", _("Turn Left"));
- act->setCustomEngineActionEvent(TwinEActionType::TurnLeft);
- act->addDefaultInputMapping("LEFT");
- act->addDefaultInputMapping("KP4");
- engineKeyMap->addAction(act);
-
- act = new Action("USEPROTOPACK", _("Use Protopack"));
- act->setCustomEngineActionEvent(TwinEActionType::UseProtoPack);
- act->addDefaultInputMapping("j");
- engineKeyMap->addAction(act);
-
- act = new Action("OPENHOLOMAP", _("Open Holomap"));
- act->setCustomEngineActionEvent(TwinEActionType::OpenHolomap);
- act->addDefaultInputMapping("h");
- engineKeyMap->addAction(act);
-
- act = new Action("INVENTORY", _("Inventory"));
- act->setCustomEngineActionEvent(TwinEActionType::InventoryMenu);
- act->addDefaultInputMapping("LSHIFT");
- act->addDefaultInputMapping("RSHIFT");
- act->addDefaultInputMapping("i");
- engineKeyMap->addAction(act);
-
- act = new Action("SPECIALACTION", _("Special Action"));
- act->setCustomEngineActionEvent(TwinEActionType::SpecialAction);
- act->addDefaultInputMapping("w");
- engineKeyMap->addAction(act);
-
- act = new Action("ESCAPE", _("Escape"));
- act->setCustomEngineActionEvent(TwinEActionType::Escape);
- act->addDefaultInputMapping("ESCAPE");
- engineKeyMap->addAction(act);
-
- act = new Action("PAGEUP", _("Page Up"));
- act->setCustomEngineActionEvent(TwinEActionType::PageUp);
- act->addDefaultInputMapping("PAGEUP");
- engineKeyMap->addAction(act);
-
- const int delta = (int)TwinEActionType::Max - (int)engineKeyMap->getActions().size();
- if (delta != 0) {
- error("Registered key map actions differs from TwinEActionType by %i", delta);
+ array[2] = cutsceneKeyMap;
}
- return Keymap::arrayOf(engineKeyMap);
+ return array;
}
} // namespace TwinE
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 3f6a18dc5b..923ab3ac36 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -198,6 +198,7 @@ void Redraw::updateOverlayTypePosition(int16 X1, int16 Y1, int16 X2, int16 Y2) {
}
}
+// TODO: convert to bool and check if this isn't always true...
void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
int16 tmp_projPosX;
int16 tmp_projPosY;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index f33c55698b..07104c498c 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -29,6 +29,7 @@
#include "common/str.h"
#include "common/system.h"
#include "common/textconsole.h"
+#include "common/translation.h"
#include "engines/util.h"
#include "graphics/managed_surface.h"
#include "graphics/palette.h"
@@ -47,8 +48,8 @@
#include "twine/grid.h"
#include "twine/holomap.h"
#include "twine/hqrdepack.h"
-#include "twine/interface.h"
#include "twine/input.h"
+#include "twine/interface.h"
#include "twine/menu.h"
#include "twine/menuoptions.h"
#include "twine/movements.h"
@@ -323,6 +324,8 @@ void TwinEEngine::processActorSamplePosition(int32 actorIdx) {
}
int32 TwinEEngine::runGameEngine() { // mainLoopInteration
+ _input->enabledKeyMap(mainKeyMapId);
+
readKeys();
if (_scene->needChangeScene > -1) {
@@ -364,7 +367,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_redraw->redrawEngineActions(1);
}
- if (loopCurrentKey == twineactions[TwinEActionType::OptionsMenu].localKey) {
+ if (_input->toggleActionIfActive(TwinEActionType::OptionsMenu)) {
freezeTime();
_sound->pauseSamples();
_menu->OptionsMenuState[MenuSettings_FirstButton] = 15; // TODO: why? - where is the reset? kReturnGame
@@ -379,7 +382,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
// inventory menu
loopInventoryItem = -1;
- if (loopCurrentKey == twineactions[TwinEActionType::InventoryMenu].localKey && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
+ if (_input->isActionActive(TwinEActionType::InventoryMenu) && _scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
freezeTime();
_menu->processInventoryMenu();
@@ -488,19 +491,19 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
// Process behaviour menu
- if ((loopCurrentKey == twineactions[TwinEActionType::BehaviourMenu].localKey ||
- loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourNormal].localKey ||
- loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAthletic].localKey ||
- loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAggressive].localKey ||
- loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey) &&
+ if ((_input->isActionActive(TwinEActionType::BehaviourMenu, false) ||
+ _input->isActionActive(TwinEActionType::QuickBehaviourNormal, false) ||
+ _input->isActionActive(TwinEActionType::QuickBehaviourAthletic, false) ||
+ _input->isActionActive(TwinEActionType::QuickBehaviourAggressive, false) ||
+ _input->isActionActive(TwinEActionType::QuickBehaviourDiscreet, false)) &&
_scene->sceneHero->entity != -1 && _scene->sceneHero->controlMode == kManual) {
- if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourNormal].localKey) {
+ if (_input->isActionActive(TwinEActionType::QuickBehaviourNormal, false)) {
_actor->heroBehaviour = HeroBehaviourType::kNormal;
- } else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAthletic].localKey) {
+ } else if (_input->isActionActive(TwinEActionType::QuickBehaviourAthletic, false)) {
_actor->heroBehaviour = HeroBehaviourType::kAthletic;
- } else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourAggressive].localKey) {
+ } else if (_input->isActionActive(TwinEActionType::QuickBehaviourAggressive, false)) {
_actor->heroBehaviour = HeroBehaviourType::kAggressive;
- } else if (loopCurrentKey == twineactions[TwinEActionType::QuickBehaviourDiscreet].localKey) {
+ } else if (_input->isActionActive(TwinEActionType::QuickBehaviourDiscreet, false)) {
_actor->heroBehaviour = HeroBehaviourType::kDiscrete;
}
freezeTime();
@@ -510,7 +513,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
// use Proto-Pack
- if (loopCurrentKey == twineactions[TwinEActionType::UseProtoPack].localKey && _gameState->gameFlags[InventoryItems::kiProtoPack] == 1) {
+ if (_input->isActionActive(TwinEActionType::UseProtoPack, false) && _gameState->gameFlags[InventoryItems::kiProtoPack] == 1) {
if (_gameState->gameFlags[InventoryItems::kiBookOfBu]) {
_scene->sceneHero->body = 0;
} else {
@@ -543,7 +546,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
// Process Pause
- if (loopCurrentKey == twineactions[TwinEActionType::Pause].localKey) {
+ if (_input->toggleActionIfActive(TwinEActionType::Pause)) {
freezeTime();
_text->setFontColor(15);
_text->drawText(5, 446, "Pause"); // no key for pause in Text Bank
@@ -554,7 +557,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
break;
}
g_system->delayMillis(10);
- } while (_input->internalKeyCode != 0x19 && !_input->pressedKey);
+ } while (!_input->toggleActionIfActive(TwinEActionType::Pause));
unfreezeTime();
_redraw->redrawEngineActions(1);
}
@@ -760,6 +763,7 @@ bool TwinEEngine::gameEngineLoop() { // mainLoop
_screens->lockPalette = true;
_movements->setActorAngle(0, -256, 5, &loopMovePtr);
+
while (quitGame == -1) {
start = g_system->getMillis();
Commit: 4c593bdbdddcce0bd2b90f07bb36939ca55f9f37
https://github.com/scummvm/scummvm/commit/4c593bdbdddcce0bd2b90f07bb36939ca55f9f37
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: further refactored the input code
Changed paths:
engines/twine/flamovies.cpp
engines/twine/input.cpp
engines/twine/input.h
engines/twine/screens.cpp
engines/twine/text.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 7b0160bb70..78e3c0c313 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -274,6 +274,8 @@ void FlaMovies::playFlaMovie(const char *flaName) {
if (!strcmp((const char *)flaHeaderData.version, "V1.3")) {
int32 currentFrame = 0;
+ debug("Play fla: %s", flaName);
+
ScopedKeyMap scopedKeyMap(_engine, cutsceneKeyMapId);
do {
diff --git a/engines/twine/input.cpp b/engines/twine/input.cpp
index cdeb91c3aa..46dcfe77d1 100644
--- a/engines/twine/input.cpp
+++ b/engines/twine/input.cpp
@@ -119,16 +119,23 @@ bool Input::isQuickBehaviourActionActive() const {
}
void Input::enabledKeyMap(const char *id) {
+ if (_currentKeyMap == id) {
+ return;
+ }
+
+ // switching the keymap must also disable all other action keys
+ memset(_pressed, 0, sizeof(_pressed));
+
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
const Common::KeymapArray &keymaps = keymapper->getKeymaps();
for (Common::Keymap *keymap : keymaps) {
keymap->setEnabled(keymap->getId() == id);
}
_currentKeyMap = id;
+ debug("enable keymap %s", id);
}
void Input::readKeys() {
- ++_tickCounter;
skippedKey = 0;
internalKeyCode = 0;
@@ -151,13 +158,11 @@ void Input::readKeys() {
break;
default:
localKey = twineactions[event.customType].localKey;
- debug("repeat: %i", event.kbdRepeat);
actionStates[event.customType] = 1 + event.kbdRepeat;
break;
}
} else {
localKey = twineactions[event.customType].localKey;
- debug("repeat: %i", event.kbdRepeat);
actionStates[event.customType] = 1 + event.kbdRepeat;
}
break;
diff --git a/engines/twine/input.h b/engines/twine/input.h
index 9afcd7ade8..60dbd686c0 100644
--- a/engines/twine/input.h
+++ b/engines/twine/input.h
@@ -131,11 +131,18 @@ struct MouseStatusStruct {
int32 y = 0;
};
+/**
+ * @brief Whenever text input is needed (like the playername)
+ * you have to disable the keymaps
+ */
struct ScopedKeyMapperDisable {
ScopedKeyMapperDisable();
~ScopedKeyMapperDisable();
};
+/**
+ * @brief Activates the given key map id that is registered in the meta engine
+ */
class ScopedKeyMap {
private:
TwinEEngine* _engine;
@@ -148,7 +155,6 @@ public:
class Input {
private:
TwinEEngine *_engine;
- int _tickCounter = 0;
uint8 _pressed[Common::KEYCODE_LAST]{0};
Common::String _currentKeyMap;
diff --git a/engines/twine/screens.cpp b/engines/twine/screens.cpp
index 6ba1c498d3..c2aad58265 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/screens.cpp
@@ -33,9 +33,7 @@ namespace TwinE {
void Screens::adelineLogo() {
_engine->_music->playMidiMusic(31);
- loadImage(RESSHQR_ADELINEIMG);
- _engine->delaySkip(7000);
- fadeOut(paletteRGBACustom);
+ loadImageDelay(RESSHQR_ADELINEIMG, 7);
palCustom = true;
}
@@ -78,6 +76,7 @@ void Screens::loadImage(int32 index, bool fade_in) {
warning("Failed to load image with index %i", index);
return;
}
+ debug("Load image: %i", index);
copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
loadCustomPalette(index + 1);
if (fade_in) {
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 11d7fc8637..88af7238fc 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -594,9 +594,10 @@ int Text::printText10() {
// TODO: refactor this code
void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
- int32 printedText;
int32 skipText = 0;
+ ScopedKeyMap scopedKeyMap(_engine, cutsceneKeyMapId);
+
_engine->_interface->saveClip();
_engine->_interface->resetClip();
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
@@ -609,50 +610,21 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
initText(index);
initDialogueBox();
+ int32 printedText;
do {
_engine->readKeys();
printedText = printText10();
playVox(currDialTextEntry);
- if (printedText == 2) {
- do {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
- break;
- }
- if (_engine->_input->internalKeyCode == 0 && _engine->_input->skippedKey == 0 && _engine->_input->pressedKey == 0) {
- break;
- }
- playVox(currDialTextEntry);
- _engine->_system->delayMillis(1);
- } while (1);
-
- do {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
- break;
- }
- if (_engine->_input->internalKeyCode != 0 || _engine->_input->skippedKey != 0 || _engine->_input->pressedKey != 0) {
- break;
- }
- playVox(currDialTextEntry);
- _engine->_system->delayMillis(1);
- } while (1);
- }
-
- if (_engine->_input->internalKeyCode == 1) {
- skipText = 1;
- }
-
- if (!printedText && !_engine->_sound->isSamplePlaying(currDialTextEntry)) {
+ if (!_engine->_sound->isSamplePlaying(currDialTextEntry)) {
break;
}
if (_engine->shouldQuit()) {
- skipText = 1;
+ break;
}
_engine->_system->delayMillis(1);
- } while (!skipText);
+ } while (!_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
hasHiddenVox = 0;
@@ -660,12 +632,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
printTextVar13 = 0;
- if (printedText != 0) {
- _engine->_interface->loadClip();
- return;
- }
-
- if (skipText != 0) {
+ if (printedText != 0 || skipText != 0) {
_engine->_interface->loadClip();
return;
}
@@ -678,7 +645,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (_engine->_input->internalKeyCode || _engine->_input->skippedKey || _engine->_input->pressedKey);
+ } while (_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
// RECHECK this later
// wait key to display next text
@@ -696,12 +663,16 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (!_engine->_input->pressedKey);
+ } while (!_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
} else { // RECHECK THIS
while (playVox(currDialTextEntry) && _engine->_input->internalKeyCode != 1) {
+ _engine->readKeys();
if (_engine->shouldQuit()) {
break;
}
+ if (_engine->_input->isActionActive(TwinEActionType::CutsceneAbort)) {
+ break;
+ }
}
hasHiddenVox = 0;
voxHiddenIndex = 0;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 07104c498c..f2abbde3c5 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -246,7 +246,9 @@ void TwinEEngine::initEngine() {
// Check if LBA CD-Rom is on drive
_music->initCdrom();
-#if 0
+#define TWINE_PLAY_INTROS 1
+#if TWINE_PLAY_INTROS
+ _input->enabledKeyMap(cutsceneKeyMapId);
// Display company logo
_screens->adelineLogo();
@@ -267,6 +269,8 @@ void TwinEEngine::initEngine() {
}
_flaMovies->playFlaMovie(FLA_DRAGON3);
+#else
+ _input->enabledKeyMap(uiKeyMapId);
#endif
_screens->loadMenuImage();
@@ -763,7 +767,6 @@ bool TwinEEngine::gameEngineLoop() { // mainLoop
_screens->lockPalette = true;
_movements->setActorAngle(0, -256, 5, &loopMovePtr);
-
while (quitGame == -1) {
start = g_system->getMillis();
@@ -787,7 +790,7 @@ void TwinEEngine::delaySkip(uint32 time) {
_input->internalKeyCode = 0;
do {
readKeys();
- if (_input->internalKeyCode == 1) {
+ if (_input->isActionActive(TwinEActionType::CutsceneAbort) || _input->isActionActive(TwinEActionType::UIAbort)) {
break;
}
if (shouldQuit()) {
Commit: 1027ddda972cb18d80718ae602fb606f960d83a4
https://github.com/scummvm/scummvm/commit/1027ddda972cb18d80718ae602fb606f960d83a4
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed memory leaks
Changed paths:
engines/twine/menu.cpp
engines/twine/menu.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index a2f6327642..c830518506 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -243,6 +243,17 @@ Menu::Menu(TwinEEngine *engine) : _engine(engine) {
AdvOptionsMenuState = copySettings(_priv::AdvOptionsMenuSettings, sizeof(_priv::AdvOptionsMenuSettings));
}
+Menu::~Menu() {
+ free(plasmaEffectPtr);
+ free(OptionsMenuState);
+ free(GiveUpMenuWithSaveState);
+ free(VolumeMenuState);
+ free(SaveManageMenuState);
+ free(GiveUpMenuState);
+ free(MainMenuState);
+ free(AdvOptionsMenuState);
+}
+
void Menu::plasmaEffectRenderFrame() {
for (int32 j = 1; j < PLASMA_HEIGHT - 1; j++) {
for (int32 i = 1; i < PLASMA_WIDTH - 1; i++) {
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index be472a8d51..09c0650570 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -96,6 +96,7 @@ private:
public:
Menu(TwinEEngine *engine);
+ ~Menu();
int16 *OptionsMenuState;
int32 currMenuTextIndex = -1;
Commit: c5b5e98db136e4ce499ed06525d593ae96d0c3a6
https://github.com/scummvm/scummvm/commit/c5b5e98db136e4ce499ed06525d593ae96d0c3a6
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: fixed showing delayed text
Changed paths:
engines/twine/menuoptions.cpp
engines/twine/text.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 6af8a4d4a6..97500370d1 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -64,17 +64,13 @@ void MenuOptions::newGame() {
_engine->_text->drawTextFullscreen(150);
_engine->readKeys();
- if (_engine->_input->internalKeyCode != 1) {
- // intro screen 1 - twinsun
- _engine->_screens->loadImage(RESSHQR_INTROSCREEN2IMG);
- _engine->_text->drawTextFullscreen(151);
- _engine->readKeys();
-
- if (_engine->_input->internalKeyCode != 1) {
- _engine->_screens->loadImage(RESSHQR_INTROSCREEN3IMG);
- _engine->_text->drawTextFullscreen(152);
- }
- }
+ // intro screen 1 - twinsun
+ _engine->_screens->loadImage(RESSHQR_INTROSCREEN2IMG);
+ _engine->_text->drawTextFullscreen(151);
+ _engine->readKeys();
+
+ _engine->_screens->loadImage(RESSHQR_INTROSCREEN3IMG);
+ _engine->_text->drawTextFullscreen(152);
_engine->_text->newGameVar5 = 0;
_engine->_text->textClipSmall();
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 88af7238fc..a309007a61 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -616,7 +616,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
printedText = printText10();
playVox(currDialTextEntry);
- if (!_engine->_sound->isSamplePlaying(currDialTextEntry)) {
+ if (!printedText && !_engine->_sound->isSamplePlaying(currDialTextEntry)) {
break;
}
@@ -624,8 +624,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (!_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
-
+ } while (!_engine->_input->toggleActionIfActive(TwinEActionType::CutsceneAbort));
hasHiddenVox = 0;
stopVox(currDialTextEntry);
@@ -645,7 +644,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
+ } while (_engine->_input->toggleActionIfActive(TwinEActionType::CutsceneAbort));
// RECHECK this later
// wait key to display next text
@@ -663,14 +662,14 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (!_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
+ } while (!_engine->_input->toggleActionIfActive(TwinEActionType::CutsceneAbort));
} else { // RECHECK THIS
while (playVox(currDialTextEntry) && _engine->_input->internalKeyCode != 1) {
_engine->readKeys();
if (_engine->shouldQuit()) {
break;
}
- if (_engine->_input->isActionActive(TwinEActionType::CutsceneAbort)) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::CutsceneAbort)) {
break;
}
}
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index f2abbde3c5..3e2e5a2f75 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -790,7 +790,7 @@ void TwinEEngine::delaySkip(uint32 time) {
_input->internalKeyCode = 0;
do {
readKeys();
- if (_input->isActionActive(TwinEActionType::CutsceneAbort) || _input->isActionActive(TwinEActionType::UIAbort)) {
+ if (_input->toggleActionIfActive(TwinEActionType::CutsceneAbort) || _input->toggleActionIfActive(TwinEActionType::UIAbort)) {
break;
}
if (shouldQuit()) {
Commit: 84f2ba7e411ef1c816fd3d950d315a5e2bdbf220
https://github.com/scummvm/scummvm/commit/84f2ba7e411ef1c816fd3d950d315a5e2bdbf220
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: implemented more keymap actions
Changed paths:
engines/twine/gamestate.cpp
engines/twine/input.cpp
engines/twine/input.h
engines/twine/interface.h
engines/twine/menu.cpp
engines/twine/menuoptions.cpp
engines/twine/redraw.cpp
engines/twine/sound.cpp
engines/twine/text.cpp
engines/twine/text.h
engines/twine/twine.cpp
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index f7d87ff868..f28f4481a1 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -458,7 +458,7 @@ void GameState::processGameChoices(int32 choiceIdx) {
}
_engine->_text->stopVox(_engine->_text->currDialTextEntry);
- _engine->_text->hasHiddenVox = 0;
+ _engine->_text->hasHiddenVox = false;
_engine->_text->voxHiddenIndex = 0;
}
}
diff --git a/engines/twine/input.cpp b/engines/twine/input.cpp
index 46dcfe77d1..5a8bf9db71 100644
--- a/engines/twine/input.cpp
+++ b/engines/twine/input.cpp
@@ -114,6 +114,10 @@ bool Input::toggleActionIfActive(TwinEActionType actionType) {
return false;
}
+bool Input::toggleAbortAction() {
+ return toggleActionIfActive(TwinEActionType::CutsceneAbort) || toggleActionIfActive(TwinEActionType::UIAbort) || toggleActionIfActive(TwinEActionType::Escape);
+}
+
bool Input::isQuickBehaviourActionActive() const {
return isActionActive(TwinEActionType::QuickBehaviourNormal) || isActionActive(TwinEActionType::QuickBehaviourAthletic) || isActionActive(TwinEActionType::QuickBehaviourAggressive) || isActionActive(TwinEActionType::QuickBehaviourDiscreet);
}
diff --git a/engines/twine/input.h b/engines/twine/input.h
index 60dbd686c0..442ef384f8 100644
--- a/engines/twine/input.h
+++ b/engines/twine/input.h
@@ -195,6 +195,8 @@ public:
*/
bool toggleActionIfActive(TwinEActionType actionType);
+ bool toggleAbortAction();
+
/**
* @param onlyFirstTime If this is set to @c true, repeating key press events are not taken into account here
* This means, that even if the key is held down, this will return @c false. @c false as value for this parameter
diff --git a/engines/twine/interface.h b/engines/twine/interface.h
index f04fd51ab0..b3108194f1 100644
--- a/engines/twine/interface.h
+++ b/engines/twine/interface.h
@@ -32,9 +32,9 @@ namespace TwinE {
/** Screen left limit to display the texts */
#define SCREEN_TEXTLIMIT_LEFT 0
/** Screen right limit to display the texts */
-#define SCREEN_TEXTLIMIT_RIGHT SCREEN_WIDTH - 1
+#define SCREEN_TEXTLIMIT_RIGHT (SCREEN_WIDTH - 1)
/** Screen bottom limit to display the texts */
-#define SCREEN_TEXTLIMIT_BOTTOM SCREEN_HEIGHT - 1
+#define SCREEN_TEXTLIMIT_BOTTOM (SCREEN_HEIGHT - 1)
class TwinEEngine;
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index c830518506..a885543b67 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -780,6 +780,7 @@ void Menu::drawInfoMenu(int16 left, int16 top) {
_engine->copyBlockPhys(left, top, left + 450, top + 135);
}
+// TODO: convert cantDrawBox to bool
void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, int16 cantDrawBox) {
int32 boxLeft = behaviour * 110 + 110;
int32 boxRight = boxLeft + 99;
@@ -886,22 +887,17 @@ void Menu::processBehaviourMenu() {
while (_engine->_input->isActionActive(TwinEActionType::BehaviourMenu) || _engine->_input->isQuickBehaviourActionActive()) {
_engine->readKeys();
- _engine->_input->key = _engine->_input->pressedKey;
int heroBehaviour = (int)_engine->_actor->heroBehaviour;
- if (_engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::TurnLeft)) {
heroBehaviour++;
- }
-
- if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft)) {
+ } else if (_engine->_input->toggleActionIfActive(TwinEActionType::TurnRight)) {
heroBehaviour--;
}
if (heroBehaviour < kNormal) {
heroBehaviour = kDiscrete;
- }
-
- if (heroBehaviour >= kProtoPack) {
+ } else if (heroBehaviour >= kProtoPack) {
heroBehaviour = kNormal;
}
@@ -912,14 +908,6 @@ void Menu::processBehaviourMenu() {
tmpHeroBehaviour = _engine->_actor->heroBehaviour;
_engine->_movements->setActorAngleSafe(_engine->_scene->sceneHero->angle, _engine->_scene->sceneHero->angle - 256, 50, &moveMenu);
_engine->_animations->setAnimAtKeyframe(behaviourAnimState[_engine->_actor->heroBehaviour], _engine->_animations->animTable[_engine->_actor->heroAnimIdx[_engine->_actor->heroBehaviour]], behaviourEntity, &behaviourAnimData[_engine->_actor->heroBehaviour]);
-
- while (_engine->_input->pressedKey) {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
- break;
- }
- drawBehaviour(_engine->_actor->heroBehaviour, -1, 1);
- }
}
drawBehaviour(_engine->_actor->heroBehaviour, -1, 1);
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 97500370d1..f5cfd3d71a 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -64,7 +64,7 @@ void MenuOptions::newGame() {
_engine->_text->drawTextFullscreen(150);
_engine->readKeys();
- // intro screen 1 - twinsun
+ // intro screen 2
_engine->_screens->loadImage(RESSHQR_INTROSCREEN2IMG);
_engine->_text->drawTextFullscreen(151);
_engine->readKeys();
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 923ab3ac36..e7911bf8bd 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -43,31 +43,30 @@
namespace TwinE {
void Redraw::addRedrawCurrentArea(int32 left, int32 top, int32 right, int32 bottom) {
- int32 area;
int32 i = 0;
- int32 leftValue;
- int32 rightValue;
- int32 topValue;
- int32 bottomValue;
- area = (right - left) * (bottom - top);
+ const int32 area = (right - left) * (bottom - top);
while (i < numOfRedrawBox) {
+ int32 leftValue;
if (currentRedrawList[i].left >= left)
leftValue = left;
else
leftValue = currentRedrawList[i].left;
+ int32 rightValue;
if (currentRedrawList[i].right <= right)
rightValue = right;
else
rightValue = currentRedrawList[i].right;
+ int32 topValue;
if (currentRedrawList[i].top >= top)
topValue = top;
else
topValue = currentRedrawList[i].top;
+ int32 bottomValue;
if (currentRedrawList[i].bottom <= bottom)
bottomValue = bottom;
else
@@ -77,23 +76,23 @@ void Redraw::addRedrawCurrentArea(int32 left, int32 top, int32 right, int32 bott
currentRedrawList[i].left = leftValue;
currentRedrawList[i].top = topValue;
currentRedrawList[i].right = rightValue;
- currentRedrawList[i].bottom = bottomValue;
+ currentRedrawList[i].bottom = MIN(SCREEN_TEXTLIMIT_BOTTOM, bottomValue);
- if (currentRedrawList[i].bottom >= SCREEN_WIDTH)
- currentRedrawList[i].bottom = SCREEN_TEXTLIMIT_BOTTOM;
+ assert(currentRedrawList[i].left < currentRedrawList[i].right);
+ assert(currentRedrawList[i].top < currentRedrawList[i].bottom);
return;
}
i++;
- };
+ }
currentRedrawList[i].left = left;
currentRedrawList[i].top = top;
currentRedrawList[i].right = right;
- currentRedrawList[i].bottom = bottom;
+ currentRedrawList[i].bottom = MIN(SCREEN_TEXTLIMIT_BOTTOM, bottom);
- if (currentRedrawList[i].bottom >= SCREEN_WIDTH)
- currentRedrawList[i].bottom = SCREEN_TEXTLIMIT_BOTTOM;
+ assert(currentRedrawList[i].left < currentRedrawList[i].right);
+ assert(currentRedrawList[i].top < currentRedrawList[i].bottom);
numOfRedrawBox++;
}
diff --git a/engines/twine/sound.cpp b/engines/twine/sound.cpp
index 17aee79b45..4a1025ba59 100644
--- a/engines/twine/sound.cpp
+++ b/engines/twine/sound.cpp
@@ -125,7 +125,7 @@ void Sound::playVoxSample(int32 index) {
// Fix incorrect sample files first byte
if (*sampPtr != 'C') {
- _engine->_text->hasHiddenVox = *sampPtr;
+ _engine->_text->hasHiddenVox = *sampPtr != '\0';
_engine->_text->voxHiddenIndex++;
}
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index a309007a61..92c0b184d9 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -25,8 +25,8 @@
#include "common/str.h"
#include "common/system.h"
#include "twine/hqrdepack.h"
-#include "twine/interface.h"
#include "twine/input.h"
+#include "twine/interface.h"
#include "twine/menu.h"
#include "twine/renderer.h"
#include "twine/resources.h"
@@ -73,7 +73,7 @@ bool Text::initVoxToPlay(int32 index) { // setVoxFileAtDigit
int16 *localOrderBuf = (int16 *)dialOrderPtr;
voxHiddenIndex = 0;
- hasHiddenVox = 0;
+ hasHiddenVox = false;
// choose right text from order index
for (int32 i = 0; i < numDialTextEntries; i++) {
@@ -114,7 +114,7 @@ bool Text::stopVox(int32 index) {
if (!_engine->_sound->isSamplePlaying(index)) {
return false;
}
- hasHiddenVox = 0;
+ hasHiddenVox = false;
_engine->_sound->stopSample(index);
return true;
}
@@ -181,7 +181,7 @@ void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
usedColor = dialTextColor;
- screen2 = (uint8*)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[y] + x;
+ screen2 = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[y] + x;
tempX = x;
tempY = y;
@@ -207,7 +207,7 @@ void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
number = *(data++);
for (i = 0; i < number; i++) {
if (tempX >= SCREEN_TEXTLIMIT_LEFT && tempX < SCREEN_TEXTLIMIT_RIGHT && tempY >= SCREEN_TEXTLIMIT_TOP && tempY < SCREEN_TEXTLIMIT_BOTTOM) {
- *((uint8*)_engine->frontVideoBuffer.getBasePtr(tempX, tempY)) = usedColor;
+ *((uint8 *)_engine->frontVideoBuffer.getBasePtr(tempX, tempY)) = usedColor;
}
screen2++;
@@ -253,11 +253,11 @@ void Text::drawCharacterShadow(int32 x, int32 y, uint8 character, int32 color) {
}
void Text::drawText(int32 x, int32 y, const char *dialogue) { // Font
- if (fontPtr == 0) // if the font is not defined
+ if (fontPtr == 0) // if the font is not defined
return;
do {
- const uint8 currChar = (uint8) *(dialogue++); // read the next char from the string
+ const uint8 currChar = (uint8) * (dialogue++); // read the next char from the string
if (currChar == '\0') {
break;
@@ -624,8 +624,8 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (!_engine->_input->toggleActionIfActive(TwinEActionType::CutsceneAbort));
- hasHiddenVox = 0;
+ } while (!_engine->_input->toggleAbortAction());
+ hasHiddenVox = false;
stopVox(currDialTextEntry);
@@ -636,7 +636,6 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
return;
}
- // RECHECK this later
// wait displaying text
do {
_engine->readKeys();
@@ -644,17 +643,12 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (_engine->_input->toggleActionIfActive(TwinEActionType::CutsceneAbort));
+ } while (!_engine->_input->toggleAbortAction());
- // RECHECK this later
// wait key to display next text
do {
_engine->readKeys();
- if (_engine->_input->internalKeyCode != 0) {
- _engine->_interface->loadClip();
- return;
- }
- if (_engine->_input->skippedKey != 0) {
+ if (_engine->_input->internalKeyCode != 0 || _engine->_input->skippedKey != 0) {
_engine->_interface->loadClip();
return;
}
@@ -662,18 +656,19 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
break;
}
_engine->_system->delayMillis(1);
- } while (!_engine->_input->toggleActionIfActive(TwinEActionType::CutsceneAbort));
+ } while (!_engine->_input->toggleAbortAction());
} else { // RECHECK THIS
- while (playVox(currDialTextEntry) && _engine->_input->internalKeyCode != 1) {
+ while (playVox(currDialTextEntry)) {
_engine->readKeys();
if (_engine->shouldQuit()) {
break;
}
- if (_engine->_input->toggleActionIfActive(TwinEActionType::CutsceneAbort)) {
+ if (_engine->_input->toggleAbortAction()) {
break;
}
+ _engine->_system->delayMillis(1);
}
- hasHiddenVox = 0;
+ hasHiddenVox = false;
voxHiddenIndex = 0;
}
@@ -797,7 +792,7 @@ void Text::textClipSmall() { // newGame4
dialTextBoxParam2 = 591;
}
-void Text::drawAskQuestion(int32 index) { // MyDial
+void Text::drawAskQuestion(int32 index) {
int32 textStatus = 1;
// get right VOX entry index
@@ -816,36 +811,26 @@ void Text::drawAskQuestion(int32 index) { // MyDial
if (_engine->shouldQuit()) {
break;
}
- playVox(currDialTextEntry);
- _engine->_system->delayMillis(1);
- } while (_engine->_input->internalKeyCode || _engine->_input->skippedKey || _engine->_input->pressedKey);
-
- do {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
+ if (!playVoxSimple(currDialTextEntry)) {
break;
}
- playVox(currDialTextEntry);
_engine->_system->delayMillis(1);
- } while (!_engine->_input->internalKeyCode && !_engine->_input->skippedKey && !_engine->_input->pressedKey);
+ } while (!_engine->_input->toggleAbortAction());
}
_engine->_system->delayMillis(1);
} while (textStatus);
while (playVoxSimple(currDialTextEntry)) {
- if (_engine->shouldQuit()) {
+ if (_engine->shouldQuit() || _engine->_input->toggleAbortAction()) {
+ stopVox(currDialTextEntry);
break;
}
+ _engine->_system->delayMillis(1);
}
- hasHiddenVox = 0;
+ hasHiddenVox = false;
voxHiddenIndex = 0;
-
- if (_engine->_sound->isSamplePlaying(currDialTextEntry)) {
- stopVox(currDialTextEntry);
- }
-
printTextVar13 = 0;
}
diff --git a/engines/twine/text.h b/engines/twine/text.h
index 6e7f917a7d..24ccd15a21 100644
--- a/engines/twine/text.h
+++ b/engines/twine/text.h
@@ -142,7 +142,7 @@ public:
int32 printTextVar13 = 0;
int32 newGameVar4 = 0;
int32 newGameVar5 = 0;
- int32 hasHiddenVox = 0; // printTextVar5
+ bool hasHiddenVox = false; // printTextVar5
int32 voxHiddenIndex = 0;
// ---
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 3e2e5a2f75..900f3c3c4d 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -246,7 +246,7 @@ void TwinEEngine::initEngine() {
// Check if LBA CD-Rom is on drive
_music->initCdrom();
-#define TWINE_PLAY_INTROS 1
+#define TWINE_PLAY_INTROS 0
#if TWINE_PLAY_INTROS
_input->enabledKeyMap(cutsceneKeyMapId);
// Display company logo
@@ -532,7 +532,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
// Recenter Screen
- if ((loopPressedKey & 2) && !disableScreenRecenter) {
+ if (_input->isActionActive(TwinEActionType::RecenterScreenOnTwinsen) && !disableScreenRecenter) {
_grid->newCameraX = _scene->sceneActors[_scene->currentlyFollowedActor].x >> 9;
_grid->newCameraY = _scene->sceneActors[_scene->currentlyFollowedActor].y >> 8;
_grid->newCameraZ = _scene->sceneActors[_scene->currentlyFollowedActor].z >> 9;
@@ -540,7 +540,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
// Draw holomap
- if (loopCurrentKey == 35 && _gameState->gameFlags[InventoryItems::kiHolomap] == 1 && !_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED]) {
+ if (_input->isActionActive(TwinEActionType::OpenHolomap) && _gameState->gameFlags[InventoryItems::kiHolomap] == 1 && !_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED]) {
freezeTime();
//TestRestoreModeSVGA(1);
_holomap->processHolomap();
@@ -790,7 +790,7 @@ void TwinEEngine::delaySkip(uint32 time) {
_input->internalKeyCode = 0;
do {
readKeys();
- if (_input->toggleActionIfActive(TwinEActionType::CutsceneAbort) || _input->toggleActionIfActive(TwinEActionType::UIAbort)) {
+ if (_input->toggleAbortAction()) {
break;
}
if (shouldQuit()) {
Commit: 5b21b55a85b29421b0ad946e1f8f98aced6580ab
https://github.com/scummvm/scummvm/commit/5b21b55a85b29421b0ad946e1f8f98aced6580ab
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: use toggleAbortAction for GameState::processFoundItem
Changed paths:
engines/twine/gamestate.cpp
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index f28f4481a1..46f84c3c4e 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -393,7 +393,7 @@ void GameState::processFoundItem(int32 item) {
_engine->_redraw->flipRedrawAreas();
_engine->readKeys();
- if (_engine->_input->skippedKey) {
+ if (_engine->_input->toggleAbortAction()) {
if (!textState) {
quitItem = 1;
}
Commit: 82cda6e217cd197bee3af167790d8a78795ebeaf
https://github.com/scummvm/scummvm/commit/82cda6e217cd197bee3af167790d8a78795ebeaf
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: reduced scope + cleanup
Changed paths:
engines/twine/grid.cpp
engines/twine/grid.h
engines/twine/redraw.cpp
engines/twine/scene.cpp
diff --git a/engines/twine/grid.cpp b/engines/twine/grid.cpp
index 7d37d911b5..9d4dc0ee6b 100644
--- a/engines/twine/grid.cpp
+++ b/engines/twine/grid.cpp
@@ -130,7 +130,7 @@ void Grid::copyGridMask(int32 index, int32 x, int32 y, uint8 *buffer) {
} while (--vSize);
}
-void Grid::drawOverModelActor(int32 X, int32 Y, int32 Z) {
+void Grid::drawOverModelActor(int32 x, int32 y, int32 z) {
const int32 copyBlockPhysLeft = ((_engine->_interface->textWindowLeft + 24) / 24) - 1;
const int32 copyBlockPhysRight = ((_engine->_interface->textWindowRight + 24) / 24);
@@ -138,8 +138,8 @@ void Grid::drawOverModelActor(int32 X, int32 Y, int32 Z) {
for (int32 i = 0; i < brickInfoBuffer[j]; i++) {
BrickEntry *currBrickEntry = &bricksDataBuffer[j][i];
- if (currBrickEntry->posY + 38 > _engine->_interface->textWindowTop && currBrickEntry->posY <= _engine->_interface->textWindowBottom && currBrickEntry->y >= Y) {
- if (currBrickEntry->x + currBrickEntry->z > Z + X) {
+ if (currBrickEntry->posY + 38 > _engine->_interface->textWindowTop && currBrickEntry->posY <= _engine->_interface->textWindowBottom && currBrickEntry->y >= y) {
+ if (currBrickEntry->x + currBrickEntry->z > z + x) {
copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, (uint8 *)_engine->workVideoBuffer.getPixels());
}
}
@@ -147,26 +147,20 @@ void Grid::drawOverModelActor(int32 X, int32 Y, int32 Z) {
}
}
-void Grid::drawOverSpriteActor(int32 X, int32 Y, int32 Z) {
- int32 copyBlockPhysLeft;
- int32 copyBlockPhysRight;
- int32 i;
- int32 j;
- BrickEntry *currBrickEntry;
-
- copyBlockPhysLeft = ((_engine->_interface->textWindowLeft + 24) / 24) - 1;
- copyBlockPhysRight = (_engine->_interface->textWindowRight + 24) / 24;
+void Grid::drawOverSpriteActor(int32 x, int32 y, int32 z) {
+ const int32 copyBlockPhysLeft = ((_engine->_interface->textWindowLeft + 24) / 24) - 1;
+ const int32 copyBlockPhysRight = (_engine->_interface->textWindowRight + 24) / 24;
- for (j = copyBlockPhysLeft; j <= copyBlockPhysRight; j++) {
- for (i = 0; i < brickInfoBuffer[j]; i++) {
- currBrickEntry = &bricksDataBuffer[j][i];
+ for (int32 j = copyBlockPhysLeft; j <= copyBlockPhysRight; j++) {
+ for (int32 i = 0; i < brickInfoBuffer[j]; i++) {
+ BrickEntry *currBrickEntry = &bricksDataBuffer[j][i];
- if (currBrickEntry->posY + 38 > _engine->_interface->textWindowTop && currBrickEntry->posY <= _engine->_interface->textWindowBottom && currBrickEntry->y >= Y) {
- if ((currBrickEntry->x == X) && (currBrickEntry->z == Z)) {
+ if (currBrickEntry->posY + 38 > _engine->_interface->textWindowTop && currBrickEntry->posY <= _engine->_interface->textWindowBottom && currBrickEntry->y >= y) {
+ if ((currBrickEntry->x == x) && (currBrickEntry->z == z)) {
copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, (uint8 *)_engine->workVideoBuffer.getPixels());
}
- if ((currBrickEntry->x > X) || (currBrickEntry->z > Z)) {
+ if ((currBrickEntry->x > x) || (currBrickEntry->z > z)) {
copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, (uint8 *)_engine->workVideoBuffer.getPixels());
}
}
@@ -391,15 +385,12 @@ void Grid::createGridMap() {
void Grid::createCellingGridMap(uint8 *gridPtr) {
int32 currGridOffset = 0;
int32 currOffset = 0;
- int32 blockOffset;
- int32 z, x;
- uint8 *tempGridPtr;
- for (z = 0; z < GRID_SIZE_Z; z++) {
- blockOffset = currOffset;
- tempGridPtr = gridPtr + currGridOffset;
+ for (int32 z = 0; z < GRID_SIZE_Z; z++) {
+ int32 blockOffset = currOffset;
+ uint8 *tempGridPtr = gridPtr + currGridOffset;
- for (x = 0; x < GRID_SIZE_X; x++) {
+ for (int32 x = 0; x < GRID_SIZE_X; x++) {
int gridOffset = *((uint16 *)tempGridPtr);
tempGridPtr += 2;
createCellingGridColumn(gridPtr + gridOffset, blockBuffer + blockOffset);
@@ -410,9 +401,13 @@ void Grid::createCellingGridMap(uint8 *gridPtr) {
}
}
-int32 Grid::initGrid(int32 index) {
+bool Grid::initGrid(int32 index) {
// load grids from file
- int32 gridSize = _engine->_hqrdepack->hqrGetallocEntry(¤tGrid, Resources::HQR_LBA_GRI_FILE, index);
+ const int32 gridSize = _engine->_hqrdepack->hqrGetallocEntry(¤tGrid, Resources::HQR_LBA_GRI_FILE, index);
+ if (gridSize == 0) {
+ warning("Failed to load grid index: %i", index);
+ return false;
+ }
// load layouts from file
_engine->_hqrdepack->hqrGetallocEntry(¤tBll, Resources::HQR_LBA_BLL_FILE, index);
@@ -425,7 +420,7 @@ int32 Grid::initGrid(int32 index) {
createGridMap();
- return 1;
+ return true;
}
int32 Grid::initCellingGrid(int32 index) {
diff --git a/engines/twine/grid.h b/engines/twine/grid.h
index 14944e6f8b..97a4eb6876 100644
--- a/engines/twine/grid.h
+++ b/engines/twine/grid.h
@@ -198,19 +198,19 @@ public:
/**
* Draw 3D actor over bricks
- * @param X actor.x coordinate
- * @param Y actor.y coordinate
- * @param Z actor.z coordinate
+ * @param x actor.x coordinate
+ * @param y actor.y coordinate
+ * @param z actor.z coordinate
*/
- void drawOverModelActor(int32 X, int32 Y, int32 Z);
+ void drawOverModelActor(int32 x, int32 y, int32 z);
/**
* Draw sprite actor over bricks
- * @param X actor.x coordinate
- * @param Y actor.y coordinate
- * @param Z actor.z coordinate
+ * @param x actor.x coordinate
+ * @param y actor.y coordinate
+ * @param z actor.z coordinate
*/
- void drawOverSpriteActor(int32 X, int32 Y, int32 Z);
+ void drawOverSpriteActor(int32 x, int32 y, int32 z);
/**
* Get sprite width and height sizes
@@ -262,7 +262,7 @@ public:
* Initialize grid (background scenearios)
* @param index grid index number
*/
- int32 initGrid(int32 index);
+ bool initGrid(int32 index);
/**
* Initialize celling grid (background scenearios)
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index e7911bf8bd..0317c33e29 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -78,8 +78,8 @@ void Redraw::addRedrawCurrentArea(int32 left, int32 top, int32 right, int32 bott
currentRedrawList[i].right = rightValue;
currentRedrawList[i].bottom = MIN(SCREEN_TEXTLIMIT_BOTTOM, bottomValue);
- assert(currentRedrawList[i].left < currentRedrawList[i].right);
- assert(currentRedrawList[i].top < currentRedrawList[i].bottom);
+ assert(currentRedrawList[i].left <= currentRedrawList[i].right);
+ assert(currentRedrawList[i].top <= currentRedrawList[i].bottom);
return;
}
@@ -91,24 +91,29 @@ void Redraw::addRedrawCurrentArea(int32 left, int32 top, int32 right, int32 bott
currentRedrawList[i].right = right;
currentRedrawList[i].bottom = MIN(SCREEN_TEXTLIMIT_BOTTOM, bottom);
- assert(currentRedrawList[i].left < currentRedrawList[i].right);
- assert(currentRedrawList[i].top < currentRedrawList[i].bottom);
+ assert(currentRedrawList[i].left <= currentRedrawList[i].right);
+ assert(currentRedrawList[i].top <= currentRedrawList[i].bottom);
numOfRedrawBox++;
}
void Redraw::addRedrawArea(int32 left, int32 top, int32 right, int32 bottom) {
- if (left < 0)
+ if (left < 0) {
left = 0;
- if (top < 0)
+ }
+ if (top < 0) {
top = 0;
- if (right >= SCREEN_WIDTH)
+ }
+ if (right >= SCREEN_WIDTH) {
right = SCREEN_TEXTLIMIT_RIGHT;
- if (bottom >= SCREEN_HEIGHT)
+ }
+ if (bottom >= SCREEN_HEIGHT) {
bottom = SCREEN_TEXTLIMIT_BOTTOM;
+ }
- if (left > right || top > bottom)
+ if (left > right || top > bottom) {
return;
+ }
nextRedrawList[currNumOfRedrawBox].left = left;
nextRedrawList[currNumOfRedrawBox].top = top;
@@ -121,45 +126,39 @@ void Redraw::addRedrawArea(int32 left, int32 top, int32 right, int32 bottom) {
}
void Redraw::moveNextAreas() {
- int32 i;
-
numOfRedrawBox = 0;
- for (i = 0; i < currNumOfRedrawBox; i++) {
+ for (int32 i = 0; i < currNumOfRedrawBox; i++) {
addRedrawCurrentArea(nextRedrawList[i].left, nextRedrawList[i].top, nextRedrawList[i].right, nextRedrawList[i].bottom);
}
}
void Redraw::flipRedrawAreas() {
- int32 i;
-
- for (i = 0; i < numOfRedrawBox; i++) { // redraw areas on screen
+ for (int32 i = 0; i < numOfRedrawBox; i++) { // redraw areas on screen
_engine->copyBlockPhys(currentRedrawList[i].left, currentRedrawList[i].top, currentRedrawList[i].right, currentRedrawList[i].bottom);
}
numOfRedrawBox = 0;
- for (i = 0; i < currNumOfRedrawBox; i++) { //setup the redraw areas for next display
+ for (int32 i = 0; i < currNumOfRedrawBox; i++) { //setup the redraw areas for next display
addRedrawCurrentArea(nextRedrawList[i].left, nextRedrawList[i].top, nextRedrawList[i].right, nextRedrawList[i].bottom);
}
}
void Redraw::blitBackgroundAreas() {
- int32 i;
const RedrawStruct *currentArea = currentRedrawList;
- for (i = 0; i < numOfRedrawBox; i++) {
+ for (int32 i = 0; i < numOfRedrawBox; i++) {
_engine->_interface->blitBox(currentArea->left, currentArea->top, currentArea->right, currentArea->bottom, (const int8*)_engine->workVideoBuffer.getPixels(), currentArea->left, currentArea->top, (int8*)_engine->frontVideoBuffer.getPixels());
currentArea++;
}
}
void Redraw::sortDrawingList(DrawListStruct *list, int32 listSize) {
- DrawListStruct tempStruct;
-
for (int32 i = 0; i < listSize - 1; i++) {
for (int32 j = 0; j < listSize - 1 - i; j++) {
if (list[j + 1].posValue < list[j].posValue) {
+ DrawListStruct tempStruct;
memcpy(&tempStruct, &list[j + 1], sizeof(DrawListStruct));
memcpy(&list[j + 1], &list[j], sizeof(DrawListStruct));
memcpy(&list[j], &tempStruct, sizeof(DrawListStruct));
@@ -169,7 +168,7 @@ void Redraw::sortDrawingList(DrawListStruct *list, int32 listSize) {
}
void Redraw::addOverlay(int16 type, int16 info0, int16 x, int16 y, int16 info1, int16 posType, int16 lifeTime) {
- for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
+ for (int32 i = 0; i < ARRAYSIZE(overlayList); i++) {
OverlayListStruct *overlay = &overlayList[i];
if (overlay->info0 == -1) {
overlay->type = type;
@@ -188,7 +187,7 @@ void Redraw::updateOverlayTypePosition(int16 X1, int16 Y1, int16 X2, int16 Y2) {
const int16 newX = X2 - X1;
const int16 newY = Y2 - Y1;
- for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
+ for (int32 i = 0; i < ARRAYSIZE(overlayList); i++) {
OverlayListStruct *overlay = &overlayList[i];
if (overlay->type == koFollowActor) {
overlay->x = newX;
@@ -356,34 +355,34 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
_engine->_animations->setModelAnimation(actor2->animPosition, _engine->_animations->animTable[actor2->previousAnimIdx], _engine->_actor->bodyTable[actor2->entity], &actor2->animTimerData);
if (!_engine->_renderer->renderIsoModel(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
- if (renderLeft < 0)
+ if (renderLeft < 0) {
renderLeft = SCREEN_TEXTLIMIT_LEFT;
+ }
- if (renderTop < 0)
+ if (renderTop < 0) {
renderTop = SCREEN_TEXTLIMIT_TOP;
+ }
- if (renderRight >= SCREEN_WIDTH)
+ if (renderRight >= SCREEN_WIDTH) {
renderRight = SCREEN_TEXTLIMIT_RIGHT;
+ }
- if (renderBottom >= SCREEN_HEIGHT)
+ if (renderBottom >= SCREEN_HEIGHT) {
renderBottom = SCREEN_TEXTLIMIT_BOTTOM;
+ }
_engine->_interface->setClip(renderLeft, renderTop, renderRight, renderBottom);
if (_engine->_interface->textWindowLeft <= _engine->_interface->textWindowRight && _engine->_interface->textWindowTop <= _engine->_interface->textWindowBottom) {
- int32 tempX;
- int32 tempY;
- int32 tempZ;
-
actor2->dynamicFlags.bIsVisible = 1;
- tempX = (actor2->x + 0x100) >> 9;
- tempY = actor2->y >> 8;
-
- if (actor2->brickShape & 0x7F)
+ const int32 tempX = (actor2->x + 0x100) >> 9;
+ int32 tempY = actor2->y >> 8;
+ if (actor2->brickShape & 0x7F) {
tempY++;
+ }
- tempZ = (actor2->z + 0x100) >> 9;
+ const int32 tempZ = (actor2->z + 0x100) >> 9;
_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
@@ -402,12 +401,12 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
}
// Drawing shadows
else if (flags == 0xC00 && !_engine->_actor->cropBottomScreen) {
- int32 spriteWidth, spriteHeight, tmpX, tmpY, tmpZ;
DrawListStruct shadow = drawList[pos];
// get actor position on screen
_engine->_renderer->projectPositionOnScreen(shadow.x - _engine->_grid->cameraX, shadow.y - _engine->_grid->cameraY, shadow.z - _engine->_grid->cameraZ);
+ int32 spriteWidth, spriteHeight;
_engine->_grid->getSpriteSize(shadow.field_A, &spriteWidth, &spriteHeight, _engine->_scene->spriteShadowPtr);
// calculate sprite size and position on screen
@@ -422,9 +421,9 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
_engine->_grid->drawSprite(shadow.field_A, renderLeft, renderTop, _engine->_scene->spriteShadowPtr);
}
- tmpX = (shadow.x + 0x100) >> 9;
- tmpY = shadow.y >> 8;
- tmpZ = (shadow.z + 0x100) >> 9;
+ const int32 tmpX = (shadow.x + 0x100) >> 9;
+ const int32 tmpY = shadow.y >> 8;
+ const int32 tmpZ = (shadow.z + 0x100) >> 9;
_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
@@ -467,14 +466,12 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
if (actor2->staticFlags.bUsesClipping) {
_engine->_grid->drawOverSpriteActor((actor2->lastX + 0x100) >> 9, actor2->lastY >> 8, (actor2->lastZ + 0x100) >> 9);
} else {
- int32 tmpX, tmpY, tmpZ;
-
- tmpX = (actor2->x + actor2->boudingBox.x.topRight + 0x100) >> 9;
- tmpY = actor2->y >> 8;
+ const int32 tmpX = (actor2->x + actor2->boudingBox.x.topRight + 0x100) >> 9;
+ int32 tmpY = actor2->y >> 8;
if (actor2->brickShape & 0x7F) {
tmpY++;
}
- tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
+ const int32 tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
}
@@ -499,7 +496,6 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
_engine->_extra->drawExtraSpecial(actorIdx, _engine->_renderer->projPosX, _engine->_renderer->projPosY);
} else {
int32 spriteWidth, spriteHeight;
-
_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, _engine->_actor->spriteTable[extra->info0]);
// calculate sprite position on screen
@@ -514,11 +510,9 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
_engine->_interface->setClip(renderLeft, renderTop, renderRight, renderBottom);
if (_engine->_interface->textWindowLeft <= _engine->_interface->textWindowRight && _engine->_interface->textWindowTop <= _engine->_interface->textWindowBottom) {
- int32 tmpX, tmpY, tmpZ;
-
- tmpX = (drawList[pos].x + 0x100) >> 9;
- tmpY = drawList[pos].y >> 8;
- tmpZ = (drawList[pos].z + 0x100) >> 9;
+ const int32 tmpX = (drawList[pos].x + 0x100) >> 9;
+ const int32 tmpY = drawList[pos].y >> 8;
+ const int32 tmpZ = (drawList[pos].z + 0x100) >> 9;
_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
addRedrawArea(_engine->_interface->textWindowLeft, _engine->_interface->textWindowTop, renderRight, renderBottom);
diff --git a/engines/twine/scene.cpp b/engines/twine/scene.cpp
index df4d719a48..077069a969 100644
--- a/engines/twine/scene.cpp
+++ b/engines/twine/scene.cpp
@@ -326,10 +326,11 @@ void Scene::changeScene() {
initScene(needChangeScene);
- //TODO: treat holomap trajectories
+ // TODO: treat holomap trajectories
- if (needChangeScene == 116 || needChangeScene == 117)
+ if (needChangeScene == 116 || needChangeScene == 117) {
_engine->_text->currentTextBank = 10;
+ }
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
_engine->_grid->initGrid(needChangeScene);
Commit: a8762fca13c46899a64b2e983dce864bdb48854f
https://github.com/scummvm/scummvm/commit/a8762fca13c46899a64b2e983dce864bdb48854f
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: sanity checks
Changed paths:
engines/twine/grid.cpp
engines/twine/grid.h
diff --git a/engines/twine/grid.cpp b/engines/twine/grid.cpp
index 9d4dc0ee6b..4d3b33a693 100644
--- a/engines/twine/grid.cpp
+++ b/engines/twine/grid.cpp
@@ -303,6 +303,9 @@ int32 Grid::loadGridBricks(int32 gridSize) {
for (uint32 i = firstBrick; i <= lastBrick; i++) {
if (brickUsageTable[i]) {
brickSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&brickTable[i], Resources::HQR_LBA_BRK_FILE, i);
+ if (brickSizeTable[i] == 0) {
+ warning("Failed to load isometric brick index %i", i);
+ }
}
}
@@ -423,20 +426,20 @@ bool Grid::initGrid(int32 index) {
return true;
}
-int32 Grid::initCellingGrid(int32 index) {
- uint8 *gridPtr;
+bool Grid::initCellingGrid(int32 index) {
+ uint8 *gridPtr = nullptr;
// load grids from file
- _engine->_hqrdepack->hqrGetallocEntry(&gridPtr, Resources::HQR_LBA_GRI_FILE, index + CELLING_GRIDS_START_INDEX);
+ const int realIndex = index + CELLING_GRIDS_START_INDEX;
+ if (_engine->_hqrdepack->hqrGetallocEntry(&gridPtr, Resources::HQR_LBA_GRI_FILE, realIndex) == 0) {
+ warning("Failed to load grid index %i", realIndex);
+ return false;
+ }
createCellingGridMap(gridPtr);
-
- if (gridPtr)
- free(gridPtr);
-
+ free(gridPtr);
_engine->_redraw->reqBgRedraw = true;
-
- return 0;
+ return true;
}
void Grid::drawBrick(int32 index, int32 posX, int32 posY) {
diff --git a/engines/twine/grid.h b/engines/twine/grid.h
index 97a4eb6876..e6ac3565e3 100644
--- a/engines/twine/grid.h
+++ b/engines/twine/grid.h
@@ -268,7 +268,7 @@ public:
* Initialize celling grid (background scenearios)
* @param index grid index number
*/
- int32 initCellingGrid(int32 index);
+ bool initCellingGrid(int32 index);
/** Redraw grid background */
void redrawGrid();
Commit: c8a12ef17800db81dd44119ecc34dfbde425b12d
https://github.com/scummvm/scummvm/commit/c8a12ef17800db81dd44119ecc34dfbde425b12d
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: reduced scope + cleanup
Changed paths:
engines/twine/grid.cpp
diff --git a/engines/twine/grid.cpp b/engines/twine/grid.cpp
index 4d3b33a693..d09e2b739b 100644
--- a/engines/twine/grid.cpp
+++ b/engines/twine/grid.cpp
@@ -301,11 +301,12 @@ int32 Grid::loadGridBricks(int32 gridSize) {
}
for (uint32 i = firstBrick; i <= lastBrick; i++) {
- if (brickUsageTable[i]) {
- brickSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&brickTable[i], Resources::HQR_LBA_BRK_FILE, i);
- if (brickSizeTable[i] == 0) {
- warning("Failed to load isometric brick index %i", i);
- }
+ if (!brickUsageTable[i]) {
+ continue;
+ }
+ brickSizeTable[i] = _engine->_hqrdepack->hqrGetallocEntry(&brickTable[i], Resources::HQR_LBA_BRK_FILE, i);
+ if (brickSizeTable[i] == 0) {
+ warning("Failed to load isometric brick index %i", i);
}
}
@@ -452,11 +453,9 @@ void Grid::drawSprite(int32 index, int32 posX, int32 posY, uint8 *ptr) {
// WARNING: Rewrite this function to have better performance
void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, uint8 *ptr, bool isSprite) {
- //unsigned char *ptr;
- uint8 *outPtr;
-
- if (isSprite)
+ if (isSprite) {
ptr = ptr + *((uint32 *)(ptr + index * 4));
+ }
int32 left = posX + *(ptr + 2);
int32 top = posY + *(ptr + 3);
@@ -473,7 +472,7 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, uint8 *ptr, bool
right++;
bottom++;
- outPtr = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
+ uint8 *outPtr = (uint8 *)_engine->frontVideoBuffer.getPixels() + _engine->screenLookupTable[top] + left;
int32 offset = -((right - left) - SCREEN_WIDTH);
@@ -528,44 +527,41 @@ void Grid::getBrickPos(int32 x, int32 y, int32 z) {
}
void Grid::drawColumnGrid(int32 blockIdx, int32 brickBlockIdx, int32 x, int32 y, int32 z) {
- uint8 *blockPtr;
- uint16 brickIdx;
- uint8 brickShape;
- uint8 brickSound;
- int32 brickBuffIdx;
- BrickEntry *currBrickEntry;
-
- blockPtr = getBlockLibrary(blockIdx) + 3 + brickBlockIdx * 4;
-
- brickShape = *((uint8 *)(blockPtr));
- brickSound = *((uint8 *)(blockPtr + 1));
- brickIdx = *((uint16 *)(blockPtr + 2));
+ uint8 *blockPtr = getBlockLibrary(blockIdx) + 3 + brickBlockIdx * 4;
- if (!brickIdx)
+ uint8 brickShape = *((uint8 *)(blockPtr + 0));
+ uint8 brickSound = *((uint8 *)(blockPtr + 1));
+ uint16 brickIdx = *((uint16 *)(blockPtr + 2));
+ if (!brickIdx) {
return;
+ }
getBrickPos(x - newCameraX, y - newCameraY, z - newCameraZ);
- if (brickPixelPosX < -24)
+ if (brickPixelPosX < -24) {
return;
- if (brickPixelPosX >= SCREEN_WIDTH)
+ }
+ if (brickPixelPosX >= SCREEN_WIDTH) {
return;
- if (brickPixelPosY < -38)
+ }
+ if (brickPixelPosY < -38) {
return;
- if (brickPixelPosY >= SCREEN_HEIGHT)
+ }
+ if (brickPixelPosY >= SCREEN_HEIGHT) {
return;
+ }
// draw the background brick
drawBrick(brickIdx - 1, brickPixelPosX, brickPixelPosY);
- brickBuffIdx = (brickPixelPosX + 24) / 24;
+ int32 brickBuffIdx = (brickPixelPosX + 24) / 24;
if (brickInfoBuffer[brickBuffIdx] >= 150) {
- warning("\nGRID WARNING: brick buffer exceeded! \n");
+ warning("GRID WARNING: brick buffer exceeded");
return;
}
- currBrickEntry = &bricksDataBuffer[brickBuffIdx][brickInfoBuffer[brickBuffIdx]];
+ BrickEntry *currBrickEntry = &bricksDataBuffer[brickBuffIdx][brickInfoBuffer[brickBuffIdx]];
currBrickEntry->x = x;
currBrickEntry->y = y;
@@ -591,12 +587,11 @@ void Grid::redrawGrid() {
_engine->_renderer->projPosXScreen = _engine->_renderer->projPosX;
_engine->_renderer->projPosYScreen = _engine->_renderer->projPosY;
- for (int32 i = 0; i < 28; i++) {
- brickInfoBuffer[i] = 0;
- }
+ memset(brickInfoBuffer, 0, sizeof(brickInfoBuffer));
- if (_engine->_scene->changeRoomVar10 == 0)
+ if (_engine->_scene->changeRoomVar10 == 0) {
return;
+ }
for (int32 z = 0; z < GRID_SIZE_Z; z++) {
for (int32 x = 0; x < GRID_SIZE_X; x++) {
@@ -610,30 +605,30 @@ void Grid::redrawGrid() {
}
}
-int32 Grid::getBrickShape(int32 x, int32 y, int32 z) { // WorldColBrick
- uint8 blockIdx;
- uint8 *blockBufferPtr;
-
- blockBufferPtr = blockBuffer;
+int32 Grid::getBrickShape(int32 x, int32 y, int32 z) {
+ uint8 *blockBufferPtr = blockBuffer;
_engine->_collision->collisionX = (x + 0x100) >> 9;
_engine->_collision->collisionY = y >> 8;
_engine->_collision->collisionZ = (z + 0x100) >> 9;
- if (_engine->_collision->collisionX < 0 || _engine->_collision->collisionX >= 64)
+ if (_engine->_collision->collisionX < 0 || _engine->_collision->collisionX >= 64) {
return 0;
+ }
- if (_engine->_collision->collisionY <= -1)
+ if (_engine->_collision->collisionY <= -1) {
return 1;
+ }
- if (_engine->_collision->collisionY < 0 || _engine->_collision->collisionY > 24 || _engine->_collision->collisionZ < 0 || _engine->_collision->collisionZ >= 64)
+ if (_engine->_collision->collisionY < 0 || _engine->_collision->collisionY > 24 || _engine->_collision->collisionZ < 0 || _engine->_collision->collisionZ >= 64) {
return 0;
+ }
blockBufferPtr += _engine->_collision->collisionX * 50;
blockBufferPtr += _engine->_collision->collisionY * 2;
blockBufferPtr += (_engine->_collision->collisionZ << 7) * 25;
- blockIdx = *blockBufferPtr;
+ uint8 blockIdx = *blockBufferPtr;
if (blockIdx) {
uint8 *blockPtr;
@@ -653,30 +648,29 @@ int32 Grid::getBrickShape(int32 x, int32 y, int32 z) { // WorldColBrick
}
int32 Grid::getBrickShapeFull(int32 x, int32 y, int32 z, int32 y2) {
- int32 newY, currY, i;
- uint8 blockIdx, brickShape;
- uint8 *blockBufferPtr;
-
- blockBufferPtr = blockBuffer;
+ uint8 *blockBufferPtr = blockBuffer;
_engine->_collision->collisionX = (x + 0x100) >> 9;
_engine->_collision->collisionY = y >> 8;
_engine->_collision->collisionZ = (z + 0x100) >> 9;
- if (_engine->_collision->collisionX < 0 || _engine->_collision->collisionX >= 64)
+ if (_engine->_collision->collisionX < 0 || _engine->_collision->collisionX >= 64) {
return 0;
+ }
- if (_engine->_collision->collisionY <= -1)
+ if (_engine->_collision->collisionY <= -1) {
return 1;
+ }
- if (_engine->_collision->collisionY < 0 || _engine->_collision->collisionY > 24 || _engine->_collision->collisionZ < 0 || _engine->_collision->collisionZ >= 64)
+ if (_engine->_collision->collisionY < 0 || _engine->_collision->collisionY > 24 || _engine->_collision->collisionZ < 0 || _engine->_collision->collisionZ >= 64) {
return 0;
+ }
blockBufferPtr += _engine->_collision->collisionX * 50;
blockBufferPtr += _engine->_collision->collisionY * 2;
blockBufferPtr += (_engine->_collision->collisionZ << 7) * 25;
- blockIdx = *blockBufferPtr;
+ uint8 blockIdx = *blockBufferPtr;
if (blockIdx) {
uint8 *blockPtr = currentBll;
@@ -687,12 +681,12 @@ int32 Grid::getBrickShapeFull(int32 x, int32 y, int32 z, int32 y2) {
uint8 tmpBrickIdx = *(blockBufferPtr + 1);
blockPtr = blockPtr + tmpBrickIdx * 4;
- brickShape = *blockPtr;
+ uint8 brickShape = *blockPtr;
- newY = (y2 + 255) >> 8;
- currY = _engine->_collision->collisionY;
+ int32 newY = (y2 + 255) >> 8;
+ int32 currY = _engine->_collision->collisionY;
- for (i = 0; i < newY; i++) {
+ for (int32 i = 0; i < newY; i++) {
if (currY > 24) {
return brickShape;
}
@@ -707,12 +701,12 @@ int32 Grid::getBrickShapeFull(int32 x, int32 y, int32 z, int32 y2) {
return brickShape;
}
- brickShape = *(blockBufferPtr + 1);
+ uint8 brickShape = *(blockBufferPtr + 1);
- newY = (y2 + 255) >> 8;
- currY = _engine->_collision->collisionY;
+ int32 newY = (y2 + 255) >> 8;
+ int32 currY = _engine->_collision->collisionY;
- for (i = 0; i < newY; i++) {
+ for (int32 i = 0; i < newY; i++) {
if (currY > 24) {
return brickShape;
}
@@ -729,29 +723,29 @@ int32 Grid::getBrickShapeFull(int32 x, int32 y, int32 z, int32 y2) {
}
int32 Grid::getBrickSoundType(int32 x, int32 y, int32 z) { // getPos2
- uint8 blockIdx;
- uint8 *blockBufferPtr;
-
- blockBufferPtr = blockBuffer;
+ uint8 *blockBufferPtr = blockBuffer;
_engine->_collision->collisionX = (x + 0x100) >> 9;
_engine->_collision->collisionY = y >> 8;
_engine->_collision->collisionZ = (z + 0x100) >> 9;
- if (_engine->_collision->collisionX < 0 || _engine->_collision->collisionX >= 64)
+ if (_engine->_collision->collisionX < 0 || _engine->_collision->collisionX >= 64) {
return 0;
+ }
- if (_engine->_collision->collisionY <= -1)
+ if (_engine->_collision->collisionY <= -1) {
return 1;
+ }
- if (_engine->_collision->collisionY < 0 || _engine->_collision->collisionY > 24 || _engine->_collision->collisionZ < 0 || _engine->_collision->collisionZ >= 64)
+ if (_engine->_collision->collisionY < 0 || _engine->_collision->collisionY > 24 || _engine->_collision->collisionZ < 0 || _engine->_collision->collisionZ >= 64) {
return 0;
+ }
blockBufferPtr += _engine->_collision->collisionX * 50;
blockBufferPtr += _engine->_collision->collisionY * 2;
blockBufferPtr += (_engine->_collision->collisionZ << 7) * 25;
- blockIdx = *blockBufferPtr;
+ uint8 blockIdx = *blockBufferPtr;
if (blockIdx) {
uint8 *blockPtr;
Commit: 600f796e572b0f3bd8d0c1cfd8409edea1c32ffd
https://github.com/scummvm/scummvm/commit/600f796e572b0f3bd8d0c1cfd8409edea1c32ffd
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: don't show the ui if you abort the intro movie
Changed paths:
engines/twine/flamovies.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 78e3c0c313..19f550cd1d 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -311,7 +311,7 @@ void FlaMovies::playFlaMovie(const char *flaName) {
currentFrame++;
_engine->_system->delayMillis(1000 / flaHeaderData.speed + 1);
- } while (!_engine->_input->isActionActive(TwinEActionType::CutsceneAbort));
+ } while (!_engine->_input->toggleAbortAction());
}
if (_engine->cfgfile.CrossFade) {
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 900f3c3c4d..35c61aa336 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -828,8 +828,8 @@ void TwinEEngine::flip() {
}
void TwinEEngine::copyBlockPhys(int32 left, int32 top, int32 right, int32 bottom) {
- assert(left < right);
- assert(top < bottom);
+ assert(left <= right);
+ assert(top <= bottom);
#if 0
// TODO: fix this - looks like the palette includes a color key at pos 0
g_system->copyRectToScreen(frontVideoBuffer.getPixels(), frontVideoBuffer.pitch, left, top, right - left + 1, bottom - top + 1);
Commit: a6117c289777eec7e490f3a0553a00f6973bddef
https://github.com/scummvm/scummvm/commit/a6117c289777eec7e490f3a0553a00f6973bddef
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: connect more keymapper events to their in-game actions
Changed paths:
engines/twine/menu.cpp
engines/twine/movements.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index a885543b67..c6069251d4 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -890,9 +890,9 @@ void Menu::processBehaviourMenu() {
int heroBehaviour = (int)_engine->_actor->heroBehaviour;
if (_engine->_input->toggleActionIfActive(TwinEActionType::TurnLeft)) {
- heroBehaviour++;
- } else if (_engine->_input->toggleActionIfActive(TwinEActionType::TurnRight)) {
heroBehaviour--;
+ } else if (_engine->_input->toggleActionIfActive(TwinEActionType::TurnRight)) {
+ heroBehaviour++;
}
if (heroBehaviour < kNormal) {
@@ -1076,7 +1076,7 @@ void Menu::processInventoryMenu() {
_engine->_system->delayMillis(15);
}
- if (_engine->loopPressedKey & 1) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UIUp)) {
if (bx == 2) {
_engine->_text->initInventoryDialogueBox();
bx = 0;
@@ -1090,7 +1090,7 @@ void Menu::processInventoryMenu() {
drawItem(inventorySelectedItem);
- if ((_engine->loopPressedKey & 2) && _engine->_gameState->gameFlags[inventorySelectedItem] == 1 && !_engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED] && inventorySelectedItem < NUM_INVENTORY_ITEMS) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown) && _engine->_gameState->gameFlags[inventorySelectedItem] == 1 && !_engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED] && inventorySelectedItem < NUM_INVENTORY_ITEMS) {
_engine->loopInventoryItem = inventorySelectedItem;
inventorySelectedColor = 91;
drawItem(inventorySelectedItem);
diff --git a/engines/twine/movements.cpp b/engines/twine/movements.cpp
index 7097b37e04..a72b23c30c 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/movements.cpp
@@ -265,23 +265,22 @@ void Movements::processActorMovements(int32 actorIdx) {
return;
if (actor->dynamicFlags.bIsFalling) {
- int16 tempAngle = 0;
- if (actor->controlMode != 1)
+ if (actor->controlMode != 1) {
return;
+ }
- if (_engine->_input->key & 4)
+ int16 tempAngle = 0;
+ if (_engine->_input->isActionActive(TwinEActionType::TurnLeft)) {
tempAngle = 0x100;
-
- if (_engine->_input->key & 8)
+ } else if (_engine->_input->isActionActive(TwinEActionType::TurnRight)) {
tempAngle = -0x100;
+ }
moveActor(actor->angle, actor->angle + tempAngle, actor->speed, &actor->move);
_engine->_input->heroPressedKey = _engine->_input->key;
} else {
- int16 tempAngle;
-
if (!actor->staticFlags.bIsSpriteActor) {
if (actor->controlMode != kManual) {
actor->angle = getRealAngle(&actor->move);
@@ -296,24 +295,24 @@ void Movements::processActorMovements(int32 actorIdx) {
heroAction = 0;
// If press W for action
- if (_engine->_input->internalKeyCode == 0x11) {
+ if (_engine->_input->isActionActive(TwinEActionType::SpecialAction)) {
heroAction = 1;
}
// Process hero actions
switch (_engine->_actor->heroBehaviour) {
case kNormal:
- if (_engine->loopPressedKey & 1) {
+ if (_engine->_input->isActionActive(TwinEActionType::ExecuteBehaviourAction)) {
heroAction = 1;
}
break;
case kAthletic:
- if (_engine->loopPressedKey & 1) {
+ if (_engine->_input->isActionActive(TwinEActionType::ExecuteBehaviourAction)) {
_engine->_animations->initAnim(kJump, 1, 0, actorIdx);
}
break;
case kAggressive:
- if (_engine->loopPressedKey & 1) {
+ if (_engine->_input->isActionActive(TwinEActionType::ExecuteBehaviourAction)) {
if (_engine->_actor->autoAgressive) {
heroMoved = 1;
actor->angle = getRealAngle(&actor->move);
@@ -333,22 +332,22 @@ void Movements::processActorMovements(int32 actorIdx) {
}
}
} else {
- if (_engine->_input->key & 8) {
+ if (_engine->_input->isActionActive(TwinEActionType::TurnRight)) {
_engine->_animations->initAnim(kRightPunch, 1, 0, actorIdx);
}
- if (_engine->_input->key & 4) {
+ if (_engine->_input->isActionActive(TwinEActionType::TurnLeft)) {
_engine->_animations->initAnim(kLeftPunch, 1, 0, actorIdx);
}
- if (_engine->_input->key & 1) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::MoveForward)) {
_engine->_animations->initAnim(kKick, 1, 0, actorIdx);
}
}
}
break;
case kDiscrete:
- if (_engine->loopPressedKey & 1) {
+ if (_engine->_input->isActionActive(TwinEActionType::ExecuteBehaviourAction)) {
_engine->_animations->initAnim(kHide, 0, 255, actorIdx);
}
break;
@@ -357,7 +356,7 @@ void Movements::processActorMovements(int32 actorIdx) {
}
}
- if ((_engine->loopPressedKey & 8) && !_engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED]) {
+ if (_engine->_input->isActionActive(TwinEActionType::ThrowMagicBall) && !_engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED]) {
if (_engine->_gameState->usingSabre == 0) { // Use Magic Ball
if (_engine->_gameState->gameFlags[InventoryItems::kiMagicBall]) {
if (_engine->_gameState->magicBallIdx == -1) {
@@ -382,8 +381,8 @@ void Movements::processActorMovements(int32 actorIdx) {
}
if (!_engine->loopPressedKey || heroAction) {
-
- if (_engine->_input->key & 3) { // if continue walking
+ // if continue walking
+ if (_engine->_input->isActionActive(TwinEActionType::MoveForward) || _engine->_input->isActionActive(TwinEActionType::MoveBackward)) {
heroMoved = 0; // don't break animation
}
@@ -395,19 +394,17 @@ void Movements::processActorMovements(int32 actorIdx) {
heroMoved = 0;
- if (_engine->_input->key & 1) { // walk forward
+ if (_engine->_input->isActionActive(TwinEActionType::MoveForward)) { // walk forward
if (!_engine->_scene->currentActorInZone) {
_engine->_animations->initAnim(kForward, 0, 255, actorIdx);
}
heroMoved = 1;
- }
-
- if (_engine->_input->key & 2 && !(_engine->_input->key & 1)) { // walk backward
+ } else if (_engine->_input->isActionActive(TwinEActionType::MoveBackward)) { // walk backward
_engine->_animations->initAnim(kBackward, 0, 255, actorIdx);
heroMoved = 1;
}
- if (_engine->_input->key & 4) { // turn left
+ if (_engine->_input->isActionActive(TwinEActionType::TurnLeft)) {
heroMoved = 1;
if (actor->anim == 0) {
_engine->_animations->initAnim(kTurnLeft, 0, 255, actorIdx);
@@ -416,9 +413,7 @@ void Movements::processActorMovements(int32 actorIdx) {
actor->angle = getRealAngle(&actor->move);
}
}
- }
-
- if (_engine->_input->key & 8) { // turn right
+ } else if (_engine->_input->isActionActive(TwinEActionType::TurnRight)) {
heroMoved = 1;
if (actor->anim == 0) {
_engine->_animations->initAnim(kTurnRight, 0, 255, actorIdx);
@@ -430,14 +425,13 @@ void Movements::processActorMovements(int32 actorIdx) {
}
}
- tempAngle = 0;
-
- if (_engine->_input->key & 4) {
+ int16 tempAngle;
+ if (_engine->_input->isActionActive(TwinEActionType::TurnLeft)) {
tempAngle = 0x100;
- }
-
- if (_engine->_input->key & 8) {
+ } else if (_engine->_input->isActionActive(TwinEActionType::TurnRight)) {
tempAngle = -0x100;
+ } else {
+ tempAngle = 0;
}
moveActor(actor->angle, actor->angle + tempAngle, actor->speed, &actor->move);
@@ -482,7 +476,8 @@ void Movements::processActorMovements(int32 actorIdx) {
}
}
}
- } break;
+ break;
+ }
default:
warning("Unknown Control mode %d\n", actor->controlMode);
break;
Commit: 235ba116fc48aed015a0e68aa23ea66e46c179ec
https://github.com/scummvm/scummvm/commit/235ba116fc48aed015a0e68aa23ea66e46c179ec
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: doxygen
Changed paths:
engines/twine/actor.h
diff --git a/engines/twine/actor.h b/engines/twine/actor.h
index f849f25995..7e5eafa8e7 100644
--- a/engines/twine/actor.h
+++ b/engines/twine/actor.h
@@ -298,36 +298,48 @@ public:
/** Load hero 3D body and animations */
void loadHeroEntities();
- /** Set hero behaviour
- @param behaviour behaviour value to set */
+ /**
+ * Set hero behaviour
+ * @param behaviour behaviour value to set
+ */
void setBehaviour(int32 behaviour);
- /** Initialize 3D actor body
- @param bodyIdx 3D actor body index
- @param actorIdx 3D actor index */
+ /**
+ * Initialize 3D actor body
+ * @param bodyIdx 3D actor body index
+ * @param actorIdx 3D actor index
+ */
int32 initBody(int32 bodyIdx, int32 actorIdx);
/** Preload all sprites */
void preloadSprites();
- /** Initialize 3D actor
- @param bodyIdx 3D actor body index
- @param actorIdx 3D actor index */
+ /**
+ * Initialize 3D actor
+ * @param bodyIdx 3D actor body index
+ * @param actorIdx 3D actor index
+ */
void initModelActor(int32 bodyIdx, int16 actorIdx);
- /** Initialize actors
- @param actorIdx actor index to init */
+ /**
+ * Initialize actors
+ * @param actorIdx actor index to init
+ */
void initActor(int16 actorIdx);
- /** Reset actor
- @param actorIdx actor index to init */
+ /**
+ * Reset actor
+ * @param actorIdx actor index to init
+ */
void resetActor(int16 actorIdx);
- /** Process hit actor
- @param actorIdx actor hitting index
- @param actorIdxAttacked actor attacked index
- @param strengthOfHit actor hitting strength of hit
- @param angle angle of actor hitting */
+ /**
+ * Process hit actor
+ * @param actorIdx actor hitting index
+ * @param actorIdxAttacked actor attacked index
+ * @param strengthOfHit actor hitting strength of hit
+ * @param angle angle of actor hitting
+ */
void hitActor(int32 actorIdx, int32 actorIdxAttacked, int32 strengthOfHit, int32 angle);
/** Process actor carrier */
Commit: a1e43850d11b926a46825ca5dff057c59cfb858b
https://github.com/scummvm/scummvm/commit/a1e43850d11b926a46825ca5dff057c59cfb858b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: cleanup and more keymapper actions connected
Changed paths:
engines/twine/extra.cpp
engines/twine/input.h
engines/twine/menu.cpp
engines/twine/menuoptions.cpp
engines/twine/movements.cpp
engines/twine/movements.h
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/extra.cpp b/engines/twine/extra.cpp
index 22231b77ae..09bef1b3d1 100644
--- a/engines/twine/extra.cpp
+++ b/engines/twine/extra.cpp
@@ -25,6 +25,7 @@
#include "twine/collision.h"
#include "twine/gamestate.h"
#include "twine/grid.h"
+#include "twine/input.h"
#include "twine/interface.h"
#include "twine/movements.h"
#include "twine/redraw.h"
@@ -861,9 +862,9 @@ void Extra::processExtras() {
// if hero touch extra
if (_engine->_collision->checkExtraCollisionWithActors(extra, -1) == 0) {
// FIXME: add constant for sample index
- _engine->_sound->playSample(97, 0x1000, 1, extra->x, extra->y, extra->z, -1);
+ _engine->_sound->playSample(97, 4096, 1, extra->x, extra->y, extra->z);
- if (extra->info1 > 1 && !(_engine->loopPressedKey & 2)) {
+ if (extra->info1 > 1 && !_engine->_input->isActionActive(TwinEActionType::MoveBackward)) {
_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
_engine->_redraw->addOverlay(koNumber, extra->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, 158, koNormal, 2);
}
diff --git a/engines/twine/input.h b/engines/twine/input.h
index 442ef384f8..fed8d80baa 100644
--- a/engines/twine/input.h
+++ b/engines/twine/input.h
@@ -167,8 +167,6 @@ public:
int16 internalKeyCode = 0;
int16 currentKey = 0;
int16 key = 0;
- int32 heroPressedKey = 0;
- int32 heroPressedKey2 = 0;
int16 leftMouse = 0;
int16 rightMouse = 0;
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index c6069251d4..4406567104 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -447,7 +447,6 @@ int32 Menu::processMenu(int16 *menuSettings) {
_engine->_screens->loadMenuImage(false);
do {
_engine->readKeys();
- _engine->_input->key = _engine->_input->pressedKey;
if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown)) {
currentButton++;
@@ -972,7 +971,6 @@ void Menu::drawInventoryItems() {
}
void Menu::processInventoryMenu() {
- int32 di = 1;
int32 tmpAlphaLight = _engine->_scene->alphaLight;
int32 tmpBetaLight = _engine->_scene->betaLight;
@@ -1000,25 +998,9 @@ void Menu::processInventoryMenu() {
_engine->readKeys();
int32 prevSelectedItem = inventorySelectedItem;
- if (!di) {
- _engine->_input->key = _engine->_input->pressedKey;
- _engine->loopPressedKey = _engine->_input->skippedKey;
- _engine->loopCurrentKey = _engine->_input->internalKeyCode;
-
- if (_engine->_input->key != 0 || _engine->_input->skippedKey != 0) {
- di = 1;
- }
- } else {
- _engine->loopCurrentKey = 0;
- _engine->_input->key = 0;
- _engine->loopPressedKey = 0;
- if (!_engine->_input->pressedKey && !_engine->_input->skippedKey) {
- di = 0;
- }
- }
-
- if (_engine->loopCurrentKey == 1 || _engine->loopPressedKey & 0x20)
+ if (_engine->_input->toggleAbortAction() || _engine->_input->isActionActive(TwinEActionType::ExecuteBehaviourAction)) {
break;
+ }
if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown)) {
inventorySelectedItem++;
@@ -1107,7 +1089,7 @@ void Menu::processInventoryMenu() {
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
- while (_engine->_input->internalKeyCode != 0 && _engine->_input->skippedKey != 0) {
+ while (!_engine->_input->toggleAbortAction()) {
_engine->readKeys();
_engine->_system->delayMillis(1);
_engine->flip(); // TODO: needed?
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index f5cfd3d71a..1efca7fec0 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -93,10 +93,8 @@ void MenuOptions::newGame() {
}
void MenuOptions::showCredits() {
- int32 tmpShadowMode;
-
canShowCredits = 1;
- tmpShadowMode = _engine->cfgfile.ShadowMode;
+ int32 tmpShadowMode = _engine->cfgfile.ShadowMode;
_engine->cfgfile.ShadowMode = 0;
_engine->_gameState->initEngineVars();
_engine->_scene->currentSceneIdx = 119;
@@ -229,21 +227,6 @@ void MenuOptions::newGameMenu() {
if (_engine->gameEngineLoop()) {
showCredits();
}
-
- _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- // TODO: recheck this
- do {
- _engine->readKeys();
- do {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
- break;
- }
- } while (_engine->_input->skippedKey != 0);
- if (_engine->shouldQuit()) {
- break;
- }
- } while (_engine->_input->internalKeyCode != 0);
}
}
diff --git a/engines/twine/movements.cpp b/engines/twine/movements.cpp
index a72b23c30c..3f373e465a 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/movements.cpp
@@ -279,7 +279,7 @@ void Movements::processActorMovements(int32 actorIdx) {
moveActor(actor->angle, actor->angle + tempAngle, actor->speed, &actor->move);
- _engine->_input->heroPressedKey = _engine->_input->key;
+ heroPressedKey = _engine->_input->key;
} else {
if (!actor->staticFlags.bIsSpriteActor) {
if (actor->controlMode != kManual) {
@@ -386,7 +386,7 @@ void Movements::processActorMovements(int32 actorIdx) {
heroMoved = 0; // don't break animation
}
- if (_engine->_input->key != _engine->_input->heroPressedKey || _engine->loopPressedKey != _engine->_input->heroPressedKey2) {
+ if (_engine->_input->key != heroPressedKey || _engine->loopPressedKey != heroPressedKey2) {
if (heroMoved) {
_engine->_animations->initAnim(kStanding, 0, 255, actorIdx);
}
@@ -436,8 +436,8 @@ void Movements::processActorMovements(int32 actorIdx) {
moveActor(actor->angle, actor->angle + tempAngle, actor->speed, &actor->move);
- _engine->_input->heroPressedKey = _engine->_input->key;
- _engine->_input->heroPressedKey2 = _engine->loopPressedKey;
+ heroPressedKey = _engine->_input->key;
+ heroPressedKey2 = _engine->loopPressedKey;
break;
case kFollow: {
diff --git a/engines/twine/movements.h b/engines/twine/movements.h
index dea9d79d07..1ea548709b 100644
--- a/engines/twine/movements.h
+++ b/engines/twine/movements.h
@@ -45,6 +45,10 @@ class TwinEEngine;
class Movements {
private:
TwinEEngine *_engine;
+
+ int32 heroPressedKey = 0;
+ int32 heroPressedKey2 = 0;
+
public:
Movements(TwinEEngine *engine);
/** Hero moved */
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 35c61aa336..16e1baac02 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -339,9 +339,8 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
previousLoopPressedKey = loopPressedKey;
_input->key = _input->pressedKey;
loopPressedKey = _input->skippedKey;
- loopCurrentKey = _input->internalKeyCode;
- _debug->processDebug(loopCurrentKey);
+ _debug->processDebug(_input->internalKeyCode);
if (_menuOptions->canShowCredits != 0) {
// TODO: if current music playing != 8, than play_track(8);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 3505e0444b..67c3fbe3c5 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -228,7 +228,6 @@ public:
int32 loopPressedKey = 0;
int32 previousLoopPressedKey = 0;
- int32 loopCurrentKey = 0;
int32 loopInventoryItem = 0;
int32 loopActorStep = 0;
Commit: 764640ac74f02584412da7d7785def5eb67edd13
https://github.com/scummvm/scummvm/commit/764640ac74f02584412da7d7785def5eb67edd13
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: connect more keymapper actions
Changed paths:
engines/twine/debug.cpp
engines/twine/debug.h
engines/twine/debug_grid.cpp
engines/twine/debug_grid.h
engines/twine/debug_scene.cpp
engines/twine/debug_scene.h
engines/twine/gamestate.cpp
engines/twine/input.h
engines/twine/menuoptions.cpp
engines/twine/redraw.cpp
engines/twine/script_life.cpp
engines/twine/text.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 9964f3f2c6..13861d66eb 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -483,15 +483,15 @@ void Debug::debugProcessWindow() {
}
}
-void Debug::processDebug(int16 pKey) {
+void Debug::processDebug() {
if (!_engine->cfgfile.Debug) {
return;
}
debugProcessWindow();
- _engine->_debugGrid->changeGrid(pKey);
- _engine->_debugGrid->changeGridCamera(pKey);
- _engine->_debugGrid->applyCellingGrid(pKey);
+ _engine->_debugGrid->changeGrid();
+ _engine->_debugGrid->changeGridCamera();
+ _engine->_debugGrid->applyCellingGrid();
}
} // namespace TwinE
diff --git a/engines/twine/debug.h b/engines/twine/debug.h
index 1ae44a7f36..92b5534bf7 100644
--- a/engines/twine/debug.h
+++ b/engines/twine/debug.h
@@ -108,7 +108,7 @@ private:
public:
Debug(TwinEEngine *engine) : _engine(engine) {}
- void processDebug(int16 pKey);
+ void processDebug();
};
} // namespace TwinE
diff --git a/engines/twine/debug_grid.cpp b/engines/twine/debug_grid.cpp
index a860775951..53e3a1e84a 100644
--- a/engines/twine/debug_grid.cpp
+++ b/engines/twine/debug_grid.cpp
@@ -34,40 +34,41 @@ DebugGrid::DebugGrid(TwinEEngine *engine) : _engine(engine) {
canChangeScenes = _engine->cfgfile.Debug;
}
-void DebugGrid::changeGridCamera(int16 pKey) {
- if (useFreeCamera) {
- // Press up - more X positions
- if (pKey == twineactions[TwinEActionType::DebugGridCameraPressUp].localKey) {
- _engine->_grid->newCameraZ--;
- _engine->_redraw->reqBgRedraw = true;
- }
+void DebugGrid::changeGridCamera() {
+ if (!useFreeCamera) {
+ return;
+ }
+ // Press up - more X positions
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::DebugGridCameraPressUp)) {
+ _engine->_grid->newCameraZ--;
+ _engine->_redraw->reqBgRedraw = true;
+ }
- // Press down - less X positions
- else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressDown].localKey) {
- _engine->_grid->newCameraZ++;
- _engine->_redraw->reqBgRedraw = true;
- }
+ // Press down - less X positions
+ else if (_engine->_input->toggleActionIfActive(TwinEActionType::DebugGridCameraPressDown)) {
+ _engine->_grid->newCameraZ++;
+ _engine->_redraw->reqBgRedraw = true;
+ }
- // Press left - less Z positions
- else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressLeft].localKey) {
- _engine->_grid->newCameraX--;
- _engine->_redraw->reqBgRedraw = true;
- }
+ // Press left - less Z positions
+ else if (_engine->_input->toggleActionIfActive(TwinEActionType::DebugGridCameraPressLeft)) {
+ _engine->_grid->newCameraX--;
+ _engine->_redraw->reqBgRedraw = true;
+ }
- // Press right - more Z positions
- else if (pKey == twineactions[TwinEActionType::DebugGridCameraPressRight].localKey) {
- _engine->_grid->newCameraX++;
- _engine->_redraw->reqBgRedraw = true;
- }
+ // Press right - more Z positions
+ else if (_engine->_input->toggleActionIfActive(TwinEActionType::DebugGridCameraPressRight)) {
+ _engine->_grid->newCameraX++;
+ _engine->_redraw->reqBgRedraw = true;
}
}
-void DebugGrid::changeGrid(int16 pKey) {
+void DebugGrid::changeGrid() {
if (!canChangeScenes) {
return;
}
// Press up - more X positions
- if (pKey == twineactions[TwinEActionType::NextRoom].localKey) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::NextRoom)) {
_engine->_scene->currentSceneIdx++;
if (_engine->_scene->currentSceneIdx > NUM_SCENES)
_engine->_scene->currentSceneIdx = 0;
@@ -76,7 +77,7 @@ void DebugGrid::changeGrid(int16 pKey) {
}
// Press down - less X positions
- if (pKey == twineactions[TwinEActionType::PreviousRoom].localKey) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::PreviousRoom)) {
_engine->_scene->currentSceneIdx--;
if (_engine->_scene->currentSceneIdx < 0)
_engine->_scene->currentSceneIdx = NUM_SCENES;
@@ -85,21 +86,21 @@ void DebugGrid::changeGrid(int16 pKey) {
}
}
-void DebugGrid::applyCellingGrid(int16 pKey) {
+void DebugGrid::applyCellingGrid() {
// Increase celling grid index
- if (pKey == twineactions[TwinEActionType::IncreaseCellingGridIndex].localKey) {
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::IncreaseCellingGridIndex)) {
_engine->_grid->cellingGridIdx++;
if (_engine->_grid->cellingGridIdx > 133)
_engine->_grid->cellingGridIdx = 133;
}
// Decrease celling grid index
- else if (pKey == twineactions[TwinEActionType::DecreaseCellingGridIndex].localKey) {
+ else if (_engine->_input->toggleActionIfActive(TwinEActionType::DecreaseCellingGridIndex)) {
_engine->_grid->cellingGridIdx--;
if (_engine->_grid->cellingGridIdx < 0)
_engine->_grid->cellingGridIdx = 0;
}
// Enable/disable celling grid
- else if (pKey == twineactions[TwinEActionType::ApplyCellingGrid].localKey) {
+ else if (_engine->_input->toggleActionIfActive(TwinEActionType::ApplyCellingGrid)) {
if (_engine->_grid->useCellingGrid == -1) {
_engine->_grid->useCellingGrid = 1;
//createGridMap();
diff --git a/engines/twine/debug_grid.h b/engines/twine/debug_grid.h
index 588a0006f1..fb9d329735 100644
--- a/engines/twine/debug_grid.h
+++ b/engines/twine/debug_grid.h
@@ -40,11 +40,11 @@ public:
bool canChangeScenes = false;
/** Change scenario camera positions */
- void changeGridCamera(int16 pKey);
+ void changeGridCamera();
/** Change grid index */
- void changeGrid(int16 pKey);
+ void changeGrid();
/** Apply and change disappear celling grid */
- void applyCellingGrid(int16 pKey);
+ void applyCellingGrid();
};
} // namespace TwinE
diff --git a/engines/twine/debug_scene.cpp b/engines/twine/debug_scene.cpp
index 53a82814e4..3a6aa51576 100644
--- a/engines/twine/debug_scene.cpp
+++ b/engines/twine/debug_scene.cpp
@@ -89,7 +89,7 @@ int32 DebugScene::checkZoneType(int32 type) {
return 0;
}
-void DebugScene::displayZones(int16 pKey) {
+void DebugScene::displayZones() {
if (!showingZones) {
return;
}
diff --git a/engines/twine/debug_scene.h b/engines/twine/debug_scene.h
index b40bc979fd..89c0405795 100644
--- a/engines/twine/debug_scene.h
+++ b/engines/twine/debug_scene.h
@@ -41,7 +41,7 @@ public:
bool showingZones = false;
int32 typeZones = 127; // all zones on as default
- void displayZones(int16 pKey);
+ void displayZones();
};
} // namespace TwinE
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 46f84c3c4e..9fb6d52f2b 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -408,7 +408,7 @@ void GameState::processFoundItem(int32 item) {
while (_engine->_text->playVoxSimple(_engine->_text->currDialTextEntry)) {
_engine->readKeys();
- if (_engine->_input->internalKeyCode == 1) {
+ if (_engine->shouldQuit() || _engine->_input->toggleAbortAction()) {
break;
}
_engine->delaySkip(1);
@@ -485,8 +485,11 @@ void GameState::processGameoverAnimation() { // makeGameOver
int32 startLbaTime = _engine->lbaTime;
_engine->_interface->setClip(120, 120, 519, 359);
- while (_engine->_input->internalKeyCode != 1 && (_engine->lbaTime - startLbaTime) <= 500) {
+ while (!_engine->_input->toggleAbortAction() && (_engine->lbaTime - startLbaTime) <= 500) {
_engine->readKeys();
+ if (_engine->shouldQuit()) {
+ return;
+ }
int32 avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
int32 cdot = _engine->_screens->crossDot(1, 1024, 100, (_engine->lbaTime - startLbaTime) % 0x64);
diff --git a/engines/twine/input.h b/engines/twine/input.h
index fed8d80baa..685dc22ba8 100644
--- a/engines/twine/input.h
+++ b/engines/twine/input.h
@@ -158,15 +158,15 @@ private:
uint8 _pressed[Common::KEYCODE_LAST]{0};
Common::String _currentKeyMap;
+ uint8 actionStates[TwinEActionType::Max]{false};
+ int16 internalKeyCode = 0;
+ int16 currentKey = 0;
public:
Input(TwinEEngine *engine);
- uint8 actionStates[TwinEActionType::Max]{false};
+ int16 key = 0;
int16 skippedKey = 0;
int16 pressedKey = 0;
- int16 internalKeyCode = 0;
- int16 currentKey = 0;
- int16 key = 0;
int16 leftMouse = 0;
int16 rightMouse = 0;
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 1efca7fec0..8e3722a448 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -252,19 +252,10 @@ void MenuOptions::continueGameMenu() {
}
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- // TODO: recheck this
do {
_engine->readKeys();
- do {
- _engine->readKeys();
- if (_engine->shouldQuit()) {
- break;
- }
- } while (_engine->_input->skippedKey != 0);
- if (_engine->shouldQuit()) {
- break;
- }
- } while (_engine->_input->internalKeyCode != 0);
+ _engine->_system->delayMillis(1);
+ } while (!_engine->shouldQuit() && !_engine->_input->toggleAbortAction());
}
}
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 0317c33e29..060d64799a 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -528,7 +528,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
}
if (_engine->cfgfile.Debug) {
- _engine->_debugScene->displayZones(_engine->_input->internalKeyCode);
+ _engine->_debugScene->displayZones();
}
for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
diff --git a/engines/twine/script_life.cpp b/engines/twine/script_life.cpp
index 4a159a3605..3a6fb6a96e 100644
--- a/engines/twine/script_life.cpp
+++ b/engines/twine/script_life.cpp
@@ -1362,7 +1362,8 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, int32 actorIdx, ActorStruct *
do {
engine->readKeys();
- } while (engine->_input->internalKeyCode || engine->_input->skippedKey);
+ engine->_system->delayMillis(1);
+ } while (engine->_input->toggleAbortAction());
engine->unfreezeTime();
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 92c0b184d9..cc848ba051 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -644,19 +644,6 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
}
_engine->_system->delayMillis(1);
} while (!_engine->_input->toggleAbortAction());
-
- // wait key to display next text
- do {
- _engine->readKeys();
- if (_engine->_input->internalKeyCode != 0 || _engine->_input->skippedKey != 0) {
- _engine->_interface->loadClip();
- return;
- }
- if (_engine->shouldQuit()) {
- break;
- }
- _engine->_system->delayMillis(1);
- } while (!_engine->_input->toggleAbortAction());
} else { // RECHECK THIS
while (playVox(currDialTextEntry)) {
_engine->readKeys();
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 16e1baac02..d348f044ad 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -246,7 +246,6 @@ void TwinEEngine::initEngine() {
// Check if LBA CD-Rom is on drive
_music->initCdrom();
-#define TWINE_PLAY_INTROS 0
#if TWINE_PLAY_INTROS
_input->enabledKeyMap(cutsceneKeyMapId);
// Display company logo
@@ -340,22 +339,16 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_input->key = _input->pressedKey;
loopPressedKey = _input->skippedKey;
- _debug->processDebug(_input->internalKeyCode);
+ _debug->processDebug();
if (_menuOptions->canShowCredits != 0) {
// TODO: if current music playing != 8, than play_track(8);
- if (_input->internalKeyCode != 0) {
- return 0;
- }
- if (_input->pressedKey != 0) {
- return 0;
- }
- if (_input->skippedKey != 0) {
+ if (_input->toggleAbortAction()) {
return 0;
}
} else {
// Process give up menu - Press ESC
- if (_input->internalKeyCode == 1 && _scene->sceneHero->life > 0 && _scene->sceneHero->entity != -1 && !_scene->sceneHero->staticFlags.bIsHidden) {
+ if (_input->toggleAbortAction() && _scene->sceneHero->life > 0 && _scene->sceneHero->entity != -1 && !_scene->sceneHero->staticFlags.bIsHidden) {
freezeTime();
if (_menu->giveupMenu()) {
unfreezeTime();
@@ -760,14 +753,12 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
}
bool TwinEEngine::gameEngineLoop() { // mainLoop
- uint32 start;
-
_redraw->reqBgRedraw = true;
_screens->lockPalette = true;
_movements->setActorAngle(0, -256, 5, &loopMovePtr);
while (quitGame == -1) {
- start = g_system->getMillis();
+ uint32 start = g_system->getMillis();
while (g_system->getMillis() < start + cfgfile.Fps) {
if (runGameEngine()) {
@@ -786,7 +777,6 @@ bool TwinEEngine::gameEngineLoop() { // mainLoop
void TwinEEngine::delaySkip(uint32 time) {
uint32 startTicks = _system->getMillis();
uint32 stopTicks = 0;
- _input->internalKeyCode = 0;
do {
readKeys();
if (_input->toggleAbortAction()) {
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 67c3fbe3c5..526d46b5eb 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -58,6 +58,9 @@ namespace TwinE {
/** Number of colors used in the game */
#define NUMOFCOLORS 256
+// TODO: disabled during development - activate me again
+#define TWINE_PLAY_INTROS 0
+
static const struct TwinELanguage {
const char *name;
const char *id;
Commit: 2ccbff91d8c3141ab41f26e06150ad75322995b4
https://github.com/scummvm/scummvm/commit/2ccbff91d8c3141ab41f26e06150ad75322995b4
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: connect some of the advanced options menu settings
Changed paths:
engines/twine/menu.cpp
engines/twine/menuoptions.cpp
engines/twine/movements.cpp
engines/twine/script_life.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 4406567104..bc5a75ae1d 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -92,6 +92,13 @@ enum VolumeMenuType {
kMasterVolume = 5
};
+enum AdvOptionsMenuType {
+ kAgressiveMode = 0,
+ kPolygonDetails = 6,
+ kShadowSettings = 7,
+ kSceneryZoom = 8
+};
+
namespace _priv {
/** Main Menu Settings
@@ -169,13 +176,13 @@ static const int16 AdvOptionsMenuSettings[] = {
0, // unused
0,
26, // return to main menu
- 0,
+ kAgressiveMode,
4, // aggressive mode (manual|auto)
- 6,
+ kPolygonDetails,
31, // Polygon detail (full|medium|low)
- 7,
+ kShadowSettings,
32, // Shadows (all|character|no)
- 8,
+ kSceneryZoom,
33, // scenary zoon (on|off)
};
@@ -438,7 +445,6 @@ void Menu::drawButton(const int16 *menuSettings, bool hover) {
int32 Menu::processMenu(int16 *menuSettings) {
int16 currentButton = menuSettings[MenuSettings_CurrentLoadedButton];
bool buttonsNeedRedraw = true;
- bool musicChanged = false;
const int32 numEntry = menuSettings[MenuSettings_NumberOfButtons];
int32 maxButton = numEntry - 1;
@@ -462,18 +468,42 @@ int32 Menu::processMenu(int16 *menuSettings) {
buttonsNeedRedraw = true;
}
- // if its a volume button
- if (menuSettings == VolumeMenuState) {
- const int16 id = *(&menuSettings[MenuSettings_FirstButtonState] + currentButton * 2); // get button parameters from settings array
-
+ const int16 id = *(&menuSettings[MenuSettings_FirstButtonState] + currentButton * 2); // get button parameters from settings array
+ if (menuSettings == AdvOptionsMenuState) {
+ switch (id) {
+ case kAgressiveMode:
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft) || _engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
+ _engine->cfgfile.AutoAgressive = !_engine->cfgfile.AutoAgressive;
+ // TODO: set into actor
+ }
+ break;
+ case kPolygonDetails:
+ // TODO:
+ break;
+ case kShadowSettings:
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft)) {
+ _engine->cfgfile.ShadowMode--;
+ } else if (_engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
+ _engine->cfgfile.ShadowMode++;
+ }
+ _engine->cfgfile.ShadowMode %= 3;
+ break;
+ case kSceneryZoom:
+ if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft) || _engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
+ _engine->cfgfile.SceZoom = !_engine->cfgfile.SceZoom;
+ }
+ break;
+ default:
+ break;
+ }
+ } else if (menuSettings == VolumeMenuState) {
Audio::Mixer *mixer = _engine->_system->getMixer();
switch (id) {
case kMusicVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
if (_engine->_input->isActionActive(TwinEActionType::UILeft)) {
volume -= 4;
- }
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
+ } else if (_engine->_input->isActionActive(TwinEActionType::UIRight)) {
volume += 4;
}
_engine->_music->musicVolume(volume);
@@ -481,10 +511,9 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kSoundVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
+ if (_engine->_input->isActionActive(TwinEActionType::UILeft)) {
volume -= 4;
- }
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
+ } else if (_engine->_input->isActionActive(TwinEActionType::UIRight)) {
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
@@ -492,10 +521,9 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kCDVolume: {
AudioCDManager::Status status = _engine->_system->getAudioCDManager()->getStatus();
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
+ if (_engine->_input->isActionActive(TwinEActionType::UILeft)) {
status.volume -= 4;
- }
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
+ } else if (_engine->_input->isActionActive(TwinEActionType::UIRight)) {
status.volume += 4;
}
_engine->_system->getAudioCDManager()->setVolume(status.volume);
@@ -503,10 +531,9 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kLineVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
+ if (_engine->_input->isActionActive(TwinEActionType::UILeft)) {
volume -= 4;
- }
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
+ } else if (_engine->_input->isActionActive(TwinEActionType::UIRight)) {
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
@@ -514,10 +541,9 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
case kMasterVolume: {
int volume = mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UILeft))) { // on arrow key left
+ if (_engine->_input->isActionActive(TwinEActionType::UILeft)) {
volume -= 4;
- }
- if (((uint8)_engine->_input->toggleActionIfActive(TwinEActionType::UIRight))) { // on arrow key right
+ } else if (_engine->_input->isActionActive(TwinEActionType::UIRight)) {
volume += 4;
}
mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
@@ -538,9 +564,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
// draw plasma effect for the current selected button
drawButton(menuSettings, true);
- if (musicChanged) {
- // TODO: update volume settings
- }
+ // TODO: update volume settings
} while (!_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter));
currentButton = *(menuSettings + MenuSettings_FirstButton + currentButton * 2); // get current browsed button
@@ -816,7 +840,7 @@ void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, int16 cantDra
_engine->_text->setFontColor(15);
char dialText[256];
- if (_engine->_actor->heroBehaviour == 2 && _engine->_actor->autoAgressive == 1) {
+ if (_engine->_actor->heroBehaviour == kAggressive && _engine->_actor->autoAgressive == 1) {
_engine->_text->getMenuText(4, dialText, sizeof(dialText));
} else {
_engine->_text->getMenuText(_engine->_actor->heroBehaviour, dialText, sizeof(dialText));
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 8e3722a448..b05514c6ee 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -44,12 +44,11 @@ namespace TwinE {
static const char allowedCharIndex[] = " ABCDEFGHIJKLM.NOPQRSTUVWXYZ-abcdefghijklm?nopqrstuvwxyz!0123456789\040\b\r\0";
void MenuOptions::newGame() {
- int32 tmpFlagDisplayText;
-
+#if TWINE_PLAY_INTROS
_engine->_music->stopMusic();
- tmpFlagDisplayText = _engine->cfgfile.FlagDisplayText;
- _engine->cfgfile.FlagDisplayText = 1;
+ int32 tmpFlagDisplayText = _engine->cfgfile.FlagDisplayText;
+ _engine->cfgfile.FlagDisplayText = true;
// intro screen 1 - twinsun
_engine->_screens->loadImage(RESSHQR_INTROSCREEN1IMG);
@@ -90,6 +89,7 @@ void MenuOptions::newGame() {
_engine->setPalette(_engine->_screens->paletteRGBA);
_engine->cfgfile.FlagDisplayText = tmpFlagDisplayText;
+#endif
}
void MenuOptions::showCredits() {
diff --git a/engines/twine/movements.cpp b/engines/twine/movements.cpp
index 3f373e465a..67289f87d4 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/movements.cpp
@@ -380,6 +380,7 @@ void Movements::processActorMovements(int32 actorIdx) {
}
}
+ // TODO: remove loopPressedKey here
if (!_engine->loopPressedKey || heroAction) {
// if continue walking
if (_engine->_input->isActionActive(TwinEActionType::MoveForward) || _engine->_input->isActionActive(TwinEActionType::MoveBackward)) {
diff --git a/engines/twine/script_life.cpp b/engines/twine/script_life.cpp
index 3a6fb6a96e..39d8dd5589 100644
--- a/engines/twine/script_life.cpp
+++ b/engines/twine/script_life.cpp
@@ -1342,16 +1342,14 @@ static int32 lSET_NORMAL_PAL(TwinEEngine *engine, int32 actorIdx, ActorStruct *a
/*0x5E*/
static int32 lMESSAGE_SENDELL(TwinEEngine *engine, int32 actorIdx, ActorStruct *actor) {
- int32 tmpFlagDisplayText;
-
engine->freezeTime();
engine->_screens->fadeToBlack(engine->_screens->paletteRGBA);
engine->_screens->loadImage(25);
engine->_text->textClipFull();
engine->_text->setFontCrossColor(15);
engine->_text->newGameVar4 = 0;
- tmpFlagDisplayText = engine->cfgfile.FlagDisplayText;
- engine->cfgfile.FlagDisplayText = 1;
+ const bool tmpFlagDisplayText = engine->cfgfile.FlagDisplayText;
+ engine->cfgfile.FlagDisplayText = true;
engine->_text->drawTextFullscreen(6);
engine->_text->newGameVar4 = 1;
engine->_text->textClipSmall();
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index d348f044ad..6e80e30979 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -233,7 +233,7 @@ void TwinEEngine::initConfigurations() {
cfgfile.UseAutoSaving = ConfGetIntOrDefault("UseAutoSaving", 0);
cfgfile.AutoAgressive = ConfGetIntOrDefault("CombatAuto", 0);
cfgfile.ShadowMode = ConfGetIntOrDefault("Shadow", 0);
- cfgfile.SceZoom = ConfGetIntOrDefault("SceZoom", 0);
+ cfgfile.SceZoom = ConfGetIntOrDefault("SceZoom", 0) == 0;
cfgfile.WallCollision = ConfGetIntOrDefault("WallCollision", 0);
}
@@ -412,8 +412,8 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_text->newGameVar4 = 0;
_text->textClipFull();
_text->setFontCrossColor(15);
- int32 tmpFlagDisplayText = cfgfile.FlagDisplayText;
- cfgfile.FlagDisplayText = 1;
+ const bool tmpFlagDisplayText = cfgfile.FlagDisplayText;
+ cfgfile.FlagDisplayText = true;
_text->drawTextFullscreen(161);
cfgfile.FlagDisplayText = tmpFlagDisplayText;
_text->textClipSmall();
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 526d46b5eb..b65098a5e9 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -86,6 +86,7 @@ enum MovieType {
CONF_MOVIE_FLAPCX = 3
};
+// TODO: persist on shutdown
/** Configuration file structure
Used in the engine to load/use certain parts of code according with
@@ -120,7 +121,7 @@ struct ConfigFile {
/** AutoAgressive mode type */
int32 AutoAgressive = 0;
/** SceZoom mode type */
- int32 SceZoom = 0;
+ bool SceZoom = false;
/** Flag to toggle Wall Collision */
int32 WallCollision = 0;
};
Commit: fdca862294effd5fe5f01ec16323b55d01d51284
https://github.com/scummvm/scummvm/commit/fdca862294effd5fe5f01ec16323b55d01d51284
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: transfer auto agressive settings to actor state
Changed paths:
engines/twine/menu.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index bc5a75ae1d..1983331e66 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -474,7 +474,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
case kAgressiveMode:
if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft) || _engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
_engine->cfgfile.AutoAgressive = !_engine->cfgfile.AutoAgressive;
- // TODO: set into actor
+ _engine->_actor->autoAgressive = _engine->cfgfile.AutoAgressive;
}
break;
case kPolygonDetails:
Commit: 4e4681f27202bcb8610d5e2e2555e0c1c19e33b1
https://github.com/scummvm/scummvm/commit/4e4681f27202bcb8610d5e2e2555e0c1c19e33b1
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-10-24T16:12:55+02:00
Commit Message:
TWINE: activate intros again and fixed warning
Changed paths:
engines/twine/text.cpp
engines/twine/twine.h
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index cc848ba051..3c2ba0ac9a 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -594,8 +594,6 @@ int Text::printText10() {
// TODO: refactor this code
void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
- int32 skipText = 0;
-
ScopedKeyMap scopedKeyMap(_engine, cutsceneKeyMapId);
_engine->_interface->saveClip();
@@ -631,7 +629,7 @@ void Text::drawTextFullscreen(int32 index) { // printTextFullScreen
printTextVar13 = 0;
- if (printedText != 0 || skipText != 0) {
+ if (printedText != 0) {
_engine->_interface->loadClip();
return;
}
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index b65098a5e9..c7a07b85e7 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -58,8 +58,7 @@ namespace TwinE {
/** Number of colors used in the game */
#define NUMOFCOLORS 256
-// TODO: disabled during development - activate me again
-#define TWINE_PLAY_INTROS 0
+#define TWINE_PLAY_INTROS 1
static const struct TwinELanguage {
const char *name;
More information about the Scummvm-git-logs
mailing list