jak-project/docs/scratch/sprite_code_old.txt
ManDude 67bb1193a8
[runtime] GPU sprite renderer (#1075)
* sprite_3d first attempt

* fixs

* fix Q usage

* ??

* attempt 2

* Update sprite_3d.vert

* works-ish

* works properly!

* scissor fix

* simplify shader

* texture support except everything is broken for some reason

* stuff

* Update SpriteRenderer.cpp

* meltdown

* Revert "simplify shader"

This reverts commit 97bd9b77be.

* Revert "Revert "simplify shader""

This reverts commit 32fb46ce90.

* fix blend

* fix blend and prim

* fix depth write and texture rendering

* fix bugs

* remove noperspective

* fix and finalize sprite 3D vert shader

* optimize 3D program

* 2D sprites! almost first try

* fixes + merge shader code

* HUD sprite support and clean up code

* oopsie

* fix 3d sprites

* minor cleanup and increase sprite buffer to 8k sprites

* clang

* replace some uses of `glBufferSubData` with `glBufferData`
2022-01-15 12:31:38 -05:00

903 lines
34 KiB
Plaintext

3D:
/*
SpriteHud2DPacket packet;
memset(&packet, 0, sizeof(packet));
// ilw.y vi08, 1(vi02) | nop vi08 = matrix
u32 offset_selector = m_vec_data_2d[sprite_idx].matrix();
// assert(offset_selector == 0 || offset_selector == 1);
// moved this out of the loop.
// lq.xyzw vf25, 900(vi00) | nop vf25 = cam_mat
// lq.xyzw vf26, 901(vi00) | nop
// lq.xyzw vf27, 902(vi00) | nop
// lq.xyzw vf28, 903(vi00) | nop
// lq.xyzw vf30, 904(vi00) | nop vf30 = hvdf_offset
// vf30
// lqi.xyzw vf01, vi02 | nop
Vector4f pos_vf01 = m_vec_data_2d[sprite_idx].xyz_sx;
// lqi.xyzw vf05, vi02 | nop
Vector4f flags_vf05 = m_vec_data_2d[sprite_idx].flag_rot_sy;
// lqi.xyzw vf11, vi02 | nop
Vector4f color_vf11 = m_vec_data_2d[sprite_idx].rgba;
// multiplications from the right column
transformed_pos_vf02 = matrix_transform(camera_matrix, pos_vf01);
scales_vf01 = pos_vf01; // now used for something else.
// lq.xyzw vf12, 1020(vi00) | mulaw.xyzw ACC, vf28, vf00
// vf12 is fog consts
fog_consts_vf12 = Vector4f(m_frame_data.fog_min, m_frame_data.fog_max, m_frame_data.max_scale,
m_frame_data.bonus);
// ilw.y vi08, 1(vi02) | maddax.xyzw ACC, vf25, vf01
// load offset selector for the next round.
// nop | madday.xyzw ACC, vf26, vf01
// nop | maddz.xyzw vf02, vf27, vf01
// move.w vf05, vf00 | addw.z vf01, vf00, vf05
// scales_vf01.z = sy
scales_vf01.z() = flags_vf05.w(); // start building the scale vector
flags_vf05.w() = 1.f; // what are we building in flags right now??
// nop | nop
// div Q, vf31.x, vf02.w | muly.z vf05, vf05, vf31
Q = m_frame_data.pfog0 / transformed_pos_vf02.w();
flags_vf05.z() *= m_frame_data.deg_to_rad;
// nop | mul.xyzw vf03, vf02, vf29
Vector4f scaled_pos_vf03 = transformed_pos_vf02.elementwise_multiply(m_frame_data.hmge_scale);
// nop | nop
// nop | nop
// nop | mulz.z vf04, vf05, vf05 (ts)
// fmt::print("rot is {} degrees\n", flags_vf05.z() * 360.0 / (2.0 * M_PI));
// the load is for rotation stuff,
// lq.xyzw vf14, 1001(vi00) | clipw.xyz vf03, vf03 (used for fcand)
// iaddi vi06, vi00, 0x1 | adda.xyzw ACC, vf11, vf11 (used for fmand)
// upcoming fcand with 0x3f, that checks all of them.
bool fcand_result = clip_xyz_plus_minus(scaled_pos_vf03);
bool fmand_result = color_vf11.w() == 0; // (really w+w, but I don't think it matters?)
// L8:
// xgkick double buffer setup
// ior vi05, vi15, vi00 | mul.zw vf01, vf01, Q
scales_vf01.z() *= Q; // sy
scales_vf01.w() *= Q; // sx
// lq.xyzw vf06, 998(vi00) | mulz.xyzw vf15, vf05, vf04 (ts)
auto adgif_vf06 = m_frame_data.adgif_giftag;
// lq.xyzw vf14, 1002(vi00) ts| mula.xyzw ACC, vf05, vf14 (ts)
// fmand vi01, vi06 | mul.xyz vf02, vf02, Q
transformed_pos_vf02.x() *= Q;
transformed_pos_vf02.y() *= Q;
transformed_pos_vf02.z() *= Q;
// ibne vi00, vi01, L10 | addz.x vf01, vf00, vf01
scales_vf01.x() = scales_vf01.z(); // = sy
if (fmand_result) {
continue; // reject!
}
// lqi.xyzw vf07, vi03 | mulz.xyzw vf16, vf15, vf04 (ts)
// vf07 is first use adgif
// lq.xyzw vf14, 1003(vi00) | madda.xyzw ACC, vf15, vf14 (ts both)
// lqi.xyzw vf08, vi03 | add.xyzw vf10, vf02, vf30
// vf08 is second user adgif
offset_pos_vf10 = transformed_pos_vf02 + hvdf_offset;
// if (m_extra_debug) {
// ImGui::Text("sel %d", offset_selector);
// //ImGui::Text("hvdf off z: %f tf/w z: %f", hvdf_offset.z(), transformed_pos_vf02.z());
// imgui_vec(hvdf_offset, "hvdf");
// imgui_vec(transformed_pos_vf02, "tf'd");
// }
// lqi.xyzw vf09, vi03 | mulw.x vf01, vf01, vf01
// vf09 is third user adgif
scales_vf01.x() *= scales_vf01.w(); // x = sx * sy
// sqi.xyzw vf06, vi05 | mulz.xyzw vf15, vf16, vf04 (ts)
// FIRST ADGIF IS adgif_vf06
packet.adgif_giftag = adgif_vf06;
// just do all 5 now.
packet.user_adgif = m_adgif[sprite_idx];
offset_pos_vf10.w() = std::max(offset_pos_vf10.w(), m_frame_data.fog_max);
scales_vf01.z() = std::max(scales_vf01.z(), m_frame_data.min_scale);
scales_vf01.w() = std::max(scales_vf01.w(), m_frame_data.min_scale);
scales_vf01.x() *= m_frame_data.inv_area; // x = sx * sy * inv_area (area ratio)
offset_pos_vf10.w() = std::min(offset_pos_vf10.w(), m_frame_data.fog_min);
scales_vf01.z() = std::min(scales_vf01.z(), fog_consts_vf12.z());
scales_vf01.w() = std::min(scales_vf01.w(), fog_consts_vf12.z());
bool use_first_giftag = offset_selector == 0;
auto flag_vi07 = m_vec_data_2d[sprite_idx].flag();
scales_vf01.x() = std::min(scales_vf01.x(), 1.f);
transformed_pos_vf02.w() = offset_pos_vf10.w() - fog_consts_vf12.y();
color_vf11.w() *= scales_vf01.x(); // is this right? doesn't this stall??
// ibne vi00, vi09, L6 | nop
if (transformed_pos_vf02.w() != 0) {
use_first_giftag = false;
}
flag_vi07 = 0; // todo hack
Vector4f* xy_array = m_frame_data.xyz_array + flag_vi07;
math::Vector<s32, 4> color_integer_vf11 = color_vf11.cast<s32>();
packet.color = color_integer_vf11;
if (fcand_result) {
continue; // reject (could move earlier)
}
Vector4f transformed[4];
flags_vf05 = m_vec_data_2d[sprite_idx].flag_rot_sy;
// do rot
rot = sprite_quat_to_rot(flags_vf05.x(), flags_vf05.y(), flags_vf05.z());
// fmt::print("root: {}\n", offset_pos_vf10.to_string_aligned());
// for (int i = 0; i < 3; i++) {
// fmt::print("M{}: {}\n", i, rot[i].to_string_aligned());
// }
for (int i = 0; i < 4; i++) {
transformed[i] =
sprite_transform2(m_vec_data_2d[sprite_idx].xyz_sx, xy_array[i], camera_matrix, rot,
m_vec_data_2d[sprite_idx].sx(), m_vec_data_2d[sprite_idx].sy(),
m_3d_matrix_data.hvdf_offset, m_frame_data.pfog0, m_frame_data.fog_min,
m_frame_data.fog_max);
}
Vector4f xy0_vf19 = transformed[0];
Vector4f xy1_vf20 = transformed[1];
Vector4f xy2_vf21 = transformed[2];
Vector4f xy3_vf22 = transformed[3];
packet.sprite_giftag =
use_first_giftag ? m_frame_data.sprite_2d_giftag : m_frame_data.sprite_2d_giftag2;
Vector4f st0_vf06 = m_frame_data.st_array[0];
Vector4f st1_vf07 = m_frame_data.st_array[1];
Vector4f st2_vf08 = m_frame_data.st_array[2];
Vector4f st3_vf09 = m_frame_data.st_array[3];
packet.st0 = st0_vf06;
packet.st1 = st1_vf07;
packet.st2 = st2_vf08;
packet.st3 = st3_vf09;
auto xy0_vf19_int = (xy0_vf19).cast<s32>();
auto xy1_vf20_int = (xy1_vf20).cast<s32>();
auto xy2_vf21_int = (xy2_vf21).cast<s32>();
auto xy3_vf22_int = (xy3_vf22).cast<s32>();
packet.xy0 = xy0_vf19_int;
packet.xy1 = xy1_vf20_int;
packet.xy2 = xy2_vf21_int;
packet.xy3 = xy3_vf22_int;
// m_sprite_renderer.render_gif((const u8*)&packet, sizeof(packet), render_state, prof);
*/
2d:
/*
if (m_extra_debug) {
ImGui::Text("Sprite: %d", sprite_idx);
}
SpriteHud2DPacket packet;
memset(&packet, 0, sizeof(packet));
// ilw.y vi08, 1(vi02) | nop vi08 = matrix
u32 offset_selector = m_vec_data_2d[sprite_idx].matrix();
// assert(offset_selector == 0 || offset_selector == 1);
// moved this out of the loop.
// lq.xyzw vf25, 900(vi00) | nop vf25 = cam_mat
// lq.xyzw vf26, 901(vi00) | nop
// lq.xyzw vf27, 902(vi00) | nop
// lq.xyzw vf28, 903(vi00) | nop
// lq.xyzw vf30, 904(vi00) | nop vf30 = hvdf_offset
// vf30
Vector4f hvdf_offset = m_3d_matrix_data.hvdf_offset;
glUniform4f(
glGetUniformLocation(render_state->shaders[ShaderId::SPRITE].id(), "hvdf_offset"),
hvdf_offset[0], hvdf_offset[1], hvdf_offset[2], hvdf_offset[3]);
glUniform1f(
glGetUniformLocation(render_state->shaders[ShaderId::SPRITE].id(), "fog_constant"),
m_frame_data.pfog0);
// lqi.xyzw vf01, vi02 | nop
Vector4f pos_vf01 = m_vec_data_2d[sprite_idx].xyz_sx;
if (m_extra_debug) {
imgui_vec(pos_vf01, "POS", 2);
}
// lqi.xyzw vf05, vi02 | nop
Vector4f flags_vf05 = m_vec_data_2d[sprite_idx].flag_rot_sy;
// lqi.xyzw vf11, vi02 | nop
Vector4f color_vf11 = m_vec_data_2d[sprite_idx].rgba;
// multiplications from the right column
Vector4f transformed_pos_vf02 = matrix_transform(camera_matrix, pos_vf01);
Vector4f scales_vf01 = pos_vf01; // now used for something else.
// lq.xyzw vf12, 1020(vi00) | mulaw.xyzw ACC, vf28, vf00
// vf12 is fog consts
Vector4f fog_consts_vf12(m_frame_data.fog_min, m_frame_data.fog_max, m_frame_data.max_scale,
m_frame_data.bonus);
// ilw.y vi08, 1(vi02) | maddax.xyzw ACC, vf25, vf01
// load offset selector for the next round.
// nop | madday.xyzw ACC, vf26, vf01
// nop | maddz.xyzw vf02, vf27, vf01
// move.w vf05, vf00 | addw.z vf01, vf00, vf05
// scales_vf01.z = sy
scales_vf01.z() = flags_vf05.w(); // start building the scale vector
flags_vf05.w() = 1.f; // what are we building in flags right now??
// nop | nop
// div Q, vf31.x, vf02.w | muly.z vf05, vf05, vf31
float Q = m_frame_data.pfog0 / transformed_pos_vf02.w();
flags_vf05.z() *= m_frame_data.deg_to_rad;
// nop | mul.xyzw vf03, vf02, vf29
Vector4f scaled_pos_vf03 = transformed_pos_vf02.elementwise_multiply(m_frame_data.hmge_scale);
// nop | nop
// nop | nop
// nop | mulz.z vf04, vf05, vf05 (ts)
// fmt::print("rot is {} degrees\n", flags_vf05.z() * 360.0 / (2.0 * M_PI));
// the load is for rotation stuff,
// lq.xyzw vf14, 1001(vi00) | clipw.xyz vf03, vf03 (used for fcand)
// iaddi vi06, vi00, 0x1 | adda.xyzw ACC, vf11, vf11 (used for fmand)
// upcoming fcand with 0x3f, that checks all of them.
bool fcand_result = clip_xyz_plus_minus(scaled_pos_vf03);
bool fmand_result = color_vf11.w() == 0; // (really w+w, but I don't think it matters?)
// L8:
// xgkick double buffer setup
// ior vi05, vi15, vi00 | mul.zw vf01, vf01, Q
scales_vf01.z() *= Q; // sy
scales_vf01.w() *= Q; // sx
// lq.xyzw vf06, 998(vi00) | mulz.xyzw vf15, vf05, vf04 (ts)
auto adgif_vf06 = m_frame_data.adgif_giftag;
// lq.xyzw vf14, 1002(vi00) ts| mula.xyzw ACC, vf05, vf14 (ts)
// fmand vi01, vi06 | mul.xyz vf02, vf02, Q
transformed_pos_vf02.x() *= Q;
transformed_pos_vf02.y() *= Q;
transformed_pos_vf02.z() *= Q;
// if (m_extra_debug) {
// imgui_vec(transformed_pos_vf02, "scaled xf");
// }
// ibne vi00, vi01, L10 | addz.x vf01, vf00, vf01
scales_vf01.x() = scales_vf01.z(); // = sy
if (fmand_result) {
if (m_extra_debug) {
ImGui::TextColored(ImVec4(0.8, 0.2, 0.2, 1.0), "fmand (1) reject");
ImGui::Separator();
}
continue; // reject!
}
// lqi.xyzw vf07, vi03 | mulz.xyzw vf16, vf15, vf04 (ts)
// vf07 is first use adgif
// lq.xyzw vf14, 1003(vi00) | madda.xyzw ACC, vf15, vf14 (ts both)
// lqi.xyzw vf08, vi03 | add.xyzw vf10, vf02, vf30
// vf08 is second user adgif
Vector4f offset_pos_vf10 = transformed_pos_vf02 + hvdf_offset;
// if (m_extra_debug) {
// ImGui::Text("sel %d", offset_selector);
// //ImGui::Text("hvdf off z: %f tf/w z: %f", hvdf_offset.z(), transformed_pos_vf02.z());
// imgui_vec(hvdf_offset, "hvdf");
// imgui_vec(transformed_pos_vf02, "tf'd");
// }
// lqi.xyzw vf09, vi03 | mulw.x vf01, vf01, vf01
// vf09 is third user adgif
scales_vf01.x() *= scales_vf01.w(); // x = sx * sy
// sqi.xyzw vf06, vi05 | mulz.xyzw vf15, vf16, vf04 (ts)
// FIRST ADGIF IS adgif_vf06
packet.adgif_giftag = adgif_vf06;
// lq.xyzw vf14, 1004(vi00) | madda.xyzw ACC, vf16, vf14 (ts both)
// sqi.xyzw vf07, vi05 | maxx.w vf10, vf10, vf12
// SECOND ADGIF is first user
// just do all 5 now.
packet.user_adgif = m_adgif[sprite_idx];
offset_pos_vf10.w() = std::max(offset_pos_vf10.w(), m_frame_data.fog_max);
// sqi.xyzw vf08, vi05 | maxz.zw vf01, vf01, vf31
// THIRD ADGIF is second user
scales_vf01.z() = std::max(scales_vf01.z(), m_frame_data.min_scale);
scales_vf01.w() = std::max(scales_vf01.w(), m_frame_data.min_scale);
// sqi.xyzw vf09, vi05 | mulz.xyzw vf16, vf15, vf04 (ts)
// FOURTH ADGIF is third user
// lq.xyzw vf14, 1005(vi00) | madda.xyzw ACC, vf15, vf14 (ts both)
// lqi.xyzw vf06, vi03 | mulw.x vf01, vf01, vf31
// vf06 is fourth user adgif
scales_vf01.x() *= m_frame_data.inv_area; // x = sx * sy * inv_area (area ratio)
// lqi.xyzw vf07, vi03 | miniy.w vf10, vf10, vf12
// vf07 is fifth user adgif
offset_pos_vf10.w() = std::min(offset_pos_vf10.w(), m_frame_data.fog_min);
// lq.xyzw vf08, 999(vi00) | miniz.zw vf01, vf01, vf12
// vf08 is 2d giftag 1 (NOTE THIS IS DIFFERENT FROM 2d 1)!!!!!
scales_vf01.z() = std::min(scales_vf01.z(), fog_consts_vf12.z());
scales_vf01.w() = std::min(scales_vf01.w(), fog_consts_vf12.z());
bool use_first_giftag = offset_selector == 0;
// ilw.x vi07, -2(vi02) | madd.xyzw vf05, vf16, vf14
auto flag_vi07 = m_vec_data_2d[sprite_idx].flag();
Vector4f vf05_sincos(0, 0, std::sin(flags_vf05.z()), std::cos(flags_vf05.z()));
// lqi.xyzw vf23, vi02 | miniw.x vf01, vf01, vf00
// pipeline
scales_vf01.x() = std::min(scales_vf01.x(), 1.f);
// nop | suby.w vf02, vf10, vf12 (unique)
transformed_pos_vf02.w() = offset_pos_vf10.w() - fog_consts_vf12.y();
// lqi.xyzw vf24, vi02 | mulx.w vf11, vf11, vf01
// pipeline
color_vf11.w() *= scales_vf01.x(); // is this right? doesn't this stall??
// fcand vi01, 0x3f | mulaw.xyzw ACC, vf28, vf00
// already computed pipeline
// lq.xyzw vf17, 1006(vi00) | maddax.xyzw ACC, vf25, vf23 (pipeline)
Vector4f basis_x_vf17 = m_frame_data.basis_x;
// fmand vi09, vi06 | nop
// ibne vi00, vi09, L6 | nop
if (transformed_pos_vf02.w() != 0) {
if (m_extra_debug) {
ImGui::TextColored(ImVec4(0.8, 0.2, 0.2, 1.0), "fmand (2) trick");
}
use_first_giftag = false;
}
// lq.xyzw vf18, 1007(vi00) | madday.xyzw ACC, vf26, vf23 (pipeline)
Vector4f basis_y_vf18 = m_frame_data.basis_y;
// assert(flag_vi07 == 0);
Vector4f* xy_array = m_frame_data.xy_array + flag_vi07;
// lq.xyzw vf19, 980(vi07) | ftoi0.xyzw vf11, vf11
Vector4f xy0_vf19 = xy_array[0];
math::Vector<s32, 4> color_integer_vf11 = color_vf11.cast<s32>();
// lq.xyzw vf20, 981(vi07) | maddz.xyzw vf02, vf27, vf23 (pipeline)
Vector4f xy1_vf20 = xy_array[1];
// lq.xyzw vf21, 982(vi07) | mulaw.xyzw ACC, vf17, vf05
Vector4f xy2_vf21 = xy_array[2];
Vector4f acc = basis_x_vf17 * vf05_sincos.w();
// lq.xyzw vf22, 983(vi07) | msubz.xyzw vf12, vf18, vf05
Vector4f xy3_vf22 = xy_array[3];
Vector4f vf12_rotated = acc - (basis_y_vf18 * vf05_sincos.z());
// sq.xyzw vf11, 3(vi05) | mulaz.xyzw ACC, vf17, vf05
// EIGHTH is color integer
packet.color = color_integer_vf11;
acc = basis_x_vf17 * vf05_sincos.z();
// lqi.xyzw vf11, vi02 | maddw.xyzw vf13, vf18, vf05
// (pipeline)
Vector4f vf13_rotated_trans = acc + basis_y_vf18 * vf05_sincos.w();
// move.w vf24, vf00 | addw.z vf23, vf00, vf24 (pipeline both)
// div Q, vf31.x, vf02.w | mulw.xyzw vf12, vf12, vf01
// (pipeline)
vf12_rotated *= scales_vf01.w();
// ibne vi00, vi01, L9 | muly.z vf24, vf24, vf31 (pipeline)
if (fcand_result) {
if (m_extra_debug) {
ImGui::TextColored(ImVec4(0.8, 0.2, 0.2, 1.0), "fcand reject");
ImGui::Separator();
}
continue; // reject (could move earlier)
}
// ilw.y vi08, 1(vi02) | mulz.xyzw vf13, vf13, vf01
// (pipeline)
vf13_rotated_trans *= scales_vf01.z();
// LEFT OFF HERE!
// sqi.xyzw vf06, vi05 | mul.xyzw vf03, vf02, vf29
// FIFTH is fourth user
// sqi.xyzw vf07, vi05 | mulaw.xyzw ACC, vf10, vf00
// SIXTH is fifth user
acc = offset_pos_vf10;
// sqi.xyzw vf08, vi05 | maddax.xyzw ACC, vf12, vf19
// SEVENTH is giftag2
packet.sprite_giftag =
use_first_giftag ? m_frame_data.sprite_2d_giftag : m_frame_data.sprite_2d_giftag2;
acc += vf12_rotated * xy0_vf19.x();
// lq.xyzw vf06, 988(vi00) | maddy.xyzw vf19, vf13, vf19
Vector4f st0_vf06 = m_frame_data.st_array[0];
xy0_vf19 = acc + vf13_rotated_trans * xy0_vf19.y();
// lq.xyzw vf07, 989(vi00) | mulaw.xyzw ACC, vf10, vf00
Vector4f st1_vf07 = m_frame_data.st_array[1];
acc = offset_pos_vf10;
// lq.xyzw vf08, 990(vi00) | maddax.xyzw ACC, vf12, vf20
Vector4f st2_vf08 = m_frame_data.st_array[2];
acc += vf12_rotated * xy1_vf20.x();
// lq.xyzw vf09, 991(vi00) | maddy.xyzw vf20, vf13, vf20
Vector4f st3_vf09 = m_frame_data.st_array[3];
xy1_vf20 = acc + vf13_rotated_trans * xy1_vf20.y();
// sq.xyzw vf06, 1(vi05) | mulaw.xyzw ACC, vf10, vf00
// NINTH is st0
packet.st0 = st0_vf06;
acc = offset_pos_vf10;
// sq.xyzw vf07, 3(vi05) | maddax.xyzw ACC, vf12, vf21
// ELEVEN is st1
packet.st1 = st1_vf07;
acc += vf12_rotated * xy2_vf21.x();
// sq.xyzw vf08, 5(vi05) | maddy.xyzw vf21, vf13, vf21
// THIRTEEN is st2
packet.st2 = st2_vf08;
xy2_vf21 = acc + vf13_rotated_trans * xy2_vf21.y();
// sq.xyzw vf09, 7(vi05) | mulaw.xyzw ACC, vf10, vf00
// FIFTEEN is st3
packet.st3 = st3_vf09;
acc = offset_pos_vf10;
// nop | maddax.xyzw ACC, vf12, vf22
acc += vf12_rotated * xy3_vf22.x();
// nop | maddy.xyzw vf22, vf13, vf22
xy3_vf22 = acc + vf13_rotated_trans * xy3_vf22.y();
// lq.xyzw vf12, 1020(vi00) | ftoi4.xyzw vf19, vf19
// (pipeline)
auto xy0_vf19_int = (xy0_vf19 * 16.f).cast<s32>();
// lq.xyzw vf14, 1001(vi00) | ftoi4.xyzw vf20, vf20
// (pipeline)
auto xy1_vf20_int = (xy1_vf20 * 16.f).cast<s32>();
// move.xyzw vf05, vf24 | ftoi4.xyzw vf21, vf21
// (pipeline)
auto xy2_vf21_int = (xy2_vf21 * 16.f).cast<s32>();
// move.xyzw vf01, vf23 | ftoi4.xyzw vf22, vf22
// (pipeline)
auto xy3_vf22_int = (xy3_vf22 * 16.f).cast<s32>();
if (m_extra_debug) {
u32 zi = xy3_vf22_int.z() >> 4;
ImGui::Text("z (int): 0x%08x %s", zi, zi >= (1 << 24) ? "bad" : "");
ImGui::Text("z (flt): %f", (double)(((u32)zi) << 8) / UINT32_MAX);
}
// sq.xyzw vf19, 2(vi05) | mulz.z vf04, vf24, vf24 (pipeline)
// TENTH is xy0int
packet.xy0 = xy0_vf19_int;
// sq.xyzw vf20, 4(vi05) | clipw.xyz vf03, vf03 (pipeline)
// TWELVE is xy1int
packet.xy1 = xy1_vf20_int;
// sq.xyzw vf21, 6(vi05) | nop
// FOURTEEN is xy2int
packet.xy2 = xy2_vf21_int;
// sq.xyzw vf22, 8(vi05) | nop
// SIXTEEN is xy3int
packet.xy3 = xy3_vf22_int;
// m_sprite_renderer.render_gif((const u8*)&packet, sizeof(packet), render_state, prof);
if (m_extra_debug) {
imgui_vec(vf12_rotated, "vf12", 2);
imgui_vec(vf13_rotated_trans, "vf13", 2);
ImGui::Separator();
}
// xgkick vi15 | nop
// iaddi vi04, vi04, -0x1 | nop
// iaddiu vi01, vi00, 0x672 | nop
// ibne vi00, vi04, L8 | nop
// isub vi15, vi01, vi15 | adda.xyzw ACC, vf11, vf11
// nop | nop :e
// nop | nop
// L9:
// iaddi vi04, vi04, -0x1 | nop
// iaddi vi02, vi02, -0x3 | nop
// ibne vi00, vi04, L7 | nop
// nop | nop
// nop | nop :e
// nop | nop
// L10:
// iaddi vi04, vi04, -0x1 | nop
// iaddi vi03, vi03, 0x4 | nop
// ibne vi00, vi04, L7 | nop
// nop | nop
// nop | nop :e
// nop | nop
*/
hud:
/*
SpriteHud2DPacket packet;
memset(&packet, 0, sizeof(packet));
// L7 (prologue, and early abort)
// ilw.y vi08, 1(vi02) | nop vi08 = matrix
u32 offset_selector = m_vec_data_2d[sprite_idx].matrix();
// moved this out of the loop.
// lq.xyzw vf25, 900(vi00) | nop vf25 = cam_mat
// lq.xyzw vf26, 901(vi00) | nop
// lq.xyzw vf27, 902(vi00) | nop
// lq.xyzw vf28, 903(vi00) | nop
// lq.xyzw vf30, 904(vi08) | nop vf30 = hvdf_offset
// vf30
Vector4f hvdf_offset = offset_selector == 0 ? m_hud_matrix_data.hvdf_offset
: m_hud_matrix_data.user_hvdf[offset_selector - 1];
glUniform4f(
glGetUniformLocation(render_state->shaders[ShaderId::SPRITE].id(), "hvdf_offset"),
hvdf_offset[0], hvdf_offset[1], hvdf_offset[2], hvdf_offset[3]);
glUniform1f(
glGetUniformLocation(render_state->shaders[ShaderId::SPRITE].id(), "fog_constant"),
m_frame_data.pfog0);
// lqi.xyzw vf01, vi02 | nop
Vector4f pos_vf01 = m_vec_data_2d[sprite_idx].xyz_sx;
if (m_extra_debug) {
imgui_vec(pos_vf01, "POS", 2);
}
// lqi.xyzw vf05, vi02 | nop
Vector4f flags_vf05 = m_vec_data_2d[sprite_idx].flag_rot_sy;
// lqi.xyzw vf11, vi02 | nop
Vector4f color_vf11 = m_vec_data_2d[sprite_idx].rgba;
// multiplications from the right column
Vector4f transformed_pos_vf02 = matrix_transform(camera_matrix, pos_vf01);
Vector4f scales_vf01 = pos_vf01; // now used for something else.
// lq.xyzw vf12, 1020(vi00) | mulaw.xyzw ACC, vf28, vf00
// vf12 is fog consts
Vector4f fog_consts_vf12(m_frame_data.fog_min, m_frame_data.fog_max, m_frame_data.max_scale,
m_frame_data.bonus);
// ilw.y vi08, 1(vi02) | maddax.xyzw ACC, vf25, vf01
// load offset selector for the next round.
// nop | madday.xyzw ACC, vf26, vf01
// nop | maddz.xyzw vf02, vf27, vf01
// move.w vf05, vf00 | addw.z vf01, vf00, vf05
// scales_vf01.z = sy
scales_vf01.z() = flags_vf05.w(); // start building the scale vector
flags_vf05.w() = 1.f; // what are we building in flags right now??
// nop | nop
// div Q, vf31.x, vf02.w | muly.z vf05, vf05, vf31
float Q = m_frame_data.pfog0 / transformed_pos_vf02.w();
flags_vf05.z() *= m_frame_data.deg_to_rad;
// nop | mul.xyzw vf03, vf02, vf29
Vector4f scaled_pos_vf03 = transformed_pos_vf02.elementwise_multiply(m_frame_data.hmge_scale);
// nop | nop
// nop | nop
// nop | mulz.z vf04, vf05, vf05 (ts)
// fmt::print("rot is {} degrees\n", flags_vf05.z() * 360.0 / (2.0 * M_PI));
// the load is for rotation stuff,
// lq.xyzw vf14, 1001(vi00) | clipw.xyz vf03, vf03 (used for fcand)
// iaddi vi06, vi00, 0x1 | adda.xyzw ACC, vf11, vf11 (used for fmand)
// upcoming fcand with 0x3f, that checks all of them.
bool fcand_result = clip_xyz_plus_minus(scaled_pos_vf03);
bool fmand_result = color_vf11.w() == 0; // (really w+w, but I don't think it matters?)
// L8:
// xgkick double buffer setup
// ior vi05, vi15, vi00 | mul.zw vf01, vf01, Q
scales_vf01.z() *= Q; // sy
scales_vf01.w() *= Q; // sx
// lq.xyzw vf06, 998(vi00) | mulz.xyzw vf15, vf05, vf04 (ts)
auto adgif_vf06 = m_frame_data.adgif_giftag;
// lq.xyzw vf14, 1002(vi00) ts| mula.xyzw ACC, vf05, vf14 (ts)
// fmand vi01, vi06 | mul.xyz vf02, vf02, Q
transformed_pos_vf02.x() *= Q;
transformed_pos_vf02.y() *= Q;
transformed_pos_vf02.z() *= Q;
// if (m_extra_debug) {
// imgui_vec(transformed_pos_vf02, "scaled xf");
// }
// ibne vi00, vi01, L10 | addz.x vf01, vf00, vf01
scales_vf01.x() = scales_vf01.z(); // = sy
if (fmand_result) {
if (m_extra_debug) {
ImGui::TextColored(ImVec4(0.8, 0.2, 0.2, 1.0), "fmand reject");
ImGui::Separator();
}
continue; // reject!
}
// lqi.xyzw vf07, vi03 | mulz.xyzw vf16, vf15, vf04 (ts)
// vf07 is first use adgif
// lq.xyzw vf14, 1003(vi00) | madda.xyzw ACC, vf15, vf14 (ts both)
// lqi.xyzw vf08, vi03 | add.xyzw vf10, vf02, vf30
// vf08 is second user adgif
Vector4f offset_pos_vf10 = transformed_pos_vf02 + hvdf_offset;
// if (m_extra_debug) {
// ImGui::Text("sel %d", offset_selector);
// //ImGui::Text("hvdf off z: %f tf/w z: %f", hvdf_offset.z(), transformed_pos_vf02.z());
// imgui_vec(hvdf_offset, "hvdf");
// imgui_vec(transformed_pos_vf02, "tf'd");
// }
// lqi.xyzw vf09, vi03 | mulw.x vf01, vf01, vf01
// vf09 is third user adgif
scales_vf01.x() *= scales_vf01.w(); // x = sx * sy
// sqi.xyzw vf06, vi05 | mulz.xyzw vf15, vf16, vf04 (ts)
// FIRST ADGIF IS adgif_vf06
packet.adgif_giftag = adgif_vf06;
// lq.xyzw vf14, 1004(vi00) | madda.xyzw ACC, vf16, vf14 (ts both)
// sqi.xyzw vf07, vi05 | maxx.w vf10, vf10, vf12
// SECOND ADGIF is first user
// just do all 5 now.
packet.user_adgif = m_adgif[sprite_idx];
offset_pos_vf10.w() = std::max(offset_pos_vf10.w(), m_frame_data.fog_max);
// sqi.xyzw vf08, vi05 | maxz.zw vf01, vf01, vf31
// THIRD ADGIF is second user
scales_vf01.z() = std::max(scales_vf01.z(), m_frame_data.min_scale);
scales_vf01.w() = std::max(scales_vf01.w(), m_frame_data.min_scale);
// sqi.xyzw vf09, vi05 | mulz.xyzw vf16, vf15, vf04 (ts)
// FOURTH ADGIF is third user
// lq.xyzw vf14, 1005(vi00) | madda.xyzw ACC, vf15, vf14 (ts both)
// lqi.xyzw vf06, vi03 | mulw.x vf01, vf01, vf31
// vf06 is fourth user adgif
scales_vf01.x() *= m_frame_data.inv_area; // x = sx * sy * inv_area (area ratio)
// lqi.xyzw vf07, vi03 | miniy.w vf10, vf10, vf12
// vf07 is fifth user adgif
offset_pos_vf10.w() = std::min(offset_pos_vf10.w(), m_frame_data.fog_min);
// lq.xyzw vf08, 1000(vi00) | nop
// vf08 is 2d giftag 2
// ilw.x vi07, -2(vi02) | madd.xyzw vf05, vf16, vf14
auto flag_vi07 = m_vec_data_2d[sprite_idx].flag();
Vector4f vf05_sincos(0, 0, std::sin(flags_vf05.z()), std::cos(flags_vf05.z()));
// lq.xyzw vf30, 904(vi08) | nop
// pipline
// lqi.xyzw vf23, vi02 | miniw.x vf01, vf01, vf00
// pipeline
scales_vf01.x() = std::min(scales_vf01.x(), 1.f);
// lqi.xyzw vf24, vi02 | mulx.w vf11, vf11, vf01
// pipeline
color_vf11.w() *= scales_vf01.x(); // is this right? doesn't this stall??
// fcand vi01, 0x3f | mulaw.xyzw ACC, vf28, vf00
// already computed pipeline
// lq.xyzw vf17, 1006(vi00) | maddax.xyzw ACC, vf25, vf23 (pipeline)
Vector4f basis_x_vf17 = m_frame_data.basis_x;
// lq.xyzw vf18, 1007(vi00) | madday.xyzw ACC, vf26, vf23 (pipeline)
Vector4f basis_y_vf18 = m_frame_data.basis_y;
assert(flag_vi07 == 0);
Vector4f* xy_array = m_frame_data.xy_array + flag_vi07;
// lq.xyzw vf19, 980(vi07) | ftoi0.xyzw vf11, vf11
Vector4f xy0_vf19 = xy_array[0];
math::Vector<s32, 4> color_integer_vf11 = color_vf11.cast<s32>();
// lq.xyzw vf20, 981(vi07) | maddz.xyzw vf02, vf27, vf23 (pipeline)
Vector4f xy1_vf20 = xy_array[1];
// lq.xyzw vf21, 982(vi07) | mulaw.xyzw ACC, vf17, vf05
Vector4f xy2_vf21 = xy_array[2];
Vector4f acc = basis_x_vf17 * vf05_sincos.w();
// lq.xyzw vf22, 983(vi07) | msubz.xyzw vf12, vf18, vf05
Vector4f xy3_vf22 = xy_array[3];
Vector4f vf12_rotated = acc - (basis_y_vf18 * vf05_sincos.z());
// sq.xyzw vf11, 3(vi05) | mulaz.xyzw ACC, vf17, vf05
// EIGHTH is color integer
packet.color = color_integer_vf11;
acc = basis_x_vf17 * vf05_sincos.z();
// lqi.xyzw vf11, vi02 | maddw.xyzw vf13, vf18, vf05
// (pipeline)
Vector4f vf13_rotated_trans = acc + basis_y_vf18 * vf05_sincos.w();
// move.w vf24, vf00 | addw.z vf23, vf00, vf24 (pipeline both)
// div Q, vf31.x, vf02.w | mulw.xyzw vf12, vf12, vf01
// (pipeline)
vf12_rotated *= scales_vf01.w();
// ibne vi00, vi01, L9 | muly.z vf24, vf24, vf31 (pipeline)
if (fcand_result) {
if (m_extra_debug) {
ImGui::TextColored(ImVec4(0.8, 0.2, 0.2, 1.0), "fcand reject");
ImGui::Separator();
}
continue; // reject (could move earlier)
}
// ilw.y vi08, 1(vi02) | mulz.xyzw vf13, vf13, vf01
// (pipeline)
vf13_rotated_trans *= scales_vf01.z();
// LEFT OFF HERE!
// sqi.xyzw vf06, vi05 | mul.xyzw vf03, vf02, vf29
// FIFTH is fourth user
// sqi.xyzw vf07, vi05 | mulaw.xyzw ACC, vf10, vf00
// SIXTH is fifth user
acc = offset_pos_vf10;
// sqi.xyzw vf08, vi05 | maddax.xyzw ACC, vf12, vf19
// SEVENTH is giftag2
packet.sprite_giftag = m_frame_data.sprite_2d_giftag2;
acc += vf12_rotated * xy0_vf19.x();
// lq.xyzw vf06, 988(vi00) | maddy.xyzw vf19, vf13, vf19
Vector4f st0_vf06 = m_frame_data.st_array[0];
xy0_vf19 = acc + vf13_rotated_trans * xy0_vf19.y();
// lq.xyzw vf07, 989(vi00) | mulaw.xyzw ACC, vf10, vf00
Vector4f st1_vf07 = m_frame_data.st_array[1];
acc = offset_pos_vf10;
// lq.xyzw vf08, 990(vi00) | maddax.xyzw ACC, vf12, vf20
Vector4f st2_vf08 = m_frame_data.st_array[2];
acc += vf12_rotated * xy1_vf20.x();
// lq.xyzw vf09, 991(vi00) | maddy.xyzw vf20, vf13, vf20
Vector4f st3_vf09 = m_frame_data.st_array[3];
xy1_vf20 = acc + vf13_rotated_trans * xy1_vf20.y();
// sq.xyzw vf06, 1(vi05) | mulaw.xyzw ACC, vf10, vf00
// NINTH is st0
packet.st0 = st0_vf06;
acc = offset_pos_vf10;
// sq.xyzw vf07, 3(vi05) | maddax.xyzw ACC, vf12, vf21
// ELEVEN is st1
packet.st1 = st1_vf07;
acc += vf12_rotated * xy2_vf21.x();
// sq.xyzw vf08, 5(vi05) | maddy.xyzw vf21, vf13, vf21
// THIRTEEN is st2
packet.st2 = st2_vf08;
xy2_vf21 = acc + vf13_rotated_trans * xy2_vf21.y();
// sq.xyzw vf09, 7(vi05) | mulaw.xyzw ACC, vf10, vf00
// FIFTEEN is st3
packet.st3 = st3_vf09;
acc = offset_pos_vf10;
// nop | maddax.xyzw ACC, vf12, vf22
acc += vf12_rotated * xy3_vf22.x();
// nop | maddy.xyzw vf22, vf13, vf22
xy3_vf22 = acc + vf13_rotated_trans * xy3_vf22.y();
// lq.xyzw vf12, 1020(vi00) | ftoi4.xyzw vf19, vf19
// (pipeline)
auto xy0_vf19_int = (xy0_vf19 * 16.f).cast<s32>();
// lq.xyzw vf14, 1001(vi00) | ftoi4.xyzw vf20, vf20
// (pipeline)
auto xy1_vf20_int = (xy1_vf20 * 16.f).cast<s32>();
// move.xyzw vf05, vf24 | ftoi4.xyzw vf21, vf21
// (pipeline)
auto xy2_vf21_int = (xy2_vf21 * 16.f).cast<s32>();
// move.xyzw vf01, vf23 | ftoi4.xyzw vf22, vf22
// (pipeline)
auto xy3_vf22_int = (xy3_vf22 * 16.f).cast<s32>();
if (m_extra_debug) {
u32 zi = xy3_vf22_int.z() >> 4;
ImGui::Text("z (int): 0x%08x %s", zi, zi >= (1 << 24) ? "bad" : "");
ImGui::Text("z (flt): %f", (double)(((u32)zi) << 8) / UINT32_MAX);
}
// sq.xyzw vf19, 2(vi05) | mulz.z vf04, vf24, vf24 (pipeline)
// TENTH is xy0int
packet.xy0 = xy0_vf19_int;
// sq.xyzw vf20, 4(vi05) | clipw.xyz vf03, vf03 (pipeline)
// TWELVE is xy1int
packet.xy1 = xy1_vf20_int;
// sq.xyzw vf21, 6(vi05) | nop
// FOURTEEN is xy2int
packet.xy2 = xy2_vf21_int;
// sq.xyzw vf22, 8(vi05) | nop
// SIXTEEN is xy3int
packet.xy3 = xy3_vf22_int;
// m_sprite_renderer.render_gif((const u8*)&packet, sizeof(packet), render_state, prof);
if (m_extra_debug) {
imgui_vec(vf12_rotated, "vf12", 2);
imgui_vec(vf13_rotated_trans, "vf13", 2);
ImGui::Separator();
}
// xgkick vi15 | nop
// iaddi vi04, vi04, -0x1 | nop
// iaddiu vi01, vi00, 0x672 | nop
// ibne vi00, vi04, L8 | nop
// isub vi15, vi01, vi15 | adda.xyzw ACC, vf11, vf11
// nop | nop :e
// nop | nop
// L9:
// iaddi vi04, vi04, -0x1 | nop
// iaddi vi02, vi02, -0x3 | nop
// ibne vi00, vi04, L7 | nop
// nop | nop
// nop | nop :e
// nop | nop
// L10:
// iaddi vi04, vi04, -0x1 | nop
// iaddi vi03, vi03, 0x4 | nop
// ibne vi00, vi04, L7 | nop
// nop | nop
// nop | nop :e
// nop | nop
*/