Tool refactoring

This commit is contained in:
2023-03-22 18:54:22 -07:00
parent f267131d6b
commit 9e2f093527
41 changed files with 1871 additions and 1664 deletions

5
.gitignore vendored
View File

@ -82,6 +82,5 @@ assets/borrowed
.vscode* .vscode*
.VSCode* .VSCode*
/vita/* /vita
/tools/* /tools
./tools/*

View File

@ -6,7 +6,7 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")

View File

@ -1,125 +1,125 @@
# Copyright (c) 2023 Dominic Msters # Copyright (c) 2023 Dominic Msters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
add_subdirectory(texturegen) add_subdirectory(texturegen)
add_subdirectory(tilesetgen) add_subdirectory(tilesetgen)
add_subdirectory(truetypegen) add_subdirectory(truetypegen)
add_subdirectory(languagegen) add_subdirectory(languagegen)
add_subdirectory(generatedlanguages) add_subdirectory(generatedlanguages)
# Settings # Settings
set(DAWN_TOOL_GENERATED_LANG_DIR "${DAWN_TEMP_DIR}/languages" CACHE INTERNAL ${DAWN_CACHE_TARGET}) set(DAWN_TOOL_GENERATED_LANG_DIR "${DAWN_TEMP_DIR}/languages" CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_SCENE_ITEM_COMPONENT_LIST "" CACHE INTERNAL ${DAWN_CACHE_TARGET}) set(DAWN_SCENE_ITEM_COMPONENT_LIST "" CACHE INTERNAL ${DAWN_CACHE_TARGET})
# Texture Tool # Texture Tool
function(tool_texture target in) function(tool_texture target in)
add_custom_target(${target} add_custom_target(${target}
COMMAND texturegen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_ASSETS_BUILD_DIR}/${target}" COMMAND texturegen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_ASSETS_BUILD_DIR}/${target}"
COMMENT "Generating texture ${target} from ${in}" COMMENT "Generating texture ${target} from ${in}"
DEPENDS texturegen DEPENDS texturegen
) )
add_dependencies(${DAWN_TARGET_NAME} ${target}) add_dependencies(${DAWN_TARGET_NAME} ${target})
endfunction() endfunction()
# Tileset Tool # Tileset Tool
function(tool_tileset targetTileset targetTexture in cols rows) function(tool_tileset targetTileset targetTexture in cols rows)
tool_texture(${targetTexture} ${in}) tool_texture(${targetTexture} ${in})
add_custom_target(${targetTileset} add_custom_target(${targetTileset}
COMMAND tilesetgen "${DAWN_ASSETS_SOURCE_DIR}/${in}" "${DAWN_ASSETS_BUILD_DIR}/${targetTileset}" "${cols}" "${rows}" COMMAND tilesetgen "${DAWN_ASSETS_SOURCE_DIR}/${in}" "${DAWN_ASSETS_BUILD_DIR}/${targetTileset}" "${cols}" "${rows}"
COMMENT "Generating tileset ${target} from ${in}" COMMENT "Generating tileset ${target} from ${in}"
DEPENDS tilesetgen ${targetTexture} DEPENDS tilesetgen ${targetTexture}
) )
add_dependencies(${DAWN_TARGET_NAME} ${targetTileset}) add_dependencies(${DAWN_TARGET_NAME} ${targetTileset})
endfunction() endfunction()
# Bitmap Font # Bitmap Font
function(tool_bitmapfont target in columns rows) function(tool_bitmapfont target in columns rows)
tool_tileset(${target}_tileset ${target}_texture ${in} ${columns} ${rows}) tool_tileset(${target}_tileset ${target}_texture ${in} ${columns} ${rows})
endfunction() endfunction()
# TrueType Tool # TrueType Tool
function(tool_truetype target in out width height fontSize) function(tool_truetype target in out width height fontSize)
add_custom_target(${target} add_custom_target(${target}
COMMAND truetypegen "${DAWN_ASSETS_SOURCE_DIR}/${in}" "${DAWN_ASSETS_BUILD_DIR}/${out}" "${width}" "${height}" "${fontSize}" COMMAND truetypegen "${DAWN_ASSETS_SOURCE_DIR}/${in}" "${DAWN_ASSETS_BUILD_DIR}/${out}" "${width}" "${height}" "${fontSize}"
COMMENT "Generating truetype ${target} from ${in}" COMMENT "Generating truetype ${target} from ${in}"
DEPENDS truetypegen DEPENDS truetypegen
) )
add_dependencies(${DAWN_TARGET_NAME} ${target}) add_dependencies(${DAWN_TARGET_NAME} ${target})
endfunction() endfunction()
# UI Tool # UI Tool
function(tool_ui target in) function(tool_ui target in)
add_custom_target(${target} add_custom_target(${target}
COMMAND uigen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_GENERATED_DIR}/prefabs/ui/${target}" COMMAND uigen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_GENERATED_DIR}/prefabs/ui/${target}"
COMMENT "Generating UI ${target} from ${in}" COMMENT "Generating UI ${target} from ${in}"
DEPENDS uigen DEPENDS uigen
) )
target_include_directories(${DAWN_TARGET_NAME} target_include_directories(${DAWN_TARGET_NAME}
PUBLIC PUBLIC
${DAWN_GENERATED_DIR}/ui ${DAWN_GENERATED_DIR}/ui
) )
add_dependencies(${DAWN_TARGET_NAME} ${target}) add_dependencies(${DAWN_TARGET_NAME} ${target})
endfunction() endfunction()
# Generated Language Rollup Tool # Generated Language Rollup Tool
function(tool_generatedlanguages in) function(tool_generatedlanguages in)
add_custom_target(generatedlanguages add_custom_target(generatedlanguages
COMMAND generatedlanguagestool --input="${DAWN_TOOL_GENERATED_LANG_DIR}" --output="${DAWN_ASSETS_BUILD_DIR}" COMMAND generatedlanguagestool --input="${DAWN_TOOL_GENERATED_LANG_DIR}" --output="${DAWN_ASSETS_BUILD_DIR}"
COMMENT "Generating all languages" COMMENT "Generating all languages"
DEPENDS generatedlanguagestool DEPENDS generatedlanguagestool
) )
if(NOT generatedlanguages IN_LIST DAWN_TARGET_DEPENDENCIES_LAST) if(NOT generatedlanguages IN_LIST DAWN_TARGET_DEPENDENCIES_LAST)
set( set(
DAWN_TARGET_DEPENDENCIES_LAST DAWN_TARGET_DEPENDENCIES_LAST
generatedlanguages generatedlanguages
CACHE INTERNAL ${DAWN_CACHE_TARGET} CACHE INTERNAL ${DAWN_CACHE_TARGET}
) )
endif() endif()
endfunction() endfunction()
# Language Tool # Language Tool
function(tool_language target in) function(tool_language target in)
add_custom_target(${target} add_custom_target(${target}
COMMAND languagegen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language" COMMAND languagegen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language"
COMMENT "Generating language set ${target} from ${in}" COMMENT "Generating language set ${target} from ${in}"
DEPENDS languagegen DEPENDS languagegen
) )
tool_generatedlanguages("${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language") tool_generatedlanguages("${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language")
add_dependencies(${DAWN_TARGET_NAME} ${target}) add_dependencies(${DAWN_TARGET_NAME} ${target})
endfunction() endfunction()
# Audio Tool # Audio Tool
if(DAWN_TARGET_OPENAL) if(DAWN_TARGET_OPENAL)
add_subdirectory(audiogen) add_subdirectory(audiogen)
function(tool_audio target in) function(tool_audio target in)
add_custom_target(${target} add_custom_target(${target}
COMMAND audiogen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_ASSETS_BUILD_DIR}/${target}" COMMAND audiogen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_ASSETS_BUILD_DIR}/${target}"
COMMENT "Generating audio ${target} from ${in}" COMMENT "Generating audio ${target} from ${in}"
DEPENDS audiogen DEPENDS audiogen
) )
add_dependencies(${DAWN_TARGET_NAME} ${target}) add_dependencies(${DAWN_TARGET_NAME} ${target})
endfunction() endfunction()
endif() endif()
if(DAWN_VISUAL_NOVEL) if(DAWN_VISUAL_NOVEL)
add_subdirectory(vnscenegen) add_subdirectory(vnscenegen)
# VN Scene Tool # VN Scene Tool
function(tool_vnscene target in) function(tool_vnscene target in)
tool_generatedlanguages("${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language") tool_generatedlanguages("${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language")
add_custom_target(${target} add_custom_target(${target}
COMMAND vnscenegen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_GENERATED_DIR}/scenes/${target}" --language-out="${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language" COMMAND vnscenegen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_GENERATED_DIR}/scenes/${target}" --language-out="${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language"
COMMENT "Generating VN Scene ${target} from ${in}" COMMENT "Generating VN Scene ${target} from ${in}"
DEPENDS vnscenegen DEPENDS vnscenegen
) )
target_include_directories(${DAWN_TARGET_NAME} target_include_directories(${DAWN_TARGET_NAME}
PUBLIC PUBLIC
${DAWN_GENERATED_DIR} ${DAWN_GENERATED_DIR}
) )
add_dependencies(${DAWN_TARGET_NAME} ${target}) add_dependencies(${DAWN_TARGET_NAME} ${target})
endfunction() endfunction()
endif() endif()

View File

@ -1,38 +1,38 @@
# Copyright (c) 2023 Dominic Msters # Copyright (c) 2023 Dominic Msters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
project(audiogen VERSION 1.0) project(audiogen VERSION 1.0)
add_executable(audiogen) add_executable(audiogen)
# Sources # Sources
target_sources(audiogen target_sources(audiogen
PRIVATE PRIVATE
${DAWN_SHARED_SOURCES} ${DAWN_SHARED_SOURCES}
${DAWN_TOOL_SOURCES} ${DAWN_TOOL_SOURCES}
AudioGen.cpp AudioGen.cpp
) )
# Includes # Includes
target_include_directories(audiogen target_include_directories(audiogen
PUBLIC PUBLIC
${DAWN_SHARED_INCLUDES} ${DAWN_SHARED_INCLUDES}
${DAWN_TOOL_INCLUDES} ${DAWN_TOOL_INCLUDES}
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}
) )
# Definitions # Definitions
target_compile_definitions(audiogen target_compile_definitions(audiogen
PUBLIC PUBLIC
${DAWN_SHARED_DEFINITIONS} ${DAWN_SHARED_DEFINITIONS}
DAWN_TOOL_INSTANCE=AudioGen DAWN_TOOL_INSTANCE=AudioGen
DAWN_TOOL_HEADER="AudioGen.hpp" DAWN_TOOL_HEADER="AudioGen.hpp"
) )
# Libraries # Libraries
target_link_libraries(audiogen target_link_libraries(audiogen
PUBLIC PUBLIC
${DAWN_BUILD_HOST_LIBS} ${DAWN_BUILD_HOST_LIBS}
AudioFile AudioFile
) )

View File

@ -1,34 +1,34 @@
# Copyright (c) 2023 Dominic Msters # Copyright (c) 2023 Dominic Msters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Generated Languages Tool # Generated Languages Tool
project(generatedlanguagestool VERSION 1.0) project(generatedlanguagestool VERSION 1.0)
add_executable(generatedlanguagestool) add_executable(generatedlanguagestool)
target_sources(generatedlanguagestool target_sources(generatedlanguagestool
PRIVATE PRIVATE
${DAWN_SHARED_SOURCES} ${DAWN_SHARED_SOURCES}
${DAWN_TOOL_SOURCES} ${DAWN_TOOL_SOURCES}
GeneratedLanguages.cpp GeneratedLanguages.cpp
) )
target_include_directories(generatedlanguagestool target_include_directories(generatedlanguagestool
PUBLIC PUBLIC
${DAWN_SHARED_INCLUDES} ${DAWN_SHARED_INCLUDES}
${DAWN_TOOL_INCLUDES} ${DAWN_TOOL_INCLUDES}
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}
) )
target_compile_definitions(generatedlanguagestool target_compile_definitions(generatedlanguagestool
PUBLIC PUBLIC
${DAWN_SHARED_DEFINITIONS} ${DAWN_SHARED_DEFINITIONS}
DAWN_TOOL_INSTANCE=GeneratedLanguages DAWN_TOOL_INSTANCE=GeneratedLanguages
DAWN_TOOL_HEADER="GeneratedLanguages.hpp" DAWN_TOOL_HEADER="GeneratedLanguages.hpp"
) )
target_link_libraries(generatedlanguagestool target_link_libraries(generatedlanguagestool
PUBLIC PUBLIC
${DAWN_BUILD_HOST_LIBS} ${DAWN_BUILD_HOST_LIBS}
) )

View File

@ -1,141 +1,141 @@
/** /**
* Copyright (c) 2021 Dominic Masters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "GeneratedLanguages.hpp" #include "GeneratedLanguages.hpp"
using namespace Dawn; using namespace Dawn;
std::vector<std::string> GeneratedLanguages::getRequiredFlags() { std::vector<std::string> GeneratedLanguages::getRequiredFlags() {
return std::vector<std::string>{ "input", "output" }; return std::vector<std::string>{ "input", "output" };
} }
int32_t GeneratedLanguages::start() { int32_t GeneratedLanguages::start() {
// Generate list of languages // Generate list of languages
std::string inNormal = File::normalizeSlashes(flags["input"]); std::string inNormal = File::normalizeSlashes(flags["input"]);
std::string error; std::string error;
std::vector<std::string> files; std::vector<std::string> files;
int32_t ret = this->scanDir(inNormal, &error, &files); int32_t ret = this->scanDir(inNormal, &error, &files);
if(ret != 0) { if(ret != 0) {
std::cout << error << std::endl; std::cout << error << std::endl;
return ret; return ret;
} }
// Now process each language file // Now process each language file
std::map<std::string, std::map<std::string, std::string>> strings; std::map<std::string, std::map<std::string, std::string>> strings;
std::vector<std::string> knownKeys; std::vector<std::string> knownKeys;
auto itFiles = files.begin(); auto itFiles = files.begin();
while(itFiles != files.end()) { while(itFiles != files.end()) {
File file(*itFiles); File file(*itFiles);
file.open(FILE_MODE_READ); file.open(FILE_MODE_READ);
std::string buffer; std::string buffer;
size_t n = 0; size_t n = 0;
while(n < file.length) { while(n < file.length) {
char lang[32]; char lang[32];
char key[128]; char key[128];
char string[32178]; char string[32178];
// Read lang // Read lang
if(n != 0) file.setPosition(n); if(n != 0) file.setPosition(n);
auto langSize = file.readAhead(lang, 32, '|'); auto langSize = file.readAhead(lang, 32, '|');
lang[langSize] = '\0'; lang[langSize] = '\0';
n += langSize + 1; n += langSize + 1;
if(langSize <= 0) { if(langSize <= 0) {
std::cout << "Error reading language name: " << langSize << std::endl; std::cout << "Error reading language name: " << langSize << std::endl;
return 1; return 1;
} }
// Read Key // Read Key
file.setPosition(n); file.setPosition(n);
auto keySize = file.readAhead(key, 128, '|'); auto keySize = file.readAhead(key, 128, '|');
key[keySize] = '\0'; key[keySize] = '\0';
n += keySize + 1; n += keySize + 1;
if(keySize <= 0) { if(keySize <= 0) {
std::cout << "Error reading language key: " << keySize << std::endl; std::cout << "Error reading language key: " << keySize << std::endl;
return 1; return 1;
} }
// Read String // Read String
file.setPosition(n); file.setPosition(n);
auto stringSize = file.readAhead(string, 32178, '|'); auto stringSize = file.readAhead(string, 32178, '|');
string[stringSize] = '\0'; string[stringSize] = '\0';
n += stringSize + 1; n += stringSize + 1;
if(stringSize <= 0) { if(stringSize <= 0) {
std::cout << "Error reading language string: " << stringSize << std::endl; std::cout << "Error reading language string: " << stringSize << std::endl;
return 1; return 1;
} }
strings[lang][key] = string; strings[lang][key] = string;
auto exist = std::find(knownKeys.begin(), knownKeys.end(), key); auto exist = std::find(knownKeys.begin(), knownKeys.end(), key);
if(exist == knownKeys.end()) knownKeys.push_back(key); if(exist == knownKeys.end()) knownKeys.push_back(key);
} }
++itFiles; ++itFiles;
} }
// Now prepare output file // Now prepare output file
auto itLang = strings.begin(); auto itLang = strings.begin();
std::string bufferOut = ""; std::string bufferOut = "";
while(itLang != strings.end()) { while(itLang != strings.end()) {
File langOut(flags["output"] + FILE_PATH_SEP + "language_" + itLang->first + ".language"); File langOut(flags["output"] + FILE_PATH_SEP + "language_" + itLang->first + ".language");
bufferOut.clear(); bufferOut.clear();
auto itKeys = knownKeys.begin(); auto itKeys = knownKeys.begin();
while(itKeys != knownKeys.end()) { while(itKeys != knownKeys.end()) {
auto key = *itKeys; auto key = *itKeys;
auto exist = itLang->second.find(key); auto exist = itLang->second.find(key);
if(exist == itLang->second.end()) { if(exist == itLang->second.end()) {
std::cout << "Language " << itLang->first << " is missing key " << key << std::endl; std::cout << "Language " << itLang->first << " is missing key " << key << std::endl;
return 1; return 1;
} }
bufferOut += exist->first + "|" + exist->second + "|"; bufferOut += exist->first + "|" + exist->second + "|";
++itKeys; ++itKeys;
} }
// Write out. // Write out.
langOut.mkdirp(); langOut.mkdirp();
if(!langOut.writeString(bufferOut)) { if(!langOut.writeString(bufferOut)) {
std::cout << "Failed to create output file \"" + langOut.filename + "\"" << std::endl; std::cout << "Failed to create output file \"" + langOut.filename + "\"" << std::endl;
return 1; return 1;
} }
++itLang; ++itLang;
} }
return 0; return 0;
} }
int32_t GeneratedLanguages::scanDir( int32_t GeneratedLanguages::scanDir(
std::string dir, std::string dir,
std::string *error, std::string *error,
std::vector<std::string> *files std::vector<std::string> *files
) { ) {
DIR* handle = opendir(dir.c_str()); DIR* handle = opendir(dir.c_str());
if(ENOENT == errno) { if(ENOENT == errno) {
*error = "Input directory \"" + dir + "\" does not exist"; *error = "Input directory \"" + dir + "\" does not exist";
return 0; return 0;
} }
if(!handle) return 0; if(!handle) return 0;
struct dirent *entry; struct dirent *entry;
while((entry=readdir(handle))) { while((entry=readdir(handle))) {
std::string name(entry->d_name); std::string name(entry->d_name);
if(name.size() == 0 || name[0] == '.') continue; if(name.size() == 0 || name[0] == '.') continue;
auto path = dir + FILE_PATH_SEP + entry->d_name; auto path = dir + FILE_PATH_SEP + entry->d_name;
if(entry->d_type == DT_DIR) { if(entry->d_type == DT_DIR) {
auto ret = this->scanDir(dir, error, files); auto ret = this->scanDir(dir, error, files);
if(ret != 0) return ret; if(ret != 0) return ret;
} else if(entry->d_type == DT_REG) { } else if(entry->d_type == DT_REG) {
files->push_back(path); files->push_back(path);
} }
} }
closedir(handle); closedir(handle);
return 0; return 0;
} }

View File

@ -1,38 +1,38 @@
# Copyright (c) 2021 Dominic Msters # Copyright (c) 2021 Dominic Msters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Texture Build Tool # Texture Build Tool
project(languagegen VERSION 2.0) project(languagegen VERSION 2.0)
add_executable(languagegen) add_executable(languagegen)
# Sources # Sources
target_sources(languagegen target_sources(languagegen
PRIVATE PRIVATE
${DAWN_SHARED_SOURCES} ${DAWN_SHARED_SOURCES}
${DAWN_TOOL_SOURCES} ${DAWN_TOOL_SOURCES}
LanguageGen.cpp LanguageGen.cpp
) )
# Includes # Includes
target_include_directories(languagegen target_include_directories(languagegen
PUBLIC PUBLIC
${DAWN_SHARED_INCLUDES} ${DAWN_SHARED_INCLUDES}
${DAWN_TOOL_INCLUDES} ${DAWN_TOOL_INCLUDES}
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}
) )
# Definitions # Definitions
target_compile_definitions(languagegen target_compile_definitions(languagegen
PUBLIC PUBLIC
DAWN_TOOL_INSTANCE=LanguageGen DAWN_TOOL_INSTANCE=LanguageGen
DAWN_TOOL_HEADER="LanguageGen.hpp" DAWN_TOOL_HEADER="LanguageGen.hpp"
) )
# Libraries # Libraries
target_link_libraries(languagegen target_link_libraries(languagegen
PUBLIC PUBLIC
${DAWN_BUILD_HOST_LIBS} ${DAWN_BUILD_HOST_LIBS}
) )

View File

@ -1,152 +1,152 @@
/** /**
* Copyright (c) 2021 Dominic Masters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "LanguageGen.hpp" #include "LanguageGen.hpp"
using namespace Dawn; using namespace Dawn;
std::vector<std::string> LanguageParser::getRequiredAttributes() { std::vector<std::string> LanguageParser::getRequiredAttributes() {
return std::vector<std::string>{ "key" }; return std::vector<std::string>{ "key" };
} }
std::map<std::string, std::string> LanguageParser::getOptionalAttributes() { std::map<std::string, std::string> LanguageParser::getOptionalAttributes() {
return std::map<std::string, std::string>(); return std::map<std::string, std::string>();
} }
int32_t LanguageParser::onParse( int32_t LanguageParser::onParse(
Xml *node, Xml *node,
std::map<std::string, std::string> values, std::map<std::string, std::string> values,
struct LanguageString *out, struct LanguageString *out,
std::string *error std::string *error
) { ) {
out->key = values["key"]; out->key = values["key"];
out->text = node->value; out->text = node->value;
return 0; return 0;
} }
std::vector<std::string> LanguageGroupParser::getRequiredAttributes() { std::vector<std::string> LanguageGroupParser::getRequiredAttributes() {
return std::vector<std::string>{ "key" }; return std::vector<std::string>{ "key" };
} }
std::map<std::string, std::string> LanguageGroupParser::getOptionalAttributes() { std::map<std::string, std::string> LanguageGroupParser::getOptionalAttributes() {
return std::map<std::string, std::string>(); return std::map<std::string, std::string>();
} }
int32_t LanguageGroupParser::onParse( int32_t LanguageGroupParser::onParse(
Xml *node, Xml *node,
std::map<std::string, std::string> values, std::map<std::string, std::string> values,
struct LanguageGroup *out, struct LanguageGroup *out,
std::string *error std::string *error
) { ) {
std::string key = values["key"]; std::string key = values["key"];
out->key += key; out->key += key;
auto it = node->children.begin(); auto it = node->children.begin();
int32_t ret; int32_t ret;
while(it != node->children.end()) { while(it != node->children.end()) {
auto c = *it; auto c = *it;
if(c->node == "string") { if(c->node == "string") {
struct LanguageString string; struct LanguageString string;
ret = (LanguageParser()).parse(c, &string, error); ret = (LanguageParser()).parse(c, &string, error);
if(ret != 0) return ret; if(ret != 0) return ret;
string.lang = out->lang; string.lang = out->lang;
string.key = out->key + "." + string.key; string.key = out->key + "." + string.key;
out->strings.push_back(string); out->strings.push_back(string);
} else if(c->node == "group") { } else if(c->node == "group") {
struct LanguageGroup group; struct LanguageGroup group;
group.key += key + "."; group.key += key + ".";
group.lang = out->lang; group.lang = out->lang;
ret = (LanguageGroupParser()).parse(c, &group, error); ret = (LanguageGroupParser()).parse(c, &group, error);
if(ret != 0) return ret; if(ret != 0) return ret;
vectorAppend(&out->strings, group.strings); vectorAppend(&out->strings, group.strings);
} }
++it; ++it;
} }
return 0; return 0;
} }
std::vector<std::string> LanguageRootParser::getRequiredAttributes() { std::vector<std::string> LanguageRootParser::getRequiredAttributes() {
return std::vector<std::string>{ "lang" }; return std::vector<std::string>{ "lang" };
} }
std::map<std::string, std::string> LanguageRootParser::getOptionalAttributes() { std::map<std::string, std::string> LanguageRootParser::getOptionalAttributes() {
return std::map<std::string, std::string>(); return std::map<std::string, std::string>();
} }
int32_t LanguageRootParser::onParse( int32_t LanguageRootParser::onParse(
Xml *node, Xml *node,
std::map<std::string, std::string> values, std::map<std::string, std::string> values,
struct LanguageRoot *out, struct LanguageRoot *out,
std::string *error std::string *error
) { ) {
int32_t ret; int32_t ret;
out->lang = values["lang"]; out->lang = values["lang"];
auto it = node->children.begin(); auto it = node->children.begin();
while(it != node->children.end()) { while(it != node->children.end()) {
auto c = *it; auto c = *it;
if(c->node == "string") { if(c->node == "string") {
struct LanguageString string; struct LanguageString string;
ret = (LanguageParser()).parse(c, &string, error); ret = (LanguageParser()).parse(c, &string, error);
if(ret != 0) return ret; if(ret != 0) return ret;
string.lang = out->lang; string.lang = out->lang;
out->strings.push_back(string); out->strings.push_back(string);
} else if(c->node == "group") { } else if(c->node == "group") {
struct LanguageGroup group; struct LanguageGroup group;
group.lang = out->lang; group.lang = out->lang;
ret = (LanguageGroupParser()).parse(c, &group, error); ret = (LanguageGroupParser()).parse(c, &group, error);
if(ret != 0) return ret; if(ret != 0) return ret;
vectorAppend(&out->strings, group.strings); vectorAppend(&out->strings, group.strings);
} }
++it; ++it;
} }
return 0; return 0;
} }
std::vector<std::string> LanguageGen::getRequiredFlags() { std::vector<std::string> LanguageGen::getRequiredFlags() {
return std::vector<std::string>{ "input", "output" }; return std::vector<std::string>{ "input", "output" };
} }
int32_t LanguageGen::start() { int32_t LanguageGen::start() {
auto fileIn = File(flags["input"]); auto fileIn = File(flags["input"]);
std::string buffer; std::string buffer;
if(!fileIn.readString(&buffer)) { if(!fileIn.readString(&buffer)) {
std::cout << "Failed to open/read input file " << fileIn.filename << std::endl; std::cout << "Failed to open/read input file " << fileIn.filename << std::endl;
return 1; return 1;
} }
auto xml = Xml::load(buffer); auto xml = Xml::load(buffer);
std::string error; std::string error;
struct LanguageRoot root; struct LanguageRoot root;
auto ret = (LanguageRootParser()).parse(&xml, &root, &error); auto ret = (LanguageRootParser()).parse(&xml, &root, &error);
if(ret != 0) { if(ret != 0) {
std::cout << error << std::endl; std::cout << error << std::endl;
return ret; return ret;
} }
// Now dump out the language strings to be picked up later. // Now dump out the language strings to be picked up later.
ret = languageSaveStrings(flags["output"], root.strings); ret = languageSaveStrings(flags["output"], root.strings);
if(ret != 0) return ret; if(ret != 0) return ret;
return 0; return 0;
} }

View File

@ -1,38 +1,38 @@
# Copyright (c) 2021 Dominic Msters # Copyright (c) 2021 Dominic Msters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Texture Build Tool # Texture Build Tool
project(texturegen VERSION 1.0) project(texturegen VERSION 1.0)
add_executable(texturegen) add_executable(texturegen)
target_sources(texturegen target_sources(texturegen
PRIVATE PRIVATE
${DAWN_SHARED_SOURCES} ${DAWN_SHARED_SOURCES}
${DAWN_TOOL_SOURCES} ${DAWN_TOOL_SOURCES}
TextureGen.cpp TextureGen.cpp
../../util/image.cpp ../../util/image.cpp
) )
target_include_directories(texturegen target_include_directories(texturegen
PUBLIC PUBLIC
${DAWN_SHARED_INCLUDES} ${DAWN_SHARED_INCLUDES}
${DAWN_TOOL_INCLUDES} ${DAWN_TOOL_INCLUDES}
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}
) )
# Definitions # Definitions
target_compile_definitions(texturegen target_compile_definitions(texturegen
PUBLIC PUBLIC
${DAWN_SHARED_DEFINITIONS} ${DAWN_SHARED_DEFINITIONS}
DAWN_TOOL_INSTANCE=TextureGen DAWN_TOOL_INSTANCE=TextureGen
DAWN_TOOL_HEADER="TextureGen.hpp" DAWN_TOOL_HEADER="TextureGen.hpp"
) )
target_link_libraries(texturegen target_link_libraries(texturegen
PUBLIC PUBLIC
${DAWN_BUILD_HOST_LIBS} ${DAWN_BUILD_HOST_LIBS}
stb stb
) )

View File

@ -1,25 +1,25 @@
# Copyright (c) 2021 Dominic Msters # Copyright (c) 2021 Dominic Msters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Texture Build Tool # Texture Build Tool
project(tilesetgen VERSION 1.0) project(tilesetgen VERSION 1.0)
add_executable(tilesetgen) add_executable(tilesetgen)
target_sources(tilesetgen target_sources(tilesetgen
PRIVATE PRIVATE
main.cpp main.cpp
../../util/file.cpp ../../util/file.cpp
../../util/image.cpp ../../util/image.cpp
) )
target_include_directories(tilesetgen target_include_directories(tilesetgen
PUBLIC PUBLIC
${DAWN_SHARED_INCLUDES} ${DAWN_SHARED_INCLUDES}
${CMAKE_CURRENT_LIST_DIR}/../../ ${CMAKE_CURRENT_LIST_DIR}/../../
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}
) )
target_link_libraries(tilesetgen target_link_libraries(tilesetgen
PUBLIC PUBLIC
${DAWN_BUILD_HOST_LIBS} ${DAWN_BUILD_HOST_LIBS}
stb stb
) )

View File

@ -1,147 +1,147 @@
/** /**
* Copyright (c) 2022 Dominic Masters * Copyright (c) 2022 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "dawnsharedlibs.hpp" #include "dawnsharedlibs.hpp"
#include "../../util/file.hpp" #include "../../util/file.hpp"
#include "../../util/image.hpp" #include "../../util/image.hpp"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
char *in; char *in;
char *out; char *out;
FILE *file; FILE *file;
char path[FILENAME_MAX + 1]; char path[FILENAME_MAX + 1];
int w, h, channels, cols, rows; int w, h, channels, cols, rows;
stbi_uc *dataImageRaw; stbi_uc *dataImageRaw;
int gapX, gapY, borderX, borderY; int gapX, gapY, borderX, borderY;
if(argc < 5) { if(argc < 5) {
printf("Invalid number of arguments"); printf("Invalid number of arguments");
return 1; return 1;
} }
in = argv[1]; in = argv[1];
out = argv[2]; out = argv[2];
gapX = 0, gapY = 0, borderX = 0, borderY = 0; gapX = 0, gapY = 0, borderX = 0, borderY = 0;
cols = atoi(argv[3]); cols = atoi(argv[3]);
if(cols <= 0) { if(cols <= 0) {
printf("Columns is invalid\n"); printf("Columns is invalid\n");
return 1; return 1;
} }
rows = atoi(argv[4]); rows = atoi(argv[4]);
if(rows <= 0) { if(rows <= 0) {
printf("Rows is invalid"); printf("Rows is invalid");
return 1; return 1;
} }
if(argc >= 6) { if(argc >= 6) {
gapX = atoi(argv[5]); gapX = atoi(argv[5]);
if(gapX <= 0) { if(gapX <= 0) {
printf("Gap X is invalid\n"); printf("Gap X is invalid\n");
return 1; return 1;
} }
} }
if(argc >= 7) { if(argc >= 7) {
gapY = atoi(argv[6]); gapY = atoi(argv[6]);
if(gapY <= 0) { if(gapY <= 0) {
printf("Gap Y is invalid\n"); printf("Gap Y is invalid\n");
return 1; return 1;
} }
} }
if(argc >= 8) { if(argc >= 8) {
borderX = atoi(argv[7]); borderX = atoi(argv[7]);
if(borderX <= 0) { if(borderX <= 0) {
printf("Border X is invalid\n"); printf("Border X is invalid\n");
return 1; return 1;
} }
} }
if(argc >= 9) { if(argc >= 9) {
borderY = atoi(argv[8]); borderY = atoi(argv[8]);
if(borderY <= 0) { if(borderY <= 0) {
printf("Border Y is invalid\n"); printf("Border Y is invalid\n");
return 1; return 1;
} }
} }
// Normalize slashes // Normalize slashes
fileNormalizeSlashes(in); fileNormalizeSlashes(in);
fileNormalizeSlashes(out); fileNormalizeSlashes(out);
// Check the output doesn't already exist // Check the output doesn't already exist
sprintf(path, "%s.tileset", out); sprintf(path, "%s.tileset", out);
file = fopen(path, "rb"); file = fopen(path, "rb");
if(file != NULL) { if(file != NULL) {
fclose(file); fclose(file);
return 0; return 0;
} }
// Read in the original texture // Read in the original texture
file = fopen(in, "rb"); file = fopen(in, "rb");
if(file == NULL) { if(file == NULL) {
printf("Failed to open file!\n"); printf("Failed to open file!\n");
return 1; return 1;
} }
// Read image data // Read image data
dataImageRaw = stbi_load_from_file(file, &w, &h, &channels, STBI_rgb_alpha); dataImageRaw = stbi_load_from_file(file, &w, &h, &channels, STBI_rgb_alpha);
if(dataImageRaw == NULL) { if(dataImageRaw == NULL) {
printf("Failed to load input texture!\n"); printf("Failed to load input texture!\n");
return 1; return 1;
} }
fclose(file); fclose(file);
free(dataImageRaw); free(dataImageRaw);
if(w <= 0 || h <= 0) { if(w <= 0 || h <= 0) {
printf("Reading image failed (corrupted?)\n"); printf("Reading image failed (corrupted?)\n");
return 1; return 1;
} }
// Calculate division sizes (pixels) // Calculate division sizes (pixels)
int divX = (w - (borderX * 2) - (gapX * (cols - 1))) / cols; int divX = (w - (borderX * 2) - (gapX * (cols - 1))) / cols;
int divY = (h - (borderY * 2) - (gapY * (rows - 1))) / rows; int divY = (h - (borderY * 2) - (gapY * (rows - 1))) / rows;
// Calculate the division sizes (units) // Calculate the division sizes (units)
float tdivX = (float)divX / (float)w; float tdivX = (float)divX / (float)w;
float tdivY = (float)divY / (float)h; float tdivY = (float)divY / (float)h;
// Output buffer prep // Output buffer prep
char *buffer = (char *)malloc(sizeof(char) * (cols * rows * 48 + 48 + 48)); char *buffer = (char *)malloc(sizeof(char) * (cols * rows * 48 + 48 + 48));
buffer[0] = '\0'; buffer[0] = '\0';
sprintf(buffer, "%i|%i|%i|%i|", cols, rows, divX, divY); sprintf(buffer, "%i|%i|%i|%i|", cols, rows, divX, divY);
// Now prep tileset. // Now prep tileset.
for(float y = 0; y < rows; y++) { for(float y = 0; y < rows; y++) {
for(float x = 0; x < cols; x++) { for(float x = 0; x < cols; x++) {
float ux0 = ((float)borderX + ((float)divX * x) + ((float)gapX * x)) / (float)w; float ux0 = ((float)borderX + ((float)divX * x) + ((float)gapX * x)) / (float)w;
float ux1 = ux0 + tdivX; float ux1 = ux0 + tdivX;
float uy0 = ((float)borderY + ((float)divY * y) + ((float)gapY * y)) / (float)h; float uy0 = ((float)borderY + ((float)divY * y) + ((float)gapY * y)) / (float)h;
float uy1 = uy0 + tdivY; float uy1 = uy0 + tdivY;
sprintf(buffer, "%s%f,%f,%f,%f|", buffer, ux0, ux1, uy0, uy1); sprintf(buffer, "%s%f,%f,%f,%f|", buffer, ux0, ux1, uy0, uy1);
} }
} }
// Open output file // Open output file
fileMkdirp(path); fileMkdirp(path);
file = fopen(path, "wb"); file = fopen(path, "wb");
if(file == NULL) { if(file == NULL) {
free(buffer); free(buffer);
printf("Invalid tileset file out!\n"); printf("Invalid tileset file out!\n");
return 1; return 1;
} }
// Write and close // Write and close
fwrite(buffer, sizeof(char), strlen(buffer), file); fwrite(buffer, sizeof(char), strlen(buffer), file);
fclose(file); fclose(file);
free(buffer); free(buffer);
return 0; return 0;
} }

View File

@ -1,25 +1,25 @@
# Copyright (c) 2021 Dominic Msters # Copyright (c) 2021 Dominic Msters
# #
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
# Texture Build Tool # Texture Build Tool
project(truetypegen VERSION 1.0) project(truetypegen VERSION 1.0)
add_executable(truetypegen) add_executable(truetypegen)
target_sources(truetypegen target_sources(truetypegen
PRIVATE PRIVATE
main.cpp main.cpp
../../util/file.cpp ../../util/file.cpp
../../util/image.cpp ../../util/image.cpp
) )
target_include_directories(truetypegen target_include_directories(truetypegen
PUBLIC PUBLIC
${DAWN_SHARED_INCLUDES} ${DAWN_SHARED_INCLUDES}
${CMAKE_CURRENT_LIST_DIR}/../../ ${CMAKE_CURRENT_LIST_DIR}/../../
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}
) )
target_link_libraries(truetypegen target_link_libraries(truetypegen
PUBLIC PUBLIC
${DAWN_BUILD_HOST_LIBS} ${DAWN_BUILD_HOST_LIBS}
stb stb
) )

View File

@ -1,141 +1,141 @@
/** /**
* Copyright (c) 2021 Dominic Masters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "dawnsharedlibs.hpp" #include "dawnsharedlibs.hpp"
#include "../../util/file.hpp" #include "../../util/file.hpp"
#include "../../util/image.hpp" #include "../../util/image.hpp"
#ifndef STB_TRUETYPE_IMPLEMENTATION #ifndef STB_TRUETYPE_IMPLEMENTATION
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h> #include <stb_truetype.h>
#endif #endif
#define TRUETYPE_FIRST_CHAR 32 #define TRUETYPE_FIRST_CHAR 32
#define TRUETYPE_NUM_CHARS 96 #define TRUETYPE_NUM_CHARS 96
int main(int argc, char *args[]) { int main(int argc, char *args[]) {
FILE *file; FILE *file;
char path[FILENAME_MAX + 1]; char path[FILENAME_MAX + 1];
int32_t width, height, fontSize, textureSize; int32_t width, height, fontSize, textureSize;
/* /*
args0 - PATH args0 - PATH
args1 - Input Filename (TTF file) args1 - Input Filename (TTF file)
args2 - Output Filename args2 - Output Filename
args3 - Width of the output texture (Resolution X) args3 - Width of the output texture (Resolution X)
args4 - Height of the output texture (Resolution Y) args4 - Height of the output texture (Resolution Y)
args5 - Font size to draw args5 - Font size to draw
*/ */
if(argc != 6) { if(argc != 6) {
printf("Invalid number of arguments\n"); printf("Invalid number of arguments\n");
return 1; return 1;
} }
char *fileIn = args[1]; char *fileIn = args[1];
char *fileOut = args[2]; char *fileOut = args[2];
char *strWidth = args[3]; char *strWidth = args[3];
char *strHeight = args[4]; char *strHeight = args[4];
char *strFontSize = args[5]; char *strFontSize = args[5];
// Normalize slashes // Normalize slashes
fileNormalizeSlashes(fileIn); fileNormalizeSlashes(fileIn);
fileNormalizeSlashes(fileOut); fileNormalizeSlashes(fileOut);
// Check the output doesn't already exist // Check the output doesn't already exist
sprintf(path, "%s.truetype", fileOut); sprintf(path, "%s.truetype", fileOut);
file = fopen(path, "rb"); file = fopen(path, "rb");
if(file != NULL) { if(file != NULL) {
fclose(file); fclose(file);
return 0; return 0;
} }
width = atoi(strWidth); width = atoi(strWidth);
if(width <= 0) { if(width <= 0) {
printf("Width is invalid.\n"); printf("Width is invalid.\n");
return 1; return 1;
} }
height = atoi(strHeight); height = atoi(strHeight);
if(height <= 0) { if(height <= 0) {
printf("Height is invalid.\n"); printf("Height is invalid.\n");
return 1; return 1;
} }
fontSize = atoi(strFontSize); fontSize = atoi(strFontSize);
if(fontSize <= 0) { if(fontSize <= 0) {
printf("Font size is invalid.\n"); printf("Font size is invalid.\n");
return 1; return 1;
} }
// Read in the TTF data // Read in the TTF data
file = fopen(fileIn, "rb"); file = fopen(fileIn, "rb");
if(file == NULL) { if(file == NULL) {
printf("Failed to open input TTF file.\n"); printf("Failed to open input TTF file.\n");
return 1; return 1;
} }
// Seek to end, get length, seek back to start. // Seek to end, get length, seek back to start.
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
size_t fileSize = ftell(file); size_t fileSize = ftell(file);
fseek(file, 0, SEEK_SET); fseek(file, 0, SEEK_SET);
// Read in all data // Read in all data
char *ttfData = (char*)malloc(sizeof(char) * fileSize); char *ttfData = (char*)malloc(sizeof(char) * fileSize);
size_t readSize = fread(ttfData, 1, fileSize, file); size_t readSize = fread(ttfData, 1, fileSize, file);
fclose(file); fclose(file);
if(readSize < fileSize) { if(readSize < fileSize) {
free(ttfData); free(ttfData);
printf("Failed to read all data form TTF\n"); printf("Failed to read all data form TTF\n");
return 1; return 1;
} }
// Create bitmap data. This is a single channel color (alpha). // Create bitmap data. This is a single channel color (alpha).
textureSize = width * height; textureSize = width * height;
stbi_uc *bitmapData = (stbi_uc*)malloc(sizeof(stbi_uc) * textureSize); stbi_uc *bitmapData = (stbi_uc*)malloc(sizeof(stbi_uc) * textureSize);
stbtt_bakedchar characterData[TRUETYPE_NUM_CHARS]; stbtt_bakedchar characterData[TRUETYPE_NUM_CHARS];
// Now parse the TTF itself. // Now parse the TTF itself.
stbtt_BakeFontBitmap( stbtt_BakeFontBitmap(
(uint8_t*)ttfData, 0, (float)fontSize, bitmapData, (uint8_t*)ttfData, 0, (float)fontSize, bitmapData,
width, height, width, height,
TRUETYPE_FIRST_CHAR, TRUETYPE_NUM_CHARS, TRUETYPE_FIRST_CHAR, TRUETYPE_NUM_CHARS,
characterData characterData
); );
// Prepare output file for writing. // Prepare output file for writing.
sprintf(path, "%s.truetype", fileOut); sprintf(path, "%s.truetype", fileOut);
fileMkdirp(path); fileMkdirp(path);
file = fopen(path, "wb"); file = fopen(path, "wb");
if(file == NULL) { if(file == NULL) {
printf("Failed to create output TTF file\n"); printf("Failed to create output TTF file\n");
return 1; return 1;
} }
// Now prepare output data. // Now prepare output data.
char headerBuffer[64]; char headerBuffer[64];
int32_t headerBufferLength = sprintf( int32_t headerBufferLength = sprintf(
headerBuffer, "%i|%i|%i|", width, height, fontSize headerBuffer, "%i|%i|%i|", width, height, fontSize
); );
fwrite(headerBuffer, sizeof(char), headerBufferLength, file); fwrite(headerBuffer, sizeof(char), headerBufferLength, file);
// Write output pixels. // Write output pixels.
float outputPixels[4]; float outputPixels[4];
for(int32_t i = 0; i < textureSize; i++) { for(int32_t i = 0; i < textureSize; i++) {
outputPixels[0] = 1.0f; outputPixels[0] = 1.0f;
outputPixels[1] = 1.0f; outputPixels[1] = 1.0f;
outputPixels[2] = 1.0f; outputPixels[2] = 1.0f;
outputPixels[3] = ((float)bitmapData[i]) / 255.0f; outputPixels[3] = ((float)bitmapData[i]) / 255.0f;
fwrite(outputPixels, sizeof(float), 4, file); fwrite(outputPixels, sizeof(float), 4, file);
} }
// Now write output quads data. // Now write output quads data.
fwrite(characterData, sizeof(stbtt_bakedchar), TRUETYPE_NUM_CHARS, file); fwrite(characterData, sizeof(stbtt_bakedchar), TRUETYPE_NUM_CHARS, file);
fclose(file); fclose(file);
free(bitmapData); free(bitmapData);
return 0; return 0;
} }

View File

@ -0,0 +1,17 @@
# Copyright (c) 2023 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(D ${CMAKE_CURRENT_LIST_DIR})
set(
DAWN_TOOL_SOURCES
${D}/DawnTool.cpp
${D}/File.cpp
${D}/Language.cpp
${D}/CodeGen.cpp
CACHE INTERNAL
${DAWN_CACHE_TARGET}
)

View File

@ -1,120 +1,120 @@
/** /**
* Copyright (c) 2022 Dominic Masters * Copyright (c) 2022 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "csv.hpp" #include "csv.hpp"
char * csvGetCell(csv_t *csv, int32_t row, int32_t cell) { char * csvGetCell(csv_t *csv, int32_t row, int32_t cell) {
return csv->rows[(row * CSV_COLUMN_COUNT_MAX) + cell]; return csv->rows[(row * CSV_COLUMN_COUNT_MAX) + cell];
} }
void csvParse(char *string, csv_t *csv) { void csvParse(char *string, csv_t *csv) {
char c; char c;
size_t i, j, length; size_t i, j, length;
csvparsestate_t state; csvparsestate_t state;
int32_t rowCellCount; int32_t rowCellCount;
length = strlen(string); length = strlen(string);
csv->buffer = (char *)malloc(sizeof(char) * (length+1) * CSV_COLUMN_COUNT_MAX * CSV_ROW_COUNT_MAX); csv->buffer = (char *)malloc(sizeof(char) * (length+1) * CSV_COLUMN_COUNT_MAX * CSV_ROW_COUNT_MAX);
csv->cellCounts = (int32_t *)malloc(sizeof(int32_t) * CSV_ROW_COUNT_MAX); csv->cellCounts = (int32_t *)malloc(sizeof(int32_t) * CSV_ROW_COUNT_MAX);
csv->rows = (char**)malloc(sizeof(char*) * CSV_ROW_COUNT_MAX * CSV_COLUMN_COUNT_MAX); csv->rows = (char**)malloc(sizeof(char*) * CSV_ROW_COUNT_MAX * CSV_COLUMN_COUNT_MAX);
i = 0; i = 0;
j = 0; j = 0;
rowCellCount = 0; rowCellCount = 0;
csv->rowCount = 0; csv->rowCount = 0;
state = CSV_PARSE_STATE_FIND_CELL; state = CSV_PARSE_STATE_FIND_CELL;
while(i < length) { while(i < length) {
c = string[i++]; c = string[i++];
// What are we doing // What are we doing
switch(state) { switch(state) {
case CSV_PARSE_STATE_FIND_CELL: case CSV_PARSE_STATE_FIND_CELL:
if(c == '"') { if(c == '"') {
state = CSV_PARSE_STATE_PARSE_CELL_WITH_QUOTES; state = CSV_PARSE_STATE_PARSE_CELL_WITH_QUOTES;
csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j; csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j;
rowCellCount++; rowCellCount++;
continue; continue;
} else if(c == '\r' || c == '\n') { } else if(c == '\r' || c == '\n') {
// Newline (todo: is this a blank line?) // Newline (todo: is this a blank line?)
state = CSV_PARSE_STATE_LINE_END; state = CSV_PARSE_STATE_LINE_END;
continue; continue;
} else if(c == ',') { } else if(c == ',') {
csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j; csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j;
csv->buffer[j++] = '\0'; csv->buffer[j++] = '\0';
rowCellCount++; rowCellCount++;
continue; continue;
} else { } else {
state = CSV_PARSE_STATE_PARSE_CELL; state = CSV_PARSE_STATE_PARSE_CELL;
csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j; csv->rows[(csv->rowCount * CSV_COLUMN_COUNT_MAX) + rowCellCount] = csv->buffer + j;
csv->buffer[j++] = c; csv->buffer[j++] = c;
rowCellCount++; rowCellCount++;
continue; continue;
} }
case CSV_PARSE_STATE_PARSE_CELL: case CSV_PARSE_STATE_PARSE_CELL:
if(c == '\r' || c == '\n') { if(c == '\r' || c == '\n') {
state = CSV_PARSE_STATE_LINE_END; state = CSV_PARSE_STATE_LINE_END;
csv->buffer[j++] = '\0'; csv->buffer[j++] = '\0';
continue; continue;
} else if(c == ',') { } else if(c == ',') {
state = CSV_PARSE_STATE_FIND_CELL; state = CSV_PARSE_STATE_FIND_CELL;
csv->buffer[j++] = '\0'; csv->buffer[j++] = '\0';
continue; continue;
} }
csv->buffer[j++] = c; csv->buffer[j++] = c;
continue; continue;
case CSV_PARSE_STATE_PARSE_CELL_WITH_QUOTES: case CSV_PARSE_STATE_PARSE_CELL_WITH_QUOTES:
if((c == '\\' && string[i] == '"') || (c == '"' && string[i] == '"')) { if((c == '\\' && string[i] == '"') || (c == '"' && string[i] == '"')) {
// Handle escaped quotes. I normally see [\"] but excel does [""] in // Handle escaped quotes. I normally see [\"] but excel does [""] in
// most cases // most cases
csv->buffer[j++] = '"'; csv->buffer[j++] = '"';
i++; i++;
continue; continue;
} else if(c == '"') { } else if(c == '"') {
// Handle end of quoted string // Handle end of quoted string
state = CSV_PARSE_STATE_FIND_CELL; state = CSV_PARSE_STATE_FIND_CELL;
csv->buffer[j++] = '\0'; csv->buffer[j++] = '\0';
// Because we tend to do [",] at the end of a quoted cell, we do this // Because we tend to do [",] at the end of a quoted cell, we do this
// to prevent [,,] cases being treated the same // to prevent [,,] cases being treated the same
if(string[i] == ',') i++; if(string[i] == ',') i++;
continue; continue;
} }
// Normal character. // Normal character.
csv->buffer[j++] = c; csv->buffer[j++] = c;
continue; continue;
case CSV_PARSE_STATE_LINE_END: case CSV_PARSE_STATE_LINE_END:
// Skip blanks // Skip blanks
if(c == '\r' || c == '\n') continue; if(c == '\r' || c == '\n') continue;
csv->cellCounts[csv->rowCount] = rowCellCount; csv->cellCounts[csv->rowCount] = rowCellCount;
csv->rowCount++; csv->rowCount++;
rowCellCount = 0; rowCellCount = 0;
state = CSV_PARSE_STATE_FIND_CELL; state = CSV_PARSE_STATE_FIND_CELL;
i--; i--;
continue; continue;
default: default:
printf("Error occured during parse operation."); printf("Error occured during parse operation.");
free(NULL); free(NULL);
} }
} }
csv->buffer[j++] = '\0'; csv->buffer[j++] = '\0';
if(rowCellCount != 0) { if(rowCellCount != 0) {
csv->cellCounts[csv->rowCount] = rowCellCount; csv->cellCounts[csv->rowCount] = rowCellCount;
csv->rowCount++; csv->rowCount++;
} }
} }
void csvDispose(csv_t *csv) { void csvDispose(csv_t *csv) {
free(csv->buffer); free(csv->buffer);
free(csv->cellCounts); free(csv->cellCounts);
free(csv->rows); free(csv->rows);
} }

View File

@ -1,33 +1,33 @@
/** /**
* Copyright (c) 2022 Dominic Masters * Copyright (c) 2022 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#pragma once #pragma once
#include "dawnsharedlibs.hpp" #include "dawnsharedlibs.hpp"
#include "string.h" #include "string.h"
#define CSV_ROW_COUNT_MAX 128 #define CSV_ROW_COUNT_MAX 128
#define CSV_COLUMN_COUNT_MAX 16 #define CSV_COLUMN_COUNT_MAX 16
typedef enum { typedef enum {
CSV_PARSE_STATE_FIND_CELL,//0 CSV_PARSE_STATE_FIND_CELL,//0
CSV_PARSE_STATE_PARSE_CELL_WITH_QUOTES, CSV_PARSE_STATE_PARSE_CELL_WITH_QUOTES,
CSV_PARSE_STATE_PARSE_CELL,//2 CSV_PARSE_STATE_PARSE_CELL,//2
CSV_PARSE_STATE_LINE_END CSV_PARSE_STATE_LINE_END
} csvparsestate_t; } csvparsestate_t;
typedef struct { typedef struct {
char *buffer; char *buffer;
char **rows; char **rows;
int32_t rowCount; int32_t rowCount;
int32_t *cellCounts; int32_t *cellCounts;
} csv_t; } csv_t;
char * csvGetCell(csv_t *csv, int32_t row, int32_t cell); char * csvGetCell(csv_t *csv, int32_t row, int32_t cell);
void csvParse(char *string, csv_t *csv); void csvParse(char *string, csv_t *csv);
void csvDispose(csv_t *csv); void csvDispose(csv_t *csv);

View File

@ -1,55 +1,55 @@
/** /**
* Copyright (c) 2021 Dominic Masters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "image.hpp" #include "image.hpp"
#ifndef STB_IMAGE_IMPLEMENTATION #ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h> #include <stb_image.h>
#endif #endif
#ifndef STB_IMAGE_RESIZE_IMPLEMENTATION #ifndef STB_IMAGE_RESIZE_IMPLEMENTATION
#define STB_IMAGE_RESIZE_IMPLEMENTATION #define STB_IMAGE_RESIZE_IMPLEMENTATION
#include <stb_image_resize.h> #include <stb_image_resize.h>
#endif #endif
#ifndef STB_IMAGE_WRITE_IMPLEMENTATION #ifndef STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb_image_write.h> #include <stb_image_write.h>
#endif #endif
void imageCopy( void imageCopy(
uint8_t *source, int32_t sourceWidth, int32_t sourceHeight, uint8_t *source, int32_t sourceWidth, int32_t sourceHeight,
uint8_t *dest, int32_t destWidth, int32_t destHeight, uint8_t *dest, int32_t destWidth, int32_t destHeight,
int32_t cropX, int32_t cropY, int32_t cropWidth, int32_t cropHeight, int32_t cropX, int32_t cropY, int32_t cropWidth, int32_t cropHeight,
int32_t pasteX, int32_t pasteY, int32_t pasteX, int32_t pasteY,
int32_t channels int32_t channels
) { ) {
int32_t x, y, c; int32_t x, y, c;
int32_t absX, absY; int32_t absX, absY;
int32_t sourceIndex, targetIndex; int32_t sourceIndex, targetIndex;
if(cropX == -1) cropX = 0; if(cropX == -1) cropX = 0;
if(cropY == -1) cropY = 0; if(cropY == -1) cropY = 0;
if(cropWidth == -1) cropWidth = sourceWidth; if(cropWidth == -1) cropWidth = sourceWidth;
if(cropHeight == -1) cropHeight = sourceHeight; if(cropHeight == -1) cropHeight = sourceHeight;
if(pasteX == -1) pasteX = 0; if(pasteX == -1) pasteX = 0;
if(pasteY == -1) pasteY = 0; if(pasteY == -1) pasteY = 0;
for(x = cropX; x < cropX + cropWidth; x++) { for(x = cropX; x < cropX + cropWidth; x++) {
for(y = cropY; y < cropY + cropHeight; y++) { for(y = cropY; y < cropY + cropHeight; y++) {
absX = x - cropX + pasteX; absX = x - cropX + pasteX;
absY = y - cropY + pasteY; absY = y - cropY + pasteY;
if(absX >= destWidth || absY >= destHeight || absX < 0 || absY < 0)continue; if(absX >= destWidth || absY >= destHeight || absX < 0 || absY < 0)continue;
targetIndex = absY * destWidth + absX; targetIndex = absY * destWidth + absX;
sourceIndex = y * sourceWidth + x; sourceIndex = y * sourceWidth + x;
for(c = 0; c < channels; c++) { for(c = 0; c < channels; c++) {
dest[(targetIndex*channels) + c] = source[(sourceIndex*channels) + c]; dest[(targetIndex*channels) + c] = source[(sourceIndex*channels) + c];
} }
} }
} }
} }

View File

@ -1,39 +1,39 @@
/** /**
* Copyright (c) 2021 Dominic Masters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#pragma once #pragma once
#include "dawnsharedlibs.hpp" #include "dawnsharedlibs.hpp"
#include "file.hpp" #include "file.hpp"
#include <stb_image.h> #include <stb_image.h>
#include <stb_image_resize.h> #include <stb_image_resize.h>
#include <stb_image_write.h> #include <stb_image_write.h>
/** /**
* Unused currently. * Unused currently.
* *
* @param source * @param source
* @param sourceWidth * @param sourceWidth
* @param sourceHeight * @param sourceHeight
* @param dest * @param dest
* @param destWidth * @param destWidth
* @param destHeight * @param destHeight
* @param cropX * @param cropX
* @param cropY * @param cropY
* @param cropWidth * @param cropWidth
* @param cropHeight * @param cropHeight
* @param pasteX * @param pasteX
* @param pasteY * @param pasteY
* @param channels * @param channels
*/ */
void imageCopy( void imageCopy(
uint8_t *source, int32_t sourceWidth, int32_t sourceHeight, uint8_t *source, int32_t sourceWidth, int32_t sourceHeight,
uint8_t *dest, int32_t destWidth, int32_t destHeight, uint8_t *dest, int32_t destWidth, int32_t destHeight,
int32_t cropX, int32_t cropY, int32_t cropWidth, int32_t cropHeight, int32_t cropX, int32_t cropY, int32_t cropWidth, int32_t cropHeight,
int32_t pasteX, int32_t pasteY, int32_t pasteX, int32_t pasteY,
int32_t channels int32_t channels
); );

View File

@ -0,0 +1,36 @@
/**
* Copyright (c) 2023 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dawnsharedlibs.hpp"
/**
* Remove all instances of a character from a C-Styled string.
*
* @param string String to remove characters from.
* @param remove Character to remove.
*/
static inline void stringRemoveAll(char *string, char remove) {
size_t len = strlen(string);
size_t i, j;
i = 0;
while(i < len) {
char c = string[i];
if(c != remove) {
i++;
continue;
}
j = i + 1;
while(j < len) {
string[j-1] = string[j];
j++;
}
len--;
}
}

View File

@ -1,231 +1,231 @@
/** /**
* Copyright (c) 2021 Dominic Masters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "xml.hpp" #include "xml.hpp"
int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) { int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) {
char c; char c;
int32_t level = 0; int32_t level = 0;
uint8_t doing = XML_DOING_NOTHING; uint8_t doing = XML_DOING_NOTHING;
uint8_t doingBeforeComment; uint8_t doingBeforeComment;
bool insideTag = false; bool insideTag = false;
char* buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX); char* buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX);
int32_t bufferLength = 0; int32_t bufferLength = 0;
xml->value = NULL; xml->value = NULL;
xml->attributeCount = 0; xml->attributeCount = 0;
xml->children = (xml_t *)malloc(sizeof(xml_t) * XML_CHILD_COUNT_MAX); xml->children = (xml_t *)malloc(sizeof(xml_t) * XML_CHILD_COUNT_MAX);
xml->childrenCount = 0; xml->childrenCount = 0;
while(c = data[i++]) { while(c = data[i++]) {
switch(doing) { switch(doing) {
case XML_DOING_NOTHING: case XML_DOING_NOTHING:
// Look for either an opening tag (<) or a word for a value. // Look for either an opening tag (<) or a word for a value.
if(c == '>') continue; if(c == '>') continue;
if(c == '<') { if(c == '<') {
if(data[i] == '!' && data[i+1] == '-' && data[i+2] == '-') { if(data[i] == '!' && data[i+1] == '-' && data[i+2] == '-') {
doingBeforeComment = doing; doingBeforeComment = doing;
doing = XML_PARSING_COMMENT; doing = XML_PARSING_COMMENT;
i += 3; i += 3;
} else if(insideTag) { } else if(insideTag) {
i = xmlLoadChild(xml->children + xml->childrenCount++, data, i-1); i = xmlLoadChild(xml->children + xml->childrenCount++, data, i-1);
doing = XML_PARSING_CHILD; doing = XML_PARSING_CHILD;
} else { } else {
doing = XML_PARSING_TAG_NAME; doing = XML_PARSING_TAG_NAME;
level++; level++;
insideTag = true; insideTag = true;
} }
continue; continue;
} }
if(xmlIsWhitespace(c)) continue; if(xmlIsWhitespace(c)) continue;
doing = XML_PARSING_VALUE; doing = XML_PARSING_VALUE;
buffer[bufferLength++] = c; buffer[bufferLength++] = c;
break; break;
case XML_PARSING_TAG_NAME: case XML_PARSING_TAG_NAME:
// Just keep reading until we either hit a space (end of the tag name) // Just keep reading until we either hit a space (end of the tag name)
// or a closing tag value, either / or > // or a closing tag value, either / or >
if(xmlIsWhitespace(c) || c == '>' || c == '/') { if(xmlIsWhitespace(c) || c == '>' || c == '/') {
buffer[bufferLength] = '\0'; buffer[bufferLength] = '\0';
xml->node = buffer; xml->node = buffer;
buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX); buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX);
bufferLength = 0; bufferLength = 0;
if(c == '/') { if(c == '/') {
level--; level--;
insideTag = false; insideTag = false;
doing = XML_PARSING_CLOSE; doing = XML_PARSING_CLOSE;
} else { } else {
doing = c == '>' ? XML_DOING_NOTHING : XML_LOOKING_FOR_ATTRIBUTE; doing = c == '>' ? XML_DOING_NOTHING : XML_LOOKING_FOR_ATTRIBUTE;
} }
continue; continue;
} }
buffer[bufferLength++] = c; buffer[bufferLength++] = c;
break; break;
case XML_LOOKING_FOR_ATTRIBUTE: case XML_LOOKING_FOR_ATTRIBUTE:
// Look until we hit either the end of a tag, or the attribute itself // Look until we hit either the end of a tag, or the attribute itself
if(xmlIsWhitespace(c) || c == '>' || c == '/' || c == '=') { if(xmlIsWhitespace(c) || c == '>' || c == '/' || c == '=') {
if(c == '>' || c == '/') { if(c == '>' || c == '/') {
doing = XML_DOING_NOTHING; doing = XML_DOING_NOTHING;
if(c == '/') { if(c == '/') {
level--; level--;
insideTag = false; insideTag = false;
doing = XML_PARSING_CLOSE; doing = XML_PARSING_CLOSE;
} }
} else if(c == '=') { } else if(c == '=') {
doing = XML_LOOKING_FOR_ATTRIBUTE_VALUE; doing = XML_LOOKING_FOR_ATTRIBUTE_VALUE;
} else { } else {
doing = XML_LOOKING_FOR_ATTRIBUTE; doing = XML_LOOKING_FOR_ATTRIBUTE;
} }
if(bufferLength > 0) { if(bufferLength > 0) {
buffer[bufferLength] = '\0'; buffer[bufferLength] = '\0';
xml->attributeNames[xml->attributeCount++] = buffer; xml->attributeNames[xml->attributeCount++] = buffer;
xml->attributeDatas[xml->attributeCount] = NULL; xml->attributeDatas[xml->attributeCount] = NULL;
buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX); buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX);
bufferLength = 0; bufferLength = 0;
} }
continue; continue;
} }
buffer[bufferLength++] = c; buffer[bufferLength++] = c;
break; break;
case XML_LOOKING_FOR_ATTRIBUTE_VALUE: case XML_LOOKING_FOR_ATTRIBUTE_VALUE:
// Keep looking until we find a quote mark // Keep looking until we find a quote mark
if(xmlIsWhitespace(c)) continue; if(xmlIsWhitespace(c)) continue;
if(c == '>' || c == '/') { if(c == '>' || c == '/') {
doing = XML_DOING_NOTHING; doing = XML_DOING_NOTHING;
insideTag = false; insideTag = false;
continue; continue;
} }
if(c != '"') continue; if(c != '"') continue;
doing = XML_PARSING_ATTRIBUTE_VALUE; doing = XML_PARSING_ATTRIBUTE_VALUE;
break; break;
case XML_PARSING_ATTRIBUTE_VALUE: case XML_PARSING_ATTRIBUTE_VALUE:
// Parse the attribute value until we find a quote mark. // Parse the attribute value until we find a quote mark.
if(c == '"') { if(c == '"') {
doing = XML_LOOKING_FOR_ATTRIBUTE; doing = XML_LOOKING_FOR_ATTRIBUTE;
buffer[bufferLength] = '\0'; buffer[bufferLength] = '\0';
xml->attributeDatas[xml->attributeCount - 1] = buffer; xml->attributeDatas[xml->attributeCount - 1] = buffer;
buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX); buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX);
bufferLength = 0; bufferLength = 0;
continue; continue;
} }
buffer[bufferLength++] = c; buffer[bufferLength++] = c;
break; break;
case XML_PARSING_VALUE: case XML_PARSING_VALUE:
// Keep parsing child until we find a < for an opening/closing tag. // Keep parsing child until we find a < for an opening/closing tag.
if(c == '<') { if(c == '<') {
// In HTML Spec there could be a child here but not in XML spec. // In HTML Spec there could be a child here but not in XML spec.
doing = XML_PARSING_CLOSE; doing = XML_PARSING_CLOSE;
buffer[bufferLength] = '\0'; buffer[bufferLength] = '\0';
bufferLength = 0; bufferLength = 0;
xml->value = buffer; xml->value = buffer;
buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX); buffer = (char *)malloc(sizeof(char) * XML_TEXT_BUFFER_MAX);
continue; continue;
} }
buffer[bufferLength++] = c; buffer[bufferLength++] = c;
break; break;
case XML_PARSING_CHILD: case XML_PARSING_CHILD:
if(c == '<') { if(c == '<') {
// Read ahead and confirm this is a close or not // Read ahead and confirm this is a close or not
if(data[i] == '/') { if(data[i] == '/') {
doing = XML_PARSING_CLOSE; doing = XML_PARSING_CLOSE;
continue; continue;
} }
if(data[i] == '!' && data[i+1] == '-' && data[i+2] == '-') { if(data[i] == '!' && data[i+1] == '-' && data[i+2] == '-') {
doingBeforeComment = doing; doingBeforeComment = doing;
doing = XML_PARSING_COMMENT; doing = XML_PARSING_COMMENT;
i += 3; i += 3;
continue; continue;
} }
// Likely another child. // Likely another child.
i = xmlLoadChild(xml->children + xml->childrenCount++, data, i-1); i = xmlLoadChild(xml->children + xml->childrenCount++, data, i-1);
} }
if(xmlIsWhitespace(c)) continue; if(xmlIsWhitespace(c)) continue;
// In HTML Spec there's a chance for there to be a value here, but not // In HTML Spec there's a chance for there to be a value here, but not
// in the XML spec. // in the XML spec.
break; break;
case XML_PARSING_CLOSE: case XML_PARSING_CLOSE:
// Just keep parsing until the tag closer finishes. // Just keep parsing until the tag closer finishes.
if(c != '>') continue; if(c != '>') continue;
doing = XML_DOING_NOTHING; doing = XML_DOING_NOTHING;
//TODO: Return index or something? //TODO: Return index or something?
free(buffer); free(buffer);
return i; return i;
case XML_PARSING_COMMENT: case XML_PARSING_COMMENT:
if(c != '-') continue; if(c != '-') continue;
if(data[i] != '-') continue; if(data[i] != '-') continue;
if(data[i+1] != '>') continue; if(data[i+1] != '>') continue;
i += 2; i += 2;
doing = doingBeforeComment; doing = doingBeforeComment;
break; break;
default: default:
break; break;
} }
} }
free(buffer); free(buffer);
return i; return i;
} }
void xmlLoad(xml_t *xml, char *data) { void xmlLoad(xml_t *xml, char *data) {
xmlLoadChild(xml, data, 0); xmlLoadChild(xml, data, 0);
} }
void xmlDispose(xml_t *xml) { void xmlDispose(xml_t *xml) {
uint8_t i; uint8_t i;
// Dispose children recursively // Dispose children recursively
for(i = 0; i < xml->childrenCount; i++) { for(i = 0; i < xml->childrenCount; i++) {
xmlDispose(xml->children + i); xmlDispose(xml->children + i);
} }
// Free children array. // Free children array.
free(xml->children); free(xml->children);
// Dispose attributes // Dispose attributes
for(i = 0; i < xml->attributeCount; i++) { for(i = 0; i < xml->attributeCount; i++) {
free(xml->attributeNames[i]); free(xml->attributeNames[i]);
if((xml->attributeDatas + i) != NULL) { if((xml->attributeDatas + i) != NULL) {
free(xml->attributeDatas[i]); free(xml->attributeDatas[i]);
} }
} }
free(xml->node); free(xml->node);
if(xml-> value != NULL) free(xml->value); if(xml-> value != NULL) free(xml->value);
} }
int16_t xmlGetAttributeByName(xml_t *xml, char *name) { int16_t xmlGetAttributeByName(xml_t *xml, char *name) {
int16_t i; int16_t i;
for(i = 0; i < xml->attributeCount; i++) { for(i = 0; i < xml->attributeCount; i++) {
if(strcmp(xml->attributeNames[i], name) == 0) return i; if(strcmp(xml->attributeNames[i], name) == 0) return i;
} }
return -1; return -1;
} }
bool xmlIsWhitespace(char c) { bool xmlIsWhitespace(char c) {
return c == ' ' || c == '\r' || c == '\n' || c == '\t'; return c == ' ' || c == '\r' || c == '\n' || c == '\t';
} }

View File

@ -1,81 +1,81 @@
/** /**
* Copyright (c) 2021 Dominic Masters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#pragma once #pragma once
#include "dawnsharedlibs.hpp" #include "dawnsharedlibs.hpp"
#include "file.hpp" #include "file.hpp"
#define XML_DOING_NOTHING 0x00 #define XML_DOING_NOTHING 0x00
#define XML_PARSING_TAG_NAME 0x01 #define XML_PARSING_TAG_NAME 0x01
#define XML_LOOKING_FOR_ATTRIBUTE 0x02 #define XML_LOOKING_FOR_ATTRIBUTE 0x02
#define XML_PARSING_ATTRIBUTE_NAME 0x03 #define XML_PARSING_ATTRIBUTE_NAME 0x03
#define XML_LOOKING_FOR_ATTRIBUTE_VALUE 0x04 #define XML_LOOKING_FOR_ATTRIBUTE_VALUE 0x04
#define XML_PARSING_ATTRIBUTE_VALUE 0x05 #define XML_PARSING_ATTRIBUTE_VALUE 0x05
#define XML_PARSING_VALUE 0x06 #define XML_PARSING_VALUE 0x06
#define XML_PARSING_CHILD 0x07 #define XML_PARSING_CHILD 0x07
#define XML_PARSING_CLOSE 0x08 #define XML_PARSING_CLOSE 0x08
#define XML_PARSING_COMMENT 0x09 #define XML_PARSING_COMMENT 0x09
#define XML_TEXT_BUFFER_MAX 2048 #define XML_TEXT_BUFFER_MAX 2048
#define XML_CHILD_COUNT_MAX 128 #define XML_CHILD_COUNT_MAX 128
#define XML_ATTRIBUTE_MAX 128 #define XML_ATTRIBUTE_MAX 128
typedef struct _xml_t xml_t; typedef struct _xml_t xml_t;
typedef struct _xml_t { typedef struct _xml_t {
char *node; char *node;
char *value; char *value;
char *attributeNames[XML_ATTRIBUTE_MAX]; char *attributeNames[XML_ATTRIBUTE_MAX];
char *attributeDatas[XML_ATTRIBUTE_MAX]; char *attributeDatas[XML_ATTRIBUTE_MAX];
uint8_t attributeCount; uint8_t attributeCount;
xml_t *children; xml_t *children;
uint8_t childrenCount; uint8_t childrenCount;
} xml_t; } xml_t;
/** /**
* Load an XML child from a string buffer. * Load an XML child from a string buffer.
* *
* @param xml XML to load. * @param xml XML to load.
* @param data Data to parse * @param data Data to parse
* @param i Character index within the data * @param i Character index within the data
* @return The index in the data string this XML node ends. * @return The index in the data string this XML node ends.
*/ */
int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i); int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i);
/** /**
* Load an XML String into an XML memory. * Load an XML String into an XML memory.
* *
* @param xml XML to load into. * @param xml XML to load into.
* @param data XML string. * @param data XML string.
*/ */
void xmlLoad(xml_t *xml, char *data); void xmlLoad(xml_t *xml, char *data);
/** /**
* Dispose a previously loaded XML. * Dispose a previously loaded XML.
* *
* @param xml XML to dispose. * @param xml XML to dispose.
*/ */
void xmlDispose(xml_t *xml); void xmlDispose(xml_t *xml);
/** /**
* Find an attribute index by its name. * Find an attribute index by its name.
* *
* @param xml Xml node to get the attribute from. * @param xml Xml node to get the attribute from.
* @param name The name of the attribute you're trying to find. * @param name The name of the attribute you're trying to find.
* @return -1 if not found, otherwise the index of the attribute within array. * @return -1 if not found, otherwise the index of the attribute within array.
*/ */
int16_t xmlGetAttributeByName(xml_t *xml, char *name); int16_t xmlGetAttributeByName(xml_t *xml, char *name);
/** /**
* Checks if a given character is a whitespace character or not. * Checks if a given character is a whitespace character or not.
* *
* @param c Character to check if a whitespace. * @param c Character to check if a whitespace.
* @return True if whitespace, otherwise false. * @return True if whitespace, otherwise false.
*/ */
bool xmlIsWhitespace(char c); bool xmlIsWhitespace(char c);

View File

@ -5,11 +5,7 @@
# Check for build target, or default. This is pretty much not guaranteed. # Check for build target, or default. This is pretty much not guaranteed.
if(NOT DEFINED DAWN_BUILD_TARGET) if(NOT DEFINED DAWN_BUILD_TARGET)
if(WIN32) set(DAWN_BUILD_TARGET "target-tools")
set(DAWN_BUILD_TARGET "target-rose-win32-glfw")
elseif(UNIX AND NOT APPLE)
set(DAWN_BUILD_TARGET "target-rose-linux64-glfw")
endif()
endif() endif()
# Now validate we have a build target for real # Now validate we have a build target for real

View File

@ -0,0 +1,9 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILDING dawnrose CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_WIN32 true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_NAME "Rose" CACHE INTERNAL ${DAWN_CACHE_TARGET})

View File

@ -18,12 +18,12 @@ void SphereMesh::createSphere(
// Create vertices // Create vertices
int32_t c = 0; int32_t c = 0;
for (int32_t i = 0; i <= stacks; i++) { for (int32_t i = 0; i <= stacks; i++) {
float_t phi = M_PI * i / stacks; float_t phi = MATH_PI * i / stacks;
float_t cosPhi = cos(phi); float_t cosPhi = cos(phi);
float_t sinPhi = sin(phi); float_t sinPhi = sin(phi);
for (int32_t j = 0; j <= slices; j++) { for (int32_t j = 0; j <= slices; j++) {
float_t theta = 2 * M_PI * j / slices; float_t theta = 2 * MATH_PI * j / slices;
float_t cosTheta = cos(theta); float_t cosTheta = cos(theta);
float_t sinTheta = sin(theta); float_t sinTheta = sin(theta);

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include "display/mesh/Mesh.hpp" #include "display/mesh/Mesh.hpp"
#include "util/mathutils.hpp"
namespace Dawn { namespace Dawn {
class SphereMesh { class SphereMesh {

View File

@ -19,7 +19,7 @@ bool_t CapsuleCollider::performRaycast(
return raytestCapsule( return raytestCapsule(
ray, ray,
{ (struct PhysicsCapsule){
.height = this->height, .height = this->height,
.radius = this->radius, .radius = this->radius,
.origin = this->transform->getWorldPosition() .origin = this->transform->getWorldPosition()

View File

@ -30,7 +30,7 @@ void GameCamera::onStart() {
if(current != slowTarget) { if(current != slowTarget) {
float_t m = 6.0f; float_t m = 6.0f;
float_t s = delta * 3.0f; float_t s = delta * 3.0f;
current += glm::vec2(. current += glm::vec2(
mathClamp<float_t>((slowTarget.x - current.x) * s, -m, m), mathClamp<float_t>((slowTarget.x - current.x) * s, -m, m),
mathClamp<float_t>((slowTarget.y - current.y) * s, -m, m) mathClamp<float_t>((slowTarget.y - current.y) * s, -m, m)
); );

View File

@ -19,4 +19,4 @@ set(
include(util/CMakeLists.txt) include(util/CMakeLists.txt)
# Tools # Tools
add_subdirectory(tools) add_subdirectory(prefabtool)

View File

@ -0,0 +1,47 @@
# Copyright (c) 2023 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Texture Build Tool
project(prefabtool VERSION 1.0)
add_executable(prefabtool)
# Sources
target_sources(prefabtool
PRIVATE
${DAWN_SHARED_SOURCES}
${DAWN_TOOL_SOURCES}
PrefabTool.cpp
)
# Includes
target_include_directories(prefabtool
PUBLIC
${DAWN_SHARED_INCLUDES}
${DAWN_TOOL_INCLUDES}
${CMAKE_CURRENT_LIST_DIR}
)
# Definitions
target_compile_definitions(prefabtool
PUBLIC
DAWN_TOOL_INSTANCE=PrefabTool
DAWN_TOOL_HEADER="PrefabTool.hpp"
)
# Libraries
target_link_libraries(prefabtool
PUBLIC
${DAWN_BUILD_HOST_LIBS}
)
# Tool Function
function(tool_prefab target in)
add_custom_target(${target}
COMMAND prefabtool --input="${DAWN_ASSETS_SOURCE_DIR}/${in}"
COMMENT "Generating prefab ${target} from ${in}"
DEPENDS prefabtool
)
add_dependencies(${DAWN_TARGET_NAME} ${target})
endfunction()

View File

@ -0,0 +1,28 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "PrefabTool.hpp"
using namespace Dawn;
std::vector<std::string> PrefabTool::getRequiredFlags() {
return { "input" };
}
std::map<std::string, std::string> PrefabTool::getOptionalFlags() {
return std::map<std::string, std::string>();
}
int32_t PrefabTool::start() {
File input = File(flags["input"]);
if(!input.exists()) {
std::cout << "Input file does not exist!" << std::endl;
return 1;
}
std::cout << "Input: " << input.filename << std::endl;
return 0;
}

View File

@ -0,0 +1,19 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "util/DawnTool.hpp"
#include "util/File.hpp"
namespace Dawn {
class PrefabTool : public DawnTool {
protected:
std::vector<std::string> getRequiredFlags() override;
std::map<std::string, std::string> getOptionalFlags() override;
public:
int32_t start();
};
}

View File

@ -5,9 +5,6 @@
#pragma once #pragma once
#include "dawnsharedlibs.hpp" #include "dawnsharedlibs.hpp"
#include "../../util/file.hpp"
#include "../../util/csv.hpp"
#include "../../util/xml.hpp"
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <vector> #include <vector>

View File

@ -1,26 +1,26 @@
/** // Copyright (c) 2023 Dominic Masters
* Copyright (c) 2021 Dominic Masters //
* // This software is released under the MIT License.
* This software is released under the MIT License. // https://opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
#include "file.hpp" #include "File.hpp"
void fileNormalizeSlashes(char *string) { using namespace Dawn;
char c;
int i = 0;
while(c = string[i++]) { std::string File::normalizeSlashes(std::string str) {
if(c != '\\' && c != '/') continue; size_t i = 0;
string[i-1] = FILE_PATH_SEP; while(i < str.size()) {
auto c = str[i];
if(c == '\\' || c == '/') str[i] = FILE_PATH_SEP;
++i;
} }
return str;
} }
void fileMkdirp(char *path) { void File::mkdirp(std::string path) {
char buffer[FILENAME_MAX]; std::string buffer;
char c; char c;
int i = 0; size_t i = 0;
bool inFile; bool inFile;
bool hasMore; bool hasMore;
@ -28,172 +28,166 @@ void fileMkdirp(char *path) {
hasMore = false; hasMore = false;
while(c = path[i]) { while(c = path[i]) {
if((c == '\\' || c == '/') && i > 0) { if((c == '\\' || c == '/') && i > 0) {
buffer[i] = '\0'; fileMkdir(buffer.c_str(), 0755);
fileMkdir(buffer, 0755);
inFile = false; inFile = false;
hasMore = false; hasMore = false;
buffer[i] = FILE_PATH_SEP; buffer += FILE_PATH_SEP;
i++; i++;
continue; continue;
} }
if(c == '.') inFile = true; if(c == '.') inFile = true;
hasMore = true; hasMore = true;
buffer[i] = c; buffer += c;
i++; i++;
} }
if(!inFile && hasMore) { if(!inFile && hasMore) {
buffer[i] = '\0'; fileMkdir(buffer.c_str(), 0755);
fileMkdir(buffer, 0755);
} }
} }
size_t assetReadString(FILE *file, char *buffer) { //
size_t length;
fseek(file, 0, SEEK_END);// Seek to the end File::File(std::string filename) {
length = ftell(file);// Get our current position (the end) this->filename = File::normalizeSlashes(filename);
fseek(file, 0, SEEK_SET);// Reset the seek
if(buffer == NULL) return length;
return fread(buffer, 1, length, file);// Read all the bytes
} }
int32_t readAhead( bool_t File::open(enum FileMode mode) {
char *bufferIn, int32_t start, assertNull(this->file);
char *bufferOut,
char *needles, int32_t needleCount
) {
int32_t i = start, k = 0, j;
char c;
bool needleFound = false;
if(bufferIn[i] == '\0') return 0; this->mode = mode;
this->file = fopen(
this->filename.c_str(),
mode == FILE_MODE_READ ? "rb" : "wb"
);
while((c = bufferIn[i++]) != '\0') { if(this->file == NULL) return false;
for(j = 0; j < needleCount; j++) {
if(c != needles[j]) continue;
needleFound = true;
}
if(needleFound) break;
if(bufferOut != NULL) bufferOut[k] = c;
k++;
}
if(bufferOut != NULL) bufferOut[k] = '\0'; if(mode == FILE_MODE_READ) {
return k; fseek(this->file, 0, SEEK_END);
} this->length = ftell(this->file);
fseek(this->file, 0, SEEK_SET);
int32_t skipAhead( if(this->length <= 0) {
char *bufferIn, int32_t start, this->close();
char *needles, int32_t needleCount
) {
char c;
int32_t j, k = 0, i = start;
bool needleFound;
while((c = bufferIn[i++]) != '\0') {
needleFound = false;
for(j = 0; j < needleCount; j++) {
if(c != needles[j]) continue;
needleFound = true;
break;
}
if(!needleFound) break;
k++;
}
return k;
}
void fileGetDirectory(char *file, char* buffer) {
char *c, *p;
int32_t i;
p = strrchr(file, FILE_PATH_SEP);
c = file;
i = 0;
do {
buffer[i++] = *c;
} while(++c < p);
buffer[i] = '\0';
}
bool fileListChildren(
char *directory,
char *buffer,
int32_t *count,
uint8_t *types,
char **children
) {
#if defined(_MSC_VER)
WIN32_FIND_DATA fdFile;
HANDLE hFind = NULL;
char sPath[2048];
int32_t i;
// Append wildcard
sprintf(sPath, "%s\\*.*", directory);
// Scan first
if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE) {
printf("Path not found: [%s]\n", directory);
return false; return false;
} }
} else {
this->length = 0;
}
// Iterate return true;
i = 0; }
do {
if(
strcmp(fdFile.cFileName, ".") == 0 ||
strcmp(fdFile.cFileName, "..") == 0
) continue;
// Get Full path. bool_t File::isOpen() {
sprintf(sPath, "%s\\%s", directory, fdFile.cFileName); return this->file != nullptr;
}
//Is the entity a File or Folder? bool_t File::exists() {
if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if(this->file != nullptr) return true;
types[i] = FILE_CHILD_TYPE_DIR; FILE *f = fopen(this->filename.c_str(), "rb");
} else { if(f == NULL || f == nullptr) return false;
types[i] = FILE_CHILD_TYPE_FILE; fclose(f);
} return true;
}
children[i] = buffer + (i * FILE_CHILD_NAME_MAX); void File::close() {
strcpy(children[i], fdFile.cFileName); assertNotNull(this->file);
i++; fclose(this->file);
} while(FindNextFile(hFind, &fdFile)); this->file = nullptr;
}
*count = i; bool_t File::mkdirp() {
return true; File::mkdirp(this->filename);
#else return true;
struct dirent *de; }
DIR *dr;
int32_t i;
// Open Dir bool_t File::readString(std::string *out) {
dr = opendir(directory); assertNotNull(out);
if(dr == NULL) {
printf("Could not open directory");
return false;
}
if(!this->isOpen()) {
if(!this->open(FILE_MODE_READ)) return false;
}
assertTrue(this->mode == FILE_MODE_READ);
out->clear();
// Iterate size_t i = 0;
i = 0; char buffer[FILE_BUFFER_SIZE + 1];// +1 for null term
while ((de = readdir(dr)) != NULL) { while(i != this->length) {
// File or folder? size_t amt = mathMin<size_t>(FILE_BUFFER_SIZE, (this->length - i));
if(de->d_type != DT_REG) continue; auto amtRead = fread(buffer, sizeof(char), amt, this->file);
if(amtRead != amt) return false;
i += amtRead;
buffer[amtRead] = '\0';
out->append(buffer);
}
// Copy into child buffer return true;
children[i] = buffer + (i * FILE_CHILD_NAME_MAX); }
strcpy(children[i], de->d_name);
i++; size_t File::readAhead(char *buffer, size_t max, char needle) {
} assertNotNull(buffer);
if(closedir(dr)) return false; assertTrue(max > 0);
if(!this->isOpen()) {
if(!this->open(FILE_MODE_READ)) return 0;
}
assertTrue(this->mode == FILE_MODE_READ);
// Buffer
size_t pos = ftell(this->file);
size_t amountLeftToRead = mathMin<size_t>(max, this->length - pos);
char temporary[FILE_BUFFER_SIZE];
size_t n = 0;
*count = i; while(amountLeftToRead > 0) {
return true; size_t toRead = mathMin<size_t>(amountLeftToRead, FILE_BUFFER_SIZE);
#endif amountLeftToRead -= toRead;
// Read bytes
size_t read = fread(temporary, sizeof(char), toRead, this->file);
// Read error?
if(toRead != read) return 0;
// Did we read the needle?
size_t i = 0;
while(i < read) {
char c = temporary[i++];
if(c == needle) {
return n;
} else {
buffer[n++] = c;
}
}
}
// Needle was not found.
return -1;
} }
std::string fileNormalizeSlashesNew(std::string str) { bool_t File::writeString(std::string in) {
return str; if(!this->isOpen()) {
if(!this->open(FILE_MODE_WRITE)) return false;
}
assertTrue(this->mode == FILE_MODE_WRITE);
return this->writeRaw((char *)in.c_str(), in.size()) && this->length == in.size();
}
bool_t File::writeRaw(char *data, size_t len) {
if(!this->isOpen()) {
if(!this->open(FILE_MODE_WRITE)) return false;
}
assertTrue(this->mode == FILE_MODE_WRITE);
this->length = fwrite(data, sizeof(char_t), len, this->file);
return true;
}
void File::setPosition(size_t n) {
fseek(this->file, 0, SEEK_SET);
fseek(this->file, n, SEEK_CUR);
}
File::~File() {
if(this->file != nullptr) this->close();
} }

View File

@ -1,17 +1,11 @@
/** // Copyright (c) 2023 Dominic Masters
* Copyright (c) 2021 Dominic Masters //
* // This software is released under the MIT License.
* This software is released under the MIT License. // https://opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
#pragma once #pragma once
#include "dawnsharedlibs.hpp" #include "assert/assert.hpp"
#include "util/mathutils.hpp"
#define FILE_CHILD_TYPE_DIR 0x00
#define FILE_CHILD_TYPE_FILE 0x01
#define FILE_CHILD_NAME_MAX 512
#define FILE_CHILD_COUNT_MAX 64
#if defined(_MSC_VER) #if defined(_MSC_VER)
#include <direct.h> #include <direct.h>
@ -26,51 +20,121 @@
#define FILE_PATH_SEP '/' #define FILE_PATH_SEP '/'
#define fileMkdir(path, perms) mkdir(path, perms) #define fileMkdir(path, perms) mkdir(path, perms)
#endif #endif
#include <errno.h>
void fileNormalizeSlashes(char *string); #define FILE_BUFFER_SIZE 512
void fileMkdirp(char *path); namespace Dawn {
enum FileMode {
FILE_MODE_READ,
FILE_MODE_WRITE
};
size_t assetReadString(FILE *file, char *buffer); class File {
private:
enum FileMode mode;
void fileGetDirectory(char *file, char* buffer); public:
static std::string normalizeSlashes(std::string str);
static void mkdirp(std::string path);
bool fileListChildren( std::string filename;
char *directory, size_t length;
char *buffer, FILE *file = nullptr;
int32_t *count,
uint8_t *types,
char **children
);
/** /**
* Reads ahead to the first instance of the given character you provide. * Constructs a new File interface class.
* *
* @param bufferIn Buffer to scan. * @param filename Filename that you want to interface with.
* @param start Start position within the buffer to scan from (inclusive). */
* @param bufferOut Where to write the temporary data that was read ahead. File(std::string filename);
* @param needles Array of characters to scan for.
* @param needleCount How many elements are within the needles array.
* @return The count of characters skipped.
*/
int32_t readAhead(
char *bufferIn, int32_t start,
char *bufferOut,
char *needles, int32_t needleCount
);
/** /**
* Skips any characters found in the needles. * Opens a connection to the file.
* *
* @param bufferIn Buffer of chars to read. * @param mode File mode to use for this interface.
* @param start Start of the buffer. * @return True if success, otherwise for failure.
* @param needles Needles you are trying to skip. */
* @param needleCount Count of needles in the needles array. bool_t open(enum FileMode mode);
* @return The count of chars to skip ahead.
*/
int32_t skipAhead(
char *bufferIn, int32_t start,
char *needles, int32_t needleCount
);
static std::string fileNormalizeSlashesNew(std::string str); /**
* Returns whether or not the file connection is currently opened.
*
* @return True if the connection is open, otherwise if it's not.
*/
bool_t isOpen();
/**
* Returns whether or not the file exists. Will open the connection if it
* does exist.
*
* @return True if exists, otherwsie if it doesn't.
*/
bool_t exists();
/**
* Closes the currently open interface to the file. Done automatically
* when this object is disposed.
*/
void close();
/**
* Makes all directories above this file's filename.
*
* @return True if successful, otherwise false.
*/
bool_t mkdirp();
/**
* Reads the entire contents of a file to the given output string buffer.
* This is a bit dangerous since the length of the file isn't checked
* against the memory to be consumed.
*
* @param out Pointer to a string where the output data will be stored.
* @return True if the read was successful, otherwise false.
*/
bool_t readString(std::string *out);
/**
* Reads ahead from the current position to a specific needle (character).
*
* @param buffer Buffer to output read chars to.
* @param max Max length of the buffer / amount of chars to read ahead.
* @param needle The character (needle) to look for.
* @return Amount of chars read, or <= 0 on error.
*/
size_t readAhead(
char *buffer,
size_t max,
char needle
);
/**
* Writes the entire contents of a string to a file.
*
* @param in String to write to this file.
* @return True if written successfully, otherwise false.
*/
bool_t writeString(std::string in);
/**
* Write raw bytes to the file.
*
* @param data Data to write.
* @return True if written successfully, otherwise false.
*/
bool_t writeRaw(char *data, size_t );
/**
* Set the position of the cursor of the file reader.
*
* @param pos Position to set.
*/
void setPosition(size_t pos);
/**
* Destruct the File manager.
*/
~File();
};
}