mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-05-23 22:45:12 -04:00
Add interpolation to almost every 2D element in the game. (#20)
* Add interpolation to almost every 2D element in the game. * Add comments. * Fix interpolation on life icon. Also fix text interpolation. * Fix interpolation for more 2D elements and disable vertex interpolation on them.
This commit is contained in:
@@ -1,11 +1,22 @@
|
||||
#include "patches.h"
|
||||
#include "transform_ids.h"
|
||||
#include "functions.h"
|
||||
#include "../src/core2/gc/zoombox.h"
|
||||
|
||||
#define AIRSCORE_COUNT (6)
|
||||
|
||||
extern u8 D_80381E58[5];
|
||||
extern u16 D_80381620[0xD][5][0x10];
|
||||
extern u16 gScissorBoxLeft;
|
||||
extern u16 gScissorBoxRight;
|
||||
extern u16 gScissorBoxTop;
|
||||
extern u16 gScissorBoxBottom;
|
||||
extern s32 D_803815C0;
|
||||
extern s32 D_803815E4;
|
||||
extern s32 D_803815EC;
|
||||
extern s32 D_8036A018[];
|
||||
extern s32 D_80381EC4;
|
||||
extern s32 gTotalHealth;
|
||||
extern f32 D_803815C8;
|
||||
extern f32 D_803815CC;
|
||||
extern f32 D_803815D0;
|
||||
@@ -13,19 +24,49 @@ extern f32 D_803815D4;
|
||||
extern f32 D_803815D8;
|
||||
extern f32 D_803815DC;
|
||||
extern f32 D_803815E0;
|
||||
extern f32 D_80381E54;
|
||||
extern f32 D_80381E60[5];
|
||||
extern f32 D_80381E78[5];
|
||||
extern f32 D_80381EB8;
|
||||
extern f32 D_80381EBC;
|
||||
extern f32 D_80381EFC;
|
||||
extern f32 D_80381F08[8];
|
||||
extern f32 D_80381F68[AIRSCORE_COUNT];
|
||||
extern f32 s_texture_scale;
|
||||
extern f32 s_active_count;
|
||||
extern s32 D_803815E8;
|
||||
extern f32 gHealth;
|
||||
extern void *D_8036A010;
|
||||
extern void *D_8036A014;
|
||||
extern Gfx D_80369920[];
|
||||
extern Gfx D_8036A030[];
|
||||
extern Gfx D_8036A228[];
|
||||
extern Gfx D_8036A278[];
|
||||
extern Gfx D_8036A918[];
|
||||
extern Gfx s_fxairscore_context[];
|
||||
extern void *D_80381EB0[2];
|
||||
extern char code_78E50_ItemValueString[8];
|
||||
extern BKSprite *D_80381E40[5];
|
||||
extern BKSprite *gSpriteHealth;
|
||||
extern BKSprite *gSpriteRedHealth;
|
||||
extern BKSprite *s_sprite;
|
||||
extern struct1Cs_1 D_8036C58C[0xD];
|
||||
|
||||
extern void func_80347FC0(Gfx **gfx, BKSprite *sprite, s32 frame, s32 tmem, s32 rtile, s32 uls, s32 ult, s32 cms, s32 cmt, s32 *width, s32 *height);
|
||||
extern void func_80348044(Gfx **gfx, BKSprite *sprite, s32 frame, s32 tmem, s32 rtile, s32 uls, s32 ult, s32 cms, s32 cmt, s32 *width, s32 *height, s32 *frame_width, s32 *frame_height, s32 *texture_x, s32 *texture_y, s32 *textureCount);
|
||||
extern f32 func_802FDE60(f32 arg0);
|
||||
extern f32 func_802FB0E4(struct8s *this);
|
||||
extern s32 func_802FB0D4(struct8s *this);
|
||||
extern f32 func_802FB0DC(struct8s *this);
|
||||
extern void func_802FD360(struct8s *arg0, Gfx **gfx, Mtx **mtx, Vtx **vtx);
|
||||
extern s32 itemPrint_getValue(s32 item_id);
|
||||
extern s32 level_get(void);
|
||||
extern s32 itemscore_noteScores_getTotal(void);
|
||||
extern s32 getGameMode(void);
|
||||
extern f32 vtxList_getGlobalNorm(BKVertexList *);
|
||||
|
||||
s32 itemPrint_lastValues[0x2C];
|
||||
|
||||
typedef struct {
|
||||
u8 pad0[0x14];
|
||||
s32 unk14;
|
||||
@@ -51,6 +92,58 @@ typedef struct {
|
||||
AnimCtrl *anim_ctrl;
|
||||
}Struct_core2_79830_0;
|
||||
|
||||
extern struct {
|
||||
u8 state;
|
||||
u8 menu;
|
||||
u8 selection; //menu page
|
||||
u8 exit_pause : 1;
|
||||
u8 unk3_6 : 1; //busy?
|
||||
u8 unk3_5 : 1;
|
||||
u8 unk3_4 : 1;
|
||||
u8 left_joystick_visible : 1;
|
||||
u8 right_joystick_visible : 1;
|
||||
u8 b_button_visible : 1;
|
||||
u8 unk3_0 : 1;
|
||||
s8 zoombox_opening_count;
|
||||
s8 zoombox_closing_count;
|
||||
u8 unk6;
|
||||
u8 unk7;
|
||||
s8 unk8; //header position
|
||||
s8 page;
|
||||
s8 joystick_frame;
|
||||
u8 joystick_frame_count;
|
||||
f32 unkC;
|
||||
GcZoombox *zoombox[4];
|
||||
f32 unk20;
|
||||
BKSprite *joystick_sprite;
|
||||
f32 unk28;
|
||||
BKSprite *b_button_sprite;
|
||||
u8 b_button_frame;
|
||||
u8 b_button_frame_count; //B-button total frames
|
||||
s16 b_button_alpha; //B-button alpha
|
||||
s16 left_joystick_alpha; //left joystick alpha
|
||||
s16 right_joystick_alpha; //right joystick alpha
|
||||
u8 page_cnt;
|
||||
u8 sns_items;
|
||||
u8 sns_visible;
|
||||
// u8 pad3B[1];
|
||||
s16 sns_alpha; //sns opacity
|
||||
s16 unk3E[7];
|
||||
s16 unk4C[7];
|
||||
// u8 pad5A[0x3];
|
||||
BKModelBin *sns_egg_model; //SnS Egg Model
|
||||
BKModelBin *ice_key_model; //Ice key model
|
||||
u8 pad64[12];
|
||||
u32 unk70_31 : 1;
|
||||
u32 unk70_30 : 1;
|
||||
u32 return_to_lair_disabled : 1;
|
||||
u32 pad70_28 : 29;
|
||||
} D_80383010;
|
||||
|
||||
extern u32 cur_pushed_text_transform_id;
|
||||
extern u32 cur_pushed_text_transform_origin;
|
||||
extern u32 cur_pushed_text_transform_skip_interpolation;
|
||||
|
||||
// @recomp Tag the matrices for each honeycomb piece.
|
||||
RECOMP_PATCH void fxhoneycarrierscore_draw(s32 arg0, struct8s *arg1, Gfx **arg2, Mtx **arg3, Vtx **arg4) {
|
||||
f64 var_f24;
|
||||
@@ -70,6 +163,13 @@ RECOMP_PATCH void fxhoneycarrierscore_draw(s32 arg0, struct8s *arg1, Gfx **arg2,
|
||||
sp118 = D_803815C0 == 2;
|
||||
if (D_8036A010 != 0) {
|
||||
func_80347FC0(arg2, (sp118) ? (D_8036A014 != 0) ? D_8036A014 : D_8036A010 : D_8036A010, 0, 0, 0, 0, 0, 2, 2, &sp13C, &sp138);
|
||||
|
||||
// @recomp Align the honeycomb pieces to the right side of the screen.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
gEXPushScissor((*arg2)++);
|
||||
gEXSetScissor((*arg2)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_RIGHT, G_EX_ORIGIN_RIGHT, gScissorBoxLeft - gScissorBoxTop, gScissorBoxRight, 0, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*arg2)++, G_EX_ORIGIN_RIGHT, -gScissorBoxTop * 4, 0);
|
||||
|
||||
viewport_setRenderViewportAndOrthoMatrix(arg2, arg3);
|
||||
gSPDisplayList((*arg2)++, D_8036A030);
|
||||
for (sp134 = 0; sp134 < ((sp118) ? ((D_8036A014 != 0) ? 2 : 1) : 6); sp134++) {
|
||||
@@ -131,6 +231,11 @@ RECOMP_PATCH void fxhoneycarrierscore_draw(s32 arg0, struct8s *arg1, Gfx **arg2,
|
||||
// @recomp Clear the matrix group.
|
||||
gEXPopMatrixGroup((*arg2)++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
gEXSetViewportAlign((*arg2)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*arg2)++);
|
||||
|
||||
gDPPipeSync((*arg2)++);
|
||||
gDPSetTextureLUT((*arg2)++, G_TT_NONE);
|
||||
gDPPipelineMode((*arg2)++, G_PM_NPRIMITIVE);
|
||||
@@ -138,6 +243,507 @@ RECOMP_PATCH void fxhoneycarrierscore_draw(s32 arg0, struct8s *arg1, Gfx **arg2,
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to tag the Jinjos on the HUD.
|
||||
RECOMP_PATCH void fxjinjoscore_draw(s32 arg0, struct8s *arg1, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
BKSprite *sprite; // s1
|
||||
s32 draw_index; // s5
|
||||
s32 texture_width; // sp11C
|
||||
s32 texture_height; // sp118
|
||||
s32 jinjo_id; // sp114
|
||||
f32 center_y; // f14 (sp110)
|
||||
f32 center_x; // f20 (sp10C)
|
||||
f32 x_offset; // f26 (sp108)
|
||||
f32 y_offset; // f28 (sp104)
|
||||
f32 pos_x; // f30 (sp100)
|
||||
s32 i; // v1 (spFC)
|
||||
s32 j; // v0_2 (spF8)
|
||||
|
||||
// @recomp Align the Jinjos to the left side of the screen.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT, gScissorBoxLeft, gScissorBoxRight, gScissorBoxTop, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_LEFT, 0, 0);
|
||||
|
||||
gSPDisplayList((*gfx)++, D_8036A228);
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
|
||||
pos_x = 44.0f;
|
||||
// Draw all jinjo heads
|
||||
for (jinjo_id = 0; jinjo_id < 5; jinjo_id++) {
|
||||
s32 jinjo_collected; // spF0 <----
|
||||
sprite = D_80381E40[jinjo_id];
|
||||
jinjo_collected = (D_80381E58[jinjo_id] != 0) ? 1 : 0;
|
||||
if (sprite != NULL) {
|
||||
func_80347FC0(gfx, sprite, (s32)D_80381E60[jinjo_id], 0, 0, 0, 0, 2, 2, &texture_width, &texture_height);
|
||||
// Load the palette for the corresponding jinjo color
|
||||
gDPLoadTLUT_pal16((*gfx)++, 0, D_80381620[(s32)D_80381E60[jinjo_id]][jinjo_id]);
|
||||
x_offset = 0.0f;
|
||||
y_offset = 0.0f;
|
||||
// Draw the jinjo head, once if uncollected and twice if collected
|
||||
// If the head is drawn twice then the first draw will be the drop shadow
|
||||
for (draw_index = jinjo_collected; draw_index >= 0; draw_index--) {
|
||||
gDPPipeSync((*gfx)++);
|
||||
// Draw 0 is the jinjo's head, anything else is a shadow
|
||||
if (draw_index != 0) {
|
||||
// Use only primitive color as the color input in order to make a solid color shadow
|
||||
gDPSetCombineLERP((*gfx)++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0);
|
||||
// Set up a translucent black for primitive color to draw the shadow
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0x00, 0x00, 0x00, 0x8C);
|
||||
}
|
||||
else {
|
||||
// Use the texture as the color input
|
||||
gDPSetCombineLERP((*gfx)++, 0, 0, 0, TEXEL0, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0, TEXEL0, 0, PRIMITIVE, 0);
|
||||
// If the jinjo is collected then it's drawn fully opaque, otherwise it's drawn with partial alpha
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0x00, 0x00, 0x00, jinjo_collected ? 0xFF : 0x6E);
|
||||
}
|
||||
center_x = pos_x - (f32)gFramebufferWidth / 2 + x_offset;
|
||||
|
||||
// @recomp Remove vertical translation from the vertices.
|
||||
center_y = (f32)gFramebufferHeight / 2 - 266.0f + 40.0f + y_offset;
|
||||
//center_y = (f32)gFramebufferHeight / 2 + func_802FB0E4(arg1) - 266.0f + 40.0f + y_offset - D_80381E78[jinjo_id];
|
||||
|
||||
// @recomp Assign the matrix group for each Jinjo and its shadow separately.
|
||||
gEXMatrixGroupSimpleNormal((*gfx)++, HUD_JINJOSCORE_TRANSFORM_ID_START + jinjo_id * 2 + draw_index, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
|
||||
// @recomp Add vertical translation to matrix.
|
||||
guTranslate(*mtx, 0.0f, (func_802FB0E4(arg1) - D_80381E78[jinjo_id]) * 4.0f, 0.0f);
|
||||
gSPMatrix((*gfx)++, OS_K0_TO_PHYSICAL((*mtx)++), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
gSPVertex((*gfx)++, *vtx, 4, 0);
|
||||
// Set up the positions of the four vertices
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
(*vtx)->v.ob[0] = ((texture_width * D_80381E54 * j) - (texture_width * D_80381E54 / 2) + center_x) * 4;
|
||||
(*vtx)->v.ob[1] = ((texture_height * D_80381E54 / 2) - (texture_height * D_80381E54 * i) + center_y) * 4;
|
||||
(*vtx)->v.ob[2] = -20;
|
||||
(*vtx)->v.tc[0] = ((texture_width - 1) * j) << 6;
|
||||
(*vtx)->v.tc[1] = ((texture_height - 1) * i) << 6;
|
||||
(*vtx)++;
|
||||
}
|
||||
}
|
||||
// Draw a quad made of the four vertices
|
||||
gSP1Quadrangle((*gfx)++, 0, 1, 3, 2, 0);
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
|
||||
x_offset += -2;
|
||||
y_offset += 2;
|
||||
}
|
||||
}
|
||||
// Move the next jinjo head over by 32 pixels
|
||||
pos_x += 32.0f;
|
||||
}
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetTextureLUT((*gfx)++, G_TT_NONE);
|
||||
gDPPipelineMode((*gfx)++, G_PM_NPRIMITIVE);
|
||||
viewport_setRenderViewportAndPerspectiveMatrix(gfx, mtx);
|
||||
}
|
||||
|
||||
// @recomp Patched to tag the pieces of air and also align them to the left side of the screen.
|
||||
RECOMP_PATCH void fxairscore_draw(enum item_e item_id, struct8s *arg1, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
f32 y;
|
||||
f32 x;
|
||||
s32 texture_width;
|
||||
s32 texture_height;
|
||||
s32 i_part;
|
||||
s32 var_s6;
|
||||
s32 v_x;
|
||||
s32 v_y;
|
||||
|
||||
if (s_sprite != 0) {
|
||||
gSPDisplayList((*gfx)++, s_fxairscore_context);
|
||||
func_80347FC0(gfx, s_sprite, 0, 0, 0, 0, 0, 2, 2, &texture_width, &texture_height);
|
||||
|
||||
// @recomp Align the pieces of air to the left side of the screen.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT, gScissorBoxLeft, gScissorBoxRight, gScissorBoxTop, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_LEFT, 0, 0);
|
||||
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
//render all 6 air pieces
|
||||
for (i_part = 0; i_part < AIRSCORE_COUNT; i_part++) {
|
||||
if ((i_part != 0) && (i_part != 5)) {
|
||||
var_s6 = (i_part & 1) ? i_part + 1 : i_part - 1;
|
||||
}
|
||||
else {
|
||||
var_s6 = i_part;
|
||||
}
|
||||
gDPPipeSync((*gfx)++);
|
||||
if ((f32)(5 - i_part) < s_active_count) {
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0x00, 0x00, 0x00, 0xFF);
|
||||
}
|
||||
else {
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0x00, 0x00, 0x00, 0x78);
|
||||
}
|
||||
x = func_802FB0E4(arg1);
|
||||
x = ((-40 + x) + D_80381F68[var_s6]) - ((f32)gFramebufferWidth / 2);
|
||||
y = ((78 + (i_part * 15.5)) - ((f32)gFramebufferHeight / 2));
|
||||
|
||||
// @recomp Assign a matrix group to each piece of air.
|
||||
gEXMatrixGroupSimpleVerts((*gfx)++, HUD_AIRSCORE_TRANSFORM_ID_START + i_part, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
|
||||
//stagger x position
|
||||
x = (i_part & 1) ? x + 5.0f : x - 5.0f;
|
||||
gSPVertex((*gfx)++, *vtx, 4, 0);
|
||||
for (v_y = 0; v_y < 2; v_y++) {
|
||||
for (v_x = 0; v_x < 2; v_x++) {
|
||||
(*vtx)->v.ob[0] = (x + (((texture_width * s_texture_scale) * v_x) - ((texture_width * s_texture_scale) / 2))) * 4.0f;
|
||||
(*vtx)->v.ob[1] = (y + (((texture_height * s_texture_scale) / 2) - (texture_height * s_texture_scale) * v_y)) * 4.0f;
|
||||
(*vtx)->v.ob[2] = -0x14;
|
||||
(*vtx)->v.tc[0] = ((texture_width - 1) * v_x) << 6;
|
||||
(*vtx)->v.tc[1] = ((texture_height - 1) * v_y) << 6;
|
||||
(*vtx)++;
|
||||
}
|
||||
}
|
||||
gSP1Quadrangle((*gfx)++, 0, 1, 3, 2, 0);
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetTextureLUT((*gfx)++, G_TT_NONE);
|
||||
gDPPipelineMode((*gfx)++, G_PM_NPRIMITIVE);
|
||||
viewport_setRenderViewportAndPerspectiveMatrix(gfx, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to tag the health bar and align it to the left side of the screen.
|
||||
RECOMP_PATCH void fxhealthscore_draw(enum item_e item_id, struct8s *arg1, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
int i;
|
||||
int tmp_v1;
|
||||
s32 honeycomb_width;
|
||||
s32 honeycomb_height;
|
||||
int tmp_v0;
|
||||
f32 f18;
|
||||
f32 f14;
|
||||
f32 f20;
|
||||
s32 is_red_health_initialized = FALSE;
|
||||
s32 s6;
|
||||
|
||||
if (gSpriteHealth == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
gSPDisplayList((*gfx)++, D_8036A918);
|
||||
func_80347FC0(gfx, gSpriteHealth, 0, 0, 0, 0, 0, 2, 2, &honeycomb_width, &honeycomb_height);
|
||||
|
||||
// @recomp Align the health bar to the left side of the screen.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT, gScissorBoxLeft, gScissorBoxRight, gScissorBoxTop, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_LEFT, 0, 0);
|
||||
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
|
||||
//loop over each honeycomb piece
|
||||
for (i = gTotalHealth - 1; i >= 0; i--) {//L80300E40
|
||||
if (i != 0 && (i + 1 != gTotalHealth || gTotalHealth & 1)) {
|
||||
s6 = (i & 1) ? i + 1 : i - 1;
|
||||
}
|
||||
else {//L80300E84
|
||||
s6 = i;
|
||||
}
|
||||
|
||||
gDPPipeSync((*gfx)++);
|
||||
|
||||
if (gHealth > i) {
|
||||
if (0 < (gHealth - 8.0f) && (gHealth - 8.0f) > i) {
|
||||
if (!is_red_health_initialized) {
|
||||
func_80347FC0(gfx, gSpriteRedHealth, 0, 0, 0, 0, 0, 2, 2, &honeycomb_width, &honeycomb_height);
|
||||
is_red_health_initialized = TRUE;
|
||||
}
|
||||
}//L80300F38
|
||||
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
else {//L80300F58
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0xFF, 0xFF, 0xFF, 0x78);
|
||||
}
|
||||
|
||||
f20 = 96.0f - (f32)gFramebufferWidth / 2 + (i * 13);
|
||||
f14 = (f32)gFramebufferHeight / 2 - func_802FB0E4(arg1) - D_80381F08[s6] - -48.0f;
|
||||
f14 = (i & 1) ? f14 + 5.75 : f14 - 5.75;
|
||||
|
||||
// @recomp Assign a matrix group to each piece of health.
|
||||
gEXMatrixGroupSimpleVerts((*gfx)++, HUD_HEALTHSCORE_TRANSFORM_ID_START + i, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
|
||||
gSPVertex((*gfx)++, *vtx, 4, 0);
|
||||
|
||||
for (tmp_v1 = 0; tmp_v1 < 2; tmp_v1++) {//L8030101C
|
||||
for (tmp_v0 = 0; tmp_v0 < 2; tmp_v0++) {//L80301030
|
||||
(*vtx)->v.ob[0] = (((honeycomb_width * D_80381EFC) * tmp_v0 - (honeycomb_width * D_80381EFC) / 2) + f20) * 4.0f;
|
||||
(*vtx)->v.ob[1] = (((honeycomb_height * D_80381EFC) / 2 - (honeycomb_height * D_80381EFC) * tmp_v1) + f14) * 4.0f;
|
||||
(*vtx)->v.ob[2] = -0x14;
|
||||
|
||||
(*vtx)->v.tc[0] = ((honeycomb_width - 1) * tmp_v0) << 6;
|
||||
(*vtx)->v.tc[1] = ((honeycomb_height - 1) * tmp_v1) << 6;
|
||||
(*vtx)++;
|
||||
}
|
||||
}
|
||||
|
||||
gSP1Quadrangle((*gfx)++, 0, 1, 3, 2, 0);
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetTextureLUT((*gfx)++, G_TT_NONE);
|
||||
gDPPipelineMode((*gfx)++, G_PM_NPRIMITIVE);
|
||||
viewport_setRenderViewportAndPerspectiveMatrix(gfx, mtx);
|
||||
}
|
||||
|
||||
// @recomp Patched to tag the life icon and align it to the left side of the screen.
|
||||
RECOMP_PATCH void fxlifescore_draw(enum item_e item_id, struct8s *arg1, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
s32 sp10C;
|
||||
Vtx *sp108;
|
||||
s32 sp104;
|
||||
s32 var_v0;
|
||||
s32 var_v1;
|
||||
s32 var_s5;
|
||||
s32 var_s4;
|
||||
s32 spF0;
|
||||
s32 spEC;
|
||||
s32 spE8;
|
||||
s32 spE4;
|
||||
s32 spE0;
|
||||
s32 spDC;
|
||||
|
||||
sp10C = -1;
|
||||
sp108 = *vtx;
|
||||
code_78E50_ItemValueString[0] = '\0';
|
||||
strIToA(code_78E50_ItemValueString, MIN(9, itemPrint_getValue(item_id)));
|
||||
|
||||
// @recomp Assign an ID to the text and align it to the left side of the screen.
|
||||
cur_pushed_text_transform_id = HUD_LIFESCORE_TRANSFORM_PRINT_ID_START;
|
||||
cur_pushed_text_transform_origin = G_EX_ORIGIN_LEFT;
|
||||
|
||||
// @recomp Keep track of the last item value. If the value has changed, skip vertex interpolation this frame.
|
||||
if (itemPrint_lastValues[item_id] != itemPrint_getValue(item_id)) {
|
||||
cur_pushed_text_transform_skip_interpolation = TRUE;
|
||||
itemPrint_lastValues[item_id] = itemPrint_getValue(item_id);
|
||||
}
|
||||
|
||||
print_bold_spaced(0x4E, (s32)(func_802FB0E4(arg1) + -16.0f + 4.0f), (char *)&code_78E50_ItemValueString);
|
||||
|
||||
// @recomp Clear the ID and alignment for the text.
|
||||
cur_pushed_text_transform_id = 0;
|
||||
cur_pushed_text_transform_origin = G_EX_ORIGIN_NONE;
|
||||
cur_pushed_text_transform_skip_interpolation = FALSE;
|
||||
|
||||
if (1); //fake
|
||||
if (D_80381EB0[D_80381EC4] != NULL) {
|
||||
// @recomp Align the life icon to the left side of the screen.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT, gScissorBoxLeft, gScissorBoxRight, gScissorBoxTop, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_LEFT, 0, 0);
|
||||
|
||||
gSPDisplayList((*gfx)++, D_8036A278);
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
if (gfx);
|
||||
|
||||
// @recomp Assign a matrix group to the life icon.
|
||||
gEXMatrixGroupSimpleNormal((*gfx)++, HUD_LIFESCORE_TRANSFORM_ID_START, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetCombineLERP((*gfx)++, 0, 0, 0, TEXEL0, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0, TEXEL0, 0, PRIMITIVE, 0);
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0x00, 0x00, 0x00, 0xFF);
|
||||
do {
|
||||
func_80348044(gfx, D_80381EB0[D_80381EC4], (s32)D_80381EBC % 4, 0, 0, 0, 0, 2, 2, &spF0, &spEC, &spE8, &spE4, &spE0, &spDC, &sp10C);
|
||||
|
||||
if (((*vtx - sp108) & 0xF) == 0) {
|
||||
gSPVertex((*gfx)++, *vtx, MIN(0x10, (1 + sp10C) << 2), 0);
|
||||
sp104 = 0;
|
||||
}
|
||||
else {
|
||||
sp104 = sp104 + 4;
|
||||
}
|
||||
|
||||
var_s5 = (40.0f - ((f32)gFramebufferWidth / 2)) + spE0;
|
||||
var_s4 = (((((f32)gFramebufferHeight / 2) - func_802FB0E4(arg1)) - -16.0f) - spDC);
|
||||
|
||||
// @recomp Assign the vertical translation of the life icon to the matrix.
|
||||
guTranslate(*mtx - 1, 0.0f, -func_802FB0E4(arg1) * 4.0f, 0.0f);
|
||||
var_s4 += func_802FB0E4(arg1);
|
||||
|
||||
for (var_v1 = 0; var_v1 < 2; var_v1++) {
|
||||
for (var_v0 = 0; var_v0 < 2; var_v0++) {
|
||||
(*vtx)->v.ob[0] = (s16)(s32)(((((f32)spF0 * D_80381EB8 * (f32)var_v0) - (((f32)spE8 * D_80381EB8) / 2)) + var_s5) * 4.0f);
|
||||
(*vtx)->v.ob[1] = (s16)(s32)((((((f32)spE4 * D_80381EB8) / 2) - ((f32)spEC * D_80381EB8 * var_v1)) + var_s4) * 4.0f);
|
||||
(*vtx)->v.ob[2] = -0x14;
|
||||
(*vtx)->v.tc[0] = ((spF0 - 1) * var_v0) << 6;
|
||||
(*vtx)->v.tc[1] = ((spEC - 1) * var_v1) << 6;
|
||||
(*vtx)++;
|
||||
}
|
||||
}
|
||||
gSP1Quadrangle((*gfx)++, sp104, sp104 + 1, sp104 + 3, sp104 + 2, 0);
|
||||
} while (sp10C != 0);
|
||||
|
||||
// @recomp Clear the matrix group and the viewport alignment.
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetTextureLUT((*gfx)++, G_TT_NONE);
|
||||
gDPPipelineMode((*gfx)++, G_PM_NPRIMITIVE);
|
||||
viewport_setRenderViewportAndPerspectiveMatrix(gfx, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to remove translation of the score element from the vertices and move it to the matrix.
|
||||
RECOMP_PATCH void func_802FD360(struct8s *arg0, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
s32 tmp_s2 = 0;
|
||||
s32 tmp_s4;
|
||||
s32 texture_width;
|
||||
s32 texture_height;
|
||||
f32 tmp_f26;
|
||||
f32 f2;
|
||||
|
||||
|
||||
if (arg0->unk50 == NULL) return;
|
||||
|
||||
gSPDisplayList((*gfx)++, &D_80369920);
|
||||
if (arg0->unk20 == ITEM_C_NOTE) {
|
||||
gDPSetCombineMode((*gfx)++, G_CC_MODULATEIA, G_CC_MODULATEIA);
|
||||
}
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
|
||||
// @recomp Add vertical animation component to the matrix.
|
||||
guTranslate(*mtx - 1, 0.0f, -func_802FB0E4(arg0) * arg0->unk4C * 4.0f, 0.0f);
|
||||
|
||||
gSPVertex((*gfx)++, *vtx, 4, 0);
|
||||
if (arg0->unk20 == ITEM_0_HOURGLASS_TIMER) {
|
||||
tmp_s2 = 0xC;
|
||||
}
|
||||
func_80347FC0(gfx, (BKSprite *)(arg0->unk50), ((s32)arg0->unk60 + tmp_s2) % arg0->unk2C, 0, 0, 0, 0, 2, 2, &texture_width, &texture_height);
|
||||
tmp_f26 = (arg0->unk20 == ITEM_0_HOURGLASS_TIMER && texture_width == 0x10) ? 1.0f : 0.0f;
|
||||
for (tmp_s4 = 0; tmp_s4 < 2; tmp_s4++) {//L802FD528
|
||||
for (tmp_s2 = 0; tmp_s2 < 2; tmp_s2++) {//
|
||||
(*vtx)->v.ob[0] = ((func_802FB0DC(arg0) + (((texture_width * arg0->unk40 * tmp_s2 - texture_width * arg0->unk40 / 2) - (f32)gFramebufferWidth / 2) + arg0->unk38)) + tmp_f26) * 4.0f;
|
||||
// @recomp Removed vertical animation component from the vertices.
|
||||
//(*vtx)->v.ob[1] = ((((texture_height * arg0->unk40 / 2 - texture_height * arg0->unk40 * tmp_s4) + (f32)gFramebufferHeight / 2) - arg0->unk3C) - func_802FB0E4(arg0) * arg0->unk4C) * 4.0f;
|
||||
(*vtx)->v.ob[1] = ((((texture_height * arg0->unk40 / 2 - texture_height * arg0->unk40 * tmp_s4) + (f32)gFramebufferHeight / 2) - arg0->unk3C)) * 4.0f;
|
||||
(*vtx)->v.ob[2] = -0x14;
|
||||
(*vtx)->v.tc[0] = ((texture_width - 1) * tmp_s2) << 6;
|
||||
(*vtx)->v.tc[1] = ((texture_height - 1) * tmp_s4) << 6;
|
||||
if (arg0->unk20 == ITEM_C_NOTE) {
|
||||
if (tmp_s4 == 0) {
|
||||
(*vtx)->v.cn[0] = 0xff;
|
||||
(*vtx)->v.cn[1] = 0xff;
|
||||
(*vtx)->v.cn[2] = 0x0;
|
||||
(*vtx)->v.cn[3] = 0xff;
|
||||
}
|
||||
else if (tmp_s2 != 0) {
|
||||
(*vtx)->v.cn[0] = 0xff;
|
||||
(*vtx)->v.cn[1] = 100;
|
||||
(*vtx)->v.cn[2] = 0x0;
|
||||
(*vtx)->v.cn[3] = 0xff;
|
||||
}
|
||||
else {
|
||||
(*vtx)->v.cn[0] = 0xff;
|
||||
(*vtx)->v.cn[1] = 200;
|
||||
(*vtx)->v.cn[2] = 0x0;
|
||||
(*vtx)->v.cn[3] = 0xff;
|
||||
}
|
||||
}
|
||||
(*vtx)++;
|
||||
}
|
||||
}
|
||||
gSP1Quadrangle((*gfx)++, 0, 1, 3, 2, 0);
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetTextureLUT((*gfx)++, G_TT_NONE);
|
||||
gDPPipelineMode((*gfx)++, G_PM_NPRIMITIVE);
|
||||
viewport_setRenderViewportAndPerspectiveMatrix(gfx, mtx);
|
||||
}
|
||||
|
||||
// @recomp Patch to tag any 2D score elements and align them to the right side of the screen.
|
||||
RECOMP_PATCH void fxcommon2score_draw(enum item_e item_id, struct8s *arg1, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
f32 pad;
|
||||
s32 sp38;
|
||||
f32 sp34;
|
||||
|
||||
|
||||
sp38 = itemPrint_getValue(item_id);
|
||||
sp34 = 0.0f;
|
||||
if (item_id == ITEM_C_NOTE) {
|
||||
if (level_get() == LEVEL_6_LAIR || level_get() == LEVEL_C_BOSS) {
|
||||
sp38 = itemscore_noteScores_getTotal();
|
||||
}
|
||||
}
|
||||
if (item_id < 6) {
|
||||
sp38 = ((sp38) ? 1 : 0) + sp38 / 60;
|
||||
}//L802FDBA8
|
||||
if (item_id == ITEM_1B_VILE_VILE_SCORE && 9 < sp38) {
|
||||
sp34 = -16.0f;
|
||||
}
|
||||
if (item_id == ITEM_1C_MUMBO_TOKEN || item_id == ITEM_25_MUMBO_TOKEN_TOTAL) {
|
||||
if (sp38 >= 100) {
|
||||
sp38 = 99;
|
||||
}
|
||||
}
|
||||
arg1->string_54[0] = 0;
|
||||
//convert to string
|
||||
strIToA(arg1->string_54, sp38);
|
||||
|
||||
// @recomp Assign an ID to the text and align it to the left or the right side of the screen.
|
||||
bool left_alignment = arg1->unk38 < (gFramebufferWidth * 1.0f / 3.0f);
|
||||
cur_pushed_text_transform_id = HUD_SCORE2_TRANSFORM_PRINT_ID_START + item_id * HUD_SCORE2_TRANSFORM_PRINT_ID_COUNT;
|
||||
cur_pushed_text_transform_origin = left_alignment ? G_EX_ORIGIN_LEFT : G_EX_ORIGIN_RIGHT;
|
||||
|
||||
// @recomp Keep track of the last item value. If the value has changed, skip vertex interpolation this frame.
|
||||
if (itemPrint_lastValues[item_id] != sp38) {
|
||||
cur_pushed_text_transform_skip_interpolation = TRUE;
|
||||
itemPrint_lastValues[item_id] = sp38;
|
||||
}
|
||||
|
||||
//print text (blue egg font)
|
||||
print_bold_spaced(
|
||||
(s32)(func_802FB0DC(arg1) + arg1->unk38 + arg1->unk44 + sp34),
|
||||
(s32)(func_802FB0E4(arg1) * arg1->unk4C + (arg1->unk3C + arg1->unk48)),
|
||||
arg1->string_54
|
||||
);
|
||||
|
||||
// @recomp Clear the ID and alignment for the text.
|
||||
cur_pushed_text_transform_id = 0;
|
||||
cur_pushed_text_transform_origin = G_EX_ORIGIN_NONE;
|
||||
cur_pushed_text_transform_skip_interpolation = FALSE;
|
||||
|
||||
// @recomp Align the score element to either the left or the right side of the screen.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_RIGHT, 0, gScissorBoxRight, 0, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*gfx)++, left_alignment ? G_EX_ORIGIN_LEFT : G_EX_ORIGIN_RIGHT, left_alignment ? 0 : gScissorBoxTop * -4, 0);
|
||||
|
||||
// @recomp Assign a matrix group to the score element.
|
||||
gEXMatrixGroupSimpleNormal((*gfx)++, HUD_SCORE2_TRANSFORM_ID_START + item_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
|
||||
//draw sprite?
|
||||
func_802FD360(arg1, gfx, mtx, vtx);
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
}
|
||||
|
||||
#define RM_DEPTH_SET(clk) \
|
||||
Z_UPD | CVG_DST_FULL | ALPHA_CVG_SEL | FORCE_BL | G_ZS_PRIM | \
|
||||
ZMODE_OPA | \
|
||||
@@ -157,7 +763,25 @@ RECOMP_PATCH void fxcommon3score_draw(enum item_e item_id, void *arg1, Gfx **gfx
|
||||
if (a1->model != NULL && func_802FB0D4(arg1)) {
|
||||
a1->value_string[0] = '\0';
|
||||
strIToA(a1->value_string, itemPrint_getValue(item_id));
|
||||
|
||||
// @recomp Align the score element's text to the right or use its default alignment.
|
||||
bool aligned_to_the_right = a1->unk30 > (gFramebufferWidth * 2 / 3);
|
||||
cur_pushed_text_transform_id = HUD_SCORE3_TRANSFORM_PRINT_ID_START + item_id * HUD_SCORE3_TRANSFORM_PRINT_ID_COUNT;
|
||||
cur_pushed_text_transform_origin = aligned_to_the_right ? G_EX_ORIGIN_RIGHT : G_EX_ORIGIN_NONE;
|
||||
|
||||
// @recomp Keep track of the last item value. If the value has changed, skip vertex interpolation this frame.
|
||||
if (itemPrint_lastValues[item_id] != itemPrint_getValue(item_id)) {
|
||||
cur_pushed_text_transform_skip_interpolation = TRUE;
|
||||
itemPrint_lastValues[item_id] = itemPrint_getValue(item_id);
|
||||
}
|
||||
|
||||
print_bold_spaced(a1->unk30 + a1->unk40, sp40 + a1->unk44, a1->value_string);
|
||||
|
||||
// @recomp Clear the ID and alignment for the text.
|
||||
cur_pushed_text_transform_id = 0;
|
||||
cur_pushed_text_transform_origin = G_EX_ORIGIN_NONE;
|
||||
cur_pushed_text_transform_skip_interpolation = FALSE;
|
||||
|
||||
sp3C = viewport_transformCoordinate(a1->unk30, sp40, sp5C, sp68);
|
||||
|
||||
sp44[0] = 0.0f;
|
||||
@@ -176,6 +800,20 @@ RECOMP_PATCH void fxcommon3score_draw(enum item_e item_id, void *arg1, Gfx **gfx
|
||||
a1->unk6C = 1.1 * (vtxList_getGlobalNorm(model_getVtxList(a1->model)) * a1->unk3C);
|
||||
}
|
||||
|
||||
if (a1->anim_ctrl != NULL) {
|
||||
anctrl_drawSetup(a1->anim_ctrl, sp5C, 1);
|
||||
}
|
||||
|
||||
// @recomp If necessary, align the score element to the right of the screen.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
if (aligned_to_the_right) {
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_RIGHT, G_EX_ORIGIN_RIGHT, gScissorBoxLeft - gScissorBoxTop, gScissorBoxRight, 0, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_RIGHT, gScissorBoxTop * -4, 0);
|
||||
}
|
||||
|
||||
viewport_setRenderViewportAndPerspectiveMatrix(gfx, mtx);
|
||||
|
||||
// @recomp Draw a rectangle that clears the depth and gets interpolated along with the 3D model.
|
||||
// This fixes an issue where the rectangle would teleport ahead of the movement of the model in HFR
|
||||
// and it also provides a minor performance boost by skipping the need to switch render targets.
|
||||
@@ -215,10 +853,6 @@ RECOMP_PATCH void fxcommon3score_draw(enum item_e item_id, void *arg1, Gfx **gfx
|
||||
gEXPopCombineMode((*gfx)++);
|
||||
}
|
||||
|
||||
if (a1->anim_ctrl != NULL) {
|
||||
anctrl_drawSetup(a1->anim_ctrl, sp5C, 1);
|
||||
}
|
||||
|
||||
// @recomp Set the model transform ID.
|
||||
cur_drawn_model_transform_id = HUD_SCORE3_TRANSFORM_ID_START + item_id * MARKER_TRANSFORM_ID_COUNT;
|
||||
|
||||
@@ -226,5 +860,23 @@ RECOMP_PATCH void fxcommon3score_draw(enum item_e item_id, void *arg1, Gfx **gfx
|
||||
|
||||
// @recomp Clear the model transform ID.
|
||||
cur_drawn_model_transform_id = 0;
|
||||
|
||||
if (aligned_to_the_right) {
|
||||
// @recomp Clear the matrix group.
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
}
|
||||
}//L80300BA4
|
||||
}
|
||||
|
||||
// @recomp: Patched to interpolate the header of the totals screen on the pause menu.
|
||||
RECOMP_PATCH void gcpausemenu_printTotalsHeader(s32 page_id) {
|
||||
// @recomp Assign an ID for the totals text.
|
||||
cur_pushed_text_transform_id = HUD_TOTALS_PRINT_TRANSFORM_ID_START;
|
||||
|
||||
struct1Cs_1 *v0 = D_8036C58C + page_id;
|
||||
print_bold_overlapping(v0->x, D_80383010.unk8, -1.05f, v0->string);
|
||||
|
||||
// @recomp Clear the ID text.
|
||||
cur_pushed_text_transform_id = 0;
|
||||
}
|
||||
@@ -4,6 +4,10 @@
|
||||
#include "functions.h"
|
||||
#include "../src/core2/gc/zoombox.h"
|
||||
|
||||
extern u16 gScissorBoxLeft;
|
||||
extern u16 gScissorBoxRight;
|
||||
extern u16 gScissorBoxTop;
|
||||
extern u16 gScissorBoxBottom;
|
||||
extern MtxF sViewportMatrix;
|
||||
extern f32 sViewportLookVector[3];
|
||||
extern u32 D_803835E0;
|
||||
@@ -41,6 +45,8 @@ void func_803382E4(s32);
|
||||
void func_8033687C(Gfx **);
|
||||
void func_80335D30(Gfx **);
|
||||
void func_80344090(BKSpriteDisplayData *self, s32 frame, Gfx **gfx);
|
||||
void func_802F7B90(s32 arg0, s32 arg1, s32 arg2);
|
||||
void gcpausemenu_zoombox_callback(s32 portrait_id, s32 zoombox_state);
|
||||
|
||||
void actor_predrawMethod(Actor *);
|
||||
void actor_postdrawMethod(ActorMarker *);
|
||||
@@ -77,6 +83,9 @@ extern void gcdialog_draw(Gfx **gfx, Mtx **mtx, Vtx **vtx);
|
||||
extern void itemPrint_draw(Gfx **gdl, Mtx **mptr, Vtx **vptr);
|
||||
extern void printbuffer_draw(Gfx **gfx, Mtx **mtx, Vtx **vtx);
|
||||
|
||||
extern u32 cur_pushed_text_transform_id;
|
||||
extern u32 cur_pushed_text_transform_origin;
|
||||
|
||||
// @recomp Patched to set the projection transform ID for the main projection.
|
||||
RECOMP_PATCH void func_802E39D0(Gfx **gdl, Mtx **mptr, Vtx **vptr, s32 framebuffer_idx, s32 arg4) {
|
||||
// @recomp Set the perspective projection transform ID.
|
||||
@@ -309,6 +318,10 @@ RECOMP_PATCH Actor *func_802DC320(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx
|
||||
return this;
|
||||
}
|
||||
|
||||
bool left_aligned_zoombox(GcZoombox *this) {
|
||||
return !this->unk1A4_15 && this->callback == &gcpausemenu_zoombox_callback;
|
||||
}
|
||||
|
||||
// @recomp Patched to set the zoombox's model transform ID.
|
||||
RECOMP_PATCH void func_803163A8(GcZoombox *this, Gfx **gfx, Mtx **mtx) {
|
||||
f32 sp5C[3];
|
||||
@@ -317,6 +330,16 @@ RECOMP_PATCH void func_803163A8(GcZoombox *this, Gfx **gfx, Mtx **mtx) {
|
||||
f32 sp38[3];
|
||||
f32 sp34;
|
||||
|
||||
// @recomp Align the zoombox to the left of the screen if necessary.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
if (left_aligned_zoombox(this)) {
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_RIGHT, 0, gScissorBoxRight, 0, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_LEFT, 0, 0);
|
||||
}
|
||||
|
||||
viewport_setRenderViewportAndPerspectiveMatrix(gfx, mtx);
|
||||
|
||||
sp34 = viewport_transformCoordinate(this->unk170, this->unk172, sp50, sp5C);
|
||||
if (this->unk1A4_24) {
|
||||
sp5C[1] += 180.0f;
|
||||
@@ -338,6 +361,12 @@ RECOMP_PATCH void func_803163A8(GcZoombox *this, Gfx **gfx, Mtx **mtx) {
|
||||
|
||||
// @recomp Reset the model transform ID.
|
||||
cur_drawn_model_transform_id = prev_transform_id;
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
if (left_aligned_zoombox(this)) {
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to set the zoombox portrait's model and ortho projection transform IDs.
|
||||
@@ -357,6 +386,14 @@ RECOMP_PATCH void func_803164B0(GcZoombox *this, Gfx **gfx, Mtx **mtx, s32 arg3,
|
||||
u32 prev_ortho_id = cur_ortho_projection_transform_id;
|
||||
cur_ortho_projection_transform_id = PROJECTION_PORTRAIT_TRANSFORM_ID_START + this->portrait_id;
|
||||
|
||||
// @recomp Align the zoombox's portrait to the left of the screen if necessary.
|
||||
// NOTE: gScissorBoxRight/gScissorBoxTop are incorrectly named in the decompilation and must be swapped.
|
||||
if (left_aligned_zoombox(this)) {
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_RIGHT, 0, gScissorBoxRight, 0, gScissorBoxBottom);
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_LEFT, 0, 0);
|
||||
}
|
||||
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
|
||||
// @recomp Reset the ortho projection transform ID.
|
||||
@@ -387,4 +424,50 @@ RECOMP_PATCH void func_803164B0(GcZoombox *this, Gfx **gfx, Mtx **mtx, s32 arg3,
|
||||
|
||||
// @recomp Pop the model matrix group.
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
|
||||
if (left_aligned_zoombox(this)) {
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to assign an ID to the text drawn by the zoombox.
|
||||
RECOMP_PATCH void func_803162B4(GcZoombox *this) {
|
||||
// @recomp Align the zoombox to the left of the screen if necessary.
|
||||
if (left_aligned_zoombox(this)) {
|
||||
cur_pushed_text_transform_origin = G_EX_ORIGIN_LEFT;
|
||||
}
|
||||
|
||||
// FIXME: Text inside the zoombox can be tagged but suffers from interpolation errors when scrolling
|
||||
// to the next line. This can probably be fixed by assigning IDs in a more clever way.
|
||||
//cur_pushed_text_transform_id = ZOOMBOX_PRINT_TRANSFORM_ID_START + this->portrait_id * ZOOMBOX_PRINT_TRANSFORM_ID_COUNT;
|
||||
|
||||
func_802F7B90(this->unk168, this->unk168, this->unk168);
|
||||
if (this->unk1A4_30) {
|
||||
if (this->unk1A4_17) {
|
||||
func_802F79D0(this->unk16A, this->unk16C, this->unk0, this->unk166, -1);
|
||||
}
|
||||
else if (this->unk1A4_15) {
|
||||
print_bold_spaced(this->unk16A, this->unk16C, this->unk0);
|
||||
}
|
||||
else {
|
||||
print_dialog(this->unk16A, this->unk16C, this->unk0);
|
||||
}
|
||||
}
|
||||
if (this->unk1A4_29) {
|
||||
if (this->unk1A4_15) {
|
||||
print_bold_spaced(this->unk16A, this->unk16E, this->unk30);
|
||||
}
|
||||
else {
|
||||
print_dialog(this->unk16A, this->unk16E, this->unk30);
|
||||
}
|
||||
}
|
||||
func_802F7B90(0xff, 0xff, 0xff);
|
||||
|
||||
if (left_aligned_zoombox(this)) {
|
||||
cur_pushed_text_transform_origin = G_EX_ORIGIN_NONE;
|
||||
}
|
||||
|
||||
// @recomp If IDs were assigned to the zoombox's text, it would get cleared here.
|
||||
//cur_pushed_text_transform_id = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
#include "patches.h"
|
||||
#include "transform_ids.h"
|
||||
#include "functions.h"
|
||||
|
||||
typedef struct {
|
||||
u8 unk0;
|
||||
u8 unk1;
|
||||
s8 unk2;
|
||||
s8 unk3;
|
||||
}Struct_6DA30_0_s;
|
||||
|
||||
typedef struct {
|
||||
s16 x;
|
||||
s16 y;
|
||||
s16 unk4;
|
||||
s16 unk6;
|
||||
u8 fmtString[8];
|
||||
f32 unk10;
|
||||
u8 *string;
|
||||
u8 rgba[4];
|
||||
} PrintBuffer;
|
||||
|
||||
extern char D_80380AB0;
|
||||
extern s8 D_80380F20[0x80];
|
||||
extern u16 gScissorBoxLeft;
|
||||
extern u16 gScissorBoxRight;
|
||||
extern u16 gScissorBoxTop;
|
||||
extern u16 gScissorBoxBottom;
|
||||
extern s32 D_80369068[];
|
||||
extern s32 D_80380B04;
|
||||
extern s32 D_80380AE8;
|
||||
extern s32 D_80380AEC;
|
||||
extern s32 D_80380AF0;
|
||||
extern s32 D_80380AF4;
|
||||
extern s32 D_80380AF8;
|
||||
extern s32 D_80380AFC;
|
||||
extern s32 D_80380B00;
|
||||
extern s32 D_80380B0C;
|
||||
extern s32 D_80380B10;
|
||||
extern s32 D_80380B14;
|
||||
extern s8 D_80380B20[0x400];
|
||||
extern bool print_sInFontFormatMode;
|
||||
extern Struct_6DA30_0_s D_80369000[];
|
||||
extern PrintBuffer *print_sPrintBuffer;
|
||||
extern PrintBuffer *print_sCurrentPtr;
|
||||
extern Gfx D_80369238[];
|
||||
|
||||
extern BKSpriteTextureBlock *func_802F5494(s32 letterId, s32 *fontType);
|
||||
extern void *func_802F55A8(u8 arg0);
|
||||
extern f32 func_802F6C90(u8 letter, f32 *xPtr, f32 *yPtr, f32 arg3);
|
||||
|
||||
extern struct {
|
||||
u8 unk0;
|
||||
u8 unk1;
|
||||
u8 unk2;
|
||||
u8 unk3;
|
||||
} D_80369078;
|
||||
|
||||
// @recomp This ID plus the index of the character in the string will be used to tag each letter if it's assigned before printing text.
|
||||
u32 cur_pushed_text_transform_id = 0;
|
||||
u32 cur_pushed_text_transform_origin = G_EX_ORIGIN_NONE;
|
||||
u32 cur_pushed_text_transform_skip_interpolation = FALSE;
|
||||
u32 cur_drawn_text_transform_id = 0;
|
||||
u32 cur_drawn_text_transform_skip_interpolation = 0;
|
||||
Mtx *cur_drawn_text_mtx = NULL;
|
||||
u32 print_sPrintBufferIDs[0x20];
|
||||
u32 print_sPrintBufferOrigins[0x20];
|
||||
u32 print_sPrintBufferSkipInterpolationFlags[0x20];
|
||||
|
||||
// @recomp Patched to assign the current ID and origin from the global variables to the print buffer array.
|
||||
RECOMP_PATCH void _printbuffer_push_new(s32 x, s32 y, u8 *string) {
|
||||
for (print_sCurrentPtr = print_sPrintBuffer; print_sCurrentPtr < print_sPrintBuffer + 0x20 && print_sCurrentPtr->string; print_sCurrentPtr++) {
|
||||
}
|
||||
if (print_sCurrentPtr == print_sPrintBuffer + 0x20) {
|
||||
print_sCurrentPtr = NULL;
|
||||
return;
|
||||
}
|
||||
print_sCurrentPtr->x = x;
|
||||
print_sCurrentPtr->y = y;
|
||||
print_sCurrentPtr->fmtString[0] = (u8)0;
|
||||
print_sCurrentPtr->string = string;
|
||||
print_sCurrentPtr->unk10 = 1.0f;
|
||||
print_sCurrentPtr->rgba[0] = (u8)D_80369078.unk0;
|
||||
print_sCurrentPtr->rgba[1] = (u8)D_80369078.unk1;
|
||||
print_sCurrentPtr->rgba[2] = (u8)D_80369078.unk2;
|
||||
print_sCurrentPtr->rgba[3] = (u8)D_80369078.unk3;
|
||||
|
||||
// @recomp Store the current ID and origin in the arrays that run parallel to the print buffer.
|
||||
u32 bufferIndex = print_sCurrentPtr - print_sPrintBuffer;
|
||||
print_sPrintBufferIDs[bufferIndex] = cur_pushed_text_transform_id;
|
||||
print_sPrintBufferOrigins[bufferIndex] = cur_pushed_text_transform_origin;
|
||||
print_sPrintBufferSkipInterpolationFlags[bufferIndex] = cur_pushed_text_transform_skip_interpolation;
|
||||
}
|
||||
|
||||
// @recomp Patched to force orthographic projections to be used for all letters.
|
||||
RECOMP_PATCH void _printbuffer_draw_letter(char letter, f32 *xPtr, f32 *yPtr, f32 arg3, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
static f32 D_80380FA0;
|
||||
|
||||
// u8 letter = arg0;
|
||||
BKSpriteTextureBlock *sp214;
|
||||
s32 sp210;
|
||||
s32 sp20C;
|
||||
s32 t0;
|
||||
s8 t1;
|
||||
f32 sp200;
|
||||
f32 f28;
|
||||
f32 sp1F8;
|
||||
s32 sp1F4; //font_type;
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
t0 = 0;
|
||||
sp200 = *xPtr;
|
||||
f28 = *yPtr;
|
||||
t1 = 0;
|
||||
|
||||
if (!D_80380B04 && !letter) {
|
||||
D_80380FA0 = 0.0f;
|
||||
}//L802F563C
|
||||
|
||||
switch (D_80380AE8) {
|
||||
case 0: //L802F5678
|
||||
if (letter >= '\x21' && letter < '\x5f') {
|
||||
sp20C = letter - '\x21';
|
||||
t0 = 1;
|
||||
}
|
||||
break;
|
||||
case 1: //L802F56A0
|
||||
if (letter < '\x80' && D_80380F20[letter] >= 0) {
|
||||
for (i = 0; D_80369000[i].unk0 != 0; i++) {
|
||||
if (letter == D_80369000[i].unk1 && D_80380AB0 == D_80369000[i].unk0) {
|
||||
t1 = D_80369000[i].unk3;
|
||||
break;
|
||||
}
|
||||
}//L802F5710
|
||||
sp20C = D_80380F20[letter];
|
||||
t0 = 1;
|
||||
D_80380AB0 = letter;
|
||||
f28 += (f32)t1 * arg3;
|
||||
}//L802F5738
|
||||
break;
|
||||
case 2: //L802F5740
|
||||
sp20C = letter;
|
||||
if (D_80380B04) {
|
||||
t0 = 1;
|
||||
sp20C += (D_80380B04 << 8) - 0x100;
|
||||
D_80380B04 = 0;
|
||||
}
|
||||
else {//L802F5764
|
||||
if (sp20C > 0 && sp20C < 0xfD)
|
||||
t0 = 1;
|
||||
}
|
||||
break;
|
||||
}//L802F5778
|
||||
|
||||
if (!t0 || print_sInFontFormatMode) {
|
||||
print_sInFontFormatMode = FALSE;
|
||||
switch (letter) {
|
||||
case ' '://802F5818
|
||||
*xPtr += ((D_80380AF0) ? D_80369068[D_80380AE8] : D_80369068[D_80380AE8] * 0.8) * arg3;
|
||||
break;
|
||||
|
||||
case 'b': //L802F5890
|
||||
//toggle background
|
||||
D_80380B00 = D_80380B00 ^ 1;
|
||||
break;
|
||||
|
||||
case 'f': //L802F58A8
|
||||
D_80380AEC = D_80380AE8 = D_80380AE8 ^ 1;
|
||||
break;
|
||||
|
||||
case 'l': //L802F58BC
|
||||
D_80380B10 = 0;
|
||||
break;
|
||||
|
||||
case 'h': //L802F58C8
|
||||
D_80380B10 = 1;
|
||||
break;
|
||||
|
||||
case 'j': //L802F58D4
|
||||
if (D_80380AFC == 0) {
|
||||
D_80380AFC = 1;
|
||||
D_80380AEC = D_80380AE8;
|
||||
D_80380AE8 = 2;
|
||||
// D_80380AE8 = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e': //L802F58FC
|
||||
if (D_80380AFC) {
|
||||
D_80380AFC = 0;
|
||||
D_80380AE8 = D_80380AEC;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p': //L802F5924
|
||||
D_80380AF0 = D_80380AF0 ^ 1;
|
||||
break;
|
||||
|
||||
case 'q': //L802F593C
|
||||
D_80380B14 = D_80380B14 ^ 1;
|
||||
if (D_80380B14) {
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_POINT);
|
||||
}
|
||||
else {//L802F5978
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_BILERP);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v': //L802F59A0
|
||||
//toggle letter gradient
|
||||
D_80380AF4 ^= 1;
|
||||
if (D_80380AF4) {
|
||||
// @recomp Comment these lines out, as the viewport is now set in the parent function.
|
||||
//viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
//gDPPipeSync((*gfx)++);
|
||||
//gDPSetTexturePersp((*gfx)++, G_TP_PERSP);
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0x00, 0x00, 0x00, 0xFF);
|
||||
gDPSetCombineLERP((*gfx)++, 0, 0, 0, TEXEL0, TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0, TEXEL0, 0, SHADE, 0);
|
||||
}
|
||||
else {//L802F5A44
|
||||
gDPSetCombineMode((*gfx)++, G_CC_DECALRGBA, G_CC_DECALRGBA);
|
||||
// @recomp Comment this line out, as texture rectangle letters are no longer possible.
|
||||
//gDPSetTexturePersp((*gfx)++, G_TP_NONE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd': //L802F5A8C
|
||||
D_80380AF8 ^= 1;
|
||||
if (D_80380AF8) {
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetCycleType((*gfx)++, G_CYC_2CYCLE);
|
||||
gDPSetRenderMode((*gfx)++, G_RM_PASS, G_RM_XLU_SURF2);
|
||||
gDPSetTextureLOD((*gfx)++, G_TL_TILE);
|
||||
gDPSetCombineLERP((*gfx)++, 0, 0, 0, TEXEL0, TEXEL0, 0, TEXEL1, 0, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED);
|
||||
}
|
||||
else {//L802F5B48
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetCombineMode((*gfx)++, G_CC_DECALRGBA, G_CC_DECALRGBA);
|
||||
gDPSetCycleType((*gfx)++, G_CYC_1CYCLE);
|
||||
gDPSetTextureLOD((*gfx)++, G_TL_LOD);
|
||||
gDPSetRenderMode((*gfx)++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xfd: //L802F5BEC
|
||||
print_sInFontFormatMode = TRUE;
|
||||
break;
|
||||
|
||||
case 0xfe://L802F5BF4
|
||||
D_80380B04 = 1;
|
||||
break;
|
||||
|
||||
case 0xff://L802F5BFC
|
||||
D_80380B04 = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {//L802F5C08
|
||||
sp214 = func_802F5494(sp20C, &sp1F4);
|
||||
if (D_80380B10 != 0) {
|
||||
sp200 += randf2(-2.0f, 2.0f);
|
||||
f28 += randf2(-2.0f, 2.0f);
|
||||
}
|
||||
sp1F8 = (D_80380AF0 != 0) ? D_80369068[D_80380AE8] : sp214->x;
|
||||
|
||||
// temp_f2 = D_80380FA0;
|
||||
// phi_f2 = temp_f2;
|
||||
if (D_80380FA0 == 0.0f) {
|
||||
D_80380FA0 = -sp1F8 * 0.5;
|
||||
}
|
||||
|
||||
sp200 += (D_80380FA0 + (sp1F8 - sp214->x) * 0.5);
|
||||
f28 -= sp214->h * 0.5;
|
||||
sp210 = (s32)(sp214 + 1);
|
||||
while (sp210 % 8) {
|
||||
sp210++;
|
||||
}
|
||||
if (sp1F4 == SPRITE_TYPE_RGBA32) {
|
||||
gDPLoadTextureTile((*gfx)++, sp210, G_IM_FMT_RGBA, G_IM_SIZ_32b, sp214->w, sp214->h, 0, 0, sp214->x - 1, sp214->y - 1, NULL, G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
}
|
||||
else if (sp1F4 == SPRITE_TYPE_IA8) {
|
||||
gDPLoadTextureTile((*gfx)++, sp210, G_IM_FMT_IA, G_IM_SIZ_8b, sp214->w, sp214->h, 0, 0, sp214->x - 1, sp214->y - 1, NULL, G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
}
|
||||
else if (sp1F4 == SPRITE_TYPE_I8) {
|
||||
gDPLoadTextureTile((*gfx)++, sp210, G_IM_FMT_I, G_IM_SIZ_8b, sp214->w, sp214->h, 0, 0, sp214->x - 1, sp214->y - 1, NULL, G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
}
|
||||
else if (sp1F4 == SPRITE_TYPE_I4) {
|
||||
gDPLoadTextureTile_4b((*gfx)++, sp210, G_IM_FMT_I, sp214->w, sp214->h, 0, 0, sp214->x - 1, sp214->y - 1, NULL, G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
}
|
||||
else if (sp1F4 == SPRITE_TYPE_CI8) {
|
||||
void *pal = func_802F55A8(sp20C);
|
||||
gDPLoadTLUT_pal256((*gfx)++, pal);
|
||||
gDPLoadTextureTile((*gfx)++, sp210, G_IM_FMT_CI, G_IM_SIZ_8b, sp214->w, sp214->h, 0, 0, sp214->x - 1, sp214->y - 1, NULL, G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
gDPSetTextureLUT((*gfx)++, G_TT_RGBA16);
|
||||
}//L802F6570
|
||||
if (D_80380AF8 != 0) {
|
||||
s32 temp_t1;
|
||||
s32 phi_a0;
|
||||
temp_t1 = ((print_sCurrentPtr->unk4 - print_sCurrentPtr->y) - D_80380B0C) + 1;
|
||||
phi_a0 = -MAX(1 - D_80380B0C, MIN(0, temp_t1));
|
||||
|
||||
gDPSetTextureImage((*gfx)++, G_IM_FMT_I, G_IM_SIZ_8b, 32, &D_80380B20);
|
||||
gDPSetTile((*gfx)++, G_IM_FMT_I, G_IM_SIZ_8b, (sp214->x + 8) >> 3, 0x0100, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOLOD);
|
||||
gDPLoadSync((*gfx)++);
|
||||
gDPLoadTile((*gfx)++, G_TX_LOADTILE, 0 << G_TEXTURE_IMAGE_FRAC, (phi_a0) << G_TEXTURE_IMAGE_FRAC, (sp214->x) << G_TEXTURE_IMAGE_FRAC, (D_80380B0C - 1) << G_TEXTURE_IMAGE_FRAC);
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetTile((*gfx)++, G_IM_FMT_I, G_IM_SIZ_8b, ((sp214->x - 0 + 1) * G_IM_SIZ_8b_LINE_BYTES + 7) >> 3, 0x0100, 1, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOLOD);
|
||||
gDPSetTileSize((*gfx)++, 1, 0 << G_TEXTURE_IMAGE_FRAC, (MAX(0, temp_t1) + phi_a0) << G_TEXTURE_IMAGE_FRAC, (sp214->x) << G_TEXTURE_IMAGE_FRAC, (MAX(0, temp_t1) - (1 - D_80380B0C)) << G_TEXTURE_IMAGE_FRAC);
|
||||
|
||||
// gDPLoadMultiTile((*gfx)++, &D_80380B20,)
|
||||
|
||||
}//L802F677C
|
||||
|
||||
// @recomp Force orthographic projection rectangles to be used for all letters as it allows them to be interpolated.
|
||||
if (TRUE) { //if (D_80380AF4 != 0) {
|
||||
f32 temp_f24;
|
||||
f32 spD0;
|
||||
f32 ix;
|
||||
f32 iy;
|
||||
f32 temp_f26;
|
||||
f32 spC0;
|
||||
|
||||
temp_f24 = (sp214->x - 1.0);
|
||||
spD0 = sp214->y - 1.0;
|
||||
temp_f26 = (f64)sp200 - (f32)gFramebufferWidth * 0.5;
|
||||
spC0 = (f64)f28 - (f32)gFramebufferHeight * 0.5 - 0.5f;
|
||||
|
||||
// @recomp Assign a unique matrix and group to each letter drawn if an ID is currently assigned.
|
||||
if (cur_drawn_text_transform_id != 0) {
|
||||
gSPMatrix((*gfx)++, OS_K0_TO_PHYSICAL(cur_drawn_text_mtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
if (cur_drawn_text_transform_skip_interpolation) {
|
||||
gEXMatrixGroupSkipAll((*gfx)++, cur_drawn_text_transform_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
}
|
||||
else {
|
||||
gEXMatrixGroupSimpleVerts((*gfx)++, cur_drawn_text_transform_id, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
}
|
||||
|
||||
cur_drawn_text_transform_id++;
|
||||
}
|
||||
|
||||
gSPVertex((*gfx)++, *vtx, 4, 0);
|
||||
for (iy = 0.0f; iy < 2.0; iy += 1.0) {
|
||||
for (ix = 0.0f; ix < 2.0; ix += 1.0) {
|
||||
s32 s = (ix * temp_f24 * 64.0f);
|
||||
(*vtx)->v.ob[0] = (s16)(s32)((f64)(temp_f26 + (temp_f24 * arg3 * ix)) * 4.0);
|
||||
{
|
||||
s32 t = (iy * spD0 * 64.0f);
|
||||
(*vtx)->v.ob[1] = (s16)(s32)((f64)(spC0 + (spD0 * arg3 * iy)) * -4.0);
|
||||
(*vtx)->v.ob[2] = -0x14;
|
||||
(*vtx)->v.tc[0] = s;
|
||||
(*vtx)->v.tc[1] = t;
|
||||
}
|
||||
(*vtx)->v.cn[3] = (iy != 0.0f) ? print_sCurrentPtr->unk6 : print_sCurrentPtr->unk4;
|
||||
|
||||
(*vtx)++;
|
||||
}
|
||||
}
|
||||
|
||||
gSP1Quadrangle((*gfx)++, 0, 1, 3, 2, 0);
|
||||
|
||||
// @recomp Clear the matrix group.
|
||||
if (cur_drawn_text_transform_id != 0) {
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
}
|
||||
}
|
||||
else {
|
||||
gSPScisTextureRectangle((*gfx)++, (s32)(sp200 * 4.0f), (s32)(f28 * 4.0f), (s32)((sp200 + sp214->x * arg3) * 4.0f), (s32)((f28 + sp214->y * arg3) * 4.0f), 0, 0, 0, (s32)(1024.0f / arg3), (s32)(1024.0f / arg3));
|
||||
}
|
||||
*xPtr += sp1F8 * arg3;
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patched to set up an orthographic projection for each print and align them to their corresponding side on the screen.
|
||||
RECOMP_PATCH void printbuffer_draw(Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
static f32 D_80380FA8[0x20];
|
||||
|
||||
s32 j;
|
||||
f32 _x;
|
||||
f32 _y;
|
||||
f32 width;
|
||||
|
||||
gSPDisplayList((*gfx)++, D_80369238);
|
||||
|
||||
// @recomp Set up a scissor that covers the entire screen.
|
||||
gEXPushScissor((*gfx)++);
|
||||
gEXSetScissor((*gfx)++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_RIGHT, 0, gScissorBoxRight, 0, gScissorBoxBottom);
|
||||
|
||||
// @recomp Set up an orthographic projection that will be used for all letters by default.
|
||||
u32 curOrigin = G_EX_ORIGIN_NONE;
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXSetRectAlign((*gfx)++, G_EX_ORIGIN_NONE, G_EX_ORIGIN_NONE, 0, 0, 0, 0);
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
cur_drawn_text_mtx = (*mtx - 1);
|
||||
|
||||
// @recomp Set up some drawing parameters that were set up when changing between rectangle and orthographic mode.
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetTexturePersp((*gfx)++, G_TP_PERSP);
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0x00, 0x00, 0x00, 0xFF);
|
||||
gDPSetCombineLERP((*gfx)++, 0, 0, 0, TEXEL0, TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0, TEXEL0, 0, SHADE, 0);
|
||||
|
||||
for (print_sCurrentPtr = print_sPrintBuffer; print_sCurrentPtr < print_sPrintBuffer + 0x20; print_sCurrentPtr++) {
|
||||
if (print_sCurrentPtr->string != 0) {
|
||||
// @recomp When the origin changes, set up a new viewport with the alignment specified for the print buffer.
|
||||
u32 bufferIndex = print_sCurrentPtr - print_sPrintBuffer;
|
||||
cur_drawn_text_transform_id = print_sPrintBufferIDs[bufferIndex];
|
||||
cur_drawn_text_transform_skip_interpolation = print_sPrintBufferSkipInterpolationFlags[bufferIndex];
|
||||
if (curOrigin != print_sPrintBufferOrigins[bufferIndex]) {
|
||||
curOrigin = print_sPrintBufferOrigins[bufferIndex];
|
||||
s32 viewportOffset = (gScissorBoxTop * curOrigin * -4) / G_EX_ORIGIN_RIGHT;
|
||||
gEXSetViewportAlign((*gfx)++, curOrigin, viewportOffset, 0);
|
||||
gEXSetRectAlign((*gfx)++, curOrigin, curOrigin, viewportOffset, 0, viewportOffset, 0);
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
}
|
||||
|
||||
_x = (f32)print_sCurrentPtr->x;
|
||||
_y = (f32)print_sCurrentPtr->y;
|
||||
//toggle on string format modifiers
|
||||
for (j = 0; print_sCurrentPtr->fmtString[j] != 0; j++) {
|
||||
_printbuffer_draw_letter(0xFD, &_x, &_y, 1.0f, gfx, mtx, vtx);
|
||||
_printbuffer_draw_letter(print_sCurrentPtr->fmtString[j], &_x, &_y, 1.0f, gfx, mtx, vtx);
|
||||
}
|
||||
if (D_80380B00 != 0) {
|
||||
width = (strlen(print_sCurrentPtr->string) - 1) * D_80369068[D_80380AE8];
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0x00, 0x00, 0x00, 0x64);
|
||||
gDPSetCombineMode((*gfx)++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
|
||||
gDPScisFillRectangle((*gfx)++, _x - D_80369068[D_80380AE8] / 2 - 1.0f, _y - D_80369068[D_80380AE8] / 2 - 1.0f, _x + width + D_80369068[D_80380AE8] / 2, _y + D_80369068[D_80380AE8] / 2 + 1.0f);
|
||||
gDPPipeSync((*gfx)++);
|
||||
|
||||
}//L802F73E8
|
||||
// @recomp Ignore the condition for not setting up these parameters while on orthographic mode.
|
||||
if (D_80380AF8 == 0) { //if ((D_80380AF8 == 0) && (D_80380AF4 == 0)) {
|
||||
if (D_80380AE8 != 0) {
|
||||
gDPSetCombineMode((*gfx)++, G_CC_DECALRGBA, G_CC_DECALRGBA);
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
else {
|
||||
gDPSetCombineMode((*gfx)++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, print_sCurrentPtr->rgba[0], print_sCurrentPtr->rgba[1], print_sCurrentPtr->rgba[2], print_sCurrentPtr->rgba[3]);
|
||||
}
|
||||
}
|
||||
if ((D_80380AE8 == 1) && ((f64)print_sCurrentPtr->unk10 < 0.0)) {
|
||||
for (j = 0; print_sCurrentPtr->string[j]; j++) {
|
||||
D_80380FA8[j] = func_802F6C90(print_sCurrentPtr->string[j], &_x, &_y, -print_sCurrentPtr->unk10);
|
||||
}
|
||||
while (j >= 0) {
|
||||
_x = D_80380FA8[j];
|
||||
_printbuffer_draw_letter(print_sCurrentPtr->string[j], &_x, &_y, -print_sCurrentPtr->unk10, gfx, mtx, vtx);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (j = 0; (print_sCurrentPtr->string[j] != 0) || (D_80380B04 != 0); j++) {
|
||||
_printbuffer_draw_letter(print_sCurrentPtr->string[j], &_x, &_y, print_sCurrentPtr->unk10, gfx, mtx, vtx);
|
||||
}
|
||||
}
|
||||
//toggle off string format modifiers
|
||||
for (j = 0; print_sCurrentPtr->fmtString[j] != 0; j++) {
|
||||
_printbuffer_draw_letter(0xFD, &_x, &_y, 1.0f, gfx, mtx, vtx);
|
||||
_printbuffer_draw_letter(print_sCurrentPtr->fmtString[j], &_x, &_y, 1.0f, gfx, mtx, vtx);
|
||||
}
|
||||
_printbuffer_draw_letter(0, &_x, &_y, 1.0f, gfx, mtx, vtx);
|
||||
print_sCurrentPtr->string = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Clear the alignment and the scissor. Also clear the assigned transform group for the letters.
|
||||
gEXSetViewportAlign((*gfx)++, G_EX_ORIGIN_NONE, 0, 0);
|
||||
gEXSetRectAlign((*gfx)++, G_EX_ORIGIN_NONE, G_EX_ORIGIN_NONE, 0, 0, 0, 0);
|
||||
gEXPopScissor((*gfx)++);
|
||||
cur_drawn_text_transform_id = 0;
|
||||
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPSetTexturePersp((*gfx)++, G_TP_PERSP);
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_BILERP);
|
||||
viewport_setRenderViewportAndPerspectiveMatrix(gfx, mtx);
|
||||
}
|
||||
+38
-6
@@ -38,13 +38,38 @@
|
||||
|
||||
// HUD Honeycomb: 0x00F34000 - 0x00F3400F
|
||||
#define HUD_HONEYCOMB_TRANSFORM_ID_START 0x00F34000
|
||||
#define HUD_HONEYCOMB_TRANSFORM_ID_COUNT 6
|
||||
|
||||
// HUD score item depth rects: 0x00F34010 - 0x00F340FF
|
||||
#define HUD_SCORE3_DEPTH_RECT_TRANSFORM_ID_START 0x00F34010
|
||||
// HUD Life Score: 0x00F34010 - 0x00F34017
|
||||
#define HUD_LIFESCORE_TRANSFORM_PRINT_ID_START 0x00F34010
|
||||
|
||||
// HUD score items: 0x00F34100 - 0x00F3FFFF
|
||||
#define HUD_SCORE3_TRANSFORM_ID_START 0x00F34100
|
||||
// HUD Life Score: 0x00F34018 - 0x00F3401F
|
||||
#define HUD_LIFESCORE_TRANSFORM_ID_START 0x00F34018
|
||||
|
||||
// HUD Health Score: 0x00F34020 - 0x00F3402F
|
||||
#define HUD_HEALTHSCORE_TRANSFORM_ID_START 0x00F34020
|
||||
|
||||
// HUD Air Score: 0x00F34030 - 0x00F3403F
|
||||
#define HUD_AIRSCORE_TRANSFORM_ID_START 0x00F34030
|
||||
|
||||
// HUD Jinjo Score: 0x00F34040 - 0x00F3404F
|
||||
#define HUD_JINJOSCORE_TRANSFORM_ID_START 0x00F34040
|
||||
|
||||
// HUD Score 2 Print: 0x00F34050 - 0x00F3414F
|
||||
#define HUD_SCORE2_TRANSFORM_PRINT_ID_START 0x00F34050
|
||||
#define HUD_SCORE2_TRANSFORM_PRINT_ID_COUNT 4
|
||||
|
||||
// HUD Score 2: 0x00F34150 - 0x00F3424F
|
||||
#define HUD_SCORE2_TRANSFORM_ID_START 0x00F34150
|
||||
|
||||
// HUD Score 3 Print: 0x00F34250 - 0x00F3434F
|
||||
#define HUD_SCORE3_TRANSFORM_PRINT_ID_START 0x00F34250
|
||||
#define HUD_SCORE3_TRANSFORM_PRINT_ID_COUNT 4
|
||||
|
||||
// HUD score item depth rects: 0x00F34350 - 0x00F343FF
|
||||
#define HUD_SCORE3_DEPTH_RECT_TRANSFORM_ID_START 0x00F34350
|
||||
|
||||
// HUD Score 3: 0x00F34400 - 0x00F3FFFF
|
||||
#define HUD_SCORE3_TRANSFORM_ID_START 0x00F34400
|
||||
|
||||
// Lens flare: 0x00F40000 - 0x00F40FFF
|
||||
#define LENS_FLARE_TRANSFORM_ID_START 0x00F40000
|
||||
@@ -53,9 +78,16 @@
|
||||
// Snow: 0x00F41000 - 0x00F410FF
|
||||
#define SNOW_TRANSFORM_ID_START 0x00F41000
|
||||
|
||||
// Snow: 0x00F42000 - 0x00F420FF
|
||||
// Clanker: 0x00F42000 - 0x00F420FF
|
||||
#define CLANKER_TRANSFORM_ID_START 0x00F42000
|
||||
|
||||
// HUD Totals Print: 0x00F42100 - 0x00F421FF
|
||||
#define HUD_TOTALS_PRINT_TRANSFORM_ID_START 0x00F42100
|
||||
|
||||
// Zoombox Print: 0x00F42200 - 0x00F520FF
|
||||
#define ZOOMBOX_PRINT_TRANSFORM_ID_START 0x00F42200
|
||||
#define ZOOMBOX_PRINT_TRANSFORM_ID_COUNT 512
|
||||
|
||||
// Normal Particles: 0x01000000 - 0x01FFFFFF
|
||||
#define NORMAL_PARTICLE_TRANSFORM_ID_START 0x01000000
|
||||
#define NORMAL_PARTICLE_ID_MAX 0x01000000
|
||||
|
||||
Reference in New Issue
Block a user