|
|
|
@ -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"; |
|
|
|
|