Skip to content

Commit 72a9fac

Browse files
committed
Merge remote-tracking branch 'vanilla/master'
2 parents 4ff1a0a + 5458d86 commit 72a9fac

File tree

888 files changed

+4233
-3897
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

888 files changed

+4233
-3897
lines changed

common/goos/Object.h

+15-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
#include "common/util/Assert.h"
5858
#include "common/util/crc32.h"
5959

60+
#include "fmt/core.h"
61+
6062
namespace goos {
6163

6264
/*!
@@ -234,10 +236,14 @@ class Object {
234236

235237
ObjectType type = ObjectType::INVALID;
236238

239+
private:
240+
bool disallow_hex_for_int = false;
241+
242+
public:
237243
std::string print() const {
238244
switch (type) {
239245
case ObjectType::INTEGER:
240-
return integer_obj.print();
246+
return disallow_hex_for_int ? fmt::format("{}", integer_obj.value) : integer_obj.print();
241247
case ObjectType::FLOAT:
242248
return float_obj.print();
243249
case ObjectType::CHAR:
@@ -278,6 +284,14 @@ class Object {
278284
return o;
279285
}
280286

287+
static Object make_integer_no_hex(IntType value) {
288+
Object o;
289+
o.type = ObjectType::INTEGER;
290+
o.integer_obj.value = value;
291+
o.disallow_hex_for_int = true;
292+
return o;
293+
}
294+
281295
static Object make_float(FloatType value) {
282296
Object o;
283297
o.type = ObjectType::FLOAT;

decompiler/IR2/AtomicOp.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ SimpleAtom SimpleAtom::make_static_address(int static_label_id) {
149149
return result;
150150
}
151151

152+
void SimpleAtom::mark_as_no_hex() {
153+
ASSERT(is_int() && !is_integer_promoted_to_float());
154+
m_no_display_int_as_hex = true;
155+
}
156+
152157
/*!
153158
* Mark this atom as a float. It will be printed as a float.
154159
* This can only be applied to an "integer" atom.
@@ -194,6 +199,8 @@ goos::Object SimpleAtom::to_form(const std::vector<DecompilerLabel>& labels, con
194199
if (std::abs(m_int) > INT32_MAX) {
195200
u64 v = m_int;
196201
return pretty_print::to_symbol(fmt::format("#x{:x}", v));
202+
} else if (m_no_display_int_as_hex) {
203+
return goos::Object::make_integer_no_hex(m_int);
197204
} else {
198205
return goos::Object::make_integer(m_int);
199206
}

decompiler/IR2/AtomicOp.h

+2
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ class SimpleAtom {
190190
ASSERT(is_sym_ptr() || is_sym_val() || is_sym_val_ptr());
191191
return m_string;
192192
}
193+
void mark_as_no_hex();
193194
void mark_as_float();
194195
bool is_integer_promoted_to_float() const;
195196
float get_integer_promoted_to_float() const;
@@ -200,6 +201,7 @@ class SimpleAtom {
200201
s64 m_int = -1; // for integer constant and static address label id
201202
RegisterAccess m_variable;
202203
bool m_display_int_as_float = false;
204+
bool m_no_display_int_as_hex = false;
203205
};
204206

205207
/*!

decompiler/IR2/Form.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,19 @@ void LoadSourceElement::get_modified_regs(RegSet& regs) const {
281281
/////////////////////////////
282282

283283
SimpleAtomElement::SimpleAtomElement(const SimpleAtom& atom, bool omit_var_cast)
284-
: m_atom(atom), m_omit_var_cast(omit_var_cast) {
284+
: m_atom(atom), m_omit_var_cast(omit_var_cast), m_no_hex(false) {
285285
if (m_omit_var_cast) {
286286
ASSERT(atom.is_var());
287287
}
288288
}
289289

290+
SimpleAtomElement::SimpleAtomElement(int int_val, bool no_hex)
291+
: m_atom(SimpleAtom::make_int_constant(int_val)), m_omit_var_cast(false), m_no_hex(no_hex) {
292+
if (m_no_hex) {
293+
m_atom.mark_as_no_hex();
294+
}
295+
}
296+
290297
goos::Object SimpleAtomElement::to_form_internal(const Env& env) const {
291298
if (m_omit_var_cast) {
292299
return m_atom.var().to_form(env, RegisterAccess::Print::AS_VARIABLE_NO_CAST);

decompiler/IR2/Form.h

+2
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ class LoadSourceElement : public FormElement {
309309
class SimpleAtomElement : public FormElement {
310310
public:
311311
explicit SimpleAtomElement(const SimpleAtom& var, bool omit_var_cast = false);
312+
SimpleAtomElement(int int_val, bool no_hex = false);
312313
goos::Object to_form_internal(const Env& env) const override;
313314
void apply(const std::function<void(FormElement*)>& f) override;
314315
void apply_form(const std::function<void(Form*)>& f) override;
@@ -324,6 +325,7 @@ class SimpleAtomElement : public FormElement {
324325
private:
325326
SimpleAtom m_atom;
326327
bool m_omit_var_cast;
328+
bool m_no_hex;
327329
};
328330

329331
/*!

decompiler/IR2/FormExpressionAnalysis.cpp

+69-1
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ FormElement* make_and_compact_math_op(Form* arg0,
965965
/*!
966966
* Update a two-argument form that uses two floats.
967967
* This is for operations like * and + that can be nested
968-
* (* (* a b)) -> (* a b c)
968+
* (* (* a b) c) -> (* a b c)
969969
* Note that we only apply this to the _first_ argument to keep the order of operations the same.
970970
*/
971971
void SimpleExpressionElement::update_from_stack_float_2_nestable(const Env& env,
@@ -2603,6 +2603,9 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
26032603
ASSERT(x->parent_form == m_src);
26042604
}
26052605

2606+
if (auto test0 = m_src->to_string(env) == "(* 0.00024414062 (-> arg0 y))") {
2607+
printf("");
2608+
}
26062609
if (m_src->is_single_element()) {
26072610
auto src_as_se = dynamic_cast<SimpleExpressionElement*>(m_src->back());
26082611
if (src_as_se) {
@@ -2624,6 +2627,71 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
26242627
}
26252628
}
26262629
}
2630+
2631+
// (* 0.125 b) -> (/ b 8)
2632+
// adds explicit cast b to float if necessary
2633+
auto src_as_ge = dynamic_cast<GenericElement*>(m_src->back());
2634+
if (src_as_ge) {
2635+
auto mr = match(Matcher::op_fixed(FixedOperatorKind::MULTIPLICATION,
2636+
{Matcher::any_single(0), Matcher::any(1)}),
2637+
m_src);
2638+
if (mr.matched && std::abs(mr.maps.floats.at(0)) < 1 && mr.maps.floats.at(0) != 0) {
2639+
auto inverse_mult = mr.maps.floats.at(0);
2640+
float divisor_num = 1.0f / inverse_mult;
2641+
2642+
// note: float inaccuracies lead to convergent values, so we can do this safely
2643+
if ((int)divisor_num != divisor_num && 1.0f / std::roundf(divisor_num) == inverse_mult) {
2644+
lg::debug("managed to round divisor - cool !! {} -> {} ({})", divisor_num,
2645+
std::roundf(divisor_num), inverse_mult);
2646+
divisor_num = std::roundf(divisor_num);
2647+
}
2648+
2649+
int divisor_int = (int)divisor_num;
2650+
bool integer = divisor_int == divisor_num;
2651+
if (integer) {
2652+
auto elt = mr.maps.forms.at(1)->try_as_single_element();
2653+
auto b_as_simple = dynamic_cast<SimpleExpressionElement*>(elt);
2654+
// WARNING : there is an assumption here that derefs DO NOT have implicit casts!
2655+
auto b_as_deref = dynamic_cast<DerefElement*>(elt);
2656+
if (b_as_deref ||
2657+
(b_as_simple && b_as_simple->expr().kind() == SimpleExpression::Kind::IDENTITY)) {
2658+
// TODO check if op is float, cast if so
2659+
Form* divisor = nullptr;
2660+
if (divisor_num == 4096.0f) {
2661+
divisor = pool.form<ConstantTokenElement>("METER_LENGTH");
2662+
} else if (integer && divisor_int % 4096 == 0) {
2663+
divisor = pool.form<GenericElement>(
2664+
GenericOperator::make_function(pool.form<ConstantTokenElement>("meters")),
2665+
pool.form<SimpleAtomElement>(divisor_int / 4096, true));
2666+
} else if (integer && divisor_int % 2048 == 0) {
2667+
divisor = pool.form<GenericElement>(
2668+
GenericOperator::make_function(pool.form<ConstantTokenElement>("meters")),
2669+
pool.form<ConstantFloatElement>(divisor_num / (float)METER_LENGTH));
2670+
} else if (integer) {
2671+
divisor = pool.form<SimpleAtomElement>(divisor_int, true);
2672+
} else {
2673+
// this shouldn't run because of the checks before.
2674+
divisor = pool.form<ConstantFloatElement>(divisor_num);
2675+
}
2676+
if (divisor) {
2677+
if (b_as_deref || (b_as_simple->expr().is_var() &&
2678+
env.get_types_before_op(b_as_simple->expr().var().idx())
2679+
.get(b_as_simple->expr().var().reg())
2680+
.typespec() == TypeSpec("float"))) {
2681+
*m_src->back_ref() = pool.alloc_element<GenericElement>(
2682+
GenericOperator::make_fixed(FixedOperatorKind::DIVISION), mr.maps.forms.at(1),
2683+
divisor);
2684+
} else {
2685+
*m_src->back_ref() = pool.alloc_element<GenericElement>(
2686+
GenericOperator::make_fixed(FixedOperatorKind::DIVISION),
2687+
pool.form<CastElement>(TypeSpec("float"), mr.maps.forms.at(1), true), divisor);
2688+
}
2689+
m_src->back()->parent_form = m_src;
2690+
}
2691+
}
2692+
}
2693+
}
2694+
}
26272695
}
26282696

26292697
stack.push_value_to_reg(m_dst, m_src, true, m_src_type, m_var_info);

decompiler/IR2/GenericElementMatcher.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ Matcher Matcher::single(std::optional<float> value) {
127127
return m;
128128
}
129129

130+
Matcher Matcher::any_single(int match_id) {
131+
Matcher m;
132+
m.m_kind = Kind::ANY_FLOAT;
133+
m.m_float_out_id = match_id;
134+
return m;
135+
}
136+
130137
Matcher Matcher::any_quoted_symbol(int match_id) {
131138
Matcher m;
132139
m.m_kind = Kind::ANY_QUOTED_SYMBOL;
@@ -477,6 +484,30 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* cons
477484
return false;
478485
} break;
479486

487+
case Kind::ANY_FLOAT: {
488+
auto as_const_float =
489+
dynamic_cast<ConstantFloatElement*>(input->try_as_single_active_element());
490+
if (as_const_float) {
491+
if (m_float_out_id != -1) {
492+
maps_out->floats[m_float_out_id] = as_const_float->value();
493+
}
494+
return true;
495+
}
496+
497+
auto as_expr = dynamic_cast<SimpleExpressionElement*>(input->try_as_single_active_element());
498+
if (as_expr && as_expr->expr().is_identity()) {
499+
const auto& atom = as_expr->expr().get_arg(0);
500+
if (atom.is_integer_promoted_to_float()) {
501+
if (m_float_out_id != -1) {
502+
maps_out->floats[m_float_out_id] = atom.get_integer_promoted_to_float();
503+
}
504+
return true;
505+
}
506+
}
507+
508+
return false;
509+
} break;
510+
480511
case Kind::ANY_QUOTED_SYMBOL: {
481512
auto as_simple_atom = dynamic_cast<SimpleAtomElement*>(input->try_as_single_active_element());
482513
if (as_simple_atom) {

decompiler/IR2/GenericElementMatcher.h

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct MatchResult {
2121
std::unordered_map<int, Form*> forms;
2222
std::unordered_map<int, s64> label;
2323
std::unordered_map<int, s64> ints;
24+
std::unordered_map<int, float> floats;
2425
} maps;
2526

2627
Form* int_or_form_to_form(FormPool& pool, int key_idx) {
@@ -56,6 +57,7 @@ class Matcher {
5657
static Matcher integer(std::optional<int> value);
5758
static Matcher any_integer(int match_id = -1);
5859
static Matcher single(std::optional<float> value);
60+
static Matcher any_single(int match_id = -1);
5961
static Matcher any_reg_cast_to_int_or_uint(int match_id = -1);
6062
static Matcher any_quoted_symbol(int match_id = -1);
6163
static Matcher any_symbol(int match_id = -1);
@@ -91,6 +93,7 @@ class Matcher {
9193
INT,
9294
ANY_INT,
9395
FLOAT,
96+
ANY_FLOAT,
9497
ANY_QUOTED_SYMBOL,
9598
ANY_SYMBOL,
9699
DEREF_OP,
@@ -132,6 +135,7 @@ class Matcher {
132135
int m_form_match;
133136
int m_label_out_id;
134137
int m_int_out_id;
138+
int m_float_out_id;
135139
};
136140
std::optional<int> m_int_match;
137141
std::optional<float> m_float_match;

goal_src/jak1/engine/anim/joint-exploder.gc

+11-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@
2121
(:methods
2222
(new (symbol type int) _type_)))
2323

24+
2425
(deftype joint-exploder-static-joint-params (structure)
2526
((joint-index int16)
2627
(parent-joint-index int16)))
2728

29+
2830
(deftype joint-exploder-static-params (basic)
2931
((joints (array joint-exploder-static-joint-params))))
3032

33+
3134
(deftype joint-exploder-joint (structure)
3235
((next int16)
3336
(prev int16)
@@ -38,18 +41,21 @@
3841
(transv vector :inline)
3942
(prev-pos vector :inline)))
4043

44+
4145
(deftype joint-exploder-joints (basic)
4246
((num-joints int32)
4347
(joint joint-exploder-joint :inline :dynamic :offset 16))
4448
(:methods
4549
(new (symbol type joint-exploder-static-params) _type_)))
4650

51+
4752
(deftype joint-exploder-list (structure)
4853
((head int32)
4954
(pre-moved? symbol)
5055
(bbox-valid? symbol)
5156
(bbox bounding-box :inline)))
5257

58+
5359
(deftype joint-exploder (process-drawable)
5460
((parent-override (pointer process-drawable) :overlay-at parent)
5561
(die-if-below-y float)
@@ -73,6 +79,7 @@
7379
(:states
7480
joint-exploder-shatter))
7581

82+
7683
(defmethod asize-of ((this joint-exploder-joints))
7784
(the-as int (+ (-> this type size) (* 176 (-> this num-joints)))))
7885

@@ -270,7 +277,7 @@
270277
(set! (-> s5-1 transv y) (* 0.7 f30-0))))
271278
(+! (-> s4-0 y) (* 40.96 (-> s3-0 normal y)))
272279
(set! (-> s4-0 w) 1.0)
273-
(set! (-> s5-1 rspeed) (* 0.5 (-> s5-1 rspeed)))))
280+
(set! (-> s5-1 rspeed) (/ (-> s5-1 rspeed) 2))))
274281
(set! v1-2 (-> s5-1 next)))))
275282
#f)
276283

@@ -381,9 +388,9 @@
381388
(add-point! s5-1 (the-as vector3s (+ (the-as uint (-> gp-0 joint 0 mat vector 3)) (* 176 s4-1)))))))
382389
#f)))
383390

384-
(defmethod relocate ((this joint-exploder) (arg0 int))
385-
(if (nonzero? (-> this joints)) (&+! (-> this joints) arg0))
386-
(the-as joint-exploder ((method-of-type process-drawable relocate) this arg0)))
391+
(defmethod relocate ((this joint-exploder) (offset int))
392+
(if (nonzero? (-> this joints)) (&+! (-> this joints) offset))
393+
(the-as joint-exploder ((method-of-type process-drawable relocate) this offset)))
387394

388395
(defbehavior joint-exploder-init-by-other joint-exploder ((arg0 skeleton-group) (arg1 int) (arg2 joint-exploder-static-params) (arg3 joint-exploder-static-params))
389396
(set! (-> self static-params) arg3)

0 commit comments

Comments
 (0)