void LodConfigSerializer::writeLodBasicInfo()
	{
		writeChunkHeader(LCCID_BASIC_INFO, calcLodBasicInfoSize());
		writeString(mLodConfig->mesh->getGroup());
		writeString(mLodConfig->mesh->getName());
		writeString(mLodConfig->strategy->getName());
	}
	//---------------------------------------------------------------------
    void SkeletonSerializer::writeSkeleton(const Skeleton* pSkel, SkeletonVersion ver)
    {
		// Write blend mode
		if ((int)ver > (int)SKELETON_VERSION_1_0)
		{
			writeChunkHeader(SKELETON_BLENDMODE, SSTREAM_OVERHEAD_SIZE + sizeof(unsigned short));
			uint16 blendMode = static_cast<uint16>(pSkel->getBlendMode());
			writeShorts(&blendMode, 1);
		}
		
        // Write each bone
        unsigned short numBones = pSkel->getNumBones();
        unsigned short i;
        for (i = 0; i < numBones; ++i)
        {
            Bone* pBone = pSkel->getBone(i);
            writeBone(pSkel, pBone);
        }
        // Write parents
        for (i = 0; i < numBones; ++i)
        {
            Bone* pBone = pSkel->getBone(i);
            unsigned short handle = pBone->getHandle();
            Bone* pParent = (Bone*)pBone->getParent(); 
            if (pParent != NULL) 
            {
                writeBoneParent(pSkel, handle, pParent->getHandle());             
            }
        }
    }
	void LodConfigSerializer::writeLodAdvancedInfo()
	{
		writeChunkHeader(LCCID_ADVANCED_INFO, calcLodAdvancedInfoSize());
		writeBools(&mLodConfig->advanced.useCompression, 1);
		writeBools(&mLodConfig->advanced.useVertexNormals, 1);
		writeBools(&mLodConfig->advanced.useBackgroundQueue, 1);
		writeFloats(&mLodConfig->advanced.outsideWeight, 1);
		writeFloats(&mLodConfig->advanced.outsideWalkAngle, 1);
	}
    //---------------------------------------------------------------------
    void SkeletonSerializer::writeAnimation(const Skeleton* pSkel, 
        const Animation* anim, SkeletonVersion ver)
    {
        writeChunkHeader(SKELETON_ANIMATION, calcAnimationSize(pSkel, anim, ver));

        // char* name                       : Name of the animation
        writeString(anim->getName());
        // float length                      : Length of the animation in seconds
        float len = anim->getLength();
        writeFloats(&len, 1);
        pushInnerChunk(mStream);
        {
        if ((int)ver > (int)SKELETON_VERSION_1_0)
        {
            if (anim->getUseBaseKeyFrame())
            {
                size_t size = SSTREAM_OVERHEAD_SIZE;
                // char* baseAnimationName (including terminator)
                    size += calcStringSize(anim->getBaseKeyFrameAnimationName());
                // float baseKeyFrameTime
                size += sizeof(float);
                
                writeChunkHeader(SKELETON_ANIMATION_BASEINFO, size);
                
                // char* baseAnimationName (blank for self)
                writeString(anim->getBaseKeyFrameAnimationName());
                
                // float baseKeyFrameTime
                float t = (float)anim->getBaseKeyFrameTime();
                writeFloats(&t, 1);
            }
        }

        // Write all tracks
        Animation::NodeTrackIterator trackIt = anim->getNodeTrackIterator();
        while(trackIt.hasMoreElements())
        {
            writeAnimationTrack(pSkel, trackIt.getNext());
        }
        }
        popInnerChunk(mStream);

    }
	void LodConfigSerializer::writeLodConfig()
	{
		writeChunkHeader(LCCID_LOD_CONFIG, calcLodConfigSize());
		pushInnerChunk(mStream);
		writeLodBasicInfo();
		writeLodLevels();
		writeLodAdvancedInfo();
		writeLodProfile();
		popInnerChunk(mStream);
	}
    //---------------------------------------------------------------------
    void SkeletonSerializer::writeBoneParent(const Skeleton* pSkel, 
        unsigned short boneId, unsigned short parentId)
    {
        writeChunkHeader(SKELETON_BONE_PARENT, calcBoneParentSize(pSkel));

        // unsigned short handle             : child bone
        writeShorts(&boneId, 1);
        // unsigned short parentHandle   : parent bone
        writeShorts(&parentId, 1);

    }
	//---------------------------------------------------------------------
	void SkeletonSerializer::writeSkeletonAnimationLink(const Skeleton* pSkel, 
		const LinkedSkeletonAnimationSource& link)
	{
		writeChunkHeader(SKELETON_ANIMATION_LINK, 
			calcSkeletonAnimationLinkSize(pSkel, link));

		// char* skeletonName
		writeString(link.skeletonName);
		// float scale
		writeFloats(&(link.scale), 1);

	}
	void LodConfigSerializer::writeLodLevels()
	{
		writeChunkHeader(LCCID_LOD_LEVELS, calcLodLevelsSize());
		uint32 size = static_cast<uint32>(mLodConfig->levels.size());
		writeInts(&size, 1);

		LodConfig::LodLevelList::iterator it = mLodConfig->levels.begin();
		LodConfig::LodLevelList::iterator itEnd = mLodConfig->levels.end();
		for(;it != itEnd; it++){
			writeFloats(&it->distance, 1);
			writeInts((Ogre::uint32*)&it->reductionMethod, 1);
			writeFloats(&it->reductionValue, 1);
			writeString(it->manualMeshName);
		}
	}
	void LodConfigSerializer::writeLodProfile()
	{
		if(mLodConfig->advanced.profile.empty()){
			return;
		}
		writeChunkHeader(LCCID_PROFILE, calcLodProfileSize());
		uint32 size = static_cast<uint32>(mLodConfig->advanced.profile.size());
		writeInts(&size, 1);
		LodProfile::iterator it = mLodConfig->advanced.profile.begin();
		LodProfile::iterator itEnd = mLodConfig->advanced.profile.end();
		for(;it != itEnd; it++){
			writeObject(it->src);
			writeObject(it->dst);
			writeFloats(&it->cost, 1);
		}
	}
    //---------------------------------------------------------------------
    void SkeletonSerializer::writeAnimationTrack(const Skeleton* pSkel, 
        const NodeAnimationTrack* track)
    {
        writeChunkHeader(SKELETON_ANIMATION_TRACK, calcAnimationTrackSize(pSkel, track));

        // unsigned short boneIndex     : Index of bone to apply to
        Bone* bone = (Bone*)track->getAssociatedNode();
        unsigned short boneid = bone->getHandle();
        writeShorts(&boneid, 1);

        // Write all keyframes
        for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i)
        {
            writeKeyFrame(pSkel, track->getNodeKeyFrame(i));
        }

    }
    //---------------------------------------------------------------------
    void SkeletonSerializer::writeAnimation(const Skeleton* pSkel, 
        const Animation* anim)
    {
        writeChunkHeader(SKELETON_ANIMATION, calcAnimationSize(pSkel, anim));

        // char* name                       : Name of the animation
        writeString(anim->getName());
        // float length                      : Length of the animation in seconds
        float len = anim->getLength();
        writeFloats(&len, 1);

        // Write all tracks
        Animation::NodeTrackIterator trackIt = anim->getNodeTrackIterator();
        while(trackIt.hasMoreElements())
        {
            writeAnimationTrack(pSkel, trackIt.getNext());
        }

    }
    //---------------------------------------------------------------------
    void SkeletonSerializer::writeBone(const Skeleton* pSkel, const Bone* pBone)
    {
        writeChunkHeader(SKELETON_BONE, calcBoneSize(pSkel, pBone));

        unsigned short handle = pBone->getHandle();
        // char* name
        writeString(pBone->getName());
        // unsigned short handle            : handle of the bone, should be contiguous & start at 0
        writeShorts(&handle, 1);
        // Vector3 position                 : position of this bone relative to parent 
        writeObject(pBone->getPosition());
        // Quaternion orientation           : orientation of this bone relative to parent 
        writeObject(pBone->getOrientation());
        // Vector3 scale                    : scale of this bone relative to parent 
        if (pBone->getScale() != Vector3::UNIT_SCALE)
        {
            writeObject(pBone->getScale());
        }
    }
    //---------------------------------------------------------------------
    void SkeletonSerializer::writeKeyFrame(const Skeleton* pSkel, 
        const TransformKeyFrame* key)
    {

        writeChunkHeader(SKELETON_ANIMATION_TRACK_KEYFRAME, calcKeyFrameSize(pSkel, key));

        // float time                    : The time position (seconds)
        float time = key->getTime();
        writeFloats(&time, 1);
        // Quaternion rotate            : Rotation to apply at this keyframe
        writeObject(key->getRotation());
        // Vector3 translate            : Translation to apply at this keyframe
        writeObject(key->getTranslate());
        // Vector3 scale                : Scale to apply at this keyframe
        if (key->getScale() != Vector3::UNIT_SCALE)
        {
            writeObject(key->getScale());
        }
    }
    //---------------------------------------------------------------------
    void SkeletonSerializer::writeBone(const Skeleton* pSkel, const Bone* pBone)
    {
        writeChunkHeader(SKELETON_BONE, calcBoneSize(pSkel, pBone));

        unsigned short handle = pBone->getHandle();
        // char* name
        writeString(pBone->getName());
#if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE
        // Hack to fix chunk size validation:
        mChunkSizeStack.back() += calcStringSize(pBone->getName());
#endif
        // unsigned short handle            : handle of the bone, should be contiguous & start at 0
        writeShorts(&handle, 1);
        // Vector3 position                 : position of this bone relative to parent 
        writeObject(pBone->getPosition());
        // Quaternion orientation           : orientation of this bone relative to parent 
        writeObject(pBone->getOrientation());
        // Vector3 scale                    : scale of this bone relative to parent 
        if (pBone->getScale() != Vector3::UNIT_SCALE)
        {
            writeObject(pBone->getScale());
        }
    }
Example #15
0
void MapTile::save()
{
    FileBuffer buffer;

    // MVER
    writeChunkHeader(buffer, "MVER", sizeof(MVER));
    buffer.write(&mver, sizeof(MVER));

    // MHDR
    writeChunkHeader(buffer, "MHDR", sizeof(MHDR));
    FileBuffer::DataPtr<MHDR> mhdrPtr = buffer.ptr<MHDR>();
    buffer.write(&mhdr, sizeof(MHDR));

    // MCIN
    mhdrPtr->mcin = buffer.tell() - 0x14;
    writeChunkHeader(buffer, "MCIN", sizeof(MCIN));
    FileBuffer::DataPtr<ENTRY_MCIN> mcinPtr = buffer.ptr<ENTRY_MCIN>();
    buffer.write(&mhdr, sizeof(MCIN));


    // MTEX
    mhdrPtr->mtex = buffer.tell() - 0x14;
    {
        FileBuffer texBuffer;

        for(auto it = mtex.begin(); it != mtex.end(); ++it)
        {
            texBuffer.write((char*)it->c_str(), it->size() + 1);
        }

        writeChunkHeader(buffer, "MTEX", texBuffer.size());
        buffer.write(&texBuffer);
    }

    //MMDX
    mhdrPtr->mmdx = buffer.tell() - 0x14;
    writeChunkHeader(buffer, "MMDX", mmdx.size());
    buffer.write(&mmdx);

    //MMID
    mhdrPtr->mmid = buffer.tell() - 0x14;
    writeChunkHeader(buffer, "MMID", mmid.size());
    buffer.write(&mmid);

    //MWMO
    mhdrPtr->mwmo = buffer.tell() - 0x14;
    writeChunkHeader(buffer, "MWMO", mwmo.size());
    buffer.write(&mwmo);

    //MWID
    mhdrPtr->mwid = buffer.tell() - 0x14;
    writeChunkHeader(buffer, "MWID", mwid.size());
    buffer.write(&mwid);

    //MDDF
    mhdrPtr->mddf = buffer.tell() - 0x14;
    writeChunkHeader(buffer, "MDDF", mddf.size());
    buffer.write(&mddf);

    //MODF
    mhdrPtr->modf = buffer.tell() - 0x14;
    writeChunkHeader(buffer, "MODF", modf.size());
    buffer.write(&modf);

    //MH2O
    if(mh2o.size())
    {
        mhdrPtr->mh2o = buffer.tell() - 0x14;
        writeChunkHeader(buffer, "MH2O", mh2o.size());
        buffer.write(&mh2o);
    }
    else
    {
        mhdrPtr->mh2o = 0;
    }

    //chunks
    for (auto it = chunks.begin(); it != chunks.end(); ++it)
    {
        FileBuffer chunk = (*it)->write();

        mcinPtr->offset = buffer.tell();
        mcinPtr->size = chunk.size();
        mcinPtr->asyncID = 32;
        mcinPtr->flags = 32;

        buffer.write(&chunk);
        mcinPtr++;
    }

    //MFBO
    if(mfbo.size())
    {
        mhdrPtr->mfbo = buffer.tell() - 0x14;
        mhdrPtr->flags |= 1;
        writeChunkHeader(buffer, "MFBO", mfbo.size());
        buffer.write(&mfbo);
    }
    else
    {
        mhdrPtr->mfbo = 0;
        mhdrPtr->flags &= ~1;
    }

    //MTFX
    if(mtfx.size())
    {
        mhdrPtr->mtfx = buffer.tell() - 0x14;
        writeChunkHeader(buffer, "MTFX", mtfx.size());
        buffer.write(&mtfx);
    }
    else
    {
        mhdrPtr->mtfx = 0;
    }

    File file(filename.toStdString(), File::write);
    file.write_from(&buffer);
}
Example #16
0
/**
 * Save an Operation Stealth type savegame. WIP!
 *
 * NOTE: This is going to be very much a work in progress so the Operation Stealth's
 *       savegame formats that are going to be tried are extremely probably not going
 *       to be supported at all after Operation Stealth becomes officially supported.
 *       This means that the savegame format will hopefully change to something nicer
 *       when official support for Operation Stealth begins.
 */
void CineEngine::makeSaveOS(Common::OutSaveFile &out) {
    int i;

    // Make a temporary Operation Stealth savegame format chunk header and save it.
    ChunkHeader header;
    header.id = TEMP_OS_FORMAT_ID;
    header.version = CURRENT_OS_SAVE_VER;
    header.size = 0; // No data is currently put inside the chunk, all the plain data comes right after it.
    writeChunkHeader(out, header);

    // Start outputting the plain savegame data right after the chunk header.
    out.writeUint16BE(currentDisk);
    out.write(currentPartName, 13);
    out.write(currentPrcName, 13);
    out.write(currentRelName, 13);
    out.write(currentMsgName, 13);
    renderer->saveBgNames(out);
    out.write(currentCtName, 13);

    saveObjectTable(out);
    renderer->savePalette(out);
    g_cine->_globalVars.save(out, NUM_MAX_VAR);
    saveZoneData(out);
    saveCommandVariables(out);
    saveCommandBuffer(out);
    saveZoneQuery(out);

    // FIXME: Save a proper name here, saving an empty string currently.
    // 0x2925: Current music name (String, 13 bytes).
    for (i = 0; i < 13; i++) {
        out.writeByte(0);
    }
    // FIXME: Save proper value for this variable, currently writing zero
    // 0x2932: Is music loaded? (Uint16BE, Boolean).
    out.writeUint16BE(0);
    // FIXME: Save proper value for this variable, currently writing zero
    // 0x2934: Is music playing? (Uint16BE, Boolean).
    out.writeUint16BE(0);

    out.writeUint16BE(renderer->_cmdY);
    out.writeUint16BE(0); // Some unknown variable that seems to always be zero
    out.writeUint16BE(allowPlayerInput);
    out.writeUint16BE(playerCommand);
    out.writeUint16BE(commandVar1);
    out.writeUint16BE(isDrawCommandEnabled);
    out.writeUint16BE(var5);
    out.writeUint16BE(var4);
    out.writeUint16BE(var3);
    out.writeUint16BE(var2);
    out.writeUint16BE(commandVar2);
    out.writeUint16BE(renderer->_messageBg);

    // FIXME: Save proper value for this variable, currently writing zero.
    // An unknown variable at 0x295E: adBgVar1 (Uint16BE).
    out.writeUint16BE(0);
    out.writeSint16BE(currentAdditionalBgIdx);
    out.writeSint16BE(currentAdditionalBgIdx2);
    // FIXME: Save proper value for this variable, currently writing zero.
    // 0x2954: additionalBgVScroll (Uint16BE). This probably means renderer->_bgShift.
    out.writeUint16BE(0);
    // FIXME: Save proper value for this variable, currently writing zero.
    // An unknown variable at 0x2956: adBgVar0 (Uint16BE). Maybe this means bgVar0?
    out.writeUint16BE(0);
    out.writeUint16BE(disableSystemMenu);

    saveAnimDataTable(out);
    saveScreenParams(out);
    saveGlobalScripts(out);
    saveObjectScripts(out);
    saveSeqList(out);
    saveOverlayList(out);
    saveBgIncrustList(out);
}