mirror of
https://github.com/pret/pmd-sky.git
synced 2026-03-21 17:25:15 -05:00
Updated nitrogfx
This commit is contained in:
parent
4f948e5c1e
commit
e66b9500dc
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2015 YamaArashi
|
Copyright (c) 2015 YamaArashi, 2021-2023 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
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,28 @@
|
||||||
CC = gcc
|
CC = gcc
|
||||||
LD = gcc
|
|
||||||
|
|
||||||
CFLAGS = -Wall -Wextra -Werror -Wno-sign-compare -std=c11 -O2 -DPNG_SKIP_SETJMP_CHECK $(shell pkg-config --cflags libpng)
|
HAVE_LIBPNG := $(shell pkg-config libpng; echo $?)
|
||||||
|
|
||||||
LIBS = $(shell pkg-config --libs libpng)
|
ifeq ($(HAVE_LIBPNG),1)
|
||||||
|
$(error No package 'libpng' found)
|
||||||
|
endif
|
||||||
|
|
||||||
SRCS = main.c convert_png.c gfx.c jasc_pal.c lz.c rl.c util.c font.c huff.c
|
CFLAGS = -Wall -Wextra -Werror -Wno-sign-compare -std=c11 -O2 -DPNG_SKIP_SETJMP_CHECK $(shell pkg-config --cflags libpng zlib)
|
||||||
|
|
||||||
|
LIBS = $(shell pkg-config --libs libpng zlib)
|
||||||
|
|
||||||
|
SRCS = main.c convert_png.c gfx.c jasc_pal.c lz.c rl.c util.c font.c huff.c json.c cJSON.c
|
||||||
OBJS = $(SRCS:%.c=%.o)
|
OBJS = $(SRCS:%.c=%.o)
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
DEPDIR := .deps
|
|
||||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d
|
|
||||||
|
|
||||||
ifneq ($(DEBUG),)
|
|
||||||
CFLAGS += -DDEBUG
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: nitrogfx
|
all: nitrogfx
|
||||||
@:
|
@:
|
||||||
|
|
||||||
nitrogfx-debug: DEBUG = 1
|
nitrogfx-debug: $(SRCS) convert_png.h gfx.h global.h jasc_pal.h lz.h rl.h util.h font.h json.h cJSON.h
|
||||||
nitrogfx-debug: nitrogfx
|
$(CC) $(CFLAGS) -g -DDEBUG $(SRCS) -o $@ $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
nitrogfx: $(OBJS)
|
nitrogfx: $(SRCS) convert_png.h gfx.h global.h jasc_pal.h lz.h rl.h util.h font.h json.h cJSON.h
|
||||||
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
%.o: %.c $(DEPDIR)/%.d | $(DEPDIR)
|
|
||||||
$(CC) $(CFLAGS) $(DEPFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) -r nitrogfx nitrogfx.exe $(OBJS) $(DEPDIR)
|
$(RM) -r nitrogfx nitrogfx.exe $(OBJS)
|
||||||
|
|
||||||
$(DEPDIR): ; @mkdir -p $@
|
|
||||||
|
|
||||||
DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d)
|
|
||||||
$(DEPFILES):
|
|
||||||
|
|
||||||
include $(wildcard $(DEPFILES))
|
|
||||||
|
|
|
||||||
3110
tools/nitrogfx/cJSON.c
Normal file
3110
tools/nitrogfx/cJSON.c
Normal file
File diff suppressed because it is too large
Load Diff
293
tools/nitrogfx/cJSON.h
Normal file
293
tools/nitrogfx/cJSON.h
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cJSON__h
|
||||||
|
#define cJSON__h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||||
|
#define __WINDOWS__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
|
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||||
|
|
||||||
|
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||||
|
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||||
|
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||||
|
|
||||||
|
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||||
|
|
||||||
|
setting default visibility to hidden by adding
|
||||||
|
-fvisibility=hidden (for gcc)
|
||||||
|
or
|
||||||
|
-xldscope=hidden (for sun cc)
|
||||||
|
to CFLAGS
|
||||||
|
|
||||||
|
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CJSON_CDECL __cdecl
|
||||||
|
#define CJSON_STDCALL __stdcall
|
||||||
|
|
||||||
|
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||||
|
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_EXPORT_SYMBOLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CJSON_HIDE_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||||
|
#endif
|
||||||
|
#else /* !__WINDOWS__ */
|
||||||
|
#define CJSON_CDECL
|
||||||
|
#define CJSON_STDCALL
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||||
|
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||||
|
#else
|
||||||
|
#define CJSON_PUBLIC(type) type
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* project version */
|
||||||
|
#define CJSON_VERSION_MAJOR 1
|
||||||
|
#define CJSON_VERSION_MINOR 7
|
||||||
|
#define CJSON_VERSION_PATCH 15
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* cJSON Types: */
|
||||||
|
#define cJSON_Invalid (0)
|
||||||
|
#define cJSON_False (1 << 0)
|
||||||
|
#define cJSON_True (1 << 1)
|
||||||
|
#define cJSON_NULL (1 << 2)
|
||||||
|
#define cJSON_Number (1 << 3)
|
||||||
|
#define cJSON_String (1 << 4)
|
||||||
|
#define cJSON_Array (1 << 5)
|
||||||
|
#define cJSON_Object (1 << 6)
|
||||||
|
#define cJSON_Raw (1 << 7) /* raw json */
|
||||||
|
|
||||||
|
#define cJSON_IsReference 256
|
||||||
|
#define cJSON_StringIsConst 512
|
||||||
|
|
||||||
|
/* The cJSON structure: */
|
||||||
|
typedef struct cJSON
|
||||||
|
{
|
||||||
|
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||||
|
struct cJSON *next;
|
||||||
|
struct cJSON *prev;
|
||||||
|
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||||
|
struct cJSON *child;
|
||||||
|
|
||||||
|
/* The type of the item, as above. */
|
||||||
|
int type;
|
||||||
|
|
||||||
|
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||||
|
char *valuestring;
|
||||||
|
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||||
|
int valueint;
|
||||||
|
/* The item's number, if type==cJSON_Number */
|
||||||
|
double valuedouble;
|
||||||
|
|
||||||
|
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||||
|
char *string;
|
||||||
|
} cJSON;
|
||||||
|
|
||||||
|
typedef struct cJSON_Hooks
|
||||||
|
{
|
||||||
|
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||||
|
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||||
|
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||||
|
} cJSON_Hooks;
|
||||||
|
|
||||||
|
typedef int cJSON_bool;
|
||||||
|
|
||||||
|
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||||
|
* This is to prevent stack overflows. */
|
||||||
|
#ifndef CJSON_NESTING_LIMIT
|
||||||
|
#define CJSON_NESTING_LIMIT 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* returns the version of cJSON as a string */
|
||||||
|
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||||
|
|
||||||
|
/* Supply malloc, realloc and free functions to cJSON */
|
||||||
|
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||||
|
|
||||||
|
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||||
|
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||||
|
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||||
|
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
|
||||||
|
/* Render a cJSON entity to text for transfer/storage. */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||||
|
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||||
|
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||||
|
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||||
|
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||||
|
/* Delete a cJSON entity and all subentities. */
|
||||||
|
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||||
|
|
||||||
|
/* Returns the number of items in an array (or object). */
|
||||||
|
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||||
|
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||||
|
/* Get item "string" from object. Case insensitive. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||||
|
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||||
|
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||||
|
|
||||||
|
/* Check item type and return its value */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||||
|
|
||||||
|
/* These functions check the type of an item */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||||
|
|
||||||
|
/* These calls create a cJSON item of the appropriate type. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||||
|
/* raw json */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||||
|
|
||||||
|
/* Create a string where valuestring references a string so
|
||||||
|
* it will not be freed by cJSON_Delete */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||||
|
/* Create an object/array that only references it's elements so
|
||||||
|
* they will not be freed by cJSON_Delete */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||||
|
|
||||||
|
/* These utilities create an Array of count items.
|
||||||
|
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||||
|
|
||||||
|
/* Append item to the specified array/object. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||||
|
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||||
|
* writing to `item->string` */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||||
|
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
|
||||||
|
/* Remove/Detach items from Arrays/Objects. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
|
||||||
|
/* Update array items. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
|
||||||
|
/* Duplicate a cJSON item */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||||
|
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||||
|
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||||
|
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||||
|
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||||
|
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||||
|
|
||||||
|
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||||
|
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||||
|
* but should point to a readable and writable address area. */
|
||||||
|
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||||
|
|
||||||
|
/* Helper functions for creating and adding items to an object at the same time.
|
||||||
|
* They return the added item or NULL on failure. */
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||||
|
|
||||||
|
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||||
|
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||||
|
/* helper for the cJSON_SetNumberValue macro */
|
||||||
|
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
|
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||||
|
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||||
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
|
||||||
|
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||||
|
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||||
|
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
1466
tools/nitrogfx/gfx.c
1466
tools/nitrogfx/gfx.c
File diff suppressed because it is too large
Load Diff
|
|
@ -1,10 +1,11 @@
|
||||||
// Copyright (c) 2015 YamaArashi
|
// Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
||||||
|
|
||||||
#ifndef GFX_H
|
#ifndef GFX_H
|
||||||
#define GFX_H
|
#define GFX_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
struct Color {
|
struct Color {
|
||||||
unsigned char red;
|
unsigned char red;
|
||||||
|
|
@ -22,20 +23,48 @@ struct Image {
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int bitDepth;
|
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) ):
|
||||||
|
* if (bitDepth == 4)
|
||||||
|
* for (int i = 0; i < width * height / 2; i++)
|
||||||
|
* xCoord = i % <WIDTH OF IMAGE>
|
||||||
|
* yCoord = i / <WIDTH OF IMAGE>
|
||||||
|
*
|
||||||
|
* leftPixel = pixels[i] & 0xF
|
||||||
|
* rightPixel = pixels[i] >> 4)
|
||||||
|
*
|
||||||
|
* leftPixel coordinates: (xCoord, yCoord)
|
||||||
|
* rightPixel coordinates: (xCoord + 1, yCoord)
|
||||||
|
* else if (bitDepth == 8)
|
||||||
|
* for (int i = 0; i < width * height; i++)
|
||||||
|
* xCoord = i % <WIDTH OF IMAGE>
|
||||||
|
* yCoord = i / <WIDTH OF IMAGE>
|
||||||
|
*
|
||||||
|
* pixel = pixels[i]
|
||||||
|
* pixel coordinates: (xCoord, yCoord)
|
||||||
|
*/
|
||||||
unsigned char *pixels;
|
unsigned char *pixels;
|
||||||
bool hasPalette;
|
bool hasPalette;
|
||||||
struct Palette palette;
|
struct Palette palette;
|
||||||
bool hasTransparency;
|
bool hasTransparency;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ReadImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors);
|
void ReadImage(char *path, int tilesWide, int bitDepth, int colsPerChunk, int rowsPerChunk, struct Image *image, bool invertColors);
|
||||||
uint32_t ReadNtrImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool scanFrontToBack);
|
uint32_t ReadNtrImage(char *path, int tilesWide, int bitDepth, int colsPerChunk, int rowsPerChunk, struct Image *image, bool invertColors, bool scanFrontToBack);
|
||||||
void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors);
|
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 metatileWidth, int metatileHeight, struct Image *image, bool invertColors, bool clobberSize, bool byteOrder, bool version101, bool sopc, uint32_t scanMode, uint32_t key);
|
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 FreeImage(struct Image *image);
|
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);
|
||||||
|
void ReadNtrCell(char *path, struct JsonToCellOptions *options);
|
||||||
|
void WriteNtrCell(char *path, struct JsonToCellOptions *options);
|
||||||
|
void WriteNtrScreen(char *path, struct JsonToScreenOptions *options);
|
||||||
|
void ReadNtrAnimation(char *path, struct JsonToAnimationOptions *options);
|
||||||
|
void WriteNtrAnimation(char *path, struct JsonToAnimationOptions *options);
|
||||||
|
|
||||||
#endif // GFX_H
|
#endif // GFX_H
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,10 @@ do { \
|
||||||
|
|
||||||
#endif // _MSC_VER
|
#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_DIFF(right, left) ((uintptr_t)(right) - (uintptr_t)(left))
|
||||||
|
|
||||||
#endif // GLOBAL_H
|
#endif // GLOBAL_H
|
||||||
|
|
|
||||||
|
|
@ -34,17 +34,17 @@ int msort_r(void * data, size_t count, size_t size, cmpfun cmp, void * buffer) {
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// Swap the two entries if the right one compares higher.
|
// Swap the two entries if the right one compares higher.
|
||||||
if (cmp(data, data + size) > 0) {
|
if (cmp(data, PTR_ADD(data, size)) > 0) {
|
||||||
memcpy(buffer, data, size);
|
memcpy(buffer, data, size);
|
||||||
memcpy(data, data + size, size);
|
memcpy(data, PTR_ADD(data, size), size);
|
||||||
memcpy(data + size, buffer, size);
|
memcpy(PTR_ADD(data, size), buffer, size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Merge sort out-of-place.
|
// Merge sort out-of-place.
|
||||||
leftPtr = data;
|
leftPtr = data;
|
||||||
leftEnd = rightPtr = data + count / 2 * size;
|
leftEnd = rightPtr = PTR_ADD(data, count / 2 * size);
|
||||||
rightEnd = data + count * size;
|
rightEnd = PTR_ADD(data, count * size);
|
||||||
|
|
||||||
// Sort the left half
|
// Sort the left half
|
||||||
if (!msort_r(leftPtr, count / 2, size, cmp, buffer))
|
if (!msort_r(leftPtr, count / 2, size, cmp, buffer))
|
||||||
|
|
@ -58,11 +58,11 @@ int msort_r(void * data, size_t count, size_t size, cmpfun cmp, void * buffer) {
|
||||||
i = 0;
|
i = 0;
|
||||||
do {
|
do {
|
||||||
if (cmp(leftPtr, rightPtr) <= 0) {
|
if (cmp(leftPtr, rightPtr) <= 0) {
|
||||||
memcpy(buffer + i * size, leftPtr, size);
|
memcpy(PTR_ADD(buffer, i * size), leftPtr, size);
|
||||||
leftPtr += size;
|
PTR_IADD(leftPtr, size);
|
||||||
} else {
|
} else {
|
||||||
memcpy(buffer + i * size, rightPtr, size);
|
memcpy(PTR_ADD(buffer, i * size), rightPtr, size);
|
||||||
rightPtr += size;
|
PTR_IADD(rightPtr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (++i < count && leftPtr < leftEnd && rightPtr < rightEnd);
|
} while (++i < count && leftPtr < leftEnd && rightPtr < rightEnd);
|
||||||
|
|
@ -70,10 +70,10 @@ int msort_r(void * data, size_t count, size_t size, cmpfun cmp, void * buffer) {
|
||||||
// Copy the remainder
|
// Copy the remainder
|
||||||
if (i < count) {
|
if (i < count) {
|
||||||
if (leftPtr < leftEnd) {
|
if (leftPtr < leftEnd) {
|
||||||
memcpy(buffer + i * size, leftPtr, leftEnd - leftPtr);
|
memcpy(PTR_ADD(buffer, i * size), leftPtr, PTR_DIFF(leftEnd, leftPtr));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy(buffer + i * size, rightPtr, rightEnd - rightPtr);
|
memcpy(PTR_ADD(buffer, i * size), rightPtr, PTR_DIFF(rightEnd, rightPtr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +163,7 @@ static void write_tree(unsigned char * dest, HuffNode_t * tree, int nitems, stru
|
||||||
if (currNode->header.isLeaf) {
|
if (currNode->header.isLeaf) {
|
||||||
dest[5 + i] = traversal[i].leaf.key;
|
dest[5 + i] = traversal[i].leaf.key;
|
||||||
} else {
|
} else {
|
||||||
dest[5 + i] = (((currNode->branch.right - traversal - i) / 2) - 1);
|
dest[5 + i] = (unsigned char)(((currNode->branch.right - traversal - i) / 2) - 1);
|
||||||
if (currNode->branch.left->header.isLeaf)
|
if (currNode->branch.left->header.isLeaf)
|
||||||
dest[5 + i] |= 0x80;
|
dest[5 + i] |= 0x80;
|
||||||
if (currNode->branch.right->header.isLeaf)
|
if (currNode->branch.right->header.isLeaf)
|
||||||
|
|
@ -194,8 +194,8 @@ static inline void read_32_le(unsigned char * src, int * srcPos, uint32_t * buff
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_bits(unsigned char * dest, int * destPos, struct BitEncoding * encoding, int value, uint32_t * buff, int * buffBits) {
|
static void write_bits(unsigned char * dest, int * destPos, struct BitEncoding * encoding, int value, uint32_t * buff, int * buffBits) {
|
||||||
int nbits = encoding[value].nbits;
|
int nbits = (int)encoding[value].nbits;
|
||||||
uint32_t bitstring = encoding[value].bitstring;
|
uint32_t bitstring = (uint32_t)encoding[value].bitstring;
|
||||||
|
|
||||||
if (*buffBits + nbits >= 32) {
|
if (*buffBits + nbits >= 32) {
|
||||||
int diff = *buffBits + nbits - 32;
|
int diff = *buffBits + nbits - 32;
|
||||||
|
|
|
||||||
640
tools/nitrogfx/json.c
Normal file
640
tools/nitrogfx/json.c
Normal file
|
|
@ -0,0 +1,640 @@
|
||||||
|
// Copyright (c) 2021-2023 red031000
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "cJSON.h"
|
||||||
|
#include "json.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static inline bool GetBool(cJSON * in)
|
||||||
|
{
|
||||||
|
if (!cJSON_IsBool(in))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return cJSON_IsTrue(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int GetInt(cJSON * in)
|
||||||
|
{
|
||||||
|
if (!cJSON_IsNumber(in))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return in->valueint;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *GetString(cJSON * in)
|
||||||
|
{
|
||||||
|
if (!cJSON_IsString(in))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return in->valuestring;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct JsonToCellOptions *ParseNCERJson(char *path)
|
||||||
|
{
|
||||||
|
int fileLength;
|
||||||
|
unsigned char *jsonString = ReadWholeFile(path, &fileLength);
|
||||||
|
|
||||||
|
cJSON *json = cJSON_Parse((const char *)jsonString);
|
||||||
|
|
||||||
|
struct JsonToCellOptions *options = malloc(sizeof(struct JsonToCellOptions));
|
||||||
|
|
||||||
|
if (json == NULL)
|
||||||
|
{
|
||||||
|
const char *errorPtr = cJSON_GetErrorPtr();
|
||||||
|
FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *labelBool = cJSON_GetObjectItemCaseSensitive(json, "labelEnabled");
|
||||||
|
cJSON *extended = cJSON_GetObjectItemCaseSensitive(json, "extended");
|
||||||
|
cJSON *cellCount = cJSON_GetObjectItemCaseSensitive(json, "cellCount");
|
||||||
|
cJSON *mappingType = cJSON_GetObjectItemCaseSensitive(json, "mappingType");
|
||||||
|
|
||||||
|
options->labelEnabled = GetBool(labelBool);
|
||||||
|
options->extended = GetBool(extended);
|
||||||
|
options->cellCount = GetInt(cellCount);
|
||||||
|
options->mappingType = GetInt(mappingType);
|
||||||
|
|
||||||
|
options->cells = malloc(sizeof(struct Cell *) * options->cellCount);
|
||||||
|
|
||||||
|
if (options->labelEnabled)
|
||||||
|
{
|
||||||
|
cJSON *labelCount = cJSON_GetObjectItemCaseSensitive(json, "labelCount");
|
||||||
|
options->labelCount = GetInt(labelCount);
|
||||||
|
options->labels = malloc(sizeof(char *) * options->labelCount);
|
||||||
|
|
||||||
|
cJSON *labels = cJSON_GetObjectItemCaseSensitive(json, "labels");
|
||||||
|
cJSON *label = NULL;
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
cJSON_ArrayForEach(label, labels)
|
||||||
|
{
|
||||||
|
char *labelString = GetString(label);
|
||||||
|
options->labels[j] = malloc(strlen(labelString) + 1);
|
||||||
|
strcpy(options->labels[j], labelString);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < options->cellCount; i++)
|
||||||
|
{
|
||||||
|
options->cells[i] = malloc(sizeof(struct Cell));
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
cJSON *cells = cJSON_GetObjectItemCaseSensitive(json, "cells");
|
||||||
|
cJSON *cell = NULL;
|
||||||
|
|
||||||
|
cJSON_ArrayForEach(cell, cells)
|
||||||
|
{
|
||||||
|
if (i > options->cellCount - 1)
|
||||||
|
FATAL_ERROR("Cell count is incorrect.\n");
|
||||||
|
|
||||||
|
cJSON *cellAttrs = cJSON_GetObjectItemCaseSensitive(cell, "cellAttrs");
|
||||||
|
|
||||||
|
cJSON *hFlip = cJSON_GetObjectItemCaseSensitive(cellAttrs, "hFlip");
|
||||||
|
cJSON *vFlip = cJSON_GetObjectItemCaseSensitive(cellAttrs, "vFlip");
|
||||||
|
cJSON *hvFlip = cJSON_GetObjectItemCaseSensitive(cellAttrs, "hvFlip");
|
||||||
|
|
||||||
|
options->cells[i]->attributes.hFlip = GetBool(hFlip);
|
||||||
|
options->cells[i]->attributes.vFlip = GetBool(vFlip);
|
||||||
|
options->cells[i]->attributes.hvFlip = GetBool(hvFlip);
|
||||||
|
|
||||||
|
cJSON *boundingRect = cJSON_GetObjectItemCaseSensitive(cellAttrs, "boundingRect");
|
||||||
|
|
||||||
|
options->cells[i]->attributes.boundingRect = GetBool(boundingRect);
|
||||||
|
|
||||||
|
cJSON *boundingSphereRadius = cJSON_GetObjectItemCaseSensitive(cellAttrs, "boundingSphereRadius");
|
||||||
|
|
||||||
|
options->cells[i]->attributes.boundingSphereRadius = GetInt(boundingSphereRadius);
|
||||||
|
|
||||||
|
if (options->extended)
|
||||||
|
{
|
||||||
|
cJSON *maxX = cJSON_GetObjectItemCaseSensitive(cell, "maxX");
|
||||||
|
cJSON *maxY = cJSON_GetObjectItemCaseSensitive(cell, "maxY");
|
||||||
|
cJSON *minX = cJSON_GetObjectItemCaseSensitive(cell, "minX");
|
||||||
|
cJSON *minY = cJSON_GetObjectItemCaseSensitive(cell, "minY");
|
||||||
|
|
||||||
|
options->cells[i]->maxX = (short)GetInt(maxX);
|
||||||
|
options->cells[i]->maxY = (short)GetInt(maxY);
|
||||||
|
options->cells[i]->minX = (short)GetInt(minX);
|
||||||
|
options->cells[i]->minY = (short)GetInt(minY);
|
||||||
|
}
|
||||||
|
//OAM data
|
||||||
|
cJSON *oamCount = cJSON_GetObjectItemCaseSensitive(cell, "oamCount");
|
||||||
|
|
||||||
|
options->cells[i]->oamCount = (short)GetInt(oamCount);
|
||||||
|
options->cells[i]->oam = malloc(sizeof(struct OAM) * options->cells[i]->oamCount);
|
||||||
|
|
||||||
|
cJSON *OAMArray = cJSON_GetObjectItemCaseSensitive(cell, "OAM");
|
||||||
|
cJSON *OAM = NULL;
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
cJSON_ArrayForEach(OAM, OAMArray)
|
||||||
|
{
|
||||||
|
if (j > options->cells[i]->oamCount - 1)
|
||||||
|
FATAL_ERROR("OAM count is incorrect.\n");
|
||||||
|
|
||||||
|
//Attr0
|
||||||
|
cJSON *Attr0 = cJSON_GetObjectItemCaseSensitive(OAM, "Attr0");
|
||||||
|
|
||||||
|
cJSON *YCoordinate = cJSON_GetObjectItemCaseSensitive(Attr0, "YCoordinate");
|
||||||
|
cJSON *Rotation = cJSON_GetObjectItemCaseSensitive(Attr0, "Rotation");
|
||||||
|
cJSON *SizeDisable = cJSON_GetObjectItemCaseSensitive(Attr0, "SizeDisable");
|
||||||
|
cJSON *Mode = cJSON_GetObjectItemCaseSensitive(Attr0, "Mode");
|
||||||
|
cJSON *Mosaic = cJSON_GetObjectItemCaseSensitive(Attr0, "Mosaic");
|
||||||
|
cJSON *Colours = cJSON_GetObjectItemCaseSensitive(Attr0, "Colours");
|
||||||
|
cJSON *Shape = cJSON_GetObjectItemCaseSensitive(Attr0, "Shape");
|
||||||
|
|
||||||
|
options->cells[i]->oam[j].attr0.YCoordinate = GetInt(YCoordinate);
|
||||||
|
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);
|
||||||
|
options->cells[i]->oam[j].attr0.Mosaic = GetBool(Mosaic);
|
||||||
|
options->cells[i]->oam[j].attr0.Colours = GetInt(Colours);
|
||||||
|
options->cells[i]->oam[j].attr0.Shape = GetInt(Shape);
|
||||||
|
|
||||||
|
//Attr1
|
||||||
|
cJSON *Attr1 = cJSON_GetObjectItemCaseSensitive(OAM, "Attr1");
|
||||||
|
|
||||||
|
cJSON *XCoordinate = cJSON_GetObjectItemCaseSensitive(Attr1, "XCoordinate");
|
||||||
|
cJSON *RotationScaling = cJSON_GetObjectItemCaseSensitive(Attr1, "RotationScaling");
|
||||||
|
cJSON *Size = cJSON_GetObjectItemCaseSensitive(Attr1, "Size");
|
||||||
|
|
||||||
|
options->cells[i]->oam[j].attr1.XCoordinate = GetInt(XCoordinate);
|
||||||
|
options->cells[i]->oam[j].attr1.RotationScaling = GetInt(RotationScaling);
|
||||||
|
options->cells[i]->oam[j].attr1.Size = GetInt(Size);
|
||||||
|
|
||||||
|
//Attr2
|
||||||
|
cJSON *Attr2 = cJSON_GetObjectItemCaseSensitive(OAM, "Attr2");
|
||||||
|
|
||||||
|
cJSON *CharName = cJSON_GetObjectItemCaseSensitive(Attr2, "CharName");
|
||||||
|
cJSON *Priority = cJSON_GetObjectItemCaseSensitive(Attr2, "Priority");
|
||||||
|
cJSON *Palette = cJSON_GetObjectItemCaseSensitive(Attr2, "Palette");
|
||||||
|
|
||||||
|
options->cells[i]->oam[j].attr2.CharName = GetInt(CharName);
|
||||||
|
options->cells[i]->oam[j].attr2.Priority = GetInt(Priority);
|
||||||
|
options->cells[i]->oam[j].attr2.Palette = GetInt(Palette);
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
free(jsonString);
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *GetNCERJson(struct JsonToCellOptions *options)
|
||||||
|
{
|
||||||
|
cJSON *ncer = cJSON_CreateObject();
|
||||||
|
|
||||||
|
cJSON_AddBoolToObject(ncer, "labelEnabled", options->labelEnabled);
|
||||||
|
cJSON_AddBoolToObject(ncer, "extended", options->extended);
|
||||||
|
cJSON_AddNumberToObject(ncer, "cellCount", options->cellCount);
|
||||||
|
cJSON_AddNumberToObject(ncer, "mappingType", options->mappingType);
|
||||||
|
|
||||||
|
cJSON *cells = cJSON_AddArrayToObject(ncer, "cells");
|
||||||
|
|
||||||
|
for (int i = 0; i < options->cellCount; i++)
|
||||||
|
{
|
||||||
|
cJSON *cell = cJSON_CreateObject();
|
||||||
|
|
||||||
|
cJSON *cellAttrs = cJSON_AddObjectToObject(cell, "cellAttrs");
|
||||||
|
|
||||||
|
cJSON_AddBoolToObject(cellAttrs, "hFlip", options->cells[i]->attributes.hFlip);
|
||||||
|
cJSON_AddBoolToObject(cellAttrs, "vFlip", options->cells[i]->attributes.vFlip);
|
||||||
|
cJSON_AddBoolToObject(cellAttrs, "hvFlip", options->cells[i]->attributes.hvFlip);
|
||||||
|
cJSON_AddBoolToObject(cellAttrs, "boundingRect", options->cells[i]->attributes.boundingRect);
|
||||||
|
cJSON_AddNumberToObject(cellAttrs, "boundingSphereRadius", options->cells[i]->attributes.boundingSphereRadius);
|
||||||
|
|
||||||
|
if (options->extended)
|
||||||
|
{
|
||||||
|
cJSON_AddNumberToObject(cell, "maxX", options->cells[i]->maxX);
|
||||||
|
cJSON_AddNumberToObject(cell, "maxY", options->cells[i]->maxY);
|
||||||
|
cJSON_AddNumberToObject(cell, "minX", options->cells[i]->minX);
|
||||||
|
cJSON_AddNumberToObject(cell, "minY", options->cells[i]->minY);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(cell, "oamCount", options->cells[i]->oamCount);
|
||||||
|
|
||||||
|
cJSON *OAMArray = cJSON_AddArrayToObject(cell, "OAM");
|
||||||
|
|
||||||
|
for (int j = 0; j < options->cells[i]->oamCount; j++)
|
||||||
|
{
|
||||||
|
cJSON *OAM = cJSON_CreateObject();
|
||||||
|
|
||||||
|
cJSON *Attr0 = cJSON_AddObjectToObject(OAM, "Attr0");
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(Attr0, "YCoordinate", options->cells[i]->oam[j].attr0.YCoordinate);
|
||||||
|
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);
|
||||||
|
cJSON_AddBoolToObject(Attr0, "Mosaic", options->cells[i]->oam[j].attr0.Mosaic);
|
||||||
|
cJSON_AddNumberToObject(Attr0, "Colours", options->cells[i]->oam[j].attr0.Colours);
|
||||||
|
cJSON_AddNumberToObject(Attr0, "Shape", options->cells[i]->oam[j].attr0.Shape);
|
||||||
|
|
||||||
|
cJSON *Attr1 = cJSON_AddObjectToObject(OAM, "Attr1");
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(Attr1, "XCoordinate", options->cells[i]->oam[j].attr1.XCoordinate);
|
||||||
|
cJSON_AddNumberToObject(Attr1, "RotationScaling", options->cells[i]->oam[j].attr1.RotationScaling);
|
||||||
|
cJSON_AddNumberToObject(Attr1, "Size", options->cells[i]->oam[j].attr1.Size);
|
||||||
|
|
||||||
|
cJSON *Attr2 = cJSON_AddObjectToObject(OAM, "Attr2");
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(Attr2, "CharName", options->cells[i]->oam[j].attr2.CharName);
|
||||||
|
cJSON_AddNumberToObject(Attr2, "Priority", options->cells[i]->oam[j].attr2.Priority);
|
||||||
|
cJSON_AddNumberToObject(Attr2, "Palette", options->cells[i]->oam[j].attr2.Palette);
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(OAMArray, OAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(cells, cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->labelEnabled)
|
||||||
|
{
|
||||||
|
cJSON *labels = cJSON_CreateStringArray((const char * const*)options->labels, options->labelCount);
|
||||||
|
cJSON_AddItemToObject(ncer, "labels", labels);
|
||||||
|
cJSON_AddNumberToObject(ncer, "labelCount", options->labelCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *jsonString = cJSON_Print(ncer);
|
||||||
|
cJSON_Delete(ncer);
|
||||||
|
return jsonString;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct JsonToScreenOptions *ParseNSCRJson(char *path)
|
||||||
|
{
|
||||||
|
int fileLength;
|
||||||
|
unsigned char *jsonString = ReadWholeFile(path, &fileLength);
|
||||||
|
|
||||||
|
cJSON *json = cJSON_Parse((const char *)jsonString);
|
||||||
|
|
||||||
|
struct JsonToScreenOptions *options = malloc(sizeof(struct JsonToScreenOptions));
|
||||||
|
|
||||||
|
if (json == NULL)
|
||||||
|
{
|
||||||
|
const char *errorPtr = cJSON_GetErrorPtr();
|
||||||
|
FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *Height = cJSON_GetObjectItemCaseSensitive(json, "height");
|
||||||
|
cJSON *Width = cJSON_GetObjectItemCaseSensitive(json, "width");
|
||||||
|
|
||||||
|
options->height = GetInt(Height);
|
||||||
|
options->width = GetInt(Width);
|
||||||
|
|
||||||
|
options->data = malloc(sizeof(unsigned short) * options->height * options->width);
|
||||||
|
|
||||||
|
cJSON *layer = NULL;
|
||||||
|
cJSON *layers = cJSON_GetObjectItemCaseSensitive(json, "layers");
|
||||||
|
int palette = 0;
|
||||||
|
cJSON *tilesets = cJSON_GetObjectItemCaseSensitive(json, "tilesets");
|
||||||
|
int tilesetSize = 0;
|
||||||
|
if (cJSON_GetArraySize(tilesets) != 1)
|
||||||
|
{
|
||||||
|
cJSON *tileset = cJSON_GetArrayItem(tilesets, 1);
|
||||||
|
cJSON *firstGid = cJSON_GetObjectItemCaseSensitive(tileset, "firstgid");
|
||||||
|
tilesetSize = GetInt(firstGid) - 1;
|
||||||
|
if (tilesetSize <= 1)
|
||||||
|
FATAL_ERROR("Wrong tileset index (tileset 0 should be added first)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_ArrayForEach(layer, layers)
|
||||||
|
{
|
||||||
|
cJSON *tile = NULL;
|
||||||
|
cJSON *data = cJSON_GetObjectItemCaseSensitive(layer, "data");
|
||||||
|
int i = 0;
|
||||||
|
cJSON_ArrayForEach(tile, data)
|
||||||
|
{
|
||||||
|
int tileInt = GetInt(tile) - 1;
|
||||||
|
if (tileInt != -1)
|
||||||
|
{
|
||||||
|
if (tilesetSize != 0)
|
||||||
|
{
|
||||||
|
palette = tileInt / tilesetSize;
|
||||||
|
tileInt %= tilesetSize;
|
||||||
|
}
|
||||||
|
bool vFlip = tileInt >> 30;
|
||||||
|
bool hFlip = tileInt >> 31;
|
||||||
|
tileInt |= vFlip << 11;
|
||||||
|
tileInt |= hFlip << 10;
|
||||||
|
tileInt |= palette << 12;
|
||||||
|
options->data[i] = (short) (tileInt & 0xFFFF);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
free(jsonString);
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct JsonToAnimationOptions *ParseNANRJson(char *path)
|
||||||
|
{
|
||||||
|
int filelength;
|
||||||
|
unsigned char *jsonString = ReadWholeFile(path, &filelength);
|
||||||
|
|
||||||
|
cJSON *json = cJSON_Parse((const char *)jsonString);
|
||||||
|
|
||||||
|
struct JsonToAnimationOptions *options = malloc(sizeof(struct JsonToAnimationOptions));
|
||||||
|
|
||||||
|
if (json == NULL)
|
||||||
|
{
|
||||||
|
const char *errorPtr = cJSON_GetErrorPtr();
|
||||||
|
FATAL_ERROR("Error in line \"%s\"\n", errorPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *sequenceCount = cJSON_GetObjectItemCaseSensitive(json, "sequenceCount");
|
||||||
|
cJSON *frameCount = cJSON_GetObjectItemCaseSensitive(json, "frameCount");
|
||||||
|
|
||||||
|
options->sequenceCount = GetInt(sequenceCount);
|
||||||
|
options->frameCount = GetInt(frameCount);
|
||||||
|
|
||||||
|
options->sequenceData = malloc(sizeof(struct SequenceData *) * options->sequenceCount);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < options->sequenceCount; i++)
|
||||||
|
{
|
||||||
|
options->sequenceData[i] = malloc(sizeof(struct SequenceData));
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *sequence = NULL;
|
||||||
|
cJSON *sequences = cJSON_GetObjectItemCaseSensitive(json, "sequences");
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
cJSON_ArrayForEach(sequence, sequences)
|
||||||
|
{
|
||||||
|
if (i > options->sequenceCount - 1)
|
||||||
|
FATAL_ERROR("Sequence count is incorrect.\n");
|
||||||
|
|
||||||
|
cJSON *frameCount = cJSON_GetObjectItemCaseSensitive(sequence, "frameCount");
|
||||||
|
cJSON *loopStartFrame = cJSON_GetObjectItemCaseSensitive(sequence, "loopStartFrame");
|
||||||
|
cJSON *animationElement = cJSON_GetObjectItemCaseSensitive(sequence, "animationElement");
|
||||||
|
cJSON *animationType = cJSON_GetObjectItemCaseSensitive(sequence, "animationType");
|
||||||
|
cJSON *playbackMode = cJSON_GetObjectItemCaseSensitive(sequence, "playbackMode");
|
||||||
|
|
||||||
|
options->sequenceData[i]->frameCount = GetInt(frameCount);
|
||||||
|
options->sequenceData[i]->loopStartFrame = GetInt(loopStartFrame);
|
||||||
|
options->sequenceData[i]->animationElement = GetInt(animationElement);
|
||||||
|
options->sequenceData[i]->animationType = GetInt(animationType);
|
||||||
|
options->sequenceData[i]->playbackMode = GetInt(playbackMode);
|
||||||
|
|
||||||
|
options->sequenceData[i]->frameData = malloc(sizeof(struct FrameData *) * options->sequenceData[i]->frameCount);
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < options->sequenceData[i]->frameCount; j++)
|
||||||
|
{
|
||||||
|
options->sequenceData[i]->frameData[j] = malloc(sizeof(struct FrameData));
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
cJSON *frame = NULL;
|
||||||
|
cJSON *frameData = cJSON_GetObjectItemCaseSensitive(sequence, "frameData");
|
||||||
|
|
||||||
|
cJSON_ArrayForEach(frame, frameData)
|
||||||
|
{
|
||||||
|
if (j > options->sequenceData[i]->frameCount - 1)
|
||||||
|
FATAL_ERROR("Sequence frame count is incorrect.\n");
|
||||||
|
|
||||||
|
cJSON *frameDelay = cJSON_GetObjectItemCaseSensitive(frame, "frameDelay");
|
||||||
|
cJSON *resultId = cJSON_GetObjectItemCaseSensitive(frame, "resultId");
|
||||||
|
|
||||||
|
options->sequenceData[i]->frameData[j]->frameDelay = GetInt(frameDelay);
|
||||||
|
options->sequenceData[i]->frameData[j]->resultId = GetInt(resultId);
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo implement extended attributes
|
||||||
|
|
||||||
|
cJSON *resultCount = cJSON_GetObjectItemCaseSensitive(json, "resultCount");
|
||||||
|
|
||||||
|
options->resultCount = GetInt(resultCount);
|
||||||
|
|
||||||
|
options->animationResults = malloc(sizeof(struct AnimationResults *) * options->resultCount);
|
||||||
|
|
||||||
|
for (i = 0; i < options->resultCount; i++)
|
||||||
|
{
|
||||||
|
options->animationResults[i] = malloc(sizeof(struct AnimationResults));
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
cJSON *animationResult = NULL;
|
||||||
|
cJSON *animationResults = cJSON_GetObjectItemCaseSensitive(json, "animationResults");
|
||||||
|
cJSON_ArrayForEach(animationResult, animationResults)
|
||||||
|
{
|
||||||
|
if (i > options->resultCount - 1)
|
||||||
|
FATAL_ERROR("Frame count is incorrect.\n");
|
||||||
|
|
||||||
|
cJSON *resultType = cJSON_GetObjectItemCaseSensitive(animationResult, "resultType");
|
||||||
|
options->animationResults[i]->resultType = GetInt(resultType);
|
||||||
|
switch (options->animationResults[i]->resultType) {
|
||||||
|
case 0: { //index
|
||||||
|
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||||
|
options->animationResults[i]->index = GetInt(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1: { //SRT
|
||||||
|
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||||
|
cJSON *rotation = cJSON_GetObjectItemCaseSensitive(animationResult, "rotation");
|
||||||
|
cJSON *scaleX = cJSON_GetObjectItemCaseSensitive(animationResult, "scaleX");
|
||||||
|
cJSON *scaleY = cJSON_GetObjectItemCaseSensitive(animationResult, "scaleY");
|
||||||
|
cJSON *positionX = cJSON_GetObjectItemCaseSensitive(animationResult, "positionX");
|
||||||
|
cJSON *positionY = cJSON_GetObjectItemCaseSensitive(animationResult, "positionY");
|
||||||
|
|
||||||
|
options->animationResults[i]->dataSrt.index = GetInt(index);
|
||||||
|
options->animationResults[i]->dataSrt.rotation = GetInt(rotation);
|
||||||
|
options->animationResults[i]->dataSrt.scaleX = GetInt(scaleX);
|
||||||
|
options->animationResults[i]->dataSrt.scaleY = GetInt(scaleY);
|
||||||
|
options->animationResults[i]->dataSrt.positionX = GetInt(positionX);
|
||||||
|
options->animationResults[i]->dataSrt.positionY = GetInt(positionY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2: { //T
|
||||||
|
cJSON *index = cJSON_GetObjectItemCaseSensitive(animationResult, "index");
|
||||||
|
//cJSON *rotation = cJSON_GetObjectItemCaseSensitive(animationResult, "rotation");
|
||||||
|
cJSON *positionX = cJSON_GetObjectItemCaseSensitive(animationResult, "positionX");
|
||||||
|
cJSON *positionY = cJSON_GetObjectItemCaseSensitive(animationResult, "positionY");
|
||||||
|
|
||||||
|
options->animationResults[i]->dataT.index = GetInt(index);
|
||||||
|
//options->animationResults[i]->dataSrt.rotation = GetInt(rotation);
|
||||||
|
options->animationResults[i]->dataT.positionX = GetInt(positionX);
|
||||||
|
options->animationResults[i]->dataT.positionY = GetInt(positionY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *labelBool = cJSON_GetObjectItemCaseSensitive(json, "labelEnabled");
|
||||||
|
options->labelEnabled = GetBool(labelBool);
|
||||||
|
|
||||||
|
if (options->labelEnabled)
|
||||||
|
{
|
||||||
|
cJSON *labelCount = cJSON_GetObjectItemCaseSensitive(json, "labelCount");
|
||||||
|
options->labelCount = GetInt(labelCount);
|
||||||
|
options->labels = malloc(sizeof(char *) * options->labelCount);
|
||||||
|
|
||||||
|
cJSON *labels = cJSON_GetObjectItemCaseSensitive(json, "labels");
|
||||||
|
cJSON *label = NULL;
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
cJSON_ArrayForEach(label, labels)
|
||||||
|
{
|
||||||
|
char *labelString = GetString(label);
|
||||||
|
options->labels[j] = malloc(strlen(labelString) + 1);
|
||||||
|
strcpy(options->labels[j], labelString);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
free(jsonString);
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *GetNANRJson(struct JsonToAnimationOptions *options)
|
||||||
|
{
|
||||||
|
cJSON *nanr = cJSON_CreateObject();
|
||||||
|
|
||||||
|
cJSON_AddBoolToObject(nanr, "labelEnabled", options->labelEnabled);
|
||||||
|
cJSON_AddNumberToObject(nanr, "sequenceCount", options->sequenceCount);
|
||||||
|
cJSON_AddNumberToObject(nanr, "frameCount", options->frameCount);
|
||||||
|
|
||||||
|
cJSON *sequences = cJSON_AddArrayToObject(nanr, "sequences");
|
||||||
|
|
||||||
|
for (int i = 0; i < options->sequenceCount; i++)
|
||||||
|
{
|
||||||
|
cJSON *sequence = cJSON_CreateObject();
|
||||||
|
cJSON_AddNumberToObject(sequence, "frameCount", options->sequenceData[i]->frameCount);
|
||||||
|
cJSON_AddNumberToObject(sequence, "loopStartFrame", options->sequenceData[i]->loopStartFrame);
|
||||||
|
cJSON_AddNumberToObject(sequence, "animationElement", options->sequenceData[i]->animationElement);
|
||||||
|
cJSON_AddNumberToObject(sequence, "animationType", options->sequenceData[i]->animationType);
|
||||||
|
cJSON_AddNumberToObject(sequence, "playbackMode", options->sequenceData[i]->playbackMode);
|
||||||
|
|
||||||
|
cJSON *frameData = cJSON_AddArrayToObject(sequence, "frameData");
|
||||||
|
|
||||||
|
for (int j = 0; j < options->sequenceData[i]->frameCount; j++)
|
||||||
|
{
|
||||||
|
cJSON *frame = cJSON_CreateObject();
|
||||||
|
cJSON_AddNumberToObject(frame, "frameDelay", options->sequenceData[i]->frameData[j]->frameDelay);
|
||||||
|
cJSON_AddNumberToObject(frame, "resultId", options->sequenceData[i]->frameData[j]->resultId);
|
||||||
|
cJSON_AddItemToArray(frameData, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(sequences, sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *animationResults = cJSON_AddArrayToObject(nanr, "animationResults");
|
||||||
|
|
||||||
|
for (int i = 0; i < options->resultCount; i++)
|
||||||
|
{
|
||||||
|
cJSON *animationResult = cJSON_CreateObject();
|
||||||
|
cJSON_AddNumberToObject(animationResult, "resultType", options->animationResults[i]->resultType);
|
||||||
|
|
||||||
|
switch (options->animationResults[i]->resultType)
|
||||||
|
{
|
||||||
|
case 0: //index
|
||||||
|
cJSON_AddNumberToObject(animationResult, "index", options->animationResults[i]->index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: //SRT
|
||||||
|
cJSON_AddNumberToObject(animationResult, "index", options->animationResults[i]->dataSrt.index);
|
||||||
|
cJSON_AddNumberToObject(animationResult, "rotation", options->animationResults[i]->dataSrt.rotation);
|
||||||
|
cJSON_AddNumberToObject(animationResult, "scaleX", options->animationResults[i]->dataSrt.scaleX);
|
||||||
|
cJSON_AddNumberToObject(animationResult, "scaleY", options->animationResults[i]->dataSrt.scaleY);
|
||||||
|
cJSON_AddNumberToObject(animationResult, "positionX", options->animationResults[i]->dataSrt.positionX);
|
||||||
|
cJSON_AddNumberToObject(animationResult, "positionY", options->animationResults[i]->dataSrt.positionY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: //T
|
||||||
|
cJSON_AddNumberToObject(animationResult, "index", options->animationResults[i]->dataT.index);
|
||||||
|
cJSON_AddNumberToObject(animationResult, "positionX", options->animationResults[i]->dataT.positionX);
|
||||||
|
cJSON_AddNumberToObject(animationResult, "positionY", options->animationResults[i]->dataT.positionY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(animationResults, animationResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(nanr, "resultCount", options->resultCount);
|
||||||
|
|
||||||
|
if (options->labelEnabled)
|
||||||
|
{
|
||||||
|
cJSON *labels = cJSON_CreateStringArray((const char * const*)options->labels, options->labelCount);
|
||||||
|
cJSON_AddItemToObject(nanr, "labels", labels);
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(nanr, "labelCount", options->labelCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *jsonString = cJSON_Print(nanr);
|
||||||
|
cJSON_Delete(nanr);
|
||||||
|
return jsonString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeNCERCell(struct JsonToCellOptions *options)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < options->cellCount; i++)
|
||||||
|
{
|
||||||
|
free(options->cells[i]->oam);
|
||||||
|
free(options->cells[i]);
|
||||||
|
}
|
||||||
|
if (options->labelEnabled)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < options->labelCount; j++)
|
||||||
|
{
|
||||||
|
free(options->labels[j]);
|
||||||
|
}
|
||||||
|
free(options->labels);
|
||||||
|
}
|
||||||
|
free(options->cells);
|
||||||
|
free(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeNSCRScreen(struct JsonToScreenOptions *options)
|
||||||
|
{
|
||||||
|
free(options->data);
|
||||||
|
free(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FreeNANRAnimation(struct JsonToAnimationOptions *options)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < options->sequenceCount; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < options->sequenceData[i]->frameCount; j++)
|
||||||
|
{
|
||||||
|
free(options->sequenceData[i]->frameData[j]);
|
||||||
|
}
|
||||||
|
free(options->sequenceData[i]->frameData);
|
||||||
|
free(options->sequenceData[i]);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < options->resultCount; i++)
|
||||||
|
{
|
||||||
|
free(options->animationResults[i]);
|
||||||
|
}
|
||||||
|
if (options->labelEnabled)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < options->labelCount; j++)
|
||||||
|
{
|
||||||
|
free(options->labels[j]);
|
||||||
|
}
|
||||||
|
free(options->labels);
|
||||||
|
}
|
||||||
|
free(options->sequenceData);
|
||||||
|
free(options->animationResults);
|
||||||
|
free(options);
|
||||||
|
}
|
||||||
17
tools/nitrogfx/json.h
Normal file
17
tools/nitrogfx/json.h
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) 2021-2023 red031000
|
||||||
|
|
||||||
|
#ifndef JSON_H
|
||||||
|
#define JSON_H
|
||||||
|
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
struct JsonToCellOptions *ParseNCERJson(char *path);
|
||||||
|
char *GetNCERJson(struct JsonToCellOptions *options);
|
||||||
|
struct JsonToScreenOptions *ParseNSCRJson(char *path);
|
||||||
|
struct JsonToAnimationOptions *ParseNANRJson(char *path);
|
||||||
|
char *GetNANRJson(struct JsonToAnimationOptions *options);
|
||||||
|
void FreeNCERCell(struct JsonToCellOptions *options);
|
||||||
|
void FreeNSCRScreen(struct JsonToScreenOptions *options);
|
||||||
|
void FreeNANRAnimation(struct JsonToAnimationOptions *options);
|
||||||
|
|
||||||
|
#endif //JSON_H
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// Copyright (c) 2015 YamaArashi
|
// Copyright (c) 2015 YamaArashi, 2021-2023 red031000
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include "rl.h"
|
#include "rl.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "huff.h"
|
#include "huff.h"
|
||||||
|
#include "json.h"
|
||||||
|
|
||||||
struct CommandHandler
|
struct CommandHandler
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +37,7 @@ void ConvertGbaToPng(char *inputPath, char *outputPath, struct GbaToPngOptions *
|
||||||
image.hasPalette = false;
|
image.hasPalette = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadImage(inputPath, options->width, options->bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette);
|
ReadImage(inputPath, options->width, options->bitDepth, options->colsPerChunk, options->rowsPerChunk, &image, !image.hasPalette);
|
||||||
|
|
||||||
image.hasTransparency = options->hasTransparency;
|
image.hasTransparency = options->hasTransparency;
|
||||||
|
|
||||||
|
|
@ -81,17 +82,18 @@ void ConvertNtrToPng(char *inputPath, char *outputPath, struct NtrToPngOptions *
|
||||||
image.hasPalette = false;
|
image.hasPalette = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t key = ReadNtrImage(inputPath, options->width, 0, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette, options->scanFrontToBack);
|
uint32_t key = ReadNtrImage(inputPath, options->width, 0, options->colsPerChunk, options->rowsPerChunk, &image, !image.hasPalette, options->scanFrontToBack);
|
||||||
|
|
||||||
if (key)
|
if (key)
|
||||||
{
|
{
|
||||||
char string[strlen(outputPath) + 5];
|
char* string = malloc(strlen(outputPath) + 5);
|
||||||
sprintf(string, "%s.key", outputPath);
|
sprintf(string, "%s.key", outputPath);
|
||||||
FILE *fp = fopen(string, "wb");
|
FILE *fp = fopen(string, "wb");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
FATAL_ERROR("Failed to open key file for writing.\n");
|
FATAL_ERROR("Failed to open key file for writing.\n");
|
||||||
fwrite(&key, 4, 1, fp);
|
fwrite(&key, 4, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
image.hasTransparency = options->hasTransparency;
|
image.hasTransparency = options->hasTransparency;
|
||||||
|
|
@ -109,7 +111,7 @@ void ConvertPngToGba(char *inputPath, char *outputPath, struct PngToGbaOptions *
|
||||||
|
|
||||||
ReadPng(inputPath, &image);
|
ReadPng(inputPath, &image);
|
||||||
|
|
||||||
WriteImage(outputPath, options->numTiles, options->bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette);
|
WriteImage(outputPath, options->numTiles, options->bitDepth, options->colsPerChunk, options->rowsPerChunk, &image, !image.hasPalette);
|
||||||
|
|
||||||
FreeImage(&image);
|
FreeImage(&image);
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +139,6 @@ void ConvertPngToNtr(char *inputPath, char *outputPath, struct PngToNtrOptions *
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
struct Image image;
|
struct Image image;
|
||||||
|
|
||||||
image.bitDepth = options->bitDepth;
|
image.bitDepth = options->bitDepth;
|
||||||
|
|
@ -147,7 +148,7 @@ void ConvertPngToNtr(char *inputPath, char *outputPath, struct PngToNtrOptions *
|
||||||
uint32_t key = 0;
|
uint32_t key = 0;
|
||||||
if (options->scanMode)
|
if (options->scanMode)
|
||||||
{
|
{
|
||||||
char string[strlen(inputPath) + 5];
|
char* string = malloc(strlen(inputPath) + 5);
|
||||||
sprintf(string, "%s.key", inputPath);
|
sprintf(string, "%s.key", inputPath);
|
||||||
FILE *fp2 = fopen(string, "rb");
|
FILE *fp2 = fopen(string, "rb");
|
||||||
if (fp2 == NULL)
|
if (fp2 == NULL)
|
||||||
|
|
@ -156,9 +157,12 @@ void ConvertPngToNtr(char *inputPath, char *outputPath, struct PngToNtrOptions *
|
||||||
if (count != 1)
|
if (count != 1)
|
||||||
FATAL_ERROR("Not a valid key file.\n");
|
FATAL_ERROR("Not a valid key file.\n");
|
||||||
fclose(fp2);
|
fclose(fp2);
|
||||||
|
free(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteNtrImage(outputPath, options->numTiles, image.bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette, options->clobberSize, options->byteOrder, options->version101, options->sopc, options->scanMode, key);
|
WriteNtrImage(outputPath, options->numTiles, image.bitDepth, options->colsPerChunk, options->rowsPerChunk,
|
||||||
|
&image, !image.hasPalette, options->clobberSize, options->byteOrder, options->version101,
|
||||||
|
options->sopc, options->vramTransfer, options->scanMode, options->mappingType, key, options->wrongSize);
|
||||||
|
|
||||||
FreeImage(&image);
|
FreeImage(&image);
|
||||||
}
|
}
|
||||||
|
|
@ -174,8 +178,8 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
options.bitDepth = 4;
|
options.bitDepth = 4;
|
||||||
options.hasTransparency = false;
|
options.hasTransparency = false;
|
||||||
options.width = 1;
|
options.width = 1;
|
||||||
options.metatileWidth = 1;
|
options.colsPerChunk = 1;
|
||||||
options.metatileHeight = 1;
|
options.rowsPerChunk = 1;
|
||||||
|
|
||||||
for (int i = 3; i < argc; i++)
|
for (int i = 3; i < argc; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -207,31 +211,31 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
if (options.width < 1)
|
if (options.width < 1)
|
||||||
FATAL_ERROR("Width must be positive.\n");
|
FATAL_ERROR("Width must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-mwidth") == 0)
|
else if (strcmp(option, "-mwidth") == 0 || strcmp(option, "-cpc") == 0)
|
||||||
{
|
{
|
||||||
if (i + 1 >= argc)
|
if (i + 1 >= argc)
|
||||||
FATAL_ERROR("No metatile width value following \"-mwidth\".\n");
|
FATAL_ERROR("No columns per chunk value following \"%s\".\n", option);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!ParseNumber(argv[i], NULL, 10, &options.metatileWidth))
|
if (!ParseNumber(argv[i], NULL, 10, &options.colsPerChunk))
|
||||||
FATAL_ERROR("Failed to parse metatile width.\n");
|
FATAL_ERROR("Failed to parse columns per chunk.\n");
|
||||||
|
|
||||||
if (options.metatileWidth < 1)
|
if (options.colsPerChunk < 1)
|
||||||
FATAL_ERROR("metatile width must be positive.\n");
|
FATAL_ERROR("columns per chunk must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-mheight") == 0)
|
else if (strcmp(option, "-mheight") == 0 || strcmp(option, "-rpc") == 0)
|
||||||
{
|
{
|
||||||
if (i + 1 >= argc)
|
if (i + 1 >= argc)
|
||||||
FATAL_ERROR("No metatile height value following \"-mheight\".\n");
|
FATAL_ERROR("No rows per chunk value following \"%s\".\n", option);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!ParseNumber(argv[i], NULL, 10, &options.metatileHeight))
|
if (!ParseNumber(argv[i], NULL, 10, &options.rowsPerChunk))
|
||||||
FATAL_ERROR("Failed to parse metatile height.\n");
|
FATAL_ERROR("Failed to parse rows per chunk.\n");
|
||||||
|
|
||||||
if (options.metatileHeight < 1)
|
if (options.rowsPerChunk < 1)
|
||||||
FATAL_ERROR("metatile height must be positive.\n");
|
FATAL_ERROR("rows per chunk must be positive.\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -239,8 +243,8 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.metatileWidth > options.width)
|
if (options.colsPerChunk > options.width)
|
||||||
options.width = options.metatileWidth;
|
options.width = options.colsPerChunk;
|
||||||
|
|
||||||
ConvertGbaToPng(inputPath, outputPath, &options);
|
ConvertGbaToPng(inputPath, outputPath, &options);
|
||||||
}
|
}
|
||||||
|
|
@ -251,8 +255,8 @@ void HandleNtrToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
options.paletteFilePath = NULL;
|
options.paletteFilePath = NULL;
|
||||||
options.hasTransparency = false;
|
options.hasTransparency = false;
|
||||||
options.width = 0;
|
options.width = 0;
|
||||||
options.metatileWidth = 1;
|
options.colsPerChunk = 1;
|
||||||
options.metatileHeight = 1;
|
options.rowsPerChunk = 1;
|
||||||
options.palIndex = 1;
|
options.palIndex = 1;
|
||||||
options.scanFrontToBack = false;
|
options.scanFrontToBack = false;
|
||||||
options.handleEmpty = false;
|
options.handleEmpty = false;
|
||||||
|
|
@ -300,31 +304,31 @@ void HandleNtrToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
if (options.width < 1)
|
if (options.width < 1)
|
||||||
FATAL_ERROR("Width must be positive.\n");
|
FATAL_ERROR("Width must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-mwidth") == 0)
|
else if (strcmp(option, "-mwidth") == 0 || strcmp(option, "-cpc") == 0)
|
||||||
{
|
{
|
||||||
if (i + 1 >= argc)
|
if (i + 1 >= argc)
|
||||||
FATAL_ERROR("No metatile width value following \"-mwidth\".\n");
|
FATAL_ERROR("No columns per chunk value following \"%s\".\n", option);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!ParseNumber(argv[i], NULL, 10, &options.metatileWidth))
|
if (!ParseNumber(argv[i], NULL, 10, &options.colsPerChunk))
|
||||||
FATAL_ERROR("Failed to parse metatile width.\n");
|
FATAL_ERROR("Failed to parse columns per chunk.\n");
|
||||||
|
|
||||||
if (options.metatileWidth < 1)
|
if (options.colsPerChunk < 1)
|
||||||
FATAL_ERROR("metatile width must be positive.\n");
|
FATAL_ERROR("columns per chunk must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-mheight") == 0)
|
else if (strcmp(option, "-mheight") == 0 || strcmp(option, "-rpc") == 0)
|
||||||
{
|
{
|
||||||
if (i + 1 >= argc)
|
if (i + 1 >= argc)
|
||||||
FATAL_ERROR("No metatile height value following \"-mheight\".\n");
|
FATAL_ERROR("No rows per chunk value following \"%s\".\n", option);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!ParseNumber(argv[i], NULL, 10, &options.metatileHeight))
|
if (!ParseNumber(argv[i], NULL, 10, &options.rowsPerChunk))
|
||||||
FATAL_ERROR("Failed to parse metatile height.\n");
|
FATAL_ERROR("Failed to parse rows per chunk.\n");
|
||||||
|
|
||||||
if (options.metatileHeight < 1)
|
if (options.rowsPerChunk < 1)
|
||||||
FATAL_ERROR("metatile height must be positive.\n");
|
FATAL_ERROR("rows per chunk must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-scanfronttoback") == 0)
|
else if (strcmp(option, "-scanfronttoback") == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -340,8 +344,8 @@ void HandleNtrToPngCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.width != 0 && options.metatileWidth > options.width)
|
if (options.width != 0 && options.colsPerChunk > options.width)
|
||||||
options.width = options.metatileWidth;
|
options.width = options.colsPerChunk;
|
||||||
|
|
||||||
ConvertNtrToPng(inputPath, outputPath, &options);
|
ConvertNtrToPng(inputPath, outputPath, &options);
|
||||||
}
|
}
|
||||||
|
|
@ -357,8 +361,8 @@ void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
struct PngToGbaOptions options;
|
struct PngToGbaOptions options;
|
||||||
options.numTiles = 0;
|
options.numTiles = 0;
|
||||||
options.bitDepth = bitDepth;
|
options.bitDepth = bitDepth;
|
||||||
options.metatileWidth = 1;
|
options.colsPerChunk = 1;
|
||||||
options.metatileHeight = 1;
|
options.rowsPerChunk = 1;
|
||||||
|
|
||||||
for (int i = 3; i < argc; i++)
|
for (int i = 3; i < argc; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -377,31 +381,31 @@ void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
if (options.numTiles < 1)
|
if (options.numTiles < 1)
|
||||||
FATAL_ERROR("Number of tiles must be positive.\n");
|
FATAL_ERROR("Number of tiles must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-mwidth") == 0)
|
else if (strcmp(option, "-mwidth") == 0 || strcmp(option, "-cpc") == 0)
|
||||||
{
|
{
|
||||||
if (i + 1 >= argc)
|
if (i + 1 >= argc)
|
||||||
FATAL_ERROR("No metatile width value following \"-mwidth\".\n");
|
FATAL_ERROR("No columns per chunk value following \"%s\".\n", option);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!ParseNumber(argv[i], NULL, 10, &options.metatileWidth))
|
if (!ParseNumber(argv[i], NULL, 10, &options.colsPerChunk))
|
||||||
FATAL_ERROR("Failed to parse metatile width.\n");
|
FATAL_ERROR("Failed to parse columns per chunk.\n");
|
||||||
|
|
||||||
if (options.metatileWidth < 1)
|
if (options.colsPerChunk < 1)
|
||||||
FATAL_ERROR("metatile width must be positive.\n");
|
FATAL_ERROR("columns per chunk must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-mheight") == 0)
|
else if (strcmp(option, "-mheight") == 0 || strcmp(option, "-rpc") == 0)
|
||||||
{
|
{
|
||||||
if (i + 1 >= argc)
|
if (i + 1 >= argc)
|
||||||
FATAL_ERROR("No metatile height value following \"-mheight\".\n");
|
FATAL_ERROR("No rows per chunk value following \"%s\".\n", option);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!ParseNumber(argv[i], NULL, 10, &options.metatileHeight))
|
if (!ParseNumber(argv[i], NULL, 10, &options.rowsPerChunk))
|
||||||
FATAL_ERROR("Failed to parse metatile height.\n");
|
FATAL_ERROR("Failed to parse rows per chunk.\n");
|
||||||
|
|
||||||
if (options.metatileHeight < 1)
|
if (options.rowsPerChunk < 1)
|
||||||
FATAL_ERROR("metatile height must be positive.\n");
|
FATAL_ERROR("rows per chunk must be positive.\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -417,14 +421,17 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
struct PngToNtrOptions options;
|
struct PngToNtrOptions options;
|
||||||
options.numTiles = 0;
|
options.numTiles = 0;
|
||||||
options.bitDepth = 4;
|
options.bitDepth = 4;
|
||||||
options.metatileWidth = 1;
|
options.colsPerChunk = 1;
|
||||||
options.metatileHeight = 1;
|
options.rowsPerChunk = 1;
|
||||||
|
options.wrongSize = false;
|
||||||
options.clobberSize = false;
|
options.clobberSize = false;
|
||||||
options.byteOrder = true;
|
options.byteOrder = true;
|
||||||
options.version101 = false;
|
options.version101 = false;
|
||||||
options.sopc = false;
|
options.sopc = false;
|
||||||
options.scanMode = 0;
|
options.scanMode = 0;
|
||||||
options.handleEmpty = false;
|
options.handleEmpty = false;
|
||||||
|
options.vramTransfer = false;
|
||||||
|
options.mappingType = 0;
|
||||||
|
|
||||||
for (int i = 3; i < argc; i++)
|
for (int i = 3; i < argc; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -443,31 +450,31 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
if (options.numTiles < 1)
|
if (options.numTiles < 1)
|
||||||
FATAL_ERROR("Number of tiles must be positive.\n");
|
FATAL_ERROR("Number of tiles must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-mwidth") == 0)
|
else if (strcmp(option, "-mwidth") == 0 || strcmp(option, "-cpc") == 0)
|
||||||
{
|
{
|
||||||
if (i + 1 >= argc)
|
if (i + 1 >= argc)
|
||||||
FATAL_ERROR("No metatile width value following \"-mwidth\".\n");
|
FATAL_ERROR("No columns per chunk value following \"%s\".\n", option);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!ParseNumber(argv[i], NULL, 10, &options.metatileWidth))
|
if (!ParseNumber(argv[i], NULL, 10, &options.colsPerChunk))
|
||||||
FATAL_ERROR("Failed to parse metatile width.\n");
|
FATAL_ERROR("Failed to parse columns per chunk.\n");
|
||||||
|
|
||||||
if (options.metatileWidth < 1)
|
if (options.colsPerChunk < 1)
|
||||||
FATAL_ERROR("metatile width must be positive.\n");
|
FATAL_ERROR("columns per chunk must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-mheight") == 0)
|
else if (strcmp(option, "-mheight") == 0 || strcmp(option, "-rpc") == 0)
|
||||||
{
|
{
|
||||||
if (i + 1 >= argc)
|
if (i + 1 >= argc)
|
||||||
FATAL_ERROR("No metatile height value following \"-mheight\".\n");
|
FATAL_ERROR("No rows per chunk value following \"%s\".\n", option);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!ParseNumber(argv[i], NULL, 10, &options.metatileHeight))
|
if (!ParseNumber(argv[i], NULL, 10, &options.rowsPerChunk))
|
||||||
FATAL_ERROR("Failed to parse metatile height.\n");
|
FATAL_ERROR("Failed to parse rows per chunk.\n");
|
||||||
|
|
||||||
if (options.metatileHeight < 1)
|
if (options.rowsPerChunk < 1)
|
||||||
FATAL_ERROR("metatile height must be positive.\n");
|
FATAL_ERROR("rows per chunk must be positive.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(option, "-bitdepth") == 0)
|
else if (strcmp(option, "-bitdepth") == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -510,10 +517,29 @@ void HandlePngToNtrCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||||
FATAL_ERROR("Scan mode specified more than once.\n-scanned goes back to front as in DP, -scanfronttoback goes front to back as in PtHGSS\n");
|
FATAL_ERROR("Scan mode specified more than once.\n-scanned goes back to front as in DP, -scanfronttoback goes front to back as in PtHGSS\n");
|
||||||
options.scanMode = 2;
|
options.scanMode = 2;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(option, "-wrongsize") == 0) {
|
||||||
|
options.wrongSize = true;
|
||||||
|
}
|
||||||
else if (strcmp(option, "-handleempty") == 0)
|
else if (strcmp(option, "-handleempty") == 0)
|
||||||
{
|
{
|
||||||
options.handleEmpty = true;
|
options.handleEmpty = true;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(option, "-vram") == 0)
|
||||||
|
{
|
||||||
|
options.vramTransfer = true;
|
||||||
|
}
|
||||||
|
else if (strcmp(option, "-mappingtype") == 0) {
|
||||||
|
if (i + 1 >= argc)
|
||||||
|
FATAL_ERROR("No mapping type value following \"-mappingtype\".\n");
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (!ParseNumber(argv[i], NULL, 10, &options.mappingType))
|
||||||
|
FATAL_ERROR("Failed to parse mapping type.\n");
|
||||||
|
|
||||||
|
if (options.mappingType != 0 && options.mappingType != 32 && options.mappingType != 64 && options.mappingType != 128 && options.mappingType != 256)
|
||||||
|
FATAL_ERROR("bitdepth must be one of the following: 0, 32, 64, 128, or 256\n");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
||||||
|
|
@ -749,6 +775,107 @@ void HandleJascToNtrPaletteCommand(char *inputPath, char *outputPath, int argc,
|
||||||
WriteNtrPalette(outputPath, &palette, ncpr, ir, bitdepth, !nopad, compNum);
|
WriteNtrPalette(outputPath, &palette, ncpr, ir, bitdepth, !nopad, compNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleJsonToNtrCellCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
|
{
|
||||||
|
struct JsonToCellOptions *options;
|
||||||
|
|
||||||
|
options = ParseNCERJson(inputPath);
|
||||||
|
|
||||||
|
WriteNtrCell(outputPath, options);
|
||||||
|
|
||||||
|
FreeNCERCell(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleNtrCellToJsonCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
|
{
|
||||||
|
struct JsonToCellOptions *options = malloc(sizeof(struct JsonToCellOptions));
|
||||||
|
|
||||||
|
ReadNtrCell(inputPath, options);
|
||||||
|
|
||||||
|
char *json = GetNCERJson(options);
|
||||||
|
|
||||||
|
WriteWholeStringToFile(outputPath, json);
|
||||||
|
|
||||||
|
FreeNCERCell(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleJsonToNtrScreenCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
|
{
|
||||||
|
struct JsonToScreenOptions *options;
|
||||||
|
|
||||||
|
options = ParseNSCRJson(inputPath);
|
||||||
|
|
||||||
|
int bitdepth = 4;
|
||||||
|
|
||||||
|
for (int i = 3; i < argc; i++)
|
||||||
|
{
|
||||||
|
char *option = argv[i];
|
||||||
|
|
||||||
|
if (strcmp(option, "-bitdepth") == 0)
|
||||||
|
{
|
||||||
|
if (i + 1 >= argc)
|
||||||
|
FATAL_ERROR("No bitdepth following \"-bitdepth\".\n");
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (!ParseNumber(argv[i], NULL, 10, &bitdepth))
|
||||||
|
FATAL_ERROR("Failed to parse bitdepth.\n");
|
||||||
|
|
||||||
|
if (bitdepth != 4 && bitdepth != 8)
|
||||||
|
FATAL_ERROR("Bitdepth must be 4 or 8.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FATAL_ERROR("Unrecognized option \"%s\".\n", option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
options->bitdepth = bitdepth;
|
||||||
|
|
||||||
|
WriteNtrScreen(outputPath, options);
|
||||||
|
|
||||||
|
FreeNSCRScreen(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleJsonToNtrAnimationCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
|
{
|
||||||
|
struct JsonToAnimationOptions *options;
|
||||||
|
|
||||||
|
options = ParseNANRJson(inputPath);
|
||||||
|
|
||||||
|
options->multiCell = false;
|
||||||
|
|
||||||
|
WriteNtrAnimation(outputPath, options);
|
||||||
|
|
||||||
|
FreeNANRAnimation(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleNtrAnimationToJsonCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
|
{
|
||||||
|
struct JsonToAnimationOptions *options = malloc(sizeof(struct JsonToAnimationOptions));
|
||||||
|
|
||||||
|
ReadNtrAnimation(inputPath, options);
|
||||||
|
|
||||||
|
char *json = GetNANRJson(options);
|
||||||
|
|
||||||
|
WriteWholeStringToFile(outputPath, json);
|
||||||
|
|
||||||
|
FreeNANRAnimation(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleJsonToNtrMulticellAnimationCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
|
{
|
||||||
|
struct JsonToAnimationOptions *options;
|
||||||
|
|
||||||
|
options = ParseNANRJson(inputPath);
|
||||||
|
|
||||||
|
options->multiCell = true;
|
||||||
|
|
||||||
|
WriteNtrAnimation(outputPath, options);
|
||||||
|
|
||||||
|
FreeNANRAnimation(options);
|
||||||
|
}
|
||||||
|
|
||||||
void HandleLatinFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
void HandleLatinFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||||
{
|
{
|
||||||
struct Image image;
|
struct Image image;
|
||||||
|
|
@ -1010,6 +1137,13 @@ int main(int argc, char **argv)
|
||||||
{ "png", "hwjpnfont", HandlePngToHalfwidthJapaneseFontCommand },
|
{ "png", "hwjpnfont", HandlePngToHalfwidthJapaneseFontCommand },
|
||||||
{ "fwjpnfont", "png", HandleFullwidthJapaneseFontToPngCommand },
|
{ "fwjpnfont", "png", HandleFullwidthJapaneseFontToPngCommand },
|
||||||
{ "png", "fwjpnfont", HandlePngToFullwidthJapaneseFontCommand },
|
{ "png", "fwjpnfont", HandlePngToFullwidthJapaneseFontCommand },
|
||||||
|
{ "json", "NCER", HandleJsonToNtrCellCommand },
|
||||||
|
{ "NCER", "json", HandleNtrCellToJsonCommand },
|
||||||
|
{ "json", "NSCR", HandleJsonToNtrScreenCommand },
|
||||||
|
{ "json", "NANR", HandleJsonToNtrAnimationCommand },
|
||||||
|
{ "NANR", "json", HandleNtrAnimationToJsonCommand },
|
||||||
|
{ "json", "NMAR", HandleJsonToNtrMulticellAnimationCommand },
|
||||||
|
{ "NMAR", "json", HandleNtrAnimationToJsonCommand },
|
||||||
{ NULL, "huff", HandleHuffCompressCommand },
|
{ NULL, "huff", HandleHuffCompressCommand },
|
||||||
{ NULL, "lz", HandleLZCompressCommand },
|
{ NULL, "lz", HandleLZCompressCommand },
|
||||||
{ "huff", NULL, HandleHuffDecompressCommand },
|
{ "huff", NULL, HandleHuffDecompressCommand },
|
||||||
|
|
|
||||||
27
tools/nitrogfx/meson.build
Normal file
27
tools/nitrogfx/meson.build
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
project('nitrogfx', 'c')
|
||||||
|
|
||||||
|
native = get_option('native')
|
||||||
|
install = native and meson.is_cross_build() ? false : true
|
||||||
|
|
||||||
|
libpng_dep = dependency('libpng', native: native)
|
||||||
|
|
||||||
|
nitrogfx_exe = executable('nitrogfx',
|
||||||
|
sources: [
|
||||||
|
'main.c',
|
||||||
|
'convert_png.c',
|
||||||
|
'gfx.c',
|
||||||
|
'jasc_pal.c',
|
||||||
|
'lz.c',
|
||||||
|
'rl.c',
|
||||||
|
'util.c',
|
||||||
|
'font.c',
|
||||||
|
'huff.c',
|
||||||
|
'json.c',
|
||||||
|
'cJSON.c',
|
||||||
|
],
|
||||||
|
dependencies: libpng_dep,
|
||||||
|
native: native,
|
||||||
|
install: install
|
||||||
|
)
|
||||||
|
|
||||||
|
meson.override_find_program('nitrogfx', nitrogfx_exe)
|
||||||
1
tools/nitrogfx/meson_options.txt
Normal file
1
tools/nitrogfx/meson_options.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
option('native', type : 'boolean', value : false, description: 'Force native compilation, even in a cross-compilation setup')
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
// Copyright (c) 2018 huderlem
|
// Copyright (c) 2018 huderlem, 2021-2023 red031000
|
||||||
|
|
||||||
#ifndef OPTIONS_H
|
#ifndef OPTIONS_H
|
||||||
#define OPTIONS_H
|
#define OPTIONS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct GbaToPngOptions {
|
struct GbaToPngOptions {
|
||||||
|
|
@ -10,29 +11,32 @@ struct GbaToPngOptions {
|
||||||
int bitDepth;
|
int bitDepth;
|
||||||
bool hasTransparency;
|
bool hasTransparency;
|
||||||
int width;
|
int width;
|
||||||
int metatileWidth;
|
int colsPerChunk;
|
||||||
int metatileHeight;
|
int rowsPerChunk;
|
||||||
int palIndex;
|
int palIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PngToGbaOptions {
|
struct PngToGbaOptions {
|
||||||
int numTiles;
|
int numTiles;
|
||||||
int bitDepth;
|
int bitDepth;
|
||||||
int metatileWidth;
|
int colsPerChunk;
|
||||||
int metatileHeight;
|
int rowsPerChunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PngToNtrOptions {
|
struct PngToNtrOptions {
|
||||||
int numTiles;
|
int numTiles;
|
||||||
int bitDepth;
|
int bitDepth;
|
||||||
int metatileWidth;
|
int colsPerChunk;
|
||||||
int metatileHeight;
|
int rowsPerChunk;
|
||||||
bool clobberSize;
|
bool clobberSize;
|
||||||
bool byteOrder;
|
bool byteOrder;
|
||||||
bool version101;
|
bool version101;
|
||||||
bool sopc;
|
bool sopc;
|
||||||
uint32_t scanMode;
|
uint32_t scanMode;
|
||||||
|
bool wrongSize;
|
||||||
bool handleEmpty;
|
bool handleEmpty;
|
||||||
|
bool vramTransfer;
|
||||||
|
int mappingType;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NtrToPngOptions {
|
struct NtrToPngOptions {
|
||||||
|
|
@ -40,12 +44,126 @@ struct NtrToPngOptions {
|
||||||
int bitDepth;
|
int bitDepth;
|
||||||
bool hasTransparency;
|
bool hasTransparency;
|
||||||
int width;
|
int width;
|
||||||
int metatileWidth;
|
int colsPerChunk;
|
||||||
int metatileHeight;
|
int rowsPerChunk;
|
||||||
int palIndex;
|
int palIndex;
|
||||||
bool scanFrontToBack;
|
bool scanFrontToBack;
|
||||||
bool handleEmpty;
|
bool handleEmpty;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Attr0 {
|
||||||
|
int YCoordinate;
|
||||||
|
bool Rotation;
|
||||||
|
bool SizeDisable;
|
||||||
|
int Mode;
|
||||||
|
bool Mosaic;
|
||||||
|
int Colours;
|
||||||
|
int Shape;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Attr1 {
|
||||||
|
int XCoordinate;
|
||||||
|
int RotationScaling;
|
||||||
|
int Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Attr2 {
|
||||||
|
int CharName;
|
||||||
|
int Priority;
|
||||||
|
int Palette;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OAM {
|
||||||
|
struct Attr0 attr0;
|
||||||
|
struct Attr1 attr1;
|
||||||
|
struct Attr2 attr2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellAttributes {
|
||||||
|
bool hFlip; // 1 << 8
|
||||||
|
bool vFlip; // 1 << 9
|
||||||
|
bool hvFlip; // 1 << 10
|
||||||
|
bool boundingRect; // 1 << 11
|
||||||
|
int boundingSphereRadius; // 1 << 0 (6 bits);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Cell {
|
||||||
|
struct CellAttributes attributes;
|
||||||
|
short maxX;
|
||||||
|
short maxY;
|
||||||
|
short minX;
|
||||||
|
short minY;
|
||||||
|
short oamCount;
|
||||||
|
struct OAM *oam;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JsonToCellOptions {
|
||||||
|
bool labelEnabled;
|
||||||
|
bool extended;
|
||||||
|
int mappingType;
|
||||||
|
int cellCount;
|
||||||
|
struct Cell **cells;
|
||||||
|
char **labels;
|
||||||
|
int labelCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JsonToScreenOptions {
|
||||||
|
int height;
|
||||||
|
int width;
|
||||||
|
unsigned short *data;
|
||||||
|
int bitdepth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FrameData {
|
||||||
|
int resultId;
|
||||||
|
short frameDelay;
|
||||||
|
int resultOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SequenceData {
|
||||||
|
short frameCount;
|
||||||
|
short loopStartFrame;
|
||||||
|
short animationElement;
|
||||||
|
short animationType;
|
||||||
|
int playbackMode;
|
||||||
|
struct FrameData **frameData;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnimationDataSRT {
|
||||||
|
short index;
|
||||||
|
unsigned short rotation;
|
||||||
|
int scaleX;
|
||||||
|
int scaleY;
|
||||||
|
short positionX;
|
||||||
|
short positionY;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnimationDataT {
|
||||||
|
short index;
|
||||||
|
//unsigned short rotation;
|
||||||
|
short positionX;
|
||||||
|
short positionY;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnimationResults {
|
||||||
|
short resultType;
|
||||||
|
union {
|
||||||
|
short index;
|
||||||
|
struct AnimationDataSRT dataSrt;
|
||||||
|
struct AnimationDataT dataT;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JsonToAnimationOptions {
|
||||||
|
bool multiCell;
|
||||||
|
short sequenceCount;
|
||||||
|
short frameCount;
|
||||||
|
struct SequenceData **sequenceData;
|
||||||
|
struct AnimationResults **animationResults;
|
||||||
|
bool labelEnabled;
|
||||||
|
char **labels;
|
||||||
|
int labelCount;
|
||||||
|
short resultCount;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // OPTIONS_H
|
#endif // OPTIONS_H
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,19 @@ unsigned char *ReadWholeFileZeroPadded(char *path, int *size, int padAmount)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteWholeStringToFile(char *path, char *string)
|
||||||
|
{
|
||||||
|
FILE *fp = fopen(path, "wb");
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
FATAL_ERROR("Failed to open \"%s\" for writing.\n", path);
|
||||||
|
|
||||||
|
if (fputs(string, fp) == EOF)
|
||||||
|
FATAL_ERROR("Failed to write to \"%s\".\n", path);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
void WriteWholeFile(char *path, void *buffer, int bufferSize)
|
void WriteWholeFile(char *path, void *buffer, int bufferSize)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(path, "wb");
|
FILE *fp = fopen(path, "wb");
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ bool ParseNumber(char *s, char **end, int radix, int *intValue);
|
||||||
char *GetFileExtension(char *path);
|
char *GetFileExtension(char *path);
|
||||||
unsigned char *ReadWholeFile(char *path, int *size);
|
unsigned char *ReadWholeFile(char *path, int *size);
|
||||||
unsigned char *ReadWholeFileZeroPadded(char *path, int *size, int padAmount);
|
unsigned char *ReadWholeFileZeroPadded(char *path, int *size, int padAmount);
|
||||||
|
void WriteWholeStringToFile(char *path, char *string);
|
||||||
void WriteWholeFile(char *path, void *buffer, int bufferSize);
|
void WriteWholeFile(char *path, void *buffer, int bufferSize);
|
||||||
void WriteGenericNtrHeader(FILE* fp, const char* magicNumber, uint32_t size, bool byteorder, bool version101, uint16_t sectionCount);
|
void WriteGenericNtrHeader(FILE* fp, const char* magicNumber, uint32_t size, bool byteorder, bool version101, uint16_t sectionCount);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user