Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,241 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_action.h"
#include "watchmaker/game.h"
#include "watchmaker/globvar.h"
#include "watchmaker/message.h"
#include "watchmaker/ll/ll_string.h"
#include "watchmaker/define.h"
#include "watchmaker/schedule.h"
#include "watchmaker/classes/do_string.h"
#include "watchmaker/classes/do_inv.h"
#include "watchmaker/ll/ll_diary.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/ll/ll_anim.h"
#include "watchmaker/classes/do_operate.h"
namespace Watchmaker {
/* -----------------05/06/00 11.10-------------------
* CheckRoomPuzzle
* --------------------------------------------------*/
bool CheckRoomPuzzle(WGame &game, uint8 ev) {
if ((game._gameVars.getCurRoomId() == r2G) && (WhichRoomChar(game.init, ocGIARDINIERE) == r2G) && ((CurObj != o2Gp2H) && (CurObj != ocGIARDINIERE))) {
ClearText();
ClearUseWith();
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dGIARDINIERE_INTERRUPT2, 0, 0, nullptr, nullptr, nullptr);
return true;
} else if ((game._gameVars.getCurRoomId() == r2G) && (WhichRoomChar(game.init, ocCUSTODE) == r2G) && ((CurObj != o2Gp2H) && (CurObj != ocCUSTODE))) {
ClearText();
ClearUseWith();
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dCUSTODE_INTERRUPT5, 0, 0, nullptr, nullptr, nullptr);
return true;
}
return false;
}
/* -----------------19/05/98 16.40-------------------
* doDoor
* --------------------------------------------------*/
void doDoor(WGame &game, int32 obj) {
int32 anim = aNULL;
Init &init = game.init;
if (!obj) return;
anim = init.Obj[obj].anim[CurPlayer];
switch (obj) {
case 0: // Quiet VS C4065 warning
default:
anim = init.Obj[obj].anim[CurPlayer];
if (init.Obj[obj].goroom)
game._gameVars.setCurRoomId(init.Obj[obj].goroom);
break;
}
if (anim != aNULL) StartAnim(game, anim);
}
/* -----------------19/05/98 16.40-------------------
* doTake
* --------------------------------------------------*/
void doTake(WGame &game, int32 obj) {
int32 anim = aNULL;
//uint8 del = TRUE;
if (!obj) return;
anim = game.init.Obj[obj].anim[CurPlayer];
switch (obj) {
case o25CHIAVI:
// if ( Anim[aMOSTRAFOTOACUOCO].active == 0 )
// return ;
break;
default:
//del = TRUE;
break;
}
if (anim) StartAnim(game, anim);
// spegne oggetto che viene preso
// if(del) Obj[obj].flags &= ~ON;
// aggiunge icona
AddIcon(game.init, game.init.Obj[obj].ninv);
}
/* -----------------19/05/98 16.40-------------------
* doExamine
* --------------------------------------------------*/
void doExamine(WGame &game, int32 obj) {
int32 anim = aNULL;
uint8 sent = FALSE;
int32 log_item = lNULL;
Init &init = game.init;
if (!obj) return;
if (init.Obj[obj].flags & EXAMINEACT)
anim = init.Obj[obj].anim2[CurPlayer];
switch (obj) {
case o1DVALIGETTACH:
UpdateSpecial(game, r1D);
anim = aTO1PERSON;
break;
case o31BAULECH:
UpdateSpecial(game, r31);
anim = aTO1PERSON;
break;
case oXT1ETARGHETTA:
log_item = lPDA2_MENU5_RAUL_ITEM2;
break;
case o13STATUETTE:
log_item = lPDA2_MENU6_CUS_ITEM3;
break;
case o29TARGA1:
case o29TARGA2:
case o29TARGA3:
case o29TARGA4:
case o29COPPA:
log_item = lPDA2_MENU8_SUP_ITEM2;
break;
case o46PRIMODIAGRAMMA:
log_item = lPDA6_MENU31_ITEM1;
break;
case o46SECONDODIAGRAMMA:
// se il flag EXTRA non e' settato vuol dire che non si e' ancora entrati nella r45 e non si
// puo' conoscere il significato del disegno
if (!(init.Obj[o46SECONDODIAGRAMMA].flags & EXTRA)) {
PlayerSpeak(game, init.Obj[o13QUADRO1].action[CurPlayer]);
return;
} else log_item = lPDA6_MENU31_ITEM2;
break;
default:
sent = TRUE;
break;
}
if (log_item != lNULL) {
if (!(init.PDALog[log_item].flags & PDA_ON)) {
init.PDALog[log_item].flags |= (PDA_ON | PDA_UPDATE);
init.PDALog[log_item].time = t3dCurTime;
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_DEFAULT, FRAME_PER_SECOND * 3, 0, EFFECT_DISPLAY_NEWLOGIMG, nullptr, nullptr, nullptr);
}
sent = TRUE;
}
if (anim != aNULL) StartAnim(game, anim);
else if ((sent) && (init.Obj[obj].examine[CurPlayer])) PlayerSpeak(game, init.Obj[obj].examine[CurPlayer]);
}
/* -----------------19/03/98 16.31-------------------
* doAction
* --------------------------------------------------*/
void doAction(WGame &game) {
Init &init = game.init;
switch (TheMessage->event) {
case ME_MOUSEEXAMINE:
CurObj = TheMessage->lparam[0];
if (CheckRoomPuzzle(game, TheMessage->event))
break;
if (bUseWith & UW_ON) {
UseWith[WITH] = CurObj;
bUseWith &= ~UW_ON;
ClearText();
// fa l'usa con
doUseWith(game);
break;
}
doExamine(game, CurObj);
break;
case ME_MOUSEOPERATE:
CurObj = TheMessage->lparam[0];
if (CheckRoomPuzzle(game, TheMessage->event))
break;
if (bUseWith & UW_ON) {
UseWith[WITH] = CurObj;
bUseWith &= ~UW_ON;
ClearText();
// fa l'usa con
doUseWith(game);
break;
}
if (init.Obj[CurObj].flags & USEWITH) {
UseWith[USED] = CurObj;
bUseWith = UW_ON;
ShowObjName(init, CurObj);
CurMousePointer = MousePointerPlus;
} else if (init.Obj[CurObj].flags & CHARACTER) {
if (bFirstPerson) {
_vm->_messageSystem.doEvent(EventClass::MC_CAMERA, ME_CAMERA1TO3, MP_DEFAULT, 0, 0, 0, nullptr, nullptr, nullptr);
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_WAIT_CAMERA, init.Obj[CurObj].goroom, 0, 0, nullptr, nullptr, nullptr);
} else
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, init.Obj[CurObj].goroom, 0, 0, nullptr, nullptr, nullptr);
} else if (init.Obj[CurObj].flags & TAKE)
doTake(game, CurObj);
else if (init.Obj[CurObj].flags & ROOM)
doDoor(game, CurObj);
else
doOperate(game, CurObj);
break;
}
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,34 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_ACTION_H
#define WATCHMAKER_DO_ACTION_H
#include "watchmaker/globvar.h"
#include "watchmaker/game.h"
namespace Watchmaker {
void doAction(WGame &game);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_ACTION_H

View File

@@ -0,0 +1,53 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_anim.h"
#include "watchmaker/game.h"
#include "watchmaker/globvar.h"
#include "watchmaker/message.h"
#include "watchmaker/ll/ll_anim.h"
namespace Watchmaker {
/* -----------------15/12/98 10.03-------------------
* doAnimation
* --------------------------------------------------*/
void doAnimation(WGame &game) {
switch (TheMessage->event) {
case ME_STARTANIM:
StartAnim(game, TheMessage->wparam1);
break;
case ME_STOPANIM:
StopAnim(game, TheMessage->wparam1);
break;
case ME_PAUSEANIM:
PauseAnim(game.init, TheMessage->wparam1);
break;
case ME_CONTINUEANIM:
ContinueAnim(game.init, TheMessage->wparam1);
break;
}
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,33 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_ANIM_H
#define WATCHMAKER_DO_ANIM_H
#include "watchmaker/game.h"
namespace Watchmaker {
void doAnimation(WGame &game);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_ANIM_H

View File

@@ -0,0 +1,960 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_camera.h"
#include "watchmaker/t3d.h"
#include "watchmaker/utils.h"
#include "watchmaker/globvar.h"
#include "watchmaker/define.h"
#include "watchmaker/3d/math/llmath.h"
#include "watchmaker/3d/geometry.h"
#include "watchmaker/3d/t3d_body.h"
#include "watchmaker/ll/ll_util.h"
#include "watchmaker/message.h"
#include "watchmaker/walk/act.h"
#include "watchmaker/ll/ll_mouse.h"
#include "watchmaker/schedule.h"
#include "watchmaker/ll/ll_string.h"
#include "watchmaker/classes/do_string.h"
#include "watchmaker/3d/animation.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/3d/loader.h"
#include "watchmaker/walk/walkutil.h"
#include "watchmaker/renderer.h"
// locals
#define FIRST_PERSON_STEPS 8
#define CAMERA_CARRELLO_DIST 800.0f
#define MAX_CAMERA_MOVE 50.0f
#define MAX_CAMERA_ANGLE 2.0f
#define CAMERA_SUB_STEPS 3
namespace Watchmaker {
/* -----------------20/10/98 10.40-------------------
* PickCamera
* --------------------------------------------------*/
t3dCAMERA *CameraMan::PickCamera(t3dBODY *b, unsigned char in) {
// TODO: This is just here until we know when we can expect a nullptr
if (!b) {
return nullptr;
}
return b->PickCamera(in);
}
t3dCAMERA *t3dBODY::PickCamera(uint8 in) {
if (NumCameras() == 0) return nullptr;
// in = 100;
for (int i = 0; i < (int32)NumCameras(); i++)
if (CameraTable[i].Index == (in + 1))
return (&CameraTable[i]);
// return( &b->CameraTable[in] );
warning("Camera %d non trovata in %s", in + 1, name.c_str());
return (&CameraTable[0]);
}
/* -----------------06/07/98 16.55-------------------
* GetRealCharPos
* --------------------------------------------------*/
void CameraMan::GetRealCharPos(Init &init, t3dV3F *Target, int32 oc, uint8 bn) {
t3dCHARACTER *Ch = Character[oc];
t3dMESH *mesh = Ch->Mesh, *m;
t3dBONE *bone;
int32 frame = mesh->CurFrame;
t3dV3F tmp;
if ((Target != nullptr) && (Ch != nullptr)) {
// Discesa del garage
if (t3dCurRoom->name.equalsIgnoreCase("rxt.t3d")) {
if ((m = LinkMeshToStr(init, "oxt-garage")) && (m->BBox[3].p.x - m->BBox[2].p.x) &&
(Player->Pos.x > m->BBox[2].p.x) && (Player->Pos.x < m->BBox[3].p.x) &&
(Player->Pos.z > m->BBox[2].p.z) && (Player->Pos.z < m->BBox[6].p.z)) {
Player->Mesh->Trasl.y = Player->Pos.y = ((Player->Pos.x - m->BBox[2].p.x) / (m->BBox[3].p.x - m->BBox[2].p.x)) * m->BBox[2].p.y;
CurFloorY = Player->Pos.y;
}
}
t3dVectCopy(Target, &mesh->Trasl);
Target->y = CurFloorY + CHEST_HEIGHT;
if ((bn) && (frame > 0)) {
if (mesh->Flags & T3D_MESH_DEFAULTANIM)
bone = &mesh->DefaultAnim.BoneTable[bn];
else
bone = &mesh->Anim.BoneTable[bn];
if ((bone) && (bone->Trasl) && (bone->Matrix)) {
Target->y = CurFloorY;
t3dVectSub(&tmp, &bone->Trasl[frame], &bone->Trasl[1]);
t3dVectTransform(&tmp, &tmp, &bone->Matrix[1]);
t3dVectTransformInv(&tmp, &tmp, &bone->Matrix[frame]);
t3dVectAdd(&tmp, &tmp, &bone->Trasl[frame]);
t3dVectAdd(Target, Target, &tmp);
}
}
}
}
/* -----------------21/08/98 14.38-------------------
* Dist Point C from AB -> Inters in I
* --------------------------------------------------*/
uint8 DistPointRect(t3dV3F *i, t3dF32 *dist, t3dV3F *a, t3dV3F *b, t3dV3F *c) {
t3dF32 d, r;
d = ((b->x - a->x) * (b->x - a->x) + (b->z - a->z) * (b->z - a->z));
r = ((a->z - c->z) * (a->z - b->z) - (a->x - c->x) * (b->x - a->x)) / d;
if (r <= 0.0f) { // Prima di A
t3dVectCopy(i, a);
*dist = t3dVectDistance(c, i);
return FALSE;
} else if (r >= 1.0f) { // Dopo B
t3dVectCopy(i, b);
*dist = t3dVectDistance(c, i);
return FALSE;
} else { // Tra A e B
i->x = a->x + r * (b->x - a->x);
i->y = a->y + r * (b->y - a->y);
i->z = a->z + r * (b->z - a->z);
*dist = t3dVectDistance(c, i);
return TRUE;
}
}
/* -----------------20/08/98 17.16-------------------
* HandleCameraCarrello
* --------------------------------------------------*/
void CameraMan::HandleCameraCarrello(t3dBODY *croom) {
t3dCAMERAPATH *cp = nullptr;
t3dF32 dist, mindist;
t3dV3F pt, i, b;
int16 j;
uint8 bcc = false;
if (!Player || !croom || !t3dCurCamera) return;
// Se e' appena partito il carrello
if (!bCameraCarrello) {
CameraCarrello = *t3dCurCamera;
t3dCurCamera = &CameraCarrello;
}
// Cerca percorso carrello
for (j = 0; j < CameraCarrello.NumAvailablePaths(); j++)
if (CameraCarrello.CameraPaths[j].PathIndex & 0x80)
break;
// Puntatore al perscorso carrello, se non lo trova esce
if ((j >= CameraCarrello.NumAvailablePaths()) ||
((cp = &croom->CameraPath[(CameraCarrello.CameraPaths[j].PathIndex) & 0x7F]) == nullptr))
return ;
// Trova il punto dell'omino che deve seguire il source del carrello
t3dVectFill(&b, 0.0f);
t3dVectFill(&pt, 0.0f);
pt.z = (t3dF32)(cp->CarrelloDist);
t3dVectTransform(&pt, &pt, &Player->Mesh->Matrix);
t3dVectAdd(&pt, &pt, &t3dCurCamera->Target);
// Cerca punto ottimale del carrello
mindist = 9999999.9f;
for (j = 0; j < cp->NumPoints() - 1; j++) {
DistPointRect(&i, &dist, &cp->PList[j], &cp->PList[j + 1], &pt);
if (dist < mindist) {
t3dVectCopy(&b, &i);
bcc = true;
mindist = dist;
}
}
// Se decide di spostare source camera carrello
if (bcc) {
// Se e' appena partito carrello, puo' fare scatto
if (!bCameraCarrello)
t3dVectCopy(&t3dCurCamera->Source, &b);
else {
// Se dorvebbe fare scatto, inizia a smussare
if (t3dVectDistance(&t3dCurCamera->Source, &b) > MAX_CAMERA_MOVE) {
t3dVectSub(&i, &b, &t3dCurCamera->Source);
t3dVectNormalize(&i);
i *= MAX_CAMERA_MOVE;
t3dVectAdd(&t3dCurCamera->Source, &t3dCurCamera->Source, &i);
} else
t3dVectCopy(&t3dCurCamera->Source, &b);
}
bCameraCarrello = bcc;
}
}
void CameraMan::MoveHeadAngles(t3dF32 diffx, t3dF32 diffy) {
t3dF32 s;
if (((diffx == 0) && (diffy == 0)) || (bLPressed) || (bRPressed) || (bDialogActive)) return;
if (diffx < -10) diffx = -10;
else if (diffx > 10) diffx = 10;
if (diffy < -10) diffy = -10;
else if (diffy > 10) diffy = 10;
s = (t3dF32)bFirstPerson + 1.0f;
if (diffx > 0) {
if ((HeadAngles.x + diffx) >= MAX_HEAD_ANGLE_X * s) {
diffx = MAX_HEAD_ANGLE_X * s - HeadAngles.x;
HeadAngles.x = MAX_HEAD_ANGLE_X * s;
} else
HeadAngles.x += diffx;
} else {
if ((HeadAngles.x + diffx) < -MAX_HEAD_ANGLE_X * s) {
diffx = -MAX_HEAD_ANGLE_X * s - HeadAngles.x;
HeadAngles.x = -MAX_HEAD_ANGLE_X * s;
} else
HeadAngles.x += diffx;
}
if (diffy > 0) {
if ((HeadAngles.y + diffy) >= MAX_HEAD_ANGLE_Y * s) {
diffy = MAX_HEAD_ANGLE_Y * s - HeadAngles.y;
HeadAngles.y = MAX_HEAD_ANGLE_Y * s;
} else
HeadAngles.y += diffy;
} else {
if ((HeadAngles.y + diffy) < -MAX_HEAD_ANGLE_Y * s) {
diffy = -MAX_HEAD_ANGLE_Y * s - HeadAngles.y;
HeadAngles.y = -MAX_HEAD_ANGLE_Y * s;
} else
HeadAngles.y += diffy;
}
CamAngleX = ((t3dF32)diffy / 180.0f * T3D_PI);
CamAngleY = ((t3dF32)diffx / 180.0f * T3D_PI);
if (bFirstPerson && !bLockCamera && ((CamAngleX != 0.0f) || (CamAngleY != 0.0f)))
t3dRotateMoveCamera(t3dCurCamera, CamAngleX, CamAngleY, 0.0f);
}
void CameraMan::resetAngle() {
CamAngleX = 0.0f;
CamAngleY = 0.0f;
t3dVectFill(&HeadAngles, 0.0f);
}
/* -----------------30/09/98 11.13-------------------
* GetCameraTaget
* --------------------------------------------------*/
void CameraMan::GetCameraTarget(Init &init, t3dV3F *Target) {
int32 i;
if (!Target) return;
if (bFirstPerson) // Se sono in prima persona e' gia' precalcolato
t3dVectCopy(Target, &FirstPersonTarget);
else if ((Player) && (!CameraTargetObj)) // Se non e' settato niente oppure e' il giocatore
GetRealCharPos(init, Target, ocCURPLAYER, 0);
else if ((CameraTargetObj == oCAMERAMAX) && (t3dCurCamera)) {
if ((bAllowCalcCamera) && (bMovingCamera) && (CurCameraStep < NumCameraSteps)) { // se li ha gia' precalcolati
t3dVectCopy(Target, &CameraStep[CurCameraStep].Target);
for (i = 0; i < CurCameraSubStep; i++)
t3dVectAdd(Target, Target, &TargetBlend);
} else
t3dVectCopy(Target, &t3dCurCamera->MaxTarget);
} else
GetRealCharPos(init, Target, CameraTargetObj, (uint8)CameraTargetBone);
}
/* -----------------05/06/98 15.34-------------------
* NextCameraStep
* --------------------------------------------------*/
void CameraMan::NextCameraStep(WGame &game) {
t3dBONE *bone;
t3dV3F Target;
int16 i;
Init &init = game.init;
if (bMovingCamera == 2) {
if ((game.init._globals._invVars.CameraDummy.CurFrame >= 0) && (game.init._globals._invVars.CameraDummy.Anim.BoneTable)) {
if ((bone = &game.init._globals._invVars.CameraDummy.Anim.BoneTable[33]) && (bone->Trasl))
t3dVectCopy(&t3dCurCamera->Source, &bone->Trasl[game.init._globals._invVars.CameraDummy.CurFrame]);
if ((bone = &game.init._globals._invVars.CameraDummy.Anim.BoneTable[34]) && (bone->Trasl))
t3dVectCopy(&t3dCurCamera->Target, &bone->Trasl[game.init._globals._invVars.CameraDummy.CurFrame]);
} else {
t3dCurCamera = DestCamera;
CurCameraSubStep = CurCameraStep = NumCameraSteps = 0;
bMovingCamera = false;
DestCamera = nullptr;
t3dVectFill(&OldCameraTarget, 0.0f);
// _vm->_messageSystem.addWaitingMsgs( MP_WAIT_CAMERA );
GetCameraTarget(init, &t3dCurCamera->Target);
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
}
return ;
}
if (!bMovingCamera || !Player) return;
GetCameraTarget(init, &Target);
// Se ha finito di muoversi
if ((NumCameraSteps != 0) && (CurCameraStep >= NumCameraSteps)) {
t3dCurCamera = DestCamera;
t3dVectCopy(&t3dCurCamera->Target, &Target);
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
CurCameraStep = NumCameraSteps = 0;
bMovingCamera = false;
DestCamera = nullptr;
_vm->_messageSystem.addWaitingMsgs(MP_WAIT_CAMERA);
// if( (bFirstPerson) && ( ( CurRoom == r32 ) && ( PlayerPos[CurPlayer+ocDARRELL] == 6 ) ) )
// PlayerSpeak( Obj[o32OROLOGIO].action[CurPlayer+ocDARRELL] );
if ((bFirstPerson) && (ToFirstPersonSent)) {
PlayerSpeak(game, ToFirstPersonSent);
ToFirstPersonSent = 0;
}
// Se ho selezionato un carrello, riposiziona il source
for (i = 0; i < t3dCurCamera->NumAvailablePaths(); i++)
if (t3dCurCamera->CameraPaths[i].PathIndex & 0x80) {
HandleCameraCarrello(t3dCurRoom);
break;
}
} else {
t3dCurCamera = &CameraStep[CurCameraStep];
t3dVectCopy(&t3dCurCamera->Target, &Target);
if ((!CurCameraSubStep) && (CurCameraStep + 1 < NumCameraSteps)) {
t3dVectSub(&SourceBlend, &CameraStep[CurCameraStep + 1].Source, &CameraStep[CurCameraStep].Source);
SourceBlend *= (1.0f / (t3dF32)CAMERA_SUB_STEPS);
t3dVectSub(&TargetBlend, &CameraStep[CurCameraStep + 1].Target, &CameraStep[CurCameraStep].Target);
TargetBlend *= (1.0f / (t3dF32)CAMERA_SUB_STEPS);
} else if (CurCameraStep + 1 < NumCameraSteps)
t3dVectAdd(&t3dCurCamera->Source, &t3dCurCamera->Source, &SourceBlend);
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
if (++CurCameraSubStep >= CAMERA_SUB_STEPS) {
CurCameraStep ++;
CurCameraSubStep = 0;
}
}
}
/* -----------------05/06/98 15.50-------------------
* doCamera
* --------------------------------------------------*/
void CameraMan::doCamera(WGame &game) {
t3dV3F Dest, Dir, ct;
t3dF32 dist;
int16 row, col, i;
Init &init = game.init;
switch (TheMessage->event) {
case ME_CAMERA3TO1:
if (bMovingCamera) {
TheMessage->flags |= MP_WAIT_CAMERA;
ReEvent();
}
if (Player == nullptr) break;
mHide = true;
bFirstPerson = true;
CharStop(ocCURPLAYER);
game._messageSystem.removeEvent(EventClass::MC_PLAYER, ME_ALL);
ClearText();
LastCamera = t3dCurCamera;
DestCamera = &FirstPersonCamera;
DestCamera->Fov = CAMERA_FOV_1ST;
// LastCamera->Fov = CAMERA_FOV;
// Abilita la modalita' muovi camera
bMovingCamera = true;
// Seleziona il punto di destinazione del Source
GetRealCharPos(init, &Dest, ocCURPLAYER, 0);
Dest.y = CurFloorY + EYES_HEIGHT;
t3dVectCopy(&FirstPersonCamera.Source, &Dest);
// Trova il target a cui puntare
t3dVectFill(&HeadAngles, 0.0f);
CamAngleX = 0.0f;
CamAngleY = 0.0f;
t3dVectNormalize(&Player->Dir);
FirstPersonTarget = Player->Dir * CHEST_HEIGHT;
t3dVectAdd(&FirstPersonTarget, &FirstPersonTarget, &Player->Mesh->Trasl);
FirstPersonTarget.y = CurFloorY + EYES_HEIGHT;
if (TheMessage->bparam) {
if (GetFullLightDirection(&FirstPersonTarget, TheMessage->bparam)) {
Dest.y = FirstPersonTarget.y;
FirstPersonCamera.Source.y = FirstPersonTarget.y;
// HeadAngles.y = -(t3dF32)asin( (FirstPersonTarget.y-(CurFloorY+EYES_HEIGHT))/CHEST_HEIGHT )*180.0f/T3D_PI;
}
}
// Calcola quanto deve muovere la camera
dist = t3dVectDistance(&LastCamera->Source, &Dest);
t3dVectSub(&Dir, &LastCamera->Source, &Dest);
t3dVectNormalize(&Dir);
Dir *= (dist / FIRST_PERSON_STEPS);
CurCameraStep = 0;
CurCameraSubStep = 0;
NumCameraSteps = FIRST_PERSON_STEPS;
// Copia tutti i passi del percorso partendo dall'arrivo
for (i = NumCameraSteps - 1; i >= 0; i--) {
t3dVectCopy(&CameraStep[i].Source, &Dest);
t3dVectAdd(&Dest, &Dest, &Dir);
CameraStep[i].Fov = LastCamera->Fov + (t3dF32)(((DestCamera->Fov - LastCamera->Fov) * (t3dF32)i) / (t3dF32)NumCameraSteps);
}
// Avanza al primo frame del percorso
NextCameraStep(game);
game._messageSystem.removeEvent(EventClass::MC_PLAYER, ME_PLAYERIDLE);
// Sistema posizione del mouse e posizione della testa
{
auto info = game._renderer->getScreenInfos();
mPosx = info.width / 2;
mPosy = info.height / 2;
}
Player->Flags |= T3D_CHARACTER_ENABLEDINMIRROR;
break;
case ME_CAMERA1TO3:
if (bMovingCamera) {
TheMessage->flags |= MP_WAIT_CAMERA;
ReEvent();
}
if (Player == nullptr) break;
mHide = true;
bFirstPerson = false;
// CharStop( Player );
ClearText();
if (FromFirstPersonAnim)
CharGotoPosition(game, ocCURPLAYER, init.Anim[FromFirstPersonAnim].pos, 0, FromFirstPersonAnim);
DestCamera = LastCamera;
if (TheMessage->bparam) DestCamera = t3dCurCamera;
LastCamera = &FirstPersonCamera;
// DestCamera->Fov = CAMERA_FOV;
LastCamera->Fov = CAMERA_FOV_1ST;
// Abilita la modalita' muovi camera
bMovingCamera = true;
// Seleziona il punto di destinazione del Source
t3dVectCopy(&Dest, &Player->Mesh->Trasl);
Dest.y = CurFloorY + EYES_HEIGHT;
t3dVectCopy(&FirstPersonCamera.Source, &Dest);
// Calcola quanto deve muovere la camera
dist = t3dVectDistance(&DestCamera->Source, &Dest);
t3dVectSub(&Dir, &DestCamera->Source, &Dest);
t3dVectNormalize(&Dir);
Dir *= (dist / FIRST_PERSON_STEPS);
CurCameraStep = 0;
CurCameraSubStep = 0;
NumCameraSteps = FIRST_PERSON_STEPS;
// Copia tutti i passi del percorso partendo dall'arrivo
for (i = 0; i < NumCameraSteps; i++) {
t3dVectCopy(&CameraStep[i].Source, &Dest);
t3dVectAdd(&Dest, &Dest, &Dir);
CameraStep[i].Fov = LastCamera->Fov + (t3dF32)(((DestCamera->Fov - LastCamera->Fov) * (t3dF32)i) / (t3dF32)NumCameraSteps);
}
// Azzera un po' di variabili
t3dVectFill(&HeadAngles, 0.0f);
CamAngleX = 0.0f;
CamAngleY = 0.0f;
// Avanza al primo frame del percorso
NextCameraStep(game);
FromFirstPersonAnim = aNULL;
if (Player)
Player->Flags &= ~T3D_CHARACTER_HIDE;
Player->Flags &= ~T3D_CHARACTER_ENABLEDINMIRROR;
break;
case ME_CAMERAPLAYER:
if (bMovingCamera) {
TheMessage->flags |= MP_WAIT_CAMERA;
ReEvent();
}
if ((Player == nullptr) || (t3dCurRoom->CameraGrid.Grid.empty())) break;
GetCameraTarget(init, &ct);
col = (int16)((ct.x - t3dCurRoom->CameraGrid.TopLeft.x) / t3dCurRoom->CameraGrid.CellDim.x);
row = (int16)((ct.z - t3dCurRoom->CameraGrid.TopLeft.z) / t3dCurRoom->CameraGrid.CellDim.z);
if (((col < 0 || row < 0) || (col >= t3dCurRoom->CameraGrid.Col) || (row >= t3dCurRoom->CameraGrid.Row))) return;
t3dLastCameraIndex = t3dCurCameraIndex;
t3dCurCameraIndex = t3dCurRoom->CameraGrid.Grid[col + row * t3dCurRoom->CameraGrid.Col];
mHide = true;
bFirstPerson = false;
ClearText();
LastCamera = t3dCurCamera;
DestCamera = PickCamera(t3dCurRoom, t3dCurCameraIndex);
// DestCamera->Fov = CAMERA_FOV;
// LastCamera->Fov = CAMERA_FOV;
// Abilita la modalita' muovi camera
bMovingCamera = true;
// Seleziona il punto di destinazione del Source
t3dVectCopy(&Dest, &Player->Mesh->Trasl);
Dest.y = CurFloorY + EYES_HEIGHT;
// Calcola quanto deve muovere la camera
dist = t3dVectDistance(&DestCamera->Source, &Dest);
t3dVectSub(&Dir, &DestCamera->Source, &Dest);
t3dVectNormalize(&Dir);
Dir *= (dist / FIRST_PERSON_STEPS);
CurCameraStep = 0;
CurCameraSubStep = 0;
NumCameraSteps = FIRST_PERSON_STEPS;
// Copia tutti i passi del percorso partendo dall'arrivo
for (i = 0; i < NumCameraSteps; i++) {
t3dVectCopy(&CameraStep[i].Source, &Dest);
t3dVectAdd(&Dest, &Dest, &Dir);
CameraStep[i].Fov = LastCamera->Fov + (t3dF32)(((DestCamera->Fov - LastCamera->Fov) * (t3dF32)i) / (t3dF32)NumCameraSteps);
}
// Azzera un po' di variabili
t3dVectFill(&HeadAngles, 0.0f);
CamAngleX = 0.0f;
CamAngleY = 0.0f;
// Avanza al primo frame del percorso
NextCameraStep(game);
FromFirstPersonAnim = aNULL;
if (Player)
Player->Flags &= ~T3D_CHARACTER_HIDE;
Player->Flags &= ~T3D_CHARACTER_ENABLEDINMIRROR;
break;
}
}
/* -----------------09/11/98 10.27-------------------
* ResetCameraSource
* --------------------------------------------------*/
void CameraMan::ResetCameraSource() {
resetLastCameraIndex();
t3dCurCameraIndex = 255;
}
/* -----------------09/11/98 10.27-------------------
* ResetCameraTarget
* --------------------------------------------------*/
void CameraMan::ResetCameraTarget() {
t3dVectFill(&OldCameraTarget, 0.0f);
}
/* -----------------09/11/98 10.32-------------------
* ClipCameraMove
* --------------------------------------------------*/
uint8 ClipCameraMove(t3dV3F *NewT, t3dV3F *OldT, t3dV3F *Source) {
t3dV3F n, o;
t3dF32 a, d, l;
t3dVectSub(&n, NewT, Source);
t3dVectSub(&o, OldT, Source);
t3dVectNormalize(&n);
t3dVectNormalize(&o);
a = t3dVectAngle(&o, &n);
if (a > MAX_CAMERA_ANGLE) d = (MAX_CAMERA_ANGLE * T3D_PI) / 180.0f;
else if (a < -MAX_CAMERA_ANGLE) d = -(MAX_CAMERA_ANGLE * T3D_PI) / 180.0f;
else return 0;
a = (a * T3D_PI) / 180.0f;
t3dVectSub(&o, NewT, OldT);
t3dVectNormalize(&o);
l = (t3dVectDistance(NewT, OldT) * d) / a;
o *= l;
t3dVectAdd(NewT, OldT, &o);
/* t3dVectSub( &o, OldT, Source );
t3dVectNormalize( &o );
l = t3dVectDistance( OldT, Source );
// l += ( ( l - t3dVectDistance( NewT, Source ) ) * d ) / a;
t3dVectScale( &o, &o, l );
t3dMatRot( &m, 0.0f, d, 0.0f );
t3dVectTransform( NewT, &o, &m );
t3dVectAdd( NewT, NewT, Source );
NewT->y += ( ( NewT->y - OldT->y ) * d ) / a;
*/
return 1;
}
/* -----------------05/06/98 10.36-------------------
* ProcessCamera
* --------------------------------------------------*/
void CameraMan::ProcessCamera(WGame &game) {
t3dCAMERAPATH *cp = nullptr;
t3dBODY *croom;
int16 row, col, i;
t3dV3F Dest, Dir;
t3dF32 dist;
int32 a, b;
t3dV3F ct;
int8 cd;
uint8 cc;
int32 foxOldRoom;
Init &init = game.init;
if (bMovingCamera && !PortalCrossed) { // Se la camera si sta muovendo
NextCameraStep(game);
return ;
}
if (bFirstPerson && !PortalCrossed) { // se sono in prima persona non devo cambiare camera
return;
}
if (PortalCrossed != nullptr) { // Se ho cambiato stanza
croom = PortalCrossed; // Nuova stanza
t3dVectFill(&OldCameraTarget, 0.0f);
bForceDirectCamera = TRUE;
t3dCurCameraIndex = 255;
resetLastCameraIndex();
_vm->_messageSystem.addWaitingMsgs(MP_WAIT_PORTAL);
// DebugLogFile("PortalCrossed %s",PortalCrossed->Name);
// PortalCrossed = nullptr;
if (bMovingCamera) {
CurCameraStep = NumCameraSteps = 0;
bMovingCamera = FALSE;
DestCamera = nullptr;
_vm->_messageSystem.addWaitingMsgs(MP_WAIT_CAMERA);
}
if (bFirstPerson)
_vm->_messageSystem.doEvent(EventClass::MC_CAMERA, ME_CAMERA3TO1, MP_DEFAULT, 0, 0, 0, nullptr, nullptr, nullptr);
// Fa partire animazione di link portali se l'ho attraversato con i tasti
for (i = 0; i < (int16)t3dCurRoom->NumMeshes(); i++) {
if (t3dCurRoom->MeshTable[i].PortalList == PortalCrossed) {
for (a = 0; a < MAX_ANIMS_IN_ROOM; a++) {
b = game.getCurRoom().anims[a];
if ((b == aNULL) || !(init.Anim[b].flags & ANIM_PORTAL_LINK)) continue;
if (t3dCurRoom->MeshTable[i].name.equalsIgnoreCase((char *)init.Anim[b].RoomName.rawArray()) && (PlayerGotoPos[CurPlayer + ocDARRELL] != init.Anim[b].pos)) {
if (!(init.Anim[b].flags & ANIM_NULL))
CharGotoPosition(game, ocCURPLAYER, init.Anim[b].pos, 10, b);
break;
}
}
}
}
foxOldRoom = game._gameVars.getCurRoomId();
game._gameVars.setCurRoomId(getRoomFromStr(init, croom->name));
t3dCurRoom = PortalCrossed;
PortalCrossed = nullptr;
UpdateRoomVisibility(game);
if (Player && t3dCurRoom) {
Player->Walk.Panel = t3dCurRoom->Panel[t3dCurRoom->CurLevel];
Player->Walk.PanelNum = t3dCurRoom->NumPanels[t3dCurRoom->CurLevel];
Player->Walk.CurPanel = -1;
Player->Walk.OldPanel = -1;
for (a = 0; a < Player->Walk.NumSteps; a++)
Player->Walk.WalkSteps[a].curp = -1;
CurFloorY = t3dCurRoom->PanelHeight[t3dCurRoom->CurLevel];
}
// Parte Morte Victoria se esce dalla r49 per andare nella r48 prima di aver attivato le leylines
if (
(game._gameVars.getCurRoomId() == r48) && (foxOldRoom == r49)
&& (!(init.Dialog[dR491].flags & DIALOG_DONE))
&& (!(LoaderFlags & T3D_DEBUGMODE))
&& (!bDialogActive)
) {
// DebugLogFile("BECCATO222");
CharStop(ocCURPLAYER);
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR48KRENNSPARA, 0, 0, nullptr, nullptr, nullptr);
}
// per sicurezza faccio sparire la bottiglia
if (game._gameVars.getCurRoomId() == r25) {
t3dMESH *m = LinkMeshToStr(init, "o25-fiaschetta");
if (m) m->Flags |= T3D_MESH_HIDDEN;
}
} else {
croom = t3dCurRoom; // Stanza attuale
if (ForcedCamera && bCutCamera) // Se ho settato un camera-cut
bForceDirectCamera = TRUE;
else
bForceDirectCamera = FALSE;
}
// Se non c'e' la griglia o non c'e' il personaggio o la camera attuale
if ((croom->CameraGrid.Grid.empty()) || (Player == nullptr) || (t3dCurCamera == nullptr)) return;
GetCameraTarget(init, &ct); // Si calcola quale sarebbe il Target giusto per la camera
// Se non devo spostare la camera esco subito
if ((ct == OldCameraTarget) && (!ForcedCamera || (t3dCurCameraIndex == ForcedCamera - 1))) {
if ((CamAngleX != 0.0f) || (CamAngleY != 0.0f))
t3dRotateMoveCamera(t3dCurCamera, CamAngleX, CamAngleY, 0.0f);
return ;
}
if (!bFirstPerson) t3dVectFill(&HeadAngles, 0.0f);
// Mi calcolo in che casella sta l'omino
col = (int16)((ct.x - croom->CameraGrid.TopLeft.x) / croom->CameraGrid.CellDim.x);
row = (int16)((ct.z - croom->CameraGrid.TopLeft.z) / croom->CameraGrid.CellDim.z);
// Se la camera si muoverebbe troppo, riduce il movimento
if (!bForceDirectCamera) ClipCameraMove(&ct, &t3dCurCamera->Target, &t3dCurCamera->Source);
// Se sono in un dialogo elimina la gestione del trova-camera
if (!ForcedCamera && bDialogActive) return ;
// Aggiorno Camera
t3dVectCopy(&t3dCurCamera->Target, &ct);
t3dVectCopy(&OldCameraTarget, &ct);
// Se e' un carrello, aggiorno carrello
if (bCameraCarrello) HandleCameraCarrello(croom); // Se carrello attivo, riposiziona il source
// Se non e' valida esco
if (!ForcedCamera && ((col < 0 || row < 0) || (col >= croom->CameraGrid.Col) || (row >= croom->CameraGrid.Row))) return;
// Prendo l'indice della nuova stanza e se e' in una zona libera esce
cc = croom->CameraGrid.Grid[col + row * croom->CameraGrid.Col];
// Se e' in zona libera e la vecchia telecamera era in zona libera, ricerca a spirale
if ((cc == 255) && (t3dLastCameraIndex == 255)) {
for (a = 1; a < 10; a++) {
for (b = -a; b <= a; b++) {
if ((col + b) >= 0 || (row + a) >= 0 || (col + b) < croom->CameraGrid.Col || (row + a) < croom->CameraGrid.Row)
if ((cc = croom->CameraGrid.Grid[col + b + (row + a) * croom->CameraGrid.Col]) != 255) break;
if ((col + b) >= 0 || (row - a) >= 0 || (col + b) < croom->CameraGrid.Col || (row - a) < croom->CameraGrid.Row)
if ((cc = croom->CameraGrid.Grid[col + b + (row - a) * croom->CameraGrid.Col]) != 255) break;
if ((col + a) >= 0 || (row + b) >= 0 || (col + a) < croom->CameraGrid.Col || (row + b) < croom->CameraGrid.Row)
if ((cc = croom->CameraGrid.Grid[col + a + (row + b) * croom->CameraGrid.Col]) != 255) break;
if ((col - a) >= 0 || (row + b) >= 0 || (col - a) < croom->CameraGrid.Col || (row + b) < croom->CameraGrid.Row)
if ((cc = croom->CameraGrid.Grid[col - a + (row + b) * croom->CameraGrid.Col]) != 255) break;
}
if (cc != 255) break;
}
}
// Se resta sempre in una zona libera esce
if (!ForcedCamera && (cc == 255)) return;
// Mi salvo l'ultima posizione della camera e la posizione attuale
t3dLastCameraIndex = t3dCurCameraIndex;
// Se obbligo a prendre una camera particolare per l'animazione
if (ForcedCamera) t3dCurCameraIndex = ForcedCamera - 1;
else t3dCurCameraIndex = cc;
// Se non deve cambiare camera ed e' nella stessa stanza esce
if ((t3dCurCameraIndex == t3dLastCameraIndex) && !(bForceDirectCamera && !bCutCamera)) return;
bCameraCarrello = FALSE;
// Puntatore alla vecchia e alla nuova camera
LastCamera = t3dCurCamera;
DestCamera = PickCamera(croom, t3dCurCameraIndex);
// DestCamera->Fov = CAMERA_FOV;
// LastCamera->Fov = CAMERA_FOV;
i = 255;
// Cerca il percorso che mi porta la veccia camera nella nuova camera
if (LastCamera->NumAvailablePaths() < 255)
for (i = 0; i < LastCamera->NumAvailablePaths(); i++)
if (LastCamera->CameraPaths[i].NumCamera == t3dCurCameraIndex)
break;
// Se non lo trova o se deve cambiare la camera senza fare il percorso e non puo' calcolarselo
if (((i >= LastCamera->NumAvailablePaths()) || (!LastCamera->NumAvailablePaths()) || bForceDirectCamera) && !bAllowCalcCamera) {
// Setta la nuova camera ed esce
t3dCurCamera = PickCamera(croom, t3dCurCameraIndex);
GetCameraTarget(init, &t3dCurCamera->Target);
// t3dCurCamera->Fov = CAMERA_FOV;
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
DestCamera = nullptr;
bMovingCamera = FALSE;
bForceDirectCamera = FALSE;
// Se ho selezionato un carrello, riposiziona il source
for (i = 0; i < t3dCurCamera->NumAvailablePaths(); i++)
if (t3dCurCamera->CameraPaths[i].PathIndex & 0x80) {
HandleCameraCarrello(croom);
break;
}
return ;
}
// Se non trova percorsi e puo' calcolarsi il percorso
if ((bAllowCalcCamera) && ((i >= LastCamera->NumAvailablePaths()) || (!LastCamera->NumAvailablePaths()))) {
t3dVectCopy(&Dest, &DestCamera->Source);
dist = t3dVectDistance(&LastCamera->Source, &Dest); // Calcola quanto deve muovere la camera
t3dVectSub(&Dir, &LastCamera->Source, &Dest);
t3dVectNormalize(&Dir);
CurCameraStep = 0;
CurCameraSubStep = 0;
NumCameraSteps = (int16)(dist / MAX_CAMERA_MOVE) + 1;
if (NumCameraSteps > MAX_CAMERA_STEPS) NumCameraSteps = MAX_CAMERA_STEPS - 1;
Dir *= (dist / NumCameraSteps);
// Copia tutti i passi del percorso partendo dall'arrivo
for (i = NumCameraSteps - 1; i >= 0; i--) {
t3dVectCopy(&CameraStep[i].Source, &Dest);
t3dVectAdd(&Dest, &Dest, &Dir);
CameraStep[i].Fov = LastCamera->Fov + (t3dF32)(((DestCamera->Fov - LastCamera->Fov) * (t3dF32)i) / (t3dF32)NumCameraSteps);
}
if (CameraTargetObj == oCAMERAMAX) { // Se deve mantenere il target di max
t3dVectCopy(&Dest, &DestCamera->MaxTarget);
dist = t3dVectDistance(&LastCamera->Target, &Dest); // Calcola quanto deve muovere il target
t3dVectSub(&Dir, &LastCamera->Target, &Dest);
t3dVectNormalize(&Dir);
Dir *= (dist / NumCameraSteps);
for (i = NumCameraSteps - 1; i >= 0; i--) {
t3dVectCopy(&CameraStep[i].MaxTarget, &Dest);
t3dVectCopy(&CameraStep[i].Target, &Dest);
t3dVectAdd(&Dest, &Dest, &Dir);
}
}
} else {
cp = &croom->CameraPath[(LastCamera->CameraPaths[i].PathIndex) & 0x7F];
cd = LastCamera->CameraPaths[i].Direction;
CurCameraStep = 0;
CurCameraSubStep = 0;
NumCameraSteps = cp->NumPoints();
if (NumCameraSteps > MAX_CAMERA_STEPS) NumCameraSteps = MAX_CAMERA_STEPS - 1;
for (i = 0; i < NumCameraSteps; i++) { // Copia tutti i passi del percorso
if (cd == 0)
t3dVectCopy(&CameraStep[i].Source, &cp->PList[cp->NumPoints() - 1 - i]);
else
t3dVectCopy(&CameraStep[i].Source, &cp->PList[i]);
CameraStep[i].Fov = LastCamera->Fov + (t3dF32)(((DestCamera->Fov - LastCamera->Fov) * (t3dF32)i) / (t3dF32)NumCameraSteps);
}
}
bMovingCamera = TRUE; // Abilita la modalita' muovi camera
NextCameraStep(game); // Avanza al primo frame del percorso
}
/* -----------------16/12/00 15.20-------------------
* GetCameraIndexUnderPlayer
* --------------------------------------------------*/
uint8 CameraMan::GetCameraIndexUnderPlayer(int32 pl) {
t3dBODY *croom;
int16 row, col;
int32 a, b;
t3dV3F ct;
uint8 cc;
croom = t3dCurRoom; // Stanza attuale
if ((!croom) || (!Character[pl])) return (255);
// Se non c'e' la griglia o non c'e' il personaggio o la camera attuale
if (croom->CameraGrid.Grid.empty()) return (255);
t3dVectCopy(&ct, &Character[pl]->Mesh->Trasl);
// Mi calcolo in che casella sta l'omino
col = (int16)((ct.x - croom->CameraGrid.TopLeft.x) / croom->CameraGrid.CellDim.x);
row = (int16)((ct.z - croom->CameraGrid.TopLeft.z) / croom->CameraGrid.CellDim.z);
// Aggiorno Camera
// Se non e' valida esco
if (((col < 0 || row < 0) || (col >= croom->CameraGrid.Col) || (row >= croom->CameraGrid.Row))) return (255);
// Prendo l'indice della nuova stanza e se e' in una zona libera esce
cc = croom->CameraGrid.Grid[col + row * croom->CameraGrid.Col];
// Se e' in zona libera e la vecchia telecamera era in zona libera, ricerca a spirale
if (cc == 255) {
for (a = 1; a < 10; a++) {
for (b = -a; b <= a; b++) {
if ((col + b) >= 0 || (row + a) >= 0 || (col + b) < croom->CameraGrid.Col || (row + a) < croom->CameraGrid.Row)
if ((cc = croom->CameraGrid.Grid[col + b + (row + a) * croom->CameraGrid.Col]) != 255) break;
if ((col + b) >= 0 || (row - a) >= 0 || (col + b) < croom->CameraGrid.Col || (row - a) < croom->CameraGrid.Row)
if ((cc = croom->CameraGrid.Grid[col + b + (row - a) * croom->CameraGrid.Col]) != 255) break;
if ((col + a) >= 0 || (row + b) >= 0 || (col + a) < croom->CameraGrid.Col || (row + b) < croom->CameraGrid.Row)
if ((cc = croom->CameraGrid.Grid[col + a + (row + b) * croom->CameraGrid.Col]) != 255) break;
if ((col - a) >= 0 || (row + b) >= 0 || (col - a) < croom->CameraGrid.Col || (row + b) < croom->CameraGrid.Row)
if ((cc = croom->CameraGrid.Grid[col - a + (row + b) * croom->CameraGrid.Col]) != 255) break;
}
if (cc != 255) break;
}
}
return (cc);
}
/* -----------------08/10/98 18.08-------------------
* StartAnimCamera
* --------------------------------------------------*/
void CameraMan::StartAnimCamera(WGame &game) {
DebugLogFile("StartAnimCamera");
t3dLastCameraIndex = t3dCurCameraIndex;
if (ForcedCamera) t3dCurCameraIndex = ForcedCamera - 1;
LastCamera = t3dCurCamera;
DestCamera = PickCamera(t3dCurRoom, t3dCurCameraIndex);
AnimCamera = *DestCamera;
t3dCurCamera = &AnimCamera;
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
bCameraCarrello = FALSE;
bCutCamera = FALSE;
bAllowCalcCamera = FALSE;
bMovingCamera = 2;
NextCameraStep(game);
}
/* -----------------09/11/98 10.32-------------------
* ClipGolfCameraMove
* --------------------------------------------------*/
uint8 CameraMan::ClipGolfCameraMove(t3dV3F *NewT, t3dV3F *OldT, t3dV3F *Source) {
t3dV3F n, o;
t3dF32 a, d, l;
t3dVectSub(&n, NewT, Source);
t3dVectSub(&o, OldT, Source);
t3dVectNormalize(&n);
t3dVectNormalize(&o);
a = t3dVectAngle(&o, &n);
if (a > MAX_CAMERA_ANGLE / 3) d = (MAX_CAMERA_ANGLE / 3 * T3D_PI) / 180.0f;
else if (a < -MAX_CAMERA_ANGLE / 3) d = -(MAX_CAMERA_ANGLE / 3 * T3D_PI) / 180.0f;
else return 0;
a = (a * T3D_PI) / 180.0f;
t3dVectSub(&o, NewT, OldT);
t3dVectNormalize(&o);
l = (t3dVectDistance(NewT, OldT) * d) / a;
o *= l;
t3dVectAdd(NewT, OldT, &o);
/* t3dVectSub( &o, OldT, Source );
t3dVectNormalize( &o );
l = t3dVectDistance( OldT, Source );
// l += ( ( l - t3dVectDistance( NewT, Source ) ) * d ) / a;
t3dVectScale( &o, &o, l );
t3dMatRot( &m, 0.0f, d, 0.0f );
t3dVectTransform( NewT, &o, &m );
t3dVectAdd( NewT, NewT, Source );
NewT->y += ( ( NewT->y - OldT->y ) * d ) / a;
*/
return 1;
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,73 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_CAMERA_H
#define WATCHMAKER_DO_CAMERA_H
#include "watchmaker/t3d.h"
#include "watchmaker/globvar.h"
#include "watchmaker/game.h"
namespace Watchmaker {
class CameraMan {
// Constants:
static const int MAX_CAMERA_STEPS = 500;
t3dCAMERA FirstPersonCamera, *DestCamera, *LastCamera, CameraCarrello;
t3dCAMERA CameraStep[MAX_CAMERA_STEPS], AnimCamera;
int16 CurCameraSubStep = 0, CurCameraStep = 0, NumCameraSteps = 0;
t3dV3F OldCameraTarget, OldPlayerDir, FirstPersonTarget;
t3dV3F SourceBlend, TargetBlend;
uint8 bForceDirectCamera = false, bCameraCarrello = false;
uint8 t3dCurCameraIndex = 255;
uint8 t3dLastCameraIndex = 255;
void NextCameraStep(WGame &game);
void HandleCameraCarrello(t3dBODY *croom);
public:
t3dV3F HeadAngles;
t3dF32 CamAngleX, CamAngleY;
void resetAngle();
void resetLastCameraIndex() { t3dLastCameraIndex = 255; }
uint8 getCurCameraIndex() { return t3dCurCameraIndex; }
void MoveHeadAngles(t3dF32 diffx, t3dF32 diffy);
void GetCameraTarget(Init &init, t3dV3F *Target);
t3dCAMERA *PickCamera(t3dBODY *b, unsigned char in);
void doCamera(WGame &game);
void GetRealCharPos(Init &init, t3dV3F *Target, int32 oc, uint8 bn);
void ResetCameraTarget();
void ResetCameraSource();
void ProcessCamera(WGame &game);
uint8 GetCameraIndexUnderPlayer(int32 pl);
void StartAnimCamera(WGame &game);
uint8 ClipGolfCameraMove(t3dV3F *NewT, t3dV3F *OldT, t3dV3F *Source);
};
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_CAMERA_H

View File

@@ -0,0 +1,540 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_dialog.h"
#include "watchmaker/globvar.h"
#include "watchmaker/define.h"
#include "watchmaker/3d/math/llmath.h"
#include "watchmaker/message.h"
#include "watchmaker/3d/loader.h"
#include "watchmaker/3d/geometry.h"
#include "watchmaker/3d/t3d_body.h"
#include "watchmaker/schedule.h"
#include "watchmaker/ll/ll_anim.h"
#include "watchmaker/walk/act.h"
#include "watchmaker/ll/ll_diary.h"
#include "watchmaker/ll/ll_util.h"
#include "watchmaker/classes/do_player.h"
#include "watchmaker/main.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/classes/do_inv.h"
#include "watchmaker/ll/ll_string.h"
#include "watchmaker/classes/do_system.h"
#include "watchmaker/classes/do_camera.h"
#include "watchmaker/classes/do_string.h"
#include "watchmaker/renderer.h"
namespace Watchmaker {
// locals
int32 DebugSent = 0;
int16 NextDlg = dNULL;
int32 ic1, ic2;
/* -----------------03/06/98 10.11-------------------
* doDialog
* --------------------------------------------------*/
void doDialog(WGame &game) {
Init &init = game.init;
struct SItemCommand *ic;
uint8 r;
switch (TheMessage->event) {
case ME_DIALOGSTART:
if (TheMessage->wparam1 == dR391) {
if (Character[ocCHIRURGO]->Mesh)
t3dVectFill(&Character[ocCHIRURGO]->Mesh->Trasl, 0.0f);
if (Character[ocVECCHIO]->Mesh)
t3dVectFill(&Character[ocVECCHIO]->Mesh->Trasl, 0.0f);
if (Character[ocOROLOGIAIO]->Mesh)
t3dVectFill(&Character[ocOROLOGIAIO]->Mesh->Trasl, 0.0f);
if (Character[ocTRADUTTORE]->Mesh)
t3dVectFill(&Character[ocTRADUTTORE]->Mesh->Trasl, 0.0f);
bSuperView = 1;
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
}
//faccio apparire la scritta di descrizione della stanza di Darrell
if ((TheMessage->wparam1 == dR000) && bShowRoomDescriptions) {
t3dCurTime = 240;
RoomInfo.name[0] = '\0';
UpdateRoomInfo(game);
}
// I make darrell disappear
if ((TheMessage->wparam1 == dRLOGHI) || (TheMessage->wparam1 == dR000)) {
Character[ocDARRELL]->Flags |= T3D_CHARACTER_HIDE; //I hide darrell to make sure he doesn't show while he loads the animations
}
if ((init.Dialog[TheMessage->wparam1].flags & DIALOG_ONCE) && (init.Dialog[TheMessage->wparam1].flags & DIALOG_DONE))
return ;
StopDiary(game, game._gameVars.getCurRoomId(), init.Dialog[TheMessage->wparam1].obj, 0);
CurDialog = TheMessage->wparam1;
bDialogActive = true;
bDialogMenuActive = true;
CurDlgItem = -1;
CurMenu = mMAIN;
InvStatus = INV_OFF;
BigInvObj = iNULL;
NextDlg = dNULL;
ClearUseWith();
ClearText();
CharStop(ocCURPLAYER);
if (bFirstPerson)
game._renderer->setCurCameraViewport(74, bSuperView);
bDialogMenuActive = false;
//DebugFile("DLG: StartDialog %d",CurDialog);
// Se sono in un fullmotion
if ((init.Dialog[CurDialog].flags & DIALOG_RTV2) && (init.Dialog[CurDialog].ItemIndex[mRTV2]))
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGCONTINUE, MP_DEFAULT, (int16)CurDialog, mRTV2, 0, nullptr, nullptr, nullptr);
else if ((init.Dialog[CurDialog].flags & DIALOG_RTV3) && (init.Dialog[CurDialog].ItemIndex[mRTV3]))
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGCONTINUE, MP_DEFAULT, (int16)CurDialog, mRTV3, 0, nullptr, nullptr, nullptr);
else if ((init.Dialog[CurDialog].flags & DIALOG_RTV) || (init.Dialog[CurDialog].ItemIndex[mRTV]))
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGCONTINUE, MP_DEFAULT, (int16)CurDialog, mRTV, 0, nullptr, nullptr, nullptr);
// Se c'e' un predialog attivo
else if (init.Dialog[CurDialog].flags & (DIALOG_PRE1 | DIALOG_PRE2 | DIALOG_PRE3 | DIALOG_PRE4)) {
if (init.Dialog[CurDialog].flags & DIALOG_PRE_RAND)
while (!(init.Dialog[CurDialog].flags & (DIALOG_PRE1 << (r = (game._rnd->getRandomNumber(3))))));
else if (init.Dialog[CurDialog].flags & DIALOG_PRE1) r = 0;
else if (init.Dialog[CurDialog].flags & DIALOG_PRE2) r = 1;
else if (init.Dialog[CurDialog].flags & DIALOG_PRE3) r = 2;
else r = 3;
if (init.Dialog[CurDialog].ItemIndex[mPREDIALOG1 + r])
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGCONTINUE, MP_DEFAULT, (int16)CurDialog, (int16)(mPREDIALOG1 + r), 0, nullptr, nullptr, nullptr);
else
bDialogMenuActive = true;
} else
bDialogMenuActive = true;
break;
case ME_DIALOGCONTINUE:
CurDialog = TheMessage->wparam1;
CurDlgItem = TheMessage->wparam2;
bDialogMenuActive = false;
ic = &init.DlgItem[init.Dialog[CurDialog].ItemIndex[CurDlgItem]].item[CurPlayer][TheMessage->lparam[0]];
// Finche' non ci sono comandi che deve aspettare tempo, li fa tutti
while (ic->com) {
TheMessage->lparam[0] ++;
// DebugLogFile("IC %d %d %d | %d %d %d",ic->com,ic->param1,ic->param2,CurDialog,CurDlgItem,TheMessage->lparam[0]);
switch (ic->com) {
case IC_NULL: // Esce dal dialogo
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGEND, MP_DEFAULT, 0, 0, 0, nullptr, nullptr, nullptr);
break;
case IC_SET_PLAYER: // non fa niente
break;
case IC_ANIM:
//DebugFile("DLG: StartAnim %d",ic->param1);
StartAnim(game, GetAlternateAnim(init, ic->param1));
break;
case IC_SET_CAMERA:
ForcedCamera = GetAlternateCamera(init, (uint8)ic->param1);
bCutCamera = true;
bAllowCalcCamera = false;
break;
case IC_MOVE_CAMERA_TO:
ForcedCamera = GetAlternateCamera(init, (uint8)ic->param1);
bCutCamera = false;
bAllowCalcCamera = true;
break;
case IC_SET_TARGET:
CameraTargetObj = ic->param1;
CameraTargetBone = ic->param2;
break;
case IC_SET_CHAR:
CharSetPosition(ic->param1, GetAlternatePosition(init, (uint8)ic->param2), nullptr);
CharStop(ic->param1);
break;
case IC_WALK_CHAR:
case IC_RUN_CHAR:
case IC_BACK_CHAR:
CharGotoPosition(game, ic->param1, GetAlternatePosition(init, (uint8)ic->param2), (uint8)(ic->com - IC_WALK_CHAR), 0);
TimeWalk = 0;
break;
case IC_HIDE_CHAR:
Character[ic->param1]->Flags |= T3D_CHARACTER_HIDE;
break;
case IC_UNHIDE_CHAR:
Character[ic->param1]->Flags &= ~T3D_CHARACTER_HIDE;
break;
case IC_CHANGE_ROOM:
ChangeRoom(game, Common::String::format("%s.t3d", init.Room[ic->param1].name), 0, aNULL);
break;
case IC_EXPRESSION:
if (Character[ic->param1])
Character[ic->param1]->CurExpressionSet = ic->param2;
break;
case IC_CHANGE_PLAYER:
UpdatePlayerStand(game, (uint8)(CurPlayer + ocDARRELL));
CurPlayer = (ic->param1 == ocDARRELL) ? DARRELL : VICTORIA;
Character[ocCURPLAYER] = Character[ic->param1];
Player = Character[ocCURPLAYER];
Player->Flags &= ~T3D_CHARACTER_HIDE;
break;
case IC_DEBUG:
DebugSent = ic->param1;
break;
case IC_ITEM:
init.DlgMenu[ic->param1].on = (uint8)ic->param2;
break;
case IC_SET_FLAGS:
if (ic->param1 != dNULL)
init.Dialog[ic->param1].flags |= ic->param2;
else
init.Dialog[CurDialog].flags |= ic->param2;
break;
case IC_CLR_FLAGS:
if (ic->param1 != dNULL)
init.Dialog[ic->param1].flags &= ~ic->param2;
else
init.Dialog[CurDialog].flags &= ~ic->param2;
break;
case IC_ATFRAME:
init.Anim[aDUMMY].atframe[0].type = (uint8)ic->param1;
init.Anim[aDUMMY].atframe[0].index = ic->param2;
init.Anim[aDUMMY].active = 12;
ProcessATF(game, aDUMMY, 0);
init.Anim[aDUMMY].active = 0;
break;
case IC_NEXT_DLG:
NextDlg = (int16)ic->param1;
break;
case IC_SET_CHAR2:
if (CurAlternate[ic->param1]) break;
CharSetPosition(ic->param1, GetAlternatePosition(init, (uint8)ic->param2), nullptr);
CharStop(ic->param1);
break;
case IC_INTRO_TEXT1:
ic1 = ic->param1;
ic2 = ic->param2;
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_DEFAULT, FRAME_PER_SECOND, FRAME_PER_SECOND, EFFECT_FADEOUT_T1, &ic1, nullptr, nullptr);
if (ic2)
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_WAITA, FRAME_PER_SECOND, FRAME_PER_SECOND, EFFECT_MOVEIN_T1, &ic1, nullptr, &ic2);
break;
case IC_INTRO_TEXT2:
ic1 = ic->param1;
ic2 = ic->param2;
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_DEFAULT, FRAME_PER_SECOND, FRAME_PER_SECOND, EFFECT_FADEOUT_T2, &ic1, nullptr, nullptr);
if (ic2)
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_WAITA, FRAME_PER_SECOND, FRAME_PER_SECOND, EFFECT_MOVEIN_T2, &ic1, nullptr, &ic2);
break;
case IC_TIME_ANIM:
//DebugFile("DLG: StartTimeAnim %d %d",ic->param1,ic->param2);
AnimAutoPush = ic->param2;
StartAnim(game, GetAlternateAnim(init, ic->param1));
TheMessage->flags |= MP_WAIT_ANIM;
TimeAnim = GetAlternateAnim(init, ic->param1);
ReEvent();
return ;
case IC_TIME_ANIM2:
//DebugFile("DLG: StartTimeAnim %d %d",ic->param1,ic->param2);
StartAnim(game, GetAlternateAnim(init, ic->param1));
TheMessage->flags |= MP_WAIT_ANIM;
TimeAnim = GetAlternateAnim(init, ic->param1);
ReEvent();
return ;
case IC_TIME_WALK_CHAR:
case IC_TIME_RUN_CHAR:
case IC_TIME_BACK_CHAR:
if (!CharGotoPosition(game, ic->param1, GetAlternatePosition(init, (uint8)ic->param2), (uint8)(ic->com - IC_TIME_WALK_CHAR), 0)) break;
TimeWalk = ic->param1;
TheMessage->flags |= MP_WAIT_ACT;
ReEvent();
return ;
case IC_TIME_WAIT_CAMERA:
TheMessage->flags |= MP_WAIT_CAMERA;
ReEvent();
return ;
case IC_TIME_WAIT:
if (TheMessage->lparam[1] == 0) {
TheMessage->lparam[1] = ic->param1;
if (DebugSent && (LoaderFlags & T3D_DEBUGMODE)) PlayerSpeak(game, DebugSent);
}
if (TheMessage->lparam[1] > 1) {
TheMessage->lparam[0] --;
TheMessage->lparam[1] --;
TheMessage->flags |= MP_WAIT_RETRACE;
ReEvent();
return;
}
TheMessage->lparam[1] = 0;
bSkipTalk = false;
DebugSent = 0;
break;
case IC_TIME_FADOUT:
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_DEFAULT, ic->param1, 1, EFFECT_FADOUT, nullptr, nullptr, nullptr);
TheMessage->flags |= MP_WAITA;
ReEvent();
return ;
}
ic = &init.DlgItem[init.Dialog[CurDialog].ItemIndex[CurDlgItem]].item[CurPlayer][TheMessage->lparam[0]];
}
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGEND, MP_DEFAULT, (int16)CurDialog, (int16)CurDlgItem, 0, nullptr, nullptr, nullptr);
break;
case ME_DIALOGEND:
case ME_DIALOGEND_SKIPINTRO:
if (TheMessage->wparam1 == dR391) {
bSuperView = 0;
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
NextDlg = dR391_end;
}
CurDialog = TheMessage->wparam1;
CurDlgItem = TheMessage->wparam2;
game._messageSystem.removeEvent(EventClass::MC_DIALOG, ME_ALL);
// Se c'e' un enddialog attivo
if ((CurDlgItem == mQUIT) && (init.Dialog[CurDialog].flags & (DIALOG_END1 | DIALOG_END2 | DIALOG_END3))) {
if (init.Dialog[CurDialog].flags & DIALOG_END_RAND)
while (!(init.Dialog[CurDialog].flags & (DIALOG_END1 << (r = (game._rnd->getRandomNumber(2))))));
else if (init.Dialog[CurDialog].flags & DIALOG_END1) r = 0;
else if (init.Dialog[CurDialog].flags & DIALOG_END2) r = 1;
else r = 2;
if (init.Dialog[CurDialog].ItemIndex[mENDDIALOG1 + r]) {
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGCONTINUE, MP_DEFAULT, (int16)(CurDialog), (int16)(mENDDIALOG1 + r), 0, nullptr, nullptr, nullptr);
return ;
}
}
if ((CurDlgItem == mRTV) || (CurDlgItem == mRTV2) || (CurDlgItem == mRTV3) || (CurDlgItem == mQUIT) ||
(CurDlgItem == mENDDIALOG1) || (CurDlgItem == mENDDIALOG2) || (CurDlgItem == mENDDIALOG3)) {
//DebugFile("DLG: EndDialog %d",CurDialog);
StopObjAnim(game, ocCURPLAYER);
CharStop(ocCURPLAYER); //evito che negli interrupt (in particolare) rimanga in memoria l'animazione di ascolta
game._cameraMan->ResetCameraTarget();
init.Dialog[CurDialog].flags |= DIALOG_DONE;
CurDialog = dNULL;
bDialogActive = false;
bDialogMenuActive = false;
bAnimWaitText = false;
CurDlgItem = -1;
CurMenu = mNULL;
ForcedCamera = 0;
bCutCamera = false;
bAllowCalcCamera = false;
CameraTargetObj = ocCURPLAYER;
CameraTargetBone = 0;
TimeWalk = ocCURPLAYER;
TimeAnim = aNULL;
bPlayerInAnim = false;
if (NextDlg != dNULL)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, NextDlg, 0, 0, nullptr, nullptr, nullptr);
else {
if ((init.Dialog[TheMessage->wparam1].obj) && (Character[init.Dialog[TheMessage->wparam1].obj]))
StartDiary(game, game._gameVars.getCurRoomId(), &Character[init.Dialog[TheMessage->wparam1].obj]->Mesh->Trasl);
else
StartDiary(game, game._gameVars.getCurRoomId(), nullptr);
DebugLogFile("EndDialog: resetto t3dLastCameraIndex");
game._cameraMan->resetLastCameraIndex(); //forzo ProcessCamera() a cercare una nuova camera, in modo finito il dialogo non rimane qualche strana camera
}
} else
bDialogMenuActive = true;
if (TheMessage->event == ME_DIALOGEND_SKIPINTRO)
if (! DataLoad(game, "WmStart.dat", 0)) {
DebugLogFile("SkipIntro: DataLoad() Failed. Quitting ...");
CloseSys(game);
}
if (TheMessage->wparam1 == dRLOGHI)
ProcessATFDO(game, fSTART_MAIN_MENU);
break;
}
}
/* -----------------06/07/00 10.48-------------------
* GetAlternatePosition
* --------------------------------------------------*/
uint8 GetAlternatePosition(Init &init, uint8 pos) {
struct SDialog *d = &init.Dialog[CurDialog];
int32 alt;
if (!d || !d->obj || !(alt = CurAlternate[d->obj])) return pos;
alt --;
if (d->AltPosSco[alt]) return pos + d->AltPosSco[alt];
return pos;
}
/* -----------------06/07/00 10.49-------------------
* GetAlternateCamera
* --------------------------------------------------*/
uint8 GetAlternateCamera(Init &init, uint8 cam) {
struct SDialog *d = &init.Dialog[CurDialog];
int32 alt;
if (!d || !d->obj || !(alt = CurAlternate[d->obj])) return cam;
alt --;
if (d->AltCamSco[alt]) return cam + d->AltCamSco[alt];
return cam;
}
/* -----------------06/07/00 10.49-------------------
* GetAlternateAnim
* --------------------------------------------------*/
int32 GetAlternateAnim(Init &init, int32 an) {
struct SDialog *d = &init.Dialog[CurDialog];
int32 a, alt;
if (!d || !d->obj || !(alt = CurAlternate[d->obj])) return an;
alt --;
for (a = 0; a < MAX_ALT_ANIMS; a++)
if ((d->AltAnims[alt][a][0] == an) && (d->AltAnims[alt][a][1] != aNULL))
return d->AltAnims[alt][a][1];
return an;
}
/* -----------------03/06/98 11.31-------------------
* UpdateDialogMenu
* --------------------------------------------------*/
void UpdateDialogMenu(WGame &game, int16 dmx, int16 dmy, uint8 db) {
struct SRect t;
int32 a, ca1, ca2;
Init &init = game.init;
Renderer &renderer = *game._renderer;
if ((bDialogActive == FALSE) || (CurDialog == dNULL) || (bDialogMenuActive == FALSE))
return ;
if ((db == ME_MLEFT) && (CurDlgItem) && (init.DlgMenu[CurDlgItem].parent == mMAIN)) {
CurMenu = CurDlgItem;
Diag2Base = 0;
} else if ((db == ME_MLEFT) && (CurDlgItem) && (CurDlgItem != -1)) { // TODO: The original didn't have a check for -1 here
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGCONTINUE, MP_DEFAULT, (int16)CurDialog, (int16)CurDlgItem, 0, nullptr, nullptr, nullptr);
UsedDlgMenu[CurPlayer][CurObj][CurDlgItem] = 1;
} else if ((db == ME_MRIGHT) && (CurMenu == mMAIN))
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGEND, MP_DEFAULT, (int16)CurDialog, (int16)mQUIT, 0, nullptr, nullptr, nullptr);
else if (db == ME_MRIGHT) {
CurMenu = mMAIN;
Diag2Base = 0;
}
//if( ( db == ME_MLEFT ) || ( db == ME_MRIGHT ) ) DebugFile("DLG: Click %d %d",CurMenu,CurDlgItem);
for (a = 0, ca1 = 0, ca2 = 0; a < MAX_DLG_MENUS; a++) {
if (!(init.DlgMenu[a].on)) continue;
// se la servetta mi ha gia' dato la banconota devo fare in modo che non me la dia ancora
if ((a == mCOSEFATTI8) && (CurObj == ocSERVETTA) && (IconInInv(init, i2cBANCONOTA1))) continue;
CurDlgItem = a;
if (init.DlgMenu[a].parent == mMAIN) {
t.x1 = DIAG1_MARG_SX;
t.x2 = DIAG1_MARG_DX;
t.y1 = DIAG1_MARG_UP + DIAG_DY * ca1;
t.y2 = DIAG1_MARG_UP + DIAG_DY * (ca1 + 1);
ca1++;
if (CheckRect(renderer, t, dmx, dmy)) return;
} else if (init.DlgMenu[a].parent == CurMenu) {
t.x1 = DIAG2_MARG_SX;
t.x2 = DIAG2_MARG_DX;
t.y1 = DIAG2_MARG_UP + DIAG2_DY * (ca2 - Diag2Base);
t.y2 = DIAG2_MARG_UP + DIAG2_DY * ((ca2 - Diag2Base) + 1);
ca2++;
if ((ca2 < Diag2Base) || (ca2 > (Diag2Base + MAX_DIAG2_ITEMS))) continue;
if (CheckRect(renderer, t, dmx, dmy)) return;
}
}
CurDlgItem = -1;
if ((db == ME_MLEFT) || (db == ME_MRIGHT)) {
// Se si cambia la logica di incremento variarla anche in PaintDialog() nella gestione delle freccette
if (CheckRect(renderer, game._gameRect._diag2Up, dmx, dmy))
Diag2Base = ((Diag2Base - 1) < 0) ? 0 : Diag2Base - 1;
else if (CheckRect(renderer, game._gameRect._diag2Down, dmx, dmy))
if ((Diag2Base + 1 + MAX_DIAG2_ITEMS) <= ca2)
Diag2Base ++;
}
}
/* -----------------03/06/98 10.47-------------------
* PaintDialog
* --------------------------------------------------*/
void PaintDialog(WGame &game) {
int32 a, ca1, ca2;
int32 tx = 0, ty = 0;
FontColor tc;
Init &init = game.init;
if ((bDialogActive == FALSE) || (CurDialog == dNULL) || (bDialogMenuActive == FALSE))
return ;
game._renderer->_2dStuff.displayDDBitmap(ConsoleD1, 7, 366, 0, 0, 0, 0);
DisplayD3DRect(*game._renderer, 15, 373, 187, 211, 18, 25, 18, 128);
game._renderer->_2dStuff.displayDDBitmap(ConsoleD2, 223, 515, 0, 0, 0, 0);
DisplayD3DRect(*game._renderer, 223 + 6, 515 + 6, 536, 62, 18, 25, 18, 128);
DisplayD3DRect(*game._renderer, 223 + 546, 515 + 22, 16, 30, 18, 25, 18, 128);
DisplayD3DRect(*game._renderer, 223 + 542, 515 + 18, 4, 38, 18, 25, 18, 128);
for (a = 0, ca1 = 0, ca2 = 0; a < MAX_DLG_MENUS; a++) {
if (!(init.DlgMenu[a].on) || ((init.DlgMenu[a].parent != mMAIN) && (init.DlgMenu[a].parent != CurMenu))) continue;
// se la servetta mi ha gia' dato la banconota devo fare in modo che non me la dia ancora
if ((a == mCOSEFATTI8) && (CurObj == ocSERVETTA) && (IconInInv(init, i2cBANCONOTA1))) continue;
tc = WHITE_FONT;
if (init.DlgMenu[a].parent == mMAIN) {
tx = DIAG1_MARG_SX;
ty = DIAG1_MARG_UP + DIAG_DY * ca1;
ca1++;
if (CurMenu == a) tc = YELLOW_FONT;
} else if (init.DlgMenu[a].parent == CurMenu) {
tx = DIAG2_MARG_SX;
ty = DIAG2_MARG_UP + DIAG2_DY * (ca2 - Diag2Base);
ca2++;
if ((ca2 <= Diag2Base) || (ca2 > (Diag2Base + MAX_DIAG2_ITEMS))) continue;
if (UsedDlgMenu[CurPlayer][CurObj][a]) tc = GRAY_FONT;
}
if (CurDlgItem == a) tc = RED_FONT;
game._renderer->_2dStuff.displayDDText(Sentence[init.DlgMenu[a].titolo], FontKind::Standard, tc, tx, ty, 0, 0, 0, 0);
}
// disegno le frecce
if (Diag2Base > 0)
game._renderer->_2dStuff.displayDDBitmap(ConsoleFrecciaSu, 223 + 550, 515 + 0, 0, 0, 0, 0);
if ((Diag2Base + 1 + MAX_DIAG2_ITEMS) <= ca2)
game._renderer->_2dStuff.displayDDBitmap(ConsoleFrecciaGiu, 223 + 550, 515 + 56, 0, 0, 0, 0);
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,42 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_DIALOG_H
#define WATCHMAKER_DO_DIALOG_H
#include "watchmaker/types.h"
#include "watchmaker/globvar.h"
#include "watchmaker/game.h"
namespace Watchmaker {
extern int16 NextDlg;
void doDialog(WGame &game);
void PaintDialog(WGame &game);
void UpdateDialogMenu(WGame &game, int16 dmx, int16 dmy, uint8 db);
int32 GetAlternateAnim(Init &init, int32 an);
uint8 GetAlternateCamera(Init &init, uint8 cam);
uint8 GetAlternatePosition(Init &init, uint8 pos);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_DIALOG_H

View File

@@ -0,0 +1,387 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_inv.h"
#include "watchmaker/define.h"
#include "watchmaker/types.h"
#include "watchmaker/globvar.h"
#include "watchmaker/message.h"
#include "watchmaker/schedule.h"
#include "watchmaker/ll/ll_string.h"
#include "watchmaker/classes/do_player.h"
#include "watchmaker/ll/ll_mouse.h"
#include "watchmaker/3d/geometry.h"
#include "watchmaker/ll/ll_anim.h"
#include "watchmaker/classes/do_string.h"
#include "watchmaker/classes/do_camera.h"
#include "watchmaker/classes/do_inv_inv.h"
#include "watchmaker/classes/do_inv_scr.h"
#include "watchmaker/classes/do_scr_scr.h"
#include "watchmaker/classes/do_sound.h"
#include "watchmaker/ll/ll_diary.h"
#include "watchmaker/walk/act.h"
#include "watchmaker/3d/math/llmath.h"
#include "watchmaker/ll/ll_util.h"
#include "watchmaker/renderer.h"
namespace Watchmaker {
/* -----------------03/04/98 10.39-------------------
* IconInInv
* --------------------------------------------------*/
uint8 IconInInv(Init &/*init*/, uint8 icon) {
uint8 i;
for (i = 0; i < MAX_ICONS_IN_INV; i++)
if ((Inv[CurPlayer][i] == icon) || (Inv[CurPlayer ^ 1][i] == icon))
break;
if (i == MAX_ICONS_IN_INV)
return false;
else
return true;
}
/* -----------------03/04/98 10.39-------------------
* IconPos
* --------------------------------------------------*/
uint8 IconPos(uint8 icon) {
uint8 i;
for (i = 0; i < MAX_ICONS_IN_INV; i++)
if (Inv[CurPlayer][i] == icon)
break;
return i;
}
/* -----------------03/04/98 10.41-------------------
* KillIcon
* --------------------------------------------------*/
void KillIcon(Init &init, uint8 icon) {
uint8 pos = IconPos(icon), op = CurPlayer;
if (pos == MAX_ICONS_IN_INV) {
CurPlayer ^= 1;
if ((pos = IconPos(icon)) == MAX_ICONS_IN_INV) {
CurPlayer = op;
return;
}
}
init.InvObj[icon].flags &= ~ON;
Inv[CurPlayer][pos] = iNULL;
for (; pos < InvLen[CurPlayer]; pos++)
Inv[CurPlayer][pos] = Inv[CurPlayer][pos + 1];
InvLen[CurPlayer] --;
if (InvBase[CurPlayer])
if ((InvLen[CurPlayer] > MAX_SHOWN_ICONS) && (Inv[CurPlayer][InvBase[CurPlayer] + MAX_SHOWN_ICONS] == iNULL))
InvBase[CurPlayer] = InvLen[CurPlayer] - MAX_SHOWN_ICONS;
if (CurInvObj == icon) CurInvObj = iNULL;
if (BigInvObj == icon) BigInvObj = iNULL;
CurPlayer = op;
}
/* -----------------03/04/98 10.50-------------------
* AddIcon
* --------------------------------------------------*/
void AddIcon(Init &init, uint8 icon) {
if (IconInInv(init, icon))
return;
init.InvObj[icon].flags |= ON;
Inv[CurPlayer][InvLen[CurPlayer]++] = icon;
if (InvLen[CurPlayer] < MAX_ICONS_IN_INV)
if (InvBase[CurPlayer] < InvLen[CurPlayer] - MAX_SHOWN_ICONS)
InvBase[CurPlayer] = InvLen[CurPlayer] - MAX_SHOWN_ICONS;
}
/* -----------------04/06/98 16.34-------------------
* ClearUseWith
* --------------------------------------------------*/
void ClearUseWith() {
bUseWith = UW_OFF;
UseWith[USED] = 0;
UseWith[WITH] = 0;
CurMousePointer = MousePointerDefault;
}
/* -----------------25/09/00 17.40-------------------
* SelectCurBigIcon
* --------------------------------------------------*/
void SelectCurBigIcon(uint8 icon) {
uint8 pos = IconPos(icon);
if (pos == MAX_ICONS_IN_INV) {
return;
}
CurInvObj = icon;
BigInvObj = icon;
}
/* -----------------23/04/98 14.45-------------------
* doUseWith
* --------------------------------------------------*/
void doUseWith(WGame &game) {
if (bUseWith & UW_USEDI) {
if (bUseWith & UW_WITHI)
doInvInvUseWith(game);
else
doInvScrUseWith(game);
//? BigInvObj = UseWith[USED];
} else {
doScrScrUseWith(game);
BigInvObj = iNULL;
}
ClearUseWith();
}
/* -----------------03/04/98 10.53-------------------
* ReplaceIcon
* --------------------------------------------------*/
void ReplaceIcon(Init &init, uint8 oldicon, uint8 newicon) {
uint8 pos = IconPos(oldicon), op = CurPlayer;
if (pos == MAX_ICONS_IN_INV) {
CurPlayer ^= 1;
if ((pos = IconPos(oldicon)) == MAX_ICONS_IN_INV) {
CurPlayer = op;
return;
}
}
init.InvObj[oldicon].flags &= ~ON;
init.InvObj[newicon].flags |= ON;
Inv[CurPlayer][pos] = newicon;
if (CurInvObj == oldicon) CurInvObj = newicon;
if (BigInvObj == oldicon) BigInvObj = newicon;
CurPlayer = op;
}
/* -----------------03/04/98 10.16-------------------
* doInventory
* --------------------------------------------------*/
void doInventory(WGame &game) {
uint8 ci;
Init &init = game.init;
switch (TheMessage->event) {
case ME_EXAMINEICON:
CurInvObj = TheMessage->lparam[0];
if (CurInvObj && (bUseWith & UW_ON)) {
UseWith[WITH] = CurInvObj;
bUseWith &= ~UW_ON;
bUseWith |= UW_WITHI;
ClearText();
// fa l'usa con
doUseWith(game);
} else if (CurInvObj) {
if (InvStatus & INV_MODE4) {
BigInvObj = iNULL;
if (
bSezioneLabirinto
|| (CurInvObj == i00TELEFONO) || (CurInvObj == i00TELEFONOVIC)
) {
PlayerSpeak(game, init.Obj[o2ACOMPUTER].action[CurPlayer]);
break;
}
ci = (uint8)CurInvObj;
KillIcon(init, ci);
CurPlayer ^= 1;
AddIcon(init, ci);
CurPlayer ^= 1;
break;
} else if (InvStatus & INV_MODE5) {
BigInvObj = CurInvObj;
ReplaceSaveLoadTexture(CurInvObj);
break;
} else if ((InvStatus & INV_MODE2) && ((CurInvObj == i00TELEFONO) || (CurInvObj == i00TELEFONOVIC))) {
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, 0, 0, tPDA, nullptr, nullptr, nullptr);
break;
}
BigInvObj = CurInvObj;
// Quando schiaccio sul nome dell'icona per aprire l'inventario grande non gli faccio dire la frase
if ((InvStatus & INV_ON) && (InvStatus & INV_MODE2))
PlayerSpeak(game, init.InvObj[CurInvObj].examine[CurPlayer]);
else
InvStatus = INV_ON | INV_MODE2;
}
break;
case ME_OPERATEICON:
CurInvObj = TheMessage->lparam[0];
if (bUseWith & UW_ON) {
UseWith[WITH] = CurInvObj;
bUseWith &= ~UW_ON;
bUseWith |= UW_WITHI;
ClearText();
// fa l'usa con
doUseWith(game);
break;
}
if (InvStatus & INV_MODE4) {
InvStatus &= ~INV_MODE4;
CurPlayer ^= 1;
CurInvObj = BigInvObj = iNULL;
} else if (init.InvObj[CurInvObj].flags & USEWITH) {
if (!(InvStatus & INV_MODE2))
InvStatus = INV_OFF;
UseWith[USED] = CurInvObj;
bUseWith = UW_ON | UW_USEDI;
ShowInvObjName(init, CurInvObj);
CurMousePointer = MousePointerPlus;
} else if (CurInvObj) {
if (init.InvObj[CurInvObj].anim[CurPlayer]) {
_vm->_messageSystem.doEvent(EventClass::MC_INVENTORY, ME_INVOFF, MP_DEFAULT, 0, 0, 0, nullptr, nullptr, nullptr);
StartAnim(game, init.InvObj[CurInvObj].anim[CurPlayer]);
break;
} else {
int an;
if (CurInvObj == i28WALKMANOK) {
if (init.InvObj[CurInvObj].flags & EXTRA) an = a289_noinctime;
else an = a289;
_vm->_messageSystem.doEvent(EventClass::MC_INVENTORY, ME_INVOFF, MP_DEFAULT, 0, 0, 0, nullptr, nullptr, nullptr);
StartAnim(game, an);
}
}
InvStatus = INV_ON | INV_MODE2;
if (CurInvObj == i22LIBROCHIUSODEPLIANT) {
StartSound(game, w228);
ReplaceIcon(init, i22LIBROCHIUSODEPLIANT, i22LIBROAPERTODEPLIANT);
} else if (CurInvObj == i22LIBROAPERTODEPLIANT) {
ReplaceIcon(init, i22LIBROAPERTODEPLIANT, i22DEPLIANT);
AddIcon(init, i22LIBROAPERTO);
IncCurTime(game, 10);
} else if (CurInvObj == i22LIBROAPERTO)
ReplaceIcon(init, i22LIBROAPERTO, i22LIBROCHIUSO);
else if (CurInvObj == i22LIBROCHIUSO)
ReplaceIcon(init, i22LIBROCHIUSO, i22LIBROAPERTO);
else if (CurInvObj == i3bLASTRA2VOLTI) {
StartSound(game, w3B22);
ReplaceIcon(init, i3bLASTRA2VOLTI, i3bLASTRABIANCA);
AddIcon(init, i3bLASTRANERA);
} else
PlayerSpeak(game, init.InvObj[CurInvObj].action[CurPlayer]);
}
break;
case ME_INVOFF:
case ME_INVMODE1:
case ME_INVMODE2:
case ME_INVMODE3:
case ME_INVMODE4:
case ME_INVSWITCH:
ClearText();
if (bSomeOneSpeak) bSkipTalk = true;
PlayerPos[CurPlayer + ocDARRELL] = 0;
PlayerGotoPos[CurPlayer + ocDARRELL] = 0;
game._messageSystem.removeEvent(EventClass::MC_PLAYER, ME_ALL);
CharStop(ocCURPLAYER);
if (TheMessage->event == ME_INVOFF)
InvStatus = INV_OFF;
else if (TheMessage->event == ME_INVSWITCH) {
if (InvStatus & INV_ON) {
if (InvStatus & INV_MODE4) {
CurPlayer ^= 1;
ChangePlayer(game, (uint8)((CurPlayer ^ 1) + ocDARRELL));
}
InvStatus = INV_OFF;
game._cameraMan->resetAngle();
game._cameraMan->GetCameraTarget(init, &t3dCurCamera->Target);
} else {
rGrabVideo("temp.tmp", 1);
InvStatus = INV_ON | INV_MODE1;
}
} else
InvStatus = INV_ON + (INV_MODE1 << (TheMessage->event - ME_INVMODE1));
if (InvStatus & INV_ON) {
if (TheMessage->event == ME_INVSWITCH) InvStatus |= INV_MODE1;
ClearUseWith();
mHide = false;
}
if (bFirstPerson)
game._renderer->setCurCameraViewport(CAMERA_FOV_1ST, bSuperView);
else
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
BigInvObj = TheMessage->wparam1;
if (TheMessage->event == ME_INVMODE3) {
bUseWith = UW_ON | (UW_USEDI * TheMessage->bparam);
UseWith[USED] = TheMessage->wparam1;
CurMousePointer = MousePointerPlus;
}
break;
}
}
/* -----------------03/04/98 10.29-------------------
* InventoryDown
* --------------------------------------------------*/
void InventoryDown() {
// Se si cambia la logica di incremento variarla anche in PaintInventory() nella gestione delle freccette
if (InvBase[CurPlayer] < (InvLen[CurPlayer] - MAX_SHOWN_ICONS))
InvBase[CurPlayer] ++;
}
/* -----------------03/04/98 10.29-------------------
* InventoryUp
* --------------------------------------------------*/
void InventoryUp() {
// Se si cambia la logica di incremento variarla anche in PaintInventory() nella gestione delle freccette
if (InvBase[CurPlayer] > 0)
InvBase[CurPlayer] --;
}
/* -----------------03/04/98 10.34-------------------
* WhatIcon
* --------------------------------------------------*/
uint8 WhatIcon(Renderer &renderer, int16 invmx, int16 invmy) {
struct SRect t;
t.x1 = INV_MARG_SX;
t.y1 = INV_MARG_UP;
t.x2 = INV_MARG_DX;
t.y2 = INV_MARG_DOWN;
if (CheckRect(renderer, t, invmx, invmy))
return Inv[CurPlayer][(InvBase[CurPlayer] + ((invmy - renderer.rFitY(INV_MARG_UP)) / (renderer.rFitY(ICON_DY))))];
else
return iNULL;
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,43 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_INV_H
#define WATCHMAKER_DO_INV_H
#include "watchmaker/globvar.h"
#include "watchmaker/game.h"
namespace Watchmaker {
void AddIcon(Init &init, uint8 icon);
void doInventory(WGame &game);
void doUseWith(WGame &game);
void KillIcon(Init &init, uint8 icon);
uint8 IconInInv(Init &init, uint8 icon);
void ReplaceIcon(Init &init, uint8 oldicon, uint8 newicon);
void ClearUseWith();
void InventoryUp();
void InventoryDown();
uint8 WhatIcon(Renderer &renderer, int16 invmx, int16 invmy);
void SelectCurBigIcon(uint8 icon);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_INV_H

View File

@@ -0,0 +1,133 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_inv_inv.h"
#include "watchmaker/define.h"
#include "watchmaker/globvar.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/message.h"
#include "watchmaker/schedule.h"
#include "watchmaker/classes/do_inv.h"
#include "watchmaker/ll/ll_diary.h"
#include "watchmaker/classes/do_sound.h"
#include "watchmaker/classes/do_string.h"
namespace Watchmaker {
/* -----------------19/05/98 16.40-------------------
* doInvInvUseWith
* --------------------------------------------------*/
void doInvInvUseWith(WGame &game) {
uint8 sent = TRUE;
Init &init = game.init;
switch (UseWith[USED]) {
case i00TELEFONO:
case i00TELEFONOVIC:
if ((UseWith[WITH] == i28WALKMANOK) && (init.InvObj[i28WALKMANOK].flags & EXTRA)) {
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, 0, 0, tPDA, &UseWith[WITH], nullptr, nullptr);
sent = FALSE;
}
break;
case i1dAUDIOCASSETTA:
if (UseWith[WITH] == i28WALKMANVUOTO) {
ReplaceIcon(init, i28WALKMANVUOTO, i28WALKMANNASTRO);
KillIcon(init, i1dAUDIOCASSETTA);
SelectCurBigIcon(i28WALKMANNASTRO);
UseWith[USED] = i28WALKMANNASTRO;
sent = false;
} else if (UseWith[WITH] == i28WALKMANPILE) {
ReplaceIcon(init, i28WALKMANPILE, i28WALKMANOK);
KillIcon(init, i1dAUDIOCASSETTA);
SelectCurBigIcon(i28WALKMANOK);
UseWith[USED] = i28WALKMANOK;
sent = false;
}
break;
case i25FIALEABPIENE:
if (UseWith[WITH] == i34STAMPO) {
ReplaceIcon(init, i34STAMPO, i25FIALEABUSATE);
ReplaceIcon(init, i25FIALEABPIENE, i25MEDAGLIONI4);
IncCurTime(game, 10);
}
break;
case i27PILE:
if (UseWith[WITH] == i28WALKMANVUOTO) {
ReplaceIcon(init, i28WALKMANVUOTO, i28WALKMANPILE);
KillIcon(init, i27PILE);
SelectCurBigIcon(i28WALKMANPILE);
UseWith[USED] = i28WALKMANPILE;
IncCurTime(game, 5);
sent = false;
} else if (UseWith[WITH] == i28WALKMANNASTRO) {
ReplaceIcon(init, i28WALKMANNASTRO, i28WALKMANOK);
KillIcon(init, i27PILE);
SelectCurBigIcon(i28WALKMANOK);
UseWith[USED] = i28WALKMANOK;
IncCurTime(game, 5);
sent = false;
}
break;
case i36BUSTA1DOSEA:
case i36BUSTA2DOSIA:
if (UseWith[WITH] == i2bSACCHETTOINCENSO)
ReplaceIcon(init, (uint8)UseWith[USED], i2rBUSTAVUOTAA);
break;
case i36BUSTA1DOSEB:
case i36BUSTA2DOSIB:
if (UseWith[WITH] == i2bSACCHETTOINCENSO)
ReplaceIcon(init, (uint8)UseWith[USED], i2rBUSTAVUOTAB);
break;
case i3bLASTRANERA:
if (UseWith[WITH] == i3bLASTRABIANCA) {
StartSound(game, w3B22);
ReplaceIcon(init, i3bLASTRABIANCA, i3bLASTRA2VOLTI);
KillIcon(init, i3bLASTRANERA);
SelectCurBigIcon(i3bLASTRA2VOLTI);
sent = false;
}
break;
case i3bLASTRABIANCA:
if (UseWith[WITH] == i3bLASTRANERA) {
StartSound(game, w3B22);
ReplaceIcon(init, i3bLASTRABIANCA, i3bLASTRA2VOLTI);
KillIcon(init, i3bLASTRANERA);
SelectCurBigIcon(i3bLASTRA2VOLTI);
sent = false;
}
break;
default:
sent = TRUE;
break;
}
if (sent)
if (!((bUseWith & UW_WITHI) && (UseWith[USED] == UseWith[WITH])))
PlayerSpeak(game, init.InvObj[UseWith[USED]].action[CurPlayer]);
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,33 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_INV_INV_H
#define WATCHMAKER_DO_INV_INV_H
#include "watchmaker/game.h"
namespace Watchmaker {
void doInvInvUseWith(WGame &game);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_INV_INV_H

View File

@@ -0,0 +1,608 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_inv_scr.h"
#include "watchmaker/types.h"
#include "watchmaker/define.h"
#include "watchmaker/message.h"
#include "watchmaker/globvar.h"
#include "watchmaker/schedule.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/classes/do_string.h"
#include "watchmaker/classes/do_inv.h"
#include "watchmaker/ll/ll_mesh.h"
#include "watchmaker/ll/ll_anim.h"
#include "watchmaker/ll/ll_diary.h"
namespace Watchmaker {
/* -----------------19/05/98 16.40-------------------
* doInvScrUseWith
* --------------------------------------------------*/
void doInvScrUseWith(WGame &game) {
uint8 sent = FALSE;
int32 sa = 0;
Init &init = game.init;
//messo fuori perche' andava in conflitto con l'usacon dell'icona
if ((UseWith[USED] == i29FOTOPROGETTO) && (UseWith[WITH] == ocCUSTODE)) {
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR005, 0, 0, nullptr, nullptr, nullptr);
return;
}
//messo fuori perche' se non parte l'RTV deve dire la frase
if ((UseWith[USED] == i1cMEDAGLIONI2) && (UseWith[WITH] == o1CBOCCA)) {
if (init.Dialog[dR1A5].flags & DIALOG_DONE) {
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR1C3, 0, 0, nullptr, nullptr, nullptr);
return;
} else {
PlayerSpeak(game, init.InvObj[i1cMEDAGLIONI2].text[1]);
return;
}
}
//messo fuori perche' nel caso non si verificasse il gioco deve procedere normalmente con frase/azione dell'icona
if ((UseWith[WITH] == o17CAVETTO) && ((UseWith[USED] == i00TELEFONO) || (UseWith[USED] == i00TELEFONOVIC))) {
// se non ho sentito il numero...
if (!(init.InvObj[i28WALKMANOK].flags & EXTRA2)) {
PlayerSpeak(game, init.Obj[o17COMPUTER].action[CurPlayer]);
return;
}
}
//caso delle chiavi del cuoco che aprono due porte: evito che si usino due volte sulla stessa porta
if ((UseWith[USED] == i25MAZZODUECHIAVI) && ((UseWith[WITH] == o2Hp2G) || (UseWith[WITH] == o2Gp2H) || (UseWith[WITH] == oXT16p17) || (UseWith[WITH] == o17p16))) {
// se ho gia' aperto la porta gli faccio dire una frase
if ((init.Obj[o2Hp2G].flags & EXTRA) || (init.Obj[oXT16p17].flags & ON)) {
PlayerSpeak(game, init.Obj[oADDTEXTOBJ].text[0]);
return;
}
}
switch (UseWith[USED]) {
case i41OGGETTO:
if (UseWith[WITH] == ocCUSTODE)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR002, 0, 0, nullptr, nullptr, nullptr);
else
sent = TRUE;
break;
case i14OCCHIALI:
if (UseWith[WITH] == ocCUSTODE)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR003, 0, 0, nullptr, nullptr, nullptr);
else
sent = TRUE;
break;
case i1cMEDAGLIONE:
if (UseWith[WITH] == o1CBOCCA)
PlayerSpeak(game, init.InvObj[i1cMEDAGLIONE].text[1]);
else
sent = TRUE;
break;
case i34FIALAA:
if (init.Obj[o25FORNOAP].flags & EXTRA2) {
if (UseWith[WITH] == o25FORNOAP)
sa = a257;
else if (UseWith[WITH] == o25CONGELATORE2AP)
sa = a2524;
} else
sent = TRUE;
break;
case i34FIALAB:
if (init.Obj[o25FORNOAP].flags & EXTRA2) {
if (UseWith[WITH] == o25FORNOAP)
sa = a258;
else if (UseWith[WITH] == o25CONGELATORE2AP)
sa = a2525;
} else
sent = TRUE;
break;
case i25MEDAGLIONI4:
if (UseWith[WITH] == o1CBOCCA) {
sa = a1C2;
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_WAIT_ANIM, dR1C1, 0, 0, nullptr, nullptr, nullptr);
} else
sent = TRUE;
break;
case i1cMEDAGLIONI3:
if (UseWith[WITH] == o1CBOCCA) {
sa = a1C2;
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_WAIT_ANIM, dR1C2, 0, 0, nullptr, nullptr, nullptr);
} else
sent = TRUE;
break;
case i24COLTELLO:
if ((UseWith[WITH] == o2GFILTRODXCH) || (UseWith[WITH] == o2GFILTROSXCH)) {
switch (UseWith[WITH]) {
case o2GFILTRODXCH:
if (init.Obj[o2GOFF].flags & ON) {
sa = a2G2;
init.Obj[o2GOFF].anim[DARRELL] = init.Obj[o2GOFF].anim[VICTORIA] = aNULL;
init.Obj[o2GOFF].flags |= EXTRA;
} else PlayerSpeak(game, init.InvObj[UseWith[USED]].text[1]);
break;
case o2GFILTROSXCH:
if (init.Obj[o2GOFF].flags & ON) {
sa = a2G3;
init.Obj[o2GOFF].anim[DARRELL] = init.Obj[o2GOFF].anim[VICTORIA] = aNULL;
init.Obj[o2GOFF].flags |= EXTRA;
} else PlayerSpeak(game, init.InvObj[UseWith[USED]].text[1]);
break;
}//switch
} else
sent = TRUE;
break;
case i25MAZZODUECHIAVI:
if (UseWith[WITH] == o2Hp2G)
sa = a2H6;
else if (UseWith[WITH] == oXT16PORTA)
sa = a162;
else
sent = TRUE;
break;
case i2iDETERSIVO:
if (UseWith[WITH] == o2GFILTRODXAP) {
sa = a2G4;
init.InvObj[UseWith[USED]].flags &= ~USEWITH;
init.InvObj[UseWith[USED]].flags |= USE;
init.InvObj[i2iDETERSIVO].flags |= EXTRA;
} else if (UseWith[WITH] == o2GFILTROSXAP) {
sa = a2G5;
init.InvObj[UseWith[USED]].flags &= ~USEWITH;
init.InvObj[UseWith[USED]].flags |= USE;
init.InvObj[i2iDETERSIVO].flags |= EXTRA;
}
break;
case i2lBOTTIGLIAVINO:
if (UseWith[WITH] == ocCUOCO) {
if (!(init.InvObj[i2lBOTTIGLIAVINO].flags & EXTRA)) {
PlayerSpeak(game, init.InvObj[i2lBOTTIGLIAVINO_NOCUOCO].text[0]);
break;
}
if (!(init.InvObj[i2lBOTTIGLIAVINO].flags & EXTRA2) &&
(((CurPlayer == DARRELL) && (PlayerStand[VICTORIA].roomName.equalsIgnoreCase("r25-a.t3d"))) ||
((CurPlayer == VICTORIA) && (PlayerStand[DARRELL].roomName.equalsIgnoreCase("r25-a.t3d"))))) {
init.Dialog[dR009].flags &= ~(DIALOG_RTV | DIALOG_RTV2 | DIALOG_RTV3);
if (init.Dialog[dR009].flags & DIALOG_DONE)
init.Dialog[dR009].flags |= DIALOG_RTV2;
else
init.Dialog[dR009].flags |= DIALOG_RTV3;
init.InvObj[i2lBOTTIGLIAVINO].flags |= EXTRA2;
}
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR009, 0, 0, nullptr, nullptr, nullptr);
}
break;
case i34LASTRE:
if (UseWith[WITH] == ocSUPERVISORE)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR007, 0, 0, nullptr, nullptr, nullptr);
else
sent = TRUE;
break;
case i22BRACCIALE:
if (UseWith[WITH] == ocSERVETTA) {
if (CurPlayer == VICTORIA) {
// PlayerSpeak( init.InvObj[i22BRACCIALE].text[1] );
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR001, 0, 0, nullptr, nullptr, nullptr);
} else {
PlayerSpeak(game, init.InvObj[i22BRACCIALE].text[0]);
}
}
break;
case i29FOTOJUDE1:
if ((UseWith[WITH] == ocSUPERVISORE) && (init.InvObj[i2aSANGUE].flags & EXTRA)) {
if (CurPlayer == DARRELL)
PlayerSpeak(game, init.InvObj[i29FOTOJUDE1].text[0]);
if (CurPlayer == VICTORIA)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR291, 0, 0, nullptr, nullptr, nullptr);
} else sent = TRUE;
break;
case i29STAMPAINGRANAGGIO:
if (UseWith[WITH] == ocCUSTODE)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR006, 0, 0, nullptr, nullptr, nullptr);
else
sent = TRUE;
break;
case i31ANELLOBRONZO:
if (UseWith[WITH] == ocCUSTODE)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR004, 0, 0, nullptr, nullptr, nullptr);
else
sent = TRUE;
break;
case i1aLUCCHETTO:
if (UseWith[WITH] == oXT1AFINESTRA) {
// morte Cacciatore
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR1A5, 0, 0, nullptr, nullptr, nullptr);
} else
sent = TRUE;
break;
case i48CHIAVIMANETTE:
if (UseWith[WITH] == o48MANETTE)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR483, 0, 0, nullptr, nullptr, nullptr);
else
sent = TRUE;
break;
case i2aSIRINGAVUOTA:
if (UseWith[WITH] == o2AACIDO)
sa = a2A14;
else if (UseWith[WITH] == o2MACIDO)
sa = a2M9;
else
sent = TRUE;
break;
case i19CRISTALLO:
if (UseWith[WITH] == o31ALLOGGIAMENTO)
sa = a3114;
else if (UseWith[WITH] == o39RETTANGOLO)
sa = a396;
else
sent = TRUE;
break;
case i39CRISTALLOATTIVATO:
if (UseWith[WITH] == o31ALLOGGIAMENTO)
sa = a3116;
else if (UseWith[WITH] == o39RETTANGOLO)
sa = a3913;
else
sent = TRUE;
break;
case i2dSESTERZO:
if ((UseWith[WITH] == o36PIATTODX) && !(init.Obj[o36INCENSODX].flags & ON)) {
if (init.Obj[o36INCENSOSX].flags & ON)
sa = a36MSDA;
else
sa = a36MSDM;
} else if ((UseWith[WITH] == o36PIATTOSX) && !(init.Obj[o36INCENSOSX].flags & ON)) {
if (init.Obj[o36INCENSODX].flags & ON)
sa = a36MSSA;
else
sa = a36MSSM;
} else if (!(init.Obj[o3BCOPPA].flags & EXTRA)) {
if (UseWith[WITH] == o3BCOPPABRACCIALI)
sa = a3B2;
else if (UseWith[WITH] == o3BCOPPA)
sa = a3B3;
} else
sent = TRUE;
break;
case i36BUSTA1DOSEA:
case i36BUSTA1DOSEB:
if ((UseWith[WITH] == o36PIATTODX) && (init.Obj[o36INCENSODX].flags & ON)) {
if (init.Obj[o36SESTERZOSX].flags & ON)
sa = a36PBDM;
else
sa = a36PBDB;
if (UseWith[USED] == i36BUSTA1DOSEA)
ReplaceIcon(init, i36BUSTA1DOSEA, i36BUSTA2DOSIA);
else
ReplaceIcon(init, i36BUSTA1DOSEB, i36BUSTA2DOSIB);
} else if ((UseWith[WITH] == o36PIATTOSX) && (init.Obj[o36INCENSOSX].flags & ON)) {
if (init.Obj[o36SESTERZODX].flags & ON)
sa = a36PBSM;
else
sa = a36PBSB;
if (UseWith[USED] == i36BUSTA1DOSEA)
ReplaceIcon(init, i36BUSTA1DOSEA, i36BUSTA2DOSIA);
else
ReplaceIcon(init, i36BUSTA1DOSEB, i36BUSTA2DOSIB);
} else if (!(init.Obj[o3BCOPPA].flags & EXTRA)) {
if ((UseWith[WITH] == o3BCOPPABRACCIALI) && !(init.Obj[o3B2DOSIBRACCIALI].flags & ON)) {
if (UseWith[USED] == i36BUSTA1DOSEA) ReplaceIcon(init, i36BUSTA1DOSEA, i2rBUSTAVUOTAA);
else ReplaceIcon(init, i36BUSTA1DOSEB, i2rBUSTAVUOTAB);
if (init.Obj[o3B1DOSEBRACCIALI].flags & ON) {
init.Obj[o3B1DOSEBRACCIALI].flags &= ~ON;
init.Obj[o3B2DOSIBRACCIALI].flags |= ON;
init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPABRACCIALI].text[4];
} else {
init.Obj[o3B1DOSEBRACCIALI].flags |= ON;
init.Obj[o3B2DOSIBRACCIALI].flags &= ~ON;
init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPABRACCIALI].text[3];
}
UpdateObjMesh(init, o3B1DOSEBRACCIALI);
UpdateObjMesh(init, o3B2DOSIBRACCIALI);
sa = a3B4;
} else if ((UseWith[WITH] == o3BCOPPA) && !(init.Obj[o3B2DOSI].flags & ON)) {
if (UseWith[USED] == i36BUSTA1DOSEA) ReplaceIcon(init, i36BUSTA1DOSEA, i2rBUSTAVUOTAA);
else ReplaceIcon(init, i36BUSTA1DOSEB, i2rBUSTAVUOTAB);
if (init.Obj[o3B1DOSE].flags & ON) {
init.Obj[o3B1DOSE].flags &= ~ON;
init.Obj[o3B2DOSI].flags |= ON;
init.Obj[o3BCOPPA].examine[CurPlayer] = init.Obj[o3BCOPPA].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPA].text[4];
} else {
init.Obj[o3B1DOSE].flags |= ON;
init.Obj[o3B2DOSI].flags &= ~ON;
init.Obj[o3BCOPPA].examine[CurPlayer] = init.Obj[o3BCOPPA].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPA].text[3];
}
UpdateObjMesh(init, o3B1DOSE);
UpdateObjMesh(init, o3B2DOSI);
sa = a3B5;
} else
sent = TRUE;
} else
sent = TRUE;
break;
case i36BUSTA2DOSIA:
case i36BUSTA2DOSIB:
if (!(init.Obj[o3BCOPPA].flags & EXTRA)) {
if ((UseWith[WITH] == o3BCOPPABRACCIALI) && !(init.Obj[o3B1DOSEBRACCIALI].flags & ON) && !(init.Obj[o3B2DOSIBRACCIALI].flags & ON)) {
if (UseWith[USED] == i36BUSTA2DOSIA) ReplaceIcon(init, i36BUSTA2DOSIA, i2rBUSTAVUOTAA);
else ReplaceIcon(init, i36BUSTA2DOSIB, i2rBUSTAVUOTAB);
init.Obj[o3B2DOSIBRACCIALI].flags |= ON;
UpdateObjMesh(init, o3B2DOSIBRACCIALI);
sa = a3B6;
} else if ((UseWith[WITH] == o3BCOPPA) && !(init.Obj[o3B1DOSE].flags & ON) && !(init.Obj[o3B2DOSI].flags & ON)) {
if (UseWith[USED] == i36BUSTA2DOSIA) ReplaceIcon(init, i36BUSTA2DOSIA, i2rBUSTAVUOTAA);
else ReplaceIcon(init, i36BUSTA2DOSIB, i2rBUSTAVUOTAB);
init.Obj[o3B2DOSI].flags |= ON;
UpdateObjMesh(init, o3B2DOSI);
sa = a3B7;
} else
sent = TRUE;
} else
sent = TRUE;
break;
case i2bSACCHETTOINCENSO:
if (UseWith[WITH] == o36PIATTODX) {
if (init.Obj[o36SESTERZOSX].flags & ON) { // se a sx sesterzo
if (!(init.Obj[o36INCENSODX].flags & ON)) // ma a dx non incenso
sa = a36MIDA; // lo mette
else // altrimenti
sa = a36PIDM; // lo prende
} else if (init.Obj[o36INCENSODX].flags & ON) // se a dx incenso
sa = a36PIDB; // lo prende
} else if (UseWith[WITH] == o36PIATTOSX) {
if (init.Obj[o36SESTERZODX].flags & ON) { // se a dx sesterzo
if (!(init.Obj[o36INCENSOSX].flags & ON)) // ma a sx non incenso
sa = a36MISA; // lo mette
else // altrimenti
sa = a36PISM; // lo prende
} else if (init.Obj[o36INCENSOSX].flags & ON) // se a sx incenso
sa = a36PISB; // lo prende
} else if (!(init.Obj[o3BCOPPA].flags & EXTRA)) {
if ((UseWith[WITH] == o3BCOPPABRACCIALI) && (init.Obj[o3B2DOSIBRACCIALI].flags & ON))
sa = a3B15;
else if ((UseWith[WITH] == o3BCOPPABRACCIALI) && (init.Obj[o3B1DOSEBRACCIALI].flags & ON))
sa = a3B13;
else if ((UseWith[WITH] == o3BCOPPA) && (init.Obj[o3B2DOSI].flags & ON))
sa = a3B16;
else if ((UseWith[WITH] == o3BCOPPA) && (init.Obj[o3B1DOSE].flags & ON))
sa = a3B14;
else
sent = TRUE;
if (sa) { //se ha fatto l'azione di raccoglie controllo il testo delle coppe
if (UseWith[WITH] == o3BCOPPABRACCIALI) {
if (init.Obj[o3BSESTERZOBRACCIALI].flags & ON)
init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPABRACCIALI].text[2];
else
init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPABRACCIALI].text[0];
init.Obj[o3BCOPPABRACCIALI].action[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].action[CurPlayer ^ 1] = 0;
} else if (UseWith[WITH] == o3BCOPPA) {
if (init.Obj[o3BSESTERZO].flags & ON)
init.Obj[o3BCOPPA].examine[CurPlayer] = init.Obj[o3BCOPPA].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPA].text[2];
else
init.Obj[o3BCOPPA].examine[CurPlayer] = init.Obj[o3BCOPPA].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPA].text[0];
init.Obj[o3BCOPPA].action[CurPlayer] = init.Obj[o3BCOPPA].action[CurPlayer ^ 1] = 0;
}
}//if sa
}
else
sent = TRUE;
break;
case i2rBUSTAVUOTAA:
if ((UseWith[WITH] == o36PIATTODX) && (init.Obj[o36INCENSODX].flags & ON)) {
if (init.Obj[o36SESTERZOSX].flags & ON)
sa = a36PBDM;
else
sa = a36PBDB;
ReplaceIcon(init, i2rBUSTAVUOTAA, i36BUSTA1DOSEA);
} else if ((UseWith[WITH] == o36PIATTOSX) && (init.Obj[o36INCENSOSX].flags & ON)) {
if (init.Obj[o36SESTERZODX].flags & ON)
sa = a36PBSM;
else
sa = a36PBSB;
ReplaceIcon(init, i2rBUSTAVUOTAA, i36BUSTA1DOSEA);
} else if (!(init.Obj[o3BCOPPA].flags & EXTRA)) {
if ((UseWith[WITH] == o3BCOPPABRACCIALI) && (init.Obj[o3B2DOSIBRACCIALI].flags & ON)) {
sa = a3B11;
ReplaceIcon(init, (uint8)UseWith[USED], i36BUSTA2DOSIA);
} else if ((UseWith[WITH] == o3BCOPPABRACCIALI) && (init.Obj[o3B1DOSEBRACCIALI].flags & ON)) {
sa = a3B9;
ReplaceIcon(init, (uint8)UseWith[USED], i36BUSTA1DOSEA);
} else if ((UseWith[WITH] == o3BCOPPA) && (init.Obj[o3B2DOSI].flags & ON)) {
sa = a3B12;
ReplaceIcon(init, (uint8)UseWith[USED], i36BUSTA2DOSIA);
} else if ((UseWith[WITH] == o3BCOPPA) && (init.Obj[o3B1DOSE].flags & ON)) {
sa = a3B10;
ReplaceIcon(init, (uint8)UseWith[USED], i36BUSTA1DOSEA);
} else
sent = TRUE;
if (sa) { //se ha fatto l'azione di raccoglie controllo il testo delle coppe
if (UseWith[WITH] == o3BCOPPABRACCIALI) {
if (init.Obj[o3BSESTERZOBRACCIALI].flags & ON)
init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPABRACCIALI].text[2];
else
init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPABRACCIALI].text[0];
init.Obj[o3BCOPPABRACCIALI].action[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].action[CurPlayer ^ 1] = 0;
} else if (UseWith[WITH] == o3BCOPPA) {
if (init.Obj[o3BSESTERZO].flags & ON)
init.Obj[o3BCOPPA].examine[CurPlayer] = init.Obj[o3BCOPPA].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPA].text[2];
else
init.Obj[o3BCOPPA].examine[CurPlayer] = init.Obj[o3BCOPPA].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPA].text[0];
init.Obj[o3BCOPPA].action[CurPlayer] = init.Obj[o3BCOPPA].action[CurPlayer ^ 1] = 0;
}
}//if sa
} else
sent = TRUE;
break;
case i2rBUSTAVUOTAB:
if ((UseWith[WITH] == o36PIATTODX) && (init.Obj[o36INCENSODX].flags & ON)) {
if (init.Obj[o36SESTERZOSX].flags & ON)
sa = a36PBDM;
else
sa = a36PBDB;
ReplaceIcon(init, i2rBUSTAVUOTAB, i36BUSTA1DOSEB);
} else if ((UseWith[WITH] == o36PIATTOSX) && (init.Obj[o36INCENSOSX].flags & ON)) {
if (init.Obj[o36SESTERZODX].flags & ON)
sa = a36PBSM;
else
sa = a36PBSB;
ReplaceIcon(init, i2rBUSTAVUOTAB, i36BUSTA1DOSEB);
} else if (!(init.Obj[o3BCOPPA].flags & EXTRA)) {
if ((UseWith[WITH] == o3BCOPPABRACCIALI) && (init.Obj[o3B2DOSIBRACCIALI].flags & ON)) {
sa = a3B11;
ReplaceIcon(init, (uint8)UseWith[USED], i36BUSTA2DOSIB);
} else if ((UseWith[WITH] == o3BCOPPABRACCIALI) && (init.Obj[o3B1DOSEBRACCIALI].flags & ON)) {
sa = a3B9;
ReplaceIcon(init, (uint8)UseWith[USED], i36BUSTA1DOSEB);
} else if ((UseWith[WITH] == o3BCOPPA) && (init.Obj[o3B2DOSI].flags & ON)) {
sa = a3B12;
ReplaceIcon(init, (uint8)UseWith[USED], i36BUSTA2DOSIB);
} else if ((UseWith[WITH] == o3BCOPPA) && (init.Obj[o3B1DOSE].flags & ON)) {
sa = a3B10;
ReplaceIcon(init, (uint8)UseWith[USED], i36BUSTA1DOSEB);
} else
sent = TRUE;
if (sa) { //se ha fatto l'azione di raccoglie controllo il testo delle coppe
if (UseWith[WITH] == o3BCOPPABRACCIALI) {
if (init.Obj[o3BSESTERZOBRACCIALI].flags & ON)
init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPABRACCIALI].text[2];
else
init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPABRACCIALI].text[0];
init.Obj[o3BCOPPABRACCIALI].action[CurPlayer] = init.Obj[o3BCOPPABRACCIALI].action[CurPlayer ^ 1] = 0;
} else if (UseWith[WITH] == o3BCOPPA) {
if (init.Obj[o3BSESTERZO].flags & ON)
init.Obj[o3BCOPPA].examine[CurPlayer] = init.Obj[o3BCOPPA].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPA].text[2];
else
init.Obj[o3BCOPPA].examine[CurPlayer] = init.Obj[o3BCOPPA].examine[CurPlayer ^ 1] = init.Obj[o3BCOPPA].text[0];
init.Obj[o3BCOPPA].action[CurPlayer] = init.Obj[o3BCOPPA].action[CurPlayer ^ 1] = 0;
}
}//if sa
} else
sent = TRUE;
break;
case i46STELLA1:
if (UseWith[WITH] == o45ALLOGGIAMENTO) {
sa = a454;
if (!(init.Obj[o45ALLOGGIAMENTO].flags & EXTRA2)) {
IncCurTime(game, 10);
init.Obj[o45ALLOGGIAMENTO].flags |= EXTRA2;
}
} else if (UseWith[WITH] == o46CERABRACERE)
sa = a4619;
else if ((UseWith[WITH] == o49INCAVODX) && !(init.Obj[o49STELLADXCIA].flags & ON)) {
if (init.Obj[o49STELLASXCIA].flags & ON)
sa = a493b;
else
sa = a493a;
} else if ((UseWith[WITH] == o49INCAVOSX) && !(init.Obj[o49STELLASXCIA].flags & ON)) {
if (init.Obj[o49STELLADXCIA].flags & ON)
sa = a494b;
else
sa = a494a;
} else
sent = TRUE;
break;
case i46STELLA2:
if ((UseWith[WITH] == o49INCAVODX) && !(init.Obj[o49STELLADX].flags & ON)) {
if (init.Obj[o49STELLASX].flags & ON)
sa = a493cb;
else
sa = a493ca;
} else if ((UseWith[WITH] == o49INCAVOSX) && !(init.Obj[o49STELLASX].flags & ON)) {
if (init.Obj[o49STELLADX].flags & ON)
sa = a494cb;
else
sa = a494ca;
} else
sent = TRUE;
break;
default:
if (init.InvObj[UseWith[USED]].uwobj && (init.InvObj[UseWith[USED]].uwobj == UseWith[WITH]) && init.InvObj[UseWith[USED]].anim2[CurPlayer])
sa = init.InvObj[UseWith[USED]].anim2[CurPlayer];
else
sent = TRUE;
break;
}
if (sent)
if (!((bUseWith & UW_WITHI) && (UseWith[USED] == UseWith[WITH])))
PlayerSpeak(game, init.InvObj[UseWith[USED]].action[CurPlayer]);
if (sa)
StartAnim(game, sa);
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,33 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_INV_SCR_H
#define WATCHMAKER_DO_INV_SCR_H
#include "watchmaker/game.h"
namespace Watchmaker {
void doInvScrUseWith(WGame &game);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_INV_SCR_H

View File

@@ -0,0 +1,715 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_keyboard.h"
#include "common/keyboard.h"
#include "watchmaker/3d/animation.h"
#include "watchmaker/3d/geometry.h"
#include "watchmaker/3d/math/llmath.h"
#include "watchmaker/3d/t3d_mesh.h"
#include "watchmaker/classes/do_camera.h"
#include "watchmaker/classes/do_dialog.h"
#include "watchmaker/classes/do_player.h"
#include "watchmaker/define.h"
#include "watchmaker/game.h"
#include "watchmaker/globvar.h"
#include "watchmaker/ll/ll_anim.h"
#include "watchmaker/ll/ll_diary.h"
#include "watchmaker/ll/ll_mesh.h"
#include "watchmaker/ll/ll_mouse.h"
#include "watchmaker/ll/ll_util.h"
#include "watchmaker/main.h"
#include "watchmaker/schedule.h"
#include "watchmaker/t2d/t2d.h"
#include "watchmaker/utils.h"
#include "watchmaker/walk/act.h"
#include "watchmaker/walk/walk.h"
#include "watchmaker/walk/walkutil.h"
namespace Watchmaker {
t3dF32 AngleX, AngleY, AngleSpeed;
char bFastAnim = 0;
int32 PlayAnim = 351;
char bBilinear = 1;
char bForceDebug = 0;
unsigned char KeyTable[Common::KEYCODE_LAST];
uint16 bnd_lev;
extern int16 NextDlg; //from doDialog.c
extern uint8 tasti_per_sfx1; //from main.c
void t3dLoadOutdoorLights(const char *pname, t3dBODY *b, int32 ora);
void ProcessKBInput() {
// TODO: Currently we're polling this in the PollEvent flow.
return;
#if 0
int numKeys = 0;
SDL_PumpEvents();
auto keyState = SDL_GetKeyboardState(&numKeys);
for (int i = 0; i < numKeys; i++) {
KeyTable[i] = keyState[i];
}
for (int i = 0; i < numKeys; i++) {
if (keyState[i])
KeyTable[i] = 0x80;
else if ((KeyTable[i] != 0) && (!keyState[i]))
KeyTable[i] = 0x10;
else
KeyTable[i] = 0x00;
}
#endif
}
bool KeyDown(Common::KeyCode key) {
if (KeyTable[key] & 0x80)
return TRUE;
else
return FALSE;
}
bool KeyUp(Common::KeyCode key) {
if (KeyTable[key] & 0x10) {
KeyTable[key] = 0;
return TRUE;
} else
return FALSE;
}
void KeyClear(Common::KeyCode key) {
KeyTable[key] = 0;
}
bool DInputExclusiveMouse() {
#if 0
HWND hwnd = GetForegroundWindow();
g_pMouse->lpVtbl->Unacquire(g_pMouse);
if (FAILED(g_pMouse->lpVtbl->SetCooperativeLevel(g_pMouse, hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND)))
return FALSE;
g_pMouse->lpVtbl->Acquire(g_pMouse);
#endif
LoaderFlags &= ~T3D_NONEXCLUSIVEMOUSE;
return TRUE;
}
bool DInputNonExclusiveMouse() {
#if 0
HWND hwnd = GetForegroundWindow();
g_pMouse->lpVtbl->Unacquire(g_pMouse);
if (FAILED(g_pMouse->lpVtbl->SetCooperativeLevel(g_pMouse, hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)))
return FALSE;
g_pMouse->lpVtbl->Acquire(g_pMouse);
#endif
LoaderFlags |= T3D_NONEXCLUSIVEMOUSE;
return TRUE;
}
/* -----------------25/08/98 10.42-------------------
* HandleFirstPerson
* --------------------------------------------------*/
void HandleFirstPersonView(WGame &game) {
t3dF32 dist;
t3dV3F d, n;
if ((!Player) || (!t3dCurCamera) || (bLockCamera)) return;
if (KeyDown(Common::KEYCODE_a)) { // Alza testa
if ((dist = CurFloorY + MAX_HEIGHT - (t3dCurCamera->Source.y + 10 * SCALEFACTOR)) > 0) {
if (dist > 10 * SCALEFACTOR) dist = 10 * SCALEFACTOR;
t3dVectInit(&d, 0.0f, dist, 0.0f);
t3dMoveAndCheck1stCamera(t3dCurRoom, t3dCurCamera, &d);
}
} else if (KeyDown(Common::KEYCODE_z)) { // Abbassa Testa
if ((dist = CurFloorY + KNEE_HEIGHT - (t3dCurCamera->Source.y - 10 * SCALEFACTOR)) < 0) {
if (dist < -10 * SCALEFACTOR) dist = -10 * SCALEFACTOR;
t3dVectInit(&d, 0.0f, dist, 0.0f);
t3dMoveAndCheck1stCamera(t3dCurRoom, t3dCurCamera, &d);
}
}
// Se tengo premuto lo shift o un tasto del mouse
if (KeyDown(Common::KEYCODE_LSHIFT) || KeyDown(Common::KEYCODE_RSHIFT) || ((bLPressed || bRPressed) && (mMove > 10))) {
t3dVectSub(&d, &t3dCurCamera->Target, &t3dCurCamera->Source);
d.y = 0.0f;
t3dVectNormalize(&d);
n.x = -d.z;
n.y = 0.0f;
n.z = d.x;
dist = (t3dF32)((t3dF32)mMoveY / (t3dF32)(MainDy / 2)) * 100.0f;
if (KeyDown(Common::KEYCODE_UP))
d *= (5 * SCALEFACTOR);
else if (KeyDown(Common::KEYCODE_DOWN))
d *= (-5 * SCALEFACTOR);
else if (((bLPressed) || (bRPressed)) && (mMoveY) && !bClock33)
d *= (-dist * SCALEFACTOR);
else
t3dVectFill(&d, 0.0f);
dist = (t3dF32)((t3dF32)mMoveX / (t3dF32)(MainDx / 2)) * 100.0f;
if (KeyDown(Common::KEYCODE_LEFT))
n *= (5 * SCALEFACTOR);
else if (KeyDown(Common::KEYCODE_RIGHT))
n *= (-5 * SCALEFACTOR);
else if (((bLPressed) || (bRPressed)) && (mMoveX) && !bClock33)
n *= (-dist * SCALEFACTOR);
else
t3dVectFill(&n, 0.0f);
t3dVectAdd(&d, &d, &n);
t3dMoveAndCheck1stCamera(t3dCurRoom, t3dCurCamera, &d);
} else {
int32 x, y;
x = 0;
y = 0;
if (KeyDown(Common::KEYCODE_UP))
y = -10;
else if (KeyDown(Common::KEYCODE_DOWN))
y = MainDy + 10;
if (KeyDown(Common::KEYCODE_LEFT))
x = -10;
else if (KeyDown(Common::KEYCODE_RIGHT))
x = MainDx + 10;
if (x || y) {
t3dF32 diffx, diffy;
diffx = 0.f;
diffy = 0.f;
if (x > MainDx) diffx = (t3dF32)((t3dF32)(x - MainDx) / 3.0f);
else if (x < 0) diffx = (t3dF32)((t3dF32)x / 3.0f);
if (y > MainDy) diffy = (t3dF32)((t3dF32)(y - MainDy) / 3.0f);
else if (y < 0) diffy = (t3dF32)((t3dF32)y / 3.0f);
game._cameraMan->MoveHeadAngles(diffx, diffy);
}
}
// Corregge Camera
t3dVectCopy(&d, &Player->Mesh->Trasl);
d.y = t3dCurCamera->Source.y;
dist = KNEE_HEIGHT - t3dVectDistance(&t3dCurCamera->Source, &d);
if (dist < 0.0f) {
t3dVectSub(&d, &t3dCurCamera->Source, &d);
d.y = 0.0f;
t3dVectNormalize(&d);
d *= dist;
t3dVectAdd(&t3dCurCamera->Source, &t3dCurCamera->Source, &d);
t3dVectAdd(&t3dCurCamera->Target, &t3dCurCamera->Target, &d);
}
}
/* -----------------23/04/98 17.24-------------------
* ProcessKeyboard
* --------------------------------------------------*/
void ProcessKeyboard(WGame &game) {
//warning("STUBBED: ProcessKeyboard");
t3dF32 TurnSpeed, Speed = 1.0f, dist;
t3dV3F cp, cd, ct;
int32 a, b;
AngleX = AngleY = AngleSpeed = 0.0f;
TurnSpeed = 3.5f * FrameFactor;
doT2DKeyboard(game);
ProcessKBInput();
if (bIngnoreDIKeyboard)
return ;
if (KeyUp(Common::KEYCODE_ESCAPE)) {
if (LoaderFlags & T3D_DEBUGMODE) {
CloseSys(game); // Quitta il gioco
} else {
// Skip Intro
if ((CurDialog == dR000) || (CurDialog == dR111) || (CurDialog == dR211)) {
NextDlg = dNULL;
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGEND_SKIPINTRO, MP_DEFAULT, (int16)CurDialog, mQUIT, 0, NULL, NULL, NULL);
}
// Skip Loghi
if (CurDialog == dRLOGHI)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGEND, MP_DEFAULT, (int16)CurDialog, mQUIT, 0, NULL, NULL, NULL);
// Skip MorteWM
if (CurDialog == dR391)
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGEND, MP_DEFAULT, (int16)CurDialog, mQUIT, 0, NULL, NULL, NULL);
// Skip durante i crediti, quitta
if (bTitoliCodaScrolling || bTitoliCodaStatic)
game.CleanUpAndPostQuit();
}
}// Common::KEYCODE_ESCAPE
//se ci sono i crediti ritorna (controlla solo l'ESC)
if (bTitoliCodaStatic || bTitoliCodaScrolling) return;
if (KeyDown(Common::KEYCODE_LSHIFT) && KeyUp(Common::KEYCODE_d))
bForceDebug ^= 1;
/* if( KeyDown(SDL_SCANCODE_LSHIFT) ) // Bomba il gioco
if( KeyUp(SDL_SCANCODE_F) )
{
t3dFree(t3dCurRoom->CameraTable);
t3dFree(t3dCurRoom->CameraTable);
}
*/
if (KeyUp(Common::KEYCODE_i)) // Escono Informazioni
bShowInfo ^= 1;
if (KeyUp(Common::KEYCODE_g)) {
error("TODO: Screenshot support");
#if 0
FILE *fh;
char str[32];
int i;
for (i = 1; i < 1000; i++) {
sprintf(str, "Wm%#04d.tga", i);
if ((fh = fopen(str, "rb")) == NULL)
break;
else
fclose(fh);
}
rGrabVideo(str, 0);
#endif
}
if (KeyUp(Common::KEYCODE_END)) {
if (!bFirstPerson)
StartAnim(game, aGIRO);
}
if ((LoaderFlags & T3D_DEBUGMODE) || bForceDebug) {
if (KeyUp(Common::KEYCODE_F5))
DataSave("Prova Save", 0);
if (KeyUp(Common::KEYCODE_F6))
DataLoad(game, "", 0);
if (KeyUp(Common::KEYCODE_w)) { // Modalita' wireframe
bForceWire ^= 1;
if (bForceWire)
rSetRenderMode(rWIREFRAMEMODE);
else
rSetRenderMode(rSOLIDMODE);
}
if (KeyUp(Common::KEYCODE_b)) // Escono BoundingBox
bShowBoundingBox ^= 1;
if (KeyUp(Common::KEYCODE_BACKSPACE)) // Fa andare le animazioni piu' veloci
bFastAnim ^= 1;
if (KeyUp(Common::KEYCODE_s))
bSkipTalk = TRUE;
if (KeyUp(Common::KEYCODE_h))
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dPROVA, 0, 0, NULL, NULL, NULL);
if (KeyUp(Common::KEYCODE_e))
StartAnim(game, aFOX);
if (KeyUp(Common::KEYCODE_j)) {
if (Player && Player->Mesh) {
ct = Player->Dir * HALF_STEP * 5.0f;
t3dVectAdd(&Player->Mesh->Trasl, &Player->Mesh->Trasl, &ct);
t3dVectCopy(&Player->Pos, &Player->Mesh->Trasl);
}
}
if (KeyUp(Common::KEYCODE_p)) {
if (KeyDown(Common::KEYCODE_LSHIFT) || KeyDown(Common::KEYCODE_RSHIFT)) {
if (++bnd_lev > 5) bnd_lev = 0;
SetBndLevel(game, NULL, bnd_lev);
DebugLogWindow("BndLev %d", bnd_lev);
} else
bShowPanels ^= 1; // Escono Pannelli
}
if (!tasti_per_sfx1) {
if (KeyUp(Common::KEYCODE_m)) {
if (KeyDown(Common::KEYCODE_LSHIFT))
DInputNonExclusiveMouse();
else if (KeyDown(Common::KEYCODE_RSHIFT))
DInputExclusiveMouse();
}
if (KeyUp(Common::KEYCODE_o))
bShowExtraLocalizationStrings ^= 1;
} else {
if (KeyUp(Common::KEYCODE_k)) {
PlayAnim --;
if (KeyDown(Common::KEYCODE_LCTRL) || KeyDown(Common::KEYCODE_RCTRL))
PlayAnim -= 19;
if (KeyDown(Common::KEYCODE_LSHIFT) || KeyDown(Common::KEYCODE_RSHIFT))
PlayAnim -= 30;
warning("PlayAnim %d '%s'\n", PlayAnim, game.init.Anim[PlayAnim].name[0].rawArray()); // TODO DebugString
}
if (KeyUp(Common::KEYCODE_l)) {
PlayAnim ++;
if (KeyDown(Common::KEYCODE_LCTRL) || KeyDown(Common::KEYCODE_RCTRL))
PlayAnim += 19;
if (KeyDown(Common::KEYCODE_LSHIFT) || KeyDown(Common::KEYCODE_RSHIFT))
PlayAnim += 30;
warning("PlayAnim %d '%s'\n", PlayAnim, game.init.Anim[PlayAnim].name[0].rawArray()); // TODO DebugString
}
if (KeyUp(Common::KEYCODE_m))
StartAnim(game, PlayAnim);
}
if (KeyDown(Common::KEYCODE_LSHIFT)) {
if (KeyUp(Common::KEYCODE_F1)) t3dLoadOutdoorLights("c:\\wm\\LMaps\\rxt.t3d", t3dRxt, 1030);
if (KeyUp(Common::KEYCODE_F2)) t3dLoadOutdoorLights("c:\\wm\\LMaps\\rxt.t3d", t3dRxt, 1530);
if (KeyUp(Common::KEYCODE_F3)) t3dLoadOutdoorLights("c:\\wm\\LMaps\\rxt.t3d", t3dRxt, 1930);
if (KeyUp(Common::KEYCODE_F4)) t3dLoadOutdoorLights("c:\\wm\\LMaps\\rxt.t3d", t3dRxt, 2230);
}
if (KeyUp(Common::KEYCODE_F11)) IncCurTime(game, 5);
if (KeyUp(Common::KEYCODE_F12)) IncCurTime(game, 100);
if (KeyUp(Common::KEYCODE_1)) CharSetPosition(ocCURPLAYER, 1, NULL);
if (KeyUp(Common::KEYCODE_2)) CharSetPosition(ocCURPLAYER, 2, NULL);
if (KeyUp(Common::KEYCODE_3)) CharSetPosition(ocCURPLAYER, 3, NULL);
if (KeyUp(Common::KEYCODE_4)) CharSetPosition(ocCURPLAYER, 4, NULL);
if (KeyUp(Common::KEYCODE_5)) CharSetPosition(ocCURPLAYER, 5, NULL);
if (KeyUp(Common::KEYCODE_6)) CharSetPosition(ocCURPLAYER, 6, NULL);
if (KeyUp(Common::KEYCODE_7)) CharSetPosition(ocCURPLAYER, 7, NULL);
if (KeyUp(Common::KEYCODE_8)) CharSetPosition(ocCURPLAYER, 8, NULL);
if (KeyUp(Common::KEYCODE_9)) CharSetPosition(ocCURPLAYER, 9, NULL);
if (KeyUp(Common::KEYCODE_KP0)) CharSetPosition(ocCURPLAYER, 10, NULL);
if (KeyUp(Common::KEYCODE_KP1)) CharSetPosition(ocCURPLAYER, 11, NULL);
if (KeyUp(Common::KEYCODE_KP2)) CharSetPosition(ocCURPLAYER, 12, NULL);
if (KeyUp(Common::KEYCODE_KP3)) CharSetPosition(ocCURPLAYER, 13, NULL);
if (KeyUp(Common::KEYCODE_KP4)) CharSetPosition(ocCURPLAYER, 14, NULL);
if (KeyUp(Common::KEYCODE_KP5)) CharSetPosition(ocCURPLAYER, 15, NULL);
if (KeyUp(Common::KEYCODE_KP6)) CharSetPosition(ocCURPLAYER, 16, NULL);
if (KeyUp(Common::KEYCODE_KP7)) CharSetPosition(ocCURPLAYER, 17, NULL);
if (KeyUp(Common::KEYCODE_KP8)) CharSetPosition(ocCURPLAYER, 18, NULL);
if (KeyUp(Common::KEYCODE_KP9)) CharSetPosition(ocCURPLAYER, 19, NULL);
if (KeyDown(Common::KEYCODE_LSHIFT))
if (KeyUp(Common::KEYCODE_x)) {
tasti_per_sfx1 ^= 1;
}
/*
if( KeyUp(SDL_SCANCODE_D) )
Event( EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, 0, 0, tDIARIO, NULL, NULL, NULL );
if( KeyUp(SDL_SCANCODE_K) )
{
PlayAnim --;
if( KeyDown(SDL_SCANCODE_LCONTROL) || KeyDown(SDL_SCANCODE_RCONTROL) )
PlayAnim -= 19;
if( KeyDown(SDL_SCANCODE_LSHIFT) || KeyDown(SDL_SCANCODE_RSHIFT) )
PlayAnim -= 30;
DebugString("PlayAnim %d '%s'",PlayAnim,Anim[PlayAnim].name[0]);
}
if( KeyUp(SDL_SCANCODE_L) )
{
PlayAnim ++;
if( KeyDown(SDL_SCANCODE_LCONTROL) || KeyDown(SDL_SCANCODE_RCONTROL) )
PlayAnim += 19;
if( KeyDown(SDL_SCANCODE_LSHIFT) || KeyDown(SDL_SCANCODE_RSHIFT) )
PlayAnim += 30;
DebugString("PlayAnim %d '%s'",PlayAnim,Anim[PlayAnim].name[0]);
}
if( KeyUp(SDL_SCANCODE_M) )
StartAnim( PlayAnim );
if ( KeyUp(SDL_SCANCODE_X) )
rSetBilinearFilterState( bBilinear ^= 1 );
if( KeyUp(SDL_SCANCODE_T) ) // Scrive su file nome mesh
DebugFile("%s",ObjectUnderCursor);
if( KeyUp(SDL_SCANCODE_BACK) ) // Attiva modalita' frame-by-frame per le animazioni
bPauseAllAnims ^= 1;
if( KeyUp(SDL_SCANCODE_RETURN) ) // Avanza di un frame tutte le animazioni
ContinueAnim( -1 );
if( KeyUp(SDL_SCANCODE_S) )
Event( EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR1a1, 0, 0, NULL, NULL, NULL );
if( KeyUp(SDL_SCANCODE_N) )
Event( EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, 0, 0, tPDA, NULL, NULL, NULL );
if( KeyUp(SDL_SCANCODE_F) )
Event( EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, 0, 0, tCOMPUTER, NULL, NULL, NULL );
if( ( KeyDown(SDL_SCANCODE_LSHIFT) || KeyDown(SDL_SCANCODE_RSHIFT) ) && ( KeyDown(SDL_SCANCODE_F5) || KeyDown(SDL_SCANCODE_F6) ) )
Event( EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, 0, 0, tOPTIONS, NULL, NULL, NULL );
if( KeyUp(SDL_SCANCODE_C) )
{
int i,len;
char Name[200];
if ( t3dCurRoom->CameraGrid.Grid)
t3dFree(t3dCurRoom->CameraGrid.Grid);
t3dCurRoom->CameraGrid.Grid=NULL;
for ( i=0; i<t3dCurRoom->NumPaths; i++)
{
if ( t3dCurRoom->CameraPath[i].PList)
{
t3dFree(t3dCurRoom->CameraPath[i].PList);
t3dCurRoom->CameraPath[i].PList=NULL;
}
}
t3dFree(t3dCurRoom->CameraPath);
t3dCurRoom->CameraPath=NULL;
for ( i=0; i<t3dCurRoom->NumCameras; i++)
{
if ( t3dCurRoom->CameraTable[i].CameraPaths)
{
t3dFree(t3dCurRoom->CameraTable[i].CameraPaths);
t3dCurRoom->CameraTable[i].CameraPaths=NULL;
}
}
t3dFree(t3dCurRoom->CameraTable);
t3dCurRoom->CameraTable=NULL;
strcpy(Name,WmCamDir);
strcat(Name,t3dCurRoom->Name);
len=strlen(Name);
Name[len-3]='c';
Name[len-2]='a';
Name[len-1]='m';
LoadCameras(Name,t3dCurRoom);
t3dCurCamera = &t3dCurRoom->CameraTable[0];
BigInvObj ++;
// DebugLogFile("%d: %s %s",BigInvObj,ObjName[InvObj[BigInvObj].name],InvObj[BigInvObj].meshlink);
}
if( KeyUp(SDL_SCANCODE_R) )
rSetFogMode( RGBA_MAKE( 70, 0, 0, 0), 4000.0f, 8000.0f, 0.1f, D3DFOG_LINEAR );
*/
}// fine tasti di debug
else {
if (KeyUp(Common::KEYCODE_d))
bShowRoomDescriptions ^= 1;
if (KeyUp(Common::KEYCODE_e))
bShowExtraLocalizationStrings ^= 1;
if (KeyUp(Common::KEYCODE_p))
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, 0, 0, tPDA, NULL, NULL, NULL);
}
if (KeyUp(Common::KEYCODE_F8) && PlayerCanSwitch(game._gameVars, 1) && !(InvStatus & INV_ON))
// && ( (InvStatus & (INV_ON|INV_MODE2)) != (INV_ON|INV_MODE2) ) )
{
KeyClear(Common::KEYCODE_F8);
if (CurPlayer == DARRELL) a = ocVICTORIA;
else a = ocDARRELL;
if (a == (ocDARRELL + CurPlayer)) return ;
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_DEFAULT, FRAME_PER_SECOND / 3, 0, EFFECT_FADOUT, NULL, NULL, NULL);
if (bMovingCamera)
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_CHANGEPLAYER, MP_WAITA | MP_WAIT_CAMERA, (int16)a, 0, 0, NULL, NULL, NULL);
else
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_CHANGEPLAYER, MP_WAITA, (int16)a, 0, 0, NULL, NULL, NULL);
}
if ((bPlayerInAnim) || (bNotSkippableWalk) || (bDialogActive)) {
KeyClear(Common::KEYCODE_F1);
KeyClear(Common::KEYCODE_F2);
KeyClear(Common::KEYCODE_F3);
KeyClear(Common::KEYCODE_TAB);
KeyClear(Common::KEYCODE_SPACE);
KeyClear(Common::KEYCODE_LCTRL);
KeyClear(Common::KEYCODE_RCTRL);
KeyClear(Common::KEYCODE_END);
return;
}
if (KeyUp(Common::KEYCODE_F1) && !(InvStatus & INV_ON) && (bT2DActive == tNULL) && PlayerCanSave()) {
rGrabVideo("temp.tmp", 1);
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, MPX_START_T2D_SAVE, 0, tOPTIONS, NULL, NULL, NULL);
}
if (KeyUp(Common::KEYCODE_F2) && !(InvStatus & INV_ON) && (bT2DActive == tNULL)) {
rGrabVideo("temp.tmp", 1);
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, MPX_START_T2D_LOAD, 0, tOPTIONS, NULL, NULL, NULL);
}
if (KeyUp(Common::KEYCODE_F3) && !(InvStatus & INV_ON) && (bT2DActive == tNULL)) {
rGrabVideo("temp.tmp", 1);
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, MPX_START_T2D_OPTIONS, 0, tOPTIONS, NULL, NULL, NULL);
}
// Se Premo Control e sono vicino ad una porta o ad una scala
if ((Player) && ((KeyUp(Common::KEYCODE_LCTRL)) || (KeyUp(Common::KEYCODE_RCTRL)))) {
KeyClear(Common::KEYCODE_LCTRL);
KeyClear(Common::KEYCODE_RCTRL);
if (bSomeOneSpeak) bSkipTalk = TRUE;
game._cameraMan->GetRealCharPos(game.init, &ct, ocCURPLAYER, 0);
ct.y = CurFloorY;
for (a = 0; a < MAX_OBJS_IN_ROOM; a++) {
b = game.getCurRoom().objects[a];
if (((game.init.Obj[b].flags & DOOR) || (bPorteEsternoBloccate && (game.init.Obj[b].flags & DONE))) && (game.init.Obj[b].flags & ON) && !(game.init.Obj[b].flags & HIDE) && (game.init.Obj[b].pos) && (GetLightPosition(&cp, game.init.Obj[b].pos))) {
GetLightDirection(&cd, game.init.Obj[b].pos);
dist = t3dVectDistance(&ct, &cp);
// Se sono abbastanza vicino a luce posizione
if (dist < (CHEST_HEIGHT)) {
t3dVectSub(&cd, &cd, &cp);
dist = t3dVectAngle(&cd, &Player->Dir);
if ((dist < 60.0f) && (dist > -60.0f)) {
CurObj = b;
_vm->_messageSystem.doEvent(EventClass::MC_MOUSE, ME_MRIGHT, MP_DEFAULT, 0, 0, 0, &CurObj, NULL, NULL);
}
}
}
}
}
if (KeyUp(Common::KEYCODE_SPACE) && (!IsPlayerInPool())) { // Cambia tra 3a e 1a persona
if (bSomeOneSpeak) bSkipTalk = TRUE;
if ((bFirstPerson == 0) && (!bMovingCamera) && (!bNoFirstPersonSwitch)/* && !( InvStatus & INV_ON )*/)
_vm->_messageSystem.doEvent(EventClass::MC_CAMERA, ME_CAMERA3TO1, MP_DEFAULT, 0, 0, 0, NULL, NULL, NULL);
else if ((!bMovingCamera) && (!bNoFirstPersonSwitch)/* && !( InvStatus & INV_ON )*/)
_vm->_messageSystem.doEvent(EventClass::MC_CAMERA, ME_CAMERA1TO3, MP_DEFAULT, 0, 0, 0, NULL, NULL, NULL);
}
if (KeyUp(Common::KEYCODE_TAB) && !bLockCamera) // Fa uscire l'inventario
_vm->_messageSystem.doEvent(EventClass::MC_INVENTORY, ME_INVSWITCH, MP_DEFAULT, 0, 0, 0, NULL, NULL, NULL);
if (KeyDown(Common::KEYCODE_LEFT) && !(InvStatus & INV_ON) && !(bFirstPerson)) { // Ruota a Destra
AngleY = (-1) * TurnSpeed / 180.0f * T3D_PI;
if ((Player->Walk.CurAction <= aSTAND) || (Player->Walk.CurAction == aROT_DX)) {
PlayerGotoPos[CurPlayer + ocDARRELL] = 0;
PlayerPos[CurPlayer + ocDARRELL] = 0;
Player->Walk.CurAction = aROT_SX;
Player->Walk.CurFrame = ActionStart[Player->Walk.CurAction];
Player->Mesh->CurFrame = Player->Walk.CurFrame;
} else if (Player->Walk.CurAction == aROT_SX) {
PlayerGotoPos[CurPlayer + ocDARRELL] = 0;
PlayerPos[CurPlayer + ocDARRELL] = 0;
Player->Walk.CurFrame ++;
if (Player->Walk.CurFrame >= ActionStart[Player->Walk.CurAction + 1] - 1)
Player->Walk.CurFrame = ActionStart[Player->Walk.CurAction];
Player->Mesh->CurFrame = Player->Walk.CurFrame;
}
} else if (KeyDown(Common::KEYCODE_RIGHT) && !(InvStatus & INV_ON) && !(bFirstPerson)) { // Ruota a Sinistra
AngleY = TurnSpeed / 180.0f * T3D_PI;
if ((Player->Walk.CurAction <= aSTAND) || (Player->Walk.CurAction == aROT_SX)) {
PlayerGotoPos[CurPlayer + ocDARRELL] = 0;
PlayerPos[CurPlayer + ocDARRELL] = 0;
Player->Walk.CurAction = aROT_DX;
Player->Walk.CurFrame = ActionStart[Player->Walk.CurAction];
Player->Mesh->CurFrame = Player->Walk.CurFrame;
} else if (Player->Walk.CurAction == aROT_DX) {
PlayerGotoPos[CurPlayer + ocDARRELL] = 0;
PlayerPos[CurPlayer + ocDARRELL] = 0;
Player->Walk.CurFrame ++;
if (Player->Walk.CurFrame >= ActionStart[Player->Walk.CurAction + 1] - 1)
Player->Walk.CurFrame = ActionStart[Player->Walk.CurAction];
Player->Mesh->CurFrame = Player->Walk.CurFrame;
}
}
if (KeyDown(Common::KEYCODE_UP) && !(InvStatus & INV_ON) && !(bFirstPerson)) {
AngleSpeed = 20.0f;
} else if (KeyDown(Common::KEYCODE_DOWN) && !(InvStatus & INV_ON) && !(bFirstPerson)) {
AngleSpeed = -20.0f;
}
if (KeyDown(Common::KEYCODE_LSHIFT) || KeyDown(Common::KEYCODE_RSHIFT)) // || (GetKeyState(Common::KEYCODE_CAPSLOCK) & 0x1)) TODO: Allow for Caps-lock for fast walk
bFastWalk = TRUE;
else
bFastWalk = FALSE;
if (!t3dCurCamera) return;
if ((bFirstPerson) && !(bMovingCamera))
HandleFirstPersonView(game);
if (bFirstPerson) {
_vm->_messageSystem.doEvent(EventClass::MC_MOUSE, ME_MOUSEUPDATE, MP_DEFAULT, 0, 0, 0, NULL, NULL, NULL);
AngleX = AngleY = AngleSpeed = 0.0f;
if (Player)
Player->Flags |= T3D_CHARACTER_HIDE;
} else if (!(InvStatus & INV_ON) && (Player)) {
UpdateChar(game, ocCURPLAYER, AngleSpeed * Speed, AngleY);
AngleX = AngleY = AngleSpeed = 0.0f;
}
}
/* -----------------28/09/98 17.18-------------------
* doClock32
* --------------------------------------------------*/
void doClock33(WGame &game, int32 obj, t3dV3F *mp) {
t3dMESH *l;
t3dV3F tmp, pos;
int32 i, r;
if (!bClock33) {
bClock33 = (uint8)(obj - o33LANCETTAHSX + 1);
if (game._gameVars.getCurRoomId() == r33)
CharSetPosition(ocCURPLAYER, game.init.Obj[o33OROLOGIO].pos, nullptr);
}
obj = (int32)bClock33 + o33LANCETTAHSX - 1;
// Trova il puntatore alla mesh
if (!(l = LinkMeshToStr(game.init, game.init.Obj[obj].getMeshLink(0)))) return;
// Trova il punto centrale attorno a cui ruotare
pos.x = l->Pos.x;
pos.y = 350.0f;
pos.z = l->Pos.z;
// Trova direzione della lancetta in base al mouse
t3dVectSub(&tmp, mp, &pos);
tmp.z = 0.0f;
r = (int32)(SinCosAngle(-tmp.x, tmp.y) * 180.0f / T3D_PI) / 30;
Comb33[bClock33 - 1] = (int32)r;
// Azzera Bounding box (tornano in posizione centrale)
for (i = 0; i < 8; i++) {
t3dVectSub(&tmp, &l->BBox[i].p, &pos);
t3dVectTransformInv(&l->BBox[i].p, &tmp, &Lanc33[obj - o33LANCETTAHSX]->Mesh->Matrix);
}
t3dMatRot(&Lanc33[obj - o33LANCETTAHSX]->Mesh->Matrix, 0.0f, 0.0f, T3D_PI * (t3dF32)r / 6.0f);
for (i = 0; i < 8; i++) {
t3dVectTransform(&tmp, &l->BBox[i].p, &Lanc33[obj - o33LANCETTAHSX]->Mesh->Matrix);
t3dVectAdd(&l->BBox[i].p, &tmp, &pos);
}
t3dPlaneNormal(&l->BBoxNormal[0], &l->BBox[0].p, &l->BBox[2].p, &l->BBox[1].p); //front
t3dPlaneNormal(&l->BBoxNormal[1], &l->BBox[4].p, &l->BBox[5].p, &l->BBox[6].p); //back
t3dPlaneNormal(&l->BBoxNormal[2], &l->BBox[4].p, &l->BBox[0].p, &l->BBox[5].p); //Up
t3dPlaneNormal(&l->BBoxNormal[3], &l->BBox[6].p, &l->BBox[7].p, &l->BBox[2].p); //Down
t3dPlaneNormal(&l->BBoxNormal[4], &l->BBox[4].p, &l->BBox[6].p, &l->BBox[0].p); //Left
t3dPlaneNormal(&l->BBoxNormal[5], &l->BBox[5].p, &l->BBox[1].p, &l->BBox[7].p); //Right
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,36 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_KEYBOARD_H
#define WATCHMAKER_DO_KEYBOARD_H
#include "watchmaker/globvar.h"
namespace Watchmaker {
void doClock33(WGame &game, int obj, struct t3dV3F *mp);
void ProcessKeyboard(WGame &game);
void ProcessKBInput();
extern unsigned char KeyTable[];
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_KEYBOARD_H

View File

@@ -0,0 +1,341 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_mouse.h"
#include "watchmaker/t3d.h"
#include "watchmaker/globvar.h"
#include "watchmaker/message.h"
#include "watchmaker/ll/ll_mouse.h"
#include "watchmaker/define.h"
#include "watchmaker/3d/math/llmath.h"
#include "watchmaker/3d/geometry.h"
#include "watchmaker/classes/do_camera.h"
#include "watchmaker/schedule.h"
#include "watchmaker/classes/do_player.h"
#include "watchmaker/main.h"
#include "watchmaker/ll/ll_util.h"
#include "watchmaker/classes/do_dialog.h"
#include "watchmaker/classes/do_inv.h"
#include "watchmaker/walk/act.h"
#include "watchmaker/3d/animation.h"
#include "watchmaker/classes/do_string.h"
#include "watchmaker/classes/do_keyboard.h"
#include "watchmaker/ll/ll_diary.h"
#include "watchmaker/ll/ll_string.h"
#include "watchmaker/t2d/t2d.h"
#include "watchmaker/walk/walk.h"
#include "watchmaker/renderer.h"
namespace Watchmaker {
// locals
t3dV3F LastClickPos;
uint8 LastFloorHit;
void doMouseButton(WGame &game) {
uint8 cp;
Init &init = game.init;
Renderer &renderer = *game._renderer;
if (bT2DActive) {
doT2DMouse(game);
return ;
}
if (bSomeOneSpeak && !bNotSkippableSent) {
/*DebugLogWindow("skip");*/bSkipTalk = true;
return;
}
if (bDialogActive) {
UpdateDialogMenu(game, TheMessage->wparam1, TheMessage->wparam2, TheMessage->event);
return;
}
if ((bPlayerInAnim) || (bNotSkippableWalk) || (bMovingCamera)) return;
if (mHide) mHide = false;
if ((bClock33) || (CurObj == o33LANCETTAMSX) || (CurObj == o33LANCETTAHSX) || (CurObj == o33LANCETTAMDX) || (CurObj == o33LANCETTAHDX)) return;
CurInvObj = 0;
CurObj = 0;
// se sono su inventario
if (InvStatus & INV_ON) {
if ((InvStatus & INV_ON) && (InvStatus & INV_MODE1) && PlayerCanCall(game._gameVars)) {
if (CheckRect(renderer, game._gameRect._callOtherPlayerRect, TheMessage->wparam1, TheMessage->wparam2)) {
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dRCALLOTHERPLAYER, 0, 0, nullptr, nullptr, nullptr);
return;
}
}
CurInvObj = WhatIcon(*game._renderer, TheMessage->wparam1, TheMessage->wparam2);
if ((CurInvObj == iNULL) && (InvStatus & INV_MODE2) && CheckRect(renderer, game._gameRect._bigIconRect, TheMessage->wparam1, TheMessage->wparam2))
CurInvObj = BigInvObj;
if (CurInvObj == iNULL) {
// se ho cliccato su icona grande
if (InvStatus & INV_MODE2) {
if (CheckRect(renderer, game._gameRect._inv1Up, TheMessage->wparam1, TheMessage->wparam2))
InventoryUp();
else if (CheckRect(renderer, game._gameRect._inv1Down, TheMessage->wparam1, TheMessage->wparam2))
InventoryDown();
else if (CheckRect(renderer, game._gameRect._closeInvRect, TheMessage->wparam1, TheMessage->wparam2)) {
if (InvStatus & INV_MODE4) {
CurPlayer ^= 1;
ChangePlayer(game, (uint8)((CurPlayer ^ 1) + ocDARRELL));
}
InvStatus = INV_OFF;
game._cameraMan->resetAngle();
game._cameraMan->GetCameraTarget(init, &t3dCurCamera->Target);
if (bFirstPerson)
game._renderer->setCurCameraViewport(CAMERA_FOV_1ST, bSuperView);
else
game._renderer->setCurCameraViewport(t3dCurCamera->Fov, bSuperView);
BigInvObj = iNULL;
} else if (CheckRect(renderer, game._gameRect._quitGameRect, TheMessage->wparam1, TheMessage->wparam2))
CloseSys(game);
else if (CheckRect(renderer, game._gameRect._invSaveRect, TheMessage->wparam1, TheMessage->wparam2) && !(InvStatus & INV_MODE4) && PlayerCanSave())
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, MPX_START_T2D_SAVE, 0, tOPTIONS, nullptr, nullptr, nullptr);
else if (CheckRect(renderer, game._gameRect._invLoadRect, TheMessage->wparam1, TheMessage->wparam2) && !(InvStatus & INV_MODE4))
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, MPX_START_T2D_LOAD, 0, tOPTIONS, nullptr, nullptr, nullptr);
else if (CheckRect(renderer, game._gameRect._invOptionsRect, TheMessage->wparam1, TheMessage->wparam2) && !(InvStatus & INV_MODE4))
_vm->_messageSystem.doEvent(EventClass::MC_T2D, ME_T2DSTART, MP_DEFAULT, MPX_START_T2D_OPTIONS, 0, tOPTIONS, nullptr, nullptr, nullptr);
else {
ClearUseWith();
if ((CheckRect(renderer, game._gameRect._playerInvRect, TheMessage->wparam1, TheMessage->wparam2)) || (InvStatus & INV_MODE4)) {
if (PlayerCanSwitch(game._gameVars, 0)) {
InvStatus ^= INV_MODE4;
CurPlayer ^= VICTORIA;
BigInvObj = iNULL;
return;
}
}
}
} else if (CheckRect(renderer, game._gameRect._inv1Up, TheMessage->wparam1, TheMessage->wparam2))
InventoryUp();
else if (CheckRect(renderer, game._gameRect._inv1Down, TheMessage->wparam1, TheMessage->wparam2))
InventoryDown();
else {
InvStatus = INV_OFF;
ClearUseWith();
}
return;
}
if ((BigInvObj != CurInvObj) && !(bUseWith & UW_ON)) {
t3dMatIdentity(&game.init._globals._invVars.BigIconM);
BigInvObj = CurInvObj;
}
if (TheMessage->event == ME_MRIGHT)
_vm->_messageSystem.doEvent(EventClass::MC_INVENTORY, ME_OPERATEICON, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, 0, &CurInvObj, nullptr, nullptr);
else if (bUseWith & UW_ON)
_vm->_messageSystem.doEvent(EventClass::MC_INVENTORY, ME_OPERATEICON, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, 0, &CurInvObj, nullptr, nullptr);
else
_vm->_messageSystem.doEvent(EventClass::MC_INVENTORY, ME_EXAMINEICON, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, 0, &CurInvObj, nullptr, nullptr);
//if( ( InvStatus & INV_MODE2 ) && CheckRect(BigIconRect,TheMessage->wparam1,TheMessage->wparam2) )
//CurInvObj = iNULL;
return;
} else if ((bUseWith & UW_ON) && (bUseWith & UW_USEDI) && CheckRect(renderer, game._gameRect._useIconRect, TheMessage->wparam1, TheMessage->wparam2)) {
ClearUseWith();
ClearText();
return;
}
// se sono su area gioco
cp = 0;
PlayerGotoPos[CurPlayer + ocDARRELL] = 0;
NextPortalObj = oNULL;
NextPortalAnim = aNULL;
// se gli ho gia' passato che oggetto deve trovare
if ((CurObj = TheMessage->lparam[0])) {
// se era per un passaggio di portale, cancella l'oggetto
if (CurObj == oNEXTPORTAL) CurObj = oNULL;
// Ripristina informazioni
bFastWalk = (uint8)TheMessage->lparam[2];
FloorHit = LastFloorHit;
t3dVectCopy(&mPos, &LastClickPos);
} else {
// Cerca l'oggetto su cui ho cliccato
CurObj = WhatObj(game, TheMessage->wparam1, TheMessage->wparam2, TheMessage->event);
// Se sono su albero e clicco fuori dal nido, simulo un cambio portale
if (bPlayerSuBasamento &&
(CurObj != oXT14ALBERO) && (CurObj != oXT14BASAMENTO) && (CurObj != oXT14NIDO_da_sopra_il_basamento) && (CurObj != oXT14OCCHIALI)) {
NextPortalObj = CurObj;
NextPortalAnim = a145;
}
// se non e' stato cliccato nessun oggetto e un oggetto era gia' selezionato dall'inventario il tasto
// destro del mouse elimina questa selezione (nd Fox)
if ((CurObj == oNULL) && (bUseWith) && (TheMessage->event == ME_MRIGHT)) {
ClearUseWith();
return;
}
// Salva informazioni
LastFloorHit = FloorHit;
t3dVectCopy(&LastClickPos, &mPos);
}
if (bFirstPerson && FromFirstPersonAnim && (!CurObj || (CurObj && (!(init.Obj[CurObj].flags & NOSWITCH))))) {
if (CurObj)
NextPortalObj = CurObj;
else
NextPortalObj = oNEXTPORTAL;
NextPortalAnim = FromFirstPersonAnim;
FromFirstPersonAnim = aNULL;
}
// Se ha cliccato in un altro portale e c'e' un'animazione di link
if ((NextPortalObj) && (NextPortalAnim)) {
// Prende luce di posizione dall'animazione
cp = init.Anim[NextPortalAnim].pos;
PlayerGotoPos[CurPlayer + ocDARRELL] = GetLightPosition(&mPos, cp);
// Simula un click per terra
CurObj = oNULL;
FloorHit = 1;
} else if ((CurObj) && !(NextPortalObj) && (init.Obj[CurObj].pos != 0)) {
// altrimenti prova a prendere la luce di posizione
cp = init.Obj[CurObj].pos;
PlayerGotoPos[CurPlayer + ocDARRELL] = GetLightPosition(&mPos, cp);
FloorHit = 1;
}
// Se deve prendere sempre un click col destro
if (init.Obj[CurObj].flags & FORCERIGHT) TheMessage->event = ME_MRIGHT;
// Cammina solo; nessuno oggetto o nessuna posizione o posizione diversa e non sono in closeup
if ((!CurObj) || ((PlayerGotoPos[CurPlayer + ocDARRELL]) && (PlayerGotoPos[CurPlayer + ocDARRELL] != PlayerPos[CurPlayer + ocDARRELL])) || (!PlayerGotoPos[CurPlayer + ocDARRELL])) {
CheckCharacterWithBounds(game, ocCURPLAYER, &mPos, cp, 10);
// Se ho cliccato in un altro portale dice di contiunare la camminata
if ((NextPortalObj) && (NextPortalAnim))
_vm->_messageSystem.doEvent(EventClass::MC_MOUSE, TheMessage->event, MP_WAIT_ANIM, 0, 0, 0, &NextPortalObj, nullptr, &bFastWalk);
else if (NextPortalObj)
_vm->_messageSystem.doEvent(EventClass::MC_MOUSE, TheMessage->event, MP_WAIT_PORTAL, 0, 0, 0, &NextPortalObj, nullptr, &bFastWalk);
// Se sono in prima torno in terza, a meno che l'oggetto non mi obblighi a restare in prima
if (bFirstPerson && !bNoFirstPersonSwitch && (!CurObj || (CurObj && (!(init.Obj[CurObj].flags & NOSWITCH) || (Player->Walk.Check & LONGPATH)))))
_vm->_messageSystem.doEvent(EventClass::MC_CAMERA, ME_CAMERA1TO3, MP_DEFAULT, 0, 0, 0, nullptr, nullptr, nullptr);
//? else if( bFirstPerson )
//? CharStop( ocCURPLAYER );
}
// Rimuove tutti gli eventi del personaggio
game._messageSystem.removeEvent(EventClass::MC_PLAYER, ME_ALL);
if (CurObj) { // se ho cliccato su un oggetto valido
if (TheMessage->event == ME_MLEFT) // se ho cliccato con sinistro
_vm->_messageSystem.doEvent(EventClass::MC_PLAYER, ME_PLAYERGOTOEXAMINE, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, bFirstPerson, &CurObj, nullptr, nullptr);
else if (TheMessage->event == ME_MRIGHT) { // se ho cliccato con destro
if ((init.Obj[CurObj].flags & USEWITH) && !(bUseWith)) { // se ho cliccato su un oggetto usacon
Player->Walk.NumSteps = 0; // Simula un PlayerStop
_vm->_messageSystem.doEvent(EventClass::MC_ACTION, ME_MOUSEOPERATE, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, bFirstPerson, &CurObj, nullptr, nullptr);
} else
_vm->_messageSystem.doEvent(EventClass::MC_PLAYER, ME_PLAYERGOTOACTION, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, bFirstPerson, &CurObj, nullptr, nullptr);
}
} else // se non ho cliccato su niente
_vm->_messageSystem.doEvent(EventClass::MC_PLAYER, ME_PLAYERGOTO, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, bFirstPerson, nullptr, &NextPortalAnim, nullptr);
}
void doMouseUpdate(WGame &game) {
Init &init = game.init;
Renderer &renderer = *game._renderer;
if (bT2DActive) {
doT2DMouse(game);
return ;
}
if (bDialogActive) {
UpdateDialogMenu(game, TheMessage->wparam1, TheMessage->wparam2, TheMessage->event);
return;
}
if (/*( mHide ) ||*/ (bSomeOneSpeak)) return;
if (!TheMessage->wparam1 && !TheMessage->wparam2) return;
if ((bPlayerInAnim) || (bNotSkippableWalk) || (mHide) || (bMovingCamera)) return;
CurObj = 0;
CurInvObj = 0;
//DebugFile("MM %d %d",TheMessage->wparam1, TheMessage->wparam2 );
// se sono su inventario
if (InvStatus & INV_ON) {
if ((bLPressed) && (InvStatus & INV_MODE2)) {
t3dM3X3F t;
t3dMatRot(&t, ((t3dF32)(TheMessage->lparam[1]) / (t3dF32)(game._gameRect._bigIconRect.y2 - game._gameRect._bigIconRect.y1))*T3D_PI * 2.0f,
((t3dF32)(TheMessage->lparam[0]) / (t3dF32)(game._gameRect._bigIconRect.x1 - game._gameRect._bigIconRect.x2))*T3D_PI * 2.0f, 0.0f);
t3dMatMul(&game.init._globals._invVars.BigIconM, &t, &game.init._globals._invVars.BigIconM);
CurInvObj = BigInvObj;
} else {
CurInvObj = WhatIcon(*game._renderer, TheMessage->wparam1, TheMessage->wparam2);
if ((CurInvObj == iNULL) && CheckRect(renderer, game._gameRect._bigIconRect, TheMessage->wparam1, TheMessage->wparam2))
CurInvObj = BigInvObj;
ShowInvObjName(init, CurInvObj);
}
return;
}
// se sono su area gioco
CurObj = WhatObj(game, TheMessage->wparam1, TheMessage->wparam2, TheMessage->event);
if ((bLPressed || bRPressed) && ((bClock33) || (CurObj == o33LANCETTAMSX) || (CurObj == o33LANCETTAHSX) || (CurObj == o33LANCETTAMDX) || (CurObj == o33LANCETTAHDX)))
doClock33(game, CurObj, &mPos);
else {
if (bClock33) {
if ((Comb33[0] == 7) && (Comb33[1] == 2) && (Comb33[2] == 9) && (Comb33[3] == 11) && IconInInv(init, i19FOGLIO1)) {
_vm->_messageSystem.doEvent(EventClass::MC_CAMERA, ME_CAMERA1TO3, MP_DEFAULT, 0, 0, 0, nullptr, nullptr, nullptr);
_vm->_messageSystem.doEvent(EventClass::MC_ANIM, ME_STARTANIM, MP_WAIT_CAMERA, a336, 0, 0, nullptr, nullptr, nullptr);
if (!(init.Obj[o33LANCETTAHSX].flags & EXTRA2)) {
IncCurTime(game, 15);
init.Obj[o33LANCETTAHSX].flags |= EXTRA2;
}
}
bClock33 = false;
}
ShowObjName(init, CurObj);
}
}
/* -----------------17/03/98 17.16-------------------
* doMouse
* --------------------------------------------------*/
void doMouse(WGame &game) {
//se ci sono i crediti ritorna
if (bTitoliCodaStatic || bTitoliCodaScrolling) return;
switch (TheMessage->event) {
case ME_MRIGHT:
case ME_MLEFT:
doMouseButton(game);
break;
case ME_MOUSEUPDATE :
doMouseUpdate(game);
break;
case ME_MOUSEHIDE :
if ((mCounter++ > 20) && !(mHide))
mHide = 1;
ClearText();
break;
case ME_MOUSEUNHIDE :
mHide = 0;
break;
}
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,34 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_MOUSE_H
#define WATCHMAKER_DO_MOUSE_H
#include "watchmaker/globvar.h"
#include "watchmaker/game.h"
namespace Watchmaker {
void doMouse(WGame &game);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_MOUSE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_OPERATE_H
#define WATCHMAKER_DO_OPERATE_H
#include "watchmaker/types.h"
#include "watchmaker/game.h"
namespace Watchmaker {
void UpdateSpecial(WGame &game, int32 room);
void doOperate(WGame &game, int32 obj);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_OPERATE_H

View File

@@ -0,0 +1,516 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_player.h"
#include "watchmaker/t3d.h"
#include "watchmaker/globvar.h"
#include "watchmaker/define.h"
#include "watchmaker/walk/act.h"
#include "watchmaker/utils.h"
#include "watchmaker/3d/t3d_body.h"
#include "watchmaker/3d/t3d_mesh.h"
#include "watchmaker/3d/geometry.h"
#include "watchmaker/3d/math/llmath.h"
#include "watchmaker/3d/animation.h"
#include "watchmaker/message.h"
#include "watchmaker/schedule.h"
#include "watchmaker/ll/ll_anim.h"
#include "watchmaker/ll/ll_util.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/ll/ll_diary.h"
#include "watchmaker/walk/walk.h"
#include "watchmaker/classes/do_sound.h"
#include "watchmaker/classes/do_string.h"
#include "watchmaker/ll/ll_mesh.h"
namespace Watchmaker {
// locals
#define BLEND_INC 65
t3dV3F SerraRect[2] = { { -6939.0f, 0.0f, -8396.0f }, { 6679.0f, 0.0f, -16561.0f } };
t3dV3F KreenRect1[2] = { { -1482.0f, 0.0f, -12162.0f }, { -1207.0f, 0.0f, -12586.0f } };
t3dV3F KreenRect2[2] = { { -1042.0f, 0.0f, -12162.0f }, { -766.0f, 0.0f, -12586.0f } };
t3dF32 KrennX = -600.0f;
t3dF32 KrennZ = -12570.0f;
t3dF32 CacciatoreXleft = -7450.0f;
t3dF32 CacciatoreXright = 8400.0f;
t3dF32 CacciatoreZright = -14701.0f;
t3dF32 r47CoordX = -2125.0f;
/* -----------------08/10/00 11.55-------------------
* SetCurPlayerPosTo_9x()
* --------------------------------------------------*/
void SetCurPlayerPosTo_9x(GameVars &gameVars, Init &init) {
// Setto il player nella posizione 91 o 92 (o successive) se esistono
t3dV3F dest;
uint8 pos, start_pos, found_pos;
pos = 0;
start_pos = 0;
found_pos = 0;
if (CurPlayer == DARRELL) start_pos = 91;
if (CurPlayer == VICTORIA) start_pos = 92;
// caso particolare nella r42, quando i personaggi potrebbero essere al di la' del portone
if ((gameVars.getCurRoomId() == r42) && (init.Dialog[dR421_fine].flags & DIALOG_DONE)) {
if (CurPlayer == DARRELL) start_pos = 93;
}
if ((gameVars.getCurRoomId() == r42) && (init.Dialog[dR42_porta].flags & DIALOG_DONE)) {
if (CurPlayer == VICTORIA) start_pos = 94;
}
// caso particolare: quando con Victoria non posso entrare nel castello ma devo tirare il lucchetto, faccio
// in modo che quando carico lei si posizioni vicino alla finestra e non a cozze
if (bPorteEsternoBloccate && (gameVars.getCurRoomId() == rXT)) {
if (CurPlayer == VICTORIA) start_pos = 96;
}
for (pos = start_pos; pos <= 98; pos += 2) {
if (!GetLightPosition(&dest, pos)) continue;
found_pos = pos;
break;
}//for
if (found_pos) {
CharSetPosition(CurPlayer + ocDARRELL, found_pos, nullptr);
warning("SETTATA POSITION: %d, %d", CurPlayer, start_pos);
} else {
t3dVectCopy(&Player->Pos, &t3dCurCamera->Target);
t3dVectCopy(&Player->Mesh->Trasl, &t3dCurCamera->Target);
warning("SETTATA POSITION SU CAMERATARGET: %d", CurPlayer);
}
}
/* -----------------17/03/98 17.16-------------------
* doMouse
* --------------------------------------------------*/
void doPlayer(WGame &game) {
switch (TheMessage->event) {
case ME_PLAYERIDLE:
// Parte animazione di idle
if ((int32)TheTime > TheMessage->lparam[0]) {
StopObjAnim(game, TheMessage->wparam1);
//DebugString("Idle %d at %d",TheMessage->wparam1,TheMessage->lparam[0]);
} else {
TheMessage->flags |= MP_WAIT_RETRACE;
//DebugString("NO %d",TheMessage->lparam[0]-TheTime);
ReEvent();
}
break;
case ME_PLAYERGOTO:
case ME_PLAYERGOTOEXAMINE:
case ME_PLAYERGOTOACTION:
case ME_PLAYERGOTOEXIT:
case ME_PLAYERGOTONOSKIP:
if (CharNextFrame(game, ocCURPLAYER)) {
TheMessage->flags |= MP_WAIT_RETRACE;
ReEvent();
} else {
// se sono partito dalla prima persona, torna in prima persona
// if ( TheMessage->bparam )
// Event( EventClass::MC_CAMERA, ME_CAMERA3TO1, MP_DEFAULT, 0, 0, 0, NULL, NULL, NULL );
if (Player)
Player->Walk.NumPathNodes = Player->Walk.CurrentStep = Player->Walk.NumSteps = bNotSkippableWalk = 0;
if ((!bDialogActive) || (TimeWalk == CurPlayer + ocDARRELL) || (TimeWalk == ocCURPLAYER))
_vm->_messageSystem.addWaitingMsgs(MP_WAIT_ACT);
if (TheMessage->event == ME_PLAYERGOTOEXAMINE)
_vm->_messageSystem.doEvent(EventClass::MC_ACTION, ME_MOUSEEXAMINE, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, 0, &TheMessage->lparam[0], nullptr, nullptr);
else if (TheMessage->event == ME_PLAYERGOTOACTION)
_vm->_messageSystem.doEvent(EventClass::MC_ACTION, ME_MOUSEOPERATE, MP_DEFAULT, TheMessage->wparam1, TheMessage->wparam2, 0, &TheMessage->lparam[0], nullptr, nullptr);
else if ((TheMessage->event == ME_PLAYERGOTO) && (TheMessage->lparam[1]))
StartAnim(game, TheMessage->lparam[1]);
/*?? if( TheMessage->lparam[0] )
{
if( (bFirstPerson) && (Obj[TheMessage->lparam[0]].flags & HIDEIN1ST) )
Event( EventClass::MC_CAMERA, ME_CAMERA1TO3, MP_DEFAULT, 0, 0, 0, NULL, NULL, NULL );
else if( !(bFirstPerson) && (Obj[TheMessage->lparam[0]].flags & HIDEIN3RD) )
Event( EventClass::MC_CAMERA, ME_CAMERA3TO1, MP_DEFAULT, 0, 0, Obj[TheMessage->lparam[0]].pos, NULL, NULL, NULL );
}*/
}
break;
}
}
/* -----------------02/10/98 10.17-------------------
* ProcessCharacters
* --------------------------------------------------*/
void ProcessCharacters(WGame &game) {
int32 i, na, nf;
uint8 cbi;
t3dMESH *m;
t3dCHARACTER *c;
for (i = 0; i < T3D_MAX_CHARACTERS; i++)
if (Character[i] && (Character[i] != Player) && (Character[i]->Walk.NumSteps))
if (!CharNextFrame(game, i))
if ((bDialogActive) && (TimeWalk == i))
_vm->_messageSystem.addWaitingMsgs(MP_WAIT_ACT);
for (i = 0; i < T3D_MAX_CHARACTERS; i++) {
c = Character[i];
if (c && (i != ocCURPLAYER) && !(c->Flags & T3D_CHARACTER_HIDE)) {
nf = c->Walk.CurFrame;
na = c->Walk.CurAction;
if ((na == aWALK_START) || (na == aWALK_LOOP) || (na == aWALK_END)) {
if ((nf == 81) || (nf == 171)) StartStepSound(game, &c->Pos, SOUND_PSX);
else if ((nf == 36) || (nf == 126) || (nf == 216)) StartStepSound(game, &c->Pos, SOUND_PDX);
} else if ((na == aBACK_START) || (na == aBACK_LOOP) || (na == aBACK_END)) {
if ((nf == 37 + ActionStart[aBACK_START] - 3) || (nf == 162 + ActionStart[aBACK_START] - 3)) StartStepSound(game, &c->Pos, SOUND_PSX);
else if (nf == 101 + ActionStart[aBACK_START] - 3) StartStepSound(game, &c->Pos, SOUND_PDX);
} else if ((na == aRUN_START) || (na == aRUN_LOOP) || (na == aRUN_END)) {
if (nf == 74 + ActionStart[aRUN_START] - 4) StartStepSound(game, &c->Pos, SOUND_PSX);
else if (nf == 45 + ActionStart[aRUN_START] - 4) StartStepSound(game, &c->Pos, SOUND_PDX);
}
}
}
// Segue con la testa il mouse
UpdateCharHead(ocCURPLAYER, &mPos);
// Discesa del garage
if (t3dCurRoom->name.equalsIgnoreCase("rxt.t3d")) {
if ((m = LinkMeshToStr(game.init, "oxt-garage")) && (m->BBox[3].p.x - m->BBox[2].p.x) &&
(Player->Pos.x > m->BBox[2].p.x) && (Player->Pos.x < m->BBox[3].p.x) &&
(Player->Pos.z > m->BBox[2].p.z) && (Player->Pos.z < m->BBox[6].p.z)) {
Player->Pos.y = ((Player->Pos.x - m->BBox[2].p.x) / (m->BBox[3].p.x - m->BBox[2].p.x)) * m->BBox[2].p.y;
t3dVectCopy(&Player->Mesh->Trasl, &Player->Pos);
}
}
// Parte RTV serra
if (!(game.init.Dialog[dR1a1].flags & DIALOG_DONE) && !(bDialogActive) && (game._gameVars.getCurRoomId() == rXT)) {
if ((Player->Mesh->Trasl.x > SerraRect[0].x) && (Player->Mesh->Trasl.x < SerraRect[1].x) &&
(Player->Mesh->Trasl.z > SerraRect[1].z) && (Player->Mesh->Trasl.z < SerraRect[0].z)) {
if (!(LoaderFlags & T3D_DEBUGMODE)) {
t3dF32 dist = SerraRect[1].x - Player->Mesh->Trasl.x;
CharStop(ocCURPLAYER);
// controllo da che parte far partire l'RTV
if ((dist >= 0.0f) && (dist < 30.f))
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dRUN_R1a1_RIGHT, 0, 0, nullptr, nullptr, nullptr);
else
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dRUN_R1a1_CENTER, 0, 0, nullptr, nullptr, nullptr);
}
}
}
// Parte Morte Cacciatore se passa l'esterno
if ((bCacciatore) && !(LoaderFlags & T3D_DEBUGMODE)) {
if (Player->Mesh->Trasl.x < CacciatoreXleft) {
bCacciatore = FALSE;
CharStop(ocCURPLAYER);
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR0014_left, 0, 0, nullptr, nullptr, nullptr);
}
if ((Player->Mesh->Trasl.x > CacciatoreXright) && (Player->Mesh->Trasl.z > CacciatoreZright)) {
bCacciatore = FALSE;
CharStop(ocCURPLAYER);
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR0014_right, 0, 0, nullptr, nullptr, nullptr);
}
}
// Quando Victoria si avvicina per la prima volta alla Room47 parte un RTV che mostra Krenn.
if (
(game._gameVars.getCurRoomId() == r47)
&& (CurPlayer == VICTORIA)
&& (!(game.init.Dialog[dR482].flags & DIALOG_DONE))
&& (!(LoaderFlags & T3D_DEBUGMODE))
&& (!bDialogActive)) {
if (Player->Mesh->Trasl.x > r47CoordX) {
CharStop(ocCURPLAYER);
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR482, 0, 0, nullptr, nullptr, nullptr);
}
}
// Parte Morte Victoria se Krenn la vede
if ((game._gameVars.getCurRoomId() == r48) && (!bDialogActive) && (!(LoaderFlags & T3D_DEBUGMODE))) {
int whichanim;
int beccato;
whichanim = WhichAnimChar(game.init, ocKRENN);
beccato = 0;
if ((whichanim == aKRE481) || (whichanim == aKRE482) || (whichanim == aKRE483) || (whichanim == aKRE484)) {
if (Player->Mesh->Trasl.z < KrennZ) {
//se Krenn e' in movimento basta arrivare sotto la linea verticale delle colonne per beccarti
beccato = 1;
} else if (whichanim != aKRE481) {
if ((Player->Mesh->Trasl.x > KrennX) //oltrepassata l'ultima colonna
|| (
(Player->Mesh->Trasl.x > KreenRect1[0].x) && (Player->Mesh->Trasl.x < KreenRect1[1].x)
&& (Player->Mesh->Trasl.z < KreenRect1[0].z) && (Player->Mesh->Trasl.z > KreenRect1[1].z)
)
|| (
(Player->Mesh->Trasl.x > KreenRect2[0].x) && (Player->Mesh->Trasl.x < KreenRect2[1].x)
&& (Player->Mesh->Trasl.z < KreenRect2[0].z) && (Player->Mesh->Trasl.z > KreenRect2[1].z)
)
)
beccato = 1;
}
}
if (beccato) {
// DebugLogFile("BECCATO");
CharStop(ocCURPLAYER);
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR48KRENNSPARA, 0, 0, nullptr, nullptr, nullptr);
}
}
// Dice la frase dell'eclisse se non l'ha gi<67> detta
if ((game._gameVars.getCurRoomId() == rXT) && (t3dCurTime >= 1300) && (t3dCurTime <= 1310) && (!(game.init.Obj[oADDTEXTOBJ].flags & EXTRA))) {
game.init.Obj[oADDTEXTOBJ].flags |= EXTRA;
PlayerSpeak(game, game.init.Obj[oADDTEXTOBJ].examine[CurPlayer]);
}
// Porta gradualmente il Blending a zero
cbi = (uint8)((t3dF32)BLEND_INC * FrameFactor);
if (bDialogActive) cbi /= 5;
for (i = 0; i < T3D_MAX_CHARACTERS; i++) {
if (Character[i] && (i != ocCURPLAYER) && (Character[i]->Mesh->BlendPercent != 255)) {
if ((Character[i]->Mesh->BlendPercent + cbi) < 255)
Character[i]->Mesh->BlendPercent += cbi;
else
Character[i]->Mesh->BlendPercent = 255;
// Character[i]->Mesh->BlendPercent = 255;
}
}
}
/* -----------------17/08/00 17.31-------------------
* UpdatePlayerStand
* --------------------------------------------------*/
void UpdatePlayerStand(WGame &game, uint8 oc) {
int32 a, b, panims[MAX_ANIMS_IN_ROOM], pc, na;
t3dF32 mindist, dist;
t3dV3F pos;
Init &init = game.init;
auto curRoom = game._gameVars.getCurRoomId();
na = 0;
pc = 0;
mindist = 9999999.0f;
memset(panims, 0, sizeof(panims));
for (a = 0; a < MAX_ANIMS_IN_ROOM; a++) {
b = game.getCurRoom().anims[a];
if ((b == aNULL) || !(init.Anim[b].flags & ANIM_STAND) || (init.Anim[b].obj != (ocDARRELL + CurPlayer)))
continue;
// caso particolare nel rXT, quando i personaggi potrebbero teletrasportarsi in mezzo all'RTV della serra (dove appunto le luci 93 e 94 sono messe)
if ((curRoom == rXT) && (!(init.Dialog[dR1a1].flags & DIALOG_DONE)))
if ((init.Anim[b].pos == 93) || (init.Anim[b].pos == 94)) continue;
if (!(GetLightPosition(&pos, init.Anim[b].pos)))
continue;
if ((dist = t3dVectDistance(&Player->Mesh->Trasl, &pos)) < mindist) {
mindist = dist;
na = b;
}
warning("Found %d, dist %f, good %d", b, dist, na);
panims[pc] = b ;
pc ++;
}
// Ferma il primo personaggio e salva le posizioni
game._messageSystem.removeEvent(EventClass::MC_PLAYER, ME_ALL);
// Salva informazioni
{
// DebugLogFile("NO");
PlayerStand[CurPlayer].pos = init.Anim[na].pos;
PlayerStand[CurPlayer].cr = curRoom;
PlayerStand[CurPlayer].bnd = t3dCurRoom->CurLevel;
if ((curRoom == r15) || (curRoom == r1F)) PlayerStand[CurPlayer].bnd = 0;
PlayerStand[CurPlayer].roomName = t3dCurRoom->name;
if (CurPlayer == DARRELL)
PlayerStand[CurPlayer].an = aIDLE_DARRELL_1;
else
PlayerStand[CurPlayer].an = aIDLE_VICTORIA_1;
}
}
/* -----------------22/10/98 17.29-------------------
* ChangePlayer
* --------------------------------------------------*/
void ChangePlayer(WGame &game, uint8 oc) {
int32 a, b,/*panims[MAX_ANIMS_IN_ROOM],pc,*/na;
// t3dF32 mindist,dist;
t3dV3F pos;
Init &init = game.init;
if ((oc - ocDARRELL) == CurPlayer)
return ;
// caso particolare: sono nella r2a e faccio andare il submusic 1 (ovvero frigo.mid), il problema e' che le altre
// stanze non hanno submusic 1 e quindi se cambio personaggio devo resettare submusic a 0 (cosa che generalmente
// fa l'animazione di uscita dalla porta, che in questo caso non viene pero' chiamata)
if (t3dCurRoom->name.equalsIgnoreCase("r2a.t3d") && CurSubMusic)
CurSubMusic = 0;
bFirstPerson = false;
// Aggiorna la variabile di cambio personaggio
UpdatePlayerStand(game, oc);
// ferma sia darrell sia victoria
StopObjAnim(game, ocDARRELL);
StopObjAnim(game, ocVICTORIA);
// cerca tutte le possibili posizioni di cambio
CharSetPosition(ocCURPLAYER, PlayerStand[CurPlayer].pos, nullptr);
StartAnim(game, PlayerStand[CurPlayer].an);
// DebugLogFile("---");
// Cambia personaggio
bPlayerInAnim = false;
CurPlayer = oc - ocDARRELL;
Character[ocCURPLAYER] = Character[oc];
Player = Character[oc];
Player->Flags &= ~T3D_CHARACTER_HIDE;
// Resetta telecamera
CameraTargetObj = ocCURPLAYER;
CameraTargetBone = 0;
auto curRoom = game._gameVars.getCurRoomId();
// Se il secondo personaggio non esisteva
if (PlayerStand[CurPlayer].cr == rNULL) {
// cerca una animazione adatta nella stessa stanza
for (a = 0; a < MAX_ANIMS_IN_ROOM; a++) {
b = game.getCurRoom().anims[a];
if ((b == aNULL) || !(init.Anim[b].flags & ANIM_STAND) || (init.Anim[b].obj != (ocDARRELL + CurPlayer)))
continue;
if (!(GetLightPosition(&pos, init.Anim[b].pos)))
continue;
na = b;
PlayerStand[CurPlayer].pos = init.Anim[na].pos;
PlayerStand[CurPlayer].cr = curRoom;
PlayerStand[CurPlayer].bnd = t3dCurRoom->CurLevel;
PlayerStand[CurPlayer].roomName = t3dCurRoom->name.c_str();
if (CurPlayer == DARRELL)
PlayerStand[CurPlayer].an = aIDLE_DARRELL_1;
else
PlayerStand[CurPlayer].an = aIDLE_VICTORIA_1;
break;
}
}
// Cambia stanza andandosi a leggere la posizione e l'animazione che aveva prima
warning("Changing Room to |%s| pos: %d an: %d", PlayerStand[CurPlayer].roomName.c_str(), PlayerStand[CurPlayer].pos, PlayerStand[CurPlayer].an);
ChangeRoom(game, PlayerStand[CurPlayer].roomName, PlayerStand[CurPlayer].pos, 0);
if ((curRoom == r15) || (curRoom == r1F))
SetBndLevel(game, nullptr, PlayerStand[CurPlayer].bnd);
CharStop(ocCURPLAYER);
Player->Mesh->Flags |= T3D_MESH_DEFAULTANIM;
if (Player && t3dCurRoom) {
Player->Walk.Panel = t3dCurRoom->Panel[t3dCurRoom->CurLevel];
Player->Walk.PanelNum = t3dCurRoom->NumPanels[t3dCurRoom->CurLevel];
Player->Mesh->Trasl.y = Player->Pos.y = CurFloorY = t3dCurRoom->PanelHeight[t3dCurRoom->CurLevel];
}
// Inizia il Fade
// Event( EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_DEFAULT, FRAME_PER_SECOND/3, 0, EFFECT_FADIN, NULL, NULL, NULL );
_vm->_messageSystem.doEvent(EventClass::MC_CAMERA, ME_CAMERAPLAYER, MP_DEFAULT, 0, 0, 0, nullptr, nullptr, nullptr);
}
/* -----------------30/10/00 18.26-------------------
* IsPlayerInPool()
* --------------------------------------------------*/
int IsPlayerInPool() {
if (!t3dCurRoom) return (0);
if (!Character[ocCURPLAYER]->CurRoom->name.equalsIgnoreCase("r22.t3d")) return (0);
if (!t3dCurRoom->name.equalsIgnoreCase("r22.t3d")) return (0);
if (t3dCurRoom->CurLevel != 1) return (0);
return (1);
}
/* -----------------31/10/00 09.26-------------------
* PlayerCanSwitch()
* --------------------------------------------------*/
int PlayerCanSwitch(GameVars &gameVars, char no_inventory) {
auto curRoom = gameVars.getCurRoomId();
if (bNoPlayerSwitch) return (0);
if (curRoom == r15) return (0);
if (curRoom == r31) return (0);
if (curRoom == r1F) return (0);
if (curRoom == r1D) return (0);
if (curRoom == r42) return (0);
if (IsPlayerInPool()) return (0);
if (bPlayerSuBasamento) return (0);
// significa che la richiesta viene fatta quando l'inventario "grosso" non e' aperto e quindi bisogna controllare
// dei parametri in piu' (parametri che quando l'inventario e' aperto sono sicuramente giusti)
if (no_inventory) {
if (bPlayerInAnim) return (0);
if (bNotSkippableWalk) return (0);
if (bDialogActive) return (0);
}
return (1);
}
/* -----------------31/10/00 09.26-------------------
* PlayerCanCall()
* --------------------------------------------------*/
int PlayerCanCall(GameVars &gameVars) {
auto curRoom = gameVars.getCurRoomId();
if (bNoPlayerSwitch) return (0);
if (curRoom == r15) return (0);
if (curRoom == r31) return (0);
if (curRoom == r1F) return (0);
if (curRoom == r1D) return (0);
if (curRoom == r42) return (0);
if (IsPlayerInPool()) return (0);
if (bPlayerSuBasamento) return (0);
if (bSezioneLabirinto) return (0);
if (curRoom == rXT) return (0);
if (t3dCurRoom->name.equalsIgnoreCase(PlayerStand[CurPlayer ^ 1].roomName)) return (0);
return (1);
}
/* -----------------31/10/00 09.26-------------------
* PlayerCanSave()
* --------------------------------------------------*/
int PlayerCanSave() {
if (bSaveDisabled) return (0);
if (bCacciatore) return (0);
if (IsPlayerInPool()) return (0);
if (bPlayerSuBasamento) return (0);
if (bLockCamera) return (0);
return (1);
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,42 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_PLAYER_H
#define WATCHMAKER_DO_PLAYER_H
#include "watchmaker/globvar.h"
#include "watchmaker/game.h"
namespace Watchmaker {
void SetCurPlayerPosTo_9x(GameVars &gameVars, Init &init);
void doPlayer(WGame &game);
void ChangePlayer(WGame &game, uint8 oc);
void ProcessCharacters(WGame &game);
void UpdatePlayerStand(WGame &game, uint8 oc);
int PlayerCanSwitch(GameVars &gameVars, char no_inventory);
int PlayerCanCall(GameVars &gameVars);
int PlayerCanSave();
int IsPlayerInPool();
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_PLAYER_H

View File

@@ -0,0 +1,55 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_scr_scr.h"
#include "watchmaker/define.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/types.h"
#include "watchmaker/ll/ll_anim.h"
#include "watchmaker/classes/do_string.h"
namespace Watchmaker {
/* -----------------19/05/98 16.40-------------------
* doScrScrUseWith
* --------------------------------------------------*/
void doScrScrUseWith(WGame &game) {
uint8 sent = TRUE;
switch (UseWith[USED]) {
case o2DQUADRODIVANO:
if (UseWith[WITH] == o2DCASSAFORTECH) {
StartAnim(game, a2D6);
sent = false;
}
break;
default:
sent = TRUE;
break;
}
if (sent)
if (!(!(bUseWith & UW_WITHI) && (UseWith[USED] == UseWith[WITH])))
PlayerSpeak(game, game.init.Obj[UseWith[USED]].action[CurPlayer]);
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,34 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_SCR_SCR_H
#define WATCHMAKER_DO_SCR_SCR_H
#include "watchmaker/saveload.h"
#include "watchmaker/game.h"
namespace Watchmaker {
void doScrScrUseWith(WGame &game);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_SCR_SCR_H

View File

@@ -0,0 +1,368 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_sound.h"
#include "watchmaker/utils.h"
#include "watchmaker/types.h"
#include "watchmaker/globvar.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/define.h"
#include "watchmaker/ll/ll_sound.h"
#include "watchmaker/3d/geometry.h"
#include "watchmaker/3d/t3d_body.h"
#include "watchmaker/3d/t3d_mesh.h"
#include "watchmaker/work_dirs.h"
#include "watchmaker/ll/ll_util.h"
#include "watchmaker/game.h"
#include "watchmaker/walk/walkutil.h"
#define METER2UNIT 256.051971816707218167072181680248f
#define PG 3.14159265358979323846f
#define GradToRad ((2.0f*PG)/360.0f)
#define gCOS(G) cos(G*GradToRad)
#define gSIN(G) sin(G*GradToRad)
namespace Watchmaker {
/* -----------------28/06/00 16.33-------------------
* InitMusic
* --------------------------------------------------*/
bool InitMusic() {
warning("STUBBED InitMusic");
#if 0
if (!mInitMusicSystem())
return false;
if (!sInitSoundSystem(hWnd))
return false;
sSetDistanceFactor(METER2UNIT);
#endif
return true;
}
bool ListenerUpdate() {
sListener CurListener;
CurListener.flDistanceFactor = 1.0f;
CurListener.flRolloff = 0.1f;
CurListener.v3flFrontOrientation.x = t3dCurCamera->NormalizedDir.x;
CurListener.v3flFrontOrientation.y = t3dCurCamera->NormalizedDir.y;
CurListener.v3flFrontOrientation.z = t3dCurCamera->NormalizedDir.z;
CurListener.v3flTopOrientation.x = 0.0f;
CurListener.v3flTopOrientation.y = 1.0f;
CurListener.v3flTopOrientation.z = 0.0f;
CurListener.v3flPosition.x = t3dCurCamera->Source.x;
CurListener.v3flPosition.y = t3dCurCamera->Source.y;
CurListener.v3flPosition.z = t3dCurCamera->Source.z;
return sSetListener(&CurListener);
}
/* -----------------06/04/00 11.52-------------------
* PlaySound
* --------------------------------------------------*/
bool StartSpeech(WGame &game, int32 n) {
sSound CurSound;
if (game.gameOptions.speech_on == FALSE) return true;
snprintf(CurSound.name, SOUND_NAME_LEN, "%ss%04d.wav", game.workDirs._speechDir.c_str(), n);
CurSound.lIndex = MAX_SOUNDS + n;
CurSound.dwLooped = FALSE;
CurSound.flMinDistance = 1000 * METER2UNIT;
CurSound.flMaxDistance = 1001 * METER2UNIT;
//CurSound.flMinDistance = 1*METER2UNIT;
//CurSound.flMaxDistance = 1*METER2UNIT;
CurSound.v3flPosition.x = 0;
CurSound.v3flPosition.y = 0;
CurSound.v3flPosition.z = 0;
/* Queste righe dovrebbero dare spazialita' al suono, ma visto che non funziona lo playamo diffuso
if( Anim[TimeAnim].obj )
{
CurSound.v3flPosition.x = Character[Anim[TimeAnim].obj]->Pos.x;
CurSound.v3flPosition.y = Character[Anim[TimeAnim].obj]->Pos.y;
CurSound.v3flPosition.z = Character[Anim[TimeAnim].obj]->Pos.z;
DebugLogWindow("StartSpeech(%d): %s",n,Character[Anim[TimeAnim].obj]->Body->Name);
}else
{
CurSound.v3flPosition.x = Character[CurPlayer+ocCURPLAYER]->Pos.x;
CurSound.v3flPosition.y = Character[CurPlayer+ocCURPLAYER]->Pos.y;
CurSound.v3flPosition.z = Character[CurPlayer+ocCURPLAYER]->Pos.z;
DebugLogWindow("StartSpeech(%d): %s",n,Character[CurPlayer+ocCURPLAYER]->Body->Name);
}*/
// 12 Ore
CurSound.v3flConeOrientation.x = 1;
CurSound.v3flConeOrientation.y = 0;
CurSound.v3flConeOrientation.z = 0;
CurSound.dwConeInsideAngle = 360;
CurSound.dwConeOutsideAngle = 360;
CurSound.dwConeOutsideVolume = 0;
CurSound.dwFlags = SOUND_SPEECH;
ListenerUpdate();
return (sStartSoundDiffuse(&CurSound));
// return( sStartSound( &CurSound, FALSE ) );
}
/* -----------------06/04/00 11.52-------------------
* PlaySound
* --------------------------------------------------*/
bool StartSound(WGame &game, int32 index) {
sSound CurSound;
t3dMESH *m;
Init &init = game.init;
if (game.gameOptions.sound_on == FALSE) return TRUE;
snprintf(CurSound.name, SOUND_NAME_LEN, "%s%s", game.workDirs._wavDir.c_str(), init.Sound[index].name);
CurSound.lIndex = index;
CurSound.dwLooped = (init.Sound[index].flags & SOUND_LOOP);
CurSound.flMinDistance = init.Sound[index].MinDist * METER2UNIT;
CurSound.flMaxDistance = init.Sound[index].MaxDist * METER2UNIT;
m = LinkMeshToStr(init, (char *)init.Sound[index].meshlink[0].rawArray());
if (m) {
CurSound.v3flPosition.x = m->Pos.x;
CurSound.v3flPosition.y = m->Pos.y;
CurSound.v3flPosition.z = m->Pos.z;
} else {
CurSound.v3flPosition.x = 0.f;
CurSound.v3flPosition.y = 0.f;
CurSound.v3flPosition.z = 0.f;
}
// 360 gradi
// CurSound.v3flConeOrientation.x = gCOS(Sound[index].Angle);
// CurSound.v3flConeOrientation.y = 0;
// CurSound.v3flConeOrientation.z = gSIN(Sound[index].Angle);
// 12 Ore
CurSound.v3flConeOrientation.x = (float) - gCOS((double)(init.Sound[index].Angle * 30.0f));
CurSound.v3flConeOrientation.y = 0.0f;
CurSound.v3flConeOrientation.z = (float) - gSIN((double)(init.Sound[index].Angle * 30.0f));
CurSound.dwConeInsideAngle = init.Sound[index].ConeInside;
CurSound.dwConeOutsideAngle = init.Sound[index].ConeOutside;
CurSound.dwConeOutsideVolume = init.Sound[index].ConeOutsideVolume;
CurSound.dwFlags = init.Sound[index].flags;
if (!sStartSound(&CurSound, FALSE)) return FALSE;
if (!ListenerUpdate()) return FALSE;
return TRUE;
}
/* -----------------06/04/00 11.52-------------------
* StopSound
* --------------------------------------------------*/
bool StopSound(int32 index) {
return (sStopSound(index));
}
/* -----------------05/06/00 12.18-------------------
* StartStepSound
* --------------------------------------------------*/
bool StartStepSound(WGame &game, t3dV3F *pos, uint8 side) {
double pgon[4][2];
int32 cs, ts, index;
sSound CurSound;
Init &init = game.init;
if (game.gameOptions.sound_on == FALSE) return TRUE;
if (!pos) return FALSE;
double px = (double)pos->x;
double pz = (double)pos->z;
if ((pos == &Player->Mesh->Trasl) && (side & SOUND_STAIRS)) {
px += (double)(Player->Dir.x * HALF_STEP);
pz += (double)(Player->Dir.z * HALF_STEP);
side &= ~SOUND_STAIRS;
}
index = cs = wNULL;
for (int32 i = 0; i < MAX_SOUNDS_IN_ROOM; i++) {
if (((cs = game.getCurRoom().sounds[i]) != wNULL) && (init.Sound[cs].flags & side)) {
bool found = false;
for (int32 j = 0; j < MAX_SOUND_MESHLINKS; j++) {
if (init.Sound[cs].meshlink[j][0] == '\0')
break;
auto it = t3dCurRoom->MeshTable.begin();
for (; it != t3dCurRoom->MeshTable.end(); ++it)
if (it->name.equalsIgnoreCase((const char *)init.Sound[cs].meshlink[j].rawArray())) {
found = true;
break;
}
}
if ((init.Sound[cs].meshlink[0][0] == '\0') || (!found)) { // se non ci sono meshlink o tutti i meshlinks sono in un'altra stanza
index = cs; // prende questo suono e continua la ricerca
continue;
}
ts = wNULL;
for (int32 j = 0; j < MAX_SOUND_MESHLINKS; j++) {
if (init.Sound[cs].meshlink[j][0] == '\0')
break;
auto it = t3dCurRoom->MeshTable.begin();
for (; it != t3dCurRoom->MeshTable.end(); ++it)
if (it->name.equalsIgnoreCase((const char *)init.Sound[cs].meshlink[j].rawArray()))
break;
if (it != t3dCurRoom->MeshTable.end()) {
auto &m = *it;
pgon[0][0] = (double)m.BBox[0].p.x;
pgon[0][1] = (double)m.BBox[0].p.z;
pgon[1][0] = (double)m.BBox[4].p.x;
pgon[1][1] = (double)m.BBox[4].p.z;
pgon[2][0] = (double)m.BBox[5].p.x;
pgon[2][1] = (double)m.BBox[5].p.z;
pgon[3][0] = (double)m.BBox[1].p.x;
pgon[3][1] = (double)m.BBox[1].p.z;
if (PointInside2DRectangle(pgon, px, pz)) {
ts = cs;
break;
} else
ts = -1;
}
}
if (ts > wNULL) {
index = ts;
break;
}
}
}
if (index == wNULL)
return FALSE;
snprintf(CurSound.name, SOUND_NAME_LEN, "%s%s", game.workDirs._wavDir.c_str(), init.Sound[index].name);
CurSound.lIndex = index;
CurSound.dwLooped = (init.Sound[index].flags & SOUND_LOOP);
CurSound.flMinDistance = init.Sound[index].MinDist * METER2UNIT;
CurSound.flMaxDistance = init.Sound[index].MaxDist * METER2UNIT;
if (pos != nullptr) {
CurSound.v3flPosition.x = pos->x;
CurSound.v3flPosition.y = pos->y;
CurSound.v3flPosition.z = pos->z;
}
//12 Ore
CurSound.v3flConeOrientation.x = (float) - gCOS((double)(init.Sound[index].Angle * 30));
CurSound.v3flConeOrientation.y = 0;
CurSound.v3flConeOrientation.z = (float) - gSIN((double)(init.Sound[index].Angle * 30));
CurSound.dwConeInsideAngle = init.Sound[index].ConeInside;
CurSound.dwConeOutsideAngle = init.Sound[index].ConeOutside;
CurSound.dwConeOutsideVolume = init.Sound[index].ConeOutsideVolume;
CurSound.dwFlags = init.Sound[index].flags;
if (!ListenerUpdate()) return FALSE;
if (!bDontPlaySteps) {
if (!sStartSound(&CurSound, FALSE)) return FALSE;
}
//if (!sStartInstantSound( &CurSound ) ) return FALSE;
//if (!ListenerUpdate()) return FALSE;
return TRUE;
}
/* -----------------28/06/00 16.33-------------------
* Ferma tutti i midi in Play
* --------------------------------------------------*/
bool StopMusic() {
if (!mStopMusic()) return FALSE;
//if( !sStopAllSounds() ) return FALSE;
warning("STUBBED: StopMusic");
#if 0
CurPlayIndex = -1;
CurPlaySubMusic = -1;
CurMusicName[0] = 0;
#endif
return TRUE;
}
/* -----------------28/06/00 16.33-------------------
* Ferma il MIDI con un fade di FadeOutTime ms,
* fa partire il MIDI index con un fade di FadeInTime ms.
* --------------------------------------------------*/
bool PlayMusic(int32 index, uint32 FadeOutTime, uint32 FadeInTime) {
warning("STUBBED: PlayMusic");
#if 0
char FileName[MAX_PATH];
if (GameOptions.music_on == FALSE) return TRUE;
if ((CurPlayIndex == index) && (CurPlaySubMusic == CurSubMusic)) return TRUE;
if (!strcasecmp(CurMusicName, Music[index].name[CurSubMusic])) return TRUE;
if ((Music[index].vol[CurSubMusic] != 0) &&
(Music[index].vol[CurSubMusic] != mGetAllVolume())) {
if (!mSetAllVolume((BYTE)Music[index].vol[CurSubMusic])) return FALSE;
}
snprintf(FileName, MAX_PATH, "%s%s", WmMidiDir, Music[index].name[CurSubMusic]);
if (!mLoadMusic(FileName)) {
if (CurPlayIndex == -1) return TRUE;
mInstantFadeOut(NULL, FadeOutTime);
CurPlayIndex = -1;
CurPlaySubMusic = -1;
CurMusicName[0] = '\0';
return TRUE;
}
//if (!mPlayMusic(FileName))
if (!mCrossFade(FileName, FadeOutTime, FadeInTime)) {
CurPlayIndex = -1;
CurPlaySubMusic = -1;
CurMusicName[0] = '\0';
return FALSE;
}
DebugLogFile("PM %s", FileName);
CurPlayIndex = index;
CurPlaySubMusic = CurSubMusic;
strcpy(CurMusicName, Music[index].name[CurSubMusic]);
#endif
return TRUE;
}
bool StopSounds() {
if (!sStopAllSounds()) return false;
return true;
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,40 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_SOUND_H
#define WATCHMAKER_DO_SOUND_H
#include "watchmaker/game.h"
namespace Watchmaker {
bool InitMusic();
bool StartSound(WGame &game, int32 index);
bool StartStepSound(WGame &game, t3dV3F *pos, uint8 side);
bool StopSound(int32 index);
bool StopSounds();
bool StopMusic();
bool StartSpeech(WGame &game, int32 n);
bool PlayMusic(int32 index, uint32 FadeOutTime, uint32 FadeInTime);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_SOUND_H

View File

@@ -0,0 +1,246 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "watchmaker/classes/do_string.h"
#include "watchmaker/globvar.h"
#include "watchmaker/message.h"
#include "watchmaker/define.h"
#include "watchmaker/ll/ll_anim.h"
#include "watchmaker/schedule.h"
#include "watchmaker/ll/ll_string.h"
#include "watchmaker/windows_hacks.h"
#include "watchmaker/ll/ll_sound.h"
#include "watchmaker/t2d/expr.h"
#include "watchmaker/classes/do_sound.h"
// Locals
#define DEFAULT_TEXT_X 25
#define DEFAULT_TEXT_Y 537
#define DEFAULT_TEXT_DX SCREEN_RES_X-DEFAULT_TEXT_X*2
namespace Watchmaker {
char UWStr[100];
/* -----------------18/03/98 11.11-------------------
* PlayerSpeak
* --------------------------------------------------*/
bool PlayerSpeak(WGame &game, int32 n) {
int32 EndSpeakTime, SentTime;
uint8 show_text;
int32 speechn = 0;
Init &init = game.init;
if (!n) return false;
if (Sentence[n][0] == '*') {
StartAnim(game, aBOH);
return false;
} else if (Sentence[n][0] == '#') {
StartAnim(game, aPENSA);
return false;
}
SentTime = VisemaRecon(n);
if ((n <= 15) && (bDialogActive)) {
switch (n) {
case 1:
SentTime = 4560;
init.Anim[aDUMMY_dR391_A].obj = ocOROLOGIAIO;
break;
case 2:
SentTime = 1200;
init.Anim[aDUMMY_dR391_A].obj = ocVECCHIO;
break;
case 3:
SentTime = 5960;
init.Anim[aDUMMY_dR391_A].obj = ocVECCHIO;
break;
case 4:
SentTime = 8200;
init.Anim[aDUMMY_dR391_A].obj = ocCHIRURGO;
break;
case 5:
SentTime = 800;
init.Anim[aDUMMY_dR391_A].obj = ocCHIRURGO;
break;
case 6:
SentTime = 4560;
init.Anim[aDUMMY_dR391_A].obj = ocVECCHIO;
break;
case 7:
SentTime = 7200;
init.Anim[aDUMMY_dR391_A].obj = ocCHIRURGO;
break;
case 8:
SentTime = 7200;
init.Anim[aDUMMY_dR391_A].obj = ocVECCHIO;
break;
case 9:
SentTime = 5520;
init.Anim[aDUMMY_dR391_A].obj = ocCHIRURGO;
break;
case 10:
SentTime = 7720;
init.Anim[aDUMMY_dR391_A].obj = ocVECCHIO;
break;
case 11:
SentTime = 1600;
init.Anim[aDUMMY_dR391_A].obj = ocCHIRURGO;
break;
case 12:
SentTime = 1200;
init.Anim[aDUMMY_dR391_A].obj = ocVECCHIO;
break;
case 13:
SentTime = 2560;
init.Anim[aDUMMY_dR391_A].obj = ocVECCHIO;
break;
case 14:
SentTime = 6720;
init.Anim[aDUMMY_dR391_A].obj = ocTRADUTTORE;
break;
case 15:
SentTime = 2200;
init.Anim[aDUMMY_dR391_A].obj = ocVECCHIO;
break;
}
}
if (game.gameOptions.subtitles_on) show_text = 1;
else show_text = 0;
if (game.gameOptions.speech_on) {
if (StartSpeech(game, n)) {
speechn = MAX_SOUNDS + n;
DebugLogWindow("PP %d, SentTime %d", speechn, SentTime);
} else show_text = 1;
}
if (show_text) {
if (InvStatus & INV_ON)
Text(DEFAULT_TEXT_X, DEFAULT_TEXT_Y, DEFAULT_TEXT_DX, Sentence[n]);
else
Text(20, DEFAULT_TEXT_Y, DEFAULT_TEXT_DX, Sentence[n]);
}
// DebugLogFile("PLS (%d) %s",SentTime,Sentence[n]);
EndSpeakTime = TheTime + SentTime;
bSomeOneSpeak = TRUE;
bPlayerSpeak = TRUE;
bSkipTalk = FALSE;
if (speechn)
_vm->_messageSystem.doEvent(EventClass::MC_STRING, ME_PLAYERCONTINUESPEAK_WAITWAVE, MP_WAIT_RETRACE, 0, 0, 0, &speechn, nullptr, nullptr);
else
_vm->_messageSystem.doEvent(EventClass::MC_STRING, ME_PLAYERCONTINUESPEAK, MP_WAIT_RETRACE, 0, 0, 0, &EndSpeakTime, nullptr, nullptr);
return TRUE;
}
/* -----------------18/03/98 11.06-------------------
* doString
* --------------------------------------------------*/
void doString(WGame &game) {
switch (TheMessage->event) {
case ME_PLAYERSPEAK:
PlayerSpeak(game, TheMessage->wparam1);
break;
case ME_PLAYERCONTINUESPEAK:
if (((int32)TheTime > TheMessage->lparam[0]) || (bSkipTalk)) {
bSomeOneSpeak = false;
bPlayerSpeak = false;
bSkipTalk = false;
bAnimWaitText = false;
ClearText();
if (!bDialogActive) _vm->_messageSystem.addWaitingMsgs(MP_WAIT_LINK);
} else {
TheMessage->flags |= MP_WAIT_RETRACE;
ReEvent();
}
break;
case ME_PLAYERCONTINUESPEAK_WAITWAVE: {
bool isp;
isp = sIsPlaying(TheMessage->lparam[0]);
if ((!isp) || bSkipTalk) {
if (bSkipTalk && isp) {
sStopSound(TheMessage->lparam[0]);
}
bSomeOneSpeak = false;
bPlayerSpeak = false;
bSkipTalk = false;
bAnimWaitText = false;
ClearText();
if (!bDialogActive) _vm->_messageSystem.addWaitingMsgs(MP_WAIT_LINK);
} else {
TheMessage->flags |= MP_WAIT_RETRACE;
ReEvent();
}
}
break;
}
}
/* -----------------17/03/98 16.19-------------------
* ShowObjName
* --------------------------------------------------*/
void ShowObjName(Init &init, int32 ob) {
if (bUseWith & UW_ON) {
if (bUseWith & UW_USEDI)
snprintf(UWStr, 100, "Use %s with ", ObjName[init.InvObj[UseWith[USED]].name]);
else
snprintf(UWStr, 100, "Use %s with ", ObjName[init.Obj[UseWith[USED]].name]);
if ((UseWith[USED] != ob) || (bUseWith & UW_USEDI))
if (ObjName[init.Obj[ob].name] != nullptr)
Common::strlcat(UWStr, ObjName[init.Obj[ob].name], 100);
Text(DEFAULT_TEXT_X, DEFAULT_TEXT_Y, DEFAULT_TEXT_DX, UWStr);
} else if (!ob || !init.Obj[ob].name)
ClearText();
else
Text(DEFAULT_TEXT_X, DEFAULT_TEXT_Y, DEFAULT_TEXT_DX, ObjName[init.Obj[ob].name]);
}
/* -----------------17/03/98 16.19-------------------
* ShowInvObjName
* --------------------------------------------------*/
void ShowInvObjName(Init &init, int32 obj) {
if (bUseWith & UW_ON) {
if (bUseWith & UW_USEDI)
snprintf(UWStr, 100, "Use %s with ", ObjName[init.InvObj[UseWith[USED]].name]);
else
snprintf(UWStr, 100, "Use %s with ", ObjName[init.Obj[UseWith[USED]].name]);
if ((UseWith[USED] != obj) || !(bUseWith & UW_USEDI))
if (ObjName[init.InvObj[obj].name] != nullptr)
Common::strlcat(UWStr, ObjName[init.InvObj[obj].name], 100);
Text(DEFAULT_TEXT_X, DEFAULT_TEXT_Y, DEFAULT_TEXT_DX, UWStr);
} else //if ( !obj )
ClearText();
// else
// Text( 100, d3dappi.szClient.cy-30, ObjName[InvObj[obj].name] );
}
} // End of namespace Watchmaker

View File

@@ -0,0 +1,38 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_STRING_H
#define WATCHMAKER_DO_STRING_H
#include "watchmaker/types.h"
#include "watchmaker/globvar.h"
#include "watchmaker/game.h"
namespace Watchmaker {
void doString(WGame &game);
bool PlayerSpeak(WGame &game, int32 n);
void ShowObjName(Init &init, int32 ob);
void ShowInvObjName(Init &init, int32 obj);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_STRING_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHMAKER_DO_SYSTEM_H
#define WATCHMAKER_DO_SYSTEM_H
#include "watchmaker/struct.h"
#include "watchmaker/globvar.h"
#include "watchmaker/game.h"
namespace Watchmaker {
void InitMain(WGame &game);
extern SRoomInfo RoomInfo;
void NextMessage(WGame &game);
void doSystem(WGame &game);
void TitoliCoda_ShowStatic(WGame &game, char initialize);
} // End of namespace Watchmaker
#endif // WATCHMAKER_DO_SYSTEM_H