void BinGZipFile::InnerGetNumberOfFiles(void) { mNumberOfFiles = 0; for (u32 pointer = 0; pointer < mBufferSize;) { u16 temp = GetU16LE(pointer); pointer += 6; // condition for gzip header if (GetU32LE(pointer) == 0x00088B1F && GetU32LE(pointer + 4) == 0x00000000) { ++mNumberOfFiles; } pointer += temp; } if (mNumberOfFiles == 0) { LOGGER->Log(LOGGER_WARNING, "Warning: %s isn't archive. number_of_files == 0", mFileName.c_str()); } }
u32 BinGZipFile::InnerGetFileOffset(const u32& fileNumber) { if (fileNumber >= mNumberOfFiles) { return 0; } u32 current_file = 0; for (u32 pointer = 0; pointer < mBufferSize;) { u16 temp = GetU16LE(pointer); pointer += 6; // condition for gzip header if (GetU32LE(pointer) == 0x00088B1F && GetU32LE(pointer + 4) == 0x00000000) { if (fileNumber == current_file) { return pointer; } } ++current_file; pointer += temp; } return 0; }
File * FieldPackFile::Extract(u32 file_number) { // there are only 8 files if (file_number > 8) { return NULL; } u32 length_uncompressed = GetU32LE(0x010C + file_number * 0x04); u32 first_file = GetU32LE(0x0130 + file_number * 0x04); u32 length = 0; if (file_number < 8) { length = GetU32LE(0x0130 + (file_number + 1) * 0x04) - first_file; } else { length = mBufferSize - first_file; } ArchiveFile* comp = new ArchiveFile(this, first_file, length); File* file = new File(comp, 0, length_uncompressed); delete comp; return file; }
void BcxFile::GetModel( std::vector< s16 >& skeleton_length, const Unit& unit, Ogre::MeshPtr mesh, Ogre::SkeletonPtr skeleton, VectorTexForGenBsx& textures ) { u32 offset_to_model_info = GetU32LE(0x04); u8 number_of_bones = GetU8(offset_to_model_info + 0x02); u8 number_of_parts = GetU8(offset_to_model_info + 0x03); u8 number_of_animations = GetU8(offset_to_model_info + 0x04); ////////////////////////// // mesh ////////////////////////// u16 offset_to_parts = GetU16LE(offset_to_model_info + 0x1c) + number_of_bones * 4; MeshFile file_m(this); file_m.GetData(unit.name, offset_to_parts, number_of_parts, mesh, textures); ////////////////////////// ////////////////////////// // skeleton ////////////////////////// u16 offset_to_bones = GetU16LE(offset_to_model_info + 0x1C); SkeletonFile file_s(this); file_s.GetData( skeleton_length, offset_to_bones, number_of_bones, skeleton ); ////////////////////////// /////////////////////////////////////////////////// // animations /////////////////////////////////////////////////// u32 offset_to_animations = GetU32LE(offset_to_model_info + 0x1C) - 0x80000000 + number_of_bones * 4 + number_of_parts * 0x20; AnimationFile afile(this); afile.GetData( skeleton_length, unit, offset_to_animations, number_of_animations, 0, skeleton ); }
void BcxFile::GetSkeleton( std::vector< s16 >& skeleton_length ) { u32 offset_to_model_info = GetU32LE(0x04); u8 number_of_bones = GetU8(offset_to_model_info + 0x02); u16 offset_to_bones = GetU16LE(offset_to_model_info + 0x1C); SkeletonFile file_s(this); Ogre::SkeletonPtr skeleton; skeleton.setNull(); file_s.GetData( skeleton_length, offset_to_bones, number_of_bones, skeleton); }
Ogre::Entity* ModelFile::GetModel( const ModelInfo& info ) { VectorTexForGen textures; Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().create( info.data.name + "export", "General" ); Ogre::SkeletonPtr skeleton = Ogre::SkeletonManager::getSingleton().create( info.data.name + "export", "General" ); int number_of_bones = GetU8( 0x02 ); int number_of_parts = GetU8( 0x03 ); int offset_to_bones = GetU32LE( 0x0c ); int offset_to_parts = GetU32LE( 0x10 ); Ogre::Bone* root1 = skeleton->createBone( "0", 0 ); Ogre::Bone* root2 = skeleton->createBone( "1", 1 ); root1->addChild( root2 ); for( int i = 0; i < number_of_bones; ++i ) { Bone bone; bone.parent_id = ( i != 0 ) ? ( s8 )GetU8( offset_to_bones + i * 0x04 + 0x03 ) : -1; bone.length = ( s16 )GetU16LE( offset_to_bones + i * 0x04 + 0x00 ); m_Skeleton.push_back(bone); Ogre::Bone* bone1 = skeleton->createBone( Ogre::StringConverter::toString( i * 2 + 2 ), i * 2 + 2 ); Ogre::Bone* bone2 = skeleton->createBone( Ogre::StringConverter::toString( i * 2 + 3 ), i * 2 + 3 ); LOGGER->Log( "Add skeleton bone: bone_id = " + Ogre::StringConverter::toString( i ) + ", length = " + Ogre::StringConverter::toString( bone.length ) + ", parent = " + Ogre::StringConverter::toString( bone.parent_id ) + ".\n" ); if( bone.parent_id == -1 ) { skeleton->getBone( 1 )->addChild( bone1 ); } else { skeleton->getBone( bone.parent_id * 2 + 3 )->addChild( bone1 ); } bone1->addChild( bone2 ); } AnimationExtractor( skeleton, info, m_Skeleton ); // draw skeleton { //DrawSkeleton( m_Skeleton, mesh ); } for( int i = 0; i < number_of_parts; ++i ) { MeshExtractor( info.data, "ffix/field_model/" + info.data.name, this, offset_to_parts + i * 0x28, textures, mesh ); } // <OGRE> /////////////////////////////// skeleton->optimiseAllAnimations(); Ogre::SkeletonSerializer skeleton_serializer; skeleton_serializer.exportSkeleton( skeleton.getPointer(), "exported/models/field/units/" + info.data.name + ".skeleton" ); // Update bounds Ogre::AxisAlignedBox aabb( -999, -999, -999, 999, 999, 999 ); mesh->_setBounds( aabb, false ); mesh->_setBoundingSphereRadius( 999 ); mesh->setSkeletonName( "models/field/units/" + info.data.name + ".skeleton" ); Ogre::MeshSerializer ser; ser.exportMesh( mesh.getPointer(), "exported/models/field/units/" + info.data.name + ".mesh" ); // create and export textures for model //if (textures.size() > 0) { Vram* vram = new Vram(); File* tex = new File( "./data/field/5/1b/2/4/1.tim" ); LoadTimFileToVram( tex, 0, vram ); delete tex; tex = new File( "./data/field/5/1b/2/4/2.tim" ); LoadTimFileToVram( tex, 0, vram ); delete tex; vram->Save( "1.jpg" ); CreateTexture( vram, info.data, "exported/models/field/units/" + info.data.name + ".png", textures ); delete vram; } CreateMaterial( "ffix/field_model/" + info.data.name, "exported/models/field/units/" + info.data.name + ".material", ( textures.size() > 0 ) ? "models/field/units/" + info.data.name + ".png" : "", "", "" ); Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager( "Scene" ); Ogre::Entity* thisEntity = scene_manager->createEntity( info.data.name, "models/field/units/" + info.data.name + ".mesh" ); //thisEntity->setDisplaySkeleton(true); //thisEntity->setDebugDisplayEnabled(true); thisEntity->setVisible( false ); thisEntity->getAnimationState( info.animations_name[ 0 ] )->setEnabled(true); thisEntity->getAnimationState( info.animations_name[ 0 ] )->setLoop(true); Ogre::SceneNode* thisSceneNode = scene_manager->getRootSceneNode()->createChildSceneNode(); thisSceneNode->setPosition( 0, 0, 0 ); thisSceneNode->roll( Ogre::Radian( Ogre::Degree( 180.0f ) ) ); thisSceneNode->yaw( Ogre::Radian( Ogre::Degree( 120.0f ) ) ); thisSceneNode->pitch( Ogre::Radian( Ogre::Degree(90.0f ) ) ); thisSceneNode->attachObject( thisEntity ); return thisEntity; }
void LzsFile::ExtractLzs() { u32 input_length = GetU32LE(0) + 4; if (input_length != m_BufferSize) { //LOGGER->Log("Warning: extract failed, this is not lzs!\n"); return; } u32 extract_size = (m_BufferSize + 255) & ~255; u8* extract_buffer = (u8*)malloc(extract_size); unsigned int input_offset = 4; int output_offset = 0; u8 control_byte = 0; u8 control_bit = 0; while (input_offset < m_BufferSize) { if (control_bit == 0) { control_byte = ((u8*)m_Buffer)[input_offset++]; control_bit = 8; } if (control_byte & 1) { ((u8*)extract_buffer)[output_offset++] = ((u8*)m_Buffer)[input_offset++]; if (output_offset == extract_size) { extract_size += 256; extract_buffer = (u8*)realloc(extract_buffer, extract_size); } } else { u8 reference1 = ((u8*)m_Buffer)[input_offset++]; u8 reference2 = ((u8*)m_Buffer)[input_offset++]; u16 reference_offset = reference1 | ((reference2 & 0xF0) << 4); u8 reference_length = (reference2 & 0xF) + 3; int real_offset = output_offset - ((output_offset - 18 - reference_offset) & 0xFFF); for (int j = 0; j < reference_length; ++j) { if (real_offset < 0) { ((u8*)extract_buffer)[output_offset++] = 0; } else { ((u8*)extract_buffer)[output_offset++] = ((u8*)extract_buffer)[real_offset]; } if (output_offset == extract_size) { extract_size += 256; extract_buffer = (u8*)realloc(extract_buffer, extract_size); } ++real_offset; } } control_byte >>= 1; control_bit--; } free(m_Buffer); // the real buffer size and mBufferSize will be a bit different m_Buffer = extract_buffer; m_BufferSize = output_offset; }
void AnimationFile::GetData( std::vector< s16 >& skeleton_length, const Unit& unit, const int offset_to_animations, const int number_of_animation, const int start_animation, Ogre::SkeletonPtr skeleton) { for (int i = 0; i < number_of_animation; ++i) { /*LOGGER->Log(LOGGER_INFO, "Animation Header %02x%02x %02x %02x %02x %02x %02x%02x %02x%02x %02x%02x %02x%02x%02x%02x", GetU8(offset_to_animations + i * 0x10 + 0x00), GetU8(offset_to_animations + i * 0x10 + 0x01), GetU8(offset_to_animations + i * 0x10 + 0x02), GetU8(offset_to_animations + i * 0x10 + 0x03), GetU8(offset_to_animations + i * 0x10 + 0x04), GetU8(offset_to_animations + i * 0x10 + 0x05), GetU8(offset_to_animations + i * 0x10 + 0x06), GetU8(offset_to_animations + i * 0x10 + 0x07), GetU8(offset_to_animations + i * 0x10 + 0x08), GetU8(offset_to_animations + i * 0x10 + 0x09), GetU8(offset_to_animations + i * 0x10 + 0x0A), GetU8(offset_to_animations + i * 0x10 + 0x0B), GetU8(offset_to_animations + i * 0x10 + 0x0C), GetU8(offset_to_animations + i * 0x10 + 0x0D), GetU8(offset_to_animations + i * 0x10 + 0x0E), GetU8(offset_to_animations + i * 0x10 + 0x0F)); */ AnimationHeader header; header.number_of_frames = GetU16LE(offset_to_animations + i * 0x10 + 0x00); header.number_of_bones = GetU8(offset_to_animations + i * 0x10 + 0x02); header.number_of_frames_translation = GetU8(offset_to_animations + i * 0x10 + 0x03); header.number_of_static_translation = GetU8(offset_to_animations + i * 0x10 + 0x04); header.number_of_frames_rotation = GetU8(offset_to_animations + i * 0x10 + 0x05); header.offset_to_frames_translation_data = GetU16LE(offset_to_animations + i * 0x10 + 0x06); header.offset_to_static_translation_data = GetU16LE(offset_to_animations + i * 0x10 + 0x08); header.offset_to_frames_rotation_data = GetU16LE(offset_to_animations + i * 0x10 + 0x0A); header.offset_to_animation_data = GetU32LE(offset_to_animations + i * 0x10 + 0x0C) - 0x80000000; m_AnimationHeaders.push_back(header); } for (size_t i = 0; (i < static_cast<size_t>(number_of_animation)) && (start_animation + i < unit.animations.size()); ++i) { if (unit.animations[start_animation + i] == "" || unit.animations[start_animation + i] == " ") { continue; } /* File file(mpBuffer, m_AnimationHeaders[i].offset_to_animation_data, 0x04 + m_AnimationHeaders[i].number_of_bones * 0x08 + m_AnimationHeaders[i].number_of_frames_translation * m_AnimationHeaders[i].number_of_frames * 0x02 + m_AnimationHeaders[i].number_of_static_translation * 0x02 + m_AnimationHeaders[i].number_of_frames_rotation * m_AnimationHeaders[i].number_of_frames); file.WriteFile(RString((Ogre::String("dump/") + Ogre::String("animation_") + Ogre::StringConverter::toString(i) + Ogre::String("_data")).c_str())); */ Ogre::Animation* anim = skeleton->createAnimation(unit.animations[start_animation + i], (float)(m_AnimationHeaders[i].number_of_frames - 1) / 30.0f); for (u32 j = 0; j < m_AnimationHeaders[i].number_of_frames; ++j) { Frame frame; // root bone Ogre::Bone* root = skeleton->getBone(0); Ogre::NodeAnimationTrack* track; if (j == 0) { track = anim->createNodeTrack(0, root); track->removeAllKeyFrames(); } else { track = anim->getNodeTrack(0); } Ogre::TransformKeyFrame* frame_root = track->createNodeKeyFrame((float)j / 30.0f); Ogre::Quaternion rot; Ogre::Matrix3 mat; mat.FromEulerAnglesZXY(Ogre::Radian(Ogre::Degree(180)), Ogre::Radian(Ogre::Degree(0)), Ogre::Radian(Ogre::Degree(0))); rot.FromRotationMatrix(mat); frame_root->setRotation(rot); for (u32 k = 0; k < m_AnimationHeaders[i].number_of_bones; ++k) { BonePosition position; u8 flag = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x00); u8 rx = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x01); u8 ry = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x02); u8 rz = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x03); u8 tx = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x04); u8 ty = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x05); u8 tz = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x06); // rotation if (flag & 0x01) { position.rotation_x = 360.0f * GetU8(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_rotation_data + rx * m_AnimationHeaders[i].number_of_frames + j) / 255.0f; } else { position.rotation_x = 360.0f * rx / 255.0f; } if (flag & 0x02) { position.rotation_y = 360.0f * GetU8(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_rotation_data + ry * m_AnimationHeaders[i].number_of_frames + j) / 255.0f; } else { position.rotation_y = 360.0f * ry / 255.0f; } if (flag & 0x04) { position.rotation_z = 360.0f * GetU8(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_rotation_data + rz * m_AnimationHeaders[i].number_of_frames + j) / 255.0f; } else { position.rotation_z = 360.0f * rz / 255.0f; } // translation position.translation_x = 0; position.translation_y = 0; position.translation_z = 0; if (flag & 0x10) { position.translation_x = static_cast<float>( -(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_translation_data + tx * m_AnimationHeaders[i].number_of_frames * 2 + j * 2)); } else if (tx != 0xFF) { position.translation_x = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_static_translation_data + tx * 2)); } if (flag & 0x20) { position.translation_y = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_translation_data + ty * m_AnimationHeaders[i].number_of_frames * 2 + j * 2)); } else if (ty != 0xFF) { position.translation_y = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_static_translation_data + ty * 2)); } if (flag & 0x40) { position.translation_z = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_translation_data + tz * m_AnimationHeaders[i].number_of_frames * 2 + j * 2)); } else if (tz != 0xFF) { position.translation_z = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_static_translation_data + tz * 2)); } //LOGGER->Log(LOGGER_INFO, "%d %d", m_AnimationHeaders[i].number_of_frames, j); //LOGGER->Log(LOGGER_INFO, "animation (%f %f %f) (%f %f %f)", position.rotation_x, position.rotation_y, position.rotation_z, position.translation_x, position.translation_y, position.translation_z); frame.bone.push_back(position); Ogre::Bone* bone1 = skeleton->getBone(k * 2 + 1); Ogre::Bone* bone2 = skeleton->getBone(k * 2 + 2); Ogre::NodeAnimationTrack* track1; Ogre::NodeAnimationTrack* track2; if (j == 0) { track1 = anim->createNodeTrack(k * 2 + 1, bone1); track1->removeAllKeyFrames(); track2 = anim->createNodeTrack(k * 2 + 2, bone2); track2->removeAllKeyFrames(); } else { track1 = anim->getNodeTrack(k * 2 + 1); track2 = anim->getNodeTrack(k * 2 + 2); } Ogre::TransformKeyFrame* frame1 = track1->createNodeKeyFrame((float)j / 30.0f); Ogre::TransformKeyFrame* frame2 = track2->createNodeKeyFrame((float)j / 30.0f); float length = skeleton_length[ k ]; frame1->setTranslate(Ogre::Vector3(position.translation_x, position.translation_z - length, position.translation_y) / 1024); Ogre::Quaternion rot; Ogre::Matrix3 mat; mat.FromEulerAnglesZXY(Ogre::Radian(Ogre::Degree(-position.rotation_y)), Ogre::Radian(Ogre::Degree(-position.rotation_x)), Ogre::Radian(Ogre::Degree(-position.rotation_z))); rot.FromRotationMatrix(mat); frame2->setRotation(rot); } } } }
Ogre::Entity* StageFile::GetModel( const StageInfo& info ) { //DumpSettings("exported/" + info.data.name + ".lua"); VectorTexForGen textures; Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().create(info.data.name + "export", "General"); Ogre::SkeletonPtr skeleton = Ogre::SkeletonManager::getSingleton().create(info.data.name + "export", "General"); u32 number_of_files = GetU32LE(0); LOGGER->Log("Number of file " + IntToString(number_of_files) + "\n"); Ogre::Bone* root1 = skeleton->createBone( "0", 0 ); Ogre::Bone* root2 = skeleton->createBone( "1", 1 ); root1->addChild( root2 ); Ogre::Animation* anim = skeleton->createAnimation( "Idle", 1 ); Ogre::NodeAnimationTrack* track1 = anim->createNodeTrack( 0, root1 ); track1->removeAllKeyFrames(); Ogre::TransformKeyFrame* frame1 = track1->createNodeKeyFrame( 0 ); Ogre::Matrix3 matrix; matrix.FromEulerAnglesYXZ( Ogre::Radian( Ogre::Degree( 0 ) ), Ogre::Radian( Ogre::Degree( -90 ) ), Ogre::Radian( Ogre::Degree( 0 ) ) ); Ogre::Quaternion rot; rot.FromRotationMatrix( matrix ); frame1->setRotation( rot ); for (u32 i = 1; i < number_of_files - 1; ++i) { int offset_to_vertex = GetU32LE(0x04 + i * 0x04); MeshExtractor(info.data, "ffvii/battle_stage/" + info.data.name, this, offset_to_vertex, textures, mesh, Ogre::StringConverter::toString(i), 1); } // <OGRE> /////////////////////////////// skeleton->optimiseAllAnimations(); Ogre::SkeletonSerializer skeleton_serializer; skeleton_serializer.exportSkeleton(skeleton.getPointer(), "exported/models/ffvii/battle/stages/" + info.data.name + ".skeleton"); // Update bounds Ogre::AxisAlignedBox aabb(-999, -999, -999, 999, 999, 999); mesh->_setBounds(aabb, false); mesh->_setBoundingSphereRadius(999); mesh->setSkeletonName( "models/ffvii/battle/stages/" + info.data.name + ".skeleton" ); Ogre::MeshSerializer ser; ser.exportMesh(mesh.getPointer(), "exported/models/ffvii/battle/stages/" + info.data.name + ".mesh"); // create and export textures for model if( textures.size() > 0 ) { int number_of_files = GetU32LE( 0x00 ); int offset_to_texture = GetU32LE( number_of_files * 0x04 ); Vram* vram = Vram::MakeInstance().release(); LoadTimFileToVram( this, offset_to_texture, vram ); //vram->Save( "qqq" ); CreateTexture( vram, info.data, "exported/models/ffvii/battle/stages/" + info.data.name + ".png", textures ); delete vram; } CreateMaterial("ffvii/battle_stage/" + info.data.name, "exported/models/ffvii/battle/stages/" + info.data.name + ".material", "models/ffvii/battle/stages/" + info.data.name + ".png", "", ""); Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager( "Scene" ); Ogre::Entity* thisEntity = scene_manager->createEntity( info.data.name, "models/ffvii/battle/stages/" + info.data.name + ".mesh" ); //thisEntity->setDisplaySkeleton(true); //thisEntity->setDebugDisplayEnabled(true); thisEntity->setVisible(false); thisEntity->getAnimationState( "Idle" )->setEnabled( true ); thisEntity->getAnimationState( "Idle" )->setLoop( true ); Ogre::SceneNode* thisSceneNode = scene_manager->getRootSceneNode()->createChildSceneNode(); thisSceneNode->setPosition( 0, 0, 0 ); thisSceneNode->roll( Ogre::Radian( Ogre::Degree( 180.0f ) ) ); thisSceneNode->yaw( Ogre::Radian( Ogre::Degree( 120.0f ) ) ); thisSceneNode->pitch( Ogre::Radian( Ogre::Degree( 90.0f ) ) ); thisSceneNode->attachObject( thisEntity ); return thisEntity; }