diff --git a/src/dawn/asset/AssetManager.hpp b/src/dawn/asset/AssetManager.hpp index 4717db15..97af6170 100644 --- a/src/dawn/asset/AssetManager.hpp +++ b/src/dawn/asset/AssetManager.hpp @@ -7,6 +7,10 @@ #include "Asset.hpp" #include "util/array.hpp" +#include "assets/TextureAsset.hpp" +#include "assets/TilesetAsset.hpp" +#include "assets/TrueTypeAsset.hpp" + namespace Dawn { class AssetManager { private: diff --git a/src/dawn/asset/assets/CMakeLists.txt b/src/dawn/asset/assets/CMakeLists.txt index 0019338d..0f57218e 100644 --- a/src/dawn/asset/assets/CMakeLists.txt +++ b/src/dawn/asset/assets/CMakeLists.txt @@ -7,5 +7,6 @@ target_sources(${DAWN_TARGET_NAME} PRIVATE TextureAsset.cpp + TilesetAsset.cpp TrueTypeAsset.cpp ) \ No newline at end of file diff --git a/src/dawn/asset/assets/TilesetAsset.cpp b/src/dawn/asset/assets/TilesetAsset.cpp new file mode 100644 index 00000000..77ebbeef --- /dev/null +++ b/src/dawn/asset/assets/TilesetAsset.cpp @@ -0,0 +1,87 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "TilesetAsset.hpp" + +using namespace Dawn; + +TilesetAsset::TilesetAsset(AssetManager *assMan, std::string name) : + Asset(assMan, name), + loader(name + ".tileset"), + tileset() +{ +} + +void TilesetAsset::updateSync() { + +} + +void TilesetAsset::updateAsync() { + uint8_t *buffer; + assertTrue(this->state == 0x00); + + this->state = 0x01; + this->loader.loadRaw(&buffer); + this->state = 0x02; + + char *strCurrent = (char *)buffer; + char *strNext, *strSubCurrent; + + // Read cols and rows + strNext = strchr(strCurrent, '|'); + *strNext = '\0'; + this->tileset.columns = atoi(strCurrent); + this->state = 0x03; + assertTrue(this->tileset.columns > 0); + + strCurrent = strNext+1; + strNext = strchr(strCurrent, '|'); + *strNext = '\0'; + this->tileset.rows = atoi(strCurrent); + this->state = 0x04; + assertTrue(this->tileset.rows > 0); + + // Begin reading tiles. + int32_t done = 0; + int32_t count = this->tileset.columns * this->tileset.rows; + while(done < count) { + struct Tile tile; + + strCurrent = strNext+1; + strNext = strchr(strCurrent, '|'); + + // Parse ux0 + strSubCurrent = strchr(strCurrent, ','); + *strSubCurrent = '\0'; + tile.uv0.x = atof(strCurrent); + + // Parse ux1 + strCurrent = strSubCurrent+1; + strSubCurrent = strchr(strCurrent, ','); + *strSubCurrent = '\0'; + tile.uv1.x = atof(strCurrent); + + // Parse uy0 + strCurrent = strSubCurrent+1; + strSubCurrent = strchr(strCurrent, ','); + *strSubCurrent = '\0'; + tile.uv0.y = atof(strCurrent); + + // Parse uy1 + strCurrent = strSubCurrent+1; + *strNext = '\0'; + tile.uv1.y = atof(strCurrent); + + // Next. + this->tileset.tiles.push_back(tile); + done++; + } + + this->state = 0x05; + this->loaded = true; + this->eventLoaded.invoke(); + + memoryFree(buffer); +} \ No newline at end of file diff --git a/src/dawn/asset/assets/TilesetAsset.hpp b/src/dawn/asset/assets/TilesetAsset.hpp new file mode 100644 index 00000000..1d36f6d0 --- /dev/null +++ b/src/dawn/asset/assets/TilesetAsset.hpp @@ -0,0 +1,25 @@ +// 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/Tileset.hpp" + +namespace Dawn { + class TilesetAsset : public Asset { + protected: + AssetLoader loader; + uint8_t state = 0x00; + + public: + struct TilesetGrid tileset; + + TilesetAsset(AssetManager *assMan, std::string name); + + void updateSync() override; + void updateAsync() override; + }; +} \ No newline at end of file diff --git a/src/dawn/display/Tileset.hpp b/src/dawn/display/Tileset.hpp index 8dfcd6a4..cd824a84 100644 --- a/src/dawn/display/Tileset.hpp +++ b/src/dawn/display/Tileset.hpp @@ -22,6 +22,10 @@ namespace Dawn { public: int32_t rows; int32_t columns; + + TilesetGrid() { + + } TilesetGrid( int32_t columns, diff --git a/src/dawnpokergame/CMakeLists.txt b/src/dawnpokergame/CMakeLists.txt index 8748c81a..96d4758b 100644 --- a/src/dawnpokergame/CMakeLists.txt +++ b/src/dawnpokergame/CMakeLists.txt @@ -23,7 +23,8 @@ add_subdirectory(visualnovel) # Assets tool_texture(texture_test texture_test.png) -tool_texture(texture_penny characters/penny/penny-blink.png) +# tool_texture(texture_penny characters/penny/penny-blink.png) +tool_tileset(tileset_penny texture_penny characters/penny/penny-blink.png 1 22) tool_truetype(truetype_ark ark-pixel.ttf truetype_ark @@ -34,6 +35,6 @@ tool_truetype(truetype_ark add_dependencies(${DAWN_TARGET_NAME} texture_test - texture_penny + tileset_penny truetype_ark ) \ No newline at end of file diff --git a/src/dawnpokergame/prefabs/VNPenny.hpp b/src/dawnpokergame/prefabs/VNPenny.hpp index 017fbca5..532f3df5 100644 --- a/src/dawnpokergame/prefabs/VNPenny.hpp +++ b/src/dawnpokergame/prefabs/VNPenny.hpp @@ -5,7 +5,6 @@ #pragma once #include "asset/AssetManager.hpp" -#include "asset/Asset.hpp" #include "poker/PokerPlayer.hpp" #include "scene/components/Components.hpp" @@ -14,7 +13,8 @@ namespace Dawn { public: static std::vector getAssets(AssetManager *assMan) { return std::vector{ - assMan->get("texture_penny") + assMan->get("texture_penny"), + assMan->get("tileset_penny") }; } diff --git a/src/dawntools/display/CMakeLists.txt b/src/dawntools/display/CMakeLists.txt index 2d84111d..ff695679 100644 --- a/src/dawntools/display/CMakeLists.txt +++ b/src/dawntools/display/CMakeLists.txt @@ -4,6 +4,7 @@ # https://opensource.org/licenses/MIT add_subdirectory(texturegen) +add_subdirectory(tilesetgen) add_subdirectory(truetypegen) # Texture Tool @@ -15,6 +16,16 @@ function(tool_texture target in) ) endfunction() +# Tileset Tool +function(tool_tileset targetTileset targetTexture in cols rows) + tool_texture(${targetTexture} ${in}) + add_custom_target(${targetTileset} + COMMAND tilesetgen "${DAWN_ASSETS_SOURCE_DIR}/${in}" "${DAWN_ASSETS_BUILD_DIR}/${targetTileset}" "${cols}" "${rows}" + COMMENT "Generating tileset ${target} from ${in}" + DEPENDS tilesetgen ${targetTexture} + ) +endfunction() + # TrueType Tool function(tool_truetype target in out width height fontSize) add_custom_target(${target} diff --git a/src/dawntools/display/tilesetgen/CMakeLists.txt b/src/dawntools/display/tilesetgen/CMakeLists.txt new file mode 100644 index 00000000..3b502e77 --- /dev/null +++ b/src/dawntools/display/tilesetgen/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (c) 2021 Dominic Msters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Texture Build Tool +project(tilesetgen VERSION 1.0) +add_executable(tilesetgen) +target_sources(tilesetgen + PRIVATE + main.c + ../../utils/file.c + ../../utils/image.c +) +target_include_directories(tilesetgen + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/../../ + ${CMAKE_CURRENT_LIST_DIR} +) +target_link_libraries(tilesetgen + PUBLIC + ${DAWN_BUILD_HOST_LIBS} + stb +) \ No newline at end of file diff --git a/src/dawntools/display/tilesetgen/main.c b/src/dawntools/display/tilesetgen/main.c new file mode 100644 index 00000000..f3a79152 --- /dev/null +++ b/src/dawntools/display/tilesetgen/main.c @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2022 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "../../utils/common.h" +#include "../../utils/file.h" +#include "../../utils/image.h" + +int main(int argc, char *argv[]) { + char *in; + char *out; + FILE *file; + char path[FILENAME_MAX + 1]; + int w, h, channels, cols, rows; + stbi_uc *dataImageRaw; + int gapX, gapY, borderX, borderY; + + if(argc < 5) { + printf("Invalid number of arguments"); + return 1; + } + + in = argv[1]; + out = argv[2]; + gapX = 0, gapY = 0, borderX = 0, borderY = 0; + + cols = atoi(argv[3]); + if(cols <= 0) { + printf("Columns is invalid\n"); + return 1; + } + + rows = atoi(argv[4]); + if(rows <= 0) { + printf("Rows is invalid"); + return 1; + } + + if(argc >= 6) { + gapX = atoi(argv[5]); + if(gapX <= 0) { + printf("Gap X is invalid\n"); + return 1; + } + } + + if(argc >= 7) { + gapY = atoi(argv[6]); + if(gapY <= 0) { + printf("Gap Y is invalid\n"); + return 1; + } + } + + if(argc >= 8) { + borderX = atoi(argv[7]); + if(borderX <= 0) { + printf("Border X is invalid\n"); + return 1; + } + } + + if(argc >= 9) { + borderY = atoi(argv[8]); + if(borderY <= 0) { + printf("Border Y is invalid\n"); + return 1; + } + } + + // Normalize slashes + fileNormalizeSlashes(in); + fileNormalizeSlashes(out); + + // Check the output doesn't already exist + sprintf(path, "%s.tileset", out); + file = fopen(path, "rb"); + if(file != NULL) { + fclose(file); + return 0; + } + + // Read in the original texture + file = fopen(in, "rb"); + if(file == NULL) { + printf("Failed to open file!\n"); + return 1; + } + + // Read image data + dataImageRaw = stbi_load_from_file(file, &w, &h, &channels, STBI_rgb_alpha); + if(dataImageRaw == NULL) { + printf("Failed to load input texture!\n"); + return 1; + } + fclose(file); + free(dataImageRaw); + + if(w <= 0 || h <= 0) { + printf("Reading image failed (corrupted?)\n"); + return 1; + } + + // Calculate division sizes (pixels) + float divX = ( + (float)w - ((float)borderX * 2.0f) - + ((float)gapX * ((float)cols - 1)) + ) / cols; + float divY = ( + (float)h - ((float)borderY * 2.0f) - + ((float)gapY * ((float)rows - 1)) + ) / rows; + + // Calculate the division sizes (units) + float tdivX = divX / (float)w; + float tdivY = divY / (float)h; + + // Output buffer prep + char *buffer = malloc(sizeof(char) * (cols * rows * 48 + 48 + 48)); + buffer[0] = '\0'; + + sprintf(buffer, "%i|%i|", cols, rows); + + // Now prep tileset. + for(int y = 0; y < rows; y++) { + for(int x = 0; x < cols; x++) { + float ux0 = (borderX + (divX * x) + (gapX * x)) / w; + float ux1 = ux0 + tdivX; + float uy0 = (borderY + (divY * y) + (gapY * y)) / h; + float uy1 = uy0 + tdivY; + sprintf(buffer, "%s%f,%f,%f,%f|", buffer, ux0, ux1, uy0, uy1); + } + } + + // Open output file + fileMkdirp(path); + file = fopen(path, "wb"); + if(file == NULL) { + free(buffer); + printf("Invalid tileset file out!\n"); + return 1; + } + + // Write and close + fwrite(buffer, sizeof(char), strlen(buffer), file); + fclose(file); + free(buffer); + + return 0; +} \ No newline at end of file