mirror of
https://github.com/pret/pokeplatinum.git
synced 2024-11-23 13:59:53 +00:00
Move gen_fx_consts to NitroSDK folder
This commit is contained in:
parent
31fc5236cb
commit
ef8cd95c12
138
lib/external/NitroSDK/autogen/nitro/fx/gen_fx_const.py
vendored
Normal file
138
lib/external/NitroSDK/autogen/nitro/fx/gen_fx_const.py
vendored
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
class FxSpec:
|
||||||
|
intpart_dict = {
|
||||||
|
'fx32': 19,
|
||||||
|
'fx64': 51,
|
||||||
|
'fx64c': 31,
|
||||||
|
'fx16': 3
|
||||||
|
}
|
||||||
|
|
||||||
|
fracpart_dict = {
|
||||||
|
'fx32': 12,
|
||||||
|
'fx64': 12,
|
||||||
|
'fx64c': 32,
|
||||||
|
'fx16': 12
|
||||||
|
}
|
||||||
|
|
||||||
|
l_suffix_dict = {
|
||||||
|
'fx32': 'L',
|
||||||
|
'fx64': 'LL',
|
||||||
|
'fx64c': 'LL',
|
||||||
|
'fx16': ''
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, name: str) -> 'FxSpec':
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def intpart(self):
|
||||||
|
return self._intpart
|
||||||
|
|
||||||
|
@intpart.getter
|
||||||
|
def intpart(self):
|
||||||
|
return self.intpart_dict[self.name]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fracpart(self):
|
||||||
|
return self._fracpart
|
||||||
|
|
||||||
|
@fracpart.getter
|
||||||
|
def fracpart(self):
|
||||||
|
return self.fracpart_dict[self.name]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def l_suffix(self):
|
||||||
|
return self._l_suffix
|
||||||
|
|
||||||
|
@l_suffix.getter
|
||||||
|
def l_suffix(self):
|
||||||
|
return self.l_suffix_dict[self.name]
|
||||||
|
|
||||||
|
|
||||||
|
class FxConst:
|
||||||
|
def __init__(self, name: str, fxtype: FxSpec, value: float) -> 'FxConst':
|
||||||
|
self.fxtype = fxtype
|
||||||
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@name.setter
|
||||||
|
def name(self, value: str):
|
||||||
|
self._name = f'{self.fxtype.name.upper()}_{value}'
|
||||||
|
|
||||||
|
def encode(self) -> int:
|
||||||
|
if self.value == 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
ret_di = 0.0
|
||||||
|
ret_df = 0.0
|
||||||
|
value_abs = 0.0
|
||||||
|
ret_ii = 0
|
||||||
|
ret_if = 0
|
||||||
|
ret_val = 0
|
||||||
|
|
||||||
|
value_abs = abs(self.value)
|
||||||
|
ret_di = math.floor(value_abs)
|
||||||
|
ret_df = value_abs - ret_di
|
||||||
|
ret_ii = int(value_abs * (1 << self.fxtype.fracpart))
|
||||||
|
ret_if = int(ret_df * (1 << self.fxtype.fracpart) + 0.5)
|
||||||
|
ret_ii &= ~((1 << self.fxtype.fracpart) - 1)
|
||||||
|
ret_if &= (1 << self.fxtype.fracpart) - 1
|
||||||
|
ret_val = ret_ii + ret_if
|
||||||
|
|
||||||
|
if self.value < 0:
|
||||||
|
ret_val = -ret_val
|
||||||
|
|
||||||
|
return ret_val
|
||||||
|
|
||||||
|
|
||||||
|
def generate_define(c: FxConst) -> str:
|
||||||
|
hex_value = f'(({c.fxtype.name}) 0x{hex(c.encode())[2:].zfill(16)}{c.fxtype.l_suffix})'
|
||||||
|
comment = f'// {c.value:.12f}'
|
||||||
|
|
||||||
|
return f'#define {c.name: <20} {hex_value: ^20} {comment: >25}'
|
||||||
|
|
||||||
|
|
||||||
|
def generate_header(constants: list[FxConst]) -> str:
|
||||||
|
guard_top = '\n'.join(['#ifndef FX_CONST_H', '#define FX_CONST_H', str()])
|
||||||
|
body = '\n'.join(generate_define(c) for c in constants)
|
||||||
|
guard_bottom = '\n'.join(['', '#endif // FX_CONST_H', ''])
|
||||||
|
|
||||||
|
return '\n'.join([guard_top, body, guard_bottom])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
constants = parse_csv(args.input)
|
||||||
|
header = generate_header(constants)
|
||||||
|
with open(args.output, 'w') as out:
|
||||||
|
out.write(header)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser(description='fx_const.h header generator')
|
||||||
|
parser.add_argument('input', type=str)
|
||||||
|
parser.add_argument('output', type=str)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def parse_csv(path: str) -> list[FxConst]:
|
||||||
|
with open(path, newline='') as file:
|
||||||
|
reader = csv.reader(file)
|
||||||
|
return list(
|
||||||
|
FxConst(
|
||||||
|
row[0], FxSpec(row[1]), float(row[2]))
|
||||||
|
for row in reader if not row[0].startswith('#'))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
1
tools/gen_fx_consts/.gitignore
vendored
1
tools/gen_fx_consts/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
gen_fx_consts
|
|
@ -1,31 +0,0 @@
|
|||||||
#ifndef GUARD_FX_H
|
|
||||||
#define GUARD_FX_H
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct FxSpec {
|
|
||||||
const char *name;
|
|
||||||
int intpart;
|
|
||||||
int fracpart;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FxConst {
|
|
||||||
char *name;
|
|
||||||
const struct FxSpec *fxtype;
|
|
||||||
double value;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct FxConst *gFxConstTable;
|
|
||||||
extern size_t gNFxConstTable;
|
|
||||||
|
|
||||||
// Init and delete the above two objects
|
|
||||||
void FxConstTableInit(void);
|
|
||||||
void FxConstTableEnd(void);
|
|
||||||
|
|
||||||
// Generates the integer value of the fixed-point value represented by FxConst*
|
|
||||||
long long MakeFix(const struct FxConst *constdef);
|
|
||||||
|
|
||||||
// For FxSpec*, get the width in bits.
|
|
||||||
int GetFxWidth(const struct FxSpec *fxtype);
|
|
||||||
|
|
||||||
#endif //GUARD_FX_H
|
|
@ -1,128 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "fx.h"
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
const struct FxSpec fx32 = {"fx32", 19, 12};
|
|
||||||
const struct FxSpec fx64 = {"fx64", 51, 12};
|
|
||||||
const struct FxSpec fx64c = {"fx64c", 31, 32};
|
|
||||||
const struct FxSpec fx16 = {"fx16", 3, 12};
|
|
||||||
|
|
||||||
const struct FxSpec *const sFxSpecPtrs[] = {
|
|
||||||
&fx32,
|
|
||||||
&fx64,
|
|
||||||
&fx64c,
|
|
||||||
&fx16,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FxConst *gFxConstTable = NULL;
|
|
||||||
size_t gNFxConstTable = 0;
|
|
||||||
|
|
||||||
void FxConstTableInit(void) {
|
|
||||||
FILE *file;
|
|
||||||
char *contents;
|
|
||||||
char *ptr;
|
|
||||||
char *linetok;
|
|
||||||
char *linetok_r;
|
|
||||||
char *commatok;
|
|
||||||
char *commatok_r;
|
|
||||||
char *_realpath;
|
|
||||||
int i, j, k;
|
|
||||||
long fsize;
|
|
||||||
long readsz;
|
|
||||||
static const char filename[] = SOURCE_DIR "/fx_const.csv";
|
|
||||||
|
|
||||||
atexit(FxConstTableEnd);
|
|
||||||
|
|
||||||
file = fopen(filename, "r");
|
|
||||||
if (file == NULL) {
|
|
||||||
fatal_error("Unable to open file '%s' for reading", filename);
|
|
||||||
}
|
|
||||||
fseek(file, 0, SEEK_END);
|
|
||||||
fsize = ftell(file);
|
|
||||||
fseek(file, 0, SEEK_SET);
|
|
||||||
contents = malloc(fsize + 1);
|
|
||||||
if (contents == NULL) {
|
|
||||||
fclose(file);
|
|
||||||
fatal_error("Unable to allocate CSV read buffer");
|
|
||||||
}
|
|
||||||
readsz = fread(contents, 1, fsize, file);
|
|
||||||
fclose(file);
|
|
||||||
if (readsz != fsize) {
|
|
||||||
free(contents);
|
|
||||||
fatal_error("Read error");
|
|
||||||
}
|
|
||||||
contents[fsize] = 0;
|
|
||||||
ptr = contents - 1;
|
|
||||||
gNFxConstTable = 0;
|
|
||||||
do {
|
|
||||||
ptr++;
|
|
||||||
gNFxConstTable += (*ptr != '#' && *ptr != '\n');
|
|
||||||
ptr = strchr(ptr, '\n');
|
|
||||||
} while (ptr != NULL);
|
|
||||||
if (gNFxConstTable == 0) {
|
|
||||||
free(contents);
|
|
||||||
fatal_error("Malformatted CSV file");
|
|
||||||
}
|
|
||||||
gFxConstTable = malloc(gNFxConstTable * sizeof(struct FxConst));
|
|
||||||
if (gFxConstTable == NULL) {
|
|
||||||
free(contents);
|
|
||||||
fatal_error("Unable to allocate gFxConstTable");
|
|
||||||
}
|
|
||||||
ptr = contents;
|
|
||||||
for (i = 0; i < gNFxConstTable; i++) {
|
|
||||||
linetok = strtok_r(ptr, "\n", &linetok_r);
|
|
||||||
ptr = NULL;
|
|
||||||
if (linetok == NULL) {
|
|
||||||
gNFxConstTable = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*linetok == '#') {
|
|
||||||
i--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (j = 0; j < 3; j++) {
|
|
||||||
commatok = strtok_r(linetok, ",", &commatok_r);
|
|
||||||
linetok = NULL;
|
|
||||||
if (commatok == NULL) {
|
|
||||||
free(contents);
|
|
||||||
fatal_error("Malformatted CSV file at line %d col %d", i, j);
|
|
||||||
}
|
|
||||||
switch (j) {
|
|
||||||
case 0:
|
|
||||||
gFxConstTable[i].name = strdup(commatok);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
for (k = 0; k < len(sFxSpecPtrs); k++) {
|
|
||||||
if (strcmp(commatok, sFxSpecPtrs[k]->name) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (k == len(sFxSpecPtrs)) {
|
|
||||||
free(contents);
|
|
||||||
fatal_error("Invalid fx type %s", commatok);
|
|
||||||
}
|
|
||||||
gFxConstTable[i].fxtype = sFxSpecPtrs[k];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gFxConstTable[i].value = strtod(commatok, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FxConstTableEnd(void) {
|
|
||||||
int i;
|
|
||||||
if (gFxConstTable != NULL) {
|
|
||||||
for (i = 0; i < gNFxConstTable; i++) {
|
|
||||||
if (gFxConstTable[i].name != NULL) {
|
|
||||||
free(gFxConstTable[i].name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(gFxConstTable);
|
|
||||||
gFxConstTable = NULL;
|
|
||||||
}
|
|
||||||
gNFxConstTable = 0;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#include <math.h>
|
|
||||||
#include "fx.h"
|
|
||||||
|
|
||||||
long long MakeFix(const struct FxConst *constdef) {
|
|
||||||
double ret_di, ret_df, value_abs;
|
|
||||||
long long ret_ii, ret_if, ret_val;
|
|
||||||
|
|
||||||
if (constdef->value == 0) {
|
|
||||||
return 0LL;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_abs = constdef->value < 0 ? -constdef->value : constdef->value;
|
|
||||||
ret_di = floor(value_abs);
|
|
||||||
ret_df = value_abs - ret_di;
|
|
||||||
ret_ii = (long long)value_abs * (1LL << constdef->fxtype->fracpart);
|
|
||||||
ret_if = (long long)(ret_df * (double)(1LL << constdef->fxtype->fracpart) + 0.5);
|
|
||||||
ret_ii &= ~((1LL << constdef->fxtype->fracpart) - 1);
|
|
||||||
ret_if &= (1LL << constdef->fxtype->fracpart) - 1;
|
|
||||||
ret_val = ret_ii + ret_if;
|
|
||||||
if (constdef->value < 0) {
|
|
||||||
ret_val = -ret_val;
|
|
||||||
}
|
|
||||||
return ret_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetFxWidth(const struct FxSpec *fxtype) {
|
|
||||||
return fxtype->fracpart + fxtype->intpart + 1;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#ifndef GUARD_GLOBAL_H
|
|
||||||
#define GUARD_GLOBAL_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdnoreturn.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define len(a) ((sizeof(a))/(sizeof(*(a))))
|
|
||||||
|
|
||||||
static inline noreturn __attribute__((format(printf, 1, 2))) void fatal_error(const char *fmt, ...) {
|
|
||||||
va_list va_args;
|
|
||||||
va_start(va_args, fmt);
|
|
||||||
vfprintf(stderr, fmt, va_args);
|
|
||||||
va_end(va_args);
|
|
||||||
fputc('\n', stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef __clang__
|
|
||||||
#undef strlcat
|
|
||||||
#define strlcat(d,s,n) strncat(d,s,(n)-strlen(d)-1)
|
|
||||||
#undef strlcpy
|
|
||||||
#define strlcpy(d,s,n) strncpy(d,s,(n)-1)
|
|
||||||
#endif //__clang__
|
|
||||||
|
|
||||||
#endif //GUARD_GLOBAL_H
|
|
@ -1,86 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "fx.h"
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
#define NAMEBUF_SIZ 32
|
|
||||||
|
|
||||||
static inline void usage(FILE *dest) {
|
|
||||||
fprintf(dest, "USAGE: gen_fx_consts FILENAME\n\n"
|
|
||||||
"FILENAME Path to write C header. Guard will be generated\n"
|
|
||||||
" automatically from the path.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
|
||||||
int i;
|
|
||||||
char namebuf[NAMEBUF_SIZ] = "";
|
|
||||||
char *header_guard;
|
|
||||||
FILE *outfile;
|
|
||||||
|
|
||||||
FxConstTableInit();
|
|
||||||
if (argc < 2) {
|
|
||||||
outfile = stdout;
|
|
||||||
header_guard = "NITRO_FX_FX_CONST_H_";
|
|
||||||
} else {
|
|
||||||
outfile = fopen(argv[1], "w");
|
|
||||||
if (outfile == NULL) {
|
|
||||||
fatal_error("Unable to open file '%s' for writing", argv[1]);
|
|
||||||
}
|
|
||||||
header_guard = strdup(argv[1]);
|
|
||||||
if (header_guard == NULL) {
|
|
||||||
fclose(outfile);
|
|
||||||
fatal_error("Unable to allocate temp buffer for header guard");
|
|
||||||
}
|
|
||||||
for (i = 0; header_guard[i]; i++) {
|
|
||||||
switch (header_guard[i]) {
|
|
||||||
case '.':
|
|
||||||
case '/':
|
|
||||||
header_guard[i] = '_';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
header_guard[i] = toupper(header_guard[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(outfile, "#ifndef %s_\n"
|
|
||||||
"#define %s_\n\n", header_guard, header_guard);
|
|
||||||
for (i = 0; i < gNFxConstTable; i++) {
|
|
||||||
long long value;
|
|
||||||
int nbyte;
|
|
||||||
char *suffix;
|
|
||||||
char *fmtstr;
|
|
||||||
int j;
|
|
||||||
value = MakeFix(&gFxConstTable[i]);
|
|
||||||
nbyte = GetFxWidth(gFxConstTable[i].fxtype) / 8;
|
|
||||||
switch (nbyte) {
|
|
||||||
case 2:
|
|
||||||
suffix = "";
|
|
||||||
fmtstr = "#define %-32s ((%s) 0x%04hx%s) // %.12f\n";
|
|
||||||
value &= 0xFFFFLL;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
suffix = "L";
|
|
||||||
fmtstr = "#define %-32s ((%s) 0x%08lx%s) // %.12f\n";
|
|
||||||
value &= 0xFFFFFFFFLL;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
suffix = "LL";
|
|
||||||
fmtstr = "#define %-32s ((%s) 0x%016llx%s) // %.12f\n";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fatal_error("invalid integer width: %d", nbyte);
|
|
||||||
}
|
|
||||||
snprintf(namebuf, NAMEBUF_SIZ, "%s_%s", gFxConstTable[i].fxtype->name, gFxConstTable[i].name);
|
|
||||||
for (j = 0; j < NAMEBUF_SIZ && namebuf[j]; j++) {
|
|
||||||
namebuf[j] = toupper(namebuf[j]);
|
|
||||||
}
|
|
||||||
fprintf(outfile, fmtstr, namebuf, gFxConstTable[i].fxtype->name, value, suffix, gFxConstTable[i].value);
|
|
||||||
}
|
|
||||||
fprintf(outfile, "\n#endif //%s_\n", header_guard);
|
|
||||||
if (argc >= 2) {
|
|
||||||
fclose(outfile);
|
|
||||||
free(header_guard);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user