From 95366d21df1a0e8c675c3527c809f4622c8a4184 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Fri, 23 Jul 2021 20:51:26 -0400 Subject: [PATCH] Get started on collide-func and clean up `log` forms in decompiler (#713) * wip * temp * temp2 * first part of log macros * more log macros * logtest * clean up * dont initialize game info because we are missing stuff --- common/CMakeLists.txt | 1 + common/math/Vector.h | 149 +++++ common/math/geometry.cpp | 0 common/math/geometry.h | 47 ++ decompiler/IR2/AtomicOp.cpp | 3 + decompiler/IR2/AtomicOp.h | 1 + decompiler/IR2/AtomicOpTypeAnalysis.cpp | 9 +- decompiler/IR2/Form.cpp | 14 + decompiler/IR2/Form.h | 17 +- decompiler/IR2/FormExpressionAnalysis.cpp | 144 +++-- decompiler/IR2/IR2_common.h | 7 + decompiler/analysis/atomic_op_builder.cpp | 74 +++ decompiler/config/all-types.gc | 38 +- .../config/jak1_ntsc_black_label/hacks.jsonc | 4 +- .../jak1_ntsc_black_label/label_types.jsonc | 2 +- .../stack_structures.jsonc | 4 +- .../jak1_ntsc_black_label/type_casts.jsonc | 16 +- .../jak1_ntsc_black_label/var_names.jsonc | 158 +++-- goal_src/engine/anim/aligner.gc | 2 +- goal_src/engine/camera/math-camera.gc | 20 +- goal_src/engine/collide/collide-func.gc | 210 ++++++- goal_src/engine/geometry/geometry.gc | 6 + goal_src/engine/gfx/hw/gs.gc | 9 +- goal_src/engine/gfx/texture.gc | 16 +- goal_src/engine/level/level.gc | 2 +- goal_src/engine/math/transformq-h.gc | 41 +- goal_src/engine/math/transformq.gc | 553 +++++++----------- goal_src/engine/math/vector-h.gc | 48 +- goal_src/engine/nav/navigate-h.gc | 11 +- goal_src/engine/nav/path-h.gc | 3 +- goal_src/engine/ps2/pad.gc | 6 +- goal_src/goal-lib.gc | 5 +- goal_src/kernel/gcommon.gc | 7 +- test/CMakeLists.txt | 1 + .../reference/engine/anim/aligner_REF.gc | 12 +- .../engine/camera/math-camera_REF.gc | 61 +- .../engine/collide/collide-frag_REF.gc | 2 +- .../reference/engine/data/res_REF.gc | 14 +- .../reference/engine/debug/menu_REF.gc | 61 +- .../reference/engine/dma/dma-disasm_REF.gc | 20 +- .../reference/engine/dma/dma_REF.gc | 60 +- .../engine/draw/process-drawable-h_REF.gc | 2 +- .../engine/entity/actor-link-h_REF.gc | 16 +- .../reference/engine/game/fact-h_REF.gc | 2 +- .../reference/engine/game/settings_REF.gc | 29 +- .../engine/game/task/task-control_REF.gc | 20 +- .../reference/engine/geometry/geometry_REF.gc | 20 +- .../reference/engine/gfx/hw/display_REF.gc | 28 +- .../reference/engine/gfx/hw/gs_REF.gc | 8 +- .../reference/engine/gfx/texture_REF.gc | 69 +-- .../reference/engine/load/loader_REF.gc | 18 +- .../reference/engine/math/transformq-h_REF.gc | 28 +- .../reference/engine/math/transformq_REF.gc | 469 +++++++++++++++ .../reference/engine/math/vector-h_REF.gc | 15 +- .../reference/engine/math/vector_REF.gc | 12 +- .../reference/engine/nav/navigate-h_REF.gc | 11 +- .../reference/engine/nav/path-h_REF.gc | 10 +- .../reference/engine/nav/path_REF.gc | 64 +- .../reference/engine/ps2/pad_REF.gc | 7 +- .../reference/engine/ps2/timer_REF.gc | 2 +- .../reference/engine/sound/gsound_REF.gc | 10 +- .../reference/kernel/gcommon_REF.gc | 11 +- .../reference/kernel/gkernel_REF.gc | 53 +- .../decompiler/reference/kernel/gstate_REF.gc | 9 +- test/decompiler/test_DisasmVifDecompile.cpp | 7 +- test/decompiler/test_FormExpressionBuild.cpp | 20 +- test/decompiler/test_FormExpressionBuild2.cpp | 18 +- .../test_FormExpressionBuildLong.cpp | 7 +- test/decompiler/test_gkernel_decomp.cpp | 4 +- .../with_game/test-ray-sphere.gc | 34 ++ test/goalc/test_with_game.cpp | 9 + test/test_math.cpp | 43 ++ tools/MemoryDumpTool/main.cpp | 4 +- 73 files changed, 1900 insertions(+), 1017 deletions(-) create mode 100644 common/math/Vector.h create mode 100644 common/math/geometry.cpp create mode 100644 common/math/geometry.h create mode 100644 test/decompiler/reference/engine/math/transformq_REF.gc create mode 100644 test/goalc/source_templates/with_game/test-ray-sphere.gc create mode 100644 test/test_math.cpp diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 711d1d9c16..0bbadfea8f 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(common goos/Reader.cpp goos/TextDB.cpp goos/ReplUtils.cpp + math/geometry.cpp log/log.cpp type_system/defenum.cpp type_system/deftype.cpp diff --git a/common/math/Vector.h b/common/math/Vector.h new file mode 100644 index 0000000000..28ea905409 --- /dev/null +++ b/common/math/Vector.h @@ -0,0 +1,149 @@ +#pragma once + +#include + +#include "third-party/fmt/core.h" + +namespace math { + +template +class Vector { + public: + Vector() = default; + static Vector zero() { + Vector result; + for (auto& x : result.m_data) { + x = T(0); + } + return result; + } + + template + Vector(Args... args) : m_data{T(args)...} {} + + T* begin() { return &m_data[0]; } + T* end() { return &m_data[Size]; } + const T* begin() const { return &m_data[0]; } + const T* end() const { return &m_data[Size]; } + + T& x() { return m_data[0]; } + + const T& x() const { return m_data[0]; } + + T& y() { + static_assert(Size >= 1, "Out of bounds"); + return m_data[1]; + } + + const T& y() const { + static_assert(Size >= 1, "Out of bounds"); + return m_data[1]; + } + + T& z() { + static_assert(Size >= 2, "Out of bounds"); + return m_data[2]; + } + + const T& z() const { + static_assert(Size >= 2, "Out of bounds"); + return m_data[2]; + } + + T& w() { + static_assert(Size >= 3, "Out of bounds"); + return m_data[3]; + } + + const T& w() const { + static_assert(Size >= 3, "Out of bounds"); + return m_data[3]; + } + + const T squared_length() const { + T sum = T(0); + for (auto val : m_data) { + sum += val * val; + } + return sum; + } + + const T length() const { return std::sqrt(squared_length()); } + + Vector operator+(const Vector& other) const { + Vector result; + for (int i = 0; i < Size; i++) { + result[i] = m_data[i] + other[i]; + } + return result; + } + + Vector operator-(const Vector& other) const { + Vector result; + for (int i = 0; i < Size; i++) { + result[i] = m_data[i] - other[i]; + } + return result; + } + + T dot(const Vector& other) const { + T result(0); + for (int i = 0; i < Size; i++) { + result += m_data[i] * other[i]; + } + return result; + } + + T operator[](int idx) const { return m_data[idx]; } + + T& operator[](int idx) { return m_data[idx]; } + + Vector operator/(const T& val) const { + Vector result; + for (int i = 0; i < Size; i++) { + result[i] = m_data[i] / val; + } + return result; + } + + Vector operator*(const T& val) const { + Vector result; + for (int i = 0; i < Size; i++) { + result[i] = m_data[i] * val; + } + return result; + } + + Vector normalized(const T& norm = T(1)) const { return (*this) * (norm / length()); } + + void normalize(const T& norm = T(1)) { *this = normalized(norm); } + + std::string to_string_aligned() const { + std::string result = "["; + for (auto x : m_data) { + result.append(fmt::format("{: 6.3f} ", x)); + } + result.pop_back(); + return result + "]"; + } + + private: + T m_data[Size]; +}; + +template +using Vector2 = Vector; + +template +using Vector3 = Vector; + +template +using Vector4 = Vector; + +using Vector2f = Vector2; +using Vector3f = Vector3; +using Vector4f = Vector4; +using Vector2d = Vector2; +using Vector3d = Vector3; +using Vector4d = Vector4; +} // namespace math diff --git a/common/math/geometry.cpp b/common/math/geometry.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/common/math/geometry.h b/common/math/geometry.h new file mode 100644 index 0000000000..4c71592bf7 --- /dev/null +++ b/common/math/geometry.h @@ -0,0 +1,47 @@ +#pragma once + +#include "common/math/Vector.h" + +namespace math { + +template +T squared(const T& in) { + return in * in; +} + +template +struct RaySphereResult { + bool hit = false; + T u[2] = {0, 0}; +}; + +/*! + * Check if a line intersects a sphere. + */ +template +RaySphereResult ray_sphere_intersect(const Vector3& ray_origin, + const Vector3& ray_direction_in, + const Vector3& sphere_origin, + T sphere_radius) { + RaySphereResult result; + Vector3 ray_direction = ray_direction_in.normalized(); + + Vector3 oc = ray_origin - sphere_origin; + + T value_under_sqrt = + squared(ray_direction.dot(oc)) - (oc.squared_length() - squared(sphere_radius)); + + if (value_under_sqrt < 0) { + result.hit = false; + return result; + } + + T minus_b = -ray_direction.dot(oc); + result.hit = true; + T sqrt_val = std::sqrt(value_under_sqrt); + + result.u[0] = minus_b + sqrt_val; + result.u[1] = minus_b - sqrt_val; + return result; +} +} // namespace math \ No newline at end of file diff --git a/decompiler/IR2/AtomicOp.cpp b/decompiler/IR2/AtomicOp.cpp index fbfb1b508b..a139a7fb6f 100644 --- a/decompiler/IR2/AtomicOp.cpp +++ b/decompiler/IR2/AtomicOp.cpp @@ -298,6 +298,8 @@ std::string get_simple_expression_op_name(SimpleExpression::Kind kind) { return "vector-!2"; case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT: return "vector-float*!2"; + case SimpleExpression::Kind::VECTOR_CROSS: + return "veccross"; case SimpleExpression::Kind::SUBU_L32_S7: return "subu-s7"; case SimpleExpression::Kind::VECTOR_3_DOT: @@ -356,6 +358,7 @@ int get_simple_expression_arg_count(SimpleExpression::Kind kind) { case SimpleExpression::Kind::VECTOR_PLUS: case SimpleExpression::Kind::VECTOR_MINUS: case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT: + case SimpleExpression::Kind::VECTOR_CROSS: return 3; case SimpleExpression::Kind::SUBU_L32_S7: return 1; diff --git a/decompiler/IR2/AtomicOp.h b/decompiler/IR2/AtomicOp.h index ff777be427..cd1303f199 100644 --- a/decompiler/IR2/AtomicOp.h +++ b/decompiler/IR2/AtomicOp.h @@ -226,6 +226,7 @@ class SimpleExpression { VECTOR_PLUS, VECTOR_MINUS, VECTOR_FLOAT_PRODUCT, + VECTOR_CROSS, SUBU_L32_S7, // use SUBU X, src0, s7 to check if lower 32-bits are s7. VECTOR_3_DOT, }; diff --git a/decompiler/IR2/AtomicOpTypeAnalysis.cpp b/decompiler/IR2/AtomicOpTypeAnalysis.cpp index 9f472e93b1..6aaa1eeac2 100644 --- a/decompiler/IR2/AtomicOpTypeAnalysis.cpp +++ b/decompiler/IR2/AtomicOpTypeAnalysis.cpp @@ -200,6 +200,7 @@ TP_Type SimpleExpression::get_type(const TypeState& input, return TP_Type::make_from_ts("uint"); case Kind::VECTOR_PLUS: case Kind::VECTOR_MINUS: + case Kind::VECTOR_CROSS: return TP_Type::make_from_ts("vector"); case Kind::VECTOR_FLOAT_PRODUCT: return TP_Type::make_from_ts("vector"); @@ -1244,8 +1245,11 @@ void FunctionEndOp::mark_function_as_no_return_value() { } TypeState AsmBranchOp::propagate_types_internal(const TypeState& input, - const Env&, - DecompilerTypeSystem&) { + const Env& env, + DecompilerTypeSystem& dts) { + if (m_branch_delay) { + return m_branch_delay->propagate_types(input, env, dts); + } // for now, just make everything uint TypeState output = input; for (auto x : m_write_regs) { @@ -1253,6 +1257,7 @@ TypeState AsmBranchOp::propagate_types_internal(const TypeState& input, output.get(x) = TP_Type::make_from_ts("uint"); } } + return output; } diff --git a/decompiler/IR2/Form.cpp b/decompiler/IR2/Form.cpp index 189e6b41f4..c719792d23 100644 --- a/decompiler/IR2/Form.cpp +++ b/decompiler/IR2/Form.cpp @@ -1739,14 +1739,26 @@ std::string fixed_operator_to_string(FixedOperatorKind kind) { return "fmax"; case FixedOperatorKind::LOGAND: return "logand"; + case FixedOperatorKind::LOGAND_IN_PLACE: + return "logand!"; case FixedOperatorKind::LOGIOR: return "logior"; + case FixedOperatorKind::LOGIOR_IN_PLACE: + return "logior!"; case FixedOperatorKind::LOGXOR: return "logxor"; case FixedOperatorKind::LOGNOR: return "lognor"; case FixedOperatorKind::LOGNOT: return "lognot"; + case FixedOperatorKind::LOGCLEAR: + return "logclear"; + case FixedOperatorKind::LOGCLEAR_IN_PLACE: + return "logclear!"; + case FixedOperatorKind::LOGTEST: + return "logtest?"; + case FixedOperatorKind::LOGTESTA: + return "logtesta?"; case FixedOperatorKind::SHL: return "shl"; case FixedOperatorKind::SHR: @@ -1801,6 +1813,8 @@ std::string fixed_operator_to_string(FixedOperatorKind kind) { return "vector-!"; case FixedOperatorKind::VECTOR_PLUS: return "vector+!"; + case FixedOperatorKind::VECTOR_CROSS: + return "vector-cross!"; case FixedOperatorKind::VECTOR_FLOAT_PRODUCT: return "vector-float*!"; case FixedOperatorKind::L32_NOT_FALSE_CBOOL: diff --git a/decompiler/IR2/Form.h b/decompiler/IR2/Form.h index d0bc3995e9..b26bccba41 100644 --- a/decompiler/IR2/Form.h +++ b/decompiler/IR2/Form.h @@ -189,6 +189,11 @@ class SimpleExpressionElement : public FormElement { FormStack& stack, std::vector* result, bool allow_side_effects); + FormElement* update_from_stack_logor_or_logand_helper(const Env& env, + FixedOperatorKind kind, + FormPool& pool, + FormStack& stack, + bool allow_side_effects); void update_from_stack_logor_or_logand(const Env& env, FixedOperatorKind kind, FormPool& pool, @@ -200,12 +205,12 @@ class SimpleExpressionElement : public FormElement { FormStack& stack, std::vector* result, bool allow_side_effects); - void update_from_stack_vector_plus_minus(bool is_add, - const Env& env, - FormPool& pool, - FormStack& stack, - std::vector* result, - bool allow_side_effects); + void update_from_stack_vector_plus_minus_cross(FixedOperatorKind op_kind, + const Env& env, + FormPool& pool, + FormStack& stack, + std::vector* result, + bool allow_side_effects); void update_from_stack_vector_float_product(const Env& env, FormPool& pool, FormStack& stack, diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index fe22cf9302..4b1ab33a36 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -1144,12 +1144,13 @@ void SimpleExpressionElement::update_from_stack_pcypld(const Env& env, result->push_back(new_form); } -void SimpleExpressionElement::update_from_stack_vector_plus_minus(bool is_add, - const Env& env, - FormPool& pool, - FormStack& stack, - std::vector* result, - bool allow_side_effects) { +void SimpleExpressionElement::update_from_stack_vector_plus_minus_cross( + FixedOperatorKind op_kind, + const Env& env, + FormPool& pool, + FormStack& stack, + std::vector* result, + bool allow_side_effects) { std::vector popped_args = pop_to_forms({m_expr.get_arg(0).var(), m_expr.get_arg(1).var(), m_expr.get_arg(2).var()}, env, pool, stack, allow_side_effects); @@ -1162,8 +1163,7 @@ void SimpleExpressionElement::update_from_stack_vector_plus_minus(bool is_add, } auto new_form = pool.alloc_element( - GenericOperator::make_fixed(is_add ? FixedOperatorKind::VECTOR_PLUS - : FixedOperatorKind::VECTOR_MINUS), + GenericOperator::make_fixed(op_kind), std::vector{popped_args.at(0), popped_args.at(1), popped_args.at(2)}); result->push_back(new_form); } @@ -1282,12 +1282,12 @@ Form* strip_int_or_uint_cast(Form* in) { } } // namespace -void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env, - FixedOperatorKind kind, - FormPool& pool, - FormStack& stack, - std::vector* result, - bool allow_side_effects) { +FormElement* SimpleExpressionElement::update_from_stack_logor_or_logand_helper( + const Env& env, + FixedOperatorKind kind, + FormPool& pool, + FormStack& stack, + bool allow_side_effects) { // grab the normal variable type auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true); @@ -1341,15 +1341,17 @@ void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env, BitfieldManip step(manip_kind, m_expr.get_arg(1).get_int()); auto other = read_elt->push_step(step, env.dts->ts, pool, env); if (other) { - result->push_back(other); + return other; } else { - result->push_back(read_elt); + return read_elt; } - return; } else if (!m_expr.get_arg(1).is_var()) { // andi, something else (don't think this can happen?) - update_from_stack_copy_first_int_2(env, kind, pool, stack, result, allow_side_effects); + std::vector result; + update_from_stack_copy_first_int_2(env, kind, pool, stack, &result, allow_side_effects); + assert(result.size() == 1); + return result.at(0); } else { // and, two forms auto arg1_type = env.get_variable_type(m_expr.get_arg(1).var(), true); @@ -1393,11 +1395,10 @@ void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env, auto other = read_elt->push_step(step, env.dts->ts, pool, env); // assert(!other); // shouldn't be complete. if (other) { - result->push_back(other); + return other; } else { - result->push_back(read_elt); + return read_elt; } - return; } else if (!made_new_read_elt) { BitfieldManip::Kind manip_kind; if (kind == FixedOperatorKind::LOGAND) { @@ -1410,22 +1411,21 @@ void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env, auto step = BitfieldManip::from_form(manip_kind, stripped_arg1); auto other = read_elt->push_step(step, env.dts->ts, pool, env); if (other) { - result->push_back(other); + return other; } else { - result->push_back(read_elt); + return read_elt; } - return; } } - if ((arg0_i && arg1_i) || (arg0_u && arg1_u) || + if (((arg0_i || arg0_u) && (arg1_i || arg1_u)) || (arg0_n && arg1_type.base_type() == "pointer") || (arg1_n && arg0_type.base_type() == "pointer")) { // types already good // we also allow (logand intvar pointer) and (logand pointer intvar) auto new_form = pool.alloc_element(GenericOperator::make_fixed(kind), args.at(0), args.at(1)); - result->push_back(new_form); + return new_form; // types bad, insert cast. } else { // this is an ugly hack to make (logand (lognot (enum-bitfield xxxx)) work. @@ -1450,22 +1450,76 @@ void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env, nullptr, GenericOperator::make_fixed(FixedOperatorKind::LOGNOT), inverted); auto new_form = pool.alloc_element(GenericOperator::make_fixed(kind), normal, args.at(1)); - result->push_back(new_form); - // assert(false); - return; + return new_form; } } } + bool arg0_int_like = env.dts->ts.tc(TypeSpec("integer"), arg0_type); + bool arg1_int_like = env.dts->ts.tc(TypeSpec("integer"), arg1_type); + + if ((arg0_int_like) && (arg1_int_like)) { + auto new_form = pool.alloc_element(GenericOperator::make_fixed(kind), + args.at(0), args.at(1)); + return new_form; + // types bad, insert cast. + } + auto cast = pool.alloc_single_element_form( nullptr, TypeSpec(arg0_i ? "int" : "uint"), args.at(1)); auto new_form = pool.alloc_element(GenericOperator::make_fixed(kind), args.at(0), cast); - result->push_back(new_form); + return new_form; } } } +void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env, + FixedOperatorKind kind, + FormPool& pool, + FormStack& stack, + std::vector* result, + bool allow_side_effects) { + auto element = + update_from_stack_logor_or_logand_helper(env, kind, pool, stack, allow_side_effects); + + /* + (defmacro logclear (a b) + "Returns the result of setting the bits in b to zero in a" + `(logand (lognot ,b) ,a) + ) + */ + + constexpr int a_form = 0; + constexpr int b_form = 1; + + auto lognot_submatcher = + Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LOGNOT), {Matcher::any(b_form)}); + auto lognot_submatchers = + Matcher::match_or({Matcher::cast("uint", lognot_submatcher), + Matcher::cast("int", lognot_submatcher), lognot_submatcher}); + + auto logclear_matcher = + Matcher::match_or({Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LOGAND), + {lognot_submatchers, Matcher::any(a_form)}), + Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LOGAND), + {Matcher::any(a_form), lognot_submatchers})}); + + Form hack_form; + hack_form.elts().push_back(element); + + auto mr = match(logclear_matcher, &hack_form); + if (mr.matched) { + result->push_back(pool.alloc_element( + GenericOperator::make_fixed(FixedOperatorKind::LOGCLEAR), + std::vector{mr.maps.forms.at(a_form), mr.maps.forms.at(b_form)})); + + return; + } + + result->push_back(element); +} + void SimpleExpressionElement::update_from_stack_left_shift(const Env& env, FormPool& pool, FormStack& stack, @@ -1875,10 +1929,16 @@ void SimpleExpressionElement::update_from_stack(const Env& env, update_from_stack_pcypld(env, pool, stack, result, allow_side_effects); break; case SimpleExpression::Kind::VECTOR_PLUS: - update_from_stack_vector_plus_minus(true, env, pool, stack, result, allow_side_effects); + update_from_stack_vector_plus_minus_cross(FixedOperatorKind::VECTOR_PLUS, env, pool, stack, + result, allow_side_effects); break; case SimpleExpression::Kind::VECTOR_MINUS: - update_from_stack_vector_plus_minus(false, env, pool, stack, result, allow_side_effects); + update_from_stack_vector_plus_minus_cross(FixedOperatorKind::VECTOR_MINUS, env, pool, stack, + result, allow_side_effects); + break; + case SimpleExpression::Kind::VECTOR_CROSS: + update_from_stack_vector_plus_minus_cross(FixedOperatorKind::VECTOR_CROSS, env, pool, stack, + result, allow_side_effects); break; case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT: update_from_stack_vector_float_product(env, pool, stack, result, allow_side_effects); @@ -2033,7 +2093,10 @@ void SetFormFormElement::push_to_stack(const Env& env, FormPool& pool, FormStack const std::pair in_place_ops[] = { {FixedOperatorKind::ADDITION, FixedOperatorKind::ADDITION_IN_PLACE}, - {FixedOperatorKind::ADDITION_PTR, FixedOperatorKind::ADDITION_PTR_IN_PLACE}}; + {FixedOperatorKind::ADDITION_PTR, FixedOperatorKind::ADDITION_PTR_IN_PLACE}, + {FixedOperatorKind::LOGAND, FixedOperatorKind::LOGAND_IN_PLACE}, + {FixedOperatorKind::LOGIOR, FixedOperatorKind::LOGIOR_IN_PLACE}, + {FixedOperatorKind::LOGCLEAR, FixedOperatorKind::LOGCLEAR_IN_PLACE}}; auto src_as_generic = m_src->try_as_element(); if (src_as_generic) { @@ -3383,6 +3446,21 @@ FormElement* ConditionElement::make_nonzero_check_generic(const Env& env, std::vector{mr.maps.forms.at(0), value_form}); } + /* + (defmacro logtest? (a b) + "does a have any of the bits in b?" + `(nonzero? (logand ,a ,b)) + ) + */ + auto logand_matcher = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LOGAND), + {Matcher::any(0), Matcher::any(1)}); + auto mr_logand = match(logand_matcher, source_forms.at(0)); + if (mr_logand.matched) { + return pool.alloc_element( + GenericOperator::make_fixed(FixedOperatorKind::LOGTEST), mr_logand.maps.forms.at(0), + mr_logand.maps.forms.at(1)); + } + return pool.alloc_element(GenericOperator::make_compare(m_kind), source_forms); } diff --git a/decompiler/IR2/IR2_common.h b/decompiler/IR2/IR2_common.h index 6a302a927c..02ca958296 100644 --- a/decompiler/IR2/IR2_common.h +++ b/decompiler/IR2/IR2_common.h @@ -119,10 +119,16 @@ enum class FixedOperatorKind { FMIN, FMAX, LOGAND, + LOGAND_IN_PLACE, LOGIOR, + LOGIOR_IN_PLACE, LOGXOR, LOGNOR, LOGNOT, + LOGCLEAR, + LOGCLEAR_IN_PLACE, + LOGTEST, + LOGTESTA, SHL, SHR, SAR, @@ -150,6 +156,7 @@ enum class FixedOperatorKind { ASM_MADDS, VECTOR_PLUS, VECTOR_MINUS, + VECTOR_CROSS, VECTOR_FLOAT_PRODUCT, L32_NOT_FALSE_CBOOL, VECTOR_3_DOT, diff --git a/decompiler/analysis/atomic_op_builder.cpp b/decompiler/analysis/atomic_op_builder.cpp index 11e1018f65..fe63929b75 100644 --- a/decompiler/analysis/atomic_op_builder.cpp +++ b/decompiler/analysis/atomic_op_builder.cpp @@ -1491,6 +1491,26 @@ std::unique_ptr convert_dsll32_4(const Instruction& i0, return nullptr; } +std::unique_ptr convert_fp_branch_with_nop(const Instruction& i0, + const Instruction& i1, + const Instruction& i2, + const Instruction& i3, + IR2_Condition::Kind kind, + int idx) { + if (i1.kind != InstructionKind::VNOP) { + return nullptr; + } + if (i2.kind == InstructionKind::BC1T || i2.kind == InstructionKind::BC1F) { + IR2_Condition condition(kind, make_src_atom(i0.get_src(0).get_reg(), idx), + make_src_atom(i0.get_src(1).get_reg(), idx)); + if (i2.kind == InstructionKind::BC1F) { + condition.invert(); + } + return make_branch(condition, i3, false, i2.get_src(0).get_label(), idx); + } + return nullptr; +} + std::unique_ptr convert_4(const Instruction& i0, const Instruction& i1, const Instruction& i2, @@ -1499,6 +1519,8 @@ std::unique_ptr convert_4(const Instruction& i0, switch (i0.kind) { case InstructionKind::DSLL32: return convert_dsll32_4(i0, i1, i2, i3, idx); + case InstructionKind::CEQS: + return convert_fp_branch_with_nop(i0, i1, i2, i3, IR2_Condition::Kind::FLOAT_EQUAL, idx); default: return nullptr; } @@ -1602,6 +1624,53 @@ std::unique_ptr convert_vector_minus(const Instruction& i0, idx); } +std::unique_ptr convert_vector_cross(const Instruction& i0, + const Instruction& i1, + const Instruction& i2, + const Instruction& i3, + const Instruction& i4, + int idx) { + // lqc2 vf1, 0(v1) (src1) + if (i0.kind != InstructionKind::LQC2 || i0.get_dst(0).get_reg() != make_vf(1) || + !i0.get_src(0).is_imm(0)) { + return nullptr; + } + Register src1 = i0.get_src(1).get_reg(); + + // lqc2 vf5, 0(a2) (src2) + if (i1.kind != InstructionKind::LQC2 || i1.get_dst(0).get_reg() != make_vf(2) || + !i1.get_src(0).is_imm(0)) { + return nullptr; + } + Register src2 = i1.get_src(1).get_reg(); + + // vopmula.xyz acc, vf1, vf2 + if (i2.kind != InstructionKind::VOPMULA || i2.get_src(0).get_reg() != make_vf(1) || + i2.get_src(1).get_reg() != make_vf(2) || i2.cop2_dest != 14) { + return nullptr; + } + + // vopmsub.xyz vf3, vf2, vf1 + if (i3.kind != InstructionKind::VOPMSUB || i3.get_dst(0).get_reg() != make_vf(3) || + i3.get_src(0).get_reg() != make_vf(2) || i3.get_src(1).get_reg() != make_vf(1) || + i3.cop2_dest != 14) { + return nullptr; + } + + // sqc2 vf3, 0(a0) + if (i4.kind != InstructionKind::SQC2 || i4.get_src(0).get_reg() != make_vf(3) || + !i4.get_src(1).is_imm(0)) { + return nullptr; + } + Register dst = i4.get_src(2).get_reg(); + + return std::make_unique( + make_dst_var(dst, idx), + SimpleExpression(SimpleExpression::Kind::VECTOR_CROSS, make_src_atom(dst, idx), + make_src_atom(src1, idx), make_src_atom(src2, idx)), + idx); +} + std::unique_ptr convert_5(const Instruction& i0, const Instruction& i1, const Instruction& i2, @@ -1629,6 +1698,11 @@ std::unique_ptr convert_5(const Instruction& i0, if (as_vector_minus) { return as_vector_minus; } + + auto as_vector_cross = convert_vector_cross(i0, i1, i2, i3, i4, idx); + if (as_vector_cross) { + return as_vector_cross; + } return nullptr; } diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 62ddf00d37..56391d9278 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -2188,23 +2188,24 @@ :size-assert #x8c :flag-assert #x1c0000008c (:methods - (TODO-RENAME-9 (_type_ vector float int) quaternion 9) - (TODO-RENAME-10 (_type_ vector) quaternion 10) - (TODO-RENAME-11 (_type_ vector float int) quaternion 11) - (TODO-RENAME-12 (_type_ vector) quaternion 12) - (TODO-RENAME-13 (_type_ float float int) quaternion 13) - (TODO-RENAME-14 (_type_ float) quaternion 14) - (TODO-RENAME-15 (_type_ float) quaternion 15) - (TODO-RENAME-VECTOR-DOT-16 (_type_ float) quaternion 16) - (TODO-RENAME-17 (_type_ quaternion float float) quaternion 17) - (set-quaternion!-18 (_type_ quaternion) quaternion 18) - (TODO-RENAME-19 (_type_ vector) quaternion 19) - (TODO-RENAME-20 (_type_ vector) quaternion 20) - (rot->dir-targ!-21 (_type_) quaternion 21) + (seek-toward-heading-vec! (_type_ vector float int) quaternion 9) + (set-heading-vec! (_type_ vector) quaternion 10) + (seek-to-point-toward-point! (_type_ vector float int) quaternion 11) + (point-toward-point! (_type_ vector) quaternion 12) + (seek-toward-yaw-angle! (_type_ float float int) quaternion 13) + (set-yaw-angle-clear-roll-pitch! (_type_ float) quaternion 14) + + (set-roll-to-grav! (_type_ float) quaternion 15) + (set-roll-to-grav-2! (_type_ float) quaternion 16) + (rotate-toward-orientation! (_type_ quaternion float float) quaternion 17) + (set-quaternion! (_type_ quaternion) quaternion 18) + (set-heading-vec-clear-roll-pitch! (_type_ vector) quaternion 19) + (point-toward-point-clear-roll-pitch! (_type_ vector) quaternion 20) + (rot->dir-targ! (_type_) quaternion 21) (y-angle (_type_) float 22) (global-y-angle-to-point (_type_ vector) float 23) (relative-y-angle-to-point (_type_ vector) float 24) - (TODO-VECTOR-MATH-ISSUES-25 (_type_) float 25) + (roll-relative-to-gravity (_type_) float 25) (TODO-RENAME-26 (_type_ int vector float) trsqv 26) (get-quaternion (_type_) quaternion 27) ) @@ -14679,7 +14680,7 @@ (define-extern matrix<-no-trans-transformq! (function matrix transformq matrix)) (define-extern matrix<-transformq+trans! (function matrix transformq vector matrix)) (define-extern matrix<-transformq+world-trans! (function matrix transformq vector matrix)) -(define-extern matrix<-parented-transformq! (function matrix transformq quaternion matrix)) +(define-extern matrix<-parented-transformq! (function matrix transformq vector matrix)) ;; ---------------------- @@ -14690,9 +14691,10 @@ ;; - Functions -(define-extern ray-sphere-intersect (function vector vector vector vector float)) -(define-extern raw-ray-sphere-intersect (function vector float)) -(define-extern ray-circle-intersect (function vector vector vector vector float)) +;; pt, u, sphere, rad +(define-extern ray-sphere-intersect (function vector vector vector float float)) +(define-extern raw-ray-sphere-intersect (function float float)) +(define-extern ray-circle-intersect (function vector vector vector float float)) (define-extern ray-cylinder-intersect (function vector vector vector vector float float vector float)) (define-extern ray-plane-intersect (function vector vector vector vector vector vector vector float)) (define-extern ray-triangle-intersect (function vector)) ;; NOTE - didn't bother to check input args diff --git a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc index bdc8bb7a2c..bc9d61d96f 100644 --- a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc @@ -109,7 +109,6 @@ "collide-do-primitives", // P: asm branching "ray-triangle-intersect", // F: asm branching "ray-cylinder-intersect", // F: asm branching - "raw-ray-sphere-intersect", // joint "calc-animation-from-spr", // F: asm branching @@ -536,6 +535,7 @@ "(method 12 perf-stat)": [0], "(method 11 perf-stat)": [0], "(method 20 actor-link-info)": [2], - "(method 21 actor-link-info)": [2] + "(method 21 actor-link-info)": [2], + "raw-ray-sphere-intersect": [0, 1, 2, 3, 4, 5] } } diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index 86751a127d..df4c4d32ce 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -497,7 +497,7 @@ "cam-update-h": [["L2", "bfloat", true]], - "collide-func": [["L41", "float", true]], + "collide-func": [["L41", "float", true], ["L40", "float", true]], "cylinder": [ ["L27", "float", true], diff --git a/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc b/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc index 5be358041a..54e7600f24 100644 --- a/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc @@ -174,7 +174,7 @@ "make-light-kit": [[16, "matrix"]], - "matrix<-parented-transformq!": [[16, "quaternion"]], + "matrix<-parented-transformq!": [[16, "vector"]], "(method 20 trsqv)": [[16, "vector"]], @@ -192,7 +192,7 @@ [16, "vector"], [32, "vector"], [48, "vector"], - [64, "quaternion"] + [64, "vector"] ], "(method 16 trsqv)": [ diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index b89c08c8fa..d3ec4fe5a2 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -552,9 +552,7 @@ "(method 0 fact-info-target)": [[[3, 20], "gp", "fact-info-target"]], - "(method 0 align-control)": [ - [[14, 18], "v0", "align-control"] - ], + "(method 0 align-control)": [[[14, 18], "v0", "align-control"]], "str-load": [[[20, 36], "s2", "load-chunk-msg"]], @@ -637,6 +635,8 @@ "num-func-chan": [[8, "v1", "joint-control-channel"]], + "cspace-by-name-no-fail": [[[0, 100], "v0", "cspace"]], + "shrubbery-login-post-texture": [ //[[13, 41], "a3", "qword"], // [[13, 41], "a2", "qword"] @@ -654,7 +654,6 @@ "(method 3 sparticle-cpuinfo)": [[106, "f0", "float"]], - "camera-teleport-to-entity": [[9, "a0", "transform"]], "add-debug-sphere-from-table": [[[9, 18], "s1", "(inline-array vector)"]], @@ -740,9 +739,7 @@ ], "(method 12 art-group)": [[13, "a0", "art-joint-anim"]], - "(method 0 path-control)": [ - ["_stack_", 16, "res-tag"] - ], + "(method 0 path-control)": [["_stack_", 16, "res-tag"]], "(method 0 curve-control)": [[[13, 55], "s3", "entity"]], @@ -1267,5 +1264,10 @@ [130, "a0", "collide-shape-moving"] ], + "raw-ray-sphere-intersect": [ + [23, "v1", "float"], + [36, "v1", "uint"] + ], + "placeholder-do-not-add-below": [] } diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index d6dfbe6966..36f90c57eb 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -1714,10 +1714,10 @@ "(method 20 actor-link-info)": { "args": ["obj", "message"], "vars": { - "s4-0":"iter", - "s5-0":"result", - "a0-1":"proc", - "a1-1":"msg-block" + "s4-0": "iter", + "s5-0": "result", + "a0-1": "proc", + "a1-1": "msg-block" } }, @@ -1824,13 +1824,12 @@ "(method 8 res-lump)": { "args": ["obj", "block", "flags"], - "vars": { - "s3-0":"mem-use-id", - "s2-0":"mem-use-name", - "v1-22":"obj-size", - "s1-0":"tag-idx", - "s0-0":"tag-data" - + "vars": { + "s3-0": "mem-use-id", + "s2-0": "mem-use-name", + "v1-22": "obj-size", + "s1-0": "tag-idx", + "s0-0": "tag-data" } }, @@ -2376,68 +2375,123 @@ "s5-9": "dma-buff", "gp-9": "dma-start", "v1-533": ["dma-pkt", "dma-packet"], - "gp-10":"timeout", - "v1-548":"inactive-timeout", - "gp-11":"game-end-proc" + "gp-10": "timeout", + "v1-548": "inactive-timeout", + "gp-11": "game-end-proc" } }, "load-game-text-info": { - "args":["txt-name","curr-text","heap"], - "vars":{ - "sv-16":"heap-sym-heap", - "sv-24":"lang", - "sv-32":"load-status", - "sv-40":"heap-free" + "args": ["txt-name", "curr-text", "heap"], + "vars": { + "sv-16": "heap-sym-heap", + "sv-24": "lang", + "sv-32": "load-status", + "sv-40": "heap-free" } }, "(method 13 art-group)": { - "vars":{ - "s3-0":"art-elt", - "s4-0":"janim", - "v1-9":"janim-group", - "s2-0":"success" + "vars": { + "s3-0": "art-elt", + "s4-0": "janim", + "v1-9": "janim-group", + "s2-0": "success" } }, "(method 14 art-group)": { - "vars":{ - "s3-0":"art-elt", - "s4-0":"janim", - "v1-9":"janim-group", - "s3-1":"success" - } - }, - - "(method 16 process-drawable)" : { "vars": { - "s3-0":"body-T-world", - "s0-0":"world-T-body", - "s2-0":"grav-rt-body", - "a1-5":"vel-rt-body" + "s3-0": "art-elt", + "s4-0": "janim", + "v1-9": "janim-group", + "s3-1": "success" } }, - "(method 11 cam-float-seeker)" : { + "(method 16 process-drawable)": { + "vars": { + "s3-0": "body-T-world", + "s0-0": "world-T-body", + "s2-0": "grav-rt-body", + "a1-5": "vel-rt-body" + } + }, + + "(method 11 cam-float-seeker)": { "args": ["obj", "offset"], "vars": { - "f1-2":"pos-error", - "f0-5":"partial-velocity-limit", - "f1-3":"daccel", - "f1-6":"abs-vel", - "f0-6":"abs-vel-limit", - "f0-10":"dpos" + "f1-2": "pos-error", + "f0-5": "partial-velocity-limit", + "f1-3": "daccel", + "f1-6": "abs-vel", + "f0-6": "abs-vel-limit", + "f0-10": "dpos" } }, - - "ja-play-spooled-anim" : { + + "(method 9 trsqv)": { + "args": ["obj", "dir", "vel", "frame-count"], "vars": { - "sv-16":"spool-part", - "sv-28":"old-skel-status", - "sv-64":"spool-sound" + "f0-0": "yaw-error", + "f1-2": "yaw-limit", + "f30-0": "saturated-yaw", + "a1-2": "quat", + "f0-2": "old-diff" } }, - - "aaaaaaaaaaaaaaaaaaaaaaa" : {} + + "(method 13 trsqv)": { + "args": ["obj", "yaw", "vel", "frame-count"] + }, + + "(method 16 trsqv)": { + "vars": { + "s5-0": "quat", + "s1-0": "grav", + "s3-0": "rot-mat", + "s4-0": "dir-z", + "a0-4": "dir-x" + } + }, + + "(method 25 trsqv)": { + "vars": { + "s5-0": "quat", + "gp-0": "dir-z", + "s5-1": "dir-y", + "a1-2": "dir-grav", + "v1-2": "grav-z-plane", + "f0-1": "grav-dot" + } + }, + + "(method 17 trsqv)": { + "args": ["obj", "target", "y-rate", "z-rate"], + "vars": { + "gp-0": "quat", + "s5-0": "temp-quat" + } + }, + + "raw-ray-sphere-intersect": { + "vars": { + "v0-0": ["result", "float"], + "v1-0": ["v1-0", "float"] + } + }, + + "ray-sphere-intersect": { + "args": ["ray-origin", "ray-dir", "sph-origin", "radius"] + }, + + "ja-play-spooled-anim": { + "vars": { + "sv-16": "spool-part", + "sv-28": "old-skel-status", + "sv-64": "spool-sound" + } + }, + + "aaaaaaaaaaaaaaaaaaaaaaa": {} } diff --git a/goal_src/engine/anim/aligner.gc b/goal_src/engine/anim/aligner.gc index aca99d537f..2a2e34980b 100644 --- a/goal_src/engine/anim/aligner.gc +++ b/goal_src/engine/anim/aligner.gc @@ -66,7 +66,7 @@ ) ) (if a0-9 - (set! (-> obj flags) (logior (-> obj flags) 1)) + (logior! (-> obj flags) 1) (set! (-> obj flags) (logand -2 (the-as int (-> obj flags)))) ) (set! (-> obj frame-group) v1-16) diff --git a/goal_src/engine/camera/math-camera.gc b/goal_src/engine/camera/math-camera.gc index 8697033dfa..5da9ba3c09 100644 --- a/goal_src/engine/camera/math-camera.gc +++ b/goal_src/engine/camera/math-camera.gc @@ -320,10 +320,10 @@ ;; circle/square move camera relative x (left and right) (set! (-> local-trans x) (cond - ((nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons circle))) + ((logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons circle)) -80.0 ) - ((nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons square))) + ((logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons square)) 80.0 ) (else @@ -338,10 +338,10 @@ ;; in and out movement (set! (-> local-trans z) (cond - ((nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons down))) + ((logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons down)) -80.0 ) - ((nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons up))) + ((logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons up)) 80.0 ) (else @@ -370,24 +370,24 @@ (set! (-> trans trans w) 1.0) ;; global translation - (if (nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r1))) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r1)) (set! (-> trans trans y) (+ 80.0 (-> trans trans y))) ) - (if (nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r2))) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r2)) (set! (-> trans trans y) (+ -80.0 (-> trans trans y))) ) ;; rotation (don't allow camera roll) - (if (nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons x))) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons x)) (set! (-> trans rot x) (+ 546.13336 (-> trans rot x))) ) - (if (nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons triangle))) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons triangle)) (set! (-> trans rot x) (+ -546.13336 (-> trans rot x))) ) - (if (nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons left))) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons left)) (set! (-> trans rot y) (+ 546.13336 (-> trans rot y))) ) - (if (nonzero? (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons right))) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons right)) (set! (-> trans rot y) (+ -546.13336 (-> trans rot y))) ) trans diff --git a/goal_src/engine/collide/collide-func.gc b/goal_src/engine/collide/collide-func.gc index b6e705ebc5..804518d396 100644 --- a/goal_src/engine/collide/collide-func.gc +++ b/goal_src/engine/collide/collide-func.gc @@ -5,4 +5,212 @@ ;; name in dgo: collide-func ;; dgos: GAME, ENGINE -;; TODO - done but there are a ton of ASM functions in here so no point adding to reference/src yet! +;; This file contains the primitive intersection functions used for collision. +;; Most take a description of primitive and a "probe" +;; The probe has an origin and a direction. The length of the direction vector is the length +;; of the probe. + +;; Generally, collision functions will return the fraction of the probe to reach the primitive. +;; For example, if the probe is 5.0 long, and hits the primitive 2.0 away from the probe origin, +;; the return value (u) would be 0.4. + +;; If (u) would be > 1.0, then it counts as "not intersecting" (object too far away) +;; If (u) would be < 0.0, then it counts as "not intersecting" (object behind probe) +;; If there's a miss, return COLLISION_MISS, a large negative number. +;; If we are inside of the primitive, return 0.0 + +(defconstant COLLISION_MISS -100000000.0) + + + +(defun raw-ray-sphere-intersect ((arg0 float)) + "DANGER: this function takes two arguments by vf registers. + As a result, it doesn't work properly in OpenGOAL. See the functions below." + (local-vars + (v1-1 float) + (v1-2 float) + (v1-4 number) + (a0-1 float) + (a0-2 float) + (a0-3 int) + (a1-0 float) + ) + (crash!) + (rlet ((Q :class vf) + (vf0 :class vf) + (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) + ) + (init-vf0-vector) + (.mov vf3 arg0) ;; vf3 = radius + ;; sphere is at the origin, vf1 is source of the ray (o) + ;; vf2 is the ray's unit vector (u) + (.mul.vf vf4 vf2 vf2) ;; vf4 = u.^2 + (.mul.vf vf3 vf3 vf3) ;; vf3 = r^2 + (.mul.vf vf6 vf1 vf1) ;; vf6 = o.^2 + (.mul.vf vf5 vf2 vf1) ;; vf5 = u . o + (.add.y.vf vf4 vf4 vf4 :mask #b1) + (let ((result (the-as float 0))) + (.add.x.vf vf6 vf6 vf6 :mask #b10) + (.sub.x.vf vf6 vf6 vf3 :mask #b100) + (.add.z.vf vf4 vf4 vf4 :mask #b1) + (.add.x.vf vf5 vf5 vf5 :mask #b10) + (let ((v1-0 (the-as float 0))) + (.add.z.vf vf6 vf6 vf6 :mask #b10) + (.div.vf Q vf0 vf4 :fsf #b11 :ftf #b0) + (.add.z.vf vf5 vf5 vf5 :mask #b10) + (.mov a0-1 vf4) + (.mul.x.vf vf7 vf6 vf4) + (.mov a1-0 vf6) + (.mul.vf vf8 vf5 vf5) + (b! (< (the-as int a1-0) 0) cfg-7 :delay (set! a0-2 a0-1)) + (.mul.vf vf4 vf0 Q :mask #b1000) + (.sub.vf vf9 vf8 vf7) + (b! (= a0-2 v1-0) cfg-6 :delay (.mov v1-1 vf5)) + ) + (.sqrt.vf Q vf9 :ftf #b1) + (b! (>= (the-as int v1-1) 0) cfg-6 :delay (.mov v1-2 vf9)) + (b! (< (the-as int v1-2) 0) cfg-6 :delay 1.0) + (.add.x.vf vf6 vf5 vf4) + (.mov v1-4 vf6) + (.mul.vf vf6 vf6 vf6) + (.mul.vf vf9 vf0 Q :mask #b1000) + (.sub.vf vf6 vf9 vf6) + (.add.w.vf vf9 vf5 vf9 :mask #b10) + (.mov a0-3 vf6) + (.mul.w.vf vf9 vf9 vf4 :mask #b10) + (b! + (< (logand (the-as uint v1-4) (the-as uint a0-3)) 0) + cfg-6 + :delay + (.sub.y.vf vf4 vf0 vf9) + ) + (b! #t cfg-7 :delay (.mov result vf4)) + (label cfg-6) + (set! result -100000000.0) + (label cfg-7) + (the-as float result) + ) + ) + ) + +(defmacro pc-port-do-raw-ray-sphere-intersect (rad vf1-val vf2-val) + "Calls to raw-ray-sphere-intersect should be replaced with this macro, + and this should be given vf1, vf2, which contain the origin and direction of the probe." + `(let ((vf1-storage (new 'stack-no-clear 'vector)) + (vf2-storage (new 'stack-no-clear 'vector)) + ) + (.svf (&-> vf1-storage quad) ,vf1-val) + (.svf (&-> vf2-storage quad) ,vf2-val) + (pc-port-raw-ray-sphere-implementation ,rad vf1-storage vf2-storage) + ) + ) + + +(defun pc-port-raw-ray-sphere-implementation ((rad float) (vf1-val vector) (vf2-val vector)) + "This is one of the main primitives for collision. + Assumes a sphere of radius rad is at the origin. + Handles: + - miss (return MISS) + - behind (return MISS) + - too far away (return MISS) + - inside (return 0) + " + (local-vars + (v1-1 int) + (v1-2 int) + (v1-4 int) + (a0-1 float) + (a0-2 float) + (a0-3 int) + (a1-0 int) + ) + (rlet ((Q :class vf) + (vf0 :class vf) + (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) + ) + (init-vf0-vector) + (.lvf vf1 (&-> vf1-val quad)) + (.lvf vf2 (&-> vf2-val quad)) + (.mov vf3 rad) + (.mul.vf vf4 vf2 vf2) + (.mul.vf vf3 vf3 vf3) + (.mul.vf vf6 vf1 vf1) + (.mul.vf vf5 vf2 vf1) + (.add.y.vf vf4 vf4 vf4 :mask #b1) + (let ((result (the-as float 0))) + (.add.x.vf vf6 vf6 vf6 :mask #b10) + (.sub.x.vf vf6 vf6 vf3 :mask #b100) + (.add.z.vf vf4 vf4 vf4 :mask #b1) + (.add.x.vf vf5 vf5 vf5 :mask #b10) + (let ((v1-0 (the-as float 0))) + (.add.z.vf vf6 vf6 vf6 :mask #b10) + (.div.vf Q vf0 vf4 :fsf #b11 :ftf #b0) + (.add.z.vf vf5 vf5 vf5 :mask #b10) + (.mov a0-1 vf4) + (.mul.x.vf vf7 vf6 vf4) + (.mov a1-0 vf6) + (.mul.vf vf8 vf5 vf5) + (b! (< (the-as int a1-0) 0) cfg-7 :delay (set! a0-2 a0-1)) ;; in the sphere + (.mul.vf vf4 vf0 Q :mask #b1000) + (.sub.vf vf9 vf8 vf7) + (b! (= a0-2 v1-0) cfg-6 :delay (.mov v1-1 vf5)) ;; bad denominator in division + ) + (.sqrt.vf Q vf9 :ftf #b1) + (b! (>= (the-as int v1-1) 0) cfg-6 :delay (.mov v1-2 vf9)) ;; wrong dir + (b! (< (the-as int v1-2) 0) cfg-6 :delay 1.0) ;; bad sqrt + (.add.x.vf vf6 vf5 vf4) + (.mov v1-4 vf6) + (.mul.vf vf6 vf6 vf6) + (.mul.vf vf9 vf0 Q :mask #b1000) + (.sub.vf vf6 vf9 vf6) + (.add.w.vf vf9 vf5 vf9 :mask #b10) + (.mov a0-3 vf6) + (.mul.w.vf vf9 vf9 vf4 :mask #b10) + + ;; too far. + (b! (< (logand (the-as int v1-4) (the-as int a0-3)) 0) + cfg-6 + :delay (.sub.y.vf vf4 vf0 vf9) + ) + (b! #t cfg-7 :delay (.mov result vf4)) + (label cfg-6) + (set! result -100000000.0) + (label cfg-7) + (the-as float result) + ) + ) + ) + + +(defun ray-sphere-intersect ((ray-origin vector) (ray-dir vector) (sph-origin vector) (radius float)) + "Intersect a ray and sphere. Will return 0 if you are in the sphere, -huge number if you don't hit it. + Returns the length of the ray to the first intersection." + + ;; offset stuff as if the sphere is at the origin. + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> ray-origin quad)) + (.lvf vf2 (&-> sph-origin quad)) + (.sub.vf vf1 vf1 vf2) ;; the sphere is at the origin in the actual intersection. + (.lvf vf2 (&-> ray-dir quad)) + ;;(raw-ray-sphere-intersect radius) + (pc-port-do-raw-ray-sphere-intersect radius vf1 vf2) + ) + ) diff --git a/goal_src/engine/geometry/geometry.gc b/goal_src/engine/geometry/geometry.gc index d27fcee95a..487924a6c4 100644 --- a/goal_src/engine/geometry/geometry.gc +++ b/goal_src/engine/geometry/geometry.gc @@ -261,6 +261,12 @@ ) ) +;; The "forward down" function take a direction for forward (+z) and down (-y) +;; and convert to a transform. +;; Note that the normal functions take their pitch from the forward vector, but +;; the "nopitch" ones use the pitch from the up/down. Of course, if you are +;; consistent and provide orthogonal forward/down, they do the same thing. + (defun forward-down->inv-matrix ((arg0 matrix) (arg1 vector) (arg2 vector)) (vector-normalize-copy! (-> arg0 vector 2) arg1 1.0) (vector-cross! (the-as vector (-> arg0 vector)) (-> arg0 vector 2) arg2) diff --git a/goal_src/engine/gfx/hw/gs.gc b/goal_src/engine/gfx/hw/gs.gc index 78c9e07537..7869071227 100644 --- a/goal_src/engine/gfx/hw/gs.gc +++ b/goal_src/engine/gfx/hw/gs.gc @@ -818,11 +818,10 @@ "Add a register to the packet" (let ((tag (-> packet gif-tag))) ;; shift the register index into the right slot - (set! (-> tag regs) (logior - (-> tag regs) - (the-as uint (ash reg-idx (shl (-> packet reg-count) 2))) - ) - ) + (logior! + (-> tag regs) + (the-as uint (ash reg-idx (* (-> packet reg-count) 4))) + ) ) ;; set register value and increment count. (set! (-> packet args (-> packet reg-count)) (the-as uint reg-val)) diff --git a/goal_src/engine/gfx/texture.gc b/goal_src/engine/gfx/texture.gc index 7ea2904c98..9c8ce0c732 100644 --- a/goal_src/engine/gfx/texture.gc +++ b/goal_src/engine/gfx/texture.gc @@ -3072,9 +3072,7 @@ ;; only do it if we need to (when (nonzero? (logand (-> shader link-test) (link-test-flags needs-log-in))) - (set! (-> shader link-test) - (logand (lognot (link-test-flags needs-log-in bit-9)) (-> shader link-test)) - ) + (logclear! (-> shader link-test) (link-test-flags needs-log-in bit-9)) ;; remap our texture (set! (-> shader texture-id) (level-remap-texture (-> shader texture-id))) ;; link this shader to the tpage dir @@ -3094,9 +3092,7 @@ (defun adgif-shader-login-no-remap ((arg0 adgif-shader)) "Same as adgif-shader-login, but don't remap our texture id" (when (nonzero? (logand (-> arg0 link-test) (link-test-flags needs-log-in))) - (set! (-> arg0 link-test) - (logand (lognot (link-test-flags needs-log-in bit-9)) (-> arg0 link-test)) - ) + (logclear! (-> arg0 link-test) (link-test-flags needs-log-in bit-9)) (link-texture-by-id (-> arg0 texture-id) arg0) (let ((s5-0 (lookup-texture-by-id (-> arg0 texture-id)))) (if s5-0 @@ -3112,9 +3108,7 @@ "Like adgif-shader-login, but assumes you've already logged in the texture" (when (nonzero? (logand (-> shader link-test) (link-test-flags needs-log-in))) ;; usual remap - (set! (-> shader link-test) - (logand (lognot (link-test-flags needs-log-in bit-9)) (-> shader link-test)) - ) + (logclear! (-> shader link-test) (link-test-flags needs-log-in bit-9)) (set! (-> shader texture-id) (level-remap-texture (-> shader texture-id))) (let ((tex-id (-> shader texture-id))) (when (and (nonzero? (-> tex-id page)) @@ -3156,9 +3150,7 @@ (defun adgif-shader-login-no-remap-fast ((arg0 adgif-shader)) "Like adgif-shader-login-fast, but no level remap" (when (nonzero? (logand (-> arg0 link-test) (link-test-flags needs-log-in))) - (set! (-> arg0 link-test) - (logand (lognot (link-test-flags needs-log-in bit-9)) (-> arg0 link-test)) - ) + (logclear! (-> arg0 link-test) (link-test-flags needs-log-in bit-9)) (let ((v1-4 (-> arg0 texture-id))) (when (and (nonzero? (-> v1-4 page)) (< (the-as uint (-> v1-4 page)) diff --git a/goal_src/engine/level/level.gc b/goal_src/engine/level/level.gc index f40e870633..9685ee64e3 100644 --- a/goal_src/engine/level/level.gc +++ b/goal_src/engine/level/level.gc @@ -1597,6 +1597,6 @@ ;; before calling play, the C Kernel would set this. (define *kernel-boot-message* 'play) (load-package "game" global) - (play #t #t) + (play #t #f) ) ) diff --git a/goal_src/engine/math/transformq-h.gc b/goal_src/engine/math/transformq-h.gc index 398c079dfb..d1167e947b 100644 --- a/goal_src/engine/math/transformq-h.gc +++ b/goal_src/engine/math/transformq-h.gc @@ -26,7 +26,6 @@ ) ;; Representing a translate/rotate/scale with a quaternion and a velocity. -;; definition of type trsqv (deftype trsqv (trsq) ((pause-adjust-distance meters :offset 4) (nav-radius meters :offset 8) @@ -41,26 +40,26 @@ :size-assert #x8c :flag-assert #x1c0000008c (:methods - (TODO-RENAME-9 (_type_ vector float int) quaternion 9) - (TODO-RENAME-10 (_type_ vector) quaternion 10) - (TODO-RENAME-11 (_type_ vector float int) quaternion 11) - (TODO-RENAME-12 (_type_ vector) quaternion 12) - (TODO-RENAME-13 (_type_ float float int) quaternion 13) - (TODO-RENAME-14 (_type_ float) quaternion 14) - (TODO-RENAME-15 (_type_ float) quaternion 15) - (TODO-RENAME-VECTOR-DOT-16 (_type_ float) quaternion 16) - (TODO-RENAME-17 (_type_ quaternion float float) quaternion 17) - (set-quaternion!-18 (_type_ quaternion) quaternion 18) - (TODO-RENAME-19 (_type_ vector) quaternion 19) - (TODO-RENAME-20 (_type_ vector) quaternion 20) - (rot->dir-targ!-21 (_type_) quaternion 21) - (y-angle (_type_) float 22) - (global-y-angle-to-point (_type_ vector) float 23) - (relative-y-angle-to-point (_type_ vector) float 24) - (TODO-VECTOR-MATH-ISSUES-25 (_type_) float 25) - (TODO-RENAME-26 (_type_ int vector float) trsqv 26) - (get-quaternion (_type_) quaternion 27) - ) + (seek-toward-heading-vec! (_type_ vector float int) quaternion 9) + (set-heading-vec! (_type_ vector) quaternion 10) + (seek-to-point-toward-point! (_type_ vector float int) quaternion 11) + (point-toward-point! (_type_ vector) quaternion 12) + (seek-toward-yaw-angle! (_type_ float float int) quaternion 13) + (set-yaw-angle-clear-roll-pitch! (_type_ float) quaternion 14) + (set-roll-to-grav! (_type_ float) quaternion 15) + (set-roll-to-grav-2! (_type_ float) quaternion 16) + (rotate-toward-orientation! (_type_ quaternion float float) quaternion 17) + (set-quaternion! (_type_ quaternion) quaternion 18) + (set-heading-vec-clear-roll-pitch! (_type_ vector) quaternion 19) + (point-toward-point-clear-roll-pitch! (_type_ vector) quaternion 20) + (rot->dir-targ! (_type_) quaternion 21) + (y-angle (_type_) float 22) + (global-y-angle-to-point (_type_ vector) float 23) + (relative-y-angle-to-point (_type_ vector) float 24) + (roll-relative-to-gravity (_type_) float 25) + (TODO-RENAME-26 (_type_ int vector float) trsqv 26) + (get-quaternion (_type_) quaternion 27) + ) ) (defmethod global-y-angle-to-point trsqv ((obj trsqv) (arg0 vector)) diff --git a/goal_src/engine/math/transformq.gc b/goal_src/engine/math/transformq.gc index 6c575e988d..88860ba3c6 100644 --- a/goal_src/engine/math/transformq.gc +++ b/goal_src/engine/math/transformq.gc @@ -5,332 +5,251 @@ ;; name in dgo: transformq ;; dgos: GAME, ENGINE -;; definition for method 2 of type transformq (defmethod print transformq ((obj transformq)) + "Print a transformq" (format #t "# obj trans x) - (-> obj trans y) - (-> obj trans z) - (-> obj trans w) - ) - (format - #t - "~T~Tquat: ~F ~F ~F ~F ~%" - (-> obj rot x) - (-> obj rot y) - (-> obj rot z) - (-> obj rot w) - ) - (format - #t - "~T~Tscale:~F ~F ~F ~F>" - (-> obj scale x) - (-> obj scale y) - (-> obj scale z) - (-> obj scale w) - ) + (format #t "~T~Ttrans:~F ~F ~F ~F ~%" + (-> obj trans x) + (-> obj trans y) + (-> obj trans z) + (-> obj trans w) + ) + (format #t "~T~Tquat: ~F ~F ~F ~F ~%" + (-> obj rot x) + (-> obj rot y) + (-> obj rot z) + (-> obj rot w) + ) + (format #t "~T~Tscale:~F ~F ~F ~F>" + (-> obj scale x) + (-> obj scale y) + (-> obj scale z) + (-> obj scale w) + ) obj ) -;; definition for method 27 of type trsqv -;; INFO: Return type mismatch vector vs quaternion. (defmethod get-quaternion trsqv ((obj trsqv)) - (the-as quaternion (-> obj rot)) + "Get the rotation as a quaternion." + (-> obj quat) ) -;; definition for method 18 of type trsqv -(defmethod set-quaternion!-18 trsqv ((obj trsqv) (arg0 quaternion)) +(defmethod set-quaternion! trsqv ((obj trsqv) (arg0 quaternion)) + "Set the rotation as a quaternion" (quaternion-copy! (get-quaternion obj) arg0) ) -;; definition for method 21 of type trsqv -(defmethod rot->dir-targ!-21 trsqv ((obj trsqv)) +(defmethod rot->dir-targ! trsqv ((obj trsqv)) + "Set the dir-targ to our current orientation" (quaternion-copy! (-> obj dir-targ) (get-quaternion obj)) ) -;; definition for method 22 of type trsqv (defmethod y-angle trsqv ((obj trsqv)) + "Get our current y-angle (y is up, so yaw)" (quaternion-y-angle (get-quaternion obj)) ) -;; definition for method 9 of type trsqv -(defmethod TODO-RENAME-9 trsqv ((obj trsqv) (arg0 vector) (arg1 float) (arg2 int)) - (let* - ((f0-0 - (deg-diff - (quaternion-y-angle (the-as quaternion (-> obj rot))) - (vector-y-angle arg0) - ) - ) - (f1-2 - (fmin - (* arg1 (-> *display* seconds-per-frame)) - (/ (* 5.0 (fabs f0-0)) (the float arg2)) - ) - ) - (f30-0 (fmax (fmin f0-0 f1-2) (- f1-2))) - ) - (let ((f0-2 (-> obj old-y-angle-diff))) - (set! f30-0 (cond - ((or - (= f0-2 0.0) - (and (< 0.0 f30-0) (< 0.0 f0-2)) - (or - (and (< f30-0 0.0) (< f0-2 0.0)) - (>= - (the-as - int - (- - (-> *display* base-frame-counter) - (-> obj angle-change-time) +(defmethod seek-toward-heading-vec! trsqv ((obj trsqv) (dir vector) (vel float) (frame-count int)) + "Adjust the orientation to point along dir, only changing our yaw. + The vel is a maximum velocity limit. + The frame count is the time constant (first order). + There's some logic to avoid rapidly changing directions" + (let* ((yaw-error (deg-diff (quaternion-y-angle (-> obj quat)) (vector-y-angle dir))) + ;; limit both on a max velocity, and a proportional to error term. + (yaw-limit (fmin (* vel (-> *display* seconds-per-frame)) + (/ (* 5.0 (fabs yaw-error)) (the float frame-count)) + ) + ) + ;; saturate the yaw error + (saturated-yaw (fmax (fmin yaw-error yaw-limit) (- yaw-limit))) + ) + (let ((old-diff (-> obj old-y-angle-diff))) + (set! saturated-yaw + (cond + ;; I have no idea what this crazy thing is. + ;; But it prevents changes in direction from happening too often. + ((or (= old-diff 0.0) + (and (< 0.0 saturated-yaw) (< 0.0 old-diff)) + (or (and (< saturated-yaw 0.0) (< old-diff 0.0)) + (>= (the-as int (- (-> *display* base-frame-counter) + (-> obj angle-change-time) + ) + ) + 60 + ) ) - ) - 60 - ) - ) ) - (set! - (-> obj angle-change-time) - (-> *display* base-frame-counter) - ) - f30-0 - ) - (else - (* 0.000000001 f30-0) - ) - ) - ) + (set! (-> obj angle-change-time) (-> *display* base-frame-counter)) + saturated-yaw + ) + (else + ;; not sure why this isn't 0. + (* 0.000000001 saturated-yaw) + ) + ) + ) + ) + (set! (-> obj old-y-angle-diff) saturated-yaw) + (let ((quat (get-quaternion obj))) + (quaternion-rotate-y! quat quat saturated-yaw) + ) ) - (set! (-> obj old-y-angle-diff) f30-0) - (let ((a1-2 (get-quaternion obj))) - (quaternion-rotate-y! a1-2 a1-2 f30-0) - ) - ) ) -;; definition for method 10 of type trsqv -(defmethod TODO-RENAME-10 trsqv ((obj trsqv) (arg0 vector)) +(defmethod set-heading-vec! trsqv ((obj trsqv) (arg0 vector)) + "Makes us look in the arg0 direction immediately. Pitch will be unchanged." (let ((s3-0 (get-quaternion obj))) (forward-up-nopitch->quaternion s3-0 - (vector-normalize-copy! (new 'stack-no-clear 'vector) arg0 1.0) - (vector-y-quaternion! (new 'stack-no-clear 'vector) s3-0) + (vector-normalize-copy! (new 'stack-no-clear 'vector) arg0 1.0) ;; forward is the given dir. + (vector-y-quaternion! (new 'stack-no-clear 'vector) s3-0) ;; use the old up ) ) ) -;; definition for method 11 of type trsqv -(defmethod TODO-RENAME-11 trsqv ((obj trsqv) (arg0 vector) (arg1 float) (arg2 int)) - (rlet ((vf0 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf) - ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (let* ((v1-0 obj) - (t9-0 (method-of-object v1-0 TODO-RENAME-9)) - (t0-1 (new 'stack-no-clear 'vector)) - ) - (let ((a0-1 (-> obj trans))) - (.lvf vf4 (&-> arg0 quad)) - (.lvf vf5 (&-> a0-1 quad)) - ) - (.mov.vf vf6 vf0 :mask #b1000) - (.sub.vf vf6 vf4 vf5 :mask #b111) - (.svf (&-> t0-1 quad) vf6) - (t9-0 v1-0 t0-1 arg1 arg2) - ) +(defmethod seek-to-point-toward-point! trsqv ((obj trsqv) (arg0 vector) (arg1 float) (arg2 int)) + "Seek toward pointing toward arg0 from our current location." + (seek-toward-heading-vec! + obj + (vector-! (new 'stack-no-clear 'vector) arg0 (-> obj trans)) + arg1 + arg2 ) ) -;; definition for method 12 of type trsqv -(defmethod TODO-RENAME-12 trsqv ((obj trsqv) (arg0 vector)) - (rlet ((vf0 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf) - ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (let* ((s3-0 (get-quaternion obj)) - (gp-0 forward-up-nopitch->quaternion) - (s5-0 s3-0) - (t9-1 vector-normalize!) - (a0-2 (new 'stack-no-clear 'vector)) - ) - (let ((v1-1 (-> obj trans))) - (.lvf vf4 (&-> arg0 quad)) - (.lvf vf5 (&-> v1-1 quad)) - ) - (.mov.vf vf6 vf0 :mask #b1000) - (.sub.vf vf6 vf4 vf5 :mask #b111) - (.svf (&-> a0-2 quad) vf6) - (gp-0 - s5-0 - (t9-1 a0-2 1.0) +(defmethod point-toward-point! trsqv ((obj trsqv) (arg0 vector)) + "Immediately point toward arg0" + (let ((s3-0 (get-quaternion obj))) + (forward-up-nopitch->quaternion + s3-0 + (vector-normalize! (vector-! (new 'stack-no-clear 'vector) arg0 (-> obj trans)) 1.0) (vector-y-quaternion! (new 'stack-no-clear 'vector) s3-0) ) ) + ) + + +(defmethod seek-toward-yaw-angle! trsqv ((obj trsqv) (yaw float) (vel float) (frame-count int)) + "Seek toward the given yaw angle." + (seek-toward-heading-vec! + obj + ;; make a vector that points toward +z (forward) rotated by the yaw. + (set-vector! (new 'stack-no-clear 'vector) (sin yaw) 0.0 (cos yaw) 1.0) + vel + frame-count ) ) -;; definition for method 13 of type trsqv -(defmethod - TODO-RENAME-13 - trsqv - ((obj trsqv) (arg0 float) (arg1 float) (arg2 int)) - (let ((s3-0 (method-of-object obj TODO-RENAME-9)) - (s2-0 (new 'stack-no-clear 'vector)) - ) - (set! (-> s2-0 x) (sin arg0)) - (set! (-> s2-0 y) 0.0) - (set! (-> s2-0 z) (cos arg0)) - (set! (-> s2-0 w) 1.0) - (s3-0 obj s2-0 arg1 arg2) +(defmethod set-yaw-angle-clear-roll-pitch! trsqv ((obj trsqv) (yaw float)) + "Immediately clear our roll and pitch and set yaw to the given angle" + (set-heading-vec-clear-roll-pitch! + obj + (set-vector! (new 'stack-no-clear 'vector) (sin yaw) 0.0 (cos yaw) 1.0) ) ) -;; definition for method 14 of type trsqv -(defmethod TODO-RENAME-14 trsqv ((obj trsqv) (arg0 float)) - (let ((s5-0 (method-of-object obj TODO-RENAME-19)) - (s4-0 (new 'stack-no-clear 'vector)) - ) - (set! (-> s4-0 x) (sin arg0)) - (set! (-> s4-0 y) 0.0) - (set! (-> s4-0 z) (cos arg0)) - (set! (-> s4-0 w) 1.0) - (s5-0 obj s4-0) - ) +(defmethod set-roll-to-grav! trsqv ((obj trsqv) (arg0 float)) + "Set our roll so that our local down aligns with standard gravity" + (set-roll-to-grav-2! obj arg0) ) -;; definition for method 15 of type trsqv -(defmethod TODO-RENAME-15 trsqv ((obj trsqv) (arg0 float)) - (TODO-RENAME-VECTOR-DOT-16 obj arg0) - ) - -;; definition for method 16 of type trsqv -(defmethod TODO-RENAME-VECTOR-DOT-16 trsqv ((obj trsqv) (arg0 float)) - (rlet ((acc :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) +(defmethod set-roll-to-grav-2! trsqv ((obj trsqv) (arg0 float)) + "Set our roll so that our local down aligns with standard gravity" + (let* ((quat (get-quaternion obj)) ;; our orientation + (grav (-> *standard-dynamics* gravity-normal)) ;; dir of gravity + (rot-mat (quaternion->matrix (new 'stack-no-clear 'matrix) quat)) ;; our orientation ) - (let* ((s5-0 (get-quaternion obj)) - (s1-0 (-> *standard-dynamics* gravity-normal)) - (s3-0 (quaternion->matrix (new 'stack-no-clear 'matrix) s5-0)) - ) - (let ((s4-0 (&-> s3-0 data 8))) - (vector-normalize! - (vector-flatten! - (the-as vector (&-> s3-0 data 4)) - s1-0 - (the-as vector s4-0) + (let ((dir-z (-> rot-mat vector 2))) ;; this is the direction of the z-axis. + ;; this projects world gravity into our local z plane (killing its pitch component), + ;; then updates the rotation matrix so that this is our y axis (up) + (vector-normalize! (vector-flatten! (-> rot-mat vector 1) grav dir-z) 1.0) + ;; fix up the rotation matrix x vector to make the matrix orthonormal again. + (vector-cross! + (-> rot-mat vector 0) + (-> rot-mat vector 1) + dir-z ) - 1.0 ) - (let ((a0-4 (-> s3-0 data))) - (let ((v1-3 (&-> s3-0 data 4))) - (.lvf vf1 v1-3) - ) - (.lvf vf2 s4-0) - (.outer.product.vf vf3 vf1 vf2) - (.svf (the-as (pointer uint128) (&-> a0-4 0)) vf3) - ) - ) + + ;; add some additional roll offset (let ((a1-5 (matrix-rotate-z! (new 'stack-no-clear 'matrix) arg0))) - (matrix*! s3-0 a1-5 s3-0) - ) - (matrix->quaternion s5-0 s3-0) + (matrix*! rot-mat a1-5 rot-mat) + ) + + ;; write it back. + (matrix->quaternion quat rot-mat) ) - ) ) -;; definition for method 25 of type trsqv -;; WARN: Unsupported inline assembly instruction kind - [mula.s f0, f3] -;; WARN: Unsupported inline assembly instruction kind - [madda.s f1, f4] -;; WARN: Unsupported inline assembly instruction kind - [madd.s f0, f2, f5] -;; WARN: Unsupported inline assembly instruction kind - [mula.s f1, f4] -;; WARN: Unsupported inline assembly instruction kind - [madda.s f2, f5] -;; WARN: Unsupported inline assembly instruction kind - [madd.s f1, f3, f6] -(defmethod TODO-VECTOR-MATH-ISSUES-25 trsqv ((obj trsqv)) - (local-vars (f0-1 float) (f1-2 float)) - (rlet ((acc :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) +(defmethod roll-relative-to-gravity trsqv ((obj trsqv)) + "Get our roll, relative to 'down' from gravity" + (let* ((quat (get-quaternion obj)) + (dir-z (vector-z-quaternion! (new 'stack-no-clear 'vector) quat)) + (dir-y (vector-y-quaternion! (new 'stack-no-clear 'vector) quat)) + (dir-grav (-> *standard-dynamics* gravity-normal)) + ;; project gravity to our z plane (kills pitch) + (grav-z-plane + (vector-normalize! + (vector-flatten! (new 'stack-no-clear 'vector) dir-grav dir-z) + 1.0 + ) + ) + (grav-dot (vector-dot grav-z-plane dir-y)) ) - (let* ((s5-0 (get-quaternion obj)) - (gp-0 (vector-z-quaternion! (new 'stack-no-clear 'vector) s5-0)) - (s5-1 (vector-y-quaternion! (new 'stack-no-clear 'vector) s5-0)) - (a1-2 (-> *standard-dynamics* gravity-normal)) - (v1-2 - (vector-normalize! - (vector-flatten! (new 'stack-no-clear 'vector) a1-2 gp-0) - 1.0 - ) + ;; normally we'd just do (acos (vector-dot grav-z-plane y)) + ;; but this won't give us the correct sign if we're rolled negatively. + ;; this check below manually inverts the acos as needed. + (if (< (vector-dot (vector-cross! (new 'stack-no-clear 'vector) grav-z-plane dir-y) dir-z) + 0.0 ) - ) - (let ((f0-2 (vector-dot v1-2 s5-1))) - (let ((a0-7 (new 'stack-no-clear 'quaternion))) - (.lvf vf1 (&-> v1-2 quad)) - (.lvf vf2 (&-> s5-1 quad)) - (.outer.product.vf vf3 vf1 vf2) - (.svf (&-> a0-7 vec quad) vf3) - (let ((f1-2 (vector-dot a0-7 gp-0))) - (if (< f1-2 0.0) - (- (acos f0-2)) - (acos f0-2) + (- (acos grav-dot)) + (acos grav-dot) ) - ) - ) - ) ) - ) ) -;; definition for method 17 of type trsqv -;; Used lq/sq -(defmethod - TODO-RENAME-17 - trsqv - ((obj trsqv) (arg0 quaternion) (arg1 float) (arg2 float)) + +(defmethod rotate-toward-orientation! trsqv ((obj trsqv) (target quaternion) (y-rate float) (z-rate float)) + "Adjust our orientation toward target, subject to some rate limits. + I don't think this is a very robust function and probably doesn't work right in cases + where an axis flips by 180 degrees." + + ;; the basic idea is that we apply two rotations: + ;; the first moves our y axis toward the desired's y axis, and the second moves + ;; out z axis. These are both rate limited. + (local-vars (sv-96 vector)) - (let ((gp-0 (get-quaternion obj))) - (let ((s5-0 (new 'stack-no-clear 'quaternion))) - (when (< 0.0 arg2) - (let ((s1-0 quaternion-from-two-vectors-max-angle!) - (s0-0 s5-0) - ) - (set! sv-96 (vector-y-quaternion! (new 'stack-no-clear 'vector) gp-0)) - (let ((a2-1 (vector-y-quaternion! (new 'stack-no-clear 'vector) arg0)) - (a3-1 (* arg2 (-> *display* seconds-per-frame))) + (let ((quat (get-quaternion obj))) + (let ((temp-quat (new 'stack-no-clear 'quaternion))) + (when (< 0.0 z-rate) + (let ((s1-0 quaternion-from-two-vectors-max-angle!) + (s0-0 temp-quat) + ) + (set! sv-96 (vector-y-quaternion! (new 'stack-no-clear 'vector) quat)) + (let ((a2-1 (vector-y-quaternion! (new 'stack-no-clear 'vector) target)) + (a3-1 (* z-rate (-> *display* seconds-per-frame))) + ) + (s1-0 s0-0 sv-96 a2-1 a3-1) ) - (s1-0 s0-0 sv-96 a2-1 a3-1) - ) - ) - (quaternion-normalize! (quaternion*! gp-0 s5-0 gp-0)) - ) - (let ((v0-6 (when (< 0.0 arg1) - (quaternion-from-two-vectors-max-angle! - s5-0 - (vector-z-quaternion! (new 'stack-no-clear 'vector) gp-0) - (vector-z-quaternion! (new 'stack-no-clear 'vector) arg0) - (* arg1 (-> *display* seconds-per-frame)) - ) - (quaternion-normalize! (quaternion*! gp-0 s5-0 gp-0)) - ) - ) ) - ) + (quaternion-normalize! (quaternion*! quat temp-quat quat)) + ) + (when (< 0.0 y-rate) + (quaternion-from-two-vectors-max-angle! + temp-quat + (vector-z-quaternion! (new 'stack-no-clear 'vector) quat) + (vector-z-quaternion! (new 'stack-no-clear 'vector) target) + (* y-rate (-> *display* seconds-per-frame)) + ) + (quaternion-normalize! (quaternion*! quat temp-quat quat)) + ) + ) + quat ) - gp-0 - ) ) -;; definition for method 19 of type trsqv -(defmethod TODO-RENAME-19 trsqv ((obj trsqv) (arg0 vector)) +(defmethod set-heading-vec-clear-roll-pitch! trsqv ((obj trsqv) (arg0 vector)) + "Set our rotation to point along the given heading, with no roll or pitch." (forward-up->quaternion (get-quaternion obj) (vector-normalize-copy! (new 'stack-no-clear 'vector) arg0 1.0) @@ -338,43 +257,28 @@ ) ) -;; definition for method 20 of type trsqv -(defmethod TODO-RENAME-20 trsqv ((obj trsqv) (arg0 vector)) - (rlet ((vf0 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf) - ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (let ((gp-0 forward-up->quaternion) - (s3-0 (get-quaternion obj)) - (t9-1 vector-normalize!) - (a0-2 (new 'stack-no-clear 'vector)) - ) - (let ((v1-1 (-> obj trans))) - (.lvf vf4 (&-> arg0 quad)) - (.lvf vf5 (&-> v1-1 quad)) - ) - (.mov.vf vf6 vf0 :mask #b1000) - (.sub.vf vf6 vf4 vf5 :mask #b111) - (.svf (&-> a0-2 quad) vf6) - (gp-0 s3-0 (t9-1 a0-2 1.0) (new 'static 'vector :y 1.0 :w 1.0)) +(defmethod point-toward-point-clear-roll-pitch! trsqv ((obj trsqv) (arg0 vector)) + "Set our orientation to point toward arg0, clearing roll and pitch" + (forward-up->quaternion + (get-quaternion obj) + (vector-normalize! + (vector-! (new 'stack-no-clear 'vector) arg0 (-> obj trans)) + 1.0 ) + (new 'static 'vector :y 1.0 :w 1.0) ) ) -;; definition for function transformq-copy! -;; Used lq/sq (defun transformq-copy! ((arg0 transformq) (arg1 transformq)) + "Set arg0 = arg1" (set! (-> arg0 trans quad) (-> arg1 trans quad)) (set! (-> arg0 rot quad) (-> arg1 rot quad)) (set! (-> arg0 scale quad) (-> arg1 scale quad)) arg0 ) -;; definition for function matrix<-transformq! -;; Used lq/sq (defun matrix<-transformq! ((arg0 matrix) (arg1 transformq)) + "Convert to 4x4 affine transform." (local-vars (v1-1 float)) (rlet ((vf0 :class vf) (vf1 :class vf) @@ -390,12 +294,13 @@ (set! (-> arg0 vector 3 quad) (-> arg1 trans quad)) ) (else + ;; apply scale and copy trans (.lvf vf1 (&-> arg1 scale quad)) (.lvf vf2 (&-> arg1 trans quad)) (.lvf vf3 (&-> arg0 vector 0 quad)) (.lvf vf4 (&-> arg0 vector 1 quad)) (.lvf vf5 (&-> arg0 vector 2 quad)) - (.mov.vf vf2 vf0 :mask #b1000) + (.mov.vf vf2 vf0 :mask #b1000) ;; don't forget the 1. (.mul.x.vf vf3 vf3 vf1) (.mul.y.vf vf4 vf4 vf1) (.mul.z.vf vf5 vf5 vf1) @@ -410,8 +315,8 @@ ) ) -;; definition for function matrix<-no-trans-transformq! (defun matrix<-no-trans-transformq! ((arg0 matrix) (arg1 transformq)) + "Create 4x4 affine transform with no translation." (rlet ((vf0 :class vf) (vf1 :class vf) (vf2 :class vf) @@ -425,7 +330,7 @@ (.lvf vf3 (&-> arg0 vector 0 quad)) (.lvf vf4 (&-> arg0 vector 1 quad)) (.lvf vf5 (&-> arg0 vector 2 quad)) - (.mov.vf vf2 vf0) + (.mov.vf vf2 vf0) ;; trans = 0,0,0,1 (.mul.x.vf vf3 vf3 vf1) (.mul.y.vf vf4 vf4 vf1) (.mul.z.vf vf5 vf5 vf1) @@ -437,8 +342,8 @@ ) ) -;; definition for function matrix<-transformq+trans! (defun matrix<-transformq+trans! ((arg0 matrix) (arg1 transformq) (arg2 vector)) + "Convert to affine transform with an additional translation (in the local frame)." (rlet ((acc :class vf) (vf0 :class vf) (vf1 :class vf) @@ -472,10 +377,8 @@ ) ) -;; definition for function matrix<-transformq+world-trans! -(defun - matrix<-transformq+world-trans! - ((arg0 matrix) (arg1 transformq) (arg2 vector)) +(defun matrix<-transformq+world-trans! ((arg0 matrix) (arg1 transformq) (arg2 vector)) + "Convert to affine transform with an additional translation in the world frame (not rotated)" (rlet ((vf0 :class vf) (vf1 :class vf) (vf2 :class vf) @@ -505,10 +408,8 @@ ) ) -;; definition for function matrix<-parented-transformq! -(defun - matrix<-parented-transformq! - ((arg0 matrix) (arg1 transformq) (arg2 quaternion)) +(defun matrix<-parented-transformq! ((arg0 matrix) (arg1 transformq) (arg2 vector)) + "Unused. Seems like the parented thing means there's an inverse scale in arg2." (local-vars (v1-1 float)) (rlet ((vf0 :class vf) (vf1 :class vf) @@ -518,31 +419,31 @@ (vf5 :class vf) (vf6 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (quaternion->matrix arg0 (the-as quaternion (-> arg1 rot))) - (let ((v1-0 (new 'stack-no-clear 'quaternion))) - (set! (-> v1-0 x) (/ 1.0 (-> arg2 x))) - (set! (-> v1-0 y) (/ 1.0 (-> arg2 y))) - (set! (-> v1-0 z) (/ 1.0 (-> arg2 z))) - (.lvf vf1 (&-> arg1 scale quad)) - (.lvf vf2 (&-> arg1 trans quad)) - (.mov.vf vf2 vf0 :mask #b1000) - (.lvf vf4 (&-> arg0 vector 0 quad)) - (.lvf vf5 (&-> arg0 vector 1 quad)) - (.lvf vf6 (&-> arg0 vector 2 quad)) - (.mul.x.vf vf4 vf4 vf1) - (.mul.y.vf vf5 vf5 vf1) - (.mul.z.vf vf6 vf6 vf1) - (.lvf vf3 (&-> v1-0 vec quad)) + (init-vf0-vector) + (quaternion->matrix arg0 (-> arg1 quat)) + (let ((v1-0 (new 'stack-no-clear 'vector))) + (set! (-> v1-0 x) (/ 1.0 (-> arg2 x))) + (set! (-> v1-0 y) (/ 1.0 (-> arg2 y))) + (set! (-> v1-0 z) (/ 1.0 (-> arg2 z))) + (.lvf vf1 (&-> arg1 scale quad)) + (.lvf vf2 (&-> arg1 trans quad)) + (.mov.vf vf2 vf0 :mask #b1000) + (.lvf vf4 (&-> arg0 vector 0 quad)) + (.lvf vf5 (&-> arg0 vector 1 quad)) + (.lvf vf6 (&-> arg0 vector 2 quad)) + (.mul.x.vf vf4 vf4 vf1) + (.mul.y.vf vf5 vf5 vf1) + (.mul.z.vf vf6 vf6 vf1) + (.lvf vf3 (&-> v1-0 quad)) + ) + (.mul.vf vf4 vf4 vf3) + (.mul.vf vf5 vf5 vf3) + (.mul.vf vf6 vf6 vf3) + (.svf (&-> arg0 vector 3 quad) vf2) + (.svf (&-> arg0 vector 0 quad) vf4) + (.svf (&-> arg0 vector 1 quad) vf5) + (.svf (&-> arg0 vector 2 quad) vf6) + (.mov v1-1 vf6) + arg0 ) - (.mul.vf vf4 vf4 vf3) - (.mul.vf vf5 vf5 vf3) - (.mul.vf vf6 vf6 vf3) - (.svf (&-> arg0 vector 3 quad) vf2) - (.svf (&-> arg0 vector 0 quad) vf4) - (.svf (&-> arg0 vector 1 quad) vf5) - (.svf (&-> arg0 vector 2 quad) vf6) - (.mov v1-1 vf6) - arg0 - ) ) diff --git a/goal_src/engine/math/vector-h.gc b/goal_src/engine/math/vector-h.gc index 235a5668e9..e714d1f609 100644 --- a/goal_src/engine/math/vector-h.gc +++ b/goal_src/engine/math/vector-h.gc @@ -38,17 +38,17 @@ (defmethod new bit-array ((allocation symbol) (type-to-make type) (length int)) "Allocate a new bit-array which can hold length bits. Sets both the length and the allocated-length to this length." - (local-vars (obj bit-array)) - ;; remove one byte, we get one in the type already. - (set! obj (object-new allocation type-to-make - (+ (+ (sar (logand -8 (+ length 7)) 3) -1) - (the-as int (-> type-to-make size)) - ) - ) + (let ((obj (object-new allocation type-to-make + (+ (+ (/ (logand -8 (+ length 7)) 8) -1) + (the-as int (-> type-to-make size)) + ) + ) + ) ) - (set! (-> obj length) length) - (set! (-> obj allocated-length) length) - obj + (set! (-> obj length) length) + (set! (-> obj allocated-length) length) + obj + ) ) (defmethod length bit-array ((obj bit-array)) @@ -58,39 +58,30 @@ (defmethod asize-of bit-array ((obj bit-array)) "Get the size in memory. - It is wrong and says its one bit longer, which is safe." + It is wrong and says its one byte longer, which is safe." (the-as int (+ (-> obj type size) - (the-as uint (sar (logand -8 (+ (-> obj allocated-length) 7)) 3)) + (the-as uint (/ (logand -8 (+ (-> obj allocated-length) 7)) 8)) ) ) ) (defmethod get-bit bit-array ((obj bit-array) (idx int)) "Is the bit at idx set or not?" - (local-vars (byte uint)) - ;; read the byte - (set! byte (-> obj bytes (sar idx 3))) - (nonzero? (logand byte (the-as uint (ash 1 (logand idx 7))))) + (let ((v1-2 (-> obj bytes (/ idx 8)))) + (nonzero? (logand v1-2 (ash 1 (logand idx 7)))) + ) ) (defmethod clear-bit bit-array ((obj bit-array) (idx int)) "Clear the bit at position idx" - (set! (-> obj bytes (sar idx 3)) - (logand (-> obj bytes (sar idx 3)) - (the-as uint (lognot (ash 1 (logand idx 7)))) - ) - ) + (logclear! (-> obj bytes (/ idx 8)) (ash 1 (logand idx 7))) 0 ) (defmethod set-bit bit-array ((obj bit-array) (idx int)) "Set the bit at position idx" - (set! (-> obj bytes (sar idx 3)) - (logior (-> obj bytes (sar idx 3)) - (the-as uint (ash 1 (logand idx 7))) - ) - ) + (logior! (-> obj bytes (/ idx 8)) (the-as uint (ash 1 (logand idx 7)))) 0 ) @@ -507,7 +498,10 @@ (set! (-> vec x) ,xv) (set! (-> vec y) ,yv) (set! (-> vec z) ,zv) - (set! (-> vec w) ,wv))) + (set! (-> vec w) ,wv) + vec + ) + ) ) (defun vector-dot ((a vector) (b vector)) diff --git a/goal_src/engine/nav/navigate-h.gc b/goal_src/engine/nav/navigate-h.gc index ca543f6375..582b2348d3 100644 --- a/goal_src/engine/nav/navigate-h.gc +++ b/goal_src/engine/nav/navigate-h.gc @@ -327,11 +327,12 @@ (else ;; we couldn't find a nav-mesh. Set a bit. (if (and nav-cont (-> proc entity)) - (set! (-> (the-as entity-links (-> (the-as entity (-> proc entity)) extra)) perm status) - (logior (-> (the-as entity-links (-> (the-as entity (-> proc entity)) extra)) perm status) - (entity-perm-status bit-1) - ) - ) + (logior! (-> (the-as entity-links (-> (the-as entity (-> proc entity)) extra)) + perm + status + ) + (entity-perm-status bit-1) + ) ) ;; no nav-mesh, so give us a default-nav-mesh. (set! entity-nav-mesh *default-nav-mesh*) diff --git a/goal_src/engine/nav/path-h.gc b/goal_src/engine/nav/path-h.gc index 3f979d207f..7b0d817147 100644 --- a/goal_src/engine/nav/path-h.gc +++ b/goal_src/engine/nav/path-h.gc @@ -100,7 +100,7 @@ ) (else ;; did not find the data. Set flags and zero stuff - (set! (-> obj flags) (logior (-> obj flags) (path-control-flag not-found))) + (logior! (-> obj flags) (path-control-flag not-found)) (set! (-> obj curve cverts) (the-as pointer #f)) (set! (-> obj curve num-cverts) 0) ) @@ -162,6 +162,7 @@ ) (else ;; couldn't get anything, mark as bad. + (logior! (-> obj flags) (path-control-flag not-found)) (set! (-> obj flags) (logior (-> obj flags) (path-control-flag not-found))) (set! (-> obj curve cverts) (the-as pointer #f)) (set! (-> obj curve num-cverts) 0) diff --git a/goal_src/engine/ps2/pad.gc b/goal_src/engine/ps2/pad.gc index 9a11a6ab67..1aaadd34c1 100644 --- a/goal_src/engine/ps2/pad.gc +++ b/goal_src/engine/ps2/pad.gc @@ -84,7 +84,7 @@ (defun cpad-invalid! ((pad cpad-info)) "Reset all data in a cpad-info" - (set! (-> pad valid) (logior (-> pad valid) 128)) + (logior! (-> pad valid) 128) (set! (-> pad button0) (the-as uint 0)) (set! (-> pad button0-abs 0) (pad-buttons)) (set! (-> pad button0-shadow-abs 0) (pad-buttons)) @@ -270,8 +270,8 @@ ) ;; buttons going down (set! (-> pad button0-rel 0) - (logand (-> pad button0-abs 0) (lognot (-> pad button0-abs 1))) - ) + (logclear (-> pad button0-abs 0) (-> pad button0-abs 1)) + ) ;; ?? (when *cpad-debug* (set! (-> pad leftx) (the-as uint 255)) diff --git a/goal_src/goal-lib.gc b/goal_src/goal-lib.gc index 94483713c5..12c71d6905 100644 --- a/goal_src/goal-lib.gc +++ b/goal_src/goal-lib.gc @@ -495,12 +495,13 @@ (defmacro logclear (a b) "Returns the result of setting the bits in b to zero in a" - `(logand (lognot ,b) ,a) + ;; put a first so the return type matches a. + `(logand ,a (lognot ,b)) ) (defmacro logclear! (a b) "Sets the bits in b to zero in a, in place" - `(set! ,a (logand (lognot ,b) ,a)) + `(set! ,a (logand ,a (lognot ,b))) ) (defmacro logtest? (a b) diff --git a/goal_src/kernel/gcommon.gc b/goal_src/kernel/gcommon.gc index 426bbb3987..887bc96234 100644 --- a/goal_src/kernel/gcommon.gc +++ b/goal_src/kernel/gcommon.gc @@ -1055,12 +1055,9 @@ Not very efficient." (let ((result dst)) (dotimes (i size) - (set! + (logior! (-> (the-as (pointer uint8) dst)) - (logior - (-> (the-as (pointer uint8) dst)) - (-> (the-as (pointer uint8) src)) - ) + (-> (the-as (pointer uint8) src)) ) (&+! dst 1) (&+! src 1) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3d93927d3e..f4fca65bc8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable(goalc-test ${CMAKE_CURRENT_LIST_DIR}/test_emitter_avx.cpp ${CMAKE_CURRENT_LIST_DIR}/test_common_util.cpp ${CMAKE_CURRENT_LIST_DIR}/test_pretty_print.cpp + ${CMAKE_CURRENT_LIST_DIR}/test_math.cpp ${CMAKE_CURRENT_LIST_DIR}/test_zydis.cpp ${CMAKE_CURRENT_LIST_DIR}/goalc/test_goal_kernel.cpp ${CMAKE_CURRENT_LIST_DIR}/decompiler/FormRegressionTest.cpp diff --git a/test/decompiler/reference/engine/anim/aligner_REF.gc b/test/decompiler/reference/engine/anim/aligner_REF.gc index d6ba1d44c5..746d4acba5 100644 --- a/test/decompiler/reference/engine/anim/aligner_REF.gc +++ b/test/decompiler/reference/engine/anim/aligner_REF.gc @@ -59,8 +59,8 @@ ) ) (if a0-9 - (set! (-> obj flags) (logior (-> obj flags) 1)) - (set! (-> obj flags) (logand -2 (the-as int (-> obj flags)))) + (logior! (-> obj flags) 1) + (set! (-> obj flags) (logand -2 (-> obj flags))) ) (set! (-> obj frame-group) v1-16) (set! (-> obj frame-num) f0-0) @@ -190,7 +190,7 @@ trsqv ((obj trsqv) (arg0 int) (arg1 vector) (arg2 float)) (let ((gp-0 (-> obj transv))) - (when (nonzero? (logand arg0 4)) + (when (logtest? arg0 4) (set! (-> gp-0 x) (-> arg1 x)) (set! (-> gp-0 z) (-> arg1 z)) (let @@ -220,13 +220,13 @@ (when (zero? (logand (-> obj flags) 1)) (let ((s5-0 (-> obj delta))) (let ((s3-0 (-> obj process root transv))) - (if (nonzero? (logand arg0 2)) + (if (logtest? arg0 2) (set! (-> s3-0 y) (* (* (-> s5-0 trans y) arg3) (-> *display* frames-per-second)) ) ) - (when (nonzero? (logand arg0 4)) + (when (logtest? arg0 4) (set! (-> s3-0 x) (-> arg1 x)) (set! (-> s3-0 z) (-> arg1 z)) (let @@ -246,7 +246,7 @@ ) ) ) - (if (nonzero? (logand arg0 16)) + (if (logtest? arg0 16) (quaternion-normalize! (quaternion*! (-> obj process root quat) diff --git a/test/decompiler/reference/engine/camera/math-camera_REF.gc b/test/decompiler/reference/engine/camera/math-camera_REF.gc index 54401693c7..122419d2d1 100644 --- a/test/decompiler/reference/engine/camera/math-camera_REF.gc +++ b/test/decompiler/reference/engine/camera/math-camera_REF.gc @@ -353,19 +353,15 @@ (defun move-target-from-pad ((trans transform) (pad-idx int)) (let ((local-trans (new-stack-vector0))) (set! (-> local-trans x) (cond - ((nonzero? - (logand - (-> *cpad-list* cpads pad-idx button0-abs 0) - (pad-buttons circle) - ) + ((logtest? + (-> *cpad-list* cpads pad-idx button0-abs 0) + (pad-buttons circle) ) -80.0 ) - ((nonzero? - (logand - (-> *cpad-list* cpads pad-idx button0-abs 0) - (pad-buttons square) - ) + ((logtest? + (-> *cpad-list* cpads pad-idx button0-abs 0) + (pad-buttons square) ) 80.0 ) @@ -376,19 +372,15 @@ ) (set! (-> local-trans y) 0.0) (set! (-> local-trans z) (cond - ((nonzero? - (logand - (-> *cpad-list* cpads pad-idx button0-abs 0) - (pad-buttons down) - ) + ((logtest? + (-> *cpad-list* cpads pad-idx button0-abs 0) + (pad-buttons down) ) -80.0 ) - ((nonzero? - (logand - (-> *cpad-list* cpads pad-idx button0-abs 0) - (pad-buttons up) - ) + ((logtest? + (-> *cpad-list* cpads pad-idx button0-abs 0) + (pad-buttons up) ) 80.0 ) @@ -408,40 +400,27 @@ (vector+! (-> trans trans) (-> trans trans) local-trans) ) (set! (-> trans trans w) 1.0) - (if - (nonzero? - (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r1)) - ) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r1)) (set! (-> trans trans y) (+ 80.0 (-> trans trans y))) ) - (if - (nonzero? - (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r2)) - ) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r2)) (set! (-> trans trans y) (+ -80.0 (-> trans trans y))) ) - (if - (nonzero? - (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons x)) - ) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons x)) (set! (-> trans rot x) (+ 546.13336 (-> trans rot x))) ) (if - (nonzero? - (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons triangle)) + (logtest? + (-> *cpad-list* cpads pad-idx button0-abs 0) + (pad-buttons triangle) ) (set! (-> trans rot x) (+ -546.13336 (-> trans rot x))) ) - (if - (nonzero? - (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons left)) - ) + (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons left)) (set! (-> trans rot y) (+ 546.13336 (-> trans rot y))) ) (if - (nonzero? - (logand (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons right)) - ) + (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons right)) (set! (-> trans rot y) (+ -546.13336 (-> trans rot y))) ) trans diff --git a/test/decompiler/reference/engine/collide/collide-frag_REF.gc b/test/decompiler/reference/engine/collide/collide-frag_REF.gc index 3039343eae..9fa14a6fe6 100644 --- a/test/decompiler/reference/engine/collide/collide-frag_REF.gc +++ b/test/decompiler/reference/engine/collide/collide-frag_REF.gc @@ -69,7 +69,7 @@ mem-usage collide-fragment ((obj collide-fragment) (arg0 memory-usage-block) (arg1 int)) - (let ((s5-0 (if (nonzero? (logand arg1 1)) + (let ((s5-0 (if (logtest? arg1 1) 53 50 ) diff --git a/test/decompiler/reference/engine/data/res_REF.gc b/test/decompiler/reference/engine/data/res_REF.gc index e94dd06198..80821b697c 100644 --- a/test/decompiler/reference/engine/data/res_REF.gc +++ b/test/decompiler/reference/engine/data/res_REF.gc @@ -284,8 +284,8 @@ (the-as res-tag-pair (logior - (logand (the-as uint #xffffffff) (the-as uint lo-tag-idx-out)) - (the-as uint (shl hi-tag-idx-out 32)) + (logand (the-as uint #xffffffff) lo-tag-idx-out) + (shl hi-tag-idx-out 32) ) ) ) @@ -851,7 +851,7 @@ (>= (the-as uint (length existing-tag)) (the-as uint data-size)) ) (set! resource-mem (&+ (-> obj data-base) (-> existing-tag data-offset))) - (when (nonzero? (logand (the-as int resource-mem) 7)) + (when (logtest? (the-as int resource-mem) 7) (set! resource-mem (logand -16 (&+ (-> obj data-top) 15))) (set! (-> obj data-top) (&+ resource-mem data-size)) ) @@ -1021,19 +1021,19 @@ (mem-use-name "res") ) (cond - ((nonzero? (logand flags 256)) + ((logtest? flags 256) (set! mem-use-id 44) (set! mem-use-name "camera") ) - ((nonzero? (logand flags 64)) + ((logtest? flags 64) (set! mem-use-id 43) (set! mem-use-name "entity") ) - ((nonzero? (logand flags 128)) + ((logtest? flags 128) (set! mem-use-id 49) (set! mem-use-name "ambient") ) - ((nonzero? (logand flags 512)) + ((logtest? flags 512) (set! mem-use-id 73) (set! mem-use-name "art-joint-geo") ) diff --git a/test/decompiler/reference/engine/debug/menu_REF.gc b/test/decompiler/reference/engine/debug/menu_REF.gc index bce6ed296c..8403e8f5d3 100644 --- a/test/decompiler/reference/engine/debug/menu_REF.gc +++ b/test/decompiler/reference/engine/debug/menu_REF.gc @@ -1570,10 +1570,7 @@ (debug-menu-context-release-joypad a0-1) ) (set! (-> arg0 grabbed-joypad-p) #f) - (when - (nonzero? - (logand (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) - ) + (when (logtest? (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) (cond ((-> arg0 float-p) (if (-> arg0 factivate-func) @@ -1612,39 +1609,27 @@ ) ) ((or - (nonzero? - (logand (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons right)) - ) - (nonzero? - (logand (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons left)) - ) - (nonzero? - (logand (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons down)) - ) + (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons right)) + (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons left)) + (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons down)) (nonzero? (logand (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons up))) ) (let ((v1-39 (cond - ((nonzero? - (logand - (-> *cpad-list* cpads 0 button0-abs 0) - (pad-buttons right) - ) + ((logtest? + (-> *cpad-list* cpads 0 button0-abs 0) + (pad-buttons right) ) 10 ) - ((nonzero? - (logand - (-> *cpad-list* cpads 0 button0-abs 0) - (pad-buttons up) - ) + ((logtest? + (-> *cpad-list* cpads 0 button0-abs 0) + (pad-buttons up) ) 1 ) - ((nonzero? - (logand - (-> *cpad-list* cpads 0 button0-abs 0) - (pad-buttons down) - ) + ((logtest? + (-> *cpad-list* cpads 0 button0-abs 0) + (pad-buttons down) ) -1 ) @@ -1953,9 +1938,7 @@ ;; definition for function debug-menus-default-joypad-func (defun debug-menus-default-joypad-func ((arg0 debug-menu-context)) (cond - ((nonzero? - (logand (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons square)) - ) + ((logtest? (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons square)) (cond ((< 1 (-> arg0 sel-length)) (debug-menu-context-close-submenu arg0) @@ -1964,25 +1947,19 @@ ) ) ) - ((nonzero? (logand (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons x))) + ((logtest? (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons x)) (debug-menu-context-activate-selection arg0) ) - ((nonzero? (logand (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons up))) + ((logtest? (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons up)) (debug-menu-context-select-new-item arg0 -1) ) - ((nonzero? - (logand (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons down)) - ) + ((logtest? (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons down)) (debug-menu-context-select-new-item arg0 1) ) - ((nonzero? - (logand (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons left)) - ) + ((logtest? (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons left)) (debug-menu-context-select-new-item arg0 -5) ) - ((nonzero? - (logand (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons right)) - ) + ((logtest? (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons right)) (debug-menu-context-select-new-item arg0 5) ) ) diff --git a/test/decompiler/reference/engine/dma/dma-disasm_REF.gc b/test/decompiler/reference/engine/dma/dma-disasm_REF.gc index e8744f1ac5..05b44dabb0 100644 --- a/test/decompiler/reference/engine/dma/dma-disasm_REF.gc +++ b/test/decompiler/reference/engine/dma/dma-disasm_REF.gc @@ -394,10 +394,7 @@ (set! cmd (-> first-tag cmd)) (when (= - (logand - cmd - (the-as uint (-> *vif-disasm-table* cmd-template-idx mask)) - ) + (logand cmd (-> *vif-disasm-table* cmd-template-idx mask)) (-> *vif-disasm-table* cmd-template-idx tag) ) (let ((print-kind (-> *vif-disasm-table* cmd-template-idx print))) @@ -507,15 +504,12 @@ (+ (logand -4 - (the-as - int - (+ - (* - (-> *vif-disasm-table* cmd-template-idx val) - (-> first-tag num) - ) - 3 + (+ + (* + (-> *vif-disasm-table* cmd-template-idx val) + (-> first-tag num) ) + 3 ) ) 4 @@ -686,7 +680,7 @@ (format stream-2 "ERROR: dma-list data pointer invalid~%") (set! end-condition 'error) ) - (when (nonzero? (logand #x3ff0000 (the-as int current-tag))) + (when (logtest? #x3ff0000 current-tag) (format stream-2 "ERROR: dma tag has data in reserved bits ~X~%") (set! end-condition 'error) ) diff --git a/test/decompiler/reference/engine/dma/dma_REF.gc b/test/decompiler/reference/engine/dma/dma_REF.gc index 2aee82d588..bfd16578fc 100644 --- a/test/decompiler/reference/engine/dma/dma_REF.gc +++ b/test/decompiler/reference/engine/dma/dma_REF.gc @@ -35,13 +35,10 @@ (.sync.l) (set! (-> arg0 madr) - (logior - (logand #xfffffff (the-as int arg1)) - (the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000) - (shl #x8000 16) - 0 - ) - ) + (logior (logand #xfffffff arg1) (if (= (logand #x70000000 arg1) #x70000000) + (shl #x8000 16) + 0 + ) ) ) (set! (-> arg0 qwc) arg2) @@ -64,13 +61,10 @@ (set! (-> arg0 qwc) (the-as uint 0)) (set! (-> arg0 tadr) - (logior - (logand #xfffffff (the-as int arg1)) - (the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000) - (shl #x8000 16) - 0 - ) - ) + (logior (logand #xfffffff arg1) (if (= (logand #x70000000 arg1) #x70000000) + (shl #x8000 16) + 0 + ) ) ) (.sync.l) @@ -95,13 +89,10 @@ (set! (-> arg0 qwc) (the-as uint 0)) (set! (-> arg0 tadr) - (logior - (logand #xfffffff (the-as int arg1)) - (the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000) - (shl #x8000 16) - 0 - ) - ) + (logior (logand #xfffffff arg1) (if (= (logand #x70000000 arg1) #x70000000) + (shl #x8000 16) + 0 + ) ) ) (.sync.l) @@ -122,13 +113,10 @@ (set! (-> arg0 qwc) (the-as uint 0)) (set! (-> arg0 tadr) - (logior - (logand #xfffffff (the-as int arg1)) - (the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000) - (shl #x8000 16) - 0 - ) - ) + (logior (logand #xfffffff arg1) (if (= (logand #x70000000 arg1) #x70000000) + (shl #x8000 16) + 0 + ) ) ) (.sync.l) @@ -151,8 +139,8 @@ (dma-sync (the-as pointer s5-0) 0 0) (flush-cache 0) (.sync.l) - (set! (-> s5-0 madr) (logand #xfffffff (the-as int madr))) - (set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr))) + (set! (-> s5-0 madr) (logand #xfffffff madr)) + (set! (-> s5-0 sadr) (logand #xfffffff sadr)) (set! (-> s5-0 qwc) qwc) (.sync.l) (set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1)) @@ -176,8 +164,8 @@ (let ((s5-0 (the-as dma-bank-spr #x1000d400))) (dma-sync (the-as pointer s5-0) 0 0) (.sync.l) - (set! (-> s5-0 madr) (logand #xfffffff (the-as int madr))) - (set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr))) + (set! (-> s5-0 madr) (logand #xfffffff madr)) + (set! (-> s5-0 sadr) (logand #xfffffff sadr)) (set! (-> s5-0 qwc) qwc) (.sync.l) (set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1)) @@ -200,8 +188,8 @@ (dma-sync (the-as pointer s5-0) 0 0) (flush-cache 0) (.sync.l) - (set! (-> s5-0 madr) (logand #xfffffff (the-as int madr))) - (set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr))) + (set! (-> s5-0 madr) (logand #xfffffff madr)) + (set! (-> s5-0 sadr) (logand #xfffffff sadr)) (set! (-> s5-0 qwc) qwc) (.sync.l) (set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1)) @@ -225,8 +213,8 @@ (let ((s5-0 (the-as dma-bank-spr #x1000d000))) (dma-sync (the-as pointer s5-0) 0 0) (.sync.l) - (set! (-> s5-0 madr) (logand #xfffffff (the-as int madr))) - (set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr))) + (set! (-> s5-0 madr) (logand #xfffffff madr)) + (set! (-> s5-0 sadr) (logand #xfffffff sadr)) (set! (-> s5-0 qwc) qwc) (.sync.l) (set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1)) diff --git a/test/decompiler/reference/engine/draw/process-drawable-h_REF.gc b/test/decompiler/reference/engine/draw/process-drawable-h_REF.gc index bc72f1cf57..8176be4486 100644 --- a/test/decompiler/reference/engine/draw/process-drawable-h_REF.gc +++ b/test/decompiler/reference/engine/draw/process-drawable-h_REF.gc @@ -8,7 +8,7 @@ (the-as cspace (cond (result (empty) - result + (the-as cspace result) ) (else (format 0 "no cspace (~A)~%" arg1) diff --git a/test/decompiler/reference/engine/entity/actor-link-h_REF.gc b/test/decompiler/reference/engine/entity/actor-link-h_REF.gc index f4dd4a2b94..e7c33c0a0c 100644 --- a/test/decompiler/reference/engine/entity/actor-link-h_REF.gc +++ b/test/decompiler/reference/engine/entity/actor-link-h_REF.gc @@ -430,11 +430,9 @@ actor-link-subtask-complete-hook ((arg0 entity-actor) (arg1 (pointer symbol))) (cond - ((nonzero? - (logand - (-> (the-as entity-links (-> arg0 extra)) perm status) - (entity-perm-status complete) - ) + ((logtest? + (-> (the-as entity-links (-> arg0 extra)) perm status) + (entity-perm-status complete) ) (set! (-> arg1 0) #t) #f @@ -449,11 +447,9 @@ ;; definition for function actor-link-dead-hook (defun actor-link-dead-hook ((arg0 entity-actor) (arg1 (pointer symbol))) (cond - ((nonzero? - (logand - (-> (the-as entity-links (-> arg0 extra)) perm status) - (entity-perm-status dead) - ) + ((logtest? + (-> (the-as entity-links (-> arg0 extra)) perm status) + (entity-perm-status dead) ) (set! (-> arg1 0) #t) #f diff --git a/test/decompiler/reference/engine/game/fact-h_REF.gc b/test/decompiler/reference/engine/game/fact-h_REF.gc index 249d7e5b11..a7ee1d8fcf 100644 --- a/test/decompiler/reference/engine/game/fact-h_REF.gc +++ b/test/decompiler/reference/engine/game/fact-h_REF.gc @@ -310,7 +310,7 @@ ) ) ) - (if (nonzero? (logand #x80200 (the-as int (-> obj options)))) + (if (logtest? #x80200 (-> obj options)) (set! (-> obj fade-time) (the-as diff --git a/test/decompiler/reference/engine/game/settings_REF.gc b/test/decompiler/reference/engine/game/settings_REF.gc index 77d01c1b88..a05af74d44 100644 --- a/test/decompiler/reference/engine/game/settings_REF.gc +++ b/test/decompiler/reference/engine/game/settings_REF.gc @@ -23,22 +23,10 @@ (('process-mask) (case (-> conn param1) (('set) - (set! - (-> obj process-mask) - (logior - (-> obj process-mask) - (the-as uint (the-as int (-> conn param3))) - ) - ) + (logior! (-> obj process-mask) (the-as int (-> conn param3))) ) (('clear) - (set! - (-> obj process-mask) - (logand - (-> obj process-mask) - (the-as uint (the-as uint (lognot (the-as uint (-> conn param3))))) - ) - ) + (logclear! (-> obj process-mask) (the-as uint (-> conn param3))) ) (('abs) (set! @@ -236,19 +224,10 @@ (('common-page) (case (-> conn param1) (('set) - (set! - (-> obj common-page) - (logior (-> obj common-page) (the-as int (-> conn param3))) - ) + (logior! (-> obj common-page) (the-as int (-> conn param3))) ) (('clear) - (set! - (-> obj common-page) - (logand - (-> obj common-page) - (the-as int (the-as uint (lognot (the-as uint (-> conn param3))))) - ) - ) + (logclear! (-> obj common-page) (the-as uint (-> conn param3))) ) ) ) diff --git a/test/decompiler/reference/engine/game/task/task-control_REF.gc b/test/decompiler/reference/engine/game/task/task-control_REF.gc index 90e8bacfbf..2f81fce552 100644 --- a/test/decompiler/reference/engine/game/task/task-control_REF.gc +++ b/test/decompiler/reference/engine/game/task/task-control_REF.gc @@ -68,11 +68,11 @@ ) (the-as int (-> obj status)) ) - (set! (-> obj flags) (logior (-> obj flags) (task-flags closed))) + (logior! (-> obj flags) (task-flags closed)) #f ) ((task-complete? *game-info* (-> obj game-task)) - (set! (-> obj flags) (logior (-> obj flags) (task-flags closed))) + (logior! (-> obj flags) (task-flags closed)) #f ) (else @@ -87,13 +87,10 @@ (if (= (-> obj game-task) (game-task none)) (return (the-as int #f)) ) - (set! (-> obj flags) (logior (-> obj flags) (task-flags closed))) - (when (nonzero? (logand (-> obj flags) (task-flags has-entity))) + (logior! (-> obj flags) (task-flags closed)) + (when (logtest? (-> obj flags) (task-flags has-entity)) (let ((v1-9 (get-entity-task-perm *game-info* (-> obj game-task)))) - (set! - (-> v1-9 status) - (logior (-> v1-9 status) (entity-perm-status user-set-from-cstage)) - ) + (logior! (-> v1-9 status) (entity-perm-status user-set-from-cstage)) (if (< (-> v1-9 user-uint8 0) (the-as uint (-> obj status))) (set! (-> v1-9 user-int8 0) (the-as int (-> obj status))) ) @@ -104,7 +101,7 @@ ;; definition for method 15 of type task-cstage (defmethod open-task! task-cstage ((obj task-cstage)) - (set! (-> obj flags) (logand (lognot (task-flags closed)) (-> obj flags))) + (logclear! (-> obj flags) (task-flags closed)) 0 ) @@ -324,10 +321,7 @@ (return 0) ) (let ((v1-4 (get-entity-task-perm *game-info* (-> obj stage 0 game-task)))) - (set! - (-> v1-4 status) - (logior (-> v1-4 status) (entity-perm-status user-set-from-cstage)) - ) + (logior! (-> v1-4 status) (entity-perm-status user-set-from-cstage)) (set! (-> v1-4 user-int8 (+ arg1 1)) arg0) ) 0 diff --git a/test/decompiler/reference/engine/geometry/geometry_REF.gc b/test/decompiler/reference/engine/geometry/geometry_REF.gc index e961719902..b519658710 100644 --- a/test/decompiler/reference/engine/geometry/geometry_REF.gc +++ b/test/decompiler/reference/engine/geometry/geometry_REF.gc @@ -693,11 +693,11 @@ ((arg0 vector) (arg1 vector) (arg2 matrix) (arg3 vector)) (local-vars (v1-0 float) - (v1-4 uint) - (v1-5 uint) - (v1-6 uint) - (v1-7 uint) - (v1-10 uint) + (v1-4 int) + (v1-5 int) + (v1-6 int) + (v1-7 int) + (v1-10 int) (a0-1 float) (a1-1 float) ) @@ -759,7 +759,7 @@ (a0-3 (* a0-2 4)) (v1-3 (logior (logior v1-1 a1-3) a0-3)) ) - (b! (nonzero? v1-3) cfg-3 :delay (set! v1-4 (the-as uint (+ v1-3 -1)))) + (b! (nonzero? v1-3) cfg-3 :delay (set! v1-4 (+ v1-3 -1))) ) (.sub.vf vf17 vf5 vf2) (.mov.vf vf18 vf0 :mask #b1000) @@ -769,7 +769,7 @@ (b! #t cfg-24 :delay (.svf (&-> arg0 quad) vf18)) (nop!) (label cfg-3) - (b! (nonzero? v1-4) cfg-6 :delay (set! v1-5 (the-as uint (+ v1-4 -1)))) + (b! (nonzero? v1-4) cfg-6 :delay (set! v1-5 (+ v1-4 -1))) (vector-segment-distance-point! arg1 (the-as vector (-> arg2 vector)) @@ -778,7 +778,7 @@ ) (goto cfg-24) (label cfg-6) - (b! (nonzero? v1-5) cfg-9 :delay (set! v1-6 (the-as uint (+ v1-5 -1)))) + (b! (nonzero? v1-5) cfg-9 :delay (set! v1-6 (+ v1-5 -1))) (vector-segment-distance-point! arg1 (-> arg2 vector 1) @@ -787,7 +787,7 @@ ) (goto cfg-24) (label cfg-9) - (b! (nonzero? v1-6) cfg-14 :delay (set! v1-7 (the-as uint (+ v1-6 -1)))) + (b! (nonzero? v1-6) cfg-14 :delay (set! v1-7 (+ v1-6 -1))) (let ((f30-0 (vector-segment-distance-point! @@ -814,7 +814,7 @@ ) (goto cfg-24) (label cfg-14) - (b! (nonzero? v1-7) cfg-17 :delay (set! v1-10 (the-as uint (+ v1-7 -1)))) + (b! (nonzero? v1-7) cfg-17 :delay (set! v1-10 (+ v1-7 -1))) (vector-segment-distance-point! arg1 (-> arg2 vector 2) diff --git a/test/decompiler/reference/engine/gfx/hw/display_REF.gc b/test/decompiler/reference/engine/gfx/hw/display_REF.gc index 36bee4dc29..2363b985b9 100644 --- a/test/decompiler/reference/engine/gfx/hw/display_REF.gc +++ b/test/decompiler/reference/engine/gfx/hw/display_REF.gc @@ -570,19 +570,13 @@ (let ((total-qwc (/ (&+ (- -16 (the-as int end-dma)) (-> buf base)) 16))) (cond ((nonzero? total-qwc) - (set! + (logior! (-> (the-as (pointer dma-tag) end-dma) 0) - (logior - (-> (the-as (pointer dma-tag) end-dma) 0) - (the-as uint (new 'static 'dma-tag :qwc total-qwc)) - ) + (new 'static 'dma-tag :qwc total-qwc) ) - (set! + (logior! (-> (the-as (pointer dma-tag) end-dma) 1) - (logior - (-> (the-as (pointer dma-tag) end-dma) 1) - (the-as uint (shl (shr (shl total-qwc 48) 48) 32)) - ) + (shl (shr (shl total-qwc 48) 48) 32) ) ) (else @@ -695,19 +689,13 @@ (let ((total-qwc (/ (&+ (- -16 (the-as int end-dma)) (-> buf base)) 16))) (cond ((nonzero? total-qwc) - (set! + (logior! (-> (the-as (pointer dma-tag) end-dma) 0) - (logior - (-> (the-as (pointer dma-tag) end-dma) 0) - (the-as uint (new 'static 'dma-tag :qwc total-qwc)) - ) + (new 'static 'dma-tag :qwc total-qwc) ) - (set! + (logior! (-> (the-as (pointer dma-tag) end-dma) 1) - (logior - (-> (the-as (pointer dma-tag) end-dma) 1) - (the-as uint (shl (shr (shl total-qwc 48) 48) 32)) - ) + (shl (shr (shl total-qwc 48) 48) 32) ) ) (else diff --git a/test/decompiler/reference/engine/gfx/hw/gs_REF.gc b/test/decompiler/reference/engine/gfx/hw/gs_REF.gc index d9e6fb4988..a82c64eb04 100644 --- a/test/decompiler/reference/engine/gfx/hw/gs_REF.gc +++ b/test/decompiler/reference/engine/gfx/hw/gs_REF.gc @@ -935,13 +935,7 @@ ;; INFO: Return type mismatch gif-packet vs none. (defun add-reg-gif-packet ((packet gif-packet) (reg-idx int) (reg-val int)) (let ((tag (-> packet gif-tag))) - (set! - (-> tag regs) - (logior - (-> tag regs) - (the-as uint (ash reg-idx (* (-> packet reg-count) 4))) - ) - ) + (logior! (-> tag regs) (ash reg-idx (* (-> packet reg-count) 4))) ) (set! (-> (&-> packet args (-> packet reg-count)) 0) (the-as uint reg-val)) (+! (-> packet reg-count) 1) diff --git a/test/decompiler/reference/engine/gfx/texture_REF.gc b/test/decompiler/reference/engine/gfx/texture_REF.gc index 9be03dab00..0528c909d4 100644 --- a/test/decompiler/reference/engine/gfx/texture_REF.gc +++ b/test/decompiler/reference/engine/gfx/texture_REF.gc @@ -1344,11 +1344,7 @@ ) (upload-now! page 2) (update-vram-pages pool (-> pool segment-near) page 2) - (let - ((page-seg-2-size - (logand -4096 (the-as int (+ (-> page segment 2 size) 4095))) - ) - ) + (let ((page-seg-2-size (logand -4096 (+ (-> page segment 2 size) 4095)))) (cond ((< (the-as uint #x24000) page-seg-2-size) (let ((after-seg-2-data (&+ (-> page segment 2 block-data) #x90000))) @@ -1384,8 +1380,7 @@ (defun texture-page-near-allocate-1 ((pool texture-pool) (page texture-page) (heap kheap) (mode int)) - (let - ((seg2-size (logand -4096 (the-as int (+ (-> page segment 2 size) 4095))))) + (let ((seg2-size (logand -4096 (+ (-> page segment 2 size) 4095)))) (let ((seg2-dest (+ (- #x62000 (the-as int seg2-size)) (-> pool segment-near dest)) @@ -3083,7 +3078,7 @@ unlink-textures-in-heap! texture-page-dir ((obj texture-page-dir) (heap kheap)) - (local-vars (dist-past-end uint)) + (local-vars (dist-past-end pointer)) (let ((mem-start (-> heap base)) (mem-end (-> heap top-base)) ) @@ -3104,7 +3099,7 @@ (< (the-as int (- (the-as int shader) (the-as int mem-start))) 0) cfg-7 :delay - (set! dist-past-end (the-as uint (- (the-as int shader) mem-end))) + (set! dist-past-end (- (the-as int shader) mem-end)) ) (b! (>= (the-as int dist-past-end) 0) cfg-7 :delay (nop!)) (let ((t4-2 (-> shader next))) @@ -3222,12 +3217,10 @@ (f1-0 (-> arg1 uv-dist)) (v1-2 (+ v1-1 -1)) (f0-2 (/ f0-1 f1-0)) - (a2-2 (logior a2-1 (the-as uint (* v1-2 4)))) + (a2-2 (logior a2-1 (* v1-2 4))) (v1-5 (shl (-> arg1 mip-shift) 19)) (a3-0 (-> arg1 tex1-control)) - (a2-4 - (logior (logior a2-2 (the-as uint v1-5)) (the-as uint (* a3-0 32))) - ) + (a2-4 (logior (logior a2-2 v1-5) (* a3-0 32))) ) (let* ((t1-1 (incomplete-bitfield-access (-> arg0 tex0))) (v1-6 (-> arg1 psm)) @@ -3248,22 +3241,17 @@ (v1-13 (shl v1-12 26)) ) (.plzcw a3-4 a3-3) - (let ((t1-7 (logior t1-6 (the-as uint v1-13)))) + (let ((t1-7 (logior t1-6 v1-13))) (.subu a3-5 t0-0 a3-4) (let* ((a3-6 (shl a3-5 30)) (v1-14 1) - (t1-9 - (logior - (logior t1-7 (the-as uint a3-6)) - (the-as uint (shl v1-14 34)) - ) - ) + (t1-9 (logior (logior t1-7 a3-6) (shl v1-14 34))) (v1-17 (shl (-> arg1 clutdest) 37)) (a3-8 (shl (-> arg1 clutpsm) 51)) (t1-11 (logior (logior t1-9 v1-17) a3-8)) (v1-19 (shl 1 61)) (f0-3 (the int f0-2)) - (t1-12 (logior t1-11 (the-as uint v1-19))) + (t1-12 (logior t1-11 v1-19)) (v1-20 f0-3) ) (set! (-> arg0 tex0) (the-as gs-tex0 t1-12)) @@ -3280,7 +3268,7 @@ (t0-5 (logand t0-4 15)) ) (nop!) - (b! #t cfg-3 :delay (set! a3-13 (the-as int (+ a3-12 t0-5)))) + (b! #t cfg-3 :delay (set! a3-13 (+ a3-12 t0-5))) ) (label cfg-2) (let* ((t0-6 (+ a3-10 -5)) @@ -3303,7 +3291,7 @@ (t1-13 (-> arg1 dest 1)) (a3-17 (shl a3-16 32)) (v1-21 (-> arg1 width 1)) - (a2-5 (logior a2-4 (the-as uint a3-17))) + (a2-5 (logior a2-4 a3-17)) (v1-22 (shl v1-21 14)) ) (set! (-> arg0 tex1) a2-5) @@ -3319,12 +3307,7 @@ (t0-10 (+ (-> arg1 num-mips) -5)) ) (set! (-> arg0 miptbp1) (the-as gs-miptbp a2-10)) - (b! - (< (the-as int t0-10) 0) - cfg-5 - :delay - (set! a3-22 (the-as uint (-> arg1 width 4))) - ) + (b! (< (the-as int t0-10) 0) cfg-5 :delay (set! a3-22 (-> arg1 width 4))) ) ) ) @@ -3349,11 +3332,8 @@ ;; definition for function adgif-shader-login (defun adgif-shader-login ((shader adgif-shader)) - (when (nonzero? (logand (-> shader link-test) (link-test-flags needs-log-in))) - (set! - (-> shader link-test) - (logand (lognot (link-test-flags needs-log-in bit-9)) (-> shader link-test)) - ) + (when (logtest? (-> shader link-test) (link-test-flags needs-log-in)) + (logclear! (-> shader link-test) (link-test-flags needs-log-in bit-9)) (set! (-> shader texture-id) (level-remap-texture (-> shader texture-id))) (link-texture-by-id (-> shader texture-id) shader) (let ((tex (lookup-texture-by-id (-> shader texture-id)))) @@ -3373,11 +3353,8 @@ ;; definition for function adgif-shader-login-no-remap (defun adgif-shader-login-no-remap ((arg0 adgif-shader)) - (when (nonzero? (logand (-> arg0 link-test) (link-test-flags needs-log-in))) - (set! - (-> arg0 link-test) - (logand (lognot (link-test-flags needs-log-in bit-9)) (-> arg0 link-test)) - ) + (when (logtest? (-> arg0 link-test) (link-test-flags needs-log-in)) + (logclear! (-> arg0 link-test) (link-test-flags needs-log-in bit-9)) (link-texture-by-id (-> arg0 texture-id) arg0) (let ((s5-0 (lookup-texture-by-id (-> arg0 texture-id)))) (if s5-0 @@ -3396,11 +3373,8 @@ ;; definition for function adgif-shader-login-fast (defun adgif-shader-login-fast ((shader adgif-shader)) - (when (nonzero? (logand (-> shader link-test) (link-test-flags needs-log-in))) - (set! - (-> shader link-test) - (logand (lognot (link-test-flags needs-log-in bit-9)) (-> shader link-test)) - ) + (when (logtest? (-> shader link-test) (link-test-flags needs-log-in)) + (logclear! (-> shader link-test) (link-test-flags needs-log-in bit-9)) (set! (-> shader texture-id) (level-remap-texture (-> shader texture-id))) (let ((tex-id (-> shader texture-id))) (when @@ -3450,11 +3424,8 @@ ;; definition for function adgif-shader-login-no-remap-fast (defun adgif-shader-login-no-remap-fast ((arg0 adgif-shader)) - (when (nonzero? (logand (-> arg0 link-test) (link-test-flags needs-log-in))) - (set! - (-> arg0 link-test) - (logand (lognot (link-test-flags needs-log-in bit-9)) (-> arg0 link-test)) - ) + (when (logtest? (-> arg0 link-test) (link-test-flags needs-log-in)) + (logclear! (-> arg0 link-test) (link-test-flags needs-log-in bit-9)) (let ((v1-4 (-> arg0 texture-id))) (when (and diff --git a/test/decompiler/reference/engine/load/loader_REF.gc b/test/decompiler/reference/engine/load/loader_REF.gc index 9d1219ee95..acf22c7bea 100644 --- a/test/decompiler/reference/engine/load/loader_REF.gc +++ b/test/decompiler/reference/engine/load/loader_REF.gc @@ -1113,7 +1113,7 @@ 0.0 0 ) ) - (set! (-> self skel status) (logior (-> self skel status) 7)) + (logior! (-> self skel status) 7) (kill-current-level-hint '() '() 'die) (level-hint-surpress!) (copy-settings-from-target! *setting-control*) @@ -1307,10 +1307,7 @@ ) ) (else - (set! - (-> self skel status) - (logand -5 (the-as int (-> self skel status))) - ) + (set! (-> self skel status) (logand -5 (-> self skel status))) ) ) (dummy-16 *load-state* (ja-aframe-num 0)) @@ -1362,7 +1359,7 @@ ) ) (if (= (-> self skel root-channel 0) (-> self skel channel)) - (set! (-> self skel status) (logior (-> self skel status) 32)) + (logior! (-> self skel status) 32) ) (if (or @@ -1378,10 +1375,7 @@ ) (set! sv-24 f28-0) ) - (set! - (-> self skel status) - (logand -33 (the-as int (-> self skel status))) - ) + (set! (-> self skel status) (logand -33 (-> self skel status))) ) (else (format @@ -1410,9 +1404,9 @@ (dummy-18 *load-state*) (str-play-stop (-> arg0 name)) (set! (-> *art-control* active-stream) #f) - (set! (-> self skel status) (logand -7 (the-as int (-> self skel status)))) + (set! (-> self skel status) (logand -7 (-> self skel status))) (if (zero? (logand (-> self skel status) 1)) - (set! (-> self skel status) (logand -2 (the-as int (-> self skel status)))) + (set! (-> self skel status) (logand -2 (-> self skel status))) ) (clear-pending-settings-from-process *setting-control* self 'spooling) (cond diff --git a/test/decompiler/reference/engine/math/transformq-h_REF.gc b/test/decompiler/reference/engine/math/transformq-h_REF.gc index 626d193b02..7da5691f72 100644 --- a/test/decompiler/reference/engine/math/transformq-h_REF.gc +++ b/test/decompiler/reference/engine/math/transformq-h_REF.gc @@ -54,23 +54,23 @@ :size-assert #x8c :flag-assert #x1c0000008c (:methods - (TODO-RENAME-9 (_type_ vector float int) quaternion 9) - (TODO-RENAME-10 (_type_ vector) quaternion 10) - (TODO-RENAME-11 (_type_ vector float int) quaternion 11) - (TODO-RENAME-12 (_type_ vector) quaternion 12) - (TODO-RENAME-13 (_type_ float float int) quaternion 13) - (TODO-RENAME-14 (_type_ float) quaternion 14) - (TODO-RENAME-15 (_type_ float) quaternion 15) - (TODO-RENAME-VECTOR-DOT-16 (_type_ float) quaternion 16) - (TODO-RENAME-17 (_type_ quaternion float float) quaternion 17) - (set-quaternion!-18 (_type_ quaternion) quaternion 18) - (TODO-RENAME-19 (_type_ vector) quaternion 19) - (TODO-RENAME-20 (_type_ vector) quaternion 20) - (rot->dir-targ!-21 (_type_) quaternion 21) + (seek-toward-heading-vec! (_type_ vector float int) quaternion 9) + (set-heading-vec! (_type_ vector) quaternion 10) + (seek-to-point-toward-point! (_type_ vector float int) quaternion 11) + (point-toward-point! (_type_ vector) quaternion 12) + (seek-toward-yaw-angle! (_type_ float float int) quaternion 13) + (set-yaw-angle-clear-roll-pitch! (_type_ float) quaternion 14) + (set-roll-to-grav! (_type_ float) quaternion 15) + (set-roll-to-grav-2! (_type_ float) quaternion 16) + (rotate-toward-orientation! (_type_ quaternion float float) quaternion 17) + (set-quaternion! (_type_ quaternion) quaternion 18) + (set-heading-vec-clear-roll-pitch! (_type_ vector) quaternion 19) + (point-toward-point-clear-roll-pitch! (_type_ vector) quaternion 20) + (rot->dir-targ! (_type_) quaternion 21) (y-angle (_type_) float 22) (global-y-angle-to-point (_type_ vector) float 23) (relative-y-angle-to-point (_type_ vector) float 24) - (TODO-VECTOR-MATH-ISSUES-25 (_type_) float 25) + (roll-relative-to-gravity (_type_) float 25) (TODO-RENAME-26 (_type_ int vector float) trsqv 26) (get-quaternion (_type_) quaternion 27) ) diff --git a/test/decompiler/reference/engine/math/transformq_REF.gc b/test/decompiler/reference/engine/math/transformq_REF.gc new file mode 100644 index 0000000000..12c935faa1 --- /dev/null +++ b/test/decompiler/reference/engine/math/transformq_REF.gc @@ -0,0 +1,469 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for method 2 of type transformq +(defmethod print transformq ((obj transformq)) + (format #t "# obj trans x) + (-> obj trans y) + (-> obj trans z) + (-> obj trans w) + ) + (format + #t + "~T~Tquat: ~F ~F ~F ~F ~%" + (-> obj quat x) + (-> obj quat y) + (-> obj quat z) + (-> obj quat w) + ) + (format + #t + "~T~Tscale:~F ~F ~F ~F>" + (-> obj scale x) + (-> obj scale y) + (-> obj scale z) + (-> obj scale w) + ) + obj + ) + +;; definition for method 27 of type trsqv +(defmethod get-quaternion trsqv ((obj trsqv)) + (-> obj quat) + ) + +;; definition for method 18 of type trsqv +(defmethod set-quaternion! trsqv ((obj trsqv) (arg0 quaternion)) + (quaternion-copy! (get-quaternion obj) arg0) + ) + +;; definition for method 21 of type trsqv +(defmethod rot->dir-targ! trsqv ((obj trsqv)) + (quaternion-copy! (-> obj dir-targ) (get-quaternion obj)) + ) + +;; definition for method 22 of type trsqv +(defmethod y-angle trsqv ((obj trsqv)) + (quaternion-y-angle (get-quaternion obj)) + ) + +;; definition for method 9 of type trsqv +(defmethod + seek-toward-heading-vec! + trsqv + ((obj trsqv) (dir vector) (vel float) (frame-count int)) + (let* + ((yaw-error + (deg-diff (quaternion-y-angle (-> obj quat)) (vector-y-angle dir)) + ) + (yaw-limit + (fmin + (* vel (-> *display* seconds-per-frame)) + (/ (* 5.0 (fabs yaw-error)) (the float frame-count)) + ) + ) + (saturated-yaw (fmax (fmin yaw-error yaw-limit) (- yaw-limit))) + ) + (let ((old-diff (-> obj old-y-angle-diff))) + (set! saturated-yaw (cond + ((or + (= old-diff 0.0) + (and (< 0.0 saturated-yaw) (< 0.0 old-diff)) + (or + (and (< saturated-yaw 0.0) (< old-diff 0.0)) + (>= + (the-as + int + (- + (-> *display* base-frame-counter) + (-> obj angle-change-time) + ) + ) + 60 + ) + ) + ) + (set! + (-> obj angle-change-time) + (-> *display* base-frame-counter) + ) + saturated-yaw + ) + (else + (* 0.000000001 saturated-yaw) + ) + ) + ) + ) + (set! (-> obj old-y-angle-diff) saturated-yaw) + (let ((quat (get-quaternion obj))) + (quaternion-rotate-y! quat quat saturated-yaw) + ) + ) + ) + +;; definition for method 10 of type trsqv +(defmethod set-heading-vec! trsqv ((obj trsqv) (arg0 vector)) + (let ((s3-0 (get-quaternion obj))) + (forward-up-nopitch->quaternion + s3-0 + (vector-normalize-copy! (new 'stack-no-clear 'vector) arg0 1.0) + (vector-y-quaternion! (new 'stack-no-clear 'vector) s3-0) + ) + ) + ) + +;; definition for method 11 of type trsqv +(defmethod + seek-to-point-toward-point! + trsqv + ((obj trsqv) (arg0 vector) (arg1 float) (arg2 int)) + (seek-toward-heading-vec! + obj + (vector-! (new 'stack-no-clear 'vector) arg0 (-> obj trans)) + arg1 + arg2 + ) + ) + +;; definition for method 12 of type trsqv +(defmethod point-toward-point! trsqv ((obj trsqv) (arg0 vector)) + (let ((s3-0 (get-quaternion obj))) + (forward-up-nopitch->quaternion + s3-0 + (vector-normalize! + (vector-! (new 'stack-no-clear 'vector) arg0 (-> obj trans)) + 1.0 + ) + (vector-y-quaternion! (new 'stack-no-clear 'vector) s3-0) + ) + ) + ) + +;; definition for method 13 of type trsqv +(defmethod + seek-toward-yaw-angle! + trsqv + ((obj trsqv) (yaw float) (vel float) (frame-count int)) + (let ((s3-0 (method-of-object obj seek-toward-heading-vec!)) + (s2-0 (new 'stack-no-clear 'vector)) + ) + (set! (-> s2-0 x) (sin yaw)) + (set! (-> s2-0 y) 0.0) + (set! (-> s2-0 z) (cos yaw)) + (set! (-> s2-0 w) 1.0) + (s3-0 obj s2-0 vel frame-count) + ) + ) + +;; definition for method 14 of type trsqv +(defmethod set-yaw-angle-clear-roll-pitch! trsqv ((obj trsqv) (arg0 float)) + (let ((s5-0 (method-of-object obj set-heading-vec-clear-roll-pitch!)) + (s4-0 (new 'stack-no-clear 'vector)) + ) + (set! (-> s4-0 x) (sin arg0)) + (set! (-> s4-0 y) 0.0) + (set! (-> s4-0 z) (cos arg0)) + (set! (-> s4-0 w) 1.0) + (s5-0 obj s4-0) + ) + ) + +;; definition for method 15 of type trsqv +(defmethod set-roll-to-grav! trsqv ((obj trsqv) (arg0 float)) + (set-roll-to-grav-2! obj arg0) + ) + +;; definition for method 16 of type trsqv +(defmethod set-roll-to-grav-2! trsqv ((obj trsqv) (arg0 float)) + (let* ((quat (get-quaternion obj)) + (grav (-> *standard-dynamics* gravity-normal)) + (rot-mat (quaternion->matrix (new 'stack-no-clear 'matrix) quat)) + ) + (let ((dir-z (-> rot-mat vector 2))) + (vector-normalize! (vector-flatten! (-> rot-mat vector 1) grav dir-z) 1.0) + (vector-cross! + (the-as vector (-> rot-mat vector)) + (-> rot-mat vector 1) + dir-z + ) + ) + (let ((a1-5 (matrix-rotate-z! (new 'stack-no-clear 'matrix) arg0))) + (matrix*! rot-mat a1-5 rot-mat) + ) + (matrix->quaternion quat rot-mat) + ) + ) + +;; definition for method 25 of type trsqv +(defmethod roll-relative-to-gravity trsqv ((obj trsqv)) + (let* ((quat (get-quaternion obj)) + (dir-z (vector-z-quaternion! (new 'stack-no-clear 'vector) quat)) + (dir-y (vector-y-quaternion! (new 'stack-no-clear 'vector) quat)) + (dir-grav (-> *standard-dynamics* gravity-normal)) + (grav-z-plane + (vector-normalize! + (vector-flatten! (new 'stack-no-clear 'vector) dir-grav dir-z) + 1.0 + ) + ) + (grav-dot (vector-dot grav-z-plane dir-y)) + ) + (if + (< + (vector-dot + (vector-cross! (new 'stack-no-clear 'vector) grav-z-plane dir-y) + dir-z + ) + 0.0 + ) + (- (acos grav-dot)) + (acos grav-dot) + ) + ) + ) + +;; definition for method 17 of type trsqv +;; Used lq/sq +(defmethod + rotate-toward-orientation! + trsqv + ((obj trsqv) (target quaternion) (y-rate float) (z-rate float)) + (local-vars (sv-96 vector)) + (let ((quat (get-quaternion obj))) + (let ((temp-quat (new 'stack-no-clear 'quaternion))) + (when (< 0.0 z-rate) + (let ((s1-0 quaternion-from-two-vectors-max-angle!) + (s0-0 temp-quat) + ) + (set! sv-96 (vector-y-quaternion! (new 'stack-no-clear 'vector) quat)) + (let ((a2-1 (vector-y-quaternion! (new 'stack-no-clear 'vector) target)) + (a3-1 (* z-rate (-> *display* seconds-per-frame))) + ) + (s1-0 s0-0 sv-96 a2-1 a3-1) + ) + ) + (quaternion-normalize! (quaternion*! quat temp-quat quat)) + ) + (when (< 0.0 y-rate) + (quaternion-from-two-vectors-max-angle! + temp-quat + (vector-z-quaternion! (new 'stack-no-clear 'vector) quat) + (vector-z-quaternion! (new 'stack-no-clear 'vector) target) + (* y-rate (-> *display* seconds-per-frame)) + ) + (quaternion-normalize! (quaternion*! quat temp-quat quat)) + ) + ) + quat + ) + ) + +;; definition for method 19 of type trsqv +(defmethod set-heading-vec-clear-roll-pitch! trsqv ((obj trsqv) (arg0 vector)) + (forward-up->quaternion + (get-quaternion obj) + (vector-normalize-copy! (new 'stack-no-clear 'vector) arg0 1.0) + (new 'static 'vector :y 1.0 :w 1.0) + ) + ) + +;; definition for method 20 of type trsqv +(defmethod point-toward-point-clear-roll-pitch! trsqv ((obj trsqv) (arg0 vector)) + (forward-up->quaternion + (get-quaternion obj) + (vector-normalize! + (vector-! (new 'stack-no-clear 'vector) arg0 (-> obj trans)) + 1.0 + ) + (new 'static 'vector :y 1.0 :w 1.0) + ) + ) + +;; definition for function transformq-copy! +;; Used lq/sq +(defun transformq-copy! ((arg0 transformq) (arg1 transformq)) + (set! (-> arg0 trans quad) (-> arg1 trans quad)) + (set! (-> arg0 quat vec quad) (-> arg1 quat vec quad)) + (set! (-> arg0 scale quad) (-> arg1 scale quad)) + arg0 + ) + +;; definition for function matrix<-transformq! +;; Used lq/sq +(defun matrix<-transformq! ((arg0 matrix) (arg1 transformq)) + (local-vars (v1-1 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + ) + (init-vf0-vector) + (quaternion->matrix arg0 (-> arg1 quat)) + (cond + (#f + (set! (-> arg0 vector 3 quad) (-> arg1 trans quad)) + ) + (else + (.lvf vf1 (&-> arg1 scale quad)) + (.lvf vf2 (&-> arg1 trans quad)) + (.lvf vf3 (&-> arg0 vector 0 quad)) + (.lvf vf4 (&-> arg0 vector 1 quad)) + (.lvf vf5 (&-> arg0 vector 2 quad)) + (.mov.vf vf2 vf0 :mask #b1000) + (.mul.x.vf vf3 vf3 vf1) + (.mul.y.vf vf4 vf4 vf1) + (.mul.z.vf vf5 vf5 vf1) + (.svf (&-> arg0 vector 3 quad) vf2) + (.svf (&-> arg0 vector 0 quad) vf3) + (.svf (&-> arg0 vector 1 quad) vf4) + (.svf (&-> arg0 vector 2 quad) vf5) + (.mov v1-1 vf5) + ) + ) + arg0 + ) + ) + +;; definition for function matrix<-no-trans-transformq! +(defun matrix<-no-trans-transformq! ((arg0 matrix) (arg1 transformq)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + ) + (init-vf0-vector) + (quaternion->matrix arg0 (-> arg1 quat)) + (.lvf vf1 (&-> arg1 scale quad)) + (.lvf vf3 (&-> arg0 vector 0 quad)) + (.lvf vf4 (&-> arg0 vector 1 quad)) + (.lvf vf5 (&-> arg0 vector 2 quad)) + (.mov.vf vf2 vf0) + (.mul.x.vf vf3 vf3 vf1) + (.mul.y.vf vf4 vf4 vf1) + (.mul.z.vf vf5 vf5 vf1) + (.svf (&-> arg0 vector 3 quad) vf2) + (.svf (&-> arg0 vector 0 quad) vf3) + (.svf (&-> arg0 vector 1 quad) vf4) + (.svf (&-> arg0 vector 2 quad) vf5) + arg0 + ) + ) + +;; definition for function matrix<-transformq+trans! +(defun matrix<-transformq+trans! ((arg0 matrix) (arg1 transformq) (arg2 vector)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (init-vf0-vector) + (quaternion->matrix arg0 (-> arg1 quat)) + (.lvf vf1 (&-> arg1 scale quad)) + (.lvf vf2 (&-> arg1 trans quad)) + (.lvf vf6 (&-> arg2 quad)) + (.lvf vf3 (&-> arg0 vector 0 quad)) + (.lvf vf4 (&-> arg0 vector 1 quad)) + (.lvf vf5 (&-> arg0 vector 2 quad)) + (.mov.vf vf2 vf0 :mask #b1000) + (.mul.x.vf vf3 vf3 vf1) + (.mul.y.vf vf4 vf4 vf1) + (.mul.z.vf vf5 vf5 vf1) + (.mul.x.vf acc vf3 vf6) + (.add.mul.y.vf acc vf4 vf6 acc) + (.add.mul.z.vf acc vf5 vf6 acc) + (.add.mul.w.vf vf2 vf2 vf0 acc :mask #b111) + (.svf (&-> arg0 vector 3 quad) vf2) + (.svf (&-> arg0 vector 0 quad) vf3) + (.svf (&-> arg0 vector 1 quad) vf4) + (.svf (&-> arg0 vector 2 quad) vf5) + arg0 + ) + ) + +;; definition for function matrix<-transformq+world-trans! +(defun + matrix<-transformq+world-trans! + ((arg0 matrix) (arg1 transformq) (arg2 vector)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (init-vf0-vector) + (quaternion->matrix arg0 (-> arg1 quat)) + (.lvf vf1 (&-> arg1 scale quad)) + (.lvf vf2 (&-> arg1 trans quad)) + (.lvf vf6 (&-> arg2 quad)) + (.lvf vf3 (&-> arg0 vector 0 quad)) + (.lvf vf4 (&-> arg0 vector 1 quad)) + (.lvf vf5 (&-> arg0 vector 2 quad)) + (.mov.vf vf2 vf0 :mask #b1000) + (.mul.x.vf vf3 vf3 vf1) + (.mul.y.vf vf4 vf4 vf1) + (.mul.z.vf vf5 vf5 vf1) + (.add.vf vf2 vf2 vf6 :mask #b111) + (.svf (&-> arg0 vector 3 quad) vf2) + (.svf (&-> arg0 vector 0 quad) vf3) + (.svf (&-> arg0 vector 1 quad) vf4) + (.svf (&-> arg0 vector 2 quad) vf5) + arg0 + ) + ) + +;; definition for function matrix<-parented-transformq! +(defun + matrix<-parented-transformq! + ((arg0 matrix) (arg1 transformq) (arg2 vector)) + (local-vars (v1-1 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (init-vf0-vector) + (quaternion->matrix arg0 (-> arg1 quat)) + (let ((v1-0 (new 'stack-no-clear 'vector))) + (set! (-> v1-0 x) (/ 1.0 (-> arg2 x))) + (set! (-> v1-0 y) (/ 1.0 (-> arg2 y))) + (set! (-> v1-0 z) (/ 1.0 (-> arg2 z))) + (.lvf vf1 (&-> arg1 scale quad)) + (.lvf vf2 (&-> arg1 trans quad)) + (.mov.vf vf2 vf0 :mask #b1000) + (.lvf vf4 (&-> arg0 vector 0 quad)) + (.lvf vf5 (&-> arg0 vector 1 quad)) + (.lvf vf6 (&-> arg0 vector 2 quad)) + (.mul.x.vf vf4 vf4 vf1) + (.mul.y.vf vf5 vf5 vf1) + (.mul.z.vf vf6 vf6 vf1) + (.lvf vf3 (&-> v1-0 quad)) + ) + (.mul.vf vf4 vf4 vf3) + (.mul.vf vf5 vf5 vf3) + (.mul.vf vf6 vf6 vf3) + (.svf (&-> arg0 vector 3 quad) vf2) + (.svf (&-> arg0 vector 0 quad) vf4) + (.svf (&-> arg0 vector 1 quad) vf5) + (.svf (&-> arg0 vector 2 quad) vf6) + (.mov v1-1 vf6) + arg0 + ) + ) diff --git a/test/decompiler/reference/engine/math/vector-h_REF.gc b/test/decompiler/reference/engine/math/vector-h_REF.gc index 31d7694ab9..7375d51eb5 100644 --- a/test/decompiler/reference/engine/math/vector-h_REF.gc +++ b/test/decompiler/reference/engine/math/vector-h_REF.gc @@ -68,28 +68,19 @@ ;; definition for method 9 of type bit-array (defmethod get-bit bit-array ((obj bit-array) (arg0 int)) (let ((v1-2 (-> obj bytes (/ arg0 8)))) - (nonzero? (logand v1-2 (the-as uint (ash 1 (logand arg0 7))))) + (nonzero? (logand v1-2 (ash 1 (logand arg0 7)))) ) ) ;; definition for method 10 of type bit-array (defmethod clear-bit bit-array ((obj bit-array) (arg0 int)) - (set! - (-> obj bytes (/ arg0 8)) - (logand - (-> obj bytes (/ arg0 8)) - (the-as uint (lognot (ash 1 (logand arg0 7)))) - ) - ) + (logclear! (-> obj bytes (/ arg0 8)) (ash 1 (logand arg0 7))) 0 ) ;; definition for method 11 of type bit-array (defmethod set-bit bit-array ((obj bit-array) (arg0 int)) - (set! - (-> obj bytes (/ arg0 8)) - (logior (-> obj bytes (/ arg0 8)) (the-as uint (ash 1 (logand arg0 7)))) - ) + (logior! (-> obj bytes (/ arg0 8)) (ash 1 (logand arg0 7))) 0 ) diff --git a/test/decompiler/reference/engine/math/vector_REF.gc b/test/decompiler/reference/engine/math/vector_REF.gc index 2c2fb4729c..5f36b8e0b9 100644 --- a/test/decompiler/reference/engine/math/vector_REF.gc +++ b/test/decompiler/reference/engine/math/vector_REF.gc @@ -3,17 +3,7 @@ ;; definition for function vector-cross! (defun vector-cross! ((arg0 vector) (arg1 vector) (arg2 vector)) - (rlet ((acc :class vf) - (vf1 :class vf) - (vf2 :class vf) - (vf3 :class vf) - ) - (.lvf vf1 (&-> arg1 quad)) - (.lvf vf2 (&-> arg2 quad)) - (.outer.product.vf vf3 vf1 vf2) - (.svf (&-> arg0 quad) vf3) - arg0 - ) + (vector-cross! arg0 arg1 arg2) ) ;; definition for function vector+float! diff --git a/test/decompiler/reference/engine/nav/navigate-h_REF.gc b/test/decompiler/reference/engine/nav/navigate-h_REF.gc index 3be7752698..2bb027f290 100644 --- a/test/decompiler/reference/engine/nav/navigate-h_REF.gc +++ b/test/decompiler/reference/engine/nav/navigate-h_REF.gc @@ -512,20 +512,13 @@ ) (else (if (and nav-cont (-> proc entity)) - (set! + (logior! (-> (the-as entity-links (-> (the-as entity (-> proc entity)) extra)) perm status ) - (logior - (-> - (the-as entity-links (-> (the-as entity (-> proc entity)) extra)) - perm - status - ) - (entity-perm-status bit-1) - ) + (entity-perm-status bit-1) ) ) (set! entity-nav-mesh *default-nav-mesh*) diff --git a/test/decompiler/reference/engine/nav/path-h_REF.gc b/test/decompiler/reference/engine/nav/path-h_REF.gc index 4f5d4c9b33..8d90f987e1 100644 --- a/test/decompiler/reference/engine/nav/path-h_REF.gc +++ b/test/decompiler/reference/engine/nav/path-h_REF.gc @@ -118,10 +118,7 @@ (set! (-> obj curve num-cverts) (the-as int (-> tag elt-count))) ) (else - (set! - (-> obj flags) - (logior (-> obj flags) (path-control-flag not-found)) - ) + (logior! (-> obj flags) (path-control-flag not-found)) (set! (-> obj cverts) (the-as (inline-array vector) #f)) (set! (-> obj curve num-cverts) 0) 0 @@ -196,10 +193,7 @@ (set! (-> obj type) path-control) ) (else - (set! - (-> obj flags) - (logior (-> obj flags) (path-control-flag not-found)) - ) + (logior! (-> obj flags) (path-control-flag not-found)) (set! (-> obj cverts) (the-as (inline-array vector) #f)) (set! (-> obj curve num-cverts) 0) 0 diff --git a/test/decompiler/reference/engine/nav/path_REF.gc b/test/decompiler/reference/engine/nav/path_REF.gc index d92cee38b1..7968fe9cbe 100644 --- a/test/decompiler/reference/engine/nav/path_REF.gc +++ b/test/decompiler/reference/engine/nav/path_REF.gc @@ -5,7 +5,7 @@ ;; INFO: Return type mismatch int vs none. (defmethod dummy-9 path-control ((obj path-control)) (cond - ((nonzero? (logand (-> obj flags) (path-control-flag not-found))) + ((logtest? (-> obj flags) (path-control-flag not-found)) (when (and (type-type? (-> obj process type) process-drawable) @@ -41,7 +41,7 @@ (let ((s4-1 (-> obj cverts s5-1))) (if (and - (nonzero? (logand (-> obj flags) (path-control-flag draw-line))) + (logtest? (-> obj flags) (path-control-flag draw-line)) (< s5-1 (+ (-> obj curve num-cverts) -1)) ) (add-debug-line @@ -54,7 +54,7 @@ (the-as rgba -1) ) ) - (if (nonzero? (logand (-> obj flags) (path-control-flag draw-point))) + (if (logtest? (-> obj flags) (path-control-flag draw-point)) (add-debug-x #t (bucket-id debug-draw1) @@ -62,7 +62,7 @@ (new 'static 'rgba :r #xff :a #x80) ) ) - (when (nonzero? (logand (-> obj flags) (path-control-flag draw-text))) + (when (logtest? (-> obj flags) (path-control-flag draw-text)) (let ((s3-1 add-debug-text-3d) (s2-1 #t) (s1-0 68) @@ -195,19 +195,17 @@ eval-path-curve! curve-control ((obj curve-control) (arg0 vector) (arg1 float) (arg2 symbol)) - (the-as - vector - (if (nonzero? (logand (-> obj flags) (path-control-flag not-found))) - 0.0 - (curve-evaluate! - arg0 - arg1 - (the-as pointer (-> obj cverts)) - (-> obj curve num-cverts) - (-> obj curve knots) - (-> obj curve num-knots) - ) - ) + (the-as vector (if (logtest? (-> obj flags) (path-control-flag not-found)) + 0.0 + (curve-evaluate! + arg0 + arg1 + (the-as pointer (-> obj cverts)) + (-> obj curve num-cverts) + (-> obj curve knots) + (-> obj curve num-knots) + ) + ) ) ) @@ -217,19 +215,17 @@ eval-path-curve-div! curve-control ((obj curve-control) (arg0 vector) (arg1 float) (arg2 symbol)) - (the-as - vector - (if (nonzero? (logand (-> obj flags) (path-control-flag not-found))) - 0.0 - (curve-evaluate! - arg0 - (/ arg1 (the float (+ (-> obj curve num-cverts) -1))) - (the-as pointer (-> obj cverts)) - (-> obj curve num-cverts) - (-> obj curve knots) - (-> obj curve num-knots) - ) - ) + (the-as vector (if (logtest? (-> obj flags) (path-control-flag not-found)) + 0.0 + (curve-evaluate! + arg0 + (/ arg1 (the float (+ (-> obj curve num-cverts) -1))) + (the-as pointer (-> obj cverts)) + (-> obj curve num-cverts) + (-> obj curve knots) + (-> obj curve num-knots) + ) + ) ) ) @@ -379,7 +375,7 @@ ;; INFO: Return type mismatch int vs none. (defmethod dummy-9 curve-control ((obj curve-control)) (cond - ((nonzero? (logand (-> obj flags) (path-control-flag not-found))) + ((logtest? (-> obj flags) (path-control-flag not-found)) (when (and (type-type? (-> obj process type) process-drawable) @@ -413,7 +409,7 @@ ) (if (and - (nonzero? (logand (-> obj flags) (path-control-flag draw-line))) + (logtest? (-> obj flags) (path-control-flag draw-line)) (> (-> obj curve num-cverts) 0) ) (add-debug-curve2 @@ -426,7 +422,7 @@ ) (dotimes (s5-1 (-> obj curve num-cverts)) (let ((s4-1 (-> obj cverts s5-1))) - (if (nonzero? (logand (-> obj flags) (path-control-flag draw-point))) + (if (logtest? (-> obj flags) (path-control-flag draw-point)) (add-debug-x #t (bucket-id debug-draw1) @@ -434,7 +430,7 @@ (new 'static 'rgba :r #xff :a #x80) ) ) - (when (nonzero? (logand (-> obj flags) (path-control-flag draw-text))) + (when (logtest? (-> obj flags) (path-control-flag draw-text)) (let ((s3-1 add-debug-text-3d) (s2-1 #t) (s1-0 68) diff --git a/test/decompiler/reference/engine/ps2/pad_REF.gc b/test/decompiler/reference/engine/ps2/pad_REF.gc index 937791191d..5516706274 100644 --- a/test/decompiler/reference/engine/ps2/pad_REF.gc +++ b/test/decompiler/reference/engine/ps2/pad_REF.gc @@ -96,7 +96,7 @@ ;; definition for function cpad-invalid! (defun cpad-invalid! ((pad cpad-info)) - (set! (-> pad valid) (logior (-> pad valid) 128)) + (logior! (-> pad valid) 128) (set! (-> pad button0) (the-as uint 0)) (set! (-> pad button0-abs 0) (pad-buttons)) (set! (-> pad button0-shadow-abs 0) (pad-buttons)) @@ -296,10 +296,7 @@ ) (set! (-> pad button0-rel 0) - (logand - (-> pad button0-abs 0) - (the-as uint (lognot (-> pad button0-abs 1))) - ) + (logclear (-> pad button0-abs 0) (-> pad button0-abs 1)) ) (when *cpad-debug* (set! (-> pad leftx) (the-as uint 255)) diff --git a/test/decompiler/reference/engine/ps2/timer_REF.gc b/test/decompiler/reference/engine/ps2/timer_REF.gc index 986da8e977..3fc1a64742 100644 --- a/test/decompiler/reference/engine/ps2/timer_REF.gc +++ b/test/decompiler/reference/engine/ps2/timer_REF.gc @@ -33,7 +33,7 @@ (local-vars (v0-0 int)) (let ((v1-0 (l.d L21))) (.mfc0 v0-0 Status) - (let ((v0-1 (logand v0-0 (the-as int v1-0)))) + (let ((v0-1 (logand v0-0 v1-0))) (.mtc0 Status v0-1) ) ) diff --git a/test/decompiler/reference/engine/sound/gsound_REF.gc b/test/decompiler/reference/engine/sound/gsound_REF.gc index 276015164c..5d21c79aa9 100644 --- a/test/decompiler/reference/engine/sound/gsound_REF.gc +++ b/test/decompiler/reference/engine/sound/gsound_REF.gc @@ -780,19 +780,13 @@ (set! (-> obj volume) 1024) (set! (-> obj pitch) 0) (when (and sv-16 (!= sv-16 *ambient-spec*)) - (if - (nonzero? - (logand (-> (the-as sound-spec sv-16) mask) 1) - ) + (if (logtest? (-> (the-as sound-spec sv-16) mask) 1) (set! (-> obj volume) (-> (the-as sound-spec sv-16) volume) ) ) - (if - (nonzero? - (logand (-> (the-as sound-spec sv-16) mask) 2) - ) + (if (logtest? (-> (the-as sound-spec sv-16) mask) 2) (set! (-> obj pitch) (-> (the-as sound-spec sv-16) pitch-mod) diff --git a/test/decompiler/reference/kernel/gcommon_REF.gc b/test/decompiler/reference/kernel/gcommon_REF.gc index 0738b17965..b71b8ef378 100644 --- a/test/decompiler/reference/kernel/gcommon_REF.gc +++ b/test/decompiler/reference/kernel/gcommon_REF.gc @@ -853,12 +853,9 @@ (defun mem-or! ((dst pointer) (src pointer) (size int)) (let ((result dst)) (dotimes (i size) - (set! + (logior! (-> (the-as (pointer uint8) dst)) - (logior - (-> (the-as (pointer uint8) dst)) - (-> (the-as (pointer uint8) src)) - ) + (-> (the-as (pointer uint8) src)) ) (&+! dst 1) (&+! src 1) @@ -966,7 +963,7 @@ (cond ((not expected-type) (cond - ((nonzero? (logand (the-as int obj) 3)) + ((logtest? (the-as int obj) 3) (if name (format print-dest @@ -998,7 +995,7 @@ ) ((= expected-type structure) (cond - ((nonzero? (logand (the-as int obj) 15)) + ((logtest? (the-as int obj) 15) (if name (format print-dest diff --git a/test/decompiler/reference/kernel/gkernel_REF.gc b/test/decompiler/reference/kernel/gkernel_REF.gc index 60dde208f5..2c62a30acc 100644 --- a/test/decompiler/reference/kernel/gkernel_REF.gc +++ b/test/decompiler/reference/kernel/gkernel_REF.gc @@ -209,31 +209,31 @@ ;; definition (debug) for function stream<-process-mask (defun-debug stream<-process-mask ((arg0 object) (arg1 process-mask)) (let ((s4-0 arg1)) - (if (= (logand #x1000000 (the-as int s4-0)) (process-mask death)) + (if (= (logand #x1000000 s4-0) (process-mask death)) (format arg0 "death ") ) - (if (= (logand #x800000 (the-as int s4-0)) (process-mask attackable)) + (if (= (logand #x800000 s4-0) (process-mask attackable)) (format arg0 "attackable ") ) - (if (= (logand #x400000 (the-as int s4-0)) (process-mask projectile)) + (if (= (logand #x400000 s4-0) (process-mask projectile)) (format arg0 "projectile ") ) - (if (= (logand #x200000 (the-as int s4-0)) (process-mask entity)) + (if (= (logand #x200000 s4-0) (process-mask entity)) (format arg0 "entity ") ) - (if (= (logand #x100000 (the-as int s4-0)) (process-mask ambient)) + (if (= (logand #x100000 s4-0) (process-mask ambient)) (format arg0 "ambient ") ) - (if (= (logand #x80000 (the-as int s4-0)) (process-mask platform)) + (if (= (logand #x80000 s4-0) (process-mask platform)) (format arg0 "platform ") ) - (if (= (logand #x40000 (the-as int s4-0)) (process-mask camera)) + (if (= (logand #x40000 s4-0) (process-mask camera)) (format arg0 "camera ") ) - (if (= (logand #x20000 (the-as int s4-0)) (process-mask enemy)) + (if (= (logand #x20000 s4-0) (process-mask enemy)) (format arg0 "enemy ") ) - (if (= (logand #x10000 (the-as int s4-0)) (process-mask collectable)) + (if (= (logand #x10000 s4-0) (process-mask collectable)) (format arg0 "collectable ") ) (if (= (logand s4-0 (process-mask crate)) (process-mask crate)) @@ -990,7 +990,7 @@ (when (not (or - (nonzero? (logand (-> arg0 mask) (process-mask heap-shrunk))) + (logtest? (-> arg0 mask) (process-mask heap-shrunk)) (and (not (-> arg0 next-state)) (not (-> arg0 state))) ) ) @@ -1003,7 +1003,7 @@ (< (the-as int arg0) (the-as int (gap-location obj (-> obj first-gap)))) (set! (-> obj first-gap) (find-gap obj (the-as dead-pool-heap-rec s5-0))) ) - (set! (-> arg0 mask) (logior (-> arg0 mask) (process-mask heap-shrunk))) + (logior! (-> arg0 mask) (process-mask heap-shrunk)) ) (if (= (-> obj first-shrink) s5-0) (set! (-> obj first-shrink) (the-as dead-pool-heap-rec (-> s5-0 2))) @@ -1250,10 +1250,7 @@ ((arg0 process-tree) (arg1 (function object object)) (arg2 kernel-context)) (let ((s4-0 - (or - (nonzero? (logand (-> arg0 mask) (process-mask process-tree))) - (arg1 arg0) - ) + (or (logtest? (-> arg0 mask) (process-mask process-tree)) (arg1 arg0)) ) ) (cond @@ -1281,10 +1278,10 @@ (let ((s3-0 (or - (nonzero? (logand (-> arg0 mask) (process-mask process-tree))) + (logtest? (-> arg0 mask) (process-mask process-tree)) (not (and - (zero? (logand (-> arg2 prevent-from-run) (the-as uint (-> arg0 mask)))) + (zero? (logand (-> arg2 prevent-from-run) (-> arg0 mask))) (run-logic? arg0) ) ) @@ -1355,11 +1352,9 @@ (('waiting-to-run 'suspended) (set! (-> s5-0 current-process) arg0) (cond - ((nonzero? - (logand - (-> arg0 mask) - (process-mask pause) - ) + ((logtest? + (-> arg0 mask) + (process-mask pause) ) (set! *stdcon* *stdcon1*) (set! *debug-draw-pauseable* #t) @@ -1394,11 +1389,9 @@ ) ) (if - (nonzero? - (logand - (-> arg0 mask) - (process-mask sleep-code) - ) + (logtest? + (-> arg0 mask) + (process-mask sleep-code) ) (set! (-> arg0 status) 'suspended) ((-> arg0 main-thread resume-hook) @@ -1710,9 +1703,9 @@ ((obj process) (arg0 process-tree) (arg1 basic) (arg2 pointer)) (set! (-> obj mask) - (logand - (lognot (process-mask sleep sleep-code process-tree heap-shrunk)) + (logclear (-> arg0 mask) + (process-mask sleep sleep-code process-tree heap-shrunk) ) ) (set! (-> obj status) 'ready) @@ -1734,7 +1727,7 @@ (set! (-> obj event-hook) #f) (set! (-> obj state) #f) (set! (-> obj next-state) #f) - (if (nonzero? (logand (-> arg0 mask) (process-mask process-tree))) + (if (logtest? (-> arg0 mask) (process-mask process-tree)) (set! (-> obj entity) #f) (set! (-> obj entity) (-> (the-as process arg0) entity)) ) diff --git a/test/decompiler/reference/kernel/gstate_REF.gc b/test/decompiler/reference/kernel/gstate_REF.gc index 2f193edaf3..a605510660 100644 --- a/test/decompiler/reference/kernel/gstate_REF.gc +++ b/test/decompiler/reference/kernel/gstate_REF.gc @@ -64,11 +64,8 @@ ) (local-vars (s7-0 none) (sp-0 none) (sp-1 int) (ra-0 int) (sv-0 none)) (with-pp - (set! - (-> pp mask) - (logand (lognot (process-mask sleep sleep-code)) (-> pp mask)) - ) - (set! (-> pp mask) (logior (-> pp mask) (process-mask going))) + (logclear! (-> pp mask) (process-mask sleep sleep-code)) + (logior! (-> pp mask) (process-mask going)) (cond ((= (-> pp status) 'initialize) (set! (-> pp trans-hook) #f) @@ -97,7 +94,7 @@ (set! s0-1 (-> s0-1 next)) ) ) - (set! (-> pp mask) (logand (lognot (process-mask going)) (-> pp mask))) + (logclear! (-> pp mask) (process-mask going)) (let ((s0-2 (-> pp state))) (set! (-> pp event-hook) (-> s0-2 event)) (if (-> s0-2 exit) diff --git a/test/decompiler/test_DisasmVifDecompile.cpp b/test/decompiler/test_DisasmVifDecompile.cpp index b5c1332f41..44d4ba2333 100644 --- a/test/decompiler/test_DisasmVifDecompile.cpp +++ b/test/decompiler/test_DisasmVifDecompile.cpp @@ -523,7 +523,7 @@ TEST_F(FormRegressionTest, ExprDisasmVif) { " (set! sv-16 (-> s1-0 cmd))\n" " (when\n" " (=\n" - " (logand sv-16 (the-as uint (-> *vif-disasm-table* v1-0 mask)))\n" + " (logand sv-16 (-> *vif-disasm-table* v1-0 mask))\n" " (-> *vif-disasm-table* v1-0 tag)\n" " )\n" " (let ((a0-12 (-> *vif-disasm-table* v1-0 print)))\n" @@ -633,10 +633,7 @@ TEST_F(FormRegressionTest, ExprDisasmVif) { " (+\n" " (logand\n" " -4\n" - " (the-as\n" - " int\n" - " (+ (* (-> *vif-disasm-table* v1-0 val) (-> s1-0 num)) 3)\n" - " )\n" + " (+ (* (-> *vif-disasm-table* v1-0 val) (-> s1-0 num)) 3)\n" " )\n" " 4\n" " )\n" diff --git a/test/decompiler/test_FormExpressionBuild.cpp b/test/decompiler/test_FormExpressionBuild.cpp index 9f7d44fbd9..dd4b1872ce 100644 --- a/test/decompiler/test_FormExpressionBuild.cpp +++ b/test/decompiler/test_FormExpressionBuild.cpp @@ -1935,16 +1935,11 @@ TEST_F(FormRegressionTest, ExprMemOr) { std::string type = "(function pointer pointer int pointer)"; std::string expected = - "(let\n" - " ((v0-0 arg0))\n" - " (dotimes\n" - " (v1-0 arg2)\n" - " (set!\n" + "(let ((v0-0 arg0))\n" + " (dotimes (v1-0 arg2)\n" + " (logior!\n" " (-> (the-as (pointer uint8) arg0))\n" - " (logior\n" - " (-> (the-as (pointer uint8) arg0))\n" - " (-> (the-as (pointer uint8) arg1))\n" - " )\n" + " (-> (the-as (pointer uint8) arg1))\n" " )\n" " (&+! arg0 1)\n" " (&+! arg1 1)\n" @@ -2904,10 +2899,7 @@ TEST_F(FormRegressionTest, AshPropagation) { std::string type = "(function bit-array int int)"; std::string expected = "(begin\n" - " (set!\n" - " (-> arg0 bytes (/ arg1 8))\n" - " (logior (-> arg0 bytes (/ arg1 8)) (the-as uint (ash 1 (logand arg1 7))))\n" - " )\n" + " (logior! (-> arg0 bytes (/ arg1 8)) (ash 1 (logand arg1 7)))\n" " 0\n" " )"; test_with_expr(func, type, expected); @@ -2942,7 +2934,7 @@ TEST_F(FormRegressionTest, AshPropagation2) { std::string type = "(function bit-array int symbol)"; std::string expected = "(let ((v1-2 (-> arg0 bytes (/ arg1 8))))\n" - " (nonzero? (logand v1-2 (the-as uint (ash 1 (logand arg1 7)))))\n" + " (nonzero? (logand v1-2 (ash 1 (logand arg1 7))))\n" " )"; test_with_expr(func, type, expected); } \ No newline at end of file diff --git a/test/decompiler/test_FormExpressionBuild2.cpp b/test/decompiler/test_FormExpressionBuild2.cpp index 5eb6edcf12..a2257e18c5 100644 --- a/test/decompiler/test_FormExpressionBuild2.cpp +++ b/test/decompiler/test_FormExpressionBuild2.cpp @@ -299,10 +299,11 @@ TEST_F(FormRegressionTest, IterateProcessTree) { " daddiu sp, sp, 80"; std::string type = "(function process-tree (function object object) kernel-context object)"; std::string expected = - "(let ((s4-0 (or (nonzero? (logand (-> arg0 mask) (process-mask process-tree))) (arg1 " - "arg0))))\n" + "(let\n" + " ((s4-0 (or (logtest? (-> arg0 mask) (process-mask process-tree)) (arg1 arg0)))\n" + " )\n" " (cond\n" - " ((= s4-0 (quote dead))\n" + " ((= s4-0 'dead)\n" " )\n" " (else\n" " (let ((v1-4 (-> arg0 child)))\n" @@ -728,13 +729,10 @@ TEST_F(FormRegressionTest, DmaSend) { " (.sync.l)\n" " (set!\n" " (-> arg0 madr)\n" - " (logior\n" - " (logand #xfffffff (the-as int arg1))\n" - " (the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)\n" - " (shl #x8000 16)\n" // note: maybe this should be #x80000000? Not sure. - " 0\n" - " )\n" - " )\n" + " (logior (logand #xfffffff arg1) (if (= (logand #x70000000 arg1) #x70000000)\n" + " (shl #x8000 16)\n" + " 0\n" + " )\n" " )\n" " )\n" " (set! (-> arg0 qwc) arg2)\n" diff --git a/test/decompiler/test_FormExpressionBuildLong.cpp b/test/decompiler/test_FormExpressionBuildLong.cpp index e5ee5a82ae..8735a08334 100644 --- a/test/decompiler/test_FormExpressionBuildLong.cpp +++ b/test/decompiler/test_FormExpressionBuildLong.cpp @@ -1785,7 +1785,7 @@ TEST_F(FormRegressionTest, ExprValid) { " (cond\n" " ((not arg1)\n" " (cond\n" - " ((nonzero? (logand (the-as int arg0) 3))\n" + " ((logtest? (the-as int arg0) 3)\n" " (if arg2\n" " (format\n" " arg4\n" @@ -1817,7 +1817,7 @@ TEST_F(FormRegressionTest, ExprValid) { " )\n" " ((= arg1 structure)\n" " (cond\n" - " ((nonzero? (logand (the-as int arg0) 15))\n" + " ((logtest? (the-as int arg0) 15)\n" " (if arg2\n" " (format\n" " arg4\n" @@ -2010,7 +2010,8 @@ TEST_F(FormRegressionTest, ExprValid) { " #t\n" " )\n" " )\n" - " )"; + " )\n" + "\n"; test_with_expr( func, type, expected, false, "", {{"L321", "ERROR: object #x~X ~S is not a valid object (misaligned)~%"}, diff --git a/test/decompiler/test_gkernel_decomp.cpp b/test/decompiler/test_gkernel_decomp.cpp index a4d927710e..797fa56ed9 100644 --- a/test/decompiler/test_gkernel_decomp.cpp +++ b/test/decompiler/test_gkernel_decomp.cpp @@ -2351,7 +2351,7 @@ TEST_F(FormRegressionTest, ExprMethod17DeadPoolHeap) { " (when\n" " (not\n" " (or\n" - " (nonzero? (logand (-> arg1 mask) (process-mask heap-shrunk)))\n" + " (logtest? (-> arg1 mask) (process-mask heap-shrunk))\n" " (and (not (-> arg1 next-state)) (not (-> arg1 state)))\n" " )\n" " )\n" @@ -2367,7 +2367,7 @@ TEST_F(FormRegressionTest, ExprMethod17DeadPoolHeap) { " (find-gap arg0 (the-as dead-pool-heap-rec s5-0))\n" " )\n" " )\n" - " (set! (-> arg1 mask) (logior (-> arg1 mask) (process-mask heap-shrunk)))\n" + " (logior! (-> arg1 mask) (process-mask heap-shrunk))\n" " )\n" " (if (= (-> arg0 first-shrink) s5-0)\n" " (set! (-> arg0 first-shrink) (the-as dead-pool-heap-rec (-> s5-0 2)))\n" diff --git a/test/goalc/source_templates/with_game/test-ray-sphere.gc b/test/goalc/source_templates/with_game/test-ray-sphere.gc new file mode 100644 index 0000000000..7a3191adb2 --- /dev/null +++ b/test/goalc/source_templates/with_game/test-ray-sphere.gc @@ -0,0 +1,34 @@ +;; A good intersection, tested against the C++ implementation. +(let ((sph (new 'static 'vector :x 0.4 :y 0.3 :z 0.7)) + (ray-origin (new 'static 'vector :x 0.2 :y -3.0)) + (ray-dir (new 'static 'vector :y 10.0))) + (format #t "Got ~f~%" (ray-sphere-intersect ray-origin ray-dir sph 1.2)) + ) + +;; Too far away, the probe is only 1 meter. +(let ((sph (new 'static 'vector :x 0.4 :y 0.3 :z 0.7)) + (ray-origin (new 'static 'vector :x 0.2 :y -3.0)) + (ray-dir (new 'static 'vector :y 1.0))) + (format #t "Got ~f~%" (ray-sphere-intersect ray-origin ray-dir sph 1.2)) + ) + +;; Wrong direction, the probe reaches, but would have to go backward. +(let ((sph (new 'static 'vector :x 0.4 :y 0.3 :z 0.7)) + (ray-origin (new 'static 'vector :x 0.2 :y -3.0)) + (ray-dir (new 'static 'vector :y -10.0))) + (format #t "Got ~f~%" (ray-sphere-intersect ray-origin ray-dir sph 1.2)) + ) + +;; starts inside of the sphere (should return 0) +(let ((sph (new 'static 'vector :x 0.4 :y 0.3 :z 0.7)) + (ray-origin (new 'static 'vector :x 0.4 :y 0.2 :z 0.7)) + (ray-dir (new 'static 'vector :y 10.0))) + (format #t "Got ~f~%" (ray-sphere-intersect ray-origin ray-dir sph 1.2)) + ) + +;; misses the sphere (negative in sqrt, needs to catch this to prevent NaNs) +(let ((sph (new 'static 'vector :x 0.4 :y 0.3 :z 0.7)) + (ray-origin (new 'static 'vector :x 1.61 :y -3.0)) + (ray-dir (new 'static 'vector :y 10.0))) + (format #t "Got ~f~%" (ray-sphere-intersect ray-origin ray-dir sph 1.2)) + ) diff --git a/test/goalc/test_with_game.cpp b/test/goalc/test_with_game.cpp index aff11c6454..02c012d3d5 100644 --- a/test/goalc/test_with_game.cpp +++ b/test/goalc/test_with_game.cpp @@ -796,6 +796,15 @@ TEST_F(WithGameTests, Behaviors) { "method obj: 456 self: 123\n0\n"}); } +TEST_F(WithGameTests, RaySphere) { + runner.run_static_test(env, testCategory, "test-ray-sphere.gc", + {"Got 0.2346\n" + "Got -100000000.0000\n" + "Got -100000000.0000\n" + "Got 0.0000\n" + "Got -100000000.0000\n0\n"}); +} + TEST(TypeConsistency, TypeConsistency) { Compiler compiler; compiler.enable_throw_on_redefines(); diff --git a/test/test_math.cpp b/test/test_math.cpp new file mode 100644 index 0000000000..7c735c8104 --- /dev/null +++ b/test/test_math.cpp @@ -0,0 +1,43 @@ +#include "gtest/gtest.h" +#include "common/math/geometry.h" + +TEST(Math, RaySphereOrigin) { + math::Vector sphere(0, 0, 0); + math::Vector line_origin(0, 0, 0); + math::Vector line_dir(1, 2, 3); // shouldn't matter + auto result = math::ray_sphere_intersect(line_origin, line_dir, sphere, 1.f); + EXPECT_FLOAT_EQ(result.u[0], 1.f); + EXPECT_FLOAT_EQ(result.u[1], -1.f); +} + +TEST(Math, RaySphereOriginOffsetXProbeX) { + math::Vector sphere(0, 0, 0); + math::Vector line_origin(0.5, 0, 0); + math::Vector line_dir(1, 0, 0); + auto result = math::ray_sphere_intersect(line_origin, line_dir, sphere, 1.f); + EXPECT_FLOAT_EQ(result.u[0], 0.5f); + EXPECT_FLOAT_EQ(result.u[1], -1.5f); +} + +TEST(Math, RaySphereOriginOffsetXProbeY) { + math::Vector sphere(0, 0, 0); + math::Vector line_origin(0.5, 0, 0); + math::Vector line_dir(0, 1, 0); + auto result = math::ray_sphere_intersect(line_origin, line_dir, sphere, 1.f); + // should be +/- sqrt(3)/2, draw a triangle. + EXPECT_FLOAT_EQ(result.u[0], std::sqrt(3.f) / 2.f); + EXPECT_FLOAT_EQ(result.u[1], -std::sqrt(3.f) / 2.f); +} + +TEST(Math, RaySphereMakeTestCaseHit) { + math::Vector sphere(0.4, 0.3, 0.7); + math::Vector line_origin(0.2, -3, 0); + math::Vector line_dir(0, 1, 0); + auto result = math::ray_sphere_intersect(line_origin, line_dir, sphere, 1.2f); + fmt::print("Test case: {} {} {}\n", result.hit, result.u[0], result.u[1]); +} + +TEST(Math, RaySphereMiss) { + math::Vector sphere(1, 2, 3); + fmt::print("{}\n", sphere.to_string_aligned()); +} diff --git a/tools/MemoryDumpTool/main.cpp b/tools/MemoryDumpTool/main.cpp index 400f64eca8..b9a95eb15e 100644 --- a/tools/MemoryDumpTool/main.cpp +++ b/tools/MemoryDumpTool/main.cpp @@ -106,6 +106,7 @@ u32 scan_for_symbol_table(const Ram& ram, u32 start_addr, u32 end_addr) { struct SymbolMap { std::unordered_map name_to_addr; + std::unordered_map name_to_value; std::unordered_map addr_to_name; }; @@ -133,6 +134,7 @@ SymbolMap build_symbol_map(const Ram& ram, u32 s7) { assert(map.name_to_addr.find(name) == map.name_to_addr.end()); map.name_to_addr[name] = sym; map.addr_to_name[sym] = name; + map.name_to_value[name] = ram.word(sym); } } } @@ -357,7 +359,7 @@ void inspect_symbols(const Ram& ram, } } if (!found_type.empty()) { - fmt::print(" {:30s} : {}\n", name, found_type); + fmt::print(" [{:08x}] {:30s} : {}\n", symbols.name_to_value.at(name), name, found_type); } } }