diff options
| author | louist103 <35883445+louist103@users.noreply.github.com> | 2021-03-17 18:17:11 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-17 18:17:11 -0400 |
| commit | 9c1cb1fc412443a48944e4cb47f52e220b4b0912 (patch) | |
| tree | ed9a7383004a6e96838f85ad68b538ba540bb105 /lib | |
| parent | 4bf6600a3b67223d5e28d6a1fccfeb54e37d7a77 (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/LICENSE | 21 | ||||
| -rw-r--r-- | lib/libgfxd/Makefile | 19 | ||||
| -rw-r--r-- | lib/libgfxd/README.md | 478 | ||||
| -rw-r--r-- | lib/libgfxd/gbi.h | 3808 | ||||
| -rw-r--r-- | lib/libgfxd/gfxd.c | 863 | ||||
| -rw-r--r-- | lib/libgfxd/gfxd.h | 11 | ||||
| -rw-r--r-- | lib/libgfxd/libgfxd.a | bin | 3348354 -> 0 bytes | |||
| -rw-r--r-- | lib/libgfxd/priv.h | 123 | ||||
| -rw-r--r-- | lib/libgfxd/uc.c | 54 | ||||
| -rw-r--r-- | lib/libgfxd/uc_argfn.c | 1814 | ||||
| -rw-r--r-- | lib/libgfxd/uc_argtbl.c | 490 | ||||
| -rw-r--r-- | lib/libgfxd/uc_f3d.c | 4 | ||||
| -rw-r--r-- | lib/libgfxd/uc_f3db.c | 5 | ||||
| -rw-r--r-- | lib/libgfxd/uc_f3dex.c | 4 | ||||
| -rw-r--r-- | lib/libgfxd/uc_f3dex2.c | 4 | ||||
| -rw-r--r-- | lib/libgfxd/uc_f3dexb.c | 5 | ||||
| -rw-r--r-- | lib/libgfxd/uc_macrofn.c | 2453 | ||||
| -rw-r--r-- | lib/libgfxd/uc_macrotbl.c | 1397 |
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 Binary files differdeleted file mode 100644 index 1f8c0e2..0000000 --- a/lib/libgfxd/libgfxd.a +++ /dev/null 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 = ¯o_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 = ¯o_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 +}; |
