Added texture, assets, tools and texture loading.

This commit is contained in:
2022-10-20 21:50:52 -07:00
parent 80d6cba854
commit 043873cc2d
38 changed files with 1626 additions and 15 deletions

View File

@ -16,5 +16,6 @@ target_include_directories(${DAWN_TARGET_NAME}
)
# Subdirs
add_subdirectory(asset)
add_subdirectory(display)
add_subdirectory(scene)

18
src/dawn/asset/Asset.cpp Normal file
View 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
View 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();
};
}

View 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;
}
}

View 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();
};
}

View 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;
}
}

View 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;
}
};
}

View 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)

View 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
)

View 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);
}
}

View 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();
};
}

View File

@ -7,6 +7,7 @@
#include "dawnlibs.hpp"
#include "scene/Scene.hpp"
#include "display/RenderManager.hpp"
#include "asset/AssetManager.hpp"
#define DAWN_GAME_INIT_RESULT_SUCCESS 0
#define DAWN_GAME_UPDATE_RESULT_SUCCESS 0
@ -20,6 +21,7 @@ namespace Dawn {
std::shared_ptr<Scene> scene;
DawnHost &host;
RenderManager renderManager;
AssetManager assetManager;
/**
* Construct a new instance of the DawnGame.