295 lines
12 KiB
C
295 lines
12 KiB
C
|
#include <ultra64.h>
|
||
|
|
||
|
#include "sm64.h"
|
||
|
#include "area.h"
|
||
|
#include "game.h"
|
||
|
#include "engine/math_util.h"
|
||
|
#include "engine/graph_node.h"
|
||
|
#include "memory.h"
|
||
|
#include "geo_misc.h"
|
||
|
|
||
|
#include "segment2.h"
|
||
|
|
||
|
u8 D_8032FF60[4] = { 0 };
|
||
|
u16 D_8032FF64[2] = { 0 };
|
||
|
|
||
|
s32 func_802CAAE0(s8 a0, u8 a1) {
|
||
|
s32 sp4 = 0;
|
||
|
|
||
|
D_8032FF60[a0]++;
|
||
|
|
||
|
if (D_8032FF60[a0] == a1) {
|
||
|
D_8032FF60[a0] = 0;
|
||
|
D_8032FF64[a0] = 0;
|
||
|
sp4 = 1;
|
||
|
}
|
||
|
return sp4;
|
||
|
}
|
||
|
|
||
|
u8 func_802CAB60(s8 a0, s8 a1, u8 a2) {
|
||
|
u8 sp7;
|
||
|
|
||
|
switch (a0) {
|
||
|
case 0:
|
||
|
sp7 = (f32) D_8032FF60[a1] * 255.0 / (f32)(a2 - 1) + 0.5;
|
||
|
break;
|
||
|
case 1:
|
||
|
sp7 = (1.0 - D_8032FF60[a1] / (f32)(a2 - 1)) * 255.0 + 0.5;
|
||
|
break;
|
||
|
}
|
||
|
return sp7;
|
||
|
}
|
||
|
|
||
|
Vtx *func_802CADB4(struct WarpTransitionData *transData, u8 alpha) {
|
||
|
Vtx *verts = alloc_display_list(4 * sizeof(*verts));
|
||
|
u8 r = transData->red;
|
||
|
u8 g = transData->green;
|
||
|
u8 b = transData->blue;
|
||
|
|
||
|
if (verts != NULL) {
|
||
|
make_vertex(verts, 0, 0, 0, -1, 0, 0, r, g, b, alpha);
|
||
|
make_vertex(verts, 1, 320, 0, -1, 0, 0, r, g, b, alpha);
|
||
|
make_vertex(verts, 2, 320, 240, -1, 0, 0, r, g, b, alpha);
|
||
|
make_vertex(verts, 3, 0, 240, -1, 0, 0, r, g, b, alpha);
|
||
|
} else {
|
||
|
}
|
||
|
return verts;
|
||
|
}
|
||
|
|
||
|
s32 func_802CAF38(s8 a0, u8 a1, struct WarpTransitionData *transData, u8 alpha) {
|
||
|
Vtx *verts = func_802CADB4(transData, alpha);
|
||
|
|
||
|
if (verts != NULL) {
|
||
|
gSPDisplayList(gDisplayListHead++, dl_proj_mtx_fullscreen)
|
||
|
gDPSetCombine(gDisplayListHead++, 0xFFFFFF, 0xFFFE793C)
|
||
|
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2)
|
||
|
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(verts), 4, 0)
|
||
|
gSPDisplayList(gDisplayListHead++, dl_draw_quad_verts_0123)
|
||
|
gSPDisplayList(gDisplayListHead++, dl_screen_transition_end)
|
||
|
}
|
||
|
return func_802CAAE0(a0, a1);
|
||
|
}
|
||
|
|
||
|
s32 func_802CB0E4(s8 a0, u8 a1, struct WarpTransitionData *transData) {
|
||
|
u8 alpha = func_802CAB60(1, a0, a1);
|
||
|
|
||
|
return func_802CAF38(a0, a1, transData, alpha);
|
||
|
}
|
||
|
|
||
|
s32 func_802CB140(s8 a0, u8 a1, struct WarpTransitionData *transData) {
|
||
|
u8 alpha = func_802CAB60(0, a0, a1);
|
||
|
|
||
|
return func_802CAF38(a0, a1, transData, alpha);
|
||
|
}
|
||
|
|
||
|
s16 func_802CB19C(s8 a0, s8 a1, struct WarpTransitionData *transData) {
|
||
|
f32 spC = transData->endCircleRadius - transData->startCircleRadius;
|
||
|
f32 sp8 = D_8032FF60[a0] * spC / (f32)(a1 - 1);
|
||
|
f32 sp4 = transData->startCircleRadius + sp8;
|
||
|
|
||
|
return sp4 + 0.5;
|
||
|
}
|
||
|
|
||
|
f32 func_802CB274(s8 a0, s8 a1, struct WarpTransitionData *transData) {
|
||
|
f32 sp2C = transData->startCircleX;
|
||
|
f32 sp28 = transData->startCircleY;
|
||
|
f32 sp24 = transData->endCircleX;
|
||
|
f32 sp20 = transData->endCircleY;
|
||
|
f32 sp1C = sqrtf((sp2C - sp24) * (sp2C - sp24) + (sp28 - sp20) * (sp28 - sp20));
|
||
|
f32 sp18 = (f32) D_8032FF60[a0] * sp1C / (f32)(a1 - 1);
|
||
|
|
||
|
return sp18;
|
||
|
}
|
||
|
|
||
|
u16 func_802CB384(struct WarpTransitionData *transData) {
|
||
|
f32 sp1C = transData->endCircleX - transData->startCircleX;
|
||
|
f32 sp18 = transData->endCircleY - transData->startCircleY;
|
||
|
|
||
|
return atan2s(sp1C, sp18);
|
||
|
}
|
||
|
|
||
|
s16 func_802CB400(struct WarpTransitionData *transData, f32 a1, u16 a2) {
|
||
|
f32 sp4 = transData->startCircleX + coss(a2) * a1;
|
||
|
|
||
|
return sp4 + 0.5;
|
||
|
}
|
||
|
|
||
|
s16 func_802CB484(struct WarpTransitionData *transData, f32 a1, u16 a2) {
|
||
|
f32 sp4 = transData->startCircleY + sins(a2) * a1;
|
||
|
|
||
|
return sp4 + 0.5;
|
||
|
}
|
||
|
|
||
|
void func_802CB508(Vtx *verts, s32 n, s8 a2, struct WarpTransitionData *transData, s16 sp62, s16 sp66,
|
||
|
s16 sp6A, s16 sp6E, s16 sp72, s16 sp76) {
|
||
|
u8 r = transData->red;
|
||
|
u8 g = transData->green;
|
||
|
u8 b = transData->blue;
|
||
|
u16 sp4A = D_8032FF64[a2];
|
||
|
f32 sp44 = sp6A * coss(sp4A) - sp6E * sins(sp4A) + sp62;
|
||
|
f32 sp40 = sp6A * sins(sp4A) + sp6E * coss(sp4A) + sp66;
|
||
|
s16 x = round_float(sp44);
|
||
|
s16 y = round_float(sp40);
|
||
|
|
||
|
make_vertex(verts, n, x, y, -1, sp72 * 32, sp76 * 32, r, g, b, 255);
|
||
|
}
|
||
|
|
||
|
void func_802CB6A0(Vtx *verts, s8 sp47, struct WarpTransitionData *transData, s16 sp4E, s16 sp52,
|
||
|
s16 sp56, s8 sp5B) {
|
||
|
switch (sp5B) {
|
||
|
case 0:
|
||
|
func_802CB508(verts, 0, sp47, transData, sp4E, sp52, -sp56, -sp56, -31, 63);
|
||
|
func_802CB508(verts, 1, sp47, transData, sp4E, sp52, sp56, -sp56, 31, 63);
|
||
|
func_802CB508(verts, 2, sp47, transData, sp4E, sp52, sp56, sp56, 31, 0);
|
||
|
func_802CB508(verts, 3, sp47, transData, sp4E, sp52, -sp56, sp56, -31, 0);
|
||
|
break;
|
||
|
case 1:
|
||
|
func_802CB508(verts, 0, sp47, transData, sp4E, sp52, -sp56, -sp56, 0, 63);
|
||
|
func_802CB508(verts, 1, sp47, transData, sp4E, sp52, sp56, -sp56, 63, 63);
|
||
|
func_802CB508(verts, 2, sp47, transData, sp4E, sp52, sp56, sp56, 63, 0);
|
||
|
func_802CB508(verts, 3, sp47, transData, sp4E, sp52, -sp56, sp56, 0, 0);
|
||
|
break;
|
||
|
}
|
||
|
func_802CB508(verts, 4, sp47, transData, sp4E, sp52, -2000, -2000, 0, 0);
|
||
|
func_802CB508(verts, 5, sp47, transData, sp4E, sp52, 2000, -2000, 0, 0);
|
||
|
func_802CB508(verts, 6, sp47, transData, sp4E, sp52, 2000, 2000, 0, 0);
|
||
|
func_802CB508(verts, 7, sp47, transData, sp4E, sp52, -2000, 2000, 0, 0);
|
||
|
}
|
||
|
|
||
|
void *D_8032FF68[] = {
|
||
|
texture_transition_star_half,
|
||
|
texture_transition_circle_half,
|
||
|
texture_transition_mario,
|
||
|
texture_transition_bowser_half,
|
||
|
};
|
||
|
|
||
|
s32 func_802CB9F8(s8 spBB, s8 spBF, struct WarpTransitionData *transData, s8 spC7, s8 spCB) {
|
||
|
f32 spB4 = func_802CB274(spBB, spBF, transData);
|
||
|
u16 spB2 = func_802CB384(transData);
|
||
|
s16 spB0 = func_802CB400(transData, spB4, spB2);
|
||
|
s16 spAE = func_802CB484(transData, spB4, spB2);
|
||
|
s16 spAC = func_802CB19C(spBB, spBF, transData);
|
||
|
Vtx *spA8 = alloc_display_list(8 * sizeof(*spA8));
|
||
|
|
||
|
if (spA8 != NULL) {
|
||
|
func_802CB6A0(spA8, spBB, transData, spB0, spAE, spAC, spCB); // TODO types
|
||
|
gSPDisplayList(gDisplayListHead++, dl_proj_mtx_fullscreen) gDPSetCombine(gDisplayListHead++,
|
||
|
0xFFFFFF, 0xFFFE793C)
|
||
|
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_OPA_SURF, G_RM_AA_OPA_SURF2)
|
||
|
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(spA8), 8, 0)
|
||
|
gSPDisplayList(gDisplayListHead++, dl_transition_draw_filled_region) gDPPipeSync(
|
||
|
gDisplayListHead++) gDPSetCombine(gDisplayListHead++, 0x127E24, 0xFFFFF3F9)
|
||
|
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2)
|
||
|
gDPSetTextureFilter(gDisplayListHead++, G_TF_BILERP) switch (spCB) {
|
||
|
case 0:
|
||
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, D_8032FF68[spC7])
|
||
|
gDPSetTile(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, 7, 0, G_TX_MIRROR,
|
||
|
6, G_TX_NOLOD, G_TX_MIRROR, 5, G_TX_NOLOD)
|
||
|
gDPLoadSync(gDisplayListHead++)
|
||
|
gDPLoadBlock(gDisplayListHead++, 7, 0, 0, 1023, 512)
|
||
|
gDPPipeSync(gDisplayListHead++)
|
||
|
gDPSetTile(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 4, 0, 0, 0,
|
||
|
G_TX_MIRROR, 6, G_TX_NOLOD, G_TX_MIRROR, 5, G_TX_NOLOD)
|
||
|
gDPSetTileSize(gDisplayListHead++, 0, 0, 0, 124, 252) break;
|
||
|
case 1:
|
||
|
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, D_8032FF68[spC7])
|
||
|
gDPSetTile(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, 7, 0,
|
||
|
G_TX_NOMIRROR | G_TX_CLAMP, 6, G_TX_NOLOD,
|
||
|
G_TX_NOMIRROR | G_TX_WRAP | G_TX_CLAMP, 6, G_TX_NOLOD)
|
||
|
gDPLoadSync(gDisplayListHead++)
|
||
|
gDPLoadBlock(gDisplayListHead++, 7, 0, 0, 2047, 256)
|
||
|
gDPPipeSync(gDisplayListHead++)
|
||
|
gDPSetTile(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 0, 0, 0,
|
||
|
G_TX_NOMIRROR | G_TX_CLAMP, 6, G_TX_NOLOD,
|
||
|
G_TX_NOMIRROR | G_TX_WRAP | G_TX_CLAMP, 6, G_TX_NOLOD)
|
||
|
gDPSetTileSize(gDisplayListHead++, 0, 0, 0, 252, 252) break;
|
||
|
}
|
||
|
gSPTexture(gDisplayListHead++, -1, -1, 0, 0, G_ON)
|
||
|
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(spA8), 4, 0)
|
||
|
gSPDisplayList(gDisplayListHead++, dl_draw_quad_verts_0123)
|
||
|
gSPTexture(gDisplayListHead++, -1, -1, 0, 0, G_OFF)
|
||
|
gSPDisplayList(gDisplayListHead++, dl_screen_transition_end) D_8032FF64[spBB] +=
|
||
|
transData->unk10;
|
||
|
} else {
|
||
|
}
|
||
|
return func_802CAAE0(spBB, spBF);
|
||
|
}
|
||
|
|
||
|
int func_802CC108(s8 sp23, s8 sp27, u8 sp2B, struct WarpTransitionData *sp2C) {
|
||
|
switch (sp27) {
|
||
|
case 0:
|
||
|
return func_802CB0E4(sp23, sp2B, sp2C);
|
||
|
break;
|
||
|
case 1:
|
||
|
return func_802CB140(sp23, sp2B, sp2C);
|
||
|
break;
|
||
|
case 8:
|
||
|
return func_802CB9F8(sp23, sp2B, sp2C, 0, 0);
|
||
|
break;
|
||
|
case 9:
|
||
|
return func_802CB9F8(sp23, sp2B, sp2C, 0, 0);
|
||
|
break;
|
||
|
case 10:
|
||
|
return func_802CB9F8(sp23, sp2B, sp2C, 1, 0);
|
||
|
break;
|
||
|
case 11:
|
||
|
return func_802CB9F8(sp23, sp2B, sp2C, 1, 0);
|
||
|
break;
|
||
|
case 16:
|
||
|
return func_802CB9F8(sp23, sp2B, sp2C, 2, 1);
|
||
|
break;
|
||
|
case 17:
|
||
|
return func_802CB9F8(sp23, sp2B, sp2C, 2, 1);
|
||
|
break;
|
||
|
case 18:
|
||
|
return func_802CB9F8(sp23, sp2B, sp2C, 3, 0);
|
||
|
break;
|
||
|
case 19:
|
||
|
return func_802CB9F8(sp23, sp2B, sp2C, 3, 0);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Gfx *func_802CC2E8(void) {
|
||
|
Vtx *verts = alloc_display_list(4 * sizeof(*verts));
|
||
|
Gfx *dlist = alloc_display_list(16 * sizeof(*dlist));
|
||
|
Gfx *g = dlist;
|
||
|
|
||
|
if (verts != NULL && dlist != NULL) {
|
||
|
make_vertex(verts, 0, 0, 0, -1, -1152, 1824, 0, 0, 0, 255);
|
||
|
make_vertex(verts, 1, 320, 0, -1, 1152, 1824, 0, 0, 0, 255);
|
||
|
make_vertex(verts, 2, 320, 240, -1, 1152, 192, 0, 0, 0, 255);
|
||
|
make_vertex(verts, 3, 0, 240, -1, -1152, 192, 0, 0, 0, 255);
|
||
|
|
||
|
gSPDisplayList(g++, dl_proj_mtx_fullscreen) gDPSetCombine(g++, 0x127E24, 0xFFFFF3F9)
|
||
|
gDPSetTextureFilter(g++, G_TF_BILERP) gDPSetTextureImage(g++, G_IM_FMT_IA, G_IM_SIZ_16b, 1,
|
||
|
D_8032FF68[1])
|
||
|
gDPSetTile(g++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, 7, 0, G_TX_MIRROR | G_TX_WRAP, 6,
|
||
|
G_TX_NOLOD, G_TX_MIRROR | G_TX_WRAP, 5, G_TX_NOLOD) gDPLoadSync(g++)
|
||
|
gDPLoadBlock(g++, 7, 0, 0, 1023, 512) gDPPipeSync(g++)
|
||
|
gDPSetTile(g++, G_IM_FMT_IA, G_IM_SIZ_8b, 4, 0, 0, 0, G_TX_MIRROR | G_TX_WRAP,
|
||
|
6, G_TX_NOLOD, G_TX_MIRROR | G_TX_WRAP, 5, G_TX_NOLOD)
|
||
|
gDPSetTileSize(g++, 0, 0, 0, 124, 252) gSPTexture(g++, -1, -1, 0, 0, G_ON)
|
||
|
gSPVertex(g++, VIRTUAL_TO_PHYSICAL(verts), 4, 0)
|
||
|
gSPDisplayList(g++, dl_draw_quad_verts_0123)
|
||
|
gSPTexture(g++, -1, -1, 0, 0, G_OFF)
|
||
|
gSPDisplayList(g++, dl_screen_transition_end)
|
||
|
gSPEndDisplayList(g)
|
||
|
} else {
|
||
|
return NULL;
|
||
|
}
|
||
|
return dlist;
|
||
|
}
|
||
|
|
||
|
Gfx *Geo18_802CD1E8(s32 run, struct GraphNode *node, UNUSED f32 mtx[4][4]) {
|
||
|
struct GraphNodeGenerated *sp1C = (struct GraphNodeGenerated *) node;
|
||
|
Gfx *dlist = NULL;
|
||
|
|
||
|
if (run == TRUE && gCurrentArea != NULL
|
||
|
&& gCurrentArea->camera->currPreset == CAMERA_PRESET_INSIDE_CANNON) {
|
||
|
sp1C->fnNode.node.flags = (sp1C->fnNode.node.flags & 0xFF) | 0x500;
|
||
|
dlist = func_802CC2E8();
|
||
|
}
|
||
|
return dlist;
|
||
|
}
|