mirror of
https://github.com/open-goal/jak-project
synced 2026-09-09 12:14:10 -04:00
[graphics] generic merc (#1192)
* begin generic merc * more generic stuff * generic dma generation not crashing, at least until high-speed-reject * c * unpacker for generic * starting to work * small fixes * more fixes * more progress * cleanup * fix tests * no custom imgui assert on windows
This commit is contained in:
+10
-3
@@ -26,10 +26,10 @@ std::string VifCode::print() {
|
||||
result = fmt::format("STCYCL cl: {} wl: {}", stcycl.cl, stcycl.wl);
|
||||
} break;
|
||||
case Kind::OFFSET:
|
||||
result = "OFFSET";
|
||||
result = fmt::format("OFFSET 0x{:x}", immediate);
|
||||
break;
|
||||
case Kind::BASE:
|
||||
result = "BASE";
|
||||
result = fmt::format("BASE 0x{:x}", immediate);
|
||||
break;
|
||||
case Kind::ITOP:
|
||||
result = "ITOP";
|
||||
@@ -59,7 +59,7 @@ std::string VifCode::print() {
|
||||
result = "MSCNT";
|
||||
break;
|
||||
case Kind::MSCALF:
|
||||
result = "MSCALF";
|
||||
result = fmt::format("MSCALF 0x{:x}", immediate);
|
||||
break;
|
||||
case Kind::STMASK:
|
||||
result = "STMASK";
|
||||
@@ -107,6 +107,13 @@ std::string VifCode::print() {
|
||||
break;
|
||||
}
|
||||
|
||||
case Kind::UNPACK_V2_16: {
|
||||
VifCodeUnpack up(*this);
|
||||
result = fmt::format("UNPACK-V2-16: {} addr: {} us: {} tops: {}", num, up.addr_qw,
|
||||
up.is_unsigned, up.use_tops_flag);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fmt::print("Unhandled vif code {}\n", (int)kind);
|
||||
|
||||
|
||||
@@ -87,6 +87,9 @@ inline void emulate_dma(const void* source_base, void* dest_base, u32 tadr, u32
|
||||
tadr += 16;
|
||||
return;
|
||||
} break;
|
||||
case DmaTag::Kind::END:
|
||||
// does this transfer anything in TTE???
|
||||
return;
|
||||
default:
|
||||
printf("bad tag: %d\n", (int)tag.kind);
|
||||
ASSERT(false);
|
||||
@@ -122,6 +125,7 @@ struct VifCode {
|
||||
UNPACK_V4_16 = 0b1101101,
|
||||
UNPACK_V3_32 = 0b1101000,
|
||||
UNPACK_V4_8 = 0b1101110,
|
||||
UNPACK_V2_16 = 0b1100101,
|
||||
};
|
||||
|
||||
VifCode(u32 value) {
|
||||
|
||||
@@ -25,6 +25,7 @@ GameTextFontBank::GameTextFontBank(GameTextVersion version,
|
||||
std::sort(
|
||||
m_replace_info->begin(), m_replace_info->end(),
|
||||
[](const ReplaceInfo& a, const ReplaceInfo& b) { return a.from.size() > b.from.size(); });
|
||||
(void)m_version;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -1225,8 +1225,8 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
as_generic->op().func()->try_as_single_element());
|
||||
if (as_func_head && as_func_head->expr().is_identity() &&
|
||||
as_func_head->expr().get_arg(0).is_sym_val()) {
|
||||
auto& name = as_func_head->expr().get_arg(0).get_str();
|
||||
if (name == "rand-vu-int-range") {
|
||||
auto& func_name = as_func_head->expr().get_arg(0).get_str();
|
||||
if (func_name == "rand-vu-int-range") {
|
||||
arg1_cast = TypeSpec("time-frame");
|
||||
}
|
||||
}
|
||||
@@ -1277,7 +1277,7 @@ void SimpleExpressionElement::update_from_stack_force_si_2(const Env& env,
|
||||
if (arg1_reg) {
|
||||
auto arg1_type =
|
||||
env.get_types_before_op(m_my_idx).get(m_expr.get_arg(1).var().reg()).typespec();
|
||||
bool is_timeframe = arg1_type == TypeSpec("time-frame");
|
||||
// bool is_timeframe = arg1_type == TypeSpec("time-frame");
|
||||
arg1_i = is_int_type(arg1_type);
|
||||
} else {
|
||||
ASSERT(m_expr.get_arg(1).is_int());
|
||||
|
||||
@@ -592,10 +592,35 @@ std::string mask_to_string(u8 val) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string vf_src(const std::string& name, bool mips2c_format) {
|
||||
if (mips2c_format) {
|
||||
return fmt::format("c->vf_src({}).vf", name);
|
||||
} else {
|
||||
return fmt::format("vu.{}", name);
|
||||
}
|
||||
}
|
||||
|
||||
std::string vf_dst(const std::string& name, bool mips2c_format) {
|
||||
if (mips2c_format) {
|
||||
return fmt::format("c->vfs[{}].vf", name);
|
||||
} else {
|
||||
return fmt::format("vu.{}", name);
|
||||
}
|
||||
}
|
||||
|
||||
std::string vi_src(const std::string& name, bool mips2c_format) {
|
||||
if (mips2c_format) {
|
||||
return fmt::format("vis[{}]", name);
|
||||
} else {
|
||||
return fmt::format("vu.{}", name);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int unk = 0;
|
||||
std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
std::string VuDisassembler::to_cpp(const VuInstruction& instr, bool mips2c_format) const {
|
||||
switch (instr.kind) {
|
||||
case VuInstrK::NOP:
|
||||
case VuInstrK::LOWER_NOP:
|
||||
@@ -606,36 +631,50 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
} else if (instr.src.at(0).value() == 0) {
|
||||
return fmt::format("lq_buffer(Mask::{}, vu.{}, vu.{});", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
return fmt::format(mips2c_format ? "lq_buffer(Mask::{}, c->vfs[{}].vf, vis[{}]);"
|
||||
: "lq_buffer(Mask::{}, vu.{}, vu.{});",
|
||||
mask_to_string(*instr.mask), instr.dst->to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
} else {
|
||||
return fmt::format("lq_buffer(Mask::{}, vu.{}, vu.{} + {});", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
return fmt::format(mips2c_format ? "lq_buffer(Mask::{}, c->vfs[{}].vf, vis[{}] + {});"
|
||||
: "lq_buffer(Mask::{}, vu.{}, vu.{} + {});",
|
||||
mask_to_string(*instr.mask), instr.dst->to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
}
|
||||
goto unknown;
|
||||
case VuInstrK::LQI:
|
||||
return fmt::format("lq_buffer(Mask::{}, vu.{}, vu.{}++);", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
ASSERT(!instr.src.at(0).is_int_reg(0));
|
||||
return fmt::format(mips2c_format ? "lq_buffer(Mask::{}, c->vfs[{}].vf, vis[{}]++);"
|
||||
: "lq_buffer(Mask::{}, vu.{}, vu.{}++);",
|
||||
mask_to_string(*instr.mask), instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
case VuInstrK::SQI:
|
||||
return fmt::format("sq_buffer(Mask::{}, vu.{}, vu.{}++);", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
ASSERT(!instr.src.at(0).is_int_reg(0));
|
||||
if (mips2c_format) {
|
||||
return fmt::format("sq_buffer(Mask::{}, {}, vis[{}]++);", mask_to_string(*instr.mask),
|
||||
vf_src(instr.dst->to_string(m_label_names), mips2c_format),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
} else {
|
||||
return fmt::format("sq_buffer(Mask::{}, vu.{}, vu.{}++);", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
}
|
||||
|
||||
case VuInstrK::SQ:
|
||||
if (instr.src.at(1).is_int_reg(0)) {
|
||||
return fmt::format("sq_buffer(Mask::{}, vu.{}, {});", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
} else if (instr.src.at(0).value() == 0) {
|
||||
return fmt::format("sq_buffer(Mask::{}, vu.{}, vu.{});", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
return fmt::format(mips2c_format ? "sq_buffer(Mask::{}, c->vf_src({}).vf, vis[{}]);"
|
||||
: "sq_buffer(Mask::{}, vu.{}, vu.{});",
|
||||
mask_to_string(*instr.mask), instr.dst->to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
} else {
|
||||
return fmt::format("sq_buffer(Mask::{}, vu.{}, vu.{} + {});", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
return fmt::format(mips2c_format ? "sq_buffer(Mask::{}, c->vf_src({}).vf, vis[{}] + {});"
|
||||
: "sq_buffer(Mask::{}, vu.{}, vu.{} + {});",
|
||||
mask_to_string(*instr.mask), instr.dst->to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
}
|
||||
@@ -650,13 +689,28 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
}
|
||||
|
||||
case VuInstrK::IADDIU:
|
||||
ASSERT(!instr.dst->is_int_reg(0));
|
||||
if (instr.src.at(0).is_int_reg(0)) {
|
||||
return fmt::format("vu.{} = 0x{:x}; /* {} */\n", instr.dst->to_string(m_label_names),
|
||||
(u16)instr.src.at(1).value(), instr.src.at(1).value());
|
||||
if (mips2c_format) {
|
||||
return fmt::format("vis[{}] = 0x{:x}; /* {} */", instr.dst->to_string(m_label_names),
|
||||
(u16)instr.src.at(1).value(), instr.src.at(1).value());
|
||||
} else {
|
||||
return fmt::format("vu.{} = 0x{:x}; /* {} */", instr.dst->to_string(m_label_names),
|
||||
(u16)instr.src.at(1).value(), instr.src.at(1).value());
|
||||
}
|
||||
|
||||
} else {
|
||||
return fmt::format("vu.{} = vu.{} + 0x{:x}; /* {} */", instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names), (u16)instr.src.at(1).value(),
|
||||
instr.src.at(1).value());
|
||||
if (mips2c_format) {
|
||||
return fmt::format("vis[{}] = vis[{}] + 0x{:x}; /* {} */",
|
||||
instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names), (u16)instr.src.at(1).value(),
|
||||
instr.src.at(1).value());
|
||||
} else {
|
||||
return fmt::format("vu.{} = vu.{} + 0x{:x}; /* {} */",
|
||||
instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names), (u16)instr.src.at(1).value(),
|
||||
instr.src.at(1).value());
|
||||
}
|
||||
}
|
||||
|
||||
case VuInstrK::ISW:
|
||||
@@ -696,7 +750,7 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
|
||||
case VuInstrK::ISUBIU:
|
||||
if (instr.src.at(0).is_int_reg(0)) {
|
||||
return fmt::format("vu.{} = -{};\n", instr.dst->to_string(m_label_names),
|
||||
return fmt::format("vu.{} = -{};", instr.dst->to_string(m_label_names),
|
||||
instr.src.at(1).value());
|
||||
} else {
|
||||
return fmt::format("vu.{} = vu.{} - 0x{:x}; /* {} */", instr.dst->to_string(m_label_names),
|
||||
@@ -705,9 +759,10 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
}
|
||||
|
||||
case VuInstrK::MTIR:
|
||||
return fmt::format("vu.{} = vu.{}.{}_as_u16();", instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
bc_to_part(*instr.first_src_field));
|
||||
return fmt::format(
|
||||
mips2c_format ? "vis[{}] = c->vf_src({}).vf.{}_as_u16();" : "vu.{} = vu.{}.{}_as_u16();",
|
||||
instr.dst->to_string(m_label_names), instr.src.at(0).to_string(m_label_names),
|
||||
bc_to_part(*instr.first_src_field));
|
||||
|
||||
case VuInstrK::MFIR:
|
||||
return fmt::format("vu.{}.mfir(Mask::{}, vu.{});", instr.dst->to_string(m_label_names),
|
||||
@@ -718,28 +773,41 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
|
||||
case VuInstrK::IBGTZ:
|
||||
return fmt::format("bc = ((s16)vu.{}) > 0;", instr.src.at(0).to_string(m_label_names));
|
||||
|
||||
case VuInstrK::IBLTZ:
|
||||
return fmt::format("bc = ((s16)vu.{}) < 0;", instr.src.at(0).to_string(m_label_names));
|
||||
case VuInstrK::IBLEZ:
|
||||
return fmt::format("bc = ((s16)vu.{}) <= 0;", instr.src.at(0).to_string(m_label_names));
|
||||
case VuInstrK::IBGEZ:
|
||||
return fmt::format("bc = ((s16)vu.{}) >= 0;", instr.src.at(0).to_string(m_label_names));
|
||||
|
||||
case VuInstrK::IBEQ:
|
||||
ASSERT(!instr.src.at(1).is_int_reg(0));
|
||||
if (instr.src.at(0).is_int_reg(0)) {
|
||||
return fmt::format("bc = (vu.{} == 0);", instr.src.at(1).to_string(m_label_names));
|
||||
return fmt::format("bc = ({} == 0);",
|
||||
vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format));
|
||||
} else {
|
||||
return fmt::format("bc = (vu.{} == vu.{});", instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
return fmt::format("bc = ({} == {});",
|
||||
vi_src(instr.src.at(0).to_string(m_label_names), mips2c_format),
|
||||
vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format));
|
||||
}
|
||||
|
||||
case VuInstrK::IBNE:
|
||||
ASSERT(!instr.src.at(1).is_int_reg(0));
|
||||
if (instr.src.at(0).is_int_reg(0)) {
|
||||
return fmt::format("bc = (vu.{} != 0);", instr.src.at(1).to_string(m_label_names));
|
||||
return fmt::format("bc = ({} != 0);",
|
||||
vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format));
|
||||
} else {
|
||||
return fmt::format("bc = (vu.{} != vu.{});", instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
return fmt::format("bc = ({} != {});",
|
||||
vi_src(instr.src.at(0).to_string(m_label_names), mips2c_format),
|
||||
vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format));
|
||||
}
|
||||
|
||||
case VuInstrK::IADD:
|
||||
return fmt::format("vu.{} = vu.{} + vu.{};", instr.dst->to_string(m_label_names),
|
||||
ASSERT(!instr.src.at(1).is_int_reg(0));
|
||||
ASSERT(!instr.src.at(0).is_int_reg(0));
|
||||
ASSERT(!instr.dst->is_int_reg(0));
|
||||
return fmt::format(mips2c_format ? "vis[{}] = vis[{}] + vis[{}];" : "vu.{} = vu.{} + vu.{};",
|
||||
instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
case VuInstrK::ISUB:
|
||||
@@ -747,13 +815,25 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
case VuInstrK::IAND:
|
||||
return fmt::format("vu.{} = vu.{} & vu.{};", instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
ASSERT(!instr.src.at(1).is_int_reg(0));
|
||||
ASSERT(!instr.src.at(0).is_int_reg(0));
|
||||
ASSERT(!instr.dst->is_int_reg(0));
|
||||
return fmt::format("{} = {} & {};",
|
||||
vi_src(instr.dst->to_string(m_label_names), mips2c_format),
|
||||
vi_src(instr.src.at(0).to_string(m_label_names), mips2c_format),
|
||||
vi_src(instr.src.at(1).to_string(m_label_names), mips2c_format));
|
||||
case VuInstrK::IOR:
|
||||
if (instr.src.at(1).is_int_reg(0)) {
|
||||
return fmt::format("vu.{} = vu.{};", instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
ASSERT(!instr.dst->is_int_reg(0));
|
||||
ASSERT(!instr.src.at(0).is_int_reg(0));
|
||||
if (mips2c_format) {
|
||||
return fmt::format("vis[{}] = vis[{}];", instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
} else {
|
||||
return fmt::format("vu.{} = vu.{};", instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
}
|
||||
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
@@ -763,80 +843,133 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
mask_to_string(*instr.mask));
|
||||
|
||||
case VuInstrK::MULq:
|
||||
return fmt::format("vu.{}.mul(Mask::{}, vu.{}, vu.Q); /* TODO mulq */",
|
||||
return fmt::format(mips2c_format ? "c->vfs[{}].vf.mul(Mask::{}, c->vf_src({}).vf, c->Q);"
|
||||
: "vu.{}.mul(Mask::{}, vu.{}, vu.Q);",
|
||||
instr.dst->to_string(m_label_names), mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
case VuInstrK::MULi:
|
||||
return fmt::format(mips2c_format ? "c->vfs[{}].vf.mul(Mask::{}, c->vf_src({}).vf, c->I);"
|
||||
: "vu.{}.mul(Mask::{}, vu.{}, vu.I);",
|
||||
instr.dst->to_string(m_label_names), mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
case VuInstrK::DIV:
|
||||
return fmt::format(
|
||||
"vu.Q = vu.{}.{}() / vu.{}.{}();\n", instr.src.at(0).to_string(m_label_names),
|
||||
"vu.Q = vu.{}.{}() / vu.{}.{}();", instr.src.at(0).to_string(m_label_names),
|
||||
bc_to_part(*instr.first_src_field), instr.src.at(1).to_string(m_label_names),
|
||||
bc_to_part(*instr.second_src_field));
|
||||
|
||||
case VuInstrK::ERLENG:
|
||||
return fmt::format("vu.P = erleng(Mask::{}, vu.{}); /* TODO erleng */",
|
||||
mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names));
|
||||
case VuInstrK::RSQRT:
|
||||
return fmt::format(
|
||||
"c->Q = c->vf_src({}).vf.{}() / std::sqrt(c->vf_src({}).vf.{}());",
|
||||
instr.src.at(0).to_string(m_label_names), bc_to_part(*instr.first_src_field),
|
||||
instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.second_src_field));
|
||||
|
||||
case VuInstrK::MR32:
|
||||
case VuInstrK::MOVE:
|
||||
case VuInstrK::ITOF0:
|
||||
case VuInstrK::ITOF12:
|
||||
case VuInstrK::ITOF15:
|
||||
case VuInstrK::FTOI0:
|
||||
case VuInstrK::FTOI4:
|
||||
return fmt::format("vu.{}.{}(Mask::{}, vu.{});", instr.dst->to_string(m_label_names),
|
||||
case VuInstrK::FTOI12:
|
||||
return fmt::format("{}.{}(Mask::{}, {});",
|
||||
vf_dst(instr.dst->to_string(m_label_names), mips2c_format),
|
||||
info(instr.kind).name, mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format));
|
||||
|
||||
case VuInstrK::CLIP:
|
||||
return fmt::format("ASSERT(false); cf = clip({}, {}.w(), cf);",
|
||||
vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format),
|
||||
vf_src(instr.src.at(1).to_string(m_label_names), mips2c_format));
|
||||
case VuInstrK::FCAND:
|
||||
return fmt::format("ASSERT(false); vu.vi01 = cf & 0x{:x};\n", instr.src.at(0).value());
|
||||
|
||||
case VuInstrK::ADDbc:
|
||||
case VuInstrK::SUBbc:
|
||||
case VuInstrK::MULbc:
|
||||
case VuInstrK::MINIbc:
|
||||
case VuInstrK::MAXbc:
|
||||
return fmt::format("vu.{}.{}(Mask::{}, vu.{}, vu.{}.{}());",
|
||||
instr.dst->to_string(m_label_names), info(instr.kind).name,
|
||||
mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.bc));
|
||||
return fmt::format("{}.{}(Mask::{}, {}, {}.{}());",
|
||||
vf_dst(instr.dst->to_string(m_label_names), mips2c_format),
|
||||
info(instr.kind).name, mask_to_string(*instr.mask),
|
||||
vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format),
|
||||
vf_src(instr.src.at(1).to_string(m_label_names), mips2c_format),
|
||||
bc_to_part(*instr.bc));
|
||||
|
||||
case VuInstrK::FP_CONSTANT:
|
||||
return fmt::format("vu.I = {};", float_to_string(instr.fp));
|
||||
if (mips2c_format) {
|
||||
return fmt::format("c->I = {};", float_to_string(instr.fp));
|
||||
|
||||
} else {
|
||||
return fmt::format("vu.I = {};", float_to_string(instr.fp));
|
||||
}
|
||||
|
||||
case VuInstrK::MINIi:
|
||||
case VuInstrK::MAXi:
|
||||
return fmt::format("vu.{}.{}(Mask::{}, vu.{}, vu.I);", instr.dst->to_string(m_label_names),
|
||||
return fmt::format("{}.{}(Mask::{}, {}, {});",
|
||||
vf_dst(instr.dst->to_string(m_label_names), mips2c_format),
|
||||
info(instr.kind).name, mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names));
|
||||
vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format),
|
||||
mips2c_format ? "c->I" : "vu.I");
|
||||
case VuInstrK::SUB:
|
||||
if (instr.dst.value().value() == instr.src.at(0).value() &&
|
||||
instr.src.at(0).value() == instr.src.at(1).value() && instr.mask.value() == 0b1111) {
|
||||
return fmt::format("vu.{}.set_zero();", instr.src.at(0).to_string(m_label_names));
|
||||
} else {
|
||||
return fmt::format("{}.{}(Mask::{}, {}, {});",
|
||||
vf_dst(instr.dst->to_string(m_label_names), mips2c_format),
|
||||
info(instr.kind).name, mask_to_string(*instr.mask),
|
||||
vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format),
|
||||
vf_src(instr.src.at(1).to_string(m_label_names), mips2c_format));
|
||||
}
|
||||
break;
|
||||
|
||||
case VuInstrK::MUL:
|
||||
case VuInstrK::ADD:
|
||||
case VuInstrK::MAX:
|
||||
case VuInstrK::MINI:
|
||||
return fmt::format("vu.{}.{}(Mask::{}, vu.{}, vu.{});", instr.dst->to_string(m_label_names),
|
||||
return fmt::format("{}.{}(Mask::{}, {}, {});",
|
||||
vf_dst(instr.dst->to_string(m_label_names), mips2c_format),
|
||||
info(instr.kind).name, mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
vf_src(instr.src.at(0).to_string(m_label_names), mips2c_format),
|
||||
vf_src(instr.src.at(1).to_string(m_label_names), mips2c_format));
|
||||
|
||||
case VuInstrK::ADDAbc:
|
||||
return fmt::format("vu.acc.adda(Mask::{}, vu.{}, vu.{}.{}());", mask_to_string(*instr.mask),
|
||||
instr.dst->to_string(m_label_names),
|
||||
return fmt::format(mips2c_format
|
||||
? "c->acc.vf.adda(Mask::{}, c->vfs[{}].vf, c->vfs[{}].vf.{}());"
|
||||
: "vu.acc.adda(Mask::{}, vu.{}, vu.{}.{}());",
|
||||
mask_to_string(*instr.mask), instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names), bc_to_part(*instr.bc));
|
||||
case VuInstrK::MADDA:
|
||||
return fmt::format("vu.acc.madda(Mask::{}, vu.{}, vu.{});", mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
case VuInstrK::MADDAbc:
|
||||
return fmt::format("vu.acc.madda(Mask::{}, vu.{}, vu.{}.{}());", mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
return fmt::format(mips2c_format
|
||||
? "c->acc.vf.madda(Mask::{}, c->vfs[{}].vf, c->vfs[{}].vf.{}());"
|
||||
: "vu.acc.madda(Mask::{}, vu.{}, vu.{}.{}());",
|
||||
mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.bc));
|
||||
case VuInstrK::MADDbc:
|
||||
return fmt::format("vu.acc.madd(Mask::{}, vu.{}, vu.{}, vu.{}.{}());",
|
||||
mask_to_string(*instr.mask), instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.bc));
|
||||
return fmt::format(
|
||||
mips2c_format
|
||||
? "c->acc.vf.madd(Mask::{}, c->vfs[{}].vf, c->vf_src({}).vf, c->vf_src({}).vf.{}());"
|
||||
: "vu.acc.madd(Mask::{}, vu.{}, vu.{}, vu.{}.{}());",
|
||||
mask_to_string(*instr.mask), instr.dst->to_string(m_label_names),
|
||||
instr.src.at(0).to_string(m_label_names), instr.src.at(1).to_string(m_label_names),
|
||||
bc_to_part(*instr.bc));
|
||||
case VuInstrK::MULA:
|
||||
return fmt::format("vu.acc.mula(Mask::{}, vu.{}, vu.{});", mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names));
|
||||
case VuInstrK::MULAbc:
|
||||
return fmt::format("vu.acc.mula(Mask::{}, vu.{}, vu.{}.{}());", mask_to_string(*instr.mask),
|
||||
instr.src.at(0).to_string(m_label_names),
|
||||
return fmt::format(mips2c_format
|
||||
? "c->acc.vf.mula(Mask::{}, c->vf_src({}).vf, c->vf_src({}).vf.{}());"
|
||||
: "vu.acc.mula(Mask::{}, vu.{}, vu.{}.{}());",
|
||||
mask_to_string(*instr.mask), instr.src.at(0).to_string(m_label_names),
|
||||
instr.src.at(1).to_string(m_label_names), bc_to_part(*instr.bc));
|
||||
|
||||
case VuInstrK::XGKICK:
|
||||
@@ -846,7 +979,7 @@ std::string VuDisassembler::to_cpp(const VuInstruction& instr) const {
|
||||
return fmt::format("vu.{} = xtop();", instr.src.at(0).to_string(m_label_names));
|
||||
default:
|
||||
unk++;
|
||||
return "???";
|
||||
return "ASSERT(false);"; //"???";
|
||||
}
|
||||
|
||||
unknown:
|
||||
@@ -1049,7 +1182,7 @@ std::string get_label_name(const VuInstructionPair& pair,
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
std::string VuDisassembler::to_string_with_cpp(const VuProgram& prog) const {
|
||||
std::string VuDisassembler::to_string_with_cpp(const VuProgram& prog, bool mips2c_format) const {
|
||||
std::string result;
|
||||
for (int i = 0; i < (int)prog.instructions().size(); i++) {
|
||||
auto lab = m_labels.find(i);
|
||||
@@ -1059,20 +1192,36 @@ std::string VuDisassembler::to_string_with_cpp(const VuProgram& prog) const {
|
||||
result += '\n';
|
||||
}
|
||||
auto& pair = prog.instructions().at(i);
|
||||
if (has_branch_delay(pair)) {
|
||||
result += "// BRANCH!\n";
|
||||
if (has_branch_delay(pair) && pair.lower.kind != VuInstrK::JALR) {
|
||||
result += " // BRANCH!\n";
|
||||
// set bc
|
||||
result += to_string_with_cpp(prog.instructions().at(i));
|
||||
result += to_string_with_cpp(prog.instructions().at(i), mips2c_format, i);
|
||||
result += "\n";
|
||||
result += to_string_with_cpp(prog.instructions().at(i + 1));
|
||||
result += to_string_with_cpp(prog.instructions().at(i + 1), mips2c_format, i + 1);
|
||||
result += "\n";
|
||||
result += fmt::format("if (bc) {{ goto {}; }}\n", get_label_name(pair, m_label_names));
|
||||
result += fmt::format(" if (bc) {{ goto {}; }}", get_label_name(pair, m_label_names));
|
||||
result += "\n\n";
|
||||
i++;
|
||||
} else {
|
||||
result += to_string_with_cpp(prog.instructions().at(i));
|
||||
result += to_string_with_cpp(prog.instructions().at(i), mips2c_format, i);
|
||||
result += '\n';
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
const auto& prev = prog.instructions().at(i - 1);
|
||||
bool has_ebit = false;
|
||||
if (prev.lower.iemdt && (*prev.lower.iemdt & 0b100000)) {
|
||||
has_ebit = true;
|
||||
}
|
||||
|
||||
if (prev.upper.iemdt && (*prev.upper.iemdt & 0b100000)) {
|
||||
has_ebit = true;
|
||||
}
|
||||
|
||||
if (has_ebit) {
|
||||
result += "return;\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt::print("TOTAL unk: {}\n", unk);
|
||||
return result;
|
||||
@@ -1083,20 +1232,23 @@ bool is_nop(const VuInstruction& i) {
|
||||
return i.kind == VuInstrK::NOP || i.kind == VuInstrK::LOWER_NOP;
|
||||
}
|
||||
} // namespace
|
||||
std::string VuDisassembler::to_string_with_cpp(const VuInstructionPair& pair) const {
|
||||
std::string VuDisassembler::to_string_with_cpp(const VuInstructionPair& pair,
|
||||
bool mips2c_format,
|
||||
int idx) const {
|
||||
std::string result;
|
||||
result += fmt::format(" // {:25s} | {:30s}\n", to_string(pair.lower), to_string(pair.upper));
|
||||
result +=
|
||||
fmt::format(" // {:25s} | {:30s} {}\n", to_string(pair.lower), to_string(pair.upper), idx);
|
||||
|
||||
if (!is_nop(pair.lower) && !is_nop(pair.upper) && pair.lower.kind == VuInstrK::FP_CONSTANT) {
|
||||
result += fmt::format(" {:25s}", to_cpp(pair.upper));
|
||||
result += fmt::format(" {:25s}", to_cpp(pair.lower));
|
||||
result += fmt::format(" {:25s}", to_cpp(pair.upper, mips2c_format));
|
||||
result += fmt::format(" {:25s}", to_cpp(pair.lower, mips2c_format));
|
||||
} else {
|
||||
if (!is_nop(pair.upper)) {
|
||||
result += fmt::format(" {:25s}", to_cpp(pair.upper));
|
||||
result += fmt::format(" {:25s}", to_cpp(pair.upper, mips2c_format));
|
||||
}
|
||||
|
||||
if (!is_nop(pair.lower)) {
|
||||
result += fmt::format(" {:25s}", to_cpp(pair.lower));
|
||||
result += fmt::format(" {:25s}", to_cpp(pair.lower, mips2c_format));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,11 +57,11 @@ class VuDisassembler {
|
||||
VuDisassembler(VuKind kind);
|
||||
VuProgram disassemble(void* data, int size_bytes, bool debug_print = false);
|
||||
std::string to_string(const VuInstruction& instr) const;
|
||||
std::string to_cpp(const VuInstruction& instr) const;
|
||||
std::string to_cpp(const VuInstruction& instr, bool mips2c_format) const;
|
||||
std::string to_string(const VuInstructionPair& pair) const;
|
||||
std::string to_string_with_cpp(const VuInstructionPair& pair) const;
|
||||
std::string to_string_with_cpp(const VuInstructionPair& pair, bool mips2c_format, int idx) const;
|
||||
std::string to_string(const VuProgram& prog) const;
|
||||
std::string to_string_with_cpp(const VuProgram& prog) const;
|
||||
std::string to_string_with_cpp(const VuProgram& prog, bool mips2c_format) const;
|
||||
int add_label(int instr);
|
||||
void add_label_with_name(int instr, const std::string& name);
|
||||
|
||||
|
||||
@@ -740,6 +740,18 @@ Mips2C_Line handle_vmadda_bc(const Instruction& i0, const std::string& instr_str
|
||||
instr_str};
|
||||
}
|
||||
|
||||
Mips2C_Line handle_vmadda(const Instruction& i0, const std::string& instr_str) {
|
||||
return {fmt::format("c->vmadda(DEST::{}, {}, {});", dest_to_char(i0.cop2_dest),
|
||||
reg_to_name(i0.get_src(0)), reg_to_name(i0.get_src(1))),
|
||||
instr_str};
|
||||
}
|
||||
|
||||
Mips2C_Line handle_vadda_bc(const Instruction& i0, const std::string& instr_str) {
|
||||
return {fmt::format("c->vadda_bc(DEST::{}, BC::{}, {}, {});", dest_to_char(i0.cop2_dest),
|
||||
i0.cop2_bc_to_char(), reg_to_name(i0.get_src(0)), reg_to_name(i0.get_src(1))),
|
||||
instr_str};
|
||||
}
|
||||
|
||||
Mips2C_Line handle_vmsuba_bc(const Instruction& i0, const std::string& instr_str) {
|
||||
return {fmt::format("c->vmsuba_bc(DEST::{}, BC::{}, {}, {});", dest_to_char(i0.cop2_dest),
|
||||
i0.cop2_bc_to_char(), reg_to_name(i0.get_src(0)), reg_to_name(i0.get_src(1))),
|
||||
@@ -869,9 +881,16 @@ Mips2C_Line handle_vopmsub(const Instruction& i0, const std::string& instr_strin
|
||||
instr_string};
|
||||
}
|
||||
|
||||
Mips2C_Line handle_lui(const Instruction& i0, const std::string& instr_string) {
|
||||
return {fmt::format("c->lui({}, {});", reg_to_name(i0.get_dst(0)), i0.get_src(0).get_imm()),
|
||||
instr_string};
|
||||
Mips2C_Line handle_lui(const Instruction& i0, const std::string& instr_string, Mips2C_Output& op) {
|
||||
if (i0.get_src(0).get_imm() == 0x7000) {
|
||||
op.require_symbol("*fake-scratchpad-data*");
|
||||
return {fmt::format("get_fake_spad_addr({}, cache.fake_scratchpad_data, 0, c);",
|
||||
reg_to_name(i0.get_dst(0))),
|
||||
instr_string};
|
||||
} else {
|
||||
return {fmt::format("c->lui({}, {});", reg_to_name(i0.get_dst(0)), i0.get_src(0).get_imm()),
|
||||
instr_string};
|
||||
}
|
||||
}
|
||||
|
||||
Mips2C_Line handle_clts(const Instruction& i0, const std::string& instr_string) {
|
||||
@@ -896,15 +915,35 @@ Mips2C_Line handle_pmfhl_lh(const Instruction& i0, const std::string& instr_stri
|
||||
return {fmt::format("c->pmfhl_lh({});", reg_to_name(i0.get_dst(0))), instr_string};
|
||||
}
|
||||
|
||||
Mips2C_Line handle_ctc2(const Instruction& i0, const std::string& instr_string) {
|
||||
return {fmt::format("{} = c->gpr_src({}).du16[0];", reg_to_name(i0.get_dst(0)),
|
||||
reg_to_name(i0.get_src(0))),
|
||||
instr_string};
|
||||
}
|
||||
|
||||
Mips2C_Line handle_cfc2(const Instruction& i0, const std::string& instr_string) {
|
||||
return {fmt::format("c->gprs[{}].du64[0] = {};", reg_to_name(i0.get_dst(0)),
|
||||
reg_to_name(i0.get_src(0))),
|
||||
instr_string};
|
||||
}
|
||||
|
||||
Mips2C_Line handle_normal_instr(Mips2C_Output& output,
|
||||
const Instruction& i0,
|
||||
const std::string& instr_str,
|
||||
int& unknown_count,
|
||||
const LinkedObjectFile* file) {
|
||||
switch (i0.kind) {
|
||||
case InstructionKind::CTC2:
|
||||
return handle_ctc2(i0, instr_str);
|
||||
case InstructionKind::CFC2:
|
||||
return handle_cfc2(i0, instr_str);
|
||||
case InstructionKind::LW:
|
||||
return handle_lw(output, i0, instr_str, file);
|
||||
case InstructionKind::LB:
|
||||
case InstructionKind::LWL:
|
||||
case InstructionKind::LWR:
|
||||
case InstructionKind::LDR:
|
||||
case InstructionKind::LDL:
|
||||
case InstructionKind::LBU:
|
||||
case InstructionKind::LWU:
|
||||
case InstructionKind::LQ:
|
||||
@@ -932,6 +971,8 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output,
|
||||
return handle_generic_op3_bc_mask(i0, instr_str, "vsub_bc");
|
||||
case InstructionKind::VMUL_BC:
|
||||
return handle_generic_op3_bc_mask(i0, instr_str, "vmul_bc");
|
||||
case InstructionKind::VMADD:
|
||||
return handle_generic_op3_mask(i0, instr_str, "vmadd");
|
||||
case InstructionKind::VMUL:
|
||||
return handle_generic_op3_mask(i0, instr_str, "vmul");
|
||||
case InstructionKind::VADD:
|
||||
@@ -978,6 +1019,7 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output,
|
||||
case InstructionKind::PSRAW:
|
||||
case InstructionKind::PSRAH:
|
||||
case InstructionKind::PSRLH:
|
||||
case InstructionKind::PSLLW:
|
||||
return handle_generic_op2_u16(i0, instr_str);
|
||||
case InstructionKind::SLL:
|
||||
return handle_sll(i0, instr_str);
|
||||
@@ -988,6 +1030,7 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output,
|
||||
case InstructionKind::PEXTLB:
|
||||
case InstructionKind::MOVN:
|
||||
case InstructionKind::PEXTUW:
|
||||
case InstructionKind::PEXTUH:
|
||||
case InstructionKind::PEXTLW:
|
||||
case InstructionKind::PCPYUD:
|
||||
case InstructionKind::PCPYLD:
|
||||
@@ -1008,7 +1051,12 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output,
|
||||
case InstructionKind::PMAXW:
|
||||
case InstructionKind::PMAXH:
|
||||
case InstructionKind::SUBU:
|
||||
case InstructionKind::SLT:
|
||||
case InstructionKind::SLTU:
|
||||
case InstructionKind::DSRAV:
|
||||
case InstructionKind::DSLLV:
|
||||
case InstructionKind::PAND:
|
||||
case InstructionKind::PCEQB:
|
||||
return handle_generic_op3(i0, instr_str, {});
|
||||
case InstructionKind::MULS:
|
||||
return handle_generic_op3(i0, instr_str, "muls");
|
||||
@@ -1034,8 +1082,12 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output,
|
||||
return handle_vmula_bc(i0, instr_str);
|
||||
case InstructionKind::VMADDA_BC:
|
||||
return handle_vmadda_bc(i0, instr_str);
|
||||
case InstructionKind::VADDA_BC:
|
||||
return handle_vadda_bc(i0, instr_str);
|
||||
case InstructionKind::VMSUBA_BC:
|
||||
return handle_vmsuba_bc(i0, instr_str);
|
||||
case InstructionKind::VMADDA:
|
||||
return handle_vmadda(i0, instr_str);
|
||||
case InstructionKind::VMADD_BC:
|
||||
return handle_generic_op3_bc_mask(i0, instr_str, "vmadd_bc");
|
||||
case InstructionKind::VMSUB_BC:
|
||||
@@ -1078,8 +1130,10 @@ Mips2C_Line handle_normal_instr(Mips2C_Output& output,
|
||||
return handle_generic_op2(i0, instr_str, "plzcw");
|
||||
case InstructionKind::PCPYH:
|
||||
return handle_generic_op2(i0, instr_str, "pcpyh");
|
||||
case InstructionKind::PROT3W:
|
||||
return handle_generic_op2(i0, instr_str, "prot3w");
|
||||
case InstructionKind::LUI:
|
||||
return handle_lui(i0, instr_str);
|
||||
return handle_lui(i0, instr_str, output);
|
||||
case InstructionKind::CLTS:
|
||||
output.needs_cop1_bc = true;
|
||||
return handle_clts(i0, instr_str);
|
||||
@@ -1317,13 +1371,17 @@ void run_mips2c(Function* f) {
|
||||
// set the branch condition
|
||||
output.lines.push_back(handle_non_likely_branch_bc(instr, instr_str));
|
||||
// then the delay slot
|
||||
ASSERT(i + 1 < block.end_instr);
|
||||
if (!(i + 1 < block.end_instr)) {
|
||||
output.lines.emplace_back("DANGER jump to delay slot, this MUST be fixed manually!",
|
||||
"");
|
||||
lg::warn("Delay slot weirdness in {}, block {}", f->name(), block_idx);
|
||||
}
|
||||
i++;
|
||||
auto& delay_i = f->instructions.at(i);
|
||||
auto delay_i_str = delay_i.to_string(file->labels);
|
||||
output.lines.push_back(
|
||||
handle_normal_instr(output, delay_i, delay_i_str, unknown_count, file));
|
||||
ASSERT(i + 1 == block.end_instr);
|
||||
// ASSERT(i + 1 == block.end_instr);
|
||||
// then the goto
|
||||
output.lines.emplace_back(fmt::format("if (bc) {{goto block_{};}}", block.succ_branch),
|
||||
"branch non-likely\n");
|
||||
|
||||
@@ -6774,8 +6774,8 @@
|
||||
)
|
||||
|
||||
(deftype generic-gif-tag (structure)
|
||||
((data uint32 4 :offset-assert 0)
|
||||
(qword qword :inline :offset 0)
|
||||
((data uint32 4 :offset-assert 0 :score -1)
|
||||
(qword qword :inline :offset 0 :score -1)
|
||||
(fan-prim uint32 :offset 0)
|
||||
(str-prim uint32 :offset 4)
|
||||
(regs uint32 :offset 8)
|
||||
@@ -6789,10 +6789,10 @@
|
||||
(deftype ad-cmd (structure)
|
||||
((word uint32 4 :offset-assert 0)
|
||||
(quad uint128 :offset 0)
|
||||
(data uint64 :offset 0)
|
||||
(data uint64 :offset 0 :score 1)
|
||||
(cmds uint64 :offset 8)
|
||||
(cmd gs-reg :offset 8)
|
||||
(x uint32 :offset 0)
|
||||
(cmd gs-reg :offset 8 :score 1)
|
||||
(x uint32 :offset 0 )
|
||||
(y uint32 :offset 4)
|
||||
(z uint32 :offset 8)
|
||||
(w uint32 :offset 12)
|
||||
@@ -8634,7 +8634,7 @@
|
||||
(next-chain uint32 :offset-assert 276)
|
||||
(buf-index uint32 :offset-assert 280)
|
||||
(fragment-count uint32 :offset-assert 284)
|
||||
(write-limit int32 :offset-assert 288)
|
||||
(write-limit pointer :offset-assert 288)
|
||||
(indexed-input-base generic-merc-input :offset-assert 292)
|
||||
(other-input-base generic-merc-input :offset-assert 296)
|
||||
(indexed-output-base generic-merc-output :offset-assert 300)
|
||||
@@ -9813,8 +9813,8 @@
|
||||
|
||||
(deftype merc-globals (structure)
|
||||
((first uint32 :offset-assert 0)
|
||||
(next uint32 :offset-assert 4)
|
||||
(sink basic :offset-assert 8) ;; dma sink
|
||||
(next (pointer uint32) :offset-assert 4)
|
||||
(sink generic-dma-foreground-sink :offset-assert 8) ;; dma sink
|
||||
)
|
||||
:allow-misaligned
|
||||
:method-count-assert 9
|
||||
@@ -13651,9 +13651,9 @@
|
||||
)
|
||||
|
||||
(deftype foreground-area (structure)
|
||||
((joint-work joint-work :inline :offset-assert 0)
|
||||
((joint-work joint-work :inline :offset-assert 0 :score 1999999999)
|
||||
(generic-work generic-work :inline :offset 0)
|
||||
(bone-mem bone-memory :score 1999999999 :inline :offset 0)
|
||||
(bone-mem bone-memory :inline :offset 0)
|
||||
(shadow-work shadow-work :inline :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
@@ -16643,7 +16643,7 @@
|
||||
(define-extern bones-debug (function none))
|
||||
(define-extern dump-bone-mem (function none))
|
||||
(define-extern draw-bones-shadow (function draw-control object object pointer))
|
||||
(define-extern draw-bones-generic-merc (function draw-control object object int pointer))
|
||||
(define-extern draw-bones-generic-merc (function draw-control pointer pointer int pointer))
|
||||
(define-extern draw-bones-merc (function draw-control object object int int pointer))
|
||||
(define-extern draw-bones-check-longest-edge (function draw-control float none))
|
||||
(define-extern draw-bones-check-longest-edge-asm (function draw-control float symbol))
|
||||
@@ -16716,10 +16716,10 @@
|
||||
|
||||
;; - Functions
|
||||
|
||||
(define-extern generic-work-init function)
|
||||
(define-extern generic-work-init (function generic-dma-foreground-sink none))
|
||||
(define-extern generic-upload-vu0 function)
|
||||
(define-extern upload-vu0-program function)
|
||||
(define-extern generic-initialize-without-sink function)
|
||||
(define-extern upload-vu0-program (function vu-function pointer none))
|
||||
(define-extern generic-initialize-without-sink (function matrix vu-lights none))
|
||||
(define-extern generic-initialize function)
|
||||
(define-extern generic-wrapup function)
|
||||
(define-extern generic-dma-from-spr function)
|
||||
@@ -16765,6 +16765,7 @@
|
||||
(init-data uint8 :offset-assert 1)
|
||||
(init-addr uint16 :offset-assert 2)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
@@ -16772,15 +16773,15 @@
|
||||
|
||||
;; - Functions
|
||||
|
||||
(define-extern generic-merc-init-asm function)
|
||||
(define-extern generic-merc-init-asm (function none))
|
||||
(define-extern mercneric-matrix-asm function)
|
||||
(define-extern mercneric-shader-asm function)
|
||||
(define-extern mercneric-bittable-asm function)
|
||||
(define-extern mercneric-convert function)
|
||||
(define-extern high-speed-reject function)
|
||||
(define-extern generic-merc-execute-asm function)
|
||||
(define-extern generic-merc-add-to-cue (function basic none))
|
||||
(define-extern generic-merc-execute-all (function none))
|
||||
(define-extern high-speed-reject (function none))
|
||||
(define-extern generic-merc-execute-asm (function none))
|
||||
(define-extern generic-merc-add-to-cue (function generic-dma-foreground-sink none))
|
||||
(define-extern generic-merc-execute-all (function dma-buffer none))
|
||||
|
||||
;; - Unknowns
|
||||
|
||||
|
||||
@@ -153,7 +153,6 @@
|
||||
"upload-vu0-program",
|
||||
|
||||
// generic-merc
|
||||
"generic-merc-execute-all",
|
||||
"generic-merc-execute-asm", // CFG
|
||||
"high-speed-reject",
|
||||
"mercneric-convert",
|
||||
@@ -488,7 +487,8 @@
|
||||
"(anon-function 2 snow-ball)": [22],
|
||||
"draw-bones-merc": [1, 3, 5, 7, 8, 10, 11, 12, 13],
|
||||
"(anon-function 48 lavatube-energy)": [13],
|
||||
"generic-tie-execute": [4, 9]
|
||||
"generic-tie-execute": [4, 9],
|
||||
"generic-merc-execute-all":[3,7, 12]
|
||||
},
|
||||
|
||||
// Sometimes the game might use format strings that are fetched dynamically,
|
||||
@@ -571,7 +571,27 @@
|
||||
"draw-bones-merc",
|
||||
"draw-bones-check-longest-edge-asm",
|
||||
"setup-blerc-chains-for-one-fragment",
|
||||
"blerc-execute"
|
||||
"blerc-execute",
|
||||
|
||||
// generic merc
|
||||
//"generic-merc-execute-all",
|
||||
"generic-merc-execute-asm",
|
||||
"high-speed-reject",
|
||||
"mercneric-convert",
|
||||
"mercneric-bittable-asm",
|
||||
"mercneric-shader-asm",
|
||||
"mercneric-matrix-asm",
|
||||
"generic-merc-init-asm",
|
||||
"generic-prepare-dma-double",
|
||||
"generic-light-proc",
|
||||
"generic-envmap-proc",
|
||||
"draw-bones-generic-merc",
|
||||
"generic-prepare-dma-single",
|
||||
|
||||
"ripple-matrix-scale",
|
||||
"ripple-apply-wave-table",
|
||||
"ripple-create-wave-table",
|
||||
"ripple-execute-init"
|
||||
],
|
||||
|
||||
"mips2c_jump_table_functions": {
|
||||
|
||||
@@ -2111,6 +2111,10 @@
|
||||
["L6", "shadow-vu1-gifbuf-template"]
|
||||
],
|
||||
|
||||
"generic-vu0": [
|
||||
["L1", "vu-function"]
|
||||
],
|
||||
|
||||
// please do not add things after this entry! git is dumb.
|
||||
"object-file-that-doesnt-actually-exist-and-i-just-put-this-here-to-prevent-merge-conflicts-with-this-file": []
|
||||
}
|
||||
|
||||
@@ -7338,5 +7338,45 @@
|
||||
[24, "a0", "dma-packet"]
|
||||
],
|
||||
|
||||
"draw-bones-generic-merc":[
|
||||
[11, "v1", "generic-merc-ctrl"],
|
||||
[198, "v1", "generic-merc-ctrl"],
|
||||
[274, "a0", "generic-merc-ctrl"],
|
||||
[277, "a0", "pointer"],
|
||||
[278, "a0", "merc-fragment-control"],
|
||||
[[270, 274], "a0", "dma-packet"],
|
||||
[[258, 262], "a0", "dma-packet"],
|
||||
[280, "a0", "pointer"],
|
||||
[[303, 306], "gp", "dma-packet"],
|
||||
[281, "v1", "merc-fragment"]
|
||||
],
|
||||
|
||||
"generic-merc-execute-all": [
|
||||
[[165,170], "v1", "terrain-context"],
|
||||
[92, "a0", "terrain-context"],
|
||||
[96, "v1", "terrain-context"],
|
||||
[100, "v1", "terrain-context"],
|
||||
[103, "a0", "generic-envmap-saves"],
|
||||
[105, "v1", "(pointer int32)"],
|
||||
[47, "v1", "terrain-context"],
|
||||
[49, "v1", "terrain-context"],
|
||||
[51, "v1", "terrain-context"],
|
||||
[66, "a0", "terrain-context"],
|
||||
[[114, 117], "v1", "dma-packet"]
|
||||
],
|
||||
|
||||
"generic-initialize-without-sink": [
|
||||
[8, "a0", "terrain-context"],
|
||||
[32, "a0", "terrain-context"]
|
||||
],
|
||||
|
||||
"generic-work-init":[
|
||||
[10, "a0", "terrain-context"],
|
||||
[13, "a0", "terrain-context"],
|
||||
[16, "a0", "terrain-context"],
|
||||
[18, "a0", "terrain-context"],
|
||||
[[21, 42], "gp", "adgif-shader"]
|
||||
],
|
||||
|
||||
"placeholder-do-not-add-below": []
|
||||
}
|
||||
|
||||
@@ -2064,7 +2064,6 @@ void make_tfrag3_data(std::map<u32, std::vector<GroupedDraw>>& draws,
|
||||
// ASSERT((vert.rgba >> 2) < 1024); spider cave has 2048?
|
||||
ASSERT((vert.rgba & 3) == 0);
|
||||
|
||||
size_t vert_idx = vertices.size();
|
||||
vertices.push_back(vtx);
|
||||
}
|
||||
tdraw.runs.push_back(run);
|
||||
|
||||
@@ -363,9 +363,6 @@ std::array<math::Vector4f, 4> extract_tie_matrix(const u16* data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// geometry we use (todo, should really look at this)
|
||||
constexpr int GEOM_IDX = 0; // todo 0 or 1??
|
||||
|
||||
/*!
|
||||
* Confirm that the initial value of all wind vectors is 0.
|
||||
* If this is true, we don't have to actually save them to the fr3 file, we can just create
|
||||
@@ -2229,7 +2226,6 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
|
||||
color_index += ifrag.color_index_offset_in_big_palette;
|
||||
}
|
||||
|
||||
size_t vert_idx = tree.packed_vertices.color_indices.size();
|
||||
tree.packed_vertices.color_indices.push_back(color_index);
|
||||
// draw_to_add_to->vertex_index_stream.push_back(vert_idx);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,11 @@ goos::Object decompile_at_label_with_hint(const LabelInfo& hint,
|
||||
// TODO - having this logic here isn't great.
|
||||
auto stride = align(field_type_info->get_size_in_memory(),
|
||||
field_type_info->get_inline_array_stride_alignment());
|
||||
fmt::print("decompiler {} stride {} {} = {}\n", field_type_info->get_name(),
|
||||
field_type_info->get_size_in_memory(),
|
||||
field_type_info->get_inline_array_stride_alignment(),
|
||||
align(field_type_info->get_size_in_memory(),
|
||||
field_type_info->get_inline_array_stride_alignment()));
|
||||
|
||||
if (dynamic_cast<BasicType*>(field_type_info)) {
|
||||
throw std::runtime_error("Plan basic arrays not supported yet");
|
||||
@@ -330,7 +335,7 @@ goos::Object decomp_ref_to_integer_array_guess_size(
|
||||
int field_location,
|
||||
const TypeSystem& ts,
|
||||
const std::vector<std::vector<LinkedWord>>& all_words,
|
||||
const LinkedObjectFile* file,
|
||||
const LinkedObjectFile* /*file*/,
|
||||
const TypeSpec& array_elt_type,
|
||||
int stride) {
|
||||
// fmt::print("Decomp decomp_ref_to_inline_array_guess_size {}\n", array_elt_type.print());
|
||||
|
||||
@@ -45,8 +45,11 @@ set(RUNTIME_SOURCE
|
||||
mips2c/functions/collide_mesh.cpp
|
||||
mips2c/functions/collide_probe.cpp
|
||||
mips2c/functions/draw_string.cpp
|
||||
mips2c/functions/generic_effect.cpp
|
||||
mips2c/functions/generic_merc.cpp
|
||||
mips2c/functions/joint.cpp
|
||||
mips2c/functions/merc_blend_shape.cpp
|
||||
mips2c/functions/ripple.cpp
|
||||
mips2c/functions/sky_tng.cpp
|
||||
mips2c/functions/sparticle.cpp
|
||||
mips2c/functions/sparticle_launcher.cpp
|
||||
@@ -75,6 +78,8 @@ set(RUNTIME_SOURCE
|
||||
graphics/opengl_renderer/debug_gui.cpp
|
||||
graphics/opengl_renderer/DirectRenderer.cpp
|
||||
graphics/opengl_renderer/EyeRenderer.cpp
|
||||
graphics/opengl_renderer/GenericProgram.cpp
|
||||
graphics/opengl_renderer/GenericRenderer.cpp
|
||||
graphics/opengl_renderer/dma_helpers.cpp
|
||||
graphics/opengl_renderer/Loader.cpp
|
||||
graphics/opengl_renderer/MercProgram.cpp
|
||||
|
||||
@@ -0,0 +1,494 @@
|
||||
#pragma once
|
||||
#include "immintrin.h"
|
||||
#include "common/math/Vector.h"
|
||||
|
||||
enum class Mask {
|
||||
NONE = 0,
|
||||
x = 1,
|
||||
y = 2,
|
||||
xy = 3,
|
||||
z = 4,
|
||||
xz = 5,
|
||||
yz = 6,
|
||||
xyz = 7,
|
||||
w = 8,
|
||||
xw = 9,
|
||||
yw = 10,
|
||||
xyw = 11,
|
||||
zw = 12,
|
||||
xzw = 13,
|
||||
yzw = 14,
|
||||
xyzw = 15
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
#define REALLY_INLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define REALLY_INLINE __forceinline
|
||||
#endif
|
||||
|
||||
// note: must be aligned.
|
||||
static inline REALLY_INLINE void copy_vector(void* dest, const void* src) {
|
||||
__m128 val = _mm_load_ps((const float*)src);
|
||||
_mm_store_ps((float*)dest, val);
|
||||
}
|
||||
|
||||
inline float vu_max(float a, float b) {
|
||||
return std::max(b, a);
|
||||
// s32 ai, bi;
|
||||
// memcpy(&ai, &a, 4);
|
||||
// memcpy(&bi, &b, 4);
|
||||
// bool flip = ai < 0 && bi < 0;
|
||||
// if (ai > bi) {
|
||||
// return flip ? b : a;
|
||||
// } else {
|
||||
// return flip ? a : b;
|
||||
// }
|
||||
}
|
||||
|
||||
inline float vu_min(float a, float b) {
|
||||
s32 ai, bi;
|
||||
memcpy(&ai, &a, 4);
|
||||
memcpy(&bi, &b, 4);
|
||||
bool flip = ai < 0 && bi < 0;
|
||||
if (ai > bi) {
|
||||
return flip ? a : b;
|
||||
} else {
|
||||
return flip ? b : a;
|
||||
}
|
||||
}
|
||||
|
||||
struct alignas(16) Vf {
|
||||
REALLY_INLINE __m128 load() const { return _mm_load_ps(data); }
|
||||
|
||||
REALLY_INLINE void move_xyzw(const Vf& src) { copy_vector(data, src.data); }
|
||||
|
||||
float data[4];
|
||||
float& x() { return data[0]; }
|
||||
float& y() { return data[1]; }
|
||||
float& z() { return data[2]; }
|
||||
float& w() { return data[3]; }
|
||||
|
||||
const float& x() const { return data[0]; }
|
||||
const float& y() const { return data[1]; }
|
||||
const float& z() const { return data[2]; }
|
||||
const float& w() const { return data[3]; }
|
||||
|
||||
std::string print() const { return fmt::format("{} {} {} {}", x(), y(), z(), w()); }
|
||||
|
||||
std::string print_hex() const {
|
||||
return fmt::format("0x{:x} 0x{:x} 0x{:x} 0x{:x}", x_as_u32(), y_as_u32(), z_as_u32(),
|
||||
w_as_u32());
|
||||
}
|
||||
|
||||
void set_zero() {
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = 0;
|
||||
data[3] = 0;
|
||||
}
|
||||
|
||||
u16 x_as_u16() const {
|
||||
u16 result;
|
||||
memcpy(&result, &data[0], 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
u16 y_as_u16() const {
|
||||
u16 result;
|
||||
memcpy(&result, &data[1], 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
u16 z_as_u16() const {
|
||||
u16 result;
|
||||
memcpy(&result, &data[2], 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
u16 w_as_u16() const {
|
||||
u16 result;
|
||||
memcpy(&result, &data[3], 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 x_as_u32() const {
|
||||
u32 result;
|
||||
memcpy(&result, &data[0], 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 y_as_u32() const {
|
||||
u32 result;
|
||||
memcpy(&result, &data[1], 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 z_as_u32() const {
|
||||
u32 result;
|
||||
memcpy(&result, &data[2], 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 w_as_u32() const {
|
||||
u32 result;
|
||||
memcpy(&result, &data[3], 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
Vf() = default;
|
||||
Vf(const math::Vector4f& vec) { memcpy(data, vec.data(), 16); }
|
||||
Vf(float a, float b, float c, float d) {
|
||||
data[0] = a;
|
||||
data[1] = b;
|
||||
data[2] = c;
|
||||
data[3] = d;
|
||||
}
|
||||
|
||||
std::string str_float() const { return fmt::format("{} {} {} {}", x(), y(), z(), w()); }
|
||||
|
||||
float& operator[](int i) { return data[i]; }
|
||||
float operator[](int i) const { return data[i]; }
|
||||
|
||||
void mr32(Mask mask, const Vf& other) {
|
||||
float temp[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
temp[i] = other[(i + 1) % 4];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = temp[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void mr32_z(const Vf& other) { data[2] = other.data[3]; }
|
||||
|
||||
void mfir(Mask mask, s16 in) {
|
||||
s32 sext = in;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
memcpy(data + i, &sext, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void maxi(Mask mask, const Vf& other, float I) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_max(other[i], I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void max(Mask mask, const Vf& other, float I) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_max(other[i], I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void max(Mask mask, const Vf& other, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_max(other[i], b[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void max_xyzw(const Vf& a, const Vf& b) {
|
||||
_mm_store_ps(data, _mm_max_ps(_mm_load_ps(a.data), _mm_load_ps(b.data)));
|
||||
}
|
||||
|
||||
REALLY_INLINE void max_xyzw(const Vf& a, float b) {
|
||||
_mm_store_ps(data, _mm_max_ps(_mm_load_ps(a.data), _mm_set1_ps(b)));
|
||||
}
|
||||
|
||||
REALLY_INLINE void mini_xyzw(const Vf& a, const Vf& b) {
|
||||
_mm_store_ps(data, _mm_min_ps(_mm_load_ps(a.data), _mm_load_ps(b.data)));
|
||||
}
|
||||
|
||||
REALLY_INLINE void mini_xyzw(const Vf& a, float b) {
|
||||
_mm_store_ps(data, _mm_min_ps(_mm_load_ps(a.data), _mm_set1_ps(b)));
|
||||
}
|
||||
|
||||
void minii(Mask mask, const Vf& other, float I) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_min(other[i], I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mini(Mask mask, const Vf& other, float I) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_min(other[i], I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill(float f) {
|
||||
for (auto& x : data) {
|
||||
x = f;
|
||||
}
|
||||
}
|
||||
|
||||
void move(Mask mask, const Vf& other) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = other[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mfp(Mask mask, float other) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = other;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] + b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void add_xyzw(const Vf& a, const Vf& b) {
|
||||
_mm_store_ps(data, _mm_add_ps(_mm_load_ps(a.data), _mm_load_ps(b.data)));
|
||||
}
|
||||
|
||||
void add(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] + b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sub(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] - b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sub(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] - b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void mul_xyzw(const Vf& a, const Vf& b) {
|
||||
_mm_store_ps(data, _mm_mul_ps(_mm_load_ps(a.data), _mm_load_ps(b.data)));
|
||||
}
|
||||
|
||||
REALLY_INLINE void mul_xyzw(const Vf& a, float b) {
|
||||
_mm_store_ps(data, _mm_mul_ps(_mm_load_ps(a.data), _mm_set1_ps(b)));
|
||||
}
|
||||
|
||||
void mul(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] * b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mul(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void itof0(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val;
|
||||
memcpy(&val, &a.data[i], 4);
|
||||
data[i] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void itof12(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val;
|
||||
memcpy(&val, &a.data[i], 4);
|
||||
data[i] = ((float)val) * (1.f / 4096.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void itof15(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val;
|
||||
memcpy(&val, &a.data[i], 4);
|
||||
data[i] = ((float)val) * (1.f / 32768.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ftoi4(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val = a.data[i] * 16.f;
|
||||
memcpy(&data[i], &val, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ftoi12(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
// if (std::isnan(a.data[i])) {
|
||||
// ASSERT(false);
|
||||
// }
|
||||
s32 val = a.data[i] * 4096.f;
|
||||
memcpy(&data[i], &val, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ftoi0(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val = a.data[i];
|
||||
memcpy(&data[i], &val, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct alignas(16) Accumulator {
|
||||
float data[4];
|
||||
|
||||
void adda(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] + b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void madda(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] += a[i] * b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void madda(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] += a[i] * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void madda_xyzw(const Vf& _a, float _b) {
|
||||
auto b = _mm_set1_ps(_b);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
auto acc = _mm_load_ps(data);
|
||||
_mm_store_ps(data, _mm_add_ps(_mm_mul_ps(a, b), acc));
|
||||
}
|
||||
|
||||
REALLY_INLINE void madda_xyzw(const Vf& _a, const Vf& _b) {
|
||||
auto b = _mm_load_ps(_b.data);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
auto acc = _mm_load_ps(data);
|
||||
_mm_store_ps(data, _mm_add_ps(_mm_mul_ps(a, b), acc));
|
||||
}
|
||||
|
||||
void madd(Mask mask, Vf& dest, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
dest[i] = data[i] + a[i] * b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void madd_xyzw(Vf& dest, const Vf& _a, float _b) {
|
||||
auto b = _mm_set1_ps(_b);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
auto acc = _mm_load_ps(data);
|
||||
_mm_store_ps(dest.data, _mm_add_ps(_mm_mul_ps(a, b), acc));
|
||||
}
|
||||
|
||||
REALLY_INLINE void madd_xyz(Vf& dest, const Vf& _a, float _b) {
|
||||
auto b = _mm_set1_ps(_b);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
auto acc = _mm_load_ps(data);
|
||||
auto prod = _mm_add_ps(_mm_mul_ps(a, b), acc);
|
||||
prod = _mm_blend_ps(prod, _mm_load_ps(dest.data), 0b1000);
|
||||
_mm_store_ps(dest.data, prod);
|
||||
}
|
||||
|
||||
void madd(Mask mask, Vf& dest, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
dest[i] = data[i] + a[i] * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u16 madd_flag(Mask mask, Vf& dest, const Vf& a, float b) {
|
||||
u16 result = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
dest[i] = data[i] + a[i] * b;
|
||||
if (dest[i] < 0) {
|
||||
result |= (1 << (3 - i)) << 4;
|
||||
}
|
||||
if (dest[i] == 0) {
|
||||
result |= (1 << (3 - i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void mula(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] * b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mula(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void mula_xyzw(const Vf& _a, float _b) {
|
||||
auto b = _mm_set1_ps(_b);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
_mm_store_ps(data, _mm_mul_ps(a, b));
|
||||
}
|
||||
|
||||
REALLY_INLINE void mula_xyzw(const Vf& _a, const Vf& _b) {
|
||||
auto b = _mm_load_ps(_b.data);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
_mm_store_ps(data, _mm_mul_ps(a, b));
|
||||
}
|
||||
};
|
||||
+4
-4
@@ -45,7 +45,7 @@ void set_discord_rpc(int state) {
|
||||
}
|
||||
|
||||
// get full level name from symbol name ("village1" -> "Sandover Village")
|
||||
const char* jak1_get_full_level_name(char* level_name) {
|
||||
const char* jak1_get_full_level_name(const char* level_name) {
|
||||
// ignore sublevels
|
||||
if (!strcmp(level_name, "jungleb")) {
|
||||
level_name = "jungle";
|
||||
@@ -75,6 +75,6 @@ void handleDiscordError(int errcode, const char* message) {
|
||||
printf("\nDiscord: error (%d: %s)\n", errcode, message);
|
||||
}
|
||||
|
||||
void handleDiscordJoin(const char* secret) {}
|
||||
void handleDiscordJoinRequest(const DiscordUser* request) {}
|
||||
void handleDiscordSpectate(const char* secret) {}
|
||||
void handleDiscordJoin(const char* /*secret*/) {}
|
||||
void handleDiscordJoinRequest(const DiscordUser* /*request*/) {}
|
||||
void handleDiscordSpectate(const char* /*secret*/) {}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
void init_discord_rpc();
|
||||
void set_discord_rpc(int state);
|
||||
const char* jak1_get_full_level_name(char* level_name);
|
||||
const char* jak1_get_full_level_name(const char* level_name);
|
||||
|
||||
void handleDiscordReady(const DiscordUser* user);
|
||||
void handleDiscordDisconnected(int errcode, const char* message);
|
||||
|
||||
@@ -19,12 +19,15 @@ enum class BucketId {
|
||||
TFRAG_LEVEL0 = 6,
|
||||
TIE_LEVEL0 = 9,
|
||||
MERC_TFRAG_TEX_LEVEL0 = 10,
|
||||
GMERC_TFRAG_TEX_LEVEL0 = 11,
|
||||
TFRAG_TEX_LEVEL1 = 12,
|
||||
TFRAG_LEVEL1 = 13,
|
||||
TIE_LEVEL1 = 16,
|
||||
MERC_TFRAG_TEX_LEVEL1 = 17,
|
||||
GMERC_TFRAG_TEX_LEVEL1 = 18,
|
||||
SHRUB_TEX_LEVEL0 = 19,
|
||||
SHRUB_TEX_LEVEL1 = 25,
|
||||
GENERIC_SHRUB = 30,
|
||||
ALPHA_TEX_LEVEL0 = 31,
|
||||
TFRAG_TRANS0_AND_SKY_BLEND_LEVEL0 = 32,
|
||||
TFRAG_DIRT_LEVEL0 = 34,
|
||||
@@ -34,16 +37,22 @@ enum class BucketId {
|
||||
TFRAG_DIRT_LEVEL1 = 41,
|
||||
TFRAG_ICE_LEVEL1 = 43,
|
||||
MERC_AFTER_ALPHA = 45,
|
||||
GENERIC_ALPHA = 46,
|
||||
PRIS_TEX_LEVEL0 = 48,
|
||||
MERC_PRIS_LEVEL0 = 49,
|
||||
GENERIC_PRIS_LEVEL0 = 50,
|
||||
PRIS_TEX_LEVEL1 = 51,
|
||||
MERC_PRIS_LEVEL1 = 52,
|
||||
GENERIC_PRIS_LEVEL1 = 53,
|
||||
MERC_EYES_AFTER_PRIS = 54,
|
||||
MERC_AFTER_PRIS = 55,
|
||||
GENERIC_PRIS = 56,
|
||||
WATER_TEX_LEVEL0 = 57,
|
||||
MERC_WATER_LEVEL0 = 58,
|
||||
GENERIC_WATER_LEVEL0 = 59,
|
||||
WATER_TEX_LEVEL1 = 60,
|
||||
MERC_WATER_LEVEL1 = 61,
|
||||
GENERIC_WATER_LEVEL1 = 62,
|
||||
// ...
|
||||
PRE_SPRITE_TEX = 65, // maybe it's just common textures?
|
||||
SPRITE = 66,
|
||||
@@ -81,6 +90,8 @@ struct SharedRenderState {
|
||||
bool use_sky_cpu = true;
|
||||
bool use_occlusion_culling = true;
|
||||
bool render_debug = false;
|
||||
bool enable_merc_xgkick = true;
|
||||
bool enable_generic_xgkick = true;
|
||||
|
||||
void reset();
|
||||
bool has_camera_planes = false;
|
||||
|
||||
@@ -259,6 +259,9 @@ void DirectRenderer::update_gl_prim(SharedRenderState* render_state) {
|
||||
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::DIRECT_BASIC_TEXTURED].id(),
|
||||
"alpha_reject"),
|
||||
alpha_reject);
|
||||
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::DIRECT_BASIC_TEXTURED].id(),
|
||||
"color_mult"),
|
||||
m_ogl.color_mult);
|
||||
}
|
||||
// update_gl_texture(render_state);
|
||||
m_global_texture_state.needs_gl_update = true;
|
||||
@@ -342,10 +345,12 @@ void DirectRenderer::update_gl_texture(SharedRenderState* render_state, int unit
|
||||
|
||||
void DirectRenderer::update_gl_blend() {
|
||||
const auto& state = m_blend_state;
|
||||
m_ogl.color_mult = 1.f;
|
||||
if (!state.alpha_blend_enable) {
|
||||
glDisable(GL_BLEND);
|
||||
} else {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendColor(1, 1, 1, 1);
|
||||
if (state.a == GsAlpha::BlendMode::SOURCE && state.b == GsAlpha::BlendMode::DEST &&
|
||||
state.c == GsAlpha::BlendMode::SOURCE && state.d == GsAlpha::BlendMode::DEST) {
|
||||
// (Cs - Cd) * As + Cd
|
||||
@@ -378,6 +383,19 @@ void DirectRenderer::update_gl_blend() {
|
||||
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
|
||||
glBlendColor(0, 0, 0, state.fix / 127.f);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
} else if (state.a == GsAlpha::BlendMode::SOURCE && state.b == GsAlpha::BlendMode::SOURCE &&
|
||||
state.c == GsAlpha::BlendMode::SOURCE && state.d == GsAlpha::BlendMode::SOURCE) {
|
||||
// this is very weird...
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
} else if (state.a == GsAlpha::BlendMode::SOURCE &&
|
||||
state.b == GsAlpha::BlendMode::ZERO_OR_FIXED &&
|
||||
state.c == GsAlpha::BlendMode::DEST && state.d == GsAlpha::BlendMode::DEST) {
|
||||
// (Cs - 0) * Ad + Cd
|
||||
glBlendFunc(GL_DST_ALPHA, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
m_ogl.color_mult = 0.5;
|
||||
m_prim_gl_state_needs_gl_update = true;
|
||||
} else {
|
||||
// unsupported blend: a 0 b 2 c 2 d 1
|
||||
lg::error("unsupported blend: a {} b {} c {} d {}", (int)state.a, (int)state.b, (int)state.c,
|
||||
@@ -911,6 +929,9 @@ void DirectRenderer::handle_xyzf2_common(u32 x,
|
||||
bool advance) {
|
||||
ASSERT(z < (1 << 24));
|
||||
(void)f; // TODO: do something with this.
|
||||
if (m_my_id == BucketId::GENERIC_PRIS) {
|
||||
// fmt::print("0x{:x}, 0x{:x}, 0x{:x}\n", x, y, z);
|
||||
}
|
||||
if (m_prim_buffer.is_full()) {
|
||||
lg::warn("Buffer wrapped in {} ({} verts, {} bytes)", m_name, m_ogl.vertex_buffer_max_verts,
|
||||
m_prim_buffer.vert_count * sizeof(Vertex));
|
||||
|
||||
@@ -63,6 +63,13 @@ class DirectRenderer : public BucketRenderer {
|
||||
|
||||
void draw_debug_window() override;
|
||||
|
||||
void hack_disable_blend() {
|
||||
m_blend_state.a = GsAlpha::BlendMode::SOURCE;
|
||||
m_blend_state.b = GsAlpha::BlendMode::SOURCE;
|
||||
m_blend_state.c = GsAlpha::BlendMode::SOURCE;
|
||||
m_blend_state.d = GsAlpha::BlendMode::SOURCE;
|
||||
}
|
||||
|
||||
private:
|
||||
void handle_ad(const u8* data, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
void handle_zbuf1(u64 val, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
@@ -239,6 +246,7 @@ class DirectRenderer : public BucketRenderer {
|
||||
GLuint vao;
|
||||
u32 vertex_buffer_bytes = 0;
|
||||
u32 vertex_buffer_max_verts = 0;
|
||||
float color_mult = 1.0;
|
||||
} m_ogl;
|
||||
|
||||
struct {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,298 @@
|
||||
#include "GenericRenderer.h"
|
||||
#include "third-party/imgui/imgui.h"
|
||||
|
||||
GenericRenderer::GenericRenderer(const std::string& name, BucketId my_id)
|
||||
: BucketRenderer(name, my_id), m_direct(name, my_id, 0x4000, DirectRenderer::Mode::NORMAL) {}
|
||||
|
||||
void GenericRenderer::render(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof) {
|
||||
m_skipped_tags = 0;
|
||||
m_debug.clear();
|
||||
m_direct.reset_state();
|
||||
|
||||
// if the first draw should have no blending, it sets ABE in PRIM, but not ALPHA.
|
||||
// the default ALPHA doesn't seem to be right. I don't know what's supposed to set it here.
|
||||
// although this is definitely a hack, it doesn't seem to cause problems when the first thing to
|
||||
// draw is transparent.
|
||||
m_direct.hack_disable_blend();
|
||||
|
||||
// skip if disabled
|
||||
if (!m_enabled) {
|
||||
while (dma.current_tag_offset() != render_state->next_bucket) {
|
||||
dma.read_and_advance();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (dma.current_tag_offset() != render_state->next_bucket) {
|
||||
auto data = dma.read_and_advance();
|
||||
m_debug += fmt::format("{} : {} {}\n", data.size_bytes, data.vifcode0().print(),
|
||||
data.vifcode1().print());
|
||||
auto v0 = data.vifcode0();
|
||||
auto v1 = data.vifcode1();
|
||||
if (data.size_bytes == 0) {
|
||||
m_debug += "Emtpy Tag\n";
|
||||
switch (v0.kind) {
|
||||
case VifCode::Kind::STCYCL:
|
||||
vu.stcycl = v0.immediate;
|
||||
break;
|
||||
case VifCode::Kind::NOP:
|
||||
break;
|
||||
default:
|
||||
fmt::print("unknown vifcode0 empty tag: {}\n", v0.print());
|
||||
ASSERT(false);
|
||||
}
|
||||
switch (v1.kind) {
|
||||
case VifCode::Kind::STCYCL:
|
||||
vu.stcycl = v1.immediate;
|
||||
break;
|
||||
case VifCode::Kind::NOP:
|
||||
break;
|
||||
case VifCode::Kind::MSCAL:
|
||||
mscal(v1.immediate, render_state, prof);
|
||||
break;
|
||||
default:
|
||||
fmt::print("unknown vifcode1 empty tag: {}\n", v1.print());
|
||||
ASSERT(false);
|
||||
}
|
||||
} else if (v0.kind == VifCode::Kind::FLUSHA && v1.kind == VifCode::Kind::DIRECT) {
|
||||
m_direct.render_gif(data.data, data.size_bytes, render_state, prof);
|
||||
ASSERT(v1.immediate == data.size_bytes / 16);
|
||||
} else if (v0.kind == VifCode::Kind::NOP && v1.kind == VifCode::Kind::DIRECT) {
|
||||
m_direct.render_gif(data.data, data.size_bytes, render_state, prof);
|
||||
ASSERT(v1.immediate == data.size_bytes / 16);
|
||||
} else if (v0.kind == VifCode::Kind::STCYCL && v1.kind == VifCode::Kind::UNPACK_V4_32) {
|
||||
vu.stcycl = v0.immediate;
|
||||
u32 bytes_used = unpack32_4(VifCodeUnpack(v1), data.data, v1.num);
|
||||
if (bytes_used < data.size_bytes) {
|
||||
handle_dma_stream(data.data + bytes_used, data.size_bytes - bytes_used, render_state, prof);
|
||||
} else if (bytes_used > data.size_bytes) {
|
||||
ASSERT(false);
|
||||
}
|
||||
} else if (v0.kind == VifCode::Kind::MSCALF && v1.kind == VifCode::Kind::STMOD) {
|
||||
mscal(v0.immediate, render_state, prof);
|
||||
ASSERT(v1.immediate == 0);
|
||||
|
||||
u32 data_offset = 0;
|
||||
u32 base_vifcode_data;
|
||||
memcpy(&base_vifcode_data, data.data + data_offset, 4);
|
||||
VifCode base_vc(base_vifcode_data);
|
||||
ASSERT(base_vc.immediate == 0);
|
||||
data_offset += 4;
|
||||
|
||||
u32 offset_vifcode_data;
|
||||
memcpy(&offset_vifcode_data, data.data + data_offset, 4);
|
||||
VifCode offset_vc(offset_vifcode_data);
|
||||
ASSERT(offset_vc.immediate == 0);
|
||||
data_offset += 4;
|
||||
|
||||
for (int i = 0; i < 1; i++) {
|
||||
u32 nop_vifcode_data;
|
||||
memcpy(&nop_vifcode_data, data.data + data_offset, 4);
|
||||
VifCode next_vc(nop_vifcode_data);
|
||||
ASSERT(next_vc.kind == VifCode::Kind::NOP);
|
||||
data_offset += 4;
|
||||
}
|
||||
|
||||
u32 strow_vifcode_data;
|
||||
memcpy(&strow_vifcode_data, data.data + data_offset, 4);
|
||||
VifCode strow_vc(strow_vifcode_data);
|
||||
data_offset += 4;
|
||||
ASSERT(strow_vc.kind == VifCode::Kind::STROW);
|
||||
|
||||
memcpy(vu.row, data.data + data_offset, 16);
|
||||
data_offset += 16;
|
||||
|
||||
ASSERT(data_offset == 32);
|
||||
ASSERT(data_offset == data.size_bytes);
|
||||
} else if (v0.kind == VifCode::Kind::NOP && v1.kind == VifCode::Kind::UNPACK_V3_32) {
|
||||
u32 bytes_used = unpack32_3(VifCodeUnpack(v1), data.data, v1.num);
|
||||
if (bytes_used < data.size_bytes) {
|
||||
handle_dma_stream(data.data + bytes_used, data.size_bytes - bytes_used, render_state, prof);
|
||||
} else if (bytes_used > data.size_bytes) {
|
||||
ASSERT(false);
|
||||
}
|
||||
} else {
|
||||
fmt::print("Generic encountered unknown DMA.\n");
|
||||
fmt::print("Size bytes: {}\n", data.size_bytes);
|
||||
fmt::print("VIF0: {}\n", data.vifcode0().print());
|
||||
fmt::print("VIF1: {}\n", data.vifcode1().print());
|
||||
ASSERT(false);
|
||||
}
|
||||
m_skipped_tags++;
|
||||
}
|
||||
m_direct.flush_pending(render_state, prof);
|
||||
}
|
||||
|
||||
void GenericRenderer::handle_dma_stream(const u8* data,
|
||||
u32 bytes,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof) {
|
||||
while (bytes) {
|
||||
u32 tag_data;
|
||||
memcpy(&tag_data, data, 4);
|
||||
bytes -= 4;
|
||||
data += 4;
|
||||
VifCode vc(tag_data);
|
||||
switch (vc.kind) {
|
||||
case VifCode::Kind::NOP:
|
||||
break;
|
||||
case VifCode::Kind::STCYCL:
|
||||
vu.stcycl = vc.immediate;
|
||||
break;
|
||||
case VifCode::Kind::UNPACK_V3_32: {
|
||||
u32 bytes_transferred = unpack32_3(VifCodeUnpack(vc), data, vc.num);
|
||||
bytes -= bytes_transferred;
|
||||
data += bytes_transferred;
|
||||
} break;
|
||||
case VifCode::Kind::UNPACK_V4_8: {
|
||||
u32 bytes_transferred = unpack8_4(VifCodeUnpack(vc), data, vc.num);
|
||||
bytes -= bytes_transferred;
|
||||
data += bytes_transferred;
|
||||
} break;
|
||||
case VifCode::Kind::UNPACK_V2_16: {
|
||||
u32 bytes_transferred = unpack16_2(VifCodeUnpack(vc), data, vc.num);
|
||||
bytes -= bytes_transferred;
|
||||
data += bytes_transferred;
|
||||
} break;
|
||||
case VifCode::Kind::UNPACK_V4_32: {
|
||||
u32 bytes_transferred = unpack32_4(VifCodeUnpack(vc), data, vc.num);
|
||||
bytes -= bytes_transferred;
|
||||
data += bytes_transferred;
|
||||
} break;
|
||||
case VifCode::Kind::MSCAL:
|
||||
mscal(vc.immediate, render_state, prof);
|
||||
break;
|
||||
default:
|
||||
fmt::print("Generic encountered unknown DMA in handle_dma_stream.\n");
|
||||
fmt::print("Bytes remaining: {}\n", bytes);
|
||||
fmt::print("VIF: {}\n", vc.print());
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GenericRenderer::draw_debug_window() {
|
||||
ImGui::Text("Skipped %d tags", m_skipped_tags);
|
||||
ImGui::Text("Debug:\n%s\n", m_debug.c_str());
|
||||
if (ImGui::TreeNode("Direct")) {
|
||||
m_direct.draw_debug_window();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
u32 GenericRenderer::unpack32_4(const VifCodeUnpack& up, const u8* data, u32 imm) {
|
||||
ASSERT(vu.stcycl == 0x404);
|
||||
ASSERT(!up.is_unsigned);
|
||||
u32 addr = up.addr_qw;
|
||||
ASSERT(imm != 0);
|
||||
// ASSERT(!m_vif.stmod);
|
||||
ASSERT(!up.use_tops_flag);
|
||||
// if (up.use_tops_flag) {
|
||||
// addr += xitop();
|
||||
// }
|
||||
|
||||
u32 start_in_buff = (addr)*16;
|
||||
u32 end_in_buff = start_in_buff + imm * 16;
|
||||
ASSERT(start_in_buff < sizeof(m_buffer.data));
|
||||
ASSERT(end_in_buff <= sizeof(m_buffer.data));
|
||||
memcpy(m_buffer.data + start_in_buff, data, imm * 16);
|
||||
|
||||
// fmt::print("---------------------------------unpack32_4: {} to {}\n", addr, addr + imm);
|
||||
return imm * 16;
|
||||
}
|
||||
|
||||
u32 GenericRenderer::unpack32_3(const VifCodeUnpack& up, const u8* data, u32 imm) {
|
||||
u32 bytes_read = 0;
|
||||
ASSERT(!up.use_tops_flag);
|
||||
ASSERT(!up.is_unsigned);
|
||||
ASSERT(vu.stcycl == 0x103); // w = 1, c = 3
|
||||
ASSERT(imm != 0);
|
||||
|
||||
for (u32 i = 0; i < imm; i++) {
|
||||
u32 xyzw[4];
|
||||
memcpy(xyzw, data + bytes_read, 12);
|
||||
bytes_read += 12;
|
||||
xyzw[3] = 0xbeef;
|
||||
|
||||
// check for garbage going into GENERIC VU1 code.
|
||||
float f[3];
|
||||
memcpy(f, xyzw, 12);
|
||||
// if (std::abs(f[0]) > 100000) {
|
||||
// fmt::print("VERY SUSPICIOUS VERTEX: {} 0x{:x} at 0x{:x}\n", f[0], xyzw[0],
|
||||
// (data + bytes_read) - g_ee_main_mem);
|
||||
// }
|
||||
|
||||
// fmt::print("vtx: {} {} {}\n", f[0], f[1], f[2]);
|
||||
u32 total_addr = 16 * (up.addr_qw + 3 * i);
|
||||
ASSERT(total_addr + 16 <= sizeof(m_buffer.data));
|
||||
memcpy(m_buffer.data + total_addr, xyzw, 16);
|
||||
}
|
||||
// fmt::print("---------------------------------unpack32_3: {} to {} imm {}\n", up.addr_qw,
|
||||
// (up.addr_qw + 3 * imm), imm);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
u32 GenericRenderer::unpack8_4(const VifCodeUnpack& up, const u8* data, u32 imm) {
|
||||
u32 bytes_read = 0;
|
||||
ASSERT(!up.use_tops_flag);
|
||||
ASSERT(up.is_unsigned);
|
||||
ASSERT(vu.stcycl == 0x103); // w = 1, c = 3
|
||||
ASSERT(imm != 0);
|
||||
for (u32 i = 0; i < imm; i++) {
|
||||
u32 xyzw[4] = {data[0], data[1], data[2], data[3]};
|
||||
bytes_read += 4;
|
||||
data += 4;
|
||||
u32 total_addr = 16 * (up.addr_qw + 3 * i);
|
||||
ASSERT(total_addr + 16 <= sizeof(m_buffer.data));
|
||||
memcpy(m_buffer.data + total_addr, xyzw, 16);
|
||||
}
|
||||
// fmt::print("---------------------------------unpack8_4: {} to {} imm {}\n", up.addr_qw,
|
||||
// (up.addr_qw + 3 * imm), imm);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
u32 GenericRenderer::unpack16_2(const VifCodeUnpack& up, const u8* data, u32 imm) {
|
||||
u32 bytes_read = 0;
|
||||
ASSERT(!up.use_tops_flag);
|
||||
ASSERT(!up.is_unsigned);
|
||||
ASSERT(vu.stcycl == 0x103); // w = 1, c = 3
|
||||
ASSERT(imm != 0);
|
||||
for (u32 i = 0; i < imm; i++) {
|
||||
s32 xyzw[4];
|
||||
s16 x, y;
|
||||
memcpy(&x, data + bytes_read, 2);
|
||||
memcpy(&y, data + bytes_read + 2, 2);
|
||||
bytes_read += 4;
|
||||
xyzw[0] = x;
|
||||
xyzw[1] = y;
|
||||
xyzw[2] = 0;
|
||||
xyzw[3] = 0;
|
||||
|
||||
u32 total_addr = 16 * (up.addr_qw + 3 * i);
|
||||
ASSERT(total_addr + 16 <= sizeof(m_buffer.data));
|
||||
memcpy(m_buffer.data + total_addr, xyzw, 16);
|
||||
}
|
||||
// fmt::print("---------------------------------unpack16_2: {} to {} imm {}\n", up.addr_qw,
|
||||
// (up.addr_qw + 3 * imm), imm);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
void GenericRenderer::mscal(int imm, SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
m_debug += fmt::format("mscal: {}\n", imm);
|
||||
switch (imm) {
|
||||
case 0:
|
||||
mscal0();
|
||||
break;
|
||||
default:
|
||||
mscal_dispatch(imm, render_state, prof);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GenericRenderer::xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
if (render_state->enable_generic_xgkick) {
|
||||
m_direct.render_gif(m_buffer.data + (16 * addr), UINT32_MAX, render_state, prof);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/graphics/opengl_renderer/BucketRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/DirectRenderer.h"
|
||||
#include "game/common/vu.h"
|
||||
|
||||
class GenericRenderer : public BucketRenderer {
|
||||
public:
|
||||
GenericRenderer(const std::string& name, BucketId my_id);
|
||||
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
|
||||
void draw_debug_window() override;
|
||||
|
||||
private:
|
||||
u32 unpack32_4(const VifCodeUnpack& up, const u8* data, u32 imm);
|
||||
u32 unpack32_3(const VifCodeUnpack& up, const u8* data, u32 imm);
|
||||
u32 unpack8_4(const VifCodeUnpack& up, const u8* data, u32 imm);
|
||||
u32 unpack16_2(const VifCodeUnpack& up, const u8* data, u32 imm);
|
||||
|
||||
void mscal(int imm, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
void mscal0();
|
||||
void mscal_dispatch(int imm, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
void handle_dma_stream(const u8* data,
|
||||
u32 bytes,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof);
|
||||
void lq_buffer(Mask mask, Vf& dest, u16 addr);
|
||||
void isw_buffer(Mask mask, u16 val, u16 addr);
|
||||
void ilw_buffer(Mask mask, u16& dest, u16 addr);
|
||||
void xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
|
||||
void sq_buffer(Mask mask, const Vf& data, u32 qw) {
|
||||
ASSERT(qw * 16 < sizeof(m_buffer.data));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
memcpy(m_buffer.data + qw * 16 + i * 4, data.data + i, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int m_skipped_tags = 0;
|
||||
DirectRenderer m_direct;
|
||||
std::string m_debug;
|
||||
|
||||
struct Vu {
|
||||
u32 row[4];
|
||||
u32 stcycl = 0;
|
||||
Vf vf01, vf02, vf03, vf04, vf05, vf06, vf07, vf08, vf09, vf10, vf11, vf12, vf13, vf14, vf15,
|
||||
vf16, vf17, vf18, vf19, vf20, vf21, vf22, vf23, vf24, vf25, vf26, vf27, vf28, vf29, vf30,
|
||||
vf31;
|
||||
const Vf vf00;
|
||||
u16 vi01, vi02, vi03, vi04, vi05, vi06, vi07, vi09, vi08, vi11, vi12, vi13, vi10, vi14, vi15;
|
||||
float I, P, Q;
|
||||
|
||||
Accumulator acc;
|
||||
const u16 vi00 = 0;
|
||||
Vu() : vf00(0, 0, 0, 1) {}
|
||||
} vu;
|
||||
|
||||
struct alignas(16) BufferMemory {
|
||||
u8 data[1024 * 16];
|
||||
} m_buffer;
|
||||
};
|
||||
@@ -340,7 +340,7 @@ void MercRenderer::draw_debug_window() {
|
||||
}
|
||||
|
||||
void MercRenderer::xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
if (m_enable_send_to_direct) {
|
||||
if (m_enable_send_to_direct && render_state->enable_merc_xgkick) {
|
||||
m_direct.render_gif(m_buffer.data + (16 * addr), UINT32_MAX, render_state, prof);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,426 +3,7 @@
|
||||
#include "game/graphics/opengl_renderer/BucketRenderer.h"
|
||||
#include "common/math/Vector.h"
|
||||
#include "game/graphics/opengl_renderer/DirectRenderer.h"
|
||||
|
||||
#include "immintrin.h"
|
||||
|
||||
enum class Mask {
|
||||
NONE = 0,
|
||||
x = 1,
|
||||
y = 2,
|
||||
xy = 3,
|
||||
z = 4,
|
||||
xz = 5,
|
||||
yz = 6,
|
||||
xyz = 7,
|
||||
w = 8,
|
||||
xw = 9,
|
||||
yw = 10,
|
||||
xyw = 11,
|
||||
zw = 12,
|
||||
xzw = 13,
|
||||
yzw = 14,
|
||||
xyzw = 15
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
#define REALLY_INLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define REALLY_INLINE __forceinline
|
||||
#endif
|
||||
|
||||
// note: must be aligned.
|
||||
static inline REALLY_INLINE void copy_vector(void* dest, const void* src) {
|
||||
__m128 val = _mm_load_ps((const float*)src);
|
||||
_mm_store_ps((float*)dest, val);
|
||||
}
|
||||
|
||||
inline float vu_max(float a, float b) {
|
||||
return std::max(b, a);
|
||||
// s32 ai, bi;
|
||||
// memcpy(&ai, &a, 4);
|
||||
// memcpy(&bi, &b, 4);
|
||||
// bool flip = ai < 0 && bi < 0;
|
||||
// if (ai > bi) {
|
||||
// return flip ? b : a;
|
||||
// } else {
|
||||
// return flip ? a : b;
|
||||
// }
|
||||
}
|
||||
|
||||
inline float vu_min(float a, float b) {
|
||||
s32 ai, bi;
|
||||
memcpy(&ai, &a, 4);
|
||||
memcpy(&bi, &b, 4);
|
||||
bool flip = ai < 0 && bi < 0;
|
||||
if (ai > bi) {
|
||||
return flip ? a : b;
|
||||
} else {
|
||||
return flip ? b : a;
|
||||
}
|
||||
}
|
||||
|
||||
struct alignas(16) Vf {
|
||||
REALLY_INLINE __m128 load() const { return _mm_load_ps(data); }
|
||||
|
||||
REALLY_INLINE void move_xyzw(const Vf& src) { copy_vector(data, src.data); }
|
||||
|
||||
float data[4];
|
||||
float& x() { return data[0]; }
|
||||
float& y() { return data[1]; }
|
||||
float& z() { return data[2]; }
|
||||
float& w() { return data[3]; }
|
||||
|
||||
const float& x() const { return data[0]; }
|
||||
const float& y() const { return data[1]; }
|
||||
const float& z() const { return data[2]; }
|
||||
const float& w() const { return data[3]; }
|
||||
|
||||
u16 x_as_u16() const {
|
||||
u16 result;
|
||||
memcpy(&result, &data[0], 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
u16 y_as_u16() const {
|
||||
u16 result;
|
||||
memcpy(&result, &data[1], 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
u16 z_as_u16() const {
|
||||
u16 result;
|
||||
memcpy(&result, &data[2], 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
u16 w_as_u16() const {
|
||||
u16 result;
|
||||
memcpy(&result, &data[3], 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 x_as_u32() const {
|
||||
u32 result;
|
||||
memcpy(&result, &data[0], 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 y_as_u32() const {
|
||||
u32 result;
|
||||
memcpy(&result, &data[1], 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 z_as_u32() const {
|
||||
u32 result;
|
||||
memcpy(&result, &data[2], 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 w_as_u32() const {
|
||||
u32 result;
|
||||
memcpy(&result, &data[3], 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
Vf() = default;
|
||||
Vf(const math::Vector4f& vec) { memcpy(data, vec.data(), 16); }
|
||||
Vf(float a, float b, float c, float d) {
|
||||
data[0] = a;
|
||||
data[1] = b;
|
||||
data[2] = c;
|
||||
data[3] = d;
|
||||
}
|
||||
|
||||
std::string str_float() const { return fmt::format("{} {} {} {}", x(), y(), z(), w()); }
|
||||
|
||||
float& operator[](int i) { return data[i]; }
|
||||
float operator[](int i) const { return data[i]; }
|
||||
|
||||
void mr32(Mask mask, const Vf& other) {
|
||||
float temp[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
temp[i] = other[(i + 1) % 4];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = temp[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void mr32_z(const Vf& other) { data[2] = other.data[3]; }
|
||||
|
||||
void mfir(Mask mask, s16 in) {
|
||||
s32 sext = in;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
memcpy(data + i, &sext, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void maxi(Mask mask, const Vf& other, float I) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_max(other[i], I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void max(Mask mask, const Vf& other, float I) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_max(other[i], I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void max(Mask mask, const Vf& other, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_max(other[i], b[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void max_xyzw(const Vf& a, const Vf& b) {
|
||||
_mm_store_ps(data, _mm_max_ps(_mm_load_ps(a.data), _mm_load_ps(b.data)));
|
||||
}
|
||||
|
||||
REALLY_INLINE void max_xyzw(const Vf& a, float b) {
|
||||
_mm_store_ps(data, _mm_max_ps(_mm_load_ps(a.data), _mm_set1_ps(b)));
|
||||
}
|
||||
|
||||
REALLY_INLINE void mini_xyzw(const Vf& a, const Vf& b) {
|
||||
_mm_store_ps(data, _mm_min_ps(_mm_load_ps(a.data), _mm_load_ps(b.data)));
|
||||
}
|
||||
|
||||
REALLY_INLINE void mini_xyzw(const Vf& a, float b) {
|
||||
_mm_store_ps(data, _mm_min_ps(_mm_load_ps(a.data), _mm_set1_ps(b)));
|
||||
}
|
||||
|
||||
void minii(Mask mask, const Vf& other, float I) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_min(other[i], I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mini(Mask mask, const Vf& other, float I) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = vu_min(other[i], I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void move(Mask mask, const Vf& other) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = other[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mfp(Mask mask, float other) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = other;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] + b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void add_xyzw(const Vf& a, const Vf& b) {
|
||||
_mm_store_ps(data, _mm_add_ps(_mm_load_ps(a.data), _mm_load_ps(b.data)));
|
||||
}
|
||||
|
||||
void add(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] + b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void mul_xyzw(const Vf& a, const Vf& b) {
|
||||
_mm_store_ps(data, _mm_mul_ps(_mm_load_ps(a.data), _mm_load_ps(b.data)));
|
||||
}
|
||||
|
||||
REALLY_INLINE void mul_xyzw(const Vf& a, float b) {
|
||||
_mm_store_ps(data, _mm_mul_ps(_mm_load_ps(a.data), _mm_set1_ps(b)));
|
||||
}
|
||||
|
||||
void mul(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] * b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mul(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void itof0(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val;
|
||||
memcpy(&val, &a.data[i], 4);
|
||||
data[i] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void itof15(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val;
|
||||
memcpy(&val, &a.data[i], 4);
|
||||
data[i] = ((float)val) * (1.f / 32768.f);
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ftoi4(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val = a.data[i] * 16.f;
|
||||
memcpy(&data[i], &val, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ftoi0(Mask mask, const Vf& a) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
s32 val = a.data[i];
|
||||
memcpy(&data[i], &val, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct alignas(16) Accumulator {
|
||||
float data[4];
|
||||
|
||||
void adda(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] + b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void madda(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] += a[i] * b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void madda(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] += a[i] * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void madda_xyzw(const Vf& _a, float _b) {
|
||||
auto b = _mm_set1_ps(_b);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
auto acc = _mm_load_ps(data);
|
||||
_mm_store_ps(data, _mm_add_ps(_mm_mul_ps(a, b), acc));
|
||||
}
|
||||
|
||||
REALLY_INLINE void madda_xyzw(const Vf& _a, const Vf& _b) {
|
||||
auto b = _mm_load_ps(_b.data);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
auto acc = _mm_load_ps(data);
|
||||
_mm_store_ps(data, _mm_add_ps(_mm_mul_ps(a, b), acc));
|
||||
}
|
||||
|
||||
void madd(Mask mask, Vf& dest, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
dest[i] = data[i] + a[i] * b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void madd_xyzw(Vf& dest, const Vf& _a, float _b) {
|
||||
auto b = _mm_set1_ps(_b);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
auto acc = _mm_load_ps(data);
|
||||
_mm_store_ps(dest.data, _mm_add_ps(_mm_mul_ps(a, b), acc));
|
||||
}
|
||||
|
||||
REALLY_INLINE void madd_xyz(Vf& dest, const Vf& _a, float _b) {
|
||||
auto b = _mm_set1_ps(_b);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
auto acc = _mm_load_ps(data);
|
||||
auto prod = _mm_add_ps(_mm_mul_ps(a, b), acc);
|
||||
prod = _mm_blend_ps(prod, _mm_load_ps(dest.data), 0b1000);
|
||||
_mm_store_ps(dest.data, prod);
|
||||
}
|
||||
|
||||
void madd(Mask mask, Vf& dest, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
dest[i] = data[i] + a[i] * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mula(Mask mask, const Vf& a, const Vf& b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] * b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mula(Mask mask, const Vf& a, float b) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
data[i] = a[i] * b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REALLY_INLINE void mula_xyzw(const Vf& _a, float _b) {
|
||||
auto b = _mm_set1_ps(_b);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
_mm_store_ps(data, _mm_mul_ps(a, b));
|
||||
}
|
||||
|
||||
REALLY_INLINE void mula_xyzw(const Vf& _a, const Vf& _b) {
|
||||
auto b = _mm_load_ps(_b.data);
|
||||
auto a = _mm_load_ps(_a.data);
|
||||
_mm_store_ps(data, _mm_mul_ps(a, b));
|
||||
}
|
||||
};
|
||||
#include "game/common/vu.h"
|
||||
|
||||
class MercRenderer : public BucketRenderer {
|
||||
public:
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "game/graphics/opengl_renderer/tfrag/Tie3.h"
|
||||
#include "game/graphics/opengl_renderer/MercRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/EyeRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/GenericRenderer.h"
|
||||
|
||||
// for the vif callback
|
||||
#include "game/kernel/kmachine.h"
|
||||
@@ -85,29 +86,31 @@ void OpenGLRenderer::init_bucket_renderers() {
|
||||
//-----------------------
|
||||
// LEVEL 0 tfrag texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("tfrag-tex-0", BucketId::TFRAG_TEX_LEVEL0); // 5
|
||||
init_bucket_renderer<TFragment>("tfrag-0", BucketId::TFRAG_LEVEL0, normal_tfrags, false, 0); // 6
|
||||
init_bucket_renderer<TextureUploadHandler>("l0-tfrag-tex", BucketId::TFRAG_TEX_LEVEL0); // 5
|
||||
init_bucket_renderer<TFragment>("l0-tfrag-tfrag", BucketId::TFRAG_LEVEL0, normal_tfrags, false,
|
||||
0); // 6
|
||||
// 7
|
||||
// 8
|
||||
init_bucket_renderer<Tie3>("tie-0", BucketId::TIE_LEVEL0, 0); // 9
|
||||
init_bucket_renderer<MercRenderer>("merc-tf-0", BucketId::MERC_TFRAG_TEX_LEVEL0); // 10
|
||||
// 11
|
||||
init_bucket_renderer<Tie3>("l0-tfrag-tie", BucketId::TIE_LEVEL0, 0); // 9
|
||||
init_bucket_renderer<MercRenderer>("l0-tfrag-merc", BucketId::MERC_TFRAG_TEX_LEVEL0); // 10
|
||||
init_bucket_renderer<GenericRenderer>("l0-tfrag-gmerc", BucketId::GMERC_TFRAG_TEX_LEVEL0); // 11
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 1 tfrag texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("tfrag-tex-1", BucketId::TFRAG_TEX_LEVEL1); // 12
|
||||
init_bucket_renderer<TFragment>("tfrag-1", BucketId::TFRAG_LEVEL1, normal_tfrags, false, 1);
|
||||
init_bucket_renderer<TextureUploadHandler>("l1-tfrag-tex", BucketId::TFRAG_TEX_LEVEL1); // 12
|
||||
init_bucket_renderer<TFragment>("l1-tfrag-tfrag", BucketId::TFRAG_LEVEL1, normal_tfrags, false,
|
||||
1);
|
||||
// 14
|
||||
// 15
|
||||
init_bucket_renderer<Tie3>("tie-1", BucketId::TIE_LEVEL1, 1);
|
||||
init_bucket_renderer<MercRenderer>("merc-tf-1", BucketId::MERC_TFRAG_TEX_LEVEL1); // 17
|
||||
// 18??
|
||||
init_bucket_renderer<Tie3>("l1-tfrag-tie", BucketId::TIE_LEVEL1, 1);
|
||||
init_bucket_renderer<MercRenderer>("l1-tfrag-merc", BucketId::MERC_TFRAG_TEX_LEVEL1); // 17
|
||||
init_bucket_renderer<GenericRenderer>("l1-tfrag-gmerc", BucketId::GMERC_TFRAG_TEX_LEVEL1); // 18
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 0 shrub texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("shrub-tex-0", BucketId::SHRUB_TEX_LEVEL0); // 19
|
||||
init_bucket_renderer<TextureUploadHandler>("l0-shrub-tex", BucketId::SHRUB_TEX_LEVEL0); // 19
|
||||
// 20
|
||||
// 21
|
||||
// 22
|
||||
@@ -117,75 +120,82 @@ void OpenGLRenderer::init_bucket_renderers() {
|
||||
//-----------------------
|
||||
// LEVEL 1 shrub texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("shrub-tex-1", BucketId::SHRUB_TEX_LEVEL1); // 25
|
||||
init_bucket_renderer<TextureUploadHandler>("l1-shrub-tex", BucketId::SHRUB_TEX_LEVEL1); // 25
|
||||
// 26
|
||||
// 27
|
||||
// 28
|
||||
// 29
|
||||
// 30
|
||||
|
||||
// I don't think this is actually used? or it might be wrong.
|
||||
init_bucket_renderer<GenericRenderer>("common-shrub-generic", BucketId::GENERIC_SHRUB); // 30
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 0 alpha texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("alpha-tex-0", BucketId::ALPHA_TEX_LEVEL0); // 31
|
||||
init_bucket_renderer<SkyBlendHandler>("sky-blend-and-tfrag-trans-0",
|
||||
init_bucket_renderer<TextureUploadHandler>("l0-alpha-tex", BucketId::ALPHA_TEX_LEVEL0); // 31
|
||||
init_bucket_renderer<SkyBlendHandler>("l0-alpha-sky-blend-and-tfrag-trans",
|
||||
BucketId::TFRAG_TRANS0_AND_SKY_BLEND_LEVEL0, 0,
|
||||
sky_gpu_blender, sky_cpu_blender); // 32
|
||||
// 33
|
||||
init_bucket_renderer<TFragment>("tfrag-dirt-0", BucketId::TFRAG_DIRT_LEVEL0, dirt_tfrags, false,
|
||||
init_bucket_renderer<TFragment>("l0-alpha-tfrag", BucketId::TFRAG_DIRT_LEVEL0, dirt_tfrags, false,
|
||||
0); // 34
|
||||
// 35
|
||||
init_bucket_renderer<TFragment>("tfrag-ice-0", BucketId::TFRAG_ICE_LEVEL0, ice_tfrags, false, 0);
|
||||
init_bucket_renderer<TFragment>("l0-alpha-tfrag-ice", BucketId::TFRAG_ICE_LEVEL0, ice_tfrags,
|
||||
false, 0);
|
||||
// 37
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 1 alpha texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("alpha-tex-1", BucketId::ALPHA_TEX_LEVEL1); // 38
|
||||
init_bucket_renderer<SkyBlendHandler>("sky-blend-and-tfrag-trans-1",
|
||||
init_bucket_renderer<TextureUploadHandler>("l1-alpha-tex", BucketId::ALPHA_TEX_LEVEL1); // 38
|
||||
init_bucket_renderer<SkyBlendHandler>("l1-alpha-sky-blend-and-tfrag-trans",
|
||||
BucketId::TFRAG_TRANS1_AND_SKY_BLEND_LEVEL1, 1,
|
||||
sky_gpu_blender, sky_cpu_blender); // 39
|
||||
// 40
|
||||
init_bucket_renderer<TFragment>("tfrag-dirt-1", BucketId::TFRAG_DIRT_LEVEL1, dirt_tfrags, false,
|
||||
init_bucket_renderer<TFragment>("l1-alpha-tfrag-dirt", BucketId::TFRAG_DIRT_LEVEL1, dirt_tfrags,
|
||||
false,
|
||||
1); // 41
|
||||
// 42
|
||||
init_bucket_renderer<TFragment>("tfrag-ice-1", BucketId::TFRAG_ICE_LEVEL1, ice_tfrags, false, 1);
|
||||
init_bucket_renderer<TFragment>("l1-alpha-tfrag-ice", BucketId::TFRAG_ICE_LEVEL1, ice_tfrags,
|
||||
false, 1);
|
||||
// 44
|
||||
init_bucket_renderer<MercRenderer>("merc-after-alpha", BucketId::MERC_AFTER_ALPHA);
|
||||
// 46?
|
||||
|
||||
init_bucket_renderer<MercRenderer>("common-alpha-merc", BucketId::MERC_AFTER_ALPHA);
|
||||
|
||||
init_bucket_renderer<GenericRenderer>("common-alpha-generic", BucketId::GENERIC_ALPHA); // 46
|
||||
// 47?
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 0 pris texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("pris-tex-0", BucketId::PRIS_TEX_LEVEL0); // 48
|
||||
init_bucket_renderer<MercRenderer>("merc-pris-0", BucketId::MERC_PRIS_LEVEL0); // 49
|
||||
// 50
|
||||
init_bucket_renderer<TextureUploadHandler>("l0-pris-tex", BucketId::PRIS_TEX_LEVEL0); // 48
|
||||
init_bucket_renderer<MercRenderer>("l0-pris-merc", BucketId::MERC_PRIS_LEVEL0); // 49
|
||||
init_bucket_renderer<GenericRenderer>("l0-pris-generic", BucketId::GENERIC_PRIS_LEVEL0); // 50
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 1 pris texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("pris-tex-1", BucketId::PRIS_TEX_LEVEL1); // 51
|
||||
init_bucket_renderer<MercRenderer>("merc-pris-1", BucketId::MERC_PRIS_LEVEL1); // 52
|
||||
// 53
|
||||
init_bucket_renderer<TextureUploadHandler>("l1-pris-tex", BucketId::PRIS_TEX_LEVEL1); // 51
|
||||
init_bucket_renderer<MercRenderer>("l1-pris-merc", BucketId::MERC_PRIS_LEVEL1); // 52
|
||||
init_bucket_renderer<GenericRenderer>("l1-pris-generic", BucketId::GENERIC_PRIS_LEVEL1); // 53
|
||||
|
||||
init_bucket_renderer<EyeRenderer>("merc-eyes-after-pris", BucketId::MERC_EYES_AFTER_PRIS); // 54
|
||||
init_bucket_renderer<MercRenderer>("merc-after-pris", BucketId::MERC_AFTER_PRIS); // 55
|
||||
// 56?
|
||||
init_bucket_renderer<EyeRenderer>("common-pris-eyes", BucketId::MERC_EYES_AFTER_PRIS); // 54
|
||||
init_bucket_renderer<MercRenderer>("common-pris-merc", BucketId::MERC_AFTER_PRIS); // 55
|
||||
init_bucket_renderer<GenericRenderer>("common-pris-generic", BucketId::GENERIC_PRIS); // 56
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 0 water texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("water-tex-0", BucketId::WATER_TEX_LEVEL0); // 57
|
||||
init_bucket_renderer<MercRenderer>("merc-water-0", BucketId::MERC_WATER_LEVEL0); // 58
|
||||
// 59
|
||||
init_bucket_renderer<TextureUploadHandler>("l0-water-tex", BucketId::WATER_TEX_LEVEL0); // 57
|
||||
init_bucket_renderer<MercRenderer>("l0-water-merc", BucketId::MERC_WATER_LEVEL0); // 58
|
||||
init_bucket_renderer<GenericRenderer>("l0-water-generic", BucketId::GENERIC_WATER_LEVEL0); // 59
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 1 water texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("water-tex-1", BucketId::WATER_TEX_LEVEL1); // 60
|
||||
init_bucket_renderer<MercRenderer>("merc-water-1", BucketId::MERC_WATER_LEVEL1); // 61
|
||||
// 62
|
||||
init_bucket_renderer<TextureUploadHandler>("l1-water-tex", BucketId::WATER_TEX_LEVEL1); // 60
|
||||
init_bucket_renderer<MercRenderer>("l1-water-merc", BucketId::MERC_WATER_LEVEL1); // 61
|
||||
init_bucket_renderer<GenericRenderer>("l1-water-generic", BucketId::GENERIC_WATER_LEVEL1); // 62
|
||||
|
||||
// 63?
|
||||
// 64?
|
||||
@@ -193,7 +203,7 @@ void OpenGLRenderer::init_bucket_renderers() {
|
||||
//-----------------------
|
||||
// COMMON texture
|
||||
//-----------------------
|
||||
init_bucket_renderer<TextureUploadHandler>("pre-sprite-tex", BucketId::PRE_SPRITE_TEX); // 65
|
||||
init_bucket_renderer<TextureUploadHandler>("common-tex", BucketId::PRE_SPRITE_TEX); // 65
|
||||
|
||||
std::vector<std::unique_ptr<BucketRenderer>> sprite_renderers;
|
||||
// the first renderer added will be the default for sprite.
|
||||
@@ -280,6 +290,8 @@ void OpenGLRenderer::draw_renderer_selection_window() {
|
||||
ImGui::Checkbox("Sky CPU", &m_render_state.use_sky_cpu);
|
||||
ImGui::Checkbox("Occlusion Cull", &m_render_state.use_occlusion_culling);
|
||||
ImGui::Checkbox("Render Debug (slower)", &m_render_state.render_debug);
|
||||
ImGui::Checkbox("Merc XGKICK", &m_render_state.enable_merc_xgkick);
|
||||
ImGui::Checkbox("Generic XGKICK", &m_render_state.enable_generic_xgkick);
|
||||
|
||||
for (size_t i = 0; i < m_bucket_renderers.size(); i++) {
|
||||
auto renderer = m_bucket_renderers[i].get();
|
||||
|
||||
@@ -5,6 +5,7 @@ out vec4 color;
|
||||
in vec4 fragment_color;
|
||||
in vec3 tex_coord;
|
||||
uniform float alpha_reject;
|
||||
uniform float color_mult;
|
||||
|
||||
in flat uvec2 tex_info;
|
||||
|
||||
@@ -41,6 +42,7 @@ void main() {
|
||||
T0.w = 1.0;
|
||||
}
|
||||
color = fragment_color * T0 * 2.0;
|
||||
color.xyz *= color_mult;
|
||||
if (color.a < alpha_reject) {
|
||||
discard;
|
||||
}
|
||||
|
||||
@@ -302,6 +302,9 @@ void interp_time_of_day_fast_avx2(const float weights[8],
|
||||
}
|
||||
#else
|
||||
// unreachable.
|
||||
(void)weights;
|
||||
(void)in;
|
||||
(void)out;
|
||||
ASSERT(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,580 @@
|
||||
|
||||
//--------------------------MIPS2C---------------------
|
||||
#include "game/mips2c/mips2c_private.h"
|
||||
#include "game/kernel/kscheme.h"
|
||||
namespace Mips2C {
|
||||
|
||||
struct RippleVu0 {
|
||||
Vf data_mem[256];
|
||||
void sq(const Vf& reg, u16 addr) {
|
||||
ASSERT(addr < 256);
|
||||
data_mem[addr] = reg;
|
||||
}
|
||||
Vf lq(u16 addr) {
|
||||
ASSERT(addr < 256);
|
||||
return data_mem[addr];
|
||||
}
|
||||
} gRippleVu0;
|
||||
|
||||
namespace ripple_execute_init {
|
||||
struct Cache {
|
||||
void* cos_poly_vec; // *cos-poly-vec*
|
||||
} cache;
|
||||
|
||||
// clang-format off
|
||||
u64 execute(void* ctxt) {
|
||||
auto* c = (ExecutionContext*)ctxt;
|
||||
bool bc = false;
|
||||
c->daddiu(sp, sp, -16); // daddiu sp, sp, -16
|
||||
c->sd(fp, 8, sp); // sd fp, 8(sp)
|
||||
c->mov64(fp, t9); // or fp, t9, r0
|
||||
c->load_symbol(v1, cache.cos_poly_vec); // lw v1, *cos-poly-vec*(s7)
|
||||
c->lqc2(vf7, 0, v1); // lqc2 vf7, 0(v1)
|
||||
c->fprs[f0] = 0.024543691; // lwc1 f0, L50(fp)
|
||||
c->mfc1(v1, f0); // mfc1 v1, f0
|
||||
c->mov128_vf_gpr(vf6, v1); // qmtc2.i vf6, v1
|
||||
c->mov128_gpr_vf(v1, vf6); // qmfc2.i v1, vf6
|
||||
c->addiu(v1, r0, 128); // addiu v1, r0, 128
|
||||
u16 vi2 = c->gpr_src(v1).du16[0]; // ctc2.i vi2, v1
|
||||
c->gprs[v1].du64[0] = vi2; // cfc2.i v1, vi2
|
||||
c->fprs[f0] = 1.0; // lwc1 f0, L61(fp)
|
||||
c->mfc1(v1, f0); // mfc1 v1, f0
|
||||
c->mov128_vf_gpr(vf9, v1); // qmtc2.i vf9, v1
|
||||
c->mov128_gpr_vf(v1, vf9); // qmfc2.i v1, vf9
|
||||
u16 vi1 = 0; // viaddi vi1, vi0, 0
|
||||
c->addiu(v1, r0, 128); // addiu v1, r0, 128
|
||||
c->vmove(DEST::xyzw, vf5, vf6); // vmove.xyzw vf5, vf6
|
||||
|
||||
block_1:
|
||||
c->vmul(DEST::xyzw, vf1, vf5, vf5); // vmul.xyzw vf1, vf5, vf5
|
||||
c->vadda_bc(DEST::xyzw, BC::w, vf0, vf0); // vaddaw.xyzw acc, vf0, vf0
|
||||
c->vadd(DEST::x, vf5, vf5, vf6); // vadd.x vf5, vf5, vf6
|
||||
c->vsub_bc(DEST::y, BC::x, vf9, vf0, vf9); // vsubx.y vf9, vf0, vf9
|
||||
c->vmul(DEST::xyzw, vf2, vf1, vf1); // vmul.xyzw vf2, vf1, vf1
|
||||
c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf7); // vmaddax.xyzw acc, vf1, vf7
|
||||
c->vmul(DEST::xyzw, vf3, vf2, vf1); // vmul.xyzw vf3, vf2, vf1
|
||||
c->vmadda_bc(DEST::xyzw, BC::y, vf2, vf7); // vmadday.xyzw acc, vf2, vf7
|
||||
c->vmul(DEST::xyzw, vf4, vf2, vf2); // vmul.xyzw vf4, vf2, vf2
|
||||
c->vmadda_bc(DEST::xyzw, BC::z, vf3, vf7); // vmaddaz.xyzw acc, vf3, vf7
|
||||
c->daddiu(v1, v1, -1); // daddiu v1, v1, -1
|
||||
c->vmadd_bc(DEST::xyzw, BC::w, vf8, vf4, vf7); // vmaddw.xyzw vf8, vf4, vf7
|
||||
c->vadd_bc(DEST::y, BC::x, vf9, vf9, vf8); // vaddx.y vf9, vf9, vf8
|
||||
c->vsub(DEST::xyzw, vf10, vf0, vf9); // vsub.xyzw vf10, vf0, vf9
|
||||
gRippleVu0.sq(c->vfs[vf9].vf, vi1++); // vsqi.xyzw vf9, vi1
|
||||
c->vmove(DEST::xyzw, vf9, vf8); // vmove.xyzw vf9, vf8
|
||||
bc = c->sgpr64(v1) != 0; // bne v1, r0, L39
|
||||
gRippleVu0.sq(c->vfs[vf10].vf, vi2++); // vsqi.xyzw vf10, vi2
|
||||
if (bc) {goto block_1;} // branch non-likely
|
||||
|
||||
c->gprs[v0].du64[0] = 0; // or v0, r0, r0
|
||||
c->ld(fp, 8, sp); // ld fp, 8(sp)
|
||||
//jr ra // jr ra
|
||||
c->daddiu(sp, sp, 16); // daddiu sp, sp, 16
|
||||
goto end_of_function; // return
|
||||
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
end_of_function:
|
||||
return c->gprs[v0].du64[0];
|
||||
}
|
||||
|
||||
void link() {
|
||||
cache.cos_poly_vec = intern_from_c("*cos-poly-vec*").c();
|
||||
gLinkedFunctionTable.reg("ripple-execute-init", execute, 32);
|
||||
}
|
||||
|
||||
} // namespace ripple_execute_init
|
||||
} // namespace Mips2C
|
||||
|
||||
//--------------------------MIPS2C---------------------
|
||||
#include "game/mips2c/mips2c_private.h"
|
||||
#include "game/kernel/kscheme.h"
|
||||
namespace Mips2C {
|
||||
namespace ripple_create_wave_table {
|
||||
struct Cache {
|
||||
void* fake_scratchpad_data; // *fake-scratchpad-data*
|
||||
void* setting_control; // *setting-control*
|
||||
void* atan; // atan
|
||||
void* cos; // cos
|
||||
void* ntsc; // ntsc
|
||||
void* pal; // pal
|
||||
void* ripple_update_waveform_offs; // ripple-update-waveform-offs
|
||||
void* sin; // sin
|
||||
} cache;
|
||||
|
||||
u64 execute(void* ctxt) {
|
||||
auto* c = (ExecutionContext*)ctxt;
|
||||
bool bc = false;
|
||||
u16 vi1, vi2;
|
||||
u32 call_addr = 0;
|
||||
c->daddiu(sp, sp, -80); // daddiu sp, sp, -80
|
||||
c->sd(ra, 0, sp); // sd ra, 0(sp)
|
||||
c->sd(fp, 8, sp); // sd fp, 8(sp)
|
||||
c->mov64(fp, t9); // or fp, t9, r0
|
||||
c->sq(s4, 16, sp); // sq s4, 16(sp)
|
||||
c->sq(s5, 32, sp); // sq s5, 32(sp)
|
||||
c->sq(gp, 48, sp); // sq gp, 48(sp)
|
||||
c->swc1(f28, 64, sp); // swc1 f28, 64(sp)
|
||||
c->swc1(f30, 68, sp); // swc1 f30, 68(sp)
|
||||
c->mov64(gp, a0); // or gp, a0, r0
|
||||
c->lwu(v1, 4, gp); // lwu v1, 4(gp)
|
||||
bc = c->sgpr64(s7) != c->sgpr64(v1); // bne s7, v1, L30
|
||||
c->mov64(v1, s7); // or v1, s7, r0
|
||||
if (bc) {goto block_9;} // branch non-likely
|
||||
|
||||
c->addiu(s5, r0, 0); // addiu s5, r0, 0
|
||||
//beq r0, r0, L29 // beq r0, r0, L29
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_7; // branch always
|
||||
|
||||
|
||||
block_2:
|
||||
c->addiu(v1, r0, 28); // addiu v1, r0, 28
|
||||
c->mult3(v1, v1, s5); // mult3 v1, v1, s5
|
||||
c->daddiu(v1, v1, 16); // daddiu v1, v1, 16
|
||||
c->daddu(s4, v1, gp); // daddu s4, v1, gp
|
||||
c->load_symbol(t9, cache.atan); // lw t9, atan(s7)
|
||||
c->lh(v1, 10, s4); // lh v1, 10(s4)
|
||||
c->mtc1(f0, v1); // mtc1 f0, v1
|
||||
c->cvtsw(f0, f0); // cvt.s.w f0, f0
|
||||
c->mfc1(a0, f0); // mfc1 a0, f0
|
||||
c->lh(v1, 8, s4); // lh v1, 8(s4)
|
||||
c->mtc1(f0, v1); // mtc1 f0, v1
|
||||
c->cvtsw(f0, f0); // cvt.s.w f0, f0
|
||||
c->mfc1(a1, f0); // mfc1 a1, f0
|
||||
call_addr = c->gprs[t9].du32[0]; // function call:
|
||||
c->sll(v0, ra, 0); // sll v0, ra, 0
|
||||
c->jalr(call_addr); // jalr ra, t9
|
||||
c->mtc1(f28, v0); // mtc1 f28, v0
|
||||
c->fprs[f0] = 16.0; // lwc1 f0, L60(fp)
|
||||
c->lh(v1, 8, s4); // lh v1, 8(s4)
|
||||
c->lh(a0, 8, s4); // lh a0, 8(s4)
|
||||
c->mult3(v1, v1, a0); // mult3 v1, v1, a0
|
||||
c->lh(a0, 10, s4); // lh a0, 10(s4)
|
||||
c->lh(a1, 10, s4); // lh a1, 10(s4)
|
||||
c->mult3(a0, a0, a1); // mult3 a0, a0, a1
|
||||
c->daddu(v1, v1, a0); // daddu v1, v1, a0
|
||||
c->mtc1(f1, v1); // mtc1 f1, v1
|
||||
c->cvtsw(f1, f1); // cvt.s.w f1, f1
|
||||
c->sqrts(f1, f1); // sqrt.s f1, f1
|
||||
c->divs(f30, f0, f1); // div.s f30, f0, f1
|
||||
c->load_symbol(t9, cache.cos); // lw t9, cos(s7)
|
||||
c->mfc1(a0, f28); // mfc1 a0, f28
|
||||
call_addr = c->gprs[t9].du32[0]; // function call:
|
||||
c->sll(v0, ra, 0); // sll v0, ra, 0
|
||||
c->jalr(call_addr); // jalr ra, t9
|
||||
c->mtc1(f0, v0); // mtc1 f0, v0
|
||||
c->fprs[f1] = 65536.0; // lwc1 f1, L52(fp)
|
||||
c->divs(f1, f1, f30); // div.s f1, f1, f30
|
||||
c->muls(f0, f0, f1); // mul.s f0, f0, f1
|
||||
c->swc1(f0, 16, s4); // swc1 f0, 16(s4)
|
||||
c->load_symbol(t9, cache.sin); // lw t9, sin(s7)
|
||||
c->mfc1(a0, f28); // mfc1 a0, f28
|
||||
call_addr = c->gprs[t9].du32[0]; // function call:
|
||||
c->sll(v0, ra, 0); // sll v0, ra, 0
|
||||
c->jalr(call_addr); // jalr ra, t9
|
||||
c->mtc1(f0, v0); // mtc1 f0, v0
|
||||
c->fprs[f1] = 65536.0; // lwc1 f1, L52(fp)
|
||||
c->divs(f1, f1, f30); // div.s f1, f1, f30
|
||||
c->muls(f0, f0, f1); // mul.s f0, f0, f1
|
||||
c->swc1(f0, 20, s4); // swc1 f0, 20(s4)
|
||||
c->load_symbol(v1, cache.setting_control); // lw v1, *setting-control*(s7)
|
||||
c->lwu(v1, 80, v1); // lwu v1, 80(v1)
|
||||
c->load_symbol_addr(a0, cache.ntsc); // daddiu a0, s7, ntsc
|
||||
bc = c->sgpr64(v1) != c->sgpr64(a0); // bne v1, a0, L27
|
||||
c->mov64(a0, s7); // or a0, s7, r0
|
||||
if (bc) {goto block_4;} // branch non-likely
|
||||
|
||||
c->fprs[f0] = 0.016666668; // lwc1 f0, L55(fp)
|
||||
c->fprs[f1] = -65536.0; // lwc1 f1, L53(fp)
|
||||
c->divs(f1, f1, f30); // div.s f1, f1, f30
|
||||
c->muls(f0, f0, f1); // mul.s f0, f0, f1
|
||||
c->lwc1(f1, 12, s4); // lwc1 f1, 12(s4)
|
||||
c->muls(f0, f0, f1); // mul.s f0, f0, f1
|
||||
c->swc1(f0, 24, s4); // swc1 f0, 24(s4)
|
||||
c->mfc1(v1, f0); // mfc1 v1, f0
|
||||
//beq r0, r0, L28 // beq r0, r0, L28
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_6; // branch always
|
||||
|
||||
|
||||
block_4:
|
||||
c->load_symbol_addr(a0, cache.pal); // daddiu a0, s7, pal
|
||||
bc = c->sgpr64(v1) != c->sgpr64(a0); // bne v1, a0, L28
|
||||
c->mov64(v1, s7); // or v1, s7, r0
|
||||
if (bc) {goto block_6;} // branch non-likely
|
||||
|
||||
c->fprs[f0] = 0.02; // lwc1 f0, L51(fp)
|
||||
c->fprs[f1] = -65536.0; // lwc1 f1, L53(fp)
|
||||
c->divs(f1, f1, f30); // div.s f1, f1, f30
|
||||
c->muls(f0, f0, f1); // mul.s f0, f0, f1
|
||||
c->lwc1(f1, 12, s4); // lwc1 f1, 12(s4)
|
||||
c->muls(f0, f0, f1); // mul.s f0, f0, f1
|
||||
c->swc1(f0, 24, s4); // swc1 f0, 24(s4)
|
||||
c->mfc1(v1, f0); // mfc1 v1, f0
|
||||
|
||||
block_6:
|
||||
c->daddiu(s5, s5, 1); // daddiu s5, s5, 1
|
||||
|
||||
block_7:
|
||||
c->lw(v1, 0, gp); // lw v1, 0(gp)
|
||||
c->slt(v1, s5, v1); // slt v1, s5, v1
|
||||
bc = c->sgpr64(v1) != 0; // bne v1, r0, L26
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_2;} // branch non-likely
|
||||
|
||||
c->mov64(v1, s7); // or v1, s7, r0
|
||||
c->mov64(v1, s7); // or v1, s7, r0
|
||||
c->daddiu(v1, s7, 8); // daddiu v1, s7, #t
|
||||
c->sw(v1, 4, gp); // sw v1, 4(gp)
|
||||
|
||||
block_9:
|
||||
c->load_symbol(t9, cache.ripple_update_waveform_offs);// lw t9, ripple-update-waveform-offs(s7)
|
||||
c->mov64(a0, gp); // or a0, gp, r0
|
||||
call_addr = c->gprs[t9].du32[0]; // function call:
|
||||
c->sll(v0, ra, 0); // sll v0, ra, 0
|
||||
c->jalr(call_addr); // jalr ra, t9
|
||||
get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672
|
||||
c->addiu(a0, r0, 64); // addiu a0, r0, 64
|
||||
c->mov64(a1, v1); // or a1, v1, r0
|
||||
|
||||
block_10:
|
||||
c->daddiu(a0, a0, -1); // daddiu a0, a0, -1
|
||||
c->sq(r0, 0, a1); // sq r0, 0(a1)
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
bc = c->sgpr64(a0) != 0; // bne a0, r0, L31
|
||||
c->daddiu(a1, a1, 16); // daddiu a1, a1, 16
|
||||
if (bc) {goto block_10;} // branch non-likely
|
||||
|
||||
c->addiu(a0, r0, 0); // addiu a0, r0, 0
|
||||
//beq r0, r0, L35 // beq r0, r0, L35
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_17; // branch always
|
||||
|
||||
|
||||
block_12:
|
||||
c->addiu(a1, r0, 28); // addiu a1, r0, 28
|
||||
c->mult3(a1, a1, a0); // mult3 a1, a1, a0
|
||||
c->daddiu(a1, a1, 16); // daddiu a1, a1, 16
|
||||
c->daddu(a1, a1, gp); // daddu a1, a1, gp
|
||||
c->fprs[f0] = 16384.0; // lwc1 f0, L54(fp)
|
||||
c->fprs[f1] = 0.00390625; // lwc1 f1, L63(fp)
|
||||
c->lwc1(f2, 4, a1); // lwc1 f2, 4(a1)
|
||||
c->muls(f1, f1, f2); // mul.s f1, f1, f2
|
||||
c->adds(f0, f0, f1); // add.s f0, f0, f1
|
||||
c->fprs[f1] = 0.00390625; // lwc1 f1, L63(fp)
|
||||
c->lwc1(f2, 16, a1); // lwc1 f2, 16(a1)
|
||||
c->muls(f1, f1, f2); // mul.s f1, f1, f2
|
||||
c->fprs[f2] = 0.00390625; // lwc1 f2, L63(fp)
|
||||
c->lwc1(f3, 20, a1); // lwc1 f3, 20(a1)
|
||||
c->muls(f2, f2, f3); // mul.s f2, f2, f3
|
||||
c->lwc1(f3, 0, a1); // lwc1 f3, 0(a1)
|
||||
c->addiu(a1, r0, 255); // addiu a1, r0, 255
|
||||
c->mfc1(a2, f0); // mfc1 a2, f0
|
||||
c->mov128_vf_gpr(vf1, a2); // qmtc2.i vf1, a2
|
||||
c->mfc1(a2, f1); // mfc1 a2, f1
|
||||
c->mov128_vf_gpr(vf2, a2); // qmtc2.i vf2, a2
|
||||
c->mfc1(a2, f2); // mfc1 a2, f2
|
||||
c->mov128_vf_gpr(vf3, a2); // qmtc2.i vf3, a2
|
||||
c->mfc1(a2, f3); // mfc1 a2, f3
|
||||
c->mov128_vf_gpr(vf4, a2); // qmtc2.i vf4, a2
|
||||
vi1 = c->gpr_src(a1).du16[0]; // ctc2.i vi1, a1
|
||||
c->mov64(a1, v1); // or a1, v1, r0
|
||||
c->addiu(a2, r0, 16); // addiu a2, r0, 16
|
||||
c->vmove(DEST::xyzw, vf6, vf0); // vmove.xyzw vf6, vf0
|
||||
|
||||
block_13:
|
||||
c->addiu(a3, r0, 16); // addiu a3, r0, 16
|
||||
c->vmove(DEST::xyzw, vf5, vf0); // vmove.xyzw vf5, vf0
|
||||
|
||||
block_14:
|
||||
c->lw(at, 0, a1); // lw at, 0(a1)
|
||||
c->vadda_bc(DEST::xyzw, BC::x, vf1, vf0); // vaddax.xyzw acc, vf1, vf0
|
||||
c->vmadda(DEST::xyzw, vf2, vf5); // vmadda.xyzw acc, vf2, vf5
|
||||
c->vmadd(DEST::xyzw, vf7, vf3, vf6); // vmadd.xyzw vf7, vf3, vf6
|
||||
c->mov128_vf_gpr(vf10, at); // qmtc2.i vf10, at
|
||||
c->vadd_bc(DEST::xyzw, BC::w, vf5, vf5, vf0); // vaddw.xyzw vf5, vf5, vf0
|
||||
c->vftoi0(DEST::xyzw, vf8, vf7); // vftoi0.xyzw vf8, vf7
|
||||
vi2 = c->vfs[vf8].vf.x_as_u16(); // vmtirx vi2, vf8
|
||||
c->vitof0(DEST::xyzw, vf8, vf8); // vitof0.xyzw vf8, vf8
|
||||
vi2 &= vi1; // Unknown instr: viand vi2, vi2, vi1
|
||||
c->vfs[vf9].vf = gRippleVu0.lq(vi2++); // Unknown instr: vlqi.xyzw vf9, vi2
|
||||
c->vsub(DEST::xyzw, vf7, vf7, vf8); // vsub.xyzw vf7, vf7, vf8
|
||||
c->vadda_bc(DEST::xyzw, BC::x, vf0, vf9); // vaddax.xyzw acc, vf0, vf9
|
||||
c->vmadd_bc(DEST::xyzw, BC::y, vf9, vf7, vf9); // vmaddy.xyzw vf9, vf7, vf9
|
||||
c->vadda_bc(DEST::xyzw, BC::x, vf10, vf0); // vaddax.xyzw acc, vf10, vf0
|
||||
c->vmadd(DEST::xyzw, vf10, vf9, vf4); // vmadd.xyzw vf10, vf9, vf4
|
||||
c->mov128_gpr_vf(at, vf10); // qmfc2.i at, vf10
|
||||
c->sw(at, 0, a1); // sw at, 0(a1)
|
||||
c->daddiu(a3, a3, -1); // daddiu a3, a3, -1
|
||||
bc = c->sgpr64(a3) != 0; // bne a3, r0, L34
|
||||
c->daddiu(a1, a1, 4); // daddiu a1, a1, 4
|
||||
if (bc) {goto block_14;} // branch non-likely
|
||||
|
||||
c->daddiu(a2, a2, -1); // daddiu a2, a2, -1
|
||||
bc = c->sgpr64(a2) != 0; // bne a2, r0, L33
|
||||
c->vadd_bc(DEST::xyzw, BC::w, vf6, vf6, vf0); // vaddw.xyzw vf6, vf6, vf0
|
||||
if (bc) {goto block_13;} // branch non-likely
|
||||
|
||||
c->mov128_gpr_vf(a1, vf6); // qmfc2.i a1, vf6
|
||||
c->daddiu(a0, a0, 1); // daddiu a0, a0, 1
|
||||
|
||||
block_17:
|
||||
c->lw(a1, 0, gp); // lw a1, 0(gp)
|
||||
c->slt(a1, a0, a1); // slt a1, a0, a1
|
||||
bc = c->sgpr64(a1) != 0; // bne a1, r0, L32
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_12;} // branch non-likely
|
||||
|
||||
c->mov64(a0, s7); // or a0, s7, r0
|
||||
c->mov64(a0, s7); // or a0, s7, r0
|
||||
c->fprs[f1] = 128.0; // lwc1 f1, L57(fp)
|
||||
c->fprs[f0] = 255.0; // lwc1 f0, L56(fp)
|
||||
c->lwc1(f2, 12, gp); // lwc1 f2, 12(gp)
|
||||
c->mfc1(a0, f2); // mfc1 a0, f2
|
||||
c->mov128_vf_gpr(vf16, a0); // qmtc2.i vf16, a0
|
||||
c->mfc1(a0, f1); // mfc1 a0, f1
|
||||
c->mov128_vf_gpr(vf14, a0); // qmtc2.i vf14, a0
|
||||
c->mfc1(a0, f0); // mfc1 a0, f0
|
||||
c->mov128_vf_gpr(vf15, a0); // qmtc2.i vf15, a0
|
||||
c->vmax_bc(DEST::xyzw, BC::x, vf16, vf0, vf16); // vmaxx.xyzw vf16, vf0, vf16
|
||||
c->vmini_bc(DEST::w, BC::x, vf16, vf0, vf0); // vminix.w vf16, vf0, vf0
|
||||
c->mov64(v1, v1); // or v1, v1, r0
|
||||
c->addiu(v0, r0, 15); // addiu v0, r0, 15
|
||||
|
||||
block_19:
|
||||
c->addiu(a0, r0, 15); // addiu a0, r0, 15
|
||||
// nop // sll r0, r0, 0
|
||||
|
||||
block_20:
|
||||
c->addiu(a2, r0, 4); // addiu a2, r0, 4
|
||||
c->addiu(at, r0, -60); // addiu at, r0, -60
|
||||
c->movz(a2, at, a0); // movz a2, at, a0
|
||||
c->addiu(a1, r0, 64); // addiu a1, r0, 64
|
||||
c->addiu(at, r0, -960); // addiu at, r0, -960
|
||||
c->daddu(a2, a2, v1); // daddu a2, a2, v1
|
||||
c->movz(a1, at, v0); // movz a1, at, v0
|
||||
c->lw(at, 0, v1); // lw at, 0(v1)
|
||||
c->lw(a2, 0, a2); // lw a2, 0(a2)
|
||||
c->daddu(a1, a1, v1); // daddu a1, a1, v1
|
||||
c->lw(a1, 0, a1); // lw a1, 0(a1)
|
||||
c->mov128_vf_gpr(vf11, at); // qmtc2.i vf11, at
|
||||
c->mov128_vf_gpr(vf12, a2); // qmtc2.i vf12, a2
|
||||
c->mov128_vf_gpr(vf13, a1); // qmtc2.i vf13, a1
|
||||
c->vadd_bc(DEST::xyzw, BC::x, vf11, vf0, vf11); // vaddx.xyzw vf11, vf0, vf11
|
||||
c->vsub_bc(DEST::y, BC::x, vf11, vf11, vf12); // vsubx.y vf11, vf11, vf12
|
||||
c->vsub_bc(DEST::z, BC::x, vf11, vf11, vf13); // vsubx.z vf11, vf11, vf13
|
||||
c->vmul(DEST::yzw, vf11, vf11, vf16); // vmul.yzw vf11, vf11, vf16
|
||||
c->vadd_bc(DEST::xyzw, BC::x, vf11, vf11, vf14); // vaddx.xyzw vf11, vf11, vf14
|
||||
c->vmax_bc(DEST::xyzw, BC::x, vf11, vf11, vf0); // vmaxx.xyzw vf11, vf11, vf0
|
||||
c->vmini_bc(DEST::xyzw, BC::x, vf11, vf11, vf15); // vminix.xyzw vf11, vf11, vf15
|
||||
c->vftoi0(DEST::xyzw, vf11, vf11); // vftoi0.xyzw vf11, vf11
|
||||
c->mov128_gpr_vf(at, vf11); // qmfc2.i at, vf11
|
||||
c->ppach(at, at, at); // ppach at, at, at
|
||||
c->ppacb(at, at, at); // ppacb at, at, at
|
||||
c->sw(at, 1024, v1); // sw at, 1024(v1)
|
||||
c->daddiu(v1, v1, 4); // daddiu v1, v1, 4
|
||||
bc = c->sgpr64(a0) != 0; // bne a0, r0, L37
|
||||
c->daddiu(a0, a0, -1); // daddiu a0, a0, -1
|
||||
if (bc) {goto block_20;} // branch non-likely
|
||||
|
||||
bc = c->sgpr64(v0) != 0; // bne v0, r0, L36
|
||||
c->daddiu(v0, v0, -1); // daddiu v0, v0, -1
|
||||
if (bc) {goto block_19;} // branch non-likely
|
||||
|
||||
c->ld(ra, 0, sp); // ld ra, 0(sp)
|
||||
c->ld(fp, 8, sp); // ld fp, 8(sp)
|
||||
c->lwc1(f30, 68, sp); // lwc1 f30, 68(sp)
|
||||
c->lwc1(f28, 64, sp); // lwc1 f28, 64(sp)
|
||||
c->lq(gp, 48, sp); // lq gp, 48(sp)
|
||||
c->lq(s5, 32, sp); // lq s5, 32(sp)
|
||||
c->lq(s4, 16, sp); // lq s4, 16(sp)
|
||||
//jr ra // jr ra
|
||||
c->daddiu(sp, sp, 80); // daddiu sp, sp, 80
|
||||
goto end_of_function; // return
|
||||
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
end_of_function:
|
||||
return c->gprs[v0].du64[0];
|
||||
}
|
||||
|
||||
void link() {
|
||||
cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c();
|
||||
cache.setting_control = intern_from_c("*setting-control*").c();
|
||||
cache.atan = intern_from_c("atan").c();
|
||||
cache.cos = intern_from_c("cos").c();
|
||||
cache.ntsc = intern_from_c("ntsc").c();
|
||||
cache.pal = intern_from_c("pal").c();
|
||||
cache.ripple_update_waveform_offs = intern_from_c("ripple-update-waveform-offs").c();
|
||||
cache.sin = intern_from_c("sin").c();
|
||||
gLinkedFunctionTable.reg("ripple-create-wave-table", execute, 128);
|
||||
}
|
||||
|
||||
} // namespace ripple_create_wave_table
|
||||
} // namespace Mips2C
|
||||
|
||||
//--------------------------MIPS2C---------------------
|
||||
#include "game/mips2c/mips2c_private.h"
|
||||
#include "game/kernel/kscheme.h"
|
||||
namespace Mips2C {
|
||||
namespace ripple_apply_wave_table {
|
||||
struct Cache {
|
||||
void* fake_scratchpad_data; // *fake-scratchpad-data*
|
||||
} cache;
|
||||
|
||||
u64 execute(void* ctxt) {
|
||||
auto* c = (ExecutionContext*)ctxt;
|
||||
|
||||
bool bc = false;
|
||||
get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672
|
||||
c->daddiu(v1, v1, 1024); // daddiu v1, v1, 1024
|
||||
c->lwu(a1, 4, a0); // lwu a1, 4(a0)
|
||||
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
|
||||
c->lwu(a2, 8, a0); // lwu a2, 8(a0)
|
||||
c->lwu(a3, 12, a0); // lwu a3, 12(a0)
|
||||
c->lhu(a0, 18, a0); // lhu a0, 18(a0)
|
||||
c->addiu(t0, r0, 0); // addiu t0, r0, 0
|
||||
//beq r0, r0, L24 // beq r0, r0, L24
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_4; // branch always
|
||||
|
||||
|
||||
block_1:
|
||||
c->lbu(t1, 0, a3); // lbu t1, 0(a3)
|
||||
c->lbu(t3, 0, a1); // lbu t3, 0(a1)
|
||||
c->daddiu(t3, t3, 3); // daddiu t3, t3, 3
|
||||
c->dsrl(t3, t3, 2); // dsrl t3, t3, 2
|
||||
c->dsll(t3, t3, 4); // dsll t3, t3, 4
|
||||
c->daddu(t2, t2, t3); // daddu t2, t2, t3
|
||||
c->mov64(t4, t2); // or t4, t2, r0
|
||||
c->mov64(t3, t1); // or t3, t1, r0
|
||||
c->mov64(t5, t4); // or t5, t4, r0
|
||||
c->mov64(t4, a2); // or t4, a2, r0
|
||||
|
||||
block_2:
|
||||
c->lb(t6, 0, t4); // lb t6, 0(t4)
|
||||
c->lb(t7, 1, t4); // lb t7, 1(t4)
|
||||
c->andi(t6, t6, 15); // andi t6, t6, 15
|
||||
c->andi(t7, t7, 15); // andi t7, t7, 15
|
||||
c->sll(t7, t7, 4); // sll t7, t7, 4
|
||||
c->daddu(t6, t6, t7); // daddu t6, t6, t7
|
||||
c->sll(t6, t6, 2); // sll t6, t6, 2
|
||||
c->daddu(t8, t6, v1); // daddu t8, t6, v1
|
||||
c->lb(t6, 0, t8); // lb t6, 0(t8)
|
||||
c->lb(t7, 1, t8); // lb t7, 1(t8)
|
||||
c->lb(t8, 2, t8); // lb t8, 2(t8)
|
||||
c->sb(t6, 7, t5); // sb t6, 7(t5)
|
||||
c->sb(t7, 2, t5); // sb t7, 2(t5)
|
||||
c->sb(t8, 10, t5); // sb t8, 10(t5)
|
||||
c->daddiu(t3, t3, -1); // daddiu t3, t3, -1
|
||||
c->daddiu(t4, t4, 2); // daddiu t4, t4, 2
|
||||
bc = c->sgpr64(t3) != 0; // bne t3, r0, L23
|
||||
c->daddiu(t5, t5, 12); // daddiu t5, t5, 12
|
||||
if (bc) {goto block_2;} // branch non-likely
|
||||
|
||||
c->lbu(t3, 2, a1); // lbu t3, 2(a1)
|
||||
c->lbu(t4, 1, a1); // lbu t4, 1(a1)
|
||||
c->daddiu(t4, t4, 3); // daddiu t4, t4, 3
|
||||
c->dsrl(t4, t4, 2); // dsrl t4, t4, 2
|
||||
c->daddu(t3, t3, t4); // daddu t3, t3, t4
|
||||
c->dsll(t3, t3, 4); // dsll t3, t3, 4
|
||||
c->daddu(t2, t2, t3); // daddu t2, t2, t3
|
||||
c->lbu(t3, 3, a1); // lbu t3, 3(a1)
|
||||
c->dsll(t3, t3, 1); // dsll t3, t3, 1
|
||||
c->daddiu(t3, t3, 4); // daddiu t3, t3, 4
|
||||
c->daddu(a1, a1, t3); // daddu a1, a1, t3
|
||||
c->dsll(t1, t1, 1); // dsll t1, t1, 1
|
||||
c->daddiu(t1, t1, 15); // daddiu t1, t1, 15
|
||||
c->andi(t1, t1, 65520); // andi t1, t1, 65520
|
||||
c->daddu(a2, a2, t1); // daddu a2, a2, t1
|
||||
c->daddiu(a3, a3, 2); // daddiu a3, a3, 2
|
||||
c->mov64(t1, a3); // or t1, a3, r0
|
||||
c->daddiu(t0, t0, 1); // daddiu t0, t0, 1
|
||||
|
||||
block_4:
|
||||
c->slt(t1, t0, a0); // slt t1, t0, a0
|
||||
bc = c->sgpr64(t1) != 0; // bne t1, r0, L22
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_1;} // branch non-likely
|
||||
|
||||
c->mov64(v1, s7); // or v1, s7, r0
|
||||
c->mov64(v0, s7); // or v0, s7, r0
|
||||
//jr ra // jr ra
|
||||
c->daddu(sp, sp, r0); // daddu sp, sp, r0
|
||||
goto end_of_function; // return
|
||||
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
end_of_function:
|
||||
return c->gprs[v0].du64[0];
|
||||
}
|
||||
|
||||
void link() {
|
||||
cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c();
|
||||
gLinkedFunctionTable.reg("ripple-apply-wave-table", execute, 128);
|
||||
}
|
||||
|
||||
} // namespace ripple_apply_wave_table
|
||||
} // namespace Mips2C
|
||||
|
||||
//--------------------------MIPS2C---------------------
|
||||
#include "game/mips2c/mips2c_private.h"
|
||||
#include "game/kernel/kscheme.h"
|
||||
namespace Mips2C {
|
||||
namespace ripple_matrix_scale {
|
||||
u64 execute(void* ctxt) {
|
||||
auto* c = (ExecutionContext*)ctxt;
|
||||
bool bc = false;
|
||||
c->mov128_vf_gpr(vf1, a3); // qmtc2.i vf1, a3
|
||||
c->mov128_vf_gpr(vf2, a2); // qmtc2.i vf2, a2
|
||||
c->mov128_vf_gpr(vf3, t0); // qmtc2.i vf3, t0
|
||||
c->mov64(v1, t1); // or v1, t1, r0
|
||||
|
||||
block_1:
|
||||
c->lqc2(vf5, 16, a0); // lqc2 vf5, 16(a0)
|
||||
c->lqc2(vf6, 48, a0); // lqc2 vf6, 48(a0)
|
||||
c->lqc2(vf7, 64, a0); // lqc2 vf7, 64(a0)
|
||||
c->lqc2(vf8, 96, a0); // lqc2 vf8, 96(a0)
|
||||
c->vmul_bc(DEST::xyzw, BC::x, vf4, vf5, vf2); // vmulx.xyzw vf4, vf5, vf2
|
||||
c->vmul_bc(DEST::xyzw, BC::x, vf5, vf5, vf1); // vmulx.xyzw vf5, vf5, vf1
|
||||
c->lq(a2, 0, a0); // lq a2, 0(a0)
|
||||
c->vmul_bc(DEST::xyzw, BC::x, vf7, vf7, vf3); // vmulx.xyzw vf7, vf7, vf3
|
||||
c->lq(v1, 32, a0); // lq v1, 32(a0)
|
||||
c->vmul_bc(DEST::xyzw, BC::x, vf8, vf8, vf3); // vmulx.xyzw vf8, vf8, vf3
|
||||
c->sq(a2, 0, t1); // sq a2, 0(t1)
|
||||
c->lq(a2, 80, a0); // lq a2, 80(a0)
|
||||
c->vsub(DEST::xyzw, vf6, vf6, vf4); // vsub.xyzw vf6, vf6, vf4
|
||||
c->sq(v1, 32, t1); // sq v1, 32(t1)
|
||||
c->sqc2(vf5, 16, t1); // sqc2 vf5, 16(t1)
|
||||
c->sq(a2, 80, t1); // sq a2, 80(t1)
|
||||
c->daddiu(a1, a1, -1); // daddiu a1, a1, -1
|
||||
c->sqc2(vf7, 64, t1); // sqc2 vf7, 64(t1)
|
||||
c->addiu(a0, a0, 128); // addiu a0, a0, 128
|
||||
c->sqc2(vf6, 48, t1); // sqc2 vf6, 48(t1)
|
||||
c->addiu(t1, t1, 128); // addiu t1, t1, 128
|
||||
bc = c->sgpr64(a1) != 0; // bne a1, r0, L12
|
||||
c->sqc2(vf8, -32, t1); // sqc2 vf8, -32(t1)
|
||||
if (bc) {goto block_1;} // branch non-likely
|
||||
|
||||
c->gprs[v0].du64[0] = 0; // or v0, r0, r0
|
||||
//jr ra // jr ra
|
||||
c->daddu(sp, sp, r0); // daddu sp, sp, r0
|
||||
goto end_of_function; // return
|
||||
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
end_of_function:
|
||||
return c->gprs[v0].du64[0];
|
||||
}
|
||||
|
||||
void link() {
|
||||
gLinkedFunctionTable.reg("ripple-matrix-scale", execute, 128);
|
||||
}
|
||||
|
||||
} // namespace ripple_matrix_scale
|
||||
} // namespace Mips2C
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "third-party/fmt/core.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "common/dma/dma.h"
|
||||
#include "game/common/vu.h"
|
||||
|
||||
// This file contains utility functions for code generated by the mips2c pass.
|
||||
// This is only useful for
|
||||
@@ -61,6 +62,7 @@ enum Gpr {
|
||||
};
|
||||
|
||||
enum VfName {
|
||||
vf00 = 0,
|
||||
vf0 = 0,
|
||||
vf1 = 1,
|
||||
vf01 = 1,
|
||||
@@ -104,6 +106,24 @@ enum VfName {
|
||||
vf31 = 31,
|
||||
};
|
||||
|
||||
enum ViName {
|
||||
vi00 = 0,
|
||||
vi01 = 1,
|
||||
vi02 = 2,
|
||||
vi03 = 3,
|
||||
vi04 = 4,
|
||||
vi05 = 5,
|
||||
vi06 = 6,
|
||||
vi07 = 7,
|
||||
vi08 = 8,
|
||||
vi09 = 9,
|
||||
vi10 = 10,
|
||||
vi11 = 11,
|
||||
vi12 = 12,
|
||||
vi13 = 13,
|
||||
vi14 = 14,
|
||||
};
|
||||
|
||||
enum FprName {
|
||||
f0 = 0,
|
||||
f1 = 1,
|
||||
@@ -161,17 +181,47 @@ enum class DEST {
|
||||
|
||||
enum class BC { x = 0, y = 1, z = 2, w = 3 };
|
||||
|
||||
struct Mips2c_vf {
|
||||
union {
|
||||
u64 du64[2];
|
||||
s64 ds64[2];
|
||||
u32 du32[4];
|
||||
s32 ds32[4];
|
||||
u16 du16[8];
|
||||
s16 ds16[8];
|
||||
u8 du8[16];
|
||||
s8 ds8[16];
|
||||
float f[4];
|
||||
Vf vf;
|
||||
};
|
||||
};
|
||||
|
||||
struct Mips2c_acc {
|
||||
union {
|
||||
u64 du64[2];
|
||||
s64 ds64[2];
|
||||
u32 du32[4];
|
||||
s32 ds32[4];
|
||||
u16 du16[8];
|
||||
s16 ds16[8];
|
||||
u8 du8[16];
|
||||
s8 ds8[16];
|
||||
float f[4];
|
||||
Accumulator vf;
|
||||
};
|
||||
};
|
||||
|
||||
struct ExecutionContext {
|
||||
// EE general purpose registers
|
||||
u128 gprs[32];
|
||||
// EE fprs
|
||||
float fprs[32];
|
||||
// VU0 vf registers
|
||||
u128 vfs[32];
|
||||
|
||||
u128 acc;
|
||||
Mips2c_vf vfs[32];
|
||||
Mips2c_acc acc;
|
||||
|
||||
float Q;
|
||||
float I;
|
||||
|
||||
u128 hi, lo;
|
||||
|
||||
@@ -181,9 +231,9 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
u128 vf_src(int idx) {
|
||||
Mips2c_vf vf_src(int idx) {
|
||||
if (idx == 0) {
|
||||
u128 result;
|
||||
Mips2c_vf result;
|
||||
result.f[0] = 0;
|
||||
result.f[1] = 0;
|
||||
result.f[2] = 0;
|
||||
@@ -215,6 +265,10 @@ struct ExecutionContext {
|
||||
gprs[gpr].ds64[0] = val; // sign extend and set
|
||||
}
|
||||
|
||||
void load_symbol_addr(int gpr, void* sym_addr) {
|
||||
gprs[gpr].du64[0] = ((const u8*)sym_addr) - g_ee_main_mem;
|
||||
}
|
||||
|
||||
void lbu(int dst, int offset, int src) {
|
||||
u8 val;
|
||||
memcpy(&val, g_ee_main_mem + gpr_src(src).du32[0] + offset, 1);
|
||||
@@ -228,6 +282,7 @@ struct ExecutionContext {
|
||||
}
|
||||
|
||||
void lqc2(int vf, int offset, int gpr) {
|
||||
ASSERT(((gpr_src(gpr).du32[0] + offset) & 0xf) == 0);
|
||||
memcpy(&vfs[vf], g_ee_main_mem + gpr_src(gpr).du32[0] + offset, 16);
|
||||
}
|
||||
|
||||
@@ -354,6 +409,19 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void pextuh(int dst, int src0, int src1) {
|
||||
auto s0 = gpr_src(src0);
|
||||
auto s1 = gpr_src(src1);
|
||||
gprs[dst].du16[0] = s1.du16[4];
|
||||
gprs[dst].du16[1] = s0.du16[4];
|
||||
gprs[dst].du16[2] = s1.du16[5];
|
||||
gprs[dst].du16[3] = s0.du16[5];
|
||||
gprs[dst].du16[4] = s1.du16[6];
|
||||
gprs[dst].du16[5] = s0.du16[6];
|
||||
gprs[dst].du16[6] = s1.du16[7];
|
||||
gprs[dst].du16[7] = s0.du16[7];
|
||||
}
|
||||
|
||||
void pextuw(int dst, int src0, int src1) {
|
||||
auto s0 = gpr_src(src0);
|
||||
auto s1 = gpr_src(src1);
|
||||
@@ -382,8 +450,8 @@ struct ExecutionContext {
|
||||
void pcpyld(int dst, int src0, int src1) {
|
||||
auto s0 = gpr_src(src0);
|
||||
auto s1 = gpr_src(src1);
|
||||
gprs[dst].du64[0] = s1.du64[0];
|
||||
gprs[dst].du64[1] = s0.du64[0];
|
||||
gprs[dst].du64[0] = s1.du64[0];
|
||||
}
|
||||
|
||||
void pexew(int dst, int src) {
|
||||
@@ -573,10 +641,25 @@ struct ExecutionContext {
|
||||
void psraw(int dest, int src, int sa) {
|
||||
auto s = gpr_src(src);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gprs[dest].ds32[i] = s.ds32[i] >> (sa & 0x1f);
|
||||
gprs[dest].du32[i] = s.ds32[i] >> (sa & 0x1f);
|
||||
}
|
||||
}
|
||||
|
||||
void psllw(int dest, int src, int sa) {
|
||||
auto s = gpr_src(src);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gprs[dest].ds32[i] = s.ds32[i] << (sa & 0x1f);
|
||||
}
|
||||
}
|
||||
|
||||
void prot3w(int dst, int src) {
|
||||
auto s = gpr_src(src);
|
||||
gprs[dst].du32[0] = s.du32[1];
|
||||
gprs[dst].du32[1] = s.du32[2];
|
||||
gprs[dst].du32[2] = s.du32[0];
|
||||
gprs[dst].du32[3] = s.du32[3];
|
||||
}
|
||||
|
||||
void paddh(int dest, int rs, int rt) {
|
||||
auto s = gpr_src(rs);
|
||||
auto t = gpr_src(rt);
|
||||
@@ -596,6 +679,21 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void pand(int dst, int rs, int rt) {
|
||||
auto s = gpr_src(rs);
|
||||
auto t = gpr_src(rt);
|
||||
gprs[dst].du64[0] = s.du64[0] & t.du64[0];
|
||||
gprs[dst].du64[1] = s.du64[1] & t.du64[1];
|
||||
}
|
||||
|
||||
void pceqb(int dst, int rs, int rt) {
|
||||
auto s = gpr_src(rs);
|
||||
auto t = gpr_src(rt);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
gprs[dst].du8[i] = (s.du8[i] == t.du8[i]) ? 0xff : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void pmfhl_lh(int dest) {
|
||||
gprs[dest].du16[0] = lo.du16[0];
|
||||
gprs[dest].du16[1] = lo.du16[2];
|
||||
@@ -695,6 +793,17 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void vadda_bc(DEST mask, BC bc, int src0, int src1) {
|
||||
auto s0 = vf_src(src0);
|
||||
auto s1 = vf_src(src1);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
acc.f[i] = s0.f[i] + s1.f[(int)bc];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vmadda_bc(DEST mask, BC bc, int src0, int src1) {
|
||||
auto s0 = vf_src(src0);
|
||||
auto s1 = vf_src(src1);
|
||||
@@ -706,6 +815,17 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void vmadda(DEST mask, int src0, int src1) {
|
||||
auto s0 = vf_src(src0);
|
||||
auto s1 = vf_src(src1);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
acc.f[i] += s0.f[i] * s1.f[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vmsuba_bc(DEST mask, BC bc, int src0, int src1) {
|
||||
auto s0 = vf_src(src0);
|
||||
auto s1 = vf_src(src1);
|
||||
@@ -728,6 +848,17 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void vmadd(DEST mask, int dst, int src0, int src1) {
|
||||
auto s0 = vf_src(src0);
|
||||
auto s1 = vf_src(src1);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
vfs[dst].f[i] = acc.f[i] + s0.f[i] * s1.f[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vmsub_bc(DEST mask, BC bc, int dst, int src0, int src1) {
|
||||
auto s0 = vf_src(src0);
|
||||
auto s1 = vf_src(src1);
|
||||
@@ -810,6 +941,14 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void slt(int dst, int src0, int src1) {
|
||||
gprs[dst].du64[0] = (gpr_src(src0).ds64[0] < gpr_src(src1).ds64[0]) ? 1 : 0;
|
||||
}
|
||||
|
||||
void sltu(int dst, int src0, int src1) {
|
||||
gprs[dst].du64[0] = (gpr_src(src0).du64[0] < gpr_src(src1).du64[0]) ? 1 : 0;
|
||||
}
|
||||
|
||||
void sll(int dst, int src, int sa) {
|
||||
u32 value = gpr_src(src).du32[0] << sa;
|
||||
s32 value_signed = value;
|
||||
@@ -827,6 +966,9 @@ struct ExecutionContext {
|
||||
void dsrav(int dst, int src, int sa) {
|
||||
gprs[dst].ds64[0] = gpr_src(src).ds64[0] >> gpr_src(sa).du32[0];
|
||||
}
|
||||
void dsllv(int dst, int src, int sa) {
|
||||
gprs[dst].ds64[0] = gpr_src(src).ds64[0] << (gpr_src(sa).du32[0] & 0b111111);
|
||||
}
|
||||
void dsra32(int dst, int src, int sa) { gprs[dst].ds64[0] = gpr_src(src).ds64[0] >> (32 + sa); }
|
||||
void dsrl32(int dst, int src, int sa) { gprs[dst].du64[0] = gpr_src(src).du64[0] >> (32 + sa); }
|
||||
void sra(int dst, int src, int sa) { gprs[dst].ds64[0] = gpr_src(src).ds32[0] >> sa; }
|
||||
@@ -987,8 +1129,8 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void mov128_vf_gpr(int dst, int src) { vfs[dst] = gpr_src(src); }
|
||||
void mov128_gpr_vf(int dst, int src) { gprs[dst] = vf_src(src); }
|
||||
void mov128_vf_gpr(int dst, int src) { memcpy(vfs[dst].f, gpr_src(src).f, 16); }
|
||||
void mov128_gpr_vf(int dst, int src) { memcpy(gprs[dst].f, vf_src(src).f, 16); }
|
||||
void mov128_gpr_gpr(int dst, int src) { gprs[dst] = gpr_src(src); }
|
||||
|
||||
void vitof0(DEST mask, int dst, int src) {
|
||||
@@ -1106,6 +1248,95 @@ struct ExecutionContext {
|
||||
vfs[dst].f[2] = acc.f[2] - s0.f[0] * s1.f[1];
|
||||
}
|
||||
|
||||
// copied from PCSX2, to handle the weirdo special case in lwr.
|
||||
static constexpr u32 LWL_MASK[4] = {0xffffff, 0x0000ffff, 0x000000ff, 0x00000000};
|
||||
static constexpr u32 LWR_MASK[4] = {0x000000, 0xff000000, 0xffff0000, 0xffffff00};
|
||||
static constexpr u8 LWL_SHIFT[4] = {24, 16, 8, 0};
|
||||
static constexpr u8 LWR_SHIFT[4] = {0, 8, 16, 24};
|
||||
|
||||
void lwl(int dst, int offset, int addr_reg) {
|
||||
s32 addr = sgpr64(addr_reg) + offset;
|
||||
u32 shift = addr & 3;
|
||||
|
||||
u32 mem;
|
||||
memcpy(&mem, g_ee_main_mem + (addr & ~3), 4);
|
||||
|
||||
if (!dst)
|
||||
return;
|
||||
|
||||
// ensure the compiler does correct sign extension into 64 bits by using s32
|
||||
gprs[dst].ds64[0] = (s32)((gprs[dst].du32[0] & LWL_MASK[shift]) | (mem << LWL_SHIFT[shift]));
|
||||
|
||||
/*
|
||||
Mem = 1234. Reg = abcd
|
||||
(result is always sign extended into the upper 32 bits of the Rt)
|
||||
|
||||
0 4bcd (mem << 24) | (reg & 0x00ffffff)
|
||||
1 34cd (mem << 16) | (reg & 0x0000ffff)
|
||||
2 234d (mem << 8) | (reg & 0x000000ff)
|
||||
3 1234 (mem ) | (reg & 0x00000000)
|
||||
*/
|
||||
}
|
||||
|
||||
void lwr(int dst, int offset, int addr_reg) {
|
||||
s32 addr = sgpr64(addr_reg) + offset;
|
||||
u32 shift = addr & 3;
|
||||
|
||||
u32 mem;
|
||||
memcpy(&mem, g_ee_main_mem + (addr & ~3), 4);
|
||||
|
||||
if (!dst)
|
||||
return;
|
||||
|
||||
// Use unsigned math here, and conditionally sign extend below, when needed.
|
||||
mem = (gprs[dst].du32[0] & LWR_MASK[shift]) | (mem >> LWR_SHIFT[shift]);
|
||||
|
||||
if (shift == 0) {
|
||||
// This special case requires sign extension into the full 64 bit dest.
|
||||
gprs[dst].ds64[0] = (s32)mem;
|
||||
} else {
|
||||
// This case sets the lower 32 bits of the target register. Upper
|
||||
// 32 bits are always preserved.
|
||||
gprs[dst].du32[0] = mem;
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr u64 LDL_MASK[8] = {
|
||||
0x00ffffffffffffffULL, 0x0000ffffffffffffULL, 0x000000ffffffffffULL, 0x00000000ffffffffULL,
|
||||
0x0000000000ffffffULL, 0x000000000000ffffULL, 0x00000000000000ffULL, 0x0000000000000000ULL};
|
||||
static constexpr u64 LDR_MASK[8] = {
|
||||
0x0000000000000000ULL, 0xff00000000000000ULL, 0xffff000000000000ULL, 0xffffff0000000000ULL,
|
||||
0xffffffff00000000ULL, 0xffffffffff000000ULL, 0xffffffffffff0000ULL, 0xffffffffffffff00ULL};
|
||||
|
||||
static constexpr u8 LDR_SHIFT[8] = {0, 8, 16, 24, 32, 40, 48, 56};
|
||||
static constexpr u8 LDL_SHIFT[8] = {56, 48, 40, 32, 24, 16, 8, 0};
|
||||
|
||||
void ldl(int dst, int offset, int addr_reg) {
|
||||
u32 addr = sgpr64(addr_reg) + offset;
|
||||
u32 shift = addr & 7;
|
||||
|
||||
u64 mem;
|
||||
// memRead64(addr & ~7, &mem);
|
||||
memcpy(&mem, g_ee_main_mem + (addr & ~7), 8);
|
||||
|
||||
if (!dst)
|
||||
return;
|
||||
gprs[dst].du64[0] = (gprs[dst].du64[0] & LDL_MASK[shift]) | (mem << LDL_SHIFT[shift]);
|
||||
}
|
||||
|
||||
void ldr(int dst, int offset, int addr_reg) {
|
||||
u32 addr = sgpr64(addr_reg) + offset;
|
||||
u32 shift = addr & 7;
|
||||
|
||||
u64 mem;
|
||||
// memRead64(addr & ~7, &mem);
|
||||
memcpy(&mem, g_ee_main_mem + (addr & ~7), 8);
|
||||
|
||||
if (!dst)
|
||||
return;
|
||||
gprs[dst].du64[0] = (gprs[dst].du64[0] & LDR_MASK[shift]) | (mem >> LDR_SHIFT[shift]);
|
||||
}
|
||||
|
||||
std::string print_vf_float(int vf) {
|
||||
auto src = vf_src(vf);
|
||||
return fmt::format("{} {} {} {}", src.f[0], src.f[1], src.f[2], src.f[3]);
|
||||
@@ -1218,6 +1449,7 @@ inline void spad_to_dma_blerc_chain(void* spad_sym_addr, u32 sadr, u32 tadr) {
|
||||
u32 spad_addr_goal;
|
||||
memcpy(&spad_addr_goal, spad_sym_addr, 4);
|
||||
void* spad_addr_c = g_ee_main_mem + spad_addr_goal;
|
||||
ASSERT(sadr < 0x4000);
|
||||
emulate_dma(g_ee_main_mem, spad_addr_c, tadr, sadr);
|
||||
}
|
||||
} // namespace Mips2C
|
||||
|
||||
@@ -224,6 +224,42 @@ extern void link();
|
||||
namespace setup_blerc_chains_for_one_fragment {
|
||||
extern void link();
|
||||
}
|
||||
namespace generic_merc_init_asm {
|
||||
extern void link();
|
||||
}
|
||||
namespace generic_merc_execute_asm {
|
||||
extern void link();
|
||||
}
|
||||
namespace mercneric_convert {
|
||||
extern void link();
|
||||
}
|
||||
namespace generic_prepare_dma_double {
|
||||
extern void link();
|
||||
}
|
||||
namespace generic_light_proc {
|
||||
extern void link();
|
||||
}
|
||||
namespace generic_envmap_proc {
|
||||
extern void link();
|
||||
}
|
||||
namespace high_speed_reject {
|
||||
extern void link();
|
||||
}
|
||||
namespace generic_prepare_dma_single {
|
||||
extern void link();
|
||||
}
|
||||
namespace ripple_create_wave_table {
|
||||
extern void link();
|
||||
}
|
||||
namespace ripple_execute_init {
|
||||
extern void link();
|
||||
}
|
||||
namespace ripple_apply_wave_table {
|
||||
extern void link();
|
||||
}
|
||||
namespace ripple_matrix_scale {
|
||||
extern void link();
|
||||
}
|
||||
LinkedFunctionTable gLinkedFunctionTable;
|
||||
Rng gRng;
|
||||
std::unordered_map<std::string, std::vector<void (*)()>> gMips2CLinkCallbacks = {
|
||||
@@ -259,7 +295,16 @@ std::unordered_map<std::string, std::vector<void (*)()>> gMips2CLinkCallbacks =
|
||||
{"joint", {calc_animation_from_spr::link, cspace_parented_transformq_joint::link}},
|
||||
{"bones",
|
||||
{bones_mtx_calc::link, draw_bones_merc::link, draw_bones_check_longest_edge_asm::link}},
|
||||
{"merc-blend-shape", {blerc_execute::link, setup_blerc_chains_for_one_fragment::link}}};
|
||||
{"merc-blend-shape", {blerc_execute::link, setup_blerc_chains_for_one_fragment::link}},
|
||||
{"generic-merc",
|
||||
{generic_merc_init_asm::link, generic_merc_execute_asm::link, mercneric_convert::link,
|
||||
high_speed_reject::link}},
|
||||
{"generic-effect",
|
||||
{generic_prepare_dma_double::link, generic_light_proc::link, generic_envmap_proc::link,
|
||||
generic_prepare_dma_single::link}},
|
||||
{"ripple",
|
||||
{ripple_execute_init::link, ripple_create_wave_table::link, ripple_apply_wave_table::link,
|
||||
ripple_matrix_scale::link}}};
|
||||
|
||||
void LinkedFunctionTable::reg(const std::string& name, u64 (*exec)(void*), u32 stack_size) {
|
||||
const auto& it = m_executes.insert({name, {exec, Ptr<u8>()}});
|
||||
|
||||
@@ -92,8 +92,8 @@
|
||||
|
||||
(deftype merc-globals (structure)
|
||||
((first uint32 :offset-assert 0)
|
||||
(next uint32 :offset-assert 4)
|
||||
(sink basic :offset-assert 8)
|
||||
(next (pointer uint32) :offset-assert 4)
|
||||
(sink generic-dma-foreground-sink :offset-assert 8)
|
||||
)
|
||||
:allow-misaligned
|
||||
:method-count-assert 9
|
||||
|
||||
+388
-151
@@ -15,6 +15,7 @@
|
||||
|
||||
;; It's more than just bones in here - submitting to merc is done from here.
|
||||
|
||||
(defglobalconstant USE_GENERIC #t)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;
|
||||
;; calc list
|
||||
@@ -350,7 +351,7 @@
|
||||
;; reset globals
|
||||
(let ((v1-3 *merc-globals*))
|
||||
(set! (-> v1-3 first) (the-as uint 0))
|
||||
(set! (-> v1-3 next) (the-as uint 0))
|
||||
(set! (-> v1-3 next) (the-as (pointer uint32) 0))
|
||||
)
|
||||
|
||||
;; upload bones program.
|
||||
@@ -477,6 +478,9 @@
|
||||
(.lvf vf27 (&-> v1-13 vector 2 quad))
|
||||
|
||||
(.mov v1-14 vf27)
|
||||
;; hack??
|
||||
|
||||
|
||||
(bones-mtx-calc
|
||||
(the-as int (-> s4-0 matrix-area))
|
||||
(the-as pointer (-> s4-0 joints))
|
||||
@@ -525,10 +529,10 @@
|
||||
(+! a0-22 -1)
|
||||
(.svf (&-> a1-9 4 quad) vf7)
|
||||
;(.addiu v1-18 (the-as object v1-18) 128)
|
||||
(&+ v1-18 128)
|
||||
(&+! v1-18 128)
|
||||
(.svf (&-> a1-9 3 quad) vf6)
|
||||
;;(.addiu (the-as (inline-array vector) a1-9) a1-9 128)
|
||||
(&+ a1-9 128)
|
||||
(&+! a1-9 128)
|
||||
(b! (nonzero? a0-22) cfg-8 :delay (.svf (&-> a1-9 -2 quad) vf8))
|
||||
)
|
||||
0
|
||||
@@ -656,108 +660,180 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; draw-bones-shadow
|
||||
;; draw-bones-generic-merc
|
||||
;; TODO draw-bones-shadow
|
||||
|
||||
;(def-mips2c draw-bones-generic-merc (function draw-control pointer pointer int pointer))
|
||||
(defun draw-bones-generic-merc ((arg0 draw-control) (arg1 pointer) (arg2 pointer) (arg3 int))
|
||||
"Add data for generic merc drawing to the dma buffer. Note that this data is not yet converted to the generic format,
|
||||
so it is not linked into the chain. This data is linked to itself and can be found again by following the chain
|
||||
in *merc-globals*, which, despite the name, only contains generic merc data."
|
||||
(local-vars
|
||||
(sv-16 generic-merc-ctrl)
|
||||
(sv-32 merc-effect)
|
||||
(sv-48 int)
|
||||
(sv-64 merc-fragment)
|
||||
(sv-80 merc-fragment-control)
|
||||
(sv-96 uint)
|
||||
(sv-112 int)
|
||||
(sv-128 int)
|
||||
(sv-144 generic-merc-ctrl)
|
||||
)
|
||||
(let ((gp-0 (the-as object (&+ arg2 0))))
|
||||
(let ((s2-0 (-> arg0 lod-set lod (-> arg0 cur-lod) geo))
|
||||
(s0-0 (-> *merc-globals* next))
|
||||
)
|
||||
(set! sv-144 (the-as generic-merc-ctrl (&+ arg2 16)))
|
||||
(dotimes (s1-0 (the-as int (-> s2-0 header effect-count)))
|
||||
(when (nonzero? (-> *merc-bucket-info* effect s1-0 use-mercneric))
|
||||
(set! sv-16 sv-144)
|
||||
(set! sv-32 (-> s2-0 effect s1-0))
|
||||
(+! (-> *merc-global-stats* mercneric fragments) (-> sv-32 frag-count))
|
||||
(+! (-> *merc-global-stats* mercneric tris) (-> sv-32 tri-count))
|
||||
(+! (-> *merc-global-stats* mercneric dverts) (-> sv-32 dvert-count))
|
||||
(when (nonzero? s0-0)
|
||||
(set! (-> s0-0 0) (the-as uint sv-16))
|
||||
sv-16
|
||||
)
|
||||
(when (zero? (-> *merc-globals* first))
|
||||
(set! (-> *merc-globals* first) (the-as uint sv-16))
|
||||
sv-16
|
||||
)
|
||||
(set! s0-0 (&-> sv-16 tag vif1))
|
||||
(quad-copy! (the-as pointer (-> sv-16 lights)) (the-as pointer (-> *merc-bucket-info* light)) 7)
|
||||
(quad-copy! (the-as pointer (-> sv-16 header)) (the-as pointer (-> s2-0 header)) 5)
|
||||
(set! (-> sv-16 header envmap-tint) (the-as uint (-> *merc-bucket-info* effect s1-0 color-fade)))
|
||||
(set! (-> sv-16 header needs-clip) (the-as uint (-> *merc-bucket-info* needs-clip)))
|
||||
(set! (-> sv-16 header use-isometric) (the-as uint arg3))
|
||||
(when (nonzero? arg3)
|
||||
(set! (-> sv-16 header needs-clip) (the-as uint 0))
|
||||
0
|
||||
)
|
||||
(set! (-> sv-16 header use-attached-shader) (the-as uint 0))
|
||||
(set! (-> sv-16 header display-triangles) (the-as uint 1))
|
||||
(set! (-> sv-16 header two-mat-count) (the-as uint 0))
|
||||
(set! (-> sv-16 header shader-upload-count) (the-as uint (if (logtest? (-> sv-32 effect-bits) 2)
|
||||
1
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (nonzero? (-> arg0 death-timer))
|
||||
(when (>= (the-as int (- (-> arg0 death-timer-org) (-> arg0 death-timer)))
|
||||
(the-as int (-> arg0 death-draw-overlap))
|
||||
)
|
||||
(set! (-> sv-16 header display-triangles) (the-as uint 0))
|
||||
0
|
||||
)
|
||||
(when (not (paused?))
|
||||
(set! (-> sv-16 header two-mat-count) (-> arg0 death-vertex-skip))
|
||||
(set! (-> sv-16 header death-effect) (-> arg0 death-effect))
|
||||
(set! (-> sv-16 header two-mat-reuse-count)
|
||||
(/ (* (-> arg0 death-vertex-skip) (- (-> arg0 death-timer-org) (-> arg0 death-timer)))
|
||||
(-> arg0 death-timer-org)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> sv-16 header query) (the-as basic 0))
|
||||
(when (logtest? (-> sv-32 effect-bits) 4)
|
||||
(when (-> arg0 ripple)
|
||||
(if (-> arg0 ripple send-query)
|
||||
(set! (-> sv-16 header query) (-> arg0 ripple query))
|
||||
)
|
||||
)
|
||||
)
|
||||
(quad-copy! (the-as pointer (-> sv-16 effect)) (the-as pointer sv-32) 2)
|
||||
(set! sv-48 15)
|
||||
(when (nonzero? (-> sv-32 extra-info))
|
||||
(when (nonzero? (-> sv-32 extra-info shader-offset))
|
||||
(set! (-> sv-16 header use-attached-shader) (the-as uint 1))
|
||||
(quad-copy!
|
||||
(the-as pointer (&+ sv-16 240))
|
||||
(the-as pointer (+ (the-as uint (-> sv-32 extra-info)) (* (-> sv-32 extra-info shader-offset) 16)))
|
||||
5
|
||||
)
|
||||
(set! sv-48 (+ sv-48 5))
|
||||
sv-48
|
||||
)
|
||||
)
|
||||
(set! (-> sv-16 tag dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc (+ sv-48 -1)))
|
||||
(set! (-> sv-16 tag vif0) (the-as vif-tag sv-48))
|
||||
(set! (-> sv-16 tag vif1) (new 'static 'vif-tag))
|
||||
(set! sv-144 (the-as generic-merc-ctrl (+ (the-as uint sv-144) (* sv-48 16))))
|
||||
sv-144
|
||||
(set! sv-64 (-> sv-32 frag-geo))
|
||||
(set! sv-80 (-> sv-32 frag-ctrl))
|
||||
(set! sv-96 (-> sv-32 frag-count))
|
||||
(set! sv-112 0)
|
||||
(while (< sv-112 (the-as int sv-96))
|
||||
(set! sv-128 (asize-of sv-80))
|
||||
(let ((v1-104 (asize-of sv-64)))
|
||||
;; (format 0 "~D TAG at #x~X merc size ~D bytes ~D qw~%" sv-112 sv-144 v1-104 (shr v1-104 4))
|
||||
(set! (-> sv-144 tag dma)
|
||||
(new 'static 'dma-tag :id (dma-tag-id ref) :addr (the-as int sv-64) :qwc (shr v1-104 4))
|
||||
)
|
||||
(set! (-> sv-144 tag vif0) (new 'static 'vif-tag))
|
||||
(set! (-> sv-144 tag vif1) (new 'static 'vif-tag))
|
||||
(when (nonzero? sv-112)
|
||||
(set! (-> (the-as (pointer vif-tag) s0-0) 0) (the-as vif-tag sv-144))
|
||||
(set! s0-0 (&-> sv-144 tag vif1))
|
||||
)
|
||||
(let ((a0-55 (the-as structure (-> sv-144 lights))))
|
||||
(dotimes (a1-17 (the-as int (-> sv-80 mat-xfer-count)))
|
||||
(let ((a3-2 (&+ arg1 (* (-> sv-80 mat-dest-data a1-17 matrix-number) 128))))
|
||||
(set! (-> (the-as dma-packet a0-55) dma)
|
||||
(new 'static 'dma-tag :qwc #x7 :id (dma-tag-id ref) :addr (the-as int a3-2))
|
||||
)
|
||||
; (let ((vec (the vector (+ (the-as int a3-2) 16))))
|
||||
; (format 0 "#x~X #x~X mat ~D: ~f ~f ~f~%" a0-55 a3-2 a1-17 (-> vec x) (-> vec y) (-> vec z))
|
||||
; )
|
||||
|
||||
)
|
||||
(set! (-> (the-as dma-packet a0-55) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet a0-55) vif1) (new 'static 'vif-tag))
|
||||
(set! a0-55 (&+ (the-as dma-packet a0-55) 16))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a0-55) dma) (new 'static 'dma-tag :id (dma-tag-id end)))
|
||||
(set! (-> (the-as dma-packet a0-55) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet a0-55) vif1) (new 'static 'vif-tag))
|
||||
(set! sv-144 (the-as generic-merc-ctrl (&+ (the-as dma-packet a0-55) 16)))
|
||||
)
|
||||
(set! sv-80 (the-as merc-fragment-control (&+ (the-as pointer sv-80) sv-128)))
|
||||
(set! sv-64 (the-as merc-fragment (&+ (the-as pointer sv-64) v1-104)))
|
||||
)
|
||||
sv-64
|
||||
(set! sv-112 (+ sv-112 1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> *merc-globals* next) s0-0)
|
||||
)
|
||||
(set! (-> (the-as dma-packet gp-0) dma)
|
||||
(new 'static 'dma-tag :id (dma-tag-id next) :addr (the-as int sv-144))
|
||||
)
|
||||
(set! (-> (the-as dma-packet gp-0) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet gp-0) vif1) (new 'static 'vif-tag))
|
||||
)
|
||||
0
|
||||
(the-as pointer sv-144)
|
||||
)
|
||||
;; draw-boes-merc
|
||||
;; draw-bones-check-longest-edge
|
||||
;; draw-bones-check-longest-edgei-asm
|
||||
;; draw-bones
|
||||
;; draw-bones-hud
|
||||
|
||||
;; HACK incomplete:
|
||||
(defun draw-bones-hack ((arg0 draw-control) (arg1 dma-buffer) (arg2 float))
|
||||
(local-vars
|
||||
(at-0 object)
|
||||
(a0-16 int)
|
||||
(a0-17 int)
|
||||
(a0-62 int)
|
||||
(a2-10 int)
|
||||
(a2-12 int)
|
||||
(sv-96 int)
|
||||
(sv-112 int)
|
||||
(sv-128 int)
|
||||
(sv-144 ripple-control)
|
||||
)
|
||||
(rlet ((vf1 :class vf)
|
||||
(vf2 :class vf)
|
||||
(vf3 :class vf)
|
||||
(vf4 :class vf)
|
||||
(vf5 :class vf)
|
||||
(vf6 :class vf)
|
||||
(vf7 :class vf)
|
||||
(vf8 :class vf)
|
||||
(vf9 :class vf)
|
||||
)
|
||||
(let* ((s1-0 (+ (-> arg0 mgeo num-joints) 3))
|
||||
(a0-1 (* s1-0 128))
|
||||
)
|
||||
;;(.lui at-0 28672)
|
||||
(let* ((v1-2 (-> arg1 base))
|
||||
(a1-1 (the-as object (&+ v1-2 16)))
|
||||
(s3-0 (the-as object (&+ v1-2 64)))
|
||||
)
|
||||
(let ((a2-1 (logand (the-as int s3-0) 48)))
|
||||
(b! (zero? a2-1) cfg-2 :delay (nop!))
|
||||
(set! s3-0 (&- (&+ (the-as pointer s3-0) 64) (the-as uint a2-1)))
|
||||
)
|
||||
(label cfg-2)
|
||||
; (let* ((a2-3 (-> *perf-stats* data 13))
|
||||
; (a3-1 (-> a2-3 ctrl))
|
||||
; )
|
||||
; (+! (-> a2-3 count) 1)
|
||||
; (b! (zero? a3-1) cfg-4 :delay (nop!))
|
||||
; (.mtc0 Perf r0)
|
||||
; (.sync.l)
|
||||
; (.sync.p)
|
||||
; (.mtpc pcr0 r0)
|
||||
; (.mtpc pcr1 r0)
|
||||
; (.sync.l)
|
||||
; (.sync.p)
|
||||
; (.mtc0 Perf a3-1)
|
||||
; )
|
||||
; (.sync.l)
|
||||
; (.sync.p)
|
||||
; (label cfg-4)
|
||||
0
|
||||
(let ((a2-6 (the-as bone-regs (+ 240 (scratchpad-object int)))))
|
||||
(set! (-> a2-6 joint-ptr) (the-as (inline-array joint) (-> arg0 jgeo data 0)))
|
||||
(set! (-> a2-6 bone-ptr) (-> arg0 skeleton bones))
|
||||
(set! (-> a2-6 num-bones) (the-as uint s1-0))
|
||||
)
|
||||
(let ((t0-2 s3-0)
|
||||
(t1-0 0)
|
||||
(t4-0 (the-as bone-memory (+ 16 (scratchpad-object int))))
|
||||
(a2-8 *bone-calculation-list*)
|
||||
(a3-8 (the-as bone-calculation a1-1))
|
||||
)
|
||||
(let ((t2-0 (-> t4-0 work regs joint-ptr))
|
||||
(t3-0 (-> t4-0 work regs bone-ptr))
|
||||
(t4-1 (-> t4-0 work regs num-bones))
|
||||
(t5-0 a3-8)
|
||||
)
|
||||
(set! (-> t5-0 flags) (the-as bone-calc-flags t1-0))
|
||||
(set! (-> t5-0 num-bones) t4-1)
|
||||
(set! (-> t5-0 matrix-area) (the-as (inline-array matrix) t0-2))
|
||||
(set! (-> t5-0 joints) t2-0)
|
||||
(set! (-> t5-0 bones) t3-0)
|
||||
(set! (-> t5-0 next) (the-as bone-calculation 0))
|
||||
)
|
||||
(if (nonzero? (-> a2-8 next))
|
||||
(set! (-> a2-8 next next) a3-8)
|
||||
)
|
||||
(if (zero? (-> a2-8 first))
|
||||
(set! (-> a2-8 first) a3-8)
|
||||
)
|
||||
(set! (-> a2-8 next) a3-8)
|
||||
;; total guess
|
||||
(&+! (-> arg1 base) (* 2 (+ 256 a0-1)))
|
||||
)
|
||||
)))
|
||||
(none))
|
||||
|
||||
(def-mips2c draw-bones-merc (function draw-control object object int int pointer))
|
||||
(def-mips2c draw-bones-check-longest-edge-asm (function draw-control float symbol))
|
||||
|
||||
(defmacro store-qw (addr val)
|
||||
`(set! (-> (the-as (pointer uint128) ,addr)) (the-as uint128 ,val))
|
||||
)
|
||||
|
||||
(defmacro store-u32 (addr val)
|
||||
`(set! (-> (the-as (pointer uint32) ,addr)) ,val)
|
||||
)
|
||||
|
||||
(defun draw-bones ((arg0 draw-control) (dma-buf dma-buffer) (arg2 float))
|
||||
"Main draw function for all bone-related renderers. Will set up merc, generic and shadow.
|
||||
and also add the bones to the calculation list."
|
||||
@@ -965,41 +1041,44 @@
|
||||
;; try ripple
|
||||
(when (logtest? (-> geom effect effect-idx effect-bits) 4)
|
||||
;; TODO.
|
||||
; (when (-> arg0 ripple)
|
||||
; (set! sv-144 (-> arg0 ripple))
|
||||
; (let* ((f1-4 (/ (- (-> sv-144 far-fade-dist) arg2) (- (-> sv-144 far-fade-dist) (-> sv-144 close-fade-dist))))
|
||||
; (f1-6 (fmax 0.0 (fmin 1.0 f1-4)))
|
||||
; (f0-4 f1-6)
|
||||
; (f30-0 (* f1-6 (-> sv-144 global-scale)))
|
||||
; )
|
||||
; (set! (-> sv-144 faded-scale) f30-0)
|
||||
; (let ((f1-9 (/ f30-0 (* 128.0 (-> geom header xyz-scale)))))
|
||||
; 0
|
||||
; (.sll a0-16 num-bones 7)
|
||||
; (let ((v1-56 #x20000000))
|
||||
; (.addu a0-17 a0-16 s2-0)
|
||||
; (s.q! s2-0 v1-56)
|
||||
; )
|
||||
; (let ((v1-57 (+ a0-17 16)))
|
||||
; (s.w! (+ s2-0 4) v1-57)
|
||||
; )
|
||||
; (.addiu matrix-data s2-0 16)
|
||||
; (let ((v1-59 (-> *bone-calculation-list* next)))
|
||||
; (logior! (-> v1-59 flags) (bone-calc-flags bncfl00))
|
||||
; (set! (-> v1-59 ripple-scale) f30-0)
|
||||
; (set! (-> v1-59 ripple-y-scale) f1-9)
|
||||
; (set! (-> v1-59 ripple-normal-scale) (* f0-4 (-> sv-144 individual-normal-scale)))
|
||||
; (set! (-> v1-59 ripple-area) (the-as (inline-array vector) matrix-data))
|
||||
; )
|
||||
; )
|
||||
; (set! (-> dma-buf base) (the-as pointer (-> (the-as (pointer uint32) s2-0) 1)))
|
||||
; (set! s2-0 (-> dma-buf base))
|
||||
; (if (not (and (= f30-0 0.0) (= (-> sv-144 last-frame-scale) 0.0)))
|
||||
; (ripple-make-request (the-as ripple-wave (-> sv-144 waveform)) (-> geom effect effect-idx))
|
||||
; )
|
||||
; (set! (-> sv-144 last-frame-scale) f30-0)
|
||||
; )
|
||||
; )
|
||||
(when (-> arg0 ripple)
|
||||
(set! sv-144 (-> arg0 ripple))
|
||||
(let* ((f1-4 (/ (- (-> sv-144 far-fade-dist) arg2) (- (-> sv-144 far-fade-dist) (-> sv-144 close-fade-dist))))
|
||||
(f1-6 (fmax 0.0 (fmin 1.0 f1-4)))
|
||||
(f0-4 f1-6)
|
||||
(f30-0 (* f1-6 (-> sv-144 global-scale)))
|
||||
)
|
||||
(set! (-> sv-144 faded-scale) f30-0)
|
||||
(let ((f1-9 (/ f30-0 (* 128.0 (-> geom header xyz-scale)))))
|
||||
0
|
||||
(set! a0-16 (* num-bones 128))
|
||||
(let ((v1-56 #x20000000))
|
||||
(set! a0-17 (+ a0-16 (the-as int s2-0)));(.addu a0-17 a0-16 s2-0)
|
||||
(logand! a0-17 #xffffffff)
|
||||
;(s.q! s2-0 v1-56)
|
||||
(store-qw s2-0 v1-56)
|
||||
)
|
||||
(let ((v1-57 (+ a0-17 16)))
|
||||
;(s.w! (+ s2-0 4) v1-57)
|
||||
(store-u32 (&+ (the pointer s2-0) 4) v1-57)
|
||||
)
|
||||
(set! matrix-data (&+ (the pointer s2-0) 16))
|
||||
(let ((v1-59 (-> *bone-calculation-list* next)))
|
||||
(logior! (-> v1-59 flags) (bone-calc-flags bncfl00))
|
||||
(set! (-> v1-59 ripple-scale) f30-0)
|
||||
(set! (-> v1-59 ripple-y-scale) f1-9)
|
||||
(set! (-> v1-59 ripple-normal-scale) (* f0-4 (-> sv-144 individual-normal-scale)))
|
||||
(set! (-> v1-59 ripple-area) (the-as (inline-array vector) matrix-data))
|
||||
)
|
||||
)
|
||||
(set! (-> dma-buf base) (the-as pointer (-> (the-as (pointer uint32) s2-0) 1)))
|
||||
(set! s2-0 (-> dma-buf base))
|
||||
(if (not (and (= f30-0 0.0) (= (-> sv-144 last-frame-scale) 0.0)))
|
||||
(ripple-make-request (the-as ripple-wave (-> sv-144 waveform)) (-> geom effect effect-idx))
|
||||
)
|
||||
(set! (-> sv-144 last-frame-scale) f30-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -1081,31 +1160,40 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; HACK just use merc.
|
||||
(when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
|
||||
(unless (logtest? (-> arg0 status) (draw-status needs-clip))
|
||||
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0))
|
||||
)
|
||||
(when (and (logtest? (-> arg0 status) (draw-status needs-clip)) ;; we need to clip
|
||||
;;(nonzero? (-> arg0 longest-edge)) ;; we known the longest edge
|
||||
;;(draw-bones-check-longest-edge-asm arg0 arg2) ;; it's ok to use percprime.
|
||||
;; HACK just use merc if we aren't using generic.
|
||||
(#unless USE_GENERIC
|
||||
(when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
|
||||
(unless (logtest? (-> arg0 status) (draw-status needs-clip))
|
||||
;; no clip, but wants generic. Just use merc for now.
|
||||
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0))
|
||||
(set! used-merc 1)
|
||||
)
|
||||
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0))
|
||||
(set! (-> *merc-bucket-info* need-mercprime-if-merc) 1)
|
||||
)
|
||||
)
|
||||
(when (and (logtest? (-> arg0 status) (draw-status needs-clip)) ;; we need to clip
|
||||
;;(nonzero? (-> arg0 longest-edge)) ;; we known the longest edge
|
||||
;;(draw-bones-check-longest-edge-asm arg0 arg2) ;; it's ok to use percprime.
|
||||
)
|
||||
;; wants clip. in all cases, give to merc. this might give it to merc even if it fails the
|
||||
;; long edge check, but it does ok
|
||||
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0))
|
||||
(set! (-> *merc-bucket-info* need-mercprime-if-merc) 1)
|
||||
(set! used-merc 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(set! effect-idx (+ effect-idx 1))
|
||||
) ;; end effect loop
|
||||
|
||||
;; draw generic!
|
||||
;; note: this doesn't do the fully draw, there's some other stuff in process-drawable.gc to actually execute.
|
||||
;; TODO!!
|
||||
; (when (nonzero? used-mercneric)
|
||||
; (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
|
||||
; (set! (-> dma-buf base) (draw-bones-generic-merc arg0 matrix-data s2-0 0))
|
||||
; (set! s2-0 (-> dma-buf base))
|
||||
; )
|
||||
; )
|
||||
(#when USE_GENERIC
|
||||
(when (nonzero? used-mercneric)
|
||||
(when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
|
||||
(set! (-> dma-buf base) (draw-bones-generic-merc arg0 (the pointer matrix-data) (the pointer s2-0) 0))
|
||||
(set! s2-0 (-> dma-buf base))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; draw shadow!
|
||||
;; TODO
|
||||
@@ -1118,7 +1206,7 @@
|
||||
|
||||
;; draw merc!
|
||||
|
||||
(set! used-merc 1)
|
||||
;;
|
||||
(when (nonzero? used-merc)
|
||||
(when (logtest? *vu1-enable-user* (vu1-renderer-mask merc))
|
||||
(when (= (-> arg0 cur-lod) (-> arg0 lod-set max-lod))
|
||||
@@ -1177,7 +1265,156 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; TODO
|
||||
(defun draw-bones-hud ((arg0 draw-control) (arg1 dma-buffer))
|
||||
(local-vars
|
||||
(at-0 object)
|
||||
(at-2 int)
|
||||
(t2-10 vu-lights)
|
||||
(t3-3 uint128)
|
||||
(t3-4 uint128)
|
||||
(t3-5 uint128)
|
||||
(t3-6 uint128)
|
||||
)
|
||||
(let ((v1-0 arg0)
|
||||
(gp-0 arg1)
|
||||
)
|
||||
;; (.lui at-0 28672)
|
||||
(set! at-0 (scratchpad-object object))
|
||||
(let* ((a3-0 (-> gp-0 base))
|
||||
(a0-3 (+ (-> v1-0 mgeo num-joints) 3))
|
||||
(a2-0 (the-as object (&+ a3-0 16)))
|
||||
(a1-1 (&+ a3-0 64))
|
||||
)
|
||||
(let ((t0-1 (scratchpad-object bone-regs :offset 240)))
|
||||
(set! (-> t0-1 joint-ptr) (the-as (inline-array joint) (-> v1-0 jgeo data 0)))
|
||||
(set! (-> t0-1 bone-ptr) (-> v1-0 skeleton bones))
|
||||
(set! (-> t0-1 num-bones) (the-as uint a0-3))
|
||||
)
|
||||
(let ((t2-0 a1-1)
|
||||
(t3-0 2)
|
||||
(t6-0 (scratchpad-object bone-memory :offset 16))
|
||||
(t0-3 *bone-calculation-list*)
|
||||
(t1-6 (the-as bone-calculation a2-0))
|
||||
)
|
||||
(let ((t4-0 (-> t6-0 work regs joint-ptr))
|
||||
(t5-0 (-> t6-0 work regs bone-ptr))
|
||||
(t6-1 (-> t6-0 work regs num-bones))
|
||||
(t7-0 t1-6)
|
||||
)
|
||||
(set! (-> t7-0 flags) (the-as bone-calc-flags t3-0))
|
||||
(set! (-> t7-0 num-bones) t6-1)
|
||||
(set! (-> t7-0 matrix-area) (the-as (inline-array matrix) t2-0))
|
||||
(set! (-> t7-0 joints) t4-0)
|
||||
(set! (-> t7-0 bones) t5-0)
|
||||
(set! (-> t7-0 next) (the-as bone-calculation 0))
|
||||
)
|
||||
(if (nonzero? (-> t0-3 next))
|
||||
(set! (-> t0-3 next next) t1-6)
|
||||
)
|
||||
(if (zero? (-> t0-3 first))
|
||||
(set! (-> t0-3 first) t1-6)
|
||||
)
|
||||
(set! (-> t0-3 next) t1-6)
|
||||
)
|
||||
(let ((a2-2 (the-as object (&+ (&+ (the-as pointer a2-0) 48) (* a0-3 128)))))
|
||||
(set! (-> (the-as (pointer uint128) a3-0))
|
||||
(logior (-> (the-as terrain-context at-0) work foreground generic-work saves envmap verts 4)
|
||||
(shl (the-as int a2-2) 32)
|
||||
)
|
||||
)
|
||||
(when (= (-> v1-0 data-format) 1)
|
||||
(let ((a0-9 (-> v1-0 lod-set lod 0 geo)))
|
||||
(dotimes (a3-2 (the-as int (-> a0-9 header effect-count)))
|
||||
(cond
|
||||
((nonzero? (-> a0-9 effect a3-2 envmap-usage))
|
||||
(let* ((t1-7 (-> *merc-bucket-info* light))
|
||||
(t2-9 (+ 64 (scratchpad-object int)))
|
||||
(t0-10 7)
|
||||
(t1-8 (the-as object t1-7))
|
||||
)
|
||||
(b! (< (+ t0-10 -4) 0) cfg-9 :delay (set! t2-10 (the-as vu-lights t2-9)))
|
||||
(nop!)
|
||||
(label cfg-8)
|
||||
(let ((t6-2 (-> t2-10 direction 0 quad)))
|
||||
(nop!)
|
||||
(let ((t3-2 (-> t2-10 direction 1 quad)))
|
||||
(+! t0-10 -4)
|
||||
(let ((t4-1 (-> t2-10 direction 2 quad)))
|
||||
(set! t1-8 (&+ (the-as pointer t1-8) 64))
|
||||
(let ((t5-1 (-> t2-10 color 0 quad)))
|
||||
(set! t2-10 (the-as vu-lights (-> t2-10 color 1)))
|
||||
(store-qw (&+ (the-as pointer t1-8) -64) t6-2)
|
||||
(let ((t6-3 (+ t0-10 -4)))
|
||||
(store-qw (&+ (the-as pointer t1-8) -48) t3-2)
|
||||
(nop!)
|
||||
(store-qw (&+ (the-as pointer t1-8) -32) t4-1)
|
||||
(b! (>= t6-3 0) cfg-8 :delay (store-qw (&+ (the-as pointer t1-8) -16) t5-1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(label cfg-9)
|
||||
(b! (zero? t0-10) cfg-14 :delay (set! t3-3 (-> t2-10 direction 0 quad)))
|
||||
(let ((t2-11 (-> t2-10 direction 1))
|
||||
(t1-9 (-> (the-as vu-lights t1-8) direction 1))
|
||||
(t0-11 (+ t0-10 -1))
|
||||
)
|
||||
(store-qw (&+ t1-9 -16) t3-3)
|
||||
(b! (zero? t0-11) cfg-14 :delay (set! t3-4 (-> t2-11 quad)))
|
||||
(let ((t2-12 (&+ t2-11 16))
|
||||
(t1-10 (&+ t1-9 16))
|
||||
(t0-12 (+ t0-11 -1))
|
||||
)
|
||||
(store-qw (&+ t1-10 -16) t3-4)
|
||||
(b! (zero? t0-12) cfg-14 :delay (set! t3-5 (-> t2-12 quad)))
|
||||
(let ((t2-13 (&+ t2-12 16))
|
||||
(t1-11 (&+ t1-10 16))
|
||||
(t0-13 (+ t0-12 -1))
|
||||
)
|
||||
(store-qw (&+ t1-11 -16) t3-5)
|
||||
(b! (zero? t0-13) cfg-14 :delay (set! t3-6 (-> t2-13 quad)))
|
||||
(&+ t2-13 16)
|
||||
(let ((t1-12 (&+ t1-11 16)))
|
||||
(+ t0-13 -1)
|
||||
(store-qw (&+ t1-12 -16) t3-6)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(label cfg-14)
|
||||
0
|
||||
(set! (-> *merc-bucket-info* effect a3-2 color-fade) (new 'static 'rgba :r #x80 :g #x80 :b #x80 :a #x80))
|
||||
(set! (-> *merc-bucket-info* effect a3-2 use-mercneric) (the-as uint 1))
|
||||
)
|
||||
(else
|
||||
(set! (-> *merc-bucket-info* effect a3-2 use-mercneric) (the-as uint 1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
|
||||
(set! (-> gp-0 base) (draw-bones-generic-merc v1-0 a1-1 (the-as pointer a2-2) 1))
|
||||
(set! a2-2 (-> gp-0 base))
|
||||
)
|
||||
)
|
||||
(let ((a0-17 (logand (the-as int a2-2) 48)))
|
||||
0
|
||||
(b! (zero? a0-17) cfg-22 :delay (set! at-2 #x20000000))
|
||||
(set! (-> (the-as (pointer int128) a2-2)) (the-as int128 at-2))
|
||||
(let ((v1-2 (the-as pointer a2-2)))
|
||||
(set! a2-2 (+ (&- (the-as pointer a2-2) (the-as uint a0-17)) 64))
|
||||
(store-u32 (&+ v1-2 4) (the-as int a2-2))
|
||||
)
|
||||
)
|
||||
(label cfg-22)
|
||||
(set! (-> gp-0 base) (the-as pointer a2-2))
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
@@ -851,26 +851,26 @@
|
||||
)
|
||||
)
|
||||
;; todo
|
||||
; (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
|
||||
; (when (nonzero? (-> *merc-globals* first))
|
||||
; (let ((s4-1 (-> *display* frames (-> *display* on-screen) frame global-buf base)))
|
||||
; (let ((a0-25 (-> (the-as (pointer uint32) (+ (the-as uint *level*) (* 2608 arg2) (* arg3 32))) 69)))
|
||||
; (generic-merc-add-to-cue a0-25)
|
||||
; )
|
||||
; (let ((a0-26 *dma-mem-usage*))
|
||||
; (when (nonzero? a0-26)
|
||||
; (set! (-> a0-26 length) (max 87 (-> a0-26 length)))
|
||||
; (set! (-> a0-26 data 86 name) "pris-generic")
|
||||
; (+! (-> a0-26 data 86 count) 1)
|
||||
; (+! (-> a0-26 data 86 used)
|
||||
; (&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint s4-1))
|
||||
; )
|
||||
; (set! (-> a0-26 data 86 total) (-> a0-26 data 86 used))
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
(when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
|
||||
(when (nonzero? (-> *merc-globals* first))
|
||||
(let ((s4-1 (-> *display* frames (-> *display* on-screen) frame global-buf base)))
|
||||
(let ((a0-25 (-> (the-as (pointer uint32) (+ (the-as uint *level*) (* 2608 arg2) (* arg3 32))) 69)))
|
||||
(generic-merc-add-to-cue (the-as generic-dma-foreground-sink a0-25))
|
||||
)
|
||||
(let ((a0-26 *dma-mem-usage*))
|
||||
(when (nonzero? a0-26)
|
||||
(set! (-> a0-26 length) (max 87 (-> a0-26 length)))
|
||||
(set! (-> a0-26 data 86 name) "pris-generic")
|
||||
(+! (-> a0-26 data 86 count) 1)
|
||||
(+! (-> a0-26 data 86 used)
|
||||
(&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint s4-1))
|
||||
)
|
||||
(set! (-> a0-26 data 86 total) (-> a0-26 data 86 used))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(when #t
|
||||
(let ((v1-41 *shadow-queue*))
|
||||
(+! (-> v1-41 cur-run) 1)
|
||||
@@ -907,9 +907,12 @@
|
||||
)
|
||||
)
|
||||
"Function to be executed to set up for engine dma"
|
||||
|
||||
;; update render enables from the debug menu
|
||||
(set! *vu1-enable-user* *vu1-enable-user-menu*)
|
||||
(set! *texture-enable-user* *texture-enable-user-menu*)
|
||||
|
||||
;; reset and display dma memory stats.
|
||||
(when *debug-segment*
|
||||
(when (or *stats-memory* *stats-memory-short*)
|
||||
(dotimes (gp-0 (-> *level* length))
|
||||
@@ -923,9 +926,9 @@
|
||||
(reset! *dma-mem-usage*)
|
||||
)
|
||||
|
||||
;; todo debug memory
|
||||
;; todo shrub matrix
|
||||
;; todo generic init
|
||||
(generic-init-buffers)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; texture uploads
|
||||
@@ -1081,7 +1084,7 @@
|
||||
)
|
||||
(let ((gp-9 (-> *display* frames (-> *display* on-screen) frame global-buf)))
|
||||
(bones-mtx-calc-execute)
|
||||
;;(generic-merc-execute-all)
|
||||
(generic-merc-execute-all gp-9)
|
||||
;;(shadow-execute-all gp-9 *shadow-queue*)
|
||||
)
|
||||
;; fg engine
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
;; name in dgo: main-h
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; hacks
|
||||
(defglobalconstant SKIP_MERC_DEATH_PARTICLES #t)
|
||||
|
||||
;; Global engine settings:
|
||||
(define *stats-poly* #f)
|
||||
(define *stats-memory* #f)
|
||||
|
||||
@@ -582,7 +582,7 @@
|
||||
(blerc-execute)
|
||||
(blerc-init)
|
||||
(texscroll-execute)
|
||||
; (ripple-execute)
|
||||
(ripple-execute)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;
|
||||
;; AMBIENT
|
||||
|
||||
@@ -5,3 +5,143 @@
|
||||
;; name in dgo: generic-effect
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
(define-extern *generic-envmap-texture* texture)
|
||||
|
||||
(define *target-lock* (the-as symbol 0))
|
||||
|
||||
(define *generic-consts*
|
||||
(new 'static 'generic-consts
|
||||
:dma-header
|
||||
(new 'static 'dma-packet
|
||||
:dma
|
||||
(new 'static 'dma-tag :id (dma-tag-id cnt))
|
||||
:vif0
|
||||
(new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl))
|
||||
:vif1
|
||||
(new 'static 'vif-tag :cmd (vif-cmd unpack-v4-32))
|
||||
)
|
||||
:vif-header
|
||||
(new 'static 'array uint32 4 #x1000404 #x1000404 #x1000404 #x6c000000)
|
||||
:dma-ref-vtxs
|
||||
(new 'static 'dma-packet :dma (new 'static 'dma-tag :id (dma-tag-id ref)))
|
||||
:dma-cnt-call
|
||||
(new 'static 'dma-packet :dma (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
:matrix
|
||||
(new 'static 'matrix
|
||||
:vector
|
||||
(new 'static 'inline-array vector 4
|
||||
(new 'static 'vector :x 1.0)
|
||||
(new 'static 'vector :y 1.0)
|
||||
(new 'static 'vector :z 1.0)
|
||||
(new 'static 'vector :w 1.0)
|
||||
)
|
||||
)
|
||||
:base-strgif
|
||||
(new 'static 'generic-gif-tag :data (new 'static 'array uint32 4 #x303ec000 #x303e4000 #x412 #x0))
|
||||
:alpha-opaque
|
||||
(new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x0 #x0 #x42 #x0))
|
||||
:alpha-translucent
|
||||
(new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x44 #x0 #x42 #x0))
|
||||
:ztest-normal
|
||||
(new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x5026b #x0 #x47 #x0))
|
||||
:ztest-opaque
|
||||
(new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x5000a #x0 #x47 #x0))
|
||||
:adcmd-offsets
|
||||
(new 'static 'array uint8 16 #x0 #x20 #x10 #x20 #x0 #x30 #x20 #x20 #x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0)
|
||||
:stcycle-tag #x1000103
|
||||
:unpack-vtx-tag #x68000000
|
||||
:unpack-clr-tag #x6e004000
|
||||
:unpack-tex-tag #x65000000
|
||||
:mscal-tag #x14000006
|
||||
:reset-cycle-tag #x1000404
|
||||
:dma-tag-cnt #x10000000
|
||||
:envmap
|
||||
(new 'static 'generic-envmap-consts
|
||||
:consts
|
||||
(new 'static 'vector :x 1.0 :z 0.5 :w 0.5)
|
||||
:strgif
|
||||
(new 'static 'generic-gif-tag :data (new 'static 'array uint32 4 #x302ec000 #x302e4000 #x412 #x0))
|
||||
:colors
|
||||
(new 'static 'vector4w :x -2139062144 :y -2139062144 :z -2139062144 :w -2139062144)
|
||||
)
|
||||
:light-consts
|
||||
(new 'static 'vector :x 255.0 :y 8388608.0)
|
||||
)
|
||||
)
|
||||
|
||||
(defun generic-work-init ((arg0 generic-dma-foreground-sink))
|
||||
"Initialize generic-work."
|
||||
;; copy to scratchpad copy of the work
|
||||
(quad-copy! (the-as pointer (-> (scratchpad-object terrain-context) work foreground generic-work fx-buf work consts))
|
||||
(the-as pointer *generic-consts*)
|
||||
27)
|
||||
;; set buffer addresses
|
||||
(set! (-> (scratchpad-object terrain-context) work foreground generic-work saves gifbuf-adr)
|
||||
(-> arg0 state gifbuf-adr)
|
||||
)
|
||||
(set! (-> (scratchpad-object terrain-context) work foreground generic-work saves inbuf-adr)
|
||||
(-> arg0 state inbuf-adr)
|
||||
)
|
||||
(set! (-> (scratchpad-object terrain-context) work foreground generic-work saves cur-outbuf)
|
||||
(the-as uint (+ 8192 (scratchpad-object int)))
|
||||
)
|
||||
|
||||
;; initialize the environment map "shader". This isn't a real shader, but just texturing settings.
|
||||
(let ((gp-1 (-> (scratchpad-object terrain-context) work foreground generic-work fx-buf work consts envmap shader)))
|
||||
(let ((a1-1 *generic-envmap-texture*))
|
||||
(adgif-shader<-texture! gp-1 a1-1)
|
||||
)
|
||||
(set! (-> gp-1 tex1) (new 'static 'gs-tex1 :mmag #x1 :mmin #x1))
|
||||
(set! (-> gp-1 clamp) (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp)))
|
||||
(set! (-> gp-1 alpha) (new 'static 'gs-alpha :b #x2 :c #x1 :d #x1))
|
||||
(set! (-> gp-1 prims 1) (gs-reg64 tex0-1))
|
||||
(set! (-> gp-1 prims 3) (gs-reg64 tex1-1))
|
||||
(set! (-> gp-1 prims 5) (gs-reg64 miptbp1-1))
|
||||
(set! (-> gp-1 clamp-reg) (gs-reg64 clamp-1))
|
||||
(set! (-> gp-1 prims 9) (gs-reg64 alpha-1))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun upload-vu0-program ((func vu-function) (wait-ptr pointer))
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun generic-initialize-without-sink ((arg0 matrix) (arg1 vu-lights))
|
||||
"Prepare for Generic.
|
||||
Upload the generic vu0 block and set the matrix and lights.
|
||||
The generic VU0 block is loaded to program address 0."
|
||||
(upload-vu0-program generic-vu0-block (the-as pointer #x70000064))
|
||||
(let (;(a2-0 (+ #x2e20 (the-as int (the-as terrain-context #x70000000))))
|
||||
(a2-0 (-> (scratchpad-object terrain-context) work foreground generic-work fx-buf work consts matrix))
|
||||
(v1-1 (-> arg0 vector 0 quad))
|
||||
(a0-3 (-> arg0 vector 1 quad))
|
||||
(a1-2 (-> arg0 vector 2 quad))
|
||||
(a3-0 (-> arg0 vector 3 quad))
|
||||
)
|
||||
;;(set! (-> (the-as (pointer uint128) a2-0)) v1-1)
|
||||
(set! (-> a2-0 vector 0 quad) v1-1)
|
||||
;;(s.q! (+ a2-0 16) a0-3)
|
||||
(set! (-> a2-0 vector 1 quad) a0-3)
|
||||
;; (s.q! (+ a2-0 32) a1-2)
|
||||
(set! (-> a2-0 vector 2 quad) a1-2)
|
||||
;;(s.q! (+ a2-0 48) a3-0)
|
||||
(set! (-> a2-0 vector 3 quad) a3-0)
|
||||
)
|
||||
|
||||
(if arg1
|
||||
;;(quad-copy! (the-as pointer (+ #x3190 #x70000000)) (the-as pointer arg1) 7)
|
||||
(quad-copy! (the pointer (-> (scratchpad-object terrain-context) work foreground generic-work fx-buf work lights)) (the-as pointer arg1) 7)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
(def-mips2c generic-prepare-dma-single function)
|
||||
|
||||
|
||||
(def-mips2c generic-prepare-dma-double function)
|
||||
|
||||
(def-mips2c generic-light-proc function)
|
||||
|
||||
(def-mips2c generic-envmap-proc function)
|
||||
@@ -12,6 +12,7 @@
|
||||
(init-data uint8 :offset-assert 1)
|
||||
(init-addr uint16 :offset-assert 2)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
@@ -27,17 +28,17 @@
|
||||
|
||||
(define *inv-init-table* (new 'static 'inline-array invinitdata 8
|
||||
(new 'static 'invinitdata :count #x48 :init-addr #x1)
|
||||
(new 'static 'invinitdata :count #x43 :init-data #xc :init-addr #x11)
|
||||
(new 'static 'invinitdata :count #x3d :init-data #x18 :init-addr #x21)
|
||||
(new 'static 'invinitdata :count #x38 :init-data #x22 :init-addr #xe0)
|
||||
(new 'static 'invinitdata :count #x38 :init-data #x24 :init-addr #xe1)
|
||||
(new 'static 'invinitdata :count #xbe)
|
||||
(new 'static 'invinitdata :count #x81 :init-data #x80 :init-addr #x3b80)
|
||||
(new 'static 'invinitdata :count #x88 :init-data #x50 :init-addr #x100a)
|
||||
(new 'static 'invinitdata :count #x7d :init-data #xb :init-addr #x81e8)
|
||||
(new 'static 'invinitdata :count #x7d :init-data #x1b :init-addr #x81e8)
|
||||
(new 'static 'invinitdata :count #x2 :init-data #x68 :init-addr #x5200)
|
||||
(new 'static 'invinitdata :count #x33 :init-data #x30 :init-addr #xf1)
|
||||
(new 'static 'invinitdata :count #x2e :init-data #x3a :init-addr #x190)
|
||||
(new 'static 'invinitdata :count #x2d :init-data #x3c :init-addr #x191)
|
||||
)
|
||||
)
|
||||
|
||||
;; (def-mips2c generic-merc-init-asm function) ;; TODO mips2c
|
||||
(def-mips2c generic-merc-init-asm (function none))
|
||||
|
||||
;; (def-mips2c mercneric-matrix-asm function) ;; TODO mips2c
|
||||
|
||||
@@ -45,20 +46,160 @@
|
||||
|
||||
;; (def-mips2c mercneric-bittable-asm function) ;; TODO mips2c
|
||||
|
||||
;; (def-mips2c mercneric-convert function) ;; TODO mips2c
|
||||
(def-mips2c mercneric-convert function)
|
||||
|
||||
;; (def-mips2c high-speed-reject function) ;; TODO mips2c
|
||||
(def-mips2c high-speed-reject (function none))
|
||||
(def-mips2c generic-merc-execute-asm (function none)) ;; TODO mips2c
|
||||
|
||||
;; (def-mips2c generic-merc-execute-asm function) ;; TODO mips2c
|
||||
|
||||
(defun generic-merc-add-to-cue ((arg0 basic))
|
||||
(defun generic-merc-add-to-cue ((arg0 generic-dma-foreground-sink))
|
||||
(set! (-> *merc-globals* sink) arg0)
|
||||
(+! (-> *merc-global-array* count) 1)
|
||||
(set! *merc-globals* (-> *merc-global-array* globals (-> *merc-global-array* count)))
|
||||
(none)
|
||||
)
|
||||
|
||||
;; (def-mips2c generic-merc-execute-all function) ;; TODO mips2c
|
||||
(defun generic-merc-execute-all ((arg0 dma-buffer))
|
||||
"Run the EE part of the generic renderer for all generic merc stuff.
|
||||
This will build DMA data in the format for generic."
|
||||
(local-vars (a0-26 int) (a0-28 int))
|
||||
;; (format 0 "[GMERC] starting generic-merc-execute-all with ~d to execute~%" (-> *merc-global-array* count))
|
||||
(when (nonzero? (-> *merc-global-array* count))
|
||||
(let ((gp-0 (-> *display* frames (-> *display* on-screen) frame global-buf base)))
|
||||
|
||||
;; set up performance stats
|
||||
(if *debug-segment*
|
||||
(add-frame
|
||||
(-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #x40 :b #x40 :a #x80)
|
||||
)
|
||||
)
|
||||
|
||||
(reset! (-> *perf-stats* data 1))
|
||||
(set! (-> (scratchpad-object terrain-context) work foreground generic-work saves to-vu0-waits)
|
||||
(the-as uint 0)
|
||||
)
|
||||
(set! (-> (scratchpad-object terrain-context) work foreground generic-work saves to-spr-waits)
|
||||
(the-as uint 0)
|
||||
)
|
||||
(set! (-> (scratchpad-object terrain-context) work foreground generic-work saves from-spr-waits)
|
||||
(the-as uint 0)
|
||||
)
|
||||
(flush-cache 0)
|
||||
|
||||
;; first, initialize the generic renderer.
|
||||
(generic-initialize-without-sink (-> *math-camera* perspective) *default-lights*)
|
||||
|
||||
;; next, initialize the merc-specific stuff.
|
||||
;; this give us function pointers to
|
||||
;; - mercneric-convert
|
||||
;; - generic-prepare-dma-single
|
||||
;; - generic-prepare-dma-double
|
||||
;; - generic-light-proc
|
||||
;; - generic-envmap-proc
|
||||
;; - high-speed-reject
|
||||
;; and also loads the mercneric-vu0-block block with an offset of 280.
|
||||
(generic-merc-init-asm)
|
||||
|
||||
;; set a limit, so we don't write off the end of the dma buffer.
|
||||
(set! (-> (scratchpad-object terrain-context) work foreground generic-work in-buf merc shadow write-limit)
|
||||
(&+ (-> arg0 end) -65536)
|
||||
)
|
||||
|
||||
(dotimes (s4-0 (the-as int (-> *merc-global-array* count)))
|
||||
(set! *merc-globals* (-> *merc-global-array* globals s4-0))
|
||||
(let ((s3-0 (-> *merc-globals* sink)))
|
||||
(when (nonzero? (-> *merc-globals* first))
|
||||
(let* ((s1-0 (-> *display* frames (-> *display* on-screen) frame global-buf))
|
||||
(s2-0 (-> s1-0 base))
|
||||
)
|
||||
;; (format 0 "[GMERC] running ~D~%" s4-0)
|
||||
(generic-work-init s3-0)
|
||||
(set! (-> (scratchpad-object terrain-context) work foreground generic-work saves basep)
|
||||
(the-as uint (-> s1-0 base))
|
||||
)
|
||||
(generic-merc-execute-asm)
|
||||
(set! (-> s1-0 base)
|
||||
(the-as pointer (-> (scratchpad-object terrain-context) work foreground generic-work saves basep))
|
||||
)
|
||||
;; todo: this part might be important...
|
||||
; (let ((v1-36 (the-as object #x1000d000))
|
||||
; (a0-19 (the-as object #x7000006c))
|
||||
; )
|
||||
; (b! (zero? (logand (-> (the-as terrain-context v1-36) bsp lev-index) 256)) cfg-9 :delay (nop!))
|
||||
; (let ((a1-6 (-> (the-as generic-envmap-saves a0-19) index-mask x)))
|
||||
; (nop!)
|
||||
; (let ((a2-1 (-> (the-as (pointer int32) v1-36) 0)))
|
||||
; (nop!)
|
||||
; (let ((a2-2 (logand a2-1 256))
|
||||
; (a1-7 (+ a1-6 1))
|
||||
; )
|
||||
; (b! (nonzero? a2-2) cfg-8 :delay (s.w! (the-as int a0-19) a1-7))
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; (label cfg-9)
|
||||
; 0
|
||||
(let ((a3-0 (-> s1-0 base)))
|
||||
(let ((v1-38 (the-as object (-> s1-0 base))))
|
||||
(set! (-> (the-as dma-packet v1-38) dma) (new 'static 'dma-tag :id (dma-tag-id next)))
|
||||
(set! (-> (the-as dma-packet v1-38) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet v1-38) vif1) (new 'static 'vif-tag))
|
||||
(set! (-> s1-0 base) (&+ (the-as pointer v1-38) 16))
|
||||
)
|
||||
(dma-bucket-insert-tag
|
||||
(-> *display* frames (-> *display* on-screen) frame bucket-group)
|
||||
(-> s3-0 bucket)
|
||||
s2-0
|
||||
(the-as (pointer dma-tag) a3-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; (let ((v1-44 (-> arg0 base)))
|
||||
; (.sync.l)
|
||||
; (.cache dxwbin v1-44 0)
|
||||
; (.sync.l)
|
||||
; (.cache dxwbin v1-44 1)
|
||||
; )
|
||||
; (.sync.l)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
(read! (-> *perf-stats* data 1))
|
||||
0
|
||||
(update-wait-stats
|
||||
(-> *perf-stats* data 1)
|
||||
(-> (scratchpad-object terrain-context) work foreground generic-work saves to-vu0-waits)
|
||||
(-> (scratchpad-object terrain-context) work foreground generic-work saves to-spr-waits)
|
||||
(-> (scratchpad-object terrain-context) work foreground generic-work saves from-spr-waits)
|
||||
)
|
||||
(if *debug-segment*
|
||||
(add-frame
|
||||
(-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
|
||||
)
|
||||
)
|
||||
(let ((v1-64 *dma-mem-usage*))
|
||||
(when (nonzero? v1-64)
|
||||
(set! (-> v1-64 length) (max 87 (-> v1-64 length)))
|
||||
(set! (-> v1-64 data 86 name) "pris-generic")
|
||||
(+! (-> v1-64 data 86 count) 1)
|
||||
(+! (-> v1-64 data 86 used)
|
||||
(&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint gp-0))
|
||||
)
|
||||
(set! (-> v1-64 data 86 total) (-> v1-64 data 86 used))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
;; (format 0 "[GMERC] made it to the end of generic-merc-execute-all.~%")
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
(next-chain uint32 :offset-assert 276)
|
||||
(buf-index uint32 :offset-assert 280)
|
||||
(fragment-count uint32 :offset-assert 284)
|
||||
(write-limit int32 :offset-assert 288)
|
||||
(write-limit pointer :offset-assert 288)
|
||||
(indexed-input-base generic-merc-input :offset-assert 292)
|
||||
(other-input-base generic-merc-input :offset-assert 296)
|
||||
(indexed-output-base generic-merc-output :offset-assert 300)
|
||||
|
||||
@@ -86,11 +86,13 @@
|
||||
)
|
||||
|
||||
(defun merc-death-spawn ((arg0 int) (arg1 vector) (arg2 vector))
|
||||
(let ((v1-2 (-> *part-id-table* arg0)))
|
||||
(if (and (nonzero? v1-2) (= (-> v1-2 type) sparticle-launcher))
|
||||
(sp-launch-particles-death *sp-particle-system-2d* v1-2 arg1)
|
||||
)
|
||||
)
|
||||
(#unless SKIP_MERC_DEATH_PARTICLES
|
||||
(let ((v1-2 (-> *part-id-table* arg0)))
|
||||
(if (and (nonzero? v1-2) (= (-> v1-2 type) sparticle-launcher))
|
||||
(sp-launch-particles-death *sp-particle-system-2d* v1-2 arg1)
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
@@ -93,6 +93,10 @@
|
||||
(none)
|
||||
)
|
||||
|
||||
(defmethod asize-of merc-fragment-control ((obj merc-fragment-control))
|
||||
(the-as int (+ (* (-> obj mat-xfer-count) 2) 4))
|
||||
)
|
||||
|
||||
(defmethod inspect merc-fragment-control ((obj merc-fragment-control))
|
||||
"Debug print a merc-fragment-control"
|
||||
(format #t "[~8x] ~A~%" obj 'merc-fragment-control)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
;; name in dgo: ripple
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
(define-extern ripple-execute-init (function none))
|
||||
(define-extern ripple-create-wave-table (function ripple-wave-set int))
|
||||
(define-extern ripple-apply-wave-table (function merc-effect symbol))
|
||||
|
||||
@@ -67,13 +66,13 @@
|
||||
)
|
||||
|
||||
;; definition for function ripple-execute-init
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
(def-mips2c ripple-execute-init (function none))
|
||||
|
||||
;; definition for function ripple-create-wave-table
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
(def-mips2c ripple-create-wave-table (function ripple-wave-set int))
|
||||
|
||||
;; definition for function ripple-apply-wave-table
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
(def-mips2c ripple-apply-wave-table (function merc-effect symbol))
|
||||
|
||||
(defun ripple-execute ()
|
||||
(when (-> *ripple-globals* count)
|
||||
|
||||
@@ -40,13 +40,6 @@ const goos::Object& cdr(const goos::Object& x) {
|
||||
return x.as_pair()->cdr;
|
||||
}
|
||||
|
||||
std::string get_string(const goos::Object& x) {
|
||||
if (x.is_string()) {
|
||||
return x.as_string()->data;
|
||||
}
|
||||
throw std::runtime_error(x.print() + " was supposed to be a string, but isn't");
|
||||
}
|
||||
|
||||
std::string uppercase(const std::string& in) {
|
||||
std::string result;
|
||||
result.reserve(in.size());
|
||||
|
||||
+3
-3
@@ -162,9 +162,9 @@
|
||||
|
||||
;; definition of type merc-globals
|
||||
(deftype merc-globals (structure)
|
||||
((first uint32 :offset-assert 0)
|
||||
(next uint32 :offset-assert 4)
|
||||
(sink basic :offset-assert 8)
|
||||
((first uint32 :offset-assert 0)
|
||||
(next (pointer uint32) :offset-assert 4)
|
||||
(sink generic-dma-foreground-sink :offset-assert 8)
|
||||
)
|
||||
:allow-misaligned
|
||||
:method-count-assert 9
|
||||
|
||||
+97
-99
@@ -957,9 +957,7 @@
|
||||
(+! upl-idx 1)
|
||||
)
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 11 scale x)
|
||||
(the-as float upl-idx)
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work num-uploads) upl-idx)
|
||||
)
|
||||
(dotimes (v1-24 nb-channels)
|
||||
(set! (-> arg0 channel v1-24 inspector-amount)
|
||||
@@ -1281,149 +1279,149 @@
|
||||
|
||||
;; definition for function make-joint-jump-tables
|
||||
(defun make-joint-jump-tables ()
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 scale x)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 108 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 0)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 108 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 scale y)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 1)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 scale z)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 233 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 2)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 233 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 scale w)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 3)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 cache bone-matrix)
|
||||
(the-as uint (+ (the-as uint decompress-fixed-data-to-accumulator) (* 301 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 4)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 301 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 cache parent-matrix)
|
||||
(the-as uint (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 5)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 cache dummy)
|
||||
(the-as uint (+ (the-as uint decompress-fixed-data-to-accumulator) (* 387 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 6)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 387 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 3 cache frame)
|
||||
(the-as uint (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 7)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 0 x)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 155 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 8)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 155 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 0 y)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 9)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 0 z)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 261 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 10)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 261 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 0 w)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 11)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 1 x)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 335 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 12)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 335 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 1 y)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 13)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 1 z)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 402 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 14)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 402 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 1 w)
|
||||
(the-as float (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work fix-jmp-table 15)
|
||||
(the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 2 x)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 0)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 2 y)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 92 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 1)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 92 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 2 z)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 2)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 2 w)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 140 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 3)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 140 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 3 x)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 4)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 3 y)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 220 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 5)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 220 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 3 z)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 6)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 transform vector 3 w)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 307 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 7)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 307 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 scale x)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 8)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 scale y)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 107 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 9)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 107 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 scale z)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 10)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 scale w)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-to-accumulator) (* 174 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 11)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 174 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 cache bone-matrix)
|
||||
(the-as uint (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 12)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 cache parent-matrix)
|
||||
(the-as uint (+ (the-as uint decompress-frame-data-to-accumulator) (* 248 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 13)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 248 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 cache dummy)
|
||||
(the-as uint (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 14)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 4 cache frame)
|
||||
(the-as uint (+ (the-as uint decompress-frame-data-to-accumulator) (* 354 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work frm-jmp-table 15)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 354 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 0 x)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 0)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 0 y)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 125 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 1)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 125 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 0 z)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 2)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 0 w)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 197 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 3)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 197 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 1 x)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 4)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 1 y)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 318 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 5)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 318 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 1 z)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 6)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 1 w)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 459 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 7)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 459 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 2 x)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 8)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 2 y)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 150 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 9)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 150 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 2 z)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 10)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 2 w)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 248 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 11)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 248 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 3 x)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 12)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 3 y)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 366 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 13)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 366 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 3 z)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 14)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4)))
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground bone-mem buffer 0 bone 5 transform vector 3 w)
|
||||
(the-as float (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 533 4)))
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work pair-jmp-table 15)
|
||||
(the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 533 4)))
|
||||
)
|
||||
0
|
||||
)
|
||||
|
||||
+2
-2
@@ -929,7 +929,7 @@
|
||||
(when (nonzero? (-> *merc-globals* first))
|
||||
(let ((s4-1 (-> *display* frames (-> *display* on-screen) frame global-buf base)))
|
||||
(let ((a0-25 (-> (the-as (pointer uint32) (+ (the-as uint *level*) (* 2608 arg2) (* arg3 32))) 69)))
|
||||
(generic-merc-add-to-cue (the-as basic a0-25))
|
||||
(generic-merc-add-to-cue (the-as generic-dma-foreground-sink a0-25))
|
||||
)
|
||||
(let ((a0-26 *dma-mem-usage*))
|
||||
(when (nonzero? a0-26)
|
||||
@@ -1322,7 +1322,7 @@
|
||||
)
|
||||
(let ((gp-9 (-> *display* frames (-> *display* on-screen) frame global-buf)))
|
||||
(bones-mtx-calc-execute)
|
||||
(generic-merc-execute-all)
|
||||
(generic-merc-execute-all gp-9)
|
||||
(shadow-execute-all gp-9 *shadow-queue*)
|
||||
)
|
||||
(-> *display* frames (-> *display* on-screen) frame global-buf)
|
||||
|
||||
+3
-3
@@ -340,8 +340,8 @@
|
||||
;; definition for method 3 of type generic-gif-tag
|
||||
(defmethod inspect generic-gif-tag ((obj generic-gif-tag))
|
||||
(format #t "[~8x] ~A~%" obj 'generic-gif-tag)
|
||||
(format #t "~Tdata[4] @ #x~X~%" (-> obj data))
|
||||
(format #t "~Tqword: #<qword @ #x~X>~%" (-> obj data))
|
||||
(format #t "~Tdata[4] @ #x~X~%" (&-> obj fan-prim))
|
||||
(format #t "~Tqword: #<qword @ #x~X>~%" (&-> obj fan-prim))
|
||||
(format #t "~Tfan-prim: ~D~%" (-> obj fan-prim))
|
||||
(format #t "~Tstr-prim: ~D~%" (-> obj str-prim))
|
||||
(format #t "~Tregs: ~D~%" (-> obj regs))
|
||||
@@ -370,7 +370,7 @@
|
||||
;; Used lq/sq
|
||||
(defmethod inspect ad-cmd ((obj ad-cmd))
|
||||
(format #t "[~8x] ~A~%" obj 'ad-cmd)
|
||||
(format #t "~Tword[4] @ #x~X~%" (-> obj word))
|
||||
(format #t "~Tword[4] @ #x~X~%" (&-> obj data))
|
||||
(format #t "~Tquad: ~D~%" (-> obj quad))
|
||||
(format #t "~Tdata: ~D~%" (-> obj data))
|
||||
(format #t "~Tcmds: ~D~%" (-> obj cmds))
|
||||
|
||||
+181
-12
@@ -10,6 +10,7 @@
|
||||
(init-data uint8 :offset-assert 1)
|
||||
(init-addr uint16 :offset-assert 2)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
@@ -27,13 +28,13 @@
|
||||
;; definition for symbol *inv-init-table*, type (inline-array invinitdata)
|
||||
(define *inv-init-table* (new 'static 'inline-array invinitdata 8
|
||||
(new 'static 'invinitdata :count #x48 :init-addr #x1)
|
||||
(new 'static 'invinitdata :count #x43 :init-data #xc :init-addr #x11)
|
||||
(new 'static 'invinitdata :count #x3d :init-data #x18 :init-addr #x21)
|
||||
(new 'static 'invinitdata :count #x38 :init-data #x22 :init-addr #xe0)
|
||||
(new 'static 'invinitdata :count #x38 :init-data #x24 :init-addr #xe1)
|
||||
(new 'static 'invinitdata :count #xbe)
|
||||
(new 'static 'invinitdata :count #x81 :init-data #x80 :init-addr #x3b80)
|
||||
(new 'static 'invinitdata :count #x88 :init-data #x50 :init-addr #x100a)
|
||||
(new 'static 'invinitdata :count #x7d :init-data #xb :init-addr #x81e8)
|
||||
(new 'static 'invinitdata :count #x7d :init-data #x1b :init-addr #x81e8)
|
||||
(new 'static 'invinitdata :count #x2 :init-data #x68 :init-addr #x5200)
|
||||
(new 'static 'invinitdata :count #x33 :init-data #x30 :init-addr #xf1)
|
||||
(new 'static 'invinitdata :count #x2e :init-data #x3a :init-addr #x190)
|
||||
(new 'static 'invinitdata :count #x2d :init-data #x3c :init-addr #x191)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -60,7 +61,7 @@
|
||||
|
||||
;; definition for function generic-merc-add-to-cue
|
||||
;; INFO: Return type mismatch merc-globals vs none.
|
||||
(defun generic-merc-add-to-cue ((arg0 basic))
|
||||
(defun generic-merc-add-to-cue ((arg0 generic-dma-foreground-sink))
|
||||
(set! (-> *merc-globals* sink) arg0)
|
||||
(+! (-> *merc-global-array* count) 1)
|
||||
(set! *merc-globals* (-> *merc-global-array* globals (-> *merc-global-array* count)))
|
||||
@@ -68,8 +69,176 @@
|
||||
)
|
||||
|
||||
;; definition for function generic-merc-execute-all
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
|
||||
|
||||
|
||||
;; INFO: Return type mismatch profile-frame vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, r0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.p]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mtpc pcr0, r0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mtpc pcr1, r0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.p]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, a0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.p]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mtc0 Perf, r0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.p]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfpc a0, pcr0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfpc a0, pcr1]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [cache dxwbin v1, 0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [cache dxwbin v1, 1]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun generic-merc-execute-all ((arg0 dma-buffer))
|
||||
(local-vars (a0-26 int) (a0-28 int))
|
||||
(when (nonzero? (-> *merc-global-array* count))
|
||||
(let ((gp-0 (-> *display* frames (-> *display* on-screen) frame global-buf base)))
|
||||
(if *debug-segment*
|
||||
(add-frame
|
||||
(-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #x40 :b #x40 :a #x80)
|
||||
)
|
||||
)
|
||||
(let* ((v1-15 (-> *perf-stats* data 1))
|
||||
(a0-8 (-> v1-15 ctrl))
|
||||
)
|
||||
(+! (-> v1-15 count) 1)
|
||||
(b! (zero? a0-8) cfg-5 :delay (nop!))
|
||||
(.mtc0 Perf r0)
|
||||
(.sync.l)
|
||||
(.sync.p)
|
||||
(.mtpc pcr0 r0)
|
||||
(.mtpc pcr1 r0)
|
||||
(.sync.l)
|
||||
(.sync.p)
|
||||
(.mtc0 Perf a0-8)
|
||||
)
|
||||
(.sync.l)
|
||||
(.sync.p)
|
||||
(label cfg-5)
|
||||
0
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 y)
|
||||
(the-as float 0)
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 z)
|
||||
(the-as float 0)
|
||||
)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 w)
|
||||
(the-as float 0)
|
||||
)
|
||||
(flush-cache 0)
|
||||
(generic-initialize-without-sink (-> *math-camera* perspective) *default-lights*)
|
||||
(generic-merc-init-asm)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work tq-acc 99 trans x)
|
||||
(the-as float (&+ (-> arg0 end) -65536))
|
||||
)
|
||||
(dotimes (s4-0 (the-as int (-> *merc-global-array* count)))
|
||||
(set! *merc-globals* (-> *merc-global-array* globals s4-0))
|
||||
(let ((s3-0 (-> *merc-globals* sink)))
|
||||
(when (nonzero? (-> *merc-globals* first))
|
||||
(let* ((s1-0 (-> *display* frames (-> *display* on-screen) frame global-buf))
|
||||
(s2-0 (-> s1-0 base))
|
||||
)
|
||||
(generic-work-init s3-0)
|
||||
(set! (-> (the-as terrain-context #x70000000) work foreground joint-work temp-mtx vector 3 w)
|
||||
(the-as float (-> s1-0 base))
|
||||
)
|
||||
(generic-merc-execute-asm)
|
||||
(set! (-> s1-0 base)
|
||||
(the-as pointer (-> (the-as terrain-context #x70000000) work foreground joint-work temp-mtx vector 3 w))
|
||||
)
|
||||
(let ((v1-36 (the-as object #x1000d000))
|
||||
(a0-19 (the-as object #x7000006c))
|
||||
)
|
||||
(b! (zero? (logand (-> (the-as terrain-context v1-36) bsp lev-index) 256)) cfg-9 :delay (nop!))
|
||||
(let ((a1-6 (-> (the-as generic-envmap-saves a0-19) index-mask x)))
|
||||
(nop!)
|
||||
(let ((a2-1 (-> (the-as (pointer int32) v1-36) 0)))
|
||||
(nop!)
|
||||
(let ((a2-2 (logand a2-1 256))
|
||||
(a1-7 (+ a1-6 1))
|
||||
)
|
||||
(b! (nonzero? a2-2) cfg-8 :delay (s.w! (the-as int a0-19) a1-7))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(label cfg-9)
|
||||
0
|
||||
(let ((a3-0 (-> s1-0 base)))
|
||||
(let ((v1-38 (the-as object (-> s1-0 base))))
|
||||
(set! (-> (the-as dma-packet v1-38) dma) (new 'static 'dma-tag :id (dma-tag-id next)))
|
||||
(set! (-> (the-as dma-packet v1-38) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet v1-38) vif1) (new 'static 'vif-tag))
|
||||
(set! (-> s1-0 base) (&+ (the-as pointer v1-38) 16))
|
||||
)
|
||||
(dma-bucket-insert-tag
|
||||
(-> *display* frames (-> *display* on-screen) frame bucket-group)
|
||||
(-> s3-0 bucket)
|
||||
s2-0
|
||||
(the-as (pointer dma-tag) a3-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((v1-44 (-> arg0 base)))
|
||||
(.sync.l)
|
||||
(.cache dxwbin v1-44 0)
|
||||
(.sync.l)
|
||||
(.cache dxwbin v1-44 1)
|
||||
)
|
||||
(.sync.l)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((v1-51 (-> *perf-stats* data 1)))
|
||||
(b! (zero? (-> v1-51 ctrl)) cfg-14 :delay (nop!))
|
||||
(.mtc0 Perf r0)
|
||||
(.sync.l)
|
||||
(.sync.p)
|
||||
(.mfpc a0-26 pcr0)
|
||||
(+! (-> v1-51 accum0) a0-26)
|
||||
(.mfpc a0-28 pcr1)
|
||||
(+! (-> v1-51 accum1) a0-28)
|
||||
)
|
||||
(label cfg-14)
|
||||
0
|
||||
(update-wait-stats
|
||||
(-> *perf-stats* data 1)
|
||||
(the-as
|
||||
uint
|
||||
(-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 y)
|
||||
)
|
||||
(the-as
|
||||
uint
|
||||
(-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 z)
|
||||
)
|
||||
(the-as
|
||||
uint
|
||||
(-> (the-as terrain-context #x70000000) work foreground joint-work joint-stack data 0 vector 0 w)
|
||||
)
|
||||
)
|
||||
(if *debug-segment*
|
||||
(add-frame
|
||||
(-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
||||
'draw
|
||||
(new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
|
||||
)
|
||||
)
|
||||
(let ((v1-64 *dma-mem-usage*))
|
||||
(when (nonzero? v1-64)
|
||||
(set! (-> v1-64 length) (max 87 (-> v1-64 length)))
|
||||
(set! (-> v1-64 data 86 name) "pris-generic")
|
||||
(+! (-> v1-64 data 86 count) 1)
|
||||
(+! (-> v1-64 data 86 used)
|
||||
(&- (-> *display* frames (-> *display* on-screen) frame global-buf base) (the-as uint gp-0))
|
||||
)
|
||||
(set! (-> v1-64 data 86 total) (-> v1-64 data 86 used))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@
|
||||
(next-chain uint32 :offset-assert 276)
|
||||
(buf-index uint32 :offset-assert 280)
|
||||
(fragment-count uint32 :offset-assert 284)
|
||||
(write-limit int32 :offset-assert 288)
|
||||
(write-limit pointer :offset-assert 288)
|
||||
(indexed-input-base generic-merc-input :offset-assert 292)
|
||||
(other-input-base generic-merc-input :offset-assert 296)
|
||||
(indexed-output-base generic-merc-output :offset-assert 300)
|
||||
|
||||
+57
-63
@@ -64,66 +64,64 @@
|
||||
)
|
||||
|
||||
;; definition for symbol *shadow-vu1-tri-template*, type shadow-vu1-gifbuf-template
|
||||
(define
|
||||
*shadow-vu1-tri-template*
|
||||
(new 'static 'shadow-vu1-gifbuf-template
|
||||
:adgif
|
||||
(new 'static 'gs-gif-tag
|
||||
:tag
|
||||
(new 'static 'gif-tag64 :nloop #x1 :nreg #x1)
|
||||
:regs
|
||||
(new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d))
|
||||
)
|
||||
:ad
|
||||
(new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x0 #x0 #x3f #x0))
|
||||
:flush
|
||||
(new 'static 'ad-cmd :word (new 'static 'array uint32 4 #x0 #x3f800000 #x1 #x0))
|
||||
:trigif
|
||||
(new 'static 'gs-gif-tag
|
||||
:tag
|
||||
(new 'static 'gif-tag64
|
||||
:nloop #x1
|
||||
:eop #x1
|
||||
:pre #x1
|
||||
:prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1)
|
||||
:nreg #x7
|
||||
(define *shadow-vu1-tri-template* (new 'static 'shadow-vu1-gifbuf-template
|
||||
:adgif
|
||||
(new 'static 'gs-gif-tag
|
||||
:tag
|
||||
(new 'static 'gif-tag64 :nloop #x1 :nreg #x1)
|
||||
:regs
|
||||
(new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d))
|
||||
)
|
||||
:ad
|
||||
(new 'static 'ad-cmd :cmd (gs-reg texflush))
|
||||
:flush
|
||||
(new 'static 'ad-cmd :data #x3f80000000000000 :cmd (gs-reg rgbaq))
|
||||
:trigif
|
||||
(new 'static 'gs-gif-tag
|
||||
:tag
|
||||
(new 'static 'gif-tag64
|
||||
:nloop #x1
|
||||
:eop #x1
|
||||
:pre #x1
|
||||
:prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1)
|
||||
:nreg #x7
|
||||
)
|
||||
:regs
|
||||
(new 'static 'gif-tag-regs
|
||||
:regs0 (gif-reg-id rgbaq)
|
||||
:regs1 (gif-reg-id st)
|
||||
:regs2 (gif-reg-id xyzf2)
|
||||
:regs3 (gif-reg-id st)
|
||||
:regs4 (gif-reg-id xyzf2)
|
||||
:regs5 (gif-reg-id st)
|
||||
:regs6 (gif-reg-id xyzf2)
|
||||
)
|
||||
)
|
||||
:quadgif
|
||||
(new 'static 'gs-gif-tag
|
||||
:tag
|
||||
(new 'static 'gif-tag64
|
||||
:nloop #x1
|
||||
:eop #x1
|
||||
:pre #x1
|
||||
:prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1)
|
||||
:nreg #x9
|
||||
)
|
||||
:regs
|
||||
(new 'static 'gif-tag-regs
|
||||
:regs0 (gif-reg-id rgbaq)
|
||||
:regs1 (gif-reg-id st)
|
||||
:regs2 (gif-reg-id xyzf2)
|
||||
:regs3 (gif-reg-id st)
|
||||
:regs4 (gif-reg-id xyzf2)
|
||||
:regs5 (gif-reg-id st)
|
||||
:regs6 (gif-reg-id xyzf2)
|
||||
:regs7 (gif-reg-id st)
|
||||
:regs8 (gif-reg-id xyzf2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
:regs
|
||||
(new 'static 'gif-tag-regs
|
||||
:regs0 (gif-reg-id rgbaq)
|
||||
:regs1 (gif-reg-id st)
|
||||
:regs2 (gif-reg-id xyzf2)
|
||||
:regs3 (gif-reg-id st)
|
||||
:regs4 (gif-reg-id xyzf2)
|
||||
:regs5 (gif-reg-id st)
|
||||
:regs6 (gif-reg-id xyzf2)
|
||||
)
|
||||
)
|
||||
:quadgif
|
||||
(new 'static 'gs-gif-tag
|
||||
:tag
|
||||
(new 'static 'gif-tag64
|
||||
:nloop #x1
|
||||
:eop #x1
|
||||
:pre #x1
|
||||
:prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1)
|
||||
:nreg #x9
|
||||
)
|
||||
:regs
|
||||
(new 'static 'gif-tag-regs
|
||||
:regs0 (gif-reg-id rgbaq)
|
||||
:regs1 (gif-reg-id st)
|
||||
:regs2 (gif-reg-id xyzf2)
|
||||
:regs3 (gif-reg-id st)
|
||||
:regs4 (gif-reg-id xyzf2)
|
||||
:regs5 (gif-reg-id st)
|
||||
:regs6 (gif-reg-id xyzf2)
|
||||
:regs7 (gif-reg-id st)
|
||||
:regs8 (gif-reg-id xyzf2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for symbol shadow-vu1-block, type vu-function
|
||||
(define shadow-vu1-block (new 'static 'vu-function :length #x2e4 :qlength #x172))
|
||||
@@ -247,7 +245,3 @@
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -298,10 +298,10 @@
|
||||
;; definition for method 3 of type foreground-area
|
||||
(defmethod inspect foreground-area ((obj foreground-area))
|
||||
(format #t "[~8x] ~A~%" obj 'foreground-area)
|
||||
(format #t "~Tjoint-work: #<joint-work @ #x~X>~%" (-> obj bone-mem))
|
||||
(format #t "~Tgeneric-work: #<generic-work @ #x~X>~%" (-> obj bone-mem))
|
||||
(format #t "~Tbone-mem: #<bone-memory @ #x~X>~%" (-> obj bone-mem))
|
||||
(format #t "~Tshadow-work: #<shadow-work @ #x~X>~%" (-> obj bone-mem))
|
||||
(format #t "~Tjoint-work: #<joint-work @ #x~X>~%" (-> obj joint-work))
|
||||
(format #t "~Tgeneric-work: #<generic-work @ #x~X>~%" (-> obj joint-work))
|
||||
(format #t "~Tbone-mem: #<bone-memory @ #x~X>~%" (-> obj joint-work))
|
||||
(format #t "~Tshadow-work: #<shadow-work @ #x~X>~%" (-> obj joint-work))
|
||||
obj
|
||||
)
|
||||
|
||||
|
||||
@@ -73,15 +73,29 @@ TEST(VuDisasm, OceanVu0) {
|
||||
TEST(VuDisasm, GenericVu0) {
|
||||
auto data = get_test_data("generic-vu0");
|
||||
VuDisassembler disasm(VuDisassembler::VuKind::VU0);
|
||||
// disasm.add_label_with_name(48, "JUMP_48");
|
||||
auto prog = disasm.disassemble(data.data(), data.size() * 4, false);
|
||||
EXPECT_EQ(disasm.to_string(prog), get_expected("generic-vu0"));
|
||||
// fmt::print("{}\n", disasm.to_string_with_cpp(prog, true));
|
||||
}
|
||||
|
||||
TEST(VuDisasm, MercnericVu0) {
|
||||
auto data = get_test_data("mercneric-vu0");
|
||||
VuDisassembler disasm(VuDisassembler::VuKind::VU0);
|
||||
// disasm.add_label_with_name(314 - 280, "JUMP_314");
|
||||
// disasm.add_label_with_name(326 - 280, "JUMP_326");
|
||||
// disasm.add_label_with_name(353 - 280, "JUMP_353");
|
||||
// disasm.add_label_with_name(386 - 280, "JUMP_386");
|
||||
// disasm.add_label_with_name(427 - 280, "JUMP_427");
|
||||
// disasm.add_label_with_name(438 - 280, "JUMP_438");
|
||||
// disasm.add_label_with_name(454 - 280, "JUMP_454");
|
||||
|
||||
auto prog = disasm.disassemble(data.data(), data.size() * 4, false);
|
||||
EXPECT_EQ(disasm.to_string(prog), get_expected("mercneric-vu0"));
|
||||
// disasm.add_label_with_name(0, "vcallms_280");
|
||||
// disasm.add_label_with_name(303 - 280, "vcallms_303");
|
||||
|
||||
// fmt::print("{}\n", disasm.to_string_with_cpp(prog, true));
|
||||
}
|
||||
|
||||
TEST(VuDisasm, OceanTexture) {
|
||||
@@ -138,6 +152,7 @@ TEST(VuDisasm, Generic) {
|
||||
VuDisassembler disasm(VuDisassembler::VuKind::VU1);
|
||||
auto prog = disasm.disassemble(data.data(), data.size() * 4, false);
|
||||
EXPECT_EQ(disasm.to_string(prog), get_expected("generic"));
|
||||
fmt::print("{}\n", disasm.to_string_with_cpp(prog, false));
|
||||
}
|
||||
|
||||
TEST(VuDisasm, TieNear) {
|
||||
|
||||
@@ -231,7 +231,8 @@
|
||||
|
||||
"curve-evaluate!",
|
||||
|
||||
"generic-reset-buffers"
|
||||
"generic-reset-buffers",
|
||||
"generic-merc-execute-all"
|
||||
],
|
||||
|
||||
"skip_compile_states": {
|
||||
|
||||
+5
-4
@@ -289,7 +289,7 @@ namespace fpng
|
||||
return crc32_slice_by_4(buf + simd_len, len - simd_len, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef _MSC_VER
|
||||
static void do_cpuid(uint32_t eax, uint32_t ecx, uint32_t* regs)
|
||||
{
|
||||
@@ -307,6 +307,7 @@ namespace fpng
|
||||
regs[0] = eax; regs[1] = ebx; regs[2] = ecx; regs[3] = edx;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
#if FPNG_X86_OR_X64_CPU && !FPNG_NO_SSE
|
||||
struct cpu_info
|
||||
@@ -1591,8 +1592,8 @@ do_literals:
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
const uint8_t* pSrc = (uint8_t*)pImage + y * bpl;
|
||||
const uint8_t* pPrev_src = y ? ((uint8_t*)pImage + (y - 1) * bpl) : nullptr;
|
||||
const uint8_t* pSrc = (const uint8_t*)pImage + y * bpl;
|
||||
const uint8_t* pPrev_src = y ? ((const uint8_t*)pImage + (y - 1) * bpl) : nullptr;
|
||||
|
||||
uint8_t* pDst = &temp_buf[temp_buf_ofs];
|
||||
|
||||
@@ -1636,7 +1637,7 @@ do_literals:
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
const uint8_t* pSrc = (uint8_t*)pImage + y * bpl;
|
||||
const uint8_t* pSrc = (const uint8_t*)pImage + y * bpl;
|
||||
|
||||
uint8_t* pDst = &temp_buf[temp_buf_ofs];
|
||||
|
||||
|
||||
+5
-1
@@ -14,9 +14,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/util/Assert.h"
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
#ifdef __linux__
|
||||
#define IM_ASSERT(_EXPR) ASSERT(_EXPR)
|
||||
#endif
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
|
||||
Reference in New Issue
Block a user