Gfx set command: v2 + Gfx/Vtx dynamic alloc (#718)
* set_gfx_command part 2 * part 3 * get gfx/vtx from name; copy gfx/vtx * gfx/vtx dynamic allocation lua * gfx/vtx_new: don't take level/model/vanilla names * Clean up gbi constants * update example * Isaac review; add gfx_get_next_command and vtx_get_next_vertex * make all commands length 1; missing NULL checks
|
|
@ -57,15 +57,49 @@ exclude_constants = {
|
|||
"src/game/obj_behaviors.c": [ "^o$" ],
|
||||
"src/pc/djui/djui_console.h": [ "CONSOLE_MAX_TMP_BUFFER" ],
|
||||
"src/pc/lua/smlua_hooks.h": [ "MAX_HOOKED_MOD_MENU_ELEMENTS" ],
|
||||
"src/pc/djui/djui_panel_menu.h": [ "RAINBOW_TEXT_LEN" ],
|
||||
"include/PR/gbi.h": ["RM_AA_", "G_RM_", "G_CC_"]
|
||||
"src/pc/djui/djui_panel_menu.h": [ "RAINBOW_TEXT_LEN" ]
|
||||
}
|
||||
|
||||
include_constants = {
|
||||
"include/geo_commands.h": [ "BACKGROUND" ],
|
||||
"include/level_commands.h": [ "WARP_CHECKPOINT", "WARP_NO_CHECKPOINT" ],
|
||||
"src/audio/external.h": [ "SEQ_PLAYER", "DS_" ],
|
||||
"src/pc/mods/mod_storage.h": [ "MAX_KEYS", "MAX_KEY_VALUE_LENGTH" ]
|
||||
"src/pc/mods/mod_storage.h": [ "MAX_KEYS", "MAX_KEY_VALUE_LENGTH" ],
|
||||
"include/PR/gbi.h": [
|
||||
"^G_NOOP$",
|
||||
"^G_SETOTHERMODE_H$",
|
||||
"^G_SETOTHERMODE_L$",
|
||||
"^G_ENDDL$",
|
||||
"^G_DL$",
|
||||
"^G_MOVEMEM$",
|
||||
"^G_MOVEWORD$",
|
||||
"^G_MTX$",
|
||||
"^G_GEOMETRYMODE$",
|
||||
"^G_POPMTX$",
|
||||
"^G_TEXTURE$",
|
||||
"^G_COPYMEM$",
|
||||
"^G_VTX$",
|
||||
"^G_TRI1$",
|
||||
"^G_TRI2$",
|
||||
"^G_SETCIMG$",
|
||||
"^G_SETZIMG$",
|
||||
"^G_SETTIMG$",
|
||||
"^G_SETCOMBINE$",
|
||||
"^G_SETENVCOLOR$",
|
||||
"^G_SETPRIMCOLOR$",
|
||||
"^G_SETBLENDCOLOR$",
|
||||
"^G_SETFOGCOLOR$",
|
||||
"^G_SETFILLCOLOR$",
|
||||
"^G_FILLRECT$",
|
||||
"^G_SETTILE$",
|
||||
"^G_LOADTILE$",
|
||||
"^G_LOADBLOCK$",
|
||||
"^G_SETTILESIZE$",
|
||||
"^G_LOADTLUT$",
|
||||
"^G_SETSCISSOR$",
|
||||
"^G_TEXRECTFLIP$",
|
||||
"^G_TEXRECT$",
|
||||
]
|
||||
}
|
||||
|
||||
pretend_find = [
|
||||
|
|
@ -80,6 +114,13 @@ overrideConstant = {
|
|||
'VERSION_REGION': '"US"',
|
||||
}
|
||||
forced_defines = ['F3DEX_GBI_2']
|
||||
defined_values = {
|
||||
'VERSION_US': True,
|
||||
'VERSION_EU': False,
|
||||
'VERSION_JP': False,
|
||||
'VERSION_SH': False,
|
||||
'F3DEX_GBI_2': True,
|
||||
}
|
||||
|
||||
############################################################################
|
||||
|
||||
|
|
@ -384,7 +425,7 @@ def doc_files(processed_files):
|
|||
|
||||
############################################################################
|
||||
|
||||
def def_constant(processed_constant):
|
||||
def def_constant(processed_constant, skip_constant):
|
||||
global totalConstants
|
||||
constants = processed_constant
|
||||
s = ''
|
||||
|
|
@ -393,7 +434,7 @@ def def_constant(processed_constant):
|
|||
if is_enum:
|
||||
constants = processed_constant['constants']
|
||||
if len(constants) == 0:
|
||||
return ''
|
||||
return '', skip_constant
|
||||
id = translate_to_def(processed_constant['identifier'])
|
||||
klen = 0
|
||||
vlen = 0
|
||||
|
|
@ -407,10 +448,18 @@ def def_constant(processed_constant):
|
|||
s += '\n--- @alias %s\n' % id
|
||||
for c in constants:
|
||||
s += '--- | `%s`\n' % c[0]
|
||||
return s
|
||||
return s, skip_constant
|
||||
|
||||
for c in [processed_constant]:
|
||||
if c[0].startswith('#'):
|
||||
if c[0].startswith('#ifdef'):
|
||||
skip_constant = not defined_values[c[0].split()[1]]
|
||||
elif c[0].startswith('#else'):
|
||||
skip_constant = not skip_constant
|
||||
elif c[0].startswith('#endif'):
|
||||
skip_constant = False
|
||||
continue
|
||||
if skip_constant:
|
||||
continue
|
||||
if '"' in c[1]:
|
||||
s += '\n--- @type string\n'
|
||||
|
|
@ -419,7 +468,7 @@ def def_constant(processed_constant):
|
|||
s += '%s = %s\n' % (c[0], c[1])
|
||||
totalConstants += 1
|
||||
|
||||
return s
|
||||
return s, skip_constant
|
||||
|
||||
def build_to_def(processed_files):
|
||||
s = '-- AUTOGENERATED FOR CODE EDITORS --\n\n'
|
||||
|
|
@ -429,8 +478,10 @@ def build_to_def(processed_files):
|
|||
|
||||
for file in processed_files:
|
||||
constants = file['constants']
|
||||
skip_constant = False
|
||||
for c in constants:
|
||||
s += def_constant(c)
|
||||
cs, skip_constant = def_constant(c, skip_constant)
|
||||
s += cs
|
||||
|
||||
return s
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ override_disallowed_functions = {
|
|||
"src/pc/lua/utils/smlua_level_utils.h": [ "smlua_level_util_reset" ],
|
||||
"src/pc/lua/utils/smlua_text_utils.h": [ "smlua_text_utils_init", "smlua_text_utils_shutdown" ],
|
||||
"src/pc/lua/utils/smlua_anim_utils.h": [ "smlua_anim_util_reset", "smlua_anim_util_register_animation" ],
|
||||
"src/pc/lua/utils/smlua_gfx_utils.h": [ "gfx_allocate_internal", "vtx_allocate_internal", "gfx_get_length_no_sentinel" ],
|
||||
"src/pc/network/lag_compensation.h": [ "lag_compensation_clear" ],
|
||||
"src/game/first_person_cam.h": [ "first_person_update" ],
|
||||
"src/pc/lua/utils/smlua_collision_utils.h": [ "collision_find_surface_on_ray" ],
|
||||
|
|
@ -758,11 +759,30 @@ N/A
|
|||
|
||||
## [gfx_set_command](#gfx_set_command)
|
||||
|
||||
Sets the specified display list command on the display list given.
|
||||
Sets a display list command on the display list given.
|
||||
|
||||
### Lua Example
|
||||
If `command` includes parameter specifiers (subsequences beginning with `%`), the additional arguments following `command` are converted and inserted in `command` replacing their respective specifiers.
|
||||
|
||||
The number of provided parameters must be equal to the number of specifiers in `command`, and the order of parameters must be the same as the specifiers.
|
||||
|
||||
The following specifiers are allowed:
|
||||
- `%i` for an `integer` parameter
|
||||
- `%s` for a `string` parameter
|
||||
- `%v` for a `Vtx` parameter
|
||||
- `%t` for a `Texture` parameter
|
||||
- `%g` for a `Gfx` parameter
|
||||
|
||||
### Lua Examples
|
||||
|
||||
Plain string:
|
||||
```lua
|
||||
gfx_set_command(gfx, "gsDPSetEnvColor", 0x00, 0xFF, 0x00, 0xFF)
|
||||
gfx_set_command(gfx, "gsDPSetEnvColor(0x00, 0xFF, 0x00, 0xFF)")
|
||||
```
|
||||
|
||||
With parameter specifiers:
|
||||
```lua
|
||||
r, g, b, a = 0x00, 0xFF, 0x00, 0xFF
|
||||
gfx_set_command(gfx, "gsDPSetEnvColor(%i, %i, %i, %i)", r, g, b, a)
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
|
@ -770,7 +790,7 @@ gfx_set_command(gfx, "gsDPSetEnvColor", 0x00, 0xFF, 0x00, 0xFF)
|
|||
| ----- | ---- |
|
||||
| gfx | [Gfx](structs.md#Gfx) |
|
||||
| command | `string` |
|
||||
| (Any number of arguments) | `integer` |
|
||||
| parameters... | any of `integer`, `string`, `Gfx`, `Texture`, `Vtx` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ sLuaManuallyDefinedStructs = [{
|
|||
|
||||
override_types = {
|
||||
"Gwords": "Gfx",
|
||||
"Vtx_t": "Vtx"
|
||||
"Vtx_L": "Vtx"
|
||||
}
|
||||
reversed_override_types = {v: k for k, v in override_types.items()}
|
||||
|
||||
|
|
@ -275,6 +275,7 @@ def table_to_string(table):
|
|||
|
||||
def parse_struct(struct_str, sortFields = True):
|
||||
struct = {}
|
||||
struct_str = strip_anonymous_blocks(struct_str) # Allow unions and sub-structs to be accessed
|
||||
match = re.match(r"struct\s*(\w+)?\s*{(.*?)}\s*(\w+)?\s*", struct_str.replace("typedef ", ""), re.DOTALL)
|
||||
struct_name, body, trailing_name = match.groups()
|
||||
identifier = struct_name if struct_name else trailing_name
|
||||
|
|
|
|||
|
|
@ -9698,50 +9698,135 @@ function gfx_parse(cmd, func)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param gfx Pointer_Gfx
|
||||
--- @param offset integer
|
||||
--- @param cmd Pointer_Gfx
|
||||
--- @return integer
|
||||
--- Gets the op of the display list command
|
||||
function gfx_get_op(cmd)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param cmd Pointer_Gfx
|
||||
--- @return Pointer_Gfx
|
||||
--- Gets the display list from a display list command if it has the op `G_DL`
|
||||
function gfx_get_display_list(cmd)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param cmd Pointer_Gfx
|
||||
--- @return Pointer_Vtx
|
||||
--- Gets a vertex from a display list command if it has the correct op. Intended to be used with `gfx_parse`
|
||||
function gfx_get_vtx(gfx, offset)
|
||||
--- Gets the vertex buffer from a display list command if it has the op `G_VTX`
|
||||
function gfx_get_vertex_buffer(cmd)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param cmd Pointer_Gfx
|
||||
--- @return integer
|
||||
--- Gets the number of vertices from a display list command if it has the correct op
|
||||
function gfx_get_vtx_count(cmd)
|
||||
--- Gets the number of vertices from a display list command if it has the op `G_VTX`
|
||||
function gfx_get_vertex_count(cmd)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param gfx Pointer_Gfx
|
||||
--- @param a0 integer
|
||||
--- @param b0 integer
|
||||
--- @param c0 integer
|
||||
--- @param d0 integer
|
||||
--- @param Aa0 integer
|
||||
--- @param Ab0 integer
|
||||
--- @param Ac0 integer
|
||||
--- @param Ad0 integer
|
||||
--- @param a1 integer
|
||||
--- @param b1 integer
|
||||
--- @param c1 integer
|
||||
--- @param d1 integer
|
||||
--- @param Aa1 integer
|
||||
--- @param Ab1 integer
|
||||
--- @param Ac1 integer
|
||||
--- @param Ad1 integer
|
||||
--- Sets the display list combine mode. you can fill this function with G_CCMUX_* and G_ACMUX_* constants
|
||||
function gfx_set_combine_lerp(gfx, a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1)
|
||||
--- @return integer
|
||||
--- Gets the max length of a display list
|
||||
function gfx_get_length(gfx)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param gfx Pointer_Gfx
|
||||
--- @param format integer
|
||||
--- @param size integer
|
||||
--- @param width integer
|
||||
--- @param texture Pointer_integer
|
||||
--- Sets the display list texture image. Pass in textureInfo.texture as `texture`
|
||||
function gfx_set_texture_image(gfx, format, size, width, texture)
|
||||
--- @param offset integer
|
||||
--- @return Pointer_Gfx
|
||||
--- Gets a command of a display list at position `offset`
|
||||
function gfx_get_command(gfx, offset)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param gfx Pointer_Gfx
|
||||
--- @return Pointer_Gfx
|
||||
--- Gets the next command of a given display list pointer. Intended to use in a for loop
|
||||
function gfx_get_next_command(gfx)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param dest Pointer_Gfx
|
||||
--- @param src Pointer_Gfx
|
||||
--- @param length integer
|
||||
--- Copies `length` commands from display list `src` to display list `dest`
|
||||
function gfx_copy(dest, src, length)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param name string
|
||||
--- @param length integer
|
||||
--- @return Pointer_Gfx
|
||||
--- Creates a new named display list of `length` commands
|
||||
function gfx_new(name, length)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param gfx Pointer_Gfx
|
||||
--- @param newLength integer
|
||||
--- @return Pointer_Gfx
|
||||
--- Reallocates a display list created by `gfx_new` to modify its length
|
||||
function gfx_realloc(gfx, newLength)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param gfx Pointer_Gfx
|
||||
--- Deletes a display list created by `gfx_new`
|
||||
function gfx_delete(gfx)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param vtx Pointer_Vtx
|
||||
--- @return integer
|
||||
--- Gets the max count of vertices of a vertex buffer
|
||||
function vtx_get_count(vtx)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param vtx Pointer_Vtx
|
||||
--- @param offset integer
|
||||
--- @return Pointer_Vtx
|
||||
--- Gets a vertex of a vertex buffer at position `offset`
|
||||
function vtx_get_vertex(vtx, offset)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param vtx Pointer_Vtx
|
||||
--- @return Pointer_Vtx
|
||||
--- Gets the next vertex of a given vertex pointer. Intended to use in a for loop
|
||||
function vtx_get_next_vertex(vtx)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param dest Pointer_Vtx
|
||||
--- @param src Pointer_Vtx
|
||||
--- @param count integer
|
||||
--- Copies `count` vertices from vertex buffer `src` to vertex buffer `dest`
|
||||
function vtx_copy(dest, src, count)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param name string
|
||||
--- @param count integer
|
||||
--- @return Pointer_Vtx
|
||||
--- Creates a new named vertex buffer of `count` vertices
|
||||
function vtx_new(name, count)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param vtx Pointer_Vtx
|
||||
--- @param newCount integer
|
||||
--- @return Pointer_Vtx
|
||||
--- Reallocates a vertex buffer created by `vtx_new` to modify its count
|
||||
function vtx_realloc(vtx, newCount)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param vtx Pointer_Vtx
|
||||
--- Deletes a vertex buffer created by `vtx_new`
|
||||
function vtx_delete(vtx)
|
||||
-- ...
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -451,8 +451,39 @@ end
|
|||
|
||||
--- @param gfx Gfx
|
||||
--- @param command string
|
||||
--- @vararg integer Parameters for the command
|
||||
--- Sets the specified display list command on the display list given
|
||||
--- @vararg integer | string | Gfx | Texture | Vtx Parameters for the command
|
||||
--- Sets a display list command on the display list given.
|
||||
---
|
||||
--- If `command` includes parameter specifiers (subsequences beginning with `%`), the additional arguments
|
||||
--- following `command` are converted and inserted in `command` replacing their respective specifiers.
|
||||
---
|
||||
--- The number of provided parameters must be equal to the number of specifiers in `command`,
|
||||
--- and the order of parameters must be the same as the specifiers.
|
||||
---
|
||||
--- The following specifiers are allowed:
|
||||
--- - `%i` for an `integer` parameter
|
||||
--- - `%s` for a `string` parameter
|
||||
--- - `%v` for a `Vtx` parameter
|
||||
--- - `%t` for a `Texture` parameter
|
||||
--- - `%g` for a `Gfx` parameter
|
||||
function gfx_set_command(gfx, command, ...)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param name string
|
||||
--- @return Pointer_Gfx
|
||||
--- @return integer
|
||||
--- Gets a display list of the current mod from its name.
|
||||
--- Returns a pointer to the display list and its length
|
||||
function gfx_get_from_name(name)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param name string
|
||||
--- @return Pointer_Vtx
|
||||
--- @return integer
|
||||
--- Gets a vertex buffer of the current mod from its name.
|
||||
--- Returns a pointer to the vertex buffering and its vertex count
|
||||
function vtx_get_from_name(name)
|
||||
-- ...
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2333,10 +2333,19 @@
|
|||
--- @field public posYaw integer
|
||||
|
||||
--- @class Vtx
|
||||
--- @field public cn integer[]
|
||||
--- @field public a integer
|
||||
--- @field public b integer
|
||||
--- @field public flag integer
|
||||
--- @field public ob number[]
|
||||
--- @field public tc integer[]
|
||||
--- @field public g integer
|
||||
--- @field public nx integer
|
||||
--- @field public ny integer
|
||||
--- @field public nz integer
|
||||
--- @field public r integer
|
||||
--- @field public tu integer
|
||||
--- @field public tv integer
|
||||
--- @field public x number
|
||||
--- @field public y number
|
||||
--- @field public z number
|
||||
|
||||
--- @class Vtx_Interp
|
||||
--- @field public n string
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "types.h"
|
||||
#include "engine/behavior_script.h"
|
||||
#include "game/moving_texture.h"
|
||||
#include "lua.h"
|
||||
|
||||
void *dynos_swap_cmd(void *cmd);
|
||||
|
||||
|
|
@ -79,16 +80,29 @@ struct GraphNode* dynos_model_load_dl(u32* aId, enum ModelPool aModelPool, u8 aL
|
|||
struct GraphNode* dynos_model_store_geo(u32* aId, enum ModelPool aModelPool, void* aAsset, struct GraphNode* aGraphNode);
|
||||
struct GraphNode* dynos_model_get_geo(u32 aId);
|
||||
void dynos_model_overwrite_slot(u32 srcSlot, u32 dstSlot);
|
||||
Gfx *dynos_model_get_writable_display_list(Gfx* gfx);
|
||||
void dynos_model_restore_vanilla_display_lists();
|
||||
u32 dynos_model_get_id_from_asset(void* aAsset);
|
||||
u32 dynos_model_get_id_from_graph_node(struct GraphNode* aGraphNode);
|
||||
void dynos_model_clear_pool(enum ModelPool aModelPool);
|
||||
|
||||
// -- gfx -- //
|
||||
Gfx *dynos_gfx_get_writable_display_list(Gfx* gfx);
|
||||
Gfx *dynos_gfx_get(const char *name, u32 *outLength);
|
||||
Gfx *dynos_gfx_new(const char *name, u32 length);
|
||||
Gfx *dynos_gfx_realloc(Gfx *gfx, u32 newLength);
|
||||
bool dynos_gfx_delete(Gfx *gfx);
|
||||
Vtx *dynos_vtx_get(const char *name, u32 *outCount);
|
||||
Vtx *dynos_vtx_new(const char *name, u32 count);
|
||||
Vtx *dynos_vtx_realloc(Vtx *vtx, u32 newCount);
|
||||
bool dynos_vtx_delete(Vtx *vtx);
|
||||
|
||||
// -- other -- //
|
||||
void dynos_mod_shutdown(void);
|
||||
void dynos_pending_scroll_targets_clear(void);
|
||||
void dynos_add_scroll_target(u32 index, const char *name, u32 offset, u32 size);
|
||||
|
||||
// -- smlua -- //
|
||||
bool dynos_smlua_parse_gfx_command(lua_State *L, Gfx *gfx, const char *command, bool hasSpecifiers, char *errorMsg, u32 errorSize);
|
||||
void dynos_smlua_clear_gfx_command_cache();
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -556,6 +556,7 @@ struct GfxData : NoCopy {
|
|||
DataNodes<Movtex> mMovtexs;
|
||||
DataNodes<MovtexQC> mMovtexQCs;
|
||||
DataNodes<u8> mRooms;
|
||||
DataNodes<void> mRawPointers;
|
||||
|
||||
// Animation data
|
||||
Array<AnimBuffer<s16> *> mAnimValues;
|
||||
|
|
@ -661,6 +662,10 @@ struct LvlCmd {
|
|||
u8 mSize;
|
||||
};
|
||||
|
||||
// modIndex -> itemName -> (itemPointer, itemSize)
|
||||
template <typename T>
|
||||
using ModData = std::map<s32, std::map<std::string, std::pair<T *, u32>>>;
|
||||
|
||||
//
|
||||
// Utils
|
||||
//
|
||||
|
|
@ -886,6 +891,7 @@ void DynOS_Pack_AddTex(PackData* aPackData, DataNode<TexData>* aTexData);
|
|||
// Actor Manager
|
||||
//
|
||||
|
||||
std::map<const void *, ActorGfx> &DynOS_Actor_GetValidActors();
|
||||
void DynOS_Actor_AddCustom(s32 aModIndex, const SysPath &aFilename, const char *aActorName);
|
||||
const void *DynOS_Actor_GetLayoutFromName(const char *aActorName);
|
||||
bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, const char **outToken);
|
||||
|
|
@ -974,10 +980,30 @@ struct GraphNode* DynOS_Model_GetGeo(u32 aId);
|
|||
u32 DynOS_Model_GetIdFromAsset(void* asset);
|
||||
u32 DynOS_Model_GetIdFromGraphNode(struct GraphNode* aNode);
|
||||
void DynOS_Model_OverwriteSlot(u32 srcSlot, u32 dstSlot);
|
||||
Gfx *DynOS_Model_GetWritableDisplayList(Gfx* aGfx);
|
||||
void DynOS_Model_RestoreVanillaDisplayLists();
|
||||
void DynOS_Model_ClearPool(enum ModelPool aModelPool);
|
||||
|
||||
//
|
||||
// Gfx Manager
|
||||
//
|
||||
|
||||
Gfx *DynOS_Gfx_GetWritableDisplayList(Gfx *aGfx);
|
||||
Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength);
|
||||
Gfx *DynOS_Gfx_New(const char *aName, u32 aLength);
|
||||
Gfx *DynOS_Gfx_Realloc(Gfx *aGfx, u32 aNewLength);
|
||||
bool DynOS_Gfx_Delete(Gfx *aGfx);
|
||||
Vtx *DynOS_Vtx_Get(const char *aName, u32 *outCount);
|
||||
Vtx *DynOS_Vtx_New(const char *aName, u32 aCount);
|
||||
Vtx *DynOS_Vtx_Realloc(Vtx *aVtx, u32 aNewCount);
|
||||
bool DynOS_Vtx_Delete(Vtx *aVtx);
|
||||
void DynOS_Gfx_ModShutdown();
|
||||
|
||||
//
|
||||
// Mod Data Manager
|
||||
//
|
||||
|
||||
// template functions
|
||||
#include "dynos_mgr_moddata.hpp"
|
||||
|
||||
//
|
||||
// Bin
|
||||
//
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <new>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <map>
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "config.h"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,31 @@
|
|||
#include "dynos.cpp.h"
|
||||
#include <map>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include "sm64.h"
|
||||
#include "include/textures.h"
|
||||
#include "src/pc/lua/smlua.h"
|
||||
#include "src/pc/lua/utils/smlua_gfx_utils.h"
|
||||
}
|
||||
|
||||
static std::map<std::string, std::pair<Gfx *, u32>> sGfxCommandCache;
|
||||
static char *sGfxCommandErrorMsg = NULL;
|
||||
static u32 sGfxCommandErrorSize = 0;
|
||||
|
||||
#define PrintDataErrorGfx(...) { \
|
||||
if (sGfxCommandErrorMsg) { \
|
||||
snprintf(sGfxCommandErrorMsg, sGfxCommandErrorSize, __VA_ARGS__); \
|
||||
aGfxData->mErrorCount++; \
|
||||
} else { \
|
||||
PrintDataError(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_TOKEN_INDEX(tokenIndex, returnValue) { \
|
||||
if (tokenIndex >= aNode->mTokens.Count()) { \
|
||||
PrintDataErrorGfx(" ERROR: Invalid token index: %llu, tokens count is: %d", tokenIndex, aNode->mTokens.Count()); \
|
||||
return returnValue; \
|
||||
} \
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
|
|
@ -403,6 +426,7 @@ s64 DynOS_Gfx_ParseGfxConstants(const String& _Arg, bool* found) {
|
|||
|
||||
static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode<Gfx>* aNode, u64* pTokenIndex, const char *aPrefix) {
|
||||
assert(aPrefix != NULL);
|
||||
if (pTokenIndex != NULL) { CHECK_TOKEN_INDEX(*pTokenIndex, 0); }
|
||||
String _Token = (pTokenIndex != NULL ? aNode->mTokens[(*pTokenIndex)++] : "");
|
||||
String _Arg("%s%s", aPrefix, _Token.begin());
|
||||
|
||||
|
|
@ -419,6 +443,13 @@ static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode<Gfx>* aNode, u64* pToke
|
|||
return constantValue;
|
||||
}
|
||||
|
||||
// Pointers
|
||||
for (auto& _Node : aGfxData->mRawPointers) {
|
||||
if (_Arg == _Node->mName) {
|
||||
return (s64) _Node->mData;
|
||||
}
|
||||
}
|
||||
|
||||
// Offset
|
||||
s32 _Offset = 0;
|
||||
s32 _Plus = _Arg.Find('+');
|
||||
|
|
@ -534,11 +565,11 @@ static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode<Gfx>* aNode, u64* pToke
|
|||
bool rdSuccess = false;
|
||||
s64 rdValue = DynOS_RecursiveDescent_Parse(_Arg.begin(), &rdSuccess, DynOS_Gfx_ParseGfxConstants);
|
||||
if (rdSuccess) {
|
||||
return (LevelScript)rdValue;
|
||||
return rdValue;
|
||||
}
|
||||
|
||||
// Unknown
|
||||
PrintDataError(" ERROR: Unknown gfx arg: %s", _Arg.begin());
|
||||
PrintDataErrorGfx(" ERROR: Unknown gfx arg: %s", _Arg.begin());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -653,10 +684,11 @@ static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode<Gfx>* aNode, u64* pToke
|
|||
return; \
|
||||
}
|
||||
|
||||
#define gfx_arg_with_suffix(argname, suffix) \
|
||||
#define gfx_arg_with_suffix(argname, suffix) \
|
||||
CHECK_TOKEN_INDEX(aTokenIndex,); \
|
||||
const String& argname##_token = aNode->mTokens[aTokenIndex]; \
|
||||
String _Token##suffix = String("%s%s", argname##_token.begin(), #suffix); \
|
||||
s64 argname = ParseGfxSymbolArg(aGfxData, aNode, NULL, _Token##suffix.begin()); \
|
||||
String _Token##suffix = String("%s%s", argname##_token.begin(), #suffix); \
|
||||
s64 argname = ParseGfxSymbolArg(aGfxData, aNode, NULL, _Token##suffix.begin()); \
|
||||
|
||||
#define STR_VALUE_2(...) #__VA_ARGS__
|
||||
#define STR_VALUE(...) STR_VALUE_2(__VA_ARGS__)
|
||||
|
|
@ -731,11 +763,12 @@ static String ConvertSetCombineModeArgToString(GfxData *aGfxData, const String&
|
|||
gfx_set_combine_mode_arg(G_CC_HILITERGBA2);
|
||||
gfx_set_combine_mode_arg(G_CC_HILITERGBDECALA2);
|
||||
gfx_set_combine_mode_arg(G_CC_HILITERGBPASSA2);
|
||||
PrintDataError(" ERROR: Unknown gfx gsDPSetCombineMode arg: %s", _Arg.begin());
|
||||
PrintDataErrorGfx(" ERROR: Unknown gfx gsDPSetCombineMode arg: %s", _Arg.begin());
|
||||
return "";
|
||||
}
|
||||
|
||||
static Array<s64> ParseGfxSetCombineMode(GfxData* aGfxData, DataNode<Gfx>* aNode, u64* pTokenIndex) {
|
||||
CHECK_TOKEN_INDEX(*pTokenIndex, Array<s64>());
|
||||
String _Buffer = ConvertSetCombineModeArgToString(aGfxData, aNode->mTokens[(*pTokenIndex)++]);
|
||||
Array<s64> _Args;
|
||||
String _Token;
|
||||
|
|
@ -751,7 +784,7 @@ static Array<s64> ParseGfxSetCombineMode(GfxData* aGfxData, DataNode<Gfx>* aNode
|
|||
}
|
||||
}
|
||||
if (_Args.Count() < 8) {
|
||||
PrintDataError(" ERROR: gsDPSetCombineMode %s: Not enough arguments", _Buffer.begin());
|
||||
PrintDataErrorGfx(" ERROR: gsDPSetCombineMode %s: Not enough arguments", _Buffer.begin());
|
||||
}
|
||||
return _Args;
|
||||
}
|
||||
|
|
@ -763,6 +796,13 @@ static void UpdateTextureInfo(GfxData* aGfxData, s64 *aTexPtr, s32 aFormat, s32
|
|||
return;
|
||||
}
|
||||
|
||||
// Skip raw pointers
|
||||
for (const auto &ptrNode : aGfxData->mRawPointers) {
|
||||
if ((void *) *aTexPtr == ptrNode->mData) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aGfxData->mGfxContext.mCurrentTexture = (DataNode<TexData>*) (*aTexPtr);
|
||||
}
|
||||
|
||||
|
|
@ -787,6 +827,7 @@ extern "C" {
|
|||
#define define_gfx_symbol(symb, params, ...) gfx_symbol_##params(symb, ##__VA_ARGS__)
|
||||
|
||||
static void ParseGfxSymbol(GfxData* aGfxData, DataNode<Gfx>* aNode, Gfx*& aHead, u64& aTokenIndex) {
|
||||
CHECK_TOKEN_INDEX(aTokenIndex,);
|
||||
const String& _Symbol = aNode->mTokens[aTokenIndex++];
|
||||
|
||||
// Simple symbols
|
||||
|
|
@ -1073,20 +1114,22 @@ static void ParseGfxSymbol(GfxData* aGfxData, DataNode<Gfx>* aNode, Gfx*& aHead,
|
|||
}
|
||||
|
||||
// Unknown
|
||||
PrintDataError(" ERROR: Unknown gfx symbol: %s", _Symbol.begin());
|
||||
PrintDataErrorGfx(" ERROR: Unknown gfx symbol: %s", _Symbol.begin());
|
||||
}
|
||||
|
||||
DataNode<Gfx>* DynOS_Gfx_Parse(GfxData* aGfxData, DataNode<Gfx>* aNode) {
|
||||
if (aNode->mData) return aNode;
|
||||
|
||||
// Display list data
|
||||
aNode->mData = New<Gfx>(aNode->mTokens.Count() * DISPLAY_LIST_SIZE_PER_TOKEN);
|
||||
u32 _Length = aNode->mTokens.Count() * DISPLAY_LIST_SIZE_PER_TOKEN;
|
||||
aNode->mData = gfx_allocate_internal(_Length);
|
||||
Gfx* _Head = aNode->mData;
|
||||
for (u64 _TokenIndex = 0; _TokenIndex < aNode->mTokens.Count();) { // Don't increment _TokenIndex here!
|
||||
ParseGfxSymbol(aGfxData, aNode, _Head, _TokenIndex);
|
||||
}
|
||||
aNode->mSize = (u32) (_Head - aNode->mData);
|
||||
aNode->mLoadIndex = aGfxData->mLoadIndex++;
|
||||
memmove(aNode->mData + aNode->mSize, aNode->mData + _Length, sizeof(Gfx)); // Move the sentinel to the true end of the display list
|
||||
return aNode;
|
||||
}
|
||||
|
||||
|
|
@ -1128,7 +1171,7 @@ void DynOS_Gfx_Load(BinFile *aFile, GfxData *aGfxData) {
|
|||
|
||||
// Data
|
||||
_Node->mSize = aFile->Read<u32>();
|
||||
_Node->mData = New<Gfx>(_Node->mSize);
|
||||
_Node->mData = gfx_allocate_internal(_Node->mSize);
|
||||
for (u32 i = 0; i != _Node->mSize; ++i) {
|
||||
u32 _WordsW0 = aFile->Read<u32>();
|
||||
u32 _WordsW1 = aFile->Read<u32>();
|
||||
|
|
@ -1144,4 +1187,254 @@ void DynOS_Gfx_Load(BinFile *aFile, GfxData *aGfxData) {
|
|||
|
||||
// Append
|
||||
aGfxData->mDisplayLists.Add(_Node);
|
||||
}
|
||||
|
||||
/////////
|
||||
// Lua //
|
||||
/////////
|
||||
|
||||
//
|
||||
// Parameter specifiers for gfx_set_command:
|
||||
//
|
||||
// %i -> integer
|
||||
// %s -> string
|
||||
// %v -> Vtx pointer
|
||||
// %t -> Texture pointer
|
||||
// %g -> Gfx pointer
|
||||
//
|
||||
|
||||
static String CreateRawPointerDataNode(GfxData *aGfxData, void *pointer) {
|
||||
String ptrNodeName = String("PTR_%016llX", (u64) pointer);
|
||||
DataNode<void> *ptrNode = New<DataNode<void>>();
|
||||
ptrNode->mName = ptrNodeName;
|
||||
ptrNode->mData = pointer;
|
||||
aGfxData->mRawPointers.Add(ptrNode);
|
||||
return ptrNodeName;
|
||||
}
|
||||
|
||||
template <typename T, typename SmluaToFunc, typename ReturnFunc>
|
||||
static String ConvertParam(lua_State *L, GfxData *aGfxData, u32 paramIndex, const char *typeName, const SmluaToFunc &smluaToFunc, const ReturnFunc &returnFunc) {
|
||||
T value = smluaToFunc(L, paramIndex);
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
PrintDataErrorGfx(" ERROR: Failed to convert parameter %u to %s", paramIndex, typeName);
|
||||
return "";
|
||||
}
|
||||
return returnFunc(value);
|
||||
}
|
||||
|
||||
static String ResolveParam(lua_State *L, GfxData *aGfxData, u32 paramIndex, char paramType) {
|
||||
switch (paramType) {
|
||||
|
||||
// Integer
|
||||
case 'i': return ConvertParam<s64>(
|
||||
L, aGfxData, paramIndex,
|
||||
"integer",
|
||||
[] (lua_State *L, u32 paramIndex) { return smlua_to_integer(L, paramIndex); },
|
||||
[] (s64 integer) { return String("%lld", integer); }
|
||||
);
|
||||
|
||||
// String
|
||||
case 's': return ConvertParam<const char *>(
|
||||
L, aGfxData, paramIndex,
|
||||
"string",
|
||||
[] (lua_State *L, u32 paramIndex) { return smlua_to_string(L, paramIndex); },
|
||||
[] (const char *string) { return String(string); }
|
||||
);
|
||||
|
||||
// Vtx pointer
|
||||
case 'v': return ConvertParam<Vtx *>(
|
||||
L, aGfxData, paramIndex,
|
||||
"Vtx pointer",
|
||||
[] (lua_State *L, u32 paramIndex) { return (Vtx *) smlua_to_cobject(L, paramIndex, LOT_VTX); },
|
||||
[&aGfxData] (Vtx *vtx) { return CreateRawPointerDataNode(aGfxData, vtx); }
|
||||
);
|
||||
|
||||
// Texture pointer
|
||||
case 't': return ConvertParam<Texture *>(
|
||||
L, aGfxData, paramIndex,
|
||||
"Texture pointer",
|
||||
[] (lua_State *L, u32 paramIndex) { return (Texture *) smlua_to_cpointer(L, paramIndex, LVT_U8_P); },
|
||||
[&aGfxData] (Texture *texture) { return CreateRawPointerDataNode(aGfxData, texture); }
|
||||
);
|
||||
|
||||
// Gfx pointer
|
||||
case 'g': return ConvertParam<Gfx *>(
|
||||
L, aGfxData, paramIndex,
|
||||
"Gfx pointer",
|
||||
[] (lua_State *L, u32 paramIndex) { return (Gfx *) smlua_to_cobject(L, paramIndex, LOT_GFX); },
|
||||
[&aGfxData] (Gfx *gfx) { return CreateRawPointerDataNode(aGfxData, gfx); }
|
||||
);
|
||||
}
|
||||
PrintDataErrorGfx(" ERROR: Unknown parameter type: '%c'", paramType);
|
||||
return "";
|
||||
}
|
||||
|
||||
static std::string ResolveGfxCommand(lua_State *L, GfxData *aGfxData, const char *command) {
|
||||
std::string output;
|
||||
for (u32 paramIndex = 3; *command; command++) {
|
||||
char c = *command;
|
||||
if (c == '%') {
|
||||
char paramType = *(++command);
|
||||
String value = ResolveParam(L, aGfxData, paramIndex++, paramType);
|
||||
if (aGfxData->mErrorCount > 0) {
|
||||
return "";
|
||||
}
|
||||
output.append(value.begin());
|
||||
} else {
|
||||
output += c;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
static Array<String> TokenizeGfxCommand(const std::string &command) {
|
||||
Array<String> tokens;
|
||||
String token;
|
||||
for (u32 i = 0, scope = 0; i < command.length(); ++i) {
|
||||
char c = command[i];
|
||||
|
||||
// Remove whitespaces
|
||||
if (c <= ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '(') {
|
||||
|
||||
// End of the command name, beginning of the arguments
|
||||
if (scope == 0) {
|
||||
if (!token.Empty()) {
|
||||
tokens.Add(token);
|
||||
token.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// That's an argument
|
||||
else {
|
||||
token.Add(c);
|
||||
}
|
||||
|
||||
scope++;
|
||||
}
|
||||
|
||||
else if (c == ')') {
|
||||
scope--;
|
||||
|
||||
// End of the command
|
||||
if (scope == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// That's an argument
|
||||
else {
|
||||
token.Add(c);
|
||||
}
|
||||
}
|
||||
|
||||
// End of an argument
|
||||
else if (c == ',') {
|
||||
if (!token.Empty()) {
|
||||
tokens.Add(token);
|
||||
token.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
token.Add(c);
|
||||
}
|
||||
}
|
||||
if (!token.Empty()) {
|
||||
tokens.Add(token);
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
static bool CheckGfxLength(GfxData *aGfxData, Gfx *gfx, u32 lengthToWrite) {
|
||||
if (lengthToWrite > 1) {
|
||||
u32 gfxLength = gfx_get_length(gfx);
|
||||
if (gfxLength < lengthToWrite) {
|
||||
PrintDataErrorGfx(" ERROR: Cannot write %u commands to display list of length: %u", lengthToWrite, gfxLength);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ParseGfxCommand(lua_State *L, GfxData *aGfxData, Gfx *gfx, const char *command, bool hasSpecifiers) {
|
||||
|
||||
// Resolve command
|
||||
std::string resolved = hasSpecifiers ? ResolveGfxCommand(L, aGfxData, command) : command;
|
||||
if (aGfxData->mErrorCount > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check cache
|
||||
const auto &it = sGfxCommandCache.find(resolved);
|
||||
if (it != sGfxCommandCache.end()) {
|
||||
const Gfx *src = it->second.first;
|
||||
u32 length = it->second.second;
|
||||
if (!CheckGfxLength(aGfxData, gfx, length)) {
|
||||
return false;
|
||||
}
|
||||
memcpy(gfx, src, length * sizeof(Gfx));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Tokenize command
|
||||
DataNode<Gfx> aNode;
|
||||
aNode.mTokens = TokenizeGfxCommand(resolved);
|
||||
if (aGfxData->mErrorCount > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse tokenized command
|
||||
u64 aTokenIndex = 0;
|
||||
Gfx gfxBuffer[16] = {0};
|
||||
Gfx *gfxHead = gfxBuffer;
|
||||
ParseGfxSymbol(aGfxData, &aNode, gfxHead, aTokenIndex);
|
||||
if (aGfxData->mErrorCount > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cache parsed command
|
||||
u32 commandLength = (u32) (gfxHead - gfxBuffer);
|
||||
size_t commandSize = commandLength * sizeof(Gfx);
|
||||
Gfx *cached = (Gfx *) malloc(commandSize);
|
||||
memcpy(cached, gfxBuffer, commandSize);
|
||||
sGfxCommandCache[resolved] = { cached, commandLength };
|
||||
|
||||
// Copy buffer to gfx
|
||||
if (!CheckGfxLength(aGfxData, gfx, commandLength)) {
|
||||
return false;
|
||||
}
|
||||
memcpy(gfx, gfxBuffer, commandLength * sizeof(Gfx));
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool dynos_smlua_parse_gfx_command(lua_State *L, Gfx *gfx, const char *command, bool hasSpecifiers, char *errorMsg, u32 errorSize) {
|
||||
|
||||
// Parse command
|
||||
GfxData aGfxData;
|
||||
sGfxCommandErrorMsg = errorMsg;
|
||||
sGfxCommandErrorSize = errorSize;
|
||||
bool ok = ParseGfxCommand(L, &aGfxData, gfx, command, hasSpecifiers);
|
||||
|
||||
// Clear stuff
|
||||
sGfxCommandErrorMsg = NULL;
|
||||
sGfxCommandErrorSize = 0;
|
||||
for (auto &ptrNode : aGfxData.mRawPointers) {
|
||||
Delete(ptrNode);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void dynos_smlua_clear_gfx_command_cache() {
|
||||
for (auto &cached : sGfxCommandCache) {
|
||||
free(cached.second.first);
|
||||
}
|
||||
sGfxCommandCache.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "dynos.cpp.h"
|
||||
extern "C" {
|
||||
#include "engine/graph_node.h"
|
||||
#include "pc/lua/utils/smlua_gfx_utils.h"
|
||||
}
|
||||
|
||||
#define F32VTX_SENTINEL_0 0x3346
|
||||
|
|
@ -34,7 +35,7 @@ DataNode<Vtx>* DynOS_Vtx_Parse(GfxData* aGfxData, DataNode<Vtx>* aNode) {
|
|||
|
||||
// Vertex data
|
||||
aNode->mSize = (u32) (aNode->mTokens.Count() / 10);
|
||||
aNode->mData = New<Vtx>(aNode->mSize);
|
||||
aNode->mData = vtx_allocate_internal(aNode->mSize);
|
||||
for (u32 i = 0; i != aNode->mSize; ++i) {
|
||||
f32 px = (f32) aNode->mTokens[10 * i + 0].ParseFloat();
|
||||
f32 py = (f32) aNode->mTokens[10 * i + 1].ParseFloat();
|
||||
|
|
@ -115,7 +116,7 @@ void DynOS_Vtx_Load(BinFile *aFile, GfxData *aGfxData) {
|
|||
// Data
|
||||
bool isUsingF32Vtx = false;
|
||||
_Node->mSize = aFile->Read<u32>();
|
||||
_Node->mData = New<Vtx>(_Node->mSize);
|
||||
_Node->mData = vtx_allocate_internal(_Node->mSize);
|
||||
for (u32 i = 0; i != _Node->mSize; ++i) {
|
||||
if (isUsingF32Vtx) {
|
||||
_Node->mData[i].n.ob[0] = aFile->Read<f32>();
|
||||
|
|
|
|||
|
|
@ -270,12 +270,42 @@ void dynos_model_overwrite_slot(u32 srcSlot, u32 dstSlot) {
|
|||
DynOS_Model_OverwriteSlot(srcSlot, dstSlot);
|
||||
}
|
||||
|
||||
Gfx *dynos_model_get_writable_display_list(Gfx* gfx) {
|
||||
return DynOS_Model_GetWritableDisplayList(gfx);
|
||||
// -- gfx -- //
|
||||
|
||||
Gfx *dynos_gfx_get_writable_display_list(Gfx* gfx) {
|
||||
return DynOS_Gfx_GetWritableDisplayList(gfx);
|
||||
}
|
||||
|
||||
void dynos_model_restore_vanilla_display_lists() {
|
||||
return DynOS_Model_RestoreVanillaDisplayLists();
|
||||
Gfx *dynos_gfx_get(const char *name, u32 *outLength) {
|
||||
return DynOS_Gfx_Get(name, outLength);
|
||||
}
|
||||
|
||||
Gfx *dynos_gfx_new(const char *name, u32 length) {
|
||||
return DynOS_Gfx_New(name, length);
|
||||
}
|
||||
|
||||
Gfx *dynos_gfx_realloc(Gfx *gfx, u32 newLength) {
|
||||
return DynOS_Gfx_Realloc(gfx, newLength);
|
||||
}
|
||||
|
||||
bool dynos_gfx_delete(Gfx *gfx) {
|
||||
return DynOS_Gfx_Delete(gfx);
|
||||
}
|
||||
|
||||
Vtx *dynos_vtx_get(const char *name, u32 *outCount) {
|
||||
return DynOS_Vtx_Get(name, outCount);
|
||||
}
|
||||
|
||||
Vtx *dynos_vtx_new(const char *name, u32 count) {
|
||||
return DynOS_Vtx_New(name, count);
|
||||
}
|
||||
|
||||
Vtx *dynos_vtx_realloc(Vtx *vtx, u32 newCount) {
|
||||
return DynOS_Vtx_Realloc(vtx, newCount);
|
||||
}
|
||||
|
||||
bool dynos_vtx_delete(Vtx *vtx) {
|
||||
return DynOS_Vtx_Delete(vtx);
|
||||
}
|
||||
|
||||
// -- other -- //
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ void DynOS_Mod_Update() {
|
|||
DynOS_Bhv_ModShutdown();
|
||||
DynOS_MovtexQC_ModShutdown();
|
||||
DynOS_Tex_ModShutdown();
|
||||
DynOS_Gfx_ModShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ static Array<Pair<const char*, void *>>& DynosCustomActors() {
|
|||
// TODO: the cleanup/refactor didn't really go as planned.
|
||||
// clean up the actor management code more
|
||||
|
||||
std::map<const void *, ActorGfx> &DynOS_Actor_GetValidActors() {
|
||||
return DynosValidActors();
|
||||
}
|
||||
|
||||
void DynOS_Actor_AddCustom(s32 aModIndex, const SysPath &aFilename, const char *aActorName) {
|
||||
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
|
||||
|
||||
|
|
|
|||
230
data/dynos_mgr_gfx.cpp
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
#include "dynos.cpp.h"
|
||||
|
||||
extern "C" {
|
||||
#include "pc/lua/smlua.h"
|
||||
#include "pc/lua/utils/smlua_gfx_utils.h"
|
||||
}
|
||||
|
||||
static ModData<Gfx> sModDisplayLists;
|
||||
static ModData<Vtx> sModVertexBuffers;
|
||||
|
||||
// Maps read-only Gfx and Vtx buffers to their writable duplicates
|
||||
static std::map<const void *, std::pair<void *, size_t>> sRomToRamGfxVtxMap;
|
||||
|
||||
static Vtx *DynOS_Vtx_Duplicate(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) {
|
||||
if (!aVtx) { return NULL; }
|
||||
|
||||
// Return duplicate if it already exists
|
||||
auto it = sRomToRamGfxVtxMap.find(aVtx);
|
||||
if (it != sRomToRamGfxVtxMap.end()) {
|
||||
return (Vtx *) it->second.first;
|
||||
}
|
||||
|
||||
// Duplicate vertex buffer and return the copy
|
||||
if (shouldDuplicate) {
|
||||
size_t vtxSize = vtxCount * sizeof(Vtx);
|
||||
Vtx *vtxDuplicate = vtx_allocate_internal(vtxCount);
|
||||
memcpy(vtxDuplicate, aVtx, vtxSize);
|
||||
DynOS_Find_Pending_Scroll_Target(aVtx, vtxDuplicate);
|
||||
sRomToRamGfxVtxMap[aVtx] = { (void *) vtxDuplicate, vtxSize };
|
||||
return vtxDuplicate;
|
||||
}
|
||||
|
||||
return aVtx;
|
||||
}
|
||||
|
||||
static Gfx *DynOS_Gfx_Duplicate(Gfx *aGfx, bool shouldDuplicate) {
|
||||
if (!aGfx) { return NULL; }
|
||||
|
||||
// Return duplicate if it already exists
|
||||
auto it = sRomToRamGfxVtxMap.find(aGfx);
|
||||
if (it != sRomToRamGfxVtxMap.end()) {
|
||||
return (Gfx *) it->second.first;
|
||||
}
|
||||
|
||||
// Check if it's vanilla
|
||||
if (!shouldDuplicate) {
|
||||
shouldDuplicate = (DynOS_Builtin_Gfx_GetFromData(aGfx) != NULL);
|
||||
}
|
||||
|
||||
// Duplicate display list
|
||||
Gfx *gfxDuplicate = aGfx;
|
||||
u32 gfxLength = shouldDuplicate ? gfx_get_length_no_sentinel(aGfx) : gfx_get_length(aGfx);
|
||||
if (shouldDuplicate) {
|
||||
size_t gfxSize = gfxLength * sizeof(Gfx);
|
||||
gfxDuplicate = gfx_allocate_internal(gfxLength);
|
||||
memcpy(gfxDuplicate, aGfx, gfxSize);
|
||||
sRomToRamGfxVtxMap[aGfx] = { (void *) gfxDuplicate, gfxSize };
|
||||
}
|
||||
|
||||
// Look for other display lists or vertices
|
||||
for (u32 i = 0; i < gfxLength; i++) {
|
||||
Gfx *cmd = gfxDuplicate + i;
|
||||
u32 op = GFX_OP(cmd);
|
||||
|
||||
// Duplicate referenced display lists
|
||||
if (op == G_DL) {
|
||||
cmd->words.w1 = (uintptr_t) DynOS_Gfx_Duplicate((Gfx *) cmd->words.w1, shouldDuplicate);
|
||||
if (C0(cmd, 16, 1) == G_DL_NOPUSH) { break; } // This is a branch (jump), end of display list
|
||||
}
|
||||
|
||||
// Duplicate referenced vertices
|
||||
if (op == G_VTX) {
|
||||
cmd->words.w1 = (uintptr_t) DynOS_Vtx_Duplicate((Vtx *) cmd->words.w1, C0(cmd, 12, 8), shouldDuplicate);
|
||||
}
|
||||
}
|
||||
|
||||
return gfxDuplicate;
|
||||
}
|
||||
|
||||
// Get a writable display list so it can be modified by mods
|
||||
// If it's a vanilla display list, duplicate it, so it can be restored later
|
||||
Gfx *DynOS_Gfx_GetWritableDisplayList(Gfx *aGfx) {
|
||||
return DynOS_Gfx_Duplicate(aGfx, false);
|
||||
}
|
||||
|
||||
Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength) {
|
||||
if (!aName) { return NULL; }
|
||||
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
|
||||
|
||||
// Check mod data
|
||||
Gfx *gfx = DynOS_ModData_Get<Gfx>(sModDisplayLists, modIndex, aName, outLength);
|
||||
if (gfx) {
|
||||
return gfx;
|
||||
}
|
||||
|
||||
// Check levels
|
||||
for (auto &lvl : DynOS_Lvl_GetArray()) {
|
||||
if (modIndex == -1 || lvl.second->mModIndex == modIndex) {
|
||||
for (auto &gfx : lvl.second->mDisplayLists) {
|
||||
if (gfx->mName == aName) {
|
||||
*outLength = gfx->mSize;
|
||||
return gfx->mData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check loaded actors
|
||||
for (auto &actor : DynOS_Actor_GetValidActors()) {
|
||||
if (modIndex == -1 || actor.second.mGfxData->mModIndex == modIndex) {
|
||||
for (auto &gfx : actor.second.mGfxData->mDisplayLists) {
|
||||
if (gfx->mName == aName) {
|
||||
*outLength = gfx->mSize;
|
||||
return gfx->mData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check vanilla display lists
|
||||
const Gfx *gfxVanilla = DynOS_Builtin_Gfx_GetFromName(aName);
|
||||
if (gfxVanilla) {
|
||||
auto it = sRomToRamGfxVtxMap.find(gfxVanilla);
|
||||
|
||||
// If not found, duplicate the display list now
|
||||
if (it == sRomToRamGfxVtxMap.end()) {
|
||||
DynOS_Gfx_Duplicate((Gfx *) gfxVanilla, true);
|
||||
it = sRomToRamGfxVtxMap.find(gfxVanilla);
|
||||
}
|
||||
|
||||
*outLength = it->second.second / sizeof(Gfx);
|
||||
return (Gfx *) it->second.first;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Gfx *DynOS_Gfx_New(const char *aName, u32 aLength) {
|
||||
if (!aName || !aLength) { return NULL; }
|
||||
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
|
||||
|
||||
return DynOS_ModData_New(sModDisplayLists, modIndex, aName, aLength, gfx_allocate_internal);
|
||||
}
|
||||
|
||||
Gfx *DynOS_Gfx_Realloc(Gfx *aGfx, u32 aNewLength) {
|
||||
if (!aGfx || !aNewLength) { return NULL; }
|
||||
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
|
||||
|
||||
return DynOS_ModData_Realloc(sModDisplayLists, modIndex, aGfx, aNewLength, gfx_allocate_internal, free);
|
||||
}
|
||||
|
||||
bool DynOS_Gfx_Delete(Gfx *aGfx) {
|
||||
if (!aGfx) { return false; }
|
||||
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
|
||||
|
||||
return DynOS_ModData_Delete(sModDisplayLists, modIndex, aGfx, free);
|
||||
}
|
||||
|
||||
Vtx *DynOS_Vtx_Get(const char *aName, u32 *outCount) {
|
||||
if (!aName) { return NULL; }
|
||||
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
|
||||
|
||||
// Check mod data
|
||||
Vtx *vtx = DynOS_ModData_Get<Vtx>(sModVertexBuffers, modIndex, aName, outCount);
|
||||
if (vtx) {
|
||||
return vtx;
|
||||
}
|
||||
|
||||
// Check levels
|
||||
for (auto &lvl : DynOS_Lvl_GetArray()) {
|
||||
if (modIndex == -1 || lvl.second->mModIndex == modIndex) {
|
||||
for (auto &vtx : lvl.second->mVertices) {
|
||||
if (vtx->mName == aName) {
|
||||
*outCount = vtx->mSize;
|
||||
return vtx->mData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check loaded actors
|
||||
for (auto &actor : DynOS_Actor_GetValidActors()) {
|
||||
if (modIndex == -1 || actor.second.mGfxData->mModIndex == modIndex) {
|
||||
for (auto &vtx : actor.second.mGfxData->mVertices) {
|
||||
if (vtx->mName == aName) {
|
||||
*outCount = vtx->mSize;
|
||||
return vtx->mData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Vtx *DynOS_Vtx_New(const char *aName, u32 aCount) {
|
||||
if (!aName || !aCount) { return NULL; }
|
||||
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
|
||||
|
||||
return DynOS_ModData_New(sModVertexBuffers, modIndex, aName, aCount, vtx_allocate_internal);
|
||||
}
|
||||
|
||||
Vtx *DynOS_Vtx_Realloc(Vtx *aVtx, u32 aNewCount) {
|
||||
if (!aVtx || !aNewCount) { return NULL; }
|
||||
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
|
||||
|
||||
return DynOS_ModData_Realloc(sModVertexBuffers, modIndex, aVtx, aNewCount, vtx_allocate_internal, free);
|
||||
}
|
||||
|
||||
bool DynOS_Vtx_Delete(Vtx *aVtx) {
|
||||
if (!aVtx) { return false; }
|
||||
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
|
||||
|
||||
return DynOS_ModData_Delete(sModVertexBuffers, modIndex, aVtx, free);
|
||||
}
|
||||
|
||||
void DynOS_Gfx_ModShutdown() {
|
||||
|
||||
// Delete all allocated display lists and vertex buffers
|
||||
DynOS_ModData_DeleteAll(sModDisplayLists, free);
|
||||
DynOS_ModData_DeleteAll(sModVertexBuffers, free);
|
||||
|
||||
// Restore vanilla display lists
|
||||
for (auto &it : sRomToRamGfxVtxMap) {
|
||||
const void *original = it.first;
|
||||
void *duplicate = it.second.first;
|
||||
size_t size = it.second.second;
|
||||
memcpy(duplicate, original, size);
|
||||
}
|
||||
}
|
||||
104
data/dynos_mgr_moddata.hpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
|
||||
template <typename T>
|
||||
T *DynOS_ModData_Get(ModData<T> &aModData, s32 aModIndex, const char *aName, u32 *outCount) {
|
||||
if (!aName) { return NULL; }
|
||||
|
||||
auto itMod = aModData.find(aModIndex);
|
||||
if (itMod == aModData.end()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto itItem = itMod->second.find(aName);
|
||||
if (itItem == itMod->second.end()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (outCount) {
|
||||
*outCount = itItem->second.second;
|
||||
}
|
||||
return itItem->second.first;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool DynOS_ModData_Find(ModData<T> &aModData, s32 aModIndex, T *aPointer, std::string &outName) {
|
||||
if (!aPointer) { return false; }
|
||||
|
||||
auto itMod = aModData.find(aModIndex);
|
||||
if (itMod == aModData.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto &modItem : itMod->second) {
|
||||
if (modItem.second.first == aPointer) {
|
||||
outName = modItem.first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
T *DynOS_ModData_New(ModData<T> &aModData, s32 aModIndex, const char *aName, u32 aCount, Allocator aAllocator) {
|
||||
if (!aName || !aCount) { return NULL; }
|
||||
|
||||
if (DynOS_ModData_Get(aModData, aModIndex, aName, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto itMod = aModData.find(aModIndex);
|
||||
if (itMod == aModData.end()) {
|
||||
aModData[aModIndex] = {};
|
||||
}
|
||||
|
||||
T *newItem = aAllocator(aCount);
|
||||
aModData[aModIndex][aName] = { newItem, aCount };
|
||||
return newItem;
|
||||
}
|
||||
|
||||
template <typename T, typename Allocator, typename Deallocator>
|
||||
T *DynOS_ModData_Realloc(ModData<T> &aModData, s32 aModIndex, T *aPointer, u32 aNewCount, Allocator aAllocator, Deallocator aDeallocator) {
|
||||
if (!aPointer) { return NULL; }
|
||||
|
||||
std::string itemName;
|
||||
if (!DynOS_ModData_Find(aModData, aModIndex, aPointer, itemName)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// No need to shrink the existing buffer
|
||||
auto &modItem = aModData[aModIndex][itemName];
|
||||
u32 itemCount = modItem.second;
|
||||
if (aNewCount < itemCount) {
|
||||
return modItem.first;
|
||||
}
|
||||
|
||||
T *newItem = aAllocator(aNewCount);
|
||||
memcpy(newItem, aPointer, itemCount * sizeof(T));
|
||||
aDeallocator(aPointer);
|
||||
aModData[aModIndex][itemName] = { newItem, aNewCount };
|
||||
return newItem;
|
||||
}
|
||||
|
||||
template <typename T, typename Deallocator>
|
||||
bool DynOS_ModData_Delete(ModData<T> &aModData, s32 aModIndex, T *aPointer, Deallocator aDeallocator) {
|
||||
if (!aPointer) { return false; }
|
||||
|
||||
std::string itemName;
|
||||
if (!DynOS_ModData_Find(aModData, aModIndex, aPointer, itemName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aDeallocator(aPointer);
|
||||
aModData[aModIndex].erase(itemName);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename Deallocator>
|
||||
void DynOS_ModData_DeleteAll(ModData<T> &aModData, Deallocator aDeallocator) {
|
||||
for (auto &modItems : aModData) {
|
||||
for (auto &modItem : modItems.second) {
|
||||
aDeallocator(modItem.second.first);
|
||||
}
|
||||
}
|
||||
aModData.clear();
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
#include "dynos.cpp.h"
|
||||
|
||||
|
|
@ -7,8 +6,6 @@ extern "C" {
|
|||
#include "engine/graph_node.h"
|
||||
#include "model_ids.h"
|
||||
#include "pc/lua/utils/smlua_model_utils.h"
|
||||
#include "engine/display_list.h"
|
||||
#include "dynos_mgr_builtin_externs.h"
|
||||
}
|
||||
|
||||
enum ModelLoadType {
|
||||
|
|
@ -30,9 +27,6 @@ static std::map<void*, struct ModelInfo> sAssetMap[MODEL_POOL_MAX];
|
|||
static std::map<u32, std::vector<struct ModelInfo>> sIdMap;
|
||||
static std::map<u32, u32> sOverwriteMap;
|
||||
|
||||
// Maps read-only Gfx and Vtx buffers to their writable duplicates
|
||||
static std::map<void *, std::pair<void *, size_t>> sRomToRamGfxVtxMap;
|
||||
|
||||
static u32 find_empty_id(bool aIsPermanent) {
|
||||
u32 id = aIsPermanent ? 9999 : VANILLA_ID_END + 1;
|
||||
s8 dir = aIsPermanent ? -1 : 1;
|
||||
|
|
@ -247,87 +241,6 @@ void DynOS_Model_OverwriteSlot(u32 srcSlot, u32 dstSlot) {
|
|||
sOverwriteMap[srcSlot] = dstSlot;
|
||||
}
|
||||
|
||||
static Vtx *DynOS_Model_DuplicateVtx(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) {
|
||||
if (!aVtx) { return NULL; }
|
||||
|
||||
// Return duplicate if it already exists
|
||||
auto it = sRomToRamGfxVtxMap.find((void *) aVtx);
|
||||
if (it != sRomToRamGfxVtxMap.end()) {
|
||||
return (Vtx *) it->second.first;
|
||||
}
|
||||
|
||||
// Duplicate vertex buffer and return the copy
|
||||
if (shouldDuplicate) {
|
||||
size_t vtxSize = vtxCount * sizeof(Vtx);
|
||||
Vtx *vtxDuplicate = (Vtx *) malloc(vtxSize);
|
||||
memcpy(vtxDuplicate, aVtx, vtxSize);
|
||||
DynOS_Find_Pending_Scroll_Target(aVtx, vtxDuplicate);
|
||||
sRomToRamGfxVtxMap[(void *) aVtx] = { (void *) vtxDuplicate, vtxSize };
|
||||
return vtxDuplicate;
|
||||
}
|
||||
|
||||
return aVtx;
|
||||
}
|
||||
|
||||
static Gfx *DynOS_Model_DuplicateDisplayList(Gfx *aGfx, bool shouldDuplicate) {
|
||||
if (!aGfx) { return NULL; }
|
||||
|
||||
// Return duplicate if it already exists
|
||||
auto it = sRomToRamGfxVtxMap.find((void *) aGfx);
|
||||
if (it != sRomToRamGfxVtxMap.end()) {
|
||||
return (Gfx *) it->second.first;
|
||||
}
|
||||
|
||||
// Check if it's vanilla
|
||||
if (!shouldDuplicate) {
|
||||
shouldDuplicate = (DynOS_Builtin_Gfx_GetFromData(aGfx) != NULL);
|
||||
}
|
||||
|
||||
// Duplicate display list
|
||||
Gfx *gfxDuplicate = aGfx;
|
||||
u32 gfxLength = gfx_get_size(aGfx);
|
||||
if (shouldDuplicate) {
|
||||
size_t gfxSize = gfxLength * sizeof(Gfx);
|
||||
gfxDuplicate = (Gfx *) malloc(gfxSize);
|
||||
memcpy(gfxDuplicate, aGfx, gfxSize);
|
||||
sRomToRamGfxVtxMap[(void *) aGfx] = { (void *) gfxDuplicate, gfxSize };
|
||||
}
|
||||
|
||||
// Look for other display lists or vertices
|
||||
for (u32 i = 0; i < gfxLength; i++) {
|
||||
Gfx *cmd = gfxDuplicate + i;
|
||||
u32 op = cmd->words.w0 >> 24;
|
||||
|
||||
// Duplicate referenced display lists
|
||||
if (op == G_DL) {
|
||||
cmd->words.w1 = (uintptr_t) DynOS_Model_DuplicateDisplayList((Gfx *) cmd->words.w1, shouldDuplicate);
|
||||
if (C0(cmd, 16, 1) == G_DL_NOPUSH) { break; } // This is a branch (jump), end of display list
|
||||
}
|
||||
|
||||
// Duplicate referenced vertices
|
||||
if (op == G_VTX) {
|
||||
cmd->words.w1 = (uintptr_t) DynOS_Model_DuplicateVtx((Vtx *) cmd->words.w1, C0(cmd, 12, 8), shouldDuplicate);
|
||||
}
|
||||
}
|
||||
|
||||
return gfxDuplicate;
|
||||
}
|
||||
|
||||
// Get a writable display list so it can be modified by mods
|
||||
// If it's a vanilla display list, duplicate it, so it can be restored later
|
||||
Gfx *DynOS_Model_GetWritableDisplayList(Gfx *aGfx) {
|
||||
return DynOS_Model_DuplicateDisplayList(aGfx, false);
|
||||
}
|
||||
|
||||
void DynOS_Model_RestoreVanillaDisplayLists() {
|
||||
for (auto &it : sRomToRamGfxVtxMap) {
|
||||
const void *original = it.first;
|
||||
void *duplicate = it.second.first;
|
||||
size_t size = it.second.second;
|
||||
memcpy(duplicate, original, size);
|
||||
}
|
||||
}
|
||||
|
||||
void DynOS_Model_ClearPool(enum ModelPool aModelPool) {
|
||||
if (!sModelPools[aModelPool]) { return; }
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ static Array<DataNode<TexData> *>& DynosScheduledInvalidTextures() {
|
|||
return sDynosScheduledInvalidTextures;
|
||||
}
|
||||
|
||||
static Array<Pair<const char*, DataNode<TexData>*>>& DynosCustomTexs() {
|
||||
static Array<Pair<const char*, DataNode<TexData>*>> sDynosCustomTexs;
|
||||
return sDynosCustomTexs;
|
||||
}
|
||||
|
||||
static bool sDynosDumpTextureCache = false;
|
||||
|
||||
//
|
||||
|
|
@ -329,6 +334,15 @@ static DataNode<TexData> *DynOS_Tex_RetrieveNode(void *aPtr) {
|
|||
if (_ValidTextures.find((DataNode<TexData>*)aPtr) != _ValidTextures.end()) {
|
||||
return (DataNode<TexData>*)aPtr;
|
||||
}
|
||||
|
||||
auto& _DynosCustomTexs = DynosCustomTexs();
|
||||
for (auto &_DynosCustomTex : _DynosCustomTexs) {
|
||||
auto& _Node = _DynosCustomTex.second;
|
||||
if (aPtr == (void *) _Node->mData->mRawData.begin()) {
|
||||
return _Node;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -360,11 +374,6 @@ bool DynOS_Tex_Import(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, voi
|
|||
// Custom Textures //
|
||||
/////////////////////
|
||||
|
||||
static Array<Pair<const char*, DataNode<TexData>*>>& DynosCustomTexs() {
|
||||
static Array<Pair<const char*, DataNode<TexData>*>> sDynosCustomTexs;
|
||||
return sDynosCustomTexs;
|
||||
}
|
||||
|
||||
void DynOS_Tex_Activate(DataNode<TexData>* aNode, bool aCustomTexture) {
|
||||
if (!aNode) { return; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1237,58 +1237,30 @@
|
|||
## [gbi.h](#gbi.h)
|
||||
- G_COPYMEM
|
||||
- G_NOOP
|
||||
- G_RDPHALF_2
|
||||
- G_SETOTHERMODE_H
|
||||
- G_SETOTHERMODE_L
|
||||
- G_RDPHALF_1
|
||||
- G_SPNOOP
|
||||
- G_ENDDL
|
||||
- G_DL
|
||||
- G_LOAD_UCODE
|
||||
- G_MOVEMEM
|
||||
- G_MOVEWORD
|
||||
- G_MTX
|
||||
- G_GEOMETRYMODE
|
||||
- G_POPMTX
|
||||
- G_TEXTURE
|
||||
- G_DMA_IO
|
||||
- G_SPECIAL_1
|
||||
- G_SPECIAL_2
|
||||
- G_SPECIAL_3
|
||||
- G_VTX
|
||||
- G_MODIFYVTX
|
||||
- G_CULLDL
|
||||
- G_BRANCH_Z
|
||||
- G_TRI1
|
||||
- G_TRI2
|
||||
- G_QUAD
|
||||
- G_LINE3D
|
||||
- G_SPNOOP
|
||||
- G_MTX
|
||||
- G_RESERVED0
|
||||
- G_MOVEMEM
|
||||
- G_VTX
|
||||
- G_RESERVED1
|
||||
- G_DL
|
||||
- G_RESERVED2
|
||||
- G_RESERVED3
|
||||
- G_SPRITE2D_BASE
|
||||
- G_IMMFIRST
|
||||
- G_TRI1
|
||||
- G_CULLDL
|
||||
- G_POPMTX
|
||||
- G_MOVEWORD
|
||||
- G_TEXTURE
|
||||
- G_SETOTHERMODE_H
|
||||
- G_SETOTHERMODE_L
|
||||
- G_ENDDL
|
||||
- G_SETGEOMETRYMODE
|
||||
- G_CLEARGEOMETRYMODE
|
||||
- G_LINE3D
|
||||
- G_RDPHALF_1
|
||||
- G_RDPHALF_2
|
||||
- G_SPRITE2D_SCALEFLIP
|
||||
- G_SPRITE2D_DRAW
|
||||
- G_NOOP
|
||||
- G_SETCIMG
|
||||
- G_SETZIMG
|
||||
|
|
@ -1305,316 +1277,9 @@
|
|||
- G_LOADBLOCK
|
||||
- G_SETTILESIZE
|
||||
- G_LOADTLUT
|
||||
- G_RDPSETOTHERMODE
|
||||
- G_SETPRIMDEPTH
|
||||
- G_SETSCISSOR
|
||||
- G_SETCONVERT
|
||||
- G_SETKEYR
|
||||
- G_SETKEYGB
|
||||
- G_RDPFULLSYNC
|
||||
- G_RDPTILESYNC
|
||||
- G_RDPPIPESYNC
|
||||
- G_RDPLOADSYNC
|
||||
- G_TEXRECTFLIP
|
||||
- G_TEXRECT
|
||||
- G_TRI_FILL
|
||||
- G_TRI_SHADE
|
||||
- G_TRI_TXTR
|
||||
- G_TRI_SHADE_TXTR
|
||||
- G_TRI_FILL_ZBUFF
|
||||
- G_TRI_SHADE_ZBUFF
|
||||
- G_TRI_TXTR_ZBUFF
|
||||
- G_TRI_SHADE_TXTR_ZBUFF
|
||||
- G_RDP_TRI_FILL_MASK
|
||||
- G_RDP_TRI_SHADE_MASK
|
||||
- G_RDP_TRI_TXTR_MASK
|
||||
- G_RDP_TRI_ZBUFF_MASK
|
||||
- BOWTIE_VAL
|
||||
- G_RDP_ADDR_FIXUP
|
||||
- G_DMACMDSIZ
|
||||
- G_IMMCMDSIZ
|
||||
- G_RDPCMDSIZ
|
||||
- G_TEXTURE_IMAGE_FRAC
|
||||
- G_TEXTURE_SCALE_FRAC
|
||||
- G_SCALE_FRAC
|
||||
- G_ROTATE_FRAC
|
||||
- G_MAXFBZ
|
||||
- G_ZBUFFER
|
||||
- G_SHADE
|
||||
- G_FOG
|
||||
- G_LIGHTING
|
||||
- G_TEXTURE_GEN
|
||||
- G_TEXTURE_GEN_LINEAR
|
||||
- G_LOD
|
||||
- G_IM_FMT_RGBA
|
||||
- G_IM_FMT_YUV
|
||||
- G_IM_FMT_CI
|
||||
- G_IM_FMT_IA
|
||||
- G_IM_FMT_I
|
||||
- G_IM_SIZ_4b
|
||||
- G_IM_SIZ_8b
|
||||
- G_IM_SIZ_16b
|
||||
- G_IM_SIZ_32b
|
||||
- G_IM_SIZ_DD
|
||||
- G_IM_SIZ_4b_BYTES
|
||||
- G_IM_SIZ_8b_BYTES
|
||||
- G_IM_SIZ_16b_BYTES
|
||||
- G_IM_SIZ_32b_BYTES
|
||||
- G_IM_SIZ_32b_TILE_BYTES
|
||||
- G_IM_SIZ_32b_LINE_BYTES
|
||||
- G_IM_SIZ_4b_SHIFT
|
||||
- G_IM_SIZ_8b_SHIFT
|
||||
- G_IM_SIZ_16b_SHIFT
|
||||
- G_IM_SIZ_32b_SHIFT
|
||||
- G_IM_SIZ_4b_INCR
|
||||
- G_IM_SIZ_8b_INCR
|
||||
- G_IM_SIZ_16b_INCR
|
||||
- G_IM_SIZ_32b_INCR
|
||||
- G_CCMUX_COMBINED
|
||||
- G_CCMUX_TEXEL0
|
||||
- G_CCMUX_TEXEL1
|
||||
- G_CCMUX_PRIMITIVE
|
||||
- G_CCMUX_SHADE
|
||||
- G_CCMUX_ENVIRONMENT
|
||||
- G_CCMUX_CENTER
|
||||
- G_CCMUX_SCALE
|
||||
- G_CCMUX_COMBINED_ALPHA
|
||||
- G_CCMUX_TEXEL0_ALPHA
|
||||
- G_CCMUX_TEXEL1_ALPHA
|
||||
- G_CCMUX_PRIMITIVE_ALPHA
|
||||
- G_CCMUX_SHADE_ALPHA
|
||||
- G_CCMUX_ENV_ALPHA
|
||||
- G_CCMUX_LOD_FRACTION
|
||||
- G_CCMUX_PRIM_LOD_FRAC
|
||||
- G_CCMUX_NOISE
|
||||
- G_CCMUX_K4
|
||||
- G_CCMUX_K5
|
||||
- G_CCMUX_1
|
||||
- G_CCMUX_0
|
||||
- G_ACMUX_COMBINED
|
||||
- G_ACMUX_TEXEL0
|
||||
- G_ACMUX_TEXEL1
|
||||
- G_ACMUX_PRIMITIVE
|
||||
- G_ACMUX_SHADE
|
||||
- G_ACMUX_ENVIRONMENT
|
||||
- G_ACMUX_LOD_FRACTION
|
||||
- G_ACMUX_PRIM_LOD_FRAC
|
||||
- G_ACMUX_1
|
||||
- G_ACMUX_0
|
||||
- G_MDSFT_ALPHACOMPARE
|
||||
- G_MDSFT_ZSRCSEL
|
||||
- G_MDSFT_RENDERMODE
|
||||
- G_MDSFT_BLENDER
|
||||
- G_MDSFT_BLENDMASK
|
||||
- G_MDSFT_ALPHADITHER
|
||||
- G_MDSFT_RGBDITHER
|
||||
- G_MDSFT_COMBKEY
|
||||
- G_MDSFT_TEXTCONV
|
||||
- G_MDSFT_TEXTFILT
|
||||
- G_MDSFT_TEXTLUT
|
||||
- G_MDSFT_TEXTLOD
|
||||
- G_MDSFT_TEXTDETAIL
|
||||
- G_MDSFT_TEXTPERSP
|
||||
- G_MDSFT_CYCLETYPE
|
||||
- G_MDSFT_COLORDITHER
|
||||
- G_MDSFT_PIPELINE
|
||||
- G_PM_1PRIMITIVE
|
||||
- G_PM_NPRIMITIVE
|
||||
- G_CYC_1CYCLE
|
||||
- G_CYC_2CYCLE
|
||||
- G_CYC_COPY
|
||||
- G_CYC_FILL
|
||||
- G_TP_NONE
|
||||
- G_TP_PERSP
|
||||
- G_TD_CLAMP
|
||||
- G_TD_SHARPEN
|
||||
- G_TD_DETAIL
|
||||
- G_TL_TILE
|
||||
- G_TL_LOD
|
||||
- G_TT_NONE
|
||||
- G_TT_RGBA16
|
||||
- G_TT_IA16
|
||||
- G_TF_POINT
|
||||
- G_TF_AVERAGE
|
||||
- G_TF_BILERP
|
||||
- G_TC_CONV
|
||||
- G_TC_FILTCONV
|
||||
- G_TC_FILT
|
||||
- G_CK_NONE
|
||||
- G_CK_KEY
|
||||
- G_CD_MAGICSQ
|
||||
- G_CD_BAYER
|
||||
- G_CD_NOISE
|
||||
- G_CD_DISABLE
|
||||
- G_CD_ENABLE
|
||||
- G_CD_ENABLE
|
||||
- G_CD_DISABLE
|
||||
- G_AD_PATTERN
|
||||
- G_AD_NOTPATTERN
|
||||
- G_AD_NOISE
|
||||
- G_AD_DISABLE
|
||||
- G_AC_NONE
|
||||
- G_AC_THRESHOLD
|
||||
- G_AC_DITHER
|
||||
- G_ZS_PIXEL
|
||||
- G_ZS_PRIM
|
||||
- AA_EN
|
||||
- Z_CMP
|
||||
- Z_UPD
|
||||
- IM_RD
|
||||
- CLR_ON_CVG
|
||||
- CVG_DST_CLAMP
|
||||
- CVG_DST_WRAP
|
||||
- CVG_DST_FULL
|
||||
- CVG_DST_SAVE
|
||||
- ZMODE_OPA
|
||||
- ZMODE_INTER
|
||||
- ZMODE_XLU
|
||||
- ZMODE_DEC
|
||||
- CVG_X_ALPHA
|
||||
- ALPHA_CVG_SEL
|
||||
- FORCE_BL
|
||||
- TEX_EDGE
|
||||
- G_BL_CLR_IN
|
||||
- G_BL_CLR_MEM
|
||||
- G_BL_CLR_BL
|
||||
- G_BL_CLR_FOG
|
||||
- G_BL_1MA
|
||||
- G_BL_A_MEM
|
||||
- G_BL_A_IN
|
||||
- G_BL_A_FOG
|
||||
- G_BL_A_SHADE
|
||||
- G_BL_1
|
||||
- G_BL_0
|
||||
- G_CV_K0
|
||||
- G_CV_K1
|
||||
- G_CV_K2
|
||||
- G_CV_K3
|
||||
- G_CV_K4
|
||||
- G_CV_K5
|
||||
- G_SC_NON_INTERLACE
|
||||
- G_SC_ODD_INTERLACE
|
||||
- G_SC_EVEN_INTERLACE
|
||||
- G_DL_PUSH
|
||||
- G_DL_NOPUSH
|
||||
- G_MW_MATRIX
|
||||
- G_MW_NUMLIGHT
|
||||
- G_MW_CLIP
|
||||
- G_MW_SEGMENT
|
||||
- G_MW_FOG
|
||||
- G_MW_LIGHTCOL
|
||||
- G_MW_PERSPNORM
|
||||
- G_MWO_NUMLIGHT
|
||||
- G_MWO_CLIP_RNX
|
||||
- G_MWO_CLIP_RNY
|
||||
- G_MWO_CLIP_RPX
|
||||
- G_MWO_CLIP_RPY
|
||||
- G_MWO_SEGMENT_0
|
||||
- G_MWO_SEGMENT_1
|
||||
- G_MWO_SEGMENT_2
|
||||
- G_MWO_SEGMENT_3
|
||||
- G_MWO_SEGMENT_4
|
||||
- G_MWO_SEGMENT_5
|
||||
- G_MWO_SEGMENT_6
|
||||
- G_MWO_SEGMENT_7
|
||||
- G_MWO_SEGMENT_8
|
||||
- G_MWO_SEGMENT_9
|
||||
- G_MWO_SEGMENT_A
|
||||
- G_MWO_SEGMENT_B
|
||||
- G_MWO_SEGMENT_C
|
||||
- G_MWO_SEGMENT_D
|
||||
- G_MWO_SEGMENT_E
|
||||
- G_MWO_SEGMENT_F
|
||||
- G_MWO_FOG
|
||||
- G_MWO_aLIGHT_1
|
||||
- G_MWO_bLIGHT_1
|
||||
- G_MWO_aLIGHT_2
|
||||
- G_MWO_bLIGHT_2
|
||||
- G_MWO_aLIGHT_3
|
||||
- G_MWO_bLIGHT_3
|
||||
- G_MWO_aLIGHT_4
|
||||
- G_MWO_bLIGHT_4
|
||||
- G_MWO_aLIGHT_5
|
||||
- G_MWO_bLIGHT_5
|
||||
- G_MWO_aLIGHT_6
|
||||
- G_MWO_bLIGHT_6
|
||||
- G_MWO_aLIGHT_7
|
||||
- G_MWO_bLIGHT_7
|
||||
- G_MWO_aLIGHT_8
|
||||
- G_MWO_bLIGHT_8
|
||||
- G_MWO_aLIGHT_2
|
||||
- G_MWO_bLIGHT_2
|
||||
- G_MWO_aLIGHT_3
|
||||
- G_MWO_bLIGHT_3
|
||||
- G_MWO_aLIGHT_4
|
||||
- G_MWO_bLIGHT_4
|
||||
- G_MWO_aLIGHT_5
|
||||
- G_MWO_bLIGHT_5
|
||||
- G_MWO_aLIGHT_6
|
||||
- G_MWO_bLIGHT_6
|
||||
- G_MWO_aLIGHT_7
|
||||
- G_MWO_bLIGHT_7
|
||||
- G_MWO_aLIGHT_8
|
||||
- G_MWO_bLIGHT_8
|
||||
- G_MWO_MATRIX_XX_XY_I
|
||||
- G_MWO_MATRIX_XZ_XW_I
|
||||
- G_MWO_MATRIX_YX_YY_I
|
||||
- G_MWO_MATRIX_YZ_YW_I
|
||||
- G_MWO_MATRIX_ZX_ZY_I
|
||||
- G_MWO_MATRIX_ZZ_ZW_I
|
||||
- G_MWO_MATRIX_WX_WY_I
|
||||
- G_MWO_MATRIX_WZ_WW_I
|
||||
- G_MWO_MATRIX_XX_XY_F
|
||||
- G_MWO_MATRIX_XZ_XW_F
|
||||
- G_MWO_MATRIX_YX_YY_F
|
||||
- G_MWO_MATRIX_YZ_YW_F
|
||||
- G_MWO_MATRIX_ZX_ZY_F
|
||||
- G_MWO_MATRIX_ZZ_ZW_F
|
||||
- G_MWO_MATRIX_WX_WY_F
|
||||
- G_MWO_MATRIX_WZ_WW_F
|
||||
- G_MWO_POINT_RGBA
|
||||
- G_MWO_POINT_ST
|
||||
- G_MWO_POINT_XYSCREEN
|
||||
- G_MWO_POINT_ZSCREEN
|
||||
- FR_NEG_FRUSTRATIO_1
|
||||
- FR_POS_FRUSTRATIO_1
|
||||
- FR_NEG_FRUSTRATIO_2
|
||||
- FR_POS_FRUSTRATIO_2
|
||||
- FR_NEG_FRUSTRATIO_3
|
||||
- FR_POS_FRUSTRATIO_3
|
||||
- FR_NEG_FRUSTRATIO_4
|
||||
- FR_POS_FRUSTRATIO_4
|
||||
- FR_NEG_FRUSTRATIO_5
|
||||
- FR_POS_FRUSTRATIO_5
|
||||
- FR_NEG_FRUSTRATIO_6
|
||||
- FR_POS_FRUSTRATIO_6
|
||||
- NUMLIGHTS_0
|
||||
- NUMLIGHTS_1
|
||||
- NUMLIGHTS_2
|
||||
- NUMLIGHTS_3
|
||||
- NUMLIGHTS_4
|
||||
- NUMLIGHTS_5
|
||||
- NUMLIGHTS_6
|
||||
- NUMLIGHTS_7
|
||||
- LIGHT_1
|
||||
- LIGHT_2
|
||||
- LIGHT_3
|
||||
- LIGHT_4
|
||||
- LIGHT_5
|
||||
- LIGHT_6
|
||||
- LIGHT_7
|
||||
- LIGHT_8
|
||||
- G_TX_LOADTILE
|
||||
- G_TX_RENDERTILE
|
||||
- G_TX_NOMIRROR
|
||||
- G_TX_WRAP
|
||||
- G_TX_MIRROR
|
||||
- G_TX_CLAMP
|
||||
- G_TX_NOMASK
|
||||
- G_TX_NOLOD
|
||||
- G_TX_DXT_FRAC
|
||||
- G_TX_LDBLK_MAX_TXL
|
||||
- G_TX_LDBLK_MAX_TXL
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
|||
155
docs/lua/examples/gfx-vtx-demo/a-math.lua
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
--
|
||||
-- Math stuff
|
||||
-- Don't mind this file, it's not relevant to the purpose of this demo.
|
||||
--
|
||||
|
||||
local SHAPE_SIZE = 100
|
||||
local SHAPE_TEXTURE_SIZE = 512
|
||||
|
||||
----------
|
||||
-- Cube --
|
||||
----------
|
||||
|
||||
local CUBE_ROTATIONS = {
|
||||
{ x = 0x0000, y = 0x0000, z = 0 },
|
||||
{ x = 0x0000, y = 0x4000, z = 0 },
|
||||
{ x = 0x0000, y = 0x8000, z = 0 },
|
||||
{ x = 0x0000, y = 0xC000, z = 0 },
|
||||
{ x = 0x4000, y = 0x0000, z = 0 },
|
||||
{ x = 0xC000, y = 0x0000, z = 0 },
|
||||
}
|
||||
|
||||
local CUBE_POINTS = {
|
||||
{ x = -1, y = -1, z = -1, tu = 0, tv = (SHAPE_TEXTURE_SIZE - 1) << 5 },
|
||||
{ x = 1, y = -1, z = -1, tu = 0, tv = 0 },
|
||||
{ x = -1, y = 1, z = -1, tu = (SHAPE_TEXTURE_SIZE - 1) << 5, tv = (SHAPE_TEXTURE_SIZE - 1) << 5 },
|
||||
{ x = 1, y = 1, z = -1, tu = (SHAPE_TEXTURE_SIZE - 1) << 5, tv = 0 },
|
||||
}
|
||||
|
||||
function get_cube_vertices()
|
||||
vertices = {}
|
||||
for _, r in ipairs(CUBE_ROTATIONS) do
|
||||
for _, p in ipairs(CUBE_POINTS) do
|
||||
local v = { x = p.x * SHAPE_SIZE, y = p.y * SHAPE_SIZE, z = p.z * SHAPE_SIZE }
|
||||
vec3f_rotate_zxy(v, r)
|
||||
table.insert(vertices, { x = v.x, y = v.y, z = v.z, tu = p.tu, tv = p.tv, r = 0xFF, g = 0xFF, b = 0xFF })
|
||||
end
|
||||
end
|
||||
return vertices
|
||||
end
|
||||
|
||||
function get_cube_triangles()
|
||||
local triangles = {}
|
||||
for i = 0, 5 do
|
||||
local offset = 4 * i
|
||||
table.insert(triangles, {
|
||||
offset + 0, offset + 1, offset + 2,
|
||||
offset + 2, offset + 1, offset + 3
|
||||
})
|
||||
end
|
||||
return triangles
|
||||
end
|
||||
|
||||
function get_cube_geometry_mode()
|
||||
return "G_TEXTURE_GEN | G_CULL_BOTH | G_LIGHTING", "0"
|
||||
end
|
||||
|
||||
function get_cube_texture_scaling()
|
||||
return 0xFFFF
|
||||
end
|
||||
|
||||
----------------
|
||||
-- Octahedron --
|
||||
----------------
|
||||
|
||||
function get_octahedron_vertices()
|
||||
local vertices = {}
|
||||
table.insert(vertices, { x = 0, y = -SHAPE_SIZE, z = 0, tu = 0, tv = (SHAPE_TEXTURE_SIZE / 2) << 5, r = 0xFF, g = 0xFF, b = 0xFF })
|
||||
table.insert(vertices, { x = 0, y = SHAPE_SIZE, z = 0, tu = (SHAPE_TEXTURE_SIZE - 1) << 5, tv = (SHAPE_TEXTURE_SIZE / 2) << 5, r = 0xFF, g = 0xFF, b = 0xFF })
|
||||
for i = 0, 3 do
|
||||
local sina = sins(0x4000 * i) * SHAPE_SIZE
|
||||
local cosa = coss(0x4000 * i) * SHAPE_SIZE
|
||||
table.insert(vertices, { x = sina, y = 0, z = cosa, tu = (SHAPE_TEXTURE_SIZE - 1) << 5, tv = (SHAPE_TEXTURE_SIZE - 1) << 5, r = 0xFF, g = 0xFF, b = 0xFF })
|
||||
table.insert(vertices, { x = sina, y = 0, z = cosa, tu = (SHAPE_TEXTURE_SIZE - 1) << 5, tv = 0, r = 0xFF, g = 0xFF, b = 0xFF })
|
||||
table.insert(vertices, { x = sina, y = 0, z = cosa, tu = 0, tv = (SHAPE_TEXTURE_SIZE - 1) << 5, r = 0xFF, g = 0xFF, b = 0xFF })
|
||||
table.insert(vertices, { x = sina, y = 0, z = cosa, tu = 0, tv = 0, r = 0xFF, g = 0xFF, b = 0xFF })
|
||||
end
|
||||
return vertices
|
||||
end
|
||||
|
||||
function get_octahedron_triangles()
|
||||
local triangles = {}
|
||||
for i = 0, 3 do
|
||||
table.insert(triangles, {
|
||||
0, 2 + i * 4 + 0, 2 + ((i + 1) % 4) * 4 + 1,
|
||||
1, 2 + i * 4 + 2, 2 + ((i + 1) % 4) * 4 + 3
|
||||
})
|
||||
end
|
||||
return triangles
|
||||
end
|
||||
|
||||
function get_octahedron_geometry_mode()
|
||||
return "G_TEXTURE_GEN | G_CULL_BOTH | G_LIGHTING", "0"
|
||||
end
|
||||
|
||||
function get_octahedron_texture_scaling()
|
||||
return 0xFFFF
|
||||
end
|
||||
|
||||
----------
|
||||
-- Star --
|
||||
----------
|
||||
|
||||
local STAR_POINTS = {
|
||||
{ x = 0, y = 8, z = -90, r = 0x00, g = 0x07, b = 0x82 },
|
||||
{ x = 190, y = -201, z = 0, r = 0x55, g = 0xa3, b = 0x00 },
|
||||
{ x = 0, y = -129, z = 0, r = 0x00, g = 0x82, b = 0x00 },
|
||||
{ x = 146, y = -42, z = 0, r = 0x7c, g = 0xe7, b = 0x00 },
|
||||
{ x = 0, y = 8, z = 90, r = 0x00, g = 0x07, b = 0x7e },
|
||||
{ x = 256, y = 84, z = 0, r = 0x68, g = 0x47, b = 0x00 },
|
||||
{ x = -146, y = -42, z = 0, r = 0x84, g = 0xe7, b = 0x00 },
|
||||
{ x = -190, y = -201, z = 0, r = 0xaa, g = 0xa3, b = 0x00 },
|
||||
{ x = -256, y = 84, z = 0, r = 0x97, g = 0x47, b = 0x00 },
|
||||
{ x = 0, y = 246, z = 0, r = 0x00, g = 0x7e, b = 0x00 },
|
||||
{ x = 96, y = 99, z = 0, r = 0x3d, g = 0x6f, b = 0x00 },
|
||||
{ x = -96, y = 99, z = 0, r = 0xc3, g = 0x6f, b = 0x00 },
|
||||
}
|
||||
|
||||
local STAR_TRIANGLES = {
|
||||
{ 0, 1, 2, 0, 3, 1 },
|
||||
{ 2, 1, 4, 1, 3, 4 },
|
||||
{ 5, 3, 0, 4, 3, 5 },
|
||||
{ 6, 7, 4, 7, 2, 4 },
|
||||
{ 8, 6, 4, 9, 4, 10 },
|
||||
{ 9, 11, 4, 4, 5, 10 },
|
||||
{ 11, 8, 4, 0, 2, 7 },
|
||||
{ 0, 7, 6, 0, 6, 8 },
|
||||
{ 0, 8, 11, 0, 11, 9 },
|
||||
{ 10, 5, 0, 10, 0, 9 },
|
||||
}
|
||||
|
||||
function get_star_vertices()
|
||||
local vertices = {}
|
||||
for _, p in ipairs(STAR_POINTS) do
|
||||
table.insert(vertices, {
|
||||
x = p.x * SHAPE_SIZE / 256,
|
||||
y = p.y * SHAPE_SIZE / 256,
|
||||
z = p.z * SHAPE_SIZE / 256,
|
||||
tu = 0, tv = 0,
|
||||
r = p.r, g = p.g, b = p.b
|
||||
})
|
||||
end
|
||||
return vertices
|
||||
end
|
||||
|
||||
function get_star_triangles()
|
||||
return STAR_TRIANGLES
|
||||
end
|
||||
|
||||
function get_star_geometry_mode()
|
||||
return "G_CULL_BOTH", "G_LIGHTING | G_TEXTURE_GEN"
|
||||
end
|
||||
|
||||
function get_star_texture_scaling()
|
||||
return 0x7FC0
|
||||
end
|
||||
8
docs/lua/examples/gfx-vtx-demo/actors/shape/geo.inc.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
const GeoLayout shape_geo[] = {
|
||||
GEO_NODE_START(),
|
||||
GEO_OPEN_NODE(),
|
||||
GEO_ASM(0, geo_update_shape),
|
||||
GEO_DISPLAY_LIST(LAYER_OPAQUE, shape_template_dl),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_END(),
|
||||
};
|
||||
19
docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// The template display list.
|
||||
// Some values are placeholders that will be filled during the custom GEO ASM function.
|
||||
Gfx shape_template_dl[] = {
|
||||
/* [00] */ gsSPGeometryMode(0, 0),
|
||||
/* [01] */ gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
|
||||
/* [02] */ gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
|
||||
/* [03] */ gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_32b_LOAD_BLOCK, 1, NULL),
|
||||
/* [04] */ gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_32b_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, 0 , G_TX_CLAMP, 0, G_TX_NOLOD, G_TX_CLAMP, 0, G_TX_NOLOD),
|
||||
/* [05] */ gsDPLoadSync(),
|
||||
/* [06] */ gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 0, 0),
|
||||
/* [07] */ gsDPPipeSync(),
|
||||
/* [08] */ gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_32b, 128, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 0, G_TX_NOLOD, G_TX_CLAMP, 0, G_TX_NOLOD),
|
||||
/* [09] */ gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, 511 << G_TEXTURE_IMAGE_FRAC, 511 << G_TEXTURE_IMAGE_FRAC),
|
||||
/* [10] */ gsSPVertex(NULL, 0, 0),
|
||||
/* [11] */ gsSPDisplayList(NULL),
|
||||
/* [12] */ gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
|
||||
/* [13] */ gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
|
||||
/* [14] */ gsSPEndDisplayList(),
|
||||
};
|
||||
182
docs/lua/examples/gfx-vtx-demo/main.lua
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
-- name: Gfx and Vtx manipulation demo
|
||||
-- description: Press X to move the shape in front of Mario.\nPress Y to change the shape.
|
||||
|
||||
local SHAPE_TEXTURES = {}
|
||||
for i = 0, 10 do
|
||||
SHAPE_TEXTURES[i] = get_texture_info("matrix_" .. i)
|
||||
end
|
||||
|
||||
SHAPES = {
|
||||
{
|
||||
name = "Cube",
|
||||
get_vertices = get_cube_vertices,
|
||||
get_triangles = get_cube_triangles,
|
||||
get_geometry_mode = get_cube_geometry_mode,
|
||||
get_texture_scaling = get_cube_texture_scaling,
|
||||
},
|
||||
{
|
||||
name = "Octahedron",
|
||||
get_vertices = get_octahedron_vertices,
|
||||
get_triangles = get_octahedron_triangles,
|
||||
get_geometry_mode = get_octahedron_geometry_mode,
|
||||
get_texture_scaling = get_octahedron_texture_scaling,
|
||||
},
|
||||
{
|
||||
name = "Star",
|
||||
get_vertices = get_star_vertices,
|
||||
get_triangles = get_star_triangles,
|
||||
get_geometry_mode = get_star_geometry_mode,
|
||||
get_texture_scaling = get_star_texture_scaling,
|
||||
}
|
||||
}
|
||||
|
||||
--- @param gfx Gfx
|
||||
--- Set the geometry mode of the current shape.
|
||||
local function set_geometry_mode(gfx)
|
||||
local clear, set = SHAPES[current_shape + 1].get_geometry_mode()
|
||||
gfx_set_command(gfx, "gsSPGeometryMode(%s, %s)", clear, set)
|
||||
end
|
||||
|
||||
--- @param gfx Gfx
|
||||
--- @param on integer
|
||||
--- Toggle on/off the texture rendering and set the texture scaling.
|
||||
local function set_texture_scaling(gfx, on)
|
||||
local scaling = SHAPES[current_shape + 1].get_texture_scaling()
|
||||
gfx_set_command(gfx, "gsSPTexture(%i, %i, 0, G_TX_RENDERTILE, %i)", scaling, scaling, on)
|
||||
end
|
||||
|
||||
--- @param gfx Gfx
|
||||
--- @param obj Object
|
||||
--- Update the texture of the current shape.
|
||||
local function update_texture(gfx, obj)
|
||||
local texture = SHAPE_TEXTURES[obj.oAnimState].texture
|
||||
gfx_set_command(gfx, "gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_32b, 1, %t)", texture)
|
||||
end
|
||||
|
||||
--- @param gfx Gfx
|
||||
--- @param obj Object
|
||||
--- Compute the vertices of the current shape and fill the vertex buffer.
|
||||
local function compute_vertices(gfx, obj)
|
||||
local vertices = SHAPES[current_shape + 1].get_vertices()
|
||||
local num_vertices = #vertices
|
||||
|
||||
-- Create a new or retrieve an existing vertex buffer for the shape
|
||||
-- Use the object pointer to form a unique identifier
|
||||
local vtx_name = "shape_vertices_" .. tostring(obj._pointer)
|
||||
local vtx = vtx_get_from_name(vtx_name)
|
||||
if vtx == nil then
|
||||
vtx = vtx_new(vtx_name, num_vertices)
|
||||
else
|
||||
vtx = vtx_realloc(vtx, num_vertices)
|
||||
end
|
||||
|
||||
-- Update the vertex command
|
||||
gfx_set_command(gfx, "gsSPVertex(%v, %i, 0)", vtx, num_vertices)
|
||||
|
||||
-- Fill the vertex buffer
|
||||
for _, vertex in ipairs(vertices) do
|
||||
vtx.x = vertex.x
|
||||
vtx.y = vertex.y
|
||||
vtx.z = vertex.z
|
||||
vtx.tu = vertex.tu
|
||||
vtx.tv = vertex.tv
|
||||
vtx.r = vertex.r
|
||||
vtx.g = vertex.g
|
||||
vtx.b = vertex.b
|
||||
vtx.a = 0xFF
|
||||
vtx = vtx_get_next_vertex(vtx)
|
||||
end
|
||||
end
|
||||
|
||||
--- @param gfx Gfx
|
||||
--- @param obj Object
|
||||
--- Build the triangles for the current shape.
|
||||
local function build_triangles(gfx, obj)
|
||||
local triangles = SHAPES[current_shape + 1].get_triangles()
|
||||
local num_triangles = #triangles
|
||||
|
||||
-- Create a new or retrieve an existing triangles display list for the shape
|
||||
-- Use the object pointer to form a unique identifier
|
||||
local tris_name = "shape_triangles_" .. tostring(obj._pointer)
|
||||
local tris = gfx_get_from_name(tris_name)
|
||||
if tris == nil then
|
||||
tris = gfx_new(tris_name, num_triangles + 1) -- +1 for the gsSPEndDisplayList command
|
||||
else
|
||||
tris = gfx_realloc(tris, num_triangles + 1)
|
||||
end
|
||||
|
||||
-- Update the triangles command
|
||||
gfx_set_command(gfx, "gsSPDisplayList(%g)", tris)
|
||||
|
||||
-- Fill the triangles display list
|
||||
for _, indices in ipairs(triangles) do
|
||||
if #indices == 6 then
|
||||
gfx_set_command(tris, "gsSP2Triangles(%i, %i, %i, 0, %i, %i, %i, 0)",
|
||||
indices[1], indices[2], indices[3],
|
||||
indices[4], indices[5], indices[6]
|
||||
)
|
||||
elseif #indices == 3 then
|
||||
gfx_set_command(tris, "gsSP1Triangle(%i, %i, %i, 0)",
|
||||
indices[1], indices[2], indices[3]
|
||||
)
|
||||
end
|
||||
tris = gfx_get_next_command(tris)
|
||||
end
|
||||
gfx_set_command(tris, "gsSPEndDisplayList()")
|
||||
end
|
||||
|
||||
--- @param node GraphNode
|
||||
--- @param matStackIndex integer
|
||||
--- The custom GEO ASM function.
|
||||
function geo_update_shape(node, matStackIndex)
|
||||
local obj = geo_get_current_object()
|
||||
|
||||
-- Create a new display list that will be attached to the display list node
|
||||
-- To get a different display list for each object, we can use the object pointer to form a unique identifier
|
||||
local gfx_name = "shape_dl_" .. tostring(obj._pointer)
|
||||
local gfx = gfx_get_from_name(gfx_name)
|
||||
if gfx == nil then
|
||||
|
||||
-- Get and copy the template to the newly created display list
|
||||
local gfx_template = gfx_get_from_name("shape_template_dl")
|
||||
local gfx_template_length = gfx_get_length(gfx_template)
|
||||
gfx = gfx_new(gfx_name, gfx_template_length)
|
||||
gfx_copy(gfx, gfx_template, gfx_template_length)
|
||||
end
|
||||
|
||||
-- Now fill the display list with the appropriate commands (see actors/shape/model.inc.c)
|
||||
-- We can retrieve the commands directly with `gfx_get_command`
|
||||
-- Index | Command | What to do
|
||||
-- ------|----------------------|----------------------------------------
|
||||
-- [00] | gsSPGeometryMode | Change the geometry mode
|
||||
-- [02] | gsSPTexture | Change the texture scaling
|
||||
-- [03] | gsDPSetTextureImage | Update the texture
|
||||
-- [10] | gsSPVertex | Compute vertices
|
||||
-- [11] | gsSPDisplayList | Build triangles
|
||||
-- [12] | gsSPTexture | Change the texture scaling
|
||||
|
||||
-- Change the geometry mode
|
||||
local cmd_geometry_mode = gfx_get_command(gfx, 0)
|
||||
set_geometry_mode(cmd_geometry_mode)
|
||||
|
||||
-- Change the texture scaling
|
||||
local cmd_texture_scaling_1 = gfx_get_command(gfx, 2)
|
||||
set_texture_scaling(cmd_texture_scaling_1, 1)
|
||||
local cmd_texture_scaling_2 = gfx_get_command(gfx, 12)
|
||||
set_texture_scaling(cmd_texture_scaling_2, 0)
|
||||
|
||||
-- Update texture
|
||||
local cmd_texture = gfx_get_command(gfx, 3)
|
||||
update_texture(cmd_texture, obj)
|
||||
|
||||
-- Compute vertices
|
||||
local cmd_vertices = gfx_get_command(gfx, 10)
|
||||
compute_vertices(cmd_vertices, obj)
|
||||
|
||||
-- Build triangles
|
||||
local cmd_triangles = gfx_get_command(gfx, 11)
|
||||
build_triangles(cmd_triangles, obj)
|
||||
|
||||
-- Update the graph node display list
|
||||
cast_graph_node(node.next).displayList = gfx
|
||||
end
|
||||
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_0.png
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_1.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_10.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_2.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_3.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_4.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_5.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_6.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_7.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_8.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
docs/lua/examples/gfx-vtx-demo/textures/matrix_9.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
48
docs/lua/examples/gfx-vtx-demo/update.lua
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
--
|
||||
-- Custom object and Mario update
|
||||
-- Don't mind this file, it's not relevant to the purpose of this demo.
|
||||
--
|
||||
|
||||
current_shape = 0
|
||||
|
||||
local E_MODEL_SHAPE = smlua_model_util_get_id("shape_geo")
|
||||
|
||||
local function bhv_shape_init(o)
|
||||
o.oFlags = o.oFlags | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
|
||||
o.oAnimState = 0
|
||||
end
|
||||
|
||||
local function bhv_shape_loop(o)
|
||||
o.oFaceAngleYaw = o.oFaceAngleYaw - 0x100
|
||||
if o.oTimer % 2 == 0 then
|
||||
o.oAnimState = (o.oAnimState + 1) % 11
|
||||
end
|
||||
end
|
||||
|
||||
local id_bhvShape = hook_behavior(nil, OBJ_LIST_DEFAULT, true, bhv_shape_init, bhv_shape_loop, "bhvShape")
|
||||
|
||||
local function mario_update(m)
|
||||
if m.playerIndex == 0 then
|
||||
if m.controller.buttonPressed & X_BUTTON ~= 0 then
|
||||
local obj = obj_get_first_with_behavior_id(id_bhvShape)
|
||||
if obj == nil then
|
||||
obj = spawn_non_sync_object(id_bhvShape, E_MODEL_SHAPE, 0, 0, 0, nil)
|
||||
end
|
||||
obj.oPosX = m.pos.x + 200 * sins(m.faceAngle.y)
|
||||
obj.oPosY = m.pos.y + 150
|
||||
obj.oPosZ = m.pos.z + 200 * coss(m.faceAngle.y)
|
||||
elseif m.controller.buttonPressed & Y_BUTTON ~= 0 then
|
||||
current_shape = (current_shape + 1) % #SHAPES
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_hud_render()
|
||||
djui_hud_set_resolution(RESOLUTION_DJUI)
|
||||
djui_hud_set_font(FONT_MENU)
|
||||
djui_hud_set_color(0xFF, 0xFF, 0x00, 0xFF)
|
||||
djui_hud_print_text(SHAPES[current_shape + 1].name, 8, djui_hud_get_screen_height() - 64, 1)
|
||||
end
|
||||
|
||||
hook_event(HOOK_MARIO_UPDATE, mario_update)
|
||||
hook_event(HOOK_ON_HUD_RENDER, on_hud_render)
|
||||
|
|
@ -8,7 +8,7 @@ function geo_hide_if_dnc(node)
|
|||
local dl = cast_graph_node(node.next)
|
||||
gfx_parse(dl.displayList, function(cmd, op)
|
||||
if op == G_SETENVCOLOR then
|
||||
gfx_set_command(cmd, "gsDPSetEnvColor", 255, 255, 255, if_then_else(_G.dayNightCycleApi ~= nil and _G.dayNightCycleApi.is_dnc_enabled(), 0, 255))
|
||||
gfx_set_command(cmd, "gsDPSetEnvColor(255, 255, 255, %i)", if_then_else(_G.dayNightCycleApi ~= nil and _G.dayNightCycleApi.is_dnc_enabled(), 0, 255))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -468,43 +468,19 @@ Traverses a display list. Takes a Lua function as a parameter, which is called b
|
|||
- None
|
||||
|
||||
### C Prototype
|
||||
`void gfx_parse(Gfx* cmd, LuaFunction func);`
|
||||
`void gfx_parse(Gfx *cmd, LuaFunction func);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_get_vtx](#gfx_get_vtx)
|
||||
## [gfx_get_op](#gfx_get_op)
|
||||
|
||||
### Description
|
||||
Gets a vertex from a display list command if it has the correct op. Intended to be used with `gfx_parse`
|
||||
Gets the op of the display list command
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = gfx_get_vtx(gfx, offset)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| gfx | `Pointer` <`Gfx`> |
|
||||
| offset | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Vtx`>
|
||||
|
||||
### C Prototype
|
||||
`Vtx *gfx_get_vtx(Gfx* gfx, u16 offset);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_get_vtx_count](#gfx_get_vtx_count)
|
||||
|
||||
### Description
|
||||
Gets the number of vertices from a display list command if it has the correct op
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = gfx_get_vtx_count(cmd)`
|
||||
`local integerValue = gfx_get_op(cmd)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
|
|
@ -515,73 +491,408 @@ Gets the number of vertices from a display list command if it has the correct op
|
|||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`u16 gfx_get_vtx_count(Gfx* cmd);`
|
||||
`u32 gfx_get_op(Gfx *cmd);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_set_combine_lerp](#gfx_set_combine_lerp)
|
||||
## [gfx_get_display_list](#gfx_get_display_list)
|
||||
|
||||
### Description
|
||||
Sets the display list combine mode. you can fill this function with G_CCMUX_* and G_ACMUX_* constants
|
||||
Gets the display list from a display list command if it has the op `G_DL`
|
||||
|
||||
### Lua Example
|
||||
`gfx_set_combine_lerp(gfx, a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1)`
|
||||
`local PointerValue = gfx_get_display_list(cmd)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| gfx | `Pointer` <`Gfx`> |
|
||||
| a0 | `integer` |
|
||||
| b0 | `integer` |
|
||||
| c0 | `integer` |
|
||||
| d0 | `integer` |
|
||||
| Aa0 | `integer` |
|
||||
| Ab0 | `integer` |
|
||||
| Ac0 | `integer` |
|
||||
| Ad0 | `integer` |
|
||||
| a1 | `integer` |
|
||||
| b1 | `integer` |
|
||||
| c1 | `integer` |
|
||||
| d1 | `integer` |
|
||||
| Aa1 | `integer` |
|
||||
| Ab1 | `integer` |
|
||||
| Ac1 | `integer` |
|
||||
| Ad1 | `integer` |
|
||||
| cmd | `Pointer` <`Gfx`> |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
- `Pointer` <`Gfx`>
|
||||
|
||||
### C Prototype
|
||||
`void gfx_set_combine_lerp(Gfx* gfx, u32 a0, u32 b0, u32 c0, u32 d0, u32 Aa0, u32 Ab0, u32 Ac0, u32 Ad0, u32 a1, u32 b1, u32 c1, u32 d1, u32 Aa1, u32 Ab1, u32 Ac1, u32 Ad1);`
|
||||
`Gfx *gfx_get_display_list(Gfx *cmd);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_set_texture_image](#gfx_set_texture_image)
|
||||
## [gfx_get_vertex_buffer](#gfx_get_vertex_buffer)
|
||||
|
||||
### Description
|
||||
Sets the display list texture image. Pass in textureInfo.texture as `texture`
|
||||
Gets the vertex buffer from a display list command if it has the op `G_VTX`
|
||||
|
||||
### Lua Example
|
||||
`gfx_set_texture_image(gfx, format, size, width, texture)`
|
||||
`local PointerValue = gfx_get_vertex_buffer(cmd)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| cmd | `Pointer` <`Gfx`> |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Vtx`>
|
||||
|
||||
### C Prototype
|
||||
`Vtx *gfx_get_vertex_buffer(Gfx *cmd);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_get_vertex_count](#gfx_get_vertex_count)
|
||||
|
||||
### Description
|
||||
Gets the number of vertices from a display list command if it has the op `G_VTX`
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = gfx_get_vertex_count(cmd)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| cmd | `Pointer` <`Gfx`> |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`u16 gfx_get_vertex_count(Gfx *cmd);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_get_length](#gfx_get_length)
|
||||
|
||||
### Description
|
||||
Gets the max length of a display list
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = gfx_get_length(gfx)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| gfx | `Pointer` <`Gfx`> |
|
||||
| format | `integer` |
|
||||
| size | `integer` |
|
||||
| width | `integer` |
|
||||
| texture | `Pointer` <`integer`> |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`u32 gfx_get_length(Gfx *gfx);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_get_command](#gfx_get_command)
|
||||
|
||||
### Description
|
||||
Gets a command of a display list at position `offset`
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = gfx_get_command(gfx, offset)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| gfx | `Pointer` <`Gfx`> |
|
||||
| offset | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Gfx`>
|
||||
|
||||
### C Prototype
|
||||
`Gfx *gfx_get_command(Gfx *gfx, u32 offset);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_get_next_command](#gfx_get_next_command)
|
||||
|
||||
### Description
|
||||
Gets the next command of a given display list pointer. Intended to use in a for loop
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = gfx_get_next_command(gfx)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| gfx | `Pointer` <`Gfx`> |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Gfx`>
|
||||
|
||||
### C Prototype
|
||||
`Gfx *gfx_get_next_command(Gfx *gfx);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_copy](#gfx_copy)
|
||||
|
||||
### Description
|
||||
Copies `length` commands from display list `src` to display list `dest`
|
||||
|
||||
### Lua Example
|
||||
`gfx_copy(dest, src, length)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| dest | `Pointer` <`Gfx`> |
|
||||
| src | `Pointer` <`Gfx`> |
|
||||
| length | `integer` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void gfx_set_texture_image(Gfx* gfx, u32 format, u32 size, u32 width, u8* texture);`
|
||||
`void gfx_copy(Gfx *dest, Gfx *src, u32 length);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_new](#gfx_new)
|
||||
|
||||
### Description
|
||||
Creates a new named display list of `length` commands
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = gfx_new(name, length)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| name | `string` |
|
||||
| length | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Gfx`>
|
||||
|
||||
### C Prototype
|
||||
`Gfx *gfx_new(const char *name, u32 length);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_realloc](#gfx_realloc)
|
||||
|
||||
### Description
|
||||
Reallocates a display list created by `gfx_new` to modify its length
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = gfx_realloc(gfx, newLength)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| gfx | `Pointer` <`Gfx`> |
|
||||
| newLength | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Gfx`>
|
||||
|
||||
### C Prototype
|
||||
`Gfx *gfx_realloc(Gfx *gfx, u32 newLength);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [gfx_delete](#gfx_delete)
|
||||
|
||||
### Description
|
||||
Deletes a display list created by `gfx_new`
|
||||
|
||||
### Lua Example
|
||||
`gfx_delete(gfx)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| gfx | `Pointer` <`Gfx`> |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void gfx_delete(Gfx *gfx);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [vtx_get_count](#vtx_get_count)
|
||||
|
||||
### Description
|
||||
Gets the max count of vertices of a vertex buffer
|
||||
|
||||
### Lua Example
|
||||
`local integerValue = vtx_get_count(vtx)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| vtx | `Pointer` <`Vtx`> |
|
||||
|
||||
### Returns
|
||||
- `integer`
|
||||
|
||||
### C Prototype
|
||||
`u32 vtx_get_count(Vtx *vtx);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [vtx_get_vertex](#vtx_get_vertex)
|
||||
|
||||
### Description
|
||||
Gets a vertex of a vertex buffer at position `offset`
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = vtx_get_vertex(vtx, offset)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| vtx | `Pointer` <`Vtx`> |
|
||||
| offset | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Vtx`>
|
||||
|
||||
### C Prototype
|
||||
`Vtx *vtx_get_vertex(Vtx *vtx, u32 offset);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [vtx_get_next_vertex](#vtx_get_next_vertex)
|
||||
|
||||
### Description
|
||||
Gets the next vertex of a given vertex pointer. Intended to use in a for loop
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = vtx_get_next_vertex(vtx)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| vtx | `Pointer` <`Vtx`> |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Vtx`>
|
||||
|
||||
### C Prototype
|
||||
`Vtx *vtx_get_next_vertex(Vtx *vtx);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [vtx_copy](#vtx_copy)
|
||||
|
||||
### Description
|
||||
Copies `count` vertices from vertex buffer `src` to vertex buffer `dest`
|
||||
|
||||
### Lua Example
|
||||
`vtx_copy(dest, src, count)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| dest | `Pointer` <`Vtx`> |
|
||||
| src | `Pointer` <`Vtx`> |
|
||||
| count | `integer` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void vtx_copy(Vtx *dest, Vtx *src, u32 count);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [vtx_new](#vtx_new)
|
||||
|
||||
### Description
|
||||
Creates a new named vertex buffer of `count` vertices
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = vtx_new(name, count)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| name | `string` |
|
||||
| count | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Vtx`>
|
||||
|
||||
### C Prototype
|
||||
`Vtx *vtx_new(const char *name, u32 count);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [vtx_realloc](#vtx_realloc)
|
||||
|
||||
### Description
|
||||
Reallocates a vertex buffer created by `vtx_new` to modify its count
|
||||
|
||||
### Lua Example
|
||||
`local PointerValue = vtx_realloc(vtx, newCount)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| vtx | `Pointer` <`Vtx`> |
|
||||
| newCount | `integer` |
|
||||
|
||||
### Returns
|
||||
- `Pointer` <`Vtx`>
|
||||
|
||||
### C Prototype
|
||||
`Vtx *vtx_realloc(Vtx *vtx, u32 newCount);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [vtx_delete](#vtx_delete)
|
||||
|
||||
### Description
|
||||
Deletes a vertex buffer created by `vtx_new`
|
||||
|
||||
### Lua Example
|
||||
`vtx_delete(vtx)`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| vtx | `Pointer` <`Vtx`> |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
||||
### C Prototype
|
||||
`void vtx_delete(Vtx *vtx);`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
|||
|
|
@ -1785,10 +1785,24 @@
|
|||
- [get_skybox_color](functions-6.md#get_skybox_color)
|
||||
- [set_skybox_color](functions-6.md#set_skybox_color)
|
||||
- [gfx_parse](functions-6.md#gfx_parse)
|
||||
- [gfx_get_vtx](functions-6.md#gfx_get_vtx)
|
||||
- [gfx_get_vtx_count](functions-6.md#gfx_get_vtx_count)
|
||||
- [gfx_set_combine_lerp](functions-6.md#gfx_set_combine_lerp)
|
||||
- [gfx_set_texture_image](functions-6.md#gfx_set_texture_image)
|
||||
- [gfx_get_op](functions-6.md#gfx_get_op)
|
||||
- [gfx_get_display_list](functions-6.md#gfx_get_display_list)
|
||||
- [gfx_get_vertex_buffer](functions-6.md#gfx_get_vertex_buffer)
|
||||
- [gfx_get_vertex_count](functions-6.md#gfx_get_vertex_count)
|
||||
- [gfx_get_length](functions-6.md#gfx_get_length)
|
||||
- [gfx_get_command](functions-6.md#gfx_get_command)
|
||||
- [gfx_get_next_command](functions-6.md#gfx_get_next_command)
|
||||
- [gfx_copy](functions-6.md#gfx_copy)
|
||||
- [gfx_new](functions-6.md#gfx_new)
|
||||
- [gfx_realloc](functions-6.md#gfx_realloc)
|
||||
- [gfx_delete](functions-6.md#gfx_delete)
|
||||
- [vtx_get_count](functions-6.md#vtx_get_count)
|
||||
- [vtx_get_vertex](functions-6.md#vtx_get_vertex)
|
||||
- [vtx_get_next_vertex](functions-6.md#vtx_get_next_vertex)
|
||||
- [vtx_copy](functions-6.md#vtx_copy)
|
||||
- [vtx_new](functions-6.md#vtx_new)
|
||||
- [vtx_realloc](functions-6.md#vtx_realloc)
|
||||
- [vtx_delete](functions-6.md#vtx_delete)
|
||||
|
||||
<br />
|
||||
|
||||
|
|
@ -2563,11 +2577,30 @@ N/A
|
|||
|
||||
## [gfx_set_command](#gfx_set_command)
|
||||
|
||||
Sets the specified display list command on the display list given.
|
||||
Sets a display list command on the display list given.
|
||||
|
||||
### Lua Example
|
||||
If `command` includes parameter specifiers (subsequences beginning with `%`), the additional arguments following `command` are converted and inserted in `command` replacing their respective specifiers.
|
||||
|
||||
The number of provided parameters must be equal to the number of specifiers in `command`, and the order of parameters must be the same as the specifiers.
|
||||
|
||||
The following specifiers are allowed:
|
||||
- `%i` for an `integer` parameter
|
||||
- `%s` for a `string` parameter
|
||||
- `%v` for a `Vtx` parameter
|
||||
- `%t` for a `Texture` parameter
|
||||
- `%g` for a `Gfx` parameter
|
||||
|
||||
### Lua Examples
|
||||
|
||||
Plain string:
|
||||
```lua
|
||||
gfx_set_command(gfx, "gsDPSetEnvColor", 0x00, 0xFF, 0x00, 0xFF)
|
||||
gfx_set_command(gfx, "gsDPSetEnvColor(0x00, 0xFF, 0x00, 0xFF)")
|
||||
```
|
||||
|
||||
With parameter specifiers:
|
||||
```lua
|
||||
r, g, b, a = 0x00, 0xFF, 0x00, 0xFF
|
||||
gfx_set_command(gfx, "gsDPSetEnvColor(%i, %i, %i, %i)", r, g, b, a)
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
|
@ -2575,7 +2608,7 @@ gfx_set_command(gfx, "gsDPSetEnvColor", 0x00, 0xFF, 0x00, 0xFF)
|
|||
| ----- | ---- |
|
||||
| gfx | [Gfx](structs.md#Gfx) |
|
||||
| command | `string` |
|
||||
| (Any number of arguments) | `integer` |
|
||||
| parameters... | any of `integer`, `string`, `Gfx`, `Texture`, `Vtx` |
|
||||
|
||||
### Returns
|
||||
- None
|
||||
|
|
|
|||
|
|
@ -3249,10 +3249,19 @@
|
|||
|
||||
| Field | Type | Access |
|
||||
| ----- | ---- | ------ |
|
||||
| cn | `Array` <`integer`> | |
|
||||
| a | `integer` | |
|
||||
| b | `integer` | |
|
||||
| flag | `integer` | |
|
||||
| ob | `Array` <`number`> | |
|
||||
| tc | `Array` <`integer`> | |
|
||||
| g | `integer` | |
|
||||
| nx | `integer` | |
|
||||
| ny | `integer` | |
|
||||
| nz | `integer` | |
|
||||
| r | `integer` | |
|
||||
| tu | `integer` | |
|
||||
| tv | `integer` | |
|
||||
| x | `number` | |
|
||||
| y | `number` | |
|
||||
| z | `number` | |
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,10 @@
|
|||
# define GBI_FLOATS
|
||||
#endif
|
||||
|
||||
#ifndef GBI_NO_MULTI_COMMANDS
|
||||
# define GBI_NO_MULTI_COMMANDS
|
||||
#endif
|
||||
|
||||
#ifdef F3DEX_GBI_2
|
||||
# ifndef F3DEX_GBI
|
||||
# define F3DEX_GBI
|
||||
|
|
@ -1133,10 +1137,33 @@ typedef struct {
|
|||
unsigned char a; /* alpha */
|
||||
} Vtx_tn;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
unsigned short flag;
|
||||
short tu;
|
||||
short tv;
|
||||
union {
|
||||
unsigned char r;
|
||||
signed char nx;
|
||||
};
|
||||
union {
|
||||
unsigned char g;
|
||||
signed char ny;
|
||||
};
|
||||
union {
|
||||
unsigned char b;
|
||||
signed char nz;
|
||||
};
|
||||
unsigned char a;
|
||||
} Vtx_L;
|
||||
|
||||
typedef union {
|
||||
Vtx_t v; /* Use this one for colors */
|
||||
Vtx_tn n; /* Use this one for normals */
|
||||
long long int force_structure_alignment;
|
||||
Vtx_t v; /* Use this one for colors */
|
||||
Vtx_tn n; /* Use this one for normals */
|
||||
Vtx_L l; /* Use this one for Lua */
|
||||
long long int force_structure_alignment;
|
||||
} Vtx;
|
||||
|
||||
/*
|
||||
|
|
@ -4457,6 +4484,22 @@ typedef union {
|
|||
}}
|
||||
|
||||
/* Fraction never used in fill */
|
||||
#ifdef GBI_NO_MULTI_COMMANDS
|
||||
|
||||
#define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *) pkt; \
|
||||
_g->words.w0 = _SHIFTL(G_FILLRECT, 24, 8) | _SHIFTL((uly), 12, 12) | _SHIFTL((lry), 0, 12); \
|
||||
_g->words.w1 = _SHIFTL((ulx), 16, 16) | _SHIFTL((lrx), 0, 16); \
|
||||
}
|
||||
|
||||
#define gsDPFillRectangle(ulx, uly, lrx, lry) \
|
||||
{{ \
|
||||
_SHIFTL(G_FILLRECT, 24, 8) | _SHIFTL((uly), 12, 12) | _SHIFTL((lry), 0, 12), \
|
||||
_SHIFTL((ulx), 16, 16) | _SHIFTL((lrx), 0, 16), \
|
||||
}}
|
||||
|
||||
#else
|
||||
#ifdef F3DEX_GBI_2E
|
||||
#define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \
|
||||
{ \
|
||||
|
|
@ -4492,6 +4535,7 @@ typedef union {
|
|||
(_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10)) \
|
||||
}}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* like gDPFillRectangle but accepts negative arguments */
|
||||
#ifndef F3DEX_GBI_2E
|
||||
|
|
@ -4590,6 +4634,7 @@ typedef union {
|
|||
* under normal circumstances (use gsSPTextureRectangle()).
|
||||
* That is also why there is no gDPTextureRectangle() macros.
|
||||
*/
|
||||
#if 0 // DO NOT USE
|
||||
#define gsDPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||
{{ \
|
||||
(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \
|
||||
|
|
@ -4637,7 +4682,50 @@ typedef union {
|
|||
_g->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
||||
_g->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GBI_NO_MULTI_COMMANDS
|
||||
|
||||
#define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *) (pkt); \
|
||||
_g->words.w0 = _SHIFTL(G_TEXRECT, 24, 8) | \
|
||||
_SHIFTL((xh) >> 2, 13, 11) | \
|
||||
_SHIFTL((yh) >> 2, 4, 9) | \
|
||||
_SHIFTL((dtdy) >> 6, 0, 4); /* decimal part */ \
|
||||
_g->words.w1 = _SHIFTL((xl) >> 2, 21, 11) | \
|
||||
_SHIFTL((yl) >> 2, 12, 9) | \
|
||||
_SHIFTL((dsdx) >> 6, 4, 8) | \
|
||||
_SHIFTL((dtdy) >> 10, 0, 4); /* integer part */ \
|
||||
}
|
||||
|
||||
#define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||
{{ \
|
||||
_SHIFTL(G_TEXRECT, 24, 8) | \
|
||||
_SHIFTL((xh) >> 2, 13, 11) | \
|
||||
_SHIFTL((yh) >> 2, 4, 9) | \
|
||||
_SHIFTL((dtdy) >> 6, 0, 4), /* decimal part */ \
|
||||
\
|
||||
_SHIFTL((xl) >> 2, 21, 11) | \
|
||||
_SHIFTL((yl) >> 2, 12, 9) | \
|
||||
_SHIFTL((dsdx) >> 6, 4, 8) | \
|
||||
_SHIFTL((dtdy) >> 10, 0, 4) /* integer part */ \
|
||||
}}
|
||||
|
||||
#define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *) (pkt); \
|
||||
_g->words.w0 = _SHIFTL(G_TEXRECTFLIP, 24, 8) | \
|
||||
_SHIFTL((xh) >> 2, 13, 11) | \
|
||||
_SHIFTL((yh) >> 2, 4, 9) | \
|
||||
_SHIFTL((dtdy) >> 6, 0, 4); /* decimal part */ \
|
||||
_g->words.w1 = _SHIFTL((xl) >> 2, 21, 11) | \
|
||||
_SHIFTL((yl) >> 2, 12, 9) | \
|
||||
_SHIFTL((dsdx) >> 6, 4, 8) | \
|
||||
_SHIFTL((dtdy) >> 10, 0, 4); /* integer part */ \
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef F3D_OLD
|
||||
# define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
|
||||
{ \
|
||||
|
|
@ -4809,6 +4897,7 @@ typedef union {
|
|||
gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define gsDPWord(wordhi, wordlo) \
|
||||
gsImmp1(G_RDPHALF_1, (uintptr_t)(wordhi)), \
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
#include "display_list.h"
|
||||
|
||||
// Get the size of a display list by iterating
|
||||
// until gsSPEndDisplayList or gsSPBranchList is found
|
||||
u32 gfx_get_size(const Gfx* gfx) {
|
||||
for (u32 i = 0;;) {
|
||||
u32 op = (gfx + i)->words.w0 >> 24;
|
||||
u32 cmdSize = 1;
|
||||
switch (op) {
|
||||
case G_DL:
|
||||
if (C0(gfx + i, 16, 1) == G_DL_NOPUSH) { return i + 1; } // For displaylists that end with branches (jumps)
|
||||
break;
|
||||
case G_ENDDL:
|
||||
return i + 1;
|
||||
case G_TEXRECT:
|
||||
case G_TEXRECTFLIP:
|
||||
cmdSize = 3;
|
||||
break;
|
||||
case G_FILLRECT:
|
||||
cmdSize = 2;
|
||||
break;
|
||||
}
|
||||
i += cmdSize;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#include <PR/gbi.h>
|
||||
|
||||
#define C0(cmd, pos, width) (((cmd)->words.w0 >> (pos)) & ((1U << width) - 1))
|
||||
|
||||
u32 gfx_get_size(const Gfx* gfx);
|
||||
|
|
@ -235,7 +235,7 @@ init_graph_node_translation_rotation(struct DynamicPool *pool,
|
|||
vec3s_copy(graphNode->translation, translation);
|
||||
vec3s_copy(graphNode->rotation, rotation);
|
||||
graphNode->node.flags = (drawingLayer << 8) | (graphNode->node.flags & 0xFF);
|
||||
graphNode->displayList = dynos_model_get_writable_display_list(displayList);
|
||||
graphNode->displayList = dynos_gfx_get_writable_display_list(displayList);
|
||||
}
|
||||
|
||||
return graphNode;
|
||||
|
|
@ -257,7 +257,7 @@ struct GraphNodeTranslation *init_graph_node_translation(struct DynamicPool *poo
|
|||
|
||||
vec3s_copy(graphNode->translation, translation);
|
||||
graphNode->node.flags = (drawingLayer << 8) | (graphNode->node.flags & 0xFF);
|
||||
graphNode->displayList = dynos_model_get_writable_display_list(displayList);
|
||||
graphNode->displayList = dynos_gfx_get_writable_display_list(displayList);
|
||||
}
|
||||
|
||||
return graphNode;
|
||||
|
|
@ -278,7 +278,7 @@ struct GraphNodeRotation *init_graph_node_rotation(struct DynamicPool *pool,
|
|||
init_scene_graph_node_links(&graphNode->node, GRAPH_NODE_TYPE_ROTATION);
|
||||
vec3s_copy(graphNode->rotation, rotation);
|
||||
graphNode->node.flags = (drawingLayer << 8) | (graphNode->node.flags & 0xFF);
|
||||
graphNode->displayList = dynos_model_get_writable_display_list(displayList);
|
||||
graphNode->displayList = dynos_gfx_get_writable_display_list(displayList);
|
||||
}
|
||||
|
||||
return graphNode;
|
||||
|
|
@ -299,7 +299,7 @@ struct GraphNodeScale *init_graph_node_scale(struct DynamicPool *pool,
|
|||
graphNode->node.flags = (drawingLayer << 8) | (graphNode->node.flags & 0xFF);
|
||||
graphNode->scale = scale;
|
||||
graphNode->prevScale = scale;
|
||||
graphNode->displayList = dynos_model_get_writable_display_list(displayList);
|
||||
graphNode->displayList = dynos_gfx_get_writable_display_list(displayList);
|
||||
}
|
||||
|
||||
return graphNode;
|
||||
|
|
@ -369,7 +369,7 @@ struct GraphNodeAnimatedPart *init_graph_node_animated_part(struct DynamicPool *
|
|||
init_scene_graph_node_links(&graphNode->node, GRAPH_NODE_TYPE_ANIMATED_PART);
|
||||
vec3s_copy(graphNode->translation, translation);
|
||||
graphNode->node.flags = (drawingLayer << 8) | (graphNode->node.flags & 0xFF);
|
||||
graphNode->displayList = dynos_model_get_writable_display_list(displayList);
|
||||
graphNode->displayList = dynos_gfx_get_writable_display_list(displayList);
|
||||
}
|
||||
|
||||
return graphNode;
|
||||
|
|
@ -390,7 +390,7 @@ struct GraphNodeBillboard *init_graph_node_billboard(struct DynamicPool *pool,
|
|||
init_scene_graph_node_links(&graphNode->node, GRAPH_NODE_TYPE_BILLBOARD);
|
||||
vec3s_copy(graphNode->translation, translation);
|
||||
graphNode->node.flags = (drawingLayer << 8) | (graphNode->node.flags & 0xFF);
|
||||
graphNode->displayList = dynos_model_get_writable_display_list(displayList);
|
||||
graphNode->displayList = dynos_gfx_get_writable_display_list(displayList);
|
||||
}
|
||||
|
||||
return graphNode;
|
||||
|
|
@ -409,7 +409,7 @@ struct GraphNodeDisplayList *init_graph_node_display_list(struct DynamicPool *po
|
|||
if (graphNode != NULL) {
|
||||
init_scene_graph_node_links(&graphNode->node, GRAPH_NODE_TYPE_DISPLAY_LIST);
|
||||
graphNode->node.flags = (drawingLayer << 8) | (graphNode->node.flags & 0xFF);
|
||||
graphNode->displayList = dynos_model_get_writable_display_list(displayList);
|
||||
graphNode->displayList = dynos_gfx_get_writable_display_list(displayList);
|
||||
}
|
||||
|
||||
return graphNode;
|
||||
|
|
|
|||
|
|
@ -384,6 +384,9 @@ static void level_reset_globals(void) {
|
|||
|
||||
// free models stored in dynos
|
||||
dynos_model_clear_pool(MODEL_POOL_LEVEL);
|
||||
|
||||
// clear the gfx command cache filled by gfx_set_command
|
||||
dynos_smlua_clear_gfx_command_cache();
|
||||
}
|
||||
|
||||
static void level_cmd_alloc_level_pool(void) {
|
||||
|
|
|
|||
|
|
@ -770,6 +770,8 @@ static float gfx_adjust_x_for_aspect_ratio(float x) {
|
|||
}
|
||||
|
||||
static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices, bool luaVertexColor) {
|
||||
if (!vertices) { return; }
|
||||
|
||||
float globalLightCached[2][3];
|
||||
float vertexColorCached[3];
|
||||
if (rsp.geometry_mode & G_LIGHTING) {
|
||||
|
|
@ -1635,6 +1637,8 @@ static inline void *seg_addr(uintptr_t w1) {
|
|||
#define C1(pos, width) ((cmd->words.w1 >> (pos)) & ((1U << width) - 1))
|
||||
|
||||
static void OPTIMIZE_O3 gfx_run_dl(Gfx* cmd) {
|
||||
if (!cmd) { return; }
|
||||
|
||||
for (;;) {
|
||||
uint32_t opcode = cmd->words.w0 >> 24;
|
||||
|
||||
|
|
@ -1788,6 +1792,16 @@ static void OPTIMIZE_O3 gfx_run_dl(Gfx* cmd) {
|
|||
int32_t lrx, lry, tile, ulx, uly;
|
||||
uint32_t uls, ult, dsdx, dtdy;
|
||||
tile = 0;
|
||||
#ifdef GBI_NO_MULTI_COMMANDS
|
||||
lrx = (int32_t) (C0(13, 11) << 21) >> 19;
|
||||
lry = (int32_t) (C0(4, 9) << 23) >> 21;
|
||||
ulx = (int32_t) (C1(21, 11) << 21) >> 19;
|
||||
uly = (int32_t) (C1(12, 9) << 23) >> 21;
|
||||
uls = 0;
|
||||
ult = 0;
|
||||
dsdx = C1(4, 8) << 6;
|
||||
dtdy = (C1(0, 4) << 10) | (C0(0, 4) << 6);
|
||||
#else
|
||||
#ifdef F3DEX_GBI_2E
|
||||
lrx = (int32_t)(C0(0, 24) << 8) >> 8;
|
||||
lry = (int32_t)(C1(0, 24) << 8) >> 8;
|
||||
|
|
@ -1811,11 +1825,23 @@ static void OPTIMIZE_O3 gfx_run_dl(Gfx* cmd) {
|
|||
++cmd;
|
||||
dsdx = C1(16, 16);
|
||||
dtdy = C1(0, 16);
|
||||
#endif
|
||||
#endif
|
||||
gfx_dp_texture_rectangle(ulx, uly, lrx, lry, tile, uls, ult, dsdx, dtdy, opcode == G_TEXRECTFLIP);
|
||||
break;
|
||||
}
|
||||
case G_FILLRECT:
|
||||
#ifdef GBI_NO_MULTI_COMMANDS
|
||||
{
|
||||
int32_t lrx, lry, ulx, uly;
|
||||
uly = (int32_t) (C0(12, 12) << 20) >> 18;
|
||||
lry = (int32_t) (C0(0, 12) << 20) >> 18;
|
||||
ulx = (int32_t) (C1(16, 16) << 16) >> 14;
|
||||
lrx = (int32_t) (C1(0, 16) << 16) >> 14;
|
||||
gfx_dp_fill_rectangle(ulx, uly, lrx, lry);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
#ifdef F3DEX_GBI_2E
|
||||
{
|
||||
int32_t lrx, lry, ulx, uly;
|
||||
|
|
@ -1830,6 +1856,7 @@ static void OPTIMIZE_O3 gfx_run_dl(Gfx* cmd) {
|
|||
#else
|
||||
gfx_dp_fill_rectangle(C1(12, 12), C1(0, 12), C0(12, 12), C0(0, 12));
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
case G_SETSCISSOR:
|
||||
gfx_dp_set_scissor(C1(24, 2), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12));
|
||||
|
|
|
|||
|
|
@ -2703,12 +2703,21 @@ static struct LuaObjectField sTransitionInfoFields[LUA_TRANSITION_INFO_FIELD_COU
|
|||
{ "posYaw", LVT_S16, offsetof(struct TransitionInfo, posYaw), false, LOT_NONE, 1, sizeof(s16) },
|
||||
};
|
||||
|
||||
#define LUA_VTX_FIELD_COUNT 4
|
||||
#define LUA_VTX_FIELD_COUNT 13
|
||||
static struct LuaObjectField sVtxFields[LUA_VTX_FIELD_COUNT] = {
|
||||
{ "cn", LVT_U8, offsetof(Vtx_t, cn), false, LOT_NONE, 4, sizeof(unsigned char) },
|
||||
{ "flag", LVT_U16, offsetof(Vtx_t, flag), false, LOT_NONE, 1, sizeof(unsigned short) },
|
||||
{ "ob", LVT_F32, offsetof(Vtx_t, ob), false, LOT_NONE, 3, sizeof(float) },
|
||||
{ "tc", LVT_S16, offsetof(Vtx_t, tc), false, LOT_NONE, 2, sizeof(short) },
|
||||
{ "a", LVT_U8, offsetof(Vtx_L, a), false, LOT_NONE, 1, sizeof(unsigned char) },
|
||||
{ "b", LVT_U8, offsetof(Vtx_L, b), false, LOT_NONE, 1, sizeof(unsigned char) },
|
||||
{ "flag", LVT_U16, offsetof(Vtx_L, flag), false, LOT_NONE, 1, sizeof(unsigned short) },
|
||||
{ "g", LVT_U8, offsetof(Vtx_L, g), false, LOT_NONE, 1, sizeof(unsigned char) },
|
||||
{ "nx", LVT_S8, offsetof(Vtx_L, nx), false, LOT_NONE, 1, sizeof(signed char) },
|
||||
{ "ny", LVT_S8, offsetof(Vtx_L, ny), false, LOT_NONE, 1, sizeof(signed char) },
|
||||
{ "nz", LVT_S8, offsetof(Vtx_L, nz), false, LOT_NONE, 1, sizeof(signed char) },
|
||||
{ "r", LVT_U8, offsetof(Vtx_L, r), false, LOT_NONE, 1, sizeof(unsigned char) },
|
||||
{ "tu", LVT_S16, offsetof(Vtx_L, tu), false, LOT_NONE, 1, sizeof(short) },
|
||||
{ "tv", LVT_S16, offsetof(Vtx_L, tv), false, LOT_NONE, 1, sizeof(short) },
|
||||
{ "x", LVT_F32, offsetof(Vtx_L, x), false, LOT_NONE, 1, sizeof(float) },
|
||||
{ "y", LVT_F32, offsetof(Vtx_L, y), false, LOT_NONE, 1, sizeof(float) },
|
||||
{ "z", LVT_F32, offsetof(Vtx_L, z), false, LOT_NONE, 1, sizeof(float) },
|
||||
};
|
||||
|
||||
#define LUA_VTX__INTERP_FIELD_COUNT 2
|
||||
|
|
|
|||
|
|
@ -1313,59 +1313,31 @@ char gSmluaConstants[] = ""
|
|||
"G_COPYMEM=0xd2\n"
|
||||
#ifdef F3DEX_GBI_2
|
||||
"G_NOOP=0x00\n"
|
||||
"G_RDPHALF_2=0xf1\n"
|
||||
"G_SETOTHERMODE_H=0xe3\n"
|
||||
"G_SETOTHERMODE_L=0xe2\n"
|
||||
"G_RDPHALF_1=0xe1\n"
|
||||
"G_SPNOOP=0xe0\n"
|
||||
"G_ENDDL=0xdf\n"
|
||||
"G_DL=0xde\n"
|
||||
"G_LOAD_UCODE=0xdd\n"
|
||||
"G_MOVEMEM=0xdc\n"
|
||||
"G_MOVEWORD=0xdb\n"
|
||||
"G_MTX=0xda\n"
|
||||
"G_GEOMETRYMODE=0xd9\n"
|
||||
"G_POPMTX=0xd8\n"
|
||||
"G_TEXTURE=0xd7\n"
|
||||
"G_DMA_IO=0xd6\n"
|
||||
"G_SPECIAL_1=0xd5\n"
|
||||
"G_SPECIAL_2=0xd4\n"
|
||||
"G_SPECIAL_3=0xd3\n"
|
||||
"G_VTX=0x01\n"
|
||||
"G_MODIFYVTX=0x02\n"
|
||||
"G_CULLDL=0x03\n"
|
||||
"G_BRANCH_Z=0x04\n"
|
||||
"G_TRI1=0x05\n"
|
||||
"G_TRI2=0x06\n"
|
||||
"G_QUAD=0x07\n"
|
||||
"G_LINE3D=0x08\n"
|
||||
#else // #ifdef F3DEX_GBI_2
|
||||
"G_SPNOOP=0\n"
|
||||
"G_MTX=1\n"
|
||||
"G_RESERVED0=2\n"
|
||||
"G_MOVEMEM=3\n"
|
||||
"G_VTX=4\n"
|
||||
"G_RESERVED1=5\n"
|
||||
"G_DL=6\n"
|
||||
"G_RESERVED2=7\n"
|
||||
"G_RESERVED3=8\n"
|
||||
"G_SPRITE2D_BASE=9\n"
|
||||
"G_IMMFIRST=-65\n"
|
||||
"G_TRI1=(G_IMMFIRST-0)\n"
|
||||
"G_CULLDL=(G_IMMFIRST-1)\n"
|
||||
"G_POPMTX=(G_IMMFIRST-2)\n"
|
||||
"G_MOVEWORD=(G_IMMFIRST-3)\n"
|
||||
"G_TEXTURE=(G_IMMFIRST-4)\n"
|
||||
"G_SETOTHERMODE_H=(G_IMMFIRST-5)\n"
|
||||
"G_SETOTHERMODE_L=(G_IMMFIRST-6)\n"
|
||||
"G_ENDDL=(G_IMMFIRST-7)\n"
|
||||
"G_SETGEOMETRYMODE=(G_IMMFIRST-8)\n"
|
||||
"G_CLEARGEOMETRYMODE=(G_IMMFIRST-9)\n"
|
||||
"G_LINE3D=(G_IMMFIRST-10)\n"
|
||||
"G_RDPHALF_1=(G_IMMFIRST-11)\n"
|
||||
"G_RDPHALF_2=(G_IMMFIRST-12)\n"
|
||||
"G_SPRITE2D_SCALEFLIP=(G_IMMFIRST-1)\n"
|
||||
"G_SPRITE2D_DRAW=(G_IMMFIRST-2)\n"
|
||||
"G_NOOP=0xc0\n"
|
||||
#endif // #ifdef F3DEX_GBI_2
|
||||
"G_SETCIMG=0xff\n"
|
||||
|
|
@ -1383,325 +1355,9 @@ char gSmluaConstants[] = ""
|
|||
"G_LOADBLOCK=0xf3\n"
|
||||
"G_SETTILESIZE=0xf2\n"
|
||||
"G_LOADTLUT=0xf0\n"
|
||||
"G_RDPSETOTHERMODE=0xef\n"
|
||||
"G_SETPRIMDEPTH=0xee\n"
|
||||
"G_SETSCISSOR=0xed\n"
|
||||
"G_SETCONVERT=0xec\n"
|
||||
"G_SETKEYR=0xeb\n"
|
||||
"G_SETKEYGB=0xea\n"
|
||||
"G_RDPFULLSYNC=0xe9\n"
|
||||
"G_RDPTILESYNC=0xe8\n"
|
||||
"G_RDPPIPESYNC=0xe7\n"
|
||||
"G_RDPLOADSYNC=0xe6\n"
|
||||
"G_TEXRECTFLIP=0xe5\n"
|
||||
"G_TEXRECT=0xe4\n"
|
||||
"G_TRI_FILL=0xc8\n"
|
||||
"G_TRI_SHADE=0xcc\n"
|
||||
"G_TRI_TXTR=0xca\n"
|
||||
"G_TRI_SHADE_TXTR=0xce\n"
|
||||
"G_TRI_FILL_ZBUFF=0xc9\n"
|
||||
"G_TRI_SHADE_ZBUFF=0xcd\n"
|
||||
"G_TRI_TXTR_ZBUFF=0xcb\n"
|
||||
"G_TRI_SHADE_TXTR_ZBUFF=0xcf\n"
|
||||
"G_RDP_TRI_FILL_MASK=0x08\n"
|
||||
"G_RDP_TRI_SHADE_MASK=0x04\n"
|
||||
"G_RDP_TRI_TXTR_MASK=0x02\n"
|
||||
"G_RDP_TRI_ZBUFF_MASK=0x01\n"
|
||||
"BOWTIE_VAL=0\n"
|
||||
"G_RDP_ADDR_FIXUP=3\n"
|
||||
"G_DMACMDSIZ=128\n"
|
||||
"G_IMMCMDSIZ=64\n"
|
||||
"G_RDPCMDSIZ=64\n"
|
||||
"G_TEXTURE_IMAGE_FRAC=2\n"
|
||||
"G_TEXTURE_SCALE_FRAC=16\n"
|
||||
"G_SCALE_FRAC=8\n"
|
||||
"G_ROTATE_FRAC=16\n"
|
||||
"G_MAXFBZ=0x3fff\n"
|
||||
"G_ZBUFFER=0x00000001\n"
|
||||
"G_SHADE=0x00000004\n"
|
||||
"G_FOG=0x00010000\n"
|
||||
"G_LIGHTING=0x00020000\n"
|
||||
"G_TEXTURE_GEN=0x00040000\n"
|
||||
"G_TEXTURE_GEN_LINEAR=0x00080000\n"
|
||||
"G_LOD=0x00100000\n"
|
||||
"G_IM_FMT_RGBA=0\n"
|
||||
"G_IM_FMT_YUV=1\n"
|
||||
"G_IM_FMT_CI=2\n"
|
||||
"G_IM_FMT_IA=3\n"
|
||||
"G_IM_FMT_I=4\n"
|
||||
"G_IM_SIZ_4b=0\n"
|
||||
"G_IM_SIZ_8b=1\n"
|
||||
"G_IM_SIZ_16b=2\n"
|
||||
"G_IM_SIZ_32b=3\n"
|
||||
"G_IM_SIZ_DD=5\n"
|
||||
"G_IM_SIZ_4b_BYTES=0\n"
|
||||
"G_IM_SIZ_8b_BYTES=1\n"
|
||||
"G_IM_SIZ_16b_BYTES=2\n"
|
||||
"G_IM_SIZ_32b_BYTES=4\n"
|
||||
"G_IM_SIZ_32b_TILE_BYTES=2\n"
|
||||
"G_IM_SIZ_32b_LINE_BYTES=2\n"
|
||||
"G_IM_SIZ_4b_SHIFT=2\n"
|
||||
"G_IM_SIZ_8b_SHIFT=1\n"
|
||||
"G_IM_SIZ_16b_SHIFT=0\n"
|
||||
"G_IM_SIZ_32b_SHIFT=0\n"
|
||||
"G_IM_SIZ_4b_INCR=3\n"
|
||||
"G_IM_SIZ_8b_INCR=1\n"
|
||||
"G_IM_SIZ_16b_INCR=0\n"
|
||||
"G_IM_SIZ_32b_INCR=0\n"
|
||||
"G_CCMUX_COMBINED=0\n"
|
||||
"G_CCMUX_TEXEL0=1\n"
|
||||
"G_CCMUX_TEXEL1=2\n"
|
||||
"G_CCMUX_PRIMITIVE=3\n"
|
||||
"G_CCMUX_SHADE=4\n"
|
||||
"G_CCMUX_ENVIRONMENT=5\n"
|
||||
"G_CCMUX_CENTER=6\n"
|
||||
"G_CCMUX_SCALE=6\n"
|
||||
"G_CCMUX_COMBINED_ALPHA=7\n"
|
||||
"G_CCMUX_TEXEL0_ALPHA=8\n"
|
||||
"G_CCMUX_TEXEL1_ALPHA=9\n"
|
||||
"G_CCMUX_PRIMITIVE_ALPHA=10\n"
|
||||
"G_CCMUX_SHADE_ALPHA=11\n"
|
||||
"G_CCMUX_ENV_ALPHA=12\n"
|
||||
"G_CCMUX_LOD_FRACTION=13\n"
|
||||
"G_CCMUX_PRIM_LOD_FRAC=14\n"
|
||||
"G_CCMUX_NOISE=7\n"
|
||||
"G_CCMUX_K4=7\n"
|
||||
"G_CCMUX_K5=15\n"
|
||||
"G_CCMUX_1=6\n"
|
||||
"G_CCMUX_0=31\n"
|
||||
"G_ACMUX_COMBINED=0\n"
|
||||
"G_ACMUX_TEXEL0=1\n"
|
||||
"G_ACMUX_TEXEL1=2\n"
|
||||
"G_ACMUX_PRIMITIVE=3\n"
|
||||
"G_ACMUX_SHADE=4\n"
|
||||
"G_ACMUX_ENVIRONMENT=5\n"
|
||||
"G_ACMUX_LOD_FRACTION=0\n"
|
||||
"G_ACMUX_PRIM_LOD_FRAC=6\n"
|
||||
"G_ACMUX_1=6\n"
|
||||
"G_ACMUX_0=7\n"
|
||||
"G_MDSFT_ALPHACOMPARE=0\n"
|
||||
"G_MDSFT_ZSRCSEL=2\n"
|
||||
"G_MDSFT_RENDERMODE=3\n"
|
||||
"G_MDSFT_BLENDER=16\n"
|
||||
"G_MDSFT_BLENDMASK=0\n"
|
||||
"G_MDSFT_ALPHADITHER=4\n"
|
||||
"G_MDSFT_RGBDITHER=6\n"
|
||||
"G_MDSFT_COMBKEY=8\n"
|
||||
"G_MDSFT_TEXTCONV=9\n"
|
||||
"G_MDSFT_TEXTFILT=12\n"
|
||||
"G_MDSFT_TEXTLUT=14\n"
|
||||
"G_MDSFT_TEXTLOD=16\n"
|
||||
"G_MDSFT_TEXTDETAIL=17\n"
|
||||
"G_MDSFT_TEXTPERSP=19\n"
|
||||
"G_MDSFT_CYCLETYPE=20\n"
|
||||
"G_MDSFT_COLORDITHER=22\n"
|
||||
"G_MDSFT_PIPELINE=23\n"
|
||||
"G_PM_1PRIMITIVE=(1 << G_MDSFT_PIPELINE)\n"
|
||||
"G_PM_NPRIMITIVE=(0 << G_MDSFT_PIPELINE)\n"
|
||||
"G_CYC_1CYCLE=(0 << G_MDSFT_CYCLETYPE)\n"
|
||||
"G_CYC_2CYCLE=(1 << G_MDSFT_CYCLETYPE)\n"
|
||||
"G_CYC_COPY=(2 << G_MDSFT_CYCLETYPE)\n"
|
||||
"G_CYC_FILL=(3 << G_MDSFT_CYCLETYPE)\n"
|
||||
"G_TP_NONE=(0 << G_MDSFT_TEXTPERSP)\n"
|
||||
"G_TP_PERSP=(1 << G_MDSFT_TEXTPERSP)\n"
|
||||
"G_TD_CLAMP=(0 << G_MDSFT_TEXTDETAIL)\n"
|
||||
"G_TD_SHARPEN=(1 << G_MDSFT_TEXTDETAIL)\n"
|
||||
"G_TD_DETAIL=(2 << G_MDSFT_TEXTDETAIL)\n"
|
||||
"G_TL_TILE=(0 << G_MDSFT_TEXTLOD)\n"
|
||||
"G_TL_LOD=(1 << G_MDSFT_TEXTLOD)\n"
|
||||
"G_TT_NONE=(0 << G_MDSFT_TEXTLUT)\n"
|
||||
"G_TT_RGBA16=(2 << G_MDSFT_TEXTLUT)\n"
|
||||
"G_TT_IA16=(3 << G_MDSFT_TEXTLUT)\n"
|
||||
"G_TF_POINT=(0 << G_MDSFT_TEXTFILT)\n"
|
||||
"G_TF_AVERAGE=(3 << G_MDSFT_TEXTFILT)\n"
|
||||
"G_TF_BILERP=(2 << G_MDSFT_TEXTFILT)\n"
|
||||
"G_TC_CONV=(0 << G_MDSFT_TEXTCONV)\n"
|
||||
"G_TC_FILTCONV=(5 << G_MDSFT_TEXTCONV)\n"
|
||||
"G_TC_FILT=(6 << G_MDSFT_TEXTCONV)\n"
|
||||
"G_CK_NONE=(0 << G_MDSFT_COMBKEY)\n"
|
||||
"G_CK_KEY=(1 << G_MDSFT_COMBKEY)\n"
|
||||
"G_CD_MAGICSQ=(0 << G_MDSFT_RGBDITHER)\n"
|
||||
"G_CD_BAYER=(1 << G_MDSFT_RGBDITHER)\n"
|
||||
"G_CD_NOISE=(2 << G_MDSFT_RGBDITHER)\n"
|
||||
#ifndef _HW_VERSION_1
|
||||
"G_CD_DISABLE=(3 << G_MDSFT_RGBDITHER)\n"
|
||||
"G_CD_ENABLE=G_CD_NOISE\n"
|
||||
#else // #ifndef _HW_VERSION_1
|
||||
"G_CD_ENABLE=(1 << G_MDSFT_COLORDITHER)\n"
|
||||
"G_CD_DISABLE=(0 << G_MDSFT_COLORDITHER)\n"
|
||||
#endif // #ifndef _HW_VERSION_1
|
||||
"G_AD_PATTERN=(0 << G_MDSFT_ALPHADITHER)\n"
|
||||
"G_AD_NOTPATTERN=(1 << G_MDSFT_ALPHADITHER)\n"
|
||||
"G_AD_NOISE=(2 << G_MDSFT_ALPHADITHER)\n"
|
||||
"G_AD_DISABLE=(3 << G_MDSFT_ALPHADITHER)\n"
|
||||
"G_AC_NONE=(0 << G_MDSFT_ALPHACOMPARE)\n"
|
||||
"G_AC_THRESHOLD=(1 << G_MDSFT_ALPHACOMPARE)\n"
|
||||
"G_AC_DITHER=(3 << G_MDSFT_ALPHACOMPARE)\n"
|
||||
"G_ZS_PIXEL=(0 << G_MDSFT_ZSRCSEL)\n"
|
||||
"G_ZS_PRIM=(1 << G_MDSFT_ZSRCSEL)\n"
|
||||
"AA_EN=0x8\n"
|
||||
"Z_CMP=0x10\n"
|
||||
"Z_UPD=0x20\n"
|
||||
"IM_RD=0x40\n"
|
||||
"CLR_ON_CVG=0x80\n"
|
||||
"CVG_DST_CLAMP=0\n"
|
||||
"CVG_DST_WRAP=0x100\n"
|
||||
"CVG_DST_FULL=0x200\n"
|
||||
"CVG_DST_SAVE=0x300\n"
|
||||
"ZMODE_OPA=0\n"
|
||||
"ZMODE_INTER=0x400\n"
|
||||
"ZMODE_XLU=0x800\n"
|
||||
"ZMODE_DEC=0xc00\n"
|
||||
"CVG_X_ALPHA=0x1000\n"
|
||||
"ALPHA_CVG_SEL=0x2000\n"
|
||||
"FORCE_BL=0x4000\n"
|
||||
"TEX_EDGE=0x0000\n"
|
||||
"G_BL_CLR_IN=0\n"
|
||||
"G_BL_CLR_MEM=1\n"
|
||||
"G_BL_CLR_BL=2\n"
|
||||
"G_BL_CLR_FOG=3\n"
|
||||
"G_BL_1MA=0\n"
|
||||
"G_BL_A_MEM=1\n"
|
||||
"G_BL_A_IN=0\n"
|
||||
"G_BL_A_FOG=1\n"
|
||||
"G_BL_A_SHADE=2\n"
|
||||
"G_BL_1=2\n"
|
||||
"G_BL_0=3\n"
|
||||
"G_CV_K0=175\n"
|
||||
"G_CV_K1=-43\n"
|
||||
"G_CV_K2=-89\n"
|
||||
"G_CV_K3=222\n"
|
||||
"G_CV_K4=114\n"
|
||||
"G_CV_K5=42\n"
|
||||
"G_SC_NON_INTERLACE=0\n"
|
||||
"G_SC_ODD_INTERLACE=3\n"
|
||||
"G_SC_EVEN_INTERLACE=2\n"
|
||||
"G_DL_PUSH=0x00\n"
|
||||
"G_DL_NOPUSH=0x01\n"
|
||||
"G_MW_MATRIX=0x00\n"
|
||||
"G_MW_NUMLIGHT=0x02\n"
|
||||
"G_MW_CLIP=0x04\n"
|
||||
"G_MW_SEGMENT=0x06\n"
|
||||
"G_MW_FOG=0x08\n"
|
||||
"G_MW_LIGHTCOL=0x0a\n"
|
||||
"G_MW_PERSPNORM=0x0e\n"
|
||||
"G_MWO_NUMLIGHT=0x00\n"
|
||||
"G_MWO_CLIP_RNX=0x04\n"
|
||||
"G_MWO_CLIP_RNY=0x0c\n"
|
||||
"G_MWO_CLIP_RPX=0x14\n"
|
||||
"G_MWO_CLIP_RPY=0x1c\n"
|
||||
"G_MWO_SEGMENT_0=0x00\n"
|
||||
"G_MWO_SEGMENT_1=0x01\n"
|
||||
"G_MWO_SEGMENT_2=0x02\n"
|
||||
"G_MWO_SEGMENT_3=0x03\n"
|
||||
"G_MWO_SEGMENT_4=0x04\n"
|
||||
"G_MWO_SEGMENT_5=0x05\n"
|
||||
"G_MWO_SEGMENT_6=0x06\n"
|
||||
"G_MWO_SEGMENT_7=0x07\n"
|
||||
"G_MWO_SEGMENT_8=0x08\n"
|
||||
"G_MWO_SEGMENT_9=0x09\n"
|
||||
"G_MWO_SEGMENT_A=0x0a\n"
|
||||
"G_MWO_SEGMENT_B=0x0b\n"
|
||||
"G_MWO_SEGMENT_C=0x0c\n"
|
||||
"G_MWO_SEGMENT_D=0x0d\n"
|
||||
"G_MWO_SEGMENT_E=0x0e\n"
|
||||
"G_MWO_SEGMENT_F=0x0f\n"
|
||||
"G_MWO_FOG=0x00\n"
|
||||
"G_MWO_aLIGHT_1=0x00\n"
|
||||
"G_MWO_bLIGHT_1=0x04\n"
|
||||
#ifdef F3DEX_GBI_2
|
||||
"G_MWO_aLIGHT_2=0x18\n"
|
||||
"G_MWO_bLIGHT_2=0x1c\n"
|
||||
"G_MWO_aLIGHT_3=0x30\n"
|
||||
"G_MWO_bLIGHT_3=0x34\n"
|
||||
"G_MWO_aLIGHT_4=0x48\n"
|
||||
"G_MWO_bLIGHT_4=0x4c\n"
|
||||
"G_MWO_aLIGHT_5=0x60\n"
|
||||
"G_MWO_bLIGHT_5=0x64\n"
|
||||
"G_MWO_aLIGHT_6=0x78\n"
|
||||
"G_MWO_bLIGHT_6=0x7c\n"
|
||||
"G_MWO_aLIGHT_7=0x90\n"
|
||||
"G_MWO_bLIGHT_7=0x94\n"
|
||||
"G_MWO_aLIGHT_8=0xa8\n"
|
||||
"G_MWO_bLIGHT_8=0xac\n"
|
||||
#else // #ifdef F3DEX_GBI_2
|
||||
"G_MWO_aLIGHT_2=0x20\n"
|
||||
"G_MWO_bLIGHT_2=0x24\n"
|
||||
"G_MWO_aLIGHT_3=0x40\n"
|
||||
"G_MWO_bLIGHT_3=0x44\n"
|
||||
"G_MWO_aLIGHT_4=0x60\n"
|
||||
"G_MWO_bLIGHT_4=0x64\n"
|
||||
"G_MWO_aLIGHT_5=0x80\n"
|
||||
"G_MWO_bLIGHT_5=0x84\n"
|
||||
"G_MWO_aLIGHT_6=0xa0\n"
|
||||
"G_MWO_bLIGHT_6=0xa4\n"
|
||||
"G_MWO_aLIGHT_7=0xc0\n"
|
||||
"G_MWO_bLIGHT_7=0xc4\n"
|
||||
"G_MWO_aLIGHT_8=0xe0\n"
|
||||
"G_MWO_bLIGHT_8=0xe4\n"
|
||||
#endif // #ifdef F3DEX_GBI_2
|
||||
"G_MWO_MATRIX_XX_XY_I=0x00\n"
|
||||
"G_MWO_MATRIX_XZ_XW_I=0x04\n"
|
||||
"G_MWO_MATRIX_YX_YY_I=0x08\n"
|
||||
"G_MWO_MATRIX_YZ_YW_I=0x0c\n"
|
||||
"G_MWO_MATRIX_ZX_ZY_I=0x10\n"
|
||||
"G_MWO_MATRIX_ZZ_ZW_I=0x14\n"
|
||||
"G_MWO_MATRIX_WX_WY_I=0x18\n"
|
||||
"G_MWO_MATRIX_WZ_WW_I=0x1c\n"
|
||||
"G_MWO_MATRIX_XX_XY_F=0x20\n"
|
||||
"G_MWO_MATRIX_XZ_XW_F=0x24\n"
|
||||
"G_MWO_MATRIX_YX_YY_F=0x28\n"
|
||||
"G_MWO_MATRIX_YZ_YW_F=0x2c\n"
|
||||
"G_MWO_MATRIX_ZX_ZY_F=0x30\n"
|
||||
"G_MWO_MATRIX_ZZ_ZW_F=0x34\n"
|
||||
"G_MWO_MATRIX_WX_WY_F=0x38\n"
|
||||
"G_MWO_MATRIX_WZ_WW_F=0x3c\n"
|
||||
"G_MWO_POINT_RGBA=0x10\n"
|
||||
"G_MWO_POINT_ST=0x14\n"
|
||||
"G_MWO_POINT_XYSCREEN=0x18\n"
|
||||
"G_MWO_POINT_ZSCREEN=0x1c\n"
|
||||
"FR_NEG_FRUSTRATIO_1=0x00000001\n"
|
||||
"FR_POS_FRUSTRATIO_1=0x0000ffff\n"
|
||||
"FR_NEG_FRUSTRATIO_2=0x00000002\n"
|
||||
"FR_POS_FRUSTRATIO_2=0x0000fffe\n"
|
||||
"FR_NEG_FRUSTRATIO_3=0x00000003\n"
|
||||
"FR_POS_FRUSTRATIO_3=0x0000fffd\n"
|
||||
"FR_NEG_FRUSTRATIO_4=0x00000004\n"
|
||||
"FR_POS_FRUSTRATIO_4=0x0000fffc\n"
|
||||
"FR_NEG_FRUSTRATIO_5=0x00000005\n"
|
||||
"FR_POS_FRUSTRATIO_5=0x0000fffb\n"
|
||||
"FR_NEG_FRUSTRATIO_6=0x00000006\n"
|
||||
"FR_POS_FRUSTRATIO_6=0x0000fffa\n"
|
||||
"NUMLIGHTS_0=1\n"
|
||||
"NUMLIGHTS_1=1\n"
|
||||
"NUMLIGHTS_2=2\n"
|
||||
"NUMLIGHTS_3=3\n"
|
||||
"NUMLIGHTS_4=4\n"
|
||||
"NUMLIGHTS_5=5\n"
|
||||
"NUMLIGHTS_6=6\n"
|
||||
"NUMLIGHTS_7=7\n"
|
||||
"LIGHT_1=1\n"
|
||||
"LIGHT_2=2\n"
|
||||
"LIGHT_3=3\n"
|
||||
"LIGHT_4=4\n"
|
||||
"LIGHT_5=5\n"
|
||||
"LIGHT_6=6\n"
|
||||
"LIGHT_7=7\n"
|
||||
"LIGHT_8=8\n"
|
||||
"G_TX_LOADTILE=7\n"
|
||||
"G_TX_RENDERTILE=0\n"
|
||||
"G_TX_NOMIRROR=0\n"
|
||||
"G_TX_WRAP=0\n"
|
||||
"G_TX_MIRROR=0x1\n"
|
||||
"G_TX_CLAMP=0x2\n"
|
||||
"G_TX_NOMASK=0\n"
|
||||
"G_TX_NOLOD=0\n"
|
||||
"G_TX_DXT_FRAC=11\n"
|
||||
#ifdef _HW_VERSION_1
|
||||
"G_TX_LDBLK_MAX_TXL=4095\n"
|
||||
#else // #ifdef _HW_VERSION_1
|
||||
"G_TX_LDBLK_MAX_TXL=2047\n"
|
||||
#endif // #ifdef _HW_VERSION_1
|
||||
"BACKGROUND_OCEAN_SKY=0\n"
|
||||
"BACKGROUND_FLAMING_SKY=1\n"
|
||||
"BACKGROUND_UNDERWATER_CITY=2\n"
|
||||
|
|
|
|||
|
|
@ -1067,44 +1067,78 @@ int smlua_func_get_uncolored_string(lua_State* L) {
|
|||
// display list //
|
||||
//////////////////
|
||||
|
||||
#define HANDLE_PARAM(paramNum) \
|
||||
s64 arg##paramNum = smlua_to_integer(L, 2 + paramNum); \
|
||||
if (!gSmLuaConvertSuccess) { \
|
||||
LOG_LUA("gfx_set_command: '%s' failed to convert parameter " #paramNum ".", symbolName); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define GET_ARG(paramNum) arg##paramNum
|
||||
#define CALL_SYMB(symb, ...) symb(__VA_ARGS__)
|
||||
|
||||
// Uses macro iterators to dynamically handle the correct number of parameters
|
||||
#define define_gfx_symbol(symb, params, ...) \
|
||||
if (strcmp(command, #symb) == 0) { \
|
||||
if (paramCount != params) { LOG_LUA("gfx_set_command: '" #symb "' received incorrect number of parameters. Received %u, expected %u", paramCount, params); return 0; } \
|
||||
UNUSED const char symbolName[] = #symb; \
|
||||
REPEAT(HANDLE_PARAM, params); \
|
||||
const Gfx _Gfx[] = { CALL_SYMB(symb, LIST_ARGS(GET_ARG, params)) }; \
|
||||
memcpy(gfx, _Gfx, sizeof(_Gfx)); \
|
||||
return 1; \
|
||||
static int get_gfx_command_specifiers_count(const char *command) {
|
||||
int count = 0;
|
||||
for (; *command; count += (*command == '%'), command++);
|
||||
return count;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_set_command(lua_State* L) {
|
||||
int top = lua_gettop(L);
|
||||
if (top < 2) {
|
||||
LOG_LUA_LINE("Improper param count: Expected at least 2, Received %u", top);
|
||||
LOG_LUA_LINE("gfx_set_command: Improper param count: Expected at least 2, Received %u", top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Gfx* gfx = smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_set_command"); return 0; }
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
LOG_LUA("gfx_set_command: Failed to convert parameter %u", 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *command = smlua_to_string(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_set_command"); return 0; }
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
LOG_LUA("gfx_set_command: Failed to convert parameter %u", 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 paramCount = top - 2;
|
||||
// Compare the number of provided parameters to the number of specifiers in the command
|
||||
int paramCount = top - 2;
|
||||
int specifiersCount = get_gfx_command_specifiers_count(command);
|
||||
if (specifiersCount != paramCount) {
|
||||
LOG_LUA_LINE("gfx_set_command: Command \"%s\": Invalid number of command parameters: Expected %u, provided %u", command, specifiersCount, paramCount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle commands using the define_gfx_symbol macro
|
||||
GFX_SYMBOLS();
|
||||
// Parse the command
|
||||
const u32 errorSize = 0x400;
|
||||
char errorMsg[errorSize];
|
||||
if (!dynos_smlua_parse_gfx_command(L, gfx, command, specifiersCount != 0, errorMsg, errorSize)) {
|
||||
LOG_LUA_LINE("gfx_set_command: Command \"%s\": %s", command, errorMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_get_from_name(lua_State *L) {
|
||||
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
const char *name = smlua_to_string(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("gfx_get_from_name: Failed to convert parameter 1"); return 0; }
|
||||
|
||||
u32 length = 0;
|
||||
Gfx *gfx = dynos_gfx_get(name, &length);
|
||||
|
||||
smlua_push_object(L, LOT_GFX, gfx, NULL);
|
||||
lua_pushinteger(L, length);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int smlua_func_vtx_get_from_name(lua_State *L) {
|
||||
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
||||
|
||||
const char *name = smlua_to_string(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("vtx_get_from_name: Failed to convert parameter 1"); return 0; }
|
||||
|
||||
u32 count = 0;
|
||||
Vtx *vtx = dynos_vtx_get(name, &count);
|
||||
|
||||
smlua_push_object(L, LOT_VTX, vtx, NULL);
|
||||
lua_pushinteger(L, count);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
//////////
|
||||
|
|
@ -1139,4 +1173,6 @@ void smlua_bind_functions(void) {
|
|||
smlua_bind_function(L, "cast_graph_node", smlua_func_cast_graph_node);
|
||||
smlua_bind_function(L, "get_uncolored_string", smlua_func_get_uncolored_string);
|
||||
smlua_bind_function(L, "gfx_set_command", smlua_func_gfx_set_command);
|
||||
smlua_bind_function(L, "gfx_get_from_name", smlua_func_gfx_get_from_name);
|
||||
smlua_bind_function(L, "vtx_get_from_name", smlua_func_vtx_get_from_name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30125,7 +30125,7 @@ int smlua_func_gfx_parse(lua_State* L) {
|
|||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx* cmd = (Gfx*)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
Gfx * cmd = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_parse"); return 0; }
|
||||
LuaFunction func = smlua_to_lua_function(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_parse"); return 0; }
|
||||
|
|
@ -30135,116 +30135,346 @@ int smlua_func_gfx_parse(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_get_vtx(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_vtx", 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx* gfx = (Gfx*)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_vtx"); return 0; }
|
||||
u16 offset = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_get_vtx"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_VTX, gfx_get_vtx(gfx, offset), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_get_vtx_count(lua_State* L) {
|
||||
int smlua_func_gfx_get_op(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_vtx_count", 1, top);
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_op", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx* cmd = (Gfx*)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_vtx_count"); return 0; }
|
||||
Gfx * cmd = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_op"); return 0; }
|
||||
|
||||
lua_pushinteger(L, gfx_get_vtx_count(cmd));
|
||||
lua_pushinteger(L, gfx_get_op(cmd));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_set_combine_lerp(lua_State* L) {
|
||||
int smlua_func_gfx_get_display_list(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 17) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_set_combine_lerp", 17, top);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_display_list", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx* gfx = (Gfx*)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 a0 = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 b0 = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 c0 = smlua_to_integer(L, 4);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 d0 = smlua_to_integer(L, 5);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 Aa0 = smlua_to_integer(L, 6);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 6, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 Ab0 = smlua_to_integer(L, 7);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 7, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 Ac0 = smlua_to_integer(L, 8);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 8, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 Ad0 = smlua_to_integer(L, 9);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 9, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 a1 = smlua_to_integer(L, 10);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 10, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 b1 = smlua_to_integer(L, 11);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 11, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 c1 = smlua_to_integer(L, 12);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 12, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 d1 = smlua_to_integer(L, 13);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 13, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 Aa1 = smlua_to_integer(L, 14);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 14, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 Ab1 = smlua_to_integer(L, 15);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 15, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 Ac1 = smlua_to_integer(L, 16);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 16, "gfx_set_combine_lerp"); return 0; }
|
||||
u32 Ad1 = smlua_to_integer(L, 17);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 17, "gfx_set_combine_lerp"); return 0; }
|
||||
Gfx * cmd = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_display_list"); return 0; }
|
||||
|
||||
gfx_set_combine_lerp(gfx, a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1);
|
||||
smlua_push_object(L, LOT_GFX, gfx_get_display_list(cmd), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_set_texture_image(lua_State* L) {
|
||||
int smlua_func_gfx_get_vertex_buffer(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 5) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_set_texture_image", 5, top);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_vertex_buffer", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx* gfx = (Gfx*)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_set_texture_image"); return 0; }
|
||||
u32 format = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_set_texture_image"); return 0; }
|
||||
u32 size = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "gfx_set_texture_image"); return 0; }
|
||||
u32 width = smlua_to_integer(L, 4);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "gfx_set_texture_image"); return 0; }
|
||||
u8* texture = (u8*)smlua_to_cpointer(L, 5, LVT_U8_P);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "gfx_set_texture_image"); return 0; }
|
||||
Gfx * cmd = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_vertex_buffer"); return 0; }
|
||||
|
||||
gfx_set_texture_image(gfx, format, size, width, texture);
|
||||
smlua_push_object(L, LOT_VTX, gfx_get_vertex_buffer(cmd), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_get_vertex_count(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_vertex_count", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx * cmd = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_vertex_count"); return 0; }
|
||||
|
||||
lua_pushinteger(L, gfx_get_vertex_count(cmd));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_get_length(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_length", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx * gfx = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_length"); return 0; }
|
||||
|
||||
lua_pushinteger(L, gfx_get_length(gfx));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_get_command(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_command", 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx * gfx = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_command"); return 0; }
|
||||
u32 offset = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_get_command"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_GFX, gfx_get_command(gfx, offset), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_get_next_command(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_next_command", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx * gfx = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_next_command"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_GFX, gfx_get_next_command(gfx), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_copy(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 3) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_copy", 3, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx * dest = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_copy"); return 0; }
|
||||
if (lua_isnil(L, 2)) { return 0; }
|
||||
Gfx * src = (Gfx *)smlua_to_cobject(L, 2, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_copy"); return 0; }
|
||||
u32 length = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "gfx_copy"); return 0; }
|
||||
|
||||
gfx_copy(dest, src, length);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_new(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_new", 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* name = smlua_to_string(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_new"); return 0; }
|
||||
u32 length = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_new"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_GFX, gfx_new(name, length), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_realloc(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_realloc", 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx * gfx = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_realloc"); return 0; }
|
||||
u32 newLength = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_realloc"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_GFX, gfx_realloc(gfx, newLength), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_gfx_delete(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_delete", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Gfx * gfx = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_delete"); return 0; }
|
||||
|
||||
gfx_delete(gfx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_vtx_get_count(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_get_count", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Vtx * vtx = (Vtx *)smlua_to_cobject(L, 1, LOT_VTX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_get_count"); return 0; }
|
||||
|
||||
lua_pushinteger(L, vtx_get_count(vtx));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_vtx_get_vertex(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_get_vertex", 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Vtx * vtx = (Vtx *)smlua_to_cobject(L, 1, LOT_VTX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_get_vertex"); return 0; }
|
||||
u32 offset = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "vtx_get_vertex"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_VTX, vtx_get_vertex(vtx, offset), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_vtx_get_next_vertex(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_get_next_vertex", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Vtx * vtx = (Vtx *)smlua_to_cobject(L, 1, LOT_VTX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_get_next_vertex"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_VTX, vtx_get_next_vertex(vtx), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_vtx_copy(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 3) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_copy", 3, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Vtx * dest = (Vtx *)smlua_to_cobject(L, 1, LOT_VTX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_copy"); return 0; }
|
||||
if (lua_isnil(L, 2)) { return 0; }
|
||||
Vtx * src = (Vtx *)smlua_to_cobject(L, 2, LOT_VTX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "vtx_copy"); return 0; }
|
||||
u32 count = smlua_to_integer(L, 3);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "vtx_copy"); return 0; }
|
||||
|
||||
vtx_copy(dest, src, count);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_vtx_new(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_new", 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* name = smlua_to_string(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_new"); return 0; }
|
||||
u32 count = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "vtx_new"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_VTX, vtx_new(name, count), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_vtx_realloc(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 2) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_realloc", 2, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Vtx * vtx = (Vtx *)smlua_to_cobject(L, 1, LOT_VTX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_realloc"); return 0; }
|
||||
u32 newCount = smlua_to_integer(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "vtx_realloc"); return 0; }
|
||||
|
||||
smlua_push_object(L, LOT_VTX, vtx_realloc(vtx, newCount), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_vtx_delete(lua_State* L) {
|
||||
if (L == NULL) { return 0; }
|
||||
|
||||
int top = lua_gettop(L);
|
||||
if (top != 1) {
|
||||
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_delete", 1, top);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lua_isnil(L, 1)) { return 0; }
|
||||
Vtx * vtx = (Vtx *)smlua_to_cobject(L, 1, LOT_VTX);
|
||||
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_delete"); return 0; }
|
||||
|
||||
vtx_delete(vtx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -35626,10 +35856,24 @@ void smlua_bind_functions_autogen(void) {
|
|||
smlua_bind_function(L, "get_skybox_color", smlua_func_get_skybox_color);
|
||||
smlua_bind_function(L, "set_skybox_color", smlua_func_set_skybox_color);
|
||||
smlua_bind_function(L, "gfx_parse", smlua_func_gfx_parse);
|
||||
smlua_bind_function(L, "gfx_get_vtx", smlua_func_gfx_get_vtx);
|
||||
smlua_bind_function(L, "gfx_get_vtx_count", smlua_func_gfx_get_vtx_count);
|
||||
smlua_bind_function(L, "gfx_set_combine_lerp", smlua_func_gfx_set_combine_lerp);
|
||||
smlua_bind_function(L, "gfx_set_texture_image", smlua_func_gfx_set_texture_image);
|
||||
smlua_bind_function(L, "gfx_get_op", smlua_func_gfx_get_op);
|
||||
smlua_bind_function(L, "gfx_get_display_list", smlua_func_gfx_get_display_list);
|
||||
smlua_bind_function(L, "gfx_get_vertex_buffer", smlua_func_gfx_get_vertex_buffer);
|
||||
smlua_bind_function(L, "gfx_get_vertex_count", smlua_func_gfx_get_vertex_count);
|
||||
smlua_bind_function(L, "gfx_get_length", smlua_func_gfx_get_length);
|
||||
smlua_bind_function(L, "gfx_get_command", smlua_func_gfx_get_command);
|
||||
smlua_bind_function(L, "gfx_get_next_command", smlua_func_gfx_get_next_command);
|
||||
smlua_bind_function(L, "gfx_copy", smlua_func_gfx_copy);
|
||||
smlua_bind_function(L, "gfx_new", smlua_func_gfx_new);
|
||||
smlua_bind_function(L, "gfx_realloc", smlua_func_gfx_realloc);
|
||||
smlua_bind_function(L, "gfx_delete", smlua_func_gfx_delete);
|
||||
smlua_bind_function(L, "vtx_get_count", smlua_func_vtx_get_count);
|
||||
smlua_bind_function(L, "vtx_get_vertex", smlua_func_vtx_get_vertex);
|
||||
smlua_bind_function(L, "vtx_get_next_vertex", smlua_func_vtx_get_next_vertex);
|
||||
smlua_bind_function(L, "vtx_copy", smlua_func_vtx_copy);
|
||||
smlua_bind_function(L, "vtx_new", smlua_func_vtx_new);
|
||||
smlua_bind_function(L, "vtx_realloc", smlua_func_vtx_realloc);
|
||||
smlua_bind_function(L, "vtx_delete", smlua_func_vtx_delete);
|
||||
|
||||
// smlua_level_utils.h
|
||||
smlua_bind_function(L, "smlua_level_util_change_area", smlua_func_smlua_level_util_change_area);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include "game/rendering_graph_node.h"
|
||||
#include "game/skybox.h"
|
||||
#include "geo_commands.h"
|
||||
#include "engine/display_list.h"
|
||||
|
||||
void set_override_fov(f32 fov) {
|
||||
gOverrideFOV = fov;
|
||||
|
|
@ -108,16 +107,70 @@ void set_skybox_color(u8 index, u8 value) {
|
|||
gSkyboxColor[index] = value;
|
||||
}
|
||||
|
||||
///
|
||||
///////////////////
|
||||
// Display lists //
|
||||
///////////////////
|
||||
|
||||
//
|
||||
// The following code and functions assume the current microcode
|
||||
// is Fast3DEX2 Extended, and all commands are of size 1
|
||||
//
|
||||
|
||||
#ifndef GBI_NO_MULTI_COMMANDS
|
||||
#error "GBI_NO_MULTI_COMMANDS not set: All GBI commands must be of size 1"
|
||||
#endif
|
||||
#ifndef F3DEX_GBI_2E
|
||||
#error "F3DEX_GBI_2E not set: Microcode must be set to `f3dex2e`"
|
||||
#endif
|
||||
|
||||
//
|
||||
// Sentinel values for dynamically allocated Gfx and Vtx buffers
|
||||
// It will prevent out-of-bounds accesses and buffer overflows
|
||||
//
|
||||
// SENTINEL_GFX is a gsSPEndDisplayList() with all other bits set
|
||||
// SENTINEL_VTX bits are all set, which results in a bunch of NaN when treated as a Vtx
|
||||
//
|
||||
|
||||
static const Gfx SENTINEL_GFX[1] = {{{ _SHIFTL(G_ENDDL, 24, 8) | _SHIFTL(UINT32_MAX, 0, 24), UINT32_MAX }}};
|
||||
static const u8 SENTINEL_VTX[sizeof(Vtx)] = {[0 ... sizeof(Vtx) - 1] = UINT8_MAX};
|
||||
|
||||
Gfx *gfx_allocate_internal(u32 length) {
|
||||
if (!length) { return NULL; }
|
||||
Gfx *gfx = calloc(length + 1, sizeof(Gfx));
|
||||
memcpy(gfx + length, SENTINEL_GFX, sizeof(Gfx));
|
||||
return gfx;
|
||||
}
|
||||
|
||||
Vtx *vtx_allocate_internal(u32 count) {
|
||||
if (!count) { return NULL; }
|
||||
Vtx *vtx = calloc(count + 1, sizeof(Vtx));
|
||||
memcpy(vtx + count, SENTINEL_VTX, sizeof(Vtx));
|
||||
return vtx;
|
||||
}
|
||||
|
||||
// Get the size of a display list by iterating
|
||||
// until gsSPEndDisplayList or gsSPBranchList is found
|
||||
u32 gfx_get_length_no_sentinel(const Gfx *gfx) {
|
||||
if (!gfx) { return 0; }
|
||||
for (u32 i = 0;; ++i) {
|
||||
u32 op = GFX_OP(gfx + i);
|
||||
switch (op) {
|
||||
case G_DL:
|
||||
if (C0(gfx + i, 16, 1) == G_DL_NOPUSH) { return i + 1; } // For displaylists that end with branches (jumps)
|
||||
break;
|
||||
case G_ENDDL:
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assumes the current microcode is Fast3DEX2 Extended (default for pc port)
|
||||
void gfx_parse(Gfx* cmd, LuaFunction func) {
|
||||
if (!cmd) { return; }
|
||||
if (func == 0) { return; }
|
||||
|
||||
lua_State* L = gLuaState;
|
||||
while (true) {
|
||||
u32 op = cmd->words.w0 >> 24;
|
||||
for (;; cmd++) {
|
||||
u32 op = GFX_OP(cmd);
|
||||
switch (op) {
|
||||
case G_DL:
|
||||
if (C0(cmd, 16, 1) == G_DL_PUSH) {
|
||||
|
|
@ -127,16 +180,10 @@ void gfx_parse(Gfx* cmd, LuaFunction func) {
|
|||
--cmd;
|
||||
}
|
||||
break;
|
||||
|
||||
case (uint8_t) G_ENDDL:
|
||||
return; // Reached end of display list
|
||||
case G_TEXRECT:
|
||||
case G_TEXRECTFLIP:
|
||||
++cmd;
|
||||
++cmd;
|
||||
break;
|
||||
case G_FILLRECT:
|
||||
++cmd;
|
||||
break;
|
||||
|
||||
default:
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, func);
|
||||
smlua_push_object(L, LOT_GFX, cmd, NULL);
|
||||
|
|
@ -149,37 +196,196 @@ void gfx_parse(Gfx* cmd, LuaFunction func) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
++cmd;
|
||||
}
|
||||
}
|
||||
|
||||
Vtx *gfx_get_vtx(Gfx* cmd, u16 offset) {
|
||||
u32 gfx_get_op(Gfx *cmd) {
|
||||
if (!cmd) { return G_NOOP; }
|
||||
|
||||
return GFX_OP(cmd);
|
||||
}
|
||||
|
||||
Gfx *gfx_get_display_list(Gfx *cmd) {
|
||||
if (!cmd) { return NULL; }
|
||||
u32 op = cmd->words.w0 >> 24;
|
||||
u32 op = GFX_OP(cmd);
|
||||
if (op != G_DL) { return NULL; }
|
||||
if (cmd->words.w1 == 0) { return NULL; }
|
||||
|
||||
return (Gfx *) cmd->words.w1;
|
||||
}
|
||||
|
||||
Vtx *gfx_get_vertex_buffer(Gfx *cmd) {
|
||||
if (!cmd) { return NULL; }
|
||||
u32 op = GFX_OP(cmd);
|
||||
if (op != G_VTX) { return NULL; }
|
||||
if (cmd->words.w1 == 0) { return NULL; }
|
||||
|
||||
u16 numVertices = C0(cmd, 12, 8);
|
||||
if (offset >= numVertices) { return NULL; }
|
||||
|
||||
return &((Vtx *) cmd->words.w1)[offset];
|
||||
return (Vtx *) cmd->words.w1;
|
||||
}
|
||||
|
||||
u16 gfx_get_vtx_count(Gfx* cmd) {
|
||||
u16 gfx_get_vertex_count(Gfx *cmd) {
|
||||
if (!cmd) { return 0; }
|
||||
u32 op = cmd->words.w0 >> 24;
|
||||
u32 op = GFX_OP(cmd);
|
||||
if (op != G_VTX) { return 0; }
|
||||
if (cmd->words.w1 == 0) { return 0; }
|
||||
|
||||
return C0(cmd, 12, 8);
|
||||
}
|
||||
|
||||
void gfx_set_combine_lerp(Gfx* gfx, u32 a0, u32 b0, u32 c0, u32 d0, u32 Aa0, u32 Ab0, u32 Ac0, u32 Ad0, u32 a1, u32 b1, u32 c1, u32 d1, u32 Aa1, u32 Ab1, u32 Ac1, u32 Ad1) {
|
||||
if (!gfx) { return; }
|
||||
gDPSetCombineLERPNoString(gfx, a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1);
|
||||
u32 gfx_get_length(Gfx *gfx) {
|
||||
if (!gfx) { return 0; }
|
||||
|
||||
u32 length = 0;
|
||||
for (; memcmp(gfx, SENTINEL_GFX, sizeof(Gfx)) != 0; ++length, gfx++);
|
||||
return length;
|
||||
}
|
||||
|
||||
void gfx_set_texture_image(Gfx* gfx, u32 format, u32 size, u32 width, u8* texture) {
|
||||
if (!gfx) { return; }
|
||||
gDPSetTextureImage(gfx, format, size, width, texture);
|
||||
Gfx *gfx_get_command(Gfx *gfx, u32 offset) {
|
||||
if (!gfx) { return NULL; }
|
||||
if (offset >= gfx_get_length(gfx)) { return NULL; }
|
||||
|
||||
return &gfx[offset];
|
||||
}
|
||||
|
||||
Gfx *gfx_get_next_command(Gfx *gfx) {
|
||||
if (!gfx) { return NULL; }
|
||||
|
||||
gfx++;
|
||||
return memcmp(gfx, SENTINEL_GFX, sizeof(Gfx)) != 0 ? gfx : NULL;
|
||||
}
|
||||
|
||||
void gfx_copy(Gfx *dest, Gfx *src, u32 length) {
|
||||
if (!src || !dest || !length) { return; }
|
||||
|
||||
u32 srcLength = gfx_get_length(src);
|
||||
if (length > srcLength) {
|
||||
LOG_LUA_LINE("gfx_copy: Cannot copy %u commands from a display list of length: %u", length, srcLength);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 destLength = gfx_get_length(dest);
|
||||
if (length > destLength) {
|
||||
LOG_LUA_LINE("gfx_copy: Cannot copy %u commands to a display list of length: %u", length, srcLength);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dest, src, length * sizeof(Gfx));
|
||||
}
|
||||
|
||||
Gfx *gfx_new(const char *name, u32 length) {
|
||||
if (!name || !length) { return NULL; }
|
||||
|
||||
// Make sure to not take the name of a level/model/vanilla display list
|
||||
u32 outLength;
|
||||
if (dynos_gfx_get(name, &outLength)) {
|
||||
LOG_LUA_LINE("gfx_new: Display list `%s` already exists", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Gfx *gfx = dynos_gfx_new(name, length);
|
||||
if (!gfx) {
|
||||
LOG_LUA_LINE("gfx_new: Display list `%s` already exists", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gfx;
|
||||
}
|
||||
|
||||
Gfx *gfx_realloc(Gfx *gfx, u32 newLength) {
|
||||
if (!gfx || !newLength) { return NULL; }
|
||||
|
||||
Gfx *newGfx = dynos_gfx_realloc(gfx, newLength);
|
||||
if (!newGfx) {
|
||||
LOG_LUA_LINE("gfx_realloc: Display list was not allocated by `gfx_new`");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newGfx;
|
||||
}
|
||||
|
||||
void gfx_delete(Gfx *gfx) {
|
||||
if (!gfx) { return; }
|
||||
|
||||
if (!dynos_gfx_delete(gfx)) {
|
||||
LOG_LUA_LINE("gfx_delete: Display list was not allocated by `gfx_new`");
|
||||
}
|
||||
}
|
||||
|
||||
u32 vtx_get_count(Vtx *vtx) {
|
||||
if (!vtx) { return 0; }
|
||||
|
||||
u32 count = 0;
|
||||
for (; memcmp(vtx, SENTINEL_VTX, sizeof(Vtx)) != 0; ++count, vtx++);
|
||||
return count;
|
||||
}
|
||||
|
||||
Vtx *vtx_get_vertex(Vtx *vtx, u32 offset) {
|
||||
if (!vtx) { return NULL; }
|
||||
if (offset >= vtx_get_count(vtx)) { return NULL; }
|
||||
|
||||
return &vtx[offset];
|
||||
}
|
||||
|
||||
Vtx *vtx_get_next_vertex(Vtx *vtx) {
|
||||
if (!vtx) { return NULL; }
|
||||
|
||||
vtx++;
|
||||
return memcmp(vtx, SENTINEL_VTX, sizeof(Vtx)) != 0 ? vtx : NULL;
|
||||
}
|
||||
|
||||
void vtx_copy(Vtx *dest, Vtx *src, u32 count) {
|
||||
if (!src || !dest || !count) { return; }
|
||||
|
||||
u32 srcLength = vtx_get_count(src);
|
||||
if (count > srcLength) {
|
||||
LOG_LUA_LINE("vtx_copy: Cannot copy %u vertices from a vertex buffer of count: %u", count, srcLength);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 destLength = vtx_get_count(dest);
|
||||
if (count > destLength) {
|
||||
LOG_LUA_LINE("vtx_copy: Cannot copy %u vertices to a vertex buffer of count: %u", count, srcLength);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dest, src, count * sizeof(Vtx));
|
||||
}
|
||||
|
||||
Vtx *vtx_new(const char *name, u32 count) {
|
||||
if (!name || !count) { return NULL; }
|
||||
|
||||
// Make sure to not take the name of a level/model/vanilla vertex buffer
|
||||
u32 outCount;
|
||||
if (dynos_vtx_get(name, &outCount)) {
|
||||
LOG_LUA_LINE("vtx_new: Vertex buffer `%s` already exists", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Vtx *vtx = dynos_vtx_new(name, count);
|
||||
if (!vtx) {
|
||||
LOG_LUA_LINE("vtx_new: Vertex buffer `%s` already exists", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vtx;
|
||||
}
|
||||
|
||||
Vtx *vtx_realloc(Vtx *vtx, u32 newCount) {
|
||||
if (!vtx || !newCount) { return NULL; }
|
||||
|
||||
Vtx *newVtx = dynos_vtx_realloc(vtx, newCount);
|
||||
if (!newVtx) {
|
||||
LOG_LUA_LINE("vtx_realloc: Vertex buffer was not allocated by `vtx_new`");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newVtx;
|
||||
}
|
||||
|
||||
void vtx_delete(Vtx *vtx) {
|
||||
if (!vtx) { return; }
|
||||
|
||||
if (!dynos_vtx_delete(vtx)) {
|
||||
LOG_LUA_LINE("vtx_delete: Vertex buffer was not allocated by `vtx_new`");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@
|
|||
#include "pc/lua/smlua.h"
|
||||
#include "types.h"
|
||||
|
||||
#define C0(cmd, pos, width) (((cmd)->words.w0 >> (pos)) & ((1U << width) - 1))
|
||||
#define GFX_OP(cmd) C0(cmd, 24, 8)
|
||||
|
||||
Gfx *gfx_allocate_internal(u32 length);
|
||||
Vtx *vtx_allocate_internal(u32 count);
|
||||
u32 gfx_get_length_no_sentinel(const Gfx *gfx);
|
||||
|
||||
/* |description|Sets the override FOV|descriptionEnd| */
|
||||
void set_override_fov(f32 fov);
|
||||
/* |description|Sets the override near plane|descriptionEnd| */
|
||||
|
|
@ -49,14 +56,44 @@ u8 get_skybox_color(u8 index);
|
|||
void set_skybox_color(u8 index, u8 value);
|
||||
|
||||
/* |description|Traverses a display list. Takes a Lua function as a parameter, which is called back for each command in the display list with the parameters `cmd` (display list pointer), and `op`|descriptionEnd| */
|
||||
void gfx_parse(Gfx* cmd, LuaFunction func);
|
||||
/* |description|Gets a vertex from a display list command if it has the correct op. Intended to be used with `gfx_parse`|descriptionEnd| */
|
||||
Vtx *gfx_get_vtx(Gfx* gfx, u16 offset);
|
||||
/* |description|Gets the number of vertices from a display list command if it has the correct op|descriptionEnd| */
|
||||
u16 gfx_get_vtx_count(Gfx* cmd);
|
||||
/* |description|Sets the display list combine mode. you can fill this function with G_CCMUX_* and G_ACMUX_* constants|descriptionEnd| */
|
||||
void gfx_set_combine_lerp(Gfx* gfx, u32 a0, u32 b0, u32 c0, u32 d0, u32 Aa0, u32 Ab0, u32 Ac0, u32 Ad0, u32 a1, u32 b1, u32 c1, u32 d1, u32 Aa1, u32 Ab1, u32 Ac1, u32 Ad1);
|
||||
/* |description|Sets the display list texture image. Pass in textureInfo.texture as `texture`|descriptionEnd| */
|
||||
void gfx_set_texture_image(Gfx* gfx, u32 format, u32 size, u32 width, u8* texture);
|
||||
void gfx_parse(Gfx *cmd, LuaFunction func);
|
||||
/* |description|Gets the op of the display list command|descriptionEnd| */
|
||||
u32 gfx_get_op(Gfx *cmd);
|
||||
/* |description|Gets the display list from a display list command if it has the op `G_DL`|descriptionEnd| */
|
||||
Gfx *gfx_get_display_list(Gfx *cmd);
|
||||
/* |description|Gets the vertex buffer from a display list command if it has the op `G_VTX`|descriptionEnd| */
|
||||
Vtx *gfx_get_vertex_buffer(Gfx *cmd);
|
||||
/* |description|Gets the number of vertices from a display list command if it has the op `G_VTX`|descriptionEnd| */
|
||||
u16 gfx_get_vertex_count(Gfx *cmd);
|
||||
|
||||
/* |description|Gets the max length of a display list|descriptionEnd| */
|
||||
u32 gfx_get_length(Gfx *gfx);
|
||||
/* |description|Gets a command of a display list at position `offset`|descriptionEnd| */
|
||||
Gfx *gfx_get_command(Gfx *gfx, u32 offset);
|
||||
/* |description|Gets the next command of a given display list pointer. Intended to use in a for loop|descriptionEnd| */
|
||||
Gfx *gfx_get_next_command(Gfx *gfx);
|
||||
/* |description|Copies `length` commands from display list `src` to display list `dest`|descriptionEnd| */
|
||||
void gfx_copy(Gfx *dest, Gfx *src, u32 length);
|
||||
/* |description|Creates a new named display list of `length` commands|descriptionEnd| */
|
||||
Gfx *gfx_new(const char *name, u32 length);
|
||||
/* |description|Reallocates a display list created by `gfx_new` to modify its length|descriptionEnd| */
|
||||
Gfx *gfx_realloc(Gfx *gfx, u32 newLength);
|
||||
/* |description|Deletes a display list created by `gfx_new`|descriptionEnd| */
|
||||
void gfx_delete(Gfx *gfx);
|
||||
|
||||
/* |description|Gets the max count of vertices of a vertex buffer|descriptionEnd| */
|
||||
u32 vtx_get_count(Vtx *vtx);
|
||||
/* |description|Gets a vertex of a vertex buffer at position `offset`|descriptionEnd| */
|
||||
Vtx *vtx_get_vertex(Vtx *vtx, u32 offset);
|
||||
/* |description|Gets the next vertex of a given vertex pointer. Intended to use in a for loop|descriptionEnd| */
|
||||
Vtx *vtx_get_next_vertex(Vtx *vtx);
|
||||
/* |description|Copies `count` vertices from vertex buffer `src` to vertex buffer `dest`|descriptionEnd| */
|
||||
void vtx_copy(Vtx *dest, Vtx *src, u32 count);
|
||||
/* |description|Creates a new named vertex buffer of `count` vertices|descriptionEnd| */
|
||||
Vtx *vtx_new(const char *name, u32 count);
|
||||
/* |description|Reallocates a vertex buffer created by `vtx_new` to modify its count|descriptionEnd| */
|
||||
Vtx *vtx_realloc(Vtx *vtx, u32 newCount);
|
||||
/* |description|Deletes a vertex buffer created by `vtx_new`|descriptionEnd| */
|
||||
void vtx_delete(Vtx *vtx);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -668,7 +668,6 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
|
|||
if (exiting) { return; }
|
||||
|
||||
dynos_model_clear_pool(MODEL_POOL_SESSION);
|
||||
dynos_model_restore_vanilla_display_lists();
|
||||
|
||||
// reset other stuff
|
||||
extern u8* gOverrideEeprom;
|
||||
|
|
|
|||