bmp — Создание пользовательского типа файла в переполнении стека

Я делаю редактор уровней, который должен выводить пользовательский файл карты для использования с исходным кодом, который я напишу для графической библиотеки.

Мой вопрос: что я должен иметь в виду при принятии решения о том, как структурировать пользовательский тип файла? Также, как я могу закодировать стандартное растровое изображение в мой файл (набор плиток), чтобы оно могло содержаться в одном файле, а не в двух файлах; файл карты и набор плиток (файл .bmp).

Благодарю.

0

Решение

Сначала вам нужно спроектировать файловый слой, вам нужны данные фиксированного размера, чтобы определить, как декодировать переменные данные, например, первые четыре байта, которые вы прочитали, могли бы сказать, сколько существует плиток, следующие 4 байта могли бы сказать, сколько файлов карты. после этого у вас, например, есть первый файл, вам нужно определить информацию о вашем файле, например, какой файл и сколько его байтов, затем вы знаете, сколько байт у вас от следующей записи файла и т. д. ,

Вы также можете использовать структуры и перегружать операторы ofstream. << и >> для этого, чтобы создать свой собственный тип файла, Я сделал это сам при создании системы воспроизведения для 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;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]