/*
===========================================================================
ARX FATALIS GPL Source Code
Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
Arx Fatalis Source Code 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.
Arx Fatalis Source Code 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 Arx Fatalis Source Code. If not, see
.
In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//////////////////////////////////////////////////////////////////////////////////////
// @@ @@@ @@@ @@ @@@@@ //
// @@@ @@@@@@ @@@ @@ @@@@ @@@ @@@ //
// @@@ @@@@@@@ @@@ @@@@ @@@@ @@ @@@@ //
// @@@ @@ @@@@ @@@ @@@@@ @@@@@@ @@@ @@@ //
// @@@@@ @@ @@@@ @@@ @@@@@ @@@@@@@ @@@ @ @@@ //
// @@@@@ @@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@ @@@@@@@ //
// @@ @@@ @@ @@@@ @@@@@@@ @@@ @@@ @@@@@@ @@ @@@@ //
// @@@ @@@ @@@ @@@@ @@@@@ @@@@@@@@@ @@@@@@@ @@@ @@@@ //
// @@@ @@@@ @@@@@@@ @@@@@@ @@@ @@@@ @@@ @@@ @@@ @@@@ //
// @@@@@@@@ @@@@@ @@@@@@@@@@ @@@ @@@ @@@ @@@ @@@ @@@@@ //
// @@@ @@@@ @@@@ @@@ @@@@@@@ @@@ @@@ @@@@ @@@ @@@@ @@@@@ //
//@@@ @@@@ @@@@@ @@@ @@@@@@ @@ @@@ @@@@ @@@@@@@ @@@@@ @@@@@ //
//@@@ @@@@@ @@@@@ @@@@ @@@ @@ @@ @@@@ @@@@@@@ @@@@@@@@@ //
//@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@@@@ //
//@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@ //
//@@@ @@@ @@@ @@@@@ @@ @@@ //
// @@@ @@@ @@ @@ STUDIOS //
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// DanaeSaveLoad.CPP
//////////////////////////////////////////////////////////////////////////////////////
//
// Description:
// DANAE Save & Load Management
//
// Updates: (date) (person) (update)
//
// Code: Cyril Meynier
//
// Copyright (c) 1999-2000 ARKANE Studios SA. All rights reserved
//////////////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "ARX_Loc.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "ARX_HWTransform.h"
#include "ARX_Time.h"
#include "DanaeDlg.h"
#include
#define _CRTDBG_MAP_ALLOC
#include
extern float PROGRESS_BAR_COUNT;
extern float PROGRESS_BAR_TOTAL;
extern long DONT_ERASE_PLAYER;
extern EERIE_BACKGROUND bkrgnd;
extern QUAKE_FX_STRUCT QuakeFx;
extern bool bGToggleCombatModeWithKey;
extern bool bGCroucheToggle;
long SPECIALPOLYSNB = 0;
BOOL CanPurge(EERIE_3D * pos)
{
long px, pz;
F2L(pos->x * ACTIVEBKG->Xmul, &px);
if (px > ACTIVEBKG->Xsize - 3)
{
return TRUE;
}
if (px < 2)
{
return TRUE;
}
F2L(pos->z * ACTIVEBKG->Zmul, &pz);
if (pz > ACTIVEBKG->Zsize - 3)
{
return TRUE;
}
if (pz < 2)
{
return TRUE;
}
EERIE_BKG_INFO * eg;
for (long j = pz - 1; j <= pz + 1; j++)
for (long i = px - 1; i <= px + 1; i++)
{
eg = &ACTIVEBKG->Backg[i+j*ACTIVEBKG->Xsize];
if (eg->nbpoly) return FALSE;
}
return TRUE;
}
void BIG_PURGE()
{
long IO_count = 0;
long LIGHT_count = 0;
long PATH_count = 0;
long FOG_count = 0;
if (OKBox("Do you really want to PURGE this level ???", "Confirm Box"))
{
for (long i = 1; i < inter.nbmax; i++)
{
if (inter.iobj[i])
if (CanPurge(&inter.iobj[i]->initpos))
{
// purge io
ARX_INTERACTIVE_DeleteByIndex(i, FLAG_NOCONFIRM | FLAG_DONTKILLDIR);
IO_count++;
}
}
for (int i = 0; i < MAX_LIGHTS; i++)
{
if (GLight[i])
if (CanPurge(&GLight[i]->pos))
{
// purge light
EERIE_LIGHT_ClearByIndex(i);
LIGHT_count++;
}
}
for (int i = nbARXpaths - 1; i >= 0; i--)
{
EERIE_3D pos;
pos.x = ARXpaths[i]->initpos.x;
pos.y = ARXpaths[i]->initpos.y;
pos.z = ARXpaths[i]->initpos.z;
if (CanPurge(&pos)) // To check (pos)
{
// purge path
ARX_PATHS_Delete(ARXpaths[i]);
PATH_count++;
}
}
for (int i = 0; i < MAX_FOG; i++)
{
if (fogs[i].exist)
{
if (CanPurge(&fogs[i].pos))
{
// purge fog
ARX_FOGS_KillByIndex(i);
FOG_count++;
}
}
}
char text[256];
sprintf(text, "Killed: %d IO; %d Lights; %d Paths; %d Fogs.",
IO_count, LIGHT_count, PATH_count, FOG_count);
ShowPopup(text);
}
}
//*************************************************************************************
//*************************************************************************************
EERIE_3DOBJ * _LoadTheObj(char * text, char * path)
{
char tex[256];
char texx[256];
char tex1[256];
EERIE_3DOBJ * wr;
MakeDir(texx, text);
File_Standardize(texx, tex);
if (path == NULL)
{
char tex2[256];
sprintf(tex2, "%sGraph\\obj3D\\textures\\", Project.workingdir);
File_Standardize(tex2, tex1);
}
else
{
char tex2[256];
strcpy(tex2, tex);
RemoveName(tex2);
strcat(tex2, path);
File_Standardize(tex2, tex1);
}
wr = TheoToEerie_Fast(tex1, tex, 0);
return wr;
}
//*************************************************************************************
//*************************************************************************************
void ReplaceSpecifics(char * text)
{
char temp[512];
UINT size_text = strlen(text);
for (unsigned long i = 0 ; i < size_text ; i++)
{
memcpy(temp, text + i, 5);
temp[5] = 0;
MakeUpcase(temp);
if (!strcmp(temp, "GRAPH"))
{
strcpy(temp, text + i);
sprintf(text, "%s%s", Project.workingdir, temp);
return;
}
}
return;
}
extern long NODIRCREATION;
extern long ADDED_IO_NOT_SAVED;
//*************************************************************************************
//*************************************************************************************
long DanaeSaveLevel(char * fic)
{
char fic2[512];
char fic3[512];
char _error[512];
DANAE_LS_HEADER dlh;
DANAE_LS_SCENE dls;
DANAE_LS_INTER dli;
DANAE_LS_LIGHTINGHEADER dll;
DANAE_LS_LIGHT dlight;
DANAE_LS_FOG dlf;
DANAE_LS_NODE dln;
char name[64];
long nb_inter = GetNumberInterWithOutScriptLoadForLevel(CURRENTLEVEL); // Without Player
unsigned char * dat = NULL;
unsigned long siz = 255;
long pos = 0;
unsigned long handle;
long bcount;
EERIE_BACKGROUND * eb = ACTIVEBKG;
long i, j;
EERIEPOLY * ep;
EERIE_BKG_INFO * eg;
memset(&dlh, 0, sizeof(DANAE_LS_HEADER));
memset(&dls, 0, sizeof(DANAE_LS_SCENE));
memset(&dli, 0, sizeof(DANAE_LS_INTER));
// Initializing datas
HERMES_DATE_TIME hdt;
GetDate(&hdt);
char tx[128];
char newtext[128];
sprintf(tx, "_%02d_%02d_%d__%dh%dmn", hdt.months, hdt.days, hdt.years, hdt.hours, hdt.mins);
SetExt(fic, ".DLF");
if (FileExist(fic))
{
strcpy(fic2, fic);
sprintf(newtext, "Backup_DLF_%s", tx);
SetExt(fic2, newtext);
rename(fic, fic2);
}
strcpy(fic2, fic);
SetExt(fic2, ".LLF");
if (FileExist(fic2))
{
strcpy(fic3, fic);
sprintf(newtext, "Backup_LLF_%s", tx);
SetExt(fic3, newtext);
rename(fic2, fic3);
}
SetExt(fic, ".DLF");
bcount = CountBkgVertex();
dlh.nb_nodes = CountNodes();
dlh.nb_nodeslinks = MAX_LINKS;
dlh.nb_lights = 0; // MUST BE 0 !!!!
dlh.nb_fogs = ARX_FOGS_Count();
dlh.nb_bkgpolys = BKG_CountPolys(ACTIVEBKG);
dlh.nb_childpolys = 0;
dlh.nb_ignoredpolys = BKG_CountIgnoredPolys(ACTIVEBKG);
dlh.nb_paths = nbARXpaths;
long allocsize = sizeof(DANAE_LS_HEADER) + sizeof(DANAE_LS_HEADER) * 1 + sizeof(DANAE_LS_INTER) * nb_inter + 512
+ sizeof(DANAE_LS_LIGHTINGHEADER) + (bcount + 1) * sizeof(D3DCOLOR)
+ dlh.nb_nodes * (sizeof(DANAE_LS_NODE) + 64 * MAX_LINKS)
+ dlh.nb_lights * sizeof(DANAE_LS_LIGHT)
+ 1000000
+ nbARXpaths * sizeof(DANAE_LS_PATH) + nbARXpaths * sizeof(DANAE_LS_PATHWAYS) * 30;
long tmpp = dlh.nb_bkgpolys * (sizeof(D3DCOLOR) + 2) + 1000000;
allocsize = __max(tmpp, allocsize);
dat = (unsigned char *)malloc(allocsize);
if (dat == NULL)
{
strcpy(_error, "Unable to allocate Buffer for save...");
goto error;
}
memset(dat, 0, allocsize);
// Preparing HEADER
dlh.version = CURRENT_VERSION;
if (NODIRCREATION) dlh.version = 1.004f;
strcpy(dlh.ident, "DANAE_FILE");
dlh.nb_scn = 1;
if (LastLoadedScene[0] == 0) dlh.nb_scn = 0;
dlh.nb_inter = nb_inter;
dlh.nb_zones = 0;
if (dlh.nb_scn != NULL)
{
dlh.pos_edit.x = subj.pos.x - Mscenepos.x;
dlh.pos_edit.y = subj.pos.y - Mscenepos.y;
dlh.pos_edit.z = subj.pos.z - Mscenepos.z;
}
else
{
dlh.pos_edit.x = subj.pos.x;
dlh.pos_edit.y = subj.pos.y;
dlh.pos_edit.z = subj.pos.z;
}
dlh.angle_edit.a = player.angle.a;
dlh.angle_edit.b = player.angle.b;
dlh.angle_edit.g = player.angle.g;
dlh.lighting = FALSE; // MUST BE FALSE !!!!
_time32(&dlh.time);
GetUserName(dlh.lastuser, &siz);
memcpy(dat, &dlh, sizeof(DANAE_LS_HEADER));
pos += sizeof(DANAE_LS_HEADER);
// Preparing SCENE DATA
if (dlh.nb_scn > 0)
{
strcpy(dls.name, LastLoadedScene);
memcpy(dat + pos, &dls, sizeof(DANAE_LS_SCENE));
pos += sizeof(DANAE_LS_SCENE);
}
//preparing INTER DATA
for (i = 1; i < inter.nbmax; i++) // Ignoring Player Data
{
if ((inter.iobj[i] != NULL) && (!inter.iobj[i]->scriptload)
&& (inter.iobj[i]->truelevel == CURRENTLEVEL))
{
INTERACTIVE_OBJ * io = inter.iobj[i];
memset(&dli, 0, sizeof(DANAE_LS_INTER));
if (dlh.nb_scn != NULL)
{
dli.pos.x = io->initpos.x - Mscenepos.x;
dli.pos.y = io->initpos.y - Mscenepos.y;
dli.pos.z = io->initpos.z - Mscenepos.z;
}
else
{
dli.pos.x = io->initpos.x;
dli.pos.y = io->initpos.y;
dli.pos.z = io->initpos.z;
}
dli.angle.a = io->initangle.a;
dli.angle.b = io->initangle.b;
dli.angle.g = io->initangle.g;
strcpy(dli.name, io->filename);
if (io->ident == 0)
{
MakeIOIdent(io);
}
dli.ident = io->ident;
if (io->ioflags & IO_FREEZESCRIPT)
dli.flags = IO_FREEZESCRIPT;
inter.iobj[i]->EditorFlags &= ~EFLAG_NOTSAVED;
memcpy(dat + pos, &dli, sizeof(DANAE_LS_INTER));
pos += sizeof(DANAE_LS_INTER);
}
}
long nbvert;
for (i = 0; i < MAX_FOG; i++)
{
if (fogs[i].exist)
{
memset(&dlf, 0, sizeof(DANAE_LS_LIGHT));
dlf.rgb.r = fogs[i].rgb.r;
dlf.rgb.g = fogs[i].rgb.g;
dlf.rgb.b = fogs[i].rgb.b;
dlf.angle.a = fogs[i].angle.a;
dlf.angle.b = fogs[i].angle.b;
dlf.angle.g = fogs[i].angle.g;
dlf.pos.x = fogs[i].pos.x - Mscenepos.x;
dlf.pos.y = fogs[i].pos.y - Mscenepos.y;
dlf.pos.z = fogs[i].pos.z - Mscenepos.z;
dlf.blend = fogs[i].blend;
dlf.frequency = fogs[i].frequency;
dlf.move.x = fogs[i].move.x;
dlf.move.y = fogs[i].move.y;
dlf.move.z = fogs[i].move.z;
dlf.rotatespeed = fogs[i].rotatespeed;
dlf.scale = fogs[i].scale;
dlf.size = fogs[i].size;
dlf.special = fogs[i].special;
dlf.speed = fogs[i].speed;
dlf.tolive = fogs[i].tolive;
memcpy(dat + pos, &dlf, sizeof(DANAE_LS_FOG));
pos += sizeof(DANAE_LS_FOG);
}
}
for (i = 0; i < nodes.nbmax; i++)
{
if (nodes.nodes[i].exist)
{
memset(&dln, 0, sizeof(DANAE_LS_NODE));
strcpy(dln.name, nodes.nodes[i].name);
dln.pos.x = nodes.nodes[i].pos.x - Mscenepos.x;
dln.pos.y = nodes.nodes[i].pos.y - Mscenepos.y;
dln.pos.z = nodes.nodes[i].pos.z - Mscenepos.z;
memcpy(dat + pos, &dln, sizeof(DANAE_LS_NODE));
pos += sizeof(DANAE_LS_NODE);
for (long j = 0; j < MAX_LINKS; j++)
{
memset(name, 0, 64);
if (nodes.nodes[i].link[j] != -1)
{
if (nodes.nodes[nodes.nodes[i].link[j]].exist)
strcpy(name, nodes.nodes[nodes.nodes[i].link[j]].name);
}
memcpy(dat + pos, name, 64);
pos += 64;
}
}
}
DANAE_LS_PATH dlp;
DANAE_LS_PATHWAYS dlpw;
for (i = 0; i < nbARXpaths; i++)
{
memset(&dlp, 0, sizeof(DANAE_LS_PATH));
dlp.flags = (short)ARXpaths[i]->flags;
dlp.idx = ARXpaths[i]->idx;
dlp.initpos.x = ARXpaths[i]->initpos.x - Mscenepos.x;
dlp.initpos.y = ARXpaths[i]->initpos.y - Mscenepos.y;
dlp.initpos.z = ARXpaths[i]->initpos.z - Mscenepos.z;
dlp.pos.x = ARXpaths[i]->pos.x - Mscenepos.x;
dlp.pos.y = ARXpaths[i]->pos.y - Mscenepos.y;
dlp.pos.z = ARXpaths[i]->pos.z - Mscenepos.z;
strcpy(dlp.name, ARXpaths[i]->name);
dlp.nb_pathways = ARXpaths[i]->nb_pathways;
dlp.height = ARXpaths[i]->height;
strcpy(dlp.ambiance, ARXpaths[i]->ambiance);
dlp.amb_max_vol = ARXpaths[i]->amb_max_vol;
dlp.farclip = ARXpaths[i]->farclip;
dlp.reverb = ARXpaths[i]->reverb;
dlp.rgb.r = ARXpaths[i]->rgb.r;
dlp.rgb.g = ARXpaths[i]->rgb.g;
dlp.rgb.b = ARXpaths[i]->rgb.b;
memcpy(dat + pos, &dlp, sizeof(DANAE_LS_PATH));
pos += sizeof(DANAE_LS_PATH);
for (long j = 0; j < dlp.nb_pathways; j++)
{
memset(&dlpw, 0, sizeof(DANAE_LS_PATHWAYS));
dlpw.flag = ARXpaths[i]->pathways[j].flag;
dlpw.rpos.x = ARXpaths[i]->pathways[j].rpos.x;
dlpw.rpos.y = ARXpaths[i]->pathways[j].rpos.y;
dlpw.rpos.z = ARXpaths[i]->pathways[j].rpos.z;
float fValue = ARXpaths[i]->pathways[j]._time ;
ARX_CHECK_ULONG(fValue);
dlpw.time = ARX_CLEAN_WARN_CAST_ULONG(fValue);
memcpy(dat + pos, &dlpw, sizeof(DANAE_LS_PATHWAYS));
pos += sizeof(DANAE_LS_PATHWAYS);
}
}
//Saving Special Polys
if (pos > allocsize)
{
sprintf(_error, "Badly Allocated SaveBuffer...%s", fic);
goto error;
}
// Now Saving Whole Buffer
if (!(handle = FileOpenWrite(fic)))
{
sprintf(_error, "Unable to Open %s for Write...", fic);
goto error;
}
if (FileWrite(handle, dat, sizeof(DANAE_LS_HEADER)) != sizeof(DANAE_LS_HEADER))
{
sprintf(_error, "Unable to Write to %s", fic);
goto error;
}
char * compressed;
compressed = NULL;
long cpr_pos;
cpr_pos = 0;
compressed = STD_Implode((char *)(dat + sizeof(DANAE_LS_HEADER)), pos - sizeof(DANAE_LS_HEADER), &cpr_pos);
if (FileWrite(handle, compressed, cpr_pos) != cpr_pos)
{
free(dat);
return FALSE;
}
free(compressed);
FileCloseWrite(handle);
//////////////////////////////////////////////////////////////////////////////
//Now Save Separate IO Ref Sheet
//////////////////////////////////////////////////////////////////////////////
//Now Save Separate LLF Lighting File
strcpy(fic2, fic);
SetExt(fic2, ".LLF");
pos = 0;
DANAE_LLF_HEADER llh;
memset(&llh, 0, sizeof(DANAE_LLF_HEADER));
// Preparing HEADER
llh.version = CURRENT_VERSION;
llh.nb_lights = EERIE_LIGHT_Count();
llh.nb_bkgpolys = BKG_CountPolys(ACTIVEBKG);
strcpy(llh.ident, "DANAE_LLH_FILE");
_time32(&llh.time);
GetUserName(llh.lastuser, &siz);
memcpy(dat, &llh, sizeof(DANAE_LLF_HEADER));
pos += sizeof(DANAE_LLF_HEADER);
for (i = 0; i < MAX_LIGHTS; i++)
{
EERIE_LIGHT * el = GLight[i];
if (el != NULL)
if (!(el->type & TYP_SPECIAL1))
{
memset(&dlight, 0, sizeof(DANAE_LS_LIGHT));
dlight.fallend = el->fallend;
dlight.fallstart = el->fallstart;
dlight.intensity = el->intensity;
dlight.pos.x = el->pos.x - Mscenepos.x;
dlight.pos.y = el->pos.y - Mscenepos.y;
dlight.pos.z = el->pos.z - Mscenepos.z;
dlight.rgb.r = el->rgb.r;
dlight.rgb.g = el->rgb.g;
dlight.rgb.b = el->rgb.b;
dlight.extras = el->extras;
dlight.ex_flicker.r = el->ex_flicker.r;
dlight.ex_flicker.g = el->ex_flicker.g;
dlight.ex_flicker.b = el->ex_flicker.b;
dlight.ex_radius = el->ex_radius;
dlight.ex_frequency = el->ex_frequency;
dlight.ex_size = el->ex_size;
dlight.ex_speed = el->ex_speed;
dlight.ex_flaresize = el->ex_flaresize;
memcpy(dat + pos, &dlight, sizeof(DANAE_LS_LIGHT));
pos += sizeof(DANAE_LS_LIGHT);
}
}
//Saving Special Polys
memset(&dll, 0, sizeof(DANAE_LS_LIGHTINGHEADER));
dll.nb_values = bcount;
dll.ModeLight = ModeLight;
dll.ViewMode = ViewMode;
memcpy(dat + pos, &dll, sizeof(DANAE_LS_LIGHTINGHEADER));
pos += sizeof(DANAE_LS_LIGHTINGHEADER);
{
for (j = 0; j < eb->Zsize; j++)
for (i = 0; i < eb->Xsize; i++)
{
eg = (EERIE_BKG_INFO *)&eb->Backg[i+j*eb->Xsize];
for (long l = 0; l < eg->nbpoly; l++)
{
ep = &eg->polydata[l];
if (ep != NULL)
{
if (ep->type & POLY_QUAD) nbvert = 4;
else nbvert = 3;
for (long k = 0; k < nbvert; k++)
{
D3DCOLOR tmp = ep->v[k].color;
memcpy(dat + pos, &tmp, sizeof(D3DCOLOR));
pos += sizeof(D3DCOLOR);
}
}
}
}
}
if (pos > allocsize)
{
sprintf(_error, "Badly Allocated SaveBuffer...%s", fic2);
goto error;
}
// Now Saving Whole Buffer
if (!(handle = FileOpenWrite(fic2)))
{
sprintf(_error, "Unable to Open %s for Write...", fic2);
goto error;
}
compressed = NULL;
cpr_pos = 0;
compressed = STD_Implode((char *)dat, pos, &cpr_pos);
if (FileWrite(handle, compressed, cpr_pos) != cpr_pos)
{
free(compressed);
sprintf(_error, "Unable to Write to %s", fic2);
goto error;
}
free(compressed);
FileCloseWrite(handle);
// End of LLF Save
//////////////////////////////////////////////////////////////////////////////
// Finish
free(dat);
ADDED_IO_NOT_SAVED = 0;
return 1;
error:
;
ShowPopup(_error);
if (dat) free(dat);
return -1;
}
extern char LastLoadedDLF[512];
extern long LOADEDD;
//*************************************************************************************
//*************************************************************************************
void WriteIOInfo(INTERACTIVE_OBJ * io, char * dir)
{
char dfile[256];
char temp[256];
FILE * fic;
HERMES_DATE_TIME hdt;
if (DirectoryExist(dir))
{
strcpy(temp, GetName(io->filename));
sprintf(dfile, "%s\\%s.log", dir, temp);
if ((fic = fopen(dfile, "w")) != NULL)
{
char name[256];
unsigned long num = 255;
fprintf(fic, "Object : %s%04d\n", temp, io->ident);
fprintf(fic, "_______________________________\n\n");
GetUserName(name, &num);
fprintf(fic, "Creator : %s\n", name);
GetDate(&hdt);
fprintf(fic, "Date : %02d/%02d/%d\n", hdt.days, hdt.months, hdt.years);
fprintf(fic, "Time : %dh%d\n", hdt.hours, hdt.mins);
fprintf(fic, "Level : %s\n", LastLoadedScene);
if (LastLoadedDLF[0] != 0)
fprintf(fic, "DLF File : %s\n", LastLoadedDLF);
else
fprintf(fic, "DLF File : None\n");
fprintf(fic, "Position : x %8.f y %8.f z %8.f (relative to anchor)\n",
io->initpos.x - Mscenepos.x, io->initpos.y - Mscenepos.y, io->initpos.z - Mscenepos.z);
fclose(fic);
}
}
}
//*************************************************************************************
//*************************************************************************************
void LogDirCreation(char * dir)
{
char dfile[256];
FILE * fic;
HERMES_DATE_TIME hdt;
if (DirectoryExist(dir))
{
sprintf(dfile, "%s\\Dir_Creation.log", Project.workingdir);
if ((fic = fopen(dfile, "a+")) != NULL)
{
char name[256];
unsigned long num = 255;
GetUserName(name, &num);
GetDate(&hdt);
fprintf(fic, "%02d/%02d/%4d %2dh%02d %s %s\n", hdt.days, hdt.months, hdt.years, hdt.hours, hdt.mins, dir, name);
fclose(fic);
}
}
}
//*************************************************************************************
//*************************************************************************************
void LogDirDestruction(char * dir)
{
char dfile[256];
FILE * fic;
HERMES_DATE_TIME hdt;
if (DirectoryExist(dir))
{
sprintf(dfile, "%s\\Dir_Creation.log", Project.workingdir);
if ((fic = fopen(dfile, "a+")) != NULL)
{
char name[256];
unsigned long num = 255;
GetUserName(name, &num);
GetDate(&hdt);
fprintf(fic, "%02d/%02d/%4d %2dh%02d DESTROYED %s %s\n", hdt.days, hdt.months, hdt.years, hdt.hours, hdt.mins, dir, name);
fclose(fic);
}
}
}
//*************************************************************************************
// Checks for IO created during this session but not saved...
//*************************************************************************************
void CheckIO_NOT_SAVED()
{
char temp[512];
char temp2[512];
char temp3[512];
if (ADDED_IO_NOT_SAVED)
{
if (OKBox("You have added objects, but not saved them...\nDELETE THEM ??????", "Danae WARNING"))
{
for (long i = 1; i < inter.nbmax; i++) // ignoring player
{
if ((inter.iobj[i] != NULL) && (!inter.iobj[i]->scriptload))
if (inter.iobj[i]->EditorFlags & EFLAG_NOTSAVED)
{
if (inter.iobj[i]->ident > 0)
{
sprintf(temp, inter.iobj[i]->filename);
strcpy(temp2, GetName(temp));
RemoveName(temp);
sprintf(temp, "%s%s_%04d.", temp, temp2, inter.iobj[i]->ident);
if (DirectoryExist(temp))
{
sprintf(temp3, "Really remove Directory & Directory Contents ?\n\n%s", temp);
if (OKBox(temp3, "WARNING"))
{
strcat(temp, "\\");
LogDirDestruction(temp);
KillAllDirectory(temp);
}
}
ReleaseInter(inter.iobj[i]);
}
}
}
}
}
}
//*************************************************************************************
//*************************************************************************************
void SaveIOScript(INTERACTIVE_OBJ * io, long fl)
{
int fic;
char temp[256];
char temp2[256];
char temp3[256];
switch (fl)
{
case 1: //CLASS SCRIPT
strcpy(temp, io->filename);
SetExt(temp, "ASL");
if ((fic = _open(temp, _O_WRONLY | _O_TRUNC | _O_CREAT | _O_BINARY, _S_IWRITE)) != -1)
{
_write(fic, io->script.data, strlen(io->script.data));
_close(fic);
}
else ShowPopup("Unable To Save...");
ARX_SCRIPT_ComputeShortcuts(&io->script);
break;
case 2: //LOCAL SCRIPT
if (io->ident != 0)
{
strcpy(temp, io->filename);
strcpy(temp2, GetName(temp));
RemoveName(temp);
sprintf(temp3, "%s%s_%04d", temp, temp2, io->ident);
sprintf(temp, "%s\\%s.asl", temp3, temp2);
if (DirectoryExist(temp3))
{
if ((fic = _open(temp, _O_WRONLY | _O_TRUNC | _O_CREAT | _O_BINARY, _S_IWRITE)) != -1)
{
_write(fic, io->over_script.data, strlen(io->over_script.data));
_close(fic);
}
else ShowPopup("Unable To Save...");
}
else ShowPopup("Local DIR don't Exists...");
}
else ShowPopup("NO IDENT...");
ARX_SCRIPT_ComputeShortcuts(&io->over_script);
break;
}
}
extern long FORCE_IO_INDEX;
INTERACTIVE_OBJ * LoadInter_Ex(DANAE_LS_INTER * dli, EERIE_3D * trans)
{
char nameident[256];
char tmp[512];
char tmp2[512];
char temp[512];
long FileSize;
INTERACTIVE_OBJ * io;
sprintf(nameident, "%s_%04d", GetName(dli->name), dli->ident);
long t;
t = GetTargetByNameTarget(nameident);
if (FORCE_IO_INDEX != -1)
{
io = AddInteractive(GDevice, dli->name, dli->ident, NO_MESH | NO_ON_LOAD);
goto suite;
}
sprintf(nameident, "%s_%04d", GetName(dli->name), dli->ident);
t = GetTargetByNameTarget(nameident);
if (t >= 0)
{
return inter.iobj[t];
}
ReplaceSpecifics(dli->name);
io = AddInteractive(GDevice, dli->name, dli->ident, NO_MESH | NO_ON_LOAD);
suite:
;
if (io)
{
RestoreInitialIOStatusOfIO(io);
ARX_INTERACTIVE_HideGore(io);
io->lastpos.x = io->initpos.x = io->pos.x = dli->pos.x + trans->x; // RELATIVE !!!!!!!!!
io->lastpos.y = io->initpos.y = io->pos.y = dli->pos.y + trans->y;
io->lastpos.z = io->initpos.z = io->pos.z = dli->pos.z + trans->z;
io->move.x = io->move.y = io->move.z = 0.f;
io->initangle.a = io->angle.a = dli->angle.a;
io->initangle.b = io->angle.b = dli->angle.b;
io->initangle.g = io->angle.g = dli->angle.g;
if (!NODIRCREATION)
{
io->ident = dli->ident;
sprintf(tmp, io->filename);
strcpy(tmp2, GetName(tmp));
RemoveName(tmp);
sprintf(tmp, "%s%s_%04d", tmp, tmp2, io->ident);
if (PAK_DirectoryExist(tmp))
{
sprintf(tmp, io->filename);
strcpy(tmp2, GetName(tmp));
RemoveName(tmp);
sprintf(tmp, "%s%s_%04d\\%s.asl", tmp, tmp2, io->ident, tmp2);
if (PAK_FileExist(tmp))
{
if (io->over_script.data)
{
free(io->over_script.data);
io->over_script.data = NULL;
}
io->over_script.data = (char *)PAK_FileLoadMallocZero(tmp, &FileSize);
if (io->over_script.data != NULL)
{
io->over_script.size = FileSize;
InitScript(&io->over_script);
}
if (io->script.data != NULL)
io->over_script.master = &io->script;
else io->over_script.master = NULL;
}
}
else
{
CreateDirectory(tmp, NULL);
LogDirCreation(tmp);
WriteIOInfo(io, temp);
}
}
if (SendIOScriptEvent(io, SM_LOAD, "", NULL) == ACCEPT)
{
if (io->obj == NULL)
{
char temp[256];
char temp2[256];
strcpy(temp2, io->filename);
sprintf(temp, "%sGraph\\Obj3D\\Textures\\", Project.workingdir);
if (io->ioflags & IO_ITEM)
io->obj = TheoToEerie_Fast(temp, temp2, 0, GDevice);
else if (io->ioflags & IO_NPC)
io->obj = TheoToEerie_Fast(temp, temp2, TTE_NO_PHYSICS_BOX | TTE_NPC, GDevice);
else
io->obj = TheoToEerie_Fast(temp, temp2, TTE_NO_PHYSICS_BOX, GDevice);
if (io->ioflags & IO_NPC)
EERIE_COLLISION_Cylinder_Create(io);
}
}
InterTreeViewItemAdd(io);
}
return io;
}
long LastLoadedLightningNb = 0;
D3DCOLOR * LastLoadedLightning = NULL;
EERIE_3D loddpos;
EERIE_3D MSP;
extern long DEBUGCODE;
//*************************************************************************************
//*************************************************************************************
extern char _CURRENTLOAD_[256];
void ShowCurLoadInfo(char * string)
{
memset(_CURRENTLOAD_, 0, 256);
}
extern long FASTmse;
long DONT_LOAD_INTERS = 0;
long FAKE_DIR = 0;
long DanaeLoadLevel(LPDIRECT3DDEVICE7 pd3dDevice, char * fic)
{
char _error[512];
DANAE_LS_HEADER dlh;
DANAE_LS_SCENE * dls;
DANAE_LS_INTER * dli;
DANAE_LS_LIGHT * dlight;
DANAE_LS_FOG * dlf;
DANAE_LS_LIGHTINGHEADER * dll;
DANAE_LS_NODE * dln;
char name[64];
char temp[512];
EERIE_3D trans;
unsigned char * dat = NULL;
long pos = 0;
long i;
long FileSize = 0;
char tstr[128];
HERMES_DATE_TIME hdt;
ShowCurLoadInfo("Starting Level Loading");
CURRENTLEVEL = GetLevelNumByName(fic);
GetDate(&hdt);
sprintf(tstr, "%2dh%02dm%02d LOADLEVEL start", hdt.hours, hdt.mins, hdt.secs);
ForceSendConsole(tstr, 1, 0, (HWND)1);
SetExt(fic, ".DLF");
char fic2[512];
strcpy(fic2, fic);
SetExt(fic2, ".LLF");
if (!PAK_FileExist(fic))
{
sprintf(_error, "Unable to find %s", fic);
goto loaderror;
}
strcpy(LastLoadedDLF, fic);
dat = (unsigned char *)PAK_FileLoadMalloc(fic, &FileSize);
PROGRESS_BAR_COUNT += 1.f;
LoadLevelScreen();
memcpy(&dlh, dat, sizeof(DANAE_LS_HEADER));
pos += sizeof(DANAE_LS_HEADER);
if (dlh.version > CURRENT_VERSION) // using compression
{
ShowPopup("DANAE Version too OLD to load this File... Please upgrade to a new DANAE Version...");
free(dat);
dat = NULL;
return -1;
}
if (dlh.version >= 1.44f) // using compression
{
char * torelease = (char *)dat;
char * compressed = (char *)(dat + pos);
long cpr_pos;
cpr_pos = 0;
dat = (unsigned char *)STD_Explode(compressed, FileSize - pos, &FileSize);
if (dat == NULL)
{
free(torelease);
goto loaderror;
}
free(torelease);
compressed = NULL;
pos = 0;
}
loddpos.x = subj.pos.x = dlh.pos_edit.x;
loddpos.y = subj.pos.y = dlh.pos_edit.y;
loddpos.z = subj.pos.z = dlh.pos_edit.z;
player.desiredangle.a = player.angle.a = subj.angle.a = dlh.angle_edit.a;
player.desiredangle.b = player.angle.b = subj.angle.b = dlh.angle_edit.b;
player.desiredangle.g = player.angle.g = subj.angle.g = dlh.angle_edit.g;
if (strcmp(dlh.ident, "DANAE_FILE"))
{
sprintf(_error, "File %s is not a valid file", fic);
goto loaderror;
}
if (dlh.version < 1.001f)
{
dlh.nb_nodes = 0;
}
// Loading Scene
if (dlh.nb_scn >= 1)
{
dls = (DANAE_LS_SCENE *)(dat + pos);
pos += sizeof(DANAE_LS_SCENE);
char ftemp[256];
if (FAKE_DIR)
{
strcpy(ftemp, fic + strlen(Project.workingdir));
RemoveName(ftemp);
strcpy(temp, fic);
RemoveName(temp);
FAKE_DIR = 0;
}
else // normal load
{
strcpy(ftemp, dls->name);
RemoveName(ftemp);
MakeDir(temp, dls->name);
RemoveName(temp);
}
if (FastSceneLoad(ftemp))
{
FASTmse = 1;
goto suite;
}
ARX_SOUND_PlayCinematic("Editor_Humiliation.wav");
mse = PAK_MultiSceneToEerie(temp);
PROGRESS_BAR_COUNT += 20.f;
LoadLevelScreen();
suite:
;
EERIEPOLY_Compute_PolyIn();
strcpy(LastLoadedScene, ftemp);
RemoveName(LastLoadedScene);
}
if (FASTmse)
{
trans.x = Mscenepos.x;
trans.y = Mscenepos.y;
trans.z = Mscenepos.z;
player.pos.x = loddpos.x + trans.x;
player.pos.y = loddpos.y + trans.y;
player.pos.z = loddpos.z + trans.z;
}
else if (mse != NULL)
{
Mscenepos.x = -mse->cub.xmin - (mse->cub.xmax - mse->cub.xmin) * DIV2 + ((float)ACTIVEBKG->Xsize * (float)ACTIVEBKG->Xdiv) * DIV2;
Mscenepos.z = -mse->cub.zmin - (mse->cub.zmax - mse->cub.zmin) * DIV2 + ((float)ACTIVEBKG->Zsize * (float)ACTIVEBKG->Zdiv) * DIV2;
float t1 = (float)(long)(mse->point0.x / BKG_SIZX);
float t2 = (float)(long)(mse->point0.z / BKG_SIZZ);
t1 = mse->point0.x - t1 * BKG_SIZX;
t2 = mse->point0.z - t2 * BKG_SIZZ;
Mscenepos.x = (float)((long)(Mscenepos.x / BKG_SIZX)) * BKG_SIZX + (float)BKG_SIZX * DIV2;
Mscenepos.z = (float)((long)(Mscenepos.z / BKG_SIZZ)) * BKG_SIZZ + (float)BKG_SIZZ * DIV2;
mse->pos.x = Mscenepos.x = Mscenepos.x + BKG_SIZX - t1;
mse->pos.z = Mscenepos.z = Mscenepos.z + BKG_SIZZ - t2;
Mscenepos.y = mse->pos.y = -mse->cub.ymin - 100.f - mse->point0.y;
lastteleport.x = map.pos.x = player.pos.x = subj.pos.x = moveto.x = mse->pos.x + mse->point0.x;
lastteleport.z = map.pos.z = player.pos.z = subj.pos.z = moveto.z = mse->pos.z + mse->point0.z;
lastteleport.y = player.pos.y = subj.pos.y = moveto.y = mse->pos.y + mse->point0.y;
lastteleport.y -= 180.f;
player.pos.y = subj.pos.y -= 180.f;
trans.x = mse->pos.x;
trans.y = mse->pos.y;
trans.z = mse->pos.z;
}
else
{
lastteleport.x = 0.f;
lastteleport.y = PLAYER_BASE_HEIGHT;
lastteleport.z = 0.f;
trans.x = 0;
trans.y = 0;
trans.z = 0;
Mscenepos.x = 0.f;
Mscenepos.z = 0.f;
Mscenepos.y = 0.f;
}
MSP.x = trans.x;
MSP.y = trans.y;
MSP.z = trans.z;
ShowCurLoadInfo("Loading Interactive Objects");
float increment = 0.f;
if (dlh.nb_inter > 0)
{
increment = (60.f / (float)dlh.nb_inter);
}
else
{
PROGRESS_BAR_COUNT += 60;
LoadLevelScreen();
}
for (i = 0 ; i < dlh.nb_inter ; i++)
{
PROGRESS_BAR_COUNT += increment;
LoadLevelScreen();
dli = (DANAE_LS_INTER *)(dat + pos);
pos += sizeof(DANAE_LS_INTER);
if (!DONT_LOAD_INTERS)
{
LoadInter_Ex(dli, &trans);
}
}
if (dlh.lighting)
{
if (!PAK_FileExist(fic2))
{
dll = (DANAE_LS_LIGHTINGHEADER *)(dat + pos);
pos += sizeof(DANAE_LS_LIGHTINGHEADER);
long bcount = dll->nb_values;
LastLoadedLightningNb = bcount;
if (LastLoadedLightning != NULL)
{
free(LastLoadedLightning);
LastLoadedLightning = NULL;
}
//DANAE_LS_VLIGHTING
D3DCOLOR * ll = LastLoadedLightning = (D3DCOLOR *)malloc(sizeof(D3DCOLOR) * bcount);
if (dlh.version > 1.001f)
{
memcpy(LastLoadedLightning, dat + pos, sizeof(D3DCOLOR)*bcount);
pos += sizeof(D3DCOLOR) * bcount;
}
else
{
DANAE_LS_VLIGHTING dlv;
while (bcount)
{
memcpy(&dlv, dat + pos, sizeof(DANAE_LS_VLIGHTING));
pos += sizeof(DANAE_LS_VLIGHTING);
*ll = (0xff000000L | (((long)(dlv.r) & 255) << 16) | (((long)(dlv.g) & 255) << 8) | (long)(dlv.b) & 255);
ll++;
bcount--;
}
}
ModeLight = dll->ModeLight;
ViewMode = dll->ViewMode;
ViewMode &= ~VIEWMODE_WIRE;
}
else
{
dll = (DANAE_LS_LIGHTINGHEADER *)(dat + pos);
pos += sizeof(DANAE_LS_LIGHTINGHEADER);
long bcount = dll->nb_values;
pos += sizeof(D3DCOLOR) * bcount;
ModeLight = dll->ModeLight;
ViewMode = dll->ViewMode;
ViewMode &= ~VIEWMODE_WIRE;
}
}
PROGRESS_BAR_COUNT += 1;
LoadLevelScreen();
if (dlh.version < 1.003f) dlh.nb_lights = 0;
if (!PAK_FileExist(fic2))
{
if (dlh.nb_lights != 0)
{
EERIE_LIGHT_GlobalInit();
}
long j;
for (i = 0; i < dlh.nb_lights; i++)
{
dlight = (DANAE_LS_LIGHT *)(dat + pos);
pos += sizeof(DANAE_LS_LIGHT);
j = EERIE_LIGHT_Create();
if (j >= 0)
{
EERIE_LIGHT * el = GLight[j];
el->exist = 1;
el->treat = 1;
el->fallend = dlight->fallend;
el->fallstart = dlight->fallstart;
el->falldiff = el->fallend - el->fallstart;
el->falldiffmul = 1.f / el->falldiff;
el->intensity = dlight->intensity;
el->pos.x = dlight->pos.x;
el->pos.y = dlight->pos.y;
el->pos.z = dlight->pos.z;
el->rgb.r = dlight->rgb.r;
el->rgb.g = dlight->rgb.g;
el->rgb.b = dlight->rgb.b;
ARX_CHECK_SHORT(dlight->extras);
el->extras = ARX_CLEAN_WARN_CAST_SHORT(dlight->extras);
el->ex_flicker.r = dlight->ex_flicker.r;
el->ex_flicker.g = dlight->ex_flicker.g;
el->ex_flicker.b = dlight->ex_flicker.b;
el->ex_radius = dlight->ex_radius;
el->ex_frequency = dlight->ex_frequency;
el->ex_size = dlight->ex_size;
el->ex_speed = dlight->ex_speed;
el->tl = -1;
el->sample = ARX_SOUND_INVALID_RESOURCE;
if ((el->extras & EXTRAS_SPAWNFIRE))
{
el->extras |= EXTRAS_FLARE;
if (el->extras & EXTRAS_FIREPLACE)
el->ex_flaresize = 95.f;
else
el->ex_flaresize = 40.f;
}
}
}
}
else
{
pos += sizeof(DANAE_LS_LIGHT) * dlh.nb_lights;
}
ShowCurLoadInfo("Loading FOGS");
ARX_FOGS_Clear();
for (i = 0; i < dlh.nb_fogs; i++)
{
dlf = (DANAE_LS_FOG *)(dat + pos);
pos += sizeof(DANAE_LS_FOG);
long n = ARX_FOGS_GetFree();
if (n > -1)
{
FOG_DEF * fd = &fogs[n];
fd->exist = 1;
fd->rgb.r = dlf->rgb.r;
fd->rgb.g = dlf->rgb.g;
fd->rgb.b = dlf->rgb.b;
fd->angle.a = dlf->angle.a;
fd->angle.b = dlf->angle.b;
fd->angle.g = dlf->angle.g;
fd->pos.x = dlf->pos.x + trans.x;
fd->pos.y = dlf->pos.y + trans.y;
fd->pos.z = dlf->pos.z + trans.z;
fd->blend = dlf->blend;
fd->frequency = dlf->frequency;
fd->move.x = dlf->move.x;
fd->move.y = dlf->move.y;
fd->move.z = dlf->move.z;
fd->rotatespeed = dlf->rotatespeed;
fd->scale = dlf->scale;
fd->size = dlf->size;
fd->special = dlf->special;
fd->speed = dlf->speed;
fd->tolive = dlf->tolive;
fd->move.x = 1.f;
fd->move.y = 0.f;
fd->move.z = 0.f;
EERIE_3D out;
float t;
t = DEG2RAD(MAKEANGLE(fd->angle.b));
_YRotatePoint(&fd->move, &out, EEcos(t), EEsin(t));
t = DEG2RAD(MAKEANGLE(fd->angle.a));
_XRotatePoint(&out, &fd->move, EEcos(t), EEsin(t));
}
}
PROGRESS_BAR_COUNT += 2.f;
LoadLevelScreen();
ShowCurLoadInfo("Loading Nodes");
ClearNodes();
for (i = 0; i < dlh.nb_nodes; i++)
{
nodes.nodes[i].exist = 1;
nodes.nodes[i].selected = 0;
dln = (DANAE_LS_NODE *)(dat + pos);
pos += sizeof(DANAE_LS_NODE);
strcpy(nodes.nodes[i].name, dln->name);
nodes.nodes[i].pos.x = dln->pos.x + trans.x;
nodes.nodes[i].pos.y = dln->pos.y + trans.y;
nodes.nodes[i].pos.z = dln->pos.z + trans.z;
for (long j = 0; j < dlh.nb_nodeslinks; j++)
{
memcpy(name, dat + pos, 64);
pos += 64;
if (name[0] != 0)
{
strcpy(nodes.nodes[i].lnames[j], name);
}
}
}
RestoreNodeNumbers();
ShowCurLoadInfo("Loading Paths");
ARX_PATH_ReleaseAllPath();
DANAE_LS_PATH * dlp;
DANAE_LS_PATHWAYS * dlpw;
if (dlh.nb_paths)
{
ARXpaths = (ARX_PATH **)malloc(sizeof(ARX_PATH *) * dlh.nb_paths);
nbARXpaths = dlh.nb_paths;
}
for (i = 0; i < dlh.nb_paths; i++)
{
ARX_PATH * ap = ARXpaths[i] = (ARX_PATH *)malloc(sizeof(ARX_PATH));
memset(ap, 0, sizeof(ARX_PATH));
dlp = (DANAE_LS_PATH *)(dat + pos);
pos += sizeof(DANAE_LS_PATH);
ap->flags = dlp->flags;
ap->idx = dlp->idx;
ap->initpos.x = dlp->initpos.x + trans.x;
ap->initpos.y = dlp->initpos.y + trans.y;
ap->initpos.z = dlp->initpos.z + trans.z;
ap->pos.x = dlp->pos.x + trans.x;
ap->pos.y = dlp->pos.y + trans.y;
ap->pos.z = dlp->pos.z + trans.z;
strcpy(ap->name, dlp->name);
ap->nb_pathways = dlp->nb_pathways;
ap->height = dlp->height;
strcpy(ap->ambiance, dlp->ambiance);
ap->amb_max_vol = dlp->amb_max_vol;
if (ap->amb_max_vol <= 1.f) ap->amb_max_vol = 100.f;
ap->farclip = dlp->farclip;
ap->reverb = dlp->reverb;
ap->rgb.r = dlp->rgb.r;
ap->rgb.g = dlp->rgb.g;
ap->rgb.b = dlp->rgb.b;
ARX_PATHWAY * app = ap->pathways = (ARX_PATHWAY *)malloc(sizeof(ARX_PATHWAY) * dlp->nb_pathways);
memset(app, 0, sizeof(ARX_PATHWAY)*dlp->nb_pathways);
for (long j = 0; j < dlp->nb_pathways; j++)
{
dlpw = (DANAE_LS_PATHWAYS *)(dat + pos);
pos += sizeof(DANAE_LS_PATHWAYS);
app[j].flag = dlpw->flag;
app[j].rpos.x = dlpw->rpos.x;
app[j].rpos.y = dlpw->rpos.y;
app[j].rpos.z = dlpw->rpos.z;
app[j]._time = ARX_CLEAN_WARN_CAST_FLOAT(dlpw->time);
}
}
ARX_PATH_ComputeAllBoundingBoxes();
PROGRESS_BAR_COUNT += 5.f;
LoadLevelScreen();
//////////////////////////////////////////////////////////////////////////////
//Now LOAD Separate LLF Lighting File
free(dat);
pos = 0;
DANAE_LLF_HEADER * llh;
if (!PAK_FileExist(fic2))
{
goto finish;
}
ShowCurLoadInfo("Loading LLF Info");
if (dlh.version >= 1.44f) // using compression
{
long cpr_pos;
char * compressed = (char *)PAK_FileLoadMalloc(fic2, &cpr_pos);
dat = (unsigned char *)STD_Explode(compressed, cpr_pos, &FileSize);
if (dat == NULL)
{
free(compressed);
goto finish;
}
free(compressed);
pos = 0;
}
else
{
dat = (unsigned char *)PAK_FileLoadMalloc(fic2, &FileSize);
}
llh = (DANAE_LLF_HEADER *)(dat);
pos += sizeof(DANAE_LLF_HEADER);
PROGRESS_BAR_COUNT += 4.f;
LoadLevelScreen();
if (llh->nb_lights != 0)
{
EERIE_LIGHT_GlobalInit();
}
long j;
for (int i = 0; i < llh->nb_lights; i++)
{
dlight = (DANAE_LS_LIGHT *)(dat + pos);
pos += sizeof(DANAE_LS_LIGHT);
j = EERIE_LIGHT_Create();
if (j >= 0)
{
EERIE_LIGHT * el = GLight[j];
el->exist = 1;
el->treat = 1;
el->fallend = dlight->fallend;
el->fallstart = dlight->fallstart;
el->falldiff = el->fallend - el->fallstart;
el->falldiffmul = 1.f / el->falldiff;
el->intensity = dlight->intensity;
if (FASTmse)
{
el->pos.x = dlight->pos.x + trans.x;
el->pos.y = dlight->pos.y + trans.y;
el->pos.z = dlight->pos.z + trans.z;
}
else
{
el->pos.x = dlight->pos.x;
el->pos.y = dlight->pos.y;
el->pos.z = dlight->pos.z;
}
el->rgb.r = dlight->rgb.r;
el->rgb.g = dlight->rgb.g;
el->rgb.b = dlight->rgb.b;
ARX_CHECK_SHORT(dlight->extras);
el->extras = ARX_CLEAN_WARN_CAST_SHORT(dlight->extras);
el->ex_flicker.r = dlight->ex_flicker.r;
el->ex_flicker.g = dlight->ex_flicker.g;
el->ex_flicker.b = dlight->ex_flicker.b;
el->ex_radius = dlight->ex_radius;
el->ex_frequency = dlight->ex_frequency;
el->ex_size = dlight->ex_size;
el->ex_speed = dlight->ex_speed;
el->ex_flaresize = dlight->ex_flaresize;
if (el->extras & EXTRAS_STARTEXTINGUISHED)
el->status = 0;
else el->status = 1;
if ((el->extras & EXTRAS_SPAWNFIRE) && (!(el->extras & EXTRAS_FLARE)))
{
el->extras |= EXTRAS_FLARE;
if (el->extras & EXTRAS_FIREPLACE)
el->ex_flaresize = 95.f;
else
el->ex_flaresize = 80.f;
}
el->tl = -1;
el->sample = ARX_SOUND_INVALID_RESOURCE;
}
}
PROGRESS_BAR_COUNT += 2.f;
LoadLevelScreen();
dll = (DANAE_LS_LIGHTINGHEADER *)(dat + pos);
pos += sizeof(DANAE_LS_LIGHTINGHEADER);
long bcount;
bcount = dll->nb_values;
LastLoadedLightningNb = bcount;
if (LastLoadedLightning != NULL)
{
free(LastLoadedLightning);
LastLoadedLightning = NULL;
}
//DANAE_LS_VLIGHTING
D3DCOLOR * ll;
ll = LastLoadedLightning = (D3DCOLOR *)malloc(sizeof(D3DCOLOR) * bcount);
if (dlh.version > 1.001f)
{
memcpy(LastLoadedLightning, dat + pos, sizeof(D3DCOLOR)*bcount);
pos += sizeof(D3DCOLOR) * bcount;
}
else
{
DANAE_LS_VLIGHTING dlv;
while (bcount)
{
memcpy(&dlv, dat + pos, sizeof(DANAE_LS_VLIGHTING));
pos += sizeof(DANAE_LS_VLIGHTING);
*ll = (0xff000000L | (((long)(dlv.r) & 255) << 16) | (((long)(dlv.g) & 255) << 8) | (long)(dlv.b) & 255);
ll++;
bcount--;
}
}
ModeLight = dll->ModeLight;
ViewMode = dll->ViewMode;
ViewMode &= ~VIEWMODE_WIRE;
free(dat);
PROGRESS_BAR_COUNT += 1.f;
LoadLevelScreen();
finish:
;
LOADEDD = 1;
FASTmse = 0;
USE_PLAYERCOLLISIONS = 1;
return 1;
loaderror:
;
FASTmse = 0;
ShowPopup(_error);
if (dat) free(dat);
LOADEDD = 1;
ARX_SCENE_Render(NULL, 3);
return -1;
}
extern void MCache_ClearAll();
extern TextureContainer * MapMarkerTc;
extern HANDLE LIGHTTHREAD;
extern long DONT_CLEAR_SCENE;
long FAST_RELEASE = 0;
extern INTERACTIVE_OBJ * FlyingOverIO;
extern void ARX_SOUND_Reinit();
extern unsigned long LAST_JUMP_ENDTIME;
extern EERIE_3DOBJ * stone0;
extern long stone0_count;
extern EERIE_3DOBJ * stone1;
extern long stone1_count;
extern EERIE_3DOBJ * ssol;
extern long ssol_count;
extern EERIE_3DOBJ * slight;
extern long slight_count;
extern EERIE_3DOBJ * srune;
extern long srune_count;
extern EERIE_3DOBJ * smotte;
extern long smotte_count;
extern EERIE_3DOBJ * stite;
extern long stite_count;
extern EERIE_3DOBJ * smissile;
extern long smissile_count;
extern EERIE_3DOBJ * spapi;
extern long spapi_count;
extern EERIE_3DOBJ * sfirewave;
extern long sfirewave_count;
extern EERIE_3DOBJ * svoodoo;
extern long svoodoo_count;
void ReleaseAllSpellResources()
{
smissile_count = 0;
if (smissile)
{
ReleaseEERIE3DObj(smissile);
smissile = NULL;
}
stite_count = 0;
if (stite)
{
ReleaseEERIE3DObj(stite);
stite = NULL;
}
smotte_count = 0;
if (smotte)
{
ReleaseEERIE3DObj(smotte);
smotte = NULL;
}
ssol_count = 0;
if (ssol)
{
ReleaseEERIE3DObj(ssol);
ssol = NULL;
}
slight_count = 0;
if (slight)
{
ReleaseEERIE3DObj(slight);
slight = NULL;
}
srune_count = 0;
if (srune)
{
ReleaseEERIE3DObj(srune);
srune = NULL;
}
svoodoo_count--;
if (svoodoo)
{
ReleaseEERIE3DObj(svoodoo);
svoodoo = NULL;
}
stone0_count = 0;
if (stone0)
{
ReleaseEERIE3DObj(stone0);
stone0 = NULL;
}
stone1_count = 0;
if (stone1)
{
ReleaseEERIE3DObj(stone1);
stone1 = NULL;
}
spapi_count = 0;
if (spapi)
{
ReleaseEERIE3DObj(spapi);
spapi = NULL;
}
sfirewave_count = 0;
if (sfirewave)
{
ReleaseEERIE3DObj(sfirewave);
sfirewave = NULL;
}
}
extern long JUST_RELOADED;
void DanaeClearLevel(long flag)
{
JUST_RELOADED = 0;
ARX_MINIMAP_Reset();
FADEDIR = 0;
FADEDURATION = 0;
LAST_JUMP_ENDTIME = 0;
FAST_RELEASE = 1;
MCache_ClearAll();
ARX_MINIMAP_PurgeTC();
ARX_GAME_Reset(flag);
FlyingOverIO = NULL;
EERIE_PATHFINDER_Release();
if (LIGHTTHREAD != NULL)
{
TerminateThread(LIGHTTHREAD, 1);
LIGHTTHREAD = NULL;
}
InitBkg(ACTIVEBKG, MAX_BKGX, MAX_BKGZ, BKG_SIZX, BKG_SIZZ);
RemoveAllBackgroundActions();
ClearNodes();
if (mse != NULL)
{
ReleaseMultiScene(mse);
mse = NULL;
}
EERIE_LIGHT_GlobalInit();
ARX_FOGS_Clear();
TOTIOPDL = 0;
UnlinkAllLinkedObjects();
FreeAllInter();
ReleaseAllSpellResources();
ReleaseAllTCWithFlag(EERIETEXTUREFLAG_LOADSCENE_RELEASE);
danaeApp.EvictManagedTextures();
MapMarkerTc = NULL;
ARX_TIME_Init();
bGToggleCombatModeWithKey = false;
bGCroucheToggle = false;
ARX_HWTransform_Kill();
INTERTRANSPOLYSPOS = 0;
for (long i = 0; i < MAX_DYNLIGHTS; i++) // DynLight 0 is reserved for torch & flares !
{
DynLight[i].exist = 0;
}
TREATZONE_Release();
TREATZONE_Clear();
FAST_RELEASE = 0;
}
extern void ARX_SOUND_PreloadAll();
void DanaeClearAll()
{
DanaeClearLevel();
ARX_SOUND_PreloadAll();
}
extern long MOULINEX;
//*************************************************************************************
//*************************************************************************************
void RestoreLastLoadedLightning()
{
D3DCOLOR dc;
long pos = 0;
long bcount = CountBkgVertex();
if (LastLoadedLightningNb <= 0) return;
if (LastLoadedLightning == NULL) return;
if (bcount != LastLoadedLightningNb)
{
free(LastLoadedLightning);
LastLoadedLightning = NULL;
LastLoadedLightningNb = 0;
return;
}
EERIE_BKG_INFO * eg;
EERIE_BACKGROUND * eb = ACTIVEBKG;
long i, j;
bcount = LastLoadedLightningNb;
EERIEPOLY * ep;
long nbvert;
for (j = 0; j < eb->Zsize; j++)
for (i = 0; i < eb->Xsize; i++)
{
eg = (EERIE_BKG_INFO *)&eb->Backg[i+j*eb->Xsize];
for (long l = 0; l < eg->nbpoly; l++)
{
ep = &eg->polydata[l];
if (ep->type & POLY_QUAD) nbvert = 4;
else nbvert = 3;
for (long k = 0; k < nbvert; k++)
{
memcpy(&dc, LastLoadedLightning + pos, sizeof(D3DCOLOR));
pos++;
dc = dc | 0xFF000000;
ep->tv[k].color = ep->v[k].color = dc;
ep->tv[k].specular = ep->v[k].specular = 0xFF000000;
bcount--;
if (bcount <= 0) goto plusloin;
}
}
}
plusloin:
;
free(LastLoadedLightning);
LastLoadedLightning = NULL;
LastLoadedLightningNb = 0;
for (i = 0; i < MAX_ACTIONS; i++)
{
if (actions[i].exist)
{
long modd = 0;
switch (actions[i].type)
{
case ACT_FIRE:
modd = 1;
break;
case ACT_FIRE2:
modd = 1;
break;
}
if (modd) _RecalcLightZone(actions[i].pos.x, actions[i].pos.y, actions[i].pos.z, (long)((float)(DynLight[actions[i].dl].fallend * ACTIVEBKG->Xmul) + 5.f));
}
}
}
typedef struct
{
char ident[256];
char nums[512];
long occurence;
} DLFCHECK;
DLFCHECK * dlfcheck = NULL;
long dlfcount = 0;
void ARX_SAVELOAD_DLFCheckInit()
{
if (dlfcheck)
free(dlfcheck);
dlfcheck = NULL;
dlfcount = 0;
}
long GetIdent(char * ident)
{
for (long n = 0; n < dlfcount; n++)
{
if (!stricmp(dlfcheck[n].ident, ident))
return n;
}
return -1;
}
void AddIdent(char * ident, long num)
{
MakeUpcase(ident);
long n = GetIdent(ident);
if (n != -1)
{
dlfcheck[n].occurence++;
char temp[64];
sprintf(temp, "%d ", num);
if (strlen(dlfcheck[n].nums) < 500)
strcat(dlfcheck[n].nums, temp);
}
else
{
dlfcheck = (DLFCHECK *)realloc(dlfcheck, sizeof(DLFCHECK) * (dlfcount + 1));
strcpy(dlfcheck[dlfcount].ident, ident);
dlfcheck[dlfcount].occurence = 1;
sprintf(dlfcheck[dlfcount].nums, "%d ", num);
dlfcount++;
}
}
void ARX_SAVELOAD_DLFCheckAdd(char * path, long num)
{
char fic[256];
sprintf(fic, "%sGraph\\Levels\\Level%s", Project.workingdir, path);
char _error[512];
DANAE_LS_HEADER dlh;
DANAE_LS_SCENE * dls;
DANAE_LS_INTER * dli;
unsigned char * dat = NULL;
long pos = 0;
long i;
long FileSize = 0;
SetExt(fic, ".DLF");
if (!PAK_FileExist(fic))
{
return;
}
dat = (unsigned char *)PAK_FileLoadMalloc(fic, &FileSize);
memcpy(&dlh, dat, sizeof(DANAE_LS_HEADER));
pos += sizeof(DANAE_LS_HEADER);
if (dlh.version > CURRENT_VERSION) // using compression
{
ShowPopup("DANAE Version too OLD to load this File... Please upgrade to a new DANAE Version...");
free(dat);
dat = NULL;
return;
}
if (dlh.version >= 1.44f) // using compression
{
char * torelease = (char *)dat;
char * compressed = (char *)(dat + pos);
long cpr_pos;
cpr_pos = 0;
dat = (unsigned char *)STD_Explode(compressed, FileSize - pos, &FileSize);
if (dat == NULL)
{
free(torelease);
return;
}
free(torelease);
compressed = NULL;
pos = 0;
}
if (strcmp(dlh.ident, "DANAE_FILE"))
{
free(dat);
sprintf(_error, "File %s is not a valid file", fic);
return;
}
// Loading Scene
if (dlh.nb_scn >= 1)
{
dls = (DANAE_LS_SCENE *)(dat + pos);
pos += sizeof(DANAE_LS_SCENE);
}
for (i = 0; i < dlh.nb_inter; i++)
{
dli = (DANAE_LS_INTER *)(dat + pos);
pos += sizeof(DANAE_LS_INTER);
char id[256];
sprintf(id, "%s_%04d", GetName(dli->name), dli->ident);
AddIdent(id, num);
}
free(dat);
}
void ARX_SAVELOAD_CheckDLFs()
{
ARX_SAVELOAD_DLFCheckInit();
for (long n = 0; n < 24; n++)
{
char temp[256];
sprintf(temp, "%d\\Level%d.dlf", n, n);
ARX_SAVELOAD_DLFCheckAdd(temp, n);
}
for (int n = 0; n < dlfcount; n++)
{
char text[256];
if (dlfcheck[n].occurence > 1)
{
sprintf(text, "Found %d times : %s in levels %s", dlfcheck[n].occurence, dlfcheck[n].ident, dlfcheck[n].nums);
ShowPopup(text);
}
}
ARX_SAVELOAD_DLFCheckInit();
}