REWise/src/wisescript.c

1744 lines
43 KiB
C

/* This file is part of REWise.
*
* REWise is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* REWise is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stddef.h>
#include <string.h>
#include <errno.h>
#ifdef __linux__
#include <linux/limits.h>
#else
#include <limits.h>
#endif
#include "wisescript.h"
#include "reader.h"
#include "print.h"
static int WiseScriptSTOP = 0;
REWError readWiseScriptHeader(FILE * fp, WiseScriptHeader * header) {
// init struct
header->logPath = NULL;
header->font = NULL;
REWError status;
status = readBytesInto(fp, header->unknown_44, 44);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &header->logPath);
if (status != REWERR_OK) {
printError("Failed to read WiseScriptHeader logpath: %d\n", status);
return status;
}
status = readString(fp, &header->font);
if (status != REWERR_OK) {
printError("Failed to read WiseScriptHeader font: %d\n", status);
freeWiseScriptHeader(header);
return status;
}
status = readBytesInto(fp, header->unknown_14, 14);
if (status != REWERR_OK) {
freeWiseScriptHeader(header);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptTexts(FILE * fp, WiseScriptTexts * texts) {
REWError status;
uint32_t i;
// Init text pointers
for (i = 0; i < 56; i++) {
texts->installTexts[i] = NULL;
}
// Read the text strings
for (i = 0; i < 56; i++) {
status = readString(fp, &texts->installTexts[i]);
if (status != REWERR_OK) {
freeWiseScriptTexts(texts);
return status;
}
}
return REWERR_OK;
}
REWError readWiseScriptFileHeader(FILE * fp, WiseScriptFileHeader * data) {
REWError status;
// init struct
data->destFile = NULL;
data->fileText = NULL;
status = readBytesInto(fp, data->unknown_2, 2);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->deflateStart);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->deflateEnd);
if (status != REWERR_OK) {
return status;
}
status = readUInt16(fp, &data->date);
if (status != REWERR_OK) {
return status;
}
status = readUInt16(fp, &data->time);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->inflatedSize);
if (status != REWERR_OK) {
return status;
}
status = readBytesInto(fp, data->unknown_40, 20);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->crc32);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->destFile);
if (status != REWERR_OK) {
printError("readWiseScriptFileHeader failed to read destFile: %d\n",
status);
return status;
}
// data->destFile is just 0x00
if (data->destFile == NULL) {
printError("readWiseScriptFileHeader destFile is a empty string\n");
return REWERR_INVALDAT;
}
// parse filepath
char * filePath = wiseScriptParsePath(data->destFile);
if (filePath == NULL) {
printError("readWiseScriptFileHeader invalid destFile\n");
freeWiseScriptFileHeader(data);
return REWERR_INVALDAT;
}
free(data->destFile);
data->destFile = filePath;
status = readString(fp, &data->fileText);
if (status != REWERR_OK) {
printError("readWiseScriptFileHeader failed to read fileText: "
"%d\n", status);
freeWiseScriptFileHeader(data);
return status;
}
status = readBytesInto(fp, &data->terminator, 1);
if (status != REWERR_OK) {
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x03(FILE * fp, WiseScriptUnknown0x03 * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
data->unknownString_2 = NULL;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x03 failed to read unknownString_1: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_2);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x03 failed to read unknownString_2: "
"%d\n", status);
freeWiseScriptUnknown0x03(data);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x04(FILE * fp, WiseScriptUnknown0x04 * data) {
REWError status;
// init struct
data->dataString = NULL;
status = readBytesInto(fp, &data->no, 1);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->dataString);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x04 failed to read dataString: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x05(FILE * fp, WiseScriptUnknown0x05 * data) {
REWError status;
// init struct
data->file = NULL;
data->section = NULL;
data->values = NULL;
status = readString(fp, &data->file);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x05 failed to read file: "
"%d\n", status);
return status;
}
status = readString(fp, &data->section);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x05 failed to read section: "
"%d\n", status);
return status;
}
status = readString(fp, &data->values);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x05 failed to read values: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x06(FILE * fp, WiseScriptUnknown0x06 * data) {
REWError status;
status = readBytesInto(fp, data->unknown, 6);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->deflateStart);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->deflateEnd);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->inflatedSize);
if (status != REWERR_OK) {
return status;
}
status = readBytesInto(fp, &data->unknown1, 1);
if (status != REWERR_OK) {
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x07(FILE * fp, WiseScriptUnknown0x07 * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
data->unknownString_2 = NULL;
data->unknownString_3 = NULL;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x07 failed to read unknownString_1: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_2);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x07 failed to read unknownString_2: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_3);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x07 failed to read unknownString_3: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x08(FILE * fp, WiseScriptUnknown0x08 * data) {
REWError status;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x09(FILE * fp, WiseScriptUnknown0x09 * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
data->unknownString_2 = NULL;
data->unknownString_3 = NULL;
data->unknownString_4 = NULL;
data->unknownString_5 = NULL;
data->unknown_2 = 0;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
if (data->unknown_1 != 0x01 && data->unknown_1 != 0x20) {
status = readBytesInto(fp, &data->unknown_2, 1);
if (status != REWERR_OK) {
return status;
}
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x09 failed to read unknownString_1: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_2);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x09 failed to read unknownString_2: "
"%d\n", status);
freeWiseScriptUnknown0x09(data);
return status;
}
status = readString(fp, &data->unknownString_3);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x09 failed to read unknownString_3: "
"%d\n", status);
freeWiseScriptUnknown0x09(data);
return status;
}
status = readString(fp, &data->unknownString_4);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x09 failed to read unknownString_4: "
"%d\n", status);
freeWiseScriptUnknown0x09(data);
return status;
}
if (data->unknown_1 == 0x01 || data->unknown_1 == 0x20) {
status = readString(fp, &data->unknownString_5);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x09 failed to read unknownString_5: "
"%d\n", status);
freeWiseScriptUnknown0x09(data);
return status;
}
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x0A(FILE * fp, WiseScriptUnknown0x0A * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
data->unknownString_2 = NULL;
data->unknownString_3 = NULL;
status = readBytesInto(fp, data->unknown_2, 2);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x0A failed to read unknownString_1: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_2);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x0A failed to read unknownString_2: "
"%d\n", status);
freeWiseScriptUnknown0x0A(data);
return status;
}
status = readString(fp, &data->unknownString_3);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x0A failed to read unknownString_3: "
"%d\n", status);
freeWiseScriptUnknown0x0A(data);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x0B(FILE * fp, WiseScriptUnknown0x0B * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x0B failed to read unknownString_1: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x0C(FILE * fp, WiseScriptUnknown0x0C * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
data->unknownString_2 = NULL;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x0C failed to read unknownString_1: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_2);
if (status != REWERR_OK) {
freeWiseScriptUnknown0x0C(data);
printError("readWiseScriptUnknown0x0C failed to read unknownString_2: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x11(FILE * fp, WiseScriptUnknown0x11 * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x11 failed to read unknownString_1: "
"%d\n", status);
freeWiseScriptUnknown0x11(data);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x12(FILE * fp, WiseScriptUnknown0x12 * data) {
REWError status;
// init struct
data->sourceFile = NULL;
data->unknownString_1 = NULL;
data->unknownString_2 = NULL;
data->destFile = NULL;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
status = readBytesInto(fp, data->unknown_41, 41);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->sourceFile);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x12 failed to read sourceFile: %d\n",
status);
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
freeWiseScriptUnknown0x12(data);
printError("readWiseScriptUnknown0x12 failed to read unknownString_1: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_2);
if (status != REWERR_OK) {
freeWiseScriptUnknown0x12(data);
printError("readWiseScriptUnknown0x12 failed to read unknownString_2: "
"%d\n", status);
return status;
}
status = readString(fp, &data->destFile);
if (status != REWERR_OK) {
freeWiseScriptUnknown0x12(data);
printError("readWiseScriptUnknown0x12 failed to read destFile: %d\n",
status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x14(FILE * fp, WiseScriptUnknown0x14 * data) {
REWError status;
// init struct
data->name = NULL;
data->message = NULL;
status = readUInt32(fp, &data->deflateStart);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->deflateEnd);
if (status != REWERR_OK) {
return status;
}
status = readUInt32(fp, &data->inflatedSize);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->name);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x14 failed to read name: %d\n", status);
return status;
}
status = readString(fp, &data->message);
if (status != REWERR_OK) {
freeWiseScriptUnknown0x14(data);
printError("readWiseScriptUnknown0x14 failed to read message: %d\n",
status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x15(FILE * fp, WiseScriptUnknown0x15 * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
data->unknownString_2 = NULL;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x15 failed to read unknownString_1: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_2);
if (status != REWERR_OK) {
freeWiseScriptUnknown0x15(data);
printError("readWiseScriptUnknown0x15 failed to read unknownString_2: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x16(FILE * fp, WiseScriptUnknown0x16 * data) {
REWError status;
// init struct
data->name = NULL;
status = readString(fp, &data->name);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x16 failed to read name: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x17(FILE * fp, WiseScriptUnknown0x17 * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
status = readBytesInto(fp, data->unknown_4, 4);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x17 failed to read unknownString_1: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x1C(FILE * fp, WiseScriptUnknown0x1C * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x1C failed to read unknownString_1: "
"%d\n", status);
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x1E(FILE * fp, WiseScriptUnknown0x1E * data) {
REWError status;
status = readBytesInto(fp, data->unknown_2, 2);
if (status != REWERR_OK) {
return status;
}
return REWERR_OK;
}
REWError readWiseScriptUnknown0x23(FILE * fp, WiseScriptUnknown0x23 * data) {
REWError status;
// init struct
data->unknownString_1 = NULL;
data->unknownString_2 = NULL;
status = readBytesInto(fp, &data->unknown_1, 1);
if (status != REWERR_OK) {
return status;
}
status = readString(fp, &data->unknownString_1);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x23 failed to read unknownString_1: "
"%d\n", status);
return status;
}
status = readString(fp, &data->unknownString_2);
if (status != REWERR_OK) {
printError("readWiseScriptUnknown0x23 failed to read unknownString_2: "
"%d\n", status);
freeWiseScriptUnknown0x23(data);
return status;
}
return REWERR_OK;
}
void freeWiseScriptHeader(WiseScriptHeader * header) {
if (header->logPath != NULL) {
free(header->logPath);
header->logPath = NULL;
}
if (header->font != NULL) {
free(header->font);
header->font = NULL;
}
}
void freeWiseScriptTexts(WiseScriptTexts * texts) {
for (uint32_t i = 0; i < 56; i++) {
if (texts->installTexts[i] != NULL) {
free(texts->installTexts[i]);
texts->installTexts[i] = NULL;
}
}
}
void freeWiseScriptFileHeader(WiseScriptFileHeader * data) {
if (data->destFile != NULL) {
free(data->destFile);
data->destFile = NULL;
}
if (data->fileText != NULL) {
free(data->fileText);
data->fileText = NULL;
}
}
void freeWiseScriptUnknown0x03(WiseScriptUnknown0x03 * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
if (data->unknownString_2 != NULL) {
free(data->unknownString_2);
data->unknownString_2 = NULL;
}
}
void freeWiseScriptUnknown0x04(WiseScriptUnknown0x04 * data) {
if (data->dataString != NULL) {
free(data->dataString);
data->dataString = NULL;
}
}
void freeWiseScriptUnknown0x05(WiseScriptUnknown0x05 * data) {
if (data->file != NULL) {
free(data->file);
data->file = NULL;
}
if (data->section != NULL) {
free(data->section);
data->section = NULL;
}
if (data->values != NULL) {
free(data->values);
data->values = NULL;
}
}
void freeWiseScriptUnknown0x07(WiseScriptUnknown0x07 * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
if (data->unknownString_2 != NULL) {
free(data->unknownString_2);
data->unknownString_2 = NULL;
}
if (data->unknownString_3 != NULL) {
free(data->unknownString_3);
data->unknownString_3 = NULL;
}
}
void freeWiseScriptUnknown0x09(WiseScriptUnknown0x09 * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
if (data->unknownString_2 != NULL) {
free(data->unknownString_2);
data->unknownString_2 = NULL;
}
if (data->unknownString_3 != NULL) {
free(data->unknownString_3);
data->unknownString_3 = NULL;
}
if (data->unknownString_4 != NULL) {
free(data->unknownString_4);
data->unknownString_4 = NULL;
}
if (data->unknownString_5 != NULL) {
free(data->unknownString_5);
data->unknownString_5 = NULL;
}
}
void freeWiseScriptUnknown0x0A(WiseScriptUnknown0x0A * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
if (data->unknownString_2 != NULL) {
free(data->unknownString_2);
data->unknownString_2 = NULL;
}
if (data->unknownString_3 != NULL) {
free(data->unknownString_3);
data->unknownString_3 = NULL;
}
}
void freeWiseScriptUnknown0x0B(WiseScriptUnknown0x0B * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
}
void freeWiseScriptUnknown0x0C(WiseScriptUnknown0x0C * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
if (data->unknownString_2 != NULL) {
free(data->unknownString_2);
data->unknownString_2 = NULL;
}
}
void freeWiseScriptUnknown0x11(WiseScriptUnknown0x11 * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
}
void freeWiseScriptUnknown0x12(WiseScriptUnknown0x12 * data) {
if (data->sourceFile != NULL) {
free(data->sourceFile);
data->sourceFile = NULL;
}
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
if (data->unknownString_2 != NULL) {
free(data->unknownString_2);
data->unknownString_2 = NULL;
}
if (data->destFile != NULL) {
free(data->destFile);
data->destFile = NULL;
}
}
void freeWiseScriptUnknown0x14(WiseScriptUnknown0x14 * data) {
if (data->name != NULL) {
free(data->name);
data->name = NULL;
}
if (data->message != NULL) {
free(data->message);
data->message = NULL;
}
}
void freeWiseScriptUnknown0x15(WiseScriptUnknown0x15 * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
if (data->unknownString_2 != NULL) {
free(data->unknownString_2);
data->unknownString_2 = NULL;
}
}
void freeWiseScriptUnknown0x16(WiseScriptUnknown0x16 * data) {
if (data->name != NULL) {
free(data->name);
data->name = NULL;
}
}
void freeWiseScriptUnknown0x17(WiseScriptUnknown0x17 * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
}
void freeWiseScriptUnknown0x1C(WiseScriptUnknown0x1C * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
}
void freeWiseScriptUnknown0x23(WiseScriptUnknown0x23 * data) {
if (data->unknownString_1 != NULL) {
free(data->unknownString_1);
data->unknownString_1 = NULL;
}
if (data->unknownString_2 != NULL) {
free(data->unknownString_2);
data->unknownString_2 = NULL;
}
}
// Debug prints //
// https://www.doubleblak.com/m/blogPosts.php?id=7
// MS-Dos FileTime
// DATE
// ----
// bit 0 - 6 Year
// bit 7 - 10 Month
// bit 11 - 15 Day
//
// TIME
// ----
// bit 0 - 4 Hour
// bit 5 - 10 Minutes
// bit 11 - 15 * 2 Seconds
void printDatetime(uint16_t date, uint16_t time) {
printf("%04d-%02d-%02d %02d:%02d:%02d",
(date >> 9) + 1980,
(date >> 5) & 0b0000000000001111,
date & 0b0000000000011111,
(time >> 11),
(time >> 5) & 0b0000000000111111,
(time & 0b0000000000011111) * 2);
}
void printHex(unsigned char * value, uint32_t size) {
for (uint32_t i=0; i < size; i++) {
printf("%02X", value[i]);
}
}
void printWiseScriptHeader(WiseScriptHeader * header) {
printf("WiseScript Header\n-----------------\n");
for (int i = 0; i < 44; i++) {
printf("%02X ", header->unknown_44[i]);
}
printf("\n");
printf("'%s': '%s'\n", header->font, header->logPath);
printf("-----------------\n");
}
void printWiseScriptTexts(WiseScriptTexts * texts) {
printf("WiseScript Texts\n");
printf("----------------\n");
for (int i = 0; i < 56; i++) {
printf("Text: \"%s\"\n", texts->installTexts[i]);
}
printf("----------------\n");
}
void printWiseScriptFileHeader(WiseScriptFileHeader * data) {
printf("0x00 0x%08X 0x%08X ", data->deflateStart, data->deflateEnd);
printDatetime(data->date, data->time);
printf(" % 11u ", data->inflatedSize);
printHex(data->unknown_40, 20);
printf(" %08X '%s' '%s' %d\n", data->crc32, data->destFile, data->fileText,
data->terminator);
}
void printWiseScriptUnknown0x03(WiseScriptUnknown0x03 * data) {
printf("0x03 0x%02X '%s' '%s'\n", data->unknown_1, data->unknownString_1,
data->unknownString_2);
}
void printWiseScriptUnknown0x04(WiseScriptUnknown0x04 * data) {
printf("0x04 0x%02X '%s'\n", data->no, data->dataString);
}
void printWiseScriptUnknown0x05(WiseScriptUnknown0x05 * data) {
printf("0x05 '%s' '%s' '%s'\n", data->file, data->section, data->values);
}
void printWiseScriptUnknown0x06(WiseScriptUnknown0x06 * data) {
printf("0x06 ");
printHex(data->unknown, 6);
printf(" 0x%08X 0x%08X % 11u %02X\n", data->deflateStart, data->deflateEnd,
data->inflatedSize, data->unknown1);
}
void printWiseScriptUnknown0x07(WiseScriptUnknown0x07 * data) {
printf("0x07 %02X '%s' '%s' '%s'\n", data->unknown_1, data->unknownString_1,
data->unknownString_2, data->unknownString_3);
}
void printWiseScriptUnknown0x08(WiseScriptUnknown0x08 * data) {
printf("0x08 %02X\n", data->unknown_1);
}
void printWiseScriptUnknown0x09(WiseScriptUnknown0x09 * data) {
printf("0x09 %02X ", data->unknown_1);
if (data->unknown_1 != 0x01 && data->unknown_1 != 0x20) {
printf("%02X ", data->unknown_2);
}
printf("'%s' '%s' '%s' '%s'", data->unknownString_1, data->unknownString_2,
data->unknownString_3, data->unknownString_4);
if (data->unknown_1 == 0x01 || data->unknown_1 == 0x20) {
printf(" '%s'", data->unknownString_5);
}
printf("\n");
}
void printWiseScriptUnknown0x0A(WiseScriptUnknown0x0A * data) {
printf("0x0A ");
printHex(data->unknown_2, 2);
printf(" '%s' '%s' '%s'\n", data->unknownString_1, data->unknownString_2,
data->unknownString_3);
}
void printWiseScriptUnknown0x0B(WiseScriptUnknown0x0B * data) {
printf("0x0B %02X '%s'\n", data->unknown_1, data->unknownString_1);
}
void printWiseScriptUnknown0x0C(WiseScriptUnknown0x0C * data) {
printf("0x0B %02X '%s' '%s'\n", data->unknown_1, data->unknownString_1,
data->unknownString_2);
}
void printWiseScriptUnknown0x11(WiseScriptUnknown0x11 * data) {
printf("0x11 '%s'\n", data->unknownString_1);
}
void printWiseScriptUnknown0x12(WiseScriptUnknown0x12 * data) {
printf("0x12 %02X ", data->unknown_1);
printHex(data->unknown_41, 41);
printf(" '%s' '%s' '%s' '%s'\n", data->sourceFile, data->unknownString_1,
data->unknownString_2, data->destFile);
}
void printWiseScriptUnknown0x14(WiseScriptUnknown0x14 * data) {
printf("0x14 0x%08X 0x%08X % 11u '%s' '%s'\n", data->deflateStart,
data->deflateEnd, data->inflatedSize, data->name, data->message);
}
void printWiseScriptUnknown0x15(WiseScriptUnknown0x15 * data) {
printf("0x15 %02X '%s' '%s'\n", data->unknown_1, data->unknownString_1,
data->unknownString_2);
}
void printWiseScriptUnknown0x16(WiseScriptUnknown0x16 * data) {
printf("0x16 '%s'\n", data->name);
}
void printWiseScriptUnknown0x17(WiseScriptUnknown0x17 * data) {
printf("0x17 %02X ", data->unknown_1);
printHex(data->unknown_4, 4);
printf(" '%s'\n", data->unknownString_1);
}
void printWiseScriptUnknown0x1C(WiseScriptUnknown0x1C * data) {
printf("0x1C '%s'\n", data->unknownString_1);
}
void printWiseScriptUnknown0x1E(WiseScriptUnknown0x1E * data) {
printf("0x1E ");
printHex(data->unknown_2, 2);
printf("\n");
}
void printWiseScriptUnknown0x23(WiseScriptUnknown0x23 * data) {
printf("0x1C %02X '%s' '%s'\n", data->unknown_1, data->unknownString_1,
data->unknownString_2);
}
void initWiseScriptCallbacks(WiseScriptCallbacks * callbacks) {
callbacks->cb_header = NULL;
callbacks->cb_texts = NULL;
callbacks->cb_0x00 = NULL;
callbacks->cb_0x03 = NULL;
callbacks->cb_0x04 = NULL;
callbacks->cb_0x05 = NULL;
callbacks->cb_0x06 = NULL;
callbacks->cb_0x07 = NULL;
callbacks->cb_0x08 = NULL;
callbacks->cb_0x09 = NULL;
callbacks->cb_0x0A = NULL;
callbacks->cb_0x0B = NULL;
callbacks->cb_0x0C = NULL;
callbacks->cb_0x0F = NULL;
callbacks->cb_0x10 = NULL;
callbacks->cb_0x11 = NULL;
callbacks->cb_0x12 = NULL;
callbacks->cb_0x14 = NULL;
callbacks->cb_0x15 = NULL;
callbacks->cb_0x16 = NULL;
callbacks->cb_0x17 = NULL;
callbacks->cb_0x1C = NULL;
callbacks->cb_0x1E = NULL;
callbacks->cb_0x23 = NULL;
}
REWError parseWiseScript(const char * filepath, WiseScriptCallbacks * callbacks) {
FILE * fp;
REWError status;
unsigned char op;
// check if file exists
if (access(filepath, F_OK) != 0) {
printError("parseWiseScript input file '%s' not found\n", filepath);
printError("parseWiseScript errno: %s\n", strerror(errno));
return REWERR_ERRNO;
}
// open the file
fp = fopen(filepath, "rb");
// failed to open the file
if (fp == NULL) {
printError("parseWiseScript failed to open file '%s'\n", filepath);
printError("parseWiseScript errno: %s\n", strerror(errno));
return REWERR_ERRNO;
}
// Read the header
{
WiseScriptHeader header;
status = readWiseScriptHeader(fp, &header);
if (status != REWERR_OK) {
printError("parseWiseScript failed to read header. %d\n", status);
fclose(fp);
return status;
}
// callback
if (callbacks->cb_header != NULL) {
(*callbacks->cb_header)(&header);
}
// cleanup
freeWiseScriptHeader(&header);
}
// Read the texts
{
WiseScriptTexts texts;
status = readWiseScriptTexts(fp, &texts);
if (status != REWERR_OK) {
printError("parseWiseScript failed to read texts. %d\n", status);
fclose(fp);
return status;
}
// callback
if (callbacks->cb_texts != NULL) {
(*callbacks->cb_texts)(&texts);
}
// cleanup
freeWiseScriptTexts(&texts);
}
// Read operation and struct
WiseScriptSTOP = 0;
while (status == REWERR_OK && WiseScriptSTOP == 0) {
int ch = fgetc(fp);
op = (unsigned char)ch;
if (ch == EOF) {
break;
}
switch (op) {
case 0x00:
{
WiseScriptFileHeader data;
status = readWiseScriptFileHeader(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x00 != NULL) {
(*callbacks->cb_0x00)(&data);
}
freeWiseScriptFileHeader(&data);
}
}
break;
case 0x03:
{
WiseScriptUnknown0x03 data;
status = readWiseScriptUnknown0x03(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x03 != NULL) {
(*callbacks->cb_0x03)(&data);
}
freeWiseScriptUnknown0x03(&data);
}
}
break;
case 0x04:
{
WiseScriptUnknown0x04 data;
status = readWiseScriptUnknown0x04(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x04 != NULL) {
(*callbacks->cb_0x04)(&data);
}
freeWiseScriptUnknown0x04(&data);
}
}
break;
case 0x05:
{
WiseScriptUnknown0x05 data;
status = readWiseScriptUnknown0x05(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x05 != NULL) {
(*callbacks->cb_0x05)(&data);
}
freeWiseScriptUnknown0x05(&data);
}
}
break;
case 0x06:
{
WiseScriptUnknown0x06 data;
status = readWiseScriptUnknown0x06(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x06 != NULL) {
(*callbacks->cb_0x06)(&data);
}
}
}
break;
case 0x07:
{
WiseScriptUnknown0x07 data;
status = readWiseScriptUnknown0x07(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x07 != NULL) {
(*callbacks->cb_0x07)(&data);
}
freeWiseScriptUnknown0x07(&data);
}
}
break;
case 0x08:
{
WiseScriptUnknown0x08 data;
status = readWiseScriptUnknown0x08(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x08 != NULL) {
(*callbacks->cb_0x08)(&data);
}
}
}
break;
case 0x09:
{
WiseScriptUnknown0x09 data;
status = readWiseScriptUnknown0x09(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x09 != NULL) {
(*callbacks->cb_0x09)(&data);
}
freeWiseScriptUnknown0x09(&data);
}
}
break;
case 0x0A:
{
WiseScriptUnknown0x0A data;
status = readWiseScriptUnknown0x0A(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x0A != NULL) {
(*callbacks->cb_0x0A)(&data);
}
freeWiseScriptUnknown0x0A(&data);
}
}
break;
case 0x0B:
{
WiseScriptUnknown0x0B data;
status = readWiseScriptUnknown0x0B(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x0B != NULL) {
(*callbacks->cb_0x0B)(&data);
}
freeWiseScriptUnknown0x0B(&data);
}
}
break;
case 0x0C:
{
WiseScriptUnknown0x0C data;
status = readWiseScriptUnknown0x0C(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x0C != NULL) {
(*callbacks->cb_0x0C)(&data);
}
freeWiseScriptUnknown0x0C(&data);
}
}
break;
case 0x0F:
// Start form data?
if (callbacks->cb_0x0F != NULL) {
(*callbacks->cb_0x0F)();
}
break;
case 0x10:
// end form data?
if (callbacks->cb_0x10 != NULL) {
(*callbacks->cb_0x10)();
}
break;
case 0x11:
{
WiseScriptUnknown0x11 data;
status = readWiseScriptUnknown0x11(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x11 != NULL) {
(*callbacks->cb_0x11)(&data);
}
freeWiseScriptUnknown0x11(&data);
}
}
break;
case 0x12:
{
WiseScriptUnknown0x12 data;
status = readWiseScriptUnknown0x12(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x12 != NULL) {
(*callbacks->cb_0x12)(&data);
}
freeWiseScriptUnknown0x12(&data);
}
}
break;
case 0x14:
{
WiseScriptUnknown0x14 data;
status = readWiseScriptUnknown0x14(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x14 != NULL) {
(*callbacks->cb_0x14)(&data);
}
freeWiseScriptUnknown0x14(&data);
}
}
break;
case 0x15:
{
WiseScriptUnknown0x15 data;
status = readWiseScriptUnknown0x15(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x15 != NULL) {
(*callbacks->cb_0x15)(&data);
}
freeWiseScriptUnknown0x15(&data);
}
}
break;
case 0x16:
{
WiseScriptUnknown0x16 data;
status = readWiseScriptUnknown0x16(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x16 != NULL) {
(*callbacks->cb_0x16)(&data);
}
freeWiseScriptUnknown0x16(&data);
}
}
break;
case 0x17:
{
WiseScriptUnknown0x17 data;
status = readWiseScriptUnknown0x17(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x17 != NULL) {
(*callbacks->cb_0x17)(&data);
}
freeWiseScriptUnknown0x17(&data);
}
}
break;
// skip tailing zeros
case 0x18:
ch = 0x00;
while (ch != EOF && ch == 0x00) {
ch = fgetc(fp);
}
if (ch != EOF) {
fseek(fp, -1, SEEK_CUR);
}
break;
case 0x1B:
case 0x0D:
case 0x24: // TODO Skip? Only seen in RTCW
case 0x25: // TODO Skip? Only seen in RTCW
// Skip this byte
break;
case 0x1C:
{
WiseScriptUnknown0x1C data;
status = readWiseScriptUnknown0x1C(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x1C != NULL) {
(*callbacks->cb_0x1C)(&data);
}
freeWiseScriptUnknown0x1C(&data);
}
}
break;
case 0x1E:
{
WiseScriptUnknown0x1E data;
status = readWiseScriptUnknown0x1E(fp, &data);
if (status == REWERR_OK && callbacks->cb_0x1E != NULL) {
(*callbacks->cb_0x1E)(&data);
}
}
break;
case 0x23:
{
WiseScriptUnknown0x23 data;
status = readWiseScriptUnknown0x23(fp, &data);
if (status == REWERR_OK) {
if (callbacks->cb_0x23 != NULL) {
(*callbacks->cb_0x23)(&data);
}
freeWiseScriptUnknown0x23(&data);
}
}
break;
default:
printError("parseWiseScript unknown OP: %02X at 0x%08X\n", ch,
ftell(fp));
status = REWERR_NOOPT;
break;
}
}
fclose(fp);
if (status != REWERR_OK) {
printError("parseWiseScript OP 0x%02X failed\n", op);
}
return status;
}
void stopWiseScriptParse(void) {
WiseScriptSTOP = 1;
}
static WiseScriptParsedInfo WISESCRIPT_PARSED_INFO = {
.totalInflatedSize = 0,
.inflatedSize0x00 = 0,
.inflatedSize0x06 = 0,
.inflatedSize0x14 = 0,
.inflateStartOffset = 0
};
void updateParsedInfo0x00(WiseScriptFileHeader * data) {
if (data->deflateEnd > WISESCRIPT_PARSED_INFO.inflateStartOffset ) {
WISESCRIPT_PARSED_INFO.inflateStartOffset = data->deflateEnd;
}
WISESCRIPT_PARSED_INFO.totalInflatedSize += data->inflatedSize;
WISESCRIPT_PARSED_INFO.inflatedSize0x00 += data->inflatedSize;
}
void updateParsedInfo0x06(WiseScriptUnknown0x06 * data) {
if (data->deflateEnd > WISESCRIPT_PARSED_INFO.inflateStartOffset ) {
WISESCRIPT_PARSED_INFO.inflateStartOffset = data->deflateEnd;
}
WISESCRIPT_PARSED_INFO.totalInflatedSize += data->inflatedSize;
WISESCRIPT_PARSED_INFO.inflatedSize0x06 += data->inflatedSize;
}
void updateParsedInfo0x14(WiseScriptUnknown0x14 * data) {
if (data->deflateEnd > WISESCRIPT_PARSED_INFO.inflateStartOffset ) {
WISESCRIPT_PARSED_INFO.inflateStartOffset = data->deflateEnd;
}
WISESCRIPT_PARSED_INFO.totalInflatedSize += data->inflatedSize;
WISESCRIPT_PARSED_INFO.inflatedSize0x14 += data->inflatedSize;
}
WiseScriptParsedInfo * wiseScriptGetParsedInfo(const char * filepath) {
WiseScriptCallbacks callbacks;
REWError status;
initWiseScriptCallbacks(&callbacks);
callbacks.cb_0x00 = &updateParsedInfo0x00;
callbacks.cb_0x06 = &updateParsedInfo0x06;
callbacks.cb_0x14 = &updateParsedInfo0x14;
WISESCRIPT_PARSED_INFO.totalInflatedSize = 0;
WISESCRIPT_PARSED_INFO.inflateStartOffset = 0;
status = parseWiseScript(filepath, &callbacks);
if (status != REWERR_OK) {
printError("wiseScriptGetDeflateEnd parsing failed\n");
return NULL;
}
return &WISESCRIPT_PARSED_INFO;
}
REWError wiseScriptDebugPrint(const char * filepath) {
WiseScriptCallbacks callbacks;
initWiseScriptCallbacks(&callbacks);
callbacks.cb_header = &printWiseScriptHeader;
callbacks.cb_texts = &printWiseScriptTexts;
callbacks.cb_0x00 = &printWiseScriptFileHeader;
callbacks.cb_0x03 = &printWiseScriptUnknown0x03;
callbacks.cb_0x04 = &printWiseScriptUnknown0x04;
callbacks.cb_0x05 = &printWiseScriptUnknown0x05;
callbacks.cb_0x06 = &printWiseScriptUnknown0x06;
callbacks.cb_0x07 = &printWiseScriptUnknown0x07;
callbacks.cb_0x08 = &printWiseScriptUnknown0x08;
callbacks.cb_0x09 = &printWiseScriptUnknown0x09;
callbacks.cb_0x0A = &printWiseScriptUnknown0x0A;
callbacks.cb_0x0B = &printWiseScriptUnknown0x0B;
callbacks.cb_0x0C = &printWiseScriptUnknown0x0C;
callbacks.cb_0x11 = &printWiseScriptUnknown0x11;
callbacks.cb_0x12 = &printWiseScriptUnknown0x12;
callbacks.cb_0x14 = &printWiseScriptUnknown0x14;
callbacks.cb_0x15 = &printWiseScriptUnknown0x15;
callbacks.cb_0x16 = &printWiseScriptUnknown0x16;
callbacks.cb_0x17 = &printWiseScriptUnknown0x17;
callbacks.cb_0x1C = &printWiseScriptUnknown0x1C;
callbacks.cb_0x1E = &printWiseScriptUnknown0x1E;
callbacks.cb_0x23 = &printWiseScriptUnknown0x23;
return parseWiseScript(filepath, &callbacks);
}
// Must be a valid pointer to a \0 terminated string.
char * wiseScriptParsePath(char * path) {
char * pathCopy;
char * section;
char newPath[PATH_MAX];
char * returnPath;
uint32_t strSize = 0;
// Basic verification that this string may be a valid path
do {
unsigned char ch = path[strSize];
if (ch == 0x00) {
break;
}
// It contains a illegal character
if (ch < 0x20 || ch > 0x7E || ch == '/') {
printError("wiseScriptParsePath path contains an illegal character "
"0x%02X\n", ch);
return NULL;
}
strSize++;
// Path is to long
if (strSize > WIN_PATH_MAX) {
printError("wiseScriptParsePath path is larger then WIN_PATH_MAX\n");
return NULL;
}
} while (1);
// Check that the path starts with '%'
if (path[0] != 0x25) {
printError("wiseScriptParsePath path does not start with '%'\n");
return NULL;
}
// Duplicate the path for the use with strtok
pathCopy = strdup(path);
if (pathCopy == NULL) {
printError("wiseScriptParsePath errno: %s\n", strerror(errno));
return NULL;
}
newPath[0] = 0x00;
section = strtok(pathCopy, "\\");
do {
size_t sectionLen = strlen(section);
// Strip '%' from variables
if (section[0] == 0x25 && section[sectionLen - 1] == 0x25) {
section[sectionLen - 1] = 0x00;
section++;
if (section[0] == 0x00) {
printError("wiseScriptParsePath empty path component.\n");
free(pathCopy);
return NULL;
}
}
if (sectionLen > NAME_MAX) {
printError("wiseScriptParsePath path component name exceeds NAME_MAX\n");
free(pathCopy);
return NULL;
}
// Don't allow a path section to start with '..'
if (sectionLen >= 2) {
if (section[0] == '.' && section[1] == '.') {
printError("wiseScriptParsePath path component starts with '..'."
" Symbolic paths are not allowed! Path: '%s'\n", path);
free(pathCopy);
return NULL;
}
}
strcat(newPath, "/");
strcat(newPath, section);
} while ((section = strtok(NULL, "\\")));
free(pathCopy);
returnPath = strdup(newPath + 1); // +1 to remove the first character '/'
if (returnPath == NULL) {
printError("wiseScriptParsePath errno: %s\n", strerror(errno));
return NULL;
}
return returnPath;
}