create textencode tool for generating message data

This commit is contained in:
Cameron Hall 2018-03-01 21:01:51 -06:00
parent d10272cb84
commit 154394e251
9 changed files with 4298 additions and 2 deletions

4
.gitignore vendored
View File

@ -58,3 +58,7 @@ src/*.s
*.dump
tools/agbcc
*.exe
# Generated source files
src/msg_data.c
include/msg_data.h

View File

@ -6,6 +6,7 @@ CPP := $(DEVKITARM)/bin/arm-none-eabi-cpp
AS := $(DEVKITARM)/bin/arm-none-eabi-as
LD := $(DEVKITARM)/bin/arm-none-eabi-ld
OBJCOPY := $(DEVKITARM)/bin/arm-none-eabi-objcopy
TEXTENCODE := tools/textencode/textencode
CC1FLAGS := -mthumb-interwork -Wimplicit -Wparentheses -Werror -O2 -fhex-asm
CPPFLAGS := -I tools/agbcc/include -iquote include -nostdinc -undef
@ -19,7 +20,8 @@ ELF := $(ROM:.gba=.elf)
MAP := $(ROM:.gba=.map)
LDSCRIPT := ldscript.txt
SYM_FILES := sym_iwram.txt sym_ewram.txt
CFILES := $(wildcard src/*.c)
CFILES_GENERATED := src/msg_data.c
CFILES := $(wildcard src/*.c) $(CFILES_GENERATED)
SFILES := $(wildcard asm/*.s) $(wildcard asm/libc/*.s) $(wildcard data/*.s)
OFILES := $(SFILES:.s=.o) $(CFILES:.c=.o)
@ -28,13 +30,14 @@ src/agb_sram.o: CC1FLAGS := -mthumb-interwork -Wimplicit -Wparentheses -Werror -
src/m4a_2.o: CC1 := tools/agbcc/bin/old_agbcc
src/m4a_4.o: CC1 := tools/agbcc/bin/old_agbcc
#### Main Targets ####
compare: $(ROM)
sha1sum -c checksum.sha1
clean:
$(RM) $(ROM) $(ELF) $(MAP) $(OFILES) src/*.s
$(RM) $(ROM) $(ELF) $(MAP) $(OFILES) src/*.s $(CFILES_GENERATED)
#### Recipes ####
@ -52,3 +55,7 @@ $(ELF): $(OFILES) $(LDSCRIPT) $(SYM_FILES)
%.o: %.s
$(AS) $(ASFLAGS) $< -o $@
# Generate msg_data.c
src/msg_data.c include/msg_data.h: msg_list.txt
$(TEXTENCODE) $< $@ include/msg_data.h

View File

@ -6,3 +6,4 @@ make -C tools/bin2c
make -C tools/rsfont
make -C tools/aif2pcm
make -C tools/ramscrgen
make -C tools/textencode

3404
msg_list.txt Normal file

File diff suppressed because one or more lines are too long

1
tools/textencode/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
textencode

14
tools/textencode/Makefile Normal file
View File

@ -0,0 +1,14 @@
CC = gcc
#CFLAGS = -Wall -Wextra -Werror -std=c11 -O2 -s
CFLAGS = -Wall -Wextra -std=c11 -O2 -g
.PHONY: clean
SRCS = textencode.c inputfile.c
textencode: $(SRCS)
$(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS)
clean:
$(RM) textencode textencode.exe

View File

@ -0,0 +1,256 @@
#include "textencode.h"
static size_t inputFileSize;
static char *inputFileBuffer;
static int lineNum;
struct String *gInputStrings = NULL;
int gInputStringsCount = 0;
static void add_input_string(char *ident, char *string)
{
int index = gInputStringsCount;
int i;
// check if ID already exists
for (i = 0; i < index; i++)
if (strcmp(ident, gInputStrings[i].id) == 0)
FATAL_ERROR("line %i: string id %s already exists\n", lineNum, ident);
gInputStringsCount++;
gInputStrings = realloc(gInputStrings, gInputStringsCount * sizeof(*gInputStrings));
gInputStrings[index].id = ident;
gInputStrings[index].text = string;
}
// null terminates the current line and returns a pointer to the next line
static char *split_next_line(char *line)
{
while (*line != '\n')
{
if (*line == 0)
{
if (line == inputFileBuffer + inputFileSize)
return NULL; // end of file
else
FATAL_ERROR("line %i: unexpected NUL character\n", lineNum);
}
line++;
}
*line = 0;
return line + 1;
}
static char *skip_whitespace(char *str)
{
while (isspace(*str))
str++;
return str;
}
static int is_identifier_char(int c)
{
return (isalnum(c) || c == '_');
}
static int hex_digit(int c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 0xA;
if (c >= 'A' && c <= 'F')
return c - 'A' + 0xA;
return -1;
}
static int is_hex_digit(int c)
{
return (hex_digit(c) != -1);
}
static int read_hex_number(char **str_)
{
char *str = *str_;
int val = 0;
int i = 0;
while (i < 2)
{
int digit = hex_digit(*str);
if (digit == -1)
break;
val = (val << 4) | digit;
str++;
i++;
}
*str_ = str;
return val;
}
/*
static int read_hex_number(char **str_)
{
char *str = *str_;
int val = 0;
while (1)
{
int digit = hex_digit(*str);
if (digit == -1)
break;
val = (val << 4) | digit;
str++;
}
*str_ = str;
return val;
}
*/
static void eval_escape_sequences(char *str)
{
const uint8_t escapeTable[] =
{
['a'] = 0x07,
['b'] = 0x08,
['f'] = 0x0C,
['n'] = 0x0A,
['r'] = 0x0D,
['t'] = 0x09,
['v'] = 0x0B,
['\\'] = '\\',
['"'] = '"',
};
char *src = str;
char *dest = str;
while (*src != 0)
{
if (*src == '\\')
{
src++;
unsigned int escval = *src;
if (escval < ARRAY_COUNT(escapeTable) && escapeTable[escval] != 0)
{
*dest++ = escapeTable[escval];
src++;
}
else
{
if (escval == 'x')
{
src++;
if (!is_hex_digit(*src))
FATAL_ERROR("line %i: invalid hex number\n", lineNum);
int val = read_hex_number(&src);
if (val > 0xFF)
FATAL_ERROR("line %i: hex value 0x%X is too large for one byte\n", lineNum, val);
*dest++ = val;
//printf("debug: hex 0x%X\n", val);
}
else
{
FATAL_ERROR("line %i: unknown escape sequence \\%c\n", lineNum, escval);
}
}
}
else
{
*dest++ = *src++;
}
}
*dest = 0;
}
static void parse_line(char *line)
{
char *identStart;
char *identEnd;
char *stringStart;
char *stringEnd;
int escaped;
line = skip_whitespace(line);
if (*line == '#') // comment
return;
if (*line == 0) // blank line
return;
// read identifier
if (!is_identifier_char(*line))
FATAL_ERROR("line %i: invalid identifier char '%c'\n", lineNum, *line);
identStart = line;
while (is_identifier_char(*line))
line++;
identEnd = line;
line = skip_whitespace(line);
// read string
if (*line != '"')
FATAL_ERROR("line %i: expected string literal following identifier\n", lineNum);
line++;
stringStart = line;
escaped = 0;
while (*line != '"' || escaped)
{
if (*line == 0)
FATAL_ERROR("line %i: unterminated string literal\n", lineNum);
if (escaped)
escaped = 0;
else if (*line == '\\')
escaped = 1;
line++;
}
stringEnd = line;
line++;
line = skip_whitespace(line);
if (*line != 0)
FATAL_ERROR("line %i: junk at end of line\n", lineNum);
*stringEnd = 0;
*identEnd = 0;
eval_escape_sequences(stringStart);
add_input_string(identStart, stringStart);
}
void read_input_file(const char *filename)
{
FILE *file;
char *line;
char *next;
// open file
file = fopen(filename, "rb");
if (file == NULL)
FATAL_ERROR("could not open file '%s' for reading\n", filename);
fseek(file, 0, SEEK_END);
inputFileSize = ftell(file);
inputFileBuffer = malloc(inputFileSize + 1);
fseek(file, 0, SEEK_SET);
if (fread(inputFileBuffer, inputFileSize, 1, file) != 1)
FATAL_ERROR("error reading data from file '%s'\n", filename);
inputFileBuffer[inputFileSize] = 0;
fclose(file);
// read contents
line = inputFileBuffer;
lineNum = 1;
while (line != NULL)
{
next = split_next_line(line);
parse_line(line);
line = next;
lineNum++;
}
}

View File

@ -0,0 +1,581 @@
#include "textencode.h"
#include <assert.h>
// TODO: Generate this table from the string data
int32_t huffmanTable[] =
{
// leaf nodes have the most significant bit set
// if the 2nd byte is zero, then the node has one character.
// if the 2nd byte is nonzero, then the node has two characters.
0xffff0000, 0xffff0001, 0xffff0002, 0xffff0003, 0xffff0004, 0xffff0005, 0xffff0006, 0xffff0007,
0xffff0008, 0xffff0009, 0xffff000a, 0xffff000b, 0xffff000c, 0xffff000d, 0xffff000e, 0xffff000f,
0xffff0010, 0xffff0011, 0xffff0015, 0xffff0016, 0xffff0017, 0xffff0018, 0xffff0019, 0xffff001a,
0xffff001b, 0xffff001c, 0xffff001d, 0xffff001e, 0xffff001f, 0xffff0021, 0xffff0022, 0xffff0023,
0xffff0025, 0xffff007f, 0xffff0080, 0xffff00e9, 0xffff0101, 0xffff0102, 0xffff0104, 0xffff0105,
0xffff0106, 0xffff0107, 0xffff0108, 0xffff0109, 0xffff010a, 0xffff010b, 0xffff010c, 0xffff010d,
0xffff010e, 0xffff010f, 0xffff0110, 0xffff0111, 0xffff0112, 0xffff0113, 0xffff0114, 0xffff0116,
0xffff0117, 0xffff0118, 0xffff0119, 0xffff011a, 0xffff011b, 0xffff011c, 0xffff011e, 0xffff0120,
0xffff0121, 0xffff0122, 0xffff0123, 0xffff0124, 0xffff0125, 0xffff0126, 0xffff0128, 0xffff0129,
0xffff012a, 0xffff012b, 0xffff012c, 0xffff012d, 0xffff012e, 0xffff012f, 0xffff0130, 0xffff0131,
0xffff0132, 0xffff0133, 0xffff0134, 0xffff0135, 0xffff0136, 0xffff0137, 0xffff0138, 0xffff0139,
0xffff013a, 0xffff013b, 0xffff013c, 0xffff013d, 0xffff013e, 0xffff013f, 0xffff0140, 0xffff0142,
0xffff0143, 0xffff0144, 0xffff0145, 0xffff0146, 0xffff0148, 0xffff0149, 0xffff014a, 0xffff014b,
0xffff014c, 0xffff014e, 0xffff014f, 0xffff0150, 0xffff0151, 0xffff0152, 0xffff0153, 0xffff0154,
0xffff0155, 0xffff0156, 0xffff0157, 0xffff0158, 0xffff0159, 0xffff015a, 0xffff015b, 0xffff015c,
0xffff015d, 0xffff015e, 0xffff015f, 0xffff0160, 0xffff0161, 0xffff0162, 0xffff0163, 0xffff0164,
0xffff0169, 0xffff016a, 0xffff016b, 0xffff016d, 0xffff016f, 0xffff1f20, 0xffff2020, 0xffff2520,
0xffff2620, 0xffff2720, 0xffff2820, 0xffff2b20, 0xffff3020, 0xffff3120, 0xffff3220, 0xffff3320,
0xffff3420, 0xffff3520, 0xffff3620, 0xffff3720, 0xffff3820, 0xffff3920, 0xffff3d20, 0xffff3f20,
0xffff4120, 0xffff4220, 0xffff4320, 0xffff4420, 0xffff4520, 0xffff4620, 0xffff4720, 0xffff4820,
0xffff4920, 0xffff4a20, 0xffff4b20, 0xffff4c20, 0xffff4d20, 0xffff4e20, 0xffff4f20, 0xffff5020,
0xffff5120, 0xffff5220, 0xffff5320, 0xffff5420, 0xffff5520, 0xffff5620, 0xffff5720, 0xffff5920,
0xffff5a20, 0xffff6120, 0xffff6220, 0xffff6320, 0xffff6420, 0xffff6520, 0xffff6620, 0xffff6720,
0xffff6820, 0xffff6920, 0xffff6a20, 0xffff6b20, 0xffff6c20, 0xffff6d20, 0xffff6e20, 0xffff6f20,
0xffff7020, 0xffff7120, 0xffff7220, 0xffff7320, 0xffff7420, 0xffff7520, 0xffff7620, 0xffff7720,
0xffff7920, 0xffff7a20, 0xffff9320, 0xffff1f21, 0xffff2021, 0xffff2121, 0xffff2221, 0xffff2921,
0xffff3f21, 0xffff9421, 0xffff5222, 0xffff5722, 0xffff1f25, 0xffff2025, 0xffff2e25, 0xffff2026,
0xffff1f27, 0xffff2027, 0xffff4127, 0xffff4327, 0xffff4e27, 0xffff5427, 0xffff6127, 0xffff6227,
0xffff6327, 0xffff6427, 0xffff6527, 0xffff6827, 0xffff6c27, 0xffff6d27, 0xffff7227, 0xffff7327,
0xffff7427, 0xffff7627, 0xffff4128, 0xffff5328, 0xffff5428, 0xffff5528, 0xffff6128, 0xffff6228,
0xffff6428, 0xffff6628, 0xffff6728, 0xffff7228, 0xffff7328, 0xffff1f29, 0xffff2029, 0xffff1f2b,
0xffff202b, 0xffff352b, 0xffff432b, 0xffff1f2c, 0xffff202c, 0xffff302c, 0xffff392c, 0xffff942c,
0xffff1f2d, 0xffff202d, 0xffff2d2d, 0xffff412d, 0xffff492d, 0xffff4c2d, 0xffff4e2d, 0xffff532d,
0xffff612d, 0xffff622d, 0xffff632d, 0xffff642d, 0xffff652d, 0xffff662d, 0xffff672d, 0xffff682d,
0xffff692d, 0xffff6b2d, 0xffff6c2d, 0xffff6d2d, 0xffff6e2d, 0xffff6f2d, 0xffff702d, 0xffff722d,
0xffff732d, 0xffff742d, 0xffff752d, 0xffff772d, 0xffff792d, 0xffff1f2e, 0xffff202e, 0xffff212e,
0xffff222e, 0xffff292e, 0xffff2e2e, 0xffff3a2e, 0xffff3f2e, 0xffff492e, 0xffff4d2e, 0xffff532e,
0xffff542e, 0xffff6d2e, 0xffff942e, 0xffff1f2f, 0xffff322f, 0xffff422f, 0xffff482f, 0xffff1f30,
0xffff2030, 0xffff2c30, 0xffff2e30, 0xffff3030, 0xffff3330, 0xffff3f30, 0xffff7330, 0xffff1f31,
0xffff2031, 0xffff2c31, 0xffff2e31, 0xffff2f31, 0xffff3031, 0xffff3131, 0xffff3431, 0xffff3531,
0xffff3931, 0xffff5431, 0xffff7331, 0xffff1f32, 0xffff2032, 0xffff2b32, 0xffff2c32, 0xffff2d32,
0xffff2e32, 0xffff2f32, 0xffff3032, 0xffff3132, 0xffff3432, 0xffff6e32, 0xffff1f33, 0xffff2033,
0xffff2c33, 0xffff2d33, 0xffff2e33, 0xffff2f33, 0xffff7233, 0xffff1f34, 0xffff2e34, 0xffff2f34,
0xffff3034, 0xffff7434, 0xffff1f35, 0xffff2035, 0xffff2c35, 0xffff2e35, 0xffff3035, 0xffff1f36,
0xffff1f37, 0xffff2037, 0xffff1f38, 0xffff2038, 0xffff2e38, 0xffff3038, 0xffff1f39, 0xffff2139,
0xffff2c39, 0xffff3439, 0xffff3839, 0xffff3939, 0xffff1f3a, 0xffff203a, 0xffff203b, 0xffff1f3f,
0xffff203f, 0xffff213f, 0xffff3f3f, 0xffff943f, 0xffff1f41, 0xffff2041, 0xffff2141, 0xffff2d41,
0xffff4141, 0xffff4841, 0xffff4941, 0xffff4d41, 0xffff4e41, 0xffff5241, 0xffff5341, 0xffff5441,
0xffff6141, 0xffff6241, 0xffff6341, 0xffff6441, 0xffff6541, 0xffff6641, 0xffff6741, 0xffff6841,
0xffff6941, 0xffff6c41, 0xffff6d41, 0xffff6e41, 0xffff7041, 0xffff7241, 0xffff7341, 0xffff7441,
0xffff7541, 0xffff7641, 0xffff7741, 0xffff7841, 0xffff7941, 0xffff1f42, 0xffff2042, 0xffff2d42,
0xffff4142, 0xffff4742, 0xffff4942, 0xffff5242, 0xffff6142, 0xffff6542, 0xffff6942, 0xffff6c42,
0xffff6f42, 0xffff7242, 0xffff7542, 0xffff7742, 0xffff7942, 0xffff1f43, 0xffff2743, 0xffff2c43,
0xffff2d43, 0xffff2e43, 0xffff4143, 0xffff4843, 0xffff4b43, 0xffff5043, 0xffff5243, 0xffff6143,
0xffff6543, 0xffff6843, 0xffff6943, 0xffff6c43, 0xffff6f43, 0xffff7243, 0xffff7543, 0xffff7943,
0xffff1f44, 0xffff2044, 0xffff2144, 0xffff2d44, 0xffff2e44, 0xffff4144, 0xffff4544, 0xffff4f44,
0xffff5544, 0xffff6144, 0xffff6544, 0xffff6644, 0xffff6944, 0xffff6f44, 0xffff7244, 0xffff7544,
0xffff1f45, 0xffff2045, 0xffff2145, 0xffff2d45, 0xffff2e45, 0xffff3045, 0xffff3145, 0xffff4445,
0xffff4545, 0xffff4c45, 0xffff5245, 0xffff5445, 0xffff5845, 0xffff6145, 0xffff6345, 0xffff6445,
0xffff6545, 0xffff6645, 0xffff6745, 0xffff6845, 0xffff6945, 0xffff6c45, 0xffff6d45, 0xffff6e45,
0xffff7045, 0xffff7145, 0xffff7245, 0xffff7345, 0xffff7645, 0xffff7745, 0xffff7845, 0xffff7945,
0xffff1f46, 0xffff2046, 0xffff3a46, 0xffff6146, 0xffff6546, 0xffff6946, 0xffff6c46, 0xffff6f46,
0xffff7246, 0xffff7546, 0xffff2047, 0xffff4547, 0xffff4f47, 0xffff6147, 0xffff6547, 0xffff6847,
0xffff6947, 0xffff6c47, 0xffff6f47, 0xffff7247, 0xffff7547, 0xffff7747, 0xffff2148, 0xffff2d48,
0xffff4148, 0xffff4548, 0xffff4848, 0xffff4948, 0xffff4f48, 0xffff5048, 0xffff5448, 0xffff6148,
0xffff6548, 0xffff6848, 0xffff6948, 0xffff6d48, 0xffff6e48, 0xffff6f48, 0xffff7248, 0xffff7548,
0xffff1f49, 0xffff2049, 0xffff2149, 0xffff2749, 0xffff2c49, 0xffff2d49, 0xffff2e49, 0xffff3049,
0xffff3149, 0xffff3f49, 0xffff4749, 0xffff4c49, 0xffff5349, 0xffff5449, 0xffff6349, 0xffff6449,
0xffff6649, 0xffff6d49, 0xffff6e49, 0xffff7249, 0xffff7349, 0xffff7449, 0xffff7649, 0xffff2d4a,
0xffff614a, 0xffff654a, 0xffff6f4a, 0xffff754a, 0xffff1f4b, 0xffff2e4b, 0xffff3a4b, 0xffff3f4b,
0xffff654b, 0xffff694b, 0xffff6c4b, 0xffff6e4b, 0xffff754b, 0xffff794b, 0xffff1f4c, 0xffff204c,
0xffff274c, 0xffff2d4c, 0xffff414c, 0xffff454c, 0xffff4c4c, 0xffff4f4c, 0xffff564c, 0xffff614c,
0xffff654c, 0xffff694c, 0xffff6f4c, 0xffff754c, 0xffff764c, 0xffff794c, 0xffff1f4d, 0xffff204d,
0xffff2d4d, 0xffff454d, 0xffff4d4d, 0xffff4f4d, 0xffff504d, 0xffff544d, 0xffff554d, 0xffff594d,
0xffff614d, 0xffff654d, 0xffff694d, 0xffff6d4d, 0xffff6e4d, 0xffff6f4d, 0xffff724d, 0xffff744d,
0xffff754d, 0xffff794d, 0xffff204e, 0xffff2d4e, 0xffff2f4e, 0xffff4f4e, 0xffff614e, 0xffff654e,
0xffff674e, 0xffff694e, 0xffff6d4e, 0xffff6e4e, 0xffff6f4e, 0xffff754e, 0xffff204f, 0xffff274f,
0xffff2d4f, 0xffff464f, 0xffff4b4f, 0xffff4e4f, 0xffff524f, 0xffff534f, 0xffff544f, 0xffff554f,
0xffff614f, 0xffff624f, 0xffff634f, 0xffff664f, 0xffff684f, 0xffff6c4f, 0xffff6e4f, 0xffff6f4f,
0xffff704f, 0xffff724f, 0xffff744f, 0xffff754f, 0xffff764f, 0xffff774f, 0xffff1f50, 0xffff2050,
0xffff2150, 0xffff2c50, 0xffff2d50, 0xffff2e50, 0xffff3150, 0xffff3250, 0xffff3350, 0xffff3450,
0xffff3550, 0xffff5050, 0xffff6150, 0xffff6550, 0xffff6850, 0xffff6950, 0xffff6c50, 0xffff6f50,
0xffff7250, 0xffff7350, 0xffff7450, 0xffff7550, 0xffff7551, 0xffff2052, 0xffff2152, 0xffff2d52,
0xffff4152, 0xffff4552, 0xffff4e52, 0xffff5352, 0xffff6152, 0xffff6552, 0xffff6952, 0xffff6e52,
0xffff6f52, 0xffff7252, 0xffff7552, 0xffff1f53, 0xffff2053, 0xffff2153, 0xffff2d53, 0xffff2f53,
0xffff4553, 0xffff4853, 0xffff4e53, 0xffff4f53, 0xffff5053, 0xffff5253, 0xffff5453, 0xffff5753,
0xffff6153, 0xffff6353, 0xffff6553, 0xffff6853, 0xffff6953, 0xffff6b53, 0xffff6c53, 0xffff6d53,
0xffff6e53, 0xffff6f53, 0xffff7053, 0xffff7453, 0xffff7553, 0xffff7753, 0xffff7953, 0xffff2054,
0xffff2d54, 0xffff3a54, 0xffff4854, 0xffff4c54, 0xffff5554, 0xffff6154, 0xffff6354, 0xffff6554,
0xffff6854, 0xffff6954, 0xffff6f54, 0xffff7254, 0xffff7354, 0xffff7554, 0xffff7754, 0xffff1f55,
0xffff2055, 0xffff2755, 0xffff2d55, 0xffff5455, 0xffff6755, 0xffff6855, 0xffff6d55, 0xffff6e55,
0xffff7055, 0xffff7255, 0xffff7355, 0xffff7455, 0xffff7555, 0xffff6156, 0xffff6356, 0xffff6556,
0xffff6956, 0xffff6f56, 0xffff7556, 0xffff1f57, 0xffff2d57, 0xffff4157, 0xffff4557, 0xffff6157,
0xffff6557, 0xffff6857, 0xffff6957, 0xffff6f57, 0xffff7257, 0xffff7457, 0xffff7957, 0xffff5058,
0xffff1f59, 0xffff2059, 0xffff2d59, 0xffff4159, 0xffff4559, 0xffff4d59, 0xffff4f59, 0xffff6159,
0xffff6559, 0xffff6959, 0xffff6f59, 0xffff7559, 0xffff615a, 0xffff655a, 0xffff6f5a, 0xffff7a5a,
0xffff1f61, 0xffff2061, 0xffff2161, 0xffff2761, 0xffff2c61, 0xffff2d61, 0xffff2e61, 0xffff3a61,
0xffff3f61, 0xffff6161, 0xffff6261, 0xffff6361, 0xffff6461, 0xffff6561, 0xffff6661, 0xffff6761,
0xffff6861, 0xffff6961, 0xffff6a61, 0xffff6b61, 0xffff6c61, 0xffff6d61, 0xffff6e61, 0xffff6f61,
0xffff7061, 0xffff7261, 0xffff7361, 0xffff7461, 0xffff7561, 0xffff7661, 0xffff7761, 0xffff7861,
0xffff7961, 0xffff7a61, 0xffff9461, 0xffff1f62, 0xffff2062, 0xffff2162, 0xffff2c62, 0xffff2d62,
0xffff2e62, 0xffff6162, 0xffff6262, 0xffff6462, 0xffff6562, 0xffff6962, 0xffff6a62, 0xffff6c62,
0xffff6e62, 0xffff6f62, 0xffff7262, 0xffff7362, 0xffff7462, 0xffff7562, 0xffff7662, 0xffff7962,
0xffff1f63, 0xffff2063, 0xffff2163, 0xffff2763, 0xffff2c63, 0xffff2d63, 0xffff2e63, 0xffff3f63,
0xffff6163, 0xffff6363, 0xffff6563, 0xffff6863, 0xffff6963, 0xffff6b63, 0xffff6c63, 0xffff6f63,
0xffff7163, 0xffff7263, 0xffff7363, 0xffff7463, 0xffff7563, 0xffff7963, 0xffff1f64, 0xffff2064,
0xffff2164, 0xffff2764, 0xffff2964, 0xffff2c64, 0xffff2d64, 0xffff2e64, 0xffff3a64, 0xffff3f64,
0xffff6164, 0xffff6264, 0xffff6364, 0xffff6464, 0xffff6564, 0xffff6664, 0xffff6764, 0xffff6864,
0xffff6964, 0xffff6a64, 0xffff6c64, 0xffff6d64, 0xffff6e64, 0xffff6f64, 0xffff7064, 0xffff7264,
0xffff7364, 0xffff7564, 0xffff7664, 0xffff7764, 0xffff7964, 0xffff1f65, 0xffff2065, 0xffff2165,
0xffff2765, 0xffff2965, 0xffff2c65, 0xffff2d65, 0xffff2e65, 0xffff3a65, 0xffff3f65, 0xffff6165,
0xffff6265, 0xffff6365, 0xffff6465, 0xffff6565, 0xffff6665, 0xffff6765, 0xffff6865, 0xffff6965,
0xffff6b65, 0xffff6c65, 0xffff6d65, 0xffff6e65, 0xffff6f65, 0xffff7065, 0xffff7165, 0xffff7265,
0xffff7365, 0xffff7465, 0xffff7565, 0xffff7665, 0xffff7765, 0xffff7865, 0xffff7965, 0xffff7a65,
0xffff9465, 0xffff1f66, 0xffff2066, 0xffff2166, 0xffff2766, 0xffff2c66, 0xffff2d66, 0xffff2e66,
0xffff3f66, 0xffff6166, 0xffff6566, 0xffff6666, 0xffff6966, 0xffff6c66, 0xffff6e66, 0xffff6f66,
0xffff7266, 0xffff7366, 0xffff7466, 0xffff7566, 0xffff7766, 0xffff7966, 0xffff9466, 0xffff1f67,
0xffff2067, 0xffff2167, 0xffff2767, 0xffff2c67, 0xffff2d67, 0xffff2e67, 0xffff3a67, 0xffff3f67,
0xffff6167, 0xffff6467, 0xffff6567, 0xffff6767, 0xffff6867, 0xffff6967, 0xffff6c67, 0xffff6d67,
0xffff6e67, 0xffff6f67, 0xffff7267, 0xffff7367, 0xffff7467, 0xffff7567, 0xffff7667, 0xffff7967,
0xffff1f68, 0xffff2068, 0xffff2168, 0xffff2768, 0xffff2c68, 0xffff2d68, 0xffff2e68, 0xffff3a68,
0xffff3f68, 0xffff6168, 0xffff6268, 0xffff6468, 0xffff6568, 0xffff6668, 0xffff6768, 0xffff6868,
0xffff6968, 0xffff6c68, 0xffff6d68, 0xffff6e68, 0xffff6f68, 0xffff7168, 0xffff7268, 0xffff7368,
0xffff7468, 0xffff7568, 0xffff7768, 0xffff7968, 0xffff9468, 0xffff1f69, 0xffff2069, 0xffff2169,
0xffff2c69, 0xffff2d69, 0xffff2e69, 0xffff3f69, 0xffff6169, 0xffff6269, 0xffff6369, 0xffff6469,
0xffff6569, 0xffff6669, 0xffff6769, 0xffff6969, 0xffff6b69, 0xffff6c69, 0xffff6d69, 0xffff6e69,
0xffff6f69, 0xffff7069, 0xffff7169, 0xffff7269, 0xffff7369, 0xffff7469, 0xffff7569, 0xffff7669,
0xffff7869, 0xffff7a69, 0xffff2d6a, 0xffff616a, 0xffff656a, 0xffff6f6a, 0xffff756a, 0xffff1f6b,
0xffff206b, 0xffff216b, 0xffff276b, 0xffff2c6b, 0xffff2d6b, 0xffff2e6b, 0xffff3f6b, 0xffff616b,
0xffff656b, 0xffff666b, 0xffff676b, 0xffff686b, 0xffff696b, 0xffff6c6b, 0xffff6e6b, 0xffff6f6b,
0xffff736b, 0xffff796b, 0xffff1f6c, 0xffff206c, 0xffff216c, 0xffff276c, 0xffff296c, 0xffff2c6c,
0xffff2d6c, 0xffff2e6c, 0xffff3a6c, 0xffff3f6c, 0xffff616c, 0xffff626c, 0xffff636c, 0xffff646c,
0xffff656c, 0xffff666c, 0xffff676c, 0xffff686c, 0xffff696c, 0xffff6b6c, 0xffff6c6c, 0xffff6d6c,
0xffff6e6c, 0xffff6f6c, 0xffff706c, 0xffff726c, 0xffff736c, 0xffff746c, 0xffff756c, 0xffff766c,
0xffff776c, 0xffff796c, 0xffff946c, 0xffff1f6d, 0xffff206d, 0xffff216d, 0xffff276d, 0xffff2c6d,
0xffff2d6d, 0xffff2e6d, 0xffff3a6d, 0xffff3f6d, 0xffff616d, 0xffff626d, 0xffff656d, 0xffff666d,
0xffff696d, 0xffff6c6d, 0xffff6d6d, 0xffff6e6d, 0xffff6f6d, 0xffff706d, 0xffff726d, 0xffff736d,
0xffff746d, 0xffff756d, 0xffff796d, 0xffff1f6e, 0xffff206e, 0xffff216e, 0xffff276e, 0xffff296e,
0xffff2c6e, 0xffff2d6e, 0xffff2e6e, 0xffff3a6e, 0xffff3f6e, 0xffff616e, 0xffff626e, 0xffff636e,
0xffff646e, 0xffff656e, 0xffff666e, 0xffff676e, 0xffff686e, 0xffff696e, 0xffff6a6e, 0xffff6b6e,
0xffff6c6e, 0xffff6d6e, 0xffff6e6e, 0xffff6f6e, 0xffff706e, 0xffff716e, 0xffff726e, 0xffff736e,
0xffff746e, 0xffff756e, 0xffff766e, 0xffff776e, 0xffff786e, 0xffff796e, 0xffff7a6e, 0xffff946e,
0xffff1f6f, 0xffff206f, 0xffff216f, 0xffff276f, 0xffff2c6f, 0xffff2d6f, 0xffff2e6f, 0xffff3f6f,
0xffff616f, 0xffff626f, 0xffff636f, 0xffff646f, 0xffff656f, 0xffff666f, 0xffff676f, 0xffff686f,
0xffff696f, 0xffff6a6f, 0xffff6b6f, 0xffff6c6f, 0xffff6d6f, 0xffff6e6f, 0xffff6f6f, 0xffff706f,
0xffff716f, 0xffff726f, 0xffff736f, 0xffff746f, 0xffff756f, 0xffff766f, 0xffff776f, 0xffff786f,
0xffff796f, 0xffff7a6f, 0xffff946f, 0xffff1f70, 0xffff2070, 0xffff2170, 0xffff2770, 0xffff2c70,
0xffff2d70, 0xffff2e70, 0xffff3a70, 0xffff3f70, 0xffff6170, 0xffff6470, 0xffff6570, 0xffff6870,
0xffff6970, 0xffff6c70, 0xffff6e70, 0xffff6f70, 0xffff7070, 0xffff7270, 0xffff7370, 0xffff7470,
0xffff7570, 0xffff7970, 0xffff7571, 0xffff1f72, 0xffff2072, 0xffff2172, 0xffff2772, 0xffff2c72,
0xffff2d72, 0xffff2e72, 0xffff3a72, 0xffff3f72, 0xffff6172, 0xffff6272, 0xffff6372, 0xffff6472,
0xffff6572, 0xffff6672, 0xffff6772, 0xffff6872, 0xffff6972, 0xffff6a72, 0xffff6b72, 0xffff6c72,
0xffff6d72, 0xffff6e72, 0xffff6f72, 0xffff7072, 0xffff7272, 0xffff7372, 0xffff7472, 0xffff7572,
0xffff7672, 0xffff7772, 0xffff7972, 0xffff9472, 0xffff1f73, 0xffff2073, 0xffff2173, 0xffff2773,
0xffff2c73, 0xffff2d73, 0xffff2e73, 0xffff2f73, 0xffff3a73, 0xffff3f73, 0xffff6173, 0xffff6273,
0xffff6373, 0xffff6473, 0xffff6573, 0xffff6673, 0xffff6773, 0xffff6873, 0xffff6973, 0xffff6b73,
0xffff6c73, 0xffff6d73, 0xffff6e73, 0xffff6f73, 0xffff7073, 0xffff7173, 0xffff7273, 0xffff7373,
0xffff7473, 0xffff7573, 0xffff7773, 0xffff7973, 0xffff1f74, 0xffff2074, 0xffff2174, 0xffff2774,
0xffff2974, 0xffff2c74, 0xffff2d74, 0xffff2e74, 0xffff3174, 0xffff3574, 0xffff3874, 0xffff3a74,
0xffff3f74, 0xffff6174, 0xffff6274, 0xffff6374, 0xffff6574, 0xffff6674, 0xffff6874, 0xffff6974,
0xffff6c74, 0xffff6d74, 0xffff6e74, 0xffff6f74, 0xffff7274, 0xffff7374, 0xffff7474, 0xffff7574,
0xffff7774, 0xffff7974, 0xffff7a74, 0xffff9474, 0xffff1f75, 0xffff2075, 0xffff2175, 0xffff2775,
0xffff2c75, 0xffff2d75, 0xffff2e75, 0xffff3a75, 0xffff3f75, 0xffff6175, 0xffff6275, 0xffff6375,
0xffff6475, 0xffff6575, 0xffff6675, 0xffff6775, 0xffff6875, 0xffff6975, 0xffff6c75, 0xffff6d75,
0xffff6e75, 0xffff6f75, 0xffff7075, 0xffff7275, 0xffff7375, 0xffff7475, 0xffff7575, 0xffff7875,
0xffff7975, 0xffff7a75, 0xffff1f76, 0xffff2c76, 0xffff2e76, 0xffff6176, 0xffff6576, 0xffff6976,
0xffff6f76, 0xffff7276, 0xffff7576, 0xffff7976, 0xffff1f77, 0xffff2077, 0xffff2177, 0xffff2777,
0xffff2977, 0xffff2c77, 0xffff2d77, 0xffff2e77, 0xffff3a77, 0xffff3f77, 0xffff6177, 0xffff6277,
0xffff6377, 0xffff6477, 0xffff6577, 0xffff6677, 0xffff6877, 0xffff6977, 0xffff6b77, 0xffff6c77,
0xffff6d77, 0xffff6e77, 0xffff6f77, 0xffff7277, 0xffff7377, 0xffff7777, 0xffff7977, 0xffff1f78,
0xffff2078, 0xffff2c78, 0xffff2d78, 0xffff2e78, 0xffff3278, 0xffff3478, 0xffff6178, 0xffff6378,
0xffff6578, 0xffff6878, 0xffff6978, 0xffff7078, 0xffff7478, 0xffff7578, 0xffff1f79, 0xffff2079,
0xffff2179, 0xffff2779, 0xffff2c79, 0xffff2d79, 0xffff2e79, 0xffff3a79, 0xffff3f79, 0xffff6179,
0xffff6279, 0xffff6379, 0xffff6479, 0xffff6579, 0xffff6779, 0xffff6879, 0xffff6979, 0xffff6c79,
0xffff6d79, 0xffff6e79, 0xffff6f79, 0xffff7079, 0xffff7279, 0xffff7379, 0xffff7479, 0xffff7579,
0xffff7679, 0xffff7779, 0xffff7a79, 0xffff9479, 0xffff1f7a, 0xffff207a, 0xffff217a, 0xffff2c7a,
0xffff2e7a, 0xffff3f7a, 0xffff617a, 0xffff627a, 0xffff657a, 0xffff697a, 0xffff6c7a, 0xffff6f7a,
0xffff797a, 0xffff7a7a, 0xffff4193, 0xffff4293, 0xffff4393, 0xffff4493, 0xffff4793, 0xffff4893,
0xffff4993, 0xffff4a93, 0xffff4b93, 0xffff4c93, 0xffff4d93, 0xffff4e93, 0xffff4f93, 0xffff5293,
0xffff5393, 0xffff5493, 0xffff5793, 0xffff5993, 0xffff6293, 0xffff6393, 0xffff6593, 0xffff6693,
0xffff6d93, 0xffff6e93, 0xffff6f93, 0xffff7393, 0xffff7493, 0xffff7793, 0xffff7993, 0xffff1f94,
0xffff2094, 0xffff2194, 0xffff3f94, 0xffffffff,
// non-leaf nodes
// lower 16 bits are the index of the left child
// upper 16 bits are the index of the right child
0x0023001e, 0x002f002d, 0x00380034, 0x00690068,
0x00870079, 0x00ce0097, 0x00d200cf, 0x00d400d3, 0x00d800d6, 0x00eb00e0, 0x00ee00ed, 0x00f000ef,
0x00f400f2, 0x00fa00f7, 0x01050103, 0x01070106, 0x01140111, 0x01210120, 0x01250123, 0x01270126,
0x01290128, 0x012c012b, 0x012e012d, 0x01340131, 0x01360135, 0x01420140, 0x01470145, 0x014b0149,
0x0150014c, 0x01530151, 0x01570156, 0x01590158, 0x01640161, 0x016b0167, 0x01760173, 0x017b017a,
0x01990184, 0x019b019a, 0x01a901a7, 0x01ac01aa, 0x01b901b8, 0x01bd01ba, 0x01c301bf, 0x01cc01c8,
0x01ce01cd, 0x01d101cf, 0x01d401d3, 0x01d701d6, 0x01e901da, 0x01f201ea, 0x020201f3, 0x02060204,
0x020c0209, 0x02170212, 0x021a0218, 0x02270226, 0x022e0228, 0x023a0236, 0x023d023b, 0x0246023e,
0x024c0248, 0x024f024d, 0x02560254, 0x0260025a, 0x02630262, 0x02700268, 0x02810272, 0x02890288,
0x02920291, 0x029a0298, 0x02a1029f, 0x02aa02a7, 0x02ac02ab, 0x02c002ad, 0x02c402c3, 0x02d202cf,
0x02db02d3, 0x02e302de, 0x02ed02e6, 0x02f102ef, 0x02f502f4, 0x02fd02f9, 0x03250307, 0x032b0327,
0x03360330, 0x033d033b, 0x03590352, 0x03a4035a, 0x03ae03a6, 0x03ce03c7, 0x03dc03da, 0x03f603eb,
0x040a03fa, 0x0416040f, 0x043a0423, 0x04460441, 0x046c044f, 0x04880481, 0x04980492, 0x04f4049d,
0x04f604f5, 0x0513050a, 0x05290526, 0x0531052b, 0x053f0538, 0x05410540, 0x0552054d, 0x05650555,
0x056c0569, 0x0577056d, 0x0581057a, 0x058e058c, 0x0591058f, 0x05930592, 0x059c0597, 0x05a205a1,
0x05a505a4, 0x00460024, 0x006a0065, 0x0072006f, 0x0088007a, 0x0092008c, 0x00c90096, 0x00dc00db,
0x00e300dd, 0x00ec00ea, 0x00f300f1, 0x010400f6, 0x013a010b, 0x013d013b, 0x01460141, 0x01520148,
0x015f0154, 0x01630162, 0x016e0169, 0x01780172, 0x01a501a3, 0x01ae01ab, 0x01bb01b7, 0x01c001bc,
0x01d801d0, 0x021601f4, 0x021c021b, 0x022c021e, 0x023c0239, 0x024a0247, 0x025c024e, 0x026c0267,
0x0275026d, 0x0280027e, 0x02850284, 0x02870286, 0x02970296, 0x02a3029b, 0x02b702a9, 0x02c602c1,
0x02d102cc, 0x02e102dc, 0x02f002e2, 0x034802f3, 0x03940356, 0x03e303d5, 0x041a040b, 0x046f0432,
0x04cb04bd, 0x04fa04d3, 0x0527050b, 0x0546053c, 0x05540551, 0x058d058b, 0x05950594, 0x059b0596,
0x059e059d, 0x05a3059f, 0x05a905a6, 0x05ad05ac, 0x05af05ae, 0x05b105b0, 0x05b305b2, 0x05b505b4,
0x05b705b6, 0x05b905b8, 0x05bb05ba, 0x05bd05bc, 0x05bf05be, 0x05c105c0, 0x05c305c2, 0x05c505c4,
0x05c705c6, 0x05c905c8, 0x05cb05ca, 0x05cd05cc, 0x05cf05ce, 0x05d105d0, 0x05d305d2, 0x05d505d4,
0x05d705d6, 0x05d905d8, 0x05db05da, 0x05dd05dc, 0x05df05de, 0x05e105e0, 0x05e305e2, 0x05e505e4,
0x05e705e6, 0x05e905e8, 0x05eb05ea, 0x05ed05ec, 0x05ef05ee, 0x05f105f0, 0x05f305f2, 0x05f505f4,
0x05f705f6, 0x05f905f8, 0x05fb05fa, 0x05fd05fc, 0x05ff05fe, 0x06010600, 0x06030602, 0x06050604,
0x06070606, 0x06090608, 0x060b060a, 0x060d060c, 0x060f060e, 0x06110610, 0x06130612, 0x06150614,
0x06170616, 0x06190618, 0x061b061a, 0x061d061c, 0x061f061e, 0x00180620, 0x001f001c, 0x00530052,
0x00570055, 0x006c0062, 0x00750073, 0x00780076, 0x008b007b, 0x00de0090, 0x00e200df, 0x010800f8,
0x010e010c, 0x01120110, 0x01160113, 0x011c011a, 0x013e0132, 0x015a014f, 0x0160015b, 0x016a0168,
0x01920186, 0x01b00196, 0x01db01d2, 0x01f101e8, 0x020101f7, 0x020e0203, 0x022d021d, 0x02370234,
0x024b0249, 0x02690265, 0x027a026b, 0x02a602a5, 0x02e502af, 0x031702fb, 0x03260322, 0x039e0390,
0x03e103b7, 0x0422041d, 0x04530438, 0x04660461, 0x0496048f, 0x04e604a2, 0x051104f0, 0x0548053a,
0x055d0553, 0x058a0587, 0x0016059a, 0x00710050, 0x0080007d, 0x0093008f, 0x00d50094, 0x0139010d,
0x014a013f, 0x015c014d, 0x0166015d, 0x018c0177, 0x01950194, 0x01a80198, 0x01e701cb, 0x022f01fe,
0x02d002a8, 0x02fe02ec, 0x03230305, 0x03660351, 0x0371036b, 0x03c5038f, 0x040203de, 0x04090404,
0x04b20456, 0x04f704d4, 0x057e052a, 0x05900582, 0x05a00598, 0x06220621, 0x06240623, 0x06260625,
0x06280627, 0x062a0629, 0x062c062b, 0x062e062d, 0x0630062f, 0x06320631, 0x06340633, 0x06360635,
0x06380637, 0x063a0639, 0x063c063b, 0x063e063d, 0x0640063f, 0x06420641, 0x06440643, 0x06460645,
0x06480647, 0x064a0649, 0x064c064b, 0x064e064d, 0x0650064f, 0x06520651, 0x06540653, 0x06560655,
0x06580657, 0x065a0659, 0x065c065b, 0x065e065d, 0x0660065f, 0x06620661, 0x06640663, 0x06660665,
0x06680667, 0x066a0669, 0x066c066b, 0x066e066d, 0x0670066f, 0x06720671, 0x06740673, 0x06760675,
0x06780677, 0x067a0679, 0x067c067b, 0x067e067d, 0x0680067f, 0x06820681, 0x06840683, 0x06860685,
0x06880687, 0x068a0689, 0x068c068b, 0x068e068d, 0x0690068f, 0x06920691, 0x06940693, 0x004d004c,
0x0051004e, 0x0074005c, 0x007c0077, 0x0091007f, 0x00fe00b0, 0x0137010a, 0x01790138, 0x017e017d,
0x01b20191, 0x025701be, 0x026e0266, 0x02a40299, 0x02d802d4, 0x03a102f6, 0x03df03cd, 0x04640448,
0x04e504dc, 0x052c0501, 0x057b0559, 0x00170695, 0x004f004b, 0x006d0056, 0x00810070, 0x00d70083,
0x011f00f9, 0x017c0165, 0x01ad0188, 0x01e301ca, 0x0223021f, 0x026f0232, 0x02ae027d, 0x02c202b1,
0x02ff02fc, 0x033c0328, 0x03a50380, 0x03d203ac, 0x045c03f8, 0x054304d1, 0x05aa054f, 0x06970696,
0x06990698, 0x069b069a, 0x069d069c, 0x069f069e, 0x06a106a0, 0x06a306a2, 0x06a506a4, 0x06a706a6,
0x06a906a8, 0x06ab06aa, 0x06ad06ac, 0x06af06ae, 0x06b106b0, 0x06b306b2, 0x06b506b4, 0x06b706b6,
0x06b906b8, 0x06bb06ba, 0x06bd06bc, 0x06bf06be, 0x06c106c0, 0x00580054, 0x005a0059, 0x00d1005b,
0x010100ff, 0x01430115, 0x0200016c, 0x02710244, 0x0282027c, 0x02bf028c, 0x03750354, 0x03ca03c3,
0x043f0418, 0x04750443, 0x04d7047f, 0x05330521, 0x057d0563, 0x06c20588, 0x008a006e, 0x0095008e,
0x012f00f5, 0x0174015e, 0x019e017f, 0x01ec01c9, 0x02e40283, 0x039602ee, 0x03be0398, 0x03dd03d7,
0x046b0465, 0x05990573, 0x06c406c3, 0x06c606c5, 0x06c806c7, 0x06ca06c9, 0x06cc06cb, 0x06ce06cd,
0x06d006cf, 0x06d206d1, 0x06d406d3, 0x06d606d5, 0x06d806d7, 0x06da06d9, 0x06dc06db, 0x06de06dd,
0x06e006df, 0x06e206e1, 0x06e406e3, 0x06e606e5, 0x06e806e7, 0x06ea06e9, 0x06ec06eb, 0x06ee06ed,
0x06f006ef, 0x06f206f1, 0x06f406f3, 0x06f606f5, 0x06f806f7, 0x06fa06f9, 0x06fc06fb, 0x06fe06fd,
0x070006ff, 0x07020701, 0x07040703, 0x07060705, 0x07080707, 0x070a0709, 0x070c070b, 0x070e070d,
0x0710070f, 0x07120711, 0x07140713, 0x07160715, 0x014e007e, 0x01900155, 0x028d027f, 0x033a02f7,
0x04fd03cb, 0x01090583, 0x01970118, 0x01ff01dd, 0x025d0219, 0x02950293, 0x033f02b5, 0x04d903e0,
0x07180717, 0x071a0719, 0x071c071b, 0x071e071d, 0x0720071f, 0x07220721, 0x07240723, 0x07260725,
0x07280727, 0x072a0729, 0x011700a8, 0x032e0181, 0x04db035f, 0x0578056a, 0x0089072b, 0x018300fd,
0x02770193, 0x02b60278, 0x03380321, 0x03d1034d, 0x046e0451, 0x057c0532, 0x072d072c, 0x072f072e,
0x07310730, 0x07330732, 0x07350734, 0x07370736, 0x07390738, 0x073b073a, 0x073d073c, 0x073f073e,
0x07410740, 0x07430742, 0x07450744, 0x07470746, 0x07490748, 0x074b074a, 0x074d074c, 0x074f074e,
0x07510750, 0x07530752, 0x006b0754, 0x00d90084, 0x01800144, 0x03930361, 0x043603aa, 0x01b30061,
0x01d501b6, 0x03e201fc, 0x05a704f2, 0x07560755, 0x07580757, 0x075a0759, 0x075c075b, 0x075e075d,
0x0760075f, 0x07620761, 0x07640763, 0x00670765, 0x011b00cd, 0x035d02d9, 0x049b0415, 0x054e04b0,
0x01d905a8, 0x025b0230, 0x02cd0261, 0x036a02ce, 0x03fb038a, 0x05470537, 0x0766057f, 0x07680767,
0x076a0769, 0x076c076b, 0x076e076d, 0x0770076f, 0x07720771, 0x07740773, 0x07760775, 0x07780777,
0x077a0779, 0x077c077b, 0x077e077d, 0x0780077f, 0x07820781, 0x07840783, 0x07860785, 0x07880787,
0x078a0789, 0x078c078b, 0x078e078d, 0x0790078f, 0x07920791, 0x07940793, 0x07960795, 0x07980797,
0x079a0799, 0x0015079b, 0x01a6008d, 0x03cf03b1, 0x042803f2, 0x05360502, 0x05850550, 0x01190047,
0x037302a2, 0x04910411, 0x055604b5, 0x0580055a, 0x079d079c, 0x079f079e, 0x032407a0, 0x07a1041e,
0x03340064, 0x07a20401, 0x07a407a3, 0x07a607a5, 0x07a807a7, 0x07aa07a9, 0x07ac07ab, 0x07ae07ad,
0x07b007af, 0x005d07b1, 0x01a4012a, 0x02ba0205, 0x03860363, 0x051a045e, 0x0100005e, 0x02580252,
0x033e032a, 0x07b20557, 0x07b407b3, 0x01ee07b5, 0x026a0253, 0x05280333, 0x013307b6, 0x028f01b5,
0x02f202bd, 0x057103d3, 0x07b807b7, 0x07ba07b9, 0x07bc07bb, 0x07be07bd, 0x07c007bf, 0x07c207c1,
0x07c407c3, 0x07c607c5, 0x07c807c7, 0x07ca07c9, 0x07cc07cb, 0x07ce07cd, 0x07d007cf, 0x002907d1,
0x0049002e, 0x02b80294, 0x07d2034a, 0x003e0030, 0x021401a0, 0x07d302c9, 0x07d507d4, 0x002707d6,
0x0033002c, 0x00820066, 0x03bc0395, 0x003b049a, 0x01e200ac, 0x049503bf, 0x056f04cf, 0x07d807d7,
0x07da07d9, 0x07dc07db, 0x07de07dd, 0x07e007df, 0x07e207e1, 0x003f0032, 0x01e10130, 0x030d01f9,
0x0570035e, 0x003707e3, 0x003c0039, 0x01240063, 0x0586013c, 0x07e507e4, 0x07e707e6, 0x002b002a,
0x0043003d, 0x01e6010f, 0x004207e8, 0x019f0060, 0x04c90215, 0x05ab0579, 0x07ea07e9, 0x07ec07eb,
0x07ee07ed, 0x07f007ef, 0x07f207f1, 0x07f407f3, 0x07f607f5, 0x07f807f7, 0x07fa07f9, 0x07fc07fb,
0x07fe07fd, 0x080007ff, 0x08020801, 0x08040803, 0x08060805, 0x08080807, 0x02be0028, 0x031f02da,
0x08090406, 0x003a0021, 0x005f0044, 0x042b0221, 0x04970435, 0x080b080a, 0x080d080c, 0x00ca080e,
0x042f01de, 0x03080045, 0x053d0403, 0x0810080f, 0x08120811, 0x08140813, 0x00350815, 0x016d00d0,
0x01df018f, 0x028a0235, 0x03b30312, 0x055b054b, 0x00070816, 0x081703a9, 0x05890567, 0x04720378,
0x081804ae, 0x081a0819, 0x081c081b, 0x081e081d, 0x0820081f, 0x01820086, 0x04eb043b, 0x004a0821,
0x0558025e, 0x08230822, 0x08250824, 0x02430040, 0x035b0309, 0x022b051c, 0x08260568, 0x08280827,
0x082a0829, 0x03b8082b, 0x057404c3, 0x082d082c, 0x041b0048, 0x082e050e, 0x082f055c, 0x08310830,
0x08330832, 0x08350834, 0x08370836, 0x08390838, 0x083b083a, 0x083d083c, 0x027b083e, 0x041402cb,
0x083f0561, 0x02df0233, 0x08400350, 0x08420841, 0x01fd001b, 0x0477022a, 0x03c20362, 0x08440843,
0x08460845, 0x040d0279, 0x01f80847, 0x049302d5, 0x08490848, 0x0584084a, 0x01c6084b, 0x04b90229,
0x084d084c, 0x084f084e, 0x08510850, 0x08530852, 0x018a0854, 0x01f501e5, 0x03030341, 0x08560855,
0x08580857, 0x04a900a6, 0x02d60859, 0x085a0427, 0x085c085b, 0x085e085d, 0x029e0185, 0x02e002a0,
0x00da0006, 0x085f0251, 0x08610860, 0x027301b1, 0x08630862, 0x08650864, 0x08670866, 0x08690868,
0x086b086a, 0x086d086c, 0x086f086e, 0x08710870, 0x08730872, 0x08750874, 0x00ad03af, 0x0876046a,
0x08780877, 0x03fc019c, 0x054c045a, 0x087a0879, 0x087c087b, 0x087e087d, 0x04a80478, 0x0031087f,
0x01c400a1, 0x04790469, 0x020f0880, 0x08820881, 0x08840883, 0x025f0885, 0x08860516, 0x0397023f,
0x04e10499, 0x08880887, 0x088a0889, 0x0171088b, 0x02bc018e, 0x0566088c, 0x0241088d, 0x00e1088e,
0x03f90339, 0x04bb042e, 0x051804e0, 0x0890088f, 0x08920891, 0x08940893, 0x028b044d, 0x04370302,
0x053004b3, 0x08950534, 0x02380896, 0x0897029c, 0x08990898, 0x001a089a, 0x01ed00a5, 0x02d70242,
0x089c089b, 0x089e089d, 0x08a0089f, 0x02ea0041, 0x047e0454, 0x02eb03b6, 0x04c804ad, 0x040508a1,
0x08a2051f, 0x035708a3, 0x04300425, 0x08a508a4, 0x036901c7, 0x01a103e5, 0x02dd01fa, 0x05080490,
0x08a708a6, 0x08a908a8, 0x08ab08aa, 0x08ad08ac, 0x02c508ae, 0x08b008af, 0x03f103ab, 0x047303ff,
0x039d047a, 0x08b208b1, 0x047408b3, 0x08b40560, 0x00c108b5, 0x04fb03fd, 0x019d0576, 0x032d01e4,
0x08b708b6, 0x027608b8, 0x08ba08b9, 0x01eb0020, 0x04a602c7, 0x08bc08bb, 0x01c108bd, 0x04ce03c8,
0x047c08be, 0x08c008bf, 0x08c208c1, 0x03c408c3, 0x020a08c4, 0x08c504a7, 0x056e02ca, 0x030408c6,
0x08c7037e, 0x03bb08c8, 0x0099042a, 0x053900a2, 0x08c9053b, 0x08ca0460, 0x08cb03db, 0x08cd08cc,
0x08ce04e2, 0x025508cf, 0x08d003d9, 0x08d208d1, 0x02100384, 0x000f08d3, 0x0367031e, 0x08d404bf,
0x08d608d5, 0x08d808d7, 0x08da08d9, 0x08dc08db, 0x02e708dd, 0x05140447, 0x08df08de, 0x04df08e0,
0x04ee04ea, 0x08e208e1, 0x02b40364, 0x08e408e3, 0x028e08e5, 0x08e601f6, 0x02310019, 0x08e70410,
0x08e908e8, 0x03a2037d, 0x08ea0515, 0x044203bd, 0x08ec08eb, 0x08ee08ed, 0x034604ba, 0x08ef04d8,
0x08f108f0, 0x036c08f2, 0x042d038c, 0x08f408f3, 0x08f50189, 0x00260391, 0x08f60310, 0x052d020b,
0x08f7009a, 0x08f802b3, 0x018708f9, 0x08fb08fa, 0x08fd08fc, 0x08fe0012, 0x01ef01c2, 0x090008ff,
0x09020901, 0x05490903, 0x04390904, 0x09060905, 0x0421039b, 0x09080907, 0x034c0433, 0x090a0909,
0x009800e4, 0x090b042c, 0x0337090c, 0x090d0222, 0x090e0036, 0x090f04aa, 0x02450910, 0x09120911,
0x038d009f, 0x091303c6, 0x041701e0, 0x02240914, 0x09150300, 0x091602bb, 0x09180917, 0x091a0919,
0x01af091b, 0x000e030e, 0x091c04be, 0x091d00e5, 0x04760240, 0x091f091e, 0x009d0920, 0x092102b0,
0x0207009b, 0x092203a3, 0x0923051d, 0x09250924, 0x04120926, 0x09270575, 0x00af0928, 0x092904d5,
0x04a00306, 0x037f0509, 0x00a4092a, 0x050c045f, 0x092c092b, 0x031c092d, 0x092e0376, 0x00c60004,
0x03ad01f0, 0x092f00a7, 0x02500930, 0x09320931, 0x09330510, 0x03a70385, 0x04500934, 0x09360935,
0x09370005, 0x00e90938, 0x043d0939, 0x093b093a, 0x036f093c, 0x0480093d, 0x093f093e, 0x00250332,
0x03440940, 0x01750941, 0x094200ae, 0x09430522, 0x0944049f, 0x01b400a3, 0x09460945, 0x00ba0947,
0x09490948, 0x094b094a, 0x094c0512, 0x03fe0353, 0x0482094d, 0x094e04f8, 0x048d03c0, 0x04af0368,
0x094f04c7, 0x025903d6, 0x09500494, 0x04c00951, 0x09520517, 0x046d0407, 0x05190953, 0x01dc0954,
0x03ba0955, 0x02b2056b, 0x09570956, 0x0958018d, 0x051b020d, 0x04700959, 0x0462095a, 0x095c095b,
0x0419095d, 0x095f095e, 0x05000960, 0x09620961, 0x096304b6, 0x096403b5, 0x04a40965, 0x037c0966,
0x0445047b, 0x096704e4, 0x096802b9, 0x096903b0, 0x00e6052f, 0x096b096a, 0x00a9096c, 0x096d0562,
0x096f096e, 0x09710970, 0x03130170, 0x097204c1, 0x00ab009e, 0x0973044b, 0x0487032f, 0x097403f7,
0x03990975, 0x0220049c, 0x09770976, 0x000201fb, 0x037000cc, 0x09790978, 0x055e097a, 0x097c097b,
0x01020349, 0x01c5097d, 0x097f097e, 0x05070505, 0x00fb0980, 0x040c0981, 0x09830982, 0x03e40984,
0x09850449, 0x09870986, 0x09880358, 0x03e903a0, 0x04f10989, 0x098b098a, 0x034b098c, 0x0011098d,
0x098f098e, 0x04a10990, 0x04ef0991, 0x038e0085, 0x09930992, 0x0345030a, 0x099400bb, 0x04a30995,
0x09970996, 0x04ab029d, 0x099804b1, 0x09990329, 0x0335099a, 0x099c099b, 0x0331099d, 0x0483099e,
0x099f0290, 0x04c609a0, 0x09a209a1, 0x09a3048a, 0x09a509a4, 0x09a60274, 0x035509a7, 0x09a803f0,
0x00aa0440, 0x09aa09a9, 0x09ac09ab, 0x09ae09ad, 0x09af045d, 0x03150379, 0x09b109b0, 0x03ec09b2,
0x000809b3, 0x031809b4, 0x018b02f8, 0x09b503e6, 0x04520564, 0x09b709b6, 0x09b909b8, 0x09ba00e8,
0x039a04b7, 0x09bc09bb, 0x034e09bd, 0x09bf09be, 0x09c109c0, 0x09c204e9, 0x009c09c3, 0x038b09c4,
0x04ca09c5, 0x09c709c6, 0x03e70264, 0x020801a2, 0x09c804d6, 0x046709c9, 0x050609ca, 0x09cc09cb,
0x09ce09cd, 0x09cf0372, 0x04c4001d, 0x04a509d0, 0x04f309d1, 0x09d309d2, 0x03b909d4, 0x09d5039c,
0x000d09d6, 0x09d809d7, 0x09d9040e, 0x09da0360, 0x09db00c5, 0x04d009dc, 0x045709dd, 0x030f09de,
0x09df041c, 0x09e003f3, 0x045509e1, 0x050f09e2, 0x09e409e3, 0x053509e5, 0x048609e6, 0x040009e7,
0x04de09e8, 0x09ea09e9, 0x09eb000a, 0x03e809ec, 0x09ee09ed, 0x044a0225, 0x044404dd, 0x09f009ef,
0x09f104ec, 0x031d09f2, 0x09f409f3, 0x09f503d8, 0x042909f6, 0x09f809f7, 0x04cc02e8, 0x09f90544,
0x09fb09fa, 0x09fd09fc, 0x052003b2, 0x032009fe, 0x0a0009ff, 0x0a0103ea, 0x03820a02, 0x0a040a03,
0x000b0a05, 0x03ee0a06, 0x0a0704c5, 0x054a0408, 0x05040a08, 0x0a0a0a09, 0x049e0a0b, 0x0a0d0a0c,
0x043100b5, 0x0a0e0343, 0x0a100a0f, 0x0a1104e7, 0x0a130a12, 0x05250a14, 0x0a15051e, 0x04f90a16,
0x0a180a17, 0x037b041f, 0x03890a19, 0x03ed0a1a, 0x0a1b044e, 0x030c03c1, 0x043c0a1c, 0x030b0a1d,
0x00cb0a1e, 0x039f0a1f, 0x03470a20, 0x0a2103d4, 0x0a230a22, 0x0a240311, 0x0a260a25, 0x0a270484,
0x0a290a28, 0x0a2a04d2, 0x03b40a2b, 0x00b70a2c, 0x0a2e0a2d, 0x0a2f0545, 0x0a310a30, 0x02e90a32,
0x0a340a33, 0x0a360a35, 0x0a370340, 0x0a390a38, 0x00c00a3a, 0x04680524, 0x0a3b0365, 0x04e300c2,
0x0a3c048b, 0x0a3e0a3d, 0x0a3f0542, 0x0a40036d, 0x03740a41, 0x0a4204ff, 0x03920434, 0x042404c2,
0x04b40a43, 0x048e0a44, 0x0a45053e, 0x0a470a46, 0x0a490a48, 0x0a4b0a4a, 0x00be0a4c, 0x035c0a4d,
0x0a4f0a4e, 0x0a50047d, 0x0a510342, 0x00bc0a52, 0x0a540a53, 0x0a560a55, 0x02130301, 0x0a580a57,
0x00e70a59, 0x0a5a016f, 0x0a5b04bc, 0x0381031a, 0x02fa0463, 0x03a80a5c, 0x032c0a5d, 0x0a5f0a5e,
0x00220a60, 0x0a620a61, 0x0a640a63, 0x00b40523, 0x041303d0, 0x0a660a65, 0x0a680a67, 0x0a6a0a69,
0x0a6c0a6b, 0x011e0a6d, 0x0a6f0a6e, 0x04fc0a70, 0x0a720a71, 0x0a740a73, 0x0a750314, 0x00b30a76,
0x00a00a77, 0x0a790a78, 0x0a7a0420, 0x00b60a7b, 0x037a0a7c, 0x0a7e0a7d, 0x037702c8, 0x0a800a7f,
0x04590a81, 0x04da0a82, 0x04580a83, 0x0a850a84, 0x0a870a86, 0x0a880489, 0x00100a89, 0x0a8b0a8a,
0x0a8d0a8c, 0x0a8f0a8e, 0x0a910a90, 0x03190a92, 0x03f40a93, 0x0a940388, 0x03f50a95, 0x0a970a96,
0x0a990a98, 0x043e0a9a, 0x055f00b2, 0x0a9c0a9b, 0x0a9e0a9d, 0x0aa00a9f, 0x0aa1050d, 0x04e80aa2,
0x04260aa3, 0x00bf045b, 0x00b90aa4, 0x00b80aa5, 0x0aa6052e, 0x0aa80aa7, 0x03830aa9, 0x044c0aaa,
0x00140aab, 0x0aad0aac, 0x0aae00bd, 0x00c80aaf, 0x0ab00485, 0x0ab20ab1, 0x0ab303c9, 0x0ab50ab4,
0x0ab70ab6, 0x04ac0503, 0x04710ab8, 0x0aba0ab9, 0x0abc0abb, 0x0abe0abd, 0x0ac00abf, 0x0ac100c3,
0x00000211, 0x0ac30ac2, 0x0ac50ac4, 0x05720ac6, 0x0ac80ac7, 0x0ac90316, 0x031b00c7, 0x0acb0aca,
0x0acd0acc, 0x0acf0ace, 0x00fc0ad0, 0x0ad20ad1, 0x0ad40ad3, 0x0ad50387, 0x0ad70ad6, 0x0ad90ad8,
0x034f0ada, 0x04b8000c, 0x00090adb, 0x0add0adc, 0x03cc0ade, 0x0ae00adf, 0x0ae103ef, 0x0ae30ae2,
0x0ae50ae4, 0x0ae6048c, 0x00b104cd, 0x0ae80ae7, 0x0aea0ae9, 0x0aec0aeb, 0x0aed0122, 0x0aef0aee,
0x0af10af0, 0x0af30af2, 0x0af50af4, 0x04ed0af6, 0x0af80af7, 0x0afa0af9, 0x0afc0afb, 0x04fe0afd,
0x0aff0afe, 0x0b010b00, 0x0b030b02, 0x0b050b04, 0x0b070b06, 0x0b0800c4, 0x0b0a0b09, 0x0b0c0b0b,
0x0b0e0b0d, 0x0b100b0f, 0x0b120b11, 0x0b140b13, 0x0b160b15, 0x036e011d, 0x00130b17, 0x0b190b18,
0x0b1b0b1a, 0x0b1d0b1c, 0x0b1f0b1e, 0x0b210b20, 0x0b230b22, 0x0b250b24, 0x0b270b26, 0x0b290b28,
0x0b2b0b2a, 0x0b2d0b2c, 0x0b2f0b2e, 0x0b300003, 0x0b320b31, 0x0b340b33, 0x00010b35, 0x0b370b36,
0x0b390b38, 0x0b3b0b3a, 0x0b3d0b3c, 0x0b3f0b3e, 0x0b410b40, 0x0b430b42, 0x0b450b44, 0x0b470b46,
0x0b490b48, 0x0b4b0b4a, 0x0b4d0b4c, 0x0b4f0b4e, 0x0b510b50, 0x0b530b52,
// last element is the root node
0x0b550b54,
};
static FILE *outCFile;
FILE *outHFile;
// searches tree for value, and appends the Huffman to the output
int compress_value_recursive(int node, uint16_t value, uint8_t *output, unsigned int *bit)
{
uint16_t lopart = (uint16_t)node;
uint16_t hipart = (uint16_t)(node >> 16);
if (hipart == 0xFFFF) // leaf node
{
// leaf node
// The upper 16 bits of a leaf node are always 0xFFFF.
// The lower 16 bits are the output data.
if (lopart == value)
return 1; // found the value
else
return 0;
}
else
{
unsigned int byte = *bit / 8;
unsigned int bit_ = *bit % 8;
// non-leaf node
// The upper 16 bits of the node are the right child index
// The lower 16 bits of the node are the left child index
// search left child
(*bit)++;
if (compress_value_recursive(huffmanTable[lopart], value, output, bit))
{
// clear current output bit because value was found
// in left subtree
output[byte] &= ~(1 << bit_);
return 1;
}
(*bit)--;
// search right child
(*bit)++;
if (compress_value_recursive(huffmanTable[hipart], value, output, bit))
{
// set current output bit because value was found
// in right subtree
output[byte] |= (1 << bit_);
return 1;
}
(*bit)--;
// not found
return 0;
}
}
int compress_string(uint8_t *input, uint8_t *output)
{
unsigned int value;
unsigned int size;
unsigned int bit = 0;
// Root node is the last element of the table.
const int rootNode = huffmanTable[ARRAY_COUNT(huffmanTable) - 1];
while (1)
{
switch (*input)
{
case 0x80:
// 1-byte
value = *input++;
if (!compress_value_recursive(rootNode, value, output, &bit))
goto error;
// 1-byte
value = *input++;
if (!compress_value_recursive(rootNode, value, output, &bit))
goto error;
break;
case 0x10:
// 1-byte
value = *input++;
if (!compress_value_recursive(rootNode, value, output, &bit))
goto error;
// 2-byte
value = *input++;
value |= *input++ << 8;
if (!compress_value_recursive(rootNode, value, output, &bit))
goto error;
break;
default:
if (*input >= 0x20)
{
// 2-byte
value = *input++;
value |= *input++ << 8;
if (!compress_value_recursive(rootNode, value, output, &bit))
goto error;
break;
}
// else fall through
case '#':
case 0x7F:
case 0xE9:
// 1-byte
value = *input++;
if (!compress_value_recursive(rootNode, value, output, &bit))
goto error;
if (value == 0)
goto done;
break;
}
}
done:
size = bit / 8;
// handle partial byte
if (bit % 8 != 0)
{
size++;
// clear out any garbage remaining in the rest of the byte
output[bit / 8] &= (1 << (bit % 8)) - 1;
}
return size;
error:
FATAL_ERROR("could not compress value 0x%X\n", value);
}
static void print_compressed_string(const char *id, const uint8_t *compressed, int compressedLength)
{
int i;
fprintf(outCFile, "const u8 gCompressedText_%s[] = {", id);
for (i = 0; i < compressedLength - 1; i++)
fprintf(outCFile, "0x%02X, ", compressed[i]);
fprintf(outCFile, "0x%02X};\n", compressed[i]);
}
void print_bytes(const uint8_t *bytes, int length)
{
int i;
for (i = 0; i < length - 1; i++)
fprintf(outCFile, "0x%02X, ", bytes[i]);
fprintf(outCFile, "0x%02X", bytes[i]);
}
static void write_c_file(const char *filename)
{
int i;
uint8_t outputBuffer[10000];
int size;
outCFile = fopen(filename, "wb");
if (outCFile == NULL)
FATAL_ERROR("failed to open file '%s' for writing\n", filename);
fputs("#include \"global.h\"\n\n", outCFile);
// compressed string data
for (i = 0; i < gInputStringsCount; i++)
{
size = compress_string((uint8_t *)gInputStrings[i].text, outputBuffer);
print_compressed_string(gInputStrings[i].id, outputBuffer, size);
}
fputs("\n", outCFile);
// Huffman table
fprintf(outCFile, "const u32 gMsgHuffmanTable[] =\n{");
for (i = 0; i < (int)ARRAY_COUNT(huffmanTable); i++)
{
if (i % 8 == 0)
fprintf(outCFile, "\n ");
fprintf(outCFile, "0x%08X, ", (uint32_t)huffmanTable[i]);
}
fputs("\n};\n\n", outCFile);
// pointer to root node of Huffman tree
fprintf(outCFile, "const u32 *const gMsgHuffmanTableRoot = gMsgHuffmanTable + %lu;\n\n", ARRAY_COUNT(huffmanTable) - 1);
// string table
fputs("const u8 *const gMsgStringTable[] =\n{\n", outCFile);
for (i = 0; i < gInputStringsCount; i++)
fprintf(outCFile, " gCompressedText_%s,\n", gInputStrings[i].id);
fputs("};\n", outCFile);
}
int main(int argc, char **argv)
{
if (argc != 4)
FATAL_ERROR("usage:\n%s STRING_LIST C_FILE H_FILE\n", argv[0]);
read_input_file(argv[1]);
write_c_file(argv[2]);
return 0;
}

View File

@ -0,0 +1,28 @@
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
#define FATAL_ERROR(message, ...) \
do { \
fprintf(stderr, message, ##__VA_ARGS__); \
exit(1); \
} while (0)
struct String
{
char *id;
char *text;
};
extern struct String *gInputStrings;
extern int gInputStringsCount;
void read_input_file(const char *name);