summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/nitrogfx/gfx.c139
-rw-r--r--tools/nitrogfx/gfx.h2
-rw-r--r--tools/nitrogfx/main.c7
-rw-r--r--tools/nitrogfx/options.h1
4 files changed, 132 insertions, 17 deletions
diff --git a/tools/nitrogfx/gfx.c b/tools/nitrogfx/gfx.c
index 7c57d269..c47b5903 100644
--- a/tools/nitrogfx/gfx.c
+++ b/tools/nitrogfx/gfx.c
@@ -93,6 +93,34 @@ static void ConvertFromTiles4Bpp(unsigned char *src, unsigned char *dest, int nu
}
}
+static uint32_t ConvertFromScanned4Bpp(unsigned char *src, unsigned char *dest, int fileSize, bool invertColours)
+{
+ uint32_t encValue = (src[fileSize - 1] << 8) | src[fileSize - 2];
+ for (int i = fileSize; i > 0; i -= 2)
+ {
+ uint16_t val = (src[i - 1] << 8) | src[i - 2];
+ val ^= (encValue & 0xFFFF);
+ src[i - 1] = (val >> 8);
+ src[i - 2] = val;
+ encValue = encValue * 1103515245;
+ encValue = encValue + 24691;
+ }
+ for (int i = 0; i < fileSize; i++)
+ {
+ unsigned char srcPixelPair = src[i];
+ unsigned char leftPixel = srcPixelPair & 0xF;
+ unsigned char rightPixel = srcPixelPair >> 4;
+
+ if (invertColours) {
+ leftPixel = 15 - leftPixel;
+ rightPixel = 15 - rightPixel;
+ }
+
+ dest[i] = (leftPixel << 4) | rightPixel;
+ }
+ return encValue;
+}
+
static void ConvertFromTiles8Bpp(unsigned char *src, unsigned char *dest, int numTiles, int metatilesWide, int metatileWidth, int metatileHeight, bool invertColors)
{
int subTileX = 0;
@@ -177,6 +205,30 @@ static void ConvertToTiles4Bpp(unsigned char *src, unsigned char *dest, int numT
}
}
+static void ConvertToScanned4Bpp(unsigned char *src, unsigned char *dest, int fileSize, bool invertColours, uint32_t encValue)
+{
+ for (int i = 0; i < fileSize; i++)
+ {
+ unsigned char srcPixelPair = src[i];
+ unsigned char leftPixel = srcPixelPair & 0xF;
+ unsigned char rightPixel = srcPixelPair >> 4;
+ if (invertColours) {
+ leftPixel = 15 - leftPixel;
+ rightPixel = 15 - rightPixel;
+ }
+ dest[i] = (leftPixel << 4) | rightPixel;
+ }
+
+ for (int i = 1; i < fileSize; i += 2)
+ {
+ uint16_t val = (dest[i] << 8) | dest[i - 1];
+ encValue = (encValue - 24691) * 4005161829;
+ val ^= (encValue & 0xFFFF);
+ dest[i] = (val >> 8);
+ dest[i - 1] = val;
+ }
+}
+
static void ConvertToTiles8Bpp(unsigned char *src, unsigned char *dest, int numTiles, int metatilesWide, int metatileWidth, int metatileHeight, bool invertColors)
{
int subTileX = 0;
@@ -272,6 +324,8 @@ void ReadNtrImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, i
unsigned char *imageData = charHeader + 0x20;
+ bool scanned = charHeader[0x14];
+
int tileSize = bitDepth * 8;
int numTiles = (charHeader[0x18] + (charHeader[0x19] << 8) + (charHeader[0x1A] << 16) + (charHeader[0x1B] << 24))
@@ -296,13 +350,37 @@ void ReadNtrImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, i
int metatilesWide = tilesWidth / metatileWidth;
- switch (bitDepth) {
- case 4:
- ConvertFromTiles4Bpp(imageData, image->pixels, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors);
- break;
- case 8:
- ConvertFromTiles8Bpp(imageData, image->pixels, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors);
- break;
+ if (scanned)
+ {
+ uint32_t key;
+ switch (bitDepth)
+ {
+ case 4:
+ key = ConvertFromScanned4Bpp(imageData, image->pixels, fileSize - 0x30, invertColors);
+ break;
+ case 8:
+ FATAL_ERROR("8bpp is not implemented yet\n");
+ break;
+ }
+ FILE *fp = fopen(strcat(path, ".key"), "wb");
+ if (fp == NULL)
+ FATAL_ERROR("Failed to open key file for writing.\n");
+ fwrite(&key, 4, 1, fp);
+ fclose(fp);
+ }
+ else
+ {
+ switch (bitDepth)
+ {
+ case 4:
+ ConvertFromTiles4Bpp(imageData, image->pixels, numTiles, metatilesWide, metatileWidth, metatileHeight,
+ invertColors);
+ break;
+ case 8:
+ ConvertFromTiles8Bpp(imageData, image->pixels, numTiles, metatilesWide, metatileWidth, metatileHeight,
+ invertColors);
+ break;
+ }
}
free(buffer);
@@ -359,7 +437,7 @@ void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int m
free(buffer);
}
-void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc)
+void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool scanned)
{
FILE *fp = fopen(path, "wb");
@@ -398,13 +476,39 @@ void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, in
int metatilesWide = tilesWidth / metatileWidth;
- switch (bitDepth) {
- case 4:
- ConvertToTiles4Bpp(image->pixels, pixelBuffer, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors);
- break;
- case 8:
- ConvertToTiles8Bpp(image->pixels, pixelBuffer, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors);
- break;
+ if (scanned)
+ {
+ FILE *fp2 = fopen(strcat(path, ".key"), "rb");
+ if (fp2 == NULL)
+ FATAL_ERROR("Failed to open key file for reading.\n");
+ uint32_t key;
+ size_t count = fread(&key, 4, 1, fp2);
+ if (count != 1)
+ FATAL_ERROR("Not a valid key file.\n");
+ fclose(fp2);
+ switch (bitDepth)
+ {
+ case 4:
+ ConvertToScanned4Bpp(image->pixels, pixelBuffer, bufferSize, invertColors, key);
+ break;
+ case 8:
+ FATAL_ERROR("8Bpp not supported yet.\n");
+ break;
+ }
+ }
+ else
+ {
+ switch (bitDepth)
+ {
+ case 4:
+ ConvertToTiles4Bpp(image->pixels, pixelBuffer, numTiles, metatilesWide, metatileWidth, metatileHeight,
+ invertColors);
+ break;
+ case 8:
+ ConvertToTiles8Bpp(image->pixels, pixelBuffer, numTiles, metatilesWide, metatileWidth, metatileHeight,
+ invertColors);
+ break;
+ }
}
WriteGenericNtrHeader(fp, "RGCN", bufferSize + (sopc ? 0x30 : 0x20), byteOrder, version101, sopc ? 2 : 1);
@@ -437,6 +541,11 @@ void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, in
charHeader[12] = bitDepth == 4 ? 3 : 4;
+ if (scanned)
+ {
+ charHeader[20] = 1;
+ }
+
charHeader[24] = bufferSize & 0xFF;
charHeader[25] = (bufferSize >> 8) & 0xFF;
charHeader[26] = (bufferSize >> 16) & 0xFF;
diff --git a/tools/nitrogfx/gfx.h b/tools/nitrogfx/gfx.h
index f833ac2e..6e5ebe9a 100644
--- a/tools/nitrogfx/gfx.h
+++ b/tools/nitrogfx/gfx.h
@@ -31,7 +31,7 @@ struct Image {
void ReadImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors);
void ReadNtrImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors);
void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors);
-void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc);
+void WriteNtrImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool scanned);
void FreeImage(struct Image *image);
void ReadGbaPalette(char *path, struct Palette *palette);
void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth);
diff --git a/tools/nitrogfx/main.c b/tools/nitrogfx/main.c
index b7136b03..265c2df9 100644
--- a/tools/nitrogfx/main.c
+++ b/tools/nitrogfx/main.c
@@ -88,7 +88,7 @@ void ConvertPngToNtr(char *inputPath, char *outputPath, struct PngToNtrOptions *
ReadPng(inputPath, &image);
- WriteNtrImage(outputPath, options->numTiles, image.bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette, options->clobberSize, options->byteOrder, options->version101, options->sopc);
+ WriteNtrImage(outputPath, options->numTiles, image.bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette, options->clobberSize, options->byteOrder, options->version101, options->sopc, options->scanned);
FreeImage(&image);
}
@@ -322,6 +322,7 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a
options.byteOrder = true;
options.version101 = false;
options.sopc = false;
+ options.scanned = false;
for (int i = 3; i < argc; i++)
{
@@ -395,6 +396,10 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a
{
options.sopc = true;
}
+ else if (strcmp(option, "-scanned") == 0)
+ {
+ options.scanned = true;
+ }
else
{
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
diff --git a/tools/nitrogfx/options.h b/tools/nitrogfx/options.h
index dc90a2a2..b03bd561 100644
--- a/tools/nitrogfx/options.h
+++ b/tools/nitrogfx/options.h
@@ -30,6 +30,7 @@ struct PngToNtrOptions {
bool byteOrder;
bool version101;
bool sopc;
+ bool scanned;
};