diff --git a/assets/games/pokergame/characters/death/sheet.png b/assets/games/pokergame/characters/death/sheet.png
index d08691aa..2dad46df 100644
Binary files a/assets/games/pokergame/characters/death/sheet.png and b/assets/games/pokergame/characters/death/sheet.png differ
diff --git a/assets/games/pokergame/scripty.docx b/assets/games/pokergame/scripty.docx
index 7cacd8c1..5a13d658 100644
Binary files a/assets/games/pokergame/scripty.docx and b/assets/games/pokergame/scripty.docx differ
diff --git a/assets/games/pokergame/vn/Scene_1.xml b/assets/games/pokergame/vn/Scene_1.xml
index dc5941ae..27814e6e 100644
--- a/assets/games/pokergame/vn/Scene_1.xml
+++ b/assets/games/pokergame/vn/Scene_1.xml
@@ -11,7 +11,7 @@
-
+
@@ -26,9 +26,18 @@
-->
+
+
-
+
+
+ Hello World English
+
+
+ Hello Japanese
+
+
-
+
\ No newline at end of file
diff --git a/src/dawnpokergame/CMakeLists.txt b/src/dawnpokergame/CMakeLists.txt
index f48fd997..fac005f4 100644
--- a/src/dawnpokergame/CMakeLists.txt
+++ b/src/dawnpokergame/CMakeLists.txt
@@ -39,7 +39,7 @@ tool_truetype(truetype_alice ${DIR_GAME_ASSETS}/font/Alice-Regular.ttf truetype_
tool_audio(audio_test borrowed/sample_short.wav)
-tool_vnscene(vnscene_1 ${DIR_GAME_ASSETS}/vn/Scene_1.xml)
+tool_vnscene(Scene_1 ${DIR_GAME_ASSETS}/vn/Scene_1.xml)
add_dependencies(${DAWN_TARGET_NAME}
locale_poker
@@ -53,5 +53,5 @@ add_dependencies(${DAWN_TARGET_NAME}
audio_test
- vnscene_1
+ Scene_1
)
\ No newline at end of file
diff --git a/src/dawnpokergame/game/DawnGame.cpp b/src/dawnpokergame/game/DawnGame.cpp
index 39f57f40..74ce541e 100644
--- a/src/dawnpokergame/game/DawnGame.cpp
+++ b/src/dawnpokergame/game/DawnGame.cpp
@@ -4,7 +4,7 @@
// https://opensource.org/licenses/MIT
#include "DawnGame.hpp"
-#include "scenes/vnscene_1.hpp"
+#include "scenes/Scene_1.hpp"
using namespace Dawn;
@@ -24,7 +24,7 @@ int32_t DawnGame::init() {
this->renderManager.init();
this->audioManager.init();
- this->scene = new vnscene_1(this);
+ this->scene = new Scene_1(this);
return DAWN_GAME_INIT_RESULT_SUCCESS;
}
diff --git a/src/dawnpokergame/scenes/Scene_1.hpp b/src/dawnpokergame/scenes/Scene_1.hpp
deleted file mode 100644
index 2c2e7d34..00000000
--- a/src/dawnpokergame/scenes/Scene_1.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2022 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "visualnovel/scene/SimpleVNScene.hpp"
-#include "scenes/Scene_2.hpp"
-#include "prefabs/characters/DeathPrefab.hpp"
-#include "visualnovel/events/characters/VisualNovelFadeCharacterEvent.hpp"
-#include "visualnovel/events/characters/VisualNovelTransformItemEvent.hpp"
-#include "visualnovel/events/timing/VisualNovelBatchEvent.hpp"
-
-namespace Dawn {
- class Scene_1 : public SimpleVNScene {
- protected:
- DeathPrefab *death;
-
- void vnStage() override {
-
- this->death = DeathPrefab::create(this);
- this->death->material->color.a = 0;
- }
-
- void onSceneEnded() {
- auto scene = new Scene_2(this->game);
- game->assetManager.queueSwap(
- scene->getRequiredAssets(), this->getRequiredAssets()
- );
- game->assetManager.syncLoad();
- scene->stage();
- this->game->sceneCutover(scene);
- }
-
- public:
- Scene_1(DawnGame *game) : SimpleVNScene(game) {
-
- }
-
- std::vector getRequiredAssets() override {
- auto man = &this->game->assetManager;
- std::vector assets = SimpleVNScene::getRequiredAssets();
- vectorAppend(&assets, DeathPrefab::getRequiredAssets(man));
- assets.push_back(man->get("audio_test"));
- return assets;
- }
-
- IVisualNovelEvent * getVNEvent() override {
- auto start = new VisualNovelPauseEvent(vnManager, 0.1f);
- start
- ->then(new VisualNovelTextboxEvent(vnManager, this->death->vnCharacter, this->death->emotionHappy, "scene.1.1"))
- ->then(new VisualNovelFadeCharacterEvent(vnManager, this->death->vnCharacter, true, &easeOutQuad, 1.0f))
- // ->then(new VisualNovelCallbackEvent(vnManager, this, &Scene_1::onSceneEnded))
- ;
- return start;
- }
- };
-}
\ No newline at end of file
diff --git a/src/dawntools/util/CodeGen.hpp b/src/dawntools/util/CodeGen.hpp
new file mode 100644
index 00000000..2fcd15e8
--- /dev/null
+++ b/src/dawntools/util/CodeGen.hpp
@@ -0,0 +1,100 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "dawnsharedlibs.hpp"
+
+namespace Dawn {
+ struct ClassGenInfo {
+ std::vector includes;
+ std::string clazz = "Unknown";
+ std::string extend = "";
+ std::string constructorArgs = "";
+ std::string extendArgs = "";
+
+ std::vector protectedCode;
+ std::vector protectedProperties;
+
+ std::vector publicCode;
+ std::vector publicProperties;
+ };
+
+ struct MethodGenInfo {
+ std::string name;
+ std::string type = "void";
+ std::vector body;
+ std::string args = "";
+ bool_t isStatic = false;
+ bool_t isOverride = false;
+ };
+
+ class CodeGen {
+ protected:
+ static void line(
+ std::vector *out,
+ std::string contents,
+ std::string tabs
+ ) {
+ out->push_back(tabs + contents);
+ }
+
+ static void lines(
+ std::vector *out,
+ std::vector lines,
+ std::string tabs
+ ) {
+ auto itLine = lines.begin();
+ while(itLine != lines.end()) {
+ line(out, *itLine, tabs);
+ ++itLine;
+ }
+ }
+
+ static void classGen(
+ std::vector *out,
+ struct ClassGenInfo info
+ ) {
+ std::vector buffer;
+
+ line(out, "#pragma once", "");
+ line(out, "", "");
+ if(info.includes.size() > 0) {
+ lines(out, info.includes, "");
+ line(out, "", "");
+ }
+ line(out, "namespace Dawn {", "");
+ line(out, "class " + info.clazz + (info.extend.size() == 0 ? "{" : " : public " + info.extend + " {" ), " ");
+ if(info.protectedCode.size() > 0) {
+ line(out, "protected:", " ");
+ lines(out, info.protectedProperties, " ");
+ line(out, "", " ");
+ lines(out, info.protectedCode, " ");
+ }
+
+ if(info.publicCode.size() > 0 || info.constructorArgs.size() > 0) {
+ line(out, "public:", " ");
+ lines(out, info.publicProperties, " ");
+ line(out, "", " ");
+ line(out, info.clazz + "(" + info.constructorArgs + ")" + (info.extend.size() > 0 ? " : " + info.extend + "(" + info.extendArgs + ")" : "") + " {", " ");
+ line(out, "}", " ");
+ if(info.publicCode.size() > 0) {
+ line(out, "", " ");
+ lines(out, info.publicCode, " ");
+ }
+ }
+ line(out, "};", " ");
+ line(out, "}", "");
+ }
+
+ static void methodGen(
+ std::vector *out,
+ struct MethodGenInfo info
+ ) {
+ line(out, info.type + " " + info.name + "(" + info.args + ") " + ( info.isOverride ? "override" : "" ) + "{", "");
+ lines(out, info.body, " ");
+ line(out, "}", "");
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/util/File.cpp b/src/dawntools/util/File.cpp
index 8423f99d..fa0ed16f 100644
--- a/src/dawntools/util/File.cpp
+++ b/src/dawntools/util/File.cpp
@@ -63,13 +63,13 @@ bool_t File::readString(std::string *out) {
out->clear();
size_t i = 0;
- char buffer[FILE_BUFFER_SIZE + 1];
+ char buffer[FILE_BUFFER_SIZE + 1];// +1 for null term
while(i != this->length) {
size_t amt = mathMin(FILE_BUFFER_SIZE, (this->length - i));
auto amtRead = fread(buffer, sizeof(char), amt, this->file);
if(amtRead != amt) return false;
i += amtRead;
- buffer[amtRead + 1] = '\0';
+ buffer[amtRead] = '\0';
out->append(buffer);
}
diff --git a/src/dawntools/util/XmlParser.hpp b/src/dawntools/util/XmlParser.hpp
new file mode 100644
index 00000000..0221c997
--- /dev/null
+++ b/src/dawntools/util/XmlParser.hpp
@@ -0,0 +1,72 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/Xml.hpp"
+
+namespace Dawn {
+ template
+ class XmlParser {
+ protected:
+ virtual std::vector getRequiredAttributes() = 0;
+ virtual std::map getOptionalAttributes() = 0;
+ virtual int32_t onParse(
+ Xml *node,
+ std::map values,
+ T *output,
+ std::string *error
+ ) = 0;
+
+ public:
+ static std::string parseDuration(std::string duration) {
+ std::string dur = duration;
+ if(dur.find('.') == std::string::npos) dur += ".0";
+ return dur + "f";
+ }
+
+ static std::string parseEase(std::string e) {
+ if(e == "out-quad") return "&easeOutQuad";
+ if(e == "linear") return "&easeLinear";
+ return "";
+ }
+
+ int32_t parse(Xml *xml, T *output, std::string *error) {
+ std::map values;
+
+ // First get the required attributes
+ auto required = this->getRequiredAttributes();
+ auto itRequired = required.begin();
+ while(itRequired != required.end()) {
+ auto s = *itRequired;
+ auto attr = xml->attributes.find(s);
+ if(attr == xml->attributes.end()) {
+ std::cout << "Missing required attribute \"" << s << "\"" << std::endl;
+ return 1;
+ }
+ values[s] = attr->second;
+ ++itRequired;
+ }
+
+ // Now get the optional attributes
+ auto optional = this->getOptionalAttributes();
+ auto itOptional = optional.begin();
+ while(itOptional != optional.end()) {
+ auto key = itOptional->first;
+ auto defaultValue = itOptional->second;
+
+ auto attr = xml->attributes.find(key);
+ if(attr == xml->attributes.end()) {
+ values[key] = defaultValue;
+ } else {
+ values[key] = attr->second;
+ }
+ ++itOptional;
+ }
+
+ // Now send to parser
+ return this->onParse(xml, values, output, error);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/CMakeLists.txt b/src/dawntools/visualnovel/vnscenegen/CMakeLists.txt
index 36fbcbfa..b4ec3631 100644
--- a/src/dawntools/visualnovel/vnscenegen/CMakeLists.txt
+++ b/src/dawntools/visualnovel/vnscenegen/CMakeLists.txt
@@ -32,7 +32,4 @@ target_compile_definitions(vnscenegen
target_link_libraries(vnscenegen
PUBLIC
${DAWN_BUILD_HOST_LIBS}
-)
-
-# Subdirs
-add_subdirectory(parse)
\ No newline at end of file
+)
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/VnSceneGen.cpp b/src/dawntools/visualnovel/vnscenegen/VnSceneGen.cpp
index 22c4fa4d..eec43f5e 100644
--- a/src/dawntools/visualnovel/vnscenegen/VnSceneGen.cpp
+++ b/src/dawntools/visualnovel/vnscenegen/VnSceneGen.cpp
@@ -23,111 +23,24 @@ int32_t VnSceneGen::start() {
// Parse XML
Xml xml = Xml::load(buffer);
-
- // First, read the header information
- struct HeaderInformation header;
- auto itXml = xml.children.begin();
- while(itXml != xml.children.end()) {
- auto child = *itXml;
- if(child->node != "head") {
- ++itXml;
- continue;
- }
-
- auto ret = parseHeader(&header, child);
- if(ret != 0) return ret;
- break;
- }
-
- // Validate header
- if(header.sceneInfo.name.size() == 0 || header.sceneInfo.type.size() == 0) {
- std::cout << "VN Scene header wasn't parsed properly." << std::endl;
- return 1;
+ std::string error;
+ struct RootInformation info;
+ auto ret = (RootParser()).parse(&xml, &info, &error);
+ if(ret != 0) {
+ std::cout << error << std::endl;
+ return ret;
}
- // Parse and load events.
- std::string bufferEvents;
- itXml = xml.children.begin();
- while(itXml != xml.children.end()) {
- auto events = *itXml;
- if(events->node != "events") {
- ++itXml;
- continue;
- }
- bufferEvents += "\n start\n";
+ std::vector lines;
+ RootGen::generate(&lines, &info, "");
- auto itChildren = events->children.begin();
- while(itChildren != events->children.end()) {
- auto evt = *itChildren;
- if(evt->node != "scene-transition") {
- auto evtParsed = parseEvent(&header, evt);
- if(evtParsed.size() == 0) return 1;
- bufferEvents += " ->then(" + evtParsed + ")\n";
- }
- ++itChildren;
- }
- bufferEvents += " ;\n";
- ++itXml;
- }
-
- // Now render output to file.
+ // Generate buffer
std::string bufferOut;
- bufferOut += "#pragma once\n\n";
- auto itInclude = header.includes.begin();
- while(itInclude != header.includes.end()) {
- bufferOut += "#include \"" + (*itInclude) + "\"\n";
- ++itInclude;
+ auto itLine = lines.begin();
+ while(itLine != lines.end()) {
+ bufferOut += *itLine + "\n";
+ ++itLine;
}
- bufferOut += "\nnamespace Dawn{\n";
- bufferOut += " class " + header.sceneInfo.name + " : public " + header.sceneInfo.type + " {\n";
- bufferOut += " protected:\n";
-
- // Characters (As properties)
- auto itCharacters = header.characters.begin();
- while(itCharacters != header.characters.end()) {
- auto c = *itCharacters;
- bufferOut += " " + c.clazz + " *" + c.name + ";\n";
- ++itCharacters;
- }
- bufferOut += "\n void vnStage() override {\n";
- bufferOut += " " + header.sceneInfo.type + "::vnStage();\n";
-
- // Initialize the characters
- itCharacters = header.characters.begin();
- while(itCharacters != header.characters.end()) {
- auto c = *itCharacters;
- bufferOut += " this->" + c.name + " = " + c.clazz + "::create(this);\n";
- ++itCharacters;
- }
-
- bufferOut += " }\n";
-
- bufferOut += "\n public:\n";
- bufferOut += " " + header.sceneInfo.name + "(DawnGame *game) : " + header.sceneInfo.type + "(game) {\n";
- bufferOut += " }\n";
-
- // Assets
- bufferOut += "\n std::vector getRequiredAssets() override{\n";
- bufferOut += " auto man = &this->game->assetManager;\n";
- bufferOut += " std::vector assets = " + header.sceneInfo.type + "::getRequiredAssets();\n";
- itCharacters = header.characters.begin();
- while(itCharacters != header.characters.end()) {
- auto c = *itCharacters;
- bufferOut += " vectorAppend(&assets, " + c.clazz + "::getRequiredAssets(man));\n";
- ++itCharacters;
- }
- bufferOut += " return assets;\n";
- bufferOut += " }\n";
-
- // VN Events
- bufferOut += "\n IVisualNovelEvent * getVNEvent() override {\n";
- bufferOut += " auto start = new VisualNovelPauseEvent(vnManager, 0.01f);\n";
- bufferOut += bufferEvents;
- bufferOut += "\n return start;\n";
- bufferOut += " }\n";
-
- bufferOut += " };\n";
- bufferOut += "}";
// Finished with XML data, now we can write data out.
File fileOut(this->args[2] + ".hpp");
diff --git a/src/dawntools/visualnovel/vnscenegen/VnSceneGen.hpp b/src/dawntools/visualnovel/vnscenegen/VnSceneGen.hpp
index 05b5e97c..8f5a1a06 100644
--- a/src/dawntools/visualnovel/vnscenegen/VnSceneGen.hpp
+++ b/src/dawntools/visualnovel/vnscenegen/VnSceneGen.hpp
@@ -6,14 +6,13 @@
#pragma once
#include "util/DawnTool.hpp"
#include "util/File.hpp"
-#include "parse/VnSceneParseEvent.hpp"
-#include "parse/VnSceneParseHeader.hpp"
+#include "parse/root.hpp"
namespace Dawn {
class VnSceneGen : public DawnTool {
protected:
public:
- int32_t start() override;
+ int32_t start();
};
}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/CMakeLists.txt b/src/dawntools/visualnovel/vnscenegen/parse/CMakeLists.txt
deleted file mode 100644
index 10679721..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) 2023 Dominic Msters
-#
-# This software is released under the MIT License.
-# https://opensource.org/licenses/MIT
-
-# Sources
-target_sources(vnscenegen
- PRIVATE
- VnSceneParseAsset.cpp
- VnSceneParseCharacter.cpp
- VnSceneParseEvent.cpp
- VnSceneParseScene.cpp
- VnSceneParseHeader.cpp
- VnSceneParseInclude.cpp
-)
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseAsset.cpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseAsset.cpp
deleted file mode 100644
index e42fd7c0..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseAsset.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "VnSceneParseAsset.hpp"
-
-using namespace Dawn;
-
-int32_t parseAsset(std::vector *assets, Xml *node) {
- auto attrType = node->attributes.find("type");
- if(attrType == node->attributes.end()) {
- std::cout << "VN Scene Asset missing type attribute" << std::endl;
- return 1;
- }
- auto attrName = node->attributes.find("name");
- if(attrName == node->attributes.end()) {
- std::cout << "VN Scene Asset missing name attribute" << std::endl;
- return 1;
- }
-
- struct Asset ass;
- ass.type = attrType->second;
- ass.name = attrType->second;
- assets->push_back(ass);
- return 0;
-}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseAsset.hpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseAsset.hpp
deleted file mode 100644
index c4ac27da..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseAsset.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "util/Xml.hpp"
-
-using namespace Dawn;
-
-struct Asset {
- std::string type;
- std::string name;
-};
-
-int32_t parseAsset(std::vector *assets, Xml *node);
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseCharacter.cpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseCharacter.cpp
deleted file mode 100644
index 6a841860..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseCharacter.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "VnSceneParseCharacter.hpp"
-
-using namespace Dawn;
-
-int32_t parseCharacter(std::vector *characters, Xml *node) {
- auto attrClass = node->attributes.find("class");
- if(attrClass == node->attributes.end()) {
- std::cout << "Character definition is missing class" << std::endl;
- return 1;
- }
-
- auto attrName = node->attributes.find("name");
- if(attrName == node->attributes.end()) {
- std::cout << "Character definition is missing name" << std::endl;
- }
-
- struct CharacterInformation character;
- character.clazz = attrClass->second;
- character.name = attrName->second;
- characters->push_back(character);
- return 0;
-}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseCharacter.hpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseCharacter.hpp
deleted file mode 100644
index 1a5b9b48..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseCharacter.hpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "util/Xml.hpp"
-
-using namespace Dawn;
-
-struct CharacterInformation {
- std::string clazz;
- std::string name;
-};
-
-int32_t parseCharacter(
- std::vector *characters,
- Xml *node
-);
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseEvent.cpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseEvent.cpp
deleted file mode 100644
index 3708ae3c..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseEvent.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "VnSceneParseEvent.hpp"
-
-using namespace Dawn;
-
-std::string parseEase(std::string e) {
- if(e == "out-quad") return "easeOutQuad";
- std::cout << "Invalid ease defined" << std::endl;
- return "";
-}
-
-std::string parseEvent(struct HeaderInformation *header, Xml *evt) {
- std::string buffer;
- std::string node(evt->node);
-
- if(node == "pause") {
- // Pause
- header->includes.push_back("visualnovel/events/timing/VisualNovelPauseEvent.hpp");
-
- auto attrDuration = evt->attributes.find("duration");
- if(attrDuration == evt->attributes.end()) {
- std::cout << "Pause event is missing duration argument." << std::endl;
- return "";
- }
- auto dur = attrDuration->second;
- if(dur.find('.') == std::string::npos) dur += ".0";
- buffer += "new VisualNovelPauseEvent(vnManager, " + dur + "f)";
-
-
- } else if(node == "text") {
- // Text
- header->includes.push_back("visualnovel/events/VisualNovelTextboxEvent.hpp");
-
- auto attrChar = evt->attributes.find("character");
- if(attrChar == evt->attributes.end()) {
- std::cout << "Text event missing character attribute." << std::endl;
- return "";
- }
-
- auto attrEmotion = evt->attributes.find("emotion");
- if(attrEmotion == evt->attributes.end()) {
- std::cout << "Text event missing emotion attribute." << std::endl;
- return "";
- }
-
- auto attrString = evt->attributes.find("string");
- if(attrString == evt->attributes.end()) {
- std::cout << "Text event missing string attribute." << std::endl;
- return "";
- }
-
- std::string emo = attrEmotion->second;
- emo[0] = toupper(emo[0]);
-
- buffer += "new VisualNovelTextboxEvent(vnManager, ";
- buffer += "this->" + attrChar->second + "->vnCharacter, ";
- buffer += "this->" + attrChar->second + "->emotion" + emo + ", ";
- buffer += "\"" + attrString->second + "\"" ;
- buffer += ")";
-
-
- } else if(node == "character-fade") {
- // Character Fade
- header->includes.push_back("visualnovel/events/characters/VisualNovelFadeCharacterEvent.hpp");
- auto attrChar = evt->attributes.find("character");
- auto attrDuration = evt->attributes.find("duration");
- auto attrEase = evt->attributes.find("ease");
- auto attrFade = evt->attributes.find("fade");
-
- if(attrChar == evt->attributes.end()) {
- std::cout << "Character fade event missing character attribute." << std::endl;
- return "";
- }
-
- std::string character = attrChar->second;
- std::string easeIn = "true";
- std::string ease = "easeLinear";
- std::string duration = "1.0";
-
- if(attrFade != evt->attributes.end()) easeIn = attrFade->second == "in" ? "true" : "false";
-
- if(attrDuration != evt->attributes.end()) duration = attrDuration->second;
- if(duration.find('.') == std::string::npos) duration += ".0";
-
- if(attrEase != evt->attributes.end()) {
- ease = parseEase(attrEase->second);
- if(ease.size() == 0) return "";
- }
-
- buffer += "new VisualNovelFadeCharacterEvent(vnManager, ";
- buffer += "this->" + character + "->vnCharacter, ";
- buffer += easeIn + ", ";
- buffer += "&" + ease + ", ";
- buffer += duration + "f";
- buffer += ")";
- } else if(node == "scene-transition") {
- buffer += " ";
- }
-
- return buffer;
-}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseEvent.hpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseEvent.hpp
deleted file mode 100644
index ee444d8d..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseEvent.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "util/Xml.hpp"
-#include "parse/VnSceneParseHeader.hpp"
-
-using namespace Dawn;
-
-std::string parseEvent(struct HeaderInformation *header, Xml *evt);
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseHeader.cpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseHeader.cpp
deleted file mode 100644
index c19c588b..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseHeader.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "VnSceneParseHeader.hpp"
-
-using namespace Dawn;
-
-int32_t parseHeader(struct HeaderInformation *info, Xml *node) {
- auto itChildren = node->children.begin();
- while(itChildren != node->children.end()) {
- auto c = *itChildren;
- int32_t ret = 0;
-
- if(c->node == "include") {
- ret = parseInclude(&info->includes, c);
- } else if(c->node == "character") {
- ret = parseCharacter(&info->characters, c);
- } else if(c->node == "scene") {
- ret = parseScene(&info->sceneInfo, c);
- } else if (c->node == "asset") {
- ret = parseAsset(&info->assets, c);
- } else {
- std::cout << "Parsing VN Scene header, unknown node " << c->node << std::endl;
- }
- if(ret != 0) return ret;
- ++itChildren;
- }
- return 0;
-}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseHeader.hpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseHeader.hpp
deleted file mode 100644
index 530bad8f..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseHeader.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "util/Xml.hpp"
-#include "parse/VnSceneParseCharacter.hpp"
-#include "parse/VnSceneParseInclude.hpp"
-#include "parse/VnSceneParseScene.hpp"
-#include "parse/VnSceneParseAsset.hpp"
-
-using namespace Dawn;
-
-struct HeaderInformation {
- std::vector includes;
- std::vector characters;
- std::vector assets;
- struct SceneInformation sceneInfo;
-};
-
-int32_t parseHeader(struct HeaderInformation *info, Xml *node);
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseInclude.cpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseInclude.cpp
deleted file mode 100644
index 7a69bf17..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseInclude.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "VnSceneParseInclude.hpp"
-
-using namespace Dawn;
-
-int32_t parseInclude(std::vector *includes, Xml *node) {
- auto attrPath = node->attributes.find("path");
- if(attrPath == node->attributes.end()) {
- std::cout << "Missing include path in VN Header Defintions." << std::endl;
- return 1;
- }
-
- includes->push_back(attrPath->second);
- return 0;
-}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseInclude.hpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseInclude.hpp
deleted file mode 100644
index 8e310af2..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseInclude.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "util/Xml.hpp"
-
-using namespace Dawn;
-
-int32_t parseInclude(std::vector *includes, Xml *node);
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseScene.cpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseScene.cpp
deleted file mode 100644
index 2c342b68..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseScene.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "VnSceneParseScene.hpp"
-
-using namespace Dawn;
-
-int32_t parseScene(struct SceneInformation *info, Xml *node) {
- auto attrName = node->attributes.find("name");
- if(attrName == node->attributes.end()) {
- std::cout << "VN Scene definition is missing name attribute" << std::endl;
- return 1;
- }
- info->name = attrName->second;
-
- auto attrType = node->attributes.find("type");
- if(attrType == node->attributes.end()) {
- info->type = "SimpleVNScene";
- } else {
- info->type = attrType->second;
- }
- return 0;
-}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseScene.hpp b/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseScene.hpp
deleted file mode 100644
index 244c956b..00000000
--- a/src/dawntools/visualnovel/vnscenegen/parse/VnSceneParseScene.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "util/Xml.hpp"
-
-using namespace Dawn;
-
-struct SceneInformation {
- std::string type;
- std::string name;
-};
-
-int32_t parseScene(struct SceneInformation *info, Xml *node);
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/asset.hpp b/src/dawntools/visualnovel/vnscenegen/parse/asset.hpp
new file mode 100644
index 00000000..4951f0b1
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/asset.hpp
@@ -0,0 +1,56 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+#include "util/CodeGen.hpp"
+
+namespace Dawn {
+ struct AssetInformation {
+ std::string type;
+ std::string name;
+ };
+
+ class AssetParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{
+ "name",
+ "type"
+ };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct AssetInformation *out,
+ std::string *error
+ ) {
+ out->name = values["name"];
+ out->type = values["type"];
+ return 0;
+ }
+
+ std::string convert(struct AssetInformation info) {
+ std::string out;
+ return out;
+ }
+ };
+
+ class AssetGen : public CodeGen {
+ public:
+ static void generate(
+ std::vector *out,
+ struct AssetInformation *info,
+ std::string tabs
+ ) {
+ return line(out, "// Asset will be generated here", tabs);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/character.hpp b/src/dawntools/visualnovel/vnscenegen/parse/character.hpp
new file mode 100644
index 00000000..ea2d81c6
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/character.hpp
@@ -0,0 +1,77 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+#include "util/CodeGen.hpp"
+
+namespace Dawn {
+ struct CharacterInformation {
+ std::string clazz;
+ std::string name;
+ };
+
+ class CharacterParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{
+ "class",
+ "name"
+ };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct CharacterInformation *out,
+ std::string *error
+ ) {
+ out->clazz = values["class"];
+ out->name = values["name"];
+
+ if(out->clazz.size() == 0) {
+ *error = "Character class cannot be empty.";
+ return 1;
+ }
+ if(out->name.size() == 0) {
+ *error = "Character name cannot be empty.";
+ return 1;
+ }
+
+ return 0;
+ }
+ };
+
+ class CharacterGen : public CodeGen {
+ public:
+ static void generateProperty(
+ std::vector *out,
+ struct CharacterInformation info,
+ std::string tabs
+ ) {
+ line(out, info.clazz + " *" + info.name + ";", tabs);
+ }
+
+ static void generateInitializer(
+ std::vector *out,
+ struct CharacterInformation info,
+ std::string tabs
+ ) {
+ line(out, "this->" + info.name + " = " + info.clazz + "::create(this);", tabs);
+ }
+
+ static void generateAssets(
+ std::vector *out,
+ struct CharacterInformation info,
+ std::string tabs
+ ) {
+ line(out, "vectorAppend(&assets, " + info.clazz + "::getRequiredAssets(man));", "");
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/event/characterfadeevent.hpp b/src/dawntools/visualnovel/vnscenegen/parse/event/characterfadeevent.hpp
new file mode 100644
index 00000000..48becb8d
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/event/characterfadeevent.hpp
@@ -0,0 +1,77 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+#include "util/CodeGen.hpp"
+
+namespace Dawn {
+ struct CharacterFadeEventInfo {
+ std::string character;
+ std::string duration;
+ std::string ease;
+ std::string fade;
+ std::string include;
+ };
+
+ class CharacterFadeParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{
+ "character"
+ };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map{
+ { "fade", "in" },
+ { "ease", "linear" },
+ { "duration", "1" }
+ };
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct CharacterFadeEventInfo *out,
+ std::string *error
+ ) {
+ out->character = values["character"];
+ out->duration = parseDuration(values["duration"]);
+ out->ease = parseEase(values["ease"]);
+ out->fade = values["fade"] == "in" ? "true" : "false";
+ out->include = "visualnovel/events/characters/VisualNovelFadeCharacterEvent.hpp";
+
+ if(out->ease.size() == 0) {
+ *error = "Invalid ease";
+ return 1;
+ }
+
+ return 0;
+ }
+ };
+
+
+ class CharacterFadeGen : public CodeGen {
+ public:
+ static void generate(
+ std::vector *out,
+ struct CharacterFadeEventInfo *info,
+ std::string tabs = ""
+ ) {
+ line(out, "new VisualNovelFadeCharacterEvent(vnManager,", tabs + " ");
+ line(out, "this->" + info->character + "->vnCharacter,", tabs + " ");
+ line(out, info->fade + ",", tabs + " ");
+ line(out, info->ease + ",", tabs + " ");
+ line(out, info->duration, tabs + " ");
+ line(out, ")", tabs);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/event/pauseevent.hpp b/src/dawntools/visualnovel/vnscenegen/parse/event/pauseevent.hpp
new file mode 100644
index 00000000..6eb4b1dc
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/event/pauseevent.hpp
@@ -0,0 +1,48 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+#include "util/CodeGen.hpp"
+
+namespace Dawn {
+ struct PauseEventInfo {
+ std::string duration;
+ std::string include;
+ };
+
+ class PauseEventParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{ "duration" };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct PauseEventInfo *out,
+ std::string *error
+ ) {
+ out->duration = parseDuration(values["duration"]);
+ out->include = "visualnovel/events/timing/VisualNovelPauseEvent.hpp";
+ return 0;
+ }
+ };
+
+ class PauseEventGen : public CodeGen {
+ public:
+ static void generate(
+ std::vector *out,
+ struct PauseEventInfo *info,
+ std::string tabs = ""
+ ) {
+ line(out, "new VisualNovelPauseEvent(vnManager, " + info->duration + ")", tabs);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/event/textevent.hpp b/src/dawntools/visualnovel/vnscenegen/parse/event/textevent.hpp
new file mode 100644
index 00000000..be45a7a2
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/event/textevent.hpp
@@ -0,0 +1,100 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+#include "util/CodeGen.hpp"
+
+namespace Dawn {
+ struct TextStringInfo {
+ std::string lang;
+ std::string text;
+ };
+
+ struct TextEventInfo {
+ std::string character;
+ std::string emotion;
+ std::vector strings;
+
+ std::string key = "scene.1.1";
+ };
+
+ class TextStringParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{ "lang" };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct TextStringInfo *out,
+ std::string *error
+ ) {
+ out->lang = values["lang"];
+ out->text = node->value;
+ return 0;
+ }
+ };
+
+ class TextEventParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{
+ "character",
+ "emotion"
+ };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct TextEventInfo *out,
+ std::string *error
+ ) {
+ int32_t ret = 0;
+ out->character = values["character"];
+ out->emotion = values["emotion"];
+
+ auto itChildren = node->children.begin();
+ while(itChildren != node->children.end()) {
+ auto c = *itChildren;
+ if(c->node == "string") {
+ struct TextStringInfo str;
+ ret = (TextStringParser()).parse(c, &str, error);
+ out->strings.push_back(str);
+ }
+ ++itChildren;
+ }
+ return ret;
+ }
+ };
+
+ class TextEventGen : public CodeGen {
+ public:
+ static void generate(
+ std::vector *out,
+ struct TextEventInfo *info,
+ std::string tabs = ""
+ ) {
+ std::string emo = info->emotion;
+ emo[0] = toupper(emo[0]);
+
+ line(out, "new VisualNovelTextboxEvent(vnManager,", tabs);
+ line(out, "this->" + info->character + "->vnCharacter, ", tabs + " ");
+ line(out, "this->" + info->character + "->emotion" + emo + ", ", tabs + " ");
+ line(out, "\"" + info->key + "\"", tabs + " ");
+ line(out, ")", tabs);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/events.hpp b/src/dawntools/visualnovel/vnscenegen/parse/events.hpp
new file mode 100644
index 00000000..d727c88b
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/events.hpp
@@ -0,0 +1,109 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+#include "parse/event/textevent.hpp"
+#include "parse/event/characterfadeevent.hpp"
+#include "parse/event/pauseevent.hpp"
+
+namespace Dawn {
+ enum EventType {
+ EVENT_TYPE_TEXT,
+ EVENT_TYPE_CHARACTER_FADE,
+ EVENT_TYPE_PAUSE
+ };
+
+ struct EventsInformation {
+ std::map eventTypes;
+ std::map textEvents;
+ std::map characterFadeEvents;
+ std::map pauseEvents;
+ std::vector includes;
+ };
+
+ class EventsParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{
+ };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct EventsInformation *out,
+ std::string *error
+ ) {
+ int32_t ret = 0;
+ int32_t i = 0;
+ auto itChildren = node->children.begin();
+ while(itChildren != node->children.end()) {
+ auto c = *itChildren;
+
+ if(c->node == "text") {
+ struct TextEventInfo textEvent;
+ ret = (TextEventParser()).parse(c, &textEvent, error);
+ out->eventTypes[i] = EVENT_TYPE_TEXT;
+ out->textEvents[i++] = textEvent;
+
+ } else if(c->node == "character-fade") {
+ struct CharacterFadeEventInfo charFadeEvent;
+ ret = (CharacterFadeParser()).parse(c, &charFadeEvent, error);
+ out->eventTypes[i] = EVENT_TYPE_CHARACTER_FADE;
+ out->characterFadeEvents[i++] = charFadeEvent;
+ out->includes.push_back(charFadeEvent.include);
+
+ } else if(c->node == "pause") {
+ struct PauseEventInfo pauseEvent;
+ ret = (PauseEventParser()).parse(c, &pauseEvent, error);
+ out->eventTypes[i] = EVENT_TYPE_PAUSE;
+ out->pauseEvents[i++] = pauseEvent;
+ out->includes.push_back(pauseEvent.include);
+
+ }
+
+ ++itChildren;
+ }
+
+ return ret;
+ }
+ };
+
+ class EventsGen : public CodeGen {
+ public:
+ static void generate(
+ std::vector *out,
+ struct EventsInformation *info,
+ std::string tabs
+ ) {
+ auto itEvents = info->eventTypes.begin();
+ while(itEvents != info->eventTypes.end()) {
+ auto e = *itEvents;
+ line(out, "->then(", tabs);
+ switch(e.second) {
+ case EVENT_TYPE_TEXT:
+ TextEventGen::generate(out, &info->textEvents[e.first], tabs + " ");
+ break;
+
+ case EVENT_TYPE_CHARACTER_FADE:
+ CharacterFadeGen::generate(out, &info->characterFadeEvents[e.first], tabs + " ");
+ break;
+
+ case EVENT_TYPE_PAUSE:
+ PauseEventGen::generate(out, &info->pauseEvents[e.first], tabs + " ");
+ break;
+
+ }
+ line(out, ")", tabs);
+ ++itEvents;
+ }
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/header.hpp b/src/dawntools/visualnovel/vnscenegen/parse/header.hpp
new file mode 100644
index 00000000..097fe744
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/header.hpp
@@ -0,0 +1,67 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "parse/include.hpp"
+#include "parse/character.hpp"
+#include "parse/scene.hpp"
+#include "parse/asset.hpp"
+
+namespace Dawn {
+ struct HeaderInformation {
+ std::vector includes;
+ std::vector characters;
+ std::vector assets;
+ std::map> languages;
+ struct SceneInformation scene;
+ };
+
+ class HeaderParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector();
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct HeaderInformation *out,
+ std::string *error
+ ) {
+ int32_t ret = 0;
+ auto itChildren = node->children.begin();
+ while(itChildren != node->children.end()) {
+ auto c = *itChildren;
+
+ if(c->node == "include") {
+ ret = (IncludeParser()).parse(c, &out->includes, error);
+
+ } else if (c->node == "character") {
+ struct CharacterInformation character;
+ ret = (CharacterParser()).parse(c, &character, error);
+ if(ret != 0) return ret;
+ out->characters.push_back(character);
+
+ } else if(c->node == "asset") {
+ struct AssetInformation asset;
+ ret = (AssetParser()).parse(c, &asset, error);
+ if(ret != 0) return ret;
+ out->assets.push_back(asset);
+
+ } else if(c->node == "scene") {
+ ret = (SceneParser()).parse(c, &out->scene, error);
+ }
+
+ if(ret != 0) return ret;
+ ++itChildren;
+ }
+ return ret;
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/include.hpp b/src/dawntools/visualnovel/vnscenegen/parse/include.hpp
new file mode 100644
index 00000000..3a6960a4
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/include.hpp
@@ -0,0 +1,59 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+#include "util/CodeGen.hpp"
+
+namespace Dawn {
+ typedef std::vector include_t;
+
+ class IncludeParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{
+ "path"
+ };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ include_t *out,
+ std::string *error
+ ) {
+ if(values["path"].size() == 0) {
+ *error = "";
+ return 1;
+ }
+
+ out->push_back(values["path"]);
+ return 0;
+ }
+ };
+
+ class IncludeGen : public CodeGen {
+ public:
+ static void generate(
+ std::vector *out,
+ include_t includes,
+ std::string tabs
+ ) {
+ std::vector generated;
+ auto it = includes.begin();
+ while(it != includes.end()) {
+ if(std::find(generated.begin(), generated.end(), *it) == generated.end()) {
+ line(out, "#include \"" + *it + "\"", tabs);
+ generated.push_back(*it);
+ }
+ ++it;
+ }
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/root.hpp b/src/dawntools/visualnovel/vnscenegen/parse/root.hpp
new file mode 100644
index 00000000..add302a0
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/root.hpp
@@ -0,0 +1,114 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "parse/header.hpp"
+#include "parse/events.hpp"
+
+namespace Dawn {
+ struct RootInformation {
+ struct HeaderInformation header;
+ struct EventsInformation events;
+ };
+
+ class RootParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector();
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map();
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct RootInformation *out,
+ std::string *error
+ ) {
+ int32_t ret = 0;
+ auto itChildren = node->children.begin();
+
+ while(itChildren != node->children.end()) {
+ auto c = *itChildren;
+
+ if(c->node == "head") {
+ ret = (HeaderParser()).parse(c, &out->header, error);
+ } else if(c->node == "events") {
+ ret = (EventsParser()).parse(c, &out->events, error);
+ }
+
+ if(ret != 0) return ret;
+ ++itChildren;
+ }
+
+ return ret;
+ }
+ };
+
+ class RootGen : public CodeGen {
+ public:
+ static void generate(
+ std::vector *out,
+ struct RootInformation *info,
+ std::string tabs = ""
+ ) {
+ struct ClassGenInfo c;
+ c.clazz = info->header.scene.name;
+ c.extend = info->header.scene.type;
+ c.constructorArgs = "DawnGame *game";
+ c.extendArgs = "game";
+
+ struct MethodGenInfo vnStage;
+ vnStage.name = "vnStage";
+ vnStage.type = "void";
+ vnStage.isOverride = true;
+ line(&vnStage.body, info->header.scene.type+ "::vnStage();", "");
+
+ struct MethodGenInfo getAssets;
+ getAssets.name = "getRequiredAssets";
+ getAssets.type = "std::vector";
+ getAssets.isOverride = true;
+ line(&getAssets.body, "auto man = &this->game->assetManager;", "");
+ line(&getAssets.body, "auto assets = " + info->header.scene.type + "::getRequiredAssets();", "");
+
+ struct MethodGenInfo getVNEvent;
+ getVNEvent.name = "getVNEvent";
+ getVNEvent.type = "IVisualNovelEvent *";
+ getVNEvent.isOverride = true;
+ line(&getVNEvent.body, "auto start = new VisualNovelPauseEvent(vnManager, 1.0f);", "");
+
+ IncludeGen::generate(&c.includes, info->header.includes, "");
+ IncludeGen::generate(&c.includes, info->events.includes, "");
+
+ // Characters
+ auto itChar = info->header.characters.begin();
+ while(itChar != info->header.characters.end()) {
+ CharacterGen::generateProperty(&c.publicProperties, *itChar, "");
+ CharacterGen::generateInitializer(&vnStage.body, *itChar, "");
+ CharacterGen::generateAssets(&getAssets.body, *itChar, "");
+ ++itChar;
+ }
+
+ // Events
+ if(info->events.eventTypes.size() > 0) {
+ line(&getVNEvent.body, "start", "");
+ EventsGen::generate(&getVNEvent.body, &info->events, " ");
+ line(&getVNEvent.body, ";", "");
+ }
+
+ // Wrap up methods
+ line(&getAssets.body, "return assets;", "");
+ line(&getVNEvent.body, "return start;", "");
+
+ methodGen(&c.publicCode, vnStage);
+ line(&c.publicCode, "", "");
+ methodGen(&c.publicCode, getAssets);
+ methodGen(&c.publicCode, getVNEvent);
+ classGen(out, c);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/visualnovel/vnscenegen/parse/scene.hpp b/src/dawntools/visualnovel/vnscenegen/parse/scene.hpp
new file mode 100644
index 00000000..47fc7603
--- /dev/null
+++ b/src/dawntools/visualnovel/vnscenegen/parse/scene.hpp
@@ -0,0 +1,40 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+
+namespace Dawn {
+ struct SceneInformation {
+ std::string type;
+ std::string name;
+ };
+
+ class SceneParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() {
+ return std::vector{
+ "name",
+ };
+ }
+
+ std::map getOptionalAttributes() {
+ return std::map{
+ { "type", "SimpleVNScene" }
+ };
+ }
+
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct SceneInformation *out,
+ std::string *error
+ ) {
+ out->name = values["name"];
+ out->type = values["type"];
+ return 0;
+ }
+ };
+}
\ No newline at end of file