Added V1.11
Contains ResourcePacks for storing image and sound data in a virtual file system
This commit is contained in:
parent
786b33b950
commit
3489f28fcb
@ -2,7 +2,7 @@
|
||||
olcPixelGameEngine.h
|
||||
|
||||
+-------------------------------------------------------------+
|
||||
| OneLoneCoder Pixel Game Engine v1.10 |
|
||||
| OneLoneCoder Pixel Game Engine v1.11 |
|
||||
| "Like the command prompt console one, but not..." - javidx9 |
|
||||
+-------------------------------------------------------------+
|
||||
|
||||
@ -207,6 +207,7 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <streambuf>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
@ -270,18 +271,46 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
||||
|
||||
//=============================================================
|
||||
|
||||
class ResourcePack
|
||||
{
|
||||
public:
|
||||
ResourcePack();
|
||||
~ResourcePack();
|
||||
struct sEntry : public std::streambuf {
|
||||
uint32_t nID, nFileOffset, nFileSize; uint8_t* data; void _config() { this->setg((char*)data, (char*)data, (char*)(data + nFileSize)); }};
|
||||
|
||||
public:
|
||||
olc::rcode AddToPack(std::string sFile);
|
||||
|
||||
public:
|
||||
olc::rcode SavePack(std::string sFile);
|
||||
olc::rcode LoadPack(std::string sFile);
|
||||
olc::rcode ClearPack();
|
||||
|
||||
public:
|
||||
olc::ResourcePack::sEntry GetStreamBuffer(std::string sFile);
|
||||
|
||||
private:
|
||||
|
||||
std::map<std::string, sEntry> mapFiles;
|
||||
};
|
||||
|
||||
//=============================================================
|
||||
|
||||
// A bitmap-like structure that stores a 2D array of Pixels
|
||||
class Sprite
|
||||
{
|
||||
public:
|
||||
Sprite();
|
||||
Sprite(std::string sImageFile);
|
||||
Sprite(std::string sImageFile, olc::ResourcePack *pack);
|
||||
Sprite(int32_t w, int32_t h);
|
||||
~Sprite();
|
||||
|
||||
public:
|
||||
olc::rcode LoadFromFile(std::string sImageFile);
|
||||
olc::rcode LoadFromSprFile(std::string sImageFile);
|
||||
olc::rcode LoadFromFile(std::string sImageFile, olc::ResourcePack *pack = nullptr);
|
||||
olc::rcode LoadFromPGESprFile(std::string sImageFile, olc::ResourcePack *pack = nullptr);
|
||||
olc::rcode SaveToPGESprFile(std::string sImageFile);
|
||||
|
||||
public:
|
||||
int32_t width = 0;
|
||||
@ -569,6 +598,11 @@ namespace olc
|
||||
LoadFromFile(sImageFile);
|
||||
}
|
||||
|
||||
Sprite::Sprite(std::string sImageFile, olc::ResourcePack *pack)
|
||||
{
|
||||
LoadFromPGESprFile(sImageFile, pack);
|
||||
}
|
||||
|
||||
Sprite::Sprite(int32_t w, int32_t h)
|
||||
{
|
||||
if(pColData) delete[] pColData;
|
||||
@ -583,12 +617,61 @@ namespace olc
|
||||
if (pColData) delete pColData;
|
||||
}
|
||||
|
||||
olc::rcode Sprite::LoadFromSprFile(std::string sImageFile)
|
||||
olc::rcode Sprite::LoadFromPGESprFile(std::string sImageFile, olc::ResourcePack *pack)
|
||||
{
|
||||
if (pColData) delete[] pColData;
|
||||
|
||||
auto ReadData = [&](std::istream &is)
|
||||
{
|
||||
is.read((char*)&width, sizeof(int32_t));
|
||||
is.read((char*)&height, sizeof(int32_t));
|
||||
pColData = new Pixel[width * height];
|
||||
is.read((char*)pColData, width * height * sizeof(uint32_t));
|
||||
};
|
||||
|
||||
// These are essentially Memory Surfaces represented by olc::Sprite
|
||||
// which load very fast, but are completely uncompressed
|
||||
if (pack == nullptr)
|
||||
{
|
||||
std::ifstream ifs;
|
||||
ifs.open(sImageFile, std::ifstream::binary);
|
||||
if (ifs.is_open())
|
||||
{
|
||||
ReadData(ifs);
|
||||
return olc::OK;
|
||||
}
|
||||
else
|
||||
return olc::FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::istream is(&(pack->GetStreamBuffer(sImageFile)));
|
||||
ReadData(is);
|
||||
}
|
||||
|
||||
|
||||
return olc::FAIL;
|
||||
}
|
||||
|
||||
olc::rcode Sprite::SaveToPGESprFile(std::string sImageFile)
|
||||
{
|
||||
if (pColData == nullptr) return olc::FAIL;
|
||||
|
||||
std::ofstream ofs;
|
||||
ofs.open(sImageFile, std::ifstream::binary);
|
||||
if (ofs.is_open())
|
||||
{
|
||||
ofs.write((char*)&width, sizeof(int32_t));
|
||||
ofs.write((char*)&height, sizeof(int32_t));
|
||||
ofs.write((char*)pColData, width*height*sizeof(uint32_t));
|
||||
ofs.close();
|
||||
return olc::OK;
|
||||
}
|
||||
|
||||
return olc::FAIL;
|
||||
}
|
||||
|
||||
olc::rcode Sprite::LoadFromFile(std::string sImageFile)
|
||||
olc::rcode Sprite::LoadFromFile(std::string sImageFile, olc::ResourcePack *pack)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Use GDI+
|
||||
@ -742,6 +825,146 @@ namespace olc
|
||||
|
||||
//==========================================================
|
||||
|
||||
ResourcePack::ResourcePack()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ResourcePack::~ResourcePack()
|
||||
{
|
||||
ClearPack();
|
||||
}
|
||||
|
||||
olc::rcode ResourcePack::AddToPack(std::string sFile)
|
||||
{
|
||||
std::ifstream ifs(sFile, std::ifstream::binary);
|
||||
if (!ifs.is_open()) return olc::FAIL;
|
||||
|
||||
// Get File Size
|
||||
std::streampos p = 0;
|
||||
p = ifs.tellg();
|
||||
ifs.seekg(0, std::ios::end);
|
||||
p = ifs.tellg() - p;
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
// Create entry
|
||||
sEntry e;
|
||||
e.data = nullptr;
|
||||
e.nFileSize = p;
|
||||
|
||||
// Read file into memory
|
||||
e.data = new uint8_t[e.nFileSize];
|
||||
ifs.read((char*)e.data, e.nFileSize);
|
||||
ifs.close();
|
||||
|
||||
// Add To Map
|
||||
mapFiles[sFile] = e;
|
||||
return olc::OK;
|
||||
}
|
||||
|
||||
olc::rcode ResourcePack::SavePack(std::string sFile)
|
||||
{
|
||||
std::ofstream ofs(sFile, std::ofstream::binary);
|
||||
if (!ofs.is_open()) return olc::FAIL;
|
||||
|
||||
// 1) Write Map
|
||||
size_t nMapSize = mapFiles.size();
|
||||
ofs.write((char*)&nMapSize, sizeof(size_t));
|
||||
for (auto &e : mapFiles)
|
||||
{
|
||||
size_t nPathSize = e.first.size();
|
||||
ofs.write((char*)&nPathSize, sizeof(size_t));
|
||||
ofs.write(e.first.c_str(), nPathSize);
|
||||
ofs.write((char*)&e.second.nID, sizeof(uint32_t));
|
||||
ofs.write((char*)&e.second.nFileSize, sizeof(uint32_t));
|
||||
ofs.write((char*)&e.second.nFileOffset, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
// 2) Write Data
|
||||
std::streampos offset = ofs.tellp();
|
||||
for (auto &e : mapFiles)
|
||||
{
|
||||
e.second.nFileOffset = offset;
|
||||
ofs.write((char*)e.second.data, e.second.nFileSize);
|
||||
offset += e.second.nFileSize;
|
||||
}
|
||||
|
||||
// 3) Rewrite Map (it has been updated with offsets now)
|
||||
ofs.seekp(std::ios::beg);
|
||||
ofs.write((char*)&nMapSize, sizeof(size_t));
|
||||
for (auto &e : mapFiles)
|
||||
{
|
||||
size_t nPathSize = e.first.size();
|
||||
ofs.write((char*)&nPathSize, sizeof(size_t));
|
||||
ofs.write(e.first.c_str(), nPathSize);
|
||||
ofs.write((char*)&e.second.nID, sizeof(uint32_t));
|
||||
ofs.write((char*)&e.second.nFileSize, sizeof(uint32_t));
|
||||
ofs.write((char*)&e.second.nFileOffset, sizeof(uint32_t));
|
||||
}
|
||||
ofs.close();
|
||||
|
||||
return olc::OK;
|
||||
}
|
||||
|
||||
olc::rcode ResourcePack::LoadPack(std::string sFile)
|
||||
{
|
||||
std::ifstream ifs(sFile, std::ifstream::binary);
|
||||
if (!ifs.is_open()) return olc::FAIL;
|
||||
|
||||
// 1) Read Map
|
||||
size_t nMapEntries;
|
||||
ifs.read((char*)&nMapEntries, sizeof(size_t));
|
||||
for (size_t i = 0; i < nMapEntries; i++)
|
||||
{
|
||||
size_t nFilePathSize = 0;
|
||||
ifs.read((char*)&nFilePathSize, sizeof(size_t));
|
||||
|
||||
std::string sFileName(nFilePathSize, ' ');
|
||||
for (size_t j = 0; j < nFilePathSize; j++)
|
||||
sFileName[j] = ifs.get();
|
||||
|
||||
sEntry e;
|
||||
e.data = nullptr;
|
||||
ifs.read((char*)&e.nID, sizeof(uint32_t));
|
||||
ifs.read((char*)&e.nFileSize, sizeof(uint32_t));
|
||||
ifs.read((char*)&e.nFileOffset, sizeof(uint32_t));
|
||||
mapFiles[sFileName] = e;
|
||||
}
|
||||
|
||||
// 2) Read Data
|
||||
for (auto &e : mapFiles)
|
||||
{
|
||||
e.second.data = new uint8_t[e.second.nFileSize];
|
||||
ifs.seekg(e.second.nFileOffset);
|
||||
ifs.read((char*)e.second.data, e.second.nFileSize);
|
||||
//e.second.setg
|
||||
e.second._config();
|
||||
//e.second.pubsetbuf((char*)e.second.data, e.second.nFileSize);
|
||||
}
|
||||
|
||||
ifs.close();
|
||||
return olc::OK;
|
||||
}
|
||||
|
||||
olc::ResourcePack::sEntry ResourcePack::GetStreamBuffer(std::string sFile)
|
||||
{
|
||||
return mapFiles[sFile];
|
||||
}
|
||||
|
||||
olc::rcode ResourcePack::ClearPack()
|
||||
{
|
||||
for (auto &e : mapFiles)
|
||||
{
|
||||
if (e.second.data != nullptr)
|
||||
delete[] e.second.data;
|
||||
}
|
||||
|
||||
mapFiles.clear();
|
||||
return olc::OK;
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
|
||||
PixelGameEngine::PixelGameEngine()
|
||||
{
|
||||
sAppName = "Undefined";
|
||||
|
Loading…
x
Reference in New Issue
Block a user