在C ++中创建自定义文件类型 [英] Creating a custom file-type in C++

查看:161
本文介绍了在C ++中创建自定义文件类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个级别编辑器,需要输出一个自定义地图文件,用于我将为图形库编写的源代码。

I am making a level editor that needs to output a custom map file for use with source code that I will write for a graphics library.

我的问题是:在决定如何构造自定义文件类型时,我需要记住什么?另外,我如何将标准位图图像编码到我的文件(图块集),以便它可以包含在一个文件,而不是两个文件;地图文件和图块集(.bmp文件)。

My question is: What do I need to bear in mind when deciding how to structure a custom file type? Also how can I encode a standard bitmap image into my file (the tile set) so that it can all be contained in a single file rather two files; the map file and tile set (.bmp file).

谢谢。

推荐答案

首先你需要设计你的文件层,你需要固定大小的数据来决定如何解码你的可变数据,例如,你读的前四个字节可以告诉多少瓦片,接下来的4个字节可以告诉有多少个地图文件,在那之后你例如有第一个文件,你必须定义你的文件信息,例如哪个文件和多少字节,那么你知道你离开下一个文件条目多少字节,etc ...

First you need to design your file layer, you need fixed size data to determine how to decode your variable data, for example, the first four bytes you read could tell how many tiles there are, the next 4 bytes could tell how many map files there are, after that you for example have the first file, you have to define your file information, eg which file and how many bytes it is, then you know how many bytes you're away from the next file entry, etc...

您还可以使用结构和重载ofstream运算符<<和>>以创建您自己的文件类型,我在为Need For Speed Underground 2创建一个重放系统时自己这样做。

You can also use structures and overload the ofstream operators << and >> for it to create your own filetype, I did this myself when creating a replay system for Need For Speed Underground 2.

struct Point4D { float x, y, z, w; };
struct Point3D { float x, y, z; };
struct Point2D { float x, y; };


struct QuatRot
{
    Point4D Front;//frontvector
    Point4D Right;//rightvector
    Point4D Up;//upvector
};

#define NFS_MAX_VEHICLES (14)//seriously just 14.. (including the player)


struct VehicleInfo
{
    //type      name                                    array   offset
    float       unknown_01                              [8];    //0x0
    Point3D     Pos;                                            //0x20
    float       unknown_02;                                     //0x2C
    QuatRot     Rotation;                                       //0x30
    Point3D     unknown_03;                                     //0x60
    float       unknown_04;                                     //0x6C
    Point3D     Velocity;                                       //0x70
    float       unknown_05;                                     //0x7C
    Point3D     TurnSpeed;                                      //0x80
    float       unknown_06;                                     //0x8C
    float       SpeedAndBrakeAccelerator;                       //0x90
    float       unknown_07                              [3];    //0x94
    Point3D     unknown_08;                                     //0xA0
    float       unknown_09;                                     //0xAC
    Point4D     unknown_10                              [5];    //0xB0
    float       unknown_11                              [20];   //0x100
    float       unknown_12_is_zero_when_accelerating;           //0x150
    //end of structure...?
};

std::ostream& operator<<(std::ostream& stream, const VehicleInfo &info);
//overload << and >> operators on "VehicleInfo" type
std::ofstream& operator<<(std::ofstream& stream, VehicleInfo &info);
std::ifstream& operator>>(std::ifstream& stream, VehicleInfo &info);
//overload << and >> operators on "FrameInfo" type
std::ofstream& operator<<(std::ofstream& stream, Recorder::FrameInfo &info);
std::ifstream& operator>>(std::ifstream& stream, Recorder::FrameInfo &info);

namespace Recorder
{
    struct FrameInfo//1392 bytes / frame | max 167040 bytes @ 120 fps | 9.56 MB / min max
    {
        std::chrono::high_resolution_clock::duration time;
        VehicleInfo Vehicle;
        int Nitro;
        float RPM;
        float TURBO;
        int CurrentGear;
        KeyManager Keys[256];
    };
};

std::ofstream& operator<<(std::ofstream& stream, VehicleInfo &info)
{
    stream.write(reinterpret_cast<char*>(&info.unknown_01[0]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_01[1]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_01[2]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_01[3]), sizeof(float));
        //...
    stream.write(reinterpret_cast<char*>(&info.unknown_11[18]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_11[19]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_11[20]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_12_is_zero_when_accelerating), sizeof(float));
    return stream;
}

std::ifstream& operator>>(std::ifstream& stream, VehicleInfo &info)
{
    stream.read(reinterpret_cast<char*>(&info.unknown_01[0]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_01[1]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_01[2]), sizeof(float));
            //.....
    stream.read(reinterpret_cast<char*>(&info.unknown_11[16]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_11[17]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_11[18]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_11[19]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_11[20]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_12_is_zero_when_accelerating), sizeof(float));
    return stream;
}

std::ofstream& operator<<(std::ofstream& stream, Recorder::FrameInfo &info)
{
    stream.write(reinterpret_cast<char*>(&info.time), sizeof(std::chrono::high_resolution_clock::duration));
    stream << info.Vehicle;
    stream.write(reinterpret_cast<char*>(&info.Nitro), sizeof(int));
    stream.write(reinterpret_cast<char*>(&info.RPM), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.CurrentGear), sizeof(int));
    stream.write(reinterpret_cast<char*>(&info.TURBO), sizeof(int));
    for(int i = 0; i < 256; ++i)
    {
        stream.write(reinterpret_cast<char*>(&info.Keys[i].Pressed), sizeof(bool));
        stream.write(reinterpret_cast<char*>(&info.Keys[i].Released), sizeof(bool));
        stream.write(reinterpret_cast<char*>(&info.Keys[i].Down), sizeof(bool));
        stream.write(reinterpret_cast<char*>(&info.Keys[i].Up), sizeof(bool));
    }
    return stream;
}

std::ifstream& operator>>(std::ifstream& stream, Recorder::FrameInfo &info)
{
    stream.read(reinterpret_cast<char*>(&info.time), sizeof(std::chrono::high_resolution_clock::duration));
    stream >> info.Vehicle;
    stream.read(reinterpret_cast<char*>(&info.Nitro), sizeof(int));
    stream.read(reinterpret_cast<char*>(&info.RPM), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.CurrentGear), sizeof(int));
    stream.read(reinterpret_cast<char*>(&info.TURBO), sizeof(int));
    for(int i = 0; i < 256; ++i)
    {
        stream.read(reinterpret_cast<char*>(&info.Keys[i].Pressed), sizeof(bool));
        stream.read(reinterpret_cast<char*>(&info.Keys[i].Released), sizeof(bool));
        stream.read(reinterpret_cast<char*>(&info.Keys[i].Down), sizeof(bool));
        stream.read(reinterpret_cast<char*>(&info.Keys[i].Up), sizeof(bool));
    }
    return stream;
}

///

std::stringstream& operator<<(std::stringstream& stream, VehicleInfo &info)
{
    stream.write(reinterpret_cast<char*>(&info.unknown_01[0]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_01[1]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_01[2]), sizeof(float));
            //...
    stream.write(reinterpret_cast<char*>(&info.unknown_11[19]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_11[20]), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.unknown_12_is_zero_when_accelerating), sizeof(float));
    return stream;
}

std::stringstream& operator>>(std::stringstream& stream, VehicleInfo &info)
{
    stream.read(reinterpret_cast<char*>(&info.unknown_01[0]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_01[1]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_01[2]), sizeof(float));
            //....
    stream.read(reinterpret_cast<char*>(&info.unknown_11[20]), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.unknown_12_is_zero_when_accelerating), sizeof(float));
    return stream;
}

std::stringstream& operator<<(std::stringstream& stream, Recorder::FrameInfo &info)
{
    stream.write(reinterpret_cast<char*>(&info.time), sizeof(std::chrono::high_resolution_clock::duration));
    stream << info.Vehicle;
    stream.write(reinterpret_cast<char*>(&info.Nitro), sizeof(int));
    stream.write(reinterpret_cast<char*>(&info.RPM), sizeof(float));
    stream.write(reinterpret_cast<char*>(&info.CurrentGear), sizeof(int));
    stream.write(reinterpret_cast<char*>(&info.TURBO), sizeof(int));
    for(int i = 0; i < 256; ++i)
    {
        stream.write(reinterpret_cast<char*>(&info.Keys[i].Pressed), sizeof(bool));
        stream.write(reinterpret_cast<char*>(&info.Keys[i].Released), sizeof(bool));
        stream.write(reinterpret_cast<char*>(&info.Keys[i].Down), sizeof(bool));
        stream.write(reinterpret_cast<char*>(&info.Keys[i].Up), sizeof(bool));
    }
    return stream;
}

std::stringstream& operator>>(std::stringstream& stream, Recorder::FrameInfo &info)
{
    stream.read(reinterpret_cast<char*>(&info.time), sizeof(std::chrono::high_resolution_clock::duration));
    stream >> info.Vehicle;
    stream.read(reinterpret_cast<char*>(&info.Nitro), sizeof(int));
    stream.read(reinterpret_cast<char*>(&info.RPM), sizeof(float));
    stream.read(reinterpret_cast<char*>(&info.CurrentGear), sizeof(int));
    stream.read(reinterpret_cast<char*>(&info.TURBO), sizeof(int));
    for(int i = 0; i < 256; ++i)
    {
        stream.read(reinterpret_cast<char*>(&info.Keys[i].Pressed), sizeof(bool));
        stream.read(reinterpret_cast<char*>(&info.Keys[i].Released), sizeof(bool));
        stream.read(reinterpret_cast<char*>(&info.Keys[i].Down), sizeof(bool));
        stream.read(reinterpret_cast<char*>(&info.Keys[i].Up), sizeof(bool));
    }
    return stream;
}

这篇关于在C ++中创建自定义文件类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆