Files
jak-project/game/graphics/opengl_renderer/ocean/OceanMid.cpp
T
water111 ef0f7635d3 [graphics] Ocean Mid (in progress) (#1232)
* first pass at ocean mid

* fix some bugs

* fix seams

* cleanup

* temp

* fix mipmap
2022-03-14 19:47:29 -04:00

146 lines
4.6 KiB
C++

#include "OceanMid.h"
static bool is_end_tag(const DmaTag& tag, const VifCode& v0, const VifCode& v1) {
return tag.qwc == 2 && tag.kind == DmaTag::Kind::CNT && v0.kind == VifCode::Kind::NOP &&
v1.kind == VifCode::Kind::DIRECT;
}
OceanMid::OceanMid() {
for (auto& x : m_vu_data) {
x.fill(999.);
}
vu.vf25 = Vf(1, 1, 1, 1);
}
void OceanMid::run(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& prof,
DirectRenderer& direct) {
// first is setting base and offset
{
auto base_offset_tag = dma.read_and_advance();
ASSERT(base_offset_tag.size_bytes == 0);
auto base = base_offset_tag.vifcode0();
ASSERT(base.kind == VifCode::Kind::BASE);
ASSERT(base.immediate == VU1_INPUT_BUFFER_BASE);
auto offset = base_offset_tag.vifcode1();
ASSERT(offset.kind == VifCode::Kind::OFFSET);
ASSERT(offset.immediate == VU1_INPUT_BUFFER_OFFSET);
}
// next is constants
{
auto constants = dma.read_and_advance();
ASSERT(constants.size_bytes == sizeof(Constants));
ASSERT(constants.vifcode0().kind == VifCode::Kind::STCYCL); // for whatever reason they do this
auto unpack = constants.vifcode1();
ASSERT(VifCodeUnpack(unpack).addr_qw == Vu1Data::CONSTANTS);
memcpy(&m_constants, constants.data, sizeof(Constants));
memcpy(m_vu_data + Vu1Data::CONSTANTS, &m_constants, sizeof(Constants));
}
// next is call 0
{
auto call0 = dma.read_and_advance();
ASSERT(call0.vifcode0().kind == VifCode::Kind::STCYCL);
auto c = call0.vifcode1();
ASSERT(c.kind == VifCode::Kind::MSCALF);
ASSERT(c.immediate == 0);
run_call0();
}
while (!is_end_tag(dma.current_tag(), dma.current_tag_vif0(), dma.current_tag_vif1())) {
auto data = dma.read_and_advance();
auto v0 = data.vifcode0();
auto v1 = data.vifcode1();
if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x404 &&
v1.kind == VifCode::Kind::UNPACK_V4_32) {
auto up = VifCodeUnpack(v1);
// ASSERT(up.use_tops_flag);
u16 addr = up.addr_qw + (up.use_tops_flag ? get_upload_buffer() : 0);
ASSERT(addr + v1.num <= 1024);
memcpy(m_vu_data + addr, data.data, 16 * v1.num);
ASSERT(16 * v1.num == data.size_bytes);
} else if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x404 &&
v1.kind == VifCode::Kind::UNPACK_V4_8) {
auto up = VifCodeUnpack(v1);
ASSERT(up.use_tops_flag);
ASSERT(up.is_unsigned);
u16 addr = up.addr_qw + get_upload_buffer();
ASSERT(addr + v1.num <= 1024);
u32 temp[4];
for (u32 i = 0; i < v1.num; i++) {
for (u32 j = 0; j < 4; j++) {
temp[j] = data.data[4 * i + j];
}
memcpy(m_vu_data + addr + i, temp, 16);
}
ASSERT(4 * v1.num == data.size_bytes);
} else if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x204 &&
v1.kind == VifCode::Kind::UNPACK_V4_8) {
auto up = VifCodeUnpack(v1);
ASSERT(up.use_tops_flag);
ASSERT(up.is_unsigned);
u16 addr = up.addr_qw + get_upload_buffer();
ASSERT(addr + v1.num <= 1024);
u32 temp[4];
for (u32 i = 0; i < v1.num; i++) {
for (u32 j = 0; j < 4; j++) {
temp[j] = data.data[4 * i + j];
}
// cl = 4
// wl = 2
u32 addr_off = 4 * (i / 2) + i % 2;
memcpy(m_vu_data + addr + addr_off, temp, 16);
}
ASSERT(8 * v1.num == data.size_bytes);
// TODO
} else if (v0.kind == VifCode::Kind::STCYCL && v0.immediate == 0x404 &&
v1.kind == VifCode::Kind::MSCALF) {
switch (v1.immediate) {
case 46:
run_call46_vu2c(render_state, prof, direct);
break;
case 73:
run_call73_vu2c(render_state, prof, direct);
break;
case 107:
run_call107_vu2c(render_state, prof, direct);
break;
case 275:
run_call275_vu2c(render_state, prof, direct);
break;
default:
fmt::print("unknown call1: {}\n", v1.immediate);
}
// TODO
} else if (v0.kind == VifCode::Kind::MSCALF && v1.kind == VifCode::Kind::FLUSHA) {
switch (v0.immediate) {
case 41:
run_call41_vu2c();
break;
case 43:
run_call43_vu2c();
break;
default:
fmt::print("unknown call2: {}\n", v0.immediate);
ASSERT(false);
}
// TODO
}
else {
fmt::print("{} {}\n", data.vifcode0().print(), data.vifcode1().print());
ASSERT(false);
}
}
}
void OceanMid::run_call0() {
run_call0_vu2c();
}