mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-10 11:51:52 +00:00
WATCHMAKER: Move room loading to RoomManager.
This lets us remove the dependency on malloc.h. The replacement logic is not 100% perfect, as the original logic will resize arrays to load additional t3dBODY-structs, and those would then be free-d alongside their parent. This logic is currently missing, so we will use some more memory. However, we won't leak, as all loads are tracked by the RoomManager, and will be freed when closing/restarting the game.
This commit is contained in:
parent
6ea8aefa7b
commit
ca12fc10ab
@ -356,9 +356,10 @@ void FixupAnim(t3dMESH *mesh, uint8 pos, const char *room) {
|
||||
db = &mesh->Anim;
|
||||
if (pos) {
|
||||
if (room && (room[0] != '\0')) {
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if ((LoadedFiles[i].b != nullptr) && LoadedFiles[i].b->name.equalsIgnoreCase(room))
|
||||
t3dCurRoom = LoadedFiles[i].b;
|
||||
t3dBODY *roomPtr = _vm->_roomManager->getRoomIfLoaded(room);
|
||||
if (room) {
|
||||
t3dCurRoom = roomPtr;
|
||||
}
|
||||
}
|
||||
if (!GetLightPosition(&lp, pos) || (lp.x == 0.0f) || (lp.z == 0.0f)) pos = 0;
|
||||
if (!GetLightDirection(&ld, pos) || (ld.x == 0.0f) || (ld.z == 0.0f)) pos = 0;
|
||||
@ -508,7 +509,7 @@ t3dBODY *LoadShadowMeshes(WGame &game, const char *pname, t3dBODY *Body) {
|
||||
strcpy(Name, pname);
|
||||
strncpy(&Name[strlen(pname) - 4], "_Shadow.t3d\0", 12);
|
||||
uint16 numBodys = 0;
|
||||
shadow = t3dLoadRoom(game, Name, shadow, &numBodys, (T3D_NOLIGHTMAPS | T3D_NORECURSION | T3D_NOVOLUMETRICLIGHTS | T3D_NOCAMERAS | T3D_NOBOUNDS | T3D_STATIC_SET0 | T3D_STATIC_SET1));
|
||||
shadow = _vm->_roomManager->loadRoom(Name, shadow, &numBodys, (T3D_NOLIGHTMAPS | T3D_NORECURSION | T3D_NOVOLUMETRICLIGHTS | T3D_NOCAMERAS | T3D_NOBOUNDS | T3D_STATIC_SET0 | T3D_STATIC_SET1));
|
||||
if (!shadow) return nullptr;
|
||||
|
||||
for (uint16 i = 0; i < shadow->NumMeshes(); i++) {
|
||||
@ -564,8 +565,11 @@ t3dCHARACTER *t3dLoadCharacter(WGame &game, const char *pname, uint16 num) {
|
||||
// gVertex *v;
|
||||
|
||||
t3dCHARACTER *b = new t3dCHARACTER[1] {};
|
||||
b->Body = t3dLoadRoom(game, pname, b->Body, &n, (T3D_NOLIGHTMAPS | T3D_NORECURSION | T3D_NOVOLUMETRICLIGHTS | T3D_NOCAMERAS | T3D_STATIC_SET0 | T3D_STATIC_SET1));
|
||||
if (!b->Body) return nullptr;
|
||||
b->Body = _vm->_roomManager->loadRoom(pname, b->Body, &n, (T3D_NOLIGHTMAPS | T3D_NORECURSION | T3D_NOVOLUMETRICLIGHTS | T3D_NOCAMERAS | T3D_STATIC_SET0 | T3D_STATIC_SET1));
|
||||
if (!b->Body) {
|
||||
delete b;
|
||||
return nullptr;
|
||||
}
|
||||
b->Mesh = &b->Body->MeshTable[0];
|
||||
b->CurRoom = t3dCurRoom;
|
||||
b->Flags = T3D_CHARACTER_HIDE | T3D_CHARACTER_REALTIMELIGHTING;
|
||||
@ -700,9 +704,7 @@ uint8 CompareLightPosition(char *roomname, uint8 pos1, t3dV3F *pos2, t3dF32 acce
|
||||
// cerco la stanza
|
||||
t = nullptr;
|
||||
if (roomname && (roomname[0] != '\0')) {
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if ((LoadedFiles[i].b != nullptr) && LoadedFiles[i].b->name.equalsIgnoreCase(roomname))
|
||||
t = LoadedFiles[i].b;
|
||||
t = _vm->_roomManager->getRoomIfLoaded(roomname);
|
||||
} else t = t3dCurRoom;
|
||||
|
||||
if (!t) return FALSE;
|
||||
|
@ -20,81 +20,30 @@
|
||||
*/
|
||||
|
||||
#include "watchmaker/3d/loader.h"
|
||||
#include "watchmaker/3d/math/llmath.h"
|
||||
#include "watchmaker/t3d.h"
|
||||
#include "watchmaker/3d/t3d_body.h"
|
||||
#include "watchmaker/3d/t3d_mesh.h"
|
||||
#include "watchmaker/types.h"
|
||||
#include "common/stream.h"
|
||||
#include "watchmaker/utils.h"
|
||||
#include "watchmaker/ll/ll_system.h"
|
||||
#include "watchmaker/work_dirs.h"
|
||||
#include "watchmaker/3d/geometry.h"
|
||||
#include "watchmaker/3d/light.h"
|
||||
#include "watchmaker/windows_hacks.h"
|
||||
#include "watchmaker/3d/math/llmath.h"
|
||||
#include "watchmaker/3d/t3d_body.h"
|
||||
#include "watchmaker/3d/t3d_mesh.h"
|
||||
#include "watchmaker/game.h"
|
||||
#include "watchmaker/ll/ll_mesh.h"
|
||||
#include "watchmaker/ll/ll_system.h"
|
||||
#include "watchmaker/renderer.h"
|
||||
#include "watchmaker/t3d.h"
|
||||
#include "watchmaker/types.h"
|
||||
#include "watchmaker/utils.h"
|
||||
#include "watchmaker/windows_hacks.h"
|
||||
#include "watchmaker/work_dirs.h"
|
||||
|
||||
namespace Watchmaker {
|
||||
|
||||
#define T3DFILEVERSION 11
|
||||
|
||||
// TODO: Globals
|
||||
#define MAX_LOADED_FILES 100
|
||||
RecStruct LoadedFiles[MAX_LOADED_FILES];
|
||||
uint16 NumLoadedFiles = 0;
|
||||
|
||||
t3dV3F CharCorrection;
|
||||
t3dF32 CurFloorY;
|
||||
int32 t3dCurTime = 900, t3dCurOliSet = 0;
|
||||
|
||||
// LoadRoom vars
|
||||
#define MAX_T3D_LOADLIST_ITEMS 50
|
||||
struct _t3dLOADLIST {
|
||||
Common::String pname = {};
|
||||
uint32 LoaderFlags = 0;
|
||||
t3dMESH *m = nullptr;
|
||||
} t3dLoadList[MAX_T3D_LOADLIST_ITEMS] = {};
|
||||
|
||||
/* -----------------10/06/99 16.03-------------------
|
||||
* AddToLoadList
|
||||
* --------------------------------------------------*/
|
||||
void AddToLoadList(t3dMESH *m, const Common::String &pname, uint32 LoaderFlags) {
|
||||
int32 a;
|
||||
|
||||
if (!pname.empty()) {
|
||||
for (a = 0; a < MAX_T3D_LOADLIST_ITEMS; a++) {
|
||||
if (t3dLoadList[a].pname.empty()) {
|
||||
t3dLoadList[a].LoaderFlags = LoaderFlags;
|
||||
t3dLoadList[a].m = m;
|
||||
t3dLoadList[a].pname = pname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (a >= MAX_T3D_LOADLIST_ITEMS)
|
||||
warning("Cannot add %s to LoadList", pname.c_str());
|
||||
} else {
|
||||
warning("Invalid parameters invoking AddToLoadList()");
|
||||
warning("Mesh (%s), pname %s", m->name.c_str(), pname.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------10/06/99 16.04-------------------
|
||||
* GetFromLoadList
|
||||
* --------------------------------------------------*/
|
||||
struct _t3dLOADLIST *GetFromLoadList(void) {
|
||||
int32 a;
|
||||
|
||||
for (a = 0; a < MAX_T3D_LOADLIST_ITEMS; a++) {
|
||||
if (!t3dLoadList[a].pname.empty())
|
||||
return &t3dLoadList[a];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
t3dPathCamera::t3dPathCamera(Common::SeekableReadStream &stream) {
|
||||
NumCamera = stream.readByte();
|
||||
PathIndex = stream.readByte();
|
||||
@ -160,21 +109,6 @@ void decodeLoaderFlags(uint32 flags) {
|
||||
warning("%d: T3D_HIPOLYCHARACTERS", flags & T3D_HIPOLYCHARACTERS);
|
||||
}
|
||||
|
||||
/* -----------------10/06/99 16.04-------------------
|
||||
* CheckIfAlreadyLoaded
|
||||
* --------------------------------------------------*/
|
||||
t3dBODY *CheckIfAlreadyLoaded(const Common::String &Name) {
|
||||
if (Name.empty()) return nullptr;
|
||||
|
||||
for (uint16 i = 0; i < NumLoadedFiles; i++) {
|
||||
if ((LoadedFiles[i].b != nullptr) && /*(LoadedFiles[i].Name != nullptr) &&*/ (!LoadedFiles[i].name.empty()))
|
||||
if (LoadedFiles[i].name.equalsIgnoreCase(Name))
|
||||
return LoadedFiles[i].b;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Common::String constructPath(const Common::String &prefix, const Common::String &filename, const char *suffix) {
|
||||
Common::String Name = prefix + filename;
|
||||
uint16 len = Name.size();
|
||||
@ -186,15 +120,188 @@ Common::String constructPath(const Common::String &prefix, const Common::String
|
||||
return Common::String(Name);
|
||||
}
|
||||
|
||||
class RoomManagerImplementation : public RoomManager {
|
||||
WGame *_game;
|
||||
#define MAX_LOADED_FILES 100
|
||||
RecStruct LoadedFiles[MAX_LOADED_FILES];
|
||||
uint16 NumLoadedFiles = 0;
|
||||
public:
|
||||
RoomManagerImplementation(WGame *game) : _game(game) {}
|
||||
#define MAX_T3D_LOADLIST_ITEMS 50
|
||||
struct _t3dLOADLIST {
|
||||
Common::String pname = {};
|
||||
uint32 LoaderFlags = 0;
|
||||
t3dMESH *m = nullptr;
|
||||
};
|
||||
_t3dLOADLIST t3dLoadList[MAX_T3D_LOADLIST_ITEMS] = {};
|
||||
|
||||
void addToLoadList(t3dMESH *m, const Common::String &pname, uint32 LoaderFlags) {
|
||||
if (!pname.empty()) {
|
||||
int32 a;
|
||||
for (a = 0; a < MAX_T3D_LOADLIST_ITEMS; a++) {
|
||||
if (t3dLoadList[a].pname.empty()) {
|
||||
t3dLoadList[a].LoaderFlags = LoaderFlags;
|
||||
t3dLoadList[a].m = m;
|
||||
t3dLoadList[a].pname = pname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (a >= MAX_T3D_LOADLIST_ITEMS)
|
||||
warning("Cannot add %s to LoadList", pname.c_str());
|
||||
} else {
|
||||
warning("Invalid parameters invoking AddToLoadList()");
|
||||
warning("Mesh (%s), pname %s", m->name.c_str(), pname.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
_t3dLOADLIST* getFromLoadList(void) {
|
||||
for (int a = 0; a < MAX_T3D_LOADLIST_ITEMS; a++) {
|
||||
if (!t3dLoadList[a].pname.empty())
|
||||
return &t3dLoadList[a];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
t3dBODY *getRoomIfLoaded(const Common::String &roomname) override {
|
||||
t3dBODY *t = nullptr;
|
||||
for (int i = 0; i < NumLoadedFiles; i++)
|
||||
if ((LoadedFiles[i].b != nullptr) && LoadedFiles[i].b->name.equalsIgnoreCase(roomname))
|
||||
t = LoadedFiles[i].b;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
t3dBODY* loadRoom(const Common::String &pname, t3dBODY *b, uint16 *NumBody, uint32 LoaderFlags) override;
|
||||
t3dBODY* loadSingleRoom(const Common::String &pname, uint16 *NumBody, uint32 LoaderFlags);
|
||||
void hideRoomMeshesMatching(const Common::String &pname) override {
|
||||
for (int i = 0; i < NumLoadedFiles; i++)
|
||||
if (LoadedFiles[i].b)
|
||||
if (LoadedFiles[i].b->name.equalsIgnoreCase(pname)) {
|
||||
HideRoomMeshes(_game->init, LoadedFiles[i].b);
|
||||
}
|
||||
}
|
||||
Common::Array<t3dBODY*> getLoadedFiles() override {
|
||||
// TODO: This won't need to be a copy if we maintain a Common::Array only containing the valid ones.
|
||||
Common::Array<t3dBODY*> files;
|
||||
for (int i = 0; i < NumLoadedFiles; i++)
|
||||
if (LoadedFiles[i].b)
|
||||
files.push_back(LoadedFiles[i].b);
|
||||
return files;
|
||||
}
|
||||
t3dBODY *checkIfAlreadyLoaded(const Common::String &Name) override {
|
||||
if (Name.empty()) return nullptr;
|
||||
|
||||
for (uint16 i = 0; i < NumLoadedFiles; i++) {
|
||||
if ((LoadedFiles[i].b != nullptr) && /*(LoadedFiles[i].Name != nullptr) &&*/ (!LoadedFiles[i].name.empty()))
|
||||
if (LoadedFiles[i].name.equalsIgnoreCase(Name))
|
||||
return LoadedFiles[i].b;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
t3dMESH *linkMeshToStr(Init &init, const Common::String &str) {
|
||||
if (str.empty()) return nullptr;
|
||||
|
||||
// Cerca tra le camere
|
||||
if (str.equalsIgnoreCase("camera"))
|
||||
return &init._globals._invVars.CameraDummy;
|
||||
// Cerca tra i personaggi
|
||||
for (uint16 i = 0; i < T3D_MAX_CHARACTERS; i++)
|
||||
if ((Character[i]) && (str.equalsIgnoreCase((char *)init.Obj[i].meshlink[0])))
|
||||
return Character[i]->Mesh;
|
||||
// Cerca nelle stanze caricate
|
||||
for (uint16 i = 0; i < NumLoadedFiles; i++) {
|
||||
if (LoadedFiles[i].b)
|
||||
for (uint16 j = 0; j < LoadedFiles[i].b->NumMeshes(); j++) {
|
||||
if (str.equalsIgnoreCase(LoadedFiles[i].b->MeshTable[j].name))
|
||||
return &LoadedFiles[i].b->MeshTable[j];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
void releaseBody(const Common::String &name, const Common::String &altName) override {
|
||||
for (int j = 0; j < NumLoadedFiles; j++) {
|
||||
if (LoadedFiles[j].name.equalsIgnoreCase(name) || LoadedFiles[j].name.equalsIgnoreCase(altName)) {
|
||||
t3dReleaseBody(LoadedFiles[j].b);
|
||||
LoadedFiles[j].b = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void releaseLoadedFiles(uint32 exceptFlag) override {
|
||||
for (int i = 0; i < NumLoadedFiles; i++) {
|
||||
if (LoadedFiles[i].b && !(LoadedFiles[i].Flags & exceptFlag)) {
|
||||
t3dReleaseBody(LoadedFiles[i].b);
|
||||
LoadedFiles[i] = RecStruct(); // TODO: Deduplicate.
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
void loadFromList();
|
||||
};
|
||||
|
||||
RoomManager *RoomManager::create(WGame *game) {
|
||||
return new RoomManagerImplementation(game);
|
||||
}
|
||||
|
||||
/* -----------------10/06/99 16.04-------------------
|
||||
* t3dLoadSingleRoom
|
||||
* t3dLoadRoom
|
||||
* --------------------------------------------------*/
|
||||
t3dBODY *t3dLoadSingleRoom(WGame &game, const Common::String &_pname, t3dBODY *b, uint16 *NumBody, uint32 LoaderFlags) {
|
||||
t3dBODY* RoomManagerImplementation::loadRoom(const Common::String &pname, t3dBODY *b, uint16 *NumBody, uint32 LoaderFlags) {
|
||||
warning("t3dLoadRoom(%s, b, %d, %d)", pname.c_str(), *NumBody, LoaderFlags);
|
||||
struct _t3dLOADLIST *l;
|
||||
t3dBODY *r, *rez;
|
||||
uint16 num, i;
|
||||
|
||||
// reset everything that was previously in the load list
|
||||
for (int i = 0; i < MAX_T3D_LOADLIST_ITEMS; i++) {
|
||||
t3dLoadList[i] = _t3dLOADLIST();
|
||||
}
|
||||
|
||||
// Add the base stanza to the upload list
|
||||
addToLoadList(nullptr, pname, LoaderFlags);
|
||||
|
||||
while ((l = getFromLoadList())) {
|
||||
num = 0;
|
||||
if (l->m) {
|
||||
if ((rez = _vm->_roomManager->checkIfAlreadyLoaded(l->pname)))
|
||||
l->m->PortalList = rez;
|
||||
else {
|
||||
// if (l->m->Flags&T3D_MESH_PREPROCESSPORTAL)
|
||||
// body=l->m->PortalList = t3dLoadSingleRoom( l->pname, l->m->PortalList, &num, (l->LoaderFlags|T3D_HALFTEXTURESIZE) );
|
||||
// else
|
||||
// TODO: This should increase some refcount on the PortalList
|
||||
warning("TODO: Handle refcounts on PortalList");
|
||||
l->m->PortalList = loadSingleRoom(l->pname, &num, l->LoaderFlags);
|
||||
}
|
||||
} else
|
||||
r = loadSingleRoom(l->pname, NumBody, l->LoaderFlags);
|
||||
|
||||
*l = _t3dLOADLIST();
|
||||
}
|
||||
|
||||
if (!(LoaderFlags & T3D_NORECURSION)) {
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if (LoadedFiles[i].b)
|
||||
t3dCalcRejectedMeshFromPortal(LoadedFiles[i].b);
|
||||
}
|
||||
|
||||
warning("Room loaded");
|
||||
return r;
|
||||
}
|
||||
|
||||
t3dBODY* RoomManagerImplementation::loadSingleRoom(const Common::String &_pname, uint16 *NumBody, uint32 LoaderFlags) {
|
||||
//warning("t3dLoadSingleRoom(workDirs, %s, b, %d, %d)", _pname, *NumBody, LoaderFlags);
|
||||
//decodeLoaderFlags(LoaderFlags);
|
||||
Common::String pname(_pname);
|
||||
|
||||
WorkDirs &workdirs = game.workDirs;
|
||||
WorkDirs &workdirs = _game->workDirs;
|
||||
|
||||
if (pname.equalsIgnoreCase("r1c.t3d"))
|
||||
if (((t3dCurTime >= 1300) && (t3dCurTime <= 1310)) || (t3dCurTime >= 1800)) //se viene cambiato l'orario cambiarlo anche in UpdateRoomVis...
|
||||
@ -212,11 +319,11 @@ t3dBODY *t3dLoadSingleRoom(WGame &game, const Common::String &_pname, t3dBODY *b
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (*NumBody == 0) { // Se e' il primo body, alloca
|
||||
b = new t3dBODY;
|
||||
(*NumBody)++;
|
||||
} else
|
||||
b = (t3dBODY *)t3dRealloc((uint32 *)b, sizeof(t3dBODY) * (++(*NumBody))); // Altrimenti, ridimensiona
|
||||
if (*NumBody != 0) {
|
||||
// TODO: This currently means that we never free the dependant bodies.
|
||||
warning("Loading a dependant body, should also be deleted alongside the base body");
|
||||
}
|
||||
t3dBODY *b = new t3dBODY();
|
||||
|
||||
//warning("Loading %s ...", name.c_str());
|
||||
*b = t3dBODY(); // Azzera Body
|
||||
@ -229,67 +336,25 @@ t3dBODY *t3dLoadSingleRoom(WGame &game, const Common::String &_pname, t3dBODY *b
|
||||
|
||||
{
|
||||
uint16 j = 1;
|
||||
while (LoadedFiles[j].b != nullptr) j++;
|
||||
while (LoadedFiles[j].b != nullptr)
|
||||
j++;
|
||||
if (j > MAX_LOADED_FILES) {
|
||||
warning("Too many t3d files loaded!");
|
||||
return nullptr;
|
||||
}
|
||||
if ((j + 1) > NumLoadedFiles) NumLoadedFiles = j + 1;
|
||||
if ((j + 1) > NumLoadedFiles)
|
||||
NumLoadedFiles = j + 1;
|
||||
|
||||
LoadedFiles[j].name = _pname; // Aggiunge il file alla lista
|
||||
LoadedFiles[j].Flags = LoaderFlags; // Aggiunge Flags alla lista
|
||||
LoadedFiles[j].b = b; // Aggiunge Body alla lista
|
||||
j = 0;
|
||||
}
|
||||
b->loadFromStream(game, pname, *stream, LoaderFlags);
|
||||
b->loadFromStream(*_game, pname, *stream, LoaderFlags);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/* -----------------10/06/99 16.04-------------------
|
||||
* t3dLoadRoom
|
||||
* --------------------------------------------------*/
|
||||
t3dBODY *t3dLoadRoom(WGame &game, const Common::String &pname, t3dBODY *b, uint16 *NumBody, uint32 LoaderFlags) {
|
||||
warning("t3dLoadRoom(%s, b, %d, %d)", pname.c_str(), *NumBody, LoaderFlags);
|
||||
struct _t3dLOADLIST *l;
|
||||
t3dBODY *r, *rez;
|
||||
uint16 num, i;
|
||||
|
||||
// azzera tutto quello che c'era prima nella load list
|
||||
for (int i = 0; i < MAX_T3D_LOADLIST_ITEMS; i++) {
|
||||
t3dLoadList[i] = _t3dLOADLIST();
|
||||
}
|
||||
|
||||
// Aggiunge la stanza base alla lista di caricamenti
|
||||
AddToLoadList(nullptr, pname, LoaderFlags);
|
||||
|
||||
while ((l = GetFromLoadList())) {
|
||||
num = 0;
|
||||
if (l->m) {
|
||||
if ((rez = CheckIfAlreadyLoaded(l->pname)))
|
||||
l->m->PortalList = rez;
|
||||
else {
|
||||
// if (l->m->Flags&T3D_MESH_PREPROCESSPORTAL)
|
||||
// body=l->m->PortalList = t3dLoadSingleRoom( l->pname, l->m->PortalList, &num, (l->LoaderFlags|T3D_HALFTEXTURESIZE) );
|
||||
// else
|
||||
l->m->PortalList = t3dLoadSingleRoom(game, l->pname, l->m->PortalList, &num, l->LoaderFlags);
|
||||
}
|
||||
} else
|
||||
r = t3dLoadSingleRoom(game, l->pname, b, NumBody, l->LoaderFlags);
|
||||
|
||||
*l = _t3dLOADLIST();
|
||||
}
|
||||
|
||||
if (!(LoaderFlags & T3D_NORECURSION)) {
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if (LoadedFiles[i].b)
|
||||
t3dCalcRejectedMeshFromPortal(LoadedFiles[i].b);
|
||||
}
|
||||
|
||||
warning("Room loaded");
|
||||
return r;
|
||||
}
|
||||
|
||||
t3dParticle::t3dParticle(Common::SeekableReadStream &stream) {
|
||||
t3dF32 difR1, difG1, difB1;
|
||||
t3dF32 difR2, difG2, difB2;
|
||||
@ -408,7 +473,7 @@ void t3dLoadSky(WGame &game, t3dBODY * /*body*/) {
|
||||
// t3dF32 Tile=1.5f;
|
||||
t3dF32 div;
|
||||
|
||||
if (!(t3dSky = t3dLoadRoom(game, "sky.t3d", t3dSky, &n, T3D_NORECURSION | T3D_NOLIGHTMAPS | T3D_NOVOLUMETRICLIGHTS | T3D_NOCAMERAS | T3D_NOBOUNDS | T3D_STATIC_SET0))) {
|
||||
if (!(t3dSky = _vm->_roomManager->loadRoom("sky.t3d", t3dSky, &n, T3D_NORECURSION | T3D_NOLIGHTMAPS | T3D_NOVOLUMETRICLIGHTS | T3D_NOCAMERAS | T3D_NOBOUNDS | T3D_STATIC_SET0))) {
|
||||
warning("Error during t3dLoadRoom: Sky not loaded");
|
||||
}
|
||||
|
||||
|
@ -69,20 +69,28 @@ struct RecStruct {
|
||||
uint32 Flags = 0;
|
||||
};
|
||||
|
||||
extern RecStruct LoadedFiles[];
|
||||
extern uint16 NumLoadedFiles;
|
||||
|
||||
t3dBODY *t3dLoadRoom(WGame &game, const Common::String &pname, t3dBODY *b, unsigned short *NumBody, unsigned int LoaderFlags);
|
||||
t3dBODY *t3dLoadSingleRoom(WGame &game, const char *_pname, t3dBODY *b, uint16 *NumBody, uint32 LoaderFlags);
|
||||
void t3dOptimizeMaterialList(t3dBODY *b);
|
||||
void t3dFinalizeMaterialList(t3dBODY *b);
|
||||
void t3dPrecalcLight(t3dBODY *b, unsigned char *sun);
|
||||
void t3dLoadSky(WGame &game, t3dBODY *b);
|
||||
|
||||
t3dBODY *CheckIfAlreadyLoaded(const Common::String &Name);
|
||||
void AddToLoadList(t3dMESH *m, const Common::String &pname, uint32 LoaderFlags);
|
||||
Common::String constructPath(const Common::String &prefix, const Common::String &filename, const char *suffix = nullptr);
|
||||
|
||||
class RoomManager {
|
||||
public:
|
||||
virtual ~RoomManager() {}
|
||||
virtual void addToLoadList(t3dMESH *m, const Common::String &pname, uint32 LoaderFlags) = 0;
|
||||
virtual t3dBODY* loadRoom(const Common::String &pname, t3dBODY *b, uint16 *NumBody, uint32 LoaderFlags) = 0;
|
||||
static RoomManager *create(WGame *game);
|
||||
virtual t3dBODY *getRoomIfLoaded(const Common::String &roomname) = 0;
|
||||
virtual t3dMESH *linkMeshToStr(Init &init, const Common::String &str) = 0;
|
||||
virtual void hideRoomMeshesMatching(const Common::String &pname) = 0;
|
||||
virtual void releaseBody(const Common::String &name, const Common::String &altName) = 0;
|
||||
virtual void releaseLoadedFiles(uint32 exceptFlag) = 0;
|
||||
virtual t3dBODY *checkIfAlreadyLoaded(const Common::String &Name) = 0;
|
||||
virtual Common::Array<t3dBODY*> getLoadedFiles() = 0;
|
||||
};
|
||||
|
||||
} // End of namespace Watchmaker
|
||||
|
||||
#endif // WATCHMAKER_LOADER_H
|
||||
|
@ -177,15 +177,15 @@ void t3dBODY::populatePortalLists() {
|
||||
//#endif
|
||||
// TODO: This should probably be upfactored.
|
||||
t3dBODY *rez = nullptr;
|
||||
if (((rez = CheckIfAlreadyLoaded(Name)) == nullptr) && (!(LoaderFlags & T3D_NORECURSION))) { // Controlla se lo ha gia' caricato
|
||||
if (((rez = _vm->_roomManager->checkIfAlreadyLoaded(Name)) == nullptr) && (!(LoaderFlags & T3D_NORECURSION))) { // Controlla se lo ha gia' caricato
|
||||
if (Name.equalsIgnoreCase("rxt.t3d"))
|
||||
AddToLoadList(&Mesh[mesh], Name, (uint16)(LoaderFlags | T3D_NORECURSION & ~T3D_RECURSIONLEVEL1)); // aggiunge e leva la ricorsione
|
||||
_vm->_roomManager->addToLoadList(&Mesh[mesh], Name, (uint16)(LoaderFlags | T3D_NORECURSION & ~T3D_RECURSIONLEVEL1)); // aggiunge e leva la ricorsione
|
||||
// Mesh[mesh].Flags|=T3D_MESH_NOPORTALCHECK;
|
||||
else {
|
||||
if (LoaderFlags & T3D_RECURSIONLEVEL1)
|
||||
AddToLoadList(&Mesh[mesh], Name, (uint16)(LoaderFlags | T3D_NORECURSION & ~T3D_RECURSIONLEVEL1)); // aggiunge e leva la ricorsione
|
||||
_vm->_roomManager->addToLoadList(&Mesh[mesh], Name, (uint16)(LoaderFlags | T3D_NORECURSION & ~T3D_RECURSIONLEVEL1)); // aggiunge e leva la ricorsione
|
||||
else
|
||||
AddToLoadList(&Mesh[mesh], Name, (uint16)(LoaderFlags)); // altrimenti lo agggiunge alla lista
|
||||
_vm->_roomManager->addToLoadList(&Mesh[mesh], Name, (uint16)(LoaderFlags)); // altrimenti lo agggiunge alla lista
|
||||
}
|
||||
} else
|
||||
Mesh[mesh].PortalList = rez;
|
||||
|
@ -562,10 +562,9 @@ void ProcessTime(WGame &game) {
|
||||
//DebugLogFile("Updating Listener ");
|
||||
UpdateListener = 20;
|
||||
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if (LoadedFiles[i].b && t3dCurRoom)
|
||||
if (LoadedFiles[i].b->name.equalsIgnoreCase(t3dCurRoom->name))
|
||||
HideRoomMeshes(game.init, LoadedFiles[i].b);
|
||||
if (t3dCurRoom) {
|
||||
_vm->_roomManager->hideRoomMeshesMatching(t3dCurRoom->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
@ -162,13 +162,7 @@ bool WGame::CheckAndLoadMoglieSupervisoreModel(int32 c) {
|
||||
t3dReleaseCharacter(Character[c]);
|
||||
Character[c] = nullptr;
|
||||
|
||||
for (j = 0; j < NumLoadedFiles; j++) {
|
||||
if (LoadedFiles[j].name.equalsIgnoreCase(RemoveName) || LoadedFiles[j].name.equalsIgnoreCase(RemoveNameHI)) {
|
||||
t3dReleaseBody(LoadedFiles[j].b);
|
||||
LoadedFiles[j].b = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_vm->_roomManager->releaseBody(RemoveName, RemoveNameHI);
|
||||
|
||||
LoaderFlags |= T3D_PRELOADBASE;
|
||||
LoaderFlags |= T3D_STATIC_SET1;
|
||||
@ -192,6 +186,7 @@ bool WGame::CheckAndLoadMoglieSupervisoreModel(int32 c) {
|
||||
WGame::WGame() : workDirs(WATCHMAKER_CFG_NAME) {
|
||||
_vm = this;
|
||||
_meshModifiers = new MeshModifiers();
|
||||
_roomManager = RoomManager::create(this);
|
||||
configLoaderFlags(); // TODO: This should probably happen before the constructor
|
||||
|
||||
// if LoaderFlags & T3D_DEBUGMODE
|
||||
@ -219,6 +214,7 @@ WGame::~WGame() {
|
||||
delete _renderer;
|
||||
delete sdl;
|
||||
delete _meshModifiers;
|
||||
delete _roomManager;
|
||||
_vm = nullptr;
|
||||
}
|
||||
|
||||
@ -313,7 +309,7 @@ bool WGame::LoadAndSetup(const Common::String &name, uint8 lite) {
|
||||
// PrintLoading();
|
||||
|
||||
if (!(LoaderFlags & T3D_NOICONS))
|
||||
if (!(init._globals._invVars.t3dIcons = t3dLoadRoom(*this, "Icons.t3d", init._globals._invVars.t3dIcons, &i, (LoaderFlags | T3D_NORECURSION | T3D_NOLIGHTMAPS | T3D_NOBOUNDS | T3D_NOCAMERAS | T3D_STATIC_SET1)))) {
|
||||
if (!(init._globals._invVars.t3dIcons = _roomManager->loadRoom("Icons.t3d", init._globals._invVars.t3dIcons, &i, (LoaderFlags | T3D_NORECURSION | T3D_NOLIGHTMAPS | T3D_NOBOUNDS | T3D_NOCAMERAS | T3D_STATIC_SET1)))) {
|
||||
warning("Error loading Icons");
|
||||
return false;
|
||||
}
|
||||
@ -361,7 +357,8 @@ bool WGame::LoadAndSetup(const Common::String &name, uint8 lite) {
|
||||
if (!lite) {
|
||||
if (LoaderFlags & T3D_PRELOAD_RXT) {
|
||||
t3dCurOliSet = -1;
|
||||
if (!(t3dRxt = t3dLoadRoom(*this, "rxt.t3d", t3dCurRoom, &i, LoaderFlags | T3D_NOLIGHTMAPS))) {
|
||||
// TODO: Figure out how this i works out.
|
||||
if (!(t3dRxt = _roomManager->loadRoom("rxt.t3d", t3dCurRoom, &i, LoaderFlags | T3D_NOLIGHTMAPS))) {
|
||||
warning("Error loading room rxt.t3d");
|
||||
return false;
|
||||
}
|
||||
@ -379,7 +376,7 @@ bool WGame::LoadAndSetup(const Common::String &name, uint8 lite) {
|
||||
}
|
||||
|
||||
if (!((LoaderFlags & T3D_PRELOAD_RXT) && name.equalsIgnoreCase("rxt.t3d"))) {
|
||||
if (!(t3dCurRoom = t3dLoadRoom(*this, name, t3dCurRoom, &i, LoaderFlags))) {
|
||||
if (!(t3dCurRoom = _roomManager->loadRoom(name, t3dCurRoom, &i, LoaderFlags))) {
|
||||
warning("Error loading room %s", name.c_str());
|
||||
return false;
|
||||
}
|
||||
@ -506,12 +503,12 @@ bool WGame::LoadAndSetup(const Common::String &name, uint8 lite) {
|
||||
void WGame::UpdateAll() {
|
||||
int32 i;
|
||||
UpdateRoomVisibility(*this);
|
||||
for (i = 0; i < NumLoadedFiles; i++) {
|
||||
if (LoadedFiles[i].b) {
|
||||
HideRoomMeshes(init, LoadedFiles[i].b);
|
||||
_meshModifiers->applyAllMeshModifiers(*this, LoadedFiles[i].b);
|
||||
}
|
||||
auto bodies = _roomManager->getLoadedFiles();
|
||||
for (auto loadedBody : bodies) {
|
||||
HideRoomMeshes(init, loadedBody);
|
||||
_meshModifiers->applyAllMeshModifiers(*this, loadedBody);
|
||||
}
|
||||
|
||||
UpdateAllClocks(*this);
|
||||
|
||||
// Init for Clock33
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
};
|
||||
|
||||
class MeshModifiers;
|
||||
class RoomManager;
|
||||
|
||||
class WGame {
|
||||
bool g_bReady, g_bActive;
|
||||
@ -69,6 +70,7 @@ public:
|
||||
GameRect _gameRect;
|
||||
Fonts _fonts;
|
||||
MessageSystem _messageSystem;
|
||||
RoomManager *_roomManager;
|
||||
WGame();
|
||||
~WGame();
|
||||
|
||||
|
@ -1829,12 +1829,7 @@ void StopPlayingGame(WGame &game) {
|
||||
StopAllAnims(init);
|
||||
StopMusic();
|
||||
t3dResetPipeline();
|
||||
for (i = 0; i < NumLoadedFiles; i++) {
|
||||
if (LoadedFiles[i].b && !(LoadedFiles[i].Flags & T3D_STATIC_SET1)) {
|
||||
t3dReleaseBody(LoadedFiles[i].b);
|
||||
LoadedFiles[i] = RecStruct(); // TODO: Deduplicate.
|
||||
}
|
||||
}
|
||||
_vm->_roomManager->releaseLoadedFiles(T3D_STATIC_SET1);
|
||||
|
||||
t3dRxt = nullptr;
|
||||
t3dSky = nullptr;
|
||||
|
@ -71,27 +71,6 @@ void *t3dCalloc(uint32 n) {
|
||||
return (res);
|
||||
}
|
||||
|
||||
void *t3dRealloc(void *pp, uint32 additionalBytes) {
|
||||
|
||||
|
||||
uint32 *res = (uint32 *)pp;
|
||||
uint32 size = 0;
|
||||
if (pp == nullptr) size = 0;
|
||||
else
|
||||
size = (uint32) MALLOC_SIZE(pp);
|
||||
//Reallocate and show new size:
|
||||
if ((res = (uint32 *)realloc(pp, (additionalBytes + size))) == nullptr) {
|
||||
warning("t3dRealloc: Memory allocation error: can't alloc %d bytes", additionalBytes + size);
|
||||
return res;
|
||||
}
|
||||
|
||||
t3dAllocatedMemory += additionalBytes;
|
||||
//malloc_size()
|
||||
pp = res;//realloc(pp, additionalBytes);
|
||||
//warning("t3dRealloc() size: %d, additionalBytes: %d, newSize = %d", size, additionalBytes, malloc_size(pp));
|
||||
return (pp);
|
||||
}
|
||||
|
||||
void t3dFree(void *p) {
|
||||
if (!p) return;
|
||||
|
||||
|
@ -269,25 +269,8 @@ int32 LoadDDBitmap(WGame &game, const char *n, uint8 flags) {
|
||||
* LinkMeshToStr
|
||||
* --------------------------------------------------*/
|
||||
t3dMESH *LinkMeshToStr(Init &init, const Common::String &str) {
|
||||
if (str.empty()) return nullptr;
|
||||
|
||||
// Cerca tra le camere
|
||||
if (str.equalsIgnoreCase("camera"))
|
||||
return &init._globals._invVars.CameraDummy;
|
||||
// Cerca tra i personaggi
|
||||
for (uint16 i = 0; i < T3D_MAX_CHARACTERS; i++)
|
||||
if ((Character[i]) && (str.equalsIgnoreCase((char *)init.Obj[i].meshlink[0])))
|
||||
return Character[i]->Mesh;
|
||||
// Cerca nelle stanze caricate
|
||||
for (uint16 i = 0; i < NumLoadedFiles; i++) {
|
||||
if (LoadedFiles[i].b)
|
||||
for (uint16 j = 0; j < LoadedFiles[i].b->NumMeshes(); j++) {
|
||||
if (str.equalsIgnoreCase(LoadedFiles[i].b->MeshTable[j].name))
|
||||
return &LoadedFiles[i].b->MeshTable[j];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
// TODO: Refactor the callsites:
|
||||
return _vm->_roomManager->linkMeshToStr(init, str);
|
||||
}
|
||||
|
||||
/* -----------------18/12/00 18.02-------------------
|
||||
@ -444,9 +427,7 @@ bool SetBndLevel(WGame &game, const char *roomname, int32 lev) {
|
||||
|
||||
t = nullptr;
|
||||
if (roomname && (roomname[0] != '\0')) {
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if ((LoadedFiles[i].b != nullptr) && LoadedFiles[i].b->name.equalsIgnoreCase(roomname))
|
||||
t = LoadedFiles[i].b;
|
||||
_vm->_roomManager->getRoomIfLoaded(roomname);
|
||||
} else t = t3dCurRoom;
|
||||
|
||||
if (!t) {
|
||||
@ -522,20 +503,13 @@ void ChangeRoom(WGame &game, Common::String n, uint8 pos, int32 an) {
|
||||
// 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);
|
||||
|
||||
t = nullptr;
|
||||
// Prima lo cerca tra le stanze in memoria
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if ((LoadedFiles[i].b != nullptr) && LoadedFiles[i].b->name.equalsIgnoreCase(n))
|
||||
t = LoadedFiles[i].b;
|
||||
t = _vm->_roomManager->getRoomIfLoaded(n);
|
||||
|
||||
// Se non lo trova tra le stanze in memoria
|
||||
if (!t) {
|
||||
t3dResetPipeline();
|
||||
for (i = 0; i < NumLoadedFiles; i++) {
|
||||
if (LoadedFiles[i].b && !(LoadedFiles[i].Flags & T3D_STATIC_SET0)) {
|
||||
t3dReleaseBody(LoadedFiles[i].b);
|
||||
LoadedFiles[i] = RecStruct(); // TODO: Deduplicate this
|
||||
}
|
||||
}
|
||||
_vm->_roomManager->releaseLoadedFiles(T3D_STATIC_SET0);
|
||||
|
||||
for (i = 0; i < T3D_MAX_CHARACTERS; i++) {
|
||||
if (Character[i]) {
|
||||
@ -597,9 +571,7 @@ int32 GetBndLevel(char *roomname) {
|
||||
|
||||
t = nullptr;
|
||||
if (roomname && (roomname[0] != '\0')) {
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if ((LoadedFiles[i].b != nullptr) && LoadedFiles[i].b->name.equalsIgnoreCase(roomname))
|
||||
t = LoadedFiles[i].b;
|
||||
t = _vm->_roomManager->getRoomIfLoaded(roomname);
|
||||
} else t = t3dCurRoom;
|
||||
|
||||
if (!t) return FALSE;
|
||||
|
@ -545,12 +545,7 @@ bool DataLoad(WGame &game, const Common::String &FileName, uint8 slot) {
|
||||
StopSounds();
|
||||
StopMusic();
|
||||
t3dResetPipeline();
|
||||
for (int i = 0; i < NumLoadedFiles; i++) {
|
||||
if (LoadedFiles[i].b && !(LoadedFiles[i].Flags & T3D_STATIC_SET1)) {
|
||||
t3dReleaseBody(LoadedFiles[i].b);
|
||||
LoadedFiles[i] = RecStruct();
|
||||
}
|
||||
}
|
||||
_vm->_roomManager->releaseLoadedFiles(T3D_STATIC_SET1);
|
||||
t3dRxt = nullptr;
|
||||
t3dSky = nullptr;
|
||||
rReleaseAllTextures(T3D_STATIC_SET0);
|
||||
|
@ -214,9 +214,10 @@ void CharSetPosition(int32 oc, uint8 pos, const char *room) {
|
||||
CharStop(oc);
|
||||
if (pos == 99) return;
|
||||
if (room && (room[0] != '\0')) {
|
||||
for (i = 0; i < NumLoadedFiles; i++)
|
||||
if ((LoadedFiles[i].b != nullptr) && LoadedFiles[i].b->name.equalsIgnoreCase(room))
|
||||
t3dCurRoom = LoadedFiles[i].b;
|
||||
t3dBODY *roomPtr = _vm->_roomManager->getRoomIfLoaded(room);
|
||||
if (roomPtr) {
|
||||
t3dCurRoom = roomPtr;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos) {
|
||||
|
Loading…
Reference in New Issue
Block a user