mirror of
https://github.com/pret/pokeheartgold.git
synced 2026-03-21 17:25:33 -05:00
Nuke changes to nitrogfx
The merge is just too complicated
This commit is contained in:
parent
bf2e15d44f
commit
c2fba5a463
|
|
@ -2,4 +2,5 @@
|
|||
**/*.inc
|
||||
**/*.json
|
||||
lib/
|
||||
tools/nitrogfx/
|
||||
tools/nitrogfx/*.c
|
||||
tools/nitrogfx/*.h
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2015 YamaArashi, 2021-2024 red031000
|
||||
Copyright (c) 2015 YamaArashi, 2021-2025 red031000
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -81,7 +81,7 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
|
|||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 18
|
||||
#define CJSON_VERSION_PATCH 19
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
|
@ -287,7 +287,10 @@ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
|||
|
||||
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
|
||||
#define cJSON_SetBoolValue(object, boolValue) ( \
|
||||
(object != NULL && ((object)->type & (cJSON_False | cJSON_True))) ? (object)->type = ((object)->type & (~(cJSON_False | cJSON_True))) | ((boolValue) ? cJSON_True : cJSON_False) : cJSON_Invalid)
|
||||
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
|
||||
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
|
||||
cJSON_Invalid\
|
||||
)
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
|
|
|||
|
|
@ -1,47 +1,39 @@
|
|||
// Copyright (c) 2015 YamaArashi
|
||||
|
||||
#include "convert_png.h"
|
||||
|
||||
#include <png.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <png.h>
|
||||
#include "global.h"
|
||||
|
||||
#include "convert_png.h"
|
||||
#include "gfx.h"
|
||||
|
||||
static FILE *PngReadOpen(char *path, png_structp *pngStruct, png_infop *pngInfo) {
|
||||
static FILE *PngReadOpen(char *path, png_structp *pngStruct, png_infop *pngInfo)
|
||||
{
|
||||
FILE *fp = fopen(path, "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
if (fp == NULL)
|
||||
FATAL_ERROR("Failed to open \"%s\" for reading.\n", path);
|
||||
}
|
||||
|
||||
unsigned char sig[8];
|
||||
|
||||
if (fread(sig, 8, 1, fp) != 1) {
|
||||
if (fread(sig, 8, 1, fp) != 1)
|
||||
FATAL_ERROR("Failed to read PNG signature from \"%s\".\n", path);
|
||||
}
|
||||
|
||||
if (png_sig_cmp(sig, 0, 8)) {
|
||||
if (png_sig_cmp(sig, 0, 8))
|
||||
FATAL_ERROR("\"%s\" does not have a valid PNG signature.\n", path);
|
||||
}
|
||||
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
if (!png_ptr) {
|
||||
if (!png_ptr)
|
||||
FATAL_ERROR("Failed to create PNG read struct.\n");
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
|
||||
if (!info_ptr) {
|
||||
if (!info_ptr)
|
||||
FATAL_ERROR("Failed to create PNG info struct.\n");
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
FATAL_ERROR("Failed to init I/O for reading \"%s\".\n", path);
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
|
@ -53,7 +45,8 @@ static FILE *PngReadOpen(char *path, png_structp *pngStruct, png_infop *pngInfo)
|
|||
return fp;
|
||||
}
|
||||
|
||||
static unsigned char *ConvertBitDepth(unsigned char *src, int srcBitDepth, int destBitDepth, int numPixels) {
|
||||
static unsigned char *ConvertBitDepth(unsigned char *src, int srcBitDepth, int destBitDepth, int numPixels)
|
||||
{
|
||||
// Round the number of bits up to the next 8 and divide by 8 to get the number of bytes.
|
||||
int srcSize = ((numPixels * srcBitDepth + 7) & ~7) / 8;
|
||||
int destSize = ((numPixels * destBitDepth + 7) & ~7) / 8;
|
||||
|
|
@ -63,18 +56,20 @@ static unsigned char *ConvertBitDepth(unsigned char *src, int srcBitDepth, int d
|
|||
int j;
|
||||
int destBit = 8 - destBitDepth;
|
||||
|
||||
for (i = 0; i < srcSize; i++) {
|
||||
for (i = 0; i < srcSize; i++)
|
||||
{
|
||||
unsigned char srcByte = src[i];
|
||||
|
||||
for (j = 8 - srcBitDepth; j >= 0; j -= srcBitDepth) {
|
||||
for (j = 8 - srcBitDepth; j >= 0; j -= srcBitDepth)
|
||||
{
|
||||
unsigned char pixel = (srcByte >> j) % (1 << srcBitDepth);
|
||||
|
||||
if (pixel >= (1 << destBitDepth)) {
|
||||
if (pixel >= (1 << destBitDepth))
|
||||
FATAL_ERROR("Image exceeds the maximum color value for a %ibpp image.\n", destBitDepth);
|
||||
}
|
||||
*dest |= pixel << destBit;
|
||||
destBit -= destBitDepth;
|
||||
if (destBit < 0) {
|
||||
if (destBit < 0)
|
||||
{
|
||||
dest++;
|
||||
destBit = 8 - destBitDepth;
|
||||
}
|
||||
|
|
@ -84,7 +79,8 @@ static unsigned char *ConvertBitDepth(unsigned char *src, int srcBitDepth, int d
|
|||
return output;
|
||||
}
|
||||
|
||||
void ReadPng(char *path, struct Image *image) {
|
||||
void ReadPng(char *path, struct Image *image)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
||||
|
|
@ -94,22 +90,12 @@ void ReadPng(char *path, struct Image *image) {
|
|||
|
||||
int color_type = png_get_color_type(png_ptr, info_ptr);
|
||||
|
||||
switch (color_type) {
|
||||
case PNG_COLOR_TYPE_GRAY:
|
||||
case PNG_COLOR_TYPE_GA:
|
||||
case PNG_COLOR_TYPE_PALETTE:
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
case PNG_COLOR_TYPE_RGBA:
|
||||
break;
|
||||
default:
|
||||
if (color_type != PNG_COLOR_TYPE_GRAY && color_type != PNG_COLOR_TYPE_PALETTE)
|
||||
FATAL_ERROR("\"%s\" has an unsupported color type.\n", path);
|
||||
}
|
||||
|
||||
// Check if the image has a palette so that we can tell if the colors need to be inverted later.
|
||||
// Don't read the palette because it's not needed for now.
|
||||
image->hasPalette = (color_type & PNG_COLOR_MASK_COLOR) != 0;
|
||||
image->hasTransparency = color_type == PNG_COLOR_TYPE_PALETTE || ((color_type & PNG_COLOR_MASK_ALPHA) != 0);
|
||||
image->pixelsAreRGB = (color_type & PNG_COLOR_MASK_COLOR) != 0 && (color_type & PNG_COLOR_MASK_PALETTE) == 0;
|
||||
image->hasPalette = (color_type == PNG_COLOR_TYPE_PALETTE);
|
||||
|
||||
image->width = png_get_image_width(png_ptr, info_ptr);
|
||||
image->height = png_get_image_height(png_ptr, info_ptr);
|
||||
|
|
@ -118,23 +104,19 @@ void ReadPng(char *path, struct Image *image) {
|
|||
|
||||
image->pixels = malloc(image->height * rowbytes);
|
||||
|
||||
if (image->pixels == NULL) {
|
||||
if (image->pixels == NULL)
|
||||
FATAL_ERROR("Failed to allocate pixel buffer.\n");
|
||||
}
|
||||
|
||||
png_bytepp row_pointers = malloc(image->height * sizeof(png_bytep));
|
||||
|
||||
if (row_pointers == NULL) {
|
||||
if (row_pointers == NULL)
|
||||
FATAL_ERROR("Failed to allocate row pointers.\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < image->height; i++) {
|
||||
for (int i = 0; i < image->height; i++)
|
||||
row_pointers[i] = (png_bytep)(image->pixels + (i * rowbytes));
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
FATAL_ERROR("Error reading from \"%s\".\n", path);
|
||||
}
|
||||
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
|
|
@ -143,19 +125,20 @@ void ReadPng(char *path, struct Image *image) {
|
|||
free(row_pointers);
|
||||
fclose(fp);
|
||||
|
||||
if ((color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth != image->bitDepth) {
|
||||
if (bit_depth != image->bitDepth)
|
||||
{
|
||||
unsigned char *src = image->pixels;
|
||||
|
||||
if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8) {
|
||||
if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8)
|
||||
FATAL_ERROR("Bit depth of image must be 1, 2, 4, or 8.\n");
|
||||
}
|
||||
image->pixels = ConvertBitDepth(image->pixels, bit_depth, image->bitDepth, image->width * image->height);
|
||||
free(src);
|
||||
image->bitDepth = bit_depth;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadPngPalette(char *path, struct Palette *palette) {
|
||||
void ReadPngPalette(char *path, struct Palette *palette)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_colorp colors;
|
||||
|
|
@ -163,17 +146,14 @@ void ReadPngPalette(char *path, struct Palette *palette) {
|
|||
|
||||
FILE *fp = PngReadOpen(path, &png_ptr, &info_ptr);
|
||||
|
||||
if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_PALETTE) {
|
||||
if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_PALETTE)
|
||||
FATAL_ERROR("The image \"%s\" does not contain a palette.\n", path);
|
||||
}
|
||||
|
||||
if (png_get_PLTE(png_ptr, info_ptr, &colors, &numColors) != PNG_INFO_PLTE) {
|
||||
if (png_get_PLTE(png_ptr, info_ptr, &colors, &numColors) != PNG_INFO_PLTE)
|
||||
FATAL_ERROR("Failed to retrieve palette from \"%s\".\n", path);
|
||||
}
|
||||
|
||||
if (numColors > 256) {
|
||||
if (numColors > 256)
|
||||
FATAL_ERROR("Images with more than 256 colors are not supported.\n");
|
||||
}
|
||||
|
||||
palette->numColors = numColors;
|
||||
for (int i = 0; i < numColors; i++) {
|
||||
|
|
@ -189,12 +169,12 @@ void ReadPngPalette(char *path, struct Palette *palette) {
|
|||
fclose(fp);
|
||||
}
|
||||
|
||||
void SetPngPalette(png_structp png_ptr, png_infop info_ptr, struct Palette *palette) {
|
||||
void SetPngPalette(png_structp png_ptr, png_infop info_ptr, struct Palette *palette)
|
||||
{
|
||||
png_colorp colors = malloc(palette->numColors * sizeof(png_color));
|
||||
|
||||
if (colors == NULL) {
|
||||
if (colors == NULL)
|
||||
FATAL_ERROR("Failed to allocate PNG palette.\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < palette->numColors; i++) {
|
||||
colors[i].red = palette->colors[i].red;
|
||||
|
|
@ -207,50 +187,40 @@ void SetPngPalette(png_structp png_ptr, png_infop info_ptr, struct Palette *pale
|
|||
free(colors);
|
||||
}
|
||||
|
||||
void WritePng(char *path, struct Image *image) {
|
||||
void WritePng(char *path, struct Image *image)
|
||||
{
|
||||
FILE *fp = fopen(path, "wb");
|
||||
|
||||
if (fp == NULL) {
|
||||
if (fp == NULL)
|
||||
FATAL_ERROR("Failed to open \"%s\" for writing.\n", path);
|
||||
}
|
||||
|
||||
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
if (!png_ptr) {
|
||||
if (!png_ptr)
|
||||
FATAL_ERROR("Failed to create PNG write struct.\n");
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
|
||||
if (!info_ptr) {
|
||||
if (!info_ptr)
|
||||
FATAL_ERROR("Failed to create PNG info struct.\n");
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
FATAL_ERROR("Failed to init I/O for writing \"%s\".\n", path);
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
FATAL_ERROR("Error writing header for \"%s\".\n", path);
|
||||
}
|
||||
|
||||
int color_type = PNG_COLOR_TYPE_GRAY;
|
||||
int color_type = image->hasPalette ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY;
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
|
||||
image->bitDepth, color_type, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
if (image->hasPalette) {
|
||||
color_type |= PNG_COLOR_MASK_COLOR;
|
||||
if (!image->pixelsAreRGB) {
|
||||
color_type |= PNG_COLOR_MASK_PALETTE;
|
||||
}
|
||||
}
|
||||
if (image->hasTransparency && !(color_type & PNG_COLOR_MASK_PALETTE)) {
|
||||
color_type |= PNG_COLOR_MASK_ALPHA;
|
||||
}
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, image->width, image->height, image->bitDepth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
SetPngPalette(png_ptr, info_ptr, &image->palette);
|
||||
|
||||
if (image->hasTransparency) {
|
||||
png_byte trans = 0;
|
||||
png_set_tRNS(png_ptr, info_ptr, &trans, 1, 0);
|
||||
|
|
@ -261,25 +231,21 @@ void WritePng(char *path, struct Image *image) {
|
|||
|
||||
png_bytepp row_pointers = malloc(image->height * sizeof(png_bytep));
|
||||
|
||||
if (row_pointers == NULL) {
|
||||
if (row_pointers == NULL)
|
||||
FATAL_ERROR("Failed to allocate row pointers.\n");
|
||||
}
|
||||
|
||||
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
|
||||
for (int i = 0; i < image->height; i++) {
|
||||
for (int i = 0; i < image->height; i++)
|
||||
row_pointers[i] = (png_bytep)(image->pixels + (i * rowbytes));
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
FATAL_ERROR("Error writing \"%s\".\n", path);
|
||||
}
|
||||
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
FATAL_ERROR("Error ending write of \"%s\".\n", path);
|
||||
}
|
||||
|
||||
png_write_end(png_ptr, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +1,29 @@
|
|||
// Copyright (c) 2015 YamaArashi
|
||||
|
||||
#include "font.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#include "font.h"
|
||||
#include "gfx.h"
|
||||
#include "options.h"
|
||||
#include "util.h"
|
||||
|
||||
unsigned char gFontPalette[][3] = {
|
||||
{ 0x90, 0xC8, 0xFF }, // bg (saturated blue that contrasts well with the shadow color)
|
||||
{ 0x38, 0x38, 0x38 }, // fg (dark grey)
|
||||
{ 0xD8, 0xD8, 0xD8 }, // shadow (light grey)
|
||||
{ 0xFF, 0xFF, 0xFF } // box (white)
|
||||
{0x90, 0xC8, 0xFF}, // bg (saturated blue that contrasts well with the shadow color)
|
||||
{0x38, 0x38, 0x38}, // fg (dark grey)
|
||||
{0xD8, 0xD8, 0xD8}, // shadow (light grey)
|
||||
{0xFF, 0xFF, 0xFF} // box (white)
|
||||
};
|
||||
|
||||
// special palette for DS subscreen font
|
||||
unsigned char gFontPalette_Subscreen[][3] = {
|
||||
{ 0x90, 0xC8, 0xFF }, // bg (saturated blue that contrasts well with the shadow color)
|
||||
{ 0xFF, 0xFF, 0xFF }, // fg (white)
|
||||
{ 0xD8, 0xD8, 0xD8 }, // shadow (light grey)
|
||||
{ 0x38, 0x38, 0x38 }, // outline (dark grey)
|
||||
{0x90, 0xC8, 0xFF}, // bg (saturated blue that contrasts well with the shadow color)
|
||||
{0xFF, 0xFF, 0xFF}, // fg (white)
|
||||
{0xD8, 0xD8, 0xD8}, // shadow (light grey)
|
||||
{0x38, 0x38, 0x38}, // outline (dark grey)
|
||||
};
|
||||
|
||||
static void ConvertFromLatinFont(unsigned char *src, unsigned char *dest, unsigned int numRows)
|
||||
|
|
@ -39,7 +36,7 @@ static void ConvertFromLatinFont(unsigned char *src, unsigned char *dest, unsign
|
|||
unsigned int pixelsX = (column * 16) + ((glyphTile & 1) * 8);
|
||||
|
||||
for (unsigned int i = 0; i < 8; i++) {
|
||||
unsigned int pixelsY = (row * 16) + ((glyphTile >> 1) * 8) + i;
|
||||
unsigned int pixelsY = (row * 16) + ((glyphTile >> 1) * 8) + i;
|
||||
unsigned int destPixelsOffset = (pixelsY * 64) + (pixelsX / 4);
|
||||
|
||||
dest[destPixelsOffset] = src[srcPixelsOffset + 1];
|
||||
|
|
@ -88,7 +85,7 @@ static void ConvertFromHalfwidthJapaneseFont(unsigned char *src, unsigned char *
|
|||
for (unsigned int i = 0; i < 8; i++) {
|
||||
unsigned int pixelsY = (row * 16) + (glyphTile * 8) + i;
|
||||
unsigned int destPixelsOffset = (pixelsY * 32) + (pixelsX / 4);
|
||||
|
||||
|
||||
dest[destPixelsOffset] = src[srcPixelsOffset + 1];
|
||||
dest[destPixelsOffset + 1] = src[srcPixelsOffset];
|
||||
|
||||
|
|
@ -171,7 +168,8 @@ static void ConvertToFullwidthJapaneseFont(unsigned char *src, unsigned char *de
|
|||
}
|
||||
}
|
||||
|
||||
static void ConvertFromNitroFont(unsigned char *src, unsigned char *dest, unsigned int numRows, struct NtrFontMetadata *metadata) {
|
||||
static void ConvertFromNitroFont(unsigned char *src, unsigned char *dest, unsigned int numRows, struct NtrFontMetadata *metadata)
|
||||
{
|
||||
unsigned int srcPixelsOffset = 0;
|
||||
unsigned int curGlyph = 0;
|
||||
|
||||
|
|
@ -194,7 +192,8 @@ static void ConvertFromNitroFont(unsigned char *src, unsigned char *dest, unsign
|
|||
}
|
||||
}
|
||||
|
||||
static void ConvertToNitroFont(unsigned char *src, unsigned char *dest, unsigned int numRows, struct NtrFontMetadata *metadata) {
|
||||
static void ConvertToNitroFont(unsigned char *src, unsigned char *dest, unsigned int numRows, struct NtrFontMetadata *metadata)
|
||||
{
|
||||
unsigned int destPixelsOffset = 0;
|
||||
unsigned int curGlyph = 0;
|
||||
|
||||
|
|
@ -232,7 +231,8 @@ static void SetFontPalette(struct Image *image)
|
|||
image->hasTransparency = false;
|
||||
}
|
||||
|
||||
static void SetSubscreenFontPalette(struct Image *image) {
|
||||
static void SetSubscreenFontPalette(struct Image *image)
|
||||
{
|
||||
image->hasPalette = true;
|
||||
|
||||
image->palette.numColors = 4;
|
||||
|
|
@ -253,9 +253,8 @@ void ReadLatinFont(char *path, struct Image *image)
|
|||
|
||||
int numGlyphs = fileSize / 64;
|
||||
|
||||
if (numGlyphs % 16 != 0) {
|
||||
if (numGlyphs % 16 != 0)
|
||||
FATAL_ERROR("The number of glyphs (%d) is not a multiple of 16.\n", numGlyphs);
|
||||
}
|
||||
|
||||
int numRows = numGlyphs / 16;
|
||||
|
||||
|
|
@ -264,9 +263,8 @@ void ReadLatinFont(char *path, struct Image *image)
|
|||
image->bitDepth = 2;
|
||||
image->pixels = malloc(fileSize);
|
||||
|
||||
if (image->pixels == NULL) {
|
||||
if (image->pixels == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for font.\n");
|
||||
}
|
||||
|
||||
ConvertFromLatinFont(buffer, image->pixels, numRows);
|
||||
|
||||
|
|
@ -277,21 +275,18 @@ void ReadLatinFont(char *path, struct Image *image)
|
|||
|
||||
void WriteLatinFont(char *path, struct Image *image)
|
||||
{
|
||||
if (image->width != 256) {
|
||||
if (image->width != 256)
|
||||
FATAL_ERROR("The width of the font image (%d) is not 256.\n", image->width);
|
||||
}
|
||||
|
||||
if (image->height % 16 != 0) {
|
||||
if (image->height % 16 != 0)
|
||||
FATAL_ERROR("The height of the font image (%d) is not a multiple of 16.\n", image->height);
|
||||
}
|
||||
|
||||
int numRows = image->height / 16;
|
||||
int bufferSize = numRows * 16 * 64;
|
||||
unsigned char *buffer = malloc(bufferSize);
|
||||
|
||||
if (buffer == NULL) {
|
||||
if (buffer == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for font.\n");
|
||||
}
|
||||
|
||||
ConvertToLatinFont(image->pixels, buffer, numRows);
|
||||
|
||||
|
|
@ -307,15 +302,13 @@ void ReadHalfwidthJapaneseFont(char *path, struct Image *image)
|
|||
|
||||
int glyphSize = 32;
|
||||
|
||||
if (fileSize % glyphSize != 0) {
|
||||
if (fileSize % glyphSize != 0)
|
||||
FATAL_ERROR("The file size (%d) is not a multiple of %d.\n", fileSize, glyphSize);
|
||||
}
|
||||
|
||||
int numGlyphs = fileSize / glyphSize;
|
||||
|
||||
if (numGlyphs % 16 != 0) {
|
||||
|
||||
if (numGlyphs % 16 != 0)
|
||||
FATAL_ERROR("The number of glyphs (%d) is not a multiple of 16.\n", numGlyphs);
|
||||
}
|
||||
|
||||
int numRows = numGlyphs / 16;
|
||||
|
||||
|
|
@ -324,9 +317,8 @@ void ReadHalfwidthJapaneseFont(char *path, struct Image *image)
|
|||
image->bitDepth = 2;
|
||||
image->pixels = malloc(fileSize);
|
||||
|
||||
if (image->pixels == NULL) {
|
||||
if (image->pixels == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for font.\n");
|
||||
}
|
||||
|
||||
ConvertFromHalfwidthJapaneseFont(buffer, image->pixels, numRows);
|
||||
|
||||
|
|
@ -337,21 +329,18 @@ void ReadHalfwidthJapaneseFont(char *path, struct Image *image)
|
|||
|
||||
void WriteHalfwidthJapaneseFont(char *path, struct Image *image)
|
||||
{
|
||||
if (image->width != 128) {
|
||||
if (image->width != 128)
|
||||
FATAL_ERROR("The width of the font image (%d) is not 128.\n", image->width);
|
||||
}
|
||||
|
||||
if (image->height % 16 != 0) {
|
||||
if (image->height % 16 != 0)
|
||||
FATAL_ERROR("The height of the font image (%d) is not a multiple of 16.\n", image->height);
|
||||
}
|
||||
|
||||
int numRows = image->height / 16;
|
||||
int bufferSize = numRows * 16 * 32;
|
||||
unsigned char *buffer = malloc(bufferSize);
|
||||
|
||||
if (buffer == NULL) {
|
||||
if (buffer == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for font.\n");
|
||||
}
|
||||
|
||||
ConvertToHalfwidthJapaneseFont(image->pixels, buffer, numRows);
|
||||
|
||||
|
|
@ -367,9 +356,8 @@ void ReadFullwidthJapaneseFont(char *path, struct Image *image)
|
|||
|
||||
int numGlyphs = fileSize / 64;
|
||||
|
||||
if (numGlyphs % 16 != 0) {
|
||||
if (numGlyphs % 16 != 0)
|
||||
FATAL_ERROR("The number of glyphs (%d) is not a multiple of 16.\n", numGlyphs);
|
||||
}
|
||||
|
||||
int numRows = numGlyphs / 16;
|
||||
|
||||
|
|
@ -378,9 +366,8 @@ void ReadFullwidthJapaneseFont(char *path, struct Image *image)
|
|||
image->bitDepth = 2;
|
||||
image->pixels = malloc(fileSize);
|
||||
|
||||
if (image->pixels == NULL) {
|
||||
if (image->pixels == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for font.\n");
|
||||
}
|
||||
|
||||
ConvertFromFullwidthJapaneseFont(buffer, image->pixels, numRows);
|
||||
|
||||
|
|
@ -391,21 +378,18 @@ void ReadFullwidthJapaneseFont(char *path, struct Image *image)
|
|||
|
||||
void WriteFullwidthJapaneseFont(char *path, struct Image *image)
|
||||
{
|
||||
if (image->width != 256) {
|
||||
if (image->width != 256)
|
||||
FATAL_ERROR("The width of the font image (%d) is not 256.\n", image->width);
|
||||
}
|
||||
|
||||
if (image->height % 16 != 0) {
|
||||
if (image->height % 16 != 0)
|
||||
FATAL_ERROR("The height of the font image (%d) is not a multiple of 16.\n", image->height);
|
||||
}
|
||||
|
||||
int numRows = image->height / 16;
|
||||
int bufferSize = numRows * 16 * 64;
|
||||
unsigned char *buffer = malloc(bufferSize);
|
||||
|
||||
if (buffer == NULL) {
|
||||
if (buffer == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for font.\n");
|
||||
}
|
||||
|
||||
ConvertToFullwidthJapaneseFont(image->pixels, buffer, numRows);
|
||||
|
||||
|
|
@ -414,14 +398,16 @@ void WriteFullwidthJapaneseFont(char *path, struct Image *image)
|
|||
free(buffer);
|
||||
}
|
||||
|
||||
static inline uint32_t ReadLittleEndianWord(unsigned char *buffer, size_t start) {
|
||||
static inline uint32_t ReadLittleEndianWord(unsigned char *buffer, size_t start)
|
||||
{
|
||||
return (buffer[start + 3] << 24)
|
||||
| (buffer[start + 2] << 16)
|
||||
| (buffer[start + 1] << 8)
|
||||
| (buffer[start]);
|
||||
}
|
||||
|
||||
void ReadNtrFont(char *path, struct Image *image, struct NtrFontMetadata *metadata, bool useSubscreenPalette) {
|
||||
void ReadNtrFont(char *path, struct Image *image, struct NtrFontMetadata *metadata, bool useSubscreenPalette)
|
||||
{
|
||||
int filesize;
|
||||
unsigned char *buffer = ReadWholeFile(path, &filesize);
|
||||
|
||||
|
|
@ -443,37 +429,33 @@ void ReadNtrFont(char *path, struct Image *image, struct NtrFontMetadata *metada
|
|||
image->bitDepth = 2;
|
||||
image->pixels = malloc(filesize);
|
||||
|
||||
if (image->pixels == NULL) {
|
||||
if (image->pixels == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for font.\n");
|
||||
}
|
||||
|
||||
ConvertFromNitroFont(buffer + metadata->size, image->pixels, numRows, metadata);
|
||||
|
||||
free(buffer);
|
||||
|
||||
if (useSubscreenPalette) {
|
||||
if (useSubscreenPalette)
|
||||
SetSubscreenFontPalette(image);
|
||||
} else {
|
||||
else
|
||||
SetFontPalette(image);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteNtrFont(char *path, struct Image *image, struct NtrFontMetadata *metadata) {
|
||||
if (image->width != 256) {
|
||||
void WriteNtrFont(char *path, struct Image *image, struct NtrFontMetadata *metadata)
|
||||
{
|
||||
if (image->width != 256)
|
||||
FATAL_ERROR("The width of the font image (%d) is not 256.\n", image->width);
|
||||
}
|
||||
|
||||
if (image->height % 16 != 0) {
|
||||
if (image->height % 16 != 0)
|
||||
FATAL_ERROR("The height of the font image (%d) is not a multiple of 16.\n", image->height);
|
||||
}
|
||||
|
||||
int numRows = image->height / 16;
|
||||
int bufferSize = metadata->widthTableOffset + metadata->numGlyphs;
|
||||
unsigned char *buffer = malloc(bufferSize);
|
||||
|
||||
if (buffer == NULL) {
|
||||
if (buffer == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for font.\n");
|
||||
}
|
||||
|
||||
buffer[0x00] = (metadata->size & 0x000000FF);
|
||||
buffer[0x01] = (metadata->size & 0x0000FF00) >> 8;
|
||||
|
|
@ -500,7 +482,8 @@ void WriteNtrFont(char *path, struct Image *image, struct NtrFontMetadata *metad
|
|||
free(buffer);
|
||||
}
|
||||
|
||||
void FreeNtrFontMetadata(struct NtrFontMetadata *metadata) {
|
||||
void FreeNtrFontMetadata(struct NtrFontMetadata *metadata)
|
||||
{
|
||||
free(metadata->glyphWidthTable);
|
||||
free(metadata);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#define FONT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "gfx.h"
|
||||
#include "options.h"
|
||||
|
||||
|
|
|
|||
2234
tools/nitrogfx/gfx.c
2234
tools/nitrogfx/gfx.c
File diff suppressed because it is too large
Load Diff
|
|
@ -1,29 +1,28 @@
|
|||
// Copyright (c) 2015 YamaArashi, 2021-2024 red031000
|
||||
// Copyright (c) 2015 YamaArashi, 2021-2025 red031000
|
||||
|
||||
#ifndef GFX_H
|
||||
#define GFX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "options.h"
|
||||
|
||||
struct Color {
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
};
|
||||
|
||||
struct Palette {
|
||||
struct Color colors[16 * 256];
|
||||
int numColors;
|
||||
int bitDepth;
|
||||
struct Color colors[256];
|
||||
int numColors;
|
||||
int bitDepth;
|
||||
};
|
||||
|
||||
struct Image {
|
||||
int width;
|
||||
int height;
|
||||
int bitDepth;
|
||||
int width;
|
||||
int height;
|
||||
int bitDepth;
|
||||
/**
|
||||
* Pseudocode for converting index in pixels to coordinates in image is as follows
|
||||
* (where (0, 0) is the top left corner with the format (x, y) ):
|
||||
|
|
@ -45,33 +44,22 @@ struct Image {
|
|||
* pixel = pixels[i]
|
||||
* pixel coordinates: (xCoord, yCoord)
|
||||
*/
|
||||
unsigned char *pixels;
|
||||
bool hasPalette;
|
||||
struct Palette palette;
|
||||
bool hasTransparency;
|
||||
bool pixelsAreRGB;
|
||||
};
|
||||
|
||||
struct NSCRFile {
|
||||
uint16_t scrnWidth; // output width in pixels
|
||||
uint16_t scrnHeight; // output height in pixels
|
||||
uint16_t colorMode; // 4bpp or 8bpp
|
||||
uint16_t scrnMode; // text, affine, or extpltt
|
||||
uint32_t scrnSize; // total data length
|
||||
uint8_t data[]; // data
|
||||
unsigned char *pixels;
|
||||
bool hasPalette;
|
||||
struct Palette palette;
|
||||
bool hasTransparency;
|
||||
};
|
||||
|
||||
void ReadImage(char *path, int tilesWide, int bitDepth, int colsPerChunk, int rowsPerChunk, struct Image *image, bool invertColors);
|
||||
uint32_t ReadNtrImage(char *path, int tilesWide, int bitDepth, int colsPerChunk, int rowsPerChunk, struct Image *image, bool invertColors, bool scanFrontToBack);
|
||||
void ApplyCellsToImage(char *cellFilePath, struct Image *image, bool toPNG);
|
||||
void ApplyScrnToImage(char *scrnFilePath, struct Image *image);
|
||||
uint32_t ReadNtrImage(char *path, int tilesWide, int bitDepth, int colsPerChunk, int rowsPerChunk, struct Image *image, bool invertColors, uint32_t encodeMode, bool convertTo8Bpp, int palIndex, bool verbose);
|
||||
void ApplyCellsToImage(char *cellFilePath, struct Image *image, bool toPNG, bool snap);
|
||||
void WriteImage(char *path, int numTiles, int bitDepth, int colsPerChunk, int rowsPerChunk, struct Image *image, bool invertColors);
|
||||
void WriteNtrImage(char *path, int numTiles, int bitDepth, int colsPerChunk, int rowsPerChunk, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool vram, uint32_t scanMode, uint32_t mappingType, uint32_t key, bool wrongSize);
|
||||
void WriteNtrImage(char *path, int numTiles, int bitDepth, int colsPerChunk, int rowsPerChunk, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, bool vram, bool scan, uint32_t encodeMode, uint32_t mappingType, uint32_t key, bool wrongSize, bool convertTo4Bpp);
|
||||
void FreeImage(struct Image *image);
|
||||
void ReadGbaPalette(char *path, struct Palette *palette);
|
||||
void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth, int palIndex, bool inverted);
|
||||
void ReadNtrPalette(char *path, struct Palette *palette, int bitdepth, int palIndex, bool inverted, bool convertTo8Bpp);
|
||||
void WriteGbaPalette(char *path, struct Palette *palette);
|
||||
void WriteNtrPalette(char *path, struct Palette *palette, bool ncpr, bool ir, int bitdepth, bool pad, int compNum, bool pcmp, bool inverted);
|
||||
void WriteNtrPalette(char *path, struct Palette *palette, bool ncpr, bool ir, int bitdepth, bool pad, int compNum, bool pcmp, int pcmpStartIndex, bool inverted, bool convertTo4Bpp);
|
||||
void ReadNtrCell(char *path, struct JsonToCellOptions *options);
|
||||
void WriteNtrCell(char *path, struct JsonToCellOptions *options);
|
||||
void WriteNtrScreen(char *path, struct JsonToScreenOptions *options);
|
||||
|
|
|
|||
|
|
@ -8,37 +8,30 @@
|
|||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define FATAL_ERROR(format, ...) \
|
||||
do { \
|
||||
fprintf(stderr, format, __VA_ARGS__); \
|
||||
exit(1); \
|
||||
} while (0)
|
||||
#define FATAL_ERROR(format, ...) \
|
||||
do { \
|
||||
fprintf(stderr, format, __VA_ARGS__); \
|
||||
exit(1); \
|
||||
} while (0)
|
||||
|
||||
#define UNUSED
|
||||
|
||||
#else
|
||||
|
||||
#define FATAL_ERROR(format, ...) \
|
||||
do { \
|
||||
fprintf(stderr, format, ##__VA_ARGS__); \
|
||||
fprintf(stderr, " -- %s:%d\n", __FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
#define FATAL_ERROR(format, ...) \
|
||||
do { \
|
||||
fprintf(stderr, format, ##__VA_ARGS__); \
|
||||
exit(1); \
|
||||
} while (0)
|
||||
|
||||
#define UNUSED __attribute__((__unused__))
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
#define PTR_ADD(ptr, value) ((void *)((uintptr_t)(ptr) + (value)))
|
||||
#define PTR_SUB(ptr, value) ((void *)((uintptr_t)(ptr) - (value)))
|
||||
#define PTR_IADD(ptr, value) \
|
||||
do { \
|
||||
(ptr) = PTR_ADD(ptr, value); \
|
||||
} while (0)
|
||||
#define PTR_ISUB(ptr, value) \
|
||||
do { \
|
||||
(ptr) = PTR_SUB(ptr, value); \
|
||||
} while (0)
|
||||
#define PTR_ADD(ptr, value) ((void*)((uintptr_t)(ptr) + (value)))
|
||||
#define PTR_SUB(ptr, value) ((void*)((uintptr_t)(ptr) - (value)))
|
||||
#define PTR_IADD(ptr, value) do { (ptr) = PTR_ADD(ptr, value); } while (0)
|
||||
#define PTR_ISUB(ptr, value) do { (ptr) = PTR_SUB(ptr, value); } while (0)
|
||||
#define PTR_DIFF(right, left) ((uintptr_t)(right) - (uintptr_t)(left))
|
||||
|
||||
#endif // GLOBAL_H
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2021-2024 red031000
|
||||
// Copyright (c) 2021-2025 red031000
|
||||
|
||||
#include "global.h"
|
||||
#include "cJSON.h"
|
||||
|
|
@ -47,13 +47,17 @@ struct JsonToCellOptions *ParseNCERJson(char *path)
|
|||
}
|
||||
|
||||
cJSON *labelBool = cJSON_GetObjectItemCaseSensitive(json, "labelEnabled");
|
||||
cJSON *dontPadKbecBool = cJSON_GetObjectItemCaseSensitive(json, "dontPadKbec");
|
||||
cJSON *vramTransferBool = cJSON_GetObjectItemCaseSensitive(json, "vramTransferEnabled");
|
||||
cJSON *ucatBool = cJSON_GetObjectItemCaseSensitive(json, "ucatEnabled");
|
||||
cJSON *extended = cJSON_GetObjectItemCaseSensitive(json, "extended");
|
||||
cJSON *cellCount = cJSON_GetObjectItemCaseSensitive(json, "cellCount");
|
||||
cJSON *mappingType = cJSON_GetObjectItemCaseSensitive(json, "mappingType");
|
||||
|
||||
options->labelEnabled = GetBool(labelBool);
|
||||
options->dontPadKbec = GetBool(dontPadKbecBool);
|
||||
options->vramTransferEnabled = GetBool(vramTransferBool);
|
||||
options->ucatEnabled = GetBool(ucatBool);
|
||||
options->extended = GetBool(extended);
|
||||
options->cellCount = GetInt(cellCount);
|
||||
options->mappingType = GetInt(mappingType);
|
||||
|
|
@ -79,17 +83,19 @@ struct JsonToCellOptions *ParseNCERJson(char *path)
|
|||
}
|
||||
}
|
||||
|
||||
if (options->vramTransferEnabled) {
|
||||
if (options->vramTransferEnabled)
|
||||
{
|
||||
cJSON *vramTransferMaxSize = cJSON_GetObjectItemCaseSensitive(json, "vramTransferMaxSize");
|
||||
options->vramTransferMaxSize = GetInt(vramTransferMaxSize);
|
||||
|
||||
|
||||
options->transferData = malloc(sizeof(struct CellVramTransferData *) * options->cellCount);
|
||||
|
||||
cJSON *transfers = cJSON_GetObjectItemCaseSensitive(json, "transferData");
|
||||
cJSON *transfer = NULL;
|
||||
|
||||
int j = 0;
|
||||
cJSON_ArrayForEach(transfer, transfers) {
|
||||
cJSON_ArrayForEach(transfer, transfers)
|
||||
{
|
||||
cJSON *vramTransferOffset = cJSON_GetObjectItemCaseSensitive(transfer, "offset");
|
||||
cJSON *vramTransferSize = cJSON_GetObjectItemCaseSensitive(transfer, "size");
|
||||
|
||||
|
|
@ -101,6 +107,16 @@ struct JsonToCellOptions *ParseNCERJson(char *path)
|
|||
}
|
||||
}
|
||||
|
||||
if (options->ucatEnabled) {
|
||||
cJSON *ucatCells = cJSON_GetObjectItemCaseSensitive(json, "cellAttributes");
|
||||
|
||||
options->ucatCellAttribtes = malloc(sizeof(uint32_t) * options->cellCount);
|
||||
|
||||
for (int i = 0; i < options->cellCount; i++) {
|
||||
options->ucatCellAttribtes[i] = GetInt(cJSON_GetArrayItem(ucatCells, i));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < options->cellCount; i++)
|
||||
{
|
||||
options->cells[i] = malloc(sizeof(struct Cell));
|
||||
|
|
@ -172,7 +188,11 @@ struct JsonToCellOptions *ParseNCERJson(char *path)
|
|||
cJSON *Colours = cJSON_GetObjectItemCaseSensitive(Attr0, "Colours");
|
||||
cJSON *Shape = cJSON_GetObjectItemCaseSensitive(Attr0, "Shape");
|
||||
|
||||
options->cells[i]->oam[j].attr0.YCoordinate = GetInt(YCoordinate);
|
||||
int y = GetInt(YCoordinate);
|
||||
if (y & (1 << 7)) {
|
||||
y &= 0xFF;
|
||||
}
|
||||
options->cells[i]->oam[j].attr0.YCoordinate = y;
|
||||
options->cells[i]->oam[j].attr0.Rotation = GetBool(Rotation);
|
||||
options->cells[i]->oam[j].attr0.SizeDisable = GetBool(SizeDisable);
|
||||
options->cells[i]->oam[j].attr0.Mode = GetInt(Mode);
|
||||
|
|
@ -187,7 +207,11 @@ struct JsonToCellOptions *ParseNCERJson(char *path)
|
|||
cJSON *RotationScaling = cJSON_GetObjectItemCaseSensitive(Attr1, "RotationScaling");
|
||||
cJSON *Size = cJSON_GetObjectItemCaseSensitive(Attr1, "Size");
|
||||
|
||||
options->cells[i]->oam[j].attr1.XCoordinate = GetInt(XCoordinate);
|
||||
int x = GetInt(XCoordinate);
|
||||
if (x & (1 << 8)) {
|
||||
x &= 0x1FF;
|
||||
}
|
||||
options->cells[i]->oam[j].attr1.XCoordinate = x;
|
||||
options->cells[i]->oam[j].attr1.RotationScaling = GetInt(RotationScaling);
|
||||
options->cells[i]->oam[j].attr1.Size = GetInt(Size);
|
||||
|
||||
|
|
@ -218,8 +242,10 @@ char *GetNCERJson(struct JsonToCellOptions *options)
|
|||
cJSON *ncer = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddBoolToObject(ncer, "labelEnabled", options->labelEnabled);
|
||||
cJSON_AddBoolToObject(ncer, "dontPadKbec", options->dontPadKbec);
|
||||
cJSON_AddBoolToObject(ncer, "extended", options->extended);
|
||||
cJSON_AddBoolToObject(ncer, "vramTransferEnabled", options->vramTransferEnabled);
|
||||
cJSON_AddBoolToObject(ncer, "ucatEnabled", options->ucatEnabled);
|
||||
cJSON_AddNumberToObject(ncer, "cellCount", options->cellCount);
|
||||
cJSON_AddNumberToObject(ncer, "mappingType", options->mappingType);
|
||||
|
||||
|
|
@ -255,7 +281,11 @@ char *GetNCERJson(struct JsonToCellOptions *options)
|
|||
|
||||
cJSON *Attr0 = cJSON_AddObjectToObject(OAM, "Attr0");
|
||||
|
||||
cJSON_AddNumberToObject(Attr0, "YCoordinate", options->cells[i]->oam[j].attr0.YCoordinate);
|
||||
int y = options->cells[i]->oam[j].attr0.YCoordinate;
|
||||
if (y & (1 << 7)) {
|
||||
y |= ~0xFF;
|
||||
}
|
||||
cJSON_AddNumberToObject(Attr0, "YCoordinate", y);
|
||||
cJSON_AddBoolToObject(Attr0, "Rotation", options->cells[i]->oam[j].attr0.Rotation);
|
||||
cJSON_AddBoolToObject(Attr0, "SizeDisable", options->cells[i]->oam[j].attr0.SizeDisable);
|
||||
cJSON_AddNumberToObject(Attr0, "Mode", options->cells[i]->oam[j].attr0.Mode);
|
||||
|
|
@ -265,7 +295,11 @@ char *GetNCERJson(struct JsonToCellOptions *options)
|
|||
|
||||
cJSON *Attr1 = cJSON_AddObjectToObject(OAM, "Attr1");
|
||||
|
||||
cJSON_AddNumberToObject(Attr1, "XCoordinate", options->cells[i]->oam[j].attr1.XCoordinate);
|
||||
int x = options->cells[i]->oam[j].attr1.XCoordinate;
|
||||
if (x & (1 << 8)) {
|
||||
x |= ~0x1FF;
|
||||
}
|
||||
cJSON_AddNumberToObject(Attr1, "XCoordinate", x);
|
||||
cJSON_AddNumberToObject(Attr1, "RotationScaling", options->cells[i]->oam[j].attr1.RotationScaling);
|
||||
cJSON_AddNumberToObject(Attr1, "Size", options->cells[i]->oam[j].attr1.Size);
|
||||
|
||||
|
|
@ -288,11 +322,13 @@ char *GetNCERJson(struct JsonToCellOptions *options)
|
|||
cJSON_AddNumberToObject(ncer, "labelCount", options->labelCount);
|
||||
}
|
||||
|
||||
if (options->vramTransferEnabled) {
|
||||
if (options->vramTransferEnabled)
|
||||
{
|
||||
cJSON_AddNumberToObject(ncer, "vramTransferMaxSize", options->vramTransferMaxSize);
|
||||
cJSON *transfers = cJSON_AddArrayToObject(ncer, "transferData");
|
||||
|
||||
for (int idx = 0; idx < options->cellCount; idx++) {
|
||||
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);
|
||||
|
|
@ -300,6 +336,14 @@ char *GetNCERJson(struct JsonToCellOptions *options)
|
|||
}
|
||||
}
|
||||
|
||||
if (options->ucatEnabled) {
|
||||
cJSON *ucatCells = cJSON_AddArrayToObject(ncer, "cellAttributes");
|
||||
|
||||
for (int i = 0; i < options->cellCount; i++) {
|
||||
cJSON_AddNumberToObject(ucatCells, "cellAttr", options->ucatCellAttribtes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
char *jsonString = cJSON_Print(ncer);
|
||||
cJSON_Delete(ncer);
|
||||
return jsonString;
|
||||
|
|
@ -473,6 +517,9 @@ struct JsonToAnimationOptions *ParseNANRJson(char *path)
|
|||
if (i > options->resultCount - 1)
|
||||
FATAL_ERROR("Frame count is incorrect.\n");
|
||||
|
||||
// init padding to false, this is used in gfx.c to control padding, and is therefore checked there
|
||||
options->animationResults[i]->padded = false;
|
||||
|
||||
cJSON *resultType = cJSON_GetObjectItemCaseSensitive(animationResult, "resultType");
|
||||
options->animationResults[i]->resultType = GetInt(resultType);
|
||||
switch (options->animationResults[i]->resultType) {
|
||||
|
|
@ -538,6 +585,27 @@ struct JsonToAnimationOptions *ParseNANRJson(char *path)
|
|||
}
|
||||
}
|
||||
|
||||
cJSON *uaatBool = cJSON_GetObjectItemCaseSensitive(json, "uaatEnabled");
|
||||
options->uaatEnabled = GetBool(uaatBool);
|
||||
|
||||
if (options->uaatEnabled) {
|
||||
cJSON *uaatData = cJSON_GetObjectItemCaseSensitive(json, "uaatData");
|
||||
|
||||
cJSON *uaatSequences = cJSON_GetObjectItemCaseSensitive(uaatData, "sequenceAttributes");
|
||||
options->uaatData.sequenceAttributes = malloc(sizeof(uint32_t) * options->sequenceCount);
|
||||
for (int i = 0; i < options->sequenceCount; i++) {
|
||||
cJSON *uaatSeq = cJSON_GetArrayItem(uaatSequences, i);
|
||||
options->uaatData.sequenceAttributes[i] = GetInt(uaatSeq);
|
||||
}
|
||||
|
||||
cJSON *uaatFrames = cJSON_GetObjectItemCaseSensitive(uaatData, "frameAttributes");
|
||||
options->uaatData.frameAttributes = malloc(sizeof(uint32_t) * options->frameCount);
|
||||
for (int i = 0; i < options->frameCount; i++) {
|
||||
cJSON *uaatFra = cJSON_GetArrayItem(uaatFrames, i);
|
||||
options->uaatData.frameAttributes[i] = GetInt(uaatFra);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
free(jsonString);
|
||||
return options;
|
||||
|
|
@ -548,6 +616,7 @@ char *GetNANRJson(struct JsonToAnimationOptions *options)
|
|||
cJSON *nanr = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddBoolToObject(nanr, "labelEnabled", options->labelEnabled);
|
||||
cJSON_AddBoolToObject(nanr, "uaatEnabled", options->uaatEnabled);
|
||||
cJSON_AddNumberToObject(nanr, "sequenceCount", options->sequenceCount);
|
||||
cJSON_AddNumberToObject(nanr, "frameCount", options->frameCount);
|
||||
|
||||
|
|
@ -617,6 +686,20 @@ char *GetNANRJson(struct JsonToAnimationOptions *options)
|
|||
cJSON_AddNumberToObject(nanr, "labelCount", options->labelCount);
|
||||
}
|
||||
|
||||
if (options->uaatEnabled) {
|
||||
cJSON *uaat = cJSON_AddObjectToObject(nanr, "uaatData");
|
||||
|
||||
cJSON *uaatSequences = cJSON_AddArrayToObject(uaat, "sequenceAttributes");
|
||||
for (int i = 0; i < options->sequenceCount; i++) {
|
||||
cJSON_AddNumberToObject(uaatSequences, "seqAttr", options->uaatData.sequenceAttributes[i]);
|
||||
}
|
||||
|
||||
cJSON *uaatFrames = cJSON_AddArrayToObject(uaat, "frameAttributes");
|
||||
for (int i = 0; i < options->frameCount; i++) {
|
||||
cJSON_AddNumberToObject(uaatFrames, "fraAttr", options->uaatData.frameAttributes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
char *jsonString = cJSON_Print(nanr);
|
||||
cJSON_Delete(nanr);
|
||||
return jsonString;
|
||||
|
|
@ -637,12 +720,17 @@ void FreeNCERCell(struct JsonToCellOptions *options)
|
|||
}
|
||||
free(options->labels);
|
||||
}
|
||||
if (options->vramTransferEnabled) {
|
||||
for (int j = 0; j < options->cellCount; j++) {
|
||||
if (options->vramTransferEnabled)
|
||||
{
|
||||
for (int j = 0; j < options->cellCount; j++)
|
||||
{
|
||||
free(options->transferData[j]);
|
||||
}
|
||||
free(options->transferData);
|
||||
}
|
||||
if (options->ucatEnabled) {
|
||||
free(options->ucatCellAttribtes);
|
||||
}
|
||||
free(options->cells);
|
||||
free(options);
|
||||
}
|
||||
|
|
@ -669,6 +757,10 @@ void FreeNANRAnimation(struct JsonToAnimationOptions *options)
|
|||
{
|
||||
free(options->animationResults[i]);
|
||||
}
|
||||
if (options->uaatEnabled) {
|
||||
free(options->uaatData.sequenceAttributes);
|
||||
free(options->uaatData.frameAttributes);
|
||||
}
|
||||
if (options->labelEnabled)
|
||||
{
|
||||
for (int j = 0; j < options->labelCount; j++)
|
||||
|
|
@ -682,14 +774,16 @@ void FreeNANRAnimation(struct JsonToAnimationOptions *options)
|
|||
free(options);
|
||||
}
|
||||
|
||||
char *GetNtrFontMetadataJson(struct NtrFontMetadata *metadata) {
|
||||
char *GetNtrFontMetadataJson(struct NtrFontMetadata *metadata)
|
||||
{
|
||||
cJSON *json = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddNumberToObject(json, "maxGlyphWidth", metadata->maxWidth);
|
||||
cJSON_AddNumberToObject(json, "maxGlyphHeight", metadata->maxHeight);
|
||||
|
||||
cJSON *glyphWidths = cJSON_AddArrayToObject(json, "glyphWidths");
|
||||
for (int i = 0; i < metadata->numGlyphs; i++) {
|
||||
for (int i = 0; i < metadata->numGlyphs; i++)
|
||||
{
|
||||
cJSON *width = cJSON_CreateNumber(metadata->glyphWidthTable[i]);
|
||||
cJSON_AddItemToArray(glyphWidths, width);
|
||||
}
|
||||
|
|
@ -699,18 +793,20 @@ char *GetNtrFontMetadataJson(struct NtrFontMetadata *metadata) {
|
|||
return jsonString;
|
||||
}
|
||||
|
||||
#define TILE_DIMENSION_PIXELS 8
|
||||
#define TILE_DIMENSION_PIXELS 8
|
||||
#define PIXELS_FOR_DIMENSION(dim) ((dim) * TILE_DIMENSION_PIXELS)
|
||||
#define TILES_FOR_PIXELS(num) (((num) + TILE_DIMENSION_PIXELS - 1) / TILE_DIMENSION_PIXELS)
|
||||
#define PIXELS_PER_BYTE_2BPP 4
|
||||
#define NTR_FONT_HEADER_SIZE 16
|
||||
#define TILES_FOR_PIXELS(num) (((num) + TILE_DIMENSION_PIXELS - 1) / TILE_DIMENSION_PIXELS)
|
||||
#define PIXELS_PER_BYTE_2BPP 4
|
||||
#define NTR_FONT_HEADER_SIZE 16
|
||||
|
||||
struct NtrFontMetadata *ParseNtrFontMetadataJson(char *path) {
|
||||
struct NtrFontMetadata *ParseNtrFontMetadataJson(char *path)
|
||||
{
|
||||
int fileLength;
|
||||
unsigned char *jsonString = ReadWholeFile(path, &fileLength);
|
||||
|
||||
cJSON *json = cJSON_Parse((const char *)jsonString);
|
||||
if (json == NULL) {
|
||||
if (json == NULL)
|
||||
{
|
||||
const char *errorPtr = cJSON_GetErrorPtr();
|
||||
FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
|
||||
}
|
||||
|
|
@ -737,8 +833,10 @@ struct NtrFontMetadata *ParseNtrFontMetadataJson(char *path) {
|
|||
|
||||
uint8_t *glyphWidthCursor = metadata->glyphWidthTable;
|
||||
cJSON *glyphWidthIter = NULL;
|
||||
cJSON_ArrayForEach(glyphWidthIter, labelGlyphWidths) {
|
||||
if (!cJSON_IsNumber(glyphWidthIter)) {
|
||||
cJSON_ArrayForEach(glyphWidthIter, labelGlyphWidths)
|
||||
{
|
||||
if (!cJSON_IsNumber(glyphWidthIter))
|
||||
{
|
||||
const char *errorPtr = cJSON_GetErrorPtr();
|
||||
FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2021-2024 red031000
|
||||
// Copyright (c) 2021-2025 red031000
|
||||
|
||||
#ifndef JSON_H
|
||||
#define JSON_H
|
||||
|
|
|
|||
|
|
@ -1,69 +1,39 @@
|
|||
// Copyright (c) 2015 YamaArashi
|
||||
|
||||
#include "lz.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "global.h"
|
||||
#include "lz.h"
|
||||
|
||||
static inline int getBlockSize(unsigned char *src, int *srcPos, int extFormat) {
|
||||
int blockSize = (src[*srcPos] >> 4);
|
||||
if (!extFormat) {
|
||||
blockSize += 3;
|
||||
} else {
|
||||
if (blockSize > 1) {
|
||||
blockSize += 1;
|
||||
} else {
|
||||
int isWide = (blockSize == 1 ? 1 : 0);
|
||||
blockSize = (src[(*srcPos)++] & 0xF) << 4;
|
||||
if (isWide) {
|
||||
blockSize = (blockSize << 8) + (src[(*srcPos)++] << 4) + 0x100;
|
||||
}
|
||||
blockSize += 0x11 + (src[*srcPos] >> 4);
|
||||
}
|
||||
}
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
unsigned char *LZDecompress(unsigned char *src, int srcSize, int *uncompressedSize) {
|
||||
if (srcSize < 4) {
|
||||
unsigned char *LZDecompress(unsigned char *src, int srcSize, int *uncompressedSize)
|
||||
{
|
||||
if (srcSize < 4)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((src[0] & 0xF0) != 0x10) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
|
||||
|
||||
unsigned char *dest = malloc(destSize);
|
||||
|
||||
if (dest == NULL) {
|
||||
if (dest == NULL)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int srcPos = 4;
|
||||
int destPos = 0;
|
||||
|
||||
int extFormat = src[0] & 0xF ? 1 : 0;
|
||||
|
||||
for (;;) {
|
||||
if (srcPos >= srcSize) {
|
||||
if (srcPos >= srcSize)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
unsigned char flags = src[srcPos++];
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (flags & 0x80) {
|
||||
if (srcPos + 1 >= srcSize) {
|
||||
if (srcPos + 1 >= srcSize)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int blockSize = getBlockSize(src, &srcPos, extFormat);
|
||||
int blockSize = (src[srcPos] >> 4) + 3;
|
||||
int blockDistance = (((src[srcPos] & 0xF) << 8) | src[srcPos + 1]) + 1;
|
||||
|
||||
srcPos += 2;
|
||||
|
|
@ -76,17 +46,14 @@ unsigned char *LZDecompress(unsigned char *src, int srcSize, int *uncompressedSi
|
|||
fprintf(stderr, "Destination buffer overflow.\n");
|
||||
}
|
||||
|
||||
if (blockPos < 0) {
|
||||
if (blockPos < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (int j = 0; j < blockSize; j++) {
|
||||
for (int j = 0; j < blockSize; j++)
|
||||
dest[destPos++] = dest[blockPos + j];
|
||||
}
|
||||
} else {
|
||||
if (srcPos >= srcSize || destPos >= destSize) {
|
||||
if (srcPos >= srcSize || destPos >= destSize)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dest[destPos++] = src[srcPos++];
|
||||
}
|
||||
|
|
@ -104,66 +71,60 @@ fail:
|
|||
FATAL_ERROR("Fatal error while decompressing LZ file.\n");
|
||||
}
|
||||
|
||||
static void FindBestBlockForwards(unsigned char *src, int srcPos, int srcSize, const int minDistance, int *outBestBlockDistance, int *outBestBlockSize, bool extFormat) {
|
||||
static void FindBestBlockForwards(unsigned char *src, int srcPos, int srcSize, const int minDistance, int *outBestBlockDistance, int *outBestBlockSize)
|
||||
{
|
||||
int blockStart = srcPos < 0x1000 ? 0 : srcPos - 0x1000;
|
||||
int maxBlockSize = extFormat ? 0xF210 : 18;
|
||||
|
||||
while (blockStart != srcPos) {
|
||||
int blockSize = 0;
|
||||
|
||||
while (blockSize < maxBlockSize
|
||||
while (blockSize < 18
|
||||
&& srcPos + blockSize < srcSize
|
||||
&& src[blockStart + blockSize] == src[srcPos + blockSize]) {
|
||||
&& src[blockStart + blockSize] == src[srcPos + blockSize])
|
||||
blockSize++;
|
||||
}
|
||||
|
||||
if (blockSize > *outBestBlockSize
|
||||
&& srcPos - blockStart >= minDistance) {
|
||||
*outBestBlockDistance = srcPos - blockStart;
|
||||
*outBestBlockSize = blockSize;
|
||||
|
||||
if (blockSize == maxBlockSize) {
|
||||
if (blockSize == 18)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
blockStart++;
|
||||
}
|
||||
}
|
||||
|
||||
static void FindBestBlockBackwards(unsigned char *src, int srcPos, int srcSize, const int minDistance, int *outBestBlockDistance, int *outBestBlockSize, bool extFormat) {
|
||||
static void FindBestBlockBackwards(unsigned char *src, int srcPos, int srcSize, const int minDistance, int *outBestBlockDistance, int *outBestBlockSize)
|
||||
{
|
||||
int blockDistance = minDistance;
|
||||
int maxBlockSize = extFormat ? 0xF210 : 18;
|
||||
|
||||
while (blockDistance <= srcPos && blockDistance <= 0x1000) {
|
||||
int blockStart = srcPos - blockDistance;
|
||||
int blockSize = 0;
|
||||
|
||||
while (blockSize < maxBlockSize
|
||||
while (blockSize < 18
|
||||
&& srcPos + blockSize < srcSize
|
||||
&& src[blockStart + blockSize] == src[srcPos + blockSize]) {
|
||||
&& src[blockStart + blockSize] == src[srcPos + blockSize])
|
||||
blockSize++;
|
||||
}
|
||||
|
||||
if (blockSize > *outBestBlockSize) {
|
||||
*outBestBlockDistance = blockDistance;
|
||||
*outBestBlockSize = blockSize;
|
||||
|
||||
if (blockSize == 18) {
|
||||
if (blockSize == 18)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
blockDistance++;
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*FindBestBlockFunc)(unsigned char *src, int srcPos, int srcSize, const int minDistance, int *outBestBlockDistance, int *outBestBlockSize, bool extFormat);
|
||||
typedef void (*FindBestBlockFunc)(unsigned char *src, int srcPos, int srcSize, const int minDistance, int *outBestBlockDistance, int *outBestBlockSize);
|
||||
|
||||
unsigned char *LZCompress(unsigned char *src, int srcSize, int *compressedSize, const int minDistance, bool forwardIteration, bool pad, bool extFormat) {
|
||||
if (srcSize <= 0) {
|
||||
unsigned char *LZCompress(unsigned char *src, int srcSize, int *compressedSize, const int minDistance, bool forwardIteration, bool pad) {
|
||||
if (srcSize <= 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int worstCaseDestSize = 4 + srcSize + ((srcSize + 7) / 8);
|
||||
|
||||
|
|
@ -172,12 +133,11 @@ unsigned char *LZCompress(unsigned char *src, int srcSize, int *compressedSize,
|
|||
|
||||
unsigned char *dest = malloc(worstCaseDestSize);
|
||||
|
||||
if (dest == NULL) {
|
||||
if (dest == NULL)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// header
|
||||
dest[0] = 0x10 | extFormat; // LZ compression type
|
||||
dest[0] = 0x10; // LZ compression type
|
||||
dest[1] = (unsigned char)srcSize;
|
||||
dest[2] = (unsigned char)(srcSize >> 8);
|
||||
dest[3] = (unsigned char)(srcSize >> 16);
|
||||
|
|
@ -194,48 +154,19 @@ unsigned char *LZCompress(unsigned char *src, int srcSize, int *compressedSize,
|
|||
int bestBlockDistance = 0;
|
||||
int bestBlockSize = 0;
|
||||
|
||||
FindBestBlock(src, srcPos, srcSize, minDistance, &bestBlockDistance, &bestBlockSize, extFormat);
|
||||
FindBestBlock(src, srcPos, srcSize, minDistance, &bestBlockDistance, &bestBlockSize);
|
||||
|
||||
if (extFormat) {
|
||||
if (bestBlockSize >= 272) {
|
||||
*flags |= (0x80 >> i);
|
||||
srcPos += bestBlockSize;
|
||||
bestBlockSize -= 273;
|
||||
bestBlockDistance--;
|
||||
dest[destPos++] = ((bestBlockSize >> 12) & 0xF) | 0x10;
|
||||
dest[destPos++] = bestBlockSize >> 4;
|
||||
dest[destPos++] = (bestBlockSize << 4) | ((unsigned int)bestBlockDistance >> 8);
|
||||
dest[destPos++] = (unsigned char)bestBlockDistance;
|
||||
} else if (bestBlockSize >= 17) {
|
||||
*flags |= (0x80 >> i);
|
||||
srcPos += bestBlockSize;
|
||||
bestBlockSize -= 17;
|
||||
bestBlockDistance--;
|
||||
dest[destPos++] = (bestBlockSize >> 4) & 0xF;
|
||||
dest[destPos++] = (bestBlockSize << 4) | ((unsigned int)bestBlockDistance >> 8);
|
||||
dest[destPos++] = (unsigned char)bestBlockDistance;
|
||||
} else if (bestBlockSize >= 3) {
|
||||
*flags |= (0x80 >> i);
|
||||
srcPos += bestBlockSize;
|
||||
bestBlockSize -= 1;
|
||||
bestBlockDistance--;
|
||||
dest[destPos++] = (bestBlockSize << 4) | ((unsigned int)bestBlockDistance >> 8);
|
||||
dest[destPos++] = (unsigned char)bestBlockDistance;
|
||||
} else {
|
||||
dest[destPos++] = src[srcPos++];
|
||||
}
|
||||
if (bestBlockSize >= 3) {
|
||||
*flags |= (0x80 >> i);
|
||||
srcPos += bestBlockSize;
|
||||
bestBlockSize -= 3;
|
||||
bestBlockDistance--;
|
||||
dest[destPos++] = (bestBlockSize << 4) | ((unsigned int)bestBlockDistance >> 8);
|
||||
dest[destPos++] = (unsigned char)bestBlockDistance;
|
||||
} else {
|
||||
if (bestBlockSize >= 3) {
|
||||
*flags |= (0x80 >> i);
|
||||
srcPos += bestBlockSize;
|
||||
bestBlockSize -= 3;
|
||||
bestBlockDistance--;
|
||||
dest[destPos++] = (bestBlockSize << 4) | ((unsigned int)bestBlockDistance >> 8);
|
||||
dest[destPos++] = (unsigned char)bestBlockDistance;
|
||||
} else {
|
||||
dest[destPos++] = src[srcPos++];
|
||||
}
|
||||
dest[destPos++] = src[srcPos++];
|
||||
}
|
||||
|
||||
if (srcPos == srcSize) {
|
||||
if (pad) {
|
||||
// Pad to multiple of 4 bytes.
|
||||
|
|
@ -247,6 +178,7 @@ unsigned char *LZCompress(unsigned char *src, int srcSize, int *compressedSize,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*compressedSize = destPos;
|
||||
return dest;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@
|
|||
#include "stdbool.h"
|
||||
|
||||
unsigned char *LZDecompress(unsigned char *src, int srcSize, int *uncompressedSize);
|
||||
unsigned char *LZCompress(unsigned char *src, int srcSize, int *compressedSize, const int minDistance, bool forwardIteration, bool pad, bool extFormat);
|
||||
unsigned char *LZCompress(unsigned char *src, int srcSize, int *compressedSize, const int minDistance, bool forwardIteration, bool pad);
|
||||
|
||||
#endif // LZ_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright (c) 2018 huderlem, 2021-2024 red031000
|
||||
// Copyright (c) 2018 huderlem, 2021-2025 red031000
|
||||
|
||||
#ifndef OPTIONS_H
|
||||
#define OPTIONS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct GbaToPngOptions {
|
||||
char *paletteFilePath;
|
||||
|
|
@ -25,6 +25,7 @@ struct PngToGbaOptions {
|
|||
|
||||
struct PngToNtrOptions {
|
||||
char *cellFilePath;
|
||||
bool cellSnap;
|
||||
int numTiles;
|
||||
int bitDepth;
|
||||
int colsPerChunk;
|
||||
|
|
@ -33,25 +34,29 @@ struct PngToNtrOptions {
|
|||
bool byteOrder;
|
||||
bool version101;
|
||||
bool sopc;
|
||||
uint32_t scanMode;
|
||||
bool scan;
|
||||
bool wrongSize;
|
||||
bool handleEmpty;
|
||||
bool vramTransfer;
|
||||
int mappingType;
|
||||
uint32_t encodeMode;
|
||||
bool convertTo4Bpp;
|
||||
};
|
||||
|
||||
struct NtrToPngOptions {
|
||||
char *paletteFilePath;
|
||||
char *cellFilePath;
|
||||
char *scrnFilePath;
|
||||
bool cellSnap;
|
||||
int bitDepth;
|
||||
bool hasTransparency;
|
||||
int width;
|
||||
int colsPerChunk;
|
||||
int rowsPerChunk;
|
||||
int palIndex;
|
||||
bool scanFrontToBack;
|
||||
bool handleEmpty;
|
||||
uint32_t encodeMode;
|
||||
bool convertTo8Bpp;
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
struct CellVramTransferData {
|
||||
|
|
@ -88,10 +93,10 @@ struct OAM {
|
|||
};
|
||||
|
||||
struct CellAttributes {
|
||||
bool hFlip; // 1 << 8
|
||||
bool vFlip; // 1 << 9
|
||||
bool hvFlip; // 1 << 10
|
||||
bool boundingRect; // 1 << 11
|
||||
bool hFlip; // 1 << 8
|
||||
bool vFlip; // 1 << 9
|
||||
bool hvFlip; // 1 << 10
|
||||
bool boundingRect; // 1 << 11
|
||||
int boundingSphereRadius; // 1 << 0 (6 bits);
|
||||
};
|
||||
|
||||
|
|
@ -107,8 +112,10 @@ struct Cell {
|
|||
|
||||
struct JsonToCellOptions {
|
||||
bool labelEnabled;
|
||||
bool dontPadKbec;
|
||||
bool extended;
|
||||
bool vramTransferEnabled;
|
||||
bool ucatEnabled;
|
||||
int mappingType;
|
||||
int cellCount;
|
||||
struct Cell **cells;
|
||||
|
|
@ -116,6 +123,7 @@ struct JsonToCellOptions {
|
|||
struct CellVramTransferData **transferData;
|
||||
char **labels;
|
||||
int labelCount;
|
||||
int *ucatCellAttribtes;
|
||||
};
|
||||
|
||||
struct JsonToScreenOptions {
|
||||
|
|
@ -151,7 +159,7 @@ struct AnimationDataSRT {
|
|||
|
||||
struct AnimationDataT {
|
||||
short index;
|
||||
// unsigned short rotation;
|
||||
//unsigned short rotation;
|
||||
short positionX;
|
||||
short positionY;
|
||||
};
|
||||
|
|
@ -166,6 +174,11 @@ struct AnimationResults {
|
|||
};
|
||||
};
|
||||
|
||||
struct UaatData {
|
||||
int *sequenceAttributes;
|
||||
int *frameAttributes;
|
||||
};
|
||||
|
||||
struct JsonToAnimationOptions {
|
||||
bool multiCell;
|
||||
short sequenceCount;
|
||||
|
|
@ -176,6 +189,8 @@ struct JsonToAnimationOptions {
|
|||
char **labels;
|
||||
int labelCount;
|
||||
short resultCount;
|
||||
bool uaatEnabled;
|
||||
struct UaatData uaatData;
|
||||
};
|
||||
|
||||
struct NtrFontOptions {
|
||||
|
|
|
|||
|
|
@ -14,29 +14,24 @@ bool ParseNumber(char *s, char **end, int radix, int *intValue)
|
|||
{
|
||||
char *localEnd;
|
||||
|
||||
if (end == NULL) {
|
||||
if (end == NULL)
|
||||
end = &localEnd;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
const long longValue = strtol(s, end, radix);
|
||||
|
||||
if (*end == s) {
|
||||
if (*end == s)
|
||||
return false; // not a number
|
||||
}
|
||||
|
||||
if ((longValue == LONG_MIN || longValue == LONG_MAX) && errno == ERANGE) {
|
||||
if ((longValue == LONG_MIN || longValue == LONG_MAX) && errno == ERANGE)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (longValue > INT_MAX) {
|
||||
if (longValue > INT_MAX)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (longValue < INT_MIN) {
|
||||
if (longValue < INT_MIN)
|
||||
return false;
|
||||
}
|
||||
|
||||
*intValue = (int)longValue;
|
||||
|
||||
|
|
@ -47,23 +42,19 @@ char *GetFileExtension(char *path)
|
|||
{
|
||||
char *extension = path;
|
||||
|
||||
while (*extension != 0) {
|
||||
while (*extension != 0)
|
||||
extension++;
|
||||
}
|
||||
|
||||
while (extension > path && *extension != '.') {
|
||||
while (extension > path && *extension != '.')
|
||||
extension--;
|
||||
}
|
||||
|
||||
if (extension == path) {
|
||||
if (extension == path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extension++;
|
||||
|
||||
if (*extension == 0) {
|
||||
if (*extension == 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(extension, "lz") == 0) {
|
||||
char *plainName = malloc(strlen(path) + 1);
|
||||
|
|
@ -83,9 +74,8 @@ unsigned char *ReadWholeFile(char *path, int *size)
|
|||
{
|
||||
FILE *fp = fopen(path, "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
if (fp == NULL)
|
||||
FATAL_ERROR("Failed to open \"%s\" for reading.\n", path);
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
|
||||
|
|
@ -93,15 +83,13 @@ unsigned char *ReadWholeFile(char *path, int *size)
|
|||
|
||||
unsigned char *buffer = malloc(*size);
|
||||
|
||||
if (buffer == NULL) {
|
||||
if (buffer == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for reading \"%s\".\n", path);
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
|
||||
if (fread(buffer, *size, 1, fp) != 1) {
|
||||
if (fread(buffer, *size, 1, fp) != 1)
|
||||
FATAL_ERROR("Failed to read \"%s\".\n", path);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
|
|
@ -112,9 +100,8 @@ unsigned char *ReadWholeFileZeroPadded(char *path, int *size, int padAmount)
|
|||
{
|
||||
FILE *fp = fopen(path, "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
if (fp == NULL)
|
||||
FATAL_ERROR("Failed to open \"%s\" for reading.\n", path);
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
|
||||
|
|
@ -122,15 +109,13 @@ unsigned char *ReadWholeFileZeroPadded(char *path, int *size, int padAmount)
|
|||
|
||||
unsigned char *buffer = calloc(*size + padAmount, 1);
|
||||
|
||||
if (buffer == NULL) {
|
||||
if (buffer == NULL)
|
||||
FATAL_ERROR("Failed to allocate memory for reading \"%s\".\n", path);
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
|
||||
if (fread(buffer, *size, 1, fp) != 1) {
|
||||
if (fread(buffer, *size, 1, fp) != 1)
|
||||
FATAL_ERROR("Failed to read \"%s\".\n", path);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
|
|
@ -141,13 +126,11 @@ void WriteWholeStringToFile(char *path, char *string)
|
|||
{
|
||||
FILE *fp = fopen(path, "wb");
|
||||
|
||||
if (fp == NULL) {
|
||||
if (fp == NULL)
|
||||
FATAL_ERROR("Failed to open \"%s\" for writing.\n", path);
|
||||
}
|
||||
|
||||
if (fputs(string, fp) == EOF) {
|
||||
if (fputs(string, fp) == EOF)
|
||||
FATAL_ERROR("Failed to write to \"%s\".\n", path);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
|
@ -156,13 +139,11 @@ void WriteWholeFile(char *path, void *buffer, int bufferSize)
|
|||
{
|
||||
FILE *fp = fopen(path, "wb");
|
||||
|
||||
if (fp == NULL) {
|
||||
if (fp == NULL)
|
||||
FATAL_ERROR("Failed to open \"%s\" for writing.\n", path);
|
||||
}
|
||||
|
||||
if (fwrite(buffer, bufferSize, 1, fp) != 1) {
|
||||
if (fwrite(buffer, bufferSize, 1, fp) != 1)
|
||||
FATAL_ERROR("Failed to write to \"%s\".\n", path);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user