Initial commit
This commit is contained in:
1862
engines/watchmaker/ll/ll_anim.cpp
Normal file
1862
engines/watchmaker/ll/ll_anim.cpp
Normal file
File diff suppressed because it is too large
Load Diff
46
engines/watchmaker/ll/ll_anim.h
Normal file
46
engines/watchmaker/ll/ll_anim.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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_LL_ANIM_H
|
||||
#define WATCHMAKER_LL_ANIM_H
|
||||
|
||||
#include "watchmaker/types.h"
|
||||
#include "watchmaker/work_dirs.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
#include "watchmaker/game.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
void StopObjAnim(WGame &game, int32 obj);
|
||||
bool CheckAndLoadMoglieSupervisoreModel(WorkDirs &workDirs, int32 c);
|
||||
void StartAnim(WGame &game, int32 an);
|
||||
void StopAnim(WGame &game, int32 an);
|
||||
void PauseAnim(Init &init, int32 an);
|
||||
void ContinueAnim(Init &init, int32 an);
|
||||
void StopAllAnims(Init &init);
|
||||
void StopPlayingGame(WGame &game);
|
||||
void ProcessATF(WGame &game, int32 an, int32 atf);
|
||||
void ProcessATFDO(WGame &game, int32 in);
|
||||
void ProcessAnims(WGame &game);
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_ANIM_H
|
||||
520
engines/watchmaker/ll/ll_diary.cpp
Normal file
520
engines/watchmaker/ll/ll_diary.cpp
Normal file
@@ -0,0 +1,520 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_strcat
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
|
||||
|
||||
#include "watchmaker/game.h"
|
||||
#include "watchmaker/ll/ll_diary.h"
|
||||
#include "watchmaker/ll/ll_util.h"
|
||||
#include "watchmaker/3d/geometry.h"
|
||||
#include "watchmaker/ll/ll_mesh.h"
|
||||
#include "watchmaker/windows_hacks.h"
|
||||
#include "watchmaker/define.h"
|
||||
#include "watchmaker/ll/ll_system.h"
|
||||
#include "watchmaker/walk/act.h"
|
||||
#include "watchmaker/ll/ll_anim.h"
|
||||
#include "watchmaker/3d/animation.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
char bDiariesStoppedByTimeInc = 0;
|
||||
|
||||
void t3dLoadOutdoorLights(const char *pname, t3dBODY *b, int32 ora);
|
||||
|
||||
/* -----------------26/11/1999 16.19-----------------
|
||||
* StartDiary
|
||||
* --------------------------------------------------*/
|
||||
void StartDiary(WGame &game, int32 room, t3dV3F *pos) {
|
||||
struct SDiary *d, *l;
|
||||
int32 tot_rand, cur_rand;
|
||||
int32 i, j, ca;
|
||||
t3dF32 acceptable_dist;
|
||||
char special_flag;
|
||||
uint8 cr;
|
||||
Init &init = game.init;
|
||||
|
||||
if (t3dCurRoom) cr = (uint8)getRoomFromStr(init, t3dCurRoom->name);
|
||||
else cr = rNULL;
|
||||
|
||||
if (bDisableDiary) return ;
|
||||
|
||||
// DebugLogFile( "Parto Diario per room %d", room );
|
||||
|
||||
for (i = 0, d = &init.Diary[0]; i < MAX_DIARIES; i++, d++) {
|
||||
if ((d->room != room) || (t3dCurTime < d->startt) || (d->endt && (t3dCurTime >= d->endt))) continue;
|
||||
if (d->item[d->cur].on) continue;
|
||||
if ((Character[d->obj]) && (Character[d->obj]->Flags & T3D_CHARACTER_DIARYDISABLE)) continue;
|
||||
if (init.Dialog[CurDialog].obj == d->obj) continue; //se e' attivo un dialogo e si cerca di far partire il diario del personaggio che sta' gia' parlando
|
||||
|
||||
for (j = 0, l = &init.Diary[0]; j < MAX_DIARIES; j++, l++)
|
||||
if ((l->obj == d->obj) && (l->item[l->cur].on))
|
||||
break;
|
||||
if (j < MAX_DIARIES) continue;
|
||||
|
||||
if (cr != rNULL) {
|
||||
//se un diario e' fuori ma l'omino e' dentro non lo faccio partire
|
||||
if ((d->room == rXT) && (cr != rXT)) {
|
||||
DebugLogWindow("Skippato diario %d in rXT: obj %d room %d", i, d->obj, d->room);
|
||||
continue;
|
||||
}
|
||||
|
||||
//se il diario e' nella r13 ma non siamo nella r13 skippo
|
||||
if ((d->room == r13) && (cr != r13)) {
|
||||
DebugLogWindow("Skippato diario %d in r13: obj %d room %d", i, d->obj, d->room);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if( i==36)
|
||||
// DebugLogFile("START36 d->startt %d, d->endt %d, d->obj %d",d->startt,d->endt,d->obj);
|
||||
// DebugLogFile( "Diario valido num %d", i );
|
||||
|
||||
// da usare per quei personaggi che, tra un diario e il successivo, cambiano posizione (sempre nel caso che un dialogo/rtv abbia incrementato il tempo e fatto cosi' switchare il diario)
|
||||
special_flag = 0;
|
||||
if (bDiariesStoppedByTimeInc && (d->obj == ocSERVETTA)) special_flag = 1;
|
||||
|
||||
acceptable_dist = 40000.0f;
|
||||
|
||||
// la servetta ha bisogno di piu' spazio vista la disposizione delle luci di posizione dei dialoghi e dei background
|
||||
if (d->obj == ocSERVETTA) acceptable_dist = 200000.0f;
|
||||
|
||||
// quando il sup non c'<27> noi possiamo rubare la foto e quindi il portafoto diventa vuoto. Quando lui torna dobbiamo fare in modo che il portafoto sia rovesciato
|
||||
if ((d->obj == ocSUPERVISORE) && (d->room == r29) && (init.Obj[o29PORTAFOTOVUOTO].flags & ON) && (!(init.Obj[o29PORTAFOTOROVESCIATO].flags & ON))) {
|
||||
init.Obj[o29PORTAFOTOVUOTO].flags &= ~ON;
|
||||
UpdateObjMesh(init, o29PORTAFOTOVUOTO);
|
||||
init.Obj[o29PORTAFOTOROVESCIATO].flags |= ON;
|
||||
UpdateObjMesh(init, o29PORTAFOTOROVESCIATO);
|
||||
}
|
||||
|
||||
// la domestica ha bisogno di piu' spazio in questa circostanza vista la disposizione delle luci di posizione dei dialoghi e dei background
|
||||
if ((d->obj == ocDOMESTICA) && ((d->room == r22) || (d->room == r26) || (d->room == r28))) acceptable_dist = 200000.0f;
|
||||
|
||||
tot_rand = 0;
|
||||
for (j = 0; j < MAX_ANIMS_PER_DIARY_ITEM; j++)
|
||||
if ((special_flag) || (pos == nullptr) || ((d->item[j].anim[0]) && (CompareLightPosition((char *) init.Anim[d->item[j].anim[0]].RoomName.rawArray(), init.Anim[d->item[j].anim[0]].pos, pos, acceptable_dist))))
|
||||
tot_rand += d->item[j].rand;
|
||||
|
||||
if (!tot_rand) continue;
|
||||
game._rnd->setSeed((unsigned)t3dReadTime());
|
||||
cur_rand = game._rnd->getRandomNumber(tot_rand - 1);
|
||||
|
||||
// DebugLogFile( "Random %d (%d)", cur_rand, tot_rand );
|
||||
|
||||
tot_rand = 0;
|
||||
for (j = 0; j < MAX_ANIMS_PER_DIARY_ITEM; j++) {
|
||||
if ((special_flag) || (pos == nullptr) || ((d->item[j].anim[0]) && (CompareLightPosition((char *) init.Anim[d->item[j].anim[0]].RoomName.rawArray(), init.Anim[d->item[j].anim[0]].pos, pos, acceptable_dist)))) {
|
||||
tot_rand += d->item[j].rand;
|
||||
// DebugLogFile( "%d: %d (%d)", j, cur_rand, tot_rand );
|
||||
if (cur_rand < tot_rand)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ca = d->item[j].anim[0]) || init.Anim[ca].active)
|
||||
continue;
|
||||
|
||||
// DebugLogFile( "Parte anim %d char %d pos %d", ca, d->obj, Anim[ca].pos );
|
||||
Character[d->obj]->Flags &= ~T3D_CHARACTER_HIDE;
|
||||
|
||||
d->cur = j;
|
||||
d->item[d->cur].on = TRUE;
|
||||
d->item[d->cur].cur = 0;
|
||||
d->item[d->cur].loopc = 0;
|
||||
if (d->end_hideobj) d->end_hideobj |= 0x8000; //se ha un oggetto assegnato setto anche il flag piu' alto
|
||||
|
||||
init.Anim[ca].flags |= ANIM_DIARY;
|
||||
if ((d->item[d->cur].bnd < 255) && !(bPlayerSuBasamento && (d->room == rXT))) {
|
||||
d->item[d->cur].saved_bnd = GetBndLevel((char *) init.Anim[ca].RoomName.rawArray());
|
||||
SetBndLevel(game, (char *)init.Anim[ca].RoomName.rawArray(), d->item[d->cur].bnd);
|
||||
} else d->item[d->cur].saved_bnd = 255;
|
||||
|
||||
if (d->obj) CharSetPosition(d->obj, init.Anim[ca].pos, (char *)init.Anim[ca].RoomName.rawArray());
|
||||
StartAnim(game, ca);
|
||||
}
|
||||
|
||||
bDiariesStoppedByTimeInc = 0;
|
||||
|
||||
// Fa partire animazione di stand dell'altro personaggio
|
||||
i = (CurPlayer ^ 1);
|
||||
if ((Character[i + ocDARRELL]->Flags & T3D_CHARACTER_HIDE) && (PlayerStand[i].cr == room)) {
|
||||
Character[i + ocDARRELL]->Flags &= ~T3D_CHARACTER_HIDE;
|
||||
// CharSetPosition( i+ocDARRELL, Anim[PlayerStand[i].an].pos, PlayerStand[i].RoomName );
|
||||
CharSetPosition(i + ocDARRELL, PlayerStand[i].pos, PlayerStand[i].roomName.c_str());
|
||||
StartAnim(game, PlayerStand[i].an);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------26/11/1999 16.39-----------------
|
||||
* StopDiary
|
||||
* --------------------------------------------------*/
|
||||
void StopDiary(WGame &game, int32 room, int32 obj, uint8 only_overtime) {
|
||||
struct SDiary *d;
|
||||
int32 i, an;
|
||||
char is_overtime;
|
||||
uint8 cr;
|
||||
Init &init = game.init;
|
||||
|
||||
if (t3dCurRoom) cr = (uint8)getRoomFromStr(init, t3dCurRoom->name);
|
||||
else cr = rNULL;
|
||||
|
||||
// DebugLogFile( "Finisco Diario per room %d", room );
|
||||
|
||||
for (i = 0, d = &init.Diary[0]; i < MAX_DIARIES; i++, d++) {
|
||||
if (obj && (obj != d->obj)) continue;
|
||||
|
||||
if ((room > 0) && (d->room != room)) continue;
|
||||
|
||||
if ((room < 0) && (room == cr)) continue;
|
||||
|
||||
is_overtime = (t3dCurTime < d->startt) || ((d->endt != 0) && (t3dCurTime >= d->endt));
|
||||
|
||||
if (only_overtime && (!is_overtime)) continue;
|
||||
|
||||
if (is_overtime && (d->end_hideobj & 0x8000)) { //se ha il bit settato significa che aveva un oggetto da nascondere e il diario era stato lanciato almeno una volta
|
||||
d->end_hideobj &= 0x7FFF; //rimuovo l'ultimo bit
|
||||
DebugLogFile("!! EndAnim !! per obj %d (%s)", d->end_hideobj, Character[d->obj]->Mesh->name.c_str());
|
||||
init.Obj[d->end_hideobj].flags &= ~ON;
|
||||
UpdateObjMesh(init, d->end_hideobj);
|
||||
d->end_hideobj = 0;
|
||||
|
||||
//caso particolare dello sportello del bagno
|
||||
if ((d->room == r2M) && (d->obj == ocCUSTODE)) {
|
||||
init.Obj[o2MOGGETTICUSTODE_TOHIDE].flags |= ON;
|
||||
UpdateObjMesh(init, o2MOGGETTICUSTODE_TOHIDE);
|
||||
}
|
||||
|
||||
//casi particolari delle porte dei diari della servetta
|
||||
if (i == eSERVETTA1) {
|
||||
init.Obj[o2CMEGABB_2R].flags &= ~ON;
|
||||
UpdateObjMesh(init, o2CMEGABB_2R);
|
||||
// stanze in cui la r2C e la r2R sono caricate
|
||||
if ((cr == r2C) || (cr == r2F) || (cr == r15) || (cr == r2E) || (cr == r2R) || (cr == r2T) || (cr == r2S) || (cr == r31)) {
|
||||
t3dResetMesh(LinkMeshToStr(init, "o2c-portacamere02"));
|
||||
t3dResetMesh(LinkMeshToStr(init, "o2r-portacamere2c01"));
|
||||
}
|
||||
}
|
||||
if (i == eSERVETTA2) {
|
||||
init.Obj[o2CMEGABB_2S].flags &= ~ON;
|
||||
UpdateObjMesh(init, o2CMEGABB_2S);
|
||||
// stanze in cui la r2C e la r2R sono caricate
|
||||
if ((cr == r2C) || (cr == r2F) || (cr == r15) || (cr == r2E) || (cr == r2R) || (cr == r2T) || (cr == r2S) || (cr == r31)) {
|
||||
t3dResetMesh(LinkMeshToStr(init, "o2c-portacamere06"));
|
||||
t3dResetMesh(LinkMeshToStr(init, "o2s-portacamere01"));
|
||||
}
|
||||
}
|
||||
if (i == eSERVETTA4) {
|
||||
init.Obj[o2PMEGABB_2D].flags &= ~ON;
|
||||
UpdateObjMesh(init, o2PMEGABB_2D);
|
||||
// stanze in cui la r2P e la r2D sono caricate
|
||||
if ((cr == r27) || (cr == r2P) || (cr == r2D)) {
|
||||
t3dResetMesh(LinkMeshToStr(init, "o2p-portasup"));
|
||||
t3dResetMesh(LinkMeshToStr(init, "o2d-portasup"));
|
||||
}
|
||||
}
|
||||
|
||||
}//end_hideobj
|
||||
|
||||
// da mettere dopo "end_hideobj", perche' anche se il diario non e' attivo gli oggetti li devo spegnere lo stesso
|
||||
if (!d->item[d->cur].on) continue;
|
||||
|
||||
an = d->item[d->cur].anim[d->item[d->cur].cur];
|
||||
init.Anim[an].flags &= ~ANIM_DIARY;
|
||||
StopAnim(game, an);
|
||||
if ((d->item[d->cur].saved_bnd < 255)) {
|
||||
if (!(bPlayerSuBasamento && (d->room == rXT)))
|
||||
SetBndLevel(game, (char *)init.Anim[an].RoomName.rawArray(), d->item[d->cur].saved_bnd);
|
||||
d->item[d->cur].saved_bnd = 255;
|
||||
}
|
||||
Character[d->obj]->Flags |= T3D_CHARACTER_HIDE;
|
||||
// DebugLogWindow("%s HIDEEEEEEEE: Flags %d",Character[d->obj]->Mesh->Name,Character[d->obj]->Flags);
|
||||
d->item[d->cur].on = FALSE;
|
||||
d->item[d->cur].loopc = 0;
|
||||
d->item[d->cur].cur = 0;
|
||||
d->cur = 0;
|
||||
}
|
||||
|
||||
// Termina animazione di stand dell'altro personaggio
|
||||
if (!obj) {
|
||||
i = (CurPlayer ^ 1);
|
||||
if (!(Character[i + ocDARRELL]->Flags & T3D_CHARACTER_HIDE) && (PlayerStand[i].cr == room)) {
|
||||
StopObjAnim(game, i + ocDARRELL);
|
||||
Character[i + ocDARRELL]->Flags |= T3D_CHARACTER_HIDE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------26/11/1999 16.49-----------------
|
||||
* ContinueDiary
|
||||
* --------------------------------------------------*/
|
||||
void ContinueDiary(WGame &game, int32 an) {
|
||||
struct SDiary *d;
|
||||
int32 i, ca;
|
||||
Init &init = game.init;
|
||||
|
||||
// DebugLogFile( "Continuo Diario per anim %d", an );
|
||||
|
||||
for (i = 0, d = &init.Diary[0]; i < MAX_DIARIES; i++, d++) {
|
||||
if ((!d->item[d->cur].on) || (d->item[d->cur].anim[d->item[d->cur].cur] != an)) continue;
|
||||
|
||||
d->item[d->cur].cur ++;
|
||||
if (!(ca = d->item[d->cur].anim[d->item[d->cur].cur]) || init.Anim[ca].active) {
|
||||
if ((!d->item[d->cur].loop) || !(ca = d->item[d->cur].anim[0]) || init.Anim[ca].active ||
|
||||
((d->item[d->cur].loop > 0) && ((d->item[d->cur].loopc + 1) >= d->item[d->cur].loop))) {
|
||||
if (!d->item[d->cur].anim[d->item[d->cur].cur])
|
||||
d->item[d->cur].cur --; //altrimenti quando stoppo il tutto becca un item vuoto
|
||||
StopDiary(game, d->room, d->obj, 0);
|
||||
/* d->item[d->cur].on = FALSE;
|
||||
d->item[d->cur].cur = 0;
|
||||
d->item[d->cur].loopc = 0;
|
||||
d->cur = 0;*/
|
||||
if (Character[d->obj] && Character[d->obj]->Mesh)
|
||||
StartDiary(game, d->room, &Character[d->obj]->Mesh->Trasl);
|
||||
else
|
||||
StartDiary(game, d->room, nullptr);
|
||||
break;
|
||||
} else {
|
||||
if (d->item[d->cur].loop > 0) d->item[d->cur].loopc ++;
|
||||
d->item[d->cur].cur = 0;
|
||||
ca = d->item[d->cur].anim[d->item[d->cur].cur];
|
||||
}
|
||||
}
|
||||
|
||||
// DebugLogFile( "Parte anim %d char %d pos %d", ca, d->obj, Anim[ca].pos );
|
||||
init.Anim[an].flags &= ~ANIM_DIARY;
|
||||
init.Anim[ca].flags |= ANIM_DIARY;
|
||||
CharSetPosition(d->obj, init.Anim[ca].pos, (char *)init.Anim[ca].RoomName.rawArray());
|
||||
StartAnim(game, ca);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------29/05/00 16.57-------------------
|
||||
* UpdateAllClocks
|
||||
* --------------------------------------------------*/
|
||||
void UpdateAllClocks(WGame &game) {
|
||||
char str[255];
|
||||
t3dMESH *mesh;
|
||||
Init &init = game.init;
|
||||
|
||||
const char *ClockMeshes[] = {
|
||||
"o21-a-ore01",
|
||||
"o21-a-minuti01",
|
||||
"o24-a-ore01",
|
||||
"o24-a-minuti01",
|
||||
"o2p-ore01",
|
||||
"o2p-minuti01",
|
||||
"o2s-ore01",
|
||||
"o2s-minuti01",
|
||||
nullptr
|
||||
};
|
||||
const char *ClockAnims[] = {
|
||||
"r21-a-orologio-ore.a3d",
|
||||
"r21-a-orologio-minuti.a3d",
|
||||
"r24-a-orologio-ore.a3d",
|
||||
"r24-a-orologio-minuti.a3d",
|
||||
"r2p-orologio-ore.a3d",
|
||||
"r2p-orologio-minuti.a3d",
|
||||
"r2s-orologio-ore.a3d",
|
||||
"r2s-orologio-minuti.a3d",
|
||||
nullptr
|
||||
};
|
||||
const char *ClockMeshes24[] = {
|
||||
"o48-lancettaore",
|
||||
"o48-lancettaore01",
|
||||
nullptr
|
||||
};
|
||||
const char *ClockAnims24[] = {
|
||||
"r48-ore.a3d",
|
||||
"r48-minuti.a3d",
|
||||
nullptr
|
||||
};
|
||||
int32 i, l[2];
|
||||
|
||||
l[0] = (t3dCurTime / 100) % 12;
|
||||
l[1] = (t3dCurTime % 100) / 5;
|
||||
if (!l[0]) l[0] = 12;
|
||||
if (!l[1]) l[1] = 12;
|
||||
// DebugLogWindow("%d: %d %d",t3dCurTime,l[0],l[1]);
|
||||
|
||||
for (i = 0;; i++) {
|
||||
if (ClockMeshes[i] == nullptr) break;
|
||||
if ((mesh = LinkMeshToStr(init, ClockMeshes[i])) == nullptr) continue;
|
||||
|
||||
t3dSetSpecialAnimFrame(game, ClockAnims[i], mesh, l[i % 2]);
|
||||
}
|
||||
|
||||
//orologio a 24ore (avanti di un'ora)
|
||||
l[0] = ((t3dCurTime + 100) / 100) % 24;
|
||||
l[1] = (t3dCurTime % 100) / 5;
|
||||
if (!l[0]) l[0] = 24;
|
||||
if (!l[1]) l[1] = 12;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
if (ClockMeshes24[i] == nullptr) break;
|
||||
if ((mesh = LinkMeshToStr(init, ClockMeshes24[i])) == nullptr) continue;
|
||||
|
||||
t3dSetSpecialAnimFrame(game, ClockAnims24[i], mesh, l[i % 2]);
|
||||
}
|
||||
|
||||
strcpy(str, game.workDirs._lightmapsDir.c_str());
|
||||
strcat(str, "rxt.t3d");
|
||||
if (t3dRxt)
|
||||
t3dLoadOutdoorLights(str, t3dRxt, t3dCurTime);
|
||||
}
|
||||
|
||||
/* -----------------22/05/00 10.03-------------------
|
||||
* IncCurTime
|
||||
* --------------------------------------------------*/
|
||||
void IncCurTime(WGame &game, int32 inc) {
|
||||
int32 h, m;
|
||||
Init &init = game.init;
|
||||
|
||||
t3dCurTime += inc;
|
||||
h = (t3dCurTime / 100);
|
||||
m = (t3dCurTime % 100);
|
||||
|
||||
while (m >= 60) {
|
||||
m -= 60;
|
||||
h ++;
|
||||
}
|
||||
|
||||
t3dCurTime = h * 100 + m;
|
||||
UpdateAllClocks(game);
|
||||
|
||||
if (bDialogActive && (init.Dialog[CurDialog].obj == ocSERVETTA)) {
|
||||
StopDiary(game, 0, init.Dialog[CurDialog].obj, 1);
|
||||
bDiariesStoppedByTimeInc = 1;
|
||||
}
|
||||
|
||||
// stoppo tutti i diari overtime di tutte le stanze esclusa la attuale
|
||||
StopDiary(game, -1, 0, 1);
|
||||
|
||||
|
||||
//la moglie del supervisore va in camera sua e non ci fa entrare in camera
|
||||
if ((t3dCurTime >= 1700) && (t3dCurTime < 1720)) {
|
||||
init.Obj[o2Pp2D].anim[CurPlayer] = a2P7;
|
||||
init.Obj[o2Pp2D].anim[CurPlayer ^ 1] = a2P7;
|
||||
init.Obj[o2Pp2D].pos = 2;
|
||||
}
|
||||
//il cuoco va a letto e noi non lo disturbiamo
|
||||
if ((t3dCurTime >= 1430) && (t3dCurTime < 1450)) {
|
||||
init.Obj[o2Cp2T].anim[CurPlayer] = a2C4_CUOCODORME;
|
||||
init.Obj[o2Cp2T].anim[CurPlayer ^ 1] = a2C4_CUOCODORME;
|
||||
}
|
||||
//il cuoco si alza e ci lascia entrare nella r2t
|
||||
if ((t3dCurTime >= 1715) && (t3dCurTime < 1735)) {
|
||||
init.Obj[o2Cp2T].anim[CurPlayer] = a2C4;
|
||||
init.Obj[o2Cp2T].anim[CurPlayer ^ 1] = a2C4;
|
||||
}
|
||||
//il supervisore ci da le foto
|
||||
if ((t3dCurTime >= 1900) && !(init.Dialog[dR008].flags & DIALOG_DONE)) {
|
||||
init.Obj[o2Qp29].anim[CurPlayer] = a2Q4b;
|
||||
init.Obj[o2Qp29].anim[CurPlayer ^ 1] = a2Q4b;
|
||||
}
|
||||
//la domestica ci cazzia
|
||||
if ((t3dCurTime >= 1715) && !(init.Dialog[dR015].flags & DIALOG_DONE)) {
|
||||
init.Obj[o25p2Q].anim[CurPlayer] = a2513_DOM;
|
||||
init.Obj[o25p2Q].anim[CurPlayer ^ 1] = a2513_DOM;
|
||||
|
||||
init.Obj[o25p24].anim[CurPlayer] = a2512_DOM;
|
||||
init.Obj[o25p24].anim[CurPlayer ^ 1] = a2512_DOM;
|
||||
|
||||
init.Obj[oXT11p21].anim[CurPlayer] = a111_DOM;
|
||||
init.Obj[oXT11p21].anim[CurPlayer ^ 1] = a111_DOM;
|
||||
|
||||
init.Obj[oXT1Ap22].anim[CurPlayer] = a1A4_DOM;
|
||||
init.Obj[oXT1Ap22].anim[CurPlayer ^ 1] = a1A4_DOM;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------22/05/00 10.03-------------------
|
||||
* DecCurTime
|
||||
* --------------------------------------------------*/
|
||||
void DecCurTime(WGame &game, int32 dec) {
|
||||
int32 h, m;
|
||||
|
||||
t3dCurTime -= dec;
|
||||
h = (t3dCurTime / 100);
|
||||
m = (t3dCurTime % 100);
|
||||
|
||||
while (m < 0) {
|
||||
m += 60;
|
||||
h --;
|
||||
}
|
||||
|
||||
t3dCurTime = h * 100 + m;
|
||||
UpdateAllClocks(game);
|
||||
}
|
||||
|
||||
/* -----------------29/05/00 15.40-------------------
|
||||
* SetCurTime
|
||||
* --------------------------------------------------*/
|
||||
void SetCurTime(WGame &game, int32 set) {
|
||||
t3dCurTime = set;
|
||||
UpdateAllClocks(game);
|
||||
}
|
||||
|
||||
/* -----------------02/06/00 10.10-------------------
|
||||
* WhichRoomChar
|
||||
* --------------------------------------------------*/
|
||||
int32 WhichRoomChar(Init &init, int32 ch) {
|
||||
struct SDiary *d;
|
||||
int32 i;
|
||||
|
||||
for (i = 0, d = &init.Diary[0]; i < MAX_DIARIES; i++, d++) {
|
||||
if ((d->obj != ch) || (t3dCurTime < d->startt) || (d->endt && (t3dCurTime >= d->endt))) continue;
|
||||
return d->room;
|
||||
}
|
||||
return rNULL;
|
||||
}
|
||||
|
||||
/* -----------------02/06/00 10.26-------------------
|
||||
* WhichAnimChar
|
||||
* --------------------------------------------------*/
|
||||
int32 WhichAnimChar(Init &init, int32 ch) {
|
||||
struct SDiary *d;
|
||||
int32 i;
|
||||
|
||||
for (i = 0, d = &init.Diary[0]; i < MAX_DIARIES; i++, d++) {
|
||||
if ((d->obj != ch) || (t3dCurTime < d->startt) || (d->endt && (t3dCurTime >= d->endt))) continue;
|
||||
if (!d->item[d->cur].on) continue;
|
||||
return d->item[d->cur].anim[d->item[d->cur].cur];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------02/06/00 10.26-------------------
|
||||
* WhichPosChar
|
||||
* --------------------------------------------------*/
|
||||
uint8 WhichPosChar(Init &init, int32 ch) {
|
||||
struct SDiary *d;
|
||||
int32 i;
|
||||
|
||||
for (i = 0, d = &init.Diary[0]; i < MAX_DIARIES; i++, d++) {
|
||||
if ((d->obj != ch) || (t3dCurTime < d->startt) || (d->endt && (t3dCurTime >= d->endt))) continue;
|
||||
if (!d->item[d->cur].on) continue;
|
||||
return init.Anim[d->item[d->cur].anim[d->item[d->cur].cur]].pos;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
43
engines/watchmaker/ll/ll_diary.h
Normal file
43
engines/watchmaker/ll/ll_diary.h
Normal 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_LL_DIARY_H
|
||||
#define WATCHMAKER_LL_DIARY_H
|
||||
|
||||
#include "watchmaker/work_dirs.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
#include "watchmaker/game.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
void UpdateAllClocks(WGame &game);
|
||||
void StopDiary(WGame &game, int32 room, int32 obj, uint8 only_overtime);
|
||||
void StartDiary(WGame &game, int32 room, t3dV3F *pos);
|
||||
void IncCurTime(WGame &game, int32 inc);
|
||||
void DecCurTime(WGame &game, int32 dec);
|
||||
void SetCurTime(WGame &game, int32 set);
|
||||
int32 WhichRoomChar(Init &init, int32 ch);
|
||||
int32 WhichAnimChar(Init &init, int32 ch);
|
||||
void ContinueDiary(WGame &game, int32 an);
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_DIARY_H
|
||||
92
engines/watchmaker/ll/ll_ffile.cpp
Normal file
92
engines/watchmaker/ll/ll_ffile.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 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/ll/ll_ffile.h"
|
||||
#include "common/substream.h"
|
||||
#include "watchmaker/ll/ll_system.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
const int MAX_NAME_LEN = 52;
|
||||
|
||||
struct FileEntry {
|
||||
Common::String name;
|
||||
int32 offset;
|
||||
int32 time;
|
||||
int32 date;
|
||||
};
|
||||
|
||||
FastFile::FastFile(const char *path) : _path(path) {
|
||||
auto stream = openFile(path);
|
||||
assert(stream);
|
||||
|
||||
_numFiles = stream->readUint32LE();
|
||||
_files = new FileEntry[_numFiles] {};
|
||||
_totalSize = stream->size();
|
||||
|
||||
for (int i = 0; i < _numFiles; i++) {
|
||||
char name[MAX_NAME_LEN] = {};
|
||||
stream->read(name, MAX_NAME_LEN);
|
||||
_files[i].name = name;
|
||||
_files[i].offset = stream->readUint32LE();
|
||||
_files[i].time = stream->readUint32LE();
|
||||
_files[i].date = stream->readUint32LE();
|
||||
for (auto it = _files[i].name.begin(); it != _files[i].name.end(); ++it) {
|
||||
if (*it == '\\') {
|
||||
*it = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FastFile::~FastFile() {
|
||||
delete[] _files;
|
||||
}
|
||||
|
||||
Common::SharedPtr<Common::SeekableReadStream> FastFile::resolve(const char *filename) {
|
||||
Common::String converted = filename;
|
||||
int index = -1;
|
||||
//HACK
|
||||
if (converted.size() >= 2 && converted[0] == '.' && converted[1] == '/') {
|
||||
converted = converted.substr(2, converted.size() - 2);
|
||||
}
|
||||
for (int i = 0; i < _numFiles; i++) {
|
||||
if (_files[i].name.equalsIgnoreCase(converted)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto &entry = _files[index];
|
||||
int size = 0;
|
||||
if (index == _numFiles - 1) {
|
||||
size = _totalSize - entry.offset;
|
||||
} else {
|
||||
size = _files[index + 1].offset - entry.offset;
|
||||
}
|
||||
auto stream = openFile(_path, entry.offset, size);
|
||||
assert(stream);
|
||||
return Common::SharedPtr<Common::SeekableReadStream>(stream);
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
47
engines/watchmaker/ll/ll_ffile.h
Normal file
47
engines/watchmaker/ll/ll_ffile.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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_LL_FFILE_H
|
||||
#define WATCHMAKER_LL_FFILE_H
|
||||
|
||||
#include "common/ptr.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
struct FileEntry;
|
||||
class FastFile {
|
||||
const char *_path = nullptr;
|
||||
int _totalSize = 0;
|
||||
public:
|
||||
int _numFiles = 0;
|
||||
FileEntry *_files = nullptr; // TODO: This could just be a Common::Array
|
||||
|
||||
FastFile(const char *path);
|
||||
~FastFile();
|
||||
|
||||
Common::SharedPtr<Common::SeekableReadStream> resolve(const char *filename);
|
||||
};
|
||||
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_FFILE_H
|
||||
881
engines/watchmaker/ll/ll_mesh.cpp
Normal file
881
engines/watchmaker/ll/ll_mesh.cpp
Normal file
@@ -0,0 +1,881 @@
|
||||
/* 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/ll/ll_mesh.h"
|
||||
#include "watchmaker/types.h"
|
||||
#include "watchmaker/t3d.h"
|
||||
#include "watchmaker/3d/math/llmath.h"
|
||||
#include "watchmaker/3d/geometry.h"
|
||||
#include "watchmaker/windows_hacks.h"
|
||||
#include "watchmaker/define.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
#include "watchmaker/ll/ll_util.h"
|
||||
#include "watchmaker/3d/animation.h"
|
||||
#include "watchmaker/utils.h"
|
||||
#include "watchmaker/ll/ll_mouse.h"
|
||||
#include "watchmaker/walk/walkutil.h"
|
||||
#include "watchmaker/walk/walk.h"
|
||||
#include "watchmaker/ll/ll_system.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
// locals
|
||||
struct t3dHEADMOVE {
|
||||
t3dV3F OldPos, DestAng, CurAng;
|
||||
};
|
||||
|
||||
t3dHEADMOVE HeadMove[T3D_MAX_CHARACTERS];
|
||||
|
||||
t3dF32 OldArrowLen, OldExplosionScale;
|
||||
uint32 **SavedBodyLight;
|
||||
uint8 LastLightChar, LastLightRoom;
|
||||
/* -----------------14/04/99 18.24-------------------
|
||||
* t3dUpdateArrow
|
||||
* --------------------------------------------------*/
|
||||
void t3dUpdateArrow(t3dMESH *m, t3dF32 len) {
|
||||
uint32 i;
|
||||
|
||||
if (!m) return;
|
||||
|
||||
m->VBptr = m->VertexBuffer;
|
||||
for (i = 0; i < m->NumVerts; i++)
|
||||
if (fabs(m->VBptr[i].z) > 1.0f)
|
||||
m->VBptr[i].z += (-len + OldArrowLen);
|
||||
m->Flags |= T3D_MESH_UPDATEVB;
|
||||
m->VBptr = nullptr;
|
||||
|
||||
OldArrowLen = len;
|
||||
}
|
||||
|
||||
/* -----------------27/04/99 10.52-------------------
|
||||
* t3dLightRoom
|
||||
* --------------------------------------------------*/
|
||||
void t3dLightRoom(Init &init, t3dBODY *b, t3dV3F *p, t3dF32 NearRange, t3dF32 FarRange, t3dF32 IperRange) {
|
||||
uint32 i, j, k, rr, gg, bb, aa, cr, cb, cg, *sbl;
|
||||
uint32 addr = 110;
|
||||
uint32 addg = 95;
|
||||
uint32 addb = 80;
|
||||
t3dMESH *m;
|
||||
t3dF32 dist;
|
||||
t3dV3F tmp;
|
||||
gVertex *gv;
|
||||
|
||||
if (!b || !p) return;
|
||||
|
||||
FarRange *= FarRange;
|
||||
NearRange *= NearRange;
|
||||
IperRange *= IperRange;
|
||||
|
||||
if (!SavedBodyLight) {
|
||||
if (!(SavedBodyLight = (uint32 **)t3dMalloc(sizeof(uint32 *) * b->NumMeshes())))
|
||||
return ;
|
||||
m = &b->MeshTable[0];
|
||||
for (j = 0; j < b->NumMeshes(); j++, m++) {
|
||||
if (!m) continue;
|
||||
if (!(SavedBodyLight[j] = (uint32 *)t3dMalloc(sizeof(uint32) * m->NumVerts * 4)))
|
||||
continue;
|
||||
|
||||
gv = m->VBptr;
|
||||
m->VBptr = m->VertexBuffer;
|
||||
for (i = 0; i < m->NumVerts; i++, gv++) {
|
||||
SavedBodyLight[j][i * 4 + 0] = RGBA_GETRED(gv->diffuse);
|
||||
SavedBodyLight[j][i * 4 + 1] = RGBA_GETGREEN(gv->diffuse);
|
||||
SavedBodyLight[j][i * 4 + 2] = RGBA_GETBLUE(gv->diffuse);
|
||||
SavedBodyLight[j][i * 4 + 3] = RGBA_GETALPHA(gv->diffuse);
|
||||
}
|
||||
m->VBptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
LastLightRoom = (LastLightRoom + 1) > 3 ? 0 : LastLightRoom + 1;
|
||||
m = &b->MeshTable[0];
|
||||
for (j = 0; j < b->NumMeshes(); j++, m++) {
|
||||
if (!m) continue;
|
||||
if (m->name.equalsIgnoreCase("p50-cielo") || m->name.equalsIgnoreCase("p50-stelle") || m->name.equalsIgnoreCase("p50-luna")) continue;
|
||||
if (!(m->Flags & T3D_MESH_VISIBLE) && !(m->Flags & T3D_MESH_HIDDEN)) {
|
||||
m->Flags &= ~T3D_MESH_HIDDEN;
|
||||
continue;
|
||||
}
|
||||
m->Flags &= ~T3D_MESH_HIDDEN;
|
||||
// if( (j%4) != LastLightRoom ) continue;
|
||||
|
||||
sbl = (uint32 *)&SavedBodyLight[j][0];
|
||||
for (k = 0; k < MAX_OBJ_MESHLINKS ; k++) {
|
||||
if (((!init.Obj[oNEXTPORTAL].meshLinkIsEmpty(k)) && (m->name.equalsIgnoreCase(init.Obj[oNEXTPORTAL].getMeshLink(k)))) ||
|
||||
m->name.equalsIgnoreCase("p50-sentierini01") || m->name.equalsIgnoreCase("p50-sentierini02") || m->name.equalsIgnoreCase("p50-sentierini03") ||
|
||||
m->name.equalsIgnoreCase("p50-sentierini04") || m->name.equalsIgnoreCase("p50-sentierini05") || m->name.equalsIgnoreCase("p50-sentierini06")) {
|
||||
tmp.x = m->Pos.x - p->x;
|
||||
tmp.z = m->Pos.z - p->z;
|
||||
gv = m->VBptr;
|
||||
m->VBptr = m->VertexBuffer;
|
||||
if ((dist = tmp.x * tmp.x + tmp.z * tmp.z) > (FarRange + m->Radius * m->Radius * 1.3f)) {
|
||||
if ((bGolfMode == 0) || (bGolfMode == 1))
|
||||
if (dist > (FarRange + m->Radius * m->Radius) * 2.5f) m->Flags |= T3D_MESH_HIDDEN;
|
||||
for (i = 0; i < m->NumVerts; i++, gv++) {
|
||||
rr = *sbl++;
|
||||
gg = *sbl++;
|
||||
bb = *sbl++;
|
||||
aa = *sbl++;
|
||||
gv->diffuse = RGBA_MAKE(rr, gg, bb, aa);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < m->NumVerts; i++, gv++) {
|
||||
tmp.x = gv->x - p->x;
|
||||
tmp.z = gv->z - p->z;
|
||||
if ((dist = tmp.x * tmp.x + tmp.z * tmp.z) < IperRange) {
|
||||
rr = *sbl++ + addr * 2;
|
||||
gg = *sbl++ + addg * 2;
|
||||
bb = *sbl++ + addb * 2;
|
||||
} else if (dist < NearRange) {
|
||||
rr = *sbl++ + addr;
|
||||
gg = *sbl++ + addg;
|
||||
bb = *sbl++ + addb;
|
||||
} else if (dist < FarRange) {
|
||||
dist = 1.0f - (dist - NearRange) / (FarRange - NearRange);
|
||||
rr = *sbl++ + (uint32)((t3dF32)(addr) * dist);
|
||||
gg = *sbl++ + (uint32)((t3dF32)(addg) * dist);
|
||||
bb = *sbl++ + (uint32)((t3dF32)(addb) * dist);
|
||||
} else {
|
||||
rr = *sbl++;
|
||||
gg = *sbl++;
|
||||
bb = *sbl++;
|
||||
}
|
||||
aa = *sbl++;
|
||||
if (rr > 255) rr = 255;
|
||||
if (gg > 255) gg = 255;
|
||||
if (bb > 255) bb = 255;
|
||||
gv->diffuse = RGBA_MAKE(rr, gg, bb, aa);
|
||||
}
|
||||
}
|
||||
m->Flags |= T3D_MESH_UPDATEVB;
|
||||
m->VBptr = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k < MAX_OBJ_MESHLINKS) continue;
|
||||
|
||||
tmp.x = m->Pos.x - p->x + m->Trasl.x;
|
||||
tmp.z = m->Pos.z - p->z + m->Trasl.z;
|
||||
if ((dist = tmp.x * tmp.x + tmp.z * tmp.z) < IperRange) {
|
||||
cr = addr * 2;
|
||||
cg = addg * 2;
|
||||
cb = addb * 2;
|
||||
} else if (dist < NearRange) {
|
||||
cr = addr;
|
||||
cg = addg;
|
||||
cb = addb;
|
||||
} else if (dist < FarRange) {
|
||||
dist = 1.0f - (dist - NearRange) / (FarRange - NearRange);
|
||||
cr = (uint32)((t3dF32)(addr) * dist);
|
||||
cg = (uint32)((t3dF32)(addg) * dist);
|
||||
cb = (uint32)((t3dF32)(addb) * dist);
|
||||
} else {
|
||||
if ((bGolfMode == 0) || (bGolfMode == 1))
|
||||
if (dist > (FarRange + m->Radius * m->Radius) * 2.5f) m->Flags |= T3D_MESH_HIDDEN;
|
||||
cr = 0;
|
||||
cg = 0;
|
||||
cb = 0;
|
||||
}
|
||||
gv = m->VBptr;
|
||||
m->VBptr = m->VertexBuffer;
|
||||
for (i = 0; i < m->NumVerts; i++, gv++) {
|
||||
rr = cr + *sbl++;
|
||||
gg = cg + *sbl++;
|
||||
bb = cb + *sbl++;
|
||||
aa = *sbl++;
|
||||
if (rr > 255) rr = 255;
|
||||
if (gg > 255) gg = 255;
|
||||
if (bb > 255) bb = 255;
|
||||
gv->diffuse = RGBA_MAKE(rr, gg, bb, aa);
|
||||
}
|
||||
m->Flags |= T3D_MESH_UPDATEVB;
|
||||
m->VBptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -----------------27/04/99 15.35-------------------
|
||||
* t3dLightChar
|
||||
* --------------------------------------------------*/
|
||||
void t3dLightChar(t3dMESH *mesh, t3dV3F *p) {
|
||||
#if 0
|
||||
int16 df;
|
||||
uint32 j, rr, gg, bb, cr, cb, cg;
|
||||
t3dF32 addr = 110 + 60;
|
||||
t3dF32 addg = 95 + 75;
|
||||
t3dF32 addb = 80 + 90;
|
||||
t3dF32 nlight;
|
||||
t3dV3F ppos, l, *normal;
|
||||
gVertex *gv;
|
||||
|
||||
if (!mesh || !p) return;
|
||||
|
||||
t3dVectAdd(&ppos, &mesh->Trasl, &mesh->Pos);
|
||||
gv = mesh->VBptr = mesh->VertexBuffer;
|
||||
|
||||
cr = (t3dU32)t3dCurRoom->AmbientLight.x + 20;
|
||||
cg = (t3dU32)t3dCurRoom->AmbientLight.y + 20;
|
||||
cb = (t3dU32)t3dCurRoom->AmbientLight.z + 20;
|
||||
df = RGBA_MAKE(cr, cg, cb, 255);
|
||||
for (j = 0; j < mesh->NumVerts; j++, gv++)
|
||||
gv->diffuse = df;
|
||||
|
||||
t3dVectSub(&l, p, &ppos);
|
||||
t3dVectTransformInv(&l, &l, &mesh->Matrix);
|
||||
t3dVectNormalize(&l);
|
||||
|
||||
gv = mesh->VBptr;
|
||||
for (j = 0; j < mesh->NumVerts; j++, gv++) {
|
||||
normal = &mesh->NList[j]->n;
|
||||
|
||||
nlight = t3dVectDot(normal, &l);
|
||||
// if( (nlight=t3dVectDot(normal,&l)) >= 0 )
|
||||
{
|
||||
rr = cr + t3dFloatToInt((addr * nlight));
|
||||
gg = cg + t3dFloatToInt((addg * nlight));
|
||||
bb = cb + t3dFloatToInt((addb * nlight));
|
||||
|
||||
if (rr > 255) rr = 255;
|
||||
if (gg > 255) gg = 255;
|
||||
if (bb > 255) bb = 255;
|
||||
|
||||
gv->diffuse = RGBA_MAKE(rr, gg, bb, 255);
|
||||
}
|
||||
}
|
||||
mesh->Flags |= T3D_MESH_UPDATEVB;
|
||||
mesh->VBptr = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* -----------------12/04/99 12.11-------------------
|
||||
* t3dVectMeshInters
|
||||
* --------------------------------------------------*/
|
||||
uint8 t3dVectMeshInters(t3dMESH *m, t3dV3F start, t3dV3F end, t3dV3F *inters) {
|
||||
t3dV3F v1, v2, v3;
|
||||
|
||||
if (!m) return 0;
|
||||
if (!t3dVectPlaneIntersection(inters, start, end, m->BBoxNormal[3])) return 0;
|
||||
|
||||
m->VBptr = m->VertexBuffer;
|
||||
for (uint32 j = 0; j < m->NumFaces(); j++) {
|
||||
t3dFACE &f = m->FList[j];
|
||||
if (!f.n) continue;
|
||||
|
||||
v1.x = m->VBptr[f.VertexIndex[0]].x;
|
||||
v1.y = m->VBptr[f.VertexIndex[0]].y;
|
||||
v1.z = m->VBptr[f.VertexIndex[0]].z;
|
||||
v2.x = m->VBptr[f.VertexIndex[1]].x;
|
||||
v2.y = m->VBptr[f.VertexIndex[1]].y;
|
||||
v2.z = m->VBptr[f.VertexIndex[1]].z;
|
||||
v3.x = m->VBptr[f.VertexIndex[2]].x;
|
||||
v3.y = m->VBptr[f.VertexIndex[2]].y;
|
||||
v3.z = m->VBptr[f.VertexIndex[2]].z;
|
||||
|
||||
if (t3dVectTriangleIntersection(inters, start, end, v1, v2, v3, *f.n)) {
|
||||
m->VBptr = nullptr;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
m->VBptr = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------19/05/00 12.43-------------------
|
||||
* t3dMoveAndCheck1stCamera
|
||||
* --------------------------------------------------*/
|
||||
bool t3dMoveAndCheck1stCamera(t3dBODY *rr, t3dCAMERA *cc, t3dV3F *mm) {
|
||||
t3dWALK *w;
|
||||
t3dV3F tmp;
|
||||
int32 i, j;
|
||||
|
||||
if (!Character[ocCURPLAYER]) return FALSE;
|
||||
w = &Character[ocCURPLAYER]->Walk;
|
||||
|
||||
t3dVectAdd(&tmp, &cc->Source, mm);
|
||||
// Controlla che non sia dentro un Bounding Box
|
||||
for (i = 0; i < (int32)rr->NumMeshes(); i++) {
|
||||
t3dMESH &mesh = rr->MeshTable[i];
|
||||
if (!(mesh.Flags & T3D_MESH_HIDDEN)) {
|
||||
// Se il punto di destinazione e' dentro il bound box (allargato dell'altezza del ginocchio)
|
||||
for (j = 0; j < 6; j++)
|
||||
if (t3dVectPlaneDistance(tmp, mesh.BBoxNormal[j]) < -KNEE_HEIGHT)
|
||||
break;
|
||||
|
||||
if (j >= 6) {
|
||||
// Prima controlla che non sia dentro i bounds
|
||||
for (j = 0; j < w->PanelNum; j++) {
|
||||
if (PointInside(ocCURPLAYER, j, (double)tmp.x, (double)tmp.z) != 0) {
|
||||
warning("Inters %s", mesh.name.c_str()); // TODO: Debug
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
warning("Saved by bounds"); // TODO: Debug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// evito che si entri nell'altro personaggio giocante
|
||||
i = (CurPlayer ^ 1);
|
||||
if (Character[i + ocDARRELL] && Character[i + ocDARRELL]->Mesh && t3dCurRoom->name.equalsIgnoreCase(PlayerStand[i].roomName)) { // Used to be stricmp
|
||||
t3dF32 d = t3dVectDistance(&tmp, &Character[i + ocDARRELL]->Mesh->Trasl);
|
||||
if (d < 435.f) return FALSE;
|
||||
}
|
||||
|
||||
t3dVectAdd(&cc->Source, &cc->Source, mm);
|
||||
t3dVectAdd(&cc->Target, &cc->Target, mm);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* -----------------03/05/99 15.24-------------------
|
||||
* t3dClipToSurface
|
||||
* --------------------------------------------------*/
|
||||
uint8 t3dClipToSurface(Init &init, t3dV3F *pt) {
|
||||
t3dV3F tmp, start, end;
|
||||
int32 i;
|
||||
t3dMESH *m;
|
||||
|
||||
t3dVectCopy(&start, pt);
|
||||
start.y = 260000.0f;
|
||||
t3dVectCopy(&end, pt);
|
||||
end.y = -130000.0f;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if ((m = LinkMeshToStr(init, init.Obj[oNEXTPORTAL].getMeshLink(i))) && (t3dVectMeshInters(m, start, end, &tmp))) {
|
||||
pt->y = tmp.y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -----------------03/05/99 16.44-------------------
|
||||
* t3dUpdateExplosion
|
||||
* --------------------------------------------------*/
|
||||
void t3dUpdateExplosion(t3dMESH *m, t3dF32 scale) {
|
||||
// t3dU32 i;
|
||||
|
||||
if (!m) return;
|
||||
|
||||
m->Matrix.M[0] = scale;
|
||||
m->Matrix.M[4] = scale;
|
||||
m->Matrix.M[8] = scale;
|
||||
|
||||
/* m->VBptr=m->VertexBuffer;
|
||||
for (i=0; i<m->NumVerts; i++ )
|
||||
{
|
||||
m->VBptr[i].x *= (scale/OldExplosionScale);
|
||||
m->VBptr[i].y *= (scale/OldExplosionScale);
|
||||
m->VBptr[i].z *= (scale/OldExplosionScale);
|
||||
}
|
||||
m->Flags |= T3D_MESH_UPDATEVB;
|
||||
m->VBptr = NULL;
|
||||
*/
|
||||
OldExplosionScale = scale;
|
||||
}
|
||||
|
||||
/* -----------------03/09/98 17.42-------------------
|
||||
* UpdateBoundingBox
|
||||
* --------------------------------------------------*/
|
||||
void UpdateBoundingBox(t3dMESH *mesh) {
|
||||
t3dBONEANIM *db;
|
||||
t3dBONE *bone;
|
||||
t3dV3F Appov;
|
||||
int32 i, frame;
|
||||
|
||||
if (!mesh || (mesh->Flags & T3D_MESH_NOBOUNDBOX))return;
|
||||
|
||||
// DebugFile("Update Bounding Box %s",mesh->Name);
|
||||
|
||||
if (mesh->Flags & T3D_MESH_DEFAULTANIM)
|
||||
db = &mesh->DefaultAnim;
|
||||
else
|
||||
db = &mesh->Anim;
|
||||
|
||||
frame = mesh->CurFrame;
|
||||
bone = db->BoneTable;
|
||||
for (i = 0; i < db->NumBones; i++, bone++) {
|
||||
if (!bone || !bone->Trasl || !bone->Matrix || (bone->ModVertices.size() > mesh->NumVerts)) continue;
|
||||
if ((!bone->ModVertices.empty()) && !(mesh->Flags & T3D_MESH_CHARACTER)) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
t3dVectSub(&Appov, &mesh->BBox[i].p, &bone->Trasl[1]);
|
||||
t3dVectTransform(&Appov, &Appov, &bone->Matrix[1]);
|
||||
t3dVectTransformInv(&Appov, &Appov, &bone->Matrix[frame]);
|
||||
t3dVectAdd(&mesh->BBox[i].p, &Appov, &bone->Trasl[frame]);
|
||||
}
|
||||
|
||||
t3dPlaneNormal(&mesh->BBoxNormal[0], &mesh->BBox[0].p, &mesh->BBox[2].p, &mesh->BBox[1].p); //front
|
||||
t3dPlaneNormal(&mesh->BBoxNormal[1], &mesh->BBox[4].p, &mesh->BBox[5].p, &mesh->BBox[6].p); //back
|
||||
t3dPlaneNormal(&mesh->BBoxNormal[2], &mesh->BBox[4].p, &mesh->BBox[0].p, &mesh->BBox[5].p); //Up
|
||||
t3dPlaneNormal(&mesh->BBoxNormal[3], &mesh->BBox[6].p, &mesh->BBox[7].p, &mesh->BBox[2].p); //Down
|
||||
t3dPlaneNormal(&mesh->BBoxNormal[4], &mesh->BBox[4].p, &mesh->BBox[6].p, &mesh->BBox[0].p); //Left
|
||||
t3dPlaneNormal(&mesh->BBoxNormal[5], &mesh->BBox[5].p, &mesh->BBox[1].p, &mesh->BBox[7].p); //Right
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------08/06/00 14.51-------------------
|
||||
* t3dSetSpecialAnimFrame
|
||||
* --------------------------------------------------*/
|
||||
bool t3dSetSpecialAnimFrame(WGame &game, const char *name, t3dMESH *mesh, int32 nf) {
|
||||
if (!name || !mesh)
|
||||
return false;
|
||||
|
||||
if (t3dLoadAnimation(game, name, mesh, T3D_MESH_DEFAULTANIM) <= 0)
|
||||
return false;
|
||||
|
||||
mesh->Flags |= (T3D_MESH_ABS_ANIM | T3D_MESH_DEFAULTANIM);
|
||||
FixupAnim(mesh, 0, "");
|
||||
|
||||
if (nf < 0) nf = mesh->DefaultAnim.NumFrames - 1;
|
||||
|
||||
mesh->CurFrame = nf;
|
||||
mesh->LastFrame = -1;
|
||||
mesh->BlendPercent = 255;
|
||||
mesh->LastBlendPercent = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MeshModifiers::modifyMesh(WGame &game, t3dMESH *mesh) {
|
||||
struct SMeshModifier *mm;
|
||||
int16 i;
|
||||
|
||||
if (!mesh || (mesh->Flags & T3D_MESH_CHARACTER))
|
||||
return;
|
||||
|
||||
// Check if there is a modifier for this mesh
|
||||
mm = &MMList[0];
|
||||
for (i = 0; i < MAX_MODIFIED_MESH; i++, mm++)
|
||||
if ((!mm->meshName.empty()) && (mm->meshName.equalsIgnoreCase(mesh->name)))
|
||||
break;
|
||||
|
||||
// If there are no modifiers for this mesh or they refer to a body
|
||||
if ((i >= MAX_MODIFIED_MESH) || (mm->getFlags() & (MM_SET_BND_LEVEL | MM_SET_HALOES)))
|
||||
return;
|
||||
|
||||
mm->modifyMesh(game, mesh);
|
||||
}
|
||||
|
||||
void SMeshModifier::modifyMesh(WGame &game, t3dMESH *mesh) {
|
||||
warning("MM %s: addflags %X, removeflags %X, anim |%s|", mesh->name.c_str(), this->AddFlags, this->RemoveFlags, this->animName.c_str());
|
||||
// Update Flags
|
||||
if (this->Flags & MM_REMOVE_FLAGS)
|
||||
mesh->Flags &= ~this->RemoveFlags;
|
||||
if (this->Flags & MM_ADD_FLAGS)
|
||||
mesh->Flags |= this->AddFlags;
|
||||
|
||||
// Update Materials
|
||||
if (this->Flags & MM_REMOVE_MAT_FLAGS)
|
||||
mesh->FList[0].getMaterial()->Flags &= ~this->RemoveMatFlags;
|
||||
if (this->Flags & MM_ADD_MAT_FLAGS)
|
||||
mesh->FList[0].getMaterial()->Flags |= this->AddMatFlags;
|
||||
if (this->Flags & MM_SET_MAT_FRAME)
|
||||
mesh->setMovieFrame(this->MatFrame); // This did NOT check for existing face/material before setting before.
|
||||
|
||||
// Update Anim
|
||||
if ((this->Flags & MM_ANIM_BLOCK) && (!this->animName.empty()) && (!mesh->CurFrame)) {
|
||||
t3dSetSpecialAnimFrame(game, this->animName.c_str(), mesh, -1);
|
||||
t3dCalcMeshBones(mesh, 1);
|
||||
UpdateBoundingBox(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------15/09/98 12.04-------------------
|
||||
* AddMeshModifier
|
||||
* --------------------------------------------------*/
|
||||
void MeshModifiers::addMeshModifier(const Common::String &name, int16 com, void *p) {
|
||||
struct SMeshModifier *mm;
|
||||
int16 i;
|
||||
|
||||
warning("Not sure this is right"); // Used to check for nullptr, not 0 length.
|
||||
if (name.empty() || !p)
|
||||
return;
|
||||
|
||||
// DebugLogFile("AddMM |%s| %d",name,com);
|
||||
|
||||
// Check if a modifier already exists for this mesh
|
||||
mm = &MMList[0];
|
||||
for (i = 0; i < MAX_MODIFIED_MESH; i++, mm++)
|
||||
if ((!mm->meshName.empty()) && mm->meshName.equalsIgnoreCase(name))
|
||||
break;
|
||||
|
||||
// If it's a new modifier look for a free place
|
||||
if (i >= MAX_MODIFIED_MESH) {
|
||||
mm = &MMList[0];
|
||||
for (i = 0; i < MAX_MODIFIED_MESH; i++, mm++)
|
||||
if (mm->meshName.empty())
|
||||
break;
|
||||
if (i >= MAX_MODIFIED_MESH) {
|
||||
warning("Troppi Mesh modifier per %s: MAX %d", name.c_str(), MAX_MODIFIED_MESH);
|
||||
return;
|
||||
}
|
||||
|
||||
*mm = SMeshModifier(name.c_str(), com, p);
|
||||
} else {
|
||||
mm->configure(name.c_str(), com, p);
|
||||
}
|
||||
}
|
||||
|
||||
SMeshModifier::SMeshModifier(Common::SeekableReadStream &stream) {
|
||||
char stringBuffer[T3D_NAMELEN] = {};
|
||||
stream.read(stringBuffer, T3D_NAMELEN);
|
||||
meshName = stringBuffer;
|
||||
Flags = stream.readSint32LE();
|
||||
AddFlags = stream.readUint32LE();
|
||||
RemoveFlags = stream.readUint32LE();
|
||||
AddMatFlags = stream.readUint32LE();
|
||||
RemoveMatFlags = stream.readUint32LE();
|
||||
MatFrame = stream.readSint32LE();
|
||||
BndLevel = stream.readUint16LE();
|
||||
HaloesStatus = stream.readByte(); // TODO: Signed.
|
||||
stream.read(stringBuffer, T3D_NAMELEN);
|
||||
animName = stringBuffer;
|
||||
}
|
||||
|
||||
SMeshModifier::SMeshModifier(const char *name, int16 com, void *p) {
|
||||
configure(name, com, p);
|
||||
}
|
||||
|
||||
void SMeshModifier::configure(const char *name, int16 com, void *p) {
|
||||
this->Flags |= com;
|
||||
switch (com) {
|
||||
case MM_ADD_FLAGS:
|
||||
Flags = *((uint32 *)p);
|
||||
this->RemoveFlags &= ~Flags;
|
||||
this->AddFlags |= Flags;
|
||||
break;
|
||||
|
||||
case MM_REMOVE_FLAGS:
|
||||
Flags = *((uint32 *)p);
|
||||
this->AddFlags &= ~Flags;
|
||||
this->RemoveFlags |= Flags;
|
||||
break;
|
||||
|
||||
case MM_ADD_MAT_FLAGS:
|
||||
Flags = *((uint32 *)p);
|
||||
this->RemoveMatFlags &= ~Flags;
|
||||
this->AddMatFlags |= Flags;
|
||||
break;
|
||||
|
||||
case MM_REMOVE_MAT_FLAGS:
|
||||
Flags = *((uint32 *)p);
|
||||
this->AddMatFlags &= ~Flags;
|
||||
this->RemoveMatFlags |= Flags;
|
||||
break;
|
||||
|
||||
case MM_SET_MAT_FRAME:
|
||||
this->MatFrame = *((int32 *)p);
|
||||
break;
|
||||
|
||||
case MM_ANIM_BLOCK:
|
||||
if (this->animName.empty())
|
||||
this->animName = (char *)p;
|
||||
else
|
||||
this->animName.clear();
|
||||
break;
|
||||
|
||||
case MM_SET_BND_LEVEL:
|
||||
this->BndLevel = *((uint16 *)p);
|
||||
break;
|
||||
|
||||
case MM_SET_HALOES:
|
||||
this->HaloesStatus = *((int8 *)p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MeshModifiers::applyAllMeshModifiers(WGame &game, t3dBODY *b) {
|
||||
// Check if there is a modifier for this body
|
||||
struct SMeshModifier *mm = &MMList[0];
|
||||
for (int32 j = 0; j < MAX_MODIFIED_MESH; j++, mm++)
|
||||
if ((!mm->meshName.empty()) && b->name.equalsIgnoreCase(mm->meshName)) {
|
||||
if (mm->getFlags() & MM_SET_BND_LEVEL)
|
||||
b->CurLevel = mm->getBndLevel();
|
||||
|
||||
if (mm->getFlags() & MM_SET_HALOES) {
|
||||
for (auto &l : b->LightTable) {
|
||||
if (!(l.Type & T3D_LIGHT_FLARE)) continue;
|
||||
|
||||
if (mm->getHaloesStatus() > 0)
|
||||
l.Type |= T3D_LIGHT_LIGHTON;
|
||||
else
|
||||
l.Type &= ~T3D_LIGHT_LIGHTON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < (int32)b->NumMeshes(); i++) {
|
||||
modifyMesh(game, &b->MeshTable[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------29/03/99 14.33-------------------
|
||||
* HideRoomMeshes
|
||||
* --------------------------------------------------*/
|
||||
void HideRoomMeshes(Init &init, t3dBODY *body) {
|
||||
int32 cr, c, a, b, i, j, k, h, skip;
|
||||
t3dMESH *m;
|
||||
|
||||
if (!(cr = getRoomFromStr(init, body->name))) return;
|
||||
// DebugFile("Hiding Room %s (%d)",body->Name,cr);
|
||||
for (a = 0; a < MAX_OBJS_IN_ROOM; a++) {
|
||||
if (!(c = init.Room[cr].objects[a])) continue;
|
||||
if (init.Obj[c].flags & NOUPDATE) continue;
|
||||
if (!(init.Obj[c].flags & ON) || (init.Obj[c].flags & HIDE)) {
|
||||
for (b = 0; b < MAX_OBJ_MESHLINKS; b++) {
|
||||
if (init.Obj[c].meshLinkIsEmpty(b)) continue;
|
||||
m = nullptr;
|
||||
const Common::String &str = init.Obj[c].getMeshLink(b);
|
||||
for (h = 0; h < (uint16)body->NumMeshes(); h++) {
|
||||
if (body->MeshTable[h].name.equalsIgnoreCase(str)) {
|
||||
m = &body->MeshTable[h];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m == nullptr) continue;
|
||||
// DebugFile("CandidateObj '%s'",Obj[c].meshlink[b]);
|
||||
|
||||
skip = 0;
|
||||
for (i = 0; i < MAX_OBJS_IN_ROOM; i++) {
|
||||
if (!(k = init.Room[cr].objects[i]) || (k == c)) continue;
|
||||
if (!(init.Obj[k].flags & ON) || (init.Obj[k].flags & HIDE)) continue;
|
||||
|
||||
for (j = 0; j < MAX_OBJ_MESHLINKS; j++) {
|
||||
if (init.Obj[k].meshLinkIsEmpty(j)) continue;
|
||||
if (!init.Obj[c].getMeshLink(b).equalsIgnoreCase(init.Obj[k].getMeshLink(j))) continue;
|
||||
|
||||
// DebugFile("Skipped for %d,%d",k,j);
|
||||
skip ++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!skip && m) {
|
||||
// DebugFile("Hiding Mesh %s",Obj[c].meshlink[b]);
|
||||
m->Flags |= T3D_MESH_HIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------28/12/98 17.43-------------------
|
||||
* UpdateCharHead
|
||||
* --------------------------------------------------*/
|
||||
void UpdateCharHead(int32 oc, t3dV3F *dir) {
|
||||
t3dCHARACTER *Ch = Character[oc];
|
||||
t3dMESH *mesh;
|
||||
t3dHEADMOVE *t;
|
||||
t3dBONE *bone;
|
||||
t3dV3F tmp;
|
||||
int32 i, cf;
|
||||
t3dF32 s;
|
||||
|
||||
if (!Ch || !(mesh = Ch->Mesh) || mHide || !dir) return;
|
||||
if ((bDialogActive) || (bT2DActive) || (InvStatus)) return;
|
||||
|
||||
if (oc == ocCURPLAYER) oc = ocDARRELL + CurPlayer;
|
||||
t = &HeadMove[oc];
|
||||
|
||||
if ((Player->Mesh->CurFrame > ActionStart[aSTAND]) || !(Player->Mesh->Flags & T3D_MESH_DEFAULTANIM))
|
||||
t3dVectFill(&t->DestAng, 0.0f);
|
||||
else if (t->OldPos != *dir) {
|
||||
t3dVectCopy(&tmp, &mesh->Trasl);
|
||||
tmp.y = CurFloorY + EYES_HEIGHT;
|
||||
t3dVectSub(&tmp, dir, &tmp);
|
||||
t->DestAng.x = t3dVectAngle(&tmp, &Ch->Dir);
|
||||
if (t->DestAng.x < -MAX_HEAD_ANGLE_X * 2) t->DestAng.x = -MAX_HEAD_ANGLE_X * 2;
|
||||
if (t->DestAng.x > MAX_HEAD_ANGLE_X * 2) t->DestAng.x = MAX_HEAD_ANGLE_X * 2;
|
||||
t->DestAng.y = -(t3dF32)asin((mPos.y - (CurFloorY + EYES_HEIGHT)) / t3dVectMod(&tmp)) * 180.0f / T3D_PI;
|
||||
if (t->DestAng.y < -MAX_HEAD_ANGLE_Y / 2) t->DestAng.y = -MAX_HEAD_ANGLE_Y / 2;
|
||||
if (t->DestAng.y > MAX_HEAD_ANGLE_Y / 2) t->DestAng.y = MAX_HEAD_ANGLE_Y / 2;
|
||||
t->DestAng.z = 0.0f;
|
||||
t3dVectCopy(&t->OldPos, dir);
|
||||
}
|
||||
|
||||
if (t->DestAng != t->CurAng) {
|
||||
Player->Mesh->LastFrame = 0;
|
||||
if (Player->Mesh->Flags & T3D_MESH_DEFAULTANIM) {
|
||||
if (Player->Mesh->CurFrame < ActionStart[aSTAND])
|
||||
Player->Mesh->CurFrame = ActionStart[aSTAND];
|
||||
cf = 1;
|
||||
for (i = 1; i < Player->Mesh->DefaultAnim.NumBones; i++) {
|
||||
if (!(bone = &Player->Mesh->DefaultAnim.BoneTable[i]) || !(bone->Trasl) || !(bone->Matrix))
|
||||
continue;
|
||||
|
||||
t3dVectCopy(&bone->Trasl[cf], &bone->Trasl[Player->Mesh->CurFrame]);
|
||||
t3dMatCopy(&bone->Matrix[cf], &bone->Matrix[Player->Mesh->CurFrame]);
|
||||
}
|
||||
bone = &Player->Mesh->DefaultAnim.BoneTable[12];
|
||||
} else {
|
||||
cf = Player->Mesh->CurFrame;
|
||||
bone = &Player->Mesh->Anim.BoneTable[12];
|
||||
}
|
||||
|
||||
if ((bone) && (bone->Trasl) && (bone->Matrix)) {
|
||||
t3dVectSub(&tmp, &t->DestAng, &t->CurAng);
|
||||
s = t3dVectMod(&tmp);
|
||||
if (s > MAX_HEAD_SPEED) {
|
||||
tmp.x *= (MAX_HEAD_SPEED / s);
|
||||
tmp.y *= (MAX_HEAD_SPEED / s);
|
||||
}
|
||||
t->CurAng.x += tmp.x;
|
||||
t->CurAng.y += tmp.y;
|
||||
t->CurAng.z = 0.0f;
|
||||
|
||||
t3dMatRot(&bone->Matrix[cf], (t->CurAng.y * T3D_PI) / 180.0f, (t->CurAng.x * T3D_PI) / 180.0f, 0.0f);
|
||||
bone->Matrix[cf].Flags &= ~T3D_MATRIX_IDENTITY;
|
||||
|
||||
// Player->Mesh->BlendPercent = 0;
|
||||
Player->Mesh->CurFrame = cf;
|
||||
}
|
||||
}
|
||||
|
||||
// se siamo in un dialogo o RTV non gli faccio muovere la testolina
|
||||
if (bDialogActive) {
|
||||
t3dVectFill(&t->CurAng, 0.0f);
|
||||
t3dVectFill(&t->DestAng, 0.0f);
|
||||
t3dVectFill(&t->OldPos, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------22/06/00 12.15-------------------
|
||||
* ChangeMeshFlags
|
||||
* --------------------------------------------------*/
|
||||
void ChangeMeshFlags(t3dMESH *m, int8 add, uint32 newflags) {
|
||||
if (!m) return;
|
||||
|
||||
if (add > 0) {
|
||||
m->Flags |= newflags;
|
||||
_vm->addMeshModifier(m->name, MM_ADD_FLAGS, &newflags);
|
||||
} else {
|
||||
m->Flags &= ~newflags;
|
||||
_vm->addMeshModifier(m->name, MM_REMOVE_FLAGS, &newflags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* -----------------29/06/00 11.22-------------------
|
||||
* ChangeHaloesStatus
|
||||
* --------------------------------------------------*/
|
||||
void ChangeHaloesStatus(t3dBODY *b, int8 op) {
|
||||
if (b == nullptr) b = t3dCurRoom;
|
||||
if (b == nullptr) return;
|
||||
|
||||
for (auto &l : b->LightTable) {
|
||||
if (!(l.Type & T3D_LIGHT_FLARE)) continue;
|
||||
|
||||
if (op > 0)
|
||||
l.Type |= T3D_LIGHT_LIGHTON;
|
||||
else
|
||||
l.Type &= ~T3D_LIGHT_LIGHTON;
|
||||
}
|
||||
_vm->addMeshModifier(b->name.c_str(), MM_SET_HALOES, &op);
|
||||
}
|
||||
|
||||
/* -----------------01/06/00 11.12-------------------
|
||||
* UpdateObjMesh
|
||||
* --------------------------------------------------*/
|
||||
void UpdateObjMesh(Init &init, int32 in) {
|
||||
t3dMESH *m;
|
||||
int32 a;
|
||||
|
||||
if (init.Obj[in].flags & NOUPDATE) return;
|
||||
|
||||
for (a = 0; a < MAX_OBJ_MESHLINKS; a++) {
|
||||
m = LinkMeshToStr(init, init.Obj[in].getMeshLink(a));
|
||||
if (m) {
|
||||
if ((init.Obj[in].flags & ON) && !(init.Obj[in].flags & HIDE))
|
||||
// m->Flags &= ~T3D_MESH_HIDDEN;
|
||||
ChangeMeshFlags(m, -1, T3D_MESH_HIDDEN);
|
||||
else
|
||||
// m->Flags |= T3D_MESH_HIDDEN;
|
||||
ChangeMeshFlags(m, +1, T3D_MESH_HIDDEN);
|
||||
} else {
|
||||
//se non la trova in memoria aggiunge solo il modifier alla lista
|
||||
uint32 newflags;
|
||||
|
||||
newflags = T3D_MESH_HIDDEN;
|
||||
if (!init.Obj[in].meshLinkIsEmpty(a)) {
|
||||
if ((init.Obj[in].flags & ON) && !(init.Obj[in].flags & HIDE))
|
||||
_vm->addMeshModifier(init.Obj[in].getMeshLink(a), MM_REMOVE_FLAGS, &newflags);
|
||||
else
|
||||
_vm->addMeshModifier(init.Obj[in].getMeshLink(a), MM_ADD_FLAGS, &newflags);
|
||||
}
|
||||
}
|
||||
}//for
|
||||
}
|
||||
|
||||
|
||||
/* -----------------22/06/00 12.15-------------------
|
||||
* SetMeshMaterialMovieFrame
|
||||
* --------------------------------------------------*/
|
||||
void SetMeshMaterialMovieFrame(t3dMESH *m, int8 op, int32 newframe) {
|
||||
if (!m || m->FList.empty() || !m->FList[0].getMaterial()) return;
|
||||
|
||||
if (op == 0)
|
||||
m->setMovieFrame(newframe);
|
||||
else if (op > 0)
|
||||
m->setMovieFrame(m->getMovieFrame() + newframe);
|
||||
else if (op < 0)
|
||||
m->setMovieFrame(m->getMovieFrame() - newframe);
|
||||
|
||||
newframe = m->getMovieFrame();
|
||||
|
||||
_vm->addMeshModifier(m->name, MM_SET_MAT_FRAME, &newframe);
|
||||
}
|
||||
|
||||
/* -----------------22/06/00 12.15-------------------
|
||||
* ChangeMeshMaterialFlags
|
||||
* --------------------------------------------------*/
|
||||
void ChangeMeshMaterialFlag(t3dMESH *m, int8 add, uint32 newflag) {
|
||||
if (!m || m->hasFaceMaterial()) return;
|
||||
|
||||
if (add > 0) {
|
||||
m->FList[0].getMaterial()->addProperty(newflag);
|
||||
_vm->addMeshModifier(m->name, MM_ADD_MAT_FLAGS, &newflag);
|
||||
} else {
|
||||
m->FList[0].getMaterial()->clearFlag(newflag);
|
||||
_vm->addMeshModifier(m->name, MM_REMOVE_MAT_FLAGS, &newflag);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------20/04/99 15.29-------------------
|
||||
* t3dProcessGolfSky
|
||||
* --------------------------------------------------*/
|
||||
void t3dProcessGolfSky(t3dMESH *gs) {
|
||||
uint32 i;
|
||||
t3dF32 GolfSkySpeed = 0.00009f;
|
||||
gVertex *gv;
|
||||
|
||||
if (!gs) return ;
|
||||
|
||||
gv = gs->VertexBuffer;
|
||||
for (i = 0; i < gs->NumVerts; i++, gv++) {
|
||||
gv->u1 += GolfSkySpeed;
|
||||
gv->v1 += GolfSkySpeed;
|
||||
}
|
||||
gs->Flags |= T3D_MESH_UPDATEVB;
|
||||
gs->VBptr = NULL;
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
89
engines/watchmaker/ll/ll_mesh.h
Normal file
89
engines/watchmaker/ll/ll_mesh.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* 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_LL_MESH_H
|
||||
#define WATCHMAKER_LL_MESH_H
|
||||
|
||||
#include "watchmaker/t3d.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
#include "watchmaker/work_dirs.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
uint8 t3dClipToSurface(Init &init, t3dV3F *pt);
|
||||
void t3dLightChar(t3dMESH *mesh, t3dV3F *p);
|
||||
void t3dProcessGolfSky(t3dMESH *gs);
|
||||
void HideRoomMeshes(Init &init, t3dBODY *body);
|
||||
void t3dUpdateArrow(t3dMESH *m, t3dF32 len);
|
||||
bool t3dSetSpecialAnimFrame(WGame &game, const char *name, t3dMESH *mesh, int32 nf);
|
||||
void ChangeMeshFlags(t3dMESH *m, int8 add, uint32 newflags);
|
||||
void UpdateObjMesh(Init &init, int32 in);
|
||||
void UpdateBoundingBox(t3dMESH *mesh);
|
||||
void UpdateCharHead(int32 oc, t3dV3F *dir);
|
||||
void SetMeshMaterialMovieFrame(t3dMESH *m, int8 op, int32 newframe);
|
||||
void ChangeMeshMaterialFlag(t3dMESH *m, int8 add, uint32 newflag);
|
||||
void ChangeHaloesStatus(t3dBODY *b, int8 op);
|
||||
uint8 t3dVectMeshInters(t3dMESH *m, t3dV3F start, t3dV3F end, t3dV3F *inters);
|
||||
void t3dLightRoom(Init &init, t3dBODY *b, t3dV3F *p, t3dF32 NearRange, t3dF32 FarRange, t3dF32 IperRange);
|
||||
void t3dUpdateExplosion(t3dMESH *m, t3dF32 scale);
|
||||
bool t3dMoveAndCheck1stCamera(t3dBODY *rr, t3dCAMERA *cc, t3dV3F *mm);
|
||||
|
||||
// TODO: This could perhaps be PIMPLd, as we don't really need to expose the implementation.
|
||||
struct SMeshModifier {
|
||||
Common::String meshName;
|
||||
private:
|
||||
int32 Flags = 0;
|
||||
uint32 AddFlags = 0;
|
||||
uint32 RemoveFlags = 0;
|
||||
uint32 AddMatFlags = 0;
|
||||
uint32 RemoveMatFlags = 0;
|
||||
int32 MatFrame = 0;
|
||||
uint16 BndLevel = 0;
|
||||
int8 HaloesStatus = 0;
|
||||
public:
|
||||
Common::String animName;
|
||||
SMeshModifier() = default;
|
||||
SMeshModifier(const char *name, int16 com, void *p);
|
||||
SMeshModifier(Common::SeekableReadStream &stream);
|
||||
void configure(const char *name, int16 com, void *p);
|
||||
void modifyMesh(WGame &game, t3dMESH *mesh);
|
||||
uint16 getBndLevel() const { return BndLevel; }
|
||||
int32 getFlags() const { return Flags; }
|
||||
int8 getHaloesStatus() const { return HaloesStatus; }
|
||||
};
|
||||
|
||||
class MeshModifiers {
|
||||
SMeshModifier MMList[MAX_MODIFIED_MESH] = {};
|
||||
public:
|
||||
MeshModifiers() = default;
|
||||
MeshModifiers(Common::SeekableReadStream &stream) {
|
||||
for (int i = 0; i < MAX_MODIFIED_MESH; i++) {
|
||||
MMList[i] = SMeshModifier(stream);
|
||||
}
|
||||
}
|
||||
void addMeshModifier(const Common::String &name, int16 com, void *p);
|
||||
void applyAllMeshModifiers(WGame &game, t3dBODY *b);
|
||||
void modifyMesh(WGame &game, t3dMESH *mesh);
|
||||
};
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_MESH_H
|
||||
129
engines/watchmaker/ll/ll_mouse.cpp
Normal file
129
engines/watchmaker/ll/ll_mouse.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
/* 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/ll/ll_mouse.h"
|
||||
#include "watchmaker/utils.h"
|
||||
#include "watchmaker/message.h"
|
||||
#include "watchmaker/game.h"
|
||||
#include "watchmaker/schedule.h"
|
||||
#include "watchmaker/classes/do_camera.h"
|
||||
#include "watchmaker/3d/geometry.h"
|
||||
#include "watchmaker/renderer.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
int32 mPosy = 0, mPosx = 0, mMoveX = 0, mMoveY = 0, mMove = 0, mCounter = 0, mHotspotX = 0, mHotspotY = 0;
|
||||
uint8 bLPressed = 0, bRPressed = 0, mHide = 1, bSkipped = 0;
|
||||
uint8 bLPressedPrev = 0, bRPressedPrev = 0;
|
||||
|
||||
/* -----------------08/05/98 11.47-------------------
|
||||
* ProcessMouse
|
||||
* --------------------------------------------------*/
|
||||
void ProcessMouse(WGame &game) {
|
||||
t3dF32 diffx, diffy;
|
||||
int32 fittedx, fittedy;
|
||||
|
||||
if (mMoveX || mMoveY) {
|
||||
mHide = 0;
|
||||
mCounter = 0;
|
||||
game._messageSystem.removeEvent(EventClass::MC_MOUSE, ME_MOUSEUPDATE);
|
||||
_vm->_messageSystem.doEvent(EventClass::MC_MOUSE, ME_MOUSEUPDATE, MP_DEFAULT, (int16)mPosx, (int16)mPosy, 0, &mMoveX, &mMoveY, NULL);
|
||||
}
|
||||
mMoveX = mMoveY = 0;
|
||||
|
||||
diffx = 0.0f;
|
||||
diffy = 0.0f;
|
||||
game._cameraMan->CamAngleX = 0.0f;
|
||||
game._cameraMan->CamAngleY = 0.0f;
|
||||
fittedx = 0;
|
||||
fittedy = 0;
|
||||
|
||||
fittedx = game._renderer->rInvFitX(mPosx);
|
||||
if (fittedx < (SCREEN_RES_X / 2)) {
|
||||
if (fittedx < 50) {
|
||||
diffx = - ((50.f - (t3dF32)fittedx) / 50.f);
|
||||
}
|
||||
|
||||
if (fittedx < 5) diffx *= 1.4f;
|
||||
} else {
|
||||
if ((SCREEN_RES_X - fittedx) < 50) {
|
||||
diffx = ((50.f - (t3dF32)(SCREEN_RES_X - fittedx)) / 50.f);
|
||||
}
|
||||
|
||||
if ((SCREEN_RES_X - fittedx) < 5) diffx *= 1.4f;
|
||||
}
|
||||
|
||||
|
||||
fittedy = game._renderer->rInvFitY(mPosy);
|
||||
if (fittedy < (SCREEN_RES_Y / 2)) {
|
||||
if (fittedy < 50) {
|
||||
diffy = - ((50.f - (t3dF32)fittedy) / 50.f);
|
||||
}
|
||||
|
||||
if (fittedy < 5) diffy *= 1.4f;
|
||||
} else {
|
||||
if ((SCREEN_RES_Y - fittedy) < 50) {
|
||||
diffy = ((50.f - (t3dF32)(SCREEN_RES_Y - fittedy)) / 50.f);
|
||||
}
|
||||
|
||||
if ((SCREEN_RES_Y - fittedy) < 5) diffy *= 1.4f;
|
||||
}
|
||||
|
||||
auto windowInfo = game._renderer->getScreenInfos();
|
||||
if (mPosx > (int32)windowInfo.width) mPosx = windowInfo.width - 1;
|
||||
else if (mPosx <= 0) mPosx = 1;
|
||||
if (mPosy > (int32)windowInfo.height) mPosy = windowInfo.height - 1;
|
||||
else if (mPosy <= 0) mPosy = 1;
|
||||
|
||||
game._cameraMan->MoveHeadAngles(diffx, diffy);
|
||||
}
|
||||
/* -----------------19/10/98 15.18-------------------
|
||||
* DInputMouseGetCoords
|
||||
* --------------------------------------------------*/
|
||||
void HandleMouseChanges() {
|
||||
// Mouse movement will have been accumulated prior to calling this function.
|
||||
// Button flags may also have been changed, this function then applies the button changes.
|
||||
|
||||
//warning("L: %d %d R: %d %d", bLPressed, bLPressedPrev, bRPressed, bRPressedPrev);
|
||||
// Button 0 pressed or released
|
||||
if (bLPressed != bLPressedPrev) {
|
||||
// se ha rilasciato e non ha mosso il mouse
|
||||
if ((!bLPressed) && (!bSkipped) && ((mMove < 10) || (!(InvStatus & INV_MODE2) && !bFirstPerson && !bT2DActive))) {
|
||||
_vm->_messageSystem.doEvent(EventClass::MC_MOUSE, ME_MLEFT, MP_DEFAULT, (int16)mPosx, (int16)mPosy, bRPressed, NULL, NULL, NULL);
|
||||
bSkipped = FALSE;
|
||||
} else if (bLPressed && (mMove >= 10) && (InvStatus & INV_MODE2) && (bSomeOneSpeak)) {
|
||||
bSkipTalk = TRUE;
|
||||
bSkipped = TRUE;
|
||||
} else if (!bLPressed)
|
||||
bSkipped = FALSE;
|
||||
mMove = 0;
|
||||
}
|
||||
// Button 1 pressed or released
|
||||
if (bRPressed != bRPressedPrev) {
|
||||
if ((!bRPressed) && ((mMove < 10) || (!bFirstPerson && !bT2DActive)))
|
||||
_vm->_messageSystem.doEvent(EventClass::MC_MOUSE, ME_MRIGHT, MP_DEFAULT, (int16)mPosx, (int16)mPosy, bLPressed, NULL, NULL, NULL);
|
||||
mMove = 0;
|
||||
}
|
||||
bLPressedPrev = bLPressed;
|
||||
bRPressedPrev = bRPressed;
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
39
engines/watchmaker/ll/ll_mouse.h
Normal file
39
engines/watchmaker/ll/ll_mouse.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 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_LL_MOUSE_H
|
||||
#define WATCHMAKER_LL_MOUSE_H
|
||||
|
||||
#include "watchmaker/types.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
class WGame;
|
||||
|
||||
// MOUSE form (llmouse.c)
|
||||
extern int32 mPosy, mPosx, mMoveX, mMoveY, mMove, mCounter, mHotspotX, mHotspotY;
|
||||
extern uint8 bLPressed, bRPressed, mHide;
|
||||
void ProcessMouse(WGame &game);
|
||||
void HandleMouseChanges();
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_MOUSE_H
|
||||
433
engines/watchmaker/ll/ll_regen.cpp
Normal file
433
engines/watchmaker/ll/ll_regen.cpp
Normal file
@@ -0,0 +1,433 @@
|
||||
/* 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/ll/ll_regen.h"
|
||||
#include "watchmaker/classes/do_camera.h"
|
||||
#include "watchmaker/render.h"
|
||||
#include "watchmaker/struct.h"
|
||||
#include "watchmaker/sysdef.h"
|
||||
#include "watchmaker/utils.h"
|
||||
#include "watchmaker/t2d/t2d.h"
|
||||
#include "watchmaker/extraLS.h"
|
||||
#include "watchmaker/ll/ll_mouse.h"
|
||||
#include "watchmaker/define.h"
|
||||
#include "watchmaker/3d/geometry.h"
|
||||
#include "watchmaker/3d/t3d_body.h"
|
||||
#include "watchmaker/ll/ll_system.h"
|
||||
#include "watchmaker/ll/ll_util.h"
|
||||
#include "watchmaker/ll/ll_string.h"
|
||||
#include "watchmaker/renderer.h"
|
||||
|
||||
// 2d-regen
|
||||
#define MAX_PAINT_RECTS MAX_DD_BITMAPS+MAX_REND_TEXTS
|
||||
#define MAX_UPDATE_RECTS MAX_DD_BITMAPS+MAX_REND_TEXTS
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
struct SDDBitmap PaintRect[MAX_PAINT_RECTS];
|
||||
struct SDDBitmap OldPaintRect[MAX_PAINT_RECTS];
|
||||
|
||||
// frame-rate
|
||||
t3dF32 hi, lo, ofps;
|
||||
|
||||
#define WM_CUR_VERSION "The Watchmaker v0.92"
|
||||
|
||||
/* -----------------30/10/98 12.19-------------------
|
||||
* IntersecateRect
|
||||
* --------------------------------------------------*/
|
||||
int32 IntersecateRect(int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3, int32 x4, int32 y4, SRect *r) {
|
||||
if ((x1 <= x4) && (x2 >= x3) && (y1 <= y4) && (y2 >= y3)) {
|
||||
if (x3 > x1)
|
||||
r->x1 = 0;
|
||||
else
|
||||
r->x1 = x1 - x3;
|
||||
|
||||
if (x2 < x4)
|
||||
r->x2 = x2 - x3;
|
||||
else
|
||||
r->x2 = x4 - x3;
|
||||
|
||||
if (y3 > y1)
|
||||
r->y1 = 0;
|
||||
else
|
||||
r->y1 = y1 - y3;
|
||||
|
||||
if (y2 < y4)
|
||||
r->y2 = y2 - y3;
|
||||
else
|
||||
r->y2 = y4 - y3;
|
||||
|
||||
if (!(r->x2 - r->x1) || !(r->y2 - r->y1))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
/* -----------------30/10/98 11.41-------------------
|
||||
* Regen
|
||||
* --------------------------------------------------*/
|
||||
void Regen(WGame &game) {
|
||||
struct SRect UpdateRect[MAX_UPDATE_RECTS], *p;
|
||||
struct SDDBitmap *n, *o;
|
||||
struct SRect r, ext;
|
||||
int32 a, b, upn;
|
||||
uint8 found, refresh[MAX_PAINT_RECTS];
|
||||
|
||||
#ifdef DEBUG_REGEN
|
||||
DebugFile("----- Nuovo Frame -----");
|
||||
#endif
|
||||
upn = 0;
|
||||
memset(refresh, 0, sizeof(refresh));
|
||||
for (uint32 i = 0; i < ARRAYSIZE(UpdateRect); i++) UpdateRect[i].reset();
|
||||
// I take the Extends of what the engine drew
|
||||
rGetExtends(&ext.x1, &ext.y1, &ext.x2, &ext.y2);
|
||||
// 1 - Compare each element of PaintRect to all OlPaintRect elements
|
||||
for (a = 0; a < MAX_PAINT_RECTS; a++) {
|
||||
n = &PaintRect[a];
|
||||
if (!(n->dx) || !(n->dy))
|
||||
continue;
|
||||
#ifdef DEBUG_REGEN
|
||||
DebugFile("%d: Controllo rect %d '%s': %d,%d %d,%d", a, n->tnum, rGetBitmapName(n->tnum), n->px + n->ox, n->py + n->oy, n->dx, n->dy);
|
||||
#endif
|
||||
found = 0;
|
||||
for (b = 0; b < MAX_PAINT_RECTS; b++) {
|
||||
o = &OldPaintRect[b];
|
||||
if (!(o->dx) || !(o->dy))
|
||||
continue;
|
||||
|
||||
if ((n->tnum == o->tnum) && (n->px == o->px) && (n->py == o->py) && (n->ox == o->ox) && (n->oy == o->oy) && (n->dx == o->dx) && (n->dy == o->dy)) {
|
||||
#ifdef DEBUG_REGEN
|
||||
DebugFile("-> Gia' disegnato");
|
||||
#endif
|
||||
refresh[b] = 1;
|
||||
found ++;
|
||||
}
|
||||
}
|
||||
// if it's a new rectangle, compile UpdateRect
|
||||
if (true || !found) { // HACK: Just always treat everything as new, since we're doing GL
|
||||
#ifdef DEBUG_REGEN
|
||||
DebugFile("-> Nuovo rettangolo");
|
||||
#endif
|
||||
UpdateRect[upn].x1 = n->px + n->ox;
|
||||
UpdateRect[upn].y1 = n->py + n->oy;
|
||||
UpdateRect[upn].x2 = n->px + n->ox + n->dx;
|
||||
UpdateRect[upn].y2 = n->py + n->oy + n->dy;
|
||||
upn ++;
|
||||
}
|
||||
}
|
||||
// 2 - If there are any reactangles that need to be deleted, compile UpdateRect
|
||||
for (a = 0; a < MAX_PAINT_RECTS; a++) {
|
||||
n = &OldPaintRect[a];
|
||||
if (!(n->dx) || !(n->dy))
|
||||
continue;
|
||||
|
||||
if ((!refresh[a]) && (n->dx) && (n->dy)) {
|
||||
#ifdef DEBUG_REGEN
|
||||
DebugFile("Non viene piu' ridisegnato %d '%s': %d,%d %d,%d", n->tnum, rGetBitmapName(n->tnum), n->px + n->ox, n->py + n->oy, n->dx, n->dy);
|
||||
#endif
|
||||
UpdateRect[upn].x1 = n->px + n->ox;
|
||||
UpdateRect[upn].y1 = n->py + n->oy;
|
||||
UpdateRect[upn].x2 = n->px + n->ox + n->dx;
|
||||
UpdateRect[upn].y2 = n->py + n->oy + n->dy;
|
||||
upn ++;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 - For all UpdateRects delete the ScreenBuffer and copy what's left
|
||||
for (a = 0; a < upn; a++) {
|
||||
p = &UpdateRect[a];
|
||||
if (!(p->x2 - p->x1) || !(p->y2 - p->y1))
|
||||
continue;
|
||||
|
||||
// Clear ScreenBuffer
|
||||
game._renderer->clearBitmap(BACK_BUFFER, (p->x1), (p->y1), (p->x2 - p->x1), (p->y2 - p->y1), 0, 0, 0);
|
||||
}
|
||||
|
||||
for (a = 0; a < upn; a++) {
|
||||
p = &UpdateRect[a];
|
||||
if (!(p->x2 - p->x1) || !(p->y2 - p->y1))
|
||||
continue;
|
||||
|
||||
#ifdef DEBUG_REGEN
|
||||
DebugFile("Ridisegno quello che sta sopra a %d,%d %d,%d", p->x1, p->y1, p->x2 - p->x1, p->y2 - p->y1);
|
||||
#endif
|
||||
found = 0;
|
||||
for (b = 0; b < MAX_PAINT_RECTS; b++) {
|
||||
n = &PaintRect[b];
|
||||
if (!(n->dx) || !(n->dy))
|
||||
continue;
|
||||
|
||||
// If it intersects, copies intersection only
|
||||
if ((IntersecateRect(p->x1, p->y1, p->x2, p->y2, n->px + n->ox, n->py + n->oy, n->px + n->ox + n->dx, n->py + n->oy + n->dy, &r)) &&
|
||||
(n->ox + r.x2 - r.x1) && (n->oy + r.y2 - r.y1)) {
|
||||
#ifdef DEBUG_REGEN
|
||||
DebugFile("Copio %d '%s': P %d,%d O %d,%d D %d,%d", n->tnum, rGetBitmapName(n->tnum), (n->px + n->ox + r.x1), (n->py + n->oy + r.y1), (n->ox + r.x1), (n->oy + r.y1), (r.x2 - r.x1), (r.y2 - r.y1));
|
||||
// DebugLogWindow( "Copio %d '%s': P %d,%d O %d,%d D %d,%d", n->tnum, rGetBitmapName(n->tnum), (n->px+n->ox+r.x1), (n->py+n->oy+r.y1), (n->ox+r.x1), (n->oy+r.y1), (r.x2-r.x1), (r.y2-r.y1) );
|
||||
#endif
|
||||
rBlitter(game, BACK_BUFFER, n->tnum, (n->px + n->ox + r.x1), (n->py + n->oy + r.y1), (n->ox + r.x1), (n->oy + r.y1), (r.x2 - r.x1), (r.y2 - r.y1));
|
||||
found ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (p) p->reset();
|
||||
}
|
||||
}
|
||||
|
||||
// 4 - Copy on screen only the UpdateRects by stretching them.
|
||||
for (a = 0; a < MAX_PAINT_RECTS; a++) {
|
||||
n = &PaintRect[a];
|
||||
if (!(n->dx) || !(n->dy))
|
||||
continue;
|
||||
|
||||
if ((n->px + n->ox) < ext.x1) ext.x1 = n->px + n->ox;
|
||||
if ((n->py + n->oy) < ext.y1) ext.y1 = n->py + n->oy;
|
||||
if ((n->px + n->ox + n->dx) > ext.x2) ext.x2 = n->px + n->ox + n->dx;
|
||||
if ((n->py + n->oy + n->dy) > ext.y2) ext.y2 = n->py + n->oy + n->dy;
|
||||
}
|
||||
for (a = 0; a < upn; a++) {
|
||||
p = &UpdateRect[a];
|
||||
if (!(p->x2 - p->x1) || !(p->y2 - p->y1))
|
||||
continue;
|
||||
|
||||
if (p->x1 < ext.x1) ext.x1 = p->x1;
|
||||
if (p->y1 < ext.y1) ext.y1 = p->y1;
|
||||
if (p->x2 > ext.x2) ext.x2 = p->x2;
|
||||
if (p->y2 > ext.y2) ext.y2 = p->y2;
|
||||
}
|
||||
auto windowInfo = game._renderer->getScreenInfos();
|
||||
if (ext.x1 < 0) ext.x1 = 0;
|
||||
if (ext.y1 < 0) ext.y1 = 0;
|
||||
if (ext.x2 > (int32)windowInfo.width) ext.x2 = windowInfo.width;
|
||||
if (ext.y2 > (int32)windowInfo.height) ext.y2 = windowInfo.height;
|
||||
#ifdef DEBUG_REGEN
|
||||
DebugFile("Aggiorna video %d,%d %d,%d", ext.x1, ext.y1, ext.x2 - ext.x1, ext.y2 - ext.y1);
|
||||
// DebugLogWindow( "Aggiorna video %d,%d %d,%d", ext.x1, ext.y1, ext.x2-ext.x1, ext.y2-ext.y1 );
|
||||
#endif
|
||||
rUpdateExtends(ext.x1, ext.y1, ext.x2, ext.y2);
|
||||
game._renderer->blitScreenBuffer();
|
||||
rResetExtends();
|
||||
|
||||
// 5 - Copy PaintRect to OldPaintRect
|
||||
memcpy(OldPaintRect, PaintRect, sizeof(OldPaintRect));
|
||||
// memset( OldPaintRect, 0, sizeof( OldPaintRect ) );
|
||||
}
|
||||
|
||||
|
||||
/* -----------------16/11/98 17.29-------------------
|
||||
* ResetScreenBuffer
|
||||
* --------------------------------------------------*/
|
||||
void ResetScreenBuffer() {
|
||||
for (uint i = 0; i < ARRAYSIZE(OldPaintRect); i++) OldPaintRect[i].reset();
|
||||
|
||||
if (!rClearBuffers(rCLEARSCREENBUFFER | rCLEARZBUFFER))
|
||||
warning("Unable to clear screenbuffer");
|
||||
}
|
||||
|
||||
/* -----------------30/10/98 16.18-------------------
|
||||
* AfterRender
|
||||
* --------------------------------------------------*/
|
||||
void AfterRender(WGame &game) {
|
||||
PaintT2D(*game._renderer);
|
||||
PaintInventory(game);
|
||||
PaintText(game);
|
||||
}
|
||||
|
||||
/* -----------------31/10/98 15.56-------------------
|
||||
* AddPaintRect
|
||||
* --------------------------------------------------*/
|
||||
void AddPaintRect(int32 tnum, int32 px, int32 py, int32 ox, int32 oy, int32 dx, int32 dy) {
|
||||
int32 a;
|
||||
for (a = 0; a < MAX_PAINT_RECTS; a++)
|
||||
if (!PaintRect[a].tnum)
|
||||
break;
|
||||
|
||||
// ce ne sono troppe
|
||||
if (a >= MAX_PAINT_RECTS) {
|
||||
warning("Too many PaintRects!");
|
||||
return ;
|
||||
}
|
||||
|
||||
PaintRect[a].tnum = tnum;
|
||||
PaintRect[a].px = (px);
|
||||
PaintRect[a].py = (py);
|
||||
PaintRect[a].ox = (ox);
|
||||
PaintRect[a].oy = (oy);
|
||||
PaintRect[a].dx = (dx);
|
||||
PaintRect[a].dy = (dy);
|
||||
}
|
||||
|
||||
void Renderer::add2DStuff() {
|
||||
// Insert pre-calculated images and texts
|
||||
_2dStuff.writeBitmapListTo(PaintRect);
|
||||
|
||||
_2dStuff.garbageCollectPreRenderedText();
|
||||
|
||||
// Put mouse over everything
|
||||
if ((!mHide) && (CurDialog <= dSUPERVISORE) && (!bTitoliCodaStatic) && (!bTitoliCodaScrolling)) {
|
||||
int32 cmx = mPosx - mHotspotX;
|
||||
int32 cmy = mPosy - mHotspotY;
|
||||
|
||||
if (cmx >= MousePointerLim.x2)
|
||||
cmx = MousePointerLim.x2 - 1;
|
||||
else if (cmx <= MousePointerLim.x1)
|
||||
cmx = MousePointerLim.x1 + 1;
|
||||
|
||||
if (cmy >= MousePointerLim.y2)
|
||||
cmy = MousePointerLim.y2 - 1;
|
||||
else if (cmy <= MousePointerLim.y1)
|
||||
cmy = MousePointerLim.y1 + 1;
|
||||
|
||||
// Draw the current mouse pointer
|
||||
if (CurMousePointer > 0)
|
||||
AddPaintRect(CurMousePointer, (cmx), (cmy), 0, 0, this->getBitmapDimX(CurMousePointer), this->getBitmapDimY(CurMousePointer));
|
||||
}
|
||||
|
||||
Regen(*_game);
|
||||
|
||||
_2dStuff.clearBitmapList();
|
||||
_2dStuff.clearTextList();
|
||||
|
||||
//check
|
||||
CheckExtraLocalizationStrings(*this, 0);
|
||||
}
|
||||
|
||||
/* -----------------27/10/98 17.14-------------------
|
||||
* Add3DStuff
|
||||
* --------------------------------------------------*/
|
||||
void Add3DStuff(WGame &game) {
|
||||
extern uint32 StatNumTris, StatNumVerts;
|
||||
struct SD3DRect *p;
|
||||
struct SD3DTriangle *t;
|
||||
int32 a, y = 0;
|
||||
// char *PauseAnimStr[] = { "", "(PAUSE)" };
|
||||
|
||||
if (bShowBoundingBox) {
|
||||
t3dShowBoundingBox(t3dCurRoom);
|
||||
for (a = ocCUOCO; a < ocCURPLAYER; a++)
|
||||
if ((Character[a]) && (Character[a]->Body) && !(Character[a]->Flags & T3D_CHARACTER_HIDE))
|
||||
t3dShowBoundingBox(Character[a]->Body);
|
||||
}
|
||||
|
||||
if (bShowPanels && Player && Player->Walk.Panel)
|
||||
t3dShowBounds(Player->Walk.Panel, Player->Walk.PanelNum);
|
||||
else if (bShowPanels)
|
||||
t3dShowBounds(t3dCurRoom->Panel[t3dCurRoom->CurLevel], t3dCurRoom->NumPanels[t3dCurRoom->CurLevel]);
|
||||
|
||||
//DisplayDDBitmap( TrecLogo, 800-10-rGetBitmapRealDimX(TrecLogo),0, 0,0, 0,0 );
|
||||
if (bShowInfo) {
|
||||
//display version
|
||||
uint32 date = 0, time = 0, d = 0, m = 0, yy = 0, h = 0, min = 0;
|
||||
t3dForceNOFastFile(1);
|
||||
if (t3dGetFileDate(&date, &time, "wm.exe ")) {
|
||||
d = date - (date / 100) * 100;
|
||||
date /= 100;
|
||||
m = date - (date / 100) * 100;
|
||||
date /= 100;
|
||||
yy = date;
|
||||
|
||||
time /= 100;
|
||||
min = time - (time / 100) * 100;
|
||||
time /= 100;
|
||||
h = time;
|
||||
} else {
|
||||
d = m = yy = h = min = 0;
|
||||
}
|
||||
t3dForceNOFastFile(0);
|
||||
DebugVideo(*game._renderer, 1, 600 - 20, "%s (%02d/%02d/%4d - %d.%d)", WM_CUR_VERSION, d, m, yy, h, min);
|
||||
|
||||
if (LoaderFlags & T3D_DEBUGMODE) {
|
||||
auto windowInfo = game._renderer->getScreenInfos();
|
||||
if (CurFps > 100.0f) CurFps = 100.0f;
|
||||
if (AvgFps > 100.0f) AvgFps = 100.0f;
|
||||
if (!AvgFps) AvgFps = CurFps;
|
||||
if (AvgFps != ofps) {
|
||||
ofps = AvgFps;
|
||||
hi = 0.0f;
|
||||
lo = 999.0f;
|
||||
}
|
||||
if (CurFps > hi) hi = CurFps;
|
||||
if (CurFps < lo) lo = CurFps;
|
||||
DisplayD3DRect(*game._renderer, 1, 1, (int32)((t3dF32)windowInfo.width * (CurFps / 101.0f)), 13, 78, 78, 78, 228);
|
||||
DebugVideo(*game._renderer, 1, y += 16, "FPS: ( LOW %2d | AVG %2d | HI %2d ) TRI: %d VERT: %d", (int)lo, (int)AvgFps, (int)hi, StatNumTris, StatNumVerts);
|
||||
// DebugVideo(1,y+=16,"(%d) CUR %f %s",(int)(1000.0f/CurFps),CurFps,PauseAnimStr[bPauseAllAnims]);
|
||||
DebugVideo(*game._renderer, 1, y += 16, "%d,%d: %s (%d %d) %X", game._gameVars.getCurRoomId(), CurObj, ObjectUnderCursor, NextPortalObj, NextPortalAnim, game.init.Obj[CurObj].flags);
|
||||
// DebugVideo(1,y+=16,"Player: %d %d %d %d",Player->Mesh->BlendPercent,Player->Mesh->CurFrame,Player->Mesh->LastFrame,Player->Walk.CurAction);
|
||||
DebugVideo(*game._renderer, 1, y += 16, "DialogActive: %d AnimWaitText: %d PlayerInAnim: %d | %d", bDialogActive, bAnimWaitText, bPlayerInAnim, Player->Mesh->CurFrame);
|
||||
DebugVideo(*game._renderer, 1, y += 16, "CurCamera %d CurTime %d (%f %f)", game._cameraMan->getCurCameraIndex() + 1, t3dCurTime, t3dCurCamera->Source.x, t3dCurCamera->Source.z);
|
||||
// DebugVideo(1,y+=16,"xy(%f %f)",Character[1]->Mesh->Trasl.x,Character[1]->Mesh->Trasl.y);
|
||||
// DebugVideo(1,y+=16,"xy(%f %f)",Character[2]->Dir.x,Character[2]->Dir.y);
|
||||
DebugVideo(*game._renderer, 1, y += 16, "bPlayerSuBasamento %d", bPlayerSuBasamento);
|
||||
DebugVideo(*game._renderer, 1, y += 16, "%f %f ", Player->Mesh->Trasl.y, Player->Pos.y);
|
||||
// DebugVideo(1,y+=16,"CurP %d",CurPlayer);
|
||||
// DebugVideo(1,y+=16,"InvStatus ON%d (1)%d (2)%d (3)%d (4)%d (5)%d",InvStatus&1,InvStatus&2,InvStatus&4,InvStatus&8,InvStatus&16,InvStatus&32);
|
||||
DebugVideo(*game._renderer, 1, y += 16, "bMovingCamera%d", bMovingCamera);
|
||||
|
||||
// DebugVideo(1,y+=16,"1-%s",PlayerStand[0].RoomName);
|
||||
// DebugVideo(1,y+=16,"2-%s",PlayerStand[1].RoomName);
|
||||
/* if( Character[1]->CurRoom )
|
||||
{
|
||||
if( Character[1]->CurRoom->Name[0]=='\0' ) DebugVideo(1,y+=16,"1-NULLA");
|
||||
else DebugVideo(1,y+=16,"1-%s",Character[1]->CurRoom->Name);
|
||||
}
|
||||
|
||||
if( Character[2]->CurRoom )
|
||||
{
|
||||
if( Character[2]->CurRoom->Name[0]=='\0' ) DebugVideo(1,y+=16,"2-NULLA");
|
||||
else DebugVideo(1,y+=16,"2-%s",Character[2]->CurRoom->Name);
|
||||
}
|
||||
*/
|
||||
DebugVideo(*game._renderer, 1, windowInfo.height - 40, "%s", CurDebugString);
|
||||
} else {
|
||||
// extern t3dU8 t3dCurCameraIndex;
|
||||
// DebugVideo(1,y+=16,"CurCamera %d CurTime %d",t3dCurCameraIndex+1,t3dCurTime);
|
||||
// extern t3dU8 t3dCurCameraIndex;
|
||||
|
||||
// if( !AvgFps ) AvgFps = CurFps;
|
||||
// if( AvgFps != ofps ) { ofps = AvgFps; hi = 0.0f; lo = 999.0f; }
|
||||
// if( CurFps > hi ) hi = CurFps;
|
||||
// if( CurFps < lo ) lo = CurFps;
|
||||
// DebugVideo(1,y+=16,"mHide %d",mHide);
|
||||
// DebugVideo(1,1,"FPS: %3d TRI: %d VERT: %d",(int)AvgFps,StatNumTris,StatNumVerts);
|
||||
// DebugVideo(1,y+=16,"CurTime %d CurCamera %d",t3dCurTime,t3dCurCameraIndex+1);
|
||||
// DebugVideo(1,y+=16,"CurDialog %d, obj %d",CurDialog,Dialog[CurDialog].obj);
|
||||
// DebugVideo(1,y+=16,"%d,%d: %s (%d %d) %X",CurRoom,CurObj,ObjectUnderCursor,NextPortalObj,NextPortalAnim,Obj[CurObj].flags); //_remove
|
||||
}
|
||||
}
|
||||
// Aggiunge i rettangoli D3D
|
||||
for (a = 0, p = &D3DRectsList[0]; a < MAX_D3D_RECTS; a++, p++)
|
||||
if (p->dx || p->dy)
|
||||
t3dAddQuad((t3dF32)(p->px), (t3dF32)(p->py), (t3dF32)(p->px + p->dx), (t3dF32)(p->py),
|
||||
(t3dF32)(p->px), (t3dF32)(p->py + p->dy), (t3dF32)(p->px + p->dx), (t3dF32)(p->py + p->dy),
|
||||
p->r, p->g, p->b, p->a);
|
||||
for (a = 0, p = &D3DRectsList[0]; a < MAX_D3D_RECTS; a++, p++)
|
||||
p->dx = p->dy = 0;
|
||||
// Aggiunge i triangoli D3D
|
||||
for (a = 0, t = &D3DTrianglesList[0]; a < MAX_D3D_TRIANGLES; a++, t++)
|
||||
if (t->x1 || t->y1 || t->x2 || t->y2)
|
||||
t3dAddTriangle((t3dF32)(t->x1), (t3dF32)(t->y1), (t3dF32)(t->x2), (t3dF32)(t->y2),
|
||||
(t3dF32)(t->x3), (t3dF32)(t->y3), t->r, t->g, t->b, t->a);
|
||||
for (a = 0, t = &D3DTrianglesList[0]; a < MAX_D3D_TRIANGLES; a++, t++)
|
||||
t->x1 = t->y1 = t->x2 = t->y2 = t->x3 = t->y3 = 0;
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
35
engines/watchmaker/ll/ll_regen.h
Normal file
35
engines/watchmaker/ll/ll_regen.h
Normal 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_LL_REGEN_H
|
||||
#define WATCHMAKER_LL_REGEN_H
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
class WGame;
|
||||
|
||||
void ResetScreenBuffer();
|
||||
void AfterRender(WGame &game);
|
||||
void Add3DStuff(WGame &game);
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_REGEN_H
|
||||
102
engines/watchmaker/ll/ll_sound.cpp
Normal file
102
engines/watchmaker/ll/ll_sound.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/* 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/ll/ll_sound.h"
|
||||
#include "watchmaker/windows_hacks.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
bool mInitMusicSystem() {
|
||||
warning("STUBBED: mInitMusicSystem");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mCloseMusicSystem() {
|
||||
warning("STUBBED: mCloseMusicSystem");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mLoadMusic(const char *FileName) {
|
||||
warning("STUBBED: mLoadMusic");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mPlayMusic(const char *FileName) {
|
||||
warning("STUBBED: mPlayMusic");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mStopMusic() {
|
||||
warning("STUBBED: mStopMusic");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mRestoreMixerVolume() {
|
||||
warning("STUBBED: mRestoreMixerVolume");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sSetListener(sListener *NewListener) {
|
||||
warning("STUBBED: sSetListener");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sStartSound(sSound *CurSound, bool Reload) {
|
||||
warning("STUBBED: sStartSound");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sStopSound(int32 index) {
|
||||
warning("STUBBED: sStopSound");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sStopAllSounds() {
|
||||
warning("STUBBED: sStopAllSounds");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sIsPlaying(sS32 lIndex) {
|
||||
warning("STUBBED: sIsPlaying");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mSetAllVolume(unsigned char Volume) {
|
||||
warning("STUBBED: mSetAllVolume");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sSetAllSoundsVolume(unsigned char Vol) {
|
||||
warning("STUBBED: sSetAllSoundsVolume");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sSetAllSpeechVolume(unsigned char Vol) {
|
||||
warning("STUBBED: sSetAllSpeechVolume");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sStartSoundDiffuse(sSound *CurSound) {
|
||||
warning("STUBBED: sStartSoundDiffuse");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
102
engines/watchmaker/ll/ll_sound.h
Normal file
102
engines/watchmaker/ll/ll_sound.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* 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_LL_SOUND_H
|
||||
#define WATCHMAKER_LL_SOUND_H
|
||||
|
||||
#include "watchmaker/types.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
typedef float sF32;
|
||||
typedef unsigned int sU32;
|
||||
typedef signed int sS32;
|
||||
typedef unsigned short sU16;
|
||||
|
||||
#define SOUND_NAME_LEN 100
|
||||
|
||||
#define SOUND_SPEECH 32
|
||||
|
||||
struct sV3F {
|
||||
sF32 x, y, z;
|
||||
};
|
||||
|
||||
struct sEnvironment {
|
||||
sS32 lIndex; // room index (for retrieval)
|
||||
sS32 lRoom; // room effect level at low frequencies
|
||||
sS32 lRoomHF; // room effect high-frequency level re. low frequency level
|
||||
sF32 flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
sF32 flDecayTime; // reverberation decay time at low frequencies
|
||||
sF32 flDecayHFRatio; // high-frequency to low-frequency decay time ratio
|
||||
sS32 lReflections; // early reflections level relative to room effect
|
||||
sF32 flReflectionsDelay; // initial reflection delay time
|
||||
sS32 lReverb; // late reverberation level relative to room effect
|
||||
sF32 flReverbDelay; // late reverberation delay time relative to initial reflection
|
||||
sU32 dwEnvironment; // sets all listener properties ****
|
||||
sF32 flEnvironmentSize; // environment size in meters
|
||||
sF32 flEnvironmentDiffusion; // environment diffusion
|
||||
sF32 flAirAbsorptionHF; // change in level per meter at 5 kHz
|
||||
sU32 dwFlags; // modifies the behavior of properties
|
||||
};
|
||||
|
||||
struct sSound {
|
||||
char name[SOUND_NAME_LEN];
|
||||
sS32 lIndex;
|
||||
sU32 dwLooped;
|
||||
sF32 flMaxDistance; // servono fl
|
||||
sF32 flMinDistance; // servono fl
|
||||
sV3F v3flPosition; // meshlink
|
||||
sV3F v3flConeOrientation; // angolo con (0,0,-1)
|
||||
sU32 dwConeInsideAngle; // servono int
|
||||
sU32 dwConeOutsideAngle; // servono int
|
||||
sS32 dwConeOutsideVolume; // servono int (negativo)
|
||||
sU32 dwFlags; // flags
|
||||
};
|
||||
|
||||
struct sListener {
|
||||
sF32 flDistanceFactor; // non serve
|
||||
sV3F v3flFrontOrientation; // vettore front camera
|
||||
sV3F v3flTopOrientation; // vettore alto camera
|
||||
sV3F v3flPosition; // quella della telecamera
|
||||
sF32 flRolloff; // non serve
|
||||
};
|
||||
|
||||
bool sSetListener(sListener *NewListener);
|
||||
bool sStartSound(sSound *CurSound, bool Reload);
|
||||
bool sStopSound(int32 index);
|
||||
bool sStopAllSounds();
|
||||
bool sIsPlaying(sS32 lIndex);
|
||||
|
||||
bool mInitMusicSystem();
|
||||
bool mCloseMusicSystem();
|
||||
bool mLoadMusic(const char *FileName);
|
||||
bool mPlayMusic(const char *FileName);
|
||||
bool mStopMusic();
|
||||
bool mRestoreMixerVolume();
|
||||
|
||||
bool mSetAllVolume(unsigned char Volume);
|
||||
bool sSetAllSoundsVolume(unsigned char Vol);
|
||||
bool sSetAllSpeechVolume(unsigned char Vol);
|
||||
bool sStartSoundDiffuse(sSound *CurSound);
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_SOUND_H
|
||||
308
engines/watchmaker/ll/ll_string.cpp
Normal file
308
engines/watchmaker/ll/ll_string.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_strcpy
|
||||
|
||||
#include "watchmaker/ll/ll_string.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
#include "watchmaker/define.h"
|
||||
#include "watchmaker/ll/ll_util.h"
|
||||
#include "watchmaker/game.h"
|
||||
#include "watchmaker/classes/do_player.h"
|
||||
#include "watchmaker/classes/do_dialog.h"
|
||||
#include "watchmaker/t2d/expr.h"
|
||||
#include "watchmaker/renderer.h"
|
||||
#include "watchmaker/3d/t3d_body.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
// locals
|
||||
int32 LastTextTime;
|
||||
int console_3_4_xoffs = 0;
|
||||
|
||||
/* -----------------17/03/98 17.48-------------------
|
||||
* Text
|
||||
* --------------------------------------------------*/
|
||||
void Text(uint16 x, uint16 y, uint16 dx, char *text) {
|
||||
if (!text) return;
|
||||
|
||||
LastTextTime = TheTime;
|
||||
|
||||
TheString.x = x;
|
||||
TheString.y = y;
|
||||
TheString.dx = dx;
|
||||
strcpy(TheString.text, text);
|
||||
}
|
||||
|
||||
/* -----------------17/03/98 17.48-------------------
|
||||
* ClearText
|
||||
* --------------------------------------------------*/
|
||||
void ClearText() {
|
||||
if (!(bUseWith & UW_ON)) {
|
||||
TheString.x = 0;
|
||||
TheString.y = 0;
|
||||
TheString.dx = 0;
|
||||
memset(TheString.text, 0, sizeof(TheString.text));
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------17/02/95 09.53-------------------
|
||||
TextLen - calcola lunghezza str dal car 0 a num
|
||||
--------------------------------------------------*/
|
||||
uint16 TextLen(Fonts &fonts, char *sign, uint16 num) {
|
||||
uint16 Len, b, c;
|
||||
b = 0;
|
||||
|
||||
if (sign == nullptr)
|
||||
return (0);
|
||||
|
||||
if (num == 0)
|
||||
Len = strlen(sign);
|
||||
else
|
||||
Len = num;
|
||||
|
||||
for (c = 0; c < Len; c++)
|
||||
b += (fonts.StandardFont.table[(uint16)((uint8)sign[c]) * 4 + 2]);
|
||||
|
||||
return (b);
|
||||
}
|
||||
|
||||
/*-----------------14/05/95 12.12-------------------
|
||||
CheckText - returns how many lines it will write
|
||||
--------------------------------------------------*/
|
||||
uint16 CheckText(Fonts &fonts, uint16 dx, char *sign) {
|
||||
uint16 a, b;
|
||||
uint16 CurInit;
|
||||
uint16 LastSpace;
|
||||
uint16 CurLine;
|
||||
|
||||
if (sign == NULL) return (0);
|
||||
// Azzera tutto
|
||||
memset(TextLines, 0, sizeof(TextLines));
|
||||
|
||||
a = 0;
|
||||
LastSpace = 0;
|
||||
CurInit = 0;
|
||||
CurLine = 0;
|
||||
|
||||
// Caso piu' semplice: sta tutto su una riga
|
||||
if (TextLen(fonts, sign, 0) <= dx) {
|
||||
strcpy((char *)TextLines[CurLine], sign);
|
||||
return (1);
|
||||
}
|
||||
|
||||
while (a < strlen(sign)) {
|
||||
a++;
|
||||
if (sign[a] == ' ') {
|
||||
if (TextLen(fonts, (char *)(sign + CurInit), (uint16)(a - CurInit)) <= dx)
|
||||
LastSpace = a;
|
||||
else if (TextLen(fonts, (char *)(sign + CurInit), (uint16)(LastSpace - CurInit)) <= dx) {
|
||||
for (b = CurInit; b < LastSpace; b++)
|
||||
TextLines[CurLine][b - CurInit] = sign[b];
|
||||
|
||||
TextLines[CurLine][b - CurInit] = '\0';
|
||||
CurInit = LastSpace + 1;
|
||||
a = CurInit;
|
||||
CurLine++;
|
||||
} else
|
||||
return (0);
|
||||
} else if (sign[a] == '\0') {
|
||||
if (TextLen(fonts, (char *)(sign + CurInit), (uint16)(a - CurInit)) <= dx) {
|
||||
for (b = CurInit; b < a; b++)
|
||||
TextLines[CurLine][b - CurInit] = sign[b];
|
||||
TextLines[CurLine][b - CurInit] = '\0';
|
||||
|
||||
CurLine++;
|
||||
CurInit = a + 1;
|
||||
return (CurLine);
|
||||
} else if (TextLen(fonts, (char *)(sign + CurInit), (uint16)(LastSpace - CurInit)) <= dx) {
|
||||
for (b = CurInit; b < LastSpace; b++)
|
||||
TextLines[CurLine][b - CurInit] = sign[b];
|
||||
|
||||
TextLines[CurLine][b - CurInit] = '\0';
|
||||
CurLine++;
|
||||
CurInit = LastSpace + 1;
|
||||
|
||||
if (CurInit < strlen(sign)) {
|
||||
for (b = CurInit; b < strlen(sign); b++)
|
||||
TextLines[CurLine][b - CurInit] = sign[b];
|
||||
|
||||
TextLines[CurLine][b - CurInit] = '\0';
|
||||
CurLine++;
|
||||
}
|
||||
return (CurLine);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/* -----------------18/03/98 9.57--------------------
|
||||
* PaintText
|
||||
* --------------------------------------------------*/
|
||||
void PaintText(WGame &game) {
|
||||
uint16 lines, i;
|
||||
int32 dx, obj;
|
||||
FontColor color;
|
||||
Init &init = game.init;
|
||||
|
||||
if (bTitoliCodaStatic || bTitoliCodaScrolling) return;
|
||||
|
||||
if (bDialogActive) {
|
||||
obj = init.Anim[TimeAnim].obj;
|
||||
if (obj == ocCURPLAYER)
|
||||
Player->Mesh->ExpressionFrame = VisemaTimeRecon(TheTime - LastTextTime);
|
||||
else if ((obj >= ocDARRELL) && (obj <= ocLASTCHAR) && (obj) && (Character[obj]->Mesh))
|
||||
Character[obj]->Mesh->ExpressionFrame = VisemaTimeRecon(TheTime - LastTextTime);
|
||||
}
|
||||
|
||||
lines = (uint16)CheckText(game._fonts, (uint16)game._renderer->rFitY((int32)TheString.dx), TheString.text);
|
||||
for (i = 0; i < lines; i++) {
|
||||
dx = (TheString.dx - (TextLen(game._fonts, TextLines[i], 0) * SCREEN_RES_X) / game._renderer->rFitX(SCREEN_RES_X)) / 2;
|
||||
obj = init.Anim[TimeAnim].obj;
|
||||
color = WHITE_FONT;
|
||||
if ((obj >= ocCUOCO) && (obj <= ocCURPLAYER)) {
|
||||
switch (obj) {
|
||||
case ocNOTAIO:
|
||||
case ocSUPERVISORE:
|
||||
case ocCUOCO:
|
||||
color = RED_FONT;
|
||||
break;
|
||||
case ocVALENCIA:
|
||||
case ocCHIRURGO:
|
||||
case ocGIARDINIERE:
|
||||
color = GREEN_FONT;
|
||||
break;
|
||||
case ocKRENN:
|
||||
case ocOROLOGIAIO:
|
||||
case ocVICTORIA:
|
||||
color = CYAN_FONT;
|
||||
break;
|
||||
case ocMOORE:
|
||||
case ocMOOREBUCATO:
|
||||
case ocDUKES:
|
||||
case ocTRADUTTORE:
|
||||
case ocCUSTODE:
|
||||
color = MAGENTA_FONT;
|
||||
break;
|
||||
case ocCORONA:
|
||||
case ocMOGLIESUPERVISORE:
|
||||
case ocMOGLIE_KIMONO:
|
||||
case ocSERVETTA:
|
||||
color = YELLOW_FONT;
|
||||
break;
|
||||
case ocVECCHIO:
|
||||
case ocCACCIATORE:
|
||||
case ocCACCIATOREMALPRESO:
|
||||
case ocDOMESTICA:
|
||||
color = GRAY_FONT;
|
||||
break;
|
||||
case ocDARRELL:
|
||||
case ocDARRELLALETTO:
|
||||
case ocCURPLAYER:
|
||||
default:
|
||||
color = WHITE_FONT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
game._renderer->_2dStuff.displayDDText(TextLines[i], FontKind::Standard, color, TheString.x + dx, TheString.y + i * 12, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------06/04/98 10.34-------------------
|
||||
* PaintInventory
|
||||
* --------------------------------------------------*/
|
||||
void PaintInventory(WGame &game) {
|
||||
int32 a, ci;
|
||||
Init &init = game.init;
|
||||
Renderer &renderer = *game._renderer;
|
||||
|
||||
if ((InvStatus & INV_ON) || ((bT2DActive == tOPTIONS) && !bShowOnlyLoadWindow)) {
|
||||
if (bT2DActive != tOPTIONS) {
|
||||
DisplayD3DRect(renderer, 27, 77, 188, 490, 18, 25, 18, 128);
|
||||
DisplayD3DRect(renderer, 13, 124, 14, 49, 18, 25, 18, 128);
|
||||
DisplayD3DRect(renderer, 215, 472, 12, 50, 18, 25, 18, 128);
|
||||
renderer._2dStuff.displayDDBitmap(Console1, 3, 73, 0, 0, 0, 0);
|
||||
|
||||
if (InvLen[CurPlayer] > MAX_SHOWN_ICONS) {
|
||||
if (InvBase[CurPlayer] > 0)
|
||||
renderer._2dStuff.displayDDBitmap(ConsoleFrecciaSu, 3 + 14, 73 + 66, 0, 0, 0, 0);
|
||||
|
||||
if (InvBase[CurPlayer] < (InvLen[CurPlayer] - MAX_SHOWN_ICONS))
|
||||
renderer._2dStuff.displayDDBitmap(ConsoleFrecciaGiu, 3 + 206, 73 + 416, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((InvStatus & INV_MODE1) && PlayerCanCall(game._gameVars)) {
|
||||
if (CurPlayer == VICTORIA)
|
||||
renderer._2dStuff.displayDDBitmap(Console5, 22, 13, 0, 0, 0, 0);
|
||||
else
|
||||
renderer._2dStuff.displayDDBitmap(Console6, 22, 13, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if ((InvStatus & INV_MODE2) || (bT2DActive == tOPTIONS)) {
|
||||
int ox;
|
||||
|
||||
if (bT2DActive == tOPTIONS) {
|
||||
ox = 192;
|
||||
console_3_4_xoffs = -94;
|
||||
} else {
|
||||
ox = 0;
|
||||
console_3_4_xoffs = 0;
|
||||
}
|
||||
|
||||
if (CurPlayer == DARRELL)
|
||||
renderer._2dStuff.displayDDBitmap(Console3, 22 + console_3_4_xoffs, 13, ox, 0, 0, 0);
|
||||
else
|
||||
renderer._2dStuff.displayDDBitmap(Console4, 22 + console_3_4_xoffs, 13, ox, 0, 0, 0);
|
||||
|
||||
if (!PlayerCanSave())
|
||||
renderer._2dStuff.displayDDBitmap(ConsoleNoSave, 227 + 22 + console_3_4_xoffs, 13, 0, 0, 0, 0);
|
||||
|
||||
if ((bT2DActive != tOPTIONS) && (!PlayerCanSwitch(game._gameVars, 0))) {
|
||||
if (CurPlayer == DARRELL)
|
||||
renderer._2dStuff.displayDDBitmap(ConsoleNoSwitchDar, 61 + 22 + console_3_4_xoffs, 13, 0, 0, 0, 0);
|
||||
else
|
||||
renderer._2dStuff.displayDDBitmap(ConsoleNoSwitchVic, 61 + 22 + console_3_4_xoffs, 13, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (bT2DActive != tOPTIONS) {
|
||||
for (a = 0; a < MAX_SHOWN_ICONS; a++) {
|
||||
if ((ci = Inv[CurPlayer][InvBase[CurPlayer] + a])) {
|
||||
if (CurInvObj == ci)
|
||||
renderer._2dStuff.displayDDText(ObjName[init.InvObj[ci].name], FontKind::Standard, RED_FONT, INV_MARG_SX, INV_MARG_UP + ICON_DY * a, 0, 0, 0, 0);
|
||||
else
|
||||
renderer._2dStuff.displayDDText(ObjName[init.InvObj[ci].name], FontKind::Standard, WHITE_FONT, INV_MARG_SX, INV_MARG_UP + ICON_DY * a, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((bUseWith & UW_ON) && (bUseWith & UW_USEDI)) {
|
||||
DisplayD3DRect(renderer, game._gameRect._useIconRect.x1 + 3, game._gameRect._useIconRect.y1 + 3, 63, 63, 22, 31, 22, 75);
|
||||
renderer._2dStuff.displayDDBitmap(IconsPics[UseWith[USED]], game._gameRect._useIconRect.x1 + 3, game._gameRect._useIconRect.y1 + 3, 0, 0, 0, 0);
|
||||
renderer._2dStuff.displayDDBitmap(Console2, game._gameRect._useIconRect.x1, game._gameRect._useIconRect.y1, 0, 0, 0, 0);
|
||||
}
|
||||
PaintDialog(game);
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
41
engines/watchmaker/ll/ll_string.h
Normal file
41
engines/watchmaker/ll/ll_string.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* 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_LL_STRING_H
|
||||
#define WATCHMAKER_LL_STRING_H
|
||||
|
||||
#include "watchmaker/types.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
class WGame;
|
||||
|
||||
void ClearText();
|
||||
void Text(uint16 x, uint16 y, uint16 dx, char *text);
|
||||
class Fonts;
|
||||
uint16 TextLen(Fonts &fonts, char *sign, uint16 num);
|
||||
void PaintInventory(WGame &game);
|
||||
void PaintText(WGame &game);
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_STRING_H
|
||||
163
engines/watchmaker/ll/ll_system.cpp
Normal file
163
engines/watchmaker/ll/ll_system.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
/* 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 "common/substream.h"
|
||||
#include "common/archive.h"
|
||||
#include "watchmaker/ll/ll_system.h"
|
||||
#include "watchmaker/types.h"
|
||||
#include "watchmaker/utils.h"
|
||||
#include "watchmaker/windows_hacks.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
char bUsingFastFile = 0;
|
||||
|
||||
char bForceNOFastFile = 0; // forza a non utilizzare il FastFile, nonostante questo sia attivo
|
||||
char bForceNOFastFile_bUsingFastFile_backup = 0; //valore precedente la chiamata di ForceNOFastFile
|
||||
|
||||
//------------------------- Memory Functions -------------------------------
|
||||
|
||||
//..........................................................................
|
||||
void *t3dMalloc(uint32 n) {
|
||||
uint32 *res;
|
||||
|
||||
if (!(res = static_cast<uint32 *>(malloc(n))))
|
||||
warning("t3dMalloc: Can't alloc %d bytes", n);
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
void *t3dCalloc(uint32 n) {
|
||||
uint32 *res;
|
||||
|
||||
if (!(res = static_cast<uint32 *>(calloc(n, 1))))
|
||||
warning("t3dCalloc: Can't alloc %d bytes", n);
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
void t3dFree(void *p) {
|
||||
if (!p) return;
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
//------------------------- Time Functions ---------------------------------
|
||||
|
||||
//..........................................................................
|
||||
void t3dStartTime() {
|
||||
warning("STUBBED t3dStartTime");
|
||||
#if 0
|
||||
timeGetDevCaps(&tc, sizeof(tc));
|
||||
timeBeginPeriod(tc.wPeriodMin);
|
||||
srand((unsigned)time(NULL));
|
||||
#endif
|
||||
}
|
||||
|
||||
void t3dEndTime() {
|
||||
warning("STUBBED t3dEndTime");
|
||||
#if 0
|
||||
timeEndPeriod(tc.wPeriodMin);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32 t3dReadTime() {
|
||||
return (timeGetTime());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//------------------------- File I/O Functions -----------------------------
|
||||
|
||||
bool t3dFastFileInit(const char *name) {
|
||||
warning("STUBBED t3dFastFileInit");
|
||||
#if 0
|
||||
bUsingFastFile = FastFileInit(name);
|
||||
return (BOOL)(bUsingFastFile);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void t3dForceNOFastFile(char valore) {
|
||||
if (valore) {
|
||||
bForceNOFastFile_bUsingFastFile_backup = bUsingFastFile;
|
||||
bUsingFastFile = 0;
|
||||
} else bUsingFastFile = bForceNOFastFile_bUsingFastFile_backup;
|
||||
}
|
||||
|
||||
int t3dAccessFile(char *name) {
|
||||
error("STUBBED: t3dAccessFile\n");
|
||||
#if 0
|
||||
FILE *tempFile = nullptr;
|
||||
if (bUsingFastFile) tempFile = (FILE *)FastFileOpen(name);
|
||||
else tempFile = fopen(name, "rb");
|
||||
|
||||
if (tempFile == NULL)
|
||||
return 0;
|
||||
|
||||
if (bUsingFastFile) FastFileClose((LPFILEHANDLE)tempFile);
|
||||
else fclose(tempFile);
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool t3dGetFileDate(uint32 *date, uint32 *time, const char *name) {
|
||||
warning("TODO: t3dGetFileDate is currently super-inefficient: %s", name);
|
||||
*date = 0;
|
||||
*time = 0;
|
||||
return checkFileExists(name);
|
||||
}
|
||||
|
||||
Common::Path adjustPath(const Common::String &path) {
|
||||
Common::Path adjustedPath;
|
||||
if (path.hasPrefix("./")) {
|
||||
adjustedPath = Common::Path(path.substr(2, path.size()));
|
||||
} else {
|
||||
adjustedPath = Common::Path(path);
|
||||
}
|
||||
return adjustedPath;
|
||||
}
|
||||
|
||||
bool checkFileExists(const Common::String &filename) {
|
||||
Common::Path adjustedPath = adjustPath(filename);
|
||||
|
||||
return SearchMan.hasFile(adjustedPath);
|
||||
}
|
||||
|
||||
Common::SharedPtr<Common::SeekableReadStream> openFile(const Common::String &filename, int offset, int size) {
|
||||
Common::Path adjustedPath = adjustPath(filename);
|
||||
|
||||
Common::SeekableReadStream *file = SearchMan.createReadStreamForMember(adjustedPath);
|
||||
|
||||
if (offset != 0 || size != -1) {
|
||||
if (size == -1) {
|
||||
size = file->size();
|
||||
}
|
||||
assert(size <= file->size());
|
||||
assert(offset >= 0 && offset <= file->size());
|
||||
file = new Common::SeekableSubReadStream(file, offset, offset + size, DisposeAfterUse::YES);
|
||||
}
|
||||
return Common::SharedPtr<Common::SeekableReadStream>(file);
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
67
engines/watchmaker/ll/ll_system.h
Normal file
67
engines/watchmaker/ll/ll_system.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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_LL_SYSTEM_H
|
||||
#define WATCHMAKER_LL_SYSTEM_H
|
||||
|
||||
#include "watchmaker/types.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/ptr.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
//------------------------- Memory Functions -------------------------------
|
||||
void *t3dMalloc(uint32 n);
|
||||
void *t3dCalloc(uint32 n);
|
||||
|
||||
template<typename T>
|
||||
T *t3dMalloc(uint32 num) {
|
||||
return static_cast<T *>(t3dMalloc(sizeof(T) * num));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *t3dCalloc(uint32 num) {
|
||||
// HACK: There are a few places where we actually access the first element even when zero-sized
|
||||
// those need to be fixed, but for now, let's pad.
|
||||
if (num == 0) {
|
||||
num++;
|
||||
}
|
||||
return (T *)t3dCalloc(sizeof(T) * num);
|
||||
}
|
||||
void *t3dRealloc(void *p, uint32 additionalBytes);
|
||||
void t3dFree(void *p);
|
||||
|
||||
//------------------------- Time Functions ---------------------------------
|
||||
void t3dStartTime();
|
||||
void t3dEndTime();
|
||||
uint32 t3dReadTime();
|
||||
|
||||
bool t3dFastFileInit(const char *name);
|
||||
void t3dForceNOFastFile(char valore);
|
||||
int t3dAccessFile(char *name);
|
||||
bool t3dGetFileDate(uint32 *date, uint32 *time, const char *name);
|
||||
bool checkFileExists(const Common::String &filename);
|
||||
Common::SeekableReadStream *resolveFile(const char *path);
|
||||
Common::SharedPtr<Common::SeekableReadStream> openFile(const Common::String &filename, int offset = 0, int size = -1);
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_SYSTEM_H
|
||||
679
engines/watchmaker/ll/ll_util.cpp
Normal file
679
engines/watchmaker/ll/ll_util.cpp
Normal file
@@ -0,0 +1,679 @@
|
||||
/* 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/ll/ll_util.h"
|
||||
#include "watchmaker/ll/ll_anim.h"
|
||||
#include "watchmaker/ll/ll_diary.h"
|
||||
#include "watchmaker/ll/ll_mesh.h"
|
||||
#include "watchmaker/ll/ll_regen.h"
|
||||
#include "watchmaker/3d/animation.h"
|
||||
#include "watchmaker/3d/geometry.h"
|
||||
#include "watchmaker/3d/loader.h"
|
||||
#include "watchmaker/3d/math/llmath.h"
|
||||
#include "watchmaker/3d/t3d_mesh.h"
|
||||
#include "watchmaker/classes/do_camera.h"
|
||||
#include "watchmaker/classes/do_operate.h"
|
||||
#include "watchmaker/classes/do_system.h"
|
||||
#include "watchmaker/define.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
#include "watchmaker/main.h"
|
||||
#include "watchmaker/message.h"
|
||||
#include "watchmaker/renderer.h"
|
||||
#include "watchmaker/schedule.h"
|
||||
#include "watchmaker/sysdef.h"
|
||||
#include "watchmaker/t2d/t2d_internal.h"
|
||||
#include "watchmaker/types.h"
|
||||
#include "watchmaker/utils.h"
|
||||
#include "watchmaker/walk/act.h"
|
||||
#include "watchmaker/windows_hacks.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
/* -----------------17/03/98 16.19-------------------
|
||||
* LinkObjToMesh
|
||||
* --------------------------------------------------*/
|
||||
uint16 LinkObjToMesh(WGame &game, t3dMESH *m, uint8 op) {
|
||||
uint16 a, b, c, i;
|
||||
t3dBODY *cr;
|
||||
int16 n;
|
||||
Init &init = game.init;
|
||||
|
||||
if (!m) return (oNULL);
|
||||
|
||||
NextPortalObj = oNULL;
|
||||
// Controllo tra gli altri personaggi
|
||||
for (c = ocCUOCO; c <= ocLASTCHAR; c++) {
|
||||
for (b = 0; b < MAX_OBJ_MESHLINKS; b++)
|
||||
if (Character[c] && Character[c]->Mesh)
|
||||
if ((!init.Obj[c].meshLinkIsEmpty(b)) && (m->name.equalsIgnoreCase(init.Obj[c].getMeshLink(b))))
|
||||
return (c);
|
||||
}
|
||||
|
||||
// Controllo in stanza attuale
|
||||
for (a = 0; a < MAX_OBJS_IN_ROOM; a++) {
|
||||
if (!(c = game.getCurRoom().objects[a])) continue;
|
||||
if ((init.Obj[c].flags & ON) && !(init.Obj[c].flags & HIDE) &&
|
||||
(((bFirstPerson) && !(init.Obj[c].flags & HIDEIN1ST)) ||
|
||||
(!(bFirstPerson) && !(init.Obj[c].flags & HIDEIN3RD)))) {
|
||||
for (b = 0; b < MAX_OBJ_MESHLINKS; b++)
|
||||
if ((!init.Obj[c].meshLinkIsEmpty(b)) && (m->name.equalsIgnoreCase(init.Obj[c].getMeshLink(b))))
|
||||
for (i = 0; i < t3dCurRoom->NumMeshes(); i++)
|
||||
if ((m->name.equalsIgnoreCase(t3dCurRoom->MeshTable[i].name)))
|
||||
return (c);
|
||||
}
|
||||
}
|
||||
|
||||
// Se non trova controlla in portali vicino
|
||||
for (i = 0; i < t3dCurRoom->NumMeshes(); i++) {
|
||||
if ((cr = t3dCurRoom->MeshTable[i].PortalList) != nullptr) {
|
||||
NextPortalAnim = aNULL;
|
||||
n = getRoomFromStr(init, cr->name);
|
||||
|
||||
if ((op == ME_MRIGHT) || (op == ME_MLEFT)) {
|
||||
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((const char *)init.Anim[b].RoomName.rawArray())) {
|
||||
NextPortalAnim = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (a = 0; a < MAX_OBJS_IN_ROOM; a++) {
|
||||
if (!(c = init.Room[n].objects[a])) continue;
|
||||
if ((init.Obj[c].flags & ON) && !(init.Obj[c].flags & HIDE) &&
|
||||
(((bFirstPerson) && !(init.Obj[c].flags & HIDEIN1ST)) ||
|
||||
(!(bFirstPerson) && !(init.Obj[c].flags & HIDEIN3RD)))) {
|
||||
for (b = 0; b < MAX_OBJ_MESHLINKS; b++) {
|
||||
if ((!init.Obj[c].meshLinkIsEmpty(b)) && m->name.equalsIgnoreCase(init.Obj[c].getMeshLink(b))) {
|
||||
if ((op == ME_MRIGHT) || (op == ME_MLEFT))
|
||||
NextPortalObj = c;
|
||||
return (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((op == ME_MRIGHT) || (op == ME_MLEFT)) {
|
||||
for (a = 0; a < cr->NumMeshes(); a++) {
|
||||
if (m->name.equalsIgnoreCase(cr->MeshTable[a].name)) {
|
||||
NextPortalObj = oNEXTPORTAL;
|
||||
return (oNULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((op == ME_MRIGHT) || (op == ME_MLEFT))
|
||||
NextPortalAnim = aNULL;
|
||||
return (oNULL);
|
||||
}
|
||||
|
||||
|
||||
/* -----------------16/04/98 11.33-------------------
|
||||
* WhatIObj
|
||||
* --------------------------------------------------*/
|
||||
int32 WhatObj(WGame &game, int32 mx, int32 my, uint8 op) {
|
||||
t3dMESH *pm, *CurMesh;
|
||||
t3dF32 minz;
|
||||
int32 ret;
|
||||
uint16 n;
|
||||
|
||||
op = ME_MRIGHT;
|
||||
|
||||
ret = 0;
|
||||
CurMesh = nullptr;
|
||||
FloorHit = 0;
|
||||
minz = 999999999.9f;
|
||||
for (n = 0; n < t3d_NumMeshesVisible; n++) { // Prima cerca in mesh associate
|
||||
if (!(pm = t3d_VisibleMeshes[n])) continue;
|
||||
|
||||
if ((pm->BBoxAverageZ < minz) && ((pm->Flags & T3D_MESH_RAYBAN) || (LinkObjToMesh(game, pm, 0)))) {
|
||||
minz = pm->BBoxAverageZ;
|
||||
CurMesh = pm;
|
||||
}
|
||||
}
|
||||
if (CurMesh == nullptr) { // Poi cerca nelle altre
|
||||
for (n = 0; n < t3d_NumMeshesVisible; n++) {
|
||||
if (!(pm = t3d_VisibleMeshes[n])) continue;
|
||||
|
||||
if (!(pm->Flags & T3D_MESH_NOBOUNDBOX) && (pm->BBoxAverageZ < minz)) {
|
||||
minz = pm->BBoxAverageZ;
|
||||
CurMesh = pm;
|
||||
}
|
||||
}
|
||||
|
||||
if (t3dCheckWithFloor() < minz)
|
||||
FloorHit = 1;
|
||||
}
|
||||
|
||||
memset(ObjectUnderCursor, 0, 400);
|
||||
if (CurMesh || (FloorHit)) {
|
||||
if (!FloorHit) {
|
||||
Common::strlcpy(ObjectUnderCursor, CurMesh->name.c_str(), 400);
|
||||
ret = LinkObjToMesh(game, CurMesh, op);
|
||||
if (NextPortalObj)
|
||||
snprintf(ObjectUnderCursor, 400, "NextPortalObj -> %s", CurMesh->name.c_str());
|
||||
|
||||
mPos.x = CurMesh->Intersection.x;
|
||||
mPos.y = CurMesh->Intersection.y;
|
||||
mPos.z = CurMesh->Intersection.z;
|
||||
} else {
|
||||
if (CurMesh)
|
||||
snprintf(ObjectUnderCursor, 400, "Floor Hit -> %s", CurMesh->name.c_str());
|
||||
else
|
||||
Common::strlcpy(ObjectUnderCursor, "Floor Hit", 400);
|
||||
LinkObjToMesh(game, CurMesh, op);
|
||||
if (NextPortalObj)
|
||||
snprintf(ObjectUnderCursor, 400, "NextPortalObj -> Floor Hit -> %s", CurMesh->name.c_str());
|
||||
|
||||
mPos.x = FloorHitCoords.x;
|
||||
mPos.y = FloorHitCoords.y;
|
||||
mPos.z = FloorHitCoords.z;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* -----------------13/07/98 12.05-------------------
|
||||
* getRoomFromStr
|
||||
* --------------------------------------------------*/
|
||||
int16 getRoomFromStr(Init &init, const Common::String &s) {
|
||||
auto end = s.findLastOf(".-");
|
||||
if (end == s.npos) {
|
||||
end = s.size() - 1;
|
||||
}
|
||||
auto start = s.findLastOf("\\/");
|
||||
if (start == s.npos) {
|
||||
start = 0;
|
||||
}
|
||||
Common::String str = s.substr(start, end - start);
|
||||
|
||||
for (int a = 0; a < MAX_ROOMS; a++)
|
||||
if (str.equalsIgnoreCase((const char *)init.Room[a].name))
|
||||
return a;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* -----------------19/01/99 11.03-------------------
|
||||
* CreateTooltipBitmap
|
||||
* --------------------------------------------------*/
|
||||
int32 CreateTooltipBitmap(Renderer &renderer, char *tooltip, FontColor color, uint8 r, uint8 g, uint8 b) {
|
||||
int32 dimx, dimy, enlarge = 5;
|
||||
char info[100];
|
||||
|
||||
if (!tooltip || !strcmp(tooltip, "")) return -1;
|
||||
FontKind font = FontKind::Standard;
|
||||
|
||||
renderer._fonts->getTextDim(tooltip, font, &dimx, &dimy);
|
||||
dimx += renderer.rFitX(enlarge * 2);
|
||||
dimy += renderer.rFitY(enlarge * 2);
|
||||
|
||||
int32 surf = rCreateSurface(dimx, dimy, 0);
|
||||
if (surf <= 0) return -1;
|
||||
|
||||
Common::strlcpy(info, "tooltip: ", 400);
|
||||
strncat(info, tooltip, 15);
|
||||
rSetBitmapName(surf, info);
|
||||
renderer.clearBitmap(surf, 0, 0, dimx, dimy, 18, 18, 18); // Bordino nero
|
||||
renderer.clearBitmap(surf, 1, 1, dimx - 2, dimy - 2, r, g, b); // Sfondo colorato
|
||||
renderer.printText(tooltip, surf, font, color, (uint16)renderer.rFitX(enlarge), (uint16)renderer.rFitY(enlarge));
|
||||
return surf;
|
||||
}
|
||||
|
||||
/* -----------------27/10/98 15.31-------------------
|
||||
* LoadDDBitmap
|
||||
* --------------------------------------------------*/
|
||||
int32 LoadDDBitmap(WGame &game, const char *n, uint8 flags) {
|
||||
auto name = game.workDirs.join(game.workDirs._miscDir, n);
|
||||
|
||||
int rez = rLoadBitmapImage(game, name.c_str(), (uint8)(rBITMAPSURFACE | rSURFACEFLIP | flags));
|
||||
|
||||
if (rez <= 0) {
|
||||
warning("Failed to load %s. Quitting ...", name.c_str());
|
||||
CloseSys(game);
|
||||
}
|
||||
|
||||
return (rez);
|
||||
}
|
||||
|
||||
/* -----------------13/05/98 10.59-------------------
|
||||
* LinkMeshToStr
|
||||
* --------------------------------------------------*/
|
||||
t3dMESH *LinkMeshToStr(Init &init, const Common::String &str) {
|
||||
// TODO: Refactor the callsites:
|
||||
return _vm->_roomManager->linkMeshToStr(init, str);
|
||||
}
|
||||
|
||||
/* -----------------18/12/00 18.02-------------------
|
||||
* UpdateRoomInfo
|
||||
* --------------------------------------------------*/
|
||||
void UpdateRoomInfo(WGame &game) {
|
||||
uint8 cr;
|
||||
|
||||
if (!t3dCurRoom) return;
|
||||
|
||||
cr = (uint8)getRoomFromStr(game.init, t3dCurRoom->name);
|
||||
if (!cr) return;
|
||||
|
||||
// se <20> diversa dalla precedente...
|
||||
if (strcmp(RoomInfo.name, game.init.Room[cr].desc)) {
|
||||
game._messageSystem.removeEvent_bparam(EventClass::MC_SYSTEM, ME_STARTEFFECT, EFFECT_ROOMINFO);
|
||||
game._messageSystem.removeEvent_bparam(EventClass::MC_SYSTEM, ME_CONTINUEEFFECT, EFFECT_ROOMINFO);
|
||||
game._messageSystem.removeEvent_bparam(EventClass::MC_SYSTEM, ME_STOPEFFECT, EFFECT_ROOMINFO);
|
||||
_vm->_messageSystem.doEvent(EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_DEFAULT, FRAME_PER_SECOND * 3, 0, EFFECT_ROOMINFO, nullptr, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------13/10/98 15.00-------------------
|
||||
* UpdateRoomVisibility
|
||||
* --------------------------------------------------*/
|
||||
void UpdateRoomVisibility(WGame &game) {
|
||||
uint32 i, j;
|
||||
t3dBODY *pr;
|
||||
uint8 cr;
|
||||
|
||||
Init &init = game.init;
|
||||
|
||||
if (!t3dCurRoom) return;
|
||||
|
||||
// Leva il flag visibile a tutte le stanze
|
||||
for (i = 0; i < MAX_ROOMS; i++) {
|
||||
if (init.Room[i].flags & ROOM_VISIBLE)
|
||||
init.Room[i].flags |= ROOM_OLDVISIBLE;
|
||||
init.Room[i].flags &= ~ROOM_VISIBLE;
|
||||
}
|
||||
|
||||
// Aggiunge room attuale
|
||||
cr = (uint8)getRoomFromStr(init, t3dCurRoom->name);
|
||||
if (!cr) {
|
||||
init.Room[cr].flags |= ROOM_VISIBLE;
|
||||
}
|
||||
|
||||
if (bShowRoomDescriptions)
|
||||
UpdateRoomInfo(game);
|
||||
// if( !( Room[cr].flags & ROOM_OLDVISIBLE ) )
|
||||
// Event( EventClass::MC_SYSTEM, ME_STARTEFFECT, MP_DEFAULT, FRAME_PER_SECOND*3, 0, EFFECT_ROOMINFO, NULL, NULL, NULL );
|
||||
|
||||
// Prima volta che entra nella r45
|
||||
if ((cr == r45) && !(init.Room[cr].flags & ROOM_VISITED))
|
||||
init.Obj[o46SECONDODIAGRAMMA].flags |= EXTRA;
|
||||
|
||||
if (!(LoaderFlags & T3D_DEBUGMODE)) {
|
||||
// Prima volta che entra nella r46
|
||||
if ((cr == r46) && !(init.Room[cr].flags & ROOM_VISITED))
|
||||
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR212, 0, 0, NULL, NULL, NULL);
|
||||
// Prima volta che entra nella r47
|
||||
if ((cr == r47) && !(init.Room[cr].flags & ROOM_VISITED))
|
||||
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR471, 0, 0, NULL, NULL, NULL);
|
||||
// Prima volta che entra nella r48
|
||||
if ((cr == r48) && !(init.Room[cr].flags & ROOM_VISITED))
|
||||
_vm->_messageSystem.doEvent(EventClass::MC_DIALOG, ME_DIALOGSTART, MP_DEFAULT, dR481, 0, 0, NULL, NULL, NULL);
|
||||
}
|
||||
#if 0
|
||||
// Se ha cambiato stanza cambia anche l'environment
|
||||
sSetEnvironment(init.Room[cr].env);
|
||||
// Se ha cambiato stanza cambia anche la musica
|
||||
if (!(LoaderFlags & T3D_NOMUSIC) && (init.Room[cr].music != nNULL))
|
||||
PlayMusic(init.Room[cr].music, 3000, 3000);
|
||||
#endif
|
||||
init.Room[cr].flags |= ROOM_VISITED;
|
||||
|
||||
// Aggiorna oggetti speciali
|
||||
UpdateSpecial(game, cr);
|
||||
|
||||
// Cerca nelle stanze visbili con ricorsione 2
|
||||
for (i = 0; i < t3dCurRoom->NumMeshes(); i++) {
|
||||
if (!(pr = t3dCurRoom->MeshTable[i].PortalList) || (t3dCurRoom->MeshTable[i].Flags & T3D_MESH_NOPORTALCHECK))
|
||||
continue;
|
||||
|
||||
cr = (uint8)getRoomFromStr(init, pr->name);
|
||||
if (!cr) {
|
||||
init.Room[cr].flags |= ROOM_VISIBLE;
|
||||
}
|
||||
|
||||
for (j = 0; j < pr->NumMeshes(); j++) {
|
||||
if ((pr->MeshTable[j].PortalList) && !(pr->MeshTable[j].Flags & T3D_MESH_NOPORTALCHECK)) {
|
||||
cr = (uint8)getRoomFromStr(init, pr->MeshTable[j].PortalList->name);
|
||||
if (!cr) {
|
||||
init.Room[cr].flags |= ROOM_VISIBLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Accende le animazioni di background delle stanze che si vedono
|
||||
// DebugFile("RoomVisibility %s",t3dCurRoom->Name);
|
||||
for (i = 0; i < MAX_ROOMS; i++) {
|
||||
if (init.Room[i].flags & ROOM_VISIBLE) {
|
||||
// Aggiunge effetti di background
|
||||
for (j = 0; j < MAX_SOUNDS_IN_ROOM; j++)
|
||||
if ((init.Room[i].sounds[j]) && (init.Sound[init.Room[i].sounds[j]].flags & SOUND_ON)) {
|
||||
//se la pompa non e' attivata non attivo nemmeno il suono
|
||||
if ((init.Room[i].sounds[j] == wPOMPA) && (init.Obj[o2GOFF].flags & ON)) continue;
|
||||
|
||||
//di notte nella r1c la fontana e' spenta
|
||||
if ((init.Room[i].sounds[j] == wFONTANA) &&
|
||||
(((t3dCurTime >= 1300) && (t3dCurTime <= 1310)) || (t3dCurTime >= 1800))
|
||||
) continue;
|
||||
#if 0
|
||||
StartSound(init.Room[i].sounds[j]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// DebugFile("%d: %d %s",i,RoomVisibility[i],Room[RoomVisibility[i]].name);
|
||||
for (j = 0; j < MAX_ANIMS_IN_ROOM; j++)
|
||||
if ((init.Room[i].anims[j]) && (init.Anim[init.Room[i].anims[j]].flags & ANIM_ON))
|
||||
if (!(init.Anim[init.Room[i].anims[j]].active)) {
|
||||
if ((init.Anim[init.Room[i].anims[j]].obj != aNULL) && (Character[init.Anim[init.Room[i].anims[j]].obj])) {
|
||||
Character[init.Anim[init.Room[i].anims[j]].obj]->Flags &= ~T3D_CHARACTER_HIDE;
|
||||
CharSetPosition(init.Anim[init.Room[i].anims[j]].obj, init.Anim[init.Room[i].anims[j]].pos, (const char*)init.Anim[init.Room[i].anims[j]].RoomName.rawArray());
|
||||
}
|
||||
DebugLogWindow("Staring Bkg Anim %d | Obj %d Pos %d", init.Room[i].anims[j], init.Anim[init.Room[i].anims[j]].obj, init.Anim[init.Room[i].anims[j]].pos);
|
||||
StartAnim(game, init.Room[i].anims[j]);
|
||||
}
|
||||
|
||||
StartDiary(game, i, NULL);
|
||||
}
|
||||
// Spegne le animazioni delle stanze che non si vedono piu'
|
||||
else if (init.Room[i].flags & ROOM_OLDVISIBLE) {
|
||||
// Leva effetti di background
|
||||
for (j = 0; j < MAX_SOUNDS_IN_ROOM; j++) {
|
||||
#if 0
|
||||
if ((init.Room[i].sounds[j]) && (init.Sound[init.Room[i].sounds[j]].flags & SOUND_ON))
|
||||
StopSound(init.Room[i].sounds[j]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Se non e' piu' in vista
|
||||
for (j = 0; j < MAX_ANIMS_IN_ROOM; j++)
|
||||
if ((init.Room[i].anims[j]) && (init.Anim[init.Room[i].anims[j]].flags & ANIM_ON)) {
|
||||
if (Character[init.Anim[init.Room[i].anims[j]].obj]) Character[init.Anim[init.Room[i].anims[j]].obj]->Flags |= T3D_CHARACTER_HIDE;
|
||||
StopAnim(game, init.Room[i].anims[j]);
|
||||
}
|
||||
init.Room[i].flags &= ~ROOM_OLDVISIBLE;
|
||||
|
||||
StopDiary(game, i, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------12/06/00 10.12-------------------
|
||||
* SetBndLevel
|
||||
* --------------------------------------------------*/
|
||||
bool SetBndLevel(WGame &game, const char *roomname, int32 lev) {
|
||||
t3dBODY *t = nullptr;
|
||||
if (roomname && (roomname[0] != '\0')) {
|
||||
_vm->_roomManager->getRoomIfLoaded(roomname);
|
||||
} else t = t3dCurRoom;
|
||||
|
||||
if (!t) {
|
||||
DebugLogFile("SETBND FAILED: %s, %d", roomname, lev);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lev >= t->NumLevels) {
|
||||
DebugLogFile("!!!! BND Lev too high: %s max %d ask %d", t->name.c_str(), t->NumLevels, lev);
|
||||
return false;
|
||||
}
|
||||
|
||||
t->CurLevel = (int16)lev;
|
||||
if (t == t3dCurRoom)
|
||||
CurFloorY = t->PanelHeight[t->CurLevel];
|
||||
|
||||
_vm->addMeshModifier(t->name, MM_SET_BND_LEVEL, &lev);
|
||||
UpdateRoomVisibility(game);
|
||||
|
||||
DebugLogFile("SETBND: %s, %d", t->name.c_str(), lev);
|
||||
|
||||
if (Player) {
|
||||
Player->Walk.CurPanel = -1;
|
||||
Player->Walk.OldPanel = -1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* -----------------17/12/00 17.59-------------------
|
||||
* PrintLoading
|
||||
* --------------------------------------------------*/
|
||||
void PrintLoading() {
|
||||
warning("STUBBED: PrintLoading");
|
||||
#if 0
|
||||
// Stampa la scritta loading
|
||||
|
||||
DisplayDDBitmap(LoadingImage, 800 - 103 - 4, 600 - 85 - 4, 0, 0, 0, 0);
|
||||
Add2DStuff();
|
||||
rShowFrame();
|
||||
|
||||
// rBlitSetStandardFont( StandardFont.Color[WHITE_FONT], StandardFont.Table );
|
||||
// DebugQuick(10,-1,"Loading...");
|
||||
// rBlitSetStandardFont( 0, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* -----------------01/09/98 16.52--------------------
|
||||
* ChangeRoom
|
||||
* --------------------------------------------------*/
|
||||
void ChangeRoom(WGame &game, Common::String n, uint8 pos, int32 an) {
|
||||
t3dBODY *t;
|
||||
int32 i, j, k;
|
||||
|
||||
if (n.equalsIgnoreCase("r21.t3d"))
|
||||
n = "r21-a.t3d";
|
||||
|
||||
bFirstPerson = false;
|
||||
if (t3dCurRoom && t3dCurRoom->name.equalsIgnoreCase(n)) {
|
||||
game.UpdateAll();
|
||||
if (pos) CharSetPosition(ocCURPLAYER, pos, nullptr);
|
||||
if (an) StartAnim(game, an);
|
||||
return ;
|
||||
}
|
||||
|
||||
PrintLoading();
|
||||
|
||||
StopAllAnims(game.init);
|
||||
// StopMusic();
|
||||
|
||||
// quando si cambia piano (e quindi si cancella quello attuale e si carica il nuovo) stoppo il diario in modo che
|
||||
// se esso aveva delle modifiche da fare al piano corrente le fa subito, e non dopo quando il piano non e' piu' disponibile
|
||||
StopDiary(game, 0, 0, 0);
|
||||
|
||||
// Prima lo cerca tra le stanze in memoria
|
||||
t = _vm->_roomManager->getRoomIfLoaded(n);
|
||||
|
||||
// Se non lo trova tra le stanze in memoria
|
||||
if (!t) {
|
||||
t3dResetPipeline();
|
||||
_vm->_roomManager->releaseLoadedFiles(T3D_STATIC_SET0);
|
||||
|
||||
for (i = 0; i < T3D_MAX_CHARACTERS; i++) {
|
||||
if (Character[i]) {
|
||||
for (j = 0; j < T3D_MAX_SHADOWBOX_PER_CHAR; j++) {
|
||||
if (Character[i]->ShadowBox[j]) {
|
||||
for (k = 0; k < MAX_SHADOWS_PER_LIGHT; k++) {
|
||||
Character[i]->ShadowBox[j]->ShadowsList[k].ProjectiveTexture.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Character[i]->Walk = t3dWALK();
|
||||
}
|
||||
}
|
||||
|
||||
rReleaseAllTextures(T3D_STATIC_SET0);
|
||||
rReleaseAllBitmaps(T3D_STATIC_SET0);
|
||||
|
||||
// t3dFree( StandardFont.Table );
|
||||
ReleasePreloadedAnims();
|
||||
t3dReleaseParticles();
|
||||
|
||||
t3dCurRoom = nullptr;
|
||||
|
||||
if (!game.LoadAndSetup(n, 0)) CloseSys(game);
|
||||
PortalCrossed = t3dCurRoom;
|
||||
|
||||
ResetScreenBuffer(); //resetto in modo che la scritta di loading non faccia casini
|
||||
} else {
|
||||
ResetScreenBuffer(); //resetto in modo che la scritta di loading non faccia casini
|
||||
|
||||
t3dResetPipeline();
|
||||
t3dCurRoom = t;
|
||||
PortalCrossed = t3dCurRoom;
|
||||
t3dCurCamera = &t3dCurRoom->CameraTable[0];
|
||||
t3dVectCopy(&t3dCurCamera->Target, &Player->Mesh->Trasl);
|
||||
game._cameraMan->ResetCameraSource();
|
||||
game._cameraMan->ResetCameraTarget();
|
||||
CurFloorY = t3dCurRoom->PanelHeight[t3dCurRoom->CurLevel];
|
||||
}
|
||||
|
||||
CameraTargetObj = 0;
|
||||
CameraTargetBone = 0;
|
||||
ForcedCamera = 0;
|
||||
|
||||
game.UpdateAll();
|
||||
if (pos)
|
||||
CharSetPosition(ocCURPLAYER, pos, nullptr);
|
||||
game._cameraMan->ProcessCamera(game);
|
||||
if (an)
|
||||
StartAnim(game, an);
|
||||
}
|
||||
|
||||
/* -----------------21/08/00 15.48-------------------
|
||||
* GetBndLevel
|
||||
* --------------------------------------------------*/
|
||||
int32 GetBndLevel(char *roomname) {
|
||||
t3dBODY *t = nullptr;
|
||||
if (roomname && (roomname[0] != '\0')) {
|
||||
t = _vm->_roomManager->getRoomIfLoaded(roomname);
|
||||
} else t = t3dCurRoom;
|
||||
|
||||
if (!t) return FALSE;
|
||||
|
||||
return (int32)t->CurLevel;
|
||||
}
|
||||
|
||||
/* -----------------23/10/98 18.17-------------------
|
||||
* CheckRect
|
||||
* --------------------------------------------------*/
|
||||
bool CheckRect(Renderer &renderer, struct SRect p, int32 cmx, int32 cmy) {
|
||||
return ((cmx >= renderer.rFitX(p.x1)) && (cmx < renderer.rFitX(p.x2)) && (cmy >= renderer.rFitY(p.y1)) && (cmy < renderer.rFitY(p.y2)));
|
||||
}
|
||||
|
||||
/* -----------------03/05/99 17.31-------------------
|
||||
* DisplayD3DTriangle
|
||||
* --------------------------------------------------*/
|
||||
void DisplayD3DTriangle(Renderer &renderer, int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3, uint8 r, uint8 g, uint8 b, uint8 al) {
|
||||
int32 a;
|
||||
for (a = 0; a < MAX_D3D_TRIANGLES; a++) {
|
||||
if ((D3DTrianglesList[a].x1 == renderer.rFitX(x1)) && (D3DTrianglesList[a].y1 == renderer.rFitY(y1)) &&
|
||||
(D3DTrianglesList[a].x2 == renderer.rFitX(x2)) && (D3DTrianglesList[a].y2 == renderer.rFitY(y2)) &&
|
||||
(D3DTrianglesList[a].x3 == renderer.rFitX(x3)) && (D3DTrianglesList[a].y3 == renderer.rFitY(y3)))
|
||||
break;
|
||||
if (!D3DTrianglesList[a].x1 && !D3DTrianglesList[a].y1 && !D3DTrianglesList[a].x2 && !D3DTrianglesList[a].y2)
|
||||
break;
|
||||
}
|
||||
|
||||
if (a >= MAX_D3D_TRIANGLES) {
|
||||
warning("Too many D3D Triangles!");
|
||||
return ;
|
||||
}
|
||||
|
||||
D3DTrianglesList[a].x1 = renderer.rFitX(x1);
|
||||
D3DTrianglesList[a].y1 = renderer.rFitY(y1);
|
||||
D3DTrianglesList[a].x2 = renderer.rFitX(x2);
|
||||
D3DTrianglesList[a].y2 = renderer.rFitY(y2);
|
||||
D3DTrianglesList[a].x3 = renderer.rFitX(x3);
|
||||
D3DTrianglesList[a].y3 = renderer.rFitY(y3);
|
||||
|
||||
D3DTrianglesList[a].r = r;
|
||||
D3DTrianglesList[a].g = g;
|
||||
D3DTrianglesList[a].b = b;
|
||||
D3DTrianglesList[a].a = al;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------24/04/98 10.33-------------------
|
||||
* DisplayD3DRect
|
||||
* --------------------------------------------------*/
|
||||
void DisplayD3DRect(Renderer &renderer, int32 px, int32 py, int32 dx, int32 dy, uint8 r, uint8 g, uint8 b, uint8 al) {
|
||||
int32 a;
|
||||
for (a = 0; a < MAX_D3D_RECTS; a++) {
|
||||
if ((D3DRectsList[a].px == renderer.rFitX(px)) && (D3DRectsList[a].py == renderer.rFitY(py)) &&
|
||||
(D3DRectsList[a].dx == renderer.rFitX(dx)) && (D3DRectsList[a].dy == renderer.rFitY(dy)))
|
||||
break;
|
||||
if (!D3DRectsList[a].dx && !D3DRectsList[a].dy)
|
||||
break;
|
||||
}
|
||||
|
||||
if (a >= MAX_D3D_RECTS) {
|
||||
warning("Too many D3D Rects!");
|
||||
return ;
|
||||
}
|
||||
|
||||
D3DRectsList[a].px = renderer.rFitX(px);
|
||||
D3DRectsList[a].py = renderer.rFitY(py);
|
||||
D3DRectsList[a].dx = renderer.rFitX(px + dx) - renderer.rFitX(px);
|
||||
D3DRectsList[a].dy = renderer.rFitY(py + dy) - renderer.rFitY(py);
|
||||
|
||||
D3DRectsList[a].r = r;
|
||||
D3DRectsList[a].g = g;
|
||||
D3DRectsList[a].b = b;
|
||||
D3DRectsList[a].a = al;
|
||||
}
|
||||
|
||||
/* -----------------15/01/99 18.15-------------------
|
||||
* GetDDBitmapExtends
|
||||
* --------------------------------------------------*/
|
||||
void GetDDBitmapExtends(Renderer &renderer, struct SRect *r, struct SDDBitmap *b) {
|
||||
if (!r || !b) return ;
|
||||
r->x1 = b->px;
|
||||
r->y1 = b->py;
|
||||
// TODO: Somehow the original engine was able to handle this
|
||||
// even though rGetBitmapRealDimX used b->tnum as index
|
||||
// into gBitmapList, which becomes problematic when using
|
||||
// the upper bits for flagging. For now let's mask out
|
||||
// the high-bit.
|
||||
uint32 mask = T2D_BM_OFF ^ 0xFFFFFFFF;
|
||||
r->x2 = r->x1 + renderer.getBitmapRealDimX(b->tnum & mask);
|
||||
r->y2 = r->y1 + renderer.getBitmapRealDimY(b->tnum & mask);
|
||||
}
|
||||
|
||||
/* -----------------05/11/98 10.36-------------------
|
||||
* DebugVideo
|
||||
* --------------------------------------------------*/
|
||||
void DebugVideo(Renderer &renderer, int32 px, int32 py, const char *format, ...) {
|
||||
char str[500];
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(str, 500, format, args);
|
||||
va_end(args);
|
||||
|
||||
renderer._2dStuff.displayDDText(str, FontKind::Standard, WHITE_FONT, px, py, 0, 0, 0, 0);
|
||||
// rPrintText( str, 0, StandardFont.Color[WHITE_FONT], StandardFont.Table, px, py );
|
||||
}
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
54
engines/watchmaker/ll/ll_util.h
Normal file
54
engines/watchmaker/ll/ll_util.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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_LL_UTIL_H
|
||||
#define WATCHMAKER_LL_UTIL_H
|
||||
|
||||
#include "watchmaker/game.h"
|
||||
#include "watchmaker/globvar.h"
|
||||
#include "watchmaker/t3d.h"
|
||||
#include "watchmaker/work_dirs.h"
|
||||
#include "watchmaker/renderer.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
int32 LoadDDBitmap(WGame &game, const char *n, uint8 flags);
|
||||
void LoadFont(WGame &game, struct SFont *f, const char *n);
|
||||
void UpdateRoomVisibility(WGame &game);
|
||||
t3dMESH *LinkMeshToStr(Init &init, const Common::String &str);
|
||||
int16 getRoomFromStr(Init &init, const Common::String &s);
|
||||
void ChangeRoom(WGame &game, Common::String n, uint8 pos, int32 an);
|
||||
bool SetBndLevel(WGame &game, const char *roomname, int32 lev);
|
||||
int32 GetBndLevel(char *roomname);
|
||||
void GetDDBitmapExtends(Renderer &renderer, struct SRect *r, struct SDDBitmap *b);
|
||||
void DisplayDDBitmap(Renderer &, int32 tnum, int32 px, int32 py, int32 ox, int32 oy, int32 dx, int32 dy);
|
||||
void DisplayDDBitmap_NoFit(Renderer &renderer, int32 tnum, int32 px, int32 py, int32 ox, int32 oy, int32 dx, int32 dy);
|
||||
void UpdateRoomInfo(WGame &game);
|
||||
bool CheckRect(Renderer &renderer, struct SRect p, int32 cmx, int32 cmy);
|
||||
void DisplayD3DTriangle(Renderer &, int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3, uint8 r, uint8 g, uint8 b, uint8 al);
|
||||
void DisplayD3DRect(Renderer &, int32 px, int32 py, int32 dx, int32 dy, uint8 r, uint8 g, uint8 b, uint8 al);
|
||||
int32 CreateTooltipBitmap(Renderer &renderer, char *tooltip, FontColor color, uint8 r, uint8 g, uint8 b);
|
||||
int32 WhatObj(WGame &game, int32 mx, int32 my, uint8 op);
|
||||
void DebugVideo(Renderer &renderer, int32 px, int32 py, const char *format, ...);
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LL_UTIL_H
|
||||
Reference in New Issue
Block a user