[jak2] decomp neon-baron-part, fix merc fog disable (#2443)

- decompile `neon-baron-part`, which also has the hideout door for some
reason
- improve a few error messages in static data decompilation
- fix bug with disabling fog in merc
This commit is contained in:
water111 2023-03-31 17:47:38 -04:00 committed by GitHub
parent 1b27257e8a
commit 57b5117cae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 8091 additions and 40 deletions

View file

@ -73,7 +73,7 @@ struct MemoryUsageTracker {
void add(MemoryUsageCategory category, u32 size_bytes) { data[category] += size_bytes; } void add(MemoryUsageCategory category, u32 size_bytes) { data[category] += size_bytes; }
}; };
constexpr int TFRAG3_VERSION = 31; constexpr int TFRAG3_VERSION = 32;
// These vertices should be uploaded to the GPU at load time and don't change // These vertices should be uploaded to the GPU at load time and don't change
struct PreloadedVertex { struct PreloadedVertex {

View file

@ -115,7 +115,11 @@ int LabelDB::get_index_by_name(const std::string& name) const {
return m_labels_by_name.at(name); return m_labels_by_name.at(name);
} }
bool LabelDB::label_exists_by_name(const std::string& name) const { bool LabelDB::label_info_known_by_name(const std::string& name) const {
return m_labels_by_name.count(name) != 0; auto it = m_labels_by_name.find(name);
if (it == m_labels_by_name.end()) {
return false;
}
return lookup(it->second).known;
} }
} // namespace decompiler } // namespace decompiler

View file

@ -35,7 +35,9 @@ class LabelDB {
int get_index_by_offset(int seg, int offset) const; int get_index_by_offset(int seg, int offset) const;
std::optional<int> try_get_index_by_offset(int seg, int offset) const; std::optional<int> try_get_index_by_offset(int seg, int offset) const;
int get_index_by_name(const std::string& name) const; int get_index_by_name(const std::string& name) const;
bool label_exists_by_name(const std::string& name) const;
// automatic, or from user
bool label_info_known_by_name(const std::string& name) const;
LabelInfo set_and_get_previous(int idx, LabelInfo set_and_get_previous(int idx,
const TypeSpec& type, const TypeSpec& type,

View file

@ -34974,8 +34974,8 @@
(flags int64 :offset-assert 128) (flags int64 :offset-assert 128)
(master-enable int64 :offset-assert 136) (master-enable int64 :offset-assert 136)
(mode int64 :offset-assert 144) (mode int64 :offset-assert 144)
(sign symbol :offset-assert 152) (sign (array object) :offset-assert 152)
(parts basic 1 :offset-assert 156) (parts sparticle-launch-control 1 :offset-assert 156)
(state-time time-frame :offset-assert 160) (state-time time-frame :offset-assert 160)
(mat matrix :inline :offset-assert 176) (mat matrix :inline :offset-assert 176)
) )
@ -34984,8 +34984,8 @@
:flag-assert #x11007000f0 :flag-assert #x11007000f0
(:methods (:methods
(idle () _type_ :state 14) (idle () _type_ :state 14)
(neon-baron-method-15 () none 15) (spawn-parts (_type_) none 15)
(neon-baron-method-16 () none 16) (update-mode (_type_) none 16)
) )
) )
@ -34998,7 +34998,7 @@
(define-extern *baron-neon-skull* (array object)) (define-extern *baron-neon-skull* (array object))
(define-extern *city-baron-group-ids* (array int32)) (define-extern *city-baron-group-ids* (array int32))
(define-extern *neon-baron-flashing-acc* (pointer int32)) (define-extern *neon-baron-flashing-acc* (pointer uint32))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; palace-ocean ;; ;; palace-ocean ;;

View file

@ -669,7 +669,205 @@
"neon-baron-part": [ "neon-baron-part": [
["L604", "uint64", true], ["L604", "uint64", true],
["L605", "uint64", true], ["L605", "uint64", true],
["L588", "uint64", true] ["L588", "(pointer uint64)", 1],
["L92", "(pointer uint32)", 40],
["L567", "vector4w"],
["L568", "vector4w"],
["L569", "vector4w"],
["L570", "vector4w"],
["L571", "vector4w"],
["L572", "vector4w"],
["L573", "vector4w"],
["L574", "vector4w"],
["L575", "vector4w"],
["L576", "vector4w"],
["L577", "vector4w"],
["L578", "vector4w"],
["L579", "vector4w"],
["L580", "vector4w"],
["L581", "vector4w"],
["L582", "vector4w"],
["L583", "vector4w"],
["L584", "vector4w"],
["L585", "vector4w"],
["L586", "vector4w"],
["L565", "vector4w"],
["L563", "vector4w"],
["L535", "vector4w"],
["L536", "vector4w"],
["L537", "vector4w"],
["L538", "vector4w"],
["L539", "vector4w"],
["L540", "vector4w"],
["L541", "vector4w"],
["L542", "vector4w"],
["L543", "vector4w"],
["L544", "vector4w"],
["L545", "vector4w"],
["L546", "vector4w"],
["L547", "vector4w"],
["L548", "vector4w"],
["L549", "vector4w"],
["L550", "vector4w"],
["L551", "vector4w"],
["L552", "vector4w"],
["L553", "vector4w"],
["L554", "vector4w"],
["L555", "vector4w"],
["L556", "vector4w"],
["L557", "vector4w"],
["L558", "vector4w"],
["L559", "vector4w"],
["L560", "vector4w"],
["L522", "vector4w"],
["L523", "vector4w"],
["L524", "vector4w"],
["L525", "vector4w"],
["L526", "vector4w"],
["L527", "vector4w"],
["L528", "vector4w"],
["L529", "vector4w"],
["L530", "vector4w"],
["L531", "vector4w"],
["L532", "vector4w"],
["L533", "vector4w"],
["L522", "vector4w"],
["L523", "vector4w"],
["L524", "vector4w"],
["L525", "vector4w"],
["L526", "vector4w"],
["L527", "vector4w"],
["L528", "vector4w"],
["L529", "vector4w"],
["L530", "vector4w"],
["L531", "vector4w"],
["L532", "vector4w"],
["L533", "vector4w"],
["L393", "vector4w"],
["L394", "vector4w"],
["L395", "vector4w"],
["L396", "vector4w"],
["L397", "vector4w"],
["L398", "vector4w"],
["L399", "vector4w"],
["L400", "vector4w"],
["L401", "vector4w"],
["L402", "vector4w"],
["L403", "vector4w"],
["L404", "vector4w"],
["L405", "vector4w"],
["L406", "vector4w"],
["L407", "vector4w"],
["L408", "vector4w"],
["L409", "vector4w"],
["L410", "vector4w"],
["L411", "vector4w"],
["L412", "vector4w"],
["L413", "vector4w"],
["L414", "vector4w"],
["L415", "vector4w"],
["L416", "vector4w"],
["L417", "vector4w"],
["L418", "vector4w"],
["L419", "vector4w"],
["L420", "vector4w"],
["L421", "vector4w"],
["L422", "vector4w"],
["L423", "vector4w"],
["L424", "vector4w"],
["L425", "vector4w"],
["L426", "vector4w"],
["L427", "vector4w"],
["L428", "vector4w"],
["L429", "vector4w"],
["L430", "vector4w"],
["L431", "vector4w"],
["L432", "vector4w"],
["L433", "vector4w"],
["L434", "vector4w"],
["L435", "vector4w"],
["L436", "vector4w"],
["L437", "vector4w"],
["L438", "vector4w"],
["L439", "vector4w"],
["L440", "vector4w"],
["L441", "vector4w"],
["L442", "vector4w"],
["L443", "vector4w"],
["L444", "vector4w"],
["L445", "vector4w"],
["L446", "vector4w"],
["L447", "vector4w"],
["L448", "vector4w"],
["L449", "vector4w"],
["L450", "vector4w"],
["L451", "vector4w"],
["L452", "vector4w"],
["L453", "vector4w"],
["L454", "vector4w"],
["L455", "vector4w"],
["L456", "vector4w"],
["L457", "vector4w"],
["L458", "vector4w"],
["L459", "vector4w"],
["L460", "vector4w"],
["L461", "vector4w"],
["L462", "vector4w"],
["L463", "vector4w"],
["L464", "vector4w"],
["L465", "vector4w"],
["L466", "vector4w"],
["L467", "vector4w"],
["L468", "vector4w"],
["L469", "vector4w"],
["L470", "vector4w"],
["L471", "vector4w"],
["L472", "vector4w"],
["L473", "vector4w"],
["L474", "vector4w"],
["L475", "vector4w"],
["L476", "vector4w"],
["L477", "vector4w"],
["L478", "vector4w"],
["L479", "vector4w"],
["L480", "vector4w"],
["L481", "vector4w"],
["L482", "vector4w"],
["L483", "vector4w"],
["L484", "vector4w"],
["L485", "vector4w"],
["L486", "vector4w"],
["L487", "vector4w"],
["L488", "vector4w"],
["L489", "vector4w"],
["L490", "vector4w"],
["L491", "vector4w"],
["L492", "vector4w"],
["L493", "vector4w"],
["L494", "vector4w"],
["L495", "vector4w"],
["L496", "vector4w"],
["L497", "vector4w"],
["L498", "vector4w"],
["L499", "vector4w"],
["L500", "vector4w"],
["L501", "vector4w"],
["L502", "vector4w"],
["L503", "vector4w"],
["L504", "vector4w"],
["L505", "vector4w"],
["L506", "vector4w"],
["L507", "vector4w"],
["L508", "vector4w"],
["L509", "vector4w"],
["L510", "vector4w"],
["L511", "vector4w"],
["L512", "vector4w"],
["L514", "vector4w"],
["L516", "vector4w"],
["L518", "vector4w"],
["L520", "vector4w"],
["L561", "vector4w"]
], ],
"ctypal-part": [["L127", "uint64", true]], "ctypal-part": [["L127", "uint64", true]],
"under-part": [["L163", "uint64", true]], "under-part": [["L163", "uint64", true]],

View file

@ -11051,5 +11051,20 @@
[216, "a0", "(pointer uint64)"], [216, "a0", "(pointer uint64)"],
[218, "a0", "(pointer gs-reg64)"], [218, "a0", "(pointer gs-reg64)"],
[[227, 264], "s3", "dma-packet"] [[227, 264], "s3", "dma-packet"]
],
"(code idle neon-baron)": [
[248, "a0", "(array object)"],
[250, "a0", "(array object)"],
[282, "a0", "(array object)"],
[284, "a0", "(array object)"],
[316, "a0", "(array object)"],
[318, "a0", "(array object)"],
[350, "a0", "(array object)"],
[352, "a0", "(array object)"],
[384, "a0", "(array object)"],
[386, "a0", "(array object)"]
] ]
} }

View file

@ -13,7 +13,7 @@ void MercEyeCtrl::from_ref(TypedRef tr, const DecompilerTypeSystem& dts) {
eye_slot = read_plain_data_field<s8>(tr, "eye-slot", dts); eye_slot = read_plain_data_field<s8>(tr, "eye-slot", dts);
} }
void MercCtrlHeader::from_ref(TypedRef tr, const DecompilerTypeSystem& dts, GameVersion version) { void MercCtrlHeader::from_ref(TypedRef tr, const DecompilerTypeSystem& dts, GameVersion) {
st_magic = read_plain_data_field<u32>(tr, "st-magic", dts); st_magic = read_plain_data_field<u32>(tr, "st-magic", dts);
xyz_scale = read_plain_data_field<float>(tr, "xyz-scale", dts); xyz_scale = read_plain_data_field<float>(tr, "xyz-scale", dts);
st_out_a = read_plain_data_field<u32>(tr, "st-out-a", dts); st_out_a = read_plain_data_field<u32>(tr, "st-out-a", dts);
@ -58,16 +58,6 @@ void MercCtrlHeader::from_ref(TypedRef tr, const DecompilerTypeSystem& dts, Game
death_effect = read_plain_data_field<u32>(tr, "death-effect", dts); death_effect = read_plain_data_field<u32>(tr, "death-effect", dts);
use_translucent = read_plain_data_field<u8>(tr, "use-translucent", dts); use_translucent = read_plain_data_field<u8>(tr, "use-translucent", dts);
display_this_fragment = read_plain_data_field<u8>(tr, "display-this-fragment", dts); display_this_fragment = read_plain_data_field<u8>(tr, "display-this-fragment", dts);
if (version > GameVersion::Jak1) {
disable_fog = read_plain_data_field<u8>(tr, "disable-fog", dts);
use_warp = read_plain_data_field<u8>(tr, "use-warp", dts);
ignore_alpha = read_plain_data_field<u8>(tr, "ignore-alpha", dts);
force_fade = read_plain_data_field<u8>(tr, "force-fade", dts);
disable_envamp = read_plain_data_field<u8>(tr, "disable-envmap", dts);
} else {
disable_fog = false;
}
} }
std::string MercCtrlHeader::print() const { std::string MercCtrlHeader::print() const {

View file

@ -64,12 +64,6 @@ struct MercCtrlHeader {
u8 use_translucent; u8 use_translucent;
u8 display_this_fragment; u8 display_this_fragment;
u8 disable_fog = false; // jak 2 only
u8 use_warp = false;
u8 ignore_alpha = false;
u8 force_fade = false;
u8 disable_envamp = false;
void from_ref(TypedRef tr, const DecompilerTypeSystem& dts, GameVersion version); void from_ref(TypedRef tr, const DecompilerTypeSystem& dts, GameVersion version);
std::string print() const; std::string print() const;
}; };

View file

@ -914,7 +914,7 @@ ConvertedMercEffect convert_merc_effect(const MercEffect& input_effect,
for (size_t i = 0; i < frag.fp_header.shader_cnt; i++) { for (size_t i = 0; i < frag.fp_header.shader_cnt; i++) {
const auto& shader = frag.shaders.at(i); const auto& shader = frag.shaders.at(i);
// update merc state from shader (will hold over to next fragment, if needed) // update merc state from shader (will hold over to next fragment, if needed)
bool fog = ctrl_header.disable_fog == 0; bool fog = true;
merc_state.merc_draw_mode.mode = merc_state.merc_draw_mode.mode =
process_draw_mode(shader, result.has_envmap, use_alpha_blend, depth_write, fog); process_draw_mode(shader, result.has_envmap, use_alpha_blend, depth_write, fog);
if (!merc_state.merc_draw_mode.mode.get_tcc_enable()) { if (!merc_state.merc_draw_mode.mode.get_tcc_enable()) {

View file

@ -32,16 +32,18 @@ goos::Object decompile_at_label_with_hint(const LabelInfo& hint,
if (!hint.array_size.has_value()) { if (!hint.array_size.has_value()) {
// if we don't have an array size, treat it as just a normal type. // if we don't have an array size, treat it as just a normal type.
if (hint.is_value) { if (hint.is_value) {
throw std::runtime_error(fmt::format( throw std::runtime_error(
"Label {} was marked as a value, but is being decompiled as a reference.", hint.name)); fmt::format("Label {} was marked as a value, but is being decompiled as a reference (1).",
hint.name));
} }
return decompile_at_label(type, label, labels, words, ts, file, version); return decompile_at_label(type, label, labels, words, ts, file, version);
} }
if (type.base_type() == "pointer") { if (type.base_type() == "pointer") {
if (hint.is_value) { if (hint.is_value) {
throw std::runtime_error(fmt::format( throw std::runtime_error(
"Label {} was marked as a value, but is being decompiled as a reference.", hint.name)); fmt::format("Label {} was marked as a value, but is being decompiled as a reference (2).",
hint.name));
} }
auto field_type_info = ts.lookup_type(type.get_single_arg()); auto field_type_info = ts.lookup_type(type.get_single_arg());
if (field_type_info->is_reference()) { if (field_type_info->is_reference()) {
@ -52,11 +54,20 @@ goos::Object decompile_at_label_with_hint(const LabelInfo& hint,
auto stride = field_type_info->get_size_in_memory(); auto stride = field_type_info->get_size_in_memory();
int word_count = ((stride * (*hint.array_size)) + 3) / 4; int word_count = ((stride * (*hint.array_size)) + 3) / 4;
std::vector<LinkedWord> obj_words; int max_word = words.at(label.target_segment).size();
obj_words.insert(obj_words.begin(), int start_word = label.offset / 4;
words.at(label.target_segment).begin() + (label.offset / 4), if (start_word + word_count > max_word) {
words.at(label.target_segment).begin() + (label.offset / 4) + word_count); throw std::runtime_error(
fmt::format("Decompiling array of {} values of type {} would go past the end of the "
"file. The file has {} words, the array starts at word {}, and has length "
"{} words, which would make it end at {}",
*hint.array_size, type.get_single_arg().print(), max_word, start_word,
word_count, start_word + word_count));
}
std::vector<LinkedWord> obj_words;
obj_words.insert(obj_words.begin(), words.at(label.target_segment).begin() + start_word,
words.at(label.target_segment).begin() + start_word + word_count);
return decompile_value_array(type.get_single_arg(), field_type_info, *hint.array_size, stride, return decompile_value_array(type.get_single_arg(), field_type_info, *hint.array_size, stride,
0, obj_words, ts); 0, obj_words, ts);
} }
@ -64,8 +75,9 @@ goos::Object decompile_at_label_with_hint(const LabelInfo& hint,
if (type.base_type() == "inline-array") { if (type.base_type() == "inline-array") {
if (hint.is_value) { if (hint.is_value) {
throw std::runtime_error(fmt::format( throw std::runtime_error(
"Label {} was marked as a value, but is being decompiled as a reference.", hint.name)); fmt::format("Label {} was marked as a value, but is being decompiled as a reference (3).",
hint.name));
} }
auto field_type_info = ts.lookup_type(type.get_single_arg()); auto field_type_info = ts.lookup_type(type.get_single_arg());
if (!field_type_info->is_reference()) { if (!field_type_info->is_reference()) {
@ -218,7 +230,8 @@ goos::Object decompile_at_label(const TypeSpec& type,
} }
} catch (std::exception& ex) { } catch (std::exception& ex) {
throw std::runtime_error( throw std::runtime_error(
fmt::format("Unable to 'decompile_at_label' {}, Reason: {}", label.name, ex.what())); fmt::format("Unable to 'decompile_at_label' {} (using type {}), Reason: {}", label.name,
type.print(), ex.what()));
} }
throw std::runtime_error(fmt::format( throw std::runtime_error(fmt::format(
@ -1726,7 +1739,7 @@ goos::Object decompile_boxed_array(const TypeSpec& type,
const auto& elt_label = labels.at(word.label_id()); const auto& elt_label = labels.at(word.label_id());
if (content_type == TypeSpec("object")) { if (content_type == TypeSpec("object")) {
// if there is a type hint for the label, no need to guess! // if there is a type hint for the label, no need to guess!
if (file->label_db->label_exists_by_name(elt_label.name)) { if (file->label_db->label_info_known_by_name(elt_label.name)) {
result.push_back(decompile_at_label_with_hint(file->label_db->lookup(elt_label.name), result.push_back(decompile_at_label_with_hint(file->label_db->lookup(elt_label.name),
elt_label, labels, words, ts, file, elt_label, labels, words, ts, file,
version)); version));

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff