mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-07-04 03:12:55 -04:00
Implement prop extension API, SpriteProp and ModelProp transform tagging
This commit is contained in:
@@ -5,6 +5,12 @@
|
||||
#include "enums.h"
|
||||
#include "prop.h"
|
||||
|
||||
typedef enum {
|
||||
EXTENSION_TYPE_MARKER,
|
||||
EXTENSION_TYPE_PROP,
|
||||
} ExtensionType;
|
||||
|
||||
// ActorMarkers
|
||||
typedef u32 MarkerExtensionId;
|
||||
|
||||
MarkerExtensionId bkrecomp_extend_marker(enum marker_e type, u32 size);
|
||||
@@ -13,4 +19,12 @@ MarkerExtensionId bkrecomp_extend_marker_all(u32 size);
|
||||
void* bkrecomp_get_extended_marker_data(ActorMarker* marker, MarkerExtensionId extension);
|
||||
u32 bkrecomp_get_marker_spawn_index(ActorMarker* marker);
|
||||
|
||||
// Props
|
||||
typedef u32 PropExtensionId;
|
||||
|
||||
PropExtensionId bkrecomp_extend_prop_all(u32 size);
|
||||
|
||||
void *bkrecomp_get_extended_prop_data(Cube* cube, Prop* prop, PropExtensionId extension_id);
|
||||
u32 bkrecomp_get_prop_spawn_index(Cube* cube, Prop* prop);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,11 +5,6 @@
|
||||
#include "object_extension_funcs.h"
|
||||
#include "bk_api.h"
|
||||
|
||||
typedef enum {
|
||||
EXTENSION_TYPE_MARKER,
|
||||
EXTENSION_TYPE_PROP,
|
||||
} ExtensionType;
|
||||
|
||||
// Array of handles for ActorMarker instances.
|
||||
// Normally the game only has at most 0xE0 ActorMarker instances, but this is larger to account for mods increasing
|
||||
// the ActorMarker count.
|
||||
|
||||
@@ -5,15 +5,33 @@
|
||||
#include "object_extension_funcs.h"
|
||||
#include "bk_api.h"
|
||||
#include "core2/coords.h"
|
||||
#include "core2/file.h"
|
||||
|
||||
// Max props per cube, limited by cube->prop2Cnt which is only 6 bits.
|
||||
#define CUBE_MAX_PROPS 63
|
||||
// Hardcoded cube limit, TODO implement a better solution that doesn't involve dedicating this much memory and allows for larger cube counts.
|
||||
#define MAX_CUBES 4000
|
||||
u32 prop_handles[MAX_CUBES][CUBE_MAX_PROPS];
|
||||
|
||||
typedef struct {
|
||||
u32 prop_handles[CUBE_MAX_PROPS];
|
||||
} CubeHandle;
|
||||
|
||||
CubeHandle all_cube_handles[MAX_CUBES];
|
||||
CubeHandle cube_3C_handle;
|
||||
CubeHandle cube_40_handle;
|
||||
|
||||
extern s32 *D_8036A9E0;
|
||||
extern s32 D_80383450[0x40];
|
||||
|
||||
void vtxList_getBounds_s32(BKVertexList *, s32[3], s32[3]);
|
||||
enum map_e map_get(void);
|
||||
void code7AF80_initCubeFromFile(File *file_ptr, Cube *cube);
|
||||
bool func_80305D14(void);
|
||||
void func_80305CD8(s32 idx, s32 count);
|
||||
s32 func_803058C0(f32 arg0);
|
||||
void code_A5BC0_initCubePropActorProp(Cube*);
|
||||
void func_80332B2C(ActorMarker * arg0);
|
||||
void bitfield_free(s32 *arg0);
|
||||
|
||||
extern struct {
|
||||
Cube *cubes;
|
||||
@@ -78,8 +96,311 @@ RECOMP_PATCH void mapModel_getCubeBounds(s32 min[3], s32 max[3]) {
|
||||
u32 stride1 = stride0 * width1;
|
||||
u32 cubeCnt = stride1 * width2;
|
||||
|
||||
recomp_printf("Cube count for map %d: %u\n", map_get(), cubeCnt);
|
||||
if (cubeCnt > MAX_CUBES) {
|
||||
recomp_abort("Cube count too high\n");
|
||||
}
|
||||
}
|
||||
|
||||
CubeHandle* get_cube_handle(Cube *cube) {
|
||||
if (cube == sCubeList.unk3C) {
|
||||
return &cube_3C_handle;
|
||||
}
|
||||
else if (cube == sCubeList.unk40) {
|
||||
return &cube_40_handle;
|
||||
}
|
||||
else {
|
||||
s32 cube_index = cube - sCubeList.cubes;
|
||||
if (cube_index < 0 || cube_index >= sCubeList.cubeCnt) {
|
||||
recomp_printf("Invalid cube index %d\n", cube_index);
|
||||
recomp_abort("Got invalid cube\n");
|
||||
}
|
||||
return &all_cube_handles[cube_index];
|
||||
}
|
||||
}
|
||||
|
||||
// Alloc prop handles:
|
||||
// __codeA5BC0_initProp2Ptr
|
||||
// code7AF80_initCubeFromFile (covered by __code7AF80_initCubeFromFile)
|
||||
|
||||
// Delete prop handles:
|
||||
// func_8032D9C0
|
||||
// cube_free
|
||||
|
||||
// Swap prop handles:
|
||||
// __cube_sort
|
||||
|
||||
// Reset all prop handles candidates:
|
||||
// cubeList_free
|
||||
|
||||
// @recomp Patched to create a handle for the new prop.
|
||||
RECOMP_PATCH Prop *__codeA5BC0_initProp2Ptr(Cube *cube) {
|
||||
Prop *sp1C;
|
||||
|
||||
if (cube->prop2Ptr != NULL) {
|
||||
cube->prop2Cnt++;
|
||||
cube->prop2Ptr = realloc(cube->prop2Ptr, cube->prop2Cnt * sizeof(Prop));
|
||||
} else {
|
||||
cube->prop2Cnt = 1;
|
||||
cube->prop2Ptr = malloc(sizeof(Prop));
|
||||
}
|
||||
sp1C = &cube->prop2Ptr[cube->prop2Cnt-1];
|
||||
sp1C->is_actor = FALSE;
|
||||
code_A5BC0_initCubePropActorProp(cube);
|
||||
|
||||
// @recomp Get the cube's prop handle list.
|
||||
CubeHandle* cube_handle = get_cube_handle(cube);
|
||||
u32 prop_index = cube->prop2Cnt - 1;
|
||||
// TODO prop subtypes.
|
||||
cube_handle->prop_handles[prop_index] = recomp_create_object_data(EXTENSION_TYPE_PROP, 0);
|
||||
|
||||
return sp1C;
|
||||
}
|
||||
|
||||
// @recomp Patched to initialize prop handles after a cube has been loaded.
|
||||
RECOMP_PATCH void __code7AF80_initCubeFromFile(Cube *cube, File* file_ptr) {
|
||||
s32 pad[3];
|
||||
|
||||
// @recomp Get the cube's prop handle list.
|
||||
CubeHandle* cube_handle = get_cube_handle(cube);
|
||||
|
||||
// @recomp Free any prop handles that the cube may already have, as this initialization resets the cube's prop list.
|
||||
for (u32 i = 0; i < cube->prop2Cnt; i++) {
|
||||
recomp_destroy_object_data(EXTENSION_TYPE_PROP, cube_handle->prop_handles[i]);
|
||||
cube_handle->prop_handles[i] = 0;
|
||||
}
|
||||
|
||||
while(!file_isNextByteExpected(file_ptr, 1)) {
|
||||
if (file_getNWords_ifExpected(file_ptr, 0, pad, 3)) {
|
||||
file_getNWords(file_ptr, pad, 3);
|
||||
} else if (!file_getNWords_ifExpected(file_ptr, 2, pad, 3) && file_isNextByteExpected(file_ptr, 3)
|
||||
) {
|
||||
code7AF80_initCubeFromFile(file_ptr, cube);
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Initialize prop handles after loading the cube.
|
||||
for (u32 i = 0; i < cube->prop2Cnt; i++) {
|
||||
// TODO prop subtypes.
|
||||
cube_handle->prop_handles[i] = recomp_create_object_data(EXTENSION_TYPE_PROP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to delete the handle for the deleted prop and shift the remaining prop handles.
|
||||
RECOMP_PATCH s32 func_8032D9C0(Cube *cube, Prop* prop){
|
||||
s32 sp24;
|
||||
s32 tmp;
|
||||
|
||||
// @recomp Get the cube's prop handle list.
|
||||
CubeHandle* cube_handle = get_cube_handle(cube);
|
||||
|
||||
sp24 = 0;
|
||||
if(cube->prop2Cnt != 0){
|
||||
// @recomp Delete the handle for the deleted prop.
|
||||
u32 prop_index = prop - cube->prop2Ptr;
|
||||
|
||||
sp24 = prop->is_3d;
|
||||
if(func_80305D14()){
|
||||
func_80305CD8(func_803058C0(prop->unk4[1]), -1);
|
||||
}
|
||||
|
||||
// @recomp Destroy the prop's extension data.
|
||||
recomp_destroy_object_data(EXTENSION_TYPE_PROP, cube_handle->prop_handles[prop_index]);
|
||||
|
||||
if((prop - cube->prop2Ptr) < (cube->prop2Cnt - 1)){
|
||||
memcpy(prop, prop + 1, (s32)(&cube->prop2Ptr[cube->prop2Cnt-1]) - (s32)(prop));
|
||||
// @recomp Shift the prop handles back by 1 to remove the gap.
|
||||
for (u32 cur_prop_index = prop_index; cur_prop_index < cube->prop2Cnt - 1; cur_prop_index++) {
|
||||
cube_handle->prop_handles[cur_prop_index] = cube_handle->prop_handles[cur_prop_index + 1];
|
||||
}
|
||||
// @recomp Clear the handle at the end of the list to account for the list decreasing in size.
|
||||
cube_handle->prop_handles[cube->prop2Cnt - 1] = 0;
|
||||
}
|
||||
cube->prop2Cnt--;
|
||||
if(cube->prop2Cnt){
|
||||
cube->prop2Ptr = realloc(cube->prop2Ptr, cube->prop2Cnt*sizeof(Prop));
|
||||
code_A5BC0_initCubePropActorProp(cube);
|
||||
}else{
|
||||
free(cube->prop2Ptr);
|
||||
cube->prop2Ptr = NULL;
|
||||
}
|
||||
return sp24;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @recomp Patched to clear all prop handles for a cube when freeing a cube.
|
||||
RECOMP_PATCH void cube_free(Cube *cube){
|
||||
Prop *iProp;
|
||||
|
||||
// @recomp Get the cube's prop handle list.
|
||||
CubeHandle* cube_handle = get_cube_handle(cube);
|
||||
|
||||
// @recomp Delete and clear the cube's prop handles.
|
||||
for (u32 prop_index = 0; prop_index < cube->prop2Cnt; prop_index++) {
|
||||
recomp_destroy_object_data(EXTENSION_TYPE_PROP, cube_handle->prop_handles[prop_index]);
|
||||
cube_handle->prop_handles[prop_index] = 0;
|
||||
}
|
||||
|
||||
if(cube->prop2Ptr){
|
||||
for(iProp = cube->prop2Ptr; iProp < cube->prop2Ptr +cube->prop2Cnt; iProp++){
|
||||
if(iProp->is_actor){
|
||||
func_80332B2C(iProp->actorProp.marker);
|
||||
}
|
||||
}
|
||||
free(cube->prop2Ptr);
|
||||
cube->prop2Ptr = NULL;
|
||||
}
|
||||
if(cube->prop1Ptr){
|
||||
free(cube->prop1Ptr);
|
||||
cube->prop1Ptr = NULL;
|
||||
}
|
||||
cube->prop2Cnt = 0;
|
||||
cube->prop1Cnt = 0;
|
||||
cube->unk0_4 = 0;
|
||||
}
|
||||
|
||||
// @recomp Patched to swap prop handles when sorting a cube's props.
|
||||
RECOMP_PATCH void __cube_sort(Cube *cube, bool global) {
|
||||
s32 ref_position[3];
|
||||
Prop *var_v1;
|
||||
Prop *start_prop;
|
||||
s32 temp_a2;
|
||||
Prop *var_t1;
|
||||
Prop * var_a3;
|
||||
Prop * var_t0;
|
||||
s32 i;
|
||||
Prop *new_var;
|
||||
|
||||
// @recomp Get the cube's prop handle list.
|
||||
CubeHandle* cube_handle = get_cube_handle(cube);
|
||||
|
||||
if (cube->prop2Cnt >= 2) {
|
||||
if (global == 0) {
|
||||
viewport_getPosition_vec3w(ref_position); //distance from viewport
|
||||
} else {
|
||||
ref_position[0] = 0;
|
||||
ref_position[1] = 0;
|
||||
ref_position[2] = 0;
|
||||
}
|
||||
|
||||
//calculate prop distances
|
||||
new_var = var_v1 = cube->prop2Ptr;
|
||||
for(i = 0; i < cube->prop2Cnt; var_v1++, i++){
|
||||
D_80383450[i] = (var_v1->actorProp.x - ref_position[0])*(var_v1->actorProp.x - ref_position[0])
|
||||
+ (var_v1->actorProp.y - ref_position[1])* (var_v1->actorProp.y - ref_position[1])
|
||||
+ (var_v1->actorProp.z - ref_position[2])* (var_v1->actorProp.z - ref_position[2]);
|
||||
}
|
||||
|
||||
//sort prop list
|
||||
start_prop = cube->prop2Ptr;
|
||||
var_t0 = cube->prop2Ptr + (cube->prop2Cnt - 1);
|
||||
do {
|
||||
new_var = start_prop;
|
||||
var_t1 = var_t0;
|
||||
start_prop = NULL;
|
||||
var_v1 = new_var;
|
||||
i = (new_var - cube->prop2Ptr);
|
||||
while(var_v1 < var_t1){
|
||||
if(D_80383450[i] < D_80383450[i + 1]){
|
||||
var_t0 = var_v1 + 1;
|
||||
if (start_prop != 0) {
|
||||
var_t0 = var_v1;
|
||||
} else {
|
||||
start_prop = (var_v1 == cube->prop2Ptr) ? var_v1 : var_v1 - 1;
|
||||
}
|
||||
|
||||
//swap_distances
|
||||
temp_a2 = D_80383450[i];
|
||||
D_80383450[i] = D_80383450[i + 1];
|
||||
D_80383450[i + 1] = temp_a2;
|
||||
|
||||
//swap_props
|
||||
temp_a2 = ((s32*)(&var_v1[0]))[0];
|
||||
((s32*)(&var_v1[0]))[0] = ((s32*)(&var_v1[1]))[0];
|
||||
((s32*)(&var_v1[1]))[0] = temp_a2;
|
||||
|
||||
temp_a2 = ((s32*)(&var_v1[0]))[1];
|
||||
((s32*)(&var_v1[0]))[1] = ((s32*)(&var_v1[1]))[1];
|
||||
((s32*)(&var_v1[1]))[1] = temp_a2;
|
||||
|
||||
temp_a2 = ((s32*)(&var_v1[0]))[2];
|
||||
((s32*)(&var_v1[0]))[2] = ((s32*)(&var_v1[1]))[2];
|
||||
((s32*)(&var_v1[1]))[2] = temp_a2;
|
||||
|
||||
// @recomp Swap prop extension data handles.
|
||||
u32 temp_handle = cube_handle->prop_handles[i];
|
||||
cube_handle->prop_handles[i] = cube_handle->prop_handles[i + 1];
|
||||
cube_handle->prop_handles[i + 1] = temp_handle;
|
||||
}
|
||||
|
||||
var_v1++;
|
||||
i++;
|
||||
}
|
||||
} while (start_prop != NULL);
|
||||
code_A5BC0_initCubePropActorProp(cube);
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to reset the prop handle list.
|
||||
RECOMP_PATCH void cubeList_free(){
|
||||
Cube *iCube;
|
||||
|
||||
for(iCube = sCubeList.cubes; iCube < sCubeList.cubes + sCubeList.cubeCnt; iCube++){
|
||||
cube_free(iCube);
|
||||
}
|
||||
free(sCubeList.cubes);
|
||||
|
||||
if(sCubeList.unk3C){
|
||||
cube_free(sCubeList.unk3C);
|
||||
free(sCubeList.unk3C);
|
||||
}
|
||||
|
||||
if(sCubeList.unk40){
|
||||
cube_free(sCubeList.unk40);
|
||||
free(sCubeList.unk40);
|
||||
}
|
||||
bitfield_free(D_8036A9E0);
|
||||
D_8036A9E0 = NULL;
|
||||
|
||||
// @recomp Reset the prop handle list.
|
||||
recomp_clear_all_object_data(EXTENSION_TYPE_PROP);
|
||||
}
|
||||
|
||||
RECOMP_EXPORT PropExtensionId bkrecomp_extend_prop_all(u32 size) {
|
||||
return recomp_register_object_extension_generic(EXTENSION_TYPE_PROP, size);
|
||||
}
|
||||
|
||||
RECOMP_EXPORT void *bkrecomp_get_extended_prop_data(Cube* cube, Prop* prop, PropExtensionId extension_id) {
|
||||
CubeHandle* cube_handle = get_cube_handle(cube);
|
||||
s32 prop_index = prop - cube->prop2Ptr;
|
||||
if (prop_index < 0 || prop_index >= cube->prop2Cnt) {
|
||||
recomp_printf("bkrecomp_get_extended_prop_data: Invalid Cube/Prop pair\n");
|
||||
recomp_abort("Fatal error in mod - Invalid call to bkrecomp_get_extended_prop_data");
|
||||
}
|
||||
|
||||
// TODO prop subtypes.
|
||||
void* data = recomp_get_object_data(EXTENSION_TYPE_PROP, 0, cube_handle->prop_handles[prop_index], extension_id);
|
||||
if (data == NULL) {
|
||||
recomp_printf("bkrecomp_get_extended_prop_data: Invalid extension id 0x%08X\n", extension_id);
|
||||
recomp_abort("Fatal error in mod - Invalid call to bkrecomp_get_extended_prop_data");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
RECOMP_EXPORT u32 bkrecomp_get_prop_spawn_index(Cube* cube, Prop* prop) {
|
||||
CubeHandle* cube_handle = get_cube_handle(cube);
|
||||
s32 prop_index = prop - cube->prop2Ptr;
|
||||
if (prop_index < 0 || prop_index >= cube->prop2Cnt) {
|
||||
recomp_printf("bkrecomp_get_prop_spawn_index: Invalid Cube/Prop pair\n");
|
||||
recomp_abort("Fatal error in mod - Invalid call to bkrecomp_get_prop_spawn_index");
|
||||
}
|
||||
|
||||
u32 spawn_index = recomp_get_object_spawn_index(EXTENSION_TYPE_PROP, cube_handle->prop_handles[prop_index]);
|
||||
if (spawn_index == 0xFFFFFFFF) {
|
||||
recomp_printf("bkrecomp_get_prop_spawn_index: Internal error\n");
|
||||
recomp_abort("Fatal error - Internal error in bkrecomp_get_prop_spawn_index");
|
||||
}
|
||||
|
||||
return spawn_index;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,122 @@
|
||||
#include "patches.h"
|
||||
#include "bk_api.h"
|
||||
#include "transform_ids.h"
|
||||
#include "functions.h"
|
||||
#include "core2/vla.h"
|
||||
|
||||
typedef union{
|
||||
struct{
|
||||
u32 pad31: 27;
|
||||
u32 unk4: 1;
|
||||
u32 pad3: 1;
|
||||
u32 unk2: 1;
|
||||
u32 unk1: 1;
|
||||
u32 unk0: 1;
|
||||
};
|
||||
u32 word;
|
||||
} tmp_bitfield;
|
||||
|
||||
extern vector(ActorMarker *) *D_80383550;
|
||||
extern vector(ActorMarker *) *D_80383554;
|
||||
|
||||
void propModelList_drawSprite(Gfx **, Mtx **, Vtx **, f32[3], f32, s32, Cube*,s32 ,s32, s32, s32, s32);
|
||||
void propModelList_drawModel(Gfx **, Mtx **, Vtx **, f32[3], f32[3], f32, s32, Cube*);
|
||||
void __marker_draw(ActorMarker *this, Gfx **gfx, Mtx **mtx, Vtx **vtx);
|
||||
void __cube_sort(Cube *cube, bool global);
|
||||
void func_8032CD60(Prop *);
|
||||
|
||||
// @recomp Patched to add transform tagging when drawing sprite and model props.
|
||||
RECOMP_PATCH void func_8032D510(Cube *cube, Gfx **gfx, Mtx **mtx, Vtx **vtx){
|
||||
Prop *iProp;
|
||||
int i;
|
||||
f32 position[3];
|
||||
f32 rotation[3];
|
||||
tmp_bitfield tmp_v0;
|
||||
int iOffset;
|
||||
ActorMarker **markerPtr;
|
||||
|
||||
if(cube->prop2Cnt == 0 ) return;
|
||||
|
||||
__cube_sort(cube, 0);
|
||||
iOffset = 0;
|
||||
for(i = 0; i < cube->prop2Cnt; i++){//L8032D5A0
|
||||
iOffset = i * 0xC;
|
||||
iProp = (Prop *)((s32)cube->prop2Ptr + iOffset);
|
||||
tmp_v0.word = *(u32 *)((s32)iProp + 0x8);
|
||||
if(!tmp_v0.unk4){
|
||||
|
||||
}else{
|
||||
if(!tmp_v0.unk1){
|
||||
func_8032CD60(iProp);
|
||||
}
|
||||
tmp_v0.word = *(u32 *)((s32)iProp + 0x8);
|
||||
if(tmp_v0.unk0){//actorProp;
|
||||
if(iProp->actorProp.marker->unk40_22){
|
||||
markerPtr = (ActorMarker **)vector_pushBackNew(&D_80383550);
|
||||
*markerPtr = iProp->actorProp.marker;
|
||||
}
|
||||
else if(iProp->actorProp.marker->unk40_19){
|
||||
markerPtr = (ActorMarker **)vector_pushBackNew(&D_80383554);
|
||||
*markerPtr = iProp->actorProp.marker;
|
||||
}
|
||||
else{
|
||||
__marker_draw(iProp->actorProp.marker, gfx, mtx, vtx);
|
||||
}//L8032D62C
|
||||
}
|
||||
else{//L8032D640
|
||||
// @recomp Calculate the base transform ID for the prop.
|
||||
u32 spawn_index = bkrecomp_get_prop_spawn_index(cube, iProp);
|
||||
u32 base_transform_id = spawn_index * PROP_TRANSFORM_ID_COUNT + PROP_TRANSFORM_ID_START;
|
||||
|
||||
position[0] = (f32)iProp->modelProp.position[0];
|
||||
position[1] = (f32)iProp->modelProp.position[1];
|
||||
position[2] = (f32)iProp->modelProp.position[2];
|
||||
if(iProp->is_3d){
|
||||
rotation[0] = 0.0f;
|
||||
rotation[1] = (f32)((s32)iProp->modelProp.yaw*2);
|
||||
rotation[2] = (f32)((s32)iProp->modelProp.roll*2);
|
||||
|
||||
// @recomp Set the model render transform ID before drawing the model.
|
||||
cur_drawn_model_transform_id = base_transform_id;
|
||||
|
||||
propModelList_drawModel(gfx, mtx, vtx,
|
||||
position, rotation, (f32)iProp->modelProp.scale/100.0,
|
||||
iProp->modelProp.model_index, cube
|
||||
);
|
||||
|
||||
|
||||
// @recomp Clear the model render transform ID after drawing the model.
|
||||
cur_drawn_model_transform_id = 0;
|
||||
}
|
||||
else{//L8032D72C
|
||||
// @recomp Set the matrix group before drawing the sprite.
|
||||
// Skip interpolation on vertices to account for vertex lists changing between frames of the sprite.
|
||||
// Also skip interpolation on scale to account for the scale inverting when sprites are mirrored.
|
||||
// TODO track this matrix for skipping interpolation when camera interpolation is skipped.
|
||||
// TODO rotation temporarily disabled for now, reenable it when RT64 decomposition is improved.
|
||||
gEXMatrixGroupDecomposed((*gfx)++, base_transform_id, G_EX_PUSH, G_MTX_MODELVIEW,
|
||||
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE,
|
||||
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE,
|
||||
G_EX_ORDER_LINEAR, G_EX_EDIT_ALLOW);
|
||||
|
||||
// @recomp Also set the model render transform ID before drawing the sprite. This won't have any effect
|
||||
// in the unmodified game, but will allow transform tagging for mods that draw models in place of sprites.
|
||||
cur_drawn_model_transform_id = base_transform_id;
|
||||
|
||||
propModelList_drawSprite(gfx, mtx, vtx,
|
||||
position, (f32)iProp->spriteProp.scale/100.0, iProp->spriteProp.sprite_index, cube,
|
||||
iProp->spriteProp.r, iProp->spriteProp.b, iProp->spriteProp.g,
|
||||
iProp->spriteProp.mirrored, iProp->spriteProp.frame
|
||||
);
|
||||
|
||||
// @recomp Pop the sprite's matrix group.
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
|
||||
// @recomp Clear the model render transform ID after drawing the sprite.
|
||||
cur_drawn_model_transform_id = 0;
|
||||
}
|
||||
}//L8032D7C4
|
||||
}
|
||||
iOffset+=0xC;
|
||||
}//L8032D7D4
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#define BANJO_TRANSFORM_ID_START 0x01000000
|
||||
#define MARKER_TRANSFORM_ID_START (BANJO_TRANSFORM_ID_START + MARKER_TRANSFORM_ID_COUNT)
|
||||
|
||||
#define PROP_TRANSFORM_ID_COUNT 256
|
||||
#define PROP_TRANSFORM_ID_START 0x01200000
|
||||
|
||||
extern u32 cur_drawn_model_transform_id;
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user