summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorlouist103 <35883445+louist103@users.noreply.github.com>2021-03-17 18:17:11 -0400
committerGitHub <noreply@github.com>2021-03-17 18:17:11 -0400
commit9c1cb1fc412443a48944e4cb47f52e220b4b0912 (patch)
treeed9a7383004a6e96838f85ad68b538ba540bb105 /lib
parent4bf6600a3b67223d5e28d6a1fccfeb54e37d7a77 (diff)
Remove libgfxd binary (#90)
* started on basic type errors * Done. For now * remove libgfxd binary * New libgfxd with MSVC support
Diffstat (limited to 'lib')
-rw-r--r--lib/libgfxd/LICENSE21
-rw-r--r--lib/libgfxd/Makefile19
-rw-r--r--lib/libgfxd/README.md478
-rw-r--r--lib/libgfxd/gbi.h3808
-rw-r--r--lib/libgfxd/gfxd.c863
-rw-r--r--lib/libgfxd/gfxd.h11
-rw-r--r--lib/libgfxd/libgfxd.abin3348354 -> 0 bytes
-rw-r--r--lib/libgfxd/priv.h123
-rw-r--r--lib/libgfxd/uc.c54
-rw-r--r--lib/libgfxd/uc_argfn.c1814
-rw-r--r--lib/libgfxd/uc_argtbl.c490
-rw-r--r--lib/libgfxd/uc_f3d.c4
-rw-r--r--lib/libgfxd/uc_f3db.c5
-rw-r--r--lib/libgfxd/uc_f3dex.c4
-rw-r--r--lib/libgfxd/uc_f3dex2.c4
-rw-r--r--lib/libgfxd/uc_f3dexb.c5
-rw-r--r--lib/libgfxd/uc_macrofn.c2453
-rw-r--r--lib/libgfxd/uc_macrotbl.c1397
18 files changed, 11552 insertions, 1 deletions
diff --git a/lib/libgfxd/LICENSE b/lib/libgfxd/LICENSE
new file mode 100644
index 0000000..a7655f8
--- /dev/null
+++ b/lib/libgfxd/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016-2021 glank (glankk@github.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/lib/libgfxd/Makefile b/lib/libgfxd/Makefile
new file mode 100644
index 0000000..ffa49a6
--- /dev/null
+++ b/lib/libgfxd/Makefile
@@ -0,0 +1,19 @@
+CFLAGS = -Wall -O2 -g
+UC_OBJ = uc_f3d.o uc_f3db.o uc_f3dex.o uc_f3dexb.o uc_f3dex2.o
+OBJ = gfxd.o $(UC_OBJ)
+LIB = libgfxd.a
+
+CPPFLAGS-$(MT) += -DCONFIG_MT
+CPPFLAGS += $(CPPFLAGS-y)
+
+.PHONY: all
+all: $(LIB)($(OBJ))
+
+.PHONY: clean
+clean:
+ rm -f $(OBJ) $(LIB)
+
+.INTERMEDIATE: $(OBJ)
+
+$(OBJ): gbi.h gfxd.h priv.h
+$(UC_OBJ): uc.c uc_argfn.c uc_argtbl.c uc_macrofn.c uc_macrotbl.c
diff --git a/lib/libgfxd/README.md b/lib/libgfxd/README.md
new file mode 100644
index 0000000..2e82589
--- /dev/null
+++ b/lib/libgfxd/README.md
@@ -0,0 +1,478 @@
+## Installing
+Run `make` for a single-threaded build, or `make MT=y` for a multi-threaded
+build. Copy `libgfxd.a` to your lib directory, and `gfxd.h` to your include
+directory.
+
+## Example usage
+Example source code:
+```
+#include <stdio.h>
+#include <gfxd.h>
+
+static int macro_fn(void)
+{
+ /* Print a tab before each macro, and a comma and newline after each
+ macro */
+ gfxd_puts("\t");
+ gfxd_macro_dflt(); /* Execute the default macro handler */
+ gfxd_puts(",\n");
+
+ return 0;
+}
+
+int main()
+{
+ /* Read from stdin and write to stdout */
+ gfxd_input_fd(fileno(stdin));
+ gfxd_output_fd(fileno(stdout));
+
+ /* Override the default macro handler to make the output prettier */
+ gfxd_macro_fn(macro_fn);
+
+ /* Select F3DEX as the target microcode */
+ gfxd_target(gfxd_f3dex);
+
+ /* Set the input endianness to big endian, and the word size to 4 */
+ gfxd_endian(gfxd_endian_big, 4);
+
+ /* Print an opening brace */
+ gfxd_puts("{\n");
+
+ /* Execute until the end of input, or until encountering an invalid
+ command */
+ gfxd_execute();
+
+ /* Print a closing brace */
+ gfxd_puts("}\n");
+}
+```
+
+Example input (binary):
+```
+0xe7000000, 0x00000000,
+0xfc127e03, 0xfffffdf8,
+0xb900031d, 0xc8112078,
+0xb6000000, 0x000e0000,
+0xb7000000, 0x00012000,
+0xfa000000, 0xffffffff,
+0x040030bf, 0x000002e0,
+0xb1000204, 0x00020604,
+0xb1080a0c, 0x000a0e0c,
+0xb10a1012, 0x000a120e,
+0xb1140200, 0x00140016,
+0xb8000000, 0x00000000,
+```
+
+Example output:
+```
+{
+ gsDPPipeSync(),
+ gsDPSetCombineLERP(TEXEL0, 0, SHADE, 0, 0, 0, 0, 1, COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED),
+ gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2),
+ gsSPClearGeometryMode(G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR),
+ gsSPSetGeometryMode(G_CULL_BACK | G_FOG),
+ gsDPSetPrimColor(0, 0, 0xFF, 0xFF, 0xFF, 0xFF),
+ gsSPVertex(0x000002E0, 12, 0),
+ gsSP2Triangles(0, 1, 2, 0, 1, 3, 2, 0),
+ gsSP2Triangles(4, 5, 6, 0, 5, 7, 6, 0),
+ gsSP1Quadrangle(5, 8, 9, 7, 0),
+ gsSP1Quadrangle(10, 1, 0, 11, 0),
+ gsSPEndDisplayList(),
+}
+```
+
+## Input/output methods
+The input consists of any number of `Gfx` packets, and the output is the
+decompiled macros in plain-text. The endianness and microcode type of the input
+can be set using `gfxd_endian` and `gfxd_target`.
+
+Several methods of doing I/O are available. No method is selected by default,
+meaning there will be no input, and any output will be discarded.
+
+---
+
+##### `void gfxd_input_buffer(const void *buf, int size)`
+##### `void gfxd_output_buffer(char *buf, int size)`
+Use the buffer pointed to by `buf`, of `size` bytes.
+
+---
+
+##### `void gfxd_input_fd(int fd)`
+##### `void gfxd_output_fd(int fd)`
+Use `read()` / `write()` with the provided file descriptor, `fd`.
+
+---
+
+##### `typedef int gfxd_input_fn_t(void *buf, int count)`
+##### `typedef int gfxd_output_fn_t(const char *buf, int count)`
+##### `void gfxd_input_callback(gfxd_input_fn_t *fn)`
+##### `void gfxd_output_callback(gfxd_output_fn_t *fn)`
+Use the provided callback function, `fn`. `fn` should copy at most `count`
+bytes to/from `buf`, and return the number of bytes actually copied. The input
+callback should return 0 to signal end of input.
+
+## Handlers
+The macro handler function is responsible for writing the output of each
+decompiled macro. The default macro handler is `gfxd_macro_dflt`, but this can
+be changed with `gfxd_macro_fn`. The new handler can extend the default
+function by calling `gfxd_macro_dflt` within it, or it can override it
+completely.
+
+---
+
+##### `int gfxd_macro_dflt()`
+The default macro handler. Outputs the macro name, dynamic display list pointer
+if one has been specified, and then each argument in order using the function
+registered using `gfxd_arg_fn` (`gfxd_arg_dflt` by default), and returns zero.
+Because it is designed to be extended, it only outputs the macro text, without
+any whitespace or punctuation before or after. When this function is used as
+the sole macro handler, it will output the entire display list on one line
+without any separation between macros, which is probably not what you want.
+
+---
+
+##### `void gfxd_macro_fn(gfxd_macro_fn_t *fn)`
+Set `fn` to be the macro handler function. `fn` can be null, in which case the
+handler is reset to the default.
+
+---
+
+##### `void gfxd_arg_dflt(int arg_num)`
+The default argument handler for `gfxd_macro_dflt`. For the argument with index
+`arg_num`, calls `gfxd_arg_callbacks`, and prints the argument value if the
+callback returns zero, or if there is no callback for the given argument.
+
+---
+
+##### `void gfxd_arg_fn(gfxd_arg_fn_t *fn)`
+Set `fn` to be the argument handler function, called by `gfxd_macro_dflt`,
+for each argument in the current macro, not counting the dynamic display list
+pointer if one has been specified. `fn` can be null, in which case the handler
+is reset to the default. This only affects the output of `gfxd_macro_dflt`, and
+has no observable effect if `gfxd_macro_dflt` is overridden (not extended).
+
+## Argument callbacks
+Callbacks can be registered that will be executed when an argument of a certain
+type is encountered. The default argument handler `gfxd_arg_dflt` will execute
+callbacks as needed using `gfxd_arg_callbacks`. If a callback returns non-zero,
+`gfxd_arg_dflt` will not output anything. This is to allow callbacks to
+override the default argument output. Otherwise, `gfxd_arg_dflt` will output
+the argument value after the callback function's output.
+
+---
+
+##### `int gfxd_arg_callbacks(int arg_num)`
+Examines the argument with index `arg_num` and executes the callback function
+for that argument type, if such a callback is supported and has been
+registered. This function returns the value that was returned by the callback
+function. If no callback function has been registered for the argument type,
+zero is returned.
+
+Most argument callbacks have some extra parameters containing information that
+might be relevant to the argument that triggered the callback. The extra
+information is extracted only from the current macro, as gfxd does not retain
+any context information from previous or subsequent macros. If any of the extra
+parameter values is not available in the current macro, the value for that
+parameter is substituted with `-1` for signed parameters, and zero for unsigned
+parameters.
+
+---
+
+##### `typedef int gfxd_tlut_fn_t(uint32_t tlut, int32_t idx, int32_t count)`
+##### `void gfxd_tlut_callback(gfxd_tlut_fn_t *fn)`
+Set the callback function for palette arguments. The argument type is
+`gfxd_Tlut`. The palette index is in `idx` and the number of colors in `count`.
+
+---
+
+##### `typedef int gfxd_timg_fn_t(uint32_t timg, int32_t fmt, int32_t siz, int32_t width, int32_t height, int32_t pal)`
+##### `void gfxd_timg_callback(gfxd_timg_fn_t *fn)`
+Set the callback function for texture arguments. The argument type is
+`gfxd_Timg`. The image format is in `fmt` and `siz`, the dimensions in `width`
+and `height`, and the palette index in `pal`.
+
+---
+
+##### `typedef int gfxd_cimg_fn_t(uint32_t cimg, int32_t fmt, int32_t siz, int32_t width)`
+##### `void gfxd_cimg_callback(gfxd_cimg_fn_t *fn)`
+Set the callback function for frame buffer arguments. The argument type is
+`gfxd_Cimg`. The image format is in `fmt` and `siz`, and the horizontal
+resolution in `width`.
+
+---
+
+##### `typedef int gfxd_zimg_fn_t(uint32_t zimg)`
+##### `void gfxd_zimg_callback(gfxd_zimg_fn_t *fn)`
+Set the callback function for depth buffer arguments. The argument type is
+`gfxd_Zimg`.
+
+---
+
+##### `typedef int gfxd_dl_fn_t(uint32_t dl)`
+##### `void gfxd_dl_callback(gfxd_dl_fn_t *fn)`
+Set the callback function for display list arguments. The argument type is
+`gfxd_Dl`.
+
+---
+
+##### `typedef int gfxd_mtx_fn_t(uint32_t mtx)`
+##### `void gfxd_mtx_callback(gfxd_mtx_fn_t *fn)`
+Set the callback function for matrix arguments. The argument type is
+`gfxd_Mtxptr`.
+
+---
+
+##### `typedef int gfxd_lookat_fn_t(uint32_t lookat, int32_t count)`
+##### `void gfxd_lookat_callback(gfxd_lookat_fn_t *fn)`
+Set the callback function for lookat array arguments. The argument type is
+`gfxd_Lookatptr`. The number of lookat structures (1 or 2) is in `count`.
+
+---
+
+##### `typedef int gfxd_light_fn_t(uint32_t light, int32_t count)`
+##### `void gfxd_light_callback(gfxd_light_fn_t *fn)`
+Set the callback function for light array arguments. The argument type is
+`gfxd_Lightptr`. The number of light structures is in `count`.
+
+---
+
+##### `typedef int gfxd_seg_fn_t(uint32_t seg, int32_t num)`
+##### `void gfxd_seg_callback(gfxd_seg_fn_t *fn)`
+Set the callback function for segment base arguments. The argument type is
+`gfxd_Segptr`. The segment number is in `num`.
+
+---
+
+##### `typedef int gfxd_vtx_fn_t(uint32_t vtx, int32_t num)`
+##### `void gfxd_vtx_callback(gfxd_vtx_fn_t *fn)`
+Set the callback function for vertex array arguments. The argument type is
+`gfxd_Vtxptr`. The number of vertex structures is in `num`.
+
+---
+
+##### `typedef int gfxd_vp_fn_t(uint32_t vp)`
+##### `void gfxd_vp_callback(gfxd_vp_fn_t *fn)`
+Set the callback function for viewport arguments. The argument type is
+`gfxd_Vp`.
+
+---
+
+##### `typedef int gfxd_uctext_fn_t(uint32_t text, uint32_t size)`
+##### `void gfxd_uctext_callback(gfxd_uctext_fn_t *fn)`
+Set the callback function for microcode text arguments. The argument type is
+`gfxd_Uctext`. The size of the text segment is in `size`.
+
+---
+
+##### `typedef int gfxd_ucdata_fn_t(uint32_t data, uint32_t size)`
+##### `void gfxd_ucdata_callback(gfxd_ucdata_fn_t *fn)`
+Set the callback function for microcode data arguments. The argument type is
+`gfxd_Ucdata`. The size of the data segment is in `size`.
+
+---
+
+##### `typedef int gfxd_dram_fn_t(uint32_t dram, uint32_t size)`
+##### `void gfxd_dram_callback(gfxd_dram_fn_t *fn)`
+Set the callback function for generic pointer arguments. The argument type is
+`gfxd_Dram`. The size of the data is in `size`.
+
+## General settings
+These functions control general input and output settings.
+
+---
+
+##### `void gfxd_target(gfxd_ucode_t ucode)`
+Select `ucode` as the target microcode. `ucode` can be `gfxd_f3d`, `gfxd_f3db`,
+`gfxd_f3dex`, `gfxd_f3dexb`, or `gfxd_f3dex2`. The microcode must be selected
+before `gfxd_execute`, as no microcode is selected by default.
+
+---
+
+##### `void gfxd_endian(int endian, int wordsize)`
+Select `endian` as the endianness of the input, and `wordsize` as the size of
+each word in number of bytes. `endian` can be `gfxd_endian_big`,
+`gfxd_endian_little`, or `gfxd_endian_host` (the endianness of the host
+machine). `wordsize` can be 1, 2, 4, or 8. Big endian is selected by default,
+with a word size of 4.
+
+---
+
+##### `void gfxd_dynamic(const char *arg)`
+Enable or disable the use of dynamic `g` macros instead of static `gs` macros,
+and select the dynamic display list pointer argument to be used. `arg` will be
+used by `gfxd_macro_dflt` as the first argument to dynamic macros. If `arg` is
+null, dynamic macros are disabled, and `gs` macros are used. Also affects the
+result of `gfxd_macro_name`, as it will return either the dynamic or static
+version of the macro name as selected by this setting.
+
+---
+
+##### `void gfxd_enable(int cap)`
+##### `void gfxd_disable(int cap)`
+Enable or disable the feature specified by `cap`. Can be one of the following;
+- `gfxd_stop_on_invalid`: Stop execution when encountering an invalid macro.
+Enabled by default.
+- `gfxd_stop_on_end`: Stop execution when encountering a `SPBranchList` or
+`SPEndDisplayList`. Enabled by default.
+- `gfxd_emit_dec_color`: Print color components as decimal instead of
+hexadecimal. Disabled by default.
+- `gfxd_emit_q_macro`: Print fixed-point conversion `q` macros for fixed-point
+values. Disabled by default.
+- `gfxd_emit_ext_macro`: Emit non-standard macros. Some commands are valid
+(though possibly meaningless), but have no macros associated with them, such as
+a standalone `G_RDPHALF_1`. When this feature is enabled, such a command will
+produce a non-standard `gsDPHalf1` macro instead of a raw hexadecimal command.
+Also enables some non-standard multi-packet texture loading macros. Disabled by
+default.
+
+---
+
+##### `void gfxd_udata_set(void *ptr)`
+##### `void *gfxd_udata_get(void)`
+Set or get a generic pointer that can be used to pass user-defined data in and
+out of callback functions.
+
+## Execution
+Decompilation is started using the `gfxd_execute` function. When gfxd is
+executing (i.e. after `gfxd_execute` has been entered, and before it returns),
+the general settings and the I/O settings should not be changed.
+
+---
+
+##### `int gfxd_execute()`
+Start executing gfxd with the current settings. For each macro, the macro
+handler registered with `gfxd_macro_fn` is called. Execution ends when the
+input ends, the macro handler returns non-zero, when an invalid macro is
+encountered and `gfxd_stop_on_invalid` is enabled, or when `SPBranchList` or
+`SPEndDisplayList` is encountered and `gfxd_stop_on_end` is enabled. If
+execution ends due to an invalid macro, `-1` is returned. If execution ends
+because the macro handler returns non-zero, the return value from the macro
+handler is returned. Otherwise zero is returned.
+
+## Macro information
+The following functions can be used to obtain information about the current
+macro and its arguments. They should only be used in custom handlers and
+callbacks from within `gfxd_execute`. If used elsewhere, their behavior is
+undefined.
+
+---
+
+##### `int gfxd_macro_offset()`
+Returns the offset in the input data of the current macro. The offset starts
+at zero when `gfxd_execute` is called.
+
+---
+
+##### `int gfxd_macro_packets()`
+Returns the number of `Gfx` packets within the current macro.
+
+---
+
+##### `const void *gfxd_macro_data()`
+Returns a pointer to the input data for the current macro. The data is not
+byte-swapped. The data has a length of `sizeof(Gfx) * gfxd_macro_packets()`.
+
+---
+
+##### `int gfxd_macro_id()`
+Returns a number that uniquely identifies the current macro. The number will
+be one of the constants in `gfxd.h`.
+
+---
+
+##### `const char *gfxd_macro_name()`
+Returns the name of the current macro. If the macro does not have a name (i.e.
+it's invalid), null is returned. If a dynamic display list pointer has been
+specified, the dynamic `g` version is returned. Otherwise the static `gs`
+version is returned. The returned pointer is invalidated by a subsequent call
+to `gfxd_macro_name`.
+
+---
+
+##### `int gfxd_arg_count()`
+Returns the number of arguments to the current macro, not including a dynamic
+display list pointer if one has been specified.
+
+---
+
+##### `int gfxd_arg_type(int arg_num)`
+Returns a number that identifies the type of the argument with index `arg_num`.
+The number will be one of the constants in `gfxd.h`.
+
+---
+
+##### `const char *gfxd_arg_name(int arg_num)`
+Returns the name of the argument with index `arg_num`. Argument names are not
+canonical, nor are they needed for macro disassembly, but they can be useful
+for informational and diagnostic purposes.
+
+---
+
+##### `int gfxd_arg_fmt(int arg_num)`
+Returns the data format of the argument with index `arg_num`. The return value
+will be `gfxd_argfmt_i` for `int32_t`, `gfxd_argfmt_u` for `uint32_t`, or
+`gfxd_argfmt_f` for `float`. When accessing the value of the argument with
+`gfxd_arg_value`, the member with the corresponding type should be used.
+
+---
+
+##### `const gfxd_value_t *gfxd_arg_value(int arg_num)`
+Returns a pointer to the value of the argument with index `arg_num`. The value
+is a union of type `gfxd_value_t` with the following layout;
+```
+typedef union
+{
+ int32_t i;
+ uint32_t u;
+ float f;
+} gfxd_value_t
+```
+
+---
+
+##### `const gfxd_value_t *gfxd_value_by_type(int type, int idx)`
+Returns a pointer to the value of the argument that is of `type`, and has order
+`idx` in all arguments of that type. An `idx` of zero returns the first
+argument that has the specified type. If there is no argument with the given
+type and order, null is returned.
+
+---
+
+##### `int gfxd_arg_valid(int arg_num)`
+Returns non-zero if the argument with index `arg_num` is "valid", for some
+definition of valid. An invalid argument generally means that the disassembler
+found inconsistencies in the input data, or that the data can not be reproduced
+by the current macro type. The argument still has a value that can be printed,
+though the value is not guaranteed to make any sense.
+
+## Custom output
+When the default handlers are overridden or extended, the custom handler
+functions will want to do some output of their own. The following methods are
+available for inserting custom text into the gfxd output.
+
+---
+
+##### `int gfxd_write(const void *buf, int count)`
+Insert `count` bytes from the buffer at `buf` into the output. The number of
+characters written is returned.
+
+---
+
+##### `int gfxd_puts(const char *str)`
+Insert the null-terminated string at `str` into the output. The number of
+characters written is returned.
+
+---
+
+##### `int gfxd_printf(const char *fmt, ...)`
+Insert the printf-formatted string described by `fmt` and additional arguments
+into the output. Limited to 255 characters. The number of characters written is
+returned.
+
+---
+
+##### `int gfxd_print_value(int type, const gfxd_value_t *value)`
+Insert the type-formatted value into the output. The type should be one of the
+constants in `gfxd.h`. The number of characters written is returned. The
+macro argument with index `n` can be printed with
+`gfxd_print_value(gfxd_arg_type(n), gfxd_arg_value(n))`.
diff --git a/lib/libgfxd/gbi.h b/lib/libgfxd/gbi.h
new file mode 100644
index 0000000..e502ee9
--- /dev/null
+++ b/lib/libgfxd/gbi.h
@@ -0,0 +1,3808 @@
+/**
+ * gbi.h version 0.3.3
+ * n64 graphics microcode interface library
+ * compatible with fast3d, f3dex, f3dex2, s2dex, and s2dex2
+ *
+ * select a microcode with one of these preprocessor definitions;
+ * #define F3D_GBI
+ * for fast3d (selected automatically by default), or
+ * #define F3DEX_GBI
+ * for f3dex/s2dex, or
+ * #define F3DEX_GBI_2
+ * for f3dex2/s2dex2
+ *
+ * for early versions of fast3d and f3dex, also define the following;
+ * #define F3D_BETA
+ *
+ * ido incompatibilities;
+ * - use of c99 variadic macros
+ * - use of c99 fixed-width integer types
+ * - use of c99 designated initializers
+ * - use of c99 compound literals
+ * - use of c11 _Alignas
+ * - use of gnu c compound expressions
+ * - use of gnu c __typeof__
+ *
+ * libultra incompatibilities;
+ * - many private, undocumented, or obsolete macros not commonly used by
+ * programmers are missing
+ * - many different implementation details that will produce matching gbi,
+ * but not matching code
+**/
+
+#ifndef N64_GBI_H
+#define N64_GBI_H
+
+#include <stdint.h>
+
+/* use fast3d by default */
+#if !defined(F3D_GBI) && !defined(F3DEX_GBI) && !defined(F3DEX_GBI_2)
+# define F3D_GBI
+#endif
+
+/* commands for fast3d and f3dex */
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+# define G_SPNOOP 0x00
+# define G_MTX 0x01
+# define G_MOVEMEM 0x03
+# define G_VTX 0x04
+# define G_DL 0x06
+# if defined(F3D_BETA)
+# define G_RDPHALF_2 0xB2
+# define G_RDPHALF_1 0xB3
+# define G_PERSPNORM 0xB4
+# else
+# define G_RDPHALF_2 0xB3
+# define G_RDPHALF_1 0xB4
+# endif
+# define G_LINE3D 0xB5
+# define G_CLEARGEOMETRYMODE 0xB6
+# define G_SETGEOMETRYMODE 0xB7
+# define G_ENDDL 0xB8
+# define G_SETOTHERMODE_L 0xB9
+# define G_SETOTHERMODE_H 0xBA
+# define G_TEXTURE 0xBB
+# define G_MOVEWORD 0xBC
+# define G_POPMTX 0xBD
+# define G_CULLDL 0xBE
+# define G_TRI1 0xBF
+# define G_NOOP 0xC0
+#endif
+
+/* commands for f3dex */
+#if defined(F3DEX_GBI)
+# define G_LOAD_UCODE 0xAF
+# define G_BRANCH_Z 0xB0
+# define G_TRI2 0xB1
+# if !defined(F3D_BETA)
+# define G_MODIFYVTX 0xB2
+# endif
+#endif
+
+/* commands for f3dex2 */
+#if defined(F3DEX_GBI_2)
+# define G_NOOP 0x00
+# define G_VTX 0x01
+# define G_MODIFYVTX 0x02
+# define G_CULLDL 0x03
+# define G_BRANCH_Z 0x04
+# define G_TRI1 0x05
+# define G_TRI2 0x06
+# define G_QUAD 0x07
+# define G_LINE3D 0x08
+# define G_SPECIAL_3 0xD3
+# define G_SPECIAL_2 0xD4
+# define G_SPECIAL_1 0xD5
+# define G_DMA_IO 0xD6
+# define G_TEXTURE 0xD7
+# define G_POPMTX 0xD8
+# define G_GEOMETRYMODE 0xD9
+# define G_MTX 0xDA
+# define G_MOVEWORD 0xDB
+# define G_MOVEMEM 0xDC
+# define G_LOAD_UCODE 0xDD
+# define G_DL 0xDE
+# define G_ENDDL 0xDF
+# define G_SPNOOP 0xE0
+# define G_RDPHALF_1 0xE1
+# define G_SETOTHERMODE_L 0xE2
+# define G_SETOTHERMODE_H 0xE3
+# define G_RDPHALF_2 0xF1
+#endif
+
+/* rdp commands */
+#define G_TEXRECT 0xE4
+#define G_TEXRECTFLIP 0xE5
+#define G_RDPLOADSYNC 0xE6
+#define G_RDPPIPESYNC 0xE7
+#define G_RDPTILESYNC 0xE8
+#define G_RDPFULLSYNC 0xE9
+#define G_SETKEYGB 0xEA
+#define G_SETKEYR 0xEB
+#define G_SETCONVERT 0xEC
+#define G_SETSCISSOR 0xED
+#define G_SETPRIMDEPTH 0xEE
+#define G_RDPSETOTHERMODE 0xEF
+#define G_LOADTLUT 0xF0
+#define G_SETTILESIZE 0xF2
+#define G_LOADBLOCK 0xF3
+#define G_LOADTILE 0xF4
+#define G_SETTILE 0xF5
+#define G_FILLRECT 0xF6
+#define G_SETFILLCOLOR 0xF7
+#define G_SETFOGCOLOR 0xF8
+#define G_SETBLENDCOLOR 0xF9
+#define G_SETPRIMCOLOR 0xFA
+#define G_SETENVCOLOR 0xFB
+#define G_SETCOMBINE 0xFC
+#define G_SETTIMG 0xFD
+#define G_SETZIMG 0xFE
+#define G_SETCIMG 0xFF
+
+/* commands for s2dex */
+#if defined(F3DEX_GBI)
+# define G_BG_1CYC 0x01
+# define G_BG_COPY 0x02
+# define G_OBJ_RECTANGLE 0x03
+# define G_OBJ_SPRITE 0x04
+# define G_OBJ_MOVEMEM 0x05
+# define G_SELECT_DL 0xB0
+# define G_OBJ_RENDERMODE 0xB1
+# define G_OBJ_RECTANGLE_R 0xB2
+# define G_OBJ_LOADTXTR 0xC1
+# define G_OBJ_LDTX_SPRITE 0xC2
+# define G_OBJ_LDTX_RECT 0xC3
+# define G_OBJ_LDTX_RECT_R 0xC4
+#endif
+
+/* commands for s2dex2 */
+#if defined(F3DEX_GBI_2)
+# define G_OBJ_RECTANGLE 0x01
+# define G_OBJ_SPRITE 0x02
+# define G_SELECT_DL 0x04
+# define G_OBJ_LOADTXTR 0x05
+# define G_OBJ_LDTX_SPRITE 0x06
+# define G_OBJ_LDTX_RECT 0x07
+# define G_OBJ_LDTX_RECT_R 0x08
+# define G_BG_1CYC 0x09
+# define G_BG_COPY 0x0A
+# define G_OBJ_RENDERMODE 0x0B
+# define G_OBJ_RECTANGLE_R 0xDA
+# define G_OBJ_MOVEMEM 0xDC
+#endif
+
+/* commands for s2dex and s2dex2 */
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+# define G_RDPHALF_0 0xE4
+#endif
+
+/* image formats */
+#define G_IM_FMT_RGBA 0
+#define G_IM_FMT_YUV 1
+#define G_IM_FMT_CI 2
+#define G_IM_FMT_IA 3
+#define G_IM_FMT_I 4
+#define G_IM_SIZ_4b 0
+#define G_IM_SIZ_8b 1
+#define G_IM_SIZ_16b 2
+#define G_IM_SIZ_32b 3
+
+/* texture settings */
+#define G_TX_NOMIRROR (gI_(0b0) << 0)
+#define G_TX_MIRROR (gI_(0b1) << 0)
+#define G_TX_WRAP (gI_(0b0) << 1)
+#define G_TX_CLAMP (gI_(0b1) << 1)
+#define G_TX_NOMASK gI_(0)
+#define G_TX_NOLOD gI_(0)
+#define G_OFF gI_(0)
+#define G_ON gI_(1)
+
+/* tile indices */
+#define G_TX_LOADTILE 7
+#define G_TX_RENDERTILE 0
+
+/* geometry mode */
+#define G_ZBUFFER (gI_(0b1) << 0)
+#define G_SHADE (gI_(0b1) << 2)
+#define G_CULL_BOTH (G_CULL_FRONT | G_CULL_BACK)
+#define G_FOG (gI_(0b1) << 16)
+#define G_LIGHTING (gI_(0b1) << 17)
+#define G_TEXTURE_GEN (gI_(0b1) << 18)
+#define G_TEXTURE_GEN_LINEAR (gI_(0b1) << 19)
+#define G_LOD (gI_(0b1) << 20)
+
+/* geometry mode for fast3d */
+#if defined(F3D_GBI)
+# define G_CLIPPING (gI_(0b0) << 0)
+#endif
+
+/* geometry mode for fast3d and f3dex */
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+# define G_TEXTURE_ENABLE (gI_(0b1) << 1)
+# define G_SHADING_SMOOTH (gI_(0b1) << 9)
+# define G_CULL_FRONT (gI_(0b1) << 12)
+# define G_CULL_BACK (gI_(0b1) << 13)
+#endif
+
+/* geometry mode for f3dex and f3dex2 */
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+# define G_CLIPPING (gI_(0b1) << 23)
+#endif
+
+/* geometry mode for f3dex2 */
+#if defined(F3DEX_GBI_2)
+# define G_TEXTURE_ENABLE (gI_(0b0) << 0)
+# define G_CULL_FRONT (gI_(0b1) << 9)
+# define G_CULL_BACK (gI_(0b1) << 10)
+# define G_SHADING_SMOOTH (gI_(0b1) << 21)
+#endif
+
+/* othermode lo */
+#define G_MDSFT_ALPHACOMPARE 0
+#define G_MDSFT_ZSRCSEL 2
+#define G_MDSFT_RENDERMODE 3
+#define G_MDSFT_BLENDER 16
+#define G_MDSIZ_ALPHACOMPARE 2
+#define G_MDSIZ_ZSRCSEL 1
+#define G_MDSIZ_RENDERMODE 29
+#define G_MDSIZ_BLENDER 13
+
+#define G_AC_NONE (gI_(0b00) << G_MDSFT_ALPHACOMPARE)
+#define G_AC_THRESHOLD (gI_(0b01) << G_MDSFT_ALPHACOMPARE)
+#define G_AC_DITHER (gI_(0b11) << G_MDSFT_ALPHACOMPARE)
+#define G_ZS_PIXEL (gI_(0b0) << G_MDSFT_ZSRCSEL)
+#define G_ZS_PRIM (gI_(0b1) << G_MDSFT_ZSRCSEL)
+#define AA_EN (gI_(0b1) << (G_MDSFT_RENDERMODE + 0))
+#define Z_CMP (gI_(0b1) << (G_MDSFT_RENDERMODE + 1))
+#define Z_UPD (gI_(0b1) << (G_MDSFT_RENDERMODE + 2))
+#define IM_RD (gI_(0b1) << (G_MDSFT_RENDERMODE + 3))
+#define CLR_ON_CVG (gI_(0b1) << (G_MDSFT_RENDERMODE + 4))
+#define CVG_DST_CLAMP (gI_(0b00) << (G_MDSFT_RENDERMODE + 5))
+#define CVG_DST_WRAP (gI_(0b01) << (G_MDSFT_RENDERMODE + 5))
+#define CVG_DST_FULL (gI_(0b10) << (G_MDSFT_RENDERMODE + 5))
+#define CVG_DST_SAVE (gI_(0b11) << (G_MDSFT_RENDERMODE + 5))
+#define ZMODE_OPA (gI_(0b00) << (G_MDSFT_RENDERMODE + 7))
+#define ZMODE_INTER (gI_(0b01) << (G_MDSFT_RENDERMODE + 7))
+#define ZMODE_XLU (gI_(0b10) << (G_MDSFT_RENDERMODE + 7))
+#define ZMODE_DEC (gI_(0b11) << (G_MDSFT_RENDERMODE + 7))
+#define CVG_X_ALPHA (gI_(0b1) << (G_MDSFT_RENDERMODE + 9))
+#define ALPHA_CVG_SEL (gI_(0b1) << (G_MDSFT_RENDERMODE + 10))
+#define FORCE_BL (gI_(0b1) << (G_MDSFT_RENDERMODE + 11))
+
+#define G_BL_1MA gI_(0b00)
+#define G_BL_1 gI_(0b10)
+#define G_BL_0 gI_(0b11)
+#define G_BL_CLR_IN gI_(0b00)
+#define G_BL_CLR_MEM gI_(0b01)
+#define G_BL_CLR_BL gI_(0b10)
+#define G_BL_CLR_FOG gI_(0b11)
+#define G_BL_A_IN gI_(0b00)
+#define G_BL_A_FOG gI_(0b01)
+#define G_BL_A_MEM gI_(0b01)
+#define G_BL_A_SHADE gI_(0b10)
+
+#define GBL_c1(p, a, m, b) \
+ ( \
+ gF_(p, 2, 30) | \
+ gF_(a, 2, 26) | \
+ gF_(m, 2, 22) | \
+ gF_(b, 2, 18) \
+ )
+#define GBL_c2(p, a, m, b) \
+ ( \
+ gF_(p, 2, 28) | \
+ gF_(a, 2, 24) | \
+ gF_(m, 2, 20) | \
+ gF_(b, 2, 16) \
+ )
+
+/* render modes */
+#define G_RM_OPA_SURF \
+ ( \
+ CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_OPA_SURF2 \
+ ( \
+ CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_AA_OPA_SURF \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_OPA_SURF2 \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_RA_OPA_SURF \
+ ( \
+ AA_EN | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_RA_OPA_SURF2 \
+ ( \
+ AA_EN | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_ZB_OPA_SURF \
+ ( \
+ Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_ZB_OPA_SURF2 \
+ ( \
+ Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_OPA_SURF \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_OPA_SURF2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_RA_ZB_OPA_SURF \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_RA_ZB_OPA_SURF2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+
+#define G_RM_XLU_SURF \
+ ( \
+ IM_RD | CVG_DST_FULL | ZMODE_OPA | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_XLU_SURF2 \
+ ( \
+ IM_RD | CVG_DST_FULL | ZMODE_OPA | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_XLU_SURF \
+ ( \
+ AA_EN | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_OPA | \
+ FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_XLU_SURF2 \
+ ( \
+ AA_EN | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_OPA | \
+ FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_ZB_XLU_SURF \
+ ( \
+ Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_XLU | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_ZB_XLU_SURF2 \
+ ( \
+ Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_XLU | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_XLU_SURF \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | \
+ ZMODE_XLU | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_XLU_SURF2 \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | \
+ ZMODE_XLU | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_ZB_OPA_DECAL \
+ ( \
+ Z_CMP | CVG_DST_FULL | ZMODE_DEC | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_ZB_OPA_DECAL2 \
+ ( \
+ Z_CMP | CVG_DST_FULL | ZMODE_DEC | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_OPA_DECAL \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | ZMODE_DEC | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_OPA_DECAL2 \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | ZMODE_DEC | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_RA_ZB_OPA_DECAL \
+ ( \
+ AA_EN | Z_CMP | CVG_DST_WRAP | ZMODE_DEC | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_RA_ZB_OPA_DECAL2 \
+ ( \
+ AA_EN | Z_CMP | CVG_DST_WRAP | ZMODE_DEC | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+
+#define G_RM_ZB_XLU_DECAL \
+ ( \
+ Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_DEC | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_ZB_XLU_DECAL2 \
+ ( \
+ Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_DEC | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_XLU_DECAL \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | \
+ ZMODE_DEC | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_XLU_DECAL2 \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | \
+ ZMODE_DEC | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_AA_ZB_OPA_INTER \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_INTER | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_OPA_INTER2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_INTER | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_RA_ZB_OPA_INTER \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | ZMODE_INTER | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_RA_ZB_OPA_INTER2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | ZMODE_INTER | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+
+#define G_RM_AA_ZB_XLU_INTER \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | \
+ ZMODE_INTER | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_XLU_INTER2 \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | \
+ ZMODE_INTER | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_AA_XLU_LINE \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_XLU_LINE2 \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_XLU_LINE \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | ZMODE_XLU | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_XLU_LINE2 \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | ZMODE_XLU | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_AA_DEC_LINE \
+ ( \
+ AA_EN | IM_RD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_DEC_LINE2 \
+ ( \
+ AA_EN | IM_RD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_DEC_LINE \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CVG_DST_SAVE | ZMODE_DEC | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_DEC_LINE2 \
+ ( \
+ AA_EN | Z_CMP | IM_RD | CVG_DST_SAVE | ZMODE_DEC | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+
+#define G_RM_TEX_EDGE \
+ ( \
+ AA_EN | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_TEX_EDGE2 \
+ ( \
+ AA_EN | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_AA_TEX_EDGE \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_TEX_EDGE2 \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_TEX_EDGE \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_TEX_EDGE2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+
+#define G_RM_AA_ZB_TEX_INTER \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_INTER | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_TEX_INTER2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_INTER | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+
+#define G_RM_AA_SUB_SURF \
+ ( \
+ AA_EN | IM_RD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_SUB_SURF2 \
+ ( \
+ AA_EN | IM_RD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_SUB_SURF \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+#define G_RM_AA_ZB_SUB_SURF2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) \
+ )
+
+#define G_RM_PCL_SURF \
+ ( \
+ G_AC_DITHER | CVG_DST_FULL | ZMODE_OPA | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_PCL_SURF2 \
+ ( \
+ G_AC_DITHER | CVG_DST_FULL | ZMODE_OPA | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_AA_PCL_SURF \
+ ( \
+ G_AC_DITHER | AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_PCL_SURF2 \
+ ( \
+ G_AC_DITHER | AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_ZB_PCL_SURF \
+ ( \
+ G_AC_DITHER | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | \
+ GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_ZB_PCL_SURF2 \
+ ( \
+ G_AC_DITHER | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | \
+ GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_AA_ZB_PCL_SURF \
+ ( \
+ G_AC_DITHER | AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
+ ZMODE_OPA | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_PCL_SURF2 \
+ ( \
+ G_AC_DITHER | AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \
+ ZMODE_OPA | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_AA_OPA_TERR \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_OPA_TERR2 \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_OPA_TERR \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_OPA_TERR2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_AA_TEX_TERR \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_TEX_TERR2 \
+ ( \
+ AA_EN | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_TEX_TERR \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_TEX_TERR2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | \
+ CVG_X_ALPHA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_AA_SUB_TERR \
+ ( \
+ AA_EN | IM_RD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_SUB_TERR2 \
+ ( \
+ AA_EN | IM_RD | CVG_DST_FULL | ZMODE_OPA | ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_SUB_TERR \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_ZB_SUB_TERR2 \
+ ( \
+ AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | ZMODE_OPA | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_CLD_SURF \
+ ( \
+ IM_RD | CVG_DST_SAVE | ZMODE_OPA | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_CLD_SURF2 \
+ ( \
+ IM_RD | CVG_DST_SAVE | ZMODE_OPA | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_ZB_CLD_SURF \
+ ( \
+ Z_CMP | IM_RD | CVG_DST_SAVE | ZMODE_XLU | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_ZB_CLD_SURF2 \
+ ( \
+ Z_CMP | IM_RD | CVG_DST_SAVE | ZMODE_XLU | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_ZB_OVL_SURF \
+ ( \
+ Z_CMP | IM_RD | CVG_DST_SAVE | ZMODE_DEC | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_ZB_OVL_SURF2 \
+ ( \
+ Z_CMP | IM_RD | CVG_DST_SAVE | ZMODE_DEC | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+
+#define G_RM_ADD \
+ ( \
+ IM_RD | CVG_DST_SAVE | ZMODE_OPA | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_1) \
+ )
+#define G_RM_ADD2 \
+ ( \
+ IM_RD | CVG_DST_SAVE | ZMODE_OPA | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_1) \
+ )
+
+#define G_RM_FOG_SHADE_A \
+ GBL_c1(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA)
+
+#define G_RM_FOG_PRIM_A \
+ GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA)
+
+#define G_RM_PASS \
+ GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)
+
+#define G_RM_VISCVG \
+ ( \
+ IM_RD | FORCE_BL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_BL, G_BL_A_MEM) \
+ )
+#define G_RM_VISCVG2 \
+ ( \
+ IM_RD | FORCE_BL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_BL, G_BL_A_MEM) \
+ )
+
+#define G_RM_OPA_CI \
+ ( \
+ CVG_DST_CLAMP | ZMODE_OPA | \
+ GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+#define G_RM_OPA_CI2 \
+ ( \
+ CVG_DST_CLAMP | ZMODE_OPA | \
+ GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) \
+ )
+
+#define G_RM_NOOP GBL_c1(0, 0, 0, 0)
+#define G_RM_NOOP2 GBL_c2(0, 0, 0, 0)
+
+#define G_RM_SPRITE G_RM_OPA_SURF
+#define G_RM_SPRITE2 G_RM_OPA_SURF2
+#define G_RM_RA_SPRITE \
+ ( \
+ AA_EN | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | \
+ GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_RA_SPRITE2 \
+ ( \
+ AA_EN | CVG_DST_CLAMP | ZMODE_OPA | CVG_X_ALPHA | \
+ ALPHA_CVG_SEL | \
+ GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) \
+ )
+#define G_RM_AA_SPRITE G_RM_AA_TEX_TERR
+#define G_RM_AA_SPRITE2 G_RM_AA_TEX_TERR2
+#define G_RM_XLU_SPRITE G_RM_XLU_SURF
+#define G_RM_XLU_SPRITE2 G_RM_XLU_SURF2
+#define G_RM_AA_XLU_SPRITE G_RM_AA_XLU_SURF
+#define G_RM_AA_XLU_SPRITE2 G_RM_AA_XLU_SURF2
+
+#define G_OBJRM_NOTXCLAMP (gI_(0b1) << 0)
+#define G_OBJRM_XLU (gI_(0b1) << 1)
+#define G_OBJRM_ANTIALIAS (gI_(0b1) << 2)
+#define G_OBJRM_BILERP (gI_(0b1) << 3)
+#define G_OBJRM_SHRINKSIZE_1 (gI_(0b1) << 4)
+#define G_OBJRM_SHRINKSIZE_2 (gI_(0b1) << 5)
+#define G_OBJRM_WIDEN (gI_(0b1) << 6)
+
+/* othermode hi */
+#define G_MDSFT_ALPHADITHER 4
+#define G_MDSFT_RGBDITHER 6
+#define G_MDSFT_COMBKEY 8
+#define G_MDSFT_TEXTCONV 9
+#define G_MDSFT_TEXTFILT 12
+#define G_MDSFT_TEXTLUT 14
+#define G_MDSFT_TEXTLOD 16
+#define G_MDSFT_TEXTDETAIL 17
+#define G_MDSFT_TEXTPERSP 19
+#define G_MDSFT_CYCLETYPE 20
+#define G_MDSFT_PIPELINE 23
+#define G_MDSIZ_ALPHADITHER 2
+#define G_MDSIZ_RGBDITHER 2
+#define G_MDSIZ_COMBKEY 1
+#define G_MDSIZ_TEXTCONV 3
+#define G_MDSIZ_TEXTFILT 2
+#define G_MDSIZ_TEXTLUT 2
+#define G_MDSIZ_TEXTLOD 1
+#define G_MDSIZ_TEXTDETAIL 2
+#define G_MDSIZ_TEXTPERSP 1
+#define G_MDSIZ_CYCLETYPE 2
+#define G_MDSIZ_PIPELINE 1
+
+#define G_AD_PATTERN (gI_(0b00) << G_MDSFT_ALPHADITHER)
+#define G_AD_NOTPATTERN (gI_(0b01) << G_MDSFT_ALPHADITHER)
+#define G_AD_NOISE (gI_(0b10) << G_MDSFT_ALPHADITHER)
+#define G_AD_DISABLE (gI_(0b11) << G_MDSFT_ALPHADITHER)
+#define G_CD_MAGICSQ (gI_(0b00) << G_MDSFT_RGBDITHER)
+#define G_CD_BAYER (gI_(0b01) << G_MDSFT_RGBDITHER)
+#define G_CD_NOISE (gI_(0b10) << G_MDSFT_RGBDITHER)
+#define G_CD_DISABLE (gI_(0b11) << G_MDSFT_RGBDITHER)
+#define G_CD_ENABLE (gI_(0b10) << G_MDSFT_RGBDITHER)
+#define G_CK_NONE (gI_(0b0) << G_MDSFT_COMBKEY)
+#define G_CK_KEY (gI_(0b1) << G_MDSFT_COMBKEY)
+#define G_TC_CONV (gI_(0b000) << G_MDSFT_TEXTCONV)
+#define G_TC_FILTCONV (gI_(0b101) << G_MDSFT_TEXTCONV)
+#define G_TC_FILT (gI_(0b110) << G_MDSFT_TEXTCONV)
+#define G_TF_POINT (gI_(0b00) << G_MDSFT_TEXTFILT)
+#define G_TF_BILERP (gI_(0b10) << G_MDSFT_TEXTFILT)
+#define G_TF_AVERAGE (gI_(0b11) << G_MDSFT_TEXTFILT)
+#define G_TT_NONE (gI_(0b00) << G_MDSFT_TEXTLUT)
+#define G_TT_RGBA16 (gI_(0b10) << G_MDSFT_TEXTLUT)
+#define G_TT_IA16 (gI_(0b11) << G_MDSFT_TEXTLUT)
+#define G_TL_TILE (gI_(0b0) << G_MDSFT_TEXTLOD)
+#define G_TL_LOD (gI_(0b1) << G_MDSFT_TEXTLOD)
+#define G_TD_CLAMP (gI_(0b00) << G_MDSFT_TEXTDETAIL)
+#define G_TD_SHARPEN (gI_(0b01) << G_MDSFT_TEXTDETAIL)
+#define G_TD_DETAIL (gI_(0b10) << G_MDSFT_TEXTDETAIL)
+#define G_TP_NONE (gI_(0b0) << G_MDSFT_TEXTPERSP)
+#define G_TP_PERSP (gI_(0b1) << G_MDSFT_TEXTPERSP)
+#define G_CYC_1CYCLE (gI_(0b00) << G_MDSFT_CYCLETYPE)
+#define G_CYC_2CYCLE (gI_(0b01) << G_MDSFT_CYCLETYPE)
+#define G_CYC_COPY (gI_(0b10) << G_MDSFT_CYCLETYPE)
+#define G_CYC_FILL (gI_(0b11) << G_MDSFT_CYCLETYPE)
+#define G_PM_NPRIMITIVE (gI_(0b0) << G_MDSFT_PIPELINE)
+#define G_PM_1PRIMITIVE (gI_(0b1) << G_MDSFT_PIPELINE)
+
+/* color conversion constants */
+#define G_CV_K0 (175)
+#define G_CV_K1 (-43)
+#define G_CV_K2 (-89)
+#define G_CV_K3 (222)
+#define G_CV_K4 (114)
+#define G_CV_K5 (42)
+
+/* color combiner */
+#define G_CCMUX_COMBINED 0
+#define G_CCMUX_TEXEL0 1
+#define G_CCMUX_TEXEL1 2
+#define G_CCMUX_PRIMITIVE 3
+#define G_CCMUX_SHADE 4
+#define G_CCMUX_ENVIRONMENT 5
+#define G_CCMUX_1 6
+#define G_CCMUX_NOISE 7
+#define G_CCMUX_0 31
+#define G_CCMUX_CENTER 6
+#define G_CCMUX_K4 7
+#define G_CCMUX_SCALE 6
+#define G_CCMUX_COMBINED_ALPHA 7
+#define G_CCMUX_TEXEL0_ALPHA 8
+#define G_CCMUX_TEXEL1_ALPHA 9
+#define G_CCMUX_PRIMITIVE_ALPHA 10
+#define G_CCMUX_SHADE_ALPHA 11
+#define G_CCMUX_ENV_ALPHA 12
+#define G_CCMUX_LOD_FRACTION 13
+#define G_CCMUX_PRIM_LOD_FRAC 14
+#define G_CCMUX_K5 15
+#define G_ACMUX_COMBINED 0
+#define G_ACMUX_TEXEL0 1
+#define G_ACMUX_TEXEL1 2
+#define G_ACMUX_PRIMITIVE 3
+#define G_ACMUX_SHADE 4
+#define G_ACMUX_ENVIRONMENT 5
+#define G_ACMUX_1 6
+#define G_ACMUX_0 7
+#define G_ACMUX_LOD_FRACTION 0
+#define G_ACMUX_PRIM_LOD_FRAC 6
+
+/*
+ * combine modes
+ * ( A - B ) * C + D
+*/
+#define G_CC_MODULATEI \
+ TEXEL0, 0, SHADE, 0, \
+ 0, 0, 0, SHADE
+#define G_CC_MODULATEIA \
+ TEXEL0, 0, SHADE, 0, \
+ TEXEL0, 0, SHADE, 0
+#define G_CC_MODULATEIDECALA \
+ TEXEL0, 0, SHADE, 0, \
+ 0, 0, 0, TEXEL0
+#define G_CC_MODULATERGB \
+ G_CC_MODULATEI
+#define G_CC_MODULATERGBA \
+ G_CC_MODULATEIA
+#define G_CC_MODULATERGBDECALA \
+ G_CC_MODULATEIDECALA
+#define G_CC_MODULATEI_PRIM \
+ TEXEL0, 0, PRIMITIVE, 0, \
+ 0, 0, 0, PRIMITIVE
+#define G_CC_MODULATEIA_PRIM \
+ TEXEL0, 0, PRIMITIVE, 0, \
+ TEXEL0, 0, PRIMITIVE, 0
+#define G_CC_MODULATEIDECALA_PRIM \
+ TEXEL0, 0, PRIMITIVE, 0, \
+ 0, 0, 0, TEXEL0
+#define G_CC_MODULATERGB_PRIM \
+ G_CC_MODULATEI_PRIM
+#define G_CC_MODULATERGBA_PRIM \
+ G_CC_MODULATEIA_PRIM
+#define G_CC_MODULATERGBDECALA_PRIM \
+ G_CC_MODULATEIDECALA_PRIM
+#define G_CC_DECALRGB \
+ 0, 0, 0, TEXEL0, \
+ 0, 0, 0, SHADE
+#define G_CC_DECALRGBA \
+ 0, 0, 0, TEXEL0, \
+ 0, 0, 0, TEXEL0
+#define G_CC_BLENDI \
+ ENVIRONMENT, SHADE, TEXEL0, SHADE, \
+ 0, 0, 0, SHADE
+#define G_CC_BLENDIA \
+ ENVIRONMENT, SHADE, TEXEL0, SHADE, \
+ TEXEL0, 0, SHADE, 0
+#define G_CC_BLENDIDECALA \
+ ENVIRONMENT, SHADE, TEXEL0, SHADE, \
+ 0, 0, 0, TEXEL0
+#define G_CC_BLENDRGBA \
+ TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, \
+ 0, 0, 0, SHADE
+#define G_CC_BLENDRGBDECALA \
+ TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, \
+ 0, 0, 0, TEXEL0
+#define G_CC_REFLECTRGB \
+ ENVIRONMENT, 0, TEXEL0, SHADE, \
+ 0, 0, 0, SHADE
+#define G_CC_REFLECTRGBDECALA \
+ ENVIRONMENT, 0, TEXEL0, SHADE, \
+ 0, 0, 0, TEXEL0
+#define G_CC_HILITERGB \
+ PRIMITIVE, SHADE, TEXEL0, SHADE, \
+ 0, 0, 0, SHADE
+#define G_CC_HILITERGBA \
+ PRIMITIVE, SHADE, TEXEL0, SHADE, \
+ PRIMITIVE, SHADE, TEXEL0, SHADE
+#define G_CC_HILITERGBDECALA \
+ PRIMITIVE, SHADE, TEXEL0, SHADE, \
+ 0, 0, 0, TEXEL0
+#define G_CC_1CYUV2RGB \
+ TEXEL0, K4, K5, TEXEL0, \
+ 0, 0, 0, SHADE
+#define G_CC_PRIMITIVE \
+ 0, 0, 0, PRIMITIVE, \
+ 0, 0, 0, PRIMITIVE
+#define G_CC_SHADE \
+ 0, 0, 0, SHADE, \
+ 0, 0, 0, SHADE
+#define G_CC_ADDRGB \
+ 1, 0, TEXEL0, SHADE, \
+ 0, 0, 0, SHADE
+#define G_CC_ADDRGBDECALA \
+ 1, 0, TEXEL0, SHADE, \
+ 0, 0, 0, TEXEL0
+#define G_CC_SHADEDECALA \
+ 0, 0, 0, SHADE, \
+ 0, 0, 0, TEXEL0
+#define G_CC_BLENDPE \
+ PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, \
+ TEXEL0, 0, SHADE, 0
+#define G_CC_BLENDPEDECALA \
+ PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, \
+ 0, 0, 0, TEXEL0
+#define G_CC_TRILERP \
+ TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0, \
+ TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0
+#define G_CC_TEMPLERP \
+ TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, \
+ TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0
+#define G_CC_INTERFERENCE \
+ TEXEL0, 0, TEXEL1, 0, \
+ TEXEL0, 0, TEXEL1, 0
+#define _G_CC_BLENDPE \
+ ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, \
+ TEXEL0, 0, SHADE, 0
+#define _G_CC_BLENDPEDECALA \
+ ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, \
+ 0, 0, 0, TEXEL0
+#define _G_CC_SPARSEST \
+ PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0, \
+ PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0
+#define _G_CC_TWOCOLORTEX \
+ PRIMITIVE, SHADE, TEXEL0, SHADE, \
+ 0, 0, 0, SHADE
+#define G_CC_MODULATEI2 \
+ COMBINED, 0, SHADE, 0, \
+ 0, 0, 0, SHADE
+#define G_CC_MODULATEIA2 \
+ COMBINED, 0, SHADE, 0, \
+ COMBINED, 0, SHADE, 0
+#define G_CC_MODULATERGB2 \
+ G_CC_MODULATEI2
+#define G_CC_MODULATERGBA2 \
+ G_CC_MODULATEIA2
+#define G_CC_MODULATEI_PRIM2 \
+ COMBINED, 0, PRIMITIVE, 0, \
+ 0, 0, 0, PRIMITIVE
+#define G_CC_MODULATEIA_PRIM2 \
+ COMBINED, 0, PRIMITIVE, 0, \
+ COMBINED, 0, PRIMITIVE, 0
+#define G_CC_MODULATERGB_PRIM2 \
+ G_CC_MODULATEI_PRIM2
+#define G_CC_MODULATERGBA_PRIM2 \
+ G_CC_MODULATEIA_PRIM2
+#define G_CC_DECALRGB2 \
+ 0, 0, 0, COMBINED, \
+ 0, 0, 0, SHADE
+#define G_CC_BLENDI2 \
+ ENVIRONMENT, SHADE, COMBINED, SHADE, \
+ 0, 0, 0, SHADE
+#define G_CC_BLENDIA2 \
+ ENVIRONMENT, SHADE, COMBINED, SHADE, \
+ COMBINED, 0, SHADE, 0
+#define G_CC_HILITERGB2 \
+ ENVIRONMENT, COMBINED, TEXEL0, COMBINED, \
+ 0, 0, 0, SHADE
+#define G_CC_HILITERGBA2 \
+ ENVIRONMENT, COMBINED, TEXEL0, COMBINED, \
+ ENVIRONMENT, COMBINED, TEXEL0, COMBINED
+#define G_CC_HILITERGBDECALA2 \
+ ENVIRONMENT, COMBINED, TEXEL0, COMBINED, \
+ 0, 0, 0, TEXEL0
+#define G_CC_HILITERGBPASSA2 \
+ ENVIRONMENT, COMBINED, TEXEL0, COMBINED, \
+ 0, 0, 0, COMBINED
+#define G_CC_CHROMA_KEY2 \
+ TEXEL0, CENTER, SCALE, 0, \
+ 0, 0, 0, 0
+#define G_CC_YUV2RGB \
+ TEXEL1, K4, K5, TEXEL1, \
+ 0, 0, 0, 0
+#define G_CC_PASS2 \
+ 0, 0, 0, COMBINED, \
+ 0, 0, 0, COMBINED
+#define G_CC_LERP(a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
+ a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \
+ ( \
+ gFL_(G_CCMUX_##a0, 4, 52) | \
+ gFL_(G_CCMUX_##c0, 5, 47) | \
+ gFL_(G_ACMUX_##Aa0, 3, 44) | \
+ gFL_(G_ACMUX_##Ac0, 3, 41) | \
+ gFL_(G_CCMUX_##a1, 4, 37) | \
+ gFL_(G_CCMUX_##c1, 5, 32) | \
+ gFL_(G_CCMUX_##b0, 4, 28) | \
+ gFL_(G_CCMUX_##b1, 4, 24) | \
+ gFL_(G_ACMUX_##Aa1, 3, 21) | \
+ gFL_(G_ACMUX_##Ac1, 3, 18) | \
+ gFL_(G_CCMUX_##d0, 3, 15) | \
+ gFL_(G_ACMUX_##Ab0, 3, 12) | \
+ gFL_(G_ACMUX_##Ad0, 3, 9) | \
+ gFL_(G_CCMUX_##d1, 3, 6) | \
+ gFL_(G_ACMUX_##Ab1, 3, 3) | \
+ gFL_(G_ACMUX_##Ad1, 3, 0) \
+ )
+#define G_CC_MODE(mode1, mode2) G_CC_LERP(mode1, mode2)
+
+/* scissor modes */
+#define G_SC_NON_INTERLACE gI_(0b00)
+#define G_SC_EVEN_INTERLACE gI_(0b10)
+#define G_SC_ODD_INTERLACE gI_(0b11)
+
+/* display list branch flags */
+#define G_DL_PUSH gI_(0b0)
+#define G_DL_NOPUSH gI_(0b1)
+
+/* conditional branching flags (f3dex and f3dex2) */
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+# define G_BZ_PERSP 0
+# define G_BZ_ORTHO 1
+#endif
+
+/* matrix params */
+#define G_MTX_MUL (gI_(0b0) << 1)
+#define G_MTX_LOAD (gI_(0b1) << 1)
+
+/* matrix params for fast3d and f3dex */
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+# define G_MTX_MODELVIEW (gI_(0b0) << 0)
+# define G_MTX_PROJECTION (gI_(0b1) << 0)
+# define G_MTX_NOPUSH (gI_(0b0) << 2)
+# define G_MTX_PUSH (gI_(0b1) << 2)
+#endif
+
+/* matrix params for f3dex2 */
+#if defined(F3DEX_GBI_2)
+# define G_MTX_NOPUSH (gI_(0b0) << 0)
+# define G_MTX_PUSH (gI_(0b1) << 0)
+# define G_MTX_MODELVIEW (gI_(0b0) << 2)
+# define G_MTX_PROJECTION (gI_(0b1) << 2)
+#endif
+
+/* moveword indices */
+#define G_MW_MATRIX 0
+#define G_MW_NUMLIGHT 2
+#define G_MW_CLIP 4
+#define G_MW_SEGMENT 6
+#define G_MW_FOG 8
+#define G_MW_GENSTAT 8
+#define G_MW_LIGHTCOL 10
+#define G_MW_PERSPNORM 14
+
+/* moveword indices for fast3d and f3dex */
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+# define G_MW_POINTS 12
+#endif
+
+/* moveword indices for f3dex2 */
+#if defined(F3DEX_GBI_2)
+# define G_MW_FORCEMTX 12
+#endif
+
+/* moveword offsets */
+#define G_MWO_NUMLIGHT gI_(0x00)
+#define G_MWO_CLIP_RNX gI_(0x04)
+#define G_MWO_CLIP_RNY gI_(0x0C)
+#define G_MWO_CLIP_RPX gI_(0x14)
+#define G_MWO_CLIP_RPY gI_(0x1C)
+#define G_MWO_SEGMENT_0 gI_(0x00)
+#define G_MWO_SEGMENT_1 gI_(0x04)
+#define G_MWO_SEGMENT_2 gI_(0x08)
+#define G_MWO_SEGMENT_3 gI_(0x0C)
+#define G_MWO_SEGMENT_4 gI_(0x10)
+#define G_MWO_SEGMENT_5 gI_(0x14)
+#define G_MWO_SEGMENT_6 gI_(0x18)
+#define G_MWO_SEGMENT_7 gI_(0x1C)
+#define G_MWO_SEGMENT_8 gI_(0x20)
+#define G_MWO_SEGMENT_9 gI_(0x24)
+#define G_MWO_SEGMENT_A gI_(0x28)
+#define G_MWO_SEGMENT_B gI_(0x2C)
+#define G_MWO_SEGMENT_C gI_(0x30)
+#define G_MWO_SEGMENT_D gI_(0x34)
+#define G_MWO_SEGMENT_E gI_(0x38)
+#define G_MWO_SEGMENT_F gI_(0x3C)
+#define G_MWO_FOG gI_(0x00)
+#define G_MWO_aLIGHT_1 gI_(0x00)
+#define G_MWO_bLIGHT_1 gI_(0x04)
+#define G_MWO_MATRIX_XX_XY_I gI_(0x00)
+#define G_MWO_MATRIX_XZ_XW_I gI_(0x04)
+#define G_MWO_MATRIX_YX_YY_I gI_(0x08)
+#define G_MWO_MATRIX_YZ_YW_I gI_(0x0C)
+#define G_MWO_MATRIX_ZX_ZY_I gI_(0x10)
+#define G_MWO_MATRIX_ZZ_ZW_I gI_(0x14)
+#define G_MWO_MATRIX_WX_WY_I gI_(0x18)
+#define G_MWO_MATRIX_WZ_WW_I gI_(0x1C)
+#define G_MWO_MATRIX_XX_XY_F gI_(0x20)
+#define G_MWO_MATRIX_XZ_XW_F gI_(0x24)
+#define G_MWO_MATRIX_YX_YY_F gI_(0x28)
+#define G_MWO_MATRIX_YZ_YW_F gI_(0x2C)
+#define G_MWO_MATRIX_ZX_ZY_F gI_(0x30)
+#define G_MWO_MATRIX_ZZ_ZW_F gI_(0x34)
+#define G_MWO_MATRIX_WX_WY_F gI_(0x38)
+#define G_MWO_MATRIX_WZ_WW_F gI_(0x3C)
+#define G_MWO_POINT_RGBA gI_(0x10)
+#define G_MWO_POINT_ST gI_(0x14)
+#define G_MWO_POINT_XYSCREEN gI_(0x18)
+#define G_MWO_POINT_ZSCREEN gI_(0x1C)
+
+/* moveword offsets for fast3d and f3dex */
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+# define G_MWO_aLIGHT_2 gI_(0x20)
+# define G_MWO_bLIGHT_2 gI_(0x24)
+# define G_MWO_aLIGHT_3 gI_(0x40)
+# define G_MWO_bLIGHT_3 gI_(0x44)
+# define G_MWO_aLIGHT_4 gI_(0x60)
+# define G_MWO_bLIGHT_4 gI_(0x64)
+# define G_MWO_aLIGHT_5 gI_(0x80)
+# define G_MWO_bLIGHT_5 gI_(0x84)
+# define G_MWO_aLIGHT_6 gI_(0xA0)
+# define G_MWO_bLIGHT_6 gI_(0xA4)
+# define G_MWO_aLIGHT_7 gI_(0xC0)
+# define G_MWO_bLIGHT_7 gI_(0xC4)
+# define G_MWO_aLIGHT_8 gI_(0xE0)
+# define G_MWO_bLIGHT_8 gI_(0xE4)
+#endif
+
+/* moveword offsets for f3dex2 */
+#if defined(F3DEX_GBI_2)
+# define G_MWO_aLIGHT_2 gI_(0x18)
+# define G_MWO_bLIGHT_2 gI_(0x1C)
+# define G_MWO_aLIGHT_3 gI_(0x30)
+# define G_MWO_bLIGHT_3 gI_(0x34)
+# define G_MWO_aLIGHT_4 gI_(0x48)
+# define G_MWO_bLIGHT_4 gI_(0x4C)
+# define G_MWO_aLIGHT_5 gI_(0x60)
+# define G_MWO_bLIGHT_5 gI_(0x64)
+# define G_MWO_aLIGHT_6 gI_(0x78)
+# define G_MWO_bLIGHT_6 gI_(0x7C)
+# define G_MWO_aLIGHT_7 gI_(0x90)
+# define G_MWO_bLIGHT_7 gI_(0x94)
+# define G_MWO_aLIGHT_8 gI_(0xA8)
+# define G_MWO_bLIGHT_8 gI_(0xAC)
+#endif
+
+/* movemem params for fast3d and f3dex */
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+# define G_MV_VIEWPORT 128
+# define G_MV_LOOKATY 130
+# define G_MV_LOOKATX 132
+# define G_MV_L0 134
+# define G_MV_L1 136
+# define G_MV_L2 138
+# define G_MV_L3 140
+# define G_MV_L4 142
+# define G_MV_L5 144
+# define G_MV_L6 146
+# define G_MV_L7 148
+# define G_MV_TXTATT 150
+# define G_MV_MATRIX_2 152
+# define G_MV_MATRIX_3 154
+# define G_MV_MATRIX_4 156
+# define G_MV_MATRIX_1 158
+#endif
+
+/* movemem params for f3dex2 */
+#if defined(F3DEX_GBI_2)
+# define G_MV_MMTX 2
+# define G_MV_PMTX 6
+# define G_MV_VIEWPORT 8
+# define G_MV_LIGHT 10
+# define G_MV_POINT 12
+# define G_MV_MATRIX 14
+# define G_MVO_LOOKATX gI_(0 * 0x18)
+# define G_MVO_LOOKATY gI_(1 * 0x18)
+# define G_MVO_L0 gI_(2 * 0x18)
+# define G_MVO_L1 gI_(3 * 0x18)
+# define G_MVO_L2 gI_(4 * 0x18)
+# define G_MVO_L3 gI_(5 * 0x18)
+# define G_MVO_L4 gI_(6 * 0x18)
+# define G_MVO_L5 gI_(7 * 0x18)
+# define G_MVO_L6 gI_(8 * 0x18)
+# define G_MVO_L7 gI_(9 * 0x18)
+#endif
+
+/* frustum ratios */
+#define FRUSTRATIO_1 gI_(1)
+#define FRUSTRATIO_2 gI_(2)
+#define FRUSTRATIO_3 gI_(3)
+#define FRUSTRATIO_4 gI_(4)
+#define FRUSTRATIO_5 gI_(5)
+#define FRUSTRATIO_6 gI_(6)
+
+/* light params */
+#define NUMLIGHTS_0 1
+#define NUMLIGHTS_1 1
+#define NUMLIGHTS_2 2
+#define NUMLIGHTS_3 3
+#define NUMLIGHTS_4 4
+#define NUMLIGHTS_5 5
+#define NUMLIGHTS_6 6
+#define NUMLIGHTS_7 7
+#define LIGHT_1 1
+#define LIGHT_2 2
+#define LIGHT_3 3
+#define LIGHT_4 4
+#define LIGHT_5 5
+#define LIGHT_6 6
+#define LIGHT_7 7
+#define LIGHT_8 8
+
+/* light params for fast3d and f3dex */
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+# define NUML(n) (((n) + 1) * 32 + 0x80000000)
+#endif
+
+/* light params for f3dex2 */
+#if defined(F3DEX_GBI_2)
+# define NUML(n) ((n) * 0x18)
+#endif
+
+/* background load types */
+#define G_BGLT_LOADBLOCK gI_(0x0033)
+#define G_BGLT_LOADTILE gI_(0xFFF4)
+
+/* background flags */
+#define G_BG_FLAG_FLIPS (gI_(0b1) << 0)
+#define G_BG_FLAG_FLIPT (gI_(0b1) << 1)
+
+/* object load types */
+#define G_OBJLT_TXTRBLOCK gI_(0x00001033)
+#define G_OBJLT_TXTRTILE gI_(0x00FC1034)
+#define G_OBJLT_TLUT gI_(0x00000030)
+
+/* object flags */
+#define G_OBJ_FLAG_FLIPS (gI_(0b1) << 0)
+#define G_OBJ_FLAG_FLIPT (gI_(0b1) << 4)
+
+/* color macros */
+#define G_MAXZ 0x03FF
+#define G_MAXFBZ 0x3FFF
+#define GPACK_RGBA5551(r, g, b, a) \
+ ( \
+ gF_(r, 5, 11) | \
+ gF_(g, 5, 6) | \
+ gF_(b, 5, 1) | \
+ gF_(a, 1, 0) \
+ )
+#define GPACK_RGBA8888(r, g, b, a) \
+ ( \
+ gF_(r, 8, 24) | \
+ gF_(g, 8, 16) | \
+ gF_(b, 8, 8) | \
+ gF_(a, 8, 0) \
+ )
+#define GPACK_RGB24A8(rgb, a) (gF_(rgb, 24, 8) | gF_(a, 8, 0))
+#define GPACK_ZDZ(z, dz) (gF_(z, 14, 2) | gF_(dz, 2, 0))
+
+/* structure definition macros */
+#define gdSPDefMtx(xx, xy, xz, xw, \
+ yx, yy, yz, yw, \
+ zx, zy, zz, zw, \
+ wx, wy, wz, ww) \
+ ( \
+ (Mtx) \
+ { \
+ .i = \
+ { \
+ (qs1616(xx) >> 16) & 0xFFFF, \
+ (qs1616(xy) >> 16) & 0xFFFF, \
+ (qs1616(xz) >> 16) & 0xFFFF, \
+ (qs1616(xw) >> 16) & 0xFFFF, \
+ (qs1616(yx) >> 16) & 0xFFFF, \
+ (qs1616(yy) >> 16) & 0xFFFF, \
+ (qs1616(yz) >> 16) & 0xFFFF, \
+ (qs1616(yw) >> 16) & 0xFFFF, \
+ (qs1616(zx) >> 16) & 0xFFFF, \
+ (qs1616(zy) >> 16) & 0xFFFF, \
+ (qs1616(zz) >> 16) & 0xFFFF, \
+ (qs1616(zw) >> 16) & 0xFFFF, \
+ (qs1616(wx) >> 16) & 0xFFFF, \
+ (qs1616(wy) >> 16) & 0xFFFF, \
+ (qs1616(wz) >> 16) & 0xFFFF, \
+ (qs1616(ww) >> 16) & 0xFFFF, \
+ }, \
+ .f = \
+ { \
+ qs1616(xx) & 0xFFFF, \
+ qs1616(xy) & 0xFFFF, \
+ qs1616(xz) & 0xFFFF, \
+ qs1616(xw) & 0xFFFF, \
+ qs1616(yx) & 0xFFFF, \
+ qs1616(yy) & 0xFFFF, \
+ qs1616(yz) & 0xFFFF, \
+ qs1616(yw) & 0xFFFF, \
+ qs1616(zx) & 0xFFFF, \
+ qs1616(zy) & 0xFFFF, \
+ qs1616(zz) & 0xFFFF, \
+ qs1616(zw) & 0xFFFF, \
+ qs1616(wx) & 0xFFFF, \
+ qs1616(wy) & 0xFFFF, \
+ qs1616(wz) & 0xFFFF, \
+ qs1616(ww) & 0xFFFF, \
+ } \
+ } \
+ )
+#define gdSPDefLookAt(rx, ry, rz, ux, uy, uz) \
+ ( \
+ (LookAt) \
+ { \
+ .l[0].l = \
+ { \
+ .col = {0, 0, 0}, \
+ .colc = {0, 0, 0}, \
+ .dir = {rx, ry, rz}, \
+ }, \
+ .l[1].l = \
+ { \
+ .col = {0, 0x80, 0}, \
+ .colc = {0, 0x80, 0}, \
+ .dir = {ux, uy, uz}, \
+ }, \
+ } \
+ )
+#define gdSPDefLights0(ar, ag, ab) \
+ ( \
+ (Lights0) \
+ { \
+ .a.l = \
+ { \
+ .col = {ar, ag, ab}, \
+ .colc = {ar, ag, ab}, \
+ }, \
+ .l[0].l = \
+ { \
+ } \
+ } \
+ )
+#define gdSPDefLights1(ar, ag, ab, \
+ r1, g1, b1, x1, y1, z1) \
+ ( \
+ (Lights1) \
+ { \
+ .a.l = \
+ { \
+ .col = {ar, ag, ab}, \
+ .colc = {ar, ag, ab}, \
+ }, \
+ .l[0].l = \
+ { \
+ .col = {r1, g1, b1}, \
+ .colc = {r1, g1, b1}, \
+ .dir = {x1, y1, z1}, \
+ } \
+ } \
+ )
+#define gdSPDefLights2(ar, ag, ab, \
+ r1, g1, b1, x1, y1, z1, \
+ r2, g2, b2, x2, y2, z2) \
+ ( \
+ (Lights2) \
+ { \
+ .a.l = \
+ { \
+ .col = {ar, ag, ab}, \
+ .colc = {ar, ag, ab}, \
+ }, \
+ .l[0].l = \
+ { \
+ .col = {r1, g1, b1}, \
+ .colc = {r1, g1, b1}, \
+ .dir = {x1, y1, z1}, \
+ } \
+ .l[1].l = \
+ { \
+ .col = {r2, g2, b2}, \
+ .colc = {r2, g2, b2}, \
+ .dir = {x2, y2, z2}, \
+ } \
+ } \
+ )
+#define gdSPDefLights3(ar, ag, ab, \
+ r1, g1, b1, x1, y1, z1, \
+ r2, g2, b2, x2, y2, z2, \
+ r3, g3, b3, x3, y3, z3) \
+ ( \
+ (Lights3) \
+ { \
+ .a.l = \
+ { \
+ .col = {ar, ag, ab}, \
+ .colc = {ar, ag, ab}, \
+ }, \
+ .l[0].l = \
+ { \
+ .col = {r1, g1, b1}, \
+ .colc = {r1, g1, b1}, \
+ .dir = {x1, y1, z1}, \
+ } \
+ .l[1].l = \
+ { \
+ .col = {r2, g2, b2}, \
+ .colc = {r2, g2, b2}, \
+ .dir = {x2, y2, z2}, \
+ } \
+ .l[2].l = \
+ { \
+ .col = {r3, g3, b3}, \
+ .colc = {r3, g3, b3}, \
+ .dir = {x3, y3, z3}, \
+ } \
+ } \
+ )
+#define gdSPDefLights4(ar, ag, ab, \
+ r1, g1, b1, x1, y1, z1, \
+ r2, g2, b2, x2, y2, z2, \
+ r3, g3, b3, x3, y3, z3, \
+ r4, g4, b4, x4, y4, z4) \
+ ( \
+ (Lights4) \
+ { \
+ .a.l = \
+ { \
+ .col = {ar, ag, ab}, \
+ .colc = {ar, ag, ab}, \
+ }, \
+ .l[0].l = \
+ { \
+ .col = {r1, g1, b1}, \
+ .colc = {r1, g1, b1}, \
+ .dir = {x1, y1, z1}, \
+ } \
+ .l[1].l = \
+ { \
+ .col = {r2, g2, b2}, \
+ .colc = {r2, g2, b2}, \
+ .dir = {x2, y2, z2}, \
+ } \
+ .l[2].l = \
+ { \
+ .col = {r3, g3, b3}, \
+ .colc = {r3, g3, b3}, \
+ .dir = {x3, y3, z3}, \
+ } \
+ .l[3].l = \
+ { \
+ .col = {r4, g4, b4}, \
+ .colc = {r4, g4, b4}, \
+ .dir = {x4, y4, z4}, \
+ } \
+ } \
+ )
+#define gdSPDefLights5(ar, ag, ab, \
+ r1, g1, b1, x1, y1, z1, \
+ r2, g2, b2, x2, y2, z2, \
+ r3, g3, b3, x3, y3, z3, \
+ r4, g4, b4, x4, y4, z4, \
+ r5, g5, b5, x5, y5, z5) \
+ ( \
+ (Lights5) \
+ { \
+ .a.l = \
+ { \
+ .col = {ar, ag, ab}, \
+ .colc = {ar, ag, ab}, \
+ }, \
+ .l[0].l = \
+ { \
+ .col = {r1, g1, b1}, \
+ .colc = {r1, g1, b1}, \
+ .dir = {x1, y1, z1}, \
+ } \
+ .l[1].l = \
+ { \
+ .col = {r2, g2, b2}, \
+ .colc = {r2, g2, b2}, \
+ .dir = {x2, y2, z2}, \
+ } \
+ .l[2].l = \
+ { \
+ .col = {r3, g3, b3}, \
+ .colc = {r3, g3, b3}, \
+ .dir = {x3, y3, z3}, \
+ } \
+ .l[3].l = \
+ { \
+ .col = {r4, g4, b4}, \
+ .colc = {r4, g4, b4}, \
+ .dir = {x4, y4, z4}, \
+ } \
+ .l[4].l = \
+ { \
+ .col = {r5, g5, b5}, \
+ .colc = {r5, g5, b5}, \
+ .dir = {x5, y5, z5}, \
+ } \
+ } \
+ )
+#define gdSPDefLights6(ar, ag, ab, \
+ r1, g1, b1, x1, y1, z1, \
+ r2, g2, b2, x2, y2, z2, \
+ r3, g3, b3, x3, y3, z3, \
+ r4, g4, b4, x4, y4, z4, \
+ r5, g5, b5, x5, y5, z5, \
+ r6, g6, b6, x6, y6, z6)\
+ ( \
+ (Lights6) \
+ { \
+ .a.l = \
+ { \
+ .col = {ar, ag, ab}, \
+ .colc = {ar, ag, ab}, \
+ }, \
+ .l[0].l = \
+ { \
+ .col = {r1, g1, b1}, \
+ .colc = {r1, g1, b1}, \
+ .dir = {x1, y1, z1}, \
+ } \
+ .l[1].l = \
+ { \
+ .col = {r2, g2, b2}, \
+ .colc = {r2, g2, b2}, \
+ .dir = {x2, y2, z2}, \
+ } \
+ .l[2].l = \
+ { \
+ .col = {r3, g3, b3}, \
+ .colc = {r3, g3, b3}, \
+ .dir = {x3, y3, z3}, \
+ } \
+ .l[3].l = \
+ { \
+ .col = {r4, g4, b4}, \
+ .colc = {r4, g4, b4}, \
+ .dir = {x4, y4, z4}, \
+ } \
+ .l[4].l = \
+ { \
+ .col = {r5, g5, b5}, \
+ .colc = {r5, g5, b5}, \
+ .dir = {x5, y5, z5}, \
+ } \
+ .l[5].l = \
+ { \
+ .col = {r6, g6, b6}, \
+ .colc = {r6, g6, b6}, \
+ .dir = {x6, y6, z6}, \
+ } \
+ } \
+ )
+#define gdSPDefLights7(ar, ag, ab, \
+ r1, g1, b1, x1, y1, z1, \
+ r2, g2, b2, x2, y2, z2, \
+ r3, g3, b3, x3, y3, z3, \
+ r4, g4, b4, x4, y4, z4, \
+ r5, g5, b5, x5, y5, z5, \
+ r6, g6, b6, x6, y6, z6, \
+ r7, g7, b7, x7, y7, z7) \
+ ( \
+ (Lights7) \
+ { \
+ .a.l = \
+ { \
+ .col = {ar, ag, ab}, \
+ .colc = {ar, ag, ab}, \
+ }, \
+ .l[0].l = \
+ { \
+ .col = {r1, g1, b1}, \
+ .colc = {r1, g1, b1}, \
+ .dir = {x1, y1, z1}, \
+ } \
+ .l[1].l = \
+ { \
+ .col = {r2, g2, b2}, \
+ .colc = {r2, g2, b2}, \
+ .dir = {x2, y2, z2}, \
+ } \
+ .l[2].l = \
+ { \
+ .col = {r3, g3, b3}, \
+ .colc = {r3, g3, b3}, \
+ .dir = {x3, y3, z3}, \
+ } \
+ .l[3].l = \
+ { \
+ .col = {r4, g4, b4}, \
+ .colc = {r4, g4, b4}, \
+ .dir = {x4, y4, z4}, \
+ } \
+ .l[4].l = \
+ { \
+ .col = {r5, g5, b5}, \
+ .colc = {r5, g5, b5}, \
+ .dir = {x5, y5, z5}, \
+ } \
+ .l[5].l = \
+ { \
+ .col = {r6, g6, b6}, \
+ .colc = {r6, g6, b6}, \
+ .dir = {x6, y6, z6}, \
+ } \
+ .l[6].l = \
+ { \
+ .col = {r7, g7, b7}, \
+ .colc = {r7, g7, b7}, \
+ .dir = {x7, y7, z7}, \
+ } \
+ } \
+ )
+#define gdSPDefVtx(x, y, z, s, t) \
+ ( \
+ (Vtx) \
+ { \
+ .v = \
+ { \
+ .ob = {x, y, z}, \
+ .tc = {qs105(s), qs105(t)}, \
+ } \
+ } \
+ )
+#define gdSPDefVtxC(x, y, z, s, t, cr, cg, cb, ca) \
+ ( \
+ (Vtx) \
+ { \
+ .v = \
+ { \
+ .ob = {x, y, z}, \
+ .tc = {qs105(s), qs105(t)}, \
+ .cn = {cr, cg, cb, ca}, \
+ } \
+ } \
+ )
+#define gdSPDefVtxN(x, y, z, s, t, nx, ny, nz, ca) \
+ ( \
+ (Vtx) \
+ { \
+ .n = \
+ { \
+ .ob = {x, y, z}, \
+ .tc = {qs105(s), qs105(t)}, \
+ .n = {nx, ny, nz}, \
+ .a = ca \
+ } \
+ } \
+ )
+
+/* instruction macros */
+
+#define gsDPFillRectangle(ulx, uly, lrx, lry) \
+ gO_( \
+ G_FILLRECT, \
+ gF_(lrx, 10, 14) | \
+ gF_(lry, 10, 2), \
+ gF_(ulx, 10, 14) | \
+ gF_(uly, 10, 2))
+
+#define gsDPScisFillRectangle(ulx, uly, lrx, lry) \
+ gsDPFillRectangle(gScC_(ulx), gScC_(uly), gScC_(lrx), gScC_(lry))
+
+#define gsDPFullSync() \
+ gO_(G_RDPFULLSYNC, 0, 0)
+
+#define gsDPLoadSync() \
+ gO_(G_RDPLOADSYNC, 0, 0)
+
+#define gsDPTileSync() \
+ gO_(G_RDPTILESYNC, 0, 0)
+
+#define gsDPPipeSync() \
+ gO_(G_RDPPIPESYNC, 0, 0)
+
+#define gsDPLoadTLUT_pal16(pal, dram) \
+ gsDPLoadTLUT(16, 256 + (gI_(pal) & 0xF) * 16, dram)
+
+#define gsDPLoadTLUT_pal256(dram) \
+ gsDPLoadTLUT(256, 256, dram)
+
+#define gLTB_(timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ dxt, tmem, rt, line) \
+ gsDPSetTextureImage(fmt, G_SIZ_LDSIZ(siz), 1, timg), \
+ gsDPSetTile( \
+ fmt, G_SIZ_LDSIZ(siz), 0, tmem, G_TX_LOADTILE, 0, \
+ cmt, maskt, shiftt, \
+ cms, masks, shifts), \
+ gsDPLoadSync(), \
+ gsDPLoadBlock( \
+ G_TX_LOADTILE, 0, 0, \
+ (((width) * (height) + 1) * G_SIZ_BITS(siz) - 1) / \
+ G_SIZ_BITS(G_SIZ_LDSIZ(siz)) - 1, \
+ dxt), \
+ gsDPPipeSync(), \
+ gsDPSetTile( \
+ fmt, siz, line, tmem, rt, pal, \
+ cmt, maskt, shiftt, \
+ cms, masks, shifts), \
+ gsDPSetTileSize(rt, 0, 0, qu102((width) - 1), qu102((height) - 1))
+
+#define gsDPLoadTextureBlock(timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(siz, width), 0x0, G_TX_RENDERTILE, \
+ ((width) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define gsDPLoadTextureBlockS(timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, 0x0, G_TX_RENDERTILE, \
+ ((width) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define gsDPLoadTextureBlock_4b(timg, fmt, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, G_IM_SIZ_4b, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(G_IM_SIZ_4b, width), 0x0, G_TX_RENDERTILE, \
+ ((width) * 4 + 63) / 64)
+
+#define gsDPLoadTextureBlock_4bS(timg, fmt, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, G_IM_SIZ_4b, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, 0x0, G_TX_RENDERTILE, \
+ ((width) * 4 + 63) / 64)
+
+#define gsDPLoadTextureBlockYuv(timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(siz, width), 0x0, G_TX_RENDERTILE, \
+ ((width) + 7) / 8)
+
+#define gsDPLoadTextureBlockYuvS(timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, 0x0, G_TX_RENDERTILE, \
+ ((width) + 7) / 8)
+
+#define _gsDPLoadTextureBlock(timg, tmem, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(siz, width), tmem, G_TX_RENDERTILE, \
+ ((width) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define _gsDPLoadTextureBlockS(timg, tmem, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, tmem, G_TX_RENDERTILE, \
+ ((width) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define _gsDPLoadTextureBlock_4b(timg, tmem, fmt, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, G_IM_SIZ_4b, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(G_IM_SIZ_4b, width), tmem, G_TX_RENDERTILE, \
+ ((width) * 4 + 63) / 64)
+
+#define _gsDPLoadTextureBlock_4bS(timg, tmem, fmt, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, G_IM_SIZ_4b, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, tmem, G_TX_RENDERTILE, \
+ ((width) * 4 + 63) / 64)
+
+#define _gsDPLoadTextureBlockYuv(timg, tmem, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(siz, width), tmem, G_TX_RENDERTILE, \
+ ((width) + 7) / 8)
+
+#define _gsDPLoadTextureBlockYuvS(timg, tmem, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, tmem, G_TX_RENDERTILE, \
+ ((width) + 7) / 8)
+
+#define gsDPLoadMultiBlock(timg, tmem, rt, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(siz, width), tmem, rt, \
+ ((width) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define gsDPLoadMultiBlockS(timg, tmem, rt, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, tmem, rt, \
+ ((width) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define gsDPLoadMultiBlock_4b(timg, tmem, rt, fmt, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, G_IM_SIZ_4b, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(G_IM_SIZ_4b, width), tmem, rt, \
+ ((width) * 4 + 63) / 64)
+
+#define gsDPLoadMultiBlock_4bS(timg, tmem, rt, fmt, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, G_IM_SIZ_4b, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, tmem, rt, \
+ ((width) * 4 + 63) / 64)
+
+#define gsDPLoadMultiBlockYuv(timg, tmem, rt, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ G_DXT(siz, width), tmem, rt, \
+ ((width) + 7) / 8)
+
+#define gsDPLoadMultiBlockYuvS(timg, tmem, rt, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTB_( \
+ timg, fmt, siz, width, height, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0, tmem, rt, \
+ ((width) + 7) / 8)
+
+#define gLTT_(timg, fmt, siz, width, height, uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ tmem, rt, line) \
+ gsDPSetTextureImage(fmt, siz, width, timg), \
+ gsDPSetTile( \
+ fmt, siz, line, tmem, \
+ G_TX_LOADTILE, 0, \
+ cmt, maskt, shiftt, \
+ cms, masks, shifts), \
+ gsDPLoadSync(), \
+ gsDPLoadTile( \
+ G_TX_LOADTILE, \
+ qu102(uls), qu102(ult), \
+ qu102(lrs), qu102(lrt)), \
+ gsDPPipeSync(), \
+ gsDPSetTile( \
+ fmt, siz, line, \
+ tmem, rt, pal, \
+ cmt, maskt, shiftt, \
+ cms, masks, shifts), \
+ gsDPSetTileSize( \
+ rt, \
+ qu102(uls), qu102(ult), \
+ qu102(lrs), qu102(lrt))
+
+#define gLTT4_(timg, fmt, width, height, uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ tmem, rt) \
+ gsDPSetTextureImage(fmt, G_IM_SIZ_8b, (width) / 2, timg), \
+ gsDPSetTile( \
+ fmt, G_IM_SIZ_8b, \
+ (((lrs) - (uls) + 1) / 2 + 7) / 8, \
+ tmem, G_TX_LOADTILE, 0, \
+ cmt, maskt, shiftt, \
+ cms, masks, shifts), \
+ gsDPLoadSync(), \
+ gsDPLoadTile( \
+ G_TX_LOADTILE, \
+ qu102(uls) / 2, qu102(ult), \
+ qu102(lrs) / 2, qu102(lrt)), \
+ gsDPPipeSync(), \
+ gsDPSetTile( \
+ fmt, G_IM_SIZ_4b, \
+ (((lrs) - (uls) + 1) / 2 + 7) / 8, \
+ tmem, rt, pal, \
+ cmt, maskt, shiftt, \
+ cms, masks, shifts), \
+ gsDPSetTileSize( \
+ rt, \
+ qu102(uls), qu102(ult), \
+ qu102(lrs), qu102(lrt))
+
+#define gsDPLoadTextureTile(timg, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTT_( \
+ timg, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0x0, G_TX_RENDERTILE, \
+ (((lrs) - (uls) + 1) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define gsDPLoadTextureTile_4b(timg, fmt, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTT4_( \
+ timg, fmt, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0x0, G_TX_RENDERTILE)
+
+#define gsDPLoadTextureTileYuv(timg, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTT_( \
+ timg, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ 0x0, G_TX_RENDERTILE, \
+ (((lrs) - (uls) + 1) + 7) / 8)
+
+#define _gsDPLoadTextureTile(timg, tmem, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTT_( \
+ timg, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ tmem, G_TX_RENDERTILE, \
+ (((lrs) - (uls) + 1) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define _gsDPLoadTextureTile_4b(timg, tmem, fmt, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTT4_( \
+ timg, fmt, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ tmem, G_TX_RENDERTILE)
+
+#define _gsDPLoadTextureTileYuv(timg, tmem, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, cms, cmt, \
+ masks, maskt, shifts, shiftt) \
+ gLTT_( \
+ timg, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ tmem, G_TX_RENDERTILE, \
+ (((lrs) - (uls) + 1) + 7) / 8)
+
+#define gsDPLoadMultiTile(timg, tmem, rt, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTT_( \
+ timg, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ tmem, rt, \
+ (((lrs) - (uls) + 1) * G_SIZ_LDBITS(siz) + 63) / 64)
+
+#define gsDPLoadMultiTile_4b(timg, tmem, rt, fmt, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTT4_( \
+ timg, fmt, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ tmem, rt)
+
+#define gsDPLoadMultiTileYuv(timg, tmem, rt, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt) \
+ gLTT_( \
+ timg, fmt, siz, width, height, \
+ uls, ult, lrs, lrt, pal, \
+ cms, cmt, masks, maskt, shifts, shiftt, \
+ tmem, rt, \
+ (((lrs) - (uls) + 1) + 7) / 8)
+
+#define gsDPLoadBlock(tile, uls, ult, lrs, dxt) \
+ gO_( \
+ G_LOADBLOCK, \
+ gF_(uls, 12, 12) | \
+ gF_(ult, 12, 0), \
+ gF_(tile, 3, 24) | \
+ gF_(lrs, 12, 12) | \
+ gF_(dxt, 12, 0))
+
+#define gsDPNoOp() \
+ gsDPNoOpTag(0)
+
+#define gsDPNoOpTag(tag) \
+ gO_(G_NOOP, 0, tag)
+
+#define gsDPPipelineMode(mode) \
+ gsSPSetOtherModeHi(G_MDSFT_PIPELINE, G_MDSIZ_PIPELINE, mode)
+
+#define gsDPSetBlendColor(r, g, b, a) \
+ gO_( \
+ G_SETBLENDCOLOR, \
+ 0, \
+ gF_(r, 8, 24) | \
+ gF_(g, 8, 16) | \
+ gF_(b, 8, 8) | \
+ gF_(a, 8, 0))
+
+#define gsDPSetEnvColor(r, g, b, a) \
+ gO_( \
+ G_SETENVCOLOR, \
+ 0, \
+ gF_(r, 8, 24) | \
+ gF_(g, 8, 16) | \
+ gF_(b, 8, 8) | \
+ gF_(a, 8, 0))
+
+#define gsDPSetFillColor(c) \
+ gO_(G_SETFILLCOLOR, 0, c)
+
+#define gsDPSetFogColor(r, g, b, a) \
+ gO_( \
+ G_SETFOGCOLOR, 0, \
+ gF_(r, 8, 24) | \
+ gF_(g, 8, 16) | \
+ gF_(b, 8, 8) | \
+ gF_(a, 8, 0))
+
+#define gsDPSetPrimColor(m, l, r, g, b, a) \
+ gO_( \
+ G_SETPRIMCOLOR, \
+ gF_(m, 8, 8) | \
+ gF_(l, 8, 0), \
+ gF_(r, 8, 24) | \
+ gF_(g, 8, 16) | \
+ gF_(b, 8, 8) | \
+ gF_(a, 8, 0))
+
+#define gsDPSetColorImage(fmt, siz, width, img) \
+ gO_( \
+ G_SETCIMG, \
+ gF_(fmt, 3, 21) | \
+ gF_(siz, 2, 19) | \
+ gF_((width) - 1, 12, 0), \
+ img)
+
+#define gsDPSetDepthImage(img) \
+ gO_(G_SETZIMG, 0, img)
+
+#define gsDPSetTextureImage(fmt, siz, width, img) \
+ gO_( \
+ G_SETTIMG, \
+ gF_(fmt, 3, 21) | \
+ gF_(siz, 2, 19) | \
+ gF_((width) - 1, 12, 0), \
+ img)
+
+#define gsDPSetHilite1Tile(tile, hilite, width, height) \
+ gsDPSetTileSize( \
+ tile, \
+ ((Hilite *)(hilite))->h.x1 & 0xFFF, \
+ ((Hilite *)(hilite))->h.y1 & 0xFFF, \
+ (((width) - 1) * 4 + ((Hilite *)(hilite))->h.x1) & 0xFFF, \
+ (((height) - 1) * 4 + ((Hilite *)(hilite))->h.y1) & 0xFFF)
+
+#define gsDPSetHilite2Tile(tile, hilite, width, height) \
+ gsDPSetTileSize( \
+ tile, \
+ ((Hilite *)(hilite))->h.x2 & 0xFFF, \
+ ((Hilite *)(hilite))->h.y2 & 0xFFF, \
+ (((width) - 1) * 4 + ((Hilite *)(hilite))->h.x2) & 0xFFF, \
+ (((height) - 1) * 4 + ((Hilite *)(hilite))->h.y2) & 0xFFF)
+
+#define gsDPSetAlphaCompare(mode) \
+ gsSPSetOtherModeLo(G_MDSFT_ALPHACOMPARE, G_MDSIZ_ALPHACOMPARE, mode)
+
+#define gsDPSetAlphaDither(type) \
+ gsSPSetOtherModeHi(G_MDSFT_ALPHADITHER, G_MDSIZ_ALPHADITHER, type)
+
+#define gsDPSetColorDither(type) \
+ gsSPSetOtherModeHi(G_MDSFT_RGBDITHER, G_MDSIZ_RGBDITHER, type)
+
+#define gsDPSetCombineMode(mode1, mode2) \
+ gsDPSetCombineLERP(mode1, mode2)
+
+#define gsDPSetCombineLERP(a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \
+ a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \
+ gO_( \
+ G_SETCOMBINE, \
+ gF_(G_CCMUX_##a0, 4, 20) | \
+ gF_(G_CCMUX_##c0, 5, 15) | \
+ gF_(G_ACMUX_##Aa0, 3, 12) | \
+ gF_(G_ACMUX_##Ac0, 3, 9) | \
+ gF_(G_CCMUX_##a1, 4, 5) | \
+ gF_(G_CCMUX_##c1, 5, 0), \
+ gF_(G_CCMUX_##b0, 4, 28) | \
+ gF_(G_CCMUX_##b1, 4, 24) | \
+ gF_(G_ACMUX_##Aa1, 3, 21) | \
+ gF_(G_ACMUX_##Ac1, 3, 18) | \
+ gF_(G_CCMUX_##d0, 3, 15) | \
+ gF_(G_ACMUX_##Ab0, 3, 12) | \
+ gF_(G_ACMUX_##Ad0, 3, 9) | \
+ gF_(G_CCMUX_##d1, 3, 6) | \
+ gF_(G_ACMUX_##Ab1, 3, 3) | \
+ gF_(G_ACMUX_##Ad1, 3, 0))
+
+#define gsDPSetConvert(k0, k1, k2, k3, k4, k5) \
+ gO_( \
+ G_SETCONVERT, \
+ gF_(k0, 9, 13) | \
+ gF_(k1, 9, 4) | \
+ gF_(gI_(k2) >> 5, 4, 0), \
+ gF_(k2, 5, 27) | \
+ gF_(k3, 9, 18) | \
+ gF_(k4, 9, 9) | \
+ gF_(k5, 9, 0))
+
+#define gsDPSetTextureConvert(type) \
+ gsSPSetOtherModeHi(G_MDSFT_TEXTCONV, G_MDSIZ_TEXTCONV, type)
+
+#define gsDPSetCycleType(type) \
+ gsSPSetOtherModeHi(G_MDSFT_CYCLETYPE, G_MDSIZ_CYCLETYPE, type)
+
+#define gsDPSetDepthSource(source) \
+ gsSPSetOtherModeLo(G_MDSFT_ZSRCSEL, G_MDSIZ_ZSRCSEL, source)
+
+#define gsDPSetCombineKey(type) \
+ gsSPSetOtherModeHi(G_MDSFT_COMBKEY, G_MDSIZ_COMBKEY, type)
+
+#define gsDPSetKeyGB(cG, sG, wG, cB, sB, wB) \
+ gO_( \
+ G_SETKEYGB, \
+ gF_(wG, 12, 12) | \
+ gF_(wB, 12, 0), \
+ gF_(cG, 8, 24) | \
+ gF_(sG, 8, 16) | \
+ gF_(cB, 8, 8) | \
+ gF_(sB, 8, 0))
+
+#define gsDPSetKeyR(cR, sR, wR) \
+ gO_( \
+ G_SETKEYR, 0, \
+ gF_(wR, 12, 16) | \
+ gF_(cR, 8, 8) | \
+ gF_(sR, 8, 0))
+
+#define gsDPSetPrimDepth(z, dz) \
+ gO_( \
+ G_SETPRIMDEPTH, \
+ 0, \
+ gF_(z, 16, 16) | \
+ gF_(dz, 16, 0))
+
+#define gsDPSetRenderMode(mode1, mode2) \
+ gsSPSetOtherModeLo( \
+ G_MDSFT_RENDERMODE, \
+ G_MDSIZ_RENDERMODE, \
+ gI_(mode1) | \
+ gI_(mode2))
+
+#define gsDPSetScissor(mode, ulx, uly, lrx, lry) \
+ gsDPSetScissorFrac( \
+ mode, \
+ qu102(gI_(ulx)), \
+ qu102(gI_(uly)), \
+ qu102(gI_(lrx)), \
+ qu102(gI_(lry)))
+
+#define gsDPSetScissorFrac(mode, ulx, uly, lrx, lry) \
+ gO_( \
+ G_SETSCISSOR, \
+ gF_(ulx, 12, 12) | \
+ gF_(uly, 12, 0), \
+ gF_(mode, 2, 24) | \
+ gF_(lrx, 12, 12) | \
+ gF_(lry, 12, 0))
+
+#define gsDPSetTextureDetail(type) \
+ gsSPSetOtherModeHi(G_MDSFT_TEXTDETAIL, G_MDSIZ_TEXTDETAIL, type)
+
+#define gsDPSetTextureFilter(mode) \
+ gsSPSetOtherModeHi(G_MDSFT_TEXTFILT, G_MDSIZ_TEXTFILT, mode)
+
+#define gsDPSetTextureLOD(mode) \
+ gsSPSetOtherModeHi(G_MDSFT_TEXTLOD, G_MDSIZ_TEXTLOD, mode)
+
+#define gsDPSetTextureLUT(mode) \
+ gsSPSetOtherModeHi(G_MDSFT_TEXTLUT, G_MDSIZ_TEXTLUT, mode)
+
+#define gsDPSetTexturePersp(enable) \
+ gsSPSetOtherModeHi(G_MDSFT_TEXTPERSP, G_MDSIZ_TEXTPERSP, enable)
+
+#define gsDPSetTile(fmt, siz, line, tmem, tile, palette, \
+ cmt, maskt, shiftt, cms, masks, shifts) \
+ gO_( \
+ G_SETTILE, \
+ gF_(fmt, 3, 21) | \
+ gF_(siz, 2, 19) | \
+ gF_(line, 9, 9) | \
+ gF_(tmem, 9, 0), \
+ gF_(tile, 3, 24) | \
+ gF_(palette, 4, 20) | \
+ gF_(cmt, 2, 18) | \
+ gF_(maskt, 4, 14) | \
+ gF_(shiftt, 4, 10) | \
+ gF_(cms, 2, 8) | \
+ gF_(masks, 4, 4) | \
+ gF_(shifts, 4, 0))
+
+#define gsDPSetTileSize(tile, uls, ult, lrs, lrt) \
+ gO_( \
+ G_SETTILESIZE, \
+ gF_(uls, 12, 12) | \
+ gF_(ult, 12, 0), \
+ gF_(tile, 3, 24) | \
+ gF_(lrs, 12, 12) | \
+ gF_(lrt, 12, 0))
+
+#define gsSPBranchList(dl) \
+ gsDisplayList(dl, 1)
+
+#define gsSPClipRatio(r) \
+ gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RNX, (uint16_t)(r)), \
+ gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RNY, (uint16_t)(r)), \
+ gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RPX, (uint16_t)-(r)), \
+ gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RPY, (uint16_t)-(r))
+
+#define gsSPDisplayList(dl) \
+ gsDisplayList(dl, 0)
+
+#define gsSPEndDisplayList() \
+ gO_(G_ENDDL, 0, 0)
+
+#define gsSPFogFactor(fm, fo) \
+ gsMoveWd( \
+ G_MW_FOG, \
+ G_MWO_FOG, \
+ gF_(fm, 16, 16) | \
+ gF_(fo, 16, 0))
+
+#define gsSPFogPosition(min, max) \
+ gsSPFogFactor( \
+ (500 * 0x100) / ((max) - (min)), \
+ (500 - (min)) * 0x100 / ((max) - (min)))
+
+#define gsSPLine3D(v0, v1, flag) \
+ gsSPLineW3D(v0, v1, 0, flag)
+
+#define gsSPLookAt(l) \
+ gsSPLookAtX(l), \
+ gsSPLookAtY(gI_(l) + 0x10)
+
+#define gsSPSegment(seg, base) \
+ gsMoveWd(G_MW_SEGMENT, (seg) * 4, base)
+
+#define gsSPSetLights0(lites) \
+ gsSPNumLights(NUMLIGHTS_0), \
+ gsSPLight(&(lites).l[0], 1), \
+ gsSPLight(&(lites).a, 2)
+
+#define gsSPSetLights1(lites) \
+ gsSPNumLights(NUMLIGHTS_1), \
+ gsSPLight(&(lites).l[0], 1), \
+ gsSPLight(&(lites).a, 2)
+
+#define gsSPSetLights2(lites) \
+ gsSPNumLights(NUMLIGHTS_2), \
+ gsSPLight(&(lites).l[0], 1), \
+ gsSPLight(&(lites).l[1], 2), \
+ gsSPLight(&(lites).a, 3)
+
+#define gsSPSetLights3(lites) \
+ gsSPNumLights(NUMLIGHTS_3), \
+ gsSPLight(&(lites).l[0], 1), \
+ gsSPLight(&(lites).l[1], 2), \
+ gsSPLight(&(lites).l[2], 3), \
+ gsSPLight(&(lites).a, 4)
+
+#define gsSPSetLights4(lites) \
+ gsSPNumLights(NUMLIGHTS_4), \
+ gsSPLight(&(lites).l[0], 1), \
+ gsSPLight(&(lites).l[1], 2), \
+ gsSPLight(&(lites).l[2], 3), \
+ gsSPLight(&(lites).l[3], 4), \
+ gsSPLight(&(lites).a, 5)
+
+#define gsSPSetLights5(lites) \
+ gsSPNumLights(NUMLIGHTS_5), \
+ gsSPLight(&(lites).l[0], 1), \
+ gsSPLight(&(lites).l[1], 2), \
+ gsSPLight(&(lites).l[2], 3), \
+ gsSPLight(&(lites).l[3], 4), \
+ gsSPLight(&(lites).l[4], 5), \
+ gsSPLight(&(lites).a, 6)
+
+#define gsSPSetLights6(lites) \
+ gsSPNumLights(NUMLIGHTS_6), \
+ gsSPLight(&(lites).l[0], 1), \
+ gsSPLight(&(lites).l[1], 2), \
+ gsSPLight(&(lites).l[2], 3), \
+ gsSPLight(&(lites).l[3], 4), \
+ gsSPLight(&(lites).l[4], 5), \
+ gsSPLight(&(lites).l[5], 6), \
+ gsSPLight(&(lites).a, 7)
+
+#define gsSPSetLights7(lites) \
+ gsSPNumLights(NUMLIGHTS_7), \
+ gsSPLight(&(lites).l[0], 1), \
+ gsSPLight(&(lites).l[1], 2), \
+ gsSPLight(&(lites).l[2], 3), \
+ gsSPLight(&(lites).l[3], 4), \
+ gsSPLight(&(lites).l[4], 5), \
+ gsSPLight(&(lites).l[5], 6), \
+ gsSPLight(&(lites).l[6], 7), \
+ gsSPLight(&(lites).a, 8)
+
+#define gsSPSetStatus(sid, val) \
+ gsMoveWd(G_MW_GENSTAT, sid, val)
+
+#define gsSPNumLights(n) \
+ gsMoveWd(G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n))
+
+#define gsSPLightColor(Lightnum, packedcolor) \
+ gsMoveWd(G_MW_LIGHTCOL, G_MWO_a##Lightnum, packedcolor), \
+ gsMoveWd(G_MW_LIGHTCOL, G_MWO_b##Lightnum, packedcolor)
+
+#define gsSPTextureRectangle(ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy) \
+ gsTexRect(ulx, uly, lrx, lry, tile), \
+ gsDPHalf1(gF_(s, 16, 16) | gF_(t, 16, 0)), \
+ gsDPHalf2(gF_(dsdx, 16, 16) | gF_(dtdy, 16, 0))
+
+#define gsSPScisTextureRectangle(ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy) \
+ gsTexRect(gScC_(ulx), gScC_(uly), gScC_(lrx), gScC_(lry), tile), \
+ gsDPHalf1( \
+ gF_(gScD_(s, ulx, dsdx), 16, 16) | \
+ gF_(gScD_(t, uly, dtdy), 16, 0)), \
+ gsDPHalf2(gF_(dsdx, 16, 16) | gF_(dtdy, 16, 0))
+
+#define gsSPTextureRectangleFlip(ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy) \
+ gsTexRectFlip(ulx, uly, lrx, lry, tile), \
+ gsDPHalf1(gF_(s, 16, 16) | gF_(t, 16, 0)), \
+ gsDPHalf2(gF_(dsdx, 16, 16) | gF_(dtdy, 16, 0))
+
+#define gsSPScisTextureRectangleFlip( \
+ ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy) \
+ gsTexRectFlip(gScC_(ulx), gScC_(uly), gScC_(lrx), gScC_(lry), tile), \
+ gsDPHalf1( \
+ gF_(gScD_(s, ulx, dsdx), 16, 16) | \
+ gF_(gScD_(t, uly, dtdy), 16, 0)), \
+ gsDPHalf2(gF_(dsdx, 16, 16) | gF_(dtdy, 16, 0))
+
+#define gsSPBgRectCopy(bg) \
+ gO_(G_BG_COPY, 0, bg)
+
+#define gsSPBgRect1Cyc(bg) \
+ gO_(G_BG_1CYC, 0, bg)
+
+#define gsSPObjRectangle(sp) \
+ gO_(G_OBJ_RECTANGLE, 0, sp)
+
+#define gsSPObjRectangleR(sp) \
+ gO_(G_OBJ_RECTANGLE_R, 0, sp)
+
+#define gsSPObjSprite(sp) \
+ gO_(G_OBJ_SPRITE, 0, sp)
+
+#define gsSPObjMatrix(mtx) \
+ gO_( \
+ G_OBJ_MOVEMEM, \
+ gF_(sizeof(uObjMtx) - 1, 8, 16), \
+ mtx)
+
+#define gsSPObjSubMatrix(mtx) \
+ gO_( \
+ G_OBJ_MOVEMEM, \
+ gF_(sizeof(uObjSubMtx) - 1, 8, 16) | \
+ gF_(2, 16, 0), \
+ mtx)
+
+#define gsSPObjRenderMode(mode) \
+ gO_(G_OBJ_RENDERMODE, 0, mode)
+
+#define gsSPObjLoadTxtr(tx) \
+ gO_(G_OBJ_LOADTXTR, 23, tx)
+
+#define gsSPObjLoadTxRect(txsp) \
+ gO_(G_OBJ_LDTX_RECT, 47, txsp)
+
+#define gsSPObjLoadTxRectR(txsp) \
+ gO_(G_OBJ_LDTX_RECT_R, 47, txsp)
+
+#define gsSPObjLoadTxSprite(txsp) \
+ gO_(G_OBJ_LDTX_SPRITE, 47, txsp)
+
+#define gsSPSelectDL(ldl, sid, flag, mask) \
+ gO_( \
+ G_RDPHALF_0, \
+ gF_(sid, 8, 16) | \
+ gF_(ldl, 16, 0), \
+ flag), \
+ gO_( \
+ G_SELECT_DL, \
+ gF_(0x00, 8, 16) | \
+ gF_(gI_(ldl) >> 16, 16, 0), \
+ mask)
+
+#define gsSPSelectBranchDL(bdl, sid, flag, mask) \
+ gO_( \
+ G_RDPHALF_0, \
+ gF_(sid, 8, 16) | \
+ gF_(bdl, 16, 0), \
+ flag), \
+ gO_( \
+ G_SELECT_DL, \
+ gF_(0x01, 8, 16) | \
+ gF_(gI_(bdl) >> 16, 16, 0), \
+ mask)
+
+/* unlisted instructions */
+
+#define gsDPLoadTLUTCmd(tile, count) \
+ gO_( \
+ G_LOADTLUT, \
+ 0, \
+ gF_(tile, 3, 24) | \
+ gF_(count, 10, 14))
+
+#define gsDPLoadTLUT(count, tmem, dram) \
+ gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, dram), \
+ gsDPTileSync(), \
+ gsDPSetTile(0, 0, 0, tmem, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0), \
+ gsDPLoadSync(), \
+ gsDPLoadTLUTCmd(G_TX_LOADTILE, (count) - 1), \
+ gsDPPipeSync()
+
+#define gsDisplayList(dl, branch) \
+ gO_(G_DL, gF_(branch, 8, 16), dl)
+
+#define gsDPLoadTile(tile, uls, ult, lrs, lrt) \
+ gO_( \
+ G_LOADTILE, \
+ gF_(uls, 12, 12) | \
+ gF_(ult, 12, 0), \
+ gF_(tile, 3, 24) | \
+ gF_(lrs, 12, 12) | \
+ gF_(lrt, 12, 0))
+
+#define gsDPSetCombine(c) \
+ gO_( \
+ G_SETCOMBINE, \
+ (gL_(c) >> 32) & 0xFFFFFFFF, \
+ (gL_(c) >> 0) & 0xFFFFFFFF)
+
+#define gsSPSetOtherModeLo(shift, length, data) \
+ gsSPSetOtherMode(G_SETOTHERMODE_L, shift, length, data)
+
+#define gsSPSetOtherModeHi(shift, length, data) \
+ gsSPSetOtherMode(G_SETOTHERMODE_H, shift, length, data)
+
+#define gsDPSetOtherMode(mode0, mode1) \
+ gO_(G_RDPSETOTHERMODE, gF_(mode0, 24, 0), mode1)
+
+#define gsTexRect(ulx, uly, lrx, lry, tile) \
+ gO_( \
+ G_TEXRECT, \
+ gF_(lrx, 12, 12) | \
+ gF_(lry, 12, 0), \
+ gF_(tile, 3, 24) | \
+ gF_(ulx, 12, 12) | \
+ gF_(uly, 12, 0))
+
+#define gsTexRectFlip(ulx, uly, lrx, lry, tile) \
+ gO_( \
+ G_TEXRECTFLIP, \
+ gF_(lrx, 12, 12) | \
+ gF_(lry, 12, 0), \
+ gF_(tile, 3, 24) | \
+ gF_(ulx, 12, 12) | \
+ gF_(uly, 12, 0))
+
+#define gsSPNoOp() \
+ gO_(G_SPNOOP, 0, 0)
+
+#define gsDPHalf1(wordhi) \
+ gO_(G_RDPHALF_1, 0, wordhi)
+
+#define gsDPHalf2(wordlo) \
+ gO_(G_RDPHALF_2, 0, wordlo)
+
+#define gsDPWord(wordhi, wordlo) \
+ gsDPHalf1(wordhi), \
+ gsDPHalf2(wordlo)
+
+/* instruction macros for fast3d */
+
+#if defined(F3D_GBI)
+
+# define gsSP1Triangle(v0, v1, v2, flag) \
+ gO_( \
+ G_TRI1, \
+ 0, \
+ gF_(flag, 8, 24) | \
+ gF_(gI_(v0) * 10, 8, 16) | \
+ gF_(gI_(v1) * 10, 8, 8) | \
+ gF_(gI_(v2) * 10, 8, 0))
+
+# define gsSPCullDisplayList(v0, vn) \
+ gO_( \
+ G_CULLDL, \
+ (gI_(v0) & 0xF) * 40, \
+ gI_((vn) + 1) & 0xF) * 40)
+
+# define gsSPLineW3D(v0, v1, wd, flag) \
+ gO_( \
+ G_LINE3D, \
+ 0, \
+ gF_(flag, 8, 24) | \
+ gF_(gI_(v0) * 10, 8, 16) | \
+ gF_(gI_(v1) * 10, 8, 8) | \
+ gF_(wd, 8, 0))
+
+# define gsSPVertex(v, n, v0) \
+ gO_( \
+ G_VTX, \
+ gF_((n) - 1, 4, 20) | \
+ gF_(v0, 4, 16) | \
+ gF_(sizeof(Vtx) * (n), 16, 0), \
+ v)
+
+#endif
+
+/* instruction macros for fast3d and beta f3dex */
+#if defined(F3D_GBI) || (defined(F3D_BETA) && defined(F3DEX_GBI))
+
+# define gsSPModifyVertex(vtx, where, val) \
+ gsMoveWd(G_MW_POINTS, (vtx) * 40 + (where), val)
+
+#endif
+
+/* instruction macros for fast3d and f3dex */
+
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+
+# define gsSPForceMatrix(mptr) \
+ gsMoveMem(16, G_MV_MATRIX_1, (char *)(mptr)), \
+ gsMoveMem(16, G_MV_MATRIX_2, (char *)(mptr) + 16), \
+ gsMoveMem(16, G_MV_MATRIX_3, (char *)(mptr) + 32), \
+ gsMoveMem(16, G_MV_MATRIX_4, (char *)(mptr) + 48)
+
+# define gsSPSetGeometryMode(mode) \
+ gO_(G_SETGEOMETRYMODE, 0, gI_(mode))
+
+# define gsSPClearGeometryMode(mode) \
+ gO_(G_CLEARGEOMETRYMODE, 0, gI_(mode))
+
+# define gsSPLoadGeometryMode(mode) \
+ gsSPClearGeometryMode(~gI_(0)), \
+ gsSPSetGeometryMode(mode)
+
+# define gsSPInsertMatrix(where, num) \
+ gsMoveWd(G_MW_MATRIX, where, num)
+
+# define gsSPLookAtX(l) \
+ gsMoveMem(sizeof(Light), G_MV_LOOKATX, l)
+
+# define gsSPLookAtY(l) \
+ gsMoveMem(sizeof(Light), G_MV_LOOKATY, l)
+
+# define gsSPMatrix(matrix, param) \
+ gO_( \
+ G_MTX, \
+ gF_(param, 8, 16) | \
+ gF_(sizeof(Mtx), 16, 0), \
+ matrix)
+
+# define gsSPPopMatrix(param) \
+ gO_(G_POPMTX, 0, param)
+
+# define gsSPLight(l, n) \
+ gsMoveMem(sizeof(Light), G_MV_L0 + ((n) - 1) * 2, l)
+
+# define gsSPTexture(sc, tc, level, tile, on) \
+ gO_( \
+ G_TEXTURE, \
+ gF_(level, 3, 11) | \
+ gF_(tile, 3, 8) | \
+ gF_(on, 8, 0), \
+ gF_(sc, 16, 16) | \
+ gF_(tc, 16, 0))
+
+# define gsSPViewport(v) \
+ gsMoveMem(sizeof(Vp), G_MV_VIEWPORT, v)
+
+# define gsSPSetOtherMode(opc, shift, length, data) \
+ gO_( \
+ opc, \
+ gF_(shift, 8, 8) | \
+ gF_(length, 8, 0), \
+ data)
+
+# define gsMoveWd(index, offset, data) \
+ gO_( \
+ G_MOVEWORD, \
+ gF_(offset, 16, 8) | \
+ gF_(index, 8, 0), \
+ data)
+
+# define gsMoveMem(size, index, address) \
+ gO_( \
+ G_MOVEMEM, \
+ gF_(index, 8, 16) | \
+ gF_(size, 16, 0), \
+ address)
+
+#endif
+
+/* instruction macros for f3dex */
+
+#if defined(F3DEX_GBI)
+
+# define gsSP1Quadrangle(v0, v1, v2, v3, flag) \
+ gO_( \
+ G_TRI2, \
+ gF_(gV4_(v0, v1, v2, v3, flag) * 2, 8, 16) | \
+ gF_(gV4_(v1, v2, v3, v0, flag) * 2, 8, 8) | \
+ gF_(gV4_(v2, v3, v0, v1, flag) * 2, 8, 0), \
+ gF_(gV4_(v0, v1, v2, v3, flag) * 2, 8, 16) | \
+ gF_(gV4_(v2, v3, v0, v1, flag) * 2, 8, 8) | \
+ gF_(gV4_(v3, v0, v1, v2, flag) * 2, 8, 0))
+
+# define gsSPVertex(v, n, v0) \
+ gO_( \
+ G_VTX, \
+ gF_((v0) * 2, 8, 16) | \
+ gF_(n, 6, 10) | \
+ gF_(sizeof(Vtx) * (n) - 1, 10, 0), \
+ v)
+
+#endif
+
+/* instruction macros for f3dex and f3dex2 */
+
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+
+# define gsSP1Triangle(v0, v1, v2, flag) \
+ gO_( \
+ G_TRI1, \
+ gF_(gV3_(v0, v1, v2, flag) * 2, 8, 16) | \
+ gF_(gV3_(v1, v2, v0, flag) * 2, 8, 8) | \
+ gF_(gV3_(v2, v0, v1, flag) * 2, 8, 0), \
+ 0)
+
+# define gsSP2Triangles(v00, v01, v02, flag0, v10, v11, v12, flag1) \
+ gO_( \
+ G_TRI2, \
+ gF_(gV3_(v00, v01, v02, flag0) * 2, 8, 16) | \
+ gF_(gV3_(v01, v02, v00, flag0) * 2, 8, 8) | \
+ gF_(gV3_(v02, v00, v01, flag0) * 2, 8, 0), \
+ gF_(gV3_(v10, v11, v12, flag1) * 2, 8, 16) | \
+ gF_(gV3_(v11, v12, v10, flag1) * 2, 8, 8) | \
+ gF_(gV3_(v12, v10, v11, flag1) * 2, 8, 0))
+
+# define gsSPBranchLessZ(branchdl, vtx, zval, near, far, flag) \
+ gsSPBranchLessZrg(branchdl, vtx, zval, near, far, flag, 0, G_MAXZ)
+
+# define gsSPBranchLessZrg(branchdl, vtx, zval, near, far, flag, zmin, zmax) \
+ gsSPBranchLessZraw(branchdl, vtx, \
+ G_DEPTOZSrg(zval, near, far, flag, zmin, zmax))
+
+# define gsSPBranchLessZraw(branchdl, vtx, zval) \
+ gsDPHalf1(branchdl), \
+ gsBranchZ(vtx, zval)
+
+# define gsSPCullDisplayList(v0, vn) \
+ gO_( \
+ G_CULLDL, \
+ gF_((v0) * 2, 16, 0), \
+ gF_((vn) * 2, 16, 0))
+
+# define gsSPLineW3D(v0, v1, wd, flag) \
+ gO_( \
+ G_LINE3D, \
+ gF_(gV2_(v0, v1, flag) * 2, 8, 16) | \
+ gF_(gV2_(v1, v0, flag) * 2, 8, 8) | \
+ gF_(wd, 8, 0), \
+ 0)
+
+# define gsSPLoadUcode(uc_start, uc_dstart) \
+ gsSPLoadUcodeEx(uc_start, uc_dstart, 0x800)
+
+# define gsSPLoadUcodeL(ucode) \
+ gsSPLoadUcode( \
+ gI_(&ucode##TextStart) & 0x1FFFFFFF, \
+ gI_(&ucode##DataStart) & 0x1FFFFFFF)
+
+# if !(defined(F3D_BETA) && defined(F3DEX_GBI))
+# define gsSPModifyVertex(vtx, where, val) \
+ gO_( \
+ G_MODIFYVTX, \
+ gF_(where, 8, 16) | \
+ gF_((vtx) * 2, 16, 0), \
+ val)
+# endif
+
+# define gsBranchZ(vtx, zval) \
+ gO_( \
+ G_BRANCH_Z, \
+ gF_((vtx) * 5, 12, 12) | \
+ gF_((vtx) * 2, 12, 0), \
+ zval)
+
+# define gsLoadUcode(uc_start, uc_dsize) \
+ gO_( \
+ G_LOAD_UCODE, \
+ gF_((uc_dsize) - 1, 16, 0), \
+ uc_start)
+
+# define gsSPLoadUcodeEx(uc_start, uc_dstart, uc_dsize) \
+ gsDPHalf1(uc_dstart), \
+ gsLoadUcode(uc_start, uc_dsize)
+
+#endif
+
+/* instruction macros for f3dex2 */
+
+#if defined(F3DEX_GBI_2)
+
+# define gsSP1Quadrangle(v0, v1, v2, v3, flag) \
+ gO_( \
+ G_QUAD, \
+ gF_(gV4_(v0, v1, v2, v3, flag) * 2, 8, 16) | \
+ gF_(gV4_(v1, v2, v3, v0, flag) * 2, 8, 8) | \
+ gF_(gV4_(v2, v3, v0, v1, flag) * 2, 8, 0), \
+ gF_(gV4_(v0, v1, v2, v3, flag) * 2, 8, 16) | \
+ gF_(gV4_(v2, v3, v0, v1, flag) * 2, 8, 8) | \
+ gF_(gV4_(v3, v0, v1, v2, flag) * 2, 8, 0))
+
+# define gsSPForceMatrix(mptr) \
+ gsMoveMem(sizeof(Mtx), G_MV_MATRIX, 0, mptr), \
+ gsMoveWd(G_MW_FORCEMTX, 0, 0x10000)
+
+# define gsSPSetGeometryMode(mode) \
+ gsSPGeometryMode(0, mode)
+
+# define gsSPClearGeometryMode(mode) \
+ gsSPGeometryMode(mode, 0)
+
+# define gsSPLoadGeometryMode(mode) \
+ gsSPGeometryMode(~gI_(0), mode)
+
+# define gsSPLookAtX(l) \
+ gsMoveMem(sizeof(Light), G_MV_LIGHT, G_MVO_LOOKATX, l)
+
+# define gsSPLookAtY(l) \
+ gsMoveMem(sizeof(Light), G_MV_LIGHT, G_MVO_LOOKATY, l)
+
+# define gsSPMatrix(matrix, param) \
+ gO_( \
+ G_MTX, \
+ gF_((sizeof(Mtx) - 1) / 8, 5, 19) | \
+ gF_(gI_(param) ^ G_MTX_PUSH, 8, 0), \
+ matrix)
+
+# define gsSPPopMatrix(param) \
+ gsSPPopMatrixN(param, 1)
+
+# define gsSPPopMatrixN(param, n) \
+ gO_( \
+ G_POPMTX, \
+ gF_((sizeof(Mtx) - 1) / 8, 5, 19) | \
+ gF_(2, 8, 0), \
+ sizeof(Mtx) * (n))
+
+# define gsSPLight(l, n) \
+ gsMoveMem(sizeof(Light), G_MV_LIGHT, ((n) + 1) * 0x18, l)
+
+# define gsSPTexture(sc, tc, level, tile, on) \
+ gO_( \
+ G_TEXTURE, \
+ gF_(level, 3, 11) | \
+ gF_(tile, 3, 8) | \
+ gF_(on, 7, 1), \
+ gF_(sc, 16, 16) | \
+ gF_(tc, 16, 0))
+
+# define gsSPVertex(v, n, v0) \
+ gO_( \
+ G_VTX, \
+ gF_(n, 8, 12) | \
+ gF_((v0) + (n), 7, 1), \
+ v)
+
+# define gsSPViewport(v) \
+ gsMoveMem(sizeof(Vp), G_MV_VIEWPORT, 0, v)
+
+# define gsSPGeometryMode(clearbits, setbits) \
+ gO_( \
+ G_GEOMETRYMODE, \
+ gF_(~gI_(clearbits), 24, 0), \
+ setbits)
+
+# define gsSPSetOtherMode(opc, shift, length, data) \
+ gO_( \
+ opc, \
+ gF_(32 - (shift) - (length), 8, 8) | \
+ gF_((length) - 1, 8, 0), \
+ data)
+
+# define gsMoveWd(index, offset, data) \
+ gO_( \
+ G_MOVEWORD, \
+ gF_(index, 8, 16) | \
+ gF_(offset, 16, 0), \
+ data)
+
+# define gsMoveMem(size, index, offset, address) \
+ gO_( \
+ G_MOVEMEM, \
+ gF_((size - 1) / 8, 5, 19) | \
+ gF_((offset) / 8, 8, 8) | \
+ gF_(index, 8, 0), \
+ address)
+
+# define gsSPDma_io(flag, dmem, dram, size) \
+ gO_( \
+ G_DMA_IO, \
+ gF_(flag, 1, 23) | \
+ gF_((dmem) / 8, 10, 13) | \
+ gF_((size) - 1, 12, 0), \
+ dram)
+
+# define gsSPDmaRead(dmem, dram, size) \
+ gsSPDma_io(0, dmem, dram, size)
+
+# define gsSPDmaWrite(dmem, dram, size) \
+ gsSPDma_io(1, dmem, dram, size)
+
+# define gsSpecial3(hi, lo) \
+ gO_(G_SPECIAL_3, hi, lo)
+
+# define gsSpecial2(hi, lo) \
+ gO_(G_SPECIAL_2, hi, lo)
+
+# define gsSpecial1(hi, lo) \
+ gO_(G_SPECIAL_1, hi, lo)
+
+#endif
+
+/* instruction macros for beta fast3d and f3dex */
+
+#if defined(F3D_BETA) && (defined(F3D_GBI) || defined(F3DEX_GBI))
+
+# define gsSPPerspNormalize(scale) \
+ gO_(G_PERSPNORM, 0, scale)
+
+#else
+
+# define gsSPPerspNormalize(scale) \
+ gsMoveWd(G_MW_PERSPNORM, 0, scale)
+
+#endif
+
+/* dynamic instruction macros */
+
+#define gDisplayListPut(gdl, ...) \
+ ({ \
+ Gfx Gd_[] = {__VA_ARGS__}; \
+ for(size_t Gi_ = 0; Gi_ < sizeof(Gd_) / sizeof(Gfx); Gi_++) \
+ { \
+ *(Gfx *)(gdl) = Gd_[Gi_]; \
+ } \
+ (void)0; \
+ })
+#define gDisplayListAppend(pgdl, ...) \
+ ({ \
+ Gfx Gd_[] = {__VA_ARGS__}; \
+ for(size_t Gi_ = 0; Gi_ < sizeof(Gd_) / sizeof(Gfx); Gi_++) \
+ { \
+ *(*(Gfx **)(pgdl))++ = Gd_[Gi_]; \
+ } \
+ (void)0; \
+ })
+#define gDisplayListData(pgdl, d) \
+ ({ \
+ Gfx **Gp_ = (void *)(pgdl); \
+ struct \
+ { \
+ __typeof__(d) v; \
+ } *Gd_, *Gs_; \
+ *Gp_ -= (sizeof(*Gd_) + sizeof(Gfx) - 1) / sizeof(Gfx); \
+ Gd_ = (void *)*Gp_; \
+ Gs_ = (void *)&(d); \
+ *Gd_ = *Gs_; \
+ &Gd_->v; \
+ })
+#define gDisplayListAlloc(pgdl, s) \
+ ({ \
+ Gfx **Gp_ = (void *)(pgdl); \
+ *Gp_ -= ((s) + sizeof(Gfx) - 1) / sizeof(Gfx); \
+ (void *)*Gp_; \
+ })
+
+#define gDPFillRectangle(gdl, ...) \
+ gD_(gdl, gsDPFillRectangle, __VA_ARGS__)
+#define gDPScisFillRectangle(gdl, ...) \
+ gD_(gdl, gsDPScisFillRectangle, __VA_ARGS__)
+#define gDPFullSync(gdl) \
+ gDisplayListPut(gdl, gsDPFullSync())
+#define gDPLoadSync(gdl) \
+ gDisplayListPut(gdl, gsDPLoadSync())
+#define gDPTileSync(gdl) \
+ gDisplayListPut(gdl, gsDPTileSync())
+#define gDPPipeSync(gdl) \
+ gDisplayListPut(gdl, gsDPPipeSync())
+#define gDPLoadTLUT_pal16(gdl, ...) \
+ gD_(gdl, gsDPLoadTLUT_pal16, __VA_ARGS__)
+#define gDPLoadTLUT_pal256(gdl, ...) \
+ gD_(gdl, gsDPLoadTLUT_pal256, __VA_ARGS__)
+#define gDPLoadTextureBlock(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureBlock, __VA_ARGS__)
+#define gDPLoadTextureBlockS(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureBlockS, __VA_ARGS__)
+#define gDPLoadTextureBlock_4b(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureBlock_4b, __VA_ARGS__)
+#define gDPLoadTextureBlock_4bS(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureBlock_4bS, __VA_ARGS__)
+#define gDPLoadTextureBlockYuv(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureBlockYuv, __VA_ARGS__)
+#define gDPLoadTextureBlockYuvS(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureBlockYuvS, __VA_ARGS__)
+#define _gDPLoadTextureBlock(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureBlock, __VA_ARGS__)
+#define _gDPLoadTextureBlockS(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureBlockS, __VA_ARGS__)
+#define _gDPLoadTextureBlock_4b(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureBlock_4b, __VA_ARGS__)
+#define _gDPLoadTextureBlock_4bS(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureBlock_4bS, __VA_ARGS__)
+#define _gDPLoadTextureBlockYuv(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureBlockYuv, __VA_ARGS__)
+#define _gDPLoadTextureBlockYuvS(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureBlockYuvS, __VA_ARGS__)
+#define gDPLoadMultiBlock(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiBlock, __VA_ARGS__)
+#define gDPLoadMultiBlockS(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiBlockS, __VA_ARGS__)
+#define gDPLoadMultiBlock_4b(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiBlock_4b, __VA_ARGS__)
+#define gDPLoadMultiBlock_4bS(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiBlock_4bS, __VA_ARGS__)
+#define gDPLoadMultiBlockYuv(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiBlockYuv, __VA_ARGS__)
+#define gDPLoadMultiBlockYuvS(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiBlockYuvS, __VA_ARGS__)
+#define gDPLoadTextureTile(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureTile, __VA_ARGS__)
+#define gDPLoadTextureTile_4b(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureTile_4b, __VA_ARGS__)
+#define gDPLoadTextureTileYuv(gdl, ...) \
+ gD_(gdl, gsDPLoadTextureTileYuv, __VA_ARGS__)
+#define _gDPLoadTextureTile(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureTile, __VA_ARGS__)
+#define _gDPLoadTextureTile_4b(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureTile_4b, __VA_ARGS__)
+#define _gDPLoadTextureTileYuv(gdl, ...) \
+ gD_(gdl, _gsDPLoadTextureTileYuv, __VA_ARGS__)
+#define gDPLoadMultiTile(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiTile, __VA_ARGS__)
+#define gDPLoadMultiTile_4b(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiTile_4b, __VA_ARGS__)
+#define gDPLoadMultiTileYuv(gdl, ...) \
+ gD_(gdl, gsDPLoadMultiTileYuv, __VA_ARGS__)
+#define gDPLoadBlock(gdl, ...) \
+ gD_(gdl, gsDPLoadBlock, __VA_ARGS__)
+#define gDPNoOp(gdl) \
+ gDisplayListPut(gdl, gsDPNoOp())
+#define gDPNoOpTag(gdl, ...) \
+ gD_(gdl, gsDPNoOpTag, __VA_ARGS__)
+#define gDPPipelineMode(gdl, ...) \
+ gD_(gdl, gsDPPipelineMode, __VA_ARGS__)
+#define gDPSetBlendColor(gdl, ...) \
+ gD_(gdl, gsDPSetBlendColor, __VA_ARGS__)
+#define gDPSetEnvColor(gdl, ...) \
+ gD_(gdl, gsDPSetEnvColor, __VA_ARGS__)
+#define gDPSetFillColor(gdl, ...) \
+ gD_(gdl, gsDPSetFillColor, __VA_ARGS__)
+#define gDPSetFogColor(gdl, ...) \
+ gD_(gdl, gsDPSetFogColor, __VA_ARGS__)
+#define gDPSetPrimColor(gdl, ...) \
+ gD_(gdl, gsDPSetPrimColor, __VA_ARGS__)
+#define gDPSetColorImage(gdl, ...) \
+ gD_(gdl, gsDPSetColorImage, __VA_ARGS__)
+#define gDPSetDepthImage(gdl, ...) \
+ gD_(gdl, gsDPSetDepthImage, __VA_ARGS__)
+#define gDPSetTextureImage(gdl, ...) \
+ gD_(gdl, gsDPSetTextureImage, __VA_ARGS__)
+#define gDPSetHilite1Tile(gdl, ...) \
+ gD_(gdl, gsDPSetHilite1Tile, __VA_ARGS__)
+#define gDPSetHilite2Tile(gdl, ...) \
+ gD_(gdl, gsDPSetHilite2Tile, __VA_ARGS__)
+#define gDPSetAlphaCompare(gdl, ...) \
+ gD_(gdl, gsDPSetAlphaCompare, __VA_ARGS__)
+#define gDPSetAlphaDither(gdl, ...) \
+ gD_(gdl, gsDPSetAlphaDither, __VA_ARGS__)
+#define gDPSetColorDither(gdl, ...) \
+ gD_(gdl, gsDPSetColorDither, __VA_ARGS__)
+#define gDPSetCombineMode(gdl, ...) \
+ gD_(gdl, gsDPSetCombineLERP, __VA_ARGS__)
+#define gDPSetCombineLERP(gdl, ...) \
+ gD_(gdl, gsDPSetCombineLERP, __VA_ARGS__)
+#define gDPSetConvert(gdl, ...) \
+ gD_(gdl, gsDPSetConvert, __VA_ARGS__)
+#define gDPSetTextureConvert(gdl, ...) \
+ gD_(gdl, gsDPSetTextureConvert, __VA_ARGS__)
+#define gDPSetCycleType(gdl, ...) \
+ gD_(gdl, gsDPSetCycleType, __VA_ARGS__)
+#define gDPSetDepthSource(gdl, ...) \
+ gD_(gdl, gsDPSetDepthSource, __VA_ARGS__)
+#define gDPSetCombineKey(gdl, ...) \
+ gD_(gdl, gsDPSetCombineKey, __VA_ARGS__)
+#define gDPSetKeyGB(gdl, ...) \
+ gD_(gdl, gsDPSetKeyGB, __VA_ARGS__)
+#define gDPSetKeyR(gdl, ...) \
+ gD_(gdl, gsDPSetKeyR, __VA_ARGS__)
+#define gDPSetPrimDepth(gdl, ...) \
+ gD_(gdl, gsDPSetPrimDepth, __VA_ARGS__)
+#define gDPSetRenderMode(gdl, ...) \
+ gD_(gdl, gsDPSetRenderMode, __VA_ARGS__)
+#define gDPSetScissor(gdl, ...) \
+ gD_(gdl, gsDPSetScissor, __VA_ARGS__)
+#define gDPSetScissorFrac(gdl, ...) \
+ gD_(gdl, gsDPSetScissorFrac, __VA_ARGS__)
+#define gDPSetTextureDetail(gdl, ...) \
+ gD_(gdl, gsDPSetTextureDetail, __VA_ARGS__)
+#define gDPSetTextureFilter(gdl, ...) \
+ gD_(gdl, gsDPSetTextureFilter, __VA_ARGS__)
+#define gDPSetTextureLOD(gdl, ...) \
+ gD_(gdl, gsDPSetTextureLOD, __VA_ARGS__)
+#define gDPSetTextureLUT(gdl, ...) \
+ gD_(gdl, gsDPSetTextureLUT, __VA_ARGS__)
+#define gDPSetTexturePersp(gdl, ...) \
+ gD_(gdl, gsDPSetTexturePersp, __VA_ARGS__)
+#define gDPSetTile(gdl, ...) \
+ gD_(gdl, gsDPSetTile, __VA_ARGS__)
+#define gDPSetTileSize(gdl, ...) \
+ gD_(gdl, gsDPSetTileSize, __VA_ARGS__)
+#define gSP1Triangle(gdl, ...) \
+ gD_(gdl, gsSP1Triangle, __VA_ARGS__)
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+# define gSP2Triangles(gdl, ...) \
+ gD_(gdl, gsSP2Triangles, __VA_ARGS__)
+# define gSP1Quadrangle(gdl, ...) \
+ gD_(gdl, gsSP1Quadrangle, __VA_ARGS__)
+# define gSPBranchLessZ(gdl, ...) \
+ gD_(gdl, gsSPBranchLessZ, __VA_ARGS__)
+# define gSPBranchLessZrg(gdl, ...) \
+ gD_(gdl, gsSPBranchLessZrg, __VA_ARGS__)
+# define gSPBranchLessZraw(gdl, ...) \
+ gD_(gdl, gsSPBranchLessZraw, __VA_ARGS__)
+#endif
+#define gSPBranchList(gdl, ...) \
+ gD_(gdl, gsSPBranchList, __VA_ARGS__)
+#define gSPClipRatio(gdl, ...) \
+ gD_(gdl, gsSPClipRatio, __VA_ARGS__)
+#define gSPCullDisplayList(gdl, ...) \
+ gD_(gdl, gsSPCullDisplayList, __VA_ARGS__)
+#define gSPDisplayList(gdl, ...) \
+ gD_(gdl, gsSPDisplayList, __VA_ARGS__)
+#define gSPEndDisplayList(gdl) \
+ gDisplayListPut(gdl, gsSPEndDisplayList())
+#define gSPFogFactor(gdl, ...) \
+ gD_(gdl, gsSPFogFactor, __VA_ARGS__)
+#define gSPFogPosition(gdl, ...) \
+ gD_(gdl, gsSPFogPosition, __VA_ARGS__)
+#define gSPForceMatrix(gdl, ...) \
+ gD_(gdl, gsSPForceMatrix, __VA_ARGS__)
+#define gSPSetGeometryMode(gdl, ...) \
+ gD_(gdl, gsSPSetGeometryMode, __VA_ARGS__)
+#define gSPClearGeometryMode(gdl, ...) \
+ gD_(gdl, gsSPClearGeometryMode, __VA_ARGS__)
+#define gSPLoadGeometryMode(gdl, ...) \
+ gD_(gdl, gsSPLoadGeometryMode, __VA_ARGS__)
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+# define gSPInsertMatrix(gdl, ...) \
+ gD_(gdl, gsSPInsertMatrix, __VA_ARGS__)
+#endif
+#define gSPLine3D(gdl, ...) \
+ gD_(gdl, gsSPLine3D, __VA_ARGS__)
+#define gSPLineW3D(gdl, ...) \
+ gD_(gdl, gsSPLineW3D, __VA_ARGS__)
+#define gSPLoadUcode(gdl, ...) \
+ gD_(gdl, gsSPLoadUcode, __VA_ARGS__)
+#define gSPLoadUcodeL(gdl, ...) \
+ gD_(gdl, gsSPLoadUcodeL, __VA_ARGS__)
+#define gSPLookAtX(gdl, ...) \
+ gD_(gdl, gsSPLookAtX, __VA_ARGS__)
+#define gSPLookAtY(gdl, ...) \
+ gD_(gdl, gsSPLookAtY, __VA_ARGS__)
+#define gSPLookAt(gdl, ...) \
+ gD_(gdl, gsSPLookAt, __VA_ARGS__)
+#define gSPMatrix(gdl, ...) \
+ gD_(gdl, gsSPMatrix, __VA_ARGS__)
+#define gSPModifyVertex(gdl, ...) \
+ gD_(gdl, gsSPModifyVertex, __VA_ARGS__)
+#define gSPPerspNormalize(gdl, ...) \
+ gD_(gdl, gsSPPerspNormalize, __VA_ARGS__)
+#define gSPPopMatrix(gdl, ...) \
+ gD_(gdl, gsSPPopMatrix, __VA_ARGS__)
+#if defined(F3DEX_GBI_2)
+# define gSPPopMatrixN(gdl, ...) \
+ gD_(gdl, gsSPPopMatrixN, __VA_ARGS__)
+#endif
+#define gSPSegment(gdl, ...) \
+ gD_(gdl, gsSPSegment, __VA_ARGS__)
+#define gSPSetLights0(gdl, ...) \
+ gD_(gdl, gsSPSetLights0, __VA_ARGS__)
+#define gSPSetLights1(gdl, ...) \
+ gD_(gdl, gsSPSetLights1, __VA_ARGS__)
+#define gSPSetLights2(gdl, ...) \
+ gD_(gdl, gsSPSetLights2, __VA_ARGS__)
+#define gSPSetLights3(gdl, ...) \
+ gD_(gdl, gsSPSetLights3, __VA_ARGS__)
+#define gSPSetLights4(gdl, ...) \
+ gD_(gdl, gsSPSetLights4, __VA_ARGS__)
+#define gSPSetLights5(gdl, ...) \
+ gD_(gdl, gsSPSetLights5, __VA_ARGS__)
+#define gSPSetLights6(gdl, ...) \
+ gD_(gdl, gsSPSetLights6, __VA_ARGS__)
+#define gSPSetLights7(gdl, ...) \
+ gD_(gdl, gsSPSetLights7, __VA_ARGS__)
+#define gSPSetStatus(gdl, ...) \
+ gD_(gdl, gsSPSetStatus, __VA_ARGS__)
+#define gSPNumLights(gdl, ...) \
+ gD_(gdl, gsSPNumLights, __VA_ARGS__)
+#define gSPLight(gdl, ...) \
+ gD_(gdl, gsSPLight, __VA_ARGS__)
+#define gSPLightColor(gdl, ...) \
+ gD_(gdl, gsSPLightColor, __VA_ARGS__)
+#define gSPTexture(gdl, ...) \
+ gD_(gdl, gsSPTexture, __VA_ARGS__)
+#define gSPTextureRectangle(gdl, ...) \
+ gD_(gdl, gsSPTextureRectangle, __VA_ARGS__)
+#define gSPScisTextureRectangle(gdl, ...) \
+ gD_(gdl, gsSPScisTextureRectangle, __VA_ARGS__)
+#define gSPTextureRectangleFlip(gdl, ...) \
+ gD_(gdl, gsSPTextureRectangleFlip, __VA_ARGS__)
+#define gSPScisTextureRectangleFlip(gdl, ...) \
+ gD_(gdl, gsSPScisTextureRectangleFlip, __VA_ARGS__)
+#define gSPVertex(gdl, ...) \
+ gD_(gdl, gsSPVertex, __VA_ARGS__)
+#define gSPViewport(gdl, ...) \
+ gD_(gdl, gsSPViewport, __VA_ARGS__)
+#define gSPBgRectCopy(gdl, ...) \
+ gD_(gdl, gsSPBgRectCopy, __VA_ARGS__)
+#define gSPBgRect1Cyc(gdl, ...) \
+ gD_(gdl, gsSPBgRect1Cyc, __VA_ARGS__)
+#define gSPObjRectangle(gdl, ...) \
+ gD_(gdl, gsSPObjRectangle, __VA_ARGS__)
+#define gSPObjRectangleR(gdl, ...) \
+ gD_(gdl, gsSPObjRectangleR, __VA_ARGS__)
+#define gSPObjSprite(gdl, ...) \
+ gD_(gdl, gsSPObjSprite, __VA_ARGS__)
+#define gSPObjMatrix(gdl, ...) \
+ gD_(gdl, gsSPObjMatrix, __VA_ARGS__)
+#define gSPObjSubMatrix(gdl, ...) \
+ gD_(gdl, gsSPObjSubMatrix, __VA_ARGS__)
+#define gSPObjRenderMode(gdl, ...) \
+ gD_(gdl, gsSPObjRenderMode, __VA_ARGS__)
+#define gSPObjLoadTxtr(gdl, ...) \
+ gD_(gdl, gsSPObjLoadTxtr, __VA_ARGS__)
+#define gSPObjLoadTxRect(gdl, ...) \
+ gD_(gdl, gsSPObjLoadTxRect, __VA_ARGS__)
+#define gSPObjLoadTxRectR(gdl, ...) \
+ gD_(gdl, gsSPObjLoadTxRectR, __VA_ARGS__)
+#define gSPObjLoadTxSprite(gdl, ...) \
+ gD_(gdl, gsSPObjLoadTxSprite, __VA_ARGS__)
+#define gSPSelectDL(gdl, ...) \
+ gD_(gdl, gsSPSelectDL, __VA_ARGS__)
+#define gSPSelectBranchDL(gdl, ...) \
+ gD_(gdl, gsSPSelectBranchDL, __VA_ARGS__)
+#define gDPLoadTLUTCmd(gdl, ...) \
+ gD_(gdl, gsDPLoadTLUTCmd, __VA_ARGS__)
+#define gDPLoadTLUT(gdl, ...) \
+ gD_(gdl, gsDPLoadTLUT, __VA_ARGS__)
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+# define gBranchZ(gdl, ...) \
+ gD_(gdl, gsBranchZ, __VA_ARGS__)
+#endif
+#define gDisplayList(gdl, ...) \
+ gD_(gdl, gsDisplayList, __VA_ARGS__)
+#define gDPHalf1(gdl, ...) \
+ gD_(gdl, gsDPHalf1, __VA_ARGS__)
+#define gDPHalf2(gdl, ...) \
+ gD_(gdl, gsDPHalf2, __VA_ARGS__)
+#define gDPLoadTile(gdl, ...) \
+ gD_(gdl, gsDPLoadTile, __VA_ARGS__)
+#define gDPSetCombine(gdl, ...) \
+ gD_(gdl, gsDPSetCombine, __VA_ARGS__)
+#if defined(F3DEX_GBI_2)
+# define gSPGeometryMode(gdl, ...) \
+ gD_(gdl, gsSPGeometryMode, __VA_ARGS__)
+#endif
+#define gSPSetOtherMode(gdl, ...) \
+ gD_(gdl, gsSPSetOtherMode, __VA_ARGS__)
+#define gSPSetOtherModeLo(gdl, ...) \
+ gD_(gdl, gsSPSetOtherModeLo, __VA_ARGS__)
+#define gSPSetOtherModeHi(gdl, ...) \
+ gD_(gdl, gsSPSetOtherModeHi, __VA_ARGS__)
+#define gDPSetOtherMode(gdl, ...) \
+ gD_(gdl, gsDPSetOtherMode, __VA_ARGS__)
+#define gMoveWd(gdl, ...) \
+ gD_(gdl, gsMoveWd, __VA_ARGS__)
+#define gMoveMem(gdl, ...) \
+ gD_(gdl, gsMoveMem, __VA_ARGS__)
+#if defined(F3DEX_GBI_2)
+# define gSPDma_io(gdl, ...) \
+ gD_(gdl, gsSPDma_io, __VA_ARGS__)
+# define gSPDmaRead(gdl, ...) \
+ gD_(gdl, gsSPDmaRead, __VA_ARGS__)
+# define gSPDmaWrite(gdl, ...) \
+ gD_(gdl, gsSPDmaWrite, __VA_ARGS__)
+#endif
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+# define gLoadUcode(gdl, ...) \
+ gD_(gdl, gsLoadUcode, __VA_ARGS__)
+# define gSPLoadUcodeEx(gdl, ...) \
+ gD_(gdl, gsSPLoadUcodeEx, __VA_ARGS__)
+#endif
+#define gTexRect(gdl, ...) \
+ gD_(gdl, gsTexRect, __VA_ARGS__)
+#define gTexRectFlip(gdl, ...) \
+ gD_(gdl, gsTexRectFlip, __VA_ARGS__)
+#define gSPNoOp(gdl) \
+ gDisplayListPut(gdl, gsSPNoOp())
+#define gDPWord(gdl, ...) \
+ gD_(gdl, gsDPWord, __VA_ARGS__)
+#if defined(F3DEX_GBI_2)
+# define gSpecial3(gdl, ...) \
+ gD_(gdl, gsSpecial3, __VA_ARGS__)
+# define gSpecial2(gdl, ...) \
+ gD_(gdl, gsSpecial2, __VA_ARGS__)
+# define gSpecial1(gdl, ...) \
+ gD_(gdl, gsSpecial1, __VA_ARGS__)
+#endif
+
+/* data types and structures */
+typedef uint8_t qu08_t;
+typedef uint16_t qu016_t;
+typedef int16_t qs48_t;
+typedef int16_t qs510_t;
+typedef uint16_t qu510_t;
+typedef int16_t qs102_t;
+typedef uint16_t qu102_t;
+typedef int16_t qs105_t;
+typedef uint16_t qu105_t;
+typedef int16_t qs132_t;
+typedef int16_t qs142_t;
+typedef int32_t qs1516_t;
+typedef int32_t qs1616_t;
+typedef int32_t qs205_t;
+
+typedef uint16_t g_bglt_t;
+typedef uint8_t g_ifmt_t;
+typedef uint8_t g_isiz_t;
+typedef uint16_t g_bgf_t;
+typedef uint8_t g_objf_t;
+typedef uint32_t g_objlt_t;
+
+typedef struct
+{
+ _Alignas(8)
+ uint32_t hi;
+ uint32_t lo;
+} Gfx;
+
+typedef struct
+{
+ int32_t x1;
+ int32_t y1;
+ int32_t x2;
+ int32_t y2;
+} Hilite_t;
+
+typedef union
+{
+ _Alignas(8)
+ Hilite_t h;
+} Hilite;
+
+typedef int32_t Mtx_t[4][4];
+
+typedef union
+{
+ _Alignas(8)
+ Mtx_t m;
+ int32_t l[16];
+ struct
+ {
+ int16_t i[16];
+ uint16_t f[16];
+ };
+} Mtx;
+
+typedef struct
+{
+ uint8_t col[3];
+ char pad1;
+ uint8_t colc[3];
+ char pad2;
+ int8_t dir[3];
+ char pad3;
+} Light_t;
+
+typedef union
+{
+ _Alignas(8)
+ Light_t l;
+} Light;
+
+typedef struct
+{
+ Light l[2];
+} LookAt;
+
+typedef struct
+{
+ uint8_t col[3];
+ char pad1;
+ uint8_t colc[3];
+ char pad2;
+} Ambient_t;
+
+typedef union
+{
+ _Alignas(8)
+ Ambient_t l;
+} Ambient;
+
+typedef struct
+{
+ Ambient a;
+ Light l[1];
+} Lights0, Lights1;
+
+typedef struct
+{
+ Ambient a;
+ Light l[2];
+} Lights2;
+
+typedef struct
+{
+ Ambient a;
+ Light l[3];
+} Lights3;
+
+typedef struct
+{
+ Ambient a;
+ Light l[4];
+} Lights4;
+
+typedef struct
+{
+ Ambient a;
+ Light l[5];
+} Lights5;
+
+typedef struct
+{
+ Ambient a;
+ Light l[6];
+} Lights6;
+
+typedef struct
+{
+ Ambient a;
+ Light l[7];
+} Lightsn, Lights7;
+
+typedef struct
+{
+ int16_t ob[3];
+ uint16_t flag;
+ qs105_t tc[2];
+ uint8_t cn[4];
+} Vtx_t;
+
+typedef struct
+{
+ int16_t ob[3];
+ uint16_t flag;
+ qs105_t tc[2];
+ int8_t n[3];
+ uint8_t a;
+} Vtx_tn;
+
+typedef union
+{
+ _Alignas(8)
+ Vtx_t v;
+ Vtx_tn n;
+} Vtx;
+
+typedef struct
+{
+ qs142_t vscale[4];
+ qs142_t vtrans[4];
+} Vp_t;
+
+typedef union
+{
+ _Alignas(8)
+ Vp_t vp;
+} Vp;
+
+typedef struct
+{
+ qs1516_t A;
+ qs1516_t B;
+ qs1516_t C;
+ qs1516_t D;
+ qs102_t X;
+ qs102_t Y;
+ qu510_t BaseScaleX;
+ qu510_t BaseScaleY;
+} uObjMtx_t;
+
+typedef union
+{
+ _Alignas(8)
+ uObjMtx_t m;
+} uObjMtx;
+
+typedef struct
+{
+ qs102_t X;
+ qs102_t Y;
+ qu510_t BaseScaleX;
+ qu510_t BaseScaleY;
+} uObjSubMtx_t;
+
+typedef union
+{
+ _Alignas(8)
+ uObjSubMtx_t m;
+} uObjSubMtx;
+
+typedef struct
+{
+ qu105_t imageX;
+ qu102_t imageW;
+ qs102_t frameX;
+ qu102_t frameW;
+ qu105_t imageY;
+ qu102_t imageH;
+ qs102_t frameY;
+ qu102_t frameH;
+ uint64_t * imagePtr;
+ g_bglt_t imageLoad;
+ g_ifmt_t imageFmt;
+ g_isiz_t imageSiz;
+ uint16_t imagePal;
+ g_bgf_t imageFlip;
+ uint16_t tmemW;
+ qs132_t tmemH;
+ uint16_t tmemLoadSH;
+ uint16_t tmemLoadTH;
+ uint16_t tmemSizeW;
+ uint16_t tmemSize;
+} uObjBg_t;
+
+typedef struct
+{
+ qu105_t imageX;
+ qu102_t imageW;
+ qs102_t frameX;
+ qu102_t frameW;
+ qu105_t imageY;
+ qu102_t imageH;
+ qs102_t frameY;
+ qu102_t frameH;
+ uint64_t * imagePtr;
+ g_bglt_t imageLoad;
+ g_ifmt_t imageFmt;
+ g_isiz_t imageSiz;
+ uint16_t imagePal;
+ g_bgf_t imageFlip;
+ qu510_t scaleW;
+ qu510_t scaleH;
+ qs205_t imageYorig;
+ char padding[4];
+} uObjScaleBg_t;
+
+typedef union
+{
+ _Alignas(8)
+ uObjBg_t b;
+ uObjScaleBg_t s;
+} uObjBg;
+
+typedef struct
+{
+ qs102_t objX;
+ qu510_t scaleW;
+ qu105_t imageW;
+ uint16_t paddingX;
+ qs102_t objY;
+ qu510_t scaleH;
+ qu105_t imageH;
+ uint16_t paddingY;
+ uint16_t imageStride;
+ uint16_t imageAdrs;
+ g_ifmt_t imageFmt;
+ g_isiz_t imageSiz;
+ uint16_t imagePal;
+ g_objf_t imageFlags;
+} uObjSprite_t;
+
+typedef union
+{
+ _Alignas(8)
+ uObjSprite_t s;
+} uObjSprite;
+
+typedef struct
+{
+ g_objlt_t type;
+ uint64_t * image;
+ uint16_t tmem;
+ uint16_t tsize;
+ uint16_t tline;
+ uint16_t sid;
+ uint32_t flag;
+ uint32_t mask;
+} uObjTxtrBlock_t;
+
+typedef struct
+{
+ g_objlt_t type;
+ uint64_t * image;
+ uint16_t tmem;
+ uint16_t twidth;
+ uint16_t theight;
+ uint16_t sid;
+ uint32_t flag;
+ uint32_t mask;
+} uObjTxtrTile_t;
+
+typedef struct
+{
+ g_objlt_t type;
+ uint64_t * image;
+ uint16_t phead;
+ uint16_t pnum;
+ uint16_t zero;
+ uint16_t sid;
+ uint32_t flag;
+ uint32_t mask;
+} uObjTxtrTLUT_t;
+
+typedef union
+{
+ _Alignas(8)
+ uObjTxtrBlock_t block;
+ uObjTxtrTile_t tile;
+ uObjTxtrTLUT_t tlut;
+} uObjTxtr;
+
+typedef struct
+{
+ uObjTxtr txtr;
+ uObjSprite sprite;
+} uObjTxSprite;
+
+/* rectangle scissoring macros */
+#define gScC_(c) ((c) < 0 ? 0 : (c))
+#define gScD_(t, c, d) \
+ ( \
+ (c) < 0 ? \
+ ( \
+ (d) < 0 ? \
+ (t) + (c) * (d) / 0x80 : \
+ (t) - (c) * (d) / 0x80 \
+ ) : \
+ (t) \
+ )
+
+/* texture loading helper macros */
+#define G_SIZ_LDSIZ(siz) ((siz) < G_IM_SIZ_16b ? G_IM_SIZ_16b : (siz))
+#define G_SIZ_BITS(siz) (4 << gI_(siz))
+#define G_SIZ_LDBITS(siz) ((siz) < G_IM_SIZ_16b ? G_SIZ_BITS(siz) : 16)
+#define G_DXT(siz, width) \
+ ( \
+ (width) * G_SIZ_BITS(siz) <= 64 ? \
+ (1 << 11) : \
+ ((1 << 11) + (width) * G_SIZ_BITS(siz) / 64 - 1) / \
+ ((width) * G_SIZ_BITS(siz) / 64) \
+ )
+
+/* depth value macros */
+#define gZp_(zval, near, far) \
+ ( \
+ (1.f - (float)(near) / (float)(zval)) / \
+ (1.f - (float)(near) / (float)(far)) \
+ )
+#define gZo_(zval, near, far) \
+ ( \
+ ((float)(zval) - (float)(near)) / \
+ ((float)(far) - (float)(near)) \
+ )
+#define gZf_(zval, near, far, flag) \
+ qs1616 \
+ ( \
+ (flag) == G_BZ_PERSP ? \
+ gZp_(zval, near, far) : \
+ gZo_(zval, near, far) \
+ )
+#define G_DEPTOZSrg(zval, near, far, flag, zmin, zmax) \
+ ( \
+ gZf_(zval, near, far, flag) * \
+ ((int32_t)((zmax) - (zmin)) & ~(int32_t)1) + \
+ qs1616(zmin) \
+ )
+#define G_DEPTOZS(zval, near, far, flag) \
+ G_DEPTOZSrg(zval, near, far, flag, 0, G_MAXZ)
+
+/* vertex ordering macros */
+#define gV2_(v0, v1, flag) \
+ ( \
+ (flag) == 0 ? gI_(v0) : \
+ gI_(v1) \
+ )
+#define gV3_(v0, v1, v2, flag) \
+ ( \
+ (flag) == 0 ? gI_(v0) : \
+ (flag) == 1 ? gI_(v1) : \
+ gI_(v2) \
+ )
+#define gV4_(v0, v1, v2, v3, flag) \
+ ( \
+ (flag) == 0 ? gI_(v0) : \
+ (flag) == 1 ? gI_(v1) : \
+ (flag) == 2 ? gI_(v2) : \
+ gI_(v3) \
+ )
+
+/* sprite texture parameter macros */
+#define GS_PIX2TMEM(pix, siz) ((pix) * G_SIZ_BITS(siz) / 64)
+#define GS_TB_TSIZE(pix, siz) (GS_PIX2TMEM(pix, siz) - 1)
+#define GS_TB_TLINE(pix, siz) (((1 << 11) - 1) / GS_PIX2TMEM(pix, siz) + 1)
+#define GS_TT_TWIDTH(pix, siz) (GS_PIX2TMEM(pix, siz) * 4 - 1)
+#define GS_TT_THEIGHT(pix, siz) ((pix) * 4 - 1)
+#define GS_PAL_HEAD(head) ((head) + 256)
+#define GS_PAL_NUM(num) ((num) - 1)
+
+/* fixed-point conversion macros */
+#define qu08(n) ((qu08_t)((n) * 0x100))
+#define qu016(n) ((qu016_t)((n) * 0x10000))
+#define qs48(n) ((qs48_t)((n) * 0x0100))
+#define qs510(n) ((qs510_t)((n) * 0x0400))
+#define qu510(n) ((qu510_t)((n) * 0x0400))
+#define qs102(n) ((qs102_t)((n) * 0x0004))
+#define qu102(n) ((qu102_t)((n) * 0x0004))
+#define qs105(n) ((qs105_t)((n) * 0x0020))
+#define qu105(n) ((qu105_t)((n) * 0x0020))
+#define qs132(n) ((qs132_t)((n) * 0x0004))
+#define qs142(n) ((qs142_t)((n) * 0x0004))
+#define qs1516(n) ((qs1516_t)((n) * 0x00010000))
+#define qs1616(n) ((qs1616_t)((n) * 0x00010000))
+#define qs205(n) ((qs205_t)((n) * 0x00000020))
+
+/* private helper macros */
+#define gI_(i) ((uint32_t)(i))
+#define gL_(l) ((uint64_t)(l))
+#define gF_(i, n, s) ((gI_(i) & ((gI_(1) << (n)) - 1)) << (s))
+#define gFL_(l, n, s) ((gL_(l) & ((gL_(1) << (n)) - 1)) << (s))
+#define gO_(opc, hi, lo) ((Gfx){gF_(opc, 8, 24) | gI_(hi), gI_(lo)})
+#define gD_(gdl, m, ...) gDisplayListPut(gdl, m(__VA_ARGS__))
+
+#endif
diff --git a/lib/libgfxd/gfxd.c b/lib/libgfxd/gfxd.c
new file mode 100644
index 0000000..76d7ded
--- /dev/null
+++ b/lib/libgfxd/gfxd.c
@@ -0,0 +1,863 @@
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef _WIN32
+# include <io.h>
+# define read _read
+# define write _write
+#else
+# include <unistd.h>
+#endif
+#include "gbi.h"
+#include "gfxd.h"
+#include "priv.h"
+
+static TLOCAL struct gfxd_state state;
+
+static int buffer_input_fn(void *buf, int count)
+{
+ if (count > config.input_buf_size)
+ count = config.input_buf_size;
+ memcpy(buf, config.input_buf, count);
+ config.input_buf += count;
+ config.input_buf_size -= count;
+ return count;
+}
+
+static int buffer_output_fn(const char *buf, int count)
+{
+ if (count > config.output_buf_size)
+ count = config.output_buf_size;
+ memcpy(config.output_buf, buf, count);
+ config.output_buf += count;
+ config.output_buf_size -= count;
+ return count;
+}
+
+static int fd_input_fn(void *buf, int count)
+{
+ return read(config.input_fd, buf, count);
+}
+
+static int fd_output_fn(const char *buf, int count)
+{
+ return write(config.output_fd, buf, count);
+}
+
+static void swap_words(Gfx *gfx)
+{
+ uint8_t b[8];
+ uint8_t *pw = (void *) gfx;
+ uint8_t *pb = b;
+
+ int endian = config.endian;
+ int wordsize = config.wordsize;
+
+ for (int i = 0; i < 8 / wordsize; i++)
+ {
+ if (endian == gfxd_endian_host)
+ {
+ switch (wordsize)
+ {
+ case 1:
+ {
+ uint8_t w = *(uint8_t *) pw;
+ *pb++ = w >> 0;
+ break;
+ }
+ case 2:
+ {
+ uint16_t w = *(uint16_t *) pw;
+ *pb++ = w >> 8;
+ *pb++ = w >> 0;
+ break;
+ }
+ case 4:
+ {
+ uint32_t w = *(uint32_t *) pw;
+ *pb++ = w >> 24;
+ *pb++ = w >> 16;
+ *pb++ = w >> 8;
+ *pb++ = w >> 0;
+ break;
+ }
+ case 8:
+ {
+ uint64_t w = *(uint64_t *) pw;
+ *pb++ = w >> 56;
+ *pb++ = w >> 48;
+ *pb++ = w >> 40;
+ *pb++ = w >> 32;
+ *pb++ = w >> 24;
+ *pb++ = w >> 16;
+ *pb++ = w >> 8;
+ *pb++ = w >> 0;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (int j = 0; j < wordsize; j++)
+ {
+ if (endian == gfxd_endian_little)
+ *pb++ = pw[wordsize - 1 - j];
+ else
+ *pb++ = pw[j];
+ }
+ }
+ pw += wordsize;
+ }
+
+ gfx->hi = ((uint32_t) b[0] << 24)
+ | ((uint32_t) b[1] << 16)
+ | ((uint32_t) b[2] << 8)
+ | ((uint32_t) b[3] << 0);
+ gfx->lo = ((uint32_t) b[4] << 24)
+ | ((uint32_t) b[5] << 16)
+ | ((uint32_t) b[6] << 8)
+ | ((uint32_t) b[7] << 0);
+}
+
+static void get_more_input(void)
+{
+ if (state.end_input != 0)
+ return;
+
+ char *recv_buf = (void *) &state.gfx[0];
+
+ while (state.n_gfx < sizeof(state.gfx) / sizeof(state.gfx[0]))
+ {
+ int n_read = sizeof(state.gfx) - state.n_byte;
+ n_read = config.input_fn(&recv_buf[state.n_byte], n_read);
+ if (n_read == 0)
+ return;
+ state.n_byte += n_read;
+
+ while (state.n_gfx < state.n_byte / sizeof(Gfx))
+ {
+ Gfx gfx = state.gfx[state.n_gfx];
+ gfxd_macro_t *m = &state.macro[state.n_gfx];
+
+ swap_words(&gfx);
+
+ int ret = config.ucode->disas_fn(m, gfx.hi, gfx.lo);
+ if (ret != 0 && config.stop_on_invalid != 0)
+ {
+ state.end_input = 1;
+ state.ret = ret;
+ return;
+ }
+
+ state.n_gfx++;
+ }
+ }
+}
+
+static int32_t typed_arg_i(int type, int idx)
+{
+ const gfxd_value_t *v = gfxd_value_by_type(type, idx);
+ if (v != NULL)
+ return v->i;
+ else
+ return -1;
+}
+
+static uint32_t typed_arg_u(int type, int idx)
+{
+ const gfxd_value_t *v = gfxd_value_by_type(type, idx);
+ if (v != NULL)
+ return v->u;
+ else
+ return 0;
+}
+
+
+TLOCAL struct gfxd_config config =
+{
+ .ucode = NULL,
+ .endian = gfxd_endian_big,
+ .wordsize = 4,
+ .arg = NULL,
+
+ .stop_on_invalid = 1,
+ .stop_on_end = 1,
+ .emit_dec_color = 0,
+ .emit_q_macro = 0,
+ .emit_ext_macro = 0,
+
+ .input_buf = NULL,
+ .input_buf_size = 0,
+ .input_fn = &buffer_input_fn,
+
+ .output_buf = NULL,
+ .output_buf_size = 0,
+ .output_fn = &buffer_output_fn,
+
+ .macro_fn = &gfxd_macro_dflt,
+ .arg_fn = &gfxd_arg_dflt,
+
+ .tlut_fn = NULL,
+ .timg_fn = NULL,
+ .cimg_fn = NULL,
+ .zimg_fn = NULL,
+ .dl_fn = NULL,
+ .mtx_fn = NULL,
+ .lookat_fn = NULL,
+ .light_fn = NULL,
+ .seg_fn = NULL,
+ .vtx_fn = NULL,
+ .vp_fn = NULL,
+ .uctext_fn = NULL,
+ .ucdata_fn = NULL,
+ .dram_fn = NULL,
+};
+
+void gfxd_input_buffer(const void *buf, int size)
+{
+ config.input_buf = buf;
+ config.input_buf_size = size;
+ config.input_fn = &buffer_input_fn;
+}
+
+void gfxd_output_buffer(char *buf, int size)
+{
+ config.output_buf = buf;
+ config.output_buf_size = size;
+ config.output_fn = &buffer_output_fn;
+}
+
+void gfxd_input_fd(int fd)
+{
+ config.input_fd = fd;
+ config.input_fn = &fd_input_fn;
+}
+
+void gfxd_output_fd(int fd)
+{
+ config.output_fd = fd;
+ config.output_fn = &fd_output_fn;
+}
+
+void gfxd_input_callback(gfxd_input_fn_t *fn)
+{
+ if (fn != NULL)
+ config.input_fn = fn;
+ else
+ gfxd_input_buffer(NULL, 0);
+}
+
+void gfxd_output_callback(gfxd_output_fn_t *fn)
+{
+ if (fn != NULL)
+ config.output_fn = fn;
+ else
+ gfxd_output_buffer(NULL, 0);
+}
+
+void gfxd_macro_fn(gfxd_macro_fn_t *fn)
+{
+ if (fn != NULL)
+ config.macro_fn = fn;
+ else
+ config.macro_fn = gfxd_macro_dflt;
+}
+
+void gfxd_arg_fn(gfxd_arg_fn_t *fn)
+{
+ if (fn != NULL)
+ config.arg_fn = fn;
+ else
+ config.arg_fn = gfxd_arg_dflt;
+}
+
+int gfxd_write(const void *buf, int count)
+{
+ return config.output_fn(buf, count);
+}
+
+int gfxd_puts(const char *str)
+{
+ return gfxd_write(str, strlen(str));
+}
+
+int gfxd_printf(const char *fmt, ...)
+{
+ char s[256];
+
+ va_list arg;
+ va_start(arg, fmt);
+ int n = vsnprintf(s, sizeof(s), fmt, arg);
+ va_end(arg);
+
+ if (n > sizeof(s) - 1)
+ n = sizeof(s) - 1;
+
+ return gfxd_write(s, n);
+}
+
+int gfxd_print_value(int type, const gfxd_value_t *value)
+{
+ return config.ucode->arg_tbl[type].fn(value);
+}
+
+int gfxd_macro_dflt(void)
+{
+ gfxd_macro_t *m = &state.macro[0];
+ const gfxd_macro_type_t *t = &config.ucode->macro_tbl[m->id];
+
+ const char *name = gfxd_macro_name();
+ if (name == NULL)
+ {
+ if (config.arg != NULL)
+ {
+ gfxd_puts(config.arg);
+ gfxd_puts(" = ");
+ }
+
+ gfxd_puts("(Gfx){");
+ }
+ else
+ {
+ gfxd_puts(name);
+ gfxd_puts("(");
+
+ if (config.arg != NULL)
+ {
+ gfxd_puts(config.arg);
+ if (t->n_arg != 0)
+ gfxd_puts(", ");
+ }
+ }
+
+ for (int i = 0; i < t->n_arg; i++)
+ {
+ if (i != 0)
+ gfxd_puts(", ");
+
+ config.arg_fn(i);
+ }
+
+ if (name == NULL)
+ gfxd_puts("}");
+ else
+ gfxd_puts(")");
+
+ return 0;
+}
+
+int gfxd_arg_callbacks(int arg_num)
+{
+ int id = gfxd_macro_id();
+
+ switch (gfxd_arg_type(arg_num))
+ {
+ case gfxd_Tlut:
+ {
+ if (config.tlut_fn != NULL)
+ {
+ int32_t num;
+ if (id == gfxd_DPLoadTLUT_pal16)
+ num = 16;
+ else if (id == gfxd_DPLoadTLUT_pal256)
+ num = 256;
+ else
+ num = typed_arg_i(gfxd_Num, 0);
+ return config.tlut_fn(
+ typed_arg_u(gfxd_Tlut, 0),
+ typed_arg_i(gfxd_Pal, 0),
+ num);
+ }
+ break;
+ }
+ case gfxd_Timg:
+ {
+ if (config.timg_fn != NULL)
+ {
+ int32_t siz = typed_arg_i(gfxd_Siz, 0);
+ if (siz == -1)
+ siz = G_IM_SIZ_4b;
+ return config.timg_fn(
+ typed_arg_u(gfxd_Timg, 0),
+ typed_arg_i(gfxd_Fmt, 0),
+ siz,
+ typed_arg_i(gfxd_Dim, 0),
+ typed_arg_i(gfxd_Dim, 1),
+ typed_arg_i(gfxd_Pal, 0));
+ }
+ break;
+ }
+ case gfxd_Cimg:
+ {
+ if (config.cimg_fn != NULL)
+ {
+ return config.cimg_fn(
+ typed_arg_u(gfxd_Cimg, 0),
+ typed_arg_i(gfxd_Fmt, 0),
+ typed_arg_i(gfxd_Siz, 0),
+ typed_arg_i(gfxd_Dim, 0));
+ }
+ break;
+ }
+ case gfxd_Zimg:
+ {
+ if (config.zimg_fn != NULL)
+ {
+ return config.zimg_fn(
+ typed_arg_u(gfxd_Zimg, 0));
+ }
+ break;
+ }
+ case gfxd_Dl:
+ {
+ if (config.dl_fn != NULL)
+ {
+ return config.dl_fn(
+ typed_arg_u(gfxd_Dl, 0));
+ }
+ break;
+ }
+ case gfxd_Mtxptr:
+ {
+ if (config.mtx_fn != NULL)
+ {
+ return config.mtx_fn(
+ typed_arg_u(gfxd_Mtxptr, 0));
+ }
+ break;
+ }
+ case gfxd_Lookatptr:
+ {
+ if (config.lookat_fn != NULL)
+ {
+ int32_t num;
+ if (id == gfxd_SPLookAt)
+ num = 2;
+ else
+ num = 1;
+ return config.lookat_fn(
+ typed_arg_u(gfxd_Lookatptr, 0),
+ num);
+ }
+ break;
+ }
+ case gfxd_Lightptr:
+ {
+ if (config.light_fn != NULL)
+ {
+ int32_t num;
+ if (id == gfxd_SPSetLights1)
+ num = 1;
+ else if (id == gfxd_SPSetLights2)
+ num = 2;
+ else if (id == gfxd_SPSetLights3)
+ num = 3;
+ else if (id == gfxd_SPSetLights4)
+ num = 4;
+ else if (id == gfxd_SPSetLights5)
+ num = 5;
+ else if (id == gfxd_SPSetLights6)
+ num = 6;
+ else if (id == gfxd_SPSetLights7)
+ num = 7;
+ else
+ num = 1;
+ return config.light_fn(
+ typed_arg_u(gfxd_Lightptr, 0),
+ num);
+ }
+ break;
+
+ }
+ case gfxd_Segptr:
+ {
+ if (config.seg_fn != NULL)
+ {
+ return config.seg_fn(
+ typed_arg_u(gfxd_Segptr, 0),
+ typed_arg_i(gfxd_Seg, 0));
+ }
+ break;
+ }
+ case gfxd_Vtxptr:
+ {
+ if (config.vtx_fn != NULL)
+ {
+ return config.vtx_fn(
+ typed_arg_u(gfxd_Vtxptr, 0),
+ typed_arg_i(gfxd_Num, 0));
+ }
+ break;
+ }
+ case gfxd_Vpptr:
+ {
+ if (config.vp_fn != NULL)
+ {
+ return config.vp_fn(
+ typed_arg_u(gfxd_Vpptr, 0));
+ }
+ break;
+ }
+ case gfxd_Uctext:
+ {
+ if (config.uctext_fn != NULL)
+ {
+ return config.uctext_fn(
+ typed_arg_u(gfxd_Uctext, 0),
+ 0x1000);
+ }
+ break;
+ }
+ case gfxd_Ucdata:
+ {
+ if (config.ucdata_fn != NULL)
+ {
+ uint32_t size;
+ if (id == gfxd_SPLoadUcodeEx)
+ size = typed_arg_u(gfxd_Size, 0);
+ else
+ size = 0x800;
+ return config.ucdata_fn(
+ typed_arg_u(gfxd_Ucdata, 0),
+ size);
+ }
+ break;
+ }
+ case gfxd_Dram:
+ {
+ if (config.dram_fn != NULL)
+ {
+ return config.dram_fn(
+ typed_arg_u(gfxd_Dram, 0),
+ typed_arg_u(gfxd_Size, 0));
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void gfxd_arg_dflt(int arg_num)
+{
+ if (gfxd_arg_callbacks(arg_num) == 0)
+ {
+ gfxd_arg_t *a = &state.macro[0].arg[arg_num];
+
+ gfxd_print_value(a->type, &a->value);
+ }
+}
+
+void gfxd_tlut_callback(gfxd_tlut_fn_t *fn)
+{
+ config.tlut_fn = fn;
+}
+
+void gfxd_timg_callback(gfxd_timg_fn_t *fn)
+{
+ config.timg_fn = fn;
+}
+
+void gfxd_cimg_callback(gfxd_cimg_fn_t *fn)
+{
+ config.cimg_fn = fn;
+}
+
+void gfxd_zimg_callback(gfxd_zimg_fn_t *fn)
+{
+ config.zimg_fn = fn;
+}
+
+void gfxd_dl_callback(gfxd_dl_fn_t *fn)
+{
+ config.dl_fn = fn;
+}
+
+void gfxd_mtx_callback(gfxd_mtx_fn_t *fn)
+{
+ config.mtx_fn = fn;
+}
+
+void gfxd_lookat_callback(gfxd_lookat_fn_t *fn)
+{
+ config.lookat_fn = fn;
+}
+
+void gfxd_light_callback(gfxd_light_fn_t *fn)
+{
+ config.light_fn = fn;
+}
+
+void gfxd_seg_callback(gfxd_seg_fn_t *fn)
+{
+ config.seg_fn = fn;
+}
+
+void gfxd_vtx_callback(gfxd_vtx_fn_t *fn)
+{
+ config.vtx_fn = fn;
+}
+
+void gfxd_vp_callback(gfxd_vp_fn_t *fn)
+{
+ config.vp_fn = fn;
+}
+
+void gfxd_uctext_callback(gfxd_uctext_fn_t *fn)
+{
+ config.uctext_fn = fn;
+}
+
+void gfxd_ucdata_callback(gfxd_ucdata_fn_t *fn)
+{
+ config.ucdata_fn = fn;
+}
+
+void gfxd_dram_callback(gfxd_dram_fn_t *fn)
+{
+ config.dram_fn = fn;
+}
+
+void gfxd_target(gfxd_ucode_t ucode)
+{
+ config.ucode = ucode;
+}
+
+void gfxd_endian(int endian, int wordsize)
+{
+ config.endian = endian;
+ config.wordsize = wordsize;
+}
+
+void gfxd_dynamic(const char *arg)
+{
+ config.arg = arg;
+}
+
+void gfxd_enable(int cap)
+{
+ switch (cap)
+ {
+ case gfxd_stop_on_invalid:
+ config.stop_on_invalid = 1;
+ break;
+
+ case gfxd_stop_on_end:
+ config.stop_on_end = 1;
+ break;
+
+ case gfxd_emit_dec_color:
+ config.emit_dec_color = 1;
+ break;
+
+ case gfxd_emit_q_macro:
+ config.emit_q_macro = 1;
+ break;
+
+ case gfxd_emit_ext_macro:
+ config.emit_ext_macro = 1;
+ break;
+ }
+}
+
+void gfxd_disable(int cap)
+{
+ switch (cap)
+ {
+ case gfxd_stop_on_invalid:
+ config.stop_on_invalid = 0;
+ return;
+
+ case gfxd_stop_on_end:
+ config.stop_on_end = 0;
+ return;
+
+ case gfxd_emit_dec_color:
+ config.emit_dec_color = 0;
+ break;
+
+ case gfxd_emit_q_macro:
+ config.emit_q_macro = 0;
+ break;
+
+ case gfxd_emit_ext_macro:
+ config.emit_ext_macro = 0;
+ break;
+ }
+}
+
+void gfxd_udata_set(void *ptr)
+{
+ config.udata = ptr;
+}
+
+void *gfxd_udata_get(void)
+{
+ return config.udata;
+}
+
+int gfxd_execute(void)
+{
+ state.macro_offset = 0;
+ state.n_byte = 0;
+ state.n_gfx = 0;
+ state.end_input = 0;
+ state.ret = 0;
+
+ for (;;)
+ {
+ get_more_input();
+ if (state.n_gfx == 0)
+ break;
+
+ gfxd_macro_t *m = &state.macro[0];
+ config.ucode->combine_fn(m, state.n_gfx);
+
+ const gfxd_macro_type_t *t = &config.ucode->macro_tbl[m->id];
+ if (t->ext != 0 && config.emit_ext_macro == 0)
+ {
+ Gfx gfx = state.gfx[0];
+ swap_words(&gfx);
+
+ t = &config.ucode->macro_tbl[gfxd_Invalid];
+ t->disas_fn(m, gfx.hi, gfx.lo);
+ }
+
+ int ret = config.macro_fn();
+ if (ret != 0)
+ {
+ state.ret = ret;
+ break;
+ }
+
+ if (config.stop_on_end != 0
+ && (m->id == gfxd_SPBranchList
+ || m->id == gfxd_SPEndDisplayList))
+ {
+ break;
+ }
+
+ int n_pop = config.ucode->macro_tbl[m->id].n_gfx;
+ int n_rem = state.n_gfx - n_pop;
+ {
+ int n_byte = n_rem * sizeof(gfxd_macro_t);
+ memmove(&state.macro[0], &state.macro[n_pop], n_byte);
+ state.n_gfx = n_rem;
+ }
+ {
+ int n_byte = n_rem * sizeof(Gfx);
+ memmove(&state.gfx[0], &state.gfx[n_pop], n_byte);
+ state.n_byte = n_byte;
+ }
+ state.macro_offset += n_pop * sizeof(Gfx);
+ }
+
+ return state.ret;
+}
+
+int gfxd_macro_offset(void)
+{
+ return state.macro_offset;
+}
+
+int gfxd_macro_packets(void)
+{
+ return config.ucode->macro_tbl[state.macro[0].id].n_gfx;
+}
+
+const void *gfxd_macro_data(void)
+{
+ return state.gfx;
+}
+
+int gfxd_macro_id(void)
+{
+ return state.macro[0].id;
+}
+
+const char *gfxd_macro_name(void)
+{
+ int id = state.macro[0].id;
+ const gfxd_macro_type_t *t = &config.ucode->macro_tbl[id];
+
+ if (t->prefix == NULL && t->suffix == NULL)
+ {
+ return NULL;
+ }
+ else
+ {
+ static TLOCAL char buf[32];
+
+ char *p = buf;
+ if (t->prefix != NULL)
+ {
+ const char *s = t->prefix;
+ while (*s != '\0')
+ *p++ = *s++;
+ }
+ *p++ = 'g';
+ if (config.arg == NULL)
+ *p++ = 's';
+ if (t->suffix != NULL)
+ {
+ const char *s = t->suffix;
+ while (*s != '\0')
+ *p++ = *s++;
+ }
+ *p++ = '\0';
+
+ return buf;
+ }
+}
+
+int gfxd_arg_count(void)
+{
+ return config.ucode->macro_tbl[state.macro[0].id].n_arg;
+}
+
+int gfxd_arg_type(int arg_num)
+{
+ return state.macro[0].arg[arg_num].type;
+}
+
+const char *gfxd_arg_name(int arg_num)
+{
+ return state.macro[0].arg[arg_num].name;
+}
+
+int gfxd_arg_fmt(int arg_num)
+{
+ return config.ucode->arg_tbl[state.macro[0].arg[arg_num].type].fmt;
+}
+
+const gfxd_value_t *gfxd_arg_value(int arg_num)
+{
+ return &state.macro[0].arg[arg_num].value;
+}
+
+const gfxd_value_t *gfxd_value_by_type(int type, int idx)
+{
+ gfxd_macro_t *m = &state.macro[0];
+ const gfxd_macro_type_t *t = &config.ucode->macro_tbl[m->id];
+
+ for (int i = 0; i < t->n_arg; i++)
+ {
+ gfxd_arg_t *a = &m->arg[i];
+ if (a->type == type)
+ {
+ if (idx == 0)
+ return &a->value;
+ else
+ idx--;
+ }
+ }
+
+ return NULL;
+}
+
+int gfxd_arg_valid(int arg_num)
+{
+ return state.macro[0].arg[arg_num].bad == 0;
+}
diff --git a/lib/libgfxd/gfxd.h b/lib/libgfxd/gfxd.h
index ee0fc64..268bbfa 100644
--- a/lib/libgfxd/gfxd.h
+++ b/lib/libgfxd/gfxd.h
@@ -10,6 +10,7 @@ extern "C"
enum
{
gfxd_Word, /* generic word */
+ gfxd_Opcode, /* command opcode (G_*) */
gfxd_Coordi, /* integer coordinate */
gfxd_Coordq, /* fractional (q10.2) coordinate */
gfxd_Pal, /* palette index */
@@ -65,7 +66,8 @@ enum
gfxd_Dlflag, /* display list flag */
gfxd_Cr, /* clip ratio */
gfxd_Num, /* element count */
- gfxd_Fogz, /* fog depth (0 - 1000) */
+ gfxd_Fogz, /* fog factor */
+ gfxd_Fogp, /* fog position (0 - 1000) */
gfxd_Mtxptr, /* matrix pointer */
gfxd_Gm, /* geometry mode */
gfxd_Mwo_matrix, /* matrix moveword offset */
@@ -186,6 +188,7 @@ enum
gfxd_SPCullDisplayList,
gfxd_SPDisplayList,
gfxd_SPEndDisplayList,
+ gfxd_SPFogFactor,
gfxd_SPFogPosition,
gfxd_SPForceMatrix,
gfxd_SPSetGeometryMode,
@@ -225,8 +228,10 @@ enum
gfxd_DisplayList,
gfxd_DPHalf1,
gfxd_DPHalf2,
+ gfxd_DPWord,
gfxd_DPLoadTile,
gfxd_SPGeometryMode,
+ gfxd_SPSetOtherMode,
gfxd_SPSetOtherModeLo,
gfxd_SPSetOtherModeHi,
gfxd_DPSetOtherMode,
@@ -251,12 +256,14 @@ enum
gfxd_stop_on_end,
gfxd_emit_dec_color,
gfxd_emit_q_macro,
+ gfxd_emit_ext_macro,
};
enum
{
gfxd_endian_big,
gfxd_endian_little,
+ gfxd_endian_host,
};
enum
@@ -347,6 +354,8 @@ void gfxd_endian(int endian, int wordsize);
void gfxd_dynamic(const char *arg);
void gfxd_enable(int cap);
void gfxd_disable(int cap);
+void gfxd_udata_set(void *ptr);
+void *gfxd_udata_get(void);
int gfxd_execute(void);
diff --git a/lib/libgfxd/libgfxd.a b/lib/libgfxd/libgfxd.a
deleted file mode 100644
index 1f8c0e2..0000000
--- a/lib/libgfxd/libgfxd.a
+++ /dev/null
Binary files differ
diff --git a/lib/libgfxd/priv.h b/lib/libgfxd/priv.h
new file mode 100644
index 0000000..37cb66b
--- /dev/null
+++ b/lib/libgfxd/priv.h
@@ -0,0 +1,123 @@
+#ifndef GFXD_PRIV_H
+#define GFXD_PRIV_H
+#include "gfxd.h"
+
+#ifdef CONFIG_MT
+# ifdef _MSC_VER
+# define TLOCAL __declspec(thread)
+# else
+# define TLOCAL _Thread_local
+# endif
+#else
+# define TLOCAL
+#endif
+
+#define UCFUNC static inline
+
+#define config gfxd_config__
+
+typedef int gfxd_argfn_t(const gfxd_value_t *v);
+
+typedef struct
+{
+ int fmt;
+ gfxd_argfn_t * fn;
+} gfxd_arg_type_t;
+
+typedef struct
+{
+ int type;
+ const char * name;
+ gfxd_value_t value;
+ int bad;
+} gfxd_arg_t;
+
+typedef struct
+{
+ int id;
+ gfxd_arg_t arg[18];
+} gfxd_macro_t;
+
+typedef int gfxd_disas_fn_t(gfxd_macro_t *macro, uint32_t hi, uint32_t lo);
+typedef int gfxd_combine_fn_t(gfxd_macro_t *macro, int n_macro);
+
+typedef struct
+{
+ const char * prefix;
+ const char * suffix;
+ int opcode;
+ int n_arg;
+ int n_gfx;
+ gfxd_disas_fn_t * disas_fn;
+ gfxd_combine_fn_t * combine_fn;
+ int alias;
+ int ext;
+} gfxd_macro_type_t;
+
+struct gfxd_ucode
+{
+ gfxd_disas_fn_t * disas_fn;
+ gfxd_combine_fn_t * combine_fn;
+ const gfxd_arg_type_t * arg_tbl;
+ const gfxd_macro_type_t * macro_tbl;
+};
+
+struct gfxd_state
+{
+ int macro_offset;
+
+ Gfx gfx[9];
+ int n_byte;
+ int n_gfx;
+ gfxd_macro_t macro[9];
+
+ int end_input;
+ int ret;
+};
+
+struct gfxd_config
+{
+ gfxd_ucode_t ucode;
+ int endian;
+ int wordsize;
+ const char * arg;
+ void * udata;
+
+ int stop_on_invalid;
+ int stop_on_end;
+ int emit_dec_color;
+ int emit_q_macro;
+ int emit_ext_macro;
+
+ const char * input_buf;
+ int input_buf_size;
+ int input_fd;
+ gfxd_input_fn_t * input_fn;
+
+ char * output_buf;
+ int output_buf_size;
+ int output_fd;
+ gfxd_output_fn_t * output_fn;
+
+ gfxd_macro_fn_t * macro_fn;
+ gfxd_arg_fn_t * arg_fn;
+
+ gfxd_tlut_fn_t * tlut_fn;
+ gfxd_timg_fn_t * timg_fn;
+ gfxd_cimg_fn_t * cimg_fn;
+ gfxd_zimg_fn_t * zimg_fn;
+ gfxd_dl_fn_t * dl_fn;
+ gfxd_mtx_fn_t * mtx_fn;
+ gfxd_lookat_fn_t * lookat_fn;
+ gfxd_light_fn_t * light_fn;
+ gfxd_seg_fn_t * seg_fn;
+ gfxd_vtx_fn_t * vtx_fn;
+ gfxd_vp_fn_t * vp_fn;
+ gfxd_uctext_fn_t * uctext_fn;
+ gfxd_ucdata_fn_t * ucdata_fn;
+ gfxd_dram_fn_t * dram_fn;
+};
+
+extern TLOCAL struct gfxd_config gfxd_config__;
+
+#endif
diff --git a/lib/libgfxd/uc.c b/lib/libgfxd/uc.c
new file mode 100644
index 0000000..7efb091
--- /dev/null
+++ b/lib/libgfxd/uc.c
@@ -0,0 +1,54 @@
+#include <inttypes.h>
+#include <string.h>
+#include <stdint.h>
+#include "gbi.h"
+#include "gfxd.h"
+#include "priv.h"
+
+#include "uc_argfn.c"
+#include "uc_argtbl.c"
+#include "uc_macrofn.c"
+#include "uc_macrotbl.c"
+
+UCFUNC int disas(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int opcode = (hi >> 24) & 0xFF;
+
+ for (int i = 0; i < sizeof(macro_tbl) / sizeof(macro_tbl[0]); i++)
+ {
+ const gfxd_macro_type_t *t = &macro_tbl[i];
+ if (t->disas_fn != NULL && t->opcode == opcode)
+ return t->disas_fn(m, hi, lo);
+ }
+
+ return d_Invalid(m, hi, lo);
+}
+
+UCFUNC int combine(gfxd_macro_t *m, int num)
+{
+ int opcode = macro_tbl[m->id].opcode;
+
+ for (int i = 0; i < sizeof(macro_tbl) / sizeof(macro_tbl[0]); i++)
+ {
+ const gfxd_macro_type_t *t = &macro_tbl[i];
+ if (t->combine_fn != NULL
+ && t->opcode == opcode
+ && (t->ext == 0 || config.emit_ext_macro != 0))
+ {
+ if (t->combine_fn(m, num) == 0)
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static const struct gfxd_ucode uc =
+{
+ .disas_fn = disas,
+ .combine_fn = combine,
+ .arg_tbl = arg_tbl,
+ .macro_tbl = macro_tbl,
+};
+
+const gfxd_ucode_t uc_name = &uc;
diff --git a/lib/libgfxd/uc_argfn.c b/lib/libgfxd/uc_argfn.c
new file mode 100644
index 0000000..f65feb6
--- /dev/null
+++ b/lib/libgfxd/uc_argfn.c
@@ -0,0 +1,1814 @@
+#define MDMASK(md) ((((uint32_t)1 << G_MDSIZ_##md) - 1) << G_MDSFT_##md)
+#define MDMASK_RM_C1 ((uint32_t)0xCCCC0000)
+#define MDMASK_RM_C2 ((uint32_t)0x33330000)
+#define MDMASK_RM_LO ((uint32_t)0x0000FFF8)
+
+UCFUNC int argfn_i(const gfxd_value_t *v)
+{
+ return gfxd_printf("%" PRIi32, v->i);
+}
+
+UCFUNC int argfn_u(const gfxd_value_t *v)
+{
+ return gfxd_printf("%" PRIu32, v->u);
+}
+
+UCFUNC int argfn_x8(const gfxd_value_t *v)
+{
+ return gfxd_printf("0x%02" PRIX32, v->u);
+}
+
+UCFUNC int argfn_x16(const gfxd_value_t *v)
+{
+ return gfxd_printf("0x%04" PRIX32, v->u);
+}
+
+UCFUNC int argfn_x32(const gfxd_value_t *v)
+{
+ return gfxd_printf("0x%08" PRIX32, v->u);
+}
+
+UCFUNC int argfn_color(const gfxd_value_t *v)
+{
+ if (config.emit_dec_color)
+ return gfxd_printf("%" PRIu32, v->u);
+ else
+ return gfxd_printf("0x%02" PRIX32, v->u);
+}
+
+UCFUNC int argfn_qu08(const gfxd_value_t *v)
+{
+ if (v->u == 0)
+ return gfxd_puts("0");
+ else if (config.emit_q_macro)
+ return gfxd_printf("qu08(%.16g)", v->u / 256.f);
+ else
+ return gfxd_printf("0x%02" PRIX32, v->u);
+}
+
+UCFUNC int argfn_qu016(const gfxd_value_t *v)
+{
+ if (v->u == 0)
+ return gfxd_puts("0");
+ else if (config.emit_q_macro)
+ return gfxd_printf("qu016(%.16g)", v->u / 65536.f);
+ else
+ return gfxd_printf("0x%04" PRIX32, v->u);
+}
+
+UCFUNC int argfn_qs48(const gfxd_value_t *v)
+{
+ if (v->i == 0)
+ return gfxd_puts("0");
+ else if (config.emit_q_macro)
+ return gfxd_printf("qs48(%.16g)", v->i / 256.f);
+ else
+ {
+ if (v->i < 0)
+ return gfxd_printf("-0x%04" PRIX32, (uint32_t)-v->i);
+ else
+ return gfxd_printf("0x%04" PRIX32, (uint32_t)v->i);
+ }
+}
+
+UCFUNC int argfn_qs510(const gfxd_value_t *v)
+{
+ if (v->i == 0)
+ return gfxd_puts("0");
+ else if (config.emit_q_macro)
+ return gfxd_printf("qs510(%.16g)", v->i / 1024.f);
+ else
+ {
+ if (v->i < 0)
+ return gfxd_printf("-0x%04" PRIX32, (uint32_t)-v->i);
+ else
+ return gfxd_printf("0x%04" PRIX32, (uint32_t)v->i);
+ }
+}
+
+UCFUNC int argfn_qu102(const gfxd_value_t *v)
+{
+ if (v->u == 0)
+ return gfxd_puts("0");
+ else if (config.emit_q_macro)
+ return gfxd_printf("qu102(%.16g)", v->u / 4.f);
+ else
+ return gfxd_printf("0x%04" PRIX32, v->u);
+}
+
+UCFUNC int argfn_qs105(const gfxd_value_t *v)
+{
+ if (v->i == 0)
+ return gfxd_puts("0");
+ else if (config.emit_q_macro)
+ return gfxd_printf("qs105(%.16g)", v->i / 32.f);
+ else
+ {
+ if (v->i < 0)
+ return gfxd_printf("-0x%04" PRIX32, (uint32_t)-v->i);
+ else
+ return gfxd_printf("0x%04" PRIX32, (uint32_t)v->i);
+ }
+}
+
+UCFUNC int argfn_qs1616(const gfxd_value_t *v)
+{
+ if (v->i == 0)
+ return gfxd_puts("0");
+ else if (config.emit_q_macro)
+ return gfxd_printf("qs1616(%.16g)", v->i / 65536.f);
+ else
+ {
+ if (v->i < 0)
+ return gfxd_printf("-0x%08" PRIX32, (uint32_t)-v->i);
+ else
+ return gfxd_printf("0x%08" PRIX32, (uint32_t)v->i);
+ }
+}
+
+UCFUNC int argfn_opc(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_SPNOOP:
+ return gfxd_puts("G_SPNOOP");
+ case G_MTX:
+ return gfxd_puts("G_MTX");
+ case G_MOVEMEM:
+ return gfxd_puts("G_MOVEMEM");
+ case G_VTX:
+ return gfxd_puts("G_VTX");
+ case G_DL:
+ return gfxd_puts("G_DL");
+ case G_RDPHALF_2:
+ return gfxd_puts("G_RDPHALF_2");
+ case G_RDPHALF_1:
+ return gfxd_puts("G_RDPHALF_1");
+#if defined(F3D_BETA) && (defined(F3D_GBI) || defined(F3DEX_GBI))
+ case G_PERSPNORM:
+ return gfxd_puts("G_PERSPNORM");
+#endif
+ case G_LINE3D:
+ return gfxd_puts("G_LINE3D");
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ case G_CLEARGEOMETRYMODE:
+ return gfxd_puts("G_CLEARGEOMETRYMODE");
+ case G_SETGEOMETRYMODE:
+ return gfxd_puts("G_SETGEOMETRYMODE");
+#endif
+ case G_ENDDL:
+ return gfxd_puts("G_ENDDL");
+ case G_SETOTHERMODE_L:
+ return gfxd_puts("G_SETOTHERMODE_L");
+ case G_SETOTHERMODE_H:
+ return gfxd_puts("G_SETOTHERMODE_H");
+ case G_TEXTURE:
+ return gfxd_puts("G_TEXTURE");
+ case G_MOVEWORD:
+ return gfxd_puts("G_MOVEWORD");
+ case G_POPMTX:
+ return gfxd_puts("G_POPMTX");
+ case G_CULLDL:
+ return gfxd_puts("G_CULLDL");
+ case G_TRI1:
+ return gfxd_puts("G_TRI1");
+ case G_NOOP:
+ return gfxd_puts("G_NOOP");
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+ case G_LOAD_UCODE:
+ return gfxd_puts("G_LOAD_UCODE");
+ case G_BRANCH_Z:
+ return gfxd_puts("G_BRANCH_Z");
+ case G_TRI2:
+ return gfxd_puts("G_TRI2");
+# if !(defined(F3D_BETA) && defined(F3DEX_GBI))
+ case G_MODIFYVTX:
+ return gfxd_puts("G_MODIFYVTX");
+# endif
+#endif
+#if defined(F3DEX_GBI_2)
+ case G_QUAD:
+ return gfxd_puts("G_QUAD");
+ case G_SPECIAL_3:
+ return gfxd_puts("G_SPECIAL_3");
+ case G_SPECIAL_2:
+ return gfxd_puts("G_SPECIAL_2");
+ case G_SPECIAL_1:
+ return gfxd_puts("G_SPECIAL_1");
+ case G_DMA_IO:
+ return gfxd_puts("G_DMA_IO");
+ case G_GEOMETRYMODE:
+ return gfxd_puts("G_GEOMETRYMODE");
+#endif
+ case G_TEXRECT:
+ return gfxd_puts("G_TEXRECT");
+ case G_TEXRECTFLIP:
+ return gfxd_puts("G_TEXRECTFLIP");
+ case G_RDPLOADSYNC:
+ return gfxd_puts("G_RDPLOADSYNC");
+ case G_RDPPIPESYNC:
+ return gfxd_puts("G_RDPPIPESYNC");
+ case G_RDPTILESYNC:
+ return gfxd_puts("G_RDPTILESYNC");
+ case G_RDPFULLSYNC:
+ return gfxd_puts("G_RDPFULLSYNC");
+ case G_SETKEYGB:
+ return gfxd_puts("G_SETKEYGB");
+ case G_SETKEYR:
+ return gfxd_puts("G_SETKEYR");
+ case G_SETCONVERT:
+ return gfxd_puts("G_SETCONVERT");
+ case G_SETSCISSOR:
+ return gfxd_puts("G_SETSCISSOR");
+ case G_SETPRIMDEPTH:
+ return gfxd_puts("G_SETPRIMDEPTH");
+ case G_RDPSETOTHERMODE:
+ return gfxd_puts("G_RDPSETOTHERMODE");
+ case G_LOADTLUT:
+ return gfxd_puts("G_LOADTLUT");
+ case G_SETTILESIZE:
+ return gfxd_puts("G_SETTILESIZE");
+ case G_LOADBLOCK:
+ return gfxd_puts("G_LOADBLOCK");
+ case G_LOADTILE:
+ return gfxd_puts("G_LOADTILE");
+ case G_SETTILE:
+ return gfxd_puts("G_SETTILE");
+ case G_FILLRECT:
+ return gfxd_puts("G_FILLRECT");
+ case G_SETFILLCOLOR:
+ return gfxd_puts("G_SETFILLCOLOR");
+ case G_SETFOGCOLOR:
+ return gfxd_puts("G_SETFOGCOLOR");
+ case G_SETBLENDCOLOR:
+ return gfxd_puts("G_SETBLENDCOLOR");
+ case G_SETPRIMCOLOR:
+ return gfxd_puts("G_SETPRIMCOLOR");
+ case G_SETENVCOLOR:
+ return gfxd_puts("G_SETENVCOLOR");
+ case G_SETCOMBINE:
+ return gfxd_puts("G_SETCOMBINE");
+ case G_SETTIMG:
+ return gfxd_puts("G_SETTIMG");
+ case G_SETZIMG:
+ return gfxd_puts("G_SETZIMG");
+ case G_SETCIMG:
+ return gfxd_puts("G_SETCIMG");
+ default:
+ return gfxd_printf("0x%02" PRIX32, (uint32_t)v->i);
+ }
+}
+
+UCFUNC int argfn_fmt(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_IM_FMT_RGBA:
+ return gfxd_puts("G_IM_FMT_RGBA");
+ case G_IM_FMT_YUV:
+ return gfxd_puts("G_IM_FMT_YUV");
+ case G_IM_FMT_CI:
+ return gfxd_puts("G_IM_FMT_CI");
+ case G_IM_FMT_IA:
+ return gfxd_puts("G_IM_FMT_IA");
+ case G_IM_FMT_I:
+ return gfxd_puts("G_IM_FMT_I");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int argfn_siz(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_IM_SIZ_4b:
+ return gfxd_puts("G_IM_SIZ_4b");
+ case G_IM_SIZ_8b:
+ return gfxd_puts("G_IM_SIZ_8b");
+ case G_IM_SIZ_16b:
+ return gfxd_puts("G_IM_SIZ_16b");
+ case G_IM_SIZ_32b:
+ return gfxd_puts("G_IM_SIZ_32b");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int argfn_cm(const gfxd_value_t *v)
+{
+ int n = 0;
+ if (v->u & G_TX_MIRROR)
+ n += gfxd_puts("G_TX_MIRROR");
+ else
+ n += gfxd_puts("G_TX_NOMIRROR");
+ if (v->u & G_TX_CLAMP)
+ n += gfxd_puts(" | G_TX_CLAMP");
+ else
+ n += gfxd_puts(" | G_TX_WRAP");
+ return n;
+}
+
+UCFUNC int argfn_tm(const gfxd_value_t *v)
+{
+ if (v->i == 0)
+ return gfxd_puts("G_TX_NOMASK");
+ else
+ return gfxd_printf("%" PRIi32, v->i);
+}
+
+UCFUNC int argfn_ts(const gfxd_value_t *v)
+{
+ if (v->i == 0)
+ return gfxd_puts("G_TX_NOLOD");
+ else
+ return gfxd_printf("%" PRIi32, v->i);
+}
+
+UCFUNC int argfn_switch(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_ON:
+ return gfxd_puts("G_ON");
+ case G_OFF:
+ return gfxd_puts("G_OFF");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int argfn_tile(const gfxd_value_t *v)
+{
+ if (v->i == G_TX_LOADTILE)
+ return gfxd_puts("G_TX_LOADTILE");
+ else if (v->i == G_TX_RENDERTILE)
+ return gfxd_puts("G_TX_RENDERTILE");
+ else
+ return gfxd_printf("%" PRIi32, v->i);
+}
+
+UCFUNC int argfn_gm(const gfxd_value_t *v)
+{
+ int n = 0;
+ uint32_t arg = v->u;
+ if (arg & G_ZBUFFER)
+ n += gfxd_puts("G_ZBUFFER");
+ if (arg & G_TEXTURE_ENABLE)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_TEXTURE_ENABLE");
+ }
+ if (arg & G_SHADE)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_SHADE");
+ }
+ if ((arg & G_CULL_BOTH) == G_CULL_BOTH)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_CULL_BOTH");
+ }
+ else
+ {
+ if (arg & G_CULL_FRONT)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_CULL_FRONT");
+ }
+ if (arg & G_CULL_BACK)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_CULL_BACK");
+ }
+ }
+ if (arg & G_FOG)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_FOG");
+ }
+ if (arg & G_LIGHTING)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_LIGHTING");
+ }
+ if (arg & G_TEXTURE_GEN)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_TEXTURE_GEN");
+ }
+ if (arg & G_TEXTURE_GEN_LINEAR)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_TEXTURE_GEN_LINEAR");
+ }
+ if (arg & G_LOD)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_LOD");
+ }
+ if (arg & G_SHADING_SMOOTH)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_SHADING_SMOOTH");
+ }
+ if (arg & G_CLIPPING)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("G_CLIPPING");
+ }
+ arg = arg & ~(G_ZBUFFER | G_TEXTURE_ENABLE | G_SHADE | G_CULL_BOTH |
+ G_FOG | G_LIGHTING | G_TEXTURE_GEN |
+ G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH |
+ G_CLIPPING);
+ if (arg)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_printf("0x%08" PRIX32, arg);
+ }
+ return n;
+}
+
+UCFUNC int argfn_sftlo(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_MDSFT_ALPHACOMPARE:
+ return gfxd_puts("G_MDSFT_ALPHACOMPARE");
+ case G_MDSFT_ZSRCSEL:
+ return gfxd_puts("G_MDSFT_ZSRCSEL");
+ case G_MDSFT_RENDERMODE:
+ return gfxd_puts("G_MDSFT_RENDERMODE");
+ case G_MDSFT_BLENDER:
+ return gfxd_puts("G_MDSFT_BLENDER");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int rm_mode_str(uint32_t arg)
+{
+ int n = 0;
+ if (arg & AA_EN)
+ n += gfxd_puts("AA_EN");
+ if (arg & Z_CMP)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("Z_CMP");
+ }
+ if (arg & Z_UPD)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("Z_UPD");
+ }
+ if (arg & IM_RD)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("IM_RD");
+ }
+ if (arg & CLR_ON_CVG)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += gfxd_puts("CLR_ON_CVG");
+ }
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ int cvg = arg & 0x00000300;
+ switch (cvg)
+ {
+ case CVG_DST_CLAMP:
+ n += gfxd_puts("CVG_DST_CLAMP");
+ break;
+ case CVG_DST_WRAP:
+ n += gfxd_puts("CVG_DST_WRAP");
+ break;
+ case CVG_DST_FULL:
+ n += gfxd_puts("CVG_DST_FULL");
+ break;
+ case CVG_DST_SAVE:
+ n += gfxd_puts("CVG_DST_SAVE");
+ break;
+ }
+ int zmode = arg & 0x00000C00;
+ switch (zmode)
+ {
+ case ZMODE_OPA:
+ n += gfxd_puts(" | ZMODE_OPA");
+ break;
+ case ZMODE_INTER:
+ n += gfxd_puts(" | ZMODE_INTER");
+ break;
+ case ZMODE_XLU:
+ n += gfxd_puts(" | ZMODE_XLU");
+ break;
+ case ZMODE_DEC:
+ n += gfxd_puts(" | ZMODE_DEC");
+ break;
+ }
+ if (arg & CVG_X_ALPHA)
+ n += gfxd_puts(" | CVG_X_ALPHA");
+ if (arg & ALPHA_CVG_SEL)
+ n += gfxd_puts(" | ALPHA_CVG_SEL");
+ if (arg & FORCE_BL)
+ n += gfxd_puts(" | FORCE_BL");
+ return n;
+}
+
+UCFUNC int rm_cbl_str(uint32_t arg, int c)
+{
+ int n = 0;
+ if (c == 2)
+ arg <<= 2;
+ int bp = (arg >> 30) & 0b11;
+ switch (bp)
+ {
+ case G_BL_CLR_IN:
+ n += gfxd_printf("GBL_c%i(G_BL_CLR_IN", c);
+ break;
+ case G_BL_CLR_MEM:
+ n += gfxd_printf("GBL_c%i(G_BL_CLR_MEM", c);
+ break;
+ case G_BL_CLR_BL:
+ n += gfxd_printf("GBL_c%i(G_BL_CLR_BL", c);
+ break;
+ case G_BL_CLR_FOG:
+ n += gfxd_printf("GBL_c%i(G_BL_CLR_FOG", c);
+ break;
+ }
+ int ba = (arg >> 26) & 0b11;
+ switch (ba)
+ {
+ case G_BL_A_IN:
+ n += gfxd_puts(", G_BL_A_IN");
+ break;
+ case G_BL_A_FOG:
+ n += gfxd_puts(", G_BL_A_FOG");
+ break;
+ case G_BL_A_SHADE:
+ n += gfxd_puts(", G_BL_A_SHADE");
+ break;
+ case G_BL_0:
+ n += gfxd_puts(", G_BL_0");
+ break;
+ }
+ int bm = (arg >> 22) & 0b11;
+ switch (bm)
+ {
+ case G_BL_CLR_IN:
+ n += gfxd_puts(", G_BL_CLR_IN");
+ break;
+ case G_BL_CLR_MEM:
+ n += gfxd_puts(", G_BL_CLR_MEM");
+ break;
+ case G_BL_CLR_BL:
+ n += gfxd_puts(", G_BL_CLR_BL");
+ break;
+ case G_BL_CLR_FOG:
+ n += gfxd_puts(", G_BL_CLR_FOG");
+ break;
+ }
+ int bb = (arg >> 18) & 0b11;
+ switch (bb)
+ {
+ case G_BL_1MA:
+ n += gfxd_puts(", G_BL_1MA)");
+ break;
+ case G_BL_A_MEM:
+ n += gfxd_puts(", G_BL_A_MEM)");
+ break;
+ case G_BL_1:
+ n += gfxd_puts(", G_BL_1)");
+ break;
+ case G_BL_0:
+ n += gfxd_puts(", G_BL_0)");
+ break;
+ }
+ return n;
+}
+
+struct rm_preset
+{
+ uint32_t rm;
+ const char * name;
+};
+
+static const struct rm_preset rm_presets[] =
+{
+ {G_RM_OPA_SURF, "G_RM_OPA_SURF"},
+ {G_RM_OPA_SURF2, "G_RM_OPA_SURF2"},
+ {G_RM_AA_OPA_SURF, "G_RM_AA_OPA_SURF"},
+ {G_RM_AA_OPA_SURF2, "G_RM_AA_OPA_SURF2"},
+ {G_RM_RA_OPA_SURF, "G_RM_RA_OPA_SURF"},
+ {G_RM_RA_OPA_SURF2, "G_RM_RA_OPA_SURF2"},
+ {G_RM_ZB_OPA_SURF, "G_RM_ZB_OPA_SURF"},
+ {G_RM_ZB_OPA_SURF2, "G_RM_ZB_OPA_SURF2"},
+ {G_RM_AA_ZB_OPA_SURF, "G_RM_AA_ZB_OPA_SURF"},
+ {G_RM_AA_ZB_OPA_SURF2, "G_RM_AA_ZB_OPA_SURF2"},
+ {G_RM_RA_ZB_OPA_SURF, "G_RM_RA_ZB_OPA_SURF"},
+ {G_RM_RA_ZB_OPA_SURF2, "G_RM_RA_ZB_OPA_SURF2"},
+ {G_RM_XLU_SURF, "G_RM_XLU_SURF"},
+ {G_RM_XLU_SURF2, "G_RM_XLU_SURF2"},
+ {G_RM_AA_XLU_SURF, "G_RM_AA_XLU_SURF"},
+ {G_RM_AA_XLU_SURF2, "G_RM_AA_XLU_SURF2"},
+ {G_RM_ZB_XLU_SURF, "G_RM_ZB_XLU_SURF"},
+ {G_RM_ZB_XLU_SURF2, "G_RM_ZB_XLU_SURF2"},
+ {G_RM_AA_ZB_XLU_SURF, "G_RM_AA_ZB_XLU_SURF"},
+ {G_RM_AA_ZB_XLU_SURF2, "G_RM_AA_ZB_XLU_SURF2"},
+ {G_RM_ZB_OPA_DECAL, "G_RM_ZB_OPA_DECAL"},
+ {G_RM_ZB_OPA_DECAL2, "G_RM_ZB_OPA_DECAL2"},
+ {G_RM_AA_ZB_OPA_DECAL, "G_RM_AA_ZB_OPA_DECAL"},
+ {G_RM_AA_ZB_OPA_DECAL2, "G_RM_AA_ZB_OPA_DECAL2"},
+ {G_RM_RA_ZB_OPA_DECAL, "G_RM_RA_ZB_OPA_DECAL"},
+ {G_RM_RA_ZB_OPA_DECAL2, "G_RM_RA_ZB_OPA_DECAL2"},
+ {G_RM_ZB_XLU_DECAL, "G_RM_ZB_XLU_DECAL"},
+ {G_RM_ZB_XLU_DECAL2, "G_RM_ZB_XLU_DECAL2"},
+ {G_RM_AA_ZB_XLU_DECAL, "G_RM_AA_ZB_XLU_DECAL"},
+ {G_RM_AA_ZB_XLU_DECAL2, "G_RM_AA_ZB_XLU_DECAL2"},
+ {G_RM_AA_ZB_OPA_INTER, "G_RM_AA_ZB_OPA_INTER"},
+ {G_RM_AA_ZB_OPA_INTER2, "G_RM_AA_ZB_OPA_INTER2"},
+ {G_RM_RA_ZB_OPA_INTER, "G_RM_RA_ZB_OPA_INTER"},
+ {G_RM_RA_ZB_OPA_INTER2, "G_RM_RA_ZB_OPA_INTER2"},
+ {G_RM_AA_ZB_XLU_INTER, "G_RM_AA_ZB_XLU_INTER"},
+ {G_RM_AA_ZB_XLU_INTER2, "G_RM_AA_ZB_XLU_INTER2"},
+ {G_RM_AA_XLU_LINE, "G_RM_AA_XLU_LINE"},
+ {G_RM_AA_XLU_LINE2, "G_RM_AA_XLU_LINE2"},
+ {G_RM_AA_ZB_XLU_LINE, "G_RM_AA_ZB_XLU_LINE"},
+ {G_RM_AA_ZB_XLU_LINE2, "G_RM_AA_ZB_XLU_LINE2"},
+ {G_RM_AA_DEC_LINE, "G_RM_AA_DEC_LINE"},
+ {G_RM_AA_DEC_LINE2, "G_RM_AA_DEC_LINE2"},
+ {G_RM_AA_ZB_DEC_LINE, "G_RM_AA_ZB_DEC_LINE"},
+ {G_RM_AA_ZB_DEC_LINE2, "G_RM_AA_ZB_DEC_LINE2"},
+ {G_RM_TEX_EDGE, "G_RM_TEX_EDGE"},
+ {G_RM_TEX_EDGE2, "G_RM_TEX_EDGE2"},
+ {G_RM_AA_TEX_EDGE, "G_RM_AA_TEX_EDGE"},
+ {G_RM_AA_TEX_EDGE2, "G_RM_AA_TEX_EDGE2"},
+ {G_RM_AA_ZB_TEX_EDGE, "G_RM_AA_ZB_TEX_EDGE"},
+ {G_RM_AA_ZB_TEX_EDGE2, "G_RM_AA_ZB_TEX_EDGE2"},
+ {G_RM_AA_ZB_TEX_INTER, "G_RM_AA_ZB_TEX_INTER"},
+ {G_RM_AA_ZB_TEX_INTER2, "G_RM_AA_ZB_TEX_INTER2"},
+ {G_RM_AA_SUB_SURF, "G_RM_AA_SUB_SURF"},
+ {G_RM_AA_SUB_SURF2, "G_RM_AA_SUB_SURF2"},
+ {G_RM_AA_ZB_SUB_SURF, "G_RM_AA_ZB_SUB_SURF"},
+ {G_RM_AA_ZB_SUB_SURF2, "G_RM_AA_ZB_SUB_SURF2"},
+ {G_RM_PCL_SURF, "G_RM_PCL_SURF"},
+ {G_RM_PCL_SURF2, "G_RM_PCL_SURF2"},
+ {G_RM_AA_PCL_SURF, "G_RM_AA_PCL_SURF"},
+ {G_RM_AA_PCL_SURF2, "G_RM_AA_PCL_SURF2"},
+ {G_RM_ZB_PCL_SURF, "G_RM_ZB_PCL_SURF"},
+ {G_RM_ZB_PCL_SURF2, "G_RM_ZB_PCL_SURF2"},
+ {G_RM_AA_ZB_PCL_SURF, "G_RM_AA_ZB_PCL_SURF"},
+ {G_RM_AA_ZB_PCL_SURF2, "G_RM_AA_ZB_PCL_SURF2"},
+ {G_RM_AA_OPA_TERR, "G_RM_AA_OPA_TERR"},
+ {G_RM_AA_OPA_TERR2, "G_RM_AA_OPA_TERR2"},
+ {G_RM_AA_ZB_OPA_TERR, "G_RM_AA_ZB_OPA_TERR"},
+ {G_RM_AA_ZB_OPA_TERR2, "G_RM_AA_ZB_OPA_TERR2"},
+ {G_RM_AA_TEX_TERR, "G_RM_AA_TEX_TERR"},
+ {G_RM_AA_TEX_TERR2, "G_RM_AA_TEX_TERR2"},
+ {G_RM_AA_ZB_TEX_TERR, "G_RM_AA_ZB_TEX_TERR"},
+ {G_RM_AA_ZB_TEX_TERR2, "G_RM_AA_ZB_TEX_TERR2"},
+ {G_RM_AA_SUB_TERR, "G_RM_AA_SUB_TERR"},
+ {G_RM_AA_SUB_TERR2, "G_RM_AA_SUB_TERR2"},
+ {G_RM_AA_ZB_SUB_TERR, "G_RM_AA_ZB_SUB_TERR"},
+ {G_RM_AA_ZB_SUB_TERR2, "G_RM_AA_ZB_SUB_TERR2"},
+ {G_RM_CLD_SURF, "G_RM_CLD_SURF"},
+ {G_RM_CLD_SURF2, "G_RM_CLD_SURF2"},
+ {G_RM_ZB_CLD_SURF, "G_RM_ZB_CLD_SURF"},
+ {G_RM_ZB_CLD_SURF2, "G_RM_ZB_CLD_SURF2"},
+ {G_RM_ZB_OVL_SURF, "G_RM_ZB_OVL_SURF"},
+ {G_RM_ZB_OVL_SURF2, "G_RM_ZB_OVL_SURF2"},
+ {G_RM_ADD, "G_RM_ADD"},
+ {G_RM_ADD2, "G_RM_ADD2"},
+ {G_RM_VISCVG, "G_RM_VISCVG"},
+ {G_RM_VISCVG2, "G_RM_VISCVG2"},
+ {G_RM_OPA_CI, "G_RM_OPA_CI"},
+ {G_RM_OPA_CI2, "G_RM_OPA_CI2"},
+ {G_RM_RA_SPRITE, "G_RM_RA_SPRITE"},
+ {G_RM_RA_SPRITE2, "G_RM_RA_SPRITE2"},
+};
+
+static const struct rm_preset bl1_presets[] =
+{
+ {G_RM_FOG_SHADE_A, "G_RM_FOG_SHADE_A"},
+ {G_RM_FOG_PRIM_A, "G_RM_FOG_PRIM_A"},
+ {G_RM_PASS, "G_RM_PASS"},
+ {G_RM_NOOP, "G_RM_NOOP"},
+};
+
+static const struct rm_preset bl2_presets[] =
+{
+ {G_RM_NOOP2, "G_RM_NOOP2"},
+};
+
+UCFUNC int othermodelo_str(uint32_t arg, uint32_t which)
+{
+ int n = 0;
+ uint32_t rm_c1_mask = MDMASK_RM_C1;
+ uint32_t rm_c2_mask = MDMASK_RM_C2;
+ uint32_t rm_mode_lo = MDMASK_RM_LO;
+ uint32_t rm_mask = rm_c1_mask | rm_c2_mask | rm_mode_lo;
+ const struct rm_preset *pre_c1 = NULL;
+ const struct rm_preset *pre_c2 = NULL;
+ int n_rm_presets = sizeof(rm_presets) / sizeof(*rm_presets);
+ for (int i = 0; i < n_rm_presets; i++)
+ {
+ const struct rm_preset *pre = &rm_presets[i];
+ uint32_t pre_extra = pre->rm & ~rm_mask;
+ uint32_t rm_c1 = arg & (rm_c1_mask | rm_mode_lo | pre_extra);
+ if (!pre_c1 && rm_c1 == pre->rm)
+ pre_c1 = pre;
+ uint32_t rm_c2 = arg & (rm_c2_mask | rm_mode_lo | pre_extra);
+ if (!pre_c2 && rm_c2 == pre->rm)
+ pre_c2 = pre;
+ }
+ if (!pre_c1 || !pre_c2 || pre_c1 + 1 != pre_c2)
+ {
+ int n_bl1_presets = sizeof(bl1_presets) / sizeof(*bl1_presets);
+ for (int i = 0; i < n_bl1_presets; i++)
+ {
+ const struct rm_preset *pre = &bl1_presets[i];
+ uint32_t pre_extra = pre->rm & ~rm_mask;
+ uint32_t rm_c1 = arg & (rm_c1_mask | pre_extra);
+ if (rm_c1 == pre->rm)
+ {
+ pre_c1 = pre;
+ break;
+ }
+ }
+ int n_bl2_presets = sizeof(bl2_presets) / sizeof(*bl2_presets);
+ for (int i = 0; i < n_bl2_presets; i++)
+ {
+ const struct rm_preset *pre = &bl2_presets[i];
+ uint32_t pre_extra = pre->rm & ~rm_mask;
+ uint32_t rm_c2 = arg & (rm_c2_mask | pre_extra);
+ if (rm_c2 == pre->rm)
+ {
+ pre_c2 = pre;
+ break;
+ }
+ }
+ }
+ uint32_t pre_rm = 0;
+ if (pre_c1)
+ pre_rm |= pre_c1->rm;
+ if (pre_c2)
+ pre_rm |= pre_c2->rm;
+ uint32_t ac_mask = MDMASK(ALPHACOMPARE);
+ if (((arg & ~pre_rm) | which) & ac_mask)
+ {
+ uint32_t ac = arg & ac_mask;
+ switch (ac)
+ {
+ case G_AC_NONE:
+ n += gfxd_puts("G_AC_NONE");
+ break;
+ case G_AC_THRESHOLD:
+ n += gfxd_puts("G_AC_THRESHOLD");
+ break;
+ case G_AC_DITHER:
+ n += gfxd_puts("G_AC_DITHER");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, ac);
+ break;
+ }
+ }
+ uint32_t zs_mask = MDMASK(ZSRCSEL);
+ if (((arg & ~pre_rm) | which) & zs_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t zs = arg & zs_mask;
+ switch (zs)
+ {
+ case G_ZS_PIXEL:
+ n += gfxd_puts("G_ZS_PIXEL");
+ break;
+ case G_ZS_PRIM:
+ n += gfxd_puts("G_ZS_PRIM");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, zs);
+ break;
+ }
+ }
+ uint32_t rm = arg & (rm_mask | pre_rm);
+ if (((arg & ~pre_rm) | which) & rm_mode_lo)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ n += rm_mode_str(rm);
+ }
+ int c = 0;
+ if (which & rm_c1_mask)
+ c |= 1;
+ if (which & rm_c2_mask)
+ c |= 2;
+ if (c & 1 || (c == 0 && arg & rm_c1_mask))
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ if (pre_c1)
+ n += gfxd_printf("%s", pre_c1->name);
+ else
+ n += rm_cbl_str(rm, 1);
+ }
+ if (c & 2 || (c == 0 && arg & rm_c2_mask))
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ if (pre_c2)
+ n += gfxd_printf("%s", pre_c2->name);
+ else
+ n += rm_cbl_str(rm, 2);
+ }
+ uint32_t unk_mask = ~(rm_mask | ac_mask | zs_mask);
+ if (arg & unk_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t unk = arg & unk_mask;
+ n += gfxd_printf("0x%08" PRIX32, unk);
+ }
+ return n;
+}
+
+UCFUNC int argfn_ac(const gfxd_value_t *v)
+{
+ return othermodelo_str(v->u, MDMASK(ALPHACOMPARE));
+}
+
+UCFUNC int argfn_zs(const gfxd_value_t *v)
+{
+ return othermodelo_str(v->u, MDMASK(ZSRCSEL));
+}
+
+UCFUNC int argfn_rm1(const gfxd_value_t *v)
+{
+ return othermodelo_str(v->u, MDMASK_RM_C1);
+}
+
+UCFUNC int argfn_rm2(const gfxd_value_t *v)
+{
+ return othermodelo_str(v->u, MDMASK_RM_C2);
+}
+
+UCFUNC int argfn_othermodelo(const gfxd_value_t *v)
+{
+ uint32_t mask = MDMASK(ALPHACOMPARE) | MDMASK(ZSRCSEL) | MDMASK_RM_C1 |
+ MDMASK_RM_C2;
+ return othermodelo_str(v->u, mask);
+}
+
+UCFUNC int argfn_sfthi(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_MDSFT_ALPHADITHER:
+ return gfxd_puts("G_MDSFT_ALPHADITHER");
+ case G_MDSFT_RGBDITHER:
+ return gfxd_puts("G_MDSFT_RGBDITHER");
+ case G_MDSFT_COMBKEY:
+ return gfxd_puts("G_MDSFT_COMBKEY");
+ case G_MDSFT_TEXTCONV:
+ return gfxd_puts("G_MDSFT_TEXTCONV");
+ case G_MDSFT_TEXTFILT:
+ return gfxd_puts("G_MDSFT_TEXTFILT");
+ case G_MDSFT_TEXTLUT:
+ return gfxd_puts("G_MDSFT_TEXTLUT");
+ case G_MDSFT_TEXTLOD:
+ return gfxd_puts("G_MDSFT_TEXTLOD");
+ case G_MDSFT_TEXTDETAIL:
+ return gfxd_puts("G_MDSFT_TEXTDETAIL");
+ case G_MDSFT_TEXTPERSP:
+ return gfxd_puts("G_MDSFT_TEXTPERSP");
+ case G_MDSFT_CYCLETYPE:
+ return gfxd_puts("G_MDSFT_CYCLETYPE");
+ case G_MDSFT_PIPELINE:
+ return gfxd_puts("G_MDSFT_PIPELINE");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int othermodehi_str(uint32_t arg, uint32_t which)
+{
+ int n = 0;
+ uint32_t ad_mask = MDMASK(ALPHADITHER);
+ if ((arg | which) & ad_mask)
+ {
+ uint32_t ad = arg & ad_mask;
+ switch (ad)
+ {
+ case G_AD_PATTERN:
+ n += gfxd_puts("G_AD_PATTERN");
+ break;
+ case G_AD_NOTPATTERN:
+ n += gfxd_puts("G_AD_NOTPATTERN");
+ break;
+ case G_AD_NOISE:
+ n += gfxd_puts("G_AD_NOISE");
+ break;
+ case G_AD_DISABLE:
+ n += gfxd_puts("G_AD_DISABLE");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, ad);
+ break;
+ }
+ }
+ uint32_t cd_mask = MDMASK(RGBDITHER);
+ if ((arg | which) & cd_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t cd = arg & cd_mask;
+ switch (cd)
+ {
+ case G_CD_MAGICSQ:
+ n += gfxd_puts("G_CD_MAGICSQ");
+ break;
+ case G_CD_BAYER:
+ n += gfxd_puts("G_CD_BAYER");
+ break;
+ case G_CD_NOISE:
+ n += gfxd_puts("G_CD_NOISE");
+ break;
+ case G_CD_DISABLE:
+ n += gfxd_puts("G_CD_DISABLE");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, cd);
+ break;
+ }
+ }
+ uint32_t ck_mask = MDMASK(COMBKEY);
+ if ((arg | which) & ck_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t ck = arg & ck_mask;
+ switch (ck)
+ {
+ case G_CK_NONE:
+ n += gfxd_puts("G_CK_NONE");
+ break;
+ case G_CK_KEY:
+ n += gfxd_puts("G_CK_KEY");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, ck);
+ break;
+ }
+ }
+ uint32_t tc_mask = MDMASK(TEXTCONV);
+ if ((arg | which) & tc_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t tc = arg & tc_mask;
+ switch (tc)
+ {
+ case G_TC_CONV:
+ n += gfxd_puts("G_TC_CONV");
+ break;
+ case G_TC_FILTCONV:
+ n += gfxd_puts("G_TC_FILTCONV");
+ break;
+ case G_TC_FILT:
+ n += gfxd_puts("G_TC_FILT");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, tc);
+ break;
+ }
+ }
+ uint32_t tf_mask = MDMASK(TEXTFILT);
+ if ((arg | which) & tf_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t tf = arg & tf_mask;
+ switch (tf)
+ {
+ case G_TF_POINT:
+ n += gfxd_puts("G_TF_POINT");
+ break;
+ case G_TF_BILERP:
+ n += gfxd_puts("G_TF_BILERP");
+ break;
+ case G_TF_AVERAGE:
+ n += gfxd_puts("G_TF_AVERAGE");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, tf);
+ break;
+ }
+ }
+ uint32_t tt_mask = MDMASK(TEXTLUT);
+ if ((arg | which) & tt_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t tt = arg & tt_mask;
+ switch (tt)
+ {
+ case G_TT_NONE:
+ n += gfxd_puts("G_TT_NONE");
+ break;
+ case G_TT_RGBA16:
+ n += gfxd_puts("G_TT_RGBA16");
+ break;
+ case G_TT_IA16:
+ n += gfxd_puts("G_TT_IA16");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, tt);
+ break;
+ }
+ }
+ uint32_t tl_mask = MDMASK(TEXTLOD);
+ if ((arg | which) & tl_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t tl = arg & tl_mask;
+ switch (tl)
+ {
+ case G_TL_TILE:
+ n += gfxd_puts("G_TL_TILE");
+ break;
+ case G_TL_LOD:
+ n += gfxd_puts("G_TL_LOD");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, tl);
+ break;
+ }
+ }
+ uint32_t td_mask = MDMASK(TEXTDETAIL);
+ if ((arg | which) & td_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t td = arg & td_mask;
+ switch (td)
+ {
+ case G_TD_CLAMP:
+ n += gfxd_puts("G_TD_CLAMP");
+ break;
+ case G_TD_SHARPEN:
+ n += gfxd_puts("G_TD_SHARPEN");
+ break;
+ case G_TD_DETAIL:
+ n += gfxd_puts("G_TD_DETAIL");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, td);
+ break;
+ }
+ }
+ uint32_t tp_mask = MDMASK(TEXTPERSP);
+ if ((arg | which) & tp_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t tp = arg & tp_mask;
+ switch (tp)
+ {
+ case G_TP_NONE:
+ n += gfxd_puts("G_TP_NONE");
+ break;
+ case G_TP_PERSP:
+ n += gfxd_puts("G_TP_PERSP");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, tp);
+ break;
+ }
+ }
+ uint32_t cyc_mask = MDMASK(CYCLETYPE);
+ if ((arg | which) & cyc_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t cyc = arg & cyc_mask;
+ switch (cyc)
+ {
+ case G_CYC_1CYCLE:
+ n += gfxd_puts("G_CYC_1CYCLE");
+ break;
+ case G_CYC_2CYCLE:
+ n += gfxd_puts("G_CYC_2CYCLE");
+ break;
+ case G_CYC_COPY:
+ n += gfxd_puts("G_CYC_COPY");
+ break;
+ case G_CYC_FILL:
+ n += gfxd_puts("G_CYC_FILL");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, cyc);
+ break;
+ }
+ }
+ uint32_t pm_mask = MDMASK(PIPELINE);
+ if ((arg | which) & pm_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t pm = arg & pm_mask;
+ switch (pm)
+ {
+ case G_PM_NPRIMITIVE:
+ n += gfxd_puts("G_PM_NPRIMITIVE");
+ break;
+ case G_PM_1PRIMITIVE:
+ n += gfxd_puts("G_PM_1PRIMITIVE");
+ break;
+ default:
+ n += gfxd_printf("0x%08" PRIX32, pm);
+ break;
+ }
+ }
+ uint32_t unk_mask = ~(ad_mask | cd_mask | ck_mask | tc_mask | tf_mask |
+ tt_mask | tl_mask | td_mask | tp_mask |
+ cyc_mask | pm_mask);
+ if (arg & unk_mask)
+ {
+ if (n > 0)
+ n += gfxd_puts(" | ");
+ uint32_t unk = arg & unk_mask;
+ n += gfxd_printf("0x%08" PRIX32, unk);
+ }
+ return n;
+}
+
+UCFUNC int argfn_ad(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(ALPHADITHER));
+}
+
+UCFUNC int argfn_cd(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(RGBDITHER));
+}
+
+UCFUNC int argfn_ck(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(COMBKEY));
+}
+
+UCFUNC int argfn_tc(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(TEXTCONV));
+}
+
+UCFUNC int argfn_tf(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(TEXTFILT));
+}
+
+UCFUNC int argfn_tt(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(TEXTLUT));
+}
+
+UCFUNC int argfn_tl(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(TEXTLOD));
+}
+
+UCFUNC int argfn_td(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(TEXTDETAIL));
+}
+
+UCFUNC int argfn_tp(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(TEXTPERSP));
+}
+
+UCFUNC int argfn_cyc(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(CYCLETYPE));
+}
+
+UCFUNC int argfn_pm(const gfxd_value_t *v)
+{
+ return othermodehi_str(v->u, MDMASK(PIPELINE));
+}
+
+UCFUNC int argfn_othermodehi(const gfxd_value_t *v)
+{
+ uint32_t mask = MDMASK(ALPHADITHER) |
+ MDMASK(RGBDITHER) |
+ MDMASK(COMBKEY) |
+ MDMASK(TEXTCONV) |
+ MDMASK(TEXTFILT) |
+ MDMASK(TEXTLUT) |
+ MDMASK(TEXTLOD) |
+ MDMASK(TEXTDETAIL) |
+ MDMASK(TEXTPERSP) |
+ MDMASK(CYCLETYPE) |
+ MDMASK(PIPELINE);
+ return othermodehi_str(v->u, mask);
+}
+
+UCFUNC int argfn_cv(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_CV_K0:
+ return gfxd_puts("G_CV_K0");
+ case G_CV_K1:
+ return gfxd_puts("G_CV_K1");
+ case G_CV_K2:
+ return gfxd_puts("G_CV_K2");
+ case G_CV_K3:
+ return gfxd_puts("G_CV_K3");
+ case G_CV_K4:
+ return gfxd_puts("G_CV_K4");
+ case G_CV_K5:
+ return gfxd_puts("G_CV_K5");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int argfn_ccmuxa(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_CCMUX_COMBINED:
+ return gfxd_puts("COMBINED");
+ case G_CCMUX_TEXEL0:
+ return gfxd_puts("TEXEL0");
+ case G_CCMUX_TEXEL1:
+ return gfxd_puts("TEXEL1");
+ case G_CCMUX_PRIMITIVE:
+ return gfxd_puts("PRIMITIVE");
+ case G_CCMUX_SHADE:
+ return gfxd_puts("SHADE");
+ case G_CCMUX_ENVIRONMENT:
+ return gfxd_puts("ENVIRONMENT");
+ case G_CCMUX_1:
+ return gfxd_puts("1");
+ case G_CCMUX_NOISE:
+ return gfxd_puts("NOISE");
+ default:
+ return gfxd_puts("0");
+ }
+}
+
+UCFUNC int argfn_ccmuxb(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_CCMUX_COMBINED:
+ return gfxd_puts("COMBINED");
+ case G_CCMUX_TEXEL0:
+ return gfxd_puts("TEXEL0");
+ case G_CCMUX_TEXEL1:
+ return gfxd_puts("TEXEL1");
+ case G_CCMUX_PRIMITIVE:
+ return gfxd_puts("PRIMITIVE");
+ case G_CCMUX_SHADE:
+ return gfxd_puts("SHADE");
+ case G_CCMUX_ENVIRONMENT:
+ return gfxd_puts("ENVIRONMENT");
+ case G_CCMUX_CENTER:
+ return gfxd_puts("CENTER");
+ case G_CCMUX_K4:
+ return gfxd_puts("K4");
+ default:
+ return gfxd_puts("0");
+ }
+}
+
+UCFUNC int argfn_ccmuxc(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_CCMUX_COMBINED:
+ return gfxd_puts("COMBINED");
+ case G_CCMUX_TEXEL0:
+ return gfxd_puts("TEXEL0");
+ case G_CCMUX_TEXEL1:
+ return gfxd_puts("TEXEL1");
+ case G_CCMUX_PRIMITIVE:
+ return gfxd_puts("PRIMITIVE");
+ case G_CCMUX_SHADE:
+ return gfxd_puts("SHADE");
+ case G_CCMUX_ENVIRONMENT:
+ return gfxd_puts("ENVIRONMENT");
+ case G_CCMUX_SCALE:
+ return gfxd_puts("SCALE");
+ case G_CCMUX_COMBINED_ALPHA:
+ return gfxd_puts("COMBINED_ALPHA");
+ case G_CCMUX_TEXEL0_ALPHA:
+ return gfxd_puts("TEXEL0_ALPHA");
+ case G_CCMUX_TEXEL1_ALPHA:
+ return gfxd_puts("TEXEL1_ALPHA");
+ case G_CCMUX_PRIMITIVE_ALPHA:
+ return gfxd_puts("PRIMITIVE_ALPHA");
+ case G_CCMUX_SHADE_ALPHA:
+ return gfxd_puts("SHADE_ALPHA");
+ case G_CCMUX_ENV_ALPHA:
+ return gfxd_puts("ENV_ALPHA");
+ case G_CCMUX_LOD_FRACTION:
+ return gfxd_puts("LOD_FRACTION");
+ case G_CCMUX_PRIM_LOD_FRAC:
+ return gfxd_puts("PRIM_LOD_FRAC");
+ case G_CCMUX_K5:
+ return gfxd_puts("K5");
+ default:
+ return gfxd_puts("0");
+ }
+}
+
+UCFUNC int argfn_ccmuxd(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_CCMUX_COMBINED:
+ return gfxd_puts("COMBINED");
+ case G_CCMUX_TEXEL0:
+ return gfxd_puts("TEXEL0");
+ case G_CCMUX_TEXEL1:
+ return gfxd_puts("TEXEL1");
+ case G_CCMUX_PRIMITIVE:
+ return gfxd_puts("PRIMITIVE");
+ case G_CCMUX_SHADE:
+ return gfxd_puts("SHADE");
+ case G_CCMUX_ENVIRONMENT:
+ return gfxd_puts("ENVIRONMENT");
+ case G_CCMUX_1:
+ return gfxd_puts("1");
+ default:
+ return gfxd_puts("0");
+ }
+}
+
+UCFUNC int argfn_acmuxabd(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_ACMUX_COMBINED:
+ return gfxd_puts("COMBINED");
+ case G_ACMUX_TEXEL0:
+ return gfxd_puts("TEXEL0");
+ case G_ACMUX_TEXEL1:
+ return gfxd_puts("TEXEL1");
+ case G_ACMUX_PRIMITIVE:
+ return gfxd_puts("PRIMITIVE");
+ case G_ACMUX_SHADE:
+ return gfxd_puts("SHADE");
+ case G_ACMUX_ENVIRONMENT:
+ return gfxd_puts("ENVIRONMENT");
+ case G_ACMUX_1:
+ return gfxd_puts("1");
+ default:
+ return gfxd_puts("0");
+ }
+}
+
+UCFUNC int argfn_acmuxc(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_ACMUX_LOD_FRACTION:
+ return gfxd_puts("LOD_FRACTION");
+ case G_ACMUX_TEXEL0:
+ return gfxd_puts("TEXEL0");
+ case G_ACMUX_TEXEL1:
+ return gfxd_puts("TEXEL1");
+ case G_ACMUX_PRIMITIVE:
+ return gfxd_puts("PRIMITIVE");
+ case G_ACMUX_SHADE:
+ return gfxd_puts("SHADE");
+ case G_ACMUX_ENVIRONMENT:
+ return gfxd_puts("ENVIRONMENT");
+ case G_ACMUX_PRIM_LOD_FRAC:
+ return gfxd_puts("PRIM_LOD_FRAC");
+ default:
+ return gfxd_puts("0");
+ }
+}
+
+struct cc_mode
+{
+ int a;
+ int b;
+ int c;
+ int d;
+ int Aa;
+ int Ab;
+ int Ac;
+ int Ad;
+};
+
+struct cc_preset
+{
+ struct cc_mode mode;
+ const char * name;
+};
+
+#define CC_(a,b,c,d,Aa,Ab,Ac,Ad) \
+ { \
+ G_CCMUX_##a, G_CCMUX_##b, \
+ G_CCMUX_##c, G_CCMUX_##d, \
+ G_ACMUX_##Aa, G_ACMUX_##Ab, \
+ G_ACMUX_##Ac, G_ACMUX_##Ad \
+ }
+#define CC(m) CC_(m)
+static const struct cc_preset cc_presets[] =
+{
+ {CC(G_CC_MODULATEI), "G_CC_MODULATEI"},
+ {CC(G_CC_MODULATEIA), "G_CC_MODULATEIA"},
+ {CC(G_CC_MODULATEIDECALA), "G_CC_MODULATEIDECALA"},
+ {CC(G_CC_MODULATERGB), "G_CC_MODULATERGB"},
+ {CC(G_CC_MODULATERGBA), "G_CC_MODULATERGBA"},
+ {CC(G_CC_MODULATERGBDECALA), "G_CC_MODULATERGBDECALA"},
+ {CC(G_CC_MODULATEI_PRIM), "G_CC_MODULATEI_PRIM"},
+ {CC(G_CC_MODULATEIA_PRIM), "G_CC_MODULATEIA_PRIM"},
+ {CC(G_CC_MODULATEIDECALA_PRIM), "G_CC_MODULATEIDECALA_PRIM"},
+ {CC(G_CC_MODULATERGB_PRIM), "G_CC_MODULATERGB_PRIM"},
+ {CC(G_CC_MODULATERGBA_PRIM), "G_CC_MODULATERGBA_PRIM"},
+ {CC(G_CC_MODULATERGBDECALA_PRIM), "G_CC_MODULATERGBDECALA_PRIM"},
+ {CC(G_CC_DECALRGB), "G_CC_DECALRGB"},
+ {CC(G_CC_DECALRGBA), "G_CC_DECALRGBA"},
+ {CC(G_CC_BLENDI), "G_CC_BLENDI"},
+ {CC(G_CC_BLENDIA), "G_CC_BLENDIA"},
+ {CC(G_CC_BLENDIDECALA), "G_CC_BLENDIDECALA"},
+ {CC(G_CC_BLENDRGBA), "G_CC_BLENDRGBA"},
+ {CC(G_CC_BLENDRGBDECALA), "G_CC_BLENDRGBDECALA"},
+ {CC(G_CC_REFLECTRGB), "G_CC_REFLECTRGB"},
+ {CC(G_CC_REFLECTRGBDECALA), "G_CC_REFLECTRGBDECALA"},
+ {CC(G_CC_HILITERGB), "G_CC_HILITERGB"},
+ {CC(G_CC_HILITERGBA), "G_CC_HILITERGBA"},
+ {CC(G_CC_HILITERGBDECALA), "G_CC_HILITERGBDECALA"},
+ {CC(G_CC_1CYUV2RGB), "G_CC_1CYUV2RGB"},
+ {CC(G_CC_PRIMITIVE), "G_CC_PRIMITIVE"},
+ {CC(G_CC_SHADE), "G_CC_SHADE"},
+ {CC(G_CC_ADDRGB), "G_CC_ADDRGB"},
+ {CC(G_CC_ADDRGBDECALA), "G_CC_ADDRGBDECALA"},
+ {CC(G_CC_SHADEDECALA), "G_CC_SHADEDECALA"},
+ {CC(G_CC_BLENDPE), "G_CC_BLENDPE"},
+ {CC(G_CC_BLENDPEDECALA), "G_CC_BLENDPEDECALA"},
+ {CC(G_CC_TRILERP), "G_CC_TRILERP"},
+ {CC(G_CC_TEMPLERP), "G_CC_TEMPLERP"},
+ {CC(G_CC_INTERFERENCE), "G_CC_INTERFERENCE"},
+ {CC(_G_CC_BLENDPE), "_G_CC_BLENDPE"},
+ {CC(_G_CC_BLENDPEDECALA), "_G_CC_BLENDPEDECALA"},
+ {CC(_G_CC_SPARSEST), "_G_CC_SPARSEST"},
+ {CC(_G_CC_TWOCOLORTEX), "_G_CC_TWOCOLORTEX"},
+ {CC(G_CC_MODULATEI2), "G_CC_MODULATEI2"},
+ {CC(G_CC_MODULATEIA2), "G_CC_MODULATEIA2"},
+ {CC(G_CC_MODULATERGB2), "G_CC_MODULATERGB2"},
+ {CC(G_CC_MODULATERGBA2), "G_CC_MODULATERGBA2"},
+ {CC(G_CC_MODULATEI_PRIM2), "G_CC_MODULATEI_PRIM2"},
+ {CC(G_CC_MODULATEIA_PRIM2), "G_CC_MODULATEIA_PRIM2"},
+ {CC(G_CC_MODULATERGB_PRIM2), "G_CC_MODULATERGB_PRIM2"},
+ {CC(G_CC_MODULATERGBA_PRIM2), "G_CC_MODULATERGBA_PRIM2"},
+ {CC(G_CC_DECALRGB2), "G_CC_DECALRGB2"},
+ {CC(G_CC_BLENDI2), "G_CC_BLENDI2"},
+ {CC(G_CC_BLENDIA2), "G_CC_BLENDIA2"},
+ {CC(G_CC_HILITERGB2), "G_CC_HILITERGB2"},
+ {CC(G_CC_HILITERGBA2), "G_CC_HILITERGBA2"},
+ {CC(G_CC_HILITERGBDECALA2), "G_CC_HILITERGBDECALA2"},
+ {CC(G_CC_HILITERGBPASSA2), "G_CC_HILITERGBPASSA2"},
+ {CC(G_CC_CHROMA_KEY2), "G_CC_CHROMA_KEY2"},
+ {CC(G_CC_YUV2RGB), "G_CC_YUV2RGB"},
+ {CC(G_CC_PASS2), "G_CC_PASS2"},
+};
+#undef CC_
+#undef CC
+
+UCFUNC int argfn_ccpre(const gfxd_value_t *v)
+{
+ return gfxd_printf("%s", cc_presets[v->i].name);
+}
+
+UCFUNC int argfn_sc(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_SC_NON_INTERLACE:
+ return gfxd_puts("G_SC_NON_INTERLACE");
+ case G_SC_EVEN_INTERLACE:
+ return gfxd_puts("G_SC_EVEN_INTERLACE");
+ case G_SC_ODD_INTERLACE:
+ return gfxd_puts("G_SC_ODD_INTERLACE");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int argfn_bz(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_BZ_PERSP:
+ return gfxd_puts("G_BZ_PERSP");
+ default:
+ return gfxd_puts("G_BZ_ORTHO");
+ }
+}
+#endif
+
+UCFUNC int argfn_dlf(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_DL_PUSH:
+ return gfxd_puts("G_DL_PUSH");
+ case G_DL_NOPUSH:
+ return gfxd_puts("G_DL_NOPUSH");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);;
+ }
+}
+
+UCFUNC int argfn_mp(const gfxd_value_t *v)
+{
+ int n = 0;
+ if (v->u & G_MTX_PUSH)
+ n += gfxd_puts("G_MTX_PUSH");
+ else
+ n += gfxd_puts("G_MTX_NOPUSH");
+ if (v->u & G_MTX_LOAD)
+ n += gfxd_puts(" | G_MTX_LOAD");
+ else
+ n += gfxd_puts(" | G_MTX_MUL");
+ if (v->u & G_MTX_PROJECTION)
+ n += gfxd_puts(" | G_MTX_PROJECTION");
+ else
+ n += gfxd_puts(" | G_MTX_MODELVIEW");
+ for (int i = 3; i < 8; i++)
+ if (v->u & (1 << i))
+ n += gfxd_printf(" | 0x%02x", 1 << i);
+ return n;
+}
+
+UCFUNC int argfn_ms(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_MTX_MODELVIEW:
+ return gfxd_puts("G_MTX_MODELVIEW");
+ case G_MTX_PROJECTION:
+ return gfxd_puts("G_MTX_PROJECTION");
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int argfn_mw(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_MW_MATRIX:
+ return gfxd_puts("G_MW_MATRIX");
+ case G_MW_NUMLIGHT:
+ return gfxd_puts("G_MW_NUMLIGHT");
+ case G_MW_CLIP:
+ return gfxd_puts("G_MW_CLIP");
+ case G_MW_SEGMENT:
+ return gfxd_puts("G_MW_SEGMENT");
+ case G_MW_FOG:
+ return gfxd_puts("G_MW_FOG");
+ case G_MW_LIGHTCOL:
+ return gfxd_puts("G_MW_LIGHTCOL");
+ case G_MW_PERSPNORM:
+ return gfxd_puts("G_MW_PERSPNORM");
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ case G_MW_POINTS:
+ return gfxd_puts("G_MW_POINTS");
+#endif
+#if defined(F3DEX_GBI_2)
+ case G_MW_FORCEMTX:
+ return gfxd_puts("G_MW_FORCEMTX");
+#endif
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int argfn_mwo_clip(const gfxd_value_t *v)
+{
+ switch (v->u)
+ {
+ case G_MWO_CLIP_RNX:
+ return gfxd_puts("G_MWO_CLIP_RNX");
+ case G_MWO_CLIP_RNY:
+ return gfxd_puts("G_MWO_CLIP_RNY");
+ case G_MWO_CLIP_RPX:
+ return gfxd_puts("G_MWO_CLIP_RPX");
+ case G_MWO_CLIP_RPY:
+ return gfxd_puts("G_MWO_CLIP_RPY");
+ default:
+ return gfxd_printf("0x%04" PRIX32, v->u);
+ }
+}
+
+UCFUNC int argfn_mwo_lightcol(const gfxd_value_t *v)
+{
+ switch (v->u)
+ {
+ case G_MWO_aLIGHT_1:
+ return gfxd_puts("G_MWO_aLIGHT_1");
+ case G_MWO_bLIGHT_1:
+ return gfxd_puts("G_MWO_bLIGHT_1");
+ case G_MWO_aLIGHT_2:
+ return gfxd_puts("G_MWO_aLIGHT_2");
+ case G_MWO_bLIGHT_2:
+ return gfxd_puts("G_MWO_bLIGHT_2");
+ case G_MWO_aLIGHT_3:
+ return gfxd_puts("G_MWO_aLIGHT_3");
+ case G_MWO_bLIGHT_3:
+ return gfxd_puts("G_MWO_bLIGHT_3");
+ case G_MWO_aLIGHT_4:
+ return gfxd_puts("G_MWO_aLIGHT_4");
+ case G_MWO_bLIGHT_4:
+ return gfxd_puts("G_MWO_bLIGHT_4");
+ case G_MWO_aLIGHT_5:
+ return gfxd_puts("G_MWO_aLIGHT_5");
+ case G_MWO_bLIGHT_5:
+ return gfxd_puts("G_MWO_bLIGHT_5");
+ case G_MWO_aLIGHT_6:
+ return gfxd_puts("G_MWO_aLIGHT_6");
+ case G_MWO_bLIGHT_6:
+ return gfxd_puts("G_MWO_bLIGHT_6");
+ case G_MWO_aLIGHT_7:
+ return gfxd_puts("G_MWO_aLIGHT_7");
+ case G_MWO_bLIGHT_7:
+ return gfxd_puts("G_MWO_bLIGHT_7");
+ case G_MWO_aLIGHT_8:
+ return gfxd_puts("G_MWO_aLIGHT_8");
+ case G_MWO_bLIGHT_8:
+ return gfxd_puts("G_MWO_bLIGHT_8");
+ default:
+ return gfxd_printf("0x%04" PRIX32, v->u);
+ }
+}
+
+UCFUNC int argfn_lightnum(const gfxd_value_t *v)
+{
+ return gfxd_printf("LIGHT_%" PRIi32, v->i);
+}
+
+UCFUNC int argfn_lightsn(const gfxd_value_t *v)
+{
+ return gfxd_printf("*(Lightsn *)0x%08" PRIX32, v->u);
+}
+
+UCFUNC int argfn_mwo_matrix(const gfxd_value_t *v)
+{
+ switch (v->u)
+ {
+ case G_MWO_MATRIX_XX_XY_I:
+ return gfxd_puts("G_MWO_MATRIX_XX_XY_I");
+ case G_MWO_MATRIX_XZ_XW_I:
+ return gfxd_puts("G_MWO_MATRIX_XZ_XW_I");
+ case G_MWO_MATRIX_YX_YY_I:
+ return gfxd_puts("G_MWO_MATRIX_YX_YY_I");
+ case G_MWO_MATRIX_YZ_YW_I:
+ return gfxd_puts("G_MWO_MATRIX_YZ_YW_I");
+ case G_MWO_MATRIX_ZX_ZY_I:
+ return gfxd_puts("G_MWO_MATRIX_ZX_ZY_I");
+ case G_MWO_MATRIX_ZZ_ZW_I:
+ return gfxd_puts("G_MWO_MATRIX_ZZ_ZW_I");
+ case G_MWO_MATRIX_WX_WY_I:
+ return gfxd_puts("G_MWO_MATRIX_WX_WY_I");
+ case G_MWO_MATRIX_WZ_WW_I:
+ return gfxd_puts("G_MWO_MATRIX_WZ_WW_I");
+ case G_MWO_MATRIX_XX_XY_F:
+ return gfxd_puts("G_MWO_MATRIX_XX_XY_F");
+ case G_MWO_MATRIX_XZ_XW_F:
+ return gfxd_puts("G_MWO_MATRIX_XZ_XW_F");
+ case G_MWO_MATRIX_YX_YY_F:
+ return gfxd_puts("G_MWO_MATRIX_YX_YY_F");
+ case G_MWO_MATRIX_YZ_YW_F:
+ return gfxd_puts("G_MWO_MATRIX_YZ_YW_F");
+ case G_MWO_MATRIX_ZX_ZY_F:
+ return gfxd_puts("G_MWO_MATRIX_ZX_ZY_F");
+ case G_MWO_MATRIX_ZZ_ZW_F:
+ return gfxd_puts("G_MWO_MATRIX_ZZ_ZW_F");
+ case G_MWO_MATRIX_WX_WY_F:
+ return gfxd_puts("G_MWO_MATRIX_WX_WY_F");
+ case G_MWO_MATRIX_WZ_WW_F:
+ return gfxd_puts("G_MWO_MATRIX_WZ_WW_F");
+ default:
+ return gfxd_printf("0x%04" PRIX32, v->u);
+ }
+}
+
+UCFUNC int argfn_mwo_point(const gfxd_value_t *v)
+{
+ switch (v->u)
+ {
+ case G_MWO_POINT_RGBA:
+ return gfxd_puts("G_MWO_POINT_RGBA");
+ case G_MWO_POINT_ST:
+ return gfxd_puts("G_MWO_POINT_ST");
+ case G_MWO_POINT_XYSCREEN:
+ return gfxd_puts("G_MWO_POINT_XYSCREEN");
+ case G_MWO_POINT_ZSCREEN:
+ return gfxd_puts("G_MWO_POINT_ZSCREEN");
+ default:
+ return gfxd_printf("0x%04" PRIX32, v->u);
+ }
+}
+
+UCFUNC int argfn_mv(const gfxd_value_t *v)
+{
+ switch (v->i)
+ {
+ case G_MV_VIEWPORT:
+ return gfxd_puts("G_MV_VIEWPORT");
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ case G_MV_LOOKATY:
+ return gfxd_puts("G_MV_LOOKATY");
+ case G_MV_LOOKATX:
+ return gfxd_puts("G_MV_LOOKATX");
+ case G_MV_L0:
+ return gfxd_puts("G_MV_L0");
+ case G_MV_L1:
+ return gfxd_puts("G_MV_L1");
+ case G_MV_L2:
+ return gfxd_puts("G_MV_L2");
+ case G_MV_L3:
+ return gfxd_puts("G_MV_L3");
+ case G_MV_L4:
+ return gfxd_puts("G_MV_L4");
+ case G_MV_L5:
+ return gfxd_puts("G_MV_L5");
+ case G_MV_L6:
+ return gfxd_puts("G_MV_L6");
+ case G_MV_L7:
+ return gfxd_puts("G_MV_L7");
+ case G_MV_TXTATT:
+ return gfxd_puts("G_MV_TXTATT");
+ case G_MV_MATRIX_2:
+ return gfxd_puts("G_MV_MATRIX_2");
+ case G_MV_MATRIX_3:
+ return gfxd_puts("G_MV_MATRIX_3");
+ case G_MV_MATRIX_4:
+ return gfxd_puts("G_MV_MATRIX_4");
+ case G_MV_MATRIX_1:
+ return gfxd_puts("G_MV_MATRIX_1");
+#elif defined(F3DEX_GBI_2)
+ case G_MV_MMTX:
+ return gfxd_puts("G_MV_MMTX");
+ case G_MV_PMTX:
+ return gfxd_puts("G_MV_PMTX");
+ case G_MV_LIGHT:
+ return gfxd_puts("G_MV_LIGHT");
+ case G_MV_POINT:
+ return gfxd_puts("G_MV_POINT");
+ case G_MV_MATRIX:
+ return gfxd_puts("G_MV_MATRIX");
+#endif
+ default:
+ return gfxd_printf("%" PRIi32, v->i);
+ }
+}
+
+UCFUNC int argfn_cr(const gfxd_value_t *v)
+{
+ switch (v->u)
+ {
+ case FRUSTRATIO_1:
+ return gfxd_puts("FRUSTRATIO_1");
+ case FRUSTRATIO_2:
+ return gfxd_puts("FRUSTRATIO_2");
+ case FRUSTRATIO_3:
+ return gfxd_puts("FRUSTRATIO_3");
+ case FRUSTRATIO_4:
+ return gfxd_puts("FRUSTRATIO_4");
+ case FRUSTRATIO_5:
+ return gfxd_puts("FRUSTRATIO_5");
+ case FRUSTRATIO_6:
+ return gfxd_puts("FRUSTRATIO_6");
+ default:
+ return gfxd_printf("%" PRIu32, v->u);
+ }
+}
diff --git a/lib/libgfxd/uc_argtbl.c b/lib/libgfxd/uc_argtbl.c
new file mode 100644
index 0000000..09baa0a
--- /dev/null
+++ b/lib/libgfxd/uc_argtbl.c
@@ -0,0 +1,490 @@
+static const gfxd_arg_type_t arg_tbl[] =
+{
+ [gfxd_Word] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Opcode] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_opc,
+ },
+ [gfxd_Coordi] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_u,
+ },
+ [gfxd_Coordq] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_qu102,
+ },
+ [gfxd_Pal] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Tlut] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Timg] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Tmem] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x16,
+ },
+ [gfxd_Tile] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_tile,
+ },
+ [gfxd_Fmt] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_fmt,
+ },
+ [gfxd_Siz] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_siz,
+ },
+ [gfxd_Dim] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Cm] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_cm,
+ },
+ [gfxd_Tm] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_tm,
+ },
+ [gfxd_Ts] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_ts,
+ },
+ [gfxd_Dxt] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_u,
+ },
+ [gfxd_Tag] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Pm] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_pm,
+ },
+ [gfxd_Colorpart] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_color,
+ },
+ [gfxd_Color] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Lodfrac] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_qu08,
+ },
+ [gfxd_Cimg] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Zimg] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Ac] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_ac,
+ },
+ [gfxd_Ad] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_ad,
+ },
+ [gfxd_Cd] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_cd,
+ },
+ [gfxd_Ccpre] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_ccpre,
+ },
+ [gfxd_Ccmuxa] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_ccmuxa,
+ },
+ [gfxd_Ccmuxb] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_ccmuxb,
+ },
+ [gfxd_Ccmuxc] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_ccmuxc,
+ },
+ [gfxd_Ccmuxd] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_ccmuxd,
+ },
+ [gfxd_Acmuxabd] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_acmuxabd,
+ },
+ [gfxd_Acmuxc] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_acmuxc,
+ },
+ [gfxd_Cv] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_cv,
+ },
+ [gfxd_Tc] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_tc,
+ },
+ [gfxd_Cyc] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_cyc,
+ },
+ [gfxd_Zs] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_zs,
+ },
+ [gfxd_Ck] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_ck,
+ },
+ [gfxd_Keyscale] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_color,
+ },
+ [gfxd_Keywidth] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_qs48,
+ },
+ [gfxd_Zi] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Rm1] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_rm1,
+ },
+ [gfxd_Rm2] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_rm2,
+ },
+ [gfxd_Sc] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_sc,
+ },
+ [gfxd_Td] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_td,
+ },
+ [gfxd_Tf] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_tf,
+ },
+ [gfxd_Tl] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_tl,
+ },
+ [gfxd_Tt] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_tt,
+ },
+ [gfxd_Tp] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_tp,
+ },
+ [gfxd_Line] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Vtx] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Vtxflag] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Dl] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+ [gfxd_Zraw] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_qs1616,
+ },
+#endif
+ [gfxd_Dlflag] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_dlf,
+ },
+ [gfxd_Cr] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_cr,
+ },
+ [gfxd_Num] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Fogz] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Fogp] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Mtxptr] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Gm] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_gm,
+ },
+ [gfxd_Mwo_matrix] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_mwo_matrix,
+ },
+ [gfxd_Linewd] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Uctext] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Ucdata] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Size] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x16,
+ },
+ [gfxd_Lookatptr] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Mtxparam] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_mp,
+ },
+ [gfxd_Mtxstack] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_ms,
+ },
+ [gfxd_Mwo_point] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_mwo_point,
+ },
+ [gfxd_Wscale] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_qu016,
+ },
+ [gfxd_Seg] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x8,
+ },
+ [gfxd_Segptr] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Lightsn] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_lightsn,
+ },
+ [gfxd_Numlights] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Lightnum] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_lightnum,
+ },
+ [gfxd_Lightptr] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Tcscale] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_qu016,
+ },
+ [gfxd_Switch] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_switch,
+ },
+ [gfxd_St] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_qs105,
+ },
+ [gfxd_Stdelta] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_qs510,
+ },
+ [gfxd_Vtxptr] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Vpptr] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Dram] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x32,
+ },
+ [gfxd_Dlflag] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+ [gfxd_Sftlo] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_sftlo,
+ },
+ [gfxd_Othermodelo] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_othermodelo,
+ },
+ [gfxd_Sfthi] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_sfthi,
+ },
+ [gfxd_Othermodehi] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_othermodehi,
+ },
+ [gfxd_Mw] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_mw,
+ },
+ [gfxd_Mwo] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x16,
+ },
+ [gfxd_Mwo_clip] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_mwo_clip,
+ },
+ [gfxd_Mwo_lightcol] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_mwo_lightcol,
+ },
+ [gfxd_Mv] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_mv,
+ },
+ [gfxd_Mvo] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x16,
+ },
+ [gfxd_Dmem] =
+ {
+ .fmt = gfxd_argfmt_u,
+ .fn = argfn_x16,
+ },
+ [gfxd_Dmaflag] =
+ {
+ .fmt = gfxd_argfmt_i,
+ .fn = argfn_i,
+ },
+};
diff --git a/lib/libgfxd/uc_f3d.c b/lib/libgfxd/uc_f3d.c
new file mode 100644
index 0000000..9465515
--- /dev/null
+++ b/lib/libgfxd/uc_f3d.c
@@ -0,0 +1,4 @@
+#define uc_name gfxd_f3d
+#define F3D_GBI
+
+#include "uc.c"
diff --git a/lib/libgfxd/uc_f3db.c b/lib/libgfxd/uc_f3db.c
new file mode 100644
index 0000000..cd49904
--- /dev/null
+++ b/lib/libgfxd/uc_f3db.c
@@ -0,0 +1,5 @@
+#define uc_name gfxd_f3db
+#define F3D_GBI
+#define F3D_BETA
+
+#include "uc.c"
diff --git a/lib/libgfxd/uc_f3dex.c b/lib/libgfxd/uc_f3dex.c
new file mode 100644
index 0000000..2ec70d8
--- /dev/null
+++ b/lib/libgfxd/uc_f3dex.c
@@ -0,0 +1,4 @@
+#define uc_name gfxd_f3dex
+#define F3DEX_GBI
+
+#include "uc.c"
diff --git a/lib/libgfxd/uc_f3dex2.c b/lib/libgfxd/uc_f3dex2.c
new file mode 100644
index 0000000..9a19c99
--- /dev/null
+++ b/lib/libgfxd/uc_f3dex2.c
@@ -0,0 +1,4 @@
+#define uc_name gfxd_f3dex2
+#define F3DEX_GBI_2
+
+#include "uc.c"
diff --git a/lib/libgfxd/uc_f3dexb.c b/lib/libgfxd/uc_f3dexb.c
new file mode 100644
index 0000000..2b5c30a
--- /dev/null
+++ b/lib/libgfxd/uc_f3dexb.c
@@ -0,0 +1,5 @@
+#define uc_name gfxd_f3dexb
+#define F3DEX_GBI
+#define F3D_BETA
+
+#include "uc.c"
diff --git a/lib/libgfxd/uc_macrofn.c b/lib/libgfxd/uc_macrofn.c
new file mode 100644
index 0000000..707c0cb
--- /dev/null
+++ b/lib/libgfxd/uc_macrofn.c
@@ -0,0 +1,2453 @@
+static inline uint32_t getfield(uint32_t w, int n, int s)
+{
+ return (w >> s) & (((uint32_t)1 << n) - 1);
+}
+
+static inline int32_t argvi(gfxd_macro_t *m, int idx)
+{
+ return m->arg[idx].value.i;
+}
+
+static inline uint32_t argvu(gfxd_macro_t *m, int idx)
+{
+ return m->arg[idx].value.u;
+}
+
+static inline float argvf(gfxd_macro_t *m, int idx)
+{
+ return m->arg[idx].value.f;
+}
+
+static inline void argi(gfxd_macro_t *m, int idx, const char *name,
+ int32_t value, int type)
+{
+ m->arg[idx].type = type;
+ m->arg[idx].name = name;
+ m->arg[idx].value.i = value;
+ m->arg[idx].bad = 0;
+}
+
+static inline void argu(gfxd_macro_t *m, int idx, const char *name,
+ uint32_t value, int type)
+{
+ m->arg[idx].type = type;
+ m->arg[idx].name = name;
+ m->arg[idx].value.u = value;
+ m->arg[idx].bad = 0;
+}
+
+static inline void argf(gfxd_macro_t *m, int idx, const char *name,
+ float value, int type)
+{
+ m->arg[idx].type = type;
+ m->arg[idx].name = name;
+ m->arg[idx].value.f = value;
+ m->arg[idx].bad = 0;
+}
+
+static inline void badarg(gfxd_macro_t *m, int idx)
+{
+ m->arg[idx].bad = 1;
+}
+
+UCFUNC int32_t sx(uint32_t n, int bits)
+{
+ int32_t smin = (int32_t)1 << (bits - 1);
+ int32_t smax = (int32_t)1 << bits;
+ int32_t i = n;
+ if (i < smin)
+ return i;
+ else
+ return i - smax;
+}
+
+UCFUNC int d_Invalid(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_Invalid;
+ argu(m, 0, "hi", hi, gfxd_Word);
+ argu(m, 1, "lo", lo, gfxd_Word);
+ return -1;
+}
+
+UCFUNC int d_DPFillRectangle(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPFillRectangle;
+ argu(m, 0, "ulx", getfield(lo, 10, 14), gfxd_Coordi);
+ argu(m, 1, "uly", getfield(lo, 10, 2), gfxd_Coordi);
+ argu(m, 2, "lrx", getfield(hi, 10, 14), gfxd_Coordi);
+ argu(m, 3, "lry", getfield(hi, 10, 2), gfxd_Coordi);
+ return 0;
+}
+
+UCFUNC int d_DPFullSync(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPFullSync;
+ return 0;
+}
+
+UCFUNC int d_DPLoadSync(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPLoadSync;
+ return 0;
+}
+
+UCFUNC int d_DPTileSync(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPTileSync;
+ return 0;
+}
+
+UCFUNC int d_DPPipeSync(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPPipeSync;
+ return 0;
+}
+
+UCFUNC int c_DPLoadTLUT_pal16(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 6)
+ return -1;
+ if (m[0].id != gfxd_DPSetTextureImage
+ || argvi(&m[0], 0) != G_IM_FMT_RGBA
+ || argvi(&m[0], 1) != G_IM_SIZ_16b
+ || argvi(&m[0], 2) != 1)
+ {
+ return -1;
+ }
+ uint32_t dram = argvu(&m[0], 3);
+ if (m[1].id != gfxd_DPTileSync)
+ return -1;
+ if (m[2].id != gfxd_DPSetTile
+ || argvi(&m[2], 0) != 0
+ || argvi(&m[2], 1) != 0
+ || argvi(&m[2], 2) != 0
+ || argvu(&m[2], 3) < 0x100
+ || argvu(&m[2], 3) % 0x10 != 0
+ || argvi(&m[2], 4) != G_TX_LOADTILE
+ || argvi(&m[2], 5) != 0
+ || argvu(&m[2], 6) != 0
+ || argvi(&m[2], 7) != 0
+ || argvi(&m[2], 8) != 0
+ || argvu(&m[2], 9) != 0
+ || argvi(&m[2], 10) != 0
+ || argvi(&m[2], 11) != 0)
+ {
+ return -1;
+ }
+ int pal = (argvu(&m[2], 3) - 0x100) / 0x10;
+ if (m[3].id != gfxd_DPLoadSync)
+ return -1;
+ if (m[4].id != gfxd_DPLoadTLUTCmd
+ || argvi(&m[4], 0) != G_TX_LOADTILE
+ || argvi(&m[4], 1) != 15)
+ {
+ return -1;
+ }
+ if (m[5].id != gfxd_DPPipeSync)
+ return -1;
+ m->id = gfxd_DPLoadTLUT_pal16;
+ argi(m, 0, "pal", pal, gfxd_Pal);
+ argu(m, 1, "dram", dram, gfxd_Tlut);
+ return 0;
+}
+
+UCFUNC int c_DPLoadTLUT_pal256(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 6)
+ return -1;
+ if (m[0].id != gfxd_DPSetTextureImage
+ || argvi(&m[0], 0) != G_IM_FMT_RGBA
+ || argvi(&m[0], 1) != G_IM_SIZ_16b
+ || argvi(&m[0], 2) != 1)
+ {
+ return -1;
+ }
+ uint32_t dram = argvu(&m[0], 3);
+ if (m[1].id != gfxd_DPTileSync)
+ return -1;
+ if (m[2].id != gfxd_DPSetTile
+ || argvi(&m[2], 0) != 0
+ || argvi(&m[2], 1) != 0
+ || argvi(&m[2], 2) != 0
+ || argvu(&m[2], 3) != 0x100
+ || argvi(&m[2], 4) != G_TX_LOADTILE
+ || argvi(&m[2], 5) != 0
+ || argvu(&m[2], 6) != 0
+ || argvi(&m[2], 7) != 0
+ || argvi(&m[2], 8) != 0
+ || argvu(&m[2], 9) != 0
+ || argvi(&m[2], 10) != 0
+ || argvi(&m[2], 11) != 0)
+ {
+ return -1;
+ }
+ if (m[3].id != gfxd_DPLoadSync)
+ return -1;
+ if (m[4].id != gfxd_DPLoadTLUTCmd
+ || argvi(&m[4], 0) != G_TX_LOADTILE
+ || argvi(&m[4], 1) != 255)
+ {
+ return -1;
+ }
+ if (m[5].id != gfxd_DPPipeSync)
+ return -1;
+ m->id = gfxd_DPLoadTLUT_pal256;
+ argu(m, 0, "dram", dram, gfxd_Tlut);
+ return 0;
+}
+
+UCFUNC int c_ltb(gfxd_macro_t *m, int n_macro, int id, int mdxt, int mtmem,
+ int mrt, int myuv, int m4b)
+{
+ if (n_macro < 7)
+ return -1;
+ if (m[0].id != gfxd_DPSetTextureImage || argvi(&m[0], 2) != 1)
+ return -1;
+ g_ifmt_t fmt = argvi(&m[0], 0);
+ g_isiz_t ldsiz = argvi(&m[0], 1);
+ uint32_t timg = argvu(&m[0], 3);
+ if (myuv && fmt != G_IM_FMT_YUV)
+ return -1;
+ if (m[1].id != gfxd_DPSetTile
+ || argvi(&m[1], 0) != fmt
+ || argvi(&m[1], 1) != ldsiz
+ || argvi(&m[1], 2) != 0
+ || argvi(&m[1], 4) != G_TX_LOADTILE
+ || argvi(&m[1], 5) != 0)
+ {
+ return -1;
+ }
+ uint32_t tmem = argvu(&m[1], 3);
+ unsigned cms = argvu(&m[1], 9);
+ unsigned cmt = argvu(&m[1], 6);
+ int masks = argvi(&m[1], 10);
+ int maskt = argvi(&m[1], 7);
+ int shifts = argvi(&m[1], 11);
+ int shiftt = argvi(&m[1], 8);
+ if (m[2].id != gfxd_DPLoadSync)
+ return -1;
+ if (m[3].id != gfxd_DPLoadBlock
+ || argvi(&m[3], 0) != G_TX_LOADTILE
+ || argvu(&m[3], 1) != 0
+ || argvu(&m[3], 2) != 0)
+ {
+ return -1;
+ }
+ qu102_t ldlrs = argvu(&m[3], 3);
+ unsigned lddxt = argvu(&m[3], 4);
+ if (m[4].id != gfxd_DPPipeSync)
+ return -1;
+ if (m[5].id != gfxd_DPSetTile
+ || argvi(&m[5], 0) != fmt
+ || G_SIZ_LDSIZ(argvi(&m[5], 1)) != ldsiz
+ || argvu(&m[5], 3) != tmem
+ || argvu(&m[5], 6) != cmt
+ || argvi(&m[5], 7) != maskt
+ || argvi(&m[5], 8) != shiftt
+ || argvu(&m[5], 9) != cms
+ || argvi(&m[5], 10) != masks
+ || argvi(&m[5], 11) != shifts)
+ {
+ return -1;
+ }
+ int siz = argvi(&m[5], 1);
+ int rdline = argvi(&m[5], 2);
+ int rt = argvi(&m[5], 4);
+ int pal = argvi(&m[5], 5);
+ if (m4b && siz != G_IM_SIZ_4b)
+ return -1;
+ if (!(mrt && rt != G_TX_RENDERTILE && tmem == 0)
+ && (tmem != 0) != mtmem)
+ {
+ return -1;
+ }
+ if ((rt != G_TX_RENDERTILE) != mrt)
+ return -1;
+ if (m[6].id != gfxd_DPSetTileSize
+ || argvi(&m[6], 0) != rt
+ || argvu(&m[6], 1) != 0
+ || argvu(&m[6], 2) != 0
+ || (argvu(&m[6], 3) & 3)
+ || (argvu(&m[6], 4) & 3))
+ {
+ return -1;
+ }
+ int width = (argvu(&m[6], 3) >> 2) + 1;
+ int height = (argvu(&m[6], 4) >> 2) + 1;
+ unsigned lrs = ((width * height + 1) * G_SIZ_BITS(siz) - 1) /
+ G_SIZ_BITS(G_SIZ_LDSIZ(siz)) - 1;
+ unsigned dxt = 0;
+ if (!mdxt)
+ {
+ dxt = (width * G_SIZ_BITS(siz) <= 64 ? (1 << 11) :
+ ((1 << 11) + width * G_SIZ_BITS(siz) / 64 - 1) /
+ (width * G_SIZ_BITS(siz) / 64));
+ }
+ int line;
+ if (myuv)
+ line = (width + 7) / 8;
+ else
+ line = (width * G_SIZ_LDBITS(siz) + 63) / 64;
+ if (ldlrs != lrs || lddxt != dxt || rdline != line)
+ return -1;
+ m->id = id;
+ int i = 0;
+ argu(m, i++, "timg", timg, gfxd_Timg);
+ if (mtmem)
+ argu(m, i++, "tmem", tmem, gfxd_Tmem);
+ if (mrt)
+ argi(m, i++, "rtile", rt, gfxd_Tile);
+ argi(m, i++, "fmt", fmt, gfxd_Fmt);
+ if (!m4b)
+ argi(m, i++, "siz", siz, gfxd_Siz);
+ argi(m, i++, "width", width, gfxd_Dim);
+ argi(m, i++, "height", height, gfxd_Dim);
+ argi(m, i++, "pal", pal, gfxd_Pal);
+ argu(m, i++, "cms", cms, gfxd_Cm);
+ argu(m, i++, "cmt", cmt, gfxd_Cm);
+ argi(m, i++, "masks", masks, gfxd_Tm);
+ argi(m, i++, "maskt", maskt, gfxd_Tm);
+ argi(m, i++, "shifts", shifts, gfxd_Ts);
+ argi(m, i++, "shiftt", shiftt, gfxd_Ts);
+ return 0;
+}
+
+UCFUNC int c_DPLoadMultiBlockYuvS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadMultiBlockYuvS, 1, 1, 1, 1, 0);
+}
+
+UCFUNC int c_DPLoadMultiBlockYuv(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadMultiBlockYuv, 0, 1, 1, 1, 0);
+}
+
+UCFUNC int c_DPLoadMultiBlock_4bS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadMultiBlock_4bS, 1, 1, 1, 0, 1);
+}
+
+UCFUNC int c_DPLoadMultiBlock_4b(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadMultiBlock_4b, 0, 1, 1, 0, 1);
+}
+
+UCFUNC int c_DPLoadMultiBlockS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadMultiBlockS, 1, 1, 1, 0, 0);
+}
+
+UCFUNC int c_DPLoadMultiBlock(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadMultiBlock, 0, 1, 1, 0, 0);
+}
+
+UCFUNC int c__DPLoadTextureBlockYuvS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd__DPLoadTextureBlockYuvS, 1, 1, 0, 1, 0);
+}
+
+UCFUNC int c__DPLoadTextureBlockYuv(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd__DPLoadTextureBlockYuv, 0, 1, 0, 1, 0);
+}
+
+UCFUNC int c__DPLoadTextureBlock_4bS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd__DPLoadTextureBlock_4bS, 1, 1, 0, 0, 1);
+}
+
+UCFUNC int c__DPLoadTextureBlock_4b(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd__DPLoadTextureBlock_4b, 0, 1, 0, 0, 1);
+}
+
+UCFUNC int c__DPLoadTextureBlockS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd__DPLoadTextureBlockS, 1, 1, 0, 0, 0);
+}
+
+UCFUNC int c__DPLoadTextureBlock(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd__DPLoadTextureBlock, 0, 1, 0, 0, 0);
+}
+
+UCFUNC int c_DPLoadTextureBlockYuvS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadTextureBlockYuvS, 1, 0, 0, 1, 0);
+}
+
+UCFUNC int c_DPLoadTextureBlockYuv(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadTextureBlockYuv, 0, 0, 0, 1, 0);
+}
+
+UCFUNC int c_DPLoadTextureBlock_4bS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadTextureBlock_4bS, 1, 0, 0, 0, 1);
+}
+
+UCFUNC int c_DPLoadTextureBlock_4b(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadTextureBlock_4b, 0, 0, 0, 0, 1);
+}
+
+UCFUNC int c_DPLoadTextureBlockS(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadTextureBlockS, 1, 0, 0, 0, 0);
+}
+
+UCFUNC int c_DPLoadTextureBlock(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltb(m, n_macro, gfxd_DPLoadTextureBlock, 0, 0, 0, 0, 0);
+}
+
+UCFUNC int c_ltt(gfxd_macro_t *m, int n_macro, int id, int mtmem, int mrt,
+ int myuv, int m4b)
+{
+ if (n_macro < 7)
+ return -1;
+ if (m[0].id != gfxd_DPSetTextureImage)
+ return -1;
+ g_ifmt_t fmt = argvi(&m[0], 0);
+ g_isiz_t ldsiz = argvi(&m[0], 1);
+ int width = argvi(&m[0], 2);
+ if (m4b)
+ {
+ if (ldsiz != G_IM_SIZ_8b)
+ return -1;
+ width *= 2;
+ }
+ uint32_t timg = argvu(&m[0], 3);
+ if (myuv && fmt != G_IM_FMT_YUV)
+ return -1;
+ if (m[1].id != gfxd_DPSetTile
+ || argvi(&m[1], 0) != fmt
+ || argvi(&m[1], 1) != ldsiz
+ || argvi(&m[1], 4) != G_TX_LOADTILE
+ || argvi(&m[1], 5) != 0)
+ {
+ return -1;
+ }
+ int ldline = argvi(&m[1], 2);
+ uint32_t tmem = argvu(&m[1], 3);
+ unsigned cms = argvu(&m[1], 9);
+ unsigned cmt = argvu(&m[1], 6);
+ int masks = argvi(&m[1], 10);
+ int maskt = argvi(&m[1], 7);
+ int shifts = argvi(&m[1], 11);
+ int shiftt = argvi(&m[1], 8);
+ if (m[2].id != gfxd_DPLoadSync)
+ return -1;
+ if (m[3].id != gfxd_DPLoadTile
+ || argvi(&m[3], 0) != G_TX_LOADTILE
+ || (argvu(&m[3], 1) & 1)
+ || (argvu(&m[3], 2) & 3)
+ || (argvu(&m[3], 3) & 1)
+ || (argvu(&m[3], 4) & 3))
+ {
+ return -1;
+ }
+ qu102_t lduls = argvu(&m[3], 1);
+ qu102_t ldult = argvu(&m[3], 2);
+ qu102_t ldlrs = argvu(&m[3], 3);
+ qu102_t ldlrt = argvu(&m[3], 4);
+ if (m[4].id != gfxd_DPPipeSync)
+ return -1;
+ if (m[5].id != gfxd_DPSetTile
+ || argvi(&m[5], 0) != fmt
+ || argvi(&m[5], 2) != ldline
+ || argvu(&m[5], 3) != tmem
+ || argvu(&m[5], 6) != cmt
+ || argvi(&m[5], 7) != maskt
+ || argvi(&m[5], 8) != shiftt
+ || argvu(&m[5], 9) != cms
+ || argvi(&m[5], 10) != masks
+ || argvi(&m[5], 11) != shifts)
+ {
+ return -1;
+ }
+ int siz = argvi(&m[5], 1);
+ int rt = argvi(&m[5], 4);
+ int pal = argvi(&m[5], 5);
+ if (m4b)
+ {
+ if (siz != G_IM_SIZ_4b)
+ return -1;
+ }
+ else if (siz != ldsiz)
+ return -1;
+ if (!(mrt && rt != G_TX_RENDERTILE && tmem == 0)
+ && (tmem != 0) != mtmem)
+ {
+ return -1;
+ }
+ if ((rt != G_TX_RENDERTILE) != mrt)
+ return -1;
+ if (m[6].id != gfxd_DPSetTileSize
+ || argvi(&m[6], 0) != rt
+ || (argvu(&m[6], 1) & 3)
+ || (argvu(&m[6], 2) & 3)
+ || (argvu(&m[6], 3) & 3)
+ || (argvu(&m[6], 4) & 3))
+ {
+ return -1;
+ }
+ unsigned uls = argvu(&m[6], 1) >> 2;
+ unsigned ult = argvu(&m[6], 2) >> 2;
+ unsigned lrs = argvu(&m[6], 3) >> 2;
+ unsigned lrt = argvu(&m[6], 4) >> 2;
+ int line;
+ if (myuv)
+ line = ((lrs - uls + 1) + 7) / 8;
+ else if (m4b)
+ line = ((lrs - uls + 1) / 2 + 7) / 8;
+ else
+ line = ((lrs - uls + 1) * G_SIZ_LDBITS(siz) + 63) / 64;
+ if (m4b)
+ {
+ if (lduls != qu102(uls) / 2 || ldlrs != qu102(lrs) / 2)
+ return -1;
+ }
+ else if (lduls != qu102(uls) || ldlrs != qu102(lrs))
+ return -1;
+ if (ldult != qu102(ult) || ldlrt != qu102(lrt) || ldline != line)
+ return -1;
+ m->id = id;
+ int i = 0;
+ argu(m, i++, "timg", timg, gfxd_Timg);
+ if (mtmem)
+ argu(m, i++, "tmem", tmem, gfxd_Tmem);
+ if (mrt)
+ argi(m, i++, "rtile", rt, gfxd_Tile);
+ argi(m, i++, "fmt", fmt, gfxd_Fmt);
+ if (!m4b)
+ argi(m, i++, "siz", siz, gfxd_Siz);
+ argi(m, i++, "width", width, gfxd_Dim);
+ argi(m, i++, "height", 0, gfxd_Dim);
+ argu(m, i++, "uls", uls, gfxd_Coordi);
+ argu(m, i++, "ult", ult, gfxd_Coordi);
+ argu(m, i++, "lrs", lrs, gfxd_Coordi);
+ argu(m, i++, "lrt", lrt, gfxd_Coordi);
+ argi(m, i++, "pal", pal, gfxd_Pal);
+ argu(m, i++, "cms", cms, gfxd_Cm);
+ argu(m, i++, "cmt", cmt, gfxd_Cm);
+ argi(m, i++, "masks", masks, gfxd_Tm);
+ argi(m, i++, "maskt", maskt, gfxd_Tm);
+ argi(m, i++, "shifts", shifts, gfxd_Ts);
+ argi(m, i++, "shiftt", shiftt, gfxd_Ts);
+ return 0;
+}
+
+UCFUNC int c_DPLoadMultiTileYuv(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd_DPLoadMultiTileYuv, 1, 1, 1, 0);
+}
+
+UCFUNC int c_DPLoadMultiTile_4b(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd_DPLoadMultiTile_4b, 1, 1, 0, 1);
+}
+
+UCFUNC int c_DPLoadMultiTile(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd_DPLoadMultiTile, 1, 1, 0, 0);
+}
+
+UCFUNC int c__DPLoadTextureTileYuv(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd__DPLoadTextureTileYuv, 1, 0, 1, 0);
+}
+
+UCFUNC int c__DPLoadTextureTile_4b(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd__DPLoadTextureTile_4b, 1, 0, 0, 1);
+}
+
+UCFUNC int c__DPLoadTextureTile(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd__DPLoadTextureTile, 1, 0, 0, 0);
+}
+
+UCFUNC int c_DPLoadTextureTileYuv(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd_DPLoadTextureTileYuv, 0, 0, 1, 0);
+}
+
+UCFUNC int c_DPLoadTextureTile_4b(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd_DPLoadTextureTile_4b, 0, 0, 0, 1);
+}
+
+UCFUNC int c_DPLoadTextureTile(gfxd_macro_t *m, int n_macro)
+{
+ return c_ltt(m, n_macro, gfxd_DPLoadTextureTile, 0, 0, 0, 0);
+}
+
+UCFUNC int d_DPLoadBlock(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPLoadBlock;
+ argi(m, 0, "tile", getfield(lo, 3, 24), gfxd_Tile);
+ argu(m, 1, "uls", getfield(hi, 12, 12), gfxd_Coordi);
+ argu(m, 2, "ult", getfield(hi, 12, 0), gfxd_Coordi);
+ argu(m, 3, "lrs", getfield(lo, 12, 12), gfxd_Coordi);
+ argu(m, 4, "dxt", getfield(lo, 12, 0), gfxd_Dxt);
+ return 0;
+}
+
+UCFUNC int d_DPNoOp(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPNoOp;
+ return 0;
+}
+
+UCFUNC int d_DPNoOpTag(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ if (lo == 0)
+ return d_DPNoOp(m, hi, lo);
+ else
+ {
+ m->id = gfxd_DPNoOpTag;
+ argu(m, 0, "tag", lo, gfxd_Tag);
+ return 0;
+ }
+}
+
+UCFUNC int d_DPPipelineMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPPipelineMode;
+ argu(m, 0, "mode", lo, gfxd_Pm);
+ return 0;
+}
+
+UCFUNC int d_DPSetBlendColor(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetBlendColor;
+ argu(m, 0, "r", getfield(lo, 8, 24), gfxd_Colorpart);
+ argu(m, 1, "g", getfield(lo, 8, 16), gfxd_Colorpart);
+ argu(m, 2, "b", getfield(lo, 8, 8), gfxd_Colorpart);
+ argu(m, 3, "a", getfield(lo, 8, 0), gfxd_Colorpart);
+ return 0;
+}
+
+UCFUNC int d_DPSetEnvColor(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetEnvColor;
+ argu(m, 0, "r", getfield(lo, 8, 24), gfxd_Colorpart);
+ argu(m, 1, "g", getfield(lo, 8, 16), gfxd_Colorpart);
+ argu(m, 2, "b", getfield(lo, 8, 8), gfxd_Colorpart);
+ argu(m, 3, "a", getfield(lo, 8, 0), gfxd_Colorpart);
+ return 0;
+}
+
+UCFUNC int d_DPSetFillColor(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetFillColor;
+ argu(m, 0, "c", lo, gfxd_Color);
+ return 0;
+}
+
+UCFUNC int d_DPSetFogColor(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetFogColor;
+ argu(m, 0, "r", getfield(lo, 8, 24), gfxd_Colorpart);
+ argu(m, 1, "g", getfield(lo, 8, 16), gfxd_Colorpart);
+ argu(m, 2, "b", getfield(lo, 8, 8), gfxd_Colorpart);
+ argu(m, 3, "a", getfield(lo, 8, 0), gfxd_Colorpart);
+ return 0;
+}
+
+UCFUNC int d_DPSetPrimColor(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetPrimColor;
+ argu(m, 0, "m", getfield(hi, 8, 8), gfxd_Lodfrac);
+ argu(m, 1, "l", getfield(hi, 8, 0), gfxd_Lodfrac);
+ argu(m, 2, "r", getfield(lo, 8, 24), gfxd_Colorpart);
+ argu(m, 3, "g", getfield(lo, 8, 16), gfxd_Colorpart);
+ argu(m, 4, "b", getfield(lo, 8, 8), gfxd_Colorpart);
+ argu(m, 5, "a", getfield(lo, 8, 0), gfxd_Colorpart);
+ return 0;
+}
+
+UCFUNC int d_DPSetColorImage(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetColorImage;
+ argi(m, 0, "fmt", getfield(hi, 3, 21), gfxd_Fmt);
+ argi(m, 1, "siz", getfield(hi, 2, 19), gfxd_Siz);
+ argi(m, 2, "width", getfield(hi, 12, 0) + 1, gfxd_Dim);
+ argu(m, 3, "cimg", lo, gfxd_Cimg);
+ return 0;
+}
+
+UCFUNC int d_DPSetDepthImage(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetDepthImage;
+ argu(m, 0, "zimg", lo, gfxd_Zimg);
+ return 0;
+}
+
+UCFUNC int d_DPSetTextureImage(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTextureImage;
+ argi(m, 0, "fmt", getfield(hi, 3, 21), gfxd_Fmt);
+ argi(m, 1, "siz", getfield(hi, 2, 19), gfxd_Siz);
+ argi(m, 2, "width", getfield(hi, 12, 0) + 1, gfxd_Dim);
+ argu(m, 3, "timg", lo, gfxd_Timg);
+ return 0;
+}
+
+UCFUNC int d_DPSetAlphaCompare(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetAlphaCompare;
+ argu(m, 0, "mode", lo, gfxd_Ac);
+ return 0;
+}
+
+UCFUNC int d_DPSetAlphaDither(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetAlphaDither;
+ argu(m, 0, "mode", lo, gfxd_Ad);
+ return 0;
+}
+
+UCFUNC int d_DPSetColorDither(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetColorDither;
+ argu(m, 0, "mode", lo, gfxd_Cd);
+ return 0;
+}
+
+UCFUNC void cc_unpack(struct cc_mode *m0, struct cc_mode *m1, uint32_t hi,
+ uint32_t lo)
+{
+ m0->a = getfield(hi, 4, 20);
+ m0->b = getfield(lo, 4, 28);
+ m0->c = getfield(hi, 5, 15);
+ m0->d = getfield(lo, 3, 15);
+ m0->Aa = getfield(hi, 3, 12);
+ m0->Ab = getfield(lo, 3, 12);
+ m0->Ac = getfield(hi, 3, 9);
+ m0->Ad = getfield(lo, 3, 9);
+ m1->a = getfield(hi, 4, 5);
+ m1->b = getfield(lo, 4, 24);
+ m1->c = getfield(hi, 5, 0);
+ m1->d = getfield(lo, 3, 6);
+ m1->Aa = getfield(lo, 3, 21);
+ m1->Ab = getfield(lo, 3, 3);
+ m1->Ac = getfield(lo, 3, 18);
+ m1->Ad = getfield(lo, 3, 0);
+}
+
+UCFUNC int cc_lookup(const struct cc_mode *m)
+{
+ struct cc_mode m_norm = *m;
+ if (m_norm.a > 0x7) m_norm.a = G_CCMUX_0;
+ if (m_norm.b > 0x7) m_norm.b = G_CCMUX_0;
+ if (m_norm.c > 0xF) m_norm.c = G_CCMUX_0;
+ if (m_norm.d > 0x6) m_norm.d = G_CCMUX_0;
+ m = &m_norm;
+ int n_presets = sizeof(cc_presets) / sizeof(*cc_presets);
+ for (int i = 0; i < n_presets; i++)
+ {
+ const struct cc_mode *p = &cc_presets[i].mode;
+ if (m->a == p->a
+ && m->b == p->b
+ && m->c == p->c
+ && m->d == p->d
+ && m->Aa == p->Aa
+ && m->Ab == p->Ab
+ && m->Ac == p->Ac
+ && m->Ad == p->Ad)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+UCFUNC int d_DPSetCombineMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetCombineMode;
+ struct cc_mode m0;
+ struct cc_mode m1;
+ cc_unpack(&m0, &m1, hi, lo);
+ int p0 = cc_lookup(&m0);
+ int p1 = cc_lookup(&m1);
+ argi(m, 0, "mode1", p0, gfxd_Ccpre);
+ argi(m, 1, "mode2", p1, gfxd_Ccpre);
+ int ret = 0;
+ if (p0 == -1)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (p1 == -1)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ return ret;
+}
+
+UCFUNC int d_DPSetCombineLERP(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ struct cc_mode m0;
+ struct cc_mode m1;
+ cc_unpack(&m0, &m1, hi, lo);
+ int p0 = cc_lookup(&m0);
+ int p1 = cc_lookup(&m1);
+ if (p0 != -1 && p1 != -1)
+ return d_DPSetCombineMode(m, hi, lo);
+ else
+ {
+ m->id = gfxd_DPSetCombineLERP;
+ argi(m, 0, "a0", m0.a, gfxd_Ccmuxa);
+ argi(m, 1, "b0", m0.b, gfxd_Ccmuxb);
+ argi(m, 2, "c0", m0.c, gfxd_Ccmuxc);
+ argi(m, 3, "d0", m0.d, gfxd_Ccmuxd);
+ argi(m, 4, "Aa0", m0.Aa, gfxd_Acmuxabd);
+ argi(m, 5, "Ab0", m0.Ab, gfxd_Acmuxabd);
+ argi(m, 6, "Ac0", m0.Ac, gfxd_Acmuxc);
+ argi(m, 7, "Ad0", m0.Ad, gfxd_Acmuxabd);
+ argi(m, 8, "a1", m1.a, gfxd_Ccmuxa);
+ argi(m, 9, "b1", m1.b, gfxd_Ccmuxb);
+ argi(m, 10, "c1", m1.c, gfxd_Ccmuxc);
+ argi(m, 11, "d1", m1.d, gfxd_Ccmuxd);
+ argi(m, 12, "Aa1", m1.Aa, gfxd_Acmuxabd);
+ argi(m, 13, "Ab1", m1.Ab, gfxd_Acmuxabd);
+ argi(m, 14, "Ac1", m1.Ac, gfxd_Acmuxc);
+ argi(m, 15, "Ad1", m1.Ad, gfxd_Acmuxabd);
+ return 0;
+ }
+}
+
+UCFUNC int d_DPSetConvert(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetConvert;
+ argi(m, 0, "k0", sx(getfield(hi, 9, 13), 9), gfxd_Cv);
+ argi(m, 1, "k1", sx(getfield(hi, 9, 4), 9), gfxd_Cv);
+ argi(m, 2, "k2", sx((getfield(hi, 4, 0) << 5) | getfield(lo, 5, 27), 9),
+ gfxd_Cv);
+ argi(m, 3, "k3", sx(getfield(lo, 9, 18), 9), gfxd_Cv);
+ argi(m, 4, "k4", sx(getfield(lo, 9, 9), 9), gfxd_Cv);
+ argi(m, 5, "k5", sx(getfield(lo, 9, 0), 9), gfxd_Cv);
+ return 0;
+}
+
+UCFUNC int d_DPSetTextureConvert(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTextureConvert;
+ argu(m, 0, "mode", lo, gfxd_Tc);
+ return 0;
+}
+
+UCFUNC int d_DPSetCycleType(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetCycleType;
+ argu(m, 0, "mode", lo, gfxd_Cyc);
+ return 0;
+}
+
+UCFUNC int d_DPSetDepthSource(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetDepthSource;
+ argu(m, 0, "mode", lo, gfxd_Zs);
+ return 0;
+}
+
+UCFUNC int d_DPSetCombineKey(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetCombineKey;
+ argu(m, 0, "mode", lo, gfxd_Ck);
+ return 0;
+}
+
+UCFUNC int d_DPSetKeyGB(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetKeyGB;
+ argu(m, 0, "cG", getfield(lo, 8, 24), gfxd_Color);
+ argu(m, 1, "sG", getfield(lo, 8, 16), gfxd_Keyscale);
+ argi(m, 2, "wG", sx(getfield(hi, 12, 12), 12), gfxd_Keywidth);
+ argu(m, 3, "cB", getfield(lo, 8, 8), gfxd_Color);
+ argu(m, 4, "sB", getfield(lo, 8, 0), gfxd_Keyscale);
+ argi(m, 5, "wB", sx(getfield(hi, 12, 0), 12), gfxd_Keywidth);
+ return 0;
+}
+
+UCFUNC int d_DPSetKeyR(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetKeyR;
+ argu(m, 0, "cR", getfield(lo, 8, 8), gfxd_Color);
+ argu(m, 1, "sR", getfield(lo, 8, 0), gfxd_Keyscale);
+ argi(m, 2, "wR", sx(getfield(lo, 12, 16), 12), gfxd_Keywidth);
+ return 0;
+}
+
+UCFUNC int d_DPSetPrimDepth(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetPrimDepth;
+ argi(m, 0, "z", sx(getfield(lo, 16, 16), 16), gfxd_Zi);
+ argi(m, 1, "dz", sx(getfield(lo, 16, 0), 16), gfxd_Zi);
+ return 0;
+}
+
+UCFUNC int d_DPSetRenderMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetRenderMode;
+ argu(m, 0, "mode1", lo, gfxd_Rm1);
+ argu(m, 1, "mode2", lo, gfxd_Rm2);
+ return 0;
+}
+
+UCFUNC int d_DPSetScissor(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetScissor;
+ argi(m, 0, "mode", getfield(lo, 2, 24), gfxd_Sc);
+ argu(m, 1, "ulx", getfield(hi, 10, 14), gfxd_Coordi);
+ argu(m, 2, "uly", getfield(hi, 10, 2), gfxd_Coordi);
+ argu(m, 3, "lrx", getfield(lo, 10, 14), gfxd_Coordi);
+ argu(m, 4, "lry", getfield(lo, 10, 2), gfxd_Coordi);
+ return 0;
+}
+
+UCFUNC int d_DPSetScissorFrac(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ qu102_t ulx = getfield(hi, 12, 12);
+ qu102_t uly = getfield(hi, 12, 0);
+ qu102_t lrx = getfield(lo, 12, 12);
+ qu102_t lry = getfield(lo, 12, 0);
+ if ((ulx & 3) || (uly & 3) || (lrx & 3) || (lry & 3))
+ {
+ m->id = gfxd_DPSetScissorFrac;
+ argi(m, 0, "mode", getfield(lo, 2, 24), gfxd_Sc);
+ argu(m, 1, "ulx", ulx, gfxd_Coordq);
+ argu(m, 2, "uly", uly, gfxd_Coordq);
+ argu(m, 3, "lrx", lrx, gfxd_Coordq);
+ argu(m, 4, "lry", lry, gfxd_Coordq);
+ return 0;
+ }
+ else
+ return d_DPSetScissor(m, hi, lo);
+}
+
+UCFUNC int d_DPSetTextureDetail(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTextureDetail;
+ argu(m, 0, "mode", lo, gfxd_Td);
+ return 0;
+}
+
+UCFUNC int d_DPSetTextureFilter(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTextureFilter;
+ argu(m, 0, "mode", lo, gfxd_Tf);
+ return 0;
+}
+
+UCFUNC int d_DPSetTextureLOD(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTextureLOD;
+ argu(m, 0, "mode", lo, gfxd_Tl);
+ return 0;
+}
+
+UCFUNC int d_DPSetTextureLUT(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTextureLUT;
+ argu(m, 0, "mode", lo, gfxd_Tt);
+ return 0;
+}
+
+UCFUNC int d_DPSetTexturePersp(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTexturePersp;
+ argu(m, 0, "mode", lo, gfxd_Tp);
+ return 0;
+}
+
+UCFUNC int d_DPSetTile(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTile;
+ argi(m, 0, "fmt", getfield(hi, 3, 21), gfxd_Fmt);
+ argi(m, 1, "siz", getfield(hi, 2, 19), gfxd_Siz);
+ argi(m, 2, "line", getfield(hi, 9, 9), gfxd_Line);
+ argu(m, 3, "tmem", getfield(hi, 9, 0), gfxd_Tmem);
+ argi(m, 4, "tile", getfield(lo, 3, 24), gfxd_Tile);
+ argi(m, 5, "pal", getfield(lo, 4, 20), gfxd_Pal);
+ argu(m, 6, "cmt", getfield(lo, 2, 18), gfxd_Cm);
+ argi(m, 7, "maskt", getfield(lo, 4, 14), gfxd_Tm);
+ argi(m, 8, "shiftt", getfield(lo, 4, 10), gfxd_Ts);
+ argu(m, 9, "cms", getfield(lo, 2, 8), gfxd_Cm);
+ argi(m, 10, "masks", getfield(lo, 4, 4), gfxd_Tm);
+ argi(m, 11, "shifts", getfield(lo, 4, 0), gfxd_Ts);
+ return 0;
+}
+
+UCFUNC int d_DPSetTileSize(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetTileSize;
+ argi(m, 0, "tile", getfield(lo, 3, 24), gfxd_Tile);
+ argu(m, 1, "uls", getfield(hi, 12, 12), gfxd_Coordq);
+ argu(m, 2, "ult", getfield(hi, 12, 0), gfxd_Coordq);
+ argu(m, 3, "lrs", getfield(lo, 12, 12), gfxd_Coordq);
+ argu(m, 4, "lrt", getfield(lo, 12, 0), gfxd_Coordq);
+ return 0;
+}
+
+#if defined(F3D_GBI)
+UCFUNC int d_SP1Triangle(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SP1Triangle;
+ int n0 = getfield(lo, 8, 16);
+ int n1 = getfield(lo, 8, 8);
+ int n2 = getfield(lo, 8, 0);
+ argi(m, 0, "v0", n0 / 10, gfxd_Vtx);
+ argi(m, 1, "v1", n1 / 10, gfxd_Vtx);
+ argi(m, 2, "v2", n2 / 10, gfxd_Vtx);
+ argi(m, 3, "flag", getfield(lo, 8, 24), gfxd_Vtxflag);
+ int ret = 0;
+ if (n0 % 10 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (n1 % 10 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ if (n2 % 10 != 0)
+ {
+ badarg(m, 2);
+ ret = -1;
+ }
+ return ret;
+}
+#elif defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int d_SP1Triangle(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SP1Triangle;
+ int n0 = getfield(hi, 8, 16);
+ int n1 = getfield(hi, 8, 8);
+ int n2 = getfield(hi, 8, 0);
+ argi(m, 0, "v0", n0 / 2, gfxd_Vtx);
+ argi(m, 1, "v1", n1 / 2, gfxd_Vtx);
+ argi(m, 2, "v2", n2 / 2, gfxd_Vtx);
+ argi(m, 3, "flag", 0, gfxd_Vtxflag);
+ int ret = 0;
+ if (n0 % 2 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (n1 % 2 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ if (n2 % 2 != 0)
+ {
+ badarg(m, 2);
+ ret = -1;
+ }
+ return ret;
+}
+
+UCFUNC int d_SP1Quadrangle(gfxd_macro_t *m, uint32_t hi, uint32_t lo);
+UCFUNC int d_SP2Triangles(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int n00 = getfield(hi, 8, 16);
+ int n01 = getfield(hi, 8, 8);
+ int n02 = getfield(hi, 8, 0);
+ int n10 = getfield(lo, 8, 16);
+ int n11 = getfield(lo, 8, 8);
+ int n12 = getfield(lo, 8, 0);
+#if defined(F3DEX_GBI)
+ if (n00 == n10 && n02 == n11)
+ return d_SP1Quadrangle(m, hi, lo);
+#endif
+ m->id = gfxd_SP2Triangles;
+ argi(m, 0, "v00", n00 / 2, gfxd_Vtx);
+ argi(m, 1, "v01", n01 / 2, gfxd_Vtx);
+ argi(m, 2, "v02", n02 / 2, gfxd_Vtx);
+ argi(m, 3, "flag0", 0, gfxd_Vtxflag);
+ argi(m, 4, "v10", n10 / 2, gfxd_Vtx);
+ argi(m, 5, "v11", n11 / 2, gfxd_Vtx);
+ argi(m, 6, "v12", n12 / 2, gfxd_Vtx);
+ argi(m, 7, "flag1", 0, gfxd_Vtxflag);
+ int ret = 0;
+ if (n00 % 2 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (n01 % 2 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ if (n02 % 2 != 0)
+ {
+ badarg(m, 2);
+ ret = -1;
+ }
+ if (n10 % 2 != 0)
+ {
+ badarg(m, 4);
+ ret = -1;
+ }
+ if (n11 % 2 != 0)
+ {
+ badarg(m, 5);
+ ret = -1;
+ }
+ if (n12 % 2 != 0)
+ {
+ badarg(m, 6);
+ ret = -1;
+ }
+ return ret;
+}
+
+UCFUNC int d_SP1Quadrangle(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SP1Quadrangle;
+ int n00 = getfield(hi, 8, 16);
+ int n01 = getfield(hi, 8, 8);
+ int n02 = getfield(hi, 8, 0);
+ int n10 = getfield(lo, 8, 16);
+ int n11 = getfield(lo, 8, 8);
+ int n12 = getfield(lo, 8, 0);
+ int v00 = n00 / 2;
+ int v01 = n01 / 2;
+ int v02 = n02 / 2;
+ int v10 = n10 / 2;
+ int v11 = n11 / 2;
+ int v12 = n12 / 2;
+ argi(m, 0, "v0", v00, gfxd_Vtx);
+ argi(m, 1, "v1", v01, gfxd_Vtx);
+ argi(m, 2, "v2", v11, gfxd_Vtx);
+ argi(m, 3, "v3", v12, gfxd_Vtx);
+ argi(m, 4, "flag", 0, gfxd_Vtxflag);
+ int ret = 0;
+ if (v00 != v10 || n00 % 2 != 0 || n10 % 2 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (n01 % 2 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ if (v02 != v11 || n02 % 2 != 0 || n11 % 2 != 0)
+ {
+ badarg(m, 2);
+ ret = -1;
+ }
+ if (n12 % 2 != 0)
+ {
+ badarg(m, 3);
+ ret = -1;
+ }
+ return ret;
+}
+
+UCFUNC int c_SPBranchLessZraw(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 2)
+ return -1;
+ if (m[0].id != gfxd_DPHalf1)
+ return -1;
+ uint32_t branchdl = argvu(&m[0], 0);
+ if (m[1].id != gfxd_BranchZ)
+ return -1;
+ int32_t vtx = argvi(&m[1], 0);
+ int32_t zval = argvi(&m[1], 1);
+ m->id = gfxd_SPBranchLessZraw;
+ argu(m, 0, "dl", branchdl, gfxd_Dl);
+ argi(m, 1, "vtx", vtx, gfxd_Vtx);
+ argi(m, 2, "zval", zval, gfxd_Zraw);
+ return 0;
+}
+#endif
+
+UCFUNC int d_SPBranchList(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPBranchList;
+ argu(m, 0, "dl", lo, gfxd_Dl);
+ return 0;
+}
+
+UCFUNC int c_SPClipRatio(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 4)
+ return -1;
+ if (m[0].id != gfxd_MoveWd
+ || argvi(&m[0], 0) != G_MW_CLIP
+ || argvu(&m[0], 1) != G_MWO_CLIP_RNX)
+ {
+ return -1;
+ }
+ uint32_t r = argvu(&m[0], 2);
+ if (m[1].id != gfxd_MoveWd
+ || argvi(&m[1], 0) != G_MW_CLIP
+ || argvu(&m[1], 1) != G_MWO_CLIP_RNY
+ || argvu(&m[1], 2) != r)
+ {
+ return -1;
+ }
+ if (m[2].id != gfxd_MoveWd
+ || argvi(&m[2], 0) != G_MW_CLIP
+ || argvu(&m[2], 1) != G_MWO_CLIP_RPX
+ || ((uint32_t)1 << 16) - argvu(&m[2], 2) != r)
+ {
+ return -1;
+ }
+ if (m[3].id != gfxd_MoveWd
+ || argvi(&m[3], 0) != G_MW_CLIP
+ || argvu(&m[3], 1) != G_MWO_CLIP_RPY
+ || ((uint32_t)1 << 16) - argvu(&m[3], 2) != r)
+ {
+ return -1;
+ }
+ m->id = gfxd_SPClipRatio;
+ argi(m, 0, "r", r, gfxd_Cr);
+ return 0;
+}
+
+#if defined(F3D_GBI)
+UCFUNC int d_SPCullDisplayList(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPCullDisplayList;
+ int n0 = getfield(hi, 24, 0);
+ int nn = getfield(lo, 16, 0);
+ argi(m, 0, "v0", n0 / 40, gfxd_Vtx);
+ argi(m, 1, "vn", nn / 40 - 1, gfxd_Num);
+ int ret = 0;
+ if (n0 % 40 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (nn % 40 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ return ret;
+}
+#elif defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int d_SPCullDisplayList(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPCullDisplayList;
+ int n0 = getfield(hi, 16, 0);
+ int nn = getfield(lo, 16, 0);
+ argi(m, 0, "v0", n0 / 2, gfxd_Vtx);
+ argi(m, 1, "vn", nn / 2, gfxd_Num);
+ int ret = 0;
+ if (n0 % 2 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (nn % 2 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ return ret;
+}
+#endif
+
+UCFUNC int d_SPDisplayList(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPDisplayList;
+ argu(m, 0, "dl", lo, gfxd_Dl);
+ return 0;
+}
+
+UCFUNC int d_SPEndDisplayList(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPEndDisplayList;
+ return 0;
+}
+
+UCFUNC int d_SPFogFactor(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPFogFactor;
+ argi(m, 0, "fm", sx(getfield(lo, 16, 16), 16), gfxd_Fogz);
+ argi(m, 1, "fo", sx(getfield(lo, 16, 0), 16), gfxd_Fogz);
+ return 0;
+}
+
+UCFUNC int d_SPFogPosition(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int x = sx(getfield(lo, 16, 16), 16);
+ int y = sx(getfield(lo, 16, 0), 16);
+ if (x == 0)
+ return d_SPFogFactor(m, hi, lo);
+ else
+ {
+ int d = 128000 / x;
+ int yd = y * d;
+ if (yd > 0)
+ yd += 255;
+ else if (yd < 0)
+ yd -= 255;
+ int min = 500 - yd / 256;
+ int max = d + min;
+
+ if (min >= 0 && min <= 1000 && max >= 0 && max <= 1000)
+ {
+ m->id = gfxd_SPFogPosition;
+ argi(m, 0, "min", min, gfxd_Fogp);
+ argi(m, 1, "max", max, gfxd_Fogp);
+ return 0;
+ }
+ else
+ return d_SPFogFactor(m, hi, lo);
+ }
+}
+
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+UCFUNC int c_SPForceMatrix(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 4)
+ return -1;
+ for (int i = 0; i < 4; i++)
+ if (m[i].id != gfxd_MoveMem
+ || argvu(&m[i], 0) != 16
+ || argvu(&m[i], 2) != argvu(&m[0], 2) + i * 16)
+ {
+ return -1;
+ }
+ if (argvi(&m[0], 1) != G_MV_MATRIX_1
+ || argvi(&m[1], 1) != G_MV_MATRIX_2
+ || argvi(&m[2], 1) != G_MV_MATRIX_3
+ || argvi(&m[3], 1) != G_MV_MATRIX_4)
+ {
+ return -1;
+ }
+ uint32_t mptr = argvu(&m[0], 2);
+ m->id = gfxd_SPForceMatrix;
+ argu(m, 0, "mptr", mptr, gfxd_Mtxptr);
+ return 0;
+}
+#elif defined(F3DEX_GBI_2)
+UCFUNC int c_SPForceMatrix(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 2)
+ return -1;
+ if (m[0].id != gfxd_MoveMem
+ || argvu(&m[0], 0) != sizeof(Mtx)
+ || argvi(&m[0], 1) != G_MV_MATRIX
+ || argvu(&m[0], 2) != 0)
+ {
+ return -1;
+ }
+ uint32_t mptr = argvu(&m[0], 3);
+ if (m[1].id != gfxd_MoveWd
+ || argvi(&m[1], 0) != G_MW_FORCEMTX
+ || argvu(&m[1], 1) != 0
+ || argvu(&m[1], 2) != 0x10000)
+ {
+ return -1;
+ }
+ m->id = gfxd_SPForceMatrix;
+ argu(m, 0, "mptr", mptr, gfxd_Mtxptr);
+ return 0;
+}
+#endif
+
+UCFUNC int d_SPSetGeometryMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPSetGeometryMode;
+ argu(m, 0, "mode", lo, gfxd_Gm);
+ return 0;
+}
+
+UCFUNC int d_SPClearGeometryMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPClearGeometryMode;
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ argu(m, 0, "mode", lo, gfxd_Gm);
+#elif defined(F3DEX_GBI_2)
+ argu(m, 0, "mode", getfield(~hi, 24, 0), gfxd_Gm);
+#endif
+ return 0;
+}
+
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+UCFUNC int c_SPLoadGeometryMode(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 2)
+ return -1;
+ if (m[0].id != gfxd_SPClearGeometryMode
+ || argvu(&m[0], 0) != 0xFFFFFFFF
+ || m[1].id != gfxd_SPSetGeometryMode)
+ {
+ return -1;
+ }
+ uint32_t mode = argvu(&m[1], 0);
+ m->id = gfxd_SPLoadGeometryMode;
+ argu(m, 0, "mode", mode, gfxd_Gm);
+ return 0;
+}
+#elif defined(F3DEX_GBI_2)
+UCFUNC int d_SPLoadGeometryMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPLoadGeometryMode;
+ argu(m, 0, "mode", lo, gfxd_Gm);
+ return 0;
+}
+#endif
+
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+UCFUNC int d_SPInsertMatrix(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPInsertMatrix;
+ argu(m, 0, "where", getfield(hi, 16, 8), gfxd_Mwo_matrix);
+ argu(m, 1, "val", lo, gfxd_Word);
+ return 0;
+}
+#endif
+
+#if defined(F3D_GBI)
+UCFUNC int d_SPLine3D(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPLine3D;
+ int n0 = getfield(lo, 8, 16);
+ int n1 = getfield(lo, 8, 8);
+ argi(m, 0, "v0", n0 / 10, gfxd_Vtx);
+ argi(m, 1, "v1", n1 / 10, gfxd_Vtx);
+ argi(m, 2, "flag", getfield(lo, 8, 24), gfxd_Vtxflag);
+ int ret = 0;
+ if (n0 % 10 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (n1 % 10 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ return ret;
+}
+#elif defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int d_SPLine3D(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPLine3D;
+ int n0 = getfield(hi, 8, 16);
+ int n1 = getfield(hi, 8, 8);
+ argi(m, 0, "v0", n0 / 2, gfxd_Vtx);
+ argi(m, 1, "v1", n1 / 2, gfxd_Vtx);
+ argi(m, 2, "flag", 0, gfxd_Vtxflag);
+ int ret = 0;
+ if (n0 % 2 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (n1 % 2 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ return ret;
+}
+#endif
+
+#if defined(F3D_GBI)
+UCFUNC int d_SPLineW3D(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int wd = getfield(lo, 8, 0);
+ if (wd == 0)
+ return d_SPLine3D(m, hi, lo);
+ else
+ {
+ m->id = gfxd_SPLineW3D;
+ int n0 = getfield(lo, 8, 16);
+ int n1 = getfield(lo, 8, 8);
+ argi(m, 0, "v0", n0 / 10, gfxd_Vtx);
+ argi(m, 1, "v1", n1 / 10, gfxd_Vtx);
+ argi(m, 2, "wd", wd, gfxd_Linewd);
+ argi(m, 3, "flag", getfield(lo, 8, 24), gfxd_Vtxflag);
+ int ret = 0;
+ if (n0 % 10 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (n1 % 10 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ return ret;
+ }
+}
+#elif defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int d_SPLineW3D(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int wd = getfield(hi, 8, 0);
+ if (wd == 0)
+ return d_SPLine3D(m, hi, lo);
+ else
+ {
+ m->id = gfxd_SPLineW3D;
+ int n0 = getfield(hi, 8, 16);
+ int n1 = getfield(hi, 8, 8);
+ argi(m, 0, "v0", n0 / 2, gfxd_Vtx);
+ argi(m, 1, "v1", n1 / 2, gfxd_Vtx);
+ argi(m, 2, "wd", wd, gfxd_Linewd);
+ argi(m, 3, "flag", 0, gfxd_Vtxflag);
+ int ret = 0;
+ if (n0 % 2 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ if (n1 % 2 != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ return ret;
+ }
+}
+#endif
+
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int c_SPLoadUcode(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 2)
+ return -1;
+ if (m[0].id != gfxd_DPHalf1)
+ return -1;
+ uint32_t uc_dstart = argvu(&m[0], 0);
+ if (m[1].id != gfxd_LoadUcode)
+ return -1;
+ uint32_t uc_start = argvu(&m[1], 0);
+ uint32_t uc_dsize = argvu(&m[1], 1);
+ if (uc_dsize != 0x800)
+ return -1;
+ m->id = gfxd_SPLoadUcode;
+ argu(m, 0, "uc_start", uc_start, gfxd_Uctext);
+ argu(m, 1, "uc_dstart", uc_dstart, gfxd_Ucdata);
+ return 0;
+}
+#endif
+
+UCFUNC int d_SPLookAtX(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPLookAtX;
+ argu(m, 0, "l", lo, gfxd_Lookatptr);
+ return 0;
+}
+
+UCFUNC int d_SPLookAtY(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPLookAtY;
+ argu(m, 0, "l", lo, gfxd_Lookatptr);
+ return 0;
+}
+
+UCFUNC int c_SPLookAt(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 2)
+ return -1;
+ if (m[0].id != gfxd_SPLookAtX)
+ return -1;
+ uint32_t l = argvu(&m[0], 0);
+ if (m[1].id != gfxd_SPLookAtY || argvu(&m[1], 0) != l + 0x10)
+ return -1;
+ m->id = gfxd_SPLookAt;
+ argu(m, 0, "l", l, gfxd_Lookatptr);
+ return 0;
+}
+
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+UCFUNC int d_SPMatrix(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPMatrix;
+ int x = getfield(hi, 16, 0);
+ argu(m, 0, "matrix", lo, gfxd_Mtxptr);
+ argi(m, 1, "param", getfield(hi, 8, 16), gfxd_Mtxparam);
+ if (x != sizeof(Mtx))
+ return -1;
+ else
+ return 0;
+}
+#elif defined(F3DEX_GBI_2)
+UCFUNC int d_SPMatrix(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPMatrix;
+ int x = getfield(hi, 5, 19);
+ argu(m, 0, "matrix", lo, gfxd_Mtxptr);
+ argi(m, 1, "param", getfield(hi, 8, 0) ^ G_MTX_PUSH, gfxd_Mtxparam);
+ if (x != (sizeof(Mtx) - 1) / 8)
+ return -1;
+ else
+ return 0;
+}
+#endif
+
+#if defined(F3D_GBI) || (defined(F3D_BETA) && defined(F3DEX_GBI))
+UCFUNC int d_SPModifyVertex(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPModifyVertex;
+ int offset = getfield(hi, 16, 8);
+ argi(m, 0, "vtx", offset / 40, gfxd_Vtx);
+ argu(m, 1, "where", offset % 40, gfxd_Mwo_point);
+ argu(m, 2, "val", lo, gfxd_Word);
+ return 0;
+}
+#elif defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int d_SPModifyVertex(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPModifyVertex;
+ int vtx = getfield(hi, 16, 0);
+ argi(m, 0, "vtx", vtx / 2, gfxd_Vtx);
+ argu(m, 1, "where", getfield(hi, 8, 16), gfxd_Mwo_point);
+ argu(m, 2, "val", lo, gfxd_Word);
+ int ret = 0;
+ if (vtx % 2 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ return ret;
+}
+#endif
+
+UCFUNC int d_SPPerspNormalize(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPPerspNormalize;
+ argu(m, 0, "scale", getfield(lo, 16, 0), gfxd_Wscale);
+ return 0;
+}
+
+UCFUNC int d_SPPopMatrix(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPPopMatrix;
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ argi(m, 0, "param", lo, gfxd_Mtxstack);
+#elif defined(F3DEX_GBI_2)
+ argi(m, 0, "param", G_MTX_MODELVIEW, gfxd_Mtxstack);
+#endif
+ return 0;
+}
+
+#if defined(F3DEX_GBI_2)
+UCFUNC int d_SPPopMatrixN(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int len = (getfield(hi, 5, 19) + 1) * 8;
+ int ofs = getfield(hi, 8, 8) * 8;
+ int idx = getfield(hi, 8, 0);
+ int n = lo / sizeof(Mtx);
+ if (lo % sizeof(Mtx) == 0
+ && len == sizeof(Mtx)
+ && ofs == 0
+ && idx == 2
+ && n == 1)
+ {
+ return d_SPPopMatrix(m, hi, lo);
+ }
+ m->id = gfxd_SPPopMatrixN;
+ argi(m, 0, "param", G_MTX_MODELVIEW, gfxd_Mtxstack);
+ argi(m, 1, "num", n, gfxd_Num);
+ int ret = 0;
+ if (lo % sizeof(Mtx) != 0)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ if (len != sizeof(Mtx) || ofs != 0 || idx != 2)
+ ret = -1;
+ return ret;
+}
+#endif
+
+UCFUNC int d_SPSegment(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPSegment;
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ int offset = getfield(hi, 16, 8);
+#elif defined(F3DEX_GBI_2)
+ int offset = getfield(hi, 16, 0);
+#endif
+ argu(m, 0, "seg", offset / 4, gfxd_Seg);
+ argu(m, 1, "base", lo, gfxd_Segptr);
+ int ret = 0;
+ if (offset % 4 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ return ret;
+}
+
+UCFUNC int c_SPSetLightsN(gfxd_macro_t *m, int n_macro, int id, int numlights)
+{
+ if (n_macro < 2 + numlights)
+ return -1;
+ if (m[0].id != gfxd_SPNumLights || argvi(&m[0], 0) != numlights)
+ return -1;
+ int a = 1 + numlights;
+ if (m[a].id != gfxd_SPLight || argvi(&m[a], 1) != a)
+ return -1;
+ uint32_t l = argvu(&m[a], 0);
+ for (int i = 1; i <= numlights; i++)
+ {
+ int offset = sizeof(Ambient) + sizeof(Light) * (i - 1);
+ if (m[i].id != gfxd_SPLight
+ || argvu(&m[i], 0) != l + offset
+ || argvi(&m[i], 1) != i)
+ {
+ return -1;
+ }
+ }
+ m->id = id;
+ argu(m, 0, "l", l, gfxd_Lightsn);
+ return 0;
+}
+
+UCFUNC int c_SPSetLights1(gfxd_macro_t *m, int n_macro)
+{
+ return c_SPSetLightsN(m, n_macro, gfxd_SPSetLights1, NUMLIGHTS_1);
+}
+
+UCFUNC int c_SPSetLights2(gfxd_macro_t *m, int n_macro)
+{
+ return c_SPSetLightsN(m, n_macro, gfxd_SPSetLights2, NUMLIGHTS_2);
+}
+
+UCFUNC int c_SPSetLights3(gfxd_macro_t *m, int n_macro)
+{
+ return c_SPSetLightsN(m, n_macro, gfxd_SPSetLights3, NUMLIGHTS_3);
+}
+
+UCFUNC int c_SPSetLights4(gfxd_macro_t *m, int n_macro)
+{
+ return c_SPSetLightsN(m, n_macro, gfxd_SPSetLights4, NUMLIGHTS_4);
+}
+
+UCFUNC int c_SPSetLights5(gfxd_macro_t *m, int n_macro)
+{
+ return c_SPSetLightsN(m, n_macro, gfxd_SPSetLights5, NUMLIGHTS_5);
+}
+
+UCFUNC int c_SPSetLights6(gfxd_macro_t *m, int n_macro)
+{
+ return c_SPSetLightsN(m, n_macro, gfxd_SPSetLights6, NUMLIGHTS_6);
+}
+
+UCFUNC int c_SPSetLights7(gfxd_macro_t *m, int n_macro)
+{
+ return c_SPSetLightsN(m, n_macro, gfxd_SPSetLights7, NUMLIGHTS_7);
+}
+
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+UCFUNC int d_SPNumLights(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPNumLights;
+ argi(m, 0, "n", (lo - 0x80000000) / 32 - 1, gfxd_Numlights);
+ int ret = 0;
+ if (lo < 0x80000040 || lo % 32 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ return ret;
+}
+#elif defined(F3DEX_GBI_2)
+UCFUNC int d_SPNumLights(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPNumLights;
+ argi(m, 0, "n", lo / 24, gfxd_Numlights);
+ int ret = 0;
+ if (lo < 24 || lo % 24 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ return ret;
+}
+#endif
+
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+UCFUNC int d_SPLight(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int n = (getfield(hi, 8, 16) - G_MV_L0) / 2 + 1;
+ m->id = gfxd_SPLight;
+ argu(m, 0, "l", lo, gfxd_Lightptr);
+ argi(m, 1, "n", n, gfxd_Num);
+ return 0;
+}
+#elif defined(F3DEX_GBI_2)
+UCFUNC int d_SPLight(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int n = (getfield(hi, 8, 8) * 8 / 24) - 1;
+ m->id = gfxd_SPLight;
+ argu(m, 0, "l", lo, gfxd_Lightptr);
+ argi(m, 1, "n", n, gfxd_Num);
+ return 0;
+}
+#endif
+
+UCFUNC int c_SPLightColor(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 2)
+ return -1;
+ if (m[0].id != gfxd_MoveWd
+ || argvi(&m[0], 0) != G_MW_LIGHTCOL
+ || argvu(&m[0], 1) % 0x18 != 0
+ || argvu(&m[0], 1) > G_MWO_aLIGHT_8)
+ {
+ return -1;
+ }
+ uint32_t offset = argvu(&m[0], 1);
+ uint32_t packedcolor = argvu(&m[0], 2);
+ if (m[1].id != gfxd_MoveWd
+ || argvi(&m[1], 0) != G_MW_LIGHTCOL
+ || argvu(&m[1], 1) != offset + 4
+ || argvu(&m[1], 2) != packedcolor)
+ {
+ return -1;
+ }
+ m->id = gfxd_SPLightColor;
+ argi(m, 0, "n", offset / 0x18 + 1, gfxd_Lightnum);
+ argu(m, 1, "c", packedcolor, gfxd_Color);
+ return 0;
+}
+
+UCFUNC int d_SPTexture(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPTexture;
+ argu(m, 0, "sc", getfield(lo, 16, 16), gfxd_Tcscale);
+ argu(m, 1, "tc", getfield(lo, 16, 0), gfxd_Tcscale);
+ argi(m, 2, "level", getfield(hi, 3, 11), gfxd_Num);
+ argi(m, 3, "tile", getfield(hi, 3, 8), gfxd_Tile);
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ argi(m, 4, "on", getfield(hi, 8, 0), gfxd_Switch);
+#elif defined(F3DEX_GBI_2)
+ argi(m, 4, "on", getfield(hi, 7, 1), gfxd_Switch);
+#endif
+ return 0;
+}
+
+UCFUNC int c_SPTextureRectangle(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 3)
+ return -1;
+ if (m[0].id != gfxd_TexRect)
+ return -1;
+ qu102_t ulx = argvu(&m[0], 0);
+ qu102_t uly = argvu(&m[0], 1);
+ qu102_t lrx = argvu(&m[0], 2);
+ qu102_t lry = argvu(&m[0], 3);
+ int tile = argvi(&m[0], 4);
+ if (m[1].id != gfxd_DPHalf1)
+ return -1;
+ qs105_t s = sx(getfield(argvu(&m[1], 0), 16, 16), 16);
+ qs105_t t = sx(getfield(argvu(&m[1], 0), 16, 0), 16);
+ if (m[2].id != gfxd_DPHalf2)
+ return -1;
+ qs510_t dsdx = sx(getfield(argvu(&m[2], 0), 16, 16), 16);
+ qs510_t dtdy = sx(getfield(argvu(&m[2], 0), 16, 0), 16);
+ m->id = gfxd_SPTextureRectangle;
+ argu(m, 0, "ulx", ulx, gfxd_Coordq);
+ argu(m, 1, "uly", uly, gfxd_Coordq);
+ argu(m, 2, "lrx", lrx, gfxd_Coordq);
+ argu(m, 3, "lry", lry, gfxd_Coordq);
+ argi(m, 4, "tile", tile, gfxd_Tile);
+ argi(m, 5, "s", s, gfxd_St);
+ argi(m, 6, "t", t, gfxd_St);
+ argi(m, 7, "dsdx", dsdx, gfxd_Stdelta);
+ argi(m, 8, "dtdy", dtdy, gfxd_Stdelta);
+ return 0;
+}
+
+UCFUNC int c_SPTextureRectangleFlip(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 3)
+ return -1;
+ if (m[0].id != gfxd_TexRectFlip)
+ return -1;
+ qu102_t ulx = argvu(&m[0], 0);
+ qu102_t uly = argvu(&m[0], 1);
+ qu102_t lrx = argvu(&m[0], 2);
+ qu102_t lry = argvu(&m[0], 3);
+ int tile = argvi(&m[0], 4);
+ if (m[1].id != gfxd_DPHalf1)
+ return -1;
+ qs105_t s = sx(getfield(argvu(&m[1], 0), 16, 16), 16);
+ qs105_t t = sx(getfield(argvu(&m[1], 0), 16, 0), 16);
+ if (m[2].id != gfxd_DPHalf2)
+ return -1;
+ qs510_t dsdx = sx(getfield(argvu(&m[2], 0), 16, 16), 16);
+ qs510_t dtdy = sx(getfield(argvu(&m[2], 0), 16, 0), 16);
+ m->id = gfxd_SPTextureRectangleFlip;
+ argu(m, 0, "ulx", ulx, gfxd_Coordq);
+ argu(m, 1, "uly", uly, gfxd_Coordq);
+ argu(m, 2, "lrx", lrx, gfxd_Coordq);
+ argu(m, 3, "lry", lry, gfxd_Coordq);
+ argi(m, 4, "tile", tile, gfxd_Tile);
+ argi(m, 5, "s", s, gfxd_St);
+ argi(m, 6, "t", t, gfxd_St);
+ argi(m, 7, "dsdx", dsdx, gfxd_Stdelta);
+ argi(m, 8, "dtdy", dtdy, gfxd_Stdelta);
+ return 0;
+}
+
+#if defined(F3D_GBI)
+UCFUNC int d_SPVertex(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPVertex;
+ int n = getfield(hi, 4, 20) + 1;
+ int v0 = getfield(hi, 4, 16);
+ int size = getfield(hi, 16, 0);
+ argu(m, 0, "v", lo, gfxd_Vtxptr);
+ argi(m, 1, "n", n, gfxd_Num);
+ argi(m, 2, "v0", v0, gfxd_Vtx);
+ int ret = 0;
+ if (size != sizeof(Vtx) * n)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ return ret;
+}
+#elif defined(F3DEX_GBI)
+UCFUNC int d_SPVertex(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPVertex;
+ int n = getfield(hi, 6, 10);
+ int v0 = getfield(hi, 8, 16);
+ int size = getfield(hi, 10, 0);
+ argu(m, 0, "v", lo, gfxd_Vtxptr);
+ argi(m, 1, "n", n, gfxd_Num);
+ argi(m, 2, "v0", v0 / 2, gfxd_Vtx);
+ int ret = 0;
+ if (size != sizeof(Vtx) * n - 1)
+ {
+ badarg(m, 1);
+ ret = -1;
+ }
+ if (v0 % 2 != 0)
+ {
+ badarg(m, 2);
+ ret = -1;
+ }
+ return ret;
+}
+#elif defined(F3DEX_GBI_2)
+UCFUNC int d_SPVertex(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPVertex;
+ int n = getfield(hi, 8, 12);
+ int v0 = getfield(hi, 7, 1) - n;
+ argu(m, 0, "v", lo, gfxd_Vtxptr);
+ argi(m, 1, "n", n, gfxd_Num);
+ argi(m, 2, "v0", v0, gfxd_Vtx);
+ return 0;
+}
+#endif
+
+UCFUNC int d_SPViewport(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPViewport;
+ argu(m, 0, "v", lo, gfxd_Vpptr);
+ return 0;
+}
+
+UCFUNC int d_DPLoadTLUTCmd(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPLoadTLUTCmd;
+ argi(m, 0, "tile", getfield(lo, 3, 24), gfxd_Tile);
+ argi(m, 1, "count", getfield(lo, 10, 14), gfxd_Num);
+ return 0;
+}
+
+UCFUNC int c_DPLoadTLUT(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 6)
+ return -1;
+ if (m[0].id != gfxd_DPSetTextureImage
+ || argvi(&m[0], 0) != G_IM_FMT_RGBA
+ || argvi(&m[0], 1) != G_IM_SIZ_16b
+ || argvi(&m[0], 2) != 1)
+ {
+ return -1;
+ }
+ uint32_t dram = argvu(&m[0], 3);
+ if (m[1].id != gfxd_DPTileSync)
+ return -1;
+ if (m[2].id != gfxd_DPSetTile
+ || argvi(&m[2], 0) != 0
+ || argvi(&m[2], 1) != 0
+ || argvi(&m[2], 2) != 0
+ || argvi(&m[2], 4) != G_TX_LOADTILE
+ || argvi(&m[2], 5) != 0
+ || argvu(&m[2], 6) != 0
+ || argvi(&m[2], 7) != 0
+ || argvi(&m[2], 8) != 0
+ || argvu(&m[2], 9) != 0
+ || argvi(&m[2], 10) != 0
+ || argvi(&m[2], 11) != 0)
+ {
+ return -1;
+ }
+ uint32_t tmem = argvu(&m[2], 3);
+ if (m[3].id != gfxd_DPLoadSync)
+ return -1;
+ if (m[4].id != gfxd_DPLoadTLUTCmd || argvi(&m[4], 0) != G_TX_LOADTILE)
+ return -1;
+ int count = argvi(&m[4], 1) + 1;
+ if (m[5].id != gfxd_DPPipeSync)
+ return -1;
+ m->id = gfxd_DPLoadTLUT;
+ argi(m, 0, "count", count, gfxd_Num);
+ argu(m, 1, "tmem", tmem, gfxd_Tmem);
+ argu(m, 2, "dram", dram, gfxd_Tlut);
+ return 0;
+}
+
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int d_BranchZ(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_BranchZ;
+ int na = getfield(hi, 12, 12);
+ int nb = getfield(hi, 12, 0);
+ int32_t zval;
+ if (lo > 0x7FFFFFFF)
+ zval = -0x80000000 + (int32_t)(lo & 0x7FFFFFFF);
+ else
+ zval = lo;
+ argi(m, 0, "vtx", nb / 2, gfxd_Vtx);
+ argi(m, 1, "zval", zval, gfxd_Zraw);
+ int ret = 0;
+ if (nb % 2 != 0 || na / 5 != nb / 2 || na % 5 != 0)
+ {
+ badarg(m, 0);
+ ret = -1;
+ }
+ return ret;
+}
+#endif
+
+UCFUNC int d_DisplayList(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int flag = getfield(hi, 8, 16);
+ if (flag == 0)
+ return d_SPDisplayList(m, hi, lo);
+ else if (flag == 1)
+ return d_SPBranchList(m, hi, lo);
+ else
+ {
+ m->id = gfxd_DisplayList;
+ argu(m, 0, "dl", lo, gfxd_Dl);
+ argi(m, 1, "flag", flag, gfxd_Dlflag);
+ return 0;
+ }
+}
+
+UCFUNC int d_DPHalf1(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPHalf1;
+ argu(m, 0, "hi", lo, gfxd_Word);
+ return 0;
+}
+
+UCFUNC int d_DPHalf2(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPHalf2;
+ argu(m, 0, "lo", lo, gfxd_Word);
+ return 0;
+}
+
+UCFUNC int c_DPWord(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 2)
+ return -1;
+ if (m[0].id != gfxd_DPHalf1 || m[1].id != gfxd_DPHalf2)
+ return -1;
+ uint32_t wordhi = argvu(&m[0], 0);
+ uint32_t wordlo = argvu(&m[1], 0);
+ m->id = gfxd_DPWord;
+ argu(m, 0, "wordhi", wordhi, gfxd_Word);
+ argu(m, 1, "wordlo", wordlo, gfxd_Word);
+ return 0;
+}
+
+UCFUNC int d_DPLoadTile(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPLoadTile;
+ argi(m, 0, "tile", getfield(lo, 3, 24), gfxd_Tile);
+ argu(m, 1, "uls", getfield(hi, 12, 12), gfxd_Coordq);
+ argu(m, 2, "ult", getfield(hi, 12, 0), gfxd_Coordq);
+ argu(m, 3, "lrs", getfield(lo, 12, 12), gfxd_Coordq);
+ argu(m, 4, "lrt", getfield(lo, 12, 0), gfxd_Coordq);
+ return 0;
+}
+
+#if defined(F3DEX_GBI_2)
+UCFUNC int d_SPGeometryMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ uint32_t clearbits = getfield(~hi, 24, 0);
+ uint32_t setbits = lo;
+ if (clearbits == 0 && setbits != 0)
+ return d_SPSetGeometryMode(m, hi, lo);
+ else if (clearbits != 0 && setbits == 0)
+ return d_SPClearGeometryMode(m, hi, lo);
+ else if (clearbits == 0x00FFFFFF)
+ return d_SPLoadGeometryMode(m, hi, lo);
+ else
+ {
+ m->id = gfxd_SPGeometryMode;
+ argu(m, 0, "c", clearbits, gfxd_Gm);
+ argu(m, 1, "s", setbits, gfxd_Gm);
+ return 0;
+ }
+}
+#endif
+
+UCFUNC int d_SPSetOtherMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPSetOtherMode;
+ int opc = getfield(hi, 8, 24);
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ int length = getfield(hi, 8, 0);
+ int shift = getfield(hi, 8, 8);
+#elif defined(F3DEX_GBI_2)
+ int length = getfield(hi, 8, 0) + 1;
+ int shift = 32 - (getfield(hi, 8, 8) + length);
+#endif
+ argi(m, 0, "opc", opc, gfxd_Opcode);
+ argi(m, 1, "sft", shift, gfxd_Sftlo);
+ argi(m, 2, "len", length, gfxd_Num);
+ if (opc == G_SETOTHERMODE_H)
+ argu(m, 3, "mode", lo, gfxd_Othermodehi);
+ else if (opc == G_SETOTHERMODE_L)
+ argu(m, 3, "mode", lo, gfxd_Othermodelo);
+ else
+ argu(m, 3, "mode", lo, gfxd_Word);
+ return 0;
+}
+
+UCFUNC int d_SPSetOtherModeLo(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ int length = getfield(hi, 8, 0);
+ int shift = getfield(hi, 8, 8);
+#elif defined(F3DEX_GBI_2)
+ int length = getfield(hi, 8, 0) + 1;
+ int shift = 32 - (getfield(hi, 8, 8) + length);
+#endif
+ if (shift == G_MDSFT_ALPHACOMPARE && length == G_MDSIZ_ALPHACOMPARE)
+ return d_DPSetAlphaCompare(m, hi, lo);
+ else if (shift == G_MDSFT_ZSRCSEL && length == G_MDSIZ_ZSRCSEL)
+ return d_DPSetDepthSource(m, hi, lo);
+ else if (shift == G_MDSFT_RENDERMODE && length == G_MDSIZ_RENDERMODE)
+ return d_DPSetRenderMode(m, hi, lo);
+ else if (config.emit_ext_macro)
+ {
+ m->id = gfxd_SPSetOtherModeLo;
+ argi(m, 0, "sft", shift, gfxd_Sftlo);
+ argi(m, 1, "len", length, gfxd_Num);
+ argu(m, 2, "mode", lo, gfxd_Othermodelo);
+ return 0;
+ }
+ else
+ return d_SPSetOtherMode(m, hi, lo);
+}
+
+UCFUNC int d_SPSetOtherModeHi(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ int length = getfield(hi, 8, 0);
+ int shift = getfield(hi, 8, 8);
+#elif defined(F3DEX_GBI_2)
+ int length = getfield(hi, 8, 0) + 1;
+ int shift = 32 - (getfield(hi, 8, 8) + length);
+#endif
+ if (shift == G_MDSFT_ALPHADITHER && length == G_MDSIZ_ALPHADITHER)
+ return d_DPSetAlphaDither(m, hi, lo);
+ else if (shift == G_MDSFT_RGBDITHER && length == G_MDSIZ_RGBDITHER)
+ return d_DPSetColorDither(m, hi, lo);
+ else if (shift == G_MDSFT_COMBKEY && length == G_MDSIZ_COMBKEY)
+ return d_DPSetCombineKey(m, hi, lo);
+ else if (shift == G_MDSFT_TEXTCONV && length == G_MDSIZ_TEXTCONV)
+ return d_DPSetTextureConvert(m, hi, lo);
+ else if (shift == G_MDSFT_TEXTFILT && length == G_MDSIZ_TEXTFILT)
+ return d_DPSetTextureFilter(m, hi, lo);
+ else if (shift == G_MDSFT_TEXTLUT && length == G_MDSIZ_TEXTLUT)
+ return d_DPSetTextureLUT(m, hi, lo);
+ else if (shift == G_MDSFT_TEXTLOD && length == G_MDSIZ_TEXTLOD)
+ return d_DPSetTextureLOD(m, hi, lo);
+ else if (shift == G_MDSFT_TEXTDETAIL && length == G_MDSIZ_TEXTDETAIL)
+ return d_DPSetTextureDetail(m, hi, lo);
+ else if (shift == G_MDSFT_TEXTPERSP && length == G_MDSIZ_TEXTPERSP)
+ return d_DPSetTexturePersp(m, hi, lo);
+ else if (shift == G_MDSFT_CYCLETYPE && length == G_MDSIZ_CYCLETYPE)
+ return d_DPSetCycleType(m, hi, lo);
+ else if (shift == G_MDSFT_PIPELINE && length == G_MDSIZ_PIPELINE)
+ return d_DPPipelineMode(m, hi, lo);
+ else if (config.emit_ext_macro)
+ {
+ m->id = gfxd_SPSetOtherModeHi;
+ argi(m, 0, "sft", shift, gfxd_Sfthi);
+ argi(m, 1, "len", length, gfxd_Num);
+ argu(m, 2, "mode", lo, gfxd_Othermodehi);
+ return 0;
+ }
+ else
+ return d_SPSetOtherMode(m, hi, lo);
+}
+
+UCFUNC int d_DPSetOtherMode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_DPSetOtherMode;
+ argu(m, 0, "hi", getfield(hi, 24, 0), gfxd_Othermodehi);
+ argu(m, 1, "lo", lo, gfxd_Othermodelo);
+ return 0;
+}
+
+UCFUNC int d_MoveWd(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ int index = getfield(hi, 8, 0);
+ int offset = getfield(hi, 16, 8);
+#elif defined(F3DEX_GBI_2)
+ int index = getfield(hi, 8, 16);
+ int offset = getfield(hi, 16, 0);
+#endif
+ if (index == G_MW_FOG && offset == G_MWO_FOG)
+ return d_SPFogPosition(m, hi, lo);
+#if !(defined(F3D_BETA) && (defined(F3D_GBI) || defined(F3DEX_GBI)))
+ else if (index == G_MW_PERSPNORM && offset == 0)
+ return d_SPPerspNormalize(m, hi, lo);
+#endif
+ else if (index == G_MW_SEGMENT)
+ return d_SPSegment(m, hi, lo);
+ else if (index == G_MW_NUMLIGHT && offset == G_MWO_NUMLIGHT)
+ return d_SPNumLights(m, hi, lo);
+#if defined(F3D_GBI) || (defined(F3D_BETA) && defined(F3DEX_GBI))
+ else if (index == G_MW_POINTS)
+ return d_SPModifyVertex(m, hi, lo);
+#endif
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ else if (index == G_MW_MATRIX)
+ return d_SPInsertMatrix(m, hi, lo);
+#endif
+ else
+ {
+ m->id = gfxd_MoveWd;
+ argi(m, 0, "index", index, gfxd_Mw);
+ if (index == G_MW_MATRIX)
+ argu(m, 1, "offset", offset, gfxd_Mwo_matrix);
+ else if (index == G_MW_CLIP)
+ argu(m, 1, "offset", offset, gfxd_Mwo_clip);
+ else if (index == G_MW_LIGHTCOL)
+ argu(m, 1, "offset", offset, gfxd_Mwo_lightcol);
+ else
+ argu(m, 1, "offset", offset, gfxd_Mwo);
+ argu(m, 2, "value", lo, gfxd_Word);
+ }
+ return 0;
+}
+
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+UCFUNC int d_MoveMem(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int size = getfield(hi, 16, 0);
+ int index = getfield(hi, 8, 16);
+ if (size == sizeof(Light)
+ && index >= G_MV_L0
+ && index <= G_MV_L7
+ && index % 2 == 0)
+ {
+ return d_SPLight(m, hi, lo);
+ }
+ else if (size == sizeof(Light) && index == G_MV_LOOKATX)
+ return d_SPLookAtX(m, hi, lo);
+ else if (size == sizeof(Light) && index == G_MV_LOOKATY)
+ return d_SPLookAtY(m, hi, lo);
+ else if (size == sizeof(Vp) && index == G_MV_VIEWPORT)
+ return d_SPViewport(m, hi, lo);
+ else
+ {
+ m->id = gfxd_MoveMem;
+ argu(m, 0, "size", size, gfxd_Size);
+ argi(m, 1, "index", index, gfxd_Mv);
+ argu(m, 2, "dram", lo, gfxd_Dram);
+ return 0;
+ }
+}
+#elif defined(F3DEX_GBI_2)
+UCFUNC int d_MoveMem(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int size = (getfield(hi, 5, 19) + 1) * 8;
+ int index = getfield(hi, 8, 0);
+ int offset = getfield(hi, 8, 8) * 8;
+ if (size == sizeof(Light)
+ && index == G_MV_LIGHT
+ && offset >= G_MVO_L0
+ && offset <= G_MVO_L7
+ && offset % 0x18 == 0)
+ {
+ return d_SPLight(m, hi, lo);
+ }
+ else if (size == sizeof(Light)
+ && index == G_MV_LIGHT
+ && offset == G_MVO_LOOKATX)
+ {
+ return d_SPLookAtX(m, hi, lo);
+ }
+ else if (size == sizeof(Light)
+ && index == G_MV_LIGHT
+ && offset == G_MVO_LOOKATY)
+ {
+ return d_SPLookAtY(m, hi, lo);
+ }
+ else if (size == sizeof(Vp)
+ && index == G_MV_VIEWPORT
+ && offset == 0)
+ {
+ return d_SPViewport(m, hi, lo);
+ }
+ else
+ {
+ m->id = gfxd_MoveMem;
+ argu(m, 0, "size", size, gfxd_Size);
+ argi(m, 1, "index", index, gfxd_Mv);
+ argu(m, 2, "offset", offset, gfxd_Size);
+ argu(m, 3, "dram", lo, gfxd_Dram);
+ return 0;
+ }
+}
+#endif
+
+#if defined(F3DEX_GBI_2)
+UCFUNC int d_SPDmaRead(gfxd_macro_t *m, uint32_t hi, uint32_t lo);
+UCFUNC int d_SPDmaWrite(gfxd_macro_t *m, uint32_t hi, uint32_t lo);
+UCFUNC int d_SPDma_io(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ int flag = getfield(hi, 1, 23);
+ if (flag == 0)
+ return d_SPDmaRead(m, hi, lo);
+ else if (flag == 1)
+ return d_SPDmaWrite(m, hi, lo);
+ else
+ {
+ m->id = gfxd_SPDma_io;
+ argi(m, 0, "flag", flag, gfxd_Dmaflag);
+ argu(m, 1, "dmem", getfield(hi, 10, 13) * 8, gfxd_Dmem);
+ argu(m, 2, "dram", lo, gfxd_Dram);
+ argu(m, 3, "size", getfield(hi, 12, 10) + 1, gfxd_Size);
+ return 0;
+ }
+}
+
+UCFUNC int d_SPDmaRead(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPDmaRead;
+ argu(m, 0, "dmem", getfield(hi, 10, 13) * 8, gfxd_Dmem);
+ argu(m, 1, "dram", lo, gfxd_Dram);
+ argu(m, 2, "size", getfield(hi, 12, 10) + 1, gfxd_Size);
+ return 0;
+}
+
+UCFUNC int d_SPDmaWrite(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPDmaWrite;
+ argu(m, 0, "dmem", getfield(hi, 10, 13) * 8, gfxd_Dmem);
+ argu(m, 1, "dram", lo, gfxd_Dram);
+ argu(m, 2, "size", getfield(hi, 12, 10) + 1, gfxd_Size);
+ return 0;
+}
+#endif
+
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+UCFUNC int d_LoadUcode(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_LoadUcode;
+ argu(m, 0, "uc_start", lo, gfxd_Uctext);
+ argu(m, 1, "uc_dsize", getfield(hi, 16, 0) + 1, gfxd_Size);
+ return 0;
+}
+
+UCFUNC int c_SPLoadUcodeEx(gfxd_macro_t *m, int n_macro)
+{
+ if (n_macro < 2)
+ return -1;
+ if (m[0].id != gfxd_DPHalf1)
+ return -1;
+ uint32_t uc_dstart = argvu(&m[0], 0);
+ if (m[1].id != gfxd_LoadUcode)
+ return -1;
+ uint32_t uc_start = argvu(&m[1], 0);
+ uint32_t uc_dsize = argvu(&m[1], 1);
+ m->id = gfxd_SPLoadUcodeEx;
+ argu(m, 0, "uc_start", uc_start, gfxd_Uctext);
+ argu(m, 1, "uc_dstart", uc_dstart, gfxd_Ucdata);
+ argu(m, 2, "uc_dsize", uc_dsize, gfxd_Size);
+ return 0;
+}
+#endif
+
+UCFUNC int d_TexRect(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_TexRect;
+ argu(m, 0, "ulx", getfield(lo, 12, 12), gfxd_Coordq);
+ argu(m, 1, "uly", getfield(lo, 12, 0), gfxd_Coordq);
+ argu(m, 2, "lrx", getfield(hi, 12, 12), gfxd_Coordq);
+ argu(m, 3, "lry", getfield(hi, 12, 0), gfxd_Coordq);
+ argi(m, 4, "tile", getfield(lo, 3, 24), gfxd_Tile);
+ return 0;
+}
+
+UCFUNC int d_TexRectFlip(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_TexRectFlip;
+ argu(m, 0, "ulx", getfield(lo, 12, 12), gfxd_Coordq);
+ argu(m, 1, "uly", getfield(lo, 12, 0), gfxd_Coordq);
+ argu(m, 2, "lrx", getfield(hi, 12, 12), gfxd_Coordq);
+ argu(m, 3, "lry", getfield(hi, 12, 0), gfxd_Coordq);
+ argi(m, 4, "tile", getfield(lo, 3, 24), gfxd_Tile);
+ return 0;
+}
+
+UCFUNC int d_SPNoOp(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_SPNoOp;
+ return 0;
+}
+
+#if defined(F3DEX_GBI_2)
+UCFUNC int d_Special3(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_Special3;
+ argu(m, 0, "hi", getfield(hi, 24, 0), gfxd_Word);
+ argu(m, 1, "lo", lo, gfxd_Word);
+ return 0;
+}
+
+UCFUNC int d_Special2(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_Special2;
+ argu(m, 0, "hi", getfield(hi, 24, 0), gfxd_Word);
+ argu(m, 1, "lo", lo, gfxd_Word);
+ return 0;
+}
+
+UCFUNC int d_Special1(gfxd_macro_t *m, uint32_t hi, uint32_t lo)
+{
+ m->id = gfxd_Special1;
+ argu(m, 0, "hi", getfield(hi, 24, 0), gfxd_Word);
+ argu(m, 1, "lo", lo, gfxd_Word);
+ return 0;
+}
+#endif
diff --git a/lib/libgfxd/uc_macrotbl.c b/lib/libgfxd/uc_macrotbl.c
new file mode 100644
index 0000000..a8939ce
--- /dev/null
+++ b/lib/libgfxd/uc_macrotbl.c
@@ -0,0 +1,1397 @@
+static const gfxd_macro_type_t macro_tbl[] =
+{
+ [gfxd_Invalid] =
+ {
+ .prefix = NULL,
+ .suffix = NULL,
+ .opcode = -1,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_Invalid,
+ },
+ [gfxd_DPFillRectangle] =
+ {
+ .prefix = NULL,
+ .suffix = "DPFillRectangle",
+ .opcode = G_FILLRECT,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_DPFillRectangle,
+ },
+ [gfxd_DPFullSync] =
+ {
+ .prefix = NULL,
+ .suffix = "DPFullSync",
+ .opcode = G_RDPFULLSYNC,
+ .n_gfx = 1,
+ .n_arg = 0,
+ .disas_fn = d_DPFullSync,
+ },
+ [gfxd_DPLoadSync] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadSync",
+ .opcode = G_RDPLOADSYNC,
+ .n_gfx = 1,
+ .n_arg = 0,
+ .disas_fn = d_DPLoadSync,
+ },
+ [gfxd_DPTileSync] =
+ {
+ .prefix = NULL,
+ .suffix = "DPTileSync",
+ .opcode = G_RDPTILESYNC,
+ .n_gfx = 1,
+ .n_arg = 0,
+ .disas_fn = d_DPTileSync,
+ },
+ [gfxd_DPPipeSync] =
+ {
+ .prefix = NULL,
+ .suffix = "DPPipeSync",
+ .opcode = G_RDPPIPESYNC,
+ .n_gfx = 1,
+ .n_arg = 0,
+ .disas_fn = d_DPPipeSync,
+ },
+ [gfxd_DPLoadTLUT_pal16] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTLUT_pal16",
+ .opcode = G_SETTIMG,
+ .n_gfx = 6,
+ .n_arg = 2,
+ .combine_fn = c_DPLoadTLUT_pal16,
+ },
+ [gfxd_DPLoadTLUT_pal256] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTLUT_pal256",
+ .opcode = G_SETTIMG,
+ .n_gfx = 6,
+ .n_arg = 1,
+ .combine_fn = c_DPLoadTLUT_pal256,
+ },
+ [gfxd_DPLoadMultiBlockYuvS] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiBlockYuvS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 14,
+ .combine_fn = c_DPLoadMultiBlockYuvS,
+ .ext = 1,
+ },
+ [gfxd_DPLoadMultiBlockYuv] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiBlockYuv",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 14,
+ .combine_fn = c_DPLoadMultiBlockYuv,
+ .ext = 1,
+ },
+ [gfxd_DPLoadMultiBlock_4bS] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiBlock_4bS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 13,
+ .combine_fn = c_DPLoadMultiBlock_4bS,
+ },
+ [gfxd_DPLoadMultiBlock_4b] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiBlock_4b",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 13,
+ .combine_fn = c_DPLoadMultiBlock_4b,
+ },
+ [gfxd_DPLoadMultiBlockS] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiBlockS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 14,
+ .combine_fn = c_DPLoadMultiBlockS,
+ },
+ [gfxd_DPLoadMultiBlock] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiBlock",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 14,
+ .combine_fn = c_DPLoadMultiBlock,
+ },
+ [gfxd__DPLoadTextureBlockYuvS] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureBlockYuvS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 13,
+ .combine_fn = c__DPLoadTextureBlockYuvS,
+ .ext = 1,
+ },
+ [gfxd__DPLoadTextureBlockYuv] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureBlockYuv",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 13,
+ .combine_fn = c__DPLoadTextureBlockYuv,
+ .ext = 1,
+ },
+ [gfxd__DPLoadTextureBlock_4bS] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureBlock_4bS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 12,
+ .combine_fn = c__DPLoadTextureBlock_4bS,
+ .ext = 1,
+ },
+ [gfxd__DPLoadTextureBlock_4b] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureBlock_4b",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 12,
+ .combine_fn = c__DPLoadTextureBlock_4b,
+ },
+ [gfxd__DPLoadTextureBlockS] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureBlockS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 13,
+ .combine_fn = c__DPLoadTextureBlockS,
+ .ext = 1,
+ },
+ [gfxd__DPLoadTextureBlock] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureBlock",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 13,
+ .combine_fn = c__DPLoadTextureBlock,
+ },
+ [gfxd_DPLoadTextureBlockYuvS] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureBlockYuvS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 12,
+ .combine_fn = c_DPLoadTextureBlockYuvS,
+ .ext = 1,
+ },
+ [gfxd_DPLoadTextureBlockYuv] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureBlockYuv",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 12,
+ .combine_fn = c_DPLoadTextureBlockYuv,
+ .ext = 1,
+ },
+ [gfxd_DPLoadTextureBlock_4bS] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureBlock_4bS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 11,
+ .combine_fn = c_DPLoadTextureBlock_4bS,
+ },
+ [gfxd_DPLoadTextureBlock_4b] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureBlock_4b",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 11,
+ .combine_fn = c_DPLoadTextureBlock_4b,
+ },
+ [gfxd_DPLoadTextureBlockS] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureBlockS",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 12,
+ .combine_fn = c_DPLoadTextureBlockS,
+ },
+ [gfxd_DPLoadTextureBlock] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureBlock",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 12,
+ .combine_fn = c_DPLoadTextureBlock,
+ },
+ [gfxd_DPLoadMultiTileYuv] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiTileYuv",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 18,
+ .combine_fn = c_DPLoadMultiTileYuv,
+ .ext = 1,
+ },
+ [gfxd_DPLoadMultiTile_4b] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiTile_4b",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 17,
+ .combine_fn = c_DPLoadMultiTile_4b,
+ },
+ [gfxd_DPLoadMultiTile] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadMultiTile",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 18,
+ .combine_fn = c_DPLoadMultiTile,
+ },
+ [gfxd__DPLoadTextureTileYuv] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureTileYuv",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 17,
+ .combine_fn = c__DPLoadTextureTileYuv,
+ .ext = 1,
+ },
+ [gfxd__DPLoadTextureTile_4b] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureTile_4b",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 16,
+ .combine_fn = c__DPLoadTextureTile_4b,
+ .ext = 1,
+ },
+ [gfxd__DPLoadTextureTile] =
+ {
+ .prefix = "_",
+ .suffix = "DPLoadTextureTile",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 17,
+ .combine_fn = c__DPLoadTextureTile,
+ .ext = 1,
+ },
+ [gfxd_DPLoadTextureTileYuv] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureTileYuv",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 16,
+ .combine_fn = c_DPLoadTextureTileYuv,
+ .ext = 1,
+ },
+ [gfxd_DPLoadTextureTile_4b] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureTile_4b",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 15,
+ .combine_fn = c_DPLoadTextureTile_4b,
+ },
+ [gfxd_DPLoadTextureTile] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTextureTile",
+ .opcode = G_SETTIMG,
+ .n_gfx = 7,
+ .n_arg = 16,
+ .combine_fn = c_DPLoadTextureTile,
+ },
+ [gfxd_DPLoadBlock] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadBlock",
+ .opcode = G_LOADBLOCK,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .disas_fn = d_DPLoadBlock,
+ },
+ [gfxd_DPNoOp] =
+ {
+ .prefix = NULL,
+ .suffix = "DPNoOp",
+ .opcode = G_NOOP,
+ .n_gfx = 1,
+ .n_arg = 0,
+ .alias = gfxd_DPNoOpTag,
+ },
+ [gfxd_DPNoOpTag] =
+ {
+ .prefix = NULL,
+ .suffix = "DPNoOpTag",
+ .opcode = G_NOOP,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_DPNoOpTag,
+ },
+ [gfxd_DPPipelineMode] =
+ {
+ .prefix = NULL,
+ .suffix = "DPPipelineMode",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetBlendColor] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetBlendColor",
+ .opcode = G_SETBLENDCOLOR,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_DPSetBlendColor,
+ },
+ [gfxd_DPSetEnvColor] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetEnvColor",
+ .opcode = G_SETENVCOLOR,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_DPSetEnvColor,
+ },
+ [gfxd_DPSetFillColor] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetFillColor",
+ .opcode = G_SETFILLCOLOR,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_DPSetFillColor,
+ },
+ [gfxd_DPSetFogColor] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetFogColor",
+ .opcode = G_SETFOGCOLOR,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_DPSetFogColor,
+ },
+ [gfxd_DPSetPrimColor] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetPrimColor",
+ .opcode = G_SETPRIMCOLOR,
+ .n_gfx = 1,
+ .n_arg = 6,
+ .disas_fn = d_DPSetPrimColor,
+ },
+ [gfxd_DPSetColorImage] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetColorImage",
+ .opcode = G_SETCIMG,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_DPSetColorImage,
+ },
+ [gfxd_DPSetDepthImage] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetDepthImage",
+ .opcode = G_SETZIMG,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_DPSetDepthImage,
+ },
+ [gfxd_DPSetTextureImage] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTextureImage",
+ .opcode = G_SETTIMG,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_DPSetTextureImage,
+ },
+ [gfxd_DPSetAlphaCompare] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetAlphaCompare",
+ .opcode = G_SETOTHERMODE_L,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeLo,
+ },
+ [gfxd_DPSetAlphaDither] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetAlphaDither",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetColorDither] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetColorDither",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetCombineMode] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetCombineMode",
+ .opcode = G_SETCOMBINE,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .alias = gfxd_DPSetCombineLERP,
+ },
+ [gfxd_DPSetCombineLERP] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetCombineLERP",
+ .opcode = G_SETCOMBINE,
+ .n_gfx = 1,
+ .n_arg = 16,
+ .disas_fn = d_DPSetCombineLERP,
+ },
+ [gfxd_DPSetConvert] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetConvert",
+ .opcode = G_SETCONVERT,
+ .n_gfx = 1,
+ .n_arg = 6,
+ .disas_fn = d_DPSetConvert,
+ },
+ [gfxd_DPSetTextureConvert] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTextureConvert",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetCycleType] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetCycleType",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetDepthSource] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetDepthSource",
+ .opcode = G_SETOTHERMODE_L,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeLo,
+ },
+ [gfxd_DPSetCombineKey] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetCombineKey",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetKeyGB] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetKeyGB",
+ .opcode = G_SETKEYGB,
+ .n_gfx = 1,
+ .n_arg = 6,
+ .disas_fn = d_DPSetKeyGB,
+ },
+ [gfxd_DPSetKeyR] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetKeyR",
+ .opcode = G_SETKEYR,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .disas_fn = d_DPSetKeyR,
+ },
+ [gfxd_DPSetPrimDepth] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetPrimDepth",
+ .opcode = G_SETPRIMDEPTH,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_DPSetPrimDepth,
+ },
+ [gfxd_DPSetRenderMode] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetRenderMode",
+ .opcode = G_SETOTHERMODE_L,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .alias = gfxd_SPSetOtherModeLo,
+ },
+ [gfxd_DPSetScissor] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetScissor",
+ .opcode = G_SETSCISSOR,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .alias = gfxd_DPSetScissorFrac,
+ },
+ [gfxd_DPSetScissorFrac] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetScissorFrac",
+ .opcode = G_SETSCISSOR,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .disas_fn = d_DPSetScissorFrac,
+ },
+ [gfxd_DPSetTextureDetail] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTextureDetail",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetTextureFilter] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTextureFilter",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetTextureLOD] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTextureLOD",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetTextureLUT] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTextureLUT",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetTexturePersp] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTexturePersp",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPSetOtherModeHi,
+ },
+ [gfxd_DPSetTile] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTile",
+ .opcode = G_SETTILE,
+ .n_gfx = 1,
+ .n_arg = 12,
+ .disas_fn = d_DPSetTile,
+ },
+ [gfxd_DPSetTileSize] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetTileSize",
+ .opcode = G_SETTILESIZE,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .disas_fn = d_DPSetTileSize,
+ },
+ [gfxd_SP1Triangle] =
+ {
+ .prefix = NULL,
+ .suffix = "SP1Triangle",
+ .opcode = G_TRI1,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_SP1Triangle,
+ },
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+ [gfxd_SP2Triangles] =
+ {
+ .prefix = NULL,
+ .suffix = "SP2Triangles",
+ .opcode = G_TRI2,
+ .n_gfx = 1,
+ .n_arg = 8,
+ .disas_fn = d_SP2Triangles,
+ },
+#endif
+#if defined(F3DEX_GBI)
+ [gfxd_SP1Quadrangle] =
+ {
+ .prefix = NULL,
+ .suffix = "SP1Quadrangle",
+ .opcode = G_TRI2,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .alias = gfxd_SP2Triangles,
+ },
+#elif defined(F3DEX_GBI_2)
+ [gfxd_SP1Quadrangle] =
+ {
+ .prefix = NULL,
+ .suffix = "SP1Quadrangle",
+ .opcode = G_QUAD,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .disas_fn = d_SP1Quadrangle,
+ },
+#endif
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+ [gfxd_SPBranchLessZraw] =
+ {
+ .prefix = NULL,
+ .suffix = "SPBranchLessZraw",
+ .opcode = G_RDPHALF_1,
+ .n_gfx = 2,
+ .n_arg = 3,
+ .combine_fn = c_SPBranchLessZraw,
+ },
+#endif
+ [gfxd_SPBranchList] =
+ {
+ .prefix = NULL,
+ .suffix = "SPBranchList",
+ .opcode = G_DL,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_DisplayList,
+ },
+ [gfxd_SPClipRatio] =
+ {
+ .prefix = NULL,
+ .suffix = "SPClipRatio",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 4,
+ .n_arg = 1,
+ .combine_fn = c_SPClipRatio,
+ },
+ [gfxd_SPCullDisplayList] =
+ {
+ .prefix = NULL,
+ .suffix = "SPCullDisplayList",
+ .opcode = G_CULLDL,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_SPCullDisplayList,
+ },
+ [gfxd_SPDisplayList] =
+ {
+ .prefix = NULL,
+ .suffix = "SPDisplayList",
+ .opcode = G_DL,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_DisplayList,
+ },
+ [gfxd_SPEndDisplayList] =
+ {
+ .prefix = NULL,
+ .suffix = "SPEndDisplayList",
+ .opcode = G_ENDDL,
+ .n_gfx = 1,
+ .n_arg = 0,
+ .disas_fn = d_SPEndDisplayList,
+ },
+ [gfxd_SPFogFactor] =
+ {
+ .prefix = NULL,
+ .suffix = "SPFogFactor",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .alias = gfxd_SPFogPosition,
+ },
+ [gfxd_SPFogPosition] =
+ {
+ .prefix = NULL,
+ .suffix = "SPFogPosition",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .alias = gfxd_MoveWd,
+ },
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ [gfxd_SPForceMatrix] =
+ {
+ .prefix = NULL,
+ .suffix = "SPForceMatrix",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 4,
+ .n_arg = 1,
+ .combine_fn = c_SPForceMatrix,
+ },
+ [gfxd_SPSetGeometryMode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetGeometryMode",
+ .opcode = G_SETGEOMETRYMODE,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_SPSetGeometryMode,
+ },
+ [gfxd_SPClearGeometryMode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPClearGeometryMode",
+ .opcode = G_CLEARGEOMETRYMODE,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_SPClearGeometryMode,
+ },
+ [gfxd_SPLoadGeometryMode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLoadGeometryMode",
+ .opcode = G_CLEARGEOMETRYMODE,
+ .n_gfx = 2,
+ .n_arg = 1,
+ .combine_fn = c_SPLoadGeometryMode,
+ },
+#elif defined(F3DEX_GBI_2)
+ [gfxd_SPForceMatrix] =
+ {
+ .prefix = NULL,
+ .suffix = "SPForceMatrix",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 2,
+ .n_arg = 1,
+ .combine_fn = c_SPForceMatrix,
+ },
+ [gfxd_SPSetGeometryMode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetGeometryMode",
+ .opcode = G_GEOMETRYMODE,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPGeometryMode,
+ },
+ [gfxd_SPClearGeometryMode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPClearGeometryMode",
+ .opcode = G_GEOMETRYMODE,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPGeometryMode,
+ },
+ [gfxd_SPLoadGeometryMode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLoadGeometryMode",
+ .opcode = G_GEOMETRYMODE,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPGeometryMode,
+ },
+#endif
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ [gfxd_SPInsertMatrix] =
+ {
+ .prefix = NULL,
+ .suffix = "SPInsertMatrix",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .alias = gfxd_MoveWd,
+ },
+#endif
+ [gfxd_SPLine3D] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLine3D",
+ .opcode = G_LINE3D,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .alias = gfxd_SPLineW3D,
+ },
+ [gfxd_SPLineW3D] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLineW3D",
+ .opcode = G_LINE3D,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_SPLineW3D,
+ },
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+ [gfxd_SPLoadUcode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLoadUcode",
+ .opcode = G_RDPHALF_1,
+ .n_gfx = 2,
+ .n_arg = 2,
+ .combine_fn = c_SPLoadUcode,
+ },
+#endif
+ [gfxd_SPLookAtX] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLookAtX",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_MoveMem,
+ },
+ [gfxd_SPLookAtY] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLookAtY",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_MoveMem,
+ },
+ [gfxd_SPLookAt] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLookAt",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 2,
+ .n_arg = 1,
+ .combine_fn = c_SPLookAt,
+ },
+ [gfxd_SPMatrix] =
+ {
+ .prefix = NULL,
+ .suffix = "SPMatrix",
+ .opcode = G_MTX,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_SPMatrix,
+ },
+#if defined(F3D_GBI) || (defined(F3D_BETA) && defined(F3DEX_GBI))
+ [gfxd_SPModifyVertex] =
+ {
+ .prefix = NULL,
+ .suffix = "SPModifyVertex",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .alias = gfxd_MoveWd,
+ },
+#elif defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+ [gfxd_SPModifyVertex] =
+ {
+ .prefix = NULL,
+ .suffix = "SPModifyVertex",
+ .opcode = G_MODIFYVTX,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .disas_fn = d_SPModifyVertex,
+ },
+#endif
+#if defined(F3D_BETA) && (defined(F3D_GBI) || defined(F3DEX_GBI))
+ [gfxd_SPPerspNormalize] =
+ {
+ .prefix = NULL,
+ .suffix = "SPPerspNormalize",
+ .opcode = G_PERSPNORM,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_SPPerspNormalize,
+ },
+#else
+ [gfxd_SPPerspNormalize] =
+ {
+ .prefix = NULL,
+ .suffix = "SPPerspNormalize",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_MoveWd,
+ },
+#endif
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ [gfxd_SPPopMatrix] =
+ {
+ .prefix = NULL,
+ .suffix = "SPPopMatrix",
+ .opcode = G_POPMTX,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_SPPopMatrix,
+ },
+#elif defined(F3DEX_GBI_2)
+ [gfxd_SPPopMatrix] =
+ {
+ .prefix = NULL,
+ .suffix = "SPPopMatrix",
+ .opcode = G_POPMTX,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_SPPopMatrixN,
+ },
+ [gfxd_SPPopMatrixN] =
+ {
+ .prefix = NULL,
+ .suffix = "SPPopMatrixN",
+ .opcode = G_POPMTX,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_SPPopMatrixN,
+ },
+#endif
+ [gfxd_SPSegment] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSegment",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .alias = gfxd_MoveWd,
+ },
+ [gfxd_SPSetLights1] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetLights1",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 3,
+ .n_arg = 1,
+ .combine_fn = c_SPSetLights1,
+ },
+ [gfxd_SPSetLights2] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetLights2",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 4,
+ .n_arg = 1,
+ .combine_fn = c_SPSetLights2,
+ },
+ [gfxd_SPSetLights3] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetLights3",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 5,
+ .n_arg = 1,
+ .combine_fn = c_SPSetLights3,
+ },
+ [gfxd_SPSetLights4] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetLights4",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 6,
+ .n_arg = 1,
+ .combine_fn = c_SPSetLights4,
+ },
+ [gfxd_SPSetLights5] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetLights5",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 7,
+ .n_arg = 1,
+ .combine_fn = c_SPSetLights5,
+ },
+ [gfxd_SPSetLights6] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetLights6",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 8,
+ .n_arg = 1,
+ .combine_fn = c_SPSetLights6,
+ },
+ [gfxd_SPSetLights7] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetLights7",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 9,
+ .n_arg = 1,
+ .combine_fn = c_SPSetLights7,
+ },
+ [gfxd_SPNumLights] =
+ {
+ .prefix = NULL,
+ .suffix = "SPNumLights",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_MoveWd,
+ },
+ [gfxd_SPLight] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLight",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .alias = gfxd_MoveMem,
+ },
+ [gfxd_SPLightColor] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLightColor",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 2,
+ .n_arg = 2,
+ .combine_fn = c_SPLightColor,
+ },
+ [gfxd_SPTexture] =
+ {
+ .prefix = NULL,
+ .suffix = "SPTexture",
+ .opcode = G_TEXTURE,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .disas_fn = d_SPTexture,
+ },
+ [gfxd_SPTextureRectangle] =
+ {
+ .prefix = NULL,
+ .suffix = "SPTextureRectangle",
+ .opcode = G_TEXRECT,
+ .n_gfx = 3,
+ .n_arg = 9,
+ .combine_fn = c_SPTextureRectangle,
+ },
+ [gfxd_SPTextureRectangleFlip] =
+ {
+ .prefix = NULL,
+ .suffix = "SPTextureRectangleFlip",
+ .opcode = G_TEXRECTFLIP,
+ .n_gfx = 3,
+ .n_arg = 9,
+ .combine_fn = c_SPTextureRectangleFlip,
+ },
+ [gfxd_SPVertex] =
+ {
+ .prefix = NULL,
+ .suffix = "SPVertex",
+ .opcode = G_VTX,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .disas_fn = d_SPVertex,
+ },
+ [gfxd_SPViewport] =
+ {
+ .prefix = NULL,
+ .suffix = "SPViewport",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .alias = gfxd_MoveMem,
+ },
+ [gfxd_DPLoadTLUTCmd] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTLUTCmd",
+ .opcode = G_LOADTLUT,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_DPLoadTLUTCmd,
+ },
+ [gfxd_DPLoadTLUT] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTLUT",
+ .opcode = G_SETTIMG,
+ .n_gfx = 6,
+ .n_arg = 3,
+ .combine_fn = c_DPLoadTLUT,
+ },
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+ [gfxd_BranchZ] =
+ {
+ .prefix = NULL,
+ .suffix = "BranchZ",
+ .opcode = G_BRANCH_Z,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_BranchZ,
+ .ext = 1,
+ },
+#endif
+ [gfxd_DisplayList] =
+ {
+ .prefix = NULL,
+ .suffix = "DisplayList",
+ .opcode = G_DL,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_DisplayList,
+ .ext = 1,
+ },
+ [gfxd_DPHalf1] =
+ {
+ .prefix = NULL,
+ .suffix = "DPHalf1",
+ .opcode = G_RDPHALF_1,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_DPHalf1,
+ .ext = 1,
+ },
+ [gfxd_DPHalf2] =
+ {
+ .prefix = NULL,
+ .suffix = "DPHalf2",
+ .opcode = G_RDPHALF_2,
+ .n_gfx = 1,
+ .n_arg = 1,
+ .disas_fn = d_DPHalf2,
+ .ext = 1,
+ },
+ [gfxd_DPWord] =
+ {
+ .prefix = NULL,
+ .suffix = "DPWord",
+ .opcode = G_RDPHALF_1,
+ .n_gfx = 2,
+ .n_arg = 2,
+ .combine_fn = c_DPWord,
+ },
+ [gfxd_DPLoadTile] =
+ {
+ .prefix = NULL,
+ .suffix = "DPLoadTile",
+ .opcode = G_LOADTILE,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .disas_fn = d_DPLoadTile,
+ },
+#if defined(F3DEX_GBI_2)
+ [gfxd_SPGeometryMode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPGeometryMode",
+ .opcode = G_GEOMETRYMODE,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_SPGeometryMode,
+ },
+#endif
+ [gfxd_SPSetOtherMode] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetOtherMode",
+ .opcode = -1,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_SPSetOtherMode,
+ },
+ [gfxd_SPSetOtherModeLo] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetOtherModeLo",
+ .opcode = G_SETOTHERMODE_L,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .disas_fn = d_SPSetOtherModeLo,
+ .ext = 1,
+ },
+ [gfxd_SPSetOtherModeHi] =
+ {
+ .prefix = NULL,
+ .suffix = "SPSetOtherModeHi",
+ .opcode = G_SETOTHERMODE_H,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .disas_fn = d_SPSetOtherModeHi,
+ .ext = 1,
+ },
+ [gfxd_DPSetOtherMode] =
+ {
+ .prefix = NULL,
+ .suffix = "DPSetOtherMode",
+ .opcode = G_RDPSETOTHERMODE,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_DPSetOtherMode,
+ },
+ [gfxd_MoveWd] =
+ {
+ .prefix = NULL,
+ .suffix = "MoveWd",
+ .opcode = G_MOVEWORD,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .disas_fn = d_MoveWd,
+ },
+#if defined(F3D_GBI) || defined(F3DEX_GBI)
+ [gfxd_MoveMem] =
+ {
+ .prefix = NULL,
+ .suffix = "MoveMem",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .disas_fn = d_MoveMem,
+ .ext = 1,
+ },
+#elif defined(F3DEX_GBI_2)
+ [gfxd_MoveMem] =
+ {
+ .prefix = NULL,
+ .suffix = "MoveMem",
+ .opcode = G_MOVEMEM,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_MoveMem,
+ .ext = 1,
+ },
+#endif
+#if defined(F3DEX_GBI_2)
+ [gfxd_SPDma_io] =
+ {
+ .prefix = NULL,
+ .suffix = "SPDma_io",
+ .opcode = G_DMA_IO,
+ .n_gfx = 1,
+ .n_arg = 4,
+ .disas_fn = d_SPDma_io,
+ },
+ [gfxd_SPDmaRead] =
+ {
+ .prefix = NULL,
+ .suffix = "SPDmaRead",
+ .opcode = G_DMA_IO,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .alias = gfxd_SPDma_io,
+ },
+ [gfxd_SPDmaWrite] =
+ {
+ .prefix = NULL,
+ .suffix = "SPDmaWrite",
+ .opcode = G_DMA_IO,
+ .n_gfx = 1,
+ .n_arg = 3,
+ .alias = gfxd_SPDma_io,
+ },
+#endif
+#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
+ [gfxd_LoadUcode] =
+ {
+ .prefix = NULL,
+ .suffix = "LoadUcode",
+ .opcode = G_LOAD_UCODE,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_LoadUcode,
+ },
+ [gfxd_SPLoadUcodeEx] =
+ {
+ .prefix = NULL,
+ .suffix = "SPLoadUcodeEx",
+ .opcode = G_RDPHALF_1,
+ .n_gfx = 2,
+ .n_arg = 3,
+ .combine_fn = c_SPLoadUcodeEx,
+ },
+#endif
+ [gfxd_TexRect] =
+ {
+ .prefix = NULL,
+ .suffix = "TexRect",
+ .opcode = G_TEXRECT,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .disas_fn = d_TexRect,
+ .ext = 1,
+ },
+ [gfxd_TexRectFlip] =
+ {
+ .prefix = NULL,
+ .suffix = "TexRectFlip",
+ .opcode = G_TEXRECTFLIP,
+ .n_gfx = 1,
+ .n_arg = 5,
+ .disas_fn = d_TexRectFlip,
+ .ext = 1,
+ },
+ [gfxd_SPNoOp] =
+ {
+ .prefix = NULL,
+ .suffix = "SPNoOp",
+ .opcode = G_SPNOOP,
+ .n_gfx = 1,
+ .n_arg = 0,
+ .disas_fn = d_SPNoOp,
+ },
+#if defined(F3DEX_GBI_2)
+ [gfxd_Special3] =
+ {
+ .prefix = NULL,
+ .suffix = "Special3",
+ .opcode = G_SPECIAL_3,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_Special3,
+ .ext = 1,
+ },
+ [gfxd_Special2] =
+ {
+ .prefix = NULL,
+ .suffix = "Special2",
+ .opcode = G_SPECIAL_2,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_Special2,
+ .ext = 1,
+ },
+ [gfxd_Special1] =
+ {
+ .prefix = NULL,
+ .suffix = "Special1",
+ .opcode = G_SPECIAL_1,
+ .n_gfx = 1,
+ .n_arg = 2,
+ .disas_fn = d_Special1,
+ .ext = 1,
+ },
+#endif
+};