#include "../mips.h" #include "../actor.h" #include "zelda64.h" #define PORTAL_ACT 0x0082 #define PORTAL_OBJ 0x0086 #define PORTAL_ORANGE 0x0000 #define PORTAL_BLUE 0x0001 /* Hack-specific addresses */ #define POS_1_DEST 0x80611000 /* Unused */ #define POS_1_ACT 0x8061100C /* Unused */ #define POS_2_DEST 0x80611010 /* Unused */ #define POS_2_ACT 0x8061101C /* Unused - FIXME: should be within first portal's actor, not way the hell over here */ #define STATUS 0x80611020 #define NO_ACTORS 0x80611024 #define ACT_LIST 0x80611040 /* OoT specific values */ #define ARROW 0x0016 extern void func_8002d62c ( struct z64_actor_t *, u32 ); extern void func_8002b1e0 ( void *, u32, void *, u32 ); extern void func_80035260 ( void *, u32 ); extern char obj_8002B5EC; extern void vase_init ( struct z64_actor_t * a, void * o ); extern void vase_null ( struct z64_actor_t * a, void * o ); extern void portal_main ( struct z64_actor_t * a, void * o ); extern void portal_render ( struct z64_actor_t * a, void * o ); /* Create actor header */ MK_AHEAD ( spec, PORTAL_ACT, 6, 0, 0x10, PORTAL_OBJ, /* ovular.zobj */ 0x14C, vase_init, vase_null, portal_main, portal_render ); void vase_init ( struct z64_actor_t * a, void * o ) { func_8002d62c( a, 0x3CCCCCCC ); /* Scale ( .025 )*/ a->coords_3 = a->coords_2; func_8002b1e0( AADDR(a, 0x00B4), 0, &obj_8002B5EC, 0x42C80000 ); } void vase_null ( struct z64_actor_t * a, void * o ) { return; } void portal_render ( struct z64_actor_t * a, void * o ) /* Only run when camera is close enough... may change */ { if (!(a->variable)) func_80035260( o, 0x06000000 ); /* Orange */ else func_80035260( o, 0x06000020 ); /* Blue */ } void portal_main ( struct z64_actor_t * a, void * o ) { u32 *pos2_act = (void*)POS_2_ACT; if (!(a->variable)) { /* Portal stuff */ CoordU *pos2 = (void*)(*pos2_act+0x24); /* Arrow stuff */ u32 *_item = (void*)ITEM_ACTORL; u16 **item = (void*)ITEM_ACTORL; u16 *item_var = (void*)((*_item) + 0x1C); u32 *hit = (void*)((*_item) + 0x60); /* Actor stuff */ u32 * status = (void*)STATUS; u16 * noActs = (void*)NO_ACTORS; u32 (*actorList)[1] = (void*)ACT_LIST; if (**item == ARROW) { if (*hit) { f32 diff[3]; Coord *link = (void*)(LINK+0x24); CoordU *arrow = (void*)(*_item + 0x24); if (*item_var == 3) { a->coords_2.rx = arrow->x.u; a->coords_2.ry = arrow->y.u; a->coords_2.rz = arrow->z.u; *status |= 1; } else if (*item_var == 4) { pos2->x.u = arrow->x.u; pos2->y.u = arrow->y.u; pos2->z.u = arrow->z.u; *status |=2; } } } if (!(*status&4)) { *pos2_act = ActorSpawn(AS_A0_D, AS_A1_D, PORTAL_ACT, 0, -2000.0, 0, 0, 0, 0, PORTAL_ORANGE); *status |= 4; } else if (*status == 7) { int i = 0; while (i < *noActs) { if (*actorList[i] ) { u32 * alive = (void*)(*actorList[i]+0x130); u16 * anum = (void*)(*actorList[i]); u16 * timer = (void*)(*actorList[i]+0x34); /* Unused space in all actors (semi-confirmed) */ if (*timer) { *timer -= 1; } else if (*alive && *anum != ARROW && *anum != PORTAL_ACT) /* Should actor be read? */ { CoordU *curAct = (void*)(*actorList[i]+0x24); if ( ( curAct->x.f <= (a->coords_2.x + 30.0) ) && ( curAct->x.f >= (a->coords_2.x - 30.0) ) && ( curAct->y.f <= (a->coords_2.y + 50.0) ) && ( curAct->y.f >= (a->coords_2.y - 50.0) ) && ( curAct->z.f <= (a->coords_2.z + 30.0) ) && ( curAct->z.f >= (a->coords_2.z - 30.0) ) ) { curAct->x.u = pos2->x.u; curAct->y.u = pos2->y.u; curAct->z.u = pos2->z.u; *timer = 32; } else if ( ( curAct->x.f <= (pos2->x.f + 30.0) ) && ( curAct->x.f >= (pos2->x.f - 30.0) ) && ( curAct->y.f <= (pos2->y.f + 50.0) ) && ( curAct->y.f >= (pos2->y.f - 50.0) ) && ( curAct->z.f <= (pos2->z.f + 30.0) ) && ( curAct->z.f >= (pos2->z.f - 30.0) ) ) { curAct->x.u = a->coords_2.rx; curAct->y.u = a->coords_2.ry; curAct->z.u = a->coords_2.rz; *timer = 32; } } else { *actorList[i] = 0; /* Don't read this actor again */ } } i+=1; } } } func_80035118(a,o); }