mirror of
https://github.com/pret/pokediamond.git
synced 2026-10-01 12:56:48 -05:00
add NANR support to nitrogfx
This commit is contained in:
5
Makefile
5
Makefile
@@ -168,7 +168,7 @@ clean: mostlyclean clean-fs clean-tools
|
||||
clean-fs:
|
||||
$(RM) $(filter %.narc %.arc,$(HOSTFS_FILES))
|
||||
$(RM) $(patsubst %.narc,%.naix,$(patsubst %.arc,%.naix,$(filter %.narc %.arc,$(HOSTFS_FILES))))
|
||||
$(RM) $(NCGR_CLEAN_LIST) $(NCLR_CLEAN_LIST) $(NCER_CLEAN_LIST) $(FS_CLEAN_LIST)
|
||||
$(RM) $(NCGR_CLEAN_LIST) $(NCLR_CLEAN_LIST) $(NCER_CLEAN_LIST) $(NANR_CLEAN_LIST) $(FS_CLEAN_LIST)
|
||||
find . \( -iname '*.1bpp' -o -iname '*.4bpp' -o -iname '*.8bpp' -o -iname '*.gbapal' -o -iname '*.lz' \) -exec $(RM) {} +
|
||||
$(RM) files/msgdata/msg/narc_*.bin
|
||||
|
||||
@@ -283,6 +283,9 @@ $(NCPR_NCLR_FILES): GFX_FLAGS = -ncpr
|
||||
%.NCER: %.json
|
||||
$(GFX) $< $@
|
||||
|
||||
%.NANR: %.json
|
||||
$(GFX) $< $@
|
||||
|
||||
%.NSCR: %_map.json
|
||||
$(GFX) $< $@ $(GFX_FLAGS)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "gx.h"
|
||||
#include "heap.h"
|
||||
|
||||
const u8 sTilemapWidthByBufferSize[] = {
|
||||
static const u8 sTilemapWidthByBufferSize[] = {
|
||||
[GF_BG_SCR_SIZE_128x128] = 0x10,
|
||||
[GF_BG_SCR_SIZE_256x256] = 0x20,
|
||||
[GF_BG_SCR_SIZE_256x512] = 0x20,
|
||||
|
||||
1
files/poketool/icongra/poke_icon/.gitignore
vendored
1
files/poketool/icongra/poke_icon/.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
narc_0000.NCLR
|
||||
narc_0001.NANR
|
||||
*.NCER
|
||||
narc_0007.NCGR
|
||||
narc_0008.NCGR
|
||||
|
||||
Binary file not shown.
32
files/poketool/icongra/poke_icon/narc_0001.json
Normal file
32
files/poketool/icongra/poke_icon/narc_0001.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"labelEnabled": true,
|
||||
"sequenceCount": 2,
|
||||
"frameCount": 2,
|
||||
"sequences": [
|
||||
{
|
||||
"frameNumber": 1,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 1
|
||||
},
|
||||
{
|
||||
"frameNumber": 1,
|
||||
"loopStartFrame": 0,
|
||||
"animationElement": 0,
|
||||
"animationType": 1,
|
||||
"playbackMode": 1
|
||||
}
|
||||
],
|
||||
"frameDelays": [1, 1],
|
||||
"animationResults": [
|
||||
{
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"index": 1
|
||||
}
|
||||
],
|
||||
"labels": ["CellAnime0", "CellAnime1"],
|
||||
"labelCount": 2
|
||||
}
|
||||
@@ -2671,6 +2671,7 @@ files/poketool/pokegra/pokegra.narc: \
|
||||
|
||||
files/poketool/icongra/poke_icon.narc: \
|
||||
files/poketool/icongra/poke_icon/narc_0000.NCLR \
|
||||
files/poketool/icongra/poke_icon/narc_0001.NANR \
|
||||
files/poketool/icongra/poke_icon/narc_0002.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0004.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0006.NCER \
|
||||
|
||||
@@ -1211,3 +1211,5 @@ NCLR_CLEAN_LIST := files/application/wifi_earth/wifi_earth/narc_0006.NCLR \
|
||||
NCER_CLEAN_LIST := files/poketool/icongra/poke_icon/narc_0002.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0004.NCER \
|
||||
files/poketool/icongra/poke_icon/narc_0006.NCER
|
||||
|
||||
NANR_CLEAN_LIST := files/poketool/icongra/poke_icon/narc_0001.NANR
|
||||
|
||||
@@ -909,12 +909,12 @@ void WriteNtrCell(char *path, struct JsonToCellOptions *options)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void WriteNtrScreen(char *outputPath, struct JsonToScreenOptions *options)
|
||||
void WriteNtrScreen(char *path, struct JsonToScreenOptions *options)
|
||||
{
|
||||
FILE *fp = fopen(outputPath, "wb");
|
||||
FILE *fp = fopen(path, "wb");
|
||||
|
||||
if (fp == NULL)
|
||||
FATAL_ERROR("Failed to open \"%s\" for writing.\n", outputPath);
|
||||
FATAL_ERROR("Failed to open \"%s\" for writing.\n", path);
|
||||
|
||||
int totalSize = options->width * options->height * 2 + 0x14;
|
||||
|
||||
@@ -947,3 +947,211 @@ void WriteNtrScreen(char *outputPath, struct JsonToScreenOptions *options)
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
||||
{
|
||||
FILE *fp = fopen(path, "wb");
|
||||
|
||||
if (fp == NULL)
|
||||
FATAL_ERROR("Failed to open \"%s\" for writing.\n", path);
|
||||
|
||||
unsigned int totalSize = 0x20 + options->sequenceCount * 0x10 + options->frameCount * 0x8;
|
||||
|
||||
//todo: check these
|
||||
for (int i = 0; i < options->frameCount; i++)
|
||||
{
|
||||
if (options->sequenceData[i]->animationElement == 0)
|
||||
totalSize += 0x4;
|
||||
else if (options->sequenceData[i]->animationElement == 1)
|
||||
totalSize += 0x10;
|
||||
else if (options->sequenceData[i]->animationElement == 2)
|
||||
totalSize += 0x8;
|
||||
}
|
||||
|
||||
unsigned int KNBASize = totalSize;
|
||||
|
||||
if (options->labelEnabled)
|
||||
{
|
||||
totalSize += 0x14;
|
||||
for (int j = 0; j < options->labelCount; j++)
|
||||
{
|
||||
totalSize += (unsigned)strlen(options->labels[j]) + 5; //strlen + terminator + pointer
|
||||
}
|
||||
}
|
||||
|
||||
WriteGenericNtrHeader(fp, "RNAN", totalSize, true, false, options->labelEnabled ? 3 : 1);
|
||||
|
||||
unsigned char KBNAHeader[0x20] =
|
||||
{
|
||||
0x4B, 0x4E, 0x42, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
KBNAHeader[4] = KNBASize & 0xff;
|
||||
KBNAHeader[5] = (KNBASize >> 8) & 0xff;
|
||||
KBNAHeader[6] = (KNBASize >> 16) & 0xff;
|
||||
KBNAHeader[7] = KNBASize >> 24;
|
||||
|
||||
KBNAHeader[8] = options->sequenceCount & 0xff;
|
||||
KBNAHeader[9] = options->sequenceCount >> 8;
|
||||
|
||||
KBNAHeader[10] = options->frameCount & 0xff;
|
||||
KBNAHeader[11] = options->frameCount >> 8;
|
||||
|
||||
unsigned int frameOffset = 0x18 + options->sequenceCount * 0x10;
|
||||
|
||||
KBNAHeader[16] = frameOffset & 0xff;
|
||||
KBNAHeader[17] = (frameOffset >> 8) & 0xff;
|
||||
KBNAHeader[18] = (frameOffset >> 16) & 0xff;
|
||||
KBNAHeader[19] = frameOffset >> 24;
|
||||
|
||||
unsigned int resultsOffset = frameOffset + options->frameCount * 0x8;
|
||||
|
||||
KBNAHeader[20] = resultsOffset & 0xff;
|
||||
KBNAHeader[21] = (resultsOffset >> 8) & 0xff;
|
||||
KBNAHeader[22] = (resultsOffset >> 16) & 0xff;
|
||||
KBNAHeader[23] = resultsOffset >> 24;
|
||||
|
||||
fwrite(KBNAHeader, 1, 0x20, fp);
|
||||
|
||||
int contentsSize = KNBASize - 0x20;
|
||||
unsigned char *KBNAContents = malloc(contentsSize);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < options->sequenceCount * 0x10; i += 0x10)
|
||||
{
|
||||
KBNAContents[i] = options->sequenceData[i / 0x10]->frameNumber & 0xff;
|
||||
KBNAContents[i + 1] = options->sequenceData[i / 0x10]->frameNumber >> 8;
|
||||
KBNAContents[i + 2] = options->sequenceData[i / 0x10]->loopStartFrame & 0xff;
|
||||
KBNAContents[i + 3] = options->sequenceData[i / 0x10]->loopStartFrame >> 8;
|
||||
KBNAContents[i + 4] = options->sequenceData[i / 0x10]->animationElement & 0xff;
|
||||
KBNAContents[i + 5] = options->sequenceData[i / 0x10]->animationElement >> 8;
|
||||
KBNAContents[i + 6] = options->sequenceData[i / 0x10]->animationType & 0xff;
|
||||
KBNAContents[i + 7] = options->sequenceData[i / 0x10]->animationType >> 8;
|
||||
KBNAContents[i + 8] = options->sequenceData[i / 0x10]->playbackMode & 0xff;
|
||||
KBNAContents[i + 9] = (options->sequenceData[i / 0x10]->playbackMode >> 8) & 0xff;
|
||||
KBNAContents[i + 10] = (options->sequenceData[i / 0x10]->playbackMode >> 16) & 0xff;
|
||||
KBNAContents[i + 11] = options->sequenceData[i / 0x10]->playbackMode >> 24;
|
||||
KBNAContents[i + 12] = (i / 0x10 * 8) & 0xff;
|
||||
KBNAContents[i + 13] = ((i / 0x10 * 8) >> 8) & 0xff;
|
||||
KBNAContents[i + 14] = ((i / 0x10 * 8) >> 16) & 0xff;
|
||||
KBNAContents[i + 15] = (i / 0x10 * 8) >> 24;
|
||||
}
|
||||
|
||||
int j;
|
||||
int resPtrCounter = 0;
|
||||
for (j = i; j < options->frameCount * 8 + i; j += 8)
|
||||
{
|
||||
KBNAContents[j] = resPtrCounter & 0xff;
|
||||
KBNAContents[j + 1] = (resPtrCounter >> 8) & 0xff;
|
||||
KBNAContents[j + 2] = (resPtrCounter >> 16) & 0xff;
|
||||
KBNAContents[j + 3] = resPtrCounter >> 24;
|
||||
if (options->sequenceData[(j - i) / 8]->animationElement == 0)
|
||||
resPtrCounter += 0x4;
|
||||
else if (options->sequenceData[(j - i) / 8]->animationElement == 1)
|
||||
resPtrCounter += 0x10;
|
||||
else if (options->sequenceData[(j - i) / 8]->animationElement == 2)
|
||||
resPtrCounter += 0x8;
|
||||
KBNAContents[j + 4] = options->frameDelay[(j - i) / 8] & 0xff;
|
||||
KBNAContents[j + 5] = options->frameDelay[(j - i) / 8] >> 8;
|
||||
KBNAContents[j + 6] = 0xEF;
|
||||
KBNAContents[j + 7] = 0xBE;
|
||||
}
|
||||
|
||||
//todo: these are extrapolated, need confirming
|
||||
resPtrCounter = j;
|
||||
for (int k = 0; k < options->frameCount; k++)
|
||||
{
|
||||
switch (options->sequenceData[k]->animationElement)
|
||||
{
|
||||
case 0:
|
||||
KBNAContents[resPtrCounter] = options->animationResults[k]->index & 0xff;
|
||||
KBNAContents[resPtrCounter + 1] = options->animationResults[k]->index >> 8;
|
||||
KBNAContents[resPtrCounter + 2] = 0xCC;
|
||||
KBNAContents[resPtrCounter + 3] = 0xCC;
|
||||
resPtrCounter += 0x4;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
KBNAContents[resPtrCounter] = options->animationResults[k]->dataSrt.index & 0xff;
|
||||
KBNAContents[resPtrCounter + 1] = options->animationResults[k]->dataSrt.index >> 8;
|
||||
KBNAContents[resPtrCounter + 2] = options->animationResults[k]->dataSrt.rotation & 0xff;
|
||||
KBNAContents[resPtrCounter + 3] = options->animationResults[k]->dataSrt.rotation >> 8;
|
||||
KBNAContents[resPtrCounter + 4] = options->animationResults[k]->dataSrt.scaleX & 0xff;
|
||||
KBNAContents[resPtrCounter + 5] = (options->animationResults[k]->dataSrt.scaleX >> 8) & 0xff;
|
||||
KBNAContents[resPtrCounter + 6] = (options->animationResults[k]->dataSrt.scaleX >> 16) & 0xff;
|
||||
KBNAContents[resPtrCounter + 7] = options->animationResults[k]->dataSrt.scaleX >> 24;
|
||||
KBNAContents[resPtrCounter + 8] = options->animationResults[k]->dataSrt.scaleY & 0xff;
|
||||
KBNAContents[resPtrCounter + 9] = (options->animationResults[k]->dataSrt.scaleY >> 8) & 0xff;
|
||||
KBNAContents[resPtrCounter + 10] = (options->animationResults[k]->dataSrt.scaleY >> 16) & 0xff;
|
||||
KBNAContents[resPtrCounter + 11] = options->animationResults[k]->dataSrt.scaleY >> 24;
|
||||
KBNAContents[resPtrCounter + 12] = options->animationResults[k]->dataSrt.positionX & 0xff;
|
||||
KBNAContents[resPtrCounter + 13] = options->animationResults[k]->dataSrt.positionX >> 8;
|
||||
KBNAContents[resPtrCounter + 14] = options->animationResults[k]->dataSrt.positionY & 0xff;
|
||||
KBNAContents[resPtrCounter + 15] = options->animationResults[k]->dataSrt.positionY >> 8;
|
||||
resPtrCounter += 0x10;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
KBNAContents[resPtrCounter] = options->animationResults[k]->dataT.index & 0xff;
|
||||
KBNAContents[resPtrCounter + 1] = options->animationResults[k]->dataT.index >> 8;
|
||||
KBNAContents[resPtrCounter + 2] = options->animationResults[k]->dataT.rotation & 0xff;
|
||||
KBNAContents[resPtrCounter + 3] = options->animationResults[k]->dataT.rotation >> 8;
|
||||
KBNAContents[resPtrCounter + 4] = options->animationResults[k]->dataT.positionX & 0xff;
|
||||
KBNAContents[resPtrCounter + 5] = options->animationResults[k]->dataT.positionX >> 8;
|
||||
KBNAContents[resPtrCounter + 6] = options->animationResults[k]->dataT.positionY & 0xff;
|
||||
KBNAContents[resPtrCounter + 7] = options->animationResults[k]->dataT.positionY >> 8;
|
||||
resPtrCounter += 0x8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(KBNAContents, 1, contentsSize, fp);
|
||||
|
||||
free(KBNAContents);
|
||||
|
||||
if (options->labelEnabled)
|
||||
{
|
||||
unsigned int lablSize = 8;
|
||||
for (int j = 0; j < options->labelCount; j++)
|
||||
{
|
||||
lablSize += (unsigned)strlen(options->labels[j]) + 5;
|
||||
}
|
||||
|
||||
unsigned char *labl = malloc(lablSize);
|
||||
|
||||
memset(labl, 0, lablSize);
|
||||
|
||||
strcpy((char *) labl, "LBAL");
|
||||
labl[4] = lablSize & 0xff;
|
||||
labl[5] = lablSize >> 8;
|
||||
|
||||
unsigned int position = 0;
|
||||
|
||||
i = 0;
|
||||
for (int j = 0; j < options->labelCount; j++)
|
||||
{
|
||||
labl[i + 8] = position & 0xff;
|
||||
labl[i + 9] = position >> 8;
|
||||
|
||||
position += (unsigned)strlen(options->labels[j]) + 1;
|
||||
i += 4;
|
||||
}
|
||||
|
||||
for (int j = 0; j < options->labelCount; j++)
|
||||
{
|
||||
strcpy((char *) (labl + (i + 8)), options->labels[j]);
|
||||
i += (int)strlen(options->labels[j]) + 1;
|
||||
}
|
||||
|
||||
fwrite(labl, 1, lablSize, fp);
|
||||
|
||||
free(labl);
|
||||
|
||||
unsigned char texu[0xc] = {0x54, 0x58, 0x45, 0x55, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
fwrite(texu, 1, 0xc, fp);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth, int palIn
|
||||
void WriteGbaPalette(char *path, struct Palette *palette);
|
||||
void WriteNtrPalette(char *path, struct Palette *palette, bool ncpr, bool ir, int bitdepth, bool pad, int compNum);
|
||||
void WriteNtrCell(char *path, struct JsonToCellOptions *options);
|
||||
void WriteNtrScreen(char *outputPath, struct JsonToScreenOptions *options);
|
||||
void WriteNtrScreen(char *path, struct JsonToScreenOptions *options);
|
||||
void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options);
|
||||
|
||||
#endif // GFX_H
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2021 red031000
|
||||
// Copyright (c) 2023 red031000
|
||||
|
||||
#include "global.h"
|
||||
#include "cJSON.h"
|
||||
@@ -230,6 +230,165 @@ struct JsonToScreenOptions *ParseNSCRJson(char *path)
|
||||
return options;
|
||||
}
|
||||
|
||||
struct JsonToAnimationOptions *ParseNANRJson(char *path)
|
||||
{
|
||||
int filelength;
|
||||
unsigned char *jsonString = ReadWholeFile(path, &filelength);
|
||||
|
||||
cJSON *json = cJSON_Parse((const char *)jsonString);
|
||||
|
||||
struct JsonToAnimationOptions *options = malloc(sizeof(struct JsonToAnimationOptions));
|
||||
|
||||
if (json == NULL)
|
||||
{
|
||||
const char *errorPtr = cJSON_GetErrorPtr();
|
||||
FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
|
||||
}
|
||||
|
||||
cJSON *sequenceCount = cJSON_GetObjectItemCaseSensitive(json, "sequenceCount");
|
||||
cJSON *frameCount = cJSON_GetObjectItemCaseSensitive(json, "frameCount");
|
||||
|
||||
options->sequenceCount = GetInt(sequenceCount);
|
||||
options->frameCount = GetInt(frameCount);
|
||||
|
||||
options->sequenceData = malloc(sizeof(struct SequenceData *) * options->sequenceCount);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < options->sequenceCount; i++)
|
||||
{
|
||||
options->sequenceData[i] = malloc(sizeof(struct SequenceData));
|
||||
}
|
||||
|
||||
cJSON *sequence = NULL;
|
||||
cJSON *sequences = cJSON_GetObjectItemCaseSensitive(json, "sequences");
|
||||
|
||||
i = 0;
|
||||
cJSON_ArrayForEach(sequence, sequences)
|
||||
{
|
||||
if (i > options->sequenceCount - 1)
|
||||
FATAL_ERROR("Sequence count is incorrect.\n");
|
||||
|
||||
cJSON *frameNumber = cJSON_GetObjectItemCaseSensitive(sequence, "frameNumber");
|
||||
cJSON *loopStartFrame = cJSON_GetObjectItemCaseSensitive(sequence, "loopStartFrame");
|
||||
cJSON *animationElement = cJSON_GetObjectItemCaseSensitive(sequence, "animationElement");
|
||||
cJSON *animationType = cJSON_GetObjectItemCaseSensitive(sequence, "animationType");
|
||||
cJSON *playbackMode = cJSON_GetObjectItemCaseSensitive(sequence, "playbackMode");
|
||||
|
||||
options->sequenceData[i]->frameNumber = GetInt(frameNumber);
|
||||
options->sequenceData[i]->loopStartFrame = GetInt(loopStartFrame);
|
||||
options->sequenceData[i]->animationElement = GetInt(animationElement);
|
||||
options->sequenceData[i]->animationType = GetInt(animationType);
|
||||
options->sequenceData[i]->playbackMode = GetInt(playbackMode);
|
||||
|
||||
//TODO: see if frame data mapping is required
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
options->frameDelay = malloc(sizeof(short) * options->frameCount);
|
||||
|
||||
cJSON *frameDelay = NULL;
|
||||
cJSON *frameDelays = cJSON_GetObjectItemCaseSensitive(json, "frameDelays");
|
||||
cJSON_ArrayForEach(frameDelay, frameDelays)
|
||||
{
|
||||
if (i > options->frameCount - 1)
|
||||
FATAL_ERROR("Frame count is incorrect.\n");
|
||||
|
||||
options->frameDelay[i] = GetInt(frameDelay);
|
||||
|
||||
//TODO: see if animation result data mapping is required
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
//todo implement extended attributes
|
||||
|
||||
options->animationResults = malloc(sizeof(struct AnimationResults *) * options->frameCount);
|
||||
|
||||
for (i = 0; i < options->frameCount; i++)
|
||||
{
|
||||
options->animationResults[i] = malloc(sizeof(struct AnimationResults));
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
cJSON *animationResult = NULL;
|
||||
cJSON *animationResults = cJSON_GetObjectItemCaseSensitive(json, "animationResults");
|
||||
cJSON_ArrayForEach(animationResult, animationResults)
|
||||
{
|
||||
if (i > options->frameCount - 1)
|
||||
FATAL_ERROR("Frame count is incorrect.\n");
|
||||
|
||||
switch (options->sequenceData[i]->animationElement) {
|
||||
case 0: { //index
|
||||
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||
options->animationResults[i]->index = GetInt(index);
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: { //SRT
|
||||
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||
cJSON *rotation = cJSON_GetObjectItemCaseSensitive(animationResult, "rotation");
|
||||
cJSON *scaleX = cJSON_GetObjectItemCaseSensitive(animationResult, "scaleX");
|
||||
cJSON *scaleY = cJSON_GetObjectItemCaseSensitive(animationResult, "scaleY");
|
||||
cJSON *positionX = cJSON_GetObjectItemCaseSensitive(animationResult, "positionX");
|
||||
cJSON *positionY = cJSON_GetObjectItemCaseSensitive(animationResult, "positionY");
|
||||
|
||||
options->animationResults[i]->dataSrt.index = GetInt(index);
|
||||
options->animationResults[i]->dataSrt.rotation = GetInt(rotation);
|
||||
options->animationResults[i]->dataSrt.scaleX = GetInt(scaleX);
|
||||
options->animationResults[i]->dataSrt.scaleY = GetInt(scaleY);
|
||||
options->animationResults[i]->dataSrt.positionX = GetInt(positionX);
|
||||
options->animationResults[i]->dataSrt.positionY = GetInt(positionY);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: { //T
|
||||
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||
cJSON *rotation = cJSON_GetObjectItemCaseSensitive(animationResult, "rotation");
|
||||
cJSON *positionX = cJSON_GetObjectItemCaseSensitive(animationResult, "positionX");
|
||||
cJSON *positionY = cJSON_GetObjectItemCaseSensitive(animationResult, "positionY");
|
||||
|
||||
options->animationResults[i]->dataSrt.index = GetInt(index);
|
||||
options->animationResults[i]->dataSrt.rotation = GetInt(rotation);
|
||||
options->animationResults[i]->dataSrt.positionX = GetInt(positionX);
|
||||
options->animationResults[i]->dataSrt.positionY = GetInt(positionY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
cJSON *labelBool = cJSON_GetObjectItemCaseSensitive(json, "labelEnabled");
|
||||
options->labelEnabled = GetBool(labelBool);
|
||||
|
||||
if (options->labelEnabled)
|
||||
{
|
||||
cJSON *labelCount = cJSON_GetObjectItemCaseSensitive(json, "labelCount");
|
||||
options->labelCount = GetInt(labelCount);
|
||||
options->labels = malloc(sizeof(char *) * options->labelCount);
|
||||
|
||||
cJSON *labels = cJSON_GetObjectItemCaseSensitive(json, "labels");
|
||||
cJSON *label = NULL;
|
||||
|
||||
int j = 0;
|
||||
cJSON_ArrayForEach(label, labels)
|
||||
{
|
||||
char *labelString = GetString(label);
|
||||
options->labels[j] = malloc(strlen(labelString) + 1);
|
||||
strcpy(options->labels[j], labelString);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
free(jsonString);
|
||||
return options;
|
||||
}
|
||||
|
||||
void FreeNCERCell(struct JsonToCellOptions *options)
|
||||
{
|
||||
for (int i = 0; i < options->cellCount; i++)
|
||||
@@ -244,6 +403,7 @@ void FreeNCERCell(struct JsonToCellOptions *options)
|
||||
}
|
||||
free(options->labels);
|
||||
}
|
||||
free(options->cells);
|
||||
free(options);
|
||||
}
|
||||
|
||||
@@ -253,3 +413,27 @@ void FreeNSCRScreen(struct JsonToScreenOptions *options)
|
||||
free(options);
|
||||
}
|
||||
|
||||
|
||||
void FreeNANRAnimation(struct JsonToAnimationOptions *options)
|
||||
{
|
||||
for (int i = 0; i < options->sequenceCount; i++)
|
||||
{
|
||||
free(options->sequenceData[i]);
|
||||
}
|
||||
for (int i = 0; i < options->frameCount; i++)
|
||||
{
|
||||
free(options->animationResults[i]);
|
||||
}
|
||||
if (options->labelEnabled)
|
||||
{
|
||||
for (int j = 0; j < options->labelCount; j++)
|
||||
{
|
||||
free(options->labels[j]);
|
||||
}
|
||||
free(options->labels);
|
||||
}
|
||||
free(options->sequenceData);
|
||||
free(options->animationResults);
|
||||
free(options->frameDelay);
|
||||
free(options);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
|
||||
struct JsonToCellOptions *ParseNCERJson(char *path);
|
||||
struct JsonToScreenOptions *ParseNSCRJson(char *path);
|
||||
struct JsonToAnimationOptions *ParseNANRJson(char *path);
|
||||
void FreeNCERCell(struct JsonToCellOptions *options);
|
||||
void FreeNSCRScreen(struct JsonToScreenOptions *options);
|
||||
void FreeNANRAnimation(struct JsonToAnimationOptions *options);
|
||||
|
||||
#endif //JSON_H
|
||||
|
||||
@@ -732,6 +732,17 @@ void HandleJsonToNtrScreenCommand(char *inputPath, char *outputPath, int argc UN
|
||||
FreeNSCRScreen(options);
|
||||
}
|
||||
|
||||
void HandleJsonToNtrAnimationCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||
{
|
||||
struct JsonToAnimationOptions *options;
|
||||
|
||||
options = ParseNANRJson(inputPath);
|
||||
|
||||
WriteNtrAnimation(outputPath, options);
|
||||
|
||||
FreeNANRAnimation(options);
|
||||
}
|
||||
|
||||
void HandleLatinFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||
{
|
||||
struct Image image;
|
||||
@@ -992,6 +1003,7 @@ int main(int argc, char **argv)
|
||||
{ "png", "fwjpnfont", HandlePngToFullwidthJapaneseFontCommand },
|
||||
{ "json", "NCER", HandleJsonToNtrCellCommand },
|
||||
{ "json", "NSCR", HandleJsonToNtrScreenCommand },
|
||||
{ "json", "NANR", HandleJsonToNtrAnimationCommand },
|
||||
{ NULL, "huff", HandleHuffCompressCommand },
|
||||
{ NULL, "lz", HandleLZCompressCommand },
|
||||
{ "huff", NULL, HandleHuffDecompressCommand },
|
||||
|
||||
@@ -91,4 +91,47 @@ struct JsonToScreenOptions {
|
||||
int bitdepth;
|
||||
};
|
||||
|
||||
struct SequenceData {
|
||||
short frameNumber;
|
||||
short loopStartFrame;
|
||||
short animationElement;
|
||||
short animationType;
|
||||
int playbackMode;
|
||||
};
|
||||
|
||||
struct AnimationDataSRT {
|
||||
short index;
|
||||
unsigned short rotation;
|
||||
int scaleX;
|
||||
int scaleY;
|
||||
short positionX;
|
||||
short positionY;
|
||||
};
|
||||
|
||||
struct AnimationDataT {
|
||||
short index;
|
||||
unsigned short rotation;
|
||||
short positionX;
|
||||
short positionY;
|
||||
};
|
||||
|
||||
struct AnimationResults {
|
||||
union {
|
||||
short index;
|
||||
struct AnimationDataSRT dataSrt;
|
||||
struct AnimationDataT dataT;
|
||||
};
|
||||
};
|
||||
|
||||
struct JsonToAnimationOptions {
|
||||
short sequenceCount;
|
||||
short frameCount;
|
||||
struct SequenceData **sequenceData;
|
||||
short *frameDelay;
|
||||
struct AnimationResults **animationResults;
|
||||
bool labelEnabled;
|
||||
char **labels;
|
||||
int labelCount;
|
||||
};
|
||||
|
||||
#endif // OPTIONS_H
|
||||
|
||||
Reference in New Issue
Block a user