v0.5.0
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)
andfloat(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)
andtimeof(label)
expressions. You can use these if you want to write a jump usingins_
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:
which defines constants
!enum(name="TestEnum") 20 Red 40 Blue
TestEnum.Red
andTestEnum.Blue
. An instruction can then specify that it takes an argument of this type, via a modifiedS
argument:In this example, when calling!ins_signatures 100 S(enum="TestEnum")
ins_100
you will be able to useins_100(Red)
as a shorthand forins_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
andfalse
are no longer keywords but rather members of a builtinenum bool
. Use it like any other enum.BitmapColorFormat
. This now houses the constantsFORMAT_ARGB_8888
,FORMAT_RGB_565
,FORMAT_ARGB_4444
, andFORMAT_GRAY_8
used byimg_format
andrt_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")
andS(enum="AnmScript")
instead ofn
andN
. 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:and then you would be able to write!msgmap !ins_instrinsics 100 Jmp() !ins_signatures 100 ot
loop { }
s in MSG!
Improvements to decompilation
- Can now detect of
if/elseif
chains that have noelse
block. - Many improvements to detection of nested
if/else
s 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 bothX
andREG[3]
in the same function body will now generate a warning. Similarly, using two different aliases (e.g.X
andY
) 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'sI0
or PCB's "param" registers in subs where these registers are already implicitly in use by function parameters.
- This is partly so that, in future versions of truth that provide
- Previously, using
-m mapfile.eclm
during decompilation would disable lookup fromTRUTH_MAP_PATH
. Now that multiple-m
are supported, this behavior now seems surprising, soTRUTH_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 signaturesotff
,toff
,ffto
, orffot
, 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.