mirror of
https://github.com/red031000/nitrogfx.git
synced 2025-06-18 21:25:38 -04:00
update NANR parser to handle resultType better and handle padding
This commit is contained in:
parent
f9a9fdc11b
commit
d55fbd6ff4
125
gfx.c
125
gfx.c
@ -1327,8 +1327,8 @@ void ReadNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
{
|
{
|
||||||
options->sequenceData[i]->frameCount = data[offset] | (data[offset + 1] << 8);
|
options->sequenceData[i]->frameCount = data[offset] | (data[offset + 1] << 8);
|
||||||
options->sequenceData[i]->loopStartFrame = data[offset + 2] | (data[offset + 3] << 8);
|
options->sequenceData[i]->loopStartFrame = data[offset + 2] | (data[offset + 3] << 8);
|
||||||
options->sequenceData[i]->animationElement = data[offset + 4] | (data[offset + 5] << 8);
|
options->sequenceData[i]->animationType = data[offset + 4] | (data[offset + 5] << 8);
|
||||||
options->sequenceData[i]->animationType = data[offset + 6] | (data[offset + 7] << 8);
|
options->sequenceData[i]->animationType2 = data[offset + 6] | (data[offset + 7] << 8);
|
||||||
options->sequenceData[i]->playbackMode = data[offset + 8] | (data[offset + 9] << 8) | (data[offset + 10] << 16) | (data[offset + 11] << 24);
|
options->sequenceData[i]->playbackMode = data[offset + 8] | (data[offset + 9] << 8) | (data[offset + 10] << 16) | (data[offset + 11] << 24);
|
||||||
frameOffsets[i] = data[offset + 12] | (data[offset + 13] << 8) | (data[offset + 14] << 16) | (data[offset + 15] << 24);
|
frameOffsets[i] = data[offset + 12] | (data[offset + 13] << 8) | (data[offset + 14] << 16) | (data[offset + 15] << 24);
|
||||||
|
|
||||||
@ -1358,6 +1358,7 @@ void ReadNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
{
|
{
|
||||||
if (resultOffsets[k] == options->sequenceData[i]->frameData[j]->resultOffset)
|
if (resultOffsets[k] == options->sequenceData[i]->frameData[j]->resultOffset)
|
||||||
{
|
{
|
||||||
|
options->sequenceData[i]->frameData[j]->resultId = k;
|
||||||
present = true;
|
present = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1370,6 +1371,7 @@ void ReadNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
{
|
{
|
||||||
if (resultOffsets[k] == -1)
|
if (resultOffsets[k] == -1)
|
||||||
{
|
{
|
||||||
|
options->sequenceData[i]->frameData[j]->resultId = k;
|
||||||
resultOffsets[k] = options->sequenceData[i]->frameData[j]->resultOffset;
|
resultOffsets[k] = options->sequenceData[i]->frameData[j]->resultOffset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1400,37 +1402,49 @@ void ReadNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
options->animationResults[i] = malloc(sizeof(struct AnimationResults));
|
options->animationResults[i] = malloc(sizeof(struct AnimationResults));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store the animationType of the corresponding sequence as this result's resultType
|
||||||
|
for (int i = 0; i < options->sequenceCount; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < options->sequenceData[i]->frameCount; j++)
|
||||||
|
{
|
||||||
|
options->animationResults[options->sequenceData[i]->frameData[j]->resultId]->resultType = options->sequenceData[i]->animationType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int resultOffset = 0;
|
int resultOffset = 0;
|
||||||
|
int lastSequence = 0;
|
||||||
for (int i = 0; i < options->resultCount; i++)
|
for (int i = 0; i < options->resultCount; i++)
|
||||||
{
|
{
|
||||||
if (data[offset + 2] == 0xCC && data[offset + 3] == 0xCC)
|
// find the earliest sequence matching this animation result,
|
||||||
{
|
// and add padding if the sequence changes + the total offset is not 4-byte aligned.
|
||||||
options->animationResults[i]->resultType = 0;
|
bool found = false;
|
||||||
}
|
|
||||||
else if (data[offset + 2] == 0xEF && data[offset + 3] == 0xBE)
|
|
||||||
{
|
|
||||||
options->animationResults[i]->resultType = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
options->animationResults[i]->resultType = 1;
|
|
||||||
}
|
|
||||||
for (int j = 0; j < options->sequenceCount; j++)
|
for (int j = 0; j < options->sequenceCount; j++)
|
||||||
{
|
{
|
||||||
for (int k = 0; k < options->sequenceData[j]->frameCount; k++)
|
for (int k = 0; k < options->sequenceData[j]->frameCount; k++)
|
||||||
{
|
{
|
||||||
if (options->sequenceData[j]->frameData[k]->resultOffset == resultOffset)
|
if (options->sequenceData[j]->frameData[k]->resultId == i)
|
||||||
{
|
{
|
||||||
options->sequenceData[j]->frameData[k]->resultId = i;
|
if (lastSequence != j)
|
||||||
|
{
|
||||||
|
lastSequence = j;
|
||||||
|
if (resultOffset % 4 != 0)
|
||||||
|
{
|
||||||
|
resultOffset += 0x2;
|
||||||
|
offset += 0x2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (found) break;
|
||||||
}
|
}
|
||||||
switch (options->animationResults[i]->resultType)
|
switch (options->animationResults[i]->resultType)
|
||||||
{
|
{
|
||||||
case 0: //index
|
case 0: //index
|
||||||
options->animationResults[i]->index = data[offset] | (data[offset + 1] << 8);
|
options->animationResults[i]->index = data[offset] | (data[offset + 1] << 8);
|
||||||
resultOffset += 0x4;
|
resultOffset += 0x2;
|
||||||
offset += 0x4;
|
offset += 0x2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: //SRT
|
case 1: //SRT
|
||||||
@ -1454,6 +1468,9 @@ void ReadNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add any missed padding from the final frame before processing labels
|
||||||
|
if (offset % 4 != 0) offset += 2;
|
||||||
|
|
||||||
if (options->labelEnabled)
|
if (options->labelEnabled)
|
||||||
{
|
{
|
||||||
options->labelCount = options->sequenceCount; //*should* be the same
|
options->labelCount = options->sequenceCount; //*should* be the same
|
||||||
@ -1479,17 +1496,60 @@ void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
|
|
||||||
unsigned int totalSize = 0x20 + options->sequenceCount * 0x10 + options->frameCount * 0x8;
|
unsigned int totalSize = 0x20 + options->sequenceCount * 0x10 + options->frameCount * 0x8;
|
||||||
|
|
||||||
//todo: check these
|
|
||||||
for (int i = 0; i < options->resultCount; i++)
|
for (int i = 0; i < options->resultCount; i++)
|
||||||
{
|
{
|
||||||
if (options->animationResults[i]->resultType == 0)
|
if (options->animationResults[i]->resultType == 0)
|
||||||
totalSize += 0x4;
|
totalSize += 0x2;
|
||||||
else if (options->animationResults[i]->resultType == 1)
|
else if (options->animationResults[i]->resultType == 1)
|
||||||
totalSize += 0x10;
|
totalSize += 0x10;
|
||||||
else if (options->animationResults[i]->resultType == 2)
|
else if (options->animationResults[i]->resultType == 2)
|
||||||
totalSize += 0x8;
|
totalSize += 0x8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// foreach sequence, need to check whether padding is applied for its results
|
||||||
|
// then add 0x02 to totalSize if padding exists.
|
||||||
|
// padding exists if the animation results for that sequence are not 4-byte aligned.
|
||||||
|
// also flag the last result for the sequence with `padded` to save having to redo this same step later.
|
||||||
|
int *usedResults = malloc(sizeof(int) * options->frameCount);
|
||||||
|
memset(usedResults, -1, sizeof(int) * options->frameCount);
|
||||||
|
for (int i = 0; i < options->sequenceCount; i++)
|
||||||
|
{
|
||||||
|
int sequenceLen = 0;
|
||||||
|
int resultIndex = 0;
|
||||||
|
for (int j = 0; j < options->sequenceData[i]->frameCount; j++)
|
||||||
|
{
|
||||||
|
// check if the result has already been used
|
||||||
|
for (resultIndex = 0; resultIndex < options->resultCount; resultIndex++)
|
||||||
|
{
|
||||||
|
if (usedResults[resultIndex] == options->sequenceData[i]->frameData[j]->resultId)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not already used, add it to the list
|
||||||
|
if (usedResults[resultIndex] == -1)
|
||||||
|
{
|
||||||
|
usedResults[resultIndex] = options->sequenceData[i]->frameData[j]->resultId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not already used, add it to the result size for the sequence
|
||||||
|
if (options->animationResults[resultIndex]->resultType == 0)
|
||||||
|
sequenceLen += 0x2;
|
||||||
|
else if (options->animationResults[resultIndex]->resultType == 1)
|
||||||
|
sequenceLen += 0x10;
|
||||||
|
else if (options->animationResults[resultIndex]->resultType == 2)
|
||||||
|
sequenceLen += 0x8;
|
||||||
|
}
|
||||||
|
if (sequenceLen % 4 != 0)
|
||||||
|
{
|
||||||
|
totalSize += 0x02;
|
||||||
|
// mark the last animationResult for the sequence as padded, this saves needing to check this again later
|
||||||
|
options->animationResults[resultIndex]->padded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int KNBASize = totalSize;
|
unsigned int KNBASize = totalSize;
|
||||||
|
|
||||||
if (options->labelEnabled)
|
if (options->labelEnabled)
|
||||||
@ -1547,10 +1607,10 @@ void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
KBNAContents[i + 1] = options->sequenceData[i / 0x10]->frameCount >> 8;
|
KBNAContents[i + 1] = options->sequenceData[i / 0x10]->frameCount >> 8;
|
||||||
KBNAContents[i + 2] = options->sequenceData[i / 0x10]->loopStartFrame & 0xff;
|
KBNAContents[i + 2] = options->sequenceData[i / 0x10]->loopStartFrame & 0xff;
|
||||||
KBNAContents[i + 3] = options->sequenceData[i / 0x10]->loopStartFrame >> 8;
|
KBNAContents[i + 3] = options->sequenceData[i / 0x10]->loopStartFrame >> 8;
|
||||||
KBNAContents[i + 4] = options->sequenceData[i / 0x10]->animationElement & 0xff;
|
KBNAContents[i + 4] = options->sequenceData[i / 0x10]->animationType & 0xff;
|
||||||
KBNAContents[i + 5] = options->sequenceData[i / 0x10]->animationElement >> 8;
|
KBNAContents[i + 5] = (options->sequenceData[i / 0x10]->animationType >> 8) & 0xff;
|
||||||
KBNAContents[i + 6] = options->sequenceData[i / 0x10]->animationType & 0xff;
|
KBNAContents[i + 6] = options->sequenceData[i / 0x10]->animationType2 & 0xff;
|
||||||
KBNAContents[i + 7] = options->sequenceData[i / 0x10]->animationType >> 8;
|
KBNAContents[i + 7] = (options->sequenceData[i / 0x10]->animationType2 >> 8) & 0xff;
|
||||||
KBNAContents[i + 8] = options->sequenceData[i / 0x10]->playbackMode & 0xff;
|
KBNAContents[i + 8] = options->sequenceData[i / 0x10]->playbackMode & 0xff;
|
||||||
KBNAContents[i + 9] = (options->sequenceData[i / 0x10]->playbackMode >> 8) & 0xff;
|
KBNAContents[i + 9] = (options->sequenceData[i / 0x10]->playbackMode >> 8) & 0xff;
|
||||||
KBNAContents[i + 10] = (options->sequenceData[i / 0x10]->playbackMode >> 16) & 0xff;
|
KBNAContents[i + 10] = (options->sequenceData[i / 0x10]->playbackMode >> 16) & 0xff;
|
||||||
@ -1570,11 +1630,13 @@ void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
int resPtr = 0;
|
int resPtr = 0;
|
||||||
for (int l = 0; l < options->sequenceData[m]->frameData[k]->resultId; l++) {
|
for (int l = 0; l < options->sequenceData[m]->frameData[k]->resultId; l++) {
|
||||||
if (options->animationResults[l]->resultType == 0)
|
if (options->animationResults[l]->resultType == 0)
|
||||||
resPtr += 0x4;
|
resPtr += 0x2;
|
||||||
else if (options->animationResults[l]->resultType == 1)
|
else if (options->animationResults[l]->resultType == 1)
|
||||||
resPtr += 0x10;
|
resPtr += 0x10;
|
||||||
else if (options->animationResults[l]->resultType == 2)
|
else if (options->animationResults[l]->resultType == 2)
|
||||||
resPtr += 0x8;
|
resPtr += 0x8;
|
||||||
|
|
||||||
|
if (options->animationResults[l]->padded) resPtr += 0x02;
|
||||||
}
|
}
|
||||||
KBNAContents[j + (k * 8)] = resPtr & 0xff;
|
KBNAContents[j + (k * 8)] = resPtr & 0xff;
|
||||||
KBNAContents[j + (k * 8) + 1] = (resPtr >> 8) & 0xff;
|
KBNAContents[j + (k * 8) + 1] = (resPtr >> 8) & 0xff;
|
||||||
@ -1588,7 +1650,6 @@ void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
j += options->sequenceData[m]->frameCount * 8;
|
j += options->sequenceData[m]->frameCount * 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: these are extrapolated, need confirming
|
|
||||||
int resPtrCounter = j;
|
int resPtrCounter = j;
|
||||||
for (int k = 0; k < options->resultCount; k++)
|
for (int k = 0; k < options->resultCount; k++)
|
||||||
{
|
{
|
||||||
@ -1597,9 +1658,7 @@ void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
case 0:
|
case 0:
|
||||||
KBNAContents[resPtrCounter] = options->animationResults[k]->index & 0xff;
|
KBNAContents[resPtrCounter] = options->animationResults[k]->index & 0xff;
|
||||||
KBNAContents[resPtrCounter + 1] = options->animationResults[k]->index >> 8;
|
KBNAContents[resPtrCounter + 1] = options->animationResults[k]->index >> 8;
|
||||||
KBNAContents[resPtrCounter + 2] = 0xCC;
|
resPtrCounter += 0x2;
|
||||||
KBNAContents[resPtrCounter + 3] = 0xCC;
|
|
||||||
resPtrCounter += 0x4;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@ -1634,6 +1693,14 @@ void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options)
|
|||||||
resPtrCounter += 0x8;
|
resPtrCounter += 0x8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use the `padded` flag which was stored earlier to inject padding
|
||||||
|
if (options->animationResults[k]->padded)
|
||||||
|
{
|
||||||
|
KBNAContents[resPtrCounter] = 0xCC;
|
||||||
|
KBNAContents[resPtrCounter + 1] = 0xCC;
|
||||||
|
resPtrCounter += 0x2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(KBNAContents, 1, contentsSize, fp);
|
fwrite(KBNAContents, 1, contentsSize, fp);
|
||||||
|
6
json.c
6
json.c
@ -376,14 +376,14 @@ struct JsonToAnimationOptions *ParseNANRJson(char *path)
|
|||||||
|
|
||||||
cJSON *frameCount = cJSON_GetObjectItemCaseSensitive(sequence, "frameCount");
|
cJSON *frameCount = cJSON_GetObjectItemCaseSensitive(sequence, "frameCount");
|
||||||
cJSON *loopStartFrame = cJSON_GetObjectItemCaseSensitive(sequence, "loopStartFrame");
|
cJSON *loopStartFrame = cJSON_GetObjectItemCaseSensitive(sequence, "loopStartFrame");
|
||||||
cJSON *animationElement = cJSON_GetObjectItemCaseSensitive(sequence, "animationElement");
|
|
||||||
cJSON *animationType = cJSON_GetObjectItemCaseSensitive(sequence, "animationType");
|
cJSON *animationType = cJSON_GetObjectItemCaseSensitive(sequence, "animationType");
|
||||||
|
cJSON *animationType2 = cJSON_GetObjectItemCaseSensitive(sequence, "animationType2");
|
||||||
cJSON *playbackMode = cJSON_GetObjectItemCaseSensitive(sequence, "playbackMode");
|
cJSON *playbackMode = cJSON_GetObjectItemCaseSensitive(sequence, "playbackMode");
|
||||||
|
|
||||||
options->sequenceData[i]->frameCount = GetInt(frameCount);
|
options->sequenceData[i]->frameCount = GetInt(frameCount);
|
||||||
options->sequenceData[i]->loopStartFrame = GetInt(loopStartFrame);
|
options->sequenceData[i]->loopStartFrame = GetInt(loopStartFrame);
|
||||||
options->sequenceData[i]->animationElement = GetInt(animationElement);
|
|
||||||
options->sequenceData[i]->animationType = GetInt(animationType);
|
options->sequenceData[i]->animationType = GetInt(animationType);
|
||||||
|
options->sequenceData[i]->animationType2 = GetInt(animationType2);
|
||||||
options->sequenceData[i]->playbackMode = GetInt(playbackMode);
|
options->sequenceData[i]->playbackMode = GetInt(playbackMode);
|
||||||
|
|
||||||
options->sequenceData[i]->frameData = malloc(sizeof(struct FrameData *) * options->sequenceData[i]->frameCount);
|
options->sequenceData[i]->frameData = malloc(sizeof(struct FrameData *) * options->sequenceData[i]->frameCount);
|
||||||
@ -521,8 +521,8 @@ char *GetNANRJson(struct JsonToAnimationOptions *options)
|
|||||||
cJSON *sequence = cJSON_CreateObject();
|
cJSON *sequence = cJSON_CreateObject();
|
||||||
cJSON_AddNumberToObject(sequence, "frameCount", options->sequenceData[i]->frameCount);
|
cJSON_AddNumberToObject(sequence, "frameCount", options->sequenceData[i]->frameCount);
|
||||||
cJSON_AddNumberToObject(sequence, "loopStartFrame", options->sequenceData[i]->loopStartFrame);
|
cJSON_AddNumberToObject(sequence, "loopStartFrame", options->sequenceData[i]->loopStartFrame);
|
||||||
cJSON_AddNumberToObject(sequence, "animationElement", options->sequenceData[i]->animationElement);
|
|
||||||
cJSON_AddNumberToObject(sequence, "animationType", options->sequenceData[i]->animationType);
|
cJSON_AddNumberToObject(sequence, "animationType", options->sequenceData[i]->animationType);
|
||||||
|
cJSON_AddNumberToObject(sequence, "animationType2", options->sequenceData[i]->animationType2);
|
||||||
cJSON_AddNumberToObject(sequence, "playbackMode", options->sequenceData[i]->playbackMode);
|
cJSON_AddNumberToObject(sequence, "playbackMode", options->sequenceData[i]->playbackMode);
|
||||||
|
|
||||||
cJSON *frameData = cJSON_AddArrayToObject(sequence, "frameData");
|
cJSON *frameData = cJSON_AddArrayToObject(sequence, "frameData");
|
||||||
|
@ -123,8 +123,8 @@ struct FrameData {
|
|||||||
struct SequenceData {
|
struct SequenceData {
|
||||||
short frameCount;
|
short frameCount;
|
||||||
short loopStartFrame;
|
short loopStartFrame;
|
||||||
short animationElement;
|
|
||||||
short animationType;
|
short animationType;
|
||||||
|
short animationType2;
|
||||||
int playbackMode;
|
int playbackMode;
|
||||||
struct FrameData **frameData;
|
struct FrameData **frameData;
|
||||||
};
|
};
|
||||||
@ -147,6 +147,7 @@ struct AnimationDataT {
|
|||||||
|
|
||||||
struct AnimationResults {
|
struct AnimationResults {
|
||||||
short resultType;
|
short resultType;
|
||||||
|
bool padded;
|
||||||
union {
|
union {
|
||||||
short index;
|
short index;
|
||||||
struct AnimationDataSRT dataSrt;
|
struct AnimationDataSRT dataSrt;
|
||||||
|
Loading…
Reference in New Issue
Block a user