Added texture, assets, tools and texture loading.
This commit is contained in:
18
src/dawn/asset/Asset.cpp
Normal file
18
src/dawn/asset/Asset.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Asset::Asset(AssetManager &assetManager, std::string name) :
|
||||
assetManager(assetManager)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
Asset::~Asset() {
|
||||
this->loaded = false;
|
||||
}
|
46
src/dawn/asset/Asset.hpp
Normal file
46
src/dawn/asset/Asset.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager;
|
||||
|
||||
class Asset {
|
||||
public:
|
||||
AssetManager &assetManager;
|
||||
std::string name;
|
||||
uint8_t state = 0x00;
|
||||
bool loaded = false;
|
||||
|
||||
/**
|
||||
* Create an abstract Asset object.
|
||||
*
|
||||
* @param assetManager Asset manager that this asset belongs to.
|
||||
* @param name Name of the asset.
|
||||
*/
|
||||
Asset(AssetManager &assetManager, std::string name);
|
||||
|
||||
/**
|
||||
* Virtual function that will be called by the asset manager on a
|
||||
* synchronous basis. This will only trigger if the blocks are false and
|
||||
* the loaded is also false.
|
||||
*/
|
||||
virtual void updateSync() = 0;
|
||||
|
||||
/**
|
||||
* Virtual function called by the asset manager asynchronously every tick.
|
||||
* This will only trigger if blocks are false and the loaded state is also
|
||||
* false.
|
||||
*/
|
||||
virtual void updateAsync() = 0;
|
||||
|
||||
/**
|
||||
* Dispose the asset item.
|
||||
*/
|
||||
virtual ~Asset();
|
||||
};
|
||||
}
|
87
src/dawn/asset/AssetLoader.cpp
Normal file
87
src/dawn/asset/AssetLoader.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetLoader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
AssetLoader::AssetLoader(std::string fileName) {
|
||||
this->fileName = fileName;
|
||||
this->handle = nullptr;
|
||||
}
|
||||
|
||||
void AssetLoader::open() {
|
||||
std::string pathFull = DAWN_ASSET_BUILD_PREFIX + this->fileName;
|
||||
this->handle = fopen(pathFull.c_str(), "rb");
|
||||
if(this->handle == NULL || this->handle == nullptr) {
|
||||
throw "Failed to open file handle for " + this->fileName;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t AssetLoader::close() {
|
||||
int32_t ret = fclose(this->handle);
|
||||
this->handle = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t AssetLoader::read(uint8_t *buffer, size_t size) {
|
||||
return fread(buffer, 1, size, this->handle);
|
||||
}
|
||||
|
||||
int32_t AssetLoader::end() {
|
||||
return fseek(this->handle, 0, SEEK_END);
|
||||
}
|
||||
|
||||
size_t AssetLoader::skip(size_t n) {
|
||||
return fseek(this->handle, n, SEEK_CUR);
|
||||
}
|
||||
|
||||
int32_t AssetLoader::rewind() {
|
||||
return fseek(this->handle, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
size_t AssetLoader::getPosition() {
|
||||
return ftell(this->handle);
|
||||
}
|
||||
|
||||
size_t AssetLoader::loadRaw(uint8_t **buffer) {
|
||||
size_t length, read;
|
||||
|
||||
// Open a buffer.
|
||||
this->open();
|
||||
|
||||
// Read the count of bytes in the file
|
||||
this->end();
|
||||
length = this->getPosition();
|
||||
|
||||
// Are we only reading the size?
|
||||
if(buffer == nullptr) {
|
||||
this->close();
|
||||
return length;
|
||||
}
|
||||
|
||||
// Reset to start
|
||||
this->rewind();
|
||||
|
||||
// Read the string then close the file handle.
|
||||
*buffer = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * length));
|
||||
read = this->read(*buffer, length);
|
||||
this->close();
|
||||
|
||||
// Did we read successfully?
|
||||
if(read < length) {
|
||||
throw "Failed to read all bytes of " + this->fileName;
|
||||
}
|
||||
|
||||
// Read successfully, return the read bytes.
|
||||
return read;
|
||||
}
|
||||
|
||||
AssetLoader::~AssetLoader() {
|
||||
if(this->handle != nullptr) {
|
||||
this->close();
|
||||
this->handle = nullptr;
|
||||
}
|
||||
}
|
126
src/dawn/asset/AssetLoader.hpp
Normal file
126
src/dawn/asset/AssetLoader.hpp
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "util/memory.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetLoader {
|
||||
private:
|
||||
std::string fileName;
|
||||
FILE *handle;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a new asset loader. Asset Loaders can be used to load data from
|
||||
* a file in a myriad of ways.
|
||||
*
|
||||
* @param fileName File name of the asset that is to be loaded.
|
||||
*/
|
||||
AssetLoader(std::string fileName);
|
||||
|
||||
/**
|
||||
* Platform-centric method to open a file buffer to an asset.
|
||||
*
|
||||
* @return 0 if success, otherwise for failure.
|
||||
*/
|
||||
void open();
|
||||
|
||||
/**
|
||||
* Closes the previously ppened asset.
|
||||
* @return 0 if successful, otherwise false.
|
||||
*/
|
||||
int32_t close();
|
||||
|
||||
/**
|
||||
* Read bytes from buffer.
|
||||
* @param buffer Pointer to a ubyte array to buffer data into.
|
||||
* @param size Length of the data buffer (How many bytes to read).
|
||||
* @return The count of bytes read.
|
||||
*/
|
||||
size_t read(uint8_t *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Skip to the end of the buffer, useful to find the length of the buffer.
|
||||
* @return 0 if successful, otherwise false.
|
||||
*/
|
||||
int32_t end();
|
||||
|
||||
/**
|
||||
* Method to skip n bytes in the buffer
|
||||
* @param n Count of bytes to skip.
|
||||
* @return 0 if successful, otherwise unsuccessful.
|
||||
*/
|
||||
size_t skip(size_t n);
|
||||
|
||||
/**
|
||||
* Rewinds to the start of the asset buffer.
|
||||
* @return 0 if successful, otherwise unsuccessful.
|
||||
*/
|
||||
int32_t rewind();
|
||||
|
||||
|
||||
/**
|
||||
* Retreive the current byte position within the asset that the head is
|
||||
* at.
|
||||
* @return Position (in bytes) that the current seek is at.
|
||||
*/
|
||||
size_t getPosition();
|
||||
|
||||
/**
|
||||
* Loads the entire file into a raw buffer.
|
||||
* @param buffer Pointer to where a pointer to the buffer will be stored.
|
||||
* @return Size of the buffer that was read (in bytes).
|
||||
*/
|
||||
size_t loadRaw(uint8_t **buffer);
|
||||
|
||||
/**
|
||||
* Run a callback for each byte within the asset. The callback will
|
||||
* receive each byte individually.
|
||||
*
|
||||
* @tparam T Type of instance to run callback against.
|
||||
* @param instance Instance of the object to run the callback against.
|
||||
* @param callback Callback method on the class to run the callback for.
|
||||
* @return The count of bytes read.
|
||||
*/
|
||||
template<class T>
|
||||
size_t loadBufferedCallback(T *instance, bool (T::*callback)(uint8_t n)) {
|
||||
uint8_t buffer[1024];
|
||||
size_t read, length;
|
||||
int32_t i;
|
||||
bool result;
|
||||
|
||||
// Open the buffer.
|
||||
this->open();
|
||||
|
||||
// Reset length size
|
||||
length = 0;
|
||||
|
||||
// Buffer from input
|
||||
while((read = this->read(buffer, 1024)) != 0) {
|
||||
for(i = 0; i < read; i++) {
|
||||
result = ((*instance).*(callback))(buffer[i]);
|
||||
if(!result) {
|
||||
length += i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!result) break;
|
||||
length += read;
|
||||
}
|
||||
|
||||
// Close the buffer
|
||||
this->close();
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup the asset loader.
|
||||
*/
|
||||
virtual ~AssetLoader();
|
||||
};
|
||||
}
|
37
src/dawn/asset/AssetManager.cpp
Normal file
37
src/dawn/asset/AssetManager.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
|
||||
#if !defined(DAWN_ASSET_BUILD_PREFIX)
|
||||
#error Asset Prefix has not been defined.
|
||||
#endif
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void AssetManager::init() {
|
||||
|
||||
}
|
||||
|
||||
void AssetManager::update() {
|
||||
auto it = this->assetsNotLoaded.begin();
|
||||
while(it != this->assetsNotLoaded.end()) {
|
||||
auto asset = it->second;
|
||||
if(asset->loaded) {
|
||||
it = this->assetsNotLoaded.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
asset->updateSync();
|
||||
asset->updateAsync();
|
||||
|
||||
if(asset->loaded) {
|
||||
it = this->assetsNotLoaded.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
38
src/dawn/asset/AssetManager.hpp
Normal file
38
src/dawn/asset/AssetManager.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "asset/Asset.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager {
|
||||
private:
|
||||
/** List of pointers to assets, mapped by their asset key. */
|
||||
std::map<std::string, std::shared_ptr<Asset>> assets;
|
||||
std::map<std::string, std::shared_ptr<Asset>> assetsNotLoaded;
|
||||
|
||||
public:
|
||||
void init();
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Creates and queue an asset to load.
|
||||
*
|
||||
* @param name Name of the asset to load.
|
||||
* @return The asset element to be loaded.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> load(std::string name) {
|
||||
auto existing = this->assets.find(name);
|
||||
if(existing != this->assets.end()) {
|
||||
return std::dynamic_pointer_cast<T>(existing->second);
|
||||
}
|
||||
auto asset = std::make_shared<T>(*this, name);
|
||||
this->assets[name] = asset;
|
||||
this->assetsNotLoaded[name] = asset;
|
||||
return asset;
|
||||
}
|
||||
};
|
||||
}
|
15
src/dawn/asset/CMakeLists.txt
Normal file
15
src/dawn/asset/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2022 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Asset.cpp
|
||||
AssetLoader.cpp
|
||||
AssetManager.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(assets)
|
10
src/dawn/asset/assets/CMakeLists.txt
Normal file
10
src/dawn/asset/assets/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2022 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
TextureAsset.cpp
|
||||
)
|
62
src/dawn/asset/assets/TextureAsset.cpp
Normal file
62
src/dawn/asset/assets/TextureAsset.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TextureAsset.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TextureAsset::TextureAsset(AssetManager &assetManager, std::string name) :
|
||||
Asset(assetManager, name),
|
||||
loader(name + ".texture")
|
||||
{
|
||||
this->texture = std::make_shared<Texture>();
|
||||
}
|
||||
|
||||
void TextureAsset::updateSync() {
|
||||
if(this->state == 0x00 || this->state == 0x01) return;
|
||||
|
||||
this->state = 0x03;
|
||||
this->texture->setSize(this->width, this->height);
|
||||
this->texture->buffer(this->colors);
|
||||
this->state = 0x04;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
void TextureAsset::updateAsync() {
|
||||
if(this->state != 0x00) return;
|
||||
this->loader.loadRaw(&this->buffer);
|
||||
|
||||
this->state = 0x01;
|
||||
|
||||
// Parse header data.
|
||||
char integer[32];
|
||||
size_t j = 0, i = 0;
|
||||
while(true) {
|
||||
auto c = this->buffer[i++];
|
||||
if(c == '|') {
|
||||
integer[j] = '\0';
|
||||
if(this->width == -1) {
|
||||
this->width = atoi(integer);
|
||||
if(this->width <= 0) throw "Invalid width";
|
||||
j = 0;
|
||||
continue;
|
||||
} else {
|
||||
this->height = atoi(integer);
|
||||
if(this->height <= 0) throw "Invalid height";
|
||||
break;
|
||||
}
|
||||
}
|
||||
integer[j++] = c;
|
||||
}
|
||||
|
||||
this->colors = (struct Color *)((void *)(this->buffer + i));
|
||||
this->state = 0x02;
|
||||
}
|
||||
|
||||
TextureAsset::~TextureAsset() {
|
||||
if(this->buffer != nullptr) {
|
||||
memoryFree(this->buffer);
|
||||
}
|
||||
}
|
29
src/dawn/asset/assets/TextureAsset.hpp
Normal file
29
src/dawn/asset/assets/TextureAsset.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TextureAsset : public Asset {
|
||||
protected:
|
||||
AssetLoader loader;
|
||||
uint8_t *buffer = nullptr;
|
||||
int32_t width = -1, height = -1;
|
||||
struct Color *colors;
|
||||
|
||||
public:
|
||||
std::shared_ptr<Texture> texture;
|
||||
|
||||
TextureAsset(AssetManager &assetManager, std::string name);
|
||||
|
||||
void updateSync() override;
|
||||
void updateAsync() override;
|
||||
|
||||
~TextureAsset();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user