Skip to content

Releases: ExpHP/truth

0.5.2

18 Aug 07:40
Compare
Choose a tag to compare

Added

  • Support for TH18.5 100th Black Market.
  • Debug info. The --output-debug-info JSONFILE flag has been added to all compile subcommands. This file can be used by debuggers to relate source-level concepts (e.g. function names and variable names) to runtime concepts (e.g. registers and const values).
    Perfect name resolution of locals in a debugger might not be possible yet as truth currently does not explicitly construct the tree used for name resolution (it is only implicitly constructed), so scope information is not yet available.
  • Bitwise negation. The unary ~ (bitwise not) operator has been added. No language natively provides it, but even when unavailable, it can be used (and will compile as -1 - x).
  • --no-builtin-mapfiles option for both compilation and decompilation. This will disable the core mapfiles which provide the builtin signatures and intrinsic mappings for all games, which can be useful if you are trying to design a comprehensive mapfile from scratch.

Other changes

  • The ternary operator a ? b : c can now be used in any expression, not just const expressions.
  • Relative time labels and interrupts now accept expressions, so you can use consts. Technically this also makes negative relative time labels possible; whether you choose to write them as +(-15): or (gasp) +-15: is up to you...
  • Unary - now can be directly provided by an intrinsic, and will otherwise fall back to -1 * x. (formerly, it would always produce 0 - x, which is not correct for all floats)

v0.5.0

15 May 00:06
Compare
Choose a tag to compare

Version 0.5.0 is a major release of the compiler containing many of the language additions that were found useful in alpha implementations of truecl. While truecl is still not officially released, these additions and improvements are available in all languages.

Added

Commands

  • Multiple -m args can now be provided.
  • Decompile commands now support -o/--output, just like compilation. This is extremely useful on Windows where redirection on STDOUT may produce a file in a different encoding from UTF-8 depending on the system configuration.
  • truanm had some unhelpful behavior when using multiple image sources that provide the same image, or when using has_data: "dummy" together with an image source. Image sources have been redesigned to better support common use cases.

Language features

  • INF, NAN, PI constants.
  • break keyword. This exits the nearest surrounding loop.
  • New type-cast syntax. The old _S and _f functions have been split into two types of operations: int(expr) and float(expr) for type-casts, and $(expr) and %(expr) to read a temporary as some type. (the two are the same in most languages, except EoSD ECL which does not auto-cast)
  • offsetof(label) and timeof(label) expressions. You can use these if you want to write a jump using ins_ syntax or the instruction alias. (these were a necessary addition for decompilation of EoSD ECL files that use conditional jumps in a funny way).
  • User-defined enums. A mapfile can define an enum:
    !enum(name="TestEnum")
    20 Red
    40 Blue
    
    which defines constants TestEnum.Red and TestEnum.Blue. An instruction can then specify that it takes an argument of this type, via a modified S argument:
    !ins_signatures
    100 S(enum="TestEnum")
    
    In this example, when calling ins_100 you will be able to use ins_100(Red) as a shorthand for ins_100(TestEnum.Red), and during decompilation it will try to decompile the values from this enum. Enums are open, in that the same enum can be defined multiple times or even across multiple mapfiles, and the list of consts will be merged.
  • Built-in enums:
    • bool. true and false are no longer keywords but rather members of a builtin enum bool. Use it like any other enum.
    • BitmapColorFormat. This now houses the constants FORMAT_ARGB_8888, FORMAT_RGB_565, FORMAT_ARGB_4444, and FORMAT_GRAY_8 used by img_format and rt_format in ANM files.
    • AnmSprite, AnmScript, MsgScript, EclSub. These get automatically generated from the names defined in a source script, allowing you to write e.g. S(enum="AnmSprite") and S(enum="AnmScript") instead of n and N. This makes them more flexible, allowing these types to be used in word-sized arguments and, in the future, timeline arg0.
  • Intrinsic mappings. (!ins_intrinsics) For instance, a patch which adds jump intrinsics to MSG could also provide a mapfile which tells trumsg about this intrinsic:
    !msgmap
    !ins_instrinsics
    100 Jmp()
    !ins_signatures
    100 ot
    
    and then you would be able to write loop { }s in MSG!

Improvements to decompilation

  • Can now detect of if/elseif chains that have no else block.
  • Many improvements to detection of nested if/elses and loops.
  • Decompiling intrinsics will fall back to instruction syntax if the intrinsic cannot be decompiled. (e.g. PCB stage 7 ECL has a set_int instruction that tries to assign to an immediate)
  • Decompiling sub/script/sprite names will fall back to raw integers if the corresponding items don't exist.

Compatibility notes

  • Using registers (e.g. $REG[8]) in a format without registers such as STD is now detected as an error.
  • If e.g. X is an alias for $REG[3], then using both X and REG[3] in the same function body will now generate a warning. Similarly, using two different aliases (e.g. X and Y) for the same register will also warn.
    • This is partly so that, in future versions of truth that provide truecl, the compiler can call attention to accidental usage of EoSD's I0 or PCB's "param" registers in subs where these registers are already implicitly in use by function parameters.
  • Previously, using -m mapfile.eclm during decompilation would disable lookup from TRUTH_MAP_PATH. Now that multiple -m are supported, this behavior now seems surprising, so TRUTH_MAP_PATH is now always searched during decompilation.

Internal changes

  • The order and encoding of arguments to intrinsics is no longer hardcoded by game/format, but rather inferred from the mapfile signature, meaning it can be defined by the user. So for instance, a CondJmp(op="=="; type="float") could have any of the signatures otff, toff, ffto, or ffot, and these would all be encoded correctly by the compiler.
  • Time labels are now internally stored as statements. This drastically simplifies parsing and some aspects of loop compilation/decompilation.

0.5.0-pre3

13 Feb 22:56
Compare
Choose a tag to compare
0.5.0-pre3 Pre-release
Pre-release

This prerelease contains a highly experimental and extremely early version of truecl with support for TH06-TH095. (N.B. Th095 is missing signatures)

Instructions on how to run truecl can be found here: https://github.com/ExpHP/truth/releases/tag/0.5.0-pre1

Changes from 0.5.0-pre2:

  • The old _S and _f functions have been split into two types of operations: int(expr) and float(expr) for type-casts, and $(expr) and %(expr) to read a temporary as some type. (the two are the same in most languages, except EoSD ECL which does not auto-cast)
    • A patch can define intrinsics for these casts in EoSD ECL as UnOp(int,float) (cast to int) and UnOp(float,int) (cast to float). Suggested signatures are Sf and SS in line with other EoSD ops, but fS should also work for float(...).
  • People strongly disliked the .Name syntax for unqualified enum consts so it is now simply Name.
  • This unifies the concepts of automatic consts and enums, finally destroying the concept of automatic consts once and for all. The previously existing automatic const kinds are now builtin enums; e.g. N in a signature can now be equivalently written as S(enum="AnmScript"). (this means you can now express e.g. a word-sized sprite)
    • The builtin enums are: AnmScript, AnmSprite, MsgScript, EclSub, BitmapColorFormat
  • An unqualified enum is now able to be used in a place without an enum type (e.g. int x = Name) provided that only one enum defines a const with that name. (this was necessary to continue supporting existing color format syntax in anm files, and just generally somehow felt appropriate given the change from .Name to Name)

0.5.0-pre2

08 Feb 03:41
Compare
Choose a tag to compare
0.5.0-pre2 Pre-release
Pre-release

This prerelease contains a highly experimental and extremely early version of truecl with support for TH06-TH095. (N.B. Th095 is missing signatures)

Instructions on how to run truecl can be found here: https://github.com/ExpHP/truth/releases/tag/0.5.0-pre1

The only differences from 0.5.0-pre1 are that this adds enum consts.

v0.5.0-pre1

19 Dec 00:46
Compare
Choose a tag to compare
v0.5.0-pre1 Pre-release
Pre-release

This prerelease contains a highly experimental and extremely early version of truecl with support for TH06-TH095. (N.B. Th095 is missing signatures)

Disclaimer:
There are many things that may yet still change about the syntax, so it is not advised to use this for developing your own patches yet.

There is no binary for truecl yet!! To use it, you must call truth-core truecl instead of truecl.

# decompile
truth-core truecl d -mmap/any.eclm th06/ecldata1.ecl > ecldata1.ecl.spec

# recompile
truth-core truecl c -mmap/any.eclm ecldata1.ecl.spec -o ecldata1.ecl

A list of known issues with truecl can be found here: #36

Here is the current working copy of the release notes:

Release notes (working copy)

Added

Commands

  • truecl (!!!!) is available in prototype status, but the way to invoke it is a well guarded secret truth-core truecl. TH06-TH095 are supported.
  • Multiple -m args can now be provided.

New language features in support of ECL

  • Function definition syntax for exported subs. void Sub0(int x) {}
  • Natural call syntax for exported subs. Sub0(10, 20.4);
  • Difficulty switches. I0 = A + (3:4:4:5);
  • Difficulty flags. {"ENH"}: ins_10();
  • INF, NAN, PI constants.
  • break keyword. This exits the nearest surrounding loop.
  • offsetof(label) and timeof(label) expressions. You can use these if you want to write a jump using ins_ syntax or the instruction alias. They'll also show up in contrived cases when decompiling an EoSD ECL file that uses conditional jumps in a funny way.
  • @arg0 pseudo-arg. This will be used together with @blob when decompiling timelines with unknown signatures in TH06 and TH07.

Improvements to decompilation

  • Allow detection of if/elseif chains that have no else block.
  • Many improvements to detection of if/elses and loops in general.
  • Decompiling intrinsics will fall back to instruction syntax if the intrinsic cannot be decompiled. (e.g. PCB stage 7 ECL has a set_int instruction that tries to assign to an immediate)
  • Decompiling sub/script/sprite names will fall back to raw integers if the corresponding items don't exist.

Additions to mapfiles

Mapfiles can now define the following additional sections:

  • Difficulty flag names. (!difficulty_flags) The prepackaged maps do this.
  • Intrinsic mappings. (!ins_intrinsics) For instance, a patch which adds a jump intrinsic to MSG could also provide a mapfile which tells trumsg about this intrinsic:
    !msgmap
    !ins_instrinsics
    100 Jmp()
    !ins_signatures
    100 ot
    
    and then you would be able to write loop { }s in MSG!

Internal changes

  • The order of arguments to intrinsics is no longer hardcoded by game/format, but rather inferred from the mapfile signature (meaning it can be defined by the user).
  • Time labels are now internally stored as statements. This drastically simplifies parsing and some aspects of loop compilation/decompilation.

Compatibility notes

  • Using registers (e.g. $REG[8]) in a format without registers such as STD is now detected as an error.
  • If e.g. X is an alias for $REG[3], then using both X and REG[3] in the same function body will now generate a warning. Similarly, using two different aliases (e.g. X and Y) for the same register will also warn.
    • This is done in order to call attention to accidental usage of EoSD's I0 or PCB's "param" registers in subs where these registers are already implicitly in use by function parameters.
  • Previously, using -m mapfile.eclm during decompilation would disable lookup from TRUTH_MAP_PATH. Now that multiple -m are supported, this behavior now seems surprising, so TRUTH_MAP_PATH is now always searched during decompilation.

v0.4.3

20 Jun 06:30
Compare
Choose a tag to compare

0.4.3 is a minor update that adds some information from Dai:

  • The unknown field in STD objects has been renamed to layer; it behaves like the layer(_) command, and is used to control the layering of 3D objects relative to 2D sprites. The old name is still accepted, but may be deprecated and eventually removed in the distant future.
  • Small update to mapfiles.

v0.4.2

11 Jun 04:01
Compare
Choose a tag to compare

v0.4.2

  • Adds truanm extract (truanm x) to extract images. See the readme for more details.

  • Adds additional flags to tweak decompilation:

    • --no-blocks: Disables conditional and loop decompilation, leaving behind all gotos and labels in their natural state.
    • --no-intrinsics: Forces every instruction to decompile into name(arg1, arg2) etc. (e.g. addf(F1, 0.3) instead of F1 += 0.3;).
    • --no-arguments: Forces all instructions to decompile into raw form using pseudo-arguments. (e.g. addi(@mask=0b1, @blob="10270000 24000000")).

    These can help work with unusual files.

  • Bugfix: Floating point comparisons actually work now instead of causing a panic. So that's cool.

v0.4.1

05 May 03:51
Compare
Choose a tag to compare

Added

  • Support for TH18: 東方虹龍洞 ~ Unconnected Marketeers has been added.
  • truanm can now import image files (PNG, BMP, GIF). Simply supply a directory instead of an ANM file to --image-source or #pragma image_source.
  • truanm can generate dummy image data to be hotswapped by thcrap; try has_data: "generate".
  • truanm now has named constants for color formats: FORMAT_ARGB_8888, FORMAT_ARGB_4444, FORMAT_RGB_565, FORMAT_GRAY_8.
  • truanm now provides sane defaults for the majority of fields on an entry.

Changed

  • Renamed some ANM entry fields to place greater focus on the things you should probably care more about:
    • width, height, and format have been renamed to rt_width, rt_height, rt_format to indicate that these are values for the runtime buffer. Generally speaking, you should almost never need to worry about these.
    • thtx_width, thtx_height, thtx_format have been renamed to img_width, img_height, img_format to make them less "scary." These describe the actual dimensions and format of an embedded image.
    • The old names still work, but will generate a deprecation warning.

0.4.0

19 Apr 06:34
Compare
Choose a tag to compare

v0.4.0

The biggest addition to 0.4.0 is that trumsg is now usable.

Compatibility Note

Text source files are now always UTF-8, never Shift-JIS. If you were previously using truth with Shift-JIS files, you may need to change their encoding and re-save them in your text editor.

Changes

  • trumsg now produces reasonable output, and can roundtrip-decode all (stage) MSG files in all games up to and including TH17.
  • Added pseudo-arguments. When decompiling, instructions with unknown signatures will now be decoded to a form like ins_1011(@mask=0b100, @blob="00501c46 00000040 00541c46");
  • Added const variables. These are typed compile-time constants. Please see the truth syntax primer for more information.
  • More warnings! Diagnostics were heavily reworked, allowing warnings to be emitted for many more things (and allowing some things that used to be errors to become warnings instead).
  • Default output line width changed from 100 to 80.

0.4.0-pre3

18 Apr 02:12
Compare
Choose a tag to compare
0.4.0-pre3 Pre-release
Pre-release

This release supports stage MSG files in all games up to TH17. Only TH06-TH08 and TH10-TH12 have been thoroughly tested; other games may be missing a few instruction names or signatures.