2019-07-01 16:45:58 +02:00
|
|
|
#! /usr/bin/env python3
|
2019-03-21 22:54:06 +01:00
|
|
|
|
|
|
|
import getopt
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import fxconv
|
2021-06-02 10:12:03 +02:00
|
|
|
import importlib.util
|
2020-05-30 12:17:06 +02:00
|
|
|
|
|
|
|
help_string = f"""
|
2021-01-11 19:17:26 +01:00
|
|
|
usage: fxconv [<TYPE>] <INPUT> -o <OUTPUT> [--fx|--cg] [<PARAMETERS>...]
|
|
|
|
|
|
|
|
fxconv converts resources such as images and fonts into binary formats for
|
|
|
|
fxSDK applications, using gint and custom conversion formats.
|
|
|
|
|
|
|
|
When no TYPE is specified (automated mode), fxconv looks for type and
|
|
|
|
parameters in an fxconv-metadata.txt file in the same folder as the input. This
|
|
|
|
is normally the default for add-ins.
|
|
|
|
|
|
|
|
When TYPE is specified (one-shot conversion), it should be one of:
|
|
|
|
-b, --binary Turn data into an object file without conversion
|
2020-03-11 19:37:27 +01:00
|
|
|
-f, --font Convert to gint's topti font format
|
2021-01-11 19:17:26 +01:00
|
|
|
--bopti-image Convert to gint's bopti image format
|
2020-03-11 19:37:27 +01:00
|
|
|
--libimg-image Convert to the libimg image format
|
2021-05-04 17:38:28 +02:00
|
|
|
--custom Use a custom converter; you might want to specify an explicit
|
|
|
|
type by adding "custom-type:your_custom_type" (see below)
|
2024-02-01 17:46:30 +01:00
|
|
|
Custom converters can be specified by:
|
2021-05-04 17:38:28 +02:00
|
|
|
--converters Semicolon-separated list of custom converters (converters.py
|
|
|
|
in the current directory is detected as one per legacy)
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2021-01-11 19:17:26 +01:00
|
|
|
During one-shot conversions, parameters can be specified with a "NAME:VALUE"
|
|
|
|
syntax (names can contain dots). For example:
|
2019-03-21 22:54:06 +01:00
|
|
|
fxconv -f myfont.png -o myfont.o charset:ascii grid.padding:1 height:7
|
2019-08-04 14:04:09 +02:00
|
|
|
|
2021-01-11 19:17:26 +01:00
|
|
|
Some formats differ between platforms so you should specify it when possible:
|
2024-02-01 17:46:30 +01:00
|
|
|
--fx CASIO fx-9860G family (black-and-white calculators)
|
2024-05-06 18:02:02 +02:00
|
|
|
--cg, --cp CASIO fx-CG 50 / fx-CP 400 family (16-bit color calcs)
|
2024-02-01 17:46:30 +01:00
|
|
|
|
|
|
|
Finally, there is some support (non-final) for PythonExtra, in which case the
|
|
|
|
output file is as Python file instead of an object file.
|
|
|
|
--py Convert for PythonExtra (some types supported)
|
|
|
|
--py-compact Use compact bytes notation (shorter, but non-printable)
|
2019-03-21 22:54:06 +01:00
|
|
|
""".strip()
|
|
|
|
|
|
|
|
# Simple error-warnings system
|
2021-01-11 19:17:26 +01:00
|
|
|
FxconvError = fxconv.FxconvError
|
|
|
|
|
2019-03-21 22:54:06 +01:00
|
|
|
def err(msg):
|
2019-08-04 14:04:09 +02:00
|
|
|
print("\x1b[31;1merror:\x1b[0m", msg, file=sys.stderr)
|
2021-01-11 19:17:26 +01:00
|
|
|
return 1
|
2019-03-21 22:54:06 +01:00
|
|
|
def warn(msg):
|
2020-03-11 19:37:27 +01:00
|
|
|
print("\x1b[33;1mwarning:\x1b[0m", msg, file=sys.stderr)
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2021-05-04 17:38:28 +02:00
|
|
|
# "converters" module from the user project... if it exists. This
|
|
|
|
# auto-detection is legacy, you should use --converters instead.
|
2020-10-23 13:05:50 +02:00
|
|
|
try:
|
2021-05-04 17:38:28 +02:00
|
|
|
import converters as conv
|
|
|
|
converters = [conv.convert]
|
2020-10-23 13:05:50 +02:00
|
|
|
except ImportError:
|
2021-05-04 17:38:28 +02:00
|
|
|
converters = []
|
2020-10-23 13:05:50 +02:00
|
|
|
|
2019-03-21 22:54:06 +01:00
|
|
|
def main():
|
2021-01-11 19:17:26 +01:00
|
|
|
types = "binary image font bopti-image libimg-image custom"
|
|
|
|
mode = ""
|
2019-03-21 22:54:06 +01:00
|
|
|
output = None
|
2019-09-09 09:18:59 +02:00
|
|
|
model = None
|
|
|
|
target = { 'toolchain': None, 'arch': None, 'section': None }
|
2020-10-23 13:05:50 +02:00
|
|
|
use_custom = False
|
2021-05-04 17:38:28 +02:00
|
|
|
converter_paths = []
|
2024-02-01 17:46:30 +01:00
|
|
|
py = { 'enabled': False, 'compact': False }
|
2019-03-21 22:54:06 +01:00
|
|
|
|
|
|
|
# Parse command-line arguments
|
|
|
|
|
|
|
|
if len(sys.argv) == 1:
|
|
|
|
print(help_string, file=sys.stderr)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
try:
|
2021-05-04 17:38:28 +02:00
|
|
|
longs = ["help", "output=", "toolchain=", "arch=", "section=", "fx",
|
2024-05-06 18:02:02 +02:00
|
|
|
"cg", "cp", "converters=", "py", "py-compact"] + types.split()
|
2021-05-04 17:38:28 +02:00
|
|
|
opts, args = getopt.gnu_getopt(sys.argv[1:], "hsbifo:", longs)
|
2019-03-21 22:54:06 +01:00
|
|
|
except getopt.GetoptError as error:
|
2021-01-11 19:17:26 +01:00
|
|
|
return err(error)
|
2019-03-21 22:54:06 +01:00
|
|
|
|
|
|
|
for name, value in opts:
|
|
|
|
# Print usage
|
|
|
|
if name == "--help":
|
2021-01-11 19:17:26 +01:00
|
|
|
print(help_string, file=sys.stderr)
|
|
|
|
return 0
|
2019-03-21 22:54:06 +01:00
|
|
|
elif name in [ "-o", "--output" ]:
|
|
|
|
output = value
|
2019-08-04 14:04:09 +02:00
|
|
|
elif name in [ "--fx", "--cg" ]:
|
2019-09-09 09:18:59 +02:00
|
|
|
model = name[2:]
|
2024-05-06 18:02:02 +02:00
|
|
|
elif name == "--cp":
|
|
|
|
model = "cg"
|
2019-09-09 09:18:59 +02:00
|
|
|
elif name == "--toolchain":
|
|
|
|
target['toolchain'] = value
|
|
|
|
elif name == "--arch":
|
|
|
|
target['arch'] = value
|
|
|
|
elif name == "--section":
|
|
|
|
target['section'] = value
|
2020-10-23 13:05:50 +02:00
|
|
|
elif name == "--custom":
|
|
|
|
use_custom = True
|
|
|
|
mode = "custom"
|
2021-05-04 17:38:28 +02:00
|
|
|
elif name == "--converters":
|
|
|
|
converter_paths = [path for path in value.split(";") if path]
|
2024-02-01 17:46:30 +01:00
|
|
|
elif name == "--py":
|
|
|
|
py['enabled'] = True
|
|
|
|
elif name == "--py-compact":
|
|
|
|
py['compact'] = True
|
2019-03-21 22:54:06 +01:00
|
|
|
# Other names are modes
|
|
|
|
else:
|
2020-03-11 19:37:27 +01:00
|
|
|
mode = name[1] if len(name)==2 else name[2:]
|
2019-03-21 22:54:06 +01:00
|
|
|
|
|
|
|
# Remaining arguments
|
|
|
|
if args == []:
|
2021-01-11 19:17:26 +01:00
|
|
|
err(f"no input file")
|
2019-03-21 22:54:06 +01:00
|
|
|
sys.exit(1)
|
|
|
|
input = args.pop(0)
|
|
|
|
|
2021-01-11 19:17:26 +01:00
|
|
|
# In automatic mode, look for information in fxconv-metadata.txt
|
|
|
|
if mode == "":
|
2022-11-05 18:44:33 +01:00
|
|
|
metadata_file = os.path.join(os.path.dirname(input),
|
|
|
|
"fxconv-metadata.txt")
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2021-01-11 19:17:26 +01:00
|
|
|
if not os.path.exists(metadata_file):
|
|
|
|
return err(f"using auto mode but {metadata_file} does not exist")
|
2020-05-30 12:17:06 +02:00
|
|
|
|
2021-12-28 18:37:40 +01:00
|
|
|
metadata = fxconv.Metadata(path=metadata_file)
|
|
|
|
params = metadata.rules_for(input)
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2022-01-28 19:07:53 +01:00
|
|
|
if params is None:
|
|
|
|
return err(f"no metadata specified for {input}")
|
|
|
|
|
2021-12-28 18:37:40 +01:00
|
|
|
if "section" in params:
|
|
|
|
target["section"] = params["section"]
|
2021-09-26 10:55:20 +02:00
|
|
|
|
2021-01-11 19:17:26 +01:00
|
|
|
# In manual conversion modes, read parameters from the command-line
|
2019-03-21 22:54:06 +01:00
|
|
|
else:
|
2022-01-26 20:54:13 +01:00
|
|
|
params = fxconv.parse_parameters(args)
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2022-01-28 19:07:38 +01:00
|
|
|
if "type" in params or "custom-type" in params:
|
2020-03-11 19:37:27 +01:00
|
|
|
pass
|
2021-01-11 19:17:26 +01:00
|
|
|
elif len(mode) == 1:
|
2020-03-11 19:37:27 +01:00
|
|
|
params["type"] = { "b": "binary", "i": "image", "f": "font" }[mode]
|
|
|
|
else:
|
|
|
|
params["type"] = mode
|
|
|
|
|
|
|
|
# Will be deprecated in the future
|
2022-01-28 19:07:38 +01:00
|
|
|
if params.get("type") == "image":
|
2020-03-11 19:37:27 +01:00
|
|
|
warn("type 'image' is deprecated, use 'bopti-image' instead")
|
|
|
|
params["type"] = "bopti-image"
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2021-05-04 17:38:28 +02:00
|
|
|
# Load custom converters:
|
|
|
|
for path in converter_paths:
|
|
|
|
spec = importlib.util.spec_from_file_location("converters", path)
|
|
|
|
module = importlib.util.module_from_spec(spec)
|
|
|
|
spec.loader.exec_module(module)
|
|
|
|
converters.append(module.convert)
|
2020-10-23 13:05:50 +02:00
|
|
|
|
2024-02-01 17:46:30 +01:00
|
|
|
params["py"] = py
|
2021-05-04 17:38:28 +02:00
|
|
|
fxconv.convert(input, params, target, output, model, converters)
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2019-08-04 14:04:09 +02:00
|
|
|
if __name__ == "__main__":
|
2021-01-11 19:17:26 +01:00
|
|
|
try:
|
|
|
|
sys.exit(main())
|
|
|
|
except fxconv.FxconvError as e:
|
|
|
|
sys.exit(err(e))
|