Commit Graph
28 Commits
Author SHA1 Message Date
Nunuhara Cabbage 3d70c81404 ainedit: support reading HLL declarations 2020-08-01 22:19:00 -07:00
Nunuhara Cabbage 44802acb48 aindump: support Hentai Labyrinth
Even though this game is still ain v14, it makes an incompatible change
to the file format: struct definitions now contain a list of functions
at the end (I believe this is a listing of the struct's vtable).

There is now a system for tracking the minor version of the ain file
format. This is a made up value, determined by the file name of the ain
file.

This commit also fixes an issue where the empty string was being added
as a new string to the string table when rebuilding ain files with
ainedit.
2020-07-31 20:42:08 -07:00
Nunuhara Cabbage f9eaef7717 Fix encoding issue with macro generation
Fixes #2.

The problem here was that init_member_functions assumed ASCII or SJIS
encoding of function/struct names in the ain file. Now it will convert
to UTF-8 when analyzing member functions.

This commit also removes the --ain-encoding option to ainedit.
--output-encoding should always match the encoding of the input ain
file. --transcode can be used to change the encoding before running
running further ainedit commands.
2020-07-11 11:10:18 -07:00
Nunuhara Cabbage d3928c774d jaf: messages and char constants 2020-07-05 22:29:45 -07:00
Nunuhara Cabbage 8bf7e2aa2b jaf: function types 2020-07-05 16:26:06 -07:00
Nunuhara Cabbage fd60c6329b jaf: arrays 2020-06-27 13:35:09 -07:00
Nunuhara Cabbage a2012a56ce jaf: support system calls
Only for ain version < 11. Starting with v11 system calls are actually
HLL calls.
2020-06-22 10:14:11 -07:00
Nunuhara Cabbage b41275f6f4 jaf: support multiple input files 2020-06-21 16:50:04 -07:00
Nunuhara Cabbage d4f1b5ba46 ainedit: support creating new ain files
This is mainly for testing purposes. Defaults to creating an ain v4
file, which is the same version produced by the SDK compiler.

Also various small improvements so that output matches the SDK compiler:
* add "0" function (currently does nothing)
* add "NULL" function
* compile null return at the end of every function
* set main function index in ain file
2020-06-21 14:52:05 -07:00
Nunuhara Cabbage 6e3a3e784a jaf: strings and reference types 2020-06-20 21:05:14 -07:00
Nunuhara Cabbage 2908e6fcdc jaf: initial compiler implementation
Supports reading from local variables (no assignment) and arithmetic.
2020-06-16 20:38:29 -07:00
Nunuhara Cabbage d8e21d0323 jaf: support parsing identifiers & function calls 2020-06-14 15:54:59 -07:00
Nunuhara Cabbage e618017e78 ainedit: support parsing .jaf functions 2020-06-13 13:36:39 -07:00
Nunuhara Cabbage 897cbde39c ainedit: initial .jaf support
Initial support for compiling .jaf (System 4 language) files. So far
this is limited to adding struct definitions and declaring new globals.
The actual bytecode compilation is not yet implemented.

This Bison grammar is based on a C grammar and should cover 95% of the
System 4 language syntax already, though many AST nodes are not yet
implemented.
2020-06-10 21:23:00 -07:00
Nunuhara Cabbage b617449178 aindump/ainedit: initial ain v14 support
Support for Evenicle 2 and Haha Ranman.

There are a few changes in v14:
* a number of new instructions (semantics yet unknown)
* HLL function arguments and return values can now be complex types
  (e.g. arrays, enums)
* support for nested arrays (this isn't necessarily new, but it doesn't
  occur in Rance X at all)
2020-05-17 13:21:37 -07:00
Nunuhara Cabbage 094ce848b9 aindump/ainedit: STRUCTREF, etc. macros
Same idea as LOCALREF/GLOBALREF, etc. except for accessing struct
members inside of a member function. This is a bit trickier since it
requires knowing which functions belong to which structs, which isn't
directly encoded in the AIN format.
2020-05-01 16:31:12 -07:00
Nunuhara Cabbage 608aedb500 Fix various issues with MSYS2/mingw build 2020-02-14 16:29:44 -08:00
Nunuhara Cabbage a76b7149d9 aindump/ainedit: add .CASE pseudo instruction
Add a pseudo instruction to represent switch case labels, along with the
infrastructure to support pseudo instructions in general. .CASE takes
two arguments: a switch:case index (e.g. "12:8") and the value to match
against.

Also, add a --no-strings option to both programs to allow modifying the
code without changing the string/message tables. This is needed for now
since rebuilding the string/message tables (as currently implemented)
causes serious bugs in Rance X (and probably other games).

Running the following command should produce an ain file that is almost
bit-for-bit identical to the input file (the only difference being minor
drift in floating point constants):

    aindump -c --no-strings in.ain | ainedit -c - --no-strings -o
        out.ain in.ain
2020-02-09 15:34:10 -08:00
Nunuhara Cabbage dab8deca42 Add ainedit utility
The ainedit utility is a tool capable of modifying AIN files up to
version 12 (Rance X). As far as I know, this is the first publicly
released tool that can handle AIN files above version 7.

The basic mode of operation is as follows:

* dump the CODE section with aindump
* edit the disassembled bytecode
* assemble & insert the edited bytebode back into the original AIN file
  using ainedit

E.g.

    aindump -c -o out.jam /path/to/Rance10.ain
    $EDITOR out.jam
    ainedit -c out.jam -o out.ain /path/to/Rance10.ain
    mv /path/to/Rance10.ain /path/to/Rance10.ain.backup
    mv out.ain /path/to/Rance10.ain

ainedit is also capable of editing declarations (structures, functions,
etc.) using the JSON (-j) output from aindump.

There is currently one major deficiency in this tool: it does not
rebuild the AIN file's switch table (SWI0 section). This means that you
can't insert or delete instructions, as it would render the addresses
stored in the switch table invalid. I hope to fix this soon.

A number of changes have also been made to the aindump utility, since
these tools need to work together.
2020-02-07 19:49:39 -08:00
Nunuhara Cabbage 167953f33c aindump: dump full enum definitions (incl. values)
This requires scanning through the code for a particular method for each
enum type. Not a great solution, but there's not much else that can be
done here.

Also, use khash.h (from klib) for hash tables.
2020-01-15 21:53:51 -08:00
Nunuhara Cabbage 74c5b91e0c aindump: enums, iterators, interface objects
Type 82
-------
I am assuming this is an iterator type because it always appears as a
local variable alongside "dummy" variables with "foreach" in their name,
and the naming of the variables suggests an iterator. Probably there is
a new syntax like:

    foreach (iter_var in array_var) { ... }

Type 89
-------
An instance of an interface. This is a 2-valued type (similar to ref
int, etc.) where the first value is the index of a struct page, and the
second value is an index into the struct's vtable.

Any struct that implements an interface gets an array<int> named
"<vtable>" as its first member. This array stores indices into the
global function table. CALLMETHOD now looks up methods in the vtable
rather than the global function table.

Types 92, 93
------------
These are enum types. Type 92 is the normal enum type, and type 93 is
the reference-to-enum type. The "struct type" for these types stores an
index into the enum table.

Types 86, 91
------------
Type 86 only seems to be used as the return value from EnumType::Parse
methods. In the ain file, it has an extra type descriptor, similar to an
array type. This extra type descriptor always has data type 91, and its
struct type is an index into the enum table. Type 91 is simlar to types
92 & 93: it stores an enum table index in its struct type.

Type 86 is a 2-valued type. The first value is the value of the enum (an
integer between 0 and n). The second value seems to be either 0 or -1,
depending on whether EnumType::Parse was able to produce a valid enum
value.

It is possible that type 86 is actually some kind of generic maybe-error
type that only happens to be used by the enum code. But that doesn't
explain why it is paired with type 91 and not type 92.
2020-01-15 12:59:41 -08:00
Nunuhara Cabbage 32bee0c242 aindump: print array types properly
Print the new v11+ array types properly. Also, print the array rank for
old array types.

The code for reading v11+ ain data is simplified a lot here as well.
2020-01-14 20:43:10 -08:00
Nunuhara Cabbage 6b34660e18 aindump: ain v8+ improvements
I've figured out what most of the extra fields are for. Mostly they are
for:

* a new array type, in which the contained value type is stored in the
  variable object rather than encoded in the type number
* argument initvals (I guess the VM is now responsible for these?)
* interfaces
2020-01-12 21:50:17 -08:00
Nunuhara Cabbage 302598ace2 aindump: add decrypt mode
Add -d,--decrypt option to dump decrypted ain file (for reverse
engineering).
2020-01-10 12:28:44 -08:00
Nunuhara Cabbage 6a4d11f3de Use libffi for library calls
Use libffi to portably call arbitrary functions at runtime, rather than
forcing library functions to use a standard prototype.
2020-01-07 22:48:29 -08:00
Nunuhara Cabbage f1cc9082b3 Don't store HLL function pointers in ain struct
Store them in vm.c. The ain structure should not contain data that
wasn't in the ain file on disk.
2020-01-03 18:48:30 -08:00
Nunuhara Cabbage 03e9d59825 aindump: improve disassembler output
Replace many instruction arguments with names/values (strings/messages,
local/global variables, structs, functions, etc.) and add labels to jump
targets.
2020-01-01 20:34:35 -08:00
Nunuhara Cabbage 5d6f148e1b Reorganize project file structure
- Create separate directories for source and header files.
- Build code shared between xsystem4 and aindump as a static library.
- Create header dirs gfx/ system4/ and vm/
- Make CG.c/h usable without a running VM
2019-12-31 17:50:40 -08:00