PakFileHandle * PakReader::open(const res::path & name) { PakFile * f = getFile(name); if(!f) { return NULL; } return f->open(); }
bool initLocalisation() { LogDebug("Starting localization"); localisation.clear(); PakFile * file; if(config.language.empty()) { file = autodetectLanguage(); } else { LogInfo << "Using language from config file: " << config.language; // Attempt to load localisation for the configured language. std::string filename = "localisation/utext_" + config.language + ".ini"; file = resources->getFile(filename); if(!file) { LogWarning << "Localisation file " << filename << " not found, autodetecting language."; /* * TODO we might want to keep the old config.language setting as there could be * localized audio for that language even if there is no localized text. */ file = autodetectLanguage(); } } if(!file) { return false; } arx_assert(!config.language.empty()); char * data = file->readAlloc(); if(!data) { return false; } LogDebug("Loaded localisation file of size " << file->size()); std::string out = util::convertUTF16LEToUTF8(data, data + file->size()); LogDebug("Converted to UTF8 string of length " << out.size()); if(!out.empty()) { LogDebug("Preparing to parse localisation file"); std::istringstream iss(out); if(!::localisation.read(iss)) { LogWarning << "Error parsing localisation file localisation/utext_" << config.language << ".ini"; } } free(data); return true; }
char * PakReader::readAlloc(const res::path & name, size_t & sizeRead) { PakFile * f = getFile(name); if(!f) { return NULL; } sizeRead = f->size(); return f->readAlloc(); }
bool PakReader::read(const res::path & name, void * buf) { PakFile * f = getFile(name); if(!f) { return false; } f->read(buf); return true; }
void MiniMap::loadOffsets(PakReader *pakRes) { std::string iniMiniOffsets = "graph/levels/mini_offsets.ini"; PakFile *file = pakRes->getFile(iniMiniOffsets.c_str()); if(!file) { LogError << "Missing " << iniMiniOffsets; return; } size_t fileSize = file->size(); char *dat = new char[fileSize + 2]; dat[fileSize + 1] = '\0'; file->read(dat); if(dat) { size_t pos = 0; for(int i = 0; i < 29; i++) { // Why 29? char t[512]; int nRead = sscanf(dat + pos, "%s %f %f", t, &m_miniOffsetX[i], &m_miniOffsetY[i]); if(nRead != 3) { LogError << "Error parsing line " << i << " of mini_offsets.ini: read " << nRead; } while((pos < fileSize) && (dat[pos] != '\n')) { pos++; } pos++; if(pos >= fileSize) { break; } } delete[] dat; } m_miniOffsetX[0] = 0; m_miniOffsetY[0] = -0.5; m_miniOffsetX[1] = 0; m_miniOffsetY[1] = 0; m_miniOffsetX[14] = 130; m_miniOffsetY[14] = 0; m_miniOffsetX[15] = 31; m_miniOffsetY[15] = -3.5; }
void Resources::openPackage(const Common::String &fileName) { debugC(1, kDebugResource, "openPackage(%s)", fileName.c_str()); Common::File file; bool opened = file.open(fileName); if (!opened) return; PakFile *pakFile = new PakFile(); pakFile->open(&file, fileName); file.close(); _pakFiles.push_back(pakFile); }
static void dump(PakDirectory & dir, const fs::path & dirname = fs::path()) { if(!fs::create_directories(dirname)) { LogWarning << "Failed to create target directory"; } for(PakDirectory::files_iterator i = dir.files_begin(); i != dir.files_end(); ++i) { fs::path filenameISO = dirname / i->first; PakFile * file = i->second; #if ARX_PLATFORM == ARX_PLATFORM_WIN32 std::string filename = filenameISO.string(); #else std::string filename = util::convert<util::ISO_8859_1, util::UTF8>(filenameISO.string().c_str()); #endif printf("%s\n", filename.c_str()); fs::ofstream ofs(filename, fs::fstream::out | fs::fstream::binary | fs::fstream::trunc); if(!ofs.is_open()) { printf("error opening file for writing: %s\n", filename.c_str()); exit(1); } if(file->size() > 0) { char * data = (char*)file->readAlloc(); arx_assert(data != NULL); if(ofs.write(data, file->size()).fail()) { printf("error writing to file: %s\n", filename.c_str()); exit(1); } free(data); } } for(PakDirectory::dirs_iterator i = dir.dirs_begin(); i != dir.dirs_end(); ++i) { dump(i->second, dirname / i->first); } }
void dump(PakDirectory & dir, const fs::path & dirname = fs::path()) { fs::create_directories(dirname); for(PakDirectory::files_iterator i = dir.files_begin(); i != dir.files_end(); ++i) { fs::path filename = dirname / i->first; PakFile * file = i->second; printf("%s\n", filename.string().c_str()); fs::ofstream ofs(filename, fs::fstream::out | fs::fstream::binary | fs::fstream::trunc); if(!ofs.is_open()) { printf("error opening file for writing: %s\n", filename.string().c_str()); exit(1); } if(file->size() > 0) { char * data = (char*)file->readAlloc(); arx_assert(data != NULL); if(ofs.write(data, file->size()).fail()) { printf("error writing to file: %s\n", filename.string().c_str()); exit(1); } free(data); } } for(PakDirectory::dirs_iterator i = dir.dirs_begin(); i != dir.dirs_end(); ++i) { dump(i->second, dirname / i->first); } }
EERIE_3DOBJ * ARX_FTL_Load(const res::path & file) { // Creates FTL file name res::path filename = (res::path("game") / file).set_ext("ftl"); // Checks for FTL file existence PakFile * pf = resources->getFile(filename); if(!pf) { return NULL; } size_t compressedSize = 0; char * compressedData = MCache_Pop(filename, compressedSize); LogDebug("File name check " << filename); bool NOrelease = true; if(!compressedData) { compressedData = pf->readAlloc(); compressedSize = pf->size(); NOrelease = MCache_Push(filename, compressedData, compressedSize) ? 1 : 0; } if(!compressedData) { LogError << "ARX_FTL_Load: error loading from PAK/cache " << filename; return NULL; } size_t allocsize; // The size of the data TODO size ignored char * dat = blastMemAlloc(compressedData, compressedSize, allocsize); if(!dat) { LogError << "ARX_FTL_Load: error decompressing " << filename; return NULL; } if(!NOrelease) { free(compressedData); } size_t pos = 0; // The position within the data // Pointer to Primary Header const ARX_FTL_PRIMARY_HEADER * afph = reinterpret_cast<const ARX_FTL_PRIMARY_HEADER *>(dat + pos); pos += sizeof(ARX_FTL_PRIMARY_HEADER); // Verify FTL file Signature if(afph->ident[0] != 'F' || afph->ident[1] != 'T' || afph->ident[2] != 'L') { LogError << "ARX_FTL_Load: wrong magic number in " << filename; free(dat); return NULL; } // Verify FTL file version if(afph->version != CURRENT_FTL_VERSION) { LogError << "ARX_FTL_Load: wring version " << afph->version << ", expected " << CURRENT_FTL_VERSION << " in " << filename; free(dat); return NULL; } // Increases offset by checksum size pos += 512; // Pointer to Secondary Header const ARX_FTL_SECONDARY_HEADER * afsh; afsh = reinterpret_cast<const ARX_FTL_SECONDARY_HEADER *>(dat + pos); if(afsh->offset_3Ddata == -1) { LogError << "ARX_FTL_Load: error loading data from " << filename; free(dat); return NULL; } pos = afsh->offset_3Ddata; // Available from here in whole function EERIE_3DOBJ * obj = new EERIE_3DOBJ(); const ARX_FTL_3D_DATA_HEADER * af3Ddh; af3Ddh = reinterpret_cast<const ARX_FTL_3D_DATA_HEADER *>(dat + pos); pos += sizeof(ARX_FTL_3D_DATA_HEADER); obj->vertexlist.resize(af3Ddh->nb_vertex); obj->facelist.resize(af3Ddh->nb_faces); obj->texturecontainer.resize(af3Ddh->nb_maps); obj->nbgroups = af3Ddh->nb_groups; obj->actionlist.resize(af3Ddh->nb_action); obj->selections.resize(af3Ddh->nb_selections); obj->origin = af3Ddh->origin; obj->file = res::path::load(safestring(af3Ddh->name)); // Alloc'n'Copy vertices if(!obj->vertexlist.empty()) { // Copy the vertex data in for(size_t ii = 0; ii < obj->vertexlist.size(); ii++) { // Vertices stored as EERIE_OLD_VERTEX, copy in to new one obj->vertexlist[ii] = *reinterpret_cast<const EERIE_OLD_VERTEX *>(dat + pos); pos += sizeof(EERIE_OLD_VERTEX); obj->vertexlist[ii].vert.color = 0xFF000000; } // Set the origin point of the mesh obj->point0 = obj->vertexlist[obj->origin].v; obj->vertexlist3 = obj->vertexlist; } // Alloc'n'Copy faces if(!obj->facelist.empty()) { // Copy the face data in for(long ii = 0; ii < af3Ddh->nb_faces; ii++) { const EERIE_FACE_FTL * eff = reinterpret_cast<const EERIE_FACE_FTL*>(dat + pos); pos += sizeof(EERIE_FACE_FTL); obj->facelist[ii].facetype = PolyType::load(eff->facetype); obj->facelist[ii].texid = eff->texid; obj->facelist[ii].transval = eff->transval; obj->facelist[ii].temp = eff->temp; obj->facelist[ii].norm = eff->norm; // Copy in all the texture and normals data BOOST_STATIC_ASSERT(IOPOLYVERT_FTL == IOPOLYVERT); for(size_t kk = 0; kk < IOPOLYVERT_FTL; kk++) { obj->facelist[ii].nrmls[kk] = eff->nrmls[kk]; obj->facelist[ii].vid[kk] = eff->vid[kk]; obj->facelist[ii].u[kk] = eff->u[kk]; obj->facelist[ii].v[kk] = eff->v[kk]; obj->facelist[ii].ou[kk] = eff->ou[kk]; obj->facelist[ii].ov[kk] = eff->ov[kk]; } } } // Alloc'n'Copy textures if(af3Ddh->nb_maps > 0) { // Copy in the texture containers for(long i = 0; i < af3Ddh->nb_maps; i++) { const Texture_Container_FTL * tex; tex = reinterpret_cast<const Texture_Container_FTL *>(dat + pos); pos += sizeof(Texture_Container_FTL); if(tex->name[0] == '\0') { // Some object files contain textures with empty names // Don't bother trying to load them as that will just generate an error message obj->texturecontainer[i] = NULL; } else { // Create the texture and put it in the container list res::path name = res::path::load(safestring(tex->name)).remove_ext(); obj->texturecontainer[i] = TextureContainer::Load(name, TextureContainer::Level); } } } // Alloc'n'Copy groups if(obj->nbgroups > 0) { // Alloc the grouplists obj->grouplist = new EERIE_GROUPLIST[obj->nbgroups]; // Copy in the grouplist data for(long i = 0 ; i < obj->nbgroups ; i++) { const EERIE_GROUPLIST_FTL* group = reinterpret_cast<const EERIE_GROUPLIST_FTL *>(dat + pos); pos += sizeof(EERIE_GROUPLIST_FTL); obj->grouplist[i].name = toLowercase(safestring(group->name)); obj->grouplist[i].origin = group->origin; obj->grouplist[i].indexes.resize(group->nb_index); obj->grouplist[i].siz = group->siz; } // Copy in the group index data for(long i = 0; i < obj->nbgroups; i++) { if(!obj->grouplist[i].indexes.empty()) { size_t oldpos = pos; pos += sizeof(s32) * obj->grouplist[i].indexes.size(); // Advance to the next index block std::copy((const s32 *)(dat+oldpos), (const s32 *)(dat + pos), obj->grouplist[i].indexes.begin()); } } } // Copy in the action points data for(size_t i = 0 ; i < obj->actionlist.size(); i++) { obj->actionlist[i] = *reinterpret_cast<const EERIE_ACTIONLIST_FTL *>(dat + pos); pos += sizeof(EERIE_ACTIONLIST_FTL); } // Copy in the selections data for(size_t i = 0 ; i < obj->selections.size(); i++) { const EERIE_SELECTIONS_FTL * selection = reinterpret_cast<const EERIE_SELECTIONS_FTL *>(dat + pos); pos += sizeof(EERIE_SELECTIONS_FTL); obj->selections[i].name = toLowercase(safestring(selection->name)); obj->selections[i].selected.resize(selection->nb_selected); } // Copy in the selections selected data for(long i = 0; i < af3Ddh->nb_selections; i++) { std::copy((const s32 *)(dat + pos), (const s32 *)(dat + pos) + obj->selections[i].selected.size(), obj->selections[i].selected.begin() ); pos += sizeof(s32) * obj->selections[i].selected.size(); // Advance to the next selection data block } obj->pbox = NULL; // Reset physics // Alloc'n'Copy Collision Spheres Data if(afsh->offset_collision_spheres != -1) { // Cast to header pos = afsh->offset_collision_spheres; const ARX_FTL_COLLISION_SPHERES_DATA_HEADER * afcsdh; afcsdh = reinterpret_cast<const ARX_FTL_COLLISION_SPHERES_DATA_HEADER*>(dat + pos); pos += sizeof(ARX_FTL_COLLISION_SPHERES_DATA_HEADER); // Alloc the collision sphere data object obj->sdata = new COLLISION_SPHERES_DATA(); obj->sdata->spheres.resize(afcsdh->nb_spheres); // Alloc the collision speheres const COLLISION_SPHERE_FTL * begin = reinterpret_cast<const COLLISION_SPHERE_FTL *>(dat + pos); pos += sizeof(COLLISION_SPHERE_FTL) * obj->sdata->spheres.size(); const COLLISION_SPHERE_FTL * end = reinterpret_cast<const COLLISION_SPHERE_FTL *>(dat + pos); std::copy(begin, end, obj->sdata->spheres.begin()); } // Alloc'n'Copy Progressive DATA if(afsh->offset_progressive_data != -1) { // Progressive data ignored. } // Alloc'n'Copy Clothes DATA if(afsh->offset_clothes_data != -1) { obj->cdata = new CLOTHES_DATA(); const ARX_FTL_CLOTHES_DATA_HEADER * afcdh; afcdh = reinterpret_cast<const ARX_FTL_CLOTHES_DATA_HEADER*>(dat + afsh->offset_clothes_data); obj->cdata->nb_cvert = (short)afcdh->nb_cvert; obj->cdata->springs.resize(afcdh->nb_springs); size_t pos = afsh->offset_clothes_data; pos += sizeof(ARX_FTL_CLOTHES_DATA_HEADER); // now load cvert obj->cdata->cvert = new CLOTHESVERTEX[obj->cdata->nb_cvert]; obj->cdata->backup = new CLOTHESVERTEX[obj->cdata->nb_cvert]; std::copy(reinterpret_cast<const CLOTHESVERTEX_FTL *>(dat + pos), reinterpret_cast<const CLOTHESVERTEX_FTL *>(dat + pos) + obj->cdata->nb_cvert, obj->cdata->cvert); memcpy(obj->cdata->backup, obj->cdata->cvert, sizeof(CLOTHESVERTEX)*obj->cdata->nb_cvert); pos += sizeof(CLOTHESVERTEX_FTL) * obj->cdata->nb_cvert; // now load springs const EERIE_SPRINGS_FTL * begin = reinterpret_cast<const EERIE_SPRINGS_FTL *>(dat + pos); pos += sizeof(EERIE_SPRINGS_FTL) * obj->cdata->springs.size(); const EERIE_SPRINGS_FTL * end = reinterpret_cast<const EERIE_SPRINGS_FTL *>(dat + pos); std::copy(begin, end, obj->cdata->springs.begin()); } // Free the loaded file memory free(dat); EERIE_OBJECT_CenterObjectCoordinates(obj); EERIE_CreateCedricData(obj); // Now we can release our cool FTL file EERIE_Object_Precompute_Fast_Access(obj); LogDebug("ARX_FTL_Load: loaded object " << filename); return obj; }
// All threads start execution here. int main() { void *frameBuffer; if (get_current_thread_id() != 0) worker_thread(); // Set up render context frameBuffer = init_vga(VGA_MODE_640x480); RenderContext *context = new RenderContext(0x1000000); RenderTarget *renderTarget = new RenderTarget(); Surface *colorBuffer = new Surface(FB_WIDTH, FB_HEIGHT, Surface::RGBA8888, (void*) frameBuffer); Surface *zBuffer = new Surface(FB_WIDTH, FB_HEIGHT, Surface::FLOAT); renderTarget->setColorBuffer(colorBuffer); renderTarget->setDepthBuffer(zBuffer); context->bindTarget(renderTarget); context->enableDepthBuffer(true); context->bindShader(new TextureShader()); // Read resources PakFile pak; pak.open("pak0.pak"); pak.readBspFile("maps/e1m1.bsp"); Texture *atlasTexture = pak.getTextureAtlasTexture(); LevelRenderer renderer; renderer.setBspData(pak.getBspTree(), pak.getPvsList(), pak.getBspTree() + pak.getNumInteriorNodes(), pak.getNumLeaves(), atlasTexture, pak.getLightmapAtlasTexture()); Entity *ent = pak.findEntityByClassName("info_player_start"); if (!ent) { printf("Error, couldn't find start position\n"); return 1; } float facingAngle = float(atoi(ent->getAttribute("angle"))) / 360.0 * M_PI * 2; gCameraOrientationMatrix = Matrix::lookAt(Vec3(0, 0, 0), Vec3(cos(facingAngle), sin(facingAngle), 0), kUpVector); float coords[3]; parseCoordinateString(ent->getAttribute("origin"), coords); for (int i = 0; i < 3; i++) gCameraPos[i] = coords[i]; printf("position %g %g %g angle %g\n", coords[0], coords[1], coords[2], facingAngle); // Start worker threads start_all_threads(); TextureUniforms uniforms; Matrix projectionMatrix = Matrix::getProjectionMatrix(FB_WIDTH, FB_HEIGHT); for (int frame = 0; ; frame++) { processKeyboardEvents(); context->enableWireframeMode(gWireframeRendering); atlasTexture->enableBilinearFiltering(gBilinearFiltering); // Set up uniforms Matrix viewMatrix = gCameraOrientationMatrix * Matrix::getTranslationMatrix(-gCameraPos); uniforms.fMVPMatrix = projectionMatrix * viewMatrix; uniforms.enableLightmap = gEnableLightmap; uniforms.enableTexture = gEnableTexture; context->bindUniforms(&uniforms, sizeof(uniforms)); renderer.render(context, gCameraPos); clock_t startTime = clock(); context->finish(); printf("rendered frame in %d uS\n", clock() - startTime); } }
bool initLocalisation() { LogDebug("Starting localization"); localisation.clear(); PakFile * file; if(config.language.empty()) { file = autodetectLanguage(); } else { // Attempt to load localisation for the configured language. std::string filename = "localisation/utext_" + config.language + ".ini"; file = resources->getFile(filename); if(!file) { LogWarning << "Localisation file " << filename << " not found, autodetecting language."; /* * TODO we might want to keep the old config.language setting as there could be * localized audio for that language even if there is no localized text. */ file = autodetectLanguage(); } } if(!file) { return false; } arx_assert(!config.language.empty()); u16 * localisation = reinterpret_cast<u16 *>(file->readAlloc()); u16 * toFree = localisation; // Scale the loaded size to new stride of uint16_t vs char size_t loc_file_size = file->size() / sizeof(*localisation); // Ignore any byte order mark. if(loc_file_size >= 1 && *localisation == 0xfeff) { loc_file_size--, localisation++; } LogDebug("Loaded localisation file of size " << loc_file_size); size_t nchars = GetUTF16Length(localisation, &localisation[loc_file_size]); ARX_UNUSED(nchars); LogDebug("UTF-16 size is " << nchars); std::string out; out.reserve(loc_file_size); UTF16ToUTF8(localisation, &localisation[loc_file_size], std::back_inserter(out)); LogDebug("Converted to UTF8 string of length " << out.size()); if(localisation && loc_file_size) { LogDebug("Preparing to parse localisation file"); std::istringstream iss( out ); if(!::localisation.read(iss)) { LogWarning << "Error parsing localisation file localisation/utext_" << config.language << ".ini"; } } free(toFree); return true; }
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; }