144 lines
4.2 KiB
C++

// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "VnSceneGen.hpp"
using namespace Dawn;
int32_t VnSceneGen::start() {
if(this->args.size() != 3) {
std::cout << "Invalid number of args passed to VNScene Generator" << std::endl;
return 1;
}
// Open input file.
File file(this->args[1]);
std::string buffer;
if(!file.readString(&buffer)) {
std::cout << "Failed to read scene " << file.filename << std::endl;
return 1;
}
// 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;
}
// 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";
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.
std::string bufferOut;
bufferOut += "#pragma once\n\n";
auto itInclude = header.includes.begin();
while(itInclude != header.includes.end()) {
bufferOut += "#include \"" + (*itInclude) + "\"\n";
++itInclude;
}
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<Asset*> getRequiredAssets() override{\n";
bufferOut += " auto man = &this->game->assetManager;\n";
bufferOut += " std::vector<Asset*> 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");
if(!fileOut.mkdirp()) {
std::cout << "Failed to make scene output dir" << std::endl;
return 1;
}
if(!fileOut.writeString(bufferOut)) {
std::cout << "Failed to generate scene " << fileOut.filename << std::endl;
return 1;
}
return 0;
}