void PakReader::removeFile(const res::path & file) { PakDirectory * dir = getDirectory(file.parent()); if(dir) { dir->removeFile(file.filename()); } }
bool PakReader::addFiles(const fs::path & path, const res::path & mount) { if(fs::is_directory(path)) { bool ret = addFiles(addDirectory(mount), path); if(ret) { LogInfo << "Added dir " << path; } return ret; } else if(fs::is_regular_file(path) && !mount.empty()) { PakDirectory * dir = addDirectory(mount.parent()); return addFile(dir, path, mount.filename()); } return false; }
long DanaeLoadLevel(const res::path & file) { LogInfo << "Loading Level " << file; ClearCurLoadInfo(); CURRENTLEVEL = GetLevelNumByName(file.string()); res::path lightingFileName = res::path(file).set_ext("llf"); LogDebug("fic2 " << lightingFileName); LogDebug("fileDlf " << file); size_t FileSize = 0; char * dat = resources->readAlloc(file, FileSize); if(!dat) { LogError << "Unable to find " << file; return -1; } PakFile * lightingFile = resources->getFile(lightingFileName); PROGRESS_BAR_COUNT += 1.f; LoadLevelScreen(); size_t pos = 0; DANAE_LS_HEADER dlh; memcpy(&dlh, dat + pos, sizeof(DANAE_LS_HEADER)); pos += sizeof(DANAE_LS_HEADER); LogDebug("dlh.version " << dlh.version << " header size " << sizeof(DANAE_LS_HEADER)); if(dlh.version > DLH_CURRENT_VERSION) { LogError << "Unexpected level file version: " << dlh.version << " for " << file; free(dat); dat = NULL; return -1; } // using compression if(dlh.version >= 1.44f) { char * torelease = dat; dat = blastMemAlloc(dat + pos, FileSize - pos, FileSize); free(torelease); pos = 0; if(!dat) { LogError << "STD_Explode did not return anything " << file; return -1; } } loddpos = subj.pos = dlh.pos_edit; player.desiredangle = player.angle = subj.angle = dlh.angle_edit; if(strcmp(dlh.ident, "DANAE_FILE")) { LogError << "Not a valid file " << file << ": \"" << safestring(dlh.ident) << '"'; return -1; } LogDebug("Loading Scene"); // Loading Scene if(dlh.nb_scn > 0) { const DANAE_LS_SCENE * dls = reinterpret_cast<const DANAE_LS_SCENE *>(dat + pos); pos += sizeof(DANAE_LS_SCENE); res::path scene = (FAKE_DIR) ? file.parent() : res::path::load(safestring(dls->name)); FAKE_DIR = 0; if(FastSceneLoad(scene)) { LogDebug("done loading scene"); FASTmse = 1; } else { #ifdef BUILD_EDIT_LOADSAVE LogDebug("fast loading scene failed"); ARX_SOUND_PlayCinematic("editor_humiliation", false); mse = PAK_MultiSceneToEerie(scene); PROGRESS_BAR_COUNT += 20.f; LoadLevelScreen(); #else LogError << "fast loading scene failed"; #endif } EERIEPOLY_Compute_PolyIn(); LastLoadedScene = scene; } Vec3f trans; if(FASTmse) { trans = Mscenepos; player.pos = loddpos + trans; } #ifdef BUILD_EDIT_LOADSAVE else if(mse != NULL) { Mscenepos.x = -mse->cub.xmin - (mse->cub.xmax - mse->cub.xmin) * ( 1.0f / 2 ) + ((float)ACTIVEBKG->Xsize * (float)ACTIVEBKG->Xdiv) * ( 1.0f / 2 ); Mscenepos.z = -mse->cub.zmin - (mse->cub.zmax - mse->cub.zmin) * ( 1.0f / 2 ) + ((float)ACTIVEBKG->Zsize * (float)ACTIVEBKG->Zdiv) * ( 1.0f / 2 ); 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 * ( 1.0f / 2 ); Mscenepos.z = (float)((long)(Mscenepos.z / BKG_SIZZ)) * BKG_SIZZ + (float)BKG_SIZZ * ( 1.0f / 2 ); mse->pos.x = Mscenepos.x = Mscenepos.x + BKG_SIZX - t1; mse->pos.z = Mscenepos.z = Mscenepos.z + BKG_SIZZ - t2; mse->pos.y = Mscenepos.y = -mse->cub.ymin - 100.f - mse->point0.y; lastteleport.x = mapcam.pos.x = player.pos.x = subj.pos.x = moveto.x = mse->pos.x + mse->point0.x; lastteleport.z = mapcam.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 = mse->pos; } #endif // BUILD_EDIT_LOADSAVE else { lastteleport.x = 0.f; lastteleport.y = PLAYER_BASE_HEIGHT; lastteleport.z = 0.f; trans.x = 0; trans.y = 0; trans.z = 0; Mscenepos = trans; } MSP = trans; ClearCurLoadInfo(); float increment = 0; if(dlh.nb_inter > 0) { increment = (60.f / (float)dlh.nb_inter); } else { PROGRESS_BAR_COUNT += 60; LoadLevelScreen(); } for(long i = 0 ; i < dlh.nb_inter ; i++) { PROGRESS_BAR_COUNT += increment; LoadLevelScreen(); const DANAE_LS_INTER * dli = reinterpret_cast<const DANAE_LS_INTER *>(dat + pos); pos += sizeof(DANAE_LS_INTER); if(!DONT_LOAD_INTERS) { string pathstr = toLowercase(safestring(dli->name)); size_t pos = pathstr.find("graph"); if(pos != std::string::npos) { pathstr = pathstr.substr(pos); } LoadInter_Ex(res::path::load(pathstr), dli->ident, dli->pos, dli->angle, trans); } } if(dlh.lighting) { const DANAE_LS_LIGHTINGHEADER * dll = reinterpret_cast<const DANAE_LS_LIGHTINGHEADER *>(dat + pos); pos += sizeof(DANAE_LS_LIGHTINGHEADER); long bcount = dll->nb_values; if(!lightingFile) { LastLoadedLightningNb = bcount; if(LastLoadedLightning != NULL) { free(LastLoadedLightning); LastLoadedLightning = NULL; } //DANAE_LS_VLIGHTING u32 * ll = LastLoadedLightning = (u32 *)malloc(sizeof(u32) * bcount); if(dlh.version > 1.001f) { std::copy((u32*)(dat + pos), (u32*)(dat + pos) + bcount, LastLoadedLightning); pos += sizeof(u32) * bcount; } else { while(bcount) { const DANAE_LS_VLIGHTING * dlv = reinterpret_cast<const DANAE_LS_VLIGHTING *>(dat + pos); pos += sizeof(DANAE_LS_VLIGHTING); *ll = 0xff000000L | ((dlv->r & 255) << 16) | ((dlv->g & 255) << 8) | (dlv->b & 255); ll++; bcount--; } } } else { pos += sizeof(u32) * bcount; } ModeLight = LightMode::load(dll->ModeLight); // TODO save/load flags ViewMode = ViewModeFlags::load(dll->ViewMode); // TODO save/load flags ViewMode &= ~VIEWMODE_WIRE; } PROGRESS_BAR_COUNT += 1; LoadLevelScreen(); long nb_lights = (dlh.version < 1.003f) ? 0 : dlh.nb_lights; if(!lightingFile) { if(nb_lights != 0) { EERIE_LIGHT_GlobalInit(); } for(long i = 0; i < nb_lights; i++) { const DANAE_LS_LIGHT * dlight = reinterpret_cast<const DANAE_LS_LIGHT *>(dat + pos); pos += sizeof(DANAE_LS_LIGHT); long 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 = dlight->pos; el->rgb = dlight->rgb; el->extras = checked_range_cast<short>(dlight->extras); el->ex_flicker = dlight->ex_flicker; 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 = audio::INVALID_ID; 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) * nb_lights; } ClearCurLoadInfo(); LogDebug("Loading FOGS"); ARX_FOGS_Clear(); for(long i = 0; i < dlh.nb_fogs; i++) { const DANAE_LS_FOG * dlf = reinterpret_cast<const 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 = dlf->rgb; fd->angle = dlf->angle; 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->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; Vec3f out; float ta = radians(MAKEANGLE(fd->angle.b)); _YRotatePoint(&fd->move, &out, EEcos(ta), EEsin(ta)); float tb = radians(MAKEANGLE(fd->angle.a)); _XRotatePoint(&out, &fd->move, EEcos(tb), EEsin(tb)); } } PROGRESS_BAR_COUNT += 2.f; LoadLevelScreen(); ClearCurLoadInfo(); LogDebug("Loading Nodes"); ClearNodes(); long nb_nodes = (dlh.version < 1.001f) ? 0 : dlh.nb_nodes; for(long i = 0; i < nb_nodes; i++) { nodes.nodes[i].exist = 1; nodes.nodes[i].selected = 0; const DANAE_LS_NODE * dln = reinterpret_cast<const DANAE_LS_NODE *>(dat + pos); pos += sizeof(DANAE_LS_NODE); strcpy(nodes.nodes[i].name, toLowercase(safestring(dln->name)).c_str()); nodes.nodes[i].pos = (Vec3f)dln->pos + trans; for(long j = 0; j < dlh.nb_nodeslinks; j++) { if(dat[pos] != '\0') { strcpy(nodes.nodes[i].lnames[j], toLowercase(safestring(dat + pos, 64)).c_str()); } pos += 64; } } RestoreNodeNumbers(); ClearCurLoadInfo(); LogDebug("Loading Paths"); ARX_PATH_ReleaseAllPath(); if(dlh.nb_paths) { ARXpaths = (ARX_PATH **)malloc(sizeof(ARX_PATH *) * dlh.nb_paths); nbARXpaths = dlh.nb_paths; } for(long i = 0; i < dlh.nb_paths; i++) { const DANAE_LS_PATH * dlp = reinterpret_cast<const DANAE_LS_PATH *>(dat + pos); pos += sizeof(DANAE_LS_PATH); Vec3f ppos = Vec3f(dlp->initpos) + trans; ARX_PATH * ap = ARXpaths[i] = new ARX_PATH(toLowercase(safestring(dlp->name)), ppos); ap->flags = PathFlags::load(dlp->flags); // TODO save/load flags ap->pos = Vec3f(dlp->pos) + trans; ap->nb_pathways = dlp->nb_pathways; ap->height = dlp->height; ap->ambiance = res::path::load(safestring(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 = dlp->rgb; 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++) { const DANAE_LS_PATHWAYS * dlpw = reinterpret_cast<const DANAE_LS_PATHWAYS *>(dat + pos); pos += sizeof(DANAE_LS_PATHWAYS); app[j].flag = (PathwayType)dlpw->flag; // save/load enum app[j].rpos = dlpw->rpos; app[j]._time = static_cast<float>(dlpw->time); } } ARX_PATH_ComputeAllBoundingBoxes(); PROGRESS_BAR_COUNT += 5.f; LoadLevelScreen(); //Now LOAD Separate LLF Lighting File free(dat); pos = 0; dat = NULL; if(lightingFile) { ClearCurLoadInfo(); LogDebug("Loading LLF Info"); // using compression if(dlh.version >= 1.44f) { char * compressed = lightingFile->readAlloc(); dat = (char*)blastMemAlloc(compressed, lightingFile->size(), FileSize); free(compressed); } else { dat = lightingFile->readAlloc(); FileSize = lightingFile->size(); } } // TODO size ignored if(!dat) { LOADEDD = 1; FASTmse = 0; USE_PLAYERCOLLISIONS = 1; LogInfo << "Done loading level"; return 1; } const DANAE_LLF_HEADER * llh = reinterpret_cast<DANAE_LLF_HEADER *>(dat + pos); pos += sizeof(DANAE_LLF_HEADER); PROGRESS_BAR_COUNT += 4.f; LoadLevelScreen(); if(llh->nb_lights != 0) { EERIE_LIGHT_GlobalInit(); } for(int i = 0; i < llh->nb_lights; i++) { const DANAE_LS_LIGHT * dlight = reinterpret_cast<const DANAE_LS_LIGHT *>(dat + pos); pos += sizeof(DANAE_LS_LIGHT); long 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 = dlight->pos; } el->rgb = dlight->rgb; el->extras = checked_range_cast<short>(dlight->extras); el->ex_flicker = dlight->ex_flicker; 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; el->status = (el->extras & EXTRAS_STARTEXTINGUISHED) ? 0 : 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 = audio::INVALID_ID; } } PROGRESS_BAR_COUNT += 2.f; LoadLevelScreen(); const DANAE_LS_LIGHTINGHEADER * dll = reinterpret_cast<const 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 u32 * ll; ll = LastLoadedLightning = (u32 *)malloc(sizeof(u32) * bcount); if(dlh.version > 1.001f) { std::copy((u32*)(dat + pos), (u32*)(dat + pos) + bcount, LastLoadedLightning); pos += sizeof(u32) * bcount; } else { while(bcount) { const DANAE_LS_VLIGHTING * dlv = reinterpret_cast<const DANAE_LS_VLIGHTING *>(dat + pos); pos += sizeof(DANAE_LS_VLIGHTING); *ll = 0xff000000L | ((dlv->r & 255) << 16) | ((dlv->g & 255) << 8) | (dlv->b & 255); ll++; bcount--; } } arx_assert(pos <= FileSize); ModeLight = LightMode::load(dll->ModeLight); // TODO save/load flags ViewMode = ViewModeFlags::load(dll->ViewMode); // TODO save/load flags ViewMode &= ~VIEWMODE_WIRE; free(dat); PROGRESS_BAR_COUNT += 1.f; LoadLevelScreen(); LOADEDD = 1; FASTmse = 0; USE_PLAYERCOLLISIONS = 1; LogInfo << "Done loading level"; return 1; }