void ARX_EQUIPMENT_RecreatePlayerMesh() { if(EXITING) return; arx_assert(entities.player()); Entity * io = entities.player(); if(io->obj != hero) delete io->obj; io->obj = loadObject("graph/obj3d/interactive/npc/human_base/human_base.teo", false); applyTweak(EQUIP_SLOT_HELMET, TWEAK_HEAD, "head"); applyTweak(EQUIP_SLOT_ARMOR, TWEAK_TORSO, "chest"); applyTweak(EQUIP_SLOT_LEGGINGS, TWEAK_LEGS, "leggings"); Entity * target = entities.player(); for(size_t i = 0; i < MAX_EQUIPED; i++) { if(ValidIONum(player.equiped[i])) { Entity *toequip = entities[player.equiped[i]]; if(toequip) { if(toequip->type_flags & (OBJECT_TYPE_DAGGER | OBJECT_TYPE_1H | OBJECT_TYPE_2H | OBJECT_TYPE_BOW)) { if(player.Interface & INTER_COMBATMODE) { ARX_EQUIPMENT_AttachPlayerWeaponToHand(); } else { EERIE_LINKEDOBJ_LinkObjectToObject(target->obj, toequip->obj, "weapon_attach", "primary_attach", toequip); } } else if(toequip->type_flags & OBJECT_TYPE_SHIELD) { if(ValidIONum(player.equiped[EQUIP_SLOT_SHIELD])) { EERIE_LINKEDOBJ_LinkObjectToObject(target->obj, toequip->obj, "shield_attach", "shield_attach", toequip); } } } } } ARX_PLAYER_Restore_Skin(); HERO_SHOW_1ST = -1; if(EXTERNALVIEW) { ARX_INTERACTIVE_Show_Hide_1st(entities.player(), 0); } else { ARX_INTERACTIVE_Show_Hide_1st(entities.player(), 1); } ARX_INTERACTIVE_HideGore(entities.player(), 1); EERIE_Object_Precompute_Fast_Access(hero); EERIE_Object_Precompute_Fast_Access(entities.player()->obj); ARX_INTERACTIVE_RemoveGoreOnIO(entities.player()); }
static void loadObjectData(EERIE_3DOBJ * eerie, const char * adr, size_t * poss, long version) { LogWarning << "loadObjectData"; size_t pos = *poss; const THEO_OFFSETS * to = reinterpret_cast<const THEO_OFFSETS *>(adr + pos); pos += sizeof(THEO_OFFSETS); const THEO_NB * tn = reinterpret_cast<const THEO_NB *>(adr + pos); LogDebug("Nb Vertex " << tn->nb_vertex << " Nb Action Points " << tn->nb_action_point << " Nb Lines " << tn->nb_lines); LogDebug("Nb Faces " << tn->nb_faces << " Nb Groups " << tn->nb_groups); eerie->vertexlist.resize(tn->nb_vertex); eerie->vertexlist3.resize(tn->nb_vertex); eerie->facelist.resize(tn->nb_faces); eerie->grouplist.resize(tn->nb_groups); eerie->actionlist.resize(tn->nb_action_point); eerie->ndata = NULL; eerie->pdata = NULL; eerie->cdata = NULL; eerie->sdata = NULL; // read vertices pos = to->vertex_seek; if(tn->nb_vertex > 65535) { LogError << ("Warning Vertex Number Too High..."); } for(long i = 0; i < tn->nb_vertex; i++) { const THEO_VERTEX * ptv = reinterpret_cast<const THEO_VERTEX *>(adr + pos); pos += sizeof(THEO_VERTEX); eerie->vertexlist[i].v = ptv->pos.toVec3(); eerie->cub.xmin = std::min(eerie->cub.xmin, ptv->pos.x); eerie->cub.xmax = std::max(eerie->cub.xmax, ptv->pos.x); eerie->cub.ymin = std::min(eerie->cub.ymin, ptv->pos.y); eerie->cub.ymax = std::max(eerie->cub.ymax, ptv->pos.y); eerie->cub.zmin = std::min(eerie->cub.zmin, ptv->pos.z); eerie->cub.zmax = std::max(eerie->cub.zmax, ptv->pos.z); } // Lecture des FACES THEO pos = to->faces_seek; for(long i = 0; i < tn->nb_faces; i++) { THEO_FACES_3006 tf3006; const THEO_FACES_3006 * ptf3006; if(version >= 3006) { ptf3006 = reinterpret_cast<const THEO_FACES_3006 *>(adr + pos); pos += sizeof(THEO_FACES_3006); } else { memset(&tf3006, 0, sizeof(THEO_FACES_3006)); const THEO_FACES * ptf = reinterpret_cast<const THEO_FACES *>(adr + pos); pos += sizeof(THEO_FACES); tf3006.color = ptf->color; tf3006.index1 = ptf->index1; tf3006.index2 = ptf->index2; tf3006.index3 = ptf->index3; tf3006.ismap = ptf->ismap; tf3006.liste_uv = ptf->liste_uv; tf3006.element_uv = ptf->element_uv; tf3006.num_map = ptf->num_map; tf3006.tile_x = ptf->tile_x; tf3006.tile_y = ptf->tile_y; tf3006.user_tile_x = ptf->user_tile_x; tf3006.user_tile_y = ptf->user_tile_y; tf3006.flag = ptf->flag; tf3006.collision_type = ptf->collision_type; tf3006.rgb = ptf->rgb; tf3006.rgb1 = ptf->rgb1; tf3006.rgb2 = ptf->rgb2; tf3006.rgb3 = ptf->rgb3; tf3006.double_side = ptf->double_side; tf3006.transparency = ptf->transparency; tf3006.trans = ptf->trans; ptf3006 = &tf3006; } eerie->facelist[i].vid[0] = (unsigned short)ptf3006->index1; eerie->facelist[i].vid[1] = (unsigned short)ptf3006->index2; eerie->facelist[i].vid[2] = (unsigned short)ptf3006->index3; s32 num_map = ((size_t)ptf3006->num_map >= eerie->texturecontainer.size()) ? -1 : ptf3006->num_map; if(ptf3006->ismap) { eerie->facelist[i].texid = (short)num_map; eerie->facelist[i].facetype = POLY_NO_SHADOW; if(num_map >= 0 && eerie->texturecontainer[num_map] && (eerie->texturecontainer[num_map]->userflags & POLY_NOCOL)) { eerie->facelist[i].facetype |= POLY_NOCOL; } } else { eerie->facelist[i].texid = -1; } switch(ptf3006->flag) { case 0: eerie->facelist[i].facetype |= POLY_GLOW; break; case 1: eerie->facelist[i].facetype |= POLY_NO_SHADOW; break; case 4: eerie->facelist[i].facetype |= POLY_METAL; break; case 10: eerie->facelist[i].facetype |= POLY_NOPATH; break; case 11: eerie->facelist[i].facetype |= POLY_CLIMB; break; case 12: eerie->facelist[i].facetype |= POLY_NOCOL; break; case 13: eerie->facelist[i].facetype |= POLY_NODRAW; break; case 14: eerie->facelist[i].facetype |= POLY_PRECISE_PATH; break; case 16: eerie->facelist[i].facetype |= POLY_NO_CLIMB; break; } eerie->facelist[i].ou[0] = (short)ptf3006->liste_uv.u1; eerie->facelist[i].ov[0] = (short)ptf3006->liste_uv.v1; eerie->facelist[i].ou[1] = (short)ptf3006->liste_uv.u2; eerie->facelist[i].ov[1] = (short)ptf3006->liste_uv.v2; eerie->facelist[i].ou[2] = (short)ptf3006->liste_uv.u3; eerie->facelist[i].ov[2] = (short)ptf3006->liste_uv.v3; if(ptf3006->double_side) { eerie->facelist[i].facetype |= POLY_DOUBLESIDED; } if(ptf3006->transparency > 0) { if(ptf3006->transparency == 2) { // NORMAL TRANS 0.00001 to 0.999999 if(ptf3006->trans < 1.f) { eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans; } } else if (ptf3006->transparency == 1) { if(ptf3006->trans < 0.f) { // SUBTRACTIVE -0.000001 to -0.999999 eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans; } else { // ADDITIVE 1.000001 to 1.9999999 eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans + 1.f; } } else { // MULTIPLICATIVE 2.000001 to 2.9999999 eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans + 2.f; } } if(eerie->facelist[i].texid != -1 && !eerie->texturecontainer.empty() && eerie->texturecontainer[eerie->facelist[i].texid] != NULL) { if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_TRANS) { if(!(eerie->facelist[i].facetype & POLY_TRANS)) { eerie->facelist[i].facetype |= POLY_TRANS; eerie->facelist[i].transval = ptf3006->trans; } } if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_WATER) { eerie->facelist[i].facetype |= POLY_WATER; } if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_LAVA) { eerie->facelist[i].facetype |= POLY_LAVA; } if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_FALL) { eerie->facelist[i].facetype |= POLY_FALL; } if(eerie->texturecontainer[eerie->facelist[i].texid]->userflags & POLY_CLIMB) { eerie->facelist[i].facetype |= POLY_CLIMB; } } } // Groups Data pos = to->groups_seek; for(long i = 0; i < tn->nb_groups; i++) { THEO_GROUPS_3011 tg3011; const THEO_GROUPS_3011 * ptg3011; if(version >= 3011) { ptg3011 = reinterpret_cast<const THEO_GROUPS_3011 *>(adr + pos); pos += sizeof(THEO_GROUPS_3011); } else { const THEO_GROUPS * ltg = reinterpret_cast<const THEO_GROUPS *>(adr + pos); pos += sizeof(THEO_GROUPS); memset(&tg3011, 0, sizeof(THEO_GROUPS_3011)); tg3011.origin = ltg->origin; tg3011.nb_index = ltg->nb_index; ptg3011 = &tg3011; } eerie->grouplist[i].origin = ptg3011->origin; eerie->grouplist[i].indexes.resize(ptg3011->nb_index); std::copy((const long*)(adr + pos), (const long*)(adr + pos) + ptg3011->nb_index, eerie->grouplist[i].indexes.begin()); pos += ptg3011->nb_index * sizeof(long); eerie->grouplist[i].name = boost::to_lower_copy(util::loadString(adr + pos, 256)); pos += 256; eerie->grouplist[i].siz = 0.f; for(long o = 0; o < ptg3011->nb_index; o++) { eerie->grouplist[i].siz = std::max(eerie->grouplist[i].siz, fdist(eerie->vertexlist[eerie->grouplist[i].origin].v, eerie->vertexlist[eerie->grouplist[i].indexes[o]].v)); } eerie->grouplist[i].siz = ffsqrt(eerie->grouplist[i].siz) * (1.f/16); } // SELECTIONS s32 THEO_nb_selected = *reinterpret_cast<const s32 *>(adr + pos); pos += sizeof(s32); eerie->selections.resize(THEO_nb_selected); for(long i = 0; i < THEO_nb_selected; i++) { const THEO_SELECTED * pts = reinterpret_cast<const THEO_SELECTED *>(adr + pos); pos += sizeof(THEO_SELECTED); eerie->selections[i].name = boost::to_lower_copy(util::loadString(pts->name)); eerie->selections[i].selected.resize(pts->nb_index); if(pts->nb_index > 0) { std::copy((const long*)(adr + pos), (const long*)(adr + pos) + pts->nb_index, eerie->selections[i].selected.begin()); pos += sizeof(long) * pts->nb_index; } } // Theo Action Points Read pos = to->action_point_seek; for(long i = 0; i < tn->nb_action_point; i++) { const THEO_ACTION_POINT * ptap = reinterpret_cast<const THEO_ACTION_POINT *>(adr + pos); pos += sizeof(THEO_ACTION_POINT); eerie->actionlist[i].act = ptap->action; eerie->actionlist[i].sfx = ptap->num_sfx; eerie->actionlist[i].idx = ptap->vert_index; eerie->actionlist[i].name = boost::to_lower_copy(util::loadString(ptap->name)); } eerie->angle = Anglef::ZERO; eerie->pos = Vec3f_ZERO; // Now Interpret Extra Data chunk pos = to->extras_seek + 4; if(version >= 3005) { const THEO_EXTRA_DATA_3005 * pted3005 = reinterpret_cast<const THEO_EXTRA_DATA_3005 *>(adr + pos); pos += sizeof(THEO_EXTRA_DATA_3005); eerie->pos = pted3005->pos.toVec3(); eerie->angle.setYaw((float)(pted3005->angle.alpha & 0xfff) * THEO_ROTCONVERT); eerie->angle.setPitch((float)(pted3005->angle.beta & 0xfff) * THEO_ROTCONVERT); eerie->angle.setRoll((float)(pted3005->angle.gamma & 0xfff) * THEO_ROTCONVERT); eerie->point0 = eerie->vertexlist[pted3005->origin_index].v; eerie->origin = pted3005->origin_index; eerie->quat = pted3005->quat; } else { const THEO_EXTRA_DATA * pted = reinterpret_cast<const THEO_EXTRA_DATA *>(adr + pos); pos += sizeof(THEO_EXTRA_DATA); eerie->pos = pted->pos.toVec3(); eerie->angle.setYaw((float)(pted->angle.alpha & 0xfff) * THEO_ROTCONVERT); eerie->angle.setPitch((float)(pted->angle.beta & 0xfff) * THEO_ROTCONVERT); eerie->angle.setRoll((float)(pted->angle.gamma & 0xfff) * THEO_ROTCONVERT); eerie->point0 = eerie->vertexlist[pted->origin_index].v; eerie->origin = pted->origin_index; } *poss = pos; eerie->vertexlist3 = eerie->vertexlist; ReCreateUVs(eerie); EERIE_Object_Precompute_Fast_Access(eerie); }
void EERIE_MESH_TWEAK_Do(INTERACTIVE_OBJ * io, long tw, char * _path) { if (!ALLOW_MESH_TWEAKING) return; char file2[256]; char filet[256]; char path[256]; File_Standardize(_path, path); strcpy(filet, "GAME\\"); strcat(filet, path); SetExt(filet, ".FTL"); File_Standardize(filet, file2); if ((!PAK_FileExist(file2)) && (!PAK_FileExist(path))) return; if (tw == TWEAK_ERROR) return; if (io == NULL) return; if (io->obj == NULL) return; EERIE_MESH_ReleaseTransPolys(io->obj); if ((path == NULL) && (tw == TWEAK_REMOVE)) { if (io->tweaky) { ReleaseEERIE3DObj(io->obj); io->obj = io->tweaky; EERIE_Object_Precompute_Fast_Access(io->obj); io->tweaky = NULL; } return; } EERIE_3DOBJ * tobj = NULL; EERIE_3DOBJ * result = NULL; EERIE_3DOBJ * result2 = NULL; if ((PAK_FileExist(file2)) || (PAK_FileExist(path))) { const char DIR_TEXTURES[] = "Graph\\Obj3D\\Textures\\"; if (io->ioflags & IO_NPC) tobj = TheoToEerie_Fast(DIR_TEXTURES, path, TTE_NPC); else tobj = TheoToEerie_Fast(DIR_TEXTURES, path, 0); if (!tobj) return; switch (tw) { case TWEAK_ALL: if (io->tweaky == NULL) io->tweaky = io->obj; else ReleaseEERIE3DObj(io->obj); long i; TextureContainer * tc; tc = NULL; for (i = 0; i < tobj->nbfaces; i++) { if ((tobj->facelist[i].texid >= 0) && (tobj->texturecontainer[tobj->facelist[i].texid])) { tc = tobj->texturecontainer[tobj->facelist[i].texid]; if (!tc->m_pddsSurface) tc->Restore(GDevice); } } io->obj = tobj; return; break; case TWEAK_UPPER: result2 = CreateIntermediaryMesh(io->obj, tobj, TWEAK_HEAD); result = CreateIntermediaryMesh(result2, tobj, TWEAK_TORSO); ReleaseEERIE3DObj(result2); break; case TWEAK_LOWER: result2 = CreateIntermediaryMesh(io->obj, tobj, TWEAK_TORSO); result = CreateIntermediaryMesh(result2, tobj, TWEAK_LEGS); ReleaseEERIE3DObj(result2); break; case TWEAK_UP_LO: result = CreateIntermediaryMesh(tobj, io->obj, TWEAK_TORSO); break; default: result = CreateIntermediaryMesh(io->obj, tobj, tw); break; } if (result == NULL) { ReleaseEERIE3DObj(tobj); return; } result->pdata = NULL; result->cdata = NULL; if (io->tweaky == NULL) io->tweaky = io->obj; else if (io->tweaky != io->obj) ReleaseEERIE3DObj(io->obj); io->obj = result; EERIE_Object_Precompute_Fast_Access(io->obj); } EERIE_CreateCedricData(io->obj); if (io) { io->lastanimtime = 0; io->nb_lastanimvertex = 0; } ReleaseEERIE3DObj(tobj); }
void EERIE_MESH_TWEAK_Do(Entity * io, TweakType tw, const res::path & path) { res::path ftl_file = ("game" / path).set_ext("ftl"); if ((!g_resources->getFile(ftl_file)) && (!g_resources->getFile(path))) return; if (!tw) return; if (io == NULL) return; if (io->obj == NULL) return; if(path.empty() && tw == TWEAK_REMOVE) { if(io->tweaky) { delete io->obj; io->obj = io->tweaky; EERIE_Object_Precompute_Fast_Access(io->obj); io->tweaky = NULL; } return; } EERIE_3DOBJ * tobj = NULL; EERIE_3DOBJ * result = NULL; { tobj = loadObject(path); if (!tobj) return; switch (tw) { case (u32)TWEAK_HEAD | (u32)TWEAK_TORSO | (u32)TWEAK_LEGS: if (!io->tweaky) io->tweaky = io->obj; else delete io->obj; io->obj = tobj; return; break; case (u32)TWEAK_HEAD | (u32)TWEAK_TORSO: { EERIE_3DOBJ * result2 = CreateIntermediaryMesh(io->obj, tobj, TWEAK_HEAD); result = CreateIntermediaryMesh(result2, tobj, TWEAK_TORSO); delete result2; break; } case (u32)TWEAK_TORSO | (u32)TWEAK_LEGS: { EERIE_3DOBJ * result2 = CreateIntermediaryMesh(io->obj, tobj, TWEAK_TORSO); result = CreateIntermediaryMesh(result2, tobj, TWEAK_LEGS); delete result2; break; } case (u32)TWEAK_HEAD | (u32)TWEAK_LEGS: result = CreateIntermediaryMesh(tobj, io->obj, TWEAK_TORSO); break; default: result = CreateIntermediaryMesh(io->obj, tobj, tw); break; } if(!result) { delete tobj; return; } if (io->tweaky == NULL) io->tweaky = io->obj; else if (io->tweaky != io->obj) delete io->obj; io->obj = result; EERIE_Object_Precompute_Fast_Access(io->obj); } EERIE_CreateCedricData(io->obj); io->animBlend.lastanimtime = 0; io->animBlend.m_active = false; delete tobj; }
//*********************************************************************************************** // Uses Fast Object Load if FTL file exists //----------------------------------------------------------------------------------------------- // VERIFIED (Cyril 2001/10/15) //*********************************************************************************************** EERIE_3DOBJ * ARX_FTL_Load(const char * file) { // Creates FTL file name char filename[256]; sprintf(filename, "Game\\%s", file); SetExt(filename, ".FTL"); // Checks for FTL file existence if(!PAK_FileExist(filename)) { LogError<<"ARX_FTL_Load: not found in PAK" << filename; return NULL; } // Our file exist we can use it unsigned char * dat; long pos = 0; size_t allocsize; ARX_FTL_PRIMARY_HEADER * afph; ARX_FTL_SECONDARY_HEADER * afsh; ARX_FTL_PROGRESSIVE_DATA_HEADER * afpdh; ARX_FTL_CLOTHES_DATA_HEADER * afcdh; ARX_FTL_COLLISION_SPHERES_DATA_HEADER * afcsdh; ARX_FTL_3D_DATA_HEADER * af3Ddh; char * compressedData = NULL; size_t compressedSize = 0; long NOrelease = 1; long NoCheck = 0; compressedData = MCache_Pop(filename, &compressedSize); if (!compressedData) { compressedData = (char *)PAK_FileLoadMalloc(filename, &compressedSize); NOrelease = MCache_Push(filename, compressedData, compressedSize) ? 1 : 0; } else NoCheck = 1; if(!compressedData) { printf("ARX_FTL_Load: error loading from PAK\n"); return NULL; } long DontCheck = 0; DontCheck = 1; dat = (unsigned char *)STD_Explode(compressedData, compressedSize, &allocsize);//pos,&cpr_pos); // TODO size ignored if(!dat) { printf("ARX_FTL_Load: error decompressing\n"); return NULL; } if (!NOrelease) free(compressedData); // Pointer to Primary Header afph = (ARX_FTL_PRIMARY_HEADER *)dat; pos += sizeof(ARX_FTL_PRIMARY_HEADER); // Verify FTL file Signature if ((afph->ident[0] != 'F') && (afph->ident[1] != 'T') && (afph->ident[2] != 'L')) { printf("ARX_FTL_Load: wrong magic number\n"); free(dat); return NULL; } // Verify FTL file version if (afph->version != CURRENT_FTL_VERSION) { printf("ARX_FTL_Load: wrong version: %f, expected %f\n", afph->version, CURRENT_FTL_VERSION); free(dat); return NULL; } // Verify Checksum if ((!NOCHECKSUM || NoCheck) && !DontCheck) { char check[512]; HERMES_CreateFileCheck(file, check, 512, CURRENT_FTL_VERSION); char * pouet = (char *)(dat + pos); for (long i = 0; i < 512; i++) if (check[i] != pouet[i]) { printf("ARX_FTL_Load: checksum error\n"); free(dat); return NULL; } } // Increases offset by checksum size pos += 512; // Pointer to Secondary Header afsh = (ARX_FTL_SECONDARY_HEADER *)(dat + pos); pos += sizeof(ARX_FTL_SECONDARY_HEADER); EERIE_3DOBJ * obj = NULL; // Check For & Load 3D Data if (afsh->offset_3Ddata != -1) { //todo free obj = (EERIE_3DOBJ *)malloc(sizeof(EERIE_3DOBJ)); memset(obj, 0, sizeof(EERIE_3DOBJ)); af3Ddh = (ARX_FTL_3D_DATA_HEADER *)(dat + afsh->offset_3Ddata); pos = afsh->offset_3Ddata; pos += sizeof(ARX_FTL_3D_DATA_HEADER); obj->nbvertex = af3Ddh->nb_vertex; obj->nbfaces = af3Ddh->nb_faces; obj->nbmaps = af3Ddh->nb_maps; obj->nbgroups = af3Ddh->nb_groups; obj->nbaction = af3Ddh->nb_action; obj->nbselections = af3Ddh->nb_selections; obj->origin = af3Ddh->origin; strcpy(obj->file, af3Ddh->name); // Alloc'n'Copy vertices if (obj->nbvertex > 0) { //todo free obj->vertexlist = (EERIE_VERTEX *)malloc(sizeof(EERIE_VERTEX) * obj->nbvertex); obj->vertexlist3 = (EERIE_VERTEX *)malloc(sizeof(EERIE_VERTEX) * obj->nbvertex); for (long ii = 0; ii < obj->nbvertex; ii++) { memcpy(&obj->vertexlist[ii], dat + pos, sizeof(EERIE_OLD_VERTEX)); memcpy(&obj->vertexlist3[ii], dat + pos, sizeof(EERIE_OLD_VERTEX)); pos += sizeof(EERIE_OLD_VERTEX); } obj->point0.x = obj->vertexlist[obj->origin].v.x; obj->point0.y = obj->vertexlist[obj->origin].v.y; obj->point0.z = obj->vertexlist[obj->origin].v.z; for (long i = 0; i < obj->nbvertex; i++) { obj->vertexlist[i].vert.color = 0xFF000000; obj->vertexlist3[i].vert.color = 0xFF000000; } } // Alloc'n'Copy faces if (obj->nbfaces > 0) { //todo free obj->facelist = (EERIE_FACE *)malloc(sizeof(EERIE_FACE) * obj->nbfaces); for (long ii = 0; ii < af3Ddh->nb_faces; ii++) { EERIE_FACE_FTL * eff = (EERIE_FACE_FTL *)(dat + pos); obj->facelist[ii].facetype = eff->facetype; obj->facelist[ii].texid = eff->texid; obj->facelist[ii].transval = eff->transval; obj->facelist[ii].temp = eff->temp; memcpy(&obj->facelist[ii].norm, &eff->norm, sizeof(EERIE_3D)); for (long kk = 0; kk < IOPOLYVERT; kk++) { memcpy(&obj->facelist[ii].nrmls[kk], &eff->nrmls[kk], sizeof(EERIE_3D)); 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]; } pos += sizeof(EERIE_FACE_FTL); } } // Alloc'n'Copy textures if (af3Ddh->nb_maps > 0) { char ficc[256]; char ficc2[256]; char ficc3[256]; //todo free obj->texturecontainer = (TextureContainer **)malloc(sizeof(TextureContainer *) * af3Ddh->nb_maps); for (long i = 0; i < af3Ddh->nb_maps; i++) { memcpy(ficc2, dat + pos, 256); strcpy(ficc3, ficc2); File_Standardize(ficc3, ficc); obj->texturecontainer[i] = D3DTextr_CreateTextureFromFile(ficc, 0, 0, EERIETEXTUREFLAG_LOADSCENE_RELEASE); if (GDevice && obj->texturecontainer[i] && !obj->texturecontainer[i]->m_pddsSurface) obj->texturecontainer[i]->Restore(GDevice); MakeUserFlag(obj->texturecontainer[i]); pos += 256; } } // Alloc'n'Copy groups if (obj->nbgroups > 0) { //todo free obj->grouplist = (EERIE_GROUPLIST *)malloc(sizeof(EERIE_GROUPLIST) * obj->nbgroups); memcpy(obj->grouplist, dat + pos, sizeof(EERIE_GROUPLIST) * obj->nbgroups); pos += sizeof(EERIE_GROUPLIST) * obj->nbgroups; for (long i = 0; i < obj->nbgroups; i++) if (obj->grouplist[i].nb_index > 0) { //TO DO: FREE+++++++++++++++++++++++ obj->grouplist[i].indexes = (long *)malloc(sizeof(long) * obj->grouplist[i].nb_index); memcpy(obj->grouplist[i].indexes, dat + pos, sizeof(long)*obj->grouplist[i].nb_index); pos += sizeof(long) * obj->grouplist[i].nb_index; } } // Alloc'n'Copy action points if (obj->nbaction > 0) { //todo free obj->actionlist = (EERIE_ACTIONLIST *)malloc(sizeof(EERIE_ACTIONLIST) * obj->nbaction); memcpy(obj->actionlist, dat + pos, sizeof(EERIE_ACTIONLIST)*obj->nbaction); pos += sizeof(EERIE_ACTIONLIST) * obj->nbaction; } // Alloc'n'Copy selections if (obj->nbselections > 0) { //todo free++ obj->selections = (EERIE_SELECTIONS *)malloc(sizeof(EERIE_SELECTIONS) * obj->nbselections); memcpy(obj->selections, dat + pos, sizeof(EERIE_SELECTIONS)*obj->nbselections); pos += sizeof(EERIE_SELECTIONS) * obj->nbselections; for (long i = 0; i < af3Ddh->nb_selections; i++) { //todo free+++ obj->selections[i].selected = (long *)malloc(sizeof(long) * obj->selections[i].nb_selected); memcpy(obj->selections[i].selected, dat + pos, sizeof(long)*obj->selections[i].nb_selected); pos += sizeof(long) * obj->selections[i].nb_selected; } } obj->pbox = NULL; } if (!obj) { printf("ARX_FTL_Load: error loading data\n"); free(dat); return NULL; } // Alloc'n'Copy Collision Spheres Data if (afsh->offset_collision_spheres != -1) { afcsdh = (ARX_FTL_COLLISION_SPHERES_DATA_HEADER *)(dat + afsh->offset_collision_spheres); pos = afsh->offset_collision_spheres; pos += sizeof(ARX_FTL_COLLISION_SPHERES_DATA_HEADER); obj->sdata = (COLLISION_SPHERES_DATA *)malloc(sizeof(COLLISION_SPHERES_DATA)); obj->sdata->nb_spheres = afcsdh->nb_spheres; obj->sdata->spheres = (COLLISION_SPHERE *)malloc(sizeof(COLLISION_SPHERE) * obj->sdata->nb_spheres); memcpy(obj->sdata->spheres, dat + pos, sizeof(COLLISION_SPHERE)*obj->sdata->nb_spheres); pos += sizeof(COLLISION_SPHERE) * obj->sdata->nb_spheres; } // Alloc'n'Copy Progressive DATA if (afsh->offset_progressive_data != -1) { afpdh = (ARX_FTL_PROGRESSIVE_DATA_HEADER *)(dat + afsh->offset_progressive_data); pos = afsh->offset_progressive_data; pos += sizeof(ARX_FTL_PROGRESSIVE_DATA_HEADER); pos += sizeof(PROGRESSIVE_DATA) * afpdh->nb_vertex; } // Alloc'n'Copy Clothes DATA if (afsh->offset_clothes_data != -1) { obj->cdata = (CLOTHES_DATA *)malloc(sizeof(CLOTHES_DATA)); memset(obj->cdata, 0, sizeof(CLOTHES_DATA)); afcdh = (ARX_FTL_CLOTHES_DATA_HEADER *)(dat + afsh->offset_clothes_data); obj->cdata->nb_cvert = (short)afcdh->nb_cvert; obj->cdata->nb_springs = (short)afcdh->nb_springs; pos = afsh->offset_clothes_data; pos += sizeof(ARX_FTL_CLOTHES_DATA_HEADER); // now load cvert obj->cdata->cvert = (CLOTHESVERTEX *)malloc(sizeof(CLOTHESVERTEX) * obj->cdata->nb_cvert); obj->cdata->backup = (CLOTHESVERTEX *)malloc(sizeof(CLOTHESVERTEX) * obj->cdata->nb_cvert); memcpy(obj->cdata->cvert, dat + pos, sizeof(CLOTHESVERTEX)*obj->cdata->nb_cvert); memcpy(obj->cdata->backup, dat + pos, sizeof(CLOTHESVERTEX)*obj->cdata->nb_cvert); pos += sizeof(CLOTHESVERTEX) * obj->cdata->nb_cvert; // now load springs obj->cdata->springs = (EERIE_SPRINGS *)malloc(sizeof(EERIE_SPRINGS) * obj->cdata->nb_springs); memcpy(obj->cdata->springs, dat + pos, sizeof(EERIE_SPRINGS)*obj->cdata->nb_springs); pos += sizeof(EERIE_SPRINGS) * obj->cdata->nb_springs; } free(dat); if (BH_MODE) EERIE_OBJECT_MakeBH(obj); EERIE_OBJECT_CenterObjectCoordinates(obj); EERIE_CreateCedricData(obj); EERIEOBJECT_CreatePFaces(obj); // Now we can release our cool FTL file EERIE_Object_Precompute_Fast_Access(obj); LogInfo<<"loaded "<< file; return obj; }