144 lines
4.2 KiB
C++
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;
|
|
} |