mirror of
https://github.com/red031000/nitrogfx.git
synced 2025-06-18 13:15:35 -04:00
add PMCP support and fix a few bugs
This commit is contained in:
parent
492688b25c
commit
3284d0d547
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
Copyright (c) 2015 YamaArashi, 2021-2024 red031000
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
56
gfx.c
56
gfx.c
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
// Copyright (c) 2015 YamaArashi, 2021-2024 red031000
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -718,10 +718,17 @@ void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth, int palIn
|
|||||||
|
|
||||||
bitdepth = bitdepth ? bitdepth : palette->bitDepth;
|
bitdepth = bitdepth ? bitdepth : palette->bitDepth;
|
||||||
|
|
||||||
palette->numColors = bitdepth == 4 ? 16 : 256; //remove header and divide by 2
|
size_t paletteSize = (paletteHeader[0x10]) | (paletteHeader[0x11] << 8) | (paletteHeader[0x12] << 16) | (paletteHeader[0x13] << 24);
|
||||||
|
if (palIndex == 0)
|
||||||
|
{
|
||||||
|
palette->numColors = paletteSize / 2;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
palette->numColors = bitdepth == 4 ? 16 : 256; //remove header and divide by 2
|
||||||
|
--palIndex;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char *paletteData = paletteHeader + 0x18;
|
unsigned char *paletteData = paletteHeader + 0x18;
|
||||||
palIndex = palIndex - 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
@ -764,20 +771,33 @@ void WriteGbaPalette(char *path, struct Palette *palette)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteNtrPalette(char *path, struct Palette *palette, bool ncpr, bool ir, int bitdepth, bool pad, int compNum)
|
void WriteNtrPalette(char *path, struct Palette *palette, bool ncpr, bool ir, int bitdepth, bool pad, int compNum, bool pcmp)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(path, "wb");
|
FILE *fp = fopen(path, "wb");
|
||||||
|
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
FATAL_ERROR("Failed to open \"%s\" for writing.\n", path);
|
FATAL_ERROR("Failed to open \"%s\" for writing.\n", path);
|
||||||
|
|
||||||
int colourNum = pad ? 256 : 16;
|
int colourNum = pad ? 256 : palette->numColors;
|
||||||
|
|
||||||
uint32_t size = colourNum * 2; //todo check if there's a better way to detect :/
|
uint32_t size = colourNum * 2; //todo check if there's a better way to detect :/
|
||||||
uint32_t extSize = size + (ncpr ? 0x10 : 0x18);
|
uint32_t extSize = size + (ncpr ? 0x10 : 0x18);
|
||||||
|
|
||||||
|
int numSections = 1;
|
||||||
|
int pcmpColorNum = 0;
|
||||||
|
uint32_t pcmpSize = 0;
|
||||||
|
if (pcmp)
|
||||||
|
{
|
||||||
|
pcmpColorNum = colourNum / (bitdepth == 4 ? 16 : 256);
|
||||||
|
if (pcmpColorNum == 0) {
|
||||||
|
FATAL_ERROR("colourNum=%d palette->bitDepth=%d\n", colourNum, bitdepth);
|
||||||
|
}
|
||||||
|
pcmpSize = 16 + pcmpColorNum * 2;
|
||||||
|
++numSections;
|
||||||
|
}
|
||||||
|
|
||||||
//NCLR header
|
//NCLR header
|
||||||
WriteGenericNtrHeader(fp, (ncpr ? "RPCN" : "RLCN"), extSize, !ncpr, false, 1);
|
WriteGenericNtrHeader(fp, (ncpr ? "RPCN" : "RLCN"), extSize + pcmpSize, !ncpr, false, numSections);
|
||||||
|
|
||||||
unsigned char palHeader[0x18] =
|
unsigned char palHeader[0x18] =
|
||||||
{
|
{
|
||||||
@ -843,6 +863,30 @@ void WriteNtrPalette(char *path, struct Palette *palette, bool ncpr, bool ir, in
|
|||||||
fwrite(colours, 1, colourNum * 2, fp);
|
fwrite(colours, 1, colourNum * 2, fp);
|
||||||
free(colours);
|
free(colours);
|
||||||
|
|
||||||
|
if (pcmp)
|
||||||
|
{
|
||||||
|
uint8_t pcmp_header[16] = {0x50, 0x4D, 0x43, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xBE, 0x08, 0x00, 0x00, 0x00};
|
||||||
|
pcmp_header[4] = pcmpSize & 0xFF;
|
||||||
|
pcmp_header[5] = (pcmpSize >> 8) & 0xFF;
|
||||||
|
pcmp_header[6] = (pcmpSize >> 16) & 0xFF;
|
||||||
|
pcmp_header[7] = (pcmpSize >> 24) & 0xFF;
|
||||||
|
pcmp_header[8] = pcmpColorNum & 0xFF;
|
||||||
|
pcmp_header[9] = (pcmpColorNum >> 8) & 0xFF;
|
||||||
|
fwrite(pcmp_header, 1, 16, fp);
|
||||||
|
|
||||||
|
uint8_t *pcmp_data = malloc(2 * pcmpColorNum);
|
||||||
|
if (pcmp_data == NULL)
|
||||||
|
{
|
||||||
|
FATAL_ERROR("failed to alloc pcmp_data\n");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < pcmpColorNum; ++i) {
|
||||||
|
pcmp_data[i * 2] = i & 0xFF;
|
||||||
|
pcmp_data[i * 2 + 1] = (i >> 8) & 0xFF;
|
||||||
|
}
|
||||||
|
fwrite(pcmp_data, 1, pcmpColorNum * 2, fp);
|
||||||
|
free(pcmp_data);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
gfx.h
4
gfx.h
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
// Copyright (c) 2015 YamaArashi, 2021-2024 red031000
|
||||||
|
|
||||||
#ifndef GFX_H
|
#ifndef GFX_H
|
||||||
#define GFX_H
|
#define GFX_H
|
||||||
@ -60,7 +60,7 @@ void FreeImage(struct Image *image);
|
|||||||
void ReadGbaPalette(char *path, struct Palette *palette);
|
void ReadGbaPalette(char *path, struct Palette *palette);
|
||||||
void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth, int palIndex);
|
void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth, int palIndex);
|
||||||
void WriteGbaPalette(char *path, struct Palette *palette);
|
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 WriteNtrPalette(char *path, struct Palette *palette, bool ncpr, bool ir, int bitdepth, bool pad, int compNum, bool pcmp);
|
||||||
void ReadNtrCell(char *path, struct JsonToCellOptions *options);
|
void ReadNtrCell(char *path, struct JsonToCellOptions *options);
|
||||||
void WriteNtrCell(char *path, struct JsonToCellOptions *options);
|
void WriteNtrCell(char *path, struct JsonToCellOptions *options);
|
||||||
void WriteNtrScreen(char *path, struct JsonToScreenOptions *options);
|
void WriteNtrScreen(char *path, struct JsonToScreenOptions *options);
|
||||||
|
2
json.c
2
json.c
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2021-2023 red031000
|
// Copyright (c) 2021-2024 red031000
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
|
2
json.h
2
json.h
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2021-2023 red031000
|
// Copyright (c) 2021-2024 red031000
|
||||||
|
|
||||||
#ifndef JSON_H
|
#ifndef JSON_H
|
||||||
#define JSON_H
|
#define JSON_H
|
||||||
|
20
main.c
20
main.c
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
// Copyright (c) 2015 YamaArashi, 2021-2024 red031000
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -172,7 +172,7 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
|||||||
char *inputFileExtension = GetFileExtension(inputPath);
|
char *inputFileExtension = GetFileExtension(inputPath);
|
||||||
struct GbaToPngOptions options;
|
struct GbaToPngOptions options;
|
||||||
options.paletteFilePath = NULL;
|
options.paletteFilePath = NULL;
|
||||||
if (isdigit(inputFileExtension[0]))
|
if (isdigit((unsigned char)inputFileExtension[0]))
|
||||||
options.bitDepth = inputFileExtension[0] - '0';
|
options.bitDepth = inputFileExtension[0] - '0';
|
||||||
else
|
else
|
||||||
options.bitDepth = 4;
|
options.bitDepth = 4;
|
||||||
@ -565,6 +565,7 @@ void HandlePngToNtrPaletteCommand(char *inputPath, char *outputPath, int argc, c
|
|||||||
bool nopad = false;
|
bool nopad = false;
|
||||||
int bitdepth = 0;
|
int bitdepth = 0;
|
||||||
int compNum = 0;
|
int compNum = 0;
|
||||||
|
bool pcmp = false;
|
||||||
|
|
||||||
for (int i = 3; i < argc; i++)
|
for (int i = 3; i < argc; i++)
|
||||||
{
|
{
|
||||||
@ -608,6 +609,10 @@ void HandlePngToNtrPaletteCommand(char *inputPath, char *outputPath, int argc, c
|
|||||||
if (compNum > 255)
|
if (compNum > 255)
|
||||||
FATAL_ERROR("Compression value must be 255 or below.\n");
|
FATAL_ERROR("Compression value must be 255 or below.\n");
|
||||||
}
|
}
|
||||||
|
else if (strcmp(option, "-pcmp") == 0)
|
||||||
|
{
|
||||||
|
pcmp = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
||||||
@ -615,7 +620,7 @@ void HandlePngToNtrPaletteCommand(char *inputPath, char *outputPath, int argc, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReadPngPalette(inputPath, &palette);
|
ReadPngPalette(inputPath, &palette);
|
||||||
WriteNtrPalette(outputPath, &palette, ncpr, ir, bitdepth, !nopad, compNum);
|
WriteNtrPalette(outputPath, &palette, ncpr, ir, bitdepth, !nopad, compNum, pcmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleGbaToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
void HandleGbaToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
@ -654,7 +659,7 @@ void HandleNtrToJascPaletteCommand(char *inputPath, char *outputPath, int argc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadNtrPalette(inputPath, &palette, bitdepth, 1);
|
ReadNtrPalette(inputPath, &palette, bitdepth, 0);
|
||||||
WriteJascPalette(outputPath, &palette);
|
WriteJascPalette(outputPath, &palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,6 +708,7 @@ void HandleJascToNtrPaletteCommand(char *inputPath, char *outputPath, int argc,
|
|||||||
bool nopad = false;
|
bool nopad = false;
|
||||||
int bitdepth = 0;
|
int bitdepth = 0;
|
||||||
int compNum = 0;
|
int compNum = 0;
|
||||||
|
bool pcmp = false;
|
||||||
|
|
||||||
for (int i = 3; i < argc; i++)
|
for (int i = 3; i < argc; i++)
|
||||||
{
|
{
|
||||||
@ -759,6 +765,10 @@ void HandleJascToNtrPaletteCommand(char *inputPath, char *outputPath, int argc,
|
|||||||
{
|
{
|
||||||
nopad = true;
|
nopad = true;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(option, "-pcmp") == 0)
|
||||||
|
{
|
||||||
|
pcmp = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
||||||
@ -772,7 +782,7 @@ void HandleJascToNtrPaletteCommand(char *inputPath, char *outputPath, int argc,
|
|||||||
if (numColors != 0)
|
if (numColors != 0)
|
||||||
palette.numColors = numColors;
|
palette.numColors = numColors;
|
||||||
|
|
||||||
WriteNtrPalette(outputPath, &palette, ncpr, ir, bitdepth, !nopad, compNum);
|
WriteNtrPalette(outputPath, &palette, ncpr, ir, bitdepth, !nopad, compNum, pcmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleJsonToNtrCellCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
void HandleJsonToNtrCellCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
|
Loading…
Reference in New Issue
Block a user