mirror of
https://github.com/pret/pokeplatinum.git
synced 2024-11-23 05:49:44 +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