Added V1.11

Contains ResourcePacks for storing image and sound data in a virtual file system
pull/113/head
Javidx9 6 years ago committed by GitHub
parent 786b33b950
commit 3489f28fcb
  1. 233
      olcPixelGameEngine.h

@ -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…
Cancel
Save