203 lines
5.3 KiB
C++
203 lines
5.3 KiB
C++
// Copyright (c) 2023 Dominic Masters
|
|
//
|
|
// This software is released under the MIT License.
|
|
// https://opensource.org/licenses/MIT
|
|
|
|
extern "C" {
|
|
#include "../../utils/file.h"
|
|
#include "../../utils/xml.h"
|
|
#include <memory.h>
|
|
}
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
struct CharacterInformation {
|
|
std::string clazz;
|
|
std::string name;
|
|
};
|
|
|
|
struct Asset {
|
|
std::string type;
|
|
std::string name;
|
|
};
|
|
|
|
struct HeaderInformation {
|
|
std::string type;
|
|
std::string name;
|
|
std::vector<std::string> includes;
|
|
std::vector<struct CharacterInformation> characters;
|
|
std::vector<struct Asset> assets;
|
|
};
|
|
|
|
int32_t parseInclude(struct HeaderInformation *info, xml_t *node) {
|
|
auto attrPath = xmlGetAttributeByName(node, "path");
|
|
if(attrPath == -1) {
|
|
std::cout << "Missing include path in VN Header Defintions." << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
info->includes.push_back(node->attributeDatas[attrPath]);
|
|
return 0;
|
|
}
|
|
|
|
int32_t parseCharacter(struct HeaderInformation *info, xml_t *node) {
|
|
auto attrClass = xmlGetAttributeByName(node, "class");
|
|
if(attrClass == -1) {
|
|
std::cout << "Character definition is missing class" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
auto attrName = xmlGetAttributeByName(node, "name");
|
|
if(attrName == -1) {
|
|
std::cout << "Character definition is missing name" << std::endl;
|
|
}
|
|
|
|
struct CharacterInformation character;
|
|
character.clazz = std::string(node->attributeDatas[attrClass]);
|
|
character.name = std::string(node->attributeDatas[attrName]);
|
|
info->characters.push_back(character);
|
|
return 0;
|
|
}
|
|
|
|
int32_t parseScene(struct HeaderInformation *info, xml_t *node) {
|
|
auto attrName = xmlGetAttributeByName(node, "name");
|
|
if(attrName == -1) {
|
|
std::cout << "VN Scene <scene> definition is missing name attribute" << std::endl;
|
|
return 1;
|
|
}
|
|
info->name = std::string(node->attributeDatas[attrName]);
|
|
|
|
auto attrType = xmlGetAttributeByName(node, "type");
|
|
if(attrType == -1) {
|
|
info->type = "SimpleVNScene";
|
|
} else {
|
|
info->type = std::string(node->attributeDatas[attrType]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int32_t parseAsset(struct HeaderInformation *info, xml_t *node) {
|
|
auto attrType = xmlGetAttributeByName(node, "type");
|
|
if(attrType == -1) {
|
|
std::cout << "VN Scene Asset missing type attribute" << std::endl;
|
|
return 1;
|
|
}
|
|
auto attrName = xmlGetAttributeByName(node, "name");
|
|
if(attrName == -1) {
|
|
std::cout << "VN Scene Asset missing name attribute" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
struct Asset ass;
|
|
ass.type = std::string(node->attributeDatas[attrType]);
|
|
ass.name = std::string(node->attributeDatas[attrName]);
|
|
info->assets.push_back(ass);
|
|
return 0;
|
|
}
|
|
|
|
int32_t parseHeader(struct HeaderInformation *info, xml_t *node) {
|
|
for(int32_t i = 0; i < node->childrenCount; i++) {
|
|
auto c = node->children + i;
|
|
auto n = std::string(c->node);
|
|
int32_t ret = 0;
|
|
|
|
std::cout << n << std::endl;
|
|
|
|
if(n == "include") {
|
|
ret = parseInclude(info, c);
|
|
} else if(n == "character") {
|
|
ret = parseCharacter(info, c);
|
|
} else if(n == "scene") {
|
|
ret = parseScene(info, c);
|
|
} else if (n == "asset") {
|
|
ret = parseAsset(info, c);
|
|
} else {
|
|
std::cout << "Parsing VN Scene header, unknown node " << n << std::endl;
|
|
}
|
|
if(ret != 0) return ret;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int main(int32_t argc, char *args[]) {
|
|
if(argc != 3) {
|
|
std::cout << "Invalid number of args passed to VNScene Generator" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
// Open input file.
|
|
char fileIn[FILENAME_MAX];
|
|
fileNormalizeSlashes(args[1]);
|
|
sprintf(fileIn, "%s", args[1]);
|
|
FILE *fin = fopen(fileIn, "rb");
|
|
if(fin == NULL) {
|
|
std::cout << "Failed to open input file " << fileIn << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
// Tell file len
|
|
auto len = assetReadString(fin, NULL);
|
|
|
|
// Read data.
|
|
char *buffer = (char *)malloc(sizeof(char) * (len + 1));
|
|
if(buffer == NULL) {
|
|
std::cout << "Failed to create temporary memory." << std::endl;
|
|
fclose(fin);
|
|
return 1;
|
|
}
|
|
assetReadString(fin, buffer);
|
|
fclose(fin);
|
|
|
|
// Parse XML
|
|
xml_t xml;
|
|
xmlLoad(&xml, buffer);
|
|
free(buffer);
|
|
|
|
// First, read the header information
|
|
struct HeaderInformation header;
|
|
for(int32_t i = 0; i < xml.childrenCount; i++) {
|
|
auto child = xml.children + i;
|
|
if(std::string(child->node) != "head") continue;
|
|
auto ret = parseHeader(&header, child);
|
|
if(ret != 0) {
|
|
xmlDispose(&xml);
|
|
return ret;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Validate header
|
|
if(header.name.size() == 0 || header.type.size() == 0) {
|
|
std::cout << "VN Scene header wasn't parsed properly." << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
std::string bufferOut;
|
|
bufferOut += "#pragma once\n";
|
|
auto itInclude = header.includes.begin();
|
|
while(itInclude != header.includes.end()) {
|
|
bufferOut += "#include \"" + (*itInclude) + "\"\n";
|
|
++itInclude;
|
|
}
|
|
|
|
// Finished with XML data, now we can write data out.
|
|
xmlDispose(&xml);
|
|
|
|
char fileOut[FILENAME_MAX];
|
|
fileNormalizeSlashes(args[2]);
|
|
sprintf(fileOut, "%s.hpp", args[2]);
|
|
fileMkdirp(fileOut);
|
|
FILE *fout = fopen(fileOut, "wb");
|
|
if(fout == NULL) {
|
|
std::cout << "Failed to open output file." << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
// Buffer out data.
|
|
const char *bufferOutStr = bufferOut.c_str();
|
|
fwrite(bufferOutStr, sizeof(char), strlen(bufferOutStr), fout);
|
|
fclose(fout);
|
|
std::cout << "Generated Scene " << fileOut << std::endl;
|
|
|
|
return 0;
|
|
} |