[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:
water111
2022-02-24 22:33:10 -05:00
committed by GitHub
parent 71f08fbd8c
commit 9c00b0c135
58 changed files with 11482 additions and 990 deletions
+10 -3
View File
@@ -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);
+4
View File
@@ -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) {
+1
View File
@@ -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;
}
/*!
+3 -3
View File
@@ -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());
+226 -74
View File
@@ -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));
}
}
+3 -3
View File
@@ -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);
+64 -6
View File
@@ -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");
+20 -19
View File
@@ -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);
}
+6 -1
View File
@@ -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());
+5
View File
@@ -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
+494
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
+1 -420
View File
@@ -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
+580
View File
@@ -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
+241 -9
View File
@@ -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
+46 -1
View File
@@ -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>()}});
+2 -2
View File
@@ -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
View File
@@ -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)
)
+25 -22
View File
@@ -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
+3
View File
@@ -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)
+1 -1
View File
@@ -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)
+153 -12
View File
@@ -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)
)
+1 -1
View File
@@ -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)
+7 -5
View File
@@ -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)
)
+4
View File
@@ -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)
+3 -4
View File
@@ -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)
-7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
)
+15
View File
@@ -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) {
+2 -1
View File
@@ -231,7 +231,8 @@
"curve-evaluate!",
"generic-reset-buffers"
"generic-reset-buffers",
"generic-merc-execute-all"
],
"skip_compile_states": {
Generated Vendored
+5 -4
View File
@@ -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
View File
@@ -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