partitions -> vram transfer data, add struct/format to represent transfer data

This commit is contained in:
Joshua Smith 2024-10-20 11:18:30 -05:00
parent 8d191dbb9a
commit 819153913a
3 changed files with 95 additions and 47 deletions

85
gfx.c
View File

@ -913,8 +913,8 @@ void ReadNtrCell_CEBK(unsigned char * restrict data, unsigned int blockOffset, u
options->cellCount = data[blockOffset + 0x8] | (data[blockOffset + 0x9] << 8);
options->extended = data[blockOffset + 0xA] == 1;
int partitionOffset = (data[blockOffset + 0x14] | data[blockOffset + 0x15] << 8);
options->partitionEnabled = partitionOffset > 0;
int vramTransferOffset = (data[blockOffset + 0x14] | data[blockOffset + 0x15] << 8);
options->vramTransferEnabled = vramTransferOffset > 0;
/*if (!options->extended)
{
//in theory not extended should be implemented, however not 100% sure
@ -1005,19 +1005,23 @@ void ReadNtrCell_CEBK(unsigned char * restrict data, unsigned int blockOffset, u
}
}
if (options->partitionEnabled)
if (options->vramTransferEnabled)
{
// FindNitroDataBlock returns a block size less 0x10 for header, but this requires the real block size
int realBlockSize = blockSize + 0x10;
offset = blockOffset + 0x08 + partitionOffset;
options->partitionData = malloc(realBlockSize - offset);
int index = 0;
while (offset < realBlockSize)
offset = blockOffset + 0x08 + vramTransferOffset;
// first 2 dwords are max size and offset, offset *should* always be 0x08 since the transfer data list immediately follows this
options->vramTransferMaxSize = data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24);
offset += 0x08;
// read 1 VRAM transfer data block for each cell (this is an assumption based on the NCERs I looked at)
options->transferData = malloc(sizeof(struct CellVramTransferData *) * options->cellCount);
for (int idx = 0; idx < options->cellCount; idx++)
{
options->partitionData[index++] = (data[offset] | data[offset + 1] << 8 | data[offset + 2] << 16 | data[offset + 3] << 24);
offset += 4;
options->transferData[idx] = malloc(sizeof(struct CellVramTransferData));
options->transferData[idx]->sourceDataOffset = data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24);
options->transferData[idx]->size = data[offset + 4] | (data[offset + 5] << 8) | (data[offset + 6] << 16) | (data[offset + 7] << 24);
offset += 8;
}
options->partitionCount = index;
}
}
@ -1095,8 +1099,11 @@ void WriteNtrCell(char *path, struct JsonToCellOptions *options)
// KBEC base size: 0x08 per bank, or 0x10 per extended bank
unsigned int kbecSize = options->cellCount * (options->extended ? 0x10 : 0x08);
// additional 0x04 for each partition.
kbecSize += options->partitionCount * 0x04;
// if VRAM transfer is enabled, add 0x08 for the header and 0x08 for each cell
if (options->vramTransferEnabled)
{
kbecSize += 0x08 + (0x08 * options->cellCount);
}
// add 0x06 for number of OAMs - can be more than 1
for (int idx = 0; idx < options->cellCount * iterNum; idx += iterNum)
{
@ -1133,14 +1140,15 @@ void WriteNtrCell(char *path, struct JsonToCellOptions *options)
KBECHeader[16] = (options->mappingType & 0xFF); //not possible to be more than 8 bits, though 32 are allocated
// offset to partition data within KBEC section (offset from KBEC start + 0x08)
if (options->partitionEnabled)
// offset to VRAM transfer data within KBEC section (offset from KBEC start + 0x08)
if (options->vramTransferEnabled)
{
unsigned int partitionStart = (kbecSize + 0x20) - (options->partitionCount * 0x04) - 0x08;
KBECHeader[20] = partitionStart & 0xFF;
KBECHeader[21] = (partitionStart >> 8) & 0xFF;
KBECHeader[22] = (partitionStart >> 16) & 0xFF;
KBECHeader[23] = (partitionStart >> 24) & 0xFF;
unsigned int vramTransferLength = 0x08 + (0x08 * options->cellCount);
unsigned int vramTransferOffset = (kbecSize + 0x20) - vramTransferLength - 0x08;
KBECHeader[20] = vramTransferOffset & 0xFF;
KBECHeader[21] = (vramTransferOffset >> 8) & 0xFF;
KBECHeader[22] = (vramTransferOffset >> 16) & 0xFF;
KBECHeader[23] = (vramTransferOffset >> 24) & 0xFF;
}
fwrite(KBECHeader, 1, 0x20, fp);
@ -1239,14 +1247,35 @@ void WriteNtrCell(char *path, struct JsonToCellOptions *options)
}
}
// partition data
for (int idx = 0; idx < options->partitionCount; idx++)
// VRAM transfer data
if (options->vramTransferEnabled)
{
KBECContents[offset] = options->partitionData[idx] & 0xFF;
KBECContents[offset + 1] = (options->partitionData[idx] >> 8) & 0xFF;
KBECContents[offset + 2] = (options->partitionData[idx] >> 16) & 0xFF;
KBECContents[offset + 3] = (options->partitionData[idx] >> 24) & 0xFF;
offset += 4;
// max transfer size + fixed offset 0x08
KBECContents[offset] = options->vramTransferMaxSize & 0xFF;
KBECContents[offset + 1] = (options->vramTransferMaxSize >> 8) & 0xFF;
KBECContents[offset + 2] = (options->vramTransferMaxSize >> 16) & 0xFF;
KBECContents[offset + 3] = (options->vramTransferMaxSize >> 24) & 0xFF;
KBECContents[offset + 4] = 0x08;
offset += 8;
// write a VRAM transfer block for each cell
for (int idx = 0; idx < options->cellCount; idx++)
{
// offset
KBECContents[offset] = options->transferData[idx]->sourceDataOffset & 0xFF;
KBECContents[offset + 1] = (options->transferData[idx]->sourceDataOffset >> 8) & 0xFF;
KBECContents[offset + 2] = (options->transferData[idx]->sourceDataOffset >> 16) & 0xFF;
KBECContents[offset + 3] = (options->transferData[idx]->sourceDataOffset >> 24) & 0xFF;
// size
KBECContents[offset + 4] = options->transferData[idx]->size & 0xFF;
KBECContents[offset + 5] = (options->transferData[idx]->size >> 8) & 0xFF;
KBECContents[offset + 6] = (options->transferData[idx]->size >> 16) & 0xFF;
KBECContents[offset + 7] = (options->transferData[idx]->size >> 24) & 0xFF;
offset += 8;
}
}
fwrite(KBECContents, 1, kbecSize, fp);

46
json.c
View File

@ -47,13 +47,13 @@ struct JsonToCellOptions *ParseNCERJson(char *path)
}
cJSON *labelBool = cJSON_GetObjectItemCaseSensitive(json, "labelEnabled");
cJSON *partitionBool = cJSON_GetObjectItemCaseSensitive(json, "partitionEnabled");
cJSON *vramTransferBool = cJSON_GetObjectItemCaseSensitive(json, "vramTransferEnabled");
cJSON *extended = cJSON_GetObjectItemCaseSensitive(json, "extended");
cJSON *cellCount = cJSON_GetObjectItemCaseSensitive(json, "cellCount");
cJSON *mappingType = cJSON_GetObjectItemCaseSensitive(json, "mappingType");
options->labelEnabled = GetBool(labelBool);
options->partitionEnabled = GetBool(partitionBool);
options->vramTransferEnabled = GetBool(vramTransferBool);
options->extended = GetBool(extended);
options->cellCount = GetInt(cellCount);
options->mappingType = GetInt(mappingType);
@ -79,20 +79,27 @@ struct JsonToCellOptions *ParseNCERJson(char *path)
}
}
if (options->partitionEnabled)
if (options->vramTransferEnabled)
{
cJSON *partitionCount = cJSON_GetObjectItemCaseSensitive(json, "partitionCount");
options->partitionCount = GetInt(partitionCount);
options->partitionData = malloc(sizeof(int) * options->partitionCount);
cJSON *vramTransferMaxSize = cJSON_GetObjectItemCaseSensitive(json, "vramTransferMaxSize");
options->vramTransferMaxSize = GetInt(vramTransferMaxSize);
options->transferData = malloc(sizeof(struct CellVramTransferData *) * options->cellCount);
cJSON *partitions = cJSON_GetObjectItemCaseSensitive(json, "partitions");
cJSON *partition = NULL;
cJSON *transfers = cJSON_GetObjectItemCaseSensitive(json, "transferData");
cJSON *transfer = NULL;
int j = 0;
cJSON_ArrayForEach(partition, partitions)
cJSON_ArrayForEach(transfer, transfers)
{
int partitionValue = GetInt(partition);
options->partitionData[j++] = partitionValue;
cJSON *vramTransferOffset = cJSON_GetObjectItemCaseSensitive(transfer, "offset");
cJSON *vramTransferSize = cJSON_GetObjectItemCaseSensitive(transfer, "size");
options->transferData[j] = malloc(sizeof(struct CellVramTransferData));
options->transferData[j]->sourceDataOffset = GetInt(vramTransferOffset);
options->transferData[j]->size = GetInt(vramTransferSize);
j++;
}
}
@ -214,7 +221,7 @@ char *GetNCERJson(struct JsonToCellOptions *options)
cJSON_AddBoolToObject(ncer, "labelEnabled", options->labelEnabled);
cJSON_AddBoolToObject(ncer, "extended", options->extended);
cJSON_AddBoolToObject(ncer, "partitionEnabled", options->partitionEnabled);
cJSON_AddBoolToObject(ncer, "vramTransferEnabled", options->vramTransferEnabled);
cJSON_AddNumberToObject(ncer, "cellCount", options->cellCount);
cJSON_AddNumberToObject(ncer, "mappingType", options->mappingType);
@ -283,11 +290,18 @@ char *GetNCERJson(struct JsonToCellOptions *options)
cJSON_AddNumberToObject(ncer, "labelCount", options->labelCount);
}
if (options->partitionEnabled)
if (options->vramTransferEnabled)
{
cJSON *partitions = cJSON_CreateIntArray(options->partitionData, options->partitionCount);
cJSON_AddItemToObject(ncer, "partitions", partitions);
cJSON_AddNumberToObject(ncer, "partitionCount", options->partitionCount);
cJSON_AddNumberToObject(ncer, "vramTransferMaxSize", options->vramTransferMaxSize);
cJSON *transfers = cJSON_AddArrayToObject(ncer, "transferData");
for (int idx = 0; idx < options->cellCount; idx++)
{
cJSON *transfer = cJSON_CreateObject();
cJSON_AddNumberToObject(transfer, "offset", options->transferData[idx]->sourceDataOffset);
cJSON_AddNumberToObject(transfer, "size", options->transferData[idx]->size);
cJSON_AddItemToArray(transfers, transfer);
}
}
char *jsonString = cJSON_Print(ncer);

View File

@ -51,6 +51,11 @@ struct NtrToPngOptions {
bool handleEmpty;
};
struct CellVramTransferData {
int sourceDataOffset;
int size;
};
struct Attr0 {
int YCoordinate;
bool Rotation;
@ -100,12 +105,12 @@ struct Cell {
struct JsonToCellOptions {
bool labelEnabled;
bool extended;
bool partitionEnabled;
bool vramTransferEnabled;
int mappingType;
int cellCount;
struct Cell **cells;
int *partitionData;
int partitionCount;
int vramTransferMaxSize;
struct CellVramTransferData **transferData;
char **labels;
int labelCount;
};