summaryrefslogtreecommitdiff
path: root/tools/nitrogfx/json.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/nitrogfx/json.c')
-rw-r--r--tools/nitrogfx/json.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/tools/nitrogfx/json.c b/tools/nitrogfx/json.c
new file mode 100644
index 00000000..fa9f9e5e
--- /dev/null
+++ b/tools/nitrogfx/json.c
@@ -0,0 +1,212 @@
+// Copyright (c) 2021 red031000
+
+#include "global.h"
+#include "cJSON.h"
+#include "json.h"
+#include "util.h"
+#include <string.h>
+#include <stdlib.h>
+
+static inline bool GetBool(cJSON * in)
+{
+ if (!cJSON_IsBool(in))
+ return false;
+
+ return cJSON_IsTrue(in);
+}
+
+static inline int GetInt(cJSON * in)
+{
+ if (!cJSON_IsNumber(in))
+ return 0;
+
+ return in->valueint;
+}
+
+static inline char *GetString(cJSON * in)
+{
+ if (!cJSON_IsString(in))
+ return NULL;
+
+ return in->valuestring;
+}
+
+struct JsonToCellOptions *ParseNCERJson(char *path)
+{
+ int fileLength;
+ unsigned char *jsonString = ReadWholeFile(path, &fileLength);
+
+ cJSON *json = cJSON_Parse((const char *)jsonString);
+
+ struct JsonToCellOptions *options = malloc(sizeof(struct JsonToCellOptions));
+
+ if (json == NULL)
+ {
+ const char *errorPtr = cJSON_GetErrorPtr();
+ FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
+ }
+
+ cJSON *labelBool = cJSON_GetObjectItemCaseSensitive(json, "label");
+ cJSON *extended = cJSON_GetObjectItemCaseSensitive(json, "extended");
+ cJSON *imageHeight = cJSON_GetObjectItemCaseSensitive(json, "imageHeight");
+ cJSON *imageWidth = cJSON_GetObjectItemCaseSensitive(json, "imageWidth");
+ cJSON *cellCount = cJSON_GetObjectItemCaseSensitive(json, "cellCount");
+
+ options->label = GetBool(labelBool);
+ options->extended = GetBool(extended);
+ options->imageHeight = GetInt(imageHeight);
+ options->imageWidth = GetInt(imageWidth);
+ options->cellCount = GetInt(cellCount);
+
+ options->cells = malloc(sizeof(struct Cell *) * options->cellCount);
+
+ for (int i = 0; i < options->cellCount; i++)
+ {
+ options->cells[i] = malloc(sizeof(struct Cell));
+ }
+
+ int i = 0;
+ cJSON *cells = cJSON_GetObjectItemCaseSensitive(json, "cells");
+ cJSON *cell = NULL;
+
+ cJSON_ArrayForEach(cell, cells)
+ {
+ if (i > options->cellCount - 1)
+ FATAL_ERROR("Cell count is incorrect.\n");
+
+ cJSON *readOnly = cJSON_GetObjectItemCaseSensitive(cell, "readOnly");
+
+ options->cells[i]->readOnly = (short)GetInt(readOnly);
+ if (options->extended)
+ {
+ cJSON *maxX = cJSON_GetObjectItemCaseSensitive(cell, "maxX");
+ cJSON *maxY = cJSON_GetObjectItemCaseSensitive(cell, "maxY");
+ cJSON *minX = cJSON_GetObjectItemCaseSensitive(cell, "minX");
+ cJSON *minY = cJSON_GetObjectItemCaseSensitive(cell, "minY");
+
+ options->cells[i]->maxX = (short)GetInt(maxX);
+ options->cells[i]->maxY = (short)GetInt(maxY);
+ options->cells[i]->minX = (short)GetInt(minX);
+ options->cells[i]->minY = (short)GetInt(minY);
+ }
+
+ if (options->label)
+ {
+ cJSON *label = cJSON_GetObjectItemCaseSensitive(cell, "label");
+ char *labelString = GetString(label);
+ options->cells[i]->label = malloc(strlen(labelString) + 1);
+ strcpy(options->cells[i]->label, labelString);
+ }
+ //OAM data
+ cJSON *OAM = cJSON_GetObjectItemCaseSensitive(cell, "OAM");
+
+ //Attr0
+ cJSON *Attr0 = cJSON_GetObjectItemCaseSensitive(OAM, "Attr0");
+
+ cJSON *YCoordinate = cJSON_GetObjectItemCaseSensitive(Attr0, "YCoordinate");
+ cJSON *Rotation = cJSON_GetObjectItemCaseSensitive(Attr0, "Rotation");
+ cJSON *SizeDisable = cJSON_GetObjectItemCaseSensitive(Attr0, "SizeDisable");
+ cJSON *Mode = cJSON_GetObjectItemCaseSensitive(Attr0, "Mode");
+ cJSON *Mosaic = cJSON_GetObjectItemCaseSensitive(Attr0, "Mosaic");
+ cJSON *Colours = cJSON_GetObjectItemCaseSensitive(Attr0, "Colours");
+ cJSON *Shape = cJSON_GetObjectItemCaseSensitive(Attr0, "Shape");
+
+ options->cells[i]->oam.attr0.YCoordinate = GetInt(YCoordinate);
+ options->cells[i]->oam.attr0.Rotation = GetBool(Rotation);
+ options->cells[i]->oam.attr0.SizeDisable = GetBool(SizeDisable);
+ options->cells[i]->oam.attr0.Mode = GetInt(Mode);
+ options->cells[i]->oam.attr0.Mosaic = GetBool(Mosaic);
+ options->cells[i]->oam.attr0.Colours = GetInt(Colours);
+ options->cells[i]->oam.attr0.Shape = GetInt(Shape);
+
+ //Attr1
+ cJSON *Attr1 = cJSON_GetObjectItemCaseSensitive(OAM, "Attr1");
+
+ cJSON *XCoordinate = cJSON_GetObjectItemCaseSensitive(Attr1, "XCoordinate");
+ cJSON *RotationScaling = cJSON_GetObjectItemCaseSensitive(Attr1, "RotationScaling");
+ cJSON *Size = cJSON_GetObjectItemCaseSensitive(Attr1, "Size");
+
+ options->cells[i]->oam.attr1.XCoordinate = GetInt(XCoordinate);
+ options->cells[i]->oam.attr1.RotationScaling = GetInt(RotationScaling);
+ options->cells[i]->oam.attr1.Size = GetInt(Size);
+
+ //Attr2
+ cJSON *Attr2 = cJSON_GetObjectItemCaseSensitive(OAM, "Attr2");
+
+ cJSON *CharName = cJSON_GetObjectItemCaseSensitive(Attr2, "CharName");
+ cJSON *Priority = cJSON_GetObjectItemCaseSensitive(Attr2, "Priority");
+ cJSON *Palette = cJSON_GetObjectItemCaseSensitive(Attr2, "Palette");
+
+ options->cells[i]->oam.attr2.CharName = GetInt(CharName);
+ options->cells[i]->oam.attr2.Priority = GetInt(Priority);
+ options->cells[i]->oam.attr2.Palette = GetInt(Palette);
+
+ i++;
+ }
+
+ cJSON_Delete(json);
+ free(jsonString);
+ return options;
+}
+
+struct JsonToScreenOptions *ParseNSCRJson(char *path)
+{
+ int fileLength;
+ unsigned char *jsonString = ReadWholeFile(path, &fileLength);
+
+ cJSON *json = cJSON_Parse((const char *)jsonString);
+
+ struct JsonToScreenOptions *options = malloc(sizeof(struct JsonToScreenOptions));
+
+ if (json == NULL)
+ {
+ const char *errorPtr = cJSON_GetErrorPtr();
+ FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
+ }
+
+ cJSON *Height = cJSON_GetObjectItemCaseSensitive(json, "height");
+ cJSON *Width = cJSON_GetObjectItemCaseSensitive(json, "width");
+
+ options->height = GetInt(Height);
+ options->width = GetInt(Width);
+
+ options->data = malloc(sizeof(unsigned short) * options->height * options->width);
+
+ cJSON *layer = NULL;
+ cJSON *layers = cJSON_GetObjectItemCaseSensitive(json, "layers");
+ cJSON_ArrayForEach(layer, layers)
+ {
+ cJSON *tile = NULL;
+ cJSON *data = cJSON_GetObjectItemCaseSensitive(layer, "data");
+ int i = 0;
+ cJSON_ArrayForEach(tile, data)
+ {
+ options->data[i] = (short)(GetInt(tile) - 1); //TODO horizontal and vertical flips
+ i++;
+ }
+ }
+
+ cJSON_Delete(json);
+ free(jsonString);
+ return options;
+}
+
+void FreeNCERCell(struct JsonToCellOptions *options)
+{
+ for (int i = 0; i < options->cellCount; i++)
+ {
+ if (options->label)
+ {
+ free(options->cells[i]->label);
+ }
+ free(options->cells[i]);
+ }
+ free(options);
+}
+
+void FreeNSCRScreen(struct JsonToScreenOptions *options)
+{
+ free(options->data);
+ free(options);
+}
+